diff --git a/CYD-Klipper-Display/.vscode/settings.json b/CYD-Klipper-Display/.vscode/settings.json new file mode 100644 index 0000000..03d5353 --- /dev/null +++ b/CYD-Klipper-Display/.vscode/settings.json @@ -0,0 +1,13 @@ +{ + "files.associations": { + "array": "cpp", + "deque": "cpp", + "list": "cpp", + "string": "cpp", + "unordered_map": "cpp", + "unordered_set": "cpp", + "vector": "cpp", + "string_view": "cpp", + "initializer_list": "cpp" + } +} \ No newline at end of file diff --git a/CYD-Klipper-Display/src/core/files_query.cpp b/CYD-Klipper-Display/src/core/files_query.cpp new file mode 100644 index 0000000..28abbb5 --- /dev/null +++ b/CYD-Klipper-Display/src/core/files_query.cpp @@ -0,0 +1,63 @@ +#include +#include "files_query.h" +#include "../conf/global_config.h" +#include +#include +#include + +// Always has +1 entry with a null'd name +FILESYSTEM_FILE* last_query = NULL; + +FILESYSTEM_FILE* get_files(){ + if (last_query != NULL){ + FILESYSTEM_FILE* current = last_query; + + while (current->name != NULL){ + free(current->name); + current += 1; + } + + free(last_query); + } + + std::list files; + char buff[256] = {}; + sprintf(buff, "http://%s:%d/server/files/list", global_config.klipperHost, global_config.klipperPort); + HTTPClient client; + client.begin(buff); + int httpCode = client.GET(); + int count = 0; + if (httpCode == 200){ + String payload = client.getString(); + DynamicJsonDocument doc(60000); + auto a = deserializeJson(doc, payload); + Serial.printf("JSON PARSE: %s\n", a.c_str()); + auto result = doc["result"].as(); + for (auto file : result){ + FILESYSTEM_FILE f = {0}; + const char* path = file["path"]; + f.name = (char*)malloc(strlen(path) + 1); + strcpy(f.name, path); + f.modified = file["modified"]; + files.push_back(f); + count++; + } + } + + //Serial.printf("Found %d files\n", count); + files.sort([](FILESYSTEM_FILE a, FILESYSTEM_FILE b){return a.modified < b.modified;}); + files.reverse(); // TODO: Reverse is unneeded here, we can iterate backwards + + size_t size = sizeof(FILESYSTEM_FILE) * (files.size() + 1); + FILESYSTEM_FILE* result = (FILESYSTEM_FILE*)malloc(size); + //Serial.printf("Allocated %d bytes\n", size); + last_query = result; + result[files.size()].name = NULL; + + for (auto file : files){ + *result = file; + result += 1; + } + + return last_query; +} \ No newline at end of file diff --git a/CYD-Klipper-Display/src/core/files_query.h b/CYD-Klipper-Display/src/core/files_query.h new file mode 100644 index 0000000..a5c6cbc --- /dev/null +++ b/CYD-Klipper-Display/src/core/files_query.h @@ -0,0 +1,22 @@ +/* +At some point it may be a fun challenge to try to implement a virtual folder structure, but not today. + +typedef struct _FILESYSTEM_FILE { + char* name; + char* parent_folder_name; + long level; +} FILESYSTEM_FILE; + +typedef struct _FILESYSTEM_FOLDER { + char** files; + char* folder_path; + FILESYSTEM_FOLDER* folders; +} FILESYSTEM_FOLDER; +*/ + +typedef struct _FILESYSTEM_FILE { + char* name; + float modified; +} FILESYSTEM_FILE; + +FILESYSTEM_FILE* get_files(); \ No newline at end of file diff --git a/CYD-Klipper-Display/src/ui/panels/print_panel.cpp b/CYD-Klipper-Display/src/ui/panels/print_panel.cpp index e03b5ea..a90137c 100644 --- a/CYD-Klipper-Display/src/ui/panels/print_panel.cpp +++ b/CYD-Klipper-Display/src/ui/panels/print_panel.cpp @@ -1,10 +1,88 @@ #include "lvgl.h" #include "panel.h" #include "../../core/data_setup.h" +#include "../../core/files_query.h" +#include "../../conf/global_config.h" +#include +#include + +FILESYSTEM_FILE* selected_file = NULL; + +static void btn_print_file(lv_event_t * e){ + lv_obj_t * panel = (lv_obj_t*)lv_event_get_user_data(e); + lv_obj_del(panel); + + char* buff = (char*)malloc(128 + strlen(selected_file->name)); + sprintf(buff, "http://%s:%d/printer/print/start?filename=%s", global_config.klipperHost, global_config.klipperPort, selected_file->name); + HTTPClient client; + client.begin(buff); + int httpCode = client.POST(""); + Serial.printf("Print start: HTTP %d\n", httpCode); +} + +static void btn_print_back(lv_event_t * e){ + lv_obj_t * panel = (lv_obj_t*)lv_event_get_user_data(e); + lv_obj_del(panel); +} + +static void btn_print_file_verify(lv_event_t * e){ + lv_obj_t * btn = lv_event_get_target(e); + selected_file = (FILESYSTEM_FILE*)lv_event_get_user_data(e); + + lv_obj_t * panel = lv_obj_create(lv_scr_act()); + lv_obj_set_size(panel, TFT_HEIGHT - 40, TFT_WIDTH - 30); + lv_obj_align(panel, LV_ALIGN_CENTER, 0, 0); + + lv_obj_t * label = lv_label_create(panel); + lv_label_set_text(label, "Print File"); + lv_obj_align(label, LV_ALIGN_TOP_LEFT, 0, 0); + + label = lv_label_create(panel); + lv_label_set_text(label, selected_file->name); + lv_obj_align(label, LV_ALIGN_CENTER, 0, -20); + lv_obj_set_width(label, TFT_HEIGHT - 90); + lv_label_set_long_mode(label, LV_LABEL_LONG_WRAP); + + btn = lv_btn_create(panel); + lv_obj_align(btn, LV_ALIGN_BOTTOM_LEFT, 10, -10); + lv_obj_set_size(btn, 40, 40); + lv_obj_add_event_cb(btn, btn_print_back, LV_EVENT_CLICKED, panel); + + label = lv_label_create(btn); + lv_label_set_text(label, LV_SYMBOL_CLOSE); + lv_obj_center(label); + + btn = lv_btn_create(panel); + lv_obj_align(btn, LV_ALIGN_BOTTOM_RIGHT, -10, -10); + lv_obj_set_size(btn, 40, 40); + lv_obj_add_event_cb(btn, btn_print_file, LV_EVENT_CLICKED, panel); + + label = lv_label_create(btn); + lv_label_set_text(label, LV_SYMBOL_OK); + lv_obj_center(label); +} void print_panel_init(lv_obj_t* panel){ if (printer.state == PRINTER_STATE_PRINTING || printer.state == PRINTER_STATE_PAUSED){ progress_panel_init(panel); return; } + + auto panel_width = TFT_HEIGHT - 40; + auto panel_height_margin = TFT_WIDTH - 10; + auto panel_width_margin = panel_width - 10; + + lv_obj_t * list = lv_list_create(panel); + lv_obj_set_size(list, panel_width_margin, panel_height_margin); + lv_obj_align(list, LV_ALIGN_CENTER, 0, 0); + + FILESYSTEM_FILE* files = get_files(); + int count = 0; + while (files->name != NULL && count <= 20){ + lv_obj_t * btn = lv_list_add_btn(list, LV_SYMBOL_FILE, files->name); + lv_obj_add_event_cb(btn, btn_print_file_verify, LV_EVENT_CLICKED, (void*)files); + + files += 1; + count++; + } } \ No newline at end of file