diff --git a/CYD-Klipper/.vscode/settings.json b/CYD-Klipper/.vscode/settings.json index e1ffb15..582e7bf 100644 --- a/CYD-Klipper/.vscode/settings.json +++ b/CYD-Klipper/.vscode/settings.json @@ -48,7 +48,8 @@ "stdexcept": "cpp", "streambuf": "cpp", "cinttypes": "cpp", - "typeinfo": "cpp" + "typeinfo": "cpp", + "lv_group.h": "c" }, "cmake.configureOnOpen": false } \ No newline at end of file diff --git a/CYD-Klipper/src/core/klipper/klipper_printer_parsers.cpp b/CYD-Klipper/src/core/klipper/klipper_printer_parsers.cpp index 5e2ed95..ae3a2c2 100644 --- a/CYD-Klipper/src/core/klipper/klipper_printer_parsers.cpp +++ b/CYD-Klipper/src/core/klipper/klipper_printer_parsers.cpp @@ -56,6 +56,12 @@ void KlipperPrinter::parse_state(JsonDocument &in) { const char *homed_axis = status["toolhead"]["homed_axes"]; printer_data.homed_axis = strcmp(homed_axis, "xyz") == 0; + + for (int i = 0; i < 3; i++) + { + printer_data.position_min[i] = status["toolhead"]["axis_minimum"][i]; + printer_data.position_max[i] = status["toolhead"]["axis_maximum"][i]; + } } if (status.containsKey("gcode_move")) diff --git a/CYD-Klipper/src/core/printer_integration.hpp b/CYD-Klipper/src/core/printer_integration.hpp index a731e34..9e6285d 100644 --- a/CYD-Klipper/src/core/printer_integration.hpp +++ b/CYD-Klipper/src/core/printer_integration.hpp @@ -82,6 +82,8 @@ typedef struct _PrinterData { float temperatures[10]; float target_temperatures[10]; float position[3]; + float position_min[3]; + float position_max[3]; float elapsed_time_s; float printed_time_s; float remaining_time_s; diff --git a/CYD-Klipper/src/ui/panels/move_panel.cpp b/CYD-Klipper/src/ui/panels/move_panel.cpp index e4d9aa8..69d82f2 100644 --- a/CYD-Klipper/src/ui/panels/move_panel.cpp +++ b/CYD-Klipper/src/ui/panels/move_panel.cpp @@ -344,18 +344,24 @@ static void root_panel_state_update(lv_event_t * e){ if (last_homing_state == get_current_printer_data()->homed_axis) return; + PrinterType printer_type = get_current_printer()->printer_config->printer_type; + bool is_klipper = printer_type == PrinterTypeKlipper || printer_type == PrinterTypeKlipperSerial; + lv_obj_t * panel = lv_event_get_target(e); last_homing_state = get_current_printer_data()->homed_axis; lv_obj_clean(panel); - if (get_current_printer_data()->homed_axis) + if (get_current_printer_data()->homed_axis && is_klipper) + move_panel_slider_init(panel); + else if (get_current_printer_data()->homed_axis) root_panel_steppers_locked(panel); - else + else root_panel_steppers_unlocked(panel); } -void move_panel_init(lv_obj_t* panel){ +void move_panel_init(lv_obj_t* panel) +{ if (get_current_printer_data()->state == PrinterState::PrinterStatePrinting){ stats_panel_init(panel); return; diff --git a/CYD-Klipper/src/ui/panels/move_panel_slider.cpp b/CYD-Klipper/src/ui/panels/move_panel_slider.cpp new file mode 100644 index 0000000..26e0e6e --- /dev/null +++ b/CYD-Klipper/src/ui/panels/move_panel_slider.cpp @@ -0,0 +1,233 @@ +#include "panel.h" +#include "lvgl.h" +#include "../../core/data_setup.h" +#include "../nav_buttons.h" +#include "../ui_utils.h" +#include "../../core/printer_integration.hpp" +#include "../../core/current_printer.h" + +static void line_custom_set(const char * axis, const char *text) +{ + float pos = atof(text); + + if (pos < 0 || pos > 500) + return; + + current_printer_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, LV_PCT(75), 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, LV_PCT(75), 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, LV_PCT(75), 6); +} + +static void pos_update(lv_obj_t *obj, const char* target_template, float target) +{ + if (lv_obj_check_type(obj, &lv_label_class)) + { + char pos_buff[12]; + sprintf(pos_buff, target_template, target); + lv_label_set_text(obj, pos_buff); + } + else + { + lv_slider_set_value(obj, target, LV_ANIM_ON); + } +} + +static void x_pos_update(lv_event_t * e) +{ + pos_update(lv_event_get_target(e), "%.1f " LV_SYMBOL_EDIT, get_current_printer_data()->position[0]); +} + +static void y_pos_update(lv_event_t * e) +{ + pos_update(lv_event_get_target(e), "%.1f", get_current_printer_data()->position[1]); +} + +static void z_pos_update(lv_event_t * e) +{ + pos_update(lv_event_get_target(e), "%.2f", get_current_printer_data()->position[2]); +} + +static void x_slider_update(lv_event_t * e) +{ + current_printer_move_printer("X", lv_slider_get_value(lv_event_get_target(e)), false); +} + +static void y_slider_update(lv_event_t * e) +{ + current_printer_move_printer("Y", lv_slider_get_value(lv_event_get_target(e)), false); +} + +static void z_slider_update(lv_event_t * e) +{ + current_printer_move_printer("Z", lv_slider_get_value(lv_event_get_target(e)), false); +} + +static void home_button_click(lv_event_t * e) +{ + current_printer_execute_feature(PrinterFeatures::PrinterFeatureHome); +} + +static void disable_steppers_button_click(lv_event_t * e) +{ + current_printer_execute_feature(PrinterFeatures::PrinterFeatureDisableSteppers); +} + +static void switch_to_params_panel_button_click(lv_event_t * e) +{ + lv_obj_t * panel = lv_event_get_target(e); + nav_buttons_setup(PANEL_STATS); +} + +static void make_vertical_slider( + lv_obj_t* parent, + const char* axis, + lv_event_cb_t position_change, + lv_event_cb_t on_slider_change, + lv_event_cb_t on_edit, + float min, + float max) +{ + lv_obj_t* root = lv_create_empty_panel(parent); + lv_layout_flex_column(root); + lv_obj_set_size(root, CYD_SCREEN_MIN_BUTTON_WIDTH_PX * 1.5, LV_PCT(100)); + lv_obj_set_style_pad_column(root, 10, 0); + lv_obj_clear_flag(root, LV_OBJ_FLAG_SCROLLABLE); + + lv_obj_t* sub_root = lv_create_empty_panel(root); + lv_layout_flex_column(sub_root); + lv_obj_set_height(sub_root, LV_SIZE_CONTENT); + lv_obj_add_flag(sub_root, LV_OBJ_FLAG_CLICKABLE); + lv_obj_add_event_cb(sub_root, on_edit, LV_EVENT_CLICKED, NULL); + + lv_obj_t* top_label = lv_label_create(sub_root); + lv_obj_add_event_cb(top_label, position_change, LV_EVENT_MSG_RECEIVED, NULL); + lv_msg_subsribe_obj(DATA_PRINTER_DATA, top_label, NULL); + + lv_obj_t* one_below_label = lv_label_create(sub_root); + lv_label_set_text(one_below_label, LV_SYMBOL_EDIT); + + lv_obj_t* two_below_label = lv_label_create(sub_root); + lv_label_set_text_fmt(two_below_label, "%s+", axis); + + lv_obj_t* slider = lv_slider_create(root); + lv_obj_set_flex_grow(slider, 1); + lv_obj_set_width(slider, CYD_SCREEN_MIN_BUTTON_WIDTH_PX / 2); + lv_slider_set_range(slider, min, max); + lv_obj_add_event_cb(slider, on_slider_change, LV_EVENT_RELEASED, NULL); + lv_obj_add_event_cb(slider, position_change, LV_EVENT_MSG_RECEIVED, NULL); + lv_msg_subsribe_obj(DATA_PRINTER_DATA, slider, NULL); + + lv_obj_t* last_label = lv_label_create(root); + lv_label_set_text_fmt(last_label, "%s-", axis); +} + +static void make_horizontal_slider( + lv_obj_t* parent, + const char* axis, + lv_event_cb_t position_change, + lv_event_cb_t on_slider_change, + lv_event_cb_t on_edit, + float min, + float max) +{ + lv_obj_t* root = lv_create_empty_panel(parent); + lv_layout_flex_column(root); + lv_obj_set_size(root, LV_PCT(100), LV_SIZE_CONTENT); + + lv_obj_t* upper = lv_create_empty_panel(root); + lv_layout_flex_row(upper, LV_FLEX_ALIGN_SPACE_BETWEEN); + lv_obj_set_size(upper, LV_PCT(100), LV_SIZE_CONTENT); + lv_obj_add_flag(upper, LV_OBJ_FLAG_CLICKABLE); + lv_obj_add_event_cb(upper, on_edit, LV_EVENT_CLICKED, NULL); + + lv_obj_t* left_label = lv_label_create(upper); + lv_label_set_text_fmt(left_label, "%s-", axis); + + lv_obj_t* position_label = lv_label_create(upper); + lv_obj_add_event_cb(position_label, position_change, LV_EVENT_MSG_RECEIVED, NULL); + lv_msg_subsribe_obj(DATA_PRINTER_DATA, position_label, NULL); + + lv_obj_t* right_label = lv_label_create(upper); + lv_label_set_text_fmt(right_label, "%s+", axis); + + lv_obj_t* slider = lv_slider_create(root); + lv_obj_set_size(slider, LV_PCT(100), CYD_SCREEN_MIN_BUTTON_HEIGHT_PX / 2); + lv_slider_set_range(slider, min, max); + lv_obj_add_event_cb(slider, on_slider_change, LV_EVENT_RELEASED, NULL); + lv_obj_add_event_cb(slider, position_change, LV_EVENT_MSG_RECEIVED, NULL); + lv_msg_subsribe_obj(DATA_PRINTER_DATA, slider, NULL); + + lv_obj_set_style_pad_bottom(root, 10, 0); + lv_obj_set_style_pad_bottom(upper, 10, 0); + lv_obj_set_style_pad_column(upper, 10, 0); +} + +static void create_button(lv_obj_t* parent, lv_event_cb_t on_click, const char* text) +{ + lv_obj_t* btn = lv_btn_create(parent); + lv_obj_set_width(btn, LV_PCT(100)); + lv_obj_set_flex_grow(btn, 1); + lv_obj_add_event_cb(btn, on_click, LV_EVENT_CLICKED, NULL); + + lv_obj_t* label = lv_label_create(btn); + lv_obj_center(label); + lv_label_set_text(label, text); +} + +void move_panel_slider_init(lv_obj_t* panel) +{ + lv_obj_t * sub_panel = lv_create_empty_panel(panel); + lv_obj_set_size(sub_panel, LV_PCT(100), LV_PCT(100)); + + lv_layout_flex_row(sub_panel); + + lv_obj_t* left = lv_create_empty_panel(sub_panel); + lv_layout_flex_column(left); + lv_obj_set_flex_grow(left, 1); + lv_obj_set_height(left, LV_PCT(100)); + + float* position_min = get_current_printer_data()->position_min; + float* position_max = get_current_printer_data()->position_max; + + make_horizontal_slider(left, "X", x_pos_update, x_slider_update, x_line_custom, position_min[0], position_max[0]); + make_vertical_slider(sub_panel, "Y", y_pos_update, y_slider_update, y_line_custom, position_min[1], position_max[1]); + make_vertical_slider(sub_panel, "Z", z_pos_update, z_slider_update, z_line_custom, position_min[2], position_max[2]); + + create_button(left, home_button_click, LV_SYMBOL_HOME " Home XYZ"); + create_button(left, disable_steppers_button_click, LV_SYMBOL_EYE_CLOSE " Free Motors"); + create_button(left, switch_to_params_panel_button_click, LV_SYMBOL_SETTINGS " Parameters"); + + lv_obj_set_style_pad_right(left, 10, 0); + lv_obj_set_style_pad_all(panel, 10, 0); +} \ 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 9e97c49..73640ff 100644 --- a/CYD-Klipper/src/ui/panels/panel.h +++ b/CYD-Klipper/src/ui/panels/panel.h @@ -12,5 +12,6 @@ void stats_panel_init(lv_obj_t* panel); void printer_panel_init(lv_obj_t* panel); void error_panel_init(lv_obj_t* panel); void connecting_panel_init(lv_obj_t* panel); +void move_panel_slider_init(lv_obj_t* panel); void settings_section_device(lv_obj_t* panel); \ No newline at end of file