📄 composit.cpp
字号:
if (m_parent)
{
m_parent->HitTest(x, y, &attachment, &dist);
m_parent->GetEventHandler()->OnDragLeft(draw, x, y, keys, attachment);
}
return;
}
wxShape::OnDragLeft(draw, x, y, keys, attachment);
}
void wxDivisionShape::OnBeginDragLeft(double x, double y, int keys, int attachment)
{
if ((m_sensitivity & OP_DRAG_LEFT) != OP_DRAG_LEFT)
{
attachment = 0;
double dist;
if (m_parent)
{
m_parent->HitTest(x, y, &attachment, &dist);
m_parent->GetEventHandler()->OnBeginDragLeft(x, y, keys, attachment);
}
return;
}
wxShape::OnBeginDragLeft(x, y, keys, attachment);
}
void wxDivisionShape::OnEndDragLeft(double x, double y, int keys, int attachment)
{
m_canvas->ReleaseMouse();
if ((m_sensitivity & OP_DRAG_LEFT) != OP_DRAG_LEFT)
{
attachment = 0;
double dist;
if (m_parent)
{
m_parent->HitTest(x, y, &attachment, &dist);
m_parent->GetEventHandler()->OnEndDragLeft(x, y, keys, attachment);
}
return;
}
wxClientDC dc(GetCanvas());
GetCanvas()->PrepareDC(dc);
dc.SetLogicalFunction(wxCOPY);
m_canvas->Snap(&m_xpos, &m_ypos);
GetEventHandler()->OnMovePre(dc, x, y, m_oldX, m_oldY);
ResetControlPoints();
Draw(dc);
MoveLinks(dc);
GetEventHandler()->OnDrawControlPoints(dc);
if (m_canvas && !m_canvas->GetQuickEditMode()) m_canvas->Redraw(dc);
}
void wxDivisionShape::SetSize(double w, double h, bool recursive)
{
m_width = w;
m_height = h;
wxRectangleShape::SetSize(w, h, recursive);
}
void wxDivisionShape::CalculateSize()
{
}
void wxDivisionShape::Copy(wxShape& copy)
{
wxCompositeShape::Copy(copy);
wxASSERT( copy.IsKindOf(CLASSINFO(wxDivisionShape)) ) ;
wxDivisionShape& divisionCopy = (wxDivisionShape&) copy;
divisionCopy.m_leftSideStyle = m_leftSideStyle;
divisionCopy.m_topSideStyle = m_topSideStyle;
divisionCopy.m_leftSideColour = m_leftSideColour;
divisionCopy.m_topSideColour = m_topSideColour;
divisionCopy.m_leftSidePen = m_leftSidePen;
divisionCopy.m_topSidePen = m_topSidePen;
divisionCopy.m_handleSide = m_handleSide;
// Division geometry copying is handled at the wxCompositeShape level.
}
#if wxUSE_PROLOGIO
void wxDivisionShape::WriteAttributes(wxExpr *clause)
{
wxCompositeShape::WriteAttributes(clause);
if (m_leftSide)
clause->AddAttributeValue(_T("left_side"), (long)m_leftSide->GetId());
if (m_topSide)
clause->AddAttributeValue(_T("top_side"), (long)m_topSide->GetId());
if (m_rightSide)
clause->AddAttributeValue(_T("right_side"), (long)m_rightSide->GetId());
if (m_bottomSide)
clause->AddAttributeValue(_T("bottom_side"), (long)m_bottomSide->GetId());
clause->AddAttributeValue(_T("handle_side"), (long)m_handleSide);
clause->AddAttributeValueString(_T("left_colour"), m_leftSideColour);
clause->AddAttributeValueString(_T("top_colour"), m_topSideColour);
clause->AddAttributeValueString(_T("left_style"), m_leftSideStyle);
clause->AddAttributeValueString(_T("top_style"), m_topSideStyle);
}
void wxDivisionShape::ReadAttributes(wxExpr *clause)
{
wxCompositeShape::ReadAttributes(clause);
clause->GetAttributeValue(_T("handle_side"), m_handleSide);
clause->GetAttributeValue(_T("left_colour"), m_leftSideColour);
clause->GetAttributeValue(_T("top_colour"), m_topSideColour);
clause->GetAttributeValue(_T("left_style"), m_leftSideStyle);
clause->GetAttributeValue(_T("top_style"), m_topSideStyle);
}
#endif
// Experimental
void wxDivisionShape::OnRightClick(double x, double y, int keys, int attachment)
{
if (keys & KEY_CTRL)
{
PopupMenu(x, y);
}
/*
else if (keys & KEY_SHIFT)
{
if (m_leftSide || m_topSide || m_rightSide || m_bottomSide)
{
if (Selected())
{
Select(false);
GetParent()->Draw(dc);
}
else
Select(true);
}
}
*/
else
{
attachment = 0;
double dist;
if (m_parent)
{
m_parent->HitTest(x, y, &attachment, &dist);
m_parent->GetEventHandler()->OnRightClick(x, y, keys, attachment);
}
return;
}
}
// Divide wxHORIZONTALly or wxVERTICALly
bool wxDivisionShape::Divide(int direction)
{
// Calculate existing top-left, bottom-right
double x1 = (double)(GetX() - (GetWidth()/2.0));
double y1 = (double)(GetY() - (GetHeight()/2.0));
wxCompositeShape *compositeParent = (wxCompositeShape *)GetParent();
double oldWidth = GetWidth();
double oldHeight = GetHeight();
if (Selected())
Select(false);
wxClientDC dc(GetCanvas());
GetCanvas()->PrepareDC(dc);
if (direction == wxVERTICAL)
{
// Dividing vertically means notionally putting a horizontal line through it.
// Break existing piece into two.
double newXPos1 = GetX();
double newYPos1 = (double)(y1 + (GetHeight()/4.0));
double newXPos2 = GetX();
double newYPos2 = (double)(y1 + (3.0*GetHeight()/4.0));
wxDivisionShape *newDivision = compositeParent->OnCreateDivision();
newDivision->Show(true);
Erase(dc);
// Anything adjoining the bottom of this division now adjoins the
// bottom of the new division.
wxNode *node = compositeParent->GetDivisions().GetFirst();
while (node)
{
wxDivisionShape *obj = (wxDivisionShape *)node->GetData();
if (obj->GetTopSide() == this)
obj->SetTopSide(newDivision);
node = node->GetNext();
}
newDivision->SetTopSide(this);
newDivision->SetBottomSide(m_bottomSide);
newDivision->SetLeftSide(m_leftSide);
newDivision->SetRightSide(m_rightSide);
m_bottomSide = newDivision;
compositeParent->GetDivisions().Append(newDivision);
// CHANGE: Need to insert this division at start of divisions in the object
// list, because e.g.:
// 1) Add division
// 2) Add contained object
// 3) Add division
// Division is now receiving mouse events _before_ the contained object,
// because it was added last (on top of all others)
// Add after the image that visualizes the container
compositeParent->AddChild(newDivision, compositeParent->FindContainerImage());
m_handleSide = DIVISION_SIDE_BOTTOM;
newDivision->SetHandleSide(DIVISION_SIDE_TOP);
SetSize(oldWidth, (double)(oldHeight/2.0));
Move(dc, newXPos1, newYPos1);
newDivision->SetSize(oldWidth, (double)(oldHeight/2.0));
newDivision->Move(dc, newXPos2, newYPos2);
}
else
{
// Dividing horizontally means notionally putting a vertical line through it.
// Break existing piece into two.
double newXPos1 = (double)(x1 + (GetWidth()/4.0));
double newYPos1 = GetY();
double newXPos2 = (double)(x1 + (3.0*GetWidth()/4.0));
double newYPos2 = GetY();
wxDivisionShape *newDivision = compositeParent->OnCreateDivision();
newDivision->Show(true);
Erase(dc);
// Anything adjoining the left of this division now adjoins the
// left of the new division.
wxNode *node = compositeParent->GetDivisions().GetFirst();
while (node)
{
wxDivisionShape *obj = (wxDivisionShape *)node->GetData();
if (obj->GetLeftSide() == this)
obj->SetLeftSide(newDivision);
node = node->GetNext();
}
newDivision->SetTopSide(m_topSide);
newDivision->SetBottomSide(m_bottomSide);
newDivision->SetLeftSide(this);
newDivision->SetRightSide(m_rightSide);
m_rightSide = newDivision;
compositeParent->GetDivisions().Append(newDivision);
compositeParent->AddChild(newDivision, compositeParent->FindContainerImage());
m_handleSide = DIVISION_SIDE_RIGHT;
newDivision->SetHandleSide(DIVISION_SIDE_LEFT);
SetSize((double)(oldWidth/2.0), oldHeight);
Move(dc, newXPos1, newYPos1);
newDivision->SetSize((double)(oldWidth/2.0), oldHeight);
newDivision->Move(dc, newXPos2, newYPos2);
}
if (compositeParent->Selected())
{
compositeParent->DeleteControlPoints(& dc);
compositeParent->MakeControlPoints();
compositeParent->MakeMandatoryControlPoints();
}
compositeParent->Draw(dc);
return true;
}
// Make one control point for every visible line
void wxDivisionShape::MakeControlPoints()
{
MakeMandatoryControlPoints();
}
void wxDivisionShape::MakeMandatoryControlPoints()
{
double maxX, maxY;
GetBoundingBoxMax(&maxX, &maxY);
double x = 0.0 , y = 0.0;
int direction = 0;
/*
if (m_leftSide)
{
x = (double)(-maxX/2.0);
y = 0.0;
wxDivisionControlPoint *control = new wxDivisionControlPoint(m_canvas, this, CONTROL_POINT_SIZE, x, y,
CONTROL_POINT_HORIZONTAL);
m_canvas->AddShape(control);
m_controlPoints.Append(control);
}
if (m_topSide)
{
x = 0.0;
y = (double)(-maxY/2.0);
wxDivisionControlPoint *control = new wxDivisionControlPoint(m_canvas, this, CONTROL_POINT_SIZE, x, y,
CONTROL_POINT_VERTICAL);
m_canvas->AddShape(control);
m_controlPoints.Append(control);
}
*/
switch (m_handleSide)
{
case DIVISION_SIDE_LEFT:
{
x = (double)(-maxX/2.0);
y = 0.0;
direction = CONTROL_POINT_HORIZONTAL;
break;
}
case DIVISION_SIDE_TOP:
{
x = 0.0;
y = (double)(-maxY/2.0);
direction = CONTROL_POINT_VERTICAL;
break;
}
case DIVISION_SIDE_RIGHT:
{
x = (double)(maxX/2.0);
y = 0.0;
direction = CONTROL_POINT_HORIZONTAL;
break;
}
case DIVISION_SIDE_BOTTOM:
{
x = 0.0;
y = (double)(maxY/2.0);
direction = CONTROL_POINT_VERTICAL;
break;
}
default:
break;
}
if (m_handleSide != DIVISION_SIDE_NONE)
{
wxDivisionControlPoint *control = new wxDivisionControlPoint(m_canvas, this, CONTROL_POINT_SIZE, x, y,
direction);
m_canvas->AddShape(control);
m_controlPoints.Append(control);
}
}
void wxDivisionShape::ResetControlPoints()
{
ResetMandatoryControlPoints();
}
void wxDivisionShape::ResetMandatoryControlPoints()
{
if (m_controlPoints.GetCount() < 1)
return;
double maxX, maxY;
GetBoundingBoxMax(&maxX, &maxY);
/*
wxNode *node = m_controlPoints.GetFirst();
while (node)
{
wxDivisionControlPoint *control = (wxDivisionControlPoint *)node->GetData();
if (control->type == CONTROL_POINT_HORIZONTAL)
{
control->xoffset = (double)(-maxX/2.0); control->m_yoffset = 0.0;
}
else if (control->type == CONTROL_POINT_VERTICAL)
{
control->xoffset = 0.0; control->m_yoffset = (double)(-maxY/2.0);
}
node = node->GetNext();
}
*/
wxNode *node = m_controlPoints.GetFirst();
if ((m_handleSide == DIVISION_SIDE_LEFT) && node)
{
wxDivisionControlPoint *control = (wxDivisionControlPoint *)node->GetData();
control->m_xoffset = (double)(-maxX/2.0); control->m_yoffset = 0.0;
}
if ((m_handleSide == DIVISION_SIDE_TOP) && node)
{
wxDivisionControlPoint *control = (wxDivisionControlPoint *)node->GetData();
control->m_xoffset = 0.0; control->m_yoffset = (double)(-maxY/2.0);
}
if ((m_handleSide == DIVISION_SIDE_RIGHT) && node)
{
wxDivisionControlPoint *control = (wxDivisionControlPoint *)node->GetData();
control->m_xoffset = (double)(maxX/2.0); control->m_yoffset = 0.0;
}
if ((m_handleSide == DIVISION_SIDE_BOTTOM) && node)
{
wxDivisionControlPoint *control = (wxDivisionControlPoint *)node->GetData();
control->m_xoffset = 0.0; control->m_yoffset = (double)(maxY/2.0);
}
}
// Adjust a side, returning false if it's not physically possible.
bool wxDivisionShape::AdjustLeft(double left, bool test)
{
double x2 = (double)(GetX() + (GetWidth()/2.0));
if (left >= x2)
return false;
if (test)
return true;
double newW = x2 - left;
double newX = (double)(left + newW/2.0);
SetSize(newW, GetHeight());
wxClientDC dc(GetCanvas());
GetCanvas()->PrepareDC(dc);
Move(dc, newX, GetY());
return true;
}
bool wxDivisionShape::AdjustTop(double top, bool test)
{
double y2 = (double)(GetY() + (GetHeight()/2.0));
if (top >= y2)
return false;
if (test)
return true;
double newH = y2 - top;
double newY = (double)(top + newH/2.0);
SetSize(GetWidth(), newH);
wxClientDC dc(GetCanvas());
GetCanvas()->PrepareDC(dc);
Move(dc, GetX(), newY);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -