Skip to content

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.

1
2
3
4
5
6
7
8
9
struct State {
    bool called = false;
};
auto state = _new<State>();
AObject::connect(master->message, AObject::GENERIC_OBSERVER, [state] {
    state->called = true;
});
master->broadcastMessage("hello");
EXPECT_TRUE(state->called);

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
propertySource
source property, whose value is preserved on connection creation.
propertyDestination
destination 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
connectionSource
The signal (or property) to connect.
receiver
Pointer to the target `AObject` instance.
function
Slot callable – can be a lambda or a member‑function pointer wrapped with `AUI_SLOT`.
Returns
A connection object that keeps the link alive.
// (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);
**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).

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
connectionSource
The signal (or property) to connect.
propertyDestination
destination 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
connectable
signal or property
function
slot. 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
connectable
signal or property
object
instance of AObject
function
slot. 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
connectionSource
signal or property
slotDef
instance of AObject + 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
property
source property.
object
instance of `AObject`.
function
slot. 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;