====== Создание интерфейса на основе Panel Stack Splitter плагина ======
===== Введение =====
Долго расписывать не буду, но вкратце всё же скажу зачем написал эту статью.\\
Многие (в том числе и я ;-)), установив себе "чистую" версию Foobar - не удовлетворены его внешним видом.\\
Поиски более "симпатичного" вида плеера приводят их к установке более красивых|функциональных сборок.\\
И после некоторого времени использования "сборки" нам начинает чего-то не хватать в "сборке", либо наоборот есть что-то что не используется вовсе, а иногда даже и мешает.\\
Здесь то и возникают проблемы (особенно у тех кто с Английским языком на "ТЫ") так как инструкци если и есть к плагинам, то они на английском (а некоторые вовсе на японском).\\
Это и становится причиной того, что появляются неудобства при переделывании плеера "под себя". \\
Инструкция предназначена для тех, __кто не испугался__ (на первый взгляд) замысловато-непонятных скриптов и __всё же решился сделать свой__\\
**Собственный интерфейс для плеера Foobar2000**
===== С чего начать =====
Первое, что нужно сделать - это :
- Определиться (хотя бы примерно) каким Вы представляете внешний вид Вашего будущего плеере и каким функционалом он должен обладать
- Установить сам плеер (я бы рекомендовал версию 0.9.6.9 - так как версия 1.0 пока ещё на стадии бета-тестирования)
- Почитать [[foobar2000:manual:pss_tutorial|инструкцию к PSS]]
- Добавить в папку **components** плагины:
*Columns UI [[http://yuo.be/columns.php|foo_ui_columns.dll]]
*Panel Stack Splitter [[http://foo2k.chottu.net/|foo_uie_panel_splitter.dll]]
*не обязательно, __но желательно__ добавить сразу остальные [[wiki:|плагины]], которые будут участвовать в создании интерфейса (конечно же их можно будет добавить и после, но в таком случае в таком случае нам придется перезапускать плеер и делать переконфигурирование **Columns**-ов и **PSS**)
===== Добавление основной панели PSS =====
**Preferences** -> **Display** -> **Columns UI** -> вкладка **Layout**\\
* в блоке **Presets** жмём кнопку _New_ и вводим имя будущего пресета (Например: "**PSS1**")
* в окошке ниже имени пресета видим "NG Playlist"
* жмём на нём **ПКМ** -> **Change base** -> **Splitters** -> **Panel Stack Splitter**
На данном этапе мы создали основу на которой и будем подбирать и размещать нужные нам панели \\
===== Добавление панелей в PSS =====
И так приступим к выбору и подключению панелей, которые нам нужны будут в конфиге.\\
Сделать это можно 2-мя способами:\\
==== Первый способ ====
**Preferences** -> **Display** -> **Columns UI** -> вкладка **Layout**
- в окошке ниже имени пресета видим "Panel Stack Splitter"
- жмём на нём **ПКМ ((ПКМ - это щелчек Правой Кнопки Мыши ;-)))** -> **Insert panel** -> из нижеследующих вкладок подбираем необходимые панели
***Panels** -> тут выбираем к примеру :::
*Artwork view
*Item details
*Item properties
*Playlist switcher
***Playlist Views** ->
*NG Playlist
Так должен будет выглядеть наш список панелей:
{{ images:2009-12-29_1503-Layout_Content.png }}\\
==== Второй способ ====
**ПКМ ((ПКМ - это щелчек Правой Кнопки Мыши ;-)))** на поле плеера -> **Add panel**
***Panels** -> добавляем панели
***Playlist Views** -> добавляем варианты отображения плейлиста
Аналогично тому как мы набирали панели в первом способе, можно набрать список панелей и этим способом (но он менее нагляден для начального понимания)
Панели подобраны. Теперь приступим к их размещению. \\
===== Размещение панелей =====
По умолчанию панели разместились с горизонтальным смещением относительно друг друга.\\
Таковое размещение панелей задано по умолчанию для **PSS ((Panel Stack Splitter))**\\
Приступим к настройке отображения панелей.\\
Щелкнув **ПКМ** на свободном от панелей месте Foobar или на панели ''Artwork view'', ''Item details'' или ''Item properties'' -> выбираем пункт **Splitter Settings...**
__Не все__ панели содержат в контекстных меню **ПКМ** пункт **Splitter Settings...**. \\
Это нужно запомнить.\\
Для ясности рассмотрим из чего состоит и за что отвечает вкладка **%%PanelList%%**.
- В левой части отображен список панелей, которые мы добавили для их последующего конфигурирования. Каждой панели соответствует свое имя, которое можно изменить в поле **Caption:**
- Ниже списка панелей есть пункт **Panel placement mode:** с вариантами
***Horizontal** - горизонтальное размещение панелей относительно друг друга
***Vertical** - вертикальное расположение панелей относительно друг друга
- Параметр **Size** отвечает за размер отображаемой панели,
- Блок правее списка панелей активируется __для каждой панели отдельно__ включением значения **Forced layout**.
***Use percentage value** - этот параметр включает процентное позиционирование **left, Top, width, height** параметров (по умолчанию координаты и размеры задаются в пикселях [PIXEL])
***Enable padding settings** - включение отступов между панелями согласно значений заданных в блоке **Padding**
***left** - левая точка панели (начальная координата отображения панели по горизонтальной оси)
***Top** - верхняя точка панели (начальная координата отображения панели по вертикальной оси)
***width** - ширина панели
***height** - высота панели
Для того чтобы отобразить панели согласно нашим требованиям - нужно **__активировать для всех панелей__** из списка **Panel List**, пункт **Forced layout**.
Нажав APPLY все панели исчезли из отображения, так как мы не задали координаты для их отображения.\\
Выбрав, к примеру, панель **Artwork view** - зададим ей координаты
left : 0
Top : 0
width : 256
height : 256
В результате получаем статическое отображение панели ''Artwork view'' в левом (**left**=0) верхнем (**Top**=0) углу с размерами 128 на 128 пиксел.\\
Далее отобразим к примеру **Item details** задав для неё координаты
left : 256
Top : 0
width : $sub(%ps_width%,512)
height : 256
По аналогии зададим параметры для остальных панелей:\\
**Item properties**
left : 0
Top : 256
width : 256
height : $sub(%ps_height%,286)
**Playlists**
left : $sub(%ps_width%,256)
Top : 0
width : 256
height : 256
**Playlist**
left : 256
Top : 256
width : $sub(%ps_width%,256)
height : $sub(%ps_height%,286)
Высоту (**height**) для панелей **Item properties** и **Playlist** специально сделали на 30 пикселей меньше.\\
Здесь мы добавим кнопки управления плеером.
Вот и разместили все панели.
===== Кнопки управления (текстовые) =====
Для создания кнопок переходим во вкладку **Script**\\
В части **%%PerTrack%%** пишем скрипты для наших кнопочек.\\
Используем для этого функцию [[pss_tutorial#textbutton_x_y_w_h_text_mover_text_command_options1_options2|$textbutton(x,y,w,h,text,mover_text,command,options1,options2)]]\\
**x** - координата начала по горизонтали\\
**y** - координата начала по вертикали\\
**w** - ширина кнопки\\
**h** - высота кнопки
**text** - текст отображаемый на кнопке\\
**mover_text** - текст отображаемый на кнопке при наведении "мышки" на неё\\
**command** - комманда, которая будет выполняться при нажатии на кнопку\\
**options1** - опции отображения кнопки\\
**options2** - опции отображения кнопки, при наведении "мышки" на неё
Рассмотрим на примере как будет выглядеть кнопка **Play**
$textbutton(120,$sub(%ps_height%,25),50,20,Play,Play,COMMAND:Playback/Play,fontcolor:64-64-64 brushcolor:192-192-192-128 pencolor:0-0-0,fontcolor:2-22-2-232 brushcolor:92-92-152-128 pencolor:0-0-0)
Вставляем код в вкладку **%%PerTrack%%** и видим в нижней части прямоугольную кнопку с текстом **Play**.
Для наглядности и большего понимания посмотрим по отдельности каждый фрагмент кода текстовой кнопки **$textbutton(...)**.\\
**x**=120 -> координата начала по горизонтали\\
**y**=$sub(%ps_height%,25) -> координата начала по вертикали\\
**w**=50 -> ширина кнопки\\
**h**=20 -> высота кнопки
**text**:Play -> текст отображаемый на кнопке\\
**mover_text**:Play -> текст отображаемый на кнопке при наведении "мышки" на неё\\
**command**:COMMAND:Playback/Play -> комманда, которая будет выполняться при нажатии на кнопку\\
**options1**:fontcolor:64-64-64 brushcolor:192-192-192-128 pencolor:0-0-0 -> опции отображения кнопки\\
**options2**:fontcolor:2-22-2-232 brushcolor:92-92-152-128 pencolor:0-0-0 -> опции отображения кнопки, при наведении "мышки" на неё
Аналогично создаем остальные кнопки.\\
Ниже пример готового набора основных кнопок управления воспроизведением:
//----Кнопки управления воспроизведением----//
$textbutton(20,$sub(%ps_height%,25),50,20,Previous,Previous,COMMAND:Playback/Previous,fontcolor:64-64-64 brushcolor:192-192-192-128 pencolor:0-0-0,fontcolor:2-22-2-232 brushcolor:92-92-152-128 pencolor:0-0-0)
$textbutton(70,$sub(%ps_height%,25),50,20,Stop,Stop,COMMAND:Playback/Stop,fontcolor:64-64-64 brushcolor:192-192-192-128 pencolor:0-0-0,fontcolor:2-22-2-232 brushcolor:92-92-152-128 pencolor:0-0-0)
$textbutton(120,$sub(%ps_height%,25),50,20,Play,Play,COMMAND:Playback/Play,fontcolor:64-64-64 brushcolor:192-192-192-128 pencolor:0-0-0,fontcolor:2-22-2-232 brushcolor:92-92-152-128 pencolor:0-0-0)
$textbutton(170,$sub(%ps_height%,25),50,20,Pause,Pause,COMMAND:Playback/Pause,fontcolor:64-64-64 brushcolor:192-192-192-128 pencolor:0-0-0,fontcolor:2-22-2-232 brushcolor:92-92-152-128 pencolor:0-0-0)
$textbutton(220,$sub(%ps_height%,25),50,20,Next,Next,COMMAND:Playback/Next,fontcolor:64-64-64 brushcolor:192-192-192-128 pencolor:0-0-0,fontcolor:2-22-2-232 brushcolor:92-92-152-128 pencolor:0-0-0)
$textbutton(290,$sub(%ps_height%,25),50,20,<<,<<<,COMMAND:Playback/Seek back by 30 seconds,fontcolor:64-64-64 brushcolor:192-192-192-128 pencolor:0-0-0,fontcolor:2-22-2-232 brushcolor:92-92-152-128 pencolor:0-0-0)
$textbutton(340,$sub(%ps_height%,25),50,20,>>,>>>,COMMAND:Playback/Seek ahead by 30 seconds,fontcolor:64-64-64 brushcolor:192-192-192-128 pencolor:0-0-0,fontcolor:2-22-2-232 brushcolor:92-92-152-128 pencolor:0-0-0)
Просто скопируйте в **%%PerTrack%%** **__ВЕСЬ__** код примера и в нижней части плеера появятся 7 кнопочек.
Как и во многих языках программирования, строки начинающиеся с **%%//%%** двух "слешей" (косые черты) являются комментариями.\\
PSS (и многие другие панели) их не обрабатывает.
Кроме кнопок с командами управления в PSS можно создавать кнопки с функционалом доступным для выбора из главного меню (File,Edit,View,...).\\
Полный список этих команд можно получить выбрав под блоком **%%PerTrack%%** в выпадающем меню пункт **Menu Command** и нажав кнопку _ _ list _ _.\\
Щелкнув на нужной команде -- она будет добавлена в **%%PerTrack%%** в позицию, в которой находился курсор в момент выбора.
Рассмотрим на примере создания кнопки вызова настроек плеера **Preferences**:\\
Создадим в **%%PerTrack%%** кнопку без комманды
$textbutton(400,$sub(%ps_height%,25),50,20,Pref-ces,Pref-ces,COMMAND:,fontcolor:64-64-64 brushcolor:192-192-192-128 pencolor:0-0-0,fontcolor:2-22-2-232 brushcolor:92-92-152-128 pencolor:0-0-0)
*далее ставим курсор после двоеточия в **COMMAND:**
*выбираем из выпадающего меню пункт **Menu Command**
*нажав кнопку _ _ list _ _ ищем в списке команд пункт **File/Preferences** и щелкаем на нём
*далее _ _ OK _ _ и кнопка вызова настроек плеера **Preferences** готова
В результате мы получили вот такой внешний вид плеера:
{{ images:2010-01-15_1205-PSS1_Visual.png }}
Верхний тулбар (toolbar) я отключил специально, чтобы не отвлекал он в процессе конфигурирования.
===== Кнопки управления (графические) =====
Кроме текстовых кнопок в PSS можно сделать графическое оформление кнопок.\\
По сути - каждую кнопочку можно отобразить графическим файлом.\\
[[pss_tutorial#imagebutton_x_y_w_h_path_mover_path_command_options1_options2|$imagebutton(x,y,w,h,path,mover_path,command,options1,options2)]]\\
Синтакс команды аналогичен текстовой кнопке [[interface_creation_on_pss#кнопки_управления_текстовые|$textbutton()]], отличие только в том, что вместо **text** и **mover_text** мы указываем путь к картинке **path** и **mover_path** и списком опций для **options1,options2** \\
Путь может быть как __явно__ инициализирован:
С:\Program Files\foobar2000\images\button_play.png
так и __косвенно__:
%ps_foobar2000_path%\images\button_play.png
Косвенная инициализация более удобна при создании **portable** конфигурации плеера.
Отмечу, что картинка будет автоматически подогнана под ширину **w** и высоту **h** кнопки.\\
Потому, для создания __квадратной__ кнопки нужно выбирать __квадратную__ картинку для сохранения пропорций при отображении.
===== Промотка и громкость =====
Явно бросается в глаза нехватка полосы промотки трека (Seekbar) и регулятора громкости (Volume), хотя громкость не всем нужна по причине недоверия ей из-за влияния на качество воспроизведения.\\
Но всё же рассмотрим, как можно реализовать эти два регулятора с помощью WSH панели.\\
Для этого:
* добавим плагин [[http://code.google.com/p/foo-wsh-panel-mod/downloads/list|WSH Panel Mod]] в папку ''components'' и перезапустим плеер
* вспомним как мы добавляли панели в PSS [[interface_creation_on_pss#второй_способ|Вторым способом]] и добавим 2 панели **WSH Panel Mod**
После добавления, для удобства переименуем **Caption** этих панелей например в **WSH Seekbar** и **WSH Volume** и разместим их таким же способом, как было [[interface_creation_on_pss#размещение_панелей|описано выше]].
Как пример приведу координаты и размеры:
**WSH Seekbar**
left : 460
Top : $sub(%ps_height%,25)
width : $sub(%ps_width%,600)
height : 20
**WSH Volume**
left : $sub(%ps_width%,130)
Top : $sub(%ps_height%,25)
width : 120
height : 20
Панели размещены, но пока они обе являются регуляторами громкости.
==== Пример кода Seekbar для WSH ====
Чтобы преобразовать среднюю (более длинную) WSH панель из регулятора громкости в промотку делаем следующие махинации: :-)\\
* жмем **ПКМ ((ПКМ - это щелчек Правой Кнопки Мыши ;-)))** на длинной WSH панели
* выбираем нижний пункт **Configure...**
* в появившемся окне удаляем весь код регулятора громкости
* и вставляем код промотки
Например такой:
// Flags, used with GdiDrawText
// For more information, see: http://msdn.microsoft.com/en-us/library/dd162498(VS.85).aspx
var DT_TOP = 0x00000000;
var DT_LEFT = 0x00000000;
var DT_CENTER = 0x00000001;
var DT_RIGHT = 0x00000002;
var DT_VCENTER = 0x00000004;
var DT_BOTTOM = 0x00000008;
var DT_WORDBREAK = 0x00000010;
var DT_SINGLELINE = 0x00000020;
var DT_EXPANDTABS = 0x00000040;
var DT_TABSTOP = 0x00000080;
var DT_NOCLIP = 0x00000100;
var DT_EXTERNALLEADING = 0x00000200;
var DT_CALCRECT = 0x00000400;
var DT_NOPREFIX = 0x00000800;
var DT_INTERNAL = 0x00001000;
var DT_EDITCONTROL = 0x00002000;
var DT_PATH_ELLIPSIS = 0x00004000;
var DT_END_ELLIPSIS = 0x00008000;
var DT_MODIFYSTRING = 0x00010000;
var DT_RTLREADING = 0x00020000;
var DT_WORD_ELLIPSIS = 0x00040000;
var DT_NOFULLWIDTHCHARBREAK = 0x00080000;
var DT_HIDEPREFIX = 0x00100000;
var DT_PREFIXONLY = 0x00200000;
function RGB(r,g,b){ return (0xff000000|(r<<16)|(g<<8)|(b)); }
var g_font = gdi.Font("Tahoma", 12, 1);
var g_drag = 0;
var g_drag_seek = 0;
var tfo = fb.TitleFormat("$if(%ispaused%,PAUSE, ) %playback_time% of %length% '('$max(0,$left($muldiv(%playback_time_seconds%,1000,%length_seconds%),$sub($len($muldiv(%playback_time_seconds%,1000,%length_seconds%)),1)))'.'$right( $muldiv(%playback_time_seconds%,1000,%length_seconds%),1)'%)' REM: %playback_time_remaining%");
function TimeFmt(t){
var zpad = function(n){
var str = n.toString();
return (str.length<2) ? "0"+str : str;
}
var h = Math.floor(t/3600); t-=h*3600;
var m = Math.floor(t/60); t-=m*60;
var s = Math.floor(t);
if(h>0) return h.toString()+":"+zpad(m)+":"+zpad(s);
return m.toString()+":"+zpad(s);
}
function on_paint(gr){
var txt = "";
var pos =0;
if(fb.PlaybackTime > 0){
if(g_drag){
pos = window.Width * g_drag_seek;
txt = "Seek " + TimeFmt(g_drag_seek * fb.PlaybackLength) + " / " + TimeFmt(fb.PlaybackLength);
}
else{
pos = window.Width * (fb.PlaybackTime / fb.PlaybackLength);
txt = tfo.Eval();
}
}else
{
txt = "Playback Stopped";
}
gr.FillGradRect( 0, 0, pos, window.Height, 90, RGB(60,10,210), RGB(4,4,93));
gr.FillGradRect(pos, 0, window.Width-pos, window.Height, 90, RGB(00,00,32), RGB(10,10,10));
gr.GdiDrawText(txt, g_font, RGB(50,250,50), 0, 0, window.Width, window.Height, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
gr.DrawRect(0,0, window.Width-1, window.Height-1, 1.0, RGB(150,150,150));
}
function on_mouse_lbtn_down(x,y){
g_drag = 1;
}
function on_mouse_lbtn_up(x,y){
if(g_drag){
g_drag = 0;
g_drag_seek = x / window.Width;
g_drag_seek = (g_drag_seek<0) ? 0 : (g_drag_seek<1) ? g_drag_seek : 1;
fb.PlaybackTime = fb.PlaybackLength * g_drag_seek;
}
}
function on_mouse_move(x,y){
if(g_drag){
g_drag_seek = x / window.Width;
g_drag_seek = (g_drag_seek<0) ? 0 : (g_drag_seek<1) ? g_drag_seek : 1;
window.Repaint();
}
}
function on_playback_time(time){
window.Repaint();
}
function on_playback_stop(){
window.Repaint();
}
function on_playback_starting(cmd, paused){
window.Repaint();
}
function on_playback_new_track(info){
window.Repaint();
}
//EOF
Расматривать и комментировать детали кода не стану - так как для этого уже совсем другая тема нужна. Но рассмотрев код - Вы и сами сможете разобраться как он работает и что за что отвечает в нем.
В результате получили такой вид панели управления:\\
{{ images:2010-01-20_1651_seek_vol_on_wsh.png }}
На данном этапе пока остановимся.\\
Но в планах у меня есть ещё расширить статью и рассмотреть как реализовуются переключатели, информеры, и т.д. с помощью PSS.\\
Если возникли вопросы - задаем их в теме [[http://foobar2000.ru/forum/index.php/topic,1519.0.html|Panel Stack Splitter (foo_uie_panel_splitter)]] \\
Творческого вдохновения всем!!!\\
C уважением **Izotop**