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;
|
||||
|
||||
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_memory -= I.m_actions.top()->memory();
|
||||
ui::Canvas::I->m_unsaved = !I.m_actions.top()->was_saved;
|
||||
I.m_actions.pop();
|
||||
//LOG("History: %.2f KB", I.m_memory / 1024.f);
|
||||
App::I.update_memory_usage(I.m_memory);
|
||||
App::I.title_update();
|
||||
}
|
||||
|
||||
void ActionManager::redo()
|
||||
@@ -34,12 +37,15 @@ void ActionManager::redo()
|
||||
return;
|
||||
|
||||
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_redos.top()->undo();
|
||||
ui::Canvas::I->m_unsaved = !I.m_redos.top()->was_saved;
|
||||
I.m_redos.pop();
|
||||
//LOG("History: %.2f KB", I.m_memory / 1024.f);
|
||||
App::I.update_memory_usage(I.m_memory);
|
||||
App::I.title_update();
|
||||
}
|
||||
|
||||
void ActionManager::clear()
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
class Action
|
||||
{
|
||||
public:
|
||||
bool was_saved = false;
|
||||
virtual void run() = 0;
|
||||
virtual void undo() = 0;
|
||||
virtual Action* get_redo() = 0;
|
||||
|
||||
@@ -40,21 +40,23 @@ bool App::request_close()
|
||||
async_start();
|
||||
auto* m = layout[main_id]->add_child<NodeMessageBox>();
|
||||
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->on_click = [](Node*) {
|
||||
};
|
||||
m->btn_cancel->m_text->set_text("No");
|
||||
m->btn_cancel->on_click = [this](Node*) {
|
||||
#ifdef _WIN32
|
||||
#ifdef _WIN32
|
||||
destroy_window();
|
||||
PostQuitMessage(0);
|
||||
#endif
|
||||
#ifdef __OSX__
|
||||
#endif
|
||||
#ifdef __OSX__
|
||||
[osx_view close];
|
||||
#endif
|
||||
#endif
|
||||
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_end();
|
||||
dialog_already_opened = true;
|
||||
@@ -267,7 +269,7 @@ void App::init()
|
||||
initShaders();
|
||||
initAssets();
|
||||
initLayout();
|
||||
|
||||
title_update();
|
||||
|
||||
GLfloat width_range[2];
|
||||
glGetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, width_range);
|
||||
|
||||
@@ -64,7 +64,7 @@ public:
|
||||
Node* current_panel = nullptr;
|
||||
NodeScroll* panels;
|
||||
const uint16_t main_id = const_hash("main");
|
||||
std::string doc_name;
|
||||
std::string doc_name = "no-name";
|
||||
float width;
|
||||
float height;
|
||||
bool keys[256];
|
||||
@@ -155,7 +155,7 @@ public:
|
||||
std::shared_ptr<NodeProgressBar> show_progress(const std::string& title);
|
||||
|
||||
void brush_update();
|
||||
void title_update(std::string name, int resolution);
|
||||
void title_update();
|
||||
void update_memory_usage(size_t bytes);
|
||||
void update_rec_frames();
|
||||
|
||||
|
||||
@@ -146,7 +146,7 @@ void App::cloud_browse()
|
||||
|
||||
async_start();
|
||||
doc_name = dialog->selected_name;
|
||||
title_update(doc_name, canvas->m_canvas->m_width);
|
||||
title_update();
|
||||
for (auto& i : canvas->m_canvas->m_order)
|
||||
layers->add_layer(canvas->m_canvas->m_layers[i].m_name.c_str());
|
||||
ActionManager::clear();
|
||||
|
||||
@@ -42,7 +42,7 @@ void App::dialog_newdoc()
|
||||
std::array<int, 4> resolutions{512, 1024, 1536, 2048};
|
||||
int res = resolutions[dialog->m_resolution->m_current_index];
|
||||
doc_name = name;
|
||||
title_update(name, res);
|
||||
title_update();
|
||||
|
||||
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] {
|
||||
// on complete
|
||||
async_start();
|
||||
title_update(doc_name, canvas->m_canvas->m_width);
|
||||
title_update();
|
||||
for (auto& i : canvas->m_canvas->m_order)
|
||||
layers->add_layer(canvas->m_canvas->m_layers[i].m_name.c_str());
|
||||
async_end();
|
||||
@@ -143,7 +143,7 @@ void App::dialog_browse()
|
||||
canvas->m_canvas->project_open(dialog->selected_path, [this] {
|
||||
// on complete
|
||||
async_start();
|
||||
title_update(doc_name, canvas->m_canvas->m_width);
|
||||
title_update();
|
||||
for (auto& i : canvas->m_canvas->m_order)
|
||||
layers->add_layer(canvas->m_canvas->m_layers[i].m_name.c_str());
|
||||
async_end();
|
||||
@@ -179,7 +179,7 @@ void App::dialog_save_ver()
|
||||
}
|
||||
|
||||
doc_name = next;
|
||||
title_update(doc_name, canvas->m_canvas->m_width);
|
||||
title_update();
|
||||
canvas->m_canvas->project_save(data_path + "/" + next + ".pano");
|
||||
}
|
||||
|
||||
@@ -214,7 +214,7 @@ void App::dialog_save()
|
||||
|
||||
auto action = [this, dialog, name, path] {
|
||||
doc_name = name;
|
||||
title_update(doc_name, canvas->m_canvas->m_width);
|
||||
title_update();
|
||||
canvas->m_canvas->project_save(path);
|
||||
dialog->destroy();
|
||||
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_hlight{ 1, .0, .0, 1 };
|
||||
|
||||
void App::title_update(std::string name, int resolution)
|
||||
void App::title_update()
|
||||
{
|
||||
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"))
|
||||
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 });
|
||||
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)
|
||||
{
|
||||
auto action = new ActionStroke;
|
||||
action->was_saved = !m_unsaved;
|
||||
for (auto i : planes)
|
||||
{
|
||||
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())
|
||||
return;
|
||||
m_unsaved = true;
|
||||
|
||||
m_dirty = false;
|
||||
m_dirty_stroke = true; // new stroke ready for timelapse capture
|
||||
App::I.redraw = true;
|
||||
@@ -476,7 +479,11 @@ void ui::Canvas::stroke_commit()
|
||||
|
||||
// allocate action to add to history
|
||||
auto action = new ActionStroke;
|
||||
|
||||
action->was_saved = !m_unsaved;
|
||||
|
||||
m_unsaved = true;
|
||||
App::I.title_update();
|
||||
|
||||
// prepare common states
|
||||
glViewport(0, 0, m_width, m_height);
|
||||
glDisable(GL_BLEND);
|
||||
@@ -854,6 +861,7 @@ void ui::Canvas::import_equirectangular_thread(std::string file_path)
|
||||
gl_state gl;
|
||||
gl.save();
|
||||
snap_history({0,1,2,3,4,5});
|
||||
m_unsaved = true;
|
||||
|
||||
Image img;
|
||||
img.load_file(file_path);
|
||||
|
||||
@@ -671,6 +671,10 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// avoid annoying alt system menu
|
||||
if (wp == SC_KEYMENU && (lp >> 16) <= 0) return 0;
|
||||
|
||||
return DefWindowProc(hWnd, msg, wp, lp);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ void NodeCanvas::init()
|
||||
m_mouse_ignore = false;
|
||||
m_canvas = std::make_unique<ui::Canvas>();
|
||||
m_canvas->create(CANVAS_RES, CANVAS_RES);
|
||||
m_canvas->m_unsaved = false;
|
||||
m_sampler.create(GL_NEAREST);
|
||||
m_sampler_linear.create(GL_LINEAR);
|
||||
m_sampler_stencil.create(GL_LINEAR, GL_REPEAT);
|
||||
|
||||
Reference in New Issue
Block a user