AObject#
A base object class.
| Header: | #include <AUI/Common/AObject.h> |
| CMake: | aui_link(my_target PUBLIC aui::core) |
Detailed Description#
AObject is required to use signal-slot system.
AObject keeps reference to itself via std::enable_shared_from_this. It can be accessed with aui::ptr::shared_from_this().
Examples#
examples/app/minesweeper/src/Style.cpp
Minesweeper Game - Minesweeper game implementation driven by ass.
void setupConnections(AView* view, const _<AAssHelper>& helper) override {
IAssSubSelector::setupConnections(view, helper);
view->customCssPropertyChanged.clearAllOutgoingConnectionsWith(helper.get());
AObject::connect(view->customCssPropertyChanged, AUI_SLOT(helper)::onInvalidateStateAss);
}
};
/// [CellSelector]
examples/7guis/flight_booker/src/main.cpp
7GUIs Flight Booker - Flight Booker.
};
auto dateTextField(_<DateTextFieldState> state) {
return _new<ATextField>() AUI_LET {
AObject::connect(
state->parsed, it, [&it = *it, &state = *state](const AOptional<system_clock::time_point>& value) {
if (!value) {
return;
}
if (state.userChangesText.is_locked()) {
examples/ui/infinite_lazy_list/src/main.cpp
Infinite Lazy List - Usage of AUI_DECLARATIVE_FOR to make an infinite lazy list.
};
});
return Vertical {
AUI_DECLARATIVE_FOR(i, *state->items, AVerticalLayout) { return Label{} & i->value; },
Centered {
_new<ASpinnerV2>() AUI_LET {
AObject::connect(it->redrawn, AObject::GENERIC_OBSERVER, [state] {
// when a spinner appears, we indicate that we need more items.
state->needMore = true;
Public fields and Signals#
GENERIC_OBSERVER#
AObjectBase* GENERIC_OBSERVER
Indicates that a connection should not be explicitly linked to receiver's lifetime.
Experimental Feature
This API is experimental. Experimental APIs are likely to contain bugs, might be changed or removed in the future.
Normally, a connection is broken when either sender or receiver die. You can indicate that you actually don't need the connection to be broken if receiver dies, or you don't have a receiver AObject either. In such case, the connection is breaks only when the sender (signal) dies.
This can be useful in situations when you don't want to introduce some receiver AObject and when slot just to observe property or signal, i.e., you just want to make a generic observer.
Use this in combination with lambda.
Examples#
Public Methods#
biConnect#
template<APropertyWritable PropertySource, APropertyWritable PropertyDestination >
static void AObject::biConnect(PropertySource&& propertySource, PropertyDestination&& propertyDestination)
Connects source property to the destination property and opposite (bidirectionally).
- Arguments
propertySourcesource property, whose value is preserved on connection creation.propertyDestinationdestination property, whose value is overwritten on connection creation.
Connects propertySource.changed to the setter of propertyDestination . Additionally, sets the
propertyDestination with the current value of the propertySource (pre-fire). Hence, initial dataflow is
from left argument to the right argument.
After pre-fire, connects propertyDestination.changed to the setter of propertySource . This way, when
propertyDestination changes (i.e, propertyDestination belongs to some view and it's value is changed due to
user action) it immediately reflects on propertySource . So, propertySource is typically a property of some
view model with prefilled interesting data, and propertyDestination is a property of some view whose value
is unimportant at the moment of connection creation.
biConnect pulls AObject from propertySource and propertyDestination to maintain the connection.
See signal-slot system for more info.
Examples:
examples/7guis/temperature_converter/src/main.cpp
7GUIs Temperature Converter - Fahrenheit to Celsius and vice versa.
TemperatureConverterWindow() : AWindow("AUI - 7GUIs - TempConv", 300_dp, 50_dp) {
setContents(Centered {
Horizontal {
myPicker() AUI_LET {
biConnect(it->value(), mCelsius);
it->focus();
},
Label { "°C" },
Label { "=" } AUI_OVERRIDE_STYLE { Margin { {}, 16_dp } },
myPicker() AUI_LET { biConnect(it->value(), mFahrenheit); },
connect#
template<aui::detail::ConnectionSource ConnectionSource, aui::derived_from<AObjectBase> Object, ACompatibleSlotFor<ConnectionSource> Function >
static decltype(auto) AObject::connect(const ConnectionSource& connectionSource, Object* receiver, Function&& function)
Connects a signal or property to a slot on an AObject.
- Arguments
connectionSourceThe signal (or property) to connect.receiverPointer to the target `AObject` instance.functionSlot callable – can be a lambda or a member‑function pointer wrapped with `AUI_SLOT`.- Returns
- A connection object that keeps the link alive.
**Important notes** - The `function` can be any callable that is compatible with the signal’s arguments; it may ignore some or all of them. - For properties, the slot receives the current value right after the call to `connect`, and thereafter whenever the property changes (pre-fire).
// (1) Connect a normal signal – the slot is invoked when the signal fires. connect(view->clicked, AUI_SLOT(otherObjectRawPtr)::handleButtonClicked); // (2) Connect a property – the slot is called immediately with the current // value (pre-fire) and subsequently whenever the property changes. connect(textField->text(), AUI_SLOT(otherObjectRawPtr)::handleText); // (3) Connect AUI_REACT – the slot is called immediately with the current // value(pre-fire) and subsequently whenever the property changes. connect(AUI_REACT(textField->text().empty()), AUI_SLOT(otherObjectRawPtr)::setEnabled);
Examples:
examples/app/minesweeper/src/Style.cpp
Minesweeper Game - Minesweeper game implementation driven by ass.
void setupConnections(AView* view, const _<AAssHelper>& helper) override {
IAssSubSelector::setupConnections(view, helper);
view->customCssPropertyChanged.clearAllOutgoingConnectionsWith(helper.get());
AObject::connect(view->customCssPropertyChanged, AUI_SLOT(helper)::onInvalidateStateAss);
}
};
/// [CellSelector]
examples/app/game_of_life/src/main.cpp
Game of Life - Game of Life implementation that uses advanced large dynamic data rendering techniques such as ITexture, AImage to be GPU friendly. The computation is performed in AThreadPool.
for (auto s : { &mStorage, &mNextPopulation }) {
s->resize(size.x * size.y);
}
connect(mTimer->fired, me::frame);
connect(isRunning.changed, AUI_SLOT(mTimer)::setRunning);
}
void frame() {
mFrame = AThreadPool::global() * [&] {
examples/7guis/flight_booker/src/main.cpp
7GUIs Flight Booker - Flight Booker.
};
auto dateTextField(_<DateTextFieldState> state) {
return _new<ATextField>() AUI_LET {
AObject::connect(
state->parsed, it, [&it = *it, &state = *state](const AOptional<system_clock::time_point>& value) {
if (!value) {
return;
}
if (state.userChangesText.is_locked()) {
examples/ui/infinite_lazy_list/src/main.cpp
Infinite Lazy List - Usage of AUI_DECLARATIVE_FOR to make an infinite lazy list.
};
});
return Vertical {
AUI_DECLARATIVE_FOR(i, *state->items, AVerticalLayout) { return Label{} & i->value; },
Centered {
_new<ASpinnerV2>() AUI_LET {
AObject::connect(it->redrawn, AObject::GENERIC_OBSERVER, [state] {
// when a spinner appears, we indicate that we need more items.
state->needMore = true;
examples/app/minesweeper/src/MinesweeperWindow.cpp
Minesweeper Game - Minesweeper game implementation driven by ass.
MinesweeperWindow::MinesweeperWindow() : AWindow("Minesweeper", 100_dp, 100_dp) {
setContents(Vertical {
Horizontal {
Centered::Expanding {
_new<AButton>("New game...").connect(&AButton::clicked, me::newGame),
},
},
_container<AStackedLayout>(
{ // also assign ".frame" ASS class in place
mGrid = _new<AViewContainer>() << ".frame" }),
examples/app/minesweeper/src/NewGameWindow.cpp
Minesweeper Game - Minesweeper game implementation driven by ass.
Horizontal {
_new<ASpacerExpanding>(),
_new<AButton>("Start game") AUI_LET {
it->setDefault();
connect(it->clicked, me::begin);
},
_new<AButton>("Cancel").connect(&AButton::clicked, me::close),
} AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } },
} AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } });
examples/app/minesweeper/src/CellView.cpp
Minesweeper Game - Minesweeper game implementation driven by ass.
#include "AUI/Render/IRenderer.h"
CellView::CellView(FieldCell& cell) : mCell(cell), mCellValueCopy(cell) {
connect(clickedButton, this, [&]() {
emit customCssPropertyChanged();
});
}
void CellView::render(ARenderContext context) {
examples/app/fractal/src/FractalWindow.cpp
Fractal Example - Fractal viewer application demonstrating usage of custom shaders.
});
}
auto fractal = _new<FractalView>();
connect(fractal->centerPosChanged, this, [centerPosDisplay](const glm::dvec2& newPos, double scale) {
centerPosDisplay->setText("Center position: {} {}, scale: {}"_format(newPos.x, -newPos.y, scale));
});
setContents(Horizontal {
Stacked::Expanding {
examples/app/fractal/src/JumpToCoordsWindow.cpp
Fractal Example - Fractal viewer application demonstrating usage of custom shaders.
{ "Scale="_as, scale },
}) AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } },
Horizontal {
SpacerExpanding {},
_new<AButton>("Jump").connect(
&AButton::clicked, this,
[&, fractalView, re, im, scale]() {
try {
auto dRe = std::stod((*re->text()).toStdString());
auto dIm = -std::stod((*re->text()).toStdString());
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/7guis/timer/src/main.cpp
7GUIs Timer - Timer example.
} AUI_OVERRIDE_STYLE { Expanding { 1, 0 } },
} AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } },
_new<AButton>("Reset Timer") AUI_OVERRIDE_STYLE {
Expanding { 1, 0 },
} AUI_LET { connect(it->clicked, me::reset); },
} AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } },
});
connect(mTimer->fired, me::update);
mTimer->start();
examples/7guis/circle_drawer/src/main.cpp
7GUIs Circle Drawer - Undo, redo, dialog control.
BackgroundSolid(AColor::WHITE),
Border(1_px, AColor::GRAY),
AOverflow::HIDDEN_FROM_THIS,
});
connect(mState->circles.changed, me::redraw);
connect(mHoveredCircle.changed, me::redraw);
}
void render(ARenderContext ctx) override {
AView::render(ctx);
examples/7guis/crud/src/main.cpp
7GUIs CRUD - Create/Read/Update/Delete example.
Label { "Filter prefix:" },
_new<ATextField>() AUI_OVERRIDE_STYLE { Expanding(1, 0) } && mFilterPrefix,
} AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } },
AScrollArea::Builder().withExpanding().withContents(
AUI_DECLARATIVE_FOR(i, *mUsers | FILTER_VIEW, AVerticalLayout) {
auto view = _new<ALabel>();
view & i->displayName;
connect(mSelectedUser, view, [this, &view = *view, i] {
view.setAssName("selected", mSelectedUser == i);
});
examples/7guis/temperature_converter/src/main.cpp
7GUIs Temperature Converter - Fahrenheit to Celsius and vice versa.
Label { "°F" },
} AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } },
});
connect(mFahrenheit.changed, [&] { mCelsius = (*mFahrenheit - 32.f) * (5.f / 9.f); });
connect(mCelsius.changed, [&] { mFahrenheit = *mCelsius * (9.f / 5.f) + 32.f; });
}
private:
AProperty<int> mCelsius, mFahrenheit;
examples/7guis/cells/src/main.cpp
7GUIs Cells - Spreadsheet processor (Excel).
Cell& mCell;
AAbstractSignal::AutoDestroyedConnection mConnection;
void inflateLabel() {
mConnection = connect(mCell.value, [this](const formula::Value& v) {
ALayoutInflater::inflate(
this,
std::visit(
aui::lambda_overloaded {
[](std::nullopt_t) -> _<AView> { return _new<AView>(); },
examples/ui/minimal_ui_assets_xmake/src/MainWindow.cpp
Minimal UI Template XMake with Assets - Minimal UI boilerplate template XMake with AUI Assets.
Centered{
Vertical{
Centered { Icon { ":img/logo.svg" } AUI_OVERRIDE_STYLE { FixedSize(64_dp) } },
Centered { Label { "Hello world from AUI!" } },
_new<AButton>("Visit GitHub repo").connect(&AView::clicked, this, [] {
APlatform::openUrl("https://github.com/aui-framework/aui");
}),
_new<AButton>("Visit docs").connect(&AView::clicked, this, [] {
APlatform::openUrl("https://aui-framework.github.io/");
}),
examples/ui/minimal_ui_xmake/src/MainWindow.cpp
Minimal UI Template XMake - Minimal UI boilerplate template XMake.
setContents(
Centered{
Vertical{
Centered { Label { "Hello world from AUI!" } },
_new<AButton>("Visit GitHub repo").connect(&AView::clicked, this, [] {
APlatform::openUrl("https://github.com/aui-framework/aui");
}),
_new<AButton>("Visit docs").connect(&AView::clicked, this, [] {
APlatform::openUrl("https://aui-framework.github.io/");
}),
examples/ui/contacts/src/view/ContactDetailsView.cpp
AUI Contacts - Usage of AUI_DECLARATIVE_FOR to make a contacts-like application.
c(".row-value"),
Expanding(1, 0),
},
});
connect(mEditorMode, [this] {
setContents(Vertical::Expanding {
AScrollArea::Builder().withContents(Centered {
Vertical::Expanding {
Horizontal {
profilePhoto(mContact),
template<aui::detail::ConnectionSource ConnectionSource, APropertyWritable PropertyDestination >
static void AObject::connect(ConnectionSource&& connectionSource, PropertyDestination&& propertyDestination)
Connects a signal or property to a property.
- Arguments
connectionSourceThe signal (or property) to connect.propertyDestinationdestination property, whose value is overwritten on connection creation.
Examples:
examples/app/minesweeper/src/Style.cpp
Minesweeper Game - Minesweeper game implementation driven by ass.
void setupConnections(AView* view, const _<AAssHelper>& helper) override {
IAssSubSelector::setupConnections(view, helper);
view->customCssPropertyChanged.clearAllOutgoingConnectionsWith(helper.get());
AObject::connect(view->customCssPropertyChanged, AUI_SLOT(helper)::onInvalidateStateAss);
}
};
/// [CellSelector]
examples/app/game_of_life/src/main.cpp
Game of Life - Game of Life implementation that uses advanced large dynamic data rendering techniques such as ITexture, AImage to be GPU friendly. The computation is performed in AThreadPool.
for (auto s : { &mStorage, &mNextPopulation }) {
s->resize(size.x * size.y);
}
connect(mTimer->fired, me::frame);
connect(isRunning.changed, AUI_SLOT(mTimer)::setRunning);
}
void frame() {
mFrame = AThreadPool::global() * [&] {
examples/7guis/flight_booker/src/main.cpp
7GUIs Flight Booker - Flight Booker.
};
auto dateTextField(_<DateTextFieldState> state) {
return _new<ATextField>() AUI_LET {
AObject::connect(
state->parsed, it, [&it = *it, &state = *state](const AOptional<system_clock::time_point>& value) {
if (!value) {
return;
}
if (state.userChangesText.is_locked()) {
examples/ui/infinite_lazy_list/src/main.cpp
Infinite Lazy List - Usage of AUI_DECLARATIVE_FOR to make an infinite lazy list.
};
});
return Vertical {
AUI_DECLARATIVE_FOR(i, *state->items, AVerticalLayout) { return Label{} & i->value; },
Centered {
_new<ASpinnerV2>() AUI_LET {
AObject::connect(it->redrawn, AObject::GENERIC_OBSERVER, [state] {
// when a spinner appears, we indicate that we need more items.
state->needMore = true;
examples/app/minesweeper/src/MinesweeperWindow.cpp
Minesweeper Game - Minesweeper game implementation driven by ass.
MinesweeperWindow::MinesweeperWindow() : AWindow("Minesweeper", 100_dp, 100_dp) {
setContents(Vertical {
Horizontal {
Centered::Expanding {
_new<AButton>("New game...").connect(&AButton::clicked, me::newGame),
},
},
_container<AStackedLayout>(
{ // also assign ".frame" ASS class in place
mGrid = _new<AViewContainer>() << ".frame" }),
examples/app/minesweeper/src/NewGameWindow.cpp
Minesweeper Game - Minesweeper game implementation driven by ass.
Horizontal {
_new<ASpacerExpanding>(),
_new<AButton>("Start game") AUI_LET {
it->setDefault();
connect(it->clicked, me::begin);
},
_new<AButton>("Cancel").connect(&AButton::clicked, me::close),
} AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } },
} AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } });
examples/app/minesweeper/src/CellView.cpp
Minesweeper Game - Minesweeper game implementation driven by ass.
#include "AUI/Render/IRenderer.h"
CellView::CellView(FieldCell& cell) : mCell(cell), mCellValueCopy(cell) {
connect(clickedButton, this, [&]() {
emit customCssPropertyChanged();
});
}
void CellView::render(ARenderContext context) {
examples/app/fractal/src/FractalWindow.cpp
Fractal Example - Fractal viewer application demonstrating usage of custom shaders.
});
}
auto fractal = _new<FractalView>();
connect(fractal->centerPosChanged, this, [centerPosDisplay](const glm::dvec2& newPos, double scale) {
centerPosDisplay->setText("Center position: {} {}, scale: {}"_format(newPos.x, -newPos.y, scale));
});
setContents(Horizontal {
Stacked::Expanding {
examples/app/fractal/src/JumpToCoordsWindow.cpp
Fractal Example - Fractal viewer application demonstrating usage of custom shaders.
{ "Scale="_as, scale },
}) AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } },
Horizontal {
SpacerExpanding {},
_new<AButton>("Jump").connect(
&AButton::clicked, this,
[&, fractalView, re, im, scale]() {
try {
auto dRe = std::stod((*re->text()).toStdString());
auto dIm = -std::stod((*re->text()).toStdString());
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/7guis/timer/src/main.cpp
7GUIs Timer - Timer example.
} AUI_OVERRIDE_STYLE { Expanding { 1, 0 } },
} AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } },
_new<AButton>("Reset Timer") AUI_OVERRIDE_STYLE {
Expanding { 1, 0 },
} AUI_LET { connect(it->clicked, me::reset); },
} AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } },
});
connect(mTimer->fired, me::update);
mTimer->start();
examples/7guis/circle_drawer/src/main.cpp
7GUIs Circle Drawer - Undo, redo, dialog control.
BackgroundSolid(AColor::WHITE),
Border(1_px, AColor::GRAY),
AOverflow::HIDDEN_FROM_THIS,
});
connect(mState->circles.changed, me::redraw);
connect(mHoveredCircle.changed, me::redraw);
}
void render(ARenderContext ctx) override {
AView::render(ctx);
examples/7guis/crud/src/main.cpp
7GUIs CRUD - Create/Read/Update/Delete example.
Label { "Filter prefix:" },
_new<ATextField>() AUI_OVERRIDE_STYLE { Expanding(1, 0) } && mFilterPrefix,
} AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } },
AScrollArea::Builder().withExpanding().withContents(
AUI_DECLARATIVE_FOR(i, *mUsers | FILTER_VIEW, AVerticalLayout) {
auto view = _new<ALabel>();
view & i->displayName;
connect(mSelectedUser, view, [this, &view = *view, i] {
view.setAssName("selected", mSelectedUser == i);
});
examples/7guis/temperature_converter/src/main.cpp
7GUIs Temperature Converter - Fahrenheit to Celsius and vice versa.
Label { "°F" },
} AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } },
});
connect(mFahrenheit.changed, [&] { mCelsius = (*mFahrenheit - 32.f) * (5.f / 9.f); });
connect(mCelsius.changed, [&] { mFahrenheit = *mCelsius * (9.f / 5.f) + 32.f; });
}
private:
AProperty<int> mCelsius, mFahrenheit;
examples/7guis/cells/src/main.cpp
7GUIs Cells - Spreadsheet processor (Excel).
Cell& mCell;
AAbstractSignal::AutoDestroyedConnection mConnection;
void inflateLabel() {
mConnection = connect(mCell.value, [this](const formula::Value& v) {
ALayoutInflater::inflate(
this,
std::visit(
aui::lambda_overloaded {
[](std::nullopt_t) -> _<AView> { return _new<AView>(); },
examples/ui/minimal_ui_assets_xmake/src/MainWindow.cpp
Minimal UI Template XMake with Assets - Minimal UI boilerplate template XMake with AUI Assets.
Centered{
Vertical{
Centered { Icon { ":img/logo.svg" } AUI_OVERRIDE_STYLE { FixedSize(64_dp) } },
Centered { Label { "Hello world from AUI!" } },
_new<AButton>("Visit GitHub repo").connect(&AView::clicked, this, [] {
APlatform::openUrl("https://github.com/aui-framework/aui");
}),
_new<AButton>("Visit docs").connect(&AView::clicked, this, [] {
APlatform::openUrl("https://aui-framework.github.io/");
}),
examples/ui/minimal_ui_xmake/src/MainWindow.cpp
Minimal UI Template XMake - Minimal UI boilerplate template XMake.
setContents(
Centered{
Vertical{
Centered { Label { "Hello world from AUI!" } },
_new<AButton>("Visit GitHub repo").connect(&AView::clicked, this, [] {
APlatform::openUrl("https://github.com/aui-framework/aui");
}),
_new<AButton>("Visit docs").connect(&AView::clicked, this, [] {
APlatform::openUrl("https://aui-framework.github.io/");
}),
examples/ui/contacts/src/view/ContactDetailsView.cpp
AUI Contacts - Usage of AUI_DECLARATIVE_FOR to make a contacts-like application.
c(".row-value"),
Expanding(1, 0),
},
});
connect(mEditorMode, [this] {
setContents(Vertical::Expanding {
AScrollArea::Builder().withContents(Centered {
Vertical::Expanding {
Horizontal {
profilePhoto(mContact),
template<typename Connectable, ACompatibleSlotFor<Connectable> Function >
decltype(auto) AObject::connect(const Connectable& connectable, Function&& function)
Connects signal or property to slot of "this" object.
- Arguments
connectablesignal or propertyfunctionslot. Can be lambda- Returns
- Connection instance
signal-slot system for more info.
connect(view->clicked, [] { printf("Button clicked!\\n"); });
connect(textField->text(), [](const AString& s) { ALogger::info(LOG_TAG) << "Text: " << s; });
Examples:
examples/app/minesweeper/src/Style.cpp
Minesweeper Game - Minesweeper game implementation driven by ass.
void setupConnections(AView* view, const _<AAssHelper>& helper) override {
IAssSubSelector::setupConnections(view, helper);
view->customCssPropertyChanged.clearAllOutgoingConnectionsWith(helper.get());
AObject::connect(view->customCssPropertyChanged, AUI_SLOT(helper)::onInvalidateStateAss);
}
};
/// [CellSelector]
examples/app/game_of_life/src/main.cpp
Game of Life - Game of Life implementation that uses advanced large dynamic data rendering techniques such as ITexture, AImage to be GPU friendly. The computation is performed in AThreadPool.
for (auto s : { &mStorage, &mNextPopulation }) {
s->resize(size.x * size.y);
}
connect(mTimer->fired, me::frame);
connect(isRunning.changed, AUI_SLOT(mTimer)::setRunning);
}
void frame() {
mFrame = AThreadPool::global() * [&] {
examples/7guis/flight_booker/src/main.cpp
7GUIs Flight Booker - Flight Booker.
};
auto dateTextField(_<DateTextFieldState> state) {
return _new<ATextField>() AUI_LET {
AObject::connect(
state->parsed, it, [&it = *it, &state = *state](const AOptional<system_clock::time_point>& value) {
if (!value) {
return;
}
if (state.userChangesText.is_locked()) {
examples/ui/infinite_lazy_list/src/main.cpp
Infinite Lazy List - Usage of AUI_DECLARATIVE_FOR to make an infinite lazy list.
};
});
return Vertical {
AUI_DECLARATIVE_FOR(i, *state->items, AVerticalLayout) { return Label{} & i->value; },
Centered {
_new<ASpinnerV2>() AUI_LET {
AObject::connect(it->redrawn, AObject::GENERIC_OBSERVER, [state] {
// when a spinner appears, we indicate that we need more items.
state->needMore = true;
examples/app/minesweeper/src/MinesweeperWindow.cpp
Minesweeper Game - Minesweeper game implementation driven by ass.
MinesweeperWindow::MinesweeperWindow() : AWindow("Minesweeper", 100_dp, 100_dp) {
setContents(Vertical {
Horizontal {
Centered::Expanding {
_new<AButton>("New game...").connect(&AButton::clicked, me::newGame),
},
},
_container<AStackedLayout>(
{ // also assign ".frame" ASS class in place
mGrid = _new<AViewContainer>() << ".frame" }),
examples/app/minesweeper/src/NewGameWindow.cpp
Minesweeper Game - Minesweeper game implementation driven by ass.
Horizontal {
_new<ASpacerExpanding>(),
_new<AButton>("Start game") AUI_LET {
it->setDefault();
connect(it->clicked, me::begin);
},
_new<AButton>("Cancel").connect(&AButton::clicked, me::close),
} AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } },
} AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } });
examples/app/minesweeper/src/CellView.cpp
Minesweeper Game - Minesweeper game implementation driven by ass.
#include "AUI/Render/IRenderer.h"
CellView::CellView(FieldCell& cell) : mCell(cell), mCellValueCopy(cell) {
connect(clickedButton, this, [&]() {
emit customCssPropertyChanged();
});
}
void CellView::render(ARenderContext context) {
examples/app/fractal/src/FractalWindow.cpp
Fractal Example - Fractal viewer application demonstrating usage of custom shaders.
});
}
auto fractal = _new<FractalView>();
connect(fractal->centerPosChanged, this, [centerPosDisplay](const glm::dvec2& newPos, double scale) {
centerPosDisplay->setText("Center position: {} {}, scale: {}"_format(newPos.x, -newPos.y, scale));
});
setContents(Horizontal {
Stacked::Expanding {
examples/app/fractal/src/JumpToCoordsWindow.cpp
Fractal Example - Fractal viewer application demonstrating usage of custom shaders.
{ "Scale="_as, scale },
}) AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } },
Horizontal {
SpacerExpanding {},
_new<AButton>("Jump").connect(
&AButton::clicked, this,
[&, fractalView, re, im, scale]() {
try {
auto dRe = std::stod((*re->text()).toStdString());
auto dIm = -std::stod((*re->text()).toStdString());
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/7guis/timer/src/main.cpp
7GUIs Timer - Timer example.
} AUI_OVERRIDE_STYLE { Expanding { 1, 0 } },
} AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } },
_new<AButton>("Reset Timer") AUI_OVERRIDE_STYLE {
Expanding { 1, 0 },
} AUI_LET { connect(it->clicked, me::reset); },
} AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } },
});
connect(mTimer->fired, me::update);
mTimer->start();
examples/7guis/circle_drawer/src/main.cpp
7GUIs Circle Drawer - Undo, redo, dialog control.
BackgroundSolid(AColor::WHITE),
Border(1_px, AColor::GRAY),
AOverflow::HIDDEN_FROM_THIS,
});
connect(mState->circles.changed, me::redraw);
connect(mHoveredCircle.changed, me::redraw);
}
void render(ARenderContext ctx) override {
AView::render(ctx);
examples/7guis/crud/src/main.cpp
7GUIs CRUD - Create/Read/Update/Delete example.
Label { "Filter prefix:" },
_new<ATextField>() AUI_OVERRIDE_STYLE { Expanding(1, 0) } && mFilterPrefix,
} AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } },
AScrollArea::Builder().withExpanding().withContents(
AUI_DECLARATIVE_FOR(i, *mUsers | FILTER_VIEW, AVerticalLayout) {
auto view = _new<ALabel>();
view & i->displayName;
connect(mSelectedUser, view, [this, &view = *view, i] {
view.setAssName("selected", mSelectedUser == i);
});
examples/7guis/temperature_converter/src/main.cpp
7GUIs Temperature Converter - Fahrenheit to Celsius and vice versa.
Label { "°F" },
} AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } },
});
connect(mFahrenheit.changed, [&] { mCelsius = (*mFahrenheit - 32.f) * (5.f / 9.f); });
connect(mCelsius.changed, [&] { mFahrenheit = *mCelsius * (9.f / 5.f) + 32.f; });
}
private:
AProperty<int> mCelsius, mFahrenheit;
examples/7guis/cells/src/main.cpp
7GUIs Cells - Spreadsheet processor (Excel).
Cell& mCell;
AAbstractSignal::AutoDestroyedConnection mConnection;
void inflateLabel() {
mConnection = connect(mCell.value, [this](const formula::Value& v) {
ALayoutInflater::inflate(
this,
std::visit(
aui::lambda_overloaded {
[](std::nullopt_t) -> _<AView> { return _new<AView>(); },
examples/ui/minimal_ui_assets_xmake/src/MainWindow.cpp
Minimal UI Template XMake with Assets - Minimal UI boilerplate template XMake with AUI Assets.
Centered{
Vertical{
Centered { Icon { ":img/logo.svg" } AUI_OVERRIDE_STYLE { FixedSize(64_dp) } },
Centered { Label { "Hello world from AUI!" } },
_new<AButton>("Visit GitHub repo").connect(&AView::clicked, this, [] {
APlatform::openUrl("https://github.com/aui-framework/aui");
}),
_new<AButton>("Visit docs").connect(&AView::clicked, this, [] {
APlatform::openUrl("https://aui-framework.github.io/");
}),
examples/ui/minimal_ui_xmake/src/MainWindow.cpp
Minimal UI Template XMake - Minimal UI boilerplate template XMake.
setContents(
Centered{
Vertical{
Centered { Label { "Hello world from AUI!" } },
_new<AButton>("Visit GitHub repo").connect(&AView::clicked, this, [] {
APlatform::openUrl("https://github.com/aui-framework/aui");
}),
_new<AButton>("Visit docs").connect(&AView::clicked, this, [] {
APlatform::openUrl("https://aui-framework.github.io/");
}),
examples/ui/contacts/src/view/ContactDetailsView.cpp
AUI Contacts - Usage of AUI_DECLARATIVE_FOR to make a contacts-like application.
c(".row-value"),
Expanding(1, 0),
},
});
connect(mEditorMode, [this] {
setContents(Vertical::Expanding {
AScrollArea::Builder().withContents(Centered {
Vertical::Expanding {
Horizontal {
profilePhoto(mContact),
template<aui::detail::ConnectionSource ConnectionSource, aui::derived_from<AObjectBase> Object, ACompatibleSlotFor<ConnectionSource> Function >
static decltype(auto) AObject::connect(const ConnectionSource& connectionSource, _<Object> object, Function&& function)
Connects signal or property to the slot of the specified object.
- Arguments
connectablesignal or propertyobjectinstance ofAObjectfunctionslot. Can be lambda- Returns
- Connection instance
See signal-slot system for more info.
connect(view->clicked, AUI_SLOT(otherObjectSharedPtr)::handleButtonClicked);
connect(textField->text(), AUI_SLOT(otherObjectSharedPtr)::handleText);
Note
_<Object> arg is accepted by value intentionally -- this way we ensure that it would not be destroyed
during connection creation.
Examples:
examples/app/minesweeper/src/Style.cpp
Minesweeper Game - Minesweeper game implementation driven by ass.
void setupConnections(AView* view, const _<AAssHelper>& helper) override {
IAssSubSelector::setupConnections(view, helper);
view->customCssPropertyChanged.clearAllOutgoingConnectionsWith(helper.get());
AObject::connect(view->customCssPropertyChanged, AUI_SLOT(helper)::onInvalidateStateAss);
}
};
/// [CellSelector]
examples/app/game_of_life/src/main.cpp
Game of Life - Game of Life implementation that uses advanced large dynamic data rendering techniques such as ITexture, AImage to be GPU friendly. The computation is performed in AThreadPool.
for (auto s : { &mStorage, &mNextPopulation }) {
s->resize(size.x * size.y);
}
connect(mTimer->fired, me::frame);
connect(isRunning.changed, AUI_SLOT(mTimer)::setRunning);
}
void frame() {
mFrame = AThreadPool::global() * [&] {
examples/7guis/flight_booker/src/main.cpp
7GUIs Flight Booker - Flight Booker.
};
auto dateTextField(_<DateTextFieldState> state) {
return _new<ATextField>() AUI_LET {
AObject::connect(
state->parsed, it, [&it = *it, &state = *state](const AOptional<system_clock::time_point>& value) {
if (!value) {
return;
}
if (state.userChangesText.is_locked()) {
examples/ui/infinite_lazy_list/src/main.cpp
Infinite Lazy List - Usage of AUI_DECLARATIVE_FOR to make an infinite lazy list.
};
});
return Vertical {
AUI_DECLARATIVE_FOR(i, *state->items, AVerticalLayout) { return Label{} & i->value; },
Centered {
_new<ASpinnerV2>() AUI_LET {
AObject::connect(it->redrawn, AObject::GENERIC_OBSERVER, [state] {
// when a spinner appears, we indicate that we need more items.
state->needMore = true;
examples/app/minesweeper/src/MinesweeperWindow.cpp
Minesweeper Game - Minesweeper game implementation driven by ass.
MinesweeperWindow::MinesweeperWindow() : AWindow("Minesweeper", 100_dp, 100_dp) {
setContents(Vertical {
Horizontal {
Centered::Expanding {
_new<AButton>("New game...").connect(&AButton::clicked, me::newGame),
},
},
_container<AStackedLayout>(
{ // also assign ".frame" ASS class in place
mGrid = _new<AViewContainer>() << ".frame" }),
examples/app/minesweeper/src/NewGameWindow.cpp
Minesweeper Game - Minesweeper game implementation driven by ass.
Horizontal {
_new<ASpacerExpanding>(),
_new<AButton>("Start game") AUI_LET {
it->setDefault();
connect(it->clicked, me::begin);
},
_new<AButton>("Cancel").connect(&AButton::clicked, me::close),
} AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } },
} AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } });
examples/app/minesweeper/src/CellView.cpp
Minesweeper Game - Minesweeper game implementation driven by ass.
#include "AUI/Render/IRenderer.h"
CellView::CellView(FieldCell& cell) : mCell(cell), mCellValueCopy(cell) {
connect(clickedButton, this, [&]() {
emit customCssPropertyChanged();
});
}
void CellView::render(ARenderContext context) {
examples/app/fractal/src/FractalWindow.cpp
Fractal Example - Fractal viewer application demonstrating usage of custom shaders.
});
}
auto fractal = _new<FractalView>();
connect(fractal->centerPosChanged, this, [centerPosDisplay](const glm::dvec2& newPos, double scale) {
centerPosDisplay->setText("Center position: {} {}, scale: {}"_format(newPos.x, -newPos.y, scale));
});
setContents(Horizontal {
Stacked::Expanding {
examples/app/fractal/src/JumpToCoordsWindow.cpp
Fractal Example - Fractal viewer application demonstrating usage of custom shaders.
{ "Scale="_as, scale },
}) AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } },
Horizontal {
SpacerExpanding {},
_new<AButton>("Jump").connect(
&AButton::clicked, this,
[&, fractalView, re, im, scale]() {
try {
auto dRe = std::stod((*re->text()).toStdString());
auto dIm = -std::stod((*re->text()).toStdString());
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/7guis/timer/src/main.cpp
7GUIs Timer - Timer example.
} AUI_OVERRIDE_STYLE { Expanding { 1, 0 } },
} AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } },
_new<AButton>("Reset Timer") AUI_OVERRIDE_STYLE {
Expanding { 1, 0 },
} AUI_LET { connect(it->clicked, me::reset); },
} AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } },
});
connect(mTimer->fired, me::update);
mTimer->start();
examples/7guis/circle_drawer/src/main.cpp
7GUIs Circle Drawer - Undo, redo, dialog control.
BackgroundSolid(AColor::WHITE),
Border(1_px, AColor::GRAY),
AOverflow::HIDDEN_FROM_THIS,
});
connect(mState->circles.changed, me::redraw);
connect(mHoveredCircle.changed, me::redraw);
}
void render(ARenderContext ctx) override {
AView::render(ctx);
examples/7guis/crud/src/main.cpp
7GUIs CRUD - Create/Read/Update/Delete example.
Label { "Filter prefix:" },
_new<ATextField>() AUI_OVERRIDE_STYLE { Expanding(1, 0) } && mFilterPrefix,
} AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } },
AScrollArea::Builder().withExpanding().withContents(
AUI_DECLARATIVE_FOR(i, *mUsers | FILTER_VIEW, AVerticalLayout) {
auto view = _new<ALabel>();
view & i->displayName;
connect(mSelectedUser, view, [this, &view = *view, i] {
view.setAssName("selected", mSelectedUser == i);
});
examples/7guis/temperature_converter/src/main.cpp
7GUIs Temperature Converter - Fahrenheit to Celsius and vice versa.
Label { "°F" },
} AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } },
});
connect(mFahrenheit.changed, [&] { mCelsius = (*mFahrenheit - 32.f) * (5.f / 9.f); });
connect(mCelsius.changed, [&] { mFahrenheit = *mCelsius * (9.f / 5.f) + 32.f; });
}
private:
AProperty<int> mCelsius, mFahrenheit;
examples/7guis/cells/src/main.cpp
7GUIs Cells - Spreadsheet processor (Excel).
Cell& mCell;
AAbstractSignal::AutoDestroyedConnection mConnection;
void inflateLabel() {
mConnection = connect(mCell.value, [this](const formula::Value& v) {
ALayoutInflater::inflate(
this,
std::visit(
aui::lambda_overloaded {
[](std::nullopt_t) -> _<AView> { return _new<AView>(); },
examples/ui/minimal_ui_assets_xmake/src/MainWindow.cpp
Minimal UI Template XMake with Assets - Minimal UI boilerplate template XMake with AUI Assets.
Centered{
Vertical{
Centered { Icon { ":img/logo.svg" } AUI_OVERRIDE_STYLE { FixedSize(64_dp) } },
Centered { Label { "Hello world from AUI!" } },
_new<AButton>("Visit GitHub repo").connect(&AView::clicked, this, [] {
APlatform::openUrl("https://github.com/aui-framework/aui");
}),
_new<AButton>("Visit docs").connect(&AView::clicked, this, [] {
APlatform::openUrl("https://aui-framework.github.io/");
}),
examples/ui/minimal_ui_xmake/src/MainWindow.cpp
Minimal UI Template XMake - Minimal UI boilerplate template XMake.
setContents(
Centered{
Vertical{
Centered { Label { "Hello world from AUI!" } },
_new<AButton>("Visit GitHub repo").connect(&AView::clicked, this, [] {
APlatform::openUrl("https://github.com/aui-framework/aui");
}),
_new<AButton>("Visit docs").connect(&AView::clicked, this, [] {
APlatform::openUrl("https://aui-framework.github.io/");
}),
examples/ui/contacts/src/view/ContactDetailsView.cpp
AUI Contacts - Usage of AUI_DECLARATIVE_FOR to make a contacts-like application.
c(".row-value"),
Expanding(1, 0),
},
});
connect(mEditorMode, [this] {
setContents(Vertical::Expanding {
AScrollArea::Builder().withContents(Centered {
Vertical::Expanding {
Horizontal {
profilePhoto(mContact),
template<aui::detail::ConnectionSource ConnectionSource, aui::derived_from<AObjectBase> Object, typename Function >
static decltype(auto) AObject::connect(const ConnectionSource& connectionSource, ASlotDef<Object *, Function> slotDef)
Connects signal to the slot of the specified object. Slot is packed to single argument.
- Arguments
connectionSourcesignal or propertyslotDefinstance ofAObject+ slot- Returns
- Connection instance
See signal-slot system for more info.
connect(view->clicked, ASlotDef { AUI_SLOT(otherObject)::handleButtonClicked });
connect(textField->text(), ASlotDef { AUI_SLOT(otherObject)::handleText });
Note
This overload is applicable for cases when you NEED to pass object and its AUI_SLOT via single argument. If possible, consider using shorter overload:
connect(view->clicked, AUI_SLOT(otherObject)::handleButtonClicked);
Examples:
examples/app/minesweeper/src/Style.cpp
Minesweeper Game - Minesweeper game implementation driven by ass.
void setupConnections(AView* view, const _<AAssHelper>& helper) override {
IAssSubSelector::setupConnections(view, helper);
view->customCssPropertyChanged.clearAllOutgoingConnectionsWith(helper.get());
AObject::connect(view->customCssPropertyChanged, AUI_SLOT(helper)::onInvalidateStateAss);
}
};
/// [CellSelector]
examples/app/game_of_life/src/main.cpp
Game of Life - Game of Life implementation that uses advanced large dynamic data rendering techniques such as ITexture, AImage to be GPU friendly. The computation is performed in AThreadPool.
for (auto s : { &mStorage, &mNextPopulation }) {
s->resize(size.x * size.y);
}
connect(mTimer->fired, me::frame);
connect(isRunning.changed, AUI_SLOT(mTimer)::setRunning);
}
void frame() {
mFrame = AThreadPool::global() * [&] {
examples/7guis/flight_booker/src/main.cpp
7GUIs Flight Booker - Flight Booker.
};
auto dateTextField(_<DateTextFieldState> state) {
return _new<ATextField>() AUI_LET {
AObject::connect(
state->parsed, it, [&it = *it, &state = *state](const AOptional<system_clock::time_point>& value) {
if (!value) {
return;
}
if (state.userChangesText.is_locked()) {
examples/ui/infinite_lazy_list/src/main.cpp
Infinite Lazy List - Usage of AUI_DECLARATIVE_FOR to make an infinite lazy list.
};
});
return Vertical {
AUI_DECLARATIVE_FOR(i, *state->items, AVerticalLayout) { return Label{} & i->value; },
Centered {
_new<ASpinnerV2>() AUI_LET {
AObject::connect(it->redrawn, AObject::GENERIC_OBSERVER, [state] {
// when a spinner appears, we indicate that we need more items.
state->needMore = true;
examples/app/minesweeper/src/MinesweeperWindow.cpp
Minesweeper Game - Minesweeper game implementation driven by ass.
MinesweeperWindow::MinesweeperWindow() : AWindow("Minesweeper", 100_dp, 100_dp) {
setContents(Vertical {
Horizontal {
Centered::Expanding {
_new<AButton>("New game...").connect(&AButton::clicked, me::newGame),
},
},
_container<AStackedLayout>(
{ // also assign ".frame" ASS class in place
mGrid = _new<AViewContainer>() << ".frame" }),
examples/app/minesweeper/src/NewGameWindow.cpp
Minesweeper Game - Minesweeper game implementation driven by ass.
Horizontal {
_new<ASpacerExpanding>(),
_new<AButton>("Start game") AUI_LET {
it->setDefault();
connect(it->clicked, me::begin);
},
_new<AButton>("Cancel").connect(&AButton::clicked, me::close),
} AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } },
} AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } });
examples/app/minesweeper/src/CellView.cpp
Minesweeper Game - Minesweeper game implementation driven by ass.
#include "AUI/Render/IRenderer.h"
CellView::CellView(FieldCell& cell) : mCell(cell), mCellValueCopy(cell) {
connect(clickedButton, this, [&]() {
emit customCssPropertyChanged();
});
}
void CellView::render(ARenderContext context) {
examples/app/fractal/src/FractalWindow.cpp
Fractal Example - Fractal viewer application demonstrating usage of custom shaders.
});
}
auto fractal = _new<FractalView>();
connect(fractal->centerPosChanged, this, [centerPosDisplay](const glm::dvec2& newPos, double scale) {
centerPosDisplay->setText("Center position: {} {}, scale: {}"_format(newPos.x, -newPos.y, scale));
});
setContents(Horizontal {
Stacked::Expanding {
examples/app/fractal/src/JumpToCoordsWindow.cpp
Fractal Example - Fractal viewer application demonstrating usage of custom shaders.
{ "Scale="_as, scale },
}) AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } },
Horizontal {
SpacerExpanding {},
_new<AButton>("Jump").connect(
&AButton::clicked, this,
[&, fractalView, re, im, scale]() {
try {
auto dRe = std::stod((*re->text()).toStdString());
auto dIm = -std::stod((*re->text()).toStdString());
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/7guis/timer/src/main.cpp
7GUIs Timer - Timer example.
} AUI_OVERRIDE_STYLE { Expanding { 1, 0 } },
} AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } },
_new<AButton>("Reset Timer") AUI_OVERRIDE_STYLE {
Expanding { 1, 0 },
} AUI_LET { connect(it->clicked, me::reset); },
} AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } },
});
connect(mTimer->fired, me::update);
mTimer->start();
examples/7guis/circle_drawer/src/main.cpp
7GUIs Circle Drawer - Undo, redo, dialog control.
BackgroundSolid(AColor::WHITE),
Border(1_px, AColor::GRAY),
AOverflow::HIDDEN_FROM_THIS,
});
connect(mState->circles.changed, me::redraw);
connect(mHoveredCircle.changed, me::redraw);
}
void render(ARenderContext ctx) override {
AView::render(ctx);
examples/7guis/crud/src/main.cpp
7GUIs CRUD - Create/Read/Update/Delete example.
Label { "Filter prefix:" },
_new<ATextField>() AUI_OVERRIDE_STYLE { Expanding(1, 0) } && mFilterPrefix,
} AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } },
AScrollArea::Builder().withExpanding().withContents(
AUI_DECLARATIVE_FOR(i, *mUsers | FILTER_VIEW, AVerticalLayout) {
auto view = _new<ALabel>();
view & i->displayName;
connect(mSelectedUser, view, [this, &view = *view, i] {
view.setAssName("selected", mSelectedUser == i);
});
examples/7guis/temperature_converter/src/main.cpp
7GUIs Temperature Converter - Fahrenheit to Celsius and vice versa.
Label { "°F" },
} AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } },
});
connect(mFahrenheit.changed, [&] { mCelsius = (*mFahrenheit - 32.f) * (5.f / 9.f); });
connect(mCelsius.changed, [&] { mFahrenheit = *mCelsius * (9.f / 5.f) + 32.f; });
}
private:
AProperty<int> mCelsius, mFahrenheit;
examples/7guis/cells/src/main.cpp
7GUIs Cells - Spreadsheet processor (Excel).
Cell& mCell;
AAbstractSignal::AutoDestroyedConnection mConnection;
void inflateLabel() {
mConnection = connect(mCell.value, [this](const formula::Value& v) {
ALayoutInflater::inflate(
this,
std::visit(
aui::lambda_overloaded {
[](std::nullopt_t) -> _<AView> { return _new<AView>(); },
examples/ui/minimal_ui_assets_xmake/src/MainWindow.cpp
Minimal UI Template XMake with Assets - Minimal UI boilerplate template XMake with AUI Assets.
Centered{
Vertical{
Centered { Icon { ":img/logo.svg" } AUI_OVERRIDE_STYLE { FixedSize(64_dp) } },
Centered { Label { "Hello world from AUI!" } },
_new<AButton>("Visit GitHub repo").connect(&AView::clicked, this, [] {
APlatform::openUrl("https://github.com/aui-framework/aui");
}),
_new<AButton>("Visit docs").connect(&AView::clicked, this, [] {
APlatform::openUrl("https://aui-framework.github.io/");
}),
examples/ui/minimal_ui_xmake/src/MainWindow.cpp
Minimal UI Template XMake - Minimal UI boilerplate template XMake.
setContents(
Centered{
Vertical{
Centered { Label { "Hello world from AUI!" } },
_new<AButton>("Visit GitHub repo").connect(&AView::clicked, this, [] {
APlatform::openUrl("https://github.com/aui-framework/aui");
}),
_new<AButton>("Visit docs").connect(&AView::clicked, this, [] {
APlatform::openUrl("https://aui-framework.github.io/");
}),
examples/ui/contacts/src/view/ContactDetailsView.cpp
AUI Contacts - Usage of AUI_DECLARATIVE_FOR to make a contacts-like application.
c(".row-value"),
Expanding(1, 0),
},
});
connect(mEditorMode, [this] {
setContents(Vertical::Expanding {
AScrollArea::Builder().withContents(Centered {
Vertical::Expanding {
Horizontal {
profilePhoto(mContact),
template<AAnyProperty Property, typename Object, ACompatibleSlotFor<Property> Function >
static void AObject::connect(const Property& property, _<Object> object, Function&& function)
Connects signal or property to the slot of the specified non-AObject type.
- Arguments
propertysource property.objectinstance of `AObject`.functionslot. Can be lambda.
See signal-slot system for more info.
struct User { AProperty<AString> name }; // user.name here is non-AObject type
connect(textField->text(), user->name.assignment());
Note
object arg is accepted by value intentionally -- this way we ensure that it would not be destroyed during
connection creation.
Examples:
examples/app/minesweeper/src/Style.cpp
Minesweeper Game - Minesweeper game implementation driven by ass.
void setupConnections(AView* view, const _<AAssHelper>& helper) override {
IAssSubSelector::setupConnections(view, helper);
view->customCssPropertyChanged.clearAllOutgoingConnectionsWith(helper.get());
AObject::connect(view->customCssPropertyChanged, AUI_SLOT(helper)::onInvalidateStateAss);
}
};
/// [CellSelector]
examples/app/game_of_life/src/main.cpp
Game of Life - Game of Life implementation that uses advanced large dynamic data rendering techniques such as ITexture, AImage to be GPU friendly. The computation is performed in AThreadPool.
for (auto s : { &mStorage, &mNextPopulation }) {
s->resize(size.x * size.y);
}
connect(mTimer->fired, me::frame);
connect(isRunning.changed, AUI_SLOT(mTimer)::setRunning);
}
void frame() {
mFrame = AThreadPool::global() * [&] {
examples/7guis/flight_booker/src/main.cpp
7GUIs Flight Booker - Flight Booker.
};
auto dateTextField(_<DateTextFieldState> state) {
return _new<ATextField>() AUI_LET {
AObject::connect(
state->parsed, it, [&it = *it, &state = *state](const AOptional<system_clock::time_point>& value) {
if (!value) {
return;
}
if (state.userChangesText.is_locked()) {
examples/ui/infinite_lazy_list/src/main.cpp
Infinite Lazy List - Usage of AUI_DECLARATIVE_FOR to make an infinite lazy list.
};
});
return Vertical {
AUI_DECLARATIVE_FOR(i, *state->items, AVerticalLayout) { return Label{} & i->value; },
Centered {
_new<ASpinnerV2>() AUI_LET {
AObject::connect(it->redrawn, AObject::GENERIC_OBSERVER, [state] {
// when a spinner appears, we indicate that we need more items.
state->needMore = true;
examples/app/minesweeper/src/MinesweeperWindow.cpp
Minesweeper Game - Minesweeper game implementation driven by ass.
MinesweeperWindow::MinesweeperWindow() : AWindow("Minesweeper", 100_dp, 100_dp) {
setContents(Vertical {
Horizontal {
Centered::Expanding {
_new<AButton>("New game...").connect(&AButton::clicked, me::newGame),
},
},
_container<AStackedLayout>(
{ // also assign ".frame" ASS class in place
mGrid = _new<AViewContainer>() << ".frame" }),
examples/app/minesweeper/src/NewGameWindow.cpp
Minesweeper Game - Minesweeper game implementation driven by ass.
Horizontal {
_new<ASpacerExpanding>(),
_new<AButton>("Start game") AUI_LET {
it->setDefault();
connect(it->clicked, me::begin);
},
_new<AButton>("Cancel").connect(&AButton::clicked, me::close),
} AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } },
} AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } });
examples/app/minesweeper/src/CellView.cpp
Minesweeper Game - Minesweeper game implementation driven by ass.
#include "AUI/Render/IRenderer.h"
CellView::CellView(FieldCell& cell) : mCell(cell), mCellValueCopy(cell) {
connect(clickedButton, this, [&]() {
emit customCssPropertyChanged();
});
}
void CellView::render(ARenderContext context) {
examples/app/fractal/src/FractalWindow.cpp
Fractal Example - Fractal viewer application demonstrating usage of custom shaders.
});
}
auto fractal = _new<FractalView>();
connect(fractal->centerPosChanged, this, [centerPosDisplay](const glm::dvec2& newPos, double scale) {
centerPosDisplay->setText("Center position: {} {}, scale: {}"_format(newPos.x, -newPos.y, scale));
});
setContents(Horizontal {
Stacked::Expanding {
examples/app/fractal/src/JumpToCoordsWindow.cpp
Fractal Example - Fractal viewer application demonstrating usage of custom shaders.
{ "Scale="_as, scale },
}) AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } },
Horizontal {
SpacerExpanding {},
_new<AButton>("Jump").connect(
&AButton::clicked, this,
[&, fractalView, re, im, scale]() {
try {
auto dRe = std::stod((*re->text()).toStdString());
auto dIm = -std::stod((*re->text()).toStdString());
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/7guis/timer/src/main.cpp
7GUIs Timer - Timer example.
} AUI_OVERRIDE_STYLE { Expanding { 1, 0 } },
} AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } },
_new<AButton>("Reset Timer") AUI_OVERRIDE_STYLE {
Expanding { 1, 0 },
} AUI_LET { connect(it->clicked, me::reset); },
} AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } },
});
connect(mTimer->fired, me::update);
mTimer->start();
examples/7guis/circle_drawer/src/main.cpp
7GUIs Circle Drawer - Undo, redo, dialog control.
BackgroundSolid(AColor::WHITE),
Border(1_px, AColor::GRAY),
AOverflow::HIDDEN_FROM_THIS,
});
connect(mState->circles.changed, me::redraw);
connect(mHoveredCircle.changed, me::redraw);
}
void render(ARenderContext ctx) override {
AView::render(ctx);
examples/7guis/crud/src/main.cpp
7GUIs CRUD - Create/Read/Update/Delete example.
Label { "Filter prefix:" },
_new<ATextField>() AUI_OVERRIDE_STYLE { Expanding(1, 0) } && mFilterPrefix,
} AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } },
AScrollArea::Builder().withExpanding().withContents(
AUI_DECLARATIVE_FOR(i, *mUsers | FILTER_VIEW, AVerticalLayout) {
auto view = _new<ALabel>();
view & i->displayName;
connect(mSelectedUser, view, [this, &view = *view, i] {
view.setAssName("selected", mSelectedUser == i);
});
examples/7guis/temperature_converter/src/main.cpp
7GUIs Temperature Converter - Fahrenheit to Celsius and vice versa.
Label { "°F" },
} AUI_OVERRIDE_STYLE { LayoutSpacing { 4_dp } },
});
connect(mFahrenheit.changed, [&] { mCelsius = (*mFahrenheit - 32.f) * (5.f / 9.f); });
connect(mCelsius.changed, [&] { mFahrenheit = *mCelsius * (9.f / 5.f) + 32.f; });
}
private:
AProperty<int> mCelsius, mFahrenheit;
examples/7guis/cells/src/main.cpp
7GUIs Cells - Spreadsheet processor (Excel).
Cell& mCell;
AAbstractSignal::AutoDestroyedConnection mConnection;
void inflateLabel() {
mConnection = connect(mCell.value, [this](const formula::Value& v) {
ALayoutInflater::inflate(
this,
std::visit(
aui::lambda_overloaded {
[](std::nullopt_t) -> _<AView> { return _new<AView>(); },
examples/ui/minimal_ui_assets_xmake/src/MainWindow.cpp
Minimal UI Template XMake with Assets - Minimal UI boilerplate template XMake with AUI Assets.
Centered{
Vertical{
Centered { Icon { ":img/logo.svg" } AUI_OVERRIDE_STYLE { FixedSize(64_dp) } },
Centered { Label { "Hello world from AUI!" } },
_new<AButton>("Visit GitHub repo").connect(&AView::clicked, this, [] {
APlatform::openUrl("https://github.com/aui-framework/aui");
}),
_new<AButton>("Visit docs").connect(&AView::clicked, this, [] {
APlatform::openUrl("https://aui-framework.github.io/");
}),
examples/ui/minimal_ui_xmake/src/MainWindow.cpp
Minimal UI Template XMake - Minimal UI boilerplate template XMake.
setContents(
Centered{
Vertical{
Centered { Label { "Hello world from AUI!" } },
_new<AButton>("Visit GitHub repo").connect(&AView::clicked, this, [] {
APlatform::openUrl("https://github.com/aui-framework/aui");
}),
_new<AButton>("Visit docs").connect(&AView::clicked, this, [] {
APlatform::openUrl("https://aui-framework.github.io/");
}),
examples/ui/contacts/src/view/ContactDetailsView.cpp
AUI Contacts - Usage of AUI_DECLARATIVE_FOR to make a contacts-like application.
c(".row-value"),
Expanding(1, 0),
},
});
connect(mEditorMode, [this] {
setContents(Vertical::Expanding {
AScrollArea::Builder().withContents(Centered {
Vertical::Expanding {
Horizontal {
profilePhoto(mContact),
setThread#
void AObject::setThread(_<AAbstractThread> thread)
Set thread of the object.
Examples:
examples/ui/infinite_lazy_list/src/main.cpp
Infinite Lazy List - Usage of AUI_DECLARATIVE_FOR to make an infinite lazy list.
};
});
return Vertical {
AUI_DECLARATIVE_FOR(i, *state->items, AVerticalLayout) { return Label{} & i->value; },
Centered {
_new<ASpinnerV2>() AUI_LET {
AObject::connect(it->redrawn, AObject::GENERIC_OBSERVER, [state] {
// when a spinner appears, we indicate that we need more items.
state->needMore = true;