×
Namespaces

Variants
Actions

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

From Nokia Developer Wiki
Jump to: navigation, search
Article Metadata

代码示例
兼容于
文章
dougcn 在 06 Jul 2008 创建
最后由 hamishwillee 在 30 May 2013 编辑
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

Contents

概述

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

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

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


后置条件

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

参见

自定义控件系列:

This page was last modified on 30 May 2013, at 07:42.
67 page views in the last 30 days.