Nux

Merge lp:~haggai-eran/nux/rtl-rebased into lp:nux/2.0

Proposed by Haggai Eran
Status: Superseded
Proposed branch: lp:~haggai-eran/nux/rtl-rebased
Merge into: lp:nux/2.0
Diff against target: 678 lines (+207/-97)
7 files modified
Nux/Area.cpp (+11/-0)
Nux/Area.h (+16/-0)
Nux/HLayout.cpp (+146/-97)
Nux/Layout.cpp (+16/-0)
Nux/Layout.h (+3/-0)
Nux/Nux.cpp (+12/-0)
Nux/Nux.h (+3/-0)
To merge this branch: bzr merge lp:~haggai-eran/nux/rtl-rebased
Reviewer Review Type Date Requested Status
Jay Taoko Pending
Review via email: mp+82225@code.launchpad.net

This proposal has been superseded by a proposal from 2012-04-27.

Commit message

Add right-to-left mirroring support. Implement mirroring for HLayout.

Description of the change

Hi,

Here's my branch rebased against trunk. I hope the changes are more clear now.

There's still a problem with this patch to HLayout, though. When in right-to-left state, it packs child elements to the layout starting from the last on the list, instead of starting from the first, in order to get them in reverse order. However, it seems that for some of the widgets this doesn't work very well. I checked the CheckBox example, and the AbstractCheckedButton::ComputeContentSize code depends on the fact that the HLayout will first allocate space to the checkbox, and afterwards to the label. When using a right-to-left direction, the label is laid out first, and then the checkbox is positioned out of the widget's bounds.

Should I change my patch to pack the children in their logical order, starting from the rightmost edge, or should I leave the code as it is, and try to fix uses like the AbstractCheckedButton?

Regards,
Haggai

To post a comment you must log in.
Revision history for this message
Jay Taoko (jaytaoko) wrote :

Haggai

Selecting right to left has to be done per layout. Lets say you have an horizontal layout that has a checkbox followed by a button, and the button is followed by a combobox. In LTR order you get this:
 checkbox | button | combobox

If you make the HLayout to be RTL then the content will look like this:

 combobox| button | checkbox

This should work out fine because only a specific HLayout has been been changed to RTL.

So you have to select only the layouts of the interface that need to be inverted. Rather than having SetDefaultDirection in Nux.cpp, it should be a function member of LinearLayout. Then for each layout (HLayout or VLayout), you will be able to decide if it goes from LTR or RTL. Individual views like the Checkbox, will remain un-affected.

How about that?

Revision history for this message
Haggai Eran (haggai-eran) wrote :

Jay,

I agree that we should be able to set directionality on per-layout basis. I even implemented it as a member of Area. However, I think that the default when using an RTL locale should be right to left, for all widgets, and not just specific HLayouts.

In the example you described, you could show the detailed widgets like this (in LTR):

[ combobox ↓ | button | [x] checkbox ]

Then, I expect the RTL rendering to be like this:

[ checkbox [x] | button | ↓ combobox ]

The internal layout of comboboxes and checkboxes should also be mirrored.

Please compare how GTK looks in LTR and RTL in the following two screenshots of the widget factory:
http://i44.tinypic.com/2lks0e8.jpg
http://i43.tinypic.com/25ri0ds.png

Haggai

Revision history for this message
Jay Taoko (jaytaoko) wrote :

Ok, I see how it is. I think many widget will have to have support for a RTL design.
But first we can get this branch in since it has global support for RTL at the layout level. Then the next step would be to go to each individual widgets that requires it and review the design.

It is up to me now to review and adapt this branch and see that we can merge it. We now have the requirement of proposing tests along side major features. Can you think of some way we can test the features of this branch?

Revision history for this message
Haggai Eran (haggai-eran) wrote :

Hi,

I think that perhaps rewriting the code to pack in the same order as in LTR might still have some advantages. I've tried to think on how that would work. Instead of walking the list of HLayout children in reverse, and packing them to the left, I'll walk the list in the usual order, and pack from right to left.

As far as I can see, I would only need to change HLayout::ComputeContentSize, and HLayout::ComputeContentPosition, which would make the changes simpler. I'm sure in both cases other widget will need to be modified, but if any widget's layout depends on the order of children's placement, then that order wouldn't change.

Regarding tests, I suppose that a tests for HLayout can be modified to test the RTL case as well, but I cannot find such a test (perhaps my tree isn't updated). I imagine a test that creates an HLayout, with several children that are using different settings for scaling, vertical placement, etc. and asserting there placement. What do you think?

Unmerged revisions

521. By Haggai Eran

Change LayoutContentDistribution only when in RTL mode.

520. By Haggai Eran

More HLayout changes toward right-to-left support.

519. By Haggai Eran

Add right-to-left mirroring support. Implement mirroring for HLayout.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Nux/Area.cpp'
2--- Nux/Area.cpp 2011-10-18 21:10:05 +0000
3+++ Nux/Area.cpp 2011-11-14 21:17:09 +0000
4@@ -39,6 +39,7 @@
5 , geometry_(0, 0, DEFAULT_WIDGET_WIDTH, DEFAULT_WIDGET_HEIGHT)
6 , min_size_(AREA_MIN_WIDTH, AREA_MIN_HEIGHT)
7 , max_size_(AREA_MAX_WIDTH, AREA_MAX_HEIGHT)
8+ , _direction (GetDefaultDirection())
9 {
10 visible_ = true;
11 view_enabled_ = true;
12@@ -1026,5 +1027,15 @@
13
14 return false;
15 }
16+
17+ Direction Area::GetDirection() const
18+ {
19+ return _direction;
20+ }
21+
22+ void Area::SetDirection(Direction direction)
23+ {
24+ _direction = direction;
25+ }
26 }
27
28
29=== modified file 'Nux/Area.h'
30--- Nux/Area.h 2011-10-17 21:23:50 +0000
31+++ Nux/Area.h 2011-11-14 21:17:09 +0000
32@@ -140,6 +140,12 @@
33 KEY_NAV_ENTER,
34 };
35
36+ typedef enum
37+ {
38+ LeftToRight,
39+ RightToLeft
40+ } Direction;
41+
42 class Layout;
43 class View;
44 class Area;
45@@ -547,6 +553,14 @@
46 */
47 bool AcceptMouseWheelEvent() const;
48
49+ //! Return the direction of the area.
50+ Direction GetDirection() const;
51+ //! Sets the direction of the area.
52+ /*!
53+ @param direction Either nux::LeftToRight or nux::RightToLeft
54+ */
55+ void SetDirection(Direction direction);
56+
57 protected:
58 /*
59 This function is reimplemented in Layout as it need to perform some special operations.
60@@ -633,6 +647,8 @@
61 bool _accept_mouse_wheel_event;
62 bool _accept_keyboard_event;
63
64+ Direction _direction;
65+
66 friend class Layout;
67 friend class View;
68 friend class WindowThread;
69
70=== modified file 'Nux/HLayout.cpp'
71--- Nux/HLayout.cpp 2011-10-21 22:06:35 +0000
72+++ Nux/HLayout.cpp 2011-11-14 21:17:09 +0000
73@@ -127,7 +127,7 @@
74 margin = 0;
75 }
76
77- LayoutContentDistribution stacking = GetContentDistribution();
78+ LayoutContentDistribution stacking = GetEffectiveContentDistribution();
79
80 switch(stacking)
81 {
82@@ -178,6 +178,8 @@
83 }
84
85 std::list<Area *>::iterator it;
86+ std::list<Area *>::reverse_iterator revit;
87+ Area* area;
88
89 for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++)
90 {
91@@ -248,19 +250,24 @@
92 ComputeStacking(width, offset_space, space_after_element);
93 current_x += offset_space;
94
95- for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++)
96+ revit = _layout_element_list.rbegin();
97+ for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++, revit++)
98 {
99- if (!(*it)->IsVisible())
100+ if (GetDirection() == LeftToRight)
101+ area = *it;
102+ else
103+ area = *revit;
104+ if (!area->IsVisible())
105 continue;
106
107 current_x += space_after_element;
108
109- (*it)->SetBaseX(current_x);
110- (*it)->SetBaseY(current_y);
111+ area->SetBaseX(current_x);
112+ area->SetBaseY(current_y);
113
114- MinorDimensionSize extend = (*it)->GetExtend();
115- MinorDimensionPosition positioning = (*it)->GetPositioning();
116- float percentage = (*it)->GetPercentage();
117+ MinorDimensionSize extend = area->GetExtend();
118+ MinorDimensionPosition positioning = area->GetPositioning();
119+ float percentage = area->GetPercentage();
120
121 // Compute the size of an ellement in the minor dimension(vertical)
122 switch(extend)
123@@ -270,7 +277,7 @@
124 // The size of the processed element in the minor dimension is a percentage of layout minor dimension size.
125 // Note that children of the processed element may force it to have a bigger size.
126 int percentage_height = (height * percentage) / 100.0f;
127- (*it)->SetBaseHeight(percentage_height);
128+ area->SetBaseHeight(percentage_height);
129 break;
130 }
131
132@@ -278,7 +285,7 @@
133 {
134 // Force the element height to be the minimum has defined with SetMinimumHeight.
135 // The children of this element can force it to get larger.
136- (*it)->ApplyMinHeight();
137+ area->ApplyMinHeight();
138 break;
139 }
140
141@@ -291,30 +298,30 @@
142 case MINOR_SIZE_FULL:
143 default:
144 {
145- (*it)->SetBaseHeight(height);
146+ area->SetBaseHeight(height);
147 break;
148 }
149 }
150
151 // Compute the position of an element in the minor dimension.
152- if ((*it)->GetBaseHeight() < height)
153+ if (area->GetBaseHeight() < height)
154 {
155- int widget_height = (*it)->GetBaseHeight();
156+ int widget_height = area->GetBaseHeight();
157
158 switch(positioning)
159 {
160 case MINOR_POSITION_START:
161 {
162 // do nothing
163- (*it)->SetBaseY(current_y);
164+ area->SetBaseY(current_y);
165 break;
166 }
167 case MINOR_POSITION_END:
168 {
169 if (widget_height < height)
170- (*it)->SetBaseY(current_y + height - widget_height);
171+ area->SetBaseY(current_y + height - widget_height);
172 else
173- (*it)->SetBaseY(current_y);
174+ area->SetBaseY(current_y);
175
176 break;
177 }
178@@ -323,14 +330,14 @@
179 default:
180 {
181 if (widget_height < height)
182- (*it)->SetBaseY(current_y + (height - widget_height) / 2);
183+ area->SetBaseY(current_y + (height - widget_height) / 2);
184 else
185- (*it)->SetBaseY(current_y);
186+ area->SetBaseY(current_y);
187 }
188 }
189 }
190
191- current_x += (*it)->GetBaseWidth() + space_after_element + space_between_children_;
192+ current_x += area->GetBaseWidth() + space_after_element + space_between_children_;
193 }
194
195 // Manage child layout
196@@ -351,9 +358,15 @@
197 // We check if that is the case and force a recompute.
198 std::vector<int> FullSizeUnadjusted;
199
200- for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++)
201+ revit = _layout_element_list.rbegin();
202+ for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++, revit++)
203 {
204- if (!(*it)->IsVisible())
205+ if (GetDirection() == LeftToRight)
206+ area = *it;
207+ else
208+ area = *revit;
209+
210+ if (!area->IsVisible())
211 continue;
212 bool smaller_height = false;
213 bool larger_height = false;
214@@ -361,16 +374,16 @@
215 bool smaller_width = false;
216 int ret = 0;
217
218- if (((*it)->IsLayout() || (*it)->IsView()) /*&& ((*it)->IsLayoutDone() == false)*/ /*&& ((*it)->GetScaleFactor() != 0)*/)
219+ if ((area->IsLayout() || area->IsView()) /*&& (area->IsLayoutDone() == false)*/ /*&& (area->GetScaleFactor() != 0)*/)
220 {
221- ret = (*it)->ComputeContentSize();
222+ ret = area->ComputeContentSize();
223
224 larger_width = (ret & eLargerWidth) ? true : false;
225 smaller_width = (ret & eSmallerWidth) ? true : false;
226 smaller_height = (ret & eSmallerHeight) ? true : false;
227 larger_height = (ret & eLargerHeight) ? true : false;
228
229- if ((larger_width || smaller_width) && ((*it)->IsLayoutDone() == false))
230+ if ((larger_width || smaller_width) && (area->IsLayoutDone() == false))
231 {
232 // Stop computing the size of this layout. Its size was not convenient to its children. So the children size take priority
233 // over the layout. In ComputeContentSize, the dimension of the layout has been set so it encompasses its children(and the margins).
234@@ -383,37 +396,37 @@
235
236 {
237 unadjusted_layout = true;
238- (*it)->SetLayoutDone(true);
239+ area->SetLayoutDone(true);
240 }
241 }
242
243- if ((smaller_height == false) && ((*it)->GetExtend() == MINOR_SIZE_FULL) && ((*it)->GetBaseHeight() < (*it)->GetMaximumHeight()))
244+ if ((smaller_height == false) && (area->GetExtend() == MINOR_SIZE_FULL) && (area->GetBaseHeight() < area->GetMaximumHeight()))
245 {
246 // We catch all object whose size is possibly larger than the layout. We check there size at the end and
247 // recompute the layout if necessary.
248 // For layout elements, make sure that the stretch factor is not 0. If it is, it means it will not use the
249 // size provided by the parent layout. Its size will be adjusted to the minimum size of the layout content.
250- if (! ((*it)->IsLayout() && (*it)->GetScaleFactor() == 0))
251- FullSizeUnadjusted.push_back((*it)->GetBaseHeight());
252+ if (! (area->IsLayout() && area->GetScaleFactor() == 0))
253+ FullSizeUnadjusted.push_back(area->GetBaseHeight());
254 }
255
256- if ((smaller_height || larger_height) && ((*it)->GetExtend() == MINOR_SIZE_MATCHCONTENT))
257+ if ((smaller_height || larger_height) && (area->GetExtend() == MINOR_SIZE_MATCHCONTENT))
258 {
259- (*it)->SetMinimumHeight((*it)->GetBaseHeight());
260+ area->SetMinimumHeight(area->GetBaseHeight());
261 unadjusted_layout = true;
262 }
263
264 // Should be reactivate so that if the parent Layout does not call
265 // ComputeContentPosition, at least it is done here to arrange the internal
266 // element of the children.
267- //(*it)->ComputeContentPosition(0,0);
268+ //area->ComputeContentPosition(0,0);
269 }
270
271- m_fittingWidth += (*it)->GetBaseWidth();
272-
273- element_height = (*it)->GetBaseHeight();
274-
275- if ((*it)->IsSpaceLayout() == false)
276+ m_fittingWidth += area->GetBaseWidth();
277+
278+ element_height = area->GetBaseHeight();
279+
280+ if (area->IsSpaceLayout() == false)
281 {
282 if ((GetScaleFactor() != 0) /* && (ret & eSmallerHeight)*/)
283 {
284@@ -434,7 +447,7 @@
285 m_contentHeight = element_height;
286 }
287
288-// else if ((*it)->GetExtend() == MINOR_SIZE_FULL)
289+// else if (area->GetExtend() == MINOR_SIZE_FULL)
290 // {
291 // unadjusted_layout = true;
292 // }
293@@ -525,15 +538,22 @@
294 int available_width = width;
295 unsigned int max_stretchfactor = GetMaxStretchFactor();
296 std::list<Area *>::iterator it;
297+ std::list<Area *>::reverse_iterator revit;
298+ Area* area;
299
300- for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++)
301+ revit = _layout_element_list.rbegin();
302+ for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++, revit++)
303 {
304- if (!(*it)->IsVisible())
305+ if (GetDirection() == LeftToRight)
306+ area = *it;
307+ else
308+ area = *revit;
309+ if (!area->IsVisible())
310 continue;
311
312- if (((*it)->GetScaleFactor() == 0) && ((*it)->IsLayoutDone() != true))
313+ if ((area->GetScaleFactor() == 0) && (area->IsLayoutDone() != true))
314 {
315- (*it)->ApplyMinWidth();
316+ area->ApplyMinWidth();
317 }
318 }
319
320@@ -570,27 +590,32 @@
321
322 if (available_width <= 2)
323 {
324- for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++)
325+ revit = _layout_element_list.rbegin();
326+ for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++, revit++)
327 {
328- if (!(*it)->IsVisible())
329+ if (GetDirection() == LeftToRight)
330+ area = *it;
331+ else
332+ area = *revit;
333+ if (!area->IsVisible())
334 continue;
335
336- if (((*it)->GetScaleFactor() != 0) && (*it)->IsArea())
337+ if ((area->GetScaleFactor() != 0) && area->IsArea())
338 {
339 // If it is not an object of type eInputArea, do not set layout_done_ to true,
340 // so, the layout management function will later be called on the object.
341- (*it)->ApplyMinWidth();
342- (*it)->SetLayoutDone(true);
343+ area->ApplyMinWidth();
344+ area->SetLayoutDone(true);
345 }
346- else if (((*it)->GetScaleFactor() != 0) && ((*it)->IsLayout()) && ((*it)->IsLayoutDone() == false)) // layout and not fixed by child
347+ else if ((area->GetScaleFactor() != 0) && (area->IsLayout()) && (area->IsLayoutDone() == false)) // layout and not fixed by child
348 {
349 // The out of bound must be reset to false.
350- (*it)->ApplyMinWidth();
351- (*it)->SetLayoutDone(false);
352+ area->ApplyMinWidth();
353+ area->SetLayoutDone(false);
354 }
355- else if (((*it)->GetScaleFactor() != 0) && ((*it)->IsLayoutDone() == false)) // layout and not fixed
356+ else if ((area->GetScaleFactor() != 0) && (area->IsLayoutDone() == false)) // layout and not fixed
357 {
358- (*it)->ApplyMinWidth();
359+ area->ApplyMinWidth();
360 // A layout must never have layout_done_ set to true "here" because it must continue
361 // doing the layout of its children and finally resize itself to fit them.
362 // The same way, A layout size factor should never be set to 0.
363@@ -604,20 +629,26 @@
364 Area *LastElementThatCanBeResized = 0;
365 int total_distributed_size = 0;
366
367- for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++)
368+ revit = _layout_element_list.rbegin();
369+ for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++, revit++)
370 {
371- if (!(*it)->IsVisible())
372+ if (GetDirection() == LeftToRight)
373+ area = *it;
374+ else
375+ area = *revit;
376+
377+ if (!area->IsVisible())
378 continue;
379
380- if (((*it)->GetScaleFactor() != 0) && ((*it)->IsLayoutDone() == false))
381+ if ((area->GetScaleFactor() != 0) && (area->IsLayoutDone() == false))
382 {
383- float sf = (float) (*it)->GetScaleFactor();
384+ float sf = (float) area->GetScaleFactor();
385 cumul += sf / max_stretchfactor;
386- LastElementThatCanBeResized = (*it);
387+ LastElementThatCanBeResized = area;
388 }
389 else
390 {
391- total_distributed_size += (*it)->GetBaseWidth();
392+ total_distributed_size += area->GetBaseWidth();
393 }
394 }
395
396@@ -633,14 +664,20 @@
397
398 need_recompute = false;;
399
400- for (it = _layout_element_list.begin(); it != _layout_element_list.end() && !need_recompute; it++)
401+ revit = _layout_element_list.rbegin();
402+ for (it = _layout_element_list.begin(); it != _layout_element_list.end() && !need_recompute; it++, revit++)
403 {
404- if (!(*it)->IsVisible())
405+ if (GetDirection() == LeftToRight)
406+ area = *it;
407+ else
408+ area = *revit;
409+
410+ if (!area->IsVisible())
411 continue;
412
413- if (((*it)->GetScaleFactor() != 0) && ((*it)->IsLayoutDone() == false))
414+ if ((area->GetScaleFactor() != 0) && (area->IsLayoutDone() == false))
415 {
416- unsigned int sf = (*it)->GetScaleFactor();
417+ unsigned int sf = area->GetScaleFactor();
418 int new_width;
419
420 if (sf == max_stretchfactor)
421@@ -654,7 +691,7 @@
422
423 total_distributed_size += new_width;
424
425- if (LastElementThatCanBeResized == (*it))
426+ if (LastElementThatCanBeResized == area)
427 {
428 // Redistribute the remaining size to the last element(at the right).
429 // This is necessary because of imprecision. For instance if available_height = 451 and we have 2 elements
430@@ -667,8 +704,8 @@
431 }
432 }
433
434- int elemt_max_width = (*it)->GetMaximumSize().width;
435- int elemt_min_width = (*it)->GetMinimumSize().width;
436+ int elemt_max_width = area->GetMaximumSize().width;
437+ int elemt_min_width = area->GetMinimumSize().width;
438
439 // A layout must never have layout_done_ set to true "here" because it must continue
440 // doing the layout of its children and finally resize itself to fit them.
441@@ -679,22 +716,22 @@
442 if (new_width < elemt_min_width)
443 {
444 // assume the minimum width
445- (*it)->SetBaseWidth(elemt_min_width);
446+ area->SetBaseWidth(elemt_min_width);
447
448- if ((*it)->IsLayout() == false || (*it)->IsSpaceLayout())
449+ if (area->IsLayout() == false || area->IsSpaceLayout())
450 {
451- (*it)->SetLayoutDone(true);
452+ area->SetLayoutDone(true);
453 need_recompute = true;
454 }
455 }
456 else if (new_width > elemt_max_width)
457 {
458 // assume the maximum width
459- (*it)->SetBaseWidth(elemt_max_width);
460+ area->SetBaseWidth(elemt_max_width);
461
462- if ((*it)->IsLayout() == false || (*it)->IsSpaceLayout())
463+ if (area->IsLayout() == false || area->IsSpaceLayout())
464 {
465- (*it)->SetLayoutDone(true);
466+ area->SetLayoutDone(true);
467 need_recompute = true;
468 }
469
470@@ -706,7 +743,7 @@
471 }
472 else
473 {
474- (*it)->SetBaseWidth(new_width);
475+ area->SetBaseWidth(new_width);
476 }
477 }
478 else
479@@ -714,10 +751,10 @@
480 // For fixed element, reset their size to the same so it is checked against
481 // the min and max. This is necessary in case you have set the size of the element first then latter,
482 // you define its MinimumSize and/or MaximumSize size.
483- unsigned int w = (*it)->GetBaseWidth();
484- unsigned int h = (*it)->GetBaseHeight();
485- (*it)->SetBaseWidth(w);
486- (*it)->SetBaseHeight(h);
487+ unsigned int w = area->GetBaseWidth();
488+ unsigned int h = area->GetBaseHeight();
489+ area->SetBaseWidth(w);
490+ area->SetBaseHeight(h);
491 }
492 }
493 }
494@@ -754,6 +791,8 @@
495 void HLayout::ComputeContentPosition(float offsetX, float offsetY)
496 {
497 std::list<Area *>::iterator it;
498+ std::list<Area *>::reverse_iterator revit;
499+ Area* area;
500 {
501 unsigned int num_element = 0;
502 for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++)
503@@ -778,37 +817,42 @@
504 ComputeStacking(width, offset_space, element_margin);
505 current_x += offset_space;
506
507- for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++)
508+ revit = _layout_element_list.rbegin();
509+ for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++, revit++)
510 {
511- if (!(*it)->IsVisible())
512+ if (GetDirection() == LeftToRight)
513+ area = *it;
514+ else
515+ area = *revit;
516+ if (!area->IsVisible())
517 continue;
518
519 current_x += element_margin;
520
521- (*it)->SetBaseX(current_x);
522- (*it)->SetBaseY(current_y);
523-
524- MinorDimensionSize extend = (*it)->GetExtend();
525- MinorDimensionPosition positioning = (*it)->GetPositioning();
526-
527- if ((*it)->GetBaseHeight() < height)
528+ area->SetBaseX(current_x);
529+ area->SetBaseY(current_y);
530+
531+ MinorDimensionSize extend = area->GetExtend();
532+ MinorDimensionPosition positioning = area->GetPositioning();
533+
534+ if (area->GetBaseHeight() < height)
535 {
536- int widget_height = (*it)->GetBaseHeight();
537+ int widget_height = area->GetBaseHeight();
538
539 switch(positioning)
540 {
541 case MINOR_POSITION_START:
542 {
543 // do nothing
544- (*it)->SetBaseY(current_y);
545+ area->SetBaseY(current_y);
546 break;
547 }
548 case MINOR_POSITION_END:
549 {
550 if (widget_height < height)
551- (*it)->SetBaseY(current_y + height - widget_height);
552+ area->SetBaseY(current_y + height - widget_height);
553 else
554- (*it)->SetBaseY(current_y);
555+ area->SetBaseY(current_y);
556
557 break;
558 }
559@@ -817,29 +861,34 @@
560 default:
561 {
562 if (widget_height < height)
563- (*it)->SetBaseY(current_y + (height - widget_height) / 2);
564+ area->SetBaseY(current_y + (height - widget_height) / 2);
565 else
566- (*it)->SetBaseY(current_y);
567+ area->SetBaseY(current_y);
568 }
569 }
570 }
571
572- current_x += (*it)->GetBaseWidth() + element_margin + space_between_children_;
573+ current_x += area->GetBaseWidth() + element_margin + space_between_children_;
574 }
575 }
576
577- for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++)
578+ revit = _layout_element_list.rbegin();
579+ for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++, revit++)
580 {
581- if (!(*it)->IsVisible())
582+ if (GetDirection() == LeftToRight)
583+ area = *it;
584+ else
585+ area = *revit;
586+ if (!area->IsVisible())
587 continue;
588
589- if ((*it)->Type().IsDerivedFromType(Layout::StaticObjectType))
590+ if (area->Type().IsDerivedFromType(Layout::StaticObjectType))
591 {
592- (*it)->ComputeContentPosition(offsetX, offsetY);
593+ area->ComputeContentPosition(offsetX, offsetY);
594 }
595- else if ((*it)->Type().IsDerivedFromType(View::StaticObjectType))
596+ else if (area->Type().IsDerivedFromType(View::StaticObjectType))
597 {
598- (*it)->ComputeContentPosition(offsetX, offsetY);
599+ area->ComputeContentPosition(offsetX, offsetY);
600 }
601 }
602 }
603
604=== modified file 'Nux/Layout.cpp'
605--- Nux/Layout.cpp 2011-10-17 20:57:35 +0000
606+++ Nux/Layout.cpp 2011-11-14 21:17:09 +0000
607@@ -557,6 +557,22 @@
608 return m_ContentStacking;
609 }
610
611+ LayoutContentDistribution Layout::GetEffectiveContentDistribution()
612+ {
613+ LayoutContentDistribution stacking = GetContentDistribution();
614+ if (GetDirection() == LeftToRight)
615+ return stacking;
616+ switch (stacking)
617+ {
618+ case eStackLeft:
619+ return eStackRight;
620+ case eStackRight:
621+ return eStackLeft;
622+ default:
623+ return stacking;
624+ }
625+ }
626+
627 void Layout::RequestBottomUpLayoutComputation(Area *bo_initiator)
628 {
629
630
631=== modified file 'Nux/Layout.h'
632--- Nux/Layout.h 2011-10-10 01:52:00 +0000
633+++ Nux/Layout.h 2011-11-14 21:17:09 +0000
634@@ -201,6 +201,9 @@
635 virtual void SetContentDistribution(LayoutContentDistribution stacking_order);
636 virtual LayoutContentDistribution GetContentDistribution();
637
638+ //! Switch the content distribution in case a RightToLeft direction is used
639+ LayoutContentDistribution GetEffectiveContentDistribution();
640+
641 virtual bool FindWidget(Area *WidgetObject) const;
642 virtual bool IsEmpty() const;
643 /*
644
645=== modified file 'Nux/Nux.cpp'
646--- Nux/Nux.cpp 2011-11-10 17:28:44 +0000
647+++ Nux/Nux.cpp 2011-11-14 21:17:09 +0000
648@@ -349,4 +349,16 @@
649 return NUX_STATIC_CAST(WindowThread *, thread)->GetGraphicsEngine();
650 }
651
652+ static Direction defaultDirection = LeftToRight;
653+
654+ Direction GetDefaultDirection()
655+ {
656+ return defaultDirection;
657+ }
658+
659+ void SetDefaultDirection(Direction direction)
660+ {
661+ defaultDirection = direction;
662+ }
663+
664 }
665
666=== modified file 'Nux/Nux.h'
667--- Nux/Nux.h 2011-10-21 22:06:35 +0000
668+++ Nux/Nux.h 2011-11-14 21:17:09 +0000
669@@ -150,6 +150,9 @@
670
671 inlDeclareThreadLocalStorage(NThread *, 0, ThreadLocal_InalogicAppImpl);
672
673+ Direction GetDefaultDirection();
674+ void SetDefaultDirection(Direction direction);
675+
676 }
677
678 #endif // NUX_H

Subscribers

People subscribed via source and target branches

to all changes: