From b9a08d76d62e7c37e726b047994082e1569eb8f5 Mon Sep 17 00:00:00 2001 From: Ahmed Essam Date: Sun, 30 Aug 2020 23:24:51 +0200 Subject: [PATCH] cleanups --- .../AlgebraicCurveParser.cpp | 7 +- .../ArrangementDemoPropertiesDialog.cpp | 2 +- .../ArrangementDemoTab.cpp | 26 +- .../ArrangementDemoTab.h | 34 ++- .../ArrangementDemoWindow.cpp | 206 +++++----------- .../ArrangementDemoWindow.h | 39 ++- .../ArrangementTypesUtils.h | 94 ++++++++ .../ForwardDeclarations.h | 1 - .../Arrangement_on_surface_2/NewTabDialog.cpp | 37 +-- .../OverlayDialog.cpp | 226 +++--------------- 10 files changed, 280 insertions(+), 392 deletions(-) create mode 100644 Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementTypesUtils.h diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/AlgebraicCurveParser.cpp b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/AlgebraicCurveParser.cpp index 5d6066d9dd9..019da1553e1 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/AlgebraicCurveParser.cpp +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/AlgebraicCurveParser.cpp @@ -17,7 +17,6 @@ // // Author(s): Saurabh Singh -#include #include #include @@ -149,8 +148,14 @@ AlgebraicCurveParser::operator()(const std::string& expression) // makes compilation slower // template class // AlgebraicCurveParser; +// AlgebraicCurveParser; +#ifdef CGAL_USE_CORE +#include +#include + template struct AlgebraicCurveParser< CGAL::Arr_algebraic_segment_traits_2::Polynomial_2>; template struct AlgebraicCurveParser< typename CGAL::Algebraic_kernel_d_1::Polynomial_1>; +#endif diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoPropertiesDialog.cpp b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoPropertiesDialog.cpp index 04fdbbb541a..f8e6e0ef735 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoPropertiesDialog.cpp +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoPropertiesDialog.cpp @@ -128,7 +128,7 @@ void ArrangementDemoPropertiesDialog::updateUi( ) { return; } - ArrangementDemoTabBase* currentTab = this->parent->getCurrentTab().first; + ArrangementDemoTabBase* currentTab = this->parent->getCurrentTab(); if ( currentTab == NULL ) { return; diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoTab.cpp b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoTab.cpp index aa39c5e19fa..16af8df2000 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoTab.cpp +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoTab.cpp @@ -10,6 +10,7 @@ // Author(s) : Alex Tsui #include "ArrangementTypes.h" +#include "ArrangementTypesUtils.h" #include "ArrangementDemoTab.h" #include "ArrangementGraphicsItem.h" #include "ArrangementDemoGraphicsView.h" @@ -25,6 +26,8 @@ #include "PointSnapper.h" #include "ConstructBoundingBox.h" +#include + #include static constexpr double MAX_WIDTH = @@ -35,14 +38,7 @@ ArrangementDemoTabBase::ArrangementDemoTabBase( QWidget* parent ) : GraphicsSceneMixin( new QGraphicsScene() ), graphicsView( new ArrangementDemoGraphicsView( this ) ), layout( new QGridLayout( this ) ), - curveInputCallback( nullptr ), - deleteCurveCallback( nullptr ), - pointLocationCallback( nullptr ), - verticalRayShootCallback( nullptr ), - mergeEdgeCallback( nullptr ), - splitEdgeCallback( nullptr ), - envelopeCallback( nullptr ), - fillFaceCallback( nullptr ), + navigation( std::make_unique() ), activeCallback( nullptr ), arrangementGraphicsItem( nullptr ), gridGraphicsItem( nullptr ) @@ -65,6 +61,8 @@ void ArrangementDemoTabBase::setupUi( ) double xymin = -MAX_WIDTH / 2; double wh = MAX_WIDTH; scene->setSceneRect(xymin, xymin, wh, wh); + + this->getView()->installEventFilter(this->navigation.get()); } QGraphicsView* ArrangementDemoTabBase::getView() const @@ -155,6 +153,12 @@ FillFaceCallbackBase* ArrangementDemoTabBase::getFillFaceCallback( ) const return this->fillFaceCallback.get(); } +CGAL::Qt::GraphicsViewNavigation* +ArrangementDemoTabBase::getGraphicsViewNavigation() const +{ + return this->navigation.get(); +} + void ArrangementDemoTabBase::activateCurveInputCallback(CGAL::Qt::CurveType type) { this->unhookCallbacks(); @@ -262,6 +266,12 @@ ArrangementDemoTab::ArrangementDemoTab( this->setupCallbacks(); } +template +demo_types::TraitsType ArrangementDemoTab::traitsType() const +{ + return demo_types::enumFromArrType(); +} + template ArrangementDemoTab::~ArrangementDemoTab() { diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoTab.h b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoTab.h index 8b335836586..c99da99d88f 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoTab.h +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoTab.h @@ -36,10 +36,16 @@ class ArrangementGraphicsItemBase; class Callback; class ArrangementGraphicsItemBase; class GraphicsViewCurveInputBase; +class GraphicsViewNavigation; enum class CurveType; } // namespace Qt } // namespace CGAL +namespace demo_types +{ +enum class TraitsType; +} + class ArrangementDemoTabBase : public QWidget, public GraphicsSceneMixin { Q_OBJECT @@ -51,9 +57,11 @@ public: ArrangementDemoTabBase( QWidget* parent ); virtual ~ArrangementDemoTabBase( ); - QGraphicsView* getView() const; virtual CGAL::Object getArrangement() const = 0; virtual void adjustViewport() = 0; + virtual demo_types::TraitsType traitsType() const = 0; + + QGraphicsView* getView() const; void showGrid(bool); bool isGridVisible(); void setSnapToGrid(bool); @@ -61,16 +69,18 @@ public: bool isSnapToGridEnabled(); bool isSnapToArrangementEnabled(); - CGAL::Qt::ArrangementGraphicsItemBase* getArrangementGraphicsItem() const; - GridGraphicsItem* getGridGraphicsItem() const; - CGAL::Qt::GraphicsViewCurveInputBase* getCurveInputCallback() const; - CGAL::Qt::Callback* getDeleteCurveCallback() const; - CGAL::Qt::Callback* getPointLocationCallback() const; - VerticalRayShootCallbackBase* getVerticalRayShootCallback() const; - CGAL::Qt::Callback* getMergeEdgeCallback() const; - SplitEdgeCallbackBase* getSplitEdgeCallback() const; - EnvelopeCallbackBase* getEnvelopeCallback() const; - FillFaceCallbackBase* getFillFaceCallback() const; + auto getArrangementGraphicsItem() const + -> CGAL::Qt::ArrangementGraphicsItemBase*; + auto getGridGraphicsItem() const -> GridGraphicsItem*; + auto getCurveInputCallback() const -> CGAL::Qt::GraphicsViewCurveInputBase*; + auto getDeleteCurveCallback() const -> CGAL::Qt::Callback*; + auto getPointLocationCallback() const -> CGAL::Qt::Callback*; + auto getVerticalRayShootCallback() const -> VerticalRayShootCallbackBase*; + auto getMergeEdgeCallback() const -> CGAL::Qt::Callback*; + auto getSplitEdgeCallback() const -> SplitEdgeCallbackBase*; + auto getEnvelopeCallback() const -> EnvelopeCallbackBase*; + auto getFillFaceCallback() const -> FillFaceCallbackBase*; + auto getGraphicsViewNavigation() const -> CGAL::Qt::GraphicsViewNavigation*; void activateCurveInputCallback(CGAL::Qt::CurveType); void activateDeleteCurveCallback(); @@ -106,6 +116,7 @@ protected: std::unique_ptr envelopeCallback; std::unique_ptr fillFaceCallback; std::unique_ptr snapper; + std::unique_ptr navigation; CGAL::Qt::Callback* activeCallback; CGAL::Qt::ArrangementGraphicsItemBase* arrangementGraphicsItem; @@ -125,6 +136,7 @@ public: ~ArrangementDemoTab(); void adjustViewport() override; CGAL::Object getArrangement() const override; + demo_types::TraitsType traitsType() const override; private: void initArrangement(); diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoWindow.cpp b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoWindow.cpp index 40384f755ab..30d8dc1be23 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoWindow.cpp +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoWindow.cpp @@ -27,6 +27,7 @@ #include "FillFaceCallback.h" #include "GridGraphicsItem.h" #include "ArrangementTypes.h" +#include "ArrangementTypesUtils.h" #include "Conic_reader.h" #include @@ -44,6 +45,7 @@ #include "ui_ArrangementDemoWindow.h" +using TraitsType = demo_types::TraitsType; ArrangementDemoWindow::ArrangementDemoWindow(QWidget* parent) : CGAL::Qt::DemosMainWindow(parent), ui(new Ui::ArrangementDemoWindow), @@ -59,7 +61,7 @@ ArrangementDemoWindow::ArrangementDemoWindow(QWidget* parent) : this->envelopeGroup, SIGNAL(triggered(QAction*)), this, SLOT(updateEnvelope(QAction*))); - this->makeTab(SEGMENT_TRAITS); + this->makeTab(TraitsType::SEGMENT_TRAITS); // Call inherited functions this->setupStatusBar(); @@ -102,97 +104,22 @@ void ArrangementDemoWindow::setupUi() this->inputTypeGroup->addAction(this->ui->actionBezier); } -template -struct TypeHolder -{ - using type = T; -}; - -template -static constexpr ArrangementDemoWindow::TraitsType traitFromType() -{ - using TraitsType = ArrangementDemoWindow::TraitsType; - using namespace std; - using namespace demo_types; - - if (is_same::value) return TraitsType::SEGMENT_TRAITS; - else if (is_same::value) return TraitsType::POLYLINE_TRAITS; - else if (is_same::value) return TraitsType::LINEAR_TRAITS; -#ifdef CGAL_USE_CORE - else if (is_same::value) return TraitsType::CONIC_TRAITS; - else if (is_same::value) return TraitsType::ALGEBRAIC_TRAITS; - else if (is_same::value) return TraitsType::BEZIER_TRAITS; - else if (is_same::value) return TraitsType::RATIONAL_FUNCTION_TRAITS; -#endif - else return TraitsType::NONE; -} - -template -static void -visitArrangementType(ArrangementDemoWindow::TraitsType tt, Lambda lambda) -{ - using TraitsType = ArrangementDemoWindow::TraitsType; - using namespace demo_types; - - switch (tt) - { - default: - case TraitsType::SEGMENT_TRAITS: - lambda(TypeHolder{}); - break; - case TraitsType::POLYLINE_TRAITS: - lambda(TypeHolder{}); - break; - case TraitsType::LINEAR_TRAITS: - lambda(TypeHolder{}); - break; -#ifdef CGAL_USE_CORE - case TraitsType::CONIC_TRAITS: - lambda(TypeHolder{}); - break; - case TraitsType::ALGEBRAIC_TRAITS: - lambda(TypeHolder{}); - break; - case TraitsType::BEZIER_TRAITS: - lambda(TypeHolder{}); - break; - case TraitsType::RATIONAL_FUNCTION_TRAITS: - lambda(TypeHolder{}); - break; -#endif - } -} - -template -static void forEachArrangementType(Lambda lambda) -{ - using namespace demo_types; - - lambda(TypeHolder{}); - lambda(TypeHolder{}); - lambda(TypeHolder{}); -#ifdef CGAL_USE_CORE - lambda(TypeHolder{}); - lambda(TypeHolder{}); - lambda(TypeHolder{}); - lambda(TypeHolder{}); -#endif -} - QString ArrangementDemoWindow::makeTabLabel(TraitsType tt) { static const char* typeNames[] = { "Segment", "Polyline", "Linear", "Conic", "Algebraic", "Bezier", "Rational Functions" }; - return QString("%1 - %2").arg(this->tabLabelCounter++).arg(typeNames[tt]); + return QString("%1 - %2") + .arg(this->tabLabelCounter++) + .arg(typeNames[static_cast(tt)]); } ArrangementDemoTabBase* ArrangementDemoWindow::makeTab(TraitsType tt) { ArrangementDemoTabBase* demoTab; QString tabLabel = makeTabLabel(tt); - visitArrangementType(tt, [&](auto type_holder) { + demo_types::visitArrangementType(tt, [&](auto type_holder) { demoTab = new ArrangementDemoTab(this); }); @@ -203,13 +130,16 @@ ArrangementDemoTabBase* ArrangementDemoWindow::makeTab(TraitsType tt) void ArrangementDemoWindow::addTab( ArrangementDemoTabBase* demoTab, QString tabLabel, TraitsType tt) { - this->tabs.push_back({demoTab, tt}); + this->tabs.push_back(demoTab); this->ui->tabWidget->addTab(demoTab, tabLabel); this->ui->tabWidget->setCurrentWidget(demoTab); - // TODO: This causes memory leak because of the existence of multiple tabs - // fix it - this->addNavigation(demoTab->getView()); + + // avoid using addNavigation since it will cause memory leaks when there are + // multiple tabs (no way to delete the navigation item!) + QObject::connect( + demoTab->getGraphicsViewNavigation(), SIGNAL(mouseCoordinates(QString)), + xycoord, SLOT(setText(QString))); } void ArrangementDemoWindow::resetActionGroups( @@ -227,12 +157,14 @@ void ArrangementDemoWindow::resetActionGroups( this->ui->actionLowerEnvelope->setChecked(tab->isLowerEnvelopeShown()); this->ui->actionUpperEnvelope->setChecked(tab->isUpperEnvelopeShown()); - if (tt != SEGMENT_TRAITS && tt != POLYLINE_TRAITS && tt != LINEAR_TRAITS) + if ( + tt != TraitsType::SEGMENT_TRAITS && tt != TraitsType::POLYLINE_TRAITS && + tt != TraitsType::LINEAR_TRAITS) this->ui->actionArrangementSnapMode->setVisible(false); else this->ui->actionArrangementSnapMode->setVisible(true); - if (tt == RATIONAL_FUNCTION_TRAITS) + if (tt == TraitsType::RATIONAL_FUNCTION_TRAITS) this->ui->actionGridSnapMode->setVisible(false); // default action group is scrolling @@ -250,7 +182,7 @@ void ArrangementDemoWindow::resetCallbackState(ArrangementDemoTabBase* tab) void ArrangementDemoWindow::updateEnvelope(QAction* newMode) { - auto currentTab = this->getCurrentTab().first; + auto currentTab = this->getCurrentTab(); if (!currentTab) return; bool show = newMode->isChecked(); @@ -286,47 +218,46 @@ void ArrangementDemoWindow::hideInsertMethods() this->ui->actionBezier->setChecked(false); } -void ArrangementDemoWindow::showInsertMethods() +void ArrangementDemoWindow::showInsertMethods(demo_types::TraitsType tabType) { - auto tabType = this->getCurrentTab().second; switch(tabType) { - case NONE: + case TraitsType::NONE: return; - case SEGMENT_TRAITS: + case TraitsType::SEGMENT_TRAITS: this->ui->actionSegment->setVisible(true); this->ui->actionSegment->activate(QAction::Trigger); break; - case POLYLINE_TRAITS: + case TraitsType::POLYLINE_TRAITS: this->ui->actionPolyline->setVisible(true); this->ui->actionPolyline->activate(QAction::Trigger); break; - case LINEAR_TRAITS: + case TraitsType::LINEAR_TRAITS: this->ui->actionSegment->setVisible(true); this->ui->actionSegment->activate(QAction::Trigger); this->ui->actionRay->setVisible(true); this->ui->actionLine->setVisible(true); break; #ifdef CGAL_USE_CORE - case CONIC_TRAITS: + case TraitsType::CONIC_TRAITS: this->ui->actionSegment->setVisible(true); this->ui->actionCircle->setVisible(true); this->ui->actionEllipse->setVisible(true); this->ui->actionConicThreePoint->setVisible(true); this->ui->actionConicFivePoint->setVisible(true); break; - case ALGEBRAIC_TRAITS: + case TraitsType::ALGEBRAIC_TRAITS: this->ui->actionCircle->setVisible(true); this->ui->actionCircle->activate(QAction::Trigger); this->ui->actionEllipse->setVisible(true); this->ui->actionLine->setVisible(true); this->ui->actionAddAlgebraicCurve->setVisible(true); break; - case BEZIER_TRAITS: + case TraitsType::BEZIER_TRAITS: this->ui->actionBezier->setVisible(true); this->ui->actionBezier->activate(QAction::Trigger); break; - case RATIONAL_FUNCTION_TRAITS: + case TraitsType::RATIONAL_FUNCTION_TRAITS: this->ui->actionAddRationalCurve->setVisible(true); break; #endif @@ -337,7 +268,7 @@ void ArrangementDemoWindow::showInsertMethods() void ArrangementDemoWindow::updateInputType(QAction* a) { - auto tab = this->getCurrentTab().first; + auto tab = this->getCurrentTab(); if (!tab) return; using namespace CGAL::Qt; @@ -390,7 +321,7 @@ void ArrangementDemoWindow::on_actionAddAlgebraicCurve_triggered() return; } - auto currentTab = this->getCurrentTab().first; + auto currentTab = this->getCurrentTab(); Alg_seg_arr* arr; if (!CGAL::assign(arr, currentTab->getArrangement())) CGAL_error(); @@ -437,7 +368,7 @@ void ArrangementDemoWindow::on_actionAddRationalCurve_triggered() return; } - auto currentTab = this->getCurrentTab().first; + auto currentTab = this->getCurrentTab(); Rational_arr* arr; if (!CGAL::assign(arr, currentTab->getArrangement())) CGAL_error(); @@ -465,18 +396,16 @@ void ArrangementDemoWindow::on_actionNewTab_triggered() if (newTabDialog.exec() == QDialog::Accepted) { int id = newTabDialog.checkedId(); - // this assumes that options have the same order as TraitsType this->makeTab(static_cast(id)); } } void ArrangementDemoWindow::on_tabWidget_currentChanged(int) { - auto tabPair = this->getCurrentTab(); - auto currentTab = tabPair.first; - auto tt = tabPair.second; + auto currentTab = this->getCurrentTab(); if (currentTab) { + auto tt = currentTab->traitsType(); this->resetCallbackState(currentTab); this->resetActionGroups(currentTab, tt); this->updateFillColorSwatch(currentTab); @@ -487,11 +416,11 @@ void ArrangementDemoWindow::on_actionInsert_toggled(bool checked) { this->hideInsertMethods(); - auto currentTab = this->getCurrentTab().first; + auto currentTab = this->getCurrentTab(); if (currentTab) { if (checked) - this->showInsertMethods(); + this->showInsertMethods(currentTab->traitsType()); else this->resetCallbackState(currentTab); } @@ -499,7 +428,7 @@ void ArrangementDemoWindow::on_actionInsert_toggled(bool checked) void ArrangementDemoWindow::on_actionDrag_toggled(bool checked) { - auto currentTab = this->getCurrentTab().first; + auto currentTab = this->getCurrentTab(); if (currentTab) { // TODO: Move this to DemoTab @@ -513,21 +442,21 @@ void ArrangementDemoWindow::on_actionDrag_toggled(bool checked) void ArrangementDemoWindow::on_actionDelete_toggled(bool checked) { - auto currentTab = this->getCurrentTab().first; + auto currentTab = this->getCurrentTab(); if (currentTab && !checked) this->resetCallbackState(currentTab); } void ArrangementDemoWindow::on_actionDelete_triggered() { - auto currentTab = this->getCurrentTab().first; + auto currentTab = this->getCurrentTab(); if (currentTab) currentTab->activateDeleteCurveCallback(); } void ArrangementDemoWindow::on_actionPointLocation_toggled(bool checked) { - auto currentTab = this->getCurrentTab().first; + auto currentTab = this->getCurrentTab(); if (currentTab) { if (!checked) @@ -539,7 +468,7 @@ void ArrangementDemoWindow::on_actionPointLocation_toggled(bool checked) void ArrangementDemoWindow::on_actionRayShootingUp_toggled(bool checked) { - auto currentTab = this->getCurrentTab().first; + auto currentTab = this->getCurrentTab(); if (currentTab) { if (!checked) @@ -551,7 +480,7 @@ void ArrangementDemoWindow::on_actionRayShootingUp_toggled(bool checked) void ArrangementDemoWindow::on_actionRayShootingDown_toggled(bool checked) { - auto currentTab = this->getCurrentTab().first; + auto currentTab = this->getCurrentTab(); if (currentTab) { if (!checked) @@ -563,7 +492,7 @@ void ArrangementDemoWindow::on_actionRayShootingDown_toggled(bool checked) void ArrangementDemoWindow::on_actionMerge_toggled(bool checked) { - auto currentTab = this->getCurrentTab().first; + auto currentTab = this->getCurrentTab(); if (currentTab) { if (!checked) @@ -575,7 +504,7 @@ void ArrangementDemoWindow::on_actionMerge_toggled(bool checked) void ArrangementDemoWindow::on_actionSplit_toggled(bool checked) { - auto currentTab = this->getCurrentTab().first; + auto currentTab = this->getCurrentTab(); if (currentTab) { if (!checked) @@ -587,7 +516,7 @@ void ArrangementDemoWindow::on_actionSplit_toggled(bool checked) void ArrangementDemoWindow::on_actionFill_toggled(bool checked) { - auto currentTab = this->getCurrentTab().first; + auto currentTab = this->getCurrentTab(); if (currentTab) { if (!checked) @@ -600,7 +529,7 @@ void ArrangementDemoWindow::on_actionFill_toggled(bool checked) void ArrangementDemoWindow::on_actionShowGrid_toggled(bool checked) { - auto currentTab = this->getCurrentTab().first; + auto currentTab = this->getCurrentTab(); if (currentTab) { currentTab->showGrid(checked); @@ -611,7 +540,7 @@ void ArrangementDemoWindow::on_actionShowGrid_toggled(bool checked) void ArrangementDemoWindow::on_actionGridSnapMode_toggled(bool checked) { - auto currentTab = this->getCurrentTab().first; + auto currentTab = this->getCurrentTab(); if (currentTab) { currentTab->setSnapToGrid(checked); @@ -622,7 +551,7 @@ void ArrangementDemoWindow::on_actionGridSnapMode_toggled(bool checked) void ArrangementDemoWindow::on_actionArrangementSnapMode_toggled(bool checked) { - auto currentTab = this->getCurrentTab().first; + auto currentTab = this->getCurrentTab(); if (currentTab) { currentTab->setSnapToArrangement(checked); @@ -631,7 +560,7 @@ void ArrangementDemoWindow::on_actionArrangementSnapMode_toggled(bool checked) void ArrangementDemoWindow::on_actionCloseTab_triggered() { - auto currentTab = this->getCurrentTab().first; + auto currentTab = this->getCurrentTab(); if (!currentTab) return; // delete the tab @@ -647,7 +576,7 @@ void ArrangementDemoWindow::on_actionCloseTab_triggered() void ArrangementDemoWindow::on_actionZoomIn_triggered() { - auto currentTab = this->getCurrentTab().first; + auto currentTab = this->getCurrentTab(); if (currentTab) { QGraphicsView* view = currentTab->getView(); @@ -657,7 +586,7 @@ void ArrangementDemoWindow::on_actionZoomIn_triggered() void ArrangementDemoWindow::on_actionZoomOut_triggered() { - auto currentTab = this->getCurrentTab().first; + auto currentTab = this->getCurrentTab(); if (currentTab) { QGraphicsView* view = currentTab->getView(); @@ -667,14 +596,14 @@ void ArrangementDemoWindow::on_actionZoomOut_triggered() void ArrangementDemoWindow::on_actionZoomReset_triggered() { - auto currentTab = this->getCurrentTab().first; + auto currentTab = this->getCurrentTab(); if (currentTab) currentTab->adjustViewport(); } void ArrangementDemoWindow::on_actionFillColor_triggered() { - auto currentTab = this->getCurrentTab().first; + auto currentTab = this->getCurrentTab(); if (!currentTab) return; FillFaceCallbackBase* fillFaceCallback = currentTab->getFillFaceCallback(); @@ -701,11 +630,10 @@ void ArrangementDemoWindow::updateFillColorSwatch(ArrangementDemoTabBase* tab) this->ui->actionFillColor->setIcon(fillColorIcon); } -auto ArrangementDemoWindow::getCurrentTab() - -> std::pair +ArrangementDemoTabBase* ArrangementDemoWindow::getCurrentTab() { int tabIndex = this->ui->tabWidget->currentIndex(); - if (tabIndex == -1) return {nullptr, NONE}; + if (tabIndex == -1) return nullptr; return this->tabs[tabIndex]; } @@ -721,7 +649,7 @@ std::vector ArrangementDemoWindow::getTabLabels() const std::vector ArrangementDemoWindow::getArrangements() const { std::vector res; - for (auto& tab : this->tabs) res.push_back(tab.first->getArrangement()); + for (auto& tab : this->tabs) res.push_back(tab->getArrangement()); return res; } @@ -733,9 +661,9 @@ void ArrangementDemoWindow::on_actionOverlay_triggered() std::vector arrs = overlayDialog.selectedArrangements(); if (arrs.size() == 2) { - forEachArrangementType([&](auto type_holder) { + demo_types::forEachArrangementType([&](auto type_holder) { using Arr = typename decltype(type_holder)::type; - auto tt = traitFromType(); + auto tt = demo_types::enumFromArrType(); Arr* arr; Arr* arr2; @@ -796,15 +724,13 @@ struct ArrWriter void ArrangementDemoWindow::on_actionSaveAs_triggered() { - auto tab_tt = this->getCurrentTab(); - auto currentTab = tab_tt.first; - auto tt = tab_tt.second; - + auto currentTab = this->getCurrentTab(); if (!currentTab) { QMessageBox::information(this, "Oops", "Create a new tab first"); return; } + auto tt = currentTab->traitsType(); QString filename = QFileDialog::getSaveFileName( this, tr("Save file"), "", "Arrangement (*.arr)"); @@ -816,7 +742,7 @@ void ArrangementDemoWindow::on_actionSaveAs_triggered() // write type info ofs << "# " << static_cast(tt) << std::endl; - visitArrangementType(tt, [&](auto type_holder) { + demo_types::visitArrangementType(tt, [&](auto type_holder) { using Arr = typename decltype(type_holder)::type; Arr* typed_arr; if (CGAL::assign(typed_arr, currentTab->getArrangement())) @@ -846,7 +772,7 @@ void ArrangementDemoWindow::on_actionOpen_triggered() struct ArrReader { template - auto operator()(TypeHolder) + auto operator()(demo_types::TypeHolder) { using Text_formatter = CGAL::Arr_text_formatter; using ArrFormatter = CGAL::Arr_with_history_text_formatter; @@ -858,7 +784,7 @@ struct ArrReader } #ifdef CGAL_USE_CORE - auto operator()(TypeHolder) + auto operator()(demo_types::TypeHolder) { using namespace demo_types; @@ -871,12 +797,12 @@ struct ArrReader return arr; } - auto operator()(TypeHolder) + auto operator()(demo_types::TypeHolder) { return std::make_unique(); } - auto operator()(TypeHolder) + auto operator()(demo_types::TypeHolder) { return std::make_unique(); } @@ -902,7 +828,7 @@ ArrangementDemoTabBase* ArrangementDemoWindow::openArrFile(QString filename) ArrangementDemoTabBase* createdTab = nullptr; - visitArrangementType(tt, [&](auto type_holder) { + demo_types::visitArrangementType(tt, [&](auto type_holder) { auto arr = ArrReader{ifs}(type_holder); createdTab = this->makeTab(std::move(arr), this->makeTabLabel(tt), tt); }); @@ -912,7 +838,7 @@ ArrangementDemoTabBase* ArrangementDemoWindow::openArrFile(QString filename) void ArrangementDemoWindow::on_actionPreferences_triggered() { - auto currentTab = this->getCurrentTab().first; + auto currentTab = this->getCurrentTab(); if (!currentTab) return; auto agi = currentTab->getArrangementGraphicsItem(); diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoWindow.h b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoWindow.h index 7bda191a597..065ac06a9b1 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoWindow.h +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementDemoWindow.h @@ -24,6 +24,15 @@ class ArrangementDemoWindow; namespace CGAL { class Object; +namespace Qt +{ + class GraphicsViewNavigation; +} +} + +namespace demo_types +{ +enum class TraitsType; } class ArrangementDemoTabBase; @@ -34,24 +43,12 @@ class ArrangementDemoWindow : public CGAL::Qt::DemosMainWindow Q_OBJECT public: - typedef enum TraitsType - { - SEGMENT_TRAITS, - POLYLINE_TRAITS, - LINEAR_TRAITS, - CONIC_TRAITS, - ALGEBRAIC_TRAITS, - BEZIER_TRAITS, - RATIONAL_FUNCTION_TRAITS, - NONE, - } TraitsType; - ArrangementDemoWindow(QWidget* parent = nullptr); ~ArrangementDemoWindow(); std::vector getArrangements() const; std::vector getTabLabels() const; - std::pair getCurrentTab(); + ArrangementDemoTabBase* getCurrentTab(); public Q_SLOTS: void updateEnvelope(QAction*); @@ -89,26 +86,26 @@ Q_SIGNALS: protected: void setupUi(); - ArrangementDemoTabBase* makeTab(TraitsType); - void addTab(ArrangementDemoTabBase*, QString, TraitsType); + ArrangementDemoTabBase* makeTab(demo_types::TraitsType); + void addTab(ArrangementDemoTabBase*, QString, demo_types::TraitsType); void resetCallbackState(ArrangementDemoTabBase*); - void resetActionGroups(ArrangementDemoTabBase*, TraitsType); + void resetActionGroups(ArrangementDemoTabBase*, demo_types::TraitsType); void hideInsertMethods(); - void showInsertMethods(); + void showInsertMethods(demo_types::TraitsType); void updateFillColorSwatch(ArrangementDemoTabBase*); - QString makeTabLabel(TraitsType); + QString makeTabLabel(demo_types::TraitsType); ArrangementDemoTabBase* openArrFile(QString filename); template ArrangementDemoTabBase* - makeTab(std::unique_ptr arr, QString, TraitsType); + makeTab(std::unique_ptr arr, QString, demo_types::TraitsType); template - void makeOverlayTab(ArrType* arr1, ArrType* arr2, TraitsType); + void makeOverlayTab(ArrType* arr1, ArrType* arr2, demo_types::TraitsType); private: Ui::ArrangementDemoWindow* ui; - std::vector> tabs; + std::vector tabs; QActionGroup* modeGroup; QActionGroup* envelopeGroup; QActionGroup* inputTypeGroup; diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementTypesUtils.h b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementTypesUtils.h new file mode 100644 index 00000000000..9610f80ccd9 --- /dev/null +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ArrangementTypesUtils.h @@ -0,0 +1,94 @@ +#ifndef ARRANGEMENT_DEMO_TYPE_UTILS +#define ARRANGEMENT_DEMO_TYPE_UTILS + +#include "ArrangementTypes.h" +#include + +namespace demo_types +{ + +enum class TraitsType : int +{ + SEGMENT_TRAITS, + POLYLINE_TRAITS, + LINEAR_TRAITS, +#ifdef CGAL_USE_CORE + CONIC_TRAITS, + ALGEBRAIC_TRAITS, + BEZIER_TRAITS, + RATIONAL_FUNCTION_TRAITS, +#endif + NONE, +}; + +template +struct TypeHolder +{ + using type = T; +}; + +template +static constexpr TraitsType enumFromArrType() +{ + using namespace std; + + if (is_same::value) return TraitsType::SEGMENT_TRAITS; + else if (is_same::value) return TraitsType::POLYLINE_TRAITS; + else if (is_same::value) return TraitsType::LINEAR_TRAITS; +#ifdef CGAL_USE_CORE + else if (is_same::value) return TraitsType::CONIC_TRAITS; + else if (is_same::value) return TraitsType::ALGEBRAIC_TRAITS; + else if (is_same::value) return TraitsType::BEZIER_TRAITS; + else if (is_same::value) return TraitsType::RATIONAL_FUNCTION_TRAITS; +#endif + else return TraitsType::NONE; +} + +template +static void visitArrangementType(TraitsType tt, Lambda lambda) +{ + switch (tt) + { + default: + case TraitsType::SEGMENT_TRAITS: + lambda(TypeHolder{}); + break; + case TraitsType::POLYLINE_TRAITS: + lambda(TypeHolder{}); + break; + case TraitsType::LINEAR_TRAITS: + lambda(TypeHolder{}); + break; +#ifdef CGAL_USE_CORE + case TraitsType::CONIC_TRAITS: + lambda(TypeHolder{}); + break; + case TraitsType::ALGEBRAIC_TRAITS: + lambda(TypeHolder{}); + break; + case TraitsType::BEZIER_TRAITS: + lambda(TypeHolder{}); + break; + case TraitsType::RATIONAL_FUNCTION_TRAITS: + lambda(TypeHolder{}); + break; +#endif + } +} + +template +static void forEachArrangementType(Lambda lambda) +{ + lambda(TypeHolder{}); + lambda(TypeHolder{}); + lambda(TypeHolder{}); +#ifdef CGAL_USE_CORE + lambda(TypeHolder{}); + lambda(TypeHolder{}); + lambda(TypeHolder{}); + lambda(TypeHolder{}); +#endif +} +} + +#endif diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ForwardDeclarations.h b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ForwardDeclarations.h index 9197114c8f9..dc2dc2f8cb1 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ForwardDeclarations.h +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/ForwardDeclarations.h @@ -43,7 +43,6 @@ struct Arr_identified_side_tag; template class Rational_traits; - } // namespace CGAL #endif diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/NewTabDialog.cpp b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/NewTabDialog.cpp index 9ad3c0f672c..a5a9128c968 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/NewTabDialog.cpp +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/NewTabDialog.cpp @@ -11,31 +11,38 @@ #include "NewTabDialog.h" #include "ArrangementDemoWindow.h" +#include "ArrangementTypesUtils.h" #include "ui_NewTabDialog.h" #include + NewTabDialog::NewTabDialog( QWidget* parent ) : QDialog( parent ), ui( new Ui::NewTabDialog ), buttonGroup( new QButtonGroup ) { - this->ui->setupUi( this ); + using TraitsType = demo_types::TraitsType; - this->buttonGroup->addButton( this->ui->segmentRadioButton, - ArrangementDemoWindow::SEGMENT_TRAITS ); - this->buttonGroup->addButton( this->ui->polylineRadioButton, - ArrangementDemoWindow::POLYLINE_TRAITS ); - this->buttonGroup->addButton( this->ui->linearRadioButton, - ArrangementDemoWindow::LINEAR_TRAITS ); + this->ui->setupUi(this); + + this->buttonGroup->addButton( + this->ui->segmentRadioButton, static_cast(TraitsType::SEGMENT_TRAITS)); + this->buttonGroup->addButton( + this->ui->polylineRadioButton, + static_cast(TraitsType::POLYLINE_TRAITS)); + this->buttonGroup->addButton( + this->ui->linearRadioButton, static_cast(TraitsType::LINEAR_TRAITS)); #ifdef CGAL_USE_CORE - this->buttonGroup->addButton( this->ui->conicRadioButton, - ArrangementDemoWindow::CONIC_TRAITS ); - this->buttonGroup->addButton( this->ui->algebraicRadioButton, - ArrangementDemoWindow::ALGEBRAIC_TRAITS ); - this->buttonGroup->addButton( this->ui->bezierRadioButton, - ArrangementDemoWindow::BEZIER_TRAITS ); - this->buttonGroup->addButton( this->ui->rationalFunctionRadioButton, - ArrangementDemoWindow::RATIONAL_FUNCTION_TRAITS ); + this->buttonGroup->addButton( + this->ui->conicRadioButton, static_cast(TraitsType::CONIC_TRAITS)); + this->buttonGroup->addButton( + this->ui->algebraicRadioButton, + static_cast(TraitsType::ALGEBRAIC_TRAITS)); + this->buttonGroup->addButton( + this->ui->bezierRadioButton, static_cast(TraitsType::BEZIER_TRAITS)); + this->buttonGroup->addButton( + this->ui->rationalFunctionRadioButton, + static_cast(TraitsType::RATIONAL_FUNCTION_TRAITS)); #else this->ui->conicRadioButton->hide(); this->ui->algebraicRadioButton->hide(); diff --git a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/OverlayDialog.cpp b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/OverlayDialog.cpp index 09f6cbffa5e..c7058f918f0 100644 --- a/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/OverlayDialog.cpp +++ b/Arrangement_on_surface_2/demo/Arrangement_on_surface_2/OverlayDialog.cpp @@ -9,7 +9,7 @@ #include "OverlayDialog.h" #include "ArrangementDemoWindow.h" -#include "ArrangementTypes.h" +#include "ArrangementTypesUtils.h" #include "QtMetaTypes.h" #include @@ -18,9 +18,6 @@ #include "ui_OverlayDialog.h" -// TODO: clean this up! -// TODO: Don't color the text, but set an icon for each arrangement type... -// TODO: Or maybe don't bother OverlayDialog::OverlayDialog( ArrangementDemoWindow* parent ) : QDialog( parent ), ui( new Ui::OverlayDialog ) @@ -46,54 +43,24 @@ OverlayDialog::OverlayDialog( ArrangementDemoWindow* parent ) : item->setData( ARRANGEMENT, QVariant::fromValue( arrangements[ i ] ) ); QIcon icon; - Seg_arr* seg; - Pol_arr* pol; - Lin_arr* lin; -#ifdef CGAL_USE_CORE - Conic_arr* conic; - Alg_seg_arr* alg; - Bezier_arr* bezier; - Rational_arr* rat_arr; -#endif + TraitsType traitsType = TraitsType::NONE; + forEachArrangementType([&](auto type_holder) { + using Arrangement = typename decltype(type_holder)::type; + Arrangement* arr; + if (CGAL::assign(arr, arrangements[i])) + traitsType = enumFromArrType(); + }); - if ( CGAL::assign( seg, arrangements[ i ] ) ) - { - icon.addFile(QString::fromUtf8(":/icons/green_icon.xpm"), QSize(), - QIcon::Normal, QIcon::Off); - } - else if ( CGAL::assign( pol, arrangements[ i ] ) ) - { - icon.addFile(QString::fromUtf8(":/icons/yellow_icon.xpm"), QSize(), - QIcon::Normal, QIcon::Off); - } - else if ( CGAL::assign( lin, arrangements[ i ] ) ) - { - icon.addFile(QString::fromUtf8(":/icons/blue_icon.xpm"), QSize(), - QIcon::Normal, QIcon::Off); - } + if (traitsType == TraitsType::NONE) + CGAL_error(); -#ifdef CGAL_USE_CORE - else if ( CGAL::assign( conic, arrangements[ i ] ) ) - { - icon.addFile(QString::fromUtf8(":/icons/red_icon.xpm"), QSize(), - QIcon::Normal, QIcon::Off); - } - else if ( CGAL::assign( alg, arrangements[ i ] ) ) - { - icon.addFile(QString::fromUtf8(":/icons/yellow_icon.xpm"), QSize(), - QIcon::Normal, QIcon::Off); - } - else if ( CGAL::assign( bezier, arrangements[ i ] ) ) - { - icon.addFile(QString::fromUtf8(":/icons/pink_icon.xpm"), QSize(), - QIcon::Normal, QIcon::Off); - } - else if ( CGAL::assign( rat_arr, arrangements[ i ] ) ) - { - icon.addFile(QString::fromUtf8(":/icons/yellow_icon.xpm"), QSize(), - QIcon::Normal, QIcon::Off); - } -#endif + static constexpr std::array icons = { + ":/cgal/icons/green_icon.xpm", ":/cgal/icons/yellow_icon.xpm", + ":/cgal/icons/blue_icon.xpm", ":/cgal/icons/red_icon.xpm", + ":/cgal/icons/pink_icon.xpm"}; + + icon.addFile( + QString::fromUtf8(icons[static_cast(traitsType) % icons.size()])); item->setIcon( icon ); } @@ -170,153 +137,24 @@ void OverlayDialog::restrictSelection( QListWidgetItem* item ) CGAL::Object o = item->data( ARRANGEMENT ).value< CGAL::Object >( ); - Seg_arr* seg; - Pol_arr* pol; - Lin_arr* lin; -#ifdef CGAL_USE_CORE - Conic_arr* conic; - Alg_seg_arr* alg; - Bezier_arr* bezier; - Rational_arr* rat_arr; -#endif + forEachArrangementType([&](auto type_holder) { + using Arrangement = typename decltype(type_holder)::type; + Arrangement* arr; + if (CGAL::assign(arr, o)) + { + for (int i = 0; i < this->ui->arrangementsListWidget->count(); ++i) + { + auto* otherItem = this->ui->arrangementsListWidget->item(i); + auto o2 = otherItem->data(ARRANGEMENT).value(); + bool enabled = CGAL::assign(arr, o2); + Qt::ItemFlags flags = otherItem->flags(); + if (!enabled) { flags &= ~(Qt::ItemIsEnabled); } + else { flags |= Qt::ItemIsEnabled; } - if ( CGAL::assign( seg, o ) ) - { - for ( int i = 0; i < this->ui->arrangementsListWidget->count( ); ++i ) - { - QListWidgetItem* otherItem = this->ui->arrangementsListWidget->item( i ); - CGAL::Object o2 = otherItem->data( ARRANGEMENT ).value< CGAL::Object >( ); - bool enabled = CGAL::assign( seg, o2 ); - Qt::ItemFlags flags = otherItem->flags( ); - if ( ! enabled ) - { - flags &= ~( Qt::ItemIsEnabled ); + otherItem->setFlags(flags); } - else - { - flags |= Qt::ItemIsEnabled; - } - otherItem->setFlags( flags ); } - } - else if ( CGAL::assign( pol, o ) ) - { - for ( int i = 0; i < this->ui->arrangementsListWidget->count( ); ++i ) - { - QListWidgetItem* otherItem = this->ui->arrangementsListWidget->item( i ); - CGAL::Object o2 = otherItem->data( ARRANGEMENT ).value< CGAL::Object >( ); - bool enabled = CGAL::assign( pol, o2 ); - Qt::ItemFlags flags = otherItem->flags( ); - if ( ! enabled ) - { - flags &= ~( Qt::ItemIsEnabled ); - } - else - { - flags |= Qt::ItemIsEnabled; - } - otherItem->setFlags( flags ); - } - } - else if ( CGAL::assign( lin, o ) ) - { - for ( int i = 0; i < this->ui->arrangementsListWidget->count( ); ++i ) - { - QListWidgetItem* otherItem = this->ui->arrangementsListWidget->item( i ); - CGAL::Object o2 = otherItem->data( ARRANGEMENT ).value< CGAL::Object >( ); - bool enabled = CGAL::assign( lin, o2 ); - Qt::ItemFlags flags = otherItem->flags( ); - if ( ! enabled ) - { - flags &= ~( Qt::ItemIsEnabled ); - } - else - { - flags |= Qt::ItemIsEnabled; - } - otherItem->setFlags( flags ); - } - } - -#ifdef CGAL_USE_CORE - else if ( CGAL::assign( conic, o ) ) - { - for ( int i = 0; i < this->ui->arrangementsListWidget->count( ); ++i ) - { - QListWidgetItem* otherItem = this->ui->arrangementsListWidget->item( i ); - CGAL::Object o2 = otherItem->data( ARRANGEMENT ).value< CGAL::Object >( ); - bool enabled = CGAL::assign( conic, o2 ); - Qt::ItemFlags flags = otherItem->flags( ); - if ( ! enabled ) - { - flags &= ~( Qt::ItemIsEnabled ); - } - else - { - flags |= Qt::ItemIsEnabled; - } - otherItem->setFlags( flags ); - } - } - else if ( CGAL::assign( alg, o ) ) - { - for ( int i = 0; i < this->ui->arrangementsListWidget->count( ); ++i ) - { - QListWidgetItem* otherItem = this->ui->arrangementsListWidget->item( i ); - CGAL::Object o2 = otherItem->data( ARRANGEMENT ).value< CGAL::Object >( ); - bool enabled = CGAL::assign( alg, o2 ); - Qt::ItemFlags flags = otherItem->flags( ); - if ( ! enabled ) - { - flags &= ~( Qt::ItemIsEnabled ); - } - else - { - flags |= Qt::ItemIsEnabled; - } - otherItem->setFlags( flags ); - } - } - else if ( CGAL::assign( bezier, o ) ) - { - for ( int i = 0; i < this->ui->arrangementsListWidget->count( ); ++i ) - { - QListWidgetItem* otherItem = this->ui->arrangementsListWidget->item( i ); - CGAL::Object o2 = otherItem->data( ARRANGEMENT ).value< CGAL::Object >( ); - bool enabled = CGAL::assign( bezier, o2 ); - Qt::ItemFlags flags = otherItem->flags( ); - if ( ! enabled ) - { - flags &= ~( Qt::ItemIsEnabled ); - } - else - { - flags |= Qt::ItemIsEnabled; - } - otherItem->setFlags( flags ); - } - } - else if ( CGAL::assign( rat_arr, o ) ) - { - for ( int i = 0; i < this->ui->arrangementsListWidget->count( ); ++i ) - { - QListWidgetItem* otherItem = this->ui->arrangementsListWidget->item( i ); - CGAL::Object o2 = otherItem->data( ARRANGEMENT ).value< CGAL::Object >( ); - bool enabled = CGAL::assign( rat_arr, o2 ); - Qt::ItemFlags flags = otherItem->flags( ); - if ( ! enabled ) - { - flags &= ~( Qt::ItemIsEnabled ); - } - else - { - flags |= Qt::ItemIsEnabled; - } - otherItem->setFlags( flags ); - } - } -#endif - + }); } void OverlayDialog::unrestrictSelection( )