From 9d5f07c882e1270783c5d89b3c25e7c160a48d6b Mon Sep 17 00:00:00 2001 From: Odilitime <janesmith@airmail.cc> Date: Tue, 22 Aug 2017 04:28:52 -0700 Subject: [PATCH] onMouseOut relay, cursor property, don't rely on window global/use win property, updateMouse(), renderComponentType() --- src/graphics/components/MultiComponent.cpp | 123 ++++++++++++++++----- src/graphics/components/MultiComponent.h | 22 +++- 2 files changed, 117 insertions(+), 28 deletions(-) diff --git a/src/graphics/components/MultiComponent.cpp b/src/graphics/components/MultiComponent.cpp index b9d209da..177c1e78 100644 --- a/src/graphics/components/MultiComponent.cpp +++ b/src/graphics/components/MultiComponent.cpp @@ -1,7 +1,10 @@ #include "MultiComponent.h" -#include "DocumentComponent.h" #include <iostream> +#include "DocumentComponent.h" +#include "TabbedComponent.h" +#include "AnimeComponent.h" + MultiComponent::MultiComponent(const float rawX, const float rawY, const float rawWidth, const float rawHeight, const int passedWindowWidth, const int passedWindowHeight) { // take our space (for parent picking) @@ -13,35 +16,25 @@ MultiComponent::MultiComponent(const float rawX, const float rawY, const float r // not really needed but nothing else sets this windowWidth = passedWindowWidth; windowHeight = passedWindowHeight; + + // we need a mouseout to mouseout our hovercomponent + onMouseout=[this]() { + if (this->hoverComponent && this->hoverComponent->onMouseout) { + this->hoverComponent->onMouseout(); + } + // select nothing + this->hoverComponent = nullptr; + }; onMousemove=[this](int passedX, int passedY) { - // set hover component - static int lx = 0; - static int ly = 0; //std::cout << "MultiComponent::MultiComponent:onMousemove - at " << passedX << "," << passedY << std::endl; - if (lx == passedX && ly == passedY) { + if (this->cursorX == passedX && this->cursorY == passedY) { return; } - lx = passedX; - ly = passedY; + this->cursorX = passedX; + this->cursorY = passedY; //std::cout << "MultiComponent::MultiComponent:onMousemove - size " << this->windowWidth << "," << this->windowHeight << std::endl; - // we need to make pX/pY relative to this component? - this->hoverComponent = this->searchComponentTree(this->rootComponent, passedX, passedY); - if (this->hoverComponent) { - //std::cout << "MultiComponent::MultiComponent:onMousemove - hovering over " << typeOfComponent(this->hoverComponent) << " component" << std::endl; - if (this->hoverComponent->onMousemove) { - // this could communicate the cursor to use - this->hoverComponent->onMousemove(passedX, passedY); - } else { - if (this->hoverComponent->onClick) { - glfwSetCursor(this->win->window, this->win->cursorHand); - } else { - glfwSetCursor(this->win->window, this->win->cursorIbeam); - } - } - } else { - glfwSetCursor(this->win->window, this->win->cursorArrow); - } + this->updateMouse(); }; onMousedown=[this](int passedX, int passedY) { //std::cout << "MultiComponent left press" << std::endl; @@ -90,11 +83,13 @@ MultiComponent::MultiComponent(const float rawX, const float rawY, const float r // ok we can't communicate through the component //std::cout << "unloaded2 " << this->parent->unloaded << std::endl; // we can through the window global - //std::cout << "win unloaded focus: " << window->focusedComponent << std::endl; - //std::cout << "win unloaded hover: " << window->hoverComponent << std::endl; + //std::cout << "window unloaded focus: " << window->focusedComponent << std::endl; + //std::cout << "window unloaded hover: " << window->hoverComponent << std::endl; + //std::cout << "win unloaded focus: " << this->win->focusedComponent << std::endl; + //std::cout << "win unloaded hover: " << this->win->hoverComponent << std::endl; } // make sure we weren't unloaded by last click and check for additional events - if (window->hoverComponent != nullptr && this->focusedComponent->onClick) { + if (this->win->focusedComponent != nullptr && this->focusedComponent->onClick) { //std::cout << "click event" << std::endl; this->focusedComponent->onClick(); } @@ -158,6 +153,36 @@ MultiComponent::MultiComponent(const float rawX, const float rawY, const float r }; } +// update component hover (need to call on component change) +void MultiComponent::updateMouse() { + // do we need to make pX/pY relative to this component? no, we just made the picking system take mouse coordinates + std::shared_ptr<Component> newHover = this->searchComponentTree(this->rootComponent, this->cursorX, this->cursorY); + if (newHover != this->hoverComponent) { + if (this->hoverComponent && this->hoverComponent->onMouseout) { + this->hoverComponent->onMouseout(); + } + if (newHover && newHover->onMouseover) { + newHover->onMouseover(); + } + this->hoverComponent = newHover; + } + if (this->hoverComponent) { + //std::cout << "MultiComponent::MultiComponent:onMousemove - hovering over " << typeOfComponent(this->hoverComponent) << " component" << std::endl; + if (this->hoverComponent->onMousemove) { + // this could communicate the cursor to use + this->hoverComponent->onMousemove(this->cursorX, this->cursorY); + } else { + if (this->hoverComponent->onClick) { + glfwSetCursor(this->win->window, this->win->cursorHand); + } else { + glfwSetCursor(this->win->window, this->win->cursorIbeam); + } + } + } else { + glfwSetCursor(this->win->window, this->win->cursorArrow); + } +} + //#include "ComponentBuilder.h" void MultiComponent::resize(const int passedWindowWidth, const int passedWindowHeight) { @@ -266,6 +291,50 @@ void MultiComponent::renderBoxComponents(std::shared_ptr<Component> component) { } } +void MultiComponent::renderComponentType(std::string str, std::shared_ptr<Component> component) { + if (!component) { + std::cout << "Window::renderComponentType - got null passed" << std::endl; + return; + } + if (typeOfComponent(component) == str) { + // how slow is this? + if (str == "doc") { + DocumentComponent *docComponent = dynamic_cast<DocumentComponent*>(component.get()); + docComponent->render(); + } else if (str =="tab") { + TabbedComponent *pTabComponent = dynamic_cast<TabbedComponent*>(component.get()); + pTabComponent->render(); + } else if (str =="text") { + TextComponent *textComponent = dynamic_cast<TextComponent*>(component.get()); + textComponent->render(); + } else if (str =="input") { + InputComponent *inputComponent = dynamic_cast<InputComponent*>(component.get()); + inputComponent->render(); + } else if (str =="anime") { + AnimeComponent *animeComponent = dynamic_cast<AnimeComponent*>(component.get()); + animeComponent->render(); + } else if (str =="box") { + //AnimeComponent *animeComponent = dynamic_cast<AnimeComponent*>(component.get()); + //if (!animeComponent) { + BoxComponent *boxComponent = dynamic_cast<BoxComponent*>(component.get()); + boxComponent->render(); + //} + } else { + std::cout << "Unknown type " << str << std::endl; + } + //} else { + //std::cout << "type: " << typeOfComponent(component) << "!=" << str << std::endl; + } + // is this needed? + if (component->children.empty()) { + return; + } + for (std::shared_ptr<Component> &child : component->children) { + this->renderComponentType(str, child); + } +} + + // used for picking std::shared_ptr<Component> MultiComponent::searchComponentTree(const std::shared_ptr<Component> &component, const int passedX, const int passedY) { if (component->children.empty()) { diff --git a/src/graphics/components/MultiComponent.h b/src/graphics/components/MultiComponent.h index 6c1ca812..9cba4faa 100644 --- a/src/graphics/components/MultiComponent.h +++ b/src/graphics/components/MultiComponent.h @@ -11,16 +11,32 @@ // this component is not scrollable class MultiComponent : public Component { public: + // + // Methods + // + MultiComponent(const float rawX, const float rawY, const float rawWidth, const float rawHeight, const int passedWindowWidth, const int passedWindowHeight); + void updateMouse(); void render(); void renderComponents(std::shared_ptr<Component> component); void renderDocumentComponents(std::shared_ptr<Component> component); void renderBoxComponents(std::shared_ptr<Component> component); + void renderComponentType(std::string str, std::shared_ptr<Component> component); void resize(const int passedWindowWidth, const int passedWindowHeight); std::shared_ptr<Component> searchComponentTree(const std::shared_ptr<Component> &component, const int passedX, const int passedY); - std::vector<std::shared_ptr<Component>> layers; + + // + // Properties + // + + // layers will replace rootComponent + std::vector<std::shared_ptr<Component>> layers; // each layer's root component std::shared_ptr<Component> rootComponent = std::make_shared<Component>(); + + // handle to signal that a redraw is needed, and access to shader programs Window *win; + + // tabbed coordinate system? bool tabbed = false; // we'll need a way to pass events down and up @@ -28,6 +44,10 @@ public: // we'll need searchComponentTree for picking std::shared_ptr<Component> hoverComponent = nullptr; std::shared_ptr<Component> focusedComponent = nullptr; + + // if the component tree changes, we'll need these to recalculate hoverComponent + double cursorX = 0; + double cursorY = 0; }; extern const std::unique_ptr<Window> window; -- GitLab