Элемент управления CAknSlider в контейнере CAknView (не как элемент настройки)

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

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

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

Любая идея, как мне это сделать.


[EDIT: в ответ на комментарий от 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 ). Обратите внимание, что тот, который я создаю, не имеет индикатора процентного значения и текстовых меток минимума и максимума, хотя я указал их в ресурсе. Внешний вид тоже жалкий.


person ardsrk    schedule 29.05.2009    source источник
comment
Было бы полезно, если бы вы описали, что вы пытались до сих пор - легче дать идеи по улучшению, если есть какой-то код или псевдокод для комментариев.   -  person laalto    schedule 29.05.2009


Ответы (2)


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

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

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

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

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

person Mark Wilcox    schedule 29.05.2009
comment
Кстати, ползунок для регулировки громкости может вас немного разочаровать, потому что базовая реализация адаптации звука на большинстве устройств Nokia имеет только 10 дискретных уровней громкости, хотя API позволяет вам установить произвольное значение от 0 до MaxVolume. - person Mark Wilcox; 29.05.2009
comment
Марк, в своем ответе вы упомянули о предварительно нарисованных прямоугольниках для блитинга... как о простейшем методе оптимизации. Не могли бы вы указать мне пример приложения, использующего эту технику, или помочь мне, объяснив, как это сделать самому. - person ardsrk; 02.06.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();
}
person Community    schedule 01.06.2009
comment
Валентин, хорошая техника. Я попробую и дам вам знать, что у меня есть. Спасибо - person ardsrk; 02.06.2009