Added revamped Object Graphics Library (for node/arc diagrams).

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@305 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Julian Smart
1998-07-18 21:57:52 +00:00
parent 0f7549d594
commit 0fc1a7137c
53 changed files with 21082 additions and 0 deletions

41
utils/ogl/distrib/ogl.rsp Normal file
View File

@@ -0,0 +1,41 @@
src/*.cpp
src/*.c
src/*.h
src/*.rc
src/*.def
src/*.xbm
src/make*.*
src/*.txt
src/*.ico
src/*.bmp
samples/ogledit/*.cpp
samples/ogledit/*.c
samples/ogledit/*.h
samples/ogledit/*.rc
samples/ogledit/*.def
samples/ogledit/*.xbm
samples/ogledit/make*.*
samples/ogledit/*.txt
samples/ogledit/*.ico
samples/ogledit/*.bmp
samples/ogledit/bitmaps/*.bmp
samples/ogledit/bitmaps/*.gif
samples/ogledit/bitmaps/*.xbm
lib/dummy
distrib/*.rsp
distrib/*.bat
docs/*.txt
docs/*.tex
docs/*.ini
docs/*.hpj
docs/*.ps
docs/*.eps
docs/*.cnt
docs/*.bmp
docs/*.gif
docs/*.hlp

48
utils/ogl/distrib/tarogl.bat Executable file
View File

@@ -0,0 +1,48 @@
@echo off
rem Tar up an external distribution of OGL
if "%1" == "" goto usage
if "%2" == "" goto usage
echo About to archive an external OGL distribution:
echo From %1
echo To %2\ogl.tgz
echo CTRL-C if this is not correct.
inkey /W4 `Press any key to continue...` %%input
erase %2\ogl.tgz
cd %1
rem First, expand the wildcards in the ogl.rsp file
rem Create empty list file
erase %1\distrib\ogl.lis
c:\bin\touch %1\distrib\ogl.lis
rem Create a .rsp file with backslashes instead
rem of forward slashes
rem No need if using ls2 (from UNIX95 distribution)
rem sed -e "s/\//\\/g" %1\distrib\ogl.rsp > %1\distrib\ogl.rs2
set len=%@LINES[%1\distrib\ogl.rsp]
rem set len=%@DEC[%len]
do i = 0 to %len by 1
set line=%@LINE[%1\distrib\ogl.rsp,%i]
if NOT "%line" == "" ls2 -1 %line >> %1\distrib\ogl.lis
enddo
tar -c -T %1\distrib\ogl.lis
move archive.tar ogl.tar
gzip ogl.tar
move ogl.taz %2\ogl.tgz
echo OGL archived.
goto end
:usage
echo DOS OGL distribution.
echo Usage: tarogl source destination
echo e.g. tarogl c:\wx\utils\ogl c:\wx\utils\ogl\deliver
:end

26
utils/ogl/distrib/zipogl.bat Executable file
View File

@@ -0,0 +1,26 @@
@echo off
rem Zip up an external distribution of OGL
if "%1" == "" goto usage
if "%2" == "" goto usage
echo About to archive an external OGL distribution:
echo From %1
echo To %2\ogl.zip
echo CTRL-C if this is not correct.
inkey /W4 `Press any key to continue...` %%input
erase %2\ogl.zip
cd %1
zip -P %3 %4 %5 %6 %7 %8 %2\ogl.zip @%1\distrib\ogl.rsp
echo OGL archived.
goto end
:usage
echo DOS OGL distribution.
echo Usage: zipogl source destination
echo e.g. zipogl c:\wx\utils\ogl c:\wx\utils\ogl\deliver
:end

BIN
utils/ogl/docs/back.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 B

BIN
utils/ogl/docs/books.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

11
utils/ogl/docs/bugs.tex Normal file
View File

@@ -0,0 +1,11 @@
\chapter{Bugs}\label{bugs}%
\setheader{{\it CHAPTER \thechapter}}{}{}{}{}{{\it CHAPTER \thechapter}}%
\setfooter{\thepage}{}{}{}{}{\thepage}
These are the known bugs.
\begin{itemize}\itemsep=0pt
\item In the OGLEdit sample, .dia files are output double-spaced
due to an unidentified bug in the way a stream is converted to a file.
\end{itemize}

BIN
utils/ogl/docs/bullet.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 B

View File

@@ -0,0 +1,9 @@
\chapter{Change log}
\setheader{{\it CHAPTER \thechapter}}{}{}{}{}{{\it CHAPTER \thechapter}}%
\setfooter{\thepage}{}{}{}{}{\thepage}
Version 2.0, June 1st 1996
\begin{itemize}\itemsep=0pt
\item First publically released version.
\end{itemize}

2505
utils/ogl/docs/classes.tex Normal file

File diff suppressed because it is too large Load Diff

BIN
utils/ogl/docs/contents.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 231 B

BIN
utils/ogl/docs/forward.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 B

45
utils/ogl/docs/intro.tex Normal file
View File

@@ -0,0 +1,45 @@
\chapter{Introduction}
\pagenumbering{arabic}%
\setheader{{\it CHAPTER \thechapter}}{}{}{}{}{{\it CHAPTER \thechapter}}%
\setfooter{\thepage}{}{}{}{}{\thepage}
Object Graphics Library (\ogl) is a C++ library supporting the creation and
manipulation of simple and complex graphic images on a canvas.
It can be found in the directory {\tt utils/ogl/src} in the
wxWindows distribution. The file {\tt ogl.h} must be included to make use
of the library.
Please see \helpref{OGL overview}{ogloverview} for a general description how the object library works. For details,
please see the \helpref{class reference}{classref}.
\section{File structure}
These are the files that comprise the \ogl\ library.
\begin{description}\itemsep=0pt
\item[basic.h] Header for basic objects such as wxShape and wxRectangleShape.
\item[basic.cpp] Basic objects implementation (1).
\item[basic2.cpp] Basic objects implementation (2).
\item[bitmap.cpp] wxBitmapShape class header.
\item[bitmap.cpp] wxBitmapShape implementation.
\item[canvas.h] wxShapeCanvas class header.
\item[canvas.cpp] wxShapeCanvas class implementation.
\item[composit.h] Composite object class header.
\item[composit.cpp] Composite object class implementation.
\item[constrnt.h] Constraint classes header.
\item[constrnt.cpp] Constraint classes implementation.
\item[divided.h] Divided object class header.
\item[divided.cpp] Divided object class implementation.
\item[drawn.h] Drawn (metafile) object class header.
\item[drawn.cpp] Drawn (metafile) object class implementation.
\item[graphics.h] Main include file.
\item[lines.h] wxLineShape class header.
\item[lines.cpp] wxLineShape class implementation.
\item[misc.h] Miscellaneous graphics functions header.
\item[misc.cpp] Miscellaneous graphics functions implementation.
\item[ogldiag.h] wxDiagram class header.
\item[ogldiag.cpp] wxDiagram implementation.
\end{description}

17
utils/ogl/docs/ogl.hpj Normal file
View File

@@ -0,0 +1,17 @@
[OPTIONS]
BMROOT=d:\wx2\wxwind~1\utils\ogl\docs ; Assume that bitmaps are where the source is
TITLE=OGL Manual
CONTENTS=Contents
COMPRESS=HIGH
[FILES]
ogl.rtf
[CONFIG]
CreateButton("Up", "&Up", "JumpId(`ogl.hlp', `Contents')")
BrowseButtons()
[MAP]
[BITMAPS]

38
utils/ogl/docs/ogl.tex Normal file
View File

@@ -0,0 +1,38 @@
\documentstyle[a4,makeidx,verbatim,texhelp,fancyhea,mysober,mytitle]{report}
\newcommand{\ogl}[0]{{OGL}}
\input psbox.tex
\parindent 0pt
\parskip 11pt
\title{Manual for Object Graphics Library 3.0}
\author{Julian Smart}
\date{July 1998}
\makeindex
\begin{document}
\maketitle
\pagestyle{fancyplain}
\bibliographystyle{plain}
\pagenumbering{roman}
\setheader{{\it CONTENTS}}{}{}{}{}{{\it CONTENTS}}
\setfooter{\thepage}{}{}{}{}{\thepage}
\tableofcontents%
\input{intro.tex}
%
\input{sample.tex}
%
\input{classes.tex}
%
\input{topics.tex}
%
\input{bugs.tex}
%
\input{changes.tex}
%
\addcontentsline{toc}{chapter}{Index}
\setheader{{\it INDEX}}{}{}{}{}{{\it INDEX}}
\setfooter{\thepage}{}{}{}{}{\thepage}%
\printindex
\end{document}

BIN
utils/ogl/docs/ogledit.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

BIN
utils/ogl/docs/ogledit.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

128
utils/ogl/docs/sample.tex Normal file
View File

@@ -0,0 +1,128 @@
\chapter{OGLEdit: a sample OGL application}\label{ogledit}%
\setheader{{\it CHAPTER \thechapter}}{}{}{}{}{{\it CHAPTER \thechapter}}%
\setfooter{\thepage}{}{}{}{}{\thepage}
OGLEdit is a sample OGL application that allows the user to draw, edit,
save and load a few shapes. It should clarify aspects of OGL usage, and
can act as a template for similar applications. OGLEdit can be found in\rtfsp
{\tt samples/ogledit} in the OGL distribution.
$$\image{10cm;0cm}{ogledit.eps}$$\par
The wxWindows document/view model has been used in OGL, to reduce the amount of
housekeeping logic required to get it up and running. OGLEdit also provides
a demonstration of the Undo/Redo capability supported by the document/view classes,
and how a typical application might implement this feature.
{\it Note:} A bug in the wxWindows document/view implementation before
version 1.66C may cause Do/Undo to misbehave and get out of sync. If this is the case,
please replace wxCommandProcessor::Submit with the following in wx\_doc.cpp.
{\small
\begin{verbatim}
Bool wxCommandProcessor::Submit(wxCommand *command, Bool storeIt)
{
Bool success = command->Do();
if (success && storeIt)
{
if (commands.Number() == maxNoCommands)
{
wxNode *firstNode = commands.First();
wxCommand *firstCommand = (wxCommand *)firstNode->Data();
delete firstCommand;
delete firstNode;
}
// Correct a bug: we must chop off the current 'branch'
// so that we're at the end of the command list.
if (currentCommand)
{
wxNode *node = currentCommand->Next();
while (node)
{
wxNode *next = node->Next();
delete node;
node = next;
}
}
commands.Append(command);
currentCommand = commands.Last();
SetMenuStrings();
}
return success;
}
\end{verbatim}
}
\section{OGLEdit files}
OGLEdit comprises the following source files.
\begin{itemize}\itemsep=0pt
\item doc.h, doc.cpp: MyDiagram, DiagramDocument, DiagramCommand, MyEvtHandler
classes related to diagram functionality and documents.
\item view.h, view.cpp: MyCanvas, DiagramView classes related to visualisation of
the diagram.
\item ogledit.h, ogledit.cpp: MyFrame, MyApp classes related to the overall application.
\item palette.h, palette.cpp: EditorToolPalette implementing the shape palette.
\end{itemize}
\section{How OGLEdit works}
OGLEdit defines a DiagramDocument class, each of instance of which holds a MyDiagram
member which itself contains the shapes.
In order to implement specific mouse behaviour for shapes, a class MyEvtHandler is
defined which is `plugged into' each shape when it is created, instead of overriding each shape class
individually. This event handler class also holds a label string.
The DiagramCommand class is the key to implementing Undo/Redo. Each instance of DiagramCommand
stores enough information about an operation (create, delete, change colour etc.) to allow
it to carry out (or undo) its command. In DiagramView::OnMenuCommand, when the user initiates the
command, a new DiagramCommand instance is created which is then sent to the document's
command processor (see wxWindows manual for more information about doc/view and command
processing).
Apart from menu commands, another way commands are initiated is by the user left-clicking on
the canvas or right-dragging on a node. MyCanvas::OnLeftClick in view.cpp shows how
the appropriate wxClassInfo is passed to a DiagramCommand, to allow DiagramCommand::Do
to create a new shape given the wxClassInfo.
The MyEvtHandler right-drag methods in doc.cpp implement drawing a line between
two shapes, detecting where the right mouse button was released and looking for a second
shape. Again, a new DiagramCommand instance is created and passed to the command
processor to carry out the command.
DiagramCommand::Do and DiagramCommand::Undo embody much of the
interesting interaction with the OGL library. A complication of note
when implementing undo is the problem of deleting a node shape which has
one or more arcs attached to it. If you delete the node, the arc(s)
should be deleted too. But multiple arc deletion represents more information
that can be incorporated in the existing DiagramCommand scheme. OGLEdit
copes with this by treating each arc deletion as a separate command, and
sending Cut commands recursively, providing an undo path. Undoing such a
Cut will only undo one command at a time - not a one to one
correspondence with the original command - but it's a reasonable
compromise and preserves Do/Undo whilst keeping our DiagramCommand class
simple.
\section{Possible enhancements}
OGLEdit is very simplistic and does not employ the more advanced features
of OGL, such as:
\begin{itemize}\itemsep=0pt
\item attachment points (arcs are drawn to particular points on a shape)
\item metafile and bitmaps shapes
\item divided rectangles
\item composite shapes, and constraints
\item creating labels in shape regions
\item arc labels (OGL has support for three movable labels per arc)
\item spline and multiple-segment line arcs
\item adding annotations to node and arc shapes
\item line-straightening (supported by OGL) and alignment (not supported directly by OGL)
\end{itemize}
These could be added to OGLEdit, at the risk of making it a less
useful example for beginners.

View File

@@ -0,0 +1,20 @@
runTwice = yes
titleFontSize = 12
authorFontSize = 10
chapterFontSize = 12
sectionFontSize = 12
subsectionFontSize = 12
headerRule = yes
footerRule = yes
useHeadingStyles = yes
listItemIndent=40
generateHPJ = no
htmlBrowseButtons = bitmap
winHelpVersion = 3
winHelpContents = yes
winHelpTitle = "OGL Manual"
truncateFilenames = yes
combineSubSections = yes
\overview [2] {\rtfonly{See also }\sethotspotcolour{off}\sethotspotunderline{on}\winhelponly{\image{}{books.bmp}}
\htmlonly{\image{}{books.gif}}\helpref{#1}{#2}
\sethotspotcolour{on}\sethotspotunderline{on}}

163
utils/ogl/docs/topics.tex Normal file
View File

@@ -0,0 +1,163 @@
\chapter{Topic overviews}
\setheader{{\it CHAPTER \thechapter}}{}{}{}{}{{\it CHAPTER \thechapter}}%
\setfooter{\thepage}{}{}{}{}{\thepage}
The following sections describe particular topics.
\section{OGL overview}\label{ogloverview}
\helpref{wxShapeCanvas}{wxshapecanvas}, derived from {\bf wxCanvas}, is the drawing area
for a number of \helpref{wxShape}{wxshape} instances. Everything drawn on a
wxShapeCanvas is derived from wxShape, which provides virtual
member functions for redrawing, creating and destroying
resize/selection `handles', movement and erasing behaviour, mouse
click behaviour, calculating the bounding box of the shape, linking
nodes with arcs, and so on.
The way a client application copes with `damage' to the canvas is to
erase (white out) anything should no longer be displayed, redraw the shape,
and then redraw everything on the canvas to repair any damage. If quick edit
mode is on for the canvas, the complete should be omitted by OGL and the
application.
Selection handles (called control points in the code) are implemented as
wxRectangleShapes.
Events are passed to shapes by the canvas in a high-level form, for example {\bf OnLeftClick},
{\bf OnBeginDragLeft}, {\bf OnDragLeft}, {\bf OnEndDragLeft}. The canvas decides
what is a click and what is a drag, whether it is on a shape or the canvas itself,
and (by interrogating the shape) which attachment point the click is associated with.
In order to provide event-handling flexibility, each shapes has an `event handler' associated with it,
which by default is the shape itself (all shapes derive from wxShapeEvtHandler).
An application can modify the event-handling behaviour simply by plugging a new
event handler into the shape. This can avoid the need for multiple inheritance when
new properties and behaviour are required for a number of different shape classes: instead
of overriding each class, one new event handler class can be defined and used for all
existing shape classes.
A range of shapes have been predefined in the library, including rectangles, ellipses,
polygons. A client application can derive from these shapes and/or derive entirely
new shapes from wxShape.
Instances of a class called \helpref{wxDiagram}{wxdiagram} organise collections of
shapes, providing default file input and output behaviour.
\section{wxDividedShape overview}\label{dividedshapeoverview}
Classes: \helpref{wxDividedShape}{wxdividedshape}
A wxDividedShape is a rectangle with a number of vertical divisions. Each
division may have its text formatted with independent characteristics, and
the size of each division relative to the whole image may be specified.
Once a wxDividedShape has been created, the user may move the divisions with the
mouse. By pressing Ctrl while right-clicking, the region attributes can be edited.
Here are examples of creating wxDividedShape objects:
{\small
\begin{verbatim}
/*
* Divided rectangle with 3 regions
*
*/
wxDividedShape *dividedRect = new wxDividedShape(50, 60);
wxShapeRegion *region = new wxShapeRegion;
region->SetProportions(0.0, 0.25);
dividedRect->AddRegion(region);
region = new wxShapeRegion;
region->SetProportions(0.0, 0.5);
dividedRect->AddRegion(region);
region = new wxShapeRegion;
region->SetProportions(0.0, 0.25);
dividedRect->AddRegion(region);
dividedRect->SetSize(50, 60); // Allow it to calculate region sizes
dividedRect->SetPen(wxBLACK_PEN);
dividedRect->SetBrush(wxWHITE_BRUSH);
dividedRect->Show(TRUE);
dividedRect->NameRegions();
/*
* Divided rectangle with 3 regions, rounded
*
*/
wxDividedShape *dividedRect3 = new wxDividedShape(50, 60);
dividedRect3->SetCornerRadius(-0.4);
region = new wxShapeRegion;
region->SetProportions(0.0, 0.25);
dividedRect3->AddRegion(region);
region = new wxShapeRegion;
region->SetProportions(0.0, 0.5);
dividedRect3->AddRegion(region);
region = new wxShapeRegion;
region->SetProportions(0.0, 0.25);
dividedRect3->AddRegion(region);
dividedRect3->SetSize(50, 60); // Allow it to calculate region sizes
dividedRect3->SetPen(wxBLACK_PEN);
dividedRect3->SetBrush(wxWHITE_BRUSH);
dividedRect3->Show(TRUE);
dividedRect3->NameRegions();
\end{verbatim}
}
\section{wxCompositeShape overview}\label{compositeshapeoverview}
Classes: \helpref{wxCompositeShape}{wxcompositeshape}, \helpref{OGLConstraint}{oglconstraint}
The wxCompositeShape allows fairly complex shapes to be created, and maintains
a set of constraints which specify the layout and proportions of child shapes.
Add child shapes to a wxCompositeShape using \helpref{AddChild}{wxcompositeshapeaddchild}, and
add constraints using \helpref{AddConstraint}{wxcompositeshapeaddconstraint}.
After children and shapes have been added, call \helpref{Recompute}{wxcompositeshaperecompute} which
will return TRUE is the constraints could be satisfied, FALSE otherwise. If
constraints have been correctly and consistently specified, this call will succeed.
If there is more than one child, constraints must be specified: OGL cannot calculate
the size and position of children otherwise. Don't assume that children will simply
move relative to the parent without the use of constraints.
To specify a constraint, you need three things:
\begin{enumerate}\itemsep=0pt
\item a constraint type, such as gyCONSTRAINT\_CENTRED\_VERTICALLY;
\item a reference shape, with respect to which other shapes are going to be positioned - the\rtfsp
{\it constraining} shape;
\item a list of one or more shapes to be constrained: the {\it constrained} shapes.
\end{enumerate}
The constraining shape can be either the parent of the constrained shapes, or a sibling. The
constrained shapes must all be siblings of each other.
For an exhaustive list and description of the available constraint types, see the \helpref{OGLConstraint constructor}{oglconstraintconstr}.
Note that most constraints operate in one dimension only (vertically or horizontally), so you will
usually need to specify constraints in pairs.
You can set the spacing between constraining and constrained shapes by
calling \helpref{OGLConstraint::SetSpacing}{oglconstraintsetspacing}.
Finally, a wxCompositeShape can have {\it divisions}, which are special child shapes of class
wxDivisionShape (not to be confused with wxDividedShape). The purpose of this is to allow
the composite to be divided into user-adjustable regions (divisions) into which other shapes
can be dropped dynamically, given suitable application code. Divisons allow the child
shapes to have an identity of their own - they can be manipulated independently of their container -
but to behave as if they are contained with the division, moving with the parent shape.
Divisions boundaries can themselves be moved using the mouse.
To create an initial division, call \helpref{wxCompositeShape::MakeContainer}{wxcompositeshapemakecontainer}.
Make further divisions by calling \helpref{wxDivisionShape::Divide}{wxdivisionshapedivide}.

BIN
utils/ogl/docs/up.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 B

2434
utils/ogl/src/basic.cpp Normal file

File diff suppressed because it is too large Load Diff

605
utils/ogl/src/basic.h Normal file
View File

@@ -0,0 +1,605 @@
/////////////////////////////////////////////////////////////////////////////
// Name: basic.h
// Purpose: Basic OGL classes and definitions
// Author: Julian Smart
// Modified by:
// Created: 12/07/98
// RCS-ID: $Id$
// Copyright: (c) Julian Smart
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef _OGL_BASIC_H_
#define _OGL_BASIC_H_
#ifdef __GNUG__
#pragma interface "basic.h"
#endif
#define OGL_VERSION 2.0
#ifndef DEFAULT_MOUSE_TOLERANCE
#define DEFAULT_MOUSE_TOLERANCE 3
#endif
// Edit these lines if you positively don't want PROLOGIO support
#ifndef PROLOGIO
#define PROLOGIO
#endif
// Key identifiers
#define KEY_SHIFT 1
#define KEY_CTRL 2
// Arrow styles
#define ARROW_NONE 0
#define ARROW_END 1
#define ARROW_BOTH 2
#define ARROW_MIDDLE 3
#define ARROW_START 4
// Control point types
// Rectangle and most other shapes
#define CONTROL_POINT_VERTICAL 1
#define CONTROL_POINT_HORIZONTAL 2
#define CONTROL_POINT_DIAGONAL 3
// Line
#define CONTROL_POINT_ENDPOINT_TO 4
#define CONTROL_POINT_ENDPOINT_FROM 5
#define CONTROL_POINT_LINE 6
// Types of formatting: can be combined in a bit list
#define FORMAT_NONE 0
// Left justification
#define FORMAT_CENTRE_HORIZ 1
// Centre horizontally
#define FORMAT_CENTRE_VERT 2
// Centre vertically
#define FORMAT_SIZE_TO_CONTENTS 4
// Resize shape to contents
// Shadow mode
#define SHADOW_NONE 0
#define SHADOW_LEFT 1
#define SHADOW_RIGHT 2
/*
* Declare types
*
*/
#define SHAPE_BASIC wxTYPE_USER + 1
#define SHAPE_RECTANGLE wxTYPE_USER + 2
#define SHAPE_ELLIPSE wxTYPE_USER + 3
#define SHAPE_POLYGON wxTYPE_USER + 4
#define SHAPE_CIRCLE wxTYPE_USER + 5
#define SHAPE_LINE wxTYPE_USER + 6
#define SHAPE_DIVIDED_RECTANGLE wxTYPE_USER + 8
#define SHAPE_COMPOSITE wxTYPE_USER + 9
#define SHAPE_CONTROL_POINT wxTYPE_USER + 10
#define SHAPE_DRAWN wxTYPE_USER + 11
#define SHAPE_DIVISION wxTYPE_USER + 12
#define SHAPE_LABEL_OBJECT wxTYPE_USER + 13
#define SHAPE_BITMAP wxTYPE_USER + 14
#define SHAPE_DIVIDED_OBJECT_CONTROL_POINT wxTYPE_USER + 15
#define OBJECT_REGION wxTYPE_USER + 20
#define OP_CLICK_LEFT 1
#define OP_CLICK_RIGHT 2
#define OP_DRAG_LEFT 4
#define OP_DRAG_RIGHT 8
#define OP_ALL (OP_CLICK_LEFT | OP_CLICK_RIGHT | OP_DRAG_LEFT | OP_DRAG_RIGHT)
class wxShapeTextLine;
class wxShapeCanvas;
class wxLineShape;
class wxControlPoint;
class wxShapeRegion;
class wxShape;
#ifdef PROLOGIO
class wxExpr;
class wxDatabase;
#endif
class wxShapeEvtHandler: public wxObject
{
DECLARE_DYNAMIC_CLASS(wxShapeEvtHandler)
public:
wxShapeEvtHandler(wxShapeEvtHandler *prev = NULL, wxShape *shape = NULL);
virtual ~wxShapeEvtHandler();
inline void SetHandlerShape(wxShape *sh) { m_handlerShape = sh; }
inline wxShape *GetShape() const { return m_handlerShape; }
// This is called when the _shape_ is deleted.
virtual void OnDelete();
virtual void OnDraw(wxDC& dc);
virtual void OnDrawContents(wxDC& dc);
virtual void OnMoveLinks(wxDC& dc);
virtual void OnErase(wxDC& dc);
virtual void OnEraseContents(wxDC& dc);
virtual void OnHighlight(wxDC& dc);
virtual void OnLeftClick(float x, float y, int keys = 0, int attachment = 0);
virtual void OnRightClick(float x, float y, int keys = 0, int attachment = 0);
virtual void OnSize(float x, float y);
virtual bool OnMovePre(wxDC& dc, float x, float y, float old_x, float old_y, bool display = TRUE);
virtual void OnMovePost(wxDC& dc, float x, float y, float old_x, float old_y, bool display = TRUE);
virtual void OnDragLeft(bool draw, float x, float y, int keys=0, int attachment = 0); // Erase if draw false
virtual void OnBeginDragLeft(float x, float y, int keys=0, int attachment = 0);
virtual void OnEndDragLeft(float x, float y, int keys=0, int attachment = 0);
virtual void OnDragRight(bool draw, float x, float y, int keys=0, int attachment = 0); // Erase if draw false
virtual void OnBeginDragRight(float x, float y, int keys=0, int attachment = 0);
virtual void OnEndDragRight(float x, float y, int keys=0, int attachment = 0);
virtual void OnDrawOutline(wxDC& dc, float x, float y, float w, float h);
virtual void OnDrawControlPoints(wxDC& dc);
virtual void OnEraseControlPoints(wxDC& dc);
virtual void OnMoveLink(wxDC& dc, bool moveControlPoints = TRUE);
virtual void OnBeginSize(float WXUNUSED(w), float WXUNUSED(h)) { }
virtual void OnEndSize(float WXUNUSED(w), float WXUNUSED(h)) { }
private:
wxShapeEvtHandler* m_previousHandler;
wxShape* m_handlerShape;
};
class wxShape: public wxShapeEvtHandler
{
DECLARE_ABSTRACT_CLASS(wxShape)
public:
wxShape(wxShapeCanvas *can = NULL);
virtual ~wxShape();
virtual void GetBoundingBoxMax(float *width, float *height);
virtual void GetBoundingBoxMin(float *width, float *height) = 0;
virtual bool GetPerimeterPoint(float x1, float y1,
float x2, float y2,
float *x3, float *y3);
inline wxShapeCanvas *GetCanvas() { return m_canvas; }
void SetCanvas(wxShapeCanvas *the_canvas);
virtual void AddToCanvas(wxShapeCanvas *the_canvas, wxShape *addAfter = NULL);
virtual void InsertInCanvas(wxShapeCanvas *the_canvas);
virtual void RemoveFromCanvas(wxShapeCanvas *the_canvas);
inline float GetX() const { return m_xpos; }
inline float GetY() const { return m_ypos; }
inline void SetX(float x) { m_xpos = x; }
inline void SetY(float y) { m_ypos = y; }
inline wxShape *GetParent() const { return m_parent; }
inline void SetParent(wxShape *p) { m_parent = p; }
wxShape *GetTopAncestor();
inline wxList& GetChildren() { return m_children; }
virtual void OnDraw(wxDC& dc);
virtual void OnDrawContents(wxDC& dc);
virtual void OnMoveLinks(wxDC& dc);
virtual void Unlink() { };
void SetDrawHandles(bool drawH);
inline bool GetDrawHandles() { return m_drawHandles; }
virtual void OnErase(wxDC& dc);
virtual void OnEraseContents(wxDC& dc);
virtual void OnHighlight(wxDC& dc);
virtual void OnLeftClick(float x, float y, int keys = 0, int attachment = 0);
virtual void OnRightClick(float x, float y, int keys = 0, int attachment = 0);
virtual void OnSize(float x, float y);
virtual bool OnMovePre(wxDC& dc, float x, float y, float old_x, float old_y, bool display = TRUE);
virtual void OnMovePost(wxDC& dc, float x, float y, float old_x, float old_y, bool display = TRUE);
virtual void OnDragLeft(bool draw, float x, float y, int keys=0, int attachment = 0); // Erase if draw false
virtual void OnBeginDragLeft(float x, float y, int keys=0, int attachment = 0);
virtual void OnEndDragLeft(float x, float y, int keys=0, int attachment = 0);
virtual void OnDragRight(bool draw, float x, float y, int keys=0, int attachment = 0); // Erase if draw false
virtual void OnBeginDragRight(float x, float y, int keys=0, int attachment = 0);
virtual void OnEndDragRight(float x, float y, int keys=0, int attachment = 0);
virtual void OnDrawOutline(wxDC& dc, float x, float y, float w, float h);
virtual void OnDrawControlPoints(wxDC& dc);
virtual void OnEraseControlPoints(wxDC& dc);
virtual void OnBeginSize(float WXUNUSED(w), float WXUNUSED(h)) { }
virtual void OnEndSize(float WXUNUSED(w), float WXUNUSED(h)) { }
virtual void MakeControlPoints();
virtual void DeleteControlPoints(wxDC *dc = NULL);
virtual void ResetControlPoints();
inline wxShapeEvtHandler *GetEventHandler() { return m_eventHandler; }
inline void SetEventHandler(wxShapeEvtHandler *handler) { m_eventHandler = handler; }
// Mandatory control points, e.g. the divided line moving handles
// should appear even if a child of the 'selected' image
virtual void MakeMandatoryControlPoints();
virtual void ResetMandatoryControlPoints();
inline virtual bool Recompute() { return TRUE; };
// Calculate size recursively, if size changes. Size might depend on children.
inline virtual void CalculateSize() { };
virtual void Select(bool select = TRUE, wxDC* dc = NULL);
virtual void SetHighlight(bool hi = TRUE, bool recurse = FALSE);
inline virtual bool IsHighlighted() const { return m_highlighted; };
virtual bool Selected() const;
virtual bool AncestorSelected() const;
void SetSensitivityFilter(int sens = OP_ALL, bool recursive = FALSE);
int GetSensitivityFilter() const { return m_sensitivity; }
void SetDraggable(bool drag, bool recursive = FALSE);
inline void SetFixedSize(bool x, bool y) { m_fixedWidth = x; m_fixedHeight = y; };
inline void GetFixedSize(bool *x, bool *y) const { *x = m_fixedWidth; *y = m_fixedHeight; };
inline bool GetFixedWidth() const { return m_fixedWidth; }
inline bool GetFixedHeight() const { return m_fixedHeight; }
inline void SetSpaceAttachments(bool sp) { m_spaceAttachments = sp; };
inline bool GetSpaceAttachments() const { return m_spaceAttachments; };
void SetShadowMode(int mode, bool redraw = FALSE);
inline int GetShadowMode() const { return m_shadowMode; }
virtual bool HitTest(float x, float y, int *attachment, float *distance);
inline void SetCentreResize(bool cr) { m_centreResize = cr; }
inline bool GetCentreResize() const { return m_centreResize; }
inline wxList& GetLines() { return m_lines; }
inline void SetDisableLabel(bool flag) { m_disableLabel = flag; }
inline bool GetDisableLabel() const { return m_disableLabel; }
inline void SetAttachmentMode(bool flag) { m_attachmentMode = flag; }
inline bool GetAttachmentMode() const { return m_attachmentMode; }
inline void SetId(long i) { m_id = i; }
inline long GetId() const { return m_id; }
void SetPen(wxPen *pen);
void SetBrush(wxBrush *brush);
inline void SetClientData(wxObject *client_data) { m_clientData = client_data; };
inline wxObject *GetClientData() const { return m_clientData; };
virtual void Show(bool show);
virtual bool IsShown() const { return m_visible; }
virtual void Move(wxDC& dc, float x1, float y1, bool display = TRUE);
virtual void Erase(wxDC& dc);
virtual void EraseContents(wxDC& dc);
virtual void Draw(wxDC& dc);
virtual void Flash();
virtual void MoveLinks(wxDC& dc);
virtual void DrawContents(wxDC& dc); // E.g. for drawing text label
virtual void SetSize(float x, float y, bool recursive = TRUE);
virtual void SetAttachmentSize(float x, float y);
void Attach(wxShapeCanvas *can);
void Detach();
inline virtual bool Constrain() { return FALSE; } ;
void AddLine(wxLineShape *line, wxShape *other,
int attachFrom = 0, int attachTo = 0);
void AddText(const wxString& string);
inline wxPen *GetPen() const { return m_pen; }
inline wxBrush *GetBrush() const { return m_brush; }
/*
* Region-specific functions (defaults to the default region
* for simple objects
*/
// Set the default, single region size to be consistent
// with the object size
void SetDefaultRegionSize();
virtual void FormatText(wxDC& dc, const wxString& s, int regionId = 0);
virtual void SetFormatMode(int mode, int regionId = 0);
virtual int GetFormatMode(int regionId = 0) const;
virtual void SetFont(wxFont *font, int regionId = 0);
virtual wxFont *GetFont(int regionId = 0) const;
virtual void SetTextColour(const wxString& colour, int regionId = 0);
virtual wxString GetTextColour(int regionId = 0) const;
virtual inline int GetNumberOfTextRegions() const { return m_regions.Number(); }
virtual void SetRegionName(const wxString& name, int regionId = 0);
// Get the name representing the region for this image alone.
// I.e. this image's region ids go from 0 to N-1.
// But the names might be "0.2.0", "0.2.1" etc. depending on position in composite.
// So the last digit represents the region Id, the others represent positions
// in composites.
virtual wxString GetRegionName(int regionId);
// Gets the region corresponding to the name, or -1 if not found.
virtual int GetRegionId(const wxString& name);
// Construct names for regions, unique even for children of a composite.
virtual void NameRegions(const wxString& parentName = "");
// Get list of regions
inline wxList& GetRegions() { return m_regions; }
virtual void AddRegion(wxShapeRegion *region);
virtual void ClearRegions();
// Assign new ids to this image and children (if composite)
void AssignNewIds();
// Returns actual image (same as 'this' if non-composite) and region id
// for given region name.
virtual wxShape *FindRegion(const wxString& regionName, int *regionId);
// Finds all region names for this image (composite or simple).
// Supply empty string list.
virtual void FindRegionNames(wxStringList& list);
virtual void ClearText(int regionId = 0);
void RemoveLine(wxLineShape *line);
#ifdef PROLOGIO
// Prolog database stuff
virtual char *GetFunctor();
virtual void WritePrologAttributes(wxExpr *clause);
virtual void ReadPrologAttributes(wxExpr *clause);
// In case the object has constraints it needs to read in in a different pass
inline virtual void ReadConstraints(wxExpr *WXUNUSED(clause), wxExprDatabase *WXUNUSED(database)) { };
virtual void WriteRegions(wxExpr *clause);
virtual void ReadRegions(wxExpr *clause);
#endif
// Does the WHOLE copy calling PrivateCopy - don't redefine.
// If canvas is non-null, set the canvas too.
wxShape *CreateNewCopy(wxShapeCanvas *theCanvas = NULL);
// Attachment code
virtual bool GetAttachmentPosition(int attachment, float *x, float *y,
int nth = 0, int no_arcs = 1, wxLineShape *line = NULL);
virtual int GetNumberOfAttachments();
virtual bool AttachmentIsValid(int attachment);
virtual void EraseLinks(wxDC& dc, int attachment = -1, bool recurse = FALSE);
virtual void DrawLinks(wxDC& dc, int attachment = -1, bool recurse = FALSE);
virtual void MoveLineToNewAttachment(wxDC& dc, wxLineShape *to_move,
float x, float y);
// Reorders the lines coming into the node image at this attachment
// position, in the order in which they appear in linesToSort.
virtual void SortLines(int attachment, wxList& linesToSort);
// This is really to distinguish between lines and other images.
// For lines, want to pass drag to canvas, since lines tend to prevent
// dragging on a canvas (they get in the way.)
virtual bool Draggable() const { return TRUE; }
// Returns TRUE if image is a descendant of this image
bool HasDescendant(wxShape *image);
// Does the copying for this object
void Copy(wxShape& copy);
// Returns a new instance, and does the copy for this class. Define for each class.
virtual wxShape *PrivateCopy() = 0;
// Rotate about the given axis by the given amount in radians
// (does nothing for most objects)
// But even non-rotating objects should record their notional
// rotation in case it's important (e.g. in dog-leg code).
virtual inline void Rotate(float WXUNUSED(x), float WXUNUSED(y), float theta) { m_rotation = theta; }
virtual inline float GetRotation() const { return m_rotation; }
void ClearAttachments();
// Recentres all the text regions for this object
void Recentre(wxDC& dc);
// Clears points from a list of wxRealPoints
void ClearPointList(wxList& list);
private:
wxObject* m_clientData;
protected:
wxShapeEvtHandler* m_eventHandler;
bool m_formatted;
float m_xpos, m_ypos;
wxPen* m_pen;
wxBrush* m_brush;
wxFont* m_font;
wxColour* m_textColour;
wxString m_textColourName;
wxShapeCanvas* m_canvas;
wxList m_lines;
wxList m_text;
wxList m_controlPoints;
wxList m_regions;
wxList m_attachmentPoints;
bool m_visible;
bool m_disableLabel;
long m_id;
bool m_selected;
bool m_highlighted; // Different from selected: user-defined highlighting,
// e.g. thick border.
float m_rotation;
int m_sensitivity;
bool m_draggable;
bool m_attachmentMode; // TRUE if using attachments, FALSE otherwise
bool m_spaceAttachments; // TRUE if lines at one side should be spaced
bool m_fixedWidth;
bool m_fixedHeight;
bool m_centreResize; // Default is to resize keeping the centre constant (TRUE)
bool m_drawHandles; // Don't draw handles if FALSE, usually TRUE
wxList m_children; // In case it's composite
wxShape* m_parent; // In case it's a child
int m_formatMode;
int m_shadowMode;
wxBrush* m_shadowBrush;
int m_shadowOffsetX;
int m_shadowOffsetY;
int m_textMarginX; // Gap between text and border
int m_textMarginY;
wxString m_regionName;
};
class wxPolygonShape: public wxShape
{
DECLARE_DYNAMIC_CLASS(wxPolygonShape)
public:
wxPolygonShape();
~wxPolygonShape();
// Takes a list of wxRealPoints; each point is an OFFSET from the centre.
// Deletes user's points in destructor.
virtual void Create(wxList *points);
void GetBoundingBoxMin(float *w, float *h);
void CalculateBoundingBox();
bool GetPerimeterPoint(float x1, float y1,
float x2, float y2,
float *x3, float *y3);
bool HitTest(float x, float y, int *attachment, float *distance);
void SetSize(float x, float y, bool recursive = TRUE);
void OnDraw(wxDC& dc);
void OnDrawOutline(wxDC& dc, float x, float y, float w, float h);
// A polygon should have a control point at each vertex,
// with the option of moving the control points individually
// to change the shape.
void MakeControlPoints();
void ResetControlPoints();
// If we've changed the shape, must make the original
// points match the working points
void UpdateOriginalPoints();
// Add a control point after the given point
virtual void AddPolygonPoint(int pos = 0);
// Delete a control point
virtual void DeletePolygonPoint(int pos = 0);
// Recalculates the centre of the polygon
virtual void CalculatePolygonCentre();
#ifdef PROLOGIO
// Prolog database stuff
void WritePrologAttributes(wxExpr *clause);
void ReadPrologAttributes(wxExpr *clause);
#endif
int GetNumberOfAttachments();
bool GetAttachmentPosition(int attachment, float *x, float *y,
int nth = 0, int no_arcs = 1, wxLineShape *line = NULL);
bool AttachmentIsValid(int attachment);
// Does the copying for this object
void Copy(wxPolygonShape& copy);
wxShape *PrivateCopy();
inline wxList *GetPoints() { return m_points; }
private:
wxList* m_points;
wxList* m_originalPoints;
float m_boundWidth;
float m_boundHeight;
float m_originalWidth;
float m_originalHeight;
};
class wxRectangleShape: public wxShape
{
DECLARE_DYNAMIC_CLASS(wxRectangleShape)
public:
wxRectangleShape(float w = 0.0, float h = 0.0);
void GetBoundingBoxMin(float *w, float *h);
bool GetPerimeterPoint(float x1, float y1,
float x2, float y2,
float *x3, float *y3);
void OnDraw(wxDC& dc);
void SetSize(float x, float y, bool recursive = TRUE);
void SetCornerRadius(float rad); // If > 0, rounded corners
#ifdef PROLOGIO
// Prolog database stuff
void WritePrologAttributes(wxExpr *clause);
void ReadPrologAttributes(wxExpr *clause);
#endif
int GetNumberOfAttachments();
bool GetAttachmentPosition(int attachment, float *x, float *y,
int nth = 0, int no_arcs = 1, wxLineShape *line = NULL);
// Does the copying for this object
void Copy(wxRectangleShape& copy);
wxShape *PrivateCopy();
inline float GetWidth() const { return m_width; }
inline float GetHeight() const { return m_height; }
protected:
float m_width;
float m_height;
float m_cornerRadius;
};
class wxTextShape: public wxRectangleShape
{
DECLARE_DYNAMIC_CLASS(wxTextShape)
public:
wxTextShape(float width = 0.0, float height = 0.0);
void OnDraw(wxDC& dc);
#ifdef PROLOGIO
void WritePrologAttributes(wxExpr *clause);
#endif
// Does the copying for this object
void Copy(wxTextShape& copy);
wxShape *PrivateCopy();
};
class wxEllipseShape: public wxShape
{
DECLARE_DYNAMIC_CLASS(wxEllipseShape)
public:
wxEllipseShape(float w = 0.0, float h = 0.0);
void GetBoundingBoxMin(float *w, float *h);
bool GetPerimeterPoint(float x1, float y1,
float x2, float y2,
float *x3, float *y3);
void OnDraw(wxDC& dc);
void SetSize(float x, float y, bool recursive = TRUE);
#ifdef PROLOGIO
// Prolog database stuff
void WritePrologAttributes(wxExpr *clause);
void ReadPrologAttributes(wxExpr *clause);
#endif
int GetNumberOfAttachments();
bool GetAttachmentPosition(int attachment, float *x, float *y,
int nth = 0, int no_arcs = 1, wxLineShape *line = NULL);
// Does the copying for this object
void Copy(wxEllipseShape& copy);
wxShape *PrivateCopy();
inline float GetWidth() const { return m_width; }
inline float GetHeight() const { return m_height; }
protected:
float m_width;
float m_height;
};
class wxCircleShape: public wxEllipseShape
{
DECLARE_DYNAMIC_CLASS(wxCircleShape)
public:
wxCircleShape(float w = 0.0);
bool GetPerimeterPoint(float x1, float y1,
float x2, float y2,
float *x3, float *y3);
// Does the copying for this object
void Copy(wxCircleShape& copy);
wxShape *PrivateCopy();
};
#endif
// _OGL_BASIC_H_

2001
utils/ogl/src/basic2.cpp Normal file

File diff suppressed because it is too large Load Diff

195
utils/ogl/src/basicp.h Normal file
View File

@@ -0,0 +1,195 @@
/////////////////////////////////////////////////////////////////////////////
// Name: basicp.h
// Purpose: Private OGL classes and definitions
// Author: Julian Smart
// Modified by:
// Created: 12/07/98
// RCS-ID: $Id$
// Copyright: (c) Julian Smart
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef _OGL_BASICP_H_
#define _OGL_BASICP_H_
#ifdef __GNUG__
#pragma interface "basicp.h"
#endif
#define CONTROL_POINT_SIZE 6
class wxShapeTextLine: public wxObject
{
DECLARE_DYNAMIC_CLASS(wxShapeTextLine)
public:
wxShapeTextLine(float the_x = 0.0, float the_y = 0.0, const wxString& the_line = "");
~wxShapeTextLine();
inline float GetX() const { return m_x; }
inline float GetY() const { return m_y; }
inline void SetX(float x) { m_x = x; }
inline void SetY(float y) { m_y = y; }
inline void SetText(const wxString& text) { m_line = text; }
inline wxString GetText() const { return m_line; }
protected:
wxString m_line;
float m_x;
float m_y;
};
class wxControlPoint: public wxRectangleShape
{
DECLARE_DYNAMIC_CLASS(wxControlPoint)
public:
wxControlPoint(wxShapeCanvas *the_canvas = NULL, wxShape *object = NULL, float size = 0.0, float the_xoffset = 0.0,
float the_yoffset = 0.0, int the_type = 0);
~wxControlPoint();
void OnDraw(wxDC& dc);
void OnErase(wxDC& dc);
void OnDrawContents(wxDC& dc);
void OnDragLeft(bool draw, float x, float y, int keys=0, int attachment = 0);
void OnBeginDragLeft(float x, float y, int keys=0, int attachment = 0);
void OnEndDragLeft(float x, float y, int keys=0, int attachment = 0);
bool GetAttachmentPosition(int attachment, float *x, float *y,
int nth = 0, int no_arcs = 1, wxLineShape *line = NULL);
int GetNumberOfAttachments();
inline void SetEraseObject(bool er) { m_eraseObject = er; }
public:
int m_type;
float m_xoffset;
float m_yoffset;
wxShape* m_shape;
wxCursor* m_oldCursor;
bool m_eraseObject; // If TRUE, erases object before dragging handle.
};
class wxPolygonControlPoint: public wxControlPoint
{
DECLARE_DYNAMIC_CLASS(wxPolygonControlPoint)
public:
wxPolygonControlPoint(wxShapeCanvas *the_canvas = NULL, wxShape *object = NULL, float size = 0.0, wxRealPoint *vertex = NULL,
float the_xoffset = 0.0, float the_yoffset = 0.0);
~wxPolygonControlPoint();
void OnDragLeft(bool draw, float x, float y, int keys=0, int attachment = 0);
void OnBeginDragLeft(float x, float y, int keys=0, int attachment = 0);
void OnEndDragLeft(float x, float y, int keys=0, int attachment = 0);
public:
wxRealPoint* m_polygonVertex;
wxRealPoint m_originalSize;
float m_originalDistance;
};
/*
* Object regions.
* Every shape has one or more text regions with various
* properties. Not all of a region's properties will be used
* by a shape.
*
*/
class wxShapeRegion: public wxObject
{
DECLARE_DYNAMIC_CLASS(wxShapeRegion)
public:
// Constructor
wxShapeRegion();
// Copy constructor
wxShapeRegion(wxShapeRegion& region);
// Destructor
~wxShapeRegion();
// Accessors
inline void SetText(const wxString& s) { m_regionText = s; }
void SetFont(wxFont *f);
void SetMinSize(float w, float h);
void SetSize(float w, float h);
void SetPosition(float x, float y);
void SetProportions(float x, float y);
void SetFormatMode(int mode);
inline void SetName(const wxString& s) { m_regionName = s; };
void SetColour(const wxString& col); // Text colour
inline wxString GetText() const { return m_regionText; }
inline wxFont *GetFont() const { return m_font; }
inline void GetMinSize(float *x, float *y) const { *x = m_minWidth; *y = m_minHeight; }
inline void GetProportion(float *x, float *y) const { *x = m_regionProportionX; *y = m_regionProportionY; }
inline void GetSize(float *x, float *y) const { *x = m_width; *y = m_height; }
inline void GetPosition(float *xp, float *yp) const { *xp = m_x; *yp = m_y; }
inline int GetFormatMode() const { return m_formatMode; }
inline wxString GetName() const { return m_regionName; }
inline wxString GetColour() const { return m_textColour; }
wxColour *GetActualColourObject();
inline wxList& GetFormattedText() { return m_formattedText; }
inline wxString GetPenColour() const { return m_penColour; }
inline int GetPenStyle() const { return m_penStyle; }
inline void SetPenStyle(int style) { m_penStyle = style; m_actualPenObject = NULL; }
void SetPenColour(const wxString& col);
wxPen *GetActualPen();
inline float GetWidth() const { return m_width; }
inline float GetHeight() const { return m_height; }
void ClearText();
public:
wxString m_regionText;
wxList m_formattedText; // List of wxShapeTextLines
wxFont* m_font;
float m_minHeight; // If zero, hide region.
float m_minWidth; // If zero, hide region.
float m_width;
float m_height;
float m_x;
float m_y;
float m_regionProportionX; // Proportion of total object size;
// -1.0 indicates equal proportion
float m_regionProportionY; // Proportion of total object size;
// -1.0 indicates equal proportion
int m_formatMode; // FORMAT_CENTRE_HORIZ | FORMAT_CENTRE_VERT | FORMAT_NONE
wxString m_regionName;
wxString m_textColour;
wxColour* m_actualColourObject; // For speed purposes
// New members for specifying divided rectangle division colour/style 30/6/94
wxString m_penColour;
int m_penStyle;
wxPen* m_actualPenObject;
};
/*
* User-defined attachment point
*/
class wxAttachmentPoint: public wxObject
{
DECLARE_DYNAMIC_CLASS(wxAttachmentPoint)
public:
inline wxAttachmentPoint()
{
m_id = 0; m_x = 0.0; m_y = 0.0;
}
public:
int m_id; // Identifier
float m_x; // x offset from centre of object
float m_y; // y offset from centre of object
};
#endif
// _OGL_BASICP_H_

126
utils/ogl/src/bitmap.cpp Normal file
View File

@@ -0,0 +1,126 @@
/////////////////////////////////////////////////////////////////////////////
// Name: bitmap.cpp
// Purpose: Bitmap shape class
// Author: Julian Smart
// Modified by:
// Created: 12/07/98
// RCS-ID: $Id$
// Copyright: (c) Julian Smart
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "bitmap.h"
#endif
// 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
#ifdef PROLOGIO
#include <wx/wxexpr.h>
#endif
#include "basic.h"
#include "basicp.h"
#include "canvas.h"
#include "bitmap.h"
#include "misc.h"
/*
* Bitmap object
*
*/
IMPLEMENT_DYNAMIC_CLASS(wxBitmapShape, wxShape)
wxBitmapShape::wxBitmapShape():wxRectangleShape(100.0, 50.0)
{
m_filename = "";
}
wxBitmapShape::~wxBitmapShape()
{
}
void wxBitmapShape::OnDraw(wxDC& dc)
{
if (!m_bitmap.Ok())
return;
wxMemoryDC tempDC;
tempDC.SelectObject(m_bitmap);
float x, y;
x = (long)(m_xpos - m_bitmap.GetWidth() / 2.0);
y = (long)(m_ypos - m_bitmap.GetHeight() / 2.0);
dc.Blit(x, y, m_bitmap.GetWidth(), m_bitmap.GetHeight(), &tempDC, 0, 0);
}
void wxBitmapShape::SetSize(float w, float h, bool recursive)
{
if (m_bitmap.Ok())
{
w = m_bitmap.GetWidth();
h = m_bitmap.GetHeight();
}
SetAttachmentSize(w, h);
m_width = w;
m_height = h;
SetDefaultRegionSize();
}
#ifdef PROLOGIO
// Prolog database stuff
char *wxBitmapShape::GetFunctor()
{
return "node_image";
}
void wxBitmapShape::WritePrologAttributes(wxExpr *clause)
{
// Can't really save the bitmap; so instantiate the bitmap
// at a higher level in the application, from a symbol library.
wxRectangleShape::WritePrologAttributes(clause);
clause->AddAttributeValueString("filename", m_filename);
}
void wxBitmapShape::ReadPrologAttributes(wxExpr *clause)
{
wxRectangleShape::ReadPrologAttributes(clause);
clause->GetAttributeValue("filename", m_filename);
}
#endif
// Does the copying for this object
void wxBitmapShape::Copy(wxBitmapShape& copy)
{
wxRectangleShape::Copy(copy);
copy.m_bitmap = m_bitmap;
copy.SetFilename(m_filename);
}
// Returns a new instance, and does the copy for this class. Define for each class.
wxShape *wxBitmapShape::PrivateCopy()
{
wxBitmapShape *obj = new wxBitmapShape;
Copy(*obj);
return obj;
}
void wxBitmapShape::SetBitmap(const wxBitmap& bm)
{
m_bitmap = bm;
if (m_bitmap.Ok())
SetSize(m_bitmap.GetWidth(), m_bitmap.GetHeight());
}

57
utils/ogl/src/bitmap.h Normal file
View File

@@ -0,0 +1,57 @@
/////////////////////////////////////////////////////////////////////////////
// Name: bitmap.h
// Purpose: wxBitmapShape
// Author: Julian Smart
// Modified by:
// Created: 12/07/98
// RCS-ID: $Id$
// Copyright: (c) Julian Smart
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef _OGL_BITMAP_H_
#define _OGL_BITMAP_H_
#ifdef __GNUG__
#pragma interface "bitmap.h"
#endif
#include "basic.h"
class wxBitmapShape: public wxRectangleShape
{
DECLARE_DYNAMIC_CLASS(wxBitmapShape)
public:
wxBitmapShape();
~wxBitmapShape();
void OnDraw(wxDC& dc);
#ifdef PROLOGIO
// Prolog database stuff
char *GetFunctor();
void WritePrologAttributes(wxExpr *clause);
void ReadPrologAttributes(wxExpr *clause);
#endif
// Does the copying for this object
void Copy(wxBitmapShape& copy);
// Returns a new instance, and does the copy for this class. Define for each class.
wxShape *PrivateCopy();
void SetSize(float w, float h, bool recursive = TRUE);
inline wxBitmap& GetBitmap() const { return (wxBitmap&) m_bitmap; }
void SetBitmap(const wxBitmap& bm);
inline void SetFilename(const wxString& f) { m_filename = f; };
inline wxString GetFilename() const { return m_filename; }
private:
wxBitmap m_bitmap;
wxString m_filename;
};
#endif
// _OGL_BITMAP_H_

511
utils/ogl/src/canvas.cpp Normal file
View File

@@ -0,0 +1,511 @@
/////////////////////////////////////////////////////////////////////////////
// Name: canvas.cpp
// Purpose: Shape canvas class
// Author: Julian Smart
// Modified by:
// Created: 12/07/98
// RCS-ID: $Id$
// Copyright: (c) Julian Smart
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "canvas.h"
#endif
// 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
#ifdef PROLOGIO
#include <wx/wxexpr.h>
#endif
#if USE_IOSTREAMH
#include <iostream.h>
#else
#include <iostream>
#endif
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
#include "basic.h"
#include "basicp.h"
#include "canvas.h"
#include "ogldiag.h"
#include "misc.h"
#include "lines.h"
#include "composit.h"
#define CONTROL_POINT_SIZE 6
// Control point types
// Rectangle and most other shapes
#define CONTROL_POINT_VERTICAL 1
#define CONTROL_POINT_HORIZONTAL 2
#define CONTROL_POINT_DIAGONAL 3
// Line
#define CONTROL_POINT_ENDPOINT_TO 4
#define CONTROL_POINT_ENDPOINT_FROM 5
#define CONTROL_POINT_LINE 6
extern wxCursor *GraphicsBullseyeCursor;
IMPLEMENT_DYNAMIC_CLASS(wxShapeCanvas, wxScrolledWindow)
BEGIN_EVENT_TABLE(wxShapeCanvas, wxScrolledWindow)
EVT_PAINT(wxShapeCanvas::OnPaint)
EVT_MOUSE_EVENTS(wxShapeCanvas::OnMouseEvent)
END_EVENT_TABLE()
// Object canvas
wxShapeCanvas::wxShapeCanvas(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style):
wxScrolledWindow(parent, id, pos, size, style)
{
m_shapeDiagram = NULL;
m_dragState = NoDragging;
m_draggedShape = NULL;
m_oldDragX = 0;
m_oldDragY = 0;
m_firstDragX = 0;
m_firstDragY = 0;
m_checkTolerance = TRUE;
}
wxShapeCanvas::~wxShapeCanvas()
{
}
void wxShapeCanvas::OnPaint(wxPaintEvent& event)
{
wxPaintDC dc(this);
PrepareDC(dc);
dc.Clear();
if (GetDiagram())
GetDiagram()->Redraw(dc);
}
void wxShapeCanvas::OnMouseEvent(wxMouseEvent& event)
{
wxClientDC dc(this);
PrepareDC(dc);
wxPoint logPos(event.GetLogicalPosition(dc));
float x, y;
x = (float) logPos.x;
y = (float) 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(x - m_firstDragX));
int dy = abs(dc.LogicalToDeviceY(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((float)x, (float)y, keys, m_draggedAttachment);
else
{
m_draggedShape = NULL;
OnBeginDragLeft((float)x, (float)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, (float)x, (float)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((float)x, (float)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((float)x, (float)y, keys, m_draggedAttachment);
else
{
m_draggedShape = NULL;
OnBeginDragRight((float)x, (float)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, (float)x, (float)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((float)x, (float)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((float)x, (float)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, (float)x, (float)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((float)x, (float)y, keys);
m_draggedShape = NULL;
}
else if (dragging && !m_draggedShape && m_dragState == StartDraggingRight)
{
m_dragState = ContinueDraggingRight;
OnBeginDragRight((float)x, (float)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, (float)x, (float)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((float)x, (float)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((float)x, (float)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((float)x, (float)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((float)x, (float)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((float)x, (float)y, keys);
m_draggedShape = NULL;
m_dragState = NoDragging;
}
}
}
}
/*
* Try to find a sensitive object, working up the hierarchy of composites.
*
*/
wxShape *wxShapeCanvas::FindFirstSensitiveShape(float x, float y, int *new_attachment, int op)
{
wxShape *image = FindShape(x, y, new_attachment);
if (!image) return NULL;
wxShape *actualImage = FindFirstSensitiveShape1(image, op);
if (actualImage)
{
float dist;
// Find actual attachment
actualImage->HitTest(x, y, new_attachment, &dist);
}
return actualImage;
}
wxShape *wxShapeCanvas::FindFirstSensitiveShape1(wxShape *image, int op)
{
if (image->GetSensitivityFilter() & op)
return image;
if (image->GetParent())
return FindFirstSensitiveShape1(image->GetParent(), op);
return NULL;
}
// Helper function: TRUE if 'contains' wholly contains 'contained'.
static bool WhollyContains(wxShape *contains, wxShape *contained)
{
float xp1, yp1, xp2, yp2;
float w1, h1, w2, h2;
float left1, top1, right1, bottom1, left2, top2, right2, bottom2;
xp1 = contains->GetX(); yp1 = contains->GetY(); xp2 = contained->GetX(); yp2 = contained->GetY();
contains->GetBoundingBoxMax(&w1, &h1);
contained->GetBoundingBoxMax(&w2, &h2);
left1 = (float)(xp1 - (w1 / 2.0));
top1 = (float)(yp1 - (h1 / 2.0));
right1 = (float)(xp1 + (w1 / 2.0));
bottom1 = (float)(yp1 + (h1 / 2.0));
left2 = (float)(xp2 - (w2 / 2.0));
top2 = (float)(yp2 - (h2 / 2.0));
right2 = (float)(xp2 + (w2 / 2.0));
bottom2 = (float)(yp2 + (h2 / 2.0));
return ((left1 <= left2) && (top1 <= top2) && (right1 >= right2) && (bottom1 >= bottom2));
}
wxShape *wxShapeCanvas::FindShape(float x, float y, int *attachment, wxClassInfo *info, wxShape *notObject)
{
float 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
wxNode *current = GetDiagram()->GetShapeList()->Last();
while (current)
{
wxShape *object = (wxShape *)current->Data();
float 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)) &&
(!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->Previous();
}
current = GetDiagram()->GetShapeList()->Last();
while (current)
{
wxShape *object = (wxShape *)current->Data();
float 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 = dist;
nearest_object = object;
nearest_attachment = temp_attachment;
current = NULL;
}
}
}
if (current)
current = current->Previous();
}
*attachment = nearest_attachment;
return nearest_object;
}
/*
* Higher-level events called by OnEvent
*
*/
void wxShapeCanvas::OnLeftClick(float x, float y, int keys)
{
}
void wxShapeCanvas::OnRightClick(float x, float y, int keys)
{
}
void wxShapeCanvas::OnDragLeft(bool draw, float x, float y, int keys)
{
}
void wxShapeCanvas::OnBeginDragLeft(float x, float y, int keys)
{
}
void wxShapeCanvas::OnEndDragLeft(float x, float y, int keys)
{
}
void wxShapeCanvas::OnDragRight(bool draw, float x, float y, int keys)
{
}
void wxShapeCanvas::OnBeginDragRight(float x, float y, int keys)
{
}
void wxShapeCanvas::OnEndDragRight(float x, float y, int keys)
{
}
void wxShapeCanvas::AddShape(wxShape *object, wxShape *addAfter)
{ GetDiagram()->AddShape(object, addAfter); }
void wxShapeCanvas::InsertShape(wxShape *object)
{ GetDiagram()->InsertShape(object); }
void wxShapeCanvas::RemoveShape(wxShape *object)
{ GetDiagram()->RemoveShape(object); }
bool wxShapeCanvas::GetQuickEditMode()
{ return GetDiagram()->GetQuickEditMode(); }
void wxShapeCanvas::Redraw(wxDC& dc)
{ GetDiagram()->Redraw(dc); }
void wxShapeCanvas::Snap(float *x, float *y)
{ GetDiagram()->Snap(x, y); }

83
utils/ogl/src/canvas.h Normal file
View File

@@ -0,0 +1,83 @@
/////////////////////////////////////////////////////////////////////////////
// Name: canvas.h
// Purpose: wxShapeCanvas
// Author: Julian Smart
// Modified by:
// Created: 12/07/98
// RCS-ID: $Id$
// Copyright: (c) Julian Smart
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef _OGL_CANVAS_H_
#define _OGL_CANVAS_H_
#ifdef __GNUG__
#pragma interface "canvas.h"
#endif
// Drag states
#define NoDragging 0
#define StartDraggingLeft 1
#define ContinueDraggingLeft 2
#define StartDraggingRight 3
#define ContinueDraggingRight 4
// When drag_count reaches 0, process drag message
class wxDiagram;
class wxShapeCanvas: public wxScrolledWindow
{
DECLARE_DYNAMIC_CLASS(wxShapeCanvas)
public:
wxShapeCanvas(wxWindow *parent = NULL, wxWindowID id = -1, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
long style = wxBORDER | wxRETAINED);
~wxShapeCanvas();
inline void SetDiagram(wxDiagram *diag) { m_shapeDiagram = diag; }
inline wxDiagram *GetDiagram() const { return m_shapeDiagram; }
virtual void OnLeftClick(float x, float y, int keys = 0);
virtual void OnRightClick(float x, float y, int keys = 0);
virtual void OnDragLeft(bool draw, float x, float y, int keys=0); // Erase if draw false
virtual void OnBeginDragLeft(float x, float y, int keys=0);
virtual void OnEndDragLeft(float x, float y, int keys=0);
virtual void OnDragRight(bool draw, float x, float y, int keys=0); // Erase if draw false
virtual void OnBeginDragRight(float x, float y, int keys=0);
virtual void OnEndDragRight(float x, float y, int keys=0);
// Find object for mouse click, of given wxClassInfo (NULL for any type).
// If notImage is non-NULL, don't find an object that is equal to or a descendant of notImage
virtual wxShape *FindShape(float x, float y, int *attachment, wxClassInfo *info = NULL, wxShape *notImage = NULL);
wxShape *FindFirstSensitiveShape(float x, float y, int *new_attachment, int op);
wxShape *FindFirstSensitiveShape1(wxShape *image, int op);
// Redirect to wxDiagram object
virtual void AddShape(wxShape *object, wxShape *addAfter = NULL);
virtual void InsertShape(wxShape *object);
virtual void RemoveShape(wxShape *object);
virtual bool GetQuickEditMode();
virtual void Redraw(wxDC& dc);
void Snap(float *x, float *y);
// Events
void OnPaint(wxPaintEvent& event);
void OnMouseEvent(wxMouseEvent& event);
protected:
wxDiagram* m_shapeDiagram;
int m_dragState;
float m_oldDragX, m_oldDragY; // Previous drag coordinates
float m_firstDragX, m_firstDragY; // INITIAL drag coordinates
bool m_checkTolerance; // Whether to check drag tolerance
wxShape* m_draggedShape;
int m_draggedAttachment;
DECLARE_EVENT_TABLE()
};
#endif
// _OGL_CANVAS_H_

1769
utils/ogl/src/composit.cpp Normal file

File diff suppressed because it is too large Load Diff

244
utils/ogl/src/composit.h Normal file
View File

@@ -0,0 +1,244 @@
/////////////////////////////////////////////////////////////////////////////
// Name: composit.h
// Purpose: wxCompositeShape
// Author: Julian Smart
// Modified by:
// Created: 12/07/98
// RCS-ID: $Id$
// Copyright: (c) Julian Smart
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef _OGL_COMPOSIT_H_
#define _OGL_COMPOSIT_H_
#ifdef __GNUG__
#pragma interface "composit.h"
#endif
class wxDivisionShape;
class OGLConstraint;
/*
* A composite object is an invisible rectangle surrounding all children
*
*/
class wxCompositeShape: public wxRectangleShape
{
DECLARE_DYNAMIC_CLASS(wxCompositeShape)
public:
wxCompositeShape();
~wxCompositeShape();
void OnDraw(wxDC& dc);
void OnDrawContents(wxDC& dc);
void OnErase(wxDC& dc);
bool OnMovePre(wxDC& dc, float x, float y, float oldX, float oldY, bool display = TRUE);
void OnDragLeft(bool draw, float x, float y, int keys, int attachment = 0);
void OnBeginDragLeft(float x, float y, int keys, int attachment = 0);
void OnEndDragLeft(float x, float y, int keys, int attachment = 0);
void OnRightClick(float x, float y, int keys, int attachment = 0);
void SetSize(float w, float h, bool recursive = TRUE);
// Returns TRUE if it settled down
bool Recompute();
// New members
void AddChild(wxShape *child, wxShape *addAfter = NULL);
void RemoveChild(wxShape *child);
OGLConstraint *AddConstraint(OGLConstraint *constraint);
OGLConstraint *AddConstraint(int type, wxShape *constraining, wxList& constrained);
OGLConstraint *AddConstraint(int type, wxShape *constraining, wxShape *constrained);
void DeleteConstraint(OGLConstraint *constraint);
// Delete constraints that involve this child.
void DeleteConstraintsInvolvingChild(wxShape *child);
// Remove the image from any constraints involving it, but DON'T
// remove any constraints.
void RemoveChildFromConstraints(wxShape *child);
// Find constraint, also returning actual composite the constraint was in,
// in case it had to find it recursively.
OGLConstraint *FindConstraint(long id, wxCompositeShape **actualComposite = NULL);
// Returns TRUE if something changed
bool Constrain();
// Make this composite into a container by creating one wxDivisionShape
void MakeContainer();
// Calculates size and position of composite object based on children
void CalculateSize();
#ifdef PROLOGIO
// Prolog database stuff
void WritePrologAttributes(wxExpr *clause);
void ReadPrologAttributes(wxExpr *clause);
// In case the object has constraints it needs to read in in a different pass
void ReadConstraints(wxExpr *clause, wxExprDatabase *database);
#endif
// Does the copying for this object
void Copy(wxCompositeShape& copy);
wxShape *PrivateCopy();
virtual wxDivisionShape *OnCreateDivision();
// Finds the image used to visualize a container. This is any child
// of the composite that is not in the divisions list.
wxShape *FindContainerImage();
// Returns TRUE if division is a descendant of this container
bool ContainsDivision(wxDivisionShape *division);
inline wxList& GetDivisions() const { return (wxList&) m_divisions; }
inline wxList& GetConstraints() const { return (wxList&) m_constraints; }
protected:
float m_oldX;
float m_oldY;
wxList m_constraints;
wxList m_divisions; // In case it's a container
};
/*
* A division object is a composite with special properties,
* to be used for containment. It's a subdivision of a container.
* A containing node image consists of a composite with a main child shape
* such as rounded rectangle, plus a list of division objects.
* It needs to be a composite because a division contains pieces
* of diagram.
* NOTE a container has at least one wxDivisionShape for consistency.
* This can be subdivided, so it turns into two objects, then each of
* these can be subdivided, etc.
*/
#define DIVISION_SIDE_NONE 0
#define DIVISION_SIDE_LEFT 1
#define DIVISION_SIDE_TOP 2
#define DIVISION_SIDE_RIGHT 3
#define DIVISION_SIDE_BOTTOM 4
class wxDivisionShape: public wxCompositeShape
{
DECLARE_DYNAMIC_CLASS(wxDivisionShape)
public:
wxDivisionShape();
~wxDivisionShape();
void OnDraw(wxDC& dc);
void OnDrawContents(wxDC& dc);
bool OnMovePre(wxDC& dc, float x, float y, float oldX, float oldY, bool display = TRUE);
void OnDragLeft(bool draw, float x, float y, int keys, int attachment = 0);
void OnBeginDragLeft(float x, float y, int keys, int attachment = 0);
void OnEndDragLeft(float x, float y, int keys, int attachment = 0);
void OnRightClick(float x, float y, int keys = 0, int attachment = 0);
// Don't want this kind of composite to resize its subdiagrams, so
// override composite's SetSize.
void SetSize(float w, float h, bool recursive = TRUE);
// Similarly for calculating size: it's fixed at whatever SetSize
// set it to, not in terms of children.
void CalculateSize();
void MakeControlPoints();
void ResetControlPoints();
void MakeMandatoryControlPoints();
void ResetMandatoryControlPoints();
#ifdef PROLOGIO
// Prolog database stuff
void WritePrologAttributes(wxExpr *clause);
void ReadPrologAttributes(wxExpr *clause);
#endif
// Does the copying for this object
void Copy(wxDivisionShape& copy);
wxShape *PrivateCopy();
// Divide horizontally (wxHORIZONTAL) or vertically (wxVERTICAL)
bool Divide(int direction);
// Resize adjoining divisions at the given side. If test is TRUE,
// just see whether it's possible for each adjoining region,
// returning FALSE if it's not.
bool ResizeAdjoining(int side, float newPos, bool test);
// Adjust a side, returning FALSE if it's not physically possible.
bool AdjustLeft(float left, bool test);
bool AdjustTop(float top, bool test);
bool AdjustRight(float right, bool test);
bool AdjustBottom(float bottom, bool test);
// Edit style of left or top side
void EditEdge(int side);
// Popup menu
void PopupMenu(float x, float y);
inline void SetLeftSide(wxDivisionShape *shape) { m_leftSide = shape; }
inline void SetTopSide(wxDivisionShape *shape) { m_topSide = shape; }
inline void SetRightSide(wxDivisionShape *shape) { m_rightSide = shape; }
inline void SetBottomSide(wxDivisionShape *shape) { m_bottomSide = shape; }
inline wxDivisionShape *GetLeftSide() const { return m_leftSide; }
inline wxDivisionShape *GetTopSide() const { return m_topSide; }
inline wxDivisionShape *GetRightSide() const { return m_rightSide; }
inline wxDivisionShape *GetBottomSide() const { return m_bottomSide; }
inline void SetHandleSide(int side) { m_handleSide = side; }
inline int GetHandleSide() const { return m_handleSide; }
inline void SetLeftSidePen(wxPen *pen) { m_leftSidePen = pen; }
inline wxPen *GetLeftSidePen() const { return m_leftSidePen; }
inline void SetTopSidePen(wxPen *pen) { m_topSidePen = pen; }
inline wxPen *GetTopSidePen() const { return m_topSidePen; }
void SetLeftSideColour(const wxString& colour);
void SetTopSideColour(const wxString& colour);
void SetLeftSideStyle(const wxString& style);
void SetTopSideStyle(const wxString& style);
inline wxString GetLeftSideColour() const { return m_leftSideColour; }
inline wxString GetTopSideColour() const { return m_topSideColour; }
inline wxString GetLeftSideStyle() const { return m_leftSideStyle; }
inline wxString GetTopSideStyle() const { return m_topSideStyle; }
protected:
// Adjoining divisions. NULL indicates edge
// of container, and that side shouldn't be
// drawn.
wxDivisionShape* m_leftSide;
wxDivisionShape* m_rightSide;
wxDivisionShape* m_topSide;
wxDivisionShape* m_bottomSide;
int m_handleSide; // Side at which handle is legal
wxPen* m_leftSidePen;
wxPen* m_topSidePen;
wxString m_leftSideColour;
wxString m_topSideColour;
wxString m_leftSideStyle;
wxString m_topSideStyle;
};
extern wxMenu *oglPopupDivisionMenu;
extern void oglGraphicsDivisionMenuProc(wxMenu& menu, wxCommandEvent& event);
#define DIVISION_MENU_SPLIT_HORIZONTALLY 1
#define DIVISION_MENU_SPLIT_VERTICALLY 2
#define DIVISION_MENU_EDIT_LEFT_EDGE 3
#define DIVISION_MENU_EDIT_TOP_EDGE 4
#define DIVISION_MENU_EDIT_RIGHT_EDGE 5
#define DIVISION_MENU_EDIT_BOTTOM_EDGE 6
#define DIVISION_MENU_DELETE_ALL 7
#endif
// _OGL_COMPOSIT_H_

600
utils/ogl/src/constrnt.cpp Normal file
View File

@@ -0,0 +1,600 @@
/////////////////////////////////////////////////////////////////////////////
// Name: constrnt.cpp
// Purpose: OGL Constraint classes
// Author: Julian Smart
// Modified by:
// Created: 12/07/98
// RCS-ID: $Id$
// Copyright: (c) Julian Smart
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "constrnt.h"
#endif
// 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
#ifdef PROLOGIO
#include <wx/wxexpr.h>
#endif
#include "basic.h"
#include "constrnt.h"
#include "canvas.h"
wxList OGLConstraintTypes(wxKEY_INTEGER);
/*
* Constraint type
*
*/
IMPLEMENT_DYNAMIC_CLASS(OGLConstraintType, wxObject)
OGLConstraintType::OGLConstraintType(int theType, const wxString& theName, const wxString& thePhrase)
{
m_type = theType;
m_name = theName;
m_phrase = thePhrase;
}
OGLConstraintType::~OGLConstraintType()
{
}
void OGLInitializeConstraintTypes()
{
OGLConstraintTypes.Append(gyCONSTRAINT_CENTRED_VERTICALLY,
new OGLConstraintType(gyCONSTRAINT_CENTRED_VERTICALLY, "Centre vertically", "centred vertically w.r.t."));
OGLConstraintTypes.Append(gyCONSTRAINT_CENTRED_HORIZONTALLY,
new OGLConstraintType(gyCONSTRAINT_CENTRED_HORIZONTALLY, "Centre horizontally", "centred horizontally w.r.t."));
OGLConstraintTypes.Append(gyCONSTRAINT_CENTRED_BOTH,
new OGLConstraintType(gyCONSTRAINT_CENTRED_BOTH, "Centre", "centred w.r.t."));
OGLConstraintTypes.Append(gyCONSTRAINT_LEFT_OF,
new OGLConstraintType(gyCONSTRAINT_LEFT_OF, "Left of", "left of"));
OGLConstraintTypes.Append(gyCONSTRAINT_RIGHT_OF,
new OGLConstraintType(gyCONSTRAINT_RIGHT_OF, "Right of", "right of"));
OGLConstraintTypes.Append(gyCONSTRAINT_ABOVE,
new OGLConstraintType(gyCONSTRAINT_ABOVE, "Above", "above"));
OGLConstraintTypes.Append(gyCONSTRAINT_BELOW,
new OGLConstraintType(gyCONSTRAINT_BELOW, "Below", "below"));
// Alignment
OGLConstraintTypes.Append(gyCONSTRAINT_ALIGNED_TOP,
new OGLConstraintType(gyCONSTRAINT_ALIGNED_TOP, "Top-aligned", "aligned to the top of"));
OGLConstraintTypes.Append(gyCONSTRAINT_ALIGNED_BOTTOM,
new OGLConstraintType(gyCONSTRAINT_ALIGNED_BOTTOM, "Bottom-aligned", "aligned to the bottom of"));
OGLConstraintTypes.Append(gyCONSTRAINT_ALIGNED_LEFT,
new OGLConstraintType(gyCONSTRAINT_ALIGNED_LEFT, "Left-aligned", "aligned to the left of"));
OGLConstraintTypes.Append(gyCONSTRAINT_ALIGNED_RIGHT,
new OGLConstraintType(gyCONSTRAINT_ALIGNED_RIGHT, "Right-aligned", "aligned to the right of"));
// Mid-alignment
OGLConstraintTypes.Append(gyCONSTRAINT_MIDALIGNED_TOP,
new OGLConstraintType(gyCONSTRAINT_MIDALIGNED_TOP, "Top-midaligned", "centred on the top of"));
OGLConstraintTypes.Append(gyCONSTRAINT_MIDALIGNED_BOTTOM,
new OGLConstraintType(gyCONSTRAINT_MIDALIGNED_BOTTOM, "Bottom-midaligned", "centred on the bottom of"));
OGLConstraintTypes.Append(gyCONSTRAINT_MIDALIGNED_LEFT,
new OGLConstraintType(gyCONSTRAINT_MIDALIGNED_LEFT, "Left-midaligned", "centred on the left of"));
OGLConstraintTypes.Append(gyCONSTRAINT_MIDALIGNED_RIGHT,
new OGLConstraintType(gyCONSTRAINT_MIDALIGNED_RIGHT, "Right-midaligned", "centred on the right of"));
}
/*
* Constraint Stuff
*
*/
IMPLEMENT_DYNAMIC_CLASS(OGLConstraint, wxObject)
OGLConstraint::OGLConstraint(int type, wxShape *constraining, wxList& constrained)
{
m_xSpacing = 0.0;
m_ySpacing = 0.0;
m_constraintType = type;
m_constrainingObject = constraining;
m_constraintId = 0;
m_constraintName = "noname";
wxNode *node = constrained.First();
while (node)
{
m_constrainedObjects.Append(node->Data());
node = node->Next();
}
}
OGLConstraint::~OGLConstraint()
{
}
bool OGLConstraint::Equals(float a, float b)
{
float marg = 0.5;
bool eq = ((b <= a + marg) && (b >= a - marg));
return eq;
}
// Return TRUE if anything changed
bool OGLConstraint::Evaluate()
{
float maxWidth, maxHeight, minWidth, minHeight, x, y;
m_constrainingObject->GetBoundingBoxMax(&maxWidth, &maxHeight);
m_constrainingObject->GetBoundingBoxMin(&minWidth, &minHeight);
x = m_constrainingObject->GetX();
y = m_constrainingObject->GetY();
wxClientDC dc(m_constrainingObject->GetCanvas());
m_constrainingObject->GetCanvas()->PrepareDC(dc);
switch (m_constraintType)
{
case gyCONSTRAINT_CENTRED_VERTICALLY:
{
int n = m_constrainedObjects.Number();
float totalObjectHeight = 0.0;
wxNode *node = m_constrainedObjects.First();
while (node)
{
wxShape *constrainedObject = (wxShape *)node->Data();
float width2, height2;
constrainedObject->GetBoundingBoxMax(&width2, &height2);
totalObjectHeight += height2;
node = node->Next();
}
float startY;
float spacingY;
// Check if within the constraining object...
if ((totalObjectHeight + (n + 1)*m_ySpacing) <= minHeight)
{
spacingY = (float)((minHeight - totalObjectHeight)/(n + 1));
startY = (float)(y - (minHeight/2.0));
}
// Otherwise, use default spacing
else
{
spacingY = m_ySpacing;
startY = (float)(y - ((totalObjectHeight + (n+1)*spacingY)/2.0));
}
// Now position the objects
bool changed = FALSE;
node = m_constrainedObjects.First();
while (node)
{
wxShape *constrainedObject = (wxShape *)node->Data();
float width2, height2;
constrainedObject->GetBoundingBoxMax(&width2, &height2);
startY += (float)(spacingY + (height2/2.0));
if (!Equals(startY, constrainedObject->GetY()))
{
constrainedObject->Move(dc, constrainedObject->GetX(), startY, FALSE);
changed = TRUE;
}
startY += (float)(height2/2.0);
node = node->Next();
}
return changed;
}
case gyCONSTRAINT_CENTRED_HORIZONTALLY:
{
int n = m_constrainedObjects.Number();
float totalObjectWidth = 0.0;
wxNode *node = m_constrainedObjects.First();
while (node)
{
wxShape *constrainedObject = (wxShape *)node->Data();
float width2, height2;
constrainedObject->GetBoundingBoxMax(&width2, &height2);
totalObjectWidth += width2;
node = node->Next();
}
float startX;
float spacingX;
// Check if within the constraining object...
if ((totalObjectWidth + (n + 1)*m_xSpacing) <= minWidth)
{
spacingX = (float)((minWidth - totalObjectWidth)/(n + 1));
startX = (float)(x - (minWidth/2.0));
}
// Otherwise, use default spacing
else
{
spacingX = m_xSpacing;
startX = (float)(x - ((totalObjectWidth + (n+1)*spacingX)/2.0));
}
// Now position the objects
bool changed = FALSE;
node = m_constrainedObjects.First();
while (node)
{
wxShape *constrainedObject = (wxShape *)node->Data();
float width2, height2;
constrainedObject->GetBoundingBoxMax(&width2, &height2);
startX += (float)(spacingX + (width2/2.0));
if (!Equals(startX, constrainedObject->GetX()))
{
constrainedObject->Move(dc, startX, constrainedObject->GetY(), FALSE);
changed = TRUE;
}
startX += (float)(width2/2.0);
node = node->Next();
}
return changed;
}
case gyCONSTRAINT_CENTRED_BOTH:
{
int n = m_constrainedObjects.Number();
float totalObjectWidth = 0.0;
float totalObjectHeight = 0.0;
wxNode *node = m_constrainedObjects.First();
while (node)
{
wxShape *constrainedObject = (wxShape *)node->Data();
float width2, height2;
constrainedObject->GetBoundingBoxMax(&width2, &height2);
totalObjectWidth += width2;
totalObjectHeight += height2;
node = node->Next();
}
float startX;
float spacingX;
float startY;
float spacingY;
// Check if within the constraining object...
if ((totalObjectWidth + (n + 1)*m_xSpacing) <= minWidth)
{
spacingX = (float)((minWidth - totalObjectWidth)/(n + 1));
startX = (float)(x - (minWidth/2.0));
}
// Otherwise, use default spacing
else
{
spacingX = m_xSpacing;
startX = (float)(x - ((totalObjectWidth + (n+1)*spacingX)/2.0));
}
// Check if within the constraining object...
if ((totalObjectHeight + (n + 1)*m_ySpacing) <= minHeight)
{
spacingY = (float)((minHeight - totalObjectHeight)/(n + 1));
startY = (float)(y - (minHeight/2.0));
}
// Otherwise, use default spacing
else
{
spacingY = m_ySpacing;
startY = (float)(y - ((totalObjectHeight + (n+1)*spacingY)/2.0));
}
// Now position the objects
bool changed = FALSE;
node = m_constrainedObjects.First();
while (node)
{
wxShape *constrainedObject = (wxShape *)node->Data();
float width2, height2;
constrainedObject->GetBoundingBoxMax(&width2, &height2);
startX += (float)(spacingX + (width2/2.0));
startY += (float)(spacingY + (height2/2.0));
if ((!Equals(startX, constrainedObject->GetX())) || (!Equals(startY, constrainedObject->GetY())))
{
constrainedObject->Move(dc, startX, startY, FALSE);
changed = TRUE;
}
startX += (float)(width2/2.0);
startY += (float)(height2/2.0);
node = node->Next();
}
return changed;
}
case gyCONSTRAINT_LEFT_OF:
{
bool changed = FALSE;
wxNode *node = m_constrainedObjects.First();
while (node)
{
wxShape *constrainedObject = (wxShape *)node->Data();
float width2, height2;
constrainedObject->GetBoundingBoxMax(&width2, &height2);
float x3 = (float)(x - (minWidth/2.0) - (width2/2.0) - m_xSpacing);
if (!Equals(x3, constrainedObject->GetX()))
{
changed = TRUE;
constrainedObject->Move(dc, x3, constrainedObject->GetY(), FALSE);
}
node = node->Next();
}
return changed;
}
case gyCONSTRAINT_RIGHT_OF:
{
bool changed = FALSE;
wxNode *node = m_constrainedObjects.First();
while (node)
{
wxShape *constrainedObject = (wxShape *)node->Data();
float width2, height2;
constrainedObject->GetBoundingBoxMax(&width2, &height2);
float x3 = (float)(x + (minWidth/2.0) + (width2/2.0) + m_xSpacing);
if (!Equals(x3, constrainedObject->GetX()))
{
changed = TRUE;
constrainedObject->Move(dc, x3, constrainedObject->GetY(), FALSE);
}
node = node->Next();
}
return changed;
return FALSE;
}
case gyCONSTRAINT_ABOVE:
{
bool changed = FALSE;
wxNode *node = m_constrainedObjects.First();
while (node)
{
wxShape *constrainedObject = (wxShape *)node->Data();
float width2, height2;
constrainedObject->GetBoundingBoxMax(&width2, &height2);
float y3 = (float)(y - (minHeight/2.0) - (height2/2.0) - m_ySpacing);
if (!Equals(y3, constrainedObject->GetY()))
{
changed = TRUE;
constrainedObject->Move(dc, constrainedObject->GetX(), y3, FALSE);
}
node = node->Next();
}
return changed;
}
case gyCONSTRAINT_BELOW:
{
bool changed = FALSE;
wxNode *node = m_constrainedObjects.First();
while (node)
{
wxShape *constrainedObject = (wxShape *)node->Data();
float width2, height2;
constrainedObject->GetBoundingBoxMax(&width2, &height2);
float y3 = (float)(y + (minHeight/2.0) + (height2/2.0) + m_ySpacing);
if (!Equals(y3, constrainedObject->GetY()))
{
changed = TRUE;
constrainedObject->Move(dc, constrainedObject->GetX(), y3, FALSE);
}
node = node->Next();
}
return changed;
}
case gyCONSTRAINT_ALIGNED_LEFT:
{
bool changed = FALSE;
wxNode *node = m_constrainedObjects.First();
while (node)
{
wxShape *constrainedObject = (wxShape *)node->Data();
float width2, height2;
constrainedObject->GetBoundingBoxMax(&width2, &height2);
float x3 = (float)(x - (minWidth/2.0) + (width2/2.0) + m_xSpacing);
if (!Equals(x3, constrainedObject->GetX()))
{
changed = TRUE;
constrainedObject->Move(dc, x3, constrainedObject->GetY(), FALSE);
}
node = node->Next();
}
return changed;
}
case gyCONSTRAINT_ALIGNED_RIGHT:
{
bool changed = FALSE;
wxNode *node = m_constrainedObjects.First();
while (node)
{
wxShape *constrainedObject = (wxShape *)node->Data();
float width2, height2;
constrainedObject->GetBoundingBoxMax(&width2, &height2);
float x3 = (float)(x + (minWidth/2.0) - (width2/2.0) - m_xSpacing);
if (!Equals(x3, constrainedObject->GetX()))
{
changed = TRUE;
constrainedObject->Move(dc, x3, constrainedObject->GetY(), FALSE);
}
node = node->Next();
}
return changed;
return FALSE;
}
case gyCONSTRAINT_ALIGNED_TOP:
{
bool changed = FALSE;
wxNode *node = m_constrainedObjects.First();
while (node)
{
wxShape *constrainedObject = (wxShape *)node->Data();
float width2, height2;
constrainedObject->GetBoundingBoxMax(&width2, &height2);
float y3 = (float)(y - (minHeight/2.0) + (height2/2.0) + m_ySpacing);
if (!Equals(y3, constrainedObject->GetY()))
{
changed = TRUE;
constrainedObject->Move(dc, constrainedObject->GetX(), y3, FALSE);
}
node = node->Next();
}
return changed;
}
case gyCONSTRAINT_ALIGNED_BOTTOM:
{
bool changed = FALSE;
wxNode *node = m_constrainedObjects.First();
while (node)
{
wxShape *constrainedObject = (wxShape *)node->Data();
float width2, height2;
constrainedObject->GetBoundingBoxMax(&width2, &height2);
float y3 = (float)(y + (minHeight/2.0) - (height2/2.0) - m_ySpacing);
if (!Equals(y3, constrainedObject->GetY()))
{
changed = TRUE;
constrainedObject->Move(dc, constrainedObject->GetX(), y3, FALSE);
}
node = node->Next();
}
return changed;
}
case gyCONSTRAINT_MIDALIGNED_LEFT:
{
bool changed = FALSE;
wxNode *node = m_constrainedObjects.First();
while (node)
{
wxShape *constrainedObject = (wxShape *)node->Data();
float x3 = (float)(x - (minWidth/2.0));
if (!Equals(x3, constrainedObject->GetX()))
{
changed = TRUE;
constrainedObject->Move(dc, x3, constrainedObject->GetY(), FALSE);
}
node = node->Next();
}
return changed;
}
case gyCONSTRAINT_MIDALIGNED_RIGHT:
{
bool changed = FALSE;
wxNode *node = m_constrainedObjects.First();
while (node)
{
wxShape *constrainedObject = (wxShape *)node->Data();
float x3 = (float)(x + (minWidth/2.0));
if (!Equals(x3, constrainedObject->GetX()))
{
changed = TRUE;
constrainedObject->Move(dc, x3, constrainedObject->GetY(), FALSE);
}
node = node->Next();
}
return changed;
return FALSE;
}
case gyCONSTRAINT_MIDALIGNED_TOP:
{
bool changed = FALSE;
wxNode *node = m_constrainedObjects.First();
while (node)
{
wxShape *constrainedObject = (wxShape *)node->Data();
float y3 = (float)(y - (minHeight/2.0));
if (!Equals(y3, constrainedObject->GetY()))
{
changed = TRUE;
constrainedObject->Move(dc, constrainedObject->GetX(), y3, FALSE);
}
node = node->Next();
}
return changed;
}
case gyCONSTRAINT_MIDALIGNED_BOTTOM:
{
bool changed = FALSE;
wxNode *node = m_constrainedObjects.First();
while (node)
{
wxShape *constrainedObject = (wxShape *)node->Data();
float y3 = (float)(y + (minHeight/2.0));
if (!Equals(y3, constrainedObject->GetY()))
{
changed = TRUE;
constrainedObject->Move(dc, constrainedObject->GetX(), y3, FALSE);
}
node = node->Next();
}
return changed;
}
default:
return FALSE;
}
return FALSE;
}

86
utils/ogl/src/constrnt.h Normal file
View File

@@ -0,0 +1,86 @@
/////////////////////////////////////////////////////////////////////////////
// Name: constrnt.h
// Purpose: OGL constraint definitions
// Author: Julian Smart
// Modified by:
// Created: 12/07/98
// RCS-ID: $Id$
// Copyright: (c) Julian Smart
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef _OGL_CONSTRNT_H_
#define _OGL_CONSTRNT_H_
#ifdef __GNUG__
#pragma interface "constrnt.h"
#endif
/*
* OGL Constraints
*
*/
class OGLConstraintType: public wxObject
{
DECLARE_DYNAMIC_CLASS(OGLConstraintType)
public:
OGLConstraintType(int type = 0, const wxString& name = "", const wxString& phrase = "");
~OGLConstraintType();
public:
int m_type; // E.g. gyCONSTRAINT_CENTRED_VERTICALLY
wxString m_name; // E.g. "Centre vertically"
wxString m_phrase; // E.g. "centred vertically with respect to", "left of"
};
extern wxList OGLConstraintTypes;
#define gyCONSTRAINT_CENTRED_VERTICALLY 1
#define gyCONSTRAINT_CENTRED_HORIZONTALLY 2
#define gyCONSTRAINT_CENTRED_BOTH 3
#define gyCONSTRAINT_LEFT_OF 4
#define gyCONSTRAINT_RIGHT_OF 5
#define gyCONSTRAINT_ABOVE 6
#define gyCONSTRAINT_BELOW 7
#define gyCONSTRAINT_ALIGNED_TOP 8
#define gyCONSTRAINT_ALIGNED_BOTTOM 9
#define gyCONSTRAINT_ALIGNED_LEFT 10
#define gyCONSTRAINT_ALIGNED_RIGHT 11
// Like aligned, but with the objects centred on the respective edge
// of the reference object.
#define gyCONSTRAINT_MIDALIGNED_TOP 12
#define gyCONSTRAINT_MIDALIGNED_BOTTOM 13
#define gyCONSTRAINT_MIDALIGNED_LEFT 14
#define gyCONSTRAINT_MIDALIGNED_RIGHT 15
class OGLConstraint: public wxObject
{
DECLARE_DYNAMIC_CLASS(OGLConstraint)
public:
OGLConstraint() { m_xSpacing = 0.0; m_ySpacing = 0.0; m_constraintType = 0; m_constraintName = ""; m_constraintId = 0;
m_constrainingObject = NULL; }
OGLConstraint(int type, wxShape *constraining, wxList& constrained);
~OGLConstraint();
// Returns TRUE if anything changed
bool Evaluate();
inline void SetSpacing(float x, float y) { m_xSpacing = x; m_ySpacing = y; };
bool Equals(float a, float b);
float m_xSpacing;
float m_ySpacing;
int m_constraintType;
wxString m_constraintName;
long m_constraintId;
wxShape* m_constrainingObject;
wxList m_constrainedObjects;
};
void OGLInitializeConstraintTypes();
#endif
// _OGL_CONSTRNT_H_

729
utils/ogl/src/divided.cpp Normal file
View File

@@ -0,0 +1,729 @@
/////////////////////////////////////////////////////////////////////////////
// Name: divided.cpp
// Purpose: wxDividedShape class
// Author: Julian Smart
// Modified by:
// Created: 12/07/98
// RCS-ID: $Id$
// Copyright: (c) Julian Smart
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "divided.h"
#endif
// 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
#ifdef PROLOGIO
#include <wx/wxexpr.h>
#endif
#include "basic.h"
#include "basicp.h"
#include "canvas.h"
#include "divided.h"
#include "lines.h"
#include "misc.h"
class wxDividedShapeControlPoint: public wxControlPoint
{
DECLARE_DYNAMIC_CLASS(wxDividedShapeControlPoint)
private:
int regionId;
public:
wxDividedShapeControlPoint() { regionId = 0; }
wxDividedShapeControlPoint(wxShapeCanvas *the_canvas, wxShape *object, int region,
float size, float the_xoffset, float the_yoffset, int the_type);
~wxDividedShapeControlPoint();
void OnDragLeft(bool draw, float x, float y, int keys=0, int attachment = 0);
void OnBeginDragLeft(float x, float y, int keys=0, int attachment = 0);
void OnEndDragLeft(float x, float y, int keys=0, int attachment = 0);
};
IMPLEMENT_DYNAMIC_CLASS(wxDividedShapeControlPoint, wxControlPoint)
/*
* Divided object
*
*/
IMPLEMENT_DYNAMIC_CLASS(wxDividedShape, wxRectangleShape)
wxDividedShape::wxDividedShape(float w, float h): wxRectangleShape(w, h)
{
ClearRegions();
}
wxDividedShape::~wxDividedShape()
{
}
void wxDividedShape::OnDraw(wxDC& dc)
{
wxRectangleShape::OnDraw(dc);
}
void wxDividedShape::OnDrawContents(wxDC& dc)
{
float defaultProportion = (float)(GetRegions().Number() > 0 ? (1.0/((float)(GetRegions().Number()))) : 0.0);
float currentY = (float)(m_ypos - (m_height / 2.0));
float maxY = (float)(m_ypos + (m_height / 2.0));
float leftX = (float)(m_xpos - (m_width / 2.0));
float rightX = (float)(m_xpos + (m_width / 2.0));
if (m_pen) dc.SetPen(m_pen);
if (m_textColour) dc.SetTextForeground(* m_textColour);
#ifdef __WXMSW__
// For efficiency, don't do this under X - doesn't make
// any visible difference for our purposes.
if (m_brush)
dc.SetTextBackground(m_brush->GetColour());
#endif
/*
if (!formatted)
{
FormatRegionText();
formatted = TRUE;
}
*/
if (GetDisableLabel()) return;
float xMargin = 2;
float yMargin = 2;
dc.SetBackgroundMode(wxTRANSPARENT);
wxNode *node = GetRegions().First();
while (node)
{
wxShapeRegion *region = (wxShapeRegion *)node->Data();
dc.SetFont(region->GetFont());
dc.SetTextForeground(* region->GetActualColourObject());
float proportion =
region->m_regionProportionY < 0.0 ? defaultProportion : region->m_regionProportionY;
float y = currentY + m_height*proportion;
float actualY = maxY < y ? maxY : y;
float centreX = m_xpos;
float centreY = (float)(currentY + (actualY - currentY)/2.0);
DrawFormattedText(dc, &region->m_formattedText,
(float)(centreX), (float)(centreY), (float)(m_width-2*xMargin), (float)(actualY - currentY - 2*yMargin),
region->m_formatMode);
if ((y <= maxY) && (node->Next()))
{
wxPen *regionPen = region->GetActualPen();
if (regionPen)
{
dc.SetPen(regionPen);
dc.DrawLine(leftX, y, rightX, y);
}
}
currentY = actualY;
node = node->Next();
}
}
void wxDividedShape::SetSize(float w, float h, bool recursive)
{
SetAttachmentSize(w, h);
m_width = w;
m_height = h;
SetRegionSizes();
}
void wxDividedShape::SetRegionSizes()
{
if (GetRegions().Number() == 0)
return;
float defaultProportion = (float)(GetRegions().Number() > 0 ? (1.0/((float)(GetRegions().Number()))) : 0.0);
float currentY = (float)(m_ypos - (m_height / 2.0));
float maxY = (float)(m_ypos + (m_height / 2.0));
// float leftX = (float)(m_xpos - (m_width / 2.0));
// float rightX = (float)(m_xpos + (m_width / 2.0));
wxNode *node = GetRegions().First();
while (node)
{
wxShapeRegion *region = (wxShapeRegion *)node->Data();
float proportion =
region->m_regionProportionY <= 0.0 ? defaultProportion : region->m_regionProportionY;
float sizeY = (float)proportion*m_height;
float y = currentY + sizeY;
float actualY = maxY < y ? maxY : y;
float centreY = (float)(currentY + (actualY - currentY)/2.0);
region->SetSize(m_width, sizeY);
region->SetPosition(0.0, (float)(centreY - m_ypos));
currentY = actualY;
node = node->Next();
}
}
// Attachment points correspond to regions in the divided box
bool wxDividedShape::GetAttachmentPosition(int attachment, float *x, float *y, int nth, int no_arcs,
wxLineShape *line)
{
int totalNumberAttachments = (GetRegions().Number() * 2) + 2;
if (!GetAttachmentMode() || (attachment >= totalNumberAttachments))
{
return wxShape::GetAttachmentPosition(attachment, x, y, nth, no_arcs);
}
int n = GetRegions().Number();
bool isEnd = (line && line->IsEnd(this));
float left = (float)(m_xpos - m_width/2.0);
float right = (float)(m_xpos + m_width/2.0);
float top = (float)(m_ypos - m_height/2.0);
float bottom = (float)(m_ypos + m_height/2.0);
// Zero is top, n+1 is bottom.
if (attachment == 0)
{
*y = top;
if (m_spaceAttachments)
{
if (line && (line->GetAlignmentType(isEnd) == LINE_ALIGNMENT_TO_NEXT_HANDLE))
{
// Align line according to the next handle along
wxRealPoint *point = line->GetNextControlPoint(this);
if (point->x < left)
*x = left;
else if (point->x > right)
*x = right;
else
*x = point->x;
}
else
*x = left + (nth + 1)*m_width/(no_arcs + 1);
}
else
*x = m_xpos;
}
else if (attachment == (n+1))
{
*y = bottom;
if (m_spaceAttachments)
{
if (line && (line->GetAlignmentType(isEnd) == LINE_ALIGNMENT_TO_NEXT_HANDLE))
{
// Align line according to the next handle along
wxRealPoint *point = line->GetNextControlPoint(this);
if (point->x < left)
*x = left;
else if (point->x > right)
*x = right;
else
*x = point->x;
}
else
*x = left + (nth + 1)*m_width/(no_arcs + 1);
}
else
*x = m_xpos;
}
// Left or right.
else
{
int i = 0;
bool isLeft = FALSE;
if (attachment < (n+1))
{
i = attachment-1;
isLeft = FALSE;
}
else
{
i = (totalNumberAttachments - attachment - 1);
isLeft = TRUE;
}
wxNode *node = GetRegions().Nth(i);
if (node)
{
wxShapeRegion *region = (wxShapeRegion *)node->Data();
if (isLeft)
*x = left;
else
*x = right;
// Calculate top and bottom of region
top = (float)((m_ypos + region->m_y) - (region->m_height/2.0));
bottom = (float)((m_ypos + region->m_y) + (region->m_height/2.0));
// Assuming we can trust the absolute size and
// position of these regions...
if (m_spaceAttachments)
{
if (line && (line->GetAlignmentType(isEnd) == LINE_ALIGNMENT_TO_NEXT_HANDLE))
{
// Align line according to the next handle along
wxRealPoint *point = line->GetNextControlPoint(this);
if (point->y < bottom)
*y = bottom;
else if (point->y > top)
*y = top;
else
*y = point->y;
}
else
// *y = (float)(((m_ypos + region->m_y) - (region->m_height/2.0)) + (nth + 1)*region->m_height/(no_arcs+1));
*y = (float)(top + (nth + 1)*region->m_height/(no_arcs+1));
}
else
*y = (float)(m_ypos + region->m_y);
}
else
{
*x = m_xpos;
*y = m_ypos;
return FALSE;
}
}
return TRUE;
}
int wxDividedShape::GetNumberOfAttachments()
{
// There are two attachments for each region (left and right),
// plus one on the top and one on the bottom.
int n = (GetRegions().Number() * 2) + 2;
int maxN = n - 1;
wxNode *node = m_attachmentPoints.First();
while (node)
{
wxAttachmentPoint *point = (wxAttachmentPoint *)node->Data();
if (point->m_id > maxN)
maxN = point->m_id;
node = node->Next();
}
return maxN + 1;
}
bool wxDividedShape::AttachmentIsValid(int attachment)
{
int totalNumberAttachments = (GetRegions().Number() * 2) + 2;
if (attachment >= totalNumberAttachments)
{
return wxShape::AttachmentIsValid(attachment);
}
else if (attachment >= 0)
return TRUE;
else
return FALSE;
}
void wxDividedShape::Copy(wxDividedShape& copy)
{
wxRectangleShape::Copy(copy);
}
wxShape *wxDividedShape::PrivateCopy()
{
wxDividedShape *obj = new wxDividedShape(m_width, m_height);
Copy(*obj);
return obj;
}
// Region operations
void wxDividedShape::MakeControlPoints()
{
wxRectangleShape::MakeControlPoints();
MakeMandatoryControlPoints();
}
void wxDividedShape::MakeMandatoryControlPoints()
{
float currentY = (float)(GetY() - (m_height / 2.0));
float maxY = (float)(GetY() + (m_height / 2.0));
wxNode *node = GetRegions().First();
int i = 0;
while (node)
{
wxShapeRegion *region = (wxShapeRegion *)node->Data();
float proportion = region->m_regionProportionY;
float y = currentY + m_height*proportion;
float actualY = (float)(maxY < y ? maxY : y);
if (node->Next())
{
wxDividedShapeControlPoint *controlPoint =
new wxDividedShapeControlPoint(m_canvas, this, i, CONTROL_POINT_SIZE, 0.0, (float)(actualY - GetY()), 0);
m_canvas->AddShape(controlPoint);
m_controlPoints.Append(controlPoint);
}
currentY = actualY;
i ++;
node = node->Next();
}
}
void wxDividedShape::ResetControlPoints()
{
// May only have the region handles, (n - 1) of them.
if (m_controlPoints.Number() > (GetRegions().Number() - 1))
wxRectangleShape::ResetControlPoints();
ResetMandatoryControlPoints();
}
void wxDividedShape::ResetMandatoryControlPoints()
{
float currentY = (float)(GetY() - (m_height / 2.0));
float maxY = (float)(GetY() + (m_height / 2.0));
wxNode *node = m_controlPoints.First();
int i = 0;
while (node)
{
wxControlPoint *controlPoint = (wxControlPoint *)node->Data();
if (controlPoint->IsKindOf(CLASSINFO(wxDividedShapeControlPoint)))
{
wxNode *node1 = GetRegions().Nth(i);
wxShapeRegion *region = (wxShapeRegion *)node1->Data();
float proportion = region->m_regionProportionY;
float y = currentY + m_height*proportion;
float actualY = (float)(maxY < y ? maxY : y);
controlPoint->m_xoffset = 0.0;
controlPoint->m_yoffset = (float)(actualY - GetY());
currentY = actualY;
i ++;
}
node = node->Next();
}
}
#ifdef PROLOGIO
void wxDividedShape::WritePrologAttributes(wxExpr *clause)
{
wxRectangleShape::WritePrologAttributes(clause);
}
void wxDividedShape::ReadPrologAttributes(wxExpr *clause)
{
wxRectangleShape::ReadPrologAttributes(clause);
}
#endif
/*
* Edit the division colour/style
*
*/
void wxDividedShape::EditRegions()
{
wxMessageBox("EditRegions() is unimplemented.", "OGL", wxOK);
// TODO
#if 0
if (GetRegions().Number() < 2)
return;
wxBeginBusyCursor();
GraphicsForm *form = new GraphicsForm("Divided nodes");
// Need an array to store all the style strings,
// since they need to be converted to integers
char **styleStrings = new char *[GetRegions().Number()];
for (int j = 0; j < GetRegions().Number(); j++)
styleStrings[j] = NULL;
int i = 0;
wxNode *node = GetRegions().First();
while (node && node->Next())
{
wxShapeRegion *region = (wxShapeRegion *)node->Data();
char buf[50];
sprintf(buf, "Region %d", (i+1));
form->Add(wxMakeFormMessage(buf));
form->Add(wxMakeFormNewLine());
form->Add(wxMakeFormString("Colour", &region->penColour, wxFORM_CHOICE,
new wxList(wxMakeConstraintStrings(
"Invisible" ,
"BLACK" ,
"BLUE" ,
"BROWN" ,
"CORAL" ,
"CYAN" ,
"DARK GREY" ,
"DARK GREEN" ,
"DIM GREY" ,
"GREY" ,
"GREEN" ,
"LIGHT BLUE" ,
"LIGHT GREY" ,
"MAGENTA" ,
"MAROON" ,
"NAVY" ,
"ORANGE" ,
"PURPLE" ,
"RED" ,
"TURQUOISE" ,
"VIOLET" ,
"WHITE" ,
"YELLOW" ,
NULL),
NULL), NULL, wxVERTICAL, 150));
char *styleString = NULL;
switch (region->penStyle)
{
case wxSHORT_DASH:
styleString = "Short Dash";
break;
case wxLONG_DASH:
styleString = "Long Dash";
break;
case wxDOT:
styleString = "Dot";
break;
case wxDOT_DASH:
styleString = "Dot Dash";
break;
case wxSOLID:
default:
styleString = "Solid";
break;
}
styleStrings[i] = copystring(styleString);
form->Add(wxMakeFormString("Style", &(styleStrings[i]), wxFORM_CHOICE,
new wxList(wxMakeConstraintStrings(
"Solid" ,
"Short Dash" ,
"Long Dash" ,
"Dot" ,
"Dot Dash" ,
NULL),
NULL), NULL, wxVERTICAL, 100));
node = node->Next();
i ++;
if (node && node->Next())
form->Add(wxMakeFormNewLine());
}
wxDialogBox *dialog = new wxDialogBox(m_canvas->GetParent(), "Divided object properties", 10, 10, 500, 500);
if (GraphicsLabelFont)
dialog->SetLabelFont(GraphicsLabelFont);
if (GraphicsButtonFont)
dialog->SetButtonFont(GraphicsButtonFont);
form->AssociatePanel(dialog);
form->dialog = dialog;
dialog->Fit();
dialog->Centre(wxBOTH);
wxEndBusyCursor();
dialog->Show(TRUE);
node = GetRegions().First();
i = 0;
while (node)
{
wxShapeRegion *region = (wxShapeRegion *)node->Data();
if (styleStrings[i])
{
if (strcmp(styleStrings[i], "Solid") == 0)
region->penStyle = wxSOLID;
else if (strcmp(styleStrings[i], "Dot") == 0)
region->penStyle = wxDOT;
else if (strcmp(styleStrings[i], "Short Dash") == 0)
region->penStyle = wxSHORT_DASH;
else if (strcmp(styleStrings[i], "Long Dash") == 0)
region->penStyle = wxLONG_DASH;
else if (strcmp(styleStrings[i], "Dot Dash") == 0)
region->penStyle = wxDOT_DASH;
delete[] styleStrings[i];
}
region->m_actualPenObject = NULL;
node = node->Next();
i ++;
}
delete[] styleStrings;
Draw(dc);
#endif
}
void wxDividedShape::OnRightClick(float x, float y, int keys, int attachment)
{
if (keys & KEY_CTRL)
{
EditRegions();
}
else
{
wxRectangleShape::OnRightClick(x, y, keys, attachment);
}
}
wxDividedShapeControlPoint::wxDividedShapeControlPoint(wxShapeCanvas *the_canvas, wxShape *object,
int region, float size, float the_m_xoffset, float the_m_yoffset, int the_type):
wxControlPoint(the_canvas, object, size, the_m_xoffset, the_m_yoffset, the_type)
{
regionId = region;
}
wxDividedShapeControlPoint::~wxDividedShapeControlPoint()
{
}
// Implement resizing of divided object division
void wxDividedShapeControlPoint::OnDragLeft(bool draw, float x, float y, int keys, int attachment)
{
wxClientDC dc(GetCanvas());
GetCanvas()->PrepareDC(dc);
dc.SetLogicalFunction(wxXOR);
wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT);
dc.SetPen(dottedPen);
dc.SetBrush((* wxTRANSPARENT_BRUSH));
wxDividedShape *dividedObject = (wxDividedShape *)m_shape;
float x1 = (float)(dividedObject->GetX() - (dividedObject->GetWidth()/2.0));
float y1 = y;
float x2 = (float)(dividedObject->GetX() + (dividedObject->GetWidth()/2.0));
float y2 = y;
dc.DrawLine(x1, y1, x2, y2);
}
void wxDividedShapeControlPoint::OnBeginDragLeft(float x, float y, int keys, int attachment)
{
wxClientDC dc(GetCanvas());
GetCanvas()->PrepareDC(dc);
wxDividedShape *dividedObject = (wxDividedShape *)m_shape;
dc.SetLogicalFunction(wxXOR);
wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT);
dc.SetPen(dottedPen);
dc.SetBrush((* wxTRANSPARENT_BRUSH));
float x1 = (float)(dividedObject->GetX() - (dividedObject->GetWidth()/2.0));
float y1 = y;
float x2 = (float)(dividedObject->GetX() + (dividedObject->GetWidth()/2.0));
float y2 = y;
dc.DrawLine(x1, y1, x2, y2);
m_canvas->CaptureMouse();
}
void wxDividedShapeControlPoint::OnEndDragLeft(float x, float y, int keys, int attachment)
{
wxClientDC dc(GetCanvas());
GetCanvas()->PrepareDC(dc);
wxDividedShape *dividedObject = (wxDividedShape *)m_shape;
wxNode *node = dividedObject->GetRegions().Nth(regionId);
if (!node)
return;
wxShapeRegion *thisRegion = (wxShapeRegion *)node->Data();
wxShapeRegion *nextRegion = NULL; // Region below this one
dc.SetLogicalFunction(wxCOPY);
m_canvas->ReleaseMouse();
// Find the old top and bottom of this region,
// and calculate the new proportion for this region
// if legal.
float currentY = (float)(dividedObject->GetY() - (dividedObject->GetHeight() / 2.0));
float maxY = (float)(dividedObject->GetY() + (dividedObject->GetHeight() / 2.0));
// Save values
float thisRegionTop = 0.0;
float thisRegionBottom = 0.0;
float nextRegionBottom = 0.0;
node = dividedObject->GetRegions().First();
while (node)
{
wxShapeRegion *region = (wxShapeRegion *)node->Data();
float proportion = region->m_regionProportionY;
float yy = currentY + (dividedObject->GetHeight()*proportion);
float actualY = (float)(maxY < yy ? maxY : yy);
if (region == thisRegion)
{
thisRegionTop = currentY;
thisRegionBottom = actualY;
if (node->Next())
nextRegion = (wxShapeRegion *)node->Next()->Data();
}
if (region == nextRegion)
{
nextRegionBottom = actualY;
}
currentY = actualY;
node = node->Next();
}
if (!nextRegion)
return;
// Check that we haven't gone above this region or below
// next region.
if ((y <= thisRegionTop) || (y >= nextRegionBottom))
return;
dividedObject->EraseLinks(dc);
// Now calculate the new proportions of this region and the next region.
float thisProportion = (float)((y - thisRegionTop)/dividedObject->GetHeight());
float nextProportion = (float)((nextRegionBottom - y)/dividedObject->GetHeight());
thisRegion->SetProportions(0.0, thisProportion);
nextRegion->SetProportions(0.0, nextProportion);
m_yoffset = (float)(y - dividedObject->GetY());
// Now reformat text
int i = 0;
node = dividedObject->GetRegions().First();
while (node)
{
wxShapeRegion *region = (wxShapeRegion *)node->Data();
if (region->GetText())
{
char *s = copystring(region->GetText());
dividedObject->FormatText(dc, s, i);
delete[] s;
}
node = node->Next();
i++;
}
dividedObject->SetRegionSizes();
dividedObject->Draw(dc);
dividedObject->GetEventHandler()->OnMoveLinks(dc);
}

77
utils/ogl/src/divided.h Normal file
View File

@@ -0,0 +1,77 @@
/////////////////////////////////////////////////////////////////////////////
// Name: divided.h
// Purpose: wxDividedShape
// Author: Julian Smart
// Modified by:
// Created: 12/07/98
// RCS-ID: $Id$
// Copyright: (c) Julian Smart
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef _OGL_DIVIDED_H_
#define _OGL_DIVIDED_H_
#ifdef __GNUG__
#pragma interface "basic.h"
#endif
/*
* Definition of a region
*
*/
/*
* Box divided into horizontal regions
*
*/
extern wxFont *g_oglNormalFont;
class wxDividedShape: public wxRectangleShape
{
DECLARE_DYNAMIC_CLASS(wxDividedShape)
public:
wxDividedShape(float w = 0.0, float h = 0.0);
~wxDividedShape();
void OnDraw(wxDC& dc);
void OnDrawContents(wxDC& dc);
void SetSize(float w, float h, bool recursive = TRUE);
void MakeControlPoints();
void ResetControlPoints();
void MakeMandatoryControlPoints();
void ResetMandatoryControlPoints();
#ifdef PROLOGIO
// Prolog database stuff
void WritePrologAttributes(wxExpr *clause);
void ReadPrologAttributes(wxExpr *clause);
#endif
void Copy(wxDividedShape &copy);
wxShape *PrivateCopy();
// Set all region sizes according to proportions and
// this object total size
void SetRegionSizes();
// Edit region colours/styles
void EditRegions();
// Attachment points correspond to regions in the divided box
bool GetAttachmentPosition(int attachment, float *x, float *y,
int nth = 0, int no_arcs = 1, wxLineShape *line = NULL);
bool AttachmentIsValid(int attachment);
int GetNumberOfAttachments();
// Invoke editor on CTRL-right click
void OnRightClick(float x, float y, int keys = 0, int attachment = 0);
};
#endif
// _OGL_DIVIDED_H_

1764
utils/ogl/src/drawn.cpp Normal file

File diff suppressed because it is too large Load Diff

119
utils/ogl/src/drawn.h Normal file
View File

@@ -0,0 +1,119 @@
/////////////////////////////////////////////////////////////////////////////
// Name: drawn.h
// Purpose: wxDrawnShape
// Author: Julian Smart
// Modified by:
// Created: 12/07/98
// RCS-ID: $Id$
// Copyright: (c) Julian Smart
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef _OGL_DRAWN_H_
#define _OGL_DRAWN_H_
#ifdef __GNUG__
#pragma interface "drawn.h"
#endif
#include "basic.h"
class wxPseudoMetaFile: public wxObject
{
DECLARE_DYNAMIC_CLASS(wxPseudoMetaFile)
public:
wxPseudoMetaFile();
wxPseudoMetaFile(wxPseudoMetaFile& mf);
~wxPseudoMetaFile();
void Draw(wxDC& dc, float xoffset, float yoffset);
#ifdef PROLOGIO
void WritePrologAttributes(wxExpr *clause);
void ReadPrologAttributes(wxExpr *clause);
#endif
void Clear();
void Copy(wxPseudoMetaFile& copy);
void Scale(float sx, float sy);
void ScaleTo(float w, float h); // Scale to fit size
void Translate(float x, float y);
// Rotate about the given axis by theta radians from the x axis.
void Rotate(float x, float y, float theta);
bool LoadFromMetaFile(char *filename, float *width, float *height);
void GetBounds(float *minX, float *minY, float *maxX, float *maxY);
inline wxList& GetOutlineColours() const { return (wxList&) m_outlineColours; }
inline wxList& GetFillColours() const { return (wxList&) m_fillColours; }
inline void SetRotateable(bool rot) { m_rotateable = rot; }
inline bool GetRotateable() const { return m_rotateable; }
public:
bool m_rotateable;
float m_width;
float m_height;
wxList m_ops; // List of drawing operations (see drawnp.h)
wxList m_gdiObjects; // List of pens, brushes and fonts for this object.
// Pen/brush specifying outline/fill colours
// to override operations.
wxPen* m_outlinePen;
wxBrush* m_fillBrush;
wxList m_outlineColours; // List of the GDI operations that comprise the outline
wxList m_fillColours; // List of the GDI operations that fill the shape
float m_currentRotation;
};
class wxDrawnShape: public wxRectangleShape
{
DECLARE_DYNAMIC_CLASS(wxDrawnShape)
public:
wxDrawnShape();
~wxDrawnShape();
void OnDraw(wxDC& dc);
#ifdef PROLOGIO
// Prolog database stuff
char *GetFunctor();
void WritePrologAttributes(wxExpr *clause);
void ReadPrologAttributes(wxExpr *clause);
#endif
// Does the copying for this object
void Copy(wxDrawnShape& copy);
// Returns a new instance, and does the copy for this class. Define for each class.
wxShape *PrivateCopy();
void Scale(float sx, float sy);
void Translate(float x, float y);
// Rotate about the given axis by theta radians from the x axis.
void Rotate(float x, float y, float theta);
// Get current rotation
inline float GetRotation() const { return m_rotation; }
void SetSize(float w, float h, bool recursive = TRUE);
bool LoadFromMetaFile(char *filename);
inline void SetSaveToFile(bool save) { m_saveToFile = save; }
inline wxPseudoMetaFile& GetMetaFile() const { return (wxPseudoMetaFile&) m_metafile; }
private:
wxPseudoMetaFile m_metafile;
// Don't save all wxDrawnShape metafiles to file: sometimes
// we take the metafile data from a symbol library.
bool m_saveToFile;
};
#endif
// _DRAWN_H_

168
utils/ogl/src/drawnp.h Normal file
View File

@@ -0,0 +1,168 @@
/////////////////////////////////////////////////////////////////////////////
// Name: drawnp.h
// Purpose: Private header for wxDrawnShape
// Author: Julian Smart
// Modified by:
// Created: 12/07/98
// RCS-ID: $Id$
// Copyright: (c) Julian Smart
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef _OGL_DRAWNP_H_
#define _OGL_DRAWNP_H_
#ifdef __GNUG__
#pragma interface "drawnp.h"
#endif
#include "drawn.h"
/*
* Drawing operations
*
*/
#define DRAWOP_SET_PEN 1
#define DRAWOP_SET_BRUSH 2
#define DRAWOP_SET_FONT 3
#define DRAWOP_SET_TEXT_COLOUR 4
#define DRAWOP_SET_BK_COLOUR 5
#define DRAWOP_SET_BK_MODE 6
#define DRAWOP_SET_CLIPPING_RECT 7
#define DRAWOP_DESTROY_CLIPPING_RECT 8
/*
#define DRAWOP_CREATE_PEN 10
#define DRAWOP_CREATE_BRUSH 11
#define DRAWOP_CREATE_FONT 12
*/
#define DRAWOP_DRAW_LINE 20
#define DRAWOP_DRAW_POLYLINE 21
#define DRAWOP_DRAW_POLYGON 22
#define DRAWOP_DRAW_RECT 23
#define DRAWOP_DRAW_ROUNDED_RECT 24
#define DRAWOP_DRAW_ELLIPSE 25
#define DRAWOP_DRAW_POINT 26
#define DRAWOP_DRAW_ARC 27
#define DRAWOP_DRAW_TEXT 28
#define DRAWOP_DRAW_SPLINE 29
/*
* Base, virtual class
*
*/
class wxDrawOp: public wxObject
{
public:
int op;
inline wxDrawOp(int theOp) { op = theOp; }
inline ~wxDrawOp() {}
inline virtual void Scale(float xScale, float yScale) {};
inline virtual void Translate(float x, float y) {};
inline virtual void Rotate(float x, float y, float sinTheta, float cosTheta) {};
virtual void Do(wxDC& dc, float xoffset, float yoffset) = 0;
virtual wxDrawOp *Copy(wxPseudoMetaFile *newImage) = 0;
virtual wxExpr *WritewxExpr(wxPseudoMetaFile *image) = 0;
virtual void ReadwxExpr(wxPseudoMetaFile *image, wxExpr *expr) = 0;
};
/*
* Set font, brush, text colour
*
*/
class wxOpSetGDI: public wxDrawOp
{
public:
int mode;
int gdiIndex;
wxPseudoMetaFile *image;
unsigned char r;
unsigned char g;
unsigned char b;
wxOpSetGDI(int theOp, wxPseudoMetaFile *theImage, int theGdiIndex, int theMode = 0);
void Do(wxDC& dc, float xoffset, float yoffset);
wxDrawOp *Copy(wxPseudoMetaFile *newImage);
wxExpr *WritewxExpr(wxPseudoMetaFile *image);
void ReadwxExpr(wxPseudoMetaFile *image, wxExpr *expr);
};
/*
* Set/destroy clipping
*
*/
class wxOpSetClipping: public wxDrawOp
{
public:
float x1;
float y1;
float x2;
float y2;
wxOpSetClipping(int theOp, float theX1, float theY1, float theX2, float theY2);
void Do(wxDC& dc, float xoffset, float yoffset);
void Scale(float xScale, float yScale);
void Translate(float x, float y);
wxDrawOp *Copy(wxPseudoMetaFile *newImage);
wxExpr *WritewxExpr(wxPseudoMetaFile *image);
void ReadwxExpr(wxPseudoMetaFile *image, wxExpr *expr);
};
/*
* Draw line, rectangle, rounded rectangle, ellipse, point, arc, text
*
*/
class wxOpDraw: public wxDrawOp
{
public:
float x1;
float y1;
float x2;
float y2;
float x3;
float radius;
char *textString;
wxOpDraw(int theOp, float theX1, float theY1, float theX2, float theY2,
float radius = 0.0, char *s = NULL);
~wxOpDraw();
void Do(wxDC& dc, float xoffset, float yoffset);
void Scale(float scaleX, float scaleY);
void Translate(float x, float y);
void Rotate(float x, float y, float sinTheta, float cosTheta);
wxDrawOp *Copy(wxPseudoMetaFile *newImage);
wxExpr *WritewxExpr(wxPseudoMetaFile *image);
void ReadwxExpr(wxPseudoMetaFile *image, wxExpr *expr);
};
/*
* Draw polyline, spline, polygon
*
*/
class wxOpPolyDraw: public wxDrawOp
{
public:
wxRealPoint *points;
int noPoints;
wxOpPolyDraw(int theOp, int n, wxRealPoint *thePoints);
~wxOpPolyDraw();
void Do(wxDC& dc, float xoffset, float yoffset);
void Scale(float scaleX, float scaleY);
void Translate(float x, float y);
void Rotate(float x, float y, float sinTheta, float cosTheta);
wxDrawOp *Copy(wxPseudoMetaFile *newImage);
wxExpr *WritewxExpr(wxPseudoMetaFile *image);
void ReadwxExpr(wxPseudoMetaFile *image, wxExpr *expr);
};
#endif
// _OGL_DRAWNP_H_

2481
utils/ogl/src/lines.cpp Normal file

File diff suppressed because it is too large Load Diff

286
utils/ogl/src/lines.h Normal file
View File

@@ -0,0 +1,286 @@
/////////////////////////////////////////////////////////////////////////////
// Name: lines.h
// Purpose: wxLineShape
// Author: Julian Smart
// Modified by:
// Created: 12/07/98
// RCS-ID: $Id$
// Copyright: (c) Julian Smart
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef _OGL_LINES_H_
#define _OGL_LINES_H_
#ifdef __GNUG__
#pragma interface "lines.h"
#endif
class wxLabelShape;
class wxPseudoMetaFile;
class wxLineControlPoint;
/*
* Arcs with multiple arrowheads
*
*/
// Types of arrowhead
// (i) Built-in
#define ARROW_HOLLOW_CIRCLE 1
#define ARROW_FILLED_CIRCLE 2
#define ARROW_ARROW 3
#define ARROW_SINGLE_OBLIQUE 4
#define ARROW_DOUBLE_OBLIQUE 5
// (ii) Custom
#define ARROW_METAFILE 20
// Position of arrow on line
#define ARROW_POSITION_START 0
#define ARROW_POSITION_END 1
#define ARROW_POSITION_MIDDLE 2
// Line alignment flags
// Vertical by default
#define LINE_ALIGNMENT_HORIZ 1
#define LINE_ALIGNMENT_VERT 0
#define LINE_ALIGNMENT_TO_NEXT_HANDLE 2
#define LINE_ALIGNMENT_NONE 0
class wxArrowHead: public wxObject
{
DECLARE_DYNAMIC_CLASS(wxArrowHead)
public:
wxArrowHead(WXTYPE type = 0, int end = 0, float size = 0.0, float dist = 0.0, const wxString& name = "", wxPseudoMetaFile *mf = NULL,
long arrowId = -1);
~wxArrowHead();
wxArrowHead(wxArrowHead& toCopy);
inline WXTYPE _GetType() const { return m_arrowType; }
inline int GetPosition() const { return m_arrowEnd; }
inline float GetXOffset() const { return m_xOffset; }
inline float GetYOffset() const { return m_yOffset; }
inline float GetSpacing() const { return m_spacing; }
inline float GetSize() const { return m_arrowSize; }
inline wxString GetName() const { return m_arrowName; }
inline void SetXOffset(float x) { m_xOffset = x; }
inline void SetYOffset(float y) { m_yOffset = y; }
inline wxPseudoMetaFile *GetMetaFile() const { return m_metaFile; }
inline long GetId() const { return m_id; }
inline int GetArrowEnd() const { return m_arrowEnd; }
inline float GetArrowSize() const { return m_arrowSize; }
void SetSize(float size);
inline void SetSpacing(float sp) { m_spacing = sp; }
protected:
WXTYPE m_arrowType;
int m_arrowEnd; // Position on line
float m_xOffset; // Distance from arc start or end, w.r.t. point on arrowhead
// nearest start or end. If zero, use default spacing.
float m_yOffset; // vertical offset (w.r.t. a horizontal line). Normally zero.
float m_spacing; // Spacing from the last arrowhead
float m_arrowSize; // Length of arrowhead
wxString m_arrowName; // Name of arrow
bool m_saveToFile; // TRUE if we want to save custom arrowheads to file.
wxPseudoMetaFile* m_metaFile; // Pseudo metafile if this is a custom arrowhead
long m_id; // identifier
};
// Line object
class wxLineShape: public wxShape
{
DECLARE_DYNAMIC_CLASS(wxLineShape)
public:
wxLineShape();
~wxLineShape();
// Called when a connected object has moved, to move the link to
// correct position
// moveControlPoints must be disabled when a control point is being
// dragged.
void OnMoveLink(wxDC& dc, bool moveControlPoints = TRUE);
bool OnMovePre(wxDC& dc, float x, float y, float old_x, float old_y, bool display = TRUE);
void OnDraw(wxDC& dc);
void OnDrawContents(wxDC& dc);
void OnDrawControlPoints(wxDC& dc);
void OnEraseControlPoints(wxDC& dc);
void OnErase(wxDC& dc);
virtual inline void OnMoveControlPoint(int WXUNUSED(which), float WXUNUSED(x), float WXUNUSED(y)) {}
void OnDrawOutline(wxDC& dc, float x, float y, float w, float h);
void GetBoundingBoxMin(float *w, float *h);
void FormatText(wxDC& dc, const wxString& s, int regionId = 0);
virtual void SetEnds(float x1, float y1, float x2, float y2);
virtual void GetEnds(float *x1, float *y1, float *x2, float *y2);
inline virtual wxShape *GetFrom() { return m_from; }
inline virtual wxShape *GetTo() { return m_to; }
inline virtual int GetAttachmentFrom() { return m_attachmentFrom; }
inline virtual int GetAttachmentTo() { return m_attachmentTo; }
virtual void SetFrom(wxShape *object);
virtual void SetTo(wxShape *object);
virtual void DrawArrows(wxDC& dc);
// Finds the x, y points at the two ends of the line.
// This function can be used by e.g. line-routing routines to
// get the actual points on the two node images where the lines will be drawn
// to/from.
void FindLineEndPoints(float *fromX, float *fromY, float *toX, float *toY);
// Format one region at this position
void DrawRegion(wxDC& dc, wxShapeRegion *region, float x, float y);
// Erase one region at this position
void EraseRegion(wxDC& dc, wxShapeRegion *region, float x, float y);
// Get the reference point for a label. Region x and y
// are offsets from this.
// position is 0 (middle), 1 (start), 2 (end)
void GetLabelPosition(int position, float *x, float *y);
// Straighten verticals and horizontals
virtual void Straighten(wxDC& dc);
// Not implemented
inline void SetMaintainStraightLines(bool flag) { m_maintainStraightLines = flag; }
inline bool GetMaintainStraightLines() const { return m_maintainStraightLines; }
// Make handle control points
void MakeControlPoints();
void ResetControlPoints();
// Make a given number of control points
virtual void MakeLineControlPoints(int n);
virtual wxNode *InsertLineControlPoint(wxDC* dc);
virtual bool DeleteLineControlPoint();
virtual void Initialise();
inline wxList *GetLineControlPoints() { return m_lineControlPoints; }
// Override dragging behaviour - don't want to be able to drag lines!
void OnDragLeft(bool draw, float x, float y, int keys=0, int attachment = 0);
void OnBeginDragLeft(float x, float y, int keys=0, int attachment = 0);
void OnEndDragLeft(float x, float y, int keys=0, int attachment = 0);
// Override select, to create/delete temporary label-moving objects
void Select(bool select = TRUE, wxDC* dc = NULL);
// Set to spline (TRUE) or line (FALSE)
inline void SetSpline(bool spl) { m_isSpline = spl; }
inline bool IsSpline() const { return m_isSpline; }
void Unlink();
void SetAttachments(int from_attach, int to_attach);
bool HitTest(float x, float y, int *attachment, float *distance);
#ifdef PROLOGIO
// Prolog database stuff
virtual char *GetFunctor();
virtual void WritePrologAttributes(wxExpr *clause);
virtual void ReadPrologAttributes(wxExpr *clause);
#endif
virtual void FindNth(wxShape *image, int *nth, int *no_arcs, bool incoming);
// Find which position we're talking about at this (x, y).
// Returns ARROW_POSITION_START, ARROW_POSITION_MIDDLE, ARROW_POSITION_END
int FindLinePosition(float x, float y);
// This is really to distinguish between lines and other images.
// For lines, want to pass drag to canvas, since lines tend to prevent
// dragging on a canvas (they get in the way.)
virtual bool Draggable() const { return FALSE; }
// Does the copying for this object
void Copy(wxLineShape& copy);
wxShape *PrivateCopy();
// New OGL stuff
wxArrowHead *AddArrow(WXTYPE type, int end = ARROW_POSITION_END,
float arrowSize = 10.0, float xOffset = 0.0, const wxString& name = "",
wxPseudoMetaFile *mf = NULL, long arrowId = -1);
// Add an arrowhead in the position indicated by the reference
// list of arrowheads, which contains all legal arrowheads for this
// line, in the correct order.
// E.g. reference list: a b c d e
// Current line list: a d
// Add c, then line list is: a c d
// If no legal arrowhead position, return FALSE.
// Assume reference list is for one end only, since it potentially defines
// the ordering for any one of the 3 positions. So we don't check
// the reference list for arrowhead position.
bool AddArrowOrdered(wxArrowHead *arrow, wxList& referenceList, int end);
// Delete arrowhead(s)
void ClearArrowsAtPosition(int end = -1);
bool ClearArrow(const wxString& name);
wxArrowHead *FindArrowHead(int position, const wxString& name);
wxArrowHead *FindArrowHead(long arrowId);
bool DeleteArrowHead(int position, const wxString& name);
bool DeleteArrowHead(long arrowId);
void DrawArrow(wxDC& dc, wxArrowHead *arrow, float xOffset, bool proportionalOffset);
inline void SetIgnoreOffsets(bool ignore) { m_ignoreArrowOffsets = ignore; }
// Find horizontal width for drawing a line with
// arrows in minimum space. Assume arrows at
// END only
float FindMinimumWidth();
// Set alignment flags. ALIGNMENT NOT IMPLEMENTED.
void SetAlignmentOrientation(bool isEnd, bool isHoriz);
void SetAlignmentType(bool isEnd, int alignType);
bool GetAlignmentOrientation(bool isEnd);
int GetAlignmentType(bool isEnd);
// Find next control point in line after the start/end point
// (depending on whether the node object is at start or end)
wxRealPoint *GetNextControlPoint(wxShape *nodeObject);
inline bool IsEnd(wxShape *nodeObject) const { return (m_to == nodeObject); }
private:
bool m_erasing; // flag to say whether we're erasing or drawing
// this line (really so metafiles can draw a
// blank rectangle)
bool m_ignoreArrowOffsets; // Don't always want to draw arrowhead offsets
// because they may not work on tool palettes (for example)
bool m_isSpline;
bool m_maintainStraightLines;
protected:
// Temporary list of line segment orientations
// so we know what direction the line is supposed to be dog-legging
// in. The values are integer: 0 for vertical, 1 for horizontal.
wxList m_lineOrientations;
// Temporary pointers for start, middle and end label editing objects
// (active only when the line is selected)
wxLabelShape* m_labelObjects[3];
// These define the segmented line - not to be confused with temporary control
// points which appear when object is selected (although in this case they'll
// probably be the same)
wxList* m_lineControlPoints;
float m_arrowSpacing; // Separation between adjacent arrows
wxShape* m_to;
wxShape* m_from;
/*
float m_actualTextWidth; // Space the text takes up
float m_actualTextHeight; // (depends on text content unlike nodes)
*/
int m_attachmentTo; // Attachment point at one end
int m_attachmentFrom; // Attachment point at other end
// Alignment flags
int m_alignmentStart;
int m_alignmentEnd;
wxList m_arcArrows;
};
#endif
// _OGL_LINES_H_

83
utils/ogl/src/linesp.h Normal file
View File

@@ -0,0 +1,83 @@
/////////////////////////////////////////////////////////////////////////////
// Name: linesp.h
// Purpose: Lines private header file
// Author: Julian Smart
// Modified by:
// Created: 12/07/98
// RCS-ID: $Id$
// Copyright: (c) Julian Smart
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef _OGL_LINESP_H_
#define _OGL_LINESP_H_
#ifdef __GNUG__
#pragma interface "linesp.h"
#endif
class wxLineControlPoint: public wxControlPoint
{
DECLARE_DYNAMIC_CLASS(wxLineControlPoint)
public:
wxLineControlPoint(wxShapeCanvas *the_canvas = NULL, wxShape *object = NULL, float size = 0.0,
float x = 0.0, float y = 0.0, int the_type = 0);
~wxLineControlPoint();
void OnDraw(wxDC& dc);
void OnDragLeft(bool draw, float x, float y, int keys=0, int attachment = 0);
void OnBeginDragLeft(float x, float y, int keys=0, int attachment = 0);
void OnEndDragLeft(float x, float y, int keys=0, int attachment = 0);
void OnDragRight(bool draw, float x, float y, int keys=0, int attachment = 0);
void OnBeginDragRight(float x, float y, int keys=0, int attachment = 0);
void OnEndDragRight(float x, float y, int keys=0, int attachment = 0);
public:
int m_type;
wxRealPoint* m_point; // Line point
};
/*
* Temporary arc label object
*/
class wxLabelShape: public wxRectangleShape
{
DECLARE_DYNAMIC_CLASS(wxLabelShape)
public:
wxLabelShape(wxLineShape *parent = NULL, wxShapeRegion *region = NULL, float w = 0.0, float h = 0.0);
~wxLabelShape();
void OnDraw(wxDC& dc);
void OnDrawContents(wxDC& dc);
void OnLeftClick(float x, float y, int keys = 0, int attachment = 0);
void OnRightClick(float x, float y, int keys = 0, int attachment = 0);
void OnDragLeft(bool draw, float x, float y, int keys=0, int attachment = 0);
void OnBeginDragLeft(float x, float y, int keys=0, int attachment = 0);
void OnEndDragLeft(float x, float y, int keys=0, int attachment = 0);
bool OnMovePre(wxDC& dc, float x, float y, float old_x, float old_y, bool display = TRUE);
public:
wxLineShape* m_lineShape;
wxShapeRegion* m_shapeRegion;
};
/*
* Get the point on the given line (x1, y1) (x2, y2)
* distance 'length' along from the end,
* returned values in x and y
*/
void GetPointOnLine(float x1, float y1, float x2, float y2,
float length, float *x, float *y);
#endif
// _OGL_LINESP_H_

106
utils/ogl/src/makefile.b32 Normal file
View File

@@ -0,0 +1,106 @@
#
# File: makefile.b32
# Author: Julian Smart
# Created: 1996
# Updated:
# Copyright: (c) 1993, AIAI, University of Edinburgh
#
# "%W% %G%"
#
# Makefile : Builds OGL for BC++, 32-bit.
!if "$(BCCDIR)" == ""
!error You must define the BCCDIR variable in autoexec.bat, e.g. BCCDIR=d:\bc4
!endif
!if "$(WXWIN)" == ""
!error You must define the WXWIN variable in autoexec.bat, e.g. WXWIN=c:\wx
!endif
# Change WXDIR to wherever wxWindows is found
WXDIR = $(WXWIN)
!include $(WXDIR)\src\makeb32.env
WXLIB = $(WXDIR)\lib\wx32.lib
WXINC = $(WXDIR)\include
CFG=$(WXWIN)\src\wxwin32.cfg
OGLDIR = $(WXDIR)\utils\ogl
OGLLIB = $(WXDIR)\lib\ogl.lib
DOCDIR = $(OGLDIR)\docs
INC=/DPROLOGIO=1 # /I$(WXDIR)\include\base /I$(WXDIR)\include\msw
LIBS=$(WXLIB) $(OGLLIB) mathwl cwl import mathwl
!ifndef FINAL
FINAL=0
!endif
!if "$(FINAL)" == "0"
LINKFLAGS=/v /Tpe /L$(WXLIBDIR);$(BCCDIR)\lib
OPT = -Od
DEBUG_FLAGS= -v -DDEBUG=$(DEBUG)
!else
LINKFLAGS=/Tpe /L$(WXLIBDIR);$(BCCDIR)\lib
OPT = -O2
DEBUG_FLAGS = -DDEBUG=$(DEBUG)
!endif
CPPFLAGS=$(DEBUG_FLAGS) $(OPT) @$(CFG)
CFLAGS=$(DEBUG_FLAGS) $(OPT) @$(CFG)
OBJECTS = basic.obj basic2.obj canvas.obj ogldiag.obj lines.obj misc.obj divided.obj constrnt.obj\
composit.obj drawn.obj bitmap.obj mfutils.obj
all: $(OGLLIB)
.$(SRCSUFF).obj:
bcc32 $(CPPFLAGS) $(INC) -c {$< }
$(OGLLIB): $(OBJECTS)
erase $(OGLLIB)
tlib /P128 @&&!
$(OGLLIB) &
+$(OBJECTS:.obj =.obj +)
!
# Making documents
docs: hlp
hlp: $(DOCDIR)/ogl.hlp
hlp32: $(DOCDIR)/hlp32/ogl.hlp
rtf: $(DOCDIR)/ogl.rtf
$(DOCDIR)/ogl.hlp: $(DOCDIR)/ogl.rtf $(DOCDIR)/ogl.hpj
cd $(DOCDIR)
-erase ogl.ph
hc ogl
cd $(THISDIR)
$(DOCDIR)/hlp32/ogl.hlp: $(DOCDIR)/hlp32/ogl.rtf $(DOCDIR)/hlp32/ogl.hpj
cd $(DOCDIR)/hlp32
-erase ogl.ph
start /w hcw /c /e ogl.hpj
cd $(THISDIR)
$(DOCDIR)/ogl.rtf: $(DOCDIR)/classes.tex $(DOCDIR)/intro.tex $(DOCDIR)/ogl.tex
cd $(DOCDIR)
start /w tex2rtf $(DOCDIR)/ogl.tex $(DOCDIR)/ogl.rtf -twice -winhelp
cd $(THISDIR)
$(DOCDIR)/hlp32/ogl.rtf: $(DOCDIR)/classes.tex $(DOCDIR)/intro.tex $(DOCDIR)/ogl.tex
cd $(DOCDIR)
start /w tex2rtf $(DOCDIR)/ogl.tex $(DOCDIR)/hlp32/ogl.rtf -twice -winhelp -macros $(DOCDIR)/t2rtf32.ini
cd $(THISDIR)
wordrtf:
cd $(DOCDIR)
-wx /W tex2rtf $(DOCDIR)/ogl.tex $(DOCDIR)/ogl.rtf -twice -rtf
cd $(THISDIR)
clean:
-erase *.obj
-erase *.exe
-erase *.res
-erase ..\lib\*.lib $(OGLLIB)

105
utils/ogl/src/makefile.bcc Normal file
View File

@@ -0,0 +1,105 @@
#
# File: makefile.bcc
# Author: Julian Smart
# Created: 1996
# Updated:
# Copyright: (c) 1996
#
# "%W% %G%"
#
# Makefile : Builds OGL for BC++, 16-bit.
!if "$(BCCDIR)" == ""
!error You must define the BCCDIR variable in autoexec.bat, e.g. BCCDIR=d:\bc4
!endif
!if "$(WXWIN)" == ""
!error You must define the WXWIN variable in autoexec.bat, e.g. WXWIN=c:\wx
!endif
# Change WXDIR to wherever wxWindows is found
WXDIR = $(WXWIN)
!include $(WXDIR)\src\makebcc.env
WXLIB = $(WXDIR)\lib\wx.lib
WXINC = $(WXDIR)\include
CFG=$(WXWIN)\src\wxwin.cfg
OGLDIR = $(WXDIR)\utils\ogl
OGLLIB = $(OGLDIR)\lib\ogl.lib
DOCDIR = $(OGLDIR)\docs
INC=/DPROLOGIO=1 # /I$(WXDIR)\include\base /I$(WXDIR)\include\msw
LIBS=$(WXLIB) $(OGLLIB) mathwl cwl import mathwl
!ifndef FINAL
FINAL=0
!endif
!if "$(FINAL)" == "0"
LINKFLAGS=/v/Vt /Twe /L$(WXDIR)\lib;$(BCCDIR)\lib
OPT = -Od
DEBUG_FLAGS= -v
!else
LINKFLAGS=/Twe /L$(WXDIR)\lib;$(BCCDIR)\lib
OPT = -O2
DEBUG_FLAGS=
!endif
CPPFLAGS=$(DEBUG_FLAGS) $(OPT) @$(CFG)
CFLAGS=$(DEBUG_FLAGS) $(OPT) @$(CFG)
OBJECTS = basic.obj basic2.obj canvas.obj ogldiag.obj lines.obj misc.obj divided.obj constrnt.obj\
composit.obj drawn.obj bitmap.obj mfutils.obj
all: $(OGLLIB)
.$(SRCSUFF).obj:
bcc $(CPPFLAGS) $(INC) -c {$< }
$(OGLLIB): $(OBJECTS)
erase $(OGLLIB)
tlib /P128 @&&!
$(OGLLIB) &
+$(OBJECTS:.obj =.obj +)
!
# Making documents
docs: hlp
hlp: $(DOCDIR)/ogl.hlp
hlp32: $(DOCDIR)/hlp32/ogl.hlp
rtf: $(DOCDIR)/ogl.rtf
$(DOCDIR)/ogl.hlp: $(DOCDIR)/ogl.rtf $(DOCDIR)/ogl.hpj
cd $(DOCDIR)
-erase ogl.ph
hc ogl
cd $(THISDIR)
$(DOCDIR)/hlp32/ogl.hlp: $(DOCDIR)/hlp32/ogl.rtf $(DOCDIR)/hlp32/ogl.hpj
cd $(DOCDIR)/hlp32
-erase ogl.ph
start /w hcw /c /e ogl.hpj
cd $(THISDIR)
$(DOCDIR)/ogl.rtf: $(DOCDIR)/classes.tex $(DOCDIR)/intro.tex $(DOCDIR)/ogl.tex
cd $(DOCDIR)
start /w tex2rtf $(DOCDIR)/ogl.tex $(DOCDIR)/ogl.rtf -twice -winhelp
cd $(THISDIR)
$(DOCDIR)/hlp32/ogl.rtf: $(DOCDIR)/classes.tex $(DOCDIR)/intro.tex $(DOCDIR)/ogl.tex
cd $(DOCDIR)
start /w tex2rtf $(DOCDIR)/ogl.tex $(DOCDIR)/hlp32/ogl.rtf -twice -winhelp -macros $(DOCDIR)/t2rtf32.ini
cd $(THISDIR)
wordrtf:
cd $(DOCDIR)
-wx /W tex2rtf $(DOCDIR)/ogl.tex $(DOCDIR)/ogl.rtf -twice -rtf
cd $(THISDIR)
clean:
-erase *.obj
-erase *.exe
-erase *.res
-erase ..\lib\*.lib

161
utils/ogl/src/makefile.dos Normal file
View File

@@ -0,0 +1,161 @@
#
# File: makefile.dos
# Author: Julian Smart
# Created: 1993
# Updated:
# Copyright: (c) 1993, AIAI, University of Edinburgh
#
# "%W% %G%"
#
# Makefile: Builds object graphics library (DOS).
# Use FINAL=1 argument to nmake to build final version with no debugging
# info
# Set WXDIR for your system
WXDIR = $(WXWIN)
!include $(WXDIR)\src\makemsc.env
OGLDIR = $(WXDIR)\utils\ogl
THISDIR = $(OGLDIR)\src
DOCDIR = $(OGLDIR)\docs
WXLIB = $(WXDIR)\lib\wx.lib
LIBS=$(WXLIB) libw llibcew commdlg shell ctl3dv2
GRAPHICSLIB = $(WXDIR)\lib\ogl.lib
INC = /I$(WXDIR)\include
# Normally set OPTIONS =
# to disable PROLOGIO-dependent code
OPTIONS = -DPROLOGIO
OBJECTS = basic.obj basic2.obj canvas.obj ogldiag.obj lines.obj misc.obj divided.obj constrnt.obj\
composit.obj drawn.obj bitmap.obj mfutils.obj
all: $(GRAPHICSLIB)
wx:
cd $(WXDIR)\src\msw
nmake -f makefile.dos $(WXLIB) FINAL=$(FINAL)
cd $(THISDIR)
$(GRAPHICSLIB): $(OBJECTS)
erase $(GRAPHICSLIB)
lib /PAGESIZE:128 @<<
$(GRAPHICSLIB)
y
$(OBJECTS)
nul
;
<<
# NOTE: This causes a floating point stack error when optimized,
# so DON'T optimize!
basic.obj: basic.$(SRCSUFF) basic.h lines.h misc.h canvas.h
cl @<<
$(CPPFLAGS) /Od /c /Tp $*.$(SRCSUFF)
<<
basic2.obj: basic2.$(SRCSUFF) basic.h lines.h misc.h canvas.h
cl @<<
$(CPPFLAGS) /Od /c /Tp $*.$(SRCSUFF)
<<
canvas.obj: canvas.$(SRCSUFF) basic.h misc.h canvas.h
cl @<<
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
<<
ogldiag.obj: ogldiag.$(SRCSUFF) ogldiag.h canvas.h basic.h
cl @<<
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
<<
lines.obj: lines.$(SRCSUFF) basic.h misc.h canvas.h lines.h basicp.h linesp.h
cl @<<
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
<<
misc.obj: misc.$(SRCSUFF) basic.h misc.h constrnt.h basicp.h
cl @<<
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
<<
divided.obj: divided.$(SRCSUFF) basic.h misc.h canvas.h divided.h basicp.h
cl @<<
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
<<
constrnt.obj: constrnt.$(SRCSUFF) basic.h constrnt.h
cl @<<
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
<<
composit.obj: composit.$(SRCSUFF) basic.h misc.h canvas.h constrnt.h composit.h basicp.h
cl @<<
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
<<
drawn.obj: drawn.$(SRCSUFF) basic.h misc.h canvas.h drawn.h drawnp.h basicp.h
cl @<<
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
<<
bitmap.obj: bitmap.$(SRCSUFF) basic.h misc.h canvas.h bitmap.h
cl @<<
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
<<
mfutils.obj: mfutils.$(SRCSUFF) mfutils.h
cl @<<
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
<<
# Making documents
docs: hlp
hlp: $(DOCDIR)/ogl.hlp
hlp32: $(DOCDIR)/hlp32/ogl.hlp
rtf: $(DOCDIR)/ogl.rtf
$(DOCDIR)/ogl.hlp: $(DOCDIR)/ogl.rtf $(DOCDIR)/ogl.hpj
cd $(DOCDIR)
-erase ogl.ph
hc ogl
cd $(THISDIR)
$(DOCDIR)/hlp32/ogl.hlp: $(DOCDIR)/hlp32/ogl.rtf $(DOCDIR)/hlp32/ogl.hpj
cd $(DOCDIR)/hlp32
-erase ogl.ph
start /w hcw /c /e ogl.hpj
cd $(THISDIR)
$(DOCDIR)/ogl.rtf: $(DOCDIR)/classes.tex $(DOCDIR)/intro.tex $(DOCDIR)/ogl.tex
cd $(DOCDIR)
start /w tex2rtf $(DOCDIR)/ogl.tex $(DOCDIR)/ogl.rtf -twice -winhelp
cd $(THISDIR)
$(DOCDIR)/hlp32/ogl.rtf: $(DOCDIR)/classes.tex $(DOCDIR)/intro.tex $(DOCDIR)/ogl.tex
cd $(DOCDIR)
start /w tex2rtf $(DOCDIR)/ogl.tex $(DOCDIR)/hlp32/ogl.rtf -twice -winhelp -macros $(DOCDIR)/t2rtf32.ini
cd $(THISDIR)
wordrtf:
cd $(DOCDIR)
-wx /W tex2rtf $(DOCDIR)/ogl.tex $(DOCDIR)/ogl.rtf -twice -rtf
cd $(THISDIR)
clean:
-erase *.obj
-erase *.sbr
-erase *.exe
-erase *.res
-erase *.map
-erase *.pdb
-erase *.lib
-erase ..\lib\*.lib
wxclean:
cd $(WXDIR)\src\msw
nmake -f makefile.dos clean
cd $(THISDIR)

180
utils/ogl/src/makefile.nt Normal file
View File

@@ -0,0 +1,180 @@
#
# File: makefile.nt
# Author: Julian Smart
# Created: 1993
# Updated:
# Copyright: (c) 1993, AIAI, University of Edinburgh
#
# "%W% %G%"
#
# Makefile : Builds OGL classes library (MS VC++).
# Use FINAL=1 argument to nmake to build final version with no debugging
# info
# Set WXDIR for your system
WXDIR = $(WXWIN)
OBJECTSDIR = $(WXDIR)\utils\ogl
THISDIR = $(WXDIR)\utils\ogl\src
EXTRALIBS=$(WXDIR)\lib\ogl.lib $(WXDIR)\lib\mfutils.lib
EXTRAINC=/I$(WXDIR)\utils\mfutils\src /I$(WXDIR)\utils\prologio\src
EXTRAFLAGS=/DPROLOGIO=1
DOCDIR=$(WXDIR)\docs
LOCALDOCDIR=$(WXDIR)\utils\ogl\docs
!include $(WXDIR)\src\ntwxwin.mak
PROGRAM=test
OBJECTS = basic.obj basic2.obj canvas.obj ogldiag.obj lines.obj misc.obj divided.obj constrnt.obj\
composit.obj drawn.obj bitmap.obj mfutils.obj
LIBTARGET=$(WXDIR)\lib\ogl.lib
all: $(LIBTARGET)
$(PROGRAM): $(PROGRAM).exe
wx:
cd $(WXDIR)\src\msw
nmake -f makefile.nt FINAL=$(FINAL)
cd $(THISDIR)
wxclean:
cd $(WXDIR)\src\msw
nmake -f makefile.nt clean
cd $(THISDIR)
$(LIBTARGET): $(OBJECTS)
-erase $(LIBTARGET)
$(implib) @<<
-out:$(LIBTARGET)
-machine:$(CPU)
$(OBJECTS)
<<
# NOTE: This causes a floating point stack error when optimized,
# so DON'T optimize!
basic.obj: basic.$(SRCSUFF) basic.h lines.h misc.h canvas.h
cl @<<
$(CPPFLAGS) /Od /c /Tp $*.$(SRCSUFF)
<<
basic2.obj: basic2.$(SRCSUFF) basic.h lines.h misc.h canvas.h
cl @<<
$(CPPFLAGS) /Od /c /Tp $*.$(SRCSUFF)
<<
canvas.obj: canvas.$(SRCSUFF) basic.h misc.h canvas.h
cl @<<
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
<<
ogldiag.obj: ogldiag.$(SRCSUFF) ogldiag.h canvas.h basic.h
cl @<<
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
<<
lines.obj: lines.$(SRCSUFF) basic.h misc.h canvas.h lines.h basicp.h linesp.h
cl @<<
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
<<
misc.obj: misc.$(SRCSUFF) basic.h misc.h constrnt.h basicp.h
cl @<<
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
<<
divided.obj: divided.$(SRCSUFF) basic.h misc.h canvas.h divided.h basicp.h
cl @<<
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
<<
constrnt.obj: constrnt.$(SRCSUFF) basic.h constrnt.h
cl @<<
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
<<
composit.obj: composit.$(SRCSUFF) basic.h misc.h canvas.h constrnt.h composit.h basicp.h
cl @<<
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
<<
drawn.obj: drawn.$(SRCSUFF) basic.h misc.h canvas.h drawn.h drawnp.h basicp.h
cl @<<
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
<<
bitmap.obj: bitmap.$(SRCSUFF) basic.h misc.h canvas.h bitmap.h
cl @<<
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
<<
mfutils.obj: mfutils.$(SRCSUFF) mfutils.h
cl @<<
$(CPPFLAGS) /c /Tp $*.$(SRCSUFF)
<<
clean:
-erase *.obj
-erase *.sbr
-erase *.exe
-erase *.res
-erase *.map
-erase *.pdb
-erase $(LIBTARGET)
DOCSOURCES=$(LOCALDOCDIR)\ogl.tex \
$(LOCALDOCDIR)\bugs.tex $(LOCALDOCDIR)\changes.tex\
$(LOCALDOCDIR)\classes.tex $(LOCALDOCDIR)\intro.tex\
$(LOCALDOCDIR)\topics.tex $(LOCALDOCDIR)\sample.tex
html: $(DOCDIR)\html\ogl\ogl.htm
hlp: $(DOCDIR)\winhelp\ogl.hlp
pdfrtf: $(DOCDIR)\pdf\ogl.rtf
ps: $(DOCDIR)\ps\ogl.ps
$(DOCDIR)\winhelp\ogl.hlp: $(LOCALDOCDIR)\ogl.rtf $(LOCALDOCDIR)\ogl.hpj
cd $(LOCALDOCDIR)
-erase ogl.ph
hc ogl
move ogl.hlp $(DOCDIR)\winhelp\ogl.hlp
move ogl.cnt $(DOCDIR)\winhelp\ogl.cnt
cd $(THISDIR)
$(LOCALDOCDIR)\ogl.rtf: $(DOCSOURCES)
cd $(LOCALDOCDIR)
-start /w tex2rtf $(LOCALDOCDIR)\ogl.tex $(LOCALDOCDIR)\ogl.rtf -twice -winhelp
cd $(THISDIR)
$(DOCDIR)\pdf\ogl.rtf: $(DOCSOURCES)
cd $(LOCALDOCDIR)
-copy *.bmp $(DOCDIR)\pdf
-start /w tex2rtf $(LOCALDOCDIR)\ogl.tex $(DOCDIR)\pdf\ogl.rtf -twice -rtf
cd $(THISDIR)
$(DOCDIR)\html\ogl\ogl.htm: $(DOCSOURCES)
cd $(LOCALDOCDIR)
-mkdir $(DOCDIR)\html\ogl
cp *.gif $(DOCDIR)\html\ogl
-start /w tex2rtf $(LOCALDOCDIR)\ogl.tex $(DOCDIR)\html\ogl\ogl.htm -twice -html
-erase $(DOCDIR)\html\ogl\*.con
-erase $(DOCDIR)\html\ogl\*.ref
cd $(THISDIR)
$(LOCALDOCDIR)\ogl.dvi: $(DOCSOURCES)
cd $(LOCALDOCDIR)
-latex ogl
-latex ogl
-makeindx ogl
-bibtex ogl
-latex ogl
-latex ogl
cd $(THISDIR)
$(WXDIR)\docs\ps\ogl.ps: $(LOCALDOCDIR)\ogl.dvi
cd $(LOCALDOCDIR)
-dvips32 -o ogl.ps ogl
move ogl.ps $(WXDIR)\docs\ps\ogl.ps
cd $(THISDIR)

125
utils/ogl/src/makefile.unx Normal file
View File

@@ -0,0 +1,125 @@
#
# File: makefile.unx
# Author: Julian Smart
# Created: 1996
# Updated:
# Copyright: (c) 1996 Julian Smart
#
# "%W% %G%"
#
# Makefile for object graphics library (UNIX).
WXDIR = ../../..
# All common UNIX compiler flags and options are now in
# this central makefile.
include $(WXDIR)/src/make.env
PRODIR = $(WXDIR)/utils/prologio
PROINC = $(PRODIR)/src
PROLIB = $(PRODIR)/lib/libproio$(GUISUFFIX).a
MFDIR = $(WXDIR)/utils/mfutils
MFINC = $(MFDIR)/src
OGLDIR = $(WXDIR)/utils/ogl
OGLLIB = $(OGLDIR)/lib/libogl$(GUISUFFIX).a
OBJECTS = $(OBJDIR)/basic.o $(OBJDIR)/basic2.o $(OBJDIR)/canvas.o $(OBJDIR)/lines.o $(OBJDIR)/misc.o\
$(OBJDIR)/divided.o $(OBJDIR)/constrnt.o $(OBJDIR)/composit.o $(OBJDIR)/drawn.o\
$(OBJDIR)/bitmap.o $(OBJDIR)/ogldiag.o
CPPFLAGS = -I$(PROINC) -I$(MFINC) $(XINCLUDE) $(INC) $(GUI) -DDEBUG='$(DEBUG)' $(DEBUGFLAGS) $(WARN) $(OPTIONS) -DPROLOGIO
all: $(OBJDIR) $(OGLLIB)
.SUFFIXES:
wx:
cd $(WXDIR)/src/x; $(MAKE) -f makefile.unx OPT=$(OPT) GUI=$(GUI)
motif:
$(MAKE) -f makefile.unx GUI=-Dwx_motif OPT=$(OPT) GUISUFFIX=_motif LDLIBS='$(MOTIFLDLIBS)' XVIEW_LINK=
xview:
$(MAKE) -f makefile.unx GUI=-Dwx_xview OPT=$(OPT) GUISUFFIX=_ol
hp:
$(MAKE) -f makefile.unx GUI=-Dwx_motif GUISUFFIX=_hp CC=CC DEBUG='$(DEBUG)' DEBUGFLAGS='-g' OPT='' WARN='-w' \
XINCLUDE='$(HPXINCLUDE)' XLIB='$(HPXLIB)' XVIEW_LINK='' \
LDLIBS='$(HPLDLIBS)'
$(OBJDIR):
mkdir $(OBJDIR)
$(OGLLIB): $(OBJECTS)
rm -f $@
ar $(AROPTIONS) $@ $(OBJECTS)
$(RANLIB) $@
$(OBJDIR)/basic.o: basic.$(SRCSUFF) basic.h lines.h misc.h canvas.h
$(CC) -c $(CPPFLAGS) -o $@ basic.$(SRCSUFF)
$(OBJDIR)/basic2.o: basic2.$(SRCSUFF) basic.h lines.h misc.h canvas.h
$(CC) -c $(CPPFLAGS) -o $@ basic2.$(SRCSUFF)
$(OBJDIR)/canvas.o: canvas.$(SRCSUFF) basic.h misc.h canvas.h
$(CC) -c $(CPPFLAGS) -o $@ canvas.$(SRCSUFF)
$(OBJDIR)/lines.o: lines.$(SRCSUFF) basic.h misc.h canvas.h lines.h
$(CC) -c $(CPPFLAGS) -o $@ lines.$(SRCSUFF)
$(OBJDIR)/misc.o: misc.$(SRCSUFF) basic.h misc.h constrnt.h
$(CC) -c $(CPPFLAGS) -o $@ misc.$(SRCSUFF)
$(OBJDIR)/divided.o: divided.$(SRCSUFF) basic.h misc.h canvas.h divided.h
$(CC) -c $(CPPFLAGS) -o $@ divided.$(SRCSUFF)
$(OBJDIR)/constrnt.o: constrnt.$(SRCSUFF) basic.h constrnt.h
$(CC) -c $(CPPFLAGS) -o $@ constrnt.$(SRCSUFF)
$(OBJDIR)/composit.o: composit.$(SRCSUFF) basic.h misc.h canvas.h constrnt.h composit.h
$(CC) -c $(CPPFLAGS) -o $@ composit.$(SRCSUFF)
$(OBJDIR)/drawn.o: drawn.$(SRCSUFF) basic.h misc.h canvas.h drawn.h drawnp.h
$(CC) -c $(CPPFLAGS) -o $@ drawn.$(SRCSUFF)
$(OBJDIR)/bitmap.o: bitmap.$(SRCSUFF) basic.h misc.h canvas.h bitmap.h
$(CC) -c $(CPPFLAGS) -o $@ bitmap.$(SRCSUFF)
$(OBJDIR)/ogldiag.o: ogldiag.$(SRCSUFF) basic.h misc.h canvas.h bitmap.h ogldiag.h
$(CC) -c $(CPPFLAGS) -o $@ ogldiag.$(SRCSUFF)
HTMLDIR=/home/hardy/html/wx/manuals
docs: ps xlp
ps: $(OGLDIR)/docs/ogl.ps
xlp: $(OGLDIR)/docs/ogl.xlp
html: $(HTMLDIR)/ogl/ogl_contents.html
$(OGLDIR)/docs/ogl.xlp: $(OGLDIR)/docs/classes.tex $(OGLDIR)/docs/ogl.tex $(OGLDIR)/docs/topics.tex $(OGLDIR)/docs/changes.tex $(OGLDIR)/docs/intro.tex
cd ../docs; tex2rtf ogl.tex tmp.xlp -xlp -twice
sed -e "s/WXHELPCONTENTS/OGL Manual/g" < $(OGLDIR)/docs/tmp.xlp > $(OGLDIR)/docs/ogl.xlp
/bin/rm -f $(OGLDIR)/docs/tmp.xlp
$(HTMLDIR)/ogl/ogl_contents.html: $(OGLDIR)/docs/classes.tex $(OGLDIR)/docs/ogl.tex $(OGLDIR)/docs/topics.tex $(OGLDIR)/docs/changes.tex $(OGLDIR)/docs/intro.tex
cd ../docs; tex2rtf ogl.tex $(HTMLDIR)/ogl/ogl -twice -html
$(OGLDIR)/docs/ogl.dvi: $(OGLDIR)/docs/ogl.tex $(OGLDIR)/docs/classes.tex $(OGLDIR)/docs/topics.tex $(OGLDIR)/docs/changes.tex $(OGLDIR)/docs/intro.tex
cd $(OGLDIR)/docs; latex ogl; latex ogl; makeindex ogl; latex ogl; \
$(OGLDIR)/docs/ogl.ps: $(OGLDIR)/docs/ogl.dvi
cd $(OGLDIR)/docs; dvips -f -r < ogl.dvi > ogl.ps
cleaneach:
rm -f $(OBJECTS) $(OGLLIB) core
clean_motif:
$(MAKE) -f makefile.unx GUISUFFIX=_motif cleaneach
clean_ol:
$(MAKE) -f makefile.unx GUISUFFIX=_ol cleaneach
clean_hp:
$(MAKE) -f makefile.unx GUISUFFIX=_hp cleaneach

View File

@@ -0,0 +1,28 @@
# Objects makefile
WXDIR = ..\..\..
!include $(WXDIR)\src\makewat.env
EXTRACPPFLAGS=/DPROLOGIO
OBJECTSLIB = $(WXDIR)\utils\objects\lib\graphics.lib
THISDIR = $(WXDIR)\utils\objects\src
NAME = graphics
LNK = $(name).lnk
IFLAGS = -i=$(WXINC) -i=$(WXBASEINC) -i=..\..\mfutils\src -i=..\..\prologio\src
OBJECTS = basic.obj basic2.obj canvas.obj lines.obj misc.obj divided.obj constrnt.obj composit.obj drawn.obj bitmap.obj
all: $(OBJECTSLIB)
$(OBJECTSLIB): $(OBJECTS)
*wlib /b /c /n /P=256 $(OBJECTSLIB) $(OBJECTS)
clean: .SYMBOLIC
-erase *.obj *.bak *.err *.pch $(OBJECTSLIB) *.lbc

1085
utils/ogl/src/mfutils.cpp Normal file

File diff suppressed because it is too large Load Diff

211
utils/ogl/src/mfutils.h Normal file
View File

@@ -0,0 +1,211 @@
/////////////////////////////////////////////////////////////////////////////
// Name: mfutils.h
// Purpose: Metafile utilities: reading a placeable metafile independently
// of Windows.
// Author: Julian Smart
// Modified by:
// Created: 12/07/98
// RCS-ID: $Id$
// Copyright: (c) Julian Smart
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef _MFUTILS_H_
#define _MFUTILS_H_
#ifdef __GNUG__
#pragma interface "mfutils.h"
#endif
#include <wx/metafile.h>
#ifndef __WXMSW__
#define GetRValue(rgb) ((unsigned char)(rgb))
#define GetGValue(rgb) ((unsigned char)(((int)(rgb)) >> 8))
#define GetBValue(rgb) ((unsigned char)((rgb)>>16))
#endif
/* Metafile Functions */
/* Win32s/Borland need these macros, although META_SETBKCOLOR is defined */
#if !defined(META_SETBKCOLOR) || defined(WIN32)
#define META_SETBKCOLOR 0x0201
#define META_SETBKMODE 0x0102
#define META_SETMAPMODE 0x0103
#define META_SETROP2 0x0104
#define META_SETRELABS 0x0105
#define META_SETPOLYFILLMODE 0x0106
#define META_SETSTRETCHBLTMODE 0x0107
#define META_SETTEXTCHAREXTRA 0x0108
#define META_SETTEXTCOLOR 0x0209
#define META_SETTEXTJUSTIFICATION 0x020A
#define META_SETWINDOWORG 0x020B
#define META_SETWINDOWEXT 0x020C
#define META_SETVIEWPORTORG 0x020D
#define META_SETVIEWPORTEXT 0x020E
#define META_OFFSETWINDOWORG 0x020F
#define META_SCALEWINDOWEXT 0x0410
#define META_OFFSETVIEWPORTORG 0x0211
#define META_SCALEVIEWPORTEXT 0x0412
#define META_LINETO 0x0213
#define META_MOVETO 0x0214
#define META_EXCLUDECLIPRECT 0x0415
#define META_INTERSECTCLIPRECT 0x0416
#define META_ARC 0x0817
#define META_ELLIPSE 0x0418
#define META_FLOODFILL 0x0419
#define META_PIE 0x081A
#define META_RECTANGLE 0x041B
#define META_ROUNDRECT 0x061C
#define META_PATBLT 0x061D
#define META_SAVEDC 0x001E
#define META_SETPIXEL 0x041F
#define META_OFFSETCLIPRGN 0x0220
#define META_TEXTOUT 0x0521
#define META_BITBLT 0x0922
#define META_STRETCHBLT 0x0B23
#define META_POLYGON 0x0324
#define META_POLYLINE 0x0325
#define META_ESCAPE 0x0626
#define META_RESTOREDC 0x0127
#define META_FILLREGION 0x0228
#define META_FRAMEREGION 0x0429
#define META_INVERTREGION 0x012A
#define META_PAINTREGION 0x012B
#define META_SELECTCLIPREGION 0x012C
#define META_SELECTOBJECT 0x012D
#define META_SETTEXTALIGN 0x012E
#define META_DRAWTEXT 0x062F
#define META_CHORD 0x0830
#define META_SETMAPPERFLAGS 0x0231
#define META_EXTTEXTOUT 0x0a32
#define META_SETDIBTODEV 0x0d33
#define META_SELECTPALETTE 0x0234
#define META_REALIZEPALETTE 0x0035
#define META_ANIMATEPALETTE 0x0436
#define META_SETPALENTRIES 0x0037
#define META_POLYPOLYGON 0x0538
#define META_RESIZEPALETTE 0x0139
#define META_DIBBITBLT 0x0940
#define META_DIBSTRETCHBLT 0x0b41
#define META_DIBCREATEPATTERNBRUSH 0x0142
#define META_STRETCHDIB 0x0f43
#define META_EXTFLOODFILL 0x0548
#define META_RESETDC 0x014C
#define META_STARTDOC 0x014D
#define META_STARTPAGE 0x004F
#define META_ENDPAGE 0x0050
#define META_ABORTDOC 0x0052
#define META_ENDDOC 0x005E
#define META_DELETEOBJECT 0x01f0
#define META_CREATEPALETTE 0x00f7
#define META_CREATEBRUSH 0x00F8
#define META_CREATEPATTERNBRUSH 0x01F9
#define META_CREATEPENINDIRECT 0x02FA
#define META_CREATEFONTINDIRECT 0x02FB
#define META_CREATEBRUSHINDIRECT 0x02FC
#define META_CREATEBITMAPINDIRECT 0x02FD
#define META_CREATEBITMAP 0x06FE
#define META_CREATEREGION 0x06FF
/* Background Modes */
#define TRANSPARENT 1
#define OPAQUE 2
/* Pen Styles */
#define PS_SOLID 0
#define PS_DASH 1
#define PS_DOT 2
#define PS_DASHDOT 3
#define PS_DASHDOTDOT 4
#define PS_NULL 5
#define PS_INSIDEFRAME 6
/* PitchAndFamily family values (high 4 bits) */
/* Win32s/Borland don't need this */
#if !defined(__BORLANDC__) && !defined(WIN32)
#define FF_DONTCARE 0x00
#define FF_ROMAN 0x10
#define FF_SWISS 0x20
#define FF_MODERN 0x30
#define FF_SCRIPT 0x40
#define FF_DECORATIVE 0x50
#endif
/* Brush Styles */
#define BS_SOLID 0
#define BS_NULL 1
#define BS_HOLLOW BS_NULL
#define BS_HATCHED 2
#define BS_PATTERN 3
#define BS_INDEXED 4
#define BS_DIBPATTERN 5
/* Hatch Styles */
#define HS_HORIZONTAL 0
#define HS_VERTICAL 1
#define HS_FDIAGONAL 2
#define HS_BDIAGONAL 3
#define HS_CROSS 4
#define HS_DIAGCROSS 5
#endif // metafile functions
class wxMetaRecord: public wxObject
{
public:
int metaFunction;
long param1;
long param2;
long param3;
long param4;
long param5;
long param6;
long param7;
long param8;
char *stringParam;
wxRealPoint *points;
wxMetaRecord(int fun)
{
metaFunction = fun; points = NULL; stringParam = NULL;
param1 = 0;
}
~wxMetaRecord(void);
};
class wxXMetaFile: public wxObject
{
public:
float lastX;
float lastY;
bool ok;
float left;
float top;
float right;
float bottom;
wxList metaRecords;
wxList gdiObjects; // List of wxMetaRecord objects created with Create...,
// referenced by position in list by SelectObject
wxXMetaFile(char *file = NULL);
~wxXMetaFile(void);
// After this is called, the metafile cannot be used for anything
// since it is now owned by the clipboard.
bool SetClipboard(int width = 0, int height = 0);
bool Play(wxDC *dc);
inline bool Ok(void) const { return ok; }
bool ReadFile(char *file);
};
#endif
// _MFUTILS_H_

805
utils/ogl/src/misc.cpp Normal file
View File

@@ -0,0 +1,805 @@
/////////////////////////////////////////////////////////////////////////////
// Name: misc.cpp
// Purpose: Miscellaneous OGL support functions
// Author: Julian Smart
// Modified by:
// Created: 12/07/98
// RCS-ID: $Id$
// Copyright: (c) Julian Smart
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "misc.h"
#endif
// 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
#ifdef PROLOGIO
#include <wx/wxexpr.h>
#endif
#include <wx/types.h>
#if USE_IOSTREAMH
#include <iostream.h>
#else
#include <iostream>
#endif
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
#include "basic.h"
#include "basicp.h"
#include "misc.h"
#include "constrnt.h"
#include "composit.h"
wxFont *g_oglNormalFont;
wxPen *black_pen;
wxPen *white_background_pen;
wxPen *transparent_pen;
wxBrush *white_background_brush;
wxPen *black_foreground_pen;
char *GraphicsBuffer = NULL;
wxCursor *GraphicsBullseyeCursor = NULL;
wxList wxObjectCopyMapping(wxKEY_INTEGER);
void wxOGLInitialize()
{
GraphicsBullseyeCursor = new wxCursor(wxCURSOR_BULLSEYE);
g_oglNormalFont = new wxFont(12, wxMODERN, wxNORMAL, wxNORMAL);
black_pen = new wxPen("BLACK", 1, wxSOLID);
white_background_pen = new wxPen("WHITE", 1, wxSOLID);
transparent_pen = new wxPen("WHITE", 1, wxTRANSPARENT);
white_background_brush = new wxBrush("WHITE", wxSOLID);
black_foreground_pen = new wxPen("BLACK", 1, wxSOLID);
OGLInitializeConstraintTypes();
// Initialize big buffer used when writing images
GraphicsBuffer = new char[3000];
if (!oglPopupDivisionMenu)
{
oglPopupDivisionMenu = new wxMenu("", (wxFunction)oglGraphicsDivisionMenuProc);
oglPopupDivisionMenu->Append(DIVISION_MENU_SPLIT_HORIZONTALLY, "Split horizontally");
oglPopupDivisionMenu->Append(DIVISION_MENU_SPLIT_VERTICALLY, "Split vertically");
oglPopupDivisionMenu->AppendSeparator();
oglPopupDivisionMenu->Append(DIVISION_MENU_EDIT_LEFT_EDGE, "Edit left edge");
oglPopupDivisionMenu->Append(DIVISION_MENU_EDIT_TOP_EDGE, "Edit top edge");
}
}
void wxOGLCleanUp()
{
if (GraphicsBuffer)
{
delete[] GraphicsBuffer;
GraphicsBuffer = NULL;
}
GraphicsBuffer = NULL;
if (oglPopupDivisionMenu)
{
delete oglPopupDivisionMenu;
oglPopupDivisionMenu = NULL;
}
}
wxFont *MatchFont(int point_size)
{
wxFont *font = wxTheFontList->FindOrCreateFont(point_size, wxSWISS, wxNORMAL, wxNORMAL);
#if 0
switch (point_size)
{
case 4:
font = swiss_font_4;
break;
case 6:
font = swiss_font_6;
break;
case 8:
font = swiss_font_8;
break;
case 12:
font = swiss_font_12;
break;
case 14:
font = swiss_font_14;
break;
case 18:
font = swiss_font_18;
break;
case 24:
font = swiss_font_24;
break;
default:
case 10:
font = swiss_font_10;
break;
}
#endif
return font;
}
int FontSizeDialog(wxFrame *parent, int old_size)
{
if (old_size <= 0)
old_size = 10;
char buf[40];
sprintf(buf, "%d", old_size);
wxString ans = wxGetTextFromUser("Enter point size", "Font size", buf, parent);
if (ans == "")
return 0;
int new_size = atoi(ans);
if ((new_size <= 0) || (new_size > 40))
{
wxMessageBox("Invalid point size!", "Error", wxOK);
return 0;
}
return new_size;
/*
char *strings[8];
strings[0] = "4";
strings[1] = "6";
strings[2] = "8";
strings[3] = "10";
strings[4] = "12";
strings[5] = "14";
strings[6] = "18";
strings[7] = "24";
char *ans = wxGetSingleChoice("Choose", "Choose a font size", 8, strings, parent);
if (ans)
{
int size;
sscanf(ans, "%d", &size);
return MatchFont(size);
}
else return NULL;
*/
}
// Centre a list of strings in the given box. xOffset and yOffset are the
// the positions that these lines should be relative to, and this might be
// the same as m_xpos, m_ypos, but might be zero if formatting from left-justifying.
void CentreText(wxDC& dc, wxList *text_list,
float m_xpos, float m_ypos, float width, float height,
int formatMode)
{
int n = text_list->Number();
if (!text_list || (n == 0))
return;
// First, get maximum dimensions of box enclosing text
float char_height = 0;
float max_width = 0;
float current_width = 0;
// Store text extents for speed
float *widths = new float[n];
wxNode *current = text_list->First();
int i = 0;
while (current)
{
wxShapeTextLine *line = (wxShapeTextLine *)current->Data();
dc.GetTextExtent(line->GetText(), &current_width, &char_height);
widths[i] = current_width;
if (current_width > max_width)
max_width = current_width;
current = current->Next();
i ++;
}
float max_height = n*char_height;
float xoffset, yoffset, xOffset, yOffset;
if (formatMode & FORMAT_CENTRE_VERT)
{
if (max_height < height)
yoffset = (float)(m_ypos - (height/2.0) + (height - max_height)/2.0);
else
yoffset = (float)(m_ypos - (height/2.0));
yOffset = m_ypos;
}
else
{
yoffset = 0.0;
yOffset = 0.0;
}
if (formatMode & FORMAT_CENTRE_HORIZ)
{
xoffset = (float)(m_xpos - width/2.0);
xOffset = m_xpos;
}
else
{
xoffset = 0.0;
xOffset = 0.0;
}
current = text_list->First();
i = 0;
while (current)
{
wxShapeTextLine *line = (wxShapeTextLine *)current->Data();
float x;
if ((formatMode & FORMAT_CENTRE_HORIZ) && (widths[i] < width))
x = (float)((width - widths[i])/2.0 + xoffset);
else
x = xoffset;
float y = (float)(i*char_height + yoffset);
line->SetX( x - xOffset ); line->SetY( y - yOffset );
current = current->Next();
i ++;
}
delete widths;
}
// Centre a list of strings in the given box
void CentreTextNoClipping(wxDC& dc, wxList *text_list,
float m_xpos, float m_ypos, float width, float height)
{
int n = text_list->Number();
if (!text_list || (n == 0))
return;
// First, get maximum dimensions of box enclosing text
float char_height = 0;
float max_width = 0;
float current_width = 0;
// Store text extents for speed
float *widths = new float[n];
wxNode *current = text_list->First();
int i = 0;
while (current)
{
wxShapeTextLine *line = (wxShapeTextLine *)current->Data();
dc.GetTextExtent(line->GetText(), &current_width, &char_height);
widths[i] = current_width;
if (current_width > max_width)
max_width = current_width;
current = current->Next();
i ++;
}
float max_height = n*char_height;
float yoffset = (float)(m_ypos - (height/2.0) + (height - max_height)/2.0);
float xoffset = (float)(m_xpos - width/2.0);
current = text_list->First();
i = 0;
while (current)
{
wxShapeTextLine *line = (wxShapeTextLine *)current->Data();
float x = (float)((width - widths[i])/2.0 + xoffset);
float y = (float)(i*char_height + yoffset);
line->SetX( x - m_xpos ); line->SetY( y - m_ypos );
current = current->Next();
i ++;
}
delete widths;
}
void GetCentredTextExtent(wxDC& dc, wxList *text_list,
float m_xpos, float m_ypos, float width, float height,
float *actual_width, float *actual_height)
{
int n = text_list->Number();
if (!text_list || (n == 0))
{
*actual_width = 0;
*actual_height = 0;
return;
}
// First, get maximum dimensions of box enclosing text
float char_height = 0;
float max_width = 0;
float current_width = 0;
wxNode *current = text_list->First();
int i = 0;
while (current)
{
wxShapeTextLine *line = (wxShapeTextLine *)current->Data();
dc.GetTextExtent(line->GetText(), &current_width, &char_height);
if (current_width > max_width)
max_width = current_width;
current = current->Next();
i ++;
}
*actual_height = n*char_height;
*actual_width = max_width;
}
// Format a string to a list of strings that fit in the given box.
// Interpret %n and 10 or 13 as a new line.
wxList *FormatText(wxDC& dc, const wxString& text, float width, float height, int formatMode)
{
// First, parse the string into a list of words
wxList word_list;
// Make new lines into NULL strings at this point
int i = 0; int j = 0; int len = strlen(text);
char word[200]; word[0] = 0;
bool end_word = FALSE; bool new_line = FALSE;
while (i < len)
{
switch (text[i])
{
case '%':
{
i ++;
if (i == len)
{ word[j] = '%'; j ++; }
else
{
if (text[i] == 'n')
{ new_line = TRUE; end_word = TRUE; i++; }
else
{ word[j] = '%'; j ++; word[j] = text[i]; j ++; i ++; }
}
break;
}
case 10:
{
new_line = TRUE; end_word = TRUE; i++;
break;
}
case 13:
{
new_line = TRUE; end_word = TRUE; i++;
}
case ' ':
{
end_word = TRUE;
i ++;
break;
}
default:
{
word[j] = text[i];
j ++; i ++;
break;
}
}
if (i == len) end_word = TRUE;
if (end_word)
{
word[j] = 0;
j = 0;
word_list.Append((wxObject *)copystring(word));
end_word = FALSE;
}
if (new_line)
{
word_list.Append((wxObject *)NULL);
new_line = FALSE;
}
}
// Now, make a list of strings which can fit in the box
wxList *string_list = new wxList;
char buffer[400];
buffer[0] = 0;
wxNode *node = word_list.First();
float x, y;
while (node)
{
char *keep_string = copystring(buffer);
char *s = (char *)node->Data();
if (!s)
{
// FORCE NEW LINE
if (strlen(keep_string) > 0)
string_list->Append((wxObject *)keep_string);
else
delete[] keep_string;
buffer[0] = 0;
}
else
{
if (buffer[0] != 0)
strcat(buffer, " ");
strcat(buffer, s);
dc.GetTextExtent(buffer, &x, &y);
// Don't fit within the bounding box if we're fitting shape to contents
if ((x > width) && !(formatMode & FORMAT_SIZE_TO_CONTENTS))
{
// Deal with first word being wider than box
if (strlen(keep_string) > 0)
string_list->Append((wxObject *)keep_string);
else
delete[] keep_string;
buffer[0] = 0;
strcat(buffer, s);
delete[] s;
}
else
delete[] keep_string;
}
node = node->Next();
}
if (buffer[0] != 0)
string_list->Append((wxObject *)copystring(buffer));
return string_list;
}
void DrawFormattedText(wxDC& dc, wxList *text_list,
float m_xpos, float m_ypos, float width, float height,
int formatMode)
{
float xoffset, yoffset;
if (formatMode & FORMAT_CENTRE_HORIZ)
xoffset = m_xpos;
else
xoffset = (float)(m_xpos - (width / 2.0));
if (formatMode & FORMAT_CENTRE_VERT)
yoffset = m_ypos;
else
yoffset = (float)(m_ypos - (height / 2.0));
dc.SetClippingRegion(
(float)(m_xpos - width/2.0), (float)(m_ypos - height/2.0),
(float)width, (float)height);
wxNode *current = text_list->First();
while (current)
{
wxShapeTextLine *line = (wxShapeTextLine *)current->Data();
dc.DrawText(line->GetText(), xoffset + line->GetX(), yoffset + line->GetY());
current = current->Next();
}
dc.DestroyClippingRegion();
}
/*
* Find centroid given list of points comprising polyline
*
*/
void find_polyline_centroid(wxList *points, float *x, float *y)
{
float xcount = 0;
float ycount = 0;
wxNode *node = points->First();
while (node)
{
wxRealPoint *point = (wxRealPoint *)node->Data();
xcount += point->x;
ycount += point->y;
node = node->Next();
}
*x = (xcount/points->Number());
*y = (ycount/points->Number());
}
/*
* Check that (x1, y1) -> (x2, y2) hits (x3, y3) -> (x4, y4).
* If so, ratio1 gives the proportion along the first line
* that the intersection occurs (or something like that).
* Used by functions below.
*
*/
void check_line_intersection(float x1, float y1, float x2, float y2,
float x3, float y3, float x4, float y4,
float *ratio1, float *ratio2)
{
float denominator_term = (y4 - y3)*(x2 - x1) - (y2 - y1)*(x4 - x3);
float numerator_term = (x3 - x1)*(y4 - y3) + (x4 - x3)*(y1 - y3);
float line_constant;
float length_ratio = 1.0;
float k_line = 1.0;
// Check for parallel lines
if ((denominator_term < 0.005) && (denominator_term > -0.005))
line_constant = -1.0;
else
line_constant = numerator_term/denominator_term;
// Check for intersection
if ((line_constant < 1.0) && (line_constant > 0.0))
{
// Now must check that other line hits
if (((y4 - y3) < 0.005) && ((y4 - y3) > -0.005))
k_line = ((x1 - x3) + line_constant*(x2 - x1))/(x4 - x3);
else
k_line = ((y1 - y3) + line_constant*(y2 - y1))/(y4 - y3);
if ((k_line >= 0.0) && (k_line < 1.0))
length_ratio = line_constant;
else
k_line = 1.0;
}
*ratio1 = length_ratio;
*ratio2 = k_line;
}
/*
* Find where (x1, y1) -> (x2, y2) hits one of the lines in xvec, yvec.
* (*x3, *y3) is the point where it hits.
*
*/
void find_end_for_polyline(float n, float xvec[], float yvec[],
float x1, float y1, float x2, float y2, float *x3, float *y3)
{
int i;
float lastx = xvec[0];
float lasty = yvec[0];
float min_ratio = 1.0;
float line_ratio;
float other_ratio;
for (i = 1; i < n; i++)
{
check_line_intersection(x1, y1, x2, y2, lastx, lasty, xvec[i], yvec[i],
&line_ratio, &other_ratio);
lastx = xvec[i];
lasty = yvec[i];
if (line_ratio < min_ratio)
min_ratio = line_ratio;
}
// Do last (implicit) line if last and first floats are not identical
if (!(xvec[0] == lastx && yvec[0] == lasty))
{
check_line_intersection(x1, y1, x2, y2, lastx, lasty, xvec[0], yvec[0],
&line_ratio, &other_ratio);
if (line_ratio < min_ratio)
min_ratio = line_ratio;
}
*x3 = (x1 + (x2 - x1)*min_ratio);
*y3 = (y1 + (y2 - y1)*min_ratio);
}
/*
* Find where the line hits the box.
*
*/
void find_end_for_box(float width, float height,
float x1, float y1, // Centre of box (possibly)
float x2, float y2, // other end of line
float *x3, float *y3) // End on box edge
{
float xvec[5];
float yvec[5];
xvec[0] = (float)(x1 - width/2.0);
yvec[0] = (float)(y1 - height/2.0);
xvec[1] = (float)(x1 - width/2.0);
yvec[1] = (float)(y1 + height/2.0);
xvec[2] = (float)(x1 + width/2.0);
yvec[2] = (float)(y1 + height/2.0);
xvec[3] = (float)(x1 + width/2.0);
yvec[3] = (float)(y1 - height/2.0);
xvec[4] = (float)(x1 - width/2.0);
yvec[4] = (float)(y1 - height/2.0);
find_end_for_polyline(5, xvec, yvec, x2, y2, x1, y1, x3, y3);
}
/*
* Find where the line hits the circle.
*
*/
void find_end_for_circle(float radius,
float x1, float y1, // Centre of circle
float x2, float y2, // Other end of line
float *x3, float *y3)
{
float H = (float)sqrt((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1));
if (H == 0.0)
{
*x3 = x1;
*y3 = y1;
}
else
{
*y3 = radius * (y2 - y1)/H + y1;
*x3 = radius * (x2 - x1)/H + x1;
}
}
/*
* Given the line (x1, y1) -> (x2, y2), and an arrow size of given length and width,
* return the position of the tip of the arrow and the left and right vertices of the arrow.
*
*/
void get_arrow_points(float x1, float y1, float x2, float y2,
float length, float width,
float *tip_x, float *tip_y,
float *side1_x, float *side1_y,
float *side2_x, float *side2_y)
{
float l = (float)sqrt((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1));
if (l < 0.01)
l = (float) 0.01;
float i_bar = (x2 - x1)/l;
float j_bar = (y2 - y1)/l;
float x3 = (- length*i_bar) + x2;
float y3 = (- length*j_bar) + y2;
*side1_x = width*(-j_bar) + x3;
*side1_y = width*i_bar + y3;
*side2_x = -width*(-j_bar) + x3;
*side2_y = -width*i_bar + y3;
*tip_x = x2; *tip_y = y2;
}
/*
* Given an ellipse and endpoints of a line, returns the point at which
* the line touches the ellipse in values x4, y4.
* This function assumes that the centre of the ellipse is at x1, y1, and the
* ellipse has a width of width1 and a height of height1. It also assumes you are
* wanting to draw an arc FROM point x2, y2 TOWARDS point x3, y3.
* This function calculates the x,y coordinates of the intersection point of
* the arc with the ellipse.
* Author: Ian Harrison
*/
void draw_arc_to_ellipse(float x1, float y1, float width1, float height1, float x2, float y2, float x3, float y3,
float *x4, float *y4)
{
float a1 = (float)(width1/2.0);
float b1 = (float)(height1/2.0);
// These are required to give top left x and y coordinates for DrawEllipse
// float top_left_x1 = (float)(x1 - a1);
// float top_left_y1 = (float)(y1 - b1);
/*
// Check for vertical line
if (fabs(x2 - x3) < 0.05)
{
*x4 = x3;
if (y2 < y3)
*y4 = (float)(y1 - b1);
else
*y4 = (float)(y1 + b1);
return;
}
*/
// Check that x2 != x3
if (fabs(x2 - x3) < 0.05)
{
*x4 = x2;
if (y3 > y2)
*y4 = (float)(y1 - sqrt((b1*b1 - (((x2-x1)*(x2-x1))*(b1*b1)/(a1*a1)))));
else
*y4 = (float)(y1 + sqrt((b1*b1 - (((x2-x1)*(x2-x1))*(b1*b1)/(a1*a1)))));
return;
}
// Calculate the x and y coordinates of the point where arc intersects ellipse
float A, B, C, D, E, F, G, H, K;
float ellipse1_x, ellipse1_y;
A = (float)(1/(a1 * a1));
B = (float)((y3 - y2) * (y3 - y2)) / ((x3 - x2) * (x3 - x2) * b1 * b1);
C = (float)(2 * (y3 - y2) * (y2 - y1)) / ((x3 - x2) * b1 * b1);
D = (float)((y2 - y1) * (y2 - y1)) / (b1 * b1);
E = (float)(A + B);
F = (float)(C - (2 * A * x1) - (2 * B * x2));
G = (float)((A * x1 * x1) + (B * x2 * x2) - (C * x2) + D - 1);
H = (float)((y3 - y2) / (x3 - x2));
K = (float)((F * F) - (4 * E * G));
if (K >= 0)
// In this case the line intersects the ellipse, so calculate intersection
{
if(x2 >= x1)
{
ellipse1_x = (float)(((F * -1) + sqrt(K)) / (2 * E));
ellipse1_y = (float)((H * (ellipse1_x - x2)) + y2);
}
else
{
ellipse1_x = (float)(((F * -1) - sqrt(K)) / (2 * E));
ellipse1_y = (float)((H * (ellipse1_x - x2)) + y2);
}
}
else
// in this case, arc does not intersect ellipse, so just draw arc
{
ellipse1_x = x3;
ellipse1_y = y3;
}
*x4 = ellipse1_x;
*y4 = ellipse1_y;
/*
// Draw a little circle (radius = 2) at the end of the arc where it hits
// the ellipse .
float circle_x = ellipse1_x - 2.0;
float circle_y = ellipse1_y - 2.0;
m_canvas->DrawEllipse(circle_x, circle_y, 4.0, 4.0);
*/
}
// Update a list item from a list of strings
void UpdateListBox(wxListBox *item, wxList *list)
{
item->Clear();
if (!list)
return;
wxNode *node = list->First();
while (node)
{
char *s = (char *)node->Data();
item->Append(s);
node = node->Next();
}
}

107
utils/ogl/src/misc.h Normal file
View File

@@ -0,0 +1,107 @@
/////////////////////////////////////////////////////////////////////////////
// Name: misc.h
// Purpose: Miscellaneous utilities for OGL
// Author: Julian Smart
// Modified by:
// Created: 12/07/98
// RCS-ID: $Id$
// Copyright: (c) Julian Smart
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef _OGL_MISC_H_
#define _OGL_MISC_H_
#ifdef __GNUG__
#pragma interface "misc.h"
#endif
// List to use when copying objects; may need to associate elements of new objects
// with elements of old objects, e.g. when copying constraint.s
extern wxList wxObjectCopyMapping;
/*
* TEXT FORMATTING FUNCTIONS
*
*/
// Centres the given list of wxShapeTextLine strings in the given box
// (changing the positions in situ). Doesn't actually draw into the DC.
void CentreText(wxDC& dc, wxList *text, float m_xpos, float m_ypos,
float width, float height,
int formatMode = FORMAT_CENTRE_HORIZ | FORMAT_CENTRE_VERT);
// Given a string, returns a list of strings that fit within the given
// width of box. Height is ignored.
wxList *FormatText(wxDC& dc, const wxString& text, float width, float height, int formatMode = 0);
// Centres the list of wxShapeTextLine strings, doesn't clip.
// Doesn't actually draw into the DC.
void CentreTextNoClipping(wxDC& dc, wxList *text_list,
float m_xpos, float m_ypos, float width, float height);
// Gets the maximum width and height of the given list of wxShapeTextLines.
void GetCentredTextExtent(wxDC& dc, wxList *text_list,
float m_xpos, float m_ypos, float width, float height,
float *actual_width, float *actual_height);
// Actually draw the preformatted list of wxShapeTextLines.
void DrawFormattedText(wxDC& context, wxList *text_list,
float m_xpos, float m_ypos, float width, float height,
int formatMode = FORMAT_CENTRE_HORIZ | FORMAT_CENTRE_VERT);
// Give it a list of points, finds the centre.
void find_polyline_centroid(wxList *points, float *x, float *y);
void check_line_intersection(float x1, float y1, float x2, float y2,
float x3, float y3, float x4, float y4,
float *ratio1, float *ratio2);
void find_end_for_polyline(float n, float xvec[], float yvec[],
float x1, float y1, float x2, float y2, float *x3, float *y3);
void find_end_for_box(float width, float height,
float x1, float y1, // Centre of box (possibly)
float x2, float y2, // other end of line
float *x3, float *y3); // End on box edge
void find_end_for_circle(float radius,
float x1, float y1, // Centre of circle
float x2, float y2, // Other end of line
float *x3, float *y3);
void get_arrow_points(float x1, float y1, float x2, float y2,
float length, float width,
float *tip_x, float *tip_y,
float *side1_x, float *side1_y,
float *side2_x, float *side2_y);
/*
* Given an ellipse and endpoints of a line, returns the point at which
* the line touches the ellipse in values x4, y4.
* This function assumes that the centre of the ellipse is at x1, y1, and the
* ellipse has a width of a1 and a height of b1. It also assumes you are
* wanting to draw an arc FROM point x2, y2 TOWARDS point x3, y3.
* This function calculates the x,y coordinates of the intersection point of
* the arc with the ellipse.
* Author: Ian Harrison
*/
void draw_arc_to_ellipse(float x1, float y1, float a1, float b1, float x2, float y2, float x3, float y3,
float *x4, float *y4);
extern wxFont *g_oglNormalFont;
extern wxPen *black_pen;
extern wxPen *white_background_pen;
extern wxPen *transparent_pen;
extern wxBrush *white_background_brush;
extern wxPen *black_foreground_pen;
extern wxCursor *GraphicsBullseyeCursor;
extern wxFont *MatchFont(int point_size);
#endif
// _OGL_MISC_H_

26
utils/ogl/src/ogl.h Normal file
View File

@@ -0,0 +1,26 @@
/////////////////////////////////////////////////////////////////////////////
// Name: ogl.h
// Purpose: OGL main include
// Author: Julian Smart
// Modified by:
// Created: 12/07/98
// RCS-ID: $Id$
// Copyright: (c) Julian Smart
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef _OGL_OGL_H_
#define _OGL_OGL_H_
#include "basic.h" // Basic shapes
#include "lines.h" // Lines and splines
#include "divided.h" // Vertically-divided rectangle
#include "composit.h" // Composite images
#include "canvas.h" // wxShapeCanvas for displaying objects
#include "ogldiag.h" // wxDiagram
extern void wxOGLInitialize();
extern void wxOGLCleanUp();
#endif
// _OGL_OGL_H_

580
utils/ogl/src/ogldiag.cpp Normal file
View File

@@ -0,0 +1,580 @@
/////////////////////////////////////////////////////////////////////////////
// Name: ogldiag.cpp
// Purpose: wxDiagram
// Author: Julian Smart
// Modified by:
// Created: 12/07/98
// RCS-ID: $Id$
// Copyright: (c) Julian Smart
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#pragma implementation "ogldiag.h"
#endif
// 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
#ifdef PROLOGIO
#include <wx/wxexpr.h>
#endif
#if USE_IOSTREAMH
#include <iostream.h>
#else
#include <iostream>
#endif
#include <fstream.h>
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
#include "basic.h"
#include "basicp.h"
#include "canvas.h"
#include "ogldiag.h"
#include "lines.h"
#include "composit.h"
#include "misc.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(float spacing)
{
m_gridSpacing = spacing;
}
void wxDiagram::Snap(float *x, float *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->First();
while (current)
{
wxShape *object = (wxShape *)current->Data();
if (!object->GetParent())
object->Draw(dc);
current = current->Next();
}
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->Next())
m_shapeList->Insert(nodeAfter->Next(), 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->First();
while (node)
{
wxShape *shape = (wxShape *)node->Data();
if (!shape->GetParent())
{
RemoveShape(shape);
delete shape;
node = m_shapeList->First();
}
else
node = node->Next();
}
}
void wxDiagram::ShowAll(bool show)
{
wxNode *current = m_shapeList->First();
while (current)
{
wxShape *object = (wxShape *)current->Data();
object->Show(show);
current = current->Next();
}
}
void wxDiagram::DrawOutline(wxDC& dc, float x1, float y1, float x2, float y2)
{
wxPen dottedPen(wxColour(0, 0, 0), 1, wxDOT);
dc.SetPen(dottedPen);
dc.SetBrush((* wxTRANSPARENT_BRUSH));
wxPoint points[5];
points[0].x = x1;
points[0].y = y1;
points[1].x = x2;
points[1].y = y1;
points[2].x = x2;
points[2].y = y2;
points[3].x = x1;
points[3].y = y2;
points[4].x = x1;
points[4].y = 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->First();
while (object_node)
{
wxShape *obj = (wxShape *)object_node->Data();
obj->Recentre(dc);
object_node = object_node->Next();
}
}
// Input/output
#ifdef PROLOGIO
bool wxDiagram::SaveFile(const wxString& filename)
{
wxBeginBusyCursor();
wxExprDatabase *database = new wxExprDatabase;
// First write the diagram type
wxExpr *header = new wxExpr("diagram");
OnHeaderSave(*database, *header);
database->Append(header);
wxNode *node = m_shapeList->First();
while (node)
{
wxShape *shape = (wxShape *)node->Data();
if (!shape->IsKindOf(CLASSINFO(wxControlPoint)))
{
wxExpr *expr = NULL;
if (shape->IsKindOf(CLASSINFO(wxLineShape)))
expr = new wxExpr("line");
else
expr = new wxExpr("shape");
OnShapeSave(*database, *shape, *expr);
}
node = node->Next();
}
OnDatabaseSave(*database);
char tempFile[400];
wxGetTempFileName("diag", tempFile);
ofstream stream(tempFile);
if (stream.bad())
{
wxEndBusyCursor();
delete database;
return FALSE;
}
database->Write(stream);
stream.close();
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(PrologInteger, "id");
if (!database.Read(filename))
{
wxEndBusyCursor();
return FALSE;
}
DeleteAllShapes();
database.BeginFind();
wxExpr *header = database.FindClauseByFunctor("diagram");
if (header)
OnHeaderLoad(database, *header);
// Scan through all clauses and register the ids
wxNode *node = database.First();
while (node)
{
wxExpr *clause = (wxExpr *)node->Data();
long id = -1;
clause->GetAttributeValue("id", id);
RegisterId(id);
node = node->Next();
}
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("shape");
while (clause)
{
char *type = NULL;
long parentId = -1;
clause->AssignAttributeValue("type", &type);
clause->AssignAttributeValue("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("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("shape");
}
return;
}
void wxDiagram::ReadLines(wxExprDatabase& database)
{
database.BeginFind();
wxExpr *clause = database.FindClauseByFunctor("line");
while (clause)
{
wxString type("");
long parentId = -1;
clause->GetAttributeValue("type", type);
clause->GetAttributeValue("parent", parentId);
wxClassInfo *classInfo = wxClassInfo::FindClass((char*) (const char*) type);
if (classInfo)
{
wxLineShape *shape = (wxLineShape *)classInfo->CreateObject();
shape->Show(TRUE);
OnShapeLoad(database, *shape, *clause);
long image_to = -1; long image_from = -1;
clause->GetAttributeValue("to", image_to);
clause->GetAttributeValue("from", image_from);
wxExpr *image_to_expr = database.HashFind("shape", image_to);
if (!image_to_expr)
{
// Error
}
wxExpr *image_from_expr = database.HashFind("shape", image_from);
if (!image_from_expr)
{
// Error
}
if (image_to_expr && image_from_expr)
{
wxShape *image_to_object = (wxShape *)image_to_expr->GetClientData();
wxShape *image_from_object = (wxShape *)image_from_expr->GetClientData();
if (image_to_object && image_from_object)
{
image_from_object->AddLine(shape, image_to_object, shape->GetAttachmentFrom(), shape->GetAttachmentTo());
}
}
clause->SetClientData(shape);
m_shapeList->Append(shape);
}
clause = database.FindClauseByFunctor("line");
}
}
// Containers have divisions that reference adjoining divisions,
// so we need a separate pass to link everything up.
// Also used by Symbol Library.
void wxDiagram::ReadContainerGeometry(wxExprDatabase& database)
{
database.BeginFind();
wxExpr *clause = database.FindClauseByFunctor("shape");
while (clause)
{
wxShape *image = (wxShape *)clause->GetClientData();
if (image && image->IsKindOf(CLASSINFO(wxCompositeShape)))
{
wxCompositeShape *composite = (wxCompositeShape *)image;
wxExpr *divisionExpr = NULL;
// Find the list of divisions in the composite
clause->GetAttributeValue("divisions", &divisionExpr);
if (divisionExpr)
{
int i = 0;
wxExpr *idExpr = divisionExpr->Nth(i);
while (idExpr)
{
long divisionId = idExpr->IntegerValue();
wxExpr *childExpr = database.HashFind("shape", divisionId);
if (childExpr && childExpr->GetClientData())
{
wxDivisionShape *child = (wxDivisionShape *)childExpr->GetClientData();
composite->GetDivisions().Append(child);
// Find the adjoining shapes
long leftSideId = -1;
long topSideId = -1;
long rightSideId = -1;
long bottomSideId = -1;
childExpr->GetAttributeValue("left_side", leftSideId);
childExpr->GetAttributeValue("top_side", topSideId);
childExpr->GetAttributeValue("right_side", rightSideId);
childExpr->GetAttributeValue("bottom_side", bottomSideId);
if (leftSideId > -1)
{
wxExpr *leftExpr = database.HashFind("shape", leftSideId);
if (leftExpr && leftExpr->GetClientData())
{
wxDivisionShape *leftSide = (wxDivisionShape *)leftExpr->GetClientData();
child->SetLeftSide(leftSide);
}
}
if (topSideId > -1)
{
wxExpr *topExpr = database.HashFind("shape", topSideId);
if (topExpr && topExpr->GetClientData())
{
wxDivisionShape *topSide = (wxDivisionShape *)topExpr->GetClientData();
child->SetTopSide(topSide);
}
}
if (rightSideId > -1)
{
wxExpr *rightExpr = database.HashFind("shape", rightSideId);
if (rightExpr && rightExpr->GetClientData())
{
wxDivisionShape *rightSide = (wxDivisionShape *)rightExpr->GetClientData();
child->SetRightSide(rightSide);
}
}
if (bottomSideId > -1)
{
wxExpr *bottomExpr = database.HashFind("shape", bottomSideId);
if (bottomExpr && bottomExpr->GetClientData())
{
wxDivisionShape *bottomSide = (wxDivisionShape *)bottomExpr->GetClientData();
child->SetBottomSide(bottomSide);
}
}
}
i ++;
idExpr = divisionExpr->Nth(i);
}
}
}
clause = database.FindClauseByFunctor("shape");
}
}
// Allow for modifying file
bool wxDiagram::OnDatabaseLoad(wxExprDatabase& db)
{
return TRUE;
}
bool wxDiagram::OnDatabaseSave(wxExprDatabase& db)
{
return TRUE;
}
bool wxDiagram::OnShapeSave(wxExprDatabase& db, wxShape& shape, wxExpr& expr)
{
shape.WritePrologAttributes(&expr);
db.Append(&expr);
if (shape.IsKindOf(CLASSINFO(wxCompositeShape)))
{
wxNode *node = shape.GetChildren().First();
while (node)
{
wxShape *childShape = (wxShape *)node->Data();
wxExpr *childExpr = new wxExpr("shape");
OnShapeSave(db, *childShape, *childExpr);
node = node->Next();
}
}
return TRUE;
}
bool wxDiagram::OnShapeLoad(wxExprDatabase& db, wxShape& shape, wxExpr& expr)
{
shape.ReadPrologAttributes(&expr);
return TRUE;
}
bool wxDiagram::OnHeaderSave(wxExprDatabase& db, wxExpr& expr)
{
return TRUE;
}
bool wxDiagram::OnHeaderLoad(wxExprDatabase& db, wxExpr& expr)
{
return TRUE;
}
#endif
void wxDiagram::SetCanvas(wxShapeCanvas *can)
{
m_diagramCanvas = can;
}

94
utils/ogl/src/ogldiag.h Normal file
View File

@@ -0,0 +1,94 @@
/////////////////////////////////////////////////////////////////////////////
// Name: ogldiag.h
// Purpose: OGL - wxDiagram class
// Author: Julian Smart
// Modified by:
// Created: 12/07/98
// RCS-ID: $Id$
// Copyright: (c) Julian Smart
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifndef _OGL_OGLDIAG_H_
#define _OGL_OGLDIAG_H_
#ifdef __GNUG__
#pragma interface "ogldiag.h"
#endif
#include "basic.h"
class wxDiagram: public wxObject
{
DECLARE_DYNAMIC_CLASS(wxDiagram)
public:
wxDiagram();
virtual ~wxDiagram();
void SetCanvas(wxShapeCanvas *can);
inline wxShapeCanvas *GetCanvas() const { return m_diagramCanvas; }
virtual void Redraw(wxDC& dc);
virtual void Clear(wxDC& dc);
virtual void DrawOutline(wxDC& dc, float x1, float y1, float x2, float y2);
// Add object to end of object list (if addAfter is NULL)
// or just after addAfter.
virtual void AddShape(wxShape *object, wxShape *addAfter = NULL);
// Add object to front of object list
virtual void InsertShape(wxShape *object);
void SetSnapToGrid(bool snap);
void SetGridSpacing(float spacing);
inline float GetGridSpacing() { return m_gridSpacing; }
inline bool GetSnapToGrid() const { return m_snapToGrid; }
void Snap(float *x, float *y);
inline void SetQuickEditMode(bool qem) { m_quickEditMode = qem; }
inline bool GetQuickEditMode() const { return m_quickEditMode; }
virtual void RemoveShape(wxShape *object);
virtual void RemoveAllShapes();
virtual void DeleteAllShapes();
virtual void ShowAll(bool show);
inline void SetMouseTolerance(int tol) { m_mouseTolerance = tol; }
inline int GetMouseTolerance() const { return m_mouseTolerance; }
inline wxList *GetShapeList() const { return m_shapeList; }
// Make sure all text that should be centred, is centred.
void RecentreAll(wxDC& dc);
#ifdef PROLOGIO
// Prolog database stuff
virtual bool SaveFile(const wxString& filename);
virtual bool LoadFile(const wxString& filename);
virtual void ReadNodes(wxExprDatabase& database);
virtual void ReadLines(wxExprDatabase& database);
virtual void ReadContainerGeometry(wxExprDatabase& database);
// Allow for modifying file
virtual bool OnDatabaseLoad(wxExprDatabase& db);
virtual bool OnDatabaseSave(wxExprDatabase& db);
virtual bool OnShapeSave(wxExprDatabase& db, wxShape& shape, wxExpr& expr);
virtual bool OnShapeLoad(wxExprDatabase& db, wxShape& shape, wxExpr& expr);
virtual bool OnHeaderSave(wxExprDatabase& db, wxExpr& expr);
virtual bool OnHeaderLoad(wxExprDatabase& db, wxExpr& expr);
#endif
protected:
wxShapeCanvas* m_diagramCanvas;
bool m_quickEditMode;
bool m_snapToGrid;
float m_gridSpacing;
int m_mouseTolerance;
wxList* m_shapeList;
};
#endif
// _OGL_OGLDIAG_H_