Nux

Merge lp:~haggai-eran/nux/rtl-logical-packing into lp:nux

Proposed by Didier Roche-Tolomelli
Status: Work in progress
Proposed branch: lp:~haggai-eran/nux/rtl-logical-packing
Merge into: lp:nux
Diff against target: 1076 lines (+421/-95)
14 files modified
Nux/Area.cpp (+15/-0)
Nux/Area.h (+16/-0)
Nux/HLayout.cpp (+24/-10)
Nux/HScrollBar.cpp (+4/-0)
Nux/Nux.cpp (+13/-0)
Nux/Nux.h (+3/-0)
Nux/RangeValue.cpp (+15/-1)
Nux/ScrollView.cpp (+49/-10)
Nux/VSplitter.cpp (+103/-33)
tests/Helpers.cpp (+50/-3)
tests/Helpers.h (+2/-1)
tests/Makefile.am (+4/-1)
tests/gtest-nux-cairo-wrapper.cpp (+2/-36)
tests/gtest-nux-hlayout.cpp (+121/-0)
To merge this branch: bzr merge lp:~haggai-eran/nux/rtl-logical-packing
Reviewer Review Type Date Requested Status
Tim Penhey Pending
Jay Taoko Pending
Review via email: mp+103818@code.launchpad.net

This proposal supersedes a proposal from 2011-12-13.

Description of the change

Hi,

I've implemented the mirroring for right-to-left locales in this branch, in a way that is different from lp:~haggai-eran/nux/rtl-rebased. I believe this implementation is simpler, requires less changes, and works better with existing widgets.

I've also added a test to make sure the HLayout mirroring is working properly, as a part of the gtest-nux-core test suite.

I'm not sure if I should delete the merge proposal for the rtl-rebased branch, since launchpad says this will also delete all comments. Perhaps it can be archived somehow.

Regards,
Haggai

To post a comment you must log in.
Revision history for this message
Tim Penhey (thumper) wrote : Posted in a previous version of this proposal

Just a few minor style things from me:
 * member variables should have trailing not leading underscore
  (parts being updated as we get to them)
 * no space before function call parenthesis
 * please use C++ style enum definitions (not typedef)

   enum Direction
   {
      // values...
   };

I'll let Jay do the actual functionality bits.

review: Needs Fixing
Revision history for this message
Haggai Eran (haggai-eran) wrote : Posted in a previous version of this proposal

Hi,

It's been 3 months since I posted this request, and except for the coding style comment I haven't gotten any feedback to this patch. Could you tell me if you need any more information or any more work to be done on it?

Revision history for this message
Shahar Or (mightyiam) wrote : Posted in a previous version of this proposal

Dear Unity/Nux developers,

This is really important for us, RTL users. And It is precious and rare that we have such a willing and able contributor in the RTL community.

So please give this merge even more love! :)

We appreciate it!

Thanks and Blessings,
Shahar
In service of Ubuntu RTL users

Revision history for this message
Jay Taoko (jaytaoko) wrote : Posted in a previous version of this proposal

It hasn't been easy to come to a decision regarding the proposal of this branch. Supporting Right-to-Left languages is very important and it as do be done right. With regard to Unity which is the main focus, the team hasn't finalised the design for Right-to-Left language support. And how it would impact Unity. That is why I can't approve the branch at this stage.

There are also other technical considerations with the branch. Activating the Right-to-Left mode will not make every widget correct. Some widgets have to be specifically designed with Right-to-Left language support in mind and we can't do it just yet.

Revision history for this message
Haggai Eran (haggai-eran) wrote : Posted in a previous version of this proposal

Hi Jay,
Thanks for your reply. I understand it is important for the Unity team to make a complete design for right-to-left language support, before accepting any changes. I'm interested in helping advancing this issue, and I would like to take part in this discussion, if that's okay. Can you tell me where is it taking place?

Regarding the branch itself, it is true that I haven't tested all the widgets, as I was focused on what was needed to make the most prominent features of unity mirrored, and hoping to continue to improve it later on.

Finally, since it doesn't seem that Unity will have right-to-left support soon, while Unity2D has right-to-left support since Oneiric (using Qt's excellent mirroring support), I'd like to offer that users of right-to-left languages will have their default desktop set to Unity2D. I wrote about it in the unity-design mailing list [1], and proposed a patch to do so at lp:~haggai-eran/nux/rtl-fallback-to-unity-2d. Would you consider implementing such workaround for Precise?

Best regards,
Haggai

[1] https://lists.launchpad.net/unity-design/msg08745.html

Unmerged revisions

536. By Haggai Eran

Right-to-left mirroring support for VSplitter.

535. By Haggai Eran

Support right-to-left mirroring in HScrollBar and ScrollView.

534. By Haggai Eran

RangeValue right-to-left mirroring support.

533. By Haggai Eran

Merge version 2.10.0 from trunk.

532. By Haggai Eran

Fix several coding style issues.

531. By Haggai Eran

Add simple HLayout test, testing both left-to-right and right-to-left modes.

Moved the run_test wrapper from test_cairo_wrapper.cpp to Helpers.cpp so that it can be reused.

530. By Haggai Eran

HLayout right-to-left support.

529. By Haggai Eran

Basic right-to-left directionality support.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'Nux/Area.cpp'
--- Nux/Area.cpp 2012-03-12 21:45:30 +0000
+++ Nux/Area.cpp 2012-04-27 07:24:03 +0000
@@ -39,6 +39,7 @@
39 , geometry_(0, 0, DEFAULT_WIDGET_WIDTH, DEFAULT_WIDGET_HEIGHT)39 , geometry_(0, 0, DEFAULT_WIDGET_WIDTH, DEFAULT_WIDGET_HEIGHT)
40 , min_size_(AREA_MIN_WIDTH, AREA_MIN_HEIGHT)40 , min_size_(AREA_MIN_WIDTH, AREA_MIN_HEIGHT)
41 , max_size_(AREA_MAX_WIDTH, AREA_MAX_HEIGHT)41 , max_size_(AREA_MAX_WIDTH, AREA_MAX_HEIGHT)
42 , direction_(GetDefaultDirection())
42 {43 {
43 window_thread_ = GetWindowThread();44 window_thread_ = GetWindowThread();
44 visible_ = true;45 visible_ = true;
@@ -336,9 +337,13 @@
336337
337 void Area::SetGeometry(int x, int y, int w, int h)338 void Area::SetGeometry(int x, int y, int w, int h)
338 {339 {
340 const int original_width = w;
339 h = nux::Clamp<int> (h, min_size_.height, max_size_.height);341 h = nux::Clamp<int> (h, min_size_.height, max_size_.height);
340 w = nux::Clamp<int> (w, min_size_.width, max_size_.width);342 w = nux::Clamp<int> (w, min_size_.width, max_size_.width);
341343
344 if (GetDirection() == RightToLeft)
345 x = x + original_width - w;
346
342 nux::Geometry geometry(x, y, w, h);347 nux::Geometry geometry(x, y, w, h);
343 if (geometry_ == geometry)348 if (geometry_ == geometry)
344 return;349 return;
@@ -1035,5 +1040,15 @@
10351040
1036 return false;1041 return false;
1037 }1042 }
1043
1044 Direction Area::GetDirection() const
1045 {
1046 return direction_;
1047 }
1048
1049 void Area::SetDirection(Direction direction)
1050 {
1051 direction_ = direction;
1052 }
1038}1053}
10391054
10401055
=== modified file 'Nux/Area.h'
--- Nux/Area.h 2012-03-12 21:45:30 +0000
+++ Nux/Area.h 2012-04-27 07:24:03 +0000
@@ -140,6 +140,12 @@
140 KEY_NAV_ENTER,140 KEY_NAV_ENTER,
141 };141 };
142142
143 enum Direction
144 {
145 LeftToRight,
146 RightToLeft
147 };
148
143 class Layout;149 class Layout;
144 class View;150 class View;
145 class Area;151 class Area;
@@ -572,6 +578,14 @@
572 */578 */
573 bool AcceptMouseWheelEvent() const;579 bool AcceptMouseWheelEvent() const;
574580
581 //! Return the direction of the area.
582 Direction GetDirection() const;
583 //! Sets the direction of the area.
584 /*!
585 @param direction Either nux::LeftToRight or nux::RightToLeft
586 */
587 void SetDirection(Direction direction);
588
575 protected:589 protected:
576 /*590 /*
577 This function is reimplemented in Layout as it need to perform some special operations.591 This function is reimplemented in Layout as it need to perform some special operations.
@@ -668,6 +682,8 @@
668682
669 WindowThread* window_thread_;683 WindowThread* window_thread_;
670684
685 Direction direction_;
686
671 friend class Layout;687 friend class Layout;
672 friend class View;688 friend class View;
673 friend class WindowThread;689 friend class WindowThread;
674690
=== modified file 'Nux/HLayout.cpp'
--- Nux/HLayout.cpp 2011-12-10 06:39:14 +0000
+++ Nux/HLayout.cpp 2012-04-27 07:24:03 +0000
@@ -172,6 +172,9 @@
172172
173 long HLayout::ComputeContentSize()173 long HLayout::ComputeContentSize()
174 {174 {
175 const bool ltr = GetDirection() == LeftToRight;
176 const int ltr_factor = ltr ? 1 : -1;
177
175 if (_layout_element_list.size() == 0)178 if (_layout_element_list.size() == 0)
176 {179 {
177 return eCompliantHeight | eCompliantWidth;180 return eCompliantHeight | eCompliantWidth;
@@ -240,22 +243,26 @@
240 HLayoutManagement(width, height);243 HLayoutManagement(width, height);
241244
242 // Objects have been resized, now position them.245 // Objects have been resized, now position them.
243 int current_x = GetBaseX() + left_padding_;246 int current_x;
247 if (ltr)
248 current_x = GetBaseX() + left_padding_;
249 else
250 current_x = GetBaseX() + GetBaseWidth() - right_padding_;
244 int current_y = GetBaseY() + top_padding_;251 int current_y = GetBaseY() + top_padding_;
245252
246 int offset_space = 0;253 int offset_space = 0;
247 int space_after_element = 0;254 int space_after_element = 0;
248 ComputeStacking(width, offset_space, space_after_element);255 ComputeStacking(width, offset_space, space_after_element);
249 current_x += offset_space;256 current_x += ltr_factor * offset_space;
250257
251 for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++)258 for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++)
252 {259 {
253 if (!(*it)->IsVisible())260 if (!(*it)->IsVisible())
254 continue;261 continue;
255262
256 current_x += space_after_element;263 current_x += ltr_factor * space_after_element;
257264
258 (*it)->SetBaseX(current_x);265 (*it)->SetBaseX(current_x - (!ltr ? (*it)->GetBaseWidth() : 0));
259 (*it)->SetBaseY(current_y);266 (*it)->SetBaseY(current_y);
260267
261 MinorDimensionSize extend = (*it)->GetExtend();268 MinorDimensionSize extend = (*it)->GetExtend();
@@ -330,7 +337,7 @@
330 }337 }
331 }338 }
332339
333 current_x += (*it)->GetBaseWidth() + space_after_element + space_between_children_;340 current_x += ltr_factor * ((*it)->GetBaseWidth() + space_after_element + space_between_children_);
334 }341 }
335342
336 // Manage child layout343 // Manage child layout
@@ -756,6 +763,9 @@
756763
757 void HLayout::ComputeContentPosition(float offsetX, float offsetY)764 void HLayout::ComputeContentPosition(float offsetX, float offsetY)
758 {765 {
766 const bool ltr = GetDirection() == LeftToRight;
767 const int ltr_factor = ltr ? 1 : -1;
768
759 std::list<Area *>::iterator it;769 std::list<Area *>::iterator it;
760 {770 {
761 unsigned int num_element = 0;771 unsigned int num_element = 0;
@@ -773,22 +783,26 @@
773 height -= (top_padding_ + bottom_padding_);783 height -= (top_padding_ + bottom_padding_);
774784
775 // Objects have been resized, now position them.785 // Objects have been resized, now position them.
776 int current_x = GetBaseX() + left_padding_ + offsetX; // add base offset in X(used for scrolling)786 int current_x;
787 if (ltr)
788 current_x = GetBaseX() + left_padding_ + offsetX; // add base offset in X(used for scrolling)
789 else
790 current_x = GetBaseX() + GetBaseWidth() - right_padding_ + offsetX;
777 int current_y = GetBaseY() + top_padding_ + offsetY; // add base offset in Y(used for scrolling)791 int current_y = GetBaseY() + top_padding_ + offsetY; // add base offset in Y(used for scrolling)
778792
779 int offset_space = 0;793 int offset_space = 0;
780 int element_margin = 0;794 int element_margin = 0;
781 ComputeStacking(width, offset_space, element_margin);795 ComputeStacking(width, offset_space, element_margin);
782 current_x += offset_space;796 current_x += ltr_factor * offset_space;
783797
784 for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++)798 for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++)
785 {799 {
786 if (!(*it)->IsVisible())800 if (!(*it)->IsVisible())
787 continue;801 continue;
788802
789 current_x += element_margin;803 current_x += ltr_factor * element_margin;
790804
791 (*it)->SetBaseX(current_x);805 (*it)->SetBaseX(current_x - (!ltr ? (*it)->GetBaseWidth() : 0));
792 (*it)->SetBaseY(current_y);806 (*it)->SetBaseY(current_y);
793807
794 MinorDimensionPosition positioning = (*it)->GetPositioning();808 MinorDimensionPosition positioning = (*it)->GetPositioning();
@@ -826,7 +840,7 @@
826 }840 }
827 }841 }
828842
829 current_x += (*it)->GetBaseWidth() + element_margin + space_between_children_;843 current_x += ltr_factor * ((*it)->GetBaseWidth() + element_margin + space_between_children_);
830 }844 }
831 }845 }
832846
833847
=== modified file 'Nux/HScrollBar.cpp'
--- Nux/HScrollBar.cpp 2011-10-17 20:57:35 +0000
+++ Nux/HScrollBar.cpp 2012-04-27 07:24:03 +0000
@@ -52,6 +52,7 @@
52 m_RightTimerHandler = 0;52 m_RightTimerHandler = 0;
5353
54 hlayout = new HLayout(NUX_TRACKER_LOCATION);54 hlayout = new HLayout(NUX_TRACKER_LOCATION);
55 hlayout->SetDirection(LeftToRight);
55 _scroll_left_button = new InputArea(NUX_TRACKER_LOCATION);56 _scroll_left_button = new InputArea(NUX_TRACKER_LOCATION);
56 _track = new InputArea(NUX_TRACKER_LOCATION);57 _track = new InputArea(NUX_TRACKER_LOCATION);
57 _scroll_right_button = new InputArea(NUX_TRACKER_LOCATION);58 _scroll_right_button = new InputArea(NUX_TRACKER_LOCATION);
@@ -302,6 +303,9 @@
302303
303 void HScrollBar::SetContentSize(int x, int y, int w, int h)304 void HScrollBar::SetContentSize(int x, int y, int w, int h)
304 {305 {
306 if (GetDirection() == RightToLeft)
307 content_offset_x_ = w - container_width_ + content_offset_x_;
308
305 // x and y are not needed309 // x and y are not needed
306 content_width_ = w;310 content_width_ = w;
307 content_height_ = h;311 content_height_ = h;
308312
=== modified file 'Nux/Nux.cpp'
--- Nux/Nux.cpp 2011-12-29 18:06:53 +0000
+++ Nux/Nux.cpp 2012-04-27 07:24:03 +0000
@@ -379,4 +379,17 @@
379 NThread *thread = GetWindowThread();379 NThread *thread = GetWindowThread();
380 return NUX_STATIC_CAST(WindowThread *, thread)->GetTimerHandler();380 return NUX_STATIC_CAST(WindowThread *, thread)->GetTimerHandler();
381 }381 }
382
383 static Direction defaultDirection = LeftToRight;
384
385 Direction GetDefaultDirection()
386 {
387 return defaultDirection;
388 }
389
390 void SetDefaultDirection(Direction direction)
391 {
392 defaultDirection = direction;
393 }
394
382}395}
383396
=== modified file 'Nux/Nux.h'
--- Nux/Nux.h 2012-02-19 00:02:14 +0000
+++ Nux/Nux.h 2012-04-27 07:24:03 +0000
@@ -235,6 +235,9 @@
235235
236 inlDeclareThreadLocalStorage(NThread *, 0, ThreadLocal_InalogicAppImpl);236 inlDeclareThreadLocalStorage(NThread *, 0, ThreadLocal_InalogicAppImpl);
237237
238 Direction GetDefaultDirection();
239 void SetDefaultDirection(Direction direction);
240
238}241}
239242
240#endif // NUX_H243#endif // NUX_H
241244
=== modified file 'Nux/RangeValue.cpp'
--- Nux/RangeValue.cpp 2012-01-17 04:34:19 +0000
+++ Nux/RangeValue.cpp 2012-04-27 07:24:03 +0000
@@ -92,11 +92,15 @@
92 void RangeValue::DrawMarker(GraphicsEngine &graphics_engine)92 void RangeValue::DrawMarker(GraphicsEngine &graphics_engine)
93 {93 {
94 int marker_position_x;94 int marker_position_x;
95 int relative_position_x;
95 int marker_position_y;96 int marker_position_y;
9697
97 graphics_engine.PushClippingRectangle(m_Percentage->GetGeometry());98 graphics_engine.PushClippingRectangle(m_Percentage->GetGeometry());
9899
99 marker_position_x = m_Percentage->GetBaseX() + (m_Value - m_min) * m_Percentage->GetBaseWidth() * 1 / (m_max - m_min);100 relative_position_x = (m_Value - m_min) * m_Percentage->GetBaseWidth() * 1 / (m_max - m_min);
101 if (GetDirection() == RightToLeft)
102 relative_position_x = m_Percentage->GetBaseWidth() - relative_position_x;
103 marker_position_x = m_Percentage->GetBaseX() + relative_position_x;
100 marker_position_y = m_Percentage->GetBaseY() + m_Percentage->GetBaseHeight();104 marker_position_y = m_Percentage->GetBaseY() + m_Percentage->GetBaseHeight();
101 GetPainter().Draw2DTriangleColor(graphics_engine, marker_position_x - 5, marker_position_y,105 GetPainter().Draw2DTriangleColor(graphics_engine, marker_position_x - 5, marker_position_y,
102 marker_position_x, marker_position_y - 5,106 marker_position_x, marker_position_y - 5,
@@ -121,6 +125,8 @@
121 if (m_EnableDrawProgress)125 if (m_EnableDrawProgress)
122 {126 {
123 P.SetWidth((m_Value - m_min) * (float) P.GetWidth() / (m_max - m_min));127 P.SetWidth((m_Value - m_min) * (float) P.GetWidth() / (m_max - m_min));
128 if (GetDirection() == RightToLeft)
129 P.OffsetPosition(m_Percentage->GetBaseWidth() - P.GetWidth(), 0);
124 GetPainter().Paint2DQuadColor(graphics_engine, P, m_ProgressColor);130 GetPainter().Paint2DQuadColor(graphics_engine, P, m_ProgressColor);
125 }131 }
126132
@@ -186,6 +192,9 @@
186////////////////192////////////////
187 void RangeValue::OnReceiveMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags)193 void RangeValue::OnReceiveMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags)
188 {194 {
195 if (GetDirection() == RightToLeft)
196 x = m_Percentage->GetBaseWidth() - x;
197
189 if (x < 0)198 if (x < 0)
190 m_Value = m_min;199 m_Value = m_min;
191 else if (x > m_Percentage->GetBaseWidth())200 else if (x > m_Percentage->GetBaseWidth())
@@ -203,6 +212,8 @@
203212
204 void RangeValue::OnReceiveMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags)213 void RangeValue::OnReceiveMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags)
205 {214 {
215 if (GetDirection() == RightToLeft)
216 x = m_Percentage->GetBaseWidth() - x;
206217
207 if (x < 0)218 if (x < 0)
208 m_Value = m_min;219 m_Value = m_min;
@@ -221,6 +232,9 @@
221232
222 void RangeValue::OnReceiveMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags)233 void RangeValue::OnReceiveMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags)
223 {234 {
235 if (GetDirection() == RightToLeft)
236 x = m_Percentage->GetBaseWidth() - x;
237
224 if (x < 0)238 if (x < 0)
225 m_Value = m_min;239 m_Value = m_min;
226 else if (x > m_Percentage->GetBaseWidth())240 else if (x > m_Percentage->GetBaseWidth())
227241
=== modified file 'Nux/ScrollView.cpp'
--- Nux/ScrollView.cpp 2011-12-13 08:20:18 +0000
+++ Nux/ScrollView.cpp 2012-04-27 07:24:03 +0000
@@ -316,6 +316,8 @@
316 {316 {
317 // Give the managed layout the same size and position as the Control.317 // Give the managed layout the same size and position as the Control.
318318
319 bool ltr = GetDirection() == LeftToRight;
320
319 Geometry geo = GetGeometry();321 Geometry geo = GetGeometry();
320 int ScrollBarWidth = _vscrollbar->GetBaseWidth();322 int ScrollBarWidth = _vscrollbar->GetBaseWidth();
321 int ScrollBarHeight = _hscrollbar->GetBaseHeight();323 int ScrollBarHeight = _hscrollbar->GetBaseHeight();
@@ -324,6 +326,8 @@
324 nuxAssertMsg(ScrollBarHeight > 0, "[ScrollView::PreLayoutManagement] Invalid scrollbar height: %d", ScrollBarHeight);326 nuxAssertMsg(ScrollBarHeight > 0, "[ScrollView::PreLayoutManagement] Invalid scrollbar height: %d", ScrollBarHeight);
325327
326 m_ViewX = GetBaseX() + m_border + m_ViewContentLeftMargin;328 m_ViewX = GetBaseX() + m_border + m_ViewContentLeftMargin;
329 if (!ltr)
330 m_ViewX += ScrollBarWidth;
327 m_ViewY = GetBaseY() + m_top_border + m_ViewContentTopMargin;331 m_ViewY = GetBaseY() + m_top_border + m_ViewContentTopMargin;
328332
329 if (m_vertical_scrollbar_enable == false)333 if (m_vertical_scrollbar_enable == false)
@@ -383,7 +387,10 @@
383 else387 else
384 _hscrollbar->SetBaseWidth(GetBaseWidth() - ScrollBarWidth - 2 * m_border);388 _hscrollbar->SetBaseWidth(GetBaseWidth() - ScrollBarWidth - 2 * m_border);
385389
386 _hscrollbar->SetBaseX(geo.x + m_border);390 if (ltr || !m_vertical_scrollbar_enable)
391 _hscrollbar->SetBaseX(geo.x + m_border);
392 else
393 _hscrollbar->SetBaseX(geo.x + m_border + ScrollBarWidth);
387 _hscrollbar->SetBaseY(geo.y + geo.GetHeight() - _hscrollbar->GetBaseHeight() - m_border);394 _hscrollbar->SetBaseY(geo.y + geo.GetHeight() - _hscrollbar->GetBaseHeight() - m_border);
388 _hscrollbar->ComputeContentSize();395 _hscrollbar->ComputeContentSize();
389 }396 }
@@ -391,7 +398,10 @@
391 {398 {
392 // The horizontal scrollbar won't be visible but give it a proper size anyway.399 // The horizontal scrollbar won't be visible but give it a proper size anyway.
393 _hscrollbar->SetBaseWidth(GetBaseWidth() - ScrollBarWidth - 2 * m_border);400 _hscrollbar->SetBaseWidth(GetBaseWidth() - ScrollBarWidth - 2 * m_border);
394 _hscrollbar->SetBaseX(geo.x + m_border);401 if (ltr)
402 _hscrollbar->SetBaseX(geo.x + m_border);
403 else
404 _hscrollbar->SetBaseX(geo.x + m_border + ScrollBarWidth);
395 _hscrollbar->SetBaseY(geo.y + geo.GetHeight() - _hscrollbar->GetBaseHeight() - m_border);405 _hscrollbar->SetBaseY(geo.y + geo.GetHeight() - _hscrollbar->GetBaseHeight() - m_border);
396 _hscrollbar->ComputeContentSize();406 _hscrollbar->ComputeContentSize();
397 }407 }
@@ -408,7 +418,10 @@
408 else418 else
409 _vscrollbar->SetBaseHeight(GetBaseHeight() - ScrollBarHeight - m_top_border - m_border);419 _vscrollbar->SetBaseHeight(GetBaseHeight() - ScrollBarHeight - m_top_border - m_border);
410420
411 _vscrollbar->SetBaseX(geo.x + geo.GetWidth() - ScrollBarWidth - m_border);421 if (ltr)
422 _vscrollbar->SetBaseX(geo.x + geo.GetWidth() - ScrollBarWidth - m_border);
423 else
424 _vscrollbar->SetBaseX(geo.x + m_border);
412 _vscrollbar->SetBaseY(geo.y + m_top_border);425 _vscrollbar->SetBaseY(geo.y + m_top_border);
413 _vscrollbar->ComputeContentSize();426 _vscrollbar->ComputeContentSize();
414 }427 }
@@ -416,7 +429,11 @@
416 {429 {
417 // The vertical scrollbar won't be visible but give it a proper size anyway.430 // The vertical scrollbar won't be visible but give it a proper size anyway.
418 _vscrollbar->SetBaseHeight(GetBaseHeight() - ScrollBarHeight - m_top_border - m_border);431 _vscrollbar->SetBaseHeight(GetBaseHeight() - ScrollBarHeight - m_top_border - m_border);
419 _vscrollbar->SetBaseX(geo.x + geo.GetWidth() - ScrollBarWidth - m_border);432 if (ltr)
433 _vscrollbar->SetBaseX(geo.x + geo.GetWidth() - ScrollBarWidth - m_border);
434 else
435 _vscrollbar->SetBaseX(geo.x + m_border);
436
420 _vscrollbar->SetBaseY(geo.y + m_top_border);437 _vscrollbar->SetBaseY(geo.y + m_top_border);
421 _vscrollbar->ComputeContentSize();438 _vscrollbar->ComputeContentSize();
422 }439 }
@@ -510,6 +527,7 @@
510 long ScrollView::PostLayoutManagement2(long LayoutResult)527 long ScrollView::PostLayoutManagement2(long LayoutResult)
511 {528 {
512 // In case IsSizeMatchContent returns True, The scroll view is resized to match its content.529 // In case IsSizeMatchContent returns True, The scroll view is resized to match its content.
530 bool ltr = GetDirection() == LeftToRight;
513 int ScrollbarWidth = 0;531 int ScrollbarWidth = 0;
514 int ScrollbarHeight = 0;532 int ScrollbarHeight = 0;
515533
@@ -564,7 +582,10 @@
564 else582 else
565 _hscrollbar->SetBaseWidth(GetBaseWidth() - ScrollbarWidth - 2 * m_border);583 _hscrollbar->SetBaseWidth(GetBaseWidth() - ScrollbarWidth - 2 * m_border);
566584
567 _hscrollbar->SetBaseX(geo.x + m_border);585 if (ltr || !m_vertical_scrollbar_enable)
586 _hscrollbar->SetBaseX(geo.x + m_border);
587 else
588 _hscrollbar->SetBaseX(geo.x + m_border + ScrollbarWidth);
568 _hscrollbar->SetBaseY(geo.y + geo.GetHeight() - _hscrollbar->GetBaseHeight() - m_border);589 _hscrollbar->SetBaseY(geo.y + geo.GetHeight() - _hscrollbar->GetBaseHeight() - m_border);
569 _hscrollbar->ComputeContentSize();590 _hscrollbar->ComputeContentSize();
570591
@@ -590,7 +611,10 @@
590 else611 else
591 {612 {
592 _hscrollbar->SetBaseWidth(GetBaseWidth() - ScrollbarWidth - 2 * m_border);613 _hscrollbar->SetBaseWidth(GetBaseWidth() - ScrollbarWidth - 2 * m_border);
593 _hscrollbar->SetBaseX(geo.x + m_border);614 if (ltr)
615 _hscrollbar->SetBaseX(geo.x + m_border);
616 else
617 _hscrollbar->SetBaseX(geo.x + m_border + ScrollbarWidth);
594 _hscrollbar->SetBaseY(geo.y + geo.GetHeight() - _hscrollbar->GetBaseHeight() - m_border);618 _hscrollbar->SetBaseY(geo.y + geo.GetHeight() - _hscrollbar->GetBaseHeight() - m_border);
595 _hscrollbar->ComputeContentSize();619 _hscrollbar->ComputeContentSize();
596620
@@ -613,7 +637,10 @@
613 else637 else
614 _vscrollbar->SetBaseHeight(GetBaseHeight() - ScrollbarHeight - m_top_border - m_border);638 _vscrollbar->SetBaseHeight(GetBaseHeight() - ScrollbarHeight - m_top_border - m_border);
615639
616 _vscrollbar->SetBaseX(geo.x + geo.GetWidth() - ScrollbarWidth - m_border);640 if (ltr)
641 _vscrollbar->SetBaseX(geo.x + geo.GetWidth() - ScrollbarWidth - m_border);
642 else
643 _vscrollbar->SetBaseX(geo.x + m_border);
617 _vscrollbar->SetBaseY(geo.y + m_top_border);644 _vscrollbar->SetBaseY(geo.y + m_top_border);
618 _vscrollbar->ComputeContentSize();645 _vscrollbar->ComputeContentSize();
619646
@@ -639,7 +666,10 @@
639 else666 else
640 {667 {
641 _vscrollbar->SetBaseHeight(GetBaseHeight() - ScrollbarHeight - m_top_border - m_border);668 _vscrollbar->SetBaseHeight(GetBaseHeight() - ScrollbarHeight - m_top_border - m_border);
642 _vscrollbar->SetBaseX(geo.x + geo.GetWidth() - ScrollbarWidth - m_border);669 if (ltr)
670 _vscrollbar->SetBaseX(geo.x + geo.GetWidth() - ScrollbarWidth - m_border);
671 else
672 _vscrollbar->SetBaseX(geo.x + m_border);
643 _vscrollbar->SetBaseY(geo.y + m_top_border);673 _vscrollbar->SetBaseY(geo.y + m_top_border);
644 _vscrollbar->ComputeContentSize();674 _vscrollbar->ComputeContentSize();
645675
@@ -667,6 +697,7 @@
667// This function is called when the ScrollView is embedded within a Layout.697// This function is called when the ScrollView is embedded within a Layout.
668 void ScrollView::ComputeContentPosition(float offsetX, float offsetY)698 void ScrollView::ComputeContentPosition(float offsetX, float offsetY)
669 {699 {
700 bool ltr = GetDirection() == LeftToRight;
670 Geometry geo = GetGeometry();701 Geometry geo = GetGeometry();
671 int w = 0;702 int w = 0;
672 int h = 0;703 int h = 0;
@@ -675,6 +706,8 @@
675 h = _hscrollbar->GetBaseHeight();706 h = _hscrollbar->GetBaseHeight();
676707
677 m_ViewX = GetBaseX() + m_border + m_ViewContentLeftMargin;708 m_ViewX = GetBaseX() + m_border + m_ViewContentLeftMargin;
709 if (!ltr)
710 m_ViewX += w;
678 m_ViewY = GetBaseY() + m_top_border + m_ViewContentTopMargin;711 m_ViewY = GetBaseY() + m_top_border + m_ViewContentTopMargin;
679712
680 if (m_vertical_scrollbar_enable == false)713 if (m_vertical_scrollbar_enable == false)
@@ -712,7 +745,10 @@
712 else745 else
713 _hscrollbar->SetBaseWidth(GetBaseWidth() - w - 2 * m_border);746 _hscrollbar->SetBaseWidth(GetBaseWidth() - w - 2 * m_border);
714747
715 _hscrollbar->SetBaseX(geo.x + m_border);748 if (ltr || !m_vertical_scrollbar_enable)
749 _hscrollbar->SetBaseX(geo.x + m_border);
750 else
751 _hscrollbar->SetBaseX(geo.x + m_border + w);
716 _hscrollbar->SetBaseY(geo.y + geo.GetHeight() - _hscrollbar->GetBaseHeight() - m_border);752 _hscrollbar->SetBaseY(geo.y + geo.GetHeight() - _hscrollbar->GetBaseHeight() - m_border);
717 _hscrollbar->ComputeContentSize();753 _hscrollbar->ComputeContentSize();
718 }754 }
@@ -725,7 +761,10 @@
725 else761 else
726 _vscrollbar->SetBaseHeight(GetBaseHeight() - h - m_top_border - m_border);762 _vscrollbar->SetBaseHeight(GetBaseHeight() - h - m_top_border - m_border);
727763
728 _vscrollbar->SetBaseX(geo.x + geo.GetWidth() - w - m_border);764 if (ltr)
765 _vscrollbar->SetBaseX(geo.x + geo.GetWidth() - w - m_border);
766 else
767 _vscrollbar->SetBaseX(geo.x + m_border);
729 _vscrollbar->SetBaseY(geo.y + m_top_border);768 _vscrollbar->SetBaseY(geo.y + m_top_border);
730 _vscrollbar->ComputeContentSize();769 _vscrollbar->ComputeContentSize();
731 }770 }
732771
=== modified file 'Nux/VSplitter.cpp'
--- Nux/VSplitter.cpp 2011-12-06 16:29:06 +0000
+++ Nux/VSplitter.cpp 2012-04-27 07:24:03 +0000
@@ -118,6 +118,7 @@
118 graphics_engine.PushClippingRectangle(GetGeometry());118 graphics_engine.PushClippingRectangle(GetGeometry());
119 Geometry base = GetGeometry();119 Geometry base = GetGeometry();
120 bool need_redraw = IsRedrawNeeded();120 bool need_redraw = IsRedrawNeeded();
121 bool ltr = GetDirection() == LeftToRight;
121122
122 std::vector<MySplitter *>::iterator it_splitter;123 std::vector<MySplitter *>::iterator it_splitter;
123 std::vector<Area *>::iterator it;124 std::vector<Area *>::iterator it;
@@ -127,10 +128,17 @@
127 it++, it_splitter++)128 it++, it_splitter++)
128 {129 {
129 Geometry sgeo = (*it_splitter)->GetGeometry();130 Geometry sgeo = (*it_splitter)->GetGeometry();
130 graphics_engine.PushClippingRectangle(Rect(131 Rect clip;
131 base.x, base.y, sgeo.x - base.x, base.GetHeight()));132 if (ltr)
133 clip = Rect(base.x, base.y, sgeo.x - base.x, base.GetHeight());
134 else
135 clip = Rect(sgeo.x + sgeo.GetWidth(), base.y, base.x + base.GetWidth() - sgeo.x - sgeo.GetWidth(), base.GetHeight());
136 graphics_engine.PushClippingRectangle(clip);
132137
133 base.SetX(sgeo.x + sgeo.GetWidth());138 if (ltr)
139 base.SetX(sgeo.x + sgeo.GetWidth());
140 else
141 base.SetWidth(sgeo.x - base.x);
134142
135 if (force_draw || need_redraw)143 if (force_draw || need_redraw)
136 {144 {
@@ -193,6 +201,7 @@
193 void VSplitter::OverlayDrawing(GraphicsEngine &graphics_engine)201 void VSplitter::OverlayDrawing(GraphicsEngine &graphics_engine)
194 {202 {
195 unsigned int num_element = (unsigned int) m_SplitterObject.size();203 unsigned int num_element = (unsigned int) m_SplitterObject.size();
204 bool ltr = GetDirection() == LeftToRight;
196205
197 Geometry base = GetGeometry();206 Geometry base = GetGeometry();
198207
@@ -203,27 +212,33 @@
203212
204 if (m_focus_splitter_index == 0 && num_element > 1)213 if (m_focus_splitter_index == 0 && num_element > 1)
205 {214 {
206 if (geo.x < base.x)215 if (( ltr && geo.x < base.x) ||
216 (!ltr && geo.x > base.x + base.GetWidth() - VSPLITTERWIDTH))
207 {217 {
208 geo.SetX(base.x);218 geo.SetX(base.x + (ltr ? 0 : (base.GetWidth() - VSPLITTERWIDTH)));
209 }219 }
210220
211 if (geo.x + VSPLITTERWIDTH > m_SplitterObject[m_focus_splitter_index + 1]->GetGeometry().x)221 if (( ltr && geo.x + VSPLITTERWIDTH > m_SplitterObject[m_focus_splitter_index + 1]->GetGeometry().x) ||
222 (!ltr && geo.x - VSPLITTERWIDTH < m_SplitterObject[m_focus_splitter_index + 1]->GetGeometry().x))
212 {223 {
213 geo.SetX(m_SplitterObject[m_focus_splitter_index+1]->GetGeometry().x - VSPLITTERWIDTH);224 geo.SetX(m_SplitterObject[m_focus_splitter_index+1]->GetGeometry().x + (ltr ? - VSPLITTERWIDTH : + VSPLITTERWIDTH));
214 }225 }
215 }226 }
216227
217 if ((m_focus_splitter_index > 0) && m_focus_splitter_index < (int) num_element - 1)228 if ((m_focus_splitter_index > 0) && m_focus_splitter_index < (int) num_element - 1)
218 {229 {
219 if (geo.x < m_SplitterObject[m_focus_splitter_index - 1]->GetGeometry().x + VSPLITTERWIDTH)230 if (( ltr && geo.x < m_SplitterObject[m_focus_splitter_index - 1]->GetGeometry().x + VSPLITTERWIDTH) ||
231 (!ltr && geo.x > m_SplitterObject[m_focus_splitter_index - 1]->GetGeometry().x - VSPLITTERWIDTH))
220 {232 {
221 geo.SetX(m_SplitterObject[m_focus_splitter_index - 1]->GetGeometry().x + VSPLITTERWIDTH);233 geo.SetX(m_SplitterObject[m_focus_splitter_index - 1]->GetGeometry().x +
234 (ltr ? VSPLITTERWIDTH : - VSPLITTERWIDTH));
222 }235 }
223236
224 if (geo.x + VSPLITTERWIDTH > m_SplitterObject[m_focus_splitter_index + 1]->GetGeometry().x)237 if (( ltr && geo.x + VSPLITTERWIDTH > m_SplitterObject[m_focus_splitter_index + 1]->GetGeometry().x) ||
238 (!ltr && geo.x - VSPLITTERWIDTH < m_SplitterObject[m_focus_splitter_index + 1]->GetGeometry().x))
225 {239 {
226 geo.SetX(m_SplitterObject[m_focus_splitter_index + 1]->GetGeometry().x - VSPLITTERWIDTH);240 geo.SetX(m_SplitterObject[m_focus_splitter_index + 1]->GetGeometry().x +
241 (ltr ? - VSPLITTERWIDTH : VSPLITTERWIDTH));
227 }242 }
228 }243 }
229244
@@ -265,6 +280,7 @@
265280
266 long VSplitter::ComputeContentSize()281 long VSplitter::ComputeContentSize()
267 {282 {
283 bool ltr = GetDirection() == LeftToRight;
268 unsigned int num_element = (unsigned int) m_InterfaceObject.size();284 unsigned int num_element = (unsigned int) m_InterfaceObject.size();
269 int x = GetBaseX();285 int x = GetBaseX();
270 int y = GetBaseY();286 int y = GetBaseY();
@@ -312,7 +328,11 @@
312 {328 {
313 int size_to_distribute = w - num_element * VSPLITTERWIDTH;329 int size_to_distribute = w - num_element * VSPLITTERWIDTH;
314 int previous_spliter_end = m_current_x;330 int previous_spliter_end = m_current_x;
331 if (!ltr)
332 previous_spliter_end += m_current_width;
315 int new_spliter_end = x;333 int new_spliter_end = x;
334 if (!ltr)
335 new_spliter_end += w;
316336
317 for (unsigned int i = 0; i < num_element; i++)337 for (unsigned int i = 0; i < num_element; i++)
318 {338 {
@@ -320,37 +340,64 @@
320 // compute percentage of space occupied by the element i;340 // compute percentage of space occupied by the element i;
321 // width of element i = m_SplitterObject[i]->GetX() - previous_splliter_end341 // width of element i = m_SplitterObject[i]->GetX() - previous_splliter_end
322 int splitter_start = m_SplitterObject[i]->GetBaseX();342 int splitter_start = m_SplitterObject[i]->GetBaseX();
343 if (!ltr)
344 splitter_start += VSPLITTERWIDTH;
323 float percent = float(splitter_start - previous_spliter_end) / float(m_current_width - num_element * VSPLITTERWIDTH);345 float percent = float(splitter_start - previous_spliter_end) / float(m_current_width - num_element * VSPLITTERWIDTH);
346 if (!ltr)
347 percent = -percent;
324348
325 if (percent > 1.0f)349 if (percent > 1.0f)
326 percent = 1.0f;350 percent = 1.0f;
327351
328 splitter_geo.SetX(new_spliter_end + size_to_distribute * percent);352 if (ltr)
329 previous_spliter_end = splitter_start + VSPLITTERWIDTH;353 {
330 new_spliter_end = new_spliter_end + size_to_distribute * percent + VSPLITTERWIDTH;354 splitter_geo.SetX(new_spliter_end + size_to_distribute * percent);
355 previous_spliter_end = splitter_start + VSPLITTERWIDTH;
356 new_spliter_end = new_spliter_end + size_to_distribute * percent + VSPLITTERWIDTH;
357 }
358 else
359 {
360 splitter_geo.SetX(new_spliter_end - size_to_distribute * percent - VSPLITTERWIDTH);
361 previous_spliter_end = splitter_start - VSPLITTERWIDTH;
362 new_spliter_end = new_spliter_end - size_to_distribute * percent + VSPLITTERWIDTH;
363 }
331 m_SplitterObject[i]->SetGeometry(splitter_geo);364 m_SplitterObject[i]->SetGeometry(splitter_geo);
332 }365 }
333366
334 if (m_SplitterObject[0]->GetBaseX() < x)367 if (ltr && m_SplitterObject[0]->GetBaseX() < x)
335 {368 {
336 m_SplitterObject[0]->SetBaseX(x);369 m_SplitterObject[0]->SetBaseX(x);
337 }370 }
371 else if (!ltr && m_SplitterObject[0]->GetBaseX() > x + w - VSPLITTERWIDTH)
372 {
373 m_SplitterObject[0]->SetBaseX(x + w - VSPLITTERWIDTH);
374 }
338375
339 m_SplitterObject[num_element-1]->SetBaseX(x + w - VSPLITTERWIDTH);376 if (ltr)
377 m_SplitterObject[num_element-1]->SetBaseX(x + w - VSPLITTERWIDTH);
378 else
379 m_SplitterObject[num_element-1]->SetBaseX(x);
340 }380 }
341381
342 int accwidth = x;382 int accwidth = x;
383 if (!ltr)
384 accwidth += w;
343385
344 for (unsigned int i = 0; i < num_element; i++)386 for (unsigned int i = 0; i < num_element; i++)
345 {387 {
346 Geometry splitter_geo = m_SplitterObject[i]->GetGeometry();388 Geometry splitter_geo = m_SplitterObject[i]->GetGeometry();
389 Geometry element_geo;
390 if (ltr)
391 element_geo = Geometry(accwidth, y, splitter_geo.x - accwidth, h);
392 else
393 element_geo = Geometry(splitter_geo.x + VSPLITTERWIDTH, y, accwidth - splitter_geo.x - VSPLITTERWIDTH, h);
347394
348 //m_InterfaceObject[i]->SetGeometry(Geometry(accwidth, y, splitter_geo.x - accwidth, h));395 //m_InterfaceObject[i]->SetGeometry(element_geo);
349396
350 if (m_InterfaceObject[i]->Type().IsDerivedFromType(View::StaticObjectType))397 if (m_InterfaceObject[i]->Type().IsDerivedFromType(View::StaticObjectType))
351 {398 {
352 View *ic = NUX_STATIC_CAST(View *, m_InterfaceObject[i]);399 View *ic = NUX_STATIC_CAST(View *, m_InterfaceObject[i]);
353 ic->SetGeometry(Geometry(accwidth, y, splitter_geo.x - accwidth, h));400 ic->SetGeometry(element_geo);
354 // if we are already computing the layout from the main window down, we need to call401 // if we are already computing the layout from the main window down, we need to call
355 // ComputeElementLayout to force the computing of this element layout.402 // ComputeElementLayout to force the computing of this element layout.
356 GetWindowThread()->ComputeElementLayout(ic);403 GetWindowThread()->ComputeElementLayout(ic);
@@ -358,18 +405,21 @@
358 else if (m_InterfaceObject[i]->Type().IsObjectType(InputArea::StaticObjectType))405 else if (m_InterfaceObject[i]->Type().IsObjectType(InputArea::StaticObjectType))
359 {406 {
360 InputArea *base_area = NUX_STATIC_CAST(InputArea *, m_InterfaceObject[i]);407 InputArea *base_area = NUX_STATIC_CAST(InputArea *, m_InterfaceObject[i]);
361 base_area->SetGeometry(Geometry(accwidth, y, splitter_geo.x - accwidth, h));408 base_area->SetGeometry(element_geo);
362 }409 }
363 else if (m_InterfaceObject[i]->Type().IsDerivedFromType(Layout::StaticObjectType))410 else if (m_InterfaceObject[i]->Type().IsDerivedFromType(Layout::StaticObjectType))
364 {411 {
365 Layout *layout = NUX_STATIC_CAST(Layout *, m_InterfaceObject[i]);412 Layout *layout = NUX_STATIC_CAST(Layout *, m_InterfaceObject[i]);
366 layout->SetGeometry(Geometry(accwidth, y, splitter_geo.x - accwidth, h));413 layout->SetGeometry(element_geo);
367 // if we are already computing the layout from the main window down, we need to call414 // if we are already computing the layout from the main window down, we need to call
368 // ComputeElementLayout to force the computing of this element layout.415 // ComputeElementLayout to force the computing of this element layout.
369 GetWindowThread()->ComputeElementLayout(layout);416 GetWindowThread()->ComputeElementLayout(layout);
370 }417 }
371418
372 accwidth += splitter_geo.x - accwidth + VSPLITTERWIDTH;419 if (ltr)
420 accwidth += splitter_geo.x - accwidth + VSPLITTERWIDTH;
421 else
422 accwidth = splitter_geo.x;
373 }423 }
374424
375 m_current_height = h;425 m_current_height = h;
@@ -382,7 +432,10 @@
382432
383 void VSplitter::ResetSplitConfig()433 void VSplitter::ResetSplitConfig()
384 {434 {
435 bool ltr = GetDirection() == LeftToRight;
385 int x = GetBaseX();436 int x = GetBaseX();
437 if (!ltr)
438 x += GetBaseWidth();
386 int y = GetBaseY();439 int y = GetBaseY();
387 int w = GetBaseWidth();440 int w = GetBaseWidth();
388 int h = GetBaseHeight();441 int h = GetBaseHeight();
@@ -420,12 +473,18 @@
420 for (unsigned int i = 0; i < (unsigned int) m_SplitConfig.size(); i++)473 for (unsigned int i = 0; i < (unsigned int) m_SplitConfig.size(); i++)
421 {474 {
422 stretchfactor = m_SplitConfig[i];475 stretchfactor = m_SplitConfig[i];
423 x += stretchfactor * max_size / max_stretch;476 if (ltr)
477 x += stretchfactor * max_size / max_stretch;
478 else
479 x -= stretchfactor * max_size / max_stretch + VSPLITTERWIDTH;
424 Geometry geo(x, y, VSPLITTERWIDTH, h);480 Geometry geo(x, y, VSPLITTERWIDTH, h);
425 m_SplitterObject[i]->SetGeometry(geo);481 m_SplitterObject[i]->SetGeometry(geo);
426 }482 }
427483
428 m_SplitterObject[num_element-1]->SetBaseX(x + w - VSPLITTERWIDTH);484 if (ltr)
485 m_SplitterObject[num_element-1]->SetBaseX(GetBaseX() + w - VSPLITTERWIDTH);
486 else
487 m_SplitterObject[num_element-1]->SetBaseX(GetBaseX());
429488
430 m_initial_config = true;489 m_initial_config = true;
431 }490 }
@@ -443,6 +502,7 @@
443502
444 void VSplitter::OnSplitterMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags, int header_pos)503 void VSplitter::OnSplitterMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags, int header_pos)
445 {504 {
505 bool ltr = GetDirection() == LeftToRight;
446 if (mvt_dx)506 if (mvt_dx)
447 {507 {
448 Geometry geo = m_SplitterObject[header_pos]->GetGeometry();508 Geometry geo = m_SplitterObject[header_pos]->GetGeometry();
@@ -453,8 +513,9 @@
453 if (header_pos < (int) num_element - 1)513 if (header_pos < (int) num_element - 1)
454 {514 {
455 // Make the splitter bar stick to the next one if the distance between them is less than VSTICK_SIZE515 // Make the splitter bar stick to the next one if the distance between them is less than VSTICK_SIZE
456 if (m_SplitterObject[header_pos + 1]->GetGeometry().x - geo.x - VSPLITTERWIDTH < VSTICK_SIZE)516 if (( ltr && m_SplitterObject[header_pos + 1]->GetGeometry().x - geo.x - VSPLITTERWIDTH < VSTICK_SIZE) ||
457 geo.SetX( m_SplitterObject[header_pos + 1]->GetGeometry().x - VSPLITTERWIDTH );517 (!ltr && m_SplitterObject[header_pos + 1]->GetGeometry().x - geo.x + VSPLITTERWIDTH > -VSTICK_SIZE))
518 geo.SetX( m_SplitterObject[header_pos + 1]->GetGeometry().x + (ltr ? - VSPLITTERWIDTH : + VSPLITTERWIDTH));
458 }519 }
459520
460 m_SplitterObject[header_pos]->SetGeometry(geo);521 m_SplitterObject[header_pos]->SetGeometry(geo);
@@ -505,15 +566,22 @@
505 {566 {
506 Geometry geo = m_SplitterObject[header_pos]->GetGeometry();567 Geometry geo = m_SplitterObject[header_pos]->GetGeometry();
507 int num_element = (int) m_SplitterObject.size();568 int num_element = (int) m_SplitterObject.size();
569 bool ltr = GetDirection() == LeftToRight;
570 int leftmost_x = GetBaseX();
571 int rightmost_x = GetBaseX() + GetBaseWidth() - VSPLITTERWIDTH;
508572
509 if ((header_pos == 0) && (m_SplitterObject[header_pos]->GetBaseX() < GetBaseX()))573 if ((header_pos == 0) && (
574 ( ltr && m_SplitterObject[header_pos]->GetBaseX() < leftmost_x) ||
575 (!ltr && m_SplitterObject[header_pos]->GetBaseX() > rightmost_x)))
510 {576 {
511 m_SplitterObject[header_pos]->SetBaseX(GetBaseX());577 m_SplitterObject[header_pos]->SetBaseX(ltr ? leftmost_x : rightmost_x);
512 }578 }
513579
514 if ((header_pos == num_element - 1) && (m_SplitterObject[header_pos]->GetBaseX() > GetBaseX() + GetBaseWidth() - VSPLITTERWIDTH))580 if ((header_pos == num_element - 1) && (
581 ( ltr && m_SplitterObject[header_pos]->GetBaseX() > rightmost_x) ||
582 (!ltr && m_SplitterObject[header_pos]->GetBaseX() < leftmost_x)))
515 {583 {
516 m_SplitterObject[header_pos]->SetBaseX(GetBaseX() + GetBaseWidth() - VSPLITTERWIDTH);584 m_SplitterObject[header_pos]->SetBaseX(ltr ? rightmost_x : leftmost_x);
517 }585 }
518586
519 if (header_pos < (int) num_element - 1)587 if (header_pos < (int) num_element - 1)
@@ -522,9 +590,10 @@
522 posx0 = m_SplitterObject[header_pos]->GetBaseX();590 posx0 = m_SplitterObject[header_pos]->GetBaseX();
523 posx1 = m_SplitterObject[header_pos + 1]->GetBaseX();591 posx1 = m_SplitterObject[header_pos + 1]->GetBaseX();
524592
525 if (posx0 > posx1 - VSPLITTERWIDTH)593 if (( ltr && posx0 > posx1 - VSPLITTERWIDTH) ||
594 (!ltr && posx0 < posx1 + VSPLITTERWIDTH))
526 {595 {
527 posx0 = posx1 - VSPLITTERWIDTH;596 posx0 = posx1 + (ltr ? - VSPLITTERWIDTH : + VSPLITTERWIDTH);
528 m_SplitterObject[header_pos]->SetBaseX(posx0);597 m_SplitterObject[header_pos]->SetBaseX(posx0);
529 }598 }
530 }599 }
@@ -535,9 +604,10 @@
535 posx0 = m_SplitterObject[header_pos]->GetBaseX();604 posx0 = m_SplitterObject[header_pos]->GetBaseX();
536 posx1 = m_SplitterObject[header_pos - 1]->GetBaseX();605 posx1 = m_SplitterObject[header_pos - 1]->GetBaseX();
537606
538 if (posx0 < posx1 + VSPLITTERWIDTH)607 if (( ltr && posx0 < posx1 + VSPLITTERWIDTH) ||
608 (!ltr && posx0 > posx1 - VSPLITTERWIDTH))
539 {609 {
540 posx0 = posx1 + VSPLITTERWIDTH;610 posx0 = posx1 + (ltr ? VSPLITTERWIDTH : - VSPLITTERWIDTH);
541 m_SplitterObject[header_pos]->SetBaseX(posx0);611 m_SplitterObject[header_pos]->SetBaseX(posx0);
542 }612 }
543 }613 }
544614
=== modified file 'tests/Helpers.cpp'
--- tests/Helpers.cpp 2011-07-15 04:00:00 +0000
+++ tests/Helpers.cpp 2012-04-27 07:24:03 +0000
@@ -25,11 +25,16 @@
25#include <fstream>25#include <fstream>
26#include <stdexcept>26#include <stdexcept>
2727
28#include <Nux/Nux.h>
29
28namespace nux30namespace nux
29{31{
30namespace testing32namespace testing
31{33{
3234
35nux::TimerFunctor* g_timer = NULL;
36nux::TimerHandle g_handler = NULL;
37
33std::string ReadFile(std::string const& filename)38std::string ReadFile(std::string const& filename)
34{39{
35 std::ifstream input(filename.c_str());40 std::ifstream input(filename.c_str());
@@ -47,6 +52,48 @@
47 }52 }
48}53}
4954
5055struct ThreadData
51}56{
52}57 TestFunc func;
58 nux::TimerFunctor* timer;
59 nux::TimerHandle handler;
60
61 ThreadData(TestFunc func) : func(func), timer(NULL) {}
62};
63
64void
65terminate (void* data)
66{
67 nux::WindowThread* thread = NUX_STATIC_CAST (nux::WindowThread*, data);
68 thread->ExitMainLoop();
69}
70
71void
72init (nux::NThread* thread, void* data)
73{
74 TestFunc func = (TestFunc) data;
75
76 (func) ();
77
78 g_timer = new nux::TimerFunctor ();
79 g_timer->time_expires.connect (sigc::ptr_fun (&terminate));
80 g_handler = nux::GetTimer().AddTimerHandler (100,
81 g_timer,
82 nux::GetWindowThread ());
83}
84
85void
86run_test (TestFunc func)
87{
88 nux::WindowThread* wt = NULL;
89
90 wt = nux::CreateGUIThread (TEXT ("Canvas Test"), 400, 400, 0, &init, (void*) func);
91 wt->Run (NULL);
92 delete wt;
93 delete g_timer;
94 g_timer = NULL;
95}
96
97}
98}
99
53100
=== modified file 'tests/Helpers.h'
--- tests/Helpers.h 2011-07-15 04:00:00 +0000
+++ tests/Helpers.h 2012-04-27 07:24:03 +0000
@@ -26,7 +26,6 @@
26#include <glib.h>26#include <glib.h>
27#include <sigc++/sigc++.h>27#include <sigc++/sigc++.h>
2828
29
30namespace nux29namespace nux
31{30{
32namespace testing31namespace testing
@@ -56,6 +55,8 @@
56 bool happened;55 bool happened;
57};56};
5857
58typedef void (*TestFunc)(void);
59void run_test(TestFunc func);
5960
60}61}
61}62}
6263
=== modified file 'tests/Makefile.am'
--- tests/Makefile.am 2012-03-28 18:29:23 +0000
+++ tests/Makefile.am 2012-04-27 07:24:03 +0000
@@ -64,6 +64,8 @@
64 -lboost_filesystem -lboost_system64 -lboost_filesystem -lboost_system
6565
66gtest_nux_SOURCES = \66gtest_nux_SOURCES = \
67 Helpers.h \
68 Helpers.cpp \
67 gtest-nux-area.cpp \69 gtest-nux-area.cpp \
68 gtest-nux-cairo-wrapper.cpp \70 gtest-nux-cairo-wrapper.cpp \
69 gtest-nux-emmetrics.cpp \71 gtest-nux-emmetrics.cpp \
@@ -72,7 +74,8 @@
72 gtest-nux-textentry.cpp \74 gtest-nux-textentry.cpp \
73 gtest-nux-view.cpp \75 gtest-nux-view.cpp \
74 gtest-nux-windowcompositor.cpp \76 gtest-nux-windowcompositor.cpp \
75 gtest-nux-windowthread.cpp77 gtest-nux-windowthread.cpp \
78 gtest-nux-hlayout.cpp
7679
77gtest_nux_CPPFLAGS = \80gtest_nux_CPPFLAGS = \
78 -I$(srcdir) \81 -I$(srcdir) \
7982
=== modified file 'tests/gtest-nux-cairo-wrapper.cpp'
--- tests/gtest-nux-cairo-wrapper.cpp 2012-02-24 05:40:23 +0000
+++ tests/gtest-nux-cairo-wrapper.cpp 2012-04-27 07:24:03 +0000
@@ -26,10 +26,9 @@
2626
27#include <iostream>27#include <iostream>
2828
29typedef void (*TestFunc)(void);29#include "Helpers.h"
3030
31nux::TimerFunctor* g_timer = NULL;31using nux::testing::run_test;
32nux::TimerHandle g_handler = NULL;
3332
34void33void
35callback_one (nux::Geometry const& geom, cairo_t* cr)34callback_one (nux::Geometry const& geom, cairo_t* cr)
@@ -70,39 +69,6 @@
70}69}
7170
72void71void
73terminate (void* data)
74{
75 nux::WindowThread* thread = NUX_STATIC_CAST (nux::WindowThread*, data);
76 thread->ExitMainLoop();
77}
78
79void
80init (nux::NThread* thread, void* data)
81{
82 TestFunc func = (TestFunc) data;
83
84 (func) ();
85
86 g_timer = new nux::TimerFunctor ();
87 g_timer->time_expires.connect (sigc::ptr_fun (&terminate));
88 g_handler = nux::GetTimer().AddTimerHandler (100,
89 g_timer,
90 nux::GetWindowThread ());
91}
92
93void
94run_test (TestFunc func)
95{
96 nux::WindowThread* wt = NULL;
97
98 wt = nux::CreateGUIThread (TEXT ("Canvas Test"), 400, 400, 0, &init, (void*) func);
99 wt->Run (NULL);
100 delete wt;
101 delete g_timer;
102 g_timer = NULL;
103}
104
105void
106test_construction ()72test_construction ()
107{73{
108 nux::Geometry geom_one = {0, 0, 100, 100};74 nux::Geometry geom_one = {0, 0, 100, 100};
10975
=== added file 'tests/gtest-nux-hlayout.cpp'
--- tests/gtest-nux-hlayout.cpp 1970-01-01 00:00:00 +0000
+++ tests/gtest-nux-hlayout.cpp 2012-04-27 07:24:03 +0000
@@ -0,0 +1,121 @@
1/*
2 * Copyright 2011
3 *
4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License version 3, as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranties of
10 * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
11 * PURPOSE. See the applicable version of the GNU Lesser General Public
12 * License for more details.
13 *
14 * You should have received a copy of both the GNU Lesser General Public
15 * License version 3 along with this program. If not, see
16 * <http://www.gnu.org/licenses/>
17 *
18 * Authored by: Haggai Eran <haggai.eran@gmail.com>
19 *
20 */
21
22#include <gmock/gmock.h>
23
24#include "Nux/Nux.h"
25#include "Nux/HLayout.h"
26
27#include "Helpers.h"
28
29#include <iostream>
30#include <list>
31
32using namespace testing;
33using nux::testing::run_test;
34
35using nux::HLayout;
36using nux::Area;
37using nux::Geometry;
38
39using std::ostream;
40using std::list;
41
42namespace {
43
44ostream& operator<<(ostream& out, const Geometry& r)
45{
46 return out << "Geometry(" << r.x << ", " << r.y << ", " << r.width << ", " << r.height << ")";
47}
48
49list<Area*> fill_test_layout(HLayout* layout)
50{
51 EXPECT_THAT(layout, NotNull());
52
53 list<Area*> areas;
54
55 for (int i = 0; i < 3; ++i)
56 {
57 Area* area = new Area(NUX_TRACKER_LOCATION);
58 EXPECT_THAT(area, NotNull());
59 area->SetMinimumSize(50, 60);
60 layout->AddView(area);
61 areas.push_back(area);
62 }
63
64 return areas;
65}
66
67void test_hlayout_ltr()
68{
69 nux::SetDefaultDirection(nux::LeftToRight);
70
71 HLayout* layout = new HLayout(NUX_TRACKER_LOCATION);
72 list<Area*> areas = fill_test_layout(layout);
73
74 Geometry geo(10,10,300,100);
75 layout->SetGeometry(geo);
76 layout->ComputeContentPosition(0, 0);
77
78 EXPECT_EQ(geo, layout->GetGeometry());
79
80 list<Area*>::const_iterator it = areas.begin();
81 for (int i = 0; it != areas.end(); ++i, ++it)
82 {
83 geo = Geometry(10 + 50 * i, 10, 50, 60);
84 EXPECT_EQ(geo, (*it)->GetGeometry());
85 }
86
87 layout->UnReference();
88}
89
90void test_hlayout_rtl()
91{
92 nux::SetDefaultDirection(nux::RightToLeft);
93
94 HLayout* layout = new HLayout(NUX_TRACKER_LOCATION);
95 list<Area*> areas = fill_test_layout(layout);
96
97 Geometry geo(10,10,300,100);
98 layout->SetGeometry(geo);
99 layout->ComputeContentPosition(0, 0);
100
101 EXPECT_EQ(geo, layout->GetGeometry());
102
103 list<Area*>::const_iterator it = areas.begin();
104 for (int i = 0; it != areas.end(); ++i, ++it)
105 {
106 geo = Geometry(310 - 50 * (i + 1), 10, 50, 60);
107 EXPECT_EQ(geo, (*it)->GetGeometry());
108 }
109
110 layout->UnReference();
111}
112
113TEST(TestHLayout, LTR) {
114 run_test(test_hlayout_ltr);
115}
116
117TEST(TestHLayout, RTL) {
118 run_test(test_hlayout_rtl);
119}
120
121}

Subscribers

People subscribed via source and target branches