mirror of
https://github.com/levinsv/pgadmin3.git
synced 2026-05-15 06:05:49 -06:00
714 lines
20 KiB
C++
714 lines
20 KiB
C++
//////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// pgAdmin III - PostgreSQL Tools
|
|
//
|
|
// Portions Copyright (C) 1998 - 2011, Julian Smart
|
|
// Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team
|
|
// This software is released under the PostgreSQL Licence
|
|
//
|
|
// divided.cpp - wxDividedShape class
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "pgAdmin3.h"
|
|
|
|
#include "ogl/ogl.h"
|
|
|
|
static wxChar *
|
|
oglCopystring (const wxChar *s)
|
|
{
|
|
if (s == NULL) s = wxEmptyString;
|
|
size_t len = wxStrlen (s) + 1;
|
|
|
|
wxChar *news = new wxChar[len];
|
|
memcpy (news, s, len * sizeof(wxChar)); // Should be the fastest
|
|
|
|
return news;
|
|
}
|
|
|
|
class wxDividedShapeControlPoint: public wxControlPoint
|
|
{
|
|
DECLARE_DYNAMIC_CLASS(wxDividedShapeControlPoint)
|
|
private:
|
|
int regionId;
|
|
public:
|
|
wxDividedShapeControlPoint()
|
|
{
|
|
regionId = 0;
|
|
}
|
|
wxDividedShapeControlPoint(wxShapeCanvas *the_canvas, wxShape *object, int region,
|
|
double size, double the_xoffset, double the_yoffset, int the_type);
|
|
~wxDividedShapeControlPoint();
|
|
|
|
void OnDragLeft(bool draw, double x, double y, int keys = 0, int attachment = 0);
|
|
void OnBeginDragLeft(double x, double y, int keys = 0, int attachment = 0);
|
|
void OnEndDragLeft(double x, double y, int keys = 0, int attachment = 0);
|
|
};
|
|
|
|
IMPLEMENT_DYNAMIC_CLASS(wxDividedShapeControlPoint, wxControlPoint)
|
|
|
|
/*
|
|
* Divided object
|
|
*
|
|
*/
|
|
|
|
IMPLEMENT_DYNAMIC_CLASS(wxDividedShape, wxRectangleShape)
|
|
|
|
wxDividedShape::wxDividedShape(double w, double h): wxRectangleShape(w, h)
|
|
{
|
|
ClearRegions();
|
|
}
|
|
|
|
wxDividedShape::~wxDividedShape()
|
|
{
|
|
}
|
|
|
|
void wxDividedShape::OnDraw(wxDC &dc)
|
|
{
|
|
wxRectangleShape::OnDraw(dc);
|
|
}
|
|
|
|
void wxDividedShape::OnDrawContents(wxDC &dc)
|
|
{
|
|
double defaultProportion = (double)(GetRegions().GetCount() > 0 ? (1.0 / ((double)(GetRegions().GetCount()))) : 0.0);
|
|
double currentY = (double)(m_ypos - (m_height / 2.0));
|
|
double maxY = (double)(m_ypos + (m_height / 2.0));
|
|
|
|
double leftX = (double)(m_xpos - (m_width / 2.0));
|
|
double rightX = (double)(m_xpos + (m_width / 2.0));
|
|
|
|
if (m_pen) dc.SetPen(* m_pen);
|
|
|
|
if (m_textColour.IsOk()) dc.SetTextForeground(m_textColour);
|
|
|
|
#ifdef __WXMSW__
|
|
// For efficiency, don't do this under X - doesn't make
|
|
// any visible difference for our purposes.
|
|
if (m_brush)
|
|
dc.SetTextBackground(m_brush->GetColour());
|
|
#endif
|
|
/*
|
|
if (!formatted)
|
|
{
|
|
FormatRegionText();
|
|
formatted = TRUE;
|
|
}
|
|
*/
|
|
if (GetDisableLabel()) return;
|
|
|
|
double xMargin = 2;
|
|
double yMargin = 2;
|
|
dc.SetBackgroundMode(wxTRANSPARENT);
|
|
|
|
wxNode *node = GetRegions().GetFirst();
|
|
while (node)
|
|
{
|
|
wxShapeRegion *region = (wxShapeRegion *)node->GetData();
|
|
dc.SetFont(* region->GetFont());
|
|
dc.SetTextForeground(region->GetActualColourObject());
|
|
|
|
double proportion =
|
|
region->m_regionProportionY < 0.0 ? defaultProportion : region->m_regionProportionY;
|
|
|
|
double y = currentY + m_height * proportion;
|
|
double actualY = maxY < y ? maxY : y;
|
|
|
|
double centreX = m_xpos;
|
|
double centreY = (double)(currentY + (actualY - currentY) / 2.0);
|
|
|
|
oglDrawFormattedText(dc, ®ion->m_formattedText,
|
|
(double)(centreX), (double)(centreY), (double)(m_width - 2 * xMargin), (double)(actualY - currentY - 2 * yMargin),
|
|
region->m_formatMode);
|
|
if ((y <= maxY) && (node->GetNext()))
|
|
{
|
|
wxPen *regionPen = region->GetActualPen();
|
|
if (regionPen)
|
|
{
|
|
dc.SetPen(* regionPen);
|
|
dc.DrawLine(WXROUND(leftX), WXROUND(y), WXROUND(rightX), WXROUND(y));
|
|
}
|
|
}
|
|
|
|
currentY = actualY;
|
|
|
|
node = node->GetNext();
|
|
}
|
|
}
|
|
|
|
void wxDividedShape::SetSize(double w, double h, bool WXUNUSED(recursive))
|
|
{
|
|
SetAttachmentSize(w, h);
|
|
m_width = w;
|
|
m_height = h;
|
|
SetRegionSizes();
|
|
}
|
|
|
|
void wxDividedShape::SetRegionSizes()
|
|
{
|
|
if (GetRegions().GetCount() == 0)
|
|
return;
|
|
|
|
double defaultProportion = (double)(GetRegions().GetCount() > 0 ? (1.0 / ((double)(GetRegions().GetCount()))) : 0.0);
|
|
double currentY = (double)(m_ypos - (m_height / 2.0));
|
|
double maxY = (double)(m_ypos + (m_height / 2.0));
|
|
|
|
// double leftX = (double)(m_xpos - (m_width / 2.0));
|
|
// double rightX = (double)(m_xpos + (m_width / 2.0));
|
|
|
|
wxNode *node = GetRegions().GetFirst();
|
|
while (node)
|
|
{
|
|
wxShapeRegion *region = (wxShapeRegion *)node->GetData();
|
|
double proportion =
|
|
region->m_regionProportionY <= 0.0 ? defaultProportion : region->m_regionProportionY;
|
|
|
|
double sizeY = (double)proportion * m_height;
|
|
double y = currentY + sizeY;
|
|
double actualY = maxY < y ? maxY : y;
|
|
|
|
double centreY = (double)(currentY + (actualY - currentY) / 2.0);
|
|
|
|
region->SetSize(m_width, sizeY);
|
|
region->SetPosition(0.0, (double)(centreY - m_ypos));
|
|
currentY = actualY;
|
|
node = node->GetNext();
|
|
}
|
|
}
|
|
|
|
// Attachment points correspond to regions in the divided box
|
|
bool wxDividedShape::GetAttachmentPosition(int attachment, double *x, double *y, int nth, int no_arcs,
|
|
wxLineShape *line)
|
|
{
|
|
int totalNumberAttachments = (GetRegions().GetCount() * 2) + 2;
|
|
if ((GetAttachmentMode() == ATTACHMENT_MODE_NONE) || (attachment >= totalNumberAttachments))
|
|
{
|
|
return wxShape::GetAttachmentPosition(attachment, x, y, nth, no_arcs);
|
|
}
|
|
|
|
int n = GetRegions().GetCount();
|
|
bool isEnd = (line && line->IsEnd(this));
|
|
|
|
double left = (double)(m_xpos - m_width / 2.0);
|
|
double right = (double)(m_xpos + m_width / 2.0);
|
|
double top = (double)(m_ypos - m_height / 2.0);
|
|
double bottom = (double)(m_ypos + m_height / 2.0);
|
|
|
|
// Zero is top, n+1 is bottom.
|
|
if (attachment == 0)
|
|
{
|
|
*y = top;
|
|
if (m_spaceAttachments)
|
|
{
|
|
if (line && (line->GetAlignmentType(isEnd) == LINE_ALIGNMENT_TO_NEXT_HANDLE))
|
|
{
|
|
// Align line according to the next handle along
|
|
wxRealPoint *point = line->GetNextControlPoint(this);
|
|
if (point->x < left)
|
|
*x = left;
|
|
else if (point->x > right)
|
|
*x = right;
|
|
else
|
|
*x = point->x;
|
|
}
|
|
else
|
|
*x = left + (nth + 1) * m_width / (no_arcs + 1);
|
|
}
|
|
else
|
|
*x = m_xpos;
|
|
}
|
|
else if (attachment == (n + 1))
|
|
{
|
|
*y = bottom;
|
|
if (m_spaceAttachments)
|
|
{
|
|
if (line && (line->GetAlignmentType(isEnd) == LINE_ALIGNMENT_TO_NEXT_HANDLE))
|
|
{
|
|
// Align line according to the next handle along
|
|
wxRealPoint *point = line->GetNextControlPoint(this);
|
|
if (point->x < left)
|
|
*x = left;
|
|
else if (point->x > right)
|
|
*x = right;
|
|
else
|
|
*x = point->x;
|
|
}
|
|
else
|
|
*x = left + (nth + 1) * m_width / (no_arcs + 1);
|
|
}
|
|
else
|
|
*x = m_xpos;
|
|
}
|
|
// Left or right.
|
|
else
|
|
{
|
|
bool isLeft = !(attachment < (n + 1));
|
|
int i = (isLeft) ? (totalNumberAttachments - attachment - 1) : (attachment - 1);
|
|
wxNode *node = GetRegions().Item(i);
|
|
if (node)
|
|
{
|
|
wxShapeRegion *region = (wxShapeRegion *)node->GetData();
|
|
|
|
if (isLeft)
|
|
*x = left;
|
|
else
|
|
*x = right;
|
|
|
|
// Calculate top and bottom of region
|
|
top = (double)((m_ypos + region->m_y) - (region->m_height / 2.0));
|
|
bottom = (double)((m_ypos + region->m_y) + (region->m_height / 2.0));
|
|
|
|
// Assuming we can trust the absolute size and
|
|
// position of these regions...
|
|
if (m_spaceAttachments)
|
|
{
|
|
if (line && (line->GetAlignmentType(isEnd) == LINE_ALIGNMENT_TO_NEXT_HANDLE))
|
|
{
|
|
// Align line according to the next handle along
|
|
wxRealPoint *point = line->GetNextControlPoint(this);
|
|
if (point->y < bottom)
|
|
*y = bottom;
|
|
else if (point->y > top)
|
|
*y = top;
|
|
else
|
|
*y = point->y;
|
|
}
|
|
else
|
|
// *y = (double)(((m_ypos + region->m_y) - (region->m_height/2.0)) + (nth + 1)*region->m_height/(no_arcs+1));
|
|
*y = (double)(top + (nth + 1) * region->m_height / (no_arcs + 1));
|
|
}
|
|
else
|
|
*y = (double)(m_ypos + region->m_y);
|
|
}
|
|
else
|
|
{
|
|
*x = m_xpos;
|
|
*y = m_ypos;
|
|
return FALSE;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
int wxDividedShape::GetNumberOfAttachments() const
|
|
{
|
|
// There are two attachments for each region (left and right),
|
|
// plus one on the top and one on the bottom.
|
|
int n = (GetRegions().GetCount() * 2) + 2;
|
|
|
|
int maxN = n - 1;
|
|
wxNode *node = m_attachmentPoints.GetFirst();
|
|
while (node)
|
|
{
|
|
wxAttachmentPoint *point = (wxAttachmentPoint *)node->GetData();
|
|
if (point->m_id > maxN)
|
|
maxN = point->m_id;
|
|
node = node->GetNext();
|
|
}
|
|
return maxN + 1;
|
|
}
|
|
|
|
bool wxDividedShape::AttachmentIsValid(int attachment) const
|
|
{
|
|
int totalNumberAttachments = (GetRegions().GetCount() * 2) + 2;
|
|
if (attachment >= totalNumberAttachments)
|
|
{
|
|
return wxShape::AttachmentIsValid(attachment);
|
|
}
|
|
else if (attachment >= 0)
|
|
return TRUE;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
void wxDividedShape::Copy(wxShape ©)
|
|
{
|
|
wxRectangleShape::Copy(copy);
|
|
}
|
|
|
|
// Region operations
|
|
|
|
void wxDividedShape::MakeControlPoints()
|
|
{
|
|
wxRectangleShape::MakeControlPoints();
|
|
|
|
MakeMandatoryControlPoints();
|
|
}
|
|
|
|
void wxDividedShape::MakeMandatoryControlPoints()
|
|
{
|
|
double currentY = (double)(GetY() - (m_height / 2.0));
|
|
double maxY = (double)(GetY() + (m_height / 2.0));
|
|
|
|
wxNode *node = GetRegions().GetFirst();
|
|
int i = 0;
|
|
while (node)
|
|
{
|
|
wxShapeRegion *region = (wxShapeRegion *)node->GetData();
|
|
|
|
double proportion = region->m_regionProportionY;
|
|
|
|
double y = currentY + m_height * proportion;
|
|
double actualY = (double)(maxY < y ? maxY : y);
|
|
|
|
if (node->GetNext())
|
|
{
|
|
wxDividedShapeControlPoint *controlPoint =
|
|
new wxDividedShapeControlPoint(m_canvas, this, i, CONTROL_POINT_SIZE, 0.0, (double)(actualY - GetY()), 0);
|
|
m_canvas->AddShape(controlPoint);
|
|
m_controlPoints.Append(controlPoint);
|
|
}
|
|
currentY = actualY;
|
|
i ++;
|
|
node = node->GetNext();
|
|
}
|
|
}
|
|
|
|
void wxDividedShape::ResetControlPoints()
|
|
{
|
|
// May only have the region handles, (n - 1) of them.
|
|
if (m_controlPoints.GetCount() > (GetRegions().GetCount() - 1))
|
|
wxRectangleShape::ResetControlPoints();
|
|
|
|
ResetMandatoryControlPoints();
|
|
}
|
|
|
|
void wxDividedShape::ResetMandatoryControlPoints()
|
|
{
|
|
double currentY = (double)(GetY() - (m_height / 2.0));
|
|
double maxY = (double)(GetY() + (m_height / 2.0));
|
|
|
|
wxNode *node = m_controlPoints.GetFirst();
|
|
int i = 0;
|
|
while (node)
|
|
{
|
|
wxControlPoint *controlPoint = (wxControlPoint *)node->GetData();
|
|
if (controlPoint->IsKindOf(CLASSINFO(wxDividedShapeControlPoint)))
|
|
{
|
|
wxNode *node1 = GetRegions().Item(i);
|
|
wxShapeRegion *region = (wxShapeRegion *)node1->GetData();
|
|
|
|
double proportion = region->m_regionProportionY;
|
|
|
|
double y = currentY + m_height * proportion;
|
|
double actualY = (double)(maxY < y ? maxY : y);
|
|
|
|
controlPoint->m_xoffset = 0.0;
|
|
controlPoint->m_yoffset = (double)(actualY - GetY());
|
|
currentY = actualY;
|
|
i ++;
|
|
}
|
|
node = node->GetNext();
|
|
}
|
|
}
|
|
|
|
#if wxUSE_PROLOGIO
|
|
void wxDividedShape::WriteAttributes(wxExpr *clause)
|
|
{
|
|
wxRectangleShape::WriteAttributes(clause);
|
|
}
|
|
|
|
void wxDividedShape::ReadAttributes(wxExpr *clause)
|
|
{
|
|
wxRectangleShape::ReadAttributes(clause);
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
* Edit the division colour/style
|
|
*
|
|
*/
|
|
|
|
void wxDividedShape::EditRegions()
|
|
{
|
|
wxMessageBox(wxT("EditRegions() is unimplemented."), wxT("OGL"), wxOK);
|
|
|
|
// TODO
|
|
#if 0
|
|
if (GetRegions().GetCount() < 2)
|
|
return;
|
|
|
|
wxBeginBusyCursor();
|
|
|
|
GraphicsForm *form = new GraphicsForm("Divided nodes");
|
|
// Need an array to store all the style strings,
|
|
// since they need to be converted to integers
|
|
char **styleStrings = new char *[GetRegions().GetCount()];
|
|
for (int j = 0; j < GetRegions().GetCount(); j++)
|
|
styleStrings[j] = NULL;
|
|
|
|
int i = 0;
|
|
wxNode *node = GetRegions().GetFirst();
|
|
while (node && node->GetNext())
|
|
{
|
|
wxShapeRegion *region = (wxShapeRegion *)node->GetData();
|
|
char buf[50];
|
|
sprintf(buf, "Region %d", (i + 1));
|
|
form->Add(wxMakeFormMessage(buf));
|
|
form->Add(wxMakeFormNewLine());
|
|
|
|
form->Add(wxMakeFormString("Colour", ®ion->penColour, wxFORM_CHOICE,
|
|
new wxList(wxMakeConstraintStrings(
|
|
"Invisible" ,
|
|
"BLACK" ,
|
|
"BLUE" ,
|
|
"BROWN" ,
|
|
"CORAL" ,
|
|
"CYAN" ,
|
|
"DARK GREY" ,
|
|
"DARK GREEN" ,
|
|
"DIM GREY" ,
|
|
"GREY" ,
|
|
"GREEN" ,
|
|
"LIGHT BLUE" ,
|
|
"LIGHT GREY" ,
|
|
"MAGENTA" ,
|
|
"MAROON" ,
|
|
"NAVY" ,
|
|
"ORANGE" ,
|
|
"PURPLE" ,
|
|
"RED" ,
|
|
"TURQUOISE" ,
|
|
"VIOLET" ,
|
|
"WHITE" ,
|
|
"YELLOW" ,
|
|
NULL),
|
|
NULL), NULL, wxVERTICAL, 150));
|
|
|
|
char *styleString = NULL;
|
|
switch (region->penStyle)
|
|
{
|
|
case wxSHORT_DASH:
|
|
styleString = "Short Dash";
|
|
break;
|
|
case wxLONG_DASH:
|
|
styleString = "Long Dash";
|
|
break;
|
|
case wxDOT:
|
|
styleString = "Dot";
|
|
break;
|
|
case wxDOT_DASH:
|
|
styleString = "Dot Dash";
|
|
break;
|
|
case wxSOLID:
|
|
default:
|
|
styleString = "Solid";
|
|
break;
|
|
}
|
|
styleStrings[i] = oglCopystring(styleString);
|
|
form->Add(wxMakeFormString("Style", &(styleStrings[i]), wxFORM_CHOICE,
|
|
new wxList(wxMakeConstraintStrings(
|
|
"Solid" ,
|
|
"Short Dash" ,
|
|
"Long Dash" ,
|
|
"Dot" ,
|
|
"Dot Dash" ,
|
|
NULL),
|
|
NULL), NULL, wxVERTICAL, 100));
|
|
node = node->GetNext();
|
|
i ++;
|
|
if (node && node->GetNext())
|
|
form->Add(wxMakeFormNewLine());
|
|
}
|
|
wxDialogBox *dialog = new wxDialogBox(m_canvas->GetParent(), "Divided object properties", 10, 10, 500, 500);
|
|
if (GraphicsLabelFont)
|
|
dialog->SetLabelFont(GraphicsLabelFont);
|
|
if (GraphicsButtonFont)
|
|
dialog->SetButtonFont(GraphicsButtonFont);
|
|
form->AssociatePanel(dialog);
|
|
form->dialog = dialog;
|
|
|
|
dialog->Fit();
|
|
dialog->Centre(wxBOTH);
|
|
|
|
wxEndBusyCursor();
|
|
|
|
dialog->Show(TRUE);
|
|
|
|
node = GetRegions().GetFirst();
|
|
i = 0;
|
|
while (node)
|
|
{
|
|
wxShapeRegion *region = (wxShapeRegion *)node->GetData();
|
|
|
|
if (styleStrings[i])
|
|
{
|
|
if (strcmp(styleStrings[i], "Solid") == 0)
|
|
region->penStyle = wxSOLID;
|
|
else if (strcmp(styleStrings[i], "Dot") == 0)
|
|
region->penStyle = wxDOT;
|
|
else if (strcmp(styleStrings[i], "Short Dash") == 0)
|
|
region->penStyle = wxSHORT_DASH;
|
|
else if (strcmp(styleStrings[i], "Long Dash") == 0)
|
|
region->penStyle = wxLONG_DASH;
|
|
else if (strcmp(styleStrings[i], "Dot Dash") == 0)
|
|
region->penStyle = wxDOT_DASH;
|
|
delete[] styleStrings[i];
|
|
}
|
|
region->m_actualPenObject = NULL;
|
|
node = node->GetNext();
|
|
i ++;
|
|
}
|
|
delete[] styleStrings;
|
|
Draw(dc);
|
|
#endif
|
|
}
|
|
|
|
void wxDividedShape::OnRightClick(double x, double y, int keys, int attachment)
|
|
{
|
|
if (keys & KEY_CTRL)
|
|
{
|
|
EditRegions();
|
|
}
|
|
else
|
|
{
|
|
wxRectangleShape::OnRightClick(x, y, keys, attachment);
|
|
}
|
|
}
|
|
|
|
wxDividedShapeControlPoint::wxDividedShapeControlPoint(wxShapeCanvas *the_canvas, wxShape *object,
|
|
int region, double size, double the_m_xoffset, double the_m_yoffset, int the_type):
|
|
wxControlPoint(the_canvas, object, size, the_m_xoffset, the_m_yoffset, the_type)
|
|
{
|
|
regionId = region;
|
|
}
|
|
|
|
wxDividedShapeControlPoint::~wxDividedShapeControlPoint()
|
|
{
|
|
}
|
|
|
|
// Implement resizing of divided object division
|
|
void wxDividedShapeControlPoint::OnDragLeft(bool WXUNUSED(draw), double WXUNUSED(x), double y, int WXUNUSED(keys), int WXUNUSED(attachment))
|
|
{
|
|
wxClientDC dc(GetCanvas());
|
|
GetCanvas()->PrepareDC(dc);
|
|
|
|
dc.SetLogicalFunction(OGLRBLF);
|
|
wxPen dottedPen(wxColour(0, 0, 0), 1, wxPENSTYLE_DOT);
|
|
dc.SetPen(dottedPen);
|
|
dc.SetBrush((* wxTRANSPARENT_BRUSH));
|
|
|
|
wxDividedShape *dividedObject = (wxDividedShape *)m_shape;
|
|
double x1 = (double)(dividedObject->GetX() - (dividedObject->GetWidth() / 2.0));
|
|
double y1 = y;
|
|
double x2 = (double)(dividedObject->GetX() + (dividedObject->GetWidth() / 2.0));
|
|
double y2 = y;
|
|
dc.DrawLine(WXROUND(x1), WXROUND(y1), WXROUND(x2), WXROUND(y2));
|
|
}
|
|
|
|
void wxDividedShapeControlPoint::OnBeginDragLeft(double WXUNUSED(x), double y, int WXUNUSED(keys), int WXUNUSED(attachment))
|
|
{
|
|
wxClientDC dc(GetCanvas());
|
|
GetCanvas()->PrepareDC(dc);
|
|
|
|
wxDividedShape *dividedObject = (wxDividedShape *)m_shape;
|
|
dc.SetLogicalFunction(OGLRBLF);
|
|
wxPen dottedPen(wxColour(0, 0, 0), 1, wxPENSTYLE_DOT);
|
|
dc.SetPen(dottedPen);
|
|
dc.SetBrush((* wxTRANSPARENT_BRUSH));
|
|
|
|
double x1 = (double)(dividedObject->GetX() - (dividedObject->GetWidth() / 2.0));
|
|
double y1 = y;
|
|
double x2 = (double)(dividedObject->GetX() + (dividedObject->GetWidth() / 2.0));
|
|
double y2 = y;
|
|
dc.DrawLine(WXROUND(x1), WXROUND(y1), WXROUND(x2), WXROUND(y2));
|
|
m_canvas->CaptureMouse();
|
|
}
|
|
|
|
void wxDividedShapeControlPoint::OnEndDragLeft(double WXUNUSED(x), double y, int WXUNUSED(keys), int WXUNUSED(attachment))
|
|
{
|
|
wxClientDC dc(GetCanvas());
|
|
GetCanvas()->PrepareDC(dc);
|
|
|
|
wxDividedShape *dividedObject = (wxDividedShape *)m_shape;
|
|
wxNode *node = dividedObject->GetRegions().Item(regionId);
|
|
if (!node)
|
|
return;
|
|
|
|
wxShapeRegion *thisRegion = (wxShapeRegion *)node->GetData();
|
|
wxShapeRegion *nextRegion = NULL; // Region below this one
|
|
|
|
dc.SetLogicalFunction(wxCOPY);
|
|
|
|
m_canvas->ReleaseMouse();
|
|
|
|
// Find the old top and bottom of this region,
|
|
// and calculate the new proportion for this region
|
|
// if legal.
|
|
|
|
double currentY = (double)(dividedObject->GetY() - (dividedObject->GetHeight() / 2.0));
|
|
double maxY = (double)(dividedObject->GetY() + (dividedObject->GetHeight() / 2.0));
|
|
|
|
// Save values
|
|
double thisRegionTop = 0.0;
|
|
#if 0
|
|
// this variable is not readed later
|
|
double thisRegionBottom = 0.0;
|
|
#endif
|
|
double nextRegionBottom = 0.0;
|
|
|
|
node = dividedObject->GetRegions().GetFirst();
|
|
while (node)
|
|
{
|
|
wxShapeRegion *region = (wxShapeRegion *)node->GetData();
|
|
|
|
double proportion = region->m_regionProportionY;
|
|
double yy = currentY + (dividedObject->GetHeight() * proportion);
|
|
double actualY = (double)(maxY < yy ? maxY : yy);
|
|
|
|
if (region == thisRegion)
|
|
{
|
|
thisRegionTop = currentY;
|
|
#if 0
|
|
// no need for assignment if value is not used later
|
|
thisRegionBottom = actualY;
|
|
#endif
|
|
if (node->GetNext())
|
|
nextRegion = (wxShapeRegion *)node->GetNext()->GetData();
|
|
}
|
|
if (region == nextRegion)
|
|
{
|
|
nextRegionBottom = actualY;
|
|
}
|
|
|
|
currentY = actualY;
|
|
node = node->GetNext();
|
|
}
|
|
if (!nextRegion)
|
|
return;
|
|
|
|
// Check that we haven't gone above this region or below
|
|
// next region.
|
|
if ((y <= thisRegionTop) || (y >= nextRegionBottom))
|
|
return;
|
|
|
|
// dividedObject->EraseLinks(dc);
|
|
|
|
// Now calculate the new proportions of this region and the next region.
|
|
double thisProportion = (double)((y - thisRegionTop) / dividedObject->GetHeight());
|
|
double nextProportion = (double)((nextRegionBottom - y) / dividedObject->GetHeight());
|
|
thisRegion->SetProportions(0.0, thisProportion);
|
|
nextRegion->SetProportions(0.0, nextProportion);
|
|
m_yoffset = (double)(y - dividedObject->GetY());
|
|
|
|
// Now reformat text
|
|
int i = 0;
|
|
node = dividedObject->GetRegions().GetFirst();
|
|
while (node)
|
|
{
|
|
wxShapeRegion *region = (wxShapeRegion *)node->GetData();
|
|
if (!region->GetText().IsEmpty())
|
|
{
|
|
wxChar *s = oglCopystring(region->GetText());
|
|
dividedObject->FormatText(dc, s, i);
|
|
delete[] s;
|
|
}
|
|
node = node->GetNext();
|
|
i++;
|
|
}
|
|
dividedObject->SetRegionSizes();
|
|
dividedObject->GetEventHandler()->OnMoveLinks();
|
|
|
|
if (GetCanvas())
|
|
GetCanvas()->Refresh();
|
|
}
|
|
|