Elements detect when children are hovered over

This commit is contained in:
Yousef Khadadeh 2026-04-02 21:57:26 +03:00
parent e3af067972
commit 031c61146b
33 changed files with 153 additions and 185 deletions

View file

@ -20,16 +20,9 @@ void CheckBox::layout(const Clay_ElementId& id, const std::function<bool()>& isT
}) {}
}
void CheckBox::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button, bool mouseHovering) {
isHovering = mouseHovering;
if(isHovering && button.button == InputManager::MouseButton::LEFT && button.down)
void CheckBox::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) {
if(mouseHovering && button.button == InputManager::MouseButton::LEFT && button.down)
gui.set_post_callback_func([&](){if(onClick) onClick();});
return Element::input_mouse_button_callback(button, mouseHovering);
}
void CheckBox::input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion, bool mouseHovering) {
isHovering = mouseHovering;
return Element::input_mouse_motion_callback(motion, mouseHovering);
}
void CheckBox::clay_draw(SkCanvas* canvas, UpdateInputData& io, Clay_RenderCommand* command, bool skiaAA) {
@ -50,7 +43,7 @@ void CheckBox::clay_draw(SkCanvas* canvas, UpdateInputData& io, Clay_RenderComma
}
else {
SkRect checkBox = SkRect::MakeLTRB(-0.45f, -0.45f, 0.45f, 0.45f);
p.setColor4f(convert_vec4<SkColor4f>(isHovering ? io.theme->fillColor1 : io.theme->fillColor2));
p.setColor4f(convert_vec4<SkColor4f>(mouseHovering ? io.theme->fillColor1 : io.theme->fillColor2));
p.setStyle(SkPaint::kStroke_Style);
p.setStrokeWidth(0.15f);
canvas->drawRoundRect(checkBox, 0.25f, 0.25f, p);
@ -77,7 +70,7 @@ void CheckBox::clay_draw(SkCanvas* canvas, UpdateInputData& io, Clay_RenderComma
static BezierEasing anim{0.445, -0.733, 0.575, 1.627};
float lerpTime2 = anim(smooth_two_way_time(hoverAnimation2, io.deltaTime, isHovering, CHECKBOX_ANIMATION_TIME));
float lerpTime2 = anim(smooth_two_way_time(hoverAnimation2, io.deltaTime, mouseHovering, CHECKBOX_ANIMATION_TIME));
std::array<Vector2f, 5> points;

View file

@ -8,13 +8,11 @@ class CheckBox : public Element {
CheckBox(GUIManager& gui);
virtual void clay_draw(SkCanvas* canvas, UpdateInputData& io, Clay_RenderCommand* command, bool skiaAA) override;
virtual void input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button, bool mouseHovering) override;
virtual void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion, bool mouseHovering) override;
virtual void input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) override;
void layout(const Clay_ElementId& id, const std::function<bool()>& isTicked, const std::function<void()>& onClick);
private:
static constexpr float CHECKBOX_ANIMATION_TIME = 0.3;
bool isHovering = false;
float hoverAnimation2 = 0.0;
std::function<bool()> isTicked;
std::function<void()> onClick;

View file

@ -63,8 +63,8 @@ template <typename T> class ColorPicker : public Element {
ColorPicker(GUIManager& gui);
void layout(const Clay_ElementId& id, T* data, bool selectAlpha, const std::function<void()>& onChange);
virtual void clay_draw(SkCanvas* canvas, UpdateInputData& io, Clay_RenderCommand* command, bool skiaAA);
void input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button, bool mouseHovering) override;
void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion, bool mouseHovering) override;
void input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) override;
void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) override;
private:
void update_color_picker_pos(const Vector2f& p);
float get_sv_selection_area_size();

View file

@ -82,7 +82,7 @@ template <typename T> void ColorPicker<T>::clay_draw(SkCanvas* canvas, UpdateInp
canvas->restore();
}
template <typename T> void ColorPicker<T>::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button, bool mouseHovering) {
template <typename T> void ColorPicker<T>::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) {
held = HeldBar::NONE;
if(mouseHovering && button.button == InputManager::MouseButton::LEFT && button.down && boundingBox.has_value()) {
auto& bb = boundingBox.value();
@ -103,12 +103,10 @@ template <typename T> void ColorPicker<T>::input_mouse_button_callback(const Inp
}
}
update_color_picker_pos(button.pos);
Element::input_mouse_button_callback(button, mouseHovering);
}
template <typename T> void ColorPicker<T>::input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion, bool mouseHovering) {
template <typename T> void ColorPicker<T>::input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) {
update_color_picker_pos(motion.pos);
Element::input_mouse_motion_callback(motion, mouseHovering);
}
template <typename T> void ColorPicker<T>::update_color_picker_pos(const Vector2f& p) {

View file

@ -19,18 +19,17 @@ template <typename T> void ColorPickerButton<T>::layout(const Clay_ElementId& id
});
if(isOpen) {
gui.set_z_index(gui.get_z_index() + 1, [&] {
ElementHelpers::top_to_bottom_window_popup_layout(gui, "Color Picker", CLAY_SIZING_FIT(300), CLAY_SIZING_FIT(0), [&, val, data = data]() {
ElementHelpers::top_to_bottom_window_popup_layout(gui, "Color Picker", CLAY_SIZING_FIT(300), CLAY_SIZING_FIT(0), [&, val, data = data](LayoutElement*) {
ElementHelpers::color_picker_items(gui, "c", val, {
.hasAlpha = data.hasAlpha,
.onEdit = data.onEdit
});
}, {
.mouseButton = [&](const InputManager::MouseButtonCallbackArgs& button, bool mouseHovering) {
if(!mouseHovering && button.button == InputManager::MouseButton::LEFT && button.down) {
.mouseButton = [&](LayoutElement* l, const InputManager::MouseButtonCallbackArgs& button) {
if(!l->mouseHovering && button.button == InputManager::MouseButton::LEFT && button.down) {
isOpen = false;
gui.set_to_layout();
}
return mouseHovering;
}
});
});

View file

@ -53,7 +53,7 @@ template <typename T> class DropDown : public Element {
if(isOpen) {
gui.set_z_index(gui.get_z_index() + 1, [&] {
gui.element<LayoutElement>("DROPDOWN", [&](const Clay_ElementId& lId) {
gui.element<LayoutElement>("DROPDOWN", [&](LayoutElement*, const Clay_ElementId& lId) {
Clay_ElementData dropdownElemData = Clay_GetElementData(lId);
float calculatedDropdownMaxHeight = 0.0f;
if(dropdownElemData.found)
@ -87,7 +87,7 @@ template <typename T> class DropDown : public Element {
.clipHorizontal = true,
.elementContent = [&](size_t i) {
bool selectedEntry = static_cast<size_t>(*data) == i;
gui.element<LayoutElement>("elem", [&] (const Clay_ElementId& lId) {
gui.element<LayoutElement>("elem", [&] (LayoutElement*, const Clay_ElementId& lId) {
CLAY(lId, {
.layout = {
.sizing = {.width = CLAY_SIZING_FIXED(250), .height = CLAY_SIZING_FIXED(18)},
@ -117,9 +117,9 @@ template <typename T> class DropDown : public Element {
}
}
}, LayoutElement::Callbacks {
.mouseButton = [&, i](const InputManager::MouseButtonCallbackArgs& button, bool mouseHovering) {
update_hovering_over(i, mouseHovering);
if(mouseHovering && button.button == InputManager::MouseButton::LEFT && button.down) {
.mouseButton = [&, i](LayoutElement* l, const InputManager::MouseButtonCallbackArgs& button) {
update_hovering_over(i, l->mouseHovering);
if(l->mouseHovering && button.button == InputManager::MouseButton::LEFT && button.down) {
gui.set_post_callback_func([&, i] {
*d = i;
isOpen = false;
@ -127,11 +127,9 @@ template <typename T> class DropDown : public Element {
});
gui.set_to_layout();
}
return mouseHovering;
},
.mouseMotion = [&, i](const InputManager::MouseMotionCallbackArgs& motion, bool mouseHovering) {
update_hovering_over(i, mouseHovering);
return mouseHovering;
.mouseMotion = [&, i](LayoutElement* l, const InputManager::MouseMotionCallbackArgs& motion) {
update_hovering_over(i, l->mouseHovering);
}
});
}

View file

@ -6,9 +6,9 @@ namespace GUIStuff {
void Element::tick_update() {}
void Element::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button, bool mouseHovering) { }
void Element::input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion, bool mouseHovering) { }
void Element::input_mouse_wheel_callback(const InputManager::MouseWheelCallbackArgs& wheel, bool mouseHovering) { }
void Element::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) { }
void Element::input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) { }
void Element::input_mouse_wheel_callback(const InputManager::MouseWheelCallbackArgs& wheel) { }
void Element::input_key_callback(const InputManager::KeyCallbackArgs& key) {}
void Element::clay_draw(SkCanvas* canvas, UpdateInputData& io, Clay_RenderCommand* command, bool skiaAA) {}

View file

@ -17,13 +17,17 @@ namespace GUIStuff {
virtual ~Element() = default;
int16_t zIndex;
bool mouseHovering = false;
bool childMouseHovering = false;
Element* parent = nullptr;
virtual void tick_update();
// Return true when mouse obstructs what's behind it
virtual void input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button, bool mouseHovering);
virtual void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion, bool mouseHovering);
virtual void input_mouse_wheel_callback(const InputManager::MouseWheelCallbackArgs& wheel, bool mouseHovering);
virtual void input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button);
virtual void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion);
virtual void input_mouse_wheel_callback(const InputManager::MouseWheelCallbackArgs& wheel);
virtual void input_key_callback(const InputManager::KeyCallbackArgs& key);
protected:
static SCollision::AABB<float> get_bb_from_command(Clay_RenderCommand* command);

View file

@ -5,28 +5,25 @@ namespace GUIStuff {
LayoutElement::LayoutElement(GUIManager& gui): Element(gui) {}
void LayoutElement::layout(const Clay_ElementId& id, const std::function<void(const Clay_ElementId&)>& layout, const Callbacks& c) {
void LayoutElement::layout(const Clay_ElementId& id, const std::function<void(LayoutElement*, const Clay_ElementId&)>& layout, const Callbacks& c) {
this->c = c;
layout(id);
layout(this, id);
}
void LayoutElement::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button, bool mouseHovering) {
if(c.mouseButton) c.mouseButton(button, mouseHovering);
return Element::input_mouse_button_callback(button, mouseHovering);
void LayoutElement::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) {
if(c.mouseButton) c.mouseButton(this, button);
}
void LayoutElement::input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion, bool mouseHovering) {
if(c.mouseMotion) c.mouseMotion(motion, mouseHovering);
return Element::input_mouse_motion_callback(motion, mouseHovering);
void LayoutElement::input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) {
if(c.mouseMotion) c.mouseMotion(this, motion);
}
void LayoutElement::input_mouse_wheel_callback(const InputManager::MouseWheelCallbackArgs& wheel, bool mouseHovering) {
if(c.mouseWheel) c.mouseWheel(wheel, mouseHovering);
return Element::input_mouse_wheel_callback(wheel, mouseHovering);
void LayoutElement::input_mouse_wheel_callback(const InputManager::MouseWheelCallbackArgs& wheel) {
if(c.mouseWheel) c.mouseWheel(this, wheel);
}
void LayoutElement::input_key_callback(const InputManager::KeyCallbackArgs& key) {
if(c.key) c.key(key);
if(c.key) c.key(this, key);
}
}

View file

@ -7,15 +7,15 @@ class LayoutElement : public Element {
public:
LayoutElement(GUIManager& gui);
struct Callbacks {
std::function<void(const InputManager::MouseButtonCallbackArgs& button, bool mouseHovering)> mouseButton;
std::function<void(const InputManager::MouseMotionCallbackArgs& motion, bool mouseHovering)> mouseMotion;
std::function<void(const InputManager::MouseWheelCallbackArgs& wheel, bool mouseHovering)> mouseWheel;
std::function<void(const InputManager::KeyCallbackArgs& key)> key;
std::function<void(LayoutElement* l, const InputManager::MouseButtonCallbackArgs& button)> mouseButton;
std::function<void(LayoutElement* l, const InputManager::MouseMotionCallbackArgs& motion)> mouseMotion;
std::function<void(LayoutElement* l, const InputManager::MouseWheelCallbackArgs& wheel)> mouseWheel;
std::function<void(LayoutElement* l, const InputManager::KeyCallbackArgs& key)> key;
};
void layout(const Clay_ElementId& id, const std::function<void(const Clay_ElementId&)>& layout, const Callbacks& c = {});
virtual void input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button, bool mouseHovering) override;
virtual void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion, bool mouseHovering) override;
virtual void input_mouse_wheel_callback(const InputManager::MouseWheelCallbackArgs& wheel, bool mouseHovering) override;
void layout(const Clay_ElementId& id, const std::function<void(LayoutElement*, const Clay_ElementId&)>& layout, const Callbacks& c = {});
virtual void input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) override;
virtual void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) override;
virtual void input_mouse_wheel_callback(const InputManager::MouseWheelCallbackArgs& wheel) override;
virtual void input_key_callback(const InputManager::KeyCallbackArgs& key) override;
private:
Callbacks c;

View file

@ -30,7 +30,7 @@ template <typename T> class NumberSlider : public Element {
canvas->save();
canvas->translate(bb.min.x(), bb.min.y());
float lerpTimeHover = smooth_two_way_time(hoverAnimation, io.deltaTime, isHovering, io.theme->hoverExpandTime);
float lerpTimeHover = smooth_two_way_time(hoverAnimation, io.deltaTime, mouseHovering, io.theme->hoverExpandTime);
static BezierEasing easeHeight(0.68, -1.55, 0.265, 2.55);
@ -73,19 +73,15 @@ template <typename T> class NumberSlider : public Element {
canvas->restore();
}
virtual void input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button, bool mouseHovering) override {
isHovering = mouseHovering;
isHeld = isHovering && button.button == InputManager::MouseButton::LEFT && button.down;
virtual void input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) override {
isHeld = mouseHovering && button.button == InputManager::MouseButton::LEFT && button.down;
if(isHeld && boundingBox.has_value())
update_slider_pos(button.pos);
Element::input_mouse_button_callback(button, mouseHovering);
}
virtual void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion, bool mouseHovering) override {
isHovering = mouseHovering;
virtual void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) override {
if(isHeld && boundingBox.has_value())
update_slider_pos(motion.pos);
Element::input_mouse_motion_callback(motion, mouseHovering);
}
private:
@ -98,7 +94,6 @@ template <typename T> class NumberSlider : public Element {
}
bool isHeld = false;
bool isHovering = false;
T* data = nullptr;
T minData = 0.0;
T maxData = 1.0;

View file

@ -30,27 +30,23 @@ bool PaintCircleMenu::collides_with_point(const Vector2f& p) const {
return boundingBox.has_value() && SCollision::collide(SCollision::Circle<float>(boundingBox.value().center(), CIRCLE_END), p) && !SCollision::collide(SCollision::Circle<float>(boundingBox.value().center(), PALETTE_START), p);
}
void PaintCircleMenu::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button, bool mouseHovering) {
void PaintCircleMenu::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) {
if(d.mouseButton) d.mouseButton(button, mouseHovering);
isHovering = mouseHovering;
isHeld = isHovering && button.button == InputManager::MouseButton::LEFT && button.down;
isHeld = mouseHovering && button.button == InputManager::MouseButton::LEFT && button.down;
update_paint_circle_menu_mouse_hover(button.pos);
isRotateBarHeld = isRotateBarHovered && isHeld;
update_paint_circle_menu_mouse(button.pos, button.button == InputManager::MouseButton::LEFT && button.down);
Element::input_mouse_button_callback(button, mouseHovering);
}
void PaintCircleMenu::input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion, bool mouseHovering) {
isHovering = mouseHovering;
void PaintCircleMenu::input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) {
update_paint_circle_menu_mouse_hover(motion.pos);
update_paint_circle_menu_mouse(motion.pos, false);
Element::input_mouse_motion_callback(motion, mouseHovering);
}
void PaintCircleMenu::update_paint_circle_menu_mouse_hover(const Vector2f& p) {
float distFromCenter = vec_distance(p, boundingBox.value().center());
isRotateBarHovered = isHovering && distFromCenter > ROTATE_START && distFromCenter < CIRCLE_END;
isColorBarHovered = isHovering && distFromCenter > PALETTE_START && distFromCenter < ROTATE_START;
isRotateBarHovered = mouseHovering && distFromCenter > ROTATE_START && distFromCenter < CIRCLE_END;
isColorBarHovered = mouseHovering && distFromCenter > PALETTE_START && distFromCenter < ROTATE_START;
}
void PaintCircleMenu::update_paint_circle_menu_mouse(const Vector2f& p, bool leftClicked) {

View file

@ -17,14 +17,13 @@ class PaintCircleMenu : public Element {
void layout(const Clay_ElementId& id, const Data& data);
virtual bool collides_with_point(const Vector2f& p) const override;
virtual void clay_draw(SkCanvas* canvas, UpdateInputData& io, Clay_RenderCommand* command, bool skiaAA) override;
virtual void input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button, bool mouseHovering) override;
virtual void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion, bool mouseHovering) override;
virtual void input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) override;
virtual void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) override;
private:
void draw_rotate_bar(SkCanvas* canvas, UpdateInputData& io, bool skiaAA);
void draw_palette_bar(SkCanvas* canvas, UpdateInputData& io, bool skiaAA);
Data d;
unsigned colorSelectionIndex = 0;
bool isHovering = false;
bool isRotateBarHeld = false;
bool isRotateBarHovered = false;
bool isColorBarHovered = false;

View file

@ -15,7 +15,7 @@ void PositionAdjustingPopupMenu::layout(const Clay_ElementId& id, Vector2f popup
popupPos.x() -= bb.width();
}
layoutElement = gui.element<LayoutElement>("popup", [&] (const Clay_ElementId& lId) {
layoutElement = gui.element<LayoutElement>("popup", [&] (LayoutElement*, const Clay_ElementId& lId) {
CLAY(lId, {
.layout = {
.sizing = {.width = CLAY_SIZING_FIT(100), .height = CLAY_SIZING_FIT(0)},

View file

@ -18,16 +18,9 @@ void RadioButton::layout(const Clay_ElementId& id, const std::function<bool()>&
}) {}
}
void RadioButton::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button, bool mouseHovering) {
isHovering = mouseHovering;
if(isHovering && button.button == InputManager::MouseButton::LEFT && button.down)
void RadioButton::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) {
if(mouseHovering && button.button == InputManager::MouseButton::LEFT && button.down)
gui.set_post_callback_func([&] { if(onClick) onClick(); });
Element::input_mouse_button_callback(button, mouseHovering);
}
void RadioButton::input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion, bool mouseHovering) {
isHovering = mouseHovering;
Element::input_mouse_motion_callback(motion, mouseHovering);
}
void RadioButton::clay_draw(SkCanvas* canvas, UpdateInputData& io, Clay_RenderCommand* command, bool skiaAA) {

View file

@ -7,8 +7,7 @@ class RadioButton : public Element {
public:
RadioButton(GUIManager& gui);
virtual void clay_draw(SkCanvas* canvas, UpdateInputData& io, Clay_RenderCommand* command, bool skiaAA) override;
virtual void input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button, bool mouseHovering) override;
virtual void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion, bool mouseHovering) override;
virtual void input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) override;
void layout(const Clay_ElementId& id, const std::function<bool()>& isTicked, const std::function<void()>& onClick);
private:

View file

@ -34,25 +34,23 @@ float RotateWheel::wheel_end() {
return boundingBox.value().width() * 0.5f;
}
void RotateWheel::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button, bool mouseHovering) {
isHovering = mouseHovering;
isHeld = isHovering && button.button == InputManager::MouseButton::LEFT && button.down;
void RotateWheel::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) {
isHeld = mouseHovering && button.button == InputManager::MouseButton::LEFT && button.down;
update_rotate_wheel_mouse_hover(button.pos);
isRotateBarHeld = isRotateBarHovered && isHeld;
update_rotate_wheel_mouse(button.pos);
Element::input_mouse_button_callback(button, mouseHovering);
Element::input_mouse_button_callback(button);
}
void RotateWheel::input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion, bool mouseHovering) {
isHovering = mouseHovering;
void RotateWheel::input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) {
update_rotate_wheel_mouse_hover(motion.pos);
update_rotate_wheel_mouse(motion.pos);
Element::input_mouse_motion_callback(motion, mouseHovering);
Element::input_mouse_motion_callback(motion);
}
void RotateWheel::update_rotate_wheel_mouse_hover(const Vector2f& p) {
float distFromCenter = vec_distance(p, boundingBox.value().center());
isRotateBarHovered = isHovering && distFromCenter > wheel_start() && distFromCenter < wheel_end();
isRotateBarHovered = mouseHovering && distFromCenter > wheel_start() && distFromCenter < wheel_end();
}
void RotateWheel::update_rotate_wheel_mouse(const Vector2f& p) {

View file

@ -8,8 +8,8 @@ class RotateWheel : public Element {
RotateWheel(GUIManager& gui);
void layout(const Clay_ElementId& id, double* rotateAngle, const std::function<void()>& onChange);
virtual void clay_draw(SkCanvas* canvas, UpdateInputData& io, Clay_RenderCommand* command, bool skiaAA) override;
virtual void input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button, bool mouseHovering) override;
virtual void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion, bool mouseHovering) override;
virtual void input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) override;
virtual void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) override;
private:
float wheel_start();
@ -18,7 +18,6 @@ class RotateWheel : public Element {
double* rotateAngle = nullptr;
bool isHeld = false;
bool isHovering = false;
bool isRotateBarHeld = false;
bool isRotateBarHovered = false;
std::function<void()> onChange;

View file

@ -48,7 +48,7 @@ void ScrollArea::layout(const Clay_ElementId& id, const Options& options) {
float scrollerPos = std::fabs(scrollOffset.y() / scrollPosMax);
float areaAboveScrollerSize = scrollerPos * (sAreaDim - scrollerSize);
gui.element<LayoutElement>("scroll bar", [&] (const Clay_ElementId& lId) {
gui.element<LayoutElement>("scroll bar", [&] (LayoutElement*, const Clay_ElementId& lId) {
CLAY(lId, {
.layout = {
.sizing = {.width = CLAY_SIZING_FIXED(12), .height = CLAY_SIZING_GROW(0)},
@ -71,28 +71,27 @@ void ScrollArea::layout(const Clay_ElementId& id, const Options& options) {
}
}) {}
gui.element<LayoutElement>("scroller", [&] (const Clay_ElementId& lId2) {
gui.element<LayoutElement>("scroller", [&] (LayoutElement*, const Clay_ElementId& lId2) {
CLAY(lId2, {
.layout = {.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(scrollerSize)}},
.backgroundColor = convert_vec4<Clay_Color>(scrollerColor),
.cornerRadius = CLAY_CORNER_RADIUS(3),
}) {}
}, LayoutElement::Callbacks{
.mouseMotion = [&] (const InputManager::MouseMotionCallbackArgs& motion, bool mouseHovering) {
if(isHoveringOverScrollerY != mouseHovering) {
isHoveringOverScrollerY = mouseHovering;
.mouseMotion = [&] (LayoutElement* t, const InputManager::MouseMotionCallbackArgs& motion) {
if(isHoveringOverScrollerY != t->mouseHovering) {
isHoveringOverScrollerY = t->mouseHovering;
gui.set_to_layout();
}
return mouseHovering;
}
});
CLAY_AUTO_ID({ .layout = {.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)}}}) {}
}
}, LayoutElement::Callbacks{
.mouseButton = [&, scrollPosMax, sAreaStart, sAreaDim, scrollerSize, areaAboveScrollerSize](const InputManager::MouseButtonCallbackArgs& button, bool mouseHovering) {
.mouseButton = [&, scrollPosMax, sAreaStart, sAreaDim, scrollerSize, areaAboveScrollerSize](LayoutElement* t, const InputManager::MouseButtonCallbackArgs& button) {
if(button.button == InputManager::MouseButton::LEFT) {
if(button.down && mouseHovering) {
if(button.down && t->mouseHovering) {
isScrollbarHeldY = true;
if(isHoveringOverScrollerY)
scrollerStartPosY = sAreaStart + areaAboveScrollerSize + scrollerSize * 0.5f;
@ -112,11 +111,10 @@ void ScrollArea::layout(const Clay_ElementId& id, const Options& options) {
gui.set_to_layout();
}
}
return mouseHovering;
},
.mouseMotion = [&, scrollPosMax, sAreaStart, sAreaDim, scrollerSize](const InputManager::MouseMotionCallbackArgs& motion, bool mouseHovering) {
if(isScrollbarHoveredY != mouseHovering) {
isScrollbarHoveredY = mouseHovering;
.mouseMotion = [&, scrollPosMax, sAreaStart, sAreaDim, scrollerSize](LayoutElement* t, const InputManager::MouseMotionCallbackArgs& motion) {
if(isScrollbarHoveredY != t->mouseHovering) {
isScrollbarHoveredY = t->mouseHovering;
gui.set_to_layout();
}
if(isScrollbarHeldY) {
@ -131,7 +129,6 @@ void ScrollArea::layout(const Clay_ElementId& id, const Options& options) {
if(oldScrollOffset != scrollOffset.y())
gui.set_to_layout();
}
return mouseHovering;
}
});
}
@ -147,7 +144,7 @@ void ScrollArea::clamp_scroll() {
scrollOffset.y() = std::clamp(scrollOffset.y(), -std::max(0.0f, contentDimensions.y() - containerDimensions.y()), 0.0f);
}
void ScrollArea::input_mouse_wheel_callback(const InputManager::MouseWheelCallbackArgs& wheel, bool mouseHovering) {
void ScrollArea::input_mouse_wheel_callback(const InputManager::MouseWheelCallbackArgs& wheel) {
if(mouseHovering) {
Vector2f oldScrollOffset = scrollOffset;
@ -160,7 +157,6 @@ void ScrollArea::input_mouse_wheel_callback(const InputManager::MouseWheelCallba
if(oldScrollOffset != scrollOffset)
gui.set_to_layout();
}
Element::input_mouse_wheel_callback(wheel, mouseHovering);
}
}

View file

@ -28,7 +28,7 @@ class ScrollArea : public Element {
void layout(const Clay_ElementId& id, const Options& options);
void reset_scroll();
virtual void input_mouse_wheel_callback(const InputManager::MouseWheelCallbackArgs& wheel, bool mouseHovering) override;
virtual void input_mouse_wheel_callback(const InputManager::MouseWheelCallbackArgs& wheel) override;
private:
Options opts;
bool isScrollbarHeldY = false;

View file

@ -16,7 +16,7 @@ void SelectableButton::layout(const Clay_ElementId& id, const Data& d) {
onClick = d.onClick;
if(isHeld || ((d.isSelected || isHovering) && d.drawType == DrawType::TRANSPARENT_BORDER))
if(isHeld || ((d.isSelected || mouseHovering) && d.drawType == DrawType::TRANSPARENT_BORDER))
borderColor = io.theme->fillColor1;
else if(d.drawType == DrawType::TRANSPARENT_BORDER)
borderColor = io.theme->backColor2;
@ -25,7 +25,7 @@ void SelectableButton::layout(const Clay_ElementId& id, const Data& d) {
if(d.isSelected)
backgroundColorHighlight = color_mul_alpha(io.theme->fillColor1, 0.4f);
else if(isHovering || isHeld)
else if(mouseHovering || isHeld)
backgroundColorHighlight = color_mul_alpha(io.theme->fillColor1, 0.2f);
else
backgroundColorHighlight = {0.0f, 0.0f, 0.0f, 0.0f};
@ -58,31 +58,27 @@ void SelectableButton::layout(const Clay_ElementId& id, const Data& d) {
.cornerRadius = CLAY_CORNER_RADIUS(4)
}) {
if(d.innerContent)
d.innerContent({.isSelected = d.isSelected, .isHovering = isHovering, .isHeld = isHeld});
d.innerContent({.isSelected = d.isSelected, .isHovering = mouseHovering, .isHeld = isHeld});
}
}
}
void SelectableButton::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button, bool mouseHovering) {
bool oldIsHovering = isHovering;
void SelectableButton::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) {
bool oldIsHeld = isHeld;
isHovering = mouseHovering;
isHeld = isHovering && button.button == InputManager::MouseButton::LEFT && button.down;
isHeld = mouseHovering && button.button == InputManager::MouseButton::LEFT && button.down;
if(isHeld) {
gui.set_post_callback_func([&]{ if(onClick) onClick(); });
gui.set_to_layout();
}
else if(isHovering != oldIsHovering || isHeld != oldIsHeld)
else if(mouseHovering != oldIsHovering || isHeld != oldIsHeld)
gui.set_to_layout();
Element::input_mouse_button_callback(button, mouseHovering);
oldIsHovering = mouseHovering;
}
void SelectableButton::input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion, bool mouseHovering) {
bool oldIsHovering = isHovering;
isHovering = mouseHovering;
if(isHovering != oldIsHovering)
void SelectableButton::input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) {
if(mouseHovering != oldIsHovering)
gui.set_to_layout();
Element::input_mouse_motion_callback(motion, mouseHovering);
oldIsHovering = mouseHovering;
}
}

View file

@ -27,12 +27,12 @@ class SelectableButton : public Element {
SelectableButton(GUIManager& gui);
void layout(const Clay_ElementId& id, const Data& d);
virtual void input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button, bool mouseHovering) override;
virtual void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion, bool mouseHovering) override;
virtual void input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) override;
virtual void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) override;
private:
bool isHovering = false;
bool isHeld = false;
bool oldIsHovering = false;
std::function<void()> onClick;
};

View file

@ -26,8 +26,8 @@ template <typename T> class TextBox : public Element {
void layout(const Clay_ElementId& id, const TextBoxData<T>& userInfo);
virtual void clay_draw(SkCanvas* canvas, UpdateInputData& io, Clay_RenderCommand* command, bool skiaAA) override;
virtual void input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button, bool mouseHovering) override;
virtual void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion, bool mouseHovering) override;
virtual void input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) override;
virtual void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) override;
virtual void input_key_callback(const InputManager::KeyCallbackArgs& key) override;
~TextBox();
private:

View file

@ -61,7 +61,7 @@ template <typename T> void TextBox<T>::clay_draw(SkCanvas* canvas, UpdateInputDa
canvas->restore();
}
template <typename T> void TextBox<T>::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button, bool mouseHovering) {
template <typename T> void TextBox<T>::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) {
auto& io = gui.io;
if(button.button == InputManager::MouseButton::LEFT && boundingBox.has_value()) {
@ -84,13 +84,11 @@ template <typename T> void TextBox<T>::input_mouse_button_callback(const InputMa
textbox->process_mouse_left_button(*cur, button.pos - boundingBox.value().min, 0, false, gui.io.input->key(InputManager::KEY_TEXT_SHIFT).held);
}
}
Element::input_mouse_button_callback(button, mouseHovering);
}
template <typename T> void TextBox<T>::input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion, bool mouseHovering) {
template <typename T> void TextBox<T>::input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) {
if(boundingBox.has_value())
textbox->process_mouse_left_button(*cur, motion.pos - boundingBox.value().min, 0, gui.io.input->mouse.leftDown, gui.io.input->key(InputManager::KEY_TEXT_SHIFT).held);
Element::input_mouse_motion_callback(motion, mouseHovering);
}
template <typename T> void TextBox<T>::input_key_callback(const InputManager::KeyCallbackArgs& key) {