1
+ /*
2
+ emWinDemo
3
+
4
+ created 04 Dec 2023
5
+ by Leonardo Cavagnis
6
+ */
7
+
8
+ #include " DIALOG.h" /* emWin library includes Arduino_H7_Video and Arduino_GigaDisplayTouch library */
9
+
10
+ /*
11
+ * Main window handler: It creates 4 window childs.
12
+ * Source: https://wiki.segger.com/WM_child_windows_(Sample)
13
+ */
14
+ static void _cbWin (WM_MESSAGE * pMsg) {
15
+ switch (pMsg->MsgId ) {
16
+ case WM_CREATE:
17
+ /* [0, 0] - Image */
18
+ WM_CreateWindowAsChild (20 , 20 , 370 , 210 , pMsg->hWin , WM_CF_SHOW, _cbChildWinImg, 0 );
19
+
20
+ /* [1, 0] - Slider */
21
+ WM_CreateWindowAsChild (20 , 210 +20 *2 , 370 , 210 , pMsg->hWin , WM_CF_SHOW, _cbChildWinSlider, 0 );
22
+
23
+ /* [0, 1] - Checkbox, button and labels */
24
+ WM_CreateWindowAsChild (370 +20 *2 , 20 , 370 , 210 , pMsg->hWin , WM_CF_SHOW, _cbChildWinChkBtn, 0 );
25
+
26
+ /* [1, 1] - Progress bar */
27
+ WM_CreateWindowAsChild (370 +20 *2 , 210 +20 *2 , 370 , 210 , pMsg->hWin , WM_CF_SHOW, _cbChildWinPgrBar, 0 );
28
+ break ;
29
+ case WM_PAINT:
30
+ GUI_SetBkColor (0x03989e ); /* Background color set to: R(0x03),G(0x98),B(0x9E) */
31
+ GUI_Clear ();
32
+ break ;
33
+ default :
34
+ WM_DefaultProc (pMsg);
35
+ break ;
36
+ }
37
+ }
38
+
39
+ /*
40
+ * Image window handler
41
+ * To convert image use "Bitmap Converter for emWin"
42
+ * https://www.segger.com/products/user-interface/emwin/tools/tools-overview/
43
+ */
44
+ extern GUI_CONST_STORAGE GUI_BITMAP bmarduinologo; /* Image bitmap structure (see img_arduinologo_emwin.c in attach) */
45
+
46
+ static void _cbChildWinImg (WM_MESSAGE * pMsg) {
47
+ switch (pMsg->MsgId ) {
48
+ case WM_CREATE:
49
+ break ;
50
+ case WM_PAINT:
51
+ GUI_SetBkColor (GUI_WHITE);
52
+ GUI_Clear ();
53
+ /* Draw image */
54
+ GUI_DrawBitmap (&bmarduinologo, 85 , 35 );
55
+ break ;
56
+ default :
57
+ WM_DefaultProc (pMsg);
58
+ break ;
59
+ }
60
+ }
61
+
62
+ /*
63
+ * Slider window handler
64
+ * Source: https://wiki.segger.com/SLIDER_-_Usage_(Sample)
65
+ */
66
+ static void _cbChildWinSlider (WM_MESSAGE * pMsg) {
67
+ static WM_HWIN hSlider;
68
+ int NCode, Id;
69
+ int Value;
70
+ char acBuffer[32 ];
71
+
72
+ switch (pMsg->MsgId ) {
73
+ case WM_CREATE:
74
+ /* Create horizonzal slider */
75
+ hSlider = SLIDER_CreateEx (110 , 90 , 150 , 30 , pMsg->hWin , WM_CF_SHOW, SLIDER_CF_HORIZONTAL, GUI_ID_SLIDER0);
76
+ /* Set range of slider */
77
+ SLIDER_SetRange (hSlider, 0 , 100 );
78
+ /* Set number of tick marks */
79
+ SLIDER_SetNumTicks (hSlider, 10 );
80
+ /* Set value of slider */
81
+ SLIDER_SetValue (hSlider, 20 );
82
+ /* Set width of thumb */
83
+ SLIDER_SetWidth (hSlider, 20 );
84
+ break ;
85
+ case WM_PAINT:
86
+ GUI_SetBkColor (GUI_WHITE);
87
+ GUI_Clear ();
88
+ GUI_SetFont (&GUI_Font13B_1);
89
+ GUI_SetColor (GUI_BLACK);
90
+
91
+ /* Display slider value */
92
+ Value = SLIDER_GetValue (hSlider);
93
+ sprintf (acBuffer, " Value: %d" , Value);
94
+ GUI_DispStringAt (acBuffer, 110 , 120 );
95
+ break ;
96
+ case WM_NOTIFY_PARENT:
97
+ Id = WM_GetId (pMsg->hWinSrc );
98
+ NCode = pMsg->Data .v ;
99
+
100
+ switch (Id) {
101
+ case GUI_ID_SLIDER0:
102
+ switch (NCode) {
103
+ case WM_NOTIFICATION_VALUE_CHANGED:
104
+ /* Redraw the window when a value has changed so the displayed value will be updated */
105
+ WM_InvalidateWindow (pMsg->hWin );
106
+ break ;
107
+ }
108
+ break ;
109
+ }
110
+ break ;
111
+ default :
112
+ WM_DefaultProc (pMsg);
113
+ }
114
+ }
115
+
116
+ /*
117
+ * Checkbox&Button window handler
118
+ * Source:
119
+ * https://wiki.segger.com/CHECKBOX_-_Usage_(Sample)
120
+ * https://wiki.segger.com/BUTTON_-_Usage_(Sample)
121
+ */
122
+ #define ID_BUTTON 1
123
+
124
+ static void _cbChildWinChkBtn (WM_MESSAGE * pMsg) {
125
+ static WM_HWIN hBox;
126
+ BUTTON_Handle hButton;
127
+ int NCode, Id;
128
+ char acBuffer[32 ];
129
+ int State;
130
+ static int Clicked, Released;
131
+
132
+ switch (pMsg->MsgId ) {
133
+ case WM_CREATE:
134
+ /* Create CHECKBOX widget */
135
+ hBox = CHECKBOX_CreateEx (10 , 30 , 80 , 20 , pMsg->hWin , WM_CF_SHOW, 0 , GUI_ID_CHECK0);
136
+ /* Edit widget properties */
137
+ CHECKBOX_SetText (hBox, " Check" );
138
+ CHECKBOX_SetTextColor (hBox, GUI_BLACK);
139
+ CHECKBOX_SetFont (hBox, &GUI_Font16_1);
140
+ /* Set number of possible states to 3 (if needed). The minimum number of states is 2 and the maximum is 3 */
141
+ CHECKBOX_SetNumStates (hBox, 3 );
142
+ /* Manually set the state */
143
+ CHECKBOX_SetState (hBox, 1 );
144
+
145
+ /* Create a button */
146
+ hButton = BUTTON_CreateEx (10 , 100 , 80 , 20 , pMsg->hWin , WM_CF_SHOW, 0 , ID_BUTTON);
147
+ BUTTON_SetText (hButton, " Click me" );
148
+ break ;
149
+ case WM_PAINT:
150
+ GUI_SetBkColor (GUI_WHITE);
151
+ GUI_Clear ();
152
+ GUI_SetFont (&GUI_Font16_1);
153
+ GUI_SetColor (GUI_BLACK);
154
+
155
+ /* Display current CHECKBOX state */
156
+ State = CHECKBOX_GetState (hBox);
157
+ sprintf (acBuffer, " State of checkbox: %d" , State);
158
+ GUI_DispStringAt (acBuffer, 10 , 60 );
159
+
160
+ /* Check button state and print info on labels */
161
+ if (Clicked) {
162
+ sprintf (acBuffer, " Button was clicked at: %d." , Clicked);
163
+ GUI_DispStringAt (acBuffer, 10 , 130 );
164
+ }
165
+ if (Released) {
166
+ sprintf (acBuffer, " Button was released at: %d." , Released);
167
+ GUI_DispStringAt (acBuffer, 10 , 150 );
168
+ }
169
+ break ;
170
+ case WM_NOTIFY_PARENT:
171
+ /* Get Id of sender window and notification code */
172
+ Id = WM_GetId (pMsg->hWinSrc );
173
+ NCode = pMsg->Data .v ;
174
+
175
+ switch (Id) {
176
+ case GUI_ID_CHECK0:
177
+ switch (NCode) {
178
+ case WM_NOTIFICATION_VALUE_CHANGED:
179
+ /* When the value of the checkbox changed, redraw parent window to update the display of the state */
180
+ WM_InvalidateWindow (pMsg->hWin );
181
+ break ;
182
+ }
183
+ break ;
184
+ case ID_BUTTON:
185
+ switch (NCode) {
186
+ case WM_NOTIFICATION_CLICKED:
187
+ Clicked = GUI_GetTime ();
188
+ WM_InvalidateWindow (pMsg->hWin );
189
+ break ;
190
+ case WM_NOTIFICATION_RELEASED:
191
+ Released = GUI_GetTime ();
192
+ WM_InvalidateWindow (pMsg->hWin );
193
+ break ;
194
+ }
195
+ break ;
196
+ break ;
197
+ }
198
+ break ;
199
+ default :
200
+ WM_DefaultProc (pMsg);
201
+ }
202
+ }
203
+
204
+ /*
205
+ * Progress bar window handler
206
+ * Source: https://wiki.segger.com/PROGBAR_-_Custom_(Sample)
207
+ */
208
+ PROGBAR_Handle hProg;
209
+
210
+ static void _cbChildWinPgrBar (WM_MESSAGE * pMsg) {
211
+ GUI_RECT Rect ;
212
+ float ValueF;
213
+ int Value;
214
+ char acBuffer[16 ];
215
+
216
+ switch (pMsg->MsgId ) {
217
+ case WM_CREATE:
218
+ hProg = PROGBAR_CreateEx (85 , 90 , 200 , 30 , pMsg->hWin , WM_CF_SHOW, PROGBAR_CF_HORIZONTAL, GUI_ID_PROGBAR0);
219
+ WM_SetCallback (hProg, _cbProgbar);
220
+ break ;
221
+ case WM_PAINT:
222
+ GUI_SetBkColor (GUI_WHITE);
223
+ GUI_Clear ();
224
+ break ;
225
+ default :
226
+ WM_DefaultProc (pMsg);
227
+ break ;
228
+ }
229
+ }
230
+
231
+ /*
232
+ * Progress bar widget handler
233
+ * Source: https://wiki.segger.com/PROGBAR_-_Custom_(Sample)
234
+ */
235
+ static void _cbProgbar (WM_MESSAGE * pMsg) {
236
+ GUI_RECT Rect ;
237
+ float ValueF;
238
+ int Value;
239
+ char acBuffer[16 ];
240
+
241
+ switch (pMsg->MsgId ) {
242
+ case WM_PAINT:
243
+ GUI_SetBkColor (GUI_WHITE);
244
+ GUI_Clear ();
245
+ /* Draw progress bar */
246
+ WM_GetClientRect (&Rect );
247
+ GUI_SetColor (GUI_BLACK);
248
+ GUI_AA_DrawRoundedRectEx (&Rect , 3 );
249
+ Value = PROGBAR_GetValue (pMsg->hWin );
250
+ ValueF = Value / 100 .0F ;
251
+ sprintf (acBuffer, " Progress: %d%%" , Value);
252
+ Rect .x0 += 2 ;
253
+ Rect .y0 += 2 ;
254
+ Rect .x1 -= 2 ;
255
+ Rect .y1 -= 2 ;
256
+ Rect .x1 = Rect .x1 * (ValueF);
257
+ GUI_SetColor (GUI_GRAY_9A);
258
+ GUI_AA_FillRoundedRectEx (&Rect , 1 );
259
+ WM_GetClientRect (&Rect );
260
+ Rect .x0 += 2 ;
261
+ Rect .y0 += 2 ;
262
+ Rect .x1 -= 2 ;
263
+ Rect .y1 -= 2 ;
264
+ GUI_SetColor (GUI_BLACK);
265
+ GUI_SetTextMode (GUI_TM_TRANS);
266
+ GUI_SetFont (&GUI_Font16B_1);
267
+ GUI_DispStringInRect (acBuffer, &Rect , GUI_TA_HCENTER | GUI_TA_VCENTER);
268
+ break ;
269
+ default :
270
+ PROGBAR_Callback (pMsg);
271
+ break ;
272
+ }
273
+ }
274
+
275
+ int progbarCnt = 0 ;
276
+ unsigned long previousMillis = 0 ;
277
+
278
+ void setup () {
279
+ /* Init SEGGER emWin library. It also init display and touch controller */
280
+ GUI_Init ();
281
+
282
+ LCD_ROTATE_SetSel (1 ); /* Set landscape mode */
283
+ WM_MULTIBUF_Enable (1 ); /* Enable multi buffering mode for Windows manager */
284
+
285
+ /* Create the main window. It will include all the sub-windows */
286
+ WM_CreateWindowAsChild (0 , 0 , LCD_GetXSize (), LCD_GetYSize (), WM_HBKWIN, WM_CF_SHOW, _cbWin, 0 );
287
+ }
288
+
289
+ void loop () {
290
+ /* Update progress bar value */
291
+ if (millis () - previousMillis >= 100 ) {
292
+ previousMillis = millis ();
293
+ progbarCnt++;
294
+ if (progbarCnt > 100 ) {
295
+ progbarCnt = 0 ;
296
+ }
297
+ PROGBAR_SetValue (hProg, progbarCnt);
298
+ WM_InvalidateWindow (hProg); /* Make sure the entire PROGBAR gets redrawn */
299
+ }
300
+
301
+ /* Keep emWin alive, handle touch and other stuff */
302
+ GUI_Exec ();
303
+ }
0 commit comments