# libs3wd - The S3D Widget Library

## Using the s3d widget library

### Getting started

Assuming you have already read about the lowlevel libs3d s3d api, the s3d widget library is build on top of it and should be (hopefully) easy to use as any other widget library. Just include

    	  #include <s3dw.h>

and link with -ls3dw -ls3d, and everything should be fine. :)

    	 bash$  gcc program.c -ls3dw -ls3d -o program

## function reference

### s3dw_surface_new

    #include <s3dw.h>

s3dw_surface *`s3dw_surface_new` const char *title, float width, float height

Creates a new surface (a new window) with title "title" and dimension "width" x "height".

See s3dw_surface for information about callbacks which may be defined.

### s3dw_button_new

    #include <s3dw.h>

s3dw_button *`s3dw_button_new` const s3dw_surface *surface, const char *text, float posx, float posy

Creates a new button on the surface, with "text" written on it and the upper left corner at (posx,posy) on the surface.

See s3dw_button for information about callbacks which may be defined.

### s3dw_input_new

    #include <s3dw.h>

s3dw_input *`s3dw_input_new` const s3dw_surface *surface, float width, float posx, float posy

Creates a new input-box on the surface with a input width of "width", the upper left corner at (posx,posy) on the surface. The input-box is empty on creation and can be change with s3dw_input_change_text, and received with s3dw_input_gettext

See s3dw_input for information about callbacks which may be defined.

### s3dw_label_new

    #include <s3dw.h>

s3dw_label *`s3dw_label_new` const s3dw_surface *surface, const char *text, float posx, float posy

Creates a new label on the surface, with "text" written on it and the upper left corner at (posx,posy) on the surface.

See s3dw_label for information about callbacks which may be defined.

### s3dw_textbox_new

    #include <s3dw.h>

s3dw_textbox *`s3dw_textbox_new` const s3dw_surface *surface, const char *text, float posx, float posy, float width, float height

Creates a new textbox on the surface, with "text" written on it and the upper left corner at (posx,posy) on the surface. Width and height define the size of the textbox including scrollbars which are rendered around the textfield.

See s3dw_textbox for information about callbacks which may be defined.

### s3dw_textbox_scrollup

    #include <s3dw.h>

void `s3dw_textbox_scrollup` s3dw_textbox *textbox

Scrolls the text in the textbox up by one line, if possible.

### s3dw_textbox_scrolldown

    #include <s3dw.h>

void `s3dw_textbox_scrolldown` s3dw_textbox *textbox

Scrolls the text in the textbox down by one line, if possible.

### s3dw_textbox_scrollleft

    #include <s3dw.h>

void `s3dw_textbox_scrollleft` s3dw_textbox *textbox

Scrolls the text in the textbox to the left by one character, if possible.

### s3dw_textbox_scrollright

    #include <s3dw.h>

void `s3dw_textbox_scrollright` s3dw_textbox *textbox

Scrolls the text in the textbox to the right by one character, if possible.

### s3dw_textbox_scrollto

    #include <s3dw.h>

void `s3dw_textbox_scrollto` s3dw_textbox *textbox, int x, int y

Scrolls the text in the textbox so that the character in row y, column x is in the top left corner of the textbox.

### s3dw_getroot

    #include <s3dw.h>

s3dw_widget *`s3dw_getroot` void

Returns the root-widget, which holds all the surfaces. E.g. if you want to move all widgets at once, adjust the root-widgets x,y,z and use s3dw_moveit()

    		s3dw_widget *root = s3dw_getroot();
    		/* move widget center to (0,5,0). upon creation, it's centered at (0,0,0),
    		 * so this might move it up */
    		root->x=0;
    		root->y=5;
    		root->z=0;
    		s3dw_moveit(root);

### s3dw_input_gettext

    #include <s3dw.h>

char *`s3dw_input_gettext` s3dw_input *input

Returns the text which is currently entered in the referenced input-box.

### s3dw_input_change_text

    #include <s3dw.h>

void `s3dw_input_change_text` s3dw_input *input, const char *text

Change the text in the referenced input-box to the specified text.

### s3dw_label_change_text

    #include <s3dw.h>

void `s3dw_label_change_text` s3dw_label *label, const char *text

Change the text in the referenced label to the specified text.

### s3dw_textbox_change_text

    #include <s3dw.h>

void `s3dw_textbox_change_text` s3dw_textbox *textbox, const char *text

Change the text in the referenced textbox to the specified text.

### s3dw_delete

    #include <s3dw.h>

void `s3dw_delete` s3dw_widget *widget

Deletes any widget. Should be casted with S3DWIDGET().

### s3dw_moveit

    #include <s3dw.h>

void `s3dw_moveit` s3dw_widget *widget

Moves/translates the widget as you specified in it's private s3dw_widget structure. Should be casted with S3DWIDGET().

### s3dw_show

    #include <s3dw.h>

void `s3dw_show` s3dw_widget *widget

Switches a widget visible. Should be casted with S3DWIDGET().

### s3dw_focus

    #include <s3dw.h>

void `s3dw_focus` s3dw_widget *focus

Gives focus to the widget, relative to its parent. That means you can focus a surface, and each surface can focus one of its element, e.g. an input field. Should be casted with S3DWIDGET().

### s3dw_handle_click

    #include <s3dw.h>

int `s3dw_handle_click` const struct s3d_evt *event

If you want your widgets on mouseclicks (believe me, you want that), you have to call this either in your clickhandler-function or specifiy it itself as the clickhandler.

    /* way 1: */
    s3d_set_callback(S3D_EVENT_OBJ_CLICK,s3dw_handle_click);

    /* way 2: */
    ...
    void click(struct s3d_evt *evt)
    {
    	s3dw_handle_click(evt);
    	....
    	/* your own clickhandler code */
    	...
    }
    ....
    s3d_set_callback(S3D_EVENT_OBJ_CLICK,click);

### s3dw_handle_key

    #include <s3dw.h>

int `s3dw_handle_key` const struct s3d_evt *event

This is somehow useful to call in your keyhandler functions if you want to have input-boxes work. ;)

    /* way 1: */
    s3d_set_callback(S3D_EVENT_KEY,s3dw_handle_key);

    /* way 2: */
    ...
    void key(struct s3d_evt *evt)
    {
    	s3dw_handle_key(evt);
    	....
    	/* your own keyhandler code */
    	...
    }
    ....
    s3d_set_callback(S3D_EVENT_KEY,key);

### s3dw_object_info

    #include <s3dw.h>

int `s3dw_object_info` struct s3d_evt *event

This can be used to let s3dw handle S3D_EVENT_OBJ_INFO-events. With this, s3dw can consider the camera position and makes things like following the camera possible.

### s3dw_ani_mate

    #include <s3dw.h>

void `s3dw_ani_mate` void

Just call this in your mainloop if you want some nice window sliding animations. it's somewhat bloating, but you don't want to miss it ;)

    #include <time.h>   /* nanosleep() */
    static struct timespec t={0,33*1000*1000}; /* 33 mili seconds */
    void mainloop()
    {
        /* keep this in your mainloop. this will do smooth animations for you ... */
        s3dw_ani_mate();
        nanosleep(&t,NULL);
    }

    ....
    s3d_mainloop(mainloop);

## Data types

### s3dw_widget

    struct _s3dw_widget {
    	/* private .. */
    	int         type;
    	s3dw_widget *parent;
    	s3dw_style  *style;
    	int         nobj;          /* number of children objects */
    	s3dw_widget **pobj;        /* pointer to list of children objects */
    	int         focus;         /* index of the widget focused in pobj */
    	int         flags;         /* flags like visibility */
    	float       ax, ay, az;    /* current position for animation */
    	float       as;            /* current scale factor */
    	float       arx, ary, arz; /* current rotation */
    	float       width, height; /* width and height of the widget, outer size */
    	uint32_t    oid;           /* the main object which is used for transformations etc ...*/
    	/* public */
    	void        *ptr;          /* a pointer to a user structure, to use in callbacks etc */
    	float       x, y, z;       /* position, relative to the surface usually */
    	float       s;             /* scale factor */
    	float       rx, ry, rz;    /* rotation around the axis */
    };
    typedef struct _s3dw_widget     s3dw_widget;

    /* type may be one of the following ... */

    enum {
    	S3DW_TROOT,
    	S3DW_TCAM,
    	S3DW_TSURFACE,
    	S3DW_TBUTTON,
    	S3DW_TLABEL,
    	S3DW_TINPUT,
    	S3DW_TTEXTBOX,
    	S3DW_TSCROLLBAR,
    	S3DW_NTYPES
    };

    #define     S3DWIDGET(x)    ((s3dw_widget *)x)

This is the most basic widget type, it contains all the "general" widget information. If you want to move a widget, you'd change x,y,z,s and rx,ry,rz and call s3dw_moveit to turn your action reality. Every other widget has this type as first entry, so a simple typecast to s3dw_widget will give you the widgets "general" information. For typecast, you may use S3DWIDGET().

The pointer ptr allows linking to user-specific datastructures. That comes in handy if the widget is called back by an event, and the program must now find out on which data the user reacted.

### s3dw_button

    typedef struct _s3dw_button     s3dw_button;
    struct _s3dw_button {
        /* private */
    	s3dw_widget      widget;
    	char            *text;
    	uint32_t    oid_text;
    	/* public */
    	s3dw_callback    onclick;
    };

The buttons is just a button as you would expect it in a 2D widget library. It only reacts on clicks.

### s3dw_input

    typedef struct _s3dw_input     s3dw_input;
    struct _s3dw_input {
        /* private */
    	s3dw_widget      widget;
    	char            *text;
    	uint32_t    oid_text;
    	/* public */
    	s3dw_callback    onclick;
    	s3dw_callback    onedit;
    };

The inputs is an input-field where a user may type things. onclick reacts on click in the field, onedit notifies you when someone writes in the field.

### s3dw_textbox

    typedef struct _s3dw_textbox     s3dw_textbox;
    struct _s3dw_textbox {
        /* private */
    	s3dw_widget      widget;
    	s3dw_scrollbar      *scroll_vertical, *scroll_horizontal;
    	char            *text;
    	int				n_lineoids, *p_lineoids;
    	int 			window_x, window_y;
    	/* public */
    	s3dw_callback    onclick;
    };

A textbox shows some text with scrollbars to scroll around. It can currently only react to a click event.

### s3dw_scrollbar

    typedef struct _s3dw_scrollbar     s3dw_scrollbar;
    struct _s3dw_scrollbar {
        /* private */
    	s3dw_widget      widget;
    	float			pos, max;
    	int				type;  /* 0 = horizontal, 1 = vertical */
    	int 			loid, roid, baroid;
    	/* public */
    	s3dw_callback    lonclick, ronclick;
    };

The Scrollbar should be placed around scrollable content. Currently only the left and right icons are clickable (lonclick and ronclick callbacks), in vertical mode lonclick is the callback for the up icon, ronclick the callback for the down icon.

### s3dw_label

    typedef struct _s3dw_label     s3dw_label;
    struct _s3dw_label {
        /* private */
    	s3dw_widget      widget;
    	char            *text;
    	/* public */
    	s3dw_callback    onclick;
    };

The labels is an label-field where a user may type things. onclick reacts on click in the field, onedit notifies you when someone writes in the field.

### s3dw_surface

    typedef struct _s3dw_surface     s3dw_surface;
    struct _s3dw_surface {
        /* private */
    	s3dw_widget      widget;
    	uint32_t         oid_title;
    	uint32_t         oid_tbar;
    	char            *title;
    };

A surface is the window of this widget library, holding all of our elements like buttons, inputfields etc ...

### s3dw_style

    typedef struct _s3dw_style     s3dw_style;
    /* style */
    struct _s3dw_style {
        char *name;                 /* name of the style ... kind of redundant */
        char *fontface;             /* font face for all used fonts */
        float surface_mat[12];      /* material for the surface background */
        float input_mat[12];        /* material for buttonboxes and other widgets */
        float inputback_mat[12];    /* material for inputfield background */
        float text_mat[12];         /* material for the text on buttons and inputs */
        float title_mat[12];        /* material for the title bar */
        float title_text_mat[12];   /* material for the text on the title bar */
    };

With s3dw_style you can change the colors/materials of your widgets. materials are in the same as in s3d_push_materials_a, that means red,green,blue and alpha float values (between 0.0 and 1.0) for Ambience, Specular and Diffuse Color.

### s3dw_callback

    typedef void (*s3dw_callback)(s3dw_widget *);

The callback type. Receive the widget which is affected as argument.

    /* example */
    void my_handler(s3dw_widget *widget)
    {
    	/* do something with the widget */
    	...
    }