From 94d39087d34ed9e5f4aafe99012cdb511cf194dc Mon Sep 17 00:00:00 2001 From: George Peden Date: Mon, 16 Jun 2025 09:05:13 -0700 Subject: [PATCH] Sketcher: Add contextual input hints to edit tools (InputHints Phase 3) (#21806) * Add input hints to fillet and chamfer tools * Add hints to trimming tool * Add hints to splitting tool * Implement hints for extend tool * Add hints to external geometry * Add hints to Carbon Copy tool * Hint updates to align with developer guidelines * change "click to set" to "set" per PR comments * Use enum (or declare one) to be type safe per PR comments * For "trivial" one-step / one-state tools, refactor with direct hint return rather than using declarative / table pattern. * Refactor hint tables initializers with C++20 features per PR feedback - Use designated initializers (.state = , .hints = ) for clearer structure - Add 'using enum Gui::InputHint::UserInput' to eliminate repetitive prefixes - Applied to DrawSketchHandlerExtend and DrawSketchHandlerFillet * Refactor Splitting tool hint implementation with direct return (trivial) pattern * For fillet change "vertex" to "point" per PR feedback * Change hint to "pick location on edge to split" per PR feedback --- .../Gui/DrawSketchHandlerCarbonCopy.h | 8 ++++ .../Sketcher/Gui/DrawSketchHandlerExtend.h | 43 ++++++++++++++++- .../Sketcher/Gui/DrawSketchHandlerExternal.h | 10 +++- .../Sketcher/Gui/DrawSketchHandlerFillet.h | 46 ++++++++++++++++++- .../Sketcher/Gui/DrawSketchHandlerSplitting.h | 16 +++++++ .../Sketcher/Gui/DrawSketchHandlerTrimming.h | 9 +++- 6 files changed, 127 insertions(+), 5 deletions(-) diff --git a/src/Mod/Sketcher/Gui/DrawSketchHandlerCarbonCopy.h b/src/Mod/Sketcher/Gui/DrawSketchHandlerCarbonCopy.h index cd4877758f..ecea388f5c 100644 --- a/src/Mod/Sketcher/Gui/DrawSketchHandlerCarbonCopy.h +++ b/src/Mod/Sketcher/Gui/DrawSketchHandlerCarbonCopy.h @@ -191,6 +191,7 @@ public: return true; } } + updateHint(); return false; } @@ -218,6 +219,13 @@ private: Q_UNUSED(sketchgui); setAxisPickStyle(true); } + +public: + std::list getToolHints() const override + { + return {{QObject::tr("%1 pick sketch to copy", "Sketcher CarbonCopy: hint"), + {Gui::InputHint::UserInput::MouseLeft}}}; + } }; } // namespace SketcherGui diff --git a/src/Mod/Sketcher/Gui/DrawSketchHandlerExtend.h b/src/Mod/Sketcher/Gui/DrawSketchHandlerExtend.h index 587db8d527..dcaf58f333 100644 --- a/src/Mod/Sketcher/Gui/DrawSketchHandlerExtend.h +++ b/src/Mod/Sketcher/Gui/DrawSketchHandlerExtend.h @@ -344,6 +344,8 @@ public: sketchgui ->purgeHandler(); // no code after this line, Handler get deleted in ViewProvider } + + updateHint(); return true; } @@ -371,6 +373,24 @@ protected: double Increment; std::vector SugConstr; + // Add hint structures here + struct HintEntry + { + SelectMode state; + std::list hints; + }; + + using HintTable = std::vector; + + static HintTable getExtendHintTable(); + static std::list lookupExtendHints(SelectMode state); + +public: + std::list getToolHints() const override + { + return lookupExtendHints(Mode); + } + private: int crossProduct(Base::Vector2d& vec1, Base::Vector2d& vec2) { @@ -378,8 +398,29 @@ private: } }; +DrawSketchHandlerExtend::HintTable DrawSketchHandlerExtend::getExtendHintTable() +{ + using enum Gui::InputHint::UserInput; + + return { + {.state = STATUS_SEEK_First, + .hints = {{QObject::tr("%1 pick edge to extend", "Sketcher Extend: hint"), {MouseLeft}}}}, + {.state = STATUS_SEEK_Second, + .hints = { + {QObject::tr("%1 set extension length", "Sketcher Extend: hint"), {MouseLeft}}}}}; +} + +std::list DrawSketchHandlerExtend::lookupExtendHints(SelectMode state) +{ + const auto extendHintTable = getExtendHintTable(); + + auto it = std::ranges::find_if(extendHintTable, [state](const HintEntry& entry) { + return entry.state == state; + }); + + return (it != extendHintTable.end()) ? it->hints : std::list {}; +} } // namespace SketcherGui - #endif // SKETCHERGUI_DrawSketchHandlerExtend_H diff --git a/src/Mod/Sketcher/Gui/DrawSketchHandlerExternal.h b/src/Mod/Sketcher/Gui/DrawSketchHandlerExternal.h index 697204f472..91ee22c2c6 100644 --- a/src/Mod/Sketcher/Gui/DrawSketchHandlerExternal.h +++ b/src/Mod/Sketcher/Gui/DrawSketchHandlerExternal.h @@ -208,6 +208,8 @@ public: return true; } } + updateHint(); + return false; } @@ -242,8 +244,14 @@ private: bool alwaysReference; bool intersection; -}; +public: + std::list getToolHints() const override + { + return {{QObject::tr("%1 pick external geometry", "Sketcher External: hint"), + {Gui::InputHint::UserInput::MouseLeft}}}; + } +}; } // namespace SketcherGui diff --git a/src/Mod/Sketcher/Gui/DrawSketchHandlerFillet.h b/src/Mod/Sketcher/Gui/DrawSketchHandlerFillet.h index f1da6a0885..2963d8a26e 100644 --- a/src/Mod/Sketcher/Gui/DrawSketchHandlerFillet.h +++ b/src/Mod/Sketcher/Gui/DrawSketchHandlerFillet.h @@ -402,6 +402,7 @@ private: moveToNextMode(); } } + updateHint(); } @@ -409,6 +410,23 @@ private: bool preserveCorner; int vtId, geoId1, geoId2; Base::Vector2d firstPos, secondPos; + + struct HintEntry + { + SelectMode state; + std::list hints; + }; + + using HintTable = std::vector; + + static HintTable getFilletHintTable(); + static std::list lookupFilletHints(SelectMode state); + +public: + std::list getToolHints() const override + { + return lookupFilletHints(state()); + } }; template<> @@ -456,7 +474,33 @@ void DSHFilletController::adaptDrawingToCheckboxChange(int checkboxindex, bool v handler->updateCursor(); } + +DrawSketchHandlerFillet::HintTable DrawSketchHandlerFillet::getFilletHintTable() +{ + using enum Gui::InputHint::UserInput; + + return {{.state = SelectMode::SeekFirst, + .hints = {{QObject::tr("%1 pick first edge or point", "Sketcher Fillet/Chamfer: hint"), + {MouseLeft}}}}, + {.state = SelectMode::SeekSecond, + .hints = {{QObject::tr("%1 pick second edge", "Sketcher Fillet/Chamfer: hint"), + {MouseLeft}}}}, + {.state = SelectMode::End, + .hints = { + {QObject::tr("%1 create fillet", "Sketcher Fillet/Chamfer: hint"), {MouseLeft}}}}}; +} + +std::list DrawSketchHandlerFillet::lookupFilletHints(SelectMode state) +{ + const auto filletHintTable = getFilletHintTable(); + + auto it = std::ranges::find_if(filletHintTable, [state](const HintEntry& entry) { + return entry.state == state; + }); + + return (it != filletHintTable.end()) ? it->hints : std::list {}; +} + } // namespace SketcherGui - #endif // SKETCHERGUI_DrawSketchHandlerFillet_H diff --git a/src/Mod/Sketcher/Gui/DrawSketchHandlerSplitting.h b/src/Mod/Sketcher/Gui/DrawSketchHandlerSplitting.h index 0507580fb9..bc1a494018 100644 --- a/src/Mod/Sketcher/Gui/DrawSketchHandlerSplitting.h +++ b/src/Mod/Sketcher/Gui/DrawSketchHandlerSplitting.h @@ -187,6 +187,22 @@ private: { return QStringLiteral("Sketcher_Pointer_Splitting"); } + + enum State + { + WaitingForEdge + }; + +private: + std::vector EditMarkers; + bool mousePressed = false; + +public: + std::list getToolHints() const override + { + return {{QObject::tr("%1 pick location on edge to split", "Sketcher Splitting: hint"), + {Gui::InputHint::UserInput::MouseLeft}}}; + } }; } // namespace SketcherGui diff --git a/src/Mod/Sketcher/Gui/DrawSketchHandlerTrimming.h b/src/Mod/Sketcher/Gui/DrawSketchHandlerTrimming.h index 83bbca9a19..1b66e2856a 100644 --- a/src/Mod/Sketcher/Gui/DrawSketchHandlerTrimming.h +++ b/src/Mod/Sketcher/Gui/DrawSketchHandlerTrimming.h @@ -208,10 +208,15 @@ private: private: std::vector EditMarkers; bool mousePressed = false; -}; +public: + std::list getToolHints() const override + { + return {{QObject::tr("%1 pick edge to trim", "Sketcher Trimming: hint"), + {Gui::InputHint::UserInput::MouseLeft}}}; + } +}; } // namespace SketcherGui - #endif // SKETCHERGUI_DrawSketchHandlerTrimming_H