⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shapes.cpp

📁 Wxpython Implemented on Windows CE, Source code
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    /*
        Formula: ((w/2) / h) = w1 / h1
        w1 = ((w/2) / h) * h1;
    */
    double ratio = ((w/2.0) / h) ;
    double w1 = ratio * h1;

    points[0] = wxPoint(0  ,  (int) (- h / 2 ));
    points[1] = wxPoint( (int) w1,  (int) (- h / 2 + h1));
    points[2] = wxPoint( (int) -w1, (int) (- h / 2 + h1));

    DrawPolygon(3, points);

    delete[] points;

    CalculateSize();

    SetAttachmentMode(ATTACHMENT_MODE_BRANCHING);
    SetBranchStyle(BRANCHING_ATTACHMENT_NORMAL|BRANCHING_ATTACHMENT_BLOB);
    SetCentreResize(false);
}

IMPLEMENT_DYNAMIC_CLASS(csSemiCircleShape, wxDrawnShape)

csSemiCircleShape::csSemiCircleShape()
{
    // Zero degrees
    DrawAtAngle(oglDRAWN_ANGLE_0);

    double w = csSTANDARD_SHAPE_WIDTH;
    double h = w/2.0;

    SetDrawnPen(wxTRANSPARENT_PEN);
    SetDrawnBrush(wxTRANSPARENT_BRUSH);

    // Draw a dummy rectangle that will be used for calculating the
    // bounding box, since we can't calculate the bounding box for
    // an arbitrary arc (not implemented)

    DrawRectangle(wxRect((int)(-w/2.0), (int)(-h/2.0), (int)(w), (int)(h)));

    SetDrawnPen(wxBLACK_PEN);
    wxBrush* brush = wxTheBrushList->FindOrCreateBrush(wxColour(220, 220, 220), wxSOLID);
    SetDrawnBrush(brush);

    DrawEllipticArc(wxRect((int)(-w/2), (int)(-h/2), (int)(w), (int)(2*h)), 0.0, 180.0);
    DrawLine(wxPoint((int)(-w/2), (int)(h/2)), wxPoint((int)(w/2), (int)(h/2)));

    CalculateSize();

    /// 90 degrees

    w = csSTANDARD_SHAPE_WIDTH/2;
    h = csSTANDARD_SHAPE_WIDTH;

    DrawAtAngle(oglDRAWN_ANGLE_90);

    SetDrawnPen(wxTRANSPARENT_PEN);
    SetDrawnBrush(wxTRANSPARENT_BRUSH);

    DrawRectangle(wxRect((int)(-w/2), (int)(-h/2), (int)(w), (int)(h)));

    SetDrawnPen(wxBLACK_PEN);
    SetDrawnBrush(brush);

    DrawEllipticArc(wxRect((int)(-w/2 - w), (int)(-h/2), (int)(2*w), (int)(h)), 270.0, 90.0);
    DrawLine(wxPoint((int)(-w/2), (int)(-h/2)), wxPoint((int)(-w/2), (int)(h/2)));

    CalculateSize();

    /// 180 degrees

    DrawAtAngle(oglDRAWN_ANGLE_180);

    w = csSTANDARD_SHAPE_WIDTH;
    h = csSTANDARD_SHAPE_WIDTH/2;

    SetDrawnPen(wxTRANSPARENT_PEN);
    SetDrawnBrush(wxTRANSPARENT_BRUSH);

    DrawRectangle(wxRect((int)(-w/2), (int)(-h/2), (int)(w), (int)(h)));

    SetDrawnPen(wxBLACK_PEN);
    SetDrawnBrush(brush);

    DrawEllipticArc(wxRect((int)(-w/2), (int)(-h/2 - h), (int)(w), (int)(2*h)), 180.0, 0.0);
    DrawLine(wxPoint((int)(-w/2), (int)(-h/2)), wxPoint((int)(w/2), (int)(-h/2)));

    CalculateSize();

    /// 270 degrees

    DrawAtAngle(oglDRAWN_ANGLE_270);

    w = csSTANDARD_SHAPE_WIDTH/2;
    h = csSTANDARD_SHAPE_WIDTH;

    SetDrawnPen(wxTRANSPARENT_PEN);
    SetDrawnBrush(wxTRANSPARENT_BRUSH);

    DrawRectangle(wxRect((int)(-w/2), (int)(-h/2), (int)(w), (int)(h)));

    SetDrawnPen(wxBLACK_PEN);
    SetDrawnBrush(brush);

    DrawEllipticArc(wxRect((int)(-w/2), (int)(-h/2), (int)(2*w), (int)(h)), 90.0, 270.0);
    DrawLine(wxPoint((int)(w/2),(int)(-h/2)), wxPoint((int)(w/2), (int)(h/2)));

    CalculateSize();

    // Reset to zero
    DrawAtAngle(oglDRAWN_ANGLE_0);
    CalculateSize();

    SetAttachmentMode(ATTACHMENT_MODE_BRANCHING);
    SetBranchStyle(BRANCHING_ATTACHMENT_NORMAL|BRANCHING_ATTACHMENT_BLOB);
    SetCentreResize(false);
}

IMPLEMENT_DYNAMIC_CLASS(csCircleShape, wxCircleShape)

csCircleShape::csCircleShape()
{
    SetPen(wxBLACK_PEN);
    wxBrush* brush = wxTheBrushList->FindOrCreateBrush(wxColour(220, 220, 220), wxSOLID);
    SetBrush(brush);

    SetSize(csSTANDARD_SHAPE_WIDTH*0.6, csSTANDARD_SHAPE_WIDTH*0.6);

    SetAttachmentMode(ATTACHMENT_MODE_BRANCHING);
    SetBranchStyle(BRANCHING_ATTACHMENT_NORMAL|BRANCHING_ATTACHMENT_BLOB);
    SetCentreResize(false);
}

IMPLEMENT_DYNAMIC_CLASS(csCircleShadowShape, wxCircleShape)

csCircleShadowShape::csCircleShadowShape()
{
    SetPen(wxBLACK_PEN);
    wxBrush* brush = wxTheBrushList->FindOrCreateBrush(wxColour(220, 220, 220), wxSOLID);
    SetBrush(brush);

    SetSize(csSTANDARD_SHAPE_WIDTH*0.6, csSTANDARD_SHAPE_WIDTH*0.6);

    SetAttachmentMode(ATTACHMENT_MODE_BRANCHING);
    SetBranchStyle(BRANCHING_ATTACHMENT_NORMAL|BRANCHING_ATTACHMENT_BLOB);
    SetCentreResize(false);
    SetShadowMode(SHADOW_RIGHT);
}

IMPLEMENT_DYNAMIC_CLASS(csOctagonShape, wxPolygonShape)

csOctagonShape::csOctagonShape()
{
    SetPen(wxBLACK_PEN);
    SetBrush(wxTheBrushList->FindOrCreateBrush(wxColour(220, 220, 220), wxSOLID));

    double w = csSTANDARD_SHAPE_WIDTH*0.5;
    double h = csSTANDARD_SHAPE_WIDTH*0.5;

    double prop = h/3.0;

    wxList* points = new wxList;
    points->Append((wxObject*) new wxRealPoint(-w/2.0 + prop, -h/2.0));
    points->Append((wxObject*) new wxRealPoint(w/2.0 - prop, -h/2.0));
    points->Append((wxObject*) new wxRealPoint(w/2.0, -h/2.0 + prop));
    points->Append((wxObject*) new wxRealPoint(w/2.0, h/2.0 - prop));
    points->Append((wxObject*) new wxRealPoint(w/2.0 - prop, h/2.0));
    points->Append((wxObject*) new wxRealPoint(-w/2.0 + prop, h/2.0));
    points->Append((wxObject*) new wxRealPoint(-w/2.0, h/2.0 - prop));
    points->Append((wxObject*) new wxRealPoint(-w/2.0, -h/2.0 + prop));

    Create(points);

    SetAttachmentMode(ATTACHMENT_MODE_BRANCHING);
    SetBranchStyle(BRANCHING_ATTACHMENT_NORMAL|BRANCHING_ATTACHMENT_BLOB);
    SetCentreResize(false);
}

// This is a transparent shape for drawing around other shapes.
IMPLEMENT_DYNAMIC_CLASS(csGroupShape, wxRectangleShape)

csGroupShape::csGroupShape()
{
    SetPen(wxThePenList->FindOrCreatePen(_T("BLACK"), 1, wxDOT));
    SetBrush(wxTRANSPARENT_BRUSH);

    SetSize(csSTANDARD_SHAPE_WIDTH, csSTANDARD_SHAPE_WIDTH);
    SetCentreResize(false);
}

void csGroupShape::OnDraw(wxDC& dc)
{
    wxRectangleShape::OnDraw(dc);
}

// Must modify the hit-test so it doesn't obscure shapes that are inside.
bool csGroupShape::HitTest(double x, double y, int* attachment, double* distance)
{
    *attachment = 0;
    *distance = 0.0;

    double width = 0.0, height = 0.0;
    GetBoundingBoxMin(&width, &height);

    double x1 = GetX() - (width/2.0);
    double y1 = GetY() - (height/2.0);
    double x2 = GetX() + (width/2.0);
    double y2 = GetY() + (height/2.0);

    double edgeTolerance = 4.0;

    // Test each edge in turn

    // Top/bottom edges
    if (x >= x1 && x <= x2)
    {
        if ((y >= y1 - edgeTolerance) && (y <= y1 + edgeTolerance))
            return true;
        if ((y <= y2 + edgeTolerance) && (y >= y2 - edgeTolerance))
            return true;
    }
    // Left/right edges
    if (y >= y1 && y <= y2)
    {
        if ((x >= x1 - edgeTolerance) && (x <= x1 + edgeTolerance))
            return true;
        if ((x <= x2 + edgeTolerance) && (x >= x2 - edgeTolerance))
            return true;
    }

    return false;
}

IMPLEMENT_DYNAMIC_CLASS(csTextBoxShape, wxRectangleShape)

csTextBoxShape::csTextBoxShape()
{
    SetPen(wxTRANSPARENT_PEN);
    SetBrush(wxTRANSPARENT_BRUSH);

    SetSize(csSTANDARD_SHAPE_WIDTH, csSTANDARD_SHAPE_WIDTH/2.0);

    SetAttachmentMode(ATTACHMENT_MODE_NONE);
    SetBranchStyle(BRANCHING_ATTACHMENT_NORMAL|BRANCHING_ATTACHMENT_BLOB);
    SetCentreResize(false);
}

IMPLEMENT_DYNAMIC_CLASS(csLineShape, wxLineShape)

csLineShape::csLineShape()
{
}

bool csLineShape::OnMoveMiddleControlPoint(wxDC& WXUNUSED(dc), wxLineControlPoint* lpt, const wxRealPoint& pt)
{
    csDiagramView* view = ((csCanvas*)GetCanvas())->GetView();

    // Temporarily set the new shape properties so we can copy it
    lpt->SetX(pt.x); lpt->SetY(pt.y);
    lpt->m_point->x = pt.x; lpt->m_point->y = pt.y;

    wxLineShape* newShape = (wxLineShape*) this->CreateNewCopy();

    // Now set them back again
    lpt->SetX(lpt->m_originalPos.x); lpt->SetY(lpt->m_originalPos.y);
    lpt->m_point->x = lpt->m_originalPos.x; lpt->m_point->y = lpt->m_originalPos.y;

    view->GetDocument()->GetCommandProcessor()->Submit(new csDiagramCommand(_T("Move line point"), (csDiagramDocument*) view->GetDocument(),
                new csCommandState(ID_CS_MOVE_LINE_POINT, newShape, this)));

    return true;
}

wxLabelShape* csLineShape::OnCreateLabelShape(wxLineShape *parent, wxShapeRegion *region, double w, double h)
{
    return new csLabelShape(parent, region, w, h);
}

#if 0
bool csLineShape::OnLabelMovePre(wxDC& dc, wxLabelShape* labelShape, double x, double y, double old_x, double old_y, bool display)
{
    csDiagramView* view = ((csCanvas*)GetCanvas())->GetView();

    wxLineShape* newShape = (wxLineShape*) this->CreateNewCopy();

    wxLineShape::OnLabelMovePre(dc, labelShape, x, y, old_x, old_y, display);

    view->GetDocument()->GetCommandProcessor()->Submit(new csDiagramCommand("Move label", (csDiagramDocument*) view->GetDocument(),
                new csCommandState(ID_CS_MOVE_LABEL, newShape, this)));
  return true;
}
#endif

IMPLEMENT_DYNAMIC_CLASS(csLabelShape, wxLabelShape)

csLabelShape::csLabelShape(wxLineShape *parent, wxShapeRegion *region, double w, double h):
  wxLabelShape(parent, region, w, h)
{
}

// TODO: not sure how intercept normal behaviour (OnMovePre) to make
// label movement undo-able.
void csLabelShape::OnEndDragLeft(double x, double y, int keys, int attachment)
{
    wxLabelShape::OnEndDragLeft(x, y, keys, attachment);
}


// Menu for editing shapes
void studioShapeEditProc(wxMenu& menu, wxCommandEvent& event)
{
    wxShape* shape = (wxShape*) menu.GetClientData();
    csDiagramView* view = ((csCanvas*)shape->GetCanvas())->GetView();

    switch (event.GetId())
    {
        case ID_CS_EDIT_PROPERTIES:
        {
            csEvtHandler* handler1 = (csEvtHandler *)shape->GetEventHandler();
            handler1->EditProperties();
#if 0
            csEvtHandler* handler1 = (csEvtHandler *)shape->GetEventHandler();
            csLabelEditingDialog* dialog = new csLabelEditingDialog(shape->GetCanvas()->GetParent());
            dialog->SetShapeLabel(handler1->m_label);
            if (dialog->ShowModal() == wxID_CANCEL)
            {
                dialog->Destroy();
                return;
            }

            wxString newLabel = dialog->GetShapeLabel();
            dialog->Destroy();

            wxShape* newShape = shape->CreateNewCopy();

            csEvtHandler* handler2 = (csEvtHandler *)newShape->GetEventHandler();
            handler2->m_label = newLabel;

            view->GetDocument()->GetCommandProcessor()->Submit(new csDiagramCommand("Edit label", (csDiagramDocument*) view->GetDocument(),
                new csCommandState(ID_CS_EDIT_LABEL, newShape, shape)));
#endif
            break;
        }
        case wxID_CUT:
        {
            wxList list;
            list.Append(shape);
            view->DoCut(list);
            break;
        }
        case ID_CS_ROTATE_CLOCKWISE:
        case ID_CS_ROTATE_ANTICLOCKWISE:
        {
            if (shape->IsKindOf(CLASSINFO(wxLineShape)))
                break;

            double theta = shape->GetRotation();
            const double myPi = M_PI;
            double ninetyDegrees = myPi/2.0;

            wxString opStr;
            if (event.GetId() == ID_CS_ROTATE_CLOCKWISE)
            {
                theta += ninetyDegrees;
                opStr = _T("Rotate clockwise");
            }
            else
            {
                theta -= ninetyDegrees;
                opStr = _T("Rotate anticlockwise");
            }

            if (theta >= 2.0*myPi || theta < 0.0)
                theta = 0.0;
            wxShape* newShape = shape->CreateNewCopy();
            newShape->Rotate(0.0, 0.0, theta);
            wxList newShapes;
            wxList oldShapes;
            newShapes.Append(newShape);
            oldShapes.Append(shape);
            view->DoCmd(newShapes, oldShapes, event.GetId(), opStr);
            break;
        }
        default:
            break;
    }
}

BEGIN_EVENT_TABLE(ShapeEditMenu, wxMenu)
    EVT_COMMAND_RANGE(1, 65000, wxEVT_COMMAND_MENU_SELECTED, ShapeEditMenu::OnCommand)
END_EVENT_TABLE()

void ShapeEditMenu::OnCommand(wxCommandEvent& event)
{
    studioShapeEditProc(*this, event);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -