781 lines
27 KiB
C++
781 lines
27 KiB
C++
/***************************************************************************
|
|
* Copyright (c) 2023 Abdullah Tahiri <abdullah.tahiri.yo@gmail.com> *
|
|
* *
|
|
* This file is part of the FreeCAD CAx development system. *
|
|
* *
|
|
* This library is free software; you can redistribute it and/or *
|
|
* modify it under the terms of the GNU Library General Public *
|
|
* License as published by the Free Software Foundation; either *
|
|
* version 2 of the License, or (at your option) any later version. *
|
|
* *
|
|
* This library is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU Library General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU Library General Public *
|
|
* License along with this library; see the file COPYING.LIB. If not, *
|
|
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
|
* Suite 330, Boston, MA 02111-1307, USA *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
#ifndef SKETCHERGUI_DrawSketchController_H
|
|
#define SKETCHERGUI_DrawSketchController_H
|
|
|
|
#include <Base/Tools2D.h>
|
|
#include <Gui/EditableDatumLabel.h>
|
|
|
|
#include "DrawSketchDefaultHandler.h"
|
|
#include "SketcherToolDefaultWidget.h"
|
|
|
|
#include "DrawSketchKeyboardManager.h"
|
|
|
|
namespace SketcherGui
|
|
{
|
|
|
|
/** @brief template class for creating a type encapsulating an int value associated to each of
|
|
the possible construction modes supported by the tool.
|
|
|
|
@details Different construction modes of a DSH may use different types of controls. This class
|
|
allows to instantiate a handler template class to provide such construction mode specific
|
|
controls.
|
|
|
|
Each different type of control is a template class deriving from this.
|
|
*/
|
|
template<int... sizes> // Initial sizes for each mode
|
|
class ControlAmount
|
|
{
|
|
public:
|
|
template<typename constructionT>
|
|
static constexpr int size(constructionT constructionmethod)
|
|
{
|
|
auto modeint = static_cast<int>(constructionmethod);
|
|
|
|
return constructionMethodParameters[modeint];
|
|
}
|
|
|
|
static constexpr int defaultMethodSize()
|
|
{
|
|
return size(0);
|
|
}
|
|
|
|
private:
|
|
static constexpr std::array<int, sizeof...(sizes)> constructionMethodParameters = {{sizes...}};
|
|
};
|
|
|
|
/** @brief Type encapsulating the number of On view parameters*/
|
|
template<int... sizes> // Initial sizes for each mode
|
|
class OnViewParameters: public ControlAmount<sizes...>
|
|
{
|
|
};
|
|
|
|
namespace sp = std::placeholders;
|
|
|
|
/** @brief Class defining a generic handler controller operable with a DrawSketchControllableHandler
|
|
*
|
|
* @details
|
|
* This class is intended as a parent for controller classes. This controller class provides the
|
|
* essential controller functionalities, including on-view parameters. This controller class does
|
|
* NOT control based on (taskbox) widgets.
|
|
*
|
|
* For an example of a tool using directly this class see DrawSketchHandlerPoint.
|
|
*
|
|
* Controls based on taskbox widgets may derive from this class and add on top any widget mandated
|
|
* functionality. For the default widget (SketcherToolDefaultWidget), see
|
|
* DrawSketchDefaultWidgetController. For custom widgets, an appropriate class, preferably deriving
|
|
* from this controller needs to be provided.
|
|
*/
|
|
template<typename HandlerT, // The name of the actual handler of the tool
|
|
typename SelectModeT, // The state machine defining the working of the tool
|
|
int PAutoConstraintSize, // The initial size of the AutoConstraint vector
|
|
typename OnViewParametersT, // The number of parameter spinboxes in the 3D view (one
|
|
// value per construction mode)
|
|
typename ConstructionMethodT =
|
|
ConstructionMethods::DefaultConstructionMethod> // The enum comprising all the
|
|
// supported construction methods
|
|
class DrawSketchController
|
|
{
|
|
public:
|
|
/** @name Meta-programming definitions and members */
|
|
//@{
|
|
using ControllerBase = void; // No base controller for parent class.
|
|
|
|
using HandlerType = HandlerT;
|
|
using SelectModeType = SelectModeT;
|
|
using ContructionMethodType = ConstructionMethodT;
|
|
static constexpr const int AutoConstraintInitialSize = PAutoConstraintSize;
|
|
//@}
|
|
|
|
/** @name Convenience definitions */
|
|
//@{
|
|
using DSDefaultHandler =
|
|
DrawSketchDefaultHandler<HandlerT, SelectModeT, PAutoConstraintSize, ConstructionMethodT>;
|
|
using ConstructionMachine = ConstructionMethodMachine<ConstructionMethodT>;
|
|
|
|
using ConstructionMethod = ConstructionMethodT;
|
|
using SelectMode = SelectModeT;
|
|
//@}
|
|
|
|
protected:
|
|
// NOLINTBEGIN
|
|
HandlerT* handler; // real derived type
|
|
std::vector<std::unique_ptr<Gui::EditableDatumLabel>> onViewParameters;
|
|
// NOLINTEND
|
|
|
|
bool init = false; // true if the controls have been initialised.
|
|
int parameterWithFocus = 0; // track the index of the parameter having the focus
|
|
|
|
/** @name Named indices for controlling on-view controls */
|
|
//@{
|
|
enum OnViewParameter
|
|
{
|
|
First,
|
|
Second,
|
|
Third,
|
|
Fourth,
|
|
Fifth,
|
|
Sixth,
|
|
Seventh,
|
|
Eighth,
|
|
Ninth,
|
|
Tenth,
|
|
nOnViewParameters // Must Always be the last one
|
|
};
|
|
//@}
|
|
|
|
private:
|
|
Base::Vector2d prevCursorPosition;
|
|
Base::Vector2d lastControlEnforcedPosition;
|
|
|
|
int nOnViewParameter = OnViewParametersT::defaultMethodSize();
|
|
|
|
/// Class to keep track of colors used by the on-view parameters
|
|
class ColorManager
|
|
{
|
|
public:
|
|
SbColor dimConstrColor, dimConstrDeactivatedColor;
|
|
|
|
ColorManager()
|
|
{
|
|
init();
|
|
}
|
|
|
|
private:
|
|
void init()
|
|
{
|
|
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
|
|
"User parameter:BaseApp/Preferences/View");
|
|
|
|
dimConstrColor = SbColor(1.0f, 0.149f, 0.0f); // NOLINT
|
|
dimConstrDeactivatedColor = SbColor(0.8f, 0.8f, 0.8f); // NOLINT
|
|
|
|
float transparency = 0.f;
|
|
unsigned long color = (unsigned long)(dimConstrColor.getPackedValue());
|
|
color = hGrp->GetUnsigned("ConstrainedDimColor", color);
|
|
dimConstrColor.setPackedValue((uint32_t)color, transparency);
|
|
|
|
color = (unsigned long)(dimConstrDeactivatedColor.getPackedValue());
|
|
color = hGrp->GetUnsigned("DeactivatedConstrDimColor", color);
|
|
dimConstrDeactivatedColor.setPackedValue((uint32_t)color, transparency);
|
|
}
|
|
};
|
|
|
|
class OnViewParameterVisibilityManager
|
|
{
|
|
public:
|
|
enum class OnViewParameterVisibility
|
|
{
|
|
Hidden = 0,
|
|
OnlyDimensional = 1,
|
|
ShowAll = 2
|
|
};
|
|
|
|
OnViewParameterVisibilityManager()
|
|
{
|
|
init();
|
|
}
|
|
|
|
OnViewParameterVisibility visibility() const
|
|
{
|
|
return onViewParameterVisibility;
|
|
}
|
|
|
|
bool isVisibility(OnViewParameterVisibility visibility) const
|
|
{
|
|
return onViewParameterVisibility == visibility;
|
|
}
|
|
|
|
bool isVisible(Gui::EditableDatumLabel* ovp) const
|
|
{
|
|
switch (onViewParameterVisibility) {
|
|
|
|
case OnViewParameterVisibility::Hidden:
|
|
return dynamicOverride;
|
|
case OnViewParameterVisibility::OnlyDimensional: {
|
|
auto isDimensional =
|
|
(ovp->getFunction() == Gui::EditableDatumLabel::Function::Dimensioning);
|
|
|
|
return isDimensional != dynamicOverride;
|
|
}
|
|
case OnViewParameterVisibility::ShowAll:
|
|
return !dynamicOverride;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void toggleDynamicOverride()
|
|
{
|
|
dynamicOverride = !dynamicOverride;
|
|
}
|
|
|
|
void resetDynamicOverride()
|
|
{
|
|
dynamicOverride = false;
|
|
}
|
|
|
|
|
|
private:
|
|
void init()
|
|
{
|
|
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
|
|
"User parameter:BaseApp/Preferences/Mod/Sketcher/Tools");
|
|
|
|
onViewParameterVisibility = static_cast<OnViewParameterVisibility>(
|
|
hGrp->GetInt("OnViewParameterVisibility", 1));
|
|
}
|
|
|
|
OnViewParameterVisibility onViewParameterVisibility;
|
|
bool dynamicOverride = false;
|
|
};
|
|
|
|
public:
|
|
/** Creates the controller.
|
|
* @param dshandler a controllable DSH handler
|
|
*/
|
|
explicit DrawSketchController(HandlerT* dshandler)
|
|
: handler(dshandler)
|
|
, keymanager(std::make_unique<DrawSketchKeyboardManager>())
|
|
{}
|
|
|
|
DrawSketchController(const DrawSketchController&) = delete;
|
|
DrawSketchController(DrawSketchController&&) = delete;
|
|
DrawSketchController& operator=(const DrawSketchController&) = delete;
|
|
DrawSketchController& operator=(DrawSketchController&&) = delete;
|
|
|
|
virtual ~DrawSketchController()
|
|
{}
|
|
|
|
/** @name functions NOT intended for specialisation offering a NVI for extension */
|
|
/** These functions offer a NVI to ensure the order on initialisation. It is heavily encouraged
|
|
* to extend functionality using the NVI interface (by overriding the NVI functions).
|
|
*/
|
|
//@{
|
|
|
|
/** @brief Initialises controls, such as the widget and the on-view parameters via NVI.*/
|
|
void initControls(QWidget* widget)
|
|
{
|
|
doInitControls(widget); // NVI
|
|
|
|
resetControls();
|
|
init = true;
|
|
}
|
|
|
|
/** @brief Resets the controls, such as the widget and the on-view parameters */
|
|
void resetControls()
|
|
{
|
|
// Make sure we do not loose focus if next methode does not have OVP that take focus.
|
|
handler->ensureFocus();
|
|
|
|
doResetControls(); // NVI
|
|
|
|
firstMoveInit = false;
|
|
}
|
|
|
|
/** @brief function triggered by the handler when the mouse has been moved */
|
|
void mouseMoved(Base::Vector2d originalSketchPosition)
|
|
{
|
|
onMouseMoved(originalSketchPosition); // NVI
|
|
|
|
if (!firstMoveInit) {
|
|
firstMoveInit = true;
|
|
}
|
|
}
|
|
|
|
/** @brief function triggered by the handler to ensure its operating position takes into
|
|
* account widget mandated parameters */
|
|
void enforceControlParameters(Base::Vector2d& onSketchPos)
|
|
{
|
|
prevCursorPosition = onSketchPos;
|
|
|
|
doEnforceControlParameters(onSketchPos); // specialisation interface
|
|
|
|
lastControlEnforcedPosition = onSketchPos; // store enforced cursor position.
|
|
|
|
afterEnforceControlParameters(); // NVI
|
|
}
|
|
|
|
/** function that is called by the handler when the construction mode changed */
|
|
void onConstructionMethodChanged()
|
|
{
|
|
doConstructionMethodChanged(); // NVI
|
|
|
|
handler->updateCursor();
|
|
|
|
if (resetOnConstructionMethodeChanged()) {
|
|
handler->reset(); // reset of handler to restart.
|
|
}
|
|
|
|
handler->mouseMove(prevCursorPosition);
|
|
}
|
|
//@}
|
|
|
|
/** function that define if the handler should be reset on construction methode change */
|
|
virtual bool resetOnConstructionMethodeChanged()
|
|
{
|
|
return true;
|
|
}
|
|
//@}
|
|
|
|
/** @name functions NOT intended for specialisation offering specialisation interface for
|
|
* extension */
|
|
/** These functions offer a specialisation interface to ensure the order on initialisation. It
|
|
* is heavily encouraged to extend functionality using the specialisation interface (by
|
|
* specialising the NVI functions).
|
|
*/
|
|
//@{
|
|
|
|
/** slot triggering when a on view parameter has changed
|
|
* It is intended to remote control the DrawSketchDefaultWidgetHandler
|
|
*/
|
|
void onViewValueChanged(int onviewparameterindex, double value)
|
|
{
|
|
int nextindex = onviewparameterindex + 1;
|
|
if (isOnViewParameterOfCurrentMode(nextindex)) {
|
|
setFocusToOnViewParameter(nextindex);
|
|
}
|
|
|
|
/* That is not supported with on-view parameters.
|
|
// -> 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
|
|
// doChangeDrawSketchHandlerMode). This ensures that the geometry has been defined
|
|
// (either by mouse clicking or by widget). Autoconstraints on point should be picked
|
|
// when the state is reached upon machine state advancement.
|
|
//
|
|
// -> 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 (isOnViewParameterOfPreviousMode(onviewparameterindex)) {
|
|
// change to previous state
|
|
handler->setState(getState(onviewparameterindex));
|
|
}*/
|
|
|
|
adaptDrawingToOnViewParameterChange(onviewparameterindex,
|
|
value); // specialisation interface
|
|
|
|
finishControlsChanged();
|
|
}
|
|
|
|
void adaptParameters()
|
|
{
|
|
adaptParameters(lastControlEnforcedPosition); // specialisation interface
|
|
}
|
|
//@}
|
|
|
|
/** @name Specialisation Interface */
|
|
/** These functions offer a specialisation interface. Non-virtual functions are specific to
|
|
* this controller. Virtual functions may depend on input from a derived controller, and thus
|
|
* the specialisation needs to be of an overridden version (so as to be able to access members
|
|
* of the derived controller).
|
|
*/
|
|
//@{
|
|
/// Change DSH to reflect a value entered in the view
|
|
void adaptDrawingToOnViewParameterChange(int onviewparameterindex, double value)
|
|
{
|
|
Q_UNUSED(onviewparameterindex);
|
|
Q_UNUSED(value);
|
|
}
|
|
|
|
/** Returns the state to which the on-view parameter corresponds in the current construction
|
|
* method. */
|
|
auto getState(int parameterindex) const
|
|
{
|
|
Q_UNUSED(parameterindex);
|
|
return handler->getFirstState();
|
|
}
|
|
|
|
/// function to create constraints based on control information.
|
|
virtual void addConstraints()
|
|
{}
|
|
|
|
/// Configures on-view parameters
|
|
void configureOnViewParameters()
|
|
{}
|
|
|
|
/** Change DSH to reflect the SelectMode it should be in based on values entered in the
|
|
* controls
|
|
*/
|
|
virtual void doChangeDrawSketchHandlerMode()
|
|
{}
|
|
|
|
/** function that is called by the handler when the selection mode changed */
|
|
void onHandlerModeChanged()
|
|
{
|
|
setModeOnViewParameters();
|
|
}
|
|
|
|
/** function that is called by the handler with a Vector2d position to update the widget
|
|
*
|
|
* It MUST be specialised if you want the parameters to update on mouseMove
|
|
*/
|
|
virtual void adaptParameters(Base::Vector2d onSketchPos)
|
|
{
|
|
Q_UNUSED(onSketchPos)
|
|
}
|
|
|
|
/** function that is called by the handler with a mouse position, enabling the
|
|
* widget to override it having regard to the widget information.
|
|
*
|
|
* It MUST be specialised if you want to override mouse position based on parameters.
|
|
*/
|
|
void doEnforceControlParameters(Base::Vector2d& onSketchPos)
|
|
{
|
|
Q_UNUSED(onSketchPos)
|
|
}
|
|
|
|
/** on first shortcut, it toggles the first checkbox if there is go. Must be specialised if
|
|
* this is not intended */
|
|
virtual void firstKeyShortcut()
|
|
{}
|
|
|
|
virtual void secondKeyShortcut()
|
|
{}
|
|
|
|
virtual void thirdKeyShortcut()
|
|
{}
|
|
|
|
virtual void fourthKeyShortcut()
|
|
{}
|
|
|
|
virtual void tabShortcut()
|
|
{
|
|
passFocusToNextOnViewParameter();
|
|
}
|
|
//@}
|
|
|
|
|
|
/// triggered by the controllable DSH after a mode change has been effected
|
|
virtual void afterHandlerModeChanged()
|
|
{
|
|
if (handler && (!handler->isState(SelectModeT::End) || handler->continuousMode)) {
|
|
handler->mouseMove(prevCursorPosition);
|
|
}
|
|
}
|
|
|
|
void drawPositionAtCursor(const Base::Vector2d& position)
|
|
{
|
|
if (shouldDrawPositionAtCursor()) {
|
|
handler->drawPositionAtCursor(position);
|
|
}
|
|
}
|
|
|
|
void drawDirectionAtCursor(const Base::Vector2d& position, const Base::Vector2d& origin)
|
|
{
|
|
if (shouldDrawDimensionsAtCursor()) {
|
|
handler->drawDirectionAtCursor(position, origin);
|
|
}
|
|
}
|
|
|
|
void
|
|
drawWidthHeightAtCursor(const Base::Vector2d& position, const double val1, const double val2)
|
|
{
|
|
if (shouldDrawDimensionsAtCursor()) {
|
|
handler->drawWidthHeightAtCursor(position, val1, val2);
|
|
}
|
|
}
|
|
|
|
void drawDoubleAtCursor(const Base::Vector2d& position,
|
|
const double radius,
|
|
Base::Unit unit = Base::Unit::Length)
|
|
{
|
|
if (shouldDrawDimensionsAtCursor()) {
|
|
handler->drawDoubleAtCursor(position, radius, unit);
|
|
}
|
|
}
|
|
|
|
protected:
|
|
/** @name NVI for extension of controller functionality in derived classes */
|
|
//@{
|
|
virtual void doInitControls(QWidget* widget)
|
|
{
|
|
Q_UNUSED(widget)
|
|
}
|
|
|
|
virtual void doResetControls()
|
|
{
|
|
resetOnViewParameters();
|
|
}
|
|
virtual void onMouseMoved(Base::Vector2d originalSketchPosition)
|
|
{
|
|
Q_UNUSED(originalSketchPosition)
|
|
|
|
if (!firstMoveInit) {
|
|
setModeOnViewParameters();
|
|
}
|
|
}
|
|
|
|
virtual void afterEnforceControlParameters()
|
|
{
|
|
// Give focus to current on-view parameter. In case user interacted outside of 3dview.
|
|
if (focusAutoPassing && parameterWithFocus >= 0) {
|
|
setFocusToOnViewParameter(parameterWithFocus);
|
|
}
|
|
}
|
|
|
|
virtual void doConstructionMethodChanged()
|
|
{}
|
|
//@}
|
|
|
|
protected:
|
|
/** @name helper functions */
|
|
//@{
|
|
/// function to assist in adaptDrawingToComboboxChange specialisation
|
|
/// assigns the modevalue to the modeenum
|
|
/// it also triggers an update of the cursor
|
|
template<typename T>
|
|
void setMode(T& modeenum, int modevalue)
|
|
{
|
|
auto mode = static_cast<T>(modevalue);
|
|
|
|
modeenum = mode;
|
|
|
|
handler->updateCursor();
|
|
|
|
handler->resetControls(); // resetControls of handler to restart.
|
|
}
|
|
|
|
/// function to redraw before and after any eventual mode change in reaction to a control
|
|
/// change
|
|
void finishControlsChanged()
|
|
{
|
|
handler->mouseMove(prevCursorPosition);
|
|
|
|
auto currentstate = handler->state();
|
|
// ensure that object at point is preselected, so that autoconstraints are generated
|
|
handler->preselectAtPoint(lastControlEnforcedPosition);
|
|
|
|
doChangeDrawSketchHandlerMode();
|
|
|
|
// if the state changed and is not the last state (End). And is init (ie tool has not
|
|
// reset)
|
|
if (!handler->isLastState() && handler->state() != currentstate && firstMoveInit) {
|
|
// mode has changed, so reprocess the previous position to the new widget state
|
|
handler->mouseMove(prevCursorPosition);
|
|
}
|
|
}
|
|
|
|
/** @brief Initialises on-screen parameters */
|
|
void initNOnViewParameters(int n)
|
|
{
|
|
Gui::View3DInventorViewer* viewer = handler->getViewer();
|
|
Base::Placement placement = handler->sketchgui->getSketchObject()->globalPlacement();
|
|
|
|
onViewParameters.clear();
|
|
|
|
for (int i = 0; i < n; i++) {
|
|
|
|
// the returned is a naked pointer
|
|
auto parameter = onViewParameters
|
|
.emplace_back(std::make_unique<Gui::EditableDatumLabel>(
|
|
viewer,
|
|
placement,
|
|
colorManager.dimConstrDeactivatedColor,
|
|
/*autoDistance = */ true,
|
|
/*avoidMouseCursor = */ true))
|
|
.get();
|
|
|
|
QObject::connect(parameter,
|
|
&Gui::EditableDatumLabel::valueChanged,
|
|
[this, parameter, i](double value) {
|
|
parameter->setColor(colorManager.dimConstrColor);
|
|
onViewValueChanged(i, value);
|
|
});
|
|
}
|
|
}
|
|
|
|
/// Allows a on-view parameter to take any mouse mandated value (as opposed to enforce one)
|
|
void unsetOnViewParameter(Gui::EditableDatumLabel* onViewParameter)
|
|
{
|
|
onViewParameter->isSet = false;
|
|
onViewParameter->setColor(colorManager.dimConstrDeactivatedColor);
|
|
}
|
|
|
|
void setOnViewParameterValue(OnViewParameter index,
|
|
double val,
|
|
const Base::Unit& unit = Base::Unit::Length)
|
|
{
|
|
bool visible = isOnViewParameterVisible(index);
|
|
|
|
if (visible) {
|
|
onViewParameters[index]->setSpinboxValue(val, unit);
|
|
}
|
|
}
|
|
|
|
/** Activates the correct set of on-view parameters corresponding to current
|
|
* mode. It may be specialized if necessary.*/
|
|
void setModeOnViewParameters()
|
|
{
|
|
// before each mode change we reset the dynamic override
|
|
ovpVisibilityManager.resetDynamicOverride();
|
|
|
|
bool firstOfMode = true;
|
|
parameterWithFocus = -1;
|
|
|
|
for (size_t i = 0; i < onViewParameters.size(); i++) {
|
|
|
|
if (!isOnViewParameterOfCurrentMode(i)) {
|
|
onViewParameters[i]->stopEdit();
|
|
if (!onViewParameters[i]->isSet || handler->state() == SelectMode::End) {
|
|
onViewParameters[i]->deactivate();
|
|
}
|
|
}
|
|
else {
|
|
|
|
if (firstOfMode) {
|
|
parameterWithFocus = static_cast<int>(i);
|
|
firstOfMode = false;
|
|
}
|
|
|
|
bool visible = isOnViewParameterVisible(i);
|
|
|
|
if (visible) {
|
|
onViewParameters[i]->activate();
|
|
|
|
// points/value will be overridden by the mouseMove triggered by the mode
|
|
// change.
|
|
onViewParameters[i]->setPoints(Base::Vector3d(), Base::Vector3d());
|
|
onViewParameters[i]->startEdit(0.0, keymanager.get());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// This function gives the focus to a spinbox and tracks the focus.
|
|
bool setFocusToOnViewParameter(unsigned int onviewparameterindex)
|
|
{
|
|
if (onviewparameterindex < onViewParameters.size()) {
|
|
|
|
bool visible = isOnViewParameterVisible(onviewparameterindex);
|
|
|
|
if (visible) {
|
|
onViewParameters[onviewparameterindex]->setFocusToSpinbox();
|
|
parameterWithFocus = static_cast<int>(onviewparameterindex);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/// Switches focus to the next parameter in the current state machine.
|
|
void passFocusToNextOnViewParameter()
|
|
{
|
|
unsigned int index = parameterWithFocus + 1;
|
|
|
|
if (index >= onViewParameters.size()) {
|
|
index = 0;
|
|
}
|
|
|
|
auto trySetFocus = [this](unsigned int& idx) -> bool {
|
|
while (idx < onViewParameters.size()) {
|
|
if (isOnViewParameterOfCurrentMode(idx) && isOnViewParameterVisible(idx)) {
|
|
setFocusToOnViewParameter(idx);
|
|
return true;
|
|
}
|
|
idx++;
|
|
}
|
|
return false;
|
|
};
|
|
|
|
if (!trySetFocus(index)) {
|
|
// We have not found a parameter in this mode after current.
|
|
// So we go back to start and retry.
|
|
index = 0;
|
|
trySetFocus(index);
|
|
}
|
|
|
|
// At that point if no onViewParameter is found, there is none.
|
|
}
|
|
|
|
/** Returns whether the provided on-view parameter index belongs to the current state of the
|
|
* state machine */
|
|
bool isOnViewParameterOfCurrentMode(unsigned int onviewparameterindex) const
|
|
{
|
|
return onviewparameterindex < onViewParameters.size()
|
|
&& getState(onviewparameterindex) == handler->state();
|
|
}
|
|
|
|
/** Returns whether the provided on-view parameter index belongs to the previous state of the
|
|
* state machine */
|
|
bool isOnViewParameterOfPreviousMode(unsigned int onviewparameterindex) const
|
|
{
|
|
return onviewparameterindex < onViewParameters.size()
|
|
&& getState(onviewparameterindex) < handler->state();
|
|
}
|
|
|
|
bool isOnViewParameterVisible(unsigned int onviewparameterindex)
|
|
{
|
|
return ovpVisibilityManager.isVisible(onViewParameters[onviewparameterindex].get());
|
|
}
|
|
|
|
/** Resets the on-view parameter controls */
|
|
void resetOnViewParameters()
|
|
{
|
|
nOnViewParameter = OnViewParametersT::size(handler->constructionMethod());
|
|
initNOnViewParameters(nOnViewParameter);
|
|
parameterWithFocus = 0;
|
|
|
|
configureOnViewParameters();
|
|
}
|
|
//@}
|
|
|
|
// makes keymanager available to derived classes so that they install it as event handler
|
|
// where necessary, without allowing them to manage resource ownership
|
|
DrawSketchKeyboardManager* getKeyManager()
|
|
{
|
|
return keymanager.get();
|
|
}
|
|
|
|
bool focusAutoPassing = true;
|
|
|
|
private:
|
|
/** @name helper functions */
|
|
//@{
|
|
bool shouldDrawPositionAtCursor() const
|
|
{
|
|
return !(ovpVisibilityManager.isVisibility(
|
|
OnViewParameterVisibilityManager::OnViewParameterVisibility::ShowAll));
|
|
}
|
|
|
|
bool shouldDrawDimensionsAtCursor() const
|
|
{
|
|
return (ovpVisibilityManager.isVisibility(
|
|
OnViewParameterVisibilityManager::OnViewParameterVisibility::Hidden));
|
|
}
|
|
//@}
|
|
|
|
private:
|
|
OnViewParameterVisibilityManager ovpVisibilityManager;
|
|
ColorManager colorManager;
|
|
std::unique_ptr<DrawSketchKeyboardManager> keymanager;
|
|
|
|
bool firstMoveInit = false; // true if first mouse movement not yet performed (resets)
|
|
};
|
|
|
|
|
|
} // namespace SketcherGui
|
|
|
|
|
|
#endif // SKETCHERGUI_DrawSketchController_H
|