diff --git a/CYD-Klipper/.vscode/settings.json b/CYD-Klipper/.vscode/settings.json index 03d5353..75d2259 100644 --- a/CYD-Klipper/.vscode/settings.json +++ b/CYD-Klipper/.vscode/settings.json @@ -8,6 +8,7 @@ "unordered_set": "cpp", "vector": "cpp", "string_view": "cpp", - "initializer_list": "cpp" + "initializer_list": "cpp", + "algorithm": "cpp" } } \ No newline at end of file diff --git a/CYD-Klipper/src/conf/global_config.cpp b/CYD-Klipper/src/conf/global_config.cpp index a23e3c3..978e1b9 100644 --- a/CYD-Klipper/src/conf/global_config.cpp +++ b/CYD-Klipper/src/conf/global_config.cpp @@ -41,6 +41,12 @@ void LoadGlobalConfig() { global_config.version = CONFIG_VERSION; global_config.brightness = 255; global_config.screenTimeout = 5; + global_config.hotend_presets[0] = 0; + global_config.hotend_presets[1] = 200; + global_config.hotend_presets[2] = 240; + global_config.bed_presets[0] = 0; + global_config.bed_presets[1] = 60; + global_config.bed_presets[2] = 70; VerifyVersion(); Preferences preferences; preferences.begin("global_config", true); diff --git a/CYD-Klipper/src/conf/global_config.h b/CYD-Klipper/src/conf/global_config.h index 05f510e..975315a 100644 --- a/CYD-Klipper/src/conf/global_config.h +++ b/CYD-Klipper/src/conf/global_config.h @@ -3,7 +3,7 @@ #include "lvgl.h" -#define CONFIG_VERSION 2 +#define CONFIG_VERSION 3 typedef struct _GLOBAL_CONFIG { unsigned char version; @@ -33,6 +33,9 @@ typedef struct _GLOBAL_CONFIG { unsigned char color_scheme; unsigned char brightness; unsigned char screenTimeout; + + unsigned short hotend_presets[3]; + unsigned short bed_presets[3]; } GLOBAL_CONFIG; typedef struct _COLOR_DEF { diff --git a/CYD-Klipper/src/core/data_setup.cpp b/CYD-Klipper/src/core/data_setup.cpp index fde8eee..4d8927e 100644 --- a/CYD-Klipper/src/core/data_setup.cpp +++ b/CYD-Klipper/src/core/data_setup.cpp @@ -4,6 +4,7 @@ #include "../conf/global_config.h" #include #include +#include "macros_query.h" const char *printer_state_messages[] = { "Error", @@ -179,4 +180,5 @@ void data_setup() { printer.print_filename = filename_buff; fetch_printer_data(); + macros_query_setup(); } \ No newline at end of file diff --git a/CYD-Klipper/src/core/data_setup.h b/CYD-Klipper/src/core/data_setup.h index 6439166..4e08ab5 100644 --- a/CYD-Klipper/src/core/data_setup.h +++ b/CYD-Klipper/src/core/data_setup.h @@ -31,6 +31,7 @@ extern Printer printer; #define DATA_PRINTER_STATE 1 #define DATA_PRINTER_DATA 2 +#define DATA_PRINTER_TEMP_PRESET 3 void data_loop(); void data_setup(); diff --git a/CYD-Klipper/src/core/macros_query.cpp b/CYD-Klipper/src/core/macros_query.cpp new file mode 100644 index 0000000..11ddef3 --- /dev/null +++ b/CYD-Klipper/src/core/macros_query.cpp @@ -0,0 +1,51 @@ +#include "lvgl.h" +#include "macros_query.h" +#include "./data_setup.h" +#include +#include "../conf/global_config.h" +#include + +static char* macros[64] = {0}; +static int macros_count = 0; + +static void on_state_change(void * s, lv_msg_t * m) { + if (printer.state == PRINTER_STATE_ERROR || printer.state == PRINTER_STATE_PAUSED){ + return; + } + + String url = "http://" + String(global_config.klipperHost) + ":" + String(global_config.klipperPort) + "/printer/gcode/help"; + HTTPClient client; + client.begin(url.c_str()); + int httpCode = client.GET(); + if (httpCode == 200){ + String payload = client.getString(); + DynamicJsonDocument doc(16384); + deserializeJson(doc, payload); + auto result = doc["result"].as(); + + for (int i = 0; i < macros_count; i++){ + free(macros[i]); + } + + macros_count = 0; + + for (JsonPair i : result){ + const char *key = i.key().c_str(); + const char *value = i.value().as().c_str(); + if (strcmp(value, "CYD_SCREEN_MACRO") == 0) { + char* macro = (char*)malloc(strlen(key) + 1); + strcpy(macro, key); + macros[macros_count++] = macro; + } + } + } +} + +MACROSQUERY macros_query() { + return {(const char**)macros, macros_count}; +} + +void macros_query_setup(){ + lv_msg_subscribe(DATA_PRINTER_STATE, on_state_change, NULL); + on_state_change(NULL, NULL); +} \ No newline at end of file diff --git a/CYD-Klipper/src/core/macros_query.h b/CYD-Klipper/src/core/macros_query.h new file mode 100644 index 0000000..5fdee3f --- /dev/null +++ b/CYD-Klipper/src/core/macros_query.h @@ -0,0 +1,9 @@ +#pragma once + +typedef struct { + const char** macros; + uint32_t count; +} MACROSQUERY; + +MACROSQUERY macros_query(); +void macros_query_setup(); \ No newline at end of file diff --git a/CYD-Klipper/src/main.cpp b/CYD-Klipper/src/main.cpp index 3517415..89851ff 100644 --- a/CYD-Klipper/src/main.cpp +++ b/CYD-Klipper/src/main.cpp @@ -30,28 +30,6 @@ void setup() { nav_style_setup(); main_ui_setup(); - - - - /* - lv_obj_clean(lv_scr_act()); - - lv_obj_t * label; - - lv_obj_t * btn1 = lv_btn_create(lv_scr_act()); - lv_obj_add_event_cb(btn1, event_handler, LV_EVENT_CLICKED, NULL); - lv_obj_align(btn1, LV_ALIGN_CENTER, 0, 0); - - label = lv_label_create(btn1); - lv_label_set_text(label, "Reset Configuration"); - lv_obj_center(label); - - lv_obj_t * slider = lv_slider_create(lv_scr_act()); - lv_obj_set_width(slider, 200); - lv_obj_align(slider, LV_ALIGN_CENTER, 0, 40); - lv_slider_set_range(slider, 0, 100); - lv_slider_set_value(slider, 50, LV_ANIM_OFF); - */ } void loop(){ diff --git a/CYD-Klipper/src/ui/nav_buttons.cpp b/CYD-Klipper/src/ui/nav_buttons.cpp index 0cee3ee..e056316 100644 --- a/CYD-Klipper/src/ui/nav_buttons.cpp +++ b/CYD-Klipper/src/ui/nav_buttons.cpp @@ -71,6 +71,10 @@ static void btn_click_settings(lv_event_t * e){ nav_buttons_setup(3); } +static void btn_click_macros(lv_event_t * e){ + nav_buttons_setup(4); +} + void nav_buttons_setup(unsigned char active_panel){ lv_obj_clean(lv_scr_act()); lv_obj_clear_flag(lv_scr_act(), LV_OBJ_FLAG_SCROLLABLE); @@ -140,14 +144,14 @@ void nav_buttons_setup(unsigned char active_panel){ lv_obj_set_size(btn, button_width, button_height); lv_obj_align(btn, LV_ALIGN_TOP_LEFT, 0, button_height * 3); lv_obj_add_style(btn, &nav_button_style, 0); - lv_obj_add_event_cb(btn, btn_click_settings, LV_EVENT_CLICKED, NULL); + lv_obj_add_event_cb(btn, btn_click_macros, LV_EVENT_CLICKED, NULL); label = lv_label_create(btn); - lv_label_set_text(label, LV_SYMBOL_SETTINGS); + lv_label_set_text(label, LV_SYMBOL_GPS); lv_obj_align(label, LV_ALIGN_CENTER, 0, -1 * icon_text_spacing); label = lv_label_create(btn); - lv_label_set_text(label, "Screen"); + lv_label_set_text(label, "Macro"); lv_obj_align(label, LV_ALIGN_CENTER, 0, icon_text_spacing); lv_obj_add_style(label, &nav_button_text_style, 0); @@ -171,6 +175,9 @@ void nav_buttons_setup(unsigned char active_panel){ case 3: settings_panel_init(panel); break; + case 4: + macros_panel_init(panel); + break; } } diff --git a/CYD-Klipper/src/ui/panels/macros_panel.cpp b/CYD-Klipper/src/ui/panels/macros_panel.cpp new file mode 100644 index 0000000..16348fb --- /dev/null +++ b/CYD-Klipper/src/ui/panels/macros_panel.cpp @@ -0,0 +1,81 @@ +#include "lvgl.h" +#include "panel.h" +#include "../nav_buttons.h" +#include "../../core/data_setup.h" +#include "../../core/macros_query.h" +#include + +int y_offset_macros = 40; +const int y_element_size = 50; +const int y_seperator_size = 1; +const int y_seperator_x_padding = 50; +const int panel_width = TFT_HEIGHT - 40; +const int y_element_x_padding = 30; +const static lv_point_t line_points[] = { {0, 0}, {panel_width - y_seperator_x_padding, 0} }; + +static void btn_press(lv_event_t * e){ + lv_obj_t * btn = lv_event_get_target(e); + const char* macro = (const char*)lv_event_get_user_data(e); + Serial.printf("Macro: %s\n", macro); + send_gcode(false, macro); +} + +static void btn_goto_settings(lv_event_t * e){ + nav_buttons_setup(3); +} + +void create_macro_widget(const char* macro, lv_obj_t* root_panel){ + lv_obj_t * panel = lv_obj_create(root_panel); + lv_obj_set_style_border_width(panel, 0, 0); + lv_obj_set_style_bg_opa(panel, LV_OPA_TRANSP, 0); + lv_obj_set_style_pad_all(panel, 0, 0); + lv_obj_align(panel, LV_ALIGN_TOP_MID, 0, y_offset_macros); + lv_obj_set_size(panel, panel_width - y_element_x_padding, y_element_size); + + lv_obj_t * line = lv_line_create(panel); + lv_line_set_points(line, line_points, 2); + lv_obj_set_style_line_width(line, y_seperator_size, 0); + lv_obj_set_style_line_color(line, lv_color_hex(0xAAAAAA), 0); + lv_obj_align(line, LV_ALIGN_BOTTOM_MID, 0, 0); + + lv_obj_t * label = lv_label_create(panel); + lv_label_set_text(label, macro); + lv_obj_align(label, LV_ALIGN_LEFT_MID, 0, 0); + lv_label_set_long_mode(label, LV_LABEL_LONG_SCROLL_CIRCULAR); + lv_obj_set_width(label, (TFT_HEIGHT - 40) * 0.75f); + + lv_obj_t * btn = lv_btn_create(panel); + lv_obj_align(btn, LV_ALIGN_RIGHT_MID, 0, 0); + lv_obj_add_event_cb(btn, btn_press, LV_EVENT_CLICKED, (void*)macro); + + label = lv_label_create(btn); + lv_label_set_text(label, "Run"); + lv_obj_center(label); + + y_offset_macros += y_element_size; +} + +void macros_panel_init(lv_obj_t* panel) { + y_offset_macros = 40; + + lv_obj_t * btn = lv_btn_create(panel); + lv_obj_add_event_cb(btn, btn_goto_settings, LV_EVENT_CLICKED, NULL); + lv_obj_set_size(btn, TFT_HEIGHT - 40 - 20, 30); + lv_obj_align(btn, LV_ALIGN_TOP_MID, 0, 5); + + lv_obj_t * label = lv_label_create(btn); + lv_label_set_text(label, LV_SYMBOL_SETTINGS " Screen Settings"); + lv_obj_center(label); + + MACROSQUERY query = macros_query(); + if (query.count == 0){ + label = lv_label_create(panel); + lv_label_set_text(label, "No macros found.\nMacros with the description\n\"CYD_SCREEN_MACRO\"\nwill show up here."); + lv_obj_align(label, LV_ALIGN_CENTER, 0, 0); + return; + } + + for (int i = 0; i < query.count; i++){ + create_macro_widget(query.macros[i], panel); + } +} \ No newline at end of file diff --git a/CYD-Klipper/src/ui/panels/panel.h b/CYD-Klipper/src/ui/panels/panel.h index 251f833..ac65776 100644 --- a/CYD-Klipper/src/ui/panels/panel.h +++ b/CYD-Klipper/src/ui/panels/panel.h @@ -6,4 +6,5 @@ void settings_panel_init(lv_obj_t* panel); void temp_panel_init(lv_obj_t* panel); void print_panel_init(lv_obj_t* panel); void move_panel_init(lv_obj_t* panel); -void progress_panel_init(lv_obj_t* panel); \ No newline at end of file +void progress_panel_init(lv_obj_t* panel); +void macros_panel_init(lv_obj_t* panel); \ No newline at end of file diff --git a/CYD-Klipper/src/ui/panels/print_panel.cpp b/CYD-Klipper/src/ui/panels/print_panel.cpp index a90137c..a44d9b6 100644 --- a/CYD-Klipper/src/ui/panels/print_panel.cpp +++ b/CYD-Klipper/src/ui/panels/print_panel.cpp @@ -12,8 +12,27 @@ static void btn_print_file(lv_event_t * e){ lv_obj_t * panel = (lv_obj_t*)lv_event_get_user_data(e); lv_obj_del(panel); - char* buff = (char*)malloc(128 + strlen(selected_file->name)); - sprintf(buff, "http://%s:%d/printer/print/start?filename=%s", global_config.klipperHost, global_config.klipperPort, selected_file->name); + char* buff = (char*)malloc(128 + (strlen(selected_file->name) * 3)); + sprintf(buff, "http://%s:%d/printer/print/start?filename=", global_config.klipperHost, global_config.klipperPort); + + char* ptr = buff + strlen(buff); + int filename_length = strlen(selected_file->name); + for (int i = 0; i < filename_length; i++){ + char c = selected_file->name[i]; + if (c == ' '){ + *ptr = '%'; + ptr++; + *ptr = '2'; + ptr++; + *ptr = '0'; + } else { + *ptr = c; + } + ptr++; + } + + *ptr = 0; + HTTPClient client; client.begin(buff); int httpCode = client.POST(""); diff --git a/CYD-Klipper/src/ui/panels/temp_panel.cpp b/CYD-Klipper/src/ui/panels/temp_panel.cpp index 9621bdb..f055869 100644 --- a/CYD-Klipper/src/ui/panels/temp_panel.cpp +++ b/CYD-Klipper/src/ui/panels/temp_panel.cpp @@ -1,25 +1,70 @@ #include "lvgl.h" -#include "panel.h" #include "../../core/data_setup.h" +#include "../../conf/global_config.h" #include -// False: Hotend, True: Bed -static bool hotend_or_bed = true; +enum temp_target{ + TARGET_HOTEND, + TARGET_BED, + TARGET_HOTEND_CONFIG_1, + TARGET_HOTEND_CONFIG_2, + TARGET_HOTEND_CONFIG_3, + TARGET_BED_CONFIG_1, + TARGET_BED_CONFIG_2, + TARGET_BED_CONFIG_3, +}; + +static temp_target keyboard_target; static char hotend_buff[40]; static char bed_buff[40]; +static bool edit_mode = false; +lv_obj_t* root_panel; static void update_printer_data_hotend_temp(lv_event_t * e){ lv_obj_t * label = lv_event_get_target(e); - sprintf(hotend_buff, "Hotend: %.0f C\nTarget: %.0f C", printer.extruder_temp, printer.extruder_target_temp); + sprintf(hotend_buff, "Hotend: %.0f C (Target: %.0f C)", printer.extruder_temp, printer.extruder_target_temp); lv_label_set_text(label, hotend_buff); } static void update_printer_data_bed_temp(lv_event_t * e){ lv_obj_t * label = lv_event_get_target(e); - sprintf(bed_buff, "Bed: %.0f C\nTarget: %.0f C", printer.bed_temp, printer.bed_target_temp); + sprintf(bed_buff, "Bed: %.0f C (Target: %.0f C)", printer.bed_temp, printer.bed_target_temp); lv_label_set_text(label, bed_buff); } +static short get_temp_preset(int target){ + switch (target){ + case TARGET_HOTEND_CONFIG_1: + return global_config.hotend_presets[0]; + case TARGET_HOTEND_CONFIG_2: + return global_config.hotend_presets[1]; + case TARGET_HOTEND_CONFIG_3: + return global_config.hotend_presets[2]; + case TARGET_BED_CONFIG_1: + return global_config.bed_presets[0]; + case TARGET_BED_CONFIG_2: + return global_config.bed_presets[1]; + case TARGET_BED_CONFIG_3: + return global_config.bed_presets[2]; + default: + return -1; + } +} + +static void update_temp_preset_label(lv_event_t * e){ + lv_obj_t * label = lv_event_get_target(e); + int target = static_cast(reinterpret_cast(lv_event_get_user_data(e))); + short value = get_temp_preset(target); + + String text_label = String(value) + " C"; + lv_label_set_text(label, text_label.c_str()); +} + +void UpdateConfig(){ + WriteGlobalConfig(); + lv_msg_send(DATA_PRINTER_TEMP_PRESET, &printer); +} + static void keyboard_callback(lv_event_t * e){ lv_event_code_t code = lv_event_get_code(e); lv_obj_t * ta = lv_event_get_target(e); @@ -33,17 +78,43 @@ static void keyboard_callback(lv_event_t * e){ return; } - Serial.printf("%d %s %d\n", hotend_or_bed, text, temp); char gcode[64]; const char* space = "%20"; - - if (hotend_or_bed){ - sprintf(gcode, "M140%sS%d", space, temp); - } else { - sprintf(gcode, "M104%sS%d", space, temp); + + switch (keyboard_target){ + case TARGET_HOTEND: + sprintf(gcode, "M104%sS%d", space, temp); + send_gcode(true, gcode); + break; + case TARGET_BED: + sprintf(gcode, "M140%sS%d", space, temp); + send_gcode(true, gcode); + break; + case TARGET_HOTEND_CONFIG_1: + global_config.hotend_presets[0] = temp; + UpdateConfig(); + break; + case TARGET_HOTEND_CONFIG_2: + global_config.hotend_presets[1] = temp; + UpdateConfig(); + break; + case TARGET_HOTEND_CONFIG_3: + global_config.hotend_presets[2] = temp; + UpdateConfig(); + break; + case TARGET_BED_CONFIG_1: + global_config.bed_presets[0] = temp; + UpdateConfig(); + break; + case TARGET_BED_CONFIG_2: + global_config.bed_presets[1] = temp; + UpdateConfig(); + break; + case TARGET_BED_CONFIG_3: + global_config.bed_presets[2] = temp; + UpdateConfig(); + break; } - - send_gcode(true, gcode); } if(code == LV_EVENT_DEFOCUSED || code == LV_EVENT_CANCEL || code == LV_EVENT_READY) { @@ -54,14 +125,14 @@ static void keyboard_callback(lv_event_t * e){ } static void show_keyboard(lv_event_t * e){ - lv_obj_t * panel = (lv_obj_t *)lv_event_get_user_data(e); - lv_obj_t * keyboard = lv_keyboard_create(panel); - lv_obj_t * ta = lv_textarea_create(panel); - lv_obj_set_size(ta, 100, 30); - lv_obj_align(ta, LV_ALIGN_TOP_MID, 0, 40); + lv_obj_t * keyboard = lv_keyboard_create(root_panel); + lv_obj_t * ta = lv_textarea_create(root_panel); + lv_obj_set_size(ta, TFT_HEIGHT - 40, 120); + lv_obj_align(ta, LV_ALIGN_TOP_MID, 0, 0); lv_textarea_set_max_length(ta, 3); - lv_textarea_set_one_line(ta, true); + //lv_textarea_set_one_line(ta, true); lv_textarea_set_text(ta, ""); + lv_textarea_set_align(ta, LV_TEXT_ALIGN_CENTER); lv_obj_add_event_cb(ta, keyboard_callback, LV_EVENT_ALL, keyboard); lv_keyboard_set_mode(keyboard, LV_KEYBOARD_MODE_NUMBER); @@ -69,12 +140,12 @@ static void show_keyboard(lv_event_t * e){ } static void show_keyboard_with_hotend(lv_event_t * e){ - hotend_or_bed = false; + keyboard_target = TARGET_HOTEND; show_keyboard(e); } static void show_keyboard_with_bed(lv_event_t * e){ - hotend_or_bed = true; + keyboard_target = TARGET_BED; show_keyboard(e); } @@ -96,6 +167,32 @@ static void btn_extrude(lv_event_t * e){ send_gcode(true, "G1%20E25%20F300"); } +static void set_temp_via_preset(lv_event_t * e){ + int target = static_cast(reinterpret_cast(lv_event_get_user_data(e))); + int value = get_temp_preset(target); + + if (edit_mode) { + keyboard_target = (temp_target)target; + show_keyboard(e); + return; + } + + char gcode[64]; + const char* space = "%20"; + if (target <= TARGET_HOTEND_CONFIG_3) + sprintf(gcode, "M104%sS%d", space, value); + else + sprintf(gcode, "M140%sS%d", space, value); + + send_gcode(true, gcode); +} + +static void btn_toggleable_edit(lv_event_t * e){ + lv_obj_t * btn = lv_event_get_target(e); + auto state = lv_obj_get_state(btn); + edit_mode = (state & LV_STATE_CHECKED == LV_STATE_CHECKED); +} + static void btn_retract(lv_event_t * e){ if (printer.state == PRINTER_STATE_PRINTING){ return; @@ -106,47 +203,91 @@ static void btn_retract(lv_event_t * e){ } void temp_panel_init(lv_obj_t* panel){ + root_panel = panel; + edit_mode = false; + const int btn_row_y_one = 30; + const int btn_row_y_two = 100; auto panel_width = TFT_HEIGHT - 40; lv_obj_t * label = lv_label_create(panel); - lv_label_set_text(label, "Hotend"); + lv_label_set_text(label, "???"); lv_obj_align(label, LV_ALIGN_TOP_LEFT, 10, 10); lv_obj_add_event_cb(label, update_printer_data_hotend_temp, LV_EVENT_MSG_RECEIVED, NULL); lv_msg_subscribe_obj(DATA_PRINTER_DATA, label, NULL); label = lv_label_create(panel); - lv_label_set_text(label, "Bed"); - lv_obj_align(label, LV_ALIGN_TOP_LEFT, 10, 50); + lv_label_set_text(label, "???"); + lv_obj_align(label, LV_ALIGN_TOP_LEFT, 10, 80); lv_obj_add_event_cb(label, update_printer_data_bed_temp, LV_EVENT_MSG_RECEIVED, NULL); lv_msg_subscribe_obj(DATA_PRINTER_DATA, label, NULL); lv_obj_t * btn = lv_btn_create(panel); - lv_obj_align(btn, LV_ALIGN_TOP_RIGHT, -10, 10); + lv_obj_align(btn, LV_ALIGN_TOP_RIGHT, -10, btn_row_y_one); lv_obj_add_event_cb(btn, show_keyboard_with_hotend, LV_EVENT_CLICKED, panel); + lv_obj_set_width(btn, panel_width / 4 - 10); label = lv_label_create(btn); lv_label_set_text(label, "Set"); lv_obj_center(label); btn = lv_btn_create(panel); - lv_obj_align(btn, LV_ALIGN_TOP_RIGHT, -10, 50); + lv_obj_align(btn, LV_ALIGN_TOP_RIGHT, -10, btn_row_y_two); lv_obj_add_event_cb(btn, show_keyboard_with_bed, LV_EVENT_CLICKED, panel); + lv_obj_set_width(btn, panel_width / 4 - 10); label = lv_label_create(btn); lv_label_set_text(label, "Set"); lv_obj_center(label); + // Presets + for (int i = 0; i < 3; i++){ + int x_pos = 10 + (panel_width / 4) * i - (3 * i); + + btn = lv_btn_create(panel); + lv_obj_align(btn, LV_ALIGN_TOP_LEFT, x_pos, btn_row_y_one); + lv_obj_add_event_cb(btn, set_temp_via_preset, LV_EVENT_CLICKED, reinterpret_cast(TARGET_HOTEND_CONFIG_1 + i)); + lv_obj_set_width(btn, panel_width / 4 - 10); + + label = lv_label_create(btn); + lv_label_set_text(label, "???"); + lv_obj_center(label); + lv_obj_add_event_cb(label, update_temp_preset_label, LV_EVENT_MSG_RECEIVED, reinterpret_cast(TARGET_HOTEND_CONFIG_1 + i)); + lv_msg_subscribe_obj(DATA_PRINTER_TEMP_PRESET, label, NULL); + + btn = lv_btn_create(panel); + lv_obj_align(btn, LV_ALIGN_TOP_LEFT, x_pos, btn_row_y_two); + lv_obj_add_event_cb(btn, set_temp_via_preset, LV_EVENT_CLICKED, reinterpret_cast(TARGET_BED_CONFIG_1 + i)); + lv_obj_set_width(btn, panel_width / 4 - 10); + + label = lv_label_create(btn); + lv_label_set_text(label, "???"); + lv_obj_center(label); + lv_obj_add_event_cb(label, update_temp_preset_label, LV_EVENT_MSG_RECEIVED, reinterpret_cast(TARGET_BED_CONFIG_1 + i)); + lv_msg_subscribe_obj(DATA_PRINTER_TEMP_PRESET, label, NULL); + } + btn = lv_btn_create(panel); - lv_obj_align(btn, LV_ALIGN_TOP_MID, 0, 90); + lv_obj_align(btn, LV_ALIGN_BOTTOM_LEFT, 10, -50); + lv_obj_set_size(btn, panel_width / 2 - 15, 40); lv_obj_add_event_cb(btn, cooldown_temp, LV_EVENT_CLICKED, panel); label = lv_label_create(btn); lv_label_set_text(label, "Cooldown"); lv_obj_center(label); + btn = lv_btn_create(panel); + lv_obj_align(btn, LV_ALIGN_BOTTOM_RIGHT, -10, -50); + lv_obj_add_event_cb(btn, btn_toggleable_edit, LV_EVENT_CLICKED, NULL); + lv_obj_add_flag(btn, LV_OBJ_FLAG_CHECKABLE); + lv_obj_set_size(btn, panel_width / 2 - 15, 40); + + label = lv_label_create(btn); + lv_label_set_text(label, "Edit Presets"); + lv_obj_center(label); + btn = lv_btn_create(panel); lv_obj_align(btn, LV_ALIGN_BOTTOM_LEFT, 10, -5); lv_obj_add_event_cb(btn, btn_extrude, LV_EVENT_CLICKED, NULL); - lv_obj_set_size(btn, panel_width / 2 - 15, 30); + lv_obj_set_size(btn, panel_width / 2 - 15, 40); label = lv_label_create(btn); lv_label_set_text(label, LV_SYMBOL_DOWN " Extrude"); @@ -155,11 +296,12 @@ void temp_panel_init(lv_obj_t* panel){ btn = lv_btn_create(panel); lv_obj_align(btn, LV_ALIGN_BOTTOM_RIGHT, -10, -5); lv_obj_add_event_cb(btn, btn_retract, LV_EVENT_CLICKED, NULL); - lv_obj_set_size(btn, panel_width / 2 - 15, 30); + lv_obj_set_size(btn, panel_width / 2 - 15, 40); label = lv_label_create(btn); lv_label_set_text(label, LV_SYMBOL_UP " Retract"); lv_obj_center(label); lv_msg_send(DATA_PRINTER_DATA, &printer); + lv_msg_send(DATA_PRINTER_TEMP_PRESET, &printer); } \ No newline at end of file