Fixed dropdown
This commit is contained in:
parent
f944cb8a68
commit
b50cab2d33
11 changed files with 135 additions and 96 deletions
|
|
@ -94,6 +94,7 @@ bool GUIHolder::load_theme(const std::filesystem::path& configPath, const std::s
|
|||
void GUIHolder::update() {
|
||||
calculate_final_gui_scale();
|
||||
gui.update_window({0, 0}, main.window.size.cast<float>(), final_gui_scale());
|
||||
gui.io.deltaTime = main.deltaTime;
|
||||
gui.layout_if_necessary();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ void top_to_bottom_window_popup_layout(GUIManager& gui, const char* id, Clay_Siz
|
|||
},
|
||||
.backgroundColor = convert_vec4<Clay_Color>(gui.io.theme->backColor1),
|
||||
.cornerRadius = CLAY_CORNER_RADIUS(10),
|
||||
.floating = { .zIndex = gui.zIndex, .attachTo = CLAY_ATTACH_TO_PARENT },
|
||||
.floating = { .zIndex = gui.get_z_index(), .attachTo = CLAY_ATTACH_TO_PARENT },
|
||||
.border = {.color = convert_vec4<Clay_Color>(gui.io.theme->fillColor2), .width = CLAY_BORDER_OUTSIDE(1)}
|
||||
}) {
|
||||
innerContent();
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ void paint_circle_popup_menu(GUIManager& gui, const char* id, const Vector2f& ce
|
|||
},
|
||||
.floating = {
|
||||
.offset = {centerPos.x() - size * 0.5f, centerPos.y() - size * 0.5f},
|
||||
.zIndex = gui.zIndex,
|
||||
.zIndex = gui.get_z_index(),
|
||||
.attachTo = CLAY_ATTACH_TO_ROOT
|
||||
}
|
||||
}) {
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ void scroll_area_many_entries(GUIManager& gui, const char* id, const ScrollBarMa
|
|||
.clipHorizontal = options.clipHorizontal,
|
||||
.clipVertical = true,
|
||||
.showScrollbarY = true,
|
||||
.innerContent = [&, options](const ScrollArea::InnerContentParameters& params) {
|
||||
options.innerContentExtraCallback(params);
|
||||
.innerContent = [&](const ScrollArea::InnerContentParameters& params) {
|
||||
if(options.innerContentExtraCallback) options.innerContentExtraCallback(params);
|
||||
|
||||
float absScrollAmount = std::fabs(params.scrollOffset.y());
|
||||
size_t startPoint = absScrollAmount / options.entryHeight;
|
||||
|
|
|
|||
|
|
@ -18,22 +18,22 @@ template <typename T> void ColorPickerButton<T>::layout(const Clay_ElementId& id
|
|||
}
|
||||
});
|
||||
if(isOpen) {
|
||||
gui.zIndex++;
|
||||
ElementHelpers::top_to_bottom_window_popup_layout(gui, "Color Picker", CLAY_SIZING_FIT(300), CLAY_SIZING_FIT(0), [&, val, data = data]() {
|
||||
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) {
|
||||
isOpen = false;
|
||||
gui.set_to_layout();
|
||||
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::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) {
|
||||
isOpen = false;
|
||||
gui.set_to_layout();
|
||||
}
|
||||
return mouseHovering;
|
||||
}
|
||||
return mouseHovering;
|
||||
}
|
||||
});
|
||||
});
|
||||
gui.zIndex--;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ template <typename T> class DropDown : public Element {
|
|||
DropDown(GUIManager& gui): Element(gui) {}
|
||||
void layout(const Clay_ElementId& id, T* data, const std::vector<std::string>& selections, const DropdownOptions& options = {}) {
|
||||
opts = options;
|
||||
d = data;
|
||||
ElementHelpers::left_to_right_layout(gui, CLAY_SIZING_FIXED(opts.width), CLAY_SIZING_FIT(0), [&] {
|
||||
gui.element<SelectableButton>("dropdown", SelectableButton::Data{
|
||||
.drawType = SelectableButton::DrawType::FILLED,
|
||||
|
|
@ -51,85 +52,93 @@ template <typename T> class DropDown : public Element {
|
|||
});
|
||||
|
||||
if(isOpen) {
|
||||
Clay_ElementId localID = CLAY_ID_LOCAL("DROPDOWN");
|
||||
Clay_ElementData dropdownElemData = Clay_GetElementData(localID);
|
||||
float calculatedDropdownMaxHeight = 0.0f;
|
||||
if(dropdownElemData.found)
|
||||
calculatedDropdownMaxHeight = std::max(gui.io.windowSize.y() - dropdownElemData.boundingBox.y - 2.0f, 0.0f);
|
||||
CLAY(localID, {
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_FIXED(opts.width), .height = CLAY_SIZING_FIT(0, calculatedDropdownMaxHeight)},
|
||||
.childGap = 0
|
||||
},
|
||||
.backgroundColor = convert_vec4<Clay_Color>(gui.io.theme->backColor1),
|
||||
.cornerRadius = CLAY_CORNER_RADIUS(4),
|
||||
.floating = {
|
||||
.offset = {
|
||||
.y = 4
|
||||
},
|
||||
.attachPoints = {
|
||||
.element = CLAY_ATTACH_POINT_LEFT_TOP,
|
||||
.parent = CLAY_ATTACH_POINT_LEFT_BOTTOM
|
||||
},
|
||||
.attachTo = CLAY_ATTACH_TO_PARENT
|
||||
},
|
||||
.border = {
|
||||
.color = convert_vec4<Clay_Color>(gui.io.theme->fillColor2),
|
||||
.width = CLAY_BORDER_OUTSIDE(1)
|
||||
}
|
||||
}) {
|
||||
ElementHelpers::scroll_area_many_entries(gui, "dropdown scroll area", {
|
||||
.entryHeight = 18.0f,
|
||||
.entryCount = selections.size(),
|
||||
.clipHorizontal = true,
|
||||
.elementContent = [&](size_t i) {
|
||||
bool selectedEntry = static_cast<size_t>(*data) == i;
|
||||
gui.element<LayoutElement>("elem", [&] (const Clay_ElementId& lId) {
|
||||
CLAY(lId, {
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_FIXED(250), .height = CLAY_SIZING_FIXED(18)},
|
||||
.padding = CLAY_PADDING_ALL(0),
|
||||
.childGap = 0,
|
||||
.childAlignment = {.x = CLAY_ALIGN_X_LEFT, .y = CLAY_ALIGN_Y_CENTER},
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM
|
||||
}
|
||||
}) {
|
||||
SkColor4f entryColor;
|
||||
if(selectedEntry)
|
||||
entryColor = gui.io.theme->backColor2;
|
||||
else if(hoveringOver.has_value() && hoveringOver.value() == i)
|
||||
entryColor = gui.io.theme->backColor2;
|
||||
else
|
||||
entryColor = gui.io.theme->backColor1;
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)},
|
||||
.padding = {.left = 2, .right = 2, .top = 0, .bottom = 0},
|
||||
.childGap = 0,
|
||||
.childAlignment = {.x = CLAY_ALIGN_X_LEFT, .y = CLAY_ALIGN_Y_CENTER}
|
||||
},
|
||||
.backgroundColor = convert_vec4<Clay_Color>(entryColor)
|
||||
}) {
|
||||
ElementHelpers::text_label(gui, selections[i]);
|
||||
}
|
||||
}
|
||||
}, LayoutElement::Callbacks {
|
||||
.mouseButton = [&, i](const InputManager::MouseButtonCallbackArgs& button, bool mouseHovering) {
|
||||
update_hovering_over(i, mouseHovering);
|
||||
if(mouseHovering && button.button == InputManager::MouseButton::LEFT && button.down) {
|
||||
gui.set_post_callback_func([&] { opts.onClick(); });
|
||||
gui.set_to_layout();
|
||||
}
|
||||
return mouseHovering;
|
||||
gui.set_z_index(gui.get_z_index() + 1, [&] {
|
||||
gui.element<LayoutElement>("DROPDOWN", [&](const Clay_ElementId& lId) {
|
||||
Clay_ElementData dropdownElemData = Clay_GetElementData(lId);
|
||||
float calculatedDropdownMaxHeight = 0.0f;
|
||||
if(dropdownElemData.found)
|
||||
calculatedDropdownMaxHeight = std::max(gui.io.windowSize.y() - dropdownElemData.boundingBox.y - 2.0f, 0.0f);
|
||||
CLAY(lId, {
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_FIXED(opts.width), .height = CLAY_SIZING_FIT(0, calculatedDropdownMaxHeight)},
|
||||
.childGap = 0
|
||||
},
|
||||
.backgroundColor = convert_vec4<Clay_Color>(gui.io.theme->backColor1),
|
||||
.cornerRadius = CLAY_CORNER_RADIUS(4),
|
||||
.floating = {
|
||||
.offset = {
|
||||
.y = 4
|
||||
},
|
||||
.mouseMotion = [&, i](const InputManager::MouseMotionCallbackArgs& motion, bool mouseHovering) {
|
||||
update_hovering_over(i, mouseHovering);
|
||||
return mouseHovering;
|
||||
.zIndex = gui.get_z_index(),
|
||||
.attachPoints = {
|
||||
.element = CLAY_ATTACH_POINT_LEFT_TOP,
|
||||
.parent = CLAY_ATTACH_POINT_LEFT_BOTTOM
|
||||
},
|
||||
.attachTo = CLAY_ATTACH_TO_PARENT
|
||||
},
|
||||
.border = {
|
||||
.color = convert_vec4<Clay_Color>(gui.io.theme->fillColor2),
|
||||
.width = CLAY_BORDER_OUTSIDE(1)
|
||||
}
|
||||
}) {
|
||||
ElementHelpers::scroll_area_many_entries(gui, "dropdown scroll area", {
|
||||
.entryHeight = 18.0f,
|
||||
.entryCount = selections.size(),
|
||||
.clipHorizontal = true,
|
||||
.elementContent = [&](size_t i) {
|
||||
bool selectedEntry = static_cast<size_t>(*data) == i;
|
||||
gui.element<LayoutElement>("elem", [&] (const Clay_ElementId& lId) {
|
||||
CLAY(lId, {
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_FIXED(250), .height = CLAY_SIZING_FIXED(18)},
|
||||
.padding = CLAY_PADDING_ALL(0),
|
||||
.childGap = 0,
|
||||
.childAlignment = {.x = CLAY_ALIGN_X_LEFT, .y = CLAY_ALIGN_Y_CENTER},
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM
|
||||
}
|
||||
}) {
|
||||
SkColor4f entryColor;
|
||||
if(selectedEntry)
|
||||
entryColor = gui.io.theme->backColor2;
|
||||
else if(hoveringOver.has_value() && hoveringOver.value() == i)
|
||||
entryColor = gui.io.theme->backColor2;
|
||||
else
|
||||
entryColor = gui.io.theme->backColor1;
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)},
|
||||
.padding = {.left = 2, .right = 2, .top = 0, .bottom = 0},
|
||||
.childGap = 0,
|
||||
.childAlignment = {.x = CLAY_ALIGN_X_LEFT, .y = CLAY_ALIGN_Y_CENTER}
|
||||
},
|
||||
.backgroundColor = convert_vec4<Clay_Color>(entryColor)
|
||||
}) {
|
||||
ElementHelpers::text_label(gui, selections[i]);
|
||||
}
|
||||
}
|
||||
}, LayoutElement::Callbacks {
|
||||
.mouseButton = [&, i](const InputManager::MouseButtonCallbackArgs& button, bool mouseHovering) {
|
||||
update_hovering_over(i, mouseHovering);
|
||||
if(mouseHovering && button.button == InputManager::MouseButton::LEFT && button.down) {
|
||||
gui.set_post_callback_func([&, i] {
|
||||
*d = i;
|
||||
isOpen = false;
|
||||
opts.onClick();
|
||||
});
|
||||
gui.set_to_layout();
|
||||
}
|
||||
return mouseHovering;
|
||||
},
|
||||
.mouseMotion = [&, i](const InputManager::MouseMotionCallbackArgs& motion, bool mouseHovering) {
|
||||
update_hovering_over(i, mouseHovering);
|
||||
return mouseHovering;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,6 +82,9 @@ template <typename T> class NumberSlider : public Element {
|
|||
}
|
||||
|
||||
virtual bool input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion, bool mouseHovering) override {
|
||||
isHovering = mouseHovering;
|
||||
if(isHeld && boundingBox.has_value())
|
||||
update_slider_pos(motion.pos);
|
||||
return Element::input_mouse_motion_callback(motion, mouseHovering);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ void PositionAdjustingPopupMenu::layout(const Clay_ElementId& id, Vector2f popup
|
|||
.cornerRadius = CLAY_CORNER_RADIUS(gui.io.theme->windowCorners1),
|
||||
.floating = {
|
||||
.offset = {popupPos.x(), popupPos.y()},
|
||||
.zIndex = gui.zIndex,
|
||||
.zIndex = gui.get_z_index(),
|
||||
.attachTo = CLAY_ATTACH_TO_ROOT
|
||||
}
|
||||
}) {
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ GUIManager::GUIManager()
|
|||
clayInstance = Clay_Initialize(clayArena, Clay_Dimensions(1.0f, 1.0f), (Clay_ErrorHandler)clay_error_handler);
|
||||
Clay_SetMeasureTextFunction(clay_skia_measure_text, this);
|
||||
setToLayout = true;
|
||||
postCallbackFuncIsHighPriority = false;
|
||||
}
|
||||
|
||||
Clay_Dimensions GUIManager::clay_skia_measure_text(Clay_StringSlice str, Clay_TextElementConfig* config, void* userData) {
|
||||
|
|
@ -295,6 +296,17 @@ void GUIManager::new_id(int64_t id, const std::function<void()>& f) {
|
|||
pop_id();
|
||||
}
|
||||
|
||||
void GUIManager::set_z_index(int16_t z, const std::function<void()>& f) {
|
||||
int16_t oldZIndex = zIndex;
|
||||
zIndex = z;
|
||||
f();
|
||||
zIndex = oldZIndex;
|
||||
}
|
||||
|
||||
int16_t GUIManager::get_z_index() {
|
||||
return zIndex;
|
||||
}
|
||||
|
||||
void GUIManager::push_id(int64_t id) {
|
||||
idStack.emplace_back(id);
|
||||
}
|
||||
|
|
@ -308,6 +320,12 @@ void GUIManager::pop_id() {
|
|||
}
|
||||
|
||||
void GUIManager::set_post_callback_func(const std::function<void()>& f) {
|
||||
if(!postCallbackFuncIsHighPriority)
|
||||
postCallbackFunc = f;
|
||||
}
|
||||
|
||||
void GUIManager::set_post_callback_func_high_priority(const std::function<void()>& f) {
|
||||
postCallbackFuncIsHighPriority = true;
|
||||
postCallbackFunc = f;
|
||||
}
|
||||
|
||||
|
|
@ -315,6 +333,7 @@ void GUIManager::run_post_callback_func() {
|
|||
if(postCallbackFunc) {
|
||||
postCallbackFunc();
|
||||
postCallbackFunc = nullptr;
|
||||
postCallbackFuncIsHighPriority = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,10 +28,13 @@ class GUIManager {
|
|||
void new_id(const char* id, const std::function<void()>& f);
|
||||
void new_id(int64_t id, const std::function<void()>& f);
|
||||
|
||||
void set_z_index(int16_t z, const std::function<void()>& f);
|
||||
int16_t get_z_index();
|
||||
|
||||
void set_post_callback_func(const std::function<void()>& f);
|
||||
void set_post_callback_func_high_priority(const std::function<void()>& f);
|
||||
void run_post_callback_func();
|
||||
|
||||
int16_t zIndex = 0;
|
||||
template <typename ElementType, typename... Args> ElementType* element(const char* id, const Args&... a) {
|
||||
push_id(id);
|
||||
ElementType* elem = insert_element<ElementType>();
|
||||
|
|
@ -80,7 +83,9 @@ class GUIManager {
|
|||
void push_id(const char* id);
|
||||
void pop_id();
|
||||
|
||||
int16_t zIndex = 0;
|
||||
std::function<void()> postCallbackFunc;
|
||||
bool postCallbackFuncIsHighPriority;
|
||||
Clay_Context* clayInstance;
|
||||
Clay_Arena clayArena;
|
||||
Clay_RenderCommandArray renderCommands;
|
||||
|
|
|
|||
|
|
@ -225,10 +225,12 @@ void ImageResourceDisplay::draw(SkCanvas* canvas, const DrawData& drawData, cons
|
|||
}
|
||||
}
|
||||
else {
|
||||
SkPaint p;
|
||||
p.setAntiAlias(drawData.skiaAA);
|
||||
if(closestMipmapLevel == get_smallest_mipmap_level())
|
||||
canvas->drawImageRect(frame.smallestMipmapLevel, imRect, {SkFilterMode::kLinear, SkMipmapMode::kLinear});
|
||||
canvas->drawImageRect(frame.smallestMipmapLevel, imRect, {SkFilterMode::kLinear, SkMipmapMode::kLinear}, &p);
|
||||
else
|
||||
canvas->drawImageRect(frame.mipmapLevels[closestMipmapLevel], imRect, {SkFilterMode::kLinear, SkMipmapMode::kNone});
|
||||
canvas->drawImageRect(frame.mipmapLevels[closestMipmapLevel], imRect, {SkFilterMode::kLinear, SkMipmapMode::kNone}, &p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue