From 4317c698fa9f48a2948548055064f51863d5081d Mon Sep 17 00:00:00 2001 From: Marco Auer Date: Sun, 27 Oct 2024 22:05:35 +0100 Subject: [PATCH] Various improvements and refactoring --- docs/changelog.md | 3 + docs/inbound_mapping.md | 17 +- docs/inbound_mapping_command_by_value.md | 12 +- docs/inbound_mapping_pushnpull.md | 4 +- docs/inbound_mapping_short_and_long.md | 22 + src/common/types.h | 7 +- src/common/utils.h | 1 - src/device/CMakeLists.txt | 12 +- src/device/conversions.cpp | 2 + .../map_in/{map_in_label.cpp => label.cpp} | 186 ++--- src/device/map_in/label.h | 48 +- src/device/map_in/map_in.h | 1 + src/device/map_in/map_in_cbv.cpp | 15 +- src/device/map_in/map_in_cbv.h | 6 +- src/device/map_in/map_in_cmd.cpp | 13 +- src/device/map_in/map_in_cmd.h | 7 +- src/device/map_in/map_in_drf.cpp | 32 +- src/device/map_in/map_in_drf.h | 8 +- src/device/map_in/map_in_enc.cpp | 780 +++++++++--------- src/device/map_in/map_in_enc.h | 8 +- src/device/map_in/map_in_label.h | 68 -- src/device/map_in/map_in_list.cpp | 10 +- src/device/map_in/map_in_pnp.cpp | 348 -------- src/device/map_in/map_in_sld.cpp | 311 +++---- src/device/map_in/map_in_sld.h | 8 +- src/device/map_in/map_in_snl.cpp | 445 ++++++++++ .../map_in/{map_in_pnp.h => map_in_snl.h} | 45 +- src/device/midi_device.cpp | 6 +- src/device/virtual_device.cpp | 6 +- src/env-xplane/data_xplane.cpp | 3 + src/env-xplane/imgui_window.cpp | 2 - src/env-xplane/xplane_window.h | 6 + src/plugin/ui/log_viewer.cpp | 6 +- src/plugin/ui/midi_watcher.cpp | 6 +- 34 files changed, 1339 insertions(+), 1115 deletions(-) create mode 100644 docs/inbound_mapping_short_and_long.md rename src/device/map_in/{map_in_label.cpp => label.cpp} (51%) delete mode 100644 src/device/map_in/map_in_label.h delete mode 100644 src/device/map_in/map_in_pnp.cpp create mode 100644 src/device/map_in/map_in_snl.cpp rename src/device/map_in/{map_in_pnp.h => map_in_snl.h} (71%) diff --git a/docs/changelog.md b/docs/changelog.md index cc4932ea..6da51686 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -8,6 +8,9 @@ + Internal refactoring + Added HIDAPI as external library and started preparations for HID support + Added new parameter values_wrap to enable/disable value wrapping ++ The command mapping will now be executed as soon as "Data 2" is equal or higher than the specified *data_2_on* +parameter. This allows the use of pad controllers like the Akai LPD8. Many thanks to GitHub user *delgod* for +contributing this feature. ----------------------------------------------------------------------------------------------------------------------- diff --git a/docs/inbound_mapping.md b/docs/inbound_mapping.md index b8e93159..c88a8a00 100644 --- a/docs/inbound_mapping.md +++ b/docs/inbound_mapping.md @@ -12,7 +12,7 @@ The following parameter is required for each mapping. | Parameter | Description | |-----------|----------------------------------------| | ch | MIDI Channel (Default Value = 11) | - | type | Specifies the mapping type (see below) | +| type | Specifies the mapping type (see below) | One of the following parameters is required, depending on the MIDI message type. @@ -33,13 +33,14 @@ One of the following parameters is required, depending on the MIDI message type. The following mapping types are supported: -| Mapping Type | Name | Description and usage | -|:------------:|:---------:|----------------------------------------------------------------------------------| -| cmd | Command | Executes a X-Plane command | -| pnp | Push&pull | Simulates a Push & pull button, which can execute two different commands | -| drf | Dataref | Toggles a given Dataref between two values | -| enc | Encoder | Executes different commands for up/down or modifies a given dataref | -| sld | Slider | Executes up to three different commands, depending on the location of the slider | +| Mapping Type | Name | Description and usage | +|:------------:|:------------:|-----------------------------------------------------------------------------------------------------------------------| +| cmd | Command | Executes a X-Plane command | +| pnp | Push & pull | *Obsolete: use Short & Long instead!*

Simulates a Push & pull button, which can execute two different commands | +| snl | Short & long | Allows to define different datarefs and/or commands for short and long button presses | +| drf | Dataref | Toggles a given Dataref between two values | +| enc | Encoder | Executes different commands for up/down or modifies a given dataref | +| sld | Slider | Executes up to three different commands, depending on the location of the slider | ## Multi-Map diff --git a/docs/inbound_mapping_command_by_value.md b/docs/inbound_mapping_command_by_value.md index 7eb507ef..89aa4f85 100644 --- a/docs/inbound_mapping_command_by_value.md +++ b/docs/inbound_mapping_command_by_value.md @@ -2,15 +2,15 @@ ## Description -Executes an X-Plane command when a button is pressed. The command will be executed as long as the button is being -pressed down. This behaviour is useful to map the CLR button of the G530, as pressing the button for a longer time -returns to the map screen. +Executes an X-Plane command based on the current value of a specified dataref. The command will be executed as long as +the button is being pressed down. This behaviour is useful to map the CLR button of the G530, as pressing the button +for a longer time returns to the map screen. ## Required Parameters -| Parameter | Description | -|-----------|--------------------------------------------| -| command | Defines the X-Plane command to be executed | +| Parameter | Description | +|-----------|-------------------------------------------------------------------------| +| dataref | Defines dataref in X-Plane which should be used for the command mapping | ## Optional Parameters diff --git a/docs/inbound_mapping_pushnpull.md b/docs/inbound_mapping_pushnpull.md index c84f6823..c12133d2 100644 --- a/docs/inbound_mapping_pushnpull.md +++ b/docs/inbound_mapping_pushnpull.md @@ -1,4 +1,6 @@ -# Inbound Mapping Type: Push&pull +# Inbound Mapping Type: Push & pull + +*Obsolete: use [Short & Long](inbound_mapping_short_and_long.md) instead!* ## Description diff --git a/docs/inbound_mapping_short_and_long.md b/docs/inbound_mapping_short_and_long.md new file mode 100644 index 00000000..89cd9982 --- /dev/null +++ b/docs/inbound_mapping_short_and_long.md @@ -0,0 +1,22 @@ +# Inbound Mapping Type: Short & long + +## Description + +This mapping simulates a push and pull button, as found in Airbus aircraft. A short button press will execute the push +command, while a longer button press (~1 sec) will execute the pull command. + +## Required Parameters + +| Parameter | Description | +|---------------|------------------------------------------------------| +| command_short | Defines the command to be executed for a push action | +| command_long | Defines the command to be executed for a pull action | + +## Examples + +``` +{ ch = 11, cc = 14, type = "snl", command_push = "AirbusFBW/PushAltitude", command_pull = "AirbusFBW/PullAltitude" } +``` +*If the button for Channel 11 and Control Change 14 is pressed and immediately released the command +'AirbusFBW/PushAltitude' will be executed. If the button is pressed for a longer time (~one second) then command +'AirbusFBW/PullAltitude' will be executed.* \ No newline at end of file diff --git a/src/common/types.h b/src/common/types.h index c8d80c5d..efa89a33 100644 --- a/src/common/types.h +++ b/src/common/types.h @@ -29,12 +29,6 @@ namespace xmidictrl { // CONSTANTS //--------------------------------------------------------------------------------------------------------------------- -// Spacer 2 -#define UI_SPACER_2 " " - -// Spacer 3 -#define UI_SPACER_3 " " - // MIDI unsigned int none const char MIDI_NONE(-1); @@ -98,6 +92,7 @@ const char* const CFG_MAPTYPE_CONSTANT = "con"; const char* const CFG_MAPTYPE_DATAREF = "drf"; const char* const CFG_MAPTYPE_ENCODER = "enc"; const char* const CFG_MAPTYPE_PUSH_PULL = "pnp"; +const char* const CFG_MAPTYPE_SHORT_AND_LONG = "snl"; const char* const CFG_MAPTYPE_SLIDER = "sld"; diff --git a/src/common/utils.h b/src/common/utils.h index 58529128..1c7eec63 100644 --- a/src/common/utils.h +++ b/src/common/utils.h @@ -31,7 +31,6 @@ class utils { public: static bool create_directory(text_logger& in_log, const std::filesystem::path& in_path); - // TODO: Move to cpp file static std::string ltrim(std::string_view in_str) { return std::regex_replace(in_str.data(), std::regex("^\\s+"), std::string()); } diff --git a/src/device/CMakeLists.txt b/src/device/CMakeLists.txt index f0c88064..7c72ead7 100644 --- a/src/device/CMakeLists.txt +++ b/src/device/CMakeLists.txt @@ -31,24 +31,26 @@ set(DEV_SRC ${CMAKE_CURRENT_LIST_DIR}/device_list.cpp ${CMAKE_CURRENT_LIST_DIR}/midi_device.cpp ${CMAKE_CURRENT_LIST_DIR}/virtual_device.cpp + ${CMAKE_CURRENT_LIST_DIR}/map_init/map_init.cpp + ${CMAKE_CURRENT_LIST_DIR}/map_init/map_init_list.cpp + + ${CMAKE_CURRENT_LIST_DIR}/map_in/label.cpp ${CMAKE_CURRENT_LIST_DIR}/map_in/map_in.cpp ${CMAKE_CURRENT_LIST_DIR}/map_in/map_in_cbv.cpp ${CMAKE_CURRENT_LIST_DIR}/map_in/map_in_cmd.cpp ${CMAKE_CURRENT_LIST_DIR}/map_in/map_in_drf.cpp ${CMAKE_CURRENT_LIST_DIR}/map_in/map_in_enc.cpp - ${CMAKE_CURRENT_LIST_DIR}/map_in/map_in_label.cpp ${CMAKE_CURRENT_LIST_DIR}/map_in/map_in_list.cpp - ${CMAKE_CURRENT_LIST_DIR}/map_in/map_in_pnp.cpp + ${CMAKE_CURRENT_LIST_DIR}/map_in/map_in_snl.cpp ${CMAKE_CURRENT_LIST_DIR}/map_in/map_in_sld.cpp - ${CMAKE_CURRENT_LIST_DIR}/map_init/map_init.cpp - ${CMAKE_CURRENT_LIST_DIR}/map_init/map_init_list.cpp + ${CMAKE_CURRENT_LIST_DIR}/map_out/map_out.cpp ${CMAKE_CURRENT_LIST_DIR}/map_out/map_out_con.cpp ${CMAKE_CURRENT_LIST_DIR}/map_out/map_out_drf.cpp ${CMAKE_CURRENT_LIST_DIR}/map_out/map_out_list.cpp ${CMAKE_CURRENT_LIST_DIR}/map_out/map_out_sld.cpp - ) +) # Build static library add_library(${XMIDICTRL_LIB_DEV} STATIC ${DEV_SRC}) diff --git a/src/device/conversions.cpp b/src/device/conversions.cpp index 1f4b0094..ac5c5b97 100644 --- a/src/device/conversions.cpp +++ b/src/device/conversions.cpp @@ -66,6 +66,8 @@ std::string conversions::map_in_type_to_str(map_in_type in_type) return "Encoder"; case map_in_type::push_pull: return "Push&Pull"; + case map_in_type::short_and_long: + return "Short & long"; case map_in_type::slider: return "Slider"; case map_in_type::none: diff --git a/src/device/map_in/map_in_label.cpp b/src/device/map_in/label.cpp similarity index 51% rename from src/device/map_in/map_in_label.cpp rename to src/device/map_in/label.cpp index b20d3dce..1b334a24 100644 --- a/src/device/map_in/map_in_label.cpp +++ b/src/device/map_in/label.cpp @@ -15,7 +15,7 @@ // If not, see . //--------------------------------------------------------------------------------------------------------------------- -#include "map_in_label.h" +#include "label.h" // fmt #include "fmt/format.h" @@ -32,8 +32,8 @@ namespace xmidictrl { /** * Constructor */ -map_in_label::map_in_label(environment& in_env) - : map_in(in_env) +label::label(environment& in_env) + : m_env(in_env) {} @@ -46,101 +46,22 @@ map_in_label::map_in_label(environment& in_env) /** * Read the config */ -void map_in_label::read_config(text_logger& in_log, toml::value& in_data, toml::value& in_config) -{ - map_in::read_config(in_log, in_data, in_config); - - // additional config - read_label(in_log, in_data, in_config); -} - - -/* - * Return the label name(s) - */ -std::string map_in_label::map_text_label() -{ - if (m_label == nullptr) - return {}; - - return m_label->id; -} - - - - -//--------------------------------------------------------------------------------------------------------------------- -// PROTECTED -//--------------------------------------------------------------------------------------------------------------------- - -/** - * Toggle dataref between values - */ -std::string map_in_label::toggle_dataref(text_logger& in_log, - std::string_view in_dataref, - std::vector& in_values, - bool in_wrap) -{ - auto new_value = map_in::toggle_dataref(in_log, in_dataref, in_values, in_wrap); - display_label(in_log, new_value); - - return new_value; -} - - -/** - * Display the label on the screen - */ -void map_in_label::display_label(text_logger& in_log, float in_value) -{ - std::stringstream ss; - ss << in_value; - - display_label(in_log, ss.str()); -} - - -/** - * Display the label on the screen - */ -void map_in_label::display_label(text_logger& in_log, std::string_view in_value) -{ - if (m_label == nullptr || m_label->id.empty()) { - in_log.debug(" --> No label defined"); - return; - } - - try { - std::string value_text = m_label->values.at(in_value.data()); - in_log.debug(" --> Found text '" + value_text + "' for value '" + std::string(in_value) + "'"); - env().show_info_message(m_label->id, m_label->text + value_text); - } catch (std::out_of_range&) { - env().show_info_message(m_label->id, m_label->text + in_value.data()); - } -} - - - - -//--------------------------------------------------------------------------------------------------------------------- -// PRIVATE -//--------------------------------------------------------------------------------------------------------------------- - -/** - * Read label definition - */ -void map_in_label::read_label(text_logger& in_log, toml::value& in_data, toml::value& in_config) +void label::read_config(text_logger& in_log, + toml::value& in_data, + toml::value& in_config, + std::string_view in_dataref, + std::string_view in_cfg_label) { // is a label defined? - if (!in_data.contains(c_cfg_label.data())) + if (!in_data.contains(in_cfg_label.data())) return; try { - std::string label_id = in_data[c_cfg_label.data()].as_string(); + std::string label_id = in_data[in_cfg_label.data()].as_string(); if (label_id.empty()) { in_log.error_line(in_data.location().line(), "Error reading mapping"); - in_log.error(fmt::format(" --> Parameter '{}' is empty", c_cfg_label)); + in_log.error(fmt::format(" --> Parameter '{}' is empty", in_cfg_label)); return; } @@ -152,18 +73,21 @@ void map_in_label::read_label(text_logger& in_log, toml::value& in_data, toml::v toml::value label_section = toml::find(in_config, label_id); - // create label - m_label = std::make_unique