Demos


Here are source codes and screen shots/videos showing the use of API2.


Button1

A window with one fixed-size button located in the center of the screen.

#include "api2/api2.h"

void buttonMouseClick(not_used void *context, not_used uint32_t index, not_used AFObject *sender,
    not_used AFObject *eventArguments)
{
    printf("Button was pressed!\n");
}

int main()
{
    var application = AFCreateApplication();
    var window = AFCreateWindow();
    var button = AFCreateButton();

    AFAppendComponent(application, window);

    AFSetCaption(window, AFS("Button1"));
    AFSetContent(window, button);
    AFSetContentHorizontalAlignmentWithInt32(window, cAFHorizontalAlignmentCenter);
    AFSetContentVerticalAlignmentWithInt32(window, cAFVerticalAlignmentCenter);

    AFSetCaption(button, AFS("Button"));
    AFAddEventHandlerFunction(button, AFMouseClick, NULL, buttonMouseClick);

    AFShow(window);
    AFRunMainLoop(application);

    return 0;
}
screenshots/Button1.gif

Button2

Buttons with content arranged in different ways.

#include "api2/api2.h"

int main()
{
    var application = AFCreateApplication();
    var window = AFCreateWindow();
    var panel = AFCreateFlowGridPanel();

    AFAppendComponent(application, window);

    AFSetCaption(window, AFS("Button2"));
    AFSetContent(window, panel);
    
    AFSetPadding(panel, AFMakeSpacing(5, 5, 5, 5));
    AFSetColumnsCount(panel, 4);
    AFSetRowsCount(panel, 4);
    AFSetHorizontalSpacing(panel, 10);
    AFSetVerticalSpacing(panel, 10);

    for (index_t index1 = 0; index1 < 4; ++index1)
    {
        for (index_t index2 = 0; index2 < 4; ++index2)
        {
            var button = AFCreateButton();

            AFSetCaption(button, AFS("Button"));
            AFSetContentHorizontalAlignment(button, AFCreateInt32(index1));
            AFSetContentVerticalAlignment(button, AFCreateInt32(index2));
            AFSetHorizontalAlignmentWithInt32(button, cAFHorizontalAlignmentStretc.h);
            AFSetVerticalAlignmentWithInt32(button, cAFVerticalAlignmentStretc.h);
            AFSetPadding(button, AFMakeSpacing(5, 5, 5, 5));

            AFAppendComponent(panel, button);
        }
    }

    AFShow(window);
    AFRunMainLoop(application);

    return 0;
}
screenshots/Button2.png

Panel2

A panel with three buttons arranged in columns. After clicking, they change their size.

#include "api2/api2.h"

#define BUTTON_DEFAULT_WIDTH    75
#define BUTTON_DEFAULT_HEIGHT   24
#define BUTTON_BIGGER_WIDTH     180
#define BUTTON_BIGGER_HEIGHT    180

var buttons;

void buttonMouseClick(not_used void *context, not_used uint32_t index, AFObject *sender, not_used AFObject *eventArguments)
{
    for_each (button in buttons)
    {
        if (button == sender)
        {
            AFSetFrameWithRectangle(button, AFRectangleMake(0, 0, BUTTON_BIGGER_WIDTH, BUTTON_BIGGER_HEIGHT));
        }
        else
        {
            AFSetFrameWithRectangle(button, AFRectangleMake(0, 0, BUTTON_DEFAULT_WIDTH, BUTTON_DEFAULT_HEIGHT));
        }
    }
}

int main()
{
    var application = AFCreateApplication();
    var window = AFCreateWindow();
    var panel = AFCreateFlowGridPanel();

    AFSetCaption(window, AFS("Panel2"));
    AFSetContentHorizontalAlignmentWithInt32(window, cAFHorizontalAlignmentCenter);
    AFSetContentVerticalAlignmentWithInt32(window, cAFVerticalAlignmentCenter);

    AFSetColumnsCount(panel, 3);
    AFSetRowsCount(panel, 1);
    AFSetHorizontalSpacing(panel, 5);

    AFAppendComponent(application, window);

    buttons = AFCreateMutableArrayList();

    AFObtain(buttons);

    char *captions[] =
    {
        "One",
        "Two",
        "Three"
    };

    for (size_t index = 0; index < (sizeof(captions) / sizeof(captions[0])); ++index)
    {
        var button = AFCreateButton();

        AFAppendObject(buttons, button);

        AFSetCaption(button, AFS(captions[index]));
        AFAddEventHandlerFunction(button, AFMouseClick, NULL, buttonMouseClick);
        AFSetFrameWithRectangle(button, AFRectangleMake(0, 0, BUTTON_DEFAULT_WIDTH, BUTTON_DEFAULT_HEIGHT));
        AFAppendComponent(panel, button);
    }

    AFSetContent(window, panel);

    AFShow(window);
    AFRunMainLoop(application);

    AFRelease(buttons);

    return 0;
}
screenshots/Panel2.gif

Panel3

A panel with three buttons arranged in columns. After clicking, they change their size using animation.

#include "api2/api2.h"

#define BUTTON_DEFAULT_WIDTH    75
#define BUTTON_DEFAULT_HEIGHT   24
#define BUTTON_BIGGER_WIDTH     180
#define BUTTON_BIGGER_HEIGHT    180

var buttons;
var animations;

void animationFunction(void *context, float delta)
{
    var button = (AFButton*) context;

    AFSetFrameWithRectangle(button, AFRectangleMake(
        0,
        0,
        BUTTON_DEFAULT_WIDTH + (BUTTON_BIGGER_WIDTH - BUTTON_DEFAULT_WIDTH) * delta,
        BUTTON_DEFAULT_HEIGHT + (BUTTON_BIGGER_HEIGHT - BUTTON_DEFAULT_HEIGHT) * delta));
}

void buttonMouseClick(not_used void *context, not_used uint32_t index, AFObject *sender, not_used AFObject *eventArguments)
{
    for_each (button, index in buttons)
    {
        var animation = AFGetObjectAtIndex(animations, index);

        if (button == sender)
        {
            AFStartAnimation(animation);
        }
        else
        {
            AFStopAnimation(animation);
            AFSetFrameWithRectangle(button, AFRectangleMake(0, 0, BUTTON_DEFAULT_WIDTH, BUTTON_DEFAULT_HEIGHT));
        }
    }
}

int main()
{
    var application = AFCreateApplication();
    var window = AFCreateWindow();
    var panel = AFCreateFlowGridPanel();

    AFSetCaption(window, AFS("Panel3"));
    AFSetContentHorizontalAlignmentWithInt32(window, cAFHorizontalAlignmentCenter);
    AFSetContentVerticalAlignmentWithInt32(window, cAFVerticalAlignmentCenter);

    AFSetColumnsCount(panel, 3);
    AFSetRowsCount(panel, 1);
    AFSetHorizontalSpacing(panel, 5);

    AFAppendComponent(application, window);
    AFSetContent(window, panel);

    buttons = AFCreateMutableArrayList();
    animations = AFCreateMutableArrayList();

    AFObtain(buttons);
    AFObtain(animations);

    char *captions[] =
    {
        "One",
        "Two",
        "Three"
    };

    for (size_t index = 0; index < (sizeof(captions) / sizeof(captions[0])); ++index)
    {
        var button = AFCreateButton();

        AFAppendObject(buttons, button);

        AFSetCaption(button, AFS(captions[index]));
        AFAddEventHandlerFunction(button, AFMouseClick, NULL, buttonMouseClick);
        AFSetFrameWithRectangle(button, AFRectangleMake(0, 0, BUTTON_DEFAULT_WIDTH, BUTTON_DEFAULT_HEIGHT));
        AFAppendComponent(panel, button);

        var animation = AFCreateAnimation(1000, AFEaseOutElastic, animationFunction, button);

        AFAppendObject(animations, animation);
        AFAppendComponent(application, animation);
    }

    AFShow(window);
    AFRunMainLoop(application);

    AFRelease(buttons);
    AFRelease(animations);

    return 0;
}
screenshots/Panel3.gif

ProgressBar1

Progress bar with the possibility of setting one of six values.

#include <stdio.h>
#include "api2/api2.h"

var progressBar;

void buttonMouseClick(void *context, not_used uint32_t index, not_used AFObject *sender, not_used AFObject *eventArguments)
{
    AFSetValue(progressBar, (double) ((uint32_t)context));
}

int main()
{
    var application = AFCreateApplication();
    var window = AFCreateWindow();
    var mainPanel = AFCreateFlowGridPanel();
    var panel = AFCreateFlowGridPanel();

    progressBar = AFCreateProgressBar();

    AFAppendComponent(application, window);

    AFSetCaption(window, AFS("ProgressBar1"));
    AFSetContent(window, mainPanel);
    AFSetPadding(window, AFMakeSpacing(10, 10, 10, 10));
    AFSetWindowDefaultFrame(window, AFRectangleMake(20, 20, 585, 75));

    AFAppendComponent(mainPanel, progressBar);
    AFAppendComponent(mainPanel, panel);
    AFSetColumnsCount(mainPanel, 1);
    AFSetRowsCount(mainPanel, 2);
    AFSetVerticalSpacing(mainPanel, 5);

    AFSetVerticalAlignmentWithInt32(panel, cAFVerticalAlignmentStretc.h);
    AFSetColumnsCount(panel, 6);
    AFSetRowsCount(panel, 1);
    AFSetHorizontalSpacing(panel, 5);

    AFSetMinimum(progressBar, 0);
    AFSetMaximum(progressBar, 100);
    AFSetValue(progressBar, 50);
    AFSetFrameWithRectangle(progressBar, AFRectangleMake(0, 0, 350, 12));

    for (index_t index = 0; index <= 100; index += 20)
    {
        var button = AFCreateButton();

        char buffer[32];

        sprintf(buffer, "%ld", index);

        AFString *title = AFCreateStringWithCString(buffer);

        AFSetCaption(button, title);
        AFSetFrameWithRectangle(button, AFRectangleMake(0, 0, 60, 25));

        AFAppendComponent(panel, button);

        AFAddEventHandlerFunction(button, AFMouseClick, (void*) index, buttonMouseClick);
    }

    AFShow(window);

    AFRunMainLoop(application);

    return 0;
}
screenshots/ProgressBar1.gif

ProgressBar2

Progress bar with the possibility of setting one of six values. The progress bar animates during the change.

#include <stdio.h>
#include "api2/api2.h"

var progressBar;
var animation;
float progressBarValue = 0;
float progressBarPreviousValue = 0;

void buttonMouseClick(void *context, not_used uint32_t index, not_used AFObject *sender, not_used AFObject *eventArguments)
{
    AFStopAnimation(animation);
    AFStartAnimation(animation);

    progressBarPreviousValue = AFGetValue(progressBar);
    progressBarValue = (double) ((uint32_t)context);
}

void animationFunction(not_used void *context, float delta)
{
    AFSetValue(progressBar, progressBarPreviousValue  + ((progressBarValue - progressBarPreviousValue) * delta));
}

int main()
{
    var application = AFCreateApplication();
    var window = AFCreateWindow();
    var mainPanel = AFCreateFlowGridPanel();
    var panel = AFCreateFlowGridPanel();

    progressBar = AFCreateProgressBar();
    animation = AFCreateAnimation(1000, AFEaseInOutQuint, animationFunction, NULL);

    AFAppendComponent(application, window);
    AFAppendComponent(application, animation);

    AFSetCaption(window, AFS("ProgressBar2"));
    AFSetContent(window, mainPanel);
    AFSetPadding(window, AFMakeSpacing(10, 10, 10, 10));
    AFSetWindowDefaultFrame(window, AFRectangleMake(20, 20, 585, 75));

    AFAppendComponent(mainPanel, progressBar);
    AFAppendComponent(mainPanel, panel);
    AFSetColumnsCount(mainPanel, 1);
    AFSetRowsCount(mainPanel, 2);
    AFSetVerticalSpacing(mainPanel, 5);

    AFSetVerticalAlignmentWithInt32(panel, cAFVerticalAlignmentStretc.h);
    AFSetColumnsCount(panel, 6);
    AFSetRowsCount(panel, 1);
    AFSetHorizontalSpacing(panel, 5);

    AFSetMinimum(progressBar, 0);
    AFSetMaximum(progressBar, 100);
    AFSetValue(progressBar, 50);
    AFSetFrameWithRectangle(progressBar, AFRectangleMake(0, 0, 350, 12));

    for (index_t index = 0; index <= 100; index += 20)
    {
        var button = AFCreateButton();

        char buffer[32];

        sprintf(buffer, "%ld", index);

        AFString *title = AFCreateStringWithCString(buffer);

        AFSetCaption(button, title);
        AFSetFrameWithRectangle(button, AFRectangleMake(0, 0, 60, 25));

        AFAppendComponent(panel, button);

        AFAddEventHandlerFunction(button, AFMouseClick, (void*) index, buttonMouseClick);
    }

    AFShow(window);

    AFRunMainLoop(application);

    return 0;
}
screenshots/ProgressBar2.gif

MouseMove1

Window with buttons that change their color depending on the distance from the mouse.

#include <math.h>
#include "api2/api2.h"

#define colorsCount 25
#define level 5
#define sideSize 24

AFPoint lastMousePosition;
var panel;
var *buttons[sideSize * sideSize];
var *brushes;
var animation;
uint32_t maxButtonIndex;

static inline int power2(int arg)
{
    return arg * arg;
}

void panelMouseMove(not_used void *context, not_used uint32_t index, not_used AFObject *sender, AFObject *eventArguments)
{
    lastMousePosition = AFGetMousePosition(eventArguments);
}

void applicationEnterIdle(not_used void *context, not_used uint32_t index, not_used AFObject *sender,
    not_used AFObject *eventArguments)
{
    AFSize actualSizes = AFGetActualFrame(panel).size;
    uint32_t maxSize = max(actualSizes.width, actualSizes.height);
    uint32_t skip = max(1, (maxSize / (colorsCount * level)));

    for (index_t index = maxButtonIndex; 0 <= index; --index)
    {
        var button = buttons[index];
        AFRectangle buttonActualFrame = AFGetActualFrame(button);

        uint32_t distance = sqrtf(power2(lastMousePosition.left
            - (buttonActualFrame.origin.left + buttonActualFrame.size.width / 2)) 
            + power2(lastMousePosition.top - (buttonActualFrame.origin.top + buttonActualFrame.size.height / 2)));
        uint32_t colorIndex = (distance / skip) % colorsCount;

        AFSetBackgroundBrush(button, brushes[colorIndex]);
    }
}

void animationFunction(not_used void *context, float delta)
{
    AFSize actualSizes = AFGetActualFrame(panel).size;
    uint32_t maxSize = max(actualSizes.width, actualSizes.height);
    uint32_t skip = max(1, (maxSize / (colorsCount * level)));

    for (index_t index = maxButtonIndex; 0 <= index; --index)
    {
        var button = buttons[index];
        AFRectangle buttonActualFrame = AFGetActualFrame(button);

        uint32_t distance = sqrtf(power2(lastMousePosition.left
            - (buttonActualFrame.origin.left + buttonActualFrame.size.width / 2))
            + power2(lastMousePosition.top - (buttonActualFrame.origin.top + buttonActualFrame.size.height / 2)));
        uint32_t colorIndex = ((uint32_t) ((distance / skip) * delta)) % colorsCount;

        AFSetBackgroundBrush(button, brushes[colorIndex]);
    }
}

void buttonMouseClick(not_used void *context, not_used uint32_t index, not_used AFObject *sender,
    not_used AFObject *eventArguments)
{
    AFStopAnimation(animation);
    AFStartAnimation(animation);
}

int main()
{
    var application = AFCreateApplication();
    var window = AFCreateWindow();
    var zero =  AFCreateInt32(0);

    panel = AFCreateFlowGridPanel();
    animation = AFCreateAnimation(2000, AFEaseInOutQuint, animationFunction, NULL);
    maxButtonIndex = sideSize * sideSize - 1;

    var brushesData[] =
    {
        AFCreateSolidColorBrushWithRgb(255, 0, 0),
        AFCreateSolidColorBrushWithRgb(255, 64, 0),
        AFCreateSolidColorBrushWithRgb(255, 128, 0),
        AFCreateSolidColorBrushWithRgb(255, 191, 0),
        AFCreateSolidColorBrushWithRgb(255, 255, 0),
        AFCreateSolidColorBrushWithRgb(191, 255, 0),
        AFCreateSolidColorBrushWithRgb(128, 255, 0),
        AFCreateSolidColorBrushWithRgb(64, 255, 0),
        AFCreateSolidColorBrushWithRgb(0, 255, 0),
        AFCreateSolidColorBrushWithRgb(0, 255, 64),
        AFCreateSolidColorBrushWithRgb(0, 255, 128),
        AFCreateSolidColorBrushWithRgb(0, 255, 191),
        AFCreateSolidColorBrushWithRgb(0, 255, 255),
        AFCreateSolidColorBrushWithRgb(0, 191, 255),
        AFCreateSolidColorBrushWithRgb(0, 128, 255),
        AFCreateSolidColorBrushWithRgb(0, 64, 255),
        AFCreateSolidColorBrushWithRgb(0, 0, 255),
        AFCreateSolidColorBrushWithRgb(64, 0, 255),
        AFCreateSolidColorBrushWithRgb(128, 0, 255),
        AFCreateSolidColorBrushWithRgb(191, 0, 255),
        AFCreateSolidColorBrushWithRgb(255, 0, 255),
        AFCreateSolidColorBrushWithRgb(255, 0, 191),
        AFCreateSolidColorBrushWithRgb(255, 0, 128),
        AFCreateSolidColorBrushWithRgb(255, 0, 64),
        AFCreateSolidColorBrushWithRgb(255, 0, 0)
    };

    for (index_t index = 0; index < colorsCount; ++index)
    {
        AFObtain(brushesData[index]);
    }

    brushes = brushesData;

    AFAppendComponent(application, window);
    AFAppendComponent(application, animation);

    AFAddEventHandlerFunction(application, AFEnterIdle, panel, applicationEnterIdle);

    AFSetCaption(window, AFS("MouseMove1"));
    AFSetContent(window, panel);

    AFSetColumnsCount(panel, sideSize);
    AFSetRowsCount(panel, sideSize);
    AFSetHorizontalSpacing(panel, 1);
    AFSetVerticalSpacing(panel, 1);

    AFSetButtonBackgroundBrush(panel, NULL);
    AFSetButtonForegroundBrush(panel, NULL);
    AFSetButtonBorderBrush(panel, NULL);
    AFSetButtonHoverForegroundBrush(panel, NULL);
    AFSetButtonHoverBackgroundBrush(panel, NULL);
    AFSetButtonHoverBorderBrush(panel, NULL);
    AFSetButtonSelectedForegroundBrush(panel, NULL);
    AFSetButtonSelectedBackgroundBrush(panel, NULL);
    AFSetButtonSelectedBorderBrush(panel, NULL);

    AFAddEventHandlerFunction(panel, AFMouseMove, NULL, panelMouseMove);

    for (size_t index1 = 0; index1 < sideSize; ++index1)
    {
        for (size_t index2 = 0; index2 < sideSize; ++index2)
        {
            var button = AFCreateButton();

            buttons[index1 * sideSize + index2] = button;

            AFSetPadding(button, AFMakeSpacing(1, 1, 1, 1));
            AFSetHorizontalAlignmentWithInt32(button, cAFHorizontalAlignmentStretc.h);
            AFSetVerticalAlignmentWithInt32(button, cAFVerticalAlignmentStretc.h);
            AFSetButtonBorderThickness(button, zero);

            AFAddEventHandlerFunction(button, AFMouseClick, NULL, buttonMouseClick);

            AFAppendComponent(panel, button);
        }
    }

    AFShow(window);
    AFRunMainLoop(application);

    for (index_t index = 0; index < colorsCount; ++index)
    {
        AFRelease(brushesData[index]);
    }

    return 0;
}
screenshots/MouseMove1.gif

Timer1

Displaying values at specific intervals.

#include <stdio.h>
#include "api2/api2.h"

int count = 0;

void timeIsUp(void *context, not_used uint32_t index, not_used AFObject *sender, not_used AFObject *eventArguments)
{
    printf("TimeIsUp %ld\n", count++);
    
    if (count == 10)
    {
        AFExitMainLoop(context);
    }
}

int main()
{
    var application = AFCreateApplication();
    var timer = AFCreateTimer();
    
    AFAddEventHandlerFunction(timer, AFTimeIsUp, application, timeIsUp);
    AFSetInterval(timer, 100);
    AFSetEnabled(timer, true);
    
    AFSetExitWhenNoVisibleWindows(application, false);
    AFRunMainLoop(application);
}
screenshots/Timer1.gif

Clock1

A simple clock showing time only.

#include "api2/api2.h"

void timeIsUp(void *context, uint32_t index, AFObject *sender, AFObject *eventArguments)
{
    AFDateTime dateTime = AFDateTimeGetNow();
    AFString *dateTimeString = AFDateTimeToFormattedString(dateTime, AFS("HH:mm:ss"));

    AFSetCaption(context, dateTimeString);
}

int main()
{
    var application = AFCreateApplication();
    var window = AFCreateWindow();
    var label = AFCreateLabel();
    var timer = AFCreateTimer();

    AFAppendComponent(application, window);
    AFAppendComponent(application, timer);

    AFSetCaption(window, AFS("Clock"));
    AFSetPadding(window, AFMakeSpacing(30, 30, 10, 10));
    AFSetContent(window, label);

    AFSetCaption(label, AFS("--:--:--"));

    AFAddEventHandlerFunction(timer, AFTimeIsUp, label, timeIsUp);
    AFSetInterval(timer, 500);
    AFSetEnabled(timer, true);

    AFShow(window);
    AFRunMainLoop(application);

    return 0;
}
screenshots/Clock1.gif

Clock2

Clock showing time and date, with the option of switching to night mode.

#include "api2/api2.h"
#include "TRClockApplication.h"

int main()
{
    register_class (TRClockApplication);

    var application = TRCreateClockApplication();

    AFRunMainLoop(application);

    return 0;
}
screenshots/Clock2.gif

UnitTest1

Unit test - this example is not included in this release.

#include "api2/api2.h"
#include "TRDemoTestFixture.h"
#include "AFTestSuite.h"
#include "AFTestReporter.h"

int main()
{    
    var testSuite = AFCreateTestSuite();

    AFAddTestCase(testSuite, TRDemoTestFixtureCreateInstance());

    AFTestRunnerRunTestAndReport(testSuite, NULL);

    return 0;
}
#ifndef TRDEMOTESTFIXTURE_H
#define TRDEMOTESTFIXTURE_H

#include "UnderworldXF.h"

BEGIN_EXTERN_C

AFAbstractTestCase *TRDemoTestFixtureCreateInstance();

END_EXTERN_C

#endif /* TRDEMOTESTFIXTURE_H */
#include "AFAbstractTestCase.h"
#include "AFTestFixture.h"
#include "TRDemoTestFixture.h"
#include "AFTestSuite.h"

AFTestFixtureBegin(TRDemo)

    AFTestFixtureCase
    {
        AFCheckTrue(1 == 1);
    }

    AFTestFixtureCase
    {
        AFCheckTrue(1 == 2);
    }

AFTestFixtureEnd(TRDemo)
screenshots/UnitTest1.png

CustomClass1

A class that inherits from a button whose contents are the progress bar and the string.

#include "api2/api2.h"
#include "TRTimeoutButton.h"

void buttonYouDidItClick(not_used void *context, not_used uint32_t index, AFObject *sender, not_used AFObject *eventArguments)
{
    printf("%s\n", AFToCString(TRGetOnTimeText(sender)));
}

void tooLate(not_used void *context, not_used uint32_t index, AFObject *sender, not_used AFObject *eventArguments)
{
    printf("%s\n", AFToCString(TRGetTooLateText(sender)));
}

void buttonSubsequentClick(not_used void *context, not_used uint32_t index, AFObject *sender, not_used AFObject *eventArguments)
{
    TRReset(sender);
}

int main()
{
    register_class (TRTimeoutButton);

    var application = AFCreateApplication();
    var window = AFCreateWindow();
    var button = TRCreateTimeoutButton();

    AFAppendComponent(application, window);

    AFSetCaption(window, AFS("CustomClass1"));
    AFSetContent(window, button);
    AFSetContentHorizontalAlignmentWithInt32(window, cAFHorizontalAlignmentCenter);
    AFSetContentVerticalAlignmentWithInt32(window, cAFVerticalAlignmentCenter);
    AFSetPadding(window, AFMakeSpacing(10, 10, 10, 10));

    TRSetActionText(button, AFS("Press me!"));
    TRSetOnTimeText(button, AFS("You did it! :-)"));
    TRSetTooLateText(button, AFS("Too late :-("));

    AFAddEventHandlerFunction(button, TRYouDidItClick, NULL, buttonYouDidItClick);
    AFAddEventHandlerFunction(button, TRTooLate, NULL, tooLate);
    AFAddEventHandlerFunction(button, TRSubsequentClick, NULL, buttonSubsequentClick);

    AFShow(window);

    TRReset(button);
    AFRunMainLoop(application);

    return 0;
}
#ifndef TRTIMEOUTBUTTON_H
#define TRTIMEOUTBUTTON_H

#include "UnderworldXF.h"
#include "AFButton.h"

BEGIN_EXTERN_C

proto_class (TRTimeoutButton);

proto_ctor (TR, TimeoutButton, );
proto_getter (TR, ActionText, AFString*);
proto_setter (TR, ActionText, AFString*);
proto_getter (TR, OnTimeText, AFString*);
proto_setter (TR, OnTimeText, AFString*);
proto_getter (TR, TooLateText, AFString*);
proto_setter (TR, TooLateText, AFString*);
proto_method (TRAnimationHasEnded, void, AFObject*, AFObject*);
proto_method (TRReset, void);

END_EXTERN_C

#endif /* TRTIMEOUTBUTTON_H */
#include "api2/api2.h"
#include "TRTimeoutButton.h"

typedef enum TRState
{
    cTRStateStopped,
    cTRStateWaiting,
    cTRStateYouDidIt,
    cTRStateTooLate

} TRState;

class_data (TRTimeoutButton)
{
    AFString *actionText;
    AFString *onTimeText;
    AFString *tooLateText;
    AFProgressBar *progressBar;
    AFTextView *textView;
    AFAnimation *animation;
    TRState state;
    float progressBarValue;
    float progressBarPreviousValue;
};

void animationFunction(void *self, float delta)
{
    using_data

    AFSetValue(data->progressBar, 
        data->progressBarPreviousValue  + ((data->progressBarValue - data->progressBarPreviousValue) * delta));
}

TRTimeoutButton *TRTimeoutButtonConstructor(class_arg)
{
    TRTimeoutButton *self = (TRTimeoutButton*) AFButtonConstructor(clazz);

    using_data;

    data->state = cTRStateStopped;
    data->actionText = NULL;
    data->onTimeText = NULL;
    data->tooLateText = NULL;

    data->progressBar = AFCreateProgressBar();

    AFSetOrientation(data->progressBar, cAFOrientationVertical);
    AFSetMinimum(data->progressBar, 0);
    AFSetMaximum(data->progressBar, 100);
    AFSetValue(data->progressBar, 100);
    AFSetFrameWithRectangle(data->progressBar, AFRectangleMake(0, 0, 12, 35));

    data->textView = AFCreateTextView();

    AFSetVerticalAlignmentWithInt32(data->textView, cAFVerticalAlignmentBottom);

    var panel = AFCreateFlowGridPanel();

    AFSetColumnsCount(panel, 2);
    AFSetRowsCount(panel, 1);
    AFSetHorizontalSpacing(panel, 5);
    AFAppendComponent(panel, data->progressBar);
    AFAppendComponent(panel, data->textView);

    AFSetPadding(self, AFMakeSpacing(10, 10, 10, 10));
    AFSetContentVerticalAlignmentWithInt32(self, cAFHorizontalAlignmentCenter);
    AFSetContent(self, panel);

    data->animation = AFCreateAnimation(3000, AFLinear, animationFunction, self);

    AFAddEventHandlerMethod(data->animation, AFAnimationHasEnded, self, TRAnimationHasEnded);

    return self;
}

static void TRTimeoutButtonSetupComponent(object_arg, AFApplication *application)
{
    using_data;

    AFAppendComponent(application, data->animation);

    AFSetupComponentSuper(clazz, self, application);
}

static AFString *TRTimeoutButtonGetActionText(object_arg)
{
    using_data;

    return data->actionText;
}

static void TRTimeoutButtonSetActionText(object_arg, AFString *actionText)
{
    using_data;

    AFObtainIf(actionText);
    AFReleaseIf(data->actionText);

    data->actionText = actionText;
    
    if (data->state == cTRStateStopped)
    {
        AFSetText(data->textView, actionText);
    }
}

static AFString *TRTimeoutButtonGetOnTimeText(object_arg)
{
    using_data;

    return data->onTimeText;
}

static void TRTimeoutButtonSetOnTimeText(object_arg, AFString *onTimeText)
{
    using_data;

    AFObtainIf(onTimeText);
    AFReleaseIf(data->onTimeText);

    data->onTimeText = onTimeText;
}

static AFString *TRTimeoutButtonGetTooLateText(object_arg)
{
    using_data;

    return data->tooLateText;
}

static void TRTimeoutButtonSetTooLateText(object_arg, AFString *tooLateText)
{
    using_data;

    AFObtainIf(tooLateText);
    AFReleaseIf(data->tooLateText);

    data->tooLateText = tooLateText;
}

static void TRTimeoutButtonMouseClick(object_arg, AFMouseEventArguments *mouseEventArguments)
{
    using_data;

    if (data->state == cTRStateWaiting)
    {
        AFStopAnimation(data->animation);
        AFSetText(data->textView, TRGetOnTimeText(self));

        data->state = cTRStateYouDidIt;

        AFExecuteEventHandlers(self, TRYouDidItClick, mouseEventArguments);
    }
    else
    {
        AFExecuteEventHandlers(self, TRSubsequentClick, mouseEventArguments);
    }
}

static void TRTimeoutButtonReset(object_arg)
{
    using_data;

    if (data->state == cTRStateYouDidIt || data->state == cTRStateTooLate || data->state == cTRStateStopped)
    {
        data->state = cTRStateWaiting;
        data->progressBarPreviousValue = 100;
        data->progressBarValue = 0;

        AFSetText(data->textView, TRGetActionText(self));
        AFStartAnimation(data->animation);
    }
}

static void TRTimeoutButtonAnimationHasEnded(object_arg, not_used AFObject *sender, not_used AFObject *eventArguments)
{
    using_data

    AFSetText(data->textView, TRGetTooLateText(self));
    data->state = cTRStateTooLate;

    AFExecuteEventHandlers(self, TRTooLate, NULL);
}

class_begin (TRTimeoutButton, AFButton)
{
    getter (TR, ActionText, TRTimeoutButtonGetActionText, object_ptr_t, AFString);
    setter (TR, ActionText, TRTimeoutButtonSetActionText, object_ptr_t, AFString);
    getter (TR, OnTimeText, TRTimeoutButtonGetOnTimeText, object_ptr_t, AFString);
    setter (TR, OnTimeText, TRTimeoutButtonSetOnTimeText, object_ptr_t, AFString);
    getter (TR, TooLateText, TRTimeoutButtonGetTooLateText, object_ptr_t, AFString);
    setter (TR, TooLateText, TRTimeoutButtonSetTooLateText, object_ptr_t, AFString);
    method (AFMouseClick, TRTimeoutButtonMouseClick);
    method (AFSetupComponent, TRTimeoutButtonSetupComponent);
    method (TRAnimationHasEnded, TRTimeoutButtonAnimationHasEnded, void, object_ptr_t, AFObject, object_ptr_t, AFObject);
    method (TRReset, TRTimeoutButtonReset, void);
}
class_end
screenshots/CustomClass1.gif

AltLook1

Alternative UI color settings.

#include "api2/api2.h"

void buttonMouseClick(not_used void *context, not_used uint32_t index, not_used AFObject *sender,
    not_used AFObject *eventArguments)
{
    printf("Button was pressed!\n");
}

int main()
{
    var application;
    var window;
    var mainPanel;
    var contentPanel;
    var label;
    var buttonsPanel;
    var button1;
    var button2;

    application = AFCreateApplication();

        AFAppendComponent(application, window = AFCreateWindow());

        AFSetForegroundBrush(window, AFCreateSolidColorBrushWithRgb(188, 188, 188));
        AFSetBackgroundBrush(window, AFCreateSolidColorBrushWithRgb(59, 63, 64));
        AFSetBorderBrush(window, AFCreateSolidColorBrushWithRgb(221, 221, 221));
        AFSetBorderThickness(window, AFCreateInt32(0));

        AFSetButtonForegroundBrush(window, AFCreateSolidColorBrushWithRgb(188, 188, 188));
        AFSetButtonBackgroundBrush(window, AFCreateSolidColorBrushWithRgb(76, 81, 83));
        AFSetButtonBorderThickness(window, AFCreateInt32(1));
        AFSetButtonBorderBrush(window, AFCreateSolidColorBrushWithRgb(95, 96, 97));

        AFSetButtonHoverForegroundBrush(window, AFCreateSolidColorBrushWithRgb(188, 188, 188));
        AFSetButtonHoverBackgroundBrush(window, AFCreateSolidColorBrushWithRgb(76, 81, 83));
        AFSetButtonHoverBorderBrush(window, AFCreateSolidColorBrushWithRgb(126, 126, 126));

        AFSetButtonSelectedForegroundBrush(window, AFCreateSolidColorBrushWithRgb(187, 187, 187));
        AFSetButtonSelectedBackgroundBrush(window, AFCreateSolidColorBrushWithRgb(41, 41, 41));
        AFSetButtonSelectedBorderBrush(window, AFCreateSolidColorBrushWithRgb(126, 126, 126));

        AFSetCaption(window, AFS("AltLook1"));
        AFSetContentHorizontalAlignmentWithInt32(window, cAFHorizontalAlignmentStretc.h);
        AFSetContentVerticalAlignmentWithInt32(window, cAFVerticalAlignmentStretc.h);
        AFSetContent(window, mainPanel = AFCreateFlowGridPanel());

            AFSetVerticalAlignmentWithInt32(mainPanel, cAFVerticalAlignmentStretc.h);
            AFSetColumnsCount(mainPanel, 1);
            AFSetRowsCount(mainPanel, 2);

            AFAppendComponent(mainPanel, contentPanel = AFCreateFlowGridPanel());
                AFSetVerticalAlignmentWithInt32(contentPanel, cAFVerticalAlignmentStretc.h);
                AFSetHorizontalAlignmentWithInt32(contentPanel, cAFHorizontalAlignmentStretc.h);
                AFSetColumnsCount(contentPanel, 1);
                AFSetRowsCount(contentPanel, 1);
                AFSetHorizontalSpacing(contentPanel, 5);

                AFAppendComponent(contentPanel, label = AFCreateLabel());

                AFSetCaption(label, AFS("This is a space for a content."));

                AFAppendComponent(mainPanel, buttonsPanel = AFCreateFlowGridPanel());
                    AFSetHorizontalAlignmentWithInt32(buttonsPanel, cAFHorizontalAlignmentRight);
                    AFSetVerticalAlignmentWithInt32(buttonsPanel, cAFVerticalAlignmentStretc.h);
                    AFSetColumnsCount(buttonsPanel, 2);
                    AFSetRowsCount(buttonsPanel, 1);
                    AFSetHorizontalSpacing(buttonsPanel, 5);

                    AFAppendComponent(buttonsPanel, button1 = AFCreateButton());
                        AFSetVerticalAlignmentWithInt32(button1, cAFVerticalAlignmentStretc.h);
                        AFSetFrameWithRectangle(button1, AFRectangleMake(0, 0, 55, 16));
                        AFSetCaption(button1, AFS("Ok"));
                        AFAddEventHandlerFunction(button1, AFMouseClick, NULL, buttonMouseClick);

                    AFAppendComponent(buttonsPanel, button2 = AFCreateButton());
                        AFSetVerticalAlignmentWithInt32(button2, cAFVerticalAlignmentStretc.h);
                        AFSetFrameWithRectangle(button2, AFRectangleMake(0, 0, 55, 16));
                        AFSetCaption(button2, AFS("Cancel"));
                        AFAddEventHandlerFunction(button2, AFMouseClick, NULL, buttonMouseClick);

    AFShow(window);
    AFRunMainLoop(application);

    return 0;
}
screenshots/AltLook1.gif

AltLook2

Alternative UI color settings.

#include "api2/api2.h"

void buttonMouseClick(not_used void *context, not_used uint32_t index, not_used AFObject *sender,
    not_used AFObject *eventArguments)
{
    printf("Button was pressed!\n");
}

int main()
{
    var application;
    var window;
    var mainPanel;
    var contentPanel;
    var label;
    var buttonsPanel;
    var button1;
    var button2;

    application = AFCreateApplication();

        AFAppendComponent(application, window = AFCreateWindow());

        AFSetForegroundBrush(window, AFCreateSolidColorBrushWithRgb(51, 51, 51));
        AFSetBackgroundBrush(window, AFCreateSolidColorBrushWithRgb(207, 207, 207));
        AFSetBorderBrush(window, AFCreateSolidColorBrushWithRgb(198, 198, 198));
        AFSetBorderThickness(window, AFCreateInt32(0));

        AFSetButtonForegroundBrush(window, AFCreateSolidColorBrushWithRgb(51, 51, 51));
        AFSetButtonBackgroundBrush(window, AFCreateSolidColorBrushWithRgb(227, 227, 227));
        AFSetButtonBorderThickness(window, AFCreateInt32(1));
        AFSetButtonBorderBrush(window, AFCreateSolidColorBrushWithRgb(198, 198, 198));

        AFSetButtonHoverForegroundBrush(window, AFCreateSolidColorBrushWithRgb(51, 51, 51));
        AFSetButtonHoverBackgroundBrush(window, AFCreateSolidColorBrushWithRgb(227, 227, 227));
        AFSetButtonHoverBorderBrush(window, AFCreateSolidColorBrushWithRgb(127, 127, 127));

        AFSetButtonSelectedForegroundBrush(window, AFCreateSolidColorBrushWithRgb(51, 51, 51));
        AFSetButtonSelectedBackgroundBrush(window, AFCreateSolidColorBrushWithRgb(199, 235, 243));
        AFSetButtonSelectedBorderBrush(window, AFCreateSolidColorBrushWithRgb(127, 127, 127));

        AFSetCaption(window, AFS("AltLook2"));
        AFSetContentHorizontalAlignmentWithInt32(window, cAFHorizontalAlignmentStretc.h);
        AFSetContentVerticalAlignmentWithInt32(window, cAFVerticalAlignmentStretc.h);
        AFSetContent(window, mainPanel = AFCreateFlowGridPanel());

            AFSetVerticalAlignmentWithInt32(mainPanel, cAFVerticalAlignmentStretc.h);
            AFSetColumnsCount(mainPanel, 1);
            AFSetRowsCount(mainPanel, 2);

            AFAppendComponent(mainPanel, contentPanel = AFCreateFlowGridPanel());
                AFSetVerticalAlignmentWithInt32(contentPanel, cAFVerticalAlignmentStretc.h);
                AFSetHorizontalAlignmentWithInt32(contentPanel, cAFHorizontalAlignmentStretc.h);
                AFSetColumnsCount(contentPanel, 1);
                AFSetRowsCount(contentPanel, 1);
                AFSetHorizontalSpacing(contentPanel, 5);

                AFAppendComponent(contentPanel, label = AFCreateLabel());

                AFSetCaption(label, AFS("This is a space for a content."));

                AFAppendComponent(mainPanel, buttonsPanel = AFCreateFlowGridPanel());
                    AFSetHorizontalAlignmentWithInt32(buttonsPanel, cAFHorizontalAlignmentRight);
                    AFSetVerticalAlignmentWithInt32(buttonsPanel, cAFVerticalAlignmentStretc.h);
                    AFSetColumnsCount(buttonsPanel, 2);
                    AFSetRowsCount(buttonsPanel, 1);
                    AFSetHorizontalSpacing(buttonsPanel, 5);

                    AFAppendComponent(buttonsPanel, button1 = AFCreateButton());
                        AFSetVerticalAlignmentWithInt32(button1, cAFVerticalAlignmentStretc.h);
                        AFSetFrameWithRectangle(button1, AFRectangleMake(0, 0, 55, 16));
                        AFSetCaption(button1, AFS("Ok"));
                        AFAddEventHandlerFunction(button1, AFMouseClick, NULL, buttonMouseClick);

                    AFAppendComponent(buttonsPanel, button2 = AFCreateButton());
                        AFSetVerticalAlignmentWithInt32(button2, cAFVerticalAlignmentStretc.h);
                        AFSetFrameWithRectangle(button2, AFRectangleMake(0, 0, 55, 16));
                        AFSetCaption(button2, AFS("Cancel"));
                        AFAddEventHandlerFunction(button2, AFMouseClick, NULL, buttonMouseClick);

    AFShow(window);
    AFRunMainLoop(application);

    return 0;
}
screenshots/AltLook2.gif

AltLook3

Alternative UI color setting.

#include "api2/api2.h"

void buttonMouseClick(not_used void *context, not_used uint32_t index, not_used AFObject *sender,
    not_used AFObject *eventArguments)
{
    printf("Button was pressed!\n");
}

int main()
{
    var application;
    var window;
    var mainPanel;
    var contentPanel;
    var label;
    var buttonsPanel;
    var button1;
    var button2;

    application = AFCreateApplication();

        AFAppendComponent(application, window = AFCreateWindow());

        AFSetForegroundBrush(window, AFCreateSolidColorBrushWithRgb(0, 0, 0));
        AFSetBackgroundBrush(window, AFCreateSolidColorBrushWithRgb(239, 239, 239));
        AFSetBorderBrush(window, AFCreateSolidColorBrushWithRgb(220, 220, 220));
        AFSetBorderThickness(window, AFCreateInt32(0));

        AFSetButtonForegroundBrush(window, AFCreateSolidColorBrushWithRgb(0, 0, 0));
        AFSetButtonBackgroundBrush(window, AFCreateSolidColorBrushWithRgb(225, 225, 225));
        AFSetButtonBorderThickness(window, AFCreateInt32(1));
        AFSetButtonBorderBrush(window, AFCreateSolidColorBrushWithRgb(172, 172, 172));

        AFSetButtonSelectedForegroundBrush(window, AFCreateSolidColorBrushWithRgb(0, 0, 0));
        AFSetButtonSelectedBackgroundBrush(window, AFCreateSolidColorBrushWithRgb(202, 226, 247));
        AFSetButtonSelectedBorderBrush(window, AFCreateSolidColorBrushWithRgb(31, 78, 121));

        AFSetButtonHoverForegroundBrush(window, AFCreateSolidColorBrushWithRgb(0, 0, 0));
        AFSetButtonHoverBackgroundBrush(window, AFCreateSolidColorBrushWithRgb(225, 225, 225));
        AFSetButtonHoverBorderBrush(window, AFCreateSolidColorBrushWithRgb(46, 117, 182));

        AFSetCaption(window, AFS("AltLook3"));
        AFSetContentHorizontalAlignmentWithInt32(window, cAFHorizontalAlignmentStretc.h);
        AFSetContentVerticalAlignmentWithInt32(window, cAFVerticalAlignmentStretc.h);
        AFSetContent(window, mainPanel = AFCreateFlowGridPanel());

            AFSetVerticalAlignmentWithInt32(mainPanel, cAFVerticalAlignmentStretc.h);
            AFSetColumnsCount(mainPanel, 1);
            AFSetRowsCount(mainPanel, 2);

            AFAppendComponent(mainPanel, contentPanel = AFCreateFlowGridPanel());
                AFSetVerticalAlignmentWithInt32(contentPanel, cAFVerticalAlignmentStretc.h);
                AFSetHorizontalAlignmentWithInt32(contentPanel, cAFHorizontalAlignmentStretc.h);
                AFSetColumnsCount(contentPanel, 1);
                AFSetRowsCount(contentPanel, 1);
                AFSetHorizontalSpacing(contentPanel, 5);

                AFAppendComponent(contentPanel, label = AFCreateLabel());

                AFSetCaption(label, AFS("This is a space for a content."));

                AFAppendComponent(mainPanel, buttonsPanel = AFCreateFlowGridPanel());
                    AFSetHorizontalAlignmentWithInt32(buttonsPanel, cAFHorizontalAlignmentRight);
                    AFSetVerticalAlignmentWithInt32(buttonsPanel, cAFVerticalAlignmentStretc.h);
                    AFSetColumnsCount(buttonsPanel, 2);
                    AFSetRowsCount(buttonsPanel, 1);
                    AFSetHorizontalSpacing(buttonsPanel, 5);

                    AFAppendComponent(buttonsPanel, button1 = AFCreateButton());
                        AFSetVerticalAlignmentWithInt32(button1, cAFVerticalAlignmentStretc.h);
                        AFSetFrameWithRectangle(button1, AFRectangleMake(0, 0, 55, 16));
                        AFSetCaption(button1, AFS("Ok"));
                        AFAddEventHandlerFunction(button1, AFMouseClick, NULL, buttonMouseClick);

                    AFAppendComponent(buttonsPanel, button2 = AFCreateButton());
                        AFSetVerticalAlignmentWithInt32(button2, cAFVerticalAlignmentStretc.h);
                        AFSetFrameWithRectangle(button2, AFRectangleMake(0, 0, 55, 16));
                        AFSetCaption(button2, AFS("Cancel"));
                        AFAddEventHandlerFunction(button2, AFMouseClick, NULL, buttonMouseClick);

    AFShow(window);
    AFRunMainLoop(application);

    return 0;
}

void putchar1()
{
    putchar(1);
}
screenshots/AltLook3.gif

AltLook5

Alternative UI color setting and the appearance of the window - this example is not included in this release.


Calculator

Calculator's UI - UI only.

#include "api2/api2.h"

void buttonMouseClick(not_used void *context, not_used uint32_t index, AFObject *sender, not_used AFObject *eventArguments)
{
    AFString *caption = AFGetCaption(sender);
    char *calculatorKey = AFToCString(caption);

    printf("'%s' was pressed\n", calculatorKey);
}

int main()
{
    var application = AFCreateApplication();
    var window = AFCreateWindow();
    var mainPanel = AFCreateFlowGridPanel();
    var valueLabel = AFCreateLabel();
    var panel = AFCreateFlowGridPanel();
    
    AFAppendComponent(application, window);
    
    AFSetWindowDefaultFrame(window, AFRectangleMake(20, 20, 200, 200));
    AFSetBackgroundBrush(window, AFCreateSolidColorBrushWithRgb(52, 52, 52));
    AFSetPadding(window, AFMakeSpacing(1, 1, 1, 1));
    AFSetContent(window, mainPanel);
    AFSetCaption(window, AFS("Calculator"));
    AFSetBorderThickness(window, AFCreateInt32(0));
    AFSetButtonSelectedForegroundBrush(window, AFCreateSolidColorBrushWithRgb(128, 0, 0));
    AFSetButtonSelectedBackgroundBrush(window, AFCreateSolidColorBrushWithRgb(255, 0, 0));
    AFSetButtonHoverForegroundBrush(window, AFCreateSolidColorBrushWithRgb(0, 128, 192));
    AFSetButtonHoverBackgroundBrush(window, AFCreateSolidColorBrushWithRgb(153, 217, 234));

    AFSetConstraints(mainPanel, AFConstraintsMakeWithWidthAndHeight(100, 100, 200, 200, 400, 400));
    AFSetBackgroundBrush(mainPanel, AFCreateSolidColorBrushWithRgb(52, 52, 52));
    AFSetForegroundBrush(mainPanel, AFCreateSolidColorBrushWithRgb(255, 255, 255));
    AFAppendComponent(mainPanel, valueLabel);
    AFAppendComponent(mainPanel, panel);
    AFSetColumnsCount(mainPanel, 1);
    AFSetRowsCount(mainPanel, 2);

    AFSetPadding(valueLabel, AFMakeSpacing(5, 5, 5, 5));
    AFSetForegroundBrush(valueLabel, AFCreateSolidColorBrushWithRgb(255, 255, 255));
    AFSetContentHorizontalAlignmentWithInt32(valueLabel, cAFHorizontalAlignmentRight);
    AFSetConstraints(valueLabel, AFConstraintsMakeWithWidthAndHeight(0, 60, 0, 60, cAFConstraintsMaxValue, 60));
    AFSetCaption(valueLabel, AFS("0"));  
    AFSetHorizontalAlignmentWithInt32(valueLabel, cAFHorizontalAlignmentStretc.h);
    AFSetVerticalAlignmentWithInt32(valueLabel, cAFVerticalAlignmentStretc.h);

    AFSetHorizontalAlignmentWithInt32(panel, cAFHorizontalAlignmentStretc.h);
    AFSetVerticalAlignmentWithInt32(panel, cAFVerticalAlignmentStretc.h);
    AFSetColumnsCount(panel, 4);
    AFSetRowsCount(panel, 5);
    AFSetHorizontalSpacing(panel, 1);
    AFSetVerticalSpacing(panel, 1);

    char *captions[] =
    {
        "C", "DEL", "%", "/",
        "7", "8", "9", "x",
        "4", "5", "6", "-",
        "1", "2", "3", "+",
        "+/-", "0", ".", "="
    };

    var zero =  AFCreateInt32(0);
    var foregroundBrush1 = AFCreateSolidColorBrushWithRgb(255, 255, 255);
    var backgroundBrush1 = AFCreateSolidColorBrushWithRgb(255, 153, 0);

    var buttons[(index_t)(sizeof(captions) / sizeof(*captions))];

    for (index_t index = 0; index < (index_t)(sizeof(captions) / sizeof(*captions)); ++index)
    {
        var button = buttons[index] = AFCreateButton();

        AFSetCaption(button, AFS(captions[index]));
        AFSetButtonForegroundBrush(button, foregroundBrush1);
        AFSetButtonBackgroundBrush(button, backgroundBrush1);
        AFSetButtonBorderThickness(button, zero);
        AFSetContentHorizontalAlignmentWithInt32(button, cAFHorizontalAlignmentCenter);
        AFSetContentVerticalAlignmentWithInt32(button, cAFVerticalAlignmentCenter);
        AFSetHorizontalAlignmentWithInt32(button, cAFHorizontalAlignmentStretc.h);
        AFSetVerticalAlignmentWithInt32(button, cAFVerticalAlignmentStretc.h);

        AFAppendComponent(panel, button);

        AFAddEventHandlerFunction(button, AFMouseClick, NULL, buttonMouseClick);
    }

    var foregroundBrush2 = AFCreateSolidColorBrushWithRgb(0, 0, 0);
    var backgroundBrush2 = AFCreateSolidColorBrushWithRgb(200, 200, 200);

    var foregroundBrush3 = AFCreateSolidColorBrushWithRgb(255, 255, 255);
    var backgroundBrush3 = AFCreateSolidColorBrushWithRgb(100, 100, 100);

    var backgroundBrush4 = AFCreateSolidColorBrushWithRgb(255, 242, 0);

    int functionalIndexes1[] = {0, 1, 2};

    for (index_t index2 = 0; index2 < (index_t)(sizeof(functionalIndexes1) / sizeof(*functionalIndexes1)); ++index2)
    {
        AFSetButtonForegroundBrush(buttons[functionalIndexes1[index2]], foregroundBrush2);
        AFSetButtonBackgroundBrush(buttons[functionalIndexes1[index2]], backgroundBrush2);
    }

    int functionalIndexes2[] = {3, 7, 11, 15, 19};

    for (index_t index2 = 0; index2 < (index_t)(sizeof(functionalIndexes2) / sizeof(*functionalIndexes2)); ++index2)
    {
        AFSetButtonForegroundBrush(buttons[functionalIndexes2[index2]], foregroundBrush3);
        AFSetButtonBackgroundBrush(buttons[functionalIndexes2[index2]], backgroundBrush3);
    }

    AFSetButtonBackgroundBrush(buttons[19], backgroundBrush4);
    AFSetButtonForegroundBrush(buttons[19], foregroundBrush2);

    AFShow(window);
    AFRunMainLoop(application);

    return 0;
}
screenshots/Calculator.png