Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

Листинг 1. Команда трансляции программы

Курсовая работа

по дисциплине
«Объектно-ориентированное проектирование»

Работу выполнил студент группы М-72         И. С. Лепихин
    подпись, дата    
         
Работу проверил       С. А. Булгаков
    подпись, дата    

Постановка задачи

Используя предоставленную документацию реализовать класс Object. Создать двух наследников класс Rect и класс Text. Класс Rect представляет собой прямоугольник. Класс Text представляет собой строку текста. Классы Rect и Text можно отрисовать в окне.

Необходимо создать окно и отрисовать в нем прямоугольник и текст. Прямоугольник должен иметь высоту окна и 1/3 его ширины. Текст должен располагаться по центру окна. При изменении размеров окна должны изменяться размеры прямоугольника и положение текста. Размер текста всегда остается неизменным.


1 Алгоритм решения задачи

Для решения задачи был использован паттерн «Компоновщик» и разработаны следующие классы:

¾ Object – класс, который реализует вырожденный случай паттерна «Компоновщик». Он выступает в качестве Component, Leaf и Composite;

¾ XWindow – класс, реализующий функциональность окна в оконной системе X Window System;

¾ Text – класс, реализующий хранение и рисование текста посередине экрана;

¾ Rect – класс, реализующий рисование прямоугольника необходимого размера и положения;

2 Решение задачи

2.1 Класс Object

Выступая в роли участника Component, этот класс реализует следующие методы:

· Operation () – findChild () – в результате вызова метод возвращает 0;

· Operation () – draw () – ничего не делает;

· Add () – setParent ();

· Remove () – SetParent ();

· GetChild () – findChild () – в результате вызова метод возвращает 0;

Функция setParent () устанавливает родителя объекта и добавляет объект в список дочерних объектов родителя. Если у объекта уже есть родитель, то вначале объект удаляется из списка дочерних объектов старого родителя. Чтобы указать, что у объекта нет родителя, параметром метода надо передать NULL. Таким образом, этот метод реализует функционал методов Add () и Remove ().

2.2 Классы Text и Rect

Эти классы выступают в роли Leaf, наследуют от Component и определяют следующие методы:

· Operation () – findChild () –проверяет переданное имя со своим собственным;

· Operation () – draw () – выполняет собственную отрисовку на экране;

Класс Text рисует хранящийся в нем текст посередине окна.

Класс Rect рисует треугольник, находящийся у левого края окна, шириной в треть ширины окна и высотой равной высоте окна.

2.3 Класс XWindow

Этот класс выступает в роли участника Composite, наследует от Component и определяет следующие методы:

· Operation () – findChild () – проверяет имена всех дочерних объектов;

· Operation () – draw () – рисует себя на экране, затем вызывает метод draw () у всех дочерних объектов:

· GetChild () – findChild () – в качестве основного метода использует метод findChild (), он же позволяет индексировать дочерние объекты;

· void Open () – создает и выводит на экран окно приложения;

· void Close () – закрывает окно;

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

3 Структура программного кода

Текст программы расположен в следующих файлах:

· object.h и object.cpp – определение и реализация класса Object;

· text.h и text.cpp – определение и реализация класса Text;

· rect.h и rect.cpp – определение и реализация класса Rect;

· window.h и window.cpp – определение и реализация класса XWindow;

· main.cpp – главная функция main;

4 Трансляция программы

Трансляция программы осуществляется из директории, в которой находятся файлы с исходным кодом. Команда для трансляции приведена в листинге 1.

 

Листинг 1. Команда трансляции программы

fox@lepihin:~/Documents/workspace/project740$ g++ -o win main.cpp window.cpp object.cpp rect.cpp text.cpp -lX11

5 Тестирование

Для тестирования программы запустим ее и попробуем изменить размер окна. На рисунке 1 приведено изображения окна до изменения его размера, на рисунке 2 – после.

.

Рисунок 1 - Окно до изменения его размера

 

Рисунок 2 – Окно после изменения его размера

 

Приложение А

Полный текст программ с комментариями.

Листинг 1. Файл object.h

#ifndef OBJECT_H

#define OBJECT_H

 

#include <list>

#include <string>

 

namespace ikita

{

 

class Object

{

Object * _parent;

std::list<Object *> _children;

std::string _name;

public:

Object (Object * parent = NULL);

virtual ~Object () = 0;

 

Object * parent () const;

void setParent (Object *);

const std::list<Object *> & children () const;

Object * findChild (const std::string & name);

std::string objectName () const;

void setObjectName (const std::string & name);

 

virtual void draw ();

};

}

 

#endif // OBJECT_H

 

Листинг 2. Файл object.cpp

#include "object.h"

 

using namespace std;

 

namespace ikita

{

 

Object::Object (Object * _parent):

_parent (_parent)

{

}

 

Object::~Object ()

{

}

 

Object * Object::parent () const

{

return _parent;

}

 

void Object::setParent (Object * _p)

{

// если есть родитель, то удалится из списка его детей

if (_parent!= NULL)

{

_parent->_children.remove (this);

}

// если в качестве нового родителя передан не нулевой указатель, то

// добавить себя в список его детей

if (_p!= NULL)

{

_p->_children.push_back (this);

}

_parent = _p;

}

 

const std::list<Object *> & Object::children () const

{

// вернуть список дочерних объектов

return _children;

}

 

Object * Object::findChild (const std::string &)

{

// вернуть нулевой указатель

return NULL;

}

 

string Object::objectName () const

{

// вернуть имя объекта

return _name;

}

 

void Object::setObjectName (const string & name)

{

// установить новое имя объекта

_name = name;

}

 

void Object::draw ()

{

// ничего не делать

}

}

 

Листинг 3. Файл window.h

#ifndef WINDOW_H

#define WINDOW_H

 

#include <X11/Xlib.h>

 

#include "object.h"

 

namespace ikita

{

class XWindow: public Object

{

Display * display;

Window window;

GC gr_context;

int width;

int height;

public:

XWindow ();

 

void Open ();

void Close ();

 

Display * getDisplay ()

{

return display;

}

 

Window getWindow () const

{

return window;

}

 

int getHeight () const

{

return height;

}

 

int getWidth () const

{

return width;

}

 

GC getGContext () const

{

return gr_context;

}

 

virtual void draw ();

};

} /* namespace ikita */

 

#endif

 

Листинг 4. Файл window.cpp

#include "window.h"

 

#include <iostream>

 

using namespace std;

 

namespace ikita

{

XWindow::XWindow ():

display (NULL)

{

}

 

void XWindow::Open()

{

// проверить, окно не создано

if (display!= NULL)

{

return;

}

// установить ширину и высоту окна по-умолчанию

width = 800;

height = 600;

// установить позицию окна и ширину бордюра по-умолчанию

unsigned

winX = 0,

winY = 0,

winBorderWidth = 0;

// присоединится к дисплею

display = XOpenDisplay(NULL);

if (display == NULL)

{

cerr << "Cannot connect to X server\n";

return;

}

// получить номер экрана по-умолчанию

const int screen_num = DefaultScreen(display);

// создать простое окно

window = XCreateSimpleWindow(

display,

RootWindow(display, screen_num),

winX, winY,

width, height,

winBorderWidth,

BlackPixel(display, screen_num),

WhitePixel(display, screen_num));

// задать имя окна

XStoreName(display, window, "Example");

// вывести окно на экран

XMapWindow(display, window);

// настроить параметры отрисовки примитивов

XGCValues gr_values;

gr_values.line_width = 1;

gr_values.line_style = LineSolid;

// получить графический контекст для рисования

gr_context = XCreateGC(display, window, GCLineWidth | GCLineStyle, &gr_values);

// установить список ожидаемых типов сообщений

XSelectInput(display, window, ExposureMask | StructureNotifyMask);

// синхронизировать дисплей

XFlush(display);

// объект структуры для приходящих сообщений

XEvent event;

// добавить в список принимаемых типов сообщений

// сообщение о нажатие на кнопку закрытия окна

Atom wmDelete = XInternAtom(display, "WM_DELETE_WINDOW", True);

XSetWMProtocols(display, window, &wmDelete, 1);

bool repeat = true;

// выполнить отрисовку содержимого окна

draw ();

while (repeat)

{

// получить следующее сообщение

XNextEvent(display, &event);

switch (event.type)

{

case Expose:

// сообщение о том, что содержимое окна надо перерисовать

draw ();

break;

case ConfigureNotify:

{

// сообщение об изменение геометрии окна

XConfigureEvent xce = event.xconfigure;

// установить новые размеры окна

width = xce.width;

height = xce.height;

break;

}

case ClientMessage:

// получено клиентское сообщение, на которое мы ранее подписались

// прекратить цикл

repeat = false;

break;

}

}

}

 

void XWindow::Close ()

{

// проверить, что окно открыто

if (display == NULL)

{

return;

}

// удалить окно

XDestroyWindow(display, window);

// синхронизовать дисплей

XFlush(display);

// отсоединится от дисплея

XCloseDisplay(display);

// указатель на дисплей приравнять к нулевому указателю

display = NULL;

}

 

void XWindow::draw()

{

// очистить окно

XClearWindow (display, window);

// отрисовать все дочерние объекты

for (list<Object *>::const_iterator it = children ().begin (); it!= children ().end (); ++it)

{

(*it)->draw ();

}

}

}

 

Листинг 5. Файл rect.h

#ifndef RECT_H

#define RECT_H

 

#include "object.h"

 

#include <string>

 

namespace ikita

{

 

class XWindow;

 

class Rect: public Object

{

XWindow * win;

public:

Rect (XWindow * _win);

virtual ~Rect () {}

 

virtual Object * findChild (const std::string & name);

virtual void draw ();

};

 

}

 

#endif // RECT_H

 

Листинг 6. Файл rect.cpp

#include "rect.h"

 

#include "window.h"

#include <X11/Xlib.h>

 

namespace ikita

{

 

Rect::Rect (XWindow * _win):

win (_win)

{

// установить имя объекта

setObjectName ("rectangle");

}

 

Object * Rect::findChild (const std::string & name)

{

// сравнить переданное имя со своим и в случае совпадения

// вернуть указатель на себя, иначе вернуть нулевой указатель

if (Object::objectName () == name)

{

return this;

}

else

{

return NULL;

}

}

 

void Rect::draw ()

{

// нарисовать прямоугольник вдоль левого края окна

// с шириной равно трети ширины окна

// и высотой равно высоте окна

XDrawRectangle (win->getDisplay (), win->getWindow (), win->getGContext (), 0, 0, win->getWidth () / 3, win->getHeight ());

}

}

 

Листинг 7. Файл text.h

#ifndef TEXT_H

#define TEXT_H

 

#include "object.h"

 

namespace ikita

{

 

class XWindow;

 

class Text: public Object

{

XWindow * win;

std::string str;

public:

Text (XWindow * _win, std::string _str);

virtual ~Text () {}

 

virtual Object * findChild (const std::string & name);

virtual void draw ();

};

 

}

 

#endif // TEXT_H

 

Листинг 8. Файл text.cpp

#include "text.h"

#include "window.h"

 

namespace ikita

{

 

Text::Text (XWindow * _win, std::string _str):

win (_win),

str (_str)

{

setObjectName ("text");

}

 

Object * Text::findChild (const std::string & name)

{

// сравнить переданное имя со своим и в случае совпадения

// вернуть указатель на себя, иначе вернуть нулевой указатель

if (Object::objectName () == name)

{

return this;

}

else

{

return NULL;

}

}

 

void Text::draw ()

{

// получить графический контекст для отрисовки примитивов

GContext gc_id = XGContextFromGC (win->getGContext ());

// получить шрифт для отрисовки текста

XFontStruct * font = XQueryFont (win->getDisplay (), gc_id);

// расчитать ширину текста в пикселях

int text_width = XTextWidth (font, str.c_str (), str.size ());

// отрисовать текст по середине окна

XDrawString(win->getDisplay (), win->getWindow (), win->getGContext (), (win->getWidth () - text_width) / 2, win->getHeight () / 2, str.c_str (), str.size ());

}

}

 

Листинг 9. Файл main.cpp

#include "window.h"

#include "rect.h"

#include "text.h"

 

int main()

{

// создать окно

ikita::XWindow win;

// создать прямоугольник

ikita::Rect rect (&win);

// создать объект класса Text

ikita::Text text (&win, "hello world");

// установить родителей

rect.setParent (&win);

text.setParent (&win);

// открыть окно

win.Open ();

// закрыть окно

win.Close ();

}

 

 

Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...