add newline feature to the text node, add about window with credits, add about menu with submenus

This commit is contained in:
2018-09-22 19:23:17 +02:00
parent fd8d6ff2d1
commit 3191730c31
18 changed files with 255 additions and 32 deletions

View File

@@ -187,6 +187,7 @@
<ClCompile Include="src\log.cpp" /> <ClCompile Include="src\log.cpp" />
<ClCompile Include="src\main.cpp" /> <ClCompile Include="src\main.cpp" />
<ClCompile Include="src\node.cpp" /> <ClCompile Include="src\node.cpp" />
<ClCompile Include="src\node_about.cpp" />
<ClCompile Include="src\node_border.cpp" /> <ClCompile Include="src\node_border.cpp" />
<ClCompile Include="src\node_button.cpp" /> <ClCompile Include="src\node_button.cpp" />
<ClCompile Include="src\node_button_custom.cpp" /> <ClCompile Include="src\node_button_custom.cpp" />
@@ -302,6 +303,7 @@
<ClInclude Include="src\layout.h" /> <ClInclude Include="src\layout.h" />
<ClInclude Include="src\log.h" /> <ClInclude Include="src\log.h" />
<ClInclude Include="src\node.h" /> <ClInclude Include="src\node.h" />
<ClInclude Include="src\node_about.h" />
<ClInclude Include="src\node_border.h" /> <ClInclude Include="src\node_border.h" />
<ClInclude Include="src\node_button.h" /> <ClInclude Include="src\node_button.h" />
<ClInclude Include="src\node_button_custom.h" /> <ClInclude Include="src\node_button_custom.h" />

View File

@@ -252,6 +252,9 @@
<ClCompile Include="src\version.cpp"> <ClCompile Include="src\version.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\node_about.cpp">
<Filter>Source Files\ui</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="src\app.h"> <ClInclude Include="src\app.h">
@@ -449,6 +452,9 @@
<ClInclude Include="src\version.h"> <ClInclude Include="src\version.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="src\node_about.h">
<Filter>Header Files\ui</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ResourceCompile Include="PanoPainter.rc"> <ResourceCompile Include="PanoPainter.rc">

View File

@@ -56,6 +56,7 @@ add_library(
../src/layout.cpp ../src/layout.cpp
../src/version.cpp ../src/version.cpp
../src/node.cpp ../src/node.cpp
../src/node_about.cpp
../src/node_border.cpp ../src/node_border.cpp
../src/node_button.cpp ../src/node_button.cpp
../src/node_button_custom.cpp ../src/node_button_custom.cpp

View File

@@ -583,6 +583,67 @@
</border> </border>
</layout> </layout>
<!--About window-->
<layout id="about">
<border positioning="absolute" position="0 0" color=".4 .4 .4 .8" width="100%" height="100%" align="center" justify="center">
<border thickness="1" border-color=".2" pad="3" max-width="650">
<border width="100%" height="30" color=".2 .2 .2 .9" dir="row" align="center" justify="center">
<text text="About PanoPainter" font-face="arial" font-size="11"></text>
</border>
<border width="100%" color="0 0 0 .9" pad="10" dir="col">
<!--window content-->
<border color=".2" width="100%" height="300">
<scroll pad="10" margin="5" color=".3 .3 .3 .4" height="100%" dir="col" wrap="0" shrink="1">
<text margin="0 0 0 5" font-face="arial" font-size="11" text=
"
--------------------------------------------------- ABOUT PANOPAINTER -----------------------------------------------------
PanoPainter - Copyright 2018 OmixLab Ltd
Thanks for using PanoPainter.
My name is Omar Mohamed Ali Mudhir and I'm the developer of this unique application.
In the late 2016 Facebook started to make it possible for users to post 360 content
captured from the first 360 cameras born after the advent of the VR to the market.
That's where me and a bounch or artists started to wonder about making art in 360.
I then started coding in my spare time to create something that would have helped
artists in the long process of creating a panoramic painting (panopainting).
Today this software has evolved a lot and reached a mature version ready for early
adopters that want to break the rules of traditional digital art and get into the
future of immersive painting.
Feel free to follow me on:
- Instagram: @panopainter
- Twitter: @panopainter
- Facebook: fb.me/panopainter
------------------------------------------------- FREE SOFTWARE LICENSES -------------------------------------------------
Free brushes:
The free brushes are provided by the freely available Brush Pack v3 from Fenris31
Link: https://www.deviantart.com/fenris31/art/Brush-Pack-v3-549566626
Roboto Font License:
Copyright 2018 OmixLab Ltd
Licensed under the Apache License, Version 2.0 (the 'License');
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an 'AS IS' BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License."/>
</scroll>
</border>
<!--footer buttons-->
<node height="40" grow="1" dir="row" align="flex-end" justify="flex-end">
<button id="btn-ok" text="Ok" width="100" height="30" margin="0 10 0 0"/>
</node>
</border>
</border>
</border>
</layout>
<!--popup menu--> <!--popup menu-->
<layout id="popup-menu"> <layout id="popup-menu">
<popup-menu positioning="absolute" position="100 100" width="150" thickness="1" border-color=".1" color=".4 .4 .4 .8" dir="col"> <popup-menu positioning="absolute" position="100 100" width="150" thickness="1" border-color=".1" color=".4 .4 .4 .8" dir="col">
@@ -611,7 +672,7 @@
<!--file menu--> <!--file menu-->
<layout id="file-menu"> <layout id="file-menu">
<popup-menu positioning="absolute" position="100 100" width="200" thickness="1" border-color=".1" color=".4 .4 .4 .8" dir="col"> <popup-menu positioning="absolute" position="100 100" width="210" thickness="1" border-color=".1" color=".4 .4 .4 .8" dir="col">
<!-- <!--
<button-custom height="30" align="center" color=".2" pad="0 20 0 10" dir="row"> <button-custom height="30" align="center" color=".2" pad="0 20 0 10" dir="row">
<checkbox width="20" height="20"/> <checkbox width="20" height="20"/>
@@ -678,10 +739,10 @@
<icon icon="weather_clouds" width="20"/> <icon icon="weather_clouds" width="20"/>
<text text="Cloud Browse" grow="1" margin="0 0 0 5" font-face="arial" font-size="11"/> <text text="Cloud Browse" grow="1" margin="0 0 0 5" font-face="arial" font-size="11"/>
</button-custom> </button-custom>
<button-custom text="Menu" height="40" align="center" color=".2" pad="0 0 0 10" dir="row"> <!--<button-custom text="Menu" height="40" align="center" color=".2" pad="0 0 0 10" dir="row">
<icon width="20"/> <icon width="20"/>
<text text="Quit" grow="1" margin="0 0 0 5" font-face="arial" font-size="11"/> <text text="Quit" grow="1" margin="0 0 0 5" font-face="arial" font-size="11"/>
</button-custom> </button-custom>-->
</popup-menu> </popup-menu>
</layout> </layout>
@@ -705,13 +766,13 @@
<!--layers menu--> <!--layers menu-->
<layout id="layers-menu"> <layout id="layers-menu">
<popup-menu positioning="absolute" position="100 100" width="250" thickness="1" border-color=".1" color=".4 .4 .4 .8" dir="col"> <popup-menu positioning="absolute" position="100 100" width="270" thickness="1" border-color=".1" color=".4 .4 .4 .8" dir="col">
<button-custom id="layer-clear" height="40" align="center" color=".2" pad="0 0 0 10" dir="row"> <button-custom id="layer-clear" height="40" align="center" color=".2" pad="0 0 0 10" dir="row">
<icon icon="cancel" width="20"/> <icon icon="cancel" width="20"/>
<text id="menu-label" text="Clear layer" margin="0 0 0 5" font-face="arial" font-size="11"/> <text id="menu-label" text="Clear layer" margin="0 0 0 5" font-face="arial" font-size="11"/>
</button-custom> </button-custom>
<button-custom id="clear-grids" height="40" align="center" color=".2" pad="0 0 0 10" dir="row"> <button-custom id="clear-grids" height="40" align="center" color=".2" pad="0 0 0 10" dir="row">
<icon icon="add" width="20"/> <icon icon="bin" width="20"/>
<text text="Clear grids" margin="0 0 0 5" font-face="arial" font-size="11"/> <text text="Clear grids" margin="0 0 0 5" font-face="arial" font-size="11"/>
</button-custom> </button-custom>
<button-custom id="layer-rename" height="40" align="center" color=".2" pad="0 0 0 10" dir="row"> <button-custom id="layer-rename" height="40" align="center" color=".2" pad="0 0 0 10" dir="row">
@@ -729,20 +790,39 @@
<layout id="timelapse-menu"> <layout id="timelapse-menu">
<popup-menu positioning="absolute" position="100 100" width="150" thickness="1" border-color=".1" color=".4 .4 .4 .8" dir="col"> <popup-menu positioning="absolute" position="100 100" width="150" thickness="1" border-color=".1" color=".4 .4 .4 .8" dir="col">
<button-custom id="timelapse-start" height="40" align="center" color=".2" pad="0 0 0 10" dir="row"> <button-custom id="timelapse-start" height="40" align="center" color=".2" pad="0 0 0 10" dir="row">
<icon icon="cancel" width="20"/> <icon icon="camera" width="20"/>
<text id="menu-label" text="Start Recording" margin="0 0 0 5" font-face="arial" font-size="11"/> <text id="menu-label" text="Start Recording" margin="0 0 0 5" font-face="arial" font-size="11"/>
</button-custom> </button-custom>
<button-custom id="timelapse-clear" height="40" align="center" color=".2" pad="0 0 0 10" dir="row"> <button-custom id="timelapse-clear" height="40" align="center" color=".2" pad="0 0 0 10" dir="row">
<icon icon="cancel" width="20"/> <icon icon="bin" width="20"/>
<text id="menu-label" text="Clear Frames" margin="0 0 0 5" font-face="arial" font-size="11"/> <text id="menu-label" text="Clear Frames" margin="0 0 0 5" font-face="arial" font-size="11"/>
</button-custom> </button-custom>
<button-custom id="timelapse-export" height="40" align="center" color=".2" pad="0 0 0 10" dir="row"> <button-custom id="timelapse-export" height="40" align="center" color=".2" pad="0 0 0 10" dir="row">
<icon icon="cancel" width="20"/> <icon icon="film_save" width="20"/>
<text id="menu-label" text="Export MP4" margin="0 0 0 5" font-face="arial" font-size="11"/> <text id="menu-label" text="Export MP4" margin="0 0 0 5" font-face="arial" font-size="11"/>
</button-custom> </button-custom>
</popup-menu> </popup-menu>
</layout> </layout>
<!-- about menu -->
<layout id="about-menu">
<popup-menu positioning="absolute" position="100 100" width="200" thickness="1" border-color=".1" color=".4 .4 .4 .8" dir="col">
<button-custom id="about-doc" height="40" align="center" color=".2" pad="0 0 0 10" dir="row">
<icon icon="help" width="20"/>
<text id="menu-label" text="Help Guide" margin="0 0 0 5" font-face="arial" font-size="11"/>
</button-custom>
<button-custom id="about-app" height="40" align="center" color=".2" pad="0 0 0 10" dir="row">
<icon icon="application_view_gallery" width="20"/>
<text id="menu-label" text="About PanoPainter" margin="0 0 0 5" font-face="arial" font-size="11"/>
</button-custom>
<button-custom id="about-news" height="40" align="center" color=".2" pad="0 0 0 10" dir="row">
<icon icon="bug" width="20"/>
<text id="menu-label" text="What's new?" margin="0 0 0 5" font-face="arial" font-size="11"/>
</button-custom>
</popup-menu>
</layout>
<!--main--> <!--main-->
<layout id="main"> <layout id="main">
<node dir="col" wrap="0" width="100%" height="100%" pad="0"> <node dir="col" wrap="0" width="100%" height="100%" pad="0">
@@ -768,7 +848,7 @@
<text id="txt-rec" text="" font-face="arial" font-size="11" margin="0 10 0 0" color=".6 .6 .6 1"/> <text id="txt-rec" text="" font-face="arial" font-size="11" margin="0 10 0 0" color=".6 .6 .6 1"/>
<text id="txt-memory" text="History memory: 0.00 Mb" font-face="arial" font-size="11" margin="0 5 0 0" color=".6 .6 .6 1"/> <text id="txt-memory" text="History memory: 0.00 Mb" font-face="arial" font-size="11" margin="0 5 0 0" color=".6 .6 .6 1"/>
<button-custom id="btn-clean-memory" margin="0 20 0 0"> <button-custom id="btn-clean-memory" margin="0 20 0 0">
<icon icon="delete" width="20"/> <icon icon="cancel" width="20"/>
</button-custom> </button-custom>
<text id="version" text="PanoPainter" font-face="arial" font-size="11" margin="0 10 0 0" color=".2 .5 1 1"/> <text id="version" text="PanoPainter" font-face="arial" font-size="11" margin="0 10 0 0" color=".2 .5 1 1"/>
</node> </node>
@@ -795,12 +875,10 @@
<button-custom id="menu-timelapse" width="80" height="100%" margin="0 0 0 0" justify="center" align="center" pad="8" color=".1"> <button-custom id="menu-timelapse" width="80" height="100%" margin="0 0 0 0" justify="center" align="center" pad="8" color=".1">
<text text="Timelapse" font-face="arial" font-size="11"/> <text text="Timelapse" font-face="arial" font-size="11"/>
</button-custom> </button-custom>
<!--
<button-custom id="menu-about" width="60" height="100%" margin="0 0 0 0" justify="center" align="center" pad="8" color=".1"> <button-custom id="menu-about" width="60" height="100%" margin="0 0 0 0" justify="center" align="center" pad="8" color=".1">
<text text="About" font-face="arial" font-size="11"/> <text text="About" font-face="arial" font-size="11"/>
</button-custom> </button-custom>
<button id="btn-anim" width="70" height="100%" margin="1 0 0 10" text="Animate"/> <!--<button id="btn-anim" width="70" height="100%" margin="1 0 0 10" text="Animate"/>-->
-->
<node dir="row" justify="center" grow="1"> <node dir="row" justify="center" grow="1">
<button-custom id="btn-pen" width="50" height="100%" margin="0 0 0 5" thickness="1" border-color="0 0 0 1" pad="2"> <button-custom id="btn-pen" width="50" height="100%" margin="0 0 0 5" thickness="1" border-color="0 0 0 1" pad="2">
<image path="data/ui/pen.png" width="100%" height="100%" align="center" justify="flex-end"/> <image path="data/ui/pen.png" width="100%" height="100%" align="center" justify="flex-end"/>

View File

@@ -139,6 +139,8 @@ public:
void init_menu_edit(); void init_menu_edit();
void init_menu_layer(); void init_menu_layer();
void init_menu_timelapse(); void init_menu_timelapse();
void init_menu_about();
void dialog_about();
void dialog_newdoc(); void dialog_newdoc();
void dialog_save(); void dialog_save();
void dialog_save_ver(); void dialog_save_ver();

View File

@@ -3,6 +3,7 @@
#include "node_dialog_open.h" #include "node_dialog_open.h"
#include "node_dialog_browse.h" #include "node_dialog_browse.h"
#include "node_dialog_cloud.h" #include "node_dialog_cloud.h"
#include "node_about.h"
std::shared_ptr<NodeProgressBar> App::show_progress(const std::string& title) std::shared_ptr<NodeProgressBar> App::show_progress(const std::string& title)
{ {
@@ -17,6 +18,17 @@ std::shared_ptr<NodeProgressBar> App::show_progress(const std::string& title)
return pb; return pb;
} }
void App::dialog_about()
{
auto dialog = std::make_shared<NodeAbout>();
dialog->m_manager = &layout;
dialog->init();
dialog->create();
dialog->loaded();
layout[main_id]->add_child(dialog);
layout[main_id]->update();
}
void App::dialog_newdoc() void App::dialog_newdoc()
{ {
auto show_dialog = [this] { auto show_dialog = [this] {

View File

@@ -5,6 +5,7 @@
#include "node_text.h" #include "node_text.h"
#include "node_progress_bar.h" #include "node_progress_bar.h"
#include "node_dialog_picker.h" #include "node_dialog_picker.h"
#include "node_about.h"
using namespace ui; using namespace ui;
@@ -520,6 +521,53 @@ void App::init_menu_timelapse()
} }
} }
void App::init_menu_about()
{
if (auto* menu_file = layout[main_id]->find<NodeButtonCustom>("menu-about"))
{
menu_file->on_click = [=](Node*) {
glm::vec2 pos = menu_file->m_pos + glm::vec2(0, menu_file->m_size.y);
popup = (NodePopupMenu*)layout[const_hash("about-menu")]->m_children[0]->clone();
popup->update();
if (YGNodeStyleGetDirection(layout[main_id]->y_node) == YGDirectionRTL)
pos.x = pos.x - popup->m_size.x + menu_file->m_size.x;
popup->SetPositioning(YGPositionTypeAbsolute);
popup->SetPosition(pos.x, pos.y);
layout[main_id]->add_child(popup);
layout[main_id]->update();
popup->mouse_capture();
popup->m_mouse_ignore = false;
popup->m_flood_events = true;
popup->m_capture_children = false;
popup->find<NodeButtonCustom>("about-app")->on_click = [this](Node*) {
dialog_about();
popup->mouse_release();
popup->destroy();
};
popup->find<NodeButtonCustom>("about-doc")->on_click = [this](Node*) {
popup->mouse_release();
popup->destroy();
};
if (auto item = popup->find<NodeButtonCustom>("about-news"))
{
if (auto text = item->find<NodeText>("menu-label"))
{
static char label[128];
sprintf(label, "What's new in %d.%d.%d?", g_version_major, g_version_minor, g_version_fix);
text->set_text(label);
}
item->on_click = [this](Node*) {
popup->mouse_release();
popup->destroy();
};
}
};
}
}
void App::brush_update() void App::brush_update()
{ {
// brushes->select_brush(canvas->m_brush.id); // brushes->select_brush(canvas->m_brush.id);
@@ -643,6 +691,7 @@ void App::initLayout()
init_menu_edit(); init_menu_edit();
init_menu_layer(); init_menu_layer();
init_menu_timelapse(); init_menu_timelapse();
init_menu_about();
// set version string // set version string
if (auto* version_label = layout[main_id]->find<NodeText>("version")) if (auto* version_label = layout[main_id]->find<NodeText>("version"))
@@ -650,15 +699,6 @@ void App::initLayout()
version_label->set_text(g_version); version_label->set_text(g_version);
} }
if (auto* menu_entry = layout[main_id]->find<NodeButtonCustom>("menu-about"))
{
menu_entry->on_click = [=](Node*) {
// int x = 0;
// sin(time(0) / x);
};
}
Brush b; Brush b;
int br_idx = brushes->find_brush("Round-Hard"); int br_idx = brushes->find_brush("Round-Hard");
b.m_tex_id = brushes->get_texture_id(br_idx); b.m_tex_id = brushes->get_texture_id(br_idx);

View File

@@ -19,6 +19,7 @@ bool Font::load(const char* ttf, int font_size)
stbtt_BakeFontBitmap(file.m_data, 0, (float)font_size*2, bitmap.get(), w, h, start_char, num_chars, chars.data()); stbtt_BakeFontBitmap(file.m_data, 0, (float)font_size*2, bitmap.get(), w, h, start_char, num_chars, chars.data());
font_tex.create(w, h, GL_R8, GL_RED, bitmap.get()); font_tex.create(w, h, GL_R8, GL_RED, bitmap.get());
file.close(); file.close();
size = font_size;
return true; return true;
} }
return false; return false;
@@ -71,6 +72,12 @@ void TextMesh::update(kFont id, const char* text)
glm::vec2 bbmax(-FLT_MAX); glm::vec2 bbmax(-FLT_MAX);
for (int i = 0; i < len; i++) for (int i = 0; i < len; i++)
{ {
if (text[i] == '\n')
{
x = 0;
y += f.size *2;
continue;
}
int c = text[i] - f.start_char; int c = text[i] - f.start_char;
stbtt_aligned_quad q; stbtt_aligned_quad q;
stbtt_GetBakedQuad((stbtt_bakedchar*)f.chars.data(), f.w, f.h, c, &x, &y, &q, true); stbtt_GetBakedQuad((stbtt_bakedchar*)f.chars.data(), f.w, f.h, c, &x, &y, &q, true);
@@ -88,10 +95,8 @@ void TextMesh::update(kFont id, const char* text)
bbmin = glm::min(bbmin, { q.x0/2.f, q.y0/2.f }); bbmin = glm::min(bbmin, { q.x0/2.f, q.y0/2.f });
bbmax = glm::max(bbmax, { q.x1/2.f, q.y1/2.f }); bbmax = glm::max(bbmax, { q.x1/2.f, q.y1/2.f });
} }
for (int i = 0; i < len*4; i++) for (auto& vi : v)
{ vi -= glm::vec4(bbmin, 0, 0);
v[i] -= glm::vec4(bbmin, 0, 0);
}
bb = bbmax - bbmin; bb = bbmax - bbmin;
font_array_count = (int)idx.size(); font_array_count = (int)idx.size();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, font_buffers[1]); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, font_buffers[1]);

View File

@@ -16,6 +16,7 @@ public:
const int h = 512; const int h = 512;
const int num_chars = 96; const int num_chars = 96;
const int start_char = 32; const int start_char = 32;
int size = 0;
stbtt_fontinfo font; stbtt_fontinfo font;
Texture2D font_tex; Texture2D font_tex;
std::vector<stbtt_bakedchar> chars; std::vector<stbtt_bakedchar> chars;

View File

@@ -31,6 +31,7 @@
#include "node_colorwheel.h" #include "node_colorwheel.h"
#include "node_dialog_picker.h" #include "node_dialog_picker.h"
#include "node_panel_grid.h" #include "node_panel_grid.h"
#include "node_about.h"
void Node::async_start() void Node::async_start()
{ {
@@ -897,6 +898,7 @@ void Node::load_internal(const tinyxml2::XMLElement* x_node)
CASE(kWidget::DialogCloudItem, NodeDialogCloudItem); CASE(kWidget::DialogCloudItem, NodeDialogCloudItem);
CASE(kWidget::ColorWheel, NodeColorWheel); CASE(kWidget::ColorWheel, NodeColorWheel);
CASE(kWidget::ColorPicker, NodeColorPicker); CASE(kWidget::ColorPicker, NodeColorPicker);
CASE(kWidget::About, NodeAbout);
#undef CASE #undef CASE
case kWidget::Ref: case kWidget::Ref:
{ {

View File

@@ -81,6 +81,7 @@ enum class kWidget : uint16_t
DialogCloudItem = const_hash("dialog-cloud-item"), DialogCloudItem = const_hash("dialog-cloud-item"),
ColorWheel = const_hash("colorwheel"), ColorWheel = const_hash("colorwheel"),
ColorPicker = const_hash("color-picker"), ColorPicker = const_hash("color-picker"),
About = const_hash("about"),
}; };
class Node class Node

26
src/node_about.cpp Normal file
View File

@@ -0,0 +1,26 @@
#include "pch.h"
#include "log.h"
#include "node_about.h"
#include "layout.h"
Node* NodeAbout::clone_instantiate() const
{
return new NodeAbout();
}
void NodeAbout::init()
{
SetPosition(0, 0);
SetWidthP(100);
SetHeightP(100);
SetPositioning(YGPositionTypeAbsolute);
m_template = (*m_manager)[const_hash("about")]->m_children[0]->clone();
add_child(m_template);
btn_ok = m_template->find<NodeButton>("btn-ok");
btn_ok->on_click = [&](Node*) { destroy(); };
}
kEventResult NodeAbout::handle_event(Event* e)
{
return kEventResult::Consumed;
}

13
src/node_about.h Normal file
View File

@@ -0,0 +1,13 @@
#pragma once
#include "node.h"
#include "node_button.h"
class NodeAbout : public Node
{
Node* m_template;
NodeButton* btn_ok;
public:
virtual Node* clone_instantiate() const override;
virtual void init() override;
virtual kEventResult handle_event(Event* e) override;
};

View File

@@ -3,6 +3,14 @@
#include "node_scroll.h" #include "node_scroll.h"
#include "event.h" #include "event.h"
NodeScroll::NodeScroll()
{
m_drag_start = glm::vec2(0);
m_offset_start = glm::vec2(0);
m_offset = glm::vec2(0);
m_mask = glm::vec2(0, 1);
}
Node* NodeScroll::clone_instantiate() const Node* NodeScroll::clone_instantiate() const
{ {
return new NodeScroll; return new NodeScroll;
@@ -43,7 +51,7 @@ kEventResult NodeScroll::handle_event(Event* e)
m_dragging = false; m_dragging = false;
break; break;
case kEventType::MouseScroll: case kEventType::MouseScroll:
m_offset += me->m_scroll_delta * 50; m_offset += me->m_scroll_delta * 50 * m_mask;
fix_scroll(); fix_scroll();
break; break;
case kEventType::GestureStart: case kEventType::GestureStart:

View File

@@ -4,11 +4,12 @@
class NodeScroll : public NodeBorder class NodeScroll : public NodeBorder
{ {
bool m_dragging = false; bool m_dragging = false;
glm::vec2 m_drag_start; glm::vec2 m_drag_start = glm::vec2(0);
glm::vec2 m_offset_start; glm::vec2 m_offset_start = glm::vec2(0);
glm::vec2 m_offset; glm::vec2 m_offset = glm::vec2(0);
glm::vec2 m_mask{ 0, 1 }; glm::vec2 m_mask = glm::vec2(1, 0);
public: public:
NodeScroll();
virtual Node* clone_instantiate() const override; virtual Node* clone_instantiate() const override;
virtual kEventResult handle_event(Event* e) override; virtual kEventResult handle_event(Event* e) override;
void fix_scroll(); void fix_scroll();

View File

@@ -54,7 +54,7 @@ void NodeText::parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* att
switch (ka) switch (ka)
{ {
case kAttribute::Text: case kAttribute::Text:
m_text = attr->Value(); m_text = unescape(attr->Value());
break; break;
case kAttribute::FontFace: case kAttribute::FontFace:
m_font = attr->Value(); m_font = attr->Value();

View File

@@ -105,6 +105,31 @@ std::vector<std::string> split(const std::string& subject, char d, int max_split
return ret; return ret;
} }
std::string unescape(const std::string& s)
{
std::string res;
std::string::const_iterator it = s.begin();
while (it != s.end())
{
char c = *it++;
if (c == '\\' && it != s.end())
{
switch (*it++) {
case '\\': c = '\\'; break;
case 'n': c = '\n'; break;
case 't': c = '\t'; break;
// all other escapes
default:
// invalid escape sequence - skip it. alternatively you can copy it as is, throw an exception...
continue;
}
}
res += c;
}
return res;
}
static const char* gl2str(GLenum err) static const char* gl2str(GLenum err)
{ {
switch (err) switch (err)

View File

@@ -16,6 +16,7 @@ glm::vec4 rand_color();
glm::vec3 convert_hsv2rgb(const glm::vec3 c); glm::vec3 convert_hsv2rgb(const glm::vec3 c);
glm::vec3 convert_rgb2hsv(const glm::vec3 c); glm::vec3 convert_rgb2hsv(const glm::vec3 c);
std::vector<std::string> split(const std::string& subject, char d, int max_split = 0); std::vector<std::string> split(const std::string& subject, char d, int max_split = 0);
std::string unescape(const std::string& s);
size_t curl_data_handler(void *contents, size_t size, size_t nmemb, void *userp); size_t curl_data_handler(void *contents, size_t size, size_t nmemb, void *userp);
size_t curl_data_write(void *ptr, size_t size, size_t nmemb, FILE *stream); size_t curl_data_write(void *ptr, size_t size, size_t nmemb, FILE *stream);
@@ -26,7 +27,6 @@ inline glm::vec2 zw(const glm::vec4& v) { return glm::vec2(v.z, v.w); }
inline glm::ivec2 xy(const glm::ivec4& v) { return glm::ivec2(v.x, v.y); } inline glm::ivec2 xy(const glm::ivec4& v) { return glm::ivec2(v.x, v.y); }
inline glm::ivec3 xyz(const glm::ivec4& v) { return glm::ivec3(v.x, v.y, v.z); } inline glm::ivec3 xyz(const glm::ivec4& v) { return glm::ivec3(v.x, v.y, v.z); }
inline glm::ivec2 zw(const glm::ivec4& v) { return glm::ivec2(v.z, v.w); } inline glm::ivec2 zw(const glm::ivec4& v) { return glm::ivec2(v.z, v.w); }
inline glm::vec2 xy(const glm::vec3& v) { return glm::vec2(v.x, v.y); } inline glm::vec2 xy(const glm::vec3& v) { return glm::vec2(v.x, v.y); }
template<typename T, int N> struct cbuffer template<typename T, int N> struct cbuffer