Текущий раздел:

Описания RDS

Описание пользователя

Глава 3. Использование стандартных модулей автокомпиляции

§3.6. Принципы создания автокомпилируемых моделей блоков

§3.6.6. Блоки с настраиваемыми пользователем параметрами

# Описание пользователя

## Глава 3. Использование стандартных модулей автокомпиляции

### §3.6. Принципы создания автокомпилируемых моделей блоков

#### §3.6.6. Блоки с настраиваемыми пользователем параметрами

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

Чтобы сделать ввод различных параметров, управляющих работой блока, более удобным, модуль автокомпиляции позволяет достаточно просто создавать окна настроек, в которых пользователь в режиме редактирования может вводить или выбирать из списков значения этих параметров. Интерфейс создания таких окон подробно описан в §3.5.6. Рассмотрим несколько простых примеров блоков с настройками.

Сначала создадим блок, умножающий вещественный вход «x» на константу «K» и выдающий полученное произведение на выход «y», причем «K» сделаем параметром блока, который пользователь сможет вводить в окне настройки, открываемом по двойному щелчку на блоке. Создадим в схеме новый блок, запускающийся по сигналу, и зададим ему следующую структуру статических переменных:

Имя | Тип | Вход/выход | Пуск | Начальное значение
--- | --- | --- | --- | ---
Start | Сигнал | Вход | ✓ | 1
Ready | Сигнал | Выход |  | 0
x | double | Вход | ✓ | 0
y | double | Вход |  | 0

Модель блока будет запускаться при самом первом запуске расчета (у сигнала «Start» единичное начальное значение) и при поступлении нового значения на вход «x» (у этого входа установлен флажок «пуск»). «K» будет настроечным параметром, поэтому в структуру переменных блока переменная с таким именем не входит. На вкладку «модель», то есть в реакцию на такт расчета, введем единственный оператор:

      y=K*x;

Осталось добавить в список настроечных параметров переменную «K» и создать для нее поле ввода.

Выберем в левой части окна редактора вкладку «настройки» (см. рис. 344) – в данный момент и список параметров, и список полей ввода окна настройки на ней пусты. Нажмем в верхней части вкладки (в списке параметров) кнопку со знаком «+» и заполним открывшееся окно согласно рис. 422.

Рис. 422. Добавление настроечного параметра «K» и поля ввода для него

На панели «переменная» введем имя «K» (это имя будет именем переменной в нашей программе, поэтому введенная буква «K» должна быть буквой латинского алфавита), выберем в списке тип «double» и дадим параметру значение по умолчанию «1». Одновременно с самим параметром создадим и поле ввода для него – на панели «поле ввода» установим флажок «добавить для этой переменной поле ввода» и введем заголовок «Множитель». Теперь окно можно закрыть кнопкой «OK». Вкладка «события» окна редактора модели после этого примет вид, изображенный на рис. 423: в списке параметров появилась переменная «K», а в списке полей окна настройки – поле ввода для нее с заголовком «множитель».

Рис. 423. Окно редактора модели с добавленным параметром

Чтобы пользователю было понятнее, настройки какого блока он вызвал, дадим окну настройки заголовок. Для этого на панели «окно настройки» в нижней части вкладки «настройки» нажмем кнопку справа сверху от списка полей (она останется нажатой) и введем заголовок «умножение на константу», как показано на рис. 424. Ширину и высоту окна вводить не будем.

Рис. 424. Ввод заголовка окна настроек

Теперь можно посмотреть, как будет выглядеть созданное нами окно настроек. Нажмем кнопку «тест» под списком полей ввода, и созданное нами окно откроется (рис. 425).

Рис. 425. Тестирование окна настроек

При некоторых настройках Windows (например, если установлены крупные шрифты), введенный нами текст заголовка окна может не уместиться в его верхней части – именно такой случай изображен на рисунке. Можно ввести другой, более короткий, заголовок, а можно просто увеличить ширину ширину окна, установив флажок «ширина» над списком полей ввода (см. рис. 424, если панель с заголовком закрылась, ее снова можно открыть кнопкой над списком полей) и введя желаемую ширину окна в точках экрана. Можно, например, установить ширину в 300 точек и снова нажать кнопку «тест», чтобы проверить, уместился ли заголовок в окно. Если он все равно не умещается, можно ввести большую ширину и снова протестировать окно, и т.д. до тех пор, пока окно с заголовком не приобретет желаемый внешний вид.

Выполненных действий достаточно, чтобы у блока появилось окно настройки, в котором можно будет вводить значение множителя «K». Это значение будет сохраняться вместе со схемой, причем независимо для всех блоков с этой моделью: если в схеме будет несколько таких блоков, значения «K» у них могут быть разными, несмотря на то, что их обслуживает одна и та же модель. Модуль автокомпиляции автоматически добавляет в модель команды сохранения и загрузки введенных пользователем значений параметров при сохранении и загрузке схемы или самого блока. Этим настроечные параметры отличаются от, например, значений по умолчанию статических переменных блока: у всех блоков с одной и той же моделью значения переменных по умолчанию будут одинаковыми, поскольку структура переменных блока с автокомпилируемой моделью запоминается в файле модели, а не в файле схемы, в котором хранятся другие данные блока.

Теперь можно скомпилировать модель и закрыть окно редактора. Если нажать на созданном блоке правую кнопку мыши и выбрать в контекстном меню пункт «настройка», откроется созданное нами окно, в котором можно будет ввести значение множителя «K» для этого блока.

В отличие от большинства стандартных блоков, у которых окно настройки открывается по двойному щелчку, в нашем блоке по двойному щелчку открывается редактор модели. Можно исправить это двумя способами. Если блок с этой моделью – единственный, как в нашем случае, проще всего открыть окно его параметров (пункт «параметры» в его контекстном меню), и на вкладке «общие» включить флажок «двойной щелчок – вызывает функцию настройки» (рис. 426).

Рис. 426. Включение настройки по двойному щелчку в окне параметров блока

Если же блоков с данной моделью несколько, лучше включить настройку по двойному щелчку для них всех одновременно. Для этого нужно открыть редактор модели и выбрать пункт меню «модель | установка параметров блоков» (см. §3.5.8): при этом откроется окно групповой установки, в котором можно изменить параметры всех блоков с этой моделью. На вкладке «разное» этого окна на панели «двойной щелчок» следует включить флажки «установить реакцию» и «передается в функцию DLL» (рис. 427). В данном случае, «передается в функцию DLL» означает, что с двойным щелчком будет разбираться модель блока, а не RDS (окно параметров блока) и не модуль автокомпиляции (редактор модели). А модель блока по двойному щелчку может только открывать окно настройки, что и будет происходить. Новая реакция на двойной щелчок вступит в силу после закрытия окна кнопкой «OK».

Рис. 427. Включение настройки по двойному щелчку в окне групповой установки

Рис. 428. Блок умножения на
константу и окно его настройки

Для проверки работы созданной модели и ее настройки можно подключить поле ввода к входу блока «x» и числовой индикатор к выходу «y» (рис. 428). Двойной щелчок на блоке откроет окно настройки, в котором вводится множитель. Запустив расчет и изменяя значение на входе блока, можно будет видеть на выходе значение произведения входа и введенной в окне константы.

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

В §3.6.5 описывается простой индикатор уровня, рисующий на белом фоне вертикальный синий столбик, высота которого пропорциональна значению входа блока, причем вход мог изменяться от нуля (столбик нулевой высоты) до ста (столбик высотой во весь блок). Изменим модель так, чтобы диапазон изменения входа и все используемые при рисовании цвета стали настроечными параметрами.

Откроем редактор ранее созданной модели и, описанным выше образом, добавим на вкладке «настройки» следующие настроечные параметры, одновременно создавая для них поля ввода:

Имя | Тип | По умолчанию | Заголовок поля ввода | Тип поля ввода
--- | --- | --- | --- | ---
Min | double | 0 | Минимум | Ввод
Max | double | 100 | Максимум | Ввод
UpColor | COLORREF | 0xffffff | Верхняя часть | Выбор цвета
DownColor | COLORREF | 0xff0000 | Нижняя часть | Выбор цвета
BorderColor | COLORREF | 0 | Рамка | Выбор цвета
ErrorColor | COLORREF | 0xff | Ошибка | Выбор цвета

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

Рис. 429. Добавленные настроечные параметры и тест окна настройки

У созданного окна настройки есть небольшой недостаток: разные по смыслу параметры изображаются вместе. Пользователю будет удобнее, если дать ему понять, что «минимум» и «максимум» относятся к диапазону входа, а кнопки – к заданию цветов блока. Можно добавить в окно пояснительные надписи, но от этого оно станет слишком высоким. Лучше всего разбить параметры на две вкладки: поля ввода диапазона входа будут находиться на вкладке «диапазон», а цвета – на вкладке «цвета».

Сейчас в нашем окне нет ни одной вкладки. Создадим первую из них: нажмем кнопку «добавить вкладку» под списком полей ввода (рис. 430) и введем ее заголовок «диапазон» в открывшемся окне. После нажатия кнопки «OK» все уже созданные поля ввода окажутся на новой вкладке. Еще раз нажмем кнопку «добавить вкладку» и введем заголовок «цвета» – новая пустая вкладка «цвета» появится в конце списка полей (рис. 431).

Рис. 430. Добавление вкладки

Рис. 431. В окно добавлены вкладки «диапазон» и «цвета»

Теперь нам нужно по очереди переместить кнопки выбора цветов на вторую вкладку. Сначала выберем в списке поле ввода для параметра «UpColor». Под списком полей слева находятся две кнопки со стрелками вниз и вверх, предназначенные для изменения порядка полей и вкладок. Будем нажимать кнопку со стрелкой вниз до тех пор, пока поле «UpColor» не переместится ниже символа вкладки «цвета». Теперь поле ввода будет располагаться на этой вкладке.

Последовательно переместим все остальные поля задания цветов на вкладку «цвета» таким же образом, выстроив их в том же порядке, в котором мы их добавляли: «UpColor», «DownColor», «BorderColor» и «ErrorColor». Чтобы визуально отделить цвет «ErrorColor», используемый для индикации ошибки входа, от остальных трех цветов, использующихся при нормальной работе блока, добавим после «BorderColor» (то есть, перед «ErrorColor») рельефную линию. Для этого дважды щелкнем на «BorderColor» в списке полей окна настройки (то есть в списке на нижней части вкладки – на верхней части вкладки располагается список самих параметров, а не полей ввода для них) и в открывшемся окне параметров поля ввода установим флажок «рельефная линия-разделитель» (рис. 432).

Рис. 432. Добавление рельефной линии в окне параметров поля ввода

Теперь поля ввода распределены по двум вкладкам. Если нажать под списком полей кнопку «тест», можно будет увидеть окно с вкладками «диапазон» и «цвета» и линией между полями «рамка» и «ошибка» на последней (рис. 433).

Рис. 433. Список полей ввода (слева) и две вкладки созданного окна настроек (в центре и справа)

Мы добавили в блок настроечные параметры и создали окно настройки для них. Теперь нужно ввести эти параметры в модель. Текст на вкладке редактора «рисование» (это единственный введенный фрагмент программы в модели индикатора уровня) нужно изменить, заменив в нем константы на настроечные параметры. В тексте ниже изменения выделены цветом. Комментарии оставлены без изменения, хотя в них вместо слов «красный», «белый», «синий» и «черный» теперь следовало бы тоже использовать имена параметров.

      // Вспомогательные переменные
      int right,bottom,h;

      // Правый нижний угол области блока
      right=DrawData->Left+DrawData->Width;
      bottom=DrawData->Top+DrawData->Height;

      // Проверка наличия ошибки на входе
      if(x==rdsbcppHugeDouble || Max<=Min) // Заливаем красным
        { // Красный фон
          rdsXGSetBrushStyle(0,RDS_GFS_SOLID,ErrorColor);
          // Черная линия
          rdsXGSetPenStyle(0,PS_SOLID,
                           DrawData->DoubleZoom,BorderColor,R2_COPYPEN);
          // Прямоугольник - черная рамка и красный фон
          rdsXGRectangle(DrawData->Left,DrawData->Top,right,bottom);
          // Завершаем реакцию, больше ничего не рисуем
          return;
        }

      // Высота синего столбика в точках экрана
      h=(x-Min)*DrawData->Height/(Max-Min);
      // Ограничение
      if(h<0)
        h=0;
      else if(h>DrawData->Height)
        h=DrawData->Height;

      // Отключаем рамку
      rdsXGSetPenStyle(RDS_GFSTYLE,PS_NULL,0,0,0);

      // Рисуем верхнюю (белую) часть
      if(h!=DrawData->Height) // Есть белое
        { // Белый фон
          rdsXGSetBrushStyle(0,RDS_GFS_SOLID,UpColor);
          // Верхняя часть - на h меньше высоты блока
          rdsXGRectangle(DrawData->Left,
                         DrawData->Top,
                         right,
                         bottom-h+1);
        }
      // Рисуем нижнюю (синюю) часть
      if(h!=0)
        { // Синий фон
          rdsXGSetBrushStyle(0,RDS_GFS_SOLID,DownColor);
          // Нижняя часть - от h до высоты блока
          rdsXGRectangle(DrawData->Left,
                         bottom-h,
                         right,
                         bottom);
        }

      // Рисуем рамку
      // Черная линия, толщина - с учетом масштаба
      rdsXGSetPenStyle(0,PS_SOLID,DrawData->DoubleZoom,
                       BorderColor,R2_COPYPEN);
      // Отключаем заливку
      rdsXGSetBrushStyle(RDS_GFSTYLE,RDS_GFS_EMPTY,0);
      // Прямоугольник рамки
      rdsXGRectangle(DrawData->Left,DrawData->Top,right,bottom);

В тексте модели, кроме замены цветовых констант на настроечные параметры, изменена также формула вычисления высоты столбика h (теперь там учитываются параметры границ диапазона x, которые раньше были жестко заданы) и проверка возможности рисования. Если раньше рисование было невозможно только тогда, когда на вход блока приходило значение-индикатор ошибки rdsbcppHugeDouble, то теперь ошибкой следует считать и неправильное задание диапазона индикатора: если пользователь по ошибке сделает верхнюю границу диапазона Max меньше или равной нижней Min, рисование индикатора становится бессмысленным. На самом деле, следовало бы также проверить и Min, и Max на равенство rdsbcppHugeDouble, но, для упрощения примера, будем считать пользователя достаточно разумным, чтобы не вводить в качестве одной из границ вопросительный знак, обозначающий в RDS ошибочное значение.

Теперь цвета и границы диапазона нашего блока могут быть настроены пользователем. Для его удобства можно сделать так, чтобы окно настройки открывалось по двойному щелчку вместо редактора модели. Индикатор, у которого изменен входной диапазон и цвета верхней и нижней части, изображен на рис. 434.

Рис. 434. Измененный индикатор и вкладки его окна настроек

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