/** * @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 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 Handles keyboard events. * * @param wdw Window recieving the key event. * @param event Keyboard event to handle. * @return 1 if the event is used, 0 if it isn't. */ static int toolkit_keyEvent( Window *wdw, SDL_Event* event ) { Widget *wgt; SDLKey key; SDLMod mod; char buf[2]; /* Event info. */ key = event->key.keysym.sym; mod = event->key.keysym.mod; /* Hack to simulate key repetition */ if (event->type == SDL_KEYDOWN) toolkit_regKey(key, event->key.keysym.unicode); else if (event->type == SDL_KEYUP) toolkit_unregKey(key); /* See if window is valid. */ if (wdw == NULL) return 0; /* Get widget. */ wgt = toolkit_getFocus( wdw ); /* We only want keydown from now on. */ if (event->type != SDL_KEYDOWN) return 0; /* Trigger event function if exists. */ if (wgt != NULL) { if (wgt->keyevent != NULL) { if ((*wgt->keyevent)( wgt, key, mod )) return 1; } if (wgt->textevent != NULL) { buf[0] = event->key.keysym.unicode & 0x7f; buf[1] = '\0'; if ((*wgt->textevent)( wgt, buf )) return 1; } } /* Handle other cases where event might be used by the window. */ switch (key) { case SDLK_TAB: if (mod & (KMOD_LCTRL | KMOD_RCTRL)) toolkit_prevFocus( wdw ); else toolkit_nextFocus( wdw ); break; case SDLK_RETURN: if (wdw->accept_fptr != NULL) { wdw->accept_fptr( wdw->id, wdw->name ); return 1; } break; case SDLK_ESCAPE: if (wdw->cancel_fptr != NULL) { wdw->cancel_fptr( wdw->id, wdw->name ); return 1; } break; default: break; } /* Finally the stuff gets passed to the custom key handler if it's defined. */ if (wdw->keyevent != NULL) (*wdw->keyevent)( wdw->id, key, mod ); 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; }