diff --git a/CYD-Klipper/boards/esp32-2432S024C-smartdisplay.json b/CYD-Klipper/boards/esp32-2432S024C-smartdisplay.json index 1d9a6f9..c186178 100644 --- a/CYD-Klipper/boards/esp32-2432S024C-smartdisplay.json +++ b/CYD-Klipper/boards/esp32-2432S024C-smartdisplay.json @@ -38,7 +38,7 @@ "'-D ILI9341_DEV_CONFIG_COLOR_SPACE=ESP_LCD_COLOR_SPACE_BGR'", "'-D ILI9341_DEV_CONFIG_BITS_PER_PIXEL=16'", "'-D ILI9341_DEV_CONFIG_FLAGS_RESET_ACTIVE_HIGH=false'", - "'-D ILI9341_DEV_CONFIG_VENDOR_CONFIG=NULL'", + "'-D ILI9341_DEV_CONFIG_VENDOR_CONFIG=\"(ili9341_vendor_config_t[]){{.init_cmds=(ili9341_lcd_init_cmd_t[]){{.cmd=0xCF,.data=(uint8_t[]){0x00,0xC1,0x30},.data_bytes=3},{.cmd=0xED,.data=(uint8_t[]){0x64,0x03,0x12,0x81},.data_bytes=4},{.cmd=0xE8,.data=(uint8_t[]){0x85,0x00,0x78},.data_bytes=3},{.cmd=0xCB,.data=(uint8_t[]){0x39,0x2C,0x00,0x34,0x02},.data_bytes=5},{.cmd=0xF7,.data=(uint8_t[]){0x20},.data_bytes=1},{.cmd=0xEA,.data=(uint8_t[]){0x00,0x00},.data_bytes=2},{.cmd=0xC0,.data=(uint8_t[]){0x10},.data_bytes=1},{.cmd=0xC1,.data=(uint8_t[]){0x00},.data_bytes=1},{.cmd=0xC5,.data=(uint8_t[]){0x30,0x30},.data_bytes=2,},{.cmd=0xC7,.data=(uint8_t[]){0xB7},.data_bytes=1},{.cmd=0x3A,.data=(uint8_t[]){0x55},.data_bytes=1},{.cmd=0x36,.data=(uint8_t[]){0x08},.data_bytes=1},{.cmd=0xB1,.data=(uint8_t[]){0x00,0x1A},.data_bytes=2},{.cmd=0xB6,.data=(uint8_t[]){0x08,0x82,0x27},.data_bytes=3},{.cmd=0xF2,.data=(uint8_t[]){0x00},.data_bytes=1},{.cmd=0x26,.data=(uint8_t[]){0x01},.data_bytes=1},{.cmd=0xE0,.data=(uint8_t[]){0x0F,0x2A,0x28,0x08,0x0E,0x08,0x54,0xA9,0x43,0x0A,0x0F,0x00,0x00,0x00,0x00},.data_bytes=15},{.cmd=0xE1,.data=(uint8_t[]){0x00,0x15,0x17,0x07,0x11,0x06,0x2B,0x56,0x3C,0x05,0x10,0x0F,0x3F,0x3F,0x0F},.data_bytes=15},{.cmd=0x2B,.data=(uint8_t[]){0x00,0x00,0x01,0x3F},.data_bytes=4},{.cmd=0x2A,.data=(uint8_t[]){0x00,0x00,0x00,0xEF},.data_bytes=4},{.cmd=0x21},{.cmd=0x11,.delay_ms=120},{.cmd=0x29,.delay_ms=1}},.init_cmds_size=23}}\"'", "'-D LCD_SWAP_XY=false'", "'-D LCD_MIRROR_X=true'", "'-D LCD_MIRROR_Y=false'", diff --git a/CYD-Klipper/src/conf/global_config.cpp b/CYD-Klipper/src/conf/global_config.cpp index cff6515..cefc9d4 100644 --- a/CYD-Klipper/src/conf/global_config.cpp +++ b/CYD-Klipper/src/conf/global_config.cpp @@ -6,12 +6,13 @@ GLOBAL_CONFIG global_config = {0}; COLOR_DEF color_defs[] = { {LV_PALETTE_BLUE, 0, LV_PALETTE_RED}, + {LV_PALETTE_GREEN, 0, LV_PALETTE_PURPLE}, {LV_PALETTE_LIME, -2, LV_PALETTE_PURPLE}, {LV_PALETTE_GREY, 0, LV_PALETTE_CYAN}, {LV_PALETTE_YELLOW, -2, LV_PALETTE_PINK}, {LV_PALETTE_ORANGE, -2, LV_PALETTE_BLUE}, - {LV_PALETTE_RED, 0, LV_PALETTE_GREEN}, - {LV_PALETTE_PURPLE, 0, LV_PALETTE_GREY}, + {LV_PALETTE_RED, 0, LV_PALETTE_BLUE}, + {LV_PALETTE_PURPLE, 0, LV_PALETTE_CYAN}, }; void write_global_config() @@ -85,11 +86,18 @@ void set_printer_config_index(int index) new_config->color_scheme = old_config->color_scheme; + // TODO: Replace with memcpy for (int i = 0; i < 3; i++){ new_config->hotend_presets[i] = old_config->hotend_presets[i]; new_config->bed_presets[i] = old_config->bed_presets[i]; } + for (int i = 0; i < 3; i++){ + new_config->printer_move_x_steps[i] = old_config->printer_move_x_steps[i]; + new_config->printer_move_y_steps[i] = old_config->printer_move_y_steps[i]; + new_config->printer_move_z_steps[i] = old_config->printer_move_z_steps[i]; + } + write_global_config(); ESP.restart(); } @@ -108,6 +116,16 @@ void load_global_config() global_config.printer_config[0].bed_presets[0] = 0; global_config.printer_config[0].bed_presets[1] = 60; global_config.printer_config[0].bed_presets[2] = 70; + global_config.printer_config[0].printer_move_x_steps[0] = 10; + global_config.printer_config[0].printer_move_x_steps[1] = 100; + global_config.printer_config[0].printer_move_x_steps[2] = 1000; + global_config.printer_config[0].printer_move_y_steps[0] = 10; + global_config.printer_config[0].printer_move_y_steps[1] = 100; + global_config.printer_config[0].printer_move_y_steps[2] = 1000; + global_config.printer_config[0].printer_move_z_steps[0] = 1; + global_config.printer_config[0].printer_move_z_steps[1] = 10; + global_config.printer_config[0].printer_move_z_steps[2] = 100; + verify_version(); 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 c7e2c1b..4e58ed8 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 5 +#define CONFIG_VERSION 6 #define PRINTER_CONFIG_COUNT 8 enum { @@ -12,6 +12,13 @@ enum { REMAINING_TIME_CALC_SLICER = 2, }; +enum { + SHOW_STATS_ON_PROGRESS_PANEL_NONE = 0, + SHOW_STATS_ON_PROGRESS_PANEL_LAYER = 1, + SHOW_STATS_ON_PROGRESS_PANEL_PARTIAL = 2, + SHOW_STATS_ON_PROGRESS_PANEL_ALL = 3, +}; + typedef struct _PRINTER_CONFIG { union { unsigned int raw; @@ -24,6 +31,7 @@ typedef struct _PRINTER_CONFIG { bool light_mode : 1; bool invert_colors : 1; unsigned char remaining_time_calc_mode : 2; + unsigned char show_stats_on_progress_panel : 2; }; }; @@ -36,6 +44,10 @@ typedef struct _PRINTER_CONFIG { unsigned short hotend_presets[3]; unsigned short bed_presets[3]; + + unsigned short printer_move_x_steps[3]; + unsigned short printer_move_y_steps[3]; + unsigned short printer_move_z_steps[3]; } PRINTER_CONFIG; typedef struct _GLOBAL_CONFIG { @@ -52,6 +64,7 @@ typedef struct _GLOBAL_CONFIG { bool auto_ota_update : 1; bool multi_printer_mode : 1; bool on_during_print : 1; + bool display_mode : 1; // Driver specifc usage. Currently only used on ESP32-2432S028R to fix the screen on the usb-c model }; }; @@ -62,8 +75,8 @@ typedef struct _GLOBAL_CONFIG { float screen_cal_y_offset; float screen_cal_y_mult; - char wifi_SSID[32]; - char wifi_password[64]; + char wifi_SSID[33]; + char wifi_password[65]; unsigned char brightness; unsigned char screen_timeout; diff --git a/CYD-Klipper/src/core/data_setup.cpp b/CYD-Klipper/src/core/data_setup.cpp index 36e0825..f1ea7e4 100644 --- a/CYD-Klipper/src/core/data_setup.cpp +++ b/CYD-Klipper/src/core/data_setup.cpp @@ -10,14 +10,9 @@ #include "../ui/ui_utils.h" #include "macros_query.h" -const char *printer_state_messages[] = { - "Error", - "Idle", - "Printing"}; - Printer printer = {0}; PrinterMinimal *printer_minimal; -int klipper_request_consecutive_fail_count = 0; +int klipper_request_consecutive_fail_count = 999; char filename_buff[512] = {0}; SemaphoreHandle_t freezeRenderThreadSemaphore, freezeRequestThreadSemaphore; const long data_update_interval = 780; @@ -120,12 +115,19 @@ void fetch_printer_data() delay(10); if (httpCode == 200) { + int printer_state = printer.state; + + if (printer.state == PRINTER_STATE_OFFLINE) + { + printer.state = PRINTER_STATE_ERROR; + } + klipper_request_consecutive_fail_count = 0; JsonDocument doc; deserializeJson(doc, client.getStream()); auto status = doc["result"]["status"]; bool emit_state_update = false; - int printer_state = printer.state; + delay(10); unfreeze_request_thread(); freeze_render_thread(); @@ -212,7 +214,8 @@ void fetch_printer_data() const char *filename = status["print_stats"]["filename"]; strcpy(filename_buff, filename); printer.print_filename = filename_buff; - printer.elapsed_time_s = status["print_stats"]["print_duration"]; + printer.elapsed_time_s = status["print_stats"]["total_duration"]; + printer.printed_time_s = status["print_stats"]["print_duration"]; printer.filament_used_mm = status["print_stats"]["filament_used"]; printer.total_layers = status["print_stats"]["info"]["total_layer"]; printer.current_layer = status["print_stats"]["info"]["current_layer"]; @@ -221,7 +224,7 @@ void fetch_printer_data() if (state == nullptr) { - printer_state = PRINTER_STATE_ERROR; + // Continue } else if (strcmp(state, "printing") == 0) { @@ -239,18 +242,19 @@ void fetch_printer_data() if (status.containsKey("display_status")) { + printer.print_progress = status["display_status"]["progress"]; const char* message = status["display_status"]["message"]; lv_create_popup_message(message, 10000); } if (printer.state == PRINTER_STATE_PRINTING && printer.print_progress > 0) { - float remaining_time_s_percentage = (printer.elapsed_time_s / printer.print_progress) - printer.elapsed_time_s; + float remaining_time_s_percentage = (printer.printed_time_s / printer.print_progress) - printer.printed_time_s; float remaining_time_s_slicer = 0; if (printer.slicer_estimated_print_time_s > 0) { - remaining_time_s_slicer = printer.slicer_estimated_print_time_s - printer.elapsed_time_s; + remaining_time_s_slicer = printer.slicer_estimated_print_time_s - printer.printed_time_s; } if (remaining_time_s_slicer <= 0 || config->remaining_time_calc_mode == REMAINING_TIME_CALC_PERCENTAGE) @@ -298,6 +302,13 @@ void fetch_printer_data() else { klipper_request_consecutive_fail_count++; + + if (klipper_request_consecutive_fail_count == 5) + { + printer.state = PRINTER_STATE_OFFLINE; + lv_msg_send(DATA_PRINTER_STATE, &printer); + } + Serial.printf("Failed to fetch printer data: %d\n", httpCode); unfreeze_request_thread(); } @@ -312,7 +323,7 @@ void fetch_printer_data_minimal() if (!config->ip_configured) { - data[i].online = false; + data[i].state = PRINTER_STATE_OFFLINE; continue; } @@ -325,8 +336,12 @@ void fetch_printer_data_minimal() delay(10); if (httpCode == 200) { - data[i].online = true; - data[i].power_devices = 0; + if (data[i].state == PRINTER_STATE_OFFLINE) + { + data[i].state = PRINTER_STATE_ERROR; + } + + data[i].power_devices = power_devices_count(config); JsonDocument doc; deserializeJson(doc, client.getStream()); auto status = doc["result"]["status"]; @@ -379,7 +394,7 @@ void fetch_printer_data_minimal() } else { - data[i].online = false; + data[i].state = PRINTER_STATE_OFFLINE; data[i].power_devices = power_devices_count(config); unfreeze_request_thread(); } diff --git a/CYD-Klipper/src/core/data_setup.h b/CYD-Klipper/src/core/data_setup.h index f6c5bde..6e9f7b5 100644 --- a/CYD-Klipper/src/core/data_setup.h +++ b/CYD-Klipper/src/core/data_setup.h @@ -1,14 +1,13 @@ #pragma once enum { - PRINTER_STATE_ERROR = 0, - PRINTER_STATE_IDLE = 1, - PRINTER_STATE_PRINTING = 2, - PRINTER_STATE_PAUSED = 3, + PRINTER_STATE_OFFLINE = 0, + PRINTER_STATE_ERROR = 1, + PRINTER_STATE_IDLE = 2, + PRINTER_STATE_PRINTING = 3, + PRINTER_STATE_PAUSED = 4, }; -extern const char* printer_state_messages[]; - typedef struct _Printer { unsigned char state; char* state_message; @@ -21,6 +20,7 @@ typedef struct _Printer { unsigned char homed_axis; unsigned char absolute_coords; float elapsed_time_s; + float printed_time_s; float remaining_time_s; float filament_used_mm; char* print_filename; @@ -38,7 +38,6 @@ typedef struct _Printer { } Printer; typedef struct _PrinterMinimal { - bool online; unsigned char state; float print_progress; // 0 -> 1 unsigned int power_devices; diff --git a/CYD-Klipper/src/core/device/ESP32-2432S028R.cpp b/CYD-Klipper/src/core/device/ESP32-2432S028R.cpp index e38edec..d35cb34 100644 --- a/CYD-Klipper/src/core/device/ESP32-2432S028R.cpp +++ b/CYD-Klipper/src/core/device/ESP32-2432S028R.cpp @@ -80,6 +80,15 @@ void screen_setup() tft.init(); + if (global_config.display_mode) { + // <3 https://github.com/witnessmenow/ESP32-Cheap-Yellow-Display/blob/main/cyd.md#the-display-doesnt-look-as-good + tft.writecommand(ILI9341_GAMMASET); //Gamma curve selected + tft.writedata(2); + delay(120); + tft.writecommand(ILI9341_GAMMASET); //Gamma curve selected + tft.writedata(1); + } + ledcSetup(0, 5000, 12); ledcAttachPin(21, 0); diff --git a/CYD-Klipper/src/core/lv_setup.cpp b/CYD-Klipper/src/core/lv_setup.cpp index 0cbb26b..264551d 100644 --- a/CYD-Klipper/src/core/lv_setup.cpp +++ b/CYD-Klipper/src/core/lv_setup.cpp @@ -12,6 +12,27 @@ #define CPU_FREQ_LOW 80 #endif +unsigned long last_milis = 0; + +void lv_handler() +{ +#ifndef CYD_SCREEN_DISABLE_TOUCH_CALIBRATION + if (digitalRead(0) == HIGH) + { + last_milis = millis(); + } + else if (millis() - last_milis > 8000) + { + global_config.screen_calibrated = false; + write_global_config(); + ESP.restart(); + } +#endif + + lv_timer_handler(); + lv_task_handler(); +} + typedef void (*lv_indev_drv_read_cb_t)(struct _lv_indev_drv_t * indev_drv, lv_indev_data_t * data); bool is_screen_in_sleep = false; @@ -95,8 +116,7 @@ void lv_do_calibration(){ #endif while (true){ - lv_timer_handler(); - lv_task_handler(); + lv_handler(); if (point[0] != 0 && point[1] != 0){ break; @@ -130,8 +150,7 @@ void lv_do_calibration(){ #endif while (true){ - lv_timer_handler(); - lv_task_handler(); + lv_handler(); if (point[0] != 0 && point[1] != 0){ break; diff --git a/CYD-Klipper/src/core/lv_setup.h b/CYD-Klipper/src/core/lv_setup.h index 5758da4..c0970a5 100644 --- a/CYD-Klipper/src/core/lv_setup.h +++ b/CYD-Klipper/src/core/lv_setup.h @@ -7,4 +7,5 @@ void screen_timer_start(); void screen_timer_stop(); void set_color_scheme(); void lv_setup(); -bool is_screen_asleep(); \ No newline at end of file +bool is_screen_asleep(); +void lv_handler(); \ No newline at end of file diff --git a/CYD-Klipper/src/main.cpp b/CYD-Klipper/src/main.cpp index 776962f..03e60ce 100644 --- a/CYD-Klipper/src/main.cpp +++ b/CYD-Klipper/src/main.cpp @@ -29,10 +29,8 @@ void setup() { void loop(){ wifi_ok(); - ip_ok(); data_loop(); - lv_timer_handler(); - lv_task_handler(); + lv_handler(); if (is_ready_for_ota_update()) { diff --git a/CYD-Klipper/src/ui/ip_setup.cpp b/CYD-Klipper/src/ui/ip_setup.cpp index 8c0ce2a..1419972 100644 --- a/CYD-Klipper/src/ui/ip_setup.cpp +++ b/CYD-Klipper/src/ui/ip_setup.cpp @@ -9,13 +9,15 @@ #include "../core/http_client.h" #include "switch_printer.h" #include "macros.h" +#include "../core/lv_setup.h" -bool connect_ok = false; -int prev_power_device_count = 0; lv_obj_t * hostEntry; lv_obj_t * portEntry; lv_obj_t * label = NULL; +void show_ip_entry(); +void show_auth_entry(); + /* Create a custom keyboard to allow hostnames or ip addresses (a-z, 0 - 9, and -) */ static const char * kb_map[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", LV_SYMBOL_BACKSPACE, "\n", @@ -31,8 +33,6 @@ static const lv_btnmatrix_ctrl_t kb_ctrl[] = { LV_KEYBOARD_CTRL_BTN_FLAGS | 6, 4, 4, 4, 4, 4, 4, 4, 4, 4, LV_KEYBOARD_CTRL_BTN_FLAGS | 6 }; -void ip_init_inner(); - enum connection_status_t { CONNECT_FAIL = 0, CONNECT_OK = 1, @@ -57,7 +57,7 @@ connection_status_t verify_ip(){ } } -static void ta_event_cb(lv_event_t * e) { +static void keyboard_event_ip_entry(lv_event_t * e) { lv_event_code_t code = lv_event_get_code(e); lv_obj_t * ta = lv_event_get_target(e); lv_obj_t * kb = (lv_obj_t *)lv_event_get_user_data(e); @@ -80,13 +80,10 @@ static void ta_event_cb(lv_event_t * e) { { get_current_printer_config()->ip_configured = true; write_global_config(); - connect_ok = true; } else if (status == CONNECT_AUTH_REQUIRED) { - label = NULL; - get_current_printer_config()->ip_configured = true; - write_global_config(); + show_auth_entry(); } else { @@ -108,54 +105,6 @@ static void ta_event_cb(lv_event_t * e) { } } -static void reset_btn_event_handler(lv_event_t * e){ - lv_event_code_t code = lv_event_get_code(e); - - if(code == LV_EVENT_CLICKED) { - get_current_printer_config()->ip_configured = false; - ip_init_inner(); - } -} - -static void power_devices_button(lv_event_t * e) { - macros_draw_power_fullscreen(); -} - -void redraw_connect_screen(){ - lv_obj_clean(lv_scr_act()); - - label = lv_label_create(lv_scr_act()); - lv_label_set_text(label, "Connecting to Klipper"); - lv_obj_align(label, LV_ALIGN_CENTER, 0, 0); - - lv_obj_t * button_row = lv_create_empty_panel(lv_scr_act()); - lv_obj_set_size(button_row, CYD_SCREEN_WIDTH_PX, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX); - lv_layout_flex_row(button_row, LV_FLEX_ALIGN_CENTER); - lv_obj_align(button_row, LV_ALIGN_CENTER, 0, CYD_SCREEN_GAP_PX + CYD_SCREEN_MIN_BUTTON_HEIGHT_PX); - - lv_obj_t * reset_btn = lv_btn_create(button_row); - lv_obj_add_event_cb(reset_btn, reset_btn_event_handler, LV_EVENT_CLICKED, NULL); - lv_obj_set_height(reset_btn, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX); - - lv_obj_t * btn_label = lv_label_create(reset_btn); - lv_label_set_text(btn_label, "Reset"); - lv_obj_center(btn_label); - - if (prev_power_device_count >= 1){ - lv_obj_t * power_devices_btn = lv_btn_create(button_row); - lv_obj_add_event_cb(power_devices_btn, power_devices_button, LV_EVENT_CLICKED, NULL); - lv_obj_set_height(power_devices_btn, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX); - - btn_label = lv_label_create(power_devices_btn); - lv_label_set_text(btn_label, "Power Devices"); - lv_obj_center(btn_label); - } - - draw_switch_printer_button(); -} - -static bool auth_entry_done = false; - static void keyboard_event_auth_entry(lv_event_t * e) { lv_event_code_t code = lv_event_get_code(e); lv_obj_t * ta = lv_event_get_target(e); @@ -169,18 +118,26 @@ static void keyboard_event_auth_entry(lv_event_t * e) { { get_current_printer_config()->auth_configured = true; strcpy(get_current_printer_config()->klipper_auth, txt); - write_global_config(); - auth_entry_done = true; + + if (verify_ip() == CONNECT_OK) + { + get_current_printer_config()->ip_configured = true; + write_global_config(); + } + else + { + lv_label_set_text(label, "Failed to connect"); + } } } else if (code == LV_EVENT_CANCEL) { - auth_entry_done = true; + show_ip_entry(); } } -void handle_auth_entry(){ - auth_entry_done = false; +void show_auth_entry() +{ get_current_printer_config()->klipper_auth[32] = 0; lv_obj_clean(lv_scr_act()); @@ -194,7 +151,7 @@ void handle_auth_entry(){ lv_obj_set_flex_grow(top_root, 1); lv_obj_set_style_pad_all(top_root, CYD_SCREEN_GAP_PX, 0); - lv_obj_t * label = lv_label_create(top_root); + label = lv_label_create(top_root); lv_label_set_text(label, "Enter API Key"); lv_obj_set_width(label, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 2); @@ -212,25 +169,13 @@ void handle_auth_entry(){ lv_obj_add_event_cb(passEntry, keyboard_event_auth_entry, LV_EVENT_ALL, keyboard); lv_obj_set_flex_grow(passEntry, 1); - lv_keyboard_set_textarea(keyboard, passEntry); lv_keyboard_set_map(keyboard, LV_KEYBOARD_MODE_USER_1, kb_map, kb_ctrl); lv_keyboard_set_mode(keyboard, LV_KEYBOARD_MODE_USER_1); - - while (!auth_entry_done) { - lv_timer_handler(); - lv_task_handler(); - } - - redraw_connect_screen(); } -void ip_init_inner(){ - if (get_current_printer_config()->ip_configured) { - redraw_connect_screen(); - return; - } - +void show_ip_entry() +{ lv_obj_clean(lv_scr_act()); lv_obj_t * root = lv_create_empty_panel(lv_scr_act()); @@ -267,57 +212,27 @@ void ip_init_inner(){ lv_obj_t * keyboard = lv_keyboard_create(root); lv_keyboard_set_map(keyboard, LV_KEYBOARD_MODE_USER_1, kb_map, kb_ctrl); - lv_obj_add_event_cb(hostEntry, ta_event_cb, LV_EVENT_ALL, keyboard); - lv_obj_add_event_cb(portEntry, ta_event_cb, LV_EVENT_ALL, keyboard); + lv_obj_add_event_cb(hostEntry, keyboard_event_ip_entry, LV_EVENT_ALL, keyboard); + lv_obj_add_event_cb(portEntry, keyboard_event_ip_entry, LV_EVENT_ALL, keyboard); lv_keyboard_set_mode(keyboard, LV_KEYBOARD_MODE_USER_1); lv_keyboard_set_textarea(keyboard, hostEntry); -} - -long last_data_update_ip = -10000; -const long data_update_interval_ip = 10000; -int retry_count = 0; -void ip_init(){ - connect_ok = false; - retry_count = 0; - prev_power_device_count = 0; - - ip_init_inner(); - - while (!connect_ok) + if (global_config.multi_printer_mode) { - lv_timer_handler(); - lv_task_handler(); - - if (!connect_ok && get_current_printer_config()->ip_configured && (millis() - last_data_update_ip) > data_update_interval_ip){ - connection_status_t status = verify_ip(); - - connect_ok = status == CONNECT_OK; - last_data_update_ip = millis(); - retry_count++; - if (label != NULL){ - String retry_count_text = "Connecting to Klipper (Try " + String(retry_count + 1) + ")"; - lv_label_set_text(label, retry_count_text.c_str()); - } - - if (status == CONNECT_AUTH_REQUIRED) - handle_auth_entry(); - - unsigned int power_device_count = power_devices_count(); - if (power_device_count != prev_power_device_count) { - prev_power_device_count = power_device_count; - redraw_connect_screen(); - } - } + lv_obj_t * btn = draw_switch_printer_button(); + lv_obj_set_parent(btn, textbow_row); + lv_obj_align(btn, LV_ALIGN_DEFAULT, 0, 0); } } -void ip_ok(){ - if (klipper_request_consecutive_fail_count > 5){ - freeze_request_thread(); - ip_init(); - unfreeze_request_thread(); - klipper_request_consecutive_fail_count = 0; - lv_msg_send(DATA_PRINTER_STATE, &printer); +void ip_init(){ + if (!get_current_printer_config()->ip_configured) + { + show_ip_entry(); + } + + while (!get_current_printer_config()->ip_configured) + { + lv_handler(); } } \ No newline at end of file diff --git a/CYD-Klipper/src/ui/ip_setup.h b/CYD-Klipper/src/ui/ip_setup.h index a9d7ece..599736f 100644 --- a/CYD-Klipper/src/ui/ip_setup.h +++ b/CYD-Klipper/src/ui/ip_setup.h @@ -1,2 +1,3 @@ -void ip_init(); -void ip_ok(); \ No newline at end of file +#pragma once + +void ip_init(); \ No newline at end of file diff --git a/CYD-Klipper/src/ui/main_ui.cpp b/CYD-Klipper/src/ui/main_ui.cpp index 4ac8492..4bff2e1 100644 --- a/CYD-Klipper/src/ui/main_ui.cpp +++ b/CYD-Klipper/src/ui/main_ui.cpp @@ -24,7 +24,10 @@ void check_if_screen_needs_to_be_disabled(){ static void on_state_change(void * s, lv_msg_t * m){ check_if_screen_needs_to_be_disabled(); - if (printer.state == PRINTER_STATE_ERROR){ + if (printer.state == PRINTER_STATE_OFFLINE){ + nav_buttons_setup(PANEL_CONNECTING); + } + else if (printer.state == PRINTER_STATE_ERROR){ nav_buttons_setup(PANEL_ERROR); } else { diff --git a/CYD-Klipper/src/ui/nav_buttons.cpp b/CYD-Klipper/src/ui/nav_buttons.cpp index aa2d0d2..e2e55ae 100644 --- a/CYD-Klipper/src/ui/nav_buttons.cpp +++ b/CYD-Klipper/src/ui/nav_buttons.cpp @@ -85,6 +85,10 @@ static void btn_click_err(lv_event_t * e){ nav_buttons_setup(PANEL_ERROR); } +static void btn_click_conn(lv_event_t * e){ + nav_buttons_setup(PANEL_CONNECTING); +} + void create_button(const char* icon, const char* name, lv_event_cb_t button_click, lv_event_cb_t label_update, lv_obj_t * root){ lv_obj_t* btn = lv_btn_create(root); lv_obj_set_flex_grow(btn, 1); @@ -128,7 +132,7 @@ void nav_buttons_setup(unsigned char active_panel){ #endif - if (printer.state != PRINTER_STATE_ERROR){ + if (printer.state > PRINTER_STATE_ERROR){ // Files/Print create_button(LV_SYMBOL_COPY, "Idle", btn_click_files, update_printer_data_time, root_panel); @@ -138,10 +142,14 @@ void nav_buttons_setup(unsigned char active_panel){ // Extrude/Temp create_button(LV_SYMBOL_WARNING, "?/?", btn_click_extrude, update_printer_data_temp, root_panel); } - else { + else if (printer.state == PRINTER_STATE_ERROR) { // Error UI create_button(LV_SYMBOL_WARNING, "Error", btn_click_err, NULL, root_panel); } + else { + // Connecting + create_button(LV_SYMBOL_REFRESH, "Link", btn_click_conn, NULL, root_panel); + } // Macros create_button(LV_SYMBOL_GPS, "Macro", btn_click_macros, NULL, root_panel); @@ -181,6 +189,9 @@ void nav_buttons_setup(unsigned char active_panel){ case PANEL_ERROR: error_panel_init(panel); break; + case PANEL_CONNECTING: + connecting_panel_init(panel); + break; } lv_msg_send(DATA_PRINTER_DATA, &printer); diff --git a/CYD-Klipper/src/ui/nav_buttons.h b/CYD-Klipper/src/ui/nav_buttons.h index b1c6c10..57f0bcb 100644 --- a/CYD-Klipper/src/ui/nav_buttons.h +++ b/CYD-Klipper/src/ui/nav_buttons.h @@ -8,6 +8,7 @@ #define PANEL_STATS 5 #define PANEL_PRINTER 6 #define PANEL_ERROR 7 +#define PANEL_CONNECTING 8 void nav_buttons_setup(unsigned char active_panel); void nav_style_setup(); \ No newline at end of file diff --git a/CYD-Klipper/src/ui/panels/connecting_panel.cpp b/CYD-Klipper/src/ui/panels/connecting_panel.cpp new file mode 100644 index 0000000..d39b9d6 --- /dev/null +++ b/CYD-Klipper/src/ui/panels/connecting_panel.cpp @@ -0,0 +1,9 @@ +#include "panel.h" +#include "../../conf/global_config.h" + +void connecting_panel_init(lv_obj_t* panel) +{ + lv_obj_t* label = lv_label_create(panel); + lv_label_set_text_fmt(label, "Connecting to %s...", (get_current_printer_config()->printer_name[0] == 0) ? get_current_printer_config()->klipper_host : get_current_printer_config()->printer_name); + lv_obj_align(label, LV_ALIGN_CENTER, 0, 0); +} \ No newline at end of file diff --git a/CYD-Klipper/src/ui/panels/macros_panel.cpp b/CYD-Klipper/src/ui/panels/macros_panel.cpp index 295eaca..f48d935 100644 --- a/CYD-Klipper/src/ui/panels/macros_panel.cpp +++ b/CYD-Klipper/src/ui/panels/macros_panel.cpp @@ -22,14 +22,8 @@ void macros_panel_init(lv_obj_t* panel) { lv_label_set_text(label, LV_SYMBOL_SETTINGS " Screen Settings"); lv_obj_center(label); - MACROSQUERY query = macros_query(); + MACROSQUERY macros = macros_query(); POWERQUERY power = power_devices_query(); - if (query.count == 0 && power.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; - } lv_obj_t * root_panel = lv_create_empty_panel(panel); lv_obj_set_scrollbar_mode(root_panel, LV_SCROLLBAR_MODE_OFF); @@ -38,5 +32,17 @@ void macros_panel_init(lv_obj_t* panel) { lv_layout_flex_column(root_panel); macros_add_power_devices_to_panel(root_panel, power); - macros_add_macros_to_panel(root_panel, query); + + if (macros.count == 0){ + label = lv_label_create(root_panel); + lv_label_set_text(label, "No macros found.\nMacros with the description\n\"CYD_SCREEN_MACRO\"\nwill show up here."); + + if (power.count == 0){ + lv_layout_flex_column(root_panel, LV_FLEX_ALIGN_CENTER); + } + + return; + } + + macros_add_macros_to_panel(root_panel, macros); } \ No newline at end of file diff --git a/CYD-Klipper/src/ui/panels/move_panel.cpp b/CYD-Klipper/src/ui/panels/move_panel.cpp index 913339d..75652ff 100644 --- a/CYD-Klipper/src/ui/panels/move_panel.cpp +++ b/CYD-Klipper/src/ui/panels/move_panel.cpp @@ -4,47 +4,157 @@ #include "../nav_buttons.h" #include "../ui_utils.h" #include +#include static bool last_homing_state = false; +static bool move_edit_mode = false; + +float x_offsets[6] = {0}; +float y_offsets[6] = {0}; +float z_offsets[6] = {0}; + +#define OFFSET_LABEL_SIZE 7 + +char x_offset_labels[6 * OFFSET_LABEL_SIZE] = {0}; +char y_offset_labels[6 * OFFSET_LABEL_SIZE] = {0}; +char z_offset_labels[6 * OFFSET_LABEL_SIZE] = {0}; + +static void calculate_offsets_from_current_printer() +{ + unsigned short* items[] = {get_current_printer_config()->printer_move_x_steps, get_current_printer_config()->printer_move_y_steps, get_current_printer_config()->printer_move_z_steps}; + float* offsets[] = {(float*)x_offsets, (float*)y_offsets, (float*)z_offsets}; + char * labels[] = {(char*)x_offset_labels, (char*)y_offset_labels, (char*)z_offset_labels}; + + for (int i = 0; i < 3; i++) + { + offsets[i][0] = items[i][2] / 10.0f * -1; + offsets[i][1] = items[i][1] / 10.0f * -1; + offsets[i][2] = items[i][0] / 10.0f * -1; + offsets[i][3] = items[i][0] / 10.0f; + offsets[i][4] = items[i][1] / 10.0f; + offsets[i][5] = items[i][2] / 10.0f; + + for (int j = 0; j < 6; j++) { + const char * formats[] = {"%.0f", "%.1f", "+%.0f", "+%.1f"}; + const char ** format = formats; + + if (offsets[i][j] != (int)offsets[i][j]) + { + format += 1; + } + + if (j >= 3) + { + format += 2; + } + + sprintf(labels[i] + OFFSET_LABEL_SIZE * j, *format, offsets[i][j]); + } + } +} + +static int selected_column = 0; +static int selected_row = 0; + +static void keyboard_cb_edit_move_increment(lv_event_t * e) +{ + lv_obj_t * ta = lv_event_get_target(e); + lv_obj_t * kb = (lv_obj_t *)lv_event_get_user_data(e); + const char * text = lv_textarea_get_text(ta); + + float increment = atof(text); + + if (increment < 0) + { + increment *= -1; + } + + if (increment == 0 || increment > 999) + { + return; + } + + unsigned short* items[] = {get_current_printer_config()->printer_move_x_steps, get_current_printer_config()->printer_move_y_steps, get_current_printer_config()->printer_move_z_steps}; + Serial.printf("Setting increment %d %d %f\n", selected_column, selected_row, increment); + items[selected_column][selected_row] = increment * 10; + write_global_config(); + nav_buttons_setup(PANEL_MOVE); +} + +static void edit_move_increment(int column, float* idx) +{ + float* offsets[] = {(float*)x_offsets, (float*)y_offsets, (float*)z_offsets}; + int row = idx - offsets[column]; + + if (row < 3) + { + selected_row = 2 - row; + } + else + { + selected_row = row - 3; + } + + selected_column = column; + lv_create_keyboard_text_entry(keyboard_cb_edit_move_increment, "Set increment", LV_KEYBOARD_MODE_NUMBER, CYD_SCREEN_PANEL_WIDTH_PX / 2, 6); +} static void x_line_button_press(lv_event_t * e) { float* data_pointer = (float*)lv_event_get_user_data(e); + + if (move_edit_mode) + { + edit_move_increment(0, data_pointer); + return; + } + float data = *data_pointer; move_printer("X", data, true); } static void y_line_button_press(lv_event_t * e) { float* data_pointer = (float*)lv_event_get_user_data(e); + + if (move_edit_mode) + { + edit_move_increment(1, data_pointer); + return; + } + float data = *data_pointer; move_printer("Y", data, true); } static void z_line_button_press(lv_event_t * e) { float* data_pointer = (float*)lv_event_get_user_data(e); + + if (move_edit_mode) + { + edit_move_increment(2, data_pointer); + return; + } + float data = *data_pointer; move_printer("Z", data, true); } -char x_pos_buff[12]; - static void x_pos_update(lv_event_t * e){ lv_obj_t * label = lv_event_get_target(e); + char x_pos_buff[12]; sprintf(x_pos_buff, "X: %.1f", printer.position[0]); lv_label_set_text(label, x_pos_buff); } -char y_pos_buff[12]; - static void y_pos_update(lv_event_t * e){ lv_obj_t * label = lv_event_get_target(e); + char y_pos_buff[12]; sprintf(y_pos_buff, "Y: %.1f", printer.position[1]); lv_label_set_text(label, y_pos_buff); } -char z_pos_buff[12]; - static void z_pos_update(lv_event_t * e){ lv_obj_t * label = lv_event_get_target(e); + char z_pos_buff[12]; sprintf(z_pos_buff, "Z: %.2f", printer.position[2]); lv_label_set_text(label, z_pos_buff); } @@ -52,23 +162,6 @@ static void z_pos_update(lv_event_t * e){ lv_event_cb_t button_callbacks[] = {x_line_button_press, y_line_button_press, z_line_button_press}; lv_event_cb_t position_callbacks[] = {x_pos_update, y_pos_update, z_pos_update}; -const float xy_offsets[] = {-100, -10, -1, 1, 10, 100}; -const float z_offsets[] = {-10, -1, -0.1, 0.1, 1, 10}; -const float* offsets[] = { - xy_offsets, - xy_offsets, - z_offsets -}; - -const char* xy_offset_labels[] = {"-100", "-10", "-1", "+1", "+10", "+100"}; -const char* z_offset_labels[] = {"-10", "-1", "-0.1", "+0.1", "+1", "+10"}; - -const char** offset_labels[] = { - xy_offset_labels, - xy_offset_labels, - z_offset_labels -}; - static void home_button_click(lv_event_t * e) { if (printer.state == PRINTER_STATE_PRINTING) return; @@ -88,6 +181,51 @@ static void switch_to_stat_panel(lv_event_t * e) { nav_buttons_setup(PANEL_STATS); } +static void move_edit_toggle(lv_event_t * e) +{ + lv_obj_t * btn = lv_event_get_target(e); + move_edit_mode = lv_obj_get_state(btn) & LV_STATE_CHECKED; +} + +static void line_custom_set(const char * axis, const char *text) +{ + float pos = atof(text); + + if (pos < 0 || pos > 500) + return; + + move_printer(axis, pos, false); +} + +static void x_line_custom_callback(lv_event_t * e) { + const char * text = lv_textarea_get_text(lv_event_get_target(e)); + line_custom_set("X", text); +} + +static void y_line_custom_callback(lv_event_t * e) { + const char * text = lv_textarea_get_text(lv_event_get_target(e)); + line_custom_set("Y", text); +} + +static void z_line_custom_callback(lv_event_t * e) { + const char * text = lv_textarea_get_text(lv_event_get_target(e)); + line_custom_set("Z", text); +} + +static void x_line_custom(lv_event_t * e) { + lv_create_keyboard_text_entry(x_line_custom_callback, "Set X position", LV_KEYBOARD_MODE_NUMBER, CYD_SCREEN_PANEL_WIDTH_PX / 2, 6); +} + +static void y_line_custom(lv_event_t * e) { + lv_create_keyboard_text_entry(y_line_custom_callback, "Set Y position", LV_KEYBOARD_MODE_NUMBER, CYD_SCREEN_PANEL_WIDTH_PX / 2, 6); +} + +static void z_line_custom(lv_event_t * e) { + lv_create_keyboard_text_entry(z_line_custom_callback, "Set Z position", LV_KEYBOARD_MODE_NUMBER, CYD_SCREEN_PANEL_WIDTH_PX / 2, 6); +} + +lv_event_cb_t custom_callbacks[] = {x_line_custom, y_line_custom, z_line_custom}; + inline void root_panel_steppers_locked(lv_obj_t * root_panel){ const auto width = CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 2; @@ -115,7 +253,7 @@ inline void root_panel_steppers_locked(lv_obj_t * root_panel){ lv_obj_set_flex_grow(btn, 1); label = lv_label_create(btn); - lv_label_set_text(label, LV_SYMBOL_EYE_CLOSE " Unlock"); + lv_label_set_text(label, LV_SYMBOL_EYE_CLOSE "Free"); lv_obj_center(label); btn = lv_btn_create(home_button_row); @@ -124,11 +262,29 @@ inline void root_panel_steppers_locked(lv_obj_t * root_panel){ lv_obj_set_flex_grow(btn, 1); label = lv_label_create(btn); - lv_label_set_text(label, LV_SYMBOL_EDIT " Params"); + lv_label_set_text(label, LV_SYMBOL_SETTINGS "Param"); lv_obj_center(label); + btn = lv_btn_create(home_button_row); + lv_obj_set_size(btn, CYD_SCREEN_MIN_BUTTON_WIDTH_PX, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX); + lv_obj_add_event_cb(btn, move_edit_toggle, LV_EVENT_CLICKED, NULL); + lv_obj_add_flag(btn, LV_OBJ_FLAG_CHECKABLE); + + if (move_edit_mode) + { + lv_obj_add_state(btn, LV_STATE_CHECKED); + } + + label = lv_label_create(btn); + lv_label_set_text(label, LV_SYMBOL_EDIT); + lv_obj_center(label); + + float* offsets[] = {(float*)x_offsets, (float*)y_offsets, (float*)z_offsets}; + char * labels[] = {(char*)x_offset_labels, (char*)y_offset_labels, (char*)z_offset_labels}; + for (int row = 0; row < 3; row++) { - label = lv_label_create(panel); + label = lv_label_btn_create(panel, custom_callbacks[row]); + lv_obj_align(label, LV_ALIGN_CENTER, 0, 0); lv_label_set_text(label, "???"); lv_obj_set_width(label, width); lv_obj_add_event_cb(label, position_callbacks[row], LV_EVENT_MSG_RECEIVED, NULL); @@ -146,7 +302,7 @@ inline void root_panel_steppers_locked(lv_obj_t * root_panel){ lv_obj_set_flex_grow(btn, 1); label = lv_label_create(btn); - lv_label_set_text(label, offset_labels[row][col]); + lv_label_set_text(label, labels[row] + OFFSET_LABEL_SIZE * col); lv_obj_center(label); } } @@ -192,6 +348,7 @@ void move_panel_init(lv_obj_t* panel){ return; } + calculate_offsets_from_current_printer(); last_homing_state = !printer.homed_axis; lv_obj_add_event_cb(panel, root_panel_state_update, LV_EVENT_MSG_RECEIVED, NULL); diff --git a/CYD-Klipper/src/ui/panels/panel.h b/CYD-Klipper/src/ui/panels/panel.h index 70223ad..319fe08 100644 --- a/CYD-Klipper/src/ui/panels/panel.h +++ b/CYD-Klipper/src/ui/panels/panel.h @@ -11,4 +11,5 @@ void progress_panel_init(lv_obj_t* panel); void macros_panel_init(lv_obj_t* panel); void stats_panel_init(lv_obj_t* panel); void printer_panel_init(lv_obj_t* panel); -void error_panel_init(lv_obj_t* panel); \ No newline at end of file +void error_panel_init(lv_obj_t* panel); +void connecting_panel_init(lv_obj_t* panel); \ No newline at end of file diff --git a/CYD-Klipper/src/ui/panels/printer_panel.cpp b/CYD-Klipper/src/ui/panels/printer_panel.cpp index 6e8dfd6..19a29d2 100644 --- a/CYD-Klipper/src/ui/panels/printer_panel.cpp +++ b/CYD-Klipper/src/ui/panels/printer_panel.cpp @@ -10,6 +10,7 @@ #include "../macros.h" const char * printer_status[] = { + "Offline", "Error", "Idle", "Printing", @@ -41,7 +42,7 @@ static void update_printer_status_text(lv_event_t * e) return; } - if (!printer->online) + if (printer->state == PRINTER_STATE_OFFLINE) { lv_label_set_text(label, "Offline"); return; @@ -50,6 +51,21 @@ static void update_printer_status_text(lv_event_t * e) lv_label_set_text(label, printer_status[printer->state]); } +static void update_printer_label_visible_active_printer(lv_event_t * e) +{ + lv_obj_t * label = lv_event_get_target(e); + PRINTER_CONFIG * config = (PRINTER_CONFIG*)lv_event_get_user_data(e); + + if (config == get_current_printer_config()) + { + lv_label_set_text(label, LV_SYMBOL_WIFI); + } + else + { + lv_label_set_text(label, ""); + } +} + static void update_printer_percentage_bar(lv_event_t * e) { lv_obj_t * percentage = lv_event_get_target(e); @@ -57,7 +73,7 @@ static void update_printer_percentage_bar(lv_event_t * e) int index = config - global_config.printer_config; PrinterMinimal * printer = &printer_minimal[index]; - if (printer->online && (printer->state == PRINTER_STATE_PRINTING || printer->state == PRINTER_STATE_PAUSED)){ + if (printer->state != PRINTER_STATE_OFFLINE && (printer->state == PRINTER_STATE_PRINTING || printer->state == PRINTER_STATE_PAUSED)){ lv_bar_set_value(percentage, printer->print_progress * 100, LV_ANIM_OFF); } else { @@ -72,7 +88,7 @@ static void update_printer_percentage_text(lv_event_t * e) int index = config - global_config.printer_config; PrinterMinimal * printer = &printer_minimal[index]; - if (printer->online && (printer->state == PRINTER_STATE_PRINTING || printer->state == PRINTER_STATE_PAUSED)) + if (printer->state != PRINTER_STATE_OFFLINE && (printer->state == PRINTER_STATE_PRINTING || printer->state == PRINTER_STATE_PAUSED)) { char percentage_buffer[12]; sprintf(percentage_buffer, "%.2f%%", printer->print_progress * 100); @@ -91,7 +107,7 @@ static void update_printer_control_button_text(lv_event_t * e) int index = config - global_config.printer_config; PrinterMinimal * printer = &printer_minimal[index]; - if (!printer->online && printer->power_devices > 0) + if (printer->power_devices > 0 && (config == get_current_printer_config() || printer->state == PRINTER_STATE_OFFLINE)) { lv_label_set_text(label, "Power"); } @@ -101,20 +117,18 @@ static void update_printer_control_button_text(lv_event_t * e) } } -static void btn_enable_delete(lv_event_t * e) +static void btn_set_secondary_button_text(lv_event_t * e) { - lv_obj_t * btn = lv_event_get_target(e); + lv_obj_t * label = lv_event_get_target(e); PRINTER_CONFIG * config = (PRINTER_CONFIG*)lv_event_get_user_data(e); if (config == get_current_printer_config()) { - // Disable - lv_obj_add_state(btn, LV_STATE_DISABLED); + lv_label_set_text(label, LV_SYMBOL_SETTINGS); } else { - // Enable - lv_obj_clear_state(btn, LV_STATE_DISABLED); + lv_label_set_text(label, LV_SYMBOL_TRASH); } } @@ -125,7 +139,7 @@ static void btn_enable_control(lv_event_t * e) int index = config - global_config.printer_config; PrinterMinimal * printer = &printer_minimal[index]; - if (config == get_current_printer_config() || (!printer->online && printer->power_devices <= 0)) + if ((config == get_current_printer_config() || printer->state == PRINTER_STATE_OFFLINE) && printer->power_devices <= 0) { // Disable lv_obj_add_state(btn, LV_STATE_DISABLED); @@ -150,13 +164,14 @@ static void keyboard_callback(lv_event_t * e){ lv_msg_send(DATA_PRINTER_MINIMAL, NULL); } -static void btn_printer_delete(lv_event_t * e) +static void btn_printer_secondary(lv_event_t * e) { lv_obj_t * btn = lv_event_get_target(e); PRINTER_CONFIG * config = (PRINTER_CONFIG*)lv_event_get_user_data(e); if (config == get_current_printer_config()) { + nav_buttons_setup(PANEL_SETTINGS); return; } @@ -166,11 +181,10 @@ static void btn_printer_delete(lv_event_t * e) nav_buttons_setup(PANEL_PRINTER); } -// TODO: Extract this from temp/print panel and combine static void btn_printer_rename(lv_event_t * e) { keyboard_config = (PRINTER_CONFIG*)lv_event_get_user_data(e); - lv_create_keyboard_text_entry(keyboard_callback, LV_KEYBOARD_MODE_TEXT_LOWER, CYD_SCREEN_WIDTH_PX * 0.75, 24, keyboard_config->printer_name, false); + lv_create_keyboard_text_entry(keyboard_callback, "Rename Printer", LV_KEYBOARD_MODE_TEXT_LOWER, CYD_SCREEN_WIDTH_PX * 0.75, 24, keyboard_config->printer_name, false); } static void btn_printer_activate(lv_event_t * e) @@ -180,7 +194,7 @@ static void btn_printer_activate(lv_event_t * e) int index = config - global_config.printer_config; PrinterMinimal * printer = &printer_minimal[index]; - if (!printer->online) + if (printer->power_devices > 0 && (config == get_current_printer_config() || printer->state == PRINTER_STATE_OFFLINE)) { macros_draw_power_fullscreen(config); return; @@ -207,6 +221,10 @@ void create_printer_ui(PRINTER_CONFIG * config, lv_obj_t * root) lv_obj_t * label = lv_label_create(data_row_name); lv_obj_add_event_cb(label, update_printer_name_text, LV_EVENT_MSG_RECEIVED, config); lv_msg_subsribe_obj(DATA_PRINTER_MINIMAL, label, config); + + label = lv_label_create(data_row_name); + lv_obj_add_event_cb(label, update_printer_label_visible_active_printer, LV_EVENT_MSG_RECEIVED, config); + lv_msg_subsribe_obj(DATA_PRINTER_MINIMAL, label, config); label = lv_label_create(data_row_name); lv_obj_add_event_cb(label, update_printer_status_text, LV_EVENT_MSG_RECEIVED, config); @@ -232,13 +250,12 @@ void create_printer_ui(PRINTER_CONFIG * config, lv_obj_t * root) lv_obj_t * btn = lv_btn_create(button_row); lv_obj_set_flex_grow(btn, 1); - lv_obj_add_event_cb(btn, btn_printer_delete, LV_EVENT_CLICKED, config); - lv_obj_add_event_cb(btn, btn_enable_delete, LV_EVENT_MSG_RECEIVED, config); - lv_msg_subsribe_obj(DATA_PRINTER_MINIMAL, btn, config); + lv_obj_add_event_cb(btn, btn_printer_secondary, LV_EVENT_CLICKED, config); label = lv_label_create(btn); - lv_label_set_text(label, LV_SYMBOL_TRASH); lv_obj_center(label); + lv_obj_add_event_cb(label, btn_set_secondary_button_text, LV_EVENT_MSG_RECEIVED, config); + lv_msg_subsribe_obj(DATA_PRINTER_MINIMAL, label, config); btn = lv_btn_create(button_row); lv_obj_set_flex_grow(btn, 2); diff --git a/CYD-Klipper/src/ui/panels/progress_panel.cpp b/CYD-Klipper/src/ui/panels/progress_panel.cpp index 7aa84ef..93825e7 100644 --- a/CYD-Klipper/src/ui/panels/progress_panel.cpp +++ b/CYD-Klipper/src/ui/panels/progress_panel.cpp @@ -28,6 +28,28 @@ static void update_printer_data_remaining_time(lv_event_t * e){ lv_label_set_text(label, time_display(printer.remaining_time_s)); } +static void update_printer_data_stats(lv_event_t * e){ + lv_obj_t * label = lv_event_get_target(e); + char buff[256] = {0}; + + switch (get_current_printer_config()->show_stats_on_progress_panel) + { + case SHOW_STATS_ON_PROGRESS_PANEL_LAYER: + sprintf(buff, "Layer %d of %d", printer.current_layer, printer.total_layers); + break; + case SHOW_STATS_ON_PROGRESS_PANEL_PARTIAL: + sprintf(buff, "Position: X%.2f Y%.2f\nFeedrate: %d mm/s\nFilament Used: %.2f m\nLayer %d of %d", + printer.position[0], printer.position[1], printer.feedrate_mm_per_s, printer.filament_used_mm / 1000, printer.current_layer, printer.total_layers); + break; + case SHOW_STATS_ON_PROGRESS_PANEL_ALL: + sprintf(buff, "Pressure Advance: %.3f (%.2fs)\nPosition: X%.2f Y%.2f Z%.2f\nFeedrate: %d mm/s\nFilament Used: %.2f m\nFan: %.0f%%\nSpeed: %.0f%%\nFlow: %.0f%%\nLayer %d of %d", + printer.pressure_advance, printer.smooth_time, printer.position[0], printer.position[1], printer.position[2], printer.feedrate_mm_per_s, printer.filament_used_mm / 1000, printer.fan_speed * 100, printer.speed_mult * 100, printer.extrude_mult * 100, printer.current_layer, printer.total_layers); + break; + } + + lv_label_set_text(label, buff); +} + static void update_printer_data_percentage(lv_event_t * e){ lv_obj_t * label = lv_event_get_target(e); char percentage_buffer[12]; @@ -52,10 +74,28 @@ void progress_panel_init(lv_obj_t* panel){ const auto button_size_mult = 1.3f; lv_obj_t * center_panel = lv_create_empty_panel(panel); - lv_obj_align(center_panel, LV_ALIGN_CENTER, 0, 0); lv_obj_set_size(center_panel, panel_width, LV_SIZE_CONTENT); lv_layout_flex_column(center_panel); + if (get_current_printer_config()->show_stats_on_progress_panel == SHOW_STATS_ON_PROGRESS_PANEL_ALL) + { + lv_obj_align(center_panel, LV_ALIGN_TOP_MID, 0, CYD_SCREEN_GAP_PX); + } + else + { + lv_obj_align(center_panel, LV_ALIGN_CENTER, 0, 0); + } + + + if (get_current_printer_config()->show_stats_on_progress_panel == SHOW_STATS_ON_PROGRESS_PANEL_LAYER) + { + lv_obj_t * label = lv_label_create(panel); + lv_obj_align(label, LV_ALIGN_TOP_MID, 0, CYD_SCREEN_GAP_PX); + lv_obj_set_style_text_font(label, &CYD_SCREEN_FONT_SMALL, 0); + lv_obj_add_event_cb(label, update_printer_data_stats, LV_EVENT_MSG_RECEIVED, NULL); + lv_msg_subsribe_obj(DATA_PRINTER_DATA, label, NULL); + } + // Filename lv_obj_t * label = lv_label_create(center_panel); lv_label_set_text(label, printer.print_filename); @@ -124,4 +164,13 @@ void progress_panel_init(lv_obj_t* panel){ lv_obj_align(btn, LV_ALIGN_BOTTOM_RIGHT, -2 * CYD_SCREEN_GAP_PX - CYD_SCREEN_MIN_BUTTON_WIDTH_PX * button_size_mult, -1 * CYD_SCREEN_GAP_PX); lv_obj_set_size(btn, CYD_SCREEN_MIN_BUTTON_WIDTH_PX * button_size_mult, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX * button_size_mult); + + if (get_current_printer_config()->show_stats_on_progress_panel >= SHOW_STATS_ON_PROGRESS_PANEL_PARTIAL) + { + label = lv_label_create(panel); + lv_obj_align(label, LV_ALIGN_BOTTOM_LEFT, CYD_SCREEN_GAP_PX, -1 * CYD_SCREEN_GAP_PX); + lv_obj_set_style_text_font(label, &CYD_SCREEN_FONT_SMALL, 0); + lv_obj_add_event_cb(label, update_printer_data_stats, LV_EVENT_MSG_RECEIVED, NULL); + lv_msg_subsribe_obj(DATA_PRINTER_DATA, label, NULL); + } } \ No newline at end of file diff --git a/CYD-Klipper/src/ui/panels/settings_panel.cpp b/CYD-Klipper/src/ui/panels/settings_panel.cpp index ecc124d..1105dd5 100644 --- a/CYD-Klipper/src/ui/panels/settings_panel.cpp +++ b/CYD-Klipper/src/ui/panels/settings_panel.cpp @@ -27,6 +27,10 @@ static void reset_calibration_click(lv_event_t * e){ ESP.restart(); } +static void reset_click(lv_event_t * e){ + ESP.restart(); +} + static void reset_wifi_click(lv_event_t * e){ global_config.wifi_configured = false; write_global_config(); @@ -48,6 +52,12 @@ static void light_mode_switch(lv_event_t * e){ set_color_scheme(); } +static void show_stats_on_progress_panel_dropdown(lv_event_t * e){ + auto selected = lv_dropdown_get_selected(lv_event_get_target(e)); + get_current_printer_config()->show_stats_on_progress_panel = selected; + write_global_config(); +} + static void theme_dropdown(lv_event_t * e){ lv_obj_t * dropdown = lv_event_get_target(e); auto selected = lv_dropdown_get_selected(dropdown); @@ -78,6 +88,14 @@ static void wake_timeout_dropdown(lv_event_t * e){ write_global_config(); } +static void dualusb_screen_fix_switch(lv_event_t* e){ + auto state = lv_obj_get_state(lv_event_get_target(e)); + bool checked = (state & LV_STATE_CHECKED == LV_STATE_CHECKED); + global_config.display_mode = checked; + write_global_config(); + ESP.restart(); +} + static void rotate_screen_switch(lv_event_t* e){ auto state = lv_obj_get_state(lv_event_get_target(e)); bool checked = (state & LV_STATE_CHECKED == LV_STATE_CHECKED); @@ -122,37 +140,61 @@ static void estimated_time_dropdown(lv_event_t * e){ write_global_config(); } -void settings_panel_init(lv_obj_t* panel){ - lv_obj_set_style_pad_all(panel, CYD_SCREEN_GAP_PX, 0); - lv_layout_flex_column(panel); - lv_obj_set_scrollbar_mode(panel, LV_SCROLLBAR_MODE_OFF); +#define PRINTER_SPECIFIC_SETTING global_config.multi_printer_mode ? LV_SYMBOL_PLUS " Stored per printer" : NULL - if (global_config.multi_printer_mode) - { - lv_obj_t * label = lv_label_create(panel); - lv_label_set_text(label, "Printer Specific Settings"); - } +void settings_section_theming(lv_obj_t* panel) +{ + lv_obj_t * label = lv_label_create(panel); + lv_label_set_text(label, "Theming"); - lv_create_custom_menu_dropdown("Estimated Time", panel, estimated_time_dropdown, estimated_time_options, get_current_printer_config()->remaining_time_calc_mode); - lv_create_custom_menu_dropdown("Theme", panel, theme_dropdown, "Blue\nGreen\nGrey\nYellow\nOrange\nRed\nPurple", get_current_printer_config()->color_scheme); + lv_create_custom_menu_dropdown("Theme", panel, theme_dropdown, "Blue\nGreen\nLime\nGrey\nYellow\nOrange\nRed\nPurple", get_current_printer_config()->color_scheme, NULL, PRINTER_SPECIFIC_SETTING); #ifndef CYD_SCREEN_DISABLE_INVERT_COLORS - lv_create_custom_menu_switch("Invert Colors", panel, invert_color_switch, get_current_printer_config()->invert_colors); + lv_create_custom_menu_switch("Invert Colors", panel, invert_color_switch, get_current_printer_config()->invert_colors, NULL, (global_config.multi_printer_mode) ? LV_SYMBOL_PLUS " Stored per printer" + #ifdef CYD_SCREEN_DRIVER_ESP32_2432S028R + "\nIntended for the 2.8\" dual USB model screen" : "Intended for the 2.8\" dual USB model screen" + #else + : NULL + #endif + ); #endif // CYD_SCREEN_DISABLE_INVERT_COLORS - lv_create_custom_menu_switch("Light Mode", panel, light_mode_switch, get_current_printer_config()->light_mode); - lv_create_custom_menu_button("Configure IP", panel, reset_ip_click, "Restart"); + lv_create_custom_menu_switch("Light Mode", panel, light_mode_switch, get_current_printer_config()->light_mode, NULL, PRINTER_SPECIFIC_SETTING); +} + +void settings_section_behaviour(lv_obj_t* panel) +{ + lv_obj_t * label = lv_label_create(panel); + lv_label_set_text(label, "\nBehaviour"); + + lv_create_custom_menu_dropdown("Estimated Time", panel, estimated_time_dropdown, estimated_time_options, get_current_printer_config()->remaining_time_calc_mode, NULL, PRINTER_SPECIFIC_SETTING); + lv_create_custom_menu_dropdown("Stats in Progress Screen", panel, show_stats_on_progress_panel_dropdown, "None\nLayers\nPartial\nAll", get_current_printer_config()->show_stats_on_progress_panel, NULL, PRINTER_SPECIFIC_SETTING); - if (global_config.multi_printer_mode) - { - lv_obj_t * label = lv_label_create(panel); - lv_label_set_text(label, "\nGlobal Settings"); +#ifndef CYD_SCREEN_DISABLE_TIMEOUT + int wake_timeout_settings_index = 0; + for (int i = 0; i < SIZEOF(wake_timeout_options_values); i++){ + if (wake_timeout_options_values[i] == global_config.screen_timeout){ + wake_timeout_settings_index = i; + break; + } } + lv_create_custom_menu_dropdown("Wake Timeout", panel, wake_timeout_dropdown, wake_timeout_options, wake_timeout_settings_index); +#endif + #ifndef CYD_SCREEN_DISABLE_TIMEOUT lv_create_custom_menu_switch("Screen On During Print", panel, on_during_print_switch, global_config.on_during_print); #endif + lv_create_custom_menu_switch("Multi Printer Mode", panel, multi_printer_switch, global_config.multi_printer_mode); + lv_create_custom_menu_button("Configure Printer IP", panel, reset_ip_click, "Restart"); +} + +void settings_section_device(lv_obj_t* panel) +{ + lv_obj_t * label = lv_label_create(panel); + lv_label_set_text(label, "\nDevice"); + int brightness_settings_index = 0; for (int i = 0; i < SIZEOF(brightness_options_values); i++){ if (brightness_options_values[i] == global_config.brightness){ @@ -163,20 +205,11 @@ void settings_panel_init(lv_obj_t* panel){ lv_create_custom_menu_dropdown("Brightness", panel, brightness_dropdown, brightness_options, brightness_settings_index); -#ifndef CYD_SCREEN_DISABLE_TIMEOUT - int wake_timeout_settings_index = 0; - for (int i = 0; i < SIZEOF(wake_timeout_options_values); i++){ - if (wake_timeout_options_values[i] == global_config.screen_timeout){ - wake_timeout_settings_index = i; - break; - } - } - - lv_create_custom_menu_dropdown("Wake Timeout", panel, wake_timeout_dropdown, wake_timeout_options, wake_timeout_settings_index); +#ifdef CYD_SCREEN_DRIVER_ESP32_2432S028R + lv_create_custom_menu_switch("Screen Color Fix", panel, dualusb_screen_fix_switch, global_config.display_mode, NULL, "ONLY for the 2.8\" dual USB model screen"); #endif lv_create_custom_menu_switch("Rotate Screen", panel, rotate_screen_switch, global_config.rotate_screen); - lv_create_custom_menu_switch("Multi Printer Mode", panel, multi_printer_switch, global_config.multi_printer_mode); lv_create_custom_menu_switch("Auto Update", panel, auto_ota_update_switch, global_config.auto_ota_update); lv_create_custom_menu_label("Version", panel, REPO_VERSION " "); @@ -194,9 +227,20 @@ void settings_panel_init(lv_obj_t* panel){ lv_create_custom_menu_label("Device", panel, ARDUINO_BOARD " "); } - #ifndef CYD_SCREEN_DISABLE_TOUCH_CALIBRATION - lv_create_custom_menu_button("Calibrate Touch", panel, reset_calibration_click, "Restart"); - #endif // CYD_SCREEN_DISABLE_TOUCH_CALIBRATION +#ifndef CYD_SCREEN_DISABLE_TOUCH_CALIBRATION + lv_create_custom_menu_button("Calibrate Touch", panel, reset_calibration_click, "Restart"); +#endif // CYD_SCREEN_DISABLE_TOUCH_CALIBRATION lv_create_custom_menu_button("Configure WiFi", panel, reset_wifi_click, "Restart"); + lv_create_custom_menu_button("Restart ESP", panel, reset_click, "Restart"); +} + +void settings_panel_init(lv_obj_t* panel){ + lv_obj_set_style_pad_all(panel, CYD_SCREEN_GAP_PX, 0); + lv_layout_flex_column(panel); + lv_obj_set_scrollbar_mode(panel, LV_SCROLLBAR_MODE_OFF); + + settings_section_theming(panel); + settings_section_behaviour(panel); + settings_section_device(panel); } \ No newline at end of file diff --git a/CYD-Klipper/src/ui/panels/temp_panel.cpp b/CYD-Klipper/src/ui/panels/temp_panel.cpp index 6b5d70c..fc1f57c 100644 --- a/CYD-Klipper/src/ui/panels/temp_panel.cpp +++ b/CYD-Klipper/src/ui/panels/temp_panel.cpp @@ -18,7 +18,7 @@ enum temp_target{ static temp_target keyboard_target; static char hotend_buff[40]; static char bed_buff[40]; -static bool edit_mode = false; +static bool temp_edit_mode = false; lv_obj_t* root_panel; static void update_printer_data_hotend_temp(lv_event_t * e){ @@ -117,12 +117,12 @@ static void keyboard_callback(lv_event_t * e){ static void show_keyboard_with_hotend(lv_event_t * e){ keyboard_target = TARGET_HOTEND; - lv_create_keyboard_text_entry(keyboard_callback); + lv_create_keyboard_text_entry(keyboard_callback, "Set Hotend Temp"); } static void show_keyboard_with_bed(lv_event_t * e){ keyboard_target = TARGET_BED; - lv_create_keyboard_text_entry(keyboard_callback); + lv_create_keyboard_text_entry(keyboard_callback, "Set Bed Temp"); } static void cooldown_temp(lv_event_t * e){ @@ -147,9 +147,9 @@ 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) { + if (temp_edit_mode) { keyboard_target = (temp_target)target; - lv_create_keyboard_text_entry(keyboard_callback); + lv_create_keyboard_text_entry(keyboard_callback, "Set Preset Temp"); return; } @@ -165,7 +165,7 @@ static void set_temp_via_preset(lv_event_t * e){ 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); + temp_edit_mode = (state & LV_STATE_CHECKED == LV_STATE_CHECKED); } static void btn_retract(lv_event_t * e){ @@ -301,7 +301,7 @@ void create_temp_buttons(lv_obj_t * root, lv_obj_t * panel) void temp_panel_init(lv_obj_t * panel){ const auto element_width = CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 2; root_panel = panel; - edit_mode = false; + temp_edit_mode = false; lv_obj_t * root_temp_panel = lv_create_empty_panel(panel); lv_obj_set_size(root_temp_panel, CYD_SCREEN_PANEL_WIDTH_PX, CYD_SCREEN_PANEL_HEIGHT_PX); diff --git a/CYD-Klipper/src/ui/switch_printer.cpp b/CYD-Klipper/src/ui/switch_printer.cpp index 20a8982..708de3a 100644 --- a/CYD-Klipper/src/ui/switch_printer.cpp +++ b/CYD-Klipper/src/ui/switch_printer.cpp @@ -1,17 +1,18 @@ #include "switch_printer.h" -#include "lvgl.h" #include "../conf/global_config.h" #include "ui_utils.h" #include "../core/http_client.h" #include "../core/lv_setup.h" #include "../core/macros_query.h" #include "../core/screen_driver.h" +#include "../core/data_setup.h" void switch_printer(int index) { set_printer_config_index(index); set_color_scheme(); set_invert_display(); + printer.slicer_estimated_print_time_s = 0; } static void btn_switch_printer(lv_event_t *e){ @@ -47,7 +48,7 @@ void switch_printer_init() { PRINTER_CONFIG * config = &global_config.printer_config[i]; const char* printer_name = (config->printer_name[0] == 0) ? config->klipper_host : config->printer_name; - if (config == get_current_printer_config()) + if (config == get_current_printer_config() && config->ip_configured) { lv_create_custom_menu_label(printer_name, parent, "Active"); continue; @@ -59,14 +60,7 @@ void switch_printer_init() { int httpCode = client.GET(); - if (httpCode == 200) - { - lv_create_custom_menu_button(printer_name, parent, btn_switch_printer, "Switch", config); - } - else - { - lv_create_custom_menu_label(printer_name, parent, "Offline"); - } + lv_create_custom_menu_button(printer_name, parent, btn_switch_printer, (httpCode == 200) ? "Switch" : "Offline", config); } } } @@ -75,11 +69,11 @@ static void show_switch_printer_screen(lv_event_t * e){ switch_printer_init(); } -void draw_switch_printer_button() +lv_obj_t * draw_switch_printer_button() { if (!global_config.multi_printer_mode) { - return; + return NULL; } lv_obj_t * btn = lv_btn_create(lv_scr_act()); @@ -90,4 +84,6 @@ void draw_switch_printer_button() lv_obj_t * label = lv_label_create(btn); lv_label_set_text(label, LV_SYMBOL_HOME); lv_obj_center(label); + + return btn; } \ No newline at end of file diff --git a/CYD-Klipper/src/ui/switch_printer.h b/CYD-Klipper/src/ui/switch_printer.h index 775303c..070ef72 100644 --- a/CYD-Klipper/src/ui/switch_printer.h +++ b/CYD-Klipper/src/ui/switch_printer.h @@ -1,5 +1,6 @@ #pragma once +#include "lvgl.h" void switch_printer(int index); void switch_printer_init(); -void draw_switch_printer_button(); \ No newline at end of file +lv_obj_t * draw_switch_printer_button(); \ No newline at end of file diff --git a/CYD-Klipper/src/ui/ui_utils.cpp b/CYD-Klipper/src/ui/ui_utils.cpp index b1e6b4a..35b399e 100644 --- a/CYD-Klipper/src/ui/ui_utils.cpp +++ b/CYD-Klipper/src/ui/ui_utils.cpp @@ -9,6 +9,7 @@ lv_obj_t* lv_create_empty_panel(lv_obj_t* root) { 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_set_style_radius(panel, 0, 0); return panel; } @@ -100,7 +101,7 @@ void lv_keyboard_text_entry_close(lv_event_t * e){ } } -void lv_create_keyboard_text_entry(lv_event_cb_t keyboard_callback, lv_keyboard_mode_t keyboard_mode, lv_coord_t width, uint8_t max_length, const char* fill_text, bool contain_in_panel) +void lv_create_keyboard_text_entry(lv_event_cb_t keyboard_callback, const char* title, lv_keyboard_mode_t keyboard_mode, lv_coord_t width, uint8_t max_length, const char* fill_text, bool contain_in_panel) { lv_obj_t * parent = lv_create_empty_panel(lv_scr_act()); lv_obj_set_style_bg_opa(parent, LV_OPA_50, 0); @@ -116,6 +117,19 @@ void lv_create_keyboard_text_entry(lv_event_cb_t keyboard_callback, lv_keyboard_ lv_obj_set_size(parent, CYD_SCREEN_WIDTH_PX, CYD_SCREEN_HEIGHT_PX); } + if (title != nullptr) + { + lv_obj_t * empty_panel = lv_create_empty_panel(parent); + lv_obj_set_size(empty_panel, 0, 0); + + lv_obj_t * title_container = lv_obj_create(parent); + lv_obj_set_style_pad_all(title_container, CYD_SCREEN_GAP_PX / 2, 0); + lv_obj_set_size(title_container, LV_SIZE_CONTENT, LV_SIZE_CONTENT); + + lv_obj_t * title_label = lv_label_create(title_container); + lv_label_set_text(title_label, title); + } + lv_obj_t * empty_panel = lv_create_empty_panel(parent); lv_obj_set_flex_grow(empty_panel, 1); @@ -135,7 +149,7 @@ void lv_create_keyboard_text_entry(lv_event_cb_t keyboard_callback, lv_keyboard_ const static lv_point_t line_points[] = { {0, 0}, {(short int)((CYD_SCREEN_PANEL_WIDTH_PX - CYD_SCREEN_GAP_PX * 2) * 0.85f), 0} }; -void lv_create_custom_menu_entry(const char* label_text, lv_obj_t* object, lv_obj_t* root_panel, bool set_height) +void lv_create_custom_menu_entry(const char* label_text, lv_obj_t* object, lv_obj_t* root_panel, bool set_height, const char * comment) { lv_obj_t * panel = lv_create_empty_panel(root_panel); lv_layout_flex_row(panel, LV_FLEX_ALIGN_END); @@ -151,6 +165,13 @@ void lv_create_custom_menu_entry(const char* label_text, lv_obj_t* object, lv_ob if (set_height) lv_obj_set_height(object, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX); + if (comment != NULL) + { + lv_obj_t * comment_label = lv_label_create(root_panel); + lv_label_set_text(comment_label, comment); + lv_obj_set_style_text_font(comment_label, &CYD_SCREEN_FONT_SMALL, 0); + } + lv_obj_t * line = lv_line_create(root_panel); lv_line_set_points(line, line_points, 2); lv_obj_set_style_line_width(line, 1, 0); @@ -160,7 +181,7 @@ void lv_create_custom_menu_entry(const char* label_text, lv_obj_t* object, lv_ob #define DROPDOWN_WIDTH CYD_SCREEN_MIN_BUTTON_WIDTH_PX * 3.75 #define TOGGLE_WIDTH CYD_SCREEN_MIN_BUTTON_WIDTH_PX * 2 -void lv_create_custom_menu_button(const char *label_text, lv_obj_t* root_panel, lv_event_cb_t on_click, const char *btn_text, void * user_data) +void lv_create_custom_menu_button(const char *label_text, lv_obj_t* root_panel, lv_event_cb_t on_click, const char *btn_text, void * user_data, const char * comment) { lv_obj_t * btn = lv_btn_create(lv_scr_act()); lv_obj_add_event_cb(btn, on_click, LV_EVENT_CLICKED, user_data); @@ -169,10 +190,10 @@ void lv_create_custom_menu_button(const char *label_text, lv_obj_t* root_panel, lv_label_set_text(label, btn_text); lv_obj_center(label); - lv_create_custom_menu_entry(label_text, btn, root_panel, true); + lv_create_custom_menu_entry(label_text, btn, root_panel, true, comment); } -void lv_create_custom_menu_switch(const char *label_text, lv_obj_t* root_panel, lv_event_cb_t on_toggle, bool state, void * user_data) +void lv_create_custom_menu_switch(const char *label_text, lv_obj_t* root_panel, lv_event_cb_t on_toggle, bool state, void * user_data, const char * comment) { lv_obj_t * toggle = lv_switch_create(lv_scr_act()); lv_obj_add_event_cb(toggle, on_toggle, LV_EVENT_VALUE_CHANGED, user_data); @@ -181,10 +202,10 @@ void lv_create_custom_menu_switch(const char *label_text, lv_obj_t* root_panel, if (state) lv_obj_add_state(toggle, LV_STATE_CHECKED); - lv_create_custom_menu_entry(label_text, toggle, root_panel, true); + lv_create_custom_menu_entry(label_text, toggle, root_panel, true, comment); } -void lv_create_custom_menu_dropdown(const char *label_text, lv_obj_t *root_panel, lv_event_cb_t on_change, const char *options, int index, void * user_data) +void lv_create_custom_menu_dropdown(const char *label_text, lv_obj_t *root_panel, lv_event_cb_t on_change, const char *options, int index, void * user_data, const char * comment) { lv_obj_t * dropdown = lv_dropdown_create(lv_scr_act()); lv_dropdown_set_options(dropdown, options); @@ -192,7 +213,7 @@ void lv_create_custom_menu_dropdown(const char *label_text, lv_obj_t *root_panel lv_obj_set_width(dropdown, DROPDOWN_WIDTH); lv_obj_add_event_cb(dropdown, on_change, LV_EVENT_VALUE_CHANGED, user_data); - lv_create_custom_menu_entry(label_text, dropdown, root_panel, true); + lv_create_custom_menu_entry(label_text, dropdown, root_panel, true, comment); } void lv_create_custom_menu_label(const char *label_text, lv_obj_t* root_panel, const char *text) @@ -247,4 +268,14 @@ void lv_create_popup_message(const char* message, uint16_t timeout_ms) lv_label_set_long_mode(label, LV_LABEL_LONG_WRAP); timer = lv_timer_create(timer_callback, timeout_ms, panel); +} + +lv_obj_t * lv_label_btn_create(lv_obj_t * parent, lv_event_cb_t btn_callback, void* user_data) +{ + lv_obj_t * panel = lv_create_empty_panel(parent); + lv_obj_set_size(panel, LV_SIZE_CONTENT, LV_SIZE_CONTENT); + lv_obj_add_event_cb(panel, btn_callback, LV_EVENT_CLICKED, user_data); + + lv_obj_t * label = lv_label_create(panel); + return label; } \ No newline at end of file diff --git a/CYD-Klipper/src/ui/ui_utils.h b/CYD-Klipper/src/ui/ui_utils.h index 8c4239c..66dd6fc 100644 --- a/CYD-Klipper/src/ui/ui_utils.h +++ b/CYD-Klipper/src/ui/ui_utils.h @@ -38,10 +38,11 @@ void lv_layout_flex_column(lv_obj_t* obj, lv_flex_align_t allign = LV_FLEX_ALIGN void lv_layout_flex_row(lv_obj_t* obj, lv_flex_align_t allign = LV_FLEX_ALIGN_START, lv_coord_t pad_column = CYD_SCREEN_GAP_PX, lv_coord_t pad_row = CYD_SCREEN_GAP_PX); void lv_create_fullscreen_button_matrix_popup(lv_obj_t * root, lv_event_cb_t title, lv_button_column_t* columns, int column_count); void destroy_event_user_data(lv_event_t * e); -void lv_create_keyboard_text_entry(lv_event_cb_t keyboard_callback, lv_keyboard_mode_t keyboard_mode = LV_KEYBOARD_MODE_NUMBER, lv_coord_t width = CYD_SCREEN_PANEL_WIDTH_PX / 2, uint8_t max_length = 3, const char* fill_text = "", bool contain_in_panel= true); -void lv_create_custom_menu_entry(const char* label_text, lv_obj_t* object, lv_obj_t* root_panel, bool set_height = true); -void lv_create_custom_menu_button(const char *label_text, lv_obj_t* root_panel, lv_event_cb_t on_click, const char *btn_text, void * user_data = NULL); -void lv_create_custom_menu_switch(const char *label_text, lv_obj_t* root_panel, lv_event_cb_t on_toggle, bool state, void * user_data = NULL); -void lv_create_custom_menu_dropdown(const char *label_text, lv_obj_t *root_panel, lv_event_cb_t on_change, const char *options, int index, void * user_data = NULL); +void lv_create_keyboard_text_entry(lv_event_cb_t keyboard_callback, const char* title = NULL, lv_keyboard_mode_t keyboard_mode = LV_KEYBOARD_MODE_NUMBER, lv_coord_t width = CYD_SCREEN_PANEL_WIDTH_PX / 2, uint8_t max_length = 3, const char* fill_text = "", bool contain_in_panel= true); +void lv_create_custom_menu_entry(const char* label_text, lv_obj_t* object, lv_obj_t* root_panel, bool set_height = true, const char * comment = NULL); +void lv_create_custom_menu_button(const char *label_text, lv_obj_t* root_panel, lv_event_cb_t on_click, const char *btn_text, void * user_data = NULL, const char * comment = NULL); +void lv_create_custom_menu_switch(const char *label_text, lv_obj_t* root_panel, lv_event_cb_t on_toggle, bool state, void * user_data = NULL, const char * comment = NULL); +void lv_create_custom_menu_dropdown(const char *label_text, lv_obj_t *root_panel, lv_event_cb_t on_change, const char *options, int index, void * user_data = NULL, const char * comment = NULL); void lv_create_custom_menu_label(const char *label_text, lv_obj_t* root_panel, const char *text); -void lv_create_popup_message(const char* message, uint16_t timeout_ms); \ No newline at end of file +void lv_create_popup_message(const char* message, uint16_t timeout_ms); +lv_obj_t * lv_label_btn_create(lv_obj_t * parent, lv_event_cb_t btn_callback, void* user_data = NULL); \ No newline at end of file diff --git a/CYD-Klipper/src/ui/wifi_setup.cpp b/CYD-Klipper/src/ui/wifi_setup.cpp index fb2e366..027011d 100644 --- a/CYD-Klipper/src/ui/wifi_setup.cpp +++ b/CYD-Klipper/src/ui/wifi_setup.cpp @@ -3,86 +3,106 @@ #include "../conf/global_config.h" #include "ui_utils.h" #include "WiFi.h" +#include "../core/data_setup.h" +#include "../core/lv_setup.h" void wifi_init_inner(); +void wifi_pass_entry(const char* ssid); + +const char * current_ssid_ptr = NULL; static void reset_btn_event_handler(lv_event_t * e) { - lv_event_code_t code = lv_event_get_code(e); + global_config.wifi_configured = false; + wifi_init_inner(); +} - if(code == LV_EVENT_CLICKED) { - global_config.wifi_configured = false; - wifi_init_inner(); - } +static void keyboard_cb_enter_password(lv_event_t * e) { + lv_obj_t * ta = lv_event_get_target(e); + lv_obj_t * kb = (lv_obj_t *)lv_event_get_user_data(e); + const char * txt = lv_textarea_get_text(ta); + global_config.wifi_configured = true; + strcpy(global_config.wifi_SSID, current_ssid_ptr); + strcpy(global_config.wifi_password, txt); + write_global_config(); + wifi_init_inner(); } -static void refresh_btn_event_handler(lv_event_t * e){ - lv_event_code_t code = lv_event_get_code(e); +static void btn_reuse_password(lv_event_t * e) +{ + ESP.restart(); +} - if(code == LV_EVENT_CLICKED) { - wifi_init_inner(); - } +static void btn_no_reuse_password(lv_event_t * e) +{ + lv_create_keyboard_text_entry(keyboard_cb_enter_password, "Enter WiFi Password", LV_KEYBOARD_MODE_TEXT_LOWER, CYD_SCREEN_WIDTH_PX * 0.75, 63, "", false); } -static void ta_event_cb(lv_event_t * e) { - lv_event_code_t code = lv_event_get_code(e); - lv_obj_t * ta = lv_event_get_target(e); +void ask_reuse_password(const char * ssid){ + lv_obj_t * root = lv_obj_create(lv_scr_act()); + lv_obj_set_size(root, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 2, CYD_SCREEN_HEIGHT_PX - CYD_SCREEN_GAP_PX * 2); + lv_obj_align(root, LV_ALIGN_CENTER, 0, 0); + lv_layout_flex_column(root, LV_FLEX_ALIGN_SPACE_BETWEEN); - if (code == LV_EVENT_READY) - { - const char * txt = lv_textarea_get_text(ta); - int len = strlen(txt); - if (len > 0) - { - global_config.wifi_configured = true; - strcpy(global_config.wifi_password, txt); - write_global_config(); - wifi_init_inner(); - } - } - else if (code == LV_EVENT_CANCEL) - { - wifi_init_inner(); - } + lv_obj_t * label = lv_label_create(root); + lv_label_set_text_fmt(label, "Reuse stored WiFi Password?\n(Password Length: %d)", strlen(global_config.wifi_password)); + + lv_obj_t * button_row = lv_create_empty_panel(root); + lv_layout_flex_row(button_row, LV_FLEX_ALIGN_SPACE_BETWEEN); + lv_obj_set_size(button_row, lv_pct(100), CYD_SCREEN_MIN_BUTTON_HEIGHT_PX); + + lv_obj_t * no_btn = lv_btn_create(button_row); + lv_obj_add_event_cb(no_btn, btn_no_reuse_password, LV_EVENT_CLICKED, (void*)ssid); + lv_obj_add_event_cb(no_btn, destroy_event_user_data, LV_EVENT_CLICKED, root); + lv_obj_set_height(no_btn, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX); + lv_obj_set_width(no_btn, CYD_SCREEN_MIN_BUTTON_WIDTH_PX); + lv_obj_set_style_pad_all(no_btn, CYD_SCREEN_GAP_PX, 0); + + label = lv_label_create(no_btn); + lv_label_set_text(label, LV_SYMBOL_CLOSE); + lv_obj_center(label); + + lv_obj_t * yes_btn = lv_btn_create(button_row); + lv_obj_add_event_cb(yes_btn, btn_reuse_password, LV_EVENT_CLICKED, (void*)ssid); + lv_obj_set_height(yes_btn, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX); + lv_obj_set_width(yes_btn, CYD_SCREEN_MIN_BUTTON_WIDTH_PX); + lv_obj_set_style_pad_all(yes_btn, CYD_SCREEN_GAP_PX, 0); + + label = lv_label_create(yes_btn); + lv_label_set_text(label, LV_SYMBOL_OK); + lv_obj_center(label); } -void wifi_pass_entry(const char* ssid){ - lv_obj_clean(lv_scr_act()); +void wifi_pass_entry(const char* ssid) +{ + current_ssid_ptr = ssid; - lv_obj_t * root = lv_create_empty_panel(lv_scr_act()); - lv_obj_set_size(root, CYD_SCREEN_WIDTH_PX, CYD_SCREEN_HEIGHT_PX); - lv_layout_flex_column(root); + if (strcmp(ssid, global_config.wifi_SSID) == 0){ + ask_reuse_password(ssid); + return; + } - lv_obj_t * top_root = lv_create_empty_panel(root); - lv_obj_set_width(top_root, CYD_SCREEN_WIDTH_PX); - lv_layout_flex_column(top_root); - lv_obj_set_flex_grow(top_root, 1); - lv_obj_set_style_pad_all(top_root, CYD_SCREEN_GAP_PX, 0); - - lv_obj_t * label = lv_label_create(top_root); - lv_label_set_text(label, "Enter WiFi Password"); - lv_obj_set_width(label, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 2); - - lv_obj_t * passEntry = lv_textarea_create(top_root); - lv_textarea_set_one_line(passEntry, true); - lv_textarea_set_text(passEntry, ""); - lv_obj_set_width(passEntry, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 2); - lv_obj_add_event_cb(passEntry, ta_event_cb, LV_EVENT_ALL, NULL); - lv_obj_set_flex_grow(passEntry, 1); - - lv_obj_t * keyboard = lv_keyboard_create(root); - lv_keyboard_set_textarea(keyboard, passEntry); + btn_no_reuse_password(NULL); } static void wifi_btn_event_handler(lv_event_t * e){ - lv_event_code_t code = lv_event_get_code(e); - - if(code == LV_EVENT_CLICKED) { - delay(100); - char* ssid = (char*)e->user_data; - strcpy(global_config.wifi_SSID, ssid); - Serial.println(ssid); - wifi_pass_entry(ssid); - } + delay(100); + char* ssid = (char*)e->user_data; + Serial.println(ssid); + wifi_pass_entry(ssid); +} + +static void wifi_keyboard_cb_manual_ssid(lv_event_t * e){ + lv_obj_t * ta = lv_event_get_target(e); + lv_obj_t * kb = (lv_obj_t *)lv_event_get_user_data(e); + const char * text = lv_textarea_get_text(ta); + char * text_copy = (char*)malloc(strlen(text) + 1); + strcpy(text_copy, text); + Serial.println(text_copy); + wifi_pass_entry(text_copy); +} + +static void wifi_btn_manual_ssid(lv_event_t * e){ + lv_create_keyboard_text_entry(wifi_keyboard_cb_manual_ssid, "Enter SSID Manually", LV_KEYBOARD_MODE_TEXT_LOWER, CYD_SCREEN_WIDTH_PX * 0.75, 31, "", false); } void wifi_init_inner(){ @@ -90,8 +110,17 @@ void wifi_init_inner(){ lv_obj_clean(lv_scr_act()); if (global_config.wifi_configured){ - WiFi.begin(global_config.wifi_SSID, global_config.wifi_password); + if (global_config.wifi_password[0] == '\0') + { + WiFi.begin(global_config.wifi_SSID); + } + else + { + WiFi.begin(global_config.wifi_SSID, global_config.wifi_password); + } + Serial.printf("Connecting to %s with a password length of %d\n", global_config.wifi_SSID, strlen(global_config.wifi_password)); + lv_obj_t * label = lv_label_create(lv_scr_act()); lv_label_set_text(label, "Connecting to WiFi"); lv_obj_align(label, LV_ALIGN_CENTER, 0, 0); @@ -125,16 +154,25 @@ void wifi_init_inner(){ lv_obj_t * top_row = lv_create_empty_panel(root); lv_obj_set_size(top_row, CYD_SCREEN_WIDTH_PX - CYD_SCREEN_GAP_PX * 2, LV_SIZE_CONTENT); - lv_layout_flex_row(top_row, LV_FLEX_ALIGN_SPACE_BETWEEN); + lv_layout_flex_row(top_row); label = lv_label_create(top_row); lv_label_set_text(label, "Select a network"); + lv_obj_set_flex_grow(label, 1); + + lv_obj_t * btn = lv_btn_create(top_row); + lv_obj_add_event_cb(btn, wifi_btn_manual_ssid, LV_EVENT_CLICKED, NULL); + lv_obj_set_size(btn, CYD_SCREEN_MIN_BUTTON_WIDTH_PX, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX); - lv_obj_t * refreshBtn = lv_btn_create(top_row); - lv_obj_add_event_cb(refreshBtn, reset_btn_event_handler, LV_EVENT_ALL, NULL); - lv_obj_set_size(refreshBtn, CYD_SCREEN_MIN_BUTTON_WIDTH_PX, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX); + label = lv_label_create(btn); + lv_label_set_text(label, LV_SYMBOL_KEYBOARD); + lv_obj_center(label); - label = lv_label_create(refreshBtn); + btn = lv_btn_create(top_row); + lv_obj_add_event_cb(btn, reset_btn_event_handler, LV_EVENT_CLICKED, NULL); + lv_obj_set_size(btn, CYD_SCREEN_MIN_BUTTON_WIDTH_PX, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX); + + label = lv_label_create(btn); lv_label_set_text(label, LV_SYMBOL_REFRESH); lv_obj_center(label); @@ -159,7 +197,7 @@ void wifi_init_inner(){ ssid_copy[j] = '\0'; lv_obj_t * btn = lv_list_add_btn(list, LV_SYMBOL_WIFI, ssid_copy); - lv_obj_add_event_cb(btn, wifi_btn_event_handler, LV_EVENT_ALL, (void*)ssid_copy); + lv_obj_add_event_cb(btn, wifi_btn_event_handler, LV_EVENT_CLICKED, (void*)ssid_copy); } } @@ -186,13 +224,39 @@ void wifi_init(){ Serial.printf("WiFi Status: %s\n", errs[WiFi.status()]); } - lv_timer_handler(); - lv_task_handler(); + lv_handler(); } } +ulong start_time_recovery = 0; + void wifi_ok(){ if (WiFi.status() != WL_CONNECTED){ - ESP.restart(); + Serial.println("WiFi Connection Lost. Reconnecting..."); + freeze_request_thread(); + WiFi.disconnect(); + delay(5000); // Wait for the WiFi to disconnect + + start_time_recovery = millis(); + + if (global_config.wifi_password[0] == '\0') + { + WiFi.begin(global_config.wifi_SSID); + } + else + { + WiFi.begin(global_config.wifi_SSID, global_config.wifi_password); + } + + while (WiFi.status() != WL_CONNECTED){ + delay(1000); + Serial.printf("WiFi Status: %s\n", errs[WiFi.status()]); + if (millis() - start_time_recovery > 15000){ + Serial.println("WiFi Connection failed to reconnect. Restarting..."); + ESP.restart(); + } + } + + unfreeze_request_thread(); } } \ No newline at end of file diff --git a/_site/index.html b/_site/index.html index a82f39c..20a3822 100644 --- a/_site/index.html +++ b/_site/index.html @@ -80,12 +80,12 @@

Report Issues

-

If you experience any issues with this project, or any feature requests for the project, please report them on the issues tab on Github.

+

If you experience any issues with this project, or have any feature requests for the project, please report them on the issues tab on Github.

Install

-

Select your device from the list below and click 'Connect'.
Note: You may need to hold the 'BOOT' button on the device while pressing install.
The 2.8" Resistive and 3.5" Capacitive models are best suited (in my opinion) for CYD-Klipper.

+

Select your device from the list below and click 'Connect'.
Note: You may need to hold the 'BOOT' button on the device while pressing install.

The 2.8" Resistive and 3.5" Capacitive models are best suited (in my opinion) for CYD-Klipper.

Note for any resistive models: You can clear touch calibration by holding the BOOT button for 8 seconds while the screen is on.