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

📄 shapes.cpp

📁 Wxpython Implemented on Windows CE, Source code
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/////////////////////////////////////////////////////////////////////////////
// Name:        contrib/samples/ogl/studio/shapes.cpp
// Purpose:     Implements Studio shapes
// Author:      Julian Smart
// Modified by:
// Created:     12/07/98
// RCS-ID:      $Id: shapes.cpp,v 1.14 2006/02/10 11:59:48 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_DOC_VIEW_ARCHITECTURE
#error You must set wxUSE_DOC_VIEW_ARCHITECTURE to 1 in wx_setup.h!
#endif

#include "wx/ogl/ogl.h" // base header of OGL, includes and adjusts wx/deprecated/setup.h

#include "studio.h"
#include "doc.h"
#include "shapes.h"
#include "view.h"
#include "cspalette.h"
#include "dialogs.h"

#define csSTANDARD_SHAPE_WIDTH      100

IMPLEMENT_CLASS(csDiagram, wxDiagram)

csDiagram::~csDiagram()
{
    DeleteAllShapes();
}

void csDiagram::Redraw(wxDC& dc)
{
    wxDiagram::Redraw(dc);

    // Draw line crossings
    wxLineCrossings lineCrossings;
    lineCrossings.FindCrossings(*this);
    lineCrossings.DrawCrossings(*this, dc);
}

/*
 * csEvtHandler: an event handler class for all shapes
 */

IMPLEMENT_DYNAMIC_CLASS(csEvtHandler, wxShapeEvtHandler)

csEvtHandler::csEvtHandler(wxShapeEvtHandler *prev, wxShape *shape, const wxString& lab):
  wxShapeEvtHandler(prev, shape)
{
    m_label = lab;
}

csEvtHandler::~csEvtHandler()
{
}

// Copy any event handler data
void csEvtHandler::CopyData(wxShapeEvtHandler& copy)
{
    wxShapeEvtHandler::CopyData(copy);

    csEvtHandler& csCopy = (csEvtHandler&) copy;
    csCopy.m_label = m_label;
}

void csEvtHandler::OnLeftClick(double WXUNUSED(x), double WXUNUSED(y), int keys, int WXUNUSED(attachment))
{
  wxClientDC dc(GetShape()->GetCanvas());
  GetShape()->GetCanvas()->PrepareDC(dc);

  csDiagramView* view = ((csCanvas*)GetShape()->GetCanvas())->GetView();
  view->ReflectPointSize(GetShape()->GetFont()->GetPointSize());

  if (GetShape()->IsKindOf(CLASSINFO(wxLineShape)))
      view->ReflectArrowState((wxLineShape*) GetShape());

  csEditorToolPalette *palette = wxGetApp().GetDiagramPalette();
  if (palette->GetSelection() == PALETTE_TEXT_TOOL)
  {
        view->ReflectPointSize(GetShape()->GetFont()->GetPointSize());

        EditProperties();
#if 0
        csLabelEditingDialog* dialog = new csLabelEditingDialog(GetShape()->GetCanvas()->GetParent());
        dialog->SetShapeLabel(m_label);
        if (dialog->ShowModal() == wxID_CANCEL)
        {
            dialog->Destroy();
            return;
        }

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

        wxShape* newShape = GetShape()->CreateNewCopy();

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

        view->GetDocument()->GetCommandProcessor()->Submit(new csDiagramCommand("Edit label", (csDiagramDocument*) view->GetDocument(),
            new csCommandState(ID_CS_EDIT_PROPERTIES, newShape, GetShape())));
#endif
        return;
  }

  if (keys == 0)
  {
    // If no shift key, then everything is deselected.
    // If the shape was selected, deselect it and vice versa.
    bool selected = GetShape()->Selected();

    view->SelectAll(false);

    selected = !selected;

    GetShape()->Select(selected, &dc);
    GetShape()->GetCanvas()->Redraw(dc); // Redraw because bits of objects will be missing

    view->SelectShape(GetShape(), selected);
  }
  else if (keys & KEY_SHIFT)
  {
    if (GetShape()->Selected())
    {
        GetShape()->Select(false, &dc);
        view->SelectShape(GetShape(), false);
    }
    else
    {
        GetShape()->Select(true, &dc);
        view->SelectShape(GetShape(), true);
    }
    GetShape()->GetCanvas()->Redraw(dc); // Redraw because bits of objects will be missing
  }
  else if (keys & KEY_CTRL)
  {
    // Do something for CONTROL
  }
  else
  {
#if wxUSE_STATUSBAR
    ((wxFrame*)wxGetApp().GetTopWindow())->SetStatusText(m_label);
#endif // wxUSE_STATUSBAR
  }
}

void csEvtHandler::OnRightClick(double x, double y, int WXUNUSED(keys), int WXUNUSED(attachment))
{
    // Have to convert back to physical coordinates from logical coordinates.

    int viewStartX, viewStartY;
    int unitX, unitY;
    GetShape()->GetCanvas()->GetViewStart(& viewStartX, & viewStartY);
    GetShape()->GetCanvas()->GetScrollPixelsPerUnit(& unitX, & unitY);

    int x1 = (int)(x * GetShape()->GetCanvas()->GetScaleX());
    int y1 = (int)(y * GetShape()->GetCanvas()->GetScaleY());

    int menuX = (int) (x1 - (viewStartX * unitX)) ;
    int menuY = (int) (y1 - (viewStartY * unitY));

    wxGetApp().GetShapeEditMenu()->SetClientData((char*) GetShape());
    wxGetApp().GetShapeEditMenu()->Enable(ID_CS_ROTATE_CLOCKWISE, !GetShape()->IsKindOf(CLASSINFO(wxLineShape)));
    wxGetApp().GetShapeEditMenu()->Enable(ID_CS_ROTATE_ANTICLOCKWISE, !GetShape()->IsKindOf(CLASSINFO(wxLineShape)));

    GetShape()->GetCanvas()->PopupMenu(wxGetApp().GetShapeEditMenu(), menuX, menuY);
}

/*
 * Implement connection of two shapes by right-dragging between them.
 */

void csEvtHandler::OnBeginDragRight(double x, double y, int WXUNUSED(keys), int attachment)
{
  wxClientDC dc(GetShape()->GetCanvas());
  GetShape()->GetCanvas()->PrepareDC(dc);

  wxPen dottedPen(*wxBLACK, 1, wxDOT);
  dc.SetLogicalFunction(OGLRBLF);
  dc.SetPen(dottedPen);
  double xp, yp;
  GetShape()->GetAttachmentPositionEdge(attachment, &xp, &yp);
  dc.DrawLine((wxCoord)xp, (wxCoord)yp, (wxCoord)x, (wxCoord)y);
  GetShape()->GetCanvas()->CaptureMouse();
}

void csEvtHandler::OnDragRight(bool WXUNUSED(draw), double x, double y, int WXUNUSED(keys), int attachment)
{
  wxClientDC dc(GetShape()->GetCanvas());
  GetShape()->GetCanvas()->PrepareDC(dc);

  wxPen dottedPen(*wxBLACK, 1, wxDOT);
  dc.SetLogicalFunction(OGLRBLF);
  dc.SetPen(dottedPen);
  double xp, yp;
  GetShape()->GetAttachmentPositionEdge(attachment, &xp, &yp);
  dc.DrawLine((wxCoord)xp, (wxCoord)yp, (wxCoord)x, (wxCoord)y);
}

void csEvtHandler::OnEndDragRight(double x, double y, int WXUNUSED(keys), int attachment)
{
  GetShape()->GetCanvas()->ReleaseMouse();
  csCanvas *canvas = (csCanvas *)GetShape()->GetCanvas();

  // Check if we're on an object
  int new_attachment;
  wxShape *otherShape = canvas->FindFirstSensitiveShape(x, y, &new_attachment, OP_DRAG_RIGHT);

  if (otherShape && !otherShape->IsKindOf(CLASSINFO(wxLineShape)))
  {
        wxLineShape* theShape = new csLineShape;

        theShape->AssignNewIds();
        theShape->SetEventHandler(new csEvtHandler(theShape, theShape, wxEmptyString));
        theShape->SetPen(wxBLACK_PEN);
        theShape->SetBrush(wxRED_BRUSH);

        wxToolBar* toolbar = wxGetApp().GetDiagramToolBar();
        bool haveArrow = toolbar->GetToolState(DIAGRAM_TOOLBAR_LINE_ARROW);

        wxLineShape *lineShape = (wxLineShape *)theShape;

        // Yes, you can have more than 2 control points, in which case
        // it becomes a multi-segment line.
        lineShape->MakeLineControlPoints(2);

        if (haveArrow)
            lineShape->AddArrow(ARROW_ARROW, ARROW_POSITION_MIDDLE, 10.0, 0.0, _T("Normal arrowhead"));

        lineShape->SetFrom(GetShape());
        lineShape->SetTo(otherShape);
        lineShape->SetAttachments(attachment, new_attachment);

        canvas->GetView()->GetDocument()->GetCommandProcessor()->Submit(
            new csDiagramCommand(_T("Line"), (csDiagramDocument *)canvas->GetView()->GetDocument(),
                    new csCommandState(ID_CS_ADD_LINE, lineShape, NULL)));
  }
}

static double g_DragOffsetX = 0.0;
static double g_DragOffsetY = 0.0;
static double g_DragStartX = 0.0;
static double g_DragStartY = 0.0;

void csEvtHandler::OnDragLeft(bool draw, double x, double y, int keys, int attachment)
{
  if ((GetShape()->GetSensitivityFilter() & OP_DRAG_LEFT) != OP_DRAG_LEFT)
  {
    attachment = 0;
    double dist;
    if (GetShape()->GetParent())
    {
      GetShape()->GetParent()->HitTest(x, y, &attachment, &dist);
      GetShape()->GetParent()->GetEventHandler()->OnDragLeft(draw, x, y, keys, attachment);
    }
    return;
  }

  wxClientDC dc(GetShape()->GetCanvas());
  GetShape()->GetCanvas()->PrepareDC(dc);

  dc.SetLogicalFunction(OGLRBLF);

  wxPen dottedPen(*wxBLACK, 1, wxDOT);
  dc.SetPen(dottedPen);
  dc.SetBrush(* wxTRANSPARENT_BRUSH);

  double xx, yy;
  xx = x + g_DragOffsetX;
  yy = y + g_DragOffsetY;

  GetShape()->GetCanvas()->Snap(&xx, &yy);

  double offsetX = xx - g_DragStartX;
  double offsetY = yy - g_DragStartY;

//  m_xpos = xx; m_ypos = yy;
  double w, h;
  GetShape()->GetBoundingBoxMax(&w, &h);
  GetShape()->GetEventHandler()->OnDrawOutline(dc, xx, yy, w, h);

  // Draw bounding box for other selected shapes
  wxObjectList::compatibility_iterator node = GetShape()->GetCanvas()->GetDiagram()->GetShapeList()->GetFirst();
  while (node)
  {
     wxShape* shape = (wxShape*) node->GetData();
     if (shape->Selected() && !shape->IsKindOf(CLASSINFO(wxLineShape)) && (shape != GetShape()))
     {
        shape->GetBoundingBoxMax(&w, &h);
        shape->OnDrawOutline(dc, shape->GetX() + offsetX, shape->GetY() + offsetY, w, h);
     }
     node = node->GetNext();
  }
}

void csEvtHandler::OnBeginDragLeft(double x, double y, int keys, int attachment)
{
  if ((GetShape()->GetSensitivityFilter() & OP_DRAG_LEFT) != OP_DRAG_LEFT)
  {
    attachment = 0;
    double dist;
    if (GetShape()->GetParent())
    {
      GetShape()->GetParent()->HitTest(x, y, &attachment, &dist);
      GetShape()->GetParent()->GetEventHandler()->OnBeginDragLeft(x, y, keys, attachment);
    }
    return;
  }

  wxClientDC dc(GetShape()->GetCanvas());
  GetShape()->GetCanvas()->PrepareDC(dc);

  // New policy: don't erase shape until end of drag.
//  Erase(dc);

  g_DragOffsetX = GetShape()->GetX() - x;
  g_DragOffsetY = GetShape()->GetY() - y;

  double xx, yy;
  xx = x + g_DragOffsetX;
  yy = y + g_DragOffsetY;

  GetShape()->GetCanvas()->Snap(&xx, &yy);

  g_DragStartX = GetShape()->GetX();
  g_DragStartY = GetShape()->GetY();

  double offsetX = xx - g_DragStartX;
  double offsetY = yy - g_DragStartY;

  dc.SetLogicalFunction(OGLRBLF);

  wxPen dottedPen(*wxBLACK, 1, wxDOT);
  dc.SetPen(dottedPen);
  dc.SetBrush((* wxTRANSPARENT_BRUSH));

  double w, h;
  GetShape()->GetBoundingBoxMax(&w, &h);
  GetShape()->GetEventHandler()->OnDrawOutline(dc, xx, yy, w, h);

  // Draw bounding box for other selected shapes
  wxObjectList::compatibility_iterator node = GetShape()->GetCanvas()->GetDiagram()->GetShapeList()->GetFirst();
  while (node)
  {
     wxShape* shape = (wxShape*) node->GetData();
     if (shape->Selected() && !shape->IsKindOf(CLASSINFO(wxLineShape)) && (shape != GetShape()))
     {
        shape->GetBoundingBoxMax(&w, &h);
        shape->OnDrawOutline(dc, shape->GetX() + offsetX, shape->GetY() + offsetY, w, h);
     }
     node = node->GetNext();
  }

  GetShape()->GetCanvas()->CaptureMouse();
}


void csEvtHandler::OnEndDragLeft(double x, double y, int keys, int attachment)
{
  csCanvas *canvas = (csCanvas *)GetShape()->GetCanvas();

  canvas->ReleaseMouse();
  if ((GetShape()->GetSensitivityFilter() & OP_DRAG_LEFT) != OP_DRAG_LEFT)
  {
    attachment = 0;
    double dist;
    if (GetShape()->GetParent())
    {
      GetShape()->GetParent()->HitTest(x, y, &attachment, &dist);
      GetShape()->GetParent()->GetEventHandler()->OnEndDragLeft(x, y, keys, attachment);
    }
    return;
  }

  wxClientDC dc(canvas);
  canvas->PrepareDC(dc);

  dc.SetLogicalFunction(wxCOPY);

  double xx = x + g_DragOffsetX;
  double yy = y + g_DragOffsetY;

  canvas->Snap(&xx, &yy);

  double offsetX = xx - g_DragStartX;
  double offsetY = yy - g_DragStartY;

⌨️ 快捷键说明

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