====== Создание интерфейса на основе 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**