Nux

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

Proposed by Didier Roche
Status: Needs review
Proposed branch: lp:~haggai-eran/nux/rtl-rebased
Merge into: lp:nux
Diff against target: 701 lines (+229/-89) (has conflicts)
7 files modified
Nux/Area.cpp (+11/-0)
Nux/Area.h (+16/-0)
Nux/HLayout.cpp (+152/-89)
Nux/Layout.cpp (+16/-0)
Nux/Layout.h (+3/-0)
Nux/Nux.cpp (+28/-0)
Nux/Nux.h (+3/-0)
Text conflict in Nux/HLayout.cpp
Text conflict in Nux/Nux.cpp
To merge this branch: bzr merge lp:~haggai-eran/nux/rtl-rebased
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Needs Fixing
Francis Ginther Abstain
Jay Taoko Pending
Review via email: mp+103814@code.launchpad.net

This proposal supersedes a proposal from 2011-11-14.

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 : Posted in a previous version of this proposal

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 : Posted in a previous version of this proposal

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 : Posted in a previous version of this proposal

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 : Posted in a previous version of this proposal

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?

Revision history for this message
Francis Ginther (fginther) wrote :

Review was claimed by accident, please ignore.

review: Abstain
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:521
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https://code.launchpad.net/~haggai-eran/nux/rtl-rebased/+merge/103814/+edit-commit-message

http://jenkins.qa.ubuntu.com/job/nux-ci/17/
Executed test runs:
    FAILURE: http://jenkins.qa.ubuntu.com/job/nux-raring-amd64-ci/17/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/nux-raring-armhf-ci/17/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/nux-raring-i386-ci/17/console

Click here to trigger a rebuild:
http://s-jenkins:8080/job/nux-ci/17/rebuild

review: Needs Fixing (continuous-integration)

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 2012-03-12 21:45:30 +0000
3+++ Nux/Area.cpp 2012-04-27 07:22:03 +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 window_thread_ = GetWindowThread();
11 visible_ = true;
12@@ -1035,5 +1036,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 2012-03-12 21:45:30 +0000
31+++ Nux/Area.h 2012-04-27 07:22:03 +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@@ -572,6 +578,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@@ -668,6 +682,8 @@
61
62 WindowThread* window_thread_;
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-12-10 06:39:14 +0000
72+++ Nux/HLayout.cpp 2012-04-27 07:22:03 +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
213 bool smaller_height = false;
214@@ -362,18 +375,22 @@
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+<<<<<<< TREE
222 Geometry pre_geo = (*it)->GetGeometry();
223 ret = (*it)->ComputeContentSize();
224 Geometry post_geo = (*it)->GetGeometry();
225+=======
226+ ret = area->ComputeContentSize();
227+>>>>>>> MERGE-SOURCE
228
229 larger_width = (pre_geo.width < post_geo.width) ? true : false;
230 smaller_width = (pre_geo.width > post_geo.width) ? true : false;
231 larger_height = (pre_geo.height < post_geo.height) ? true : false;
232 smaller_height = (pre_geo.height > post_geo.height) ? true : false;
233
234- if ((larger_width || smaller_width) && ((*it)->IsLayoutDone() == false))
235+ if ((larger_width || smaller_width) && (area->IsLayoutDone() == false))
236 {
237 // Stop computing the size of this layout. Its size was not convenient to its children. So the children size take priority
238 // over the layout. In ComputeContentSize, the dimension of the layout has been set so it encompasses its children(and the margins).
239@@ -386,37 +403,37 @@
240
241 {
242 unadjusted_layout = true;
243- (*it)->SetLayoutDone(true);
244+ area->SetLayoutDone(true);
245 }
246 }
247
248- if ((smaller_height == false) && ((*it)->GetExtend() == MINOR_SIZE_FULL) && ((*it)->GetBaseHeight() < (*it)->GetMaximumHeight()))
249+ if ((smaller_height == false) && (area->GetExtend() == MINOR_SIZE_FULL) && (area->GetBaseHeight() < area->GetMaximumHeight()))
250 {
251 // We catch all object whose size is possibly larger than the layout. We check there size at the end and
252 // recompute the layout if necessary.
253 // For layout elements, make sure that the stretch factor is not 0. If it is, it means it will not use the
254 // size provided by the parent layout. Its size will be adjusted to the minimum size of the layout content.
255- if (! ((*it)->IsLayout() && (*it)->GetScaleFactor() == 0))
256- FullSizeUnadjusted.push_back((*it)->GetBaseHeight());
257+ if (! (area->IsLayout() && area->GetScaleFactor() == 0))
258+ FullSizeUnadjusted.push_back(area->GetBaseHeight());
259 }
260
261- if ((smaller_height || larger_height) && ((*it)->GetExtend() == MINOR_SIZE_MATCHCONTENT))
262+ if ((smaller_height || larger_height) && (area->GetExtend() == MINOR_SIZE_MATCHCONTENT))
263 {
264- (*it)->SetMinimumHeight((*it)->GetBaseHeight());
265+ area->SetMinimumHeight(area->GetBaseHeight());
266 unadjusted_layout = true;
267 }
268
269 // Should be reactivate so that if the parent Layout does not call
270 // ComputeContentPosition, at least it is done here to arrange the internal
271 // element of the children.
272- //(*it)->ComputeContentPosition(0,0);
273+ //area->ComputeContentPosition(0,0);
274 }
275
276- m_fittingWidth += (*it)->GetBaseWidth();
277-
278- element_height = (*it)->GetBaseHeight();
279-
280- if ((*it)->IsSpaceLayout() == false)
281+ m_fittingWidth += area->GetBaseWidth();
282+
283+ element_height = area->GetBaseHeight();
284+
285+ if (area->IsSpaceLayout() == false)
286 {
287 if ((GetScaleFactor() != 0) && (ret & eSmallerHeight))
288 {
289@@ -437,7 +454,7 @@
290 m_contentHeight = element_height;
291 }
292
293-// else if ((*it)->GetExtend() == MINOR_SIZE_FULL)
294+// else if (area->GetExtend() == MINOR_SIZE_FULL)
295 // {
296 // unadjusted_layout = true;
297 // }
298@@ -528,15 +545,22 @@
299 int available_width = width;
300 unsigned int max_stretchfactor = GetMaxStretchFactor();
301 std::list<Area *>::iterator it;
302+ std::list<Area *>::reverse_iterator revit;
303+ Area* area;
304
305- for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++)
306+ revit = _layout_element_list.rbegin();
307+ for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++, revit++)
308 {
309- if (!(*it)->IsVisible())
310+ if (GetDirection() == LeftToRight)
311+ area = *it;
312+ else
313+ area = *revit;
314+ if (!area->IsVisible())
315 continue;
316
317- if (((*it)->GetScaleFactor() == 0) && ((*it)->IsLayoutDone() != true))
318+ if ((area->GetScaleFactor() == 0) && (area->IsLayoutDone() != true))
319 {
320- (*it)->ApplyMinWidth();
321+ area->ApplyMinWidth();
322 }
323 }
324
325@@ -573,27 +597,32 @@
326
327 if (available_width <= 2)
328 {
329- for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++)
330+ revit = _layout_element_list.rbegin();
331+ for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++, revit++)
332 {
333- if (!(*it)->IsVisible())
334+ if (GetDirection() == LeftToRight)
335+ area = *it;
336+ else
337+ area = *revit;
338+ if (!area->IsVisible())
339 continue;
340
341- if (((*it)->GetScaleFactor() != 0) && (*it)->IsArea())
342+ if ((area->GetScaleFactor() != 0) && area->IsArea())
343 {
344 // If it is not an object of type eInputArea, do not set layout_done_ to true,
345 // so, the layout management function will later be called on the object.
346- (*it)->ApplyMinWidth();
347- (*it)->SetLayoutDone(true);
348+ area->ApplyMinWidth();
349+ area->SetLayoutDone(true);
350 }
351- else if (((*it)->GetScaleFactor() != 0) && ((*it)->IsLayout()) && ((*it)->IsLayoutDone() == false)) // layout and not fixed by child
352+ else if ((area->GetScaleFactor() != 0) && (area->IsLayout()) && (area->IsLayoutDone() == false)) // layout and not fixed by child
353 {
354 // The out of bound must be reset to false.
355- (*it)->ApplyMinWidth();
356- (*it)->SetLayoutDone(false);
357+ area->ApplyMinWidth();
358+ area->SetLayoutDone(false);
359 }
360- else if (((*it)->GetScaleFactor() != 0) && ((*it)->IsLayoutDone() == false)) // layout and not fixed
361+ else if ((area->GetScaleFactor() != 0) && (area->IsLayoutDone() == false)) // layout and not fixed
362 {
363- (*it)->ApplyMinWidth();
364+ area->ApplyMinWidth();
365 // A layout must never have layout_done_ set to true "here" because it must continue
366 // doing the layout of its children and finally resize itself to fit them.
367 // The same way, A layout size factor should never be set to 0.
368@@ -607,20 +636,26 @@
369 Area *LastElementThatCanBeResized = 0;
370 int total_distributed_size = 0;
371
372- for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++)
373+ revit = _layout_element_list.rbegin();
374+ for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++, revit++)
375 {
376- if (!(*it)->IsVisible())
377+ if (GetDirection() == LeftToRight)
378+ area = *it;
379+ else
380+ area = *revit;
381+
382+ if (!area->IsVisible())
383 continue;
384
385- if (((*it)->GetScaleFactor() != 0) && ((*it)->IsLayoutDone() == false))
386+ if ((area->GetScaleFactor() != 0) && (area->IsLayoutDone() == false))
387 {
388- float sf = (float) (*it)->GetScaleFactor();
389+ float sf = (float) area->GetScaleFactor();
390 cumul += sf / max_stretchfactor;
391- LastElementThatCanBeResized = (*it);
392+ LastElementThatCanBeResized = area;
393 }
394 else
395 {
396- total_distributed_size += (*it)->GetBaseWidth();
397+ total_distributed_size += area->GetBaseWidth();
398 }
399 }
400
401@@ -636,14 +671,20 @@
402
403 need_recompute = false;;
404
405- for (it = _layout_element_list.begin(); it != _layout_element_list.end() && !need_recompute; it++)
406+ revit = _layout_element_list.rbegin();
407+ for (it = _layout_element_list.begin(); it != _layout_element_list.end() && !need_recompute; it++, revit++)
408 {
409- if (!(*it)->IsVisible())
410+ if (GetDirection() == LeftToRight)
411+ area = *it;
412+ else
413+ area = *revit;
414+
415+ if (!area->IsVisible())
416 continue;
417
418- if (((*it)->GetScaleFactor() != 0) && ((*it)->IsLayoutDone() == false))
419+ if ((area->GetScaleFactor() != 0) && (area->IsLayoutDone() == false))
420 {
421- unsigned int sf = (*it)->GetScaleFactor();
422+ unsigned int sf = area->GetScaleFactor();
423 int new_width;
424
425 if (sf == max_stretchfactor)
426@@ -657,7 +698,7 @@
427
428 total_distributed_size += new_width;
429
430- if (LastElementThatCanBeResized == (*it))
431+ if (LastElementThatCanBeResized == area)
432 {
433 // Redistribute the remaining size to the last element(at the right).
434 // This is necessary because of imprecision. For instance if available_height = 451 and we have 2 elements
435@@ -670,8 +711,8 @@
436 }
437 }
438
439- int elemt_max_width = (*it)->GetMaximumSize().width;
440- int elemt_min_width = (*it)->GetMinimumSize().width;
441+ int elemt_max_width = area->GetMaximumSize().width;
442+ int elemt_min_width = area->GetMinimumSize().width;
443
444 // A layout must never have layout_done_ set to true "here" because it must continue
445 // doing the layout of its children and finally resize itself to fit them.
446@@ -682,22 +723,22 @@
447 if (new_width < elemt_min_width)
448 {
449 // assume the minimum width
450- (*it)->SetBaseWidth(elemt_min_width);
451+ area->SetBaseWidth(elemt_min_width);
452
453- if ((*it)->IsLayout() == false || (*it)->IsSpaceLayout())
454+ if (area->IsLayout() == false || area->IsSpaceLayout())
455 {
456- (*it)->SetLayoutDone(true);
457+ area->SetLayoutDone(true);
458 need_recompute = true;
459 }
460 }
461 else if (new_width > elemt_max_width)
462 {
463 // assume the maximum width
464- (*it)->SetBaseWidth(elemt_max_width);
465+ area->SetBaseWidth(elemt_max_width);
466
467- if ((*it)->IsLayout() == false || (*it)->IsSpaceLayout())
468+ if (area->IsLayout() == false || area->IsSpaceLayout())
469 {
470- (*it)->SetLayoutDone(true);
471+ area->SetLayoutDone(true);
472 need_recompute = true;
473 }
474
475@@ -709,7 +750,7 @@
476 }
477 else
478 {
479- (*it)->SetBaseWidth(new_width);
480+ area->SetBaseWidth(new_width);
481 }
482 }
483 else
484@@ -717,10 +758,10 @@
485 // For fixed element, reset their size to the same so it is checked against
486 // the min and max. This is necessary in case you have set the size of the element first then latter,
487 // you define its MinimumSize and/or MaximumSize size.
488- unsigned int w = (*it)->GetBaseWidth();
489- unsigned int h = (*it)->GetBaseHeight();
490- (*it)->SetBaseWidth(w);
491- (*it)->SetBaseHeight(h);
492+ unsigned int w = area->GetBaseWidth();
493+ unsigned int h = area->GetBaseHeight();
494+ area->SetBaseWidth(w);
495+ area->SetBaseHeight(h);
496 }
497 }
498 }
499@@ -757,6 +798,8 @@
500 void HLayout::ComputeContentPosition(float offsetX, float offsetY)
501 {
502 std::list<Area *>::iterator it;
503+ std::list<Area *>::reverse_iterator revit;
504+ Area* area;
505 {
506 unsigned int num_element = 0;
507 for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++)
508@@ -781,36 +824,51 @@
509 ComputeStacking(width, offset_space, element_margin);
510 current_x += offset_space;
511
512- for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++)
513+ revit = _layout_element_list.rbegin();
514+ for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++, revit++)
515 {
516- if (!(*it)->IsVisible())
517+ if (GetDirection() == LeftToRight)
518+ area = *it;
519+ else
520+ area = *revit;
521+ if (!area->IsVisible())
522 continue;
523
524 current_x += element_margin;
525
526+<<<<<<< TREE
527 (*it)->SetBaseX(current_x);
528 (*it)->SetBaseY(current_y);
529
530 MinorDimensionPosition positioning = (*it)->GetPositioning();
531
532 if ((*it)->GetBaseHeight() < height)
533+=======
534+ area->SetBaseX(current_x);
535+ area->SetBaseY(current_y);
536+
537+ MinorDimensionSize extend = area->GetExtend();
538+ MinorDimensionPosition positioning = area->GetPositioning();
539+
540+ if (area->GetBaseHeight() < height)
541+>>>>>>> MERGE-SOURCE
542 {
543- int widget_height = (*it)->GetBaseHeight();
544+ int widget_height = area->GetBaseHeight();
545
546 switch(positioning)
547 {
548 case MINOR_POSITION_START:
549 {
550 // do nothing
551- (*it)->SetBaseY(current_y);
552+ area->SetBaseY(current_y);
553 break;
554 }
555 case MINOR_POSITION_END:
556 {
557 if (widget_height < height)
558- (*it)->SetBaseY(current_y + height - widget_height);
559+ area->SetBaseY(current_y + height - widget_height);
560 else
561- (*it)->SetBaseY(current_y);
562+ area->SetBaseY(current_y);
563
564 break;
565 }
566@@ -819,29 +877,34 @@
567 default:
568 {
569 if (widget_height < height)
570- (*it)->SetBaseY(current_y + (height - widget_height) / 2);
571+ area->SetBaseY(current_y + (height - widget_height) / 2);
572 else
573- (*it)->SetBaseY(current_y);
574+ area->SetBaseY(current_y);
575 }
576 }
577 }
578
579- current_x += (*it)->GetBaseWidth() + element_margin + space_between_children_;
580+ current_x += area->GetBaseWidth() + element_margin + space_between_children_;
581 }
582 }
583
584- for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++)
585+ revit = _layout_element_list.rbegin();
586+ for (it = _layout_element_list.begin(); it != _layout_element_list.end(); it++, revit++)
587 {
588- if (!(*it)->IsVisible())
589+ if (GetDirection() == LeftToRight)
590+ area = *it;
591+ else
592+ area = *revit;
593+ if (!area->IsVisible())
594 continue;
595
596- if ((*it)->Type().IsDerivedFromType(Layout::StaticObjectType))
597+ if (area->Type().IsDerivedFromType(Layout::StaticObjectType))
598 {
599- (*it)->ComputeContentPosition(offsetX, offsetY);
600+ area->ComputeContentPosition(offsetX, offsetY);
601 }
602- else if ((*it)->Type().IsDerivedFromType(View::StaticObjectType))
603+ else if (area->Type().IsDerivedFromType(View::StaticObjectType))
604 {
605- (*it)->ComputeContentPosition(offsetX, offsetY);
606+ area->ComputeContentPosition(offsetX, offsetY);
607 }
608 }
609 }
610
611=== modified file 'Nux/Layout.cpp'
612--- Nux/Layout.cpp 2011-11-25 04:59:29 +0000
613+++ Nux/Layout.cpp 2012-04-27 07:22:03 +0000
614@@ -575,6 +575,22 @@
615 return m_ContentStacking;
616 }
617
618+ LayoutContentDistribution Layout::GetEffectiveContentDistribution()
619+ {
620+ LayoutContentDistribution stacking = GetContentDistribution();
621+ if (GetDirection() == LeftToRight)
622+ return stacking;
623+ switch (stacking)
624+ {
625+ case eStackLeft:
626+ return eStackRight;
627+ case eStackRight:
628+ return eStackLeft;
629+ default:
630+ return stacking;
631+ }
632+ }
633+
634 void Layout::RequestBottomUpLayoutComputation(Area *bo_initiator)
635 {
636
637
638=== modified file 'Nux/Layout.h'
639--- Nux/Layout.h 2011-11-24 17:54:41 +0000
640+++ Nux/Layout.h 2012-04-27 07:22:03 +0000
641@@ -220,6 +220,9 @@
642 virtual void SetContentDistribution(LayoutContentDistribution stacking_order);
643 virtual LayoutContentDistribution GetContentDistribution();
644
645+ //! Switch the content distribution in case a RightToLeft direction is used
646+ LayoutContentDistribution GetEffectiveContentDistribution();
647+
648 virtual bool FindWidget(Area *WidgetObject) const;
649 virtual bool IsEmpty() const;
650 /*
651
652=== modified file 'Nux/Nux.cpp'
653--- Nux/Nux.cpp 2011-12-29 18:06:53 +0000
654+++ Nux/Nux.cpp 2012-04-27 07:22:03 +0000
655@@ -379,4 +379,32 @@
656 NThread *thread = GetWindowThread();
657 return NUX_STATIC_CAST(WindowThread *, thread)->GetTimerHandler();
658 }
659+<<<<<<< TREE
660+=======
661+
662+ GraphicsDisplay& GetWindow()
663+ {
664+ NThread *thread = GetWindowThread();
665+ return NUX_STATIC_CAST(WindowThread *, thread)->GetWindow();
666+ }
667+
668+ GraphicsEngine& GetGraphicsEngine()
669+ {
670+ NThread *thread = GetWindowThread();
671+ return NUX_STATIC_CAST(WindowThread *, thread)->GetGraphicsEngine();
672+ }
673+
674+ static Direction defaultDirection = LeftToRight;
675+
676+ Direction GetDefaultDirection()
677+ {
678+ return defaultDirection;
679+ }
680+
681+ void SetDefaultDirection(Direction direction)
682+ {
683+ defaultDirection = direction;
684+ }
685+
686+>>>>>>> MERGE-SOURCE
687 }
688
689=== modified file 'Nux/Nux.h'
690--- Nux/Nux.h 2012-02-19 00:02:14 +0000
691+++ Nux/Nux.h 2012-04-27 07:22:03 +0000
692@@ -235,6 +235,9 @@
693
694 inlDeclareThreadLocalStorage(NThread *, 0, ThreadLocal_InalogicAppImpl);
695
696+ Direction GetDefaultDirection();
697+ void SetDefaultDirection(Direction direction);
698+
699 }
700
701 #endif // NUX_H

Subscribers

People subscribed via source and target branches