///------------------------------------------------------------------------------------------------- /// /// \file ovpCBoxAlgorithmP300TactileVisualization.h /// \brief Classes of the Box P300 Tactile Visualization. !!This is a modification of the P300 Speller Visualization Box!! /// \author Tobias Baumann (TH Nuernberg). /// \version 1.0. /// \date Mon Feb 04 12:43:53 2022. /// \copyright GNU Affero General Public License v3.0. /// ///------------------------------------------------------------------------------------------------- //includes #pragma once #include "TactileMenu.h" #include "../ovp_defines.h" #include #include #include #include #include #include #include #include "../utils.h" namespace TCPTagging { class IStimulusSender; // fwd declare } // namespace TCPTagging namespace OpenViBE { namespace Plugins { namespace Tactilebci { class CBoxAlgorithmP300TactileVisualization final : public Toolkit::TBoxAlgorithm { public: void release() override { delete this; } bool initialize() override; bool uninitialize() override; bool processInput(const size_t index) override; bool process() override; _IsDerivedFromClass_Final_(Toolkit::TBoxAlgorithm, OVP_ClassId_BoxAlgorithm_P300TactileVisualization) // Sends all accumulated stimuli to the TCP Tagging void flushQueue(); private: Kernel::IAlgorithmProxy* m_sequenceStimulationDecoder = nullptr; Kernel::IAlgorithmProxy* m_targetStimulationDecoder = nullptr; Kernel::IAlgorithmProxy* m_targetFlaggingStimulationEncoder = nullptr; Kernel::IAlgorithmProxy* m_rowSelectionStimulationDecoder = nullptr; Kernel::IAlgorithmProxy* m_columnSelectionStimulationDecoder = nullptr; Kernel::TParameterHandler m_sequenceMemoryBuffer; Kernel::TParameterHandler m_targetMemoryBuffer; Kernel::TParameterHandler m_targetFlaggingStimulationSet; Kernel::TParameterHandler m_sequenceStimulationSet; Kernel::TParameterHandler m_targetStimulationSet; Kernel::TParameterHandler m_targetFlaggingMemoryBuffer; uint64_t m_lastTime = 0; GtkBuilder* m_mainWidgetInterface = nullptr; GtkBuilder* m_toolbarWidgetInterface = nullptr; GtkWidget* m_mainWindow = nullptr; GtkWidget* m_toolbarWidget = nullptr; GtkTable* m_table = nullptr; GtkLabel* m_result = nullptr; GtkLabel* m_target = nullptr; //Deklaration TactileMenu Variablen std::vector m_Menu; std::vector m_Label; TactileMenu* m_currMenu; uint64_t m_nRow = 0; uint64_t m_nCol = 0; int m_lastTargetRow = 0; int m_lastTargetCol = 0; int m_targetRow = 0; int m_targetCol = 0; int m_selectedRow = 0; int m_selectedCol = 0; bool m_tableInitialized = false; using widget_style_t = struct { GtkWidget* widget; GtkWidget* childWidget; GdkColor bgColor; GdkColor fgColor; PangoFontDescription* fontDesc; }; typedef void (CBoxAlgorithmP300TactileVisualization::*cache_callback)(widget_style_t& style, void* data); void cacheBuildFromTable(GtkTable* table); void cacheForEach(cache_callback callback, void* data); void cacheForEachIf(int iLine, int iColumn, cache_callback ifCB, cache_callback elseCB, void* ifUserData, void* elseUserData); void cacheChangeNullCB(widget_style_t& style, void* data); void cacheChangeBackgroundCB(widget_style_t& style, void* data); void cacheChangeForegroundCB(widget_style_t& style, void* data); void cacheChangeFontCB(widget_style_t& style, void* data); void cacheCollectWidgetCB(widget_style_t& style, void* data); void cacheCollectChildWidgetCB(widget_style_t& style, void* data); // @todo refactor to std::pair ? std::map> m_cache; std::list> m_targetHistory; // TCP Tagging std::vector m_stimuliQueue; guint m_idleFuncTag = 0; TCPTagging::IStimulusSender* m_stimulusSender = nullptr; VisualizationToolkit::IVisualizationContext* m_visualizationCtx = nullptr; protected: CString m_interfaceFilename; uint64_t m_rowStimulationBase = 0; uint64_t m_columnStimulationBase = 0; GdkColor m_flashBgColor = InitGDKColor(0, 6554, 6554, 6554); GdkColor m_flashFgColor = InitGDKColor(0, 65535, 65535, 65535); uint64_t m_flashFontSize = 100; PangoFontDescription* m_flashFontDesc = nullptr; GdkColor m_noFlashBgColor = InitGDKColor(0, 0, 0, 0); GdkColor m_noFlashFgColor = InitGDKColor(0, 32768, 32768, 32768); uint64_t m_noFlashFontSize = 75; PangoFontDescription* m_noFlashFontDesc = nullptr; GdkColor m_targetBgColor = InitGDKColor(0, 6554, 26214, 6554); GdkColor m_targetFgColor = InitGDKColor(0, 39321, 65535, 39321); uint64_t m_targetFontSize = 100; PangoFontDescription* m_targetFontDesc = nullptr; GdkColor m_selectedBgColor = InitGDKColor(0, 45875, 13107, 13107); GdkColor m_selectedFgColor = InitGDKColor(0, 19661, 6554, 6554); uint64_t m_selectedFontSize = 100; PangoFontDescription* m_selectedFontDesc = nullptr; uint64_t m_nTactilos = 0; }; class CBoxAlgorithmP300TactileVisualizationDesc final : public IBoxAlgorithmDesc { public: void release() override { } CString getName() const override { return CString("P300 Tactile Visualization"); } CString getAuthorName() const override { return CString("Tobias Baumann"); } CString getAuthorCompanyName() const override { return CString("TH-Nürnberg"); } CString getShortDescription() const override { return CString("Visualizes the Menus for a Tactile P300 BCI"); } CString getDetailedDescription() const override { return CString(""); } CString getCategory() const override { return CString("TactileBCI"); } CString getVersion() const override { return CString("1.0"); } CString getStockItemName() const override { return CString("gtk-select-font"); } CIdentifier getCreatedClass() const override { return OVP_ClassId_BoxAlgorithm_P300TactileVisualization; } IPluginObject* create() override { return new CBoxAlgorithmP300TactileVisualization; } bool hasFunctionality(const EPluginFunctionality functionality) const override { return functionality == EPluginFunctionality::Visualization; } bool getBoxPrototype(Kernel::IBoxProto& prototype) const override { prototype.addInput("Sequence stimulations", OV_TypeId_Stimulations); prototype.addInput("Target stimulations", OV_TypeId_Stimulations); prototype.addInput("Row selection stimulations", OV_TypeId_Stimulations); prototype.addInput("Column selection stimulations", OV_TypeId_Stimulations); prototype.addOutput("Target / Non target flagging (deprecated)", OV_TypeId_Stimulations); prototype.addSetting("Interface filename", OV_TypeId_Filename, "${Path_Data}/plugins/simple-visualization/p300-speller.ui"); prototype.addSetting("Row stimulation base", OV_TypeId_Stimulation, "OVTK_StimulationId_Label_01"); prototype.addSetting("Column stimulation base", OV_TypeId_Stimulation, "OVTK_StimulationId_Label_07"); prototype.addSetting("Flash background color", OV_TypeId_Color, "10,10,10"); prototype.addSetting("Flash foreground color", OV_TypeId_Color, "100,100,100"); prototype.addSetting("Flash font size", OV_TypeId_Integer, "100"); prototype.addSetting("No flash background color", OV_TypeId_Color, "0,0,0"); prototype.addSetting("No flash foreground color", OV_TypeId_Color, "50,50,50"); prototype.addSetting("No flash font size", OV_TypeId_Integer, "75"); prototype.addSetting("Target background color", OV_TypeId_Color, "10,40,10"); prototype.addSetting("Target foreground color", OV_TypeId_Color, "60,100,60"); prototype.addSetting("Target font size", OV_TypeId_Integer, "100"); prototype.addSetting("Selected background color", OV_TypeId_Color, "70,20,20"); prototype.addSetting("Selected foreground color", OV_TypeId_Color, "30,10,10"); prototype.addSetting("Selected font size", OV_TypeId_Integer, "100"); prototype.addSetting("Number of Tactilos",OV_TypeId_Integer,"6"); return true; } _IsDerivedFromClass_Final_(IBoxAlgorithmDesc, OVP_ClassId_BoxAlgorithm_P300TactileVisualizationDesc) }; } // namespace Tactilebci } // namespace Plugins } // namespace OpenViBE