Initial commit.

This commit is contained in:
2018-12-06 16:01:56 +01:00
parent 10867b60c2
commit 18eb3f6047
1011 changed files with 345688 additions and 10 deletions

View File

@@ -0,0 +1,80 @@
/***************************************************************
* Name: ArrowBase.cpp
* Purpose: Implements line arrow base class
* Author: Michal Bližňák (michal.bliznak@tiscali.cz)
* Created: 2007-07-22
* Copyright: Michal Bližňák
* License: wxWidgets license (www.wxwidgets.org)
* Notes:
**************************************************************/
#include "wx_pch.h"
#ifdef _DEBUG_MSVC
#define new DEBUG_NEW
#endif
#include "wx/wxsf/ArrowBase.h"
#include "wx/wxsf/LineShape.h"
#include "wx/wxsf/CommonFcn.h"
using namespace wxSFCommonFcn;
XS_IMPLEMENT_CLONABLE_CLASS(wxSFArrowBase, xsSerializable);
wxSFArrowBase::wxSFArrowBase(void)
{
m_pParentShape = NULL;
}
wxSFArrowBase::wxSFArrowBase(wxSFShapeBase* parent)
{
m_pParentShape = parent;
}
wxSFArrowBase::wxSFArrowBase(const wxSFArrowBase& obj)
: xsSerializable(obj)
{
m_pParentShape = obj.m_pParentShape;
}
wxSFArrowBase::~wxSFArrowBase(void)
{
}
//----------------------------------------------------------------------------------//
// public virtual functions
//----------------------------------------------------------------------------------//
void wxSFArrowBase::Draw(const wxRealPoint& from, const wxRealPoint& to, wxDC& dc)
{
// HINT: override it for custom drawing...
wxUnusedVar( from );
wxUnusedVar( to );
wxUnusedVar( dc );
}
//----------------------------------------------------------------------------------//
// protected functions
//----------------------------------------------------------------------------------//
void wxSFArrowBase::TranslateArrow(wxPoint *trg, const wxRealPoint *src, int n, const wxRealPoint &from, const wxRealPoint& to)
{
double cosa, sina, dist;
// calculate distance between line points
dist = Distance(from, to);
// calculate sin and cos of given line segment
sina = (from.y - to.y)/dist;
cosa = (from.x - to.x)/dist;
// rotate arrow
for(int i = 0; i<n; i++)
{
trg->x = (int)((src->x*cosa-src->y*sina)+to.x);
trg->y = (int)((src->x*sina+src->y*cosa)+to.y);
trg++;
src++;
}
}

View File

@@ -0,0 +1,269 @@
/***************************************************************
* Name: BitmapShape.cpp
* Purpose: Implements bitmap shape class
* Author: Michal Bližňák (michal.bliznak@tiscali.cz)
* Created: 2007-07-22
* Copyright: Michal Bližňák
* License: wxWidgets license (www.wxwidgets.org)
* Notes:
**************************************************************/
#include "wx_pch.h"
#ifdef _DEBUG_MSVC
#define new DEBUG_NEW
#endif
#include "wx/wxsf/BitmapShape.h"
#include "wx/wxsf/ShapeCanvas.h"
#include "wx/wxsf/CommonFcn.h"
#include "res/NoSource.xpm"
using namespace wxSFCommonFcn;
XS_IMPLEMENT_CLONABLE_CLASS(wxSFBitmapShape, wxSFRectShape);
wxSFBitmapShape::wxSFBitmapShape(void)
: wxSFRectShape()
{
m_sBitmapPath = wxT("");
m_fRescaleInProgress = false;
m_fCanScale = sfdvBITMAPSHAPE_SCALEIMAGE;
CreateFromXPM(NoSource_xpm);
// mark serialized properties
MarkSerializableDataMembers();
}
wxSFBitmapShape::wxSFBitmapShape(const wxRealPoint& pos, const wxString& bitmapPath, wxSFDiagramManager* manager)
: wxSFRectShape(pos, wxRealPoint(1, 1), manager)
{
m_sBitmapPath = wxT("");
m_fRescaleInProgress = false;
m_fCanScale = sfdvBITMAPSHAPE_SCALEIMAGE;
CreateFromFile(bitmapPath);
// mark serialized properties
MarkSerializableDataMembers();
}
wxSFBitmapShape::wxSFBitmapShape(const wxSFBitmapShape& obj)
: wxSFRectShape(obj)
{
m_sBitmapPath = obj.m_sBitmapPath;
m_fRescaleInProgress = false;
m_fCanScale = obj.m_fCanScale;
// create real bitmap copy
m_Bitmap = obj.m_Bitmap.GetSubBitmap(wxRect(0, 0, obj.m_Bitmap.GetWidth(), obj.m_Bitmap.GetHeight()));
m_OriginalBitmap = m_Bitmap;
// mark serialized properties
MarkSerializableDataMembers();
}
wxSFBitmapShape::~wxSFBitmapShape(void)
{
}
void wxSFBitmapShape::MarkSerializableDataMembers()
{
XS_SERIALIZE(m_sBitmapPath, wxT("path"));
XS_SERIALIZE_EX(m_fCanScale, wxT("scale_image"), sfdvBITMAPSHAPE_SCALEIMAGE);
}
//----------------------------------------------------------------------------------//
// public functions
//----------------------------------------------------------------------------------//
bool wxSFBitmapShape::CreateFromFile(const wxString& file, wxBitmapType type)
{
bool fSuccess = true;
// load bitmap from the file
//if((m_sBitmapPath != file) || (!m_Bitmap.IsOk()))
{
m_sBitmapPath = file;
if(wxFileExists(m_sBitmapPath))
{
fSuccess = m_Bitmap.LoadFile(m_sBitmapPath, type);
}
else
fSuccess = false;
}
if(!fSuccess)
{
m_Bitmap = wxBitmap(NoSource_xpm);
}
m_OriginalBitmap = m_Bitmap;
m_nRectSize.x = m_Bitmap.GetWidth();
m_nRectSize.y = m_Bitmap.GetHeight();
if(m_fCanScale)
{
AddStyle(sfsSIZE_CHANGE);
}
else
RemoveStyle(sfsSIZE_CHANGE);
return fSuccess;
}
bool wxSFBitmapShape::CreateFromXPM(const char* const* bits)
{
bool fSuccess = false;
m_sBitmapPath = wxT("");
// create bitmap from XPM
m_Bitmap = wxBitmap(bits);
fSuccess = m_Bitmap.IsOk();
if(!fSuccess)
{
m_Bitmap = wxBitmap(NoSource_xpm);
}
m_OriginalBitmap = m_Bitmap;
m_nRectSize.x = m_Bitmap.GetWidth();
m_nRectSize.y = m_Bitmap.GetHeight();
if(m_fCanScale)
{
AddStyle(sfsSIZE_CHANGE);
}
else
RemoveStyle(sfsSIZE_CHANGE);
return fSuccess;
}
//----------------------------------------------------------------------------------//
// public virtual functions
//----------------------------------------------------------------------------------//
void wxSFBitmapShape::Scale(double x, double y, bool children)
{
if(m_fCanScale)
{
m_nRectSize.x *= x;
m_nRectSize.y *= y;
if(!m_fRescaleInProgress) RescaleImage(m_nRectSize);
// call default function implementation (needed for scaling of shape's children)
wxSFShapeBase::Scale(x, y, children);
}
}
void wxSFBitmapShape::OnBeginHandle(wxSFShapeHandle& handle)
{
if(m_fCanScale)
{
m_fRescaleInProgress = true;
m_nPrevPos = GetAbsolutePosition();
}
wxSFShapeBase::OnBeginHandle(handle);
}
void wxSFBitmapShape::OnHandle(wxSFShapeHandle& handle)
{
if(m_fCanScale)
{
wxSFRectShape::OnHandle(handle);
}
else
RemoveStyle(sfsSIZE_CHANGE);
}
void wxSFBitmapShape::OnEndHandle(wxSFShapeHandle& handle)
{
if(m_fCanScale)
{
m_fRescaleInProgress = false;
RescaleImage(m_nRectSize);
}
wxSFShapeBase::OnEndHandle(handle);
}
//----------------------------------------------------------------------------------//
// protected functions
//----------------------------------------------------------------------------------//
void wxSFBitmapShape::RescaleImage(const wxRealPoint& size)
{
if( GetParentCanvas() )
{
wxImage image = m_OriginalBitmap.ConvertToImage();
if( wxSFShapeCanvas::IsGCEnabled() )
{
image.Rescale(int(size.x), int(size.y), wxIMAGE_QUALITY_NORMAL);
}
else
{
image.Rescale(int(size.x * GetParentCanvas()->GetScale()), int(size.y * GetParentCanvas()->GetScale()), wxIMAGE_QUALITY_NORMAL);
}
m_Bitmap = wxBitmap(image);
}
}
//----------------------------------------------------------------------------------//
// protected virtual functions
//----------------------------------------------------------------------------------//
void wxSFBitmapShape::DrawNormal(wxDC& dc)
{
// HINT: overload it for custom actions...
if(m_fRescaleInProgress)
{
dc.DrawBitmap(m_Bitmap, Conv2Point(m_nPrevPos));
dc.SetBrush(*wxTRANSPARENT_BRUSH);
dc.SetPen(wxPen(wxColour(100, 100, 100), 1, wxDOT));
dc.DrawRectangle(Conv2Point(GetAbsolutePosition()), Conv2Size(m_nRectSize));
dc.SetPen(wxNullPen);
dc.SetBrush(wxNullBrush);
}
else
dc.DrawBitmap(m_Bitmap, Conv2Point(GetAbsolutePosition()));
}
void wxSFBitmapShape::DrawHover(wxDC& dc)
{
// HINT: overload it for custom actions...
wxRealPoint pos = GetAbsolutePosition();
dc.DrawBitmap(m_Bitmap, Conv2Point(pos));
dc.SetPen(wxPen(m_nHoverColor, 1));
dc.SetBrush(*wxTRANSPARENT_BRUSH);
dc.DrawRectangle(Conv2Point(pos), Conv2Size(m_nRectSize));
dc.SetBrush(wxNullBrush);
dc.SetPen(wxNullPen);
}
void wxSFBitmapShape::DrawHighlighted(wxDC& dc)
{
// HINT: overload it for custom actions...
wxRealPoint pos = GetAbsolutePosition();
dc.DrawBitmap(m_Bitmap, Conv2Point(pos));
dc.SetPen(wxPen(m_nHoverColor, 2));
dc.SetBrush(*wxTRANSPARENT_BRUSH);
dc.DrawRectangle(Conv2Point(pos), Conv2Size(m_nRectSize));
dc.SetBrush(wxNullBrush);
dc.SetPen(wxNullPen);
}

View File

@@ -0,0 +1,59 @@
/***************************************************************
* Name: BitmapShapeXml.cpp
* Purpose: Implements bitmap shape's serialization capability
* Author: Michal Bližňák (michal.bliznak@tiscali.cz)
* Created: 2007-07-22
* Copyright: Michal Bližňák
* License: wxWidgets license (www.wxwidgets.org)
* Notes:
**************************************************************/
#include "wx_pch.h"
#ifdef _DEBUG_MSVC
#define new DEBUG_NEW
#endif
#include "wx/wxsf/BitmapShape.h"
#include "wx/wxsf/CommonFcn.h"
//----------------------------------------------------------------------------------//
// Serialization
//----------------------------------------------------------------------------------//
wxXmlNode* wxSFBitmapShape::Serialize(wxXmlNode* node)
{
// HINT: overload it for custom actions...
if(node)
{
node = wxSFRectShape::Serialize(node);
}
return node;
}
void wxSFBitmapShape::Deserialize(wxXmlNode* node)
{
// HINT: overload it for custom actions...
wxSFRectShape::Deserialize(node);
wxRealPoint prevSize = m_nRectSize;
if(!m_sBitmapPath.IsEmpty())
{
CreateFromFile(m_sBitmapPath);
}
if(m_fCanScale)
{
if(m_nRectSize != prevSize)
{
m_nRectSize = prevSize;
RescaleImage(prevSize);
}
else
Scale(1, 1);
}
}

View File

@@ -0,0 +1,176 @@
/***************************************************************
* Name: CanvasHistory.cpp
* Purpose: Implements manager for stored canvas states
* Author: Michal Bližňák (michal.bliznak@tiscali.cz)
* Created: 2007-07-22
* Copyright: Michal Bližňák
* License: wxWidgets license (www.wxwidgets.org)
* Notes:
**************************************************************/
#include "wx_pch.h"
#ifdef _DEBUG_MSVC
#define new DEBUG_NEW
#endif
#include <wx/mstream.h>
#include "wx/wxsf/CanvasHistory.h"
#include "wx/wxsf/ShapeCanvas.h"
wxSFCanvasHistory::wxSFCanvasHistory(MODE hmode)
{
m_nWorkingMode = hmode;
m_pParentCanvas = NULL;
m_pCurrentCanvasState = NULL;
m_nHistoryDepth = sfDEFAULT_MAX_CANVAS_STATES;
m_lstCanvasStates.DeleteContents(true);
}
wxSFCanvasHistory::wxSFCanvasHistory(wxSFShapeCanvas *canvas, MODE hmode)
{
wxASSERT(canvas);
m_nWorkingMode = hmode;
m_pParentCanvas = canvas;
m_pCurrentCanvasState = NULL;
m_nHistoryDepth = sfDEFAULT_MAX_CANVAS_STATES;
m_lstCanvasStates.DeleteContents(true);
}
wxSFCanvasHistory::~wxSFCanvasHistory(void)
{
Clear();
}
//----------------------------------------------------------------------------------//
// Public functions
//----------------------------------------------------------------------------------//
void wxSFCanvasHistory::SetMode(MODE hmode)
{
Clear();
m_nWorkingMode = hmode;
}
void wxSFCanvasHistory::Clear()
{
m_lstCanvasStates.Clear();
m_pCurrentCanvasState = NULL;
}
void wxSFCanvasHistory::SaveCanvasState()
{
wxASSERT(m_pParentCanvas);
wxASSERT(m_pParentCanvas->GetDiagramManager());
if( m_nWorkingMode == histUSE_CLONING )
{
if(m_pParentCanvas && m_pParentCanvas->GetDiagramManager())
{
// create temporal copy of current diagram manager
wxSFDiagramManager *pDataManager = (wxSFDiagramManager*)m_pParentCanvas->GetDiagramManager()->Clone();
if( !pDataManager ) return;
// delete all states newer than the current state
if( m_pCurrentCanvasState )
{
StateList::compatibility_iterator delnode = m_lstCanvasStates.GetLast();
while(delnode->GetData() != m_pCurrentCanvasState)
{
m_lstCanvasStates.DeleteNode(delnode);
delnode = m_lstCanvasStates.GetLast();
}
}
// create and append new canvas state
m_pCurrentCanvasState = new wxSFCanvasState(pDataManager);
m_lstCanvasStates.Append(m_pCurrentCanvasState);
// check the history bounds
if(m_lstCanvasStates.GetCount() > m_nHistoryDepth)
{
m_lstCanvasStates.DeleteNode(m_lstCanvasStates.GetFirst());
}
}
}
else if( m_nWorkingMode == histUSE_SERIALIZATION )
{
wxMemoryOutputStream outstream;
if(outstream.IsOk() && m_pParentCanvas && m_pParentCanvas->GetDiagramManager())
{
// serialize canvas to memory stream
m_pParentCanvas->GetDiagramManager()->SerializeToXml(outstream);
// delete all states newer than the current state
if( m_pCurrentCanvasState )
{
StateList::compatibility_iterator delnode = m_lstCanvasStates.GetLast();
while(delnode->GetData() != m_pCurrentCanvasState)
{
m_lstCanvasStates.DeleteNode(delnode);
delnode = m_lstCanvasStates.GetLast();
}
}
// create and append new canvas state
m_pCurrentCanvasState = new wxSFCanvasState(outstream.GetOutputStreamBuffer());
m_lstCanvasStates.Append(m_pCurrentCanvasState);
// check the history bounds
if(m_lstCanvasStates.GetCount() > m_nHistoryDepth)
{
m_lstCanvasStates.DeleteNode(m_lstCanvasStates.GetFirst());
}
}
}
}
void wxSFCanvasHistory::RestoreOlderState()
{
if( !m_pCurrentCanvasState ) return;
// move to previous canvas state and restore it if exists
StateList::compatibility_iterator node = m_lstCanvasStates.Find(m_pCurrentCanvasState)->GetPrevious();
if( node ) m_pCurrentCanvasState = node->GetData();
else
m_pCurrentCanvasState = NULL;
if( m_pCurrentCanvasState )
{
m_pCurrentCanvasState->Restore(m_pParentCanvas);
}
}
void wxSFCanvasHistory::RestoreNewerState()
{
if( !m_pCurrentCanvasState ) return;
// move to next canvas state and restore it if exists
StateList::compatibility_iterator node = m_lstCanvasStates.Find(m_pCurrentCanvasState)->GetNext();
if( node ) m_pCurrentCanvasState = node->GetData();
else
m_pCurrentCanvasState = NULL;
if( m_pCurrentCanvasState )
{
m_pCurrentCanvasState->Restore(m_pParentCanvas);
}
}
bool wxSFCanvasHistory::CanUndo()
{
return ((m_pCurrentCanvasState != NULL) && (m_pCurrentCanvasState != m_lstCanvasStates.GetFirst()->GetData()));
}
bool wxSFCanvasHistory::CanRedo()
{
return ((m_pCurrentCanvasState != NULL) && (m_pCurrentCanvasState != m_lstCanvasStates.GetLast()->GetData()));
}

View File

@@ -0,0 +1,83 @@
/***************************************************************
* Name: CanvasState.cpp
* Purpose: Implements container for stored canvas state
* Author: Michal Bližňák (michal.bliznak@tiscali.cz)
* Created: 2007-07-22
* Copyright: Michal Bližňák
* License: wxWidgets license (www.wxwidgets.org)
* Notes:
**************************************************************/
#include "wx_pch.h"
#ifdef _DEBUG_MSVC
#define new DEBUG_NEW
#endif
#include <wx/mstream.h>
#include "wx/wxsf/CanvasState.h"
#include "wx/wxsf/ShapeCanvas.h"
#include <wx/listimpl.cpp>
WX_DEFINE_LIST(StateList);
wxSFCanvasState::wxSFCanvasState(wxStreamBuffer *data)
{
// copy content of stream buffer to local memory buffer
if(data)
{
data->ResetBuffer();
m_dataBuffer.AppendData(data->GetBufferStart(), data->GetDataLeft());
m_dataBuffer.AppendByte(0);
}
m_pDataManager = NULL;
}
wxSFCanvasState::wxSFCanvasState(wxSFDiagramManager *data)
{
wxASSERT(data);
m_pDataManager = data;
}
wxSFCanvasState::~wxSFCanvasState(void)
{
if( m_pDataManager)
{
delete m_pDataManager;
}
}
//----------------------------------------------------------------------------------//
// Public functions
//----------------------------------------------------------------------------------//
void wxSFCanvasState::Restore(wxSFShapeCanvas* canvas)
{
wxASSERT(canvas);
wxASSERT(canvas->GetDiagramManager());
if( m_pDataManager )
{
// copy content of stored temporal data manager into the currently used one
canvas->GetDiagramManager()->CopyItems(*m_pDataManager);
canvas->Refresh(false);
}
else
{
// create input stream from local memory buffer
wxMemoryInputStream instream(m_dataBuffer.GetData(), m_dataBuffer.GetDataLen()-1);
// deserialize canvas content
if(instream.IsOk() && canvas && canvas->GetDiagramManager())
{
// clear all previous canvas content
canvas->GetDiagramManager()->Clear();
canvas->GetDiagramManager()->DeserializeFromXml(instream);
canvas->Refresh(false);
}
}
}

View File

@@ -0,0 +1,66 @@
/***************************************************************
* Name: SolidArrow.cpp
* Purpose: Implements solid arrow for line shapes
* Author: Michal Bližňák (michal.bliznak@tiscali.cz)
* Created: 2007-07-22
* Copyright: Michal Bližňák
* License: wxWidgets license (www.wxwidgets.org)
* Notes:
**************************************************************/
#include "wx_pch.h"
#ifdef _DEBUG_MSVC
#define new DEBUG_NEW
#endif
#include "wx/wxsf/CircleArrow.h"
#include "wx/wxsf/CommonFcn.h"
using namespace wxSFCommonFcn;
XS_IMPLEMENT_CLONABLE_CLASS(wxSFCircleArrow, wxSFSolidArrow);
wxSFCircleArrow::wxSFCircleArrow(void)
: wxSFSolidArrow()
{
m_nRadius = sfdvARROW_RADIUS;
XS_SERIALIZE_INT_EX( m_nRadius, wxT("radius"), sfdvARROW_RADIUS );
}
wxSFCircleArrow::wxSFCircleArrow(wxSFShapeBase* parent)
: wxSFSolidArrow(parent)
{
m_nRadius = sfdvARROW_RADIUS;
XS_SERIALIZE_INT_EX( m_nRadius, wxT("radius"), sfdvARROW_RADIUS );
}
wxSFCircleArrow::wxSFCircleArrow(const wxSFCircleArrow& obj)
: wxSFSolidArrow(obj)
{
m_nRadius = obj.m_nRadius;
XS_SERIALIZE_INT_EX( m_nRadius, wxT("radius"), sfdvARROW_RADIUS );
}
wxSFCircleArrow::~wxSFCircleArrow(void)
{
}
//----------------------------------------------------------------------------------//
// public virtual functions
//----------------------------------------------------------------------------------//
void wxSFCircleArrow::Draw(const wxRealPoint &from, const wxRealPoint &to, wxDC& dc)
{
wxUnusedVar(from);
dc.SetPen(m_Pen);
dc.SetBrush(m_Fill);
dc.DrawCircle( Conv2Point( to ), m_nRadius );
dc.SetBrush(wxNullBrush);
dc.SetPen(wxNullPen);
}

View File

@@ -0,0 +1,138 @@
/***************************************************************
* Name: CircleShape.cpp
* Purpose: Implements circle shape class
* Author: Michal Bližňák (michal.bliznak@tiscali.cz)
* Created: 2007-07-22
* Copyright: Michal Bližňák
* License: wxWidgets license (www.wxwidgets.org)
* Notes:
**************************************************************/
#include "wx_pch.h"
#ifdef _DEBUG_MSVC
#define new DEBUG_NEW
#endif
#include "wx/wxsf/CircleShape.h"
#include "wx/wxsf/CommonFcn.h"
#include "wx/wxsf/ShapeCanvas.h"
using namespace wxSFCommonFcn;
XS_IMPLEMENT_CLONABLE_CLASS(wxSFCircleShape, wxSFSquareShape);
wxSFCircleShape::wxSFCircleShape(void)
: wxSFSquareShape()
{
SetRectSize(50, 50);
}
wxSFCircleShape::wxSFCircleShape(const wxRealPoint& pos, double radius, wxSFDiagramManager* manager)
: wxSFSquareShape(pos, radius, manager)
{
}
wxSFCircleShape::wxSFCircleShape(const wxSFCircleShape& obj)
: wxSFSquareShape(obj)
{
}
wxSFCircleShape::~wxSFCircleShape()
{
}
//----------------------------------------------------------------------------------//
// public virtual functions
//----------------------------------------------------------------------------------//
wxRealPoint wxSFCircleShape::GetBorderPoint(const wxRealPoint& start, const wxRealPoint& end)
{
double dist = Distance(start, end);
wxRealPoint nCenter = GetAbsolutePosition() + wxRealPoint(m_nRectSize.x/2, m_nRectSize.y/2);
if(dist)
{
double srcDx = m_nRectSize.x/2*(end.x-start.x)/dist - (start.x-nCenter.x);
double srcDy = m_nRectSize.y/2*(end.y-start.y)/dist - (start.y-nCenter.y);
return wxRealPoint(start.x + srcDx, start.y + srcDy);
}
else
return nCenter;
}
bool wxSFCircleShape::Contains(const wxPoint& pos)
{
wxRealPoint center = GetAbsolutePosition() + wxRealPoint(m_nRectSize.x/2, m_nRectSize.y/2);
if(Distance(center, wxRealPoint(pos.x, pos.y)) <= m_nRectSize.x/2) return true;
else
return false;
}
//----------------------------------------------------------------------------------//
// protected virtual functions
//----------------------------------------------------------------------------------//
void wxSFCircleShape::DrawNormal(wxDC& dc)
{
// HINT: overload it for custom actions...
wxRealPoint pos = GetAbsolutePosition();
dc.SetPen(m_Border);
dc.SetBrush(m_Fill);
dc.DrawCircle(int(pos.x + m_nRectSize.x/2), int(pos.y + m_nRectSize.y/2), int(m_nRectSize.x/2));
dc.SetBrush(wxNullBrush);
dc.SetPen(wxNullPen);
}
void wxSFCircleShape::DrawHover(wxDC& dc)
{
// HINT: overload it for custom actions...
wxRealPoint pos = GetAbsolutePosition();
dc.SetPen(wxPen(m_nHoverColor, 1));
dc.SetBrush(m_Fill);
dc.DrawCircle(int(pos.x + m_nRectSize.x/2), int(pos.y + m_nRectSize.y/2), int(m_nRectSize.x/2));
dc.SetBrush(wxNullBrush);
dc.SetPen(wxNullPen);
}
void wxSFCircleShape::DrawHighlighted(wxDC& dc)
{
// HINT: overload it for custom actions...
wxRealPoint pos = GetAbsolutePosition();
dc.SetPen(wxPen(m_nHoverColor, 2));
dc.SetBrush(m_Fill);
dc.DrawCircle(int(pos.x + m_nRectSize.x/2), int(pos.y + m_nRectSize.y/2), int(m_nRectSize.x/2));
dc.SetBrush(wxNullBrush);
dc.SetPen(wxNullPen);
}
void wxSFCircleShape::DrawShadow(wxDC& dc)
{
// HINT: overload it for custom actions...
if( m_Fill.GetStyle() != wxTRANSPARENT )
{
wxRealPoint pos = GetAbsolutePosition();
dc.SetPen(*wxTRANSPARENT_PEN);
dc.SetBrush(GetParentCanvas()->GetShadowFill());
dc.DrawCircle(int(pos.x + m_nRectSize.x/2 + GetParentCanvas()->GetShadowOffset().x), int(pos.y + m_nRectSize.y/2 + GetParentCanvas()->GetShadowOffset().y), int(m_nRectSize.x/2));
dc.SetBrush(wxNullBrush);
dc.SetPen(wxNullPen);
}
}

View File

@@ -0,0 +1,117 @@
/***************************************************************
* Name: CommonFcn.cpp
* Purpose: Implements set of global (auxiliary) functions
* Author: Michal Bližňák (michal.bliznak@tiscali.cz)
* Created: 2007-07-22
* Copyright: Michal Bližňák
* License: wxWidgets license (www.wxwidgets.org)
* Notes:
**************************************************************/
#include "wx_pch.h"
#ifdef _DEBUG_MSVC
#define new DEBUG_NEW
#endif
#include <math.h>
#include <wx/tokenzr.h>
#include "wx/wxsf/CommonFcn.h"
namespace wxSFCommonFcn
{
//----------------------------------------------------------------------------------//
// conversion functions
//----------------------------------------------------------------------------------//
wxPoint Conv2Point(const wxRealPoint& pt)
{
return wxPoint((int)pt.x, (int)pt.y);
}
wxSize Conv2Size(const wxRealPoint& pt)
{
return wxSize((int)pt.x, (int)pt.y);
}
wxRealPoint Conv2RealPoint(const wxPoint& pt)
{
return wxRealPoint((double)pt.x, (double)pt.y);
}
//----------------------------------------------------------------------------------//
// graphical functions
//----------------------------------------------------------------------------------//
wxColour GetHybridColour(const wxColour &orig, const wxColour &modificator)
{
int r, g, b;
r = orig.Red() - (255 - modificator.Red())/20;
g = orig.Green() - (255 - modificator.Green())/20;
b = orig.Blue() - (255 - modificator.Blue())/20;
if(r < 0) r = 0;
if(g < 0) g = 0;
if(b < 0) b = 0;
return wxColour(r, g, b);
}
bool LinesIntersection(const wxRealPoint& from1, const wxRealPoint& to1, const wxRealPoint& from2, const wxRealPoint& to2, wxRealPoint& i)
{
double a1, b1, c1, a2, b2, c2, ka, kb;
// bug in GCC ???
volatile double xi, yi;
// create line 1 info
a1 = to1.y - from1.y;
b1 = from1.x - to1.x;
c1 = -a1*from1.x - b1*from1.y;
// create line 2 info
a2 = to2.y - from2.y;
b2 = from2.x - to2.x;
c2 = -a2*from2.x - b2*from2.y;
// check, whether the lines are parallel...
ka = a1 / a2;
kb = b1 / b2;
if(ka == kb) return false;
// find intersection point
#ifdef __WXMSW__
xi = floor(((b1*c2 - c1*b2) / (a1*b2 - a2*b1)) + 0.5);
yi = floor((-(a1*c2 - a2*c1) / (a1*b2 - a2*b1)) + 0.5);
#else
xi = (b1*c2 - c1*b2) / (a1*b2 - a2*b1);
yi = -(a1*c2 - a2*c1) / (a1*b2 - a2*b1);
#endif
if( ((from1.x - xi)*(xi - to1.x) >= 0) &&
((from2.x - xi)*(xi - to2.x) >= 0) &&
((from1.y - yi)*(yi - to1.y) >= 0) &&
((from2.y - yi)*(yi - to2.y) >= 0) )
{
i.x = xi;
i.y = yi;
return true;
}
else
return false;
}
double Distance(const wxRealPoint& pt1, const wxRealPoint& pt2)
{
return sqrt((pt2.x - pt1.x)*(pt2.x - pt1.x) + (pt2.y - pt1.y)*(pt2.y - pt1.y));
}
}
namespace wxSF
{
const double PI = 3.14159265;
}

View File

@@ -0,0 +1,404 @@
/***************************************************************
* Name: ControlShape.cpp
* Purpose: Implements GUI control shape class
* Author: Michal Bližňák (michal.bliznak@tiscali.cz)
* Created: 2008-04-30
* Copyright: Michal Bližňák
* License: wxWidgets license (www.wxwidgets.org)
* Notes:
**************************************************************/
#include "wx_pch.h"
#ifdef _DEBUG_MSVC
#define new DEBUG_NEW
#endif
#include "wx/wxsf/ControlShape.h"
#include "wx/wxsf/DiagramManager.h"
#include "wx/wxsf/ShapeCanvas.h"
XS_IMPLEMENT_CLONABLE_CLASS(wxSFControlShape, wxSFRectShape);
wxSFControlShape::wxSFControlShape() : wxSFRectShape()
{
m_pControl = NULL;
m_nProcessEvents = sfdvCONTROLSHAPE_PROCESSEVENTS;
m_ModFill = sfdvCONTROLSHAPE_MODFILL;
m_ModBorder = sfdvCONTROLSHAPE_MODBORDER;
m_nControlOffset = sfdvCONTROLSHAPE_CONTROLOFFSET;
m_pEventSink = new EventSink(this);
m_Fill = *wxTRANSPARENT_BRUSH;
m_Border = *wxTRANSPARENT_PEN;
MarkSerializableDataMembers();
}
wxSFControlShape::wxSFControlShape(wxWindow *ctrl, const wxRealPoint& pos, const wxRealPoint& size, wxSFDiagramManager* manager)
: wxSFRectShape(pos, size, manager)
{
SetControl(ctrl);
m_nProcessEvents = sfdvCONTROLSHAPE_PROCESSEVENTS;
m_ModFill = sfdvCONTROLSHAPE_MODFILL;
m_ModBorder = sfdvCONTROLSHAPE_MODBORDER;
m_nControlOffset = sfdvCONTROLSHAPE_CONTROLOFFSET;
m_pEventSink = new EventSink(this);
m_Fill = *wxTRANSPARENT_BRUSH;
m_Border = *wxTRANSPARENT_PEN;
MarkSerializableDataMembers();
}
wxSFControlShape::wxSFControlShape(const wxSFControlShape& obj)
: wxSFRectShape(obj)
{
m_pControl = NULL;
m_nProcessEvents = obj.m_nProcessEvents;
m_ModFill = obj.m_ModFill;
m_ModBorder = obj.m_ModBorder;
m_nControlOffset = obj.m_nControlOffset;
m_pEventSink = new EventSink(this);
MarkSerializableDataMembers();
}
wxSFControlShape::~wxSFControlShape()
{
if( m_pControl ) m_pControl->Destroy();
if( m_pEventSink ) delete m_pEventSink;
}
void wxSFControlShape::MarkSerializableDataMembers()
{
XS_SERIALIZE_EX(m_nProcessEvents, wxT("process_events"), sfdvCONTROLSHAPE_PROCESSEVENTS);
XS_SERIALIZE_EX(m_nControlOffset, wxT("offset"), sfdvCONTROLSHAPE_CONTROLOFFSET);
XS_SERIALIZE_EX(m_ModFill, wxT("modification_fill"), sfdvCONTROLSHAPE_MODFILL);
XS_SERIALIZE_EX(m_ModBorder, wxT("modification_border"), sfdvCONTROLSHAPE_MODBORDER);
}
//----------------------------------------------------------------------------------//
// public functions
//----------------------------------------------------------------------------------//
void wxSFControlShape::SetControl(wxWindow *ctrl, bool fit)
{
if( m_pControl ) m_pControl->Reparent( m_pPrevParent );
m_pControl = ctrl;
if( m_pControl )
{
m_pPrevParent = ctrl->GetParent();
if( m_pParentManager )
{
wxSFShapeCanvas *pCanvas = ((wxSFDiagramManager*)m_pParentManager)->GetShapeCanvas();
// reparent GUI control if necessary
if( pCanvas && ( (wxWindow*)pCanvas != m_pPrevParent ) ) m_pControl->Reparent( (wxWindow*)pCanvas );
// redirect mouse events to the event sink for their delayed processing
m_pControl->Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(EventSink::_OnMouseButton), NULL, m_pEventSink);
m_pControl->Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(EventSink::_OnMouseButton), NULL, m_pEventSink);
m_pControl->Connect(wxEVT_LEFT_UP, wxMouseEventHandler(EventSink::_OnMouseButton), NULL, m_pEventSink);
m_pControl->Connect(wxEVT_RIGHT_UP, wxMouseEventHandler(EventSink::_OnMouseButton), NULL, m_pEventSink);
m_pControl->Connect(wxEVT_LEFT_DCLICK, wxMouseEventHandler(EventSink::_OnMouseButton), NULL, m_pEventSink);
m_pControl->Connect(wxEVT_RIGHT_DCLICK, wxMouseEventHandler(EventSink::_OnMouseButton), NULL, m_pEventSink);
m_pControl->Connect(wxEVT_MOTION, wxMouseEventHandler(EventSink::_OnMouseMove), NULL, m_pEventSink);
m_pControl->Connect(wxEVT_KEY_DOWN, wxKeyEventHandler(EventSink::_OnKeyDown), NULL, m_pEventSink);
m_pControl->Connect(wxEVT_SIZE, wxSizeEventHandler(EventSink::_OnSize), NULL, m_pEventSink);
}
if( fit ) UpdateShape();
UpdateControl();
}
}
//----------------------------------------------------------------------------------//
// public virtual functions
//----------------------------------------------------------------------------------//
void wxSFControlShape::FitToChildren()
{
wxRect ctrlRct;
wxRect bbRct = GetBoundingBox();
if( m_pControl ) ctrlRct = wxRect(m_pControl->GetPosition(), m_pControl->GetSize());
else
ctrlRct = bbRct;
wxSFRectShape::FitToChildren();
if( bbRct.Intersects(ctrlRct) && !bbRct.Contains(ctrlRct) ) UpdateShape();
}
void wxSFControlShape::Scale(double x, double y, bool children)
{
wxSFRectShape::Scale(x, y, children);
UpdateControl();
}
void wxSFControlShape::MoveTo(double x, double y)
{
wxSFRectShape::MoveTo(x, y);
UpdateControl();
}
void wxSFControlShape::MoveBy(double x, double y)
{
wxSFRectShape::MoveBy(x, y);
UpdateControl();
}
void wxSFControlShape::OnBeginDrag(const wxPoint& pos)
{
wxUnusedVar( pos );
m_PrevFill = m_Fill;
m_Fill = m_ModFill;
if( m_pParentManager )
{
wxSFShapeCanvas *pCanvas = ((wxSFDiagramManager*)m_pParentManager)->GetShapeCanvas();
if( pCanvas )
{
m_nPrevStyle = pCanvas->GetStyle();
pCanvas->RemoveStyle(wxSFShapeCanvas::sfsDND);
}
}
if( m_pControl )
{
m_pControl->Hide();
m_pControl->Disconnect(wxEVT_SIZE, wxSizeEventHandler(EventSink::_OnSize), NULL, m_pEventSink);
}
wxSFShapeBase::OnBeginDrag(pos);
}
void wxSFControlShape::OnEndDrag(const wxPoint& pos)
{
m_Fill = m_PrevFill;
if( m_pParentManager )
{
wxSFShapeCanvas *pCanvas = ((wxSFDiagramManager*)m_pParentManager)->GetShapeCanvas();
if( pCanvas ) pCanvas->SetStyle(m_nPrevStyle);
}
UpdateControl();
if( m_pControl )
{
m_pControl->Connect(wxEVT_SIZE, wxSizeEventHandler(EventSink::_OnSize), NULL, m_pEventSink);
m_pControl->Show();
m_pControl->SetFocus();
}
wxSFShapeBase::OnEndDrag(pos);
}
void wxSFControlShape::OnBeginHandle(wxSFShapeHandle& handle)
{
m_PrevBorder = m_Border;
m_Border = m_ModBorder;
m_PrevFill = m_Fill;
m_Fill = m_ModFill;
if( m_pControl )
{
m_pControl->Hide();
m_pControl->Disconnect(wxEVT_SIZE, wxSizeEventHandler(EventSink::_OnSize), NULL, m_pEventSink);
}
// call default handler
wxSFRectShape::OnBeginHandle(handle);
}
void wxSFControlShape::OnHandle(wxSFShapeHandle& handle)
{
// call default handler
wxSFRectShape::OnHandle(handle);
UpdateControl();
}
void wxSFControlShape::OnEndHandle(wxSFShapeHandle& handle)
{
m_Border = m_PrevBorder;
m_Fill = m_PrevFill;
if( m_pControl )
{
m_pControl->Show();
m_pControl->SetFocus();
m_pControl->Connect(wxEVT_SIZE, wxSizeEventHandler(EventSink::_OnSize), NULL, m_pEventSink);
}
// call default handler
wxSFRectShape::OnEndHandle(handle);
}
void wxSFControlShape::Update()
{
wxSFShapeBase::Update();
UpdateControl();
}
//----------------------------------------------------------------------------------//
// protected functions
//----------------------------------------------------------------------------------//
void wxSFControlShape::UpdateControl()
{
if( m_pControl )
{
int x = 0, y = 0;
wxRect minBB = m_pControl->GetMinSize();
wxRect rctBB = GetBoundingBox().Deflate(m_nControlOffset, m_nControlOffset);
if( rctBB.GetWidth() < minBB.GetWidth() )
{
rctBB.SetWidth(minBB.GetWidth());
m_nRectSize.x = minBB.GetWidth() + 2*m_nControlOffset;
}
if( rctBB.GetHeight() < minBB.GetHeight() )
{
rctBB.SetHeight(minBB.GetHeight());
m_nRectSize.y = minBB.GetHeight() + 2*m_nControlOffset;
}
GetParentCanvas()->CalcUnscrolledPosition(0, 0, &x, &y);
// set the control's dimensions and position according to the parent control shape
m_pControl->SetSize(rctBB.GetWidth(), rctBB.GetHeight());
m_pControl->Move(rctBB.GetLeft() - x, rctBB.GetTop() - y);
}
}
void wxSFControlShape::UpdateShape()
{
if( m_pControl )
{
wxSize nCtrlSize = m_pControl->GetSize();
m_nRectSize.x = nCtrlSize.x + 2*m_nControlOffset;
m_nRectSize.y = nCtrlSize.y + 2*m_nControlOffset;
GetShapeManager()->GetShapeCanvas()->Refresh(false);
}
}
//----------------------------------------------------------------------------------//
// private functions
//----------------------------------------------------------------------------------//
//----------------------------------------------------------------------------------//
// EventSink class
//----------------------------------------------------------------------------------//
EventSink::EventSink()
{
m_pParentShape = NULL;
}
EventSink::EventSink(wxSFControlShape *parent)
{
wxASSERT(parent);
m_pParentShape = parent;
}
EventSink::~EventSink()
{
}
//----------------------------------------------------------------------------------//
// public functions
//----------------------------------------------------------------------------------//
void EventSink::_OnMouseButton(wxMouseEvent &event)
{
if( m_pParentShape->GetEventProcessing() & wxSFControlShape::evtMOUSE2CANVAS )
{
wxMouseEvent updatedEvent(event);
UpdateMouseEvent(updatedEvent);
SendEvent(updatedEvent);
}
// process the event also by an original handler if requested
if( m_pParentShape->GetEventProcessing() & wxSFControlShape::evtMOUSE2GUI ) event.Skip();
//m_pParentShape->GetControl()->SetFocus();
}
void EventSink::_OnMouseMove(wxMouseEvent &event)
{
if( m_pParentShape->GetEventProcessing() & wxSFControlShape::evtMOUSE2CANVAS )
{
wxMouseEvent updatedEvent(event);
UpdateMouseEvent(updatedEvent);
SendEvent(updatedEvent);
}
// process the event also by an original handler if requested
if( m_pParentShape->GetEventProcessing() & wxSFControlShape::evtMOUSE2GUI ) event.Skip();
}
void EventSink::_OnKeyDown(wxKeyEvent &event)
{
if( m_pParentShape->GetEventProcessing() & wxSFControlShape::evtKEY2CANVAS ) SendEvent(event);
// process the event also by an original handler if requested
if( m_pParentShape->GetEventProcessing() & wxSFControlShape::evtKEY2GUI ) event.Skip();
}
void EventSink::_OnSize(wxSizeEvent &event)
{
event.Skip();
m_pParentShape->UpdateShape();
}
//----------------------------------------------------------------------------------//
// protected functions
//----------------------------------------------------------------------------------//
void EventSink::SendEvent(wxEvent &event)
{
if( m_pParentShape && m_pParentShape->GetParentManager() )
{
wxSFShapeCanvas *pCanvas = ((wxSFDiagramManager*)m_pParentShape->GetParentManager())->GetShapeCanvas();
// send copy of the event to the shape canvas
if( pCanvas ) wxPostEvent( pCanvas, event );
}
}
void EventSink::UpdateMouseEvent(wxMouseEvent &event)
{
int x = 0, y = 0;
wxRealPoint nAbsPos = m_pParentShape->GetAbsolutePosition();
m_pParentShape->GetParentCanvas()->CalcUnscrolledPosition(0, 0, &x, &y);
event.m_x += ( (int)nAbsPos.x + m_pParentShape->GetControlOffset() - x );
event.m_y += ( (int)nAbsPos.y + m_pParentShape->GetControlOffset() - y );
}

View File

@@ -0,0 +1,283 @@
/***************************************************************
* Name: CurveShape.cpp
* Purpose: Implements curve shape class
* Author: Michal Bližňák (michal.bliznak@tiscali.cz)
* Created: 2007-07-22
* Copyright: Michal Bližňák
* License: wxWidgets license (www.wxwidgets.org)
* Notes:
**************************************************************/
#include "wx_pch.h"
#ifdef _DEBUG_MSVC
#define new DEBUG_NEW
#endif
#include <math.h>
#include "wx/wxsf/CurveShape.h"
#include "wx/wxsf/ShapeCanvas.h"
#include "wx/wxsf/CommonFcn.h"
using namespace wxSFCommonFcn;
XS_IMPLEMENT_CLONABLE_CLASS(wxSFCurveShape, wxSFLineShape);
wxSFCurveShape::wxSFCurveShape() : wxSFLineShape()
{
}
wxSFCurveShape::wxSFCurveShape(long src, long trg, const wxXS::RealPointList& path, wxSFDiagramManager* manager)
: wxSFLineShape(src, trg, path, manager)
{
}
wxSFCurveShape::wxSFCurveShape(const wxSFCurveShape& obj)
: wxSFLineShape(obj)
{
}
wxSFCurveShape::~wxSFCurveShape()
{
}
//----------------------------------------------------------------------------------//
// public virtual functions
//----------------------------------------------------------------------------------//
wxRect wxSFCurveShape::GetBoundingBox()
{
return wxSFLineShape::GetBoundingBox().Inflate(20, 20);
}
//----------------------------------------------------------------------------------//
// public functions
//----------------------------------------------------------------------------------//
wxRealPoint wxSFCurveShape::GetPoint(size_t segment, double offset)
{
if( segment <= m_lstPoints.GetCount() )
{
wxRealPoint A, B, C, D;
GetSegmentQuaternion( segment, A, B, C, D );
return Coord_Catmul_Rom_Kubika(A, B, C, D, offset);
}
else
return wxRealPoint();
}
//----------------------------------------------------------------------------------//
// protected virtual functions
//----------------------------------------------------------------------------------//
void wxSFCurveShape::DrawCompleteLine(wxDC& dc)
{
size_t i = 0;
wxRealPoint A, B, C, D;
switch(m_nMode)
{
case modeREADY:
{
// draw line segments
if( !m_lstPoints.IsEmpty() )
{
for( i = 0; i <= m_lstPoints.GetCount(); i++ )
{
GetSegmentQuaternion( i, A, B, C, D );
Catmul_Rom_Kubika(A, B, C, D, dc);
}
}
else
{
GetDirectLine( B, C );
dc.DrawLine( Conv2Point(B), Conv2Point(C) );
}
// draw target arrow
if( m_pTrgArrow ) m_pTrgArrow->Draw( B, C, dc);
GetLineSegment( 0, B, C );
// draw source arrow
if( m_pSrcArrow ) m_pSrcArrow->Draw(C, B, dc);
}
break;
case modeUNDERCONSTRUCTION:
{
// draw basic line parts
if( !m_lstPoints.IsEmpty() )
{
for( i = 0; i < m_lstPoints.GetCount(); i++ )
{
GetSegmentQuaternion( i, A, B, C, D );
Catmul_Rom_Kubika(A, B, C, D, dc);
}
}
// draw unfinished line segment if any (for interactive line creation)
dc.SetPen(wxPen(*wxBLACK, 1, wxDOT));
if( i )
{
dc.DrawLine(Conv2Point( C ), m_nUnfinishedPoint);
}
else if( m_nSrcShapeId != -1 )
{
// draw unfinished line segment if any (for interactive line creation)
dc.SetPen(wxPen(*wxBLACK, 1, wxDOT));
wxSFShapeBase* pSrcShape = GetShapeManager()->FindShape(m_nSrcShapeId);
if( pSrcShape )
{
if( pSrcShape->GetConnectionPoints().IsEmpty() )
{
dc.DrawLine( Conv2Point(pSrcShape->GetBorderPoint(pSrcShape->GetCenter(), Conv2RealPoint(m_nUnfinishedPoint))), m_nUnfinishedPoint );
}
else
dc.DrawLine( Conv2Point( GetModSrcPoint() ), m_nUnfinishedPoint );
}
dc.SetPen(wxNullPen);
}
dc.SetPen(wxNullPen);
}
break;
case modeSRCCHANGE:
{
// draw basic line parts
for( i = 1; i <= m_lstPoints.GetCount(); i++ )
{
GetSegmentQuaternion( i, A, B, C, D );
Catmul_Rom_Kubika(A, B, C, D, dc);
}
// draw linesegment being updated
dc.SetPen(wxPen(*wxBLACK, 1, wxDOT));
if( !m_lstPoints.IsEmpty() )
{
GetSegmentQuaternion( 0, A, B, C, D );
}
else
GetDirectLine( B, C );
dc.DrawLine(m_nUnfinishedPoint, Conv2Point(C));
dc.SetPen(wxNullPen);
}
break;
case modeTRGCHANGE:
{
// draw basic line parts
if( !m_lstPoints.IsEmpty() )
{
for( i = 0; i < m_lstPoints.GetCount(); i++ )
{
GetSegmentQuaternion( i, A, B, C, D );
Catmul_Rom_Kubika(A, B, C, D, dc);
}
}
else
C = GetSrcPoint();
// draw linesegment being updated
dc.SetPen(wxPen(*wxBLACK, 1, wxDOT));
dc.DrawLine(m_nUnfinishedPoint, Conv2Point(C));
dc.SetPen(wxNullPen);
}
break;
}
}
//----------------------------------------------------------------------------------//
// private functions
//----------------------------------------------------------------------------------//
void wxSFCurveShape::GetSegmentQuaternion(size_t segment, wxRealPoint& A, wxRealPoint& B, wxRealPoint& C, wxRealPoint& D)
{
static wxRealPoint quart[4];
wxXS::RealPointList::compatibility_iterator node;
int nIndex = 2 - segment;
if( ( nIndex - 1 ) >= 0 ) quart[ nIndex - 1 ] = GetSrcPoint();
if( ( nIndex - 2 ) >= 0 ) quart[ nIndex - 2 ] = GetModSrcPoint();
if( nIndex >= 0 ) node = m_lstPoints.Item( 0 );
else
{
node = m_lstPoints.Item( abs( nIndex ) );
nIndex = 0;
}
for( ; nIndex < 4; nIndex++ )
{
if( node )
{
quart[ nIndex ] = *node->GetData();
node = node->GetNext();
}
else
{
if( nIndex == 2 ) quart[ 2 ] = GetTrgPoint();
else if( nIndex == 3 )
{
if( m_nMode == modeUNDERCONSTRUCTION ) quart[ 3 ] = Conv2RealPoint( m_nUnfinishedPoint );
else if( m_nTrgShapeId != -1 ) quart[ 3 ] = GetModTrgPoint();
}
}
}
A = quart[0];
B = quart[1];
C = quart[2];
D = quart[3];
}
void wxSFCurveShape::Catmul_Rom_Kubika(const wxRealPoint& A, const wxRealPoint& B, const wxRealPoint& C, const wxRealPoint& D, wxDC& dc)
{
// the begginig of the curve is in the B point
wxRealPoint point0=B;
wxRealPoint point1;
int nOptimSteps = double(Distance(B, C)) / 10;
if( nOptimSteps < 10 ) nOptimSteps = 10;
// draw the curve
for(double t = 0; t <= (1 + (1.0f / nOptimSteps)); t += 1.0f / (nOptimSteps-1))
{
point1 = Coord_Catmul_Rom_Kubika(A,B,C,D,t);
dc.DrawLine((int)point0.x, (int)point0.y, (int)point1.x, (int)point1.y);
point0 = point1;
}
point1 = Coord_Catmul_Rom_Kubika(A,B,C,D,1);
dc.DrawLine((int)point0.x, (int)point0.y, (int)point1.x, (int)point1.y);
}
wxRealPoint wxSFCurveShape::Coord_Catmul_Rom_Kubika(const wxRealPoint& p1, const wxRealPoint& p2, const wxRealPoint& p3, const wxRealPoint& p4, double t)
{
double pom1, pom2;
double C1,C2,C3,C4;
wxRealPoint point;
// auxiliary variables
pom1 = t - 1;
pom2 = t * t;
// used polynoms
C1 = (-pom2*t + 2*pom2 - t) / 2;
C2 = (3*pom2*t - 5*pom2 + 2) / 2;
C3 = (-3*pom2*t + 4*pom2 +t) / 2;
C4 = pom1*pom2 / 2;
// calculation of curve point for t = <0,1>
point.x = C1*p1.x + C2*p2.x + C3*p3.x + C4*p4.x;
point.y = C1*p1.y + C2*p2.y + C3*p3.y + C4*p4.y;
//point.z = C1*p1.z + C2*p2.z + C3*p3.z + C4*p4.z;
return point;
}

View File

@@ -0,0 +1,827 @@
/***************************************************************
* Name: DiagramManager.cpp
* Purpose: Implements shape manager class
* Author: Michal Bližňák (michal.bliznak@tiscali.cz)
* Created: 2007-07-25
* Copyright: Michal Bližňák
* License: wxWidgets license (www.wxwidgets.org)
* Notes:
**************************************************************/
#include "wx_pch.h"
#ifdef _DEBUG_MSVC
#define new DEBUG_NEW
#endif
#include <wx/wfstream.h>
#include <wx/mstream.h>
#include <wx/listimpl.cpp>
#include "wx/wxsf/DiagramManager.h"
#include "wx/wxsf/ShapeCanvas.h"
#include "wx/wxsf/ControlShape.h"
#include "wx/wxsf/LineShape.h"
#include "wx/wxsf/GridShape.h"
using namespace wxSFCommonFcn;
// TODO: implement autolayout
// TODO: implement better line X ellipse check
WX_DEFINE_LIST(IDList);
XS_IMPLEMENT_CLONABLE_CLASS(wxSFDiagramManager, wxXmlSerializer);
wxSFDiagramManager::wxSFDiagramManager()
{
m_pShapeCanvas = NULL;
m_lstIDPairs.DeleteContents(true);
m_sSFVersion = wxT("1.12.4 beta");
SetSerializerOwner(wxT("wxShapeFramework"));
SetSerializerVersion(wxT("1.0"));
SetSerializerRootName(wxT("chart"));
}
wxSFDiagramManager::wxSFDiagramManager(const wxSFDiagramManager &obj)
: wxXmlSerializer(obj)
{
m_pShapeCanvas = NULL;
m_sSFVersion = obj.m_sSFVersion;
m_lstIDPairs.DeleteContents(true);
}
wxSFDiagramManager::~wxSFDiagramManager()
{
Clear();
}
//----------------------------------------------------------------------------------//
// Adding/removing shapes functions
//----------------------------------------------------------------------------------//
wxSFShapeBase* wxSFDiagramManager::AddShape(wxClassInfo* shapeInfo, bool saveState, wxSF::ERRCODE *err)
{
wxPoint shapePos;
if(m_pShapeCanvas)
{
wxRect crect = m_pShapeCanvas->GetClientRect();
shapePos = wxPoint((crect.GetRight() - crect.GetLeft())/2,
(crect.GetBottom() - crect.GetTop())/2);
}
wxSFShapeBase* pShape = AddShape(shapeInfo, shapePos, saveState, err);
return pShape;
}
wxSFShapeBase* wxSFDiagramManager::AddShape(wxClassInfo* shapeInfo, const wxPoint& pos, bool saveState, wxSF::ERRCODE *err)
{
wxASSERT( shapeInfo );
if( shapeInfo && IsShapeAccepted(shapeInfo->GetClassName()) )
{
// create shape object from class info
wxSFShapeBase *pShape = (wxSFShapeBase*)shapeInfo->CreateObject();
wxSFShapeBase *pParentShape = NULL;
// update given possition
wxPoint lpos = pos;
if( m_pShapeCanvas )
{
lpos = m_pShapeCanvas->FitPositionToGrid( m_pShapeCanvas->DP2LP(pos) );
}
// line shapes can be assigned to root only
if( !pShape->IsKindOf(CLASSINFO(wxSFLineShape)) ) pParentShape = GetShapeAtPosition(lpos);
if( pParentShape && pParentShape->IsChildAccepted(shapeInfo->GetClassName()) )
{
pShape = AddShape(pShape, (xsSerializable*)pParentShape, pos - Conv2Point( pParentShape->GetAbsolutePosition() ), sfINITIALIZE, saveState, err);
}
else
pShape = AddShape(pShape, GetRootItem(), pos, sfINITIALIZE, saveState, err);
if( pParentShape )pParentShape->Update();
return pShape;
}
else
{
if( err ) *err = wxSF::errNOT_ACCEPTED;
return NULL;
}
}
wxSFShapeBase* wxSFDiagramManager::AddShape(wxSFShapeBase* shape, xsSerializable* parent, const wxPoint& pos, bool initialize, bool saveState, wxSF::ERRCODE *err)
{
if(shape)
{
if( shape->IsKindOf(CLASSINFO(wxSFShapeBase)) && IsShapeAccepted(shape->GetClassInfo()->GetClassName()) )
{
if( m_pShapeCanvas )
{
wxPoint newPos = m_pShapeCanvas->FitPositionToGrid(m_pShapeCanvas->DP2LP(pos));
shape->SetRelativePosition( Conv2RealPoint(newPos) );
}
else
shape->SetRelativePosition( Conv2RealPoint(pos) );
// add parent shape to the data manager (serializer)
if(parent)
{
AddItem(parent, shape);
}
else
AddItem(GetRootItem(), shape);
// initialize added shape
if(initialize)
{
shape->CreateHandles();
if( m_pShapeCanvas )
{
shape->SetHoverColour(m_pShapeCanvas->GetHoverColour());
}
if(HasChildren(shape))
{
wxSFShapeBase* pChild;
ShapeList lstChildren;
// get shape's children (if exist)
shape->GetChildShapes(sfANY, lstChildren, sfRECURSIVE);
// initialize shape's children
ShapeList::compatibility_iterator node = lstChildren.GetFirst();
while(node)
{
pChild = (wxSFShapeBase*)node->GetData();
pChild->CreateHandles();
pChild->Update();
if( m_pShapeCanvas )
{
pChild->SetHoverColour(m_pShapeCanvas->GetHoverColour());
}
node = node->GetNext();
}
}
}
// reset scale of assigned shape canvas (if exists and it is necessary...)
if( m_pShapeCanvas && shape->IsKindOf( CLASSINFO(wxSFControlShape) ) )
{
m_pShapeCanvas->SetScale( 1 );
}
if( m_pShapeCanvas )
{
if( saveState )
{
m_pShapeCanvas->SaveCanvasState();
}
}
if( err ) *err = wxSF::errOK;
}
else
{
//wxMessageBox(wxString::Format(wxT("Unable to add '%s' class object to the canvas"), shape->GetClassInfo()->GetClassName()), wxT("ShapeFramework"), wxICON_WARNING);
delete shape;
shape = NULL;
if( err ) *err = wxSF::errNOT_ACCEPTED;
}
}
else if( err ) *err = wxSF::errINVALID_INPUT;
return shape;
}
wxSFShapeBase* wxSFDiagramManager::CreateConnection(long srcId, long trgId, bool saveState, wxSF::ERRCODE *err)
{
return CreateConnection(srcId, trgId, CLASSINFO(wxSFLineShape), saveState, err);
}
wxSFShapeBase* wxSFDiagramManager::CreateConnection(long srcId, long trgId, wxClassInfo *lineInfo, bool saveState, wxSF::ERRCODE *err)
{
wxSFShapeBase* pShape = AddShape(lineInfo, sfDONT_SAVE_STATE, err);
if(pShape)
{
wxSFLineShape *pLine = (wxSFLineShape*)pShape;
pLine->SetSrcShapeId(srcId);
pLine->SetTrgShapeId(trgId);
if( m_pShapeCanvas )
{
if(saveState)m_pShapeCanvas->SaveCanvasState();
pLine->Refresh();
}
}
return pShape;
}
wxSFShapeBase* wxSFDiagramManager::CreateConnection(long srcId, long trgId, wxSFLineShape *line, bool saveState, wxSF::ERRCODE *err)
{
wxSFShapeBase* pShape = AddShape(line, NULL, wxDefaultPosition, sfINITIALIZE, sfDONT_SAVE_STATE, err);
if(pShape)
{
wxSFLineShape *pLine = (wxSFLineShape*)pShape;
pLine->SetSrcShapeId(srcId);
pLine->SetTrgShapeId(trgId);
if( m_pShapeCanvas )
{
if(saveState)m_pShapeCanvas->SaveCanvasState();
pLine->Refresh();
}
}
return pShape;
}
void wxSFDiagramManager::RemoveShape(wxSFShapeBase* shape, bool refresh)
{
if(shape)
{
wxSFShapeBase *pParent = shape->GetParentShape();
// remove connected lines (to all children)
ShapeList lstChildren;
ShapeList lstConnections;
ShapeList lstRemovedConnections;
// get all shape's children
shape->GetChildShapes(sfANY, lstChildren, sfRECURSIVE);
lstChildren.Append(shape);
// retrieve all assigned lines
ShapeList::compatibility_iterator snode = lstChildren.GetFirst();
while(snode)
{
GetAssignedConnections(snode->GetData(), CLASSINFO(wxSFLineShape), wxSFShapeBase::lineBOTH, lstConnections);
snode = snode->GetNext();
}
// remove all assigne lines
ShapeList::compatibility_iterator node = lstConnections.GetFirst();
while(node)
{
// one connection may be used by the parent and also by his child
if(lstRemovedConnections.IndexOf(node->GetData()) == wxNOT_FOUND)
{
lstRemovedConnections.Append(node->GetData());
RemoveShape(node->GetData(), false);
}
node = node->GetNext();
}
// remove the shape also from m_lstCurrentShapes list
if( m_pShapeCanvas ) m_pShapeCanvas->RemoveFromTemporaries( shape );
// remove the shape
RemoveItem(shape);
if( pParent ) pParent->Update();
if( refresh && m_pShapeCanvas ) m_pShapeCanvas->Refresh(false);
}
}
void wxSFDiagramManager::RemoveShapes(const ShapeList& selection)
{
wxSFShapeBase* pShape;
ShapeList::compatibility_iterator node = selection.GetFirst();
while(node)
{
pShape = node->GetData();
// it is important to check whether double-linked shapes already exist before
// they are deleted
if(Contains(pShape))RemoveShape(pShape, false);
node = node->GetNext();
}
}
void wxSFDiagramManager::Clear()
{
RemoveAll();
if( m_pShapeCanvas )
{
m_pShapeCanvas->GetMultiselectionBox().Show(false);
m_pShapeCanvas->UpdateVirtualSize();
}
}
//----------------------------------------------------------------------------------//
// Serialization/deserialization functions
//----------------------------------------------------------------------------------//
bool wxSFDiagramManager::SerializeToXml(const wxString& file, bool withroot)
{
return wxXmlSerializer::SerializeToXml(file, withroot);
}
bool wxSFDiagramManager::SerializeToXml(wxOutputStream& outstream, bool withroot)
{
return wxXmlSerializer::SerializeToXml(outstream, withroot);
}
bool wxSFDiagramManager::DeserializeFromXml(const wxString& file)
{
bool fSuccess = false;
wxFileInputStream instream(file);
if(instream.IsOk())
{
if( m_pShapeCanvas) m_pShapeCanvas->ClearCanvasHistory();
fSuccess = DeserializeFromXml(instream);
if( m_pShapeCanvas) m_pShapeCanvas->SaveCanvasState();
}
else
wxMessageBox(wxT("Unable to initialize input stream."), wxT("ShapeFramework"), wxOK | wxICON_ERROR);
return fSuccess;
}
bool wxSFDiagramManager::DeserializeFromXml(wxInputStream& instream)
{
// load an XML file
try
{
wxXmlDocument xmlDoc;
xmlDoc.Load(instream);
wxXmlNode* root = xmlDoc.GetRoot();
if(root && (root->GetName() == wxT("chart")))
{
// read shape objects from XML recursively
DeserializeObjects(NULL, root);
return true;
}
else
wxMessageBox(wxT("Unknown file format."), wxT("ShapeFramework"), wxOK | wxICON_WARNING);
}
catch (...)
{
wxMessageBox(wxT("Unable to load XML file."), wxT("ShapeFramework"), wxOK | wxICON_ERROR);
}
return false;
}
void wxSFDiagramManager::DeserializeObjects(xsSerializable* parent, wxXmlNode* node)
{
_DeserializeObjects(parent, node);
// update IDs in connection lines and grids
UpdateConnections();
UpdateGrids();
m_lstIDPairs.Clear();
if( m_pShapeCanvas )
{
//m_pShapeCanvas->MoveShapesFromNegatives();
m_pShapeCanvas->UpdateVirtualSize();
}
}
void wxSFDiagramManager::_DeserializeObjects(xsSerializable* parent, wxXmlNode* node)
{
wxSFShapeBase *pShape;
wxXS::IntArray arrNewIDs;
SerializableList lstForUpdate;
wxXmlNode* shapeNode = node->GetChildren();
while(shapeNode)
{
if(shapeNode->GetName() == wxT("object"))
{
#if wxVERSION_NUMBER < 2900
pShape = AddShape((wxSFShapeBase*)wxCreateDynamicObject(shapeNode->GetPropVal(wxT("type"), wxT(""))), parent, wxPoint(0, 0), true, sfDONT_SAVE_STATE);
#else
pShape = AddShape((wxSFShapeBase*)wxCreateDynamicObject(shapeNode->GetAttribute(wxT("type"), wxT(""))), parent, wxPoint(0, 0), true, sfDONT_SAVE_STATE);
#endif
if(pShape)
{
// store new assigned ID
lstForUpdate.Append( pShape );
pShape->GetChildrenRecursively( NULL, lstForUpdate );
for( SerializableList::iterator it = lstForUpdate.begin(); it != lstForUpdate.end(); ++it )
{
arrNewIDs.Add( (*it)->GetId() );
}
// deserialize stored content
pShape->DeserializeObject(shapeNode);
// update handle in line shapes
if( pShape->IsKindOf( CLASSINFO(wxSFLineShape) ) )
{
pShape->CreateHandles();
m_lstLinesForUpdate.Append(pShape);
}
else if( pShape->IsKindOf( CLASSINFO(wxSFGridShape) ) )
{
m_lstGridsForUpdate.Append(pShape);
}
// store information about IDs' changes and re-assign shapes' IDs
int newId, i = 0;
for( SerializableList::iterator it = lstForUpdate.begin(); it != lstForUpdate.end(); ++it )
{
newId = arrNewIDs[i++];
if( newId != (*it)->GetId() )
{
m_lstIDPairs.Append( new IDPair((*it)->GetId(), newId) );
(*it)->SetId( newId );
}
}
// deserialize child objects
_DeserializeObjects(pShape, shapeNode);
arrNewIDs.Clear();
lstForUpdate.Clear();
}
else
{
// there are some unsupported shapes so the diagrams must be cleared because of possible damage
RemoveAll();
m_lstLinesForUpdate.Clear();
m_lstGridsForUpdate.Clear();
wxMessageBox( wxT("Deserialization couldn't be completed because not of all shapes are accepted."), wxT("wxShapeFramework"), wxOK | wxICON_WARNING );
return;
}
}
else if(shapeNode->GetName() == m_sRootName + wxT("_properties"))
{
m_pRoot->DeserializeObject(shapeNode->GetChildren());
}
shapeNode = shapeNode->GetNext();
}
}
//----------------------------------------------------------------------------------//
// Shape handling functions
//----------------------------------------------------------------------------------//
void wxSFDiagramManager::AcceptShape(const wxString& type)
{
if(m_arrAcceptedShapes.Index(type) == wxNOT_FOUND)
{
m_arrAcceptedShapes.Add(type);
}
}
bool wxSFDiagramManager::IsShapeAccepted(const wxString& type)
{
if( m_arrAcceptedShapes.Index(type) != wxNOT_FOUND )return true;
else if( m_arrAcceptedShapes.Index(wxT("All")) != wxNOT_FOUND )return true;
else
return false;
}
void wxSFDiagramManager::GetAssignedConnections(wxSFShapeBase* parent, wxClassInfo* shapeInfo, wxSFShapeBase::CONNECTMODE mode, ShapeList& lines)
{
wxSFLineShape* pLine;
if( parent->GetId() == -1 ) return;
SerializableList lstLines;
// lines are children of root item only so we have not to search recursively...
GetRootItem()->GetChildren( shapeInfo, lstLines );
if( !lstLines.IsEmpty() )
{
SerializableList::compatibility_iterator node = lstLines.GetFirst();
while(node)
{
pLine = (wxSFLineShape*)node->GetData();
switch(mode)
{
case wxSFShapeBase::lineSTARTING:
if( pLine->GetSrcShapeId() == parent->GetId() ) lines.Append(pLine);
break;
case wxSFShapeBase::lineENDING:
if( pLine->GetTrgShapeId() == parent->GetId() ) lines.Append(pLine);
break;
case wxSFShapeBase::lineBOTH:
if( ( pLine->GetSrcShapeId() == parent->GetId() ) ||
( pLine->GetTrgShapeId() == parent->GetId() ) ) lines.Append(pLine);
break;
}
node = node->GetNext();
}
}
}
void wxSFDiagramManager::GetShapes(wxClassInfo* shapeInfo, ShapeList& shapes, xsSerializable::SEARCHMODE mode)
{
GetItems(shapeInfo, (SerializableList&)shapes, mode);
}
wxSFShapeBase* wxSFDiagramManager::GetShapeAtPosition(const wxPoint& pos, int zorder, SEARCHMODE mode)
{
int nCounter = 0;
ShapeList m_lstSortedShapes;
wxSFShapeBase* pShape;
// sort shapes list in the way that the line shapes will be at the top of the list
ShapeList shapes;
GetShapes(CLASSINFO(wxSFShapeBase), shapes, xsSerializable::searchBFS);
ShapeList::compatibility_iterator node = shapes.GetFirst();
while(node)
{
pShape = node->GetData();
if(pShape->IsKindOf(CLASSINFO(wxSFLineShape)))
{
m_lstSortedShapes.Insert(pShape);
nCounter++;
}
else
m_lstSortedShapes.Insert(nCounter, pShape);
node = node->GetNext();
}
// find the topmost shape according to the given rules
nCounter = 1;
node = m_lstSortedShapes.GetFirst();
while(node)
{
pShape = (wxSFShapeBase*)node->GetData();
if(pShape->IsVisible() && pShape->IsActive() && pShape->Contains(pos))
{
switch(mode)
{
case searchSELECTED:
if(pShape->IsSelected())
{
if(nCounter == zorder)return pShape;
else
nCounter++;
}
break;
case searchUNSELECTED:
if(!pShape->IsSelected())
{
if(nCounter == zorder)return pShape;
else
nCounter++;
}
break;
case searchBOTH:
if(nCounter == zorder)return pShape;
else
nCounter++;
break;
}
}
node = node->GetNext();
}
return NULL;
}
void wxSFDiagramManager::GetShapesAtPosition(const wxPoint& pos, ShapeList& shapes)
{
shapes.Clear();
wxSFShapeBase *pShape;
ShapeList lstShapes;
GetShapes(CLASSINFO(wxSFShapeBase), lstShapes);
ShapeList::compatibility_iterator node = lstShapes.GetFirst();
while(node)
{
pShape = node->GetData();
if(pShape->IsVisible() && pShape->IsActive() && pShape->Contains(pos))shapes.Append(pShape);
node = node->GetNext();
}
}
void wxSFDiagramManager::GetShapesInside(const wxRect& rct, ShapeList& shapes)
{
shapes.Clear();
wxSFShapeBase* pShape;
ShapeList lstShapes;
GetShapes(CLASSINFO(wxSFShapeBase), lstShapes);
ShapeList::compatibility_iterator node = lstShapes.GetFirst();
while(node)
{
pShape = node->GetData();
if(pShape->IsVisible() && pShape->IsActive() && pShape->Intersects(rct))shapes.Append(pShape);
node = node->GetNext();
}
}
wxSFShapeBase* wxSFDiagramManager::FindShape(long id)
{
if(id == -1)return NULL;
else
return (wxSFShapeBase*)GetItem(id);
}
void wxSFDiagramManager::GetNeighbours(wxSFShapeBase* parent, ShapeList& neighbours, wxClassInfo *shapeInfo, wxSFShapeBase::CONNECTMODE condir, bool direct)
{
if(parent)
{
parent->GetNeighbours(neighbours, shapeInfo, condir, direct);
}
else
{
wxASSERT(GetRootItem());
wxSFShapeBase* pShape;
SerializableList::compatibility_iterator node = GetRootItem()->GetFirstChildNode();
while(node)
{
pShape = (wxSFShapeBase*)node->GetData();
pShape->GetNeighbours(neighbours, shapeInfo, condir, direct);
node = node->GetNext();
}
}
}
bool wxSFDiagramManager::HasChildren(wxSFShapeBase* parent)
{
if(parent->GetFirstChildNode())return true;
else
return false;
}
void wxSFDiagramManager::UpdateConnections()
{
if( !m_lstLinesForUpdate.IsEmpty() )
{
wxSFLineShape* pLine;
IDPair* pIDPair;
// now check ids
long oldSrcId, oldTrgId;
long newSrcId, newTrgId;
IDList::compatibility_iterator idnode;
ShapeList::compatibility_iterator node = m_lstLinesForUpdate.GetFirst();
while(node)
{
pLine = (wxSFLineShape*)node->GetData();
newSrcId = oldSrcId = pLine->GetSrcShapeId();
newTrgId = oldTrgId = pLine->GetTrgShapeId();
idnode = m_lstIDPairs.GetFirst();
while(idnode)
{
pIDPair = idnode->GetData();
/*if(pIDPair->m_nNewID != pIDPair->m_nOldID)
{*/
if(oldSrcId == pIDPair->m_nOldID) newSrcId = pIDPair->m_nNewID;
if(oldTrgId == pIDPair->m_nOldID) newTrgId = pIDPair->m_nNewID;
/*}*/
idnode = idnode->GetNext();
}
pLine->SetSrcShapeId(newSrcId);
pLine->SetTrgShapeId(newTrgId);
// check whether line's src and trg shapes really exists
if(!GetItem(pLine->GetSrcShapeId()) || !GetItem(pLine->GetTrgShapeId()))
{
RemoveItem(pLine);
}
node = node->GetNext();
}
m_lstLinesForUpdate.Clear();
}
}
void wxSFDiagramManager::UpdateGrids()
{
if( !m_lstGridsForUpdate.IsEmpty() )
{
// now check ids
wxSFGridShape* pGrid;
IDPair* pIDPair;
int nIndex;
IDList::compatibility_iterator idnode;
ShapeList::compatibility_iterator node = m_lstGridsForUpdate.GetFirst();
while(node)
{
pGrid = (wxSFGridShape*)node->GetData();
nIndex = wxNOT_FOUND;
idnode = m_lstIDPairs.GetFirst();
while(idnode)
{
pIDPair = idnode->GetData();
nIndex = pGrid->m_arrCells.Index( pIDPair->m_nOldID );
if( nIndex != wxNOT_FOUND ) pGrid->m_arrCells[ nIndex ] = pIDPair->m_nNewID;
idnode = idnode->GetNext();
}
// check whether grid's children really exists
for( size_t i = 0; i < pGrid->m_arrCells.GetCount(); )
{
if( !GetItem( pGrid->m_arrCells[i] ) ) pGrid->RemoveFromGrid( pGrid->m_arrCells[i] );
else
i++;
}
node = node->GetNext();
}
m_lstGridsForUpdate.Clear();
}
}
void wxSFDiagramManager::UpdateAll()
{
wxSFShapeBase *pShape;
ShapeList lstShapes;
GetShapes( CLASSINFO(wxSFShapeBase), lstShapes );
ShapeList::compatibility_iterator node = lstShapes.GetFirst();
while( node )
{
pShape = node->GetData();
// update only shapes withour children because the Update() function is called recursively on all parents
if( !HasChildren( pShape ) ) pShape->Update();
node = node->GetNext();
}
}
void wxSFDiagramManager::MoveShapesFromNegatives()
{
wxSFShapeBase *pShape;
wxRealPoint shapePos;
double minx = 0, miny = 0;
// find the maximal negative position value
ShapeList shapes;
GetShapes(CLASSINFO(wxSFShapeBase), shapes);
ShapeList::compatibility_iterator node = shapes.GetFirst();
while(node)
{
shapePos = node->GetData()->GetAbsolutePosition();
if(node == shapes.GetFirst())
{
minx = shapePos.x;
miny = shapePos.y;
}
else
{
if(shapePos.x < minx)minx = shapePos.x;
if(shapePos.y < miny)miny = shapePos.y;
}
node = node->GetNext();
}
// move all parents shape so they (and their children) will be located in the positive values only
if((minx < 0) || (miny < 0))
{
node = shapes.GetFirst();
while(node)
{
pShape = node->GetData();
if(pShape->GetParentShape() == NULL)
{
if(minx < 0)pShape->MoveBy(abs((int)minx), 0);
if(miny < 0)pShape->MoveBy(0, abs((int)miny));
}
node = node->GetNext();
}
}
}

View File

@@ -0,0 +1,58 @@
/***************************************************************
* Name: DiamondArrow.cpp
* Purpose: Implements diamond arrow for line shapes
* Author: Michal Bližňák (michal.bliznak@tiscali.cz)
* Created: 2009-04-18
* Copyright: Michal Bližňák
* License: wxWidgets license (www.wxwidgets.org)
* Notes:
**************************************************************/
#include "wx_pch.h"
#ifdef _DEBUG_MSVC
#define new DEBUG_NEW
#endif
#include "wx/wxsf/DiamondArrow.h"
// arrow shape
static const wxRealPoint arrow[4]={wxRealPoint(0,0), wxRealPoint(10,4), wxRealPoint(20,0), wxRealPoint(10,-4)};
XS_IMPLEMENT_CLONABLE_CLASS(wxSFDiamondArrow, wxSFSolidArrow);
wxSFDiamondArrow::wxSFDiamondArrow(void)
: wxSFSolidArrow()
{
}
wxSFDiamondArrow::wxSFDiamondArrow(wxSFShapeBase* parent)
: wxSFSolidArrow(parent)
{
}
wxSFDiamondArrow::wxSFDiamondArrow(const wxSFDiamondArrow& obj)
: wxSFSolidArrow(obj)
{
}
wxSFDiamondArrow::~wxSFDiamondArrow(void)
{
}
//----------------------------------------------------------------------------------//
// public virtual functions
//----------------------------------------------------------------------------------//
void wxSFDiamondArrow::Draw(const wxRealPoint &from, const wxRealPoint &to, wxDC& dc)
{
wxPoint rarrow[4];
TranslateArrow( rarrow, arrow, 4, from, to );
dc.SetPen(m_Pen);
dc.SetBrush(m_Fill);
dc.DrawPolygon(4, rarrow);
dc.SetBrush(wxNullBrush);
dc.SetPen(wxNullPen);
}

View File

@@ -0,0 +1,78 @@
/***************************************************************
* Name: DiamondShape.cpp
* Purpose: Implements diamond shape class
* Author: Michal Bližňák (michal.bliznak@tiscali.cz)
* Created: 2007-07-22
* Copyright: Michal Bližňák
* License: wxWidgets license (www.wxwidgets.org)
* Notes:
**************************************************************/
#include "wx_pch.h"
#ifdef _DEBUG_MSVC
#define new DEBUG_NEW
#endif
#include "wx/wxsf/DiamondShape.h"
#include "wx/wxsf/CommonFcn.h"
// diamond shape
const wxRealPoint diamond[4]={wxRealPoint(0,25), wxRealPoint(50,0), wxRealPoint(100, 25), wxRealPoint(50, 50)};
XS_IMPLEMENT_CLONABLE_CLASS(wxSFDiamondShape, wxSFPolygonShape);
wxSFDiamondShape::wxSFDiamondShape()
: wxSFPolygonShape()
{
EnablePropertySerialization(wxT("vertices"), false);
SetVertices(4, diamond);
}
wxSFDiamondShape::wxSFDiamondShape(const wxRealPoint& pos, wxSFDiagramManager* manager)
: wxSFPolygonShape(4, diamond, pos, manager)
{
EnablePropertySerialization(wxT("vertices"), false);
}
wxSFDiamondShape::wxSFDiamondShape(const wxSFDiamondShape& obj)
: wxSFPolygonShape(obj)
{
}
wxSFDiamondShape::~wxSFDiamondShape()
{
}
//----------------------------------------------------------------------------------//
// public virtual functions
//----------------------------------------------------------------------------------//
bool wxSFDiamondShape::Contains(const wxPoint& pos)
{
wxRect bbRct = this->GetBoundingBox();
if(!bbRct.Contains(pos))return false;
wxRealPoint center = GetCenter();
double k = ((double)bbRct.GetHeight()/2)/((double)bbRct.GetWidth()/2);
if(pos.x <= center.x)
{
// test left-top quadrant
if((pos.y <= center.y) && (pos.y >= (center.y - (pos.x - bbRct.GetLeft())*k))) return true;
// test left-bottom quadrant
if((pos.y >= center.y) && (pos.y <= (center.y + (pos.x - bbRct.GetLeft())*k))) return true;
}
else
{
// test right-top quadrant
if((pos.y <= center.y) && (pos.y >= (bbRct.GetTop() + (pos.x - center.x)*k))) return true;
// test left-bottom quadrant
if((pos.y >= center.y) && (pos.y <= (bbRct.GetBottom() - (pos.x - center.x)*k))) return true;
}
return false;
}

View File

@@ -0,0 +1,290 @@
/***************************************************************
* Name: EditTextShape.cpp
* Purpose: Implements editable text shape class
* Author: Michal Bližňák (michal.bliznak@tiscali.cz)
* Created: 2007-07-22
* Copyright: Michal Bližňák
* License: wxWidgets license (www.wxwidgets.org)
* Notes:
**************************************************************/
#include "wx_pch.h"
#ifdef _DEBUG_MSVC
#define new DEBUG_NEW
#endif
#include <wx/textctrl.h>
#include "wx/wxsf/EditTextShape.h"
#include "wx/wxsf/ShapeCanvas.h"
static int textCtrlId = wxNewId();
XS_IMPLEMENT_CLONABLE_CLASS(wxSFEditTextShape, wxSFTextShape);
BEGIN_EVENT_TABLE(wxSFContentCtrl, wxTextCtrl)
EVT_KILL_FOCUS(wxSFContentCtrl::OnKillFocus)
EVT_KEY_DOWN(wxSFContentCtrl::OnKeyDown)
END_EVENT_TABLE()
//----------------------------------------------------------------------------------//
// wxSFContentCtrl control class
//----------------------------------------------------------------------------------//
wxSFContentCtrl::wxSFContentCtrl(wxWindow* parent, wxWindowID id, wxSFEditTextShape* parentShape, const wxString& content, wxPoint pos, wxSize size, int style)
: wxTextCtrl(parent, id, content, pos, size, wxTE_PROCESS_ENTER | wxTE_PROCESS_TAB | wxNO_BORDER | style)
{
m_pParent = parent;
m_pParentShape = parentShape;
m_sPrevContent = content;
SetInsertionPointEnd();
if(m_pParentShape)
{
wxSFTextShape* pTextShape = (wxSFTextShape*)m_pParentShape;
// update the font size in accordance to the canvas scale
wxFont font = pTextShape->GetFont();
font.SetPointSize(int(font.GetPointSize() * m_pParentShape->GetParentCanvas()->GetScale()));
SetFont(font);
SetBackgroundColour(wxColour(200, 200, 200));
SetFocus();
}
}
void wxSFContentCtrl::OnKillFocus(wxFocusEvent& event)
{
wxUnusedVar( event );
//Quit();
}
void wxSFContentCtrl::OnKeyDown(wxKeyEvent& event)
{
switch(event.GetKeyCode())
{
case WXK_ESCAPE:
Quit( sfCANCEL_TEXT_CHANGES );
break;
case WXK_TAB:
Quit( sfAPPLY_TEXT_CHANGES );
break;
case WXK_RETURN:
// enter new line if SHIFT key was pressed together with the ENTER key
if( wxGetKeyState( WXK_SHIFT ) )
{
event.Skip();
}
else
Quit( sfAPPLY_TEXT_CHANGES );
break;
default:
event.Skip();
}
}
void wxSFContentCtrl::Quit(bool apply)
{
Hide();
if(m_pParentShape)
{
m_pParentShape->m_pTextCtrl = NULL;
m_pParentShape->SetStyle(m_pParentShape->m_nCurrentState);
// save canvas state if the textctrl content has changed...
if( apply && ( m_sPrevContent != GetValue() ) )
{
m_pParentShape->SetText(GetValue());
m_sPrevContent = GetValue();
// inform parent shape canvas about text change...
m_pParentShape->GetParentCanvas()->OnTextChange(m_pParentShape);
m_pParentShape->GetParentCanvas()->SaveCanvasState();
}
m_pParentShape->Update();
m_pParentShape->GetParentCanvas()->Refresh();
}
Destroy();
}
//----------------------------------------------------------------------------------//
// wxSFDetachedContentCtrl control class
//----------------------------------------------------------------------------------//
wxSFDetachedContentCtrl::wxSFDetachedContentCtrl( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxDialog( parent, id, title, pos, size, style )
{
this->SetSizeHints( wxSize( -1,-1 ), wxDefaultSize );
wxBoxSizer* mainSizer;
mainSizer = new wxBoxSizer( wxVERTICAL );
m_pText = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 350,100 ), wxTE_MULTILINE );
m_pText->SetMinSize( wxSize( 350,100 ) );
mainSizer->Add( m_pText, 1, wxALL|wxEXPAND, 5 );
wxStdDialogButtonSizer* buttonSizer;
wxButton* buttonSizerOK;
wxButton* buttonSizerCancel;
buttonSizer = new wxStdDialogButtonSizer();
buttonSizerOK = new wxButton( this, wxID_OK );
buttonSizer->AddButton( buttonSizerOK );
buttonSizerCancel = new wxButton( this, wxID_CANCEL );
buttonSizer->AddButton( buttonSizerCancel );
buttonSizer->Realize();
mainSizer->Add( buttonSizer, 0, wxALIGN_RIGHT|wxBOTTOM|wxRIGHT, 5 );
this->SetSizer( mainSizer );
this->Layout();
mainSizer->Fit( this );
this->Centre( wxBOTH );
}
wxSFDetachedContentCtrl::~wxSFDetachedContentCtrl()
{
}
//----------------------------------------------------------------------------------//
// wxSFEditTextShape shape class
//----------------------------------------------------------------------------------//
wxSFEditTextShape::wxSFEditTextShape(void)
: wxSFTextShape()
{
m_pTextCtrl = NULL;
m_fForceMultiline = sfdvEDITTEXTSHAPE_FORCEMULTILINE;
m_nEditType = sfdvEDITTEXTSHAPE_EDITTYPE;
XS_SERIALIZE_EX(m_fForceMultiline, wxT("multiline"), sfdvEDITTEXTSHAPE_FORCEMULTILINE);
XS_SERIALIZE_INT_EX(m_nEditType, wxT("edittype"), sfdvEDITTEXTSHAPE_EDITTYPE);
}
wxSFEditTextShape::wxSFEditTextShape(const wxRealPoint& pos, const wxString& txt, wxSFDiagramManager* manager)
: wxSFTextShape(pos, txt, manager)
{
m_pTextCtrl = NULL;
m_fForceMultiline = sfdvEDITTEXTSHAPE_FORCEMULTILINE;
m_nEditType = sfdvEDITTEXTSHAPE_EDITTYPE;
XS_SERIALIZE_EX(m_fForceMultiline, wxT("multiline"), sfdvEDITTEXTSHAPE_FORCEMULTILINE);
XS_SERIALIZE_INT_EX(m_nEditType, wxT("edittype"), sfdvEDITTEXTSHAPE_EDITTYPE);
}
wxSFEditTextShape::wxSFEditTextShape(const wxSFEditTextShape& obj)
: wxSFTextShape(obj)
{
m_pTextCtrl = NULL;
m_fForceMultiline = obj.m_fForceMultiline;
m_nEditType = obj.m_nEditType;
XS_SERIALIZE_EX(m_fForceMultiline, wxT("multiline"), sfdvEDITTEXTSHAPE_FORCEMULTILINE);
XS_SERIALIZE_INT_EX(m_nEditType, wxT("edittype"), sfdvEDITTEXTSHAPE_EDITTYPE);
}
wxSFEditTextShape::~wxSFEditTextShape(void)
{
if(m_pTextCtrl)delete m_pTextCtrl;
}
//----------------------------------------------------------------------------------//
// public functions
//----------------------------------------------------------------------------------//
void wxSFEditTextShape::EditLabel()
{
if( GetParentCanvas() )
{
int dx, dy;
wxRealPoint shpPos = GetAbsolutePosition();
double scale = GetParentCanvas()->GetScale();
GetParentCanvas()->CalcUnscrolledPosition(0, 0, &dx, &dy);
switch( m_nEditType )
{
case editINPLACE:
{
wxRect shpBB = GetBoundingBox();
int style = 0;
if( m_fForceMultiline || m_sText.Contains(wxT("\n")) )
{
style = wxTE_MULTILINE;
// set minimal control size
}
if( (m_sText == wxEmptyString) || ((style == wxTE_MULTILINE) && (shpBB.GetWidth() < 50)) )shpBB.SetWidth(50);
m_nCurrentState = GetStyle();
RemoveStyle(sfsSIZE_CHANGE);
m_pTextCtrl = new wxSFContentCtrl(GetParentCanvas(), textCtrlId, this, m_sText, wxPoint(int((shpPos.x * scale) - dx), int((shpPos.y * scale) - dy)), wxSize(int(shpBB.GetWidth() * scale), int(shpBB.GetHeight() * scale)), style);
}
break;
case editDIALOG:
{
wxString sPrevText = GetText();
wxSFDetachedContentCtrl m_pTextDlg( GetParentCanvas() );
//m_pTextDlg.Move( wxPoint(int((shpPos.x * scale) - dx), int((shpPos.y * scale) - dy)) );
m_pTextDlg.SetContent( sPrevText );
if( m_pTextDlg.ShowModal() == wxID_OK )
{
if( m_pTextDlg.GetContent() != sPrevText )
{
SetText( m_pTextDlg.GetContent() );
GetParentCanvas()->OnTextChange( this );
GetParentCanvas()->SaveCanvasState();
Update();
GetParentCanvas()->Refresh( false );
}
}
}
break;
default:
break;
}
}
}
//----------------------------------------------------------------------------------//
// public virtual functions
//----------------------------------------------------------------------------------//
void wxSFEditTextShape::OnLeftDoubleClick(const wxPoint& pos)
{
// HINT: override it if neccessary...
wxUnusedVar( pos );
EditLabel();
}
bool wxSFEditTextShape::OnKey(int key)
{
// HINT: override it if neccessary...
switch(key)
{
case WXK_F2:
if(IsActive() && IsVisible())
{
EditLabel();
}
break;
default:
break;
}
return wxSFShapeBase::OnKey(key);
}

View File

@@ -0,0 +1,138 @@
/***************************************************************
* Name: EllipseShape.cpp
* Purpose: Implements ellipse shape class
* Author: Michal Bližňák (michal.bliznak@tiscali.cz)
* Created: 2007-07-22
* Copyright: Michal Bližňák
* License: wxWidgets license (www.wxwidgets.org)
* Notes:
**************************************************************/
#include "wx_pch.h"
#ifdef _DEBUG_MSVC
#define new DEBUG_NEW
#endif
#include "wx/wxsf/EllipseShape.h"
#include "wx/wxsf/ShapeCanvas.h"
#include "wx/wxsf/CommonFcn.h"
using namespace wxSFCommonFcn;
XS_IMPLEMENT_CLONABLE_CLASS(wxSFEllipseShape, wxSFRectShape);
wxSFEllipseShape::wxSFEllipseShape(void)
:wxSFRectShape()
{
}
wxSFEllipseShape::wxSFEllipseShape(const wxRealPoint& pos, const wxRealPoint& size, wxSFDiagramManager* manager)
: wxSFRectShape(pos, size, manager)
{
}
wxSFEllipseShape::wxSFEllipseShape(const wxSFEllipseShape& obj)
: wxSFRectShape(obj)
{
}
wxSFEllipseShape::~wxSFEllipseShape()
{
}
//----------------------------------------------------------------------------------//
// public virtual functions
//----------------------------------------------------------------------------------//
wxRealPoint wxSFEllipseShape::GetBorderPoint(const wxRealPoint& start, const wxRealPoint& end)
{
double dist = Distance(start, end);
wxRealPoint nCenter = GetAbsolutePosition() + wxRealPoint(m_nRectSize.x/2, m_nRectSize.y/2);
if(dist)
{
double srcDx = m_nRectSize.x/2*(end.x-start.x)/dist - (start.x-nCenter.x);
double srcDy = m_nRectSize.y/2*(end.y-start.y)/dist - (start.y-nCenter.y);
return wxRealPoint(start.x + srcDx, start.y + srcDy);
}
else
return nCenter;
}
bool wxSFEllipseShape::Contains(const wxPoint& pos)
{
// HINT: overload it for custom actions...
double m, n, a, b;
wxRealPoint apos;
a = GetRectSize().x/2;
b = GetRectSize().y/2;
apos = GetAbsolutePosition();
m = apos.x + a;
n = apos.y + b;
if((((pos.x - m)*(pos.x - m))/(a*a) + ((pos.y - n)*(pos.y - n))/(b*b)) < 1)return true;
else
return false;
}
//----------------------------------------------------------------------------------//
// protected virtual functions
//----------------------------------------------------------------------------------//
void wxSFEllipseShape::DrawNormal(wxDC& dc)
{
// HINT: overload it for custom actions...
dc.SetPen(m_Border);
dc.SetBrush(m_Fill);
dc.DrawEllipse(Conv2Point(GetAbsolutePosition()), Conv2Size(m_nRectSize));
dc.SetBrush(wxNullBrush);
dc.SetPen(wxNullPen);
}
void wxSFEllipseShape::DrawHover(wxDC& dc)
{
// HINT: overload it for custom actions...
dc.SetPen(wxPen(m_nHoverColor, 1));
dc.SetBrush(m_Fill);
dc.DrawEllipse(Conv2Point(GetAbsolutePosition()), Conv2Size(m_nRectSize));
dc.SetBrush(wxNullBrush);
dc.SetPen(wxNullPen);
}
void wxSFEllipseShape::DrawHighlighted(wxDC& dc)
{
// HINT: overload it for custom actions...
dc.SetPen(wxPen(m_nHoverColor, 2));
dc.SetBrush(m_Fill);
dc.DrawEllipse(Conv2Point(GetAbsolutePosition()), Conv2Size(m_nRectSize));
dc.SetBrush(wxNullBrush);
dc.SetPen(wxNullPen);
}
void wxSFEllipseShape::DrawShadow(wxDC& dc)
{
// HINT: overload it for custom actions...
if( m_Fill.GetStyle() != wxTRANSPARENT )
{
dc.SetPen(*wxTRANSPARENT_PEN);
dc.SetBrush(GetParentCanvas()->GetShadowFill());
dc.DrawEllipse(Conv2Point(GetAbsolutePosition() + GetParentCanvas()->GetShadowOffset()), Conv2Size(m_nRectSize));
dc.SetBrush(wxNullBrush);
dc.SetPen(wxNullPen);
}
}

View File

@@ -0,0 +1,160 @@
/***************************************************************
* Name: FixedRectShape.cpp
* Purpose: Implements square shape class
* Author: Michal Bližňák (michal.bliznak@tiscali.cz)
* Created: 2007-07-22
* Copyright: Michal Bližňák
* License: wxWidgets license (www.wxwidgets.org)
* Notes:
**************************************************************/
#include "wx_pch.h"
#ifdef _DEBUG_MSVC
#define new DEBUG_NEW
#endif
#include "wx/wxsf/FixedRectShape.h"
XS_IMPLEMENT_CLONABLE_CLASS(wxSFSquareShape, wxSFRectShape);
wxSFSquareShape::wxSFSquareShape(void)
: wxSFRectShape()
{
SetRectSize(100, 100);
}
wxSFSquareShape::wxSFSquareShape(const wxRealPoint& pos, double size, wxSFDiagramManager* manager)
: wxSFRectShape(pos, wxRealPoint(size, size), manager)
{
}
wxSFSquareShape::wxSFSquareShape(const wxSFSquareShape& obj)
: wxSFRectShape(obj)
{
}
wxSFSquareShape::~wxSFSquareShape()
{
}
//----------------------------------------------------------------------------------//
// public virtual functions
//----------------------------------------------------------------------------------//
void wxSFSquareShape::Scale(double x, double y, bool children)
{
// HINT: overload it for custom actions...
if((x > 0) && (y > 0))
{
double s = 1;
if(x == 1) s = y;
else if (y == 1) s = x;
else if(x >= y) s = x;
else
s = y;
SetRectSize(m_nRectSize.x * s, m_nRectSize.y * s);
// call default function implementation (needed for scaling of shape's children)
wxSFShapeBase::Scale(x, y, children);
}
}
void wxSFSquareShape::OnHandle(wxSFShapeHandle& handle)
{
// HINT: overload it for custom actions...
double maxsize = 0, dx = 0, dy = 0;
wxRealPoint prevSize = m_nRectSize;
// perform standard operations
switch(handle.GetType())
{
case wxSFShapeHandle::hndLEFTTOP:
case wxSFShapeHandle::hndLEFT:
case wxSFShapeHandle::hndLEFTBOTTOM:
OnLeftHandle(handle);
break;
case wxSFShapeHandle::hndRIGHTTOP:
case wxSFShapeHandle::hndRIGHT:
case wxSFShapeHandle::hndRIGHTBOTTOM:
OnRightHandle(handle);
break;
case wxSFShapeHandle::hndTOP:
OnTopHandle(handle);
break;
case wxSFShapeHandle::hndBOTTOM:
OnBottomHandle(handle);
break;
default:
break;
}
// calculate common size and some auxilary values
if((prevSize.x < m_nRectSize.x) || (prevSize.y < m_nRectSize.y))
{
if(m_nRectSize.x >= m_nRectSize.y)maxsize = m_nRectSize.x;
else
maxsize = m_nRectSize.y;
}
else
{
if(m_nRectSize.x <= m_nRectSize.y)maxsize = m_nRectSize.x;
else
maxsize = m_nRectSize.y;
}
dx = maxsize - m_nRectSize.x;
dy = maxsize - m_nRectSize.y;
// normalize rect sizes
m_nRectSize.x = m_nRectSize.y = maxsize;
// move rect if neccessary
switch(handle.GetType())
{
case wxSFShapeHandle::hndLEFT:
MoveBy(-dx, -dy/2);
break;
case wxSFShapeHandle::hndLEFTTOP:
MoveBy(-dx, -dy);
break;
case wxSFShapeHandle::hndLEFTBOTTOM:
MoveBy(-dx, 0);
break;
case wxSFShapeHandle::hndRIGHT:
MoveBy(0, -dy/2);
break;
case wxSFShapeHandle::hndRIGHTTOP:
MoveBy(0, -dy);
break;
case wxSFShapeHandle::hndTOP:
MoveBy(-dx/2, -dy);
break;
case wxSFShapeHandle::hndBOTTOM:
MoveBy(-dx/2, 0);
break;
default:
break;
}
wxSFShapeBase::OnHandle( handle );
}

View File

@@ -0,0 +1,114 @@
/***************************************************************
* Name: FlexGridShape.cpp
* Purpose: Implements flexible grid shape class
* Author: Michal Bližňák (michal.bliznak@tiscali.cz)
* Created: 2008-09-27
* Copyright: Michal Bližňák
* License: wxWidgets license (www.wxwidgets.org)
* Notes:
**************************************************************/
#include "wx_pch.h"
#ifdef _DEBUG_MSVC
#define new DEBUG_NEW
#endif
#include "wx/wxsf/FlexGridShape.h"
XS_IMPLEMENT_CLONABLE_CLASS(wxSFFlexGridShape, wxSFGridShape);
wxSFFlexGridShape::wxSFFlexGridShape() : wxSFGridShape()
{
}
wxSFFlexGridShape::wxSFFlexGridShape(const wxRealPoint& pos, const wxRealPoint& size, int rows, int cols, int cellspace, wxSFDiagramManager* manager)
: wxSFGridShape(pos, size, rows, cols, cellspace, manager)
{
}
wxSFFlexGridShape::wxSFFlexGridShape(const wxSFFlexGridShape& obj) : wxSFGridShape(obj)
{
}
wxSFFlexGridShape::~wxSFFlexGridShape()
{
}
//----------------------------------------------------------------------------------//
// public virtual functions
//----------------------------------------------------------------------------------//
void wxSFFlexGridShape::DoChildrenLayout()
{
if( !m_nCols || !m_nRows ) return;
wxSFShapeBase *pShape;
int nIndex, nRow, nCol, nTotalX, nTotalY;
size_t i;
wxRect nCurrRect;
// initialize size arrays
m_arrRowSizes.SetCount( m_nRows );
m_arrColSizes.SetCount( m_nCols );
for( i = 0; i < (size_t)m_nRows; i++ ) m_arrRowSizes[i] = 0;
for( i = 0; i < (size_t)m_nCols; i++ ) m_arrColSizes[i] = 0;
nIndex = nCol = nTotalX = nTotalY = 0;
nRow = -1;
// prepare a storage for processed shapes pointers
m_arrChildShapes.SetCount( m_arrCells.GetCount() );
// get maximum size of all managed (child) shapes per row and collumn
for( i = 0; i < m_arrCells.GetCount(); i++ )
{
pShape = (wxSFShapeBase*)GetChild(m_arrCells[i]);
if( pShape )
{
// store used shape pointer for further processing (optimization for speed)
m_arrChildShapes[i] = pShape;
if( nIndex++ % m_nCols == 0 )
{
nCol = 0; nRow++;
}
else
nCol++;
nCurrRect = pShape->GetBoundingBox();
// update maximum rows and columns sizes
if( (pShape->GetHAlign() != halignEXPAND) && (nCurrRect.GetWidth() > m_arrColSizes[nCol]) ) m_arrColSizes[nCol] = nCurrRect.GetWidth();
if( (pShape->GetVAlign() != valignEXPAND) && (nCurrRect.GetHeight() > m_arrRowSizes[nRow]) ) m_arrRowSizes[nRow] = nCurrRect.GetHeight();
}
}
// put managed shapes to appropriate positions
nIndex = nCol = 0;
nRow = -1;
for( i = 0; i < m_arrCells.GetCount(); i++ )
{
pShape = m_arrChildShapes[i];
if( pShape )
{
if( nIndex++ % m_nCols == 0 )
{
nCol = 0; nTotalX = 0; nRow++;
if( nRow > 0 ) nTotalY += m_arrRowSizes[ nRow-1 ];
}
else
{
nCol++;
if( nCol > 0 ) nTotalX += m_arrColSizes[ nCol-1 ];
}
FitShapeToRect( pShape, wxRect( nTotalX + (nCol+1)*m_nCellSpace,
nTotalY + (nRow+1)*m_nCellSpace,
m_arrColSizes[ nCol ], m_arrRowSizes[ nRow ] ) );
}
}
}

View File

@@ -0,0 +1,171 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<wxFormBuilder_Project>
<FileVersion major="1" minor="9" />
<object class="Project" expanded="1">
<property name="class_decoration"></property>
<property name="code_generation">C++</property>
<property name="disconnect_events">1</property>
<property name="encoding">UTF-8</property>
<property name="event_generation">connect</property>
<property name="event_handler">impl_virtual</property>
<property name="file">wxsfdetachedcontentctrl</property>
<property name="first_id">1000</property>
<property name="help_provider">none</property>
<property name="internationalize">1</property>
<property name="name">wxSFDetachedContentCtrl</property>
<property name="namespace"></property>
<property name="path">.</property>
<property name="precompiled_header"></property>
<property name="relative_path">1</property>
<property name="use_enum">0</property>
<property name="use_microsoft_bom">0</property>
<object class="Dialog" expanded="1">
<property name="bg"></property>
<property name="center">wxBOTH</property>
<property name="context_help"></property>
<property name="enabled">1</property>
<property name="extra_style"></property>
<property name="fg"></property>
<property name="font"></property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="maximum_size"></property>
<property name="minimum_size">-1,-1</property>
<property name="name">wxSFDetachedContentCtrl</property>
<property name="pos"></property>
<property name="size">-1,-1</property>
<property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
<property name="subclass"></property>
<property name="title">Edit content...</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnActivate"></event>
<event name="OnActivateApp"></event>
<event name="OnChar"></event>
<event name="OnClose"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnHibernate"></event>
<event name="OnIconize"></event>
<event name="OnIdle"></event>
<event name="OnInitDialog"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">mainSizer</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL|wxEXPAND</property>
<property name="proportion">1</property>
<object class="wxTextCtrl" expanded="1">
<property name="bg"></property>
<property name="context_help"></property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="font"></property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="maximum_size"></property>
<property name="maxlength">0</property>
<property name="minimum_size">350,100</property>
<property name="name">m_pText</property>
<property name="permission">protected</property>
<property name="pos"></property>
<property name="size">350,100</property>
<property name="style">wxTE_MULTILINE</property>
<property name="subclass"></property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="value"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnText"></event>
<event name="OnTextEnter"></event>
<event name="OnTextMaxLen"></event>
<event name="OnTextURL"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALIGN_RIGHT|wxBOTTOM|wxRIGHT</property>
<property name="proportion">0</property>
<object class="wxStdDialogButtonSizer" expanded="1">
<property name="Apply">0</property>
<property name="Cancel">1</property>
<property name="ContextHelp">0</property>
<property name="Help">0</property>
<property name="No">0</property>
<property name="OK">1</property>
<property name="Save">0</property>
<property name="Yes">0</property>
<property name="minimum_size"></property>
<property name="name">buttonSizer</property>
<property name="permission">none</property>
<event name="OnApplyButtonClick"></event>
<event name="OnCancelButtonClick"></event>
<event name="OnContextHelpButtonClick"></event>
<event name="OnHelpButtonClick"></event>
<event name="OnNoButtonClick"></event>
<event name="OnOKButtonClick"></event>
<event name="OnSaveButtonClick"></event>
<event name="OnYesButtonClick"></event>
</object>
</object>
</object>
</object>
</object>
</wxFormBuilder_Project>

View File

@@ -0,0 +1,389 @@
/***************************************************************
* Name: GridShape.cpp
* Purpose: Implements grid shape class
* Author: Michal Bližňák (michal.bliznak@tiscali.cz)
* Created: 2008-08-02
* Copyright: Michal Bližňák
* License: wxWidgets license (www.wxwidgets.org)
* Notes:
**************************************************************/
#include "wx_pch.h"
#ifdef _DEBUG_MSVC
#define new DEBUG_NEW
#endif
#include "wx/wxsf/GridShape.h"
#include "wx/wxsf/LineShape.h"
XS_IMPLEMENT_CLONABLE_CLASS(wxSFGridShape, wxSFRectShape);
wxSFGridShape::wxSFGridShape() : wxSFRectShape()
{
m_nRows = sfdvGRIDSHAPE_ROWS;
m_nCols = sfdvGRIDSHAPE_COLS;
m_nCellSpace = sfdvGRIDSHAPE_CELLSPACE;
RemoveStyle(sfsSIZE_CHANGE);
MarkSerializableDataMembers();
}
wxSFGridShape::wxSFGridShape(const wxRealPoint& pos, const wxRealPoint& size, int rows, int cols, int cellspace, wxSFDiagramManager* manager)
: wxSFRectShape(pos, size, manager)
{
m_nRows = rows;
m_nCols = cols;
m_nCellSpace = cellspace;
RemoveStyle(sfsSIZE_CHANGE);
m_arrCells.Alloc( rows * cols );
MarkSerializableDataMembers();
}
wxSFGridShape::wxSFGridShape(const wxSFGridShape& obj) : wxSFRectShape(obj)
{
m_nRows = obj.m_nRows;
m_nCols = obj.m_nCols;
m_nCellSpace = obj.m_nCellSpace;
RemoveStyle(sfsSIZE_CHANGE);
m_arrCells.Clear();
WX_APPEND_ARRAY(m_arrCells, obj.m_arrCells);
MarkSerializableDataMembers();
}
wxSFGridShape::~wxSFGridShape()
{
}
void wxSFGridShape::MarkSerializableDataMembers()
{
XS_SERIALIZE_EX(m_nRows, wxT("rows"), sfdvGRIDSHAPE_ROWS);
XS_SERIALIZE_EX(m_nCols, wxT("cols"), sfdvGRIDSHAPE_COLS);
XS_SERIALIZE_EX(m_nCellSpace, wxT("cell_space"), sfdvGRIDSHAPE_CELLSPACE);
XS_SERIALIZE(m_arrCells, wxT("cells"));
}
//----------------------------------------------------------------------------------//
// public functions
//----------------------------------------------------------------------------------//
void wxSFGridShape::SetDimensions(int rows, int cols)
{
wxASSERT(rows);
wxASSERT(cols);
if( !(rows * cols) ) return;
m_nRows = rows;
m_nCols = cols;
m_arrCells.Alloc( rows * cols );
}
void wxSFGridShape::GetDimensions(int *rows, int *cols)
{
*rows = m_nRows;
*cols = m_nCols;
}
void wxSFGridShape::ClearGrid()
{
m_nRows = 0;
m_nCols = 0;
m_arrCells.Clear();
}
bool wxSFGridShape::AppendToGrid(wxSFShapeBase *shape)
{
int row = m_arrCells.GetCount() / m_nCols;
int col = m_arrCells.GetCount() - row*m_nCols;
return InsertToGrid( row, col, shape );
}
bool wxSFGridShape::InsertToGrid(int row, int col, wxSFShapeBase *shape)
{
wxASSERT(shape);
if( shape && shape->IsKindOf(CLASSINFO(wxSFShapeBase)) && IsChildAccepted(shape->GetClassInfo()->GetClassName()) )
{
// protect duplicated occurences
if( m_arrCells.Index(shape->GetId()) != wxNOT_FOUND) return false;
// protect unbounded horizontal index (grid can grow in a vertical direction only)
if( col >= m_nCols ) return false;
// add the shape to the children list if neccessary
if( GetChildrenList().IndexOf(shape) == wxNOT_FOUND )
{
shape->Reparent(this);
}
m_arrCells.SetCount(row * m_nCols + col + 1);
m_arrCells[row * m_nCols + col] = shape->GetId();
if( m_nRows <= row ) m_nRows = row + 1;
return true;
}
return false;
}
bool wxSFGridShape::InsertToGrid(int index, wxSFShapeBase *shape)
{
wxASSERT(shape);
if( shape && shape->IsKindOf(CLASSINFO(wxSFShapeBase)) && IsChildAccepted(shape->GetClassInfo()->GetClassName()) )
{
// protect duplicated occurences
if( m_arrCells.Index(shape->GetId()) != wxNOT_FOUND) return false;
// protect unbounded index
if( index >= (m_nRows * m_nCols) ) return false;
// add the shape to the children list if neccessary
if( GetChildrenList().IndexOf(shape) == wxNOT_FOUND )
{
shape->Reparent(this);
}
m_arrCells.SetCount(index + 1);
m_arrCells.Insert(shape->GetId(), index);
return true;
}
return false;
}
wxSFShapeBase* wxSFGridShape::GetManagedShape(size_t index)
{
if( (index >= 0) && (index < GetChildrenList().GetCount()) )
{
return (wxSFShapeBase*) GetChild( m_arrCells[index] );
}
else
return NULL;
}
wxSFShapeBase* wxSFGridShape::GetManagedShape(int row, int col)
{
if( (row >= 0) && (row < m_nRows) && (col >=0) && (col < m_nCols) )
{
return GetManagedShape( row * m_nCols + col );
}
else
return NULL;
}
void wxSFGridShape::RemoveFromGrid(long id)
{
if( m_arrCells.Index( id ) != wxNOT_FOUND )
{
m_arrCells.Remove( id );
}
}
//----------------------------------------------------------------------------------//
// public virtual functions
//----------------------------------------------------------------------------------//
void wxSFGridShape::DoChildrenLayout()
{
if( !m_nCols || !m_nRows ) return;
wxSFShapeBase *pShape;
int nIndex, nRow, nCol;
//wxRealPoint nAbsPos = GetAbsolutePosition();
wxRect currRect, maxRect = wxRect(0,0,0,0);
// get maximum size of all managed (child) shapes
SerializableList::compatibility_iterator node = GetFirstChildNode();
while(node)
{
pShape = (wxSFShapeBase*)node->GetData();
currRect = pShape->GetBoundingBox();
if( (pShape->GetHAlign() != halignEXPAND) && (currRect.GetWidth() > maxRect.GetWidth()) ) maxRect.SetWidth(currRect.GetWidth());
if( (pShape->GetVAlign() != valignEXPAND) && (currRect.GetHeight() > maxRect.GetHeight()) ) maxRect.SetHeight(currRect.GetHeight());
node = node->GetNext();
}
// put managed shapes to appropriate positions
nIndex = nCol = 0;
nRow = -1;
for(size_t i = 0; i < m_arrCells.GetCount(); i++ )
{
pShape = (wxSFShapeBase*) GetChild(m_arrCells[i]);
if( pShape )
{
if( nIndex++ % m_nCols == 0 )
{
nCol = 0; nRow++;
}
else
nCol++;
FitShapeToRect( pShape, wxRect( nCol*maxRect.GetWidth() + (nCol+1)*m_nCellSpace,
nRow*maxRect.GetHeight() + (nRow+1)*m_nCellSpace,
maxRect.GetWidth(), maxRect.GetHeight() ) );
}
}
}
void wxSFGridShape::Update()
{
wxSFShapeBase *pShape;
// check an existence of already assigned shapes
for(size_t i = 0; i < m_arrCells.GetCount(); )
{
if( !GetChild(m_arrCells[i])) m_arrCells.RemoveAt(i);
else
i++;
}
// check whether all child shapes' IDs are present in the cells array...
SerializableList::compatibility_iterator node = GetFirstChildNode();
while(node)
{
pShape = (wxSFShapeBase*)node->GetData();
if( m_arrCells.Index(pShape->GetId()) == wxNOT_FOUND ) m_arrCells.Add(pShape->GetId());
node = node->GetNext();
}
// do self-alignment
DoAlignment();
// do alignment of shape's children
this->DoChildrenLayout();
// fit the shape to its children
this->FitToChildren();
// do it recursively on all parent shapes
if( GetParentShape() )GetParentShape()->Update();
}
void wxSFGridShape::FitToChildren()
{
// HINT: overload it for custom actions...
wxSFShapeBase* pChild;
// get bounding box of the shape and children set be inside it
wxRealPoint nAbsPos = GetAbsolutePosition();
wxRect chBB = wxRect(nAbsPos.x, nAbsPos.y, 0, 0);
SerializableList::compatibility_iterator node = GetFirstChildNode();
while(node)
{
pChild = (wxSFShapeBase*)node->GetData();
if( pChild->GetStyle() & sfsALWAYS_INSIDE )
{
pChild->GetCompleteBoundingBox(chBB, bbSELF | bbCHILDREN);
}
node = node->GetNext();
}
// do not let the grid shape 'disappear' due to zero sizes...
if( (!chBB.GetWidth() || !chBB.GetHeight()) && !m_nCellSpace )
{
chBB.SetWidth( 10 );
chBB.SetHeight( 10 );
}
m_nRectSize = wxRealPoint(chBB.GetSize().x + 2*m_nCellSpace, chBB.GetSize().y + 2*m_nCellSpace);
}
void wxSFGridShape::OnChildDropped(const wxRealPoint& pos, wxSFShapeBase *child)
{
wxASSERT(child);
wxUnusedVar( pos );
if( child && !child->IsKindOf(CLASSINFO(wxSFLineShape)) ) AppendToGrid( child );
}
//----------------------------------------------------------------------------------//
// protected functions
//----------------------------------------------------------------------------------//
void wxSFGridShape::FitShapeToRect(wxSFShapeBase *shape, const wxRect& rct)
{
wxRect shapeBB = shape->GetBoundingBox();
wxRealPoint prevPos = shape->GetRelativePosition();
// do vertical alignment
switch( shape->GetVAlign() )
{
case valignTOP:
shape->SetRelativePosition( prevPos.x, rct.GetTop() + shape->GetVBorder() );
break;
case valignMIDDLE:
shape->SetRelativePosition( prevPos.x, rct.GetTop() + (rct.GetHeight()/2 - shapeBB.GetHeight()/2) );
break;
case valignBOTTOM:
shape->SetRelativePosition( prevPos.x, rct.GetBottom() - shapeBB.GetHeight() - shape->GetVBorder() );
break;
case valignEXPAND:
if( shape->ContainsStyle( sfsSIZE_CHANGE ) )
{
shape->SetRelativePosition( prevPos.x, rct.GetTop() + shape->GetVBorder() );
shape->Scale( 1.f, double(rct.GetHeight() - 2*shape->GetVBorder())/shapeBB.GetHeight() );
}
break;
default:
shape->SetRelativePosition( prevPos.x, rct.GetTop() );
break;
}
prevPos = shape->GetRelativePosition();
// do horizontal alignment
switch( shape->GetHAlign() )
{
case halignLEFT:
shape->SetRelativePosition( rct.GetLeft() + shape->GetHBorder(), prevPos.y );
break;
case halignCENTER:
shape->SetRelativePosition( rct.GetLeft() + (rct.GetWidth()/2 - shapeBB.GetWidth()/2), prevPos.y );
break;
case halignRIGHT:
shape->SetRelativePosition( rct.GetRight() - shapeBB.GetWidth() - shape->GetHBorder(), prevPos.y );
break;
case halignEXPAND:
if( shape->ContainsStyle( sfsSIZE_CHANGE ) )
{
shape->SetRelativePosition( rct.GetLeft() + shape->GetHBorder(), prevPos.y );
shape->Scale( double(rct.GetWidth() - 2*shape->GetHBorder())/shapeBB.GetWidth(), 1.f );
}
break;
default:
shape->SetRelativePosition( rct.GetLeft(), prevPos.y );
break;
}
}

View File

@@ -0,0 +1,927 @@
/***************************************************************
* Name: LineShape.cpp
* Purpose: Implements line shape class
* Author: Michal Bližňák (michal.bliznak@tiscali.cz)
* Created: 2007-07-22
* Copyright: Michal Bližňák
* License: wxWidgets license (www.wxwidgets.org)
* Notes:
**************************************************************/
#include "wx_pch.h"
#ifdef _DEBUG_MSVC
#define new DEBUG_NEW
#endif
#include "wx/wxsf/LineShape.h"
#include "wx/wxsf/ShapeCanvas.h"
#include "wx/wxsf/CommonFcn.h"
using namespace wxSFCommonFcn;
XS_IMPLEMENT_CLONABLE_CLASS(wxSFLineShape, wxSFShapeBase);
// arrow shape
const wxRealPoint arrow[3]={wxRealPoint(0,0), wxRealPoint(10,4), wxRealPoint(10,-4)};
wxSFLineShape::wxSFLineShape(void)
{
m_nSrcShapeId = sfdvLINESHAPE_UNKNOWNID;
m_nTrgShapeId = sfdvLINESHAPE_UNKNOWNID;
m_pSrcArrow = NULL;
m_pTrgArrow = NULL;
m_nSrcPoint = sfdvLINESHAPE_DEFAULTPOINT;
m_nTrgPoint = sfdvLINESHAPE_DEFAULTPOINT;
m_nDockPoint = sfdvLINESHAPE_DOCKPOINT;
m_Pen = sfdvLINESHAPE_PEN;
m_nSrcOffset = m_nTrgOffset = sfdvLINESHAPE_OFFSET;
m_nMode = modeREADY;
m_fStandAlone = sfdvLINESHAPE_STANDALONE;
MarkSerializableDataMembers();
m_lstPoints.DeleteContents(true);
}
wxSFLineShape::wxSFLineShape(long src, long trg, const wxXS::RealPointList& path, wxSFDiagramManager* manager)
: wxSFShapeBase(wxRealPoint(0, 0), manager)
{
m_nSrcShapeId = src;
m_nTrgShapeId = trg;
m_nDockPoint = sfdvLINESHAPE_DOCKPOINT;
m_pSrcArrow = NULL;
m_pTrgArrow = NULL;
m_nSrcPoint = sfdvLINESHAPE_DEFAULTPOINT;
m_nTrgPoint = sfdvLINESHAPE_DEFAULTPOINT;
m_Pen = sfdvLINESHAPE_PEN;
m_nSrcOffset = m_nTrgOffset = sfdvLINESHAPE_OFFSET;
m_nMode = modeREADY;
m_fStandAlone = false;
wxXS::RealPointList::compatibility_iterator node = path.GetFirst();
while(node)
{
m_lstPoints.Append(new wxRealPoint(*node->GetData()));
node = node->GetNext();
}
MarkSerializableDataMembers();
m_lstPoints.DeleteContents(true);
}
wxSFLineShape::wxSFLineShape(const wxRealPoint& src, const wxRealPoint& trg, const wxXS::RealPointList& path, wxSFDiagramManager* manager)
: wxSFShapeBase(wxRealPoint(0, 0), manager)
{
m_nSrcShapeId = sfdvLINESHAPE_UNKNOWNID;
m_nTrgShapeId = sfdvLINESHAPE_UNKNOWNID;
m_nDockPoint = sfdvLINESHAPE_DOCKPOINT;
m_pSrcArrow = NULL;
m_pTrgArrow = NULL;
m_nSrcPoint = src;
m_nTrgPoint = trg;
m_Pen = sfdvLINESHAPE_PEN;
m_nSrcOffset = m_nTrgOffset = sfdvLINESHAPE_OFFSET;
m_nMode = modeREADY;
m_fStandAlone = true;
wxXS::RealPointList::compatibility_iterator node = path.GetFirst();
while(node)
{
m_lstPoints.Append(new wxRealPoint(*node->GetData()));
node = node->GetNext();
}
MarkSerializableDataMembers();
m_lstPoints.DeleteContents(true);
}
wxSFLineShape::wxSFLineShape(const wxSFLineShape& obj)
: wxSFShapeBase(obj)
{
m_nSrcShapeId = obj.m_nSrcShapeId;
m_nTrgShapeId = obj.m_nTrgShapeId;
m_nDockPoint = obj.m_nDockPoint;
m_nSrcOffset = obj.m_nSrcOffset;
m_nTrgOffset = obj.m_nTrgOffset;
m_nSrcPoint = obj.m_nSrcPoint;
m_nTrgPoint = obj.m_nTrgPoint;
if(obj.m_pSrcArrow)
{
m_pSrcArrow = (wxSFArrowBase*)obj.m_pSrcArrow->Clone();
}
else
m_pSrcArrow = NULL;
if(obj.m_pTrgArrow)
{
m_pTrgArrow = (wxSFArrowBase*)obj.m_pTrgArrow->Clone();
}
else
m_pTrgArrow = NULL;
m_Pen = obj.m_Pen;
m_nMode = obj.m_nMode;
m_fStandAlone = obj.m_fStandAlone;
wxXS::RealPointList::compatibility_iterator node = obj.m_lstPoints.GetFirst();
while(node)
{
m_lstPoints.Append(new wxRealPoint(*node->GetData()));
node = node->GetNext();
}
MarkSerializableDataMembers();
m_lstPoints.DeleteContents(true);
}
wxSFLineShape::~wxSFLineShape(void)
{
m_lstPoints.Clear();
if(m_pSrcArrow)delete m_pSrcArrow;
if(m_pTrgArrow)delete m_pTrgArrow;
}
void wxSFLineShape::MarkSerializableDataMembers()
{
XS_SERIALIZE_EX(m_nSrcShapeId, wxT("source"), sfdvLINESHAPE_UNKNOWNID);
XS_SERIALIZE_EX(m_nTrgShapeId, wxT("target"), sfdvLINESHAPE_UNKNOWNID);
XS_SERIALIZE_EX(m_nSrcPoint, wxT("source_point"), sfdvLINESHAPE_DEFAULTPOINT);
XS_SERIALIZE_EX(m_nTrgPoint, wxT("target_point"), sfdvLINESHAPE_DEFAULTPOINT);
XS_SERIALIZE_EX(m_fStandAlone, wxT("standalone"), sfdvLINESHAPE_STANDALONE);
XS_SERIALIZE_DYNAMIC_OBJECT(m_pSrcArrow, wxT("source_arrow"));
XS_SERIALIZE_DYNAMIC_OBJECT(m_pTrgArrow, wxT("target_arrow"));
XS_SERIALIZE_EX(m_nSrcOffset, wxT("source_offset"), sfdvLINESHAPE_OFFSET);
XS_SERIALIZE_EX(m_nTrgOffset, wxT("target_offset"), sfdvLINESHAPE_OFFSET);
XS_SERIALIZE_LONG_EX(m_nDockPoint, wxT("dock_point"), sfdvLINESHAPE_DOCKPOINT);
XS_SERIALIZE_EX(m_Pen, wxT("line_style"), sfdvLINESHAPE_PEN);
XS_SERIALIZE(m_lstPoints, wxT("control_points"));
}
//----------------------------------------------------------------------------------//
// public functions
//----------------------------------------------------------------------------------//
void wxSFLineShape::SetSrcArrow(wxSFArrowBase* arrow)
{
if(m_pSrcArrow)delete m_pSrcArrow;
m_pSrcArrow = arrow;
if(m_pSrcArrow)
{
m_pSrcArrow->SetParentShape(this);
}
}
wxSFArrowBase* wxSFLineShape::SetSrcArrow(wxClassInfo* arrowInfo)
{
SetSrcArrow((wxSFArrowBase*)arrowInfo->CreateObject());
return m_pSrcArrow;
}
void wxSFLineShape::SetTrgArrow(wxSFArrowBase* arrow)
{
if(m_pTrgArrow)delete m_pTrgArrow;
m_pTrgArrow = arrow;
if(m_pTrgArrow)
{
m_pTrgArrow->SetParentShape(this);
}
}
wxSFArrowBase* wxSFLineShape::SetTrgArrow(wxClassInfo* arrowInfo)
{
SetTrgArrow((wxSFArrowBase*)arrowInfo->CreateObject());
return m_pTrgArrow;
}
wxRealPoint wxSFLineShape::GetSrcPoint()
{
if( m_fStandAlone )
{
return m_nSrcPoint;
}
else
{
wxRealPoint pt1, pt2;
wxSFShapeBase* pSrcShape = GetShapeManager()->FindShape(m_nSrcShapeId);
if( pSrcShape && !m_lstPoints.IsEmpty() )
{
if( pSrcShape->GetConnectionPoints().IsEmpty() )
{
wxXS::RealPointList::compatibility_iterator node = m_lstPoints.GetFirst();
if( node )
{
pt1 = *node->GetData();
return pSrcShape->GetBorderPoint(GetModSrcPoint(), pt1);
}
}
else
return GetModSrcPoint();
}
else
{
if( m_nMode != modeUNDERCONSTRUCTION )
GetDirectLine( pt1, pt2 );
else
pt1 = GetModSrcPoint();
return pt1;
}
return wxRealPoint();
}
}
wxRealPoint wxSFLineShape::GetTrgPoint()
{
if( m_fStandAlone )
{
return m_nTrgPoint;
}
else
{
wxRealPoint pt1, pt2;
wxSFShapeBase* pTrgShape = GetShapeManager()->FindShape(m_nTrgShapeId);
if( pTrgShape && !m_lstPoints.IsEmpty() )
{
if( pTrgShape->GetConnectionPoints().IsEmpty() )
{
wxXS::RealPointList::compatibility_iterator node = m_lstPoints.GetLast();
if( node )
{
pt2 = *node->GetData();
return pTrgShape->GetBorderPoint(GetModTrgPoint(), pt2);
}
}
else
return GetModTrgPoint();
}
else
{
if( m_nMode != modeUNDERCONSTRUCTION )
GetDirectLine( pt1, pt2 );
else
pt2 = Conv2RealPoint( m_nUnfinishedPoint );
return pt2;
}
return wxRealPoint();
}
}
void wxSFLineShape::GetDirectLine(wxRealPoint& src, wxRealPoint& trg)
{
if( m_fStandAlone )
{
src = m_nSrcPoint;
trg = m_nTrgPoint;
}
else
{
wxSFShapeBase* pSrcShape = GetShapeManager()->FindShape(m_nSrcShapeId);
wxSFShapeBase* pTrgShape = GetShapeManager()->FindShape(m_nTrgShapeId);
if( pSrcShape && pTrgShape )
{
wxRealPoint trgCenter = GetModTrgPoint();
wxRealPoint srcCenter = GetModSrcPoint();
if( (pSrcShape->GetParent() == pTrgShape) || (pTrgShape->GetParent() == pSrcShape) )
{
wxRect trgBB = pTrgShape->GetBoundingBox();
wxRect srcBB = pSrcShape->GetBoundingBox();
if( trgBB.Contains((int)srcCenter.x, (int)srcCenter.y) )
{
if( srcCenter.y > trgCenter.y )
{
src = wxRealPoint(srcCenter.x, srcBB.GetBottom());
trg = wxRealPoint(srcCenter.x, trgBB.GetBottom());
}
else
{
src = wxRealPoint(srcCenter.x, srcBB.GetTop());
trg = wxRealPoint(srcCenter.x, trgBB.GetTop());
}
return;
}
else if( srcBB.Contains((int)trgCenter.x, (int)trgCenter.y) )
{
if( trgCenter.y > srcCenter.y )
{
src = wxRealPoint(trgCenter.x, srcBB.GetBottom());
trg = wxRealPoint(trgCenter.x, trgBB.GetBottom());
}
else
{
src = wxRealPoint(trgCenter.x, srcBB.GetTop());
trg = wxRealPoint(trgCenter.x, trgBB.GetTop());
}
return;
}
}
if( pSrcShape->GetConnectionPoints().IsEmpty() ) src = pSrcShape->GetBorderPoint(srcCenter, trgCenter);
else
src = srcCenter;
if( pTrgShape->GetConnectionPoints().IsEmpty() ) trg = pTrgShape->GetBorderPoint(trgCenter, srcCenter);
else
trg = trgCenter;
}
}
}
//----------------------------------------------------------------------------------//
// public virtual functions
//----------------------------------------------------------------------------------//
wxRealPoint wxSFLineShape::GetAbsolutePosition()
{
return GetDockPointPosition( m_nDockPoint );
}
wxRealPoint wxSFLineShape::GetBorderPoint(const wxRealPoint& start, const wxRealPoint& end)
{
wxUnusedVar( start );
wxUnusedVar( end );
return GetAbsolutePosition();
}
wxRect wxSFLineShape::GetBoundingBox()
{
wxASSERT(m_pParentManager);
wxRect lineRct(0, 0, 0, 0);
// calculate control points area if they exist
if( !m_lstPoints.IsEmpty() )
{
wxRealPoint prevPt = GetSrcPoint();
wxXS::RealPointList::compatibility_iterator node = m_lstPoints.GetFirst();
while( node )
{
if(lineRct.IsEmpty())
{
lineRct = wxRect(Conv2Point(prevPt), Conv2Point(*node->GetData()));
}
else
lineRct.Union(wxRect(Conv2Point(prevPt), Conv2Point(*node->GetData())));
prevPt = *node->GetData();
node = node->GetNext();
}
lineRct.Union(wxRect(Conv2Point(prevPt), Conv2Point(GetTrgPoint())));
}
else
{
wxRealPoint pt;
// include starting point
pt = GetSrcPoint();
if(!lineRct.IsEmpty())
{
lineRct.Union(wxRect((int)pt.x, (int)pt.y, 1, 1));
}
else
lineRct = wxRect((int)pt.x, (int)pt.y, 1, 1);
// include ending point
pt = GetTrgPoint();
if(!lineRct.IsEmpty())
{
lineRct.Union(wxRect((int)pt.x, (int)pt.y, 1, 1));
}
else
lineRct = wxRect((int)pt.x, (int)pt.y, 1, 1);
}
// include unfinished point if the line is under construction
if((m_nMode == modeUNDERCONSTRUCTION) || (m_nMode == modeSRCCHANGE) || (m_nMode == modeTRGCHANGE))
{
if(!lineRct.IsEmpty())
{
lineRct.Union(wxRect(m_nUnfinishedPoint.x, m_nUnfinishedPoint.y, 1, 1));
}
else
lineRct = wxRect(m_nUnfinishedPoint.x, m_nUnfinishedPoint.y, 1, 1);
}
return lineRct;
}
wxRealPoint wxSFLineShape::GetDockPointPosition(int dp)
{
wxXS::RealPointList::compatibility_iterator ptnode;
int ptsCnt = (int)m_lstPoints.GetCount();
if( dp >= 0 )
{
if( ptsCnt > dp )
{
ptnode = m_lstPoints.Item(dp);
if( ptnode )return *ptnode->GetData();
}
else if( ptsCnt > 0 )
{
ptnode = m_lstPoints.Item(ptsCnt/2);
if( ptnode )return *ptnode->GetData();
}
}
else if( dp == -1 ) // start line point
{
return GetSrcPoint();
}
else if( dp == -2 ) // end line point
{
return GetTrgPoint();
}
return GetCenter();
}
bool wxSFLineShape::GetLineSegment(size_t index, wxRealPoint& src, wxRealPoint& trg)
{
if( !m_lstPoints.IsEmpty() )
{
if( index == 0 )
{
src = GetSrcPoint();
trg = *m_lstPoints.GetFirst()->GetData();
return true;
}
else if( index == m_lstPoints.GetCount() )
{
src = *m_lstPoints.GetLast()->GetData();
trg = GetTrgPoint();
return true;
}
else if( (index > 0) && (index < m_lstPoints.GetCount()) )
{
wxXS::RealPointList::compatibility_iterator node = m_lstPoints.Item(index);
src = *node->GetPrevious()->GetData();
trg = *node->GetData();
return true;
}
return false;
}
else
{
if( index == 0 )
{
GetDirectLine( src, trg );
return true;
}
else
return false;
}
}
bool wxSFLineShape::Contains(const wxPoint& pos)
{
if( (m_nMode != modeUNDERCONSTRUCTION) && (this->GetHitLinesegment(pos) >= 0) )return true;
else
return false;
}
void wxSFLineShape::Scale(double x, double y, bool children)
{
wxRealPoint *pt;
wxXS::RealPointList::compatibility_iterator node = m_lstPoints.GetFirst();
while(node)
{
pt = node->GetData();
pt->x *= x;
pt->y *= y;
node = node->GetNext();
}
// call default function implementation (needed for scaling of shape's children)
wxSFShapeBase::Scale(x, y, children);
}
void wxSFLineShape::MoveTo(double x, double y)
{
MoveBy(x - m_nPrevPosition.x, y - m_nPrevPosition.y);
m_nPrevPosition.x = x;
m_nPrevPosition.y = y;
}
void wxSFLineShape::MoveBy(double x, double y)
{
wxRealPoint *pt;
wxXS::RealPointList::compatibility_iterator node = m_lstPoints.GetFirst();
while(node)
{
pt = node->GetData();
pt->x += x;
pt->y += y;
node = node->GetNext();
}
if( m_fStandAlone )
{
m_nSrcPoint = m_nSrcPoint + wxRealPoint(x, y);
m_nTrgPoint = m_nTrgPoint + wxRealPoint(x, y);
}
if( !m_lstChildItems.IsEmpty() ) Update();
}
void wxSFLineShape::CreateHandles()
{
// first clear all previously used handles and then create new ones
m_lstHandles.Clear();
// create control points handles
for(size_t i = 0; i < m_lstPoints.GetCount(); i++) AddHandle(wxSFShapeHandle::hndLINECTRL, (int)i);
// create border handles
AddHandle(wxSFShapeHandle::hndLINESTART);
AddHandle(wxSFShapeHandle::hndLINEEND);
}
void wxSFLineShape::OnHandle(wxSFShapeHandle& handle)
{
switch(handle.GetType())
{
case wxSFShapeHandle::hndLINECTRL:
{
wxXS::RealPointList::compatibility_iterator node = m_lstPoints.Item(handle.GetId());
if(node)
{
wxRealPoint* pt = node->GetData();
pt->x = handle.GetPosition().x;
pt->y = handle.GetPosition().y;
}
}
break;
case wxSFShapeHandle::hndLINEEND:
{
m_nUnfinishedPoint = handle.GetPosition();
if( m_fStandAlone ) m_nTrgPoint = Conv2RealPoint( handle.GetPosition() );
}
break;
case wxSFShapeHandle::hndLINESTART:
{
m_nUnfinishedPoint = handle.GetPosition();
if( m_fStandAlone ) m_nSrcPoint = Conv2RealPoint( handle.GetPosition() );
}
break;
default:
break;
}
wxSFShapeBase::OnHandle( handle );
}
void wxSFLineShape::OnEndHandle(wxSFShapeHandle& handle)
{
// update percentual offset of the line's ending points
wxSFShapeBase *pParent = GetParentCanvas()->GetShapeUnderCursor();
if( pParent )
{
wxRect bbRect = pParent->GetBoundingBox();
switch( handle.GetType() )
{
case wxSFShapeHandle::hndLINESTART:
if( !m_fStandAlone && ( pParent->GetId() == m_nSrcShapeId ) )
{
m_nSrcOffset.x = double(handle.GetPosition().x - bbRect.GetLeft()) / bbRect.GetWidth();
m_nSrcOffset.y = double(handle.GetPosition().y - bbRect.GetTop()) / bbRect.GetHeight();
}
break;
case wxSFShapeHandle::hndLINEEND:
if( !m_fStandAlone && ( pParent->GetId() == m_nTrgShapeId ) )
{
m_nTrgOffset.x = double(handle.GetPosition().x - bbRect.GetLeft()) / bbRect.GetWidth();
m_nTrgOffset.y = double(handle.GetPosition().y - bbRect.GetTop()) / bbRect.GetHeight();
}
break;
default:
break;
}
}
wxSFShapeBase::OnEndHandle(handle);
}
void wxSFLineShape::OnBeginDrag(const wxPoint& pos)
{
m_nPrevPosition = GetAbsolutePosition();
wxSFShapeBase::OnBeginDrag(pos);
}
void wxSFLineShape::OnLeftDoubleClick(const wxPoint& pos)
{
// HINT: override it for custom actions
if(GetParentCanvas())
{
// remove existing handle if exist otherwise create a new one at the
// given position
wxSFShapeHandle *pHandle = GetParentCanvas()->GetTopmostHandleAtPosition(pos);
if(pHandle && (pHandle->GetParentShape() == this))
{
if(pHandle->GetType() == wxSFShapeHandle::hndLINECTRL)
m_lstPoints.DeleteNode(m_lstPoints.Item(pHandle->GetId()));
}
else
{
int nIndex = this->GetHitLinesegment(pos);
if( nIndex > -1 ) m_lstPoints.Insert(nIndex, new wxRealPoint(pos.x, pos.y));
}
CreateHandles();
ShowHandles(true);
}
}
//----------------------------------------------------------------------------------//
// protected virtual functions
//----------------------------------------------------------------------------------//
void wxSFLineShape::DrawNormal(wxDC& dc)
{
dc.SetPen(m_Pen);
DrawCompleteLine(dc);
dc.SetPen(wxNullPen);
}
void wxSFLineShape::DrawHover(wxDC& dc)
{
dc.SetPen(wxPen(m_nHoverColor, 1));
DrawCompleteLine(dc);
dc.SetPen(wxNullPen);
}
void wxSFLineShape::DrawHighlighted(wxDC& dc)
{
dc.SetPen(wxPen(m_nHoverColor, 2));
DrawCompleteLine(dc);
dc.SetPen(wxNullPen);
}
void wxSFLineShape::DrawCompleteLine(wxDC& dc)
{
if(!m_pParentManager)return;
size_t i;
wxRealPoint src, trg;
switch(m_nMode)
{
case modeREADY:
{
// draw basic line parts
for(i = 0; i <= m_lstPoints.GetCount(); i++)
{
GetLineSegment( i, src, trg );
dc.DrawLine(Conv2Point(src), Conv2Point(trg));
}
// draw target arrow
if(m_pTrgArrow)m_pTrgArrow->Draw(src, trg, dc);
// draw source arrow
if(m_pSrcArrow)
{
GetLineSegment( 0, src, trg );
m_pSrcArrow->Draw(trg, src, dc);
}
}
break;
case modeUNDERCONSTRUCTION:
{
// draw basic line parts
for(i = 0; i < m_lstPoints.GetCount(); i++)
{
GetLineSegment( i, src, trg );
dc.DrawLine(Conv2Point(src), Conv2Point(trg));
}
// draw unfinished line segment if any (for interactive line creation)
dc.SetPen( wxPen(*wxBLACK, 1, wxDOT) );
if( i )
{
dc.DrawLine( Conv2Point(trg), m_nUnfinishedPoint );
}
else
{
wxSFShapeBase* pSrcShape = GetShapeManager()->FindShape(m_nSrcShapeId);
if( pSrcShape )
{
if( pSrcShape->GetConnectionPoints().IsEmpty() )
{
dc.DrawLine( Conv2Point(pSrcShape->GetBorderPoint(pSrcShape->GetCenter(), Conv2RealPoint(m_nUnfinishedPoint))), m_nUnfinishedPoint );
}
else
dc.DrawLine( Conv2Point( GetModSrcPoint() ), m_nUnfinishedPoint );
}
}
dc.SetPen(wxNullPen);
}
break;
case modeSRCCHANGE:
{
// draw basic line parts
for(i = 1; i <= m_lstPoints.GetCount(); i++)
{
GetLineSegment( i, src, trg );
dc.DrawLine(Conv2Point(src), Conv2Point(trg));
}
// draw linesegment being updated
GetLineSegment( 0, src, trg );
if( !m_fStandAlone ) dc.SetPen(wxPen(*wxBLACK, 1, wxDOT));
dc.DrawLine(m_nUnfinishedPoint, Conv2Point(trg));
dc.SetPen(wxNullPen);
}
break;
case modeTRGCHANGE:
{
// draw basic line parts
if( !m_lstPoints.IsEmpty() )
{
for(i = 0; i < m_lstPoints.GetCount(); i++)
{
GetLineSegment( i, src, trg );
dc.DrawLine(Conv2Point(src), Conv2Point(trg));
}
}
else
trg = GetSrcPoint();
// draw linesegment being updated
if( !m_fStandAlone ) dc.SetPen(wxPen(*wxBLACK, 1, wxDOT));
dc.DrawLine( Conv2Point(trg), m_nUnfinishedPoint);
dc.SetPen(wxNullPen);
}
break;
}
}
int wxSFLineShape::GetHitLinesegment(const wxPoint& pos)
{
//if(!GetBoundingBox().Inflate(10, 10).Contains(pos))return -1;
if(!GetBoundingBox().Contains(pos))return -1;
double a, b, c, d;
wxRealPoint ptSrc, ptTrg;
wxRect lsBB;
// Get all polyline segments
for(size_t i = 0; i <= m_lstPoints.GetCount(); i++)
{
GetLineSegment( i, ptSrc, ptTrg );
// calculate line segment bounding box
lsBB = wxRect(Conv2Point(ptSrc), Conv2Point(ptTrg));
lsBB.Inflate(2);
// convert line segment to its parametric form
a = ptTrg.y - ptSrc.y;
b = ptSrc.x - ptTrg.x;
c = -a*ptSrc.x - b*ptSrc.y;
// calculate distance of the line and give point
d = (a*pos.x + b*pos.y + c)/sqrt(a*a + b*b);
if((abs((int)d) <= 5) && lsBB.Contains(pos)) return (int)i;
}
return -1;
}
//----------------------------------------------------------------------------------//
// protected functions
//----------------------------------------------------------------------------------//
wxRealPoint wxSFLineShape::GetModSrcPoint()
{
wxSFShapeBase* pSrcShape = GetShapeManager()->FindShape(m_nSrcShapeId);
if( !pSrcShape )return wxRealPoint();
wxRealPoint nModPoint;
if( m_nSrcOffset != sfdvLINESHAPE_OFFSET )
{
wxRect bbRct = pSrcShape->GetBoundingBox();
nModPoint = pSrcShape->GetAbsolutePosition();
nModPoint.x += (double)bbRct.GetWidth() * m_nSrcOffset.x;
nModPoint.y += (double)bbRct.GetHeight() * m_nSrcOffset.y;
}
else
nModPoint = pSrcShape->GetCenter();
wxSFConnectionPoint *pConnPt = pSrcShape->GetNearestConnectionPoint( nModPoint );
if( pConnPt ) nModPoint = pConnPt->GetConnectionPoint();
return nModPoint;
}
wxRealPoint wxSFLineShape::GetModTrgPoint()
{
wxSFShapeBase* pTrgShape = GetShapeManager()->FindShape(m_nTrgShapeId);
if( !pTrgShape )return wxRealPoint();
wxRealPoint nModPoint;
if( m_nTrgOffset != sfdvLINESHAPE_OFFSET )
{
wxRect bbRct = pTrgShape->GetBoundingBox();
nModPoint = pTrgShape->GetAbsolutePosition();
nModPoint.x += (double)bbRct.GetWidth() * m_nTrgOffset.x;
nModPoint.y += (double)bbRct.GetHeight() * m_nTrgOffset.y;
}
else
nModPoint = pTrgShape->GetCenter();
wxSFConnectionPoint *pConnPt = pTrgShape->GetNearestConnectionPoint( nModPoint );
if( pConnPt ) nModPoint = pConnPt->GetConnectionPoint();
return nModPoint;
}
void wxSFLineShape::SetEndingConnectionPoint(const wxSFConnectionPoint* cp)
{
if( cp && cp->GetParentShape() )
{
wxRealPoint posCp = cp->GetConnectionPoint();
wxRect rctBB = cp->GetParentShape()->GetBoundingBox();
m_nTrgOffset.x = double(posCp.x - rctBB.GetLeft()) / rctBB.GetWidth();
m_nTrgOffset.y = double(posCp.y - rctBB.GetTop()) / rctBB.GetHeight();
}
}
void wxSFLineShape::SetStartingConnectionPoint(const wxSFConnectionPoint* cp)
{
if( cp && cp->GetParentShape() )
{
wxRealPoint posCp = cp->GetConnectionPoint();
wxRect rctBB = cp->GetParentShape()->GetBoundingBox();
m_nSrcOffset.x = double(posCp.x - rctBB.GetLeft()) / rctBB.GetWidth();
m_nSrcOffset.y = double(posCp.y - rctBB.GetTop()) / rctBB.GetHeight();
}
}

View File

@@ -0,0 +1,350 @@
/***************************************************************
* Name: MultiSelRect.cpp
* Purpose: Implements aux. multiselection shape class
* Author: Michal Bližňák (michal.bliznak@tiscali.cz)
* Created: 2007-07-22
* Copyright: Michal Bližňák
* License: wxWidgets license (www.wxwidgets.org)
* Notes:
**************************************************************/
#include "wx_pch.h"
#ifdef _DEBUG_MSVC
#define new DEBUG_NEW
#endif
#include "wx/wxsf/MultiSelRect.h"
#include "wx/wxsf/ShapeCanvas.h"
#include "wx/wxsf/TextShape.h"
#include <math.h>
wxSFMultiSelRect::wxSFMultiSelRect(void)
{
SetBorder(wxPen(wxColour(100, 100, 100), 1, wxDOT));
SetFill(*wxTRANSPARENT_BRUSH);
}
wxSFMultiSelRect::~wxSFMultiSelRect(void)
{
}
//----------------------------------------------------------------------------------//
// public virtual functions
//----------------------------------------------------------------------------------//
void wxSFMultiSelRect::OnBeginHandle(wxSFShapeHandle& handle)
{
// inform all selected shapes about begin of the handle dragging
if(GetParentCanvas())
{
ShapeList lstShapes;
GetParentCanvas()->GetSelectedShapes(lstShapes);
ShapeList::compatibility_iterator node = lstShapes.GetFirst();
while(node)
{
node->GetData()->OnBeginHandle(handle);
node = node->GetNext();
}
}
}
void wxSFMultiSelRect::OnEndHandle(wxSFShapeHandle& handle)
{
// inform all selected shapes about end of the handle dragging
if(GetParentCanvas())
{
ShapeList lstShapes;
GetParentCanvas()->GetSelectedShapes(lstShapes);
ShapeList::compatibility_iterator node = lstShapes.GetFirst();
while(node)
{
node->GetData()->OnEndHandle(handle);
node = node->GetNext();
}
}
}
//----------------------------------------------------------------------------------//
// protected functions
//----------------------------------------------------------------------------------//
bool wxSFMultiSelRect::AnyWidthExceeded(const wxPoint& delta)
{
if(GetParentCanvas())
{
wxSFShapeBase* pShape;
ShapeList m_lstSelection;
GetParentCanvas()->GetSelectedShapes(m_lstSelection);
// first determine whether any shape in the selection exceeds its bounds
ShapeList::compatibility_iterator node = m_lstSelection.GetFirst();
while(node)
{
pShape = node->GetData();
if(!pShape->IsKindOf(CLASSINFO(wxSFLineShape)))
if((pShape->GetBoundingBox().GetWidth() + delta.x) <= 1)return true;
node = node->GetNext();
}
return false;
}
return true;
}
bool wxSFMultiSelRect::AnyHeightExceeded(const wxPoint& delta)
{
if(GetParentCanvas())
{
wxSFShapeBase* pShape;
ShapeList m_lstSelection;
GetParentCanvas()->GetSelectedShapes(m_lstSelection);
// first determine whether any shape in the selection exceeds its bounds
ShapeList::compatibility_iterator node = m_lstSelection.GetFirst();
while(node)
{
pShape = node->GetData();
if(!pShape->IsKindOf(CLASSINFO(wxSFLineShape)))
if((pShape->GetBoundingBox().GetHeight() + delta.y) <= 1)return true;
node = node->GetNext();
}
return false;
}
return true;
}
//----------------------------------------------------------------------------------//
// public virtual functions
//----------------------------------------------------------------------------------//
void wxSFMultiSelRect::OnRightHandle(wxSFShapeHandle& handle)
{
if(GetParentCanvas() && !AnyWidthExceeded(handle.GetDelta()))
{
wxXS::RealPointList::compatibility_iterator ptnode;
wxSFLineShape* pLine;
wxRealPoint* pt;
double dx, sx = (GetRectSize().x - 2*sfDEFAULT_ME_OFFSET + handle.GetDelta().x)/(GetRectSize().x - 2*sfDEFAULT_ME_OFFSET);
ShapeList m_lstSelection;
GetParentCanvas()->GetSelectedShapes(m_lstSelection);
ShapeList::compatibility_iterator node = m_lstSelection.GetFirst();
while(node)
{
wxSFShapeBase* pShape = node->GetData();
// scale main parent shape
if(!pShape->IsKindOf(CLASSINFO(wxSFLineShape)))
{
dx = (pShape->GetAbsolutePosition().x - (GetAbsolutePosition().x + sfDEFAULT_ME_OFFSET))/(GetRectSize().x - 2*sfDEFAULT_ME_OFFSET)*handle.GetDelta().x;
if(pShape->ContainsStyle(sfsSIZE_CHANGE))pShape->Scale(sx, 1, sfWITHCHILDREN);
if(pShape->ContainsStyle(sfsPOSITION_CHANGE))pShape->MoveBy(dx, 0);
pShape->FitToChildren();
}
else
{
if(pShape->ContainsStyle(sfsPOSITION_CHANGE))
{
pLine = (wxSFLineShape*)pShape;
ptnode = pLine->GetControlPoints().GetFirst();
while(ptnode)
{
pt = ptnode->GetData();
dx = ( pt->x - (GetAbsolutePosition().x + sfDEFAULT_ME_OFFSET))/(GetRectSize().x - 2*sfDEFAULT_ME_OFFSET)*handle.GetDelta().x;
pt->x += dx;
pt->x = floor(pt->x);
ptnode = ptnode->GetNext();
}
}
}
node = node->GetNext();
}
}
}
void wxSFMultiSelRect::OnLeftHandle(wxSFShapeHandle& handle)
{
if(GetParentCanvas() && !AnyWidthExceeded(wxPoint(-handle.GetDelta().x, 0)))
{
wxXS::RealPointList::compatibility_iterator ptnode;
wxSFLineShape* pLine;
wxRealPoint* pt;
double dx, sx = (GetRectSize().x - 2*sfDEFAULT_ME_OFFSET - handle.GetDelta().x)/(GetRectSize().x - 2*sfDEFAULT_ME_OFFSET);
ShapeList m_lstSelection;
GetParentCanvas()->GetSelectedShapes(m_lstSelection);
ShapeList::compatibility_iterator node = m_lstSelection.GetFirst();
while(node)
{
wxSFShapeBase* pShape = node->GetData();
if(!pShape->IsKindOf(CLASSINFO(wxSFLineShape)))
{
if(pShape->ContainsStyle(sfsPOSITION_CHANGE))
{
if(pShape->GetParentShape())
{
pShape->SetRelativePosition(pShape->GetRelativePosition().x*sx, pShape->GetRelativePosition().y);
}
else
{
double dx = handle.GetDelta().x - (pShape->GetAbsolutePosition().x - (GetAbsolutePosition().x + sfDEFAULT_ME_OFFSET))/(GetRectSize().x - 2*sfDEFAULT_ME_OFFSET)*handle.GetDelta().x;
pShape->MoveBy(dx, 0);
}
}
if(pShape->ContainsStyle(sfsSIZE_CHANGE))pShape->Scale(sx, 1, sfWITHCHILDREN);
pShape->FitToChildren();
}
else
{
if(pShape->ContainsStyle(sfsPOSITION_CHANGE))
{
pLine = (wxSFLineShape*)pShape;
ptnode = pLine->GetControlPoints().GetFirst();
while(ptnode)
{
pt = ptnode->GetData();
dx = handle.GetDelta().x - (pt->x - (GetAbsolutePosition().x + sfDEFAULT_ME_OFFSET))/(GetRectSize().x - 2*sfDEFAULT_ME_OFFSET)*handle.GetDelta().x;
pt->x += dx;
pt->x = floor(pt->x);
ptnode = ptnode->GetNext();
}
}
}
node = node->GetNext();
}
}
}
void wxSFMultiSelRect::OnBottomHandle(wxSFShapeHandle& handle)
{
if(GetParentCanvas() && !AnyHeightExceeded(handle.GetDelta()))
{
wxXS::RealPointList::compatibility_iterator ptnode;
wxSFLineShape* pLine;
wxRealPoint* pt;
double dy, sy = (GetRectSize().y - 2*sfDEFAULT_ME_OFFSET + handle.GetDelta().y)/(GetRectSize().y - 2*sfDEFAULT_ME_OFFSET);
ShapeList m_lstSelection;
GetParentCanvas()->GetSelectedShapes(m_lstSelection);
ShapeList::compatibility_iterator node = m_lstSelection.GetFirst();
while(node)
{
wxSFShapeBase* pShape = node->GetData();
if(!pShape->IsKindOf(CLASSINFO(wxSFLineShape)))
{
dy = (pShape->GetAbsolutePosition().y - (GetAbsolutePosition().y + sfDEFAULT_ME_OFFSET))/(GetRectSize().y - 2*sfDEFAULT_ME_OFFSET)*handle.GetDelta().y;
if(pShape->ContainsStyle(sfsSIZE_CHANGE))pShape->Scale(1, sy, sfWITHCHILDREN);
if(pShape->ContainsStyle(sfsPOSITION_CHANGE))pShape->MoveBy(0, dy);
pShape->FitToChildren();
}
else
{
if(pShape->ContainsStyle(sfsPOSITION_CHANGE))
{
pLine = (wxSFLineShape*)pShape;
ptnode = pLine->GetControlPoints().GetFirst();
while(ptnode)
{
pt = ptnode->GetData();
dy = ( pt->y - (GetAbsolutePosition().y + sfDEFAULT_ME_OFFSET))/(GetRectSize().y - 2*sfDEFAULT_ME_OFFSET)*handle.GetDelta().y;
pt->y += dy;
pt->y = floor(pt->y);
ptnode = ptnode->GetNext();
}
}
}
node = node->GetNext();
}
}
}
void wxSFMultiSelRect::OnTopHandle(wxSFShapeHandle& handle)
{
if(GetParentCanvas() && !AnyHeightExceeded(wxPoint(0, -handle.GetDelta().y)))
{
wxXS::RealPointList::compatibility_iterator ptnode;
wxSFLineShape* pLine;
wxRealPoint* pt;
double dy, sy = (GetRectSize().y - 2*sfDEFAULT_ME_OFFSET - handle.GetDelta().y)/(GetRectSize().y - 2*sfDEFAULT_ME_OFFSET);
ShapeList m_lstSelection;
GetParentCanvas()->GetSelectedShapes(m_lstSelection);
ShapeList::compatibility_iterator node = m_lstSelection.GetFirst();
while(node)
{
wxSFShapeBase* pShape = node->GetData();
if(!pShape->IsKindOf(CLASSINFO(wxSFLineShape)))
{
if(pShape->ContainsStyle(sfsPOSITION_CHANGE))
{
if(pShape->GetParentShape())
{
pShape->SetRelativePosition(pShape->GetRelativePosition().x, pShape->GetRelativePosition().y*sy);
}
else
{
double dy = handle.GetDelta().y - (pShape->GetAbsolutePosition().y - (GetAbsolutePosition().y + sfDEFAULT_ME_OFFSET))/(GetRectSize().y - 2*sfDEFAULT_ME_OFFSET)*handle.GetDelta().y;
pShape->MoveBy(0, dy);
}
}
if(pShape->ContainsStyle(sfsSIZE_CHANGE))pShape->Scale(1, sy, sfWITHCHILDREN);
pShape->FitToChildren();
}
else
{
if(pShape->ContainsStyle(sfsPOSITION_CHANGE))
{
pLine = (wxSFLineShape*)pShape;
ptnode = pLine->GetControlPoints().GetFirst();
while(ptnode)
{
pt = ptnode->GetData();
dy = handle.GetDelta().y - (pt->y - (GetAbsolutePosition().y + sfDEFAULT_ME_OFFSET))/(GetRectSize().y - 2*sfDEFAULT_ME_OFFSET)*handle.GetDelta().y;
pt->y += dy;
pt->y = floor(pt->y);
ptnode = ptnode->GetNext();
}
}
}
node = node->GetNext();
}
}
}
void wxSFMultiSelRect::OnHandle(wxSFShapeHandle& handle)
{
wxSFRectShape::OnHandle( handle );
GetParentCanvas()->InvalidateVisibleRect();
}

View File

@@ -0,0 +1,69 @@
/***************************************************************
* Name: OpenArrow.cpp
* Purpose: Implements open arrow for line shapes
* Author: Michal Bližňák (michal.bliznak@tiscali.cz)
* Created: 2007-07-22
* Copyright: Michal Bližňák
* License: wxWidgets license (www.wxwidgets.org)
* Notes:
**************************************************************/
#include "wx_pch.h"
#ifdef _DEBUG_MSVC
#define new DEBUG_NEW
#endif
#include "wx/wxsf/OpenArrow.h"
#include "wx/wxsf/CommonFcn.h"
// arrow shape
static const wxRealPoint arrow[3]={wxRealPoint(0,0), wxRealPoint(10,4), wxRealPoint(10,-4)};
using namespace wxSFCommonFcn;
XS_IMPLEMENT_CLONABLE_CLASS(wxSFOpenArrow, wxSFArrowBase);
wxSFOpenArrow::wxSFOpenArrow(void)
: wxSFArrowBase()
{
m_Pen = sfdvARROW_BORDER;
XS_SERIALIZE_EX(m_Pen, wxT("arrow_style"), sfdvARROW_BORDER);
}
wxSFOpenArrow::wxSFOpenArrow(wxSFShapeBase* parent)
: wxSFArrowBase(parent)
{
m_Pen = sfdvARROW_BORDER;
XS_SERIALIZE_EX(m_Pen, wxT("arrow_style"), sfdvARROW_BORDER);
}
wxSFOpenArrow::wxSFOpenArrow(const wxSFOpenArrow& obj)
: wxSFArrowBase(obj)
{
m_Pen = obj.m_Pen;
XS_SERIALIZE_EX(m_Pen, wxT("arrow_style"), sfdvARROW_BORDER);
}
wxSFOpenArrow::~wxSFOpenArrow(void)
{
}
//----------------------------------------------------------------------------------//
// public virtual functions
//----------------------------------------------------------------------------------//
void wxSFOpenArrow::Draw(const wxRealPoint &from, const wxRealPoint &to, wxDC& dc)
{
wxPoint rarrow[3];
TranslateArrow( rarrow, arrow, 3, from, to );
dc.SetPen( m_Pen );
dc.DrawLine(rarrow[0], rarrow[1]);
dc.DrawLine(rarrow[0], rarrow[2]);
dc.SetPen( wxNullPen );
}

View File

@@ -0,0 +1,295 @@
/***************************************************************
* Name: OrthoShape.cpp
* Purpose: Implements orthogonal line shape class
* Author: Michal Bližňák (michal.bliznak@gmail.com)
* Created: 2009-04-26
* Copyright: Michal Bližňák
* License: wxWidgets license (www.wxwidgets.org)
* Notes:
**************************************************************/
#include "wx_pch.h"
#ifdef _DEBUG_MSVC
#define new DEBUG_NEW
#endif
#include <math.h>
#include "wx/wxsf/OrthoShape.h"
#include "wx/wxsf/ShapeCanvas.h"
#include "wx/wxsf/CommonFcn.h"
using namespace wxSFCommonFcn;
XS_IMPLEMENT_CLONABLE_CLASS(wxSFOrthoLineShape, wxSFLineShape);
wxSFOrthoLineShape::wxSFOrthoLineShape() : wxSFLineShape()
{
}
wxSFOrthoLineShape::wxSFOrthoLineShape(long src, long trg, const wxXS::RealPointList& path, wxSFDiagramManager* manager)
: wxSFLineShape(src, trg, path, manager)
{
}
wxSFOrthoLineShape::wxSFOrthoLineShape(const wxSFOrthoLineShape& obj)
: wxSFLineShape(obj)
{
}
wxSFOrthoLineShape::~wxSFOrthoLineShape()
{
}
//----------------------------------------------------------------------------------//
// protected virtual functions
//----------------------------------------------------------------------------------//
void wxSFOrthoLineShape::DrawCompleteLine(wxDC& dc)
{
if(!m_pParentManager)return;
size_t i;
wxRealPoint src, trg;
switch(m_nMode)
{
case modeREADY:
{
// draw basic line parts
for(i = 0; i <= m_lstPoints.GetCount(); i++)
{
GetLineSegment( i, src, trg );
this->DrawLineSegment( dc, src, trg );
}
// draw target arrow
if(m_pTrgArrow)
{
wxRealPoint asrc, atrg;
GetLastSubsegment( src, trg, asrc, atrg );
m_pTrgArrow->Draw( asrc, atrg, dc );
}
// draw source arrow
if(m_pSrcArrow)
{
wxRealPoint asrc, atrg;
GetLineSegment( 0, src, trg );
GetFirstSubsegment( src, trg, asrc, atrg );
m_pSrcArrow->Draw( atrg, asrc, dc );
}
}
break;
case modeUNDERCONSTRUCTION:
{
// draw basic line parts
for(i = 0; i < m_lstPoints.GetCount(); i++)
{
GetLineSegment( i, src, trg );
this->DrawLineSegment( dc, src, trg );
}
// draw unfinished line segment if any (for interactive line creation)
dc.SetPen( wxPen(*wxBLACK, 1, wxDOT) );
if( i )
{
this->DrawLineSegment( dc, trg, Conv2RealPoint(m_nUnfinishedPoint) );
}
else
{
wxSFShapeBase* pSrcShape = GetShapeManager()->FindShape(m_nSrcShapeId);
if( pSrcShape )
{
if( pSrcShape->GetConnectionPoints().IsEmpty() )
{
this->DrawLineSegment( dc, pSrcShape->GetBorderPoint(pSrcShape->GetCenter(), Conv2RealPoint(m_nUnfinishedPoint)), Conv2RealPoint(m_nUnfinishedPoint) );
}
else
this->DrawLineSegment( dc, GetModSrcPoint(), Conv2RealPoint(m_nUnfinishedPoint) );
}
}
dc.SetPen(wxNullPen);
}
break;
case modeSRCCHANGE:
{
// draw basic line parts
for(i = 1; i <= m_lstPoints.GetCount(); i++)
{
GetLineSegment( i, src, trg );
this->DrawLineSegment( dc, src, trg );
}
// draw linesegment being updated
GetLineSegment( 0, src, trg );
dc.SetPen(wxPen(*wxBLACK, 1, wxDOT));
this->DrawLineSegment( dc, Conv2RealPoint(m_nUnfinishedPoint), trg );
dc.SetPen(wxNullPen);
}
break;
case modeTRGCHANGE:
{
// draw basic line parts
if( !m_lstPoints.IsEmpty() )
{
for(i = 0; i < m_lstPoints.GetCount(); i++)
{
GetLineSegment( i, src, trg );
this->DrawLineSegment( dc, src, trg );
}
}
else
trg = GetSrcPoint();
// draw linesegment being updated
dc.SetPen(wxPen(*wxBLACK, 1, wxDOT));
this->DrawLineSegment( dc, trg, Conv2RealPoint(m_nUnfinishedPoint) );
dc.SetPen(wxNullPen);
}
break;
}
}
int wxSFOrthoLineShape::GetHitLinesegment(const wxPoint& pos)
{
if( !GetBoundingBox().Inflate(5, 5).Contains(pos) )return -1;
wxRealPoint ptSrc, ptTrg, ptSSrc, ptSTrg;
wxRect rctBB;
// Get all polyline segments
for(size_t i = 0; i <= m_lstPoints.GetCount(); i++)
{
GetLineSegment( i, ptSrc, ptTrg );
// test first subsegment
GetFirstSubsegment( ptSrc, ptTrg, ptSSrc, ptSTrg );
rctBB = wxRect(Conv2Point(ptSSrc), Conv2Point(ptSTrg));
rctBB.Inflate(5);
if( rctBB.Contains(pos) ) return (int)i;
// test middle subsegment
GetMiddleSubsegment( ptSrc, ptTrg, ptSSrc, ptSTrg );
rctBB = wxRect(Conv2Point(ptSSrc), Conv2Point(ptSTrg));
rctBB.Inflate(5);
if( rctBB.Contains(pos) ) return (int)i;
// test last subsegment
GetLastSubsegment( ptSrc, ptTrg, ptSSrc, ptSTrg );
rctBB = wxRect(Conv2Point(ptSSrc), Conv2Point(ptSTrg));
rctBB.Inflate(5);
if( rctBB.Contains(pos) ) return (int)i;
}
return -1;
}
//----------------------------------------------------------------------------------//
// protected functions
//----------------------------------------------------------------------------------//
void wxSFOrthoLineShape::DrawLineSegment(wxDC& dc, const wxRealPoint& src, const wxRealPoint& trg)
{
double nDirection;
if( (trg.x == src.x) || ( trg.y == src.y ) )
{
dc.DrawLine( src.x, src.y, trg.x, trg.y );
return;
}
else
nDirection = fabs( trg.y - src.y ) / fabs( trg.x - src.x );
wxRealPoint ptCenter( (src.x + trg.x)/2, (src.y + trg.y)/2 );
if( nDirection < 1 )
{
dc.DrawLine( src.x, src.y, ptCenter.x, src.y );
dc.DrawLine( ptCenter.x, src.y, ptCenter.x, trg.y );
dc.DrawLine( ptCenter.x, trg.y, trg.x, trg.y );
}
else
{
dc.DrawLine( src.x, src.y, src.x, ptCenter.y );
dc.DrawLine( src.x, ptCenter.y, trg.x, ptCenter.y );
dc.DrawLine( trg.x, ptCenter.y, trg.x, trg.y );
}
}
void wxSFOrthoLineShape::GetFirstSubsegment(const wxRealPoint& src, const wxRealPoint& trg, wxRealPoint& subsrc, wxRealPoint& subtrg)
{
double nDirection = 0;
if( trg.x == src.x ) nDirection = 1;
else nDirection = fabs( trg.y - src.y ) / fabs( trg.x - src.x );
wxRealPoint ptCenter( (src.x + trg.x)/2, (src.y + trg.y)/2 );
if( nDirection < 1 )
{
subsrc = src;
subtrg = wxRealPoint( ptCenter.x, src.y );
}
else
{
subsrc = src;
subtrg = wxRealPoint( src.x, ptCenter.y );
}
}
void wxSFOrthoLineShape::GetLastSubsegment(const wxRealPoint& src, const wxRealPoint& trg, wxRealPoint& subsrc, wxRealPoint& subtrg)
{
double nDirection = 0;
if( trg.x == src.x ) nDirection = 1;
else nDirection = fabs( trg.y - src.y ) / fabs( trg.x - src.x );
wxRealPoint ptCenter( (src.x + trg.x)/2, (src.y + trg.y)/2 );
if( nDirection < 1 )
{
subsrc = wxRealPoint( ptCenter.x, trg.y );
subtrg = trg;
}
else
{
subsrc = wxRealPoint( trg.x, ptCenter.y );
subtrg = trg;
}
}
void wxSFOrthoLineShape::GetMiddleSubsegment(const wxRealPoint& src, const wxRealPoint& trg, wxRealPoint& subsrc, wxRealPoint& subtrg)
{
double nDirection = 0;
if( trg.x == src.x ) nDirection = 1;
else nDirection = fabs( trg.y - src.y ) / fabs( trg.x - src.x );
wxRealPoint ptCenter( (src.x + trg.x)/2, (src.y + trg.y)/2 );
if( nDirection < 1 )
{
subsrc = wxRealPoint( ptCenter.x, src.y);
subtrg = wxRealPoint( ptCenter.x, trg.y );
}
else
{
subsrc = wxRealPoint( src.x, ptCenter.y );
subtrg = wxRealPoint( trg.x, ptCenter.y );
}
}

View File

@@ -0,0 +1,322 @@
/***************************************************************
* Name: PolygonShape.cpp
* Purpose: Implements polygonial shape class
* Author: Michal Bližňák (michal.bliznak@tiscali.cz)
* Created: 2007-07-22
* Copyright: Michal Bližňák
* License: wxWidgets license (www.wxwidgets.org)
* Notes:
**************************************************************/
#include "wx_pch.h"
#ifdef _DEBUG_MSVC
#define new DEBUG_NEW
#endif
#include "wx/wxsf/PolygonShape.h"
#include "wx/wxsf/CommonFcn.h"
#include "wx/wxsf/ShapeCanvas.h"
using namespace wxSFCommonFcn;
XS_IMPLEMENT_CLONABLE_CLASS(wxSFPolygonShape, wxSFRectShape);
wxSFPolygonShape::wxSFPolygonShape(void)
: wxSFRectShape()
{
m_fConnectToVertex = sfdvPOLYGONSHAPE_VERTEXCONNECTIONS;
MarkSerializableDataMembers();
}
wxSFPolygonShape::wxSFPolygonShape(int n, const wxRealPoint pts[], const wxRealPoint& pos, wxSFDiagramManager* manager)
: wxSFRectShape(pos, wxRealPoint(1, 1), manager)
{
m_fConnectToVertex = sfdvPOLYGONSHAPE_VERTEXCONNECTIONS;
MarkSerializableDataMembers();
SetVertices(n, pts);
}
wxSFPolygonShape::wxSFPolygonShape(const wxSFPolygonShape& obj)
: wxSFRectShape(obj)
{
m_fConnectToVertex = obj.m_fConnectToVertex;
MarkSerializableDataMembers();
m_arrVertices.Clear();
for(size_t i = 0; i < obj.m_arrVertices.Count(); i++)m_arrVertices.Add(obj.m_arrVertices[i]);
}
wxSFPolygonShape::~wxSFPolygonShape(void)
{
}
void wxSFPolygonShape::MarkSerializableDataMembers()
{
XS_SERIALIZE_EX(m_fConnectToVertex, wxT("connect_to_vertex"), sfdvPOLYGONSHAPE_VERTEXCONNECTIONS);
XS_SERIALIZE(m_arrVertices, wxT("vertices"));
}
//----------------------------------------------------------------------------------//
// public functions
//----------------------------------------------------------------------------------//
void wxSFPolygonShape::SetVertices(size_t n, const wxRealPoint pts[])
{
m_arrVertices.Clear();
for(size_t i = 0; i < n; i++)m_arrVertices.Add(pts[i]);
NormalizeVertices();
FitBoundingBoxToVertices();
}
//----------------------------------------------------------------------------------//
// public virtual functions
//----------------------------------------------------------------------------------//
wxRealPoint wxSFPolygonShape::GetBorderPoint(const wxRealPoint& start, const wxRealPoint& end)
{
// HINT: override it for custom actions ...
bool fSuccess = false;
double tmpMinDist = 0, minDist = 0;
wxRealPoint tmpIntersection, intersection;
size_t ptsCnt = m_arrVertices.Count();
wxRealPoint *pts = new wxRealPoint[ptsCnt];
GetTranslatedVerices(pts);
intersection = start; //GetCenter();
if(ptsCnt == 0)return GetCenter();
if(m_fConnectToVertex)
{
minDist = Distance(pts[0], end);
intersection = pts[0];
for(size_t i = 1; i < ptsCnt; i++)
{
tmpMinDist = Distance(pts[i], end);
if(tmpMinDist < minDist)
{
minDist = tmpMinDist;
intersection = pts[i];
}
}
delete [] pts;
return intersection;
}
else
{
for(size_t i = 0; i < ptsCnt; i++)
{
if(LinesIntersection(pts[i], pts[(i+1) % ptsCnt], start, end, tmpIntersection))
{
if(!fSuccess)
{
minDist = Distance(intersection, end);
intersection = tmpIntersection;
}
else
{
tmpMinDist = Distance(intersection, end);
if(tmpMinDist < minDist)
{
minDist = tmpMinDist;
intersection = tmpIntersection;
}
}
fSuccess = true;
}
}
delete [] pts;
if(fSuccess)
{
return intersection;
}
else
{
return GetCenter();
}
}
}
void wxSFPolygonShape::FitToChildren()
{
wxSFRectShape::FitToChildren();
FitVerticesToBoundingBox();
}
void wxSFPolygonShape::Scale(double x, double y, bool children)
{
m_nRectSize.x *= x;
m_nRectSize.y *= y;
FitVerticesToBoundingBox();
// call default function implementation (needed for scaling of shape's children)
wxSFShapeBase::Scale(x, y, children);
}
void wxSFPolygonShape::OnHandle(wxSFShapeHandle& handle)
{
wxSFRectShape::OnHandle(handle);
FitVerticesToBoundingBox();
}
//----------------------------------------------------------------------------------//
// protected functions
//----------------------------------------------------------------------------------//
void wxSFPolygonShape::GetExtents(double *minx, double *miny, double *maxx, double *maxy)
{
if(m_arrVertices.Count() == 0)return;
*minx = *maxx = m_arrVertices[0].x;
*miny = *maxy = m_arrVertices[0].y;
for(size_t i = 1; i < m_arrVertices.Count(); i++)
{
if(m_arrVertices[i].x < *minx)*minx = m_arrVertices[i].x;
if(m_arrVertices[i].x > *maxx)*maxx = m_arrVertices[i].x;
if(m_arrVertices[i].y < *miny)*miny = m_arrVertices[i].y;
if(m_arrVertices[i].y > *maxy)*maxy = m_arrVertices[i].y;
}
}
void wxSFPolygonShape::GetTranslatedVerices(wxRealPoint pts[])
{
wxRealPoint absPos = GetAbsolutePosition();
for(size_t i = 0; i < m_arrVertices.Count(); i++)pts[i] = absPos + m_arrVertices[i];
}
void wxSFPolygonShape::GetTranslatedVerices(wxPoint pts[])
{
wxPoint absPos = Conv2Point(GetAbsolutePosition());
for(size_t i = 0; i < m_arrVertices.Count(); i++)pts[i] = absPos + Conv2Point(m_arrVertices[i]);
}
void wxSFPolygonShape::NormalizeVertices()
{
// move all vertices so the polygon's relative bounding box will be located in the origin
double minx = 0, miny = 0, maxx = 0, maxy = 0, dx = 0, dy = 0;
GetExtents(&minx, &miny, &maxx, &maxy);
dx = minx*(-1);
dy = miny*(-1);
for(size_t i = 0; i < m_arrVertices.Count(); i++)
{
m_arrVertices[i].x += dx;
m_arrVertices[i].y += dy;
}
}
void wxSFPolygonShape::FitVerticesToBoundingBox()
{
double minx = 0, miny = 0, maxx = 0, maxy = 0, sx = 1, sy = 1;
GetExtents(&minx, &miny, &maxx, &maxy);
sx = m_nRectSize.x/(maxx - minx);
sy = m_nRectSize.y/(maxy - miny);
for(size_t i = 0; i < m_arrVertices.Count(); i++)
{
m_arrVertices[i].x *= sx;
m_arrVertices[i].y *= sy;
}
}
void wxSFPolygonShape::FitBoundingBoxToVertices()
{
double minx = 0, miny = 0, maxx = 0, maxy = 0;
GetExtents(&minx, &miny, &maxx, &maxy);
m_nRectSize.x = maxx - minx;
m_nRectSize.y = maxy - miny;
}
void wxSFPolygonShape::DrawPolygonShape(wxDC& dc)
{
size_t vcount = m_arrVertices.Count();
wxPoint *pts = new wxPoint[vcount];
GetTranslatedVerices(pts);
dc.DrawPolygon(vcount, pts);
delete [] pts;
}
//----------------------------------------------------------------------------------//
// protected virtual functions
//----------------------------------------------------------------------------------//
void wxSFPolygonShape::DrawNormal(wxDC& dc)
{
// HINT: overload it for custom actions...
dc.SetPen(m_Border);
dc.SetBrush(m_Fill);
DrawPolygonShape(dc);
dc.SetBrush(wxNullBrush);
dc.SetPen(wxNullPen);
}
void wxSFPolygonShape::DrawHover(wxDC& dc)
{
// HINT: overload it for custom actions...
dc.SetPen(wxPen(m_nHoverColor, 1));
dc.SetBrush(m_Fill);
DrawPolygonShape(dc);
dc.SetBrush(wxNullBrush);
dc.SetPen(wxNullPen);
}
void wxSFPolygonShape::DrawHighlighted(wxDC& dc)
{
// HINT: overload it for custom actions...
dc.SetPen(wxPen(m_nHoverColor, 2));
dc.SetBrush(m_Fill);
DrawPolygonShape(dc);
dc.SetBrush(wxNullBrush);
dc.SetPen(wxNullPen);
}
void wxSFPolygonShape::DrawShadow(wxDC& dc)
{
// HINT: overload it for custom actions...
if( m_Fill.GetStyle() != wxTRANSPARENT )
{
dc.SetPen(*wxTRANSPARENT_PEN);
dc.SetBrush(GetParentCanvas()->GetShadowFill());
wxRealPoint nOffset = GetParentCanvas()->GetShadowOffset();
MoveBy(nOffset);
DrawPolygonShape(dc);
MoveBy(-nOffset.x, -nOffset.y);
dc.SetBrush(wxNullBrush);
dc.SetPen(wxNullPen);
}
}

View File

@@ -0,0 +1,44 @@
/***************************************************************
* Name: PolygonShapeXml.cpp
* Purpose: Implements polygonial shape's serialization cap.
* Author: Michal Bližňák (michal.bliznak@tiscali.cz)
* Created: 2007-07-22
* Copyright: Michal Bližňák
* License: wxWidgets license (www.wxwidgets.org)
* Notes:
**************************************************************/
#include "wx_pch.h"
#ifdef _DEBUG_MSVC
#define new DEBUG_NEW
#endif
#include "wx/wxsf/PolygonShape.h"
#include "wx/wxsf/CommonFcn.h"
//----------------------------------------------------------------------------------//
// Serialization
//----------------------------------------------------------------------------------//
wxXmlNode* wxSFPolygonShape::Serialize(wxXmlNode* node)
{
// HINT: overload it for custom actions...
if(node)
{
node = wxSFRectShape::Serialize(node);
}
return node;
}
void wxSFPolygonShape::Deserialize(wxXmlNode* node)
{
// HINT: overload it for custom actions...
wxSFRectShape::Deserialize(node);
NormalizeVertices();
FitVerticesToBoundingBox();
}

View File

@@ -0,0 +1,195 @@
/***************************************************************
* Name: Printout.cpp
* Purpose: Implements printout class for shape canvas
* Author: Michal Bližňák (michal.bliznak@tiscali.cz)
* Created: 2008-05-06
* Copyright: Michal Bližňák
* License: wxWidgets license (www.wxwidgets.org)
* Notes:
**************************************************************/
#include "wx_pch.h"
#ifdef _DEBUG_MSVC
#define new DEBUG_NEW
#endif
#include "wx/wxsf/Printout.h"
#include "wx/wxsf/ScaledDC.h"
#include "wx/wxsf/ShapeCanvas.h"
wxSFPrintout::wxSFPrintout(const wxString& title, wxSFShapeCanvas *canvas)
: wxPrintout(title)
{
m_pCanvas = canvas;
}
wxSFPrintout::~wxSFPrintout()
{
}
//----------------------------------------------------------------------------------//
// public virtual functions
//----------------------------------------------------------------------------------//
bool wxSFPrintout::HasPage(int page)
{
return (page == 1);
}
bool wxSFPrintout::OnBeginDocument(int startPage, int endPage)
{
// HINT: perform custom actions...
return wxPrintout::OnBeginDocument(startPage, endPage);
}
void wxSFPrintout::OnEndDocument()
{
// HINT: perform custom actions ...
wxPrintout::OnEndDocument();
}
bool wxSFPrintout::OnPrintPage(int page)
{
wxUnusedVar( page );
wxASSERT_MSG(m_pCanvas, wxT("Shape canvas must be set in the wxSFPrintout class instance."));
wxDC *dc = GetDC();
if (dc && m_pCanvas)
{
// get grawing size
wxRect fitRect, totalBB = m_pCanvas->GetTotalBoundingBox();
wxCoord maxX = totalBB.GetRight();
wxCoord maxY = totalBB.GetBottom();
// set printing mode
switch( m_pCanvas->GetPrintMode() )
{
case wxSFShapeCanvas::prnFIT_TO_PAGE:
FitThisSizeToPage(wxSize(maxX, maxY));
fitRect = GetLogicalPageRect();
break;
case wxSFShapeCanvas::prnFIT_TO_PAPER:
FitThisSizeToPaper(wxSize(maxX, maxY));
fitRect = GetLogicalPaperRect();
break;
case wxSFShapeCanvas::prnFIT_TO_MARGINS:
FitThisSizeToPageMargins(wxSize(maxX, maxY), *g_pageSetupData);
fitRect = GetLogicalPageMarginsRect(*g_pageSetupData);
break;
case wxSFShapeCanvas::prnMAP_TO_PAGE:
MapScreenSizeToPage();
fitRect = GetLogicalPageRect();
break;
case wxSFShapeCanvas::prnMAP_TO_PAPER:
MapScreenSizeToPaper();
fitRect = GetLogicalPaperRect();
break;
case wxSFShapeCanvas::prnMAP_TO_MARGINS:
MapScreenSizeToPage();
fitRect = GetLogicalPageMarginsRect(*g_pageSetupData);
break;
case wxSFShapeCanvas::prnMAP_TO_DEVICE:
MapScreenSizeToDevice();
fitRect = GetLogicalPageRect();
break;
}
// This offsets the image so that it is centered within the reference
// rectangle defined above.
wxCoord xoff = ((fitRect.width - maxX - totalBB.GetLeft()) / 2) - fitRect.x;
wxCoord yoff = ((fitRect.height - maxY - totalBB.GetTop()) / 2) - fitRect.y;
switch( m_pCanvas->GetPrintHAlign() )
{
case wxSFShapeCanvas::halignLEFT:
xoff = 0;
break;
case wxSFShapeCanvas::halignRIGHT:
xoff = fitRect.width - totalBB.GetWidth();
break;
default:
break;
}
switch( m_pCanvas->GetPrintVAlign() )
{
case wxSFShapeCanvas::valignTOP:
yoff = 0;
break;
case wxSFShapeCanvas::valignBOTTOM:
yoff = fitRect.height - totalBB.GetHeight();
break;
default:
break;
}
OffsetLogicalOrigin(xoff, yoff);
// store current canvas properties
double prevScale = m_pCanvas->GetScale();
long prevStyle = m_pCanvas->GetStyle();
wxColour prevColour = m_pCanvas->GetCanvasColour();
// disable canvas background drawing if required
if( !m_pCanvas->ContainsStyle( wxSFShapeCanvas::sfsPRINT_BACKGROUND ) )
{
m_pCanvas->RemoveStyle( wxSFShapeCanvas::sfsGRADIENT_BACKGROUND );
m_pCanvas->RemoveStyle( wxSFShapeCanvas::sfsGRID_SHOW );
m_pCanvas->SetCanvasColour( *wxWHITE);
}
// draw the canvas content without any scale (dc is scaled by the printing framework)
#if wxVERSION_NUMBER < 2900
double nScale = 1;
if( wxSFShapeCanvas::IsGCEnabled() ) dc->GetUserScale( &nScale, &nScale );
m_pCanvas->SetScale(1);
#ifdef __WXMSW__
wxSFScaledDC sdc( (wxWindowDC*)dc, nScale );
sdc.PrepareGC();
m_pCanvas->DrawContent(sdc, sfNOT_FROM_PAINT);
#else
m_pCanvas->DrawContent(*dc, sfNOT_FROM_PAINT);
#endif
m_pCanvas->SetScale(prevScale);
#else
m_pCanvas->SetScale(1);
m_pCanvas->DrawContent(*dc, sfNOT_FROM_PAINT);
m_pCanvas->SetScale(prevScale);
#endif
// restore previous canvas properties if needed
if( !m_pCanvas->ContainsStyle( wxSFShapeCanvas::sfsPRINT_BACKGROUND ) )
{
m_pCanvas->SetStyle( prevStyle );
m_pCanvas->SetCanvasColour( prevColour );
}
return true;
}
else
return false;
}
void wxSFPrintout::GetPageInfo(int *minPage, int *maxPage, int *selPageFrom, int *selPageTo)
{
*minPage = 1;
*maxPage = 1;
*selPageFrom = 1;
*selPageTo = 1;
}

View File

@@ -0,0 +1,365 @@
/***************************************************************
* Name: RectShape.cpp
* Purpose: Implements rectangular shape class
* Author: Michal Bližňák (michal.bliznak@tiscali.cz)
* Created: 2007-07-22
* Copyright: Michal Bližňák
* License: wxWidgets license (www.wxwidgets.org)
* Notes:
**************************************************************/
#include "wx_pch.h"
#ifdef _DEBUG_MSVC
#define new DEBUG_NEW
#endif
#include "wx/wxsf/RectShape.h"
#include "wx/wxsf/ShapeCanvas.h"
#include "wx/wxsf/CommonFcn.h"
// TODO: wxSFShapeBase: Implement LockAspectRation() function
using namespace wxSFCommonFcn;
XS_IMPLEMENT_CLONABLE_CLASS(wxSFRectShape, wxSFShapeBase);
wxSFRectShape::wxSFRectShape(void) : wxSFShapeBase()
{
m_nRectSize = sfdvRECTSHAPE_SIZE;
m_Border = sfdvRECTSHAPE_BORDER;
m_Fill = sfdvRECTSHAPE_FILL;
MarkSerializableDataMembers();
}
wxSFRectShape::wxSFRectShape(const wxRealPoint& pos, const wxRealPoint& size, wxSFDiagramManager* manager)
: wxSFShapeBase(pos, manager)
{
m_nRectSize = size;
m_Border = sfdvRECTSHAPE_BORDER;
m_Fill = sfdvRECTSHAPE_FILL;
MarkSerializableDataMembers();
}
wxSFRectShape::wxSFRectShape(const wxSFRectShape& obj) : wxSFShapeBase(obj)
{
m_nRectSize = obj.m_nRectSize;
m_Border = obj.m_Border;
m_Fill = obj.m_Fill;
MarkSerializableDataMembers();
}
wxSFRectShape::~wxSFRectShape(void)
{
}
void wxSFRectShape::MarkSerializableDataMembers()
{
XS_SERIALIZE_EX(m_nRectSize, wxT("size"), sfdvRECTSHAPE_SIZE);
XS_SERIALIZE_EX(m_Border, wxT("border"), sfdvRECTSHAPE_BORDER);
XS_SERIALIZE_EX(m_Fill, wxT("fill"), sfdvRECTSHAPE_FILL);
}
//----------------------------------------------------------------------------------//
// public virtual functions
//----------------------------------------------------------------------------------//
wxRect wxSFRectShape::GetBoundingBox()
{
wxRealPoint apos = this->GetAbsolutePosition();
return wxRect(wxPoint((int)apos.x, (int)apos.y), wxSize((int)m_nRectSize.x, (int)m_nRectSize.y ));
}
void wxSFRectShape::Scale(double x, double y, bool children)
{
// HINT: overload it for custom actions...
if((x > 0) && (y > 0))
{
SetRectSize(m_nRectSize.x * x, m_nRectSize.y * y);
// call default function implementation (needed for scaling of shape's children)
wxSFShapeBase::Scale(x, y, children);
}
}
void wxSFRectShape::FitToChildren()
{
// HINT: overload it for custom actions...
wxSFShapeBase* pChild;
// get bounding box of the shape and children set be inside it
wxRect chBB = this->GetBoundingBox();
wxRect shpBB = chBB;
SerializableList::compatibility_iterator node = GetFirstChildNode();
while(node)
{
pChild = (wxSFShapeBase*)node->GetData();
if( pChild->ContainsStyle(sfsALWAYS_INSIDE) )
{
pChild->GetCompleteBoundingBox(chBB, bbSELF | bbCHILDREN);
}
node = node->GetNext();
}
if(!chBB.IsEmpty())
{
//wxRect shpBB = this->GetBoundingBox();
if(!shpBB.Contains(chBB))
{
double dx = chBB.GetLeft() - shpBB.GetLeft();
double dy = chBB.GetTop() - shpBB.GetTop();
// resize parent shape
shpBB.Union(chBB);
MoveTo(shpBB.GetPosition().x, shpBB.GetPosition().y);
m_nRectSize = wxRealPoint(shpBB.GetSize().x, shpBB.GetSize().y);
// move its "1st level" children if neccessary
if((dx < 0) || (dy < 0))
{
node = GetFirstChildNode();
while(node)
{
pChild = (wxSFShapeBase*)node->GetData();
if(dx < 0)pChild->MoveBy(abs((int)dx), 0);
if(dy < 0)pChild->MoveBy(0, abs((int)dy));
node = node->GetNext();
}
}
}
}
}
//----------------------------------------------------------------------------------//
// protected virtual functions
//----------------------------------------------------------------------------------//
void wxSFRectShape::DrawNormal(wxDC& dc)
{
// HINT: overload it for custom actions...
dc.SetPen(m_Border);
dc.SetBrush(m_Fill);
dc.DrawRectangle(Conv2Point(GetAbsolutePosition()), Conv2Size(m_nRectSize));
dc.SetBrush(wxNullBrush);
dc.SetPen(wxNullPen);
}
void wxSFRectShape::DrawHover(wxDC& dc)
{
// HINT: overload it for custom actions...
dc.SetPen(wxPen(m_nHoverColor, 1));
dc.SetBrush(m_Fill);
dc.DrawRectangle(Conv2Point(GetAbsolutePosition()), Conv2Size(m_nRectSize));
dc.SetBrush(wxNullBrush);
dc.SetPen(wxNullPen);
}
void wxSFRectShape::DrawHighlighted(wxDC& dc)
{
// HINT: overload it for custom actions...
dc.SetPen(wxPen(m_nHoverColor, 2));
dc.SetBrush(m_Fill);
dc.DrawRectangle(Conv2Point(GetAbsolutePosition()), Conv2Size(m_nRectSize));
dc.SetBrush(wxNullBrush);
dc.SetPen(wxNullPen);
}
void wxSFRectShape::DrawShadow(wxDC& dc)
{
// HINT: overload it for custom actions...
if( m_Fill.GetStyle() != wxTRANSPARENT )
{
dc.SetPen(*wxTRANSPARENT_PEN);
dc.SetBrush(GetParentCanvas()->GetShadowFill());
dc.DrawRectangle(Conv2Point(GetAbsolutePosition() + GetParentCanvas()->GetShadowOffset()), Conv2Size(m_nRectSize));
dc.SetBrush(m_Fill);
dc.SetPen(wxNullPen);
}
}
void wxSFRectShape::OnRightHandle(wxSFShapeHandle& handle)
{
// HINT: overload it for custom actions...
//m_nRectSize.x = handle.GetPosition().x - GetAbsolutePosition().x;
m_nRectSize.x += handle.GetDelta().x;
}
void wxSFRectShape::OnLeftHandle(wxSFShapeHandle& handle)
{
// HINT: overload it for custom actions...
wxSFShapeBase *pChild;
//double dx = (double)handle.GetPosition().x - GetAbsolutePosition().x;
double dx = (double)handle.GetDelta().x;
// update position of children
if( !ContainsStyle(sfsLOCK_CHILDREN) )
{
SerializableList::compatibility_iterator node = GetFirstChildNode();
while(node)
{
pChild = (wxSFShapeBase*)node->GetData();
if( pChild->GetHAlign() == halignNONE )
{
pChild->MoveBy(-dx, 0);
}
node = node->GetNext();
}
}
// update position and size of the shape
m_nRectSize.x -= dx;
m_nRelativePosition.x += dx;
}
void wxSFRectShape::OnTopHandle(wxSFShapeHandle& handle)
{
// HINT: overload it for custom actions...
wxSFShapeBase *pChild;
//double dy = (double)handle.GetPosition().y - GetAbsolutePosition().y;
double dy = (double)handle.GetDelta().y;
// update position of children
if( !ContainsStyle( sfsLOCK_CHILDREN ) )
{
SerializableList::compatibility_iterator node = GetFirstChildNode();
while(node)
{
pChild = (wxSFShapeBase*)node->GetData();
if( pChild->GetVAlign() == valignNONE )
{
pChild->MoveBy(0, -dy);
}
node = node->GetNext();
}
}
// update position and size of the shape
m_nRectSize.y -= dy;
m_nRelativePosition.y += dy;
}
void wxSFRectShape::OnBottomHandle(wxSFShapeHandle& handle)
{
// HINT: overload it for custom actions...
//m_nRectSize.y = handle.GetPosition().y - GetAbsolutePosition().y;
m_nRectSize.y += handle.GetDelta().y;
}
wxRealPoint wxSFRectShape::GetBorderPoint(const wxRealPoint& start, const wxRealPoint& end)
{
// HINT: override it for custom actions ...
// the function calculates intesection of line leading from the shape center to
// given point with the shape's bounding box;
wxRealPoint intersection;
wxRect bbRct = this->GetBoundingBox();
if(LinesIntersection(wxRealPoint(bbRct.GetTopLeft().x, bbRct.GetTopLeft().y),
wxRealPoint(bbRct.GetTopRight().x + 1, bbRct.GetTopRight().y), start, end, intersection)) return intersection;
if(LinesIntersection(wxRealPoint(bbRct.GetTopRight().x + 1, bbRct.GetTopRight().y),
wxRealPoint(bbRct.GetBottomRight().x + 1, bbRct.GetBottomRight().y + 1), start, end, intersection)) return intersection;
if(LinesIntersection(wxRealPoint(bbRct.GetBottomRight().x + 1, bbRct.GetBottomRight().y + 1),
wxRealPoint(bbRct.GetBottomLeft().x, bbRct.GetBottomLeft().y + 1), start, end, intersection)) return intersection;
if(LinesIntersection(wxRealPoint(bbRct.GetBottomLeft().x, bbRct.GetBottomLeft().y + 1),
wxRealPoint(bbRct.GetTopLeft().x, bbRct.GetTopLeft().y), start, end, intersection)) return intersection;
return GetCenter();
}
//----------------------------------------------------------------------------------//
// public virtual functions
//----------------------------------------------------------------------------------//
void wxSFRectShape::CreateHandles()
{
// HINT: overload it for custom actions...
AddHandle(wxSFShapeHandle::hndLEFTTOP);
AddHandle(wxSFShapeHandle::hndTOP);
AddHandle(wxSFShapeHandle::hndRIGHTTOP);
AddHandle(wxSFShapeHandle::hndRIGHT);
AddHandle(wxSFShapeHandle::hndRIGHTBOTTOM);
AddHandle(wxSFShapeHandle::hndBOTTOM);
AddHandle(wxSFShapeHandle::hndLEFTBOTTOM);
AddHandle(wxSFShapeHandle::hndLEFT);
AddHandle(wxSFShapeHandle::hndLEFTTOP);
}
void wxSFRectShape::OnHandle(wxSFShapeHandle& handle)
{
// HINT: overload it for custom actions...
switch(handle.GetType())
{
case wxSFShapeHandle::hndLEFT:
OnLeftHandle(handle);
break;
case wxSFShapeHandle::hndLEFTTOP:
OnLeftHandle(handle);
OnTopHandle(handle);
break;
case wxSFShapeHandle::hndLEFTBOTTOM:
OnLeftHandle(handle);
OnBottomHandle(handle);
break;
case wxSFShapeHandle::hndRIGHT:
OnRightHandle(handle);
break;
case wxSFShapeHandle::hndRIGHTTOP:
OnRightHandle(handle);
OnTopHandle(handle);
break;
case wxSFShapeHandle::hndRIGHTBOTTOM:
OnRightHandle(handle);
OnBottomHandle(handle);
break;
case wxSFShapeHandle::hndTOP:
OnTopHandle(handle);
break;
case wxSFShapeHandle::hndBOTTOM:
OnBottomHandle(handle);
break;
default:
break;
}
wxSFShapeBase::OnHandle( handle );
}
void wxSFRectShape::OnBeginHandle(wxSFShapeHandle& handle)
{
m_nPrevPosition = m_nRelativePosition;
m_nPrevSize = m_nRectSize;
wxSFShapeBase::OnBeginHandle( handle );
}

View File

@@ -0,0 +1,136 @@
/***************************************************************
* Name: RoundRectShape.cpp
* Purpose: Implements rounded rectangular shape class
* Author: Michal Bližňák (michal.bliznak@tiscali.cz)
* Created: 2007-07-22
* Copyright: Michal Bližňák
* License: wxWidgets license (www.wxwidgets.org)
* Notes:
**************************************************************/
#include "wx_pch.h"
#ifdef _DEBUG_MSVC
#define new DEBUG_NEW
#endif
#include <math.h>
#include "wx/wxsf/RoundRectShape.h"
#include "wx/wxsf/ShapeCanvas.h"
#include "wx/wxsf/CommonFcn.h"
using namespace wxSFCommonFcn;
XS_IMPLEMENT_CLONABLE_CLASS(wxSFRoundRectShape, wxSFRectShape);
wxSFRoundRectShape::wxSFRoundRectShape(void) : wxSFRectShape()
{
m_nRadius = sfdvROUNDRECTSHAPE_RADIUS;
MarkSerializableDataMembers();
}
wxSFRoundRectShape::wxSFRoundRectShape(const wxRealPoint& pos, const wxRealPoint &size, double radius, wxSFDiagramManager* manager)
: wxSFRectShape(pos, size, manager)
{
m_nRadius = radius;
MarkSerializableDataMembers();
}
wxSFRoundRectShape::wxSFRoundRectShape(const wxSFRoundRectShape& obj) : wxSFRectShape(obj)
{
m_nRadius = obj.m_nRadius;
MarkSerializableDataMembers();
}
wxSFRoundRectShape::~wxSFRoundRectShape(void)
{
}
void wxSFRoundRectShape::MarkSerializableDataMembers()
{
XS_SERIALIZE_EX(m_nRadius, wxT("radius"), sfdvROUNDRECTSHAPE_RADIUS);
}
//----------------------------------------------------------------------------------//
// public virtual functions
//----------------------------------------------------------------------------------//
bool wxSFRoundRectShape::Contains(const wxPoint &pos)
{
// get original bounding box
wxRect shpBB = GetBoundingBox();
// calculate modified boxes
wxRect hr(shpBB);
hr.Deflate(0, (int)m_nRadius);
wxRect vr(shpBB);
vr.Deflate((int)m_nRadius, 0);
// test whether given position is inside body rect or rounded corners
if(hr.Contains(pos))return true;
else if(vr.Contains(pos))return true;
else if(IsInCircle(pos, shpBB.GetTopLeft() + wxPoint((int)m_nRadius, (int)m_nRadius)))return true;
else if(IsInCircle(pos, shpBB.GetBottomLeft() + wxPoint((int)m_nRadius, (int)-m_nRadius)))return true;
else if(IsInCircle(pos, shpBB.GetTopRight() + wxPoint((int)-m_nRadius, (int)m_nRadius)))return true;
else if(IsInCircle(pos, shpBB.GetBottomRight() + wxPoint((int)-m_nRadius, (int)-m_nRadius)))return true;
return false;
}
//----------------------------------------------------------------------------------//
// protected virtual functions
//----------------------------------------------------------------------------------//
void wxSFRoundRectShape::DrawNormal(wxDC& dc)
{
dc.SetPen(m_Border);
dc.SetBrush(m_Fill);
dc.DrawRoundedRectangle(Conv2Point(GetAbsolutePosition()), Conv2Size(m_nRectSize), m_nRadius);
dc.SetBrush(wxNullBrush);
dc.SetPen(wxNullPen);
}
void wxSFRoundRectShape::DrawHover(wxDC& dc)
{
dc.SetPen(wxPen(m_nHoverColor, 1));
dc.SetBrush(m_Fill);
dc.DrawRoundedRectangle(Conv2Point(GetAbsolutePosition()), Conv2Size(m_nRectSize), m_nRadius);
dc.SetBrush(wxNullBrush);
dc.SetPen(wxNullPen);
}
void wxSFRoundRectShape::DrawHighlighted(wxDC& dc)
{
dc.SetPen(wxPen(m_nHoverColor, 2));
dc.SetBrush(m_Fill);
dc.DrawRoundedRectangle(Conv2Point(GetAbsolutePosition()), Conv2Size(m_nRectSize), m_nRadius);
dc.SetBrush(wxNullBrush);
dc.SetPen(wxNullPen);
}
void wxSFRoundRectShape::DrawShadow(wxDC& dc)
{
// HINT: overload it for custom actions...
if( m_Fill.GetStyle() != wxTRANSPARENT )
{
dc.SetPen(*wxTRANSPARENT_PEN);
dc.SetBrush(GetParentCanvas()->GetShadowFill());
dc.DrawRoundedRectangle(Conv2Point(GetAbsolutePosition() + GetParentCanvas()->GetShadowOffset()), Conv2Size(m_nRectSize), m_nRadius);
dc.SetBrush(wxNullBrush);
dc.SetPen(wxNullPen);
}
}
//----------------------------------------------------------------------------------//
// public functions
//----------------------------------------------------------------------------------//
bool wxSFRoundRectShape::IsInCircle(const wxPoint& pos, const wxPoint& center)
{
return (Distance(Conv2RealPoint(center), Conv2RealPoint(pos)) <= m_nRadius);
}

View File

@@ -0,0 +1,231 @@
/***************************************************************
* Name: SFEvents.cpp
* Purpose: Implements shape events classes
* Author: Michal Bližňák (michal.bliznak@tiscali.cz)
* Created: 2007-09-11
* Copyright: Michal Bližňák
* License: wxWidgets license (www.wxwidgets.org)
* Notes:
**************************************************************/
#include "wx_pch.h"
#ifdef _DEBUG_MSVC
#define new DEBUG_NEW
#endif
#include "wx/wxsf/SFEvents.h"
DEFINE_EVENT_TYPE( wxEVT_SF_LINE_DONE );
DEFINE_EVENT_TYPE( wxEVT_SF_TEXT_CHANGE );
DEFINE_EVENT_TYPE( wxEVT_SF_ON_DROP );
DEFINE_EVENT_TYPE( wxEVT_SF_ON_PASTE );
DEFINE_EVENT_TYPE( wxEVT_SF_SHAPE_LEFT_DOWN );
DEFINE_EVENT_TYPE( wxEVT_SF_SHAPE_LEFT_DCLICK );
DEFINE_EVENT_TYPE( wxEVT_SF_SHAPE_RIGHT_DOWN );
DEFINE_EVENT_TYPE( wxEVT_SF_SHAPE_RIGHT_DCLICK);
DEFINE_EVENT_TYPE( wxEVT_SF_SHAPE_DRAG_BEGIN);
DEFINE_EVENT_TYPE( wxEVT_SF_SHAPE_DRAG );
DEFINE_EVENT_TYPE( wxEVT_SF_SHAPE_DRAG_END );
DEFINE_EVENT_TYPE( wxEVT_SF_SHAPE_HANDLE_BEGIN );
DEFINE_EVENT_TYPE( wxEVT_SF_SHAPE_HANDLE );
DEFINE_EVENT_TYPE( wxEVT_SF_SHAPE_HANDLE_END );
DEFINE_EVENT_TYPE( wxEVT_SF_SHAPE_KEYDOWN );
DEFINE_EVENT_TYPE( wxEVT_SF_SHAPE_MOUSE_ENTER );
DEFINE_EVENT_TYPE( wxEVT_SF_SHAPE_MOUSE_OVER );
DEFINE_EVENT_TYPE( wxEVT_SF_SHAPE_MOUSE_LEAVE );
DEFINE_EVENT_TYPE( wxEVT_SF_SHAPE_CHILD_DROP );
DEFINE_EVENT_TYPE( wxEVT_SF_LINE_BEFORE_DONE );
//----------------------------------------------------------------------------------//
// wxSFShapeEvent class
//----------------------------------------------------------------------------------//
wxSFShapeEvent::wxSFShapeEvent(wxEventType cmdType, int id)
: wxEvent(id, cmdType), m_Vetoed(false)
{
m_Shape = NULL;
}
wxSFShapeEvent::wxSFShapeEvent(const wxSFShapeEvent& obj)
: wxEvent(obj), m_Vetoed(obj.m_Vetoed)
{
m_Shape = obj.m_Shape;
}
wxSFShapeEvent::~wxSFShapeEvent()
{
}
//----------------------------------------------------------------------------------//
// wxSFShapeEvent class
//----------------------------------------------------------------------------------//
wxSFShapeTextEvent::wxSFShapeTextEvent(wxEventType cmdType, int id)
: wxEvent(id, cmdType)
{
m_Shape = NULL;
m_Text = wxT("");
}
wxSFShapeTextEvent::wxSFShapeTextEvent(const wxSFShapeTextEvent& obj)
: wxEvent(obj)
{
m_Shape = obj.m_Shape;
m_Text = obj.m_Text;
}
wxSFShapeTextEvent::~wxSFShapeTextEvent()
{
}
//----------------------------------------------------------------------------------//
// wxSFShapeDropEvent class
//----------------------------------------------------------------------------------//
wxSFShapeDropEvent::wxSFShapeDropEvent(wxEventType cmdType, wxCoord x, wxCoord y, wxSFShapeCanvas* target, wxDragResult def, int id)
: wxEvent(id, cmdType)
{
m_nDropPosition = wxPoint(x, y);
m_nDragResult = def;
m_pDropTarget = target;
}
wxSFShapeDropEvent::wxSFShapeDropEvent(const wxSFShapeDropEvent& obj)
: wxEvent(obj)
{
SetDroppedShapes(obj.m_lstDroppedShapes);
m_nDropPosition = obj.m_nDropPosition;
m_nDragResult = obj.m_nDragResult;
m_pDropTarget = obj.m_pDropTarget;
}
wxSFShapeDropEvent::~wxSFShapeDropEvent()
{
m_lstDroppedShapes.Clear();
}
void wxSFShapeDropEvent::SetDroppedShapes(const ShapeList &list)
{
ShapeList::compatibility_iterator node = list.GetFirst();
while(node)
{
m_lstDroppedShapes.Append(node->GetData());
node = node->GetNext();
}
}
//----------------------------------------------------------------------------------//
// wxSFShapeDropEvent class
//----------------------------------------------------------------------------------//
wxSFShapePasteEvent::wxSFShapePasteEvent(wxEventType cmdType, wxSFShapeCanvas *target, int id)
: wxEvent(id, cmdType)
{
m_pDropTarget = target;
}
wxSFShapePasteEvent::wxSFShapePasteEvent(const wxSFShapePasteEvent& obj)
: wxEvent(obj)
{
SetPastedShapes(obj.m_lstPastedShapes);
m_pDropTarget = obj.m_pDropTarget;
}
wxSFShapePasteEvent::~wxSFShapePasteEvent()
{
m_lstPastedShapes.Clear();
}
void wxSFShapePasteEvent::SetPastedShapes(const ShapeList &list)
{
ShapeList::compatibility_iterator node = list.GetFirst();
while(node)
{
m_lstPastedShapes.Append(node->GetData());
node = node->GetNext();
}
}
//----------------------------------------------------------------------------------//
// wxSFShapeKeyEvent class
//----------------------------------------------------------------------------------//
wxSFShapeKeyEvent::wxSFShapeKeyEvent(const wxSFShapeKeyEvent& obj) : wxEvent(obj)
{
m_Shape = obj.m_Shape;
m_KeyCode = obj.m_KeyCode;
}
wxSFShapeKeyEvent::wxSFShapeKeyEvent(wxEventType cmdType, int id) : wxEvent(id, cmdType)
{
m_Shape = NULL;
m_KeyCode = 0;
}
wxSFShapeKeyEvent::~wxSFShapeKeyEvent()
{
}
//----------------------------------------------------------------------------------//
// wxSFShapeHandleEvent class
//----------------------------------------------------------------------------------//
wxSFShapeHandleEvent::wxSFShapeHandleEvent(const wxSFShapeHandleEvent& obj) : wxEvent(obj)
{
m_Shape = obj.m_Shape;
m_Handle = obj.m_Handle;
}
wxSFShapeHandleEvent::wxSFShapeHandleEvent(wxEventType cmdType, int id) : wxEvent(id, cmdType)
{
m_Shape = NULL;
m_Handle = NULL;
}
wxSFShapeHandleEvent::~wxSFShapeHandleEvent()
{
}
//----------------------------------------------------------------------------------//
// wxSFShapeChildDropEvent class
//----------------------------------------------------------------------------------//
wxSFShapeChildDropEvent::wxSFShapeChildDropEvent(const wxSFShapeChildDropEvent& obj) : wxEvent(obj)
{
m_Shape = obj.m_Shape;
m_ChildShape = obj.m_ChildShape;
}
wxSFShapeChildDropEvent::wxSFShapeChildDropEvent(wxEventType cmdType, int id) : wxEvent(id, cmdType)
{
m_Shape = NULL;
m_ChildShape = NULL;
}
wxSFShapeChildDropEvent::~wxSFShapeChildDropEvent()
{
}
//----------------------------------------------------------------------------------//
// wxSFShapeMouseEvent class
//----------------------------------------------------------------------------------//
wxSFShapeMouseEvent::wxSFShapeMouseEvent(const wxSFShapeMouseEvent& obj) : wxEvent(obj)
{
m_Shape = obj.m_Shape;
m_MousePosition = obj.m_MousePosition;
}
wxSFShapeMouseEvent::wxSFShapeMouseEvent(wxEventType cmdType, int id) : wxEvent(id, cmdType)
{
m_Shape = NULL;
m_MousePosition = wxDefaultPosition;
}
wxSFShapeMouseEvent::~wxSFShapeMouseEvent()
{
}

View File

@@ -0,0 +1,683 @@
/***************************************************************
* Name: ScaledDC.cpp
* Purpose: Implements scaled DC class
* Author: Michal Bližňák (michal.bliznak@tiscali.cz)
* Created: 2008-11-7
* Copyright: Michal Bližňák
* License: wxWidgets license (www.wxwidgets.org)
* Notes:
**************************************************************/
#include "wx_pch.h"
#ifdef _DEBUG_MSVC
#define new DEBUG_NEW
#endif
#include "wx/wxsf/ScaledDC.h"
#if wxVERSION_NUMBER >= 2900
wxSFScaledDC::wxSFScaledDC( wxWindowDC *target, double scale) : wxDC( new wxSFDCImplWrapper( target->GetImpl(), scale ) )
{
}
wxSFScaledDC::~wxSFScaledDC()
{
}
#else // ! wxVERSION_NUMBER >= 2900
#include "wx/wxsf/CommonFcn.h"
bool wxSFScaledDC::m_fEnableGC = false;
//----------------------------------------------------------------------------------//
// Constructor and destructor
//----------------------------------------------------------------------------------//
wxSFScaledDC::wxSFScaledDC( wxWindowDC *target, double scale)
{
m_nScale = scale;
m_pTargetDC = target;
#if wxUSE_GRAPHICS_CONTEXT
m_pGC = wxGraphicsContext::Create( *m_pTargetDC );
//m_pGC->Scale( scale, scale );
#endif
}
wxSFScaledDC::~wxSFScaledDC()
{
#if wxUSE_GRAPHICS_CONTEXT
if( m_pGC ) delete m_pGC;
#endif
}
//----------------------------------------------------------------------------------//
// wxGraphicContext related functions
//----------------------------------------------------------------------------------//
void wxSFScaledDC::InitGC()
{
#if wxUSE_GRAPHICS_CONTEXT
m_pGC->PushState();
m_pGC->Scale( m_nScale, m_nScale );
/*m_pGC->SetPen( this->GetPen() );
m_pGC->SetBrush( this->GetBrush() );
m_pGC->SetFont( this->GetFont(), this->GetTextForeground() );*/
#endif
}
void wxSFScaledDC::UninitGC()
{
#if wxUSE_GRAPHICS_CONTEXT
/*m_pGC->SetPen( wxNullPen );
m_pGC->SetBrush( wxNullBrush );
m_pGC->SetFont( wxNullFont, *wxBLACK );*/
m_pGC->PopState();
#endif
}
void wxSFScaledDC::PrepareGC()
{
#if wxUSE_GRAPHICS_CONTEXT && !defined(__WXMAC__)
int x, y;
GetDeviceOrigin(&x, &y);
//m_pGC->Translate( x / m_nScale, y / m_nScale );
m_pGC->Translate( x, y );
#endif
}
//----------------------------------------------------------------------------------//
// Wrapped wxDC functions
//----------------------------------------------------------------------------------//
void wxSFScaledDC::CalcBoundingBox(wxCoord x, wxCoord y)
{
m_pTargetDC->CalcBoundingBox(x, y);
}
bool wxSFScaledDC::CanDrawBitmap() const
{
return m_pTargetDC->CanDrawBitmap();
}
bool wxSFScaledDC::CanGetTextExtent() const
{
return m_pTargetDC->CanGetTextExtent();
}
void wxSFScaledDC::Clear()
{
m_pTargetDC->Clear();
}
void wxSFScaledDC::ComputeScaleAndOrigin()
{
m_pTargetDC->ComputeScaleAndOrigin();
}
bool wxSFScaledDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height, wxDC* source, wxCoord xsrc, wxCoord ysrc, int rop, bool useMask, wxCoord xsrcMask, wxCoord ysrcMask)
{
return m_pTargetDC->Blit( Scale(xdest), Scale(ydest), width, height, source, xsrc, ysrc, rop, useMask, xsrcMask, ysrcMask);
}
void wxSFScaledDC::DoCrossHair(wxCoord x, wxCoord y)
{
m_pTargetDC->CrossHair( Scale(x), Scale(y) );
}
void wxSFScaledDC::DoDrawArc(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2, wxCoord xc, wxCoord yc)
{
if( m_fEnableGC )
{
#if wxUSE_GRAPHICS_CONTEXT
InitGC();
wxGraphicsPath path = m_pGC->CreatePath();
double dist, sang, eang;
dist = wxSFCommonFcn::Distance( wxRealPoint(x2, y2), wxRealPoint(xc, yc) );
sang = acos( (x2 - xc) / dist ) + ( yc > y2 ? wxSF::PI : 0 );
dist = wxSFCommonFcn::Distance( wxRealPoint(x1, y1), wxRealPoint(xc, yc) );
eang = acos( (x1 - xc) / dist ) + ( yc > y1 ? wxSF::PI : 0 );
path.AddArc( xc, yc, dist, sang, eang, true );
m_pGC->StrokePath( path );
UninitGC();
#endif
}
else
m_pTargetDC->DrawArc(Scale(x1), Scale(y1), Scale(x2), Scale(y2), Scale(xc), Scale(yc));
}
void wxSFScaledDC::DoDrawBitmap(const wxBitmap& bmp, wxCoord x, wxCoord y, bool useMask)
{
if( m_fEnableGC )
{
#if wxUSE_GRAPHICS_CONTEXT
InitGC();
m_pGC->DrawBitmap( bmp, x, y, bmp.GetWidth(), bmp.GetHeight() );
UninitGC();
#endif
}
else
m_pTargetDC->DrawBitmap( bmp, Scale(x), Scale(y), useMask );
}
void wxSFScaledDC::DoDrawCheckMark(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
{
m_pTargetDC->DrawCheckMark(Scale(x), Scale(y), Scale(width), Scale(height));
}
void wxSFScaledDC::DoDrawEllipse(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
{
if( m_fEnableGC )
{
#if wxUSE_GRAPHICS_CONTEXT
InitGC();
m_pGC->DrawEllipse(x, y, width, height );
UninitGC();
#endif
}
else
m_pTargetDC->DrawEllipse( Scale(x), Scale(y), Scale(width), Scale(height) );
}
void wxSFScaledDC::DoDrawEllipticArc(wxCoord x, wxCoord y, wxCoord w, wxCoord h, double sa, double ea)
{
m_pTargetDC->DrawEllipticArc(Scale(x), Scale(y), Scale(w), Scale(h), sa, ea);
}
void wxSFScaledDC::DoDrawIcon(const wxIcon& icon, wxCoord x, wxCoord y)
{
m_pTargetDC->DrawIcon( icon, Scale(x), Scale(y) );
}
void wxSFScaledDC::DoDrawLine(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
{
if( m_fEnableGC )
{
#if wxUSE_GRAPHICS_CONTEXT
InitGC();
m_pGC->StrokeLine(x1, y1, x2, y2);
UninitGC();
#endif
}
else
m_pTargetDC->DrawLine(Scale(x1), Scale(y1), Scale(x2), Scale(y2));
}
void wxSFScaledDC::DoDrawLines(int n, wxPoint points[], wxCoord xoffset, wxCoord yoffset)
{
if( m_fEnableGC )
{
#if wxUSE_GRAPHICS_CONTEXT
InitGC();
wxPoint2DDouble *pts = new wxPoint2DDouble[n];
for(int i = 0; i < n; i++)
{
pts[0].m_x = points[0].x;
pts[0].m_y = points[0].y;
}
m_pGC->StrokeLines(n, pts);
delete [] pts;
UninitGC();
#endif
}
else
{
wxPoint *updPoints = new wxPoint[n];
for(int i = 0; i < n; i++)
{
updPoints[i].x = (int)((double)points[i].x*m_nScale);
updPoints[i].y = (int)((double)points[i].y*m_nScale);
}
m_pTargetDC->DrawLines(n, updPoints, Scale(xoffset), Scale(yoffset));
delete [] updPoints;
}
}
void wxSFScaledDC::DoDrawPoint(wxCoord x, wxCoord y)
{
if( m_fEnableGC )
{
#if wxUSE_GRAPHICS_CONTEXT
InitGC();
m_pGC->StrokeLine(x, y, x+1, y);
UninitGC();
#endif
}
else
m_pTargetDC->DrawPoint(Scale(x), Scale(y));
}
void wxSFScaledDC::DoDrawPolyPolygon(int n, int count[], wxPoint points[], wxCoord xoffset, wxCoord yoffset, int fillStyle)
{
if( m_fEnableGC )
{
#if wxUSE_GRAPHICS_CONTEXT
int nIndex = 0;
InitGC();
wxGraphicsPath gcPath = m_pGC->CreatePath();
for(int i = 0; i < n; i++)
{
gcPath.MoveToPoint( points[nIndex].x, points[nIndex].y );
for(int j = 0; j < count[i]; j++)
{
nIndex++;
gcPath.AddLineToPoint( points[nIndex].x, points[nIndex].y );
}
gcPath.CloseSubpath();
}
m_pGC->Translate( xoffset, yoffset );
m_pGC->DrawPath( gcPath );
UninitGC();
#endif
}
else
{
int nTotalPoints = 0;
for(int i = 0; i < n; i++)nTotalPoints += count[i];
wxPoint *updPoints = new wxPoint[nTotalPoints];
for(int i = 0; i < nTotalPoints; i++)
{
updPoints[i].x = (int)((double)points[i].x*m_nScale);
updPoints[i].y = (int)((double)points[i].y*m_nScale);
}
m_pTargetDC->DrawPolyPolygon(n, count, updPoints, Scale(xoffset), Scale(yoffset), fillStyle);
delete [] updPoints;
}
}
void wxSFScaledDC::DoDrawPolygon(int n, wxPoint points[], wxCoord xoffset, wxCoord yoffset, int fillStyle)
{
if( m_fEnableGC )
{
#if wxUSE_GRAPHICS_CONTEXT
InitGC();
wxGraphicsPath gcPath = m_pGC->CreatePath();
gcPath.MoveToPoint( points[0].x, points[0].y );
for(int i = 1; i < n; i++)
{
gcPath.AddLineToPoint( points[i].x, points[i].y );
}
gcPath.CloseSubpath();
m_pGC->DrawPath( gcPath );
UninitGC();
#endif
}
else
{
wxPoint *updPoints = new wxPoint[n];
for(int i = 0; i < n; i++)
{
updPoints[i].x = (int)((double)points[i].x*m_nScale);
updPoints[i].y = (int)((double)points[i].y*m_nScale);
}
m_pTargetDC->DrawPolygon(n, updPoints, Scale(xoffset), Scale(yoffset), fillStyle);
delete [] updPoints;
}
}
void wxSFScaledDC::DoDrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
{
if( m_fEnableGC )
{
#if wxUSE_GRAPHICS_CONTEXT
InitGC();
m_pGC->DrawRectangle(x, y, width, height);
UninitGC();
#endif
}
else
m_pTargetDC->DrawRectangle(Scale(x), Scale(y), Scale(width), Scale(height));
}
void wxSFScaledDC::DoDrawRotatedText(const wxString& text, wxCoord x, wxCoord y, double angle)
{
if( m_fEnableGC )
{
#if wxUSE_GRAPHICS_CONTEXT
InitGC();
m_pGC->DrawText( text, x, y, angle );
UninitGC();
#endif
}
else
{
wxFont font = GetFont();
wxFont prevfont = font;
if(font != wxNullFont)
{
font.SetPointSize(int(font.GetPointSize()*m_nScale));
SetFont(font);
}
m_pTargetDC->DrawRotatedText(text, Scale(x), Scale(y), angle);
SetFont(prevfont);
}
}
void wxSFScaledDC::DoDrawRoundedRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height, double radius)
{
if( m_fEnableGC )
{
#if wxUSE_GRAPHICS_CONTEXT
InitGC();
m_pGC->DrawRoundedRectangle(x, y, width, height, radius);
UninitGC();
#endif
}
else
m_pTargetDC->DrawRoundedRectangle(Scale(x), Scale(y), Scale(width), Scale(height), radius*m_nScale);
}
void wxSFScaledDC::DoDrawSpline(wxList* points)
{
m_pTargetDC->DrawSpline( points );
}
void wxSFScaledDC::DoDrawText(const wxString& text, wxCoord x, wxCoord y)
{
if( m_fEnableGC )
{
#if wxUSE_GRAPHICS_CONTEXT
InitGC();
m_pGC->DrawText( text, x, y );
UninitGC();
#endif
}
else
{
wxFont font = GetFont();
wxFont prevfont = font;
if(font != wxNullFont)
{
int scaledSize = int(font.GetPointSize()*m_nScale);
font.SetPointSize( scaledSize ? scaledSize : 1 );
SetFont(font);
}
m_pTargetDC->DrawText(text, Scale(x), Scale(y));
SetFont(prevfont);
}
}
bool wxSFScaledDC::DoFloodFill(wxCoord x, wxCoord y, const wxColour& col, int style)
{
return m_pTargetDC->FloodFill( Scale(x), Scale(y), col, style );
}
wxBitmap wxSFScaledDC::DoGetAsBitmap(const wxRect *subrect) const
{
return m_pTargetDC->GetAsBitmap( subrect );
}
void wxSFScaledDC::DoGetClippingBox(wxCoord* x, wxCoord* y, wxCoord* w, wxCoord* h) const
{
m_pTargetDC->GetClippingBox( x, y, w, h );
}
void wxSFScaledDC::DoGetClippingRegion(wxCoord* x, wxCoord* y, wxCoord* w, wxCoord* h)
{
wxUnusedVar( x );
wxUnusedVar( y );
wxUnusedVar( w );
wxUnusedVar( h );
// not implemented...
}
void wxSFScaledDC::DoGetDeviceOrigin(wxCoord* x, wxCoord* y) const
{
m_pTargetDC->GetDeviceOrigin( x, y );
}
void wxSFScaledDC::DoGetLogicalOrigin(wxCoord* x, wxCoord* y) const
{
m_pTargetDC->GetLogicalOrigin( x, y );
}
bool wxSFScaledDC::DoGetPartialTextExtents(const wxString& text, wxArrayInt& widths) const
{
return m_pTargetDC->GetPartialTextExtents( text, widths );
}
bool wxSFScaledDC::DoGetPixel(wxCoord x, wxCoord y, wxColour* col) const
{
return m_pTargetDC->GetPixel( x, y, col );
}
void wxSFScaledDC::DoGetSize(int* width, int* height) const
{
m_pTargetDC->GetSize( width, height );
}
void wxSFScaledDC::DoGetSizeMM(int* width, int* height) const
{
m_pTargetDC->GetSizeMM( width, height );
}
void wxSFScaledDC::DoGetTextExtent(const wxString& string, wxCoord* x, wxCoord* y, wxCoord* descent, wxCoord* externalLeading, wxFont* theFont) const
{
m_pTargetDC->GetTextExtent( string, x, y, descent, externalLeading, theFont );
}
void wxSFScaledDC::DoGradientFillConcentric(const wxRect& rect, const wxColour& initialColour, const wxColour& destColour, const wxPoint& circleCenter)
{
wxRect updRct( rect.x * m_nScale, rect.y * m_nScale, rect.width * m_nScale, rect.height * m_nScale );
m_pTargetDC->GradientFillConcentric( updRct, initialColour, destColour, circleCenter);
}
void wxSFScaledDC::DoGradientFillLinear(const wxRect& rect, const wxColour& initialColour, const wxColour& destColour, wxDirection nDirection)
{
wxRect updRct( rect.x * m_nScale, rect.y * m_nScale, rect.width * m_nScale, rect.height * m_nScale );
m_pTargetDC->GradientFillLinear( updRct, initialColour, destColour, nDirection );
}
void wxSFScaledDC::DoSetClippingRegion(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
{
m_pTargetDC->SetClippingRegion( x, y, width, height );
}
void wxSFScaledDC::DoSetClippingRegionAsRegion(const wxRegion& region)
{
wxUnusedVar( region );
// not implemented...
}
void wxSFScaledDC::DrawObject(wxDrawObject* drawobject)
{
m_pTargetDC->DrawObject( drawobject );
}
void wxSFScaledDC::EndDoc()
{
m_pTargetDC->EndDoc();
}
void wxSFScaledDC::EndPage()
{
m_pTargetDC->EndPage();
}
const wxBrush& wxSFScaledDC::GetBackground() const
{
return m_pTargetDC->GetBackground();
}
int wxSFScaledDC::GetBackgroundMode() const
{
return m_pTargetDC->GetBackgroundMode();
}
const wxBrush& wxSFScaledDC::GetBrush() const
{
return m_pTargetDC->GetBrush();
}
wxCoord wxSFScaledDC::GetCharHeight() const
{
return m_pTargetDC->GetCharHeight();
}
wxCoord wxSFScaledDC::GetCharWidth() const
{
return m_pTargetDC->GetCharWidth();
}
int wxSFScaledDC::GetDepth() const
{
return m_pTargetDC->GetDepth();
}
const wxFont& wxSFScaledDC::GetFont() const
{
return m_pTargetDC->GetFont();
}
#ifdef __WXGTK__
GdkWindow* wxSFScaledDC::GetGDKWindow() const
{
return m_pTargetDC->GetGDKWindow();
}
#endif
wxLayoutDirection wxSFScaledDC::GetLayoutDirection() const
{
return m_pTargetDC->GetLayoutDirection();
}
int wxSFScaledDC::GetLogicalFunction() const
{
return m_pTargetDC->GetLogicalFunction();
}
void wxSFScaledDC::GetLogicalScale(double* x, double* y)
{
m_pTargetDC->GetLogicalScale( x, y );
}
int wxSFScaledDC::GetMapMode() const
{
return m_pTargetDC->GetMapMode();
}
void wxSFScaledDC::GetMultiLineTextExtent(const wxString& string, wxCoord* width, wxCoord* height, wxCoord* heightLine, wxFont* font) const
{
m_pTargetDC->GetMultiLineTextExtent( string, width, height, heightLine, font );
}
wxSize wxSFScaledDC::GetPPI() const
{
return m_pTargetDC->GetPPI();
}
const wxPen& wxSFScaledDC::GetPen() const
{
return m_pTargetDC->GetPen();
}
wxBitmap wxSFScaledDC::GetSelectedBitmap() const
{
#ifndef __WXMAC__
return m_pTargetDC->GetSelectedBitmap();
#else
return wxNullBitmap;
#endif
}
const wxColour& wxSFScaledDC::GetTextBackground() const
{
return m_pTargetDC->GetTextBackground();
}
const wxColour& wxSFScaledDC::GetTextForeground() const
{
return m_pTargetDC->GetTextForeground();
}
void wxSFScaledDC::GetUserScale(double* x, double* y) const
{
m_pTargetDC->GetUserScale( x, y );
}
bool wxSFScaledDC::IsOk() const
{
return m_pTargetDC->IsOk();
}
bool wxSFScaledDC::Ok() const
{
return m_pTargetDC->Ok();
}
void wxSFScaledDC::SetAxisOrientation(bool xLeftRight, bool yBottomUp)
{
m_pTargetDC->SetAxisOrientation( xLeftRight, yBottomUp );
}
void wxSFScaledDC::SetBackground(const wxBrush& brush)
{
m_pTargetDC->SetBackground( brush );
}
void wxSFScaledDC::SetBackgroundMode(int mode)
{
m_pTargetDC->SetBackgroundMode( mode );
}
void wxSFScaledDC::SetBrush(const wxBrush& brush)
{
if( m_fEnableGC )
{
#if wxUSE_GRAPHICS_CONTEXT
m_pGC->SetBrush( brush );
#endif
}
m_pTargetDC->SetBrush( brush );
}
void wxSFScaledDC::SetDeviceOrigin(wxCoord x, wxCoord y)
{
m_pTargetDC->SetDeviceOrigin( x, y );
}
void wxSFScaledDC::SetFont(const wxFont& font)
{
if( m_fEnableGC )
{
#if wxUSE_GRAPHICS_CONTEXT
m_pGC->SetFont( font, this->GetTextForeground() );
#endif
}
m_pTargetDC->SetFont( font );
}
void wxSFScaledDC::SetLayoutDirection(wxLayoutDirection dir)
{
m_pTargetDC->SetLayoutDirection( dir );
}
void wxSFScaledDC::SetLogicalFunction(int function)
{
m_pTargetDC->SetLogicalFunction( function );
}
void wxSFScaledDC::SetLogicalOrigin(wxCoord x, wxCoord y)
{
m_pTargetDC->SetLogicalOrigin( x, y );
}
void wxSFScaledDC::SetLogicalScale(double x, double y)
{
m_pTargetDC->SetLogicalScale( x, y );
}
void wxSFScaledDC::SetMapMode(int mode)
{
m_pTargetDC->SetMapMode( mode );
}
void wxSFScaledDC::SetPalette(const wxPalette& palette)
{
m_pTargetDC->SetPalette( palette );
}
void wxSFScaledDC::SetPen(const wxPen& pen)
{
if( m_fEnableGC )
{
#if wxUSE_GRAPHICS_CONTEXT
m_pGC->SetPen( pen );
#endif
}
m_pTargetDC->SetPen( pen );
}
void wxSFScaledDC::SetTextBackground(const wxColour& colour)
{
m_pTargetDC->SetTextBackground( colour );
}
void wxSFScaledDC::SetTextForeground(const wxColour& colour)
{
m_pTargetDC->SetTextForeground( colour );
}
void wxSFScaledDC::SetUserScale(double x, double y)
{
m_pTargetDC->SetUserScale( x, y );
}
bool wxSFScaledDC::StartDoc( const wxString& message )
{
return m_pTargetDC->StartDoc( message );
}
void wxSFScaledDC::StartPage()
{
m_pTargetDC->StartPage();
}
#endif // wxVERSION_NUMBER >= 2900

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,50 @@
/***************************************************************
* Name: ShapeBaseXml.cpp
* Purpose: Implements basic shape's serialization capability
* Author: Michal Bližňák (michal.bliznak@tiscali.cz)
* Created: 2007-07-22
* Copyright: Michal Bližňák
* License: wxWidgets license (www.wxwidgets.org)
* Notes:
**************************************************************/
#include "wx_pch.h"
#ifdef _DEBUG_MSVC
#define new DEBUG_NEW
#endif
#include "wx/wxsf/ShapeBase.h"
#include "wx/wxsf/CommonFcn.h"
//----------------------------------------------------------------------------------//
// Serialization
//----------------------------------------------------------------------------------//
wxXmlNode* wxSFShapeBase::Serialize(wxXmlNode* node)
{
// HINT: overload it for custom actions...
node = xsSerializable::Serialize(node);
return node;
}
void wxSFShapeBase::Deserialize(wxXmlNode* node)
{
// HINT: overload it for custom actions...
xsSerializable::Deserialize(node);
if( m_pUserData )
{
m_pUserData->SetParent(this);
}
// update fixed connection points
for( ConnectionPointList::iterator it = m_lstConnectionPts.begin(); it != m_lstConnectionPts.end(); ++it )
{
wxSFConnectionPoint *pCp = (wxSFConnectionPoint*) *it;
pCp->SetParentShape( this );
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,92 @@
/***************************************************************
* Name: ShapeDataObject.cpp
* Purpose: Implements shape data object class
* Author: Michal Bližňák (michal.bliznak@tiscali.cz)
* Created: 2007-07-22
* Copyright: Michal Bližňák
* License: wxWidgets license (www.wxwidgets.org)
* Notes:
**************************************************************/
#include "wx_pch.h"
#ifdef _DEBUG_MSVC
#define new DEBUG_NEW
#endif
#include <wx/mstream.h>
#include "wx/wxsf/ShapeDataObject.h"
wxSFShapeDataObject::wxSFShapeDataObject(const wxDataFormat& format)
: wxDataObjectSimple(format)
{
m_Data.SetText(wxT("<?xml version=\"1.0\" encoding=\"utf-8\"?><chart />"));
}
wxSFShapeDataObject::wxSFShapeDataObject(const wxDataFormat& format, const ShapeList& selection, wxSFDiagramManager* manager)
: wxDataObjectSimple(format)
{
m_Data.SetText(SerializeSelectedShapes(selection, manager));
}
wxSFShapeDataObject::~wxSFShapeDataObject(void)
{
}
wxString wxSFShapeDataObject::SerializeSelectedShapes(const ShapeList& selection, wxSFDiagramManager* manager)
{
// create root node
wxSFShapeBase *pShape;
wxXmlNode *root = new wxXmlNode(wxXML_ELEMENT_NODE, wxT("chart"));
// serialize copied shapes to XML node
ShapeList::compatibility_iterator node = selection.GetFirst();
while(node)
{
pShape = node->GetData();
if(pShape)
{
// serialize parent's children
manager->SerializeObjects(pShape, root, serINCLUDE_PARENTS);
}
node = node->GetNext();
}
// create XML document in the memory stream
wxMemoryOutputStream outstream;
wxXmlDocument xmlDoc;
xmlDoc.SetRoot(root);
xmlDoc.Save(outstream);
char *buffer = new char [outstream.GetSize()];
if(buffer)
{
memset(buffer, 0, outstream.GetSize());
outstream.CopyTo(buffer, outstream.GetSize()-1);
wxString output(buffer, wxConvUTF8);
delete [] buffer;
return output;
}
else
return wxT("<?xml version=\"1.0\" encoding=\"utf-8\"?><chart />");
}
size_t wxSFShapeDataObject::GetDataSize() const
{
return m_Data.GetDataSize();
}
bool wxSFShapeDataObject::GetDataHere(void* buf) const
{
return m_Data.GetDataHere(buf);
}
bool wxSFShapeDataObject::SetData(size_t len, const void* buf)
{
return m_Data.SetData(len, buf);
}

View File

@@ -0,0 +1,318 @@
/***************************************************************
* Name: ShapeHandle.cpp
* Purpose: Implements shape handle class
* Author: Michal Bližňák (michal.bliznak@tiscali.cz)
* Created: 2007-07-22
* Copyright: Michal Bližňák
* License: wxWidgets license (www.wxwidgets.org)
* Notes:
**************************************************************/
#include "wx_pch.h"
#ifdef _DEBUG_MSVC
#define new DEBUG_NEW
#endif
#include "wx/wxsf/ShapeCanvas.h"
#include "wx/wxsf/ShapeHandle.h"
#include "wx/wxsf/ShapeBase.h"
#include <wx/listimpl.cpp>
IMPLEMENT_DYNAMIC_CLASS(wxSFShapeHandle, wxObject);
WX_DEFINE_LIST(HandleList);
wxSFShapeHandle::wxSFShapeHandle(void)
{
// initialize data members
m_nType = hndUNDEF;
m_pParentShape = NULL;
m_nPrevPos = wxPoint(0, 0);
m_nCurrPos = wxPoint(0, 0);
m_nId = -1;
m_fVisible = false;
m_fMouseOver = false;
}
wxSFShapeHandle::wxSFShapeHandle(wxSFShapeBase* parent, HANDLETYPE type, long id)
{
// initialize data members
m_nType = type;
m_pParentShape = parent;
m_nPrevPos = wxPoint(0, 0);
m_nCurrPos = wxPoint(0, 0);
m_nId = id;
m_fVisible = false;
m_fMouseOver = false;
}
wxSFShapeHandle::wxSFShapeHandle(const wxSFShapeHandle& obj)
: wxObject(obj)
{
// initialize data members
m_nType = obj.m_nType;
m_pParentShape = obj.m_pParentShape;
m_nPrevPos = wxPoint(0, 0);
m_nCurrPos = wxPoint(0, 0);
m_nId = obj.m_nId;
m_fVisible = obj.m_fVisible;
m_fMouseOver = obj.m_fMouseOver;
}
wxSFShapeHandle::~wxSFShapeHandle(void)
{
}
//----------------------------------------------------------------------------------//
// Public functions
//----------------------------------------------------------------------------------//
bool wxSFShapeHandle::Contains(const wxPoint& pos)
{
return GetHandleRect().Contains(pos);
}
void wxSFShapeHandle::Draw(wxDC& dc)
{
if(m_fVisible && m_pParentShape)
{
if(m_fMouseOver)DrawHover(dc);
else
DrawNormal(dc);
}
}
void wxSFShapeHandle::Refresh()
{
if( m_pParentShape ) m_pParentShape->Refresh( sfDELAYED );
}
//----------------------------------------------------------------------------------//
// Protected functions
//----------------------------------------------------------------------------------//
void wxSFShapeHandle::DrawNormal(wxDC& dc)
{
#ifdef __WXGTK__
dc.SetPen(*wxTRANSPARENT_PEN);
#else
dc.SetPen(*wxBLACK_PEN);
#endif
#if wxUSE_GRAPHICS_CONTEXT
if( wxSFShapeCanvas::IsGCEnabled() )
{
dc.SetBrush( wxColour(0, 0, 0, 128) );
}
else
{
dc.SetBrush(*wxBLACK_BRUSH);
dc.SetLogicalFunction(wxINVERT);
}
#else
dc.SetBrush(*wxBLACK_BRUSH);
dc.SetLogicalFunction(wxINVERT);
#endif
dc.DrawRectangle(GetHandleRect());
dc.SetLogicalFunction(wxCOPY);
dc.SetPen(wxNullPen);
dc.SetBrush(wxNullBrush);
}
void wxSFShapeHandle::DrawHover(wxDC& dc)
{
if(m_pParentShape->ContainsStyle(wxSFShapeBase::sfsSIZE_CHANGE))
{
dc.SetPen(*wxBLACK_PEN);
dc.SetBrush(wxBrush(m_pParentShape->GetHoverColour()));
dc.DrawRectangle(GetHandleRect());
dc.SetBrush(wxNullBrush);
dc.SetPen(wxNullPen);
}
else
{
DrawNormal(dc);
}
}
wxRect wxSFShapeHandle::GetHandleRect() const
{
if(m_pParentShape)
{
wxRect hrct;
wxRect brct = m_pParentShape->GetBoundingBox();
switch(m_nType)
{
case hndLEFTTOP:
hrct = wxRect(brct.GetLeftTop(), wxSize(7,7));
break;
case hndTOP:
hrct = wxRect(wxPoint(brct.GetLeft() + brct.GetWidth()/2, brct.GetTop()), wxSize(7,7));
break;
case hndRIGHTTOP:
hrct = wxRect(brct.GetRightTop(), wxSize(7,7));
break;
case hndRIGHT:
hrct = wxRect(wxPoint(brct.GetRight(), brct.GetTop() + brct.GetHeight()/2), wxSize(7,7));
break;
case hndRIGHTBOTTOM:
hrct = wxRect(brct.GetRightBottom(), wxSize(7,7));
break;
case hndBOTTOM:
hrct = wxRect(wxPoint(brct.GetLeft() + brct.GetWidth()/2, brct.GetBottom()), wxSize(7,7));
break;
case hndLEFTBOTTOM:
hrct = wxRect(brct.GetLeftBottom(), wxSize(7,7));
break;
case hndLEFT:
hrct = wxRect(wxPoint(brct.GetLeft(), brct.GetTop() + brct.GetHeight()/2), wxSize(7,7));
break;
case hndLINECTRL:
{
wxRealPoint* pt = ((wxSFLineShape*)m_pParentShape)->GetControlPoints().Item(m_nId)->GetData();
hrct = wxRect(wxPoint((int)pt->x, (int)pt->y), wxSize(7,7));
}
break;
case hndLINEEND:
case hndLINESTART:
{
wxSFLineShape *pLine = (wxSFLineShape*)m_pParentShape;
wxRealPoint pt;
if( m_nType == hndLINESTART )
{
pt = pLine->GetSrcPoint();
}
else
pt = pLine->GetTrgPoint();
hrct = wxRect(wxPoint((int)pt.x, (int)pt.y), wxSize(7,7));
}
break;
default:
hrct = wxRect();
}
hrct.Offset(-3, -3);
return hrct;
}
else
return wxRect();
}
//----------------------------------------------------------------------------------//
// Private functions
//----------------------------------------------------------------------------------//
void wxSFShapeHandle::_OnBeginDrag(const wxPoint& pos)
{
m_nPrevPos = m_nStartPos = m_nCurrPos = pos;
if(m_pParentShape)m_pParentShape->OnBeginHandle(*this);
}
void wxSFShapeHandle::_OnDragging(const wxPoint& pos)
{
if(m_fVisible && m_pParentShape && m_pParentShape->ContainsStyle(wxSFShapeBase::sfsSIZE_CHANGE))
{
if(pos != m_nPrevPos)
{
wxRect prevRct = m_pParentShape->GetBoundingBox();
m_nCurrPos = pos;
switch(m_nType)
{
case hndLEFTTOP:
if((pos.x < prevRct.GetRight()) && (pos.y < prevRct.GetBottom()))
m_pParentShape->_OnHandle(*this);
break;
case hndTOP:
if(pos.y < prevRct.GetBottom())
m_pParentShape->_OnHandle(*this);
break;
case hndRIGHTTOP:
if((pos.x > prevRct.GetLeft()) && (pos.y < prevRct.GetBottom()))
m_pParentShape->_OnHandle(*this);
break;
case hndRIGHT:
if(pos.x > prevRct.GetLeft())
m_pParentShape->_OnHandle(*this);
break;
case hndRIGHTBOTTOM:
if((pos.x > prevRct.GetLeft()) && (pos.y > prevRct.GetTop()))
m_pParentShape->_OnHandle(*this);
break;
case hndBOTTOM:
if(pos.y > prevRct.GetTop())
m_pParentShape->_OnHandle(*this);
break;
case hndLEFTBOTTOM:
if((pos.x < prevRct.GetRight()) && (pos.y > prevRct.GetTop()))
m_pParentShape->_OnHandle(*this);
break;
case hndLEFT:
if(pos.x < prevRct.GetRight())
m_pParentShape->_OnHandle(*this);
break;
case hndLINESTART:
case hndLINEEND:
case hndLINECTRL:
m_pParentShape->_OnHandle(*this);
break;
default:
break;
}
}
m_nPrevPos = pos;
}
}
void wxSFShapeHandle::_OnEndDrag(const wxPoint& pos)
{
wxUnusedVar( pos );
if(m_pParentShape)m_pParentShape->OnEndHandle(*this);
}
void wxSFShapeHandle::_OnMouseMove(const wxPoint& pos)
{
if(m_fVisible)
{
if(Contains(pos))
{
if(!m_fMouseOver)
{
m_fMouseOver = true;
Refresh();
}
}
else
{
if(m_fMouseOver)
{
m_fMouseOver = false;
Refresh();
}
}
}
}

View File

@@ -0,0 +1,80 @@
/***************************************************************
* Name: SolidArrow.cpp
* Purpose: Implements solid arrow for line shapes
* Author: Michal Bližňák (michal.bliznak@tiscali.cz)
* Created: 2007-07-22
* Copyright: Michal Bližňák
* License: wxWidgets license (www.wxwidgets.org)
* Notes:
**************************************************************/
#include "wx_pch.h"
#ifdef _DEBUG_MSVC
#define new DEBUG_NEW
#endif
#include "wx/wxsf/SolidArrow.h"
#include "wx/wxsf/CommonFcn.h"
// arrow shape
static const wxRealPoint arrow[3]={wxRealPoint(0,0), wxRealPoint(10,4), wxRealPoint(10,-4)};
using namespace wxSFCommonFcn;
XS_IMPLEMENT_CLONABLE_CLASS(wxSFSolidArrow, wxSFArrowBase);
wxSFSolidArrow::wxSFSolidArrow(void)
: wxSFArrowBase()
{
m_Fill = sfdvARROW_FILL;
m_Pen = sfdvARROW_BORDER;
MarkSerializableDataMembers();
}
wxSFSolidArrow::wxSFSolidArrow(wxSFShapeBase* parent)
: wxSFArrowBase(parent)
{
m_Fill = sfdvARROW_FILL;
m_Pen = sfdvARROW_BORDER;
MarkSerializableDataMembers();
}
wxSFSolidArrow::wxSFSolidArrow(const wxSFSolidArrow& obj)
: wxSFArrowBase(obj)
{
m_Fill = obj.m_Fill;
m_Pen = obj.m_Pen;
MarkSerializableDataMembers();
}
wxSFSolidArrow::~wxSFSolidArrow(void)
{
}
void wxSFSolidArrow::MarkSerializableDataMembers()
{
XS_SERIALIZE_EX(m_Fill, wxT("fill"), sfdvARROW_FILL);
XS_SERIALIZE_EX(m_Pen, wxT("border"), sfdvARROW_BORDER);
}
//----------------------------------------------------------------------------------//
// public virtual functions
//----------------------------------------------------------------------------------//
void wxSFSolidArrow::Draw(const wxRealPoint &from, const wxRealPoint &to, wxDC& dc)
{
wxPoint rarrow[3];
TranslateArrow( rarrow, arrow, 3, from, to );
dc.SetPen(m_Pen);
dc.SetBrush(m_Fill);
dc.DrawPolygon(3, rarrow);
dc.SetBrush(wxNullBrush);
dc.SetPen(wxNullPen);
}

View File

@@ -0,0 +1,390 @@
/***************************************************************
* Name: TextShape.cpp
* Purpose: Implements static text shape class
* Author: Michal Bližňák (michal.bliznak@tiscali.cz)
* Created: 2007-07-22
* Copyright: Michal Bližňák
* License: wxWidgets license (www.wxwidgets.org)
* Notes:
**************************************************************/
#include "wx_pch.h"
#ifdef _DEBUG_MSVC
#define new DEBUG_NEW
#endif
#include "wx/wxsf/TextShape.h"
#include "wx/wxsf/ShapeCanvas.h"
XS_IMPLEMENT_CLONABLE_CLASS(wxSFTextShape, wxSFRectShape);
wxSFTextShape::wxSFTextShape(void)
: wxSFRectShape()
{
m_Font = sfdvTEXTSHAPE_FONT;
m_Font.SetPointSize(12);
m_nLineHeight = 12;
m_TextColor = sfdvTEXTSHAPE_TEXTCOLOR;
m_sText = wxT("Text");
m_Fill = *wxTRANSPARENT_BRUSH;
m_Border = *wxTRANSPARENT_PEN;
m_nRectSize = wxRealPoint(0, 0);
MarkSerializableDataMembers();
UpdateRectSize();
}
wxSFTextShape::wxSFTextShape(const wxRealPoint& pos, const wxString& txt, wxSFDiagramManager* manager)
: wxSFRectShape(pos, wxRealPoint(0, 0), manager)
{
m_Font = sfdvTEXTSHAPE_FONT;
m_Font.SetPointSize(12);
m_nLineHeight = 12;
m_TextColor = sfdvTEXTSHAPE_TEXTCOLOR;
m_sText = txt;
m_Fill = *wxTRANSPARENT_BRUSH;
m_Border = *wxTRANSPARENT_PEN;
MarkSerializableDataMembers();
UpdateRectSize();
}
wxSFTextShape::wxSFTextShape(const wxSFTextShape& obj)
: wxSFRectShape(obj)
{
m_Font = obj.m_Font;
m_TextColor = obj.m_TextColor;
m_sText = obj.m_sText;
MarkSerializableDataMembers();
UpdateRectSize();
}
wxSFTextShape::~wxSFTextShape()
{
}
void wxSFTextShape::MarkSerializableDataMembers()
{
XS_SERIALIZE_EX(m_Font, wxT("font"), sfdvTEXTSHAPE_FONT);
XS_SERIALIZE_EX(m_TextColor, wxT("color"), sfdvTEXTSHAPE_TEXTCOLOR);
XS_SERIALIZE(m_sText, wxT("text"));
}
//----------------------------------------------------------------------------------//
// public virtual functions
//----------------------------------------------------------------------------------//
void wxSFTextShape::Update()
{
UpdateRectSize();
wxSFShapeBase::Update();
}
void wxSFTextShape::Scale(double x, double y, bool children)
{
// HINT: overload it for custom actions...
if((x > 0) && (y > 0))
{
double s = 1;
if(x == 1) s = y;
else if (y == 1) s = x;
else if(x >= y) s = x;
else
s = y;
double size = (double)m_Font.GetPointSize()*s;
if(size < 5)size = 5;
m_Font.SetPointSize((int)size);
UpdateRectSize();
// call default function implementation (needed for scaling of shape's children)
wxSFShapeBase::Scale(x, y, children);
}
}
void wxSFTextShape::OnHandle(wxSFShapeHandle& handle)
{
// HINT: overload it for custom actions...
wxRealPoint prevSize = GetRectSize();
// perform standard operations
switch(handle.GetType())
{
case wxSFShapeHandle::hndLEFT:
OnLeftHandle(handle);
break;
case wxSFShapeHandle::hndRIGHT:
OnRightHandle(handle);
break;
case wxSFShapeHandle::hndTOP:
OnTopHandle(handle);
break;
case wxSFShapeHandle::hndBOTTOM:
OnBottomHandle(handle);
break;
default:
break;
}
wxRealPoint newSize = m_nRectSize;
double sx = newSize.x / prevSize.x;
double sy = newSize.y / prevSize.y;
Scale(sx, sy);
switch(handle.GetType())
{
case wxSFShapeHandle::hndLEFT:
{
double dx = m_nRectSize.x - prevSize.x;
MoveBy(-dx, 0);
SerializableList::compatibility_iterator node = GetFirstChildNode();
while(node)
{
((wxSFShapeBase*)node->GetData())->MoveBy(-dx, 0);
node = node->GetNext();
}
}
break;
case wxSFShapeHandle::hndTOP:
{
double dy = m_nRectSize.y - prevSize.y;
MoveBy(0, -dy);
SerializableList::compatibility_iterator node = GetFirstChildNode();
while(node)
{
((wxSFShapeBase*)node->GetData())->MoveBy(0, -dy);
node = node->GetNext();
}
}
break;
default:
break;
}
wxSFShapeBase::OnHandle( handle );
}
//----------------------------------------------------------------------------------//
// public functions
//----------------------------------------------------------------------------------//
wxSize wxSFTextShape::GetTextExtent()
{
wxCoord w = -1, h = -1;
if(m_pParentManager && GetParentCanvas())
{
wxClientDC dc((wxWindow*)GetParentCanvas());
// calculate text extent
if( wxSFShapeCanvas::IsGCEnabled() )
{
#if wxUSE_GRAPHICS_CONTEXT
double wd = -1, hd = -1, d = 0, e = 0;
wxGraphicsContext *pGC = wxGraphicsContext::Create( dc );
pGC->SetFont( m_Font, *wxBLACK );
// we must use string tokenizer to inspect all lines of possible multiline text
h = 0;
wxString sLine;
wxStringTokenizer tokens( m_sText, wxT("\n\r"), wxTOKEN_RET_EMPTY );
while( tokens.HasMoreTokens() )
{
sLine = tokens.GetNextToken();
pGC->GetTextExtent( sLine, &wd, &hd, &d, &e );
h += (hd + e);
if( (wd + d) > w ) w = (wd + d);
}
m_nLineHeight = (hd + e);
pGC->SetFont( wxNullFont, *wxBLACK );
#endif
}
else
{
dc.SetFont(m_Font);
dc.GetMultiLineTextExtent(m_sText, &w, &h, &m_nLineHeight);
dc.SetFont(wxNullFont);
}
}
else
{
w = (int)m_nRectSize.x;
h = (int)m_nRectSize.y;
wxStringTokenizer tokens(m_sText, wxT("\n\r"), wxTOKEN_RET_EMPTY);
m_nLineHeight = int(m_nRectSize.y/tokens.CountTokens());
}
/*if( wxSFShapeCanvas::IsGCEnabled() )
{
return wxSize((wxCoord)(wd + d), (wxCoord)(hd + e));
}
else*/
return wxSize(w, h);
}
void wxSFTextShape::UpdateRectSize()
{
wxSize tsize = GetTextExtent();
if(tsize.IsFullySpecified())
{
if(tsize.x <= 0) tsize.x = 1;
if(tsize.y <= 0) tsize.y = 1;
m_nRectSize.x = (double)tsize.x;
m_nRectSize.y = (double)tsize.y;
}
}
void wxSFTextShape::SetText(const wxString& txt)
{
m_sText = txt;
UpdateRectSize();
}
void wxSFTextShape::SetFont(const wxFont& font)
{
m_Font = font;
UpdateRectSize();
}
//----------------------------------------------------------------------------------//
// protected virtual functions
//----------------------------------------------------------------------------------//
void wxSFTextShape::DrawNormal(wxDC& dc)
{
wxSFRectShape::DrawNormal(dc);
DrawTextContent(dc);
}
void wxSFTextShape::DrawHover(wxDC& dc)
{
wxSFRectShape::DrawHover(dc);
DrawTextContent(dc);
}
void wxSFTextShape::DrawHighlighted(wxDC& dc)
{
wxSFRectShape::DrawHighlighted(dc);
DrawTextContent(dc);
}
void wxSFTextShape::DrawShadow(wxDC& dc)
{
// HINT: overload it for custom actions...
wxColour nCurrColor = m_TextColor;
m_TextColor = GetParentCanvas()->GetShadowFill().GetColour();
wxRealPoint nOffset = GetParentCanvas()->GetShadowOffset();
MoveBy(nOffset);
DrawTextContent(dc);
MoveBy(-nOffset.x, -nOffset.y);
m_TextColor = nCurrColor;
}
void wxSFTextShape::OnLeftHandle(wxSFShapeHandle& handle)
{
// HINT: overload it for custom actions...
m_nRectSize.x -= ((double)handle.GetPosition().x - GetAbsolutePosition().x);
//m_nRectSize.x -= (double)handle.GetDelta().x;
}
void wxSFTextShape::OnTopHandle(wxSFShapeHandle& handle)
{
// HINT: overload it for custom actions...
m_nRectSize.y -= ((double)handle.GetPosition().y - GetAbsolutePosition().y);
//m_nRectSize.y -= (double)handle.GetDelta().y;
}
void wxSFTextShape::OnBottomHandle(wxSFShapeHandle& handle)
{
// HINT: overload it for custom actions...
m_nRectSize.y = handle.GetPosition().y - GetAbsolutePosition().y;
}
void wxSFTextShape::OnRightHandle(wxSFShapeHandle& handle)
{
// HINT: overload it for custom actions...
m_nRectSize.x =handle.GetPosition().x - GetAbsolutePosition().x;
}
//----------------------------------------------------------------------------------//
// protected functions
//----------------------------------------------------------------------------------//
void wxSFTextShape::DrawTextContent(wxDC& dc)
{
wxString line;
int i = 0;
dc.SetBrush(m_Fill);
dc.SetBackgroundMode(wxTRANSPARENT);
/*#ifdef __WXMSW__
if(m_Fill.GetStyle() == wxTRANSPARENT)
{
dc.SetBackgroundMode(wxTRANSPARENT);
}
else
{
dc.SetBackgroundMode(wxSOLID);
dc.SetTextBackground(m_Fill.GetColour());
}
#endif*/
dc.SetTextForeground(m_TextColor);
dc.SetFont(m_Font);
wxRealPoint pos = GetAbsolutePosition();
// draw all text lines
wxStringTokenizer tokens(m_sText, wxT("\n\r"), wxTOKEN_RET_EMPTY);
while(tokens.HasMoreTokens())
{
line = tokens.GetNextToken();
dc.DrawText(line, (int)pos.x, (int)pos.y + i*m_nLineHeight);
i++;
}
dc.SetFont(wxNullFont);
dc.SetBrush(wxNullBrush);
}

View File

@@ -0,0 +1,45 @@
/***************************************************************
* Name: TextShapeXml.cpp
* Purpose: Implements text shape's serialization capability
* Author: Michal Bližňák (michal.bliznak@tiscali.cz)
* Created: 2007-07-22
* Copyright: Michal Bližňák
* License: wxWidgets license (www.wxwidgets.org)
* Notes:
**************************************************************/
#include "wx_pch.h"
#ifdef _DEBUG_MSVC
#define new DEBUG_NEW
#endif
#include "wx/wxsf/TextShape.h"
#include "wx/wxsf/CommonFcn.h"
//----------------------------------------------------------------------------------//
// Serialization
//----------------------------------------------------------------------------------//
wxXmlNode * wxSFTextShape::Serialize(wxXmlNode* node)
{
// HINT: overload it for custom actions...
if(node)
{
node = wxSFShapeBase::Serialize(node);
}
return node;
}
void wxSFTextShape::Deserialize(wxXmlNode* node)
{
// HINT: overload it for custom actions...
wxSFShapeBase::Deserialize(node);
UpdateRectSize();
}

View File

@@ -0,0 +1,256 @@
/***************************************************************
* Name: Thumbnail.h
* Purpose: Implements canvas thumbnail class
* Author: Michal Bližňák (michal.bliznak@tiscali.cz)
* Created: 2009-06-09
* Copyright: Michal Bližňák
* License: wxWidgets license (www.wxwidgets.org)
* Notes:
**************************************************************/
#include "wx_pch.h"
#ifdef _DEBUG_MSVC
#define new DEBUG_NEW
#endif
#include <wx/dcbuffer.h>
#include "wx/wxsf/Thumbnail.h"
#include "wx/wxsf/BitmapShape.h"
BEGIN_EVENT_TABLE(wxSFThumbnail, wxPanel)
EVT_PAINT( wxSFThumbnail::_OnPaint )
EVT_ERASE_BACKGROUND( wxSFThumbnail::_OnEraseBackground )
EVT_MOTION( wxSFThumbnail::_OnMouseMove )
EVT_LEFT_DOWN( wxSFThumbnail::_OnLeftDown )
EVT_RIGHT_DOWN( wxSFThumbnail::_OnRightDown )
EVT_TIMER( wxSFThumbnail::ID_UPDATETIMER, wxSFThumbnail::_OnTimer )
EVT_UPDATE_UI( wxSFThumbnail::IDM_SHOWELEMENTS, wxSFThumbnail::_OnUpdateShowElements )
EVT_UPDATE_UI( wxSFThumbnail::IDM_SHOWCONNECTIONS, wxSFThumbnail::_OnUpdateShowConnections )
EVT_MENU( wxSFThumbnail::IDM_SHOWELEMENTS, wxSFThumbnail::_OnShowElements )
EVT_MENU( wxSFThumbnail::IDM_SHOWCONNECTIONS, wxSFThumbnail::_OnShowConnections )
END_EVENT_TABLE()
//----------------------------------------------------------------------------------//
// constructor and destructor
//----------------------------------------------------------------------------------//
wxSFThumbnail::wxSFThumbnail(wxWindow *parent) : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxSize(200, 150), wxTAB_TRAVERSAL | wxFULL_REPAINT_ON_RESIZE )
{
SetExtraStyle( wxWS_EX_BLOCK_EVENTS );
SetSizeHints( wxSize(10, 10), wxDefaultSize );
m_pCanvas = NULL;
m_nScale = 1;
m_nThumbStyle = tsSHOW_ELEMENTS | tsSHOW_CONNECTIONS;
m_UpdateTimer.SetOwner(this, ID_UPDATETIMER);
}
wxSFThumbnail::~wxSFThumbnail()
{
m_pCanvas = NULL;
m_UpdateTimer.Stop();
}
//----------------------------------------------------------------------------------//
// public functions
//----------------------------------------------------------------------------------//
void wxSFThumbnail::SetCanvas(wxSFShapeCanvas* canvas)
{
m_pCanvas = canvas;
if( m_pCanvas ) m_UpdateTimer.Start(100);
else
{
m_UpdateTimer.Stop();
Refresh(false);
}
}
void wxSFThumbnail::DrawContent(wxDC& dc)
{
// HINT: overload it for custom actions...
wxSFShapeBase *pShape;
SerializableList::compatibility_iterator node = m_pCanvas->GetDiagramManager()->GetRootItem()->GetFirstChildNode();
while( node )
{
pShape = wxDynamicCast( node->GetData(), wxSFShapeBase );
if( pShape )
{
if( (m_nThumbStyle & tsSHOW_CONNECTIONS) && pShape->IsKindOf(CLASSINFO(wxSFLineShape)) ) pShape->Draw( dc, sfWITHOUTCHILDREN );
else if( m_nThumbStyle & tsSHOW_ELEMENTS )
{
if( pShape->IsKindOf(CLASSINFO(wxSFBitmapShape)) )
{
dc.SetPen( wxPen( *wxBLACK, 1, wxDOT) );
dc.SetBrush( *wxWHITE_BRUSH );
dc.DrawRectangle( pShape->GetBoundingBox() );
dc.SetBrush( wxNullBrush );
dc.SetPen( wxNullPen );
}
else if( !pShape->IsKindOf(CLASSINFO(wxSFLineShape)) ) pShape->Draw( dc, sfWITHOUTCHILDREN );
}
}
node = node->GetNext();
}
}
//----------------------------------------------------------------------------------//
// protected event handlers
//----------------------------------------------------------------------------------//
void wxSFThumbnail::_OnEraseBackground(wxEraseEvent& event)
{
wxUnusedVar( event );
// do nothing to eliminate flickering on Windows
}
void wxSFThumbnail::_OnLeftDown(wxMouseEvent& event)
{
m_nPrevMousePos = event.GetPosition();
}
void wxSFThumbnail::_OnRightDown(wxMouseEvent& event)
{
wxMenu menuPopup;
menuPopup.AppendCheckItem( IDM_SHOWELEMENTS, wxT("Show elements") );
menuPopup.AppendCheckItem( IDM_SHOWCONNECTIONS, wxT("Show connections") );
PopupMenu( &menuPopup, event.GetPosition() );
}
void wxSFThumbnail::_OnMouseMove(wxMouseEvent& event)
{
if( m_pCanvas && IsShown() && event.Dragging() )
{
int ux, uy;
m_pCanvas->GetScrollPixelsPerUnit( &ux, &uy );
wxPoint szDelta = event.GetPosition() - m_nPrevMousePos;
wxSize szCanvasOffset = GetCanvasOffset();
m_pCanvas->Scroll( (double(szDelta.x)/m_nScale + szCanvasOffset.x)/ux, (double(szDelta.y)/m_nScale + szCanvasOffset.y)/uy );
m_nPrevMousePos = event.GetPosition();
Refresh(false);
}
}
void wxSFThumbnail::_OnPaint(wxPaintEvent& event)
{
wxUnusedVar( event );
#if wxVERSION_NUMBER < 2900 && wxUSE_GRAPHICS_CONTEXT
bool fGCEnabled = wxSFShapeCanvas::IsGCEnabled();
wxSFScaledDC::EnableGC( false );
#endif
wxBufferedPaintDC dc(this);
// clear background
dc.SetBackground( wxBrush(wxColour(150, 150, 150)) );
dc.Clear();
if( m_pCanvas )
{
wxSize szCanvas = m_pCanvas->GetClientSize();
wxSize szVirtCanvas = m_pCanvas->GetVirtualSize();
wxSize szCanvasOffset = GetCanvasOffset();
wxSize szThumb = GetClientSize();
// scale and copy bitmap to DC
double cx = szVirtCanvas.x, cy = szVirtCanvas.y, tx = szThumb.x, ty = szThumb.y;
if( (tx/ty) > (cx/cy) ) m_nScale = ty/cy;
else
m_nScale = tx/cx;
// draw virtual canvas area
dc.SetPen(*wxWHITE_PEN);
dc.SetBrush( wxBrush(wxColour(240, 240, 240)) );
dc.DrawRectangle(0, 0, double(szVirtCanvas.x)*m_nScale, double(szVirtCanvas.y)*m_nScale);
// draw top level shapes
wxSFScaledDC sdc( (wxWindowDC*)&dc, m_nScale * m_pCanvas->GetScale() );
this->DrawContent( sdc );
// draw canvas client area
dc.SetPen(*wxRED_PEN);
dc.SetBrush(*wxTRANSPARENT_BRUSH);
dc.DrawRectangle(double(szCanvasOffset.x)*m_nScale, double(szCanvasOffset.y)*m_nScale, double(szCanvas.x)*m_nScale, double(szCanvas.y)*m_nScale);
dc.SetBrush(wxNullBrush);
dc.SetPen(wxNullPen);
}
dc.SetBackground( wxNullBrush );
#if wxVERSION_NUMBER < 2900 && wxUSE_GRAPHICS_CONTEXT
wxSFScaledDC::EnableGC( fGCEnabled );
#endif
}
void wxSFThumbnail::_OnTimer(wxTimerEvent& event)
{
wxUnusedVar( event );
if( m_pCanvas && IsShown() ) Refresh(false);
}
void wxSFThumbnail::_OnShowConnections(wxCommandEvent& event)
{
wxUnusedVar( event );
if( m_nThumbStyle & tsSHOW_CONNECTIONS ) m_nThumbStyle &= ~tsSHOW_CONNECTIONS;
else
m_nThumbStyle |= tsSHOW_CONNECTIONS;
}
void wxSFThumbnail::_OnShowElements(wxCommandEvent& event)
{
wxUnusedVar( event );
if( m_nThumbStyle & tsSHOW_ELEMENTS ) m_nThumbStyle &= ~tsSHOW_ELEMENTS;
else
m_nThumbStyle |= tsSHOW_ELEMENTS;
}
void wxSFThumbnail::_OnUpdateShowConnections(wxUpdateUIEvent& event)
{
event.Check( m_nThumbStyle & tsSHOW_CONNECTIONS );
}
void wxSFThumbnail::_OnUpdateShowElements(wxUpdateUIEvent& event)
{
event.Check( m_nThumbStyle & tsSHOW_ELEMENTS );
}
//----------------------------------------------------------------------------------//
// protected functions
//----------------------------------------------------------------------------------//
wxSize wxSFThumbnail::GetCanvasOffset()
{
if( m_pCanvas )
{
int ux, uy, offsetx, offsety;
m_pCanvas->GetScrollPixelsPerUnit( &ux, &uy );
m_pCanvas->GetViewStart( &offsetx, &offsety );
return wxSize( offsetx*ux, offsety*uy );
}
return wxSize();
}

View File

@@ -0,0 +1,60 @@
--*****************************************************************************
--* Author: Michal Bližňák
--* Date: 18/11/2007
--* Version: 1.00
--*
--* NOTES:
--* - use the '/' slash for all paths.
--*****************************************************************************
dofile('../build/premake/scripts/init.lua')
--******* Initial Setup ************
--* Most of the setting are set here.
--**********************************
-- Set the name of your package.
package.name = "wxSF"
-- Set this if you want a different name for your target than the package's name.
targetName = "wxsf"
-- Set the kind of package you want to create.
-- Options: exe | winexe | lib | dll
if( options["shared"] ) then
package.kind = "dll"
else
package.kind = "lib"
end
-- Setup the package compiler settings.
if( options["shared"] ) then
package.defines = { "WXMAKINGDLL_WXSF", "WXMAKINGDLL_WXXS" }
end
if ( target == "vs2005" ) then
-- Windows and Visual C++ 2005
table.insert(package.defines,"_CRT_SECURE_NO_DEPRECATE" )
end
if( target == "vs2003" or target == "vs2005" ) then
table.insert( package.defines, "_DISWARNINGS_MSVC" )
table.insert(package.config["Debug"].defines, "_DEBUG_MSVC")
end
if( ( target == "vs2003" or target == "vs2005" ) and options["no-builtin-wchar"] ) then
table.insert(package.buildoptions, "/Zc:wchar_t-")
end
-- Set the files to include.
package.files = { matchrecursive( "*.cpp", "*.h", "*.rc", "../include/*.h" ) }
if ( not windows ) then
table.insert( package.excludes, matchrecursive( "*.rc" ) )
end
-- Set the include paths.
package.includepaths = { "../include", "../src" }
-- Set precompiled headers support
package.pchheader = "wx_pch.h"
package.pchsource = "wx_pch.cpp"
dofile('../build/premake/scripts/wxpresets.lua')

View File

@@ -0,0 +1,69 @@
/* XPM */
static const char * NoSource_xpm[] = {
"100 50 16 1",
" c #000000",
". c #800000",
"+ c #008000",
"@ c #808000",
"# c #000080",
"$ c #800080",
"% c #008080",
"& c #808080",
"* c #C0C0C0",
"= c #FF0000",
"- c #00FF00",
"; c #FFFF00",
"> c #0000FF",
", c #FF00FF",
"' c #00FFFF",
") c #FFFFFF",
"====================================================================================================",
"=)==))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))==)=",
"=)))==))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))==)))=",
"=)))))==))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))==)))))=",
"=)))))))==))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))==)))))))=",
"=)))))))))==))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))==)))))))))=",
"=)))))))))))==))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))==)))))))))))=",
"=)))))))))))))==))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))==)))))))))))))=",
"=)))))))))))))))==))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))==)))))))))))))))=",
"=)))))))))))))))))==))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))==)))))))))))))))))=",
"=)))))))))))))))))))==))))))))))))))))))))))))))))))))))))))))))))))))))))))))==)))))))))))))))))))=",
"=)))))))))))))))))))====)===)))))))))===))))))))))))))))))))))))))))))))))))==)))))))))))))))))))))=",
"=)))))))))))))))))))===)====)))))))))===))))))))))))))))))))))))))))))))))==)))))))))))))))))))))))=",
"=)))))))))))))))))))===))===)===)==))===))======)==))))===)))===)===)======)==)))))))))))))))))))))=",
"=)))))))))))))))))))===))===========)===)===)=======))=====))===)===)==========))))))))))))))))))))=",
"=)))))))))))))))))))===))===)===)===)======))===)===)===)===))=========)===)===))))))))))))))))))))=",
"=)))))))))))))))))))===))===)=======)======))===)===)===)===))=========)===)===))))))))))))))))))))=",
"=)))))))))))))))))))===))===)===)===)=======)===)===)===)===))====)====)===)===))))))))))))))))))))=",
"=))))))))))))))))))))======))===)=======)===)===)===))=====)))===)))==))===)===))))))))))))))))))))=",
"=)))))))))))))))))))))====)))===)===)===))======)===)))===))==)==)))==))===)===))))))))))))))))))))=",
"=)))))))))))))))))))))))))))))))))))))))==))))))))))))))))==)))))))))))))))))))))))))))))))))))))))=",
"=)))))))))))))))))))))))))))))))))))))))))==))))))))))))==)))))))))))))))))))))))))))))))))))))))))=",
"=)))))))))))))))))))))))))))))))))))))))))))==))))))))==)))))))))))))))))))))))))))))))))))))))))))=",
"=)))))))))))))))))))))))))))))))))))))))))))))==))))==)))))))))))))))))))))))))))))))))))))))))))))=",
"=)))))))))))))))))))))))))))))))))))))))))))))))====)))))))))))))))))))))))))))))))))))))))))))))))=",
"=)))))))))))))))))))))))))))))))))))))))))))))))====)))))))))))))))))))))))))))))))))))))))))))))))=",
"=)))))))))))))))))))))))))))))))))))))))))))))==))))==)))))))))))))))))))))))))))))))))))))))))))))=",
"=)))))))))))))))))))))))))))))))))))))))))))==))))))))==)))))))))))))))))))))))))))))))))))))))))))=",
"=)))))))))))))))))))))))))))))))))))))))))==))))))))))))==)))))))))))))))))))))))))))))))))))))))))=",
"=)))))))))))))))))))))))))))))===)))))))==))))))))))))))))==)))))))))))))))))))))))))))))))))))))))=",
"=)))))))))))))))))))))))))))))))))))))==))))))))))))))))))))==)))))))))))))))))))))))))))))))))))))=",
"=)))))))))))))))))))))))))))))===)======)===)))=====)))==)===)======)))))))))))))))))))))))))))))))=",
"=)))))))))))))))))))))))))))))===)===========)=======)=======))=====)))))))))))))))))))))))))))))))=",
"=)))))))))))))))))))))))))))))=======)===)===)==))===)===)===)===)===))))))))))))))))))))))))))))))=",
"=)))))))))))))))))))))))))))))===)===)===)===)))=====)===)===)========)))))))))))))))))))))))))))))=",
"=)))))))))))))))))))))))))))=====)===)===)===)===)===)===)===)===)))))==)))))))))))))))))))))))))))=",
"=)))))))))))))))))))))))))==))===)===)===)===)===)===)=======))======)))==)))))))))))))))))))))))))=",
"=)))))))))))))))))))))))==))))===)===)===)===))======))==)===)))====))))))==)))))))))))))))))))))))=",
"=)))))))))))))))))))))==))))))))))))))))))))))))))))))))))===)))))))))))))))==)))))))))))))))))))))=",
"=)))))))))))))))))))==))))))))))))))))))))))))))))))))======))))))))))))))))))==)))))))))))))))))))=",
"=)))))))))))))))))==))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))==)))))))))))))))))=",
"=)))))))))))))))==))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))==)))))))))))))))=",
"=)))))))))))))==))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))==)))))))))))))=",
"=)))))))))))==))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))==)))))))))))=",
"=)))))))))==))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))==)))))))))=",
"=)))))))==))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))==)))))))=",
"=)))))==))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))==)))))=",
"=)))==))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))==)))=",
"=)==))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))==)=",
"===================================================================================================="};

View File

@@ -0,0 +1,17 @@
/////////////////////////////////////////////////////////////////////////////
// Name: wxSF.rc
// Purpose: a standard Win32 .rc file for the wxWidgets
// Author: Ryan Pusztai
// Modified by: Ryan Mulder
// Created: 11.21.05
// Copyright: (c) 2005 RJP Computing <support@rjpcomputing.com>
/////////////////////////////////////////////////////////////////////////////
// set this to 1 if you don't want to use manifest resource (manifest resource
// is needed to enable visual styles on Windows XP - see docs/msw/winxp.txt
// for more information)
#define wxUSE_NO_MANIFEST 0
// this is not always needed but doesn't hurt (except making the executable
// very slightly larger): this file contains the standard icons, cursors, ...
#include "wx/msw/wx.rc"

View File

@@ -0,0 +1 @@
#include "wx_pch.h"

View File

@@ -0,0 +1,44 @@
/***************************************************************
* Name: wx_pch.h
* Purpose: Header to create Pre-Compiled Header (PCH)
* Author: Michal Bližňák ()
* Created: 2007-03-04
* Copyright: Michal Bližňák ()
* License:
**************************************************************/
#ifndef WX_PCH_H_INCLUDED
#define WX_PCH_H_INCLUDED
#ifdef _DISWARNINGS_MSVC
//#pragma warning( disable : 4100 )
#pragma warning( disable : 4251 )
#pragma warning( disable : 4275 )
#endif
// debug memory allocation enhancement (see next tip)
#ifdef _DEBUG_MSVC
#ifdef _DEBUG
#include <crtdbg.h>
#define DEBUG_NEW new(_NORMAL_BLOCK ,__FILE__, __LINE__)
#else
#define DEBUG_NEW new
#endif
#endif
// basic wxWidgets headers
#include <wx/wxprec.h>
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
#ifdef WX_PRECOMP
// put here all your rarely-changing header files
#endif // WX_PRECOMP
#endif // WX_PCH_H_INCLUDED

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff