Setting Event Handlers

From Agar

Jump to: navigation, search
Agar windows demo: agar/demos/windows/

In this example, we will create a simple form for entering an email address and a name in a CSV file. The task involves:

  • Creating and populating an Agar Window with two Textboxes and a Button widget.
  • Configuring an event handler routine which will be executed when the user presses the button.
  • From the event handler routine, insert the address in the CSV file.

Contents

Initialization

We start with a typical main() to initialize the library, create our GUI elements and enter the stock event loop:

#include <agar/core.h>
#include <agar/gui.h>
 
int
main(int argc, char *argv[])
{
        AG_Window *win;
        AG_Textbox *tbName;
        AG_Textbox *tbEmail;
 
        AG_InitCore("myapp", 0);
        AG_InitGraphics(NULL);
 
        /* Create Agar window with our main GUI elements. */
        win = AG_WindowNew(AG_WINDOW_PLAIN);
        tbName = AG_TextboxNew(win, 0, "Name: ");
        tbEmail = AG_TextboxNew(win, 0, "Email address: ");
        AG_ButtonNewFn(win, 0, "Submit",
            SubmittedAddress, "%p,%p", tbName, tbEmail);
 
        AG_WindowShow(win);
        AG_WindowMaximize(win);
 
        AG_EventLoop();
        return (0);
}

AG_ButtonNewFn() is just a convenient shorthand constructor which sets a default button-pushed handler. The more explicit way of configuring the event handler would be:

AG_Button *btn = AG_ButtonNew(win, 0, "Submit");
AG_SetEvent(btn, "button-pushed",
    SubmittedAddress, "%p,%p", tbName, tbEmail);

The "%p,%p" string and following two arguments in AG_ButtonNewFn() or AG_SetEvent() specify the arguments which will be passed to the event handler routine. The tbName argument will be retrievable with AG_PTR(1) by the event handler, and tbEmail will be retrievable as AG_PTR(2). It is also possible to retrieve arguments by name instead of index.

See AG_Event(3) for a full description of the Agar event system.

The Event Handler

static void
SubmittedAddress(AG_Event *event)
{
        char name[200], addr[200];
        AG_Button *btn = AG_SELF();
        AG_Textbox *tbName = AG_PTR(1);
        AG_Textbox *tbAddr = AG_PTR(2);
        FILE *f;
 
        /* Copy the user-specified strings into temporary buffers. */
        AG_TextboxCopyString(tbName, name, sizeof(name));
        AG_TextboxCopyString(tbAddr, addr, sizeof(addr));
 
        /* Append the contents of the buffer to our CSV file. */
        if ((f = fopen("emails.txt", "a")) == NULL) {
                AG_TextError("emails.txt: %s", strerror(errno));
                return;
        }
        fprintf(f, "%s:%s\n", name, addr);
        fclose(f);
 
        /* Let the user know the operation succeeded. */
        AG_TextInfo("success", "Successfully added %s <%s> to database",
            name, addr);
}

The event handler function retrieves the pointers to the name and address textboxes, copies their contents to temporary buffers, and write them into a file. AG_TextError() and AG_TextInfo() displays a dialog letting the user know whether the operation has succeeded or failed. Anything is possible in an event handler routine - you can create new windows, call other event handlers, or even spawn new threads.

Alternatives to event handlers

This application demonstrates how a typical event handler routines might look like, but there are smarter, more powerful ways to implement what it does, without the need for event handler routines.

A major feature of the Agar library, widget bindings allow widgets to access and modify data directly, without the need for event handlers.

One method relies on database-bound objects (see AG_Db(3) and AG_DbObject(3) for details).

Threaded operation

In this example, we simply append data to a file. If your database was network-based, it would be a good idea to spawn a new thread to prevent the application from blocking.

See also

Personal tools