Skip to content

Commit ff3334d

Browse files
authored
Merge pull request #788 from leonardocavagnis/h7_video_emwin_example
Arduino_H7_Video: Adding SEGGER emWin example
2 parents fcc63d9 + e15288a commit ff3334d

File tree

4 files changed

+2312
-0
lines changed

4 files changed

+2312
-0
lines changed

.github/workflows/compile-examples.yml

+2
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ jobs:
7171
- name: ArduinoBLE
7272
- name: ArduinoGraphics
7373
- name: Arduino_GigaDisplayTouch
74+
- name: emWin
7475
additional-sketch-paths: |
7576
- libraries/PDM
7677
- libraries/doom
@@ -142,6 +143,7 @@ jobs:
142143
- name: ArduinoGraphics
143144
- name: Arduino_GigaDisplayTouch
144145
- name: arducam_dvp
146+
- name: emWin
145147
additional-sketch-paths: |
146148
- libraries/PDM
147149
- libraries/MCUboot

libraries/Arduino_H7_Video/docs/README.md

+12
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,18 @@ void loop() { }
4646
- **[ArduinoLogo](../examples/ArduinoLogo):** This example demonstrates how to display an Arduino logo image on the screen.
4747
- **[ArduinoLogoDrawing](../examples/ArduinoLogoDrawing):** This example demonstrates how to draw an Arduino logo image using graphics primitives (line, circle, rect, etc.).
4848
- **[LVGLDemo](../examples/LVGLDemo):** This example demonstrates how to create a graphical user interface (GUI) using the LVGL library. It includes the [Arduino_GigaDisplayTouch](https://github.com/arduino-libraries/Arduino_GigaDisplayTouch/) library to handle touch events.
49+
- **[emWinDemo](../examples/emWinDemo):** This example demonstrates how to create a graphical user interface (GUI) using the SEGGER emWin library. It includes the [emWin-Arduino-Library](https://github.com/SEGGERMicro/emWin-Arduino-Library) library.
50+
51+
## Guides
52+
53+
To learn more about usage of this library, you can check out the following guides:
54+
- [GIGA Display Shield LVGL Guide](https://docs.arduino.cc/tutorials/giga-display-shield/lvgl-guide).
55+
- [GIGA Display Shield Image Orientation Guide](https://docs.arduino.cc/tutorials/giga-display-shield/image-orientation)
56+
- [GIGA Display Shield Image Draw Guide](https://docs.arduino.cc/tutorials/giga-display-shield/basic-draw-and-image)
57+
58+
59+
You can also check out the following guide available in the Segger Wiki:
60+
- using the SEGGER emWin library on the GIGA Display Shield, check out the [SEGGER emWin on Arduino Wiki](https://wiki.segger.com/emWin_on_Arduino).
4961
5062
## API
5163
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,303 @@
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

Comments
 (0)