X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fapplicationwindow.cpp;h=f2dc923b5c2313b852ee56109efe0cc9434d8e33;hb=6c1279871f6bb86bc59e2561b6a7f74ab081f71e;hp=8220a0eeca1138d6523c884ae70b26c828f92980;hpb=428876081ee41d40e32f5b4f2bfcfdb7a835e6e1;p=architektonas diff --git a/src/applicationwindow.cpp b/src/applicationwindow.cpp index 8220a0e..f2dc923 100644 --- a/src/applicationwindow.cpp +++ b/src/applicationwindow.cpp @@ -30,17 +30,28 @@ #include "about.h" #include "blockwidget.h" +#include "dimension.h" #include "drawingview.h" #include "drawarcaction.h" #include "drawcircleaction.h" #include "drawdimensionaction.h" #include "drawlineaction.h" +#include "drawsplineaction.h" #include "fileio.h" #include "generaltab.h" +#include "geometry.h" #include "layerwidget.h" +#include "line.h" #include "mirroraction.h" #include "painter.h" +#include "rotateaction.h" #include "settingsdialog.h" +#include "triangulateaction.h" +#include "trimaction.h" + + +// Class variables +DrawingView * ApplicationWindow::drawing; ApplicationWindow::ApplicationWindow(): @@ -78,13 +89,15 @@ ApplicationWindow::ApplicationWindow(): dock2->setObjectName("Blocks"); // Create status bar - zoomIndicator = new QLabel("Grid: 12.0\" Zoom: 12.5%"); + zoomIndicator = new QLabel("Grid: 12.0\" BU: Inch"); statusBar()->addPermanentWidget(zoomIndicator); statusBar()->showMessage(tr("Ready")); ReadSettings(); setUnifiedTitleAndToolBarOnMac(true); Object::SetFont(new QFont("Verdana", 15, QFont::Bold)); + + connect(lw, SIGNAL(LayerSelected(int)), drawing, SLOT(SetCurrentLayer(int))); } @@ -111,7 +124,12 @@ void ApplicationWindow::FileOpen(void) { QString filename = QFileDialog::getOpenFileName(this, tr("Open Drawing"), "", tr("Architektonas files (*.drawing)")); - FILE * file = fopen(filename.toAscii().data(), "r"); + + // User cancelled open + if (filename.isEmpty()) + return; + + FILE * file = fopen(filename.toUtf8().data(), "r"); if (file == 0) { @@ -150,7 +168,7 @@ void ApplicationWindow::FileSave(void) documentName = QFileDialog::getSaveFileName(this, tr("Save Drawing"), "", tr("Architektonas drawings (*.drawing)")); - FILE * file = fopen(documentName.toAscii().data(), "w"); + FILE * file = fopen(documentName.toUtf8().data(), "w"); if (file == 0) { @@ -171,7 +189,8 @@ void ApplicationWindow::FileSave(void) msg.setIcon(QMessageBox::Critical); msg.exec(); // In this case, we should unlink the created file, since it's not right... - unlink(documentName.toAscii().data()); +// unlink(documentName.toUtf8().data()); + QFile::remove(documentName); return; } @@ -251,6 +270,20 @@ void ApplicationWindow::MirrorTool(void) } +void ApplicationWindow::TrimTool(void) +{ + ClearUIToolStatesExcept(trimAct); + SetInternalToolStates(); +} + + +void ApplicationWindow::TriangulateTool(void) +{ + ClearUIToolStatesExcept(triangulateAct); + SetInternalToolStates(); +} + + void ApplicationWindow::AddLineTool(void) { ClearUIToolStatesExcept(addLineAct); @@ -279,6 +312,13 @@ void ApplicationWindow::AddPolygonTool(void) } +void ApplicationWindow::AddSplineTool(void) +{ + ClearUIToolStatesExcept(addSplineAct); + SetInternalToolStates(); +} + + void ApplicationWindow::ZoomInTool(void) { double zoomFactor = 2.0; @@ -305,18 +345,14 @@ when zooming in, new origin will be (xCenter - origin.x) / 2, (yCenter - origin. Painter::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] - // This should actually be calculated by drawing->gridPixels / grid size. + // This just zooms leaving origin intact... should zoom in at the current + // center! [DONE] Painter::zoom *= zoomFactor; -// drawing->gridSpacing = drawing->gridPixels / Painter::zoom; Object::gridSpacing = drawing->gridPixels / Painter::zoom; -// zoomIndicator->setText(QString("Grid: %2\" Zoom: %1%").arg(Painter::zoom * 100.0 * SCREEN_ZOOM).arg(drawing->gridSpacing)); -// zoomIndicator->setText(QString("Grid: %1\", BU: Inch").arg(drawing->gridSpacing)); - zoomIndicator->setText(QString("Grid: %1\", BU: Inch").arg(Object::gridSpacing)); drawing->UpdateGridBackground(); drawing->update(); -// baseUnitInput->setText(QString("%1").arg(drawing->gridSpacing)); + zoomIndicator->setText(QString("Grid: %1\", BU: Inch").arg(Object::gridSpacing)); baseUnitInput->setText(QString("%1").arg(Object::gridSpacing)); } @@ -348,17 +384,14 @@ x 2 = (-426, -301) //printf("newOrigin=%.2f,%.2f;\n", newOrigin.x, newOrigin.y); Painter::origin = newOrigin; //printf("Zoom out...\n"); - // This just zooms leaving origin intact... should zoom out at the current center! [DONE] + // This just zooms leaving origin intact... should zoom out at the current + // center! [DONE] Painter::zoom /= zoomFactor; -// drawing->gridSpacing = drawing->gridPixels / Painter::zoom; Object::gridSpacing = drawing->gridPixels / Painter::zoom; -// zoomIndicator->setText(QString("Grid: %2\" Zoom: %1%").arg(Painter::zoom * 100.0 * SCREEN_ZOOM).arg(drawing->gridSpacing)); -// zoomIndicator->setText(QString("Grid: %1\", BU: Inch").arg(drawing->gridSpacing)); - zoomIndicator->setText(QString("Grid: %1\", BU: Inch").arg(Object::gridSpacing)); drawing->UpdateGridBackground(); drawing->update(); -// baseUnitInput->setText(QString("%1").arg(drawing->gridSpacing)); + zoomIndicator->setText(QString("Grid: %1\", BU: Inch").arg(Object::gridSpacing)); baseUnitInput->setText(QString("%1").arg(Object::gridSpacing)); } @@ -380,6 +413,9 @@ void ApplicationWindow::ClearUIToolStatesExcept(QAction * exception) if (exception != addPolygonAct) addPolygonAct->setChecked(false); + if (exception != addSplineAct) + addSplineAct->setChecked(false); + if (exception != deleteAct) deleteAct->setChecked(false); @@ -388,6 +424,12 @@ void ApplicationWindow::ClearUIToolStatesExcept(QAction * exception) if (exception != mirrorAct) mirrorAct->setChecked(false); + + if (exception != trimAct) + trimAct->setChecked(false); + + if (exception != triangulateAct) + triangulateAct->setChecked(false); } @@ -395,7 +437,6 @@ void ApplicationWindow::SetInternalToolStates(void) { Object::SetDeleteActive(deleteAct->isChecked()); Object::SetDimensionActive(addDimensionAct->isChecked()); - drawing->SetRotateToolActive(rotateAct->isChecked()); // We can be sure that if we've come here, then either an active tool is // being deactivated, or a new tool is being created. In either case, the @@ -404,22 +445,23 @@ void ApplicationWindow::SetInternalToolStates(void) { delete drawing->toolAction; drawing->toolAction = NULL; + Object::ignoreClicks = false; } -#if 0 - drawing->SetAddLineToolActive(addLineAct->isChecked()); - drawing->SetAddCircleToolActive(addCircleAct->isChecked()); - drawing->SetAddArcToolActive(addArcAct->isChecked()); - drawing->SetAddDimensionToolActive(addDimensionAct->isChecked()); -#else drawing->SetToolActive(addLineAct->isChecked() ? new DrawLineAction() : NULL); drawing->SetToolActive(addCircleAct->isChecked() ? new DrawCircleAction() : NULL); drawing->SetToolActive(addArcAct->isChecked() ? new DrawArcAction() : NULL); drawing->SetToolActive(addDimensionAct->isChecked() ? new DrawDimensionAction() : NULL); + drawing->SetToolActive(addSplineAct->isChecked() ? new DrawSplineAction() : NULL); drawing->SetToolActive(mirrorAct->isChecked() ? new MirrorAction() : NULL); -#endif + drawing->SetToolActive(rotateAct->isChecked() ? new RotateAction() : NULL); + drawing->SetToolActive(trimAct->isChecked() ? new TrimAction() : NULL); + drawing->SetToolActive(triangulateAct->isChecked() ? new TriangulateAction() : NULL); + + if (drawing->toolAction) + Object::ignoreClicks = true; - update(); + drawing->update(); } @@ -502,6 +544,78 @@ else } +void ApplicationWindow::HandleConnection(void) +{ +//double tt = Geometry::ParameterOfLineAndPoint(Vector(0, 0), Vector(10, 0), Vector(8, 2)); +//printf("Parameter of point @ (8,2) of line (0,0), (10,0): %lf\n", tt); + int itemsSelected = drawing->document.ItemsSelected(); + + // If nothing selected, do nothing + if (itemsSelected == 0) + { + statusBar()->showMessage(tr("No objects selected to connect.")); + return; + } + + // If one thing selected, do nothing + if (itemsSelected == 1) + { + statusBar()->showMessage(tr("Nothing to connect object to.")); + return; + } + + // This is O(n^2 / 2) :-P + for(int i=0; idocument.SelectedItem(i); + + for(int j=i+1; jdocument.SelectedItem(j); + double t, u, v, w; + +// if ((obj1->type != OTLine) || (obj2->type != OTLine)) +// continue; + + if ((obj1->type == OTLine) && (obj2->type == OTLine)) + { +//printf("Testing objects for intersection (%X, %X)...\n", obj1, obj2); + int intersects = Geometry::Intersects((Line *)obj1, (Line *)obj2, &t, &u); +//printf(" (%s) --> t=%lf, u=%lf\n", (intersects ? "true" : "FALSE"), t, u); + + if (intersects) + { + //printf("Connecting objects (%X, %X)...\n", obj1, obj2); + obj1->Connect(obj2, u); + obj2->Connect(obj1, t); + } + } + else if (((obj1->type == OTLine) && (obj2->type == OTDimension)) + || ((obj2->type == OTLine) && (obj1->type == OTDimension))) + { +printf("Testing Line<->Dimension intersection...\n"); + Line * line = (Line *)(obj1->type == OTLine ? obj1 : obj2); + Dimension * dim = (Dimension *)(obj1->type == OTDimension ? obj1 : obj2); + + int intersects = Geometry::Intersects(line, dim, &t, &u); +printf(" -> intersects = %i, t=%lf, u=%lf\n", intersects, t, u); + + if (intersects) + { + obj1->Connect(obj2, u); + obj2->Connect(obj1, t); + } + } + } + } +} + + +void ApplicationWindow::HandleDisconnection(void) +{ +} + + void ApplicationWindow::HandleGridSizeInPixels(int size) { drawing->SetGridSize(size); @@ -581,6 +695,9 @@ void ApplicationWindow::CreateActions(void) addPolygonAct = CreateAction(tr("Add &Polygon"), tr("Add Polygon"), tr("Add polygons to the drawing."), QIcon(":/res/add-polygon-tool.png"), QKeySequence("A,P"), true); connect(addPolygonAct, SIGNAL(triggered()), this, SLOT(AddPolygonTool())); + addSplineAct = CreateAction(tr("Add &Spline"), tr("Add Spline"), tr("Add a NURB spline to the drawing."), QIcon(":/res/add-spline-tool.png"), QKeySequence("A,S"), true); + connect(addSplineAct, SIGNAL(triggered()), this, SLOT(AddSplineTool())); + aboutAct = CreateAction(tr("About &Architektonas"), tr("About Architektonas"), tr("Gives information about this program."), QIcon(":/res/generic-tool.png"), QKeySequence()); connect(aboutAct, SIGNAL(triggered()), this, SLOT(HelpAbout())); @@ -614,12 +731,20 @@ void ApplicationWindow::CreateActions(void) connect(groupAct, SIGNAL(triggered()), this, SLOT(HandleGrouping())); connectAct = CreateAction(tr("&Connect"), tr("Connect"), tr("Connect objects at point."), QIcon(":/res/connect-tool.png"), QKeySequence("c,c")); + connect(connectAct, SIGNAL(triggered()), this, SLOT(HandleConnection())); disconnectAct = CreateAction(tr("&Disconnect"), tr("Disconnect"), tr("Disconnect objects joined at point."), QIcon(":/res/disconnect-tool.png"), QKeySequence("d,d")); + connect(disconnectAct, SIGNAL(triggered()), this, SLOT(HandleDisconnection())); mirrorAct = CreateAction(tr("&Mirror"), tr("Mirror"), tr("Mirror selected objects around a line."), QIcon(":/res/mirror-tool.png"), QKeySequence("m,i"), true); connect(mirrorAct, SIGNAL(triggered()), this, SLOT(MirrorTool())); + trimAct = CreateAction(tr("&Trim"), tr("Trim"), tr("Trim extraneous lines from selected objects."), QIcon(":/res/trim-tool.png"), QKeySequence("t,r"), true); + connect(trimAct, SIGNAL(triggered()), this, SLOT(TrimTool())); + + triangulateAct = CreateAction(tr("&Triangulate"), tr("Triangulate"), tr("Make triangles from selected lines, preserving their lengths."), QIcon(":/res/triangulate-tool.png"), QKeySequence("t,g"), true); + connect(triangulateAct, SIGNAL(triggered()), this, SLOT(TriangulateTool())); + //Hm. I think we'll have to have separate logic to do the "Radio Group Toolbar" thing... // Yup, in order to turn them off, we'd have to have an "OFF" toolbar button. Ick. @@ -690,6 +815,8 @@ void ApplicationWindow::CreateMenus(void) menu->addAction(fixLengthAct); menu->addAction(rotateAct); menu->addAction(mirrorAct); + menu->addAction(trimAct); + menu->addAction(triangulateAct); menu->addAction(connectAct); menu->addAction(disconnectAct); menu->addSeparator(); @@ -699,6 +826,7 @@ void ApplicationWindow::CreateMenus(void) menu->addAction(addCircleAct); menu->addAction(addArcAct); menu->addAction(addPolygonAct); + menu->addAction(addSplineAct); menu->addAction(addDimensionAct); menu->addSeparator(); menu->addAction(settingsAct); @@ -738,6 +866,8 @@ void ApplicationWindow::CreateToolbars(void) toolbar->addAction(fixLengthAct); toolbar->addAction(rotateAct); toolbar->addAction(mirrorAct); + toolbar->addAction(trimAct); + toolbar->addAction(triangulateAct); toolbar->addAction(deleteAct); toolbar->addAction(connectAct); toolbar->addAction(disconnectAct); @@ -746,6 +876,7 @@ void ApplicationWindow::CreateToolbars(void) toolbar->addAction(addCircleAct); toolbar->addAction(addArcAct); toolbar->addAction(addPolygonAct); + toolbar->addAction(addSplineAct); toolbar->addAction(addDimensionAct); spinbox->setRange(4, 256);