|
|
|
|
|
|
|
|
///-------------------------------------------------------------------------------------------------
|
|
|
|
|
|
///
|
|
|
|
|
|
/// \file CBoxAlgorithmP300TactileVisualization.h
|
|
|
|
|
|
/// \brief Classes of the Box P300TactileVisualization.
|
|
|
|
|
|
/// \author Tobias Baumann (TH Nuernberg).
|
|
|
|
|
|
/// \version 1.0.
|
|
|
|
|
|
/// \date Sat May 07 14:20:29 2022.
|
|
|
|
|
|
/// \copyright <a href="https://choosealicense.com/licenses/agpl-3.0/">GNU Affero General Public License v3.0</a>.
|
|
|
|
|
|
///
|
|
|
|
|
|
///-------------------------------------------------------------------------------------------------
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
|
|
//You may have to change this path to match your folder organisation
|
|
|
|
|
|
#include "../ovp_defines.h"
|
|
|
|
|
|
#include "TactileMenu.h"
|
|
|
|
|
|
#include <openvibe/ov_all.h>
|
|
|
|
|
|
#include <toolkit/ovtk_all.h>
|
|
|
|
|
|
#include <tcptagging/IStimulusSender.h>
|
|
|
|
|
|
#include <visualization-toolkit/ovviz_all.h>
|
|
|
|
|
|
|
|
|
|
|
|
#include <gtk/gtk.h>
|
|
|
|
|
|
#include <list>
|
|
|
|
|
|
#include <map>
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
|
#include <string>
|
|
|
|
|
|
#include "../utils.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace TCPTagging {
|
|
|
|
|
|
class IStimulusSender; // fwd declare
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
namespace OpenViBE
|
|
|
|
|
|
{
|
|
|
|
|
|
namespace Plugins
|
|
|
|
|
|
{
|
|
|
|
|
|
namespace Tactilebci
|
|
|
|
|
|
{
|
|
|
|
|
|
/// <summary> The class CBoxAlgorithmP300TactileVisualization describes the box P300TactileVisualization. </summary>
|
|
|
|
|
|
class CBoxAlgorithmP300TactileVisualization final : virtual public Toolkit::TBoxAlgorithm<IBoxAlgorithm>
|
|
|
|
|
|
{
|
|
|
|
|
|
public:
|
|
|
|
|
|
// ------ OV base functions
|
|
|
|
|
|
void release() override { delete this; }
|
|
|
|
|
|
|
|
|
|
|
|
bool initialize() override;
|
|
|
|
|
|
bool uninitialize() override;
|
|
|
|
|
|
|
|
|
|
|
|
//Process Callback on new input received (the most common behaviour for signal processing) :
|
|
|
|
|
|
bool processInput(const size_t index) override;
|
|
|
|
|
|
|
|
|
|
|
|
bool process() override;
|
|
|
|
|
|
|
|
|
|
|
|
// As we do with any class in openvibe, we use the macro below to associate this box to an unique identifier.
|
|
|
|
|
|
// The inheritance information is also made available, as we provide the superclass Toolkit::TBoxAlgorithm < IBoxAlgorithm >
|
|
|
|
|
|
_IsDerivedFromClass_Final_(Toolkit::TBoxAlgorithm<IBoxAlgorithm>, OVP_ClassId_BoxAlgorithm_P300TactileVisualization)
|
|
|
|
|
|
|
|
|
|
|
|
// ------ TCP Tagging
|
|
|
|
|
|
void flushQueue();
|
|
|
|
|
|
|
|
|
|
|
|
// ------ UI Functions
|
|
|
|
|
|
void toggleFlashColor(uint64_t id);
|
|
|
|
|
|
void toggleTargetColor(uint64_t id);
|
|
|
|
|
|
void toggleResultColor(uint64_t id);
|
|
|
|
|
|
void resetColor();
|
|
|
|
|
|
void toggleLabelText();
|
|
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
|
// ------ Input decoder:
|
|
|
|
|
|
Toolkit::TStimulationDecoder<CBoxAlgorithmP300TactileVisualization> m_SequenceInputDecoder;
|
|
|
|
|
|
Toolkit::TStimulationDecoder<CBoxAlgorithmP300TactileVisualization> m_TargetInputDecoder;
|
|
|
|
|
|
Toolkit::TStimulationDecoder<CBoxAlgorithmP300TactileVisualization> m_ResultInputDecoder;
|
|
|
|
|
|
// ------ Output decoder:
|
|
|
|
|
|
Toolkit::TStimulationEncoder<CBoxAlgorithmP300TactileVisualization> m_ResultOutputEncoder;
|
|
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
uint64_t m_LastTarget = 0;
|
|
|
|
|
|
uint64_t m_LastTime = 0;
|
|
|
|
|
|
|
|
|
|
|
|
// ------ Box setting variables
|
|
|
|
|
|
CString m_InterfaceFilename;
|
|
|
|
|
|
uint64_t m_RowBase = 0;
|
|
|
|
|
|
uint64_t m_nTactilos = 6;
|
|
|
|
|
|
bool m_FreeSpelling = false;
|
|
|
|
|
|
|
|
|
|
|
|
// ------TactileMenu variables
|
|
|
|
|
|
std::vector<TactileMenu> m_Menu;
|
|
|
|
|
|
TactileMenu* m_CurrMenu = nullptr;
|
|
|
|
|
|
|
|
|
|
|
|
// ------ GTK variables
|
|
|
|
|
|
GtkBuilder* m_MainWidgetInterface = nullptr;
|
|
|
|
|
|
GtkWidget* m_MainWindow = nullptr;
|
|
|
|
|
|
GtkTable* m_Table = nullptr;
|
|
|
|
|
|
std::vector<GtkWidget*> m_EventBox;
|
|
|
|
|
|
GtkLabel* m_ResultLabel = nullptr;
|
|
|
|
|
|
GtkLabel* m_TargetLabel = nullptr;
|
|
|
|
|
|
|
|
|
|
|
|
GdkColor m_FlashBG = InitGDKColor(0, 3276, 3276, 3276);
|
|
|
|
|
|
GdkColor m_FlashFG = InitGDKColor(0, 65535, 65535, 65535);
|
|
|
|
|
|
GdkColor m_NoFlashBG = InitGDKColor(0, 0, 0, 0);
|
|
|
|
|
|
GdkColor m_NoFlashFG = InitGDKColor(0, 16383, 16383, 16383);
|
|
|
|
|
|
GdkColor m_TargetBG = InitGDKColor(0, 13107, 13107, 45874);
|
|
|
|
|
|
GdkColor m_TargetFG = InitGDKColor(0, 6553, 6553, 19660);
|
|
|
|
|
|
GdkColor m_ResultBG = InitGDKColor(0, 6553, 26214, 6553);
|
|
|
|
|
|
GdkColor m_ResultFG = InitGDKColor(0, 39321, 65535, 39321);
|
|
|
|
|
|
|
|
|
|
|
|
uint64_t FontSize = 50;
|
|
|
|
|
|
PangoFontDescription* m_FontDesc = nullptr;
|
|
|
|
|
|
|
|
|
|
|
|
// ------ TCP Tagging
|
|
|
|
|
|
std::vector<uint64_t> m_stimuliQueue;
|
|
|
|
|
|
guint m_idleFuncTag = 0;
|
|
|
|
|
|
TCPTagging::IStimulusSender* m_stimulusSender = nullptr;
|
|
|
|
|
|
|
|
|
|
|
|
// ------ Box visualization
|
|
|
|
|
|
VisualizationToolkit::IVisualizationContext* m_visualizationCtx = nullptr;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary> Descriptor of the box P300TactileVisualization. </summary>
|
|
|
|
|
|
class CBoxAlgorithmP300TactileVisualizationDesc final : virtual public IBoxAlgorithmDesc
|
|
|
|
|
|
{
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
|
|
|
|
void release() override { }
|
|
|
|
|
|
|
|
|
|
|
|
CString getName() const override { return CString("P300TactileVisualization"); }
|
|
|
|
|
|
CString getAuthorName() const override { return CString("Tobias Baumann"); }
|
|
|
|
|
|
CString getAuthorCompanyName() const override { return CString("TH Nuernberg"); }
|
|
|
|
|
|
CString getShortDescription() const override { return CString(""); }
|
|
|
|
|
|
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-underline"); }
|
|
|
|
|
|
|
|
|
|
|
|
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",OV_TypeId_Stimulations);
|
|
|
|
|
|
prototype.addInput("Target",OV_TypeId_Stimulations);
|
|
|
|
|
|
prototype.addInput("Result",OV_TypeId_Stimulations);
|
|
|
|
|
|
|
|
|
|
|
|
prototype.addOutput("Result",OV_TypeId_Stimulations);
|
|
|
|
|
|
|
|
|
|
|
|
prototype.addSetting("Interface Filename",OV_TypeId_Filename,"/ui/p300-tactile-6.ui");
|
|
|
|
|
|
prototype.addSetting("Row Stimulation Base",OV_TypeId_Stimulation,"OVTK_StimulationId_Label_01");
|
|
|
|
|
|
prototype.addSetting("Number of Tactilos",OV_TypeId_Integer,"6");
|
|
|
|
|
|
prototype.addSetting("Free Spelling",OV_TypeId_Boolean,"false");
|
|
|
|
|
|
|
|
|
|
|
|
prototype.addFlag(OV_AttributeId_Box_FlagIsUnstable);
|
|
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, OVP_ClassId_BoxAlgorithm_P300TactileVisualizationDesc)
|
|
|
|
|
|
};
|
|
|
|
|
|
} // namespace Tactilebci
|
|
|
|
|
|
} // namespace Plugins
|
|
|
|
|
|
} // namespace OpenViBE
|
|
|
|
|
|
|
|
|
///------------------------------------------------------------------------------------------------- |
|
|
|
|
|
/// |
|
|
|
|
|
/// \file CBoxAlgorithmP300TactileVisualization.h |
|
|
|
|
|
/// \brief Classes of the Box P300TactileVisualization. |
|
|
|
|
|
/// \author Tobias Baumann (TH Nuernberg). |
|
|
|
|
|
/// \version 1.0. |
|
|
|
|
|
/// \date Sat May 07 14:20:29 2022. |
|
|
|
|
|
/// \copyright <a href="https://choosealicense.com/licenses/agpl-3.0/">GNU Affero General Public License v3.0</a>. |
|
|
|
|
|
/// |
|
|
|
|
|
///------------------------------------------------------------------------------------------------- |
|
|
|
|
|
#pragma once |
|
|
|
|
|
|
|
|
|
|
|
//You may have to change this path to match your folder organisation |
|
|
|
|
|
#include "../ovp_defines.h" |
|
|
|
|
|
#include "TactileMenu.h" |
|
|
|
|
|
#include <openvibe/ov_all.h> |
|
|
|
|
|
#include <toolkit/ovtk_all.h> |
|
|
|
|
|
#include <tcptagging/IStimulusSender.h> |
|
|
|
|
|
#include <visualization-toolkit/ovviz_all.h> |
|
|
|
|
|
|
|
|
|
|
|
#include <gtk/gtk.h> |
|
|
|
|
|
#include <list> |
|
|
|
|
|
#include <map> |
|
|
|
|
|
#include <vector> |
|
|
|
|
|
#include <algorithm> |
|
|
|
|
|
#include <string> |
|
|
|
|
|
#include "../utils.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace TCPTagging { |
|
|
|
|
|
class IStimulusSender; // fwd declare |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
namespace OpenViBE |
|
|
|
|
|
{ |
|
|
|
|
|
namespace Plugins |
|
|
|
|
|
{ |
|
|
|
|
|
namespace Tactilebci |
|
|
|
|
|
{ |
|
|
|
|
|
/// <summary> The class CBoxAlgorithmP300TactileVisualization describes the box P300TactileVisualization. </summary> |
|
|
|
|
|
class CBoxAlgorithmP300TactileVisualization final : virtual public Toolkit::TBoxAlgorithm<IBoxAlgorithm> |
|
|
|
|
|
{ |
|
|
|
|
|
public: |
|
|
|
|
|
// ------ OV base functions |
|
|
|
|
|
void release() override { delete this; } |
|
|
|
|
|
|
|
|
|
|
|
bool initialize() override; |
|
|
|
|
|
bool uninitialize() override; |
|
|
|
|
|
|
|
|
|
|
|
//Process Callback on new input received (the most common behaviour for signal processing) : |
|
|
|
|
|
bool processInput(const size_t index) override; |
|
|
|
|
|
|
|
|
|
|
|
bool process() override; |
|
|
|
|
|
|
|
|
|
|
|
// As we do with any class in openvibe, we use the macro below to associate this box to an unique identifier. |
|
|
|
|
|
// The inheritance information is also made available, as we provide the superclass Toolkit::TBoxAlgorithm < IBoxAlgorithm > |
|
|
|
|
|
_IsDerivedFromClass_Final_(Toolkit::TBoxAlgorithm<IBoxAlgorithm>, OVP_ClassId_BoxAlgorithm_P300TactileVisualization) |
|
|
|
|
|
|
|
|
|
|
|
// ------ TCP Tagging |
|
|
|
|
|
void flushQueue(); |
|
|
|
|
|
|
|
|
|
|
|
// ------ UI Functions |
|
|
|
|
|
void toggleFlashColor(uint64_t id); |
|
|
|
|
|
void toggleTargetColor(uint64_t id); |
|
|
|
|
|
void toggleResultColor(uint64_t id); |
|
|
|
|
|
void resetColor(); |
|
|
|
|
|
void toggleLabelText(); |
|
|
|
|
|
|
|
|
|
|
|
protected: |
|
|
|
|
|
// ------ Input decoder: |
|
|
|
|
|
Toolkit::TStimulationDecoder<CBoxAlgorithmP300TactileVisualization> m_SequenceInputDecoder; |
|
|
|
|
|
Toolkit::TStimulationDecoder<CBoxAlgorithmP300TactileVisualization> m_TargetInputDecoder; |
|
|
|
|
|
Toolkit::TStimulationDecoder<CBoxAlgorithmP300TactileVisualization> m_ResultInputDecoder; |
|
|
|
|
|
// ------ Output decoder: |
|
|
|
|
|
Toolkit::TStimulationEncoder<CBoxAlgorithmP300TactileVisualization> m_ResultOutputEncoder; |
|
|
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
|
uint64_t m_LastTarget = 0; |
|
|
|
|
|
uint64_t m_LastTime = 0; |
|
|
|
|
|
|
|
|
|
|
|
// ------ Box setting variables |
|
|
|
|
|
CString m_InterfaceFilename; |
|
|
|
|
|
uint64_t m_RowBase = 0; |
|
|
|
|
|
uint64_t m_nTactilos = 6; |
|
|
|
|
|
bool m_FreeSpelling = false; |
|
|
|
|
|
|
|
|
|
|
|
// ------TactileMenu variables |
|
|
|
|
|
std::vector<TactileMenu> m_Menu; |
|
|
|
|
|
TactileMenu* m_CurrMenu = nullptr; |
|
|
|
|
|
|
|
|
|
|
|
// ------ GTK variables |
|
|
|
|
|
GtkBuilder* m_MainWidgetInterface = nullptr; |
|
|
|
|
|
GtkWidget* m_MainWindow = nullptr; |
|
|
|
|
|
GtkTable* m_Table = nullptr; |
|
|
|
|
|
std::vector<GtkWidget*> m_EventBox; |
|
|
|
|
|
GtkLabel* m_ResultLabel = nullptr; |
|
|
|
|
|
GtkLabel* m_TargetLabel = nullptr; |
|
|
|
|
|
|
|
|
|
|
|
GdkColor m_FlashBG = InitGDKColor(0, 3276, 3276, 3276); |
|
|
|
|
|
GdkColor m_FlashFG = InitGDKColor(0, 65535, 65535, 65535); |
|
|
|
|
|
GdkColor m_NoFlashBG = InitGDKColor(0, 0, 0, 0); |
|
|
|
|
|
GdkColor m_NoFlashFG = InitGDKColor(0, 16383, 16383, 16383); |
|
|
|
|
|
GdkColor m_TargetBG = InitGDKColor(0, 13107, 13107, 45874); |
|
|
|
|
|
GdkColor m_TargetFG = InitGDKColor(0, 6553, 6553, 19660); |
|
|
|
|
|
GdkColor m_ResultBG = InitGDKColor(0, 6553, 26214, 6553); |
|
|
|
|
|
GdkColor m_ResultFG = InitGDKColor(0, 39321, 65535, 39321); |
|
|
|
|
|
|
|
|
|
|
|
uint64_t FontSize = 50; |
|
|
|
|
|
PangoFontDescription* m_FontDesc = nullptr; |
|
|
|
|
|
|
|
|
|
|
|
// ------ TCP Tagging |
|
|
|
|
|
std::vector<uint64_t> m_stimuliQueue; |
|
|
|
|
|
guint m_idleFuncTag = 0; |
|
|
|
|
|
TCPTagging::IStimulusSender* m_stimulusSender = nullptr; |
|
|
|
|
|
|
|
|
|
|
|
// ------ Box visualization |
|
|
|
|
|
VisualizationToolkit::IVisualizationContext* m_visualizationCtx = nullptr; |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
/// <summary> Descriptor of the box P300TactileVisualization. </summary> |
|
|
|
|
|
class CBoxAlgorithmP300TactileVisualizationDesc final : virtual public IBoxAlgorithmDesc |
|
|
|
|
|
{ |
|
|
|
|
|
public: |
|
|
|
|
|
|
|
|
|
|
|
void release() override { } |
|
|
|
|
|
|
|
|
|
|
|
CString getName() const override { return CString("P300TactileVisualization"); } |
|
|
|
|
|
CString getAuthorName() const override { return CString("Tobias Baumann"); } |
|
|
|
|
|
CString getAuthorCompanyName() const override { return CString("TH Nuernberg"); } |
|
|
|
|
|
CString getShortDescription() const override { return CString(""); } |
|
|
|
|
|
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-underline"); } |
|
|
|
|
|
|
|
|
|
|
|
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",OV_TypeId_Stimulations); |
|
|
|
|
|
prototype.addInput("Target",OV_TypeId_Stimulations); |
|
|
|
|
|
prototype.addInput("Result",OV_TypeId_Stimulations); |
|
|
|
|
|
|
|
|
|
|
|
prototype.addOutput("Result",OV_TypeId_Stimulations); |
|
|
|
|
|
|
|
|
|
|
|
prototype.addSetting("Interface Filename",OV_TypeId_Filename,"${Player_ScenarioDirectory}/ui/p300-tactile-6.ui"); |
|
|
|
|
|
prototype.addSetting("Row Stimulation Base",OV_TypeId_Stimulation,"OVTK_StimulationId_Label_01"); |
|
|
|
|
|
prototype.addSetting("Number of Tactilos",OV_TypeId_Integer,"6"); |
|
|
|
|
|
prototype.addSetting("Free Spelling",OV_TypeId_Boolean,"false"); |
|
|
|
|
|
|
|
|
|
|
|
prototype.addFlag(OV_AttributeId_Box_FlagIsUnstable); |
|
|
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
} |
|
|
|
|
|
_IsDerivedFromClass_Final_(IBoxAlgorithmDesc, OVP_ClassId_BoxAlgorithm_P300TactileVisualizationDesc) |
|
|
|
|
|
}; |
|
|
|
|
|
} // namespace Tactilebci |
|
|
|
|
|
} // namespace Plugins |
|
|
|
|
|
} // namespace OpenViBE |