Icon Editor GUI Demonstration
Приклад "Icon Editor GUI Demonstration". Опис складено за участю студента Ульченка Є.Г. (СамДТУ).
Модель графічного інтерфейсу користувача "Редактор піктограм" міститься у розділі Simulink-Stateflow-Examples.

Рис.1 Запуск демонстраційного прикладу
Запустивши модель, побачимо наступне вікно.

У перекладі українською мовою написи позначають таке.

Блок Event Injector виконує роль системи, що стежить, яка відстежує зміну стану маніпулятора "миша" і синтезує відповідні події на виході. Внутрішню структуру блоку Event Injector ми можемо побачити малюнку 4:
Рис.4 "Внутрішня структура блоку Event Injector"
'BM' Mouse motion - Переміщення миші
'NBD' Normal (left) mouse button-down - Натиснута ліва кнопка миші
'BU' Mouse button-up - Кнопка миші відпущена
'ABD' Alternate (right) mouse button-down - Натиснута права кнопка миші
Виходом цієї функції є масив-рядок, що складається із чотирьох елементів. Зміна відповідного елемента масиву з 0 на 1 або навпаки – відображає появу цієї події.
Наприклад, якщо вихідний вихідний масив був , то після натискання і відпускання, наприклад лівої кнопки миші вихідний масив зміниться - що відповідає появі двох подій: натискання лівої кнопки ( 'NBD') і відпускання кнопки ('BU'). Якщо тепер натиснути та відпустити праву кнопку миші, то на виході буде .

Блок 'Chart' є керуючою програмою, написаною мовою алгоритмів, що використовується для побудови Stateflow-моделей. Т.о. блок 'Chart' є алгоритмом подієво керованої моделі. Внутрішня структура блоку Chart представлена на малюнку 6.

Рис.6"Внутрішня структура блоку 'Chart'"
Як видно з малюнка, в блоці Chart є три підсистеми: Main, Focus, ToolBar, кожна з яких реалізує окремий алгоритм.
Всі підсистеми працюють паралельно, однак, на рис.6 в прямокутнику знаходиться замітка - 'Note: Make sure "Focus" використовується для "Tool". "Переконайтеся, що 'Focus' знаходиться перед 'Tool'. Стан 'Tool' залежить від поточної інформації про 'Focus'". Тобто. обчислення змінних, що використовуються в 'ToolBar', але обчислюваних у 'Focus', має відбуватися раніше, ніж використання їх значень у 'ToolBar'.
У блоці 'Chart' використовується:
Підсистема 'Focus'.

Рис.7 "Підсистема 'Focus'"
Ця підсистема призначена для відстеження положення курсору миші у вікні Stateflow Icon Editor.
- 'ToolBar' - 'Панель інструментів' - область панелі інструментів (на рис.5 - панель інструментів).
- 'Palette' - 'Палітра' - область палітри, яка підрозділяється на області 'Swatch' - 'Зразок' і 'None'- 'Ніяке'. ('Swatch' - область кольорів палітри; 'None' - решта області палітри, до цієї області відноситься і індикатор, що показує вибраний колір).
- 'Canvas' - 'Полотно' - область малювання (на рис.5 - великий білий квадрат).
- "Icon" - "Піктограма" - область відображення зменшеної іконки (на рис.5 - маленький білий квадрат у лівому нижньому кутку).
- 'None' - 'Ніяке' - порожня область, тобто. область, що не відноситься до жодної з перелічених вище (на рис.5 ця область зафарбована яскраво-синім кольором).
Варто відзначити, що вхідною подією для підсистеми Focus є лише подія BM - переміщення миші.
Характеристика положення курсору мишіобмежується п'ятьма вищезгаданими областями, т.к. в областях 'Palette' та 'ToolBar' є свої підобласті, безпосередньо окремі кольори на палітрі та сім керуючих кнопок на панелі інструментів.
Відстеження положення миші всередині палітри здійснюється всередині модуля sf_edit_icon.m, а стеження за положенням миші на панелі інструментів здійснюється за допомогою функції set_focusedIcon(), яка є набором умов, за якими визначається значення змінної 'focusedIcon', яка в свою чергу і є характеристикою положення курсор.

Відстеження значення цієї змінної починається з моменту переходу підсистеми 'Focus' у стан 'ToolBar', продовжується протягом знаходження 'Focus' у цьому стані, і при виході зі стану 'ToolBar' змінної focusedIcon присвоюється значення 0, що відповідає випадку, коли курсор миші не знаходиться на жодній з кнопок панелі керування. Т.о. Значення змінної focusedIcon є вихідним для роботи алгоритму підсистеми 'ToolBar', саме тому алгоритм 'Focus' повинен виконуватися перед алгоритмом 'ToolBar'.

Рис.9 "Підсистема 'ToolBar'"
Ця підсистема є керуючим алгоритмом панелі інструментів.
Як видно з рис.9, підсистема 'ToolBar' має 4 стани: 'None' - 'Ніяке', 'Pressed' - 'Натиснуто', 'Released' - 'Відпущено', 'Locked' - 'Вибрано'.
по-перше, цей стан відповідає положенню курсору миші як усередині, так і поза області панелі інструментів;
по-третє, перехід із цього стану може бути здійснений тільки в стан 'Pressed' і тільки в тому випадку, якщо курсор миші знаходився в області панелі інструментів, і при цьому була натиснута ліва клавіша миші - на рис.9 це відображено умовним переходомNBD [in(Focus.Toolbar)].
При вході в стан 'Pressed' відбуваються такі дії: змінної 'pressedIcon' присвоюється значення змінної 'focusedIcon' (pressedIcon=focusedIcon), і викликається функція 'press' (press(pressedIcon,1)). При виході зі стану 'Pressed' також активується функція 'press' (press(pressedIcon,0)). За допомогою активації цієї функції реалізуються візуальні ефекти натискання та відпускання вибраних кнопок на панелі інструментів.
Вхідними змінними функції 'press' є змінні 'icon' та 'sp'. У змінну 'icon' міститься інформація про вибраний елемент панелі інструментів, а змінна 'sp' визначає, яку дію (натиснути або відпустити кнопку) потрібно виконати з вибраним елементом. Завдання вхідних змінних виконується стандартним записом виклику функції - 'press(icon,sp)', де:
'press' - ім'я функції, що викликається,
'icon' - змінна, що відповідає вибраному елементу панелі інструментів,
'sp' - змінна, що відповідає типу дії над вибраним елементом.
Т.о. при вході в стан 'pressed', що відповідає дії - натискання лівої кнопки миші на панелі інструментів, змінну 'pressedIcon' заноситься значення змінної 'focusedIcon' - тобто. відбувається ідентифікація обраного елемента панелі інструментів. Викликом функції 'press' - press(pressedIcon,1) (icon=pressedIcon, sp=1) здійснюється активація візуального ефекту - натискання кнопки вибраного елемента. При виході зі стану 'Pressed' викликом функції 'press' - press(pressedIcon,0) проводиться візуалізація ефекту відпускання кнопки обраного елемента.
Внутрішній алгоритм цієї функції представлено малюнку 10.

Внутрішній алгоритм є набір з 7-ми умов, типу"якщо, то:", що відповідають 7-ми кнопкам на панелі інструментів, що передбачають виклик відповідної процедури, при виконанні однієї з умов.
Зі стану 'Pressed' система може потрапити або в стан 'Released', або в стан 'Locked', або в стан 'None'.
Перехід у стан 'Released' здійснюється тоді, коли одночасно відбувається подія 'BM' - рух миші, і перестає виконуватися умова рівності змінних 'pressedIcon' та 'focusedIcon'. Тобто. це відповідає такому ланцюгу подій: ми навели курсор миші на одну з 7 кнопок на панелі інструментів і натиснули ліву кнопку миші - так ми перевели систему в стан 'Pressed'. Далі якщо ми, не відпускаючи кнопки, зрушимо курсор миші з обраної спочатку кнопки, ми переведемо систему у стан 'Released' - 'Отпущенный'. Зі стану 'Released' система може перейти в стан 'None' - це станеться якщо ми відпустимо ліву кнопку миші, або назад у стан 'Pressed' - якщо ми. Не відпускаючи ліву кнопку, повернемо курсор миші на вибрану кнопку панелі.
Якщо ж ми відпустимо ліву клавішу, не зрушуючи курсор миші з кнопки обраного елемента, то відбудеться перехід по гілці 'BU' - відпускання кнопки, і система перейде або до стану 'Locked', або до стану 'None'.
Перехід у стан 'None' буде здійснено в п'яти випадках, коли елемент, що вибирається, не є інструментом "лінія" або "олівець", і при цьому переході буде викликана функція 'icon_operation(pressedIcon)', яка в залежності від обраної кнопки активує потрібну вкладену функцію . Алгоритм функції 'icon_operation(icon)' аналогічний алгоритму функції 'press(icon, sp)'. Тобто. алгоритм є набором із п'яти умов "якщо, то:", при виконанні одного з яких викликається потрібна функція, абоздійснює скасування попереднього впливу (кнопка повернення) чи відкриває необхідне діалогове вікно (інші 4 кнопки).
Перехід у стан 'Locked' відбудеться у випадку, якщо вибраним елементом був інструмент олівець або лінія (при цьому в процесі переходу відповідною гілкою буде активовано функцію ml.sf_edit_icon('pencil_cursor') або ml.sf_edit_icon('line_cursor'), яка змінить вид курсору миші зі стрілки на олівець – для олівця або на хрест – для лінії). При вході системи в стан 'Locked' у рядку стану напис 'Select a Tool', що виставляється при попаданні в стан 'None', заміниться написом 'Tool locked' - 'Інструмент вибраний'. Зі стану 'Locked' система може перейти тільки в стан 'Pressed', і тільки в тому випадку якщо буде натиснута ліва кнопка миші в області панелі інструментів. Зі стану 'Pressed' система може перейти в будь-який інший стан при виконанні необхідних умов.
Підсистема 'Main' - 'Головна' є підсистемою управління безпосередньо редагуванням піктограм. З рис.6 видно, що система 'Main' має 4 стани: 'Idle' - 'Холостий хід', 'LineDraw' - 'Малювання лінією', 'PencilDraw' - 'Малювання олівцем', 'FGColorSelect' - 'Вибір кольору' , і ще один стан, під час переходу до якого активізується меню палітри.
1-2)NBD[in(ToolBar.Locked)&&. in(Focus.Canvas)] - була натиснута ліва кнопка миші, причому підсистема 'ToolBar' перебуває у стані 'Locked', а підсистема 'Focus' може 'Canvas'. Це відповідає випадку, коли відбулася подія NBD - була натиснута ліва кнопка миші, при цьому вже був обраний інструмент (причому або "олівець", або "лінія"), і курсор миші знаходиться в полі малювання - Canvas.
Далі цей умовний перехід поділяється на 2 гілки зумовами:
[pressedIcon == LINE_ICON] - було обрано інструмент " лінія " , система перетворюється на стан 'LineDraw'.
[pressedIcon == PENCIL_ICON] - був вибраний інструмент "олівець", система переходить у стан 'PencilDraw'.