Программирование диалоговых окон на языке DCL
Функция dimx_tile
Функция dimx_tile вычисляет горизонтальный размер графического элемента с данным кодом (точнее, размер элемента минус 1). Синтаксис:
(dimх_tile <код>)
Аргумент <код> - строка с кодом графического элемента. Возвращаемое значение - целое число с номером крайнего правого пикселя элемента (левый крайний пиксель имеет номер ноль).
Пример:
(dimx_tile "igp2") - может вернуть 50 (всего по горизонтали 51 пиксель)
Функция dimy_tile
Функция dimy_tile вычисляет вертикальный размер графического элемента с данным кодом (точнее, размер элемента минус 1). Синтаксис:
(dimy_tile <код>)
Аргумент <код> - строка с кодом графического элемента. Возвращаемое значение - целое число с номером крайнего нижнего пикселя элемента (верхний крайний пиксель имеет номер ноль)
Пример: (dimy_tile "igp2") - может вернуть 32 (всего по вертикали будет 33 пикселя).
Упражнения с элементами диалоговых окон
Построение элементов
Установите элементы диалогового окна согласно следующей программе:
// Установки элементов диалогового окна // elements: dialog {label="Установка элементов диалогового окна"; :column{:row{:boxed_column{label="Элементы управления"; :row{:boxed_column{label="Поле и выпадающий список"; :edit_box {label="Edit_box";key="txt";value="0.00";edit_width=8;} :popup_list {label="Popup_list";key="pop";width="8";list="Иванов\nПетров\nСидоров";}} :boxed_column{label="Кнопка и шкала"; :button {label="Button";key="but";color="1";width="8";} :slider {label="Slider";}}} :spacer{height=1;} :radio_row {label="Ряд переключателей (radio_row)"; :radio_button {label="Radio_button 1";value=1;} :radio_button {label="Radio_button 2";value=0;} } } :boxed_row{:column{label="Список и флажок"; :list_box {label="List_box";key="list";list="Иванов\nПетров\nСидоров";height="8";} :toggle {label="Toggle";value=1;} } }} :boxed_row{label="Стандартная кнопка закрытия окна"; ok_cancel_help_info; }}}
Сохраните файл как Elements.dcl в папке Support.
Создайте файл загрузки:
(defun c:show_elements (/ num ddiag) (if (< (setq num (load_dialog "elements.dcl")) 0) (prong (alert "The Elements.dcl file could not be loaded!") (exit)) ) (if (not (new_dialog "elements" num)) (exit) ) (start_dialog) (unload_dialog num) ;;;--- If the user pressed the Cancel button (if (= ddiag 1) (princ "\n Window cancelled!") ) ;;;--- If the user pressed the Okay button (if (= ddiag 2) (progn (princ "\n The user pressed Okey!") ) ) (princ) ) ;_defun
Сохраните файл загрузки как Elements.dcl.
Запустите функцию show_elements из командной строки AutoCAD. На экране должно появиться диалоговое окно (рис. 6.3).
Программа может различить в наших действиях лишь нажатие кнопок ОК и Cancel.
Текстовые поля Edit_Box
Измените описание диалогового окна в файле rog.dcl:
//Диалоговое окно установки параметров рога rog: dialog{label="Установка параметров рога"; :edit_box{label="Радиус окружности ";key="rad" ;value="80.00"; edit_width=8;} :edit_box{label="Диаметр дуги, мм";key="diam";value="400.00";edit_width=8;} :edit_box{label="Толщина стенки, мм";key="thick";value="1.00";edit_width=6;} :spacer{height=1;} :edit_box{label="Индекс цвета";key="col";value="2";edit_width=4;} :spacer{height=1;} ok_cancel; }
А теперь вернитесь к файлу rog.lsp. В функции qrog отклики на события в диалоговом окне описывались с помощью функции action_tile. Значения переменных сохранялись для каждого отдельного элемента. Опробуйте другой способ сохранения указанных данных - по нажатии кнопки ОК. В этом случае можно оставить значения величин по умолчанию, либо отредактировать их в текстовых полях диалогового окна.
Создайте в этом же файле новую функцию save_vars, которая будет вызываться после нажатия кнопки ОК. Содержимое текстовых полей прочитает функция get_tile.
Следует учесть, что в данном случае переменные rad1, diam1, thick1, col1 должны быть общими для функций qrog и save_vars, т.е. глобальными.
(defun save_vars () (setq rad1 (atof (get_tile "rad"))) (setq diam1 (atof (get_tile "diam"))) (setq thick1 (atof (get_tile "thick"))) (setq col1 (get_tile "col")) )
Программа построения рога будет выглядеть следующим образом:
(defun c:qrog (/ cenrt1 circle1 arc1 rog1 angle1 endp1 dial) (setq centr1 '(0 0 0)) ; исходная базовая точка (if (< (setq num (load_dialog "rog.dcl")) 0); загружаем в память файл "rog.dcl" (progn (alert "Файл Rog.dcl не загружен!"); сообщение о неудачной загрузке (exit) )) (if (not (new_dialog "rog" num)); ;; ;;функция new_dialog проверяет наличие в файле диалога "rog" (progn (alert "Диалог Rog не найден!"); сообщение о неудачном поиске файла (exit) )) ;;;If an action event occurs, do this function (action_tile "accept" "(setq dial 2)(save_vars)(done_dialog)"); действия при нажатии ОК (action_tile "cancel" "(setq dial 1)(done_dialog)"); действия при нажатии CANCEL (start_dialog); активизирует диалоговое окно (unload_dialog num); выгружаем окно из памяти (setq angle1 (* 55.0 (atan rad1 (* diam1 (/ pi 2))))); находим угол сужения тела рога (command "_view" "_top") ; начинаем со стандартного вида (command "_view" "_swiso"); переходим к северо-западному виду (command "_circle" centr1 rad1 ""); строим базовую окружность (setq circle1 (entlast)); извлекаем имя сущности для базовой окружности (command "_ucs" "_x" "90" ""); поворачиваем ПСК (setq endp1 (list diam1 0.0)); находим координаты конечной точки дуги (command "_arc" centr1 "e" endp1 "a" "-180" ""); строим дугу изгиба рога (setq arc1 (entlast)); извлекаем имя сущности для дуги и сохраняем его (command "_ucs" "_x" "-90"); совмещаем плоскость окружности с плоскостью XY (command "extrude" circle1 "" "t" angle1 "p" arc1 "");создаем тело рога (setq rog1 (entlast)); извлекаем имя сущности для рога и сохраняем его (command "_zoom" "e" ""); растягиваем изображение на весь экран (command "_vscurrent" "_r" ""); устанавливаем текущий визуальный стиль realistic (command "_chprop" "_all" "" "_color" col1 ""); закрашиваем цветом col1 (command "_view" "_bottom" ""); устанавливаем вид снизу (command "_solidedit" "_body" "_shell" rog1 centr1 "" thick1 "" ""); делаем полость (command "_erase" arc1 ""); удаляем ненужную образующую дугу ;;;If the user pressed the Okey Or Cancel button (if(= dial 2) (alert "Congratulations!")); поздравление при успешном построении (if(= dial 1) (alert "Alas!")); увы! - при неудачном построении (princ); тихий выход )
В качестве варианта введите операции сохранения значений переменных в функцию qrog. Сделайте все переменные локальными. Функция save_vars тогда не нужна.
Рассмотрим теперь более подробно работу с отдельными элементами диалоговых окон: с кнопками, со списками, с флажками и с радиокнопками.
Кнопки Button
Создадим DCL-файл описания диалогового окна с тремя кнопками Button и одной кнопкой Cancel. Каждая из трех кнопок должна выдать послание при нажатии.
Расположите кнопки в колонку друг под другом в две группы:
But:dialog {label="Работа с кнопками Button"; :column{:boxed_column { :button {key="but1";label="Button1";is_default="false";} :button {key="but2";label="Button2";is_default="false";} :button {key="but3";label="Button3";is_default="false";} } :boxed_row{ok_cancel; } } }
Сохраните файл как But.dcl в папке …\Support.
А теперь составьте файл But.lsp для загрузки dcl-файла и описания сценария отклика на события в диалоговом окне. Он будет состоять из двух функций:
(defun C:But1() ;;;--- Load the dcl file (setq dcl_id (load_dialog "But.dcl")) ;;;--- Load the dialog definition if it is not already loaded (if (not (new_dialog "But" dcl_id)) (progn (alert "The But.dcl file could not be loaded!")(exit) ) ) ;;;--- If an action event occurs, do this function (action_tile "but1" "(doButton 1)") (action_tile "but2" "(doButton 2)") (action_tile "but3" "(doButton 3)") (action_tile "cancel" "(done_dialog)") ;;;--- Display the dialog box (start_dialog) ;;;--- Unload the dialog box (unload_dialog dcl_id) ;;;--- Suppress the last echo for a clean exit (princ) ) (defun doButton(a) (cond ((= a 1)(alert "Button 1 was pressed!")) ((= a 2)(alert "Button 2 was pressed!")) ((= a 3)(alert "Button 3 was pressed!")) ) )
На экране должна быть картинка, подобная рис. 6.4.