implement document resize with menu and dialog
This commit is contained in:
@@ -152,6 +152,7 @@ public:
|
||||
void dialog_export();
|
||||
void dialog_export_cubes();
|
||||
void dialog_layer_rename();
|
||||
void dialog_resize();
|
||||
|
||||
void cloud_upload();
|
||||
void cloud_upload_all();
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "app.h"
|
||||
#include "node_dialog_open.h"
|
||||
#include "node_dialog_browse.h"
|
||||
#include "node_dialog_resize.h"
|
||||
#include "node_dialog_cloud.h"
|
||||
#include "node_about.h"
|
||||
#include "node_changelog.h"
|
||||
@@ -244,8 +245,11 @@ void App::dialog_browse()
|
||||
|
||||
dialog->btn_ok->on_click = [this, dialog](Node*)
|
||||
{
|
||||
open_document(dialog->selected_path);
|
||||
dialog->destroy();
|
||||
if (dialog->is_selected())
|
||||
{
|
||||
open_document(dialog->selected_path);
|
||||
dialog->destroy();
|
||||
}
|
||||
};
|
||||
async_end();
|
||||
};
|
||||
@@ -389,6 +393,30 @@ void App::dialog_export()
|
||||
}
|
||||
}
|
||||
|
||||
void App::dialog_resize()
|
||||
{
|
||||
auto dialog = std::make_shared<NodeDialogResize>();
|
||||
dialog->m_manager = &layout;
|
||||
dialog->init();
|
||||
dialog->create();
|
||||
dialog->loaded();
|
||||
|
||||
layout[main_id]->add_child(dialog);
|
||||
layout[main_id]->update();
|
||||
|
||||
dialog->btn_ok->on_click = [this,dialog](Node*)
|
||||
{
|
||||
int res = dialog->get_resolution();
|
||||
if (canvas)
|
||||
canvas->m_canvas->resize(res, res);
|
||||
App::I.title_update();
|
||||
dialog->destroy();
|
||||
};
|
||||
|
||||
popup->mouse_release();
|
||||
popup->destroy();
|
||||
}
|
||||
|
||||
void App::dialog_export_cubes()
|
||||
{
|
||||
if (canvas)
|
||||
|
||||
@@ -429,6 +429,12 @@ void App::init_menu_file()
|
||||
dialog_export();
|
||||
popup->mouse_release();
|
||||
popup->destroy();
|
||||
};
|
||||
if (auto b = popup->find<NodeButtonCustom>("file-resize"))
|
||||
b->on_click = [this](Node*) {
|
||||
dialog_resize();
|
||||
popup->mouse_release();
|
||||
popup->destroy();
|
||||
};
|
||||
if (auto b = popup->find<NodeButtonCustom>("file-export-cubes"))
|
||||
b->on_click = [this](Node*) {
|
||||
|
||||
@@ -136,7 +136,11 @@ 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::clear_all()
|
||||
{
|
||||
for (auto& l : m_layers)
|
||||
l.clear({0, 0, 0, 0});
|
||||
}
|
||||
void ui::Canvas::snap_history(const std::vector<int>& planes)
|
||||
{
|
||||
@@ -908,9 +912,9 @@ void ui::Canvas::resize(int width, int height)
|
||||
m_tex2[i].create(width, height, GL_RGBA8);
|
||||
}
|
||||
for (auto& l : m_layers)
|
||||
{
|
||||
l.create(width, height, "");
|
||||
}
|
||||
l.resize(width, height);
|
||||
m_smask.create(width*2, height*2, "mask");
|
||||
m_unsaved = true;
|
||||
}
|
||||
bool ui::Canvas::create(int width, int height)
|
||||
{
|
||||
@@ -1733,12 +1737,13 @@ void ui::Canvas::project_open_thread(std::string file_path)
|
||||
|
||||
int progress = 0;
|
||||
int total = n_layers * 6;
|
||||
|
||||
|
||||
App::I.async_start();
|
||||
for (auto& l : m_layers)
|
||||
l.destroy();
|
||||
m_layers.clear();
|
||||
m_order.clear();
|
||||
//clear_all();
|
||||
resize(m_width, m_height);
|
||||
App::I.async_end();
|
||||
|
||||
@@ -1757,6 +1762,7 @@ void ui::Canvas::project_open_thread(std::string file_path)
|
||||
fread(&name_len, sizeof(int), 1, fp);
|
||||
std::string name(name_len, '\0');
|
||||
fread((char*)name.data(), name_len, 1, fp);
|
||||
snap.clear();
|
||||
for (int plane_index = 0; plane_index < 6; plane_index++)
|
||||
{
|
||||
int has_data;
|
||||
@@ -1802,6 +1808,7 @@ void ui::Canvas::project_open_thread(std::string file_path)
|
||||
tmp_layers.emplace_back();
|
||||
tmp_layers.back().m_opacity = layer_opacity;
|
||||
tmp_layers.back().create(m_width, m_height, name.c_str());
|
||||
tmp_layers.back().clear({0, 0, 0, 0});
|
||||
tmp_layers.back().restore(snap);
|
||||
tmp_order.push_back(n_order);
|
||||
App::I.async_end();
|
||||
@@ -2106,12 +2113,20 @@ void ui::Layer::restore(const Snapshot& snap)
|
||||
m_dirty_box[i] = snap.m_dirty_box[i];
|
||||
m_dirty_face[i] = snap.m_dirty_face[i];
|
||||
|
||||
m_rtt[i].recreate(); // TODO: this should not be recreated here! Sorry I messed up with this, just quick fix DON'T SHIP!!
|
||||
// TODO: this should not be recreated here!
|
||||
// Sorry I messed up with this,
|
||||
// it's just a quick fix DON'T SHIP!!
|
||||
//m_rtt[i].recreate();
|
||||
|
||||
m_rtt[i].bindTexture();
|
||||
glm::vec2 box_sz = zw(m_dirty_box[i]) - xy(m_dirty_box[i]);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, m_dirty_box[i].x, m_dirty_box[i].y, box_sz.x, box_sz.y, GL_RGBA, GL_UNSIGNED_BYTE, snap.image[i].get());
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0,
|
||||
m_dirty_box[i].x, m_dirty_box[i].y,
|
||||
box_sz.x, box_sz.y, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
snap.image[i].get());
|
||||
m_rtt[i].unbindTexture();
|
||||
LOG("restore face %d - %d bytes (%dx%d)", i, (int)box_sz.x * (int)box_sz.y * 4, (int)box_sz.x, (int)box_sz.y);
|
||||
LOG("restore face %d - %d bytes (%dx%d)", i,
|
||||
(int)box_sz.x * (int)box_sz.y * 4, (int)box_sz.x, (int)box_sz.y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2195,3 +2210,16 @@ bool ui::Layer::create(int width, int height, std::string name)
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void ui::Layer::resize(int width, int height)
|
||||
{
|
||||
glm::vec2 ratio = glm::vec2(width, height) / glm::vec2(w, h);
|
||||
w = width;
|
||||
h = height;
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
m_rtt[i].resize(width, height);
|
||||
m_dirty_box[i] = m_dirty_box[i] * glm::vec4(ratio, ratio);
|
||||
//m_dirty_face[i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
16
src/canvas.h
16
src/canvas.h
@@ -29,12 +29,27 @@ public:
|
||||
std::unique_ptr<uint8_t[]> image[6] = SIXPLETTE(0);
|
||||
glm::vec4 m_dirty_box[6] = SIXPLETTE(glm::vec4(0));
|
||||
bool m_dirty_face[6] = SIXPLETTE(false);
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
void create(int w, int h)
|
||||
{
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
image[i] = std::make_unique<uint8_t[]>(w*h*4);
|
||||
std::fill_n(image[i].get(), w*h*4, 0);
|
||||
}
|
||||
}
|
||||
void clear()
|
||||
{
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
m_dirty_face[i] = false;
|
||||
m_dirty_box[i] = glm::vec4(0);
|
||||
std::fill_n(image[i].get(), width*height*4, 0);
|
||||
}
|
||||
}
|
||||
};
|
||||
void resize(int width, int height);
|
||||
bool create(int width, int height, std::string name);
|
||||
void clear(const glm::vec4& c);
|
||||
Snapshot snapshot(std::string data_path);
|
||||
@@ -182,6 +197,7 @@ public:
|
||||
void stroke_cancel();
|
||||
void stroke_commit();
|
||||
void clear(const glm::vec4& color = { 1, 1, 1, 0 });
|
||||
void clear_all();
|
||||
void pick_start();
|
||||
void pick_update(int plane);
|
||||
glm::vec4 pick_get(glm::vec2 canvas_loc);
|
||||
|
||||
@@ -61,6 +61,9 @@ void NodeDialogBrowse::init_controls()
|
||||
else
|
||||
{
|
||||
current = nullptr;
|
||||
selected_path = "";
|
||||
selected_file = "";
|
||||
selected_name = "";
|
||||
}
|
||||
Asset::delete_file(path);
|
||||
msgbox->destroy();
|
||||
@@ -108,6 +111,11 @@ void NodeDialogBrowse::init_controls()
|
||||
// }
|
||||
}
|
||||
|
||||
bool NodeDialogBrowse::is_selected()
|
||||
{
|
||||
return current != nullptr;
|
||||
}
|
||||
|
||||
void NodeDialogBrowse::loaded()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -43,4 +43,5 @@ public:
|
||||
virtual void init() override;
|
||||
void init_controls();
|
||||
virtual void loaded() override;
|
||||
bool is_selected();
|
||||
};
|
||||
|
||||
54
src/node_dialog_resize.cpp
Normal file
54
src/node_dialog_resize.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
#include "pch.h"
|
||||
#include "log.h"
|
||||
#include "node_dialog_resize.h"
|
||||
#include "canvas.h"
|
||||
#include "node_image_texture.h"
|
||||
#include "app.h"
|
||||
#include <array>
|
||||
|
||||
Node* NodeDialogResize::clone_instantiate() const
|
||||
{
|
||||
return new NodeDialogResize();
|
||||
}
|
||||
|
||||
void NodeDialogResize::clone_finalize(Node* dest) const
|
||||
{
|
||||
NodeDialogResize* n = static_cast<NodeDialogResize*>(dest);
|
||||
n->init_controls();
|
||||
}
|
||||
|
||||
void NodeDialogResize::init()
|
||||
{
|
||||
auto tpl = static_cast<const NodeBorder*>(init_template("dialog-resize"));
|
||||
m_color = tpl->m_color;
|
||||
m_border_color = tpl->m_border_color;;
|
||||
m_thinkness = tpl->m_thinkness;;
|
||||
init_controls();
|
||||
}
|
||||
|
||||
void NodeDialogResize::init_controls()
|
||||
{
|
||||
btn_ok = find<NodeButton>("btn-ok");
|
||||
btn_cancel = find<NodeButton>("btn-cancel");
|
||||
combo = find<NodeComboBox>("resolution");
|
||||
text = find<NodeText>("current-res");
|
||||
resolution = ui::Canvas::I->m_width;
|
||||
static char txt[128];
|
||||
sprintf(txt, "Current: %dpx", resolution);
|
||||
text->set_text(txt);
|
||||
btn_cancel->on_click = [this](Node*) {
|
||||
destroy();
|
||||
};
|
||||
}
|
||||
|
||||
void NodeDialogResize::loaded()
|
||||
{
|
||||
// ui::Image thumb = ui::Canvas::I->thumbnail_read(data_path);
|
||||
// auto image_tex = find<NodeImageTexture>("thumb-tex");
|
||||
// image_tex->tex.create(thumb);
|
||||
}
|
||||
|
||||
int NodeDialogResize::get_resolution()
|
||||
{
|
||||
return combo ? res_map[combo->m_current_index] : 512;
|
||||
}
|
||||
22
src/node_dialog_resize.h
Normal file
22
src/node_dialog_resize.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
#include "node_border.h"
|
||||
#include "node_button.h"
|
||||
#include "node_combobox.h"
|
||||
#include "node_text.h"
|
||||
|
||||
class NodeDialogResize : public NodeBorder
|
||||
{
|
||||
public:
|
||||
const std::array<int, 4> res_map{512, 1024, 1536, 2048};
|
||||
NodeButton* btn_cancel;
|
||||
NodeButton* btn_ok;
|
||||
NodeComboBox* combo;
|
||||
NodeText* text;
|
||||
int resolution;
|
||||
virtual Node* clone_instantiate() const override;
|
||||
virtual void clone_finalize(Node* dest) const override;
|
||||
virtual void init() override;
|
||||
void init_controls();
|
||||
virtual void loaded() override;
|
||||
int get_resolution();
|
||||
};
|
||||
29
src/rtt.cpp
29
src/rtt.cpp
@@ -15,6 +15,34 @@ RTT::~RTT()
|
||||
//destroy();
|
||||
}
|
||||
|
||||
void RTT::resize(int width, int height)
|
||||
{
|
||||
RTT new_rtt;
|
||||
|
||||
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldDFboID);
|
||||
glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &oldRFboID);
|
||||
|
||||
new_rtt.create(width, height, -1, int_fmt);
|
||||
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, new_rtt.fboID);
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, fboID);
|
||||
glBlitFramebuffer(0, 0, w, h, 0, 0, new_rtt.w, new_rtt.h, GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, oldDFboID);
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, oldRFboID);
|
||||
|
||||
destroy();
|
||||
|
||||
oldRFboID = 0;
|
||||
oldDFboID = 0;
|
||||
fboID = new_rtt.fboID;
|
||||
rboID = new_rtt.rboID;
|
||||
texID = new_rtt.texID;
|
||||
int_fmt = new_rtt.int_fmt;
|
||||
w = new_rtt.w;
|
||||
h = new_rtt.h;
|
||||
}
|
||||
|
||||
void RTT::destroy()
|
||||
{
|
||||
if (rboID)
|
||||
@@ -47,6 +75,7 @@ bool RTT::create(int width, int height, int tex/* = -1*/, GLint internal_format)
|
||||
|
||||
w = width;
|
||||
h = height;
|
||||
int_fmt = internal_format;
|
||||
|
||||
if (tex == -1)
|
||||
{
|
||||
|
||||
@@ -8,6 +8,7 @@ class RTT
|
||||
GLuint fboID = 0;
|
||||
GLuint rboID = 0;
|
||||
GLuint texID = 0;
|
||||
GLint int_fmt = 0;
|
||||
int w = 0;
|
||||
int h = 0;
|
||||
|
||||
@@ -16,6 +17,7 @@ public:
|
||||
~RTT();
|
||||
|
||||
void destroy();
|
||||
void resize(int width, int height);
|
||||
bool create(int width, int height, int tex = -1, GLint internal_format = GL_RGBA8);
|
||||
bool recreate() { return create(w, h); }
|
||||
void clear(glm::vec4 color = glm::vec4(0));
|
||||
|
||||
Reference in New Issue
Block a user