Элемент управления CAknSlider в контейнере CAknView (не как элемент настройки) - PullRequest
2 голосов
/ 29 мая 2009

Я поражен тем, насколько хорошо реализованы нативные компоненты Symbian. Одним из них является CAknSlider. CAknSlider - это элемент управления с ползунком, который пользователи могут использовать для его перемещения вдоль панели, ориентация которой может быть вертикальной или горизонтальной.

Теперь при скольжении ползунка скольжение очень плавное и не мерцает. Но если бы по какой-то причине мне пришлось реализовать собственный элемент управления ползунком, я бы не стал таким аккуратным, как CAknSlider.

Итак, мой вопрос: как я могу понять, как CAknSlider реализован под капотом? Я хочу реализовать пользовательский ползунок для моего радиоприложения для управления громкостью аудиопотока.

Есть идеи, как мне это сделать.


[РЕДАКТИРОВАТЬ: В ответ на комментарий от laalto]

Элемент управления CAknSlider часто реализуется как элемент настройки на экране настроек .

Я никогда не видел, чтобы он реализовывался как элемент управления компонента в контейнере составного элемента управления (например, CCoeControl или CAknView). Это то, что я пробовал до сих пор:

Сначала я создал файл ресурсов, описывающий ползунок, как показано ниже:

RESOURCE SLIDER r_volume_slider
{
 layout=EAknCtSlider;
 minvalue=0;
 maxvalue=10;
 step=1;
 valuetype=EAknSliderValuePercentage;
 minlabel="mute";
 maxlabel="full";
}

Затем я использую файл ресурсов в своем источнике для создания слайдера, как показано ниже:

void CVolumePopupAppView::ConstructL(const TRect& aRect)
{
// Create a window for this application view
CreateWindowL();

InitComponentArrayL( );
iSlider = new ( ELeave ) CAknSlider( );
TResourceReader reader;
iEikonEnv->CreateResourceReaderLC( reader, R_VOLUME_SLIDER );

iSlider->ConstructFromResourceL( reader );
CleanupStack::PopAndDestroy ( );
iSlider->SetContainerWindowL( *this );
iSlider->SetParent( this );

Components().AppendLC( iSlider );

CleanupStack::Pop ( iSlider );

// Set the windows size
SetRect(aRect);

// Activate the window, which makes it ready to be drawn
ActivateL();
}

Теперь приведено сравнение CAknSlider как элемента настройки ( Screenshot1 ) и CAknSlider, который создается описанным выше методом ( Screenshot2 ). Обратите внимание, что у созданного мной нет индикатора процентного значения, а также минимальных и максимальных текстовых меток, хотя я указал их в ресурсе. Внешний вид также жалок.

Ответы [ 2 ]

2 голосов
/ 29 мая 2009

Существует множество методов, позволяющих избежать мерцания: от двойной буферизации всего экрана до более простых оптимизаций, например, перерисовывание только тех частей элемента управления, которые действительно изменились. Предварительно нарисованные соответствующие прямоугольники, чтобы переместиться туда, где находился ползунок, и его следующий шаг, вероятно, самый простой способ сделать это эффективно.

Чтобы узнать, как именно CAknSlider это делает, вы можете: 1) Подождите, пока соответствующий пакет на платформе Symbian Foundation выйдет с открытым исходным кодом (EPL) - должно произойти где-то в ближайшие 12 месяцев или 2) Присоединяйтесь к Symbian Foundation и получите доступ к исходному тексту

РЕДАКТИРОВАТЬ: (В ответ на запрос более подробной информации по оптимизации графики)

Чаще всего мерцание вызвано перерисовкой всего элемента управления. Я реализовал (через проект переноса) некоторые пользовательские элементы управления, которые не мерцают здесь: http://developer.symbian.com/main/documentation/porting/#linux2 Есть даже что-то вроде слайдера. Этот пример далек от идеала, у него нет предварительно нарисованных прямоугольников для блиттинга, но графика - очень простые линии и заполненные прямоугольники. Концепция перезаписи только измененной части идентична. Бить предварительно нарисованные участки. Нарисуйте фон слайдера за пределами экрана и сделайте то же самое с подвижной частью слайдера. Когда ползунок перемещен, сотрите подвижную часть, выполнив BitBlt () из закадрового фона (только части, которая должна быть стерта), а затем BitBlt () подвижной части в новое положение.

Имеет ли это смысл?

1 голос
/ 02 июня 2009

Вам нужен CAknSlider? укради это! :) CAknSliderSettingPage сделает все за нас. Мы просто используем это.

iSettingPage = new(ELeave) CAknSliderSettingPage(R_SLIDER_PAGE, iValue);
iSettingPage->ConstructL();

iSettingPage->SetSize(iSettingPage->MinimumSize());

TInt CCustomColorPalette::CountComponentControls() const
{
    return 1;
}

CCoeControl* CCustomColorPalette::ComponentControl( TInt aIndex ) const
{
   return iSettingPage->SliderControl();
}
...