diff --git a/src/TactileVisualization/ovpCBoxAlgorithmP300TactileVisualization.cpp b/src/TactileVisualization/ovpCBoxAlgorithmP300TactileVisualization.cpp
index ffba376..4ca66e2 100644
--- a/src/TactileVisualization/ovpCBoxAlgorithmP300TactileVisualization.cpp
+++ b/src/TactileVisualization/ovpCBoxAlgorithmP300TactileVisualization.cpp
@@ -1,32 +1,9 @@
-///-------------------------------------------------------------------------------------------------
-///
-/// \file ovpCBoxAlgorithmP300TactileVisualization.cpp
-/// \brief Functions of the Class P300TactileVisualization. !!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
#include "ovpCBoxAlgorithmP300TactileVisualization.h"
-#include
-#include
-#include
-#include
-#include
-
-namespace OpenViBE {
-namespace Plugins {
-namespace Tactilebci {
-
-static void ToggleButtonShowHideCB(GtkToggleToolButton* button, gpointer data)
-{
- if (gtk_toggle_tool_button_get_active(button)) { gtk_widget_show(GTK_WIDGET(data)); }
- else { gtk_widget_hide(GTK_WIDGET(data)); }
-}
+using namespace OpenViBE;
+using namespace /*OpenViBE::*/Kernel;
+using namespace /*OpenViBE::*/Plugins;
+using namespace /*OpenViBE::Plugins::*/Tactilebci;
// This callback flushes all accumulated stimulations to the TCP Tagging
// after the rendering has completed.
@@ -39,790 +16,454 @@ static gboolean FlushCB(gpointer data)
bool CBoxAlgorithmP300TactileVisualization::initialize()
{
- const Kernel::IBox& boxContext = this->getStaticBoxContext();
-
- m_mainWidgetInterface = nullptr;
- m_toolbarWidgetInterface = nullptr;
- m_flashFontDesc = nullptr;
- m_noFlashFontDesc = nullptr;
- m_targetFontDesc = nullptr;
- m_selectedFontDesc = nullptr;
-
- // ----------------------------------------------------------------------------------------------------------------------------------------------------------
-
- m_interfaceFilename = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 0);
- m_rowStimulationBase = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 1);
- m_columnStimulationBase = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 2);
-
- m_flashBgColor = CGdkcolorAutoCast(boxContext, this->getConfigurationManager(), 3);
- m_flashFgColor = CGdkcolorAutoCast(boxContext, this->getConfigurationManager(), 4);
- m_flashFontSize = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 5);
- m_noFlashBgColor = CGdkcolorAutoCast(boxContext, this->getConfigurationManager(), 6);
- m_noFlashFgColor = CGdkcolorAutoCast(boxContext, this->getConfigurationManager(), 7);
- m_noFlashFontSize = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 8);
- m_targetBgColor = CGdkcolorAutoCast(boxContext, this->getConfigurationManager(), 9);
- m_targetFgColor = CGdkcolorAutoCast(boxContext, this->getConfigurationManager(), 10);
- m_targetFontSize = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 11);
- m_selectedBgColor = CGdkcolorAutoCast(boxContext, this->getConfigurationManager(), 12);
- m_selectedFgColor = CGdkcolorAutoCast(boxContext, this->getConfigurationManager(), 13);
- m_selectedFontSize = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 14);
+ // ------ Init decoder/encoder
+ m_SequenceInputDecoder.initialize(*this, 0);
+ m_TargetInputDecoder.initialize(*this, 1);
+ m_ResultInputDecoder.initialize(*this, 2);
+ m_ResultOutputEncoder.initialize(*this, 0);
- m_nTactilos = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 15);
-
- //set m_nTactilos to 2 if lower than 2
+ // ------ Get box settings
+ m_InterfaceFilename = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 0);
+ m_RowBase = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 1);
+ m_nTactilos = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 2);
+ m_FreeSpelling = FSettingValueAutoCast(*this->getBoxAlgorithmContext(), 3);
+
+ //set m_nTactilos minimum number of 2, if lower
if(m_nTactilos < 2)
{
m_nTactilos = 2;
}
- //set m_nTactilos to MAX if greater than MAX_TACTILOS
+
+ //set m_nTactilos maximum number of MAX_TACTILOS(10), if higher
if(m_nTactilos > MAX_TACTILOS)
{
m_nTactilos = MAX_TACTILOS;
}
-
- // ----------------------------------------------------------------------------------------------------------------------------------------------------------
-
- m_sequenceStimulationDecoder = &this->getAlgorithmManager().getAlgorithm(
- this->getAlgorithmManager().createAlgorithm(OVP_GD_ClassId_Algorithm_StimulationDecoder));
- m_sequenceStimulationDecoder->initialize();
-
- m_targetStimulationDecoder = &this->getAlgorithmManager().getAlgorithm(
- this->getAlgorithmManager().createAlgorithm(OVP_GD_ClassId_Algorithm_StimulationDecoder));
- m_targetStimulationDecoder->initialize();
-
- m_targetFlaggingStimulationEncoder = &this->getAlgorithmManager().getAlgorithm(
- this->getAlgorithmManager().createAlgorithm(OVP_GD_ClassId_Algorithm_StimulationEncoder));
- m_targetFlaggingStimulationEncoder->initialize();
-
- m_rowSelectionStimulationDecoder = &this->getAlgorithmManager().getAlgorithm(
- this->getAlgorithmManager().createAlgorithm(OVP_GD_ClassId_Algorithm_StimulationDecoder));
- m_rowSelectionStimulationDecoder->initialize();
-
- m_columnSelectionStimulationDecoder = &this->getAlgorithmManager().getAlgorithm(
- this->getAlgorithmManager().createAlgorithm(OVP_GD_ClassId_Algorithm_StimulationDecoder));
- m_columnSelectionStimulationDecoder->initialize();
-
- m_sequenceMemoryBuffer.initialize(
- m_sequenceStimulationDecoder->getInputParameter(OVP_GD_Algorithm_StimulationDecoder_InputParameterId_MemoryBufferToDecode));
- m_sequenceStimulationSet.initialize(
- m_sequenceStimulationDecoder->getOutputParameter(OVP_GD_Algorithm_StimulationDecoder_OutputParameterId_StimulationSet));
-
- m_targetMemoryBuffer.initialize(
- m_targetStimulationDecoder->getInputParameter(OVP_GD_Algorithm_StimulationDecoder_InputParameterId_MemoryBufferToDecode));
- m_targetStimulationSet.initialize(
- m_targetStimulationDecoder->getOutputParameter(OVP_GD_Algorithm_StimulationDecoder_OutputParameterId_StimulationSet));
-
- m_targetFlaggingStimulationSet.initialize(
- m_targetFlaggingStimulationEncoder->getInputParameter(OVP_GD_Algorithm_StimulationEncoder_InputParameterId_StimulationSet));
- m_targetFlaggingMemoryBuffer.initialize(
- m_targetFlaggingStimulationEncoder->getOutputParameter(OVP_GD_Algorithm_StimulationEncoder_OutputParameterId_EncodedMemoryBuffer));
-
- m_lastTime = 0;
-
- m_stimulusSender = nullptr;
-
- m_idleFuncTag = 0;
- m_stimuliQueue.clear();
-
- m_mainWidgetInterface = gtk_builder_new(); // glade_xml_new(m_interfaceFilename.toASCIIString(), "p300-speller-main", nullptr);
- if (!gtk_builder_add_from_file(m_mainWidgetInterface, m_interfaceFilename.toASCIIString(), nullptr))
- {
- this->getLogManager() << Kernel::LogLevel_ImportantWarning << "Could not load interface file [" << m_interfaceFilename << "]\n";
- this->getLogManager() << Kernel::LogLevel_ImportantWarning <<
- "The file may be missing. However, the interface files now use gtk-builder instead of glade. Did you update your files ?\n";
- return false;
- }
-
- m_toolbarWidgetInterface = gtk_builder_new(); // glade_xml_new(m_interfaceFilename.toASCIIString(), "p300-speller-toolbar", nullptr);
- gtk_builder_add_from_file(m_toolbarWidgetInterface, m_interfaceFilename.toASCIIString(), nullptr);
-
- m_mainWindow = GTK_WIDGET(gtk_builder_get_object(m_mainWidgetInterface, "p300-speller-main"));
- m_toolbarWidget = GTK_WIDGET(gtk_builder_get_object(m_toolbarWidgetInterface, "p300-speller-toolbar"));
- m_table = GTK_TABLE(gtk_builder_get_object(m_mainWidgetInterface, "p300-speller-table"));
- m_result = GTK_LABEL(gtk_builder_get_object(m_mainWidgetInterface, "label-result"));
- m_target = GTK_LABEL(gtk_builder_get_object(m_mainWidgetInterface, "label-target"));
- //Begin Menu Initialization -------------------------------------------------------------------------------------
- if(m_nTactilos == 6) //Create Menus for m_nTactilos = 6
+ // ------ Setup acquisition server TCP tagging
+ m_stimuliQueue.clear();
+ m_stimulusSender = TCPTagging::CreateStimulusSender();
+ if(!m_stimulusSender->connect("localhost", "15361"))
{
- m_Menu.push_back(TactileMenu(6));
- m_Menu[0].set_LabelText(0, "Ja");
- m_Menu[0].set_LabelText(1, "Nein");
- m_Menu[0].set_LabelText(2, "Pflege");
- m_Menu[0].set_LabelText(3, "Hilfe");
- m_Menu[0].set_LabelText(4, "Geräte");
- m_Menu[0].set_LabelText(5, "Funktionen");
-
- m_Menu.push_back(TactileMenu(6));
- m_Menu[1].set_LabelText(0, "Ja");
- m_Menu[1].set_LabelText(1, "Nein");
- m_Menu[1].set_LabelText(2, "Hunger");
- m_Menu[1].set_LabelText(3, "Lage");
- m_Menu[1].set_LabelText(4, "Müdigkeit");
- m_Menu[1].set_LabelText(5, "Hauptmenü");
-
- m_Menu.push_back(TactileMenu(6));
- m_Menu[2].set_LabelText(0, "Ja");
- m_Menu[2].set_LabelText(1, "Nein");
- m_Menu[2].set_LabelText(2, "Schmerzen");
- m_Menu[2].set_LabelText(3, "Atemnot");
- m_Menu[2].set_LabelText(4, "Anderes");
- m_Menu[2].set_LabelText(5, "Hauptmenü");
-
- m_Menu.push_back(TactileMenu(6));
- m_Menu[3].set_LabelText(0, "Ja");
- m_Menu[3].set_LabelText(1, "Nein");
- m_Menu[3].set_LabelText(2, "Atemgerät");
- m_Menu[3].set_LabelText(3, "Rollstuhl");
- m_Menu[3].set_LabelText(4, "Computer");
- m_Menu[3].set_LabelText(5, "Hauptmenü");
-
- //Set SubMenu ptr
- m_Menu[0].set_SubMenu(2, &m_Menu[1]);
- m_Menu[0].set_SubMenu(3, &m_Menu[2]);
- m_Menu[0].set_SubMenu(4, &m_Menu[3]);
- m_Menu[1].set_SubMenu(5, &m_Menu[0]);
- m_Menu[2].set_SubMenu(5, &m_Menu[0]);
- m_Menu[3].set_SubMenu(5, &m_Menu[0]);
-
- //Set current menu ptr to Mainmenu
- m_currMenu = &m_Menu[0];
+ this->getLogManager() << LogLevel_Warning << "Failed to connect to acquisition server TCP tagging.\n";
}
- else //Create default menu for m_nTactilos != 6
+
+ // ------ Gtk variables
+ // Build main UI elements
+ m_MainWidgetInterface = gtk_builder_new();
+ if(!gtk_builder_add_from_file(m_MainWidgetInterface, m_InterfaceFilename.toASCIIString(), nullptr))//error
+ {
+ this->getLogManager() << LogLevel_ImportantWarning << "Failed to load UI file [" << m_InterfaceFilename << "]\n";
+ this->getLogManager() << LogLevel_ImportantWarning << "Make sure, that the given filename and path are correct\n";
+ return(false);
+ }
+ m_MainWindow = GTK_WIDGET(gtk_builder_get_object(m_MainWidgetInterface, "p300-tactile-main"));
+ m_Table = GTK_TABLE(gtk_builder_get_object(m_MainWidgetInterface, "p300-tactile-table"));
+ m_ResultLabel = GTK_LABEL(gtk_builder_get_object(m_MainWidgetInterface, "label-result"));
+ m_TargetLabel = GTK_LABEL(gtk_builder_get_object(m_MainWidgetInterface, "label-target"));
+
+ // Create font description
+ m_FontDesc = pango_font_description_copy(pango_context_get_font_description(gtk_widget_get_pango_context(m_MainWindow)));
+ pango_font_description_set_size(m_FontDesc, gint(FontSize*PANGO_SCALE));
+
+ // test if the UI-file fits the number of tactilos
+ guint nRow = 0;
+ g_object_get(m_Table, "n-rows", &nRow, nullptr);
+ if(m_nTactilos != nRow)
+ {
+ this->getLogManager() << LogLevel_ImportantWarning << "The number of tactilos " << m_nTactilos<<" used and the number of rows "<< nRow << " in the ui file must be the same.\n";
+ this->getLogManager() << LogLevel_ImportantWarning << "Make sure to choose the right UI-File, e.g. p300-tactile-6.ui for 6 tactilos\n";
+ return(false);
+ }
+ else
+ {
+ for(uint64_t i = 0; i < m_nTactilos; i++)
+ {
+ std::string eventbox_id = "eventbox-" + std::to_string(i+1);
+
+ m_EventBox.push_back(GTK_WIDGET(gtk_builder_get_object(m_MainWidgetInterface, eventbox_id.c_str())));
+ }
+ }
+
+ // ------ Setup tactile UI
+ //Create UI for m_nTactilos = 6
+ if(m_nTactilos == 6)
+ {
+ //create free spelling UI for 6 tactilos
+ if(m_FreeSpelling)
+ {
+ m_Menu.push_back(TactileMenu(6));
+ m_Menu[0].set_LabelText(0, "Ja");
+ m_Menu[0].set_LabelText(1, "Nein");
+ m_Menu[0].set_LabelText(2, "Pflege");
+ m_Menu[0].set_LabelText(3, "Hilfe");
+ m_Menu[0].set_LabelText(4, "Geräte");
+ m_Menu[0].set_LabelText(5, "Funktionen");
+
+ m_Menu.push_back(TactileMenu(6));
+ m_Menu[1].set_LabelText(0, "Ja");
+ m_Menu[1].set_LabelText(1, "Nein");
+ m_Menu[1].set_LabelText(2, "Hunger");
+ m_Menu[1].set_LabelText(3, "Lage");
+ m_Menu[1].set_LabelText(4, "Müdigkeit");
+ m_Menu[1].set_LabelText(5, "Hauptmenü");
+
+ m_Menu.push_back(TactileMenu(6));
+ m_Menu[2].set_LabelText(0, "Ja");
+ m_Menu[2].set_LabelText(1, "Nein");
+ m_Menu[2].set_LabelText(2, "Schmerzen");
+ m_Menu[2].set_LabelText(3, "Atemnot");
+ m_Menu[2].set_LabelText(4, "Anderes");
+ m_Menu[2].set_LabelText(5, "Hauptmenü");
+
+ m_Menu.push_back(TactileMenu(6));
+ m_Menu[3].set_LabelText(0, "Ja");
+ m_Menu[3].set_LabelText(1, "Nein");
+ m_Menu[3].set_LabelText(2, "Atemgerät");
+ m_Menu[3].set_LabelText(3, "Rollstuhl");
+ m_Menu[3].set_LabelText(4, "Computer");
+ m_Menu[3].set_LabelText(5, "Hauptmenü");
+
+ //set SubMenu ptr
+ m_Menu[0].set_SubMenu(2, &m_Menu[1]);
+ m_Menu[0].set_SubMenu(3, &m_Menu[2]);
+ m_Menu[0].set_SubMenu(4, &m_Menu[3]);
+ m_Menu[1].set_SubMenu(5, &m_Menu[0]);
+ m_Menu[2].set_SubMenu(5, &m_Menu[0]);
+ m_Menu[3].set_SubMenu(5, &m_Menu[0]);
+
+ //set curr Menu ptr to main menu
+ m_CurrMenu = &m_Menu[0];
+ }
+ //create copy spelling UI for 6 tactilos
+ else
+ {
+ m_Menu.push_back(TactileMenu(6));
+ m_Menu[0].set_LabelText(0, "Hand links");
+ m_Menu[0].set_LabelText(1, "Arm links");
+ m_Menu[0].set_LabelText(2, "Brust links");
+ m_Menu[0].set_LabelText(3, "Brust rechts");
+ m_Menu[0].set_LabelText(4, "Arm rechts");
+ m_Menu[0].set_LabelText(5, "Hand rechts");
+
+ m_CurrMenu = &m_Menu[0];
+ }
+ }
+ //Create default UI for m_nTactilos != 6
+ else
{
m_Menu.push_back(TactileMenu(m_nTactilos));
- m_currMenu = &m_Menu[0];
+ m_CurrMenu = &m_Menu[0];
}
- //Init Gtk Labels
- for(int i = 0; i < m_nTactilos; i++)
+ // ------ Init UI
+ m_visualizationCtx = dynamic_cast(this->createPluginObject(OVP_ClassId_Plugin_VisualizationCtx));
+ m_visualizationCtx->setWidget(*this, m_MainWindow);
+
+ for(uint64_t i = 0; i < m_nTactilos; ++i)
{
- std::string label_id = "label-" + std::to_string(i+1);
- std::string label_text = m_currMenu->get_LabelText(i);
-
- m_Label.push_back(GTK_LABEL(gtk_builder_get_object(m_mainWidgetInterface, label_id.c_str())));
- gtk_label_set_text(m_Label[i], label_text.c_str());
- }
-
- //End Menu Initialization ---------------------------------------------------------------------------------------
-
- gtk_builder_connect_signals(m_mainWidgetInterface, nullptr);
- gtk_builder_connect_signals(m_toolbarWidgetInterface, nullptr);
-
- g_signal_connect(gtk_builder_get_object(m_toolbarWidgetInterface, "toolbutton-show_target_text"), "toggled", G_CALLBACK(ToggleButtonShowHideCB),
- gtk_builder_get_object(m_mainWidgetInterface, "label-target"));
- g_signal_connect(gtk_builder_get_object(m_toolbarWidgetInterface, "toolbutton-show_target_text"), "toggled", G_CALLBACK(ToggleButtonShowHideCB),
- gtk_builder_get_object(m_mainWidgetInterface, "label-target-title"));
- g_signal_connect(gtk_builder_get_object(m_toolbarWidgetInterface, "toolbutton-show_result_text"), "toggled", G_CALLBACK(ToggleButtonShowHideCB),
- gtk_builder_get_object(m_mainWidgetInterface, "label-result"));
- g_signal_connect(gtk_builder_get_object(m_toolbarWidgetInterface, "toolbutton-show_result_text"), "toggled", G_CALLBACK(ToggleButtonShowHideCB),
- gtk_builder_get_object(m_mainWidgetInterface, "label-result-title"));
-
- m_visualizationCtx = dynamic_cast(this->createPluginObject(
- OVP_ClassId_Plugin_VisualizationCtx));
- m_visualizationCtx->setWidget(*this, m_mainWindow);
- m_visualizationCtx->setToolbar(*this, m_toolbarWidget);
-
- guint nRow = 0, nCol = 0;
- g_object_get(m_table, "n-rows", &nRow, nullptr);
- g_object_get(m_table, "n-columns", &nCol, nullptr);
-
- m_nRow = nRow;
- m_nCol = nCol;
-
- PangoFontDescription* maxFontDesc = pango_font_description_copy(pango_context_get_font_description(gtk_widget_get_pango_context(m_mainWindow)));
- m_flashFontDesc = pango_font_description_copy(pango_context_get_font_description(gtk_widget_get_pango_context(m_mainWindow)));
- m_noFlashFontDesc = pango_font_description_copy(pango_context_get_font_description(gtk_widget_get_pango_context(m_mainWindow)));
- m_targetFontDesc = pango_font_description_copy(pango_context_get_font_description(gtk_widget_get_pango_context(m_mainWindow)));
- m_selectedFontDesc = pango_font_description_copy(pango_context_get_font_description(gtk_widget_get_pango_context(m_mainWindow)));
-
- uint64_t maxSize = 0;
- maxSize = std::max(maxSize, m_flashFontSize);
- maxSize = std::max(maxSize, m_noFlashFontSize);
- maxSize = std::max(maxSize, m_targetFontSize);
- maxSize = std::max(maxSize, m_selectedFontSize);
-
- pango_font_description_set_size(maxFontDesc, gint(maxSize * PANGO_SCALE));
- pango_font_description_set_size(m_flashFontDesc, gint(m_flashFontSize * PANGO_SCALE));
- pango_font_description_set_size(m_noFlashFontDesc, gint(m_noFlashFontSize * PANGO_SCALE));
- pango_font_description_set_size(m_targetFontDesc, gint(m_targetFontSize * PANGO_SCALE));
- pango_font_description_set_size(m_selectedFontDesc, gint(m_selectedFontSize * PANGO_SCALE));
-
- this->cacheBuildFromTable(m_table);
- this->cacheForEach(&CBoxAlgorithmP300TactileVisualization::cacheChangeBackgroundCB, &m_noFlashBgColor);
- this->cacheForEach(&CBoxAlgorithmP300TactileVisualization::cacheChangeForegroundCB, &m_noFlashFgColor);
- this->cacheForEach(&CBoxAlgorithmP300TactileVisualization::cacheChangeFontCB, maxFontDesc);
-
- pango_font_description_free(maxFontDesc);
-
- m_lastTargetRow = -1;
- m_lastTargetCol = -1;
- m_targetRow = -1;
- m_targetCol = -1;
- m_selectedRow = -1;
- m_selectedCol = -1;
-
- m_stimulusSender = TCPTagging::CreateStimulusSender();
-
- if (!m_stimulusSender->connect("localhost", "15361"))
- {
- this->getLogManager() << Kernel::LogLevel_Warning << "Unable to connect to AS TCP Tagging, stimuli wont be forwarded.\n";
+ resetColor();
+ gtk_widget_modify_font(gtk_bin_get_child(GTK_BIN(m_EventBox[i])), m_FontDesc);
}
- m_tableInitialized = false;
-
- return true;
+ toggleLabelText();
+
+ return(true);
}
+/*******************************************************************************/
bool CBoxAlgorithmP300TactileVisualization::uninitialize()
-{
- if (m_idleFuncTag)
+{
+ // ------ uninitialize decoder/encoder
+ m_SequenceInputDecoder.uninitialize();
+ m_TargetInputDecoder.uninitialize();
+ m_ResultInputDecoder.uninitialize();
+ m_ResultOutputEncoder.uninitialize();
+
+ // ------ uninitialize GTK UI
+ if (m_MainWidgetInterface)
+ {
+ g_object_unref(m_MainWidgetInterface);
+ m_MainWidgetInterface = nullptr;
+ }
+ if (m_visualizationCtx)
+ {
+ this->releasePluginObject(m_visualizationCtx);
+ }
+
+ // ------ uinitialize TCP Tagging
+ if (m_idleFuncTag != 0)
{
m_stimuliQueue.clear();
g_source_remove(m_idleFuncTag);
m_idleFuncTag = 0;
}
-
if (m_stimulusSender)
{
delete m_stimulusSender;
m_stimulusSender = nullptr;
}
- if (m_selectedFontDesc)
- {
- pango_font_description_free(m_selectedFontDesc);
- m_selectedFontDesc = nullptr;
- }
-
- if (m_targetFontDesc)
- {
- pango_font_description_free(m_targetFontDesc);
- m_targetFontDesc = nullptr;
- }
-
- if (m_noFlashFontDesc)
- {
- pango_font_description_free(m_noFlashFontDesc);
- m_noFlashFontDesc = nullptr;
- }
-
- if (m_flashFontDesc)
- {
- pango_font_description_free(m_flashFontDesc);
- m_flashFontDesc = nullptr;
- }
-
- if (m_toolbarWidgetInterface)
- {
- g_object_unref(m_toolbarWidgetInterface);
- m_toolbarWidgetInterface = nullptr;
- }
-
- if (m_mainWidgetInterface)
- {
- g_object_unref(m_mainWidgetInterface);
- m_mainWidgetInterface = nullptr;
- }
-
- m_targetFlaggingStimulationSet.uninitialize();
- m_targetFlaggingMemoryBuffer.uninitialize();
-
- m_targetStimulationSet.uninitialize();
- m_targetMemoryBuffer.uninitialize();
-
- m_sequenceStimulationSet.uninitialize();
- m_sequenceMemoryBuffer.uninitialize();
-
- if (m_columnSelectionStimulationDecoder)
- {
- m_columnSelectionStimulationDecoder->uninitialize();
- this->getAlgorithmManager().releaseAlgorithm(*m_columnSelectionStimulationDecoder);
- m_columnSelectionStimulationDecoder = nullptr;
- }
-
- if (m_rowSelectionStimulationDecoder)
- {
- m_rowSelectionStimulationDecoder->uninitialize();
- this->getAlgorithmManager().releaseAlgorithm(*m_rowSelectionStimulationDecoder);
- m_rowSelectionStimulationDecoder = nullptr;
- }
-
- if (m_targetFlaggingStimulationEncoder)
- {
- m_targetFlaggingStimulationEncoder->uninitialize();
- this->getAlgorithmManager().releaseAlgorithm(*m_targetFlaggingStimulationEncoder);
- m_targetFlaggingStimulationEncoder = nullptr;
-
- }
-
- if (m_targetStimulationDecoder)
- {
- m_targetStimulationDecoder->uninitialize();
- this->getAlgorithmManager().releaseAlgorithm(*m_targetStimulationDecoder);
- m_targetStimulationDecoder = nullptr;
- }
-
- if (m_sequenceStimulationDecoder)
- {
- m_sequenceStimulationDecoder->uninitialize();
- this->getAlgorithmManager().releaseAlgorithm(*m_sequenceStimulationDecoder);
- m_sequenceStimulationDecoder = nullptr;
- }
-
- if (m_visualizationCtx)
- {
- this->releasePluginObject(m_visualizationCtx);
- m_sequenceStimulationDecoder = nullptr;
- }
-
- return true;
+ return(true);
}
+/*******************************************************************************/
-bool CBoxAlgorithmP300TactileVisualization::processInput(const size_t /*index*/)
+
+bool CBoxAlgorithmP300TactileVisualization::processInput(const size_t index)
{
- this->getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
+ // ------ ready to process
+ getBoxAlgorithmContext()->markAlgorithmAsReadyToProcess();
- if (!m_tableInitialized)
- {
- this->cacheForEach(&CBoxAlgorithmP300TactileVisualization::cacheChangeBackgroundCB, &m_noFlashBgColor);
- this->cacheForEach(&CBoxAlgorithmP300TactileVisualization::cacheChangeForegroundCB, &m_noFlashFgColor);
- this->cacheForEach(&CBoxAlgorithmP300TactileVisualization::cacheChangeFontCB, m_noFlashFontDesc);
- m_tableInitialized = true;
- }
-
- return true;
+ return(true);
}
+/*******************************************************************************/
+
+
bool CBoxAlgorithmP300TactileVisualization::process()
{
- Kernel::IBoxIO& boxContext = this->getDynamicBoxContext();
+ const IBox& staticBoxContext=this->getStaticBoxContext();
+ IBoxIO& boxContext = this->getDynamicBoxContext();
+
+ //variables for processing of input chunks
+ uint64_t SequenceID = 0;
+ uint64_t TargetID = 0;
+ uint64_t ResultID = 0;
+ int Row = -1;
+ bool IsTarget = false;
+ bool TargetReceived = false;
+ bool ResultReceived = false;
+
+ //variables for forwarding of target stimulations
+ uint64_t ChunkStartTime = 0;
+ uint64_t ChunkEndTime = 0;
+ uint64_t Size = 0;
+ const uint8_t* Buffer = nullptr;
- // --- Sequence stimulations
-
- for (size_t i = 0; i < boxContext.getInputChunkCount(0); ++i)
+
+ // ------ Sequence stimulation
+ for(uint64_t i = 0; i < boxContext.getInputChunkCount(0); ++i)
{
- CStimulationSet flaggingStimulationSet;
-
- m_sequenceMemoryBuffer = boxContext.getInputChunk(0, i);
- m_targetFlaggingStimulationSet = &flaggingStimulationSet;
- m_targetFlaggingMemoryBuffer = boxContext.getOutputChunk(0);
-
- m_sequenceStimulationDecoder->process();
-
- m_lastTime = boxContext.getInputChunkEndTime(0, i);
-
- if (m_sequenceStimulationDecoder->isOutputTriggerActive(OVP_GD_Algorithm_StimulationDecoder_OutputTriggerId_ReceivedHeader))
+ m_SequenceInputDecoder.decode(i);
+ m_LastTime = boxContext.getInputChunkEndTime(0, i);
+
+ // if header received
+ if(m_SequenceInputDecoder.isHeaderReceived())
+ {}
+
+ // if buffer received
+ if(m_SequenceInputDecoder.isBufferReceived())
{
- m_targetFlaggingStimulationEncoder->process(OVP_GD_Algorithm_StimulationEncoder_InputTriggerId_EncodeHeader);
- }
-
- if (m_sequenceStimulationDecoder->isOutputTriggerActive(OVP_GD_Algorithm_StimulationDecoder_OutputTriggerId_ReceivedBuffer))
- {
- CStimulationSet* stimulationSet = m_sequenceStimulationSet;
- for (size_t j = 0; j < stimulationSet->size(); ++j)
+ //check received stimulations on sequence input
+ CStimulationSet* SequenceStimulationSet = m_SequenceInputDecoder.getOutputStimulationSet();
+ for(uint64_t j = 0; j < SequenceStimulationSet->size(); ++j)
{
- uint64_t id = stimulationSet->getId(j);
- bool flash = false;
- int row = -1;
- int col = -1;
- bool isTarget = false;
-
- if (id >= m_rowStimulationBase && id < m_rowStimulationBase + m_nRow)
+ SequenceID = SequenceStimulationSet->getId(j);
+
+ if(SequenceID >= m_RowBase && SequenceID < m_RowBase + m_nTactilos)
{
- row = int(id - m_rowStimulationBase);
- flash = true;
- isTarget = (row == m_lastTargetRow);
+ Row = SequenceID - m_RowBase;
+ IsTarget = (Row == (int)m_LastTarget);
}
- if (id >= m_columnStimulationBase && id < m_columnStimulationBase + m_nCol)
+ if(SequenceID == OVTK_StimulationId_VisualStimulationStart)
{
- col = int(id - m_columnStimulationBase);
- flash = true;
- isTarget = (col == m_lastTargetCol);
- }
- if (id == OVTK_StimulationId_VisualStimulationStop)
- {
- this->getLogManager() << Kernel::LogLevel_Debug << "Received OVTK_StimulationId_VisualStimulationStop - resets grid\n";
- this->cacheForEach(&CBoxAlgorithmP300TactileVisualization::cacheChangeBackgroundCB, &m_noFlashBgColor);
- this->cacheForEach(&CBoxAlgorithmP300TactileVisualization::cacheChangeForegroundCB, &m_noFlashFgColor);
- this->cacheForEach(&CBoxAlgorithmP300TactileVisualization::cacheChangeFontCB, m_noFlashFontDesc);
- }
- if (id == OVTK_StimulationId_Reset)
- {
- gtk_label_set_text(m_target, "");
- gtk_label_set_text(m_result, "");
- }
-
- if (flash)
- {
- this->cacheForEachIf(row, col, &CBoxAlgorithmP300TactileVisualization::cacheChangeBackgroundCB,
- &CBoxAlgorithmP300TactileVisualization::cacheChangeBackgroundCB, &m_flashBgColor, &m_noFlashBgColor);
- this->cacheForEachIf(row, col, &CBoxAlgorithmP300TactileVisualization::cacheChangeForegroundCB,
- &CBoxAlgorithmP300TactileVisualization::cacheChangeForegroundCB, &m_flashFgColor, &m_noFlashFgColor);
- this->cacheForEachIf(row, col, &CBoxAlgorithmP300TactileVisualization::cacheChangeFontCB,
- &CBoxAlgorithmP300TactileVisualization::cacheChangeFontCB, m_flashFontDesc, m_noFlashFontDesc);
-
- // We now know if this flash corresponds to the current target or not, merge this to the outgoing stimulation stream
- if (isTarget)
+ resetColor();
+ toggleFlashColor(Row);
+ if (IsTarget)
{
m_stimuliQueue.push_back(OVTK_StimulationId_Target);
- flaggingStimulationSet.push_back(OVTK_StimulationId_Target, stimulationSet->getDate(j), 0);
}
else
{
m_stimuliQueue.push_back(OVTK_StimulationId_NonTarget);
- flaggingStimulationSet.push_back(OVTK_StimulationId_NonTarget, stimulationSet->getDate(j), 0);
}
}
-
- // Pass the stimulation to the server also as-is. If its a flash, it can be differentiated from a 'target' spec because
- // its NOT between OVTK_StimulationId_RestStart and OVTK_StimulationId_RestStop stimuli in the generated P300 timeline.
- m_stimuliQueue.push_back(id);
- }
- m_targetFlaggingStimulationEncoder->process(OVP_GD_Algorithm_StimulationEncoder_InputTriggerId_EncodeBuffer);
- }
-
- if (m_sequenceStimulationDecoder->isOutputTriggerActive(OVP_GD_Algorithm_StimulationDecoder_OutputTriggerId_ReceivedEnd))
- {
- m_targetFlaggingStimulationEncoder->process(OVP_GD_Algorithm_StimulationEncoder_InputTriggerId_EncodeEnd);
- }
-
- boxContext.markInputAsDeprecated(0, i);
- boxContext.markOutputAsReadyToSend(0, boxContext.getInputChunkStartTime(0, i), boxContext.getInputChunkEndTime(0, i));
- }
-
- // --- Target stimulations
-
- for (size_t i = 0; i < boxContext.getInputChunkCount(1); ++i)
- {
- if (m_lastTime >= boxContext.getInputChunkStartTime(1, i))
- {
- m_targetMemoryBuffer = boxContext.getInputChunk(1, i);
- m_targetStimulationDecoder->process();
-
- if (m_targetStimulationDecoder->isOutputTriggerActive(OVP_GD_Algorithm_StimulationDecoder_OutputTriggerId_ReceivedHeader)) { }
-
- if (m_targetStimulationDecoder->isOutputTriggerActive(OVP_GD_Algorithm_StimulationDecoder_OutputTriggerId_ReceivedBuffer))
- {
- CStimulationSet* stimulationSet = m_targetStimulationSet;
- for (size_t j = 0; j < stimulationSet->size(); ++j)
+ if(SequenceID == OVTK_StimulationId_VisualStimulationStop)
{
- uint64_t id = stimulationSet->getId(j);
- bool target = false;
- if (id >= m_rowStimulationBase && id < m_rowStimulationBase + m_nRow)
+ resetColor();
+ }
+ if(SequenceID == OVTK_StimulationId_SegmentStart)
+ {
+ toggleLabelText();
+ }
+
+ m_stimuliQueue.push_back(SequenceID);
+ }
+ }
+
+ // if end received
+ if(m_SequenceInputDecoder.isEndReceived())
+ {}
+
+ boxContext.markInputAsDeprecated(0, i);
+ }
+
+ // ------ Target stimulation
+ for(uint64_t i = 0; i < boxContext.getInputChunkCount(1); ++i)
+ {
+ if(m_LastTime >= boxContext.getInputChunkStartTime(1, i))
+ {
+ m_TargetInputDecoder.decode(i);
+
+ // if header received
+ if(m_SequenceInputDecoder.isHeaderReceived())
+ {}
+
+ // if buffer received
+ if(m_SequenceInputDecoder.isBufferReceived())
+ {
+ // check received dtimulations on Target input
+ CStimulationSet* TargetStimulationSet = m_TargetInputDecoder.getOutputStimulationSet();
+ for(uint64_t j = 0; j < TargetStimulationSet->size(); ++j)
+ {
+ TargetID = TargetStimulationSet->getId(j);
+
+ if(TargetID >= m_RowBase && TargetID < m_RowBase + m_nTactilos)
{
- this->getLogManager() << Kernel::LogLevel_Debug << "Received Target Row " << id << "\n";
- m_targetRow = int(id - m_rowStimulationBase);
- target = true;
+ Row = TargetID - m_RowBase;
+ TargetReceived = true;
}
- if (id >= m_columnStimulationBase && id < m_columnStimulationBase + m_nCol)
+ if(TargetReceived)
{
- this->getLogManager() << Kernel::LogLevel_Debug << "Received Target Column " << id << "\n";
- m_targetCol = int(id - m_columnStimulationBase);
- target = true;
- }
-
- if (target && m_targetRow != -1 && m_targetCol != -1)
- {
- this->getLogManager() << Kernel::LogLevel_Debug << "Displays Target Cell\n";
- this->cacheForEachIf(m_targetRow, m_targetCol, &CBoxAlgorithmP300TactileVisualization::cacheChangeBackgroundCB,
- &CBoxAlgorithmP300TactileVisualization::cacheChangeNullCB, &m_targetBgColor, nullptr);
- this->cacheForEachIf(m_targetRow, m_targetCol, &CBoxAlgorithmP300TactileVisualization::cacheChangeForegroundCB,
- &CBoxAlgorithmP300TactileVisualization::cacheChangeNullCB, &m_targetFgColor, nullptr);
- this->cacheForEachIf(m_targetRow, m_targetCol, &CBoxAlgorithmP300TactileVisualization::cacheChangeFontCB,
- &CBoxAlgorithmP300TactileVisualization::cacheChangeNullCB, m_targetFontDesc, nullptr);
-
- std::vector widgets;
- this->cacheForEachIf(m_targetRow, m_targetCol, &CBoxAlgorithmP300TactileVisualization::cacheCollectChildWidgetCB,
- &CBoxAlgorithmP300TactileVisualization::cacheCollectChildWidgetCB, &widgets, nullptr);
-
- // Merge the current target into the stimulation stream. It can be differentiated
- // from a 'flash' spec because it IS between OVTK_StimulationId_RestStart and
- // OVTK_StimulationId_RestStop stimulations in the P300 timeline.
- {
- m_stimuliQueue.push_back(m_targetRow + m_rowStimulationBase);
- m_stimuliQueue.push_back(m_targetCol + m_columnStimulationBase);
- }
-
- if (widgets.size() == 1)
- {
- if (GTK_IS_LABEL(widgets[0]))
- {
- std::string label;
- label = gtk_label_get_text(m_target);
- label += gtk_label_get_text(GTK_LABEL(widgets[0]));
- gtk_label_set_text(m_target, label.c_str());
- }
- else
- {
- this->getLogManager() << Kernel::LogLevel_Warning << "Expected label class widget... could not find a valid text to append\n";
- }
- }
- else
- {
- this->getLogManager() << Kernel::LogLevel_Warning << "Did not find a unique widget at row:" << size_t(m_targetRow) << " column:" <<
- size_t(m_targetCol) << "\n";
- }
-
- m_targetHistory.emplace_back(m_targetRow, m_targetCol);
- m_lastTargetRow = m_targetRow;
- m_lastTargetCol = m_targetCol;
- m_targetRow = -1;
- m_targetCol = -1;
+ toggleTargetColor(Row);
+ m_stimuliQueue.push_back(TargetID);
+
+ std::string TargetLabel = gtk_label_get_text(m_TargetLabel);
+ TargetLabel += gtk_label_get_text(GTK_LABEL(gtk_bin_get_child(GTK_BIN(m_EventBox[Row]))));
+ gtk_label_set_text(m_TargetLabel, TargetLabel.c_str());
+
+ m_LastTarget = Row;
}
}
}
-
- if (m_targetStimulationDecoder->isOutputTriggerActive(OVP_GD_Algorithm_StimulationDecoder_OutputTriggerId_ReceivedEnd)) { }
-
+
+ // if end received
+ if(m_SequenceInputDecoder.isEndReceived())
+ {}
+
boxContext.markInputAsDeprecated(1, i);
}
}
-
- // --- Selection stimulations
-
- for (size_t k = 2; k < 4; ++k)
+
+ // ------ Result stimulation
+ for(uint64_t i = 0; i < boxContext.getInputChunkCount(2); ++i)
{
- Kernel::IAlgorithmProxy* decoder = (k == 2 ? m_rowSelectionStimulationDecoder : m_columnSelectionStimulationDecoder);
- Kernel::TParameterHandler selectionMemoryBuffer(
- decoder->getInputParameter(OVP_GD_Algorithm_StimulationDecoder_InputParameterId_MemoryBufferToDecode));
- Kernel::TParameterHandler selectionStimulationSet(
- decoder->getOutputParameter(OVP_GD_Algorithm_StimulationDecoder_OutputParameterId_StimulationSet));
-
- for (size_t i = 0; i < boxContext.getInputChunkCount(k); ++i)
+ if(m_LastTime >= boxContext.getInputChunkStartTime(2, i))
{
- if (m_lastTime >= boxContext.getInputChunkStartTime(k, i))
+ m_ResultInputDecoder.decode(i);
+
+ // if header received
+ if(m_SequenceInputDecoder.isHeaderReceived())
+ {}
+
+ // if buffer received
+ if(m_SequenceInputDecoder.isBufferReceived())
{
- selectionMemoryBuffer = boxContext.getInputChunk(k, i);
- decoder->process();
-
- if (decoder->isOutputTriggerActive(OVP_GD_Algorithm_StimulationDecoder_OutputTriggerId_ReceivedHeader)) { }
-
- if (decoder->isOutputTriggerActive(OVP_GD_Algorithm_StimulationDecoder_OutputTriggerId_ReceivedBuffer))
+ // check received stimulations on result input
+ CStimulationSet* ResultStimulationSet = m_ResultInputDecoder.getOutputStimulationSet();
+ for(uint64_t j = 0; j < ResultStimulationSet->size(); ++j)
{
- CStimulationSet* stimulationSet = selectionStimulationSet;
- for (size_t j = 0; j < stimulationSet->size(); ++j)
+ ResultID = ResultStimulationSet->getId(j);
+
+ if(ResultID >= m_RowBase && ResultID < m_RowBase + m_nTactilos)
{
- uint64_t id = stimulationSet->getId(j);
- bool selected = false;
- if (id >= m_rowStimulationBase && id < m_rowStimulationBase + m_nRow)
- {
- this->getLogManager() << Kernel::LogLevel_Debug << "Received Selected Row " << id << "\n";
- m_selectedRow = int(id - m_rowStimulationBase);
- selected = true;
- }
- if (id >= m_columnStimulationBase && id < m_columnStimulationBase + m_nRow)
- {
- this->getLogManager() << Kernel::LogLevel_Debug << "Received Selected Column " << id << "\n";
- m_selectedCol = int(id - m_columnStimulationBase);
- selected = true;
- }
- if (id == OVTK_StimulationId_Label_00)
- {
- if (k == 2) { m_selectedRow = -2; }
- if (k == 3) { m_selectedCol = -2; }
- selected = true;
- }
- if (selected && m_selectedRow != -1 && m_selectedCol != -1)
- {
- if (m_selectedRow >= 0 && m_selectedCol >= 0)
- {
- this->getLogManager() << Kernel::LogLevel_Debug << "Displays Selected Cell\n";
- this->cacheForEachIf(m_selectedRow, m_selectedCol, &CBoxAlgorithmP300TactileVisualization::cacheChangeBackgroundCB,
- &CBoxAlgorithmP300TactileVisualization::cacheChangeNullCB, &m_selectedBgColor, nullptr);
- this->cacheForEachIf(m_selectedRow, m_selectedCol, &CBoxAlgorithmP300TactileVisualization::cacheChangeForegroundCB,
- &CBoxAlgorithmP300TactileVisualization::cacheChangeNullCB, &m_selectedFgColor, nullptr);
- this->cacheForEachIf(m_selectedRow, m_selectedCol, &CBoxAlgorithmP300TactileVisualization::cacheChangeFontCB,
- &CBoxAlgorithmP300TactileVisualization::cacheChangeNullCB, m_selectedFontDesc, nullptr);
-
- std::vector widgets;
- this->cacheForEachIf(m_selectedRow, m_selectedCol, &CBoxAlgorithmP300TactileVisualization::cacheCollectChildWidgetCB,
- &CBoxAlgorithmP300TactileVisualization::cacheCollectChildWidgetCB, &widgets, nullptr);
-
- if (widgets.size() == 1)
- {
- if (GTK_IS_LABEL(widgets[0]))
- {
- std::string label;
- label = gtk_label_get_text(GTK_LABEL(widgets[0]));
- if (!m_targetHistory.empty())
- {
- auto it = m_targetHistory.begin();
- bool correct = (it->first == m_selectedRow && it->second == m_selectedCol);
- bool halfCorrect = (it->first == m_selectedRow || it->second == m_selectedCol);
- m_targetHistory.pop_front();
- std::string tmp;
- if (correct) { tmp = ""; }
- else if (halfCorrect) { tmp = ""; }
- else { tmp = ""; }
- label = tmp.append(label).append("");
- }
- label = std::string(gtk_label_get_label(m_result)).append(label);
- gtk_label_set_markup(m_result, label.c_str());
- }
- else
- {
- this->getLogManager() << Kernel::LogLevel_Warning <<
- "Expected label class widget... could not find a valid text to append\n";
- }
- }
- else
- {
- this->getLogManager() << Kernel::LogLevel_Warning << "Did not find a unique widget at row : " << size_t(m_selectedRow) <<
- " column : " << size_t(m_selectedCol) << "\n";
- }
- //Switch Menu
- if(m_currMenu->get_SubMenu(m_selectedRow) != nullptr)
- {
- m_currMenu = m_currMenu->get_SubMenu(m_selectedRow);
- for(uint64_t i = 0; i < m_nTactilos; i++)
- {
- std::string label_text = m_currMenu->get_LabelText(i);
-
- gtk_label_set_text(m_Label[i], label_text.c_str());
- }
- }
- }
- else
- {
- this->getLogManager() << Kernel::LogLevel_Trace << "Selection Rejected !\n";
- std::string label;
- label = gtk_label_get_text(m_result);
- label += "*";
- gtk_label_set_text(m_result, label.c_str());
- }
+ Row = ResultID - m_RowBase;
+ ResultReceived = true;
+ }
+ if(ResultReceived)
+ {
+ toggleResultColor(Row);
- m_selectedRow = -1;
- m_selectedCol = -1;
- }
+ std::string ResultLabel = gtk_label_get_text(m_ResultLabel);
+ ResultLabel += gtk_label_get_text(GTK_LABEL(gtk_bin_get_child(GTK_BIN(m_EventBox[Row]))));
+ gtk_label_set_text(m_ResultLabel, ResultLabel.c_str());
+
+ //switch current menu ptr to submenu
+ if(m_CurrMenu->get_SubMenu(Row) != nullptr)
+ {
+ m_CurrMenu = m_CurrMenu->get_SubMenu(Row);
+ }
}
}
-
- if (decoder->isOutputTriggerActive(OVP_GD_Algorithm_StimulationDecoder_OutputTriggerId_ReceivedEnd)) { }
- boxContext.markInputAsDeprecated(k, i);
}
- }
+
+ // if end received
+ if(m_SequenceInputDecoder.isEndReceived())
+ {}
+
+ // forward target stimulations
+ boxContext.getInputChunk(2, i, ChunkStartTime, ChunkEndTime, Size, Buffer);
+ boxContext.appendOutputChunkData(0, Buffer, Size);
+ boxContext.markOutputAsReadyToSend(0, ChunkStartTime, ChunkEndTime);
+ boxContext.markInputAsDeprecated(2, i);
+
+ }
}
- // After any possible rendering, we flush the accumulated stimuli. The default idle func is low priority, so it should be run after rendering by gtk.
- if (m_idleFuncTag == 0) { m_idleFuncTag = g_idle_add(FlushCB, this); }
-
- return true;
-}
-// _________________________________________________________________________________________________________________________________________________________
-//
-
-void CBoxAlgorithmP300TactileVisualization::cacheBuildFromTable(GtkTable* table)
-{
- if (table)
+ // ------ Send accumulated stimuli to the acquisition server
+ if(m_idleFuncTag == 0)
{
- const GdkColor white = InitGDKColor(65535, 65535, 65535, 65535);
-
- for (GList* list = table->children; list; list = list->next)
- {
- GtkTableChild* child = static_cast(list->data);
-
- for (size_t i = child->top_attach; i < child->bottom_attach; ++i)
- {
- for (size_t j = child->left_attach; j < child->right_attach; ++j)
- {
- widget_style_t& style = m_cache[i][j];
- style.widget = child->widget;
- style.childWidget = gtk_bin_get_child(GTK_BIN(child->widget));
- style.bgColor = white;
- style.fgColor = white;
- style.fontDesc = nullptr;
- }
- }
- }
+ m_idleFuncTag = g_idle_add(FlushCB, this);
}
+
+ return(true);
}
-void CBoxAlgorithmP300TactileVisualization::cacheForEach(const cache_callback callback, void* data)
-{
- for (auto i = m_cache.begin(); i != m_cache.end(); ++i)
- {
- for (auto j = i->second.begin(); j != i->second.end(); ++j) { (this->*callback)(j->second, data); }
- }
-}
-void CBoxAlgorithmP300TactileVisualization::cacheForEachIf(const int iLine, const int iColumn, const cache_callback ifCB, const cache_callback elseCB,
- void* ifUserData, void* elseUserData)
-{
- for (auto i = m_cache.begin(); i != m_cache.end(); ++i)
- {
- for (auto j = i->second.begin(); j != i->second.end(); ++j)
- {
- const bool line = (iLine != -1);
- const bool column = (iColumn != -1);
- bool inLine = false;
- bool inCol = false;
- bool first;
- if (line && size_t(iLine) == i->first) { inLine = true; }
- if (column && size_t(iColumn) == j->first) { inCol = true; }
+// ------ Function Definitions
- if (line && column) { first = inLine && inCol; }
- else { first = inLine || inCol; }
- if (first) { (this->*ifCB)(j->second, ifUserData); }
- else { (this->*elseCB)(j->second, elseUserData); }
- }
- }
-}
-
-void CBoxAlgorithmP300TactileVisualization::cacheChangeNullCB(widget_style_t& /*rWidgetStyle*/, void* /*data*/) { }
-
-void CBoxAlgorithmP300TactileVisualization::cacheChangeBackgroundCB(widget_style_t& style, void* data)
-{
- GdkColor oColor = *static_cast(data);
- if (memcmp(&style.bgColor, &oColor, sizeof(GdkColor)) != 0)
- {
- gtk_widget_modify_bg(style.widget, GTK_STATE_NORMAL, &oColor);
- style.bgColor = oColor;
- }
-}
-
-void CBoxAlgorithmP300TactileVisualization::cacheChangeForegroundCB(widget_style_t& style, void* data)
-{
- GdkColor oColor = *static_cast(data);
- if (memcmp(&style.fgColor, &oColor, sizeof(GdkColor)) != 0)
- {
- gtk_widget_modify_fg(style.childWidget, GTK_STATE_NORMAL, &oColor);
- style.fgColor = oColor;
- }
-}
-
-void CBoxAlgorithmP300TactileVisualization::cacheChangeFontCB(widget_style_t& style, void* data)
-{
- auto* pFontDescription = static_cast(data);
- if (style.fontDesc != pFontDescription)
- {
- gtk_widget_modify_font(style.childWidget, pFontDescription);
- style.fontDesc = pFontDescription;
- }
-}
-
-void CBoxAlgorithmP300TactileVisualization::cacheCollectWidgetCB(widget_style_t& style, void* data)
-{
- if (data) { (static_cast*>(data))->push_back(style.widget); }
-}
-
-void CBoxAlgorithmP300TactileVisualization::cacheCollectChildWidgetCB(widget_style_t& style, void* data)
-{
- if (data) { (static_cast*>(data))->push_back(style.childWidget); }
-}
-
-// Note that we don't need concurrency control here as gtk callbacks run in the main thread
+// Sends all accumulated stimuli to the TCP Tagging
void CBoxAlgorithmP300TactileVisualization::flushQueue()
{
- for (const auto& stimulation : m_stimuliQueue) { m_stimulusSender->sendStimulation(stimulation); }
+ for (const auto& stimulation : m_stimuliQueue)
+ {
+ m_stimulusSender->sendStimulation(stimulation);
+ }
m_stimuliQueue.clear();
// This function will be automatically removed after completion, so set to 0
m_idleFuncTag = 0;
}
-} // namespace Tactilebci
-} // namespace Plugins
-} // namespace OpenViBE
+
+// Change labels fore-/background
+void CBoxAlgorithmP300TactileVisualization::toggleFlashColor(uint64_t id)
+{
+ gtk_widget_modify_fg(gtk_bin_get_child(GTK_BIN(m_EventBox[id])), GTK_STATE_NORMAL, &m_FlashFG);
+ gtk_widget_modify_bg(m_EventBox[id], GTK_STATE_NORMAL, &m_FlashBG);
+}
+
+void CBoxAlgorithmP300TactileVisualization::toggleTargetColor(uint64_t id)
+{
+ gtk_widget_modify_fg(gtk_bin_get_child(GTK_BIN(m_EventBox[id])), GTK_STATE_NORMAL, &m_TargetFG);
+ gtk_widget_modify_bg(m_EventBox[id], GTK_STATE_NORMAL, &m_TargetBG);
+}
+
+void CBoxAlgorithmP300TactileVisualization::toggleResultColor(uint64_t id)
+{
+ gtk_widget_modify_fg(gtk_bin_get_child(GTK_BIN(m_EventBox[id])), GTK_STATE_NORMAL, &m_ResultFG);
+ gtk_widget_modify_bg(m_EventBox[id], GTK_STATE_NORMAL, &m_ResultBG);
+}
+
+void CBoxAlgorithmP300TactileVisualization::resetColor()
+{
+ for(uint64_t i = 0; i < m_nTactilos; i++)
+ {
+ gtk_widget_modify_fg(gtk_bin_get_child(GTK_BIN(m_EventBox[i])), GTK_STATE_NORMAL, &m_NoFlashFG);
+ gtk_widget_modify_bg(m_EventBox[i], GTK_STATE_NORMAL, &m_NoFlashBG);
+ }
+}
+
+
+// Change label text
+void CBoxAlgorithmP300TactileVisualization::toggleLabelText()
+{
+ for(uint64_t i = 0; i < m_nTactilos; i++)
+ {
+ std::string label_text = m_CurrMenu->get_LabelText(i);
+
+ gtk_label_set_text(GTK_LABEL(gtk_bin_get_child(GTK_BIN(m_EventBox[i]))), label_text.c_str());
+ }
+}
\ No newline at end of file
diff --git a/src/TactileVisualization/ovpCBoxAlgorithmP300TactileVisualization.h b/src/TactileVisualization/ovpCBoxAlgorithmP300TactileVisualization.h
index 9ff0502..631b028 100644
--- a/src/TactileVisualization/ovpCBoxAlgorithmP300TactileVisualization.h
+++ b/src/TactileVisualization/ovpCBoxAlgorithmP300TactileVisualization.h
@@ -1,208 +1,162 @@
///-------------------------------------------------------------------------------------------------
///
-/// \file ovpCBoxAlgorithmP300TactileVisualization.h
-/// \brief Classes of the Box P300 Tactile Visualization. !!This is a modification of the P300 Speller Visualization Box!!
+/// \file CBoxAlgorithmP300TactileVisualization.h
+/// \brief Classes of the Box P300TactileVisualization.
/// \author Tobias Baumann (TH Nuernberg).
/// \version 1.0.
-/// \date Mon Feb 04 12:43:53 2022.
+/// \date Sat May 07 14:20:29 2022.
/// \copyright GNU Affero General Public License v3.0.
///
///-------------------------------------------------------------------------------------------------
-//includes
#pragma once
-#include "TactileMenu.h"
+//You may have to change this path to match your folder organisation
#include "../ovp_defines.h"
+#include "TactileMenu.h"
#include
#include
+#include
#include
#include
#include
#include