implement file browser dialog

This commit is contained in:
2017-11-04 14:50:06 +00:00
parent a3276906f9
commit b49414bcd6
14 changed files with 330 additions and 15 deletions

View File

@@ -231,8 +231,8 @@ void App::update(float dt)
//glViewport(0, 0, (GLsizei)width, (GLsizei)height);
//glClear(GL_COLOR_BUFFER_BIT);
#ifndef __ANDROID__
//layout.reload();
#ifdef _WIN32
layout.reload();
#endif
if (auto* main = layout[main_id])
main->update(width, height, zoom);

View File

@@ -123,6 +123,7 @@ public:
void dialog_newdoc();
void dialog_save();
void dialog_open();
void dialog_browse();
void dialog_export();
void dialog_layer_rename();
void brush_update();

View File

@@ -1,6 +1,7 @@
#include "pch.h"
#include "app.h"
#include "node_dialog_open.h"
#include "node_dialog_browse.h"
void App::dialog_newdoc()
{
@@ -75,6 +76,37 @@ void App::dialog_open()
}
}
void App::dialog_browse()
{
if (canvas)
{
// load thumbnail test
auto dialog = std::make_shared<NodeDialogBrowse>();
dialog->m_manager = &layout;
dialog->data_path = data_path;
dialog->init();
dialog->create();
dialog->loaded();
layout[main_id]->add_child(dialog);
layout[main_id]->update();
dialog->btn_ok->on_click = [this, dialog](Node*)
{
canvas->reset_camera();
layers->clear();
canvas->m_canvas->project_open(dialog->selected_path);
doc_name = dialog->selected_name;
if (auto docname = layout[main_id]->find<NodeText>("txt-docname"))
docname->set_text(("Panodoc: " + doc_name).c_str());
for (auto& i : canvas->m_canvas->m_order)
layers->add_layer(canvas->m_canvas->m_layers[i].m_name.c_str());
dialog->destroy();
ActionManager::clear();
};
}
}
void App::dialog_save()
{
if (canvas)

View File

@@ -360,6 +360,11 @@ void App::init_menu_file()
popup->mouse_release();
popup->destroy();
};
popup->find<NodeButtonCustom>("file-browse")->on_click = [this](Node*) {
dialog_browse();
popup->mouse_release();
popup->destroy();
};
popup->find<NodeButtonCustom>("file-save")->on_click = [this](Node*) {
dialog_save();
popup->mouse_release();

View File

@@ -8,16 +8,17 @@
bool LayoutManager::load(const char* path)
{
if (m_loaded)
return true; // already loaded
#if !defined(__ANDROID__)
// struct stat tmp_info;
// if (stat(path, &tmp_info) != 0)
// return false;
// if (tmp_info.st_mtime <= m_file_info.st_mtime)
// return false;
// m_file_info = tmp_info;
#if _WIN32
struct stat tmp_info;
if (stat(path, &tmp_info) != 0)
return false;
if (tmp_info.st_mtime <= m_file_info.st_mtime)
return false;
m_file_info = tmp_info;
#else
if (m_loaded)
return true; // already loaded
#endif // __ANDROID__
m_path = path;

View File

@@ -349,6 +349,7 @@ int main(int argc, char** argv)
bool running = true;
unsigned long t0 = GetTickCount();
unsigned long t1;
float one_sec = 0;
while (running)
{
// If there any message in the queue process it
@@ -362,6 +363,15 @@ int main(int argc, char** argv)
{
t1 = GetTickCount();
float dt = (float)(t1 - t0) / 1000.0f;
// force redraw every one second
one_sec += dt;
if (one_sec > 1.f)
{
one_sec = 0;
App::I.redraw = true;
}
if (dt > 1.0f / 60.0f)
{
t0 = t1;

View File

@@ -24,6 +24,7 @@
#include "node_stroke_preview.h"
#include "node_canvas.h"
#include "node_scroll.h"
#include "node_dialog_browse.h"
void Node::watch(std::function<void(Node*)> observer)
{
@@ -739,6 +740,9 @@ void Node::parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr)
case kAttribute::FloodEvents:
m_flood_events = attr->IntValue() > 0;
break;
case kAttribute::AspectRatio:
YGNodeStyleSetAspectRatio(y_node, attr->FloatValue());
break;
default:
break;
}
@@ -791,6 +795,8 @@ void Node::load_internal(const tinyxml2::XMLElement* x_node)
CASE(kWidget::StrokePreview, NodeStrokePreview);
CASE(kWidget::Canvas, NodeCanvas);
CASE(kWidget::Scroll, NodeScroll);
CASE(kWidget::DialogBrowse, NodeDialogBrowse);
CASE(kWidget::DialogBrowseItem, NodeDialogBrowseItem);
#undef CASE
case kWidget::Ref:
{

View File

@@ -38,6 +38,7 @@ enum class kAttribute : uint16_t
Template = const_hash("template"),
Value = const_hash("value"),
Range = const_hash("range"),
AspectRatio = const_hash("aspect-ratio"),
};
enum class kWidget : uint16_t
@@ -68,6 +69,8 @@ enum class kWidget : uint16_t
StrokePreview = const_hash("stroke-preview"),
Canvas = const_hash("canvas"),
Scroll = const_hash("scroll"),
DialogBrowse = const_hash("dialog-browse"),
DialogBrowseItem = const_hash("dialog-browse-item"),
};
class Node

View File

@@ -0,0 +1,166 @@
#include "pch.h"
#include "log.h"
#include "node_dialog_browse.h"
#include "canvas.h"
#include "node_image_texture.h"
#include "asset.h"
#include "node_message_box.h"
#include "app.h"
Node* NodeDialogBrowse::clone_instantiate() const
{
return new NodeDialogBrowse();
}
void NodeDialogBrowse::clone_finalize(Node* dest) const
{
NodeDialogBrowse* n = static_cast<NodeDialogBrowse*>(dest);
n->init_controls();
}
void NodeDialogBrowse::init()
{
auto tpl = static_cast<const NodeBorder*>(init_template("dialog-browse"));
m_color = tpl->m_color;
m_border_color = tpl->m_border_color;;
m_thinkness = tpl->m_thinkness;;
init_controls();
}
void NodeDialogBrowse::init_controls()
{
btn_ok = find<NodeButton>("btn-ok");
btn_cancel = find<NodeButton>("btn-cancel");
btn_cancel->on_click = [this](Node*) {
destroy();
};
btn_delete = find<NodeButton>("btn-delete");
btn_delete->on_click = [this](Node*) {
if (!current)
return;
auto msgbox = new NodeMessageBox();
msgbox->m_manager = m_manager;
msgbox->init();
msgbox->m_title->set_text("Delete Project");
msgbox->m_message->set_text(("Are you sure you want to delete " + current->m_file_name + "?").c_str());
msgbox->btn_ok->on_click = [this,msgbox](Node*){
auto path = current->m_path;
int idx = container->get_child_index(current);
container->remove_child(current);
if (!container->m_children.empty())
{
int newidx = std::min<int>(idx, (int)container->m_children.size() - 1);
auto next = (NodeDialogBrowseItem*)container->get_child_at(newidx);
current = nullptr;
next->on_selected(next);
next->m_selected = true;
}
else
{
current = nullptr;
auto image_tex = find<NodeImageTexture>("thumb-tex");
image_tex->tex.destroy();
}
Asset::delete_file(path);
msgbox->destroy();
};
root()->add_child(msgbox);
root()->update();
};
container = find<Node>("files-list");
auto names = Asset::list_files(data_path, false, ".*\\.pano");
for (const auto& n : names)
{
auto node = new NodeDialogBrowseItem;
node->m_manager = m_manager;
node->init();
node->m_text->set_text(n.c_str());
node->m_path = data_path + "/" + n;
node->m_file_name = n;
node->on_selected = [&](NodeDialogBrowseItem* target) {
if (target == current)
return;
selected_path = target->m_path;
selected_file = target->m_file_name;
selected_name = selected_file.substr(0, selected_file.length() - 5);
if (current)
current->m_selected = false;
current = target;
};
// load thumb
ui::Image thumb = ui::Canvas::I->thumbnail_read(node->m_path);
auto image_tex = node->find<NodeImageTexture>("thumb-tex");
image_tex->tex.destroy();
image_tex->tex.create(thumb);
container->add_child(node);
}
// if (auto* first = (NodeDialogBrowseItem*)container->get_child_at(0))
// {
// first->on_selected(first);
// first->m_selected = true;
// }
}
void NodeDialogBrowse::loaded()
{
}
//////////////////////////////////////////////////////////////////
Node* NodeDialogBrowseItem::clone_instantiate() const
{
return new NodeDialogBrowseItem;
}
void NodeDialogBrowseItem::clone_finalize(Node* dest) const
{
NodeDialogBrowseItem* n = static_cast<NodeDialogBrowseItem*>(dest);
n->init_controls();
}
void NodeDialogBrowseItem::init()
{
auto tpl = static_cast<const NodeBorder*>(init_template("dialog-browse-item"));
m_color = tpl->m_color;
m_border_color = tpl->m_border_color;
m_thinkness = tpl->m_thinkness;
init_controls();
}
void NodeDialogBrowseItem::init_controls()
{
m_text = find<NodeText>("title");
}
void NodeDialogBrowseItem::loaded()
{
}
void NodeDialogBrowseItem::draw()
{
auto c = m_selected ? m_color_selected : m_color_normal;
m_thinkness = m_selected ? 1.f : 0.f;
m_color = m_mouse_inside ? m_color_hover : c;
NodeBorder::draw();
}
kEventResult NodeDialogBrowseItem::handle_event(Event* e)
{
NodeBorder::handle_event(e);
switch (e->m_type)
{
case kEventType::MouseEnter:
break;
case kEventType::MouseLeave:
break;
case kEventType::MouseDownL:
m_selected = true;
if (on_selected)
on_selected(this);
break;
case kEventType::MouseUpL:
break;
default:
return kEventResult::Available;
break;
}
return kEventResult::Consumed;
}

View File

@@ -0,0 +1,46 @@
#pragma once
#include "node_border.h"
#include "node_button.h"
#include "node_image_texture.h"
#include "node_text.h"
#include "node_text_input.h"
class NodeDialogBrowseItem : public NodeBorder
{
public:
NodeText* m_text;
NodeImageTexture* m_thumb;
glm::vec4 m_color_normal = glm::vec4(.4, .4, .4, 1);
glm::vec4 m_color_selected = glm::vec4(.3, .3, .3, 1);
glm::vec4 m_color_hover = glm::vec4(.5, .5, .5, 1);
bool m_selected = false;
std::string m_path;
std::string m_file_name;
std::function<void(NodeDialogBrowseItem* target)> on_selected;
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;
virtual void draw() override;
virtual kEventResult handle_event(Event* e) override;
};
class NodeDialogBrowse : public NodeBorder
{
public:
NodeButton* btn_cancel;
NodeButton* btn_ok;
NodeButton* btn_delete;
NodeDialogBrowseItem* current = nullptr;
Node* container;
std::string selected_path;
std::string selected_file;
std::string selected_name;
std::string data_path;
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;
};

View File

@@ -118,8 +118,14 @@ bool WacomTablet::init(HWND hWnd)
if (LoadWintab())
{
/* check if WinTab available. */
if (gpWTInfoA(0, 0, NULL))
gpWTInfoA(0, 0, 0);
if (UINT ret = gpWTInfoA(WTI_DEFSYSCTX, 0, &glogContext))
{
#ifdef _DEBUG
// this should just avoid errors in debug mode
if (ret != sizeof(LOGCONTEXTA))
return false;
#endif // _DEBUG
g_hCtx = TabletInit(hWnd);
if (!g_hCtx)
{
@@ -147,6 +153,7 @@ bool WacomTablet::init(HWND hWnd)
void WacomTablet::terminate()
{
gpWTClose(g_hCtx);
UnloadWintab();
}