Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Пример кода.






 

Класс Window (WindowImp) определяет абстракцию окна для клиентских приложений:

 

 

class Window {

public:

Window(View* contents);

// запросы, обрабатываемые окном

virtual void DrawContents();

virtual void Open();

virtual void Close();

virtual void Iconify(),

virtual void Deiconify();

// запросы, перенаправляемые реализации

virtual void SetOrigin(const Point& at);

virtual void SetExtent(const Point& extent);

virtual void Raise();

virtual void Lower();

virtual void DrawLine(const Point&, const Point&);

virtual void DrawRect(const Point&, const Point&);

virtual void DrawPolygon(const Point[], int n);

virtual void DrawText(const char*, const Point&);

protected:

Windowlmp* GetWindowImp();

View* GetView();

private:

Windowlmp* _imp;

View* _contents; // содержимое окна

};

 

 

В классе Window хранится ссылка на Windowlmp - абстрактный класс, в котором объявлен интерфейс к данной оконной системе:

 

class Windowlmp {

public:

virtual void ImpTop() = 0;

virtual void ImpBottom() = 0;

virtual void ImpSetExtent(const Point&) = 0;

virtual void ImpSetOrigin(const Point&) = 0;

 

virtual void DeviceRect(Coord, Coord, Coord, Coord) = 0;

virtual void DeviceText(const char*, Coord, Coord) = 0;

virtual void DeviceBitmap(const char*, Coord, Coord) = 0;

// множество других функций для рисования в окне...

protected:

Windowlmp();

};

 

Подклассы Window определяют различные виды окон, как то: окно приложения, пиктограмма, временное диалоговое окно, плавающая палитра инструментов и т.д.

 

Например, класс ApplicationWindow реализует операцию DrawContents для отрисовки содержимого экземпляра класса View, который в нем хранится:

 

 

class ApplicationWindow: public Window {

public:

//...

virtual void DrawContents();

};

 

 

 

void ApplicationWindow:: DrawContents () {

GetView() -> DrawOn(this);

}

 

 

А в классе IconWindow содержится имя растрового изображения для пиктограммы

 

 

class IconWindow: public Window {

public:

//...

virtual void DrawContents();

private:

const char* _bitmapName;

};

 

 

и реализация операции DrawContents для рисования этого изображения в окне:

 

 

void IconWindow:: DrawContents() {

Windowlmp* imp = GetWindowImp();

if (imp! = 0) {

imp-> DeviceBitmap(_bitmapName, 0.0, 0.0);

}

}

 

 

Могут существовать и другие разновидности класса Window. Окну класса TransientWindow иногда необходимо как-то сообщаться с создавшим его окном во время диалога, поэтому в объекте класса хранится ссылка на создателя.

Окно класса PaletteWindow всегда располагается поверх других. Окно класса ZconDockWindow (контейнер пиктограмм) хранит окна класса IconWindow и располагает их в ряд.

 

Операции класса Window определены в терминах интерфейса Windowlmp.

Например, DrawRect вычисляет координаты по двум своим параметрам Point перед тем, как вызвать операцию Windowlmp, которая рисует в окне прямоугольник:

 

 

void Window:: DrawRect (const Point& pi, const Point& p2) {

Windowlmp* imp = GetWindowImp ();

imp-> DeviceRect(pl.X(), pl.Y(), p2.X(), p2.Y());

}

 

 

Конкретные подклассы Windowlmp поддерживают разные оконные системы. Так, класс XWindowImp ориентирован на систему X Window:

 

 

class XWindowImp: public Windowlmp {

public:

XWindowImp();

virtual void DeviceRect(Coord, Coord, Coord, Coord);

 

// прочие операции открытого интерфейса...

private:

 

// переменные, описывающие специфичное для X Window состояние,

// в том числе:

Display* _dpy;

Drawable _winid; // идентификатор окна

GC _gc; // графический контекст окна

};

 

 

Для Presentation Manager (РМ) мы определяем класс PMWindowImp:

 

 

class PMWindowImp: public Windowlmp {

public:

PMWindowImp ();

virtual void DeviceRect(Coord, Coord, Coord, Coord);

// прочие операции открытого интерфейса...

private:

// переменные, описывающие специфичное для РМ Window состояние,

// в том числе:

HPS _hps;

};

 

 

Эти подклассы реализуют операции Windowlmp в терминах примитивов оконной системы. Например, DeviceRect для X Window реализуется так:

 

 

void XWindowImp:: DeviceRect (

Coord x0, Coord y0, Coord xl, Coord yl)

{

int x = round(min(x0, x l));

int у = rpund(min(y0, yl));

int w = round(abs(x0 - x l));

int h = round(abs(y0 - y l));

XDrawRectangle(_dpy, _winid, _gc, x, y, w, h);

}

 

 

А для РМ - так:

 

 

void PMWindowImp:: DeviceRect (Coord x0, Coord y0, Coord xl, Coord yl)

{

Coord left = min(x0, xl);

Coord right = max(x0, xl);

Coord bottom = min(y0, yl);

Coord top = max(y0, yl);

PPOINTL point[4];

 

point[0].x = left; point[0].у = top;

point[1].x = right; point[1].у = top;

point[2].x = right; point[2].у = bottom;

point[3].x = left; point[3].у = bottom;

if (

(GpiBeginPath(_hps, 1L) = = false) ||

(GpiSetCurrentPosition(_hps, & point[3]) = = false) ||

(GpiPolyLine(_hps, 4L, point) == GPI_ERROR) ||

(GpiEndPath(_hps) == false))

{

// сообщить об ошибке

}

else

{

GpiStrokePath(_hps, 1L, 0L);

}

}

 

 

 

Как окно получает экземпляр нужного подкласса Windowlmp? В данном примере мы предположим, что за это отвечает класс Window. Его операция GetWindowImp получает подходящий экземпляр от абстрактной фабрики, которая инкапсулирует все зависимости от оконной системы.

 

 

Windowlmp* Window:: GetWindowImp () {

if (_imp == 0)

{

_imp = WindowSystemFactory:: Instance() -> MakeWindowImp();

}

return _imp;

 

 

WindowSystemFactory:: Instance () возвращает абстрактную фабрику, которая изготавливает все системно-зависимые объекты. Для простоты мы сделали эту фабрику одиночкой и позволили классу Window обращаться к ней напрямую.

 


 






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.