Как вы уже знаете, Гена использовал на своем рабочем рабочем столе так называемые "виджеты" - приблуды, расширяющие возможности рабочего стола. Именно виджеты позволяют увидеть погоду, если "в падлу встать и в окно посмотреть", именно виджетами являются те самые "секретные кнопки" и т.д.
В этой статье мы расскажем как сделать свой виджет самому.

Мы разберем процесс создания виджета с самого начала на примере виджета Кнопка слива.

Для начала обзаведемся необходимым инструментарием.

У вас уже установлен Yahoo! Widget Engine? Если нет - скачиваем и устанавливаем.

Скачиваем и устанавливаем Yahoo! Widgets SDK. Тогда все нижеследующее вам скачивать не понадобиться - все это включено в SDK. Итак, вам понадобятся:

1) Widget Creation Script for Photoshop CS
2) Widget Converter. Если вас не пугает конвертер, работающий из командной строки - берем версию 1.0, если же хочется чтоб было удобно и без лишнего гемороя - берем версию 2.0.
3) Документация.
В обязательном порядке вам понадобится Yahoo! Widget Engine Reference Guide 3.1.1 и необязательно - Widget Creation Tutorial - это что-то вроде этой статьи, но полнее и на английском языке.

В нагрузку ко всему этому вам нужен Photoshop CS. (бесплатный фотожоп с русиком и плагинами, весом 330 метров здесь)

Итак, все скачано и установлено. Приступим.
Создание виджета начинается... с чего бы вы думали? С Фотошопа!
Открываем наш ненаглядный и начинаем ваять внешний вид виджета. В нашем случае - открываем картинку с кнопкой и обрезаем до нужного размера, чтобы вокруг самого слива было еще небольшое пространство (можно оставить только сам слив - но мне так больше нравиться). Итак один слой у нас есть - с обрезанной картинкой. Назовем его чем-нибудь вроде backgr. Далее нам надо еще два слоя - вырезаем точно сам слив и ложим его слоем повыше. Обзовем его button. На третий слой ложим только что вырезанный слив, осветляем его и называем button_over. Итак у нас есть три слоя, видимость на всех включена - запускаем скрипт.
Идем в File > Scripts > Browse (для английского CS2), там где Тип файлов ставим Java Script File *.js и указываем на Create Widget.js (Это и есть Widget Creation Script for Photoshop CS - куда вы его положите я не знаю). Открывается окошко - вводим желаемое имя виджета, имя автора и путь куда будет сохранен виджет. После сообщения Creation complete закрывам фотошоп - он свою (а точнее часть вашей) работы сделал. Идем в то место, куда вы сохранили виджет. Что мы видим? Мы видим там папочку, названную имя_вашего_виджета.widget. Внутри папка Contents. Внутри нее и лежит ваш виджет (Яйцо в утке, утка в зайце и т.д. =)). В некомпилированном виде он представляет из себя XML файл имя_виджета.kon и папку Resources - в ней лежит внешний вид виджета, разбитый на три файла - в нашем случае backgr.png, button.png и button_over.png. В принципе, если вам уже не терпиться посмотреть на свой виджет - можете запустить kon-файл... Поигравшись, возвращаемся добавлять интерактивность. Открываем вашим любимым текстовым редактором файл имя_виджета.kon. Что мы видим? Видим че-то вроде того:

<?xml version="1.0" encoding="macintosh"?>
<widget version="1.0" minimumVersion="2.0">
<debug>on</debug>
<!--
Untitled-1

Generated by Photoshop Widget Generator Script
Copyright (C) 2004 - 2005 Pixoria, Inc. All Rights Reserved.

Any modifications will be lost if the generation script is run again.
-->

<window title="Untitled-1">
<name>mainWindow</name>
<width>1024</width>
<height>768</height>
<visible>1</visible>
<shadow>0</shadow>
</window>

<image src="Resources/Background.png">
<name>Background</name>
<hOffset>0</hOffset>
<vOffset>0</vOffset>
<width>1024</width>
<height>768</height>
<opacity>100%</opacity>
</image>

</widget>

Как видим все элементы описываются с помощью тегов. Например элемент window - это само окно виджета описывается тегами:

<window title="Untitled-1">// заголовок окна
<name>mainWindow</name>
<width>1024</width>// ширина
<height>768</height>// высота
<visible>1</visible>//видимость
<shadow>0</shadow>// тень
</window>

с разными свойствами. За расшифровкой каждого из них отправляю вас к Widget Engine Reference Guide - там простым языком и с наглядными примерами все описано.

Теги <image> это и есть ваши картинки. Так вот. Интерактивность добавляется вот так:

<image src="Resources/button.png"> // это путь к картинке
<name>button</name> // ее имя
<hOffset>111</hOffset>// положение относительно
<vOffset>104</vOffset>// окна виджета
<width>224</width>
<height>225</height>
<opacity>100%</opacity>// прозрачность
<onMouseEnter>// вызывается, если мыш. находиться над объектом
button.src = "Resources/button_over.png";// просто меняем объекту картинку
</onMouseEnter>
<onMouseExit>// когда мыш. уходит с объекта
button.src = "Resources/button.png";// возвращаем все как было
</onMouseExit>
<onMouseUp> если нажата левая кнопка мыша
//пишем здесь что -нибудь, напимер
alert("Вы нажали на кнопку");
</onMouseUp>
</image>

Я думаю, основы вы уже поняли, поэтому далее идет исходный код виджета "Кнопка слива" с необходимыми комментариями. Но для начала приведу структуру виджета:

sliv_button.kon
resourses ->
-backgr.png
-button.png
-button_over.png
-about.png // это изображение показывается, если выбрать из контекстного меню "О программе ..."
-sliv_sound.mp3 // звук слива
tools ->
rasdial.exe //

rasdial.exe - это стандартная виндовская прога для соединения с инетом. Именно она и устанавливает соединение.

<?xml version="1.0" encoding="macintosh"?>
<widget version="1.2" minimumVersion="2.0">
<debug>off</debug>// дебаг косоль
<!--
sliv_button
Written by: _SKif_
Специально для hottabych.net

Generated by Photoshop Widget Generator Script
Copyright (C) 2004 - 2005 Pixoria, Inc. All Rights Reserved.
-->

<window title="Кнопка слива"> // название окна
<name>mainWindow</name> // имя окна
<width>449</width> // его ширина
<height>435</height> // высота
<visible>1</visible> // видимость
<shadow>0</shadow> // тень
<onFirstDisplay> // то что между этими тегами выполняется при первом запуске виджета
mainWindow.locked = true; // запретить перетаскивание виджета
mainWindow.level = "desktop" // его уровень - можно потом поменять в настройках
// так как виджет делался из большой картинки 1600х1200 - это подгонит его размеры к разрешению пользователя
mainWindow.width = screen.width/1600*mainWindow.width;
mainWindow.height= screen.height/1200*mainWindow.height;
// то же самое для картинки backgr и button
backgr.width = screen.width/1600*backgr.width;
backgr.height= screen.height/1200*backgr.height;

button.width = screen.width/1600*button.width;
button.height= screen.height/1200*button.height;

// центрирование окна
mainWindow.hOffset = screen.width/2-mainWindow.width/2;
mainWindow.vOffset = screen.height/2-mainWindow.height/2;

// центрирование кнопки в окне
button.hOffset = mainWindow.width/2-button.width/2;
button.vOffset = mainWindow.height/2-button.height/2;

// Первоначальные настройки
alert("Настройте ваше соединение");
showWidgetPreferences();// показывает окно настроек виджета

</onFirstDisplay>
</window>
// здесь мы встречаем нечто новое, о именно тэги, описывающие добавление новых настроек виджету
<preferenceGroup name="prefsDial" // создаем новую группу настроек с именем prefsDiad для настроек соединения
title="Настройки соединения"/>

<preference name="prefNameConnection" // создаем настройку имени соединения
group="prefsDial" // в только что созданной группе prefsDial
type="text" // ее тип - текстовое поле
style="open"
title="Введите имя соединения"

/>
// все также
<preference name="prefUser"
group="prefsDial"
type="text"
style="open"
title="Введите имя пользователя"

/>

<preference name="prefPass"
group="prefsDial"
type="text"
secure="yes"
title="Введите пароль"
/>
// здесь появляется новая группа "Другие настройки"
<preferenceGroup name="prefsOther"
title="Другие настройки"/>

<preference name="prefSize"// настройка размеров виджета
group="prefsOther"
style="open"
title="Размер"
defaultValue = 100 // значение по умолчанию
description = "Масштабирование виджета"
>
<type>slider</type>// ее тип - ползунок
<ticks>5</ticks> // содержит 5 меток
<tickLabel>x1</tickLabel>// а это надписи к меткам
<tickLabel>x1,5</tickLabel>
<tickLabel>x2</tickLabel>
<tickLabel>x2,5</tickLabel>
<tickLabel>x3</tickLabel>
<minLength>100</minLength> // минимальное значение
<maxLength>300</maxLength> // максимальное
</preference>

<preference name="prefShowMessage"// настройка сообщения
group="prefsOther"
style="open"
title="Показывать сообщение"
defaultValue = "0" // чекбокс принимает 2 значения 0 и 1
description = 'Определяет, будет ли показываться сообщение Соединение установлено"'
>
<type>checkbox</type> // типа чекбокс
</preference>
// все тоже самое
<preference name="prefNoSound"
group="prefsOther"
style="open"
title="НЕ использовать звуки"
defaultValue = "0"
>
<type>checkbox</type>
</preference>

<preference name="prefPlaySound"
group="prefsOther"
style="open"
title="Проигрывать стандартный звук слива"
defaultValue = "1"
>
<type>checkbox</type>
</preference>
// а вот это новое
<preference name="prefUserSound"
group="prefsOther"
style="open"
title="Проигрывать свой звук"
defaultValue = ""
description = "Выберите свой звук"
>
<type>selector</type>// тип - не знаю как по-русски, короче может открывать диалоговое окно для выбора файла
<extension>.mp3</extension>// можно задать поддерживаемые расширения
<extension>.WAV</extension>
<extension>.AIFF</extension>
<extension>.AU</extension>
<extension>.SND</extension>
</preference>

<preference name="prefCenter"
group="prefsOther"
style="open"
title="Центрировать"
defaultValue = "0"
description = "Определяет, будет ли кнопка выровнена по центру рабочего стола. Полезно для тех кто использует кнопку вместе с обоями"
>
<type>checkbox</type>
</preference>

<preference name="prefVoice"
group="prefsOther"
style="open"
title="Голосовые сообщения"
defaultValue = "0"
description = "Голос, сообщающий о коннекте/дисконнекте"
>
<type>checkbox</type>
</preference>
// теперь тэг action. Он реагирует на некоторые события, происходящие с виджетом
<action trigger="onLoad">// это например активируется при загрузке виджета
// объявляем переменную size
var size = preferences.prefSize.value/100;
// что мы сейчас сделали? Мы считали из настроек настройку prefSize (помните, чуть выше мы ее создавали?), разделили на 100 и присвоили переменной size
// так мы получаем доступ к настройке : references.имя_настройки.value
// далее устанавливаем размеры окна и его элементов
mainWindow.width = screen.width/1600*mainWindow.width*size;
mainWindow.height= screen.height/1200*mainWindow.height*size;

backgr.width = screen.width/1600*backgr.width*size;
backgr.height= screen.height/1200*backgr.height*size;

button.width = screen.width/1600*button.width*size;
button.height= screen.height/1200*button.height*size;

// центрирование кнопки в окне

button.hOffset = mainWindow.width/2-button.width/2;
button.vOffset = mainWindow.height/2-button.height/2;

if (preferences.prefCenter.value==1) {
// центрирование окна
mainWindow.hOffset = screen.width/2-mainWindow.width/2;
mainWindow.vOffset = screen.height/2-mainWindow.height/2;


}
// здесь мы проверяем, заданны ли настройки соединения - это критично, т.к. без них мы не сможем законнектиться
if (!preferences.prefNameConnection.value) alert("Введите имя соединения");// дословно: если нет значения настройки prefNameConnection то показываем алерт
if (!preferences.prefUser.value) alert("Введите имя пользователя, которое вы используете для подключения к интернету");
if (!preferences.prefPass.value) alert("Введите пароль для подключения к интернету");

// теперь к звуку
var sound = "Resources/sliv_sound.mp3";// извлекаем звук
if (preferences.prefPlaySound.value == 0) sound = preferences.prefUserSound.value;// если не стоит галочка "Проигрывать стандартный звук слива" то sound присваивается определенный пользователем звук.
// извлекаем из виджета прогу rasdial. Переменная converter теперь содержит ее адрес
converter = widget.extractFile("tools/rasdial.exe");
// надо проверить, подключен ли инет
var connected = false;// по дефолту false
// новый объект url
var url = new URL();
url.location = "http://hottabych.net";
url.fetch();// отправить запрос
if ( url.response == 200 ){ // если ответ 200 ОК
connected = true; // значит подключено
}
</action>

<action trigger="onPreferencesChanged"> // при изменении настроек
reloadWidget();// перезагрузим виджет
</action>

// уже знакомый объект image
<image src="Resources/backgr.png">
<name>backgr</name>
<hOffset>0</hOffset>
<vOffset>0</vOffset>
<width>435</width>
<height>435</height>
<opacity>100%</opacity>
</image>

<image src="Resources/button.png">
<name>button</name>
<hOffset>111</hOffset>
<vOffset>104</vOffset>
<width>224</width>
<height>225</height>
<opacity>100%</opacity>
<onMouseEnter>
button.src = "Resources/button_over.png";
</onMouseEnter>
<onMouseExit>
button.src = "Resources/button.png";
</onMouseExit>
<onMouseUp>
if (connected){
if (preferences.prefNoSound.value!=1) play(sound); // проиграть звук

// запускаем converter с переменными
runCommand('\"' + converter + '\" '+preferences.prefNameConnection.value + '\ /disconnect');
connected = false;
if (preferences.prefVoice.value==1)speak("disconnected");
// функция speak("что_сказать") проговаривает стандартным виндовским голосом что вы захотите но только по-английски
}else{
if (preferences.prefNoSound.value!=1) play(sound);
runCommand('\"' + converter + '\" '+preferences.prefNameConnection.value + '\ '+preferences.prefUser.value + '\ '+preferences.prefPass.value);
connected = true;
if (preferences.prefVoice.value==1) speak("connected");
if (preferences.prefShowMessage.value==1) alert("Соединение установлено");
}
</onMouseUp>
</image>
// описывает опцию about
<about-box>
<image>Resources/About.png</image> // его изображение
<about-text>// а это текст - ссылка
<data>Hottabych.net</data>
<url>http://Hottabych.net</url>
<font>Arial</font>
<size>16</size>
<hOffset>190</hOffset>
<vOffset>168</vOffset>
<color>#fff000</color>
<shadow>
<color>#000000</color>
<hOffset>0</hOffset>
<vOffset>1</vOffset>
</shadow>
</about-text>
</about-box>

</widget>

Как пользоваться Widget Converter:
Если он консольный - вот параметры:

Упаковка:
Converter_4a.exe convert -flat папка виджета -o папка куда положить виджет
Распаковка:
Converter_4a.exe convert -unflat имя виджета -o папка куда распаковать

Если же пользуетесь версией 2.0 - перетаскиваете главную папку с виджетом (называется имя_виджета.widget) на вехнюю панель, выбираете во что сконвертить - и вперед!
Вообще если хотите чему нибудь научиться - берете приглянувшийся виджет, декомпилируете его и смотрите.

PS: Если у кого есть вопросы (только толковые, пожалуйста) - задавайте тут!

Автор: _SKif_

Ссылки по теме:

• Yahoo! Widgets SDK
• Widget Converter 2.0
• Widget Creation Script for Photoshop CS
• Yahoo! Widget Engine Reference Guide 3.1.1
• Widget Creation Tutorial
• Photoshop CS

Обсудить на форуме | Рекомендовать другу