Skip to content

Commit

Permalink
Merge pull request #326 from 4ms/v1.0-dev
Browse files Browse the repository at this point in the history
Screen support (text only)
  • Loading branch information
danngreen authored Aug 13, 2024
2 parents d218c88 + 9e7f57b commit 43e4710
Show file tree
Hide file tree
Showing 40 changed files with 4,382 additions and 695 deletions.
507 changes: 507 additions & 0 deletions LICENSE-GPL-v3.txt

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions LICENSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
## MetaModule License

MetaModule is copyright (c) 2024 4ms Company.

This program is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or (at your option) any later
version.

See LICENSE-GPL-v3.txt for the text of the license.

The MetaModule name is copyright (c) 2024 4ms Company. It may not be used in
derivative works. However, you may use any of the phrases "works with
MetaModule" or "compatible with MetaModule" or "for MetaModule" when promoting
a plugin which was built with the MetaModule Plugin SDK and runs on the
MetaModule hardware.

Third-party libraries are licensed by the respective licenses of the copyright
holders, which are included in their respective sub-directories.

2 changes: 1 addition & 1 deletion firmware/metamodule-plugin-sdk
9 changes: 9 additions & 0 deletions firmware/src/core_a7/aux_core_main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,21 @@ extern "C" void aux_core_main() {
constexpr auto ReadPatchLightsIRQn = SMPControl::IRQn(SMPCommand::ReadPatchLights);
InterruptManager::register_and_start_isr(ReadPatchLightsIRQn, 2, 0, [patch_player, &ui]() {
if (ui.new_patch_data == false) {

for (auto &w : ui.lights().watch_lights) {
if (w.is_active()) {
auto val = patch_player->get_module_light(w.module_id, w.light_id);
w.value = val;
}
}

for (auto &d : ui.displays().watch_displays) {
if (d.is_active()) {
auto text = std::span<char>(d.text._data, d.text.capacity);
patch_player->get_display_text(d.module_id, d.light_id, text);
}
}

ui.new_patch_data = true;
}

Expand Down
8 changes: 8 additions & 0 deletions firmware/src/gui/elements/draw.hh
Original file line number Diff line number Diff line change
Expand Up @@ -249,4 +249,12 @@ inline lv_obj_t *draw_element(const TextDisplay &el, lv_obj_t *canvas, uint32_t
return label;
}

inline lv_obj_t *draw_element(const DynamicTextDisplay &el, lv_obj_t *canvas, uint32_t module_h) {
auto label = draw_element(TextDisplay(el), canvas, module_h);
//DOT mode don't work with dynamic elements
//because we can't compare the new text with the existing text since it may contain dots
lv_label_set_long_mode(label, LV_LABEL_LONG_CLIP);
return label;
}

} // namespace MetaModule::ElementDrawer
49 changes: 49 additions & 0 deletions firmware/src/gui/elements/redraw_display.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#pragma once
#include "CoreModules/elements/elements.hh"
#include "debug.hh"
#include "gui/elements/context.hh"
#include "gui/images/paths.hh"
#include "lvgl.h"
#include "patch_data.hh"
#include "patch_play/text_display.hh"
#include "pr_dbg.hh"
#include "util/overloaded.hh"

namespace MetaModule
{

inline bool redraw_text(lv_obj_t *obj, std::string_view text) {
bool is_label = lv_obj_has_class(obj, &lv_label_class);
if (is_label) {
if (text != lv_label_get_text(obj)) {
lv_label_set_text(obj, text.data());
return true;
}
}
return false;
}

inline bool redraw_display(DrawnElement &drawn_el,
unsigned this_module_id,
std::array<WatchedTextDisplay, TextDisplayWatcher::MaxDisplaysToWatch> &watch_displays) {

bool was_redrawn = false;
if (drawn_el.element.index() == Element{DynamicTextDisplay{}}.index()) {

// Scan all watch_displays to find a match
for (auto &d : watch_displays) {
if (!d.is_active())
continue;
if (d.module_id != this_module_id)
continue;
if (d.light_id != drawn_el.gui_element.idx.light_idx)
continue;

was_redrawn = redraw_text(drawn_el.gui_element.obj, d.text);
break;
}
}
return was_redrawn;
}

} // namespace MetaModule
6 changes: 4 additions & 2 deletions firmware/src/gui/pages/cable_drawer.hh
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once
#include "CoreModules/elements/element_info.hh"
#include "CoreModules/moduleFactory.hh"
#include "cmsis_gcc.h"
#include "gui/elements/context.hh"
#include "gui/styles.hh"
#include "lvgl.h"
Expand Down Expand Up @@ -185,11 +186,13 @@ public:
draw_cable(start, end);
}

static constexpr size_t MAX_STEPS = 128;

void draw_cable(Vec2 start, Vec2 end) {
float dist_x = std::abs(start.x - end.x);
float dist_y = std::abs(start.y - end.y);
CableDrawer::Vec2 control{(start.x + end.x) / 2, ((start.y + end.y) / 2) + (int32_t)dist_x};
auto steps = std::max<unsigned>(dist_x * dist_y / 1000, 8);
auto steps = std::clamp<unsigned>(dist_x * dist_y / 1000, 8, MAX_STEPS - 1);
CableDrawer::draw_bezier(start, end, control, steps);
}

Expand All @@ -213,7 +216,6 @@ public:
}

void draw_bezier(Vec2 start, Vec2 end, Vec2 control, unsigned steps) {
constexpr size_t MAX_STEPS = 128;

float step_size = 1.0f / steps;
lv_point_t points[MAX_STEPS];
Expand Down
4 changes: 2 additions & 2 deletions firmware/src/gui/pages/description_panel.hh
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,6 @@ struct PatchDescriptionPanel {

void set_patch(PatchData *cur_patch) {
patch = cur_patch;
lv_label_set_text(ui_Description, patch->description.c_str());
lv_label_set_text(ui_DescPanelPatchName, patch->patch_name.c_str());
}

bool is_visible() {
Expand Down Expand Up @@ -77,6 +75,8 @@ struct PatchDescriptionPanel {
is_showing = true;
edit_panel_visible = false;

lv_label_set_text(ui_Description, patch->description.c_str());
lv_label_set_text(ui_DescPanelPatchName, patch->patch_name.c_str());
set_content_max_height(ui_DescriptionPanel, 230);
}

Expand Down
18 changes: 15 additions & 3 deletions firmware/src/gui/pages/module_view.hh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "gui/elements/map_ring_animate.hh"
#include "gui/elements/module_drawer.hh"
#include "gui/elements/redraw.hh"
#include "gui/elements/redraw_display.hh"
#include "gui/elements/redraw_light.hh"
#include "gui/pages/base.hh"
#include "gui/pages/cable_drawer.hh"
Expand Down Expand Up @@ -126,9 +127,17 @@ struct ModuleViewPage : PageBase {
for (auto [drawn_el_idx, drawn_element] : enumerate(drawn_elements)) {
auto &drawn = drawn_element.gui_element;

for (unsigned i = 0; i < drawn.count.num_lights; i++) {
params.lights.start_watching_light(this_module_id, drawn.idx.light_idx + i);
}
std::visit(overloaded{
[&](auto const &el) {
for (unsigned i = 0; i < drawn.count.num_lights; i++) {
params.lights.start_watching_light(this_module_id, drawn.idx.light_idx + i);
}
},
[&](DynamicTextDisplay const &el) {
params.displays.start_watching_display(this_module_id, drawn.idx.light_idx);
},
},
drawn_element.element);

auto base = base_element(drawn_element.element);

Expand Down Expand Up @@ -279,6 +288,8 @@ struct ModuleViewPage : PageBase {
}

update_light(drawn_el, light_vals);

redraw_display(drawn_el, this_module_id, params.displays.watch_displays);
}
}

Expand Down Expand Up @@ -344,6 +355,7 @@ struct ModuleViewPage : PageBase {

void blur() final {
params.lights.stop_watching_all();
params.displays.stop_watching_all();
settings_menu.hide();
action_menu.hide();
}
Expand Down
22 changes: 17 additions & 5 deletions firmware/src/gui/pages/patch_view.hh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "gui/elements/mapping.hh"
#include "gui/elements/module_drawer.hh"
#include "gui/elements/redraw.hh"
#include "gui/elements/redraw_display.hh"
#include "gui/elements/redraw_light.hh"
#include "gui/helpers/lv_helpers.hh"
#include "gui/pages/base.hh"
Expand Down Expand Up @@ -208,6 +209,8 @@ struct PatchViewPage : PageBase {
settings_menu.hide();
desc_panel.hide();
file_menu.hide();
params.displays.stop_watching_all();
params.lights.stop_watching_all();
}

void update() override {
Expand Down Expand Up @@ -255,7 +258,6 @@ struct PatchViewPage : PageBase {
} else {
page_list.request_last_page();
blur();
params.lights.stop_watching_all();
}
}

Expand Down Expand Up @@ -299,9 +301,18 @@ private:
if (is_patch_playing) {
for (const auto &drawn_element : drawn_elements) {
auto &gui_el = drawn_element.gui_element;
for (unsigned i = 0; i < gui_el.count.num_lights; i++) {
params.lights.start_watching_light(gui_el.module_idx, gui_el.idx.light_idx + i);
}

std::visit(overloaded{
[&](auto const &el) {
for (unsigned i = 0; i < gui_el.count.num_lights; i++) {
params.lights.start_watching_light(gui_el.module_idx, gui_el.idx.light_idx + i);
}
},
[&](DynamicTextDisplay const &el) {
params.displays.start_watching_display(gui_el.module_idx, gui_el.idx.light_idx);
},
},
drawn_element.element);
}
}
}
Expand Down Expand Up @@ -343,7 +354,6 @@ private:
auto &gui_el = drawn_el.gui_element;

auto was_redrawn = std::visit(RedrawElement{patch, drawn_el.gui_element}, drawn_el.element);

if (was_redrawn) {
if (page_settings.map_ring_flash_active)
map_ring_display.flash_once(gui_el.map_ring, highlighted_module_id == gui_el.module_idx);
Expand All @@ -353,6 +363,8 @@ private:
}

update_light(drawn_el, light_vals[gui_el.module_idx]);

redraw_display(drawn_el, gui_el.module_idx, params.displays.watch_displays);
}
}

Expand Down
11 changes: 7 additions & 4 deletions firmware/src/gui/pages/patch_view_file_menu.hh
Original file line number Diff line number Diff line change
Expand Up @@ -207,9 +207,12 @@ private:
}

void copy_patchname_to_filename() {
// Copy patchname -> filename if patchname has been set
std::string patchname = patches.get_view_patch()->patch_name;
patchname.append(".yml");
patches.set_patch_filename(patchname);
if (!patchname.starts_with("Untitled Patch ")) {
patchname.append(".yml");
patches.set_patch_filename(patchname);
}
}

static void menu_button_cb(lv_event_t *event) {
Expand Down Expand Up @@ -243,8 +246,8 @@ private:
return;
auto page = static_cast<PatchViewFileMenu *>(event->user_data);

// If the filename has not been set yet, set it to the patchname + .yml
if (page->patches.get_view_patch_filename().starts_with("Untitled Patch ")) {
// If it hasn't been saved yet, use the patchname if its been set
if (page->patches.get_view_patch_vol() == Volume::RamDisk) {
page->copy_patchname_to_filename();
}
page->show_save_dialog();
Expand Down
5 changes: 5 additions & 0 deletions firmware/src/gui/pages/save_dialog.hh
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,11 @@ private:
if (page->patches.get_view_patch_vol() == Volume::RamDisk) {
page->patches.rename_view_patch_file(fullpath, page->file_vol);
page->patch_playloader.request_save_patch();
auto &patchname = page->patches.get_view_patch()->patch_name;
if (std::string_view(patchname).starts_with("Untitled Patch ")) {
patchname.copy(page->file_name);
}

page->saved = true;
page->hide();
} else {
Expand Down
2 changes: 1 addition & 1 deletion firmware/src/gui/pages/system_tab.hh
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ private:
}
},
"Do you really want to PERMANENTLY DELETE all patches stored internally? This will replace them with "
"factory default patches.\n",
"factory default patches. You must reboot.\n",
"Delete");
}

Expand Down
7 changes: 6 additions & 1 deletion firmware/src/gui/ui.hh
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ public:
plugin_manager.autoload_plugins(settings.plugin_autoload);
}

TextDisplayWatcher &displays() {
return params.displays;
}

bool new_patch_data = false;

private:
Expand All @@ -106,7 +110,8 @@ private:

auto load_status = patch_playloader.handle_file_events();
if (!load_status.success) {
notify_queue.put({load_status.error_string, Notification::Priority::Error, 3000});
notify_queue.put({load_status.error_string, Notification::Priority::Error, 1500});

} else if (load_status.error_string.size()) {
notify_queue.put({load_status.error_string, Notification::Priority::Info, 3000});
}
Expand Down
3 changes: 3 additions & 0 deletions firmware/src/params/params_state.hh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "patch.hh"
#include "patch/midi_def.hh"
#include "patch_play/lights.hh"
#include "patch_play/text_display.hh"
#include "util/debouncer.hh"
#include "util/parameter.hh"
#include "util/zip.hh"
Expand Down Expand Up @@ -77,11 +78,13 @@ struct ParamsMidiState : ParamsState {
bool midi_gate = false;

LightWatcher lights;
TextDisplayWatcher displays;

void clear() {
ParamsState::clear();

lights.stop_watching_all();
displays.stop_watching_all();

for (auto &cc : midi_ccs)
cc = 0;
Expand Down
Loading

0 comments on commit 43e4710

Please sign in to comment.