Join Now
Quality Rating:
  • Currently 0.0 / 5
(0.0 / 5 - 0 votes cast)
This page was last modified 13:53, 6 July 2008.

自定义控件: 滚动条(五)

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

概述

这个代码片段演示如何给有自定义控件的容器控件添加滚动条,以及如何只显示可见部件并在视图的顶部和底部搜查更多的可视部件。

本例扩展了已存代码片段自定义控件: 聚焦(四)。查看本文的“参见”部分以了解自定义控件系列的其它代码片段。

CMyContainerControl - 头文件

添加这些方法和成员数据到CMyContainerControl部件的头文件中。

MoveFocusUpL() 移动焦点寻求更多的部件以显示到视图顶部屏幕
MoveFocusDownL() 移动焦点寻求更多部件以显示到视图底部屏幕
UpdateScrollBarFrameL() 更新滚动条
ShowNextItem() 查找更多条目并在视图底部屏幕显示出来
ShowPrevItem() 查找更多条目并在视图顶部屏幕显示出来

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

CMyContainerControl - 源代码

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 );

CMyContainerControl::UpdateScrollBarFrameL()中更新滚动条数据; 在添加部件到这个容器控件后,这个方法会在CMyContainerControl::AddControlL()中调用。

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()移动活动部件焦点,以及若达到屏幕顶部就请求显示更多部件。

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()移动活动部件焦点,以及若焦点到达屏幕底部就请求显示更多部件。

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()void CMyContainerControl::ShowPrevItem()查找更多的部件以便查看及设置到正确的位置。

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);
            }
        }
    }


后置条件

自定义控件有滚动条演示视图中焦点的位置。当达到视图的底部或顶部将显示更多部件。

参见

自定义控件系列:

 
Powered by MediaWiki
     
     RDF Facets:
     
     
     qfnZtopicQUqfnTopicZseriesE5f60Q
     qfnZtypeQUqfnTypeZCommunityContentQ
     qfnZtypeQUqfnTypeZWebpageQ
     qfnZtypeQUqfnTypeZWikiContentQ
     qmarsZlanguageQUxhttpE3aE2fE2fswE2enokiaE2ecomE2flanguageE2d1E2fenX