|
1 /* |
|
2 * Copyright (c) 2005-2008 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: Button component |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 // INCLUDE FILES |
|
20 #include <aknbutton.h> |
|
21 |
|
22 #include <gulicon.h> // CGulIcon |
|
23 #include <barsread.h> // TResourceReader |
|
24 #include <avkon.hrh> |
|
25 #include <StringLoader.h> // StringLoader |
|
26 #include <AknsDrawUtils.h> |
|
27 #include <AknsControlContext.h> |
|
28 #include <AknBidiTextUtils.h> |
|
29 #include <aknlayout.cdl.h> |
|
30 #include <aknlayoutscalable_avkon.cdl.h> |
|
31 #include <AknInfoPopupNoteController.h> |
|
32 #include <AknPictographInterface.h> |
|
33 #include <AknPictographDrawerInterface.h> |
|
34 #include <AknsFrameBackgroundControlContext.h> |
|
35 #include <aknconsts.h> |
|
36 #include <layoutmetadata.cdl.h> |
|
37 #include <AknPriv.hrh> |
|
38 #include <AknLayoutFont.h> |
|
39 #include <akniconconfig.h> |
|
40 |
|
41 #include <AknTasHook.h> // for testability hooks |
|
42 #include "aknresourceprovider.h" |
|
43 #include "aknbitmapresourceitem.h" |
|
44 #include "akncommandbuttonstate.h" |
|
45 |
|
46 #include <touchfeedback.h> |
|
47 const TUint KPointerFlag = 3; // second bit |
|
48 |
|
49 |
|
50 // CONSTANTS |
|
51 enum TSkinItemIdIndex |
|
52 { |
|
53 KFrameId = 0, |
|
54 KCenterId, |
|
55 KLatchedFrameId, |
|
56 KLatchedCenterId, |
|
57 KDimmedFrameId, |
|
58 KDimmedCenterId, |
|
59 KPressedFrameId, |
|
60 KPressedCenterId, |
|
61 KLatchedDimmedFrameId, |
|
62 KLatchedDimmedCenterId |
|
63 }; |
|
64 |
|
65 // ATTENTION, if the values bellow are changed, make the changes in AknButton.h |
|
66 const TInt KTimeoutBeforeHelpNote = 150; // in milliseconds |
|
67 const TInt KTimeoutInViewHelpNote = 3000; // in milliseconds |
|
68 |
|
69 const TInt KKeyRepeatDelay = 500000; // 0,5 seconds |
|
70 const TInt KKeyRepeatInterval = 500000; // 0,5 seconds |
|
71 const TInt KLongPressInterval = 800000; // 0,8 seconds |
|
72 |
|
73 const TInt KDragEventSensitivity = 1; |
|
74 |
|
75 // Value table for 70% Transparency |
|
76 const TInt KTransparency[256] = |
|
77 { |
|
78 0, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, |
|
79 8, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 13, |
|
80 14, 14, 14, 14, 15, 15, 15, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 19, |
|
81 19, 19, 20, 20, 20, 20, 21, 21, 21, 22, 22, 22, 23, 23, 23, 23, 24, 24, |
|
82 24, 25, 25, 25, 26, 26, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29, 29, 29, |
|
83 30, 30, 30, 31, 31, 31, 32, 32, 32, 32, 33, 33, 33, 34, 34, 34, 35, 35, |
|
84 35, 35, 36, 36, 36, 37, 37, 37, 38, 38, 38, 38, 39, 39, 39, 40, 40, 40, |
|
85 41, 41, 41, 41, 42, 42, 42, 43, 43, 43, 44, 44, 44, 44, 45, 45, 45, 46, |
|
86 46, 46, 47, 47, 47, 47, 48, 48, 48, 49, 49, 49, 50, 50, 50, 50, 51, 51, |
|
87 51, 52, 52, 52, 53, 53, 53, 53, 54, 54, 54, 55, 55, 55, 56, 56, 56, 56, |
|
88 57, 57, 57, 58, 58, 58, 59, 59, 59, 59, 60, 60, 60, 61, 61, 61, 62, 62, |
|
89 62, 62, 63, 63, 63, 64, 64, 64, 65, 65, 65, 65, 66, 66, 66, 67, 67, 67, |
|
90 68, 68, 68, 68, 69, 69, 69, 70, 70, 70, 71, 71, 71, 71, 72, 72, 72, 73, |
|
91 73, 73, 74, 74, 74, 74, 75, 75, 75, 76, 76, 76, 77, 77 |
|
92 }; |
|
93 |
|
94 // ----------------------------------------------------------------------------- |
|
95 // ResizeIcon |
|
96 // Tries to resize the given icon. If the operation fails the icon is deleted. |
|
97 // ----------------------------------------------------------------------------- |
|
98 // |
|
99 static TInt ResizeIcon( CGulIcon*& aIcon, |
|
100 const TSize& aSize, |
|
101 TScaleMode aScaleMode ) |
|
102 { |
|
103 TInt retval = KErrNotFound; |
|
104 |
|
105 if ( aIcon ) |
|
106 { |
|
107 CFbsBitmap* bmp = aIcon->Bitmap(); |
|
108 |
|
109 if ( bmp ) |
|
110 { |
|
111 retval = !( aSize == bmp->SizeInPixels() ); |
|
112 } |
|
113 |
|
114 if ( retval != KErrNone ) |
|
115 { |
|
116 retval = AknIconUtils::SetSize( bmp, aSize, aScaleMode ); |
|
117 } |
|
118 |
|
119 // Retval is checked outside of the "if ( bmp )" scope above in order |
|
120 // to detect if the given icon's bitmap is NULL. This is required since |
|
121 // AknIconUtils::SetSize returns KErrNone for NULL bitmaps and we want |
|
122 // to delete icons that couldn't be resized. |
|
123 if ( retval != KErrNone ) |
|
124 { |
|
125 delete aIcon; |
|
126 aIcon = NULL; |
|
127 } |
|
128 } |
|
129 |
|
130 return retval; |
|
131 } |
|
132 |
|
133 static void ReplaceIconStatic( CGulIcon*& aIcon, CGulIcon* aNewIcon, |
|
134 TScaleMode aScaleMode ) |
|
135 { |
|
136 TSize iconSize( 0, 0 ); |
|
137 |
|
138 if ( aIcon && aIcon->Bitmap() ) |
|
139 { |
|
140 iconSize = aIcon->Bitmap()->SizeInPixels(); |
|
141 } |
|
142 |
|
143 delete aIcon; |
|
144 aIcon = aNewIcon; |
|
145 |
|
146 if ( iconSize != TSize( 0, 0 ) ) |
|
147 { |
|
148 ResizeIcon( aIcon, iconSize, aScaleMode ); |
|
149 } |
|
150 } |
|
151 |
|
152 // ----------------------------------------------------------------------------- |
|
153 // CreateAndSetDimmedIconL |
|
154 // Creates and sets a dimmed icon from the normal icon |
|
155 // by making a partially transparent version of it. |
|
156 // |
|
157 // @param aIcon The original icon |
|
158 // @param aDimmedIcon The dimmed icon |
|
159 // @param aScaleMode The preferred ScaleMode |
|
160 // ----------------------------------------------------------------------------- |
|
161 static void CreateAndSetDimmedIconL( CGulIcon*& aDimmedIcon, |
|
162 const CGulIcon* aIcon, |
|
163 TScaleMode aScaleMode ) |
|
164 { |
|
165 if ( aIcon ) |
|
166 { |
|
167 CFbsBitmap* mask = aIcon->Mask(); |
|
168 |
|
169 if ( mask && mask->DisplayMode() == EGray256 ) |
|
170 { |
|
171 CGulIcon* newIcon = CGulIcon::NewLC(); |
|
172 CFbsBitmap* newPic = new ( ELeave ) CFbsBitmap; |
|
173 CleanupStack::PushL( newPic ); |
|
174 |
|
175 newPic->Duplicate( aIcon->Bitmap()->Handle() ); |
|
176 newIcon->SetBitmap( newPic ); |
|
177 |
|
178 CFbsBitmap* newMask = new ( ELeave ) CFbsBitmap; |
|
179 |
|
180 User::LeaveIfError( newMask->Create( |
|
181 newIcon->Bitmap()->SizeInPixels(), EGray256 ) ); |
|
182 CleanupStack::PushL( newMask ); |
|
183 |
|
184 CFbsBitmapDevice* bitmapDevice = CFbsBitmapDevice::NewL( newMask ); |
|
185 CleanupStack::PushL( bitmapDevice ); |
|
186 |
|
187 CFbsBitGc* bitGc( NULL ); |
|
188 User::LeaveIfError( bitmapDevice->CreateContext( bitGc ) ); |
|
189 CleanupStack::PushL( bitGc ); |
|
190 |
|
191 bitGc->SetPenStyle( CGraphicsContext::ESolidPen ); |
|
192 bitGc->BitBlt( TPoint( 0, 0 ), mask ); |
|
193 |
|
194 newMask->LockHeap(); |
|
195 TInt w = mask->SizeInPixels().iWidth; |
|
196 TInt h = mask->SizeInPixels().iHeight; |
|
197 TInt dataStride = mask->DataStride() - w; |
|
198 unsigned char* address = (unsigned char *)newMask->DataAddress(); |
|
199 |
|
200 for ( TInt i = 0; i < h; ++i ) |
|
201 { |
|
202 for ( TInt j = 0; j < w; ++j ) |
|
203 { |
|
204 *address = KTransparency[*address]; |
|
205 ++address; |
|
206 } |
|
207 address += dataStride; |
|
208 } |
|
209 |
|
210 newMask->UnlockHeap(); |
|
211 newIcon->SetMask( newMask ); |
|
212 ReplaceIconStatic( aDimmedIcon, newIcon, aScaleMode ); |
|
213 |
|
214 CleanupStack::PopAndDestroy( 2 ); // bitmapDevice, bitGc |
|
215 CleanupStack::Pop( 3 ); // newIcon, newPic, newMask |
|
216 } |
|
217 } |
|
218 } |
|
219 // ============================ EXTENSION CLASS ================================ |
|
220 |
|
221 NONSHARABLE_CLASS( CAknButtonExtension ) : public CBase, MCoeControlHitTest |
|
222 { |
|
223 friend class CAknButton; |
|
224 |
|
225 public: |
|
226 // bitflags used to keep track of several button's internal features |
|
227 enum TFlags |
|
228 { |
|
229 EUseAdditionalMask, |
|
230 ECheckHitArea, |
|
231 EDimmed, |
|
232 ELongPressReported, |
|
233 EUseDefaultIconSize, |
|
234 EKeyRepeatEventReported, |
|
235 EUseDefaultMargins |
|
236 }; |
|
237 |
|
238 static CAknButtonExtension* NewL( CAknButton& aButton ); |
|
239 ~CAknButtonExtension(); |
|
240 |
|
241 // Starts the long press timer. |
|
242 void StartLongPressTimerL(); |
|
243 |
|
244 TBool HitRegionContains( const TPoint &aPoint, |
|
245 const CCoeControl &aControl ) const; |
|
246 |
|
247 void HandleFeedbackAreaChange(); |
|
248 private: |
|
249 |
|
250 CAknButtonExtension( CAknButton& aButton ); |
|
251 void ConstructL(); |
|
252 |
|
253 // Callback method for long press timer. |
|
254 static TInt ReportLongPressL( TAny* aThis ); |
|
255 |
|
256 // Handles long press. |
|
257 void DoReportLongPressL(); |
|
258 |
|
259 // Deletes pressed down bitmaps |
|
260 void DeletePressedBmps(); |
|
261 |
|
262 // Fetches bitmaps from resource provider (if one exists) |
|
263 TBool FetchProviderPressedBmpsL(); |
|
264 |
|
265 // Sets bitmaps to resource provider (if one exists) |
|
266 void SetProviderPressedBmpsL(); |
|
267 |
|
268 private: // Data |
|
269 |
|
270 CAknButton& iButton; |
|
271 CAknButton::TTooltipPosition iTooltipPosition; |
|
272 CAknPictographInterface* iPictographInterface; // not owned |
|
273 CPeriodic* iLongPressTimer; |
|
274 TInt iLongPressInterval; |
|
275 TFontUnderline iUnderlineStyle; |
|
276 RArray<TAknsItemID> iFrameAndCenterIds; |
|
277 CAknButton::TAlignment iVerticalIconAlignment; |
|
278 CAknButton::TAlignment iHorizontalIconAlignment; |
|
279 TMargins8 iMargins; |
|
280 TSize iIconSize; |
|
281 CAknButton::TTextAndIconAlignment iTextAndIconAlignment; |
|
282 TBitFlags iFlags; |
|
283 MTouchFeedback* iFeedback; |
|
284 CFbsBitmap* iPressedDownBmp; |
|
285 CFbsBitmap* iPressedDownBmpMask; |
|
286 CAknResourceProvider* iResourceProvider; |
|
287 }; |
|
288 |
|
289 // ============================ MEMBER FUNCTIONS =============================== |
|
290 |
|
291 // ----------------------------------------------------------------------------- |
|
292 // CAknButtonExtension::CAknButtonExtension |
|
293 // C++ default constructor. |
|
294 // ----------------------------------------------------------------------------- |
|
295 // |
|
296 CAknButtonExtension::CAknButtonExtension( CAknButton& aButton ) |
|
297 : iButton( aButton ), |
|
298 iTooltipPosition( CAknButton::EPositionTop ), |
|
299 iLongPressTimer( NULL ), |
|
300 iLongPressInterval( KLongPressInterval ), |
|
301 iUnderlineStyle( EUnderlineOff ), |
|
302 iFrameAndCenterIds( 2 ), |
|
303 iVerticalIconAlignment( CAknButton::ECenter ), |
|
304 iHorizontalIconAlignment( CAknButton::ECenter ), |
|
305 iTextAndIconAlignment( CAknButton::EIconBeforeText ), |
|
306 iResourceProvider( 0 ) |
|
307 { |
|
308 // default margins, these are applied to both text and icon |
|
309 iMargins.SetAllValuesTo( |
|
310 AknLayoutScalable_Avkon::aid_value_unit2().LayoutLine().iW / 10 ); |
|
311 |
|
312 // default icon size |
|
313 TRect rect( TSize( 100, 100 ) ); |
|
314 TAknLayoutRect layoutRect; |
|
315 layoutRect.LayoutRect( rect, |
|
316 AknLayoutScalable_Avkon::toolbar_button_pane_g10().LayoutLine() ); |
|
317 iIconSize = layoutRect.Rect().Size(); |
|
318 iFlags.Set( EUseDefaultIconSize ); |
|
319 iFlags.Set( EUseDefaultMargins ); |
|
320 } |
|
321 |
|
322 // ----------------------------------------------------------------------------- |
|
323 // CAknButtonExtension::~CAknButtonExtension |
|
324 // Destructor. |
|
325 // ----------------------------------------------------------------------------- |
|
326 // |
|
327 CAknButtonExtension::~CAknButtonExtension() |
|
328 { |
|
329 delete iLongPressTimer; |
|
330 iPictographInterface = NULL; // not owned |
|
331 iFrameAndCenterIds.Close(); |
|
332 DeletePressedBmps(); |
|
333 } |
|
334 |
|
335 // ----------------------------------------------------------------------------- |
|
336 // CAknButtonExtension::NewL |
|
337 // Symbian two-phased constructor. |
|
338 // ----------------------------------------------------------------------------- |
|
339 // |
|
340 CAknButtonExtension* CAknButtonExtension::NewL( CAknButton& aButton ) |
|
341 { |
|
342 CAknButtonExtension* ext = new ( ELeave ) CAknButtonExtension( aButton ); |
|
343 CleanupStack::PushL( ext ); |
|
344 ext->ConstructL(); |
|
345 CleanupStack::Pop( ext ); |
|
346 return ext; |
|
347 } |
|
348 |
|
349 // ----------------------------------------------------------------------------- |
|
350 // CAknButtonExtension::ConstructL |
|
351 // Symbian 2nd stage constructor. |
|
352 // ----------------------------------------------------------------------------- |
|
353 // |
|
354 void CAknButtonExtension::ConstructL() |
|
355 { |
|
356 // Normal frame and center |
|
357 iFrameAndCenterIds.AppendL( KAknsIIDQsnFrButtonNormal ); |
|
358 iFrameAndCenterIds.AppendL( KAknsIIDQsnFrButtonCenterNormal ); |
|
359 // Latched frame and center |
|
360 iFrameAndCenterIds.AppendL( KAknsIIDQsnFrButtonPressed ); |
|
361 iFrameAndCenterIds.AppendL( KAknsIIDQsnFrButtonCenterPressed ); |
|
362 // Dimmed frame and center |
|
363 iFrameAndCenterIds.AppendL( KAknsIIDQsnFrButtonInactive ); |
|
364 iFrameAndCenterIds.AppendL( KAknsIIDQsnFrButtonCenterInactive ); |
|
365 // Pressed frame and center |
|
366 iFrameAndCenterIds.AppendL( KAknsIIDQsnFrButtonPressed ); |
|
367 iFrameAndCenterIds.AppendL( KAknsIIDQsnFrButtonCenterPressed ); |
|
368 // Latched dimmed frame and center |
|
369 iFrameAndCenterIds.AppendL( KAknsIIDQsnFrButtonInactive ); |
|
370 iFrameAndCenterIds.AppendL( KAknsIIDQsnFrButtonCenterInactive ); |
|
371 } |
|
372 |
|
373 // ----------------------------------------------------------------------------- |
|
374 // CAknButtonExtension::StartLongPressTimerL |
|
375 // Starts the long press timer. The timer is constructed when used for the |
|
376 // first time. |
|
377 // ----------------------------------------------------------------------------- |
|
378 // |
|
379 void CAknButtonExtension::StartLongPressTimerL() |
|
380 { |
|
381 if ( !iLongPressTimer ) |
|
382 { |
|
383 iLongPressTimer = CPeriodic::NewL( CActive::EPriorityStandard ); |
|
384 } |
|
385 else if ( iLongPressTimer->IsActive() ) |
|
386 { |
|
387 iLongPressTimer->Cancel(); |
|
388 } |
|
389 |
|
390 if ( iLongPressInterval > 0 ) |
|
391 { |
|
392 iLongPressTimer->Start( iLongPressInterval, iLongPressInterval, |
|
393 TCallBack( ReportLongPressL, this ) ); |
|
394 } |
|
395 } |
|
396 |
|
397 // ----------------------------------------------------------------------------- |
|
398 // CAknButtonExtension::ReportLongPressL |
|
399 // ----------------------------------------------------------------------------- |
|
400 // |
|
401 TInt CAknButtonExtension::ReportLongPressL( TAny* aThis ) |
|
402 { |
|
403 static_cast<CAknButtonExtension*>( aThis )->DoReportLongPressL(); |
|
404 return 0; |
|
405 } |
|
406 |
|
407 // ----------------------------------------------------------------------------- |
|
408 // CAknButtonExtension::DoReportLongPressL |
|
409 // ----------------------------------------------------------------------------- |
|
410 // |
|
411 void CAknButtonExtension::DoReportLongPressL() |
|
412 { |
|
413 if ( iLongPressTimer && iLongPressTimer->IsActive() ) |
|
414 { |
|
415 iLongPressTimer->Cancel(); |
|
416 } |
|
417 |
|
418 if ( iButton.Observer() ) |
|
419 { |
|
420 iButton.Observer()->HandleControlEventL( &iButton, |
|
421 static_cast<MCoeControlObserver::TCoeEvent>( |
|
422 CAknButton::ELongPressEvent ) ); |
|
423 |
|
424 iFlags.Set( ELongPressReported ); |
|
425 } |
|
426 } |
|
427 |
|
428 |
|
429 // ----------------------------------------------------------------------------- |
|
430 // CAknButtonExtension::DeletePressedBmps |
|
431 // Deletes pressed down bitmaps |
|
432 // ----------------------------------------------------------------------------- |
|
433 // |
|
434 void CAknButtonExtension::DeletePressedBmps() |
|
435 { |
|
436 delete iPressedDownBmp; |
|
437 delete iPressedDownBmpMask; |
|
438 iPressedDownBmp = 0; |
|
439 iPressedDownBmpMask = 0; |
|
440 } |
|
441 |
|
442 |
|
443 // ----------------------------------------------------------------------------- |
|
444 // CAknButtonExtension::FetchProviderPressedBmpsL |
|
445 // Fetches bitmaps from provider (if one exists). Returns ETrue if bitmaps were |
|
446 // found. |
|
447 // ----------------------------------------------------------------------------- |
|
448 // |
|
449 TBool CAknButtonExtension::FetchProviderPressedBmpsL() |
|
450 { |
|
451 TBool bmpsFetched = EFalse; |
|
452 if ( iResourceProvider ) |
|
453 { |
|
454 MAknResourceItem* resourceItem = 0; |
|
455 |
|
456 // Check if resource provider has item for KPressedFrameId |
|
457 if ( iResourceProvider->GetResourceL( |
|
458 KPressedFrameId, resourceItem ) != KErrNotFound |
|
459 && resourceItem ) |
|
460 { |
|
461 DeletePressedBmps(); |
|
462 static_cast<CAknBitmapResourceItem*>( resourceItem )->GetBitmaps( |
|
463 iPressedDownBmp, iPressedDownBmpMask ); |
|
464 delete resourceItem; |
|
465 |
|
466 // Check if found bitmap size matches with button size |
|
467 if ( iPressedDownBmp |
|
468 && iPressedDownBmpMask |
|
469 && iPressedDownBmp->SizeInPixels() == iButton.Size() ) |
|
470 { |
|
471 bmpsFetched = ETrue; |
|
472 } |
|
473 // If not, delete the fetched bitmaps |
|
474 else |
|
475 { |
|
476 DeletePressedBmps(); |
|
477 } |
|
478 } |
|
479 } |
|
480 return bmpsFetched; |
|
481 } |
|
482 |
|
483 |
|
484 // ----------------------------------------------------------------------------- |
|
485 // CAknButtonExtension::SetProviderPressedBmpsL |
|
486 // Sets bitmaps to provider (if one exists). |
|
487 // ----------------------------------------------------------------------------- |
|
488 // |
|
489 void CAknButtonExtension::SetProviderPressedBmpsL() |
|
490 { |
|
491 if ( iResourceProvider ) |
|
492 { |
|
493 CAknBitmapResourceItem* resourceItem = |
|
494 CAknBitmapResourceItem::NewL( KPressedFrameId ); |
|
495 resourceItem->SetBitmapsL( iPressedDownBmp, iPressedDownBmpMask ); |
|
496 iResourceProvider->SetResourceL( |
|
497 KPressedFrameId, |
|
498 static_cast<MAknResourceItem*>( resourceItem ) ); |
|
499 } |
|
500 } |
|
501 |
|
502 |
|
503 |
|
504 // |
|
505 TBool CAknButtonExtension::HitRegionContains( const TPoint &aPoint, |
|
506 const CCoeControl& /*aControl*/ ) const |
|
507 { |
|
508 TBool retval = EFalse; |
|
509 |
|
510 TRAP_IGNORE( retval = iButton.HitAreaContainsL( aPoint, iFlags.IsSet( ECheckHitArea ) ) ); |
|
511 |
|
512 return retval; |
|
513 } |
|
514 |
|
515 void CAknButtonExtension::HandleFeedbackAreaChange() |
|
516 { |
|
517 // it is possible that feedback does not exist, eg. while booting. |
|
518 // try getting one, and give up if that fails. |
|
519 if ( !iFeedback ) |
|
520 { |
|
521 iFeedback = MTouchFeedback::Instance(); |
|
522 } |
|
523 if ( !iFeedback ) |
|
524 { |
|
525 return; |
|
526 } |
|
527 |
|
528 if ( iButton.ButtonFlags() & KAknButtonHitTest ) |
|
529 { |
|
530 // no registry feedback if shaped buttons are used |
|
531 iFeedback->RemoveFeedbackArea( &iButton, 0 ); |
|
532 } |
|
533 else |
|
534 { |
|
535 CFeedbackSpec* spec = CFeedbackSpec::New(); |
|
536 if (spec) |
|
537 { |
|
538 spec->AddFeedback( ETouchEventStylusDown, |
|
539 ETouchFeedbackBasicButton ); |
|
540 spec->AddFeedback( ETouchEventStylusUp, |
|
541 ETouchFeedbackBasicButton, |
|
542 ETouchFeedbackVibra ); |
|
543 iFeedback->SetFeedbackArea( &iButton, 0, iButton.Rect(), spec ); |
|
544 delete spec; |
|
545 } |
|
546 } |
|
547 } |
|
548 |
|
549 // ============================ EXTENSION CLASS ================================ |
|
550 |
|
551 NONSHARABLE_CLASS( CAknButtonStateExtension ) : public CBase |
|
552 { |
|
553 friend class CAknButtonState; |
|
554 |
|
555 public: |
|
556 static CAknButtonStateExtension* NewL(); |
|
557 ~CAknButtonStateExtension(); |
|
558 |
|
559 void ConfigureExtensionFromResourceL( const TInt aResourceId ); |
|
560 void ConfigureExtensionFromResourceL( TResourceReader& aReader ); |
|
561 |
|
562 private: |
|
563 CAknButtonStateExtension(); |
|
564 void ConstructL(); |
|
565 |
|
566 private: // Data |
|
567 TBool iGeneratedDimmedIcon; |
|
568 HBufC* iFilePath; |
|
569 TInt iBmpId; |
|
570 TInt iMaskId; |
|
571 TInt iDimmedBmpId; |
|
572 TInt iDimmedMaskId; |
|
573 TInt iPressedBmpId; |
|
574 TInt iPressedMaskId; |
|
575 TInt iHoverBmpId; |
|
576 TInt iHoverMaskId; |
|
577 TAknsItemID iId; |
|
578 TAknsItemID iDimmedId; |
|
579 TAknsItemID iPressedId; |
|
580 TAknsItemID iHoverId; |
|
581 TScaleMode iScaleMode; |
|
582 }; |
|
583 |
|
584 // ============================ MEMBER FUNCTIONS =============================== |
|
585 |
|
586 // ----------------------------------------------------------------------------- |
|
587 // CAknButtonStateExtension::CAknButtonStateExtension |
|
588 // C++ default constructor. |
|
589 // ----------------------------------------------------------------------------- |
|
590 // |
|
591 CAknButtonStateExtension::CAknButtonStateExtension() |
|
592 : iGeneratedDimmedIcon ( EFalse ), iBmpId( -1 ), iMaskId( -1 ), |
|
593 iDimmedBmpId( -1 ), iDimmedMaskId( -1 ), iPressedBmpId( -1 ), |
|
594 iPressedMaskId( -1 ), iHoverBmpId( -1 ), iHoverMaskId( -1 ), |
|
595 iId( KAknsIIDNone ), iDimmedId( KAknsIIDNone ), |
|
596 iPressedId( KAknsIIDNone ), iHoverId( KAknsIIDNone ), |
|
597 iScaleMode( EAspectRatioNotPreserved ) |
|
598 { |
|
599 } |
|
600 |
|
601 // ----------------------------------------------------------------------------- |
|
602 // CAknButtonStateExtension::~CAknButtonStateExtension |
|
603 // Destructor. |
|
604 // ----------------------------------------------------------------------------- |
|
605 // |
|
606 CAknButtonStateExtension::~CAknButtonStateExtension() |
|
607 { |
|
608 delete iFilePath; |
|
609 } |
|
610 |
|
611 // ----------------------------------------------------------------------------- |
|
612 // CAknButtonStateExtension::NewL |
|
613 // Symbian two-phased constructor. |
|
614 // ----------------------------------------------------------------------------- |
|
615 // |
|
616 CAknButtonStateExtension* CAknButtonStateExtension::NewL() |
|
617 { |
|
618 CAknButtonStateExtension* ext = new ( ELeave ) CAknButtonStateExtension; |
|
619 CleanupStack::PushL( ext ); |
|
620 ext->ConstructL(); |
|
621 CleanupStack::Pop( ext ); |
|
622 return ext; |
|
623 } |
|
624 |
|
625 // ----------------------------------------------------------------------------- |
|
626 // CAknButtonStateExtension::ConstructL |
|
627 // Symbian 2nd stage constructor. |
|
628 // ----------------------------------------------------------------------------- |
|
629 // |
|
630 void CAknButtonStateExtension::ConstructL() |
|
631 { |
|
632 } //lint !e1762 function cannot be made const |
|
633 |
|
634 // ----------------------------------------------------------------------------- |
|
635 // CAknButtonStateExtension::ConfigureExtensionFromResourceL |
|
636 // ----------------------------------------------------------------------------- |
|
637 // |
|
638 void CAknButtonStateExtension::ConfigureExtensionFromResourceL( |
|
639 const TInt aResourceId ) |
|
640 { |
|
641 |
|
642 if ( aResourceId ) |
|
643 { |
|
644 TResourceReader reader; |
|
645 CCoeEnv::Static()->CreateResourceReaderLC( reader, aResourceId ); |
|
646 ConfigureExtensionFromResourceL( reader ); |
|
647 CleanupStack::PopAndDestroy(); |
|
648 } |
|
649 } |
|
650 |
|
651 // ----------------------------------------------------------------------------- |
|
652 // CAknButtonStateExtension::ConfigureExtensionFromResourceL |
|
653 // ----------------------------------------------------------------------------- |
|
654 // |
|
655 void CAknButtonStateExtension::ConfigureExtensionFromResourceL( |
|
656 TResourceReader& aReader ) |
|
657 { |
|
658 TInt version = aReader.ReadInt8(); |
|
659 |
|
660 // bmp ids |
|
661 TInt major = aReader.ReadInt32(); |
|
662 TInt minor = aReader.ReadInt32(); |
|
663 |
|
664 if ( major != 0 && minor != 0 ) |
|
665 { |
|
666 iId.Set( major, minor ); |
|
667 } |
|
668 |
|
669 // dimmed ids |
|
670 major = aReader.ReadInt32(); |
|
671 minor = aReader.ReadInt32(); |
|
672 |
|
673 if ( major != 0 && minor != 0 ) |
|
674 { |
|
675 iDimmedId.Set( major, minor ); |
|
676 } |
|
677 |
|
678 // pressed ids |
|
679 major = aReader.ReadInt32(); |
|
680 minor = aReader.ReadInt32(); |
|
681 |
|
682 if ( major != 0 && minor != 0 ) |
|
683 { |
|
684 iPressedId.Set( major, minor ); |
|
685 } |
|
686 |
|
687 // hover ids |
|
688 major = aReader.ReadInt32(); |
|
689 minor = aReader.ReadInt32(); |
|
690 |
|
691 if ( major != 0 && minor != 0 ) |
|
692 { |
|
693 iHoverId.Set( major, minor ); |
|
694 } |
|
695 } |
|
696 |
|
697 // ============================ MEMBER FUNCTIONS =============================== |
|
698 |
|
699 // ----------------------------------------------------------------------------- |
|
700 // CAknButtonState::CAknButtonState |
|
701 // Constructor |
|
702 // ----------------------------------------------------------------------------- |
|
703 // |
|
704 EXPORT_C CAknButtonState::CAknButtonState( const TInt aFlags ) : |
|
705 iFlags( aFlags ) |
|
706 { |
|
707 } |
|
708 |
|
709 // ----------------------------------------------------------------------------- |
|
710 // CAknButtonState::~CAknButtonState |
|
711 // Destructor |
|
712 // ----------------------------------------------------------------------------- |
|
713 // |
|
714 EXPORT_C CAknButtonState::~CAknButtonState() |
|
715 { |
|
716 delete iIcon; |
|
717 delete iDimmedIcon; |
|
718 delete iPressedIcon; |
|
719 delete iHoverIcon; |
|
720 delete iText; |
|
721 delete iHelpText; |
|
722 delete iExtension; |
|
723 } |
|
724 |
|
725 // ----------------------------------------------------------------------------- |
|
726 // CAknButtonState::ConstructFromResourceL |
|
727 // Constructs the button state from the resources |
|
728 // ----------------------------------------------------------------------------- |
|
729 // |
|
730 EXPORT_C void CAknButtonState::ConstructFromResourceL( TResourceReader& aReader ) |
|
731 { |
|
732 if ( !iExtension ) |
|
733 { |
|
734 iExtension = CAknButtonStateExtension::NewL(); |
|
735 } |
|
736 |
|
737 // flags |
|
738 iFlags = aReader.ReadInt16(); |
|
739 |
|
740 // txt |
|
741 TPtrC txt = aReader.ReadTPtrC(); |
|
742 SetTextL( txt ); |
|
743 |
|
744 // helptxt |
|
745 TPtrC helpTxt = aReader.ReadTPtrC(); |
|
746 SetHelpTextL( helpTxt ); |
|
747 |
|
748 if ( iExtension->iFilePath ) |
|
749 { |
|
750 delete iExtension->iFilePath; |
|
751 iExtension->iFilePath = NULL; |
|
752 } |
|
753 |
|
754 // bmpfile |
|
755 iExtension->iFilePath = aReader.ReadTPtrC().AllocL(); |
|
756 |
|
757 // bmpid & bmpmask |
|
758 iExtension->iBmpId = aReader.ReadInt16(); |
|
759 iExtension->iMaskId = aReader.ReadInt16(); |
|
760 |
|
761 // dim_bmpid & dim_bmpmask |
|
762 iExtension->iDimmedBmpId = aReader.ReadInt16(); |
|
763 iExtension->iDimmedMaskId = aReader.ReadInt16(); |
|
764 |
|
765 // press_bmpid & press_bmpmask |
|
766 iExtension->iPressedBmpId = aReader.ReadInt16(); |
|
767 iExtension->iPressedMaskId = aReader.ReadInt16(); |
|
768 |
|
769 // hover_bmpid & hover_bmpmask |
|
770 iExtension->iHoverBmpId = aReader.ReadInt16(); |
|
771 iExtension->iHoverMaskId = aReader.ReadInt16(); |
|
772 |
|
773 // extension |
|
774 TInt extensionLink = aReader.ReadInt32(); |
|
775 |
|
776 if ( extensionLink != 0 ) |
|
777 { |
|
778 iExtension->ConfigureExtensionFromResourceL( extensionLink ); |
|
779 } |
|
780 |
|
781 LoadButtonIcon( iIcon ); |
|
782 LoadButtonIcon( iDimmedIcon ); |
|
783 LoadButtonIcon( iPressedIcon ); |
|
784 LoadButtonIcon( iHoverIcon ); |
|
785 } |
|
786 |
|
787 // ----------------------------------------------------------------------------- |
|
788 // CAknButtonState::ConstructL |
|
789 // |
|
790 // ----------------------------------------------------------------------------- |
|
791 // |
|
792 EXPORT_C void CAknButtonState::ConstructL( CGulIcon* aIcon, |
|
793 CGulIcon* aDimmedIcon, |
|
794 CGulIcon* aPressedIcon, |
|
795 CGulIcon* aHoverIcon, |
|
796 const TDesC& aText, |
|
797 const TDesC& aHelpText ) |
|
798 { |
|
799 if ( !iExtension ) |
|
800 { |
|
801 iExtension = CAknButtonStateExtension::NewL(); |
|
802 } |
|
803 |
|
804 SetIcon( aIcon ); |
|
805 SetDimmedIcon( aDimmedIcon ); |
|
806 SetPressedIcon( aPressedIcon ); |
|
807 SetHoverIcon( aHoverIcon ); |
|
808 SetTextL( aText ); |
|
809 SetHelpTextL( aHelpText ); |
|
810 } |
|
811 |
|
812 // ----------------------------------------------------------------------------- |
|
813 // CAknButtonState:: |
|
814 // Symbian 2nd phase constructor. |
|
815 // ----------------------------------------------------------------------------- |
|
816 // |
|
817 EXPORT_C void CAknButtonState::ConstructL( const TDesC& aFilePath, |
|
818 const TInt aBmpId, |
|
819 const TInt aMaskId, |
|
820 const TInt aDimmedBmpId, |
|
821 const TInt aDimmedMaskId, |
|
822 const TInt aPressedBmpId, |
|
823 const TInt aPressedMaskId, |
|
824 const TInt aHoverBmpId, |
|
825 const TInt aHoverMaskId, |
|
826 const TDesC& aText, |
|
827 const TDesC& aHelpText, |
|
828 const TAknsItemID& aId, |
|
829 const TAknsItemID& aDimmedId, |
|
830 const TAknsItemID& aPressedId, |
|
831 const TAknsItemID& aHoverId ) |
|
832 { |
|
833 UpdateIconL( aFilePath, aBmpId, aMaskId, aDimmedBmpId, aDimmedMaskId, |
|
834 aPressedBmpId, aPressedMaskId, aHoverBmpId, aHoverMaskId, aId, aDimmedId, |
|
835 aPressedId, aHoverId ); |
|
836 |
|
837 SetTextL( aText ); |
|
838 SetHelpTextL( aHelpText ); |
|
839 } |
|
840 |
|
841 // ----------------------------------------------------------------------------- |
|
842 // CAknButtonState::Icon |
|
843 // Returns the icon for the normal state. |
|
844 // ----------------------------------------------------------------------------- |
|
845 // |
|
846 EXPORT_C const CGulIcon* CAknButtonState::Icon() const |
|
847 { |
|
848 return iIcon; |
|
849 } |
|
850 |
|
851 // ----------------------------------------------------------------------------- |
|
852 // CAknButtonState::DimmedIcon |
|
853 // Returns the icon for the dimmed state |
|
854 // ----------------------------------------------------------------------------- |
|
855 // |
|
856 EXPORT_C const CGulIcon* CAknButtonState::DimmedIcon() const |
|
857 { |
|
858 return iDimmedIcon; |
|
859 } |
|
860 |
|
861 // ----------------------------------------------------------------------------- |
|
862 // CAknButtonState::PressedIcon |
|
863 // Returns the icon for the pressed but not released state. |
|
864 // ----------------------------------------------------------------------------- |
|
865 // |
|
866 EXPORT_C const CGulIcon* CAknButtonState::PressedIcon() const |
|
867 { |
|
868 return iPressedIcon; |
|
869 } |
|
870 |
|
871 // ----------------------------------------------------------------------------- |
|
872 // CAknButtonState::HoverIcon |
|
873 // Returns the icon for the hover state. |
|
874 // ----------------------------------------------------------------------------- |
|
875 // |
|
876 EXPORT_C const CGulIcon* CAknButtonState::HoverIcon() const |
|
877 { |
|
878 return iHoverIcon; |
|
879 } |
|
880 |
|
881 // ----------------------------------------------------------------------------- |
|
882 // CAknButtonState::Text |
|
883 // Returns the text inside the button. |
|
884 // ----------------------------------------------------------------------------- |
|
885 // |
|
886 EXPORT_C const TDesC& CAknButtonState::Text() const |
|
887 { |
|
888 if ( iText ) |
|
889 { |
|
890 return *iText; |
|
891 } |
|
892 else |
|
893 { |
|
894 return KNullDesC(); |
|
895 } |
|
896 } |
|
897 |
|
898 // ----------------------------------------------------------------------------- |
|
899 // CAknButtonState::HelpText |
|
900 // Returns the text inside the help note. |
|
901 // ----------------------------------------------------------------------------- |
|
902 // |
|
903 EXPORT_C const TDesC& CAknButtonState::HelpText() const |
|
904 { |
|
905 if ( iHelpText ) |
|
906 { |
|
907 return *iHelpText; |
|
908 } |
|
909 else |
|
910 { |
|
911 return KNullDesC(); |
|
912 } |
|
913 } |
|
914 |
|
915 // ----------------------------------------------------------------------------- |
|
916 // CAknButtonState::Flags |
|
917 // Returns the state flags. |
|
918 // ----------------------------------------------------------------------------- |
|
919 // |
|
920 EXPORT_C TInt CAknButtonState::Flags() const |
|
921 { |
|
922 return iFlags; |
|
923 } |
|
924 |
|
925 // ----------------------------------------------------------------------------- |
|
926 // CAknButtonState::SetIcon |
|
927 // Sets the icon for the normal state. |
|
928 // ----------------------------------------------------------------------------- |
|
929 // |
|
930 EXPORT_C void CAknButtonState::SetIcon( CGulIcon* aIcon ) |
|
931 { |
|
932 ReplaceIcon( iIcon, aIcon ); |
|
933 |
|
934 if ( iExtension->iGeneratedDimmedIcon ) |
|
935 { |
|
936 TRAP_IGNORE( CreateAndSetDimmedIconL( iDimmedIcon, iIcon, |
|
937 iExtension->iScaleMode ) ); |
|
938 } |
|
939 } |
|
940 |
|
941 // ----------------------------------------------------------------------------- |
|
942 // CAknButtonState::SetDimmedIcon |
|
943 // Sets the icon for the dimmed state. |
|
944 // ----------------------------------------------------------------------------- |
|
945 // |
|
946 EXPORT_C void CAknButtonState::SetDimmedIcon( CGulIcon* aDimmedIcon ) |
|
947 { |
|
948 ReplaceIcon( iDimmedIcon, aDimmedIcon ); |
|
949 } |
|
950 |
|
951 // ----------------------------------------------------------------------------- |
|
952 // CAknButtonState::SetPressedIcon |
|
953 // Sets the icon for the pressed but not released state. |
|
954 // ----------------------------------------------------------------------------- |
|
955 // |
|
956 EXPORT_C void CAknButtonState::SetPressedIcon( CGulIcon* aPressedIcon ) |
|
957 { |
|
958 ReplaceIcon( iPressedIcon, aPressedIcon ); |
|
959 } |
|
960 |
|
961 // ----------------------------------------------------------------------------- |
|
962 // CAknButtonState::SetHoverIcon |
|
963 // Sets the icon for the hover state. |
|
964 // ----------------------------------------------------------------------------- |
|
965 // |
|
966 EXPORT_C void CAknButtonState::SetHoverIcon( CGulIcon* aHoverIcon ) |
|
967 { |
|
968 ReplaceIcon( iHoverIcon, aHoverIcon ); |
|
969 } |
|
970 |
|
971 // ----------------------------------------------------------------------------- |
|
972 // CAknButtonState::ReplaceIcon |
|
973 // Replaces the given icon with a new one. If the original icon had its size set |
|
974 // then the new icon is scaled to that size. |
|
975 // ----------------------------------------------------------------------------- |
|
976 // |
|
977 void CAknButtonState::ReplaceIcon( CGulIcon*& aIcon, CGulIcon* aNewIcon ) |
|
978 { |
|
979 ReplaceIconStatic( aIcon, aNewIcon, iExtension->iScaleMode ); |
|
980 } |
|
981 |
|
982 |
|
983 // ----------------------------------------------------------------------------- |
|
984 // CAknButtonState::SetTextL |
|
985 // Sets the text inside the button |
|
986 // ----------------------------------------------------------------------------- |
|
987 // |
|
988 EXPORT_C void CAknButtonState::SetTextL( const TDesC& aText ) |
|
989 { |
|
990 delete iText; |
|
991 iText = NULL; |
|
992 |
|
993 iText = aText.AllocL(); |
|
994 } |
|
995 |
|
996 // ----------------------------------------------------------------------------- |
|
997 // CAknButtonState::SetHelpTextL |
|
998 // Sets the text inside the help note |
|
999 // ----------------------------------------------------------------------------- |
|
1000 // |
|
1001 EXPORT_C void CAknButtonState::SetHelpTextL( const TDesC& aHelpText ) |
|
1002 { |
|
1003 delete iHelpText; |
|
1004 iHelpText = NULL; |
|
1005 |
|
1006 iHelpText = aHelpText.AllocL(); |
|
1007 } |
|
1008 |
|
1009 // ----------------------------------------------------------------------------- |
|
1010 // CAknButtonState:: |
|
1011 // Sets state flags. |
|
1012 // ----------------------------------------------------------------------------- |
|
1013 // |
|
1014 EXPORT_C void CAknButtonState::SetFlags( const TInt aFlags ) |
|
1015 { |
|
1016 iFlags = aFlags; |
|
1017 } |
|
1018 |
|
1019 // ----------------------------------------------------------------------------- |
|
1020 // CAknButtonState::UpdateIconL |
|
1021 // Updates button icons. |
|
1022 // ----------------------------------------------------------------------------- |
|
1023 void CAknButtonState::UpdateIconL( const TDesC& aFilePath, |
|
1024 const TInt aBmpId, |
|
1025 const TInt aMaskId, |
|
1026 const TInt aDimmedBmpId, |
|
1027 const TInt aDimmedMaskId, |
|
1028 const TInt aPressedBmpId, |
|
1029 const TInt aPressedMaskId, |
|
1030 const TInt aHoverBmpId, |
|
1031 const TInt aHoverMaskId, |
|
1032 const TAknsItemID& aId, |
|
1033 const TAknsItemID& aDimmedId, |
|
1034 const TAknsItemID& aPressedId, |
|
1035 const TAknsItemID& aHoverId ) |
|
1036 |
|
1037 { |
|
1038 if ( !iExtension ) |
|
1039 { |
|
1040 iExtension = CAknButtonStateExtension::NewL(); |
|
1041 } |
|
1042 |
|
1043 if ( iExtension->iFilePath ) |
|
1044 { |
|
1045 delete iExtension->iFilePath; |
|
1046 iExtension->iFilePath = NULL; |
|
1047 } |
|
1048 |
|
1049 // try to save some ram by defaulting to avkon bitmap file |
|
1050 if ( aFilePath != KAvkonBitmapFile ) |
|
1051 { |
|
1052 iExtension->iFilePath = aFilePath.AllocL(); |
|
1053 } |
|
1054 |
|
1055 iExtension->iBmpId = aBmpId; |
|
1056 iExtension->iMaskId = aMaskId; |
|
1057 iExtension->iDimmedBmpId = aDimmedBmpId; |
|
1058 iExtension->iDimmedMaskId = aDimmedMaskId; |
|
1059 iExtension->iPressedBmpId = aPressedBmpId; |
|
1060 iExtension->iPressedMaskId = aPressedMaskId; |
|
1061 iExtension->iHoverBmpId = aHoverBmpId; |
|
1062 iExtension->iHoverMaskId = aHoverMaskId; |
|
1063 iExtension->iId = aId; |
|
1064 iExtension->iDimmedId = aDimmedId; |
|
1065 iExtension->iPressedId = aPressedId; |
|
1066 iExtension->iHoverId = aHoverId; |
|
1067 |
|
1068 LoadButtonIcon( iIcon ); |
|
1069 LoadButtonIcon( iDimmedIcon ); |
|
1070 LoadButtonIcon( iPressedIcon ); |
|
1071 LoadButtonIcon( iHoverIcon ); |
|
1072 } |
|
1073 |
|
1074 // ----------------------------------------------------------------------------- |
|
1075 // CAknButtonState::SizeChanged |
|
1076 // Scales function graphics to the given size |
|
1077 // ----------------------------------------------------------------------------- |
|
1078 // |
|
1079 EXPORT_C void CAknButtonState::SizeChanged( const TRect& aRect, |
|
1080 TScaleMode aScaleMode ) |
|
1081 { |
|
1082 ScaleIcons( aRect.Size(), aScaleMode ); |
|
1083 } |
|
1084 |
|
1085 // ----------------------------------------------------------------------------- |
|
1086 // CAknButtonState::HasText |
|
1087 // Returns ETrue if the text inside button is not empty or space. |
|
1088 // ----------------------------------------------------------------------------- |
|
1089 // |
|
1090 EXPORT_C TBool CAknButtonState::HasText() const |
|
1091 { |
|
1092 if ( !iText ) |
|
1093 return EFalse; |
|
1094 |
|
1095 TBool ret = EFalse; |
|
1096 for ( TInt i = 0; i < iText->Des().Length(); i++ ) |
|
1097 { |
|
1098 TChar c ( (iText->Des())[i]); |
|
1099 |
|
1100 // TChar::TCategory cat = c.GetCategory(); |
|
1101 if ( !c.IsSpace() /*&& cat != TChar::ECoCategory*/ ) |
|
1102 { |
|
1103 // not space and not private use char |
|
1104 ret = ETrue; |
|
1105 break; |
|
1106 } |
|
1107 } |
|
1108 |
|
1109 return ret; |
|
1110 } |
|
1111 |
|
1112 // ----------------------------------------------------------------------------- |
|
1113 // CAknButtonState::HasHelp |
|
1114 // Returns ETrue if the text inside the help note is not empty or space. |
|
1115 // ----------------------------------------------------------------------------- |
|
1116 // |
|
1117 EXPORT_C TBool CAknButtonState::HasHelp() const |
|
1118 { |
|
1119 if ( !iHelpText ) |
|
1120 return EFalse; |
|
1121 |
|
1122 TBool ret = EFalse; |
|
1123 for ( TInt i = 0; i < iHelpText->Des().Length(); i++ ) |
|
1124 { |
|
1125 TChar c( ( *iHelpText )[i] ); |
|
1126 |
|
1127 // TChar::TCategory cat = c.GetCategory(); |
|
1128 if ( !c.IsSpace() /*&& cat != TChar::ECoCategory*/ ) |
|
1129 { |
|
1130 // not space and not private use char |
|
1131 ret = ETrue; |
|
1132 break; |
|
1133 } |
|
1134 } |
|
1135 |
|
1136 return ret; |
|
1137 } |
|
1138 |
|
1139 // ----------------------------------------------------------------------------- |
|
1140 // CAknButtonState::HandleResourceChange |
|
1141 // Handles changes in state's environment. |
|
1142 // ----------------------------------------------------------------------------- |
|
1143 // |
|
1144 void CAknButtonState::HandleResourceChange( TInt aType ) |
|
1145 { |
|
1146 // Update icons if skin is changed. KEikDynamicLayoutVariantSwitch event is |
|
1147 // handled via SizeChanged. |
|
1148 if ( aType == KAknsMessageSkinChange ) |
|
1149 { |
|
1150 LoadButtonIcon( iIcon ); |
|
1151 LoadButtonIcon( iDimmedIcon ); |
|
1152 LoadButtonIcon( iPressedIcon ); |
|
1153 LoadButtonIcon( iHoverIcon ); |
|
1154 |
|
1155 // generated dimmed state icon has to be regenerated |
|
1156 if ( iExtension->iGeneratedDimmedIcon ) |
|
1157 { |
|
1158 TRAP_IGNORE( CreateAndSetDimmedIconL( iDimmedIcon, iIcon, |
|
1159 iExtension->iScaleMode ) ); |
|
1160 } |
|
1161 } |
|
1162 } |
|
1163 |
|
1164 // ----------------------------------------------------------------------------- |
|
1165 // CAknButtonState::SetIconScaleMode |
|
1166 // Sets default scaling mode. |
|
1167 // ----------------------------------------------------------------------------- |
|
1168 // |
|
1169 void CAknButtonState::SetIconScaleMode( const TScaleMode aScaleMode ) |
|
1170 { |
|
1171 iExtension->iScaleMode = aScaleMode; |
|
1172 } |
|
1173 |
|
1174 // ----------------------------------------------------------------------------- |
|
1175 // CAknButtonState::CreateButtonIconL |
|
1176 // Creates one of the icons |
|
1177 // ----------------------------------------------------------------------------- |
|
1178 // |
|
1179 void CAknButtonState::CreateButtonIconL( CGulIcon*& aIcon, |
|
1180 const TDesC& aFilePath, |
|
1181 TInt aBmpId, |
|
1182 TInt aMaskId, |
|
1183 const TAknsItemID& aId ) const |
|
1184 { |
|
1185 MAknsSkinInstance* skin = AknsUtils::SkinInstance(); |
|
1186 |
|
1187 if ( aIcon ) |
|
1188 { |
|
1189 if ( ( aId != KAknsIIDNone && skin ) || aBmpId != -1 ) |
|
1190 { |
|
1191 delete aIcon; |
|
1192 aIcon = NULL; |
|
1193 } |
|
1194 } |
|
1195 |
|
1196 if ( aFilePath == KNullDesC || aBmpId == -1 ) |
|
1197 { |
|
1198 if ( aId != KAknsIIDNone && skin ) |
|
1199 { |
|
1200 aIcon = AknsUtils::CreateGulIconL( skin, aId, EFalse ); |
|
1201 } |
|
1202 } |
|
1203 else |
|
1204 { |
|
1205 if ( aId != KAknsIIDNone && skin ) |
|
1206 { |
|
1207 aIcon = AknsUtils::CreateGulIconL( skin, aId, aFilePath, aBmpId, |
|
1208 aMaskId); |
|
1209 } |
|
1210 else |
|
1211 { |
|
1212 CFbsBitmap* bmp; |
|
1213 CFbsBitmap* mask; |
|
1214 AknIconUtils::CreateIconLC( bmp, mask, aFilePath, aBmpId, aMaskId); |
|
1215 aIcon = CGulIcon::NewL( bmp, mask ); // ownership passed |
|
1216 CleanupStack::Pop( 2 ); |
|
1217 } |
|
1218 } |
|
1219 } |
|
1220 |
|
1221 // ----------------------------------------------------------------------------- |
|
1222 // CAknButtonState::LoadButtonIcon |
|
1223 // Reloads one button icon. |
|
1224 // ----------------------------------------------------------------------------- |
|
1225 // |
|
1226 void CAknButtonState::LoadButtonIcon( CGulIcon*& aIcon ) const |
|
1227 { |
|
1228 TSize iconSize( 0, 0 ); |
|
1229 |
|
1230 if ( aIcon && aIcon->Bitmap() ) |
|
1231 { |
|
1232 iconSize = aIcon->Bitmap()->SizeInPixels(); |
|
1233 } |
|
1234 |
|
1235 TInt bmpId = -1; |
|
1236 TInt maskId = -1; |
|
1237 TAknsItemID skinId = KAknsIIDNone; |
|
1238 |
|
1239 if ( &aIcon == &iIcon ) |
|
1240 { |
|
1241 bmpId = iExtension->iBmpId; |
|
1242 maskId = iExtension->iMaskId; |
|
1243 skinId = iExtension->iId; |
|
1244 } |
|
1245 else if ( &aIcon == &iPressedIcon ) |
|
1246 { |
|
1247 bmpId = iExtension->iPressedBmpId; |
|
1248 maskId = iExtension->iPressedMaskId; |
|
1249 skinId = iExtension->iPressedId; |
|
1250 } |
|
1251 else if ( &aIcon == &iDimmedIcon ) |
|
1252 { |
|
1253 bmpId = iExtension->iDimmedBmpId; |
|
1254 maskId = iExtension->iDimmedMaskId; |
|
1255 skinId = iExtension->iDimmedId; |
|
1256 } |
|
1257 else if ( &aIcon == &iHoverIcon ) |
|
1258 { |
|
1259 bmpId = iExtension->iHoverBmpId; |
|
1260 maskId = iExtension->iHoverMaskId; |
|
1261 skinId = iExtension->iHoverId; |
|
1262 } |
|
1263 |
|
1264 TPtrC16 bitmapFile; |
|
1265 |
|
1266 if ( iExtension->iFilePath ) |
|
1267 { |
|
1268 bitmapFile.Set( *iExtension->iFilePath ); |
|
1269 } |
|
1270 else |
|
1271 { |
|
1272 bitmapFile.Set( KAvkonBitmapFile ); |
|
1273 } |
|
1274 |
|
1275 // aIcon is set to NULL if the next call fails |
|
1276 TRAP_IGNORE( CreateButtonIconL( aIcon, bitmapFile, bmpId, maskId, skinId ) ); |
|
1277 |
|
1278 if ( aIcon && iconSize != TSize( 0, 0 ) ) |
|
1279 { |
|
1280 ResizeIcon( aIcon, iconSize, iExtension->iScaleMode ); |
|
1281 } |
|
1282 } |
|
1283 |
|
1284 // ----------------------------------------------------------------------------- |
|
1285 // CAknButtonState::ScaleIcons |
|
1286 // Sets the size for bitmap and mask |
|
1287 // ----------------------------------------------------------------------------- |
|
1288 // |
|
1289 TInt CAknButtonState::ScaleIcons( const TSize& aSize, TScaleMode aScaleMode ) |
|
1290 { |
|
1291 TInt retval = ResizeIcon( iIcon, aSize, aScaleMode ); |
|
1292 retval = Min( retval, ResizeIcon( iPressedIcon, aSize, aScaleMode ) ); |
|
1293 |
|
1294 // Generated dimmed state icon has to be regenerated |
|
1295 if ( iExtension->iGeneratedDimmedIcon ) |
|
1296 { |
|
1297 TRAP_IGNORE ( CreateAndSetDimmedIconL( iDimmedIcon, iIcon, aScaleMode ) ); |
|
1298 } |
|
1299 else |
|
1300 { |
|
1301 retval = Min( retval, ResizeIcon( iDimmedIcon, aSize, aScaleMode ) ); |
|
1302 } |
|
1303 |
|
1304 return retval; |
|
1305 } |
|
1306 |
|
1307 // ----------------------------------------------------------------------------- |
|
1308 // CAknButtonState::ScaleMode |
|
1309 // Getter for the current scalemode of the state |
|
1310 // ----------------------------------------------------------------------------- |
|
1311 TScaleMode CAknButtonState::ScaleMode() const |
|
1312 { |
|
1313 return iExtension->iScaleMode; |
|
1314 } |
|
1315 |
|
1316 // ----------------------------------------------------------------------------- |
|
1317 // CAknButtonState::SetGeneratedDimmedIcon |
|
1318 // Whether the dimmed icon of the state is created by owning Button |
|
1319 // ----------------------------------------------------------------------------- |
|
1320 void CAknButtonState::SetGeneratedDimmedIcon( TBool aDimmedIconCreatedByButton ) |
|
1321 { |
|
1322 iExtension->iGeneratedDimmedIcon = aDimmedIconCreatedByButton; |
|
1323 } |
|
1324 |
|
1325 // ----------------------------------------------------------------------------- |
|
1326 // CAknButtonState::Extension |
|
1327 // ----------------------------------------------------------------------------- |
|
1328 // |
|
1329 CAknButtonStateExtension* CAknButtonState::Extension() const |
|
1330 { |
|
1331 return iExtension; |
|
1332 } |
|
1333 |
|
1334 // ============================ MEMBER FUNCTIONS =============================== |
|
1335 |
|
1336 // ----------------------------------------------------------------------------- |
|
1337 // CAknButton::NewL |
|
1338 // Two-phased constructor. |
|
1339 // Constructs an empty button |
|
1340 // ----------------------------------------------------------------------------- |
|
1341 // |
|
1342 EXPORT_C CAknButton* CAknButton::NewL() |
|
1343 { |
|
1344 CAknButton* self = NewLC(); |
|
1345 CleanupStack::Pop( self ); |
|
1346 return self; |
|
1347 } |
|
1348 |
|
1349 // ----------------------------------------------------------------------------- |
|
1350 // CAknButton::NewLC |
|
1351 // Two-phased constructor. |
|
1352 // Constructs an empty button |
|
1353 // ----------------------------------------------------------------------------- |
|
1354 // |
|
1355 EXPORT_C CAknButton* CAknButton::NewLC() |
|
1356 { |
|
1357 CAknButton* self = new (ELeave) CAknButton( 0 ); |
|
1358 CleanupStack::PushL( self ); |
|
1359 self->ConstructL(); |
|
1360 AKNTASHOOK_ADDL( self, "CAknButton" ); |
|
1361 return self; |
|
1362 } |
|
1363 |
|
1364 // ----------------------------------------------------------------------------- |
|
1365 // CAknButton::NewL |
|
1366 // Two-phased constructor. |
|
1367 // Constructs the button from resources. |
|
1368 // ----------------------------------------------------------------------------- |
|
1369 // |
|
1370 EXPORT_C CAknButton* CAknButton::NewL( TResourceReader& aReader ) |
|
1371 { |
|
1372 CAknButton* self = NewLC( aReader ); |
|
1373 CleanupStack::Pop( self ); |
|
1374 return self; |
|
1375 } |
|
1376 |
|
1377 // ----------------------------------------------------------------------------- |
|
1378 // CAknButton::NewLC |
|
1379 // Two-phased constructor. |
|
1380 // Constructs the button from resources. |
|
1381 // ----------------------------------------------------------------------------- |
|
1382 // |
|
1383 EXPORT_C CAknButton* CAknButton::NewLC( TResourceReader& aReader ) |
|
1384 { |
|
1385 CAknButton* self = new( ELeave ) CAknButton( 0 ); |
|
1386 CleanupStack::PushL( self ); |
|
1387 self->ConstructL(); |
|
1388 self->ConstructFromResourceL( aReader ); |
|
1389 AKNTASHOOK_ADDL( self, "CAknButton" ); |
|
1390 return self; |
|
1391 } |
|
1392 |
|
1393 // ----------------------------------------------------------------------------- |
|
1394 // CAknButton::NewL |
|
1395 // Two-phased constructor. |
|
1396 // Constructs the button from resources. |
|
1397 // ----------------------------------------------------------------------------- |
|
1398 // |
|
1399 EXPORT_C CAknButton* CAknButton::NewL( const TInt aResourceId ) |
|
1400 { |
|
1401 CAknButton* self = NewLC( aResourceId ); |
|
1402 CleanupStack::Pop( self ); |
|
1403 return self; |
|
1404 } |
|
1405 |
|
1406 // ----------------------------------------------------------------------------- |
|
1407 // CAknButton::NewLC |
|
1408 // Two-phased constructor. |
|
1409 // Constructs the button from resources. |
|
1410 // ----------------------------------------------------------------------------- |
|
1411 // |
|
1412 EXPORT_C CAknButton* CAknButton::NewLC( const TInt aResourceId ) |
|
1413 { |
|
1414 CAknButton* self = new (ELeave) CAknButton( 0 ); |
|
1415 CleanupStack::PushL( self ); |
|
1416 self->ConstructL(); |
|
1417 self->ConstructFromResourceL( aResourceId ); |
|
1418 AKNTASHOOK_ADDL( self, "CAknButton" ); |
|
1419 return self; |
|
1420 } |
|
1421 |
|
1422 // ----------------------------------------------------------------------------- |
|
1423 // CAknButton::NewL |
|
1424 // Two-phased constructor. |
|
1425 // Constructs one state button. |
|
1426 // ----------------------------------------------------------------------------- |
|
1427 // |
|
1428 EXPORT_C CAknButton* CAknButton::NewL( CGulIcon* aIcon, |
|
1429 CGulIcon* aDimmedIcon, |
|
1430 CGulIcon* aPressedIcon, |
|
1431 CGulIcon* aHoverIcon, |
|
1432 const TDesC& aText, |
|
1433 const TDesC& aHelpText, |
|
1434 const TInt aButtonFlags, |
|
1435 const TInt aStateFlags ) |
|
1436 { |
|
1437 CAknButton* self = NewLC( aIcon, aDimmedIcon, aPressedIcon, aHoverIcon, |
|
1438 aText, aHelpText, aButtonFlags, aStateFlags ); |
|
1439 CleanupStack::Pop( self ); |
|
1440 return self; |
|
1441 } |
|
1442 |
|
1443 // ----------------------------------------------------------------------------- |
|
1444 // CAknButton::NewLC |
|
1445 // Two-phased constructor. |
|
1446 // Constructs one state button. |
|
1447 // ----------------------------------------------------------------------------- |
|
1448 // |
|
1449 EXPORT_C CAknButton* CAknButton::NewLC( CGulIcon* aIcon, |
|
1450 CGulIcon* aDimmedIcon, |
|
1451 CGulIcon* aPressedIcon, |
|
1452 CGulIcon* aHoverIcon, |
|
1453 const TDesC& aText, |
|
1454 const TDesC& aHelpText, |
|
1455 const TInt aButtonFlags, |
|
1456 const TInt aStateFlags ) |
|
1457 { |
|
1458 CAknButton* self = new (ELeave) CAknButton( aButtonFlags ); |
|
1459 CleanupStack::PushL( self ); |
|
1460 self->ConstructL( aIcon, aDimmedIcon, aPressedIcon, aHoverIcon, aText, |
|
1461 aHelpText, aStateFlags ); |
|
1462 AKNTASHOOK_ADDL( self, "CAknButton" ); |
|
1463 return self; |
|
1464 } |
|
1465 |
|
1466 // ----------------------------------------------------------------------------- |
|
1467 // CAknButton::NewL |
|
1468 // Two-phased constructor. |
|
1469 // Constructs one state button. |
|
1470 // ----------------------------------------------------------------------------- |
|
1471 // |
|
1472 EXPORT_C CAknButton* CAknButton::NewL( const TDesC& aFilePath, |
|
1473 const TInt aBmpId, |
|
1474 const TInt aMaskId, |
|
1475 const TInt aDimmedBmpId, |
|
1476 const TInt aDimmedMaskId, |
|
1477 const TInt aPressedBmpId, |
|
1478 const TInt aPressedMaskId, |
|
1479 const TInt aHoverBmpId, |
|
1480 const TInt aHoverMaskId, |
|
1481 const TDesC& aText, |
|
1482 const TDesC& aHelpText, |
|
1483 const TInt aButtonFlags, |
|
1484 const TInt aStateFlags, |
|
1485 const TAknsItemID& aId, |
|
1486 const TAknsItemID& aDimmedId, |
|
1487 const TAknsItemID& aPressedId, |
|
1488 const TAknsItemID& aHoverId ) |
|
1489 { |
|
1490 CAknButton* self = NewLC( aFilePath, aBmpId, aMaskId, aDimmedBmpId, |
|
1491 aDimmedMaskId, aPressedBmpId, aPressedMaskId, aHoverBmpId, aHoverMaskId, |
|
1492 aText, aHelpText, aButtonFlags, aStateFlags, aId, aDimmedId, aPressedId, |
|
1493 aHoverId ); |
|
1494 CleanupStack::Pop( self ); |
|
1495 return self; |
|
1496 } |
|
1497 |
|
1498 // ----------------------------------------------------------------------------- |
|
1499 // CAknButton::NewLC |
|
1500 // Two-phased constructor. |
|
1501 // Constructs one state button. |
|
1502 // ----------------------------------------------------------------------------- |
|
1503 // |
|
1504 EXPORT_C CAknButton* CAknButton::NewLC( const TDesC& aFilePath, |
|
1505 const TInt aBmpId, |
|
1506 const TInt aMaskId, |
|
1507 const TInt aDimmedBmpId, |
|
1508 const TInt aDimmedMaskId, |
|
1509 const TInt aPressedBmpId, |
|
1510 const TInt aPressedMaskId, |
|
1511 const TInt aHoverBmpId, |
|
1512 const TInt aHoverMaskId, |
|
1513 const TDesC& aText, |
|
1514 const TDesC& aHelpText, |
|
1515 const TInt aButtonFlags, |
|
1516 const TInt aStateFlags, |
|
1517 const TAknsItemID& aId, |
|
1518 const TAknsItemID& aDimmedId, |
|
1519 const TAknsItemID& aPressedId, |
|
1520 const TAknsItemID& aHoverId ) |
|
1521 { |
|
1522 CAknButton* self = new (ELeave) CAknButton( aButtonFlags ); |
|
1523 CleanupStack::PushL( self ); |
|
1524 self->ConstructL( aFilePath, aBmpId, aMaskId, aDimmedBmpId, aDimmedMaskId, |
|
1525 aPressedBmpId, aPressedMaskId, aHoverBmpId, aHoverMaskId, |
|
1526 aText, aHelpText, aStateFlags, aId, aDimmedId, aPressedId, aHoverId ); |
|
1527 AKNTASHOOK_ADDL( self, "CAknButton" ); |
|
1528 return self; |
|
1529 } |
|
1530 |
|
1531 // ----------------------------------------------------------------------------- |
|
1532 // CAknButton::CAknButton |
|
1533 // C++ constructor. |
|
1534 // ----------------------------------------------------------------------------- |
|
1535 // |
|
1536 EXPORT_C CAknButton::CAknButton( const TInt aFlags ) |
|
1537 : iFlags( aFlags ), |
|
1538 iVerticalAlignment( ECenter ), |
|
1539 iHorizontalAlignment( CGraphicsContext::ECenter ), |
|
1540 iTextColorTableId( KAknsIIDQsnTextColors ), // TODO |
|
1541 iTextColorIndex( EAknsCIQsnTextColorsCG80 ), // TODO |
|
1542 iScaleMode( EAspectRatioNotPreserved ), |
|
1543 iHelpNoteWaitInterval( KTimeoutBeforeHelpNote ), |
|
1544 iHelpNoteInViewInterval( KTimeoutInViewHelpNote ), |
|
1545 iKeyRepeatDelay( KKeyRepeatDelay ), |
|
1546 iKeyRepeatInterval( KKeyRepeatInterval ) |
|
1547 { |
|
1548 } |
|
1549 |
|
1550 // ----------------------------------------------------------------------------- |
|
1551 // CAknButton::ConstructL |
|
1552 // Symbian 2nd phase constructor. |
|
1553 // Constructor for the empty button. |
|
1554 // ----------------------------------------------------------------------------- |
|
1555 // |
|
1556 EXPORT_C void CAknButton::ConstructL() |
|
1557 { |
|
1558 TRgb textColor; |
|
1559 |
|
1560 if ( AknsUtils::GetCachedColor( AknsUtils::SkinInstance(), textColor, |
|
1561 iTextColorTableId, iTextColorIndex ) == KErrNone ) |
|
1562 { |
|
1563 OverrideColorL( EColorButtonText, textColor ); |
|
1564 } |
|
1565 |
|
1566 if ( !iStates ) |
|
1567 { |
|
1568 iStates = new ( ELeave ) CArrayPtrFlat<CAknButtonState>( 2 ); |
|
1569 } |
|
1570 |
|
1571 if ( !iBgContext ) |
|
1572 { |
|
1573 iBgContext = CAknsFrameBackgroundControlContext::NewL( |
|
1574 KAknsIIDNone, TRect(), TRect(), EFalse ); |
|
1575 } |
|
1576 |
|
1577 if ( !iExtension ) |
|
1578 { |
|
1579 iExtension = CAknButtonExtension::NewL( *this ); |
|
1580 } |
|
1581 |
|
1582 if ( iFlags & KAknButtonHitTest ) |
|
1583 { |
|
1584 SetHitTest( iExtension ); |
|
1585 } |
|
1586 |
|
1587 if ( iFlags & KAknButtonNoFrame ) |
|
1588 { |
|
1589 iExtension->iMargins.SetAllValuesTo( 0 ); |
|
1590 } |
|
1591 |
|
1592 if ( iFlags & KAknButtonTextLeft ) |
|
1593 { |
|
1594 iHorizontalAlignment = CGraphicsContext::ELeft; |
|
1595 } |
|
1596 iExtension->HandleFeedbackAreaChange(); |
|
1597 } |
|
1598 |
|
1599 // ----------------------------------------------------------------------------- |
|
1600 // CAknButton::ConstructL |
|
1601 // Symbian 2nd phase constructor for 1 state button. |
|
1602 // ----------------------------------------------------------------------------- |
|
1603 // |
|
1604 EXPORT_C void CAknButton::ConstructL( CGulIcon* aIcon, |
|
1605 CGulIcon* aDimmedIcon, |
|
1606 CGulIcon* aPressedIcon, |
|
1607 CGulIcon* aHoverIcon, |
|
1608 const TDesC& aText, |
|
1609 const TDesC& aHelpText, |
|
1610 const TInt aStateFlags ) |
|
1611 { |
|
1612 ConstructL(); |
|
1613 AddStateL( aIcon, aDimmedIcon, aPressedIcon, aHoverIcon, aText, aHelpText, |
|
1614 aStateFlags); |
|
1615 } |
|
1616 |
|
1617 // ----------------------------------------------------------------------------- |
|
1618 // CAknButton::ConstructL |
|
1619 // Symbian 2nd phase constructor for 1 state button |
|
1620 // ----------------------------------------------------------------------------- |
|
1621 // |
|
1622 EXPORT_C void CAknButton::ConstructL( const TDesC& aFilePath, |
|
1623 const TInt aBmpId, |
|
1624 const TInt aMaskId, |
|
1625 const TInt aDimmedBmpId, |
|
1626 const TInt aDimmedMaskId, |
|
1627 const TInt aPressedBmpId, |
|
1628 const TInt aPressedMaskId, |
|
1629 const TInt aHoverBmpId, |
|
1630 const TInt aHoverMaskId, |
|
1631 const TDesC& aText, |
|
1632 const TDesC& aHelpText, |
|
1633 const TInt aStateFlags, |
|
1634 const TAknsItemID& aId, |
|
1635 const TAknsItemID& aDimmedId, |
|
1636 const TAknsItemID& aPressedId, |
|
1637 const TAknsItemID& aHoverId ) |
|
1638 { |
|
1639 ConstructL(); |
|
1640 AddStateL( aFilePath, aBmpId, aMaskId, aDimmedBmpId, aDimmedMaskId, |
|
1641 aPressedBmpId, aPressedMaskId, aHoverBmpId, aHoverMaskId, |
|
1642 aText, aHelpText, aStateFlags, aId, aDimmedId, aPressedId, aHoverId ); |
|
1643 } |
|
1644 |
|
1645 // ----------------------------------------------------------------------------- |
|
1646 // Destructor |
|
1647 // ----------------------------------------------------------------------------- |
|
1648 // |
|
1649 EXPORT_C CAknButton::~CAknButton() |
|
1650 { |
|
1651 AKNTASHOOK_REMOVE(); |
|
1652 if ( iStates ) |
|
1653 { |
|
1654 iStates->ResetAndDestroy(); |
|
1655 delete iStates; |
|
1656 } |
|
1657 |
|
1658 // MTouchFeedback instance lives in AknAppUi. AppUi might be |
|
1659 // destroyed when this destructor is running. If there is no |
|
1660 // MTouchFeedback instance there is no need to remove any areas |
|
1661 // either, as these are ( naturally ) destroyed with |
|
1662 // MTouchFeedback instance. |
|
1663 MTouchFeedback* fb = MTouchFeedback::Instance(); |
|
1664 if ( fb ) |
|
1665 { |
|
1666 fb->RemoveFeedbackForControl( this ); |
|
1667 } |
|
1668 |
|
1669 delete iBgContext; |
|
1670 delete iDimmedHelpText; |
|
1671 delete iHelpNote; |
|
1672 delete iKeyRepeatTimer; |
|
1673 delete iExtension; |
|
1674 iFont = NULL; |
|
1675 } |
|
1676 |
|
1677 // ----------------------------------------------------------------------------- |
|
1678 // CAknButton::ActivateL |
|
1679 // Sets control as ready to be drawn. |
|
1680 // ----------------------------------------------------------------------------- |
|
1681 // |
|
1682 EXPORT_C void CAknButton::ActivateL() |
|
1683 { |
|
1684 // request for drag events outside the button |
|
1685 SetAllowStrayPointers(); |
|
1686 // Requesting pointer drag events |
|
1687 EnableDragEvents(); |
|
1688 |
|
1689 CAknControl::ActivateL(); |
|
1690 } |
|
1691 |
|
1692 // ----------------------------------------------------------------------------- |
|
1693 // CAknButton::ConstructFromResourceL |
|
1694 // Constructs controls from a resource file. |
|
1695 // ----------------------------------------------------------------------------- |
|
1696 // |
|
1697 EXPORT_C void CAknButton::ConstructFromResourceL( TResourceReader& aReader ) |
|
1698 { |
|
1699 if ( !iExtension ) |
|
1700 { |
|
1701 iExtension = CAknButtonExtension::NewL( *this ); |
|
1702 } |
|
1703 |
|
1704 // flags |
|
1705 iFlags = aReader.ReadInt16(); |
|
1706 |
|
1707 // state index |
|
1708 SetStateIndexL( aReader.ReadInt16() ); |
|
1709 |
|
1710 // read states |
|
1711 const TInt stateCount = aReader.ReadInt16(); |
|
1712 for ( TInt ii = 0; ii < stateCount; ii++ ) |
|
1713 { |
|
1714 CAknButtonState* state = new (ELeave) CAknButtonState( 0 ); |
|
1715 CleanupStack::PushL( state ); |
|
1716 state->ConstructFromResourceL( aReader ); |
|
1717 iStates->AppendL( state ); |
|
1718 CleanupStack::Pop( state ); |
|
1719 } |
|
1720 |
|
1721 aReader.ReadInt32(); // extension link, not used currently |
|
1722 |
|
1723 if ( iFlags & KAknButtonHitTest ) |
|
1724 { |
|
1725 SetHitTest( iExtension ); |
|
1726 } |
|
1727 |
|
1728 if ( iFlags & KAknButtonNoFrame ) |
|
1729 { |
|
1730 iExtension->iMargins.SetAllValuesTo( 0 ); |
|
1731 } |
|
1732 |
|
1733 if ( iFlags & KAknButtonTextLeft ) |
|
1734 { |
|
1735 iHorizontalAlignment = CGraphicsContext::ELeft; |
|
1736 } |
|
1737 iExtension->HandleFeedbackAreaChange(); |
|
1738 } |
|
1739 |
|
1740 // ----------------------------------------------------------------------------- |
|
1741 // CAknButton::HandleResourceChange |
|
1742 // Handles a change to the control's resources. |
|
1743 // ----------------------------------------------------------------------------- |
|
1744 // |
|
1745 EXPORT_C void CAknButton::HandleResourceChange( TInt aType ) |
|
1746 { |
|
1747 // No need to call base class implementation since CountComponentControls |
|
1748 // is always zero. |
|
1749 |
|
1750 if ( aType == KAknsMessageSkinChange || aType == KEikDynamicLayoutVariantSwitch ) |
|
1751 { |
|
1752 if ( iButtonPressed ) |
|
1753 { |
|
1754 ResetState(); |
|
1755 DrawDeferred(); |
|
1756 } |
|
1757 } |
|
1758 |
|
1759 // UIFW informs control about lost focus when moved to background. |
|
1760 // Rest of pointer events are no longer forvarded to control. |
|
1761 if ( aType == KAknMessageFocusLost || aType == KEikMessageFadeAllWindows ) |
|
1762 { |
|
1763 if (iHelpNote) |
|
1764 { |
|
1765 iHelpNote->HideInfoPopupNote(); |
|
1766 } |
|
1767 |
|
1768 if (iButtonPressed) |
|
1769 { |
|
1770 ResetState(); |
|
1771 DrawDeferred(); |
|
1772 } |
|
1773 return; |
|
1774 } |
|
1775 |
|
1776 if ( iStates ) |
|
1777 { |
|
1778 for ( TInt i = 0; i < iStates->Count(); ++i ) |
|
1779 { |
|
1780 CAknButtonState* state = iStates->At( i ); |
|
1781 |
|
1782 if ( state ) |
|
1783 { |
|
1784 state->HandleResourceChange( aType ); |
|
1785 } |
|
1786 } |
|
1787 } |
|
1788 |
|
1789 if ( aType == KAknsMessageSkinChange ) |
|
1790 { |
|
1791 TRgb textColor; |
|
1792 |
|
1793 if ( AknsUtils::GetCachedColor( AknsUtils::SkinInstance(), textColor, |
|
1794 iTextColorTableId, iTextColorIndex ) == KErrNone ) |
|
1795 { |
|
1796 TRAP_IGNORE( OverrideColorL( EColorButtonText, textColor ) ); |
|
1797 } |
|
1798 |
|
1799 // generated pressed frame has to be regenerated |
|
1800 if ( iFlags & KAknButtonNoFrame && iFlags & KAknButtonPressedDownFrame ) |
|
1801 { |
|
1802 iExtension->DeletePressedBmps(); |
|
1803 TRAP_IGNORE( CreatePressedDownFrameL() ); |
|
1804 } |
|
1805 } |
|
1806 } |
|
1807 |
|
1808 // ----------------------------------------------------------------------------- |
|
1809 // CAknButton::MinimumSize |
|
1810 // Returns the control's minimum required size. This doesn't include highlight |
|
1811 // area. |
|
1812 // ----------------------------------------------------------------------------- |
|
1813 // |
|
1814 EXPORT_C TSize CAknButton::MinimumSize() |
|
1815 { |
|
1816 // by default, margins decide the absolute minimum size... |
|
1817 TInt width = iExtension->iMargins.iLeft + iExtension->iMargins.iRight; |
|
1818 TInt height = iExtension->iMargins.iTop + iExtension->iMargins.iBottom; |
|
1819 |
|
1820 // ...but possible frames may enlarge the required area... |
|
1821 if ( !( iFlags & KAknButtonNoFrame ) ) |
|
1822 { |
|
1823 TAknLayoutRect tl; |
|
1824 tl.LayoutRect( Rect(), |
|
1825 AknLayoutScalable_Avkon::toolbar_button_pane_g2().LayoutLine() ); |
|
1826 |
|
1827 TAknLayoutRect br; |
|
1828 br.LayoutRect( Rect(), |
|
1829 AknLayoutScalable_Avkon::toolbar_button_pane_g5().LayoutLine() ); |
|
1830 |
|
1831 TInt frameWidth = tl.Rect().Width() + br.Rect().Width(); |
|
1832 TInt frameHeight = tl.Rect().Height() + br.Rect().Height(); |
|
1833 |
|
1834 if ( !( iFlags & KAknButtonTextInsideFrame ) ) |
|
1835 { |
|
1836 width = Max( width, frameWidth ); |
|
1837 height = Max( height, frameHeight ); |
|
1838 } |
|
1839 else |
|
1840 { |
|
1841 width = frameWidth; |
|
1842 height = frameHeight; |
|
1843 } |
|
1844 } |
|
1845 |
|
1846 // ...as well as evil flags |
|
1847 if ( iStates && ( iFlags & KAknButtonSizeFitText ) ) |
|
1848 { |
|
1849 if ( !iFont ) |
|
1850 { |
|
1851 iFont = iCoeEnv->NormalFont(); |
|
1852 } |
|
1853 |
|
1854 height += iFont->FontMaxHeight(); |
|
1855 |
|
1856 TInt textWidth = 0; |
|
1857 |
|
1858 // choose the longest one |
|
1859 for ( TInt ii = 0; ii < iStates->Count(); ii++ ) |
|
1860 { |
|
1861 CAknButtonState* state = iStates->At( ii ); |
|
1862 if ( state && state->HasText() ) |
|
1863 { |
|
1864 TInt tempWidth = iFont->TextWidthInPixels( state->Text() ); |
|
1865 textWidth = Max( textWidth, tempWidth ); |
|
1866 } |
|
1867 } |
|
1868 |
|
1869 width += textWidth; |
|
1870 } |
|
1871 |
|
1872 return TSize( width, height ); |
|
1873 } |
|
1874 |
|
1875 // ----------------------------------------------------------------------------- |
|
1876 // CAknButton::SetDimmed |
|
1877 // Sets button dimmed. Doesn't redraw. |
|
1878 // Button needs to get pointer events even if it is dimmed to be able to show |
|
1879 // help text in dimmed state. So, the CCoeControl::SetDimmed(TBool) cannot be |
|
1880 // used to set button dimmed if the help text is used. |
|
1881 // ----------------------------------------------------------------------------- |
|
1882 // |
|
1883 EXPORT_C void CAknButton::SetDimmed( TBool aDimmed ) |
|
1884 { |
|
1885 if ( aDimmed ) |
|
1886 { |
|
1887 StopKeyRepeatTimer(); |
|
1888 StopLongPressTimer(); |
|
1889 HideHelp(); |
|
1890 iButtonPressed = EFalse; |
|
1891 } |
|
1892 |
|
1893 if ( aDimmed ) |
|
1894 { |
|
1895 iExtension->iFlags.Set( CAknButtonExtension::EDimmed ); |
|
1896 } |
|
1897 else |
|
1898 { |
|
1899 iExtension->iFlags.Clear( CAknButtonExtension::EDimmed ); |
|
1900 } |
|
1901 if ( iExtension->iFeedback ) |
|
1902 { |
|
1903 if ( aDimmed ) |
|
1904 { |
|
1905 iExtension->iFeedback->MoveFeedbackAreaToFirstPriority( this, 0 ); |
|
1906 } |
|
1907 iExtension->iFeedback->EnableFeedbackForControl( this, !aDimmed && IsVisible() ); |
|
1908 } |
|
1909 |
|
1910 TBool hasHelp ( EFalse ); |
|
1911 |
|
1912 for ( TInt i = 0; i < iStates->Count(); ++i ) |
|
1913 { |
|
1914 CAknButtonState* state = iStates->At( i ); |
|
1915 |
|
1916 if ( state ) |
|
1917 { |
|
1918 if ( !state->iDimmedIcon ) |
|
1919 { |
|
1920 TRAP_IGNORE ( CreateAndSetDimmedIconL( state->iDimmedIcon, |
|
1921 state->iIcon, state->ScaleMode() ) ); |
|
1922 state->SetGeneratedDimmedIcon( ETrue ); |
|
1923 } |
|
1924 |
|
1925 if ( state->HasHelp() ) |
|
1926 { |
|
1927 hasHelp = ETrue; |
|
1928 } |
|
1929 } |
|
1930 } |
|
1931 // None of states has help text, CCoeControl::SetDimmed can be used |
|
1932 if ( !hasHelp ) |
|
1933 { |
|
1934 CCoeControl::SetDimmed( aDimmed ); |
|
1935 } |
|
1936 } |
|
1937 |
|
1938 // ----------------------------------------------------------------------------- |
|
1939 // CAknButton::OfferKeyEventL |
|
1940 // Handles key events. |
|
1941 // ----------------------------------------------------------------------------- |
|
1942 // |
|
1943 EXPORT_C TKeyResponse CAknButton::OfferKeyEventL( const TKeyEvent& aKeyEvent, |
|
1944 TEventCode aType ) |
|
1945 { |
|
1946 if ( IsDimmed() ) |
|
1947 return EKeyWasNotConsumed; |
|
1948 |
|
1949 if ( aType == EEventKeyDown && IsVisible() ) |
|
1950 { |
|
1951 HideHelp(); // hides help text as soon as the first key event comes. |
|
1952 } |
|
1953 |
|
1954 if ( aKeyEvent.iScanCode == EStdKeyDevice3 || |
|
1955 aKeyEvent.iScanCode == EStdKeyEnter ) |
|
1956 { |
|
1957 if ( aType == EEventKeyDown ) |
|
1958 { |
|
1959 iKeyDownReported = ETrue; |
|
1960 |
|
1961 if ( !iButtonPressed ) |
|
1962 { |
|
1963 // show press changes |
|
1964 iButtonPressed = ETrue; |
|
1965 if ( NeedsRedrawWhenPressed() ) |
|
1966 { |
|
1967 DrawNow(); |
|
1968 } |
|
1969 } |
|
1970 |
|
1971 if ( iFlags & KAknButtonReportOnKeyDown ) |
|
1972 { |
|
1973 ChangeState( ETrue ); |
|
1974 if ( Observer() ) |
|
1975 { |
|
1976 Observer()->HandleControlEventL( this, |
|
1977 MCoeControlObserver::EEventStateChanged ); |
|
1978 } |
|
1979 } |
|
1980 |
|
1981 if ( iFlags & KAknButtonKeyRepeat ) |
|
1982 { |
|
1983 iExtension->iFlags.Clear( CAknButtonExtension::EKeyRepeatEventReported ); |
|
1984 StartKeyRepeatTimerL(); |
|
1985 } |
|
1986 |
|
1987 if ( iFlags & KAknButtonReportOnLongPress ) |
|
1988 { |
|
1989 iExtension->iFlags.Clear( CAknButtonExtension::ELongPressReported ); |
|
1990 iExtension->StartLongPressTimerL(); |
|
1991 } |
|
1992 } |
|
1993 |
|
1994 else if ( aType == EEventKeyUp ) |
|
1995 { |
|
1996 if ( iButtonPressed ) |
|
1997 { |
|
1998 iButtonPressed = EFalse; |
|
1999 |
|
2000 if ( NeedsRedrawWhenPressed() ) |
|
2001 { |
|
2002 DrawNow(); |
|
2003 } |
|
2004 } |
|
2005 |
|
2006 StopKeyRepeatTimer(); |
|
2007 StopLongPressTimer(); |
|
2008 |
|
2009 // The state is not changed, if it is already changed on key |
|
2010 // down event, or if a long press or a key repeat event is |
|
2011 // already reported to the observer. |
|
2012 if ( !( iFlags & KAknButtonReportOnKeyDown ) && |
|
2013 !( iExtension->iFlags.IsSet( CAknButtonExtension::ELongPressReported ) ) && |
|
2014 !( iExtension->iFlags.IsSet( CAknButtonExtension::EKeyRepeatEventReported ) ) && |
|
2015 iKeyDownReported ) |
|
2016 { |
|
2017 ChangeState( ETrue ); |
|
2018 if ( Observer() ) |
|
2019 { |
|
2020 Observer()->HandleControlEventL( this, |
|
2021 MCoeControlObserver::EEventStateChanged ); |
|
2022 } |
|
2023 } |
|
2024 else |
|
2025 { |
|
2026 if ( iExtension->iFlags.IsSet( CAknButtonExtension::ELongPressReported ) && iKeyDownReported ) |
|
2027 { |
|
2028 Observer()->HandleControlEventL( this, |
|
2029 static_cast<MCoeControlObserver::TCoeEvent>( |
|
2030 CAknButton::ELongPressEndedEvent ) ); |
|
2031 } |
|
2032 iExtension->iFlags.Clear( CAknButtonExtension::ELongPressReported ); |
|
2033 iExtension->iFlags.Clear( CAknButtonExtension::EKeyRepeatEventReported ); |
|
2034 } |
|
2035 |
|
2036 if ( iKeyDownReported && RequestExit() && Observer() ) |
|
2037 { |
|
2038 Observer()->HandleControlEventL( this, |
|
2039 MCoeControlObserver::EEventRequestExit ); |
|
2040 } |
|
2041 |
|
2042 iKeyDownReported = EFalse; |
|
2043 } |
|
2044 // we don't want aKeyEvent to go somewhere else :) |
|
2045 return EKeyWasConsumed; |
|
2046 } |
|
2047 |
|
2048 return EKeyWasNotConsumed; |
|
2049 } |
|
2050 |
|
2051 // ----------------------------------------------------------------------------- |
|
2052 // CAknButton::MakeVisible |
|
2053 // Sets this control as visible or invisible. |
|
2054 // ----------------------------------------------------------------------------- |
|
2055 // |
|
2056 EXPORT_C void CAknButton::MakeVisible( TBool aVisible ) |
|
2057 { |
|
2058 if ( aVisible != IsVisible() ) |
|
2059 { |
|
2060 CAknControl::MakeVisible( aVisible ); |
|
2061 if ( iExtension->iFeedback ) |
|
2062 { |
|
2063 if ( aVisible ) |
|
2064 { |
|
2065 iExtension->iFeedback->MoveFeedbackAreaToFirstPriority( this, |
|
2066 0 ); |
|
2067 } |
|
2068 iExtension->iFeedback->EnableFeedbackForControl( |
|
2069 this, |
|
2070 aVisible && !IsDimmed() ); |
|
2071 } |
|
2072 |
|
2073 CAknButtonState* state = State(); |
|
2074 if ( !aVisible && state && state->HasHelp() ) |
|
2075 { |
|
2076 HideHelp(); |
|
2077 } |
|
2078 } |
|
2079 } |
|
2080 |
|
2081 // ----------------------------------------------------------------------------- |
|
2082 // CAknButton::PrepareForFocusLossL |
|
2083 // This function is called by the dialog framework immediately before it removes |
|
2084 // keyboard focus from a control within a dialog. |
|
2085 // Currently has empty implementation. |
|
2086 // ----------------------------------------------------------------------------- |
|
2087 // |
|
2088 EXPORT_C void CAknButton::PrepareForFocusLossL() |
|
2089 { |
|
2090 CAknControl::PrepareForFocusLossL(); // empty but it can be changed... :) |
|
2091 } |
|
2092 |
|
2093 // ----------------------------------------------------------------------------- |
|
2094 // CAknButton::PrepareForFocusGainL |
|
2095 // Prepares the control for gaining focus. |
|
2096 // Must be used before calling SetFocus() function in case when help note |
|
2097 // should be shown. |
|
2098 // ----------------------------------------------------------------------------- |
|
2099 // |
|
2100 EXPORT_C void CAknButton::PrepareForFocusGainL() |
|
2101 { |
|
2102 CAknControl::PrepareForFocusGainL(); // empty but it can be changed... :) |
|
2103 |
|
2104 CAknButtonState* state = State(); |
|
2105 if ( state && state->HasHelp() && IsVisible() && !IsFocused() ) |
|
2106 { |
|
2107 iShowHelp = ETrue; |
|
2108 } |
|
2109 else |
|
2110 { |
|
2111 iShowHelp = EFalse; |
|
2112 } |
|
2113 } |
|
2114 |
|
2115 // ----------------------------------------------------------------------------- |
|
2116 // CAknButton::SizeChanged |
|
2117 // Responds to size changes to sets the size and position of the contents of |
|
2118 // this control. |
|
2119 // ----------------------------------------------------------------------------- |
|
2120 // |
|
2121 EXPORT_C void CAknButton::SizeChanged() |
|
2122 { |
|
2123 // If default icon size from LAF is used re-request that, otherwise trust |
|
2124 // that size will be updated by the utilising application. |
|
2125 if ( iExtension->iFlags.IsSet( CAknButtonExtension::EUseDefaultIconSize ) ) |
|
2126 { |
|
2127 if ( iFlags & KAknButtonNoFrame && !State()->HasText() ) |
|
2128 { |
|
2129 iExtension->iIconSize = Size(); |
|
2130 } |
|
2131 else |
|
2132 { |
|
2133 TAknLayoutRect layoutRect; |
|
2134 layoutRect.LayoutRect( Rect(), |
|
2135 AknLayoutScalable_Avkon::toolbar_button_pane_g10().LayoutLine() ); |
|
2136 iExtension->iIconSize = layoutRect.Rect().Size(); |
|
2137 } |
|
2138 } |
|
2139 |
|
2140 // Update margins from LAF if default values are used. This also refreshes |
|
2141 // icon size in case it overlaps margins. |
|
2142 CalculateDefaultMargins(); |
|
2143 |
|
2144 // scale all icons |
|
2145 ScaleIcons(); |
|
2146 |
|
2147 // Pressed down frame has to be regenerated |
|
2148 if ( iFlags & KAknButtonNoFrame && iFlags & KAknButtonPressedDownFrame ) |
|
2149 { |
|
2150 TRAP_IGNORE( CreatePressedDownFrameL() ); |
|
2151 } |
|
2152 |
|
2153 iExtension->HandleFeedbackAreaChange(); |
|
2154 } |
|
2155 |
|
2156 // ----------------------------------------------------------------------------- |
|
2157 // CAknButton::HandlePointerEventL |
|
2158 // Handles pointer events. |
|
2159 // @param aPointerEvent is the pointer event. |
|
2160 // ----------------------------------------------------------------------------- |
|
2161 // |
|
2162 EXPORT_C void CAknButton::HandlePointerEventL( const TPointerEvent& aPointerEvent ) |
|
2163 { |
|
2164 if ( AknLayoutUtils::PenEnabled() ) |
|
2165 { |
|
2166 if ( !IsVisible() ) |
|
2167 { |
|
2168 if ( iButtonPressed ) |
|
2169 { |
|
2170 ResetState(); |
|
2171 } |
|
2172 return; |
|
2173 } |
|
2174 TBool buttonEvent( TouchArea().Contains( aPointerEvent.iPosition ) ); |
|
2175 CAknButtonState* state = State(); |
|
2176 if ( !state ) |
|
2177 { |
|
2178 return; |
|
2179 } |
|
2180 |
|
2181 if ( ( iFlags & KAknButtonHitTest ) && |
|
2182 !HitAreaContainsL( aPointerEvent.iPosition, EFalse ) ) |
|
2183 { |
|
2184 buttonEvent = EFalse; |
|
2185 } |
|
2186 |
|
2187 TBool redrawNeeded(EFalse); |
|
2188 switch ( aPointerEvent.iType ) |
|
2189 { |
|
2190 case TPointerEvent::EButton1Down: |
|
2191 { |
|
2192 if ( buttonEvent && IsDimmed() ) |
|
2193 { |
|
2194 ShowHelpL(); |
|
2195 } |
|
2196 else if ( buttonEvent ) |
|
2197 { |
|
2198 if ( !iButtonPressed ) |
|
2199 { |
|
2200 iButtonPressed = ETrue; |
|
2201 // feedback/basic on down event, if hit test is |
|
2202 // used. Area registry is used for rectangular |
|
2203 // buttons |
|
2204 if ( ( iFlags & KAknButtonHitTest ) |
|
2205 && !IsDimmed() |
|
2206 && iExtension->iFeedback ) |
|
2207 { |
|
2208 iExtension->iFeedback->InstantFeedback( |
|
2209 this, |
|
2210 ETouchFeedbackBasicButton, |
|
2211 aPointerEvent ); |
|
2212 } |
|
2213 |
|
2214 // make a mark so that we can later test that the button press comes from pointer event |
|
2215 iButtonPressed |= KPointerFlag; |
|
2216 |
|
2217 // Redraw button, if needed |
|
2218 if ( NeedsRedrawWhenPressed() ) |
|
2219 { |
|
2220 redrawNeeded = ETrue; |
|
2221 } |
|
2222 |
|
2223 ShowHelpL(); |
|
2224 } |
|
2225 |
|
2226 if ( iFlags & KAknButtonReportOnKeyDown ) |
|
2227 { |
|
2228 // State is changed on button down event |
|
2229 ChangeState( EFalse ); |
|
2230 redrawNeeded = EFalse; |
|
2231 DrawNow(); //Redraw before noticing the observer for observer might open dialog |
|
2232 if ( Observer() ) |
|
2233 { |
|
2234 Observer()->HandleControlEventL( this, |
|
2235 MCoeControlObserver::EEventStateChanged ); |
|
2236 } |
|
2237 } |
|
2238 |
|
2239 if ( iFlags & KAknButtonKeyRepeat ) |
|
2240 { |
|
2241 // Key repeat |
|
2242 iExtension->iFlags.Clear( CAknButtonExtension::EKeyRepeatEventReported ); |
|
2243 StartKeyRepeatTimerL(); |
|
2244 } |
|
2245 |
|
2246 if ( iFlags & KAknButtonReportOnLongPress ) |
|
2247 { |
|
2248 iExtension->iFlags.Clear( CAknButtonExtension::ELongPressReported ); |
|
2249 iExtension->StartLongPressTimerL(); |
|
2250 } |
|
2251 } |
|
2252 break; |
|
2253 } |
|
2254 |
|
2255 case TPointerEvent::EDrag: |
|
2256 { |
|
2257 iNumberOfDragEvents++; |
|
2258 if ( iNumberOfDragEvents >= KDragEventSensitivity ) |
|
2259 { |
|
2260 iNumberOfDragEvents = 0; |
|
2261 |
|
2262 // Pointer is dragged out of the button area |
|
2263 if ( !buttonEvent && iButtonPressed ) |
|
2264 { |
|
2265 // Redraw button, if needed |
|
2266 if ( NeedsRedrawWhenPressed() ) |
|
2267 { |
|
2268 iButtonPressed = EFalse; |
|
2269 redrawNeeded = ETrue; |
|
2270 } |
|
2271 iButtonPressed = EFalse; |
|
2272 |
|
2273 StopKeyRepeatTimer(); |
|
2274 StopLongPressTimer(); |
|
2275 |
|
2276 if ( !IsFocused() ) |
|
2277 { |
|
2278 HideHelp(); |
|
2279 } |
|
2280 if ( iExtension->iFlags.IsSet( CAknButtonExtension::ELongPressReported ) && Observer() ) |
|
2281 { |
|
2282 Observer()->HandleControlEventL( this, |
|
2283 static_cast<MCoeControlObserver::TCoeEvent>( |
|
2284 CAknButton::ELongPressEndedEvent ) ); |
|
2285 } |
|
2286 iExtension->iFlags.Clear( CAknButtonExtension::ELongPressReported ); |
|
2287 } |
|
2288 |
|
2289 // Pointer is dragged back into button area |
|
2290 else if ( buttonEvent && !iButtonPressed && !IsDimmed() ) |
|
2291 { |
|
2292 iButtonPressed = ETrue; |
|
2293 |
|
2294 // Redraw button, if needed |
|
2295 if ( NeedsRedrawWhenPressed() ) |
|
2296 { |
|
2297 redrawNeeded = ETrue; |
|
2298 } |
|
2299 |
|
2300 if ( iFlags & KAknButtonKeyRepeat ) |
|
2301 { |
|
2302 // Continue key repeat |
|
2303 StartKeyRepeatTimerL(); |
|
2304 } |
|
2305 |
|
2306 if ( ( iFlags & KAknButtonReportOnLongPress ) && |
|
2307 !( iExtension->iFlags.IsSet( CAknButtonExtension::ELongPressReported ) ) ) |
|
2308 { |
|
2309 // Restart long press timer |
|
2310 StartLongPressTimerL(); |
|
2311 } |
|
2312 } |
|
2313 } |
|
2314 break; |
|
2315 } |
|
2316 |
|
2317 case TPointerEvent::EButton1Up: |
|
2318 { |
|
2319 iNumberOfDragEvents = 0; |
|
2320 HideHelp(); |
|
2321 |
|
2322 StopKeyRepeatTimer(); |
|
2323 StopLongPressTimer(); |
|
2324 |
|
2325 if ( iButtonPressed ) |
|
2326 { |
|
2327 // Redraw button, if needed |
|
2328 if ( NeedsRedrawWhenPressed() ) |
|
2329 { |
|
2330 iButtonPressed = EFalse; |
|
2331 if ( ! ( buttonEvent && iStates->Count() > 1 ) ) |
|
2332 { |
|
2333 redrawNeeded = ETrue; |
|
2334 } |
|
2335 } |
|
2336 iButtonPressed = EFalse; |
|
2337 } |
|
2338 |
|
2339 TBool hasDrawn( EFalse ); |
|
2340 if ( buttonEvent && !IsDimmed() ) |
|
2341 { |
|
2342 // feedback/BasicButton on up event, if hit test is |
|
2343 // used. Area registry is used for rectangular |
|
2344 // buttons |
|
2345 if ( ( iFlags & KAknButtonHitTest ) |
|
2346 && iExtension->iFeedback ) |
|
2347 { |
|
2348 iExtension->iFeedback->InstantFeedback( |
|
2349 this, |
|
2350 ETouchFeedbackBasicButton, |
|
2351 ETouchFeedbackVibra, |
|
2352 aPointerEvent ); |
|
2353 } |
|
2354 // The state is not changed, if it is already changed on key |
|
2355 // down event, or if a long press or a key repeat event is |
|
2356 // already reported to the observer. |
|
2357 if ( !( iFlags & KAknButtonReportOnKeyDown ) && |
|
2358 !( iExtension->iFlags.IsSet( CAknButtonExtension::ELongPressReported ) ) && |
|
2359 !( iExtension->iFlags.IsSet( CAknButtonExtension::EKeyRepeatEventReported ) ) ) |
|
2360 { |
|
2361 ChangeState( EFalse ); |
|
2362 if ( !hasDrawn ) |
|
2363 { |
|
2364 DrawNow(); |
|
2365 hasDrawn = ETrue; |
|
2366 } |
|
2367 |
|
2368 if ( Observer() ) |
|
2369 { |
|
2370 Observer()->HandleControlEventL( this, |
|
2371 MCoeControlObserver::EEventStateChanged ); |
|
2372 } |
|
2373 } |
|
2374 else |
|
2375 { |
|
2376 if ( iExtension->iFlags.IsSet( CAknButtonExtension::ELongPressReported ) && Observer() ) |
|
2377 { |
|
2378 if ( redrawNeeded && !hasDrawn ) |
|
2379 { |
|
2380 DrawNow(); |
|
2381 hasDrawn = ETrue; |
|
2382 } |
|
2383 Observer()->HandleControlEventL( this, |
|
2384 static_cast<MCoeControlObserver::TCoeEvent>( |
|
2385 CAknButton::ELongPressEndedEvent ) ); |
|
2386 } |
|
2387 iExtension->iFlags.Clear( CAknButtonExtension::ELongPressReported ); |
|
2388 iExtension->iFlags.Clear( CAknButtonExtension::EKeyRepeatEventReported ); |
|
2389 } |
|
2390 |
|
2391 if ( RequestExit() && Observer() ) |
|
2392 { |
|
2393 if ( redrawNeeded && !hasDrawn ) |
|
2394 { |
|
2395 DrawNow(); |
|
2396 hasDrawn = ETrue; |
|
2397 } |
|
2398 Observer()->HandleControlEventL( this, |
|
2399 MCoeControlObserver::EEventRequestExit ); |
|
2400 } |
|
2401 } |
|
2402 |
|
2403 if ( !buttonEvent && !IsDimmed() && Observer() ) |
|
2404 { |
|
2405 if ( redrawNeeded && !hasDrawn ) |
|
2406 { |
|
2407 DrawNow(); |
|
2408 hasDrawn = ETrue; |
|
2409 } |
|
2410 Observer()->HandleControlEventL( this, |
|
2411 MCoeControlObserver::EEventRequestCancel ); |
|
2412 |
|
2413 if ( iExtension->iFlags.IsSet( CAknButtonExtension::ELongPressReported ) ) |
|
2414 { |
|
2415 Observer()->HandleControlEventL( this, |
|
2416 static_cast<MCoeControlObserver::TCoeEvent>( |
|
2417 CAknButton::ELongPressEndedEvent ) ); |
|
2418 iExtension->iFlags.Clear( CAknButtonExtension::ELongPressReported ); |
|
2419 iExtension->iFlags.Clear( CAknButtonExtension::EKeyRepeatEventReported ); |
|
2420 } |
|
2421 } |
|
2422 if ( hasDrawn ) |
|
2423 { |
|
2424 redrawNeeded = EFalse; |
|
2425 } |
|
2426 break; |
|
2427 } |
|
2428 |
|
2429 default: |
|
2430 break; |
|
2431 } |
|
2432 if (redrawNeeded) |
|
2433 { |
|
2434 DrawNow(); |
|
2435 } |
|
2436 } |
|
2437 } |
|
2438 |
|
2439 // ----------------------------------------------------------------------------- |
|
2440 // CAknButton::PositionChanged |
|
2441 // |
|
2442 // ----------------------------------------------------------------------------- |
|
2443 // |
|
2444 EXPORT_C void CAknButton::PositionChanged() |
|
2445 { |
|
2446 if ( iExtension ) iExtension->HandleFeedbackAreaChange(); |
|
2447 CAknControl::PositionChanged(); |
|
2448 } |
|
2449 |
|
2450 // ----------------------------------------------------------------------------- |
|
2451 // CAknButton::FocusChanged |
|
2452 // This function is called whenever a control gains or loses focus. |
|
2453 // ----------------------------------------------------------------------------- |
|
2454 // |
|
2455 EXPORT_C void CAknButton::FocusChanged( TDrawNow aDrawNow ) |
|
2456 { |
|
2457 if ( !IsFocused() && iButtonPressed ) |
|
2458 { |
|
2459 iButtonPressed = EFalse; |
|
2460 iKeyDownReported = EFalse; |
|
2461 } |
|
2462 if ( IsVisible() ) |
|
2463 { |
|
2464 |
|
2465 if ( IsFocused() && iShowHelp ) |
|
2466 { |
|
2467 TRAP_IGNORE( ShowHelpL() ); |
|
2468 } |
|
2469 else |
|
2470 { |
|
2471 HideHelp(); |
|
2472 |
|
2473 // Stop the timers if active |
|
2474 StopLongPressTimer(); |
|
2475 StopKeyRepeatTimer(); |
|
2476 } |
|
2477 if ( !IsBackedUp() && aDrawNow ) |
|
2478 { |
|
2479 DrawNow(); |
|
2480 } |
|
2481 } |
|
2482 |
|
2483 iShowHelp = EFalse; |
|
2484 } |
|
2485 |
|
2486 // ----------------------------------------------------------------------------- |
|
2487 // CAknButton::ExtensionInterface |
|
2488 // For future extensions |
|
2489 // ----------------------------------------------------------------------------- |
|
2490 // |
|
2491 EXPORT_C void* CAknButton::ExtensionInterface( TUid /*aInterface*/ ) |
|
2492 { |
|
2493 return NULL; |
|
2494 } |
|
2495 |
|
2496 // ----------------------------------------------------------------------------- |
|
2497 // CAknButton::Draw |
|
2498 // Draw a control called by window server. |
|
2499 // ----------------------------------------------------------------------------- |
|
2500 // |
|
2501 EXPORT_C void CAknButton::Draw( const TRect& /*aRect*/ ) const |
|
2502 { |
|
2503 TRect rect( Rect() ); |
|
2504 TAknLayoutRect centerLayout; |
|
2505 centerLayout.LayoutRect( rect, |
|
2506 AknLayoutScalable_Avkon::toolbar_button_pane_g1().LayoutLine() ); |
|
2507 TRect innerRect( centerLayout.Rect() ); |
|
2508 TRect highlightRect( HighlightRect() ); |
|
2509 CWindowGc& gc = SystemGc(); |
|
2510 CAknButtonState* state = State(); |
|
2511 |
|
2512 // Skin ids are determined here (a bit too early than necessary) so that |
|
2513 // we can avoid doing the same thing in DrawMaskedL. |
|
2514 if ( !( iFlags & KAknButtonNoFrame ) ) |
|
2515 { |
|
2516 TInt frameIdIndex = KFrameId; |
|
2517 |
|
2518 if ( iButtonPressed ) |
|
2519 { |
|
2520 frameIdIndex = KPressedFrameId; |
|
2521 } |
|
2522 else if ( state && state->Flags() & KAknButtonStateHasLatchedFrame ) |
|
2523 { |
|
2524 if ( IsDimmed() ) |
|
2525 { |
|
2526 // dimmed latched frame |
|
2527 frameIdIndex = KLatchedDimmedFrameId; |
|
2528 } |
|
2529 else |
|
2530 { |
|
2531 // latched down |
|
2532 frameIdIndex = KLatchedFrameId; |
|
2533 } |
|
2534 } |
|
2535 else if ( IsDimmed()) |
|
2536 { |
|
2537 // dimmed frame |
|
2538 frameIdIndex = KDimmedFrameId; |
|
2539 } |
|
2540 |
|
2541 if ( SkinIID( frameIdIndex ) != KAknsIIDNone ) |
|
2542 { |
|
2543 iBgContext->SetFrame( SkinIID( frameIdIndex ) ); |
|
2544 iBgContext->SetCenter( SkinIID( ++frameIdIndex ) ); |
|
2545 iBgContext->SetFrameRects( rect, innerRect ); |
|
2546 } |
|
2547 } |
|
2548 |
|
2549 if ( !iExtension->iFlags.IsSet( CAknButtonExtension::EUseAdditionalMask ) ) |
|
2550 { |
|
2551 MAknsSkinInstance* skin = AknsUtils::SkinInstance(); |
|
2552 MAknsControlContext* cc = AknsDrawUtils::ControlContext( this ); |
|
2553 |
|
2554 if ( !( iFlags & KAknButtonNoFrame ) ) |
|
2555 { |
|
2556 // frame graphics |
|
2557 if ( !AknsDrawUtils::Background( skin, iBgContext, NULL, gc, |
|
2558 rect, KAknsDrawParamNoClearUnderImage ) ) |
|
2559 { |
|
2560 gc.SetBrushColor( KRgbRed ); |
|
2561 gc.SetBrushStyle( CGraphicsContext::ESolidBrush ); |
|
2562 gc.DrawRect( rect ); |
|
2563 } |
|
2564 |
|
2565 |
|
2566 if ( IsFocused() && !highlightRect.IsEmpty() ) |
|
2567 { |
|
2568 iBgContext->SetFrame( KAknsIIDQsnFrButtonHighlight ); |
|
2569 iBgContext->SetCenter( KAknsIIDQsnFrButtonHighlightCenter ); |
|
2570 iBgContext->SetFrameRects( rect, innerRect ); |
|
2571 |
|
2572 // frame graphics |
|
2573 if ( !AknsDrawUtils::Background( skin, iBgContext, NULL, gc, |
|
2574 rect, KAknsDrawParamNoClearUnderImage ) ) |
|
2575 { |
|
2576 gc.SetBrushColor( KRgbRed ); |
|
2577 gc.SetBrushStyle( CGraphicsContext::ESolidBrush ); |
|
2578 gc.DrawRect( rect ); |
|
2579 } |
|
2580 } |
|
2581 } |
|
2582 else if ( ( iFlags & KAknButtonNoFrame && iFlags & KAknButtonPressedDownFrame ) && |
|
2583 ( iButtonPressed || |
|
2584 ( state && state->Flags() & KAknButtonStateHasLatchedFrame && |
|
2585 !IsDimmed() ) ) ) |
|
2586 { |
|
2587 gc.BitBltMasked( Rect().iTl, iExtension->iPressedDownBmp, |
|
2588 TRect( TPoint(0,0), Size() ), |
|
2589 iExtension->iPressedDownBmpMask, EFalse ); |
|
2590 } |
|
2591 } |
|
2592 else if ( !( iFlags & KAknButtonNoFrame ) ) |
|
2593 { |
|
2594 if ( AknsUtils::SkinInstance() ) |
|
2595 { |
|
2596 AknsDrawUtils::Background( AknsUtils::SkinInstance(), iBgContext, this, gc, |
|
2597 rect, KAknsDrawParamNoClearUnderImage ); |
|
2598 } |
|
2599 } |
|
2600 |
|
2601 TBool hasIcon = ( GetCurrentIcon() != NULL ); |
|
2602 TBool hasText = state && state->HasText(); |
|
2603 |
|
2604 if ( hasIcon && hasText ) |
|
2605 { |
|
2606 DrawTextAndIconButton( gc ); |
|
2607 } |
|
2608 else if ( hasText ) |
|
2609 { |
|
2610 DrawTextButton( gc ); |
|
2611 } |
|
2612 else if ( hasIcon ) |
|
2613 { |
|
2614 DrawIconButton( gc ); |
|
2615 } |
|
2616 } |
|
2617 |
|
2618 // ----------------------------------------------------------------------------- |
|
2619 // CAknButton::ConstructFromResourceL |
|
2620 // Constructs controls from a resource file. |
|
2621 // @param aResourceId is the ID for this component's resource |
|
2622 // ----------------------------------------------------------------------------- |
|
2623 // |
|
2624 EXPORT_C void CAknButton::ConstructFromResourceL( const TInt aResourceId ) |
|
2625 { |
|
2626 if ( aResourceId ) |
|
2627 { |
|
2628 TResourceReader reader; |
|
2629 iCoeEnv->CreateResourceReaderLC( reader, aResourceId ); |
|
2630 ConstructFromResourceL( reader ); |
|
2631 CleanupStack::PopAndDestroy(); |
|
2632 } |
|
2633 } |
|
2634 |
|
2635 // ----------------------------------------------------------------------------- |
|
2636 // CAknButton::SetCurrentState |
|
2637 // Sets active button state index |
|
2638 // @param aStateIndex is the index inside state array |
|
2639 // @param aDrawNow should be ETrue for the button to be redrawn |
|
2640 // ----------------------------------------------------------------------------- |
|
2641 // |
|
2642 EXPORT_C void CAknButton::SetCurrentState( const TInt aStateIndex, |
|
2643 const TBool aDrawNow ) |
|
2644 { |
|
2645 TInt newIndex = -1; |
|
2646 if ( iStates && iStates->Count() ) |
|
2647 { |
|
2648 newIndex = aStateIndex % iStates->Count(); |
|
2649 } |
|
2650 |
|
2651 TRAP_IGNORE( SetStateIndexL( newIndex ) ); |
|
2652 if ( aDrawNow ) |
|
2653 { |
|
2654 DrawNow(); |
|
2655 } |
|
2656 } |
|
2657 |
|
2658 // ----------------------------------------------------------------------------- |
|
2659 // CAknButton::AddStateL |
|
2660 // Adds one more state for the button to the end of state array. |
|
2661 // ----------------------------------------------------------------------------- |
|
2662 // |
|
2663 EXPORT_C void CAknButton::AddStateL( CGulIcon* aIcon, |
|
2664 CGulIcon* aDimmedIcon, |
|
2665 CGulIcon* aPressedIcon, |
|
2666 CGulIcon* aHoverIcon, |
|
2667 const TDesC& aText, |
|
2668 const TDesC& aHelpText, |
|
2669 const TInt aStateFlags ) |
|
2670 { |
|
2671 CAknButtonState* state = new (ELeave) CAknButtonState( aStateFlags ); |
|
2672 CleanupStack::PushL( state ); |
|
2673 state->ConstructL( aIcon, aDimmedIcon, aPressedIcon, aHoverIcon, aText, |
|
2674 aHelpText ); |
|
2675 iStates->AppendL( state ); |
|
2676 CleanupStack::Pop( state ); |
|
2677 } |
|
2678 |
|
2679 // ----------------------------------------------------------------------------- |
|
2680 // CAknButton::AddStateL |
|
2681 // Adds one more state for the button to the end of state array. |
|
2682 // ----------------------------------------------------------------------------- |
|
2683 // |
|
2684 EXPORT_C void CAknButton::AddStateL( const TDesC& aFilePath, |
|
2685 const TInt aBmpId, |
|
2686 const TInt aMaskId, |
|
2687 const TInt aDimmedBmpId, |
|
2688 const TInt aDimmedMaskId, |
|
2689 const TInt aPressedBmpId, |
|
2690 const TInt aPressedMaskId, |
|
2691 const TInt aHoverBmpId, |
|
2692 const TInt aHoverMaskId, |
|
2693 const TDesC& aText, |
|
2694 const TDesC& aHelpText, |
|
2695 const TInt aStateFlags, |
|
2696 const TAknsItemID& aId, |
|
2697 const TAknsItemID& aDimmedId, |
|
2698 const TAknsItemID& aPressedId, |
|
2699 const TAknsItemID& aHoverId ) |
|
2700 { |
|
2701 CAknButtonState* state = new (ELeave) CAknButtonState( aStateFlags ); |
|
2702 CleanupStack::PushL( state ); |
|
2703 state->ConstructL( aFilePath, aBmpId, aMaskId, aDimmedBmpId, aDimmedMaskId, |
|
2704 aPressedBmpId, aPressedMaskId, aHoverBmpId, aHoverMaskId, |
|
2705 aText, aHelpText, aId, aDimmedId, aPressedId, aHoverId ); |
|
2706 iStates->AppendL( state ); |
|
2707 CleanupStack::Pop( state ); |
|
2708 } |
|
2709 |
|
2710 |
|
2711 // ----------------------------------------------------------------------------- |
|
2712 // CAknButton::AddStateL |
|
2713 // Adds one more state for the button to the end of state array. |
|
2714 // ----------------------------------------------------------------------------- |
|
2715 // |
|
2716 void CAknButton::AddStateL( CGulIcon* aIcon, |
|
2717 CGulIcon* aDimmedIcon, |
|
2718 CGulIcon* aPressedIcon, |
|
2719 CGulIcon* aHoverIcon, |
|
2720 const TDesC& aText, |
|
2721 const TDesC& aHelpText, |
|
2722 const TInt aStateFlags, |
|
2723 const TInt aCommandId ) |
|
2724 { |
|
2725 CAknCommandButtonState* state = |
|
2726 new (ELeave) CAknCommandButtonState( aStateFlags, aCommandId ); |
|
2727 CleanupStack::PushL( state ); |
|
2728 state->ConstructL( aIcon, aDimmedIcon, aPressedIcon, aHoverIcon, aText, |
|
2729 aHelpText ); |
|
2730 iStates->AppendL( state ); |
|
2731 CleanupStack::Pop( state ); |
|
2732 } |
|
2733 |
|
2734 |
|
2735 // ----------------------------------------------------------------------------- |
|
2736 // CAknButton::SetFlags |
|
2737 // Sets the button flags |
|
2738 // ----------------------------------------------------------------------------- |
|
2739 // |
|
2740 EXPORT_C void CAknButton::SetButtonFlags( const TInt aFlags ) |
|
2741 { |
|
2742 if ( !(iFlags & KAknButtonNoFrame ) && aFlags & KAknButtonNoFrame ) |
|
2743 { |
|
2744 iExtension->iMargins.SetAllValuesTo( 0 ); |
|
2745 } |
|
2746 if ( aFlags & KAknButtonHitTest ) |
|
2747 { |
|
2748 SetHitTest( iExtension ); |
|
2749 iExtension->HandleFeedbackAreaChange(); |
|
2750 } |
|
2751 if ( aFlags & KAknButtonNoFrame && aFlags & KAknButtonPressedDownFrame ) |
|
2752 { |
|
2753 TRAP_IGNORE ( CreatePressedDownFrameL() ); |
|
2754 } |
|
2755 iFlags = aFlags; |
|
2756 } |
|
2757 |
|
2758 // ----------------------------------------------------------------------------- |
|
2759 // CAknButton::SetFrameAndCenterIds |
|
2760 // Sets specified frame IDs. Can be used when default frame is not suitable. |
|
2761 // Use KAknsIIDNone value in case when some frame or center drawing is not |
|
2762 // needed or KAknsIIDDefault when the default button frame should be used. |
|
2763 // ----------------------------------------------------------------------------- |
|
2764 // |
|
2765 EXPORT_C void CAknButton::SetFrameAndCenterIds( |
|
2766 const TAknsItemID& aFrameId, |
|
2767 const TAknsItemID& aCenterId, |
|
2768 const TAknsItemID& aLatchedFrameId, |
|
2769 const TAknsItemID& aLatchedCenterId, |
|
2770 const TAknsItemID& aDimmedFrameId, |
|
2771 const TAknsItemID& aDimmedCenterId, |
|
2772 const TAknsItemID& aPressedFrameId, |
|
2773 const TAknsItemID& aPressedCenterId, |
|
2774 const TAknsItemID& aLatchedDimmedFrameId, |
|
2775 const TAknsItemID& aLatchedDimmedCenterId ) |
|
2776 { |
|
2777 RArray<TAknsItemID>& skinIds = iExtension->iFrameAndCenterIds; |
|
2778 |
|
2779 if ( aFrameId != KAknsIIDDefault ) |
|
2780 { |
|
2781 skinIds[KFrameId] = aFrameId; |
|
2782 } |
|
2783 if ( aCenterId != KAknsIIDDefault ) |
|
2784 { |
|
2785 skinIds[KCenterId] = aCenterId; |
|
2786 } |
|
2787 if ( aLatchedFrameId != KAknsIIDDefault ) |
|
2788 { |
|
2789 skinIds[KLatchedFrameId] = aLatchedFrameId; |
|
2790 } |
|
2791 if ( aLatchedCenterId != KAknsIIDDefault ) |
|
2792 { |
|
2793 skinIds[KLatchedCenterId] = aLatchedCenterId; |
|
2794 } |
|
2795 if ( aDimmedFrameId != KAknsIIDDefault ) |
|
2796 { |
|
2797 skinIds[KDimmedFrameId] = aDimmedFrameId; |
|
2798 } |
|
2799 if ( aDimmedCenterId != KAknsIIDDefault ) |
|
2800 { |
|
2801 skinIds[KDimmedCenterId] = aDimmedCenterId; |
|
2802 } |
|
2803 if ( aPressedFrameId != KAknsIIDDefault ) |
|
2804 { |
|
2805 skinIds[KPressedFrameId] = aPressedFrameId; |
|
2806 } |
|
2807 if ( aPressedCenterId != KAknsIIDDefault ) |
|
2808 { |
|
2809 skinIds[KPressedCenterId] = aPressedCenterId; |
|
2810 } |
|
2811 if ( aLatchedDimmedFrameId != KAknsIIDDefault ) |
|
2812 { |
|
2813 skinIds[KLatchedDimmedFrameId] = aLatchedDimmedFrameId; |
|
2814 } |
|
2815 if ( aLatchedDimmedCenterId != KAknsIIDDefault ) |
|
2816 { |
|
2817 skinIds[KLatchedDimmedCenterId] = aLatchedDimmedCenterId; |
|
2818 } |
|
2819 } |
|
2820 |
|
2821 // ----------------------------------------------------------------------------- |
|
2822 // CAknButton::SetBackgroundIds |
|
2823 // ----------------------------------------------------------------------------- |
|
2824 // |
|
2825 EXPORT_C void CAknButton::SetBackgroundIds( |
|
2826 const TAknsItemID& aBackgroundId, |
|
2827 const TAknsItemID& aLatchedBackgroundId, |
|
2828 const TAknsItemID& aDimmedBackgroundId, |
|
2829 const TAknsItemID& aPressedBackgroundId, |
|
2830 const TAknsItemID& aLatchedDimmedBackgroundId ) |
|
2831 { |
|
2832 CAknButton::SetFrameAndCenterIds( aBackgroundId, aBackgroundId, |
|
2833 aLatchedBackgroundId, |
|
2834 aLatchedBackgroundId, |
|
2835 aDimmedBackgroundId, aDimmedBackgroundId, |
|
2836 aPressedBackgroundId, |
|
2837 aPressedBackgroundId, |
|
2838 aLatchedDimmedBackgroundId, |
|
2839 aLatchedDimmedBackgroundId ); |
|
2840 } |
|
2841 |
|
2842 // ----------------------------------------------------------------------------- |
|
2843 // CAknButton::SetTextFont |
|
2844 // Sets some specific text font. |
|
2845 // ----------------------------------------------------------------------------- |
|
2846 // |
|
2847 EXPORT_C void CAknButton::SetTextFont( const CFont* aFont ) |
|
2848 { |
|
2849 iFont = aFont; |
|
2850 } |
|
2851 |
|
2852 // ----------------------------------------------------------------------------- |
|
2853 // CAknButton::SetTextColorIds |
|
2854 // Sets the color table and color index for the button text. |
|
2855 // It will be used on button drawing if color of the text shouldn't be taken |
|
2856 // from text layout. |
|
2857 // ----------------------------------------------------------------------------- |
|
2858 // |
|
2859 EXPORT_C void CAknButton::SetTextColorIds( const TAknsItemID& aTextColorTableId, |
|
2860 const TInt aTextColorIndex ) |
|
2861 { |
|
2862 iTextColorTableId = aTextColorTableId; |
|
2863 iTextColorIndex = aTextColorIndex; |
|
2864 |
|
2865 TRgb textColor; |
|
2866 |
|
2867 if ( AknsUtils::GetCachedColor( AknsUtils::SkinInstance(), textColor, |
|
2868 iTextColorTableId, iTextColorIndex ) == KErrNone ) |
|
2869 { |
|
2870 TRAP_IGNORE( OverrideColorL( EColorButtonText, textColor ) ); |
|
2871 DrawDeferred(); |
|
2872 } |
|
2873 } |
|
2874 |
|
2875 // ----------------------------------------------------------------------------- |
|
2876 // CAknButton::SetTextHorizontalAlignment |
|
2877 // Sets the horizontal alignment for the text inside the button. It will be used |
|
2878 // if alignment shouldn't be taken from text layout. By default it will be |
|
2879 // centered. |
|
2880 // ----------------------------------------------------------------------------- |
|
2881 // |
|
2882 EXPORT_C void CAknButton::SetTextHorizontalAlignment( |
|
2883 const CGraphicsContext::TTextAlign aHorizontalAlignment ) |
|
2884 { |
|
2885 iHorizontalAlignment = aHorizontalAlignment; |
|
2886 } |
|
2887 |
|
2888 // ----------------------------------------------------------------------------- |
|
2889 // CAknButton::SetTextVerticalAlignment |
|
2890 // Sets the vertical alignment for the text inside the button. It will be used |
|
2891 // if alignment shouldn't be taken from text layout. By default it will be |
|
2892 // centered. |
|
2893 // ----------------------------------------------------------------------------- |
|
2894 // |
|
2895 EXPORT_C void CAknButton::SetTextVerticalAlignment( |
|
2896 const CAknButton::TAlignment aVerticalAlignment ) |
|
2897 { |
|
2898 iVerticalAlignment = aVerticalAlignment; |
|
2899 } |
|
2900 |
|
2901 // ----------------------------------------------------------------------------- |
|
2902 // CAknButton::SetTextUnderlineStyle |
|
2903 // Sets the text underline style for the text inside the button. |
|
2904 // ----------------------------------------------------------------------------- |
|
2905 // |
|
2906 EXPORT_C void CAknButton::SetTextUnderlineStyle( TFontUnderline aUnderlineStyle ) |
|
2907 { |
|
2908 iExtension->iUnderlineStyle = aUnderlineStyle; |
|
2909 } |
|
2910 |
|
2911 // ----------------------------------------------------------------------------- |
|
2912 // CAknButton::SetIconScaleMode |
|
2913 // Sets the scale mode for the icon inside the button. The default is |
|
2914 // EAspectRatioNotPreserved. |
|
2915 // ----------------------------------------------------------------------------- |
|
2916 // |
|
2917 EXPORT_C void CAknButton::SetIconScaleMode( const TScaleMode aScaleMode ) |
|
2918 { |
|
2919 iScaleMode = aScaleMode; |
|
2920 |
|
2921 for ( TInt i = 0; i < iStates->Count(); ++i ) |
|
2922 { |
|
2923 CAknButtonState* state = iStates->At( i ); |
|
2924 |
|
2925 if ( state ) |
|
2926 { |
|
2927 state->SetIconScaleMode( aScaleMode ); |
|
2928 } |
|
2929 } |
|
2930 } |
|
2931 |
|
2932 // ----------------------------------------------------------------------------- |
|
2933 // CAknButton::SetIconHorizontalAlignment |
|
2934 // Sets the horizontal alignment for the icon inside the button. |
|
2935 // The default is ECenter |
|
2936 // ----------------------------------------------------------------------------- |
|
2937 // |
|
2938 EXPORT_C void CAknButton::SetIconHorizontalAlignment( |
|
2939 const CAknButton::TAlignment aHorizontalAlignment ) |
|
2940 { |
|
2941 iExtension->iHorizontalIconAlignment = aHorizontalAlignment; |
|
2942 } |
|
2943 // ----------------------------------------------------------------------------- |
|
2944 // CAknButton::SetIconVerticalAlignment |
|
2945 // Sets the vertical alignment for the icon inside the button. |
|
2946 // The default is ECenter |
|
2947 // ----------------------------------------------------------------------------- |
|
2948 // |
|
2949 EXPORT_C void CAknButton::SetIconVerticalAlignment( |
|
2950 const CAknButton::TAlignment aVerticalAlignment ) |
|
2951 { |
|
2952 iExtension->iVerticalIconAlignment = aVerticalAlignment; |
|
2953 } |
|
2954 |
|
2955 // ----------------------------------------------------------------------------- |
|
2956 // CAknButton::SetTextAndIconAlignment |
|
2957 // Sets the icon and text alignment for the button having both |
|
2958 // The default is EIconBeforeText |
|
2959 // ----------------------------------------------------------------------------- |
|
2960 // |
|
2961 EXPORT_C void CAknButton::SetTextAndIconAlignment ( |
|
2962 const CAknButton::TTextAndIconAlignment aAlignment ) |
|
2963 { |
|
2964 iExtension->iTextAndIconAlignment = aAlignment; |
|
2965 } |
|
2966 |
|
2967 // ----------------------------------------------------------------------------- |
|
2968 // CAknButton::SetHelpNoteTimeouts |
|
2969 // Sets the delay before the help text is shown and also specifies the time for |
|
2970 // how long help text is visible. |
|
2971 // ----------------------------------------------------------------------------- |
|
2972 // |
|
2973 EXPORT_C void CAknButton::SetHelpNoteTimeouts( const TInt aBeforeTimeout, |
|
2974 const TInt aInViewTimeout ) |
|
2975 { |
|
2976 if ( aBeforeTimeout >= 0 ) |
|
2977 { |
|
2978 iHelpNoteWaitInterval = aBeforeTimeout; |
|
2979 } |
|
2980 if ( aInViewTimeout >= 0 ) |
|
2981 { |
|
2982 iHelpNoteInViewInterval = aInViewTimeout; |
|
2983 } |
|
2984 |
|
2985 if(iHelpNote) |
|
2986 { |
|
2987 iHelpNote->SetTimeDelayBeforeShow( iHelpNoteWaitInterval ); |
|
2988 iHelpNote->SetTimePopupInView( iHelpNoteInViewInterval ); |
|
2989 } |
|
2990 } |
|
2991 |
|
2992 // ----------------------------------------------------------------------------- |
|
2993 // CAknButton::SetKeyRepeatInterval |
|
2994 // Sets the interval for the key repeat. |
|
2995 // ----------------------------------------------------------------------------- |
|
2996 // |
|
2997 EXPORT_C void CAknButton::SetKeyRepeatInterval( const TInt aKeyRepeatDelay, |
|
2998 const TInt aKeyRepeatInterval ) |
|
2999 { |
|
3000 // Convert time intervals to microseconds |
|
3001 iKeyRepeatDelay = aKeyRepeatDelay * 1000; |
|
3002 iKeyRepeatInterval = aKeyRepeatInterval * 1000; |
|
3003 } |
|
3004 |
|
3005 // ----------------------------------------------------------------------------- |
|
3006 // CAknButton::SetLongPressInterval |
|
3007 // Sets the interval for the long presses. |
|
3008 // ----------------------------------------------------------------------------- |
|
3009 // |
|
3010 EXPORT_C void CAknButton::SetLongPressInterval( const TInt aLongPressInterval ) |
|
3011 { |
|
3012 iExtension->iLongPressInterval = aLongPressInterval * 1000; |
|
3013 } |
|
3014 |
|
3015 // ----------------------------------------------------------------------------- |
|
3016 // CAknButton::StateIndex |
|
3017 // Returns the index of the current button state. |
|
3018 // ----------------------------------------------------------------------------- |
|
3019 // |
|
3020 EXPORT_C TInt CAknButton::StateIndex() const |
|
3021 { |
|
3022 return iStateIndex; |
|
3023 } |
|
3024 |
|
3025 // ----------------------------------------------------------------------------- |
|
3026 // CAknButton::EnablePictographsL |
|
3027 // Enables pictograph drawing in the button text. |
|
3028 // Only effective in Japanese variant. |
|
3029 // By default, it is disabled. |
|
3030 // ----------------------------------------------------------------------------- |
|
3031 // |
|
3032 EXPORT_C void CAknButton::EnablePictographsL( CAknPictographInterface& aInterface ) |
|
3033 { |
|
3034 iExtension->iPictographInterface = &aInterface; |
|
3035 } |
|
3036 |
|
3037 // ----------------------------------------------------------------------------- |
|
3038 // CAknButton::DisablePictographs |
|
3039 // Disables pictograph drawing in the button text. |
|
3040 // Only effective in Japanese variant. |
|
3041 // By default, it is disabled. |
|
3042 // ----------------------------------------------------------------------------- |
|
3043 // |
|
3044 EXPORT_C void CAknButton::DisablePictographs() |
|
3045 { |
|
3046 iExtension->iPictographInterface = NULL; |
|
3047 } |
|
3048 |
|
3049 // ----------------------------------------------------------------------------- |
|
3050 // CAknButton::SetHighlightRect |
|
3051 // It will change the default highlight rectangular around |
|
3052 // the focused button |
|
3053 // ----------------------------------------------------------------------------- |
|
3054 // |
|
3055 EXPORT_C void CAknButton::SetHighlightRect( const TRect& aRect ) |
|
3056 { |
|
3057 iHighlightRect = aRect; |
|
3058 } |
|
3059 |
|
3060 // ----------------------------------------------------------------------------- |
|
3061 // CAknButton::HighlightRect |
|
3062 // Returns highlight rectangular around button |
|
3063 // ----------------------------------------------------------------------------- |
|
3064 // |
|
3065 EXPORT_C TRect CAknButton::HighlightRect() const |
|
3066 { |
|
3067 if ( IsNonFocusing() ) |
|
3068 { |
|
3069 return TRect(); |
|
3070 } |
|
3071 else |
|
3072 { |
|
3073 return iHighlightRect; |
|
3074 } |
|
3075 } |
|
3076 |
|
3077 // ----------------------------------------------------------------------------- |
|
3078 // CAknButton::SetTooltipPosition |
|
3079 // ----------------------------------------------------------------------------- |
|
3080 // |
|
3081 EXPORT_C void CAknButton::SetTooltipPosition( const TTooltipPosition aPosition ) |
|
3082 { |
|
3083 iExtension->iTooltipPosition = aPosition; |
|
3084 } |
|
3085 |
|
3086 // ----------------------------------------------------------------------------- |
|
3087 // CAknButton::RequestExit |
|
3088 // ----------------------------------------------------------------------------- |
|
3089 // |
|
3090 EXPORT_C void CAknButton::SetRequestExit( const TBool aRequestExit ) |
|
3091 { |
|
3092 if (aRequestExit) |
|
3093 { |
|
3094 iFlags |= KAknButtonRequestExitOnButtonUpEvent; |
|
3095 } |
|
3096 else |
|
3097 { |
|
3098 iFlags &= ~KAknButtonRequestExitOnButtonUpEvent; |
|
3099 } |
|
3100 } |
|
3101 |
|
3102 // ----------------------------------------------------------------------------- |
|
3103 // CAknButton::IsDimmed |
|
3104 // ----------------------------------------------------------------------------- |
|
3105 // |
|
3106 EXPORT_C TBool CAknButton::IsDimmed() const |
|
3107 { |
|
3108 return iExtension->iFlags.IsSet( CAknButtonExtension::EDimmed ); |
|
3109 } |
|
3110 |
|
3111 // ----------------------------------------------------------------------------- |
|
3112 // CAknButton::SetHelpTextL |
|
3113 // Sets the help text for dimmed button |
|
3114 // ----------------------------------------------------------------------------- |
|
3115 // |
|
3116 EXPORT_C void CAknButton::SetDimmedHelpTextL( const TDesC& aHelpText ) |
|
3117 { |
|
3118 delete iDimmedHelpText; |
|
3119 iDimmedHelpText = NULL; |
|
3120 |
|
3121 iDimmedHelpText = aHelpText.AllocL(); |
|
3122 } |
|
3123 |
|
3124 // ----------------------------------------------------------------------------- |
|
3125 // CAknButton::ChangeState |
|
3126 // Changes the state of the button |
|
3127 // ----------------------------------------------------------------------------- |
|
3128 // |
|
3129 EXPORT_C TInt CAknButton::ChangeState( TBool aDrawNow ) |
|
3130 { |
|
3131 if ( !iStates || !iStates->Count() ) |
|
3132 { |
|
3133 return -1; |
|
3134 } |
|
3135 |
|
3136 TInt newIndex( iStateIndex + 1 ); |
|
3137 |
|
3138 if ( iStateIndex == iStates->Count() - 1 ) |
|
3139 { |
|
3140 newIndex = 0; |
|
3141 } |
|
3142 |
|
3143 TRAP_IGNORE( SetStateIndexL( newIndex ) ); |
|
3144 |
|
3145 if ( aDrawNow ) |
|
3146 { |
|
3147 DrawNow(); |
|
3148 } |
|
3149 |
|
3150 return iStateIndex; |
|
3151 } |
|
3152 |
|
3153 // ----------------------------------------------------------------------------- |
|
3154 // CAknButton::GetCurrentText |
|
3155 // Returns the texts which will be displayed inside the button for the current |
|
3156 // state. |
|
3157 // ----------------------------------------------------------------------------- |
|
3158 // |
|
3159 EXPORT_C const TDesC& CAknButton::GetCurrentText() const |
|
3160 { |
|
3161 CAknButtonState* state = State(); |
|
3162 if ( state ) |
|
3163 { |
|
3164 return state->Text(); |
|
3165 } |
|
3166 else |
|
3167 { |
|
3168 return KNullDesC(); |
|
3169 } |
|
3170 } |
|
3171 |
|
3172 // ----------------------------------------------------------------------------- |
|
3173 // CAknButton::GetCurrentIcon |
|
3174 // Returns the right icon for the current state |
|
3175 // ----------------------------------------------------------------------------- |
|
3176 // |
|
3177 EXPORT_C const CGulIcon* CAknButton::GetCurrentIcon() const |
|
3178 { |
|
3179 CAknButtonState* state = State(); |
|
3180 const CGulIcon* icon = NULL; |
|
3181 if ( state ) |
|
3182 { |
|
3183 if ( iButtonPressed && state->PressedIcon() ) |
|
3184 { |
|
3185 icon = state->PressedIcon(); |
|
3186 } |
|
3187 else if ( IsDimmed() && state->DimmedIcon() ) |
|
3188 { |
|
3189 icon = state->DimmedIcon(); |
|
3190 } |
|
3191 else |
|
3192 { |
|
3193 icon = state->Icon(); |
|
3194 } |
|
3195 } |
|
3196 return icon; |
|
3197 } |
|
3198 |
|
3199 // ----------------------------------------------------------------------------- |
|
3200 // CAknButton::ShowHelpL |
|
3201 // Shows help text for a certain period of time. |
|
3202 // ----------------------------------------------------------------------------- |
|
3203 // |
|
3204 EXPORT_C void CAknButton::ShowHelpL() |
|
3205 { |
|
3206 if ( !IsVisible() ) |
|
3207 { |
|
3208 return; |
|
3209 } |
|
3210 if ( !iHelpNote ) |
|
3211 { |
|
3212 iHelpNote = CAknInfoPopupNoteController::NewL(); |
|
3213 |
|
3214 iHelpNote->SetTimeDelayBeforeShow( iHelpNoteWaitInterval ); |
|
3215 iHelpNote->SetTimePopupInView( iHelpNoteInViewInterval ); |
|
3216 iHelpNote->SetTooltipModeL( ETrue ); |
|
3217 } |
|
3218 |
|
3219 if ( IsDimmed() && iDimmedHelpText ) |
|
3220 { |
|
3221 iHelpNote->SetTextL( *iDimmedHelpText ); |
|
3222 } |
|
3223 else |
|
3224 { |
|
3225 CAknButtonState* state = State(); |
|
3226 if ( state && state->HasHelp() ) |
|
3227 { |
|
3228 iHelpNote->SetTextL( state->HelpText() ); |
|
3229 } |
|
3230 else |
|
3231 { |
|
3232 return; |
|
3233 } |
|
3234 } |
|
3235 |
|
3236 UpdateTooltipPosition(); |
|
3237 iHelpNote->ShowInfoPopupNote(); |
|
3238 } |
|
3239 |
|
3240 // ----------------------------------------------------------------------------- |
|
3241 // CAknButton::HideHelp |
|
3242 // Hides help text after certain interval. |
|
3243 // ----------------------------------------------------------------------------- |
|
3244 // |
|
3245 EXPORT_C void CAknButton::HideHelp() |
|
3246 { |
|
3247 if(iHelpNote) |
|
3248 { |
|
3249 iHelpNote->HideInfoPopupNote(); |
|
3250 } |
|
3251 } |
|
3252 |
|
3253 // ----------------------------------------------------------------------------- |
|
3254 // CAknButton::State |
|
3255 // Returns current state. |
|
3256 // ----------------------------------------------------------------------------- |
|
3257 // |
|
3258 EXPORT_C CAknButtonState* CAknButton::State() const |
|
3259 { |
|
3260 return State( iStateIndex ); |
|
3261 } |
|
3262 |
|
3263 // ----------------------------------------------------------------------------- |
|
3264 // CAknButton::State |
|
3265 // Returns the state under the specified index. |
|
3266 // ----------------------------------------------------------------------------- |
|
3267 // |
|
3268 EXPORT_C CAknButtonState* CAknButton::State( const TInt aStateIndex ) const |
|
3269 { |
|
3270 CAknButtonState* state = NULL; |
|
3271 if ( iStates && aStateIndex >= 0 && aStateIndex < iStates->Count() ) |
|
3272 { |
|
3273 state = iStates->At( aStateIndex ); |
|
3274 } |
|
3275 return state; |
|
3276 } |
|
3277 |
|
3278 // ----------------------------------------------------------------------------- |
|
3279 // CAknButton::Flags |
|
3280 // ----------------------------------------------------------------------------- |
|
3281 // |
|
3282 EXPORT_C TInt CAknButton::ButtonFlags() const |
|
3283 { |
|
3284 return iFlags; |
|
3285 } |
|
3286 |
|
3287 // ----------------------------------------------------------------------------- |
|
3288 // CAknButton::SetMargins |
|
3289 // Sets button's marginals. |
|
3290 // ----------------------------------------------------------------------------- |
|
3291 // |
|
3292 EXPORT_C void CAknButton::SetMargins( const TMargins8& aMargins ) |
|
3293 { |
|
3294 iExtension->iFlags.Clear( CAknButtonExtension::EUseDefaultMargins ); |
|
3295 iExtension->iMargins = aMargins; |
|
3296 SizeChanged(); |
|
3297 } |
|
3298 |
|
3299 // ----------------------------------------------------------------------------- |
|
3300 // CAknButton::SetIconSize |
|
3301 // Sets button's icon size. |
|
3302 // ----------------------------------------------------------------------------- |
|
3303 // |
|
3304 EXPORT_C TInt CAknButton::SetIconSize( const TSize& aSize ) |
|
3305 { |
|
3306 iExtension->iFlags.Clear( CAknButtonExtension::EUseDefaultIconSize ); |
|
3307 iExtension->iIconSize = aSize; |
|
3308 |
|
3309 return ScaleIcons(); |
|
3310 } |
|
3311 |
|
3312 // ----------------------------------------------------------------------------- |
|
3313 // CAknButton::ResetState |
|
3314 // Sets button to unpressed state. |
|
3315 // ----------------------------------------------------------------------------- |
|
3316 // |
|
3317 EXPORT_C void CAknButton::ResetState( ) |
|
3318 { |
|
3319 StopKeyRepeatTimer(); |
|
3320 StopLongPressTimer(); |
|
3321 iButtonPressed = EFalse; |
|
3322 HideHelp(); |
|
3323 if ( iExtension ) |
|
3324 { |
|
3325 if ( iExtension->iFlags.IsSet( CAknButtonExtension::ELongPressReported ) && Observer() ) |
|
3326 { |
|
3327 TRAP_IGNORE( Observer()->HandleControlEventL( this, |
|
3328 static_cast<MCoeControlObserver::TCoeEvent>( CAknButton::ELongPressEndedEvent ) ) ); |
|
3329 } |
|
3330 |
|
3331 iExtension->iFlags.Clear( CAknButtonExtension::ELongPressReported ); |
|
3332 iExtension->iFlags.Clear( CAknButtonExtension::EKeyRepeatEventReported ); |
|
3333 } |
|
3334 } |
|
3335 |
|
3336 // ----------------------------------------------------------------------------- |
|
3337 // CAknButton::CalculateDefaultMargins |
|
3338 // Calculates default margins. |
|
3339 // ----------------------------------------------------------------------------- |
|
3340 // |
|
3341 void CAknButton::CalculateDefaultMargins() |
|
3342 { |
|
3343 if ( iExtension->iFlags.IsSet( CAknButtonExtension::EUseDefaultMargins ) ) |
|
3344 { |
|
3345 if ( !( iFlags & KAknButtonNoFrame ) ) |
|
3346 { |
|
3347 TAknLayoutRect layoutRect; |
|
3348 layoutRect.LayoutRect( Rect(), |
|
3349 AknLayoutScalable_Avkon::aid_value_unit2().LayoutLine() ); |
|
3350 iExtension->iMargins.SetAllValuesTo( |
|
3351 layoutRect.Rect().Size().iWidth / 10 ); // always square |
|
3352 } |
|
3353 } |
|
3354 |
|
3355 if ( iExtension->iFlags.IsSet( CAknButtonExtension::EUseDefaultIconSize ) ) |
|
3356 { |
|
3357 // ensure that icon size never exceeds the space inside margins |
|
3358 TRect rectInsideMargins( iExtension->iMargins.InnerRect( Rect() ) ); |
|
3359 |
|
3360 if ( rectInsideMargins.Size().iWidth < iExtension->iIconSize.iWidth ) |
|
3361 { |
|
3362 iExtension->iIconSize.iWidth = |
|
3363 Max( 0, rectInsideMargins.Size().iWidth ); |
|
3364 } |
|
3365 |
|
3366 if ( rectInsideMargins.Size().iHeight < iExtension->iIconSize.iHeight ) |
|
3367 { |
|
3368 iExtension->iIconSize.iHeight = |
|
3369 Max( 0, rectInsideMargins.Size().iHeight ); |
|
3370 } |
|
3371 } |
|
3372 } |
|
3373 |
|
3374 // ----------------------------------------------------------------------------- |
|
3375 // CAknButton::ScaleIcons |
|
3376 // Scales all icons. |
|
3377 // ----------------------------------------------------------------------------- |
|
3378 // |
|
3379 TInt CAknButton::ScaleIcons() |
|
3380 { |
|
3381 TInt retval = KErrNone; |
|
3382 |
|
3383 for ( TInt i = 0; i < iStates->Count(); ++i ) |
|
3384 { |
|
3385 CAknButtonState* state = iStates->At( i ); |
|
3386 |
|
3387 if ( state ) |
|
3388 { |
|
3389 retval = Min( retval, state->ScaleIcons( iExtension->iIconSize, |
|
3390 iScaleMode ) ); |
|
3391 if ( iExtension->iFlags.IsSet( CAknButtonExtension::EDimmed ) && |
|
3392 !state->iDimmedIcon && |
|
3393 state->iIcon ) |
|
3394 { |
|
3395 TRAP_IGNORE( CreateAndSetDimmedIconL( state->iDimmedIcon, |
|
3396 state->iIcon, state->ScaleMode() ) ); |
|
3397 } |
|
3398 } |
|
3399 } |
|
3400 |
|
3401 return retval; |
|
3402 } |
|
3403 |
|
3404 // ----------------------------------------------------------------------------- |
|
3405 // CAknButton::DrawTextButton |
|
3406 // Continues drawing of the button which has only text |
|
3407 // ----------------------------------------------------------------------------- |
|
3408 // |
|
3409 void CAknButton::DrawTextButton( CWindowGc& aGc ) const |
|
3410 { |
|
3411 CAknButtonState* state = State(); |
|
3412 if ( !state || !state->HasText() ) |
|
3413 return; |
|
3414 |
|
3415 MAknsSkinInstance* skin = AknsUtils::SkinInstance(); |
|
3416 |
|
3417 TRect textRect = iExtension->iMargins.InnerRect( Rect() ); |
|
3418 |
|
3419 if ( !( iFlags & KAknButtonNoFrame ) && |
|
3420 ( iFlags & KAknButtonTextInsideFrame ) ) |
|
3421 { |
|
3422 TAknLayoutRect center; |
|
3423 center.LayoutRect( Rect(), |
|
3424 AknLayoutScalable_Avkon::toolbar_button_pane_g1().LayoutLine() ); |
|
3425 |
|
3426 textRect = center.Rect(); |
|
3427 } |
|
3428 |
|
3429 aGc.SetBrushStyle( CGraphicsContext::ENullBrush ); |
|
3430 |
|
3431 TRgb penColor; |
|
3432 TRgb brushColor; |
|
3433 GetTextColors( penColor, brushColor ); |
|
3434 aGc.SetPenColor( penColor ); |
|
3435 aGc.SetBrushColor( brushColor ); |
|
3436 |
|
3437 const CFont* font = iFont; |
|
3438 if ( !font ) |
|
3439 { |
|
3440 font = iCoeEnv->NormalFont(); |
|
3441 } |
|
3442 aGc.UseFont( font ); |
|
3443 |
|
3444 aGc.SetUnderlineStyle( iExtension->iUnderlineStyle ); |
|
3445 |
|
3446 // buffer for visually ordered text |
|
3447 TBuf<255 + KAknBidiExtraSpacePerLine> visualText; |
|
3448 TInt clipWidth = textRect.Width(); |
|
3449 |
|
3450 // bidi processing - using AknBidiTextUtils. |
|
3451 AknBidiTextUtils::ConvertToVisualAndClip( |
|
3452 state->Text(), |
|
3453 visualText, |
|
3454 *font, |
|
3455 clipWidth, |
|
3456 clipWidth ); |
|
3457 |
|
3458 TInt baselineOffset = 0; |
|
3459 switch ( iVerticalAlignment ) |
|
3460 { |
|
3461 case ETop: |
|
3462 baselineOffset = font->AscentInPixels(); |
|
3463 break; |
|
3464 |
|
3465 case EBottom: |
|
3466 baselineOffset = textRect.Height(); |
|
3467 break; |
|
3468 |
|
3469 default: // centered |
|
3470 baselineOffset = font->AscentInPixels() + |
|
3471 ( textRect.Height() - font->AscentInPixels() ) / 2; |
|
3472 } |
|
3473 |
|
3474 CGraphicsContext::TTextAlign horAlignment = iHorizontalAlignment; |
|
3475 |
|
3476 aGc.DrawText( visualText, textRect, baselineOffset, horAlignment ); |
|
3477 if ( iExtension->iPictographInterface ) |
|
3478 { |
|
3479 // For Japanese variant only |
|
3480 iExtension->iPictographInterface->Interface()->DrawPictographsInText( |
|
3481 aGc, *font, visualText, textRect, baselineOffset, horAlignment ); |
|
3482 } |
|
3483 } |
|
3484 |
|
3485 // ----------------------------------------------------------------------------- |
|
3486 // CAknButton::DrawIconButton |
|
3487 // Continues drawing of the button which has only an icon in it |
|
3488 // ----------------------------------------------------------------------------- |
|
3489 // |
|
3490 void CAknButton::DrawIconButton( CWindowGc& aGc ) const |
|
3491 { |
|
3492 TRect iconRect( iExtension->iMargins.InnerRect( Rect() ) ); |
|
3493 |
|
3494 aGc.SetBrushStyle( CGraphicsContext::ENullBrush ); |
|
3495 |
|
3496 const CGulIcon* icon = GetCurrentIcon(); |
|
3497 if ( !icon ) |
|
3498 return; |
|
3499 |
|
3500 CFbsBitmap* buttonBmp = icon->Bitmap(); |
|
3501 CFbsBitmap* buttonMask = icon->Mask(); |
|
3502 |
|
3503 TPoint iconPoint; |
|
3504 TSize iconSize ( buttonBmp->SizeInPixels()); |
|
3505 |
|
3506 switch ( iExtension->iHorizontalIconAlignment ) |
|
3507 { |
|
3508 case ERight: |
|
3509 { |
|
3510 iconPoint.iX = iconRect.iBr.iX - iconSize.iWidth; |
|
3511 } |
|
3512 break; |
|
3513 |
|
3514 case ECenter: |
|
3515 { |
|
3516 iconPoint.iX = iconRect.iTl.iX + |
|
3517 (iconRect.Width() / 2 - iconSize.iWidth / 2 ); |
|
3518 } |
|
3519 break; |
|
3520 |
|
3521 case ELeft: |
|
3522 { |
|
3523 iconPoint.iX = iconRect.iTl.iX; |
|
3524 } |
|
3525 break; |
|
3526 |
|
3527 default: |
|
3528 // Should never come here |
|
3529 break; |
|
3530 } |
|
3531 |
|
3532 switch ( iExtension->iVerticalIconAlignment ) |
|
3533 { |
|
3534 case ETop: |
|
3535 { |
|
3536 iconPoint.iY = iconRect.iTl.iY; |
|
3537 } |
|
3538 break; |
|
3539 |
|
3540 case ECenter: |
|
3541 { |
|
3542 iconPoint.iY = iconRect.iTl.iY + |
|
3543 ( iconRect.Height() / 2 - iconSize.iHeight / 2 ); |
|
3544 } |
|
3545 break; |
|
3546 |
|
3547 case EBottom: |
|
3548 { |
|
3549 iconPoint.iY = iconRect.iBr.iY - iconSize.iHeight; |
|
3550 } |
|
3551 break; |
|
3552 |
|
3553 default: |
|
3554 // Should never come here |
|
3555 break; |
|
3556 } |
|
3557 |
|
3558 if( buttonBmp && buttonMask ) |
|
3559 { |
|
3560 aGc.BitBltMasked( iconPoint, buttonBmp, |
|
3561 iconRect.Size(), buttonMask, ETrue ); |
|
3562 } |
|
3563 else if ( buttonBmp ) |
|
3564 { |
|
3565 aGc.BitBlt( iconPoint, buttonBmp, iconRect.Size() ); |
|
3566 } |
|
3567 } |
|
3568 |
|
3569 // ----------------------------------------------------------------------------- |
|
3570 // CAknButton::DrawTextAndIconButton |
|
3571 // Continues drawing of the button which has both text and icon |
|
3572 // ----------------------------------------------------------------------------- |
|
3573 // |
|
3574 void CAknButton::DrawTextAndIconButton( CWindowGc& aGc ) const |
|
3575 { |
|
3576 CAknButtonState* state = State(); |
|
3577 if ( !state || !state->HasText() ) |
|
3578 { |
|
3579 return; |
|
3580 } |
|
3581 |
|
3582 const CGulIcon* icon = GetCurrentIcon(); |
|
3583 if ( !icon ) |
|
3584 { |
|
3585 return; |
|
3586 } |
|
3587 |
|
3588 TRect rect = iExtension->iMargins.InnerRect( Rect() ); |
|
3589 TRect iconRect; |
|
3590 TRect textRect; |
|
3591 |
|
3592 if ( !( iFlags & KAknButtonNoFrame ) && |
|
3593 ( iFlags & KAknButtonTextInsideFrame )) |
|
3594 { |
|
3595 TAknLayoutRect centerLayout; |
|
3596 centerLayout.LayoutRect( rect, |
|
3597 AknLayoutScalable_Avkon::toolbar_button_pane_g1().LayoutLine() ); |
|
3598 rect = centerLayout.Rect(); |
|
3599 } |
|
3600 |
|
3601 CFbsBitmap* buttonBmp = icon->Bitmap(); |
|
3602 CFbsBitmap* buttonMask = icon->Mask(); |
|
3603 TSize iconSize ( buttonBmp->SizeInPixels()); |
|
3604 |
|
3605 // Set rects for icon and text according to their positioning |
|
3606 // First icon rect according to icon size - rest is for text |
|
3607 |
|
3608 switch ( iExtension->iTextAndIconAlignment ) |
|
3609 { |
|
3610 case EIconBeforeText: |
|
3611 if ( AknLayoutUtils::LayoutMirrored() ) |
|
3612 { |
|
3613 textRect.SetRect( rect.iTl.iX, rect.iTl.iY, |
|
3614 rect.iBr.iX - iconSize.iWidth, rect.iBr.iY); |
|
3615 iconRect.SetRect( rect.iTl.iX + |
|
3616 rect.Width() -iconSize.iWidth, |
|
3617 rect.iTl.iY, rect.iBr.iX, rect.iBr.iY ); |
|
3618 } |
|
3619 else |
|
3620 { |
|
3621 iconRect.SetRect( rect.iTl.iX, rect.iTl.iY, |
|
3622 rect.iTl.iX + iconSize.iWidth, rect.iBr.iY); |
|
3623 textRect.SetRect( rect.iTl.iX + iconSize.iWidth, |
|
3624 rect.iTl.iY, rect.iBr.iX, rect.iBr.iY ); |
|
3625 } |
|
3626 |
|
3627 break; |
|
3628 |
|
3629 case EIconAfterText: |
|
3630 if ( AknLayoutUtils::LayoutMirrored() ) |
|
3631 { |
|
3632 iconRect.SetRect( rect.iTl.iX, rect.iTl.iY, |
|
3633 rect.iTl.iX + iconSize.iWidth, rect.iBr.iY); |
|
3634 textRect.SetRect( rect.iTl.iX + iconSize.iWidth, |
|
3635 rect.iTl.iY, rect.iBr.iX, rect.iBr.iY ); |
|
3636 } |
|
3637 else |
|
3638 { |
|
3639 textRect.SetRect( rect.iTl.iX, rect.iTl.iY, |
|
3640 rect.iBr.iX - iconSize.iWidth, rect.iBr.iY); |
|
3641 iconRect.SetRect( rect.iTl.iX + |
|
3642 rect.Width() -iconSize.iWidth, |
|
3643 rect.iTl.iY, rect.iBr.iX, rect.iBr.iY ); |
|
3644 } |
|
3645 break; |
|
3646 |
|
3647 case EIconOverText: |
|
3648 iconRect.SetRect( rect.iTl.iX, rect.iTl.iY, |
|
3649 rect.iBr.iX, rect.iTl.iY + iconSize.iHeight ); |
|
3650 textRect.SetRect( rect.iTl.iX, rect.iTl.iY + iconSize.iHeight, |
|
3651 rect.iBr.iX, rect.iBr.iY ); |
|
3652 break; |
|
3653 |
|
3654 case EIconUnderText: |
|
3655 textRect.SetRect( rect.iTl.iX, rect.iTl.iY, |
|
3656 rect.iBr.iX, rect.iBr.iY - iconSize.iHeight ); |
|
3657 iconRect.SetRect( rect.iTl.iX, rect.iBr.iY - iconSize.iHeight, |
|
3658 rect.iBr.iX, rect.iBr.iY ); |
|
3659 break; |
|
3660 |
|
3661 case EOverlay: |
|
3662 { |
|
3663 textRect = rect; |
|
3664 iconRect = rect; |
|
3665 } |
|
3666 break; |
|
3667 |
|
3668 default: |
|
3669 return; |
|
3670 } |
|
3671 |
|
3672 // Draw icon |
|
3673 TPoint iconPoint; |
|
3674 switch ( iExtension->iHorizontalIconAlignment ) |
|
3675 { |
|
3676 case ERight: |
|
3677 { |
|
3678 iconPoint.iX = iconRect.iBr.iX - iconSize.iWidth; |
|
3679 } |
|
3680 break; |
|
3681 |
|
3682 case ECenter: |
|
3683 { |
|
3684 iconPoint.iX = iconRect.iTl.iX + |
|
3685 (iconRect.Width() / 2 - iconSize.iWidth / 2 ); |
|
3686 } |
|
3687 break; |
|
3688 |
|
3689 case ELeft: |
|
3690 { |
|
3691 iconPoint.iX = iconRect.iTl.iX; |
|
3692 } |
|
3693 break; |
|
3694 |
|
3695 default: |
|
3696 // Should never come here |
|
3697 break; |
|
3698 } |
|
3699 |
|
3700 switch ( iExtension->iVerticalIconAlignment ) |
|
3701 { |
|
3702 case ETop: |
|
3703 { |
|
3704 iconPoint.iY = iconRect.iTl.iY; |
|
3705 } |
|
3706 break; |
|
3707 |
|
3708 case ECenter: |
|
3709 { |
|
3710 iconPoint.iY = iconRect.iTl.iY + |
|
3711 ( iconRect.Height() / 2 - iconSize.iHeight / 2 ); |
|
3712 } |
|
3713 break; |
|
3714 |
|
3715 case EBottom: |
|
3716 { |
|
3717 iconPoint.iY = iconRect.iBr.iY - iconSize.iHeight; |
|
3718 } |
|
3719 break; |
|
3720 |
|
3721 default: |
|
3722 // Should never come here |
|
3723 break; |
|
3724 } |
|
3725 |
|
3726 if( buttonBmp && buttonMask ) |
|
3727 { |
|
3728 aGc.BitBltMasked( iconPoint, buttonBmp, |
|
3729 iconRect.Size(), buttonMask, ETrue ); |
|
3730 } |
|
3731 else if ( buttonBmp ) |
|
3732 { |
|
3733 aGc.BitBlt( iconPoint, buttonBmp, iconRect.Size() ); |
|
3734 } |
|
3735 |
|
3736 const CFont* font = iFont; |
|
3737 if ( !font ) |
|
3738 { |
|
3739 font = iCoeEnv->NormalFont(); |
|
3740 } |
|
3741 aGc.UseFont( font ); |
|
3742 |
|
3743 TRgb penColor; |
|
3744 TRgb brushColor; |
|
3745 GetTextColors( penColor, brushColor ); |
|
3746 aGc.SetPenColor( penColor ); |
|
3747 aGc.SetBrushColor( brushColor ); |
|
3748 |
|
3749 aGc.SetUnderlineStyle( iExtension->iUnderlineStyle ); |
|
3750 |
|
3751 TBuf<255 + KAknBidiExtraSpacePerLine> visualText; // buffer for visually ordered text |
|
3752 TInt clipWidth = textRect.Width(); |
|
3753 |
|
3754 // bidi processing - using AknBidiTextUtils. |
|
3755 AknBidiTextUtils::ConvertToVisualAndClip( |
|
3756 state->Text(), |
|
3757 visualText, |
|
3758 *font, |
|
3759 clipWidth, |
|
3760 clipWidth ); |
|
3761 |
|
3762 TInt baselineOffset = 0; |
|
3763 switch ( iVerticalAlignment ) |
|
3764 { |
|
3765 case ETop: |
|
3766 baselineOffset = font->AscentInPixels(); |
|
3767 break; |
|
3768 |
|
3769 case EBottom: |
|
3770 baselineOffset = textRect.Height(); |
|
3771 break; |
|
3772 |
|
3773 default: // centered |
|
3774 baselineOffset = font->AscentInPixels() + |
|
3775 ( textRect.Height() - font->AscentInPixels() ) / 2; |
|
3776 } |
|
3777 |
|
3778 CGraphicsContext::TTextAlign horAlignment = iHorizontalAlignment; |
|
3779 |
|
3780 aGc.DrawText( visualText, textRect, baselineOffset, horAlignment ); |
|
3781 if ( iExtension->iPictographInterface ) |
|
3782 { |
|
3783 // For Japanese variant only |
|
3784 iExtension->iPictographInterface->Interface()->DrawPictographsInText( |
|
3785 aGc, *font, visualText, textRect, baselineOffset, horAlignment ); |
|
3786 } |
|
3787 } |
|
3788 |
|
3789 // ----------------------------------------------------------------------------- |
|
3790 // Starts the long press timer. |
|
3791 // ----------------------------------------------------------------------------- |
|
3792 // |
|
3793 void CAknButton::StartLongPressTimerL() |
|
3794 { |
|
3795 if ( iExtension ) |
|
3796 { |
|
3797 iExtension->StartLongPressTimerL(); |
|
3798 } |
|
3799 } |
|
3800 |
|
3801 // ----------------------------------------------------------------------------- |
|
3802 // Stops the long press timer. |
|
3803 // ----------------------------------------------------------------------------- |
|
3804 // |
|
3805 void CAknButton::StopLongPressTimer() |
|
3806 { |
|
3807 if ( iExtension && iExtension->iLongPressTimer && |
|
3808 iExtension->iLongPressTimer->IsActive() ) |
|
3809 { |
|
3810 iExtension->iLongPressTimer->Cancel(); |
|
3811 } |
|
3812 } |
|
3813 |
|
3814 // ----------------------------------------------------------------------------- |
|
3815 // CAknButton::StartKeyRepeatTimerL |
|
3816 // Starts the timer for the long presses. The timer is constructed when used |
|
3817 // for the first time. |
|
3818 // ----------------------------------------------------------------------------- |
|
3819 // |
|
3820 void CAknButton::StartKeyRepeatTimerL() |
|
3821 { |
|
3822 if ( !iKeyRepeatTimer ) |
|
3823 { |
|
3824 iKeyRepeatTimer = CPeriodic::NewL( CActive::EPriorityStandard ); |
|
3825 } |
|
3826 else if ( iKeyRepeatTimer->IsActive() ) |
|
3827 { |
|
3828 iKeyRepeatTimer->Cancel(); |
|
3829 } |
|
3830 |
|
3831 if ( iKeyRepeatInterval > 0 ) |
|
3832 { |
|
3833 iKeyRepeatTimer->Start( iKeyRepeatDelay, iKeyRepeatInterval, |
|
3834 TCallBack( ReportKeyRepeatL, this ) ); |
|
3835 } |
|
3836 } |
|
3837 |
|
3838 // ----------------------------------------------------------------------------- |
|
3839 // Stops the key repeat timer. |
|
3840 // ----------------------------------------------------------------------------- |
|
3841 // |
|
3842 void CAknButton::StopKeyRepeatTimer() |
|
3843 { |
|
3844 if ( iKeyRepeatTimer && iKeyRepeatTimer->IsActive() ) |
|
3845 { |
|
3846 iKeyRepeatTimer->Cancel(); |
|
3847 } |
|
3848 } |
|
3849 |
|
3850 // ----------------------------------------------------------------------------- |
|
3851 // CAknButton::ReportKeyRepeatL |
|
3852 // Cancel the timer. |
|
3853 // ----------------------------------------------------------------------------- |
|
3854 // |
|
3855 TInt CAknButton::ReportKeyRepeatL( TAny* aThis ) |
|
3856 { |
|
3857 // Fixes TSW error AJUA-7CEF8H |
|
3858 User::ResetInactivityTime(); |
|
3859 CAknButton* self = reinterpret_cast< CAknButton* >( aThis ); |
|
3860 |
|
3861 if ( self->IsVisible() && |
|
3862 !self->iExtension->iFlags.IsSet( CAknButtonExtension::EDimmed ) ) |
|
3863 { |
|
3864 if ( self->iStates->Count() > 1 ) |
|
3865 { |
|
3866 self->ChangeState( ETrue ); |
|
3867 } |
|
3868 |
|
3869 if ( self->Observer() ) |
|
3870 { |
|
3871 self->Observer()->HandleControlEventL( self, |
|
3872 MCoeControlObserver::EEventStateChanged ); |
|
3873 } |
|
3874 |
|
3875 TBool feedbackNeeded = (self->iStates->Count() > 1) || (self->Observer()); |
|
3876 TBool pointerRepeat = (self->iButtonPressed & KPointerFlag); // it was caused by pointer event |
|
3877 if ( self->iExtension->iFeedback && feedbackNeeded && pointerRepeat) |
|
3878 { |
|
3879 self->iExtension->iFeedback->InstantFeedback( self, ETouchFeedbackSensitiveButton ); |
|
3880 } |
|
3881 |
|
3882 self->iExtension->iFlags.Set( CAknButtonExtension::EKeyRepeatEventReported ); |
|
3883 } |
|
3884 else if ( self->iKeyRepeatTimer && self->iKeyRepeatTimer->IsActive() ) |
|
3885 { |
|
3886 self->iKeyRepeatTimer->Cancel(); |
|
3887 } |
|
3888 |
|
3889 return 1; // CPeriodic ignores return value |
|
3890 } |
|
3891 |
|
3892 // ----------------------------------------------------------------------------- |
|
3893 // CAknButton::Extension |
|
3894 // ----------------------------------------------------------------------------- |
|
3895 // |
|
3896 CAknButtonExtension* CAknButton::Extension() const |
|
3897 { |
|
3898 return iExtension; |
|
3899 } |
|
3900 |
|
3901 // ----------------------------------------------------------------------------- |
|
3902 // CAknButton::UpdateTooltipPosition |
|
3903 // ----------------------------------------------------------------------------- |
|
3904 // |
|
3905 void CAknButton::UpdateTooltipPosition() |
|
3906 { |
|
3907 TPoint position; |
|
3908 |
|
3909 if ( AknsUtils::GetControlPosition( this, position ) != KErrNone ) |
|
3910 { |
|
3911 position = PositionRelativeToScreen(); |
|
3912 } |
|
3913 TRect rect( position, Size() ); |
|
3914 |
|
3915 TPoint center = rect.Center(); |
|
3916 |
|
3917 switch ( iExtension->iTooltipPosition ) |
|
3918 { |
|
3919 case EPositionTop: |
|
3920 { |
|
3921 iHelpNote->SetPositionAndAlignment( |
|
3922 TPoint( center.iX, rect.iTl.iY ), EHCenterVBottom ); |
|
3923 break; |
|
3924 } |
|
3925 case EPositionBottom: |
|
3926 { |
|
3927 iHelpNote->SetPositionAndAlignment( |
|
3928 TPoint( center.iX, rect.iBr.iY ), EHCenterVTop ); |
|
3929 break; |
|
3930 } |
|
3931 case EPositionLeft: |
|
3932 { |
|
3933 iHelpNote->SetPositionAndAlignment( |
|
3934 TPoint( rect.iTl.iX, center.iY ), EHRightVCenter ); |
|
3935 break; |
|
3936 } |
|
3937 case EPositionRight: |
|
3938 { |
|
3939 iHelpNote->SetPositionAndAlignment( |
|
3940 TPoint( rect.iBr.iX, center.iY ), EHLeftVCenter ); |
|
3941 break; |
|
3942 } |
|
3943 default: |
|
3944 { |
|
3945 return; |
|
3946 } |
|
3947 } |
|
3948 } |
|
3949 |
|
3950 // ----------------------------------------------------------------------------- |
|
3951 // CAknButton::RequestExit |
|
3952 // Returns whether button should send EEventRequestExit to command observer |
|
3953 // on button up events. |
|
3954 // ----------------------------------------------------------------------------- |
|
3955 // |
|
3956 TBool CAknButton::RequestExit() const |
|
3957 { |
|
3958 if ( iFlags & KAknButtonRequestExitOnButtonUpEvent ) |
|
3959 { |
|
3960 return ETrue; |
|
3961 } |
|
3962 else |
|
3963 { |
|
3964 return EFalse; |
|
3965 } |
|
3966 } |
|
3967 |
|
3968 // ----------------------------------------------------------------------------- |
|
3969 // CAknButton::ContentRect |
|
3970 // Returns the the rectangle reserved for frame center, or the rect for text and |
|
3971 // icon, if the button has no frames (controls rect for now). |
|
3972 // ----------------------------------------------------------------------------- |
|
3973 // |
|
3974 TRect CAknButton::ContentRect() const |
|
3975 { |
|
3976 TRect rect( Size() ); |
|
3977 if ( !( iFlags & KAknButtonNoFrame ) && |
|
3978 ( iFlags & KAknButtonTextInsideFrame ) ) |
|
3979 { |
|
3980 TAknLayoutRect centerLayout; |
|
3981 centerLayout.LayoutRect( rect, |
|
3982 AknLayoutScalable_Avkon::toolbar_button_pane_g1().LayoutLine() ); |
|
3983 rect = centerLayout.Rect(); |
|
3984 } |
|
3985 return rect; |
|
3986 } |
|
3987 |
|
3988 // ----------------------------------------------------------------------------- |
|
3989 // CAknButton::NeedsRedrawWhenPressed |
|
3990 // Returns boolean value indicating whether button needs redraw when it is |
|
3991 // pressed or released without changes in its state. |
|
3992 // ----------------------------------------------------------------------------- |
|
3993 // |
|
3994 TBool CAknButton::NeedsRedrawWhenPressed() const |
|
3995 { |
|
3996 CAknButtonState* state = State(); |
|
3997 if ( !iButtonPressed && iStates->Count() > 1 ) |
|
3998 { |
|
3999 return EFalse; |
|
4000 } |
|
4001 |
|
4002 if ( iButtonPressed && iFlags & KAknButtonPressedDownFrame ) |
|
4003 { |
|
4004 return ETrue; |
|
4005 } |
|
4006 |
|
4007 return ( state && state->PressedIcon() || |
|
4008 ( !( iFlags & KAknButtonNoFrame ) && |
|
4009 !( iFlags & KAknButtonNoFramePressEvent ) && |
|
4010 !( state && state->Flags() & KAknButtonStateHasLatchedFrame && |
|
4011 SkinIID( KPressedFrameId ) == SkinIID( KLatchedFrameId ) ) ) ); |
|
4012 } |
|
4013 |
|
4014 // ----------------------------------------------------------------------------- |
|
4015 // CAknButton::SkinIID |
|
4016 // ----------------------------------------------------------------------------- |
|
4017 // |
|
4018 TAknsItemID CAknButton::SkinIID( const TInt aIndex ) const |
|
4019 { |
|
4020 if ( iExtension && aIndex >= 0 && |
|
4021 aIndex < iExtension->iFrameAndCenterIds.Count() ) |
|
4022 { |
|
4023 return iExtension->iFrameAndCenterIds[aIndex]; |
|
4024 } |
|
4025 else |
|
4026 { |
|
4027 return KAknsIIDNone; |
|
4028 } |
|
4029 } |
|
4030 |
|
4031 // ----------------------------------------------------------------------------- |
|
4032 // CAknButton::HitAreaContainsL |
|
4033 // Checks if a button icon's non-transparent area was tapped. |
|
4034 // ----------------------------------------------------------------------------- |
|
4035 // |
|
4036 TBool CAknButton::HitAreaContainsL( const TPoint& aPoint, TBool aCheckHitArea ) const |
|
4037 { |
|
4038 TBool buttonEvent( ETrue ); |
|
4039 |
|
4040 if ( aCheckHitArea ) |
|
4041 { |
|
4042 if ( TouchArea().Contains( aPoint ) ) |
|
4043 { |
|
4044 return ETrue; |
|
4045 } |
|
4046 else |
|
4047 { |
|
4048 return EFalse; |
|
4049 } |
|
4050 } |
|
4051 else if ( iFlags & KAknButtonHitTest ) |
|
4052 { |
|
4053 TRect rect( Size() ); |
|
4054 TRect contentRect( ContentRect() ); |
|
4055 |
|
4056 CFbsBitmap* bitmap = new (ELeave) CFbsBitmap; |
|
4057 CleanupStack::PushL( bitmap ); |
|
4058 |
|
4059 User::LeaveIfError( bitmap->Create( rect.Size(), EGray256 ) ); |
|
4060 |
|
4061 CFbsBitmapDevice* device = CFbsBitmapDevice::NewL( bitmap ); |
|
4062 |
|
4063 CleanupStack::PushL( device ); |
|
4064 CFbsBitGc* gc = CFbsBitGc::NewL(); |
|
4065 gc->Activate( device ); |
|
4066 gc->SetBrushStyle( CGraphicsContext::ENullBrush ); |
|
4067 |
|
4068 MAknsSkinInstance* skin = AknsUtils::SkinInstance(); |
|
4069 MAknsControlContext* cc = AknsDrawUtils::ControlContext( this ); |
|
4070 |
|
4071 if ( !(iFlags & KAknButtonNoFrame ) ) |
|
4072 { |
|
4073 CAknButtonState* state = State(); |
|
4074 |
|
4075 TInt frameIdIndex = KFrameId; |
|
4076 if ( iButtonPressed ) |
|
4077 { |
|
4078 frameIdIndex = KPressedFrameId; |
|
4079 } |
|
4080 else if ( state && state->Flags() & KAknButtonStateHasLatchedFrame ) |
|
4081 { |
|
4082 if ( IsDimmed() ) |
|
4083 { |
|
4084 // dimmed latched frame |
|
4085 frameIdIndex = KLatchedDimmedFrameId; |
|
4086 } |
|
4087 else |
|
4088 { |
|
4089 // latched down |
|
4090 frameIdIndex = KLatchedFrameId; |
|
4091 } |
|
4092 } |
|
4093 else if ( IsDimmed()) |
|
4094 { |
|
4095 // dimmed frame |
|
4096 frameIdIndex = KDimmedFrameId; |
|
4097 } |
|
4098 |
|
4099 if ( SkinIID( frameIdIndex ) != KAknsIIDNone ) |
|
4100 { |
|
4101 TAknsItemID frameId = SkinIID( frameIdIndex ); |
|
4102 TAknsItemID centerId = SkinIID( frameIdIndex + 1 ); |
|
4103 |
|
4104 gc->SetBrushColor( KRgbWhite ); |
|
4105 |
|
4106 if ( !AknsDrawUtils::DrawFrame( skin, *gc, rect, |
|
4107 contentRect, frameId, centerId, KAknsSDMAlphaOnly ) ) |
|
4108 { |
|
4109 gc->DrawRect( rect ); |
|
4110 } |
|
4111 gc->DrawRect( contentRect ); |
|
4112 } |
|
4113 } |
|
4114 else if ( GetCurrentIcon() ) |
|
4115 { |
|
4116 // if button has (only) icon, then mark other parts transparent |
|
4117 gc->SetBrushColor( KRgbBlack ); |
|
4118 gc->Clear(); |
|
4119 CFbsBitmap* mask = GetCurrentIcon()->Mask(); |
|
4120 if ( mask ) |
|
4121 { |
|
4122 gc->BitBlt( contentRect.iTl, mask, mask->SizeInPixels() ); |
|
4123 } |
|
4124 } |
|
4125 else if ( GetCurrentText() != KNullDesC ) |
|
4126 { |
|
4127 gc->SetBrushColor( KRgbWhite ); |
|
4128 gc->Clear( contentRect ); |
|
4129 } |
|
4130 else |
|
4131 { |
|
4132 // if this happens.. make the whole button transparent! |
|
4133 gc->SetBrushColor( KRgbBlack ); |
|
4134 gc->Clear( contentRect ); |
|
4135 } |
|
4136 |
|
4137 TRgb pixel; |
|
4138 TPoint point( aPoint - Rect().iTl ); |
|
4139 bitmap->GetPixel( pixel, point ); |
|
4140 |
|
4141 delete gc; |
|
4142 CleanupStack::PopAndDestroy( 2 ); // bitmap, device |
|
4143 |
|
4144 if ( pixel == KRgbBlack ) |
|
4145 { |
|
4146 buttonEvent = EFalse; |
|
4147 } |
|
4148 } // iFlags & KAknButtonHitTest |
|
4149 return buttonEvent; |
|
4150 } |
|
4151 |
|
4152 // ----------------------------------------------------------------------------- |
|
4153 // CAknButton::UsesDefaultMargins |
|
4154 // Checks if the button uses default margins. |
|
4155 // ----------------------------------------------------------------------------- |
|
4156 // |
|
4157 TBool CAknButton::UsesDefaultMargins() const |
|
4158 { |
|
4159 return iExtension->iFlags.IsSet( CAknButtonExtension::EUseDefaultMargins ); |
|
4160 } |
|
4161 |
|
4162 // ----------------------------------------------------------------------------- |
|
4163 // CAknButton::TextColor |
|
4164 // Gets the correct text color. |
|
4165 // ----------------------------------------------------------------------------- |
|
4166 // |
|
4167 TRgb CAknButton::TextColor() const |
|
4168 { |
|
4169 TRgb color; |
|
4170 |
|
4171 if ( IsDimmed() ) |
|
4172 { |
|
4173 color = iEikonEnv->ControlColor( EColorButtonText, *this ); |
|
4174 color.SetAlpha( 77 ); |
|
4175 } |
|
4176 else if ( iButtonPressed ) |
|
4177 { |
|
4178 color = iEikonEnv->ControlColor( EColorButtonTextPressed, *this ); |
|
4179 } |
|
4180 else |
|
4181 { |
|
4182 color = iEikonEnv->ControlColor( EColorButtonText, *this ); |
|
4183 } |
|
4184 |
|
4185 return color; |
|
4186 } |
|
4187 |
|
4188 // ----------------------------------------------------------------------------- |
|
4189 // CAknButton::CreatePressedDownFrameL |
|
4190 // Generates a pressed down mask |
|
4191 // ----------------------------------------------------------------------------- |
|
4192 // |
|
4193 void CAknButton::CreatePressedDownFrameL() |
|
4194 { |
|
4195 |
|
4196 // Fetch frames from frame provider if one exists |
|
4197 if ( iExtension->FetchProviderPressedBmpsL() ) |
|
4198 { |
|
4199 return; |
|
4200 } |
|
4201 |
|
4202 if ( iExtension->iPressedDownBmp && |
|
4203 iExtension->iPressedDownBmp->SizeInPixels() == Size() ) |
|
4204 { |
|
4205 iExtension->SetProviderPressedBmpsL(); |
|
4206 return; |
|
4207 } |
|
4208 |
|
4209 iExtension->DeletePressedBmps(); |
|
4210 |
|
4211 // Fetch preffered display mode for icon type images |
|
4212 AknIconConfig::TPreferredDisplayMode displayMode; |
|
4213 AknIconConfig::PreferredDisplayMode( |
|
4214 displayMode, AknIconConfig::EImageTypeIcon ); |
|
4215 |
|
4216 iExtension->iPressedDownBmp = new ( ELeave ) CFbsBitmap; |
|
4217 User::LeaveIfError( iExtension->iPressedDownBmp->Create( Size(), |
|
4218 displayMode.iBitmapMode) ); |
|
4219 iExtension->iPressedDownBmpMask = new ( ELeave ) CFbsBitmap; |
|
4220 User::LeaveIfError( iExtension->iPressedDownBmpMask->Create( Size(), |
|
4221 displayMode.iMaskMode ) ); |
|
4222 |
|
4223 CFbsBitmapDevice* bmpDevice = CFbsBitmapDevice::NewL( |
|
4224 iExtension->iPressedDownBmp ); |
|
4225 CleanupStack::PushL( bmpDevice ); |
|
4226 |
|
4227 CFbsBitGc* bmpGc (NULL ); |
|
4228 User::LeaveIfError( bmpDevice->CreateContext( bmpGc ) ); |
|
4229 CleanupStack::PushL( bmpGc ); |
|
4230 |
|
4231 CFbsBitmapDevice* bmpMaskDevice = CFbsBitmapDevice::NewL( |
|
4232 iExtension->iPressedDownBmpMask ); |
|
4233 CleanupStack::PushL( bmpMaskDevice ); |
|
4234 |
|
4235 CFbsBitGc* bmpMaskGc( NULL ); |
|
4236 User::LeaveIfError( bmpMaskDevice->CreateContext( bmpMaskGc ) ); |
|
4237 CleanupStack::PushL( bmpMaskGc ); |
|
4238 |
|
4239 TRect rect ( Size() ); |
|
4240 TAknLayoutRect centerLayout; |
|
4241 centerLayout.LayoutRect( rect, |
|
4242 AknLayoutScalable_Avkon::toolbar_button_pane_g1().LayoutLine() ); |
|
4243 TRect innerRect( centerLayout.Rect() ); |
|
4244 |
|
4245 TAknWindowLineLayout unit = AknLayoutScalable_Avkon::aid_value_unit2().LayoutLine(); |
|
4246 innerRect.Shrink( unit.iW/10, unit.iH/10 ); |
|
4247 |
|
4248 AknsDrawUtils::DrawFrame( AknsUtils::SkinInstance(), |
|
4249 *bmpGc, rect, innerRect, |
|
4250 SkinIID( KPressedFrameId ), KAknsIIDDefault, |
|
4251 KAknsDrawParamRGBOnly ); |
|
4252 |
|
4253 AknsDrawUtils::DrawFrame( AknsUtils::SkinInstance(), |
|
4254 *bmpMaskGc, rect, innerRect, |
|
4255 SkinIID( KPressedFrameId ), KAknsIIDDefault, |
|
4256 KAknsSDMAlphaOnly ); |
|
4257 |
|
4258 // Modify mask 50% transparent |
|
4259 iExtension->iPressedDownBmpMask->LockHeap(); |
|
4260 |
|
4261 TInt w = iExtension->iPressedDownBmpMask->SizeInPixels().iWidth; |
|
4262 TInt h = iExtension->iPressedDownBmpMask->SizeInPixels().iHeight; |
|
4263 TInt dataStride = iExtension->iPressedDownBmpMask->DataStride() - w; |
|
4264 unsigned char* address = (unsigned char *)iExtension->iPressedDownBmpMask->DataAddress(); |
|
4265 |
|
4266 |
|
4267 for ( TInt i = 0; i < h; ++i ) |
|
4268 { |
|
4269 for ( TInt j = 0; j < w; ++j ) |
|
4270 { |
|
4271 *address >>= 1; |
|
4272 ++address; |
|
4273 } |
|
4274 address += dataStride; |
|
4275 } |
|
4276 |
|
4277 iExtension->iPressedDownBmpMask->UnlockHeap(); |
|
4278 |
|
4279 // Set created frames to frame provider if one exists |
|
4280 iExtension->SetProviderPressedBmpsL(); |
|
4281 |
|
4282 CleanupStack::PopAndDestroy( 4 ); // bmpDevice, bmpGc, bmpMaskDevice, bmpMaskGc |
|
4283 } |
|
4284 |
|
4285 |
|
4286 // ----------------------------------------------------------------------------- |
|
4287 // CAknButton::HideTooltipWhenAppFaded |
|
4288 // Sets tooltip to show or hide itself when background faded. By default tooltip |
|
4289 // is not shown when background faded. |
|
4290 // ----------------------------------------------------------------------------- |
|
4291 // |
|
4292 void CAknButton::HideTooltipWhenAppFaded( TBool aHide ) |
|
4293 { |
|
4294 if(iHelpNote) |
|
4295 { |
|
4296 iHelpNote->HideWhenAppFaded( aHide ); |
|
4297 } |
|
4298 } |
|
4299 |
|
4300 |
|
4301 // ----------------------------------------------------------------------------- |
|
4302 // CAknButton::CheckHitArea |
|
4303 // This checks hit area for fixed toolbar buttons. |
|
4304 // ----------------------------------------------------------------------------- |
|
4305 // |
|
4306 void CAknButton::CheckHitArea( ) |
|
4307 { |
|
4308 iExtension->iFlags.Set( CAknButtonExtension::ECheckHitArea ); |
|
4309 SetHitTest( iExtension ); |
|
4310 iExtension->HandleFeedbackAreaChange(); |
|
4311 } |
|
4312 |
|
4313 // ----------------------------------------------------------------------------- |
|
4314 // CAknButton::UseAdditionalMask |
|
4315 // Sets button to use additional masks during drawing. |
|
4316 // ----------------------------------------------------------------------------- |
|
4317 // |
|
4318 void CAknButton::UseMaskedDraw( TBool aMaskedDraw ) |
|
4319 { |
|
4320 if ( aMaskedDraw ) |
|
4321 { |
|
4322 iExtension->iFlags.Set( CAknButtonExtension:: EUseAdditionalMask ); |
|
4323 } |
|
4324 else |
|
4325 { |
|
4326 iExtension->iFlags.Clear( CAknButtonExtension:: EUseAdditionalMask ); |
|
4327 } |
|
4328 } |
|
4329 |
|
4330 |
|
4331 // ----------------------------------------------------------------------------- |
|
4332 // Registers resource provider. |
|
4333 // ----------------------------------------------------------------------------- |
|
4334 // |
|
4335 void CAknButton::RegisterResourceProvider( CAknResourceProvider* aProvider ) |
|
4336 { |
|
4337 iExtension->iResourceProvider = aProvider; |
|
4338 } |
|
4339 |
|
4340 |
|
4341 // ----------------------------------------------------------------------------- |
|
4342 // Unregisters resource provider. |
|
4343 // ----------------------------------------------------------------------------- |
|
4344 // |
|
4345 void CAknButton::UnregisterResourceProvider() |
|
4346 { |
|
4347 iExtension->iResourceProvider = 0; |
|
4348 } |
|
4349 |
|
4350 |
|
4351 CAknsFrameBackgroundControlContext* CAknButton::BgContext() |
|
4352 { |
|
4353 return iBgContext; |
|
4354 } |
|
4355 |
|
4356 |
|
4357 // ----------------------------------------------------------------------------- |
|
4358 // CAknButton::RemoveCurrentState |
|
4359 // Removes the current state. |
|
4360 // ----------------------------------------------------------------------------- |
|
4361 // |
|
4362 void CAknButton::RemoveCurrentState() |
|
4363 { |
|
4364 // Can't remove the state if it's the only one left. |
|
4365 if ( iStates->Count() > 1 ) |
|
4366 { |
|
4367 CAknButtonState* state = iStates->At( iStateIndex ); |
|
4368 delete state; |
|
4369 state = NULL; |
|
4370 iStates->Delete( iStateIndex ); |
|
4371 |
|
4372 iStateIndex <= 0 ? iStateIndex = 0 : iStateIndex--; |
|
4373 DrawNow(); |
|
4374 } |
|
4375 } |
|
4376 |
|
4377 |
|
4378 // ----------------------------------------------------------------------------- |
|
4379 // CAknButton::CalculateLuminance |
|
4380 // Calculates color's luminance value. |
|
4381 // ----------------------------------------------------------------------------- |
|
4382 // |
|
4383 TInt CAknButton::CalculateLuminance( const TRgb& aColor ) const |
|
4384 { |
|
4385 TInt R = aColor.Red(); |
|
4386 TInt G = aColor.Green(); |
|
4387 TInt B = aColor.Blue(); |
|
4388 // Should be scaled to 0-255? |
|
4389 TInt Y = (((66 * R) + (129 * G) + (25 * B) + 128) >> 8) + 16; |
|
4390 return Y; |
|
4391 } |
|
4392 |
|
4393 |
|
4394 // ----------------------------------------------------------------------------- |
|
4395 // CAknButton::ConvertColorsForOutlineEffect |
|
4396 // Converts the outline color to be white or black if the fill color is |
|
4397 // too similar to outline color. |
|
4398 // ----------------------------------------------------------------------------- |
|
4399 // |
|
4400 void CAknButton::ConvertColorsForOutlineEffect( TRgb& aFillColor, TRgb& aOutlineColor ) const |
|
4401 { |
|
4402 // @todo maybe there is already some conversion utility in multimedia image library? |
|
4403 TInt innerLum = CalculateLuminance(aFillColor); |
|
4404 TInt outerLum = CalculateLuminance(aOutlineColor); |
|
4405 |
|
4406 // if the defined colours are the same, then change the outline color so that |
|
4407 // it's either black or white, contrasting according to the font label text color's brightness |
|
4408 TInt difference = outerLum - innerLum; |
|
4409 difference = Abs(difference); |
|
4410 TInt half = (0xff / 2); // @todo figure out hlsMax somehow |
|
4411 TInt threshold = (0xff / 3); // @todo figure out hlsMax somehow, and decide on the threshold! |
|
4412 if(difference < threshold) |
|
4413 { |
|
4414 // if inner luminance is low, the outer luminance should be high, i.e. white |
|
4415 aOutlineColor = (innerLum < half) ? KRgbWhite : KRgbBlack; |
|
4416 } |
|
4417 } |
|
4418 |
|
4419 // ----------------------------------------------------------------------------- |
|
4420 // CAknButton::GetTextColors |
|
4421 // Gets correct text colors |
|
4422 // ----------------------------------------------------------------------------- |
|
4423 // |
|
4424 void CAknButton::GetTextColors( TRgb& aPenColor, TRgb& aBrushColor ) const |
|
4425 { |
|
4426 TBool outlineEffectOn = EFalse; |
|
4427 const CAknLayoutFont* layoutFont = CAknLayoutFont::AsCAknLayoutFontOrNull( iFont ); |
|
4428 if ( layoutFont ) |
|
4429 { |
|
4430 outlineEffectOn = layoutFont->FontSpecification().IsOutlineEffectOn(); |
|
4431 } |
|
4432 |
|
4433 if ( IsDimmed() ) |
|
4434 { |
|
4435 aPenColor = TextColor(); |
|
4436 aBrushColor = iEikonEnv->ControlColor( EColorControlDimmedBackground,*this ); |
|
4437 } |
|
4438 else |
|
4439 { |
|
4440 aPenColor = TextColor(); |
|
4441 aBrushColor = iEikonEnv->ControlColor( EColorControlBackground,*this ); |
|
4442 } |
|
4443 if ( outlineEffectOn ) |
|
4444 { |
|
4445 ConvertColorsForOutlineEffect( aBrushColor, aPenColor ); |
|
4446 } |
|
4447 } |
|
4448 |
|
4449 // ----------------------------------------------------------------------------- |
|
4450 // CAknButton::SetStateIndexL |
|
4451 // Sets new state index |
|
4452 // ----------------------------------------------------------------------------- |
|
4453 // |
|
4454 void CAknButton::SetStateIndexL( TInt aNewIndex ) |
|
4455 { |
|
4456 if ( iStateIndex != aNewIndex ) |
|
4457 { |
|
4458 iStateIndex = aNewIndex; |
|
4459 // Create new popup note controller every time state changes |
|
4460 // (text is not updated properly in help note if this is not done) |
|
4461 if ( iHelpNote ) |
|
4462 { |
|
4463 delete iHelpNote; |
|
4464 iHelpNote = 0; |
|
4465 } |
|
4466 iHelpNote = CAknInfoPopupNoteController::NewL(); |
|
4467 iHelpNote->SetTimeDelayBeforeShow( iHelpNoteWaitInterval ); |
|
4468 iHelpNote->SetTimePopupInView( iHelpNoteInViewInterval ); |
|
4469 iHelpNote->SetTooltipModeL( ETrue ); |
|
4470 } |
|
4471 } |
|
4472 |
|
4473 // ----------------------------------------------------------------------------- |
|
4474 // CAknButton::TouchArea |
|
4475 // Returns the button touchable area. |
|
4476 // ----------------------------------------------------------------------------- |
|
4477 // |
|
4478 TRect CAknButton::TouchArea() const |
|
4479 { |
|
4480 TRect touchRect( Rect() ); |
|
4481 if ( iExtension->iFlags.IsSet( CAknButtonExtension::ECheckHitArea ) ) |
|
4482 { |
|
4483 TAknLayoutRect layoutRect; |
|
4484 layoutRect.LayoutRect( Rect(), |
|
4485 AknLayoutScalable_Avkon::aid_touch_sctrl_middle( |
|
4486 !Layout_Meta_Data::IsLandscapeOrientation() ).LayoutLine() ); |
|
4487 touchRect = layoutRect.Rect(); |
|
4488 } |
|
4489 return touchRect; |
|
4490 } |
|
4491 // end of file |