infinipaint/src/GUIStuff/Elements/SelectableButton.cpp

123 lines
4.3 KiB
C++
Raw Normal View History

2025-07-06 20:43:53 +03:00
#include "SelectableButton.hpp"
#include "Helpers/ConvertVec.hpp"
#include "../GUIManager.hpp"
2025-07-06 20:43:53 +03:00
namespace GUIStuff {
SelectableButton::SelectableButton(GUIManager& gui):
Element(gui) {}
void SelectableButton::layout(const Clay_ElementId& id, const Data& d) {
auto& io = gui.io;
SkColor4f borderColor;
SkColor4f backgroundColorHighlight;
SkColor4f backgroundColor;
2026-04-09 16:30:28 +03:00
instantResponse = d.instantResponse;
onClick = [&, this, d] {
if(d.onClickButton)
d.onClickButton(this);
else if(d.onClick) d.onClick();
};
2026-04-28 20:13:47 +03:00
if(isHeld || ((d.isSelected || isHovering) && d.drawType == DrawType::TRANSPARENT_BORDER))
borderColor = io.theme->fillColor1;
else if(d.drawType == DrawType::TRANSPARENT_BORDER)
borderColor = io.theme->backColor2;
else
borderColor = SkColor4f{0.0f, 0.0f, 0.0f, 0.0f};
if(d.isSelected)
backgroundColorHighlight = color_mul_alpha(io.theme->fillColor1, 0.4f);
2026-04-28 20:13:47 +03:00
else if(isHovering || isHeld)
backgroundColorHighlight = color_mul_alpha(io.theme->fillColor1, 0.2f);
else
backgroundColorHighlight = {0.0f, 0.0f, 0.0f, 0.0f};
if(d.drawType == DrawType::TRANSPARENT_ALL || d.drawType == DrawType::TRANSPARENT_BORDER)
backgroundColor = {0.0f, 0.0f, 0.0f, 0.0f};
else if(d.drawType == DrawType::FILLED)
backgroundColor = io.theme->backColor2;
else
backgroundColor = io.theme->fillColor2;
CLAY(id, {.layout = {
.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)},
.childGap = 0,
.childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER }
},
.backgroundColor = convert_vec4<Clay_Color>(backgroundColor),
.cornerRadius = CLAY_CORNER_RADIUS(4),
.border = {
.color = convert_vec4<Clay_Color>(borderColor),
2025-11-04 10:58:26 +03:00
.width = CLAY_BORDER_OUTSIDE(2)
}
}) {
CLAY_AUTO_ID({.layout = {
2025-07-06 20:43:53 +03:00
.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)},
.padding = (d.drawType == DrawType::TRANSPARENT_BORDER) ? CLAY_PADDING_ALL(0) : CLAY_PADDING_ALL(4),
2025-07-06 20:43:53 +03:00
.childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER },
},
.backgroundColor = convert_vec4<Clay_Color>(backgroundColorHighlight),
.cornerRadius = CLAY_CORNER_RADIUS(4)
2025-07-06 20:43:53 +03:00
}) {
if(d.innerContent)
2026-04-28 20:13:47 +03:00
d.innerContent({.isSelected = d.isSelected, .isHovering = isHovering, .isHeld = isHeld});
2025-07-06 20:43:53 +03:00
}
}
}
void SelectableButton::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) {
bool oldIsHeld = isHeld;
isHeld = mouseHovering && button.button == InputManager::MouseButton::LEFT && button.down;
2026-04-09 16:30:28 +03:00
if(isHeld) {
if(instantResponse)
2026-04-09 16:30:28 +03:00
gui.set_post_callback_func(onClick);
gui.set_to_layout();
2026-04-09 16:30:28 +03:00
}
else if(mouseHovering && oldIsHeld && button.button == InputManager::MouseButton::LEFT && !button.down) {
2026-04-09 16:30:28 +03:00
if(!instantResponse)
gui.set_post_callback_func(onClick);
gui.set_to_layout();
}
2026-04-28 20:13:47 +03:00
else if(mouseHovering != isHovering || isHeld != oldIsHeld)
gui.set_to_layout();
2026-04-28 20:13:47 +03:00
isHovering = mouseHovering;
}
void SelectableButton::input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) {
2026-04-28 20:13:47 +03:00
if(mouseHovering != isHovering)
gui.set_to_layout();
2026-04-28 20:13:47 +03:00
isHovering = mouseHovering;
}
void SelectableButton::input_finger_touch_callback(const InputManager::FingerTouchCallbackArgs& touch) {
bool oldIsHeld = isHeld;
bool oldIsHovering = isHovering;
isHeld = mouseHovering && touch.down;
isHovering = mouseHovering && touch.down;
if(isHeld) {
if(instantResponse)
gui.set_post_callback_func(onClick);
gui.set_to_layout();
}
else if(mouseHovering && oldIsHeld && !touch.down) {
if(!instantResponse)
gui.set_post_callback_func(onClick);
gui.set_to_layout();
}
else if(oldIsHovering != isHovering || isHeld != oldIsHeld)
gui.set_to_layout();
}
void SelectableButton::input_finger_motion_callback(const InputManager::FingerMotionCallbackArgs& motion) {
if(isHovering || isHeld) {
isHovering = false;
isHeld = false;
gui.set_to_layout();
}
2025-07-06 20:43:53 +03:00
}
}