BasicC/BasicGEM
GEM jest małą biblioteką obsługi podstawowych elementów graficznego interfejsu użytkownika jak przyciski, okna dialogowe, pola edycyjne, selektor plików. Nazwa jest skrótem od Graphics Entry Manager i nawiązuje do systemu operacyjnego GEM firmy Digital Research stosowanego m.in. w komputerach Atari ST.
Podstawowymi elementami GEM są przyciski i pola edycji, które z poziomu programisty są tymi samymi obiektami, opisanymi w zmiennej strukturalnej typu GEMBOX. GEM nie tworzy oddzielnych okien, "okna" wiadomości, czy wybierania pliku wyświetlane są w podstawowym oknie SDLWindow. Selektor plików tworzony jest w obrazie GEMScreen typu SDL_Texture, który następnie jest wyświetlany. Przy korzystaniu z GEM zalecane jest używanie GEMScreen jako targetu.
Definicje w BasicGEM.h wraz z wartościami domyślnymi:
- FILES_MAX 1000 - maksymalna ilość plików w katalogu wyświetlana w selektorze plików
- ALERTW 320, ALERTH 200 - szerokość i wysokość okna komunikatów
- GEMMOUSEBUTTONUP 0 - czy GEMMenu obsługuje zdarzenia puszczenia przycisków myszy: 0 - nie, 1 - tak
- CFACE 0xafcfaf - kolor powierzchni (tła) obiektów GEM
- CUPPER 0xcfffcf - kolor jasny/górnej krawędzi
- CLOWER 0x7faf7f - kolor ciemny/dolnej krawędzi
- CTEXT 0x000000 - kolor tekstu
- CTEXTBG 0xafffaf - kolor tła tekstu
- CCURSOR 0xff0000 - kolor kursora tekstowego
- CDIS 0x8fbf8f - kolor tekstu nieaktywnego przycisku
- tablica GEMColor typu union BASSDLColor zawierająca wartości 16 kolorów, domyślnie odpowiadają one podstawowym kolorom Atari ST, a wartość alfa wynosi 127 (pół-przeźroczyste).
- obraz GEMScreen typu SDL_Texture* będący wirtualnym ekranem stosowanym w GEM
- struktura GEMBOX opisująca obiekty GEM
Tworzenie menu GEM polega na zadeklarowaniu obiektów typu GEMBOX, podanie ich współrzędnych, typów i właściwości, następnie sprawdzaniu i obsługiwaniu zdarzeń z nimi związanych. Można w tym celu napisać własną procedurę lub używać komendy GEMMenu. Do BasicC dołączony jest przykładowy program graficzny NIKIFOR wykorzystujący GEM.
Struktura GEMBOX zawiera następujące pola:
- Text - tekst wyświetlany w danym obiekcie, typ char*
- State - liczba typu Uint8, zawierająca informacje o stanie i właściwościach obiektu, ustawienie kolejnych bitów na 1 oznacza:
0 (odpowiada wartości 1): obiekt aktywny, obsługiwany przez GEM 1 (2): widoczny, brak widoczności oznacza również brak aktywności (pomijanie przez funkcje GEM) 2 (4): wybrany 3 (8): odznaczany (bit 2 ustawiany na 0) przy kolejnym wywołaniu GEMMenu 4 (16): radiowy - może być wybrany tylko jeden z tej grupy 5 (32): XOR - kliknięcie w obiekt powoduje wybranie/odznaczenie
- Type - liczba Uint8 oznaczająca typ obiektu: 0 - pusty blok, 1 - przycisk tekstowy, 2 - przycisk obrazkowy, 10 - puste pole tekstowe, 11 - linia tekstu, 12 - pole z tekstem wieloliniowym, 13 - lista tekstowa
- x,y,w,h - współrzędne i wymiary obiektu, typ int
- n,s - liczby typu int, znaczenie zależne od typu obiektu lub do innego wykorzystania
- P - wskaźnik na obraz typu SDL_Texture*, który może być wyświetlany w obiekcie
Obiekty typu GEMBOX deklarujemy poprzez: struct GEMBOX nazwa;
można zadeklarować tablicę obiektów: struct GEMBOX nazwa_tablicy[ilość];
Przykład Informatyczne Pianino z przycisków GEM:
#include "BasicGEM.h"
MAIN
int w,o;
struct GEMBOX b[48];
STRING txt[21]={" "};
SDLOpen(0)
For(w,0,20)
GEMBox(b[w],1,txt[w],5+w*30,10,30,200) b[w].State+=16;b[w].n=RGBA(222,222,222,255);
GEMBox(b[w+21],0,0,25+w*30,10,20,100) b[w+21].State+=16;b[w+21].n=RGBA(66,66,66,155);
txt[w][0]=((w+2) MOD 7)+65;
Next
b[23].State=0;b[27].State=0;b[30].State=0;b[34].State=0;b[37].State=0;b[41].State=0;
GEMBox(b[42],1,"SIN",5,300,99,20) b[42].State+=8;
GEMBox(b[43],1,"ROUND",100,300,99,20) b[43].State+=8;
GEMBox(b[44],1,"TOOTH",200,300,99,20) b[44].State+=8;
GEMBox(b[45],1,"TRIANG",300,300,99,20) b[45].State+=8;
GEMBox(b[46],1,"SQUARE",400,300,99,20) b[46].State+=8;
GEMBox(b[47],1,"NOISE",500,300,99,20) b[47].State+=8;
Do
Target(GEMScreen)
Color(CFACE)
Cls
GEMBoxesDraw(b,sizeof b/sizeof b[0])
GEMShow
GEMMenu(b,sizeof b/sizeof b[0],0,w)
Print$ "Wcisnieto przycisk nr" _ w );
if(w==42)Wave(0,sin,0.1,.5)
if(w==43)Wave(0,WavRound,0.1,1)
if(w==44)Wave(0,WavTooth,.5,1)
if(w==45)Wave(0,WavTriang,.5,.5)
if(w==46)Wave(0,WavSqr,0.2,0.2)
if(w==47)Wave(0,WavNoise,0.1,1)
o=1<<w/7;
w=w MOD 7;
Print$ "Segment:" _ o $ "Dzwiek:" _ w NL
If(o<5)
if(w<3)Sound(0,(128+w*16)*o,1,1)
else Sound(0,(168+(w-3)*24)*o,1,1)
Else
o>>=3;
if(w<3)Sound(0,(136+w*16)*o,1,1)
else Sound(0,(180+(w-3)*24)*o,1,1)
EndIf
Loop
SDLQuit
ENDMAIN