You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
607 lines
17 KiB
607 lines
17 KiB
/***************************************************************************
|
|
* Copyright (C) 2004-2005 by David Saxton *
|
|
* david@bluehaze.org *
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
***************************************************************************/
|
|
|
|
#ifndef CANVAsmANIPULATOR_H
|
|
#define CANVAsmANIPULATOR_H
|
|
|
|
#include "eventinfo.h"
|
|
|
|
#include <tqcanvas.h>
|
|
#include <tqguardedptr.h>
|
|
|
|
class CanvasManipulator;
|
|
class Connector;
|
|
class CMManager;
|
|
class CNItem;
|
|
class CNItemGroup;
|
|
class EventInfo;
|
|
class FlowContainer;
|
|
class ICNDocument;
|
|
class Item;
|
|
class ItemDocument;
|
|
class ItemGroup;
|
|
class ItemView;
|
|
class ManipulatorInfo;
|
|
class ManualConnectorDraw;
|
|
class MechanicsItem;
|
|
class MechanicsGroup;
|
|
class MechanicsDocument;
|
|
class Node;
|
|
class NodeGroup;
|
|
class ResizeHandle;
|
|
|
|
class TQCanvas;
|
|
class TQCanvasItem;
|
|
class TQCanvasLine;
|
|
class TQCanvasRectangle;
|
|
class TQMouseEvent;
|
|
class TQTimer;
|
|
class TQWheelEvent;
|
|
|
|
typedef CanvasManipulator*(*CreateManipulatorPtr)( ItemDocument *, CMManager * );
|
|
typedef bool(*AcceptManipulationPtr)( uint eventState, uint cmState, uint itemType, uint cnItemType );
|
|
typedef TQValueList<NodeGroup*> NodeGroupList;
|
|
typedef TQValueList<TQGuardedPtr<Connector> > ConnectorList;
|
|
typedef TQValueList<TQPoint> TQPointList;
|
|
|
|
|
|
class ManipulatorInfo
|
|
{
|
|
public:
|
|
ManipulatorInfo();
|
|
AcceptManipulationPtr m_acceptManipulationPtr;
|
|
CreateManipulatorPtr m_createManipulatorPtr;
|
|
};
|
|
typedef TQValueList<ManipulatorInfo*> ManipulatorInfoList;
|
|
|
|
|
|
/**
|
|
Handles canvas manipulation, such as moving an item or resizing the canvas
|
|
@author David Saxton
|
|
*/
|
|
class CMManager : public TQObject
|
|
{
|
|
Q_OBJECT
|
|
|
|
public:
|
|
enum EventState
|
|
{
|
|
es_right_click = 1 << 0,
|
|
es_ctrl_pressed = 1 << 1
|
|
};
|
|
enum CMState
|
|
{
|
|
cms_repeated_add = 1 << 0,
|
|
cms_manual_route = 1 << 1,
|
|
cms_draw = 1 << 2
|
|
};
|
|
enum ItemType
|
|
{
|
|
it_none = 1 << 0,
|
|
it_node = 1 << 1,
|
|
it_connector = 1 << 2,
|
|
it_pin = 1 << 3,
|
|
it_canvas_item = 1 << 4,
|
|
it_mechanics_item = 1 << 5,
|
|
it_resize_handle = 1 << 6,
|
|
it_drawpart = 1 << 7
|
|
};
|
|
enum ItemStateInfo
|
|
{
|
|
isi_isMovable = 0x2,
|
|
};
|
|
CMManager( ItemDocument *itemDocument );
|
|
~CMManager();
|
|
/**
|
|
* Called when the user single-clicks the mouse
|
|
*/
|
|
void mousePressEvent( EventInfo eventInfo );
|
|
/**
|
|
* Called when the user releases the mouse
|
|
*/
|
|
void mouseReleaseEvent( const EventInfo &eventInfo );
|
|
/**
|
|
* Called when the user double clicks the mouse
|
|
*/
|
|
void mouseDoubleClickEvent( const EventInfo &eventInfo );
|
|
/**
|
|
* Called when the user moves the mouse
|
|
*/
|
|
void mouseMoveEvent( const EventInfo &eventInfo );
|
|
/**
|
|
* Called when the user scrolls the mouse
|
|
*/
|
|
void wheelEvent( const EventInfo &eventInfo );
|
|
/**
|
|
* Set a current CMState to true or false
|
|
*/
|
|
void setCMState( CMState type, bool state );
|
|
/**
|
|
* Cancels the current manipulation (if there is one)
|
|
*/
|
|
void cancelCurrentManipulation();
|
|
CanvasManipulator * currentManipulator() const { return m_canvasManipulator; }
|
|
void setRepeatedAddId( const TQString & repeatedId = TQString() );
|
|
uint cmState() const { return m_cmState; }
|
|
void addManipulatorInfo( ManipulatorInfo *info );
|
|
TQString repeatedItemId() const { return m_repeatedItemId; }
|
|
void setDrawAction( int drawAction );
|
|
int drawAction() const { return m_drawAction; }
|
|
|
|
public slots:
|
|
void slotSetManualRoute( bool manualRoute );
|
|
|
|
signals:
|
|
void manualRoutingChanged( bool manualRouting );
|
|
|
|
protected:
|
|
/**
|
|
* Called when the mouse is moved or released, with the ResizeHandle that
|
|
* the mouse is currently over (which can be null). Updates which handle is
|
|
* selected, etc.
|
|
*/
|
|
void updateCurrentResizeHandle( ResizeHandle * mouseOver );
|
|
CanvasManipulator *m_canvasManipulator;
|
|
uint m_cmState;
|
|
TQString m_repeatedItemId;
|
|
ItemDocument *p_itemDocument;
|
|
ManipulatorInfoList m_manipulatorInfoList;
|
|
TQGuardedPtr<Item> p_lastMouseOverItem; // Pointer to the item where the mouse was last over - this is used to determine when mouse
|
|
TQGuardedPtr<ResizeHandle> p_lastMouseOverResizeHandle;
|
|
TQGuardedPtr<Item> p_lastItemClicked;
|
|
TQTimer *m_allowItemScrollTmr; // When a user scrolls on the canvas, we don't want to stop scrolling when the user gets to (e.g.) a scrollable widget. So this timer prevents scrolling a widget for a few hundred milliseconds after a scroll event if it was initiated over the canvas
|
|
bool b_allowItemScroll; // See above.
|
|
int m_drawAction;
|
|
|
|
private slots:
|
|
void slotAllowItemScroll() { b_allowItemScroll = true; }
|
|
};
|
|
|
|
|
|
/**
|
|
Abstract class for a "editing operation" on the ICNDocument, such as moving an item or resizing the canvas
|
|
@author David Saxton
|
|
*/
|
|
class CanvasManipulator
|
|
{
|
|
public:
|
|
CanvasManipulator( ItemDocument *itemDocument, CMManager *cmManager );
|
|
virtual ~CanvasManipulator();
|
|
enum Type
|
|
{
|
|
RepeatedItemAdd,
|
|
RightClick,
|
|
AutoConnector,
|
|
ManualConnector,
|
|
ItemMove,
|
|
ItemResize,
|
|
MechItemMove,
|
|
Select,
|
|
CanvasResize,
|
|
ItemDrag,
|
|
Draw
|
|
};
|
|
virtual Type type() const = 0;
|
|
/**
|
|
* Called when the user single-clicks the mouse
|
|
* @returns true if the manipulation operation has finished
|
|
*/
|
|
virtual bool mousePressedInitial( const EventInfo &/*info*/ ) { return false; }
|
|
/**
|
|
* Called when the user single-clicks the mouse after the first time (only
|
|
* applicable for those operations who are not oneClick
|
|
* @returns true if the manipulation operation has finished
|
|
*/
|
|
virtual bool mousePressedRepeat( const EventInfo &/*info*/ ) { return false; };
|
|
/**
|
|
* Called when the user moves the mouse
|
|
* @returns true if the manipulation operation has finished
|
|
*/
|
|
virtual bool mouseMoved( const EventInfo &/*info*/ ) { return false; };
|
|
/**
|
|
* Called when the user releases the mouse
|
|
* @returns true if the manipulation operation has finished
|
|
*/
|
|
virtual bool mouseReleased( const EventInfo &/*info*/ ) { return true; }
|
|
|
|
protected:
|
|
Type m_type;
|
|
EventInfo m_eventInfo;
|
|
TQPoint m_prevPos;
|
|
ItemDocument *p_itemDocument;
|
|
ICNDocument *p_icnDocument;
|
|
MechanicsDocument *p_mechanicsDocument;
|
|
TQCanvas *p_canvas;
|
|
ItemGroup *p_selectList;
|
|
CNItemGroup *p_cnItemSelectList;
|
|
MechanicsGroup *p_mechItemSelectList;
|
|
CNItem *p_cnItemClickedOn;
|
|
MechanicsItem *p_mechanicsItemClickedOn;
|
|
CMManager *p_cmManager;
|
|
};
|
|
|
|
|
|
/**
|
|
@author David Saxton
|
|
*/
|
|
class CMRepeatedItemAdd : public CanvasManipulator
|
|
{
|
|
public:
|
|
CMRepeatedItemAdd( ItemDocument *itemDocument, CMManager *cmManager );
|
|
virtual ~CMRepeatedItemAdd();
|
|
virtual Type type() const { return RepeatedItemAdd; }
|
|
|
|
static CanvasManipulator* construct( ItemDocument *itemDocument, CMManager *cmManager );
|
|
static ManipulatorInfo *manipulatorInfo();
|
|
static bool acceptManipulation( uint eventState, uint cmState, uint itemType, uint cnItemType );
|
|
|
|
virtual bool mousePressedInitial( const EventInfo &info );
|
|
virtual bool mousePressedRepeat( const EventInfo &info );
|
|
virtual bool mouseMoved( const EventInfo &info );
|
|
virtual bool mouseReleased( const EventInfo &info );
|
|
|
|
protected:
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
@author David Saxton
|
|
*/
|
|
class CMRightClick : public CanvasManipulator
|
|
{
|
|
public:
|
|
CMRightClick( ItemDocument *itemDocument, CMManager *cmManager );
|
|
virtual ~CMRightClick();
|
|
virtual Type type() const { return RightClick; }
|
|
|
|
static CanvasManipulator* construct( ItemDocument *itemDocument, CMManager *cmManager );
|
|
static ManipulatorInfo *manipulatorInfo();
|
|
static bool acceptManipulation( uint eventState, uint cmState, uint itemType, uint cnItemType );
|
|
|
|
virtual bool mousePressedInitial( const EventInfo &info );
|
|
virtual bool mouseMoved( const EventInfo &info );
|
|
virtual bool mouseReleased( const EventInfo &info );
|
|
|
|
protected:
|
|
};
|
|
|
|
|
|
/**
|
|
@author David Saxton
|
|
*/
|
|
class ConnectorDraw : public CanvasManipulator
|
|
{
|
|
public:
|
|
ConnectorDraw( ItemDocument *itemDocument, CMManager *cmManager );
|
|
virtual ~ConnectorDraw();
|
|
|
|
/**
|
|
* Returns the colour used to indicate that the current connection
|
|
* being drawn is valid. Invalid colour is black.
|
|
*/
|
|
static TQColor validConnectionColor();
|
|
|
|
protected:
|
|
/**
|
|
* If the node has more than 2 connections, return one of the
|
|
* connectors
|
|
*/
|
|
Connector * toConnector( Node * node );
|
|
/**
|
|
* Converts the given qcanvasitem to an appropriate node or connector.
|
|
* @param posIsExact if true, then only gets an appropriate node or
|
|
* connector when the to-be end-point of the new connector will coincide
|
|
* with pos (i.e. auto-connector will call this with posIsExact = false,
|
|
* and manual-connector will call this with posIsExact = true).
|
|
*/
|
|
void grabEndStuff( TQCanvasItem * endItem, const TQPoint & pos, bool posIsExact );
|
|
/**
|
|
* Returns the closest point to the clickPos that is on the given
|
|
* connector.
|
|
*/
|
|
TQPoint toValidPos( const TQPoint & clickPos, Connector * clickedConnector ) const;
|
|
|
|
TQGuardedPtr<Node> p_startNode;
|
|
TQGuardedPtr<Connector> p_startConnector;
|
|
Node * p_endNode;
|
|
Connector * p_endConnector;
|
|
TQPoint startConnectorPoint;
|
|
};
|
|
|
|
|
|
/**
|
|
@author David Saxton
|
|
*/
|
|
class CMAutoConnector : public ConnectorDraw
|
|
{
|
|
public:
|
|
CMAutoConnector( ItemDocument *itemDocument, CMManager *cmManager );
|
|
virtual ~CMAutoConnector();
|
|
virtual Type type() const { return AutoConnector; }
|
|
|
|
static CanvasManipulator* construct( ItemDocument *itemDocument, CMManager *cmManager );
|
|
static ManipulatorInfo *manipulatorInfo();
|
|
static bool acceptManipulation( uint eventState, uint cmState, uint itemType, uint cnItemType );
|
|
|
|
virtual bool mousePressedInitial( const EventInfo &info );
|
|
virtual bool mouseMoved( const EventInfo &info );
|
|
virtual bool mouseReleased( const EventInfo &info );
|
|
|
|
protected:
|
|
TQCanvasLine *m_connectorLine;
|
|
};
|
|
|
|
|
|
/**
|
|
@author David Saxton
|
|
*/
|
|
class CMManualConnector : public ConnectorDraw
|
|
{
|
|
public:
|
|
CMManualConnector( ItemDocument *itemDocument, CMManager *cmManager );
|
|
virtual ~CMManualConnector();
|
|
virtual Type type() const { return ManualConnector; }
|
|
|
|
static CanvasManipulator* construct( ItemDocument *itemDocument, CMManager *cmManager );
|
|
static ManipulatorInfo *manipulatorInfo();
|
|
static bool acceptManipulation( uint eventState, uint cmState, uint itemType, uint cnItemType );
|
|
|
|
virtual bool mousePressedInitial( const EventInfo &info );
|
|
virtual bool mousePressedRepeat( const EventInfo &info );
|
|
virtual bool mouseMoved( const EventInfo &info );
|
|
virtual bool mouseReleased( const EventInfo &info );
|
|
|
|
protected:
|
|
ConnectorList m_fixedRouteConnectors;
|
|
ManualConnectorDraw *m_manualConnectorDraw;
|
|
};
|
|
|
|
|
|
/**
|
|
@author David Saxton
|
|
*/
|
|
class CMItemMove : public CanvasManipulator
|
|
{
|
|
public:
|
|
CMItemMove( ItemDocument *itemDocument, CMManager *cmManager );
|
|
virtual ~CMItemMove();
|
|
virtual Type type() const { return ItemMove; }
|
|
|
|
static CanvasManipulator* construct( ItemDocument *itemDocument, CMManager *cmManager );
|
|
static ManipulatorInfo *manipulatorInfo();
|
|
static bool acceptManipulation( uint eventState, uint cmState, uint itemType, uint cnItemType );
|
|
|
|
virtual bool mousePressedInitial( const EventInfo &info );
|
|
virtual bool mouseMoved( const EventInfo &info );
|
|
virtual bool mouseReleased( const EventInfo &info );
|
|
|
|
protected:
|
|
ConnectorList m_translatableConnectors;
|
|
NodeGroupList m_translatableNodeGroups;
|
|
FlowContainer *p_flowContainerCandidate;
|
|
};
|
|
|
|
|
|
/**
|
|
@author David Saxton
|
|
*/
|
|
class CMItemResize : public CanvasManipulator
|
|
{
|
|
public:
|
|
CMItemResize( ItemDocument *itemDocument, CMManager *cmManager );
|
|
virtual ~CMItemResize();
|
|
virtual Type type() const { return ItemResize; }
|
|
|
|
static CanvasManipulator* construct( ItemDocument *itemDocument, CMManager *cmManager );
|
|
static ManipulatorInfo *manipulatorInfo();
|
|
static bool acceptManipulation( uint eventState, uint cmState, uint itemType, uint cnItemType );
|
|
|
|
virtual bool mousePressedInitial( const EventInfo &info );
|
|
virtual bool mouseMoved( const EventInfo &info );
|
|
virtual bool mouseReleased( const EventInfo &info );
|
|
|
|
protected:
|
|
ResizeHandle *p_resizeHandle;
|
|
double m_rh_dx;
|
|
double m_rh_dy;
|
|
};
|
|
|
|
|
|
/**
|
|
@author David Saxton
|
|
*/
|
|
class CMMechItemMove : public CanvasManipulator
|
|
{
|
|
public:
|
|
CMMechItemMove( ItemDocument *itemDocument, CMManager *cmManager );
|
|
virtual ~CMMechItemMove();
|
|
virtual Type type() const { return MechItemMove; }
|
|
|
|
static CanvasManipulator* construct( ItemDocument *itemDocument, CMManager *cmManager );
|
|
static ManipulatorInfo *manipulatorInfo();
|
|
static bool acceptManipulation( uint eventState, uint cmState, uint itemType, uint cnItemType );
|
|
|
|
virtual bool mousePressedInitial( const EventInfo &info );
|
|
virtual bool mouseMoved( const EventInfo &info );
|
|
virtual bool mouseReleased( const EventInfo &info );
|
|
|
|
protected:
|
|
uint m_prevClickedOnSM; // Previous select mode of the item that was clicked on
|
|
};
|
|
|
|
|
|
/**
|
|
@author David Saxton
|
|
*/
|
|
class SelectRectangle
|
|
{
|
|
public:
|
|
SelectRectangle( int x, int y, int w, int h, TQCanvas *qcanvas );
|
|
~SelectRectangle();
|
|
|
|
void setSize( int w, int h );
|
|
TQCanvasItemList collisions();
|
|
|
|
protected:
|
|
TQCanvasLine *m_topLine;
|
|
TQCanvasLine *m_rightLine;
|
|
TQCanvasLine *m_bottomLine;
|
|
TQCanvasLine *m_leftLine;
|
|
const int m_x;
|
|
const int m_y;
|
|
int m_w;
|
|
int m_h;
|
|
int m_prevCollisions_w;
|
|
int m_prevCollisions_h;
|
|
TQCanvasItemList m_prevCollisions;
|
|
};
|
|
|
|
|
|
/**
|
|
@author David Saxton
|
|
*/
|
|
class CMSelect : public CanvasManipulator
|
|
{
|
|
public:
|
|
CMSelect( ItemDocument *itemDocument, CMManager *cmManager );
|
|
virtual ~CMSelect();
|
|
virtual Type type() const { return Select; }
|
|
|
|
static CanvasManipulator* construct( ItemDocument *itemDocument, CMManager *cmManager );
|
|
static ManipulatorInfo *manipulatorInfo();
|
|
static bool acceptManipulation( uint eventState, uint cmState, uint itemType, uint cnItemType );
|
|
|
|
virtual bool mousePressedInitial( const EventInfo &info );
|
|
virtual bool mouseMoved( const EventInfo &info );
|
|
virtual bool mouseReleased( const EventInfo &info );
|
|
|
|
protected:
|
|
SelectRectangle *m_selectRectangle;
|
|
};
|
|
|
|
|
|
/**
|
|
@author David Saxton
|
|
*/
|
|
class CMItemDrag : public CanvasManipulator
|
|
{
|
|
public:
|
|
CMItemDrag( ItemDocument *itemDocument, CMManager *cmManager );
|
|
virtual ~CMItemDrag();
|
|
virtual Type type() const { return ItemDrag; }
|
|
|
|
static CanvasManipulator* construct( ItemDocument *itemDocument, CMManager *cmManager );
|
|
static ManipulatorInfo *manipulatorInfo();
|
|
static bool acceptManipulation( uint eventState, uint cmState, uint itemType, uint cnItemType );
|
|
|
|
virtual bool mousePressedInitial( const EventInfo &info );
|
|
virtual bool mouseMoved( const EventInfo &info );
|
|
virtual bool mouseReleased( const EventInfo &info );
|
|
|
|
protected:
|
|
bool b_dragged;
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
@author David Saxton
|
|
A TQCanvasEllipse that uses a pen (not a brush) to paint
|
|
*/
|
|
class CanvasEllipseDraw : public TQCanvasEllipse
|
|
{
|
|
public:
|
|
CanvasEllipseDraw( int x, int y, TQCanvas * canvas );
|
|
|
|
protected:
|
|
virtual void drawShape( TQPainter & p );
|
|
};
|
|
|
|
|
|
/**
|
|
@author David Saxton
|
|
*/
|
|
class CMDraw : public CanvasManipulator
|
|
{
|
|
public:
|
|
CMDraw( ItemDocument *itemDocument, CMManager *cmManager );
|
|
virtual ~CMDraw();
|
|
virtual Type type() const { return Draw; }
|
|
|
|
static CanvasManipulator* construct( ItemDocument *itemDocument, CMManager *cmManager );
|
|
static ManipulatorInfo *manipulatorInfo();
|
|
static bool acceptManipulation( uint eventState, uint cmState, uint itemType, uint cnItemType );
|
|
|
|
virtual bool mousePressedInitial( const EventInfo &info );
|
|
virtual bool mouseMoved( const EventInfo &info );
|
|
virtual bool mouseReleased( const EventInfo &info );
|
|
|
|
protected:
|
|
TQCanvasRectangle * m_pDrawRectangle;
|
|
CanvasEllipseDraw * m_pDrawEllipse;
|
|
TQCanvasLine * m_pDrawLine;
|
|
};
|
|
|
|
|
|
/**
|
|
@author David Saxton
|
|
*/
|
|
class ManualConnectorDraw
|
|
{
|
|
public:
|
|
ManualConnectorDraw( ICNDocument *_icnDocument, const TQPoint &initialPos );
|
|
virtual ~ManualConnectorDraw();
|
|
|
|
/**
|
|
* Called when the mouse is moved.
|
|
* Normally will do something like updating the connector route
|
|
*/
|
|
void mouseMoved( const TQPoint &pos );
|
|
/**
|
|
* Called when the user clicks the mouse. If the connector finishes on a
|
|
* valid TQCanvasItem (Node or Connetor), then this is returned. Otherwise,
|
|
* null is returned.
|
|
*/
|
|
TQCanvasItem * mouseClicked( const TQPoint &pos );
|
|
/**
|
|
* Returns the list of points that define the manual connection route
|
|
*/
|
|
TQPointList pointList();
|
|
/**
|
|
* Sets the colour used to draw the connection lines.
|
|
*/
|
|
void setColor( const TQColor & color );
|
|
|
|
protected:
|
|
void updateConnectorEnds();
|
|
|
|
TQValueList<TQCanvasLine*> m_connectorLines;
|
|
ICNDocument *icnDocument;
|
|
|
|
bool b_currentVertical;
|
|
bool b_orientationDefined;
|
|
|
|
TQPoint m_initialPos;
|
|
TQPoint m_previousPos;
|
|
TQPoint m_currentPos;
|
|
|
|
TQCanvasLine *m_currentCon;
|
|
TQCanvasLine *m_previousCon;
|
|
|
|
// The first item that we clicked on
|
|
TQCanvasItem *p_initialItem;
|
|
|
|
TQColor m_color;
|
|
};
|
|
|
|
|
|
#endif
|