11std::string GuiFormat(
const char * fmt, ...)
17 const int n = vsnprintf(
nullptr, 0, fmt, copy);
23 out.resize((
size_t)n + 1);
24 vsnprintf(&out[0], out.size(), fmt, args);
25 out.resize((
size_t)n);
32static const char * textOrNull(
const char * t)
34 return (t && *t) ? t :
nullptr;
42 const bool selected = s == STATE::SELECTED || s == STATE::HELD;
43 if(selected && !wasSelected && focus)
45 wasSelected = selected;
47 if(s == STATE::CLICKED && click)
62 Runner(UiScope& s) : scope(s) {}
69UiScope::UiScope() : trig(&primary), soundOver(nullptr), soundClick(nullptr), runner(nullptr)
71 primary.setPrimaryTrigger();
77 for(
size_t i = holders.size(); i > 0; i--)
78 delete holders[i - 1];
86 bindings.push_back(fn);
89void UiScope::visibleWhen(GuiElement& e, std::function<
bool()> fn)
91 GuiElement * target = &e;
99void UiScope::enabledWhen(GuiElement& e, std::function<
bool()> fn)
101 GuiElement * target = &e;
102 bind([target, fn]() {
103 const bool enabled = fn();
104 const bool off = target->
getState() == STATE::DISABLED;
107 else if(!enabled && !off)
112void UiScope::attachTo(GuiWindow& window)
115 runner = &make<Runner>(*
this);
120void UiScope::runBindings()
122 for(
size_t i = 0; i < bindings.size(); i++)
128GuiLabel::GuiLabel(UiScope& scope,
const char * t) :
129 GuiText(textOrNull(t), 20, GuiTheme::current().text), ui(scope)
133GuiLabel& GuiLabel::fontSize(
int px)
139GuiLabel& GuiLabel::textColor(PixelColor c)
145GuiLabel& GuiLabel::muted()
150GuiLabel& GuiLabel::accent()
155GuiLabel& GuiLabel::bind(std::function<std::string()> fn)
157 GuiLabel * self =
this;
158 std::string last =
"\x01";
159 ui.bind([self, fn, last]()
mutable {
160 const std::string s = fn();
163 self->setText(textOrNull(s.c_str()));
170GuiLabel& GuiLabel::visibleWhen(std::function<
bool()> fn)
172 ui.visibleWhen(*
this, fn);
178GuiChip::GuiChip(UiScope& scope,
const char * t) :
179 ui(scope), backdrop(1, 1), label(scope, t)
183 backdrop.setCapsule();
192GuiChip& GuiChip::bind(std::function<std::string()> fn)
198GuiChip& GuiChip::visibleWhen(std::function<
bool()> fn)
200 ui.visibleWhen(*
this, fn);
206GuiTextButton::GuiTextButton(UiScope& scope,
const char * t) :
207 GuiButton(150, 44), ui(scope), shape(150, 44), text(scope, t), textLit(scope, t), wasSelected(false)
214 text.setAlignment(ALIGN_H::CENTRE, ALIGN_V::MIDDLE);
215 textLit.setAlignment(ALIGN_H::CENTRE, ALIGN_V::MIDDLE);
219 setLabelOver(&textLit);
221 setSoundOver(scope.getSoundOver());
222 setSoundClick(scope.getSoundClick());
226GuiTextButton& GuiTextButton::size(
int w,
int h)
230 shape.setLayoutSize(w, h);
234GuiTextButton& GuiTextButton::fontSize(
int px)
237 textLit.fontSize(px);
241void GuiTextButton::setLayoutSize(
int w,
int h)
244 shape.setLayoutSize(w, h);
247GuiTextButton& GuiTextButton::onClick(
UiCallback fn)
253GuiTextButton& GuiTextButton::onFocus(
UiCallback fn)
259GuiTextButton& GuiTextButton::style(
const GuiShapeStyle& s)
265GuiTextButton& GuiTextButton::rounded(
float radius)
267 shape.setCorners(GuiCorners(radius));
271GuiTextButton& GuiTextButton::disabled(
bool d)
274 setState(STATE::DISABLED);
275 else if(state == STATE::DISABLED)
276 setState(STATE::DEFAULT);
280void GuiTextButton::setText(
const char * t)
282 text.setText(textOrNull(t));
283 textLit.setText(textOrNull(t));
286GuiTextButton& GuiTextButton::bind(std::function<std::string()> fn)
293GuiTextButton& GuiTextButton::visibleWhen(std::function<
bool()> fn)
295 ui.visibleWhen(*
this, fn);
299GuiTextButton& GuiTextButton::enabledWhen(std::function<
bool()> fn)
301 ui.enabledWhen(*
this, fn);
305void GuiTextButton::update(InputController * c)
308 pollButton(*
this, wasSelected, clickCb, focusCb);
313GuiCardSurface::GuiCardSurface() : GuiButton(1, 1), shape(1, 1)
318void GuiCardSurface::setLayoutSize(
int w,
int h)
321 shape.setLayoutSize(w, h);
324GuiCard::GuiCard(UiScope& scope) : ui(scope), wasSelected(false)
328 surface.shape.setCorners(GuiCorners(theme.
radius));
329 surface.shape.setStyle(theme.
cardStyle());
330 surface.setTrigger(scope.trigger());
331 surface.setSoundOver(scope.getSoundOver());
332 surface.setSoundClick(scope.getSoundClick());
350GuiCard& GuiCard::style(
const GuiShapeStyle& s)
352 surface.shape.setStyle(s);
356GuiCard& GuiCard::corners(
const GuiCorners& c)
358 surface.shape.setCorners(c);
362GuiCard& GuiCard::selectable(
bool s)
364 surface.setSelectable(s);
367 surface.setState(STATE::DISABLED);
368 else if(surface.getState() == STATE::DISABLED)
369 surface.setState(STATE::DEFAULT);
373GuiCard& GuiCard::disabled(
bool d)
376 const bool off = surface.getState() == STATE::DISABLED;
378 surface.setState(STATE::DISABLED);
380 surface.setState(STATE::DEFAULT);
384GuiCard& GuiCard::visibleWhen(std::function<
bool()> fn)
386 ui.visibleWhen(*
this, fn);
390GuiCard& GuiCard::enabledWhen(std::function<
bool()> fn)
392 GuiCard * self =
this;
393 ui.bind([self, fn]() { self->disabled(!fn()); });
397void GuiCard::update(InputController * c)
400 pollButton(surface, wasSelected, clickCb, focusCb);
Umbrella header for the platform-agnostic libgui core.
bool isVisible()
Checks whether or not the element is visible.
int getStateChan()
Gets the controller channel that last changed the element's state.
STATE getState()
Gets the element's current state.
void setTrigger(GuiTrigger *t)
Set a new GuiTrigger for the element.
virtual void setState(STATE s, int c=-1)
Sets the element's state.
virtual void setVisible(bool v)
Sets the element's visibility.
virtual void update(InputController *c)
Called constantly to allow the element to respond to the current input data.
void setEffectGrow()
Shortcut to SetEffectOnOver(EFFECT::SCALE, 4, 110)
virtual void setLayoutSize(int w, int h)
Gives the element a size chosen by a container (default: sets width and height)
GuiLayout & add(GuiElement *e, const GuiItem &item=GuiItem())
Adds a child. Children are laid out in the order they are added.
void append(GuiElement *e)
Appends a GuiElement to the GuiWindow.
void update(InputController *) override
Called constantly to allow the element to respond to the current input data.
void draw() override
Called constantly to redraw the element.
std::function< void()> UiCallback
A callback with no arguments.
STATE
Interaction state of a GuiElement (default, selected, clicked, held, disabled).
GuiShapeStyle cardStyle() const
A raised card: gradient surface, outline, drop shadow; a glowing accent outline when focused.
float padding
Space inside a card.
GuiShapeStyle chipStyle() const
A small label background (a "chip")
static GuiTheme & current()
The theme the rest of the library reads. Starts as the default dark theme.
GuiShapeStyle buttonStyle() const
A capsule or rounded button: lights up in the accent color when focused, darkens when pressed.
float radius
Corner radius of cards and panels.
PixelColor textOnAccent
Text drawn over the accent color.