|
1 /* |
|
2 * Copyright (c) 2005-2006 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: Implementation for a popup |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include "xnpopupadapter.h" |
|
20 |
|
21 #include "xncomponentnodeimpl.h" |
|
22 #include "xnnodepluginif.h" |
|
23 #include "xnproperty.h" |
|
24 #include "xndompropertyvalue.h" |
|
25 #include "xndomlist.h" |
|
26 #include "xncomponent.h" |
|
27 |
|
28 #include <AknUtils.h> |
|
29 |
|
30 const TInt KStartDelay = 1000000; |
|
31 const TInt KDisplayTime = 0; |
|
32 |
|
33 // ----------------------------------------------------------------------------- |
|
34 // Control |
|
35 // Gets a CXnControlAdapter from node |
|
36 // ----------------------------------------------------------------------------- |
|
37 static CXnControlAdapter* Control( CXnNodePluginIf* aNode ) |
|
38 { |
|
39 if( aNode ) |
|
40 { |
|
41 CXnComponent* component( NULL ); |
|
42 |
|
43 if( aNode->ComponentNodeImpl() ) |
|
44 { |
|
45 component = aNode->ComponentNodeImpl()->Component(); |
|
46 } |
|
47 |
|
48 if( component ) |
|
49 { |
|
50 return component->ControlAdapter(); |
|
51 } |
|
52 } |
|
53 |
|
54 return NULL; |
|
55 } |
|
56 |
|
57 // ----------------------------------------------------------------------------- |
|
58 // IsNodeDisplayedL |
|
59 // |
|
60 // ----------------------------------------------------------------------------- |
|
61 static TBool IsNodeDisplayedL( CXnNodePluginIf* aNode ) |
|
62 { |
|
63 CXnProperty* visibilityProp( aNode->VisibilityL() ); |
|
64 |
|
65 // Am I visible? |
|
66 if( visibilityProp ) |
|
67 { |
|
68 const TDesC8& visibility( visibilityProp->StringValue() ); |
|
69 |
|
70 if( visibility != XnPropertyNames::style::common::visibility::KVisible ) |
|
71 { |
|
72 return EFalse; |
|
73 } |
|
74 } |
|
75 |
|
76 // Am I displayed? |
|
77 CXnProperty* displayProp( aNode->DisplayL() ); |
|
78 |
|
79 if( displayProp ) |
|
80 { |
|
81 const TDesC8& display( displayProp->StringValue() ); |
|
82 |
|
83 if( display != XnPropertyNames::style::common::display::KBlock ) |
|
84 { |
|
85 return EFalse; |
|
86 } |
|
87 } |
|
88 |
|
89 return ETrue; |
|
90 } |
|
91 |
|
92 // ----------------------------------------------------------------------------- |
|
93 // class CXnPopupController |
|
94 // |
|
95 // ----------------------------------------------------------------------------- |
|
96 class CXnPopupController : public CActive |
|
97 { |
|
98 public: |
|
99 static CXnPopupController* NewL(CXnControlAdapter& aAdapter) |
|
100 { |
|
101 CXnPopupController* self = new (ELeave) CXnPopupController; |
|
102 CleanupStack::PushL(self); |
|
103 self->ConstructL(aAdapter); |
|
104 CleanupStack::Pop(self); |
|
105 return self; |
|
106 } |
|
107 ~CXnPopupController() |
|
108 { |
|
109 iDestroying = ETrue; |
|
110 Cancel(); |
|
111 iTimer.Close(); |
|
112 } |
|
113 void SetTimes(TTimeIntervalMicroSeconds32 aShowDelay, TTimeIntervalMicroSeconds32 aDisplayTime) |
|
114 { |
|
115 Cancel(); |
|
116 iShowDelay = aShowDelay; |
|
117 iDisplayTime = aDisplayTime; |
|
118 iShowing = ETrue; |
|
119 iTimer.After(iStatus, aShowDelay); |
|
120 SetActive(); |
|
121 } |
|
122 private: |
|
123 CXnPopupController() : CActive(0) |
|
124 { |
|
125 } |
|
126 void ConstructL(CXnControlAdapter& aAdapter) |
|
127 { |
|
128 iAdapter = &aAdapter; |
|
129 User::LeaveIfError(iTimer.CreateLocal()); |
|
130 CActiveScheduler::Add(this); |
|
131 } |
|
132 void RunL() |
|
133 { |
|
134 if (iShowing) |
|
135 { |
|
136 iAdapter->ActivateL(); |
|
137 iAdapter->MakeVisible(ETrue); |
|
138 |
|
139 // Check are childs visible |
|
140 CXnNodePluginIf* node( iAdapter->Component()->Node() ); |
|
141 |
|
142 RPointerArray<CXnNodePluginIf> children( node->ChildrenL() ); |
|
143 CleanupClosePushL( children ); |
|
144 |
|
145 TInt visibleCount( 0 ); |
|
146 |
|
147 for( TInt i = 0; i < children.Count(); i++ ) |
|
148 { |
|
149 CXnNodePluginIf* child( children[i] ); |
|
150 |
|
151 TBool visible( IsNodeDisplayedL( child ) ); |
|
152 |
|
153 CCoeControl* control( Control( child ) ); |
|
154 |
|
155 if( control ) |
|
156 { |
|
157 control->MakeVisible( visible ); |
|
158 } |
|
159 |
|
160 if( visible ) |
|
161 { |
|
162 visibleCount++; |
|
163 } |
|
164 } |
|
165 |
|
166 CleanupStack::PopAndDestroy( &children ); |
|
167 |
|
168 if( visibleCount == 0 ) |
|
169 { |
|
170 iAdapter->MakeVisible( EFalse ); |
|
171 // Nothing to show |
|
172 return; |
|
173 } |
|
174 |
|
175 iAdapter->DrawNow(); |
|
176 iShowing = EFalse; |
|
177 if (iDisplayTime.Int() != 0) |
|
178 { |
|
179 iHiding = ETrue; |
|
180 iTimer.After(iStatus, iDisplayTime); |
|
181 SetActive(); |
|
182 } |
|
183 } |
|
184 else if (iHiding) |
|
185 { |
|
186 iAdapter->MakeVisible(EFalse); |
|
187 iHiding = EFalse; |
|
188 } |
|
189 } |
|
190 void DoCancel() |
|
191 { |
|
192 if (!iDestroying) |
|
193 { |
|
194 iAdapter->MakeVisible(EFalse); |
|
195 } |
|
196 |
|
197 iTimer.Cancel(); |
|
198 } |
|
199 private: |
|
200 TBool iDestroying; |
|
201 CXnControlAdapter* iAdapter; |
|
202 RTimer iTimer; |
|
203 TBool iShowing; |
|
204 TBool iHiding; |
|
205 TTimeIntervalMicroSeconds32 iShowDelay; |
|
206 TTimeIntervalMicroSeconds32 iDisplayTime; |
|
207 }; |
|
208 |
|
209 |
|
210 static CActive* CreateActiveObjectL(CXnControlAdapter& aAdapter) |
|
211 { |
|
212 return CXnPopupController::NewL(aAdapter); |
|
213 } |
|
214 |
|
215 // ============================ MEMBER FUNCTIONS =============================== |
|
216 |
|
217 // ----------------------------------------------------------------------------- |
|
218 // CXnPopup::NewL |
|
219 // Symbian static 1st phase constructor |
|
220 // ----------------------------------------------------------------------------- |
|
221 // |
|
222 CXnPopupAdapter* CXnPopupAdapter::NewL(CXnNodePluginIf& aNode, CXnControlAdapter* aParent) |
|
223 { |
|
224 CXnPopupAdapter* self = new( ELeave ) CXnPopupAdapter; |
|
225 |
|
226 CleanupStack::PushL( self ); |
|
227 self->ConstructL(aNode, aParent); |
|
228 CleanupStack::Pop(); |
|
229 |
|
230 return self; |
|
231 } |
|
232 |
|
233 // ----------------------------------------------------------------------------- |
|
234 // CXnPopupAdapter::ConstructL |
|
235 // Symbian 2nd phase constructor can leave. |
|
236 // ----------------------------------------------------------------------------- |
|
237 // |
|
238 void CXnPopupAdapter::ConstructL(CXnNodePluginIf& aNode, CXnControlAdapter* /*aParent*/) |
|
239 { |
|
240 MakeVisible(EFalse); |
|
241 CXnProperty* positionHintProp = aNode.GetPropertyL(XnPropertyNames::tooltip::KPositionHint); |
|
242 if( positionHintProp ) |
|
243 { |
|
244 const TDesC8& displayHintVal = positionHintProp->StringValue(); |
|
245 if( displayHintVal == XnPropertyNames::tooltip::positionhint::KAboveLeft ) |
|
246 { |
|
247 iPositionHint = EAboveLeft; |
|
248 } |
|
249 else if( displayHintVal == XnPropertyNames::tooltip::positionhint::KAboveRight ) |
|
250 { |
|
251 iPositionHint = EAboveRight; |
|
252 } |
|
253 else if( displayHintVal == XnPropertyNames::tooltip::positionhint::KBelowLeft ) |
|
254 { |
|
255 iPositionHint = EBelowLeft; |
|
256 } |
|
257 else if( displayHintVal == XnPropertyNames::tooltip::positionhint::KBelowRight ) |
|
258 { |
|
259 iPositionHint = EBelowRight; |
|
260 } |
|
261 else if( displayHintVal == XnPropertyNames::tooltip::positionhint::KRight ) |
|
262 { |
|
263 iPositionHint = ERight; |
|
264 } |
|
265 else if( displayHintVal == XnPropertyNames::tooltip::positionhint::KLeft ) |
|
266 { |
|
267 iPositionHint = ELeft; |
|
268 } |
|
269 } |
|
270 if(iPositionHint == ENone) |
|
271 { |
|
272 // Use default value |
|
273 if(AknLayoutUtils::LayoutMirrored()) |
|
274 { |
|
275 iPositionHint = EAboveRight; |
|
276 } |
|
277 else |
|
278 { |
|
279 iPositionHint = EAboveLeft; |
|
280 } |
|
281 } |
|
282 |
|
283 CreateWindowL(); |
|
284 |
|
285 if( CAknEnv::Static()->TransparencyEnabled() ) |
|
286 { |
|
287 // try to enable window transparency |
|
288 if ( Window().SetTransparencyAlphaChannel() == KErrNone ) |
|
289 { |
|
290 TRgb color( ~0 ); |
|
291 Window().SetBackgroundColor( color ); |
|
292 } |
|
293 } |
|
294 |
|
295 CXnControlAdapter::ConstructL(aNode); |
|
296 iNode = &aNode; |
|
297 iAppUi = CCoeEnv::Static()->AppUi(); |
|
298 } |
|
299 |
|
300 // ----------------------------------------------------------------------------- |
|
301 // CXnPopupAdapter::CXnPopupAdapter |
|
302 // C++ default constructor |
|
303 // ----------------------------------------------------------------------------- |
|
304 // |
|
305 CXnPopupAdapter::CXnPopupAdapter(): iPositionHint( ENone ) |
|
306 { |
|
307 } |
|
308 |
|
309 // ----------------------------------------------------------------------------- |
|
310 // CXnPopupAdapter::~CXnPopupAdapter |
|
311 // C++ destructor |
|
312 // ----------------------------------------------------------------------------- |
|
313 // |
|
314 CXnPopupAdapter::~CXnPopupAdapter() |
|
315 { |
|
316 delete iActiveObject; |
|
317 } |
|
318 |
|
319 // ----------------------------------------------------------------------------- |
|
320 // CXnPopupAdapter::ShowPopupL |
|
321 // Shows the popup |
|
322 // ----------------------------------------------------------------------------- |
|
323 // |
|
324 void CXnPopupAdapter::ShowPopupL(const TRect& aContainerRect) |
|
325 { |
|
326 // Don't show tooltip if display property is none. |
|
327 CXnProperty* displayProperty( iNode->DisplayL() ); |
|
328 |
|
329 if( displayProperty ) |
|
330 { |
|
331 const TDesC8& displayValue = displayProperty->StringValue(); |
|
332 |
|
333 if( displayValue == XnPropertyNames::style::common::display::KNone ) |
|
334 { |
|
335 return; |
|
336 } |
|
337 } |
|
338 |
|
339 CXnProperty* visibilityProp( iNode->VisibilityL() ); |
|
340 |
|
341 if( visibilityProp ) |
|
342 { |
|
343 const TDesC8& value( visibilityProp->StringValue() ); |
|
344 |
|
345 if( value == XnPropertyNames::style::common::visibility::KHidden ) |
|
346 { |
|
347 return; |
|
348 } |
|
349 } |
|
350 |
|
351 TTimeIntervalMicroSeconds32 startDelay(KStartDelay); |
|
352 TTimeIntervalMicroSeconds32 displayTime(KDisplayTime); |
|
353 CXnProperty* startDelayProperty = iNode->GetPropertyL(XnPropertyNames::tooltip::KStartDelay); |
|
354 if (startDelayProperty) |
|
355 { |
|
356 CXnDomPropertyValue* value = static_cast<CXnDomPropertyValue*>(startDelayProperty->Property()->PropertyValueList().Item(0)); |
|
357 TInt factor = 1; |
|
358 if (value->PrimitiveValueType() == CXnDomPropertyValue::ES) |
|
359 { |
|
360 factor = 1000000; |
|
361 } |
|
362 else if (value->PrimitiveValueType() == CXnDomPropertyValue::EMs) |
|
363 { |
|
364 factor = 1000; |
|
365 } |
|
366 startDelay = factor * static_cast<TInt>(startDelayProperty->FloatValueL()); |
|
367 } |
|
368 CXnProperty* displayTimeProperty = iNode->GetPropertyL(XnPropertyNames::tooltip::KDisplayTime); |
|
369 if (displayTimeProperty) |
|
370 { |
|
371 CXnDomPropertyValue* value = static_cast<CXnDomPropertyValue*>(displayTimeProperty->Property()->PropertyValueList().Item(0)); |
|
372 TInt factor = 1; |
|
373 if (value->PrimitiveValueType() == CXnDomPropertyValue::ES) |
|
374 { |
|
375 factor = 1000000; |
|
376 } |
|
377 else if (value->PrimitiveValueType() == CXnDomPropertyValue::EMs) |
|
378 { |
|
379 factor = 1000; |
|
380 } |
|
381 displayTime = factor * static_cast<TInt>(displayTimeProperty->FloatValueL()); |
|
382 } |
|
383 if (displayTime.Int() == 0 ) |
|
384 { |
|
385 return; |
|
386 } |
|
387 ShowPopupL(aContainerRect, startDelay, displayTime); |
|
388 } |
|
389 |
|
390 // ----------------------------------------------------------------------------- |
|
391 // CXnPopupAdapter::ShowPopupL |
|
392 // Shows the popup |
|
393 // ----------------------------------------------------------------------------- |
|
394 // |
|
395 void CXnPopupAdapter::ShowPopupL(const TRect& aContainerRect, TTimeIntervalMicroSeconds32 aShowDelay, TTimeIntervalMicroSeconds32 aDisplayTime) |
|
396 { |
|
397 if (!iActiveObject) |
|
398 { |
|
399 iActiveObject = CreateActiveObjectL(*this); |
|
400 } |
|
401 |
|
402 iActiveObject->Cancel(); |
|
403 |
|
404 // Calculates position according to position hint and |
|
405 // set new rect for CCoeControl. |
|
406 CalculatePosition(aContainerRect); |
|
407 |
|
408 static_cast<CXnPopupController*>(iActiveObject)->SetTimes(aShowDelay, aDisplayTime); |
|
409 } |
|
410 |
|
411 // ----------------------------------------------------------------------------- |
|
412 // CXnPopupAdapter::HidePopupL |
|
413 // Hides the popup |
|
414 // ----------------------------------------------------------------------------- |
|
415 // |
|
416 void CXnPopupAdapter::HidePopupL() |
|
417 { |
|
418 if (!iActiveObject) |
|
419 { |
|
420 MakeVisible(EFalse); |
|
421 return; |
|
422 } |
|
423 iActiveObject->Cancel(); |
|
424 MakeVisible(EFalse); |
|
425 } |
|
426 |
|
427 // ----------------------------------------------------------------------------- |
|
428 // CXnPopupAdapter::Draw |
|
429 // Draws the popup. |
|
430 // ----------------------------------------------------------------------------- |
|
431 // |
|
432 void CXnPopupAdapter::Draw(const TRect& aRect) const |
|
433 { |
|
434 CXnControlAdapter::Draw(aRect); |
|
435 } |
|
436 |
|
437 // ----------------------------------------------------------------------------- |
|
438 // CXnPopupAdapter::DoEnterPowerSaveModeL |
|
439 // Hides the popup when power save mode is entered. |
|
440 // ----------------------------------------------------------------------------- |
|
441 // |
|
442 void CXnPopupAdapter::DoEnterPowerSaveModeL( TModeEvent /*aEvent*/ ) |
|
443 { |
|
444 HidePopupL(); |
|
445 } |
|
446 |
|
447 // ----------------------------------------------------------------------------- |
|
448 // CXnPopupAdapter::Draw |
|
449 // Hides the popup when screen device is changed. |
|
450 // ----------------------------------------------------------------------------- |
|
451 // |
|
452 void CXnPopupAdapter::HandleScreenDeviceChangedL() |
|
453 { |
|
454 HidePopupL(); |
|
455 CXnControlAdapter::HandleScreenDeviceChangedL(); |
|
456 } |
|
457 |
|
458 // ----------------------------------------------------------------------------- |
|
459 // CXnPopupAdapter::DoHandlePropertyChangeL |
|
460 // Handles property changes |
|
461 // ----------------------------------------------------------------------------- |
|
462 // |
|
463 void CXnPopupAdapter::DoHandlePropertyChangeL(CXnProperty* aProperty) |
|
464 { |
|
465 if( aProperty ) |
|
466 { |
|
467 const TDesC8& name( aProperty->Property()->Name() ); |
|
468 |
|
469 if( name == XnPropertyNames::style::common::KDisplay ) |
|
470 { |
|
471 const TDesC8& display( aProperty->StringValue() ); |
|
472 |
|
473 if( display != XnPropertyNames::style::common::display::KBlock ) |
|
474 { |
|
475 HidePopupL(); |
|
476 } |
|
477 } |
|
478 else if( name == XnPropertyNames::style::common::KVisibility ) |
|
479 { |
|
480 const TDesC8& visibility( aProperty->StringValue() ); |
|
481 |
|
482 if( visibility != XnPropertyNames::style::common::visibility::KVisible ) |
|
483 { |
|
484 HidePopupL(); |
|
485 } |
|
486 } |
|
487 } |
|
488 } |
|
489 |
|
490 // ----------------------------------------------------------------------------- |
|
491 // CalculatePosition |
|
492 // |
|
493 // ----------------------------------------------------------------------------- |
|
494 void CXnPopupAdapter::CalculatePosition( TRect aPopupRect ) |
|
495 { |
|
496 TRect clientRect = static_cast<CEikAppUi&>(*iAppUi).ClientRect(); |
|
497 TPoint offset(clientRect.iTl); |
|
498 TRect controlRect = iNode->BorderRect(); |
|
499 TRect contentRect(0, 0, clientRect.iBr.iX, clientRect.iBr.iY); // entire screen except control pane |
|
500 TRect rect; |
|
501 switch(iPositionHint) |
|
502 { |
|
503 case CXnPopupAdapter::EAboveLeft: |
|
504 rect = TRect(TPoint(aPopupRect.iTl.iX, aPopupRect.iTl.iY - controlRect.Height()), TPoint(aPopupRect.iTl.iX + controlRect.Width(), aPopupRect.iTl.iY)); |
|
505 break; |
|
506 case CXnPopupAdapter::EAboveRight: |
|
507 rect = TRect(TPoint(aPopupRect.iBr.iX - controlRect.Width(), aPopupRect.iTl.iY - controlRect.Height()), TPoint(aPopupRect.iBr.iX, aPopupRect.iTl.iY)); |
|
508 break; |
|
509 case CXnPopupAdapter::EBelowLeft: |
|
510 rect = TRect(TPoint(aPopupRect.iTl.iX, aPopupRect.iBr.iY), TPoint(aPopupRect.iTl.iX + controlRect.Width(), aPopupRect.iBr.iY + controlRect.Height())); |
|
511 break; |
|
512 case CXnPopupAdapter::EBelowRight: |
|
513 rect = TRect(TPoint(aPopupRect.iBr.iX - controlRect.Width(), aPopupRect.iBr.iY), TPoint(aPopupRect.iBr.iX, aPopupRect.iBr.iY + controlRect.Height())); |
|
514 break; |
|
515 case CXnPopupAdapter::ERight: |
|
516 rect = TRect(TPoint(aPopupRect.iBr.iX, aPopupRect.iTl.iY), TPoint(aPopupRect.iBr.iX + controlRect.Width(), aPopupRect.iTl.iY + controlRect.Height())); |
|
517 break; |
|
518 case CXnPopupAdapter::ELeft: |
|
519 rect = TRect(TPoint(aPopupRect.iTl.iX - controlRect.Width(), aPopupRect.iTl.iY), TPoint(aPopupRect.iTl.iX, aPopupRect.iTl.iY + controlRect.Height())); |
|
520 break; |
|
521 default: |
|
522 break; |
|
523 } |
|
524 rect.Move(offset); |
|
525 if(rect.iTl.iY < contentRect.iTl.iY) |
|
526 { |
|
527 rect.Move(0, contentRect.iTl.iY - rect.iTl.iY); |
|
528 } |
|
529 if(rect.iTl.iX < contentRect.iTl.iX) |
|
530 { |
|
531 rect.Move(contentRect.iTl.iX - rect.iTl.iX, 0); |
|
532 } |
|
533 if(rect.iBr.iY > contentRect.iBr.iY) |
|
534 { |
|
535 rect.Move(0, contentRect.iBr.iY - rect.iBr.iY); |
|
536 } |
|
537 if(rect.iBr.iX > contentRect.iBr.iX) |
|
538 { |
|
539 rect.Move(contentRect.iBr.iX - rect.iBr.iX, 0); |
|
540 } |
|
541 this->SetRect( rect ); |
|
542 } |
|
543 |
|
544 // End of File |