#include "IconActionButton.h" #include "../Assets.h" #include "Widgets/Widget.h" namespace UI { IconActionButton::IconActionButton(const std::string& icon, const std::string& label, std::function onClick) : Button(label, onClick), icon(icon) { padding = Thickness(0,0,0,0); minSize.width = 96; verticalAlignment = VerticalAlignment::Stretch; } void IconActionButton::RefreshPrimitives() { bgRect = std::make_unique(globalBounds.X + (globalBounds.Width - 64)/2, globalBounds.Y, 64,64); Color drawColor = normalColor; if (pressed) { drawColor = activeColor; } else if (hovered) { drawColor = hoverColor; } bgRect->SetColor(drawColor.r, drawColor.g, drawColor.b, drawColor.a); bgRect->SetBorderColor(1, 1, 1, 1); bgRect->SetBorderWidth(2); bgRect->SetRoundness(32); previousColor = drawColor; UI::Size textSize = Text::Measure(label); UI::Size iconSize(24,24); float contentW = std::max(0.0f, globalBounds.Width - padding.HorizontalTotal()); float contentH = std::max(0.0f, globalBounds.Height - padding.VerticalTotal()); float textX = globalBounds.X + padding.Left + std::max(0.0f, (contentW - textSize.width) * 0.5f); float textY = globalBounds.Y + padding.Top + std::max(0.0f, (contentH - textSize.height) * 1.0f); labelText = std::make_unique(textX, textY, label); float iconX = globalBounds.X + padding.Left + std::max(0.0f, (contentW - iconSize.width) * 0.5f); float iconY = globalBounds.Y + padding.Top + std::max(0.0f, (iconSize.height + 10) * 0.5f); static TTF_Font *iconFont; if (!iconFont) iconFont = TTF_OpenFont(Assets::Path("fonts/materialSymbolsRounded.ttf").data(), 24); iconText = std::make_unique(iconX, iconY, icon, iconFont); } void IconActionButton::Measure(Size /*availableSpace*/) { UI::Size textSize = Text::Measure(label); desiredSize.width = std::clamp(textSize.width+ padding.HorizontalTotal() + margin.HorizontalTotal(), minSize.width, maxSize.width); desiredSize.height = std::clamp(textSize.height+10+64 + padding.VerticalTotal() + margin.VerticalTotal(), minSize.height, maxSize.height); } void IconActionButton::Draw() { if (!visible) return; if (!bgRect || IsDirty(DirtyFlags::Layout)) { RefreshPrimitives(); } // Determine primitive color based on input interaction state // TODO: needs dedup Color drawColor = normalColor; if (pressed) { drawColor = activeColor; } else if (hovered) { drawColor = hoverColor; } if (drawColor != previousColor) { bgRect->SetColor(drawColor.r, drawColor.g, drawColor.b, drawColor.a); previousColor = drawColor; } if (bgRect) { bgRect->Render(); } if (labelText) { labelText->Render(); } if (iconText) { iconText->Render(); } Widget::Draw(); } }