diff --git a/data/layout.xml b/data/layout.xml
index 96cfbaa..b520fd3 100644
--- a/data/layout.xml
+++ b/data/layout.xml
@@ -163,6 +163,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -243,33 +257,15 @@
-
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
diff --git a/data/spritesheet.png b/data/spritesheet.png
index a92c234..9364647 100644
Binary files a/data/spritesheet.png and b/data/spritesheet.png differ
diff --git a/engine/app.cpp b/engine/app.cpp
index 72acae1..e94be0b 100644
--- a/engine/app.cpp
+++ b/engine/app.cpp
@@ -13,6 +13,25 @@ App App::I; // singleton
#define SHADER_VERSION "#version 150\n"
#endif
+static std::vector FindAllBrushes(std::string folder)
+{
+ std::vector 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;
+}
+
void App::create()
{
@@ -150,6 +169,23 @@ void App::initLayout()
layout.on_loaded = [&] {
LOG("initializing layout updating after load");
+ static auto icons = FindAllBrushes("data\\Icons\\");
+ if (auto* container = layout[main_id]->find("brushes"))
+ {
+ if (auto* tpl = layout[const_hash("tpl-brush-icon")])
+ {
+ for (auto& i : icons)
+ {
+ NodeButtonCustom* btn = (NodeButtonCustom*)tpl->m_children[0]->clone();
+ NodeImage* img = (NodeImage*)btn->m_children[0].get();
+ img->m_path = "data\\Icons\\" + i;
+ img->m_tex_id = const_hash(img->m_path.c_str());
+ img->create();
+ container->add_child(btn);
+ }
+ }
+ }
+
layout[main_id]->update(width, height, zoom);
LOG("initializing layout components");
sidebar = layout[main_id]->find("sidebar");
diff --git a/engine/layout.cpp b/engine/layout.cpp
index d8c3939..a3826b5 100644
--- a/engine/layout.cpp
+++ b/engine/layout.cpp
@@ -12,6 +12,9 @@ std::map NodeIcon::m_icons;
kEventResult Node::on_event(Event* e)
{
+ if (current_mouse_capture)
+ return current_mouse_capture->on_event(e);
+
kEventResult ret = kEventResult::Available;
for (auto it = m_children.rbegin(); it != m_children.rend(); ++it)
{
@@ -42,7 +45,7 @@ kEventResult Node::on_event(Event* e)
case kEventType::MouseDownR:
case kEventType::MouseUpL:
case kEventType::MouseUpR:
- if (inside && handle_event(e) == kEventResult::Consumed)
+ if ((inside || m_mouse_captured) && handle_event(e) == kEventResult::Consumed)
return kEventResult::Consumed;
break;
case kEventType::MouseMove:
@@ -53,7 +56,7 @@ kEventResult Node::on_event(Event* e)
handle_event(&e2);
}
m_mouse_inside = inside;
- if (inside)
+ if (inside || m_mouse_captured)
ret = handle_event(e);
if (inside_old == true && inside == false)
{
@@ -399,6 +402,13 @@ void Node::load_internal(const tinyxml2::XMLElement* x_node)
n->load_internal(x_child);
break;
}
+ case kWidget::SliderCursor:
+ {
+ auto n = new NodeSliderCursor();
+ add_child(n);
+ n->load_internal(x_child);
+ break;
+ }
case kWidget::PopupMenu:
{
auto n = new NodePopupMenu();
diff --git a/engine/layout.h b/engine/layout.h
index 66f3a62..fa2ab58 100644
--- a/engine/layout.h
+++ b/engine/layout.h
@@ -51,6 +51,7 @@ enum class kWidget : uint16_t
Icon = const_hash("icon"),
Button = const_hash("button"),
ButtonCustom = const_hash("button-custom"),
+ SliderCursor = const_hash("slider-cursor"),
PopupMenu = const_hash("popup-menu"),
Viewport = const_hash("viewport"),
Ref = const_hash("ref"),
@@ -126,6 +127,8 @@ public:
uint16_t m_nodeID;
std::string m_nodeID_s;
std::vector> m_children;
+ Node* current_mouse_capture = nullptr;
+ bool m_mouse_captured = false;
glm::mat4 m_proj;
glm::mat4 m_mvp;
@@ -204,6 +207,11 @@ public:
void SetPositioning(YGPositionType value) { YGNodeStyleSetPositionType(y_node, value); }
void SetAspectRatio(float ar) { YGNodeStyleSetAspectRatio(y_node, ar); }
+ glm::vec2 GetPosition() { return{ YGNodeLayoutGetLeft(y_node), YGNodeLayoutGetTop(y_node) }; }
+ float GetWidth() { return YGNodeLayoutGetWidth(y_node); }
+ float GetHeight() { return YGNodeLayoutGetHeight(y_node); }
+ glm::vec2 GetSize() { return { GetWidth(), GetHeight() }; }
+
glm::vec4 rect_intersection(glm::vec4 a, glm::vec4 b)
{
// convert from [x,y,w,h] to [x1,y1,x2,y1]
@@ -257,6 +265,8 @@ public:
virtual void loaded() { }
void add_child(Node* n);
void remove_child(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; }
// class iterator
// {
@@ -876,3 +886,47 @@ public:
return kEventResult::Consumed;
}
};
+
+class NodeSliderCursor : public NodeButtonCustom
+{
+public:
+ glm::vec2 drag_start;
+ glm::vec2 drag_diff;
+ bool dragging = false;
+ glm::vec2 old_pos;
+ virtual Node* clone_instantiate() const override { return new NodeSliderCursor(); }
+ virtual void clone_copy(Node* dest) const override
+ {
+ NodeButtonCustom::clone_copy(dest);
+ NodeSliderCursor* n = static_cast(dest);
+ }
+ virtual kEventResult handle_event(Event* e) override
+ {
+ NodeBorder::handle_event(e);
+ switch (e->m_type)
+ {
+ case kEventType::MouseDownL:
+ drag_start = ((MouseEvent*)e)->m_pos;
+ dragging = true;
+ mouse_capture();
+ break;
+ case kEventType::MouseUpL:
+ mouse_release();
+ dragging = false;
+ break;
+ case kEventType::MouseMove:
+ if (dragging)
+ {
+ float pw = parent->GetWidth();
+ float w = GetWidth();
+ drag_diff = ((MouseEvent*)e)->m_pos - drag_start;
+ float x = glm::clamp(drag_diff.x, 0, pw - w);
+ SetPosition(x, 0);
+ }
+ break;
+ default:
+ break;
+ }
+ return kEventResult::Consumed;
+ }
+};