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