uifw/EikStd/coctlsrc/EIKSCRLB.CPP
changeset 0 2f259fa3e83a
child 4 8ca85d2f0db7
child 14 3320e4e6e8bb
equal deleted inserted replaced
-1:000000000000 0:2f259fa3e83a
       
     1 /*
       
     2 * Copyright (c) 1997-2006 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
       
    20 #include <uikon/eikdefmacros.h>
       
    21 #endif
       
    22 #include <eikscrlb.h>
       
    23 #include <eikpanic.h>
       
    24 #include <eikcoctlpanic.h>
       
    25 #include <eikenv.h>
       
    26 #include <AknLayout.lag>
       
    27 #include <eikcba.h>
       
    28 #include <AknsDrawUtils.h>
       
    29 #include <AknUtils.h>
       
    30 #include <aknappui.h>
       
    31 #include <AknsUtils.h>
       
    32 #include <AknLayout2ScalableDef.h>
       
    33 #include <aknlayoutscalable_avkon.cdl.h>
       
    34 #include <AknInfoPopupNoteController.h>
       
    35 #include <aknpointereventmodifier.h>
       
    36 #include <AknTasHook.h>
       
    37 #include <touchfeedback.h>
       
    38 
       
    39 
       
    40 #include "AknDoubleSpanScrollIndicator.h"
       
    41 #include "eikscrlb.h"
       
    42 #include "EIKSBEXT.H"
       
    43 
       
    44 const TInt KIntensity = 50; // 50%
       
    45 
       
    46 const TInt KScrollBarWidth=9;
       
    47 // const TInt KScrollButtonHeight=10;
       
    48 // const TInt KArrowHeadScrollBarLength=20;
       
    49 
       
    50 // Constants for double span scrollbar
       
    51 const TInt KAknDoubleSpanScrollBarWidth = 6;
       
    52 const TInt KDoubleSpanMaxModelValue     = 0x1FFF7FFF;
       
    53 const TInt KDoubleSpanMinModelValue     = -0x1FFF7FFF;
       
    54 const TInt16 KDoubleSpanMaxScaleValue   = 0x3FFF;
       
    55 const TInt16 KDoubleSpanMinScaleValue   = 1;
       
    56 const TInt KDoubleSpanMaxRawValue       = 0x8000;
       
    57 
       
    58 // Mask values for double span scrollbar
       
    59 const TUint KDoubleSpanModelMaskBitsHigh       = 0xFFFF0000;
       
    60 const TUint KDoubleSpanModelMaskBitsLow        = 0x0000FFFF;
       
    61 const TUint KDoubleSpanModelMaskBitsScale      = 0x3FFF0000;
       
    62 const TUint KDoubleSpanModelMaskBitsType       = 0x3FFFFFFF;
       
    63 const TUint16 KDoubleSpanModelMaskBitsScale16 = 0x3FFF;
       
    64 
       
    65 const TInt KScrollRepeatTimeout = 250000; // 0.25 seconds
       
    66 const TInt KScrollDragTimeout =    66000; // 0.66 seconds means 16 fps
       
    67 
       
    68 EXPORT_C TBool TEikScrollBarModel::operator==(const TEikScrollBarModel aModel) const
       
    69     {
       
    70     return ((iScrollSpan==aModel.iScrollSpan)&(iThumbSpan==aModel.iThumbSpan)&(iThumbPosition==aModel.iThumbPosition));
       
    71     }
       
    72 
       
    73 EXPORT_C TEikScrollBarModel::TEikScrollBarModel(TInt aScrollSpan,TInt aThumbSpan,TInt aThumbPosition)
       
    74     : iScrollSpan(aScrollSpan),
       
    75     iThumbSpan(aThumbSpan),
       
    76     iThumbPosition(aThumbPosition)
       
    77     {}
       
    78 
       
    79 EXPORT_C TBool TEikScrollBarModel::ScrollBarUseful() const
       
    80     {
       
    81     return iThumbSpan<iScrollSpan;
       
    82     }
       
    83 
       
    84 EXPORT_C TInt TEikScrollBarModel::MaxThumbPos() const
       
    85     {
       
    86     return iScrollSpan-iThumbSpan;
       
    87     }
       
    88 
       
    89 EXPORT_C void TEikScrollBarModel::CheckBounds()
       
    90 // Ensure the thumbposition remains within it's valid range
       
    91     {
       
    92     iThumbPosition=Max(0,Min(iThumbPosition,iScrollSpan-1));
       
    93     }
       
    94 
       
    95 TEikScrollBarModel::TEikScrollBarModelType TEikScrollBarModel::ScrollBarModelType() const
       
    96     {
       
    97     TUint type = (~KDoubleSpanModelMaskBitsType) & iScrollSpan;
       
    98     if (type == EAknDoubleSpanScrollBarModel)
       
    99         {
       
   100         return EAknDoubleSpanScrollBarModel;
       
   101         }
       
   102     else
       
   103         {
       
   104         return EEikScrollBarModel;
       
   105         }
       
   106     }
       
   107 
       
   108 //
       
   109 // CEikScrollBar class
       
   110 //
       
   111 
       
   112 EXPORT_C CEikScrollBar::~CEikScrollBar()
       
   113 // Destructor
       
   114     {
       
   115     AKNTASHOOK_REMOVE();
       
   116     DisconnectExternalFrames();
       
   117     delete(iButtons.iIncreaseNudge);
       
   118     delete(iButtons.iDecreaseNudge);
       
   119     delete iExtension;
       
   120     }
       
   121 
       
   122 EXPORT_C CEikScrollBar::CEikScrollBar()
       
   123 // Default constructor
       
   124     {
       
   125     SetNonFocusing();
       
   126     SetComponentsToInheritVisibility();
       
   127     AKNTASHOOK_ADD( this, "CEikScrollBar" );
       
   128     }
       
   129 
       
   130 EXPORT_C void CEikScrollBar::ConstructL(MEikScrollBarObserver* aScrollBarObserver,const CCoeControl* aParent,
       
   131                                         TOrientation aOrientation,TInt /*aLength*/,TInt /*aScrollBarFlags*/)
       
   132 // Second-phase construction
       
   133     {
       
   134     // If extension has not been created by deriving class, create default extension.
       
   135     if (!iExtension)
       
   136         {
       
   137         iExtension = new(ELeave) CEikScrollBarExtension(this);
       
   138         }
       
   139 
       
   140     if(AknLayoutUtils::PenEnabled())
       
   141         {
       
   142         CEikScrollBarExtension* extension = static_cast<CEikScrollBarExtension*> (iExtension);
       
   143         extension->SetScrollBarObserver(aScrollBarObserver);
       
   144         }
       
   145 
       
   146     CreateWindowL(aParent);
       
   147 
       
   148     if(aParent)
       
   149         SetObserver(aParent->Observer());
       
   150     else
       
   151         SetObserver(NULL);
       
   152 
       
   153     iOrientation=aOrientation;
       
   154     // Fix scrollbar frame's position to middle of cba
       
   155     CreateRequiredComponentsL();
       
   156     Window().SetPointerGrab(ETrue);
       
   157     EnableDragEvents();
       
   158     MakeVisible(EFalse);
       
   159     ActivateL();
       
   160     }
       
   161 
       
   162 EXPORT_C TInt CEikScrollBar::CountComponentControls() const
       
   163     {
       
   164     TInt controlCount = 0;
       
   165     if(iButtons.iIncreaseNudge)
       
   166         {
       
   167         controlCount++;
       
   168         }
       
   169     if(iButtons.iDecreaseNudge)
       
   170         {
       
   171         controlCount++;
       
   172         }
       
   173     return controlCount;
       
   174     }
       
   175 
       
   176 EXPORT_C CCoeControl* CEikScrollBar::ComponentControl(TInt aIndex) const
       
   177     {
       
   178     if (aIndex==0)
       
   179         return iButtons.iIncreaseNudge;
       
   180     else
       
   181         return iButtons.iDecreaseNudge;
       
   182     }
       
   183 
       
   184 EXPORT_C void CEikScrollBar::SetLengthL(TInt /*aLength*/)
       
   185 // Change the scrollbar's length.  Will redraw
       
   186     {
       
   187     }
       
   188 
       
   189 EXPORT_C void CEikScrollBar::SetModelL(const TEikScrollBarModel* aModel)
       
   190     {
       
   191     SetModel(aModel);
       
   192     }
       
   193 
       
   194 EXPORT_C void CEikScrollBar::SetModel(const TEikScrollBarModel* aModel)
       
   195 // Change the scrollbar model
       
   196     {
       
   197     if (*aModel==iModel)
       
   198         return;
       
   199     DoSetModel(aModel);
       
   200     }
       
   201 
       
   202 EXPORT_C void CEikScrollBar::SetLengthAndModelL(TInt /*aLength*/,const TEikScrollBarModel* aModel)
       
   203 // Change the length and model at once to avoid a double update of the scrollbar
       
   204     {
       
   205     SetModel(aModel);
       
   206     }
       
   207 
       
   208 EXPORT_C void CEikScrollBar::SetModelThumbPosition(TInt /*aThumbPos*/)
       
   209     {
       
   210     }
       
   211 
       
   212 EXPORT_C void CEikScrollBar::SetFocusPosToThumbPos(TInt /*aFocusPosition*/)
       
   213     {
       
   214     }
       
   215 
       
   216 EXPORT_C TInt CEikScrollBar::ThumbPosition() const
       
   217 // Retrun the model's thumb position (eg in response to a scroll event)
       
   218     {
       
   219     if (iExtension)
       
   220         {
       
   221         return iExtension->ThumbPosition();
       
   222         }
       
   223     else
       
   224         {
       
   225         return 0;
       
   226         }
       
   227     }
       
   228 
       
   229 EXPORT_C TInt CEikScrollBar::ScrollBarBreadth() const
       
   230 // returns the height of a horizontal scrollbar or width of a vertical scrollbar
       
   231     {
       
   232     if (iExtension)
       
   233         {
       
   234         return iExtension->ScrollBarBreadth();
       
   235         }
       
   236     else
       
   237         {
       
   238         return 0;
       
   239         }
       
   240     }
       
   241 
       
   242 EXPORT_C TInt CEikScrollBar::MinVisibleLength(const TInt /*aScrollBarFlags*/)
       
   243 // STATIC - Calculates the minimum length in which scrollbar will remain "visible" (not necessarily with all it's components though)
       
   244     {
       
   245     return 0;
       
   246     }
       
   247 
       
   248 EXPORT_C void CEikScrollBar::SetDecreaseButtonsDimmed(TBool /*aDimmed*/)
       
   249 // Dim out the decrease buttons
       
   250     {
       
   251     }
       
   252 
       
   253 EXPORT_C void CEikScrollBar::SetIncreaseButtonsDimmed(TBool /*aDimmed*/)
       
   254 // Dim out the increase buttons
       
   255     {
       
   256     }
       
   257 
       
   258 EXPORT_C void CEikScrollBar::SetAllButtonsDimmed(TBool /*aDimmed*/)
       
   259 // Dim out all buttons
       
   260     {
       
   261     }
       
   262 
       
   263 void CEikScrollBar::CreateRequiredComponentsL()
       
   264 // Allocates and constructs all the required components of the scrollbar
       
   265     {
       
   266     if (iExtension)
       
   267         {
       
   268         iExtension->CreateRequiredComponentsL();
       
   269         }
       
   270     }
       
   271 
       
   272 EXPORT_C void CEikScrollBar::CreateButtonL(CAknScrollButton*& /*aButton*/,CAknScrollButton::TType /*aType*/)
       
   273 // Create the appropriate button
       
   274     {
       
   275     }
       
   276 
       
   277 void CEikScrollBar::DestroyButton(CAknScrollButton*& aButton)
       
   278 // destroy a button
       
   279     {
       
   280     delete aButton;
       
   281     aButton=NULL;
       
   282     }
       
   283 
       
   284 EXPORT_C void CEikScrollBar::SetButtonPositionL(CAknScrollButton* /*aButton*/)
       
   285 // Calculates and sets a buttons position,making necessary adjustments for densely packed buttons
       
   286     {
       
   287     }
       
   288 
       
   289 void CEikScrollBar::DoSetModel(const TEikScrollBarModel* aModel)
       
   290 // Just change the internal model checking it's valid
       
   291     {
       
   292     if (iExtension)
       
   293         {
       
   294         iExtension->DoSetModel(aModel);
       
   295         }
       
   296     }
       
   297 
       
   298 void CEikScrollBar::SizeChanged()
       
   299     {
       
   300     // Update position of components
       
   301     if (iButtons.iIncreaseNudge)
       
   302         {
       
   303         TRAP_IGNORE(SetButtonPositionL(iButtons.iIncreaseNudge));
       
   304         }
       
   305     if (iButtons.iDecreaseNudge)
       
   306         {
       
   307         TRAP_IGNORE(SetButtonPositionL(iButtons.iDecreaseNudge));
       
   308         }
       
   309     }
       
   310 
       
   311 EXPORT_C TInt CEikScrollBar::DefaultScrollBarBreadth()
       
   312     {
       
   313     return KScrollBarWidth;
       
   314     }
       
   315 
       
   316 EXPORT_C void CEikScrollBar::HandleControlEventL(CCoeControl* /*aControl*/, TCoeEvent /*aEventType*/)
       
   317     {
       
   318     }
       
   319 
       
   320 EXPORT_C void CEikScrollBar::HandlePointerEventL(const TPointerEvent& aPointerEvent)
       
   321     {
       
   322     CEikBorderedControl::HandlePointerEventL(aPointerEvent);
       
   323     }
       
   324 
       
   325 EXPORT_C void CEikScrollBar::SetExtensionAreaType(TScrollBarExtensionAreaType aType)
       
   326     {
       
   327     if(ScrollBarType() == CEikScrollBar::EDoubleSpan)
       
   328         {
       
   329         CAknDoubleSpanScrollBarExtension* extension = static_cast<CAknDoubleSpanScrollBarExtension*> (iExtension);
       
   330         extension->iExtensionType = aType;
       
   331         }
       
   332     }
       
   333 
       
   334 EXPORT_C void* CEikScrollBar::ExtensionInterface( TUid /*aInterface*/ )
       
   335     {
       
   336     return NULL;
       
   337     }
       
   338 
       
   339 EXPORT_C void CEikScrollBar::Reserved_2()
       
   340     {
       
   341     }
       
   342 
       
   343 EXPORT_C void CEikScrollBar::MakeVisible(TBool aVisible)
       
   344     {
       
   345     if (COMPARE_BOOLS(aVisible, IsVisible()))
       
   346         return;
       
   347 
       
   348     TAknWindowLineLayout lay(AKN_LAYOUT_WINDOW_Control_pane_elements_Line_1);
       
   349     TAknLayoutRect lr;
       
   350     lr.LayoutRect( Rect(), lay );
       
   351     TRect r( lr.Rect() );
       
   352     SetExtent( r.iTl, TSize( aVisible ? r.Width() : 0, 2 * r.Height() ) );
       
   353 
       
   354     // Arrow head scroll bar will not be displayed
       
   355     if ( iExtension->ScrollBarType() == CEikScrollBar::EArrowHead )
       
   356         {
       
   357         CCoeControl::MakeVisible( EFalse );
       
   358         }
       
   359     else
       
   360         {
       
   361         CCoeControl::MakeVisible( aVisible );
       
   362         }
       
   363 
       
   364 
       
   365     if (Cba())
       
   366         {
       
   367         Cba()->UpdateCbaLabels( aVisible );
       
   368         }
       
   369     }
       
   370 
       
   371 EXPORT_C void CEikScrollBar::SetContainingCba(CEikCba* aCba)
       
   372     {
       
   373     // This is technically a compatability break, because it means that SetContainingCba
       
   374     // must only be called after ConstructL(). Fortunately, the only place where this API
       
   375     // should ever be called is already correct.
       
   376     __ASSERT_ALWAYS(iExtension, Panic(EEikPanicScrollBarExtensionNotCreated));
       
   377     iExtension->SetContainingCba(aCba);
       
   378     }
       
   379 
       
   380 CEikCba* CEikScrollBar::Cba() const
       
   381     {
       
   382     if (iExtension)
       
   383         return iExtension->Cba();
       
   384     else
       
   385         return NULL;
       
   386     }
       
   387 
       
   388 void CEikScrollBar::AddExternalFrameL(CEikScrollBarFrame* aFrame)
       
   389     {
       
   390     __ASSERT_ALWAYS(iExtension, Panic(EEikPanicScrollBarExtensionNotCreated));
       
   391     iExtension->AddExternalFrameL(aFrame);
       
   392     }
       
   393 
       
   394 void CEikScrollBar::RemoveExternalFrame(CEikScrollBarFrame* aFrame)
       
   395     {
       
   396     __ASSERT_ALWAYS(iExtension, Panic(EEikPanicScrollBarExtensionNotCreated));
       
   397     iExtension->RemoveExternalFrame(aFrame);
       
   398     }
       
   399 
       
   400 void CEikScrollBar::DisconnectExternalFrames()
       
   401     {
       
   402     if (iExtension)
       
   403         {
       
   404         iExtension->DisconnectExternalFrames();
       
   405         }
       
   406     }
       
   407 
       
   408 CEikScrollBar::TScrollBarType CEikScrollBar::ScrollBarType()
       
   409     {
       
   410     if (iExtension)
       
   411         {
       
   412         return static_cast<CEikScrollBar::TScrollBarType> (iExtension->ScrollBarType());
       
   413         }
       
   414     return CEikScrollBar::TScrollBarType(ENormalScrollBar);
       
   415      }
       
   416 
       
   417 
       
   418 
       
   419 // ----------------------------------------------------------------------------
       
   420 // CEikScrollBar::SetScrollBarObserver
       
   421 //
       
   422 // Sets scroll bar observer. This enables changing of the observer also after the
       
   423 // scroll bar has been constructed.
       
   424 // ----------------------------------------------------------------------------
       
   425 //
       
   426 void CEikScrollBar::SetScrollBarObserver(MEikScrollBarObserver* aScrollBarObserver)
       
   427     {
       
   428     if( !AknLayoutUtils::PenEnabled() )
       
   429         {
       
   430         return;
       
   431         }
       
   432 
       
   433     if(ScrollBarType() == CEikScrollBar::EDoubleSpan)
       
   434         {
       
   435         CAknDoubleSpanScrollBarExtension* extension = static_cast<CAknDoubleSpanScrollBarExtension*> (iExtension);
       
   436         extension->SetScrollBarObserver(aScrollBarObserver);
       
   437         }
       
   438     else
       
   439         {
       
   440         CEikScrollBarExtension* extension = static_cast<CEikScrollBarExtension*> (iExtension);
       
   441         extension->SetScrollBarObserver(aScrollBarObserver);
       
   442         }
       
   443     }
       
   444 
       
   445 //
       
   446 // class CEikScrollBarExtension
       
   447 //
       
   448 
       
   449 CEikScrollBarExtension::CEikScrollBarExtension(CEikScrollBar* aParent)
       
   450 : iExternalFrames(1)
       
   451     {
       
   452     iParent=aParent;
       
   453     }
       
   454 
       
   455 CEikScrollBarExtension::~CEikScrollBarExtension()
       
   456     {
       
   457     }
       
   458 
       
   459 
       
   460 void CEikScrollBarExtension::SetLengthL(TInt /*aLength*/)
       
   461     {
       
   462     }
       
   463 
       
   464 void CEikScrollBarExtension::SetModelL(const TEikScrollBarModel* /*aModel*/)
       
   465     {
       
   466     }
       
   467 
       
   468 void CEikScrollBarExtension::SetModel(const TEikScrollBarModel* /*aModel*/)
       
   469     {
       
   470     }
       
   471 
       
   472 void CEikScrollBarExtension::SetLengthAndModelL(TInt /*aLength*/,const TEikScrollBarModel* /*aModel*/)
       
   473     {
       
   474     }
       
   475 
       
   476 void CEikScrollBarExtension::SetModelThumbPosition(TInt /*aThumbPos*/)
       
   477     {
       
   478     }
       
   479 
       
   480 void CEikScrollBarExtension::SetFocusPosToThumbPos(TInt /*aFocusPosition*/)
       
   481     {
       
   482     }
       
   483 
       
   484 TInt CEikScrollBarExtension::ThumbPosition() const
       
   485     {
       
   486     return(iParent->iModel.iThumbPosition);
       
   487     }
       
   488 
       
   489 TInt CEikScrollBarExtension::ScrollBarBreadth() const
       
   490     {
       
   491     if (iParent->iOrientation==CEikScrollBar::EHorizontal)
       
   492         return iParent->iSize.iHeight;
       
   493     return iParent->iSize.iWidth;
       
   494     }
       
   495 
       
   496 void CEikScrollBarExtension::SetDecreaseButtonsDimmed(TBool /*aDimmed*/)
       
   497     {
       
   498     }
       
   499 
       
   500 void CEikScrollBarExtension::SetIncreaseButtonsDimmed(TBool /*aDimmed*/)
       
   501     {
       
   502     }
       
   503 
       
   504 void CEikScrollBarExtension::SetAllButtonsDimmed(TBool /*aDimmed*/)
       
   505     {
       
   506     }
       
   507 
       
   508 void CEikScrollBarExtension::SetContainingCba(CEikCba* aCba)
       
   509     {
       
   510     iCba = aCba;
       
   511     }
       
   512 
       
   513 TInt CEikScrollBarExtension::ScrollBarType()
       
   514     {
       
   515     return CEikScrollBar::EArrowHead;
       
   516     }
       
   517 
       
   518 void CEikScrollBarExtension::CreateButtonL(CAknScrollButton*& /*aButton*/,CAknScrollButton::TType /*aType*/)
       
   519     {
       
   520     }
       
   521 
       
   522 void CEikScrollBarExtension::DoSetModel(const TEikScrollBarModel* aModel)
       
   523     {
       
   524     iParent->iModel=(*aModel);
       
   525     iParent->iModel.CheckBounds();
       
   526 
       
   527     TInt focusPosition=iParent->iModel.iThumbPosition;
       
   528     if ((focusPosition!=-1) && iParent && iParent->iButtons.iIncreaseNudge && iParent->iButtons.iDecreaseNudge)
       
   529         {
       
   530         iParent->iButtons.iIncreaseNudge->SetPosition(focusPosition, iParent->iModel.iScrollSpan);
       
   531         iParent->iButtons.iDecreaseNudge->SetPosition(focusPosition, iParent->iModel.iScrollSpan);
       
   532         }
       
   533     }
       
   534 
       
   535 CEikCba* CEikScrollBarExtension::Cba() const
       
   536     {
       
   537     return iCba;
       
   538     }
       
   539 
       
   540 void CEikScrollBarExtension::AddExternalFrameL(CEikScrollBarFrame* aFrame)
       
   541     {
       
   542     iExternalFrames.AppendL(aFrame);
       
   543     }
       
   544 
       
   545 
       
   546 void CEikScrollBarExtension::RemoveExternalFrame(CEikScrollBarFrame* aFrame)
       
   547     {
       
   548     TInt count = iExternalFrames.Count();
       
   549     for (TInt ii=count-1; ii>=0; ii--)
       
   550         {
       
   551         if (iExternalFrames[ii] == aFrame)
       
   552             {
       
   553             iExternalFrames[ii]->DisconnectExternalScrollBar(iParent);
       
   554             iExternalFrames.Delete(ii);
       
   555             }
       
   556         }
       
   557     }
       
   558 
       
   559 void CEikScrollBarExtension::DisconnectExternalFrames()
       
   560     {
       
   561     TInt count = iExternalFrames.Count();
       
   562     for (TInt ii=count-1; ii>=0; ii--)
       
   563         {
       
   564         iExternalFrames[ii]->DisconnectExternalScrollBar(iParent);
       
   565         }
       
   566     iExternalFrames.Reset();
       
   567     }
       
   568 
       
   569 void CEikScrollBarExtension::CreateRequiredComponentsL()
       
   570     {
       
   571     TBool horiz=(iParent->iOrientation==CEikScrollBar::EHorizontal);
       
   572     iParent->CreateButtonL(iParent->iButtons.iDecreaseNudge,horiz ? CAknScrollButton::ENudgeLeft : CAknScrollButton::ENudgeUp);
       
   573     iParent->CreateButtonL(iParent->iButtons.iIncreaseNudge,horiz ? CAknScrollButton::ENudgeRight : CAknScrollButton::ENudgeDown);
       
   574     }
       
   575 
       
   576 void CEikScrollBarExtension::DestroyButton(CAknScrollButton*& /*aButton*/)
       
   577     {
       
   578     }
       
   579 
       
   580 void CEikScrollBarExtension::SetButtonPositionL(CAknScrollButton* /*aButton*/)
       
   581     {
       
   582     }
       
   583 
       
   584 
       
   585 void CEikScrollBarExtension::SetScrollBarObserver(MEikScrollBarObserver* aScrollBarObserver)
       
   586     {
       
   587     iScrollBarObserver = aScrollBarObserver;
       
   588     }
       
   589 
       
   590 MEikScrollBarObserver* CEikScrollBarExtension::ScrollBarObserver()
       
   591     {
       
   592     return iScrollBarObserver;
       
   593     }
       
   594 
       
   595 TBool CEikScrollBarExtension::HasModelChanged(const TEikScrollBarModel* /*aModel*/)
       
   596     {
       
   597     return EFalse;
       
   598     }
       
   599 TInt CEikScrollBarExtension::Reserved_1(){return 0;};
       
   600 TInt CEikScrollBarExtension::Reserved_2(){return 0;};
       
   601 
       
   602 
       
   603 
       
   604 //
       
   605 // class CEikArrowHeadScrollBar
       
   606 //
       
   607 
       
   608 EXPORT_C CEikArrowHeadScrollBar::CEikArrowHeadScrollBar(CCoeControl* aParentWindow)
       
   609     : iParentControl(aParentWindow)
       
   610     {
       
   611     AKNTASHOOK_ADD( this, "CEikArrowHeadScrollBar" );
       
   612     }
       
   613 
       
   614 EXPORT_C CEikArrowHeadScrollBar::~CEikArrowHeadScrollBar()
       
   615     {
       
   616     AKNTASHOOK_REMOVE();
       
   617     }
       
   618 
       
   619 EXPORT_C void CEikArrowHeadScrollBar::ConstructL(MEikScrollBarObserver* aScrollBarObserver,const CCoeControl* aParent,
       
   620                                                  TOrientation aOrientation,TInt aLength,TInt aScrollBarFlags)
       
   621 // Second-phase construction
       
   622     {
       
   623     iExtension = new(ELeave) CEikScrollBarExtension(this);
       
   624     CEikScrollBar::ConstructL(aScrollBarObserver,aParent,aOrientation,aLength,aScrollBarFlags);
       
   625     }
       
   626 
       
   627 void CEikArrowHeadScrollBar::CreateButtonL(CAknScrollButton*& aButton,CAknScrollButton::TType aType)
       
   628 // Create the appropriate button
       
   629     {
       
   630     if (aButton)
       
   631         return;
       
   632     CAknScrollButton* button=CAknScrollButton::NewL(aType);
       
   633     CleanupStack::PushL(button);
       
   634      button->CreateWindowOnlyForArrowsL(iParentControl);
       
   635     button->SetObserver((MCoeControlObserver*)this);
       
   636     SetButtonPositionL(button);
       
   637     button->SetTypeOfScrollBarUsingButton(CAknScrollButton::EArrowHead);
       
   638     CleanupStack::Pop(); // button
       
   639     aButton=button;
       
   640     }
       
   641 
       
   642 void CEikArrowHeadScrollBar::SetButtonPositionL(CAknScrollButton* aButton)
       
   643     {
       
   644     TInt index = aButton->Type()==CAknScrollButton::ENudgeDown ? 1 : 0;
       
   645     TAknWindowLineLayout lay( AKN_LAYOUT_TABLE_Control_pane_elements(index) );
       
   646     TAknLayoutRect lr;
       
   647     lr.LayoutRect( Rect(), lay );
       
   648     TRect r( lr.Rect() );
       
   649     aButton->SetExtent( r.iTl, TSize( Size().iWidth, r.Height() ) );
       
   650     }
       
   651 
       
   652 EXPORT_C void CEikArrowHeadScrollBar::HandlePointerEventL(const TPointerEvent& aPointerEvent)
       
   653     {
       
   654     CEikScrollBar::HandlePointerEventL(aPointerEvent);
       
   655     }
       
   656 
       
   657 EXPORT_C void* CEikArrowHeadScrollBar::ExtensionInterface( TUid /*aInterface*/ )
       
   658     {
       
   659     return NULL;
       
   660     }
       
   661 
       
   662 //
       
   663 // class CAknDoubleSpanScrollBar
       
   664 //
       
   665 EXPORT_C CAknDoubleSpanScrollBar::CAknDoubleSpanScrollBar(CCoeControl* aParentWindow)
       
   666     : iParentControl(aParentWindow)
       
   667     {
       
   668     AKNTASHOOK_ADD( this, "CAknDoubleSpanScrollBar" );
       
   669     }
       
   670 
       
   671 EXPORT_C CAknDoubleSpanScrollBar::~CAknDoubleSpanScrollBar()
       
   672     {
       
   673     AKNTASHOOK_REMOVE();
       
   674     if ( iAvkonAppUiBase )
       
   675         {
       
   676         CAknPointerEventModifier* modifier = iAvkonAppUiBase->PointerEventModifier();
       
   677         
       
   678         if ( modifier )
       
   679             {
       
   680             modifier->Pop( *this );
       
   681             }
       
   682         }
       
   683         
       
   684     AknsUtils::DeregisterControlPosition( this );
       
   685     }
       
   686 
       
   687 EXPORT_C void CAknDoubleSpanScrollBar::ConstructL(TBool aWindowOwning, MEikScrollBarObserver* aScrollBarObserver,const CCoeControl* aParent,
       
   688                                                  TOrientation aOrientation,TInt /*aLength*/,TInt aScrollBarFlags )
       
   689     {
       
   690     iExtension = new(ELeave) CAknDoubleSpanScrollBarExtension(this);
       
   691     CAknDoubleSpanScrollBarExtension* extension = static_cast<CAknDoubleSpanScrollBarExtension*> (iExtension);
       
   692 
       
   693     extension->iScrollBarFlags = aScrollBarFlags;
       
   694     extension->iExtensionType = ENormalExpandedTouchArea;
       
   695 
       
   696     if ( AknLayoutUtils::PenEnabled() )
       
   697         {
       
   698         extension->SetScrollBarObserver(aScrollBarObserver); // sets also the owning observer
       
   699 
       
   700         extension->iPopupController = CAknInfoPopupNoteController::NewL();
       
   701         extension->iPopupController->SetTooltipModeL( ETrue );
       
   702         extension->iPopupController->SetTimeDelayBeforeShow( 1 );
       
   703         extension->iShowPopup = EFalse;
       
   704         }
       
   705 
       
   706     if (aWindowOwning)
       
   707         {
       
   708         CreateWindowL(aParent);
       
   709         if ( CAknEnv::Static()->TransparencyEnabled() )
       
   710             {
       
   711             Window().SetRequiredDisplayMode( EColor16MA );
       
   712             if ( Window().SetTransparencyAlphaChannel() == KErrNone )
       
   713                 {
       
   714                 Window().SetBackgroundColor( ~0 );
       
   715                 }
       
   716             }
       
   717         }
       
   718     else if(aParent)
       
   719         {
       
   720         SetContainerWindowL(*aParent);
       
   721         }
       
   722     else
       
   723         {
       
   724         User::Leave(KErrArgument);
       
   725         }
       
   726 
       
   727     if( aParent )
       
   728         SetObserver(aParent->Observer());
       
   729     else
       
   730         SetObserver(NULL);
       
   731 
       
   732     iOrientation=aOrientation;
       
   733     CreateRequiredComponentsL();
       
   734 
       
   735     if (aWindowOwning)
       
   736         {
       
   737         Window().SetPointerGrab(ETrue);
       
   738         EnableDragEvents();
       
   739         if (extension->iScrollIndicator)
       
   740                extension->iScrollIndicator->SetAsWindowOwning(ETrue);
       
   741 
       
   742 
       
   743         // By default set background to transparent
       
   744         SetTransparentBackground(ETrue);
       
   745         }
       
   746 
       
   747     SetComponentsToInheritVisibility(ETrue);
       
   748     MakeVisible(EFalse);
       
   749     ActivateL();
       
   750     }
       
   751 
       
   752 
       
   753 EXPORT_C void CAknDoubleSpanScrollBar::ConstructL(MEikScrollBarObserver* aScrollBarObserver,const CCoeControl* aParent,
       
   754                                                  TOrientation aOrientation,TInt aLength,TInt aScrollBarFlags)
       
   755 // Second-phase construction, overides method from CEikScrollBar
       
   756     {
       
   757     ConstructL(ETrue, aScrollBarObserver, aParent, aOrientation, aLength, aScrollBarFlags);
       
   758     }
       
   759 
       
   760 
       
   761 // ----------------------------------------------------------------------------
       
   762 // CAknDoubleSpanScrollBar::CreateButtonL
       
   763 //
       
   764 // Creates buttons for double span scrollbar when __PEN_SUPPORT is enabled
       
   765 // ----------------------------------------------------------------------------
       
   766 //
       
   767 void CAknDoubleSpanScrollBar::CreateButtonL(CAknScrollButton*& aButton, CAknScrollButton::TType aType)
       
   768 // Create the appropriate button
       
   769     {
       
   770     if( !AknLayoutUtils::PenEnabled() )
       
   771         {
       
   772         // No buttons exist in this type of scrollbar
       
   773         return;
       
   774         }
       
   775 
       
   776     if (aButton)
       
   777         {
       
   778         return;
       
   779         }
       
   780     CAknScrollButton* button = CAknScrollButton::NewL(aType, CAknScrollButton::ENormal);
       
   781     CleanupStack::PushL(button);
       
   782     if ( OwnsWindow() && AknLayoutUtils::PenEnabled() )
       
   783         {
       
   784         button->CreateWindowOnlyForArrowsL( this );
       
   785         }
       
   786     button->SetContainerWindowL( *this );
       
   787 
       
   788     CleanupStack::Pop(); // button
       
   789     aButton = button;
       
   790     }
       
   791 
       
   792 
       
   793 // ----------------------------------------------------------------------------
       
   794 // CAknDoubleSpanScrollBar::SetButtonPositionL
       
   795 //
       
   796 // Sets button position when AknLayoutUtils::PenEnabled() returns ETrue
       
   797 // This function is called from CAknDoubleSpanScrollBar::SizeChanged() function
       
   798 // The button rectangle should be set in this function according to LAF spec
       
   799 // ----------------------------------------------------------------------------
       
   800 //
       
   801 void CAknDoubleSpanScrollBar::SetButtonPositionL(CAknScrollButton* aButton)
       
   802     {
       
   803     if( !AknLayoutUtils::PenEnabled() )
       
   804         {
       
   805         // No buttons exist in this type of scrollbar
       
   806         return;
       
   807         }
       
   808 
       
   809     if ( aButton )
       
   810         {
       
   811         if( iExtension )
       
   812             {
       
   813             TAknWindowComponentLayout buttonLayout;
       
   814             TAknLayoutRect buttonRect;
       
   815 
       
   816             switch(aButton->Type())
       
   817                 {
       
   818                 case CAknScrollButton::ENudgeUp:
       
   819                     buttonLayout = AknLayoutScalable_Avkon::scroll_sc2_up_pane( 1 );
       
   820                     buttonRect.LayoutRect( Rect(), buttonLayout.LayoutLine() );
       
   821                     aButton->SetRect( buttonRect.Rect() );
       
   822                     break;
       
   823                 case CAknScrollButton::ENudgeDown:
       
   824                     buttonLayout = AknLayoutScalable_Avkon::scroll_sc2_down_pane( 1 );
       
   825                     buttonRect.LayoutRect( Rect(), buttonLayout.LayoutLine() );
       
   826                     aButton->SetRect( buttonRect.Rect() );
       
   827                     break;
       
   828                 case CAknScrollButton::ENudgeLeft:
       
   829                     buttonLayout = AknLayoutScalable_Avkon::scroll_sc2_left_pane();
       
   830                     buttonRect.LayoutRect( Rect(), buttonLayout.LayoutLine() );
       
   831                     aButton->SetRect( buttonRect.Rect() );
       
   832                     break;
       
   833                 case CAknScrollButton::ENudgeRight:
       
   834                     buttonLayout = AknLayoutScalable_Avkon::scroll_sc2_right_pane();
       
   835                     buttonRect.LayoutRect( Rect(), buttonLayout.LayoutLine() );
       
   836                     aButton->SetRect( buttonRect.Rect() );
       
   837                     break;
       
   838                 default:
       
   839                     break;
       
   840                 }
       
   841             }
       
   842         }
       
   843     }
       
   844 
       
   845 
       
   846 EXPORT_C void CAknDoubleSpanScrollBar::MakeVisible(TBool aVisible)
       
   847     {
       
   848     CAknPointerEventModifier* modifier = iAvkonAppUiBase ? iAvkonAppUiBase->PointerEventModifier() : NULL;
       
   849     
       
   850     if ( modifier )
       
   851         {
       
   852         CAknDoubleSpanScrollBarExtension* extension = static_cast<CAknDoubleSpanScrollBarExtension*> (iExtension);
       
   853         if ( aVisible  && (extension->iScrollIndicator->ScrollSpan() > 0) )
       
   854             {
       
   855             modifier->Push( *this, ExtensionArea() );
       
   856             }
       
   857         else
       
   858             {
       
   859             modifier->Pop( *this );
       
   860             }
       
   861         }
       
   862 
       
   863     CCoeControl::MakeVisible(aVisible);
       
   864     }
       
   865 
       
   866 EXPORT_C TInt CAknDoubleSpanScrollBar::CountComponentControls() const
       
   867     {
       
   868     TInt controlCount = 0;
       
   869     if (iExtension)
       
   870         {
       
   871         CAknDoubleSpanScrollBarExtension* extension = static_cast<CAknDoubleSpanScrollBarExtension*> (iExtension);
       
   872         if (extension->iScrollIndicator)
       
   873             {
       
   874             controlCount = 1;
       
   875             }
       
   876         }
       
   877     if(AknLayoutUtils::PenEnabled())
       
   878         {
       
   879         if(iButtons.iIncreaseNudge)
       
   880             {
       
   881             controlCount++;
       
   882             }
       
   883         if(iButtons.iDecreaseNudge)
       
   884             {
       
   885             controlCount++;
       
   886             }
       
   887         }
       
   888 
       
   889     return controlCount;
       
   890     }
       
   891 
       
   892 EXPORT_C CCoeControl* CAknDoubleSpanScrollBar::ComponentControl(TInt aIndex) const
       
   893     {
       
   894     CCoeControl* control = NULL;
       
   895     if (aIndex==0 && iExtension)
       
   896         {
       
   897         CAknDoubleSpanScrollBarExtension* extension = static_cast<CAknDoubleSpanScrollBarExtension*> (iExtension);
       
   898         control = extension->iScrollIndicator;
       
   899         }
       
   900     if(AknLayoutUtils::PenEnabled())
       
   901         {
       
   902         if(aIndex == 1)
       
   903             {
       
   904             control = iButtons.iIncreaseNudge;
       
   905             }
       
   906         else if(aIndex == 2)
       
   907             {
       
   908             control = iButtons.iDecreaseNudge;
       
   909             }
       
   910         }
       
   911 
       
   912     return control;
       
   913     }
       
   914 
       
   915 
       
   916 EXPORT_C void CAknDoubleSpanScrollBar::SizeChanged()
       
   917     {
       
   918     CAknPointerEventModifier* modifier = iAvkonAppUiBase ? iAvkonAppUiBase->PointerEventModifier() : NULL;
       
   919     
       
   920     if ( modifier && IsVisible() )
       
   921         {
       
   922         modifier->Update( *this, ExtensionArea() );
       
   923         }
       
   924 
       
   925     AknsUtils::RegisterControlPosition( this );
       
   926     if (iExtension)
       
   927         {
       
   928         CAknDoubleSpanScrollBarExtension* extension = static_cast<CAknDoubleSpanScrollBarExtension*> (iExtension);
       
   929         CAknDoubleSpanScrollIndicator* indicator = extension->iScrollIndicator;
       
   930         // set indicator size to same as the whole scrollbar.
       
   931         if (indicator)
       
   932            {
       
   933             TAknWindowComponentLayout combinedRect;
       
   934 
       
   935             TInt variety = 0;
       
   936             TInt scVariety = 0;
       
   937             // No pen check as the layout for the non-pen is not taken from layout data
       
   938             // if in future made so, this must be changed to support also non-pen situations
       
   939             if( AknLayoutUtils::PenEnabled() )
       
   940                 {
       
   941                 if ( iOrientation == EHorizontal)
       
   942                     {
       
   943                     variety = 2;
       
   944                     scVariety = 1;
       
   945                     }
       
   946                 else
       
   947                     {
       
   948                     variety = 1;
       
   949                     }
       
   950                 }
       
   951 
       
   952 
       
   953             combinedRect = TAknWindowComponentLayout::Compose( AknLayoutScalable_Avkon::scroll_pane( scVariety ),
       
   954                                                                AknLayoutScalable_Avkon::bg_scroll_pane( variety ) );
       
   955             TAknLayoutRect indicatorRect;
       
   956 
       
   957             if (OwnsWindow())
       
   958                 {
       
   959                 if( AknLayoutUtils::PenEnabled() &&
       
   960                     ( extension->iScrollBarFlags & EEnableNudgeButtons ) )
       
   961                     {
       
   962                     // when the pen support is enabled, the space for arrows must be reserved.
       
   963                     indicatorRect.LayoutRect( Rect(), combinedRect.LayoutLine() );
       
   964                     indicator->SetRect( indicatorRect.Rect() );
       
   965                     }
       
   966                 else
       
   967                     {
       
   968                     indicator->SetExtent(TPoint(0,0),Size());
       
   969                     }
       
   970 
       
   971                 if (indicator->TransparentBackground())
       
   972                     {
       
   973                     // This will refresh the transparency masks
       
   974                     SetTransparentBackground(ETrue);
       
   975                     }
       
   976                 }
       
   977             else
       
   978                 {
       
   979                 if( AknLayoutUtils::PenEnabled() &&
       
   980                     ( extension->iScrollBarFlags & EEnableNudgeButtons ) )
       
   981                     {
       
   982                     // when the pen support is enabled, the space for arrows must be reserved.
       
   983                     TRect rect( Position(), Size() );
       
   984                     indicatorRect.LayoutRect( rect, combinedRect.LayoutLine() );
       
   985                     indicator->SetRect( indicatorRect.Rect() );
       
   986                     }
       
   987                 else
       
   988                     {
       
   989                     indicator->SetExtent(Position(),Size());
       
   990                     }
       
   991                 }
       
   992             }
       
   993 
       
   994         if(AknLayoutUtils::PenEnabled())
       
   995             {
       
   996             if ( !iButtons.iIncreaseNudge || !iButtons.iDecreaseNudge )
       
   997                 {
       
   998                 TRAP_IGNORE( CreateRequiredComponentsL() );
       
   999                 }
       
  1000             // Set scroll button positions
       
  1001             TRAP_IGNORE( SetButtonPositionL( iButtons.iIncreaseNudge ) );
       
  1002             TRAP_IGNORE( SetButtonPositionL( iButtons.iDecreaseNudge ) );
       
  1003             }
       
  1004         }
       
  1005     }
       
  1006 
       
  1007 
       
  1008 // ----------------------------------------------------------------------------
       
  1009 // CAknDoubleSpanScrollBar::HandlePointerEventL
       
  1010 //
       
  1011 // Handles pointer events.
       
  1012 // ----------------------------------------------------------------------------
       
  1013 //
       
  1014 EXPORT_C void CAknDoubleSpanScrollBar::HandlePointerEventL(const TPointerEvent& aPointerEvent)
       
  1015     {
       
  1016     if( !AknLayoutUtils::PenEnabled() || !iExtension)
       
  1017         {
       
  1018         return;
       
  1019         }
       
  1020 
       
  1021     if ( aPointerEvent.iType == TPointerEvent::EButton1Down && GrabbingComponent() != this && OwnsWindow() )
       
  1022         {
       
  1023         ClaimPointerGrab( EFalse );
       
  1024         }
       
  1025 
       
  1026     CAknDoubleSpanScrollBarExtension* extension =
       
  1027         static_cast<CAknDoubleSpanScrollBarExtension*> (iExtension);
       
  1028     CAknDoubleSpanScrollIndicator* indicator = extension->iScrollIndicator;
       
  1029 
       
  1030     RDrawableWindow* pointerWindow = &Window();
       
  1031     TRect rect(indicator->Rect());
       
  1032 
       
  1033     // scale the pointer event position relative to indicator rect
       
  1034     // this has effect only if the scroll bar is not window owning
       
  1035     TPoint eventPos(aPointerEvent.iPosition - rect.iTl);
       
  1036 
       
  1037     // use x or y values depending on orientation
       
  1038     TInt position(eventPos.iY);
       
  1039     TInt scrollSpanPix(rect.Height());
       
  1040     if(iOrientation == EHorizontal)
       
  1041         {
       
  1042         position = eventPos.iX;
       
  1043         scrollSpanPix = rect.Width();
       
  1044         }
       
  1045 
       
  1046     // get current values from the indicator
       
  1047     TInt scrollSpan(indicator->ScrollSpan());
       
  1048     TInt thumbSpan(indicator->WindowSize());
       
  1049     TInt thumbPosition(indicator->FocusPosition());
       
  1050     TInt thumbSpanPix     = indicator->GetCurrentThumbSpanInPixels();
       
  1051     TInt thumbPositionPix = indicator->GetCurrentThumbPositionInPixels();
       
  1052     // clear the pointer down info on pen up and hide info popup
       
  1053     TInt lastPointerDownOn = extension->iPointerDownOn;
       
  1054     // The real span area available (as pixels)
       
  1055     scrollSpanPix -= thumbSpanPix;
       
  1056 
       
  1057             
       
  1058          // touch release on thumb
       
  1059          TBool thumbPressed = 
       
  1060                  ( position < (thumbPositionPix + thumbSpanPix) 
       
  1061                          && position > thumbPositionPix );
       
  1062          if ( thumbPressed &&
       
  1063               aPointerEvent.iType == TPointerEvent::EButton1Up &&
       
  1064               thumbSpan < scrollSpan )
       
  1065              {
       
  1066              MTouchFeedback* feedback = MTouchFeedback::Instance();
       
  1067 
       
  1068              CCoeControl* parent = Parent();
       
  1069              TBool feedbackEnabled = !IsDimmed() && IsVisible();
       
  1070              if (parent && feedbackEnabled)
       
  1071                  {
       
  1072                  // check the same for the parent
       
  1073                  feedbackEnabled = !parent->IsDimmed() && parent->IsVisible();
       
  1074                  }
       
  1075              if ( feedback && feedbackEnabled )
       
  1076                  {
       
  1077                  feedback->InstantFeedback( this, 
       
  1078                                             ETouchFeedbackSlider, 
       
  1079                                             ETouchFeedbackVibra, 
       
  1080                                             aPointerEvent );
       
  1081                  }
       
  1082              }
       
  1083      
       
  1084     // check that scroll bar is useful
       
  1085     if (thumbSpan < scrollSpan)
       
  1086         {
       
  1087         // check where the pointer down occured
       
  1088         if(aPointerEvent.iType == TPointerEvent::EButton1Down )
       
  1089             {
       
  1090             indicator->SetBackgroudHighlight( ETrue );
       
  1091 
       
  1092             extension->iPointerDownPosition  = position;
       
  1093             
       
  1094             if(iButtons.iIncreaseNudge &&
       
  1095                iButtons.iIncreaseNudge->Rect().Contains(aPointerEvent.iPosition))
       
  1096                 {
       
  1097                 extension->iPointerDownOn = CEikScrollBar::EIncreaseNudgeButton;
       
  1098                 }
       
  1099             else if(iButtons.iDecreaseNudge &&
       
  1100                     iButtons.iDecreaseNudge->Rect().Contains(aPointerEvent.iPosition))
       
  1101                 {
       
  1102                 extension->iPointerDownOn = CEikScrollBar::EDecreaseNudgeButton;
       
  1103                 }
       
  1104             else if (position < thumbPositionPix)
       
  1105                 {
       
  1106                 extension->iPointerDownOn = CEikScrollBar::EDecreaseShaft;
       
  1107                 }
       
  1108             else if (position < (thumbPositionPix + thumbSpanPix))
       
  1109                 {
       
  1110                 extension->iDragged = EFalse;
       
  1111                 extension->iPointerDownOn = CEikScrollBar::EThumb;
       
  1112                 extension->iPointerOffsetFromThumb = position - thumbPositionPix;
       
  1113 
       
  1114                 indicator->SetHandleHighlight( ETrue );
       
  1115                 indicator->DrawDeferred();
       
  1116                 }
       
  1117             else
       
  1118                 {
       
  1119                 extension->iPointerDownOn = CEikScrollBar::EIncreaseShaft;
       
  1120                 }
       
  1121             }
       
  1122 
       
  1123         if (aPointerEvent.iType == TPointerEvent::EButton1Up)
       
  1124             {
       
  1125             extension->iPointerDownOn = CEikScrollBar::ENone;
       
  1126 
       
  1127             // Highlight off always when the pointer is lifted
       
  1128             indicator->SetHandleHighlight( EFalse );
       
  1129             indicator->DrawDeferred();
       
  1130             indicator->SetBackgroudHighlight( EFalse );
       
  1131 
       
  1132             if ( extension->iPopupController )
       
  1133                 {
       
  1134                 extension->iPopupController->HideInfoPopupNote();
       
  1135                     extension->iShowPopup = EFalse;
       
  1136                 }
       
  1137             }
       
  1138 
       
  1139         // respond to the pointer event
       
  1140         switch(extension->iPointerDownOn)
       
  1141             {
       
  1142             case CEikScrollBar::EDecreaseShaft:
       
  1143             case CEikScrollBar::EIncreaseShaft:
       
  1144                 {
       
  1145                 TEikScrollEvent event = EEikScrollPageUp;
       
  1146                 if(aPointerEvent.iType == TPointerEvent::EButton1Down ||
       
  1147                    aPointerEvent.iType == TPointerEvent::EButtonRepeat)
       
  1148                     {
       
  1149                     if(extension->iPointerDownOn == CEikScrollBar::EDecreaseShaft)
       
  1150                         {
       
  1151                         event = iOrientation==EHorizontal ? EEikScrollPageLeft : EEikScrollPageUp;
       
  1152                         thumbPosition -= thumbSpan;
       
  1153                         thumbPosition = Max(0, thumbPosition);
       
  1154 
       
  1155 
       
  1156                         TInt prevPosValue = extension->ThumbPosition();
       
  1157                         
       
  1158                         // This will update the thumb's pixel extent, used
       
  1159                         // below
       
  1160                         extension->SetModelThumbPosition(thumbPosition);
       
  1161                         indicator->SetIndicatorValues(scrollSpan, thumbPosition, thumbSpan, 0, 0);
       
  1162 
       
  1163                         TInt afterPosValue = extension->ThumbPosition();
       
  1164                         if (prevPosValue != afterPosValue)
       
  1165                             {
       
  1166                             MTouchFeedback* feedback = MTouchFeedback::Instance();
       
  1167 
       
  1168                             CCoeControl* parent = Parent();
       
  1169                             TBool feedbackEnabled = !IsDimmed() && IsVisible();
       
  1170                             if (parent && feedbackEnabled)
       
  1171                                 {
       
  1172                                 // check the same for the parent
       
  1173                                 feedbackEnabled = !parent->IsDimmed() && parent->IsVisible();
       
  1174                                 }
       
  1175                             if ( feedback && feedbackEnabled )
       
  1176                                 {
       
  1177                                 feedback->InstantFeedback( this, ETouchFeedbackSlider, aPointerEvent );
       
  1178                                 }
       
  1179                             }
       
  1180 
       
  1181                         // request pointer repeat until the thumb reaches the pen down position
       
  1182                         TInt newThumbPosPix = indicator->GetCurrentThumbPositionInPixels();
       
  1183                         if(position < newThumbPosPix)
       
  1184                             {
       
  1185                             TRect ignoreRect(rect);
       
  1186                             TRect rt = ExtensionArea();
       
  1187                             if(iOrientation == EVertical)
       
  1188                                 {
       
  1189                                 ignoreRect.iTl = TPoint(rt.iTl.iX, rect.iTl.iY);
       
  1190                                 ignoreRect.iBr = TPoint(ignoreRect.iBr.iX, newThumbPosPix + rect.iTl.iY);
       
  1191                                 }
       
  1192                             else
       
  1193                                 {
       
  1194                                 ignoreRect.iTl = TPoint(rect.iTl.iX, rt.iTl.iY);
       
  1195                                 ignoreRect.iBr = TPoint(newThumbPosPix, rt.iBr.iY);
       
  1196                                 }
       
  1197                             // repeat until thumb reaches the stylus down position
       
  1198                             pointerWindow->RequestPointerRepeatEvent(KScrollRepeatTimeout, ignoreRect);
       
  1199                             }
       
  1200                         
       
  1201 
       
  1202                         }
       
  1203                     else
       
  1204                         {
       
  1205                         event = iOrientation==EHorizontal ? EEikScrollPageRight : EEikScrollPageDown;
       
  1206                         thumbPosition += thumbSpan;
       
  1207                         thumbPosition = Min((scrollSpan - thumbSpan), thumbPosition);
       
  1208 
       
  1209                         TInt prevPosValue = extension->ThumbPosition();
       
  1210                         extension->SetModelThumbPosition(thumbPosition);
       
  1211                         indicator->SetIndicatorValues(scrollSpan, thumbPosition, thumbSpan, 0, 0);
       
  1212 
       
  1213                         TInt afterPosValue = extension->ThumbPosition();
       
  1214                         if (prevPosValue != afterPosValue)
       
  1215                             {
       
  1216                             MTouchFeedback* feedback = MTouchFeedback::Instance();
       
  1217 
       
  1218                             CCoeControl* parent = Parent();
       
  1219                             TBool feedbackEnabled = !IsDimmed() && IsVisible();
       
  1220                             if (parent && feedbackEnabled)
       
  1221                                 {
       
  1222                                 // check the same for the parent
       
  1223                                 feedbackEnabled = !parent->IsDimmed() && parent->IsVisible();
       
  1224                                 }
       
  1225                             if ( feedback && feedbackEnabled )
       
  1226                                 {
       
  1227                                 feedback->InstantFeedback( this, ETouchFeedbackSlider, aPointerEvent );
       
  1228                                 }
       
  1229                             }
       
  1230 
       
  1231                         // request pointer repeat until the thumb reaches the pen down position
       
  1232                         TInt newThumbPosPix = indicator->GetCurrentThumbPositionInPixels();
       
  1233                         newThumbPosPix += thumbSpanPix;
       
  1234 
       
  1235                         if(position > newThumbPosPix )
       
  1236                             {
       
  1237                             TRect ignoreRect(rect);
       
  1238                             TRect rt = ExtensionArea();
       
  1239                             if(iOrientation == EVertical)
       
  1240                                 {
       
  1241                                 ignoreRect.iTl = TPoint(rt.iTl.iX, newThumbPosPix + rect.iTl.iY);
       
  1242                                 }
       
  1243                             else
       
  1244                                 {
       
  1245                                 ignoreRect.iTl = TPoint(newThumbPosPix, rt.iTl.iY);
       
  1246                                 }
       
  1247                             // repeat until thumb reaches the stylus down position
       
  1248                             pointerWindow->RequestPointerRepeatEvent(KScrollRepeatTimeout, ignoreRect);
       
  1249 
       
  1250                             }
       
  1251                         
       
  1252                         }
       
  1253 
       
  1254                     if(indicator->DrawBackgroundState())
       
  1255                         indicator->DrawNow();
       
  1256                     else
       
  1257                         indicator->DrawDeferred();
       
  1258 
       
  1259                     if(extension->ScrollBarObserver())
       
  1260                         {
       
  1261                         extension->ScrollBarObserver()->HandleScrollEventL(this, event);
       
  1262                         }
       
  1263                     }
       
  1264 
       
  1265                 }
       
  1266                 break;
       
  1267 
       
  1268             case CEikScrollBar::EThumb:
       
  1269                 if( aPointerEvent.iType == TPointerEvent::EButton1Down )
       
  1270                     {
       
  1271                     MTouchFeedback* feedback = MTouchFeedback::Instance();
       
  1272 
       
  1273                     if ( feedback )
       
  1274                         {
       
  1275                         TTouchFeedbackType fbType = TTouchFeedbackType( 
       
  1276                                                         ETouchFeedbackAudio |
       
  1277                                                         ETouchFeedbackVibra );
       
  1278                           
       
  1279                         feedback->InstantFeedback( this, ETouchFeedbackSlider, fbType, aPointerEvent );
       
  1280                         }
       
  1281                     }
       
  1282 
       
  1283                 if( aPointerEvent.iType == TPointerEvent::EDrag 
       
  1284                    || aPointerEvent.iType == TPointerEvent::EButtonRepeat )
       
  1285                     {
       
  1286                     // performace improving. Too many drag event received, handling every single event 
       
  1287                     // will use too much CPU time.
       
  1288                     TTime now;
       
  1289                     now.HomeTime();                    
       
  1290                     if ( extension->iDragged &&
       
  1291                          now.MicroSecondsFrom( extension->iLastDrag ) 
       
  1292                          < KScrollDragTimeout )
       
  1293                         {                        
       
  1294                         break; // ignore drag for this time
       
  1295                         }
       
  1296                     extension->iDragged = ETrue; // after this time, iLastDragged has value.
       
  1297                     extension->iLastDrag = now;
       
  1298                     
       
  1299                     thumbPositionPix = position - extension->iPointerOffsetFromThumb;
       
  1300                     TInt oldPosition = thumbPosition;
       
  1301                     TReal newPosition = thumbPositionPix * ( scrollSpan - thumbSpan ) / (TReal)scrollSpanPix;
       
  1302                     thumbPosition = newPosition;
       
  1303 
       
  1304                     // round the value to the nearest possible position
       
  1305                     if( TInt(newPosition * 2) >= ((thumbPosition * 2) + 1 ))
       
  1306                         {
       
  1307                         ++thumbPosition;
       
  1308                         }
       
  1309 
       
  1310                     // enforce limits
       
  1311                     thumbPosition = Max(0, thumbPosition);
       
  1312                     thumbPosition = Min((scrollSpan - thumbSpan), thumbPosition);
       
  1313 
       
  1314                     if(thumbPosition != oldPosition)
       
  1315                         {
       
  1316                         // Smooth continuous tactile feedback is produced
       
  1317                         // during thumb dragging. The tactile feedback API 
       
  1318                         // filters out possible re-startings of the effect.
       
  1319                         MTouchFeedback* feedback = MTouchFeedback::Instance();
       
  1320 
       
  1321                         if ( feedback )
       
  1322                             {
       
  1323                             TTimeIntervalMicroSeconds32 timeout( 300000 );
       
  1324                             feedback->StartFeedback( this, 
       
  1325                                                      ETouchContinuousSlider, 
       
  1326                                                      &aPointerEvent, 
       
  1327                                                      KIntensity, // intensity 50%
       
  1328                                                      timeout );
       
  1329                             }
       
  1330                         extension->SetModelThumbPosition(thumbPosition);
       
  1331                         indicator->SetIndicatorValues(scrollSpan, thumbPosition, thumbSpan, 0, 0);
       
  1332 
       
  1333                         if(indicator->DrawBackgroundState())
       
  1334                             indicator->DrawNow();
       
  1335                         else
       
  1336                             indicator->DrawDeferred();
       
  1337 
       
  1338                         if(extension->ScrollBarObserver())
       
  1339                             {
       
  1340                             extension->ScrollBarObserver()->HandleScrollEventL(
       
  1341                                 this,
       
  1342                                 iOrientation==EHorizontal ? EEikScrollThumbDragHoriz : EEikScrollThumbDragVert);
       
  1343                             }
       
  1344                         }
       
  1345                     // Show popup info
       
  1346                     if ( extension->iShowPopup && extension->iPopupController )
       
  1347                         {
       
  1348                         TPoint infoPoint = PositionRelativeToScreen();
       
  1349 
       
  1350                         if ( iOrientation == EVertical )
       
  1351                             {
       
  1352                             if ( AknLayoutUtils::LayoutMirrored() )
       
  1353                                 {
       
  1354                                 infoPoint.iX += Rect().Width();
       
  1355                                 infoPoint.iY += aPointerEvent.iPosition.iY;
       
  1356                                 extension->iPopupController->SetPositionAndAlignment (
       
  1357                                     infoPoint, EHLeftVCenter );
       
  1358                                 }
       
  1359                             else
       
  1360                                 {
       
  1361                                 infoPoint.iY += aPointerEvent.iPosition.iY;
       
  1362                                 extension->iPopupController->SetPositionAndAlignment (
       
  1363                                     infoPoint, EHRightVCenter );
       
  1364                                 }
       
  1365                             }
       
  1366                         else if ( iOrientation == EHorizontal )
       
  1367                             {
       
  1368                             infoPoint.iX += aPointerEvent.iPosition.iX;
       
  1369                             extension->iPopupController->SetPositionAndAlignment(
       
  1370                                 infoPoint, EHCenterVBottom );
       
  1371                             }
       
  1372                         extension->iPopupController->ShowInfoPopupNote();
       
  1373                         extension->iShowPopup = EFalse;
       
  1374                         }
       
  1375                     }
       
  1376                 break;
       
  1377 
       
  1378             case CEikScrollBar::ENone:
       
  1379                 {
       
  1380                 // Stop the continuous tactile feedback that may be playing
       
  1381                 // at the time due to possible previous thumb dragging.
       
  1382                 MTouchFeedback* feedback = MTouchFeedback::Instance();
       
  1383 
       
  1384                 if ( feedback )
       
  1385                     {
       
  1386                     feedback->StopFeedback( this );
       
  1387                     }
       
  1388                 }
       
  1389 
       
  1390                 if(lastPointerDownOn == CEikScrollBar::EThumb)
       
  1391                     {
       
  1392                     if(extension->ScrollBarObserver())
       
  1393                         {
       
  1394                         extension->ScrollBarObserver()->HandleScrollEventL(
       
  1395                             this,
       
  1396                             iOrientation==EHorizontal ? EEikScrollThumbReleaseHoriz : EEikScrollThumbReleaseVert);
       
  1397                         }
       
  1398 
       
  1399                     }
       
  1400                 break;
       
  1401 
       
  1402             case CEikScrollBar::EIncreaseNudgeButton:
       
  1403                 // handle increase scroll button press (right or down button)
       
  1404                 if(aPointerEvent.iType == TPointerEvent::EButton1Down ||
       
  1405                    aPointerEvent.iType == TPointerEvent::EButtonRepeat)
       
  1406                     {
       
  1407                     TInt oldPosition = thumbPosition;
       
  1408                     thumbPosition++;
       
  1409                     thumbPosition = Min((scrollSpan - thumbSpan), thumbPosition);
       
  1410 
       
  1411                     if(oldPosition != thumbPosition)
       
  1412                         {
       
  1413                         // Note: Depending on layout and style the nudge
       
  1414                         //       button may be obsolete.
       
  1415                         // Sensitive feedback given for each "nudge"
       
  1416                         MTouchFeedback* feedback = MTouchFeedback::Instance();
       
  1417                         if ( feedback )
       
  1418                             {
       
  1419                             feedback->InstantFeedback ( this, ETouchFeedbackSlider, aPointerEvent );
       
  1420                             }
       
  1421                         extension->SetModelThumbPosition(thumbPosition);
       
  1422                         indicator->SetIndicatorValues(scrollSpan, thumbPosition, thumbSpan, 0, 0);
       
  1423                         if(indicator->DrawBackgroundState())
       
  1424                             indicator->DrawNow();
       
  1425                         else
       
  1426                             indicator->DrawDeferred();
       
  1427                         }
       
  1428 
       
  1429                     // even if the thumb position did not change (thumb has reached its last
       
  1430                     // possible position), we must send the event
       
  1431                     // to the observer, so that it can implement the looping scrolling if necessary
       
  1432                     if(extension->ScrollBarObserver())
       
  1433                         {
       
  1434                         extension->ScrollBarObserver()->HandleScrollEventL(
       
  1435                             this,
       
  1436                             iOrientation==EHorizontal ? EEikScrollRight : EEikScrollDown);
       
  1437                         }
       
  1438                     // repeat untill stylus is lifted or dragged outside the button
       
  1439                     TRect nudgeRect( iButtons.iIncreaseNudge->Rect() );
       
  1440 
       
  1441                     pointerWindow->RequestPointerRepeatEvent(KScrollRepeatTimeout, nudgeRect );
       
  1442                     }
       
  1443 
       
  1444                 break;
       
  1445 
       
  1446             case CEikScrollBar::EDecreaseNudgeButton:
       
  1447                 // handle decrease scroll button press (left or up button)
       
  1448                 if(aPointerEvent.iType == TPointerEvent::EButton1Down ||
       
  1449                    aPointerEvent.iType == TPointerEvent::EButtonRepeat)
       
  1450                     {
       
  1451                     TInt oldPosition = thumbPosition;
       
  1452                     thumbPosition--;
       
  1453                     thumbPosition = Max(0, thumbPosition);
       
  1454                     if(oldPosition != thumbPosition)
       
  1455                         {
       
  1456                         // Note: Depending on layout and style the nudge
       
  1457                         //       button may be obsolete.
       
  1458                         // Sensitive feedback given for each "nudge"
       
  1459                         MTouchFeedback* feedback = MTouchFeedback::Instance();
       
  1460                         if ( feedback )
       
  1461                             {
       
  1462                             feedback->InstantFeedback ( this, ETouchFeedbackSlider, aPointerEvent );
       
  1463                             }
       
  1464                         extension->SetModelThumbPosition(thumbPosition);
       
  1465                         indicator->SetIndicatorValues(scrollSpan, thumbPosition, thumbSpan, 0, 0);
       
  1466                         if(indicator->DrawBackgroundState())
       
  1467                             indicator->DrawNow();
       
  1468                         else
       
  1469                             indicator->DrawDeferred();
       
  1470                         }
       
  1471 
       
  1472                     // even if the thumb position did not change (thumb has reached its first
       
  1473                     // possible position), we must send the event
       
  1474                     // to the observer, so that it can implement the looping scrolling if necessary
       
  1475                     if(extension->ScrollBarObserver())
       
  1476                         {
       
  1477                         extension->ScrollBarObserver()->HandleScrollEventL(
       
  1478                             this,
       
  1479                             iOrientation==EHorizontal ? EEikScrollLeft : EEikScrollUp);
       
  1480                         }
       
  1481                     // repeat untill stylus is lifted or dragged outside the button
       
  1482                     TRect nudgeRect( iButtons.iDecreaseNudge->Rect() );
       
  1483 
       
  1484                     pointerWindow->RequestPointerRepeatEvent(KScrollRepeatTimeout, nudgeRect );
       
  1485                     }
       
  1486 
       
  1487                 break;
       
  1488 
       
  1489             default:
       
  1490                 break;
       
  1491 
       
  1492             } // end: of switch
       
  1493 
       
  1494         } // end of: if (thumbSpan < scrollSpan)
       
  1495     }
       
  1496 
       
  1497 EXPORT_C void* CAknDoubleSpanScrollBar::ExtensionInterface( TUid /*aInterface*/ )
       
  1498     {
       
  1499     return NULL;
       
  1500     }
       
  1501 
       
  1502 EXPORT_C void CAknDoubleSpanScrollBar::SetFixedLayoutRect(TRect aScrollBarRect)
       
  1503     {
       
  1504     if (iExtension)
       
  1505         {
       
  1506         CAknDoubleSpanScrollBarExtension* extension = static_cast<CAknDoubleSpanScrollBarExtension*> (iExtension);
       
  1507         extension->iFixedLayoutRect = aScrollBarRect;
       
  1508         SetRect(aScrollBarRect);
       
  1509         }
       
  1510     }
       
  1511 
       
  1512 EXPORT_C void CAknDoubleSpanScrollBar::SetScrollPopupInfoTextL( const TDesC& aText )
       
  1513     {
       
  1514     if ( !AknLayoutUtils::PenEnabled() )
       
  1515         {
       
  1516         return;
       
  1517         }
       
  1518 
       
  1519     if ( iExtension )
       
  1520         {
       
  1521         CAknDoubleSpanScrollBarExtension* extension = static_cast<CAknDoubleSpanScrollBarExtension*> (iExtension);
       
  1522 
       
  1523         if ( extension->iPopupController )
       
  1524             {
       
  1525             if ( aText.Length() > 0 )
       
  1526                 {
       
  1527                 extension->iPopupController->SetTextL( aText );
       
  1528                 extension->iShowPopup = ETrue;
       
  1529                 }
       
  1530             else
       
  1531                 {
       
  1532                 extension->iPopupController->HideInfoPopupNote();
       
  1533                 extension->iShowPopup = EFalse;
       
  1534                 }
       
  1535             }
       
  1536         }
       
  1537     }
       
  1538 
       
  1539 TRect CAknDoubleSpanScrollBar::FixedLayoutRect()
       
  1540     {
       
  1541     TRect fixedLayoutRect;
       
  1542     if (iExtension)
       
  1543         {
       
  1544         CAknDoubleSpanScrollBarExtension* extension = static_cast<CAknDoubleSpanScrollBarExtension*> (iExtension);
       
  1545         fixedLayoutRect = extension->iFixedLayoutRect;
       
  1546         }
       
  1547     return fixedLayoutRect;
       
  1548     }
       
  1549 
       
  1550 void CAknDoubleSpanScrollBar::SetTransparentBackground(TBool aTransparentBackground)
       
  1551     {
       
  1552     // In transparency-enabled builds, consider making this function
       
  1553     // act as if DrawBackground( EFalse ) was called..
       
  1554 
       
  1555     TBool transparencyIsSupported = EFalse; // Transparent windows are not supported for now
       
  1556 
       
  1557     if (iExtension && OwnsWindow() && transparencyIsSupported)
       
  1558         {
       
  1559         CAknDoubleSpanScrollBarExtension* extension = static_cast<CAknDoubleSpanScrollBarExtension*> (iExtension);
       
  1560         CAknDoubleSpanScrollIndicator* indicator = extension->iScrollIndicator;
       
  1561 
       
  1562         if (aTransparentBackground)
       
  1563             {
       
  1564             // removed old transparency related code
       
  1565             }
       
  1566         else
       
  1567             {
       
  1568             Window().SetNonTransparent();
       
  1569             }
       
  1570 
       
  1571         indicator->SetTransparentBackground(aTransparentBackground);
       
  1572 
       
  1573         }
       
  1574 
       
  1575     }
       
  1576 
       
  1577 TBool CAknDoubleSpanScrollBar::DrawBackgroundState()
       
  1578     {
       
  1579     CAknDoubleSpanScrollBarExtension* extension = static_cast<CAknDoubleSpanScrollBarExtension*> (iExtension);
       
  1580     CAknDoubleSpanScrollIndicator* indicator = extension->iScrollIndicator;
       
  1581 
       
  1582     return indicator->DrawBackgroundState();
       
  1583     }
       
  1584 
       
  1585 void CAknDoubleSpanScrollBar::DrawBackground(TBool aDraw)
       
  1586     {
       
  1587     CAknDoubleSpanScrollBarExtension* extension = static_cast<CAknDoubleSpanScrollBarExtension*> (iExtension);
       
  1588     CAknDoubleSpanScrollIndicator* indicator = extension->iScrollIndicator;
       
  1589 
       
  1590     indicator->SetDrawBackgroundState(aDraw);
       
  1591     }
       
  1592 
       
  1593 
       
  1594 // ---------------------------------------------------------------------------
       
  1595 // CAknDoubleSpanScrollBar::ResetPressedDownHighlight
       
  1596 // ---------------------------------------------------------------------------
       
  1597 //
       
  1598 void CAknDoubleSpanScrollBar::ResetPressedDownHighlight()
       
  1599     {
       
  1600     CAknDoubleSpanScrollBarExtension* extension =
       
  1601         static_cast<CAknDoubleSpanScrollBarExtension*>( iExtension );
       
  1602         
       
  1603     CAknDoubleSpanScrollIndicator* indicator = extension->iScrollIndicator;
       
  1604     
       
  1605     indicator->SetHandleHighlight( EFalse );
       
  1606     }
       
  1607 
       
  1608 
       
  1609 //
       
  1610 // class CAknDoubleSpanScrollBarExtension
       
  1611 //
       
  1612 
       
  1613 CAknDoubleSpanScrollBarExtension::CAknDoubleSpanScrollBarExtension(CEikScrollBar* aParent)
       
  1614 : iExternalFrames(1), iActiveScheduledDraw(NULL)
       
  1615     {
       
  1616     iParent=aParent;
       
  1617     }
       
  1618 
       
  1619 CAknDoubleSpanScrollBarExtension::~CAknDoubleSpanScrollBarExtension()
       
  1620     {
       
  1621     delete iScrollIndicator;
       
  1622     iScrollIndicator = NULL;
       
  1623 
       
  1624     if ( iPopupController )
       
  1625         {
       
  1626         delete iPopupController;
       
  1627         iPopupController = NULL;
       
  1628         }
       
  1629 
       
  1630     if(iActiveScheduledDraw && iActiveScheduledDraw->IsActive())
       
  1631         iActiveScheduledDraw->Cancel();
       
  1632 
       
  1633     delete iActiveScheduledDraw;
       
  1634     }
       
  1635 
       
  1636 
       
  1637 void CAknDoubleSpanScrollBarExtension::SetLengthL(TInt /*aLength*/)
       
  1638     {
       
  1639     }
       
  1640 
       
  1641 void CAknDoubleSpanScrollBarExtension::SetModelL(const TEikScrollBarModel* /*aModel*/)
       
  1642     {
       
  1643     }
       
  1644 
       
  1645 void CAknDoubleSpanScrollBarExtension::SetModel(const TEikScrollBarModel* /*aModel*/)
       
  1646     {
       
  1647     }
       
  1648 
       
  1649 void CAknDoubleSpanScrollBarExtension::SetLengthAndModelL(TInt /*aLength*/,const TEikScrollBarModel* /*aModel*/)
       
  1650     {
       
  1651     }
       
  1652 
       
  1653 // ----------------------------------------------------------------------------
       
  1654 // CAknDoubleSpanScrollBarExtension::SetModelThumbPosition
       
  1655 // Sets the thumb position to the model. This function has to be used because
       
  1656 // CAknDoubleSpanScrollBar does not have direct access to the model.
       
  1657 // ----------------------------------------------------------------------------
       
  1658 //
       
  1659 void CAknDoubleSpanScrollBarExtension::SetModelThumbPosition(TInt aThumbPos)
       
  1660     {
       
  1661     if( !AknLayoutUtils::PenEnabled() )
       
  1662         {
       
  1663         return;
       
  1664         }
       
  1665 
       
  1666     if (iParent->iModel.ScrollBarModelType() == TEikScrollBarModel::EAknDoubleSpanScrollBarModel)
       
  1667         {
       
  1668         static_cast <TAknDoubleSpanScrollBarModel*> (&iParent->iModel)->SetFocusPosition(aThumbPos);
       
  1669         }
       
  1670     else
       
  1671         {
       
  1672         // Incorrect model is used, but in most cases we can work with the TEikScrollBarModel model.
       
  1673         iParent->iModel.iThumbPosition = aThumbPos;
       
  1674         }
       
  1675     }
       
  1676 
       
  1677 void CAknDoubleSpanScrollBarExtension::SetFocusPosToThumbPos(TInt /*aFocusPosition*/)
       
  1678     {
       
  1679     }
       
  1680 
       
  1681 TInt CAknDoubleSpanScrollBarExtension::ThumbPosition() const
       
  1682     {
       
  1683     if (iParent->iModel.ScrollBarModelType() == TEikScrollBarModel::EAknDoubleSpanScrollBarModel)
       
  1684         {
       
  1685         if( AknLayoutUtils::PenEnabled() )
       
  1686             {
       
  1687             // it is more effective to cast the pointer and use it directly
       
  1688             // than creating a copy of the model just to return a value
       
  1689             return static_cast <TAknDoubleSpanScrollBarModel*> (&iParent->iModel)->FocusPosition();
       
  1690             }
       
  1691         else
       
  1692             {
       
  1693             TAknDoubleSpanScrollBarModel& model = static_cast <TAknDoubleSpanScrollBarModel&> (iParent->iModel);
       
  1694             return model.FocusPosition();
       
  1695             }
       
  1696         }
       
  1697     else
       
  1698         {
       
  1699             // Error. User of the API is perhaps assigning values directly to TEikScrollBarModel
       
  1700             // member variables which is not allowed with EAknDoubleSpanScrollBarModel.
       
  1701             // #ifdef _DEBUG
       
  1702             // RDebug::Print(_L("CAknDoubleSpanScrollBarExtension: Please, use TAknDoubleSpanScrollBarModel instead of TEikScrollBarModel"));
       
  1703             // #endif
       
  1704             // In most cases we can work with the TEikScrollBarModel model.
       
  1705             return iParent->iModel.iThumbPosition;
       
  1706         }
       
  1707     }
       
  1708 
       
  1709 TInt CAknDoubleSpanScrollBarExtension::ScrollBarBreadth() const
       
  1710     {
       
  1711     if (iScrollIndicator)
       
  1712         return iScrollIndicator->IndicatorWidth();
       
  1713     else
       
  1714         return KAknDoubleSpanScrollBarWidth;
       
  1715     }
       
  1716 
       
  1717 void CAknDoubleSpanScrollBarExtension::SetDecreaseButtonsDimmed(TBool /*aDimmed*/)
       
  1718     {
       
  1719     }
       
  1720 
       
  1721 void CAknDoubleSpanScrollBarExtension::SetIncreaseButtonsDimmed(TBool /*aDimmed*/)
       
  1722     {
       
  1723     }
       
  1724 
       
  1725 void CAknDoubleSpanScrollBarExtension::SetAllButtonsDimmed(TBool /*aDimmed*/)
       
  1726     {
       
  1727     }
       
  1728 
       
  1729 void CAknDoubleSpanScrollBarExtension::SetContainingCba(CEikCba* /*aCba*/)
       
  1730     {
       
  1731     // Not needed in this type of scrollbar
       
  1732     }
       
  1733 
       
  1734 TInt CAknDoubleSpanScrollBarExtension::ScrollBarType()
       
  1735     {
       
  1736     return CEikScrollBarFrame::EDoubleSpan;
       
  1737     }
       
  1738 
       
  1739 void CAknDoubleSpanScrollBarExtension::CreateButtonL(CAknScrollButton*& /*aButton*/,CAknScrollButton::TType /*aType*/)
       
  1740     {
       
  1741     }
       
  1742 
       
  1743 void CAknDoubleSpanScrollBarExtension::DoSetModel(const TEikScrollBarModel* aModel)
       
  1744     {
       
  1745     iParent->iModel=(*aModel);
       
  1746     if (iScrollIndicator)
       
  1747         {
       
  1748         if (aModel->ScrollBarModelType() == TEikScrollBarModel::EAknDoubleSpanScrollBarModel)
       
  1749             {
       
  1750             const TAknDoubleSpanScrollBarModel* model = static_cast <const TAknDoubleSpanScrollBarModel*> (aModel);
       
  1751 
       
  1752             iScrollIndicator->SetIndicatorValues(model->ScrollSpan(),
       
  1753                 model->FocusPosition(),
       
  1754                 model->WindowSize(),
       
  1755                 model->FieldPosition(),
       
  1756                 model->FieldSize());
       
  1757             }
       
  1758         else
       
  1759             {
       
  1760             // Error. User of the API is perhaps assigning values directly to TEikScrollBarModel
       
  1761             // member variables which is not allowed with TAknDoubleSpanScrollBarModel.
       
  1762             // #ifdef _DEBUG
       
  1763             // RDebug::Print(_L("CAknDoubleSpanScrollBarExtension: Please, use TAknDoubleSpanScrollBarModel instead of TEikScrollBarModel"));
       
  1764             // #endif
       
  1765             // In most cases we can work with the TEikScrollBarModel model.
       
  1766             iScrollIndicator->SetIndicatorValues(aModel->iScrollSpan,
       
  1767                 aModel->iThumbPosition,
       
  1768                 aModel->iThumbSpan,
       
  1769                 0,
       
  1770                 0);
       
  1771             }
       
  1772 
       
  1773         if (iParent->OwnsWindow() && iScrollIndicator->TransparentBackground())
       
  1774             {
       
  1775             iParent->Window().HandleTransparencyUpdate();
       
  1776             }
       
  1777         if(iScrollIndicator->IsVisible())
       
  1778             {
       
  1779             if(iScrollIndicator->DrawBackgroundState() && !iParent->OwnsWindow())
       
  1780                 {
       
  1781                 if(HasModelChanged(aModel))
       
  1782                     {
       
  1783                     TInt err = KErrNone;
       
  1784                     if(!iActiveScheduledDraw) // create if not initialized
       
  1785                         TRAP(err, iActiveScheduledDraw = CIdle::NewL(EPriorityHigh));
       
  1786                     if(!err && !iActiveScheduledDraw->IsActive())
       
  1787                         iActiveScheduledDraw->Start(TCallBack(ScheduledDraw,this));
       
  1788                     }
       
  1789                 }
       
  1790             else
       
  1791                 {
       
  1792                 iParent->DrawDeferred();                 
       
  1793                 }
       
  1794 
       
  1795             }
       
  1796         }
       
  1797     }
       
  1798 
       
  1799 TBool CAknDoubleSpanScrollBarExtension::HasModelChanged(const TEikScrollBarModel* aModel)
       
  1800     {
       
  1801     if(iPreviousModel.ScrollBarModelType() == TEikScrollBarModel::EAknDoubleSpanScrollBarModel &&
       
  1802         aModel->ScrollBarModelType() == TEikScrollBarModel::EAknDoubleSpanScrollBarModel)
       
  1803         {
       
  1804         TAknDoubleSpanScrollBarModel* previousModel = static_cast<TAknDoubleSpanScrollBarModel*> (&iPreviousModel);
       
  1805         const TAknDoubleSpanScrollBarModel* model = static_cast<const TAknDoubleSpanScrollBarModel*> (aModel);
       
  1806         if(previousModel->ScrollSpan() != model->ScrollSpan() ||
       
  1807         previousModel->FocusPosition() != model->FocusPosition() ||
       
  1808         previousModel->WindowSize() != model->WindowSize() ||
       
  1809         previousModel->FieldPosition() != model->FieldPosition() ||
       
  1810         previousModel->FieldSize() != model->FieldSize())
       
  1811             {
       
  1812             iPreviousModel = *aModel;
       
  1813             return ETrue;
       
  1814             }
       
  1815         }
       
  1816     else if(iPreviousModel.ScrollBarModelType() == TEikScrollBarModel::EEikScrollBarModel &&
       
  1817         aModel->ScrollBarModelType() == TEikScrollBarModel::EAknDoubleSpanScrollBarModel)
       
  1818         {
       
  1819         const TAknDoubleSpanScrollBarModel* model = static_cast<const TAknDoubleSpanScrollBarModel*> (aModel);
       
  1820         if(iPreviousModel.iScrollSpan != model->ScrollSpan() ||
       
  1821         iPreviousModel.iThumbPosition != model->FocusPosition() ||
       
  1822         iPreviousModel.iThumbSpan != model->WindowSize())
       
  1823             {
       
  1824             iPreviousModel = *aModel;
       
  1825             return ETrue;
       
  1826             }
       
  1827         }
       
  1828     else if(iPreviousModel.ScrollBarModelType() == TEikScrollBarModel::EAknDoubleSpanScrollBarModel &&
       
  1829         aModel->ScrollBarModelType() == TEikScrollBarModel::EEikScrollBarModel)
       
  1830         {
       
  1831         TAknDoubleSpanScrollBarModel* previousModel = static_cast<TAknDoubleSpanScrollBarModel*> (&iPreviousModel);
       
  1832         if(previousModel->ScrollSpan() != aModel->iScrollSpan ||
       
  1833         previousModel->FocusPosition() != aModel->iThumbPosition ||
       
  1834         previousModel->WindowSize() != aModel->iThumbSpan)
       
  1835             {
       
  1836             iPreviousModel = *aModel;
       
  1837             return ETrue;
       
  1838             }
       
  1839         }
       
  1840     else
       
  1841         {
       
  1842         if(iPreviousModel.iScrollSpan != aModel->iScrollSpan ||
       
  1843         iPreviousModel.iThumbPosition != aModel->iThumbPosition ||
       
  1844         iPreviousModel.iThumbSpan != aModel->iThumbSpan)
       
  1845             {
       
  1846             iPreviousModel = *aModel;
       
  1847             return ETrue;
       
  1848             }
       
  1849         }
       
  1850     iPreviousModel = *aModel;
       
  1851     return EFalse;
       
  1852     }
       
  1853 
       
  1854 CEikCba* CAknDoubleSpanScrollBarExtension::Cba() const
       
  1855     {
       
  1856     return NULL; // Not needed in this type of scrollbar
       
  1857     }
       
  1858 
       
  1859 void CAknDoubleSpanScrollBarExtension::AddExternalFrameL(CEikScrollBarFrame* aFrame)
       
  1860     {
       
  1861     iExternalFrames.AppendL(aFrame);
       
  1862     iScrollBarObserver = aFrame->ScrollBarFrameObserver();
       
  1863     }
       
  1864 
       
  1865 
       
  1866 void CAknDoubleSpanScrollBarExtension::RemoveExternalFrame(CEikScrollBarFrame* aFrame)
       
  1867     {
       
  1868     TInt count = iExternalFrames.Count();
       
  1869     for (TInt ii=count-1; ii>=0; ii--)
       
  1870         {
       
  1871         if (iExternalFrames[ii] == aFrame)
       
  1872             {
       
  1873             iExternalFrames[ii]->DisconnectExternalScrollBar(iParent);
       
  1874             iExternalFrames.Delete(ii);
       
  1875             }
       
  1876         }
       
  1877 
       
  1878     count = iExternalFrames.Count();
       
  1879     if(count == 0) //no externally owned anymore
       
  1880         {
       
  1881         iScrollBarObserver = iOwningScrollBarObserver;
       
  1882         }
       
  1883     else // set the next external frame as observer
       
  1884         {
       
  1885         iScrollBarObserver = iExternalFrames[(count - 1)]->ScrollBarFrameObserver();
       
  1886         }
       
  1887     }
       
  1888 
       
  1889 void CAknDoubleSpanScrollBarExtension::DisconnectExternalFrames()
       
  1890     {
       
  1891     TInt count = iExternalFrames.Count();
       
  1892     for (TInt ii=count-1; ii>=0; ii--)
       
  1893         {
       
  1894         iExternalFrames[ii]->DisconnectExternalScrollBar(iParent);
       
  1895         }
       
  1896     iExternalFrames.Reset();
       
  1897     }
       
  1898 
       
  1899 void CAknDoubleSpanScrollBarExtension::CreateRequiredComponentsL()
       
  1900     {
       
  1901     if ( !iScrollIndicator )
       
  1902         {
       
  1903         iScrollIndicator = CAknDoubleSpanScrollIndicator::NewL( iParent->iOrientation );
       
  1904         iScrollIndicator->SetContainerWindowL( *iParent );
       
  1905         iScrollIndicator->SetRect( iParent->Rect() );
       
  1906         iScrollIndicator->SetComponentsToInheritVisibility(ETrue);
       
  1907         }
       
  1908 
       
  1909     if ( AknLayoutUtils::PenEnabled() &&
       
  1910         ( iScrollBarFlags & CEikScrollBar::EEnableNudgeButtons ) )
       
  1911         {
       
  1912         TBool horiz=(iParent->iOrientation == CEikScrollBar::EHorizontal);
       
  1913 
       
  1914         if ( !iParent->iButtons.iDecreaseNudge )
       
  1915             {
       
  1916             iParent->CreateButtonL(iParent->iButtons.iDecreaseNudge,horiz ? CAknScrollButton::ENudgeLeft : CAknScrollButton::ENudgeUp);
       
  1917             }
       
  1918 
       
  1919         if ( !iParent->iButtons.iIncreaseNudge )
       
  1920             {
       
  1921             iParent->CreateButtonL(iParent->iButtons.iIncreaseNudge,horiz ? CAknScrollButton::ENudgeRight : CAknScrollButton::ENudgeDown);
       
  1922             }
       
  1923         }
       
  1924     }
       
  1925 
       
  1926 void CAknDoubleSpanScrollBarExtension::DestroyButton(CAknScrollButton*& /*aButton*/)
       
  1927     {
       
  1928     }
       
  1929 
       
  1930 void CAknDoubleSpanScrollBarExtension::SetButtonPositionL(CAknScrollButton* /*aButton*/)
       
  1931     {
       
  1932     }
       
  1933 
       
  1934 void CAknDoubleSpanScrollBarExtension::SetScrollBarObserver(MEikScrollBarObserver* aScrollBarObserver)
       
  1935     {
       
  1936     iScrollBarObserver = aScrollBarObserver;
       
  1937 
       
  1938     if(iExternalFrames.Count() == 0)
       
  1939         {
       
  1940         iOwningScrollBarObserver = aScrollBarObserver;
       
  1941         }
       
  1942     }
       
  1943 
       
  1944 MEikScrollBarObserver* CAknDoubleSpanScrollBarExtension::ScrollBarObserver()
       
  1945     {
       
  1946     return iScrollBarObserver;
       
  1947     }
       
  1948 
       
  1949 TInt CAknDoubleSpanScrollBarExtension::ScheduledDraw( TAny* aThis )
       
  1950     {
       
  1951     static_cast<CAknDoubleSpanScrollBarExtension*>( aThis )->DoScheduledDraw();
       
  1952     return 0;
       
  1953     }
       
  1954 
       
  1955 void CAknDoubleSpanScrollBarExtension::DoScheduledDraw()
       
  1956     {
       
  1957     if(iParent)
       
  1958         iParent->DrawNow();
       
  1959     }
       
  1960 
       
  1961 
       
  1962 TInt CAknDoubleSpanScrollBarExtension::Reserved_1(){return 0;};
       
  1963 TInt CAknDoubleSpanScrollBarExtension::Reserved_2(){return 0;};
       
  1964 
       
  1965 
       
  1966 //
       
  1967 // TAknDoubleSpanScrollBarModel class
       
  1968 //
       
  1969 //
       
  1970 // This class stores its own model in its base class (TEikScrollBarModel)
       
  1971 // member variables as following:
       
  1972 //
       
  1973 //
       
  1974 // bits 31 to 0
       
  1975 //
       
  1976 // ZZAAAAAAAAAAAAA BBBBBBBBBBBBBBBB   (iScrollSpane)
       
  1977 // CCCCCCCCCCCCCCC DDDDDDDDDDDDDDDD   (iThumbSpan)
       
  1978 // EEEEEEEEEEEEEEE FFFFFFFFFFFFFFFF   (iThumbPosition)
       
  1979 //
       
  1980 // Bits ZZ = model type.
       
  1981 //           00 EikScrollBarModel
       
  1982 //           11 EikScrollBarModel
       
  1983 //           10 TAknDoubleSpanScrollBarModel
       
  1984 //           01 Reserved for future
       
  1985 //
       
  1986 // Bits   AAAAAAAAAAAAA = scale
       
  1987 // Bits BBBBBBBBBBBBBBB = scroll span
       
  1988 // Bits CCCCCCCCCCCCCCC = focus position
       
  1989 // Bits DDDDDDDDDDDDDDD = field position
       
  1990 // Bits EEEEEEEEEEEEEEE = field size
       
  1991 // Bits FFFFFFFFFFFFFFF = window size
       
  1992 //
       
  1993 //
       
  1994 // Reason for this solution is to preserve binary compatibility with the old model.
       
  1995 //
       
  1996 // If this model is not supported by the scrollbar system, then values are stored
       
  1997 // as in the base class for compatibility resons.
       
  1998 
       
  1999 EXPORT_C TAknDoubleSpanScrollBarModel::TAknDoubleSpanScrollBarModel()
       
  2000     {
       
  2001     if (ModelIsSupported())
       
  2002         {
       
  2003         SetScrollBarModelType(EAknDoubleSpanScrollBarModel);
       
  2004         SetScale(KDoubleSpanMinScaleValue);
       
  2005         SetScrollSpanValue(0);
       
  2006         SetFocusPositionValue(0);
       
  2007         SetFieldPositionValue(0);
       
  2008         SetFieldSizeValue(0);
       
  2009         SetWindowSizeValue(0);
       
  2010         }
       
  2011     else
       
  2012         {
       
  2013         iScrollSpan = 0;
       
  2014         iThumbSpan = 0;
       
  2015         iThumbPosition = 0;
       
  2016         }
       
  2017     }
       
  2018 
       
  2019 EXPORT_C TAknDoubleSpanScrollBarModel::TAknDoubleSpanScrollBarModel(const TEikScrollBarModel& aEikModel)
       
  2020     {
       
  2021 
       
  2022     if(aEikModel.ScrollBarModelType() == EAknDoubleSpanScrollBarModel)
       
  2023         {
       
  2024         const TAknDoubleSpanScrollBarModel* model = static_cast <const TAknDoubleSpanScrollBarModel*> (&aEikModel);
       
  2025 
       
  2026         // if parameter is
       
  2027         if (model->ModelIsSupported())
       
  2028             {
       
  2029             iScrollSpan = aEikModel.iScrollSpan;
       
  2030             iThumbSpan = aEikModel.iThumbSpan;
       
  2031             iThumbPosition = aEikModel.iThumbPosition;
       
  2032             }
       
  2033         else if(!ModelIsSupported() && model->ModelIsSupported())
       
  2034             {
       
  2035             SetScrollBarModelType(EAknDoubleSpanScrollBarModel);
       
  2036             SetScale(KDoubleSpanMinScaleValue);
       
  2037             SetScrollSpan(CheckMinMaxValue(model->ScrollSpan()));
       
  2038             SetFocusPosition(CheckMinMaxValue(model->FocusPosition()));
       
  2039             SetWindowSize(CheckMinMaxValue(model->WindowSize()));
       
  2040             SetFieldPositionValue(0);
       
  2041             SetFieldSizeValue(0);
       
  2042             }
       
  2043         }
       
  2044     // if parameter is only eikscb
       
  2045     else if(ModelIsSupported() && aEikModel.ScrollBarModelType() == EEikScrollBarModel)
       
  2046         {
       
  2047         SetScrollBarModelType(EAknDoubleSpanScrollBarModel);
       
  2048         SetScale(KDoubleSpanMinScaleValue);
       
  2049         SetScrollSpan(CheckMinMaxValue(aEikModel.iScrollSpan));
       
  2050         SetFocusPosition(CheckMinMaxValue(aEikModel.iThumbPosition));
       
  2051         SetWindowSize(CheckMinMaxValue(aEikModel.iThumbSpan));
       
  2052         SetFieldPositionValue(0);
       
  2053         SetFieldSizeValue(0);
       
  2054         }
       
  2055     else
       
  2056         {
       
  2057         SetScrollBarModelType(EAknDoubleSpanScrollBarModel);
       
  2058         SetScale(KDoubleSpanMinScaleValue);
       
  2059         SetScrollSpan(CheckMinMaxValue(aEikModel.iScrollSpan));
       
  2060         SetFocusPosition(CheckMinMaxValue(aEikModel.iThumbPosition));
       
  2061         SetWindowSize(CheckMinMaxValue(aEikModel.iThumbSpan));
       
  2062         SetFieldPositionValue(0);
       
  2063         SetFieldSizeValue(0);
       
  2064         }
       
  2065     }
       
  2066 
       
  2067 
       
  2068 EXPORT_C TInt TAknDoubleSpanScrollBarModel::ScrollSpan() const
       
  2069     {
       
  2070     if (ModelIsSupported())
       
  2071         {
       
  2072         // Assert that API user has not set TEikScrollBarModel values directly
       
  2073         __ASSERT_ALWAYS(ScrollBarModelType() == EAknDoubleSpanScrollBarModel,Panic(EEikPanicOutOfRange));
       
  2074         return Scale() * ScrollSpanValue();
       
  2075         }
       
  2076     else
       
  2077         {
       
  2078         return iScrollSpan;
       
  2079         }
       
  2080     }
       
  2081 
       
  2082 EXPORT_C void TAknDoubleSpanScrollBarModel::SetScrollSpan(TInt aScrollSpan)
       
  2083     {
       
  2084     if (ModelIsSupported())
       
  2085         {
       
  2086         // Assert that API user has not set TEikScrollBarModel values directly
       
  2087         __ASSERT_ALWAYS(ScrollBarModelType() == EAknDoubleSpanScrollBarModel,Panic(EEikPanicOutOfRange));
       
  2088         SetScrollSpanValue(PrepareScaledValue(CheckMinMaxValue(aScrollSpan)));
       
  2089         }
       
  2090     else
       
  2091         {
       
  2092         iScrollSpan = aScrollSpan;
       
  2093         }
       
  2094     }
       
  2095 
       
  2096 EXPORT_C TInt TAknDoubleSpanScrollBarModel::FocusPosition() const
       
  2097     {
       
  2098     if (ModelIsSupported())
       
  2099         {
       
  2100         // Assert that API user has not set TEikScrollBarModel values directly
       
  2101         __ASSERT_ALWAYS(ScrollBarModelType() == EAknDoubleSpanScrollBarModel,Panic(EEikPanicOutOfRange));
       
  2102         return Scale() * FocusPositionValue();
       
  2103         }
       
  2104     else
       
  2105         {
       
  2106         return iThumbPosition;
       
  2107         }
       
  2108     }
       
  2109 
       
  2110 EXPORT_C void TAknDoubleSpanScrollBarModel::SetFocusPosition(TInt aFocusPosition)
       
  2111     {
       
  2112     if (ModelIsSupported())
       
  2113         {
       
  2114         // Assert that API user has not set TEikScrollBarModel values directly
       
  2115         __ASSERT_ALWAYS(ScrollBarModelType() == EAknDoubleSpanScrollBarModel,Panic(EEikPanicOutOfRange));
       
  2116         SetFocusPositionValue(PrepareScaledValue(CheckMinMaxValue(aFocusPosition)));
       
  2117         }
       
  2118     else
       
  2119         {
       
  2120         iThumbPosition = aFocusPosition;
       
  2121         }
       
  2122     }
       
  2123 
       
  2124 EXPORT_C TInt TAknDoubleSpanScrollBarModel::FieldPosition() const
       
  2125     {
       
  2126     if (ModelIsSupported())
       
  2127         {
       
  2128         // Assert that API user has not set TEikScrollBarModel values directly
       
  2129         __ASSERT_ALWAYS(ScrollBarModelType() == EAknDoubleSpanScrollBarModel,Panic(EEikPanicOutOfRange));
       
  2130         return Scale() * FieldPositionValue();
       
  2131         }
       
  2132     else
       
  2133         {
       
  2134         return 0;
       
  2135         }
       
  2136     }
       
  2137 
       
  2138 EXPORT_C void TAknDoubleSpanScrollBarModel::SetFieldPosition(TInt aFieldPosition)
       
  2139     {
       
  2140     if (ModelIsSupported())
       
  2141         {
       
  2142         // Assert that API user has not set TEikScrollBarModel values directly
       
  2143         __ASSERT_ALWAYS(ScrollBarModelType() == EAknDoubleSpanScrollBarModel,Panic(EEikPanicOutOfRange));
       
  2144         SetFieldPositionValue(PrepareScaledValue(CheckMinMaxValue(aFieldPosition)));
       
  2145         }
       
  2146     else
       
  2147         {
       
  2148         // do nothing
       
  2149         }
       
  2150     }
       
  2151 
       
  2152 EXPORT_C TInt TAknDoubleSpanScrollBarModel::FieldSize() const
       
  2153     {
       
  2154     if (ModelIsSupported())
       
  2155         {
       
  2156         // Assert that API user has not set TEikScrollBarModel values directly
       
  2157         __ASSERT_ALWAYS(ScrollBarModelType() == EAknDoubleSpanScrollBarModel,Panic(EEikPanicOutOfRange));
       
  2158         return Scale() * FieldSizeValue();
       
  2159         }
       
  2160     else
       
  2161         {
       
  2162         return 0;
       
  2163         }
       
  2164     }
       
  2165 
       
  2166 EXPORT_C void TAknDoubleSpanScrollBarModel::SetFieldSize(TInt aFieldSize)
       
  2167     {
       
  2168     if (ModelIsSupported())
       
  2169         {
       
  2170         // Assert that API user has not set TEikScrollBarModel values directly
       
  2171         __ASSERT_ALWAYS(ScrollBarModelType() == EAknDoubleSpanScrollBarModel,Panic(EEikPanicOutOfRange));
       
  2172         SetFieldSizeValue(PrepareScaledValue(CheckMinMaxValue(aFieldSize)));
       
  2173         }
       
  2174     else
       
  2175         {
       
  2176         // do nothing
       
  2177         }
       
  2178     }
       
  2179 
       
  2180 EXPORT_C TInt TAknDoubleSpanScrollBarModel::WindowSize() const
       
  2181     {
       
  2182     if (ModelIsSupported())
       
  2183         {
       
  2184         // Assert that API user has not set TEikScrollBarModel values directly
       
  2185         __ASSERT_ALWAYS(ScrollBarModelType() == EAknDoubleSpanScrollBarModel,Panic(EEikPanicOutOfRange));
       
  2186         return Scale() * WindowSizeValue();
       
  2187         }
       
  2188     else
       
  2189         {
       
  2190         return iThumbSpan;
       
  2191         }
       
  2192     }
       
  2193 
       
  2194 EXPORT_C void TAknDoubleSpanScrollBarModel::SetWindowSize (TInt aWindowSize)
       
  2195     {
       
  2196     if (ModelIsSupported())
       
  2197         {
       
  2198         // Assert that API user has not set TEikScrollBarModel values directly
       
  2199         __ASSERT_ALWAYS(ScrollBarModelType() == EAknDoubleSpanScrollBarModel,Panic(EEikPanicOutOfRange));
       
  2200         SetWindowSizeValue(PrepareScaledValue(CheckMinMaxValue(aWindowSize)));
       
  2201         }
       
  2202     else
       
  2203         {
       
  2204         iThumbSpan = aWindowSize;
       
  2205         }
       
  2206     }
       
  2207 
       
  2208 TUint16 TAknDoubleSpanScrollBarModel::Scale() const
       
  2209     {
       
  2210     TUint16 scale = TUint16(KDoubleSpanModelMaskBitsScale16 & HighBytes(iScrollSpan));
       
  2211     return scale;
       
  2212     }
       
  2213 
       
  2214 void TAknDoubleSpanScrollBarModel::SetScale(TUint16 aScale)
       
  2215     {
       
  2216     __ASSERT_ALWAYS(aScale != 0,Panic(EEikPanicOutOfRange));
       
  2217     __ASSERT_ALWAYS(aScale <= KDoubleSpanMaxScaleValue,Panic(EEikPanicOutOfRange));
       
  2218 
       
  2219     iScrollSpan &= ~KDoubleSpanModelMaskBitsScale;
       
  2220     iScrollSpan |= KDoubleSpanModelMaskBitsScale & (TInt(aScale) << 16);
       
  2221     }
       
  2222 
       
  2223 // getter/setters for raw values without scaling
       
  2224 TInt16 TAknDoubleSpanScrollBarModel::ScrollSpanValue() const
       
  2225     {
       
  2226     return LowBytes(iScrollSpan);
       
  2227     }
       
  2228 
       
  2229 void TAknDoubleSpanScrollBarModel::SetScrollSpanValue(TInt16 aScrollSpan)
       
  2230     {
       
  2231     SetLowBytes(iScrollSpan, aScrollSpan);
       
  2232     }
       
  2233 
       
  2234 TInt16 TAknDoubleSpanScrollBarModel::FocusPositionValue() const
       
  2235     {
       
  2236     return HighBytes(iThumbSpan);
       
  2237     }
       
  2238 
       
  2239 void TAknDoubleSpanScrollBarModel::SetFocusPositionValue(TInt16 aFocusPosition)
       
  2240     {
       
  2241     SetHighBytes(iThumbSpan, aFocusPosition);
       
  2242     }
       
  2243 
       
  2244 TInt16 TAknDoubleSpanScrollBarModel::FieldPositionValue() const
       
  2245     {
       
  2246     return LowBytes(iThumbSpan);
       
  2247     }
       
  2248 
       
  2249 void TAknDoubleSpanScrollBarModel::SetFieldPositionValue(TInt16 aFieldPosition)
       
  2250     {
       
  2251     SetLowBytes(iThumbSpan, aFieldPosition);
       
  2252     }
       
  2253 
       
  2254 TInt16 TAknDoubleSpanScrollBarModel::FieldSizeValue() const
       
  2255     {
       
  2256     return HighBytes(iThumbPosition);
       
  2257     }
       
  2258 
       
  2259 void TAknDoubleSpanScrollBarModel::SetFieldSizeValue(TInt16 aFieldSize)
       
  2260     {
       
  2261     SetHighBytes(iThumbPosition, aFieldSize);
       
  2262     }
       
  2263 
       
  2264 TInt16 TAknDoubleSpanScrollBarModel::WindowSizeValue() const
       
  2265     {
       
  2266     return LowBytes(iThumbPosition);
       
  2267     }
       
  2268 
       
  2269 void TAknDoubleSpanScrollBarModel::SetWindowSizeValue(TInt16 aWindowSize)
       
  2270     {
       
  2271     SetLowBytes(iThumbPosition, aWindowSize);
       
  2272     }
       
  2273 
       
  2274 TInt16 TAknDoubleSpanScrollBarModel::LowBytes(TInt aInt) const
       
  2275     {
       
  2276     return TInt16(KDoubleSpanModelMaskBitsLow & aInt);
       
  2277     }
       
  2278 
       
  2279 TInt16 TAknDoubleSpanScrollBarModel::HighBytes(TInt aInt) const
       
  2280     {
       
  2281     return TInt16((KDoubleSpanModelMaskBitsHigh & aInt) >> 16);
       
  2282     }
       
  2283 
       
  2284 void TAknDoubleSpanScrollBarModel::SetLowBytes(TInt& aInt, TInt16 aValue)
       
  2285     {
       
  2286     aInt &= KDoubleSpanModelMaskBitsHigh;
       
  2287     aInt |= TInt(KDoubleSpanModelMaskBitsLow & aValue);
       
  2288     }
       
  2289 
       
  2290 void TAknDoubleSpanScrollBarModel::SetHighBytes(TInt& aInt, TInt16 aValue)
       
  2291     {
       
  2292     aInt &= KDoubleSpanModelMaskBitsLow;
       
  2293     aInt |= TInt(aValue) << 16;
       
  2294     }
       
  2295 
       
  2296 TInt16 TAknDoubleSpanScrollBarModel::PrepareScaledValue(TInt aNonScaledValue)
       
  2297     {
       
  2298      __ASSERT_ALWAYS(KDoubleSpanMinModelValue <= aNonScaledValue && aNonScaledValue <= KDoubleSpanMaxModelValue, Panic(EEikPanicOutOfRange));
       
  2299 
       
  2300     TUint16 requiredScale = KDoubleSpanMinScaleValue;
       
  2301     if (aNonScaledValue < 0)
       
  2302         {
       
  2303         requiredScale = TUint16(( -aNonScaledValue / KDoubleSpanMaxRawValue ) + KDoubleSpanMinScaleValue);
       
  2304         }
       
  2305     else
       
  2306         {
       
  2307         requiredScale = TUint16(( aNonScaledValue / KDoubleSpanMaxRawValue ) + KDoubleSpanMinScaleValue);
       
  2308         }
       
  2309 
       
  2310     if ( requiredScale > Scale() )
       
  2311         {
       
  2312          ReScale( requiredScale );
       
  2313         }
       
  2314     TInt16 scaledValue = TInt16(aNonScaledValue / Scale());
       
  2315      return scaledValue;
       
  2316     }
       
  2317 
       
  2318 void TAknDoubleSpanScrollBarModel::ReScale(TUint16 aNewScale)
       
  2319     {
       
  2320     __ASSERT_ALWAYS(aNewScale != 0,Panic(EEikPanicOutOfRange));
       
  2321     __ASSERT_ALWAYS(aNewScale <= KDoubleSpanMaxScaleValue,Panic(EEikPanicOutOfRange));
       
  2322 
       
  2323     SetScrollSpanValue(TInt16((ScrollSpanValue() * Scale())/aNewScale));
       
  2324     SetFocusPositionValue(TInt16((FocusPositionValue() * Scale())/aNewScale));
       
  2325     SetFieldPositionValue(TInt16((FieldPositionValue() * Scale())/aNewScale));
       
  2326     SetFieldSizeValue(TInt16((FieldSizeValue() * Scale())/aNewScale));
       
  2327     SetWindowSizeValue(TInt16((WindowSizeValue() * Scale())/aNewScale));
       
  2328     SetScale(aNewScale);
       
  2329     }
       
  2330 
       
  2331 void TAknDoubleSpanScrollBarModel::SetScrollBarModelType(TEikScrollBarModelType aModelType)
       
  2332     {
       
  2333     iScrollSpan &= KDoubleSpanModelMaskBitsType;
       
  2334     iScrollSpan |= (~KDoubleSpanModelMaskBitsType) & aModelType;
       
  2335     }
       
  2336 
       
  2337 TInt TAknDoubleSpanScrollBarModel::CheckMinMaxValue(TInt aValue)
       
  2338     {
       
  2339     if ((aValue > 0) && (aValue > KDoubleSpanMaxModelValue))
       
  2340         {
       
  2341         return KDoubleSpanMaxModelValue;
       
  2342         }
       
  2343     if ((aValue < 0) && (aValue < KDoubleSpanMinModelValue))
       
  2344         {
       
  2345         return KDoubleSpanMinModelValue;
       
  2346         }
       
  2347     return aValue;
       
  2348     }
       
  2349 
       
  2350 TBool TAknDoubleSpanScrollBarModel::ModelIsSupported()
       
  2351     {
       
  2352     // Check here feature flags etc. to decide if this device can support this
       
  2353     // type of model and scrollbars.
       
  2354     return ETrue;
       
  2355     }
       
  2356 
       
  2357 TRect CAknDoubleSpanScrollBar::ExtensionArea() const
       
  2358     {
       
  2359     // Usage of hard-coded parent rectangle is acceptable since we're
       
  2360     // interested in only about the ratio between scrollbar and extension.
       
  2361     TAknLayoutRect layoutRect;
       
  2362     layoutRect.LayoutRect( TRect( 0, 0, 200, 200 ), AknLayoutScalable_Avkon::listscroll_gen_pane( 0 ).LayoutLine() );
       
  2363     
       
  2364     TRect parent( layoutRect.Rect() ); // parent of both extension and scrollbar
       
  2365     
       
  2366     layoutRect.LayoutRect( parent, AknLayoutScalable_Avkon::scroll_pane( 0 ).LayoutLine() );
       
  2367     
       
  2368     TRect scrollbar( layoutRect.Rect() );
       
  2369     
       
  2370     CAknDoubleSpanScrollBarExtension* extension1 = static_cast<CAknDoubleSpanScrollBarExtension*> (iExtension);
       
  2371     if( extension1->iExtensionType & ENormalExpandedTouchArea )
       
  2372         layoutRect.LayoutRect( parent, AknLayoutScalable_Avkon::aid_size_touch_scroll_bar( 0 ).LayoutLine() );
       
  2373     else if( extension1->iExtensionType & EScaleExpandedTouchArea )
       
  2374         layoutRect.LayoutRect( parent, AknLayoutScalable_Avkon::aid_size_touch_scroll_bar_cale( 0 ).LayoutLine() );
       
  2375     else
       
  2376         layoutRect.LayoutRect( parent, AknLayoutScalable_Avkon::aid_size_touch_scroll_bar( 0 ).LayoutLine() );
       
  2377     TRect extension( layoutRect.Rect() );
       
  2378 
       
  2379     TRect area;
       
  2380     
       
  2381     if ( iOrientation == CEikScrollBar::EVertical )
       
  2382         {
       
  2383         area.iTl.iX = extension.iTl.iX - scrollbar.iTl.iX;
       
  2384         area.iTl.iY = scrollbar.iTl.iY - extension.iTl.iY;
       
  2385         area.iBr.iX = area.iTl.iX + extension.Width();
       
  2386         area.iBr.iY = iSize.iHeight + ( extension.Height() - scrollbar.Height() );
       
  2387         }
       
  2388     else
       
  2389         {
       
  2390         area.iTl.iX = scrollbar.iTl.iY - extension.iTl.iY;
       
  2391         area.iTl.iY = scrollbar.Width() - extension.Width();
       
  2392         area.iBr.iX = iSize.iWidth + ( extension.Height() - scrollbar.Height() );
       
  2393         area.iBr.iY = area.iTl.iY + extension.Width();
       
  2394         }
       
  2395     
       
  2396     return area;
       
  2397     }
       
  2398