Státusz-Módú GUI API

Üdvözöl az SMGUI, a státusz vezérelt grafikus felhasználói felület eszköztár kézikönyve.

A státusz-vezérelt UI alapelve az, hogy már úgyis megvannak a változóid, szóval elég csak hivatkozni azokra egy űrlapból, nem kell sem visszahívás sem azonnali kódlekezlés, csupán csak azon már meglévő változók értékei vezérlik a GUI megjelenítését.

TIPP

Ez a kézikönyv internet nélkül is használható. A jobb-klikk menüben válaszd az "Oldal mentése" menüpontot.

Behúzás

Ez a függvénykönyvtár mindent tartalmaz egyetlen fejlécfájlban, és használható mind fejléc, mind implementációs módban. Alapból a fejléc-mód van használatban, ami lehetővé teszi, hogy más fejlécekből is behúzásra kerüljön, és nem tartalmazza ilyenkor az implementációt. Az implementációs módhoz pontosan egyetlen egy .c/.cpp forrásban meg kell adni az UI_IMPLEMENTATION előfordító define-t pontosan ezen fejléc fájl include-ja előtt.

Az alap függvénykönyvtár platform és motor független. Bármilyen motorral és fontmeghajtóval képes működni, ehhez csak be kell húzni a megfelelő fejlécfájlt még az ui.h előtt. Például:

1
2
3
4
#include "ui_glfw.h" #include "ui_psf2.h" #define UI_IMPLEMENTATION #include "ui.h"

A referencia implementáció GLFW3, SDL2/3 és X11 motorral érkezik; ami a fontokat illeti, van PC-Screen-Font (amit a Linux Console használ), illetve Scalable Screen Font (sokkal hatékonyabb, mint a TTF vagy OTF, és bármilyen font, bitmap, vektor vagy pixel font átkonvertálható SSFN-é).

Alapból - ha semmilyen másik modul nem lett előtte behúzva -, akkor az ui.h behúzza a GLFW3 motort és a PSF2 font meghajtót, valamint egy minimális, ékezetes betűk néküli ASCII font-ot is beágyaz (2080 bájt lefordítva).

Visszatérési értékek

Hacsak másképp nincs jelezve, minden függvény negatív hibakódot ad vissza.

Define Leírás
UI_OK Sikeres, nem volt hiba
UI_ERR_BADINP Hibás paraméter
UI_ERR_BACKEND Hiba a motor inicializálásánál
UI_ERR_NOMEM Memória foglalási hiba


Ablak

Inicializálás

1
int ui_init(ui_t *ctx, int txtc, char **txtv, int w, int h, ui_image_t *icon);

Inicializálja az UI kontextust és ablakot nyit. A legelső sztringnek a txtv[] tömbben az ablak fejlécének kell lennie, a többi szabadon választható.

Paraméter Leírás
ctx Mutató az UI kontextusra
txtc Sztringek száma
txtv Lokalizációhoz sztringtömb
w Ablak szélessége
h Ablak magassága
icon Ablak ikonja kép (vagy NULL)

Siker esetén 0-val tér vissza, egyébként hibakóddal.

Felszabadítás

1
int ui_free(ui_t *ctx);

Bezárja az ablakot és felszabadítja a lefoglalt erőforrásokat.

Paraméter Leírás
ctx Mutató az UI kontextusra

Siker esetén 0-val tér vissza, egyébként hibakóddal.

Teljesképernyő

1
int ui_fullscreen(ui_t *ctx);

Váltogatja a kontextust teljesképernyős és ablakos mód között (inicializálást követően ablakos).

Paraméter Leírás
ctx Mutató az UI kontextusra

Siker esetén 0-val tér vissza, egyébként hibakóddal.

Háttérablak

1
void *ui_getwindow(ui_t *ctx);

Amennyiben szükség lenne rá, ezzel a funkcióval lekérhető a motor által használt ablak objektum.

Paraméter Leírás
ctx Mutató az UI kontextusra

Egy implementációfüggő objektumot ad vissza.

Általános szerkezet

A program általános szerkezetének valami ilyesminek kell lennie:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/* UI kontextus, ablakonként egy */ ui_t ctx; /* lokalizációhoz sztringtömb */ enum { WINDOW_TITLE, HELLO_WORLD }; char *english[] = { "Window title", "Hello World!" }; /* ablak megnyitása és kontextus inicializálása */ ui_init(&ctx, 2, english, 640, 480, NULL); /* a fő ciklus */ do { /* tedd, amit tennél, rajzolj, amit akarsz */ glClearColor(0.0, 0.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* ... */ /* események lekérése és UI réteg megjelenítése a kívánt űrlappal */ /* ha ez NULL-t ad vissza, ki kell lépni a ciklusból */ if(!(evt = ui_event(&ctx, form))) break; /* események feldolgozása */ switch(evt->type) { case UI_EVT_KEY: /* billentyűleütés */ break; case UI_EVT_MOUSE: /* egérgomb esemény */ break; case UI_EVT_GAMEPAD: /* gamepad esemény */ break; /* ... */ } } while(1); /* ablak bezárása */ ui_free(&ctx);


Lokalizáció

Az SMGUI támogatja a többnyelvűséget, de ehhez a sztringeket össze kell gyűjteni egy tömbbe. Javaslom egy enum létrehozását is az indexekhez.

char *dictionary[];

Ezt a tömböt át kell adni, amikor az ablakot megnyitjuk. A legelső sztringnek a tömbben az ablak fejlécének kell lennie, a többi szabadon választható.

Nyelvválasztás

1
int ui_settxt(ui_t *ctx, char **txtv);

A nyelv futás közben bármikor megváltoztatható. Az új txtv[] tömbnek pontosan annyi elemének kell lennie, mint ahány elemű az inicializálásnál átadott tömb volt.

Paraméter Leírás
ctx Mutató az UI kontextusra
txtv Sztringtömb

Siker esetén 0-val tér vissza, egyébként hibakóddal.



Fontok

Az SMGUI tetszőleges fontokat képes támogatni, és mindjárt kétféle referencia implementációval érkezik, ui_psf2.h (alapértelmezett, egyszerű bitmap font) és ui_ssfn.h (vektor, átméretezett bitmap és pixelmap fontok), de saját is egyszerűen hozzáadható.

Tetszőleges implementáció megadása

1
int ui_fonthook(ui_t *ctx, ui_font_bbox bbox, ui_font_draw draw);

Egy bármilyen font formátum támogatásához két visszacsatolás megadására van szükség a kontextusban.

Paraméter Leírás
ctx Mutató az UI kontextusra
bbox Méretfunkció
draw Kirajzolófunkció

Siker esetén 0-val tér vissza, egyébként hibakóddal.

A visszacsatolások:

1
2
typedef int (*ui_font_bbox)(void *fnt, char *str, char *end, int *w, int *h, int *l, int *t);

Megméri a sztringet, és a szélességét a w, a magasságát a h változóban adja vissza pixelben. Ha van baloldali átfedés, akkor az az l-be kerül. Az alapvonal felülről számítva a t-be kerül (mind az l és a t lehet NULL, ha nincs ezekre szükség). A sztring egy nullával lezárt UTF-8 sztring str-ben, de ha az end nem NULL, akkor ott véget ér.

1
2
3
typedef int (*ui_font_draw)(void *fnt, char *str, char *end, uint8_t *dst, uint32_t color, int x, int y, int l, int t, int p, int cx0, int cy0, int cx1, int cy1);

Kirajzolja a sztringet x, y koordinátákra (l baloldali átfedéssel és t alapvonalra) a dst pixelbufferre, aminek egy rasztersora p bájtnyi. Nagyon fontos, hogy a megadott cx0, cy0 és cx1, cy1 koordináták közötti crop régión kívül nem szabad semmit módosítania. Az implementációspecifikus fnt hivatkozik a fontra, a szöveg színe color, a nullával lezárt UTF-8 sztring str-ben, de ha az end nem NULL, akkor ott véget ér.

Font betöltése

FIGYELEM

Ez a funkció nem inicializálja a fontot, csak letárolja a mutatót, hogy átadja a visszacsatolásoknak. A font inicializálás és felszabadítás platform-specifikus és a hívó dolga (a PSF2 meghajtónak nincs ezekre szüksége).

1
int ui_font(ui_t *ctx, void *fnt);

Beállítja a használandó fontot.

Paraméter Leírás
ctx Mutató az UI kontextusra
fnt Használandó font

Siker esetén 0-val tér vissza, egyébként hibakóddal.



Kinézet

Egérmutató

1
int ui_swcursor(ui_t *ctx, ui_image_t *cursor);

Kikapcsolja a hardveres egérmutatót és helyette egy képet rak ki szoftveresen.

Paraméter Leírás
ctx Mutató az UI kontextusra
cursor Mutató a kurzor képre

Siker esetén 0-val tér vissza, egyébként hibakóddal.

1
int ui_hwcursor(ui_t *ctx);

Kikapcsolja a szoftveres egérmutatót és engedélyezi a hardverest.

Paraméter Leírás
ctx Mutató az UI kontextusra

Siker esetén 0-val tér vissza, egyébként hibakóddal.

Színtéma

Az SMGUI többféle színtémát is támogat, amik lényegében paletták. Minden palettaelem egy UI elem színének felel meg. Ezek sorrendben a következők:

  • előtér (betűk) színe
  • felugró és menü címsor színe
  • felugró és menü háttérszíne
  • felugró és menü árnyékszíne
  • aktív kapcsoló előtérszíne
  • aktív kapcsoló háttérszíne
  • menü kielemlés előtérszíne
  • menü kiemelés háttérszíne
  • inaktív előtérszín
  • inaktív háttérszín
  • szkrollozó háttérszíne
  • beviteli mező előtérszíne
  • beviteli mező világos keretszín
  • beviteli mező sötét keretszín
  • beviteli mező háttérszíne
  • kiválasztott beviteli mező előtérszíne
  • kiválasztott beviteli mező keretszíne
  • kiválasztott beviteli mező kurzorszíne
  • normál gomb előtérszíne
  • normál gomb árnyékszíne
  • normál gomb külső keretszíne
  • kiválasztott gomb előtérszíne
  • kiválasztott gomb árnyékszíne
  • kiválasztott gomb külső keretszíne
  • gomb világos belső keretszín
  • gomb sötét belső keretszín
  • gomb világos háttérszín
  • gomb sötét háttérszín
  • folyamatjelző világos színe
  • folyamatjelző háttérszíne
  • folyamatjelző sötét színe
1
int ui_theme(ui_t *ctx, uint32_t *theme);

Beállít egy tetszőleges színtémát. A theme[] tömbnek annyi eleműnek kell lennie, ahány UI szín van, lásd a fenti listát.

Paraméter Leírás
ctx Mutató az UI kontextusra
theme Mutató a palettára

Siker esetén 0-val tér vissza, egyébként hibakóddal.

Bőr

Az SMGUI bőröket is támogat, amik lényegében képek, mindegyik az UI egy-egy elemének felel meg. Ezek sorrendben a következők:

  • egérkurzor (kattintópont középen)
  • felugró és menü bal felső sarok
  • felugró és menü felső középső sáv
  • felugró és menü jobb felső sarok
  • felugró és menü bal oldal
  • felugró és menü háttér
  • felugró és menü jobb oldal
  • felugró és menü bal alsó sarok
  • felugró és menü alsó középső sáv
  • felugró és menü jobb alsó sarok
  • felugró és menü cím háttere
  • felugró és menü bezár gomb
  • felugró és menü alternatív bal felső sarok
  • felugró és menü alternatív felső középső sáv
  • felugró és menü alternatív jobb felső sarok
  • felugró és menü alternatív bal oldal
  • felugró és menü alternatív háttér
  • felugró és menü alternatív jobb oldal
  • felugró és menü alternatív bal alsó sarok
  • felugró és menü alternatív alsó középső sáv
  • felugró és menü alternatív jobb alsó sarok
  • felugró és menü alternatív cím háttere
  • felugró és menü alternatív bezár gomb
  • menü alternatív bal oldal
  • menü alternatív háttér
  • menü alternatív jobb oldal
  • menü kiemelés háttér
  • beviteli mező háttér
  • folyamatjelző gomb háttere
  • csúszka bal oldal
  • csúszka háttér
  • csúszka jobb oldal
  • csúszka gomb
  • függőleges szkrollozó teteje
  • függőleges szkrollozó háttere
  • függőleges szkrollozó alja
  • függőleges szkrollozó gomb teteje
  • függőleges szkrollozó gomb közepe
  • függőleges szkrollozó gomb alja
  • vízszintes szkrollozó eleje
  • vízszintes szkrollozó háttere
  • vízszintes szkrollozó vége
  • vízszintes szkrollozó gomb bal oldal
  • vízszintes szkrollozó gomb közepe
  • vízszintes szkrollozó gomb jobb oldal
  • pipamező üresen
  • pipamező bepipálva
  • választó üresen
  • választó kiválasztva
  • normál gomb bal oldal
  • normál gomb háttere
  • normál gomb jobb oldal
  • lenyomott gomb bal oldal
  • lenyomott gomb háttere
  • lenyomott gomb jobb oldal
  • kiválasztott gomb bal oldal
  • kiválasztott gomb háttere
  • kiválasztott gomb jobb oldal
  • balra nyíl gomb
  • lefelé nyíl gomb
  • jobbra nyíl gomb
  • lenyomott balra nyíl gomb
  • lenyomott lefelé nyíl gomb
  • lenyomott jobbra nyíl gomb
  • kiválasztott balra nyíl gomb
  • kiválasztott lefelé nyíl gomb
  • kiválasztott jobbra nyíl gomb
1
int ui_skin(ui_t *ctx, ui_image_t *skin);

Betölt egy tetszőleges bőrt. A skin[] tömbnek annyi eleműnek kell lennie, ahány UI elem van, lásd a fenti listát.

Paraméter Leírás
ctx Mutató az UI kontextusra
skin Mutató a bőr képek tömbre

Siker esetén 0-val tér vissza, egyébként hibakóddal.

Ha az stb_image.h be lett húzva az ui.h előtt, akkor a következő függvény is használható, hogy egyetlen PNG képről töltse be az összes bőrképet:

1
int ui_pngskin(ui_t *ctx, uint8_t *png, int size);

Betölt egy tetszőleges bőrt egy csomagolt PNG fájlból.

Paraméter Leírás
ctx Mutató az UI kontextusra
png Mutató a PNG képre
size A PNG kép mérete bájtokban

Siker esetén 0-val tér vissza, egyébként hibakóddal.

A csomagolt PNG-ben kell lennie egy kommentnek, x, y, w, h ASCII decimális számokkal minden sorban, amik területeket jelölnek a képen. Ilyen csomagolt PNG előállítható például az sprpack program -cdt kapcsolóival:

sprpack -cdt bőr.png egér.png felugró_balfelső.png felugró_felsőközép.png ...

Minden UI elem PNG-jét fel kell sorolni, és pontosan abban a sorrendben, ahogy fentebb látszik, máskülönben a bőr PNG nem fog működni.



Eseménykezelés

1
ui_event_t *ui_event(ui_t *ctx, ui_form_t *form);

Ez az SMGUI lelke, ez a függvény lekéri az eseményeket és hozzáad a megjelenítéshez egy UI réteget a megadott elrendezés szerint.

Paraméter Leírás
ctx Mutató az UI kontextusra
form Űrlap elrendezés

Ha ki kell lépni a fő ciklusból, NULL-al tér vissza, egyébként egy esemény objektummal.

Ha az UI-tól függetlenül megváltozott az egyik változó, amire az átadott form hivatkozik, akkor meg kell hívni az ui_refresh() függvényt az ui_event() hívása előtt, hogy kikényszerítsünk egy újrarajzolást.

A visszaadott eseményt az evt->type alapján kell értelmezni, mivel a legtöbb eseménymező típusfüggő.



Nincs esemény

Semmi sem történt.

Paraméter Leírás
evt->type UI_EVT_NONE (0)


Egér

Ez akkor generálódik, ha egy egérgombot lenyomnak vagy felengednek.

Paraméter Leírás
evt->type UI_EVT_MOUSE
evt->btn Aktuális gombstátusz
evt->x Aktuális egér X pozíció
evt->y Aktuális egér Y pozíció

A btn mező egy bitmaszkot tartalmaz, a következő értékekkel:

Define Leírás
UI_BTN_L Bal egérgomb
UI_BTN_M Középső egérgomb
UI_BTN_R Jobb egérgomb
UI_BTN_U Felfelegörgetés
UI_BTN_D Lefelegörgetés
UI_BTN_A Balragörgetés
UI_BTN_B Jobbragörgetés
UI_BTN_RELEASE Ha felengedés esemény

Ha esemény nélkül van szükség az egér pozíciójára, akkor használható az

1
int ui_getmouse(ui_t *ctx, int *x, int *y);
Paraméter Leírás
ctx Mutató az UI kontextusra
x Mutató az X pozíció tárolásához
y Mutató az Y pozíció tárolásához

Siker esetén 0-val tér vissza, egyébként hibakóddal.



Gamepad

Ez akkor generálódik, ha valamelyik gamepad státusza megváltozik.

Paraméter Leírás
evt->type UI_EVT_GAMEPAD
evt->btn Aktuális gombstátusz
evt->x Bal botkar X pozíció
evt->y Bal botkar Y pozíció
evt->rx Jobb botkar X pozíció
evt->ry Jobb botkar Y pozíció
evt->key[0] Gamepad indexe ha több is lenne

A botkarok koordinátái előjelesek, és a -32768 .. +32768 tartományba esnek. A btn mező egy bitmaszkot tartalmaz, a következő értékekkel:

Define Leírás
UI_BTN_A Az 'A'/kereszt gomb státusza
UI_BTN_B Az 'B'/kör gomb státusza
UI_BTN_X Az 'X'/négyzet gomb státusza
UI_BTN_Y Az 'Y'/háromszög gomb státusza
UI_BTN_L DPad balra státusza
UI_BTN_R DPad jobbra státusza
UI_BTN_U DPad fel státusza
UI_BTN_D DPad le státusza
UI_BTN_BA Vissza gomb státusza
UI_BTN_ST Start gomb státusza
UI_BTN_GU Útmutató gomb státusza
UI_BTN_LT Balhüvelyk gomb státusza
UI_BTN_RT Jobbhüvelyk gomb státusza
UI_BTN_LS Balra shoulder gomb státusza
UI_BTN_RS Jobbra shoulder gomb státusza


Billentyűzet

Ez akkor generálódik, ha egy billentyűt leütnek.

Paraméter Leírás
evt->type UI_EVT_KEY
evt->btn Módosítók státusza
evt->key Leütött gomb

A visszaadott gomb egy UTF-8 karakter, vagy (speciális gombok esetén) egy érvénytelen UTF-8 szekvencia a gomb nevével. A megkülönböztetéshez meg kell nézni, hogy key[1] üres-e, és hogy a legmagasabb bit a key[0]-ban be van-e állítva (érvényes UTF-8) vagy sem (gombnév).

TIPP

Nincs gombleképezés, hogy megtudjuk, milyen kódot gerenál egy gomb, csak ki kell iratni a evt->key tartalmát.

A btn mező egy bitmaszkot tartalmaz, a következő értékekkel:

Define Leírás
UI_BTN_SHIFT Az egyik Shift le van nyomva
UI_BTN_CONTROL Az egyik Control le van nyomva
UI_BTN_ALT Az egyik Alt le van nyomva (jobboldalit hívják AltGr-nek)
UI_BTN_GUI Az egyik GUI le van nyomva

A módosító gombok (LShift, RShift, LCtrl, RCtrl, LAlt, RAlt, LGui és RGui) esetén billentyűfelengedés esemény is generálódik, ahol a UI_BTN_RELEASE be van állítva. A többi gomb nem generál ilyen eseményt.



Ráhúzott fájl

Ez akkor keletkezik, ha a felhasználó egy fájlt húz az ablakra.

Paraméter Leírás
evt->type UI_EVT_DROP
evt->x Aktuális egér X pozíció
evt->y Aktuális egér Y pozíció
evt->fn A fájl elérési útja


Ablakátméretezés

Ez akkor generálódik, ha az ablakot átméretezik.

Paraméter Leírás
evt->type UI_EVT_RESIZE
evt->x Az új ablak szélesség
evt->y Az új ablak magasság


Vágólap

Beillesztés

A vágólap lekéréséhez (amikor olyan billentyűzet esemény érkezett, amiben a gomb Paste), a következő függvény hívható:

1
char *ui_getclipboard(ui_t *ctx);
Paraméter Leírás
ctx Mutató az UI kontextusra

NULL-t ad vissza, ha a vágólap üres, egyébként a vágólap tartalmát egy újonnan allokált bufferben. A hívó felelőssége a buffer felszabadítása, ha már nincs rá szükség.

Kivágás

A vágólap beállítására (amikor olyan billentyűzet esemény érkezett, amiben a gomb Cut vagy Copy), a következő függvény való:

1
char *ui_setclipboard(ui_t *ctx, char *str);
Paraméter Leírás
ctx Mutató az UI kontextusra
str Vágólapra helyezendő sztring

Siker esetén 0-val tér vissza, egyébként hibakóddal.



Elrendezés

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)

Mező jelzők

Ezek szabályozzák, hogy egy űrlapelem mező hogyan jelenik meg.

  • UI_HIDDEN nem látszik, nem befolyásolja a normál folyamot
  • UI_NOBULLET csak kapcsoló, pipa és választó, csak a címkét jelenítsék meg
  • UI_NOHEADER csak táblázat és rács, ne rajzolja ki a fejlécet
  • UI_NOBR a következő mezőt ugyanebbe a sorba kényszeríti, nincs sortörés
  • UI_FORCEBR ellenkező, a következő mező mindenképp új sorba kerül
  • UI_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 keret
  • UI_NOSHADOW felugróknál, ne legyen árnyékuk
  • UI_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ó átmozgassa
  • UI_RESIZABLE felugróknál, engedélyezi, hogy a felhasználó átméretezze
  • UI_SELECTED a beviteli mezőt kiválasztottként jeleníti meg
  • UI_DISABLED inaktívvá teszi a mezőt, más a megjelenése és nem kattintható

Pozícionálás

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.

  • Relatív pozícionálás az alapértelmezett, de használható az UI_REL() makró is. Az így pozícionált mezők befolyásolják a folyamot.
  • Abszolút pozícionáláshoz az 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.
  • Százalékhoz az 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.
  • Százalék plusz valamennyi pixelhez az 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 van
  • UI_CENTER a mezőt úgy helyezi, hogy a form->x középre kerül
  • UI_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ül
  • UI_MIDDLE a mezőt úgy helyezi, hogy a form->y középre kerül

Példák:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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 } };

Többszálúság

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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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.

Újrarajzolás

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:

1
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.



Tárolók

Ha egy tárolót egy kapcsoló mező előz meg, akkor az a kapcsoló ennek a tárolónak a láthatóságát fogja kapcsolni.

Felugró

ui_popup.png

Kirajzol egy felugrót.

Paraméter Leírás
form->type UI_POPUP
form->flags Esetleg UI_HIDDEN, UI_DRAGGABLE vagy UI_RESIZABLE
form->ptr Mutató egy másik ui_form_t bufferre
form->m Margó pixelekben
form->p Eltartás pixelekben
form->label Cím, lokalizált sztringtömb index (vagy 0)
ui_menu.png

Ugyanaz, mint a felugró, de alapból UI_HIDDEN, azaz elrejtett és egyszerre csak egy menü lehet megjelenítve. A gyerek pipa és választó mezői ki lesznek emelve, amikor az egér föléjük kerül.

Paraméter Leírás
form->type UI_MENU
form->flags Esetleg UI_SCROLL
form->ptr Mutató egy másik ui_form_t bufferre
form->m Margó pixelekben
form->p Eltartás pixelekben

Divízió

Nem rajzol ki semmit, csak csoportosíthatóvá teszi a mezőket, hogy egyszerre lehessen őket megjeleníteni / elrejteni meg pozícionálni.

Paraméter Leírás
form->type UI_DIV
form->flags Esetleg UI_SCROLL
form->ptr Mutató egy másik ui_form_t bufferre
form->m Margó pixelekben
form->p Eltartás pixelekben

Táblázat

Adatmezőket rajzol ki táblázat vagy rács formájában. Be kell húzni hozzá az ui_table.h modult.

Paraméter Leírás
form->type UI_TABLE
form->flags Esetleg UI_SCROLL vagy UI_NOHEADER
form->ptr Mutató az adatokra
form->tblsel A kiválasztott adatrekord indexe
form->tblnum Adatrekordok száma
form->tblsiz Egy adatrekord mérete bájtokban
form->tblrow Sor mérete pixelekben
form->tblcol Oszlop mérete pixelekben (rács esetén, egyébként 0)
form->data Mutató az ui_form_t fejléclistára
form->cmps Összehasonlító függvények rendezéshez (vagy NULL)
form->m Cellamargó pixelekben

A form->ptr mutat az adatrekordokra, ami táblázat esetén valószínűleg egy struktúrákat tartalmazó tömb. A form->data listának legalább egy UI mezőt kell tartalmaznia, és MINDIG egy UI_END mezővel kell lezárni. Ez tárolja a hdr fejléceket, valamint megadja az adott oszlop megjelenítését. Táblázathoz a form->tblcol értékét 0-ára kell állítani, és ilyenkor valószínűleg a form->data több fejlécet fog tartalmazni. Rács esetén a form->tblcol nem nulla és ilyenkor egységesen minden cellához az első form->data fejléc használatos.

Paraméter Leírás
hdr->type A cella megjelenítésének típusa
hdr->tblhdr Fejléc cím, lokalizált sztringtömb index
hdr->tblofs A mező adatrekordon belüli címe (csak táblázat esetén)
hdr->flags UI_POINTER, ha az oszlop mezője egy mutató
hdr->w Oszlop szélessége, használható UI_PERCENT

A rendezés engedélyezéséhez kétszer annyi komparátor funkciót kell megadni, mint ahány fejlécmező van. Oszloponként az első a növekvő, a második a csökkenő sorrendért felel.

1
typedef int (*ui_comp)(const void *a, const void *b);

A prototípusuk a szabványos POSIX komparátoré, a libc qsort() gyorsrendezés függvényének adódnak át paraméterül.



Cimkék

Cimke

ui_label.png

Kirajzol egy szöveg cimkét. Ha a form->label 0, akkor a form->ptr egy nullával lezárt UTF-8 sztringre kell mutasson.

Paraméter Leírás
form->type UI_LABEL
form->label Lokalizált sztringtömb indexe (vagy 0)
form->ptr Csak ha label 0, mutató egy sztringre

Státusz

ui_label.png

Kirajzol egy szöveg cimkét. Ugyanaz, mint az UI_LABEL, csak form->label helyett annak a mezőnek a form->desc értékét használja, ami fölött az egér tartózkodik. Ha ez 0, akkor a form->ptr egy nullával lezárt UTF-8 sztringre kell mutasson.

Paraméter Leírás
form->type UI_STATUS
form->ptr Csak ha hover->desc 0, mutató egy sztringre
hover->desc Lokalizált sztringtömb indexe (vagy 0)

Decimális

ui_dec.png

Kirajzol egy értéket tízes számrendszerben. A szám a define végén jelzi, hogy hány biten tárolódik az érték.

Paraméter Leírás
form->type UI_DEC8 / UI_DEC16 / UI_DEC32 / UI_DEC64
form->ptr Mutató az értékre

Hexadecimális

ui_hex.png

Kirajzol egy értéket tizenhatos számrendszerben. A szám a define végén jelzi, hogy hány biten tárolódik az érték.

Paraméter Leírás
form->type UI_HEX8 / UI_HEX16 / UI_HEX32 / UI_HEX64
form->ptr Mutató az értékre

Folyamatjelző

ui_pbar.png

Kirajzol egy 64 bites egész számot folyamatjelzőként.

Paraméter Leírás
form->type UI_PBAR
form->ptr Mutató egy int64 értékre
form->max Teljes érték

Lebegőpontos

ui_dec_float.png

Kirajzol egy lebegőpontos értéket.

Paraméter Leírás
form->type UI_DEC_FLOAT
form->ptr Mutató az értékre

Kép

ui_image.png

Kirajzol egy ikont képpel. Ha a form->ptr nem NULL, akkor kattintható és úgy viselkedik, mint egy gomb.

Paraméter Leírás
form->type UI_IMAGE
form->icon Mutató egy ui_image_t struct-ra
form->ptr Mutató az int értékre (vagy NULL)
form->value A cimke int értéke

Az ui_image_t képstruktúra pedig a következő:

Mező Leírás
w Szélesség pixelekben
h Magasság pixelekben
p Rasztersor bájtokban (legalább w * 4)
buf Pixelbuffer 32 bites RGBA színkódokkal


Bevitel

Szöveg

ui_text.png

Kirajzol egy szövegbeviteli mezőt. A bufferben egy nullával lezárt UTF-8 sztringnek kell lennie. Alapból bármilyen nem vezérlőkaraktert elfogad, de ez tovább szűkíthető: UI_FILTER_ID (egy UNIX azonosító), UI_FILTER_VAR (változónév, mint a UNIX azonosító, csak nem kezdődhet számmal), UI_FILTER_EXPR (kifejezés, mint a változó plusz zárójelek és operátorok), és UI_FILTER_HEX (csak a hexadecimálishoz szükséges 0-9A-F gombokat engedi). Az UI_FILTER_PASS nem a bementet, hanem a kimenetet szűri, csillagokat jelenít meg. Beillesztés is működik. Ha az ui_textosk.h modul be van húzva, akkor bevitelkor megjelenít szoftveresen egy billentyűzetet a képernyőn, egyébként az OS-specifikus OSK csak akkor jelenik meg, ha a platform támogatja azt.

Paraméter Leírás
form->type UI_TEXT
form->ptr Mutató a bufferre
form->max A buffer mérete
form->inc 0 bármi, vagy valamelyik UI_FILTER_x filter

Választódoboz

ui_select.png

Kirajzol egy választódobozt. Ha rákattintanak, akkor az opciók egy felugróban jelennek meg.

Paraméter Leírás
form->type UI_SELECT
form->ptr Mutató az int értékre
form->optc Maximum érték plusz 1, opciók száma
form->optv Mutató egy sztringtömbre, opciók
form->m Jobb margó

Opciólista

ui_option.png

Kirajzol egy opciólistát. Pont, mint a választódoboz, csak számbekérő megjelenéssel, nincs felugró.

Paraméter Leírás
form->type UI_OPTION
form->ptr Mutató az int értékre
form->optc Maximum érték plusz 1, opciók száma
form->optv Mutató egy sztringtömbre, opciók
form->m Bal és jobb margó

Lebegőpont

ui_float.png

Kirajzol egy lebegőpontos számbeviteli mezőt.

Paraméter Leírás
form->type UI_FLOAT
form->ptr Mutató az értékre
form->fmin Minimum érték
form->fmax Maximum érték
form->finc Léptetési érték
form->m Bal és jobb margó

Egészszám

ui_int.png

Kirajzol egy egészszámbeviteli mezőt. A szám a define végén jelzi, hogy hány biten tárolódik az érték.

Paraméter Leírás
form->type UI_INT8 / UI_INT16 / UI_INT32 / UI_INT64
form->ptr Mutató az értékre
form->min Minimum érték
form->max Maximum érték
form->inc Léptetési érték
form->m Bal és jobb margó

Csúszka

ui_slider.png

Kirajzol egy egészszámbeviteli mezőt csúszkaként (csak 32 bit).

Paraméter Leírás
form->type UI_SLIDER
form->ptr Mutató az értékre
form->min Minimum érték
form->max Maximum érték
form->inc Léptetési érték

Függőleges szkrollozó

ui_vscrbar.png

Kirajzol egy függőleges szkroll mezőt (csak 32 bit). A tárolók maguktól kezelik a szkrollozást, szóval ez bármi más esetre.

Paraméter Leírás
form->type UI_VSCRBAR
form->ptr Mutató az int értékre
form->max Maximum érték

Vízszintes szkrollozó

ui_hscrbar.png

Kirajzol egy vízszintes szkroll mezőt (csak 32 bit).

Paraméter Leírás
form->type UI_HSCRBAR
form->ptr Mutató az int értékre
form->max Maximum érték

Szín

ui_color.png

Kirajzol egy egészszámbeviteli mezőt színként (csak 32 bit). Ha rákattintanak, akkor egy színválasztó ugrik fel.

Paraméter Leírás
form->type UI_COLOR
form->ptr Mutató az int értékre

Fájl

ui_file.png

Kirajzol egy szövegbeviteli mezőt. A bufferben egy nullával lezárt UTF-8 sztringnek kell lennie az elérési úttal. Ha a felhasználó rákattint, akkor egy elérési út választót hoz elő, amivel a sztring egyszerűen szerkeszthető. Az str paraméter leírását lásd ott. Be kell húzni hozzá az ui_file.h modult.

Paraméter Leírás
form->type UI_FILE
form->ptr Mutató a bufferre az elérési úttal
form->max A buffer mérete
form->min Az elérési út választó minimális magassága
form->str Lokalizált sztringtömb indexe (vagy 0)

Elérési út

ui_path.png

Kirajzol egy elérési út választót. Az str a lokalizált sztring tömbben egy 8 sztringből álló csoport első indexe, ezek rendre: fájl neve, mérete, módosítási dátuma, most, N perce, egy órája, N órája, tegnap. Be kell húzni hozzá az ui_file.h modult.

Paraméter Leírás
form->type UI_PATH
form->ptr Mutató a bufferre az elérési úttal
form->max A buffer mérete
form->str Lokalizált sztringtömb indexe (vagy 0)
form->data Mutató az ui_path_t kontextusra

Az ui_path_t struktúra pedig a következő:

Mező Leírás
flags Elérési út jelzőbitek
exts Kiterjesztéslista (vagy NULL)
select Kiválasztás rendben (vagy NULL)

A jelzőbitek:

Define Leírás
UI_PATH_SEARCH Keresőmezőt is tartalmazzon
UI_PATH_NEWDIR Új könyvtár létrehozása gomb is legyen
UI_PATH_ONLYDIR Csak könyvtárakat listázzon
UI_PATH_HIDDEN Listázza a rejtett fájlokat is

A kiterjesztéslista egy nullával lezárt sztringeket tartalmazó lista, amit két nulla karakter zár, például png\0jpg\0\0. Ha meg van adva, akkor a lista csak az itt felsorolt kiterjesztésű fájlokat fogja tartalmazni.

Ha a select visszahívás NULL, akkor egyszerűen az alkönyvtárakba belép, a fájlokat meg visszaadja. Ha meg van adva

1
typedef int (*ui_form_select)(char *path, int isdir);

formában, akkor az 1-el tér vissza, ha az elérési út kiválasztható, egyébként 0-ával. Ha 0-val tért vissza, akkor az alkönyvtárakba belép, a fájlokkal pedig semmit sem csinál. A path paraméter könyvtárelválasztóra végződik, ha az egy könyvtár, és ilyenkor az isdir értéke 1. Ez arra használható, hogy további kritériát szabjunk a kiválasztandó elérési útnak, például könyvtárak esetében hogy tartalmaz-e egy bizonyos fájlt, vagy fájlok esetében hogy adott mágikus bájttal kezdődik-e vagy sem. A megadott visszahívás bármilyen plusz ellenőrzést implementálhat.



Gombok

Kapcsoló

ui_toggle.png

Ez egy speciális mező, amit egy tároló mezőnek kell követnie, és annak a tároló mezőnek a láthatóságát kapcsolja. Ha a következő mező mégsem tároló lenne, akkor a form->value egy index az ui_event()-nek átadott űrlap elemeire. Ha a form->label 0, akkor a form->ptr egy nullával lezárt UTF-8 sztringre kell mutasson, ami cimkeként jelenik meg. Alapból ez elé a cimke elé kerül egy jobbra vagy lefelé nyíl, hacsak nincs UI_NOBULLET megadva, ekkor ugyanis nincs nyíl, helyette a cimke más színnel jelenik meg (lásd színtéma, ez a menüelemekhez kell).

Paraméter Leírás
form->type UI_TOGGLE
form->flags Esetleg UI_NOBULLET
form->label Lokalizált sztringtömb indexe (vagy 0)
form->ptr Csak ha label 0, mutató egy sztringre
form->value Ha nem tároló követi, ui_event() űrlap indexe

Pipa

ui_check.png

Kirajzol egy pipát cimkével. A mutatott érték jelzi, hogy be van-e pipálva. Ha rákattintanak, akkor a value int érték XOR-olódik a megadott címen lévő értékkel.

Paraméter Leírás
form->type UI_CHECK
form->flags Esetleg UI_NOBULLET
form->ptr Mutató az int értékre
form->value A gomb bitmaszkja
form->label Lokalizált sztringtömb indexe

Választó

ui_radio.png

Kirajzol egy választót cimkével. A mutatott érték jelzi, hogy ez-e az aktív. Ha rákattintanak, akkor a value int érték kerül a megadott címre.

Paraméter Leírás
form->type UI_RADIO
form->flags Esetleg UI_NOBULLET
form->ptr Mutató az int értékre
form->value A gomb int értéke
form->label Lokalizált sztringtömb indexe

Gomb

ui_button.png

Kirajzol egy gombot. A mutatott érték jelzi, hogy be van-e nyomva. Ha rákattintanak, akkor a value int érték kerül a megadott címre. Lehet ikonja is, cimkéje is, vagy akár mindkettő. Ha bőrrel van rajzolva, akkor ott lehet árnyék, ami függőlegesen eltolja a cimkét. Ha ez előfordulna, akkor az m margóval igazítható (lehet negatív is).

Paraméter Leírás
form->type UI_BUTTON
form->flags Esetleg UI_NOBORDER
form->ptr Mutató az int értékre
form->value A gomb int értéke
form->label Lokalizált sztringtömb indexe
form->icon Mutató egy ui_image_t struct-ra
form->m Felső margó, ha bőrözött

Gombkapcsoló

ui_button.png

Kirajzol egy gombot, ami kapcsolóként viselkedik. Ha rákattintanak, akkor a mutatott tároló mező láthatóságát kapcsolja. Ha a ptr értéke NULL, akkor a form->value egy index az ui_event()-nek átadott űrlap elemeire.

Paraméter Leírás
form->type UI_BTNTGL
form->flags Esetleg UI_NOBORDER
form->ptr Mutató egy ui_form_t tároló mezőre
form->value Ha a ptr NULL, ui_event() űrlap indexe
form->label Lokalizált sztringtömb indexe
form->icon Mutató egy ui_image_t struct-ra
form->m Felső margó, ha bőrözött

Ikongomb

ui_image.png

Kirajzol egy ikont, ha be van pipálva, egyébként semmit. Ha rákattintanak, akkor a value int érték XOR-olódik a megadott címen lévő értékkel. Pontosan úgy működik, mint a pipa.

Paraméter Leírás
form->type UI_BTNICN
form->ptr Mutató az int értékre
form->value A gomb bitmaszkja
form->icon Mutató egy ui_image_t struct-ra


Vonalak

Vonal

ui_lines.png

Egy sor összefüggő vonalat húz. A form->ptr egy int16_t (short int) értékeket tartalmazó tömbre kell mutasson, több x és y párral, és a legutolsó párnak 0,0-nak kell lennie.

Paraméter Leírás
form->type UI_LINES
form->ptr Mutató az int16_t tömbre
form->value 32 bites RGBA szín

Vízszintes összekötés

ui_hconnect.png

Összeköt két pontot vízszintesen egy ívvel. A form->ptr egy pontosan 4 elemű int16_t tömbre kell mutasson, x0 és y0 a kiinduló pont, x1 és y1 pedig a végpont pár.

Paraméter Leírás
form->type UI_HCONNECT
form->ptr Mutató a 4 elemű int16_t tömbre
form->value 32 bites RGBA szín

Függőleges összekötés

ui_vconnect.png

Összeköt két pontot függőlegesen egy ívvel. A form->ptr egy pontosan 4 elemű int16_t tömbre kell mutasson, x0 és y0 a kiinduló pont, x1 és y1 pedig a végpont pár.

Paraméter Leírás
form->type UI_VCONNECT
form->ptr Mutató a 4 elemű int16_t tömbre
form->value 32 bites RGBA szín

Bezier ív

ui_curve.png

Tetszőleges Bezier ív kirajzolása. A form->ptr egy pontosan 8 elemű int16_t tömbre kell mutasson, x0 és y0 a kiinduló pont, x1 és y1 a végpont, cx0 és cy0 az első kontrollpont, cx1 és cy1 pedig a második kontrollpont koordináta párja.

Paraméter Leírás
form->type UI_CURVE
form->ptr Mutató a 8 elemű int16_t tömbre
form->value 32 bites RGBA szín


Egyedi

Felhasználó által kreált egyedi mezők is használhatók, ehhez mindössze típusonként 4 visszacsatolásra van szükség.

Paraméter Leírás
form->type UI_CUSTOM
form->flags Figyelembe kell venni a UI_HIDDEN-t és UI_DISABLED-t
form->ptr Mutató tetszőleges adat bufferre
form->data Mutató tetszőleges adat kontextusra
form->str Lokalizált sztringtömb indexe (vagy 0)
form->bbox Méretfunkció
form->view Kirajzolófunkció
form->ctrl Eseménykezelőfunkció
form->fini Opcionális felszabadításfunkció

Méretezés

1
2
typedef int (*ui_bbox)(ui_t *ctx, int x, int y, int w, int h, ui_form_t *form, int *dw, int *dh);

Ez a funkció a számolt területet kapja x, y, w, h változókban, ahol a mezőnek meg kell jelennie, az űrlapelemet pedig a form-ban, majd vissza kell adnia a tényleges szélességet a dw és a tényleges magasságot a dh változókban.

Megjelenítés

1
2
typedef int (*ui_view)(ui_t *ctx, int x, int y, int w, int h, ui_form_t *form);

Ez a funkció a tényleges területet kapja x, y, w, h változókban, ahová a mezőt ki kell rajzolni, az űrlapelemet pedig a form-ban. Használhatja az alacsonyszintű _ui_line(), _ui_cbez(), _ui_rect(), _ui_blit() stb. hívásokat, vagy direktben változtathatja a pixeleket a ctx->screen képben. Nagyon fontos, hogy nem módosíthat a megadott területen hívül.

Kontroller

1
2
typedef int (*ui_ctrl)(ui_t *ctx, int x, int y, int w, int h, ui_form_t *form, ui_event_t *evt);

Ez a funkció a tényleges területet kapja x, y, w, h változókban, ahol a mező található, az űrlapelemet a form-ban, az aktuális eseményt pedig az evt-ben az eseménykezeléshez. Ez csak akkor hívódik, ha a form nem UI_HIDDEN (rejtett) és nem is UI_DISABLED (inaktív), és az egér épp fölötte tartózkodik.

Destruktor

1
typedef int (*ui_fini)(ui_t *ctx, ui_form_t *form);

Erre az opcionális visszacsatolásra csak akkor van szükség, ha az egyedi mező memóriát allokált. Többször is meghívódhat, ezért fontos úgy megírni, hogy csak egyszer szabadítsa fel a buffer(eke)t.



Példa

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#define UI_IMPLEMENTATION #include <ui.h> int main(int argc, char **argv) { /* lokalizált sztringek tömbje */ enum { WINDOW_TITLE, POPUP_TITLE, BUTTON_TITLE, EASY_TITLE, HARD_TITLE, VOLUME_TITLE }; char *lang[] = { "Basic demo", "Show", "Button", "easy", "hard", "Volume:" }; /* állapotok tárolására használt változók */ int button = 0, difficulty = 0, volume = 25; /* ezekre hivatkozó űrlap, HTML-folyam szerű elrendezéssel */ ui_t ctx; ui_form_t popup[] = { { .type = UI_BUTTON, .flags = UI_FORCEBR, .ptr = &button, .value = 1, .label = BUTTON_TITLE }, { .type = UI_RADIO, .flags = UI_NOBR, .ptr = &difficulty, .value = 0, .y = 5, .label = EASY_TITLE }, { .type = UI_RADIO, .flags = UI_FORCEBR, .ptr = &difficulty, .value = 1, .x = 20, .label = HARD_TITLE }, { .type = UI_LABEL, .flags = UI_NOBR, .y = 5, .label = VOLUME_TITLE }, { .type = UI_SLIDER, .ptr = &volume, .max = 100 }, { .type = UI_END } }; ui_form_t form[] = { { .type = UI_POPUP, .align = UI_CENTER | UI_MIDDLE, .ptr = &popup, .x = UI_PERCENT(50), .y = UI_PERCENT(50), .m = 10, .label = POPUP_TITLE }, { .type = UI_END } }; /* UI kontextus inicializálása */ ui_init(&ctx, sizeof(lang)/sizeof(lang[0]), lang, 640, 480, NULL); /* várunk, amíg a felhasználó be nem zárja az ablakot */ while(ui_event(&ctx, form)) { /* gomb lekezelése, ez akár másik szálban is lehetne */ if(button) { printf("button clicked\n"); button = 0; ui_refresh(&ctx); } } /* ablak bezárása, erőforrások felszabadítása */ ui_free(&ctx); return 0; }

example.png



Finomhangolás

Alap

Az SMGUI alaprendszere hangolható néhány define-al az ui.h behúzása előtt.

UI_IMPLEMENTATION

FIGYELEM

Ezt mindig a modulok behúzása után szabad csak definiálni.

Akkor kell megadni, ha nemcsak a prototípusokra, de az implementációra is szükség van.

UI_NOAA

Anti-alias nélküli vonalat rajzol (kiiktatja a math.h és libm függőséget).

UI_MAXEVENTS

A várakozó események maximális száma. Ha nincs megadva, alapértelmezetten 16.

UI_MAXPOPUPS

A látható felugrók maximális száma. Ha nincs megadva, alapértelmezetten 16.

UI_BACKEND_INITIALIZED

Ha a kódból már meg lett hívva a glfwInit() / glfwTerminate(), SDL_Init() / SDL_Quit() stb., akkor használatos. Erre akkor van szükség, ha az SMGUI-val több ablakot is akarunk kezelni egyszerre.

UI_BACKEND_NOFLUSH

Ha nem akarod, hogy az ui_event() érvényesítse a képet, hanem kódból magad hívod a glfwSwapBuffers() / SDL_RenderPresent() / stb. függvényeket. Erre akkor van szükség, ha az UI réteg fölé még rajzolni szeretnénk.

GLFW3

Függetlenül a GLFW3 motor is finomhangolható define-okkal, a ui_glfw.h behúzása előtt.

Alapból ez a motor OpenGL 3.3 core profile-os shaderekkel fordul, és egyaránt támogatja a glad és glew bővítménybetöltést.

UI_GLFW_NOSHADER

A régi OpenGL API használata. Ez mindenhol működik és nem kell neki bővítménybetöltő se shader. A hátránya, hogy néhány videokártya meghajtóban bugos a visszafele kompatibilitás, emiatt nem lehet már saját shadert se használni, ha ez az opció engedélyezve lett.

UI_GLFW_GLES2

Használjon shadereket, de csak OpenGL ES 2.0-t (mobil platform verzió). Csak régi mobilok támogatásához, a mai modern eszközök általában gond nélkül kezelik az OpenGL 3.3 core-t.

UI_GLFW_CUSTOMHOOKS

Akkor használatos, ha magunk akarjuk a GLFW3 visszacsatolásokat megadni. Ekkor a visszacsatolásokból meg kell hívni a motor visszacsatolásait is. Például:

1
2
3
4
5
6
7
8
9
10
11
/* visszacsatolás megadása a szokásos módon */ glfwSetMouseButtonCallback(ui_getwindow(ctx), my_glfw_mouse); /* a visszacsatolásod */ void my_glfw_mouse(GLFWwindow *window, int button, int action, int mods) { /* tetszőlegesen értelmezhető */ /* ... */ /* a végén meg kell hívni az ui_glfw visszacsatolását is */ ui_glfw_mouse(window, button, action, mods); }


SMGUI Licensz

A megengedő MIT licensz szerint kerül terjesztésre.

A szabad felhasználás jogát ezennel ráruházom bármely személyre
aki jelen mű és dokumentációjának egy példányát (a továbbiakban
“Szoftver”) megszerezte, hogy a szoftvert korlátozás nélkül -
beleértve a használat, másolás, módosítás, kiadás, terjesztés,
és/vagy értékesítés jogát - felhasználhassa, és a továbbadott
példánnyal hasonlóan járhasson el, amennyiben a következő feltételek
teljesülnek:

A fenti szerzői jogot és felhasználási jogot biztosító szöveget
fel kell tüntetni a Szoftver minden teljes és rész másolataiban is.

A SZOFTVER “ÚGY, AHOGY VAN” KERÜL TERJESZTÉSE, MINDENNEMŰ JÓTÁLLÁS
NÉLKÜL, KÖZVETVE VAGY KÖZVETETTEN, BELEÉRTVE A KERESKEDELMI JÓTÁLLÁS
VAGY EGY ADOTT CÉLRA TÖRTÉNŐ FELHASZNÁLÁSRA ALKALMASSÁGOT. A SZERZŐI
JOG TULAJDONOSA SEMMILYEN KÖRÜLMÉNYEK KÖZÖTT NEM TEHETŐ FELELŐSSÉ
BÁRMILYEN MÓDON, BELEÉRVE A SZOFTVER RENDELTETÉSSZERŰ HASZNÁLATA
SORÁN, VAGY RENDELTETÉSSZERŰ HASZNÁLATTÓL ELTÉRŐ FELHASZNÁLÁS
SORÁN A SZOFTVER ÁLTAL ESETLEGESEN OKOZOTT KÁROKÉRT.