Лабораторная
работа №3.
Разработка библиотеки интерфейсных элементов GUI
Преамбула
Интерфейсные элементы GUI носят название "виджет" (widget). Современные GUI-системы
(win32, kde, gtk и т.п.) предлагают достаточно большой набор разнообразных виджетов
(окна, меню, кнопки, метки и т.п.)
и обеспечивают средства управления ими. Часто управление виджетами
основано на объектно-ориентированной парадигме, когда каждый виджет является экземпляром
того или иного класса, при этом базовый класс иерархии имеет достаточный набор
абстрактных методов для управления виджетами. Другой подход предлагает использовать
дескрипторы графических виджетов и позволяет управлять ими с помощью набора графических
функций. При любом подходе GUI-система реализует обработку внешних событий,
обеспечивает передачу событий виджетам, организует отрисовку виджетов на экране и т.п.
Задание
Разработать программу, реализующую простейшую GUI-систему с отрисовкой
виджетов на холсте графического окна и реакцией на мышиные события. В качестве среды программирования
предлагается использовать Lazarus в операционных системах Linux или Windows на
усмотрение студента.
Базовый класс виджета
Базовый класс виджета должен инкпсулировать все необходимые для манипуляций с виджетом
свойства и методы. Например:
type
TGWidget=class;
TGNotifyEvent=procedure (Sender:TGWidget) of object;
TGWidget=class
public
top,left:integer; // координаты виджета
width,height:integer; // размеры виджета
canvas:tcanvas; // холст для прорисовки виджета
notifyredraw:tgnotifyevent; // callback для предупреждения хозяина о
// о необходимости перерисовки виджета
constructor create(_canvas:tcanvas);
procedure redraw(); virtual; abstract; // перерисовка виджета
procedure mouseClick(x,y:integer); virtual; abstract; // реакция виджета на мышиный клик
// далее - абстрактные методы-заглушки для реакции на различные типы событий
end;
Экземпляры базового класса виджета не создаются, он служит исключтиельно шаблоном для
виджетов других типов. В потомках базового класса виджета предусматривается перекрытие
всех абстрактных методов предка с описанием соответсвующей реакции на события (в реальных системах
предлагается создавать множество промежуточных классов с обеспечением реакции по умолчанию на все события).
Виджет-кнопка
В качестве примера рассмотрим описание класса TGClickButton. Данный
класс представляет собой кнопку, которая может существовать в двух состояних - нажатом и отжатом.
type
TGClickButton=class(TGWidget)
constructor create(_canvas:tcanvas; _top,_left,_width,_height:integer);
procedure mouseClick(x,y:integer); override;
procedure redraw(); override;
public
rised:boolean; // состояние кнопки
end;
В исходных файлах примера (см.ниже) отсутствует реализация
методов класса TGClickButton (файл gclickbutton.inc), Вам предлагается реализовать ее самостоятельно.
GUI-система
GUI-систему предлагается реализовать на базе холста основной формы.
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
procedure FormPaint(Sender: TObject);
public
WGS:array of TGWidget;
procedure RedrawWidget(Sender:TGWidget);
end;
Метод FormCreate (событие onCreate формы) обеспечивает инициализацию виджетов и их связь с формой.
Метод FormMouseUp (событие onMouseUp формы) обеспечивает передачу виджетам поступающих на форму
кликов мыши.
Метод FormPaint (событие onPaint формы) обеспечивает перерисовку виджетов.
Метод RedrawWidget является функцией обратного вызова (callback) для виджетов и предназначен
для информирования базовой формы об изменения состояния виджетов.
WGS - динамический массив для хранения всех виджетов.
Исходные и бинарные файлы примера
Для Linux:
Для Windows:
Замечания
- Для компиляции файлов примеров следует использовать среду
Lazarus версии 0.9.26
или более поздних версий
- Применение среды Lazarus для решения данной задачи не является является обязательным. Однако,
в случае выбора другой среды и(или) языка программирования, Вы будете вынуждены
самостоятельно реализовывать всю технологию обработки виджетов.