Az SMGUI nem tartalmaz azonnali kódlekezlést, sem visszahívásokat. Elhelyett feltételezi, hogy már úgyis megvannak a változóid, és csak egy űrlapot kér, ami ezekre a változókra hivatkozik.
Az űrlap maga egy ui_form_t
elemeket tartalmazó tömb, amiben a legutolsó elem típusa MINDIG UI_END
. Néhány mező
általános, mások típusspecifikusak. Az általános mezők a következők:
Paraméter | Leírás |
---|---|
form->ptr |
Mutató az adatra |
form->type |
Űrlapelem típusa |
form->align |
Űrlapelem igazítása |
form->flags |
Űrlapelem jelzők (pl. láthatóság) |
form->x |
Űrlapelem igényelt pozíció |
form->y |
Űrlapelem igényelt pozíció |
form->w |
Űrlapelem igényelt szélesség |
form->h |
Űrlapelem igényelt magasság |
form->m |
Űrlapelem margó |
form->p |
Űrlapelem eltartás (csak tárolóknál) |
Ezek szabályozzák, hogy egy űrlapelem mező hogyan jelenik meg.
UI_HIDDEN
nem látszik, nem befolyásolja a normál folyamotUI_NOBULLET
csak [kapcsoló], [pipa] és [választó], csak a címkét jelenítsék megUI_NOHEADER
csak [táblázat] és rács, ne rajzolja ki a fejlécetUI_NOBR
a következő mezőt ugyanebbe a sorba kényszeríti, nincs sortörésUI_FORCEBR
ellenkező, a következő mező mindenképp új sorba kerülUI_ALTSKIN
olyan mezők esetén, amik több bőrt is támogatnak (pl. tab menü helyett)UI_NOBORDER
tárolóknál, ne jelenjen meg a keretUI_NOSHADOW
felugróknál, ne legyen árnyékukUI_HSCROLL
tárolóknál, jelenljen meg vízszintes szkrollozóUI_VSCROLL
tárolóknál, jelenljen meg függőleges szkrollozóUI_SCROLL
ugyanaz, mint az UI_HSCROLL
+ UI_VSCROLL
UI_DRAGGABLE
felugróknál, engedélyezi, hogy a felhasználó átmozgassaUI_RESIZABLE
felugróknál, engedélyezi, hogy a felhasználó átméretezzeUI_SELECTED
a beviteli mezőt kiválasztottként jeleníti megUI_DISABLED
inaktívvá teszi a mezőt, más a megjelenése és nem kattinthatóAz SMGUI nem használja a szokásos pakolt sor / oszlop / négyzetrács elrendezést, helyette HTML-szerű flexibilis folyamot
alkalmaz. A koordináták megadhatók a form->x
és form->y
mezőkben háromféleképp: relatív, abszolút és százalékban.
UI_REL()
makró is. Az így pozícionált mezők befolyásolják a folyamot.UI_ABS()
makrót kell használni. Megváltoztatható a gravitáció is, UI_ABS_RIGHT()
(jobbról) vagy UI_ABS_BOTTOM()
(alulról) a szülő tároló jobb oldalától vagy aljától számítódik. A normál folyamon kívüli.UI_PERCENT()
makró használatos. Ez a szülő tároló méretéhez képest határozza meg a pozíciót. A normál folyamon kívüli.UI_PERPLUS()
makrót kell használni.Ha a form->w
és form->h
nincs megadva és 0, akkor a mező szélessége és magassága automatikusan számítódik. Ha az UI_ABS()
makrót használjuk ezekre, akkor az a szülő tároló szélessége (vagy magassága) mínusz a megadott érték pixelben lesz a szélesség
(vagy magasság).
Használható a form->align
a megadott x, y koordinátákhoz való igazításhoz. Ez egy VAGY-olt bitmaszk.
UI_LEFT
a mezőt úgy helyezi, hogy a form->x
balra van (alapértelmezett)UI_RIGHT
a mezőt úgy helyezi, hogy a form->x
jobbra vanUI_CENTER
a mezőt úgy helyezi, hogy a form->x
középre kerülUI_TOP
a mezőt úgy helyezi, hogy a form->y
felülre kerül (alapértelmezett)UI_BOTTOM
a mezőt úgy helyezi, hogy a form->y
alulra kerülUI_MIDDLE
a mezőt úgy helyezi, hogy a form->y
középre kerülPéldák:
ui_form_t form[] = {
/* ezek szorosan egymás mellé kerülnek, balról jobbra,
* csak akkor új sorba, ha muszáj */
{ .type = UI_LABEL, .label = 1 },
{ .type = UI_LABEL, .label = 1 },
/* ezek szintén egymás mellé kerülnek, de eltartással */
{ .type = UI_LABEL, .x = UI_REL(10), .label = 1 },
/* ez abszolút pozícióra kerül */
{ .type = UI_LABEL, .x = UI_ABS(100), .y = UI_ABS(100), .label = 1 },
/* ez az ablak közepére kerül */
{ .type = UI_LABEL, .align = UI_CENTER | UI_MIDDLE,
.x = UI_PERCENT(50), .y = UI_PERCENT(50), .label = 1 },
/* ez ablak szélesség - 20 és ablak magasság - 20 méretű lesz */
{ .type = UI_POPUP, .x = UI_ABS(10), .y = UI_ABS(10),
.w = UI_ABS(20), .h = UI_ABS(20), .ptr = &popupform },
/* fontos, hogy zárjuk a listát */
{ .type = UI_END }
};
Mivel az űrlap csupán csak hivatkozik a változókra, ezért simán működik az, hogy az egyik szálon van megjelenítve az elrendezés és egy másik szálon történik a változók kezelése. Ugyanakkor ha magát az űrlapot szeretnénk dinamikusan változtatni egy másik szálból, akkor az a fejlesztő felelőssége, hogy ilyenkor megfelelően szemaforokkal védje az űrlapját. Például:
ui_form_t form[];
/* ez a funkció bármelyik szálról hívható */
void regenerate_form()
{
mutex_lock(&my_form_mutex);
/* itt lehet módosítani a form[] tömböt */
mutex_unlock(&my_form_mutex);
}
/* ez pedig a fő szálon a fő ciklusban */
mutex_lock(&my_form_mutex);
evt = ui_event(&ctx, form);
mutex_unlock(&my_form_mutex);
Mivel az SMGUI maga semmilyen threading függvénykönyvtárat nem használ, ezért bármelyik threading és mutex implementáció
használható vele. Az SDL motor például biztosít egy SDL_Mutex
típust, GLFW esetén meg használható a pthread függvénykönyvtár.
Az újrarajzolás az [eseménykezelés] hívásakor automatikusan megtörténik, ha szükség van rá, és ennyi. De ha valamelyik hivatkozott változó az UI látókörén kívül módosul, akkor szükséges a következő függvény hívása:
int ui_refresh(ui_t *ctx);
Jelzi az UI-nak, hogy szükség van az újrarajzolásra.
Paraméter | Leírás |
---|---|
ctx |
Mutató az UI kontextusra |
Siker esetén 0-val tér vissza, egyébként hibakóddal.