|
1 /* |
|
2 * Copyright (c) 1997-1999 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: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include <coecntrl.h> |
|
20 #include <aknconsts.h> |
|
21 #include "aknscbut.h" |
|
22 #include "aknscind.h" |
|
23 #include <avkon.mbg> |
|
24 #include <eikenv.h> |
|
25 #include <AknsDrawUtils.h> |
|
26 #include <AknLayout.lag> |
|
27 #include <AknIconUtils.h> |
|
28 #include <AknUtils.h> |
|
29 #include <AknsUtils.h> |
|
30 #include <aknlayoutscalable_avkon.cdl.h> |
|
31 #include <aknappui.h> |
|
32 #include <gulicon.h> |
|
33 #include <AknsConstants.h> |
|
34 |
|
35 static const TInt KNoOfIndicatorColors = 17; |
|
36 static const TInt KMaxIndicatorIndex = KNoOfIndicatorColors - 1; |
|
37 static const TInt KNoOfGrayMaskColors = 256; |
|
38 static const TInt KMaxGrayMaskIndex = KNoOfGrayMaskColors - 1; |
|
39 static const TInt KMinGrayMaskIndex = 0; |
|
40 static const TInt KFullColor = 16; |
|
41 |
|
42 const TUint8 KIndicatorColors[KNoOfIndicatorColors] = |
|
43 { |
|
44 0, |
|
45 226, |
|
46 227, |
|
47 228, |
|
48 229, |
|
49 230, |
|
50 231, |
|
51 232, |
|
52 233, |
|
53 234, |
|
54 235, |
|
55 236, |
|
56 237, |
|
57 238, |
|
58 239, |
|
59 240, |
|
60 241 |
|
61 }; |
|
62 |
|
63 // |
|
64 // Local panics + routine |
|
65 // |
|
66 enum TEikPanicResourceScrollerIndicator |
|
67 { |
|
68 EEikPanicScrollbarScrollRangeLow, |
|
69 EEikPanicScrollbarIndicatorOutOfRangeLow, |
|
70 EEikPanicScrollbarIndicatorOutOfRangeHigh, |
|
71 EEikPanicScrollbarScrollSpanLow, |
|
72 EEikPanicScrollbarFocusPosOutOfRange |
|
73 }; |
|
74 |
|
75 #if defined(_DEBUG) |
|
76 LOCAL_C void Panic(TEikPanicResourceScrollerIndicator aPanic) |
|
77 { |
|
78 _LIT(KPanicCat,"AVKON-Scroll Indicator"); |
|
79 User::Panic(KPanicCat, aPanic); |
|
80 } |
|
81 #endif |
|
82 |
|
83 CAknScrollIndicator::CAknScrollIndicator(CAknScrollButton::TType aType) |
|
84 : iFocusPosition(0), iScrollSpan(1), iType(aType), iTypeOfScrollBar(CAknScrollButton::EArrowHead) |
|
85 { |
|
86 } |
|
87 |
|
88 CAknScrollIndicator* CAknScrollIndicator::NewL(CAknScrollButton::TType aType) |
|
89 { |
|
90 CAknScrollIndicator* self = new(ELeave) CAknScrollIndicator(aType); |
|
91 CleanupStack::PushL(self); |
|
92 self->ConstructL(); |
|
93 CleanupStack::Pop(); |
|
94 return self; |
|
95 } |
|
96 |
|
97 |
|
98 CAknScrollIndicator* CAknScrollIndicator::NewL(CAknScrollButton::TType aType, CAknScrollButton::TTypeOfScrollBar aTypeOfScrollBar) |
|
99 { |
|
100 CAknScrollIndicator* self = new(ELeave) CAknScrollIndicator(aType); |
|
101 CleanupStack::PushL(self); |
|
102 self->ConstructL(aTypeOfScrollBar); |
|
103 CleanupStack::Pop(); |
|
104 return self; |
|
105 } |
|
106 |
|
107 void CAknScrollIndicator::ConstructL(CAknScrollButton::TTypeOfScrollBar aTypeOfScrollBar) |
|
108 { |
|
109 iTypeOfScrollBar = aTypeOfScrollBar; |
|
110 ConstructL(); |
|
111 } |
|
112 |
|
113 void CAknScrollIndicator::ConstructL() |
|
114 { |
|
115 iIsWindowOwningScrollBar = EFalse; |
|
116 if( AknLayoutUtils::PenEnabled() && (iTypeOfScrollBar == CAknScrollButton::ENormal) ) |
|
117 { |
|
118 // TODO: Load bitmaps for double span scroll bar buttons when they become available |
|
119 // Get the correct sizes from LAF when the support for the buttons is available |
|
120 // Initalize the bitmap devices and graphics contexts correctly |
|
121 TInt err; |
|
122 TAknsItemID indicator; |
|
123 TAknWindowComponentLayout buttonLayout; |
|
124 TAknWindowComponentLayout scrollpaneLayout; |
|
125 |
|
126 switch( iType ) |
|
127 { |
|
128 case CAknScrollButton::ENudgeUp: |
|
129 buttonLayout = AknLayoutScalable_Avkon::scroll_sc2_up_pane( 1 ); |
|
130 indicator = KAknsIIDQgnGrafScrollArrowUp; |
|
131 scrollpaneLayout = AknLayoutScalable_Avkon::scroll_pane(); |
|
132 break; |
|
133 case CAknScrollButton::ENudgeDown: |
|
134 buttonLayout = AknLayoutScalable_Avkon::scroll_sc2_down_pane( 1 ); |
|
135 indicator = KAknsIIDQgnGrafScrollArrowDown; |
|
136 scrollpaneLayout = AknLayoutScalable_Avkon::scroll_pane(); |
|
137 break; |
|
138 case CAknScrollButton::ENudgeLeft: |
|
139 buttonLayout = AknLayoutScalable_Avkon::scroll_sc2_left_pane(); |
|
140 indicator = KAknsIIDQgnGrafScrollArrowLeft; |
|
141 scrollpaneLayout = AknLayoutScalable_Avkon::scroll_pane(1); |
|
142 break; |
|
143 case CAknScrollButton::ENudgeRight: |
|
144 buttonLayout = AknLayoutScalable_Avkon::scroll_sc2_right_pane(); |
|
145 indicator = KAknsIIDQgnGrafScrollArrowRight; |
|
146 scrollpaneLayout = AknLayoutScalable_Avkon::scroll_pane(1); |
|
147 break; |
|
148 default: |
|
149 return; |
|
150 } |
|
151 |
|
152 TAknLayoutRect scrollpaneLayoutRect, buttonLayoutRect; |
|
153 |
|
154 // Using mainpanerect only for counting the size of button bitmap |
|
155 TRect mainpaneRect; |
|
156 AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EMainPane, mainpaneRect ); |
|
157 scrollpaneLayoutRect.LayoutRect( mainpaneRect, scrollpaneLayout.LayoutLine() ); |
|
158 buttonLayoutRect.LayoutRect( scrollpaneLayoutRect.Rect(), buttonLayout.LayoutLine() ); |
|
159 |
|
160 // trapping possible leave in this phase when there's no bitmaps in other skins |
|
161 |
|
162 TRAP( err, iIcon = AknsUtils::CreateGulIconL( AknsUtils::SkinInstance(), |
|
163 indicator, EFalse ) ); |
|
164 |
|
165 if( err == KErrNone ) |
|
166 { |
|
167 AknIconUtils::SetSize( iIcon->Bitmap(), buttonLayoutRect.Rect().Size() ); |
|
168 AknIconUtils::SetSize( iIcon->Mask(), buttonLayoutRect.Rect().Size() ); |
|
169 } |
|
170 } |
|
171 else |
|
172 { |
|
173 TInt indicator; |
|
174 TSize indiSize; |
|
175 |
|
176 |
|
177 // screen |
|
178 TRect screenRect = iAvkonAppUi->ApplicationRect(); |
|
179 |
|
180 //TAknWindowLineLayout screenLayout = AknLayout::screen(); |
|
181 //TRect screenRect = screenLayout.Rect(); |
|
182 |
|
183 // app window |
|
184 TAknWindowLineLayout applicationWindowLayout = |
|
185 AknLayout::application_window(screenRect); |
|
186 |
|
187 TAknLayoutRect applicationWindowLayoutRect; |
|
188 applicationWindowLayoutRect.LayoutRect(screenRect, applicationWindowLayout); |
|
189 TRect applicationWindowRect = applicationWindowLayoutRect.Rect(); |
|
190 |
|
191 // control pane |
|
192 TAknWindowLineLayout controlPaneLayout = |
|
193 AknLayout::control_pane(applicationWindowRect); |
|
194 |
|
195 TAknLayoutRect controlPaneLayoutRect; |
|
196 controlPaneLayoutRect.LayoutRect(applicationWindowRect, controlPaneLayout); |
|
197 TRect controlPaneRect = controlPaneLayoutRect.Rect(); |
|
198 |
|
199 |
|
200 if (iType == CAknScrollButton::ENudgeUp) |
|
201 { |
|
202 // scroll up |
|
203 TAknWindowLineLayout scrollLayout = |
|
204 AknLayout::Control_pane_elements_Line_1(); |
|
205 TAknLayoutRect scrollLayoutRect; |
|
206 scrollLayoutRect.LayoutRect(controlPaneRect, scrollLayout); |
|
207 TRect scrollRect = scrollLayoutRect.Rect(); |
|
208 |
|
209 indicator=EMbmAvkonQgn_indi_scroll_a; |
|
210 indiSize = scrollRect.Size(); |
|
211 } |
|
212 else |
|
213 { |
|
214 // scroll down |
|
215 TAknWindowLineLayout scrollLayout = |
|
216 AknLayout::Control_pane_elements_Line_2(); |
|
217 TAknLayoutRect scrollLayoutRect; |
|
218 scrollLayoutRect.LayoutRect(controlPaneRect, scrollLayout); |
|
219 TRect scrollRect = scrollLayoutRect.Rect(); |
|
220 |
|
221 indicator=EMbmAvkonQgn_indi_scroll_b; |
|
222 indiSize = scrollRect.Size(); |
|
223 } |
|
224 |
|
225 // iBitmap = new (ELeave) CFbsBitmap(); |
|
226 // User::LeaveIfError(iBitmap->Load(KAvkonBitmapFile, |
|
227 // indicator,ETrue)); |
|
228 |
|
229 // iBitmap = AknIconUtils::CreateIconL(KAvkonBitmapFile, indicator); |
|
230 |
|
231 iBitmap = new (ELeave) CEikImage(); |
|
232 CFbsBitmap* mask = NULL; |
|
233 CFbsBitmap* bitmap = NULL; |
|
234 |
|
235 // Use bitmap id for both mask and bitmap because of 1-bit icons. |
|
236 AknIconUtils::CreateIconL( |
|
237 bitmap, mask, KAvkonBitmapFile, indicator, indicator ); |
|
238 AknIconUtils::SetSize(bitmap,indiSize); |
|
239 // Also note that in the drawing time mask is used as bitmap. We store the bitmap |
|
240 // only because AknIconUtils requires to do so. |
|
241 iBitmap->SetBitmap(bitmap); |
|
242 iBitmap->SetMask(mask); |
|
243 |
|
244 iColorBitmap = new (ELeave) CFbsBitmap(); |
|
245 User::LeaveIfError( iColorBitmap->Create( bitmap->SizeInPixels(), |
|
246 iEikonEnv->ScreenDevice()->DisplayMode() ) ); |
|
247 iColorBmpDev = CFbsBitmapDevice::NewL( iColorBitmap ); |
|
248 // User::LeaveIfError( iColorBmpDev->Resize( bitmap->SizeInPixels())); |
|
249 iColorBmpGc = CFbsBitGc::NewL(); |
|
250 iColorBmpGc->Activate( iColorBmpDev ); |
|
251 |
|
252 iMaskBitmap = new (ELeave) CFbsBitmap(); |
|
253 //8-bit bitmap |
|
254 User::LeaveIfError( iMaskBitmap->Create( bitmap->SizeInPixels(), |
|
255 EGray256 )); |
|
256 iMaskBmpDev = CFbsBitmapDevice::NewL( iMaskBitmap ); |
|
257 // User::LeaveIfError( iMaskBmpDev->Resize( bitmap->SizeInPixels())); |
|
258 iMaskBmpGc = CFbsBitGc::NewL(); |
|
259 iMaskBmpGc->Activate( iMaskBmpDev ); |
|
260 } |
|
261 } |
|
262 |
|
263 CAknScrollIndicator::~CAknScrollIndicator() |
|
264 { |
|
265 delete iBitmap; |
|
266 delete iColorBitmap; |
|
267 delete iColorBmpDev; |
|
268 delete iColorBmpGc; |
|
269 delete iMaskBmpGc; |
|
270 delete iMaskBmpDev; |
|
271 delete iMaskBitmap; |
|
272 delete iIcon; |
|
273 |
|
274 |
|
275 } |
|
276 |
|
277 |
|
278 /** |
|
279 * Main method. Calculates the index of the appropriate scroller |
|
280 * indicator bitmap color and draws it. |
|
281 * |
|
282 * Alternatively draws a transparent indicator using 8-bit |
|
283 * greyscale mask. |
|
284 */ |
|
285 void CAknScrollIndicator::DrawScrollIndicator(const TRect& aRect) |
|
286 { |
|
287 if( AknLayoutUtils::PenEnabled() && (iTypeOfScrollBar == CAknScrollButton::ENormal) ) |
|
288 { |
|
289 CWindowGc& gc = SystemGc(); |
|
290 |
|
291 MAknsSkinInstance* skin = AknsUtils::SkinInstance(); |
|
292 MAknsControlContext* cc = AknsDrawUtils::ControlContext( this ); |
|
293 |
|
294 if ( iIsWindowOwningScrollBar ) |
|
295 { |
|
296 TRect rect( Window().Position() + aRect.iTl, aRect.Size() ); |
|
297 AknsDrawUtils::DrawBackground( skin, cc, NULL, gc, aRect.iTl, rect , KAknsDrawParamNoClearUnderImage ); |
|
298 } |
|
299 else |
|
300 { |
|
301 AknsDrawUtils::Background( skin, cc, this, gc, aRect, KAknsDrawParamNoClearUnderImage ); |
|
302 } |
|
303 |
|
304 if( iIcon ) |
|
305 { |
|
306 gc.BitBltMasked( aRect.iTl, iIcon->Bitmap(), aRect.Size(), iIcon->Mask(), ETrue ); |
|
307 } |
|
308 } |
|
309 else |
|
310 { |
|
311 |
|
312 if (Size().iWidth) // only draw bitmaps if the button has some size to it |
|
313 { |
|
314 CWindowGc& gc=SystemGc(); // graphics context we draw to |
|
315 TInt indicator( 0 ); // which indicator color to draw |
|
316 TInt grayIndicator( KMinGrayMaskIndex ); |
|
317 |
|
318 // if focus position is at the lower limit the color is the 0th... |
|
319 if (iFocusPosition <= 0) {}// do nothing |
|
320 // at the upper limit it is the MAXth... |
|
321 else if (iFocusPosition >= iScrollSpan-1) |
|
322 { |
|
323 indicator = KMaxIndicatorIndex; |
|
324 grayIndicator = KMaxGrayMaskIndex; |
|
325 } |
|
326 // ...all other indicator colors are spread evenly between |
|
327 // all other focus positions... |
|
328 else |
|
329 { |
|
330 // all indicators minus top & bottom |
|
331 TInt variableIndicatorRange( KNoOfIndicatorColors-2 ); |
|
332 TInt maxVariableIndex( iScrollSpan-1 ); |
|
333 // Calculate the indicator value... |
|
334 indicator=((iFocusPosition*variableIndicatorRange)+ |
|
335 (maxVariableIndex-1))/maxVariableIndex; |
|
336 |
|
337 grayIndicator = KMaxGrayMaskIndex - |
|
338 ( maxVariableIndex - iFocusPosition ) * |
|
339 ( KMaxGrayMaskIndex - KMinGrayMaskIndex ) / |
|
340 maxVariableIndex; |
|
341 } |
|
342 // Sanity checks... |
|
343 __ASSERT_DEBUG(indicator>=0, |
|
344 Panic( EEikPanicScrollbarIndicatorOutOfRangeLow)); |
|
345 __ASSERT_DEBUG(indicator<=KMaxIndicatorIndex, |
|
346 Panic(EEikPanicScrollbarIndicatorOutOfRangeHigh)); |
|
347 __ASSERT_DEBUG(grayIndicator>=0, |
|
348 Panic( EEikPanicScrollbarIndicatorOutOfRangeLow)); |
|
349 __ASSERT_DEBUG(grayIndicator<=KMaxGrayMaskIndex, |
|
350 Panic(EEikPanicScrollbarIndicatorOutOfRangeHigh)); |
|
351 |
|
352 // reverse the colors for down buttons |
|
353 if ( iType == CAknScrollButton::ENudgeDown ) |
|
354 { |
|
355 indicator = KMaxIndicatorIndex - indicator; |
|
356 grayIndicator = KMaxGrayMaskIndex - grayIndicator; |
|
357 } |
|
358 MAknsSkinInstance* skin = AknsUtils::SkinInstance(); |
|
359 MAknsControlContext* cc = AknsDrawUtils::ControlContext( this ); |
|
360 |
|
361 AknsDrawUtils::Background( skin, cc, this, gc, aRect ); |
|
362 |
|
363 if( indicator ) |
|
364 { |
|
365 CFbsBitmap* mask = NULL; |
|
366 if (iType == CAknScrollButton::ENudgeUp) |
|
367 { |
|
368 mask = AknsUtils::GetCachedBitmap( skin, KAknsIIDQgnIndiScrollUpMask ); |
|
369 if ( mask ) |
|
370 { |
|
371 AknIconUtils::SetSize( mask, aRect.Size() ); |
|
372 } |
|
373 } |
|
374 else |
|
375 { |
|
376 mask = AknsUtils::GetCachedBitmap( skin, KAknsIIDQgnIndiScrollDownMask ); |
|
377 if ( mask ) |
|
378 { |
|
379 AknIconUtils::SetSize( mask, aRect.Size() ); |
|
380 } |
|
381 } |
|
382 |
|
383 |
|
384 const CFbsBitmap* blitMask = mask; |
|
385 if( !blitMask ) |
|
386 { |
|
387 blitMask = iBitmap->Mask(); |
|
388 } |
|
389 |
|
390 |
|
391 TRgb color( AKN_LAF_COLOR( KIndicatorColors[indicator] ) ); |
|
392 |
|
393 TInt err( AknsUtils::GetCachedColor( skin, color, KAknsIIDQsnScrollColors, KFullColor ) ); |
|
394 |
|
395 const TRect bmpRect( TPoint( 0,0 ), aRect.Size() ); |
|
396 |
|
397 iColorBmpGc->SetPenStyle( CGraphicsContext::ENullPen ); |
|
398 iColorBmpGc->SetBrushStyle( CGraphicsContext::ESolidBrush ); |
|
399 |
|
400 if ( err == KErrNone ) |
|
401 { |
|
402 TRgb gray( 0,0,0 ); |
|
403 //mask bitmap with right gray color |
|
404 iMaskBmpGc->SetPenStyle( CGraphicsContext::ENullPen ); |
|
405 iMaskBmpGc->SetBrushStyle( CGraphicsContext::ESolidBrush ); |
|
406 iMaskBmpGc->SetBrushColor( gray.Gray256( grayIndicator ) ); |
|
407 iMaskBmpGc->DrawRect( bmpRect ); |
|
408 |
|
409 //bitmap temporarily filled with black |
|
410 iColorBmpGc->SetBrushColor( TRgb( 0, 0, 0 ) ); |
|
411 iColorBmpGc->DrawRect( bmpRect ); |
|
412 |
|
413 //create the mask with gray colored shape |
|
414 iMaskBmpGc->SetBrushStyle( CGraphicsContext::ENullBrush ); |
|
415 iMaskBmpGc->BitBltMasked( aRect.iTl, iColorBitmap, |
|
416 bmpRect, blitMask, EFalse ); |
|
417 |
|
418 //set the skin color |
|
419 iColorBmpGc->SetBrushColor( color ); |
|
420 iColorBmpGc->DrawRect( bmpRect ); |
|
421 |
|
422 //blit to screen with transparent color |
|
423 gc.SetBrushStyle( CGraphicsContext::ENullBrush ); |
|
424 gc.BitBltMasked( aRect.iTl, iColorBitmap, |
|
425 bmpRect, iMaskBitmap, ETrue ); |
|
426 } |
|
427 else |
|
428 { |
|
429 iColorBmpGc->SetBrushColor( color ); |
|
430 iColorBmpGc->DrawRect( bmpRect ); |
|
431 |
|
432 //draw default color |
|
433 gc.BitBltMasked( aRect.iTl, iColorBitmap, bmpRect, |
|
434 blitMask, ETrue ); |
|
435 } |
|
436 } |
|
437 } |
|
438 } //end of else |
|
439 } |
|
440 |
|
441 |
|
442 |
|
443 void CAknScrollIndicator::SetPosition(const TInt aFocusPosition, const TInt aScrollSpan) |
|
444 /** |
|
445 / Sets the new focus position in the list and the list length. |
|
446 */ |
|
447 { |
|
448 // check parameters valid |
|
449 // scrollspan can now be zero and focusposition -1 for empty lists. |
|
450 __ASSERT_DEBUG(aScrollSpan>=0,Panic(EEikPanicScrollbarScrollSpanLow)); |
|
451 __ASSERT_DEBUG((aFocusPosition>=-1) && (aFocusPosition<=aScrollSpan),Panic(EEikPanicScrollbarFocusPosOutOfRange)); |
|
452 |
|
453 iFocusPosition = aFocusPosition; |
|
454 iScrollSpan = aScrollSpan; |
|
455 } |
|
456 void CAknScrollIndicator::SetWindowOwning( const TBool aBool ) |
|
457 { |
|
458 iIsWindowOwningScrollBar = aBool; |
|
459 } |
|
460 |
|
461 |