Розділ 7. Логічна взаємодія між елементами графічного інтерфейсу

Логіка графічного інтерфейсу

Усі базові поняття щодо створення додатків до RKWard було описано у попередніх розділах. Цих базових понять достатньо для багатьох, якщо не більшості, випадків. Втім, іноді вам можуть знадобитися додаткові можливості з керування графічним інтерфейсом вашого додатка.

Наприклад, припустімо, що ви хочете розширити приклад з t-перевіркою, використаний у цій документації, так, щоб можна було виконувати два завдання: порівняння змінної з іншою змінною (як показано) і порівняння змінної зі сталим значенням. Одним зі способом це реалізувати є додавання пунктів варіантів для перемикання між двома режимами та додавання пункту лічильника для введення сталого значення, з яким слід порівнювати змінну. Розгляньмо цей спрощений приклад:

<!DOCTYPE rkplugin>
<document>
        <code file="code.js"/>

        <dialog label="T-Test">
                <row>
                        <varselector id="vars"/>
                        <column>
                                <varslot id="x" types="number" source="vars" required="true" label="compare"/>
                                <radio id="mode" label="Compare against">
                                        <option value="variable" checked="true" label="another variable (select below)"/>
                                        <option value="constant" label="a constant value (set below)"/>
                                </radio>
                                <varslot id="y" types="number" source="vars" required="true" label="variable" i18n_context="Noun; a variable"/>
                                <spinbox id="constant" initial="0" label="constant" i18n_context="Noun; a constant"/>
                        </column>
                </row>
        </dialog>
</document>
        

Здається усе добре, але з таким графічним інтерфейсом є декілька проблем. По-перше, і varslot, і spinbox буде завжди показано, хоча насправді буде використано лише один з цих елементів. Гірше того, varslot завжди потребуватиме коректного вибору, навіть якщо порівняння буде виконуватися лише зі сталою. Очевидно, якщо ми створюємо багатоцільовий графічний інтерфейс, подібний до цього, нам потрібна більша гнучкість. Введіть до розділу <logic> (вставлено на той самий рівень, що і <code>, <dialog> або <wizard>):

[...]
        <code file="code.js"/>

        <logic>
                <convert id="varmode" mode="equals" sources="mode.string" standard="variable" />

                <connect client="y.visible" governor="varmode" />
                <connect client="constant.visible" governor="varmode.not" />
        </logic>

        <dialog label="T-Test">
        [...]
        

Першим рядком у розділі logic є теґ <convert>. На базовому рівні, це створює нову булеву властивість (увімкнено або вимкнено, так або ні), якою можна згодом скористатися. Ця властивість ("varmode") матиме значення «так», якщо буде вибрано верхній варіант, і значення «ні», якщо буде вибрано нижній варіант. Як же це досягається?

По-перше, у sources наведено список властивостей джерела, на якими слід працювати (у цьому випадку лише одну; декілька можна вказати так: sources="mode.string;щось_іще", тоді "varmode" матиме значення true, якщо і "mode.string" і "щось_іще" дорівнюють рядку "variable"). Зауважте, що у цьому випадку ми не написали просто "mode" (як було у getString("mode")), а "mode.string". Насправді, це пов’язано з тим, як працює засіб вибору з варіантів на внутрішньому рівні: він має властивість «string», у якій зберігається її рядкове значення. getString("mode") — просто скорочення, яке є еквівалентним до getString("mode.string"). Ознайомитися із усіма властивостями різних елементів графічного інтерфейсу можна за допомогою відповідного розділу цього підручника.

По-друге, ми встановлюємо режим перетворення mode="equals". Це означає, що ми хочемо перевірити, чи є джерело (чи джерела) рівним певному значенню. Нарешті, standard є значенням, із якими слід виконувати порівняння, отже, за допомогою standard="variable" ми перевіряємо, чи є властивість "mode.string" рівною рядку "variable" (значенню верхнього пункту варіанта). Якщо є, значенням змінної varmode буде true, інакше — false.

Тепер до справи: ми з’єднуємо (<connect>) змінну "varmode" з властивістю y.visible, яка керує видимістю varslot-а "y". Зауважте, що будь-який елемент, який стає невидимим, неявним чином стає необов’язковим. Отже, якщо позначено верхній варіант, varslot "y" буде обов’язковим і видимим. Якщо ж позначено інший варіант, він стане необов’язковим і невидимим.

Для поля лічильника нам потрібне зовсім протилежне. На щастя, нам не обов’язково додавати ще одне <convert> для цього: булеві змінні легко перетворювати на протилежні за допомогою додавання модифікатора "not", отже, ми з’єднаємо "varmode.not" із властивістю видимості поля лічильника. У результаті або буде показаним і обов’язковим varslot, або буде показаним і обов’язковим поле лічильника (spinbox). Усе залежатиме від вибраного варіанта. Графічний інтерфейс змінюватиметься автоматично у відповідь на дії користувача. Спробуйте поекспериментувати з нашим прикладом.

Повний список властивостей можна знайти у довідковій частині підручника. Втім, варто обговорити ще одну властивість, яка є специфічною для усіх елементів графічного інтерфейсу: «enabled». Вона не така дієва, як «visible». Вона не керує показом або приховуванням елемента графічного інтерфейсу, а лише вмикає або вимикає його. Вимкнені елементи типово буде показано сірим кольором, вони не реагуватимуть на дії користувача.

Примітка

Окрім <convert> і <connect>, у розділі <logic> можна використати ще декілька елементів. Наприклад, розгалуження за умовою може бути реалізовано за допомогою елемента <switch>. Докладніший опис можна знайти у довідці щодо елементів логіки.