diff --git a/src/avtk/clipselector.cxx b/src/avtk/clipselector.cxx index 394ab6ce..b41cdacc 100644 --- a/src/avtk/clipselector.cxx +++ b/src/avtk/clipselector.cxx @@ -18,12 +18,14 @@ #include "clipselector.hxx" +#include "hotkeydialog.hxx" #include #pragma GCC diagnostic ignored "-Wmissing-field-initializers" #include "../gui.hxx" +#include "../hotkeymanager.hxx" extern Gui* gui; @@ -276,6 +278,7 @@ int ClipSelector::handle(int event) {0}, //{ "Record" }, { "Use as tempo" }, + { "Assign Hotkey" }, { "Rename", 0, 0, 0, FL_MENU_DIVIDER}, { "Clear" }, { 0 } @@ -285,6 +288,19 @@ int ClipSelector::handle(int event) return 0; } else if ( strcmp(m->label(), "Load") == 0 ) { gui->selectLoadSample( ID, clipNum ); + } else if ( strcmp(m->label(), "Assign Hotkey") == 0 ) { + int currentKey = getCurrentKeyForClip(ID, clipNum); + HotkeyDialog* dialog = new HotkeyDialog(300, 140, currentKey); + dialog->show(); + while (dialog->shown()) { + Fl::wait(); + } + + int newKey = dialog->getHotkey(); + if (newKey) { + updateKeyToGrid(currentKey, newKey, ID, clipNum); + } + } else if ( strcmp(m->label(), "Save") == 0 ) { //gui->saveBufferPath = "/tmp/test.wav"; char* tmp = gui->selectSavePath(); diff --git a/src/avtk/hotkeydialog.cxx b/src/avtk/hotkeydialog.cxx new file mode 100644 index 00000000..0e24839f --- /dev/null +++ b/src/avtk/hotkeydialog.cxx @@ -0,0 +1,61 @@ +#include "hotkeydialog.hxx" +#include +#include +#include + +HotkeyDialog::HotkeyDialog(int w, int h, int currentKey) + : Fl_Window(w, h, "Assign New Hotkey"), hotkey(0) { + this->set_modal(); // Prevent application closing without this window closing first + current_key_label = new Fl_Box(10, 10, w - 20, 20, "Current key:"); + current_key_label->box(FL_NO_BOX); + current_key_label->align(FL_ALIGN_INSIDE | FL_ALIGN_CENTER); + + // Concert currentKey to string if available + if (currentKey) { + current_key_str = static_cast(currentKey); + } else { + current_key_label->hide(); + current_key_str = "No key set"; + } + + current_key_display = new Fl_Box(10, 30, w - 20, 30, current_key_str.c_str()); + current_key_display->box(FL_NO_BOX); + current_key_display->align(FL_ALIGN_INSIDE | FL_ALIGN_CENTER); + current_key_display->labelfont(FL_HELVETICA_BOLD); + current_key_display->labelsize(14); + + instructions_box = new Fl_Box(10, 60, w - 20, 30, "Press new hotkey: \n(Esc to cancel)"); + instructions_box->box(FL_NO_BOX); + instructions_box->align(FL_ALIGN_INSIDE | FL_ALIGN_CENTER); + + cancel_button = new Fl_Button(w / 2 - 40, h - 40, 80, 30, "Cancel"); + cancel_button->callback(Cancel_CB, this); + end(); +} + +int HotkeyDialog::getHotkey() const { + return hotkey; +} + +int HotkeyDialog::handle(int event) { + switch (event) { + case FL_KEYDOWN: + if (Fl::event_key() == FL_Escape || Fl::event_key() == FL_Shift_L || Fl::event_key() == FL_Shift_R) { + hide(); + return 1; + } + hotkey = Fl::event_key(); + //std::cout << "Hotkey captured: " << hotkey << std::endl; + hide(); + return 1; + + default: + break; + } + return Fl_Window::handle(event); +} + +void HotkeyDialog::Cancel_CB(Fl_Widget*, void* v) { + HotkeyDialog* dialog = (HotkeyDialog*)v; + dialog->hide(); +} diff --git a/src/avtk/hotkeydialog.hxx b/src/avtk/hotkeydialog.hxx new file mode 100644 index 00000000..613f6039 --- /dev/null +++ b/src/avtk/hotkeydialog.hxx @@ -0,0 +1,30 @@ +#ifndef HOTKEYDIALOG_H +#define HOTKEYDIALOG_H + +#include +#include +#include +#include + +class HotkeyDialog : public Fl_Window { +public: + HotkeyDialog(int w, int h, int currentKey); + int getHotkey() const; + +protected: + int handle(int event) override; + +private: + static void Cancel_CB(Fl_Widget*, void* v); + + Fl_Box* current_key_label; + Fl_Box* current_key_display; + Fl_Box* instructions_box; + Fl_Button* cancel_button; + int hotkey; + + std::string message_text; + std::string current_key_str; +}; + +#endif // HOTKEYDIALOG_H diff --git a/src/avtk/meson.build b/src/avtk/meson.build index 66860a87..0de9c79a 100644 --- a/src/avtk/meson.build +++ b/src/avtk/meson.build @@ -1 +1 @@ -luppp_src += files( 'bindings.cxx', 'volume.cxx', 'clipselector.cxx') +luppp_src += files( 'bindings.cxx', 'volume.cxx', 'clipselector.cxx', 'hotkeydialog.cxx') diff --git a/src/diskreader.cxx b/src/diskreader.cxx index 6d5f0327..c91ec13b 100644 --- a/src/diskreader.cxx +++ b/src/diskreader.cxx @@ -31,7 +31,7 @@ #include "audiobuffer.hxx" #include "eventhandler.hxx" #include "gmastertrack.hxx" - +#include "hotkeymanager.hxx" #include "controller/genericmidi.hxx" #include @@ -93,6 +93,23 @@ int DiskReader::loadPreferences() LUPPP_NOTE("No default controllers active."); } + cJSON* hotkeyAssignment = cJSON_GetObjectItem(preferencesJson, "hotkeyAssignment"); + if (hotkeyAssignment) { + keyToGrid.clear(); + cJSON* key = hotkeyAssignment->child; + while (key) { + int keycode = atoi(key->string); + cJSON* gridArray = key; + if (cJSON_GetArraySize(gridArray) == 2) { + int x = cJSON_GetArrayItem(gridArray, 0)->valueint; + int y = cJSON_GetArrayItem(gridArray, 1)->valueint; + keyToGrid[keycode] = {x, y}; + } + key = key->next; + } + } else { + LUPPP_WARN("No hotkeyAssignment found in preferences"); + } cJSON* projDir=cJSON_GetObjectItem(preferencesJson,"saveDirectory"); string dir=getenv("HOME"); diff --git a/src/diskwriter.cxx b/src/diskwriter.cxx index 30ef46e8..90ac3e81 100644 --- a/src/diskwriter.cxx +++ b/src/diskwriter.cxx @@ -31,6 +31,7 @@ #include #include "gui.hxx" +#include "hotkeymanager.hxx" #include "gmastertrack.hxx" #include "controller/genericmidi.hxx" @@ -474,9 +475,29 @@ void DiskWriter::writeDefaultConfigToUserHome() // per track send and return option cJSON_AddNumberToObject( prfs, "enablePerTrackSendReturns", 0 ); + + cJSON* hotkeyAssignment = cJSON_CreateObject(); + + // Iterate through the keyToGrid map and add each key-value pair to hotkeyAssignment + for (const auto& pair : keyToGrid) { + int key = pair.first; + int id = pair.second.first; + int clipNumber = pair.second.second; + + // Create an array for the id and clipNumber + cJSON* array = cJSON_CreateArray(); + cJSON_AddItemToArray(array, cJSON_CreateNumber(id)); + cJSON_AddItemToArray(array, cJSON_CreateNumber(clipNumber)); + + // Convert key to string and add to hotkeyAssignment + cJSON_AddItemToObject(hotkeyAssignment, std::to_string(key).c_str(), array); + } + cJSON_AddItemToObject(prfs, "hotkeyAssignment", hotkeyAssignment); + // test output on console // cout << endl << cJSON_Print( prfs ) << endl << endl; - + + // write JSON to .config/openAV/luppp/luppp.prfs stringstream f; diff --git a/src/gui.cxx b/src/gui.cxx index 572e4e3f..c4051f54 100644 --- a/src/gui.cxx +++ b/src/gui.cxx @@ -17,6 +17,7 @@ */ #include "gui.hxx" +#include "hotkeymanager.hxx" #include "avtk/avtk_image.h" #include "avtk/avtk_button.h" @@ -37,6 +38,7 @@ extern Jack* jack; #include #include +#include #include #include #include @@ -552,7 +554,7 @@ int Gui::quit() // ensure the subwindows are closed optionWindow->hide(); audioEditor->hide(); - + gui->getDiskWriter()->writeDefaultConfigToUserHome(); // quit main window, causing program termination window.hide(); @@ -569,308 +571,53 @@ void Gui::askQuit() int Gui::keyboardHandler(int event) { - switch( event ) { case FL_SHORTCUT: - if ( strcmp( Fl::event_text(), "1" ) == 0 ) { - EventGridEvent e( 0, 0, true ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "2" ) == 0 ) { - EventGridEvent e( 1, 0, true ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "3" ) == 0 ) { - EventGridEvent e( 2, 0, true ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "4" ) == 0 ) { - EventGridEvent e( 3, 0, true ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "5" ) == 0 ) { - EventGridEvent e( 4, 0, true ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "6" ) == 0 ) { - EventGridEvent e( 5, 0, true ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "7" ) == 0 ) { - EventGridEvent e( 6, 0, true ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "8" ) == 0 ) { - EventGridEvent e( 7, 0, true ); - writeToDspRingbuffer( &e ); - return 1; - } - - else if( strcmp( Fl::event_text(), "!" ) == 0 ) { - EventGridState e( 0, 0, GridLogic::STATE_EMPTY ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "@" ) == 0 ) { - EventGridState e( 1, 0, GridLogic::STATE_EMPTY ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "\"" ) == 0 ) { - EventGridState e( 1, 0, GridLogic::STATE_EMPTY ); // for UK/Ireland keyboards - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "#" ) == 0 ) { - EventGridState e( 2, 0, GridLogic::STATE_EMPTY ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "£" ) == 0 ) { - EventGridState e( 2, 0, GridLogic::STATE_EMPTY ); // for UK/Ireland keyboards - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "$" ) == 0 ) { - EventGridState e( 3, 0, GridLogic::STATE_EMPTY ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "%" ) == 0 ) { - EventGridState e( 4, 0, GridLogic::STATE_EMPTY ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "^" ) == 0 ) { - EventGridState e( 5, 0, GridLogic::STATE_EMPTY ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "&" ) == 0 ) { - EventGridState e( 6, 0, GridLogic::STATE_EMPTY ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "*" ) == 0 ) { - EventGridState e( 7, 0, GridLogic::STATE_EMPTY ); - writeToDspRingbuffer( &e ); - return 1; - } - else if( strcmp( Fl::event_text(), "q" ) == 0 ) { - EventGridEvent e( 0, 1, true ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "w" ) == 0 ) { - EventGridEvent e( 1, 1, true ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "e" ) == 0 ) { - EventGridEvent e( 2, 1, true ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "r" ) == 0 ) { - EventGridEvent e( 3, 1, true ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "t" ) == 0 ) { - EventGridEvent e( 4, 1, true ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "y" ) == 0 ) { - EventGridEvent e( 5, 1, true ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "u" ) == 0 ) { - EventGridEvent e( 6, 1, true ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "i" ) == 0 ) { - EventGridEvent e( 7, 1, true ); - writeToDspRingbuffer( &e ); - return 1; - } - - else if( strcmp( Fl::event_text(), "Q" ) == 0 ) { - EventGridState e( 0, 1, GridLogic::STATE_EMPTY ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "W" ) == 0 ) { - EventGridState e( 1, 1, GridLogic::STATE_EMPTY ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "E" ) == 0 ) { - EventGridState e( 2, 1, GridLogic::STATE_EMPTY ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "R" ) == 0 ) { - EventGridState e( 3, 1, GridLogic::STATE_EMPTY ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "T" ) == 0 ) { - EventGridState e( 4, 1, GridLogic::STATE_EMPTY ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "Y" ) == 0 ) { - EventGridState e( 5, 1, GridLogic::STATE_EMPTY ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "U" ) == 0 ) { - EventGridState e( 6, 1, GridLogic::STATE_EMPTY ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "I" ) == 0 ) { - EventGridState e( 7, 1, GridLogic::STATE_EMPTY ); - writeToDspRingbuffer( &e ); - return 1; - } - - else if( strcmp( Fl::event_text(), "a" ) == 0 ) { - EventGridEvent e( 0, 2, true ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "s" ) == 0 ) { - EventGridEvent e( 1, 2, true ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "d" ) == 0 ) { - EventGridEvent e( 2, 2, true ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "f" ) == 0 ) { - EventGridEvent e( 3, 2, true ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "g" ) == 0 ) { - EventGridEvent e( 4, 2, true ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "h" ) == 0 ) { - EventGridEvent e( 5, 2, true ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "j" ) == 0 ) { - EventGridEvent e( 6, 2, true ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "k" ) == 0 ) { - EventGridEvent e( 7, 2, true ); - writeToDspRingbuffer( &e ); - return 1; - } - - else if( strcmp( Fl::event_text(), "A" ) == 0 ) { - EventGridState e( 0, 2, GridLogic::STATE_EMPTY ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "S" ) == 0 ) { - EventGridState e( 1, 2, GridLogic::STATE_EMPTY ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "D" ) == 0 ) { - EventGridState e( 2, 2, GridLogic::STATE_EMPTY ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "F" ) == 0 ) { - EventGridState e( 3, 2, GridLogic::STATE_EMPTY ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "G" ) == 0 ) { - EventGridState e( 4, 2, GridLogic::STATE_EMPTY ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "H" ) == 0 ) { - EventGridState e( 5, 2, GridLogic::STATE_EMPTY ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "J" ) == 0 ) { - EventGridState e( 6, 2, GridLogic::STATE_EMPTY ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "K" ) == 0 ) { - EventGridState e( 7, 2, GridLogic::STATE_EMPTY ); - writeToDspRingbuffer( &e ); - return 1; - } - - else if( strcmp( Fl::event_text(), "z" ) == 0 ) { - EventGridEvent e( 0, 3, true ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "x" ) == 0 ) { - EventGridEvent e( 1, 3, true ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "c" ) == 0 ) { - EventGridEvent e( 2, 3, true ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "v" ) == 0 ) { - EventGridEvent e( 3, 3, true ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "b" ) == 0 ) { - EventGridEvent e( 4, 3, true ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "n" ) == 0 ) { - EventGridEvent e( 5, 3, true ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "m" ) == 0 ) { - EventGridEvent e( 6, 3, true ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "," ) == 0 ) { - EventGridEvent e( 7, 3, true ); - writeToDspRingbuffer( &e ); - return 1; - } - - else if( strcmp( Fl::event_text(), "Z" ) == 0 ) { - EventGridState e( 0, 3, GridLogic::STATE_EMPTY ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "X" ) == 0 ) { - EventGridState e( 1, 3, GridLogic::STATE_EMPTY ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "C" ) == 0 ) { - EventGridState e( 2, 3, GridLogic::STATE_EMPTY ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "V" ) == 0 ) { - EventGridState e( 3, 3, GridLogic::STATE_EMPTY ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "B" ) == 0 ) { - EventGridState e( 4, 3, GridLogic::STATE_EMPTY ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "N" ) == 0 ) { - EventGridState e( 5, 3, GridLogic::STATE_EMPTY ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "M" ) == 0 ) { - EventGridState e( 6, 3, GridLogic::STATE_EMPTY ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "<" ) == 0 ) { - EventGridState e( 7, 3, GridLogic::STATE_EMPTY ); - writeToDspRingbuffer( &e ); - return 1; - } - - else if( strcmp( Fl::event_text(), "9" ) == 0 ) { - EventGridLaunchScene e( 0 ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "o" ) == 0 ) { - EventGridLaunchScene e( 1 ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "l" ) == 0 ) { - EventGridLaunchScene e( 2 ); - writeToDspRingbuffer( &e ); - return 1; - } else if( strcmp( Fl::event_text(), "." ) == 0 ) { - EventGridLaunchScene e( 3 ); - writeToDspRingbuffer( &e ); - return 1; - } - - else { + const char* eventText = Fl::event_text(); + int eventKey = Fl::event_key(); + + if (eventKey) { + // char buffer [50]; + // snprintf(buffer, sizeof(buffer), "Keyboard input: %s | %i", eventText, eventKey); + // printf("%s\n", buffer); + + if (keyToGrid.find(eventKey) != keyToGrid.end()) { + auto gridPos = keyToGrid[eventKey]; + int x = gridPos.first; + int y = gridPos.second; + + // Check if Shift is held down + bool shiftHeld = (Fl::event_state() & FL_SHIFT) != 0; + + if (shiftHeld) { + EventGridState e(x, y, GridLogic::STATE_EMPTY); + writeToDspRingbuffer(&e); + } else { + EventGridEvent e(x, y, true); + writeToDspRingbuffer(&e); + } + + return 1; + + } else if( strcmp( eventText, "9" ) == 0 ) { + EventGridLaunchScene e( 0 ); + writeToDspRingbuffer( &e ); + return 1; + } else if( strcmp( eventText, "o" ) == 0 ) { + EventGridLaunchScene e( 1 ); + writeToDspRingbuffer( &e ); + return 1; + } else if( strcmp( eventText, "l" ) == 0 ) { + EventGridLaunchScene e( 2 ); + writeToDspRingbuffer( &e ); + return 1; + } else if( strcmp( eventText, "." ) == 0 ) { + EventGridLaunchScene e( 3 ); + writeToDspRingbuffer( &e ); + return 1; + } + } else { //printf("%s\n", Fl::event_text() ); return 1; } } diff --git a/src/hotkeymanager.cxx b/src/hotkeymanager.cxx new file mode 100644 index 00000000..31948ec6 --- /dev/null +++ b/src/hotkeymanager.cxx @@ -0,0 +1,38 @@ +#include "hotkeymanager.hxx" +#include + +std::map> keyToGrid = { + {49, {0, 0}}, {50, {1, 0}}, {51, {2, 0}}, {52, {3, 0}}, {53, {4, 0}}, {54, {5, 0}}, {55, {6, 0}}, {56, {7, 0}}, // 1-8 + {113, {0, 1}}, {119, {1, 1}}, {101, {2, 1}}, {114, {3, 1}}, {116, {4, 1}}, {121, {5, 1}}, {117, {6, 1}}, {105, {7, 1}}, // q-i + {97, {0, 2}}, {115, {1, 2}}, {100, {2, 2}}, {102, {3, 2}}, {103, {4, 2}}, {104, {5, 2}}, {106, {6, 2}}, {107, {7, 2}}, // a-k + {122, {0, 3}}, {120, {1, 3}}, {99, {2, 3}}, {118, {3, 3}}, {98, {4, 3}}, {110, {5, 3}}, {109, {6, 3}}, {44, {7, 3}}, // z-, +}; + +void addKeyToGrid(int key, int id, int clipNumber) { + keyToGrid[key] = {id, clipNumber}; +} + +void updateKeyToGrid(int oldKey, int newkey, int id, int clipNumber) { + removeKeyFromGrid(oldKey, id, clipNumber); + removeKeyFromGrid(newkey, id, clipNumber); // remove previous assignment of new key if it exists + addKeyToGrid(newkey, id, clipNumber); +} + +void removeKeyFromGrid(int key, int id, int clipNumber) { + for (auto it = keyToGrid.begin(); it != keyToGrid.end(); ) { + if (it->second.first == id && it->second.second == clipNumber) { + it = keyToGrid.erase(it); // Remove the existing mapping and get the new iterator + } else { + ++it; // Move to the next element + } + } +} + +int getCurrentKeyForClip(int id, int clipNumber) { + for (const auto& pair : keyToGrid) { + if (pair.second.first == id && pair.second.second == clipNumber) { + return pair.first; + } + } + return 0; +} \ No newline at end of file diff --git a/src/hotkeymanager.hxx b/src/hotkeymanager.hxx new file mode 100644 index 00000000..cb92cd7f --- /dev/null +++ b/src/hotkeymanager.hxx @@ -0,0 +1,14 @@ +#ifndef HOTKEYMANAGER_H +#define HOTKEYMANAGER_H + +#include +#include + +extern std::map> keyToGrid; + +void addKeyToGrid(int key, int id, int clipNumber); +void updateKeyToGrid(int oldKey, int newkey, int id, int clipNumber); +void removeKeyFromGrid(int key, int id, int clipNumber); +int getCurrentKeyForClip(int id, int clipNumber); + +#endif // HOTKEYMANAGER_H \ No newline at end of file diff --git a/src/meson.build b/src/meson.build index 18fafb95..27e89cba 100644 --- a/src/meson.build +++ b/src/meson.build @@ -18,6 +18,7 @@ luppp_src = files( 'gridlogic.cxx', 'gtrack.cxx', 'gui.cxx', + 'hotkeymanager.cxx', 'jack.cxx', 'jacksendreturn.cxx', 'logic.cxx',