📄 ogldiag.cpp
字号:
/////////////////////////////////////////////////////////////////////////////
// Name: ogldiag.cpp
// Purpose: wxDiagram
// Author: Julian Smart
// Modified by:
// Created: 12/07/98
// RCS-ID: $Id: ogldiag.cpp,v 1.18 2005/10/06 18:17:22 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
#ifdef new
#undef new
#endif
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
#include "wx/ogl/ogl.h"
IMPLEMENT_DYNAMIC_CLASS(wxDiagram, wxObject)
// Object canvas
wxDiagram::wxDiagram()
{
m_diagramCanvas = NULL;
m_quickEditMode = false;
m_snapToGrid = true;
m_gridSpacing = 5.0;
m_shapeList = new wxList;
m_mouseTolerance = DEFAULT_MOUSE_TOLERANCE;
}
wxDiagram::~wxDiagram()
{
if (m_shapeList)
delete m_shapeList;
}
void wxDiagram::SetSnapToGrid(bool snap)
{
m_snapToGrid = snap;
}
void wxDiagram::SetGridSpacing(double spacing)
{
m_gridSpacing = spacing;
}
void wxDiagram::Snap(double *x, double *y)
{
if (m_snapToGrid)
{
*x = m_gridSpacing * ((int)(*x/m_gridSpacing + 0.5));
*y = m_gridSpacing * ((int)(*y/m_gridSpacing + 0.5));
}
}
void wxDiagram::Redraw(wxDC& dc)
{
if (m_shapeList)
{
if (GetCanvas())
GetCanvas()->SetCursor(* wxHOURGLASS_CURSOR);
wxNode *current = m_shapeList->GetFirst();
while (current)
{
wxShape *object = (wxShape *)current->GetData();
if (!object->GetParent())
object->Draw(dc);
current = current->GetNext();
}
if (GetCanvas())
GetCanvas()->SetCursor(* wxSTANDARD_CURSOR);
}
}
void wxDiagram::Clear(wxDC& dc)
{
dc.Clear();
}
// Insert object after addAfter, or at end of list.
void wxDiagram::AddShape(wxShape *object, wxShape *addAfter)
{
wxNode *nodeAfter = NULL;
if (addAfter)
nodeAfter = m_shapeList->Member(addAfter);
if (!m_shapeList->Member(object))
{
if (nodeAfter)
{
if (nodeAfter->GetNext())
m_shapeList->Insert(nodeAfter->GetNext(), object);
else
m_shapeList->Append(object);
}
else
m_shapeList->Append(object);
object->SetCanvas(GetCanvas());
}
}
void wxDiagram::InsertShape(wxShape *object)
{
m_shapeList->Insert(object);
object->SetCanvas(GetCanvas());
}
void wxDiagram::RemoveShape(wxShape *object)
{
m_shapeList->DeleteObject(object);
}
// Should this delete the actual objects too? I think not.
void wxDiagram::RemoveAllShapes()
{
m_shapeList->Clear();
}
void wxDiagram::DeleteAllShapes()
{
wxNode *node = m_shapeList->GetFirst();
while (node)
{
wxShape *shape = (wxShape *)node->GetData();
if (!shape->GetParent())
{
RemoveShape(shape);
delete shape;
node = m_shapeList->GetFirst();
}
else
node = node->GetNext();
}
}
void wxDiagram::ShowAll(bool show)
{
wxNode *current = m_shapeList->GetFirst();
while (current)
{
wxShape *object = (wxShape *)current->GetData();
object->Show(show);
current = current->GetNext();
}
}
void wxDiagram::DrawOutline(wxDC& dc, double x1, double y1, double x2, double y2)
{
wxPen dottedPen(*wxBLACK, 1, wxDOT);
dc.SetPen(dottedPen);
dc.SetBrush((* wxTRANSPARENT_BRUSH));
wxPoint points[5];
points[0].x = (int) x1;
points[0].y = (int) y1;
points[1].x = (int) x2;
points[1].y = (int) y1;
points[2].x = (int) x2;
points[2].y = (int) y2;
points[3].x = (int) x1;
points[3].y = (int) y2;
points[4].x = (int) x1;
points[4].y = (int) y1;
dc.DrawLines(5, points);
}
// Make sure all text that should be centred, is centred.
void wxDiagram::RecentreAll(wxDC& dc)
{
wxNode *object_node = m_shapeList->GetFirst();
while (object_node)
{
wxShape *obj = (wxShape *)object_node->GetData();
obj->Recentre(dc);
object_node = object_node->GetNext();
}
}
// Input/output
#if wxUSE_PROLOGIO
bool wxDiagram::SaveFile(const wxString& filename)
{
wxBeginBusyCursor();
wxExprDatabase *database = new wxExprDatabase;
// First write the diagram type
wxExpr *header = new wxExpr(_T("diagram"));
OnHeaderSave(*database, *header);
database->Append(header);
wxNode *node = m_shapeList->GetFirst();
while (node)
{
wxShape *shape = (wxShape *)node->GetData();
if (!shape->IsKindOf(CLASSINFO(wxControlPoint)))
{
wxExpr *expr;
if (shape->IsKindOf(CLASSINFO(wxLineShape)))
expr = new wxExpr(_T("line"));
else
expr = new wxExpr(_T("shape"));
OnShapeSave(*database, *shape, *expr);
}
node = node->GetNext();
}
OnDatabaseSave(*database);
wxString tempFile;
wxGetTempFileName(wxT("diag"), tempFile);
FILE* file = fopen(tempFile.mb_str(wxConvFile), "w");
if (! file)
{
wxEndBusyCursor();
delete database;
return false;
}
database->Write(file);
fclose(file);
delete database;
/*
// Save backup
if (FileExists(filename))
{
char buf[400];
#ifdef __X__
sprintf(buf, "%s.bak", filename);
#endif
#ifdef __WXMSW__
sprintf(buf, "_diagram.bak");
#endif
if (FileExists(buf)) wxRemoveFile(buf);
if (!wxRenameFile(filename, buf))
{
wxCopyFile(filename, buf);
wxRemoveFile(filename);
}
}
*/
// Copy the temporary file to the correct filename
if (!wxRenameFile(tempFile, filename))
{
wxCopyFile(tempFile, filename);
wxRemoveFile(tempFile);
}
wxEndBusyCursor();
return true;
}
bool wxDiagram::LoadFile(const wxString& filename)
{
wxBeginBusyCursor();
wxExprDatabase database(wxExprInteger, _T("id"));
if (!database.Read(filename))
{
wxEndBusyCursor();
return false;
}
DeleteAllShapes();
database.BeginFind();
wxExpr *header = database.FindClauseByFunctor(_T("diagram"));
if (header)
OnHeaderLoad(database, *header);
// Scan through all clauses and register the ids
wxNode *node = database.GetFirst();
while (node)
{
wxExpr *clause = (wxExpr *)node->GetData();
long id = -1;
clause->GetAttributeValue(_T("id"), id);
wxRegisterId(id);
node = node->GetNext();
}
ReadNodes(database);
ReadContainerGeometry(database);
ReadLines(database);
OnDatabaseLoad(database);
wxEndBusyCursor();
return true;
}
void wxDiagram::ReadNodes(wxExprDatabase& database)
{
// Find and create the node images
database.BeginFind();
wxExpr *clause = database.FindClauseByFunctor(_T("shape"));
while (clause)
{
wxChar *type = NULL;
long parentId = -1;
clause->AssignAttributeValue(wxT("type"), &type);
clause->AssignAttributeValue(wxT("parent"), &parentId);
wxClassInfo *classInfo = wxClassInfo::FindClass(type);
if (classInfo)
{
wxShape *shape = (wxShape *)classInfo->CreateObject();
OnShapeLoad(database, *shape, *clause);
shape->SetCanvas(GetCanvas());
shape->Show(true);
m_shapeList->Append(shape);
// If child of composite, link up
if (parentId > -1)
{
wxExpr *parentExpr = database.HashFind(_T("shape"), parentId);
if (parentExpr && parentExpr->GetClientData())
{
wxShape *parent = (wxShape *)parentExpr->GetClientData();
shape->SetParent(parent);
parent->GetChildren().Append(shape);
}
}
clause->SetClientData(shape);
}
if (type)
delete[] type;
clause = database.FindClauseByFunctor(_T("shape"));
}
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -