Интеграция интеракторов в многопотоковом графическом пользовательском интерфейсе
Суть принципов построения сложных приложений на основе стандартных классов объектов. Разработка необходимых классов интеракторов. Определение условия срабатывания интерактора в момент, явно определенный действием пользователя с помощью функции trigger.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | статья |
Язык | русский |
Дата добавления | 15.08.2020 |
Размер файла | 40,1 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Размещено на http://www.allbest.ru/
Интеграция интеракторов в многопотоковом графическом пользовательском интерфейсе
Гордиенко А.П.
С развитием объектно-ориентированного программирования сформировались принципы построения сложных приложений на основе стандартных классов объектов. Эта тенденция нашла своё отражение и в области графического пользовательского интерфейса (ГПИ), где такие стандартные объекты получили название интеракторов [1,2]. В нашем обзоре [3] рассмотрены основные модели интеракторов, а в работе [4] показано, что интерактор можно рассматривать как обобщённое логическое устройство ввода, определённое международными стандартами GKS и PHIGS.
Однако следует отметить, что разработка необходимых классов интеракторов ещё не решает проблему создания ГПИ, поскольку требуется определить ещё и метод интеграции совокупности экземпляров интеракторов в единую систему. Хотя в этом вопросе пока нет законченных решений, их можно найти, если попытаться построить ГПИ на основе интеракторов средствами чисто функционального программирования [5,6].
Предлагаемый подход определяется следующим образом. Логика диалога описывается взаимодействующими последовательными процессами Хоара [7], которые легко реализуемы средствами функционального программирования [8]. В этом описании каждому событию соответствует логическое устройство ввода, которое назовём примитивным интерактором. Поскольку в каждой фазе диалога активны сразу несколько интеракторов, то необходимо обеспечить их совместную работу. Для этого представим примитивный интерактор в виде функционала, определяющего действие - ввод данных от пользователя. Он получает параметры настройки:
Сегменты графических примитивов, определяющих внешний вид прикладной модели, элементов управления ГПИ и курсора.
Условия срабатывания интерактора по нажатию кнопки и по взаимоотношению объектов курсора с объектами прикладной модели и элементов управления ГПИ.
Функции, формирующие курсор, список предполагаемых геометрических соотношений и выдаваемый интерактором знак.
В данной статье будет показано, что совместная работа нескольких примитивных интеракторов может быть обеспечена одним универсальным интерактором, параметры настройки которого строятся из параметров настройки отдельных примитивных интеракторов.
ПРИМИТИВНЫЙ ИНТЕРАКТОР
Интеракторы пользовательского интерфейса строятся функцией interactor, которая имеет тип:
interactor :: Window -> GrSeg -> GrSeg -> GrSeg -> Ftrigger -> Fsample -> Fecho -> Fguess -> Ftoken -> IO(Token)
Эта функция для заданных окна, трёх сегментов графических примитивов типа GrSeg, определяющих внешний вид соответственно прикладной модели, объектов пользовательского интерфейса и курсора, и функций настройки trigger::Ftrigger, sample::Fsample, echo::Fecho, guess::Fguess и token::Ftoken строит монадическое действие ввода-вывода типа IO(Token), которое будучи выполненным, получит от пользователя событие и выдаст его в форме знака типа Token.
Рассмотрим реализацию интерактора средствами функционального программирования, в соответствии со структурой его процессов, описанной в [4]. Для повышения эффективности работы интерактора количество параллельных процессов можно сократить до двух: оставить процесс измерения, а остальные процессы объединить в один последовательный. Таким образом, интерактор будет получать из буфера последовательность асинхронно измеренных значений, вводимых пользователем, и далее работать в соответствии с алгоритмом, показанным на рисунке 1. В начале работы интерактор из полученных от адаптера функционального ядра данных строит направленный ациклический граф (НАГ) прикладных сегментов. Из модуля управления контекстом он получит данные для построения НАГ объектов ПИ и курсора. После этого он формирует монады визуализации и выводит на экран свое изображение. Теперь он готов принять сообщение от процесса измерения.
Получив измеренное значение, интерактор проверяет, переместил ли пользователь позицию устройства (условие move) или нажал кнопку (условие button). В первом случае строятся новый НАГ курсора и объектов ПИ и монада ввода-вывода для их визуализации, затем строится множество предположений о геометрических соотношениях между измененными пользователем объектами, входящими в состав курсора, и неподвижными объектами. После этого нужно обновить изображение на экране и обозначить сделанные предположения. На основе этих предположений условие sample определяет, необходимо ли интерактору завершить работу или нужно её продолжить и обработать следующее событие от процесса измерения.
Во втором случае условие trigger проверяет, нажал ли пользователь кнопку, по которой интерактор должен завершить свою работу. Завершая работу, интерактор генерирует знак, который явится событием, передаваемым вверх по иерархии интеракторов.
Таким образом, интерактор работает одинаково, обеспечивая функциональность всех классов логических устройств ввода. Для конкретизации его возможностей, ему необходимо передать в качестве параметров функции настройки: trigger и sample для проверки соответствующих условий завершения работы, echo - для построения монады вывода курсора (эха) в зависимости от текущего положения устройства ввода, guess - для формирования множества предположений о геометрических соотношениях между входящими в состав курсора объектами и объектами прикладных сегментов, token - для генерации выходного знака. приложение класс интерактор
ФУНКЦИИ НАСТРОЙКИ ИНТЕРАКТОРА
Функция trigger определяет условие срабатывания интерактора в момент, явно определенный действием пользователя. Она имеет тип:
(Point,Bool,Bool)->Bool, и отображает состояние «мыши» (позицию и положение кнопок) в признак необходимости завершения работы интерактора. Например, если срабатывание должно происходить по нажатию левой кнопки, то определение функции trigger будет иметь вид:
trigger pt isLeft isDown = isLeft.
Рисунок 1 - Алгоритм работы интерактора
Условие, реализуемое функцией trigger, может учитывать не только положение кнопок «мыши», но и её положение. При необходимости, чтобы триггер срабатывал только в определенной области экрана, функцию trigger можно получить частичным применением, например, функции:
triggerInArea :: (Point->Bool)->((Point,Bool,Bool)->Bool)
->(Point->Bool->Bool) ->Bool
triggerInArea test trigger mouseState =
(test mouseState) && (trigger mouseState)
к функции test, проверяющей попадание точки внутрь области и к исходной функции basetrigger, определяющей комбинацию кнопок:
trigger = triggerInArea test basetrigger.
Функция sample позволяет использовать такой метод взаимодействия с объектами, при котором, только подведя курсор к объекту, пользователь может получить ответ системы. Таким ответом может быть просто пояснение назначения объекта или раскрытие всплывающего меню. Для реализации этого метода в интеракторе должна быть предусмотрена возможность завершения работы и генерации знака не только вследствие срабатывания триггера, но и вследствие возникших соотношений между изменяемыми и неизменяемыми объектами. Интерактор использует параметр - функцию sample типа
[Guess] -> Bool,
которая, получив список предположений о геометрических соотношениях, определяет, необходимо ли интерактору завершить работу и выдать знак или нет. Например, функция:
mysample [] = False
mysample (PntOnLine _ _ : _) = True
mysample (_: g) = mysample g
определяет был ли указан отрезок. Если эту функцию передать интерактору как параметр sample, то выходной знак будет генерироваться при подведении курсора к какому-либо отрезку.
Функция guess, определяющая возможные геометрические соотношения между подвижными и неподвижными элементами графического представления имеет тип: guess :: DAG->DAG-> [Guess] ,
где тип Guess определяет виды геометрических соотношений:
data Guess = CoordX Int Int |CoordY Int Int |EqPnts Int Int |PntOnLine Int Int |Perpend Int Int |Parallel Int Int ,
где запись CoordX i j обозначает совпадение координат X, CoordY i j - совпадение координат Y, EqPnts i j - совпадение точек, PntOnLine i j - обозначает принадлежность точки i отрезку j, а Perpend i j и Parallel i j обозначают соответственно перпендикулярность и параллельность отрезков i и j. Тип Guess может быть расширен и другими видами геометрических соотношений.
Функция echo, определяющая графическое представление курсора, отслеживающего текущее положение устройства ввода, имеет тип:
echo :: (Point->Graphic).
Например, функцию echo, реализующую резиновую нить, можно получить посредством функции
rubberLine Point -> Point -> Graphic
rubberLine p1 p2 = line p1 p2,
частично применив последнюю к аргументу p1, содержащему координаты фиксированной точки:
echo = rubberLine p1 .
В общем случае функция echo может строиться и на основе более сложных функций. Функцию echo, в которой строится изображение изменяемого сложного графического сегмента, можно получить следующим образом:
echo = dragSeg grSeg moveSeg showSeg .
Функция token, формирующая знак, выдаваемый интерактором вверх по иерархии в направлении функционального ядра, имеет тип:
token :: [Guess] -> Token,
где тип Token зависит от логики диалога и определяет возможные форматы событий в выражениях поведения. Например, если нужно, чтобы интерактор работал как стандартные логические устройства ввода, тип Token можно определить следующим образом:
data Token = Locator Point | Stroke [Point] |Pick Int |Choice Int Int |Valuator Int ,
но, скорее всего, вместе с событием класса Locator понадобится и информация о предполагаемых геометрических соотношениях, а вместе с событием класса Pick - тип указанного объекта. В таком случае лучше использовать тип:
data Token' = |Locator Point [Guess]| Stroke [Point] |PickPnt Int |PickLine Int |PickArc Int |Choice Int Int |Valuator Int ,
где конструкторы PickPnt, PickLine и PickArc обозначают соответственно, что были указаны точка, отрезок или дуга окружности.
КОМПОЗИЦИЯ ФУНКЦИЙ НАСТРОЙКИ
Поскольку один интерактор должен иметь возможность генерировать несколько классов событий (отношение событие - интерактор имеет тип «многие к одному»), нужно решить вопрос о том, как объединить действия функций trigger, echo, match и token, заданных для каждого события, для работы с общим интерактором. Рассмотрим, на каких принципах могут объединяться эти функции.
Для функций trigger и sample это объединение элементарно. Если интерактор должен генерировать N событий, то для него должно быть определено N функций trigger и N функций sample. По любому из триггеров интерактор должен завершить свою работу. Следовательно, ему должен быть передан параметр trigger полученный дизъюнкцией всех N функций trigger:
trigger = or [trigger1, trigger2, … triggerN] .
Функции sample объединяются аналогично.
Объединение функций echo можно выполнить двумя способами. В первом случае, когда одно из событий можно принять за основное, его функцию echo следует использовать для всех событий. Например, если интерактор объединяет события двух классов Pick и Locator, то эхо можно взять у одного события Pick. Во втором случае функцию echo можно выбрать, проверяя попадание текущей позиции в область эха. Для этого нужно определить функцию:
echoInArea :: Point -> [(EchoArea,FEcho)] -> FEcho
echoInArea pt (ea,ef):rest =
if (inArea pt ea) then ef
else echoInArea pt rest
echoInArea pt [] = defaultEcho ,
которая для ассоциативного списка область эха - функция эха находит функцию, соответствующую той области, в которой находится текущая позиция устройства ввода. Здесь defaultEcho - функция, используемая по умолчанию, если текущая позиция не попала ни в одну из областей.
Функцию guess можно построить из отдельных функций guessi , путём слияния отдельных списков, учитывая приоритеты элементов. Для этого на множествах конструкторов, определяющих тип Guess нужно определить отношение порядка и задать его функцией:
gtGuess :: Guess -> Guess -> Bool ,
которая возвращают истину, если одно предположение имеет более высокий приоритет, чем другое. Функция слияния предположений определяется следующим образом:
gtMerge :: [Guess] -> [Guess] -> [Guess]
gtMerge l1@(h1:t1) l2@(h2:t2) =
gtGuess h1 h2 | h1: gtMerge t1 l2
otherwise h2: gtMerge l1 t2
Слияние произвольного числа списков можно определить выражением:
guess = foldr gtMerge [] [guess1, guess2, … guessN] ,
где - guessi i-тый список предположений.
Рассмотрим теперь процесс интеграции формирующих знак функций. Для каждого номера примитивного интерактора при разработке ПИ должен быть определён кортеж атрибутов: имя триггера, имя знака, его приоритет и формирующая его функция. Поэтому будем считать заданным отношение:
Rt :: Номер ИмяТриггера ИмяЗнака Приоритет FToken .
Выбрав из этого отношения кортежи, относящиеся к меню m, получим отношение:
Rm = {t | tRt Номер(Rt)m}.
Выбор формирующей знак функции зависит, прежде всего, от сработавшего триггера, поэтому определим функцию:
F(tr) = {tok | tRm t.ИмяТриггера=tr tok=t.FToken}.
Теперь для списка функций, формирующих знак, можно построить одну общую функцию, которая будет по очереди применять функции из списка до тех пор, пока не будет получен знак, отличный от пустого.
Заключение
Использование описанного выше универсального интерактора, настраиваемого передаваемыми ему функциями, композиция которых позволяет моделировать совместную работу нескольких интеракторов, открывает перспективу разработки ГПИ декларативными методами на основе формальных спецификаций. Это даст возможность применить эффективные инструментальные средства для проектирования ГПИ, поскольку декларативность описания интеракторов позволит разработать базу данных типовых интеракторов, компоновка которых в ГПИ будет происходить автоматически.
Литература
1. Faconti G.P. Towards the Concept of Interactor/ AMODEUS project report. Esprit Basic Research 7040. Amodeus Project Document, system modelling/WP8. 1993. ftp://ftp.mrc-apu.cam.ac.uk/pub/amodeus/sysmod/sm_wp08.ps.Z.
2. Duke D.J., Harrison M.D. Abstract Interaction Objects // Computer Graphics Forum. 1993.- Vol. 12.- N 3.- P. 26-36.
3. Гордиенко А.П. Модели интеракторов // Вестник МЭИ.- 2004.- N 5.- С. 58-64.
4. Гордиенко А.П. Формирование модели интерактора как универсального логического устройства ввода // Вестник ОрелГТУ.- 2005.- (готовится к печати)
5. Sabry A. What is a purely functional programming // J. Functional Programming.- 1993.- N 1.- p. 1-22.
6. Bird R. Introduction to functional programming using Haskell.- Prentice Hall Press, 1998.
7. Хоар Ч. Взаимодействующие последовательные процессы М: Мир, 1989.
8. Гордиенко А.П. Процессы диалога // Известия ОрёлГТУ. Серия «Информационные системы и технологии».- 2005.- N 2(8).- С. 50 -61.
Размещено на Allbest.ru
Подобные документы
Разработка веб-приложений на основе Servlet API. Основные способы передачи данных от пользователя. Краткая справка по необходимым программным компонентам. Составление программы интернет-чата на основе протокола HTTP. Диаграмма классов веб-приложения.
лабораторная работа [1,1 M], добавлен 01.05.2014Изучение принципов объектно-ориентированного программирования. Понятие класса в Delphi, в основе которых лежат три фундаментальные принципы - инкапсуляция, наследование и полиморфизм. Разработка классов транспортных средств и структур классов (кошки).
курсовая работа [29,7 K], добавлен 29.10.2011Описание используемых понятий и механизмов объектно-ориентированного программирования. Разработка и описание необходимых классов. Демонстрационный модуль с кратким описанием использованных стандартных компонентов. Внешний вид и листинг программы.
курсовая работа [1,3 M], добавлен 24.07.2013Обзор технологии OpenStack, область ее применения. Реализация библиотеки классов. Реализация базовых классов и интерфейсов архитектуры. Создание виртуального сервера. Интеграция разработанной библиотеки классов и архитектура проектного решения.
дипломная работа [1,0 M], добавлен 09.08.2016Оценка функциональных возможностей стандартных классов представления данных на примерах использования избранных методов ("detect: ifNone:" класса Set, "to:by:do:" класса Number и "copy: ReplaceFrom: to: with:" класса OrderedCollection), их тестирование.
лабораторная работа [1,1 M], добавлен 14.10.2012Создание библиотеки классов на основе C-строк и управляемую пользователем программу с псевдографическим интерфейсом, тестирующую её работу и отображающую результат. Упрощённая структура библиотек, взаимодействие классов и объектов, основные алгоритмы.
курсовая работа [37,5 K], добавлен 15.08.2012Диаграмма последовательности работы в интерфейсе программы. Интерфейсы необходимых классов и их взаимодействие. Средства обработки исключений. Начальный экран работы программы. Инструменты работы с персоналом. Основные функции работника регистратуры.
курсовая работа [3,7 M], добавлен 09.10.2013Листинг класса для работы с регулярными выражениями. Особенности классов для проверки данных при регистрации и отправки сообщений. Отправка ссылки для активации на почту пользователя, описание основных классов, анализ их назначения и листинг функций.
курсовая работа [1,7 M], добавлен 17.09.2013Разработка простейших классов на примере разработки моделей элементарных объектов и динамических информационных структур (одно и двунаправленных списков). Разработка простых классов. Вызывающая программа (main). Информационные динамические структуры.
творческая работа [17,5 K], добавлен 08.12.2007Принципы построения распределенных информационных приложений. Распределенное трех уровневое приложение. Необходимость использования приложений в средней школе. Системы управления контентом для создания сайта. Анализ сайтов учителей начальных классов.
дипломная работа [2,1 M], добавлен 26.05.2014