Использование паттерна Decorator
От: ain Россия  
Дата: 04.10.02 10:31
Оценка:
Здравствуйте, подскажите пожалуйста:
есть графический объект, при попадании в него мышью, объект должен выделяться. Следует ли в этом случае использовать паттерн Decorator?
если нет то кто должен отвечать за рисование рамки, сам объект?
надо ли к классу добавлять переменную, определяющию выделен класс или нет?
Спасибо.
... << Янус 1.0 alpha 10 >>
Re: Использование паттерна Decorator
От: ain Россия  
Дата: 04.10.02 10:42
Оценка:
Здравствуйте ain, Вы писали:

еще вопрос:
каким образом в CAD системах осуществляется перерисовка окна, надо ведь перерисовывать только те объекты которые попадают в недействительный регион?
добавление объекту свойства — надо перерисовываться или нет?
... << Янус 1.0 alpha 10 >>
Re: Использование паттерна Decorator
От: Anatolix Россия https://www.linkedin.com/in/anatolix/
Дата: 04.10.02 10:47
Оценка:
Здравствуйте ain, Вы писали:

ain>Здравствуйте, подскажите пожалуйста:

ain>есть графический объект, при попадании в него мышью, объект должен выделяться. Следует ли в этом случае использовать паттерн Decorator?
ain>если нет то кто должен отвечать за рисование рамки, сам объект?
ain>надо ли к классу добавлять переменную, определяющию выделен класс или нет?
ain>Спасибо.

Смотря в какой ситуации ты это делаешь. Если умение выделяться это не неотъемлимая часть объекта то скорее всего надо.

Хотя здесь больше все зависит от архитектуры а не от идеологии.

Я вот например писал редактор форм для дельфи без декоратора, потому как там его было сложно вписать в архитектуру.
Любая проблема дизайна может быть решена введением дополнительного абстрактного слоя, за исключением проблемы слишком большого количества дополнительных абстрактных слоев
Re[2]: Использование паттерна Decorator
От: Anatolix Россия https://www.linkedin.com/in/anatolix/
Дата: 04.10.02 10:49
Оценка:
Здравствуйте ain, Вы писали:

ain>Здравствуйте ain, Вы писали:


ain>еще вопрос:

ain>каким образом в CAD системах осуществляется перерисовка окна, надо ведь перерисовывать только те объекты которые попадают в недействительный регион?

Тебе же в любом случае придется уметь отрисовывать регион, например у тебя есть большая диаграма, и из нее на экран попадает только треть. Не будешь же ты всею ее за экраном отрисовывать.
Любая проблема дизайна может быть решена введением дополнительного абстрактного слоя, за исключением проблемы слишком большого количества дополнительных абстрактных слоев
Re[2]: Использование паттерна Decorator
От: ain Россия  
Дата: 04.10.02 11:00
Оценка:
Здравствуйте Anatolix, Вы писали:

Подскажите пожалуйста, где можно посмотреть основные идеи используемые при создании графических редакторов (2d, векторные), очень не хочется изобретать велосепед.

Вообще почти все графические объекты должны рисовать рамку при выделении, получается что необходимо в базовый класс добавить соответствующию функцию.
... << Янус 1.0 alpha 10 >>
Re: Использование паттерна Decorator
От: Igor Trofimov  
Дата: 04.10.02 12:27
Оценка:
Вообще зависит от того, что у тебя за объекты и как они организованы, как могут выглядеть и т.п.

Декоратор полезен, если для твоих родных объектов — иерархия — типичная вещь.

Я бы предложил сделать так — чтобы каждый класс, который отрисовывает тот или иной элемент — умел создавать объект-МАНИПУЛЯТОР, подходящий для себя.

Манипулятор умеет рисовать рамку нужной формы или другие какие-то вещи (drag points) и реагировать на таскания мышкой — транслировать их целевому объекту.
Re[2]: Использование паттерна Decorator
От: ain Россия  
Дата: 04.10.02 12:45
Оценка:
Здравствуйте Igor Trofimov, Вы писали:

Насколько я понимаю должно быть две иерархии, графические объекты и манипуляторы.
не совсем ясно, как манипулятор должен взаимодействовать с графическим объектом?
манипулятор получает указатель на графический объект при инстанцировании?
class CManipulator
{
public:
    CManipulator(CFigure*);

    virtual void MouseDown();
    virtual void MouseUp();
    ...
};

class CRectangleManipulator : public CManipulator
{
public:
    CRectangleManipulator(CFigure* pFigure) : CManipulator(pFigure) {}
};

class CRectangle : CFigure
{
public:
    CManipulator* GetManipulator()
    {
        return (new CRectangleManipulator(this));
    }    
}


получается манипулятор изменяет состояние графического объекта, если я правильно понял.

IT>Вообще зависит от того, что у тебя за объекты и как они организованы, как могут выглядеть и т.п.


IT>Декоратор полезен, если для твоих родных объектов — иерархия — типичная вещь.


IT>Я бы предложил сделать так — чтобы каждый класс, который отрисовывает тот или иной элемент — умел создавать объект-МАНИПУЛЯТОР, подходящий для себя.


IT>Манипулятор умеет рисовать рамку нужной формы или другие какие-то вещи (drag points) и реагировать на таскания мышкой — транслировать их целевому объекту.
... << Янус 1.0 alpha 10 >>
Re[3]: Использование паттерна Decorator
От: Igor Trofimov  
Дата: 04.10.02 14:39
Оценка:
ain>Насколько я понимаю должно быть две иерархии, графические объекты и манипуляторы.

Да, при этом классов манипуляторов может быть существенно меньше — например, для многих подойдет манипулятор Rectangle, а для кого-то потребуется совсем-совсем специальный.

Поясню — я это не реализовывал таким образом, но размышляя недавно на эту тему, подумал, что так будет правильно...

ain>получается манипулятор изменяет состояние графического объекта, если я правильно понял.


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

Мне кажется, что эту достаточно хитрую логику лучше отделить от логики рисования схемы.
Re[3]: Использование паттерна Decorator
От: ain Россия  
Дата: 05.10.02 10:17
Оценка:
Здравствуйте Anatolix, Вы писали:

Интересно каким образом определять какие объекты надо перерисовывать, создавать отдельный список объектов попавших в недействительный регион или в каждый объект добавить свойство определяющие надо его перерисовывать или нет, мне кажется лучше первое ?


A>Здравствуйте ain, Вы писали:


ain>>Здравствуйте ain, Вы писали:


ain>>еще вопрос:

ain>>каким образом в CAD системах осуществляется перерисовка окна, надо ведь перерисовывать только те объекты которые попадают в недействительный регион?

A>Тебе же в любом случае придется уметь отрисовывать регион, например у тебя есть большая диаграма, и из нее на экран попадает только треть. Не будешь же ты всею ее за экраном отрисовывать.


A>
Re[4]: Использование паттерна Decorator
От: Anatolix Россия https://www.linkedin.com/in/anatolix/
Дата: 07.10.02 05:57
Оценка:
Здравствуйте ain, Вы писали:

ain>Здравствуйте Anatolix, Вы писали:


ain>Интересно каким образом определять какие объекты надо перерисовывать, создавать отдельный список объектов попавших в недействительный регион или в каждый объект добавить свойство определяющие надо его перерисовывать или нет, мне кажется лучше первое ?


Обычно просто держат список объектов отсортированый по координатам. И чтобы проверять попадание надо только по какой-то его части пробежаться.
Любая проблема дизайна может быть решена введением дополнительного абстрактного слоя, за исключением проблемы слишком большого количества дополнительных абстрактных слоев
Re[5]: Использование паттерна Decorator
От: Anatolix Россия https://www.linkedin.com/in/anatolix/
Дата: 07.10.02 05:58
Оценка:
Здравствуйте Anatolix, Вы писали:

A>Обычно просто держат список объектов отсортированый по координатам. И чтобы проверять попадание надо только по какой-то его части пробежаться.


Удобнее держать даже не сами объекты а обрамляющие их квадраты/прямоугольники. Если никакая часть квадрата(в котором лежит сложный объект) не должна быть отрисована то очевидно что и сам объект не попадает в область отрисовки.
Любая проблема дизайна может быть решена введением дополнительного абстрактного слоя, за исключением проблемы слишком большого количества дополнительных абстрактных слоев
Re[4]: Использование паттерна Decorator
От: Anton V. Kolotaev  
Дата: 07.10.02 07:48
Оценка:
Здравствуйте ain, Вы писали:

ain>Интересно каким образом определять какие объекты надо перерисовывать, создавать отдельный список объектов попавших в недействительный регион или в каждый объект добавить свойство определяющие надо его перерисовывать или нет, мне кажется лучше первое ?


Вроде бы все так просто.
Предположим, перетаскивается фигура. Чтобы отобразить изменение, достаточно перерисовать объединение ее старого и нового региона. Т.е. элементарно посылаются ::InvalidateRect/::InvalidateRgn. К тебе приходят сообщения WM_PAINT с HDC на проставленным clipping-region. Заморачиваться с обсчетом пересечения этого региона с твоими фигурами не стоит — как показывает практика, GDI делает это даже быстрее.

Или я не правильно понял вопрос???

При использовании другого графического API, я не думаю, что такая модель там не будет поддерживаться.

Интересный момент появляется, когда удобно не инвалидировать некоторую область, а руками рисовать прямо на dc. Причем отрисовка должна происходить порциями. Заводится некоторый класс Updator, у которого два рода клиентов: рисующие агенты (они оставляют заявки на перерисовку) и представитель GDI (к которому идут запросы на инвалидацию).
Паттерн Команда здесь идеально подходит
    struct IUpdateCommand
    {
        virtual void Apply    (canvas&) const  = 0;
        virtual     ~IUpdateCommand () {}
    };

    struct IUpdator
    {
        virtual void Apply   (IUpdateCommand*) = 0;
    };
    struct UpdatorEvents
    {
        virtual void NeedDrawOver ()     = 0;
    };

    class Updator 
        :  public IUpdator
    {
    public:
        Updator (UpdatorEvents*);

        void Apply   (IUpdateCommand*);

        void DrawOver (canvas &);

        ~Updator ();
    private:
        UpdatorEvents         *_sink;
        typedef std::vector<IUpdateCommand*>    Queue;
        typedef Queue::const_iterator           QCI;
        typedef Queue::iterator                 QI;
        Queue           _queue;
        void            _purge ();
    };
    Updator::Updator (UpdatorEvents *ev) 
        :   _sink (ev)
    {
    }

    void Updator::Apply (IUpdateCommand *cmd)
    {
        _queue.push_back (cmd);
        _sink->NeedDrawOver ();
    }


    void Updator::DrawOver (canvas & c) 
    {
        for (QCI it = _queue.begin (); it != _queue.end (); it++)
            (*it)->Apply (c);
        _purge ();
    }

    void Updator::_purge ()
    {
        for (QI it = _queue.begin (); it != _queue.end (); it++)
            delete *it;
        _queue.clear ();
    }

    Updator::~Updator ()
    {
        _purge ();
    }


Я думаю, предназначение этого куска кода очевидно.
Re[5]: Использование паттерна Decorator
От: ain Россия  
Дата: 07.10.02 13:06
Оценка:
Здравствуйте Anton V. Kolotaev, Вы писали:

AVK>Вроде бы все так просто.

AVK>Предположим, перетаскивается фигура. Чтобы отобразить изменение, достаточно перерисовать объединение ее старого и нового региона. Т.е. элементарно посылаются ::InvalidateRect/::InvalidateRgn. К тебе приходят сообщения WM_PAINT с HDC на проставленным clipping-region. Заморачиваться с обсчетом пересечения этого региона с твоими фигурами не стоит — как показывает практика, GDI делает это даже быстрее.

При перетаскивании фигуры каким образом надо уведомлять окно что требуется перерисовать регион.
Получается графический объект должен в себе содержать указатель на окно в котором он должен перерисоваться. Я видел пример где в конструкторе передавался указатель на документ, и затем вызывалось InvalidateRect с нужным rect. Правильно ли так делать?
Спасибо.
... << Янус 1.0 alpha 10 >>
Re[6]: Использование паттерна Decorator
От: Anton V. Kolotaev  
Дата: 07.10.02 13:25
Оценка: 6 (1)
Здравствуйте ain, Вы писали:

ain>При перетаскивании фигуры каким образом надо уведомлять окно что требуется перерисовать регион.

ain>Получается графический объект должен в себе содержать указатель на окно в котором он должен перерисоваться. Я видел пример где в конструкторе передавался указатель на документ, и затем вызывалось InvalidateRect с нужным rect. Правильно ли так делать?
ain>Спасибо.

Элементарная схема, которую я использовал, заключалась в следующем:
1) фигура является пассивным объектом. Под этим подразумевается, что она хранит описывающие ее данные, стараясь как можно реже из изменять. Например, у меня класс Polyline конструировался с уже созданным массивом точек (в сессии) и пером. Он умел себя рисовать на канве, позволял устраивать преобразования координат (сдвиг, растяжение-сжатие), сообщал свои границы и умел записывать себя в поток (на самом деле использовался паттерн Visitor). НО!!! Число точек в массиве не изменялось!!! Также не менялось их взимное расположение.
2) рисунок содержит массив фигур.
3) редактор содержит рисунок и одну или ноль сессий.
4) Сессия — это объект, представляющий процесс создания фигуры. Именно в нем реализуются операции типа mouse_move, которые формируют фигуру и соотв. образ оставляют Updator'у запрос на обновление. В редакторе по mouse_down создается такой объект, ему дается Updator. Затем mouse_move транслируются сессии. По отпускании мыши сессия уничтожается, причем в своем деструкторе она создает объект фигуры и пихает в рисунок.

Редактор связан с Updator, а он знает, как обновлять экран. И ничего в этом страшного нет.

Если интересно, могу замылить свой диплом, где я как раз этим и занимался.
Re[7]: Использование паттерна Decorator
От: ain Россия  
Дата: 07.10.02 13:28
Оценка:
Здравствуйте Anton V. Kolotaev, Вы писали:

AVK>Если интересно, могу замылить свой диплом, где я как раз этим и занимался.


Да конечно, очень интересно посмотреть, большое спасибо.
... << Янус 1.0 alpha 10 >>
Re[7]: Использование паттерна Decorator
От: ain Россия  
Дата: 07.10.02 13:35
Оценка:
Здравствуйте Anton V. Kolotaev, Вы писали:

Сам объект отвечает за свои преобразования?
я читал что можно создавать объект манипулятор, который занимается различными преобразованиями объекта, и хранит промежуточные данные( нужные лишь на время преобразования). Шаблон Factory Method.
Нужно ли реализовывать подобную схему, или особого выигрыша(удобство разработки) это не дает?
Спасибо.
... << Янус 1.0 alpha 10 >>
Re[8]: Использование паттерна Decorator
От: Anton V. Kolotaev  
Дата: 07.10.02 13:35
Оценка:
Здравствуйте ain, Вы писали:

ain>Да конечно, очень интересно посмотреть, большое спасибо.


ушло на ain@list.ru
Re[8]: Использование паттерна Decorator
От: Anton V. Kolotaev  
Дата: 07.10.02 13:38
Оценка:
Здравствуйте ain, Вы писали:

ain>Здравствуйте Anton V. Kolotaev, Вы писали:


ain>Сам объект отвечает за свои преобразования?

ain>я читал что можно создавать объект манипулятор, который занимается различными преобразованиями объекта, и хранит промежуточные данные( нужные лишь на время преобразования). Шаблон Factory Method.
ain>Нужно ли реализовывать подобную схему, или особого выигрыша(удобство разработки) это не дает?
ain>Спасибо.

Как уже было сказано, у фигуры есть методы Zoom и Shift. У манипулятора есть down_click, mouse_move и т.д. Оттуда он вызывает методы связанной с ним фигуры.
Re[5]: Использование паттерна Decorator
От: Anatolix Россия https://www.linkedin.com/in/anatolix/
Дата: 08.10.02 05:30
Оценка:
Здравствуйте Anton V. Kolotaev, Вы писали:

AVK>Здравствуйте ain, Вы писали:


ain>>Интересно каким образом определять какие объекты надо перерисовывать, создавать отдельный список объектов попавших в недействительный регион или в каждый объект добавить свойство определяющие надо его перерисовывать или нет, мне кажется лучше первое ?


AVK>Вроде бы все так просто.

AVK>К тебе приходят сообщения WM_PAINT с HDC на проставленным clipping-region. Заморачиваться с обсчетом пересечения этого региона с твоими фигурами не стоит — как показывает практика, GDI делает это даже быстрее.

AVK>Или я не правильно понял вопрос???


Так просто будет если у тебя объектов меньше сотни. В противном случае нужна будет более агрессивная оптимизация
Любая проблема дизайна может быть решена введением дополнительного абстрактного слоя, за исключением проблемы слишком большого количества дополнительных абстрактных слоев
Re[7]: Использование паттерна Decorator
От: maximka_z Беларусь  
Дата: 04.12.03 07:18
Оценка:
Здравствуйте, Anton V. Kolotaev, Вы писали:


AVK>Если интересно, могу замылить свой диплом, где я как раз этим и занимался.


Если не трудно, замыльте пожалуйста на . Столкнулся
с написанием графической библиотеки, поэтому любые идеи пригодятся.

Заранее благодарен.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.