LINUX.ORG.RU

Как полностью разделить логику приложения и его GUI?


0

0

Я хочу позволить пользователю две вещи:

1. возможность полностью (на 100%) изменить скин и поведение GUI (отключить часть диалогов, настроить уведомления, звуки, для каждого окошка/поля ввода задать свой цвет текста, фон, текстуру и т.д.)

2. возможность заменить GUI на свой собственный (ну скорее как плагин наверное), если настроек скинования будет недостаточно

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

* * *

Я так понимаю, что нужно будет задекларировать все вызовы гуя (все сообщения, все кнопки, все формы, поля текста и вообще все, с чем работает пользователь), процесс гуя запускать отдельно, которому сообщения выдавать в некотором промежуточном формате вроде «NEW_USER_MESSAGE someuser Привет!», а оно уже и мелодию для события NEW_USER_MESSAGE проиграет, и окошко/попап с текстом «новое сообщение „Привет!“ от someuser» выдать, или вообще что-то скриптовое запустить. А если настроек будет мало, то морду вообще можно переписать, например, под ncurses, здесь от NEW_USER_MESSAGE может зависеть цвет шрифта (его тоже надо разрешить настраивать). Здесь же решается проблема с локализациями, все текстовое даем юзеру. Проблема в том, что я не знаю до какого уровня абстракций идти: сделать ли многоуровневые команды, типа ALERT TYPE=NOTIFY SOURCE=REMOTEUSER ID=NEW_USER_MESSAGE, сделав минимальную обертку над тулкитом, повторяя его Alert.Info/Warning/Danger, или каждый NEW_USER_MESSAGE изобретать с нуля. А может есть что-то более лучшее?

Ответ на: комментарий от Hjorn

при желании уровень декларативности можно поднять

вот тут человек очень хорошо об этом пишет

Проще пока ничего нет

есть REBOL GUI - он местами интересней, и в принципе очень похож на Tcl/Tk идеологически; вот только R3 всё никак не выйдет, а до тех пор пользоваться им в силу закрытости смысла особого нет

jtootf ★★★★★
()
Ответ на: комментарий от jtootf

вот тут человек очень хорошо об этом пишет

«Графический интерфейс: то, что нельзя» - хороший пример, что у меня уже лучше :) т.к. мой макрос ENABLE_IF и прост и универсален, и не накладывает ограничения

ENABLE_IF( text ) // используется дефолтное свойство - в данном случае виджет активен, если текстовое поле text имеет непустое значение
ENABLE_IF( list, ltIF_SELECTION, 0 ) // если в списке выделен первый элемент, в принципе это будет задаваться в редакторе, так что запоминать названия свойств нет надобности

ну и опять же - в качестве параметра можно использовать лямбды, методы или сделать это с помощью action

lester ★★★★
()
Ответ на: комментарий от lester

кстати у меня есть еще и макрос SHOW_IF, который не только позволяет скрывать/показывать виджеты или элементы меню, но и автоматом дергает лайоты( не он сам конечно, но думаю принцип понятен )

lester ★★★★
()
Ответ на: комментарий от jtootf

> вот тут человек очень хорошо об этом пишет

Спасибо за ссылку. Там же нашёл ещё и статью о coroutines, отлично! Попробую 8.6 в деле, хоть она и застряла в бете.

есть REBOL GUI

Угу, я немного ковырял REBOL, интересная игрушка, но тикль как то привычней и практичней.

Hjorn
()
Ответ на: комментарий от lester

> «Графический интерфейс: то, что нельзя» - хороший пример, что у меня уже лучше

Хе, так то ж просто пример как за 5 минут на коленке сделать конфетку. Тех же реализаций actions я уже штуки 3 видел. Или взять snit (объектная система) - он на чистом тикле реализован, при этом позволяет клепать кастомные виджеты опять же на коленке. А ваше решение на макросах как юзеру расширять?

Hjorn
()

В Qt можно подгружать UI на лету. Соответственно, пользователю нужно будет только накидать форму с нужными контроллами в дизайнере. Поддержка пользовательских скинов также есть.
//Где-то видел даже ман по изготовлению скинов к qutim (или qmmp, не помню уже) таким образом.

unikoid ★★★
()
Ответ на: комментарий от Hjorn

> при этом позволяет клепать кастомные виджеты опять же на коленке.

тоже самое, а что там сложного?

А ваше решение на макросах как юзеру расширять?


да очень просто - макросы они и есть макросы, за ними стоят обычные интерфейсы и классы, навроде тех же в Qt, хочет человек виджет добавить свой или расширить существующий - наследуется и пишет дальше, хочет руками прописывать гуи( хотя опять редактор будет гораздо удобней ) - легко, пишет WIDGET( myCustomWidget ) и работает с ним как и со всеми виджетами, точно также может при желании и свойства свои сделать через те же макросы - получит текущий виджет через макрос THIS, и сделает с ним все что хочет в своей функции

lester ★★★★
()
Ответ на: комментарий от lester

> да очень просто - макросы они и есть макросы, за ними стоят обычные интерфейсы и классы

Вот именно, и придётся все равно писать часть гуя на С++. Тикль удобен как раз тем, что это скриптовый язык, который сам по себе расширяем. Потому можно жонглировать виджетами, оборачивать их во что угодно и как угодно, не прикасаясь к низкоуровневому коду. А ваша макросовая надстройка - это по сути жёстко заданный DSL, который нельзя расширить средствами самого DSL. Если же вы будете двигаться в сторону поддержки метапрограммирования, то уткнётесь несомненно в 10-е правило Гринспуна. В общем нет пути :) Вернее путь может и есть, но только для фанатов С++.

Hjorn
()
Ответ на: комментарий от Hjorn

Вот именно, и придётся все равно писать часть гуя на С++
Если же вы будете двигаться в сторону поддержки метапрограммирования, то уткнётесь несомненно в 10-е правило Гринспуна. В общем нет пути :) Вернее путь может и есть, но только для фанатов С++.

вы неверно поняли основную идею :) макросы - это не программирование гуи, возьмем «чистый» код:

LButton* btn = new LButton( parent, _("Text") );
btn->EnableIf( text );
sizer->Add( btn );

что равнозначно:

BUTTON( btn, _("Text") ) ENABLE_IF( text )

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

lester ★★★★
()
Ответ на: комментарий от lester

по сути они просто нужны, чтоб не писать постоянно «sizer->Add» и «btn->», а также чтоб не заводить на каждый виджет по переменной - вот и все что они дают, в остальном это копия стандартных методов, так что нет тут никакого сверх-мета-программирования :)

lester ★★★★
()
Ответ на: комментарий от lester

> в данном случае макросы просто помогают писать меньше кода, не меняя логики и не строя новые конструкции

Не, на самом деле я понял, что у вас чисто декларативное решение. Просто мне показалось, что это только начало, а дальше будет интересней :) Я же агитирую за программируемый GUI, который может удачно мимикрировать под декларативное описание, оставляя при этом под рукой все императивные возможности. Для этого нужен скриптовый язык, да ещё не всякий подойдёт.

Hjorn
()
Ответ на: комментарий от jtootf

> да, лиспы здесь вполне уместны :)

не уместны - если лисперы пишут гуй, то сразу по привычке делают биндинг к библиотеке на другом языке, а потом, используя биндинг, пишут нечто, что по задумке должно быть одним, а по внешнему виду получается копия емакса в виде текстового редактора посередине и меню сверху ;)

lester ★★★★
()

Сейчас смотрю на enlightenment, точнее на http://trac.enlightenment.org/e/wiki/Edje - вроде бы искомое

Да, обязательно будет клиент-сервер, я еще хочу сделать удаленное управление прикрутить, в том числе по http (т.е. декларация всех уведомлений / форм / окошек будет выдана клиенту, а «морда на js» пусть сама разбирается как это рисовать, где кнопки расставлять, что дисаблить, что проверять). Самое сложное: придумать протокол обмена.

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

eternalgeek
() автор топика
Ответ на: комментарий от eternalgeek

Самое сложное: придумать протокол обмена [...] Фактически я создаю свой собственный тулкит.

Вы не мешаете в одну кучу графический сервер и тулкит?

mv ★★★★★
()
Ответ на: комментарий от lester

А как ты сделал связи гуя и исполнительных функций? Просто если в диалоге надо отобразить какие-то уже введенные данные, то надо придумывать интерфейс для проброски данных, а это уже не так тривиально. Особенно, если данные могут отображаться не только в виде текста, но скажем и в виде прогресс-баров с разными цветами, где цвет определяют данные+морда (например, в данных «WARN», которое транслируется в красный цвет). У меня получается очень много объектов на экране (кнопки, поля ввода, индикаторы), и у каждого из них множество данных, в результате протокол обмена выглядит как огромный лог непойми чего

eternalgeek
() автор топика
Ответ на: комментарий от mv

> Вы не мешаете в одну кучу графический сервер и тулкит?

Нет, посмотри на такие вещи как Y-server и Wayland, можно даже вспомнить концепцию CICS-терминалов. Зачем каждый клик гонять между приложением и сервером? Путь графическая часть соберет все данные и отдаст приложению, а уж как она это сделает - ее проблемы (таким образом нету привязки к разрешению экрана, клавиатуре, аппаратным возможностям и средствам ввода)

eternalgeek
() автор топика
Ответ на: комментарий от eternalgeek

в результате протокол обмена выглядит как огромный лог непойми чего

честно говоря не совсем понял задачи, которые перед тобой стоят; расскажу как понял, у меня например каждому виджету можно дать конфиг( по умолчанию используются глобальный ) + путь в этом конфиге, где лежат данные и куда сам виджет может их сохранять, если он изменяет состояние, выглядит все очень просто:

GAUGE( tc, 0, 100 ) CONFIG_ENTRY( "/SomeDialog/GaugeData" )

можно указать в том числе RO или WO режим; и, если записать в конфиг данные через theConfig->Write, то виджет обновится, можно даже делать экспорт/импорт целой ветки - и получить сохранение/загрузку данных в XML для целого диалога, что, как я вроде понял, тебе и надо пересылать куда-то

lester ★★★★
()
Ответ на: комментарий от eternalgeek

> Самое сложное: придумать протокол обмена.

xml-rpc

LamerOk ★★★★★
()
Ответ на: комментарий от eternalgeek

Вы не мешаете в одну кучу графический сервер и тулкит?

Нет, посмотри на такие вещи как Y-server и Wayland

Сами-то смотрели?

mv ★★★★★
()
Ответ на: комментарий от lester

в ближайшем будущем ситуация к лучшему не изменится

в смысле популярности? однозначно. у рынка новый hype и новые buzzword'ы

jtootf ★★★★★
()
Ответ на: комментарий от lester

> честно говоря не совсем понял задачи, которые перед тобой стоят

Задача любого UI в отображении и вводе данных. Есть у меня сообщение «Внимание, соединение с сервером потеряно» - я должен его как-то выдать при ошибке в приложении. А вот пользователь сам пусть решает, как именно он хочет видеть его: в виде голосового сообщения, в виде красной лампочки в трее, в виде всплывающих плашек в бубунте, попап-окошка, в виде логов, в виде смс-сообщения на телефон (можно сразу на двух языках), в виде... Да чего угодно! Пусть сам морду настраивает, или пишет с нуля, если функций мало.

Вот только каждый стринг мне нужно будет превратить в ресурс, которому назначит ID вида SERVER_ERROR_CONNECTION_LOST, дабы гуи-клиент сам разбирался, как ему отображать инфу. А как быть со сложными формами? Я пока склоняюсь к чему-то вроде XForms.

Я делаю что-то вроде чата + сетевой игры (ага, почти QIP), где надо будет постоянно обновлять данные игрового поля + сотни команд для управления игроками, протокол представляю в виде:

CHAT_USER_TEXT:27678:2010/03/30:Привет, как дела? PLAY_USER_MOVE:76467:78:26 PLAY_USER_ACT:8723:GETFLAG

Но если надо ввести достаточно сложную форму, со многими списками и уровнями вложенности? Что-то я представляю это все в виде большой помойки в итоге, а ничего лучше придумать не могу

eternalgeek
() автор топика
Ответ на: комментарий от mv

> Сами-то смотрели?

Y specifies a core set of widget classes. Objects of these classes are stored in the server, where they are closer to the user and thus more responsive from the user's point of view. Consistency and Themeability

Y widgets use the currently loaded theme to render themselves. Since all server widgets are using the same theme, all widgets appear consistent throughout the desktop. Client applications can also use the theme's drawing operations, allowing specialised widgets to make themselves fit in with the look-and-feel.

* * *

Wayland, a project by Kristian Høgsberg to create a new display server for Linux that leverages kernel mode-setting, the Graphics Execution Manager, and other newer Linux graphics technologies, continues to mature. Last month Eagle (the Wayland EGL stack) got working DRI2 support (DRI2 was also masterminded by Kristian) and now there's also some work going on within the tool-kit realm. There remains no GTK or Qt back-end for the Wayland Display Server, but one is in development by Kristian for Clutter.

eternalgeek
() автор топика
Ответ на: комментарий от eternalgeek

> Я делаю что-то вроде чата + сетевой игры (ага, почти QIP), где надо будет постоянно обновлять данные игрового поля + сотни команд для управления игроками, протокол представляю в виде:

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

2. для обновления отсылать последовательность:

ID_WIDGET, ID_ACTION/ID_PROPERTY, PARAM1, ...

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

П.С. вобщем я согласен с тобой и ничего оригинального и полезного предложить не могу :)

lester ★★★★
()
Ответ на: комментарий от eternalgeek

Ну и, перевод Wayland'а осилили?

А ты демки этого самого клуттера смотрел?

OMG, а clutter-то тут при чём?

mv ★★★★★
()

>1. возможность полностью (на 100%) изменить скин и поведение GUI (отключить часть диалогов, настроить уведомления, звуки, для каждого окошка/поля ввода задать свой цвет текста, фон, текстуру и т.д.)

2. возможность заменить GUI на свой собственный (ну скорее как плагин наверное), если настроек скинования будет недостаточно

по обоим пунктам - XUL (+XML+XSLT и проч.)..

MKuznetsov ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.