save on exit message, * symbol on unsaved docs, saved status on history
This commit is contained in:
@@ -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()
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,7 +479,11 @@ 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);
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user