#include "pch.h" #include "log.h" #include "node_dialog_cloud.h" #include "canvas.h" #include "node_image_texture.h" #include "asset.h" #include "node_message_box.h" #include "app.h" #include "image.h" Node* NodeDialogCloud::clone_instantiate() const { return new NodeDialogCloud(); } void NodeDialogCloud::clone_finalize(Node* dest) const { NodeDialogCloud* n = static_cast(dest); n->init_controls(); } void NodeDialogCloud::init() { init_template_file("data/dialogs/cloud-browse.xml", "dialog-cloud"); init_controls(); } void NodeDialogCloud::init_controls() { btn_ok = find("btn-ok"); btn_cancel = find("btn-cancel"); btn_cancel->on_click = [this](Node*) { destroy(); }; container = find("files-list"); std::thread(&NodeDialogCloud::load_thumbs_thread, this).detach(); } void NodeDialogCloud::loaded() { } void NodeDialogCloud::removed(Node* parent) { NodeBorder::removed(parent); closed = true; } void NodeDialogCloud::load_thumbs_thread() { #if WITH_CURL BT_SetTerminate(); CURL *curl = curl_easy_init(); std::string res; if (curl) { auto* align = container->add_child(); align->SetWidthP(100.f); align->SetHeightP(100.f); align->SetAlign(YGAlignCenter); align->SetJustify(YGJustifyCenter); auto* text = align->add_child(); text->set_font_size(30); text->set_text("Connecting to the server..."); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &res); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_data_handler); curl_easy_setopt(curl, CURLOPT_URL, "https://panopainter.com/cloud/cloud-list.php"); #ifdef __ANDROID__ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); #endif auto err = curl_easy_perform(curl); if (err != CURLE_OK) { LOG("connection error: %d", err); text->set_text("Could not connect to the server"); return; } align->destroy(); LOG("CLOUD LIST: %s", res.c_str()); auto names = split(res, ','); std::vector nodes; // create slots with name for (const auto& n : names) { auto node = new NodeDialogCloudItem; node->set_manager(m_manager); node->init(); node->m_text->set_text(n.c_str()); node->m_path = App::I->work_path + "/" + n; node->m_file_name = n; container->add_child(node); node->on_selected = [&](NodeDialogCloudItem* target) { if (target == current) return; selected_path = target->m_path; selected_file = target->m_file_name; selected_name = selected_file.substr(0, selected_file.length() - strlen(".ppi")); if (current) current->m_selected = false; current = target; }; nodes.push_back(node); } // load the icons for (int i = 0; i < names.size(); i++) { const auto& n = names[i]; auto* node = nodes[i]; if (closed) break; res.clear(); char* url_escaped = curl_easy_escape(curl, n.c_str(), (int)n.size()); std::string url = std::string("https://panopainter.com/cloud/cloud-info.php?file=") + url_escaped; delete url_escaped; curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); LOG("%s", url.c_str()); auto err = curl_easy_perform(curl); if (err != CURLE_OK) break; // TODO: handle this error with a message or something auto info = split(res, ',', 3); int width = atoi(info[0].c_str()); int height = atoi(info[1].c_str()); int comp = atoi(info[2].c_str()); assert(comp == 4); std::string rgb; rgb.resize(Base64::DecodedLength(info[3])); Base64::Decode(info[3], &rgb); Image thumb; thumb.create(width, height); thumb.copy_from((uint8_t*)rgb.data()); auto image_tex = node->find("thumb-tex"); image_tex->tex = std::make_shared(); image_tex->tex->create(thumb); app_redraw(); } curl_easy_cleanup(curl); } #endif //CURL } ////////////////////////////////////////////////////////////////// Node* NodeDialogCloudItem::clone_instantiate() const { return new NodeDialogCloudItem; } void NodeDialogCloudItem::clone_finalize(Node* dest) const { NodeDialogCloudItem* n = static_cast(dest); n->init_controls(); } void NodeDialogCloudItem::init() { init_template_file("data/dialogs/cloud-browse.xml", "dialog-cloud-item"); init_controls(); } void NodeDialogCloudItem::init_controls() { m_text = find("title"); } void NodeDialogCloudItem::loaded() { } void NodeDialogCloudItem::draw() { auto c = m_selected ? m_color_selected : m_color_normal; m_thinkness = m_selected ? 1.f : 0.f; m_color = m_mouse_inside ? m_color_hover : c; NodeBorder::draw(); } kEventResult NodeDialogCloudItem::handle_event(Event* e) { NodeBorder::handle_event(e); switch (e->m_type) { case kEventType::MouseEnter: break; case kEventType::MouseLeave: break; case kEventType::MouseDownL: m_selected = true; if (on_selected) on_selected(this); break; case kEventType::MouseUpL: break; default: return kEventResult::Available; break; } return kEventResult::Consumed; }