papagaj — GUI обертка для shell-скриптов. Yet another another *dialog

от автора


Когда я впервые узнал об утилитах dialog, xdialog, zenity я был поражен тем, что буквально из пары строк можно было создать графический интерфейс для скрипта.
Однако, когда я пошел дальше и захотел создать что-то более сложное, чем просто окошко со списком или диалог «Да/нет» — я был слегка разочарован, т.к. не смог найти требуемого. В итоге, мое знакомство с этой областью приостановилось на несколько лет.
Недавно я вспомнил о своем желании и попытался узнать о прогрессе в этом деле. Увы, и сейчас результат оказался не таким как ожидалось — я по-прежнему ничего не находил. По этой причине я и написал программу papagaj. Она позволяет из гов… и палок из xml-файла и пары скриптов построить несложный графический интерфейс для вашего консольного приложения.

Сперва об инструментах необходимых для сборки papagaj. Программа написана на ObjC с использованием библиотеки GNUStep Foundation, поэтому вам нужно иметь в системе установленные пакеты gnustep-base, gnustep-base-dev, gnustep-base-runtime.

Для сборки используется GNUmakefile, для него нужен будет пакет gnustep-make. На случай, если вы не хотите устанавливать gnustep-make я приведу обычный Makefile.

В качестве графической библиотеки я использовал IUP, расположенной по адресу www.tecgraf.puc-rio.br/iup/. В README содержатся инструкции по сборке библиотеки. Имейте в виду, что она требует dev-пакетов для Gtk, т.к. является оберткой для этой библиотеки.

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

После удачной установки перечисленных выше пакетов можно начинать собирать papagaj. Скачайте исходники из git-репозитория, зайдите в директорию и смело набирайте make. В случае невероятного везения вы найдет готовый исполняемый файл papagaj-bin в директории ./obj/. Это и есть программа.

При желании можете переместить ее в /usr/*/bin или создать ссылку оттуда на исполняемый файл.

Makefile:

CC=gcc CFLAGS=-O2 -W -Wall IUP=-liup   GNUSTEP=-lgnustep-base  CONFIG= `pkg-config --cflags --libs gtk+-2.0` `gnustep-config --objc-flags` INCLUD=-I/usr/include/iup LIBS=$(GNUSTEP) $(IUP) COMPLETE=$(CONFIG) $(INCLUD) $(IUP) $(GNUSTEP)   all: main.m 	$(CC) main.m -o papagaj-bin $(COMPLETE)   .PHONY: clean  clean: 	rm papagaj-bin 	rm *.d 	clear 
Использование программы:

papagaj-bin interface-file [onstart-script], где
papagaj-bin — имя программы;
interface-file — файл с описанием интерфейса
onstart-script — файл с shell-скриптом, выполняемым при запуске программы.

Пример:

  • Файл интерфейса:
    				<application name="#app-name"> 					<dialog name="#dlg1" attributes='TITLE="sup, habr"' other="index"> 						<vbox name="#vbox1" attributes="EXPAND=YES, SIZE=100x100, MARGIN=15x15"> 							<button name="#btn1" attributes='TITLE="Click Me!",EXPAND=YES' callback="SHOW #dlg2 :"></button> 						</vbox> 					</dialog> 					<dialog name="#dlg2" attributes='TITLE="SURPRISE!"'> 						<vbox name="#vbox2" attributes="EXPAND=YES, MARGIN=15x15"> 							<label name="#lbl1" attributes='EXPAND=YES,TITLE="Sup, Хабр",FONT="Comic Sans MS, 50"' ></label> 						</vbox> 					</dialog> 				</application> 			

  • Результат:
    papagaj-bin index.xml # index.xml - файл интерфейса. см выше

Структура файла интерфейса.

Файлы интерфейса представляют собой обычные xml-файлы, содержащие описание вложенности виджетов.

Формат описания:

<widget-type name="#widget-name" attributes="<>" callback="<>" other=""></widget-type>

  • widget-type
  • name
    Имя виджета является обязательным, оно используется в обратных вызовах и позволяет обращаться к определнному виджету и изменять его настройки, например цвет, шрифт.
  • attributes
    Кроме того, на внешний вид приложения могут влиять значения атрибутов виджетов. Атрибуты могут принимать значения в нескольких форматах — логические, строчные, числа и размер/координаты.
    • Логические используются в тех случаях, когда значение атрибута виджета может принимать только два значения. Например, виджет может быть активен или нет, соответсвенно и значения могут быть YES или NO.
    • Строчные используются, если значение атрибута — набор символов, например заголовок диалога или содержимое текстового виджета.
    • Числа используются в случаях, когда надо указать какое-то конкретно значение, например значение положения ползунка. Используются довольно редко и с успехом заменяются строчными ( 90 == «90» и т.д.).
    • Размеры используются только в случае задания размера по ширинеи высоте одновременно.(100×50, 25×25).

    Список общих атрибутов для большинства виджетов:

    • ACTIVE — статус виджета (YES/NO).
    • BGCOLOR — цвет подложки в формате RGB («120 120 120»).
    • FGCOLOR — аналогично BGCOLOR, но только для содержимого («10 155 66»).
    • FONT — шрифт (FONT=«Comic Sans MS, 50»).
    • VISIBLE — видимость, в отличии от ACTIVE виджет невидим (YES/NO).
    • EXPAND — вомножность изменения размеров виджета (YES/NO/HORIZNOTAL/VERTICAL).
    • SIZE — размер виджета в пикселах в формате HEIGHTxWIDTH («100×100»).
    • TIP — текст, показываемый во всплывающей подсказке. Отображается при наведении курсора на виджет («wazzup!»).
    • TITLE — текст в заголовке виджета («some title»).
    • VALUE — значение элемента виджета, в некторых случаях аналогичен TITLE («some value»).

  • callback
    Обратный вызов.
    Для некоторых виджетов можно (и даже нужно) указать то, как они будут реагировать на различные действия пользователя.
    • Для кнопок, переключателей (toggle) — нажатие кнопки мыши.
    • Для списков — выбор элемента списка, двойной клик по элементу.
    • Для поля ввода — нажатие на клавишу Enter.

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

  • other
    Этот пункт важен только для типов dialog и list. При значении «index» диалог становится основным и при запуске программы именно он показывается первым. Для list other содержит обратный вызов на двойной клик.

Описание отдельных виджетов и их атрибутов.

  • hbox
    Располагает вложенные виджеты горизонтально, слево направо.

    Атрибуты:

    • ALIGMENT — вертикальное выравнивание виджетов.
      Возможные значения:
      • ATOP — по верхнему краю
      • ACENTER — по центру
      • ABOTTOM — по нижнему краю.

      По-умолчанию — ATOP.

    • GAP — расстояние между вложеными виджетами.
      По-умолчанию — 0.
    • MARGIN — расстояние отступа от края элемента. Получает значение в формате «ШИРИНАxВЫСОТА». Похож на свойство margin для css.
      По-умолчанию 0x0.
    • NORMALIZESIZE — приводит размеры вложенных виджетов к наибольшему среди них.
      Возможные значения:
      • NO — не изменяет размеры.
      • HORIZONTAL — приводит к ширине наибольшей среди вложенных виджетов.
      • VERTICAL — приводит к высоте наибольшей среди вложенных виджетов.
      • BOTH — изменяет и ширины и высоту.

      По-умолчанию — NO.

  • vbox
    Располагает вложенные виджеты вертикально, сверху вниз.


    Имеет те же атрибуты, что и hbox.

  • radio
    Контейнер для логического представления radio button (переключателя). Не выполняет какой-либо вертикальной либо горизонтальной компоновки.
    Если во вложенном контейнере (vbox/hbox) находятся виджеты типа toggle (checkbox) — превращает флажки в переключатели. Может принимать только один контейнер с элементами.

    Атрибуты:

    • VALUE — имя выбранного элемента.

    Пример использования:

    <radio name="#rd1" attributes="" callback="" other=""> 				<vbox name="#vbox1" attributes="" callback="" other=""> 					<toggle name="#n1" attributes='TITLE="Один"' callback="" other=""></toggle> 					<toggle name="#n2" attributes='TITLE="Два"' callback="" other=""></toggle> 					<toggle name="#n3" attributes='TITLE="Три"' callback="" other=""></toggle> 				</vbox> 			</radio>

  • frame
    Окружает вложенные виджеты рамкой с подписью.

  • tabs
    Вкладки. Для каждого вложенного контейнера создает отдельную вкладку.

    Атрибуты:

    • COUNT — количество вкладок. Число или строка.
    • PADDING — задает внутренние отступы для каждой вкладки. Принимает значение в виде «ШИРИНАхВЫСОТА».
      По-умолчанию — 0х0.
    • TABTITLEn — задает заголовок для вкладки n, где n — номер вкладки, отсчет начинается с 0. Чтобы создать мнемоническую команду (Alt+SOME_KEY) для выбора вкладки, перед выбранным символом должен находиться символы "__".

  • label
    Элемент с текстовой строкой.


    Атрибуты:

    • ALIGNMENT — задает вертикальное и горизонтальное выравнивание текста в формате «HORIZONTAL:VERTICAL».
      Возможные значения:
      • Горизонтальное выравнивание:
        ALEFT — по левому краю.
        ACENTER — по центру.
        ARIGHT — по правому краю.
      • Вертикальное выравнивание:
        ATOP — по верхнему краю.
        ACENTER — по центру.
        ABOTTOM — по нижнему краю.

      По-умолчанию — ALEFT:ACENTER.

    • PADDING — устанавливает отступы от границ виджета в формате ШИРИНАхВЫСОТА.
      По-умолчанию — 0х0.
    • SEPARATOR — позволяет превратить ярыл в вертикальный или горизонтальный разделитель.
      Возможные значения:
      • HORIZONTAL — горизонтальный разделитель.
      • VERTICAL — вертикальный разделитель.

  • button
    Кнопка с подписью. При нажатии активирует обратный вызов, записанный в атрибуте callback.

    Атрибуты аналогичны атрибутам элемента label.

  • list
    Список с несколькими элементами. Список элементов задается в атрибутах.

    1="Один"

    — заголовок первого элемента — «Один»

    2="Два"

    — второго — «Два»

    3="Три"

    — третьего — «Три»

    n="Какой-нибудь"

    — n-го — «Какой-нибудь»

    Атрибуты:

    • APPENDITEM — используется в обратных вызовах для добавления новго элемента в список.
    • AUTOHIDE — Скрытие полосы прокрутки (YES/NO).
      По-умолчанию — YES.
    • COUNT — количество элементов в списке.
    • DROPDOWN — создание выпадающего списка (YES/NO).
      По-умолчанию — NO.
    • MULTIPLE — возможность выбора нескольких элементов одновременно (YES/NO).
      По-умолчанию — NO.
    • VALUE — возвращает выбранные элементы. Существует несколько вариантов возвращаемого значения:
      • Возвращает номер выбранного элемента, при условии что следующие атрибуты заданы DROPDOWN=YES или MULTIPLE=NO.
      • Возвращает последовательность символов "+" и "-" для выбранного и невыбранного элемента соответственно, если список позволяет выбирать несколько элементов одновременно.

    Пример использования:

    <vbox name="#vbox0" attributes="GAP=10"> 				<list name="#lst1" attributes='1="1",2=2,3=3,4=4,EXPAND=YES' callback="" other=""></list> 		</vbox>

  • oneline
    Однострочное поле ввода.

    Атрибуты:

    • APPEND — добавляет текст к уже существующему.
    • INSERT — вставляет текст в начале текущей позиции курсора, если при этом в поле ввода выделен какой-либо текст — замещает выделенное.
    • PADDING — устанавливает отступы от границ виджета в формате ШИРИНАхВЫСОТА.
      По-умолчанию — 0х0.
    • READONLY — запрещает возможность редактирования данных (YES/NO).
      По-умолчанию — NO.
    • APPEND — добавляет новый текст в конец.

  • multiline
    Многострочный текстовый виджет. Основные атрибуты те же, что и у oneline.

  • progressbar
    Индикатор прогресса чего-нибудь.


    Атрибуты:

    • MIN — минимальное значение.
    • MAX — максимальное значение.
    • VALUE — текущее значение.

  • toggle
    Флажок или переключатель (см.radio). По атрибутам и обратным вызовам сходен с button.

  • vscale/hscale
    Вертикальный/горизонтальный ползунок.


    Атрибуты:

    • MIN — минимальное значение.
    • MAX — максимальное значение.
    • VALUE — текущее значение.

Для более подробного описания всех атрибутов виджетов обратитесь к документации по библиотеке IUP, расположенной в www.tecgraf.puc-rio.br/iup/

Описание возможностей обратного вызова.

Формат команд для обратного вызова:

<word1> <word2> ... <wordN> :

Правила:

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

Команды обратного вызова размещаются в атрибутах callback (и other для элемента list).

Значения атрибутов виджетов, переменные в приложении.

  • Атрибуты виджетов.
    Если вы просматривали небольшие примеры, приведенные выше, вы наверняка заметили, что имена всех виджетов начинались с символа решетки (#).
    Это, конечно, не случайно. Дело в том, что # используется для обозначения виджета в обратных вызовах и позволяет обращаться к атрибутам виджета, получая значения или, наоборот, меняя их. Теперь кратко: имя виджета должно начинаться с символа решетки и не содержать каких-либо пробельных символов.
    Пример:
    #widget-name WIDGET-ATTRIBUTE
  • Переменные приложения.
    Переменные приложения хранят ранее сохраненные в них данные. Переменные доступны по всему приложению, т.е. созданная в результате обратного вызова одного виджета, доступна для обработки в обратном вызове другого виджета. Если переменная ранее не определялась, при подстановке она возвращает пустое значение. И самое главное, имя переменной ДОЛЖНО начинаться с символа нижнего подчеркивания и не должно содержать пробельных символов.
    Пример:
    _some-variableName
  • Присвоение значений атрибутам виджета и переменным.
    Чтобы присвоить новое значение атрибуту виджета необходимо указать имя виджета, атрибут,"=" и новое значение. Не забывайте о пробелах между словами.
    Пример:
    #dlg1 TITLE = "Hello world" :
    Аналогично присваивается новое значение и переменной — название переменной,"=", новое значение.
    _some-variable = "hello world" :
    Обратите внимание на пробелы между словами и двоеточие, как символ окончания команды.

    Пример.

    		<application name="#app"> 			<dialog name="#dlg" attributes='SIZE=150x150, TITLE="Неизмененное значение"' other="index"> 				<vbox name="#vbox1" attributes="EXPAND=YES,MARGIN=15x15"> 					<button name="#b1" attributes='TITLE="Нажми меня",EXPAND=YES' callback='#dlg TITLE = "Измененное значение" :'/> 				</vbox> 			</dialog> 		</application> 	

    При нажатии на кнопку, заголовок окна будет изменен.

  • Подстановка значений.
    В обратных вызовах также возможна подстановка значений атрибутов виджетов и переменных. Общий формат:
    #widget-name ATTRIBUTE = #widget-name2 ATTRIBUTE: — производится подстановка значения атрибута ATTRIBUTE виджета #wdiget-name2.
    #widget-name ATTRIBUTE = _variable: — производится подстановка значения переменной _variable.
    _variable = #widget-name ATTRIBUTE: — производится подстановка значения атрибута ATTRIBUTE виджета #wdiget-name2.

    Рассмотрим на примере:

    				<application name="#app"> 					<dialog name="#dlg" attributes='SIZE=150x150, TITLE=""' other="index"> 						<vbox name="#vbox1" attributes="EXPAND=YES,MARGIN=15x15"> 							<label name="#lbl1" attributes='TITLE="Привет",EXPAND=YES'/> 							<label name="#lbl2" attributes='TITLE="Мир",EXPAND=YES'/> 							<button name="#b1" attributes='TITLE="Swap!",EXPAND=YES' callback='_swap = #lbl1 TITLE : #lbl1 TITLE = #lbl2 TITLE : #lbl2 TITLE = _swap :'/> 						</vbox> 					</dialog> 				</application> 			

    Создан файл интерфейса с двумя ярлыками и одной кнопкой, при нажатии на кнопку подписи в ярлыках меняются местами. Разберем обратный вызов кнопки подробнее:

    _swap = #lbl1 TITLE :

    — создается переменная _swap, с содержимым подписи первого ярлыка.

    #lbl1 TITLE = #lbl2 TITLE :

    — задается значение #lbl1 TITLE равным #lbl2 TITLE.

    #lbl2 TITLE = _swap :

    — присваивает значение переменной _swap атрибуту TITLE виджета #lbl2.

  • Удаление, добавление, вставка виджетов.
    Изменения интерфейса могут быть более глобальными нежели просто измение цвета/размера заголовка ярлыка — можно изменять количество виджетов в контейнерах, удаляя из одних, добавляя к другим и вставляя к третьим.
    • Удаление виджетов
      Чтобы удалить какой-либо виджет из родительского контейнера используется команда DETACH:
      DETACH #widget-name :
      					<application name="#app"> 						<dialog name="#dlg" attributes='SIZE=150x150, TITLE=""' other="index"> 							<vbox name="#vbox1" attributes="EXPAND=YES,MARGIN=15x15"> 								<label name="#lbl1" attributes='TITLE="Привет",EXPAND=YES'/> 								<button name="#b1" attributes='TITLE="detach",EXPAND=YES' callback='DETACH #lbl1 :'/> 							</vbox> 						</dialog> 					</application> 				

      При нажатии на кнопку удаляется виджет #lbl1.

    • Добавление виджета в контейнер.
      Для добавление виджета используется команда APPEND.
      APPEND #widget-parent #widget-child,
      где #widget-parent — новый родитель для #widget-child
      					<application name="#app"> 						<dialog name="#dlg" attributes='SIZE=150x150, TITLE=""' other="index"> 							<vbox name="#main" attributes="EXPAND=YES"> 								<vbox name="#vbox1" attributes="EXPAND=YES,MARGIN=15x15"> 									<label name="#lbl1" attributes='TITLE="Привет",EXPAND=YES'/> 									<button name="#b1" attributes='TITLE="detach",EXPAND=YES' callback='DETACH #lbl1 :'/> 								</vbox> 								<vbox name="#vbox2" attributes="EXPAND=YES,MARGIN=15x15"> 									<button name="#b2" attributes='TITLE="append",EXPAND=YES' callback='APPEND #vbox2 #lbl1 : '/> 								</vbox> 							</vbox> 						</dialog> 					</application> 				

      При нажатии на кнопку detach, виджет #lbl1 будет удален из контейнера #vbox1. При нажатии на кнопку append, #lbl1 будет присоединен к контейнеру #vbox2. Обратите внимание на то, что добавляемый виджет сперва должен быть удален из предыдущего контейнера.

    • Добавление виджета в определенную позицию.
      При использовании команды APPEND виджет будет добавлен в конец контейнера. Существует возможность вставки виджета в опреденную позицию в контейнере, для этого используется команда INSERT.
      INSERT #new-parent-container #ref-widget #new-widget,
      где #new-parent-container — контейнер, куда будет добавлен виджет,
      #ref-widget — виджет, ПЕРЕД которым будет вставлен новый виджет
      #new-widget — новый виджет
      					<application name="#app"> 						<dialog name="#dlg" attributes='SIZE=150x150, TITLE=""' other="index"> 							<vbox name="#main" attributes="EXPAND=YES"> 								<vbox name="#vbox1" attributes="EXPAND=YES,MARGIN=15x15"> 									<label name="#lbl1" attributes='TITLE="Привет",EXPAND=YES'/> 									<button name="#b1" attributes='TITLE="detach",EXPAND=YES' callback=''/> 								</vbox> 								<vbox name="#vbox2" attributes="EXPAND=YES,MARGIN=15x15"> 									<button name="#b2" attributes='TITLE="insert",EXPAND=YES' callback='DETACH #lbl1 : INSERT #vbox2 #b2 #lbl1 : '/> 								</vbox> 							</vbox> 						</dialog> 					</application> 				

  • Отображение диалогов.
    Кроме основного диалога, который отображается при старрте программы можут быть и другие.
    Они определяются на том же уровне вложенности, что и основной диалог, но остаются скрытыми. Чтобы отобразить их используется команда SHOW.
    SHOW #some-dialog :,
    где #some-dialog — имя диалога

    Пример:

    			<application name="#app"> 				<dialog name="#dlg" attributes='TITLE=""' other="index"> 					<vbox name="#main" attributes="EXPAND=YES,MARGIN=15x15"> 						<button name="#b1" attributes='TITLE="SHOW",EXPAND=YES' callback='SHOW #dlg2 :'/> 					</vbox> 				</dialog> 				<dialog name="#dlg2" attributes='TITLE="привет",SIZE=50x50'> 					<vbox name="#vbox" attributes="EXPAND=YES, MARGIN=15x15"> 						<label name="#lbl1" attributes='TITLE="Привет",EXPAND=YES'/> 					</vbox> 				</dialog> 			</application> 		

    При нажатии на кнопку SHOW отобразится диалог #dlg2

  • Кроме размещения скрытых диалогов на первом уровне вложенности могут находиться и другие виджеты, которые могут понадобиться позднее. Их можно присоединить командой APPEND или INSERT.
    	 			<application name="#app"> 				<dialog name="#dlg" attributes='TITLE=""' other="index"> 					<vbox name="#main" attributes="EXPAND=YES,MARGIN=15x15"> 						<button name="#b1" attributes='TITLE="APPEND",EXPAND=YES' callback='APPEND #main #vbox2 :'/> 					</vbox> 				</dialog> 				<vbox name="#vbox2" attributes='EXPAND=YES, MARGIN=15x15, FGCOLOR="100 50 250"'> 					<label name="#some-label" attributes='TITLE="SOME LABEL"' /> 				</vbox> 			</application> 		

Несколько слов об исполнении shell-скриптов и других внешних программ.

Обратным вызовом может быть выполнение и внешних прорамм, таких как shell-скрипты, команды оболочки и т.п.

Если программа не может разобрать обратный вызов виджета, она предполагает, что он является внешней командой и обращается к оболочке для исполнения команды.
Пример:

	<application name="#app"> 		<dialog name="#dlg" attributes='TITLE=""' other="index"> 			<vbox name="#main" attributes="EXPAND=YES,MARGIN=15x15"> 				<multiline name="#content" attributes="EXPAND=YES" /> 				<button name="#b1" attributes='TITLE="List",EXPAND=YES' callback='ls -l' /> 			</vbox> 		</dialog> 	</application> 

При нажатии на кнопку List будет выполнена команда оболочки ls -l.

Однако, какой смысл в выполнении команды, если нет возможности увидеть результат? Так как программы зачастую выводят множество информации, которая нам не нужна есть ее следует отфильтровать и только затем вернуть в основную программу.
Пример:
ls -a | awk '{printf(" #content APPEND = \"%s\" : ", $0);}'

Но даже сейчас вывод команды никак не воздействует на основную программу. Чтобы вернуть информацию в вызывающую программу сперва должен идти маркер о начале приема информации — !BEGIN. Маркер !END сообщает об окончании приема. Т.е. весь вывод находящийся между этими двумя маркерами будет считаться валидными командами для программы и она будет стремиться их выполнить.

Поместим ls -a | awk '{printf(" #content APPEND = \"%s\" : ", $0);}' в файл ls.sh и добавим маркеры для получения результата.
ls.sh:

	echo "!BEGIN " 	ls -a | awk '{printf(" #content APPEND = \"%s\" : ", $0);}' 	echo " !END" 

Файл с описанием интерфейса:

	<application name="#app"> 		<dialog name="#dlg" attributes='TITLE=""' other="index"> 			<vbox name="#main" attributes="EXPAND=YES,MARGIN=15x15"> 				<multiline name="#content" attributes="EXPAND=YES" /> 				<button name="#b1" attributes='TITLE="List",EXPAND=YES' callback='bash ./ls.sh :'/> 			</vbox> 		</dialog> 	</application> 

Теперь при нажатии на кнопку List в текстовый виджет #content будет добавлен результат выполнения скрипта ls.sh.

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

	echo "!BEGIN " 	ls -a $1 | awk '{printf(" #content APPEND = \"%s\" : ", $0);}' 	echo " !END" 

	<application name="#app"> 		<dialog name="#dlg" attributes='TITLE=""' other="index"> 			<vbox name="#main" attributes="EXPAND=YES,MARGIN=15x15"> 				<oneline name="#addr" attributes="EXPAND=HORIZONTAL" /> 				<multiline name="#content" attributes="EXPAND=YES" /> 				<button name="#b1" attributes='TITLE="APPEND",EXPAND=YES' callback='#content VALUE = "" : bash ./ls.sh #addr VALUE :'/> 			</vbox> 		</dialog> 	</application> 

Скрипты, выполняемые при запуске.

Кроме файла интерфейса, параметром для papagaj-bin может быть еще файл скрипта, выполняемый при запуске программы. Это должен быть просто shell-скрипт, похожий на используемый нами ранее ls.sh. Дальше, в примерах, показывается как использовать скрипты при запуске и зачем они вообще нужны.

В завершение несколько простых примеров:

Ползунок и индикатор прогресса:

<application name="#app"> 	<dialog name="#dlg" attributes='TITLE=""' other="index"> 		<vbox name="#main" attributes="EXPAND=YES,MARGIN=15x15"> 			<progressbar name="#bar" attributes='EXPAND=YES,MIN=0,MAX=100,VALUE=50' /> 			<hscale name="#scale" attributes='EXPAND=YES,MIN=0,MAX=100,VALUE=-50' callback="#bar VALUE = #scale VALUE :"/> 		</vbox> 	</dialog> </application> 

Список и поле ввода

<application name="#app"> 	<dialog name="#dlg" attributes='TITLE=""' other="index"> 		<vbox name="#main" attributes="EXPAND=YES,MARGIN=15x15"> 			<oneline name="#addr" attributes="EXPAND=HORIZONTAL" callback="#lst APPENDITEM = #addr VALUE :"/> 			<list name="#lst" attributes="EXPAND=YES" /> 		</vbox> 	</dialog> </application> 


Небольшая графическая обертка для команды ls -a
Файл интерфейса:

<application name="#app"> 		<dialog name="#dlg1" attributes='EXPAND=YES,TITLE="YAFM",SIZE=500x200' other="index"> 			<vbox name="#main" attributes="NGAP=10,EXPAND=YES"> 				<hbox name="#top-fill" attributes="MARGIN=5x5"></hbox> 				<hbox name="#list-panel" attributes="EXPAND=YES,MARGIN=5x5" > 					<vbox name="#lst-cont" attributes="EXPAND=YES,NGAP=5" > 						<hbox name="#up-cont" attributes="MARGIN=0x0" > 							<oneline name="#curr-pos" attributes='EXPAND=HORIZONTAL'></oneline> 							<button name="#btn-go-lst" attributes='TITLE="Go/Refresh",EXPAND=NO' callback='bash ./change_dir.sh #curr-pos VALUE :'></button> 						</hbox> 						<list name="#lst" attributes='EXPAND=YES,MULTIPLE=NO,EDITBOX=YES' callback='_active = "#lst1" : ' /> 					</vbox> 				</hbox> 			</vbox> 		</dialog> </application> 

Скрипт исполняемый при загрузке:
onstart.sh

pwd_now=$PWD echo " !BEGIN " echo " #curr-pos VALUE = "$pwd_now" : " bash get_filelist.sh $pwd_now echo " !END" 

Пара вспомогательных скриптов:
change_dir.sh

echo " !BEGIN " echo " #lst REMOVEITEM = ALL : " bash ./get_filelist.sh $1 echo " !END " 

get_filelist.sh

# взял из http://www.cyberciti.biz/tips/handling-filenames-with-spaces-in-bash.html  SAVEIFS=$IFS IFS=$(echo -en "\n\b") cd $1 some_files=$(ls -a) for x in  $some_files;  do  	if [ -d $x ];  		then  			echo " #lst APPENDITEM = \"[$x]\" : ";  		else  			echo " #lst APPENDITEM = \"$x\" : ";  	fi;  done IFS=$SAVEIFS 

Использование papagaj совместно с zenity

<application name="#app">         <dialog name="#dlg" attributes='TITLE=""' other="index">             <vbox name="#main" attributes="EXPAND=YES,MARGIN=15x15">                 <oneline name="#content" attributes="EXPAND=YES,READONLY=YES" />                 <button name="#b1" attributes='TITLE="My name is ...",EXPAND=YES' callback='echo "!BEGIN #content VALUE = \""; zenity --entry ; echo "\" : !END " :' />             </vbox>         </dialog> </application> 

Несколько ссылок:

git-репозиторий papagaj
GNUStep.org
Страница проекта IUP на сайте Tecgraf/PUC-Rio

С радостью отвечу на вопросы.
p.s. если заметите опечатку или что-то подобное — сообщите в личку, буду очень благодарен.

ссылка на оригинал статьи http://habrahabr.ru/post/155839/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *