root/src/apps/icon-o-matic/transformable/TransformBox.h
/*
 * Copyright 2006-2007, Haiku.
 * Distributed under the terms of the MIT License.
 *
 * Authors:
 *              Stephan Aßmus <superstippi@gmx.de>
 */
#ifndef TRANSFORM_BOX_H
#define TRANSFORM_BOX_H

#include <List.h>

#include "ChannelTransform.h"
#include "Manipulator.h"


namespace TransformBoxStates {
        class DragState;
}

class Command;
class StateView;
class TransformBox;
class TransformCommand;


class TransformBoxListener {
public:
                                                                TransformBoxListener() {}
        virtual                                         ~TransformBoxListener() {}

        virtual void                            TransformBoxDeleted(
                                                                        const TransformBox* box) = 0;
};

class TransformBox : public ChannelTransform,
                                         public Manipulator {
public:
                                                                TransformBox(StateView* view, BRect box);
        virtual                                         ~TransformBox();

        // Manipulator interface
        virtual void                            Draw(BView* into, BRect updateRect);

        virtual bool                            MouseDown(BPoint where);
        virtual void                            MouseMoved(BPoint where);
        virtual Command*                        MouseUp();
        virtual bool                            MouseOver(BPoint where);
        virtual bool                            DoubleClicked(BPoint where);

        virtual BRect                           Bounds();
        virtual BRect                           TrackingBounds(BView* withinView);

        virtual void                            ModifiersChanged(uint32 modifiers);
        virtual bool                            HandleKeyDown(uint32 key,
                                                                        uint32 modifiers, Command** _command);
        virtual bool                            HandleKeyUp(uint32 key,
                                                                        uint32 modifiers, Command** _command);

        virtual bool                            UpdateCursor();

        virtual void                            AttachedToView(BView* view);
        virtual void                            DetachedFromView(BView* view);

        // TransformBox
        virtual void                            Update(bool deep = true);

                        void                            OffsetCenter(BPoint offset);
                        BPoint                          Center() const;
                        void                            SetBox(BRect box);
                        BRect                           Box() const
                                                                        { return fOriginalBox; }

                        Command*                        FinishTransaction();

                        void                            NudgeBy(BPoint offset);
                        bool                            IsNudging() const
                                                                        { return fNudging; }
                        Command*                        FinishNudging();

        virtual void                            TransformFromCanvas(BPoint& point) const;
        virtual void                            TransformToCanvas(BPoint& point) const;
        virtual float                           ZoomLevel() const;


        virtual TransformCommand*       MakeCommand(const char* actionName) = 0;

                        bool                            IsRotating() const
                                                                        { return fCurrentState == fRotateState; }
        virtual double                          ViewSpaceRotation() const;

        // Listener support
                        bool                            AddListener(TransformBoxListener* listener);
                        bool                            RemoveListener(TransformBoxListener* listener);

private:
                        TransformBoxStates::DragState* _DragStateFor(
                                                                        BPoint canvasWhere, float canvasZoom);
                        void                            _StrokeBWLine(BView* into,
                                                                        BPoint from, BPoint to) const;
                        void                            _StrokeBWPoint(BView* into,
                                                                        BPoint point, double angle) const;

private:
                        BRect                           fOriginalBox;

                        BPoint                          fLeftTop;
                        BPoint                          fRightTop;
                        BPoint                          fLeftBottom;
                        BPoint                          fRightBottom;

                        BPoint                          fPivot;
                        BPoint                          fPivotOffset;

                        TransformCommand*       fCurrentCommand;
                        TransformBoxStates::DragState* fCurrentState;

                        bool                            fDragging;
                        BPoint                          fMousePos;
                        uint32                          fModifiers;

                        bool                            fNudging;

                        BList                           fListeners;

protected:
                        void                            _NotifyDeleted() const;

                        // "static" state objects
                        StateView*                      fView;

                        TransformBoxStates::DragState* fDragLTState;
                        TransformBoxStates::DragState* fDragRTState;
                        TransformBoxStates::DragState* fDragLBState;
                        TransformBoxStates::DragState* fDragRBState;

                        TransformBoxStates::DragState* fDragLState;
                        TransformBoxStates::DragState* fDragRState;
                        TransformBoxStates::DragState* fDragTState;
                        TransformBoxStates::DragState* fDragBState;

                        TransformBoxStates::DragState* fRotateState;
                        TransformBoxStates::DragState* fTranslateState;
                        TransformBoxStates::DragState* fOffsetCenterState;
};

#endif // TRANSFORM_BOX_H