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

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

View File

@@ -3,6 +3,7 @@
#include "node_dialog_open.h"
#include "node_dialog_browse.h"
#include "node_dialog_cloud.h"
#include "node_about.h"
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;
}
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()
{
auto show_dialog = [this] {

View File

@@ -5,6 +5,7 @@
#include "node_text.h"
#include "node_progress_bar.h"
#include "node_dialog_picker.h"
#include "node_about.h"
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()
{
// brushes->select_brush(canvas->m_brush.id);
@@ -643,6 +691,7 @@ void App::initLayout()
init_menu_edit();
init_menu_layer();
init_menu_timelapse();
init_menu_about();
// set version string
if (auto* version_label = layout[main_id]->find<NodeText>("version"))
@@ -650,15 +699,6 @@ void App::initLayout()
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;
int br_idx = brushes->find_brush("Round-Hard");
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());
font_tex.create(w, h, GL_R8, GL_RED, bitmap.get());
file.close();
size = font_size;
return true;
}
return false;
@@ -71,6 +72,12 @@ void TextMesh::update(kFont id, const char* text)
glm::vec2 bbmax(-FLT_MAX);
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;
stbtt_aligned_quad q;
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 });
bbmax = glm::max(bbmax, { q.x1/2.f, q.y1/2.f });
}
for (int i = 0; i < len*4; i++)
{
v[i] -= glm::vec4(bbmin, 0, 0);
}
for (auto& vi : v)
vi -= glm::vec4(bbmin, 0, 0);
bb = bbmax - bbmin;
font_array_count = (int)idx.size();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, font_buffers[1]);

View File

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

View File

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

View File

@@ -81,6 +81,7 @@ enum class kWidget : uint16_t
DialogCloudItem = const_hash("dialog-cloud-item"),
ColorWheel = const_hash("colorwheel"),
ColorPicker = const_hash("color-picker"),
About = const_hash("about"),
};
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 "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
{
return new NodeScroll;
@@ -43,7 +51,7 @@ kEventResult NodeScroll::handle_event(Event* e)
m_dragging = false;
break;
case kEventType::MouseScroll:
m_offset += me->m_scroll_delta * 50;
m_offset += me->m_scroll_delta * 50 * m_mask;
fix_scroll();
break;
case kEventType::GestureStart:

View File

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

View File

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

View File

@@ -16,6 +16,7 @@ glm::vec4 rand_color();
glm::vec3 convert_hsv2rgb(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::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_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::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::vec2 xy(const glm::vec3& v) { return glm::vec2(v.x, v.y); }
template<typename T, int N> struct cbuffer