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; + } +};