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
							
								
								
									
										41
									
								
								utils/ogl/distrib/ogl.rsp
									
									
									
									
									
										Normal 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
									
								
							
							
						
						| @@ -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
									
								
							
							
						
						| @@ -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
									
								
							
							
						
						| After Width: | Height: | Size: 225 B | 
							
								
								
									
										
											BIN
										
									
								
								utils/ogl/docs/books.bmp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 1.2 KiB | 
							
								
								
									
										11
									
								
								utils/ogl/docs/bugs.tex
									
									
									
									
									
										Normal 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
									
								
							
							
						
						| After Width: | Height: | Size: 138 B | 
							
								
								
									
										9
									
								
								utils/ogl/docs/changes.tex
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								utils/ogl/docs/contents.gif
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 231 B | 
							
								
								
									
										
											BIN
										
									
								
								utils/ogl/docs/forward.gif
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 164 B | 
							
								
								
									
										45
									
								
								utils/ogl/docs/intro.tex
									
									
									
									
									
										Normal 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
									
								
							
							
						
						| @@ -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
									
								
							
							
						
						| @@ -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
									
								
							
							
						
						| After Width: | Height: | Size: 86 KiB | 
							
								
								
									
										
											BIN
										
									
								
								utils/ogl/docs/ogledit.gif
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 7.0 KiB | 
							
								
								
									
										128
									
								
								utils/ogl/docs/sample.tex
									
									
									
									
									
										Normal 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. | ||||
							
								
								
									
										20
									
								
								utils/ogl/docs/tex2rtf.ini
									
									
									
									
									
										Normal 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
									
								
							
							
						
						| @@ -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
									
								
							
							
						
						| After Width: | Height: | Size: 137 B | 
							
								
								
									
										2434
									
								
								utils/ogl/src/basic.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										605
									
								
								utils/ogl/src/basic.h
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
							
								
								
									
										195
									
								
								utils/ogl/src/basicp.h
									
									
									
									
									
										Normal 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
									
								
							
							
						
						| @@ -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
									
								
							
							
						
						| @@ -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
									
								
							
							
						
						| @@ -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
									
								
							
							
						
						| @@ -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
									
								
							
							
						
						
							
								
								
									
										244
									
								
								utils/ogl/src/composit.h
									
									
									
									
									
										Normal 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
									
								
							
							
						
						| @@ -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
									
								
							
							
						
						| @@ -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
									
								
							
							
						
						| @@ -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, ®ion->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", ®ion->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
									
								
							
							
						
						| @@ -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 ©); | ||||
|   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
									
								
							
							
						
						
							
								
								
									
										119
									
								
								utils/ogl/src/drawn.h
									
									
									
									
									
										Normal 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
									
								
							
							
						
						| @@ -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
									
								
							
							
						
						
							
								
								
									
										286
									
								
								utils/ogl/src/lines.h
									
									
									
									
									
										Normal 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
									
								
							
							
						
						| @@ -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
									
								
							
							
						
						| @@ -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
									
								
							
							
						
						| @@ -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
									
								
							
							
						
						| @@ -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
									
								
							
							
						
						| @@ -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
									
								
							
							
						
						| @@ -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  | ||||
|  | ||||
							
								
								
									
										28
									
								
								utils/ogl/src/makefile.wat
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
							
								
								
									
										211
									
								
								utils/ogl/src/mfutils.h
									
									
									
									
									
										Normal 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
									
								
							
							
						
						| @@ -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(), ¤t_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(), ¤t_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(), ¤t_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
									
								
							
							
						
						| @@ -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
									
								
							
							
						
						| @@ -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
									
								
							
							
						
						| @@ -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
									
								
							
							
						
						| @@ -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_ | ||||