Шкурки. Практика - Справка Light Alloy

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

Что может быть идеей для простой шкурки? Что угодно: от красивого цвета или реализации какой-либо концепции до портирования интерфейса другой программы. Это даже необязательно должен быть другой видеопроигрыватель. Например, можно представить родной интерфейс операционной системы:

Задача эскиза - ответить на такие вопросы:

  1. Какие будут использоваться цвета?
  2. Что и как будет выглядеть?
  3. ... и где располагаться.

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

Информация о шкурке (SkinInfo.txt)

Информация о шкурке не имеет каких либо требований, кроме максимальной длины 45 символов (чтобы уместиться в окне настроек проигрывателя). Просто надо заполнить название шкурки, автора и (при желании) всё остальное. Единственное, избегайте пробелов сразу после знака "равно". В данном случае это выглядит так:

SkinTitle=Ei8ht SkinAuthor=Gilorn SkinVer=4.8.0 SkinWWW=http://www.light-alloy.ru/forum/ru_skins/ei8ht SkinCmt=Training skin SkinAudio=0

Визитка (preview.png)

Две важные детали, которые делают визитку визиткой:

  1. стилизация под шкурку;
  2. Наличие названия (да-да, и на визитке тоже).

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

Рисунки для шкуры

Начиная с этого момента придётся сильно полагаться на эскиз и воображение. Ведь создание рисунков для шкуры оценить невозможно: проигрыватель не понимает просто рисунки.

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

После тщательного размышления было решено оформить отдельными рисунками следующие элементы:

Логотип

С ним проще всего: в файле будет только одно изображение. Всё, что требуется - это просто перенести логотип из эскиза.

Контекстное меню

Здесь уже сложнее, поскольку элементов несколько. Поскольку размер всех элементов стандартен, то можно подумать, как удобно разместить элементы.

Или взять в качестве основы изображение из похожей по оформлению шкурки:

Между прочим, 10 значков контекстного меню являются единым объектом, поэтому изменять их порядок или количество рядов нельзя.

Обратите внимание на фон: он красно-розовый. Его задача - давать однозначный и очевидный ответ на вопрос "это фон?", а также удобно показывать границы отдельных рисунков в файле. Вместо красно-розового цвета можно было подобрать любой другой - это дело личных предпочтений.

К слову, такой модульный подход позволяет копировать часть файла разметки (interface.xml) из старой шкурки в новую.

Наборы цветов

Тут всё просто (масштаб 500 %)...

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

Наиболее разумный вариант - использовать для каждого цвета не один пиксель, а пиксель с иллюстрацией. Конечно, создание такой системы займёт не один час, но в результате появится несравненно более удобный и наглядный механизм выбора цветов. Например, как этот (масштаб 200 %):

Здесь каждый цвет представлен слоем-заливкой "цвет" с графической маской (инструментарий Photoshop). Все цвета удобно сгруппированы по папкам. В результате уже на этапе первоначального подбора цветов видно, как он будет смотреться. Кроме того, каждый слой имеет говорящее имя, так что нужный слой отыскивается очень быстро. Для изменения цвета здесь нужен лишь двойной клик на соответствующем слое.

Рисунки для хинтов

Эти рисунки имеет смысл делать после того, как будут определены цвета хинтов. Цвет фона рисунков сразу можно взять из набора цветов, так что остаётся только нарисовать сами рисунки. Для чёткого различия рисунков рекомендуется разделить их заметной линией:

Верхняя панель

Верхняя панель будет содержать:

Особых проблем здесь быть не должно: большинство элементов однородны:

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

Есть несколько нюансов, касающихся бордюра:

  1. пространство внутри бордюра тоже используется, его можно заметить во время изменения размера окна проигрывателя, поэтому его нужно заполнять гармонирующим цветом (в данном случае это - цвет разделителя списка);
  2. Бордюр, в отличие от остальных контролов, растягивается не в одной точке а в прямоугольнике (его интерполяция производится по соседним пикселям);

Панель списка

Панель списка будет содержать:

Изображения панели списка создаются аналогично верхней панели:

Нижняя панель

Это самая сложная панель, поскольку она содержит наиболее разнородные элементы:

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

На представленном выше рисунке можно увидеть сгруппированными следующие группы элементов:

Элементы сгруппированы примерно так же, как они будут располагаться в самой шкурке, а значит довольно просто понять, что чем является. Также они имеют объединённую разметку,что визуально объединяет их и позволяет идентифицировать.

Несложно заметить, что часть элементов выглядит не так, как на эскизе: пройденный участок на шкале времени, шрифт длительности, бегунок. С бегунком проще всего: он просто нарисован прозрачным цветом (#00FF00). Остальные элементы в процессе рисования были признаны негармоничными и потому - перерисованы.

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

Файл разметки (interface.xml)

Это самая важная часть работы по созданию шкурки, которую хорошо бы проверять наживую (т.е. примерять недошкурку на проигрыватель). Перво-наперво, нужно создать заготовку: разместить блоки кода в удобном порядке (помним про кодировку UTF-8 with signature):

<?xml version="1.0" encoding="UTF-8"?> <SKIN type="standart" minsize="100,100"> <!-- ================================================================== --> <!-- ============= PREDEFINED DECORATIVE IMAGES. ID FIXED ============= --> <!-- ================================================================== --> <!-- Logo --> <IMAGE id="Logo" file="logo.bmp"> <AREA id="Splash" pos="0,0" size="200,170"/> <!-- Logo picture --> </IMAGE> <!-- Color sets --> <IMAGE id="Color" file="Color.bmp"> <AREA id="LACaption" pos="1,1" size="1,2"/> <!-- title --> <AREA id="OSD" pos="141,18" size="1,5"/> <!-- OSD --> <AREA id="Timeline" pos="71,83" size="1,2"/> <!-- Autorewind --> <AREA id="Hint" pos="141,83" size="1,3"/> <!-- Hints --> <AREA id="PL" pos="1,18" size="1,12"/> <!-- Playlist --> <AREA id="Menu" pos="71,18" size="1,7"/> <!-- Context menu --> <AREA id="FOD_TV" pos="1,83" size="1,18"/> <!-- Fullscreen file opendialog --> <AREA id="SOD_TV" pos="1,83" size="1,18"/> <!-- Fullscreen subs opendialog --> </IMAGE> <!-- Context menu --> <IMAGE id="Menu" file="Menu.bmp"> <AREA id="bg" pos="17,0" size="20,28"/> <!-- Left column background --> <AREA id="pics" pos="0,29" size="33,84"/> <!-- Icons --> <AREA id="Checked" pos="0,12" size="16,16"/> <!-- Marker --> <AREA id="Bookmark" pos="0,0" size="11,11"/> <!-- Playlist bookmark --> </IMAGE> <!-- Hint's images --> <IMAGE id="Hint" file="Hint.bmp"> <AREA id="Lclick" pos="0,0" size="22,22"/> <!-- L-click mouse --> <AREA id="Rclick" pos="23,0" size="22,22"/> <!-- R-click mouse --> </IMAGE> <!-- ================================================================== --> <!-- ======================= GRAPHIC CONSTANTS ======================== --> <!-- ================================================================== --> <!-- Parameters: id=%unique name%; pos=%left,top pixel of constanta% // size=%size of constanta (can be ignored for buttons)%. --> <!-- Header --> <IMAGE id="Hd" file="Header.bmp"> <AREA id="" pos="," size=","/> </IMAGE> <!-- Footer --> <IMAGE id="Ft" file="Footer.bmp"> <AREA id="" pos="," size=","/> <!-- timeline --> <AREA id="SeekBGfill" pos="," size=","/> <!-- Timeline filled --> <AREA id="SeekThumb" pos="," size=","/> <!-- track, align=bottom --> <AREA id="SeekBG" pos="," size=","/> <!-- Timeline empty --> <AREA id="SeekHiTick" pos="," size=","/> <!-- main scale lines --> <AREA id="SeekLoTick" pos="," size=","/> <!-- secondary scale lines --> <AREA id="SeekChapter" pos="," size=","/> <!-- Chapter --> <!-- volume --> <AREA id="VolBGF" pos="," size=","/> <!-- Volume filled --> <AREA id="VolThumb" pos="," size=","/> <!-- track --> <AREA id="VolBG" pos="," size=","/> <!-- Volume empty --> </IMAGE> <!-- Playlist --> <IMAGE id="Pl" file="Playlist.bmp"> <AREA id="" pos="," size=","/> </IMAGE> <!-- ================================================================== --> <!-- ========================= GRAPHIC FONTS ========================== --> <!-- ================================================================== --> <FONT id="Digits" img="FT.Digits" chars="0123456789: -"/> <!-- for Position --> <FONT id="Digits_dur" img="FT.Digits_dur" chars="0123456789: "/> <!-- for Duration --> <!-- ================================================================== --> <!-- ============================ CONTROLS ============================ --> <!-- ================================================================== --> <!-- Window border controls --> <CTLDEF id="WndBorder" type="Panel" bg="Hd.brd" size="30,120" border_size="6,1,6,6" bgsplit_lt="6,26" bgsplit_rb="6,6"/> <!-- Header controls --> <CTLDEF id="Caption" type="Panel" size="400," bgsplit="10,10" bg="Hd.bg"> <!-- Header background --> <CONTROL type="Text" pos="," size="," font="Verdana" fontsz="11" top_delta="-1" bold="0" bg="Hd.TitleBG" bgsplit="5,5" text="{TITLE}"/> <!-- Title --> <CONTROL type="GfxBtn" pos="," size="," img="Hd." link=""/> </CTLDEF> <!-- Footer controls --> <CTLDEF id="CtlPanel" type="Panel" size="400," bgsplit="10,10" bg="Ft.bg"> <!-- Footer background --> <CONTROL type="Seeker" pos="," size="," bgsplit="," OpeningPos="0" OpeningHeight="14" bg="Ft.SeekBG" bgfill="Ft.SeekBGfill" thumb="Ft.SeekThumb" lotick="Ft.SeekLoTick" hitick="Ft.SeekHiTick" digits_ypos="0" ticks_ypos="7" chapter="Ft.SeekChapter" chapter_pos="-1,12" /> <!-- Timeline --> <CONTROL type="Slider" pos="," size="," bgsplit="5,10" bg="Ft.VolBG" bgfill="Ft.VolBGF" thumb="Ft.VolThumb"/> <!-- Volume --> <CONTROL type="GfxBtn" pos="," size="," img="Ft." link=""/> <CONTROL type="Panel" pos="," size="," align="center" bgsplit="10,10" bg="Ft.CenterBg"> <!-- Central panel --> <CONTROL type="GfxBtn" pos="," size="," img="Ft." link=""/> <!-- [Stop] --> </CONTROL> <CONTROL type="Text" pos="," size="," font="Digits" text=" {POS}" link="Position.Switch"/> <!-- Position --> <CONTROL type="Text" pos="," size="," font="Digits_dur" text="{DUR}"/> <!-- Duration --> </CTLDEF> <!-- Playlist controls --> <CTLDEF id="PListPanel" type="Panel" bg="Pl.bg" size="200,42" bgsplit="10,10"> <!-- Playlist background --> <CONTROL type="GfxBtn" pos="," size="," img="Pl." link=""/> </CTLDEF> </SKIN>

В заготовке находится 4 раздела, причём первые два отличаются только тем, что в первом меняются только координаты (и то не всегда), а во втором меняется всё.

Зелёный текст - это комментарии. Они помогают ориентироваться в тексте, но при этом игнорируются программой.

Объявление графических констант

Каждая константа имеет уникальное имя, положение и размер. Если имя можно взять из справочника, то положение с размером придётся определять самостоятельно. Делается это с помощью графического редактора.

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

Для целей разметки просто идеально подойдёт PhotoFiltre (бесплатная для некоммерческого использования, официальный сайт, портативная версия). Она при выделении позволяет сразу узнать и позицию, и размер. Причём размер выделения можно на месте поправить мышкой:

Таким образом определение всех значений происходит в четыре этапа:

  1. В файл разметки добавляется новая строка вида "<AREA id="," pos="" size=","/>".
  2. Из справочника подставляется id.
  3. В графическом редакторе определяются значения позиции и размера.
  4. Эти значения подставляются в pos="," size=",".

В результате 15-и минут усилий первая часть файла разметки приобретает следующий вид:

<!-- ================================================================== --> <!-- ============= PREDEFINED DECORATIVE IMAGES. ID FIXED ============= --> <!-- ================================================================== --> <!-- Logo --> <IMAGE id="Logo" file="logo.bmp"> <AREA id="Splash" pos="0,0" size="200,170"/> <!-- Logo picture --> </IMAGE> <!-- Color sets --> <IMAGE id="Color" file="Color.bmp"> <AREA id="LACaption" pos="1,1" size="1,2"/> <!-- title --> <AREA id="OSD" pos="141,18" size="1,5"/> <!-- OSD --> <AREA id="Timeline" pos="71,83" size="1,2"/> <!-- Autorewind --> <AREA id="Hint" pos="141,83" size="1,3"/> <!-- Hints --> <AREA id="PL" pos="1,18" size="1,12"/> <!-- Playlist --> <AREA id="Menu" pos="71,18" size="1,7"/> <!-- Context menu --> <AREA id="FOD_TV" pos="1,83" size="1,18"/> <!-- Fullscreen file opendialog --> <AREA id="SOD_TV" pos="1,83" size="1,18"/> <!-- Fullscreen subs opendialog --> </IMAGE> <!-- Context menu --> <IMAGE id="Menu" file="Menu.bmp"> <AREA id="bg" pos="17,0" size="20,28"/> <!-- Left column background --> <AREA id="pics" pos="0,29" size="33,84"/> <!-- Icons --> <AREA id="Checked" pos="0,12" size="16,16"/> <!-- Marker --> <AREA id="Bookmark" pos="0,0" size="11,11"/> <!-- Playlist bookmark --> </IMAGE> <!-- Hint's images --> <IMAGE id="Hint" file="Hint.bmp"> <AREA id="Lclick" pos="0,0" size="22,22"/> <!-- L-click mouse --> <AREA id="Rclick" pos="23,0" size="22,22"/> <!-- R-click mouse --> </IMAGE> <!-- ================================================================== --> <!-- ======================= GRAPHIC CONSTANTS ======================== --> <!-- ================================================================== --> <!-- Parameters: id=%unique name%; pos=%left,top pixel of constanta% // size=%size of constanta (can be ignored for buttons)%. --> <!-- Header --> <IMAGE id="Hd" file="Header.bmp"> <AREA id="brd" pos="0,0" size="30,62"/> <!-- Window border --> <AREA id="bg" pos="6,1" size="18,25"/> <!-- Header background --> <AREA id="TitleBG" pos="6,1" size="18,20"/> <!-- Title background--> <AREA id="btAbout" pos="31,0" size="26,62"/> <!-- [About Light Alloy] --> <AREA id="btTop" pos="58,0" size="53,62"/> <!-- [Always on top]--> <AREA id="btMin" pos="112,0" size="26,62"/> <!-- [Minimize] --> <AREA id="btMax" pos="139,0" size="53,62"/> <!-- [Window / FullScreen] --> <AREA id="btExit" pos="193,0" size="45,62"/> <!-- [Exit] --> </IMAGE> <!-- Footer --> <IMAGE id="Ft" file="Footer.bmp"> <AREA id="bg" pos="0,0" size="30,70"/> <!-- Footer background --> <AREA id="CenterBg" pos="0,14" size="30,56"/> <!-- Central panel background --> <AREA id="btStop" pos="0,71" size="42,74"/> <!-- [Stop] --> <AREA id="btPlPrev" pos="43,71" size="43,74"/> <!-- [Previous in playlist] --> <AREA id="btPlNext" pos="87,71" size="43,74"/> <!-- [Next in playlist] --> <AREA id="btOpen" pos="131,71" size="42,74"/> <!-- [Open file] --> <AREA id="BtPlay" pos="174,0" size="101,152"/> <!-- [Play / pause] --> <AREA id="BtMute" pos="276,0" size="43,182"/> <!-- [Mute] --> <AREA id="BtPlist" pos="320,0" size="43,182"/> <!-- [Playlist] --> <AREA id="Digits" pos="33,18" size="138,16"/> <!-- digits for Position --> <AREA id="Digits_dur" pos="33,37" size="68,8"/> <!-- digits for Duration --> <!-- timeline --> <AREA id="SeekBGfill" pos="33,1" size="24,14"/> <!-- Timeline filled --> <AREA id="SeekThumb" pos="64,1" size="14,14"/> <!-- track, align=bottom --> <AREA id="SeekBG" pos="79,1" size="24,14"/> <!-- Timeline empty --> <AREA id="SeekHiTick" pos="58,1" size="1,3"/> <!-- main scale lines --> <AREA id="SeekLoTick" pos="59,1" size="1,3"/> <!-- secondary scale lines --> <AREA id="SeekChapter" pos="58,13" size="3,2"/> <!-- Chapter --> <!-- volume --> <AREA id="VolBGF" pos="107,1" size="9,14"/> <!-- Volume filled --> <AREA id="VolThumb" pos="117,1" size="14,14"/> <!-- track --> <AREA id="VolBG" pos="132,1" size="9,14"/> <!-- Volume empty --> </IMAGE> <!-- Playlist --> <IMAGE id="Pl" file="Playlist.bmp"> <AREA id="bg" pos="0,0" size="20,42"/> <!-- Playlist background --> <AREA id="btPlay" pos="21,0" size="31,83"/> <!-- [Play selected] --> <AREA id="btAdd" pos="53,0" size="31,83"/> <!-- [Add file(s) to playlist] --> <AREA id="btRem" pos="85,0" size="31,83"/> <!-- [Remove from playlist] --> <AREA id="btMarks" pos="117,0" size="63,83"/> <!-- [Bookmarks in playlist] --> </IMAGE>

Создание графического шрифта

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

<FONT id="Digits" img="FT.Digits" chars="0123456789: -"/> <!-- for Position --> <FONT id="Digits_dur" img="FT.Digits_dur" chars="0123456789: "/> <!-- for Duration -->

Применение констант и шрифтов в контролах

Это финальный этап создания шкурки. И его желательно визуально контролировать.

Есть несколько примечаний, которые необходимо сделать:

  1. позиция вида "-90,6" подразумевает расстояние между правым краем панели и левым верхним пикселем контрола, а вовсе не ширину пустого места между краем и контролом.
  2. запись вида pos="140,18" size="-50,24" сообщает, что ширина контрола составляет от точки 140 до точки, смещённой влево относительно правого края панели на 50 пикселей. Т.е. по сути определяется позиция правой грани контрола;
  3. Как сделать выравнивание нескольких контролов по центру? - надо создать плавающую панель, которая располагается по центру, а уже в ней расположить контролы;
  4. Если используется дополнительная плавающая панель, то координаты вложенных в неё контролов отсчитываются от левого верхнего угла именно этой плавающей панели.

В примечаниях это может выглядеть сложно, но если посмотреть их на живой шкуре, станет понятнее.

От чего зависят позиция и размер контролов? Размер - только от того, какое изображение было нарисовано (кроме панелей и полос прокрутки громкости и шкалы времени - они тянутся). Позиция не зависит ни от чего. Она определяется лишь задумкой автора.

<!-- ================================================================== --> <!-- ============================ CONTROLS ============================ --> <!-- ================================================================== --> <!-- Window border controls --> <CTLDEF id="WndBorder" type="Panel" bg="Hd.brd" size="30,120" border_size="6,1,6,6" bgsplit_lt="6,26" bgsplit_rb="6,6"/> <!-- Header controls --> <CTLDEF id="Caption" type="Panel" size="400,25" bgsplit="14,10" bg="Hd.bg"> <!-- Header background --> <CONTROL type="Text" pos="40,3" size="-80,20" font="Verdana" fontsz="11" top_delta="-1" bold="0" bg="Hd.TitleBG" bgsplit="8,5" text="{TITLE}"/> <!-- Title --> <CONTROL type="GfxBtn" pos="0,0" size="26,20" img="Hd.btAbout" link="App.About"/> <!-- [About Light Alloy] --> <CONTROL type="GfxBtn" pos="27,0" size="26,20" img="Hd.btTop" link="App.StayOnTop"/> <!-- [Always on top] --> <CONTROL type="GfxBtn" pos="-99,0" size="26,20" img="Hd.btMin" link="App.Minimize"/> <!-- [Minimize] --> <CONTROL type="GfxBtn" pos="-72,0" size="26,20" img="Hd.btMax" link="Window.FullScreen"/> <!-- [Window / FullScreen] --> <CONTROL type="GfxBtn" pos="-45,0" size="45,20" img="Hd.btExit" link="App.Exit"/> <!-- [Exit] --> </CTLDEF> <!-- Footer controls --> <CTLDEF id="CtlPanel" type="Panel" size="400,70" bgsplit="10,10" bg="Ft.bg"> <!-- Footer background --> <CONTROL type="Seeker" pos="0,0" size="-1,14" bgsplit="12,6" OpeningPos="0" OpeningHeight="14" bg="Ft.SeekBG" bgfill="Ft.SeekBGfill" thumb="Ft.SeekThumb" lotick="Ft.SeekLoTick" hitick="Ft.SeekHiTick" digits_ypos="4" ticks_ypos="0" chapter="Ft.SeekChapter" chapter_pos="-1,12" /> <!-- Timeline --> <CONTROL type="GfxBtn" pos="0,14" size="21,56" img="Ft.btMute" link="Audio.Mute"/> <!-- [Mute] --> <CONTROL type="GfxBtn" pos="-21,14" size="21,56" img="Ft.btPlist" link="Window.PlayList"/> <!-- [Playlist] --> <CONTROL type="Slider" pos="28,35" size="90,14" bgsplit="5,10" bg="Ft.VolBG" bgfill="Ft.VolBGF" thumb="Ft.VolThumb"/> <!-- Volume --> <CONTROL type="Panel" pos="0,17" align="center" size="218,50" bgsplit="10,10" bg="Ft.CenterBg"> <!-- Central panel --> <CONTROL type="GfxBtn" pos="0,13" size="42,24" img="Ft.btStop" link="Playback.RealStop"/> <!-- [Stop] --> <CONTROL type="GfxBtn" pos="42,13" size="43,24" img="Ft.btPlPrev" link="PlayList.Prev"/> <!-- [Previous in playlist] --> <CONTROL type="GfxBtn" pos="133,13" size="43,24" img="Ft.btPlNext" link="PlayList.Next"/> <!-- [Next in playlist] --> <CONTROL type="GfxBtn" pos="84,0" size="50,50" img="Ft.btPlay" link="App.SuperPlay"/> <!-- [Play / pause] --> <CONTROL type="GfxBtn" pos="176,13" size="42,24" img="Ft.btOpen" link="PlayList.OpenFiles"/><!-- [Open file] --> </CONTROL> <CONTROL type="Text" pos="-100,33" size="75,15" font="Digits" text=" {POS}" link="Position.Switch"/> <!-- Position --> <CONTROL type="Text" pos="-65,52" size="38,7" font="Digits_dur" text="{DUR}"/> <!-- Duration --> </CTLDEF> <!-- Playlist controls --> <CTLDEF id="PListPanel" type="Panel" bg="Pl.bg" size="200,42" bgsplit="10,10"> <!-- Playlist background --> <CONTROL type="GfxBtn" pos="10,7" size="31,27" img="Pl.btPlay" link="PList.Play"/> <!-- [Play selected] --> <CONTROL type="GfxBtn" pos="45,7" size="31,27" img="Pl.btAdd" link="PList.AddFiles"/> <!-- [Add file(s) to playlist] --> <CONTROL type="GfxBtn" pos="80,7" size="31,27" img="Pl.btRem" link="PList.Remove"/> <!-- [Remove from playlist] --> <CONTROL type="GfxBtn" pos="115,7" size="31,27" img="Pl.btMarks" link="PList.ShowMarks"/><!-- [Bookmarks in playlist] --> </CTLDEF>

После того, как все элементы получают свою позицию и размер, шкурку надо посмотреть на предмет проблем, некрасивых решений и недоработок. Если что - поправить позицию контролов.

После этого этапа работа над файлом разметки завершена.

Сборка шкурки

На данный момент шкуркой уже можно пользоваться но всё ещё неудобно передавать. Теперь её нужно оптимизировать и упаковать.

Оптимизация шкурки

Оптимизация заключается в изменении графических файлов.

Как известно, формат "bmp" очень расточительно расходует место, поскольку он не имеет встроенных возможностей к сжатию. Но не всё так плохо. Взамен можно сыграть на глубине цвета. Рисунок формата "bmp" поддерживает такие варианты глубины цвета:

Количество цветов в рисунках нашей шкурки следующее:

Как видно, большинство изображении можно сжать до 8-битной глубины цвета. В принципе, даже если сжать Footer.bmp и Menu.bmp, это будет незаметно. Чтобы в новом изображении сохранились нужные цвета, их необходимо проиндексировать. Как это сделать, зависит от графического редактора. Например, в Photoshop нужно перейти в главное меню \ Изображение \ Режим \ Индексированные цвета.... В результате объёмы файлов изменились следующим образом:

Файл Старый размер, KiB Новая глубина цвета Новый размер, KiB
Color.bmp 64,5 8 бит 21,6
Footer.bmp 182 8 бит 61,4
Header.bmp 43,4 8 бит 14,6
hint.bmp 3,0 8 бит 1,2
Logo.bmp 99.6 24 бит 99.6
Menu.bmp 12,4 8 бит 5,6
Playlist.bmp 43,8 8 бит 14,8
ВСЕГО 448,7 - 218,8

Как оказалось общий объём рисунков уменьшился примерно вдвое. Впечатляет! Аналогичным образом нужно поступить с файлом "preview.png" Единственная разница, что формат "png" не имеет 4-битную глубину цвета, а только полную (16,8 млн. цветов) или 8-битную (256 цветов).

Упаковка шкурки

Всё довольно просто: берутся все нужные файлы и архивируются в формат "zip". Уровень сжатия - любой, но рекомендуется максимальный. Настройки сжатия лучше оставить по умолчанию, поскольку Light Alloy не понимает современные методы сжатия навроде LZMA.

Наконец, финальный штрих: у шкурки необходимо поменять расширение. Был ".zip" - стал ".las".

Результат

Наконец, можно насладиться результатом!

Сохранить шкурку...

Сохранить исходные файлы к шкурке...