From a5b5d01c22c173f97ea614dc2b71293b0d0df696 Mon Sep 17 00:00:00 2001 From: Paddle Date: Wed, 30 Aug 2023 14:24:10 +0200 Subject: [PATCH] DSH architecture: On-view spinboxes --- .../Gui/DrawSketchDefaultWidgetHandler.h | 183 +++++++++++++++--- 1 file changed, 158 insertions(+), 25 deletions(-) diff --git a/src/Mod/Sketcher/Gui/DrawSketchDefaultWidgetHandler.h b/src/Mod/Sketcher/Gui/DrawSketchDefaultWidgetHandler.h index 55fa936f42..a88992232f 100644 --- a/src/Mod/Sketcher/Gui/DrawSketchDefaultWidgetHandler.h +++ b/src/Mod/Sketcher/Gui/DrawSketchDefaultWidgetHandler.h @@ -29,6 +29,7 @@ #include "SketcherToolDefaultWidget.h" #include +#include #include @@ -72,7 +73,7 @@ namespace SketcherGui * Widget MAY need to specialise, if default behaviour is not appropriate: * - doChangeDrawSketchHandlerMode() * - onHandlerModeChanged() - * - adaptWidgetParameters() + * - adaptParameters() * - doEnforceWidgetParameters() * * Handler provides: @@ -120,6 +121,11 @@ private: static constexpr std::array constructionMethodParameters = {{sizes...}}; }; +template // Initial sizes for each mode +class OnViewParameters: public WidgetInitialValues +{ +}; + template // Initial sizes for each mode class WidgetParameters: public WidgetInitialValues { @@ -139,6 +145,7 @@ template onViewParameters; + + public: + bool firstMoveInit = false; + int labelIndexWithFocus = 0; + public: ToolWidgetManager(DrawSketchDefaultWidgetHandler* dshandler) : handler(dshandler) @@ -193,6 +221,10 @@ private: connectionParameterValueChanged.disconnect(); connectionCheckboxCheckedChanged.disconnect(); connectionComboboxSelectionChanged.disconnect(); + + for (auto* label : onViewParameters) { + delete label; + } } /** @name functions NOT intended for specialisation */ @@ -224,11 +256,38 @@ private: boost::signals2::shared_connection_block combobox_block( connectionComboboxSelectionChanged); + initNLabels(nOnViewParameter); toolWidget->initNParameters(nParameter); toolWidget->initNCheckboxes(nCheckbox); toolWidget->initNComboboxes(nCombobox); configureToolWidget(); + + firstMoveInit = false; + labelIndexWithFocus = 0; + } + + void initNLabels(int n) + { + Gui::View3DInventorViewer* viewer = handler->getViewer(); + Base::Placement placement = handler->sketchgui->getSketchObject()->Placement.getValue(); + + for (auto* label : onViewParameters) { + delete label; + } + onViewParameters.clear(); + + for (int i = 0; i < n; i++) { + auto* label = new Gui::EditableDatumLabel(viewer, + placement, + SbColor(0.8f, 0.8f, 0.8f), + /*autoDistance = */ true); + QObject::connect(label, &Gui::EditableDatumLabel::valueChanged, [=](double value) { + label->setColor(SbColor(1.0f, 0.149f, 0.0f)); + labelValueChanged(i, value); + }); + onViewParameters.push_back(label); + } } void enforceWidgetParameters(Base::Vector2d& onSketchPos) @@ -238,13 +297,20 @@ private: doEnforceWidgetParameters(onSketchPos); lastWidgetEnforcedPosition = onSketchPos; // store enforced cursor position. + + // Give focus to current label. In case user interacted outside of 3dview. + setFocusToLabel(labelIndexWithFocus); } - /** boost slot triggering when a parameter has changed in the widget + /** slot triggering when a on view parameter has changed * It is intended to remote control the DrawSketchDefaultWidgetHandler */ - void parameterValueChanged(int parameterindex, double value) + void labelValueChanged(int labelindex, double value) { + if (isLabelOfCurrentMode(labelindex + 1)) { + setFocusToLabel(labelindex + 1); + } + // -> A machine does not forward to a next state when adapting the parameter (though it // may forward to // a next state if all the parameters are fulfilled, see @@ -255,13 +321,25 @@ private: // -> A machine goes back to a previous state if a parameter of a previous state is // modified. This ensures // that appropriate autoconstraints are picked. - if (isParameterOfPreviousMode(parameterindex)) { + if (isLabelOfPreviousMode(labelindex)) { // change to previous state - handler->setState(getState(parameterindex)); + handler->setState(getState(labelindex)); } enforceWidgetParametersOnPreviousCursorPosition(); + adaptDrawingToLabelChange(labelindex, value); + + finishWidgetChanged(); + } + + /** boost slot triggering when a parameter has changed in the widget + * It is intended to remote control the DrawSketchDefaultWidgetHandler + */ + void parameterValueChanged(int parameterindex, double value) + { + enforceWidgetParametersOnPreviousCursorPosition(); + adaptDrawingToParameterChange(parameterindex, value); finishWidgetChanged(); @@ -293,15 +371,22 @@ private: finishWidgetChanged(); } - void adaptWidgetParameters() + void adaptParameters() { - adaptWidgetParameters(lastWidgetEnforcedPosition); + adaptParameters(lastWidgetEnforcedPosition); } //@} /** @name functions which MUST be specialised */ //@{ + /// Change DSH to reflect a value entered in the view + void adaptDrawingToLabelChange(int labelindex, double value) + { + Q_UNUSED(labelindex); + Q_UNUSED(value); + } + /// Change DSH to reflect a value entered in the widget void adaptDrawingToParameterChange(int parameterindex, double value) { @@ -414,6 +499,13 @@ private: } } + /// Function triggered before the first mouse move, to be used to initialize the on view + /// labels. + void beforeFirstMouseMove(Base::Vector2d onSketchPos) + { + Q_UNUSED(onSketchPos); + } + /** Change DSH to reflect the SelectMode it should be in based on values entered in the * widget * @@ -609,6 +701,7 @@ private: void onConstructionMethodChanged() { + nOnViewParameter = OnViewParametersT::size(handler->constructionMethod()); nParameter = WidgetParametersT::size(handler->constructionMethod()); nCheckbox = WidgetCheckboxesT::size(handler->constructionMethod()); nCombobox = WidgetComboboxesT::size(handler->constructionMethod()); @@ -639,7 +732,7 @@ private: * * It MUST be specialised if the states correspond to different parameters */ - void adaptWidgetParameters(Base::Vector2d onSketchPos) + void adaptParameters(Base::Vector2d onSketchPos) { if constexpr (std::is_same_v) { switch (handler->state()) { @@ -894,31 +987,62 @@ private: toolWidget->setCheckboxChecked(WCheckbox::SecondBox, !secondchecked); } } + + /* This function give the focus to a spinbox and register to which it gave it.*/ + void setFocusToLabel(unsigned int labelindex) + { + if (labelindex < onViewParameters.size()) { + onViewParameters[labelindex]->setFocusToSpinbox(); + labelIndexWithFocus = labelindex; + } + } //@} + void passFocusToNextLabel() + { + unsigned int index = labelIndexWithFocus + 1; + + if (index >= onViewParameters.size()) { + index = 0; + } + while (index < onViewParameters.size()) { + if (isLabelOfCurrentMode(index)) { + setFocusToLabel(index); + break; + } + index++; + } + } + private: /** @name helper functions */ //@{ /// function to assist in adaptDrawingToComboboxChange specialisation /// assigns the modevalue to the modeenum and updates the number of parameters according to /// map it also triggers an update of the cursor - /*template + /* + template void setModeAndAdaptParameters(T & modeenum, int modevalue, const std::vector & - parametersmap) { if (modevalue < static_cast(parametersmap.size())) { auto mode = - static_cast(modevalue); + parametersmap) + { + if (modevalue < static_cast(parametersmap.size())) { + auto mode = static_cast(modevalue); - nParameter = WidgetParametersT::constructionMethodParameters[modevalue]; - nCheckbox = WidgetCheckboxesT::constructionMethodParameters[modevalue]; - nCombobox = WidgetComboboxesT::constructionMethodParameters[modevalue]; + nOnViewParameter = OnViewParametersT::constructionMethodParameters[modevalue]; + nParameter = WidgetParametersT::constructionMethodParameters[modevalue]; + nCheckbox = WidgetCheckboxesT::constructionMethodParameters[modevalue]; + nCombobox = WidgetComboboxesT::constructionMethodParameters[modevalue]; - modeenum = mode; - dHandler->updateCursor(); + modeenum = mode; - reset(); //reset the widget to take into account the change of nparameter - dHandler->reset(); //reset of handler to restart. + dHandler->updateCursor(); + + reset(); //reset the widget to take into account the change of nparameter + dHandler->reset(); //reset of handler to restart. } - }*/ + } + */ /// function to assist in adaptDrawingToComboboxChange specialisation /// assigns the modevalue to the modeenum @@ -956,7 +1080,7 @@ private: enforceWidgetParametersOnPreviousCursorPosition(); // update the widget if state changed - adaptWidgetParameters(lastWidgetEnforcedPosition); + adaptParameters(lastWidgetEnforcedPosition); // ensure drawing in the next mode handler->updateDataAndDrawToPosition(lastWidgetEnforcedPosition); @@ -1021,14 +1145,14 @@ private: } } - bool isParameterOfCurrentMode(int parameterindex) const + bool isLabelOfCurrentMode(unsigned int labelindex) const { - return getState(parameterindex) == handler->state(); + return labelindex < onViewParameters.size() && getState(labelindex) == handler->state(); } - bool isParameterOfPreviousMode(int parameterindex) const + bool isLabelOfPreviousMode(unsigned int labelindex) const { - return getState(parameterindex) < handler->state(); + return labelindex < onViewParameters.size() && getState(labelindex) < handler->state(); } //@} }; @@ -1039,14 +1163,19 @@ public: : DSDefaultHandler(constructionmethod) , toolWidgetManager(this) {} + virtual ~DrawSketchDefaultWidgetHandler() = default; /** @name functions NOT intended for specialisation */ //@{ virtual void mouseMove(Base::Vector2d onSketchPos) override { + if (!toolWidgetManager.firstMoveInit) { + toolWidgetManager.firstMoveInit = true; + toolWidgetManager.beforeFirstMouseMove(onSketchPos); + } toolWidgetManager.enforceWidgetParameters(onSketchPos); - toolWidgetManager.adaptWidgetParameters(onSketchPos); + toolWidgetManager.adaptParameters(onSketchPos); updateDataAndDrawToPosition(onSketchPos); } @@ -1141,6 +1270,10 @@ private: if (key == SoKeyboardEvent::J && !pressed && !this->isLastState()) { toolWidgetManager.secondKeyShortcut(); } + + if (key == SoKeyboardEvent::TAB && !pressed) { + toolWidgetManager.passFocusToNextLabel(); + } } //@}