From 9bf789d643e1885fee526a1d4d1e2648f02bbd86 Mon Sep 17 00:00:00 2001 From: Shamus Hammons Date: Tue, 26 Jan 2021 21:24:05 -0600 Subject: [PATCH] Added automagically resizing grid. :-D --- src/applicationwindow.cpp | 118 ++++++++++++++--------------- src/applicationwindow.h | 1 + src/drawingview.cpp | 155 ++++++++++++++++++++++++++++++++++---- src/drawingview.h | 9 ++- src/painter.cpp | 18 +++++ src/painter.h | 2 + 6 files changed, 226 insertions(+), 77 deletions(-) diff --git a/src/applicationwindow.cpp b/src/applicationwindow.cpp index 9064595..773146f 100644 --- a/src/applicationwindow.cpp +++ b/src/applicationwindow.cpp @@ -87,7 +87,7 @@ ApplicationWindow::ApplicationWindow(): dock3->setObjectName("Object"); // Create status bar - zoomIndicator = new QLabel("Grid: 12.0\" BU: Inch"); + zoomIndicator = new QLabel("Zoom: 100% Grid: 12.0\" BU: Inch"); statusBar()->addPermanentWidget(zoomIndicator); statusBar()->showMessage(tr("Ready")); @@ -101,6 +101,7 @@ ApplicationWindow::ApplicationWindow(): connect(this, SIGNAL(ReloadLayers()), lw, SLOT(Reload())); connect(drawing, SIGNAL(ObjectHovered(Object *)), ow, SLOT(ShowInfo(Object *))); + connect(drawing, SIGNAL(NeedZoomUpdate()), this, SLOT(UpdateZoom())); } @@ -385,78 +386,68 @@ void ApplicationWindow::AddSplineTool(void) void ApplicationWindow::ZoomInTool(void) { - double zoomFactor = 2.0; -/* -We need to find the center of the screen, then figure out where the new corner -will be in the zoomed in window. - -So we know in Qt coords, the center is found via: -size.width() / 2 --> xCenter -size.height() / 2 --> yCenter - -transform x/yCenter to Cartesian coordinates. So far, so good. - -when zooming in, new origin will be (xCenter - origin.x) / 2, (yCenter - origin.y) / 2 -(after subtracting from center, that is...) -*/ + double zoomFactor = 1.20; QSize size = drawing->size(); - Vector center(size.width() / 2.0, size.height() / 2.0); -//printf("Zoom in... Center=%.2f,%.2f; ", center.x, center.y); - center = Painter::QtToCartesianCoords(center); -//printf("(%.2f,%.2f); origin=%.2f,%.2f; ", center.x, center.y, Painter::origin.x, Painter::origin.y); - Vector newOrigin = center - ((center - Global::origin) / zoomFactor); -//printf("newOrigin=%.2f,%.2f;\n", newOrigin.x, newOrigin.y); - Global::origin = newOrigin; - -//printf("Zoom in... level going from %02f to ", Painter::zoom); - // This just zooms leaving origin intact... should zoom in at the current - // center! [DONE] + Vector center = Painter::QtToCartesianCoords(Vector(size.width() / 2.0, size.height() / 2.0)); + + Global::origin = center - ((center - Global::origin) / zoomFactor); Global::zoom *= zoomFactor; - Global::gridSpacing = drawing->gridPixels / Global::zoom; - drawing->UpdateGridBackground(); - drawing->update(); - zoomIndicator->setText(QString("Grid: %1\", BU: Inch").arg(Global::gridSpacing)); - baseUnitInput->setText(QString("%1").arg(Global::gridSpacing)); + UpdateZoom(); } void ApplicationWindow::ZoomOutTool(void) { -/* -Ok, real example. -center = (436, 311) -origin = (223, 160.5) -newOrigin should be (-10, -10) -Why isn't it? - -center - origin = (213, 150.5) -origin - center = (-213, -150.5) -x 2 = (-426, -301) -+ center = (-10, -10) - -*/ - double zoomFactor = 2.0; + double zoomFactor = 1.20; QSize size = drawing->size(); - Vector center(size.width() / 2.0, size.height() / 2.0); -//printf("Zoom out... Center=%.2f,%.2f; ", center.x, center.y); - center = Painter::QtToCartesianCoords(center); -//printf("(%.2f,%.2f); origin=%.2f,%.2f; ", center.x, center.y, Painter::origin.x, Painter::origin.y); -// Vector newOrigin = (center - Painter::origin) * zoomFactor; -// Vector newOrigin = center - (Painter::origin * zoomFactor); - Vector newOrigin = center + ((Global::origin - center) * zoomFactor); -//printf("newOrigin=%.2f,%.2f;\n", newOrigin.x, newOrigin.y); - Global::origin = newOrigin; -//printf("Zoom out...\n"); - // This just zooms leaving origin intact... should zoom out at the current - // center! [DONE] + Vector center = Painter::QtToCartesianCoords(Vector(size.width() / 2.0, size.height() / 2.0)); + + Global::origin = center + ((Global::origin - center) * zoomFactor); Global::zoom /= zoomFactor; - Global::gridSpacing = drawing->gridPixels / Global::zoom; - drawing->UpdateGridBackground(); + + UpdateZoom(); +} + + +void ApplicationWindow::UpdateZoom(void) +{ + // And now, a bunch of heuristics to select the right grid size--autogrid! + // :-P + if (Global::zoom < 0.25) + Global::gridSpacing = 48.0; + else if (Global::zoom >= 0.25 && Global::zoom < 0.50) + Global::gridSpacing = 36.0; + else if (Global::zoom >= 0.50 && Global::zoom < 1.00) + Global::gridSpacing = 24.0; + else if (Global::zoom >= 1.00 && Global::zoom < 2.00) + Global::gridSpacing = 12.0; + else if (Global::zoom >= 2.00 && Global::zoom < 4.00) + Global::gridSpacing = 6.0; + else if (Global::zoom >= 4.00 && Global::zoom < 8.00) + Global::gridSpacing = 3.0; + else if (Global::zoom >= 8.00 && Global::zoom < 16.00) + Global::gridSpacing = 1.0; + else if (Global::zoom >= 16.00 && Global::zoom < 32.00) + Global::gridSpacing = 0.5; + else if (Global::zoom >= 32.00 && Global::zoom < 64.00) + Global::gridSpacing = 0.25; + else if (Global::zoom >= 64.00 && Global::zoom < 128.00) + Global::gridSpacing = 0.125; + else if (Global::zoom >= 128.00 && Global::zoom < 256.00) + Global::gridSpacing = 0.0625; + else if (Global::zoom >= 256.00 && Global::zoom < 512.00) + Global::gridSpacing = 0.03125; + else + Global::gridSpacing = 0.015625; + + drawing->SetGridSize((double)(Global::gridSpacing * Global::zoom)); drawing->update(); - zoomIndicator->setText(QString("Grid: %1\", BU: Inch").arg(Global::gridSpacing)); - baseUnitInput->setText(QString("%1").arg(Global::gridSpacing)); + zoomIndicator->setText(QString("Zoom: %1% Grid: %2\" BU: Inch").arg(Global::zoom * 100.0).arg(Global::gridSpacing)); + + // This is the problem... Changing this causes the state to update itself again, screwing up the origin... !!! FIX !!! (commented out for now) +// baseUnitInput->setText(QString("%1").arg(Global::gridSpacing)); } @@ -464,7 +455,8 @@ void ApplicationWindow::ClearUIToolStatesExcept(QAction * exception) { QAction * actionList[] = { addArcAct, addLineAct, addCircleAct, addDimensionAct, addPolygonAct, - addSplineAct, deleteAct, rotateAct, mirrorAct, trimAct, triangulateAct, 0 + addSplineAct, deleteAct, rotateAct, mirrorAct, trimAct, + triangulateAct, 0 }; for(int i=0; actionList[i]!=0; i++) @@ -675,7 +667,7 @@ void ApplicationWindow::HandleDisconnection(void) void ApplicationWindow::HandleGridSizeInPixels(int size) { - drawing->SetGridSize(size); + drawing->SetGridSize((uint32_t)size); drawing->update(); } diff --git a/src/applicationwindow.h b/src/applicationwindow.h index 0bd3581..f35ba1c 100644 --- a/src/applicationwindow.h +++ b/src/applicationwindow.h @@ -54,6 +54,7 @@ class ApplicationWindow: public QMainWindow void EditCopy(void); void EditPaste(void); void SelectAllObjects(void); + void UpdateZoom(void); signals: void ReloadLayers(void); diff --git a/src/drawingview.cpp b/src/drawingview.cpp index dc68532..ca352c2 100644 --- a/src/drawingview.cpp +++ b/src/drawingview.cpp @@ -120,16 +120,84 @@ need a thickness parameter similar to the "size" param for dimensions. (And now we do! :-) */ - SetGridSize(12); // This is in pixels + gridPixels = 12; //tmp + SetGridSize(12.0); // This is in pixels +} + + +void DrawingView::DrawBackground(Painter * painter) +{ + Point ul = Painter::QtToCartesianCoords(Vector(0, 0)); + Point br = Painter::QtToCartesianCoords(Vector(Global::screenSize.x, Global::screenSize.y)); + + painter->SetBrush(0xF0F0F0); + painter->SetPen(0xF0F0F0, 1, 1); + painter->DrawRect(QRectF(QPointF(ul.x, ul.y), QPointF(br.x, br.y))); + + double spacing = Global::gridSpacing; + + if (spacing < 1.0) + spacing = 1.0; + + double leftx = floor(ul.x / spacing) * spacing; + double bottomy = floor(br.y / spacing) * spacing; + + double w = (br.x - ul.x) + Global::gridSpacing + 1.0; + double h = (ul.y - br.y) + Global::gridSpacing + 1.0; + + Vector start(leftx, bottomy), size(w, h); + + if (Global::gridSpacing <= 0.015625) + DrawSubGrid(painter, 0xFFD2D2, 0.015625, start, size); + + if (Global::gridSpacing <= 0.03125) + DrawSubGrid(painter, 0xFFD2D2, 0.03125, start, size); + + if (Global::gridSpacing <= 0.0625) + DrawSubGrid(painter, 0xB8ECFF, 0.0625, start, size); + + if (Global::gridSpacing <= 0.125) + DrawSubGrid(painter, 0xB8ECFF, 0.125, start, size); + + if (Global::gridSpacing <= 0.25) + DrawSubGrid(painter, 0xDBDBFF, 0.25, start, size); + + if (Global::gridSpacing <= 0.5) + DrawSubGrid(painter, 0xDBDBFF, 0.5, start, size); + + painter->SetPen(QPen(QColor(0xD2, 0xD2, 0xFF), 2.0, Qt::SolidLine)); + + for(double i=0; i<=w; i+=spacing) + painter->DrawVLine(leftx + i); + + for(double i=0; i<=h; i+=spacing) + painter->DrawHLine(bottomy + i); +} + + +void DrawingView::DrawSubGrid(Painter * painter, uint32_t color, double step, Vector start, Vector size) +{ + painter->SetPen(color, 1, 1); + + for(double i=-step; i<=size.x; i+=step*2.0) + painter->DrawVLine(start.x + i); + + for(double i=-step; i<=size.y; i+=step*2.0) + painter->DrawHLine(start.y + i); } void DrawingView::SetGridSize(uint32_t size) { +#if 0 // Sanity check if (size == gridPixels) return; + // tmp... + if (size <= 1) + return; + // Recreate the background bitmap gridPixels = size; QPainter pmp(&gridBackground); @@ -148,11 +216,13 @@ void DrawingView::SetGridSize(uint32_t size) // This shouldn't be done here, because it fucks up the scrollwheel zooming... // Global::zoom = gridPixels / Global::gridSpacing; UpdateGridBackground(); +#endif } void DrawingView::UpdateGridBackground(void) { +#if 0 // Transform the origin to Qt coordinates Vector pixmapOrigin = Painter::CartesianToQtCoords(Vector()); int x = (int)pixmapOrigin.x; @@ -227,6 +297,70 @@ zero; so we do another modulus operation on the result to achieve this. pal.setBrush(backgroundRole(), QBrush(pm)); setAutoFillBackground(true); setPalette(pal); +#endif +} + + +void DrawingView::SetGridSize(double size) +{ +#if 0 + // Sanity check + if (size == gridPixelsF) + return; + + // tmp... + if (size <= 1) + return; + + // Recreate the background bitmap + gridPixelsF = size; + QPainter pmp(&gridBackground); + pmp.fillRect(0, 0, BACKGROUND_MAX_SIZE, BACKGROUND_MAX_SIZE, QColor(240, 240, 240)); + pmp.setPen(QPen(QColor(210, 210, 255), 2.0, Qt::SolidLine)); + + for(double i=0; i<(BACKGROUND_MAX_SIZE-1); i+=gridPixelsF) + { + pmp.drawLine(i, 0, i, (double)(BACKGROUND_MAX_SIZE - 1)); + pmp.drawLine(0, i, (double)(BACKGROUND_MAX_SIZE - 1), i); + } + + pmp.end(); + + // Set up new BG brush & zoom level (pixels per base unit) +// This shouldn't be done here, because it fucks up the scrollwheel zooming... +// Global::zoom = gridPixels / Global::gridSpacing; + UpdateGridBackgroundF(); +#endif +} + + +void DrawingView::UpdateGridBackgroundF(void) +{ +#if 0 + // Transform the origin to Qt coordinates + Vector pixmapOrigin = Painter::CartesianToQtCoords(Vector()); + int x = 0;// (int)pixmapOrigin.x; + int y = 0;// (int)pixmapOrigin.y; + // Use mod arithmetic to grab the correct swatch of background + +/* if (x < 0) + x = -x % gridPixels; + else + x = (gridPixels - (x % gridPixels)) % gridPixels; + + if (y < 0) + y = -y % gridPixels; + else + y = (gridPixels - (y % gridPixels)) % gridPixels;*/ + + // Here we grab a section of the bigger pixmap, so that the background + // *looks* like it's scrolling... + QPixmap pm = gridBackground.copy(x, y, gridPixelsF, gridPixelsF); + QPalette pal = palette(); + pal.setBrush(backgroundRole(), QBrush(pm)); + setAutoFillBackground(true); + setPalette(pal); +#endif } @@ -381,6 +515,8 @@ void DrawingView::paintEvent(QPaintEvent * /*event*/) Global::viewportHeight = size().height(); + DrawBackground(&painter); + // Draw coordinate axes painter.SetPen(QPen(Qt::blue, 1.0, Qt::DotLine)); painter.DrawLine(0, -16384, 0, 16384); @@ -1996,35 +2132,28 @@ void DrawingView::mouseReleaseEvent(QMouseEvent * event) void DrawingView::wheelEvent(QWheelEvent * event) { - double zoomFactor = 1.25; + double zoomFactor = 1.20; scrollWheelSeen = true; - if (event->delta() < 0) + if (event->angleDelta().y() < 0) { - if (Global::zoom > 20.0) + if (Global::zoom > 400.0) return; Global::zoom *= zoomFactor; -// Point np = Painter::QtToCartesianCoords(oldScrollPoint); -// Global::origin += (oldPoint - np); } else { - if (Global::zoom < 0.25) + if (Global::zoom < 0.125) return; Global::zoom /= zoomFactor; -// Point np = Painter::QtToCartesianCoords(oldScrollPoint); -// Global::origin += (oldPoint - np); } Point np = Painter::QtToCartesianCoords(oldScrollPoint); Global::origin += (oldPoint - np); -// Global::gridSpacing = gridPixels / Painter::zoom; - SetGridSize(Global::gridSpacing * Global::zoom); - update(); -// zoomIndicator->setText(QString("Grid: %1\", BU: Inch").arg(Global::gridSpacing)); + emit(NeedZoomUpdate()); } diff --git a/src/drawingview.h b/src/drawingview.h index d252ffc..441b7a8 100644 --- a/src/drawingview.h +++ b/src/drawingview.h @@ -18,8 +18,11 @@ class DrawingView: public QWidget DrawingView(QWidget * parent = NULL); public: + void DrawBackground(Painter *); void SetGridSize(uint32_t); + void SetGridSize(double); void UpdateGridBackground(void); + void UpdateGridBackgroundF(void); Point SnapPointToGrid(Point); Point SnapPointToAngle(Point); void RenderObjects(Painter *, VPVector &, int, bool ignoreLayer = false); @@ -57,6 +60,7 @@ class DrawingView: public QWidget signals: void ObjectHovered(Object *); void ObjectSelected(Object *); + void NeedZoomUpdate(void); protected: void focusOutEvent(QFocusEvent * event); @@ -70,6 +74,7 @@ class DrawingView: public QWidget void keyReleaseEvent(QKeyEvent * event); private: + void DrawSubGrid(Painter *, uint32_t, double, Vector, Vector); QPoint GetAdjustedMousePosition(QMouseEvent * event); QPoint GetAdjustedClientPosition(int x, int y); @@ -87,7 +92,9 @@ class DrawingView: public QWidget public: Container document; uint32_t gridPixels; // Grid size in pixels - private: + double gridPixelsF; // Grid size in pixels (float) +// private: + public: bool collided; bool scrollDrag; Vector oldPoint; diff --git a/src/painter.cpp b/src/painter.cpp index 6cb74ea..e20f3ee 100644 --- a/src/painter.cpp +++ b/src/painter.cpp @@ -372,6 +372,24 @@ void Painter::DrawLine(Vector v1, Vector v2) } +void Painter::DrawHLine(double ypos) +{ + double width = Global::screenSize.x / Global::zoom; + Vector v1 = CartesianToQtCoords(Vector(Global::origin.x, ypos)); + Vector v2 = CartesianToQtCoords(Vector(Global::origin.x + width, ypos)); + painter->drawLine(QPointF(v1.x, v1.y), QPointF(v2.x, v2.y)); +} + + +void Painter::DrawVLine(double xpos) +{ + double height = Global::screenSize.y / Global::zoom; + Vector v1 = CartesianToQtCoords(Vector(xpos, Global::origin.y)); + Vector v2 = CartesianToQtCoords(Vector(xpos, Global::origin.y + height)); + painter->drawLine(QPointF(v1.x, v1.y), QPointF(v2.x, v2.y)); +} + + void Painter::DrawPoint(int x, int y) { if (!painter) diff --git a/src/painter.h b/src/painter.h index 98c81f3..403476e 100644 --- a/src/painter.h +++ b/src/painter.h @@ -33,6 +33,8 @@ class Painter void DrawArrowToLineHandle(Vector, double); void DrawLine(int, int, int, int); void DrawLine(Vector, Vector); + void DrawHLine(double); + void DrawVLine(double); void DrawPoint(int, int); void DrawRoundedRect(QRectF, double, double); void DrawPaddedRect(QRectF); -- 2.37.2