Files
2018-12-06 16:01:56 +01:00

1197 lines
44 KiB
C++

/***************************************************************
* Name: ShapeCanvas.h
* Purpose: Defines shape canvas class
* Author: Michal Bližňák (michal.bliznak@tiscali.cz)
* Created: 2007-07-22
* Copyright: Michal Bližňák
* License: wxWidgets license (www.wxwidgets.org)
* Notes:
**************************************************************/
#ifndef _WXSFSHAPECANVAS_H
#define _WXSFSHAPECANVAS_H
#include <wx/dataobj.h>
#include <wx/dnd.h>
#include <wx/wxsf/ShapeBase.h>
#include <wx/wxsf/DiagramManager.h>
#include <wx/wxsf/MultiSelRect.h>
#include <wx/wxsf/CanvasHistory.h>
#include <wx/wxsf/LineShape.h>
#include <wx/wxsf/EditTextShape.h>
#include <wx/wxsf/Printout.h>
#include <wx/wxsf/CommonFcn.h>
#ifdef __WXMAC__
#include <wx/printdlg.h>
#endif
/*! \brief XPM (mono-)bitmap which can be used in shape's shadow brush */
extern const char* wxSFShadowBrush_xpm[];
/*! \brief Global page setup data */
extern wxPageSetupDialogData* g_pageSetupData;
/*! \brief Global print data, to remember settings during the session */
extern wxPrintData *g_printData;
#define sfDEFAULT_ME_OFFSET 5
#define sfSAVE_STATE true
#define sfDONT_SAVE_STATE false
#define sfFROM_PAINT true
#define sfNOT_FROM_PAINT false
#define sfTOPMOST_SHAPES true
#define sfALL_SHAPES false
#define sfPROMPT true
#define sfNO_PROMPT false
#define sfWITH_BACKGROUND true
#define sfWITHOUT_BACKGROUND false
// default values
/*! \brief Default value of wxSFCanvasSettings::m_nBackgroundColor data member */
#define sfdvSHAPECANVAS_BACKGROUNDCOLOR wxColour(240, 240, 240)
/*! \brief Default value of wxSFCanvasSettings::m_nGridSize data member */
#define sfdvSHAPECANVAS_GRIDSIZE wxSize(10, 10)
/*! \brief Default value of wxSFCanvasSettings::m_nGridLineMult data member */
#define sfdvSHAPECANVAS_GRIDLINEMULT 1
/*! \brief Default value of wxSFCanvasSettings::m_nGridColor data member */
#define sfdvSHAPECANVAS_GRIDCOLOR wxColour(200, 200, 200)
/*! \brief Default value of wxSFCanvasSettings::m_nGridStyle data member */
#define sfdvSHAPECANVAS_GRIDSTYLE wxSOLID
/*! \brief Default value of wxSFCanvasSettings::m_CommnonHoverColor data member */
#define sfdvSHAPECANVAS_HOVERCOLOR wxColor(120, 120, 255)
/*! \brief Default value of wxSFCanvasSettings::m_nGradientFrom data member */
#define sfdvSHAPECANVAS_GRADIENT_FROM wxColour(240, 240, 240)
/*! \brief Default value of wxSFCanvasSettings::m_nGradientTo data member */
#define sfdvSHAPECANVAS_GRADIENT_TO wxColour(200, 200, 255)
/*! \brief Default value of wxSFCanvasSettings::m_nStyle data member */
#define sfdvSHAPECANVAS_STYLE wxSFShapeCanvas::sfsDEFAULT_CANVAS_STYLE
/*! \brief Default value of wxSFCanvasSettings::m_nShadowOffset data member */
#define sfdvSHAPECANVAS_SHADOWOFFSET wxRealPoint(4, 4)
/*! \brief Default shadow colour */
#define sfdvSHAPECANVAS_SHADOWCOLOR wxColour(150, 150, 150, 128)
/*! \brief Default value of wxSFCanvasSettings::m_ShadowFill data member */
#define sfdvSHAPECANVAS_SHADOWBRUSH wxBrush(sfdvSHAPECANVAS_SHADOWCOLOR, wxSOLID)
/*! \brief Default value of wxSFCanvasSettings::m_nPrintHAlign data member */
#define sfdvSHAPECANVAS_PRINT_HALIGN wxSFShapeCanvas::halignCENTER
/*! \brief Default value of wxSFCanvasSettings::m_nPrintVAlign data member */
#define sfdvSHAPECANVAS_PRINT_VALIGN wxSFShapeCanvas::valignMIDDLE
/*! \brief Default value of wxSFCanvasSettings::m_nPrintMode data member */
#define sfdvSHAPECANVAS_PRINT_MODE wxSFShapeCanvas::prnFIT_TO_MARGINS
/*! \brief Default value of wxSFCanvasSettings::m_nMinScale data member */
#define sfdvSHAPECANVAS_SCALE_MIN 0.1
/*! \brief Default value of wxSFCanvasSettings::m_nMaxScale data member */
#define sfdvSHAPECANVAS_SCALE_MAX 5
class wxSFCanvasDropTarget;
/*!
* \brief Auxiliary class encapsulating shape drop target.
*/
class wxSFCanvasDropTarget : public wxDropTarget
{
friend class wxSFShapeCanvas;
protected:
wxSFCanvasDropTarget(wxDataObject *data, wxSFShapeCanvas *parent);
virtual ~wxSFCanvasDropTarget();
virtual wxDragResult OnData(wxCoord x, wxCoord y, wxDragResult def);
wxSFShapeCanvas *m_pParentCanvas;
};
/*!
* \brief Auxiliary serializable class encapsulating the canvas properties.
*/
class wxSFCanvasSettings : public xsSerializable
{
public:
DECLARE_DYNAMIC_CLASS(wxSFCanvasSettings);
wxSFCanvasSettings();
wxColour m_nBackgroundColor;
wxColour m_nCommonHoverColor;
wxColour m_nGradientFrom;
wxColour m_nGradientTo;
wxSize m_nGridSize;
int m_nGridLineMult;
wxColour m_nGridColor;
int m_nGridStyle;
wxRealPoint m_nShadowOffset;
wxBrush m_ShadowFill;
wxArrayString m_arrAcceptedShapes;
double m_nScale;
double m_nMinScale;
double m_nMaxScale;
long m_nStyle;
int m_nPrintHAlign;
int m_nPrintVAlign;
int m_nPrintMode;
};
/*!
* \brief Class encapsulating a Shape canvas. The shape canvas is window control
* which extends the wxScrolledWindow and is responsible for displaying of shapes diagrams.
* It also supports clipboard and drag&drop operations, undo/redo operations,
* and graphics exporting functions.
*
* This class is a core framework class and provides many member functions suitable for adding,
* removing, moving, resizing and drawing of shape objects. It can be used as it is or as a base class
* if necessary. In that case, the default class functionality can be enhaced by overriding of
* its virtual functions or by manual events handling. In both cases the user is responsible
* for invoking of default event handlers/virtual functions otherwise the
* built in functionality wont be available.
* \sa wxSFDiagramManager
*/
class WXDLLIMPEXP_SF wxSFShapeCanvas : public wxScrolledWindow
{
public:
friend class wxSFDiagramManager;
friend class wxSFCanvasDropTarget;
/*!
* \brief Default constructor
*/
wxSFShapeCanvas();
/*!
* \brief Constructor
* \param manager Pointer to shape manager
* \param parent Parent window
* \param id Window ID
* \param pos Initial position
* \param size Initial size
* \param style Window style
*/
wxSFShapeCanvas(wxSFDiagramManager* manager, wxWindow* parent, wxWindowID id = -1, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxHSCROLL | wxVSCROLL);
/*! \brief Destructor */
~wxSFShapeCanvas(void);
/*!
* \brief Creates the window in two-step construction mode. SetDiagramManager() function must be also called to complete the canvas initialization.
* \param parent Parent window
* \param id Window ID
* \param pos Initial position
* \param size Initial size
* \param style Window style
* \param name Window name
*/
virtual bool Create(wxWindow* parent, wxWindowID id = -1, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxHSCROLL | wxVSCROLL, const wxString& name = wxT("scrolledWindow"));
/*! \brief Working modes */
enum MODE
{
/*! \brief The shape canvas is in ready state (no operation is pending) */
modeREADY = 0,
/*! \brief Some shape handle is dragged */
modeHANDLEMOVE,
/*! \brief Handle of multiselection tool is dragged */
modeMULTIHANDLEMOVE,
/*! \brief Some shape/s is/are dragged */
modeSHAPEMOVE,
/*! \brief Multiple shape selection is in progess */
modeMULTISELECTION,
/*! \brief Interactive connection creation is in progress */
modeCREATECONNECTION,
/*! \brief Canvas is in the Drag&Drop mode */
modeDND
};
/*! \brief Search mode flags for GetShapeAtPosition function */
enum SEARCHMODE
{
/*! \brief Search for selected shapes only*/
searchSELECTED,
/*! \brief Search for unselected shapes only */
searchUNSELECTED,
/*! \brief Search for both selected and unselected shapes */
searchBOTH
};
/*! \brief Flags for AlignSelected function */
enum VALIGN
{
valignNONE,
valignTOP,
valignMIDDLE,
valignBOTTOM
};
/*! \brief Flags for AlignSelected function */
enum HALIGN
{
halignNONE,
halignLEFT,
halignCENTER,
halignRIGHT
};
/*! \brief Style flags */
enum STYLE
{
/*! \brief Allow multiselection box. */
sfsMULTI_SELECTION = 1,
/*! \brief Allow shapes' size change done via the multiselection box. */
sfsMULTI_SIZE_CHANGE = 2,
/*! \brief Show grid. */
sfsGRID_SHOW = 4,
/*! \brief Use grid. */
sfsGRID_USE = 8,
/*! \brief Enable Drag & Drop operations. */
sfsDND = 16,
/*! \brief Enable Undo/Redo operations. */
sfsUNDOREDO = 32,
/*! \brief Enable the clipboard. */
sfsCLIPBOARD = 64,
/*! \brief Enable mouse hovering */
sfsHOVERING = 128,
/*! \brief Enable highligting of shapes able to accept dragged shape(s). */
sfsHIGHLIGHTING = 256,
/*! \brief Use gradient color for the canvas background. */
sfsGRADIENT_BACKGROUND = 512,
/*! \brief Print also canvas background. */
sfsPRINT_BACKGROUND = 1024,
/*! \brief Process mouse wheel by the canvas (canvas scale will be changed). */
sfsPROCESS_MOUSEWHEEL = 2048,
/*! \brief Default canvas style. */
sfsDEFAULT_CANVAS_STYLE = sfsMULTI_SELECTION | sfsMULTI_SIZE_CHANGE | sfsDND | sfsUNDOREDO | sfsCLIPBOARD | sfsHOVERING | sfsHIGHLIGHTING
};
/*! \brief Flags for ShowShadow function. */
enum SHADOWMODE
{
/*! \brief Show/hide shadow under topmost shapes only. */
shadowTOPMOST,
/*! \brief Show/hide shadow under all shapes in the diagram. */
shadowALL
};
/*! \brief Printing modes used by SetPrintMode() function. */
enum PRINTMODE
{
/*! \brief This sets the user scale and origin of the DC so that the image fits
* within the paper rectangle (but the edges could be cut off by printers
* that can't print to the edges of the paper -- which is most of them. Use
* this if your image already has its own margins. */
prnFIT_TO_PAPER,
/*! \brief This sets the user scale and origin of the DC so that the image fits
* within the page rectangle, which is the printable area on Mac and MSW
* and is the entire page on other platforms. */
prnFIT_TO_PAGE,
/*! \brief This sets the user scale and origin of the DC so that the image fits
* within the page margins as specified by g_PageSetupData, which you can
* change (on some platforms, at least) in the Page Setup dialog. Note that
* on Mac, the native Page Setup dialog doesn't let you change the margins
* of a wxPageSetupDialogData object, so you'll have to write your own dialog or
* use the Mac-only wxMacPageMarginsDialog, as we do in this program. */
prnFIT_TO_MARGINS,
/*! \brief This sets the user scale and origin of the DC so that you could map the
* screen image to the entire paper at the same size as it appears on screen. */
prnMAP_TO_PAPER,
/*! \brief This sets the user scale and origin of the DC so that the image appears
* on the paper at the same size that it appears on screen (i.e., 10-point
* type on screen is 10-point on the printed page). */
prnMAP_TO_PAGE,
/*! \brief This sets the user scale and origin of the DC so that you could map the
* screen image to the page margins specified by the native Page Setup dialog at the same
* size as it appears on screen. */
prnMAP_TO_MARGINS,
/*! \brief This sets the user scale and origin of the DC so that you can to do you own
* scaling in order to draw objects at full native device resolution. */
prnMAP_TO_DEVICE
};
// public functions
/*!
* \brief Get diagram manager associated with this instance of shape canvas
* \return Pointer to diagram manager
* \sa wxSFDiagramManager
*/
inline wxSFDiagramManager* GetDiagramManager() { return m_pManager; }
/*!
* \brief Set diagram manager for this shape canvas
* \param manager Pointer to diagram manager instance
* \sa wxSFDiagramManager
*/
void SetDiagramManager(wxSFDiagramManager* manager);
/*!
* \brief Load serialized canvas content (diagrams) from given file.
* \param file Full file name
*/
void LoadCanvas(const wxString& file);
/*!
* \brief Save canvas content (diagrams) to given file.
* \param file Full file name
*/
void SaveCanvas(const wxString& file);
/*!
* \brief Export canvas content to BMP file.
* DEPRECATED: use SaveCanvasToImage() instead.
* \param file Full file name
*/
void SaveCanvasToBMP(const wxString& file);
/*!
* \brief Export canvas content to image file.
* \param file Full file name
* \param type Image type. See wxBitmapType for more details. Default type is
* wxBITMAP_TYPE_BMP.
* \param background Export also diagram background
* \param scale Image scale. If -1 then current canvas scale id used.
*/
void SaveCanvasToImage(const wxString& file, wxBitmapType type = wxBITMAP_TYPE_BMP, bool background = true, double scale = -1);
/*!
* \brief Start interactive connection creation.
*
* This function switch the canvas to a mode in which a new shape connection
* can be created interactively (by mouse operations). Every connection must
* start and finish in some shape object or another connection. At the end of the
* process the OnConnectionFinished event handler is invoked so the user can
* set needed connection properties immediately.
*
* Function must be called from mouse event handler and the event must be passed
* to the function.
* \param shapeInfo Connection type
* \param pos Position where to start
* \param err Pointer to variable where operation result will be stored. Can be NULL.
* \sa CreateConnection
*/
void StartInteractiveConnection(wxClassInfo* shapeInfo, const wxPoint& pos, wxSF::ERRCODE *err = NULL);
/*!
* \brief Start interactive connection creation from existing line object.
*
* This function switch the canvas to a mode in which a new shape connection
* can be created interactively (by mouse operations). Every connection must
* start and finish in some shape object or another connection. At the end of the
* process the OnConnectionFinished event handler is invoked so the user can
* set needed connection properties immediately.
*
* Function must be called from mouse event handler and the event must be passed
* to the function.
* \param shape Pointer to existing line shape object which will be used as a connection.
* \param pos Position where to start
* \param err Pointer to variable where operation result will be stored. Can be NULL.
* \sa CreateConnection
*/
void StartInteractiveConnection(wxSFLineShape* shape, const wxPoint& pos, wxSF::ERRCODE *err = NULL);
/*! \brief Abort interactive connection creation process */
void AbortInteractiveConnection();
/*! \brief Select all shapes in the canvas */
void SelectAll();
/*! \brief Deselect all shapes */
void DeselectAll();
/*! \brief Hide handles of all shapes */
void HideAllHandles();
/*!
* \brief Repaint the shape canvas.
* \param erase TRUE if the canvas should be erased before repainting
* \param rct Refreshed region (rectangle)
*/
void RefreshCanvas(bool erase, const wxRect& rct);
/*!
* \brief Mark given rectangle as an invalidated one, i.e. as a rectangle which should
* be refreshed (by using wxSFShapeCanvas::RefreshInvalidatedRect()).
* \param rct Rectangle to be invalidated
*/
void InvalidateRect(const wxRect& rct);
/*!
* \brief Mark whole visible canvas portion as an invalidated rectangle.
*/
void InvalidateVisibleRect();
/*!
* \brief Refresh all canvas rectangles marked as invalidated.
* \sa wxSFShapeCanvas::InvalidateRect()
*/
void RefreshInvalidatedRect();
/*!
* \brief Show shapes shadows (only current digram shapes are affected).
*
* The functions sets/unsets sfsSHOW_SHADOW flag for all shapes currently included in the diagram.
* \param show TRUE if the shadow shoud be shown, otherwise FALSE
* \param style Shadow style
* \sa SHADOWMODE
*/
void ShowShadows(bool show, SHADOWMODE style);
/*!
* \brief Start Drag&Drop operation with shapes included in the given list.
* \param shapes List of shapes which should be dragged
* \param start A point where the dragging operation has started
* \return rct Drag result
*/
wxDragResult DoDragDrop(ShapeList &shapes, const wxPoint& start = wxPoint(-1, -1));
/*! \brief Copy selected shapes to the clipboard */
void Copy();
/*! \brief Copy selected shapes to the clipboard and remove them from the canvas */
void Cut();
/*! \brief Paste shapes stored in the clipboard to the canvas */
void Paste();
/*! \brief Perform Undo operation (if available) */
void Undo();
/*! \brief Perform Redo operation (if available) */
void Redo();
/*! \brief Function returns TRUE if some shapes can be copied to the clipboard (it means they are selected) */
bool CanCopy();
/*! \brief Function returns TRUE if some shapes can be cutted to the clipboard (it means they are selected) */
bool CanCut();
/*! \brief Function returns TRUE if some shapes can be copied from the clipboard to the canvas
* (it means the clipboard contains stored shapes) */
bool CanPaste();
/*! \brief Function returns TRUE if Undo operation can be done */
bool CanUndo();
/*! \brief Function returns TRUE if Redo operation can be done */
bool CanRedo();
/*! \brief Function returns TRUE if AlignSelected function can be invoked (if more than
* one shape is selected) */
bool CanAlignSelected();
/*! \brief Save current canvas state (for Undo/Redo operations) */
void SaveCanvasState();
/*! \brief Clear all stored canvas states (no Undo/Redo operations will be available) */
void ClearCanvasHistory();
/*!
* \brief Print current canvas content.
* \param prompt If TRUE (sfPROMT) then the the native print dialog will be displayed before printing
*/
void Print(bool prompt = sfPROMPT);
/*!
* \brief Print current canvas content using user-defined printout class.
* \param printout Pointer to user-defined printout object (inherited from wxSFPrintout class). Do not delete this object explicitly.
* \param prompt If TRUE (sfPROMT) then the native print dialog will be displayed before printing
* \sa wxSFPrintout
*/
void Print(wxSFPrintout *printout, bool prompt = sfPROMPT);
/*! \brief Show print preview. */
void PrintPreview();
/*!
* \brief Show print preview using user-defined printout classes.
* \param preview Pointer to user-defined printout object (inherited from wxSFPrintout class) used for print preview.
* Do not delete this object explicitly.
* \param printout Pointer to user-defined printout class (inherited from wxSFPrintout class) used for printing.
* Do not delete this object explicitly. This parameter can be NULL (in this case a print button will not be available
* in the print preview window).
* \sa wxSFPrintout
*/
void PrintPreview(wxSFPrintout *preview, wxSFPrintout *printout = NULL);
/*! \brief Show page setup dialog for printing. */
void PageSetup();
// #ifdef __WXMAC__
// /*! \brief Show page margins setup dialog (available only for MAC). */
// void PageMargins();
// #endif
/*!
* \brief Convert device position to logical position.
*
* The function returns unscrolled unscaled canvas position.
* \param pos Device position (for example mouse position)
* \return Logical position
*/
wxPoint DP2LP(const wxPoint& pos) const;
wxRect DP2LP(const wxRect& rct) const;
/*!
* \brief Convert logical position to device position.
*
* The function returns scrolled scaled canvas position.
* \param pos Logical position (for example shape position)
* \return Device position
*/
wxPoint LP2DP(const wxPoint& pos) const;
wxRect LP2DP(const wxRect& rct) const;
/*!
* \brief Get shape under current mouse cursor position (fast implementation - use everywhere
* it is possible instead of much slower GetShapeAtPosition()).
* \param mode Search mode
* \return Pointer to shape if found, otherwise NULL
* \sa SEARCHMODE, wxSFShapeCanvas::DP2LP, wxSFShapeCanvas::GetShapeAtPosition
*/
wxSFShapeBase* GetShapeUnderCursor(SEARCHMODE mode = searchBOTH);
/*!
* \brief Get shape at given logical position
* \param pos Logical position
* \param zorder Z-order of searched shape (usefull if several shapes are located
* at the given position)
* \param mode Search mode
* \return Pointer to shape if found, otherwise NULL
* \sa SEARCHMODE, wxSFShapeCanvas::DP2LP,, wxSFShapeCanvas::GetShapeUnderCursor
*/
wxSFShapeBase* GetShapeAtPosition(const wxPoint& pos, int zorder = 1, SEARCHMODE mode = searchBOTH);
/*!
* \brief Get topmost handle at given position
* \param pos Logical position
* \return Pointer to shape handle object if found, otherwise NULL
* \sa wxSFShapeCanvas::DP2LP
*/
wxSFShapeHandle* GetTopmostHandleAtPosition(const wxPoint& pos);
/*!
* \brief Get list of all shapes located at given position
* \param pos Logical position
* \param shapes Reference to shape list where pointers to all found shapes will be stored
* \sa wxSFShapeCanvas::DP2LP
*/
void GetShapesAtPosition(const wxPoint& pos, ShapeList& shapes);
/*!
* \brief Get list of shapes located inside given rectangle
* \param rct Examined rectangle
* \param shapes Reference to shape list where pointers to all found shapes will be stored
*/
void GetShapesInside(const wxRect& rct, ShapeList& shapes);
/*!
* \brief Get list of selected shapes.
* \param selection Reference to shape list where pointers to all selected shapes will be stored
*/
void GetSelectedShapes(ShapeList& selection);
/*!
* \brief Get box bounding all shapes in the canvas.
* \return Total bounding box
*/
wxRect GetTotalBoundingBox() const;
/*!
* \brief Get bounding box of all selected shapes.
* \return Selection bounding box
*/
wxRect GetSelectionBB();
/*!
* \brief Align selected shapes in given directions.
*
* Shapes will be aligned according to most far shape in appropriate direction.
* \param halign Horizontal alignment
* \param valign Vertical alignment
*/
void AlignSelected(HALIGN halign, VALIGN valign);
/*!
* \brief Set canvas style.
*
* Default value is sfsMULTI_SELECTION | sfsMULTI_SIZE_CHANGE | sfsDND | sfsUNDOREDO | sfsCLIPBOARD | sfsHOVERING | sfsHIGHLIGHTING
* \param style Combination of the canvas styles
* \sa STYLE
*/
inline void SetStyle(long style) { m_Settings.m_nStyle = style; }
/*! \brief Get current canvas style. */
inline long GetStyle() const { return m_Settings.m_nStyle; }
/*! \brief Add new style flag. */
inline void AddStyle(STYLE style) { m_Settings.m_nStyle |= style; }
/*! \brief Remove given style flag. */
inline void RemoveStyle(STYLE style) { m_Settings.m_nStyle &= ~style; }
/*! \brief Check whether given style flag is used. */
inline bool ContainsStyle(STYLE style) const { return (m_Settings.m_nStyle & style) != 0; }
// public members accessors
/*!
* \brief Set canvas background color.
* \param col Background color
*/
inline void SetCanvasColour(const wxColour& col) { m_Settings.m_nBackgroundColor = col; }
/*!
* \brief Get canvas background color.
* \return Background color
*/
inline wxColour GetCanvasColour() const { return m_Settings.m_nBackgroundColor; }
/*!
* \brief Set starting gradient color.
* \param col Color
*/
inline void SetGradientFrom(const wxColour& col) { m_Settings.m_nGradientFrom = col; }
/*!
* \brief Get starting gradient color.
* \return Color
*/
inline wxColour GetGradientFrom() const { return m_Settings.m_nGradientFrom; }
/*!
* \brief Set ending gradient color.
* \param col Color
*/
inline void SetGradientTo(const wxColour& col) { m_Settings.m_nGradientTo = col; }
/*!
* \brief Get ending gradient color.
* \return Color
*/
inline wxColour GetGradientTo() const { return m_Settings.m_nGradientTo; }
/*!
* \brief Get grid size.
* \return Grid size
*/
inline wxSize GetGrid() const { return m_Settings.m_nGridSize; }
/*!
* \brief Set grid size.
* \param grid Grid size
*/
inline void SetGrid(wxSize grid) { m_Settings.m_nGridSize = grid; }
/*!
* \brief Set grid line multiple.
*
* Grid lines will be drawn in a distance calculated as grid size multiplicated by this value.
* Default value is 1.
* \param multiple Multiple value
*/
inline void SetGridLineMult(int multiple) { m_Settings.m_nGridLineMult = multiple; }
/**
* \brief Get grid line multiple.
* \return Value by which a grid size will be multiplicated to determine grid lines distance
*/
inline int GetGrigLineMult() const { return m_Settings.m_nGridLineMult; }
/*!
* \brief Set grid color.
* \param col Grid color
*/
inline void SetGridColour(const wxColour& col) { m_Settings.m_nGridColor = col; }
/*!
* \brief Get grid color.
* \return Grid color
*/
inline wxColour GetGridColour() const { return m_Settings.m_nGridColor; }
/*!
* \brief Set grid line style.
* \param style Line style
*/
inline void SetGridStyle(int style) { m_Settings.m_nGridStyle = style; }
/*!
* \brief Get grid line style.
* \return Line style
*/
inline int GetGridStyle() const {return m_Settings.m_nGridStyle; }
/*!
* \brief Set shadow offset.
* \param offset Shadow offset
*/
inline void SetShadowOffset(const wxRealPoint& offset) { m_Settings.m_nShadowOffset = offset; }
/*!
* \brief Get shadow offset.
* \return Shadow offset
*/
inline wxRealPoint GetShadowOffset() const { return m_Settings.m_nShadowOffset; }
/*!
* \brief Set shadow fill (used for shadows of non-text shapes only).
* \param brush Reference to brush object
*/
inline void SetShadowFill(const wxBrush& brush) { m_Settings.m_ShadowFill = brush; }
/*!
* \brief Get shadow fill.
* \return Current shadow brush
*/
inline wxBrush GetShadowFill() const { return m_Settings.m_ShadowFill; }
/*!
* \brief Set horizontal align of printed drawing.
* \param val Horizontal align
* \sa HALIGN
*/
inline void SetPrintHAlign(HALIGN val) { m_Settings.m_nPrintHAlign = (int)val; }
/*!
* \brief Get horizontal align of printed drawing.
* \return Current horizontal align
* \sa HALIGN
*/
inline HALIGN GetPrintHAlign() const { return (HALIGN)m_Settings.m_nPrintHAlign; }
/*!
* \brief Set vertical align of printed drawing.
* \param val Verical align
* \sa VALIGN
*/
inline void SetPrintVAlign(VALIGN val) { m_Settings.m_nPrintVAlign = (int)val; }
/*!
* \brief Get vertical align of printed drawing.
* \return Current vertical align
* \sa VALIGN
*/
inline VALIGN GetPrintVAlign() const { return (VALIGN)m_Settings.m_nPrintVAlign; }
/*!
* \brief Set printing mode for this canvas.
* \param mode Printing mode
* \sa PRINTMODE
*/
inline void SetPrintMode(PRINTMODE mode) { m_Settings.m_nPrintMode = (int)mode; }
/*!
* \brief Get printing mode for this canvas.
* \return Current printing mode
* \sa PRINTMODE
*/
inline PRINTMODE GetPrintMode() const { return (PRINTMODE)m_Settings.m_nPrintMode; }
/*!
* \brief Set canvas scale.
* \param scale Scale value
*/
void SetScale(double scale);
/*!
* \brief Set minimal allowed scale (for mouse wheel scale change).
* \param scale Minimal scale
*/
void SetMinScale(double scale) { m_Settings.m_nMinScale = scale; }
/*!
* \brief Get minimal allowed scale (for mouse wheel scale change).
* \return Minimal scale
*/
double GetMinScale() { return m_Settings.m_nMinScale; }
/*!
* \brief Set maximal allowed scale (for mouse wheel scale change).
* \param scale Maximal scale
*/
void SetMaxScale(double scale) { m_Settings.m_nMaxScale = scale; }
/*!
* \brief Set maximal allowed scale (for mouse wheel scale change).
* \return Maximal scale
*/
double GetMaxScale() { return m_Settings.m_nMaxScale; }
/*!
* \brief Get the canvas scale.
* \return Canvas scale
*/
inline double GetScale() const { return m_Settings.m_nScale; }
/*!
* \brief Set the canvas scale so a whole diagram is visible.
*/
void SetScaleToViewAll();
/**
* \brief Scroll the shape canvas so the given shape will be located in its center.
* \param shape Pointer to focused shape
*/
void ScrollToShape(wxSFShapeBase* shape);
/*!
* \brief Enable usage of wxGraphicsContext for drawing (if supported).
* \param enab If TRUE then the wxGraphicsContext will be used
*/
static void EnableGC(bool enab);
/*!
* \brief Function returns information whether the wxGraphicsContext is enabled (if supported).
* \return TRUE if the wxGraphicsContext is enabled
*/
static bool IsGCEnabled() { return m_fEnableGC; }
/*!
* \brief Get canvas workind mode.
* \return Working mode
* \sa MODE
*/
inline MODE GetMode() const { return m_nWorkingMode; }
/*!
* \brief Set default hover color.
* \param col Hover color.
*/
void SetHoverColour(const wxColour& col);
/*!
* \brief Get default hover color.
* \return Hover color
*/
inline wxColour GetHoverColour() const { return m_Settings.m_nCommonHoverColor; }
/*!
* \brief Get canvas hostory manager.
* \return Reference to the canvas history manager
* \sa wxSFCanvasHistory
*/
inline wxSFCanvasHistory& GetHistoryManager() { return m_CanvasHistory; }
/*!
* \brief Update given position so it will fit canvas grid (if enabled).
* \param pos Position which should be updated
* \return Updated position
*/
wxPoint FitPositionToGrid(const wxPoint& pos);
/*! \brief Update size of multi selection rectangle */
void UpdateMultieditSize();
/*! \brief Update scroll window virtual size so it can display all shape canvas */
void UpdateVirtualSize();
/*! \brief Move all shapes so none of it will be located in negative position */
void MoveShapesFromNegatives();
/*! \brief Center diagram in accordance to the shape canvas extent. */
void CenterShapes();
/*!
* \brief Validate selection (remove redundantly selected shapes etc...).
* \param selection List of selected shapes that should be validated
*/
void ValidateSelection(ShapeList& selection);
/*!
* \brief Function responsible for drawing of the canvas's content to given DC.
* \param dc Reference to device context where the shapes will be drawn to
* \param fromPaint Set the argument to TRUE if the dc argument refers to the wxPaintDC instance
*/
void DrawContent(wxDC& dc, bool fromPaint);
/*!
* \brief Get reference to multiselection box
* \return Reference to multiselection box object
*/
inline wxSFMultiSelRect& GetMultiselectionBox() { return m_shpMultiEdit; }
/*! \brief Close and delete all opened text editing controls actualy used by editable text shapes */
void DeleteAllTextCtrls();
// public virtual event handlers
/*!
* \brief Event handler called when the canvas is clicked by
* the left mouse button. The function can be overrided if necessary.
*
* The function is called by the framework and provides basic functionality
* needed for proper management of displayed shape. It is necessary to call
* this function from overrided methods if the default canvas behaviour
* should be preserved.
* \param event Mouse event
* \sa _OnLeftDown()
*/
virtual void OnLeftDown(wxMouseEvent& event);
/*!
* \brief Event handler called when the canvas is double-clicked by
* the left mouse button. The function can be overrided if necessary.
*
* The function is called by the framework and provides basic functionality
* needed for proper management of displayed shape. It is necessary to call
* this function from overrided methods if the default canvas behaviour
* should be preserved.
* \param event Mouse event
* \sa _OnLeftDoubleClick()
*/
virtual void OnLeftDoubleClick(wxMouseEvent& event);
/*!
* \brief Event handler called when the left mouse button is released.
* The function can be overrided if necessary.
*
* The function is called by the framework and provides basic functionality
* needed for proper management of displayed shape. It is necessary to call
* this function from overrided methods if the default canvas behaviour
* should be preserved.
* \param event Mouse event
* \sa _OnLeftUp()
*/
virtual void OnLeftUp(wxMouseEvent& event);
/*!
* \brief Event handler called when the canvas is clicked by
* the right mouse button. The function can be overrided if necessary.
*
* The function is called by the framework and provides basic functionality
* needed for proper management of displayed shape. It is necessary to call
* this function from overrided methods if the default canvas behaviour
* should be preserved.
* \param event Mouse event
* \sa _OnRightDown()
*/
virtual void OnRightDown(wxMouseEvent& event);
/*!
* \brief Event handler called when the canvas is double-clicked by
* the right mouse button. The function can be overrided if necessary.
*
* The function is called by the framework and provides basic functionality
* needed for proper management of displayed shape. It is necessary to call
* this function from overrided methods if the default canvas behaviour
* should be preserved.
* \param event Mouse event
* \sa _OnRightDoubleClick()
*/
virtual void OnRightDoubleClick(wxMouseEvent& event);
/*!
* \brief Event handler called when the right mouse button is released.
* The function can be overrided if necessary.
*
* The function is called by the framework and provides basic functionality
* needed for proper management of displayed shape. It is necessary to call
* this function from overrided methods if the default canvas behaviour
* should be preserved.
* \param event Mouse event
* \sa _OnRightUp()
*/
virtual void OnRightUp(wxMouseEvent& event);
/*!
* \brief Event handler called when the mouse pointer is moved.
* The function can be overrided if necessary.
*
* The function is called by the framework and provides basic functionality
* needed for proper management of displayed shape. It is necessary to call
* this function from overrided methods if the default canvas behaviour
* should be preserved.
* \param event Mouse event
* \sa _OnMouseMove()
*/
virtual void OnMouseMove(wxMouseEvent& event);
/*!
* \brief Event handler called when the mouse wheel position is changed.
* The function can be overrided if necessary.
*
* The function is called by the framework and provides basic functionality
* needed for proper management of displayed shape. It is necessary to call
* this function from overrided methods if the default canvas behaviour
* should be preserved.
* \param event Mouse event
* \sa _OnMouseWheel()
*/
virtual void OnMouseWheel(wxMouseEvent& event);
/*!
* \brief Event handler called when any key is pressed.
* The function can be overrided if necessary.
*
* The function is called by the framework and provides basic functionality
* needed for proper management of displayed shape. It is necessary to call
* this function from overrided methods if the default canvas behaviour
* should be preserved.
* \param event Keyboard event
* \sa _OnKeyDown()
*/
virtual void OnKeyDown(wxKeyEvent& event);
/*!
* \brief Event handler called when any editable text shape is changed.
* The function can be overrided if necessary.
* The function is called by the framework and its default implementation
* generates wxEVT_SF_TEXT_CHANGE event.
* \param shape Changed wxSFEditTextShape object
* \sa wxSFEditTextShape::EditLabel(), wxSFShapeTextEvent
*/
virtual void OnTextChange(wxSFEditTextShape* shape);
/*!
* \brief Event handler called after successfull conection creation. The function
* can be overrided if necessary. The default implementation
* generates wxEVT_SF_LINE_DONE event.
* \param connection Pointer to new connection object
* \sa StartInteractiveConnection(), wxSFShapeEvent
*/
virtual void OnConnectionFinished(wxSFLineShape* connection);
/*!
* \brief Event handler called after successfull conection creation in
* order to alow developper to perform some kind of checks
* before the connection is really added to the diagram. The function
* can be overrided if necessary. The default implementation
* generates wxEVT_SF_LINE_DONE event.
* \param connection Pointer to new connection object
* \sa StartInteractiveConnection(), wxSFShapeEvent
* \return false if the generated event has been vetoed in this case,
* the connection creation is cancelled
*/
virtual bool OnPreConnectionFinished(wxSFLineShape* connection);
/*!
* \brief Event handler called by the framework after any dragged shapes
* are dropped to the canvas. The default implementation
* generates wxEVT_SF_ON_DROP event.
* \param x X-coordinate of a position the data was dropped to
* \param y Y-coordinate of a position the data was dropped to
* \param def Drag result
* \param dropped Reference to a list containing the dropped data
* \sa wxSFCanvasDropTarget, wxSFShapeDropEvent
*/
virtual void OnDrop(wxCoord x, wxCoord y, wxDragResult def, const ShapeList& dropped);
/*!
* \brief Event handler called by the framework after pasting of shapes
* from the clipboard to the canvas. The default implementation
* generates wxEVT_SF_ON_PASTE event.
* \param pasted Reference to a list containing the pasted data
* \sa wxSFShapeCanvas::Paste(), wxSFShapePasteEvent
*/
virtual void OnPaste(const ShapeList& pasted);
/*!
* \brief Event handler called if canvas virtual size is going to be updated.
* The default implementation does nothing but the function can be overrided by
* a user to modify calculated virtual canvas size.
* \param virtrct Calculated canvas virtual size
*/
virtual void OnUpdateVirtualSize(wxRect &virtrct);
protected:
// protected data members
MODE m_nWorkingMode;
wxSFCanvasSettings m_Settings;
static bool m_fEnableGC;
// protected functions
private:
// private data members
wxSFMultiSelRect m_shpMultiEdit;
static wxBitmap m_OutBMP;
bool m_fCanSaveStateOnMouseUp;
static int m_nRefCounter;
/*! \brief Flag used for determination whether the D&D operation has started and ended in one canvas instance */
bool m_fDnDStartedHere;
/*! \brief Started position of current D&D operation */
wxPoint m_nDnDStartedAt;
/*! \brief Custom data format object (used for the clipboard and D&D operations */
wxDataFormat m_formatShapes;
wxPoint m_nPrevMousePos;
wxRect m_nInvalidateRect;
/*! \brief Canvas history manager */
wxSFCanvasHistory m_CanvasHistory;
/*! \brief Pointer to parent data (shapes) manager */
wxSFDiagramManager* m_pManager;
/*! \brief Pointer to currently selected shape handle */
wxSFShapeHandle* m_pSelectedHandle;
/*! \brief Pointer to new line shape under constuction */
wxSFLineShape* m_pNewLineShape;
/*! \brief Pointer to topmost unselected shape under the mouse cursor */
wxSFShapeBase *m_pUnselectedShapeUnderCursor;
/*! \brief Pointer to topmost selected shape under the mouse cursor */
wxSFShapeBase *m_pSelectedShapeUnderCursor;
/*! \brief Pointer to topmost shape under the mouse cursor */
wxSFShapeBase *m_pTopmostShapeUnderCursor;
/*! \brief Current list of all shapes in the canvas updated during mouse movement */
ShapeList m_lstCurrentShapes;
// private functions
/*! \brief Validate selection so the shapes in the given list can be processed by the clipboard functions */
void ValidateSelectionForClipboard(ShapeList& selection);
/*! \brief Append connections assigned to shapes in given list to this list as well */
void AppendAssignedConnections(wxSFShapeBase *shape, ShapeList& selection, bool childrenonly);
/*! \brief Initialize printing framework */
void InitializePrinting();
/*! \brief Deinitialize prnting framework */
void DeinitializePrinting();
/*! \brief Remove given shape for temporary containers */
void RemoveFromTemporaries(wxSFShapeBase *shape);
/*! \brief Clear all temporary containers */
void ClearTemporaries();
/*! \brief Assign give shape to parent at given location (if exists) */
void ReparentShape(wxSFShapeBase *shape, const wxPoint& parentpos);
/*! \brief Propagate selection recursively to all parents if sfsPROPAGATE_SELECTION flag is set */
void PropagateSelection(wxSFShapeBase *shape, bool selection);
// private event handlers
/*!
* \brief Event handler called when the canvas should be repainted.
* \param event Paint event
*/
void _OnPaint(wxPaintEvent& event);
/*!
* \brief Event handler called when the canvas should be erased.
* \param event Erase event
*/
void _OnEraseBackground(wxEraseEvent& event);
/*!
* \brief Event handler called when the mouse pointer leaves the canvas window.
* \param event Mouse event
*/
void _OnLeaveWindow(wxMouseEvent& event);
/*!
* \brief Event handler called when the mouse pointer enters the canvas window.
* \param event Mouse event
*/
void _OnEnterWindow(wxMouseEvent& event);
/*!
* \brief Event handler called when the canvas size has changed.
* \param event Size event
*/
void _OnResize(wxSizeEvent& event);
// original private event handlers
/*!
* \brief Original private event handler called when the canvas is clicked by
* left mouse button. The handler calls user-overridable event handler function
* and skips the event for next possible processing.
* \param event Mouse event
* \sa wxSFShapeCanvas::OnLeftDown
*/
void _OnLeftDown(wxMouseEvent& event);
/*!
* \brief Original private event handler called when the canvas is double-clicked by
* left mouse button. The handler calls user-overridable event handler function
* and skips the event for next possible processing.
* \param event Mouse event
* \sa wxSFShapeCanvas::OnLeftDoubleClick
*/
void _OnLeftDoubleClick(wxMouseEvent& event);
/*!
* \brief Original private event handler called when the left mouse button
* is release above the canvas. The handler calls user-overridable event handler function
* and skips the event for next possible processing.
* \param event Mouse event
* \sa wxSFShapeCanvas::OnLeftUp
*/
void _OnLeftUp(wxMouseEvent& event);
/*!
* \brief Original private event handler called when the canvas is clicked by
* right mouse button. The handler calls user-overridable event handler function
* and skips the event for next possible processing.
* \param event Mouse event
* \sa wxSFShapeCanvas::OnRightDown
*/
void _OnRightDown(wxMouseEvent& event);
/*!
* \brief Original private event handler called when the canvas is double-clicked by
* right mouse button. The handler calls user-overridable event handler function
* and skips the event for next possible processing.
* \param event Mouse event
* \sa wxSFShapeCanvas::OnRightDoubleClick
*/
void _OnRightDoubleClick(wxMouseEvent& event);
/*!
* \brief Original private event handler called when the right mouse button
* is release above the canvas. The handler calls user-overridable event handler function
* and skips the event for next possible processing.
* \param event Mouse event
* \sa wxSFShapeCanvas::OnRightUp
*/
void _OnRightUp(wxMouseEvent& event);
/*!
* \brief Original private event handler called when the mouse pointer is moving above
* the canvas. The handler calls user-overridable event handler function
* and skips the event for next possible processing.
* \param event Mouse event
* \sa wxSFShapeCanvas::OnMouseMove
*/
void _OnMouseMove(wxMouseEvent& event);
/*!
* \brief Original private event handler called when the mouse wheel pocition is changed.
* The handler calls user-overridable event handler function and skips the event
* for next possible processing.
* \param event Mouse event
* \sa wxSFShapeCanvas::OnMouseWheel
*/
void _OnMouseWheel(wxMouseEvent& event);
/*!
* \brief Original private event handler called when any key is pressed.
* The handler calls user-overridable event handler function
* and skips the event for next possible processing.
* \param event Keyboard event
* \sa wxSFShapeCanvas::OnKeyDown
*/
void _OnKeyDown(wxKeyEvent& event);
/*!
* \brief Function is called by associated wxSFCanvasDropTarget after any dragged shapes
* are dropped to the canvas.
* \param x X-coordinate of a position the data was dropped to
* \param y Y-coordinate of a position the data was dropped to
* \param def Drag result
* \param data Pointer to a data object encapsulating dropped data
* \sa wxSFCanvasDropTarget
*/
void _OnDrop(wxCoord x, wxCoord y, wxDragResult def, wxDataObject *data);
DECLARE_EVENT_TABLE();
};
#endif //_WXSFSHAPECANVAS_H