From e0ad7c817b6ad77cae3362791a60c2c7c5601032 Mon Sep 17 00:00:00 2001 From: thibaudk Date: Tue, 8 Oct 2024 16:12:35 +0100 Subject: [PATCH] [bugui] refactor and add bugui submodule --- .gitmodules | 3 + CMakeLists.txt | 15 ++- Hardware/3rdparty/bugui | 1 + Hardware/Controller.cpp | 43 ++++----- Hardware/Controller.hpp | 27 +----- Hardware/MidiController.cpp | 183 ------------------------------------ Hardware/MidiController.hpp | 71 -------------- 7 files changed, 31 insertions(+), 312 deletions(-) create mode 100644 .gitmodules create mode 160000 Hardware/3rdparty/bugui delete mode 100644 Hardware/MidiController.cpp delete mode 100644 Hardware/MidiController.hpp diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..91f5cdd --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "Hardware/3rdparty/bugui"] + path = Hardware/3rdparty/bugui + url = https://codeberg.org/bugui/bugui.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 8da92fb..4780cc4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,18 +9,17 @@ if(NOT TARGET libremidi) return() endif() - score_common_setup() -set(HDRS - "Hardware/Controller.hpp" - "Hardware/MidiController.hpp" +add_subdirectory(Hardware/3rdparty/bugui) +set(HDRS "Hardware/Settings/Model.hpp" "Hardware/Settings/Presenter.hpp" "Hardware/Settings/View.hpp" "Hardware/Settings/Factory.hpp" + "Hardware/Controller.hpp" "Hardware/DocumentPlugin.hpp" "Hardware/ApplicationPlugin.hpp" @@ -28,24 +27,22 @@ set(HDRS ) set(SRCS - "${CMAKE_CURRENT_SOURCE_DIR}/Hardware/Controller.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/Hardware/MidiController.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/Hardware/Settings/Model.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/Hardware/Settings/Presenter.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/Hardware/Settings/View.cpp" + "${CMAKE_CURRENT_SOURCE_DIR}/Hardware/Controller.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/Hardware/DocumentPlugin.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/Hardware/ApplicationPlugin.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/score_addon_hardware.cpp" ) -add_library(${PROJECT_NAME} ${SRCS} ${HDRS} ${QRCS}) +add_library(${PROJECT_NAME} ${SRCS} ${HDRS}) target_link_libraries(${PROJECT_NAME} PUBLIC score_plugin_scenario - libremidi + bugui ) setup_score_plugin(${PROJECT_NAME}) diff --git a/Hardware/3rdparty/bugui b/Hardware/3rdparty/bugui new file mode 160000 index 0000000..f97533d --- /dev/null +++ b/Hardware/3rdparty/bugui @@ -0,0 +1 @@ +Subproject commit f97533d59cd0db29221dda683d845120617ae8a3 diff --git a/Hardware/Controller.cpp b/Hardware/Controller.cpp index 75c6c66..df6eacb 100644 --- a/Hardware/Controller.cpp +++ b/Hardware/Controller.cpp @@ -1,37 +1,30 @@ -#include - #include #include #include -#include "MidiController.hpp" - #include "Controller.hpp" namespace Hardware { Controller::Controller(const score::DocumentContext& doc) - : h_ofset{0.} // initial horizontal ofset - , v_ofset{0.} // initial verticalal ofset - , h_zoom{.125} // initial horizontal zoom - , v_zoom{1.1} // initial verticalal zoom -{ - commandCallback = [&doc, this](Controller::Commands com, const bool& shift) { + : bugui::controller{[&doc, this] + (commands com, const bool& shift) + { switch (com) { - case Controller::Play: + case Play: if (shift) doc.app.actions.action().action()->trigger(); else doc.app.actions.action().action()->trigger(); break; - case Controller::Stop: + case Stop: if (shift) doc.app.actions.action().action()->trigger(); else doc.app.actions.action().action()->trigger(); break; - case Controller::Up: + case Up: if (shift) { v_zoom += .2; @@ -43,7 +36,7 @@ Controller::Controller(const score::DocumentContext& doc) draw_intervals(); } break; - case Controller::Down: + case Down: if (shift) { if (v_zoom > .2) @@ -58,7 +51,7 @@ Controller::Controller(const score::DocumentContext& doc) draw_intervals(); } break; - case Controller::Left: + case Left: if (shift) { if (h_zoom > .02) @@ -76,7 +69,7 @@ Controller::Controller(const score::DocumentContext& doc) } } break; - case Controller::Right: + case Right: if (shift) { h_zoom += .02; @@ -96,15 +89,9 @@ Controller::Controller(const score::DocumentContext& doc) // qDebug() << "v_zoom: " << v_zoom; // qDebug() << "h_ofset: " << h_ofset; // qDebug() << "h_zoom: " << h_ofset; - }; -} - -void Controller::setup() -{ - ctl = new MidiController{}; - ctl->on_command = commandCallback; - ctl->setup(); + } } +{} void Controller::setup_scenario(Scenario::ProcessModel* s) { @@ -135,11 +122,13 @@ void Controller::draw_intervals() auto def = c.duration.defaultDuration().sec() * h_zoom; auto st = (c.date().sec() * h_zoom) - h_ofset; auto y = (c.heightPercentage() * v_zoom) + v_ofset; - ctl->draw_line({st, y}, {st + def, y}); + draw_line({st, y}, {st + def, y}); } - ctl->update_grid(); -} + update_grid(); } +} + +#include W_OBJECT_IMPL(Hardware::Controller) diff --git a/Hardware/Controller.hpp b/Hardware/Controller.hpp index d0c5bcd..507eb02 100644 --- a/Hardware/Controller.hpp +++ b/Hardware/Controller.hpp @@ -5,44 +5,27 @@ #include #include +#include + namespace Hardware { -class MidiController; - class SCORE_ADDON_HARDWARE_EXPORT Controller - : public QObject + : public bugui::controller + , public QObject { W_OBJECT(Controller) public: explicit Controller(const score::DocumentContext& doc); - enum Commands - { - Play = 0, - Stop, - Left, - Right, - Up, - Down - }; - - void setup(); void setup_scenario(Scenario::ProcessModel* s); void draw_intervals(); private: - double h_ofset; - double v_ofset; - double h_zoom; - double v_zoom; - - MidiController* ctl; Scenario::ProcessModel* scenar; - std::function commandCallback; - void on_interval_changed(const Scenario::IntervalModel &); }; + } diff --git a/Hardware/MidiController.cpp b/Hardware/MidiController.cpp deleted file mode 100644 index 921818c..0000000 --- a/Hardware/MidiController.cpp +++ /dev/null @@ -1,183 +0,0 @@ -#include - -#include "MidiController.hpp" - -namespace Hardware -{ -MidiController::MidiController() - : grid{GRID} - , previous_grid{BLACK} - , current_grid{BLACK} - , m_output{} - , m_input{{.on_message = [this] (const libremidi::message& message) -{ - if (message.get_message_type() == libremidi::message_type::CONTROL_CHANGE) - switch (message.bytes[1]) - { - case SHIFT: - shift = message.bytes[2] > 0; - break; - case PLAY: - if (message.bytes[2] > 0) - on_command(Controller::Play, shift); - break; - case STOP: - if (message.bytes[2] > 0) - on_command(Controller::Stop, shift); - break; - case UP: - if (message.bytes[2] > 0) - on_command(Controller::Up, shift); - break; - case DOWN: - if (message.bytes[2] > 0) - on_command(Controller::Down, shift); - break; - case LEFT: - if (message.bytes[2] > 0) - on_command(Controller::Left, shift); - break; - case RIGHT: - if (message.bytes[2] > 0) - on_command(Controller::Right, shift); - break; - default: - break; - } -}, - .ignore_sensing = false, - .ignore_timing = false, - .ignore_sysex = false, - } - } -{} - -MidiController::~MidiController() -{ - m_input.close_port(); - m_output.close_port(); -} - -void MidiController::setup(const QString& deviceName) -{ - open_port_by_name(deviceName); - - if (m_output.is_port_open()) - { - using namespace libremidi; - using e = channel_events; - - m_output.send_message(message PROGRAMER_MODE); - - m_output.send_message(e::note_on(1, u_int8_t{SHIFT}, u_int8_t{WHITE})); - m_output.send_message(e::note_on(1, u_int8_t{PLAY}, u_int8_t{GREEN})); - m_output.send_message(e::note_on(1, u_int8_t{STOP}, u_int8_t{ORANGE})); - - clear_grid(); - } -} - -void MidiController::update_grid() -{ - for (int i{0}; i <= MAX_COLUMN_INDEX; i++) - for (int j{0}; j <= MAX_ROW_INDEX; j++) - { - if (current_grid[i][j] != previous_grid[i][j]) - m_output.send_message(libremidi::channel_events::note_on(1, - grid[i][j], - current_grid[i][j])); - previous_grid[i][j] = current_grid[i][j]; - current_grid[i][j] = BLACK; - } -} - -void MidiController::clear_grid() -{ - for (int i{0}; i <= MAX_COLUMN_INDEX; i++) - for (int j{0}; j <= MAX_ROW_INDEX; j++) - { - current_grid[i][j] = BLACK; - m_output.send_message(libremidi::channel_events::note_on(1, - grid[i][j], - BLACK)); - previous_grid[i][j] = BLACK; - } -} - -void MidiController::draw_line(const std::array& p1, - const std::array& p2) -{ - int p1x = int(p1[0] * MAX_ROW_INDEX); - int p2x = int(p2[0] * MAX_ROW_INDEX); - int p1y = int(p1[1] * MAX_COLUMN_INDEX); - int p2y = int(p2[1] * MAX_COLUMN_INDEX); - - using namespace std; - using namespace libremidi; - using e = channel_events; - - // qDebug() << "p1y: " << p1y; - // qDebug() << "p2y: " << p2y; - - if (p1y == p2y) // draw horizontal lines - { - if (p1y < 0 || p1y > MAX_COLUMN_INDEX) // vertical position out of range - return; - else - { - int start{min(p1x, p2x)}; - int end{max(p1x, p2x)}; - - if (start > MAX_ROW_INDEX || end < 0) // horizonal position out of range - return; - - int last{min(MAX_ROW_INDEX, end)}; // last index in range - - for (int i{max(0, start)}; i <= last; i++) // itterate from first index in range - current_grid[p1y][i] = LIGHT_BLUE; - } - } - else if (p1x == p2x) // draw verticatl lines - { - if (p1x < 0 || p1x > MAX_ROW_INDEX) // horizontal position out of range - return; - else - { - int start{min(p1y, p2y)}; - int end{max(p1y, p2y)}; - - if (start > MAX_COLUMN_INDEX || end < 0) // vertical position out of range - return; - - int last{min(MAX_COLUMN_INDEX, end)}; // last index in range - - for (int i{max(0, start)}; i <= last; i++) // itterate from first index in range - current_grid[p1y][i] = LIGHT_BLUE; - } - } -} - -void MidiController::open_port_by_name(const QString& deviceName) -{ - libremidi::observer obs; - - for (const auto& input : obs.get_input_ports()) - { - if (deviceName == QString::fromStdString(input.port_name).split(":").back()) - m_input.open_port(input); - } - - // TODO : error handling here - if (!m_input.is_port_connected()) return; - - for (const auto& output : obs.get_output_ports()) - { - if (deviceName == QString::fromStdString(output.port_name).split(":").back()) - m_output.open_port(output); - } - - // TODO : error handling here - if (!m_output.is_port_connected()) return; -} - -} diff --git a/Hardware/MidiController.hpp b/Hardware/MidiController.hpp deleted file mode 100644 index 48dbccf..0000000 --- a/Hardware/MidiController.hpp +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef MIDICONTROLLER_HPP -#define MIDICONTROLLER_HPP - -#include -#include - -#include - -#include "Controller.hpp" - -// Macros to temporarly act as the device description file -#define PROGRAMER_MODE {240, 0, 32, 41, 2, 16, 44, 3, 247} - -#define SHIFT 80 -#define PLAY 19 -#define STOP 8 -#define UP 91 -#define DOWN 92 -#define LEFT 93 -#define RIGHT 94 - -#define BLACK 0 -#define WHITE 2 -#define LIGHT_BLUE 36 -#define GREEN 64 -#define ORANGE 9 - -// Grid -#define GRID \ - {81, 82, 83, 84, 85, 86, 87, 88}, \ - {71, 72, 73, 74, 75, 76, 77, 78}, \ - {61, 62, 63, 64, 65, 66, 67, 68}, \ - {51, 52, 53, 54, 55, 56, 57, 58}, \ - {41, 42, 43, 44, 45, 46, 47, 48}, \ - {31, 32, 33, 34, 35, 36, 37, 38}, \ - {21, 22, 23, 24, 25, 26, 27, 28}, \ - {11, 12, 13, 14, 15, 16, 17, 18} - -#define MAX_ROW_INDEX 7 -#define MAX_COLUMN_INDEX 7 - -namespace Hardware -{ -class MidiController -{ -public: - MidiController(); - ~MidiController(); - - std::function on_command; - - void setup(const QString& deviceName = "Launchpad Pro Standalone Port"); - void update_grid(); - void clear_grid(); - void draw_line(const std::array& p1, const std::array& p2); - -private: - void open_port_by_name(const QString& deviceName); - - u_int8_t grid[MAX_ROW_INDEX + 1][MAX_COLUMN_INDEX + 1]; - u_int8_t previous_grid[MAX_ROW_INDEX + 1][MAX_COLUMN_INDEX + 1]; - u_int8_t current_grid[MAX_ROW_INDEX + 1][MAX_COLUMN_INDEX + 1]; - bool shift{false}; - - libremidi::midi_out m_output; - libremidi::midi_in m_input; -}; - -} - -#endif // MIDICONTROLLER_HPP