This commit is contained in:
2021-10-14 13:47:35 +02:00
commit 6625a8dfaa
4026 changed files with 844291 additions and 0 deletions
@@ -0,0 +1,35 @@
project(openvibe-visualization-toolkit)
MESSAGE(STATUS "Now building ${PROJECT_NAME} ${PROJECT_VERSION} (${OV_PROJECT_BRANCH}~${OV_PROJECT_COMMITHASH})" )
OV_ADD_THIS_TO_PROJECT_LIST()
file(GLOB_RECURSE SRC_FILES src/*.cpp src/*.h src/*.hpp include/*.h include/*.hpp)
include("FindSourceRCProperties")
include_directories(${openvibe-visualization-toolkit_SOURCE_DIR}/include/)
include_directories(${openvibe-visualization-toolkit_SOURCE_DIR}/include/visualization-toolkit)
add_library(${PROJECT_NAME} SHARED ${SRC_FILES})
set_target_properties(${PROJECT_NAME} PROPERTIES
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}
COMPILE_FLAGS "-DOVVIZ_Exports -DOVVIZ_Shared")
include("AddOpenViBESDKComponents")
include("FindThirdPartyGTK")
# ---------------------------------
# Target macros
# Defines target operating system, architecture and compiler
# ---------------------------------
SET_BUILD_PLATFORM()
# -----------------------------
# Install files
# -----------------------------
install(TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION ${DIST_BINDIR}
LIBRARY DESTINATION ${DIST_LIBDIR}
ARCHIVE DESTINATION ${DIST_LIBDIR})
install(DIRECTORY include/ DESTINATION ${DIST_INCLUDEDIR} FILES_MATCHING PATTERN "*.h")
@@ -0,0 +1,13 @@
#pragma once
#include "ovviz_base.h"
namespace OpenViBE {
namespace VisualizationToolkit {
namespace ColorGradient {
OVVIZ_API bool parse(CMatrix& colorGradient, const CString& string);
OVVIZ_API bool format(CString& string, const CMatrix& colorGradient);
OVVIZ_API bool interpolate(CMatrix& interpolatedColorGradient, const CMatrix& colorGradient, size_t steps);
} // namespace ColorGradient
} // namespace VisualizationToolkit
} // namespace OpenViBE
@@ -0,0 +1,45 @@
#pragma once
#include <openvibe/plugins/ovIPluginObject.h>
#include <toolkit/ovtk_all.h>
#include <gtk/gtk.h>
#include "ovvizIVisualizationManager.h"
#define OV_ClassId_VisualizationCtx OpenViBE::CIdentifier(0xE06B92EF, 0xB6B68081)
namespace OpenViBE {
namespace VisualizationToolkit {
class IVisualizationContext : public Plugins::IPluginObject
{
public:
/**
* @brief Assing a visualization manager to the visualization context singleton
* @param visualizationManager The visualization manager that handles visualization widgets for the application
* @retval true In case of success.
* @retval false In case of error.
*/
virtual bool setManager(IVisualizationManager* visualizationManager) = 0;
/**
* @brief Forward a GtkWidget which displays content to the visualization manager
* @param box The current box.
* @param widget The Gtk widget used to display the content.
* @retval true In case of success.
* @retval false In case of error.
*/
virtual bool setWidget(Toolkit::TBoxAlgorithm<Plugins::IBoxAlgorithm>& box, GtkWidget* widget) = 0;
/**
* @brief Forward a GtkWidget which displays the box toolbar to the visualization manager
* @param box The current box.
* @param toolbarWidget The Gtk widget used to display the controls of the visualization.
* @retval true In case of success.
* @retval false In case of error.
*/
virtual bool setToolbar(Toolkit::TBoxAlgorithm<Plugins::IBoxAlgorithm>& box, GtkWidget* toolbarWidget) = 0;
_IsDerivedFromClass_(Plugins::IPluginObject, OV_ClassId_VisualizationCtx)
};
} // namespace VisualizationToolkit
} // namespace OpenViBE
@@ -0,0 +1,83 @@
#pragma once
#include "ovvizIVisualizationTree.h"
#include <openvibe/ov_all.h>
typedef struct _GtkWidget GtkWidget;
namespace OpenViBE {
namespace VisualizationToolkit {
/**
* \class IVisualizationManager
* \author Vincent Delannoy (INRIA/IRISA)
* \date 2007-11
* \brief The VisualizationManager handles IVisualizationTree objects
* It maintains a list of IVisualizationTree objects, each of which is associated to a scenario. This
* manager is used both at scenario creation time (to load or create IVisualizationTree objects), and when the
* scenario is being run (to forward IVisualizationWidget pointers to the related IVisualizationTree).
*/
class IVisualizationManager
{
public:
virtual ~IVisualizationManager() = default;
/**
* \brief An interface used to iteratively notify its creator of the existence of IVisualizationTree objects
*/
class IVisualizationTreeEnum
{
public:
virtual ~IVisualizationTreeEnum() = default;
/**
* \brief Callback method called iteratively as the IVisualizationManager goes through a set of IVisualizationTree objects
* \param visualizationTreeIdentifier identifier of an IVisualizationTree object
* \param visualizationTree corresponding IVisualizationTree object
* \return True if IVisualizationTree object was successfully registered, false otherwise
*/
virtual bool callback(const CIdentifier& visualizationTreeIdentifier, const IVisualizationTree& visualizationTree) = 0;
};
/**
* \brief Creates an IVisualizationTree object.
* \param visualizationTreeIdentifier [out] identifier of the IVisualizationTree object created by this method
* \return True if object was successfully created, false otherwise
*/
virtual bool createVisualizationTree(CIdentifier& visualizationTreeIdentifier) = 0;
/**
* \brief Releases an IVisualizationTree object.
* \param visualizationTreeIdentifier identifier of the IVisualizationTree object to be released
* \return True if object was successfully released, false otherwise
*/
virtual bool releaseVisualizationTree(const CIdentifier& visualizationTreeIdentifier) = 0;
/**
* \brief Looks for an IVisualizationTree object.
* \param visualizationTreeIdentifier identifier of the IVisualizationTree object to be returned
* \return Reference on IVisualizationTree looked for, OV_Undefined otherwise
*/
virtual IVisualizationTree& getVisualizationTree(const CIdentifier& visualizationTreeIdentifier) = 0;
/**
* \brief Set the toolbar of a visualization plugin.
* This method is to be called by visualization plugins as they are being initialized. It lets them send
* a pointer to their toolbar (if they have one) to the scenario's IVisualizationTree.
* \param visualizationTreeIdentifier identifier of IVisualizationTree to which the toolbar pointer is to be forwarded
* \param boxID Identifier of IBox whose toolbar pointer is being set
* \param toolbar pointer to the toolbar of the widget
* \return True if pointer was successfully forwarded to IVisualizationTree, false otherwise
*/
virtual bool setToolbar(const CIdentifier& visualizationTreeIdentifier, const CIdentifier& boxID, GtkWidget* toolbar) = 0;
/**
* \brief Set the topmost widget of a visualization plugin.
* This method is to be called by visualization plugins as they are being initialized. It lets them send
* a pointer to their topmost widget to the scenario's IVisualizationTree.
* \param visualizationTreeIdentifier identifier of IVisualizationTree to which the toolbar pointer is to be forwarded
* \param boxID Identifier of IBox whose topmost widget pointer is being set
* \param widget pointer to the main window of the widget
* \return True if pointer was successfully forwarded to IVisualizationTree, false otherwise
*/
virtual bool setWidget(const CIdentifier& visualizationTreeIdentifier, const CIdentifier& boxID, GtkWidget* widget) = 0;
};
} // namespace VisualizationToolkit
} // namespace OpenViBE
@@ -0,0 +1,483 @@
#pragma once
#include "ovvizIVisualizationWidget.h"
typedef struct _GtkWidget GtkWidget;
typedef struct _GtkTreeView GtkTreeView;
typedef struct _GtkTreeIter GtkTreeIter;
typedef struct _GtkTreePath GtkTreePath;
namespace OpenViBE {
namespace VisualizationToolkit {
/**
* \brief Drag locations around a widget
*/
enum class EDragLocation { Left, Right, Top, Bottom };
/**
* \brief Column types in a visualization tree
*/
enum class EVisualizationTreeColumn
{
/**
* \brief Node name
* Depending on the node type, it refers to :
* the name given to the window for EVisualizationTreeNode::VisualizationWindow nodes,
* the name of the notebook tab for EVisualizationTreeNode::VisualizationPanel nodes,
* the name of the related IBox for EVisualizationTreeNode::VisualizationBox nodes,
* "Vertical split" for EVisualizationTreeNode::VerticalSplit nodes,
* "Horizontal split" for EVisualizationTreeNode::HorizontalSplit nodes,
* "Unaffected display plugins" for the EVisualizationTreeNode::Unaffected node
*/
StringName,
/**
* \brief Icon associated to a node
* Constant except for type EVisualizationTreeNode::VisualizationBox, for which it can be specified in the plugin descriptor
*/
StringStockIcon,
ULongNodeType, ///< EVisualizationTreeNode type
StringIdentifier, ///< IVisualizationWidget identifier
PointerWidget ///< Pointer to the GtkWidget associated to the node (if any)
};
/**
* \brief Node types in a visualization tree
*/
enum class EVisualizationTreeNode
{
Undefined, ///< May be used for placeholders
VPU, ///< Not used yet
VisualizationWindow, ///< A top level window
VisualizationPanel, ///< A notebook tab inside a window
VisualizationBox, ///< A visualization box (a plugin which displays something)
VerticalSplit, ///< A vertical split widget
HorizontalSplit, ///< A horizontal split widget
Unaffected ///< A special node parent to all unaffected visualization boxes
};
class IVisualizationTree;
/**
* \brief Tree view interface
* It must be implemented by classes which communicate with the IVisualizationTree class in order
* to display the contents of the visualization tree.
*/
struct ITreeViewCB
{
virtual ~ITreeViewCB() = default;
/**
* \brief Notifies the tree view that a new widget is being created
* \param widget pointer to the newly created widget
*/
virtual void createTreeWidget(IVisualizationWidget* widget) { }
/**
* \brief Notifies the tree view that a widget is being loaded.
* This method must return a Gtk widget that matches the description passed in parameter, or nullptr if
* it doesn't wish to support a specific kind of widget (e.g. top level windows are not instantiated by the
* offline window manager). The widget pointer returned is stored in the EVisualizationTreeColumn::PointerWidget
* column of the corresponding tree node.
* \param widget pointer to loaded visualization widget
* \return GtkWidget* pointer to Gtk widget associated to visualization widget (possibly nullptr)
*/
virtual GtkWidget* loadTreeWidget(IVisualizationWidget* widget) { return nullptr; }
/**
* \brief Notifies the tree view that a widget hierarchy has been loaded
* This method lets the tree view perform additional loading operations at the end of the loading
* process
* \param widget pointer to visualization widget
*/
virtual void endLoadTreeWidget(IVisualizationWidget* widget) { }
/**
* \brief Asks for the visualization (visible) widget associated to the tree widget passed in parameter
* In some cases the Gtk 'tree widget' associated to a tree node is a table comprising several widgets.
* For example, in the offline window manager, a widget is often stored in the central cell of a 3x3 table and is surrounded
* by transparent event boxes for drag n' drop purposes.
* This callback returns the central 'visualization widget' (the visible widget) contained in such a table if any, otherwise
* it returns the tree widget itself.
* \param widget pointer to the Gtk widget associated to a tree node (as stored in the EVisualizationTreeColumn::PointerWidget
* column of a tree store)
* \return pointer to the visible Gtk widget if pTreeWidget is a table, pTreeWidget itself otherwise(default)
* \sa getTreeWidget()
*/
virtual GtkWidget* getVisualizationWidget(GtkWidget* widget) { return widget; }
/**
* \brief Asks for the tree widget associated to a visualization widget
* In some cases a Gtk widget is inserted in a 3x3 table for drag n' drop purposes. In such cases, a distinction is
* made between the 'visualization widget' (the actual visible widget) and the widget stored in the EVisualizationTreeColumn::PointerWidget
* column of a tree store.
* \param widget pointer to visualization widget
* \return parent table if any, visualizationWidget otherwise (default)
* \sa getVisualizationWidget()
*/
virtual GtkWidget* getTreeWidget(GtkWidget* widget) { return widget; }
/**
* \brief Icon associated to a visualization tree node
* Each node has a Gtk icon. It is defined by the tree view, but can be customised for nodes of type EVisualizationTreeNode::VisualizationBox.
* This method asks the tree view what icon is to be used for a given type of node.
* \param nodeType type of node whose icon name is to be retrieved
* \return name of stock icon to be associated to the type of node passed in parameter
*/
virtual const char* getTreeWidgetIcon(EVisualizationTreeNode nodeType) { return ""; }
/**
* \brief Set toolbar pointer of a visualization box
* Forwards pointer to the toolbar of a visualization box as the player is launched and each visualization
* box contained in the active scenario is being instantiated.
* \param boxID Identifier of IBox whose toolbar is being set
* \param toolbar pointer to toolbar of visualization box
* \return true if widget was successfully registered, false otherwise
*/
virtual bool setToolbar(const CIdentifier& boxID, GtkWidget* toolbar) { return false; }
/**
* \brief Set topmost widget pointer of a visualization box
* Forwards pointer to the topmost widget of a visualization box as the player is launched and each visualization
* box contained in the active scenario is being instantiated. Used to position each box at the appropriate position, as defined
* using the offline window manager.
* \param boxID Identifier of IBox whose toolbar is being set
* \param widget pointer to main window of visualization box
* \return true if widget was successfully registered, false otherwise
*/
virtual bool setWidget(const CIdentifier& boxID, GtkWidget* widget) { return false; }
};
/**
* \class IVisualizationTree
* \author Vincent Delannoy (INRIA/IRISA)
* \date 2007-11
* \brief Handles visualization widgets and their arrangement in space
* This interface lets applications configure visualization widgets by adding them to windows and
* tabs, positioning them next to each other using paned widgets, and resizing them as the user
* sees fit. All widgets are saved in a symbolic way as IVisualizationWidget instances referenced in a tree store.
* Methods of this class are essentially meant to be called from an external class inheriting from the ITreeViewCB
* interface, for offline design or online use of the widgets.
*/
class IVisualizationTree
{
public:
virtual ~IVisualizationTree() = default;
/**
* \brief Initializes the visualization tree
* This method registers the scenario associated to this tree and creates a tree store.
* \param scenario scenario associated to this tree store
* \return true if tree was successfully initialized, false otherwise
*/
virtual bool init(const Kernel::IScenario* scenario) = 0;
/**
* \name IVisualizationWidget management
*/
//@{
/**
* \brief Iterates through IVisualizationWidget instances managed by this tree
* Upon first call, this method should be passed an identifier initialized with CIdentifier::undefined().
* It is modified at each subsequent call until all widgets have been returned (in which
* case the identifier is reset to OV_Undefined)
* \param id [in/out] identifier of current visualization widget when calling the method and of next widget upon return
* \return true if a widget was found, false if past beyond last one
*/
virtual bool getNextVisualizationWidgetIdentifier(CIdentifier& id) const = 0;
/**
* \brief Iterates through IVisualizationWidget instances of type type managed by this tree
* \param id [in/out] identifier of current visualization widget when calling the method and of next widget upon return
* \param type restricts search to IVisualizationWidget instances of type type
* \return true if a widget was found, false if past beyond last one
* \sa getNextVisualizationWidgetIdentifier()
*/
virtual bool getNextVisualizationWidgetIdentifier(CIdentifier& id, EVisualizationWidget type) const = 0;
/**
* \brief Tests whether an identifier corresponds to an IVisualizationWidget instance
* This method browses the internal tree store to look for a node whose EVisualizationTreeColumn::StringIdentifier field
* equals 'identifier' once converted to CString format.
* \param id identifier to look for in the internal tree store
* \return true if identifier corresponds to an IVisualizationWidget instance stored in this tree, false otherwise
*/
virtual bool isVisualizationWidget(const CIdentifier& id) const = 0;
/**
* \brief Returns the IVisualizationWidget instance whose identifier is passed in parameter
* \param id identifier to look for in the internal tree store
* \return pointer to IVisualizationWidget whose identifier matches 'identifier' if any, nullptr otherwise
*/
virtual IVisualizationWidget* getVisualizationWidget(const CIdentifier& id) const = 0;
/**
* \brief Returns the IVisualizationWidget instance whose corresponding IBox identifier matches 'boxID'
* This method inherently restricts the search to nodes of type EVisualizationTreeNode::VisualizationBox
* since only these nodes are associated to an IBox instance.
* \param boxID identifier of IBox whose associated IVisualizationWidget is to be retrieved
* \return IVisualizationWidget whose associated IBox identifier matches 'boxID' if any, nullptr otherwise
*/
virtual IVisualizationWidget* getVisualizationWidgetFromBoxIdentifier(const CIdentifier& boxID) const = 0;
/**
* \brief Adds an IVisualizationWidget instance to the tree
* Seven parameters describe the IVisualizationWidget to be created. Not all are relevant for every type of widget.
* \param id identifier of the widget to be created
* \param name name of the widget
* \param type type of the widget
* \param parentID parent widget identifier (CIdentifier::undefined() for top-level widgets)
* \param parentIdx index where this widget is to be parented (irrelevant for top-level widgets)
* \param boxID identifier of associated IBox (for widgets of type EVisualizationWidget::Box only)
* \param nChild number of children of this widget (none for a visualization box, 1 for a visualization panel, 2 for split widgets, variable number for windows)
* \param suggestedID a suggestion as to the identifier to use
* \return true if widget successfully added to the internal tree store, false otherwise
*/
virtual bool addVisualizationWidget(CIdentifier& id, const CString& name,
EVisualizationWidget type, const CIdentifier& parentID,
size_t parentIdx, const CIdentifier& boxID,
size_t nChild, const CIdentifier& suggestedID) = 0;
/**
* \brief Returns the index where a widget is parented
* Irrelevant for top level windows.
* \param id identifier of the IVisualizationWidget whose index is to be retrieved
* \param index [out] index where the widget is parented
* \return true if widget index could be determined, false otherwise
*/
virtual bool getVisualizationWidgetIndex(const CIdentifier& id, size_t& index) const = 0;
/**
* \brief Unparents a widget from its parent, if any
* \param id identifier of widget to be unparented
* \param index [out] index where this widget was parented
* \return true if widget could be removed from its parent, false otherwise
*/
virtual bool unparentVisualizationWidget(const CIdentifier& id, size_t& index) = 0;
/**
* \brief Parents a widget to a parent widget
* \param id identifier of widget to be parented
* \param parentID identifier of parent widget
* \param index index where widget is to be parented
* \return true if widget could be parented as desired, false otherwise
*/
virtual bool parentVisualizationWidget(const CIdentifier& id, const CIdentifier& parentID, const size_t index) = 0;
/**
* \brief Destroys a widget hierarchy
* \param id identifier of widget that is to be destroyed, along with all widgets in its subtree
* \param destroy if false, widgets of type EVisualizationTreeNode::VisualizationBox are unaffected only (as opposed to destroyed)
* \return true if hierarchy was successfully destroyed, false otherwise
*/
virtual bool destroyHierarchy(const CIdentifier& id, bool destroy = true) = 0;
//@}
/**
* \name Tree view creation/registration
*/
//@{
/**
* \brief Creates a tree view from the internal tree store/model
* \return pointer to newly created tree view
*/
virtual GtkTreeView* createTreeViewWithModel() = 0;
/**
* \brief Sets the instance implementing the ITreeViewCB interface that is to be used with the visualization tree
* \param callback pointer to an implementation of the ITreeViewCB interface
* \return true if tree view was successfully registered, false otherwise
* \sa ITreeViewCB
*/
virtual bool setTreeViewCB(ITreeViewCB* callback) = 0;
//@}
/**
* \brief Recreates Gtk widgets based on the widgets description stored in the internal tree store.
* To be called upon widget creation, deletion or repositioning. Side effects : all tree iterators
* and GtkWidget pointers are invalidated and replaced with new values.
* \return true if widgets were successfully reloaded, false otherwise
*/
virtual bool reloadTree() = 0;
/**
* \name Helper functions
*/
//@{
/**
* \brief Returns currently selected node
* \param treeView pointer to tree view whose selected node is to be retrieved
* \param iter [out] pointer to selected node
* \return true if a node is selected, false otherwise
*/
virtual bool getTreeSelection(GtkTreeView* treeView, GtkTreeIter* iter) = 0;
/**
* \brief Returns tree path of a given node
* \param iter pointer to node whose path is to be retrieved
* \return pointer to path of node
*/
virtual GtkTreePath* getTreePath(GtkTreeIter* iter) const = 0;
/**
* \brief Returns size_t value stored in the 'colType' column of node 'iter'
* \param iter pointer to node
* \param colType index of column where size_t value is stored
* \return size_t value retrieved at the specified column of the specified node, if any, 0 otherwise.
*/
virtual size_t getULongValueFromTreeIter(GtkTreeIter* iter, EVisualizationTreeColumn colType) const = 0;
/**
* \brief Returns string stored in the 'colType' column of node 'iter'
* \param iter pointer to node
* \param string [out] string to be retrieved
* \param colType index of column where string is stored
* \return true if string was successfully retrieved at the specified column of the specified node, 0 otherwise.
*/
virtual bool getStringValueFromTreeIter(GtkTreeIter* iter, char*& string, EVisualizationTreeColumn colType) const = 0;
/**
* \brief Returns pointer stored in the 'colType' column of node 'iter'
* \param iter pointer to node
* \param pointer [out] pointer to be retrieved
* \param colType index of column where pointer is stored
* \return true if pointer was successfully retrieved at the specified column of the specified node, 0 otherwise.
*/
virtual bool getPointerValueFromTreeIter(GtkTreeIter* iter, void*& pointer, EVisualizationTreeColumn colType) const = 0;
/**
* \brief Returns identifier stored in the 'colType' column of node 'iter'
* \param iter pointer to node
* \param id [out] identifier to be retrieved
* \param colType index of column where identifier is stored
* \return true if identifier was successfully retrieved at the specified column of the specified node, 0 otherwise.
*/
virtual bool getIdentifierFromTreeIter(GtkTreeIter* iter, CIdentifier& id, EVisualizationTreeColumn colType) const = 0;
//@}
/**
* \name Node searching
*/
//@{
/**
* \brief Looks for a node of name 'label' and type 'type' from the root of the internal tree store
* \param iter [out] pointer to node to be retrieved
* \param label label of node to be retrieved, as stored in the EVisualizationTreeColumn::StringName column
* \param type type of node to be retrieved, as stored in the EVisualizationTreeColumn::ULongNodtype column
* \return true if node was found, false otherwise
*/
virtual bool findChildNodeFromRoot(GtkTreeIter* iter, const char* label, EVisualizationTreeNode type) = 0;
/**
* \brief Looks for a node of name 'label' and type 'type' from a given node in the internal tree store
* \param iter [in/out] pointer to node from which to start searching when calling function and to node found upon return
* \param label label of node to be retrieved, as stored in the EVisualizationTreeColumn::StringName column
* \param type type of node to be retrieved, as stored in the EVisualizationTreeColumn::ULongNodtype column
* \return true if node was found, false otherwise
*/
virtual bool findChildNodeFromParent(GtkTreeIter* iter, const char* label, EVisualizationTreeNode type) = 0;
/**
* \brief Looks for a node whose associated Gtk widget matches 'widget' from the root of the internal tree store
* \param iter [out] pointer to node to be retrieved
* \param widget pointer to Gtk widget of node to be retrieved, as stored in the EVisualizationTreeColumn::PointerWidget column
* \return true if node was found, false otherwise
*/
virtual bool findChildNodeFromRoot(GtkTreeIter* iter, void* widget) = 0;
/**
* \brief Looks for a node whose associated Gtk widget matches 'widget' from a given node in the internal tree store
* \param iter [in/out] pointer to node from which to start searching when calling function and to node found upon return
* \param widget pointer to Gtk widget of node to be retrieved, as stored in the EVisualizationTreeColumn::PointerWidget column
* \return true if node was found, false otherwise
*/
virtual bool findChildNodeFromParent(GtkTreeIter* iter, void* widget) = 0;
/**
* \brief Looks for a node whose identifier matches 'identifier' from the root of the internal tree store
* \param iter [out] pointer to node to be retrieved
* \param id identifier of node to be retrieved, as stored in the EVisualizationTreeColumn::StringIdentifier column
* \return true if node was found, false otherwise
*/
virtual bool findChildNodeFromRoot(GtkTreeIter* iter, CIdentifier id) = 0;
/**
* \brief Looks for a node whose identifier matches 'identifier' from a given node in the internal tree store
* \param iter [in/out] pointer to node from which to start searching when calling function and to node found upon return
* \param id identifier of node to be retrieved, as stored in the EVisualizationTreeColumn::StringIdentifier column
* \return true if node was found, false otherwise
*/
virtual bool findChildNodeFromParent(GtkTreeIter* iter, CIdentifier id) = 0;
/**
* \brief Find first parent node of a given type
* Looks for first parent node of type 'type' from a given node in the internal tree store
* \param iter [in/out] pointer to node from which to start searching when calling function and to node found upon return
* \param type type of parent node looked for, as stored in the EVisualizationTreeColumn::ULongNodtype column
* \return true if node was found, false otherwise
*/
virtual bool findParentNode(GtkTreeIter* iter, EVisualizationTreeNode type) = 0;
//@}
/**
* \name Drag n' drop functions
*/
//@{
/**
* \brief Handles drop of a widget in an existing widget
* This operation replaces the existing widget with the one passed in parameter. The existing widget
* is unaffected if it is of type EVisualizationTreeNode::VisualizationBox, or destroyed if it is of
* type EVisualizationTreeNode::Undefined (placeholder widget).
* \param srcWidgetID identifier of widget being dropped
* \param dstWidget pointer to widget on which the drop operation is performed
* \return true if drop operation was successfully completed, false otherwise
*/
virtual bool dragDataReceivedInWidgetCB(const CIdentifier& srcWidgetID, GtkWidget* dstWidget) = 0;
/**
* \brief Handles drop of a widget in an event box
* This operation adds a widget to the tree and changes the tree structure.
* If a widget is moved from one place to the other in the tree, it is automatically
* simplified to avoid placeholders creation.
* \param srcWidgetID identifier of widget being dropped
* \param dstWidget pointer to widget on which the drop operation is performed
* \param location
* \return true if drop operation was successfully completed, false otherwise
*/
virtual bool dragDataReceivedOutsideWidgetCB(const CIdentifier& srcWidgetID, GtkWidget* dstWidget, EDragLocation location) = 0;
//@}
/**
* \brief Forward pointer to the toolbar of a visualization plugin (if any) to the tree view
* \param boxID Identifier of IBox whose toolbar pointer is being set
* \param toolbar pointer to toolbar
* \return \e true in case of success, \e false otherwise.
*/
virtual bool setToolbar(const CIdentifier& boxID, GtkWidget* toolbar) = 0;
/**
* \brief Forward pointer to the main widget of a visualization plugin to the tree view
* \param boxID Identifier of IBox whose topmost widget pointer is being set
* \param widget pointer to main window
* \return \e true in case of success, \e false otherwise.
*/
virtual bool setWidget(const CIdentifier& boxID, GtkWidget* widget) = 0;
/**
* \return String representation of the visualization tree
*/
virtual CString serialize() const = 0;
/**
* \brief Initializes the visualization tree from a string representation
* \param tree The string representation of the new tree
* \retval true In case of success
* \retval false In case of error
*/
virtual bool deserialize(const CString& tree) = 0;
};
} // namespace VisualizationToolkit
} // namespace OpenViBE
@@ -0,0 +1,146 @@
#pragma once
#include <openvibe/ov_all.h>
namespace OpenViBE {
namespace VisualizationToolkit {
/// <summary> This enum lists the different types of IVisualizationWidget supported by the platform. </summary>
enum class EVisualizationWidget
{
Undefined, ///< Undefined widget (empty slot in an IVisualizationTree)
Window, ///< Top-level IVisualizationWidget container
Panel, ///< Notebook tab containing IVisualizationWidget objects
Box, ///< Visualization plugin
VerticalSplit, ///< Split widget that divides its client area vertically in two
HorizontalSplit ///< Split widget that divides its client area horizontally in two
};
/**
* \class IVisualizationWidget
* \author Vincent Delannoy (INRIA/IRISA)
* \date 2007-11
* \brief Interface of visualization widgets that are handled by an IVisualizationTree
* These objects are stored in an IVisualizationTree object as they are being created and modified
* to suit the graphical needs of a scenario.
*/
class IVisualizationWidget
{
public:
virtual ~IVisualizationWidget() = default;
/**
* \brief Initializes the widget
* \param identifier identifier of the widget
* \param name name of the widget (optional)
* \param type type of the widget
* \param parentID parent widget identifier (OV_Undefined for top-level widgets)
* \param boxID if widget type is EVisualizationWidget::Box, identifier of corresponding IBox
* \param nChild number of children of this widget (none for a visualization box, 1 for a visualization panel, 2 for split widgets, variable number for windows)
* \return True if widget was successfully initialized, false otherwise
*/
virtual bool initialize(const CIdentifier& identifier, const CString& name,
const EVisualizationWidget type, const CIdentifier& parentID,
const CIdentifier& boxID, const size_t nChild) = 0;
/**
* \brief Returns the identifier of the widget
* \return Widget identifier
*/
virtual CIdentifier getIdentifier() const = 0;
/**
* \brief Returns the name of the widget
* \return Widget name
*/
virtual const CString& getName() const = 0;
/**
* \brief Sets the name of the widget
* \param name name to give to the widget
*/
virtual void setName(const CString& name) = 0;
/**
* \brief Returns the type of the widget
* \return Widget type
*/
virtual EVisualizationWidget getType() const = 0;
/**
* \brief Returns the identifier of the widget's parent (if any)
* \return Widget's parent identifier if any, OV_Undefined otherwise
*/
virtual CIdentifier getParentIdentifier() const = 0;
/**
* \brief Sets the identifier of the widget's parent
* \param parentID identifier of the widget's parent
*/
virtual void setParentIdentifier(const CIdentifier& parentID) = 0;
/**
* \brief Returns the identifier of the IBox associated to this widget.
*
* This only applies to widgets of type EVisualizationWidget::Box.
* \return Identifier of IBox associated to this widget
*/
virtual CIdentifier getBoxIdentifier() const = 0;
/**
* \brief Returns the number of children of this widget
* \return Number of child widgets
*/
virtual size_t getNbChildren() const = 0;
/**
* \brief Returns the index of a given child
* \param identifier identifier of a child widget
* \param index [out] index at which the child widget is stored
* \return True if the child was found, false otherwise
*/
virtual bool getChildIndex(const CIdentifier& identifier, size_t& index) const = 0;
/**
* \brief Adds a child to a widget
*
* Only useful for top-level widgets (EVisualizationWidget::Window) since the number
* of tabs their notebook may contain is unknown a priori. The child is added after existing children.
* \param childIdentifier identifier of child to be added to widget
* \return True if child was successfully added
*/
virtual bool addChild(const CIdentifier& childIdentifier) = 0;
/**
* \brief Removes a child from a widget
* \param childIdentifier identifier of child to be removed to the widget
* \return True if the child was successfully removed
*/
virtual bool removeChild(const CIdentifier& childIdentifier) = 0;
/**
* \brief Returns the identifier of a given child
* \param childIndex index of child whose identifier is to be retrieved
* \param childIdentifier [out] identifier of child
* \return True if child identifier was successfully returned, false otherwise
*/
virtual bool getChildIdentifier(const size_t childIndex, CIdentifier& childIdentifier) const = 0;
/**
* \brief Sets the identifier of a child
* \param childIndex index of child whose identifier is to be set
* \param childIdentifier identifier of the child to be added to the widget
* \return True if the child was successfully set
*/
virtual bool setChildIdentifier(const size_t childIndex, const CIdentifier& childIdentifier) = 0;
virtual void setWidth(const size_t width) = 0;
virtual void setHeight(const size_t height) = 0;
virtual size_t getWidth() = 0;
virtual size_t getHeight() = 0;
virtual void setDividerPosition(const int dividerPosition) = 0;
virtual void setMaxDividerPosition(const int maxDividerPosition) = 0;
virtual int getDividerPosition() = 0;
virtual int getMaxDividerPosition() = 0;
};
} // namespace VisualizationToolkit
} // namespace OpenViBE
@@ -0,0 +1,29 @@
#pragma once
#include "ovp_global_defines.h"
//___________________________________________________________________//
// //
// Basic includes //
//___________________________________________________________________//
#include "ovviz_defines.h"
#include "ovviz_base.h"
//___________________________________________________________________//
// //
// Tools //
//___________________________________________________________________//
#include "ovvizColorGradient.h"
#include "ovvizIVisualizationContext.h"
#include "ovvizIVisualizationManager.h"
#include "ovvizIVisualizationTree.h"
#include "ovvizIVisualizationWidget.h"
namespace OpenViBE {
namespace VisualizationToolkit {
OVVIZ_API bool initialize(const Kernel::IKernelContext& ctx);
OVVIZ_API bool uninitialize(const Kernel::IKernelContext& ctx);
} // namespace VisualizationToolkit
} // namespace OpenViBE
@@ -0,0 +1,5 @@
#pragma once
#include "ovviz_defines.h"
#include <openvibe/ov_all.h>
@@ -0,0 +1,38 @@
#pragma once
#define OV_TypeId_Color OpenViBE::CIdentifier(0x7F45A2A9, 0x7DB12219)
#define OV_TypeId_ColorGradient OpenViBE::CIdentifier(0x3D3C7C7F, 0xEF0E7129)
#define OVP_ClassId_Plugin_VisualizationCtx OpenViBE::CIdentifier(0x05A7171D, 0x78E4FE3C)
#define OVVIZ_MetadataIdentifier_VisualizationTree OpenViBE::CIdentifier(0x3BCCE5D2, 0x43F2D968)
//___________________________________________________________________//
// //
// API Definition //
//___________________________________________________________________//
// //
// Taken from
// - http://people.redhat.com/drepper/dsohowto.pdf
// - http://www.nedprod.com/programs/gccvisibility.html
#if defined OVVIZ_Shared
#if defined TARGET_OS_Windows
#define OVVIZ_API_Export __declspec(dllexport)
#define OVVIZ_API_Import __declspec(dllimport)
#elif defined TARGET_OS_Linux || defined TARGET_OS_MacOS
#define OVVIZ_API_Export __attribute__((visibility("default")))
#define OVVIZ_API_Import __attribute__((visibility("default")))
#else
#define OVVIZ_API_Export
#define OVVIZ_API_Import
#endif
#else
#define OVVIZ_API_Export
#define OVVIZ_API_Import
#endif
#if defined OVVIZ_Exports
#define OVVIZ_API OVVIZ_API_Export
#else
#define OVVIZ_API OVVIZ_API_Import
#endif
@@ -0,0 +1,33 @@
#include "ovvizCVisualizationContext.hpp"
namespace OpenViBE {
namespace VisualizationToolkit {
bool CVisualizationContext::setWidget(Toolkit::TBoxAlgorithm<Plugins::IBoxAlgorithm>& box, GtkWidget* widget)
{
const CIdentifier boxID = box.getStaticBoxContext().getIdentifier();
CIdentifier treeIdentifier = CIdentifier::undefined();
// When a scenario is created in the designer, the designer creates a visualization tree for it. The box will then need to add
// visualization widgets into this tree. The designer can not pass this information directly to a box in a way that can be read
// here (for example an Attribute could be written in the designer but then it is not possible to read it here).
//
// What we do is that we write the visualization tree identifier into the local scenario configuration manager. This manager
// can be accessed as long as we have the boxAlgorithm.
if (!treeIdentifier.fromString(box.getConfigurationManager().lookUpConfigurationTokenValue("VisualizationContext_VisualizationTreeId"))) { return false; }
return m_VisualizationManager->setWidget(treeIdentifier, boxID, widget);
}
bool CVisualizationContext::setToolbar(Toolkit::TBoxAlgorithm<Plugins::IBoxAlgorithm>& box, GtkWidget* toolbarWidget)
{
const CIdentifier boxID = box.getStaticBoxContext().getIdentifier();
CIdentifier treeIdentifier = CIdentifier::undefined();
if (!treeIdentifier.fromString(box.getConfigurationManager().lookUpConfigurationTokenValue("VisualizationContext_VisualizationTreeId"))) { return false; }
return m_VisualizationManager->setToolbar(treeIdentifier, boxID, toolbarWidget);
}
} // namespace VisualizationToolkit
} // namespace OpenViBE
@@ -0,0 +1,93 @@
#pragma once
#include <map>
#include <memory>
#include <openvibe/plugins/ovIPluginObjectDesc.h>
#include <visualization-toolkit/ovviz_all.h>
#include <gtk/gtk.h>
#include "ovvizIVisualizationManager.h"
#include "ovvizIVisualizationContext.h"
#define OVP_ClassId_Plugin_VisualizationCtx OpenViBE::CIdentifier(0x05A7171D, 0x78E4FE3C)
#define OVP_ClassId_Plugin_VisualizationCtxDesc OpenViBE::CIdentifier(0x35A11438, 0x764F72E8)
namespace OpenViBE {
namespace VisualizationToolkit {
/**
* @brief The CVisualizationContext class is a singleton used for passing visualization related information between the application
* and visualization plugins.
*/
class CVisualizationContext final : public IVisualizationContext
{
public:
/**
* The release function is neutralized. The object is only allocated once in the descriptor as a unique_ptr
* and will be released at its destruction.
*/
void release() override { }
bool setManager(IVisualizationManager* visualizationManager) override
{
m_VisualizationManager = visualizationManager;
return true;
}
bool setWidget(Toolkit::TBoxAlgorithm<Plugins::IBoxAlgorithm>& box, GtkWidget* widget) override;
bool setToolbar(Toolkit::TBoxAlgorithm<Plugins::IBoxAlgorithm>& box, GtkWidget* toolbarWidget) override;
bool isDerivedFromClass(const CIdentifier& classIdentifier) const override
{
return ((classIdentifier == OVP_ClassId_Plugin_VisualizationCtx) || IVisualizationContext::isDerivedFromClass(classIdentifier));
}
CIdentifier getClassIdentifier() const override { return OVP_ClassId_Plugin_VisualizationCtx; }
CVisualizationContext() = default;
private:
IVisualizationManager* m_VisualizationManager = nullptr;
};
class CVisualizationContextDesc final : public Plugins::IPluginObjectDesc
{
public:
CVisualizationContextDesc() : m_visualizationCtx(new CVisualizationContext()) {}
void release() override { }
CString getName() const override { return CString("Visualization Context"); }
CString getAuthorName() const override { return CString("Jozef Legény"); }
CString getAuthorCompanyName() const override { return CString("Mensia Technologies"); }
CString getShortDescription() const override { return CString(""); }
CString getDetailedDescription() const override { return CString(""); }
CString getCategory() const override { return CString(""); }
CString getVersion() const override { return CString("1.0"); }
CIdentifier getCreatedClass() const override { return OVP_ClassId_Plugin_VisualizationCtx; }
/**
* The create function usage is different from standard plugins. As we need to be able to pass data between
* the application and the plugins, we need a permanent object that can be accessed by both. We achieve this
* by saving the object within the plugin descriptor and returning the pointer to the same object to all
* plugins.
*
* @return The singleton visualizationContext object
*/
Plugins::IPluginObject* create() override { return m_visualizationCtx.get(); }
bool isDerivedFromClass(const CIdentifier& classIdentifier) const override
{
return ((classIdentifier == OVP_ClassId_Plugin_VisualizationCtxDesc) || IPluginObjectDesc::isDerivedFromClass(classIdentifier));
}
CIdentifier getClassIdentifier() const override { return OVP_ClassId_Plugin_VisualizationCtxDesc; }
private:
std::unique_ptr<CVisualizationContext> m_visualizationCtx;
};
} // namespace VisualizationToolkit
} // namespace OpenViBE
@@ -0,0 +1,144 @@
#include "ovvizColorGradient.h"
#include <cstdio>
#include <string>
#include <map>
namespace OpenViBE {
namespace VisualizationToolkit {
namespace {
typedef struct
{
double percent, red, green, blue;
} SColor;
} // namespace
bool ColorGradient::parse(CMatrix& colorGradient, const CString& string)
{
const std::string colorString(string.toASCIIString());
size_t startPosition = 0;
std::map<double, SColor> colorGradientVector;
do
{
size_t endPosition = colorString.find(OV_Value_EnumeratedStringSeparator, startPosition);
if (endPosition == std::string::npos) { endPosition = colorString.length(); }
std::string colorSubString;
colorSubString.assign(colorString, startPosition, endPosition - startPosition);
int p, r, g, b;
if (sscanf(colorSubString.c_str(), "%i:%i,%i,%i", &p, &r, &g, &b) == 4)
{
SColor color;
color.percent = p;
color.red = r;
color.green = g;
color.blue = b;
colorGradientVector[color.percent] = color;
}
startPosition = endPosition + 1;
} while (startPosition < colorString.length());
colorGradient.resize(4, colorGradientVector.size());
size_t i = 0;
for (auto it = colorGradientVector.begin(); it != colorGradientVector.end(); ++it, i++)
{
colorGradient[i * 4] = it->second.percent;
colorGradient[i * 4 + 1] = it->second.red;
colorGradient[i * 4 + 2] = it->second.green;
colorGradient[i * 4 + 3] = it->second.blue;
}
return true;
}
bool ColorGradient::format(CString& string, const CMatrix& colorGradient)
{
if (colorGradient.getDimensionCount() != 2) { return false; }
if (colorGradient.getDimensionSize(0) != 4) { return false; }
std::string separator(" ");
separator[0] = OV_Value_EnumeratedStringSeparator;
std::string result;
for (size_t i = 0; i < colorGradient.getDimensionSize(1); ++i)
{
char buffer[1024];
sprintf(buffer, "%.0lf:%i,%i,%i", colorGradient[i * 4], int(colorGradient[i * 4 + 1]), int(colorGradient[i * 4 + 2]), int(colorGradient[i * 4 + 3]));
result += (i == 0 ? "" : separator);
result += buffer;
}
string = result.c_str();
return true;
}
bool ColorGradient::interpolate(CMatrix& interpolatedColorGradient, const CMatrix& colorGradient, const size_t steps)
{
size_t i;
if (colorGradient.getDimensionCount() != 2 || colorGradient.getDimensionSize(0) != 4) { return false; }
if (steps <= 1) { return false; }
interpolatedColorGradient.resize(4, steps);
std::map<double, SColor> colors;
for (i = 0; i < colorGradient.getDimensionSize(1); ++i)
{
SColor color;
color.percent = colorGradient[i * 4];
color.red = colorGradient[i * 4 + 1];
color.green = colorGradient[i * 4 + 2];
color.blue = colorGradient[i * 4 + 3];
colors[color.percent] = color;
}
if (colors.find(0) == colors.end())
{
SColor color = colors.begin()->second;
color.percent = 0;
colors[0] = color;
}
if (colors.find(100) == colors.end())
{
SColor color = colors.rbegin()->second;
color.percent = 100;
colors[100] = color;
}
auto it1 = colors.begin();
auto it2 = colors.begin();
++it2;
for (i = 0; i < steps; ++i)
{
const double t = double(100 * i) / (steps - 1);
while (it2->first < t)
{
++it1;
++it2;
}
const double a = it2->first - t;
const double b = t - it1->first;
const double d = it2->first - it1->first;
interpolatedColorGradient[i * 4] = t;
interpolatedColorGradient[i * 4 + 1] = (it1->second.red * a + it2->second.red * b) / d;
interpolatedColorGradient[i * 4 + 2] = (it1->second.green * a + it2->second.green * b) / d;
interpolatedColorGradient[i * 4 + 3] = (it1->second.blue * a + it2->second.blue * b) / d;
}
return true;
}
} // namespace VisualizationToolkit
} // namespace OpenViBE
@@ -0,0 +1,25 @@
#include "visualization-toolkit/ovviz_all.h"
#include "ovvizCVisualizationContext.hpp"
namespace OpenViBE {
namespace {
VisualizationToolkit::CVisualizationContextDesc visualizationContextDesc;
} // namespace
bool VisualizationToolkit::initialize(const Kernel::IKernelContext& ctx)
{
Kernel::ITypeManager& typeManager = ctx.getTypeManager();
Kernel::IPluginManager& pluginManager = ctx.getPluginManager();
typeManager.registerType(OV_TypeId_Color, "Color");
typeManager.registerType(OV_TypeId_ColorGradient, "Color Gradient");
pluginManager.registerPluginDesc(visualizationContextDesc);
return true;
}
bool VisualizationToolkit::uninitialize(const Kernel::IKernelContext& /*ctx*/) { return true; }
} // namespace OpenViBE