From 87aec0d9edc2a00507382aa3bc3f694076b1961f Mon Sep 17 00:00:00 2001 From: Abdullah Tahiri Date: Wed, 17 May 2023 14:58:15 +0200 Subject: [PATCH] Skecher: Rendering order ======================== Recently the rendering order functionality was temporarely removed, as it interferred with the development of visual layers. However, the release comes before visual layers are finished and can provide such functionality. This commit reintroduces the functionality for the release. --- src/Mod/Sketcher/Gui/Command.cpp | 227 +++++++++++++++++++++++++++++ src/Mod/Sketcher/Gui/Workbench.cpp | 3 +- 2 files changed, 229 insertions(+), 1 deletion(-) diff --git a/src/Mod/Sketcher/Gui/Command.cpp b/src/Mod/Sketcher/Gui/Command.cpp index 978997afc4..aa229ad7ee 100644 --- a/src/Mod/Sketcher/Gui/Command.cpp +++ b/src/Mod/Sketcher/Gui/Command.cpp @@ -1444,6 +1444,232 @@ bool CmdSketcherSnap::isActive() return false; } + +/* Rendering Order */ +class RenderingOrderAction : public QWidgetAction +{ +public: + RenderingOrderAction(QObject* parent) : QWidgetAction(parent) { + setEnabled(false); + } + + void updateWidget() { + + auto hGrp = getParameterPath(); + + // 1->Normal Geometry, 2->Construction, 3->External + int topid = hGrp->GetInt("TopRenderGeometryId", 1); + int midid = hGrp->GetInt("MidRenderGeometryId", 2); + int lowid = hGrp->GetInt("LowRenderGeometryId", 3); + + { + QSignalBlocker block(this); + list->clear(); + + QListWidgetItem* newItem = new QListWidgetItem; + newItem->setData(Qt::UserRole, QVariant(topid)); + newItem->setText(topid == 1 ? tr("Normal Geometry") : topid == 2 ? tr("Construction Geometry") : tr("External Geometry")); + list->insertItem(0, newItem); + + newItem = new QListWidgetItem; + newItem->setData(Qt::UserRole, QVariant(midid)); + newItem->setText(midid == 1 ? tr("Normal Geometry") : midid == 2 ? tr("Construction Geometry") : tr("External Geometry")); + list->insertItem(1, newItem); + + newItem = new QListWidgetItem; + newItem->setData(Qt::UserRole, QVariant(lowid)); + newItem->setText(lowid == 1 ? tr("Normal Geometry") : lowid == 2 ? tr("Construction Geometry") : tr("External Geometry")); + list->insertItem(2, newItem); + } + } + + void languageChange() + { + updateWidget(); + } + +protected: + QWidget* createWidget(QWidget* parent) override + { + list = new QListWidget(); + list->setDragDropMode(QAbstractItemView::InternalMove); + list->setDefaultDropAction(Qt::MoveAction); + list->setSelectionMode(QAbstractItemView::SingleSelection); + list->setDragEnabled(true); + + QWidget* renderingWidget = new QWidget(parent); + auto* layout = new QGridLayout(renderingWidget); + layout->addWidget(list, 0, 0, 0, 0); + + languageChange(); + + // Handle change in the order of the list entries + QObject::connect(list->model(), &QAbstractItemModel::rowsMoved, + [this](const QModelIndex &sourceParent, int sourceStart, int sourceEnd, + const QModelIndex &destinationParent, int destinationRow) { + Q_UNUSED(sourceParent) + Q_UNUSED(sourceStart) + Q_UNUSED(sourceEnd) + Q_UNUSED(destinationParent) + Q_UNUSED(destinationRow) + + int topid = list->item(0)->data(Qt::UserRole).toInt(); + int midid = list->item(1)->data(Qt::UserRole).toInt(); + int lowid = list->item(2)->data(Qt::UserRole).toInt(); + + auto hGrp = getParameterPath(); + + hGrp->SetInt("TopRenderGeometryId", topid); + hGrp->SetInt("MidRenderGeometryId", midid); + hGrp->SetInt("LowRenderGeometryId", lowid); + }); + + return renderingWidget; + } + +private: + ParameterGrp::handle getParameterPath() { + return App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher/General"); + } + +private: + QListWidget* list; +}; + +class CmdRenderingOrder : public Gui::Command, public ParameterGrp::ObserverType +{ + enum class ElementType { + Normal = 1, + Construction = 2, + External = 3, + }; +public: + CmdRenderingOrder(); + virtual ~CmdRenderingOrder(); + virtual const char* className() const override + { return "CmdRenderingOrder"; } + virtual void languageChange() override; + void OnChange(Base::Subject &rCaller, const char * sReason) override; +protected: + virtual void activated(int iMsg) override; + virtual bool isActive(void) override; + virtual Gui::Action * createAction(void) override; +private: + void updateIcon(); + + ParameterGrp::handle getParameterPath() { + return App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher/General"); + } + + CmdRenderingOrder(const CmdRenderingOrder&) = delete; + CmdRenderingOrder(CmdRenderingOrder&&) = delete; + CmdRenderingOrder& operator= (const CmdRenderingOrder&) = delete; + CmdRenderingOrder& operator= (CmdRenderingOrder&&) = delete; + + ElementType TopElement = ElementType::Normal; +}; + +CmdRenderingOrder::CmdRenderingOrder() + : Command("Sketcher_RenderingOrder") +{ + sAppModule = "Sketcher"; + sGroup = "Sketcher"; + sMenuText = QT_TR_NOOP("Configure rendering order"); + sToolTipText = QT_TR_NOOP("Reorder the items in the list to configure rendering order."); + sWhatsThis = "Sketcher_RenderingOrder"; + sStatusTip = sToolTipText; + eType = 0; + + ParameterGrp::handle hGrp = this->getParameterPath(); + hGrp->Attach(this); + + TopElement = static_cast(getParameterPath()->GetInt("TopRenderGeometryId", 1)); +} + +CmdRenderingOrder::~CmdRenderingOrder() { + + ParameterGrp::handle hGrp = this->getParameterPath(); + hGrp->Detach(this); +} + +void CmdRenderingOrder::OnChange(Base::Subject &rCaller, const char * sReason) +{ + Q_UNUSED(rCaller) + + if (strcmp(sReason, "TopRenderGeometryId") == 0) { + TopElement = static_cast(getParameterPath()->GetInt("TopRenderGeometryId", 1)); + + updateIcon(); + } +} + +void CmdRenderingOrder::updateIcon() +{ + static QIcon normal = Gui::BitmapFactory().iconFromTheme("Sketcher_RenderingOrder_Normal"); + static QIcon construction = Gui::BitmapFactory().iconFromTheme("Sketcher_RenderingOrder_Construction"); + static QIcon external = Gui::BitmapFactory().iconFromTheme("Sketcher_RenderingOrder_External"); + + auto * pcAction = qobject_cast(getAction()); + + if(TopElement == ElementType::Normal) { + pcAction->setIcon(normal); + } + else if(TopElement == ElementType::Construction) { + pcAction->setIcon(construction); + } + else if(TopElement == ElementType::External) { + pcAction->setIcon(external); + } +} + +void CmdRenderingOrder::activated(int iMsg) +{ + Q_UNUSED(iMsg); +} + +Gui::Action* CmdRenderingOrder::createAction() +{ + auto * pcAction = new Gui::ActionGroup(this, Gui::getMainWindow()); + pcAction->setDropDownMenu(true); + pcAction->setExclusive(false); + applyCommandData(this->className(), pcAction); + + RenderingOrderAction* roa = new RenderingOrderAction(pcAction); + pcAction->addAction(roa); + + _pcAction = pcAction; + + QObject::connect(pcAction, &Gui::ActionGroup::aboutToShow, [roa](QMenu * menu) { + Q_UNUSED(menu) + roa->updateWidget(); + }); + + // set the right pixmap + updateIcon(); + + return pcAction; +} + +void CmdRenderingOrder::languageChange() +{ + Command::languageChange(); + + if (!_pcAction) + return; + + Gui::ActionGroup* pcAction = qobject_cast(_pcAction); + QList a = pcAction->actions(); + + auto* roa = static_cast(a[0]); + roa->languageChange(); +} + +bool CmdRenderingOrder::isActive() +{ + return isSketchInEdit(getActiveGuiDocument());; +} + + void CreateSketcherCommands() { Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager(); @@ -1461,4 +1687,5 @@ void CreateSketcherCommands() rcCmdMgr.addCommand(new CmdSketcherViewSection()); rcCmdMgr.addCommand(new CmdSketcherGrid()); rcCmdMgr.addCommand(new CmdSketcherSnap()); + rcCmdMgr.addCommand(new CmdRenderingOrder()); } diff --git a/src/Mod/Sketcher/Gui/Workbench.cpp b/src/Mod/Sketcher/Gui/Workbench.cpp index ee3c733daa..46cfdc4d92 100644 --- a/src/Mod/Sketcher/Gui/Workbench.cpp +++ b/src/Mod/Sketcher/Gui/Workbench.cpp @@ -511,7 +511,8 @@ template <> inline void SketcherAddWorkbenchEditTools(Gui::ToolBarItem& edittools) { edittools << "Sketcher_Grid" - << "Sketcher_Snap"; + << "Sketcher_Snap" + << "Sketcher_RenderingOrder"; } void addSketcherWorkbenchSketchActions(Gui::MenuItem& sketch)