Something went wrong. Try again.
art software for the rest of us
drawing paint image sdl art
Something went wrong. Try again.
C++
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109#include "Button.h"#include <algorithm>
namespace UI {
Button::Button(const std::string& label, std::function<void()> onClick) : label(label), onClick(onClick) { focusable = true; padding = Thickness(12.0f, 6.0f); minSize = Size(80.0f, 32.0f); horizontalAlignment = HorizontalAlignment::Center;}
void Button::SetLabel(const std::string& newLabel) { label = newLabel; MarkDirty(DirtyFlags::Layout | DirtyFlags::Render);}
void Button::RefreshPrimitives() { bgRect = std::make_unique<Rectangle>(globalBounds.X, globalBounds.Y, globalBounds.Width, globalBounds.Height); Color drawColor = normalColor; if (pressed) { drawColor = activeColor; } else if (hovered) { drawColor = hoverColor; } bgRect->SetColor(drawColor.r, drawColor.g, drawColor.b, drawColor.a); previousColor = drawColor;
UI::Size textSize = Text::Measure(label); 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) * 0.5f); labelText = std::make_unique<Text>(textX, textY, label);}
void Button::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 + padding.VerticalTotal() + margin.VerticalTotal(), minSize.height, maxSize.height);}
void Button::Arrange(Rect finalBounds) { Rect oldGlobal = globalBounds; bool doWeRefreshMaybe = IsDirty(DirtyFlags::Render | DirtyFlags::Layout); Widget::Arrange(finalBounds);
if (doWeRefreshMaybe || globalBounds != oldGlobal) { RefreshPrimitives(); }}
void Button::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(); }
Widget::Draw();}
bool Button::OnPointerStream(const std::shared_ptr<PointerStream>& stream) { if (!enabled || !visible) return false;
const auto event = stream->PeekLatestInput();
if (event.actDirection == PointerDirection::Down) { SetPressed(true); return true; } else if (event.actDirection == PointerDirection::Up) { if (pressed) { SetPressed(false); if (globalBounds.Contains(event.screenX, event.screenY)) { if (onClick) { onClick(); } } return true; } } return false;}
}