add remote page loading
This commit is contained in:
@@ -370,6 +370,7 @@
|
|||||||
<ClCompile Include="src\node_image_texture.cpp" />
|
<ClCompile Include="src\node_image_texture.cpp" />
|
||||||
<ClCompile Include="src\node_input_box.cpp" />
|
<ClCompile Include="src\node_input_box.cpp" />
|
||||||
<ClCompile Include="src\node_message_box.cpp" />
|
<ClCompile Include="src\node_message_box.cpp" />
|
||||||
|
<ClCompile Include="src\node_metadata.cpp" />
|
||||||
<ClCompile Include="src\node_panel_brush.cpp" />
|
<ClCompile Include="src\node_panel_brush.cpp" />
|
||||||
<ClCompile Include="src\node_panel_color.cpp" />
|
<ClCompile Include="src\node_panel_color.cpp" />
|
||||||
<ClCompile Include="src\node_panel_floating.cpp" />
|
<ClCompile Include="src\node_panel_floating.cpp" />
|
||||||
@@ -380,6 +381,7 @@
|
|||||||
<ClCompile Include="src\node_panel_animation.cpp" />
|
<ClCompile Include="src\node_panel_animation.cpp" />
|
||||||
<ClCompile Include="src\node_popup_menu.cpp" />
|
<ClCompile Include="src\node_popup_menu.cpp" />
|
||||||
<ClCompile Include="src\node_progress_bar.cpp" />
|
<ClCompile Include="src\node_progress_bar.cpp" />
|
||||||
|
<ClCompile Include="src\node_remote_page.cpp" />
|
||||||
<ClCompile Include="src\node_scroll.cpp" />
|
<ClCompile Include="src\node_scroll.cpp" />
|
||||||
<ClCompile Include="src\node_settings.cpp" />
|
<ClCompile Include="src\node_settings.cpp" />
|
||||||
<ClCompile Include="src\node_slider.cpp" />
|
<ClCompile Include="src\node_slider.cpp" />
|
||||||
@@ -500,6 +502,7 @@
|
|||||||
<ClInclude Include="src\node_image_texture.h" />
|
<ClInclude Include="src\node_image_texture.h" />
|
||||||
<ClInclude Include="src\node_input_box.h" />
|
<ClInclude Include="src\node_input_box.h" />
|
||||||
<ClInclude Include="src\node_message_box.h" />
|
<ClInclude Include="src\node_message_box.h" />
|
||||||
|
<ClInclude Include="src\node_metadata.h" />
|
||||||
<ClInclude Include="src\node_panel_brush.h" />
|
<ClInclude Include="src\node_panel_brush.h" />
|
||||||
<ClInclude Include="src\node_panel_color.h" />
|
<ClInclude Include="src\node_panel_color.h" />
|
||||||
<ClInclude Include="src\node_panel_floating.h" />
|
<ClInclude Include="src\node_panel_floating.h" />
|
||||||
@@ -510,6 +513,7 @@
|
|||||||
<ClInclude Include="src\node_panel_animation.h" />
|
<ClInclude Include="src\node_panel_animation.h" />
|
||||||
<ClInclude Include="src\node_popup_menu.h" />
|
<ClInclude Include="src\node_popup_menu.h" />
|
||||||
<ClInclude Include="src\node_progress_bar.h" />
|
<ClInclude Include="src\node_progress_bar.h" />
|
||||||
|
<ClInclude Include="src\node_remote_page.h" />
|
||||||
<ClInclude Include="src\node_scroll.h" />
|
<ClInclude Include="src\node_scroll.h" />
|
||||||
<ClInclude Include="src\node_settings.h" />
|
<ClInclude Include="src\node_settings.h" />
|
||||||
<ClInclude Include="src\node_slider.h" />
|
<ClInclude Include="src\node_slider.h" />
|
||||||
|
|||||||
@@ -384,6 +384,12 @@
|
|||||||
<ClCompile Include="src\mp4enc.cpp">
|
<ClCompile Include="src\mp4enc.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\node_remote_page.cpp">
|
||||||
|
<Filter>Source Files\ui</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\node_metadata.cpp">
|
||||||
|
<Filter>Source Files\ui</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="libs\jpeg\jpgd.h">
|
<ClInclude Include="libs\jpeg\jpgd.h">
|
||||||
@@ -638,6 +644,12 @@
|
|||||||
<ClInclude Include="src\mp4enc.h">
|
<ClInclude Include="src\mp4enc.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="src\node_remote_page.h">
|
||||||
|
<Filter>Source Files\ui</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="src\node_metadata.h">
|
||||||
|
<Filter>Source Files\ui</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="PanoPainter.rc">
|
<ResourceCompile Include="PanoPainter.rc">
|
||||||
|
|||||||
28
data/dialogs/remote-page.xml
Normal file
28
data/dialogs/remote-page.xml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<root
|
||||||
|
xmlns="http://panopainter.com/layout.xsd"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
>
|
||||||
|
|
||||||
|
<layout id="remote-page">
|
||||||
|
<border positioning="absolute" position="0 0" color=".4 .4 .4 .8" width="100%" height="100%" align="center" justify="center" mouse-capture="1">
|
||||||
|
<border thickness="1" border-color=".2" pad="3" max-width="650" dir="col" width="80%" height="80%">
|
||||||
|
<border width="100%" height="30" color=".2 .2 .2 .9" dir="row" align="center" justify="center">
|
||||||
|
<text id="title" text="PageTitle"></text>
|
||||||
|
</border>
|
||||||
|
<border width="100%" height="100%" color="0 0 0 .9" pad="10" dir="col">
|
||||||
|
<!--window content-->
|
||||||
|
<border color=".2" width="100%" height="1" grow="1">
|
||||||
|
<scroll id="content" pad="10" margin="5" color=".3 .3 .3 .4" height="100%" dir="col" wrap="0" shrink="1">
|
||||||
|
</scroll>
|
||||||
|
</border>
|
||||||
|
<!--footer buttons-->
|
||||||
|
<node id="footer" height="60" dir="row" justify="flex-end">
|
||||||
|
<!--<button id="btn-ok" text="Ok" width="100" height="30" margin="5 0 0 0"/>-->
|
||||||
|
</node>
|
||||||
|
</border>
|
||||||
|
</border>
|
||||||
|
</border>
|
||||||
|
</layout>
|
||||||
|
|
||||||
|
</root>
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "serializer.h"
|
#include "serializer.h"
|
||||||
#include "font.h"
|
#include "font.h"
|
||||||
|
#include "node_remote_page.h"
|
||||||
|
|
||||||
void App::title_update()
|
void App::title_update()
|
||||||
{
|
{
|
||||||
@@ -1333,6 +1334,32 @@ void App::initLayout()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto whatsnew = std::make_shared<NodeRemotePage>();
|
||||||
|
whatsnew->m_manager = &layout;
|
||||||
|
whatsnew->init();
|
||||||
|
whatsnew->load_url("http://localhost:8080/app-content/whatsnew.xml", [this, whatsnew] (bool success) {
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
int last_id = Settings::value_or<Serializer::Integer>("whatsnew-id", 0);
|
||||||
|
if (whatsnew->m_page_id <= g_version_build && whatsnew->m_page_id > last_id)
|
||||||
|
{
|
||||||
|
whatsnew->set_title(fmt::format("What's new in version {}", g_version_number));
|
||||||
|
layout[main_id]->add_child(whatsnew);
|
||||||
|
}
|
||||||
|
whatsnew->add_button("Reload", 120, [this, whatsnew](Node*) {
|
||||||
|
whatsnew->reload();
|
||||||
|
});
|
||||||
|
whatsnew->add_button("Read Later", 120, [this, whatsnew](Node*) {
|
||||||
|
whatsnew->destroy();
|
||||||
|
});
|
||||||
|
whatsnew->add_button("Close", 100, [this, whatsnew](Node*) {
|
||||||
|
Settings::set<Serializer::Integer>("whatsnew-id", whatsnew->m_page_id);
|
||||||
|
Settings::save();
|
||||||
|
whatsnew->destroy();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
brush_update(true, true);
|
brush_update(true, true);
|
||||||
|
|
||||||
// hacky thing to make the toolbar buttons not steal events when moving cursor fast
|
// hacky thing to make the toolbar buttons not steal events when moving cursor fast
|
||||||
|
|||||||
@@ -186,6 +186,7 @@ bool Asset::open_url(const std::string& url, std::function<bool(float)> progress
|
|||||||
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
|
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &tmp_data);
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &tmp_data);
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_data_handler_asset);
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_data_handler_asset);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L);
|
||||||
#ifdef __ANDROID__
|
#ifdef __ANDROID__
|
||||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||||
#endif
|
#endif
|
||||||
@@ -221,7 +222,7 @@ std::future<bool>& Asset::open_url_async(const std::string& url,
|
|||||||
m_stop_async = false;
|
m_stop_async = false;
|
||||||
remote_future = std::async([this, url, progress, complete] {
|
remote_future = std::async([this, url, progress, complete] {
|
||||||
bool ok = open_url(url, progress);
|
bool ok = open_url(url, progress);
|
||||||
if (ok && complete)
|
if (complete)
|
||||||
complete(ok);
|
complete(ok);
|
||||||
return ok;
|
return ok;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -39,14 +39,28 @@ bool LayoutManager::load(const char* path)
|
|||||||
|
|
||||||
m_path = path;
|
m_path = path;
|
||||||
|
|
||||||
auto old = std::move(m_layouts);
|
|
||||||
|
|
||||||
Asset file;
|
Asset file;
|
||||||
if (!(file.open(path) && file.read_all()))
|
if (!(file.open(path) && file.read_all()))
|
||||||
return false;
|
return false;
|
||||||
tinyxml2::XMLDocument xml;
|
auto xml_string = std::string((char*)file.m_data, (size_t)file.m_len);
|
||||||
auto ret = xml.Parse((char*)file.m_data, file.m_len);
|
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
|
if (!parse(xml_string))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (on_loaded)
|
||||||
|
on_loaded(m_loaded);
|
||||||
|
m_loaded = true;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LayoutManager::parse(const std::string& xml_string) noexcept
|
||||||
|
{
|
||||||
|
auto old = std::move(m_layouts);
|
||||||
|
|
||||||
|
tinyxml2::XMLDocument xml;
|
||||||
|
auto ret = xml.Parse(xml_string.c_str(), xml_string.size());
|
||||||
if (ret != tinyxml2::XMLError::XML_SUCCESS)
|
if (ret != tinyxml2::XMLError::XML_SUCCESS)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -70,7 +84,7 @@ bool LayoutManager::load(const char* path)
|
|||||||
if (std::find(osv.begin(), osv.end(), PP_OS) == osv.end())
|
if (std::find(osv.begin(), osv.end(), PP_OS) == osv.end())
|
||||||
{
|
{
|
||||||
LOG("Layout %s not for this os(%s), skipping", id_str, PP_OS)
|
LOG("Layout %s not for this os(%s), skipping", id_str, PP_OS)
|
||||||
current = current->NextSiblingElement("layout");
|
current = current->NextSiblingElement("layout");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -105,11 +119,6 @@ bool LayoutManager::load(const char* path)
|
|||||||
}
|
}
|
||||||
current = current->NextSiblingElement("layout");
|
current = current->NextSiblingElement("layout");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (on_loaded)
|
|
||||||
on_loaded(m_loaded);
|
|
||||||
m_loaded = true;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
12
src/layout.h
12
src/layout.h
@@ -1,15 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "shape.h"
|
|
||||||
#include "util.h"
|
|
||||||
#include "shader.h"
|
|
||||||
#include "font.h"
|
|
||||||
#include "asset.h"
|
|
||||||
#include "rtt.h"
|
|
||||||
#include "bezier.h"
|
|
||||||
#include "canvas.h"
|
|
||||||
#include "event.h"
|
|
||||||
#include <tinyxml2.h>
|
|
||||||
#include <yoga/Yoga.h>
|
|
||||||
|
|
||||||
class LayoutManager
|
class LayoutManager
|
||||||
{
|
{
|
||||||
@@ -23,6 +12,7 @@ public:
|
|||||||
void unload();
|
void unload();
|
||||||
void create();
|
void create();
|
||||||
bool load(const char* path);
|
bool load(const char* path);
|
||||||
|
bool parse(const std::string& xml_string) noexcept;
|
||||||
bool reload();
|
bool reload();
|
||||||
class Node* operator[](uint16_t id)
|
class Node* operator[](uint16_t id)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1177,6 +1177,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
|||||||
}
|
}
|
||||||
case WM_ACTIVATE:
|
case WM_ACTIVATE:
|
||||||
{
|
{
|
||||||
|
win32_show_cursor(true);
|
||||||
App::I->ui_task_async([=] {
|
App::I->ui_task_async([=] {
|
||||||
int active = GET_WM_ACTIVATE_STATE(wp, lp);
|
int active = GET_WM_ACTIVATE_STATE(wp, lp);
|
||||||
WacomTablet::I.set_focus(active);
|
WacomTablet::I.set_focus(active);
|
||||||
|
|||||||
25
src/node.cpp
25
src/node.cpp
@@ -37,6 +37,7 @@
|
|||||||
#include "node_panel_quick.h"
|
#include "node_panel_quick.h"
|
||||||
#include "node_tool_bucket.h"
|
#include "node_tool_bucket.h"
|
||||||
#include "node_panel_animation.h"
|
#include "node_panel_animation.h"
|
||||||
|
#include "node_metadata.h"
|
||||||
|
|
||||||
void Node::app_redraw()
|
void Node::app_redraw()
|
||||||
{
|
{
|
||||||
@@ -389,6 +390,16 @@ std::shared_ptr<Node> Node::load_template(const std::string& filename, const std
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<Node> Node::parse_template(const std::string& xml_string, const std::string& name) const
|
||||||
|
{
|
||||||
|
LayoutManager m;
|
||||||
|
std::shared_ptr<Node> ret;
|
||||||
|
if (m.parse(xml_string))
|
||||||
|
ret = m.get_ref(name.c_str())->m_children[0]->clone();
|
||||||
|
m.unload();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void Node::add_child(Node* n)
|
void Node::add_child(Node* n)
|
||||||
{
|
{
|
||||||
App::I->ui_task([&]
|
App::I->ui_task([&]
|
||||||
@@ -749,6 +760,8 @@ Node::Node(Node&& o)
|
|||||||
m_pos_offset_childred = o.m_pos_offset_childred;
|
m_pos_offset_childred = o.m_pos_offset_childred;
|
||||||
m_clip_uncut = o.m_clip_uncut;
|
m_clip_uncut = o.m_clip_uncut;
|
||||||
|
|
||||||
|
auto_width = o.auto_width;
|
||||||
|
auto_height = o.auto_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
Node::~Node()
|
Node::~Node()
|
||||||
@@ -764,12 +777,14 @@ void Node::SetWidth(float value)
|
|||||||
{
|
{
|
||||||
YGNodeStyleSetWidth(y_node, value);
|
YGNodeStyleSetWidth(y_node, value);
|
||||||
m_size.x = value;
|
m_size.x = value;
|
||||||
|
auto_width = value == YGUndefined;
|
||||||
app_redraw();
|
app_redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Node::SetWidthP(float value)
|
void Node::SetWidthP(float value)
|
||||||
{
|
{
|
||||||
YGNodeStyleSetWidthPercent(y_node, value);
|
YGNodeStyleSetWidthPercent(y_node, value);
|
||||||
|
auto_width = value == YGUndefined;
|
||||||
app_redraw();
|
app_redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -777,12 +792,14 @@ void Node::SetHeight(float value)
|
|||||||
{
|
{
|
||||||
YGNodeStyleSetHeight(y_node, value);
|
YGNodeStyleSetHeight(y_node, value);
|
||||||
m_size.y = value;
|
m_size.y = value;
|
||||||
|
auto_height = value == YGUndefined;
|
||||||
app_redraw();
|
app_redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Node::SetHeightP(float value)
|
void Node::SetHeightP(float value)
|
||||||
{
|
{
|
||||||
YGNodeStyleSetHeightPercent(y_node, value);
|
YGNodeStyleSetHeightPercent(y_node, value);
|
||||||
|
auto_height = value == YGUndefined;
|
||||||
app_redraw();
|
app_redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1163,6 +1180,7 @@ void Node::parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr)
|
|||||||
{
|
{
|
||||||
YGNodeStyleSetWidth(y_node, YGUndefined);
|
YGNodeStyleSetWidth(y_node, YGUndefined);
|
||||||
YGNodeStyleSetWidthPercent(y_node, YGUndefined);
|
YGNodeStyleSetWidthPercent(y_node, YGUndefined);
|
||||||
|
auto_width = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1170,6 +1188,7 @@ void Node::parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr)
|
|||||||
YGNodeStyleSetWidthPercent(y_node, attr->FloatValue());
|
YGNodeStyleSetWidthPercent(y_node, attr->FloatValue());
|
||||||
else
|
else
|
||||||
YGNodeStyleSetWidth(y_node, attr->FloatValue());
|
YGNodeStyleSetWidth(y_node, attr->FloatValue());
|
||||||
|
auto_width = false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case kAttribute::MinWidth:
|
case kAttribute::MinWidth:
|
||||||
@@ -1183,6 +1202,7 @@ void Node::parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr)
|
|||||||
{
|
{
|
||||||
YGNodeStyleSetHeight(y_node, YGUndefined);
|
YGNodeStyleSetHeight(y_node, YGUndefined);
|
||||||
YGNodeStyleSetHeightPercent(y_node, YGUndefined);
|
YGNodeStyleSetHeightPercent(y_node, YGUndefined);
|
||||||
|
auto_height = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1190,6 +1210,7 @@ void Node::parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr)
|
|||||||
YGNodeStyleSetHeightPercent(y_node, attr->FloatValue());
|
YGNodeStyleSetHeightPercent(y_node, attr->FloatValue());
|
||||||
else
|
else
|
||||||
YGNodeStyleSetHeight(y_node, attr->FloatValue());
|
YGNodeStyleSetHeight(y_node, attr->FloatValue());
|
||||||
|
auto_height = false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case kAttribute::MinHeight:
|
case kAttribute::MinHeight:
|
||||||
@@ -1416,6 +1437,7 @@ void Node::load_internal(const tinyxml2::XMLElement* x_node)
|
|||||||
CASE(kWidget::UserManual, NodeUserManual);
|
CASE(kWidget::UserManual, NodeUserManual);
|
||||||
CASE(kWidget::ToolBucket, NodeToolBucket);
|
CASE(kWidget::ToolBucket, NodeToolBucket);
|
||||||
CASE(kWidget::Timeline, NodeAnimationTimeline);
|
CASE(kWidget::Timeline, NodeAnimationTimeline);
|
||||||
|
CASE(kWidget::Metadata, NodeMetadata);
|
||||||
#undef CASE
|
#undef CASE
|
||||||
case kWidget::Ref:
|
case kWidget::Ref:
|
||||||
{
|
{
|
||||||
@@ -1481,6 +1503,9 @@ void Node::clone_copy(Node* dest) const
|
|||||||
dest->m_pos_offset = m_pos_offset;
|
dest->m_pos_offset = m_pos_offset;
|
||||||
dest->m_pos_offset_childred = m_pos_offset_childred;
|
dest->m_pos_offset_childred = m_pos_offset_childred;
|
||||||
dest->m_clip_uncut = m_clip_uncut;
|
dest->m_clip_uncut = m_clip_uncut;
|
||||||
|
|
||||||
|
dest->auto_width = auto_width;
|
||||||
|
dest->auto_height = auto_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Node::clone_children(Node* dest) const
|
void Node::clone_children(Node* dest) const
|
||||||
|
|||||||
14
src/node.h
14
src/node.h
@@ -97,6 +97,7 @@ enum class kWidget : uint16_t
|
|||||||
UserManual = const_hash("usermanual"),
|
UserManual = const_hash("usermanual"),
|
||||||
ToolBucket = const_hash("tool-bucket"),
|
ToolBucket = const_hash("tool-bucket"),
|
||||||
Timeline = const_hash("timeline"),
|
Timeline = const_hash("timeline"),
|
||||||
|
Metadata = const_hash("metadata"),
|
||||||
};
|
};
|
||||||
|
|
||||||
class Node : public std::enable_shared_from_this<Node>
|
class Node : public std::enable_shared_from_this<Node>
|
||||||
@@ -143,6 +144,9 @@ public:
|
|||||||
// it's actually rendering
|
// it's actually rendering
|
||||||
bool m_on_screen = false;
|
bool m_on_screen = false;
|
||||||
|
|
||||||
|
bool auto_width = true;
|
||||||
|
bool auto_height = true;
|
||||||
|
|
||||||
Node(const Node&) = delete;
|
Node(const Node&) = delete;
|
||||||
Node& operator=(const Node&) = delete;
|
Node& operator=(const Node&) = delete;
|
||||||
Node&& operator=(Node&& o);
|
Node&& operator=(Node&& o);
|
||||||
@@ -279,6 +283,15 @@ public:
|
|||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
template<class T = Node> std::shared_ptr<T> add_child_xml(const std::string& xml_string, const std::string& name)
|
||||||
|
{
|
||||||
|
if (auto t = parse_template(xml_string, name))
|
||||||
|
{
|
||||||
|
add_child(t);
|
||||||
|
return std::dynamic_pointer_cast<T>(t);
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void on_tick(float dt) { };
|
virtual void on_tick(float dt) { };
|
||||||
virtual kEventResult on_event(Event* e);
|
virtual kEventResult on_event(Event* e);
|
||||||
@@ -296,6 +309,7 @@ public:
|
|||||||
const Node* init_template(const char* id);
|
const Node* init_template(const char* id);
|
||||||
bool init_template_file(const std::string& path, const std::string& id);
|
bool init_template_file(const std::string& path, const std::string& id);
|
||||||
std::shared_ptr<Node> load_template(const std::string& filename, const std::string& name) const;
|
std::shared_ptr<Node> load_template(const std::string& filename, const std::string& name) const;
|
||||||
|
std::shared_ptr<Node> parse_template(const std::string& xml_stirng, const std::string& name) const;
|
||||||
void tick(float dt);
|
void tick(float dt);
|
||||||
void app_redraw();
|
void app_redraw();
|
||||||
void add_child(Node* n);
|
void add_child(Node* n);
|
||||||
|
|||||||
25
src/node_metadata.cpp
Normal file
25
src/node_metadata.cpp
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
#include "pch.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "node_metadata.h"
|
||||||
|
|
||||||
|
NodeMetadata::NodeMetadata() noexcept
|
||||||
|
{
|
||||||
|
m_nodeID = const_hash("metadata");
|
||||||
|
m_nodeID_s = "metadata";
|
||||||
|
}
|
||||||
|
|
||||||
|
Node* NodeMetadata::clone_instantiate() const
|
||||||
|
{
|
||||||
|
return new NodeMetadata();
|
||||||
|
}
|
||||||
|
void NodeMetadata::clone_copy(Node* dest) const
|
||||||
|
{
|
||||||
|
Node::clone_copy(dest);
|
||||||
|
NodeMetadata* n = static_cast<NodeMetadata*>(dest);
|
||||||
|
n->m_props = m_props;
|
||||||
|
}
|
||||||
|
void NodeMetadata::parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr)
|
||||||
|
{
|
||||||
|
Node::parse_attributes(ka, attr);
|
||||||
|
m_props[attr->Name()] = attr->Value();
|
||||||
|
}
|
||||||
12
src/node_metadata.h
Normal file
12
src/node_metadata.h
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "node.h"
|
||||||
|
|
||||||
|
class NodeMetadata : public Node
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::map<std::string, std::string> m_props;
|
||||||
|
NodeMetadata() noexcept;
|
||||||
|
virtual Node* clone_instantiate() const override;
|
||||||
|
virtual void clone_copy(Node* dest) const override;
|
||||||
|
virtual void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr) override;
|
||||||
|
};
|
||||||
98
src/node_remote_page.cpp
Normal file
98
src/node_remote_page.cpp
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
#include "pch.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "node_remote_page.h"
|
||||||
|
#include "node_button.h"
|
||||||
|
#include "node_scroll.h"
|
||||||
|
#include "asset.h"
|
||||||
|
#include "node_text.h"
|
||||||
|
#include "node_metadata.h"
|
||||||
|
|
||||||
|
Node* NodeRemotePage::clone_instantiate() const
|
||||||
|
{
|
||||||
|
return new NodeRemotePage();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeRemotePage::clone_copy(Node* dest) const
|
||||||
|
{
|
||||||
|
auto n = static_cast<NodeRemotePage*>(dest);
|
||||||
|
n->m_page_id = m_page_id;
|
||||||
|
n->m_loaded = m_loaded;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeRemotePage::init()
|
||||||
|
{
|
||||||
|
init_template_file("data/dialogs/remote-page.xml", "remote-page");
|
||||||
|
init_controls();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeRemotePage::init_controls()
|
||||||
|
{
|
||||||
|
m_content = find<NodeScroll>("content");
|
||||||
|
m_title = find<NodeText>("title");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::future<bool> NodeRemotePage::load_url(const std::string& url,
|
||||||
|
std::function<void(bool success)> on_complete /*= nullptr*/) noexcept
|
||||||
|
{
|
||||||
|
m_loading = true;
|
||||||
|
|
||||||
|
auto align = m_content->add_child_ref<Node>();
|
||||||
|
align->SetWidthP(100.f);
|
||||||
|
align->SetHeightP(100.f);
|
||||||
|
align->SetAlign(YGAlignCenter);
|
||||||
|
align->SetJustify(YGJustifyCenter);
|
||||||
|
auto text = align->add_child_ref<NodeText>();
|
||||||
|
text->set_font(kFont::Arial_30);
|
||||||
|
text->set_text("Connecting to the server...");
|
||||||
|
|
||||||
|
m_url = url;
|
||||||
|
m_loaded = false;
|
||||||
|
auto remote = std::make_shared<Asset>();
|
||||||
|
auto prom = std::make_shared<std::promise<bool>>();
|
||||||
|
remote->open_url_async(url, nullptr, [this, remote, align, text, prom, on_complete](bool success) {
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
m_content->add_child_xml(std::string((char*)remote->m_data, (size_t)remote->m_len), "about");
|
||||||
|
if (auto meta = m_content->find<NodeMetadata>("metadata"))
|
||||||
|
m_page_id = std::stol(meta->m_props["page-id"]);
|
||||||
|
align->destroy();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
text->set_text("Error loading the page");
|
||||||
|
}
|
||||||
|
m_loaded = success;
|
||||||
|
m_loading = false;
|
||||||
|
prom->set_value(success);
|
||||||
|
if (on_complete)
|
||||||
|
on_complete(success);
|
||||||
|
});
|
||||||
|
return prom->get_future();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeRemotePage::reload() noexcept
|
||||||
|
{
|
||||||
|
if (m_loading)
|
||||||
|
return;
|
||||||
|
m_content->remove_all_children();
|
||||||
|
load_url(m_url);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeRemotePage::set_title(const std::string& title)
|
||||||
|
{
|
||||||
|
m_title->set_text(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeRemotePage::add_button(const std::string& label, int width,
|
||||||
|
std::function<void(Node* target)> onclic /*= nullptr*/) noexcept
|
||||||
|
{
|
||||||
|
if (auto footer = find("footer"))
|
||||||
|
{
|
||||||
|
auto b = footer->add_child<NodeButton>();
|
||||||
|
b->m_text->set_text(label);
|
||||||
|
b->m_border->SetWidth(width);
|
||||||
|
b->m_border->SetHeight(30);
|
||||||
|
b->m_border->SetMargin(5, 0, 0, 0);
|
||||||
|
b->on_click = onclic;
|
||||||
|
}
|
||||||
|
}
|
||||||
23
src/node_remote_page.h
Normal file
23
src/node_remote_page.h
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "node_border.h"
|
||||||
|
|
||||||
|
class NodeRemotePage : public NodeBorder
|
||||||
|
{
|
||||||
|
class NodeScroll* m_content;
|
||||||
|
class NodeText* m_title;
|
||||||
|
bool m_loading;
|
||||||
|
std::string m_url;
|
||||||
|
public:
|
||||||
|
bool m_loaded;
|
||||||
|
int m_page_id;
|
||||||
|
virtual Node* clone_instantiate() const override;
|
||||||
|
virtual void clone_copy(Node* dest) const override;
|
||||||
|
virtual void init() override;
|
||||||
|
void init_controls();
|
||||||
|
std::future<bool> load_url(const std::string& url,
|
||||||
|
std::function<void(bool success)> on_complete = nullptr) noexcept;
|
||||||
|
void reload() noexcept;
|
||||||
|
void set_title(const std::string& title);
|
||||||
|
void add_button(const std::string& label, int width,
|
||||||
|
std::function<void(Node* target)> onclic = nullptr) noexcept;
|
||||||
|
};
|
||||||
@@ -20,6 +20,10 @@ void NodeText::clone_copy(Node* dest) const
|
|||||||
n->m_color = m_color;
|
n->m_color = m_color;
|
||||||
n->m_font_size = m_font_size;
|
n->m_font_size = m_font_size;
|
||||||
n->font_id = font_id;
|
n->font_id = font_id;
|
||||||
|
n->m_multiline = m_multiline;
|
||||||
|
n->m_off = m_off;
|
||||||
|
n->m_text_align_v = m_text_align_v;
|
||||||
|
n->m_text_align_h = m_text_align_h;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeText::create()
|
void NodeText::create()
|
||||||
@@ -32,7 +36,7 @@ void NodeText::create()
|
|||||||
font_id = (kFont)const_hash(font);
|
font_id = (kFont)const_hash(font);
|
||||||
m_text_mesh.create();
|
m_text_mesh.create();
|
||||||
m_text_mesh.update(font_id, m_text);
|
m_text_mesh.update(font_id, m_text);
|
||||||
SetSize(m_text_mesh.bb);
|
update_layout();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,13 +45,7 @@ void NodeText::set_font(kFont fontID)
|
|||||||
font_id = fontID;
|
font_id = fontID;
|
||||||
m_text_mesh.create();
|
m_text_mesh.create();
|
||||||
m_text_mesh.update(font_id, m_text);
|
m_text_mesh.update(font_id, m_text);
|
||||||
SetSize(m_text_mesh.bb);
|
update_layout();
|
||||||
}
|
|
||||||
|
|
||||||
void NodeText::restore_context()
|
|
||||||
{
|
|
||||||
Node::restore_context();
|
|
||||||
create();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeText::parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr)
|
void NodeText::parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr)
|
||||||
@@ -55,6 +53,25 @@ void NodeText::parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* att
|
|||||||
Node::parse_attributes(ka, attr);
|
Node::parse_attributes(ka, attr);
|
||||||
switch (ka)
|
switch (ka)
|
||||||
{
|
{
|
||||||
|
case kAttribute::Multiline:
|
||||||
|
m_multiline = attr->BoolValue();
|
||||||
|
break;
|
||||||
|
case kAttribute::TextAlign:
|
||||||
|
if (strcmp(attr->Value(), "left") == 0)
|
||||||
|
m_text_align_h = TextAlign::Begin;
|
||||||
|
else if (strcmp(attr->Value(), "center") == 0)
|
||||||
|
m_text_align_h = TextAlign::Center;
|
||||||
|
else if (strcmp(attr->Value(), "right") == 0)
|
||||||
|
m_text_align_h = TextAlign::End;
|
||||||
|
break;
|
||||||
|
case kAttribute::TextVerticalAlign:
|
||||||
|
if (strcmp(attr->Value(), "top") == 0)
|
||||||
|
m_text_align_v = TextAlign::Begin;
|
||||||
|
else if (strcmp(attr->Value(), "center") == 0)
|
||||||
|
m_text_align_v = TextAlign::Center;
|
||||||
|
else if (strcmp(attr->Value(), "bottom") == 0)
|
||||||
|
m_text_align_v = TextAlign::End;
|
||||||
|
break;
|
||||||
case kAttribute::TextWrapWidth:
|
case kAttribute::TextWrapWidth:
|
||||||
m_text_mesh.max_width = attr->IntValue();
|
m_text_mesh.max_width = attr->IntValue();
|
||||||
break;
|
break;
|
||||||
@@ -82,11 +99,11 @@ void NodeText::parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* att
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeText::set_text(const char* s)
|
void NodeText::set_text(const std::string& s)
|
||||||
{
|
{
|
||||||
m_text = s;
|
m_text = s;
|
||||||
m_text_mesh.update(font_id, s);
|
m_text_mesh.update(font_id, s);
|
||||||
SetSize(m_text_mesh.bb);
|
update_layout();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeText::set_text_format(const char* fmt, ...)
|
void NodeText::set_text_format(const char* fmt, ...)
|
||||||
@@ -98,7 +115,39 @@ void NodeText::set_text_format(const char* fmt, ...)
|
|||||||
va_end(args);
|
va_end(args);
|
||||||
m_text = buffer;
|
m_text = buffer;
|
||||||
m_text_mesh.update(font_id, buffer);
|
m_text_mesh.update(font_id, buffer);
|
||||||
SetSize(m_text_mesh.bb);
|
update_layout();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeText::update_layout()
|
||||||
|
{
|
||||||
|
if (auto_width)
|
||||||
|
{
|
||||||
|
YGNodeStyleSetWidth(y_node, m_text_mesh.bb.x);
|
||||||
|
m_size.x = m_text_mesh.bb.x;
|
||||||
|
}
|
||||||
|
if (auto_height)
|
||||||
|
{
|
||||||
|
YGNodeStyleSetHeight(y_node, m_text_mesh.bb.y);
|
||||||
|
m_size.y = m_text_mesh.bb.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto pad = GetPadding();
|
||||||
|
float h = GetHeight() - (pad[1] + pad[3]);
|
||||||
|
float w = GetWidth() - (pad[0] + pad[2]);
|
||||||
|
|
||||||
|
if (m_text_align_v == TextAlign::Begin)
|
||||||
|
m_off.y = pad[0];
|
||||||
|
else if (m_text_align_v == TextAlign::Center)
|
||||||
|
m_off.y = (h - m_text_mesh.bb.y) * 0.5f + pad[0];
|
||||||
|
else
|
||||||
|
m_off.y = (h - m_text_mesh.bb.y) + pad[0];
|
||||||
|
|
||||||
|
if (m_text_align_h == TextAlign::Begin)
|
||||||
|
m_off.x = pad[3];
|
||||||
|
else if (m_text_align_v == TextAlign::Center)
|
||||||
|
m_off.x = (w - m_text_mesh.bb.x) * 0.5f + pad[3];
|
||||||
|
else
|
||||||
|
m_off.x = (w - m_text_mesh.bb.x) + pad[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeText::draw()
|
void NodeText::draw()
|
||||||
@@ -116,6 +165,8 @@ void NodeText::draw()
|
|||||||
|
|
||||||
void NodeText::handle_resize(glm::vec2 old_size, glm::vec2 new_size, float zoom)
|
void NodeText::handle_resize(glm::vec2 old_size, glm::vec2 new_size, float zoom)
|
||||||
{
|
{
|
||||||
|
auto pad = GetPadding();
|
||||||
|
m_text_mesh.max_width = m_multiline ? new_size.x - (pad[1] + pad[3]) : 0;
|
||||||
m_text_mesh.update(font_id, m_text);
|
m_text_mesh.update(font_id, m_text);
|
||||||
SetSize(m_text_mesh.bb);
|
update_layout();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,20 +5,33 @@
|
|||||||
class NodeText : public Node
|
class NodeText : public Node
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
enum class TextAlign
|
||||||
|
{
|
||||||
|
Begin,
|
||||||
|
Center,
|
||||||
|
End,
|
||||||
|
};
|
||||||
TextMesh m_text_mesh;
|
TextMesh m_text_mesh;
|
||||||
std::string m_text;
|
std::string m_text;
|
||||||
std::string m_font = "arial";
|
std::string m_font = "arial";
|
||||||
glm::vec4 m_color{ 1, 1, 1, 1 };
|
glm::vec4 m_color{ 1, 1, 1, 1 };
|
||||||
int m_font_size = 11;
|
int m_font_size = 11;
|
||||||
kFont font_id;
|
kFont font_id;
|
||||||
|
|
||||||
|
bool m_multiline = false;
|
||||||
|
glm::vec2 m_off;
|
||||||
|
TextAlign m_text_align_v = TextAlign::Center;
|
||||||
|
TextAlign m_text_align_h = TextAlign::Begin;
|
||||||
|
|
||||||
virtual Node* clone_instantiate() const override;
|
virtual Node* clone_instantiate() const override;
|
||||||
virtual void clone_copy(Node* dest) const override;
|
virtual void clone_copy(Node* dest) const override;
|
||||||
virtual void create() override;
|
virtual void create() override;
|
||||||
virtual void restore_context() override;
|
|
||||||
virtual void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr) override;
|
virtual void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr) override;
|
||||||
void set_text(const char* s);
|
|
||||||
void set_text_format(const char* fmt, ...);
|
|
||||||
void set_font(kFont fontID);
|
|
||||||
virtual void draw() override;
|
virtual void draw() override;
|
||||||
virtual void handle_resize(glm::vec2 old_size, glm::vec2 new_size, float zoom) override;
|
virtual void handle_resize(glm::vec2 old_size, glm::vec2 new_size, float zoom) override;
|
||||||
|
|
||||||
|
void set_text(const std::string& s);
|
||||||
|
void set_text_format(const char* fmt, ...);
|
||||||
|
void set_font(kFont fontID);
|
||||||
|
void update_layout();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -33,9 +33,6 @@ void NodeTextInput::clone_copy(Node* dest) const
|
|||||||
{
|
{
|
||||||
NodeBorder::clone_copy(dest);
|
NodeBorder::clone_copy(dest);
|
||||||
NodeTextInput* n = static_cast<NodeTextInput*>(dest);
|
NodeTextInput* n = static_cast<NodeTextInput*>(dest);
|
||||||
|
|
||||||
n->m_multiline = m_multiline;
|
|
||||||
|
|
||||||
n->m_text_mesh.max_width = m_text_mesh.max_width;
|
n->m_text_mesh.max_width = m_text_mesh.max_width;
|
||||||
n->m_text_mesh.create();
|
n->m_text_mesh.create();
|
||||||
n->m_text_mesh.update(font_id, m_text);
|
n->m_text_mesh.update(font_id, m_text);
|
||||||
@@ -44,6 +41,7 @@ void NodeTextInput::clone_copy(Node* dest) const
|
|||||||
n->m_color = m_color;
|
n->m_color = m_color;
|
||||||
n->m_font_size = m_font_size;
|
n->m_font_size = m_font_size;
|
||||||
n->font_id = font_id;
|
n->font_id = font_id;
|
||||||
|
n->m_multiline = m_multiline;
|
||||||
n->m_off = m_off;
|
n->m_off = m_off;
|
||||||
n->m_text_align_v = m_text_align_v;
|
n->m_text_align_v = m_text_align_v;
|
||||||
n->m_text_align_h = m_text_align_h;
|
n->m_text_align_h = m_text_align_h;
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ public:
|
|||||||
glm::vec4 m_color{ 1, 1, 1, 1 };
|
glm::vec4 m_color{ 1, 1, 1, 1 };
|
||||||
int m_font_size = 11;
|
int m_font_size = 11;
|
||||||
kFont font_id;
|
kFont font_id;
|
||||||
|
|
||||||
bool m_multiline = false;
|
bool m_multiline = false;
|
||||||
bool m_cursor_visible = false;
|
bool m_cursor_visible = false;
|
||||||
glm::vec2 m_off;
|
glm::vec2 m_off;
|
||||||
|
|||||||
Reference in New Issue
Block a user