]> Shamusworld >> Repos - ttedit/blobdiff - src/editwindow.cpp
Added preview window to file loading dialog. :-)
[ttedit] / src / editwindow.cpp
old mode 100755 (executable)
new mode 100644 (file)
index f617f3d..dac63c2
@@ -6,9 +6,10 @@
 // JLH = James L. Hammons <jlhamm@acm.org>
 //
 // Who  When        What
-// ---  ----------  -------------------------------------------------------------
+// ---  ----------  -----------------------------------------------------------
 // JLH  08/28/2008  Created this file
 // JLH  09/02/2008  Separated scrolling from dedicated tool to MMB drag
+// JLH  03/13/2009  Converted from wxWidgets to Qt
 //
 
 // FIXED:
@@ -24,6 +25,7 @@
 //   point on screen
 // - Add poly multi-select
 // - Add point multi-select
+// - Undo system
 //
 
 // Uncomment this for debugging...
 #define DEBUGTP                                // Toolpalette debugging...
 
 #include "editwindow.h"
-#include "graphicprimitives.h"
-#include "toolwindow.h"
+#include "charwindow.h"
 #include "debug.h"
+#include "global.h"
+#include "mainwindow.h"
+#include "mathconstants.h"
+#include "ttedit.h"
 #include "vector.h"
 
 
-BEGIN_EVENT_TABLE(TTEditWindow, wxWindow)
-       EVT_PAINT(TTEditWindow::OnPaint)
-       EVT_MOUSE_EVENTS(TTEditWindow::OnMouseEvent)
-END_EVENT_TABLE()
+EditWindow::EditWindow(QWidget * parent/*= NULL*/): QWidget(parent),
+       tool(TOOLSelect), ptHighlight(-1), oldPtHighlight(-1), ptNextHighlight(-1),
+       oldPtNextHighlight(-1), polyFirstPoint(true), showRotationCenter(false),
+       haveZeroPoint(false), selectionInProgress(false)
+{
+       setBackgroundRole(QPalette::Base);
+       setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+
+       toolPalette = new ToolWindow();
+       CreateCursors();
+       setCursor(cur[TOOLSelect]);
+       setMouseTracking(true);
+       ClearSelection();
+}
 
-TTEditWindow::TTEditWindow(wxFrame * parent, const wxPoint &pos, const wxSize &size, long style):
-       wxWindow(parent, -1, pos, size, style | wxFULL_REPAINT_ON_RESIZE),
-       app(wxGetApp()), scale(1.0), offsetX(-10), offsetY(-10), tool(TOOLSelect),
-       ptHighlight(-1), oldPtHighlight(-1), ptNextHighlight(-1), oldPtNextHighlight(-1),
-       polyFirstPoint(true), bmp(NULL)
-{ 
-       SetCursor(*(app.cur[tool]));
-       SetBackgroundColour(wxColour(0xFF, 0xFF, 0xFF));
 
-       wxString s;
-       s.Printf(_("Zoom: %.2f%%"), scale * 100.0);
-       parent->SetStatusText(s, 1);
+QSize EditWindow::minimumSizeHint() const
+{
+       return QSize(50, 50);
 }
 
-TTEditWindow::~TTEditWindow(void)
+
+QSize EditWindow::sizeHint() const
 {
-       if (bmp)
-               delete bmp;
+       return QSize(400, 400);
 }
 
-void TTEditWindow::OnPaint(wxPaintEvent &e)
+
+void EditWindow::CreateCursors(void)
 {
-       wxPaintDC dc(this);
-//Doesn't do crap!
-//dc.SetBackground(*wxWHITE_BRUSH);
+       int hotx[12] = {  1,  1, 1, 15,  1,  1,  1,  1,  1,  1,  1, 11 };
+       int hoty[12] = {  1,  1, 1, 13,  1,  1,  1,  1,  1,  1,  1, 11 };
+       char cursorName[12][48] = { "select", "select-poly", "select-multi", "zoom",
+               "add-point", "add-poly", "del-point", "del-poly", "rotate", "rotate",
+               "select", "scroll" };
+
+       for(int i=0; i<12; i++)
+       {
+               QPixmap pmTmp(QString(":/res/cursor-%1.png").arg(cursorName[i]));
+               cur[i] = QCursor(pmTmp, hotx[i], hoty[i]);
+       }
+}
+
 
-// Due to the screwiness of wxWidgets coord system, the origin is ALWAYS
-// the upper left corner--regardless of axis orientation, etc...
-       wxCoord width, height;
-       dc.GetSize(&width, &height);
+/*
+TODO:
+ o  Different colors for polys on selected points
+ o  Different colors for handles on non-selected polys
+ o  Line of sight (dashed, dotted) for off-curve points
+ o  Repaints for press/release of CTRL/SHIFT during point creation
+*/
+void EditWindow::paintEvent(QPaintEvent * /*event*/)
+{
+       QPainter qtp(this);
+       Painter painter(&qtp);
+       painter.SetRenderHint(QPainter::Antialiasing);
 
-       dc.SetDeviceOrigin(-offsetX, height - (-offsetY));
-       dc.SetAxisOrientation(true, true);
+       Global::viewportHeight = size().height();
+       Global::screenSize = Vector(size().width(), size().height());
 
-// Scrolling can be done by using OffsetViewportOrgEx
-// Scaling can be done by adjusting SetWindowExtEx (it's denominator of txform)
-// you'd use: % = ViewportExt / WindowExt
-// But it makes the window look like crap: fuggetuboutit.
-// Instead, we have to scale EVERYTHING by hand. Crap!
-// It's not *that* bad, but not as convenient either...
+       // Draw coordinate axes
 
-       dc.SetPen(*(wxThePenList->FindOrCreatePen(wxColour(0x00, 0x00, 0xFF), 1, wxDOT)));
-//     dc.DrawLine(0, 0, 10, 10);
+       painter.SetPen(QPen(Qt::blue, 1.0, Qt::DotLine));
+       painter.DrawLine(0, -16384, 0, 16384);
+       painter.DrawLine(-16384, 0, 16384, 0);
 
-    // Draw coordinate axes
+       // Draw rotation center (if active)
 
-       dc.CrossHair(0, 0);
+       if (showRotationCenter)
+       {
+               painter.SetPen(QPen(Qt::red, 2.0, Qt::SolidLine));
+               painter.DrawLine(rotationCenter.x + 7, rotationCenter.y, rotationCenter.x - 7, rotationCenter.y);
+               painter.DrawLine(rotationCenter.x, rotationCenter.y + 7, rotationCenter.x, rotationCenter.y - 7);
+       }
 
-    // Draw points
+       // Draw points
 
        for(int i=0; i<pts.GetNumPoints(); i++)
        {
-               if (i == ptHighlight)
+               /*if (tool == TOOLMultiSelect)
+               {
+                       if (selectedPoints[i])
+                       {
+                               qtp.setPen(QPen(Qt::red, 1.0, Qt::SolidLine));
+                       }
+                       else
+                       {
+                               qtp.setPen(QPen(Qt::black, 1.0, Qt::SolidLine));
+                       }
+               }
+               else*/
+               if (((i == ptHighlight) && (tool != TOOLMultiSelect)) || ((tool == TOOLMultiSelect) && selectedPoints[i]))
                {
-                       dc.SetPen(*(wxThePenList->FindOrCreatePen(wxColour(0xFF, 0x00, 0x00), 1, wxSOLID)));
-//                     SelectObject(hdc, hRedPen1);
+                       painter.SetPen(QPen(Qt::red, 1.0, Qt::SolidLine));
 
                        if (pts.GetOnCurve(i))
                        {
-                               DrawSquareDotN(dc, pts.GetX(i), pts.GetY(i), 7);
-                               DrawSquareDotN(dc, pts.GetX(i), pts.GetY(i), 9);
+                               painter.DrawSquareDotN(pts.GetXY(i), 7);
+                               painter.DrawSquareDotN(pts.GetXY(i), 9);
                        }
                        else
                        {
-                               DrawRoundDotN(dc, pts.GetX(i), pts.GetY(i), 7);
-                               DrawRoundDotN(dc, pts.GetX(i), pts.GetY(i), 9);
+                               painter.DrawRoundDotN(pts.GetXY(i), 7);
+                               painter.DrawRoundDotN(pts.GetXY(i), 9);
                        }
                }
                else if ((i == ptHighlight || i == ptNextHighlight) && tool == TOOLAddPt)
                {
-                       dc.SetPen(*(wxThePenList->FindOrCreatePen(wxColour(0x00, 0xAF, 0x00), 1, wxSOLID)));
-//                     SelectObject(hdc, hGreenPen1);
+                       painter.SetPen(QPen(Qt::green, 1.0, Qt::SolidLine));
 
                        if (pts.GetOnCurve(i))
                        {
-                               DrawSquareDotN(dc, pts.GetX(i), pts.GetY(i), 7);
-                               DrawSquareDotN(dc, pts.GetX(i), pts.GetY(i), 9);
+                               painter.DrawSquareDotN(pts.GetXY(i), 7);
+                               painter.DrawSquareDotN(pts.GetXY(i), 9);
                        }
                        else
                        {
-                               DrawRoundDotN(dc, pts.GetX(i), pts.GetY(i), 7);
-                               DrawRoundDotN(dc, pts.GetX(i), pts.GetY(i), 9);
+                               painter.DrawRoundDotN(pts.GetXY(i), 7);
+                               painter.DrawRoundDotN(pts.GetXY(i), 9);
                        }
                }
                else
                {
-                       dc.SetPen(*(wxThePenList->FindOrCreatePen(wxColour(0x00, 0x00, 0x00), 1, wxSOLID)));
-//                     SelectObject(hdc, hBlackPen1);
+                       painter.SetPen(QPen(Qt::black, 1.0, Qt::SolidLine));
 
+#if 1
                        if (pts.GetOnCurve(i))
-                               DrawSquareDot(dc, pts.GetX(i), pts.GetY(i));
+                               painter.DrawSquareDot(pts.GetXY(i));
                        else
-                               DrawRoundDot(dc, pts.GetX(i), pts.GetY(i));
+                               painter.DrawRoundDot(pts.GetXY(i));
+#else
+                       (pts.GetOnCurve(i) ? DrawSquareDot(p, pts.GetX(i), pts.GetY(i))
+                               : DrawRoundDot(p, pts.GetX(i), pts.GetY(i)));
+#endif
                }
 
                if (tool == TOOLDelPt && i == ptHighlight)
                {
-                       dc.SetPen(*(wxThePenList->FindOrCreatePen(wxColour(0xFF, 0x00, 0x00), 1, wxSOLID)));
-//                     SelectObject(hdc, hRedPen1);
-//                     MoveToEx(hdc, pts.GetX(i) - 5, pts.GetY(i) - 5, NULL);
-//                     LineTo(hdc, pts.GetX(i) + 5, pts.GetY(i) + 5);
-//                     LineTo(hdc, pts.GetX(i) - 5, pts.GetY(i) - 5);//Lameness!
-//                     MoveToEx(hdc, pts.GetX(i) - 5, pts.GetY(i) + 5, NULL);
-//                     LineTo(hdc, pts.GetX(i) + 5, pts.GetY(i) - 5);
-//                     LineTo(hdc, pts.GetX(i) - 5, pts.GetY(i) + 5);//More lameness!!
-                       dc.DrawLine(pts.GetX(i) - 5, pts.GetY(i) - 5, pts.GetX(i) + 5, pts.GetY(i) + 5);
-                       dc.DrawLine(pts.GetX(i) + 5, pts.GetY(i) - 5, pts.GetX(i) - 5, pts.GetY(i) + 5);
+                       painter.SetPen(QPen(Qt::red, 1.0, Qt::SolidLine));
+                       painter.DrawLine(pts.GetX(i) - 5, pts.GetY(i) - 5, pts.GetX(i) + 5, pts.GetY(i) + 5);
+                       painter.DrawLine(pts.GetX(i) + 5, pts.GetY(i) - 5, pts.GetX(i) - 5, pts.GetY(i) + 5);
                }
        }
 
-//             SelectObject(hdc, hBlackPen1);
-       dc.SetPen(*(wxThePenList->FindOrCreatePen(wxColour(0x00, 0x00, 0x00), 1, wxSOLID)));
+       // Draw highlighted point on poly add tool
+       if (tool == TOOLAddPoly)
+       {
+               painter.SetPen(QPen(Qt::red, 1.0, Qt::SolidLine));
+
+               if (addPointOnCurve)
+               {
+                       painter.DrawSquareDotN(addPoint, 7);
+                       painter.DrawSquareDotN(addPoint, 9);
+               }
+               else
+               {
+                       painter.DrawRoundDotN(addPoint, 7);
+                       painter.DrawRoundDotN(addPoint, 9);
+               }
+       }
 
        // Draw curve formed by points
 
-       for(int poly=0; poly<pts.GetNumPolys(); poly++)
+       painter.SetPen(QPen(Qt::black, 1.0, Qt::SolidLine));
+       DrawGlyph(painter, pts);
+
+       if (haveZeroPoint)
        {
-               if (pts.GetNumPoints(poly) > 2)
+               // Rotation code
+               GlyphPoints rotated = pts;
+
+               if (tool == TOOLRotate)
+                       rotated.RotatePoints(rotationAngle, IPoint(rotationCenter.x, rotationCenter.y));
+               else if (tool == TOOLRotatePoly)
                {
-                       // Initial move...
-                       // If it's not on curve, then move to it, otherwise move to last point...
+                       uint16_t poly = rotated.GetPolyForPointNumber(ptHighlight);
+                       rotated.RotatePolyAroundCentroid(poly, rotationAngle);
+               }
+
+               painter.SetPen(QPen(QColor(255, 0, 255), 1.0, Qt::SolidLine));
+               DrawGlyph(painter, rotated);
+       }
+
+       if (selectionInProgress)
+       {
+               painter.SetPen(QPen(QColor(255, 127, 0, 255)));
+               painter.SetBrush(QBrush(QColor(255, 127, 0, 100)));
+               painter.DrawRect(selection);
+       }
+}
+
 
-                       wxCoord x, y;
-       
-                       if (pts.GetOnCurve(poly, pts.GetNumPoints(poly) - 1))
-                               x = (wxCoord)pts.GetX(poly, pts.GetNumPoints(poly) - 1), y = (wxCoord)pts.GetY(poly, pts.GetNumPoints(poly) - 1);
+void EditWindow::DrawGlyph(Painter & p, GlyphPoints & glyph)
+{
+       for(int poly=0; poly<glyph.GetNumPolys(); poly++)
+       {
+#if 0
+               if (glyph.GetNumPoints(poly) < 3)
+                       continue;
+
+               // Initial move: If our start point is on curve, then go to it. Otherwise,
+               // check previous point. If it's on curve, go to it otherwise go the
+               // midpoint between start point and previous (since it's between two curve
+               // control points).
+               IPoint pt = (glyph.GetOnCurve(poly, 0)
+                       ? glyph.GetPoint(poly, 0) : (glyph.GetPrevOnCurve(poly, 0)
+                               ? glyph.GetPrevPoint(poly, 0) : glyph.GetMidpointToPrev(poly, 0)));
+
+// Need to add separate color handling here for polys that are being manipulated...
+
+               for(int i=0; i<glyph.GetNumPoints(poly); i++)
+               {
+                       // If this point and then next are both on curve, we have a line...
+                       if (glyph.GetOnCurve(poly, i) && glyph.GetNextOnCurve(poly, i))
+                       {
+                               IPoint pt2 = glyph.GetNextPoint(poly, i);
+                               p.drawLine(pt.x, pt.y, pt2.x, pt2.y);
+                               pt = pt2;
+                       }
                        else
-                               x = (wxCoord)pts.GetX(poly, 0), y = (wxCoord)pts.GetY(poly, 0);
-       
-                       for(int i=0; i<pts.GetNumPoints(poly); i++)
                        {
-                               if (pts.GetOnCurve(poly, i))
-//                                     LineTo(hdc, pts.GetX(poly, i), pts.GetY(poly, i));
-                               {
-                                       dc.DrawLine(x, y, pts.GetX(poly, i), pts.GetY(poly, i));
-                                       x = (wxCoord)pts.GetX(poly, i), y = (wxCoord)pts.GetY(poly, i);
-                               }
-                               else
-                               {
-                                       uint32 prev = pts.GetPrev(poly, i), next = pts.GetNext(poly, i);
-                                       float px = pts.GetX(poly, prev), py = pts.GetY(poly, prev),
-                                               nx = pts.GetX(poly, next), ny = pts.GetY(poly, next);
-       
-                                       if (!pts.GetOnCurve(poly, prev))
-                                               px = (px + pts.GetX(poly, i)) / 2.0f,
-                                               py = (py + pts.GetY(poly, i)) / 2.0f;
-       
-                                       if (!pts.GetOnCurve(poly, next))
-                                               nx = (nx + pts.GetX(poly, i)) / 2.0f,
-                                               ny = (ny + pts.GetY(poly, i)) / 2.0f;
-       
-                                       Bezier(dc, point(px, py), point(pts.GetX(poly, i), pts.GetY(poly, i)), point(nx, ny));
-                                       x = (wxCoord)nx, y = (wxCoord)ny;
-       
-                                       if (pts.GetOnCurve(poly, next))
-                                               i++;                                    // Following point is on curve, so move past it
-                               }
+                               // Skip point if it's on curve (start of curve--it's already
+                               // been plotted so we don't need to handle it...)
+                               if (glyph.GetOnCurve(poly, i))
+                                       continue;
+
+                               // We are now guaranteed that we are sitting on a curve control point
+                               // (off curve). Figure the extent of the curve: If the following is a
+                               // curve control point, then use the midpoint to it otherwise go to
+                               // the next point since it's on curve.
+                               IPoint pt2 = (glyph.GetNextOnCurve(poly, i)
+                                       ? glyph.GetNextPoint(poly, i) : glyph.GetMidpointToNext(poly, i));
+
+                               Bezier(p, pt, glyph.GetPoint(poly, i), pt2);
+                               pt = pt2;
                        }
                }
+#else
+               DrawGlyphPoly(p, glyph, poly);
+#endif
        }
-
-//             SelectObject(hdc, oldPen);                              // Restore the stuff we disrupted...
-       dc.SetPen(wxNullPen);
-//             SelectObject(hdc, oldBrush);
-//             EndPaint(hWnd, &ps);
 }
 
-void TTEditWindow::OnMouseEvent(wxMouseEvent &e)
+
+/*
+So, to make it draw the point the pointer is pointing at, we need to do something. Either patch the GlyphPoints to handle it, or insert the point into the GlyphPoints and delete it if the user changes tools. Either way, need
+to change the color of the line(s) drawn to the point to signal to the user
+that it isn't finalized until they click the button.
+*/
+void EditWindow::DrawGlyphPoly(Painter & p, GlyphPoints & glyph, uint16_t poly)
 {
-#ifdef DEBUGTP
-//printf("!!! This window %s focus...!\n", (HasCapture() ? "has" : "doesn't have"));
-#endif
-       if (e.RightDown())
+       // Sanity check
+       if (glyph.GetNumPoints(poly) < 3)
+               return;
+
+       IPoint p1 = glyph.GetPrevPoint(poly, 0);
+       IPoint p2 = glyph.GetPoint(poly, 0);
+
+       // Inject the new poly point into the current polygon
+       if ((tool == TOOLAddPoly) && (poly == (glyph.GetNumPolys() - 1)))
        {
-               // Handle tool palette (NOTE: tool palette deals with RightUp event.)
-
-               wxPoint pt = ClientToScreen(e.GetPosition());
-               app.toolPalette->Move(pt);
-               app.toolPalette->Show(true);
-               SetCursor(*wxSTANDARD_CURSOR);
-               app.toolPalette->SetCursor(*wxSTANDARD_CURSOR);
-               app.toolPalette->prevTool = TOOLSelect;
-               app.toolPalette->Refresh(false);
-               CaptureMouse();
+               p1 = IPoint(addPoint.x, addPoint.y, addPointOnCurve);
        }
-       else if (e.RightUp())
+
+       for(int i=0; i<glyph.GetNumPoints(poly); i++)
        {
-               ToolType newTool = app.toolPalette->FindSelectedTool();//, oldTool = tool;
+               IPoint p3 = glyph.GetNextPoint(poly, i);
 
-               // We only change the tool if a new one was actually selected. Otherwise, we do nothing.
-               if (newTool != TOOLNone)
+               if ((tool == TOOLAddPoly) && (poly == (glyph.GetNumPolys() - 1))
+                       && (i == (glyph.GetNumPoints(poly) - 1)))
                {
-                       tool = newTool;
+                       p3 = IPoint(addPoint.x, addPoint.y, addPointOnCurve);
+                       p.SetPen(QPen(Qt::green, 1.0, Qt::SolidLine));
+                       DrawGlyphSegment(p, p1, p2, p3);
+                       p1 = p2;
+                       p2 = p3;
+                       p3 = glyph.GetNextPoint(poly, i);
+               }
 
-                       if (tool == TOOLScroll || tool == TOOLZoom || tool == TOOLAddPoly
-                               || tool == TOOLDelPoly)
-                               ptHighlight = -1;
+               DrawGlyphSegment(p, p1, p2, p3);
 
-                       if (tool == TOOLAddPoly)
-                               polyFirstPoint = true;
-               }
+               p1 = p2;
+               p2 = p3;
+       }
+}
+
+
+//
+// Draw a glyph segment given 3 points
+//
+void EditWindow::DrawGlyphSegment(Painter & p, IPoint p1, IPoint p2, IPoint p3)
+{
+       if (p2.onCurve)
+       {
+               // Skip drawing if the middle point is on curve and the last is off
+               if (p3.onCurve)
+                       p.DrawLine(p2, p3);
+       }
+       else
+       {
+               // The middle point is off curve, and so we need to draw a Bezier curve.
+               // Also, depending on whether or not the previous or follow points are
+               // off curve, we need to draw to the midpoints if so.
+               IPoint mid12 = IPoint((p1.x + p2.x) / 2, (p1.y + p2.y) / 2);
+               IPoint mid23 = IPoint((p2.x + p3.x) / 2, (p2.y + p3.y) / 2);
+               p.DrawBezier((p1.onCurve ? p1 : mid12), p2, (p3.onCurve ? p3 : mid23));
+       }
+}
+
+
+void EditWindow::ClearSelection(void)
+{
+       for(int i=0; i<65536; i++)
+               selectedPoints[i] = false;
+}
 
-               ReleaseMouse();
-               app.toolPalette->Show(false);
-               SetCursor(*(app.cur[tool]));
+
+void EditWindow::mousePressEvent(QMouseEvent * event)
+{
+       if (event->button() == Qt::RightButton)
+       {
+               toolPalette->move(event->globalPos());
+               toolPalette->setVisible(true);
+               setCursor(cur[TOOLSelect]);
+               toolPalette->prevTool = TOOLSelect;
+       }
+       else if (event->button() == Qt::MidButton)
+       {
+               // Scrolling cursor
+               setCursor(cur[11]);
+               ptPrevious = Vector(event->x(), event->y());
+               ptPrevious /= Global::zoom;
        }
-       else if (e.LeftDown())
+       else if (event->button() == Qt::LeftButton)
        {
                if (tool == TOOLScroll || tool == TOOLZoom)
-                       CaptureMouse();                                         // Make sure we capture the mouse when in scroll/zoom mode
+;//meh                 CaptureMouse();                                         // Make sure we capture the mouse when in scroll/zoom mode
+               else if (tool == TOOLMultiSelect)
+               {
+//                     QPoint pt = GetAdjustedMousePosition(event);
+                       Vector pt = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
+                       selectionInProgress = true;
+                       selection.setTopLeft(QPoint(pt.x, pt.y));
+                       selection.setBottomRight(QPoint(pt.x, pt.y));
+               }
                else if (tool == TOOLAddPt)             // "Add Point" tool
                {
-                       if (pts.GetNumPoints() > 0)
+//                     QPoint pt = GetAdjustedMousePosition(event);
+                       Vector pt = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
+                       IPoint pointToAdd(pt.x, pt.y, ((event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier) ? false : true));
+
+                       if (pts.GetNumPoints() < 2)
+                       {
+//                             pts += IPoint(pt.x(), pt.y(), ((event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier) ? false : true));
+                               pts += pointToAdd;
+                               ptHighlight = pts.GetNumPoints() - 1;
+                       }
+                       else
                        {
-                               wxPoint pt = GetAdjustedMousePosition(e);
-                               pts.InsertPoint(pts.GetNext(ptHighlight), pt.x, pt.y, (e.ShiftDown() | e.ControlDown() ? false : true));
+//                             QPoint pt = GetAdjustedMousePosition(event);
+//                             pts.InsertPoint(pts.GetNext(ptHighlight), pt.x(), pt.y(), ((event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier) ? false : true));
+                               pts.InsertPoint(pts.GetNext(ptHighlight), pointToAdd);
                                ptHighlight = ptNextHighlight;
-                               Refresh();
+//                             update();
                        }
+
+                       update();
                }
+// Moved to mouse up routine, so we can slide the point around
+#if 0
                else if (tool == TOOLAddPoly)   // "Add Poly" tool
                {
 #ifdef DEBUGFOO
@@ -274,24 +424,33 @@ WriteLogMsg("Adding point... # polys: %u, # points: %u", pts.GetNumPolys(), pts.
                                pts.AddNewPolyAtEnd();
                        }
 
-                       wxPoint pt = GetAdjustedMousePosition(e);
+//                     QPoint pt = GetAdjustedMousePosition(event);
+                       Vector pt = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
+//printf("GetAdjustedMousePosition = %i, %i\n", pt.x(), pt.y());
                        // Append a point to the end of the structure
-                       pts += IPoint(pt.x, pt.y, (e.ShiftDown() | e.ControlDown() ? false : true));
+                       pts += IPoint(pt.x, pt.y, ((event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier) ? false : true));
                        ptHighlight = pts.GetNumPoints() - 1;
-                       Refresh();
+                       update();
 #ifdef DEBUGFOO
 WriteLogMsg(" --> [# polys: %u, # points: %u]\n", pts.GetNumPolys(), pts.GetNumPoints());
 #endif
                }
+#endif
                else if (tool == TOOLSelect || tool == TOOLPolySelect)
                {
                        if (pts.GetNumPoints() > 0)
                        {
-                               pt = GetAdjustedClientPosition(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
-                               WarpPointer(pt.x, pt.y);
+//                             pt = GetAdjustedClientPosition(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
+                               Vector pt = Painter::CartesianToQtCoords(Vector(pts.GetX(ptHighlight), pts.GetY(ptHighlight)));
+//printf("GetAdjustedClientPosition = %lf, %lf\n", pt.x, pt.y);
+                               QPoint warp(pt.x, pt.y);
+                               QCursor::setPos(mapToGlobal(warp));
 
-                               if (e.ShiftDown() | e.ControlDown())
+                               if (event->modifiers() == Qt::ShiftModifier || event->modifiers() == Qt::ControlModifier)
+                               {
                                        pts.SetOnCurve(ptHighlight, !pts.GetOnCurve(ptHighlight));
+                                       update();
+                               }
                        }
                }
                else if (tool == TOOLDelPt)
@@ -303,185 +462,246 @@ WriteLogMsg(" --> [# polys: %u, # points: %u]\n", pts.GetNumPolys(), pts.GetNumP
 //This assumes that WM_MOUSEMOVE happens before this!
 //The above commented out line should take care of this contingency... !!! FIX !!!
                                pts.DeletePoint(ptHighlight);
-                               Refresh();
+                               update();
                        }
                }
+               else if (tool == TOOLRotate)
+               {
+                       // I think what's needed here is to keep the initial mouse click,
+                       // paint the rotation center, then use the 1st mouse move event to
+                       // establish the rotation "zero line", which becomes the line of
+                       // reference to all subsequent mouse moves.
+//                     rotationCenter = GetAdjustedMousePosition(event);
+                       rotationCenter = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
+                       showRotationCenter = true;
+                       haveZeroPoint = false;
+                       rotationAngle = 0;
+                       update();
+               }
+               else if (tool == TOOLRotatePoly)
+               {
+                       IPoint centroid = pts.GetPolyCentroid(pts.GetPolyForPointNumber(ptHighlight));
+                       rotationCenter = Vector(centroid.x, centroid.y);
+                       showRotationCenter = true;
+//                     pt = GetAdjustedClientPosition(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
+                       Vector pt = Painter::CartesianToQtCoords(Vector(pts.GetX(ptHighlight), pts.GetY(ptHighlight)));
+                       QCursor::setPos(mapToGlobal(QPoint(pt.x, pt.y)));
+                       rotationZeroPoint = Vector(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
+                       haveZeroPoint = true;
+                       rotationAngle = 0;
+                       update();
+               }
+               else if (tool == TOOLFlipWinding)
+               {
+                       pts.InvertPolyDrawSequence(pts.GetPolyForPointNumber(ptHighlight));
+//                     pt = GetAdjustedClientPosition(pts.GetX(ptHighlight), pts.GetY(ptHighlight));
+                       Vector pt = Painter::CartesianToQtCoords(Vector(pts.GetX(ptHighlight), pts.GetY(ptHighlight)));
+                       QCursor::setPos(mapToGlobal(QPoint(pt.x, pt.y)));
+                       update();
+               }
        }
-       else if (e.LeftUp())
-       {
-               if (tool == TOOLScroll || tool == TOOLZoom)
-                       ReleaseMouse();
-       }
-       else if (e.MiddleDown())
+
+       event->accept();
+}
+
+
+void EditWindow::mouseMoveEvent(QMouseEvent * event)
+{
+       if (event->buttons() == Qt::RightButton)
        {
-               SetCursor(*(app.cur[2]));                               // Scrolling cursor
+               ToolType newTool = toolPalette->FindSelectedTool();
+
+               if (newTool != toolPalette->prevTool)
+               {
+                       toolPalette->prevTool = newTool;
+                       toolPalette->repaint();
+               }
        }
-       else if (e.MiddleUp())
+       else if (event->buttons() == Qt::MidButton)
        {
-               SetCursor(*(app.cur[tool]));                    // Restore previous cursor
+               // Calc offset from previous point
+               Vector pt(event->x(), event->y());
+               pt /= Global::zoom;
+               ptOffset = Vector(pt.x - ptPrevious.x, -(pt.y - ptPrevious.y));
+
+// Then multiply it by the scaling factor. Whee!
+               // This looks wacky because we're using screen coords for the offset...
+               // Otherwise, we would subtract both offsets!
+//             offsetX -= ptOffset.x, offsetY += ptOffset.y;
+               Global::origin -= ptOffset;
+               ptPrevious = pt;
+               update();
        }
-       else if (e.Dragging())
+       else if (event->buttons() == Qt::LeftButton)
        {
-               if (e.RightIsDown())
+               if (tool == TOOLAddPt || tool == TOOLAddPoly || tool == TOOLSelect)
                {
-                       ToolType newTool = app.toolPalette->FindSelectedTool();
+                       // Bail out if we have the select tool and no points yet...
+                       if ((tool == TOOLSelect) && (pts.GetNumPoints() == 0))
+                               return;
 
-                       if (newTool != app.toolPalette->prevTool)
+//                     QPoint pt2 = GetAdjustedMousePosition(event);
+                       Vector pt2 = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
+
+                       if (tool != TOOLSelect)
                        {
-                               app.toolPalette->prevTool = newTool;
-                               app.toolPalette->Refresh(false);
+                               addPoint = pt2;
+                               ptHighlight = -1;
+                               // Prolly should move this to the key handlers below...
+//now we do! :-D
+//                             addPointOnCurve = ((event->modifiers() == Qt::ShiftModifier) || (event->modifiers() == Qt::ControlModifier) ? false : true);
                        }
+                       else
+                               pts.SetXY(ptHighlight, pt2.x, pt2.y);
 
-//                     return;
-               }
-               else if (e.MiddleIsDown())
-               {
-                   // Calc offset from previous point
-                       pt = e.GetPosition();
-                       ptOffset.x = pt.x - ptPrevious.x,
-                       ptOffset.y = pt.y - ptPrevious.y;
-
-// Then multiply it by the scaling factor. Whee!
-                       // This looks wacky because we're using screen coords for the offset...
-                       // Otherwise, we would subtract both offsets!
-                       offsetX -= ptOffset.x, offsetY += ptOffset.y;
-                       Refresh();
-//                     ptPrevious = pt;
-
-//                     return;
+                       update();
                }
-
-               else if (e.LeftIsDown())
+               else if (tool == TOOLPolySelect)
                {
-#if 0
-                       if (tool == TOOLScroll)
+                       if (pts.GetNumPoints() > 0)
                        {
-                           // Extract current point from lParam/calc offset from previous point
-
-                               pt = e.GetPosition();
-                               ptOffset.x = pt.x - ptPrevious.x,
-                               ptOffset.y = pt.y - ptPrevious.y;
-
-                               // NOTE: OffsetViewportOrg operates in DEVICE UNITS...
-
-//Seems there's no equivalent for this in wxWidgets...!
-//!!! FIX !!!
-//                             hdc = GetDC(hWnd);
-//                             OffsetViewportOrgEx(hdc, ptOffset.x, ptOffset.y, NULL);
-//                             ReleaseDC(hWnd, hdc);
-
-// this shows that it works, so the logic above must be faulty...
-// And it is. It should convert the coords first, then do the subtraction to figure the offset...
-// Above: DONE
-// Then multiply it by the scaling factor. Whee!
-                               // This looks wacky because we're using screen coords for the offset...
-                               // Otherwise, we would subtract both offsets!
-                               offsetX -= ptOffset.x, offsetY += ptOffset.y;
-                               Refresh();
+//                             QPoint pt2 = GetAdjustedMousePosition(event);
+                               Vector pt2 = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
+                               // Should also set onCurve here as well, depending on keystate
+//Or should we?
+//Would be nice, but we'd need to trap the keyPressEvent() as well, otherwise pressing/releasing
+//the hotkey would show no change until the user moved their mouse.
+                               pts.OffsetPoly(pts.GetPoly(ptHighlight), pt2.x - pts.GetX(ptHighlight), pt2.y - pts.GetY(ptHighlight));
+                               update();
                        }
-                       else
-#endif
-                       if (tool == TOOLAddPt || tool == TOOLAddPoly || tool == TOOLSelect)
+               }
+               else if (tool == TOOLRotate || tool == TOOLRotatePoly)
+               {
+                       if (pts.GetNumPoints() > 0)
                        {
-                               if (tool != TOOLAddPt || pts.GetNumPoints() > 0)//yecch.
+                               if (!haveZeroPoint)
                                {
-//temporary, for testing. BTW, Select drag bug is here...!
-#if 1
-                                       wxPoint pt2 = GetAdjustedMousePosition(e);
-                                       pts.SetXY(ptHighlight, pt2.x, pt2.y);
-                                       Refresh();
-#endif
+//                                     rotationZeroPoint = GetAdjustedMousePosition(event);
+                                       rotationZeroPoint = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
+                                       haveZeroPoint = true;
                                }
-                       }
-                       else if (tool == TOOLPolySelect)
-                       {
-                               if (pts.GetNumPoints() > 0)
+                               else
                                {
-                                       wxPoint pt2 = GetAdjustedMousePosition(e);
-                                       // Should also set onCurve here as well, depending on keystate
-//Or should we?
-                                       pts.OffsetPoly(pts.GetPoly(ptHighlight), pt2.x - pts.GetX(ptHighlight), pt2.y - pts.GetY(ptHighlight));
-                                       Refresh();
+                                       // Figure out the angle between the "zero" vector and the
+                                       // current one, then rotate all points relative to the
+                                       // "zero" vector (done by paint())
+//                                     QPoint currentPoint = GetAdjustedMousePosition(event);
+                                       Vector currentPoint = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
+                                       Vector v1(rotationZeroPoint.x, rotationZeroPoint.y, 0,
+                                               rotationCenter.x, rotationCenter.y, 0);
+                                       Vector v2(currentPoint.x, currentPoint.y, 0,
+                                               rotationCenter.x, rotationCenter.y, 0);
+//                                     rotationAngle = v1.Angle(v2);
+                                       rotationAngle = v2.Angle(v1);
+
+                                       QString s;
+                                       s.sprintf("%.3f degrees", rotationAngle * RADIANS_TO_DEGREES);
+                                       Global::mainWindow->statusBar()->showMessage(s);
                                }
+
+                               update();
                        }
                }
+               else if (tool == TOOLMultiSelect)
+               {
+//                     QPoint pt = GetAdjustedMousePosition(event);
+                       Vector pt = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
+                       selection.setBottomRight(QPoint(pt.x, pt.y));
 
-               ptPrevious = pt;
+                       for(int i=0; i<pts.GetNumPoints(); i++)
+                       {
+                               if (selection.contains(QPoint(pts.GetX(i), pts.GetY(i))))
+                                       selectedPoints[i] = true;
+                               else
+                                       selectedPoints[i] = false;
+                       }
+
+                       update();
+               }
        }
-       else if (e.Moving())
+       else if (event->buttons() == Qt::NoButton)
        {
-//             else    // Moving, not dragging...
-//             {
-                       if (tool == TOOLSelect || tool == TOOLDelPt || tool == TOOLAddPt
-                               || tool == TOOLPolySelect)// || tool == TOOLAddPoly)
+               // Moving, not dragging...
+               if (tool == TOOLSelect || tool == TOOLDelPt || tool == TOOLAddPt
+                       || tool == TOOLPolySelect || tool == TOOLRotatePoly || tool == TOOLFlipWinding)
+               {
+//                     QPoint pt2 = GetAdjustedMousePosition(event);
+                       Vector pt2 = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
+                       double closest = 1.0e+99;
+
+                       for(int i=0; i<pts.GetNumPoints(); i++)
                        {
-                               wxPoint pt2 = GetAdjustedMousePosition(e);
-                               double closest = 1.0e+99;
+                               double dist = ((pt2.x - pts.GetX(i)) * (pt2.x - pts.GetX(i)))
+                                       + ((pt2.y - pts.GetY(i)) * (pt2.y - pts.GetY(i)));
 
-                               for(int i=0; i<pts.GetNumPoints(); i++)
-                               {
-                                       double dist = ((pt2.x - pts.GetX(i)) * (pt2.x - pts.GetX(i)))
-                                               + ((pt2.y - pts.GetY(i)) * (pt2.y - pts.GetY(i)));
+                               if (dist < closest)
+                                       closest = dist, ptHighlight = i;
+                       }
 
-                                       if (dist < closest)
-                                               closest = dist, ptHighlight = i;
-                               }
+                       if (ptHighlight != oldPtHighlight)
+                       {
+                               oldPtHighlight = ptHighlight;
+                               update();
+                       }
 
-                               if (ptHighlight != oldPtHighlight)
-                               {
-                                       oldPtHighlight = ptHighlight;
-                                       Refresh();
-                               }
+                       // What follows here looks like voodoo, but is really simple. What
+                       // we do is check to see if the mouse point has a perpendicular
+                       // intersection with any of the line segments. If it does,
+                       // calculate the length of the perpendicular and choose the
+                       // smallest length. If there is no perpendicular, then choose the
+                       // length of line connecting the closer of either the first
+                       // endpoint or the second and choose the smallest of those.
 
-                               // What follows here looks like voodoo, but is really simple. What we do is
-                               // check to see if the mouse point has a perpendicular intersection with any of
-                               // the line segments. If it does, calculate the length of the perpendicular
-                               // and choose the smallest length. If there is no perpendicular, then choose the
-                               // length of line connecting the closer of either the first endpoint or the
-                               // second and choose the smallest of those.
+                       // There is one bit of math that looks like voodoo to me ATM--will
+                       // explain once I understand it better (the calculation of the
+                       // length of the perpendicular).
 
-                               // There is one bit of math that looks like voodoo to me ATM--will explain once
-                               // I understand it better (the calculation of the length of the perpendicular).
+                       if (pts.GetNumPoints() > 1 && tool == TOOLAddPt)
+                       {
+                               double smallest = 1.0e+99;
 
-                               if (pts.GetNumPoints() > 1 && tool == TOOLAddPt)
+                               for(int i=0; i<pts.GetNumPoints(); i++)
                                {
-                                       double smallest = 1.0e+99;
+                                       int32_t p1x = pts.GetX(i), p1y = pts.GetY(i),
+                                               p2x = pts.GetX(pts.GetNext(i)), p2y = pts.GetY(pts.GetNext(i));
 
-                                       for(int i=0; i<pts.GetNumPoints(); i++)
-                                       {
-                                               int32 p1x = pts.GetX(i), p1y = pts.GetY(i),
-                                                       p2x = pts.GetX(pts.GetNext(i)), p2y = pts.GetY(pts.GetNext(i));
-
-                                               vector ls(p2x, p2y, 0, p1x, p1y, 0), v1(pt2.x, pt2.y, 0, p1x, p1y, 0),
-                                                       v2(pt2.x, pt2.y, 0, p2x, p2y, 0);
-                                               double pp = ls.dot(v1) / ls.length(), dist;
+                                       Vector ls(p2x, p2y, 0, p1x, p1y, 0),
+                                               v1(pt2.x, pt2.y, 0, p1x, p1y, 0),
+                                               v2(pt2.x, pt2.y, 0, p2x, p2y, 0);
+                                       double pp = ls.Dot(v1) / ls.Magnitude(), dist;
 // Geometric interpretation:
-// pp is the paremeterized point on the vector ls where the perpendicular intersects ls.
-// If pp < 0, then the perpendicular lies beyond the 1st endpoint. If pp > length of ls,
-// then the perpendicular lies beyond the 2nd endpoint.
-
-                                               if (pp < 0.0)
-                                                       dist = v1.length();
-                                               else if (pp > ls.length())
-                                                       dist = v2.length();
-                                               else                                    // distance = ?Det?(ls, v1) / |ls|
-                                                       dist = fabs((ls.x * v1.y - v1.x * ls.y) / ls.length());
+// pp is the paremeterized point on the vector ls where the perpendicular
+// intersects ls. If pp < 0, then the perpendicular lies beyond the 1st
+// endpoint. If pp > length of ls, then the perpendicular lies beyond the 2nd
+// endpoint.
+
+                                       if (pp < 0.0)
+                                               dist = v1.Magnitude();
+                                       else if (pp > ls.Magnitude())
+                                               dist = v2.Magnitude();
+                                       else                                    // distance = ?Det?(ls, v1) / |ls|
+                                               dist = fabs((ls.x * v1.y - v1.x * ls.y) / ls.Magnitude());
 
 //The answer to the above looks like it might be found here:
 //
-//If the segment endpoints are s and e, and the point is p, then the test for the perpendicular
-//intercepting the segment is equivalent to insisting that the two dot products {s-e}.{s-p} and
-//{e-s}.{e-p} are both non-negative.  Perpendicular distance from the point to the segment is
-//computed by first computing the area of the triangle the three points form, then dividing by the
-//length of the segment.  Distances are done just by the Pythagorean theorem.  Twice the area of the
-//triangle formed by three points is the determinant of the following matrix:
+//If the segment endpoints are s and e, and the point is p, then the test for
+//the perpendicular intercepting the segment is equivalent to insisting that
+//the two dot products {s-e}.{s-p} and {e-s}.{e-p} are both non-negative.
+//Perpendicular distance from the point to the segment is computed by first
+//computing the area of the triangle the three points form, then dividing by
+//the length of the segment.  Distances are done just by the Pythagorean
+//theorem. Twice the area of the triangle formed by three points is the
+//determinant of the following matrix:
 //
 //sx sy 1
 //ex ey 1
 //px py 1
 //
-//(???) By translating the start point to the origin, this can be rewritten as:
+//By translating the start point to the origin, this can be rewritten as:
 //By subtracting row 1 from all rows, you get the following:
+//[because sx = sy = 0. you could leave out the -sx/y terms below. because we
+//subtracted row 1 from all rows (including row 1) row 1 turns out to be zero.
+//duh!]
 //
 //0         0         0
 //(ex - sx) (ey - sy) 0
@@ -489,1141 +709,162 @@ WriteLogMsg(" --> [# polys: %u, # points: %u]\n", pts.GetNumPolys(), pts.GetNumP
 //
 //which greatly simplifies the calculation of the determinant.
 
-                                               if (dist < smallest)
-                                                       smallest = dist, ptNextHighlight = pts.GetNext(i), ptHighlight = i;
-                                       }
+                                       if (dist < smallest)
+                                               smallest = dist, ptNextHighlight = pts.GetNext(i), ptHighlight = i;
+                               }
 
-                                       if (ptNextHighlight != oldPtNextHighlight)
-                                       {
-                                               oldPtNextHighlight = ptNextHighlight;
-                                               Refresh();
-                                       }
+                               if (ptNextHighlight != oldPtNextHighlight)
+                               {
+                                       oldPtNextHighlight = ptNextHighlight;
+                                       update();
                                }
                        }
-//             }
-
-               ptPrevious = e.GetPosition();
-       }
-}
-
-wxPoint TTEditWindow::GetAdjustedMousePosition(wxMouseEvent &e)
-{
-       wxCoord width, height;
-       wxClientDC dc(this);
-
-       dc.GetSize(&width, &height);
-       dc.SetDeviceOrigin(-offsetX, height - (-offsetY));
-       dc.SetAxisOrientation(true, true);
-
-#if 0
-wxStatusBar * sb = ((wxFrame *)GetParent())->GetStatusBar();
-wxString s;
-s.Printf("Logical mouse pos: %d, %d (%d, %d)", pt.x, pt.y, width, height);
-sb->SetStatusText(s);
-#endif
-
-       return e.GetLogicalPosition(dc);
-}
+               }
 
-wxPoint TTEditWindow::GetAdjustedClientPosition(wxCoord x, wxCoord y)
-{
-       wxCoord width, height;
-       wxClientDC dc(this);
+               ptPrevious = Vector(event->x(), event->y());
+               addPoint = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
+//handled by real key handlers now...
+//             addPointOnCurve = ((event->modifiers() == Qt::ShiftModifier) || (event->modifiers() == Qt::ControlModifier) ? false : true);
 
-       dc.GetSize(&width, &height);
-       dc.SetDeviceOrigin(-offsetX, height - (-offsetY));
-       dc.SetAxisOrientation(true, true);
+               if (tool == TOOLAddPoly)
+                       update();
+       }
 
-       return wxPoint(dc.LogicalToDeviceX(x), dc.LogicalToDeviceY(y));
+       event->accept();
 }
 
 
-#if 0
-
-!!! OLD STUFF !!!
-
-
-LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam)
+void EditWindow::mouseReleaseEvent(QMouseEvent * event)
 {
-       RECT rc1, rc2;
-       HDC hdc;
-       POINT pt, ptOffset;
-       SIZE sz;
-       PAINTSTRUCT ps;
-
-       switch (msgID)
+       if (event->button() == Qt::RightButton)
        {
-       case WM_CREATE:
-
-               MiscCenterWnd(hWnd, GetDesktopWindow());
-               InitCommonControls();
-               hStatusBar = CreateStatusWindow(WS_CHILD | WS_VISIBLE, statusBarTxt, hWnd, ID_STATUSBAR);
-
-               if (!hStatusBar)
-                       return -1;
-
-// clean this crap up!
-// well, the only crappy thing here is using a POINT as an int array, but otherwise, this is OK
-               wsprintf(strBuf, zoom, 1000);
-               hdc = GetDC(hWnd);
-               GetTextExtentPoint32(hdc, strBuf, lstrlen(strBuf), &sz);
-               ReleaseDC(hWnd, hdc);
-               zoomWndWidth = sz.cx;
-               wsprintf(strBuf, zoom, 100);
-
-               GetClientRect(hWnd, &rc1);
-               pt.x = rc1.right - zoomWndWidth, pt.y = -1;
-               SendMessage(hStatusBar, SB_SETPARTS, 2, (LPARAM)&pt);
-               SendMessage(hStatusBar, SB_SETTEXT, (0 | SBT_NOBORDERS), (LPARAM)statusBarTxt);
-               SendMessage(hStatusBar, SB_SETTEXT, 1, (LPARAM)strBuf);
-
-               hToolBar = CreateToolbarEx(hWnd, WS_CHILD | WS_BORDER | WS_VISIBLE | TBSTYLE_TOOLTIPS,
-                       IDR_TOOLBAR1, 3, hInst, IDB_TOOLBAR1, tbButtons, 4, 16, 16, 16, 16, sizeof(TBBUTTON));
-
-               if (!hToolBar)
-                       return -1;
-
-               CreateNewDoc();
-
-// The following can only be done because we use a private DC (using "CS_OWNDC")
-// (Is that true???)
-// Set the mapping to draw the character so it fits in the viewport...
-               hdc = GetDC(hWnd);
-               GetClientRect(hWnd, &rc1);
-               GetClientRect(hStatusBar, &rc2);
-               rc1.bottom -= rc2.bottom;
-               SetMapMode(hdc, MM_ISOTROPIC);
-               SetWindowExtEx(hdc, rc1.right, rc1.bottom, NULL);
-               SetViewportExtEx(hdc, rc1.right, -rc1.bottom, NULL);
-               SetViewportOrgEx(hdc, 0, rc1.bottom, NULL);
-               ReleaseDC(hWnd, hdc);
-               break;
-
-       case WM_CLOSE:
-
-               if (SaveChanges())
-               {
-                       wpM.length = wpC.length = sizeof(WINDOWPLACEMENT);
-                       GetWindowPlacement(hMainWnd, &wpM);
-                       GetWindowPlacement(hCharWnd, &wpC);
+               ToolType newTool = toolPalette->FindSelectedTool();
 
-                       if (!IsWindowVisible(hCharWnd))         // Needed because Windows lies about visibility
-                               wpC.showCmd = SW_HIDE;
+               // We only change the tool if a new one was actually selected. Otherwise, we do nothing.
+               if (newTool != TOOLNone)
+               {
+                       tool = newTool;
 
-                       hdc = GetDC(hWnd);
-                       GetViewportOrgEx(hdc, &ptVPM);
-                       ReleaseDC(hWnd, hdc);
+                       if (tool == TOOLScroll || tool == TOOLZoom || tool == TOOLAddPoly
+                               || tool == TOOLDelPoly)
+                               ptHighlight = -1;
 
-                       DestroyWindow(hWnd);
+                       if (tool == TOOLAddPoly)
+                               polyFirstPoint = true;
                }
 
-               break;
+               toolPalette->setVisible(false);
+               setCursor(cur[tool]);
+               // Just in case we changed highlighting style with the new tool...
+               update();
+       }
+       else if (event->button() == Qt::MidButton)
+       {
+               setCursor(cur[tool]);                                           // Restore previous cursor
+       }
+       else if (event->button() == Qt::LeftButton)
+       {
+               if (showRotationCenter)
+               {
+                       showRotationCenter = false;
+                       haveZeroPoint = false;
 
-       case WM_DESTROY:
+                       if (tool == TOOLRotate)
+                               pts.RotatePoints(rotationAngle, IPoint(rotationCenter.x, rotationCenter.y));
+                       else
+                       {
+                               uint16_t poly = pts.GetPolyForPointNumber(ptHighlight);
+                               pts.RotatePolyAroundCentroid(poly, rotationAngle);
+                       }
 
-               PostQuitMessage(0);
-               break;
+                       update();
+                       Global::mainWindow->statusBar()->showMessage("");
+               }
 
-       case WM_NCLBUTTONDOWN:
+//             if (tool == TOOLScroll || tool == TOOLZoom)
+//                     ReleaseMouse();
+//this is prolly too much
+               Global::charWnd->MakePathFromPoints(&pts);
+               Global::charWnd->update();
 
-               if (wParam == HTCAPTION)
+               if (tool == TOOLMultiSelect)
                {
-                       NCMouseDown = true;
-                       GetWindowRect(hMainWnd, &rc1);
-                       GetWindowRect(hCharWnd, &rc2);
-                       ptWinOffset.x = rc2.left - rc1.left;
-                       ptWinOffset.y = rc2.top - rc1.top;
+                       selectionInProgress = false;
+                       update();
                }
-                   
-               // Let Windows do its thing with this msg, or weird things will happen...
-
-               DefWindowProc(hWnd, msgID, wParam, lParam);
-               NCMouseDown = false;
-               break;
-
-       case WM_WINDOWPOSCHANGING:
-
-               if (NCMouseDown)
+               else if (tool == TOOLAddPoly)   // "Add Poly" tool
                {
-                       WINDOWPOS * wp = (WINDOWPOS *)lParam;
+#ifdef DEBUGFOO
+WriteLogMsg("Adding point... # polys: %u, # points: %u", pts.GetNumPolys(), pts.GetNumPoints());
+#endif
+                       if (polyFirstPoint)
+                       {
+                               polyFirstPoint = false;
+                               pts.AddNewPolyAtEnd();
+                       }
 
-                       if (wp->hwnd == hMainWnd && !(wp->flags & SWP_NOMOVE))
-                               SetWindowPos(hCharWnd, 0, wp->x + ptWinOffset.x, wp->y + ptWinOffset.y,
-                                               0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
+//                     QPoint pt = GetAdjustedMousePosition(event);
+                       Vector pt = Painter::QtToCartesianCoords(Vector(event->x(), event->y()));
+//printf("GetAdjustedMousePosition = %i, %i\n", pt.x(), pt.y());
+                       // Append a point to the end of the structure
+                       pts += IPoint(pt.x, pt.y, addPointOnCurve);
+//                     ptHighlight = pts.GetNumPoints() - 1;
+                       update();
+#ifdef DEBUGFOO
+WriteLogMsg(" --> [# polys: %u, # points: %u]\n", pts.GetNumPolys(), pts.GetNumPoints());
+#endif
                }
+       }
 
-               return DefWindowProc(hWnd, msgID, wParam, lParam);      // Seems this is needed... Bleah!
-
-       case WM_PAINT:
-       {
-               hdc = BeginPaint(hWnd, &ps);
+       event->accept();
+}
 
-// Scrolling can be done by using OffsetViewportOrgEx
-// Scaling can be done by adjusting SetWindowExtEx (it's denominator of txform)
-// you'd use: % = ViewportExt / WindowExt
-// But it makes the window look like crap: fuggetuboutit.
-// Instead, we have to scale EVERYTHING by hand. Crap!
 
-               // Apparently, you *must* save the individual object types (pen, brush, etc.)
+void EditWindow::keyPressEvent(QKeyEvent * event)
+{
+       // We do this here because of the ptHighlight nonsense. If we're in
+       // the add poly tool, we'll never see this if it's under the 'sanity'
+       // check (which is needed for the arrow key shite, but still...)
+       if ((event->key() == Qt::Key_Shift) || (event->key() == Qt::Key_Control))
+       {
+               addPointOnCurve = false;
+               update();
+       }
 
-               HGDIOBJ oldPen = SelectObject(hdc, hBluePen1),
-                       oldBrush = SelectObject(hdc, hNullBrush);
+       // Sanity checking...
+       if (ptHighlight == -1)
+               return;
 
-           // Draw coordinate axes
+       if (event->key() == Qt::Key_Up)
+       {
+               pts.SetXY(ptHighlight, pts.GetX(ptHighlight), pts.GetY(ptHighlight) + 1);
+       }
+       else if (event->key() == Qt::Key_Down)
+               pts.SetXY(ptHighlight, pts.GetX(ptHighlight), pts.GetY(ptHighlight) - 1);
+       else if (event->key() == Qt::Key_Right)
+               pts.SetXY(ptHighlight, pts.GetX(ptHighlight) + 1, pts.GetY(ptHighlight));
+       else if (event->key() == Qt::Key_Left)
+               pts.SetXY(ptHighlight, pts.GetX(ptHighlight) - 1, pts.GetY(ptHighlight));
+       else
+               return;
 
-               MoveToEx(hdc, 0, -32000, NULL);
-               LineTo(hdc, 0, 32000);
-               MoveToEx(hdc, -32000, 0, NULL);
-               LineTo(hdc, 32000, 0);
+//Not need but you need to call the base class for some reason??
+//     event->accept();
+       update();
+       Global::charWnd->MakePathFromPoints(&pts);
+       Global::charWnd->update();
+}
 
-           // Draw points
 
-               for(int i=0; i<pts.GetNumPoints(); i++)
-               {
-                       if (i == ptHighlight)
-                       {
-                               SelectObject(hdc, hRedPen1);
+void EditWindow::keyReleaseEvent(QKeyEvent * event)
+{
+       if ((event->key() == Qt::Key_Shift) || (event->key() == Qt::Key_Control))
+       {
+               addPointOnCurve = true;
+       }
+       else
+               return;
 
-                               if (pts.GetOnCurve(i))
-                               {
-                                       DrawSquareDotN(hdc, pts.GetX(i), pts.GetY(i), 7);
-                                       DrawSquareDotN(hdc, pts.GetX(i), pts.GetY(i), 9);
-                               }
-                               else
-                               {
-                                       DrawRoundDotN(hdc, pts.GetX(i), pts.GetY(i), 7);
-                                       DrawRoundDotN(hdc, pts.GetX(i), pts.GetY(i), 9);
-                               }
-                       }
-                       else if ((i == ptHighlight || i == ptNextHighlight) && currentTool == TOOLAddPt)
-                       {
-                               SelectObject(hdc, hGreenPen1);
+       update();
+}
 
-                               if (pts.GetOnCurve(i))
-                               {
-                                       DrawSquareDotN(hdc, pts.GetX(i), pts.GetY(i), 7);
-                                       DrawSquareDotN(hdc, pts.GetX(i), pts.GetY(i), 9);
-                               }
-                               else
-                               {
-                                       DrawRoundDotN(hdc, pts.GetX(i), pts.GetY(i), 7);
-                                       DrawRoundDotN(hdc, pts.GetX(i), pts.GetY(i), 9);
-                               }
-                       }
-                       else
-                       {
-                               SelectObject(hdc, hBlackPen1);
-
-                               if (pts.GetOnCurve(i))
-                                       DrawSquareDot(hdc, pts.GetX(i), pts.GetY(i));
-                               else
-                                       DrawRoundDot(hdc, pts.GetX(i), pts.GetY(i));
-                       }
-
-                       if (currentTool == TOOLDelPt && i == ptHighlight)
-                       {
-                               SelectObject(hdc, hRedPen1);
-                               MoveToEx(hdc, pts.GetX(i) - 5, pts.GetY(i) - 5, NULL);
-                               LineTo(hdc, pts.GetX(i) + 5, pts.GetY(i) + 5);
-                               LineTo(hdc, pts.GetX(i) - 5, pts.GetY(i) - 5);//Lameness!
-                               MoveToEx(hdc, pts.GetX(i) - 5, pts.GetY(i) + 5, NULL);
-                               LineTo(hdc, pts.GetX(i) + 5, pts.GetY(i) - 5);
-                               LineTo(hdc, pts.GetX(i) - 5, pts.GetY(i) + 5);//More lameness!!
-                       }
-               }
-
-               SelectObject(hdc, hBlackPen1);
-
-               // Draw curve formed by points
-
-               for(int poly=0; poly<pts.GetNumPolys(); poly++)
-               {
-                       if (pts.GetNumPoints(poly) > 2)
-                       {
-                               // Initial move...
-                               // If it's not on curve, then move to it, otherwise move to last point...
-       
-                               if (pts.GetOnCurve(poly, pts.GetNumPoints(poly) - 1))
-                                       MoveToEx(hdc, pts.GetX(poly, pts.GetNumPoints(poly) - 1), pts.GetY(poly, pts.GetNumPoints(poly) - 1), NULL);
-                               else
-                                       MoveToEx(hdc, pts.GetX(poly, 0), pts.GetY(poly, 0), NULL);
-       
-                               for(int i=0; i<pts.GetNumPoints(poly); i++)
-                               {
-                                       if (pts.GetOnCurve(poly, i))
-                                               LineTo(hdc, pts.GetX(poly, i), pts.GetY(poly, i));
-                                       else
-                                       {
-                                               uint32 prev = pts.GetPrev(poly, i), next = pts.GetNext(poly, i);
-                                               float px = pts.GetX(poly, prev), py = pts.GetY(poly, prev),
-                                                       nx = pts.GetX(poly, next), ny = pts.GetY(poly, next);
-       
-                                               if (!pts.GetOnCurve(poly, prev))
-                                                       px = (px + pts.GetX(poly, i)) / 2.0f,
-                                                       py = (py + pts.GetY(poly, i)) / 2.0f;
-       
-                                               if (!pts.GetOnCurve(poly, next))
-                                                       nx = (nx + pts.GetX(poly, i)) / 2.0f,
-                                                       ny = (ny + pts.GetY(poly, i)) / 2.0f;
-       
-                                               Bezier(hdc, point(px, py), point(pts.GetX(poly, i), pts.GetY(poly, i)), point(nx, ny));
-       
-                                               if (pts.GetOnCurve(poly, next))
-                                                       i++;                                    // Following point is on curve, so move past it
-                                       }
-                               }
-                       }
-               }
-
-               SelectObject(hdc, oldPen);                              // Restore the stuff we disrupted...
-               SelectObject(hdc, oldBrush);
-               EndPaint(hWnd, &ps);
-               break;
-       }
-       case WM_SIZE:
-
-               // Apparently this is needed since these windows don't update themselves.
-               SendMessage(hStatusBar, msgID, wParam, lParam);
-               SendMessage(hToolBar, msgID, wParam, lParam);
-
-               // This is needed to make the 2nd status pane visible
-               GetClientRect(hWnd, &rc1);
-               pt.x = rc1.right - zoomWndWidth, pt.y = -1;
-               SendMessage(hStatusBar, SB_SETPARTS, 2, (LPARAM)&pt);
-               break;
-
-       case WM_RBUTTONDOWN:
-
-               GetCursorPos(&pt);
-               SetWindowPos(hToolPalWnd, 0, pt.x, pt.y, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_SHOWWINDOW);
-               SetFocus(hToolPalWnd);
-               SetCapture(hToolPalWnd);                                // Ensure tool palette gets RButtonUp
-               SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW)));        // Tool pallete has "regular" cursor
-               break;
-
-       case WM_LBUTTONDOWN:
-
-               mouseDown = true;
-
-               if (currentTool == TOOLScroll || currentTool == TOOLZoom)
-                       SetCapture(hWnd);                                       // Make sure we capture the mouse when in scroll/zoom mode
-               else if (currentTool == TOOLAddPt)              // "Add Point" tool
-               {
-                       if (pts.GetNumPoints() > 0)
-                       {
-//Do we really need to put a cap on this???
-//Maybe...
-//                             if (pts.GetNumPoints() < 16)
-//                             {
-                               pt.x = lParam & 0xFFFF, pt.y = lParam >> 16;
-                               hdc = GetDC(hWnd);
-                               DPtoLP(hdc, &pt, 1);
-                               pts.InsertPoint(pts.GetNext(ptHighlight), pt.x, pt.y, (wParam & (MK_SHIFT | MK_CONTROL) ? false : true));
-                               ptHighlight = ptNextHighlight;
-                               ReleaseDC(hWnd, hdc);
-                               InvalidateRect(hWnd, NULL, TRUE);
-//                             }
-                       }
-               }
-               else if (currentTool == TOOLAddPoly)    // "Add Poly" tool
-               {
-#ifdef DEBUGFOO
-wsprintf(strBuf, "Adding point... # polys: %u, # points: %u", pts.GetNumPolys(), pts.GetNumPoints());
-WriteLogMsg(strBuf);
-#endif
-                       if (polyFirstPoint)
-                       {
-                               polyFirstPoint = false;
-                               pts.AddNewPolyAtEnd();
-                       }
-
-//Do we really need to put a cap on this???
-//Maybe...
-//                     if (pts.GetNumPoints() < 16)
-//                     {
-                       pt.x = lParam & 0xFFFF, pt.y = lParam >> 16;
-                       hdc = GetDC(hWnd);
-                       DPtoLP(hdc, &pt, 1);
-                       ReleaseDC(hWnd, hdc);
-                       // Append a point to the end of the structure
-                       pts += IPoint(pt.x, pt.y, (wParam & (MK_SHIFT | MK_CONTROL) ? false : true));
-ptHighlight = pts.GetNumPoints() - 1;
-                       InvalidateRect(hWnd, NULL, TRUE);
-//                     }
-#ifdef DEBUGFOO
-wsprintf(strBuf, " --> [# polys: %u, # points: %u]\xD\xA", pts.GetNumPolys(), pts.GetNumPoints());
-WriteLogMsg(strBuf);
-#endif
-               }
-               else if (currentTool == TOOLSelect || currentTool == TOOLPolySelect)
-               {
-                       if (pts.GetNumPoints() > 0)
-                       {
-                               pt.x = pts.GetX(ptHighlight), pt.y = pts.GetY(ptHighlight);
-                               hdc = GetDC(hWnd);
-                               LPtoDP(hdc, &pt, 1);
-                               ClientToScreen(hWnd, &pt);
-                               SetCursorPos(pt.x, pt.y);
-                               ReleaseDC(hWnd, hdc);
-
-                               if (wParam & (MK_SHIFT | MK_CONTROL))
-                                       pts.SetOnCurve(ptHighlight, !pts.GetOnCurve(ptHighlight));
-                       }
-               }
-               else if (currentTool == TOOLDelPt)
-               {
-                       if (pts.GetNumPoints() > 0)
-//Or could use:
-//                     if (ptHighlight != -1)
-                       {
-//This assumes that WM_MOUSEMOVE happens before this!
-//The above commented out line should take care of this contingency... !!! FIX !!!
-                               pts.DeletePoint(ptHighlight);
-                               InvalidateRect(hWnd, NULL, TRUE);
-                       }
-               }
-
-               break;
-
-       case WM_LBUTTONUP:
-
-               mouseDown = false;
-
-               if (currentTool == TOOLScroll || currentTool == TOOLZoom)
-                       ReleaseCapture();
-
-               break;
-
-       case WM_MOUSEMOVE:
-
-               SetCursor(hCur[currentTool]);
-
-           // Extract current point from lParam/calc offset from previous point
-
-               pt.x = lParam & 0xFFFF, pt.y = lParam >> 16;
-               ptOffset.x = pt.x - ptPrevious.x,
-               ptOffset.y = pt.y - ptPrevious.y;
-
-               if (mouseDown)
-               {
-                       if (currentTool == TOOLScroll)
-                       {
-                               // NOTE: OffsetViewportOrg operates in DEVICE UNITS...
-
-                               hdc = GetDC(hWnd);
-                               OffsetViewportOrgEx(hdc, ptOffset.x, ptOffset.y, NULL);
-                               ReleaseDC(hWnd, hdc);
-
-// this shows that it works, so the logic above must be faulty...
-// And it is. It should convert the coords first, then do the subtraction to figure the offset...
-// Above: DONE
-// Then multiply it by the scaling factor. Whee!
-
-                               InvalidateRect(hWnd, NULL, TRUE);
-//                             SendMessage(hWnd, WM_PAINT, NULL, NULL);
-                       }
-                       else if (currentTool == TOOLAddPt || currentTool == TOOLAddPoly || currentTool == TOOLSelect)
-                       {
-                               if (currentTool != TOOLAddPt || pts.GetNumPoints() > 0)//yecch.
-                               {
-                                       POINT pt2;
-                                       pt2.x = pt.x, pt2.y = pt.y;
-                                       // Should also set onCurve here as well, depending on keystate
-//Or should we?
-                                       hdc = GetDC(hWnd);
-                                       DPtoLP(hdc, &pt2, 1);
-                                       pts.SetXY(ptHighlight, pt2.x, pt2.y);
-                                       ReleaseDC(hWnd, hdc);
-                                       InvalidateRect(hWnd, NULL, TRUE);
-                               }
-                       }
-                       else if (currentTool == TOOLPolySelect)
-                       {
-                               if (pts.GetNumPoints() > 0)
-                               {
-                                       POINT pt2;
-                                       pt2.x = pt.x, pt2.y = pt.y;
-                                       // Should also set onCurve here as well, depending on keystate
-//Or should we?
-                                       hdc = GetDC(hWnd);
-                                       DPtoLP(hdc, &pt2, 1);
-                                       pts.OffsetPoly(pts.GetPoly(ptHighlight), pt2.x - pts.GetX(ptHighlight), pt2.y - pts.GetY(ptHighlight));
-                                       ReleaseDC(hWnd, hdc);
-                                       InvalidateRect(hWnd, NULL, TRUE);
-                               }
-                       }
-               }
-               else
-               {
-                       if (currentTool == TOOLSelect || currentTool == TOOLDelPt || currentTool == TOOLAddPt
-                               || currentTool == TOOLPolySelect)// || currentTool == TOOLAddPoly)
-                       {
-                               POINT pt2;
-                               pt2.x = pt.x, pt2.y = pt.y;
-                               hdc = GetDC(hWnd);
-                               DPtoLP(hdc, &pt2, 1);
-                               ReleaseDC(hWnd, hdc);
-
-                               double closest = 1.0e+99;
-
-                               for(int i=0; i<pts.GetNumPoints(); i++)
-                               {
-                                       double dist = ((pt2.x - pts.GetX(i)) * (pt2.x - pts.GetX(i)))
-                                               + ((pt2.y - pts.GetY(i)) * (pt2.y - pts.GetY(i)));
-
-                                       if (dist < closest)
-                                               closest = dist, ptHighlight = i;
-                               }
-
-                               if (ptHighlight != oldPtHighlight)
-                               {
-                                       oldPtHighlight = ptHighlight;
-                                       InvalidateRect(hWnd, NULL, TRUE);
-                               }
-
-                               // What follows here looks like voodoo, but is really simple. What we do is
-                               // check to see if the mouse point has a perpendicular intersection with any of
-                               // the line segments. If it does, calculate the length of the perpendicular
-                               // and choose the smallest length. If there is no perpendicular, then choose the
-                               // length of line connecting the closer of either the first endpoint or the
-                               // second and choose the smallest of those.
-
-                               // There is one bit of math that looks like voodoo to me ATM--will explain once
-                               // I understand it better (the calculation of the length of the perpendicular).
-
-                               if (pts.GetNumPoints() > 1 && currentTool == TOOLAddPt)
-                               {
-                                       double smallest = 1.0e+99;
-
-                                       for(int i=0; i<pts.GetNumPoints(); i++)
-                                       {
-                                               int32 p1x = pts.GetX(i), p1y = pts.GetY(i),
-                                                       p2x = pts.GetX(pts.GetNext(i)), p2y = pts.GetY(pts.GetNext(i));
-
-                                               vector ls(p2x, p2y, 0, p1x, p1y, 0), v1(pt2.x, pt2.y, 0, p1x, p1y, 0),
-                                                       v2(pt2.x, pt2.y, 0, p2x, p2y, 0);
-                                               double pp = ls.dot(v1) / ls.length(), dist;
-// Geometric interpretation:
-// pp is the paremeterized point on the vector ls where the perpendicular intersects ls.
-// If pp < 0, then the perpendicular lies beyond the 1st endpoint. If pp > length of ls,
-// then the perpendicular lies beyond the 2nd endpoint.
-
-                                               if (pp < 0.0)
-                                                       dist = v1.length();
-                                               else if (pp > ls.length())
-                                                       dist = v2.length();
-                                               else                                    // distance = ?Det?(ls, v1) / |ls|
-                                                       dist = abs((ls.x * v1.y - v1.x * ls.y) / ls.length());
-
-//The answer to the above looks like it might be found here:
-//
-//If the segment endpoints are s and e, and the point is p, then the test for the perpendicular
-//intercepting the segment is equivalent to insisting that the two dot products {s-e}.{s-p} and
-//{e-s}.{e-p} are both non-negative.  Perpendicular distance from the point to the segment is
-//computed by first computing the area of the triangle the three points form, then dividing by the
-//length of the segment.  Distances are done just by the Pythagorean theorem.  Twice the area of the
-//triangle formed by three points is the determinant of the following matrix:
-//
-//sx sy 1
-//ex ey 1
-//px py 1
-//
-//(???) By translating the start point to the origin, this can be rewritten as:
-//By subtracting row 1 from all rows, you get the following:
-//
-//0         0         0
-//(ex - sx) (ey - sy) 0
-//(px - sx) (py - sy) 0
-//
-//which greatly simplifies the calculation of the determinant.
-
-                                               if (dist < smallest)
-                                                       smallest = dist, ptNextHighlight = pts.GetNext(i), ptHighlight = i;
-                                       }
-
-                                       if (ptNextHighlight != oldPtNextHighlight)
-                                       {
-                                               oldPtNextHighlight = ptNextHighlight;
-                                               InvalidateRect(hWnd, NULL, TRUE);
-                                       }
-                               }
-                       }
-               }
-
-               ptPrevious.x = pt.x, ptPrevious.y = pt.y;
-
-               break;
-
-       case WM_NOTIFY:
-
-               if (((NMHDR *)lParam)->code == TTN_NEEDTEXT)
-               {
-                       LoadString(hInst, ((TOOLTIPTEXT *)lParam)->hdr.idFrom + 0x80, toolTipTxt, 16);
-                       ((TOOLTIPTEXT *)lParam)->lpszText = toolTipTxt;
-               }
-
-               break;
-
-       case WM_MENUSELECT:
-       {
-               statusBarTxt[0] = 0;                                    // Clear status bar text
-               uint16 flags = wParam >> 16;                    // Extract flags
-
-               if (!(flags & MFT_SEPARATOR))
-               {
-                       uint16 id = wParam & 0xFFFF;
-
-                       if (flags & MF_POPUP)
-                       {
-                               if (flags & MF_SYSMENU)
-                                       id = IDS_SYSMENU;
-                               else
-                                       id = IDM_FILEMENU + wParam;
-                       }
-
-                       LoadString(hInst, id, statusBarTxt, 64);
-               }
-
-               SendMessage(hStatusBar, SB_SETTEXT, 0 + SBT_NOBORDERS, (LPARAM)statusBarTxt);
-               break;
-       }
-       case WM_COMMAND:
-       {
-               uint16 cmd = wParam & 0xFFFF;
-
-               if (cmd == IDM_NEW)
-               {
-//                   call   CmdIDM_NEW
-               }
-               else if (cmd == IDM_OPEN)
-               {
-//                   call   SaveChanges
-//                   .IF (eax)
-//                     movmov ofn.hwndOwner, eax, hMainWnd
-//                     mov    ofn.Flags, OFN_PATHMUSTEXIST + OFN_FILEMUSTEXIST
-//                     invoke GetOpenFileName, ADDR ofn
-//                     .IF (eax)
-////////
-//jmp @F
-//szDMsg1a     BYTE    "Could not open the file (GetOpenFileName)...", 0
-//szDMsg1b     BYTE    "Open error!", 0
-//szDMsg1c     BYTE    "About to attempt to open file...", 0
-//@@:
-////invoke MessageBox, hWnd, ADDR szDMsg1a, ADDR szDMsg1b, MB_ICONERROR or MB_OK
-//invoke MessageBox, hMainWnd, ADDR szDMsg1c, ADDR szFile, MB_ICONERROR or MB_OK
-//                       invoke LoadTTF, ADDR szFile
-//
-//////
-//                       // <<< FILE OPEN CODE HERE >>>
-//                       or     fFileStatus, NAMEDbit
-//                       and    fFileStatus, NOT CHANGEDbit
-//                       call   NewWindowName
-//                       mov    eax, TRUE      // return TRUE
-//                       jmp    Return
-//                       //��������������������������������������
-//OpenError:             invoke GetLastError
-//                       // <<< FILE OPEN ERROR CODE HERE >>>
-//                     .ENDIF
-//                     zero   eax      // return FALSE
-//                   .ENDIF
-               }
-               else if (cmd == IDM_SAVEAS)
-               {
-//                   and    fFileStatus, NOT NAMEDbit
-//                   call   CmdIDM_SAVE
-               }
-               else if (cmd == IDM_SAVE)
-               {
-//                   call   CmdIDM_SAVE
-               }
-               else if (cmd == IDM_ABOUT)
-                       DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_ABOUT), hMainWnd, AboutProc, NULL);
-               else if (cmd == IDM_EXIT)
-                       SendMessage(hWnd, WM_CLOSE, 0, 0);
-               else if (cmd == ID_TBCHARWIN)
-               {
-                       ShowWindow(hCharWnd, (IsWindowVisible(hCharWnd) ? SW_HIDE : SW_SHOWNOACTIVATE));
-
-#ifdef DEBUGFOO
-wpC.length = sizeof(WINDOWPLACEMENT);
-GetWindowPlacement(hCharWnd, &wpC);
-wsprintf(strBuf, "Char window showCmd = %08X...\n", wpC.showCmd);
-WriteLogMsg(strBuf);
-#endif
-               }
-               else
-                       return DefWindowProc(hWnd, msgID, wParam, lParam);
-
-               break;
-       }
-       default:
-               return DefWindowProc(hWnd, msgID, wParam, lParam);
-       }
-
-       return 0;
-}
-
-//
-// Initialize TTF data
-//
-void CreateNewDoc(void)
-{
-}
-
-//
-// Save changes to document before quitting
-//
-bool SaveChanges(void)
-{
-       return true;
-}
-
-
-
-//
-// ABOUT Dialog WndProc
-//
-BOOL CALLBACK AboutProc(HWND hDlg, UINT msgID, WPARAM wParam, LPARAM lParam)
-{
-       switch (msgID)
-       {
-       case WM_INITDIALOG:
-
-               MiscCenterWnd(hDlg, hMainWnd);
-               break;
-
-       case WM_COMMAND:
-
-               if (wParam == IDOK || wParam == IDCANCEL)
-                       EndDialog(hDlg, TRUE);
-
-               break;
-
-       default:
-               return FALSE;
-       }
-
-       return TRUE;
-}
-
-//
-// Character Window WndProc
-//
-WndProcCW      PROC  STDCALL, hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
-
-               mov    eax, uMsg                // pickup our message
-               .IF (eax == WM_PAINT)
-                 mov    eax, 0                 // Non-sense... (placeholder!)
-// Scan conversion etc. goes here...
-               .ELSEIF (eax == WM_LBUTTONDOWN)
-                 invoke SetCapture, hCharWnd
-               .ELSEIF (eax == WM_LBUTTONUP)
-                 invoke ReleaseCapture
-                 invoke SetFocus, hMainWnd     // Make sure the main wnd keeps focus!
-               .ELSEIF (eax == WM_NCLBUTTONDOWN)
-                 invoke DefWindowProc, hWnd, uMsg, wParam, lParam // Let it do its thing
-                 invoke SetFocus, hMainWnd     // Make sure the main wnd keeps focus!
-               .ELSE
-DefProc:         invoke DefWindowProc, hWnd, uMsg, wParam, lParam
-               .ENDIF
-               ret
-
-WndProcCW      ENDP
-
-//
-// Character Window WndProc
-//
-LRESULT CALLBACK WndProcCW(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam)
-{
-       switch (msgID)
-       {
-       default:
-               return DefWindowProc(hWnd, msgID, wParam, lParam);
-       }
-
-       return 0;
-}
-
-
-// Function prototypes
-
-int32 FindSelectedTool(void);
-
-//
-// Tool Palette WndProc
-//
-LRESULT CALLBACK WndProcTP(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam)
-{
-       PAINTSTRUCT ps;
-       HDC hdc;
-       POINT pt;
-       static uint32 prevTool = -1;
-
-       switch (msgID)
-       {
-       case WM_PAINT:
-       {
-               hdc = BeginPaint(hWnd, &ps);
-               HDC newDC = CreateCompatibleDC(NULL);
-               SelectObject(newDC, hBMToolPal1);
-               BitBlt(hdc, 0, 0, sizeTPBM.x, sizeTPBM.y, newDC, 0, 0, SRCCOPY);
-               DeleteDC(newDC);
-
-// This is crappy. Find some way to tighten this up!
-               int32 tool = FindSelectedTool();
-
-               if (tool != -1)
-               {
-                       newDC = CreateCompatibleDC(NULL);
-                       SelectObject(newDC, hBMToolPal1);
-                   //need ul corner of bitmap, ul corner of dest, width/height
-                       pt.x = sizeStamp.x * (tool & 0x03), pt.y = sizeStamp.y * (tool >> 2);
-                       BitBlt(hdc, pt.x, pt.y, sizeStamp.x, sizeStamp.y, newDC, pt.x, pt.y, NOTSRCCOPY);
-                       DeleteDC(newDC);
-               }
-
-               EndPaint(hWnd, &ps);
-               break;
-       }
-       case WM_MOUSEMOVE:
-       {
-               int32 tool = FindSelectedTool();
-
-               if (tool != prevTool)
-               {
-                       prevTool = tool;
-                       InvalidateRect(hWnd, NULL, FALSE);
-               }
-
-               break;
-       }
-       case WM_RBUTTONUP:
-       {
-               int32 tool = FindSelectedTool(), oldTool = currentTool;
-
-               if (tool != -1)
-                       currentTool = tool;
-
-               if (currentTool != TOOLSelect && currentTool != TOOLDelPt && currentTool != TOOLAddPt
-                       && currentTool != TOOLPolySelect)
-                       ptHighlight = -1;
-
-               if (currentTool != oldTool)
-                       InvalidateRect(hMainWnd, NULL, TRUE);
-
-               if (currentTool == TOOLAddPoly)
-#ifdef DEBUGFOO
-{
-#endif
-                       polyFirstPoint = true;
-#ifdef DEBUGFOO
-wsprintf(strBuf, "--> Selected poly tool, polyFirstPoint is %s\n", polyFirstPoint ? "true" : "false");
-WriteLogMsg(strBuf);
-}
-#endif
-
-               ReleaseCapture();
-               ShowWindow(hToolPalWnd, SW_HIDE);
-               SetFocus(hMainWnd);                                             // Make sure the main wnd keeps focus!
-
-               break;
-       }
-       default:
-               return DefWindowProc(hWnd, msgID, wParam, lParam);
-       }
-
-       return 0;
-}
-
-//
-// Find which tool we're pointing at
-// Use: xcoord = mouse.x / (bmsize.x/4), ycoord = mouse.y / (bmsize.y/2)
-//
-int32 FindSelectedTool(void)
-{
-       POINT pt;
-               
-       GetCursorPos(&pt);
-       ScreenToClient(hToolPalWnd, &pt);
-
-       uint32 x = (uint32)pt.x / sizeStamp.x, y = (uint32)pt.y / sizeStamp.y, tool = -1;
-
-       if (x < 4 && y < 2)
-//     {
-               tool = (y * 4) + x;
-
-//             if (tool == 7)
-//                     tool = -1;                                                      // 7 has no tool...
-//     }
-
-       return tool;
-}
-
-
-//
-// Misc center window
-//
-void MiscCenterWnd(HWND hChild, HWND hParent)
-{
-       RECT parent, child;
-
-       if (!GetWindowRect(hParent, &parent) || !GetWindowRect(hChild, &child))
-               return;
-
-       int32 x = parent.left + (((parent.right - parent.left) - (child.right - child.left)) / 2),
-               y = parent.top + (((parent.bottom - parent.top) - (child.bottom - child.top)) / 2);
-
-       if (x < 0)
-               x = 0;
-       else if (x > GetSystemMetrics(SM_CXFULLSCREEN) - (child.right - child.left))
-               x = GetSystemMetrics(SM_CXFULLSCREEN) - (child.right - child.left);
-
-       if (y < 0)
-               y = 0;
-       else if (y > GetSystemMetrics(SM_CYFULLSCREEN) - (child.bottom - child.top))
-               y = GetSystemMetrics(SM_CYFULLSCREEN) - (child.bottom - child.top);
-
-       SetWindowPos(hChild, NULL, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
-}
-
-//
-// Allow only one instance
-//
-bool OnlyOneInstance(void)
-{
-       HWND window = FindWindow(className, NULL);
-
-       if (window == NULL)
-               return true;
-
-       ShowWindow(window, SW_SHOWNORMAL);
-       SetWindowPos(window, NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
-
-       return false;
-}
-
-//
-// Load/Allocate all resources
-//
-bool LoadResources(void)
-{
-       hCur[0] = LoadCursor(hInst, MAKEINTRESOURCE(IDC_CURSOR1));
-       hCur[1] = LoadCursor(hInst, MAKEINTRESOURCE(IDC_CURSOR2));
-       hCur[2] = LoadCursor(hInst, MAKEINTRESOURCE(IDC_CURSOR3));
-       hCur[3] = LoadCursor(hInst, MAKEINTRESOURCE(IDC_CURSOR4));
-       hCur[4] = LoadCursor(hInst, MAKEINTRESOURCE(IDC_CURSOR5));
-       hCur[5] = LoadCursor(hInst, MAKEINTRESOURCE(IDC_CURSOR6));
-       hCur[6] = LoadCursor(hInst, MAKEINTRESOURCE(IDC_CURSOR7));
-       hCur[7] = LoadCursor(hInst, MAKEINTRESOURCE(IDC_CURSOR8));
-
-       BITMAP bm;
-
-       hBMToolPal1 = LoadBitmap(hInst, MAKEINTRESOURCE(IDB_TOOLPAL1));
-       GetObject(hBMToolPal1, sizeof(bm), &bm);
-
-       // Set up sizes
-
-       sizeTPBM.x = bm.bmWidth, sizeTPBM.y = bm.bmHeight;
-       sizeStamp.x = bm.bmWidth / 4, sizeStamp.y = bm.bmHeight / 2;
-
-       hBluePen1 = CreatePen(PS_DOT, 1, 0x00FF0000);
-       hRedPen1 = CreatePen(PS_SOLID, 1, 0x000000FF);
-       hGreenPen1 = CreatePen(PS_SOLID, 1, 0x0000AF00);
-       hBlackPen1 = CreatePen(PS_SOLID, 1, 0x00000000);
-
-       LOGBRUSH lb = { BS_NULL, 0, 0 };
-
-       hNullBrush = CreateBrushIndirect(&lb);
-
-       return true;
-}
-
-//
-// Deallocate all resources
-//
-void DeallocateResources(void)
-{
-       DeleteObject(hBMToolPal1);
-       DeleteObject(hBluePen1);
-       DeleteObject(hRedPen1);
-       DeleteObject(hGreenPen1);
-       DeleteObject(hBlackPen1);
-       DeleteObject(hNullBrush);
-}
-
-//
-// Save all application specific data, so we can pick up where we last left off...
-//
-void SaveAppState(void)
-{
-       SetINIInt("Main", "flags", wpM.flags);
-       SetINIInt("Main", "showCmd", wpM.showCmd);
-       SetINIInt("Main", "x1", wpM.rcNormalPosition.left);
-       SetINIInt("Main", "y1", wpM.rcNormalPosition.top);
-       SetINIInt("Main", "x2", wpM.rcNormalPosition.right);
-       SetINIInt("Main", "y2", wpM.rcNormalPosition.bottom);
-
-       SetINIInt("Main", "vpx", ptVPM.x);
-       SetINIInt("Main", "vpy", ptVPM.y);
-
-       SetINIInt("Char", "flags", wpC.flags);
-       SetINIInt("Char", "showCmd", wpC.showCmd);
-       SetINIInt("Char", "x1", wpC.rcNormalPosition.left);
-       SetINIInt("Char", "y1", wpC.rcNormalPosition.top);
-       SetINIInt("Char", "x2", wpC.rcNormalPosition.right);
-       SetINIInt("Char", "y2", wpC.rcNormalPosition.bottom);
-
-       // Need to write out currently opened font, character looking at, other misc. crap
-//     SetINIString("Main", "currentFile", pDoc->GetPathName());
-//     SetINIInt("Main", "currentChar", pDoc->character_num);
-}
-
-//
-// Restore all application specific data previously saved
-//
-bool RestoreAppState(void)
-{
-       InitINIFile();
-
-       WINDOWPLACEMENT wp;
-       wp.length = sizeof(WINDOWPLACEMENT);
-       GetWindowPlacement(hMainWnd, &wp);
-
-       wp.flags = GetINIInt("Main", "flags", wp.flags);
-       wp.showCmd = GetINIInt("Main", "showCmd", wp.showCmd);
-       wp.rcNormalPosition.left = GetINIInt("Main", "x1", wp.rcNormalPosition.left);
-       wp.rcNormalPosition.top = GetINIInt("Main", "y1", wp.rcNormalPosition.top);
-       wp.rcNormalPosition.right = GetINIInt("Main", "x2", wp.rcNormalPosition.right);
-       wp.rcNormalPosition.bottom = GetINIInt("Main", "y2", wp.rcNormalPosition.bottom);
-
-       SetWindowPlacement(hMainWnd, &wp);
-
-       HDC hdc;
-       POINT pt;
-       hdc = GetDC(hMainWnd);
-       GetViewportOrgEx(hdc, &pt);
-
-       pt.x = GetINIInt("Main", "vpx", pt.x);
-       pt.y = GetINIInt("Main", "vpy", pt.y);
-
-       SetViewportOrgEx(hdc, pt.x, pt.y, NULL);
-       ReleaseDC(hMainWnd, hdc);
-
-       GetWindowPlacement(hCharWnd, &wp);
-
-       wp.flags = GetINIInt("Char", "flags", wp.flags);
-       wp.showCmd = GetINIInt("Char", "showCmd", wp.showCmd);
-       wp.rcNormalPosition.left = GetINIInt("Char", "x1", wp.rcNormalPosition.left);
-       wp.rcNormalPosition.top = GetINIInt("Char", "y1", wp.rcNormalPosition.top);
-       wp.rcNormalPosition.right = GetINIInt("Char", "x2", wp.rcNormalPosition.right);
-       wp.rcNormalPosition.bottom = GetINIInt("Char", "y2", wp.rcNormalPosition.bottom);
-
-       SetWindowPlacement(hCharWnd, &wp);
-
-       if (wp.showCmd == SW_HIDE)
-               SendMessage(hToolBar, TB_SETSTATE, ID_TBCHARWIN, MAKELONG(TBSTATE_ENABLED, 0));
-
-//  CString lastFile = theApplicationObject.GetProfileString(version, "currentFile", "");
-//  int lastChar = theApplicationObject.GetProfileInt(version, "currentChar", 0);
-//  if (lastFile.GetLength())
-//  {
-//    // Attempt to restore the last session by open the last file used, etc...
-//    if (!pDoc->m_myFont.Load(lastFile))
-//    {
-//      // Err, make sure you can support any allegations you make below, buddy!
-//      AfxMessageBox("The last file opened with TTF Edit\n\rseems to have been moved or deleted.");
-//    }
-//    else
-//    {
-//      pDoc->m_myFont.SetGlyph(lastChar);  // Set TTF object to last used char
-//      pDoc->character_num = lastChar;
-//      pDoc->SetPathName(lastFile);
-//
-//      BYTE name[512];
-//      pDoc->m_myFont.GetCharName(lastChar, name);
-//      m_wndOwned.SetWindowText((char *)name);
-//    }
-//  }
-
-       return true;
-}
-
-//
-// Initialization
-//
-bool Initialization(void)
-{
-       WNDCLASSEX wcex;
-
-       if (!LoadResources())
-               return false;
-
-       RtlFillMemory(&wcex, sizeof(WNDCLASSEX), 0);
-       wcex.cbSize = sizeof(WNDCLASSEX);
-       wcex.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
-       wcex.lpfnWndProc = WndProc;
-       wcex.hInstance = hInst;
-       wcex.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_ICON));
-       wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
-       wcex.lpszMenuName = MAKEINTRESOURCE(IDM_MENU);
-       wcex.lpszClassName = className;
-       wcex.hIconSm = (HICON)LoadImage(hInst, MAKEINTRESOURCE(IDI_ICON), IMAGE_ICON, 16, 16, NULL);
-
-       if (!RegisterClassEx(&wcex))
-               return false;
-
-       hMainWnd = CreateWindowEx(NULL, className, className, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
-               0, 0, 0x1A0, 0x180, NULL, NULL, hInst, NULL);
-
-       if (!hMainWnd)
-               return false;
-
-       ShowWindow(hMainWnd, nCmdShow);
-       UpdateWindow(hMainWnd);
-
-       // Character window creation
-
-       wcex.lpfnWndProc = WndProcCW;
-       wcex.lpszMenuName = NULL;
-       wcex.lpszClassName = CNCharWin;
-       wcex.hCursor = LoadCursor(NULL, IDC_ARROW);     // Owned windows have "regular" cursors
-
-       if (!RegisterClassEx(&wcex))
-               return false;
-
-       hCharWnd = CreateWindowEx(WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW, CNCharWin,
-               curCharName, WS_POPUP | WS_CAPTION | WS_VISIBLE | WS_THICKFRAME,
-               100, 100, 120, 120, hMainWnd, NULL, hInst, NULL);
-
-       if (!hCharWnd)
-               return false;
-
-       ShowWindow(hCharWnd, SW_SHOWNORMAL);
-       UpdateWindow(hCharWnd);
-       SetFocus(hMainWnd);                                                     // Make sure main wnd has focus!
-
-       // Tool palette window creation
-
-       wcex.lpfnWndProc = WndProcTP;
-       wcex.lpszClassName = CNToolPal;
-
-       if (!RegisterClassEx(&wcex))
-               return false;
-
-       hToolPalWnd = CreateWindowEx(WS_EX_WINDOWEDGE, CNToolPal, NULL, WS_POPUP,
-               0, 0, sizeTPBM.x, sizeTPBM.y, hMainWnd, NULL, hInst, NULL);
-
-       if (!hToolPalWnd)
-               return false;
-
-// Note: A better way to handle this would be to have a sub that registers ALL
-//       classes beforehand and passes a TRUE/FALSE back depending on whether or not
-//       all the classes were able to be registered or not, THEN create the windows
-//       and controls...
-
-       RestoreAppState();                                                      // Restore app related stuff
-
-       return true;
-}
-
-#endif