From b1e70ec64cc05da5a1cd32f49f3145c4091f625c Mon Sep 17 00:00:00 2001 From: Thomas Kroes Date: Wed, 20 Nov 2024 11:49:07 +0100 Subject: [PATCH] Tix toggle action drag and drop (#723) * Refactor Move action drag behavior to specific WidgetActionDrag class Remove virtual + final from WidgetAction class Override WidgetAction destructor * Check for dragging inside the ToggleAction and some housekeeping --- ManiVault/cmake/CMakeMvSourcesPublic.cmake | 2 + ManiVault/src/actions/ToggleAction.cpp | 8 +- ManiVault/src/actions/WidgetAction.cpp | 35 +--- ManiVault/src/actions/WidgetAction.h | 168 +++++++++--------- .../src/actions/WidgetActionContextMenu.cpp | 2 +- ManiVault/src/actions/WidgetActionDrag.cpp | 60 +++++++ ManiVault/src/actions/WidgetActionDrag.h | 64 +++++++ ManiVault/src/actions/WidgetActionLabel.cpp | 10 +- .../src/actions/WidgetActionMimeData.cpp | 4 +- 9 files changed, 233 insertions(+), 120 deletions(-) create mode 100644 ManiVault/src/actions/WidgetActionDrag.cpp create mode 100644 ManiVault/src/actions/WidgetActionDrag.h diff --git a/ManiVault/cmake/CMakeMvSourcesPublic.cmake b/ManiVault/cmake/CMakeMvSourcesPublic.cmake index e5b7c4c6e..af43a1813 100644 --- a/ManiVault/cmake/CMakeMvSourcesPublic.cmake +++ b/ManiVault/cmake/CMakeMvSourcesPublic.cmake @@ -324,6 +324,7 @@ set(PUBLIC_ACTIONS_INTERNAL_HEADERS src/actions/WidgetActionMimeData.h src/actions/WidgetActionHighlightWidget.h src/actions/WidgetActionBadge.h + src/actions/WidgetActionDrag.h src/actions/TasksTreeAction.h src/actions/TasksListAction.h src/actions/SplashScreenAction.h @@ -356,6 +357,7 @@ set(PUBLIC_ACTIONS_INTERNAL_SOURCES src/actions/WidgetActionMimeData.cpp src/actions/WidgetActionHighlightWidget.cpp src/actions/WidgetActionBadge.cpp + src/actions/WidgetActionDrag.cpp src/actions/TasksTreeAction.cpp src/actions/TasksListAction.cpp src/actions/SplashScreenAction.cpp diff --git a/ManiVault/src/actions/ToggleAction.cpp b/ManiVault/src/actions/ToggleAction.cpp index 05dbbd73d..e38db50f6 100644 --- a/ManiVault/src/actions/ToggleAction.cpp +++ b/ManiVault/src/actions/ToggleAction.cpp @@ -171,10 +171,14 @@ bool ToggleAction::CheckBoxWidget::eventFilter(QObject* target, QEvent* event) { case QEvent::MouseButtonPress: { - auto mouseEvent = static_cast(event); + auto mouseEvent = dynamic_cast(event); - if (_toggleAction->isEnabled() && mouseEvent->button() == Qt::LeftButton) + if (_toggleAction->isEnabled() && mouseEvent->button() == Qt::LeftButton && !_toggleAction->getDrag().isDragging()) + { + qDebug() << "Toggle!"; _toggleAction->setChecked(!_toggleAction->isChecked()); + } + return true; } diff --git a/ManiVault/src/actions/WidgetAction.cpp b/ManiVault/src/actions/WidgetAction.cpp index a521ef1df..dbee68574 100644 --- a/ManiVault/src/actions/WidgetAction.cpp +++ b/ManiVault/src/actions/WidgetAction.cpp @@ -17,9 +17,7 @@ #include #include #include -#include #include -#include #ifdef _DEBUG //#define WIDGET_ACTION_VERBOSE @@ -34,13 +32,12 @@ bool isInPopupMode(QWidget* parent) { } QMap WidgetAction::scopeNames { - { WidgetAction::Scope::Private, "Private" }, - { WidgetAction::Scope::Public, "Public" } + { Scope::Private, "Private" }, + { Scope::Public, "Public" } }; WidgetAction::WidgetAction(QObject* parent, const QString& title) : QWidgetAction(parent), - util::Serializable(), _defaultWidgetFlags(), _sortIndex(-1), _stretch(-1), @@ -50,16 +47,11 @@ WidgetAction::WidgetAction(QObject* parent, const QString& title) : _cachedConnectionPermissions(static_cast(ConnectionPermissionFlag::None)), _scope(Scope::Private), _publicAction(nullptr), - _connectedActions(), - _settingsPrefix(), _highlighting(HighlightOption::None), - _popupSizeHint(), - _overrideSizeHint(), _configuration(static_cast(ConfigurationFlag::Default)), - _location(), _namedIcon(""), - _widgetConfigurationFunction(), - _badge(this) + _badge(this), + _drag(this) { Q_ASSERT(!title.isEmpty()); @@ -581,20 +573,6 @@ void WidgetAction::restoreConnectionPermissions(bool recursive /*= false*/) childAction->restoreConnectionPermissions(recursive); } -void WidgetAction::startDrag() -{ - if (!mayConnect(WidgetAction::Gui)) - return; - - auto drag = new QDrag(this); - auto mimeData = new WidgetActionMimeData(this); - - drag->setMimeData(mimeData); - drag->setPixmap(Application::getIconFont("FontAwesome").getIcon("link").pixmap(QSize(12, 12))); - - drag->exec(); -} - void WidgetAction::setSettingsPrefix(const QString& settingsPrefix, const bool& load /*= true*/) { _settingsPrefix = settingsPrefix; @@ -964,6 +942,11 @@ WidgetActionBadge& WidgetAction::getBadge() return _badge; } +WidgetActionDrag& WidgetAction::getDrag() +{ + return _drag; +} + void WidgetAction::setOverrideSizeHint(const QSize& sizeHint) { _overrideSizeHint = sizeHint; diff --git a/ManiVault/src/actions/WidgetAction.h b/ManiVault/src/actions/WidgetAction.h index 9a7b05366..4b2844b55 100644 --- a/ManiVault/src/actions/WidgetAction.h +++ b/ManiVault/src/actions/WidgetAction.h @@ -6,6 +6,7 @@ #include "WidgetActionWidget.h" #include "WidgetActionBadge.h" +#include "WidgetActionDrag.h" #include "util/Serializable.h" @@ -121,7 +122,7 @@ class CORE_EXPORT WidgetAction : public QWidgetAction, public util::Serializable WidgetAction(QObject* parent, const QString& title); /** Destructor */ - ~WidgetAction(); + ~WidgetAction() override; public: // Hierarchy queries @@ -288,7 +289,7 @@ class CORE_EXPORT WidgetAction : public QWidgetAction, public util::Serializable * Compute the location of the action and update the cached location if it changed * @param recursive Whether to also update child actions recursively */ - virtual void updateLocation(bool recursive = true) final; + void updateLocation(bool recursive = true); public: @@ -317,13 +318,13 @@ class CORE_EXPORT WidgetAction : public QWidgetAction, public util::Serializable * Establish whether this action is positioned at the top of the hierarchy * @return Boolean determining whether this action is positioned at the top of the hierarchy */ - virtual bool isRoot() const final; + bool isRoot() const; /** * Establish whether this action is positioned at the bottom of the hierarchy * @return Boolean determining whether this action is positioned at the bottom of the hierarchy */ - virtual bool isLeaf() const final; + bool isLeaf() const; public: // Widgets @@ -332,7 +333,7 @@ class CORE_EXPORT WidgetAction : public QWidgetAction, public util::Serializable * @param parent Parent widget * @return Pointer to created widget */ - virtual QWidget* createWidget(QWidget* parent) override final; + QWidget* createWidget(QWidget* parent) override final; /** * Create widget with pointer to \p parent widget and \p widgetFlags @@ -340,7 +341,7 @@ class CORE_EXPORT WidgetAction : public QWidgetAction, public util::Serializable * @param widgetFlags Widget flags * @return Pointer to created widget */ - virtual QWidget* createWidget(QWidget* parent, const std::int32_t& widgetFlags) final; + QWidget* createWidget(QWidget* parent, const std::int32_t& widgetFlags); /** * Create widget with pointer to \p parent widget, \p widgetFlags and \p widgetConfigurationFunction @@ -349,7 +350,7 @@ class CORE_EXPORT WidgetAction : public QWidgetAction, public util::Serializable * @param widgetConfigurationFunction Configuration function to run after the widget is created (overrides WidgetAction#_widgetConfigurationFunction) * @return Pointer to created widget */ - virtual QWidget* createWidget(QWidget* parent, const std::int32_t& widgetFlags, const WidgetConfigurationFunction& widgetConfigurationFunction) final; + QWidget* createWidget(QWidget* parent, const std::int32_t& widgetFlags, const WidgetConfigurationFunction& widgetConfigurationFunction); /** * Create widget with pointer to \p parent widget and \p widgetConfigurationFunction @@ -357,7 +358,7 @@ class CORE_EXPORT WidgetAction : public QWidgetAction, public util::Serializable * @param widgetConfigurationFunction Configuration function to run after the widget is created (overrides WidgetAction#_widgetConfigurationFunction) * @return Pointer to created widget */ - virtual QWidget* createWidget(QWidget* parent, const WidgetConfigurationFunction& widgetConfigurationFunction) final; + QWidget* createWidget(QWidget* parent, const WidgetConfigurationFunction& widgetConfigurationFunction); /** * Create collapsed widget @@ -366,7 +367,7 @@ class CORE_EXPORT WidgetAction : public QWidgetAction, public util::Serializable * @param widgetConfigurationFunction Configuration function to run after the widget is created (overrides WidgetAction#_widgetConfigurationFunction) * @return Pointer to collapsed widget */ - virtual QWidget* createCollapsedWidget(QWidget* parent, std::int32_t widgetFlags = 0) const final; + QWidget* createCollapsedWidget(QWidget* parent, std::int32_t widgetFlags = 0) const; /** * Create collapsed widget @@ -375,7 +376,7 @@ class CORE_EXPORT WidgetAction : public QWidgetAction, public util::Serializable * @param widgetConfigurationFunction Configuration function to run after the widget is created (overrides WidgetAction#_widgetConfigurationFunction) * @return Pointer to collapsed widget */ - virtual QWidget* createCollapsedWidget(QWidget* parent, std::int32_t widgetFlags, const WidgetConfigurationFunction& widgetConfigurationFunction) const final; + QWidget* createCollapsedWidget(QWidget* parent, std::int32_t widgetFlags, const WidgetConfigurationFunction& widgetConfigurationFunction) const; /** * Create label widget @@ -383,7 +384,7 @@ class CORE_EXPORT WidgetAction : public QWidgetAction, public util::Serializable * @param widgetFlags Label widget configuration flags * @return Pointer to widget */ - virtual QWidget* createLabelWidget(QWidget* parent, const std::int32_t& widgetFlags = 0x00001) const final; + QWidget* createLabelWidget(QWidget* parent, const std::int32_t& widgetFlags = 0x00001) const; /** * Get the context menu for the action @@ -393,25 +394,25 @@ class CORE_EXPORT WidgetAction : public QWidgetAction, public util::Serializable virtual QMenu* getContextMenu(QWidget* parent = nullptr); /** Get the sort index */ - virtual std::int32_t getSortIndex() const final; + std::int32_t getSortIndex() const; /** * Set the sort index * @param sortIndex Sorting index */ - virtual void setSortIndex(const std::int32_t& sortIndex) final; + void setSortIndex(const std::int32_t& sortIndex); /** * Get stretch * @return The stretch factor */ - virtual std::int32_t getStretch() const final; + std::int32_t getStretch() const; /** * Set stretch to \p stretch * @param stretch Stretch factor */ - virtual void setStretch(const std::int32_t& stretch) final; + void setStretch(const std::int32_t& stretch); /** * Get widget configuration function @@ -438,19 +439,19 @@ class CORE_EXPORT WidgetAction : public QWidgetAction, public util::Serializable * Get force hidden * @return Boolean determining whether the widget action should be forcibly hidden (regardless of the visibility setting in the base QWidgetAction class) */ - virtual bool getForceHidden() const final; + bool getForceHidden() const; /** * Set force hidden to \p forceHidden * @param forceHidden Boolean determining whether the widget action should be forcibly hidden (regardless of the enabled visibility in the base QWidgetAction class) */ - virtual void setForceHidden(bool forceHidden) final; + void setForceHidden(bool forceHidden); /** * Re-implement the isVisible() getter from the base QWidgetAction class to support the force hidden functionality * @return Boolean determining whether the widget action is visible or not */ - virtual bool isVisible() const final; + bool isVisible() const; public: // Disabled @@ -458,19 +459,19 @@ class CORE_EXPORT WidgetAction : public QWidgetAction, public util::Serializable * Get force disabled * @return Boolean determining whether the widget action should be forcibly disabled (regardless of the enabled setting in the base QWidgetAction class) */ - virtual bool getForceDisabled() const final; + bool getForceDisabled() const; /** * Set force disabled to \p forceDisabled * @param forceDisabled Boolean determining whether the widget action should be forcibly disabled (regardless of the enabled setting in the base QWidgetAction class) */ - virtual void setForceDisabled(bool forceDisabled) final; + void setForceDisabled(bool forceDisabled); /** * Re-implement the isEnabled() getter from the base QWidgetAction class to support the force disabled functionality * @return Boolean determining whether the widget action is enabled or not */ - virtual bool isEnabled() const final; + bool isEnabled() const; public: // Text @@ -483,20 +484,20 @@ class CORE_EXPORT WidgetAction : public QWidgetAction, public util::Serializable public: // Widget flags /** Gets the default widget flags */ - virtual std::int32_t getDefaultWidgetFlags() const final; + std::int32_t getDefaultWidgetFlags() const; /** * Set the widget flags * @param widgetFlags Widget flags */ - virtual void setDefaultWidgetFlags(const std::int32_t& widgetFlags) final; + void setDefaultWidgetFlags(const std::int32_t& widgetFlags); /** * Set a single widget flag on/off * @param widgetFlag Widget flag to set on/off * @param unset Whether to unset the default widget flag */ - virtual void setDefaultWidgetFlag(const std::int32_t& widgetFlag, bool unset = false) final; + void setDefaultWidgetFlag(const std::int32_t& widgetFlag, bool unset = false); public: // Highlighting @@ -504,31 +505,31 @@ class CORE_EXPORT WidgetAction : public QWidgetAction, public util::Serializable * Get highlighting * @return Highlight option */ - virtual HighlightOption getHighlighting() const final; + HighlightOption getHighlighting() const; /** * Determine whether the action is in a highlighted state or not * @return Boolean determining whether the action is in a highlighted state or not */ - virtual bool isHighlighted() const final; + bool isHighlighted() const; /** * Set highlighting to \p highlighting * @param highlighting Highlighting state */ - virtual void setHighlighting(const HighlightOption& highlighting) final; + void setHighlighting(const HighlightOption& highlighting); /** * Set highlighted to \p highlighted * @param highlighted Boolean determining whether the action is in a normal highlighted state or not */ - virtual void setHighlighted(bool highlighted) final; + void setHighlighted(bool highlighted); /** Convenience method to highlight the action */ - virtual void highlight() final; + void highlight(); /** Convenience method to un-highlight the action */ - virtual void unHighlight() final; + void unHighlight(); public: // Scope @@ -536,19 +537,19 @@ class CORE_EXPORT WidgetAction : public QWidgetAction, public util::Serializable * Get widget action scope * @return Widget action scope enum */ - virtual Scope getScope() const final; + Scope getScope() const; /** * Get whether this action is in the private actions pool * @return Boolean determining whether this action is in the private actions pool */ - virtual bool isPrivate() const final; + bool isPrivate() const; /** * Get whether this action is in the public actions pool * @return Boolean determining whether this action is in the private public pool */ - virtual bool isPublic() const final; + bool isPublic() const; protected: // Connections @@ -556,7 +557,7 @@ class CORE_EXPORT WidgetAction : public QWidgetAction, public util::Serializable * Make widget action public (and possibly all of its descendant widget actions) * @param recursive Whether to also make all descendant widget actions public */ - virtual void makePublic(bool recursive = true) final; + void makePublic(bool recursive = true); public: // Connections and publishing @@ -564,20 +565,20 @@ class CORE_EXPORT WidgetAction : public QWidgetAction, public util::Serializable * Get whether the action is published * @return Boolean indicating whether the action is published */ - virtual bool isPublished() const final; + bool isPublished() const; /** * Get whether the action is connect to a public action * @return Boolean indicating whether the action is connect to a public action */ - virtual bool isConnected() const final; + bool isConnected() const; /** * Get whether the action may connect to \p publicAction * @param publicAction Pointer to public action * @return Boolean determining whether the action may connect to \p publicAction */ - virtual bool mayConnectToPublicAction(const WidgetAction* publicAction) const final; + bool mayConnectToPublicAction(const WidgetAction* publicAction) const; /** * Publish this action so that other actions can connect to it @@ -585,7 +586,7 @@ class CORE_EXPORT WidgetAction : public QWidgetAction, public util::Serializable * @param allowDuplicateName Boolean determining whether publishing will take place when a public with the same name already exists in the public actions database * @return Boolean determining whether the action is successfully published or not */ - virtual bool publish(const QString& name = "", bool allowDuplicateName = false) final; + bool publish(const QString& name = "", bool allowDuplicateName = false); protected: @@ -600,8 +601,7 @@ class CORE_EXPORT WidgetAction : public QWidgetAction, public util::Serializable * Connect this action to a public action * @param publicAction Pointer to public action to connect to */ - [[deprecated("This function will be deprecated in version 1.0 of ManiVault, Please establish connections with the connections GUI instead.")]] - virtual void connectToPublicActionByName(const QString& publicActionName) final; + void connectToPublicActionByName(const QString& publicActionName); /** * Disconnect this action from its public action @@ -615,25 +615,25 @@ class CORE_EXPORT WidgetAction : public QWidgetAction, public util::Serializable * Get the public action to which the action is connected * @return Pointer to the public action (returns nullptr if not connected to a public action) */ - virtual WidgetAction* getPublicAction() final; + WidgetAction* getPublicAction(); /** * Get public copy of the action (other compatible actions can connect to it) * @return Pointer to public copy of the action */ - virtual WidgetAction* getPublicCopy() const final; + WidgetAction* getPublicCopy() const; /** * Get connected actions * @return Vector of pointers to connected actions */ - virtual const WidgetActions getConnectedActions() const final; + const WidgetActions getConnectedActions() const; /** * Get connected actions * @return Vector of pointers to connected actions */ - virtual WidgetActions& getConnectedActions() final; + WidgetActions& getConnectedActions(); public: // Connection permissions @@ -642,34 +642,34 @@ class CORE_EXPORT WidgetAction : public QWidgetAction, public util::Serializable * @param connectionContextFlags The context from which the action will be published (API and/or GUI) * @return Boolean determining whether a copy of this action may published and shared, depending on the \p connectionContextFlags */ - virtual bool mayPublish(ConnectionContextFlag connectionContextFlags) const final; + bool mayPublish(ConnectionContextFlag connectionContextFlags) const; /** * Get whether this action may connect to a public action, depending on the \p connectionContextFlags * @param connectionContextFlags The context from which the connection will be made (API and/or GUI) * @return Boolean determining whether this action may connect to a public action, depending on the \p connectionContextFlags */ - virtual bool mayConnect(ConnectionContextFlag connectionContextFlags) const final; + bool mayConnect(ConnectionContextFlag connectionContextFlags) const; /** * Get whether this action may disconnect from a public action, depending on the \p connectionContextFlags * @param connectionContextFlags The context from which the disconnection will be initiated (API and/or GUI) * @return Boolean determining whether this action may disconnect from a public action, depending on the \p connectionContextFlags */ - virtual bool mayDisconnect(ConnectionContextFlag connectionContextFlags) const final; + bool mayDisconnect(ConnectionContextFlag connectionContextFlags) const; /** * Get connection permission flags * @return Connection permission flags */ - virtual std::int32_t getConnectionPermissions() const final; + std::int32_t getConnectionPermissions() const; /** * Check whether \p connectionPermissionsFlag is set or not * @param connectionPermissionsFlag Connection permissions flag * @return Boolean determining whether \p connectionPermissionsFlag is set or not */ - virtual bool isConnectionPermissionFlagSet(ConnectionPermissionFlag connectionPermissionsFlag) final; + bool isConnectionPermissionFlagSet(ConnectionPermissionFlag connectionPermissionsFlag); /** * Set connection permissions flag @@ -677,49 +677,44 @@ class CORE_EXPORT WidgetAction : public QWidgetAction, public util::Serializable * @param unset Whether to unset the connection permissions flag * @param recursive Whether to recursively set child connection permissions */ - virtual void setConnectionPermissionsFlag(ConnectionPermissionFlag connectionPermissionsFlag, bool unset = false, bool recursive = false) final; + void setConnectionPermissionsFlag(ConnectionPermissionFlag connectionPermissionsFlag, bool unset = false, bool recursive = false); /** * Set connection permissions * @param connectionPermissions Connection permissions value * @param recursive Whether to recursively set child connection permissions */ - virtual void setConnectionPermissions(std::int32_t connectionPermissions, bool recursive = false) final; + void setConnectionPermissions(std::int32_t connectionPermissions, bool recursive = false); /** * Reset connection permissions to none * @param recursive Whether to recursively set child connection permissions */ - virtual void setConnectionPermissionsToNone(bool recursive = false) final; + void setConnectionPermissionsToNone(bool recursive = false); /** * Set connection permissions to force none (connections fully disabled, regardless of other connection permission flags) * @param recursive Whether to recursively set child connection permissions */ - virtual void setConnectionPermissionsToForceNone(bool recursive = false) final; + void setConnectionPermissionsToForceNone(bool recursive = false); /** * Set connection permissions to all * @param recursive Whether to recursively set child connection permissions */ - virtual void setConnectionPermissionsToAll(bool recursive = false) final; + void setConnectionPermissionsToAll(bool recursive = false); /** * Cache connection permissions * @param recursive Whether to recursively cache child connection permissions */ - virtual void cacheConnectionPermissions(bool recursive = false) final; + void cacheConnectionPermissions(bool recursive = false); /** * Restore connection permissions * @param recursive Whether to recursively restore child connection permissions */ - virtual void restoreConnectionPermissions(bool recursive = false) final; - -public: // Drag and drop - - /** Start drag process */ - virtual void startDrag() final; + void restoreConnectionPermissions(bool recursive = false); public: // Settings @@ -728,18 +723,18 @@ class CORE_EXPORT WidgetAction : public QWidgetAction, public util::Serializable * @return Whether the action can be reset to its default */ [[deprecated("This method is a placeholder and not operational yet")]] - virtual bool isResettable() const final; + bool isResettable() const; /** Reset to default */ [[deprecated("This method is a placeholder and not operational yet")]] - virtual void reset() final; + void reset(); /** * Set settings prefix * @param load Whether to restore settings after setting the prefix * @param settingsPrefix Settings prefix */ - virtual void setSettingsPrefix(const QString& settingsPrefix, const bool& load = true) final; + void setSettingsPrefix(const QString& settingsPrefix, const bool& load = true); /** * Set settings prefix in the context of a plugin (the combined settings prefix will be: Plugins/PluginKind/SettingsPrefix) @@ -747,7 +742,7 @@ class CORE_EXPORT WidgetAction : public QWidgetAction, public util::Serializable * @param plugin Pointer to plugin context * @param settingsPrefix Settings prefix */ - virtual void setSettingsPrefix(plugin::Plugin* plugin, const QString& settingsPrefix, const bool& load = true) final; + void setSettingsPrefix(plugin::Plugin* plugin, const QString& settingsPrefix, const bool& load = true); /** * Get settings prefix @@ -756,10 +751,10 @@ class CORE_EXPORT WidgetAction : public QWidgetAction, public util::Serializable virtual QString getSettingsPrefix() const; /** Load from settings (if the settings prefix is set) */ - virtual void loadFromSettings() final; + void loadFromSettings(); /** Save to settings (if the settings prefix is set) */ - virtual void saveToSettings() final; + void saveToSettings(); public: // Popups @@ -767,27 +762,27 @@ class CORE_EXPORT WidgetAction : public QWidgetAction, public util::Serializable * Get size hint of popups (in case of collapsed actions) * @return Popup size hint */ - virtual QSize getPopupSizeHint() const final; + QSize getPopupSizeHint() const; /** * Set size hint of popups (in case of collapsed actions) * @param popupSizeHint Popup size hint */ - virtual void setPopupSizeHint(const QSize& popupSizeHint) final; + void setPopupSizeHint(const QSize& popupSizeHint); /** * Get override size hint * @return Override size hint */ [[deprecated("This method is a placeholder and not operational yet")]] - virtual QSize getOverrideSizeHint() const final; + QSize getOverrideSizeHint() const; /** * Set override size hint * @param overrideSizeHint Override size hint */ [[deprecated("This method is a placeholder and not operational yet")]] - virtual void setOverrideSizeHint(const QSize& overrideSizeHint) final; + void setOverrideSizeHint(const QSize& overrideSizeHint); public: // Configuration flags @@ -795,14 +790,14 @@ class CORE_EXPORT WidgetAction : public QWidgetAction, public util::Serializable * Get configuration * @return Configuration */ - virtual std::int32_t getConfiguration() const final; + std::int32_t getConfiguration() const; /** * Check whether \p configurationFlag is set or not * @param configurationFlag Configuration flag * @return Boolean determining whether \p configurationFlag is set or not */ - virtual bool isConfigurationFlagSet(ConfigurationFlag configurationFlag) const final; + bool isConfigurationFlagSet(ConfigurationFlag configurationFlag) const; /** * Set configuration flag @@ -810,14 +805,14 @@ class CORE_EXPORT WidgetAction : public QWidgetAction, public util::Serializable * @param unset Whether to unset the \p configurationFlag flag * @param recursive Whether to recursively set child child configuration flag */ - virtual void setConfigurationFlag(ConfigurationFlag configurationFlag, bool unset = false, bool recursive = false) final; + void setConfigurationFlag(ConfigurationFlag configurationFlag, bool unset = false, bool recursive = false); /** * Set configuration * @param configuration Configuration value * @param recursive Whether to recursively set child child configuration flag */ - virtual void setConfiguration(std::int32_t configuration, bool recursive = false) final; + void setConfiguration(std::int32_t configuration, bool recursive = false); public: // Type string @@ -826,7 +821,7 @@ class CORE_EXPORT WidgetAction : public QWidgetAction, public util::Serializable * @param humanFriendly Whether to return a type string where the namespace is omitted * @return Widget action type in string format */ - virtual QString getTypeString(bool humanFriendly = false) const final; + QString getTypeString(bool humanFriendly = false) const; protected: // Widgets @@ -857,20 +852,20 @@ class CORE_EXPORT WidgetAction : public QWidgetAction, public util::Serializable * Determine whether cache with name exists * @param name Name to use for the cached widget action state */ - virtual bool hasCacheState(const QString& name) const final; + bool hasCacheState(const QString& name) const; /** * Cache the state of a widget action under \p name in the action itself (for global presets use the presets action) * @param name Name to use for the cached widget action state */ - virtual void cacheState(const QString& name = "cache") final; + void cacheState(const QString& name = "cache"); /** * Restore the state of under \p name * @param name Name of the cached widget action state to restore * @param remove Whether to remove the cache */ - virtual void restoreState(const QString& name = "cache", bool remove = true) final; + void restoreState(const QString& name = "cache", bool remove = true); public: // Studio mode @@ -879,7 +874,7 @@ class CORE_EXPORT WidgetAction : public QWidgetAction, public util::Serializable * @param studioMode Boolean determining whether studio mode is on or off * @param recursive Boolean determining whether to also apply the studio mode to child actions recursively */ - virtual void setStudioMode(bool studioMode, bool recursive = true) final; + void setStudioMode(bool studioMode, bool recursive = true); public: // Font Icon @@ -887,7 +882,7 @@ class CORE_EXPORT WidgetAction : public QWidgetAction, public util::Serializable * Set the icon using a icon font name (i.e., fontawesome) * @param setIcon the name of the icon in fontawesome v5 */ - virtual void setIconByName(QString namedIcon) final; + void setIconByName(QString namedIcon); private: @@ -897,7 +892,7 @@ class CORE_EXPORT WidgetAction : public QWidgetAction, public util::Serializable /** refresh the icon when a icon font is used */ void updateCustomStyle(); -public: // Badge +public: // Badge-related /** * Get badge @@ -905,6 +900,14 @@ class CORE_EXPORT WidgetAction : public QWidgetAction, public util::Serializable */ WidgetActionBadge& getBadge(); +public: // Drag-related + + /** + * Get drag + * @return Reference to the widget action drag + */ + WidgetActionDrag& getDrag(); + signals: /** @@ -1031,6 +1034,7 @@ class CORE_EXPORT WidgetAction : public QWidgetAction, public util::Serializable QString _namedIcon; /** The name of a font awesome icon. When using this the widget can handle icon updates itself, instead of the containing view */ WidgetConfigurationFunction _widgetConfigurationFunction; /** When set, this function is called right after any widget action widget is created (useful for manual manipulation of the generated widget) */ WidgetActionBadge _badge; /** Badge configuration */ + WidgetActionDrag _drag; /** Drag behaviour */ protected: friend class mv::AbstractActionsManager; diff --git a/ManiVault/src/actions/WidgetActionContextMenu.cpp b/ManiVault/src/actions/WidgetActionContextMenu.cpp index 5294fccc0..d1046d7d1 100644 --- a/ManiVault/src/actions/WidgetActionContextMenu.cpp +++ b/ManiVault/src/actions/WidgetActionContextMenu.cpp @@ -205,7 +205,7 @@ WidgetActionContextMenu::WidgetActionContextMenu(QWidget* parent, WidgetActions if (_actions.isEmpty()) return; - _actions.first()->startDrag(); + _actions.first()->getDrag().start(); }); connect(&_disconnectAction, &TriggerAction::triggered, this, [this]() -> void { diff --git a/ManiVault/src/actions/WidgetActionDrag.cpp b/ManiVault/src/actions/WidgetActionDrag.cpp new file mode 100644 index 000000000..adf11829e --- /dev/null +++ b/ManiVault/src/actions/WidgetActionDrag.cpp @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later +// A corresponding LICENSE file is located in the root directory of this source tree +// Copyright (C) 2023 BioVault (Biomedical Visual Analytics Unit LUMC - TU Delft) + +#include "WidgetActionDrag.h" +#include "WidgetActionMimeData.h" + +#include "Application.h" + +#include +#include + +using namespace mv::util; + +namespace mv::gui { + +WidgetActionDrag::WidgetActionDrag(WidgetAction* dragAction) : + QObject(dragAction), + _dragAction(dragAction), + _isDragging(false) +{ + Q_ASSERT(_dragAction); +} + +bool WidgetActionDrag::isDragging() const +{ + return _isDragging; +} + +void WidgetActionDrag::start() +{ + Q_ASSERT(_dragAction); + + if (!_dragAction) + return; + + setIsDragging(true); + { + auto drag = new QDrag(this); + auto mimeData = new WidgetActionMimeData(_dragAction); + + drag->setMimeData(mimeData); + drag->setPixmap(Application::getIconFont("FontAwesome").getIcon("link").pixmap(QSize(12, 12))); + + drag->exec(); + } + QTimer::singleShot(100, [this]() { setIsDragging(false); }); +} + +void WidgetActionDrag::setIsDragging(bool dragging) +{ + if (dragging == _isDragging) + return; + + _isDragging = dragging; + + emit isDraggingChanged(_isDragging); +} + +} diff --git a/ManiVault/src/actions/WidgetActionDrag.h b/ManiVault/src/actions/WidgetActionDrag.h new file mode 100644 index 000000000..592a403fc --- /dev/null +++ b/ManiVault/src/actions/WidgetActionDrag.h @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later +// A corresponding LICENSE file is located in the root directory of this source tree +// Copyright (C) 2023 BioVault (Biomedical Visual Analytics Unit LUMC - TU Delft) + +#pragma once + +#include + +namespace mv::gui { + +class WidgetAction; + +/** + * Widget action drag class + * + * Implements dragging behaviour for WidgetAction derived classes. + * + * Note: This action is developed for internal use only + * + * @author Thomas Kroes + */ +class CORE_EXPORT WidgetActionDrag final : public QObject +{ + Q_OBJECT + +public: + + /** + * Construct with pointer to \p dragAction + * @param dragAction Pointer to drag action + */ + WidgetActionDrag(WidgetAction* dragAction); + + /** + * Get whether dragging is taking place + * @return Boolean determining whether dragging is taking place + */ + bool isDragging() const; + + /** Start the dragging process */ + void start(); + +private: + + /** + * Set dragging to \p dragging + * @param dragging Boolean determining if the action is being dragge + */ + void setIsDragging(bool dragging); + +signals: + + /** + * Signals that the dragging state changed to \p isDragging + * @param isDragging Boolean determining if the action is being dragged + */ + void isDraggingChanged(bool isDragging); + +private: + WidgetAction* _dragAction; /** Pointer to drag action */ + bool _isDragging; /** Boolean determining whether this action is being dragged to connect to another action */ +}; + +} \ No newline at end of file diff --git a/ManiVault/src/actions/WidgetActionLabel.cpp b/ManiVault/src/actions/WidgetActionLabel.cpp index d03a07bfe..a86d48e3b 100644 --- a/ManiVault/src/actions/WidgetActionLabel.cpp +++ b/ManiVault/src/actions/WidgetActionLabel.cpp @@ -19,10 +19,8 @@ namespace mv::gui { WidgetActionLabel::WidgetActionLabel(WidgetAction* action, QWidget* parent /*= nullptr*/, const std::uint32_t& flags /*= ColonAfterName*/) : WidgetActionViewWidget(parent, action), _flags(flags), - _nameLabel(), _elide(false), - _drag(nullptr), - _lastMousePressPosition() + _drag(nullptr) { setAction(action); setAcceptDrops(true); @@ -63,7 +61,7 @@ bool WidgetActionLabel::eventFilter(QObject* target, QEvent* event) if (dynamic_cast(target) != &_nameLabel) break; - auto mouseEvent = static_cast(event); + auto mouseEvent = dynamic_cast(event); switch (mouseEvent->button()) { @@ -75,7 +73,7 @@ bool WidgetActionLabel::eventFilter(QObject* target, QEvent* event) if (!getAction()->mayConnect(WidgetAction::Gui)) break; - getAction()->startDrag(); + getAction()->getDrag().start(); break; } @@ -99,7 +97,7 @@ bool WidgetActionLabel::eventFilter(QObject* target, QEvent* event) if (contextMenu->actions().isEmpty()) return QWidget::eventFilter(target, event); - contextMenu->exec(cursor().pos()); + contextMenu->exec(QCursor::pos()); break; } diff --git a/ManiVault/src/actions/WidgetActionMimeData.cpp b/ManiVault/src/actions/WidgetActionMimeData.cpp index 2c2bc3993..50a700104 100644 --- a/ManiVault/src/actions/WidgetActionMimeData.cpp +++ b/ManiVault/src/actions/WidgetActionMimeData.cpp @@ -7,9 +7,7 @@ namespace mv::gui { WidgetActionMimeData::WidgetActionMimeData(WidgetAction* action) : - QMimeData(), - _action(action), - _highlightActions() + _action(action) { ActionsListModel actionsListModel; /** Actions list model */ ActionsFilterModel actionsFilterModel; /** Filtered actions model */