From f115270f68eacc79c1cfdbb7c1a7306a65d4d997 Mon Sep 17 00:00:00 2001
From: Gergo Koteles <soyer@irl.hu>
Date: Tue, 26 Nov 2024 00:32:58 +0100
Subject: [PATCH]  add MIDI Button actions

---
 src/config.cpp    | 69 +++++++++++++++++++++++++++++++++++++++++++++++
 src/config.h      | 28 +++++++++++++++++++
 src/minidexed.ini | 11 ++++++++
 src/uibuttons.cpp | 21 +++++++++++----
 src/uibuttons.h   | 12 +++++++++
 5 files changed, 136 insertions(+), 5 deletions(-)

diff --git a/src/config.cpp b/src/config.cpp
index 482b2b2..7f5d040 100644
--- a/src/config.cpp
+++ b/src/config.cpp
@@ -178,18 +178,32 @@ void CConfig::Load (void)
 
 	m_nMIDIButtonCh = m_Properties.GetNumber ("MIDIButtonCh", 0);
 	m_nMIDIButtonNotes = m_Properties.GetNumber ("MIDIButtonNotes", 0);
+
 	m_nMIDIButtonPrev = m_Properties.GetNumber ("MIDIButtonPrev", 0);
 	m_nMIDIButtonNext = m_Properties.GetNumber ("MIDIButtonNext", 0);
 	m_nMIDIButtonBack = m_Properties.GetNumber ("MIDIButtonBack", 0);
 	m_nMIDIButtonSelect = m_Properties.GetNumber ("MIDIButtonSelect", 0);
 	m_nMIDIButtonHome = m_Properties.GetNumber ("MIDIButtonHome", 0);
 
+	m_MIDIButtonActionPrev = m_Properties.GetString ("MIDIButtonActionPrev", "");
+	m_MIDIButtonActionNext = m_Properties.GetString ("MIDIButtonActionNext", "");
+	m_MIDIButtonActionBack = m_Properties.GetString ("MIDIButtonActionBack", "");
+	m_MIDIButtonActionSelect = m_Properties.GetString ("MIDIButtonActionSelect", "");
+	m_MIDIButtonActionHome = m_Properties.GetString ("MIDIButtonActionHome", "");
+
 	m_nMIDIButtonPgmUp = m_Properties.GetNumber ("MIDIButtonPgmUp", 0);
 	m_nMIDIButtonPgmDown = m_Properties.GetNumber ("MIDIButtonPgmDown", 0);
 	m_nMIDIButtonBankUp = m_Properties.GetNumber ("MIDIButtonBankUp", 0);
 	m_nMIDIButtonBankDown = m_Properties.GetNumber ("MIDIButtonBankDown", 0);
 	m_nMIDIButtonTGUp = m_Properties.GetNumber ("MIDIButtonTGUp", 0);
 	m_nMIDIButtonTGDown = m_Properties.GetNumber ("MIDIButtonTGDown", 0);
+
+	m_MIDIButtonActionPgmUp = m_Properties.GetString ("MIDIButtonActionPgmUp", "");
+	m_MIDIButtonActionPgmDown = m_Properties.GetString ("MIDIButtonActionPgmDown", "");
+	m_MIDIButtonActionBankUp = m_Properties.GetString ("MIDIButtonActionBankUp", "");
+	m_MIDIButtonActionBankDown = m_Properties.GetString ("MIDIButtonActionBankDown", "");
+	m_MIDIButtonActionTGUp = m_Properties.GetString ("MIDIButtonActionTGUp", "");
+	m_MIDIButtonActionTGDown = m_Properties.GetString ("MIDIButtonActionTGDown", "");
 	
 	m_bEncoderEnabled = m_Properties.GetNumber ("EncoderEnabled", 0) != 0;
 	m_nEncoderPinClock = m_Properties.GetNumber ("EncoderPinClock", 10);
@@ -652,6 +666,31 @@ unsigned CConfig::GetMIDIButtonHome (void) const
 	return m_nMIDIButtonHome;
 }
 
+const char *CConfig::GetMIDIButtonActionPrev (void) const
+{
+	return m_MIDIButtonActionPrev.c_str();
+}
+
+const char *CConfig::GetMIDIButtonActionNext (void) const
+{
+	return m_MIDIButtonActionNext.c_str();
+}
+
+const char *CConfig::GetMIDIButtonActionBack (void) const
+{
+	return m_MIDIButtonActionBack.c_str();
+}
+
+const char *CConfig::GetMIDIButtonActionSelect (void) const
+{
+	return m_MIDIButtonActionSelect.c_str();
+}
+
+const char *CConfig::GetMIDIButtonActionHome (void) const
+{
+	return m_MIDIButtonActionHome.c_str();
+}
+
 unsigned CConfig::GetMIDIButtonPgmUp (void) const
 {
 	return m_nMIDIButtonPgmUp;
@@ -682,6 +721,36 @@ unsigned CConfig::GetMIDIButtonTGDown (void) const
 	return m_nMIDIButtonTGDown;
 }
 
+const char *CConfig::GetMIDIButtonActionPgmUp (void) const
+{
+	return m_MIDIButtonActionPgmUp.c_str();
+}
+
+const char *CConfig::GetMIDIButtonActionPgmDown (void) const
+{
+	return m_MIDIButtonActionPgmDown.c_str();
+}
+
+const char *CConfig::GetMIDIButtonActionBankUp (void) const
+{
+	return m_MIDIButtonActionBankUp.c_str();
+}
+
+const char *CConfig::GetMIDIButtonActionBankDown (void) const
+{
+	return m_MIDIButtonActionBankDown.c_str();
+}
+
+const char *CConfig::GetMIDIButtonActionTGUp (void) const
+{
+	return m_MIDIButtonActionTGUp.c_str();
+}
+
+const char *CConfig::GetMIDIButtonActionTGDown (void) const
+{
+	return m_MIDIButtonActionTGDown.c_str();
+}
+
 bool CConfig::GetEncoderEnabled (void) const
 {
 	return m_bEncoderEnabled;
diff --git a/src/config.h b/src/config.h
index 5d0cbc1..f7da3ef 100644
--- a/src/config.h
+++ b/src/config.h
@@ -210,12 +210,20 @@ public:
 	// MIDI Button Navigation
 	unsigned GetMIDIButtonCh   (void) const;
 	unsigned GetMIDIButtonNotes (void) const;
+
 	unsigned GetMIDIButtonPrev (void) const;
 	unsigned GetMIDIButtonNext (void) const;
 	unsigned GetMIDIButtonBack (void) const;
 	unsigned GetMIDIButtonSelect (void) const;
 	unsigned GetMIDIButtonHome (void) const;
 
+	// Action type for Midi buttons: "click", "doubleclick", "longpress", ""
+	const char *GetMIDIButtonActionPrev (void) const;
+	const char *GetMIDIButtonActionNext (void) const;
+	const char *GetMIDIButtonActionBack (void) const;
+	const char *GetMIDIButtonActionSelect (void) const;
+	const char *GetMIDIButtonActionHome (void) const;
+
 	// MIDI Button Program and TG Selection
 	unsigned GetMIDIButtonPgmUp (void) const;
 	unsigned GetMIDIButtonPgmDown (void) const;
@@ -224,6 +232,14 @@ public:
 	unsigned GetMIDIButtonTGUp (void) const;
 	unsigned GetMIDIButtonTGDown (void) const;
 	
+	// Action type for buttons: "click", "doubleclick", "longpress", ""
+	const char *GetMIDIButtonActionPgmUp (void) const;
+	const char *GetMIDIButtonActionPgmDown (void) const;
+	const char *GetMIDIButtonActionBankUp (void) const;
+	const char *GetMIDIButtonActionBankDown (void) const;
+	const char *GetMIDIButtonActionTGUp (void) const;
+	const char *GetMIDIButtonActionTGDown (void) const;
+
 	// KY-040 Rotary Encoder
 	// GPIO pin numbers are chip numbers, not header positions
 	bool GetEncoderEnabled (void) const;
@@ -326,6 +342,18 @@ private:
 	std::string m_ButtonActionTGUp;
 	std::string m_ButtonActionTGDown;
 	
+	std::string m_MIDIButtonActionPrev;
+	std::string m_MIDIButtonActionNext;
+	std::string m_MIDIButtonActionBack;
+	std::string m_MIDIButtonActionSelect;
+	std::string m_MIDIButtonActionHome;
+	std::string m_MIDIButtonActionPgmUp;
+	std::string m_MIDIButtonActionPgmDown;
+	std::string m_MIDIButtonActionBankUp;
+	std::string m_MIDIButtonActionBankDown;
+	std::string m_MIDIButtonActionTGUp;
+	std::string m_MIDIButtonActionTGDown;
+
 	unsigned m_nDoubleClickTimeout;
 	unsigned m_nLongPressTimeout;
 
diff --git a/src/minidexed.ini b/src/minidexed.ini
index 5b6b13d..57eac0f 100644
--- a/src/minidexed.ini
+++ b/src/minidexed.ini
@@ -124,20 +124,31 @@ MIDIButtonCh=17
 MIDIButtonNotes=0
 # Arrow left
 MIDIButtonPrev=46
+MIDIButtonActionPrev=click
 # Arrow right
 MIDIButtonNext=47
+MIDIButtonActionNext=click
 # Arrow up
 MIDIButtonBack=48
+MIDIButtonActionBack=click
 # Arrow down
 MIDIButtonSelect=49
+MIDIButtonActionSelect=click
 # Home button
 MIDIButtonHome=50
+MIDIButtonActionHome=click
 MIDIButtonPgmUp=51
+MIDIButtonActionPgmUp=click
 MIDIButtonPgmDown=52
+MIDIButtonActionPgmDown=click
 MIDIButtonBankUp=53
+MIDIButtonActionBankUp=click
 MIDIButtonBankDown=54
+MIDIButtonActionBankDown=click
 MIDIButtonTGUp=55
+MIDIButtonActionTGUp=click
 MIDIButtonTGDown=56
+MIDIButtonActionTGDown=click
 
 # KY-040 Rotary Encoder
 EncoderEnabled=1
diff --git a/src/uibuttons.cpp b/src/uibuttons.cpp
index ae206dc..3df7f4b 100644
--- a/src/uibuttons.cpp
+++ b/src/uibuttons.cpp
@@ -299,17 +299,28 @@ boolean CUIButtons::Initialize (void)
 	m_TGDownAction = CUIButton::triggerTypeFromString( m_pConfig->GetButtonActionTGDown ());
 	m_notesMidi = ccToMidiPin( m_pConfig->GetMIDIButtonNotes ());
 	m_prevMidi = ccToMidiPin( m_pConfig->GetMIDIButtonPrev ());
+	m_prevMidiAction = CUIButton::triggerTypeFromString( m_pConfig->GetMIDIButtonActionPrev ());
 	m_nextMidi = ccToMidiPin( m_pConfig->GetMIDIButtonNext ());
+	m_nextMidiAction = CUIButton::triggerTypeFromString( m_pConfig->GetMIDIButtonActionNext ());
 	m_backMidi = ccToMidiPin( m_pConfig->GetMIDIButtonBack ());
+	m_backMidiAction = CUIButton::triggerTypeFromString( m_pConfig->GetMIDIButtonActionBack ());
 	m_selectMidi = ccToMidiPin( m_pConfig->GetMIDIButtonSelect ());
+	m_selectMidiAction = CUIButton::triggerTypeFromString( m_pConfig->GetMIDIButtonActionSelect ());
 	m_homeMidi = ccToMidiPin( m_pConfig->GetMIDIButtonHome ());
+	m_homeMidiAction = CUIButton::triggerTypeFromString( m_pConfig->GetMIDIButtonActionHome ());
 	m_pgmUpMidi = ccToMidiPin( m_pConfig->GetMIDIButtonPgmUp ());
+	m_pgmUpMidiAction = CUIButton::triggerTypeFromString( m_pConfig->GetMIDIButtonActionPgmUp ());
 	m_pgmDownMidi = ccToMidiPin( m_pConfig->GetMIDIButtonPgmDown ());
+	m_pgmDownMidiAction = CUIButton::triggerTypeFromString( m_pConfig->GetMIDIButtonActionPgmDown ());
 	m_BankUpMidi = ccToMidiPin( m_pConfig->GetMIDIButtonBankUp ());
+	m_BankUpMidiAction = CUIButton::triggerTypeFromString( m_pConfig->GetMIDIButtonActionBankUp ());
 	m_BankDownMidi = ccToMidiPin( m_pConfig->GetMIDIButtonBankDown ());
+	m_BankDownMidiAction = CUIButton::triggerTypeFromString( m_pConfig->GetMIDIButtonActionBankDown ());
 	m_TGUpMidi = ccToMidiPin( m_pConfig->GetMIDIButtonTGUp ());
+	m_TGUpMidiAction = CUIButton::triggerTypeFromString( m_pConfig->GetMIDIButtonActionTGUp ());
 	m_TGDownMidi = ccToMidiPin( m_pConfig->GetMIDIButtonTGDown ());
-	
+	m_TGDownMidiAction = CUIButton::triggerTypeFromString( m_pConfig->GetMIDIButtonActionTGDown ());
+
 	// First sanity check and convert the timeouts:
 	// Internally values are in tenths of a millisecond, but config values
 	// are in milliseconds
@@ -328,7 +339,7 @@ boolean CUIButtons::Initialize (void)
 
 	// Each normal button can be assigned up to 3 actions: click, doubleclick and
 	// longpress. We may not initialise all of the buttons.
-	// MIDI buttons only support a single click.
+	// MIDI Buttons can be assigned to click, doubleclick, longpress
 	unsigned pins[MAX_BUTTONS] = {
 		m_prevPin, m_nextPin, m_backPin, m_selectPin, m_homePin, m_pgmUpPin,  m_pgmDownPin,  m_BankUpPin,  m_BankDownPin, m_TGUpPin,  m_TGDownPin, 
 		m_prevMidi, m_nextMidi, m_backMidi, m_selectMidi, m_homeMidi, m_pgmUpMidi, m_pgmDownMidi, m_BankUpMidi, m_BankDownMidi, m_TGUpMidi, m_TGDownMidi
@@ -337,9 +348,9 @@ boolean CUIButtons::Initialize (void)
 		// Normal buttons
 		m_prevAction, m_nextAction, m_backAction, m_selectAction, m_homeAction,
 		m_pgmUpAction, m_pgmDownAction, m_BankUpAction, m_BankDownAction, m_TGUpAction, m_TGDownAction, 
-		// MIDI Buttons only support a single click (at present)
-		CUIButton::BtnTriggerClick, CUIButton::BtnTriggerClick, CUIButton::BtnTriggerClick, CUIButton::BtnTriggerClick, CUIButton::BtnTriggerClick,
-		CUIButton::BtnTriggerClick, CUIButton::BtnTriggerClick, CUIButton::BtnTriggerClick, CUIButton::BtnTriggerClick, CUIButton::BtnTriggerClick, CUIButton::BtnTriggerClick
+		// MIDI buttons
+		m_prevMidiAction, m_nextMidiAction, m_backMidiAction, m_selectMidiAction, m_homeMidiAction,
+		m_pgmUpMidiAction, m_pgmDownMidiAction, m_BankUpMidiAction, m_BankDownMidiAction, m_TGUpMidiAction, m_TGDownMidiAction,
 	};
 	CUIButton::BtnEvent events[MAX_BUTTONS] = {
 		// Normal buttons
diff --git a/src/uibuttons.h b/src/uibuttons.h
index be17934..76febdd 100644
--- a/src/uibuttons.h
+++ b/src/uibuttons.h
@@ -165,18 +165,30 @@ private:
 	
 	// MIDI button configuration
 	unsigned m_notesMidi;
+
 	unsigned m_prevMidi;
+	CUIButton::BtnTrigger m_prevMidiAction;
 	unsigned m_nextMidi;
+	CUIButton::BtnTrigger m_nextMidiAction;
 	unsigned m_backMidi;
+	CUIButton::BtnTrigger m_backMidiAction;
 	unsigned m_selectMidi;
+	CUIButton::BtnTrigger m_selectMidiAction;
 	unsigned m_homeMidi;
+	CUIButton::BtnTrigger m_homeMidiAction;
 	
 	unsigned m_pgmUpMidi;
+	CUIButton::BtnTrigger m_pgmUpMidiAction;
 	unsigned m_pgmDownMidi;
+	CUIButton::BtnTrigger m_pgmDownMidiAction;
 	unsigned m_BankUpMidi;
+	CUIButton::BtnTrigger m_BankUpMidiAction;
 	unsigned m_BankDownMidi;
+	CUIButton::BtnTrigger m_BankDownMidiAction;
 	unsigned m_TGUpMidi;
+	CUIButton::BtnTrigger m_TGUpMidiAction;
 	unsigned m_TGDownMidi;
+	CUIButton::BtnTrigger m_TGDownMidiAction;
 
 	BtnEventHandler *m_eventHandler;
 	void *m_eventParam;