diff options
Diffstat (limited to 'Marlin/src/lcd/menu/menu_mixer.cpp')
-rw-r--r-- | Marlin/src/lcd/menu/menu_mixer.cpp | 278 |
1 files changed, 278 insertions, 0 deletions
diff --git a/Marlin/src/lcd/menu/menu_mixer.cpp b/Marlin/src/lcd/menu/menu_mixer.cpp new file mode 100644 index 0000000..d07b89c --- /dev/null +++ b/Marlin/src/lcd/menu/menu_mixer.cpp @@ -0,0 +1,278 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + * + */ + +// +// Mixer Menu +// + +#include "../../inc/MarlinConfigPre.h" + +#if BOTH(HAS_LCD_MENU, MIXING_EXTRUDER) + +#include "menu_item.h" +#include "menu_addon.h" + +#include "../../feature/mixing.h" + +#if HAS_GRAPHICAL_TFT + #include "../tft/tft.h" +#endif + +#define CHANNEL_MIX_EDITING !HAS_DUAL_MIXING + +#if ENABLED(GRADIENT_MIX) + + void _lcd_mixer_gradient_z_edit(const bool isend) { + ui.defer_status_screen(); + ENCODER_RATE_MULTIPLY(true); + + float &zvar = isend ? mixer.gradient.end_z : mixer.gradient.start_z; + + if (ui.encoderPosition) { + zvar += float(int32_t(ui.encoderPosition)) * 0.1; + ui.encoderPosition = 0; + NOLESS(zvar, 0); + NOMORE(zvar, Z_MAX_POS); + } + + if (ui.should_draw()) { + char tmp[16]; + SETCURSOR(1, (LCD_HEIGHT - 1) / 2); + lcd_put_u8str_P(isend ? GET_TEXT(MSG_END_Z) : GET_TEXT(MSG_START_Z)); + sprintf_P(tmp, PSTR("%4d.%d mm"), int(zvar), int(zvar * 10) % 10); + SETCURSOR_RJ(9, (LCD_HEIGHT - 1) / 2); + lcd_put_u8str(tmp); + } + + if (ui.lcd_clicked) { + if (isend && zvar < mixer.gradient.start_z) + mixer.gradient.start_z = zvar; + else if (!isend && zvar > mixer.gradient.end_z) + mixer.gradient.end_z = zvar; + mixer.refresh_gradient(); + ui.goto_previous_screen(); + } + else { + TERN_(HAS_GRAPHICAL_TFT, tft.draw_edit_screen_buttons()); + } + } + + void lcd_mixer_edit_gradient_menu() { + START_MENU(); + BACK_ITEM(MSG_MIXER); + + EDIT_ITEM(int8, MSG_START_VTOOL, &mixer.gradient.start_vtool, 0, MIXING_VIRTUAL_TOOLS - 1, mixer.refresh_gradient); + EDIT_ITEM(int8, MSG_END_VTOOL, &mixer.gradient.end_vtool, 0, MIXING_VIRTUAL_TOOLS - 1, mixer.refresh_gradient); + + #if ENABLED(GRADIENT_VTOOL) + EDIT_ITEM(int8, MSG_GRADIENT_ALIAS, &mixer.gradient.vtool_index, -1, MIXING_VIRTUAL_TOOLS - 1, mixer.refresh_gradient); + #endif + + char tmp[18]; + + PGM_P const slabel = GET_TEXT(MSG_START_Z); + SUBMENU_P(slabel, []{ _lcd_mixer_gradient_z_edit(false); }); + MENU_ITEM_ADDON_START_RJ(11); + sprintf_P(tmp, PSTR("%4d.%d mm"), int(mixer.gradient.start_z), int(mixer.gradient.start_z * 10) % 10); + lcd_put_u8str(tmp); + MENU_ITEM_ADDON_END(); + + PGM_P const elabel = GET_TEXT(MSG_END_Z); + SUBMENU_P(elabel, []{ _lcd_mixer_gradient_z_edit(true); }); + MENU_ITEM_ADDON_START_RJ(11); + sprintf_P(tmp, PSTR("%4d.%d mm"), int(mixer.gradient.end_z), int(mixer.gradient.end_z * 10) % 10); + lcd_put_u8str(tmp); + MENU_ITEM_ADDON_END(); + + END_MENU(); + } + +#endif // GRADIENT_MIX + +static uint8_t v_index; + +#if HAS_DUAL_MIXING + void _lcd_draw_mix(const uint8_t y) { + char tmp[20]; // "100%_100%" + sprintf_P(tmp, PSTR("%3d%% %3d%%"), int(mixer.mix[0]), int(mixer.mix[1])); + SETCURSOR(2, y); lcd_put_u8str_P(GET_TEXT(MSG_MIX)); + SETCURSOR_RJ(10, y); lcd_put_u8str(tmp); + } +#endif + +void _lcd_mixer_select_vtool() { + mixer.T(v_index); + TERN_(HAS_DUAL_MIXING, _lcd_draw_mix(LCD_HEIGHT - 1)); +} + +#if CHANNEL_MIX_EDITING + + void _lcd_mixer_cycle_mix() { + uint16_t bits = 0; + MIXER_STEPPER_LOOP(i) if (mixer.collector[i]) SBI(bits, i); + bits = (bits + 1) & (_BV(MIXING_STEPPERS) - 1); + if (!bits) ++bits; + MIXER_STEPPER_LOOP(i) mixer.collector[i] = TEST(bits, i) ? 10.0f : 0.0f; + ui.refresh(); + } + + void _lcd_mixer_commit_vtool() { + mixer.normalize(); + ui.goto_previous_screen(); + } + +#endif + +void lcd_mixer_mix_edit() { + + #if HAS_DUAL_MIXING && !CHANNEL_MIX_EDITING + + // Adjust 2-channel mix from the encoder + if (ui.encoderPosition) { + mixer.mix[0] += int32_t(ui.encoderPosition); + ui.encoderPosition = 0; + if (mixer.mix[0] < 0) mixer.mix[0] += 101; + if (mixer.mix[0] > 100) mixer.mix[0] -= 101; + mixer.mix[1] = 100 - mixer.mix[0]; + } + _lcd_draw_mix((LCD_HEIGHT - 1) / 2); + + // Click to commit the change + if (ui.lcd_clicked) { + mixer.update_vtool_from_mix(); + ui.goto_previous_screen(); + } + + TERN_(HAS_GRAPHICAL_TFT, tft.draw_edit_screen_buttons()); + + #else + + START_MENU(); + BACK_ITEM(MSG_MIXER); + + #if CHANNEL_MIX_EDITING + + LOOP_S_LE_N(n, 1, MIXING_STEPPERS) + EDIT_ITEM_FAST_N(float42_52, n, MSG_MIX_COMPONENT_N, &mixer.collector[n-1], 0, 10); + + ACTION_ITEM(MSG_CYCLE_MIX, _lcd_mixer_cycle_mix); + ACTION_ITEM(MSG_COMMIT_VTOOL, _lcd_mixer_commit_vtool); + + #endif + + END_MENU(); + + #endif +} + +#if HAS_DUAL_MIXING + + // + // Toggle Dual-Mix + // + inline void _lcd_mixer_toggle_mix() { + mixer.mix[0] = mixer.mix[0] == 100 ? 0 : 100; + mixer.mix[1] = 100 - mixer.mix[0]; + mixer.update_vtool_from_mix(); + ui.refresh(LCDVIEW_CALL_REDRAW_NEXT); + } + +#endif + +#if CHANNEL_MIX_EDITING + + // + // Prepare and Edit Mix + // + inline void _lcd_goto_mix_edit() { + mixer.refresh_collector(10, v_index); + ui.goto_screen(lcd_mixer_mix_edit); + lcd_mixer_mix_edit(); + } + +#endif + +#if ENABLED(GRADIENT_MIX) + // + // Reverse Gradient + // + inline void _lcd_mixer_reverse_gradient() { + const uint8_t sv = mixer.gradient.start_vtool; + mixer.gradient.start_vtool = mixer.gradient.end_vtool; + mixer.gradient.end_vtool = sv; + mixer.refresh_gradient(); + ui.refresh(LCDVIEW_CALL_REDRAW_NEXT); + } +#endif + +void menu_mixer() { + START_MENU(); + BACK_ITEM(MSG_MAIN); + + v_index = mixer.get_current_vtool(); + EDIT_ITEM(uint8, MSG_ACTIVE_VTOOL, &v_index, 0, MIXING_VIRTUAL_TOOLS - 1, _lcd_mixer_select_vtool, ENABLED(HAS_DUAL_MIXING)); + + #if HAS_DUAL_MIXING + { + char tmp[11]; + SUBMENU(MSG_MIX, lcd_mixer_mix_edit); + MENU_ITEM_ADDON_START_RJ(9); + mixer.update_mix_from_vtool(); + sprintf_P(tmp, PSTR("%3d;%3d%%"), int(mixer.mix[0]), int(mixer.mix[1])); + lcd_put_u8str(tmp); + MENU_ITEM_ADDON_END(); + ACTION_ITEM(MSG_TOGGLE_MIX, _lcd_mixer_toggle_mix); + } + #else + SUBMENU(MSG_MIX, _lcd_goto_mix_edit); + #endif + + // + // Reset All V-Tools + // + CONFIRM_ITEM(MSG_RESET_VTOOLS, + MSG_BUTTON_RESET, MSG_BUTTON_CANCEL, + []{ + mixer.reset_vtools(); + LCD_MESSAGEPGM(MSG_VTOOLS_RESET); + ui.return_to_status(); + }, + nullptr, + GET_TEXT(MSG_RESET_VTOOLS), (const char *)nullptr, PSTR("?") + ); + + #if ENABLED(GRADIENT_MIX) + { + char tmp[13]; + SUBMENU(MSG_GRADIENT, lcd_mixer_edit_gradient_menu); + MENU_ITEM_ADDON_START_RJ(9); + sprintf_P(tmp, PSTR("T%i->T%i"), mixer.gradient.start_vtool, mixer.gradient.end_vtool); + lcd_put_u8str(tmp); + MENU_ITEM_ADDON_END(); + ACTION_ITEM(MSG_REVERSE_GRADIENT, _lcd_mixer_reverse_gradient); + } + #endif + + END_MENU(); +} + +#endif // HAS_LCD_MENU && MIXING_EXTRUDER |