save on exit message, * symbol on unsaved docs, saved status on history

This commit is contained in:
2018-07-31 17:25:50 +02:00
parent 5a37f578cb
commit 1a7677a727
10 changed files with 43 additions and 21 deletions

View File

@@ -20,12 +20,15 @@ void ActionManager::undo()
return; return;
I.m_redos.emplace(I.m_actions.top()->get_redo()); I.m_redos.emplace(I.m_actions.top()->get_redo());
I.m_redos.top()->was_saved = !ui::Canvas::I->m_unsaved;
I.m_actions.top()->undo(); I.m_actions.top()->undo();
I.m_memory -= I.m_actions.top()->memory(); I.m_memory -= I.m_actions.top()->memory();
ui::Canvas::I->m_unsaved = !I.m_actions.top()->was_saved;
I.m_actions.pop(); I.m_actions.pop();
//LOG("History: %.2f KB", I.m_memory / 1024.f); //LOG("History: %.2f KB", I.m_memory / 1024.f);
App::I.update_memory_usage(I.m_memory); App::I.update_memory_usage(I.m_memory);
App::I.title_update();
} }
void ActionManager::redo() void ActionManager::redo()
@@ -34,12 +37,15 @@ void ActionManager::redo()
return; return;
I.m_actions.emplace(I.m_redos.top()->get_redo()); I.m_actions.emplace(I.m_redos.top()->get_redo());
I.m_actions.top()->was_saved = !ui::Canvas::I->m_unsaved;
I.m_memory += I.m_actions.top()->memory(); I.m_memory += I.m_actions.top()->memory();
I.m_redos.top()->undo(); I.m_redos.top()->undo();
ui::Canvas::I->m_unsaved = !I.m_redos.top()->was_saved;
I.m_redos.pop(); I.m_redos.pop();
//LOG("History: %.2f KB", I.m_memory / 1024.f); //LOG("History: %.2f KB", I.m_memory / 1024.f);
App::I.update_memory_usage(I.m_memory); App::I.update_memory_usage(I.m_memory);
App::I.title_update();
} }
void ActionManager::clear() void ActionManager::clear()

View File

@@ -3,6 +3,7 @@
class Action class Action
{ {
public: public:
bool was_saved = false;
virtual void run() = 0; virtual void run() = 0;
virtual void undo() = 0; virtual void undo() = 0;
virtual Action* get_redo() = 0; virtual Action* get_redo() = 0;

View File

@@ -40,21 +40,23 @@ bool App::request_close()
async_start(); async_start();
auto* m = layout[main_id]->add_child<NodeMessageBox>(); auto* m = layout[main_id]->add_child<NodeMessageBox>();
m->m_title->set_text("Unsaved document"); m->m_title->set_text("Unsaved document");
m->m_message->set_text("Would you like to save before closing?"); m->m_message->set_text("Do you want to close without saving?");
m->btn_ok->m_text->set_text("Yes"); m->btn_ok->m_text->set_text("Yes");
m->btn_ok->on_click = [](Node*) { m->btn_ok->on_click = [](Node*) {
}; #ifdef _WIN32
m->btn_cancel->m_text->set_text("No");
m->btn_cancel->on_click = [this](Node*) {
#ifdef _WIN32
destroy_window(); destroy_window();
PostQuitMessage(0); PostQuitMessage(0);
#endif #endif
#ifdef __OSX__ #ifdef __OSX__
[osx_view close]; [osx_view close];
#endif #endif
ui::Canvas::I->m_unsaved = false; ui::Canvas::I->m_unsaved = false;
}; };
m->btn_cancel->m_text->set_text("No");
m->btn_cancel->on_click = [this,m](Node*) {
m->destroy();
dialog_already_opened = false;
};
async_redraw(); async_redraw();
async_end(); async_end();
dialog_already_opened = true; dialog_already_opened = true;
@@ -267,7 +269,7 @@ void App::init()
initShaders(); initShaders();
initAssets(); initAssets();
initLayout(); initLayout();
title_update();
GLfloat width_range[2]; GLfloat width_range[2];
glGetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, width_range); glGetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, width_range);

View File

@@ -64,7 +64,7 @@ public:
Node* current_panel = nullptr; Node* current_panel = nullptr;
NodeScroll* panels; NodeScroll* panels;
const uint16_t main_id = const_hash("main"); const uint16_t main_id = const_hash("main");
std::string doc_name; std::string doc_name = "no-name";
float width; float width;
float height; float height;
bool keys[256]; bool keys[256];
@@ -155,7 +155,7 @@ public:
std::shared_ptr<NodeProgressBar> show_progress(const std::string& title); std::shared_ptr<NodeProgressBar> show_progress(const std::string& title);
void brush_update(); void brush_update();
void title_update(std::string name, int resolution); void title_update();
void update_memory_usage(size_t bytes); void update_memory_usage(size_t bytes);
void update_rec_frames(); void update_rec_frames();

View File

@@ -146,7 +146,7 @@ void App::cloud_browse()
async_start(); async_start();
doc_name = dialog->selected_name; doc_name = dialog->selected_name;
title_update(doc_name, canvas->m_canvas->m_width); title_update();
for (auto& i : canvas->m_canvas->m_order) for (auto& i : canvas->m_canvas->m_order)
layers->add_layer(canvas->m_canvas->m_layers[i].m_name.c_str()); layers->add_layer(canvas->m_canvas->m_layers[i].m_name.c_str());
ActionManager::clear(); ActionManager::clear();

View File

@@ -42,7 +42,7 @@ void App::dialog_newdoc()
std::array<int, 4> resolutions{512, 1024, 1536, 2048}; std::array<int, 4> resolutions{512, 1024, 1536, 2048};
int res = resolutions[dialog->m_resolution->m_current_index]; int res = resolutions[dialog->m_resolution->m_current_index];
doc_name = name; doc_name = name;
title_update(name, res); title_update();
layers->clear(); layers->clear();
canvas->m_canvas->m_layers.clear(); canvas->m_canvas->m_layers.clear();
@@ -109,7 +109,7 @@ void App::dialog_open()
canvas->m_canvas->project_open(dialog->selected_path, [this] { canvas->m_canvas->project_open(dialog->selected_path, [this] {
// on complete // on complete
async_start(); async_start();
title_update(doc_name, canvas->m_canvas->m_width); title_update();
for (auto& i : canvas->m_canvas->m_order) for (auto& i : canvas->m_canvas->m_order)
layers->add_layer(canvas->m_canvas->m_layers[i].m_name.c_str()); layers->add_layer(canvas->m_canvas->m_layers[i].m_name.c_str());
async_end(); async_end();
@@ -143,7 +143,7 @@ void App::dialog_browse()
canvas->m_canvas->project_open(dialog->selected_path, [this] { canvas->m_canvas->project_open(dialog->selected_path, [this] {
// on complete // on complete
async_start(); async_start();
title_update(doc_name, canvas->m_canvas->m_width); title_update();
for (auto& i : canvas->m_canvas->m_order) for (auto& i : canvas->m_canvas->m_order)
layers->add_layer(canvas->m_canvas->m_layers[i].m_name.c_str()); layers->add_layer(canvas->m_canvas->m_layers[i].m_name.c_str());
async_end(); async_end();
@@ -179,7 +179,7 @@ void App::dialog_save_ver()
} }
doc_name = next; doc_name = next;
title_update(doc_name, canvas->m_canvas->m_width); title_update();
canvas->m_canvas->project_save(data_path + "/" + next + ".pano"); canvas->m_canvas->project_save(data_path + "/" + next + ".pano");
} }
@@ -214,7 +214,7 @@ void App::dialog_save()
auto action = [this, dialog, name, path] { auto action = [this, dialog, name, path] {
doc_name = name; doc_name = name;
title_update(doc_name, canvas->m_canvas->m_width); title_update();
canvas->m_canvas->project_save(path); canvas->m_canvas->project_save(path);
dialog->destroy(); dialog->destroy();
App::I.hideKeyboard(); App::I.hideKeyboard();

View File

@@ -11,10 +11,10 @@ using namespace ui;
static glm::vec4 color_button_normal{ .1, .1, .1, 1 }; static glm::vec4 color_button_normal{ .1, .1, .1, 1 };
static glm::vec4 color_button_hlight{ 1, .0, .0, 1 }; static glm::vec4 color_button_hlight{ 1, .0, .0, 1 };
void App::title_update(std::string name, int resolution) void App::title_update()
{ {
static char str[256]; static char str[256];
snprintf(str, 256, "Panodoc: %s%s (%dpx)", doc_name.c_str(), canvas->m_canvas->m_unsaved ? "*" : "", resolution); snprintf(str, 256, "Panodoc: %s%s (%dpx)", doc_name.c_str(), canvas->m_canvas->m_unsaved ? "*" : "", canvas->m_canvas->m_width);
if (auto docname = layout[main_id]->find<NodeText>("txt-docname")) if (auto docname = layout[main_id]->find<NodeText>("txt-docname"))
docname->set_text(str); docname->set_text(str);
} }

View File

@@ -135,10 +135,13 @@ void ui::Canvas::clear(const glm::vec4& c/*={0,0,0,1}*/)
{ {
snap_history({ 0, 1, 2, 3, 4, 5 }); snap_history({ 0, 1, 2, 3, 4, 5 });
m_layers[m_current_layer_idx].clear(c); m_layers[m_current_layer_idx].clear(c);
m_unsaved = true;
App::I.title_update();
} }
void ui::Canvas::snap_history(const std::vector<int>& planes) void ui::Canvas::snap_history(const std::vector<int>& planes)
{ {
auto action = new ActionStroke; auto action = new ActionStroke;
action->was_saved = !m_unsaved;
for (auto i : planes) for (auto i : planes)
{ {
if (!m_layers[m_current_layer_idx].m_dirty_face[i]) if (!m_layers[m_current_layer_idx].m_dirty_face[i])
@@ -462,7 +465,7 @@ void ui::Canvas::stroke_commit()
{ {
if (!m_dirty || m_layers.empty()) if (!m_dirty || m_layers.empty())
return; return;
m_unsaved = true;
m_dirty = false; m_dirty = false;
m_dirty_stroke = true; // new stroke ready for timelapse capture m_dirty_stroke = true; // new stroke ready for timelapse capture
App::I.redraw = true; App::I.redraw = true;
@@ -476,6 +479,10 @@ void ui::Canvas::stroke_commit()
// allocate action to add to history // allocate action to add to history
auto action = new ActionStroke; auto action = new ActionStroke;
action->was_saved = !m_unsaved;
m_unsaved = true;
App::I.title_update();
// prepare common states // prepare common states
glViewport(0, 0, m_width, m_height); glViewport(0, 0, m_width, m_height);
@@ -854,6 +861,7 @@ void ui::Canvas::import_equirectangular_thread(std::string file_path)
gl_state gl; gl_state gl;
gl.save(); gl.save();
snap_history({0,1,2,3,4,5}); snap_history({0,1,2,3,4,5});
m_unsaved = true;
Image img; Image img;
img.load_file(file_path); img.load_file(file_path);

View File

@@ -671,6 +671,10 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
break; break;
} }
} }
// avoid annoying alt system menu
if (wp == SC_KEYMENU && (lp >> 16) <= 0) return 0;
return DefWindowProc(hWnd, msg, wp, lp); return DefWindowProc(hWnd, msg, wp, lp);
} }

View File

@@ -13,6 +13,7 @@ void NodeCanvas::init()
m_mouse_ignore = false; m_mouse_ignore = false;
m_canvas = std::make_unique<ui::Canvas>(); m_canvas = std::make_unique<ui::Canvas>();
m_canvas->create(CANVAS_RES, CANVAS_RES); m_canvas->create(CANVAS_RES, CANVAS_RES);
m_canvas->m_unsaved = false;
m_sampler.create(GL_NEAREST); m_sampler.create(GL_NEAREST);
m_sampler_linear.create(GL_LINEAR); m_sampler_linear.create(GL_LINEAR);
m_sampler_stencil.create(GL_LINEAR, GL_REPEAT); m_sampler_stencil.create(GL_LINEAR, GL_REPEAT);