... | ... |
@@ -1,138 +1,114 @@ |
1 | 1 |
/* |
2 | 2 |
* boxui_demo_helloworld.c |
3 | 3 |
* |
4 |
- * Box-UI small example with best practices. |
|
4 |
+ * box-ui small example with best practices. |
|
5 | 5 |
* |
6 |
- * (c) 2023 Dario Rodriguez <antartica@whereismybit.com> |
|
6 |
+ * (c) 2024 Dario Rodriguez <antartica@whereismybit.com> |
|
7 | 7 |
* This program is licensed under the terms of the MIT/X license. |
8 | 8 |
*/ |
9 | 9 |
|
10 |
-#ifdef EMSCRIPTEN |
|
11 |
-#include <emscripten.h> |
|
12 |
-#endif |
|
10 |
+ |
|
13 | 11 |
#include <stdio.h> |
14 | 12 |
#include <stdlib.h> |
15 | 13 |
#include <unistd.h> |
16 | 14 |
#include <string.h> |
17 |
-#include <time.h> |
|
18 | 15 |
#include <signal.h> |
16 |
+ |
|
17 |
+#define SDL_MAIN_USE_CALLBACKS 1 |
|
18 |
+#include <SDL3/SDL.h> |
|
19 |
+#include <SDL3/SDL_main.h> |
|
20 |
+ |
|
19 | 21 |
#include "boxui.h" |
20 | 22 |
|
21 |
-#define DEFAULT_SCREENW 640 |
|
22 |
-#define DEFAULT_SCREENH 480 |
|
23 |
+#define DEFAULT_SCREENW 800 |
|
24 |
+#define DEFAULT_SCREENH 600 |
|
23 | 25 |
|
24 | 26 |
typedef struct mydata_t { |
25 |
- int flag_exit; |
|
27 |
+ SDL_Window *window; |
|
28 |
+ SDL_Renderer *renderer; |
|
26 | 29 |
boxui_t *boxui; |
27 | 30 |
} mydata_t; |
28 | 31 |
|
29 |
-volatile int flag_sigint; |
|
30 |
-static void sigint(int n); |
|
31 |
-static int install_signal(int n,void (*f)(int)); |
|
32 |
- |
|
33 |
-mydata_t *mydata_init(void); |
|
34 |
-void mydata_free(mydata_t *mydata); |
|
35 |
-int main_loop_iteration(mydata_t *mydata); |
|
36 |
- |
|
37 |
-int |
|
38 |
-main(int argc, char *argv[]) |
|
39 |
-{ |
|
40 |
- mydata_t *mydata; |
|
41 |
- if((mydata=mydata_init())==NULL) { |
|
42 |
- DEBUG_FPRINTF((stderr,"Couldn't init\n")); |
|
43 |
- return(-1); /* couldn't init */ |
|
44 |
- } |
|
45 |
- flag_sigint=0; |
|
46 |
- install_signal(SIGINT,sigint); |
|
47 |
- while(flag_sigint==0 && mydata->flag_exit==0 && mydata->boxui!=NULL) { |
|
48 |
-#ifdef EMSCRIPTEN |
|
49 |
- emscripten_set_main_loop_arg((void (*)(void *))main_loop_iteration,(void *) mydata,boxui_getfps(mydata->boxui),1); |
|
50 |
-#else |
|
51 |
- main_loop_iteration(mydata); |
|
52 |
-#endif |
|
53 |
- } |
|
54 |
- mydata_free(mydata),mydata=NULL; |
|
55 |
- return(0); |
|
56 |
-} |
|
57 |
- |
|
58 |
-static int |
|
59 |
-install_signal(int n,void (*f)(int)) |
|
60 |
-{ |
|
61 |
-#ifndef LINUX |
|
62 |
- return(-1); |
|
63 |
-#else |
|
64 |
- struct sigaction sact; |
|
65 |
- sact.sa_handler=f; |
|
66 |
- sigemptyset(&sact.sa_mask); |
|
67 |
- sact.sa_flags=0; |
|
68 |
- return(sigaction(n,&sact,0)); |
|
69 |
-#endif |
|
70 |
-} |
|
71 |
- |
|
72 |
-static void |
|
73 |
-sigint(int n) |
|
74 |
-{ |
|
75 |
- flag_sigint++; |
|
76 |
-} |
|
77 |
- |
|
78 |
-mydata_t * |
|
79 |
-mydata_init(void) |
|
32 |
+SDL_AppResult |
|
33 |
+SDL_AppInit(void **appstate, int argc, char *argv[]) |
|
80 | 34 |
{ |
81 | 35 |
boxui_t *boxui; |
82 |
- mydata_t *mydata; |
|
36 |
+ static mydata_t realmydata,*mydata; |
|
83 | 37 |
char *p; |
84 |
- if((mydata=malloc(sizeof(mydata_t)))==NULL) |
|
85 |
- return(NULL); |
|
86 |
- memset(mydata,0,sizeof(mydata_t)); |
|
87 |
- if((mydata->boxui=boxui=boxui_init("boxui demo helloworld",DEFAULT_SCREENW,DEFAULT_SCREENH,0))==NULL |
|
88 |
- || boxui_setuserptr(boxui,mydata)!=0) { |
|
89 |
- mydata_free(mydata),mydata=NULL; |
|
90 |
- return(NULL); |
|
38 |
+ char *strerror; |
|
39 |
+ |
|
40 |
+ memset(&realmydata,0,sizeof(realmydata)); |
|
41 |
+ mydata=&realmydata; |
|
42 |
+ SDL_SetAppMetadata("Boxui demo simplified", "1.0", "org.box-ui.com.example.camera-read-and-draw"); |
|
43 |
+ if((strerror="SDL_init")==NULL |
|
44 |
+ || !SDL_Init(SDL_INIT_VIDEO) |
|
45 |
+ || (strerror="SDL_CreateWindowAndRenderer")==NULL |
|
46 |
+ || !SDL_CreateWindowAndRenderer("boxui demo helloworld",DEFAULT_SCREENW,DEFAULT_SCREENH,0,&mydata->window,&mydata->renderer) |
|
47 |
+ || (strerror="boxui")==NULL |
|
48 |
+ || (boxui=mydata->boxui=boxui_init(mydata->window,mydata->renderer,DEFAULT_SCREENW,DEFAULT_SCREENH))==NULL |
|
49 |
+ || (strerror="boxui_add")==NULL |
|
50 |
+ || (p=boxui_add(boxui,_F,_L,"label:.label","-text \"Hello World!\" -click labelclicked"))==NULL |
|
51 |
+ || (strerror="boxui_pack")==NULL |
|
52 |
+ || boxui_pack(boxui,_F,_L,p,"-side top -fill both -expand true -anchor center")!=0) { |
|
53 |
+ SDL_Log("ERROR: Couldn't init UI: %s failed\n",strerror); |
|
54 |
+ return SDL_APP_FAILURE; |
|
91 | 55 |
} |
92 |
- /* initial UI config */ |
|
93 |
- p=boxui_add(boxui,_F,_L,"label:.l","-text \"Hello World!\" -click changetext"); |
|
94 |
- boxui_pack(boxui,_F,_L,p,"-side top -fill both -expand true"); |
|
95 |
- return(mydata); |
|
56 |
+ boxui_setuserptr(boxui,mydata); |
|
57 |
+ boxui_setsignal(boxui,SIGINT,"sigint"); |
|
58 |
+ *appstate=(void *)mydata; |
|
59 |
+ return SDL_APP_CONTINUE; |
|
96 | 60 |
} |
97 | 61 |
|
98 |
-void |
|
99 |
-mydata_free(mydata_t *mydata) |
|
62 |
+/* NOTE: SDL_AppEvent may get called concurrently with SDL_AppEvent() for events not pushed on the main thread. */ |
|
63 |
+SDL_AppResult |
|
64 |
+SDL_AppEvent(void *appstate, SDL_Event *event) |
|
100 | 65 |
{ |
101 |
- boxui_t *boxui; |
|
102 |
- if(mydata==NULL) |
|
103 |
- return; |
|
104 |
- if((boxui=mydata->boxui)!=NULL) { |
|
105 |
- boxui_setuserptr(boxui,NULL); |
|
106 |
- boxui_free(boxui),boxui=NULL,mydata->boxui=NULL; |
|
66 |
+ mydata_t *mydata=(mydata_t *)appstate; |
|
67 |
+ if(event->type==SDL_EVENT_QUIT) { |
|
68 |
+ return SDL_APP_SUCCESS; /* exit program with code 0 (ok) */ |
|
69 |
+ } else if(event->type==SDL_EVENT_WINDOW_RESIZED) { |
|
70 |
+ boxui_resize(mydata->boxui,event->window.data1,event->window.data1); |
|
71 |
+ } else if(event->type==SDL_EVENT_KEY_DOWN && event->key.key==SDLK_ESCAPE) { |
|
72 |
+ return SDL_APP_SUCCESS; /* ESC key pressed, exit program with code 0 (ok) */ |
|
73 |
+ } else { |
|
74 |
+ boxui_event(mydata->boxui,event); |
|
107 | 75 |
} |
108 |
- free(mydata),mydata=NULL; |
|
109 |
- return; |
|
76 |
+ return SDL_APP_CONTINUE; /* don't exit program */ |
|
110 | 77 |
} |
111 | 78 |
|
112 |
-int |
|
113 |
-main_loop_iteration(mydata_t *mydata) |
|
79 |
+SDL_AppResult |
|
80 |
+SDL_AppIterate(void *appstate) |
|
114 | 81 |
{ |
82 |
+ mydata_t *mydata=(mydata_t *)appstate; |
|
115 | 83 |
boxui_t *boxui; |
116 |
- SDL_Event event; |
|
117 |
- int keycode,neww,newh; |
|
118 |
- char *actionstr,*actionparams; |
|
84 |
+ char *action,*actiondata; |
|
119 | 85 |
if(mydata==NULL || (boxui=mydata->boxui)==NULL) |
120 |
- return(-1); |
|
121 |
- boxui_tick(boxui); |
|
122 |
- boxui_refreshevents(boxui); |
|
123 |
- while(boxui_getevent(boxui,&event)==0) { |
|
124 |
- /* standard events */ |
|
125 |
- if(boxui_event_isquit(boxui,&event)) |
|
126 |
- mydata->flag_exit=1; |
|
127 |
- if(boxui_event_iskeydown(boxui,&event,&keycode) && keycode==SDLK_ESCAPE) |
|
128 |
- mydata->flag_exit=1; |
|
129 |
- if(boxui_event_isresize(boxui,&event,&neww,&newh)) |
|
130 |
- boxui_resize(boxui,neww,newh); |
|
86 |
+ return SDL_APP_FAILURE; /* internal error, exit loop */ |
|
87 |
+ /* actions */ |
|
88 |
+ while((action=boxui_getaction(boxui,&actiondata))!=NULL) { |
|
89 |
+ if(strcmp(action,"sigint")==0) { |
|
90 |
+ return SDL_APP_SUCCESS; /* interrupted by user, exit program with code 0 (ok) */ |
|
91 |
+ } else if(strcmp(action,"labelclicked")==0) { |
|
92 |
+ boxui_config(mydata->boxui,_F,_L,".label","-text \"Hello again!\""); |
|
93 |
+ } |
|
131 | 94 |
} |
132 |
- while((actionstr=boxui_getactionstr(boxui,&actionparams))!=NULL) { |
|
133 |
- if(strcmp(actionstr,"changetext")==0) |
|
134 |
- boxui_config(boxui,_F,_L,".l","-text \"Hello again!\""); |
|
95 |
+ /* rendering */ |
|
96 |
+ boxui_tick(mydata->boxui); |
|
97 |
+ if(boxui_haschanged(mydata->boxui)) { |
|
98 |
+ SDL_Texture *texture; |
|
99 |
+ texture=boxui_gettexture(mydata->boxui); |
|
100 |
+ SDL_SetRenderDrawColor(mydata->renderer, 0x99, 0x99, 0x99, 255); |
|
101 |
+ SDL_RenderClear(mydata->renderer); |
|
102 |
+ SDL_RenderTexture(mydata->renderer, texture, NULL, NULL); |
|
103 |
+ SDL_RenderPresent(mydata->renderer); |
|
135 | 104 |
} |
136 |
- return(0); |
|
105 |
+ return SDL_APP_CONTINUE; /* don't exit program */ |
|
106 |
+} |
|
107 |
+ |
|
108 |
+void SDL_AppQuit(void *appstate, SDL_AppResult result) |
|
109 |
+{ |
|
110 |
+ mydata_t *mydata=(mydata_t *)appstate; |
|
111 |
+ if(mydata!=NULL) |
|
112 |
+ boxui_free(mydata->boxui),mydata->boxui=NULL; |
|
137 | 113 |
} |
138 | 114 |
|
1 | 1 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,141 @@ |
1 |
+/* |
|
2 |
+ * boxui_demo_helloworld.c |
|
3 |
+ * |
|
4 |
+ * Box-UI small example with best practices. |
|
5 |
+ * |
|
6 |
+ * (c) 2023 Dario Rodriguez <antartica@whereismybit.com> |
|
7 |
+ * This program is licensed under the terms of the MIT/X license. |
|
8 |
+ */ |
|
9 |
+ |
|
10 |
+#ifdef EMSCRIPTEN |
|
11 |
+#include <emscripten.h> |
|
12 |
+#endif |
|
13 |
+#include <stdio.h> |
|
14 |
+#include <stdlib.h> |
|
15 |
+#include <unistd.h> |
|
16 |
+#include <string.h> |
|
17 |
+#include <time.h> |
|
18 |
+#include <signal.h> |
|
19 |
+#include "boxui.h" |
|
20 |
+ |
|
21 |
+ |
|
22 |
+ |
|
23 |
+#define FRAMEMS (1000/30) |
|
24 |
+#define DEFAULT_SCREENW 640 |
|
25 |
+#define DEFAULT_SCREENH 480 |
|
26 |
+ |
|
27 |
+typedef struct mydata_t { |
|
28 |
+ int flag_exit; |
|
29 |
+ boxui_t *boxui; |
|
30 |
+} mydata_t; |
|
31 |
+ |
|
32 |
+volatile int flag_sigint; |
|
33 |
+static void sigint(int n); |
|
34 |
+static int install_signal(int n,void (*f)(int)); |
|
35 |
+ |
|
36 |
+mydata_t *mydata_init(void); |
|
37 |
+void mydata_free(mydata_t *mydata); |
|
38 |
+int main_loop_iteration(mydata_t *mydata); |
|
39 |
+ |
|
40 |
+int |
|
41 |
+main(int argc, char *argv[]) |
|
42 |
+{ |
|
43 |
+ mydata_t *mydata; |
|
44 |
+ if((mydata=mydata_init())==NULL) { |
|
45 |
+ DEBUG_FPRINTF((stderr,"Couldn't init\n")); |
|
46 |
+ return(-1); /* couldn't init */ |
|
47 |
+ } |
|
48 |
+ flag_sigint=0; |
|
49 |
+ install_signal(SIGINT,sigint); |
|
50 |
+ while(flag_sigint==0 && mydata->flag_exit==0 && mydata->boxui!=NULL) { |
|
51 |
+#ifdef EMSCRIPTEN |
|
52 |
+ emscripten_set_main_loop_arg((void (*)(void *))main_loop_iteration,(void *) mydata,boxui_getfps(mydata->boxui),1); |
|
53 |
+#else |
|
54 |
+ main_loop_iteration(mydata); |
|
55 |
+#endif |
|
56 |
+ } |
|
57 |
+ mydata_free(mydata),mydata=NULL; |
|
58 |
+ return(0); |
|
59 |
+} |
|
60 |
+ |
|
61 |
+static int |
|
62 |
+install_signal(int n,void (*f)(int)) |
|
63 |
+{ |
|
64 |
+#ifndef LINUX |
|
65 |
+ return(-1); |
|
66 |
+#else |
|
67 |
+ struct sigaction sact; |
|
68 |
+ sact.sa_handler=f; |
|
69 |
+ sigemptyset(&sact.sa_mask); |
|
70 |
+ sact.sa_flags=0; |
|
71 |
+ return(sigaction(n,&sact,0)); |
|
72 |
+#endif |
|
73 |
+} |
|
74 |
+ |
|
75 |
+static void |
|
76 |
+sigint(int n) |
|
77 |
+{ |
|
78 |
+ flag_sigint++; |
|
79 |
+} |
|
80 |
+ |
|
81 |
+mydata_t * |
|
82 |
+mydata_init(void) |
|
83 |
+{ |
|
84 |
+ boxui_t *boxui; |
|
85 |
+ mydata_t *mydata; |
|
86 |
+ char *p; |
|
87 |
+ if((mydata=malloc(sizeof(mydata_t)))==NULL) |
|
88 |
+ return(NULL); |
|
89 |
+ memset(mydata,0,sizeof(mydata_t)); |
|
90 |
+ if((mydata->boxui=boxui=boxui_init("boxui demo helloworld",DEFAULT_SCREENW,DEFAULT_SCREENH,0))==NULL |
|
91 |
+ || boxui_setuserptr(boxui,mydata)!=0) { |
|
92 |
+ mydata_free(mydata),mydata=NULL; |
|
93 |
+ return(NULL); |
|
94 |
+ } |
|
95 |
+ /* initial UI config */ |
|
96 |
+ p=boxui_add(boxui,_F,_L,"label:.l","-text \"Hello World!\" -click changetext"); |
|
97 |
+ boxui_pack(boxui,_F,_L,p,"-side top -fill both -expand true"); |
|
98 |
+ return(mydata); |
|
99 |
+} |
|
100 |
+ |
|
101 |
+void |
|
102 |
+mydata_free(mydata_t *mydata) |
|
103 |
+{ |
|
104 |
+ boxui_t *boxui; |
|
105 |
+ if(mydata==NULL) |
|
106 |
+ return; |
|
107 |
+ if((boxui=mydata->boxui)!=NULL) { |
|
108 |
+ boxui_setuserptr(boxui,NULL); |
|
109 |
+ boxui_free(boxui),boxui=NULL,mydata->boxui=NULL; |
|
110 |
+ } |
|
111 |
+ free(mydata),mydata=NULL; |
|
112 |
+ return; |
|
113 |
+} |
|
114 |
+ |
|
115 |
+int |
|
116 |
+main_loop_iteration(mydata_t *mydata) |
|
117 |
+{ |
|
118 |
+ boxui_t *boxui; |
|
119 |
+ SDL_Event event; |
|
120 |
+ int keycode,neww,newh; |
|
121 |
+ char *actionstr,*actionparams; |
|
122 |
+ if(mydata==NULL || (boxui=mydata->boxui)==NULL) |
|
123 |
+ return(-1); |
|
124 |
+ boxui_tick(boxui); |
|
125 |
+ boxui_refreshevents(boxui); |
|
126 |
+ while(boxui_getevent(boxui,&event)==0) { |
|
127 |
+ /* standard events */ |
|
128 |
+ if(boxui_event_isquit(boxui,&event)) |
|
129 |
+ mydata->flag_exit=1; |
|
130 |
+ if(boxui_event_iskeydown(boxui,&event,&keycode) && keycode==SDLK_ESCAPE) |
|
131 |
+ mydata->flag_exit=1; |
|
132 |
+ if(boxui_event_isresize(boxui,&event,&neww,&newh)) |
|
133 |
+ boxui_resize(boxui,neww,newh); |
|
134 |
+ } |
|
135 |
+ while((actionstr=boxui_getactionstr(boxui,&actionparams))!=NULL) { |
|
136 |
+ if(strcmp(actionstr,"changetext")==0) |
|
137 |
+ boxui_config(boxui,_F,_L,".l","-text \"Hello again!\""); |
|
138 |
+ } |
|
139 |
+ return(0); |
|
140 |
+} |
|
141 |
+ |