1 /* |
|
2 * Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: layoutmanager implementation class with focus handling in 1D (next/previous) |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include <alf/ialfwidgetcontrol.h> |
|
20 #include "alf/ialfattributeowner.h" |
|
21 #include "alf/alfattribute.h" |
|
22 #include <alf/alfvisual.h> |
|
23 #include <alf/alfenv.h> |
|
24 #include "alf/alfwidget.h" |
|
25 #include <alf/alfvisualfactory.h> |
|
26 #include <alf/alfexceptions.h> |
|
27 #include <alf/ialflayoutpreferences.h> |
|
28 #include <alf/alfwidgetenvextension.h> |
|
29 #include <alf/ialfwidgetfactory.h> |
|
30 #include <osn/osnnew.h> |
|
31 #include <libc/assert.h> |
|
32 #include <alf/attrproperty.h> |
|
33 #include "alflayoutmanagerimpl.h" |
|
34 |
|
35 |
|
36 |
|
37 namespace Alf |
|
38 { |
|
39 |
|
40 //ifdef to prevent compiler warning: className not used. |
|
41 #ifdef ALF_DEBUG_EXCEPTIONS |
|
42 static const char* const className = "AlfLayoutManagerImpl"; |
|
43 #endif |
|
44 |
|
45 // ======== MEMBER FUNCTIONS ======== |
|
46 |
|
47 // --------------------------------------------------------------------------- |
|
48 // layoutmanagerimpl constructor |
|
49 // --------------------------------------------------------------------------- |
|
50 // |
|
51 AlfLayoutManagerImpl::AlfLayoutManagerImpl( |
|
52 TAlfLayoutType aLayoutType) |
|
53 { |
|
54 mLayoutType = aLayoutType; |
|
55 } |
|
56 |
|
57 // --------------------------------------------------------------------------- |
|
58 // creates the layout used by the layoutmanager. |
|
59 // --------------------------------------------------------------------------- |
|
60 // |
|
61 AlfLayoutManagerImpl::~AlfLayoutManagerImpl() |
|
62 { |
|
63 if (mLayout.get()) |
|
64 { |
|
65 CAlfLayout* layout = mLayout.release(); |
|
66 layout->RemoveAndDestroyAllD(); |
|
67 } |
|
68 } |
|
69 |
|
70 // --------------------------------------------------------------------------- |
|
71 // creates the layout used by the layoutmanager. |
|
72 // --------------------------------------------------------------------------- |
|
73 // |
|
74 void AlfLayoutManagerImpl::createLayout(CAlfWidgetControl& aOwner, |
|
75 CAlfLayout* aParentLayout, int aLayoutIndex) |
|
76 { |
|
77 |
|
78 //check parameter validity. |
|
79 if (aParentLayout && |
|
80 (aLayoutIndex < 0 ||aLayoutIndex > aParentLayout->Count())) |
|
81 { |
|
82 ALF_THROW(AlfException, EInvalidArrayIndex, className); |
|
83 } |
|
84 |
|
85 //create layout |
|
86 CAlfLayout* layout = 0; |
|
87 TRAPD(err, layout = aOwner.AppendLayoutL(mLayoutType, aParentLayout)); |
|
88 |
|
89 if(!layout || err != KErrNone) |
|
90 { |
|
91 ALF_THROW(AlfVisualException, ECanNotCreateVisual, className); |
|
92 } |
|
93 |
|
94 //reorder, if needed. |
|
95 if (aParentLayout && aLayoutIndex != aParentLayout->Count() - 1) |
|
96 { |
|
97 aParentLayout->Reorder(*layout, aLayoutIndex); |
|
98 } |
|
99 |
|
100 mLayout.reset(layout); |
|
101 } |
|
102 |
|
103 // --------------------------------------------------------------------------- |
|
104 // returns the layout used by the layoutmanager. |
|
105 // --------------------------------------------------------------------------- |
|
106 // |
|
107 CAlfLayout& AlfLayoutManagerImpl::getLayout() const |
|
108 { |
|
109 checkLayout(); |
|
110 return *mLayout.get(); |
|
111 } |
|
112 |
|
113 // --------------------------------------------------------------------------- |
|
114 // updates the main layout |
|
115 // --------------------------------------------------------------------------- |
|
116 // |
|
117 void AlfLayoutManagerImpl::updateMainLayout() |
|
118 { |
|
119 checkLayout(); |
|
120 |
|
121 const IAlfLayoutPreferences* layoutPrefs = |
|
122 getLayoutPreferences(getControl(*mLayout.get())); |
|
123 if (layoutPrefs) |
|
124 { |
|
125 TAlfXYMetric prefSize; |
|
126 if (layoutPrefs->getPreferredSize(prefSize)) |
|
127 { |
|
128 TAlfRealPoint p(prefSize.iX.iMagnitude, |
|
129 prefSize.iY.iMagnitude); |
|
130 mLayout->SetSize(p); |
|
131 } |
|
132 } |
|
133 } |
|
134 |
|
135 // --------------------------------------------------------------------------- |
|
136 // notifies the layout manager, that the control's has been |
|
137 // removed from the layout. |
|
138 // --------------------------------------------------------------------------- |
|
139 // |
|
140 void AlfLayoutManagerImpl::childRemoved(CAlfWidgetControl* /*aControl*/) |
|
141 { |
|
142 checkLayout(); |
|
143 mLayout->UpdateChildrenLayout(); |
|
144 } |
|
145 |
|
146 // --------------------------------------------------------------------------- |
|
147 // returns the owner control of the layoutmanager. |
|
148 // --------------------------------------------------------------------------- |
|
149 // |
|
150 CAlfWidgetControl& AlfLayoutManagerImpl::owner() const |
|
151 { |
|
152 checkLayout(); |
|
153 CAlfWidgetControl* widgetControl = 0; |
|
154 |
|
155 /* The owner is always a AlfWidgetControl. |
|
156 So a static_cast is safe. see AlfLayoutManagerImpl::createLayout() */ |
|
157 widgetControl = static_cast<CAlfWidgetControl*>( |
|
158 &mLayout->Owner()); |
|
159 |
|
160 return *widgetControl; |
|
161 } |
|
162 |
|
163 // --------------------------------------------------------------------------- |
|
164 // from IAlfLayoutPreferences |
|
165 // Returns the minimum area that this layout manager can occupy by observing |
|
166 // the minimum sizes of the child UI elements in the layout |
|
167 // --------------------------------------------------------------------------- |
|
168 // |
|
169 bool AlfLayoutManagerImpl::getMinimumSize( TAlfXYMetric& /*aMinSize*/ ) const |
|
170 { |
|
171 return false; |
|
172 } |
|
173 |
|
174 // --------------------------------------------------------------------------- |
|
175 // from IAlfLayoutPreferences |
|
176 // Returns the maximum area that this layout manager can occupy by observing |
|
177 // the maximum sizes of the child UI elements in the layout |
|
178 // --------------------------------------------------------------------------- |
|
179 // |
|
180 bool AlfLayoutManagerImpl::getMaximumSize( TAlfXYMetric& /*aMaxSize*/ ) const |
|
181 { |
|
182 return false; |
|
183 } |
|
184 |
|
185 // --------------------------------------------------------------------------- |
|
186 // Combines and returns the preferred sizes of all child UI elements according |
|
187 // to the layouting rules. |
|
188 // --------------------------------------------------------------------------- |
|
189 // |
|
190 bool AlfLayoutManagerImpl::getPreferredSize(TAlfXYMetric& /*aPreferredSize*/) const |
|
191 { |
|
192 return false; |
|
193 } |
|
194 |
|
195 // --------------------------------------------------------------------------- |
|
196 // from IAlfLayoutPreferences |
|
197 // At the moment doesn't do anything since preferred size is being queried |
|
198 // from the child UI elements added to this layout manager. |
|
199 // --------------------------------------------------------------------------- |
|
200 // |
|
201 void AlfLayoutManagerImpl::setPreferredSize( const TAlfXYMetric& /*aPreferredSize*/ ) |
|
202 { |
|
203 |
|
204 } |
|
205 |
|
206 // --------------------------------------------------------------------------- |
|
207 // From class IAlfInterfaceBase. |
|
208 // Getter for interfaces provided by the element. |
|
209 // --------------------------------------------------------------------------- |
|
210 // |
|
211 IAlfInterfaceBase* AlfLayoutManagerImpl::makeInterface(const IfId& aType) |
|
212 { |
|
213 UString param(aType.mImplementationId); |
|
214 if (param == IAlfLayoutPreferences::type().mImplementationId) |
|
215 { |
|
216 return static_cast<IAlfLayoutPreferences*>(this); |
|
217 } |
|
218 |
|
219 return 0; |
|
220 } |
|
221 |
|
222 // --------------------------------------------------------------------------- |
|
223 // gets control at aIndex position in the layout. |
|
224 // --------------------------------------------------------------------------- |
|
225 // |
|
226 CAlfWidgetControl* AlfLayoutManagerImpl::getControl(int aIndex) const |
|
227 { |
|
228 CAlfWidgetControl* control = 0; |
|
229 CAlfLayout* layout = mLayout.get(); |
|
230 if (layout) |
|
231 { |
|
232 CAlfVisual& visual = layout->Visual(aIndex); |
|
233 control = getControl(visual); |
|
234 } |
|
235 return control; |
|
236 } |
|
237 |
|
238 // --------------------------------------------------------------------------- |
|
239 // returns the control, which owns the visual |
|
240 // --------------------------------------------------------------------------- |
|
241 // |
|
242 void AlfLayoutManagerImpl::doUpdateChildLayout(CAlfWidgetControl* aControl) |
|
243 { |
|
244 const IAlfLayoutPreferences* layoutPrefs = |
|
245 getLayoutPreferences(aControl); |
|
246 |
|
247 if (layoutPrefs) |
|
248 { |
|
249 TAlfXYMetric prefSize; |
|
250 if (layoutPrefs->getPreferredSize(prefSize)) |
|
251 { |
|
252 CAlfVisual* v = findRootVisual(aControl); |
|
253 if (v) |
|
254 { |
|
255 v->SetSize(TAlfRealPoint(prefSize.iX.iMagnitude, |
|
256 prefSize.iY.iMagnitude)); |
|
257 } |
|
258 } |
|
259 } |
|
260 } |
|
261 |
|
262 // --------------------------------------------------------------------------- |
|
263 // returns the size of the widget. |
|
264 // --------------------------------------------------------------------------- |
|
265 // |
|
266 bool AlfLayoutManagerImpl::controlRect(CAlfWidgetControl& aControl, |
|
267 TAlfRealRect& aRect) |
|
268 { |
|
269 CAlfVisual* v = findRootVisual(&aControl); |
|
270 if (v != 0) |
|
271 { |
|
272 TAlfRealPoint size(v->Size().Target()); |
|
273 TAlfRealPoint pos(v->Pos().Target()); |
|
274 aRect.iTl = pos; |
|
275 aRect.iBr.iX = pos.iX + size.iX; |
|
276 aRect.iBr.iY = pos.iY + size.iY; |
|
277 return true; |
|
278 } |
|
279 |
|
280 return false; |
|
281 } |
|
282 |
|
283 // --------------------------------------------------------------------------- |
|
284 // set the size and position to the widget. |
|
285 // --------------------------------------------------------------------------- |
|
286 // |
|
287 void AlfLayoutManagerImpl::setWidgetRect(IAlfWidget& aWidget, const TAlfRealRect &aRect) |
|
288 { |
|
289 const UString widthName(layoutattributes::KWidth); |
|
290 const UString heightName(layoutattributes::KHeight); |
|
291 const UString posX(layoutattributes::KPositionX); |
|
292 const UString posY(layoutattributes::KPositionY); |
|
293 |
|
294 IAlfAttributeOwner* attrOwner = |
|
295 IAlfInterfaceBase::makeInterface<IAlfAttributeOwner>(&aWidget); |
|
296 if (attrOwner) |
|
297 { |
|
298 auto_ptr<AlfAttributeValueType> w( |
|
299 new (EMM) AlfAttributeValueType(aRect.Width())); |
|
300 auto_ptr<AlfAttributeValueType> h( |
|
301 new (EMM) AlfAttributeValueType(aRect.Height())); |
|
302 auto_ptr<AlfAttributeValueType> x( |
|
303 new (EMM) AlfAttributeValueType(aRect.iTl.iX)); |
|
304 auto_ptr<AlfAttributeValueType> y( |
|
305 new (EMM) AlfAttributeValueType(aRect.iTl.iY)); |
|
306 attrOwner->setAttribute(heightName, h.get()); |
|
307 attrOwner->setAttribute(widthName, w.get()); |
|
308 attrOwner->setAttribute(posX, x.get()); |
|
309 attrOwner->setAttribute(posY, y.get()); |
|
310 |
|
311 h.release(); |
|
312 w.release(); |
|
313 x.release(); |
|
314 y.release(); |
|
315 } |
|
316 } |
|
317 |
|
318 // --------------------------------------------------------------------------- |
|
319 // set the position for the widget. |
|
320 // --------------------------------------------------------------------------- |
|
321 // |
|
322 void AlfLayoutManagerImpl::setWidgetPosition(IAlfWidget& aWidget, |
|
323 const TAlfRealPoint &aPos) |
|
324 { |
|
325 const UString posX(layoutattributes::KPositionX); |
|
326 const UString posY(layoutattributes::KPositionY); |
|
327 |
|
328 IAlfAttributeOwner* attrOwner = |
|
329 IAlfInterfaceBase::makeInterface<IAlfAttributeOwner>(&aWidget); |
|
330 if (attrOwner) |
|
331 { |
|
332 auto_ptr<AlfAttributeValueType> x( |
|
333 new (EMM) AlfAttributeValueType(aPos.iX)); |
|
334 auto_ptr<AlfAttributeValueType> y( |
|
335 new (EMM) AlfAttributeValueType(aPos.iY)); |
|
336 attrOwner->setAttribute(posX, x.get()); |
|
337 attrOwner->setAttribute(posY, y.get()); |
|
338 x.release(); |
|
339 y.release(); |
|
340 } |
|
341 } |
|
342 |
|
343 // --------------------------------------------------------------------------- |
|
344 // set the size for the widget. |
|
345 // --------------------------------------------------------------------------- |
|
346 // |
|
347 void AlfLayoutManagerImpl::setWidgetSize(IAlfWidget& aWidget, const TAlfRealPoint &aSize) |
|
348 { |
|
349 const UString widthName(layoutattributes::KWidth); |
|
350 const UString heightName(layoutattributes::KHeight); |
|
351 IAlfAttributeOwner* attrOwner = |
|
352 IAlfInterfaceBase::makeInterface<IAlfAttributeOwner>(&aWidget); |
|
353 if (attrOwner) |
|
354 { |
|
355 auto_ptr<AlfAttributeValueType> w( |
|
356 new (EMM) AlfAttributeValueType(aSize.iX)); |
|
357 auto_ptr<AlfAttributeValueType> h( |
|
358 new (EMM) AlfAttributeValueType(aSize.iY)); |
|
359 attrOwner->setAttribute(heightName, h.get()); |
|
360 attrOwner->setAttribute(widthName, w.get()); |
|
361 h.release(); |
|
362 w.release(); |
|
363 } |
|
364 } |
|
365 |
|
366 // --------------------------------------------------------------------------- |
|
367 // updates widget size and position properties for all the children |
|
368 // to correct sizes and positions of the root visuals. |
|
369 // --------------------------------------------------------------------------- |
|
370 // |
|
371 void AlfLayoutManagerImpl::updateAllWidgetRects() |
|
372 { |
|
373 const int childCount = mLayout->Count(); |
|
374 TAlfRealRect rect; |
|
375 for (int i = 0; i < childCount; i++) |
|
376 { |
|
377 CAlfWidgetControl* control = getControl(i); |
|
378 controlRect(*control, rect); //returns the real rect(of the root visual) |
|
379 AlfWidget* widget = control->widget(); |
|
380 if(widget) |
|
381 { |
|
382 const char* name = widget->widgetName(); |
|
383 IAlfWidget* ownerwidget = AlfWidgetEnvExtension::widgetFactory(control->Env()).findWidget(name); |
|
384 if (ownerwidget) |
|
385 { |
|
386 setWidgetRect(*ownerwidget, rect); //sets the rect using widget properties. |
|
387 } |
|
388 } |
|
389 } |
|
390 |
|
391 } |
|
392 |
|
393 // --------------------------------------------------------------------------- |
|
394 // returns the child visual count |
|
395 // --------------------------------------------------------------------------- |
|
396 // |
|
397 int AlfLayoutManagerImpl::count() const |
|
398 { |
|
399 return getLayout().Count(); |
|
400 } |
|
401 |
|
402 // --------------------------------------------------------------------------- |
|
403 // returns the control, which owns the visual |
|
404 // --------------------------------------------------------------------------- |
|
405 // |
|
406 CAlfWidgetControl* AlfLayoutManagerImpl::getControl(CAlfVisual& aVisual) const |
|
407 { |
|
408 CAlfWidgetControl* temp = 0; |
|
409 temp = dynamic_cast<CAlfWidgetControl*>(&aVisual.Owner()); |
|
410 return temp; |
|
411 } |
|
412 |
|
413 // --------------------------------------------------------------------------- |
|
414 // returns the control, which owns the visual |
|
415 // --------------------------------------------------------------------------- |
|
416 // |
|
417 const IAlfLayoutPreferences* AlfLayoutManagerImpl::getLayoutPreferences( |
|
418 CAlfWidgetControl* aControl) const |
|
419 { |
|
420 IAlfLayoutPreferences* layoutPrefs = 0; |
|
421 if (aControl) |
|
422 { |
|
423 layoutPrefs = |
|
424 CAlfWidgetControl::makeInterface<IAlfLayoutPreferences>(aControl); |
|
425 } |
|
426 |
|
427 return layoutPrefs; |
|
428 } |
|
429 |
|
430 // --------------------------------------------------------------------------- |
|
431 // finds the root visual for a control. |
|
432 // --------------------------------------------------------------------------- |
|
433 // |
|
434 CAlfVisual* AlfLayoutManagerImpl::findRootVisual(CAlfWidgetControl* aControl) const |
|
435 { |
|
436 CAlfVisual* root = 0; |
|
437 if (aControl->VisualCount() > 0) |
|
438 { |
|
439 //take first visual, |
|
440 //go up in layout hierarchy until the control is not owner anymore. |
|
441 for (root = &aControl->Visual(0); |
|
442 root && root->Layout() && &root->Layout()->Owner() == aControl; |
|
443 root = root->Layout()){} |
|
444 } |
|
445 return root; |
|
446 } |
|
447 |
|
448 // --------------------------------------------------------------------------- |
|
449 // throws an exception, if layout is not created. |
|
450 // --------------------------------------------------------------------------- |
|
451 // |
|
452 void AlfLayoutManagerImpl::checkLayout() const |
|
453 { |
|
454 if (!mLayout.get()) |
|
455 { |
|
456 ALF_THROW(AlfVisualException, EInvalidVisual, className); |
|
457 } |
|
458 } |
|
459 |
|
460 } // Alf |
|