#include "lvgl.h" #include "panel.h" #include "../../core/data_setup.h" #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); } 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); } 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); } 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); } 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}; static void home_button_click(lv_event_t * e) { if (printer.state == PRINTER_STATE_PRINTING) return; send_gcode(false, "G28"); } static void disable_steppers_click(lv_event_t * e) { if (printer.state == PRINTER_STATE_PRINTING) return; send_gcode(true, "M18"); } static void switch_to_stat_panel(lv_event_t * e) { lv_obj_t * panel = lv_event_get_target(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; lv_obj_t * panel = lv_create_empty_panel(root_panel); lv_obj_set_size(panel, CYD_SCREEN_PANEL_WIDTH_PX, CYD_SCREEN_PANEL_HEIGHT_PX); lv_obj_set_style_pad_all(panel, CYD_SCREEN_GAP_PX, 0); lv_layout_flex_column(panel, LV_FLEX_ALIGN_SPACE_BETWEEN, 0, 0); lv_obj_t * home_button_row = lv_create_empty_panel(panel); lv_obj_set_size(home_button_row, width, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX); lv_layout_flex_row(home_button_row); lv_obj_t * btn = lv_btn_create(home_button_row); lv_obj_set_height(btn, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX); lv_obj_add_event_cb(btn, home_button_click, LV_EVENT_CLICKED, NULL); lv_obj_set_flex_grow(btn, 1); lv_obj_t * label = lv_label_create(btn); lv_label_set_text(label, LV_SYMBOL_HOME "Home"); lv_obj_center(label); btn = lv_btn_create(home_button_row); lv_obj_set_height(btn, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX); lv_obj_add_event_cb(btn, disable_steppers_click, LV_EVENT_CLICKED, NULL); lv_obj_set_flex_grow(btn, 1); label = lv_label_create(btn); lv_label_set_text(label, LV_SYMBOL_EYE_CLOSE "Free"); lv_obj_center(label); btn = lv_btn_create(home_button_row); lv_obj_set_height(btn, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX); lv_obj_add_event_cb(btn, switch_to_stat_panel, LV_EVENT_CLICKED, NULL); lv_obj_set_flex_grow(btn, 1); label = lv_label_create(btn); 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_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); lv_msg_subsribe_obj(DATA_PRINTER_DATA, label, NULL); lv_obj_t * row_panel = lv_create_empty_panel(panel); lv_obj_set_size(row_panel, width, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX); lv_layout_flex_row(row_panel); for (int col = 0; col < 6; col++) { btn = lv_btn_create(row_panel); lv_obj_set_height(btn, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX); lv_obj_add_event_cb(btn, button_callbacks[row], LV_EVENT_CLICKED, (void*)(offsets[row] + col)); lv_obj_set_flex_grow(btn, 1); label = lv_label_create(btn); lv_label_set_text(label, labels[row] + OFFSET_LABEL_SIZE * col); lv_obj_center(label); } } } inline void root_panel_steppers_unlocked(lv_obj_t * root_panel){ lv_obj_t * panel = lv_create_empty_panel(root_panel); lv_obj_set_size(panel, CYD_SCREEN_PANEL_WIDTH_PX, CYD_SCREEN_PANEL_HEIGHT_PX); lv_obj_set_style_pad_all(panel, CYD_SCREEN_GAP_PX, 0); lv_layout_flex_column(panel, LV_FLEX_ALIGN_CENTER); lv_obj_t * label = lv_label_create(panel); lv_label_set_text(label, LV_SYMBOL_EYE_CLOSE " Steppers unlocked"); lv_obj_t * btn = lv_btn_create(panel); lv_obj_set_height(btn, CYD_SCREEN_MIN_BUTTON_HEIGHT_PX); lv_obj_add_event_cb(btn, home_button_click, LV_EVENT_CLICKED, NULL); label = lv_label_create(btn); lv_label_set_text(label, LV_SYMBOL_HOME "Home Axis"); lv_obj_center(label); } static void root_panel_state_update(lv_event_t * e){ if (last_homing_state == printer.homed_axis) return; lv_obj_t * panel = lv_event_get_target(e); last_homing_state = printer.homed_axis; lv_obj_clean(panel); if (printer.homed_axis) root_panel_steppers_locked(panel); else root_panel_steppers_unlocked(panel); } void move_panel_init(lv_obj_t* panel){ if (printer.state == PRINTER_STATE_PRINTING){ stats_panel_init(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); lv_msg_subsribe_obj(DATA_PRINTER_DATA, panel, NULL); }