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/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/7guis/flight_booker/src/main.cpp

7GUIs Flight Booker - Flight Booker.

auto formatDate(system_clock::time_point date) { return "{0:%d}.{0:%m}.{0:%G}"_format(date); }

auto dateTextField(DateTextFieldState& state) {
    return _new<ATextField>() AUI_LET {
        AObject::biConnect(
            state.parsed.biProjected(aui::lambda_overloaded {
              [](const AOptional<system_clock::time_point>& v) -> AString {
                  if (!v) {
                      return "";
                  }

examples/7guis/counter/src/main.cpp

7GUIs Counter - Simple counter.

    CounterWindow(): AWindow("AUI - 7GUIs - Counter", 200_dp, 100_dp) {
        setContents(Centered {
          Horizontal {
            _new<ATextField>() AUI_LET {
                AObject::connect(mCounter.readProjected(AString::number<int>), it->text());
                it->setEditable(false);
            },
            Button { "Count" }.connect(&AView::clicked, [&] { mCounter += 1; }),
          },
        });

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/flight_booker/src/main.cpp

7GUIs Flight Booker - Flight Booker.

auto formatDate(system_clock::time_point date) { return "{0:%d}.{0:%m}.{0:%G}"_format(date); }

auto dateTextField(DateTextFieldState& state) {
    return _new<ATextField>() AUI_LET {
        AObject::biConnect(
            state.parsed.biProjected(aui::lambda_overloaded {
              [](const AOptional<system_clock::time_point>& v) -> AString {
                  if (!v) {
                      return "";
                  }
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_WITH_STYLE { Margin { {}, 16_dp } },
            myPicker() AUI_LET { biConnect(it->value(), mFahrenheit); },

connect#


template<AAnySignal Signal, aui::derived_from<AObjectBase> Object, ACompatibleSlotFor<Signal> Function >
static decltype(auto) AObject::connect(const Signal& signal, Object* object, Function&& function)

Connects signal to the slot of the specified object.

Arguments
signal
signal
object
instance of AObject
function
slot. Can be lambda
Returns
Connection instance

See signal-slot system for more info.

connect(view->clicked, AUI_DO_ONCE(otherObjectRawPtr)::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/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/7guis/counter/src/main.cpp

7GUIs Counter - Simple counter.

    CounterWindow(): AWindow("AUI - 7GUIs - Counter", 200_dp, 100_dp) {
        setContents(Centered {
          Horizontal {
            _new<ATextField>() AUI_LET {
                AObject::connect(mCounter.readProjected(AString::number<int>), it->text());
                it->setEditable(false);
            },
            Button { "Count" }.connect(&AView::clicked, [&] { mCounter += 1; }),
          },
        });
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/app/fractal/src/JumpToCoordsWindow.cpp

Fractal Example - Fractal viewer application demonstrating usage of custom shaders.

        { "Scale="_as, scale },
      }),
      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/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/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/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),
      },
    });
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/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/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),
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/7guis/crud/src/main.cpp

7GUIs CRUD - Create/Read/Update/Delete example.

                Label { "Filter prefix:" },
                _new<ATextField>() AUI_WITH_STYLE { Expanding(1, 0) } && mFilterPrefix,
              },
              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/flight_booker/src/main.cpp

7GUIs Flight Booker - Flight Booker.

        } });
        setContents(Centered {
          Vertical {
            _new<ADropdownList>(AListModel<AString>::make({ "one-way flight", "return flight" })) AUI_LET {
                    connect(it->selectionId().readProjected([](int selectionId) { return selectionId == 1; }),
                            mIsReturnFlight);
                },
            dateTextField(mDepartureDate),
            dateTextField(mReturnDate) AUI_LET { connect(mIsReturnFlight, AUI_SLOT(it)::setEnabled); },
            _new<AButton>("Book") AUI_LET {
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/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/temperature_converter/src/main.cpp

7GUIs Temperature Converter - Fahrenheit to Celsius and vice versa.

            Label { "°F" },
          },
        });

        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/timer/src/main.cpp

7GUIs Timer - Timer example.

                  },
            },
            _new<AButton>("Reset Timer") AUI_WITH_STYLE {
                  Expanding { 1, 0 },
                } AUI_LET { connect(it->clicked, me::reset); },
          },
        });

        connect(mTimer->fired, me::update);
        mTimer->start();

template<AAnyProperty Property, aui::derived_from<AObjectBase> Object, typename Function >
static decltype(auto) AObject::connect(const Property& property, Object* object, Function&& function)

Connects property to the slot of the specified object.

Arguments
property
property
object
instance of AObject
function
slot. Can be lambda

Connects to "changed" signal of the property. Additionally, calls specified function with the current value of the property (pre-fire).

See signal-slot system for more info.

connect(textField->text(), AUI_DO_ONCE(otherObjectRawPtr)::handleText);

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/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/7guis/counter/src/main.cpp

7GUIs Counter - Simple counter.

    CounterWindow(): AWindow("AUI - 7GUIs - Counter", 200_dp, 100_dp) {
        setContents(Centered {
          Horizontal {
            _new<ATextField>() AUI_LET {
                AObject::connect(mCounter.readProjected(AString::number<int>), it->text());
                it->setEditable(false);
            },
            Button { "Count" }.connect(&AView::clicked, [&] { mCounter += 1; }),
          },
        });
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/app/fractal/src/JumpToCoordsWindow.cpp

Fractal Example - Fractal viewer application demonstrating usage of custom shaders.

        { "Scale="_as, scale },
      }),
      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/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/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/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),
      },
    });
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/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/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),
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/7guis/crud/src/main.cpp

7GUIs CRUD - Create/Read/Update/Delete example.

                Label { "Filter prefix:" },
                _new<ATextField>() AUI_WITH_STYLE { Expanding(1, 0) } && mFilterPrefix,
              },
              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/flight_booker/src/main.cpp

7GUIs Flight Booker - Flight Booker.

        } });
        setContents(Centered {
          Vertical {
            _new<ADropdownList>(AListModel<AString>::make({ "one-way flight", "return flight" })) AUI_LET {
                    connect(it->selectionId().readProjected([](int selectionId) { return selectionId == 1; }),
                            mIsReturnFlight);
                },
            dateTextField(mDepartureDate),
            dateTextField(mReturnDate) AUI_LET { connect(mIsReturnFlight, AUI_SLOT(it)::setEnabled); },
            _new<AButton>("Book") AUI_LET {
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/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/temperature_converter/src/main.cpp

7GUIs Temperature Converter - Fahrenheit to Celsius and vice versa.

            Label { "°F" },
          },
        });

        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/timer/src/main.cpp

7GUIs Timer - Timer example.

                  },
            },
            _new<AButton>("Reset Timer") AUI_WITH_STYLE {
                  Expanding { 1, 0 },
                } AUI_LET { connect(it->clicked, me::reset); },
          },
        });

        connect(mTimer->fired, me::update);
        mTimer->start();

template<APropertyReadable PropertySource, APropertyWritable PropertyDestination >
static void AObject::connect(PropertySource&& propertySource, PropertyDestination&& propertyDestination)

Connects source property to the destination property.

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, dataflow is from left argument to the right argument.

connect pulls AObject from propertyDestination to maintain the connection.

See signal-slot system for more info.

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/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/7guis/counter/src/main.cpp

7GUIs Counter - Simple counter.

    CounterWindow(): AWindow("AUI - 7GUIs - Counter", 200_dp, 100_dp) {
        setContents(Centered {
          Horizontal {
            _new<ATextField>() AUI_LET {
                AObject::connect(mCounter.readProjected(AString::number<int>), it->text());
                it->setEditable(false);
            },
            Button { "Count" }.connect(&AView::clicked, [&] { mCounter += 1; }),
          },
        });
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/app/fractal/src/JumpToCoordsWindow.cpp

Fractal Example - Fractal viewer application demonstrating usage of custom shaders.

        { "Scale="_as, scale },
      }),
      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/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/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/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),
      },
    });
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/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/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),
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/7guis/crud/src/main.cpp

7GUIs CRUD - Create/Read/Update/Delete example.

                Label { "Filter prefix:" },
                _new<ATextField>() AUI_WITH_STYLE { Expanding(1, 0) } && mFilterPrefix,
              },
              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/flight_booker/src/main.cpp

7GUIs Flight Booker - Flight Booker.

        } });
        setContents(Centered {
          Vertical {
            _new<ADropdownList>(AListModel<AString>::make({ "one-way flight", "return flight" })) AUI_LET {
                    connect(it->selectionId().readProjected([](int selectionId) { return selectionId == 1; }),
                            mIsReturnFlight);
                },
            dateTextField(mDepartureDate),
            dateTextField(mReturnDate) AUI_LET { connect(mIsReturnFlight, AUI_SLOT(it)::setEnabled); },
            _new<AButton>("Book") AUI_LET {
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/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/temperature_converter/src/main.cpp

7GUIs Temperature Converter - Fahrenheit to Celsius and vice versa.

            Label { "°F" },
          },
        });

        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/timer/src/main.cpp

7GUIs Timer - Timer example.

                  },
            },
            _new<AButton>("Reset Timer") AUI_WITH_STYLE {
                  Expanding { 1, 0 },
                } AUI_LET { connect(it->clicked, me::reset); },
          },
        });

        connect(mTimer->fired, me::update);
        mTimer->start();

template<AAnySignalOrProperty Connectable, aui::derived_from<AObjectBase> Object, ACompatibleSlotFor<Connectable> Function >
static decltype(auto) AObject::connect(const Connectable& connectable, 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

signal-slot system for more info.

connect(view->clicked, AUI_DO_ONCE(otherObjectRef)::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/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/7guis/counter/src/main.cpp

7GUIs Counter - Simple counter.

    CounterWindow(): AWindow("AUI - 7GUIs - Counter", 200_dp, 100_dp) {
        setContents(Centered {
          Horizontal {
            _new<ATextField>() AUI_LET {
                AObject::connect(mCounter.readProjected(AString::number<int>), it->text());
                it->setEditable(false);
            },
            Button { "Count" }.connect(&AView::clicked, [&] { mCounter += 1; }),
          },
        });
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/app/fractal/src/JumpToCoordsWindow.cpp

Fractal Example - Fractal viewer application demonstrating usage of custom shaders.

        { "Scale="_as, scale },
      }),
      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/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/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/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),
      },
    });
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/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/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),
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/7guis/crud/src/main.cpp

7GUIs CRUD - Create/Read/Update/Delete example.

                Label { "Filter prefix:" },
                _new<ATextField>() AUI_WITH_STYLE { Expanding(1, 0) } && mFilterPrefix,
              },
              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/flight_booker/src/main.cpp

7GUIs Flight Booker - Flight Booker.

        } });
        setContents(Centered {
          Vertical {
            _new<ADropdownList>(AListModel<AString>::make({ "one-way flight", "return flight" })) AUI_LET {
                    connect(it->selectionId().readProjected([](int selectionId) { return selectionId == 1; }),
                            mIsReturnFlight);
                },
            dateTextField(mDepartureDate),
            dateTextField(mReturnDate) AUI_LET { connect(mIsReturnFlight, AUI_SLOT(it)::setEnabled); },
            _new<AButton>("Book") AUI_LET {
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/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/temperature_converter/src/main.cpp

7GUIs Temperature Converter - Fahrenheit to Celsius and vice versa.

            Label { "°F" },
          },
        });

        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/timer/src/main.cpp

7GUIs Timer - Timer example.

                  },
            },
            _new<AButton>("Reset Timer") AUI_WITH_STYLE {
                  Expanding { 1, 0 },
                } AUI_LET { connect(it->clicked, me::reset); },
          },
        });

        connect(mTimer->fired, me::update);
        mTimer->start();

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/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/7guis/counter/src/main.cpp

7GUIs Counter - Simple counter.

    CounterWindow(): AWindow("AUI - 7GUIs - Counter", 200_dp, 100_dp) {
        setContents(Centered {
          Horizontal {
            _new<ATextField>() AUI_LET {
                AObject::connect(mCounter.readProjected(AString::number<int>), it->text());
                it->setEditable(false);
            },
            Button { "Count" }.connect(&AView::clicked, [&] { mCounter += 1; }),
          },
        });
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/app/fractal/src/JumpToCoordsWindow.cpp

Fractal Example - Fractal viewer application demonstrating usage of custom shaders.

        { "Scale="_as, scale },
      }),
      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/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/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/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),
      },
    });
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/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/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),
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/7guis/crud/src/main.cpp

7GUIs CRUD - Create/Read/Update/Delete example.

                Label { "Filter prefix:" },
                _new<ATextField>() AUI_WITH_STYLE { Expanding(1, 0) } && mFilterPrefix,
              },
              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/flight_booker/src/main.cpp

7GUIs Flight Booker - Flight Booker.

        } });
        setContents(Centered {
          Vertical {
            _new<ADropdownList>(AListModel<AString>::make({ "one-way flight", "return flight" })) AUI_LET {
                    connect(it->selectionId().readProjected([](int selectionId) { return selectionId == 1; }),
                            mIsReturnFlight);
                },
            dateTextField(mDepartureDate),
            dateTextField(mReturnDate) AUI_LET { connect(mIsReturnFlight, AUI_SLOT(it)::setEnabled); },
            _new<AButton>("Book") AUI_LET {
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/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/temperature_converter/src/main.cpp

7GUIs Temperature Converter - Fahrenheit to Celsius and vice versa.

            Label { "°F" },
          },
        });

        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/timer/src/main.cpp

7GUIs Timer - Timer example.

                  },
            },
            _new<AButton>("Reset Timer") AUI_WITH_STYLE {
                  Expanding { 1, 0 },
                } AUI_LET { connect(it->clicked, me::reset); },
          },
        });

        connect(mTimer->fired, me::update);
        mTimer->start();

template<AAnySignalOrProperty Connectable, aui::derived_from<AObjectBase> Object, ACompatibleSlotFor<Connectable> Function >
static decltype(auto) AObject::connect(const Connectable& connectable, _<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_DO_ONCE(otherObjectSharedPtr)::handleButtonClicked);
connect(textField->text(), AUI_DO_ONCE(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/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/7guis/counter/src/main.cpp

7GUIs Counter - Simple counter.

    CounterWindow(): AWindow("AUI - 7GUIs - Counter", 200_dp, 100_dp) {
        setContents(Centered {
          Horizontal {
            _new<ATextField>() AUI_LET {
                AObject::connect(mCounter.readProjected(AString::number<int>), it->text());
                it->setEditable(false);
            },
            Button { "Count" }.connect(&AView::clicked, [&] { mCounter += 1; }),
          },
        });
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/app/fractal/src/JumpToCoordsWindow.cpp

Fractal Example - Fractal viewer application demonstrating usage of custom shaders.

        { "Scale="_as, scale },
      }),
      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/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/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/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),
      },
    });
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/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/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),
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/7guis/crud/src/main.cpp

7GUIs CRUD - Create/Read/Update/Delete example.

                Label { "Filter prefix:" },
                _new<ATextField>() AUI_WITH_STYLE { Expanding(1, 0) } && mFilterPrefix,
              },
              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/flight_booker/src/main.cpp

7GUIs Flight Booker - Flight Booker.

        } });
        setContents(Centered {
          Vertical {
            _new<ADropdownList>(AListModel<AString>::make({ "one-way flight", "return flight" })) AUI_LET {
                    connect(it->selectionId().readProjected([](int selectionId) { return selectionId == 1; }),
                            mIsReturnFlight);
                },
            dateTextField(mDepartureDate),
            dateTextField(mReturnDate) AUI_LET { connect(mIsReturnFlight, AUI_SLOT(it)::setEnabled); },
            _new<AButton>("Book") AUI_LET {
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/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/temperature_converter/src/main.cpp

7GUIs Temperature Converter - Fahrenheit to Celsius and vice versa.

            Label { "°F" },
          },
        });

        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/timer/src/main.cpp

7GUIs Timer - Timer example.

                  },
            },
            _new<AButton>("Reset Timer") AUI_WITH_STYLE {
                  Expanding { 1, 0 },
                } AUI_LET { connect(it->clicked, me::reset); },
          },
        });

        connect(mTimer->fired, me::update);
        mTimer->start();

template<AAnySignalOrProperty Connectable, aui::derived_from<AObjectBase> Object, typename Function >
static decltype(auto) AObject::connect(const Connectable& connectable, ASlotDef<Object *, Function> slotDef)

Connects signal to the slot of the specified object. Slot is packed to single argument.

Arguments
connectable
signal or property
slotDef
instance of AObject + slot
Returns
Connection instance

See signal-slot system for more info.

connect(view->clicked, ASlotDef { AUI_DO_ONCE(otherObject)::handleButtonClicked });
connect(textField->text(), ASlotDef { AUI_DO_ONCE(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_DO_ONCE(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/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/7guis/counter/src/main.cpp

7GUIs Counter - Simple counter.

    CounterWindow(): AWindow("AUI - 7GUIs - Counter", 200_dp, 100_dp) {
        setContents(Centered {
          Horizontal {
            _new<ATextField>() AUI_LET {
                AObject::connect(mCounter.readProjected(AString::number<int>), it->text());
                it->setEditable(false);
            },
            Button { "Count" }.connect(&AView::clicked, [&] { mCounter += 1; }),
          },
        });
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/app/fractal/src/JumpToCoordsWindow.cpp

Fractal Example - Fractal viewer application demonstrating usage of custom shaders.

        { "Scale="_as, scale },
      }),
      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/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/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/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),
      },
    });
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/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/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),
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/7guis/crud/src/main.cpp

7GUIs CRUD - Create/Read/Update/Delete example.

                Label { "Filter prefix:" },
                _new<ATextField>() AUI_WITH_STYLE { Expanding(1, 0) } && mFilterPrefix,
              },
              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/flight_booker/src/main.cpp

7GUIs Flight Booker - Flight Booker.

        } });
        setContents(Centered {
          Vertical {
            _new<ADropdownList>(AListModel<AString>::make({ "one-way flight", "return flight" })) AUI_LET {
                    connect(it->selectionId().readProjected([](int selectionId) { return selectionId == 1; }),
                            mIsReturnFlight);
                },
            dateTextField(mDepartureDate),
            dateTextField(mReturnDate) AUI_LET { connect(mIsReturnFlight, AUI_SLOT(it)::setEnabled); },
            _new<AButton>("Book") AUI_LET {
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/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/temperature_converter/src/main.cpp

7GUIs Temperature Converter - Fahrenheit to Celsius and vice versa.

            Label { "°F" },
          },
        });

        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/timer/src/main.cpp

7GUIs Timer - Timer example.

                  },
            },
            _new<AButton>("Reset Timer") AUI_WITH_STYLE {
                  Expanding { 1, 0 },
                } AUI_LET { connect(it->clicked, me::reset); },
          },
        });

        connect(mTimer->fired, me::update);
        mTimer->start();

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/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/7guis/counter/src/main.cpp

7GUIs Counter - Simple counter.

    CounterWindow(): AWindow("AUI - 7GUIs - Counter", 200_dp, 100_dp) {
        setContents(Centered {
          Horizontal {
            _new<ATextField>() AUI_LET {
                AObject::connect(mCounter.readProjected(AString::number<int>), it->text());
                it->setEditable(false);
            },
            Button { "Count" }.connect(&AView::clicked, [&] { mCounter += 1; }),
          },
        });
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/app/fractal/src/JumpToCoordsWindow.cpp

Fractal Example - Fractal viewer application demonstrating usage of custom shaders.

        { "Scale="_as, scale },
      }),
      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/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/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/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),
      },
    });
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/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/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),
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/7guis/crud/src/main.cpp

7GUIs CRUD - Create/Read/Update/Delete example.

                Label { "Filter prefix:" },
                _new<ATextField>() AUI_WITH_STYLE { Expanding(1, 0) } && mFilterPrefix,
              },
              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/flight_booker/src/main.cpp

7GUIs Flight Booker - Flight Booker.

        } });
        setContents(Centered {
          Vertical {
            _new<ADropdownList>(AListModel<AString>::make({ "one-way flight", "return flight" })) AUI_LET {
                    connect(it->selectionId().readProjected([](int selectionId) { return selectionId == 1; }),
                            mIsReturnFlight);
                },
            dateTextField(mDepartureDate),
            dateTextField(mReturnDate) AUI_LET { connect(mIsReturnFlight, AUI_SLOT(it)::setEnabled); },
            _new<AButton>("Book") AUI_LET {
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/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/temperature_converter/src/main.cpp

7GUIs Temperature Converter - Fahrenheit to Celsius and vice versa.

            Label { "°F" },
          },
        });

        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/timer/src/main.cpp

7GUIs Timer - Timer example.

                  },
            },
            _new<AButton>("Reset Timer") AUI_WITH_STYLE {
                  Expanding { 1, 0 },
                } AUI_LET { connect(it->clicked, me::reset); },
          },
        });

        connect(mTimer->fired, me::update);
        mTimer->start();

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;