Н. Вирт - Программирование на языке Модула-2 (1160777), страница 23
Текст из файла (страница 23)
Все это и определило его название.Положение мыши отображается на экран с помощью отметки, называемой курсором. Темсамым осуществляется привязка устройства к экрану и к положению отдельных объектов,изображенных на экране. Способ изображения курсора и связь его положения на экране сперемещениями мыши по столу скрыты внутри модуля, который будет назван Mouse (Мышь).Пользователю не нужно знать ни его деталей, ни даже того, реализован ли модуль сиспользованием аппаратных средств или же только программными средствами.
Однакосущественно то, что курсор может быть установлен на любой элемент растра. Тем самымустройство ввода получает наибольшее полезное разрешение.118Процедуры, используемые для управления мышью, - TrackMouse (СледМыши) и FlipCursor(ПереключитьКурсор). TrackMouse используется для отслеживания перемещений мыши, т.е. рукипользователя. Она считывает положение мыши, изображает в соответствующем положениикурсор и присваивает его координаты экспортируемым переменным Мх и My. Обычно этапроцедура вызывается внутри короткого цикла, выполняемого, пока не будет нажата одна изкнопок, что сигнализирует о необходимости выполнить некоторое действие, связанное суказанными координатами.
Процедура FlipCursor переключает внутренний Флажок, включающийи выключающий изображение курсора на экране. Эта процедура важна, если необходимо иногдана время удалять курсор с экрана. Например, модуль Mouse, реализованный автором на машинеЛилит, требует, чтобы курсор удалялся с экрана во время рисования, записи или стиранияэлементов изображения. Текущее значение Флажка представляется экспортируемой переменнойcurOn (курсор включен).Процедура ShowMenu (ПоказМеню) предоставляет удобный способ ввода команд. Еевызов приводит к высвечиванию в текущей позиции курсора на экране списка командных слов,задаваемых текстовым параметром. Выдаваемая таким образом информация должнарассматриваться как меню команд, доступных в текущий момент.
Последующими перемещениямимыши можно выбрать одну из команд. Предполагается, что ShowMenu должна вызываться принажатии специальной клавиши мыши. При отпускании клавиши управление возвращается созначением параметра, указывающим выбранное командное слово. Использование таких меню удобное средство гибкого ввода команд с использованием единого простого устройства ввода содновременным указанием позиции объекта, к которому применяется команда.
Меню командпоявляется в текущей позиции курсора, т.е. именно там, где сфокусировано вниманиеработающего.DEFINITION MODULE Mouse;VAR keys: BITSET; (* кнопки мыши *)Mx,My: INTEGER; (* координаты курсора и мыши *)curOn: BOOLEAN; (* флажок состояния курсора;начальное значение = FALSE *)mode: CARDINAL;PROCEDURE TrackMouse;(* прочитать координаты мыши Мх.Му и состояние кнопок;сдвинуть курсор в соответствующую позицию *)PROCEDURE FlipCursor:(* переключить состояние Флажка курсора *)PROCEDURE ShowMenu(текст: ARRAY OF CHAR;VAR Выбор: INTEGER);(* высвечивает текст меню в текущей позиции курсора: последующими движениями мышивыбирается нужная команда.
Выбор происходит при отпускании кнопки. Выбор = 0означает, что никакая команда не была выбрана. В строке "текст" командные словаразделяются литерой "|". Должно быть не более 8 команд, и командные слова не должнысодержать более 7 литер *)119END Mouse.Использование модуля LineDrawing совместно с модулем Mouse демонстрируетсяследующей программой Рисование. Она позволяет рисовать картинки на квадратном участке,содержащем 64*64 растровых "элемента". Каждый из этих "элементов" представляетсяквадратиком 8*8 растровых элементов (пикселов). Используя меню, можно выбирать длярисования различные цвета или яркости. Эту программу можно дополнить и усовершенствоватьмногими способами, но основная ее структура такова:инициализировать экран;F1ipCursor; (*включить *)REPEAT TrackCursor;IF (нажата кнопка) & (мышь передвинута) THENFlipCursor; (*выключить*)выполнить нужное действие;FlipCursor; (*включить*)END;BusyRead(ch);(* проверка нажатой клавиши *)UNTIL ch = ESC;очистить экранЭтот пример также демонстрирует то, каким образом можно "одновременно" получатьинформацию и от клавиш мыши, и с клавиатуры (обычно используемой только для ввода текста,но иногда и для сигнальных Функций).
Ввод с клавиатуры происходит через процедуру BusyRead(ЧтениеЗанятого), которая в отличие от стандартной процедуры Read не ждет очередного нажатияклавиши, а немедленно возвращает значение 0С, если символ отсутствует.120MODULE Рисование;FROM Terminal IMPORT BusyRead;FROM LineDrawing IMPORTwidth,height,Px,Py,dot,line,area,clear;FROM Mouse IMPORTkeys,Mx,My,FlipCursor,TrackMouse,ShowMenu;CONST L = 512; (* размер квадрата *)ESC = 33C; DEL = 177C;VAR i,цвет,х0,у0,х1,у1: INTEGER;minx,maxx,miny,maxy: INTEGER;ch: CHAR;PROCEDURE ИнициализацияЭкрана;BEGIN area(1,0,0,width,height);Px := minx; Py := miny; area(0,Px,Py,L,L);line(0,L); line(2,L); line(4,L); line(6,L):121END ИнициализацияЭкрана;BEGINminx := (width-L) DIV 2; miny := (height-L) D1V 2;maxx := minx + L; maxy := miny + L: цвет := 3;ИнициализацияЭкрана; FlipCursor;(* включить курсор *)REPEAT TrackMouse;IF 14 IN keys THENShowMenu("white|grey0|grey1 |black", i);IF i # 0 THEN цвет := i - 1 ENDELSIF (15 IN keys)&(minx <= Mx)&(Mx < maxx)&(miny <= My)&(My < maxy) THENx1 := (Mx - minx) DIV 8; y1 := (My - miny) DIV 8;IF (x1 # x0) OR (y1 # y0) THENFlipCursor; (*выключить*)area( цвет,minx + x1*8,miny + yl*8,8,8); x0 := xl; y0 := y1;FlipCursor (*включить*)ENDEND;BusyRead(ch);IF ch = DEL THENFlipCursor; ИнициализацияЭкрана: FlipCursor;END UNTIL ch = ESC;clearEND Рисование.Обратимся теперь к модулю, позволяющему имитировать наличие многих дисплеев наединственном экране.
Каждый имитируемый дисплей представляется прямоугольником, вкотором операции вывода графики и текста так же доступны, как и для всего экрана. Такойпрямоугольный участок экрана называется одном, поскольку он может считаться окном, черезкоторое может быть видна выбранная часть документа. Эта техника была использована впрограмме преобразования выражений в польскую инверсную запись. Эта программа описана вразделе, посвященном рекурсии (разд.14).При использовании модуля работы с окнами можно открывать (создавать) окна изакрывать их по мере необходимости. Каждое окно изображается в виде прямоугольной области,содержащей заголовок, задаваемый при открытии окна.
Окна можно перемещать, как если бы этобыли листы бумаги, лежащие на столе, размеры окон можно менять, и их можно накладывать одно122на другое, опять же как будто бы это листы бумаги, лежащие на столе. Следовательно, модульработы с окнами дает мощное средство одновременного просмотра и обработки многихдокументов и тем самым очень существенно увеличивает возможности экрана. Улучшениестановится еще значительнее, если при работе с окнами возможен выбор размеров и начертаниялитер, причем буквы большего размера употребляются в наиболее используемых окнах, аменьшего - в менее важных документах или при необходимости просмотра за один раз большихФрагментов текста.Хороший пример одновременного использования нескольких окон -отладчик программ.
Наприведенном в разд. 29 рисунке окна используются для просмотра текста программы, значенийпеременных, содержимого памяти, последовательности вызовов, а также для диалога междупрограммистом и ЭВМ.Так как экран предоставляет гораздо более широкие возможности, чем простопоследовательный вывод текста, то будет разумным разбить систему работы с окнами нанесколько модулей. Они позволят выбрать только нужные средства (и исключить те, которые непотребуются).
Основной модуль может, например, сосредоточить возможности, необходимые вовсех приложениях, такие, как создание, удаление и наложение окон. Такой модуль долженобеспечивать вычерчивание рамок окон в соответствующих местах. Дополнительные модулимогут затем по отдельности обеспечивать либо возможность записи текста, либо возможностьвычерчивания прямых линий и заполнения областей шаблонами. Пример такой схемы приведен вприложении. Там даны два модуля Windows и TextWindows. Основной модуль предоставляетпроцедуры для. открытия нового окна и для закрытия окна. Кроме того, может изменяться какразмер, так и положение окна процедурой RedefineWindow. В третьем измерении окно можнопомещать на верх, или в самый низ перекрывающихся окон.
Этот метод позволяет сделатьдоступным больше окон (портов данных), чем действительно могло бы поместиться на экране.Модуль TextWindows обеспечивает средства для записи последовательного текста, вомногом аналогичные средствам основного модуля Terminal. Кроме того, он позволяет задаватьпозицию записи (SetPos), получать эту позицию (GetPos), устанавливать текстовый курсор взаданную позицию (SetCaret) и инвертировать область, в которую идет запись. Еще можнозадавать действие, выполняемое при' достижении конца страницы (AssignEOWAction). Этодействие передается в процедуру как параметр процедурного типа. Такой способ может служитьпрекрасной иллюстрацией полезности понятия Формальной процедуры.