AUI_REACT#
Explicitly denotes a reactive expression.
| Header: | #include <AUI/Common/APropertyPrecomputed.h> |
| CMake: | aui_link(my_target PUBLIC aui::core) |
Definition#
#define AUI_REACT(...) \
::aui::react::makeExpression( \
[=]() -> decltype(auto) { return (__VA_ARGS__); } \
)
Detailed Description#
AUI_REACT is a core component of AUI Framework's reactive reactive programming model. It's used to create reactive expressions that automatically update UI elements when their dependent values change.
The expression is a C++ expression that depends on AProperty values:
Basic example#
This creates a label that automatically updates when property mCounter changes:
|
Formatted label example#
|
Implementation details#
When used in declarative UI building, AUI_REACT creates an instance of APropertyPrecomputed<T> behind the scenes,
which:
- Evaluates the expression initially.
- Sets up observers for all dependent properties.
- Re-evaluates when dependencies change.
The macros itself consists of a lambda syntax with forced [=] capture and explicit decltype(auto) return type.
The lambda is wrapped with aui::react::Expression to be strongly typed.
The decltype(auto) return type is used to avoid property copy when referenced.
Examples#
examples/app/notes/src/main.cpp
Notes App - Note taking app that demonstrates usage of AListModel, AProperty, user data saving and loading.
},
/// [scrollarea]
AScrollArea::Builder()
.withContents(
AUI_DECLARATIVE_FOR(note, *mNotes, AVerticalLayout) {
observeChangesForDirty(note);
return notePreview(note) AUI_LET {
connect(it->clicked, [this, note] { mCurrentNote = note; });
it& mCurrentNote > [note](AView& view, const _<Note>& currentNote) {
ALOG_DEBUG(LOG_TAG) << "currentNote == note " << currentNote << " == " << note;
examples/ui/contacts/src/main.cpp
AUI Contacts - Usage of AUI_DECLARATIVE_FOR to make a contacts-like application.
mSelectedContact = nullptr;
}
_<AView> indexedList() {
return AUI_DECLARATIVE_FOR(group, *mContacts | ranges::views::chunk_by([](const _<Contact>& lhs, const _<Contact>& rhs) {
return groupLetter(lhs->displayName) == groupLetter(rhs->displayName);
}), AVerticalLayout) {
auto firstContact = *ranges::begin(group);
auto firstLetter = groupLetter(firstContact->displayName);
ALogger::info("Test") << "Computing view for group " << AString(1, firstLetter);
examples/ui/views/src/ExampleWindow.cpp
Views Example - All-in-one views building example.
}
}),
_new<ASpacerExpanding>(),
} AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } },
AUI_DECLARATIVE_FOR(i, *state->colors, AWordWrappingLayout) {
return Horizontal {
_new<ALabel>(i.toString()) AUI_OVERRIDE_STYLE {
TextColor { i.readableBlackOrWhite() },
}
} AUI_OVERRIDE_STYLE {
examples/ui/opengl_simple/src/main.cpp
OpenGL Example - Demonstrates how to integrate custom OpenGL rendering with AUI Framework.
_new<MyRenderer>(state) AUI_OVERRIDE_STYLE { Expanding() },
Horizontal::Expanding {
Vertical {
Vertical {
Label { AUI_REACT(fmt::format("FPS: {:.1f}", *state->fps)) },
} AUI_OVERRIDE_STYLE {
Padding(16_dp),
BackgroundSolid { AColor::WHITE.transparentize(0.5f) },
MinSize { 150_dp, {} },
},
examples/7guis/counter/src/main.cpp
7GUIs Counter - Simple counter.
public:
CounterWindow() : AWindow("AUI - 7GUIs - Counter", 200_dp, 100_dp) {
setContents(Centered {
Horizontal {
Label { AUI_REACT("Count: {}"_format(mCounter)) },
Button { Label { "Count" }, [this] { mCounter += 1; } },
} AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } },
});
}
examples/7guis/flight_booker/src/main.cpp
7GUIs Flight Booker - Flight Booker.
examples/7guis/timer/src/main.cpp
7GUIs Timer - Timer example.
it->setCustomStyle({ Expanding { 1, 0 } });
},
},
} AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } },
Label { AUI_REACT("{:.1f}s"_format(duration_cast<milliseconds>(*mElapsedTime).count() / 1000.f)) },
Horizontal {
Label { "Duration:" },
Slider {
.value = AUI_REACT(float(mDuration->count()) / float(MAX_DURATION.count())),
.onValueChanged =
examples/7guis/circle_drawer/src/main.cpp
7GUIs Circle Drawer - Undo, redo, dialog control.
"", 200_dp, 50_dp, dynamic_cast<AWindow*>(AWindow::current()), WindowStyle::MODAL);
radiusPopup->setContents(Vertical {
Label { "Adjust diameter of circle at {}."_format(circle->position) },
Slider {
.value = AUI_REACT(circle->radius / MAX_RADIUS),
.onValueChanged =
[this, circle](aui::float_within_0_1 s) {
circle->radius = s * MAX_RADIUS;
mState->circles.notify();
},
Examples#
examples/ui/contacts/src/view/ContactDetailsView.cpp
AUI Contacts - Usage of AUI_DECLARATIVE_FOR to make a contacts-like application.
namespace {
_<AView> profilePhoto(const _<Contact>& contact) {
return Centered {
Label {
AUI_REACT(contact->displayName->empty() ? "?" : AString(1, contact->displayName->first()).uppercase())
} AUI_OVERRIDE_STYLE { Opacity(0.5f), FontSize { 32_dp } },
} AUI_OVERRIDE_STYLE {
FixedSize { 64_dp },
BorderRadius { 32_dp },
BackgroundGradient { AColor::GRAY.lighter(0.5f), AColor::GRAY, 163_deg },