Beispiel #1
0
void ExplainCanvas::SaveAsImage(const wxString &fileName, wxBitmapType imageType)
{
	if (GetDiagram()->GetCount() == 0)
	{
		wxMessageBox(_("Nothing to be saved!"), _("Save As an image"), wxOK | wxICON_INFORMATION);
		return;
	}

	int width = 0, height = 0;
	GetVirtualSize(&width, &height);

	/*
	* Create the bitmap from the Explain window
	*/
	wxMemoryDC memDC;
	wxBitmap tempBitmap(width, height);

	memDC.SelectObject(tempBitmap);
	memDC.Clear();

	// Draw the diagram on the bitmap (Memory Device Context)
	GetDiagram()->Redraw(memDC);

	memDC.SelectObject(wxNullBitmap);

	if (!tempBitmap.SaveFile(fileName, imageType))
	{
		wxLogError(_("Could not write file \"%s\": error code %d."), fileName.c_str(), wxSysErrorCode());
	}
}
Beispiel #2
0
void wxShapeCanvas::OnPaint(wxPaintEvent& WXUNUSED(event))
{
    wxPaintDC dc(this);

    PrepareDC(dc);

    dc.SetBackground(wxBrush(GetBackgroundColour(), wxSOLID));
    dc.Clear();

    if (GetDiagram())
        GetDiagram()->Redraw(dc);
}
Beispiel #3
0
void csCanvas::OnEndDragLeft(double x, double y, int WXUNUSED(keys))
{
    ReleaseMouse();

    wxClientDC dc(this);
    PrepareDC(dc);

    // Select all images within the rectangle
    float min_x, max_x, min_y, max_y;
    min_x = wxMin(x, sg_initialX);
    max_x = wxMax(x, sg_initialX);
    min_y = wxMin(y, sg_initialY);
    max_y = wxMax(y, sg_initialY);

    wxObjectList::compatibility_iterator node = GetDiagram()->GetShapeList()->GetFirst();
    while (node)
    {
        wxShape *shape = (wxShape *)node->GetData();
        if (shape->GetParent() == NULL && !shape->IsKindOf(CLASSINFO(wxControlPoint)))
        {
            float image_x = shape->GetX();
            float image_y = shape->GetY();
            if (image_x >= min_x && image_x <= max_x &&
                image_y >= min_y && image_y <= max_y)
            {
                shape->Select(true, &dc);
                GetView()->SelectShape(shape, true);
            }
        }
        node = node->GetNext();
    }
}
//*******************************************************************************
int CBCGPDiagramView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CView::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	m_pWndDiagramCtrl = CreateDiagram ();
	if (m_pWndDiagramCtrl == NULL)
	{
		TRACE0("CBCGPDiagramView::OnCreate: Diagram control is not created\n");
		return -1;
	}

	ASSERT_VALID (m_pWndDiagramCtrl);
	ASSERT (m_pWndDiagramCtrl->IsKindOf (RUNTIME_CLASS (CBCGPDiagramVisualContainerCtrl)));
	
	if (!m_pWndDiagramCtrl->Create (CBCGPRect(), this, ID_Diagram_CTRL))
	{
		TRACE0("CBCGPDiagramView::OnCreate: cannot create Diagram control\n");
		return -1;
	}

	CBCGPDiagramVisualContainer* pDiagram = GetDiagram();
	if (pDiagram != NULL)
	{
		pDiagram->EnableScrollBars();
	}

	return 0;
}
Beispiel #5
0
ExplainCanvas::ExplainCanvas(wxWindow *parent)
	: wxShapeCanvas(parent)
{
	SetDiagram(new wxDiagram);
	GetDiagram()->SetCanvas(this);
	SetBackgroundColour(*wxWHITE);
	popup = NULL;
}
Beispiel #6
0
void wxShapeCanvas::OnPaint(wxPaintEvent &WXUNUSED(event))
{
#if OGL_USE_BUFFERED_PAINT
	RecreateBuffer();
	wxBufferedPaintDC dc(this, m_bufferBitmap);
#else
	wxPaintDC dc(this);
#endif

	PrepareDC(dc);

	DrawBackground(dc, true);

	if (GetDiagram())
		GetDiagram()->Redraw(dc);

	// Necessary or it unscales again if there's a zoom level
	dc.SetUserScale(1.0, 1.0);
}
Beispiel #7
0
void wxShapeCanvas::OnMouseEvent(wxMouseEvent& event)
{
  wxClientDC dc(this);
  PrepareDC(dc);

  wxPoint logPos(event.GetLogicalPosition(dc));

  double x, y;
  x = (double) logPos.x;
  y = (double) logPos.y;

  int keys = 0;
  if (event.ShiftDown())
    keys = keys | KEY_SHIFT;
  if (event.ControlDown())
    keys = keys | KEY_CTRL;

  bool dragging = event.Dragging();

  // Check if we're within the tolerance for mouse movements.
  // If we're very close to the position we started dragging
  // from, this may not be an intentional drag at all.
  if (dragging)
  {
    int dx = abs(dc.LogicalToDeviceX((long) (x - m_firstDragX)));
    int dy = abs(dc.LogicalToDeviceY((long) (y - m_firstDragY)));
    if (m_checkTolerance && (dx <= GetDiagram()->GetMouseTolerance()) && (dy <= GetDiagram()->GetMouseTolerance()))
    {
      return;
    }
    else
      // If we've ignored the tolerance once, then ALWAYS ignore
      // tolerance in this drag, even if we come back within
      // the tolerance range.
      m_checkTolerance = false;
  }

  // Dragging - note that the effect of dragging is left entirely up
  // to the object, so no movement is done unless explicitly done by
  // object.
  if (dragging && m_draggedShape && m_dragState == StartDraggingLeft)
  {
    m_dragState = ContinueDraggingLeft;

    // If the object isn't m_draggable, transfer message to canvas
    if (m_draggedShape->Draggable())
      m_draggedShape->GetEventHandler()->OnBeginDragLeft((double)x, (double)y, keys, m_draggedAttachment);
    else
    {
      m_draggedShape = NULL;
      OnBeginDragLeft((double)x, (double)y, keys);
    }

    m_oldDragX = x; m_oldDragY = y;
  }
  else if (dragging && m_draggedShape && m_dragState == ContinueDraggingLeft)
  {
    // Continue dragging
    m_draggedShape->GetEventHandler()->OnDragLeft(false, m_oldDragX, m_oldDragY, keys, m_draggedAttachment);
    m_draggedShape->GetEventHandler()->OnDragLeft(true, (double)x, (double)y, keys, m_draggedAttachment);
    m_oldDragX = x; m_oldDragY = y;
  }
  else if (event.LeftUp() && m_draggedShape && m_dragState == ContinueDraggingLeft)
  {
    m_dragState = NoDragging;
    m_checkTolerance = true;

    m_draggedShape->GetEventHandler()->OnDragLeft(false, m_oldDragX, m_oldDragY, keys, m_draggedAttachment);

    m_draggedShape->GetEventHandler()->OnEndDragLeft((double)x, (double)y, keys, m_draggedAttachment);
    m_draggedShape = NULL;
  }
  else if (dragging && m_draggedShape && m_dragState == StartDraggingRight)
  {
    m_dragState = ContinueDraggingRight;

    if (m_draggedShape->Draggable())
      m_draggedShape->GetEventHandler()->OnBeginDragRight((double)x, (double)y, keys, m_draggedAttachment);
    else
    {
      m_draggedShape = NULL;
      OnBeginDragRight((double)x, (double)y, keys);
    }
    m_oldDragX = x; m_oldDragY = y;
  }
  else if (dragging && m_draggedShape && m_dragState == ContinueDraggingRight)
  {
    // Continue dragging
    m_draggedShape->GetEventHandler()->OnDragRight(false, m_oldDragX, m_oldDragY, keys, m_draggedAttachment);
    m_draggedShape->GetEventHandler()->OnDragRight(true, (double)x, (double)y, keys, m_draggedAttachment);
    m_oldDragX = x; m_oldDragY = y;
  }
  else if (event.RightUp() && m_draggedShape && m_dragState == ContinueDraggingRight)
  {
    m_dragState = NoDragging;
    m_checkTolerance = true;

    m_draggedShape->GetEventHandler()->OnDragRight(false, m_oldDragX, m_oldDragY, keys, m_draggedAttachment);

    m_draggedShape->GetEventHandler()->OnEndDragRight((double)x, (double)y, keys, m_draggedAttachment);
    m_draggedShape = NULL;
  }

  // All following events sent to canvas, not object
  else if (dragging && !m_draggedShape && m_dragState == StartDraggingLeft)
  {
    m_dragState = ContinueDraggingLeft;
    OnBeginDragLeft((double)x, (double)y, keys);
    m_oldDragX = x; m_oldDragY = y;
  }
  else if (dragging && !m_draggedShape && m_dragState == ContinueDraggingLeft)
  {
    // Continue dragging
    OnDragLeft(false, m_oldDragX, m_oldDragY, keys);
    OnDragLeft(true, (double)x, (double)y, keys);
    m_oldDragX = x; m_oldDragY = y;
  }
  else if (event.LeftUp() && !m_draggedShape && m_dragState == ContinueDraggingLeft)
  {
    m_dragState = NoDragging;
    m_checkTolerance = true;

    OnDragLeft(false, m_oldDragX, m_oldDragY, keys);
    OnEndDragLeft((double)x, (double)y, keys);
    m_draggedShape = NULL;
  }
  else if (dragging && !m_draggedShape && m_dragState == StartDraggingRight)
  {
    m_dragState = ContinueDraggingRight;
    OnBeginDragRight((double)x, (double)y, keys);
    m_oldDragX = x; m_oldDragY = y;
  }
  else if (dragging && !m_draggedShape && m_dragState == ContinueDraggingRight)
  {
    // Continue dragging
    OnDragRight(false, m_oldDragX, m_oldDragY, keys);
    OnDragRight(true, (double)x, (double)y, keys);
    m_oldDragX = x; m_oldDragY = y;
  }
  else if (event.RightUp() && !m_draggedShape && m_dragState == ContinueDraggingRight)
  {
    m_dragState = NoDragging;
    m_checkTolerance = true;

    OnDragRight(false, m_oldDragX, m_oldDragY, keys);
    OnEndDragRight((double)x, (double)y, keys);
    m_draggedShape = NULL;
  }

  // Non-dragging events
  else if (event.IsButton())
  {
    m_checkTolerance = true;

    // Find the nearest object
    int attachment = 0;
    wxShape *nearest_object = FindShape(x, y, &attachment);
    if (nearest_object) // Object event
    {
      if (event.LeftDown())
      {
        m_draggedShape = nearest_object;
        m_draggedAttachment = attachment;
        m_dragState = StartDraggingLeft;
        m_firstDragX = x;
        m_firstDragY = y;
      }
      else if (event.LeftUp())
      {
        // N.B. Only register a click if the same object was
        // identified for down *and* up.
        if (nearest_object == m_draggedShape)
          nearest_object->GetEventHandler()->OnLeftClick((double)x, (double)y, keys, attachment);

        m_draggedShape = NULL;
        m_dragState = NoDragging;
      }
      else if (event.LeftDClick())
      {
        nearest_object->GetEventHandler()->OnLeftDoubleClick((double)x, (double)y, keys, attachment);

        m_draggedShape = NULL;
        m_dragState = NoDragging;
      }
      else if (event.RightDown())
      {
        m_draggedShape = nearest_object;
        m_draggedAttachment = attachment;
        m_dragState = StartDraggingRight;
        m_firstDragX = x;
        m_firstDragY = y;
      }
      else if (event.RightUp())
      {
        if (nearest_object == m_draggedShape)
          nearest_object->GetEventHandler()->OnRightClick((double)x, (double)y, keys, attachment);

        m_draggedShape = NULL;
        m_dragState = NoDragging;
      }
    }
    else // Canvas event (no nearest object)
    {
      if (event.LeftDown())
      {
        m_draggedShape = NULL;
        m_dragState = StartDraggingLeft;
        m_firstDragX = x;
        m_firstDragY = y;
      }
      else if (event.LeftUp())
      {
        OnLeftClick((double)x, (double)y, keys);

        m_draggedShape = NULL;
        m_dragState = NoDragging;
      }
      else if (event.RightDown())
      {
        m_draggedShape = NULL;
        m_dragState = StartDraggingRight;
        m_firstDragX = x;
        m_firstDragY = y;
      }
      else if (event.RightUp())
      {
        OnRightClick((double)x, (double)y, keys);

        m_draggedShape = NULL;
        m_dragState = NoDragging;
      }
    }
  }
}
Beispiel #8
0
void wxShapeCanvas::Snap(double *x, double *y)
 { GetDiagram()->Snap(x, y); }
Beispiel #9
0
void wxShapeCanvas::Redraw(wxDC& dc)
 { GetDiagram()->Redraw(dc); }
Beispiel #10
0
bool wxShapeCanvas::GetQuickEditMode()
 { return GetDiagram()->GetQuickEditMode(); }
Beispiel #11
0
void wxShapeCanvas::RemoveShape(wxShape *object)
 { GetDiagram()->RemoveShape(object); }
Beispiel #12
0
void wxShapeCanvas::InsertShape(wxShape *object)
 { GetDiagram()->InsertShape(object); }
Beispiel #13
0
void wxShapeCanvas::AddShape(wxShape *object, wxShape *addAfter)
 { GetDiagram()->AddShape(object, addAfter); }
Beispiel #14
0
wxShape *wxShapeCanvas::FindShape(double x, double y, int *attachment, wxClassInfo *info, wxShape *notObject, wxClassInfo *notinfo)
//wxShape *wxShapeCanvas::FindShape(double x, double y, int *attachment, wxClassInfo *info, wxShape *notObject)
{
  double nearest = 100000.0;
  int nearest_attachment = 0;
  wxShape *nearest_object = NULL;

  // Go backward through the object list, since we want:
  // (a) to have the control points drawn LAST to overlay
  //     the other objects
  // (b) to find the control points FIRST if they exist

  wxObjectList::compatibility_iterator current = GetDiagram()->GetShapeList()->GetLast();
  while (current)
  {
    wxShape *object = (wxShape *)current->GetData();

    double dist;
    int temp_attachment;

    // First pass for lines, which might be inside a container, so we
    // want lines to take priority over containers. This first loop
    // could fail if we clickout side a line, so then we'll
    // try other shapes.
    if (object->IsShown() &&
        object->IsKindOf(CLASSINFO(wxLineShape)) &&
        object->HitTest(x, y, &temp_attachment, &dist) &&
        ((info == NULL) || object->IsKindOf(info)) &&
		((notinfo == NULL) || !object->IsKindOf(notinfo)) &&
        (!notObject || !notObject->HasDescendant(object)))
    {
      // A line is trickier to spot than a normal object.
      // For a line, since it's the diagonal of the box
      // we use for the hit test, we may have several
      // lines in the box and therefore we need to be able
      // to specify the nearest point to the centre of the line
      // as our hit criterion, to give the user some room for
      // manouevre.
      if (dist < nearest)
      {
        nearest = dist;
        nearest_object = object;
        nearest_attachment = temp_attachment;
      }
    }
    if (current)
      current = current->GetPrevious();
  }

  current = GetDiagram()->GetShapeList()->GetLast();
  while (current)
  {
    wxShape *object = (wxShape *)current->GetData();
    double dist;
    int temp_attachment;

    // On second pass, only ever consider non-composites or divisions. If children want to pass
    // up control to the composite, that's up to them.
    if (object->IsShown() && (object->IsKindOf(CLASSINFO(wxDivisionShape)) || !object->IsKindOf(CLASSINFO(wxCompositeShape)))
        && object->HitTest(x, y, &temp_attachment, &dist) && ((info == NULL) || object->IsKindOf(info)) &&
        (!notObject || !notObject->HasDescendant(object)))
    {
      if (!object->IsKindOf(CLASSINFO(wxLineShape)))
      {
        // If we've hit a container, and we have already found a line in the
        // first pass, then ignore the container in case the line is in the container.
        // Check for division in case line straddles divisions (i.e. is not wholly contained).
        if (!nearest_object || !(object->IsKindOf(CLASSINFO(wxDivisionShape)) || WhollyContains(object, nearest_object)))
        {
          nearest_object = object;
          nearest_attachment = temp_attachment;
          current = GetDiagram()->GetShapeList()->GetFirst()->GetPrevious(); // finish loop
        }
      }
    }
    if (current)
      current = current->GetPrevious();
  }

  *attachment = nearest_attachment;
  return nearest_object;
}
Beispiel #15
0
void ExplainCanvas::SetExplainString(const wxString &str)
{
	Clear();

	ExplainShape *last = 0;
	int maxLevel = 0;

	wxStringTokenizer lines(str, wxT("\n"));

	while (lines.HasMoreTokens())
	{
		wxString tmp = lines.GetNextToken();
		wxString line = tmp.Strip(wxString::both);

		int braceCount = 0;
		do
		{
			const wxChar *cp = line.c_str();
			while (*cp)
			{
				if (*cp == '(')
					braceCount++;
				else if (*cp == ')')
					braceCount--;
				cp++;
			}
			if (braceCount > 0)
			{
				wxString tmp = lines.GetNextToken();
				line += wxT(" ") + tmp.Strip(wxString::both);
				braceCount = 0;
			}
			else
				break;
		}
		while (lines.HasMoreTokens());

		long level = (tmp.Length() - line.Length() + 4) / 6;

		if (last)
		{
			if (level)
			{
				if (line.Left(4) == wxT("->  "))
					line = line.Mid(4);
				else
				{
					last->SetCondition(line);
					continue;
				}
			}

			while (last && level <= last->GetLevel())
				last = last->GetUpper();
		}


		ExplainShape *s = ExplainShape::Create(level, last, line);
		if (!s)
			continue;
		s->SetCanvas(this);
		InsertShape(s);
		s->Show(true);

		if (level > maxLevel)
			maxLevel = level;

		if (!last)
			rootShape = s;
		last = s;
	}


	int x0 = (int)(rootShape->GetWidth() * 3);
	int y0 = (int)(rootShape->GetHeight() * 3 / 2);
	int xoffs = (int)(rootShape->GetWidth() * 3);
	int yoffs = (int)(rootShape->GetHeight() * 5 / 4);

	wxNode *current = GetDiagram()->GetShapeList()->GetFirst();
	while (current)
	{
		ExplainShape *s = (ExplainShape *)current->GetData();

		if (!s->totalShapes)
			s->totalShapes = 1;
		if (s->GetUpper())
			s->GetUpper()->totalShapes += s->totalShapes;
		current = current->GetNext();
	}

	current = GetDiagram()->GetShapeList()->GetLast();
	while (current)
	{
		ExplainShape *s = (ExplainShape *)current->GetData();

		s->SetX(y0 + (maxLevel - s->GetLevel()) * xoffs);
		ExplainShape *upper = s->GetUpper();

		if (upper)
		{
			s->SetY(upper->GetY() + upper->usedShapes * yoffs);
			upper->usedShapes += s->totalShapes;

			wxLineShape *l = new ExplainLine(s, upper);
			l->Show(true);
			AddShape(l);
		}
		else
		{
			s->SetY(y0);
		}

		current = current->GetPrevious();
	}

#define PIXPERUNIT  20
	int w = (maxLevel * xoffs + x0 * 2 + PIXPERUNIT - 1) / PIXPERUNIT;
	int h = (rootShape->totalShapes * yoffs + y0 * 2 + PIXPERUNIT - 1) / PIXPERUNIT;

	SetScrollbars(PIXPERUNIT, PIXPERUNIT, w, h);
}
Beispiel #16
0
void ExplainCanvas::Clear()
{
	GetDiagram()->DeleteAllShapes();
}