/** * @brief Adds a button widget to a window. * * Position origin is 0,0 at bottom left. If you use negative X or Y * positions. They actually count from the opposite side in. * * @param wid ID of the window to add the widget to. * @param x X position within the window to use. * @param y Y position within the window to use. * @param w Width of the widget. * @param h Height of the widget. * @param name Name of the widget to use internally. * @param ntabs Number of tabs in the widget. * @param tabnames Name of the tabs in the widget. * @return List of created windows. */ unsigned int* window_addTabbedWindow( const unsigned int wid, const int x, const int y, /* position */ const int w, const int h, /* size */ const char* name, int ntabs, const char **tabnames ) { int i; Window *wdw, *wtmp; Widget *wgt; /* Create the Widget. */ wdw = window_wget(wid); wgt = window_newWidget(wdw, name); if (wgt == NULL) return NULL; /* generic */ wgt->type = WIDGET_TABBEDWINDOW; /* specific */ wgt_setFlag( wgt, WGT_FLAG_RAWINPUT ); wgt->rawevent = tab_raw; wgt->render = tab_render; wgt->renderOverlay = tab_renderOverlay; wgt->cleanup = tab_cleanup; wgt->dat.tab.ntabs = ntabs; /* position/size */ wgt->w = (double) w; wgt->h = (double) h; toolkit_setPos( wdw, wgt, x, y ); /* Copy tab information. */ wgt->dat.tab.tabnames = malloc( sizeof(char*) * ntabs ); wgt->dat.tab.windows = malloc( sizeof(unsigned int) * ntabs ); wgt->dat.tab.namelen = malloc( sizeof(int) * ntabs ); for (i=0; i<ntabs; i++) { /* Hack to get around possible reallocs. */ wdw = window_wget(wid); /* Get name and length. */ wgt->dat.tab.tabnames[i] = strdup( tabnames[i] ); wgt->dat.tab.namelen[i] = gl_printWidthRaw( &gl_defFont, wgt->dat.tab.tabnames[i] ); /* Create windows. */ wgt->dat.tab.windows[i] = window_create( tabnames[i], wdw->x + x, wdw->y + y + TAB_HEIGHT, wdw->w, wdw->h - TAB_HEIGHT ); wtmp = window_wget( wgt->dat.tab.windows[i] ); /* Set flags. */ window_setFlag( wtmp, WINDOW_NOFOCUS ); window_setFlag( wtmp, WINDOW_NORENDER ); window_setFlag( wtmp, WINDOW_NOINPUT ); window_setFlag( wtmp, WINDOW_NOBORDER ); } /* Return list of windows. */ return wgt->dat.tab.windows; }
/** * @brief Adds a custom widget to a window. * * Position origin is 0,0 at bottom left. If you use negative X or Y * positions. They actually count from the opposite side in. * * You are in charge of the rendering and handling mouse input for this widget. * Mouse events outside the widget position won't be passed on. * * @param wid ID of the window to add the widget to. * @param x X position within the window to use. * @param y Y position within the window to use. * @param w Width of the widget. * @param h Height of the widget. * @param name Name of the widget to use internally. * @param border Whether or not it should have a border. * @param render Render function, passes the position and dimensions of the * widget as parameters. * @param mouse Mouse function, passes the window id, event and position as * parameters. */ void window_addCust( const unsigned int wid, const int x, const int y, /* position */ const int w, const int h, /* size */ char* name, const int border, void (*render) (double x, double y, double w, double h, void *data), void (*mouse) (unsigned int wid, SDL_Event* event, double x, double y, double w, double h, void *data), void *data ) { Window *wdw = window_wget(wid); Widget *wgt = window_newWidget(wdw, name); if (wgt == NULL) return; /* generic */ wgt->type = WIDGET_CUST; /* specific */ wgt->render = cst_render; wgt->renderOverlay = cst_renderOverlay; wgt->dat.cst.border = border; wgt->dat.cst.render = render; wgt->dat.cst.mouse = mouse; wgt->dat.cst.clip = 1; wgt->dat.cst.userdata = data; /* position/size */ wgt->w = (double) w; wgt->h = (double) h; toolkit_setPos( wdw, wgt, x, y ); }
/** * @brief Destroys a widget in a window. * * @param wid Window to destroy widget in. * @param wgtname Name of the widget to destroy. */ void window_destroyWidget( unsigned int wid, const char* wgtname ) { Window *wdw; Widget *wgt; /* Get the window. */ wdw = window_wget( wid ); if (wdw == NULL) return; /* Get the widget. */ /* get widget. */ for (wgt=wdw->widgets; wgt!=NULL; wgt=wgt->next) { if (strcmp(wgt->name, wgtname)==0) { break; } } if (wgt == NULL) { WARN("Widget '%s' not found in window '%s'", wgtname, wdw->name ); return; } /* Defocus. */ if (wdw->focus == wgt->id) wdw->focus = -1; /* There's dead stuff now. */ window_dead = 1; wgt_setFlag( wgt, WGT_FLAG_KILL ); }
/** * @brief Handles input for an button widget. * * @param tab Tabbed Window widget to handle event. * @param key Key being handled. * @param mod Mods when key is being pressed. * @return 1 if the event was used, 0 if it wasn't. */ static int tab_raw( Widget* tab, SDL_Event *event ) { Window *wdw; int ret; /* First handle event internally. */ ret = 0; if (event->type == SDL_MOUSEBUTTONDOWN) ret = tab_mouse( tab, event ); else if (event->type == SDL_KEYDOWN) ret = tab_key( tab, event ); /* Took the event. */ if (ret) return ret; /* Give event to window. */ wdw = window_wget( tab->dat.tab.windows[ tab->dat.tab.active ] ); if (wdw == NULL) { WARN("Active window in window '%s' not found in stack.", tab->name); return 0; } /* Give the active window the input. */ toolkit_inputWindow( wdw, event, 0 ); return 0; /* Never block event. */ }
/** * @brief Adds a text widget to the window. * * Position origin is 0,0 at bottom left. If you use negative X or Y * positions. They actually count from the opposite side in. * * @param wid ID of the window to add the widget to. * @param x X position within the window to use. * @param y Y position within the window to use. * @param w Maximum width of the text. * @param h Maximum height of the text. * @param centered Whether text should be centered. * @param name Name of the widget to use internally. * @param font Font to use (NULL is default). * @param colour Colour to use (NULL is default). * @param string Text to display. */ void window_addText( const unsigned int wid, const int x, const int y, const int w, const int h, const int centered, char* name, glFont* font, glColour* colour, const char* string ) { Window *wdw = window_wget(wid); Widget *wgt = window_newWidget(wdw, name); /* generic */ wgt->type = WIDGET_TEXT; /* specific */ wgt->render = txt_render; wgt->cleanup = txt_cleanup; wgt->dat.txt.font = (font==NULL) ? &gl_defFont : font; wgt->dat.txt.colour = (colour==NULL) ? &cBlack : colour; wgt->dat.txt.centered = centered; wgt->dat.txt.text = (string==NULL) ? NULL : strdup(string); /* position/size */ wgt->w = (double) w; wgt->h = (double) h; toolkit_setPos( wdw, wgt, x, y ); }
/** * @brief Adds an input widget to a window. * * Position origin is 0,0 at bottom left. If you use negative X or Y * positions. They actually count from the opposite side in. * * @param wid ID of the window to add the widget to. * @param x X position within the window to use. * @param y Y position within the window to use. * @param w Width of the widget. * @param h Height of the widget. * @param name Name of the widget to use internally. * @param max Max amount of characters that can be written. * @param oneline Whether widget should only be one line long. * @param font Font to use. */ void window_addInput( const unsigned int wid, const int x, const int y, /* position */ const int w, const int h, /* size */ char* name, const int max, const int oneline, glFont *font ) { Window *wdw = window_wget(wid); Widget *wgt = window_newWidget(wdw, name); if (wgt == NULL) return; /* generic */ wgt->type = WIDGET_INPUT; /* specific */ wgt->render = inp_render; wgt->cleanup = inp_cleanup; wgt_setFlag(wgt, WGT_FLAG_CANFOCUS); wgt->keyevent = inp_key; wgt->textevent = inp_text; /*wgt->keyevent = inp_key;*/ wgt->dat.inp.font = (font != NULL) ? font : &gl_smallFont; wgt->dat.inp.max = max+1; wgt->dat.inp.oneline = oneline; wgt->dat.inp.pos = 0; wgt->dat.inp.view = 0; wgt->dat.inp.input = malloc(sizeof(char)*wgt->dat.inp.max); memset(wgt->dat.inp.input, 0, wgt->dat.inp.max*sizeof(char)); /* position/size */ wgt->w = (double) w; wgt->h = (double) h; toolkit_setPos( wdw, wgt, x, y ); }
/** * @brief Adds a rectangle widget to a window. * * Position origin is 0,0 at bottom left. If you use negative X or Y * positions. They actually count from the opposite side in. * * @param wid ID of the window to add the widget to. * @param x X position within the window to use. * @param y Y position within the window to use. * @param w Width of the widget. * @param h Height of the widget. * @param name Name of the widget to use internally. * @param colour Colour of the rectangle. * @param border Whether or not it should have a border. */ void window_addRect( const unsigned int wid, const int x, const int y, /* position */ const int w, const int h, /* size */ char* name, const glColour* colour, int border ) { Window *wdw = window_wget(wid); Widget *wgt = window_newWidget(wdw, name); if (wgt == NULL) return; /* generic */ wgt->type = WIDGET_RECT; /* specific */ wgt->render = rct_render; if (colour != NULL) { wgt->dat.rct.colour = *colour; wgt->dat.rct.fill = 1; } else wgt->dat.rct.fill = 0; wgt->dat.rct.border = border; /* position/size */ wgt->w = (double) w; wgt->h = (double) h; toolkit_setPos( wdw, wgt, x, y ); }
/** * @brief Adds a button widget to a window. * * Position origin is 0,0 at bottom left. If you use negative X or Y * positions. They actually count from the opposite side in. * * @param wid ID of the window to add the widget to. * @param x X position within the window to use. * @param y Y position within the window to use. * @param w Width of the widget. * @param h Height of the widget. * @param name Name of the widget to use internally. * @param display Text displayed on the button (centered). * @param call Function to call when checkbox is toggled Parameter passed * is the name of the checkbox. */ void window_addCheckbox( const unsigned int wid, const int x, const int y, /* position */ const int w, const int h, /* size */ char* name, char* display, /* label name, display name */ void (*call) (unsigned int,char*), /* toggle function */ int default_state ) /* default state. */ { Window *wdw = window_wget(wid); Widget *wgt = window_newWidget(wdw, name); if (wgt == NULL) return; /* generic */ wgt->type = WIDGET_CHECKBOX; /* specific */ wgt->keyevent = chk_key; wgt->mclickevent = chk_mclick; wgt->render = chk_render; wgt->cleanup = chk_cleanup; wgt->dat.chk.display = (display == NULL) ? NULL : strdup(display); wgt->dat.chk.fptr = call; wgt->dat.chk.state = default_state; /* position/size */ wgt->w = (double) w; wgt->h = (double) h; toolkit_setPos( wdw, wgt, x, y ); }
/** * @brief Sets a window as a window's parent. * * When a window's parent closes, it closes the window also. * * @param wid Window to set as child. * @param parent Window to set as parent. */ void window_setParent( unsigned int wid, unsigned int parent ) { Window *wdw; /* Get the window. */ wdw = window_wget( wid ); if (wdw == NULL) return; /* Set the parent. */ wdw->parent = parent; }
/** * @brief Sets the default close function of the window. * * This function is called when the window is closed. * * @param wid Window to set close function of. * @param Function to tirgger when window is closed, parameter is window id * and name. */ void window_onClose( unsigned int wid, void (*fptr)(unsigned int,char*) ) { Window *wdw; /* Get the window. */ wdw = window_wget( wid ); if (wdw == NULL) return; /* Set the close function. */ wdw->close_fptr = fptr; }
/** * @brief Sets the default accept function of the window. * * This function is called whenever 'enter' is pressed and the current widget * does not catch it. NULL disables the accept function. * * @param wid ID of the window to set the accept function. * @param accept Function to trigger when window is "accepted". Parameter * passed is window name. */ void window_setAccept( const unsigned int wid, void (*accept)(unsigned int,char*) ) { Window *wdw; /* Get the window. */ wdw = window_wget( wid ); if (wdw == NULL) return; /* Set the accept function. */ wdw->accept_fptr = accept; }
/** * @brief Gets the window's parent. * * @param wid Window to get parent of. * @return Parent of the window or 0 on error. */ unsigned int window_getParent( unsigned int wid ) { Window *wdw; /* Get the window. */ wdw = window_wget( wid ); if (wdw == NULL) return 0; /* Get the parent. */ return wdw->parent; }
/** * @brief Sets the default cancel function of the window. * * This function is called whenever 'escape' is hit and the current widget * does not catch it. NULL disables the cancel function. * * @param wid ID of the window to set cancel function. * @param cancel Function to trigger when window is "cancelled". Parameter * passed is window name. */ void window_setCancel( const unsigned int wid, void (*cancel)(unsigned int,char*) ) { Window *wdw; /* Get the window. */ wdw = window_wget( wid ); if (wdw == NULL) return; /* Set the cancel function. */ wdw->cancel_fptr = cancel; }
/** * @brief Sets the key handler for the window. * * This function is only called if neither the active widget nor the window * itself grabs the input. */ void window_handleKeys( const unsigned int wid, int (*keyhandler)(unsigned int,SDLKey,SDLMod) ) { Window *wdw; /* Get the window. */ wdw = window_wget( wid ); if (wdw == NULL) return; /* Set key event handler function. */ wdw->keyevent = keyhandler; }
/** * @brief Sets the event handler for the window. * * This function is called every time the window recieves input. */ void window_handleEvents( const unsigned int wid, int (*eventhandler)(unsigned int,SDL_Event*) ) { Window *wdw; /* Get the window. */ wdw = window_wget( wid ); if (wdw == NULL) return; /* Set key event handler function. */ wdw->eventevent = eventhandler;; }
/** * @brief Handles mouse events. */ static int tab_mouse( Widget* tab, SDL_Event *event ) { int i, p, change; Window *parent; int x, y, rx, ry; /* Get parent window. */ parent = window_wget( tab->wdw ); if (parent == NULL) return 0; /* Convert to window space. */ toolkit_inputTranslateCoords( parent, event, &x, &y, &rx, &ry ); /* Translate to widget space. */ x += parent->w - tab->x; y += parent->h - tab->y; /* Make sure event is in bottom 20 pixels. */ if ((y>=TAB_HEIGHT) || (y<0)) return 0; /* Handle event. */ p = 20; for (i=0; i<tab->dat.tab.ntabs; i++) { p += 10 + tab->dat.tab.namelen[i]; /* Mark as active. */ if (x < p) { change = -1; if (event->button.button == SDL_BUTTON_WHEELUP) change = (tab->dat.tab.active - 1) % tab->dat.tab.ntabs; else if (event->button.button == SDL_BUTTON_WHEELDOWN) change = (tab->dat.tab.active + 1) % tab->dat.tab.ntabs; else tab->dat.tab.active =i; if ((change != -1) && (change < tab->dat.tab.ntabs)) tab->dat.tab.active = change; /* Create event. */ if (tab->dat.tab.onChange != NULL) tab->dat.tab.onChange( tab->wdw, tab->name, tab->dat.tab.active ); break; } } return 0; }
/** * @brief Gets the dimensions of a window. * * @param wid ID of the window to get dimension of. * @param[out] w Width of the window or -1 on error. * @param[out] h Height of the window or -1 on error. */ void window_dimWindow( const unsigned int wid, int *w, int *h ) { Window *wdw; /* Get the window. */ wdw = window_wget(wid); if (wdw == NULL) { *w = -1; *h = -1; return; } /* Set dimensions. */ *w = wdw->w; *h = wdw->h; }
/** * @brief Renders a button widget overlay. * * @param tab WIDGET_BUTTON widget to render. * @param bx Base X position. * @param by Base Y position. */ static void tab_renderOverlay( Widget* tab, double bx, double by ) { (void) bx; (void) by; Window *wdw; /** Get window. */ wdw = window_wget( tab->dat.tab.windows[ tab->dat.tab.active ] ); if (wdw == NULL) { WARN("Active window in widget '%s' not found in stack.", tab->name); return; } /* Render overlay. */ window_renderOverlay( wdw ); }
/** * @brief Adds an Image Array widget. * * Position origin is 0,0 at bottom left. If you use negative X or Y * positions. They actually count from the opposite side in. * * @param wid Window to add to. * @param x X position. * @param y Y position. * @param w Width. * @param h Height. * @param name Internal widget name. * @param iw Image width to use. * @param ih Image height to use. * @param tex Texture array to use (not freed). * @param caption Caption array to use (freed). * @param nelem Elements in tex and caption. * @param call Callback when modified. */ void window_addImageArray( const unsigned int wid, const int x, const int y, /* position */ const int w, const int h, /* size */ char* name, const int iw, const int ih, glTexture** tex, char** caption, int nelem, void (*call) (unsigned int wdw, char* wgtname), void (*rmcall) (unsigned int wdw, char* wgtname) ) { Window *wdw = window_wget(wid); Widget *wgt = window_newWidget(wdw, name); if (wgt == NULL) return; /* generic */ wgt->type = WIDGET_IMAGEARRAY; /* position/size */ wgt->w = (double) w; wgt->h = (double) h; toolkit_setPos( wdw, wgt, x, y ); /* specific */ wgt->render = iar_render; wgt->renderOverlay = iar_renderOverlay; wgt->cleanup = iar_cleanup; wgt_setFlag(wgt, WGT_FLAG_CANFOCUS); wgt->keyevent = iar_key; wgt->mclickevent = iar_mclick; wgt->mmoveevent = iar_mmove; wgt_setFlag(wgt, WGT_FLAG_ALWAYSMMOVE); wgt->dat.iar.images = tex; wgt->dat.iar.captions = caption; wgt->dat.iar.nelements = nelem; wgt->dat.iar.selected = 0; wgt->dat.iar.pos = 0; wgt->dat.iar.alt = -1; wgt->dat.iar.iw = iw; wgt->dat.iar.ih = ih; wgt->dat.iar.fptr = call; wgt->dat.iar.rmptr = rmcall; wgt->dat.iar.xelem = floor((w - 10.) / (double)(wgt->dat.iar.iw+10)); wgt->dat.iar.yelem = (wgt->dat.iar.xelem == 0) ? 0 : (int)wgt->dat.iar.nelements / wgt->dat.iar.xelem + 1; if (wdw->focus == -1) /* initialize the focus */ toolkit_nextFocus( wdw ); }
/** * @brief Renders a button widget. * * @param tab WIDGET_BUTTON widget to render. * @param bx Base X position. * @param by Base Y position. */ static void tab_render( Widget* tab, double bx, double by ) { int i, x; Window *wdw; glColour *c, *lc; /** Get window. */ wdw = window_wget( tab->dat.tab.windows[ tab->dat.tab.active ] ); if (wdw == NULL) { WARN("Active window in widget '%s' not found in stack.", tab->name); return; } /* Render the active window. */ window_render( wdw ); /* Render tabs ontop. */ x = 20; for (i=0; i<tab->dat.tab.ntabs; i++) { if (i!=tab->dat.tab.active) { lc = toolkit_col; c = toolkit_colDark; /* Draw border. */ toolkit_drawRect( bx+x, by+0, tab->dat.tab.namelen[i] + 10, TAB_HEIGHT, lc, c ); toolkit_drawOutline( bx+x+1, by+1, tab->dat.tab.namelen[i] + 8, TAB_HEIGHT-1, 1., c, &cBlack ); } else { if (i==0) toolkit_drawRect( bx+x-1, by+0, 1, TAB_HEIGHT+1, toolkit_colDark, &cGrey20 ); else if (i==tab->dat.tab.ntabs-1) toolkit_drawRect( bx+x+tab->dat.tab.namelen[i]+9, by+0, 1, TAB_HEIGHT+1, toolkit_colDark, &cGrey20 ); } /* Draw text. */ gl_printRaw( &gl_defFont, bx+x + 5 + SCREEN_W/2, by + (TAB_HEIGHT-gl_defFont.h)/2 + SCREEN_H/2, &cBlack, tab->dat.tab.tabnames[i] ); /* Go to next line. */ x += 10 + tab->dat.tab.namelen[i]; } }
/** * @brief Disables a button. * * @param wid ID of the window to get widget from. * @param name Name of the button to disable. */ void window_disableButton( const unsigned int wid, char* name ) { Widget *wgt; Window *wdw; /* Get the widget. */ wgt = btn_get( wid, name ); if (wgt == NULL) return; /* Disable button. */ wgt->dat.btn.disabled = 1; /* Sanitize focus. */ wdw = window_wget(wid); toolkit_focusSanitize(wdw); }
/** * @brief Checks to see if a widget exists. * * @param wid Window to check widget in. * @param wgtname Name of the widget to check; * @return 1 if the widget exists. */ int widget_exists( const unsigned int wid, const char* wgtname ) { Window *w = window_wget(wid); Widget *wgt; /* Get window. */ if (w==NULL) { WARN("window '%d' does not exist", wid); return 0; } /* Check for widget. */ for (wgt=w->widgets; wgt!=NULL; wgt=wgt->next) if (strcmp(wgtname, wgt->name)==0) return !wgt_isFlag(wgt, WGT_FLAG_KILL); return 0; }
/** * @brief Gets a widget from window id and widgetname. * * @param wid ID of the window to get widget from. * @param name Name of the widget to get. * @return Widget matching name in the window. */ Widget* window_getwgt( const unsigned int wid, const char* name ) { Window *wdw; Widget *wgt; /* Get the window. */ wdw = window_wget(wid); if (wdw == NULL) return NULL; /* Find the widget. */ for (wgt=wdw->widgets; wgt!=NULL; wgt=wgt->next) if (strcmp(wgt->name, name)==0) return wgt; WARN("Widget '%s' not found in window '%u'!", name, wid ); return NULL; }
/** * @brief Moves a widget. * * @param wid ID of the window to get widget from. * @param name Name of the widget to set position to. * @param x New X position to set widget to. * @param y New Y position to set widget to. */ void window_moveWidget( const unsigned int wid, char* name, int x, int y ) { Window *wdw; Widget *wgt; /* Get window. */ wdw = window_wget(wid); if (wdw == NULL) return; /* Get widget. */ wgt = window_getwgt(wid,name); if (wgt == NULL) return; /* Set position. */ toolkit_setPos( wdw, wgt, x, y ); }
/** * @brief Adds a list widget to a window. * * Position origin is 0,0 at bottom left. If you use negative X or Y * positions. They actually count from the opposite side in. * * @param wid ID of the window to add the widget to. * @param x X position within the window to use. * @param y Y position within the window to use. * @param w Width of the widget. * @param h Height of the widget. * @param name Name of the widget to use internally. * @param items Items in the list (will be freed automatically). * @param nitems Number of items in items parameter. * @param defitem Default item to select. * @param call Function to call when new item is selected. Parameter passed * is the name of the list. */ void window_addList( const unsigned int wid, const int x, const int y, const int w, const int h, char* name, char **items, int nitems, int defitem, void (*call) (unsigned int wdw, char* wgtname) ) { Window *wdw = window_wget(wid); Widget *wgt = window_newWidget(wdw, name); if (wgt == NULL) return; /* generic */ wgt->type = WIDGET_LIST; /* specific */ wgt->render = lst_render; wgt->cleanup = lst_cleanup; wgt_setFlag(wgt, WGT_FLAG_CANFOCUS); wgt->keyevent = lst_key; wgt->mclickevent = lst_mclick; wgt->mmoveevent = lst_mmove; wgt->dat.lst.options = items; wgt->dat.lst.noptions = nitems; wgt->dat.lst.selected = defitem; /* -1 would be none */ wgt->dat.lst.pos = 0; wgt->dat.lst.fptr = call; /* position/size */ wgt->w = (double) w; wgt->h = (double) h - ((h % (gl_defFont.h+2)) - 2); toolkit_setPos( wdw, wgt, x, y ); /* check if needs scrollbar. */ if (2 + (nitems * (gl_defFont.h + 2)) > (int)wgt->h) wgt->dat.lst.height = (2 + gl_defFont.h) * nitems + 2; else wgt->dat.lst.height = 0; if (wdw->focus == -1) /* initialize the focus */ toolkit_nextFocus(); }
/** * @brief Adds a button widget to a window, with a hotkey that enables the button to be activated with that key. * * Position origin is 0,0 at bottom left. If you use negative X or Y * positions. They actually count from the opposite side in. * * @param wid ID of the window to add the widget to. * @param x X position within the window to use. * @param y Y position within the window to use. * @param w Width of the widget. * @param h Height of the widget. * @param name Name of the widget to use internally. * @param display Text displayed on the button (centered). * @param call Function to call when button is pressed. Parameter passed * is the name of the button. * @param key Hotkey for using the button without it being focused. */ void window_addButtonKey( const unsigned int wid, const int x, const int y, const int w, const int h, char* name, char* display, void (*call) (unsigned int wgt, char* wdwname), SDLKey key ) { Window *wdw = window_wget(wid); Widget *wgt = window_newWidget(wdw, name); if (wgt == NULL) return; /* generic */ wgt->type = WIDGET_BUTTON; /* specific */ wgt->keyevent = btn_key; wgt->render = btn_render; wgt->cleanup = btn_cleanup; wgt_setFlag(wgt, WGT_FLAG_CANFOCUS); wgt->dat.btn.display = strdup(display); wgt->dat.btn.disabled = 0; /* initially enabled */ wgt->dat.btn.fptr = call; if (key != 0) { wgt->dat.btn.key = key; btn_updateHotkey(wgt); } /* position/size */ wgt->w = (double) w; wgt->h = (double) h; toolkit_setPos( wdw, wgt, x, y ); if (wgt->dat.btn.fptr == NULL) { /* Disable if function is NULL. */ wgt->dat.btn.disabled = 1; wgt_rmFlag(wgt, WGT_FLAG_CANFOCUS); } if (wdw->focus == -1) /* initialize the focus */ toolkit_nextFocus( wdw ); }
/** * @brief Adds an image widget to the window. * * Position origin is 0,0 at bottom left. If you use negative X or Y * positions. They actually count from the opposite side in. * * @param wid ID of the window to add the widget to. * @param x X position within the window to use. * @param y Y position within the window to use. * @param name Name of the widget to use internally. * @param image Image to use. * @param border Whether to use a border. */ void window_addImage( const unsigned int wid, const int x, const int y, char* name, glTexture* image, int border ) { Window *wdw = window_wget(wid); Widget *wgt = window_newWidget(wdw, name); /* generic */ wgt->type = WIDGET_IMAGE; /* specific */ wgt->render = img_render; wgt->dat.img.image = image; wgt->dat.img.border = border; wgt->dat.img.colour = NULL; /* normal colour */ /* position/size */ wgt->w = (image==NULL) ? 0 : wgt->dat.img.image->sw; wgt->h = (image==NULL) ? 0 : wgt->dat.img.image->sh; toolkit_setPos( wdw, wgt, x, y ); }
/** * @brief Handles mouse events. */ static int tab_mouse( Widget* tab, SDL_Event *event ) { int i, p; Window *parent; int x, y, rx, ry; Uint8 type; /* Get parrent window. */ parent = window_wget( tab->wdw ); if (parent == NULL) return 0; /* Convert to window space. */ type = toolkit_inputTranslateCoords( parent, event, &x, &y, &rx, &ry, 0 ); /* Translate to widget space. */ x += parent->w - tab->x; y += parent->h - tab->y; /* Make sure event is in bottom 20 pixels. */ if ((y>=TAB_HEIGHT) || (y<0)) return 0; /* Handle event. */ p = 20; for (i=0; i<tab->dat.tab.ntabs; i++) { p += 10 + tab->dat.tab.namelen[i]; /* Mark as active. */ if (x < p) { tab->dat.tab.active = i; /* Create event. */ if (tab->dat.tab.onChange != NULL) tab->dat.tab.onChange( tab->wdw, tab->name, tab->dat.tab.active ); break; } } return 0; }
static int tab_key( Widget* tab, SDL_Event *event ) { int change; SDLKey key, bind_key; SDLMod mod, bind_mod; Window *wdw; int ret; /* Event info. */ key = event->key.keysym.sym; mod = input_translateMod( event->key.keysym.mod ); /* Handle tab changing. */ change = -1; CHECK_CHANGE( "switchtab1", 0 ); CHECK_CHANGE( "switchtab2", 1 ); CHECK_CHANGE( "switchtab3", 2 ); CHECK_CHANGE( "switchtab4", 3 ); CHECK_CHANGE( "switchtab5", 4 ); CHECK_CHANGE( "switchtab6", 5 ); CHECK_CHANGE( "switchtab7", 6 ); CHECK_CHANGE( "switchtab8", 7 ); CHECK_CHANGE( "switchtab9", 8 ); CHECK_CHANGE( "switchtab0", 9 ); /* Window. */ ret = 0; wdw = window_wget( tab->dat.tab.windows[ tab->dat.tab.active ] ); /* Handle keypresses. */ switch (key) { case SDLK_TAB: if (mod & NMOD_SHIFT) { if (mod & NMOD_CTRL) change = (tab->dat.tab.active - 1) % tab->dat.tab.ntabs; else change = (tab->dat.tab.active + 1) % tab->dat.tab.ntabs; } else { if (mod & NMOD_CTRL) toolkit_prevFocus( wdw ); else toolkit_nextFocus( wdw ); } ret = 1; break; default: break; } /* Switch to the selected tab if it exists. */ if ((change != -1) && (change < tab->dat.tab.ntabs)) { tab->dat.tab.active = change; /* Create event. */ if (tab->dat.tab.onChange != NULL) tab->dat.tab.onChange( tab->wdw, tab->name, tab->dat.tab.active ); ret = 1; } return ret; }