Join Now
Quality Rating:
  • Currently 0.0 / 5
(0.0 / 5 - 0 votes cast)
Expertise Level:
  • Currently 0.0 / 5
(0.0 / 5 - 0 votes cast)

This page was last modified 11:42, 28 March 2008.

CS000869 - Custom control: Scrollbars

From Forum Nokia Wiki


ID CS000869 Creation date March 28, 2008
Platform S60 3rd Edition, FP1 Tested on devices Nokia N95
Category Symbian C++ Subcategory UI


Keywords (APIs, classes, methods, functions): CCoeControl, TKeyEvent, CEikScrollBarFrame, TAknDoubleSpanScrollBarModel

Overview

This code snippet shows how to add scrollbars to a container control that has custom controls and how to show only visible components and search for more of them in view top and bottom.

This example extends the existing code snippet CS000868 - Custom control: Focusing. Check the See also section of this article for other snippets of the Custom Control series.


CMyContainerControl - Header

Add these methods and member data to the CMyContainerControl component header.

MoveFocusUpL() Moves focus to ask for more components to the screen at the bottom of the view
MoveFocusDownL() Moves focus to ask for more components to the screen at the bottom of the view
UpdateScrollBarFrameL() Updates scroll bar
ShowNextItem() Searches for more items to the screen at the bottom of the view
ShowPrevItem() Searches for more items to the screen at the top of the view

#include <eiksbfrm.h>
 
private:
    void ShowNextItem();
    void ShowPrevItem();
    void MoveFocusUpL();
    void MoveFocusDownL();
    void UpdateScrollBarFrameL();
private:
    CEikScrollBarFrame*                   iScrollBarFrame;
    TAknDoubleSpanScrollBarModel          iHDsSbarModel;
    TAknDoubleSpanScrollBarModel          iVDsSbarModel;        
    TInt                                  iFocusedIndex;

CMyContainerControl - Source

Create scroll bar in CMyContainerControl::ConstructL()

// Creating Scroll Bars
iScrollBarFrame = new ( ELeave ) CEikScrollBarFrame( this, NULL );
iScrollBarFrame->CreateDoubleSpanScrollBarsL( ETrue, EFalse );
iScrollBarFrame->SetTypeOfVScrollBar( CEikScrollBarFrame::EDoubleSpan );
iScrollBarFrame->SetScrollBarVisibilityL( CEikScrollBarFrame::EOff, 
CEikScrollBarFrame::EOff );

Update scroll bar data in CMyContainerControl::UpdateScrollBarFrameL() The method will be called in CMyContainerControl::AddControlL() after adding components into this container control.

void CMyContainerControl::UpdateScrollBarFrameL()
    {
    TInt controlsHeight = 0; // Height of the controls
    TInt height = 0; // This view height
    
    // Calculate components height
    CCoeControlArray::TCursor cursor = Components().Begin();
    CCoeControl* ctrl = NULL;
    while ((ctrl = cursor.Control<CCoeControl>()) != NULL)
        {
        controlsHeight += ctrl->MinimumSize().iHeight;
        cursor.Next();
        }
 
    // This view height
    height = Rect().Height();
    
    // Set teh scrollbar visible if fields do not fit the screen
    if( controlsHeight > height && 
        iScrollBarFrame->VScrollBarVisibility() == 
        CEikScrollBarFrame::EOff)
        {
        iScrollBarFrame->SetScrollBarVisibilityL(
                CEikScrollBarFrame::EOff, // horizontal
                CEikScrollBarFrame::EOn); // vertical
        }
    // Hide the scrollbar if fields fit the screen
    else if ( controlsHeight <= height && 
              iScrollBarFrame->VScrollBarVisibility() == 
              CEikScrollBarFrame::EOn)
        {
        iScrollBarFrame->SetScrollBarVisibilityL(
                CEikScrollBarFrame::EOff, // horizontal
                CEikScrollBarFrame::EOff); // vertical
        }
    
    // Update scroll bar position
    iVDsSbarModel.SetScrollSpan(Components().Count());
    iVDsSbarModel.SetWindowSize(1);
    iVDsSbarModel.SetFocusPosition(iFocusedIndex);
    TEikScrollBarFrameLayout layout;
    layout.iTilingMode = TEikScrollBarFrameLayout::EInclusiveRectConstant;
    TRect rect = Rect();
    iScrollBarFrame->TileL(&iHDsSbarModel,&iVDsSbarModel,rect,rect,layout);
    iScrollBarFrame->SetVFocusPosToThumbPos(iVDsSbarModel.FocusPosition());
    }

CMyContainerControl::MoveFocusUpL() moves active component focus and asks to show more components if the cursor reaches the screen top.

void CMyContainerControl::MoveFocusUpL()
    {
    CCoeControlArray::TCursor cursor = Components().Begin();
    CCoeControl* ctrl = NULL;
    CCoeControl* prevCtrl = NULL;
    while ((ctrl = cursor.Control<CCoeControl>()) != NULL)
        {
        if (ctrl->IsFocused())
            {
            if (prevCtrl)
                {
                // Set focus to previous control
                ctrl->SetFocus(EFalse);
                prevCtrl->SetFocus(ETrue);
                iFocusedIndex--;
                
                // Focus is over the view?
                if (iFocusedIndex > 0 && !prevCtrl->IsVisible())
                    {
                    ShowPrevItem();
                    }
                break;
                }
            else
                {
                break; // First control is already focused
                }
            }
        prevCtrl = ctrl;
        cursor.Next();
        }
 
    UpdateScrollBarFrameL();
    }

CMyContainerControl::MoveFocusDownL() moves active component focus and asks to show more components if the cursor reaches the screen bottom.

void CMyContainerControl::MoveFocusDownL()
    {
    CCoeControlArray::TCursor cursor = Components().Begin();
    CCoeControl* ctrl = NULL;
    CCoeControl* nextCtrl = NULL;
    while ((ctrl = cursor.Control<CCoeControl>()) != NULL)
        {
        if (ctrl && ctrl->IsFocused())
            {
            cursor.Next();
            nextCtrl = cursor.Control<CCoeControl>();
            if (nextCtrl)
                {
                // Set focus to next control
                ctrl->SetFocus(EFalse);
                nextCtrl->SetFocus(ETrue);
                iFocusedIndex++;
                
                // Focus is over the view?
                if (!nextCtrl->IsVisible())
                    {
                    ShowNextItem();
                    }
                break;
                }
            else
                {
                break; // Last control is already focused
                }
            }
        cursor.Next();
        }
 
    UpdateScrollBarFrameL();
    }


void CMyContainerControl::ShowNextItem() and void CMyContainerControl::ShowPrevItem() find more components to view and set them to the correct position.

void CMyContainerControl::ShowNextItem()
    {
    TPoint position;
 
    // Goes throught all components of this container control
    CCoeControlArray::TCursor cursor = Components().Begin();
    CCoeControl* ctrl = NULL;
    TBool focusedFound = EFalse;
    while ((ctrl = cursor.Control<CCoeControl>()) != NULL)
        {
        if (ctrl && ctrl->IsFocused())
            {
            focusedFound = ETrue;
            }
 
        if (focusedFound)
            {
            // Set size
            TSize size = ctrl->MinimumSize();
            size.SetSize(Rect().Width(),size.iHeight);
            ctrl->SetSize(size);
 
            // Does it fit to the screen?
            if ((position.iY + size.iHeight) >= Rect().iBr.iY)
                {
                ctrl->MakeVisible(EFalse);
                focusedFound = EFalse; // Let rest components be MakeVisible(EFalse) 
                }
            else
                {
                ctrl->MakeVisible(ETrue);
 
                // Set position
                ctrl->SetPosition(position);
                
                // Store position of last component
                position.iY += size.iHeight;
                }
            }
        else
            {
            ctrl->MakeVisible(EFalse);
            }
        cursor.Next();
        }
    }
 
 
void CMyContainerControl::ShowPrevItem()
    {
    TPoint position;
    position.iY = Rect().iBr.iY;
    
    // Goes throught all components from the last -> to the first one
    CCoeControlArray::TCursor cursor = Components().End();
    CCoeControl* ctrl = NULL;
    TBool focusedFound = EFalse;
    while (cursor.Prev())
        {
        ctrl = cursor.Control<CCoeControl>();
        if (ctrl && ctrl->IsFocused())
            {
            focusedFound = ETrue;
            }
        
        if (focusedFound)
            {
            // Set size
            TSize size = ctrl->MinimumSize();
            size.SetSize(Rect().Width(),size.iHeight);
            ctrl->SetSize(size);
 
            // Fix position
            position.iY -= size.iHeight;
            
            if ((position.iY) <= Rect().iTl.iY-2)
                {
                // Does not fit anymore
                ctrl->MakeVisible(EFalse);
                focusedFound = EFalse; // Let rest components be MakeVisible(EFalse)
                }
            else
                {
                ctrl->MakeVisible(ETrue);
 
                // Set position
                ctrl->SetPosition(position);
                }
            }
        else
            {
            ctrl->MakeVisible(EFalse);
            }
        }
    }


Postconditions

Custom control has scrollbars that show the position of the focus in the view. More components will be shown when reaching the bottom or top of the view.

See also

Custom Control Series:

Related Discussions
Thread Thread Starter Forum Replies Last Post
Location API's Burning_Up Mobile Java Tools & SDKs 7 2006-11-14 01:02
problem in custom control..... platinnum General Symbian C++ 0 2005-06-30 07:11
Need help with custom Item drawer gigglie Symbian User Interface 0 2008-03-10 10:49
Does traverseOut Work? ktorimaru Mobile Java General 7 2004-07-21 22:39
Hello dll problem doctordwarf General Symbian C++ 12 2003-09-22 16:28
 
Powered by MediaWiki
     
     RDF Facets:
     
     
     qfnZtopicQUqfnTopicZseriesE5f60Q
     qfnZtypeQUqfnTypeZCommunityContentQ
     qfnZtypeQUqfnTypeZWebpageQ
     qfnZtypeQUqfnTypeZWikiContentQ
     qmarsZlanguageQUxhttpE3aE2fE2fswE2enokiaE2ecomE2flanguageE2d1E2fenX