added checkbox, slider, layer panel, brushes panel

This commit is contained in:
2017-03-19 23:51:45 +00:00
parent 011aeb8948
commit 03a8266972
5 changed files with 624 additions and 203 deletions

View File

@@ -40,6 +40,7 @@ enum class kAttribute : uint16_t
Positioning = const_hash("positioning"),
FloodEvents = const_hash("flood-events"),
Icon = const_hash("icon"),
Selected = const_hash("selected"),
};
enum class kWidget : uint16_t
@@ -52,9 +53,14 @@ enum class kWidget : uint16_t
Button = const_hash("button"),
ButtonCustom = const_hash("button-custom"),
SliderCursor = const_hash("slider-cursor"),
Slider = const_hash("slider"),
PopupMenu = const_hash("popup-menu"),
Viewport = const_hash("viewport"),
Ref = const_hash("ref"),
CheckBox = const_hash("checkbox"),
Layer = const_hash("layer"),
PanelLayers = const_hash("panel-layers"),
PanelBrushes = const_hash("panel-brushes"),
};
enum class kShapeType : uint16_t
@@ -136,6 +142,7 @@ public:
bool m_flood_events = false;
bool m_destroyed = false;
bool m_mouse_ignore = true;
float m_zoom = 1.f;
glm::vec2 m_scale{ 1.f };
glm::vec2 m_pos;
@@ -161,6 +168,7 @@ public:
m_size = o.m_size;
m_clip = o.m_clip;
m_zoom = o.m_zoom;
m_mouse_ignore = o.m_mouse_ignore;
o.y_node = nullptr;
o.parent = nullptr;
}
@@ -263,8 +271,13 @@ public:
virtual void create() { }
virtual void init() { }
virtual void loaded() { }
const Node* init_template(const char* id);
void add_child(Node* n);
void add_child(Node* n, int index);
void remove_child(Node* n);
void move_child(Node* n, int index);
void move_child_offset(Node* n, int offset);
int get_child_index(Node* n);
void mouse_capture() { root()->current_mouse_capture = this; m_mouse_captured = true; }
void mouse_release() { root()->current_mouse_capture = nullptr; m_mouse_captured = false; }
@@ -309,6 +322,7 @@ public:
glm::vec4 m_color{ 0, 0, 0, 1 };
glm::vec4 m_border_color{ 1, 1, 1, 1 };
float m_thinkness{ 0 };
NodeBorder() { m_mouse_ignore = false; }
static void static_init()
{
m_plane.create<1>(1, 1);
@@ -321,6 +335,7 @@ public:
n->m_color = m_color;
n->m_border_color = m_border_color;
n->m_thinkness = m_thinkness;
n->m_mouse_ignore = false;
}
virtual void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr) override
{
@@ -386,22 +401,25 @@ public:
std::string m_font;
glm::vec4 m_color{ 1, 1, 1, 1 };
int m_font_size;
kFont font_id;
virtual Node* clone_instantiate() const override { return new NodeText(); }
virtual void clone_copy(Node* dest) const override
{
Node::clone_copy(dest);
NodeText* n = static_cast<NodeText*>(dest);
n->m_text_mesh = m_text_mesh;
n->m_text_mesh.create();
n->m_text_mesh.update(font_id, m_text.c_str());
n->m_text = m_text;
n->m_font = m_font;
n->m_color = m_color;
n->m_font_size = m_font_size;
n->font_id = font_id;
}
virtual void create() override
{
char font[64];
sprintf(font, "%s-%d", m_font.c_str(), m_font_size);
kFont font_id = (kFont)const_hash(font);
font_id = (kFont)const_hash(font);
m_text_mesh.create();
m_text_mesh.update(font_id, m_text.c_str());
SetSize(m_text_mesh.bb);
@@ -434,6 +452,12 @@ public:
break;
}
}
void set_text(const char* s)
{
m_text = s;
m_text_mesh.update(font_id, s);
SetSize(m_text_mesh.bb);
}
virtual void draw() override
{
using namespace ui;
@@ -543,7 +567,7 @@ public:
glm::vec4 color_normal{ .1, .1, .1, 1 };
glm::vec4 color_hover{ .2, .2, .2, 1 };
glm::vec4 color_down{ .3, .3, .3, 1 };
std::function<void()> on_click;
std::function<void(Node* target)> on_click;
virtual Node* clone_instantiate() const override { return new NodeButton(); }
virtual void clone_children(Node* dest) const override
{
@@ -562,6 +586,7 @@ public:
n->color_hover = color_hover;
n->color_down = color_down;
//n->on_click = on_click;
n->m_mouse_ignore = false;
}
virtual void init() override
{
@@ -576,17 +601,23 @@ public:
m_text->m_font_size = 11;
m_border->SetAlign(YGAlignCenter);
m_border->SetJustify(YGJustifyCenter);
m_border->m_mouse_ignore = false;
m_mouse_ignore = false;
}
virtual void create() override
{
m_border->create();
m_text->create();
m_border->m_mouse_ignore = false;
m_mouse_ignore = false;
}
virtual void loaded() override
{
m_border->m_thinkness = 1;
m_border->m_border_color = glm::vec4(0, 0, 0, 1);
m_border->m_color = color_normal;
m_border->m_mouse_ignore = false;
m_mouse_ignore = false;
}
virtual void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr) override
{
@@ -614,6 +645,7 @@ public:
}
virtual kEventResult handle_event(Event* e) override
{
Node::handle_event(e);
switch (e->m_type)
{
case kEventType::MouseEnter:
@@ -628,7 +660,7 @@ public:
case kEventType::MouseUpL:
m_border->m_color = color_normal;
if (m_mouse_inside && on_click != nullptr)
on_click();
on_click(this);
break;
default:
break;
@@ -652,7 +684,7 @@ public:
m_template = (*m_manager)[const_hash("message-box")]->m_children[0]->clone();
add_child(m_template);
btnOk = m_template->find<NodeButton>("btn-ok");
btnOk->on_click = [&] { destroy(); };
btnOk->on_click = [&](Node*) { destroy(); };
}
};
@@ -670,6 +702,20 @@ public:
}
virtual kEventResult handle_event(Event* e) override
{
switch (e->m_type)
{
case kEventType::MouseDownL:
if (!m_mouse_inside)
{
mouse_release();
destroy();
}
break;
case kEventType::MouseUpL:
break;
default:
break;
}
return kEventResult::Consumed;
}
};
@@ -677,10 +723,10 @@ public:
class NodeButtonCustom : public NodeBorder
{
public:
glm::vec4 color_normal{ .1, .1, .1, 1 };
glm::vec4 color_hover{ .2, .2, .2, 1 };
glm::vec4 color_down{ .3, .3, .3, 1 };
std::function<void()> on_click;
glm::vec4 color_normal{ .2, .2, .2, 1 };
glm::vec4 color_hover{ .3, .3, .3, 1 };
glm::vec4 color_down{ .4, .4, .4, 1 };
std::function<void(Node* target)> on_click;
virtual Node* clone_instantiate() const override { return new NodeButtonCustom(); }
virtual void clone_copy(Node* dest) const override
{
@@ -689,6 +735,8 @@ public:
n->color_normal = color_normal;
n->color_hover = color_hover;
n->color_down = color_down;
n->m_mouse_ignore = false;
n->m_color = color_normal;
}
virtual void loaded() override
{
@@ -696,6 +744,7 @@ public:
//m_thinkness = 1;
//m_border_color = glm::vec4(0, 0, 0, 1);
m_color = color_normal;
m_mouse_ignore = false;
}
virtual kEventResult handle_event(Event* e) override
{
@@ -712,15 +761,27 @@ public:
m_color = color_down;
break;
case kEventType::MouseUpL:
m_color = color_normal;
m_color = m_mouse_inside ? color_hover : color_normal;
if (m_mouse_inside && on_click != nullptr)
on_click();
on_click(this);
break;
default:
break;
}
return kEventResult::Consumed;
}
virtual void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr) override
{
NodeBorder::parse_attributes(ka, attr);
switch (ka)
{
case kAttribute::Color:
color_normal = m_color;
break;
default:
break;
}
}
};
class NodeSettings : public Node
@@ -738,7 +799,7 @@ public:
m_template = (*m_manager)[const_hash("settings")]->m_children[0]->clone();
add_child(m_template);
btnOk = m_template->find<NodeButton>("btn-ok");
btnOk->on_click = [&] { destroy(); };
btnOk->on_click = [&](Node*) { destroy(); };
}
virtual kEventResult handle_event(Event* e) override
{
@@ -906,6 +967,7 @@ public:
switch (e->m_type)
{
case kEventType::MouseDownL:
old_pos = GetPosition();
drag_start = ((MouseEvent*)e)->m_pos;
dragging = true;
mouse_capture();
@@ -919,7 +981,7 @@ public:
{
float pw = parent->GetWidth();
float w = GetWidth();
drag_diff = ((MouseEvent*)e)->m_pos - drag_start;
drag_diff = old_pos + ((MouseEvent*)e)->m_pos - drag_start;
float x = glm::clamp<float>(drag_diff.x, 0, pw - w);
SetPosition(x, 0);
}
@@ -930,3 +992,327 @@ public:
return kEventResult::Consumed;
}
};
class NodeSlider : public NodeBorder
{
public:
NodeSliderCursor* m_cursor;
virtual Node* clone_instantiate() const override { return new NodeSlider(); }
virtual void init() override
{
const auto& m_template = (NodeBorder*)init_template("tpl-slider");
m_color = m_template->m_color;
m_border_color = m_template->m_border_color;
m_thinkness = m_thinkness;
m_cursor = find<NodeSliderCursor>("cursor");
}
};
class NodeCheckBox : public Node
{
public:
NodeBorder* m_outer;
NodeBorder* m_inner;
bool checked = false;
virtual Node* clone_instantiate() const override { return new NodeCheckBox(); }
virtual void clone_children(Node* dest) const override
{
Node::clone_children(dest);
NodeCheckBox* n = static_cast<NodeCheckBox*>(dest);
n->m_outer = (NodeBorder*)n->m_children[0].get();
n->m_inner = (NodeBorder*)n->m_outer->m_children[0].get();
n->m_mouse_ignore = false;
}
virtual void init() override
{
m_outer = new NodeBorder();
m_inner = new NodeBorder();
add_child(m_outer);
m_outer->add_child(m_inner);
m_outer->init();
m_outer->m_color = { .3, .3, .3, 1 };
m_outer->SetAlign(YGAlignCenter);
m_outer->SetJustify(YGJustifyCenter);
m_outer->SetPadding(5, 5, 5, 5);
m_outer->SetWidthP(100);
m_outer->SetHeightP(100);
m_outer->m_mouse_ignore = false;
m_inner->init();
m_inner->SetWidthP(100);
m_inner->SetHeightP(100);
m_inner->m_border_color = glm::vec4(.8, .8, .8, 1);
m_inner->m_thinkness = 1;
m_inner->m_color = glm::vec4(.8, .8, .8, 1);
m_mouse_ignore = false;
}
virtual void create() override
{
m_outer->create();
m_inner->create();
}
virtual kEventResult handle_event(Event* e) override
{
Node::handle_event(e);
switch (e->m_type)
{
case kEventType::MouseEnter:
break;
case kEventType::MouseLeave:
break;
case kEventType::MouseDownL:
break;
case kEventType::MouseUpL:
checked = !checked;
break;
default:
break;
}
return kEventResult::Consumed;
}
virtual void draw() override
{
m_inner->m_color = checked ? glm::vec4(.4, .4, .4, 1) : glm::vec4(.8, .8, .8, 1);
Node::draw();
}
};
class NodeLayer : public NodeBorder
{
public:
std::function<void(NodeLayer* target)> on_selected;
bool m_selected = false;
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);
std::string m_label_text;
NodeText* m_label;
NodeCheckBox* m_visibility;
virtual Node* clone_instantiate() const override { return new NodeLayer(); }
virtual void clone_children(Node* dest) const override
{
NodeBorder::clone_children(dest);
NodeLayer* n = static_cast<NodeLayer*>(dest);
n->m_label = n->find<NodeText>("label");
n->m_visibility = n->find<NodeCheckBox>("cb");
}
virtual void clone_copy(Node* dest) const override
{
NodeBorder::clone_copy(dest);
NodeLayer* n = (NodeLayer*)dest;
n->m_selected = m_selected;
n->m_label_text = m_label_text;
}
virtual void init() override
{
const auto& m_template = (NodeBorder*)init_template("tpl-layer");
m_color = m_template->m_color;
m_border_color = m_template->m_border_color;
m_thinkness = m_template->m_thinkness;
m_label = find<NodeText>("label");
m_visibility = find<NodeCheckBox>("cb");
}
virtual void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr) override
{
NodeBorder::parse_attributes(ka, attr);
switch (ka)
{
case kAttribute::Text:
m_label_text = attr->Value();
break;
case kAttribute::Selected:
m_selected = attr->BoolValue();
default:
break;
}
}
virtual void loaded() override
{
NodeBorder::loaded();
if (!m_label_text.empty())
m_label->set_text(m_label_text.c_str());
}
virtual kEventResult handle_event(Event* e) override
{
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:
break;
}
return kEventResult::Consumed;
}
virtual void draw() override
{
auto c = m_selected ? m_color_selected : m_color_normal;
m_thinkness = m_selected ? 1 : 0;
m_color = m_mouse_inside ? m_color_hover : c;
NodeBorder::draw();
}
void set_name(const char* s)
{
m_label_text = s;
m_label->set_text(s);
}
};
class NodePanelLayers : public Node
{
NodeButtonCustom* btn_add;
NodeButtonCustom* btn_remove;
NodeButtonCustom* btn_up;
NodeButtonCustom* btn_down;
public:
NodeLayer* m_current_layer = nullptr;
std::vector<NodeLayer*> m_layers;
NodeBorder* m_layers_container;
virtual Node* clone_instantiate() const override { return new NodePanelLayers(); }
virtual void init() override
{
init_template("tpl-panel-layers");
m_layers_container = find<NodeBorder>("layers-container");
for (int i = 0; i < 5; i++)
{
static char s[64];
sprintf(s, "Layer-%d", i);
add_layer(s);
}
m_current_layer = m_layers[0];
m_layers[0]->m_selected = true;
btn_add = find<NodeButtonCustom>("btn-add");
btn_remove = find<NodeButtonCustom>("btn-remove");
btn_up = find<NodeButtonCustom>("btn-up");
btn_down = find<NodeButtonCustom>("btn-down");
btn_add->on_click = [this](Node*) { add_layer("New Layer"); };
btn_remove->on_click = [this](Node*) {
if (m_layers.size() == 1)
return; // dont' delete the last layer
auto it = std::find(m_layers.begin(), m_layers.end(), m_current_layer);
auto i = m_layers_container->get_child_index(m_current_layer);
m_layers_container->remove_child(m_current_layer);
m_layers.erase(it);
i = std::min<int>(i, m_layers.size() - 1);
m_current_layer = m_layers[i];
m_current_layer->m_selected = true;
};
btn_up->on_click = [this](Node*) { m_layers_container->move_child_offset(m_current_layer, -1); };
btn_down->on_click = [this](Node*) { m_layers_container->move_child_offset(m_current_layer, +1); };
}
void add_layer(const char* name)
{
NodeLayer* l = new NodeLayer;
m_layers_container->add_child(l);
l->init();
l->create();
l->loaded();
l->set_name(name);
l->on_selected = std::bind(&NodePanelLayers::handle_layer_selected, this, std::placeholders::_1);
m_layers.push_back(l);
}
void handle_layer_selected(NodeLayer* target)
{
if (m_current_layer)
m_current_layer->m_selected = false;
m_current_layer = target;
m_current_layer->m_selected = true;
}
};
class NodeButtonBrush : public NodeButtonCustom
{
public:
int m_brushID;
bool m_selected = false;
NodeImage* img;
virtual Node* clone_instantiate() const override { return new NodeButtonBrush(); }
virtual void init() override
{
init_template("tpl-brush-icon");
color_hover = glm::vec4(.7, .7, .7, 1);
color_normal = glm::vec4(.3, .3, .3, 1);
m_color = color_normal;
img = (NodeImage*)m_children[0].get();
}
void set_icon(const char* path)
{
img->m_path = path;
img->m_tex_id = const_hash(img->m_path.c_str());
img->create();
}
virtual void draw() override
{
m_color = m_selected ? glm::vec4(1, 0, 0, 1) : color_normal;
NodeButtonCustom::draw();
}
};
class NodePanelBrushes : public Node
{
std::vector<NodeButtonBrush*> m_brushes;
NodeButtonBrush* m_current = nullptr;
Node* m_container;
public:
std::function<void(Node* target, int id)> on_brush_changed;
virtual Node* clone_instantiate() const override { return new NodePanelLayers(); }
virtual void init() override
{
init_template("tpl-panel-brushes");
//m_layers_container = find<NodeBorder>("layers-container");
static auto icons = FindAllBrushes("data\\Icons\\");
if (m_container = find<NodeBorder>("brushes"))
{
int count = 0;
for (auto& i : icons)
{
std::string path = "data\\Icons\\" + i;
NodeButtonBrush* brush = new NodeButtonBrush;
m_container->add_child(brush);
brush->init();
brush->create();
brush->loaded();
brush->set_icon(path.c_str());
brush->m_brushID = count++;
m_brushes.push_back(brush);
brush->on_click = std::bind(&NodePanelBrushes::handle_click, this, std::placeholders::_1);
}
}
}
void handle_click(Node* target)
{
if (target == m_current)
return;
if (m_current)
m_current->m_selected = false;
m_current = (NodeButtonBrush*)target;
m_current->m_selected = true;
on_brush_changed(this, m_current->m_brushID);
}
std::vector<std::string> FindAllBrushes(std::string folder)
{
std::vector<std::string> names;
std::string search_path = folder + "*.png";
WIN32_FIND_DATAA fd;
HANDLE hFind = ::FindFirstFileA(search_path.c_str(), &fd);
if (hFind != INVALID_HANDLE_VALUE) {
do {
// read all (real) files in current folder
// , delete '!' read other 2 default folder . and ..
if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
names.push_back(fd.cFileName);
}
} while (::FindNextFileA(hFind, &fd));
::FindClose(hFind);
}
return names;
}
};