diff --git a/src/app.h b/src/app.h index 528cf1c..de4df43 100644 --- a/src/app.h +++ b/src/app.h @@ -155,7 +155,7 @@ public: bool key_char(char key); void toggle_ui(); void set_stylus(); - void message_box(const std::string& title, const std::string& text); + NodeMessageBox* message_box(const std::string& title, const std::string& text, bool cancel_button = false); void rec_clear(); void rec_loop(); diff --git a/src/app_dialogs.cpp b/src/app_dialogs.cpp index f6bbd1c..62d00c1 100644 --- a/src/app_dialogs.cpp +++ b/src/app_dialogs.cpp @@ -22,17 +22,19 @@ std::shared_ptr App::show_progress(const std::string& title) return pb; } -void App::message_box(const std::string &title, const std::string& text) +NodeMessageBox* App::message_box(const std::string &title, const std::string& text, bool cancel_button) { async_start(); auto* m = layout[main_id]->add_child(); m->m_title->set_text(title.c_str()); m->m_message->set_text(text.c_str()); m->btn_ok->m_text->set_text("Ok"); - m->btn_cancel->destroy(); + if (!cancel_button) + m->btn_cancel->destroy(); layout[main_id]->update(); async_redraw(); async_end(); + return m; } void App::dialog_usermanual() diff --git a/src/main.cpp b/src/main.cpp index 28260c3..6e95ba2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -73,7 +73,6 @@ void destroy_window() main_tasklist.emplace_back([=] { SendMessage(hWnd, WM_USER_CLOSE, 0, 0); }); - SendMessage(hWnd, WM_USER_CLOSE, 0, 0); } void async_lock() @@ -826,6 +825,7 @@ int main(int argc, char** argv) LOG("hmd renderer terminated"); }); + SetTimer(hWnd, 1, 500, NULL); MSG msg; LOG("start main loop"); diff --git a/src/node_canvas.cpp b/src/node_canvas.cpp index e2f0de2..2e8a691 100644 --- a/src/node_canvas.cpp +++ b/src/node_canvas.cpp @@ -464,7 +464,9 @@ kEventResult NodeCanvas::handle_event(Event* e) App::I.show_cursor(); break; case kEventType::MouseFocus: - App::I.hide_cursor(); + m_canvas->m_current_mode == kCanvasMode::Draw || + m_canvas->m_current_mode == kCanvasMode::Erase ? + App::I.hide_cursor() : App::I.show_cursor(); break; case kEventType::KeyDown: if (ke->m_key == kKey::KeyE) @@ -472,9 +474,14 @@ kEventResult NodeCanvas::handle_event(Event* e) if (ke->m_key == kKey::AndroidBack) if (!ActionManager::empty()) ActionManager::undo(); - + if (ke->m_key == kKey::KeyAlt) + App::I.show_cursor(); break; case kEventType::KeyUp: + if (ke->m_key == kKey::KeyAlt) + m_canvas->m_current_mode == kCanvasMode::Draw || + m_canvas->m_current_mode == kCanvasMode::Erase ? + App::I.hide_cursor() : App::I.show_cursor(); if (ke->m_key == kKey::KeyE) Canvas::set_mode(kCanvasMode::Draw); if (ke->m_key == kKey::KeyTab) diff --git a/src/node_panel_brush.cpp b/src/node_panel_brush.cpp index dfa2b0a..c003f84 100644 --- a/src/node_panel_brush.cpp +++ b/src/node_panel_brush.cpp @@ -429,7 +429,17 @@ void NodePanelBrushPreset::init() save(); }; - restore(); + if (Asset::exist(App::I.data_path + "/settings/presets.bin") && !restore()) + { + auto mb = App::I.message_box("Presets", "Could not read brush presets file, it will be deleted.", true); + mb->btn_ok->on_click = [mb](Node*) { + Asset::delete_file(App::I.data_path + "/settings/presets.bin"); + mb->destroy(); + }; + mb->btn_cancel->on_click = [mb](Node*) { + mb->destroy(); + }; + } } kEventResult NodePanelBrushPreset::handle_event(Event* e) @@ -476,12 +486,14 @@ bool NodePanelBrushPreset::save() { BinaryStreamWriter sw; sw.init(); + sw.wstring_raw("PPVR"); + sw.wu16(0); + sw.wu16(1); sw.wu32(m_container->m_children.size()); for (int ci = 0; ci < m_container->m_children.size(); ci++) { auto bpi = static_cast(m_container->get_child_at(ci)); auto& b = bpi->m_brush; - sw << *b; } fwrite(sw.m_data.data(), sw.m_data.size(), 1, fp); @@ -501,15 +513,37 @@ bool NodePanelBrushPreset::restore() fseek(fp, 0, SEEK_SET); std::vector data(sz); fread(data.data(), 1, sz, fp); + BinaryStreamReader sr; sr.init(data.data(), sz); + // sanity checks + if (sr.rstring(4) != "PPVR") + { + LOG("PPVR tag not found") + fclose(fp); + return false; + } + auto vmaj = sr.ru16(); + auto vmin = sr.ru16(); + if (vmaj != 0 && vmin != 1) + { + LOG("unrecognised version %d.$d", vmaj, vmin); + fclose(fp); + return false; + } + auto count = sr.ru32(); for (int k = 0; k < count; k++) { auto b = std::make_shared(); - sr >> *b; + if (!b->read(sr)) + { + LOG("error deserializing the brush"); + fclose(fp); + return false; + } if (b->valid()) {