📄 divided.cpp
字号:
/////////////////////////////////////////////////////////////////////////////
// Name: divided.cpp
// Purpose: wxDividedShape class
// Author: Julian Smart
// Modified by:
// Created: 12/07/98
// RCS-ID: $Id: divided.cpp,v 1.19 2005/10/06 18:17:21 ABX Exp $
// Copyright: (c) Julian Smart
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#if wxUSE_PROLOGIO
#include "wx/deprecated/wxexpr.h"
#endif
#include "wx/ogl/ogl.h"
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);
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);
wxObjectList::compatibility_iterator 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));
wxObjectList::compatibility_iterator 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);
wxObjectList::compatibility_iterator 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;
wxObjectList::compatibility_iterator 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& copy)
{
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));
wxObjectList::compatibility_iterator 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())
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -