When to use _cbCallback and when _cbDialog?
STM32F746G-Discovery
-
-
HI,
Of course, _cbCallback and _cbDialog are just names and you can choose them freely.
But, the callback set for a dialog receives a WM_INIT_DIALOG message after all its dialog elements are created. This gives you the chance to configure the different elements.
A callback function set for a single window gets a WM_CREATE message giving you the chance of reacting to it and creating further child windows or set up some data.
You can react to WM_CREATE only if the pointer to the callback function is a prameter of the create function like "cb" of the following function:
CWM_HWIN WM_CreateWindowAsChild(int x0, int y0, int width, int height, WM_HWIN hParent, U32 Style, WM_CALLBACK * cb, int NumExtraBytes);
With a widget it is not possible to pass a callback to its create function. Therefore we have added a message to react on setting a callback. Since emWin version 5.46 a callback gets send a WM_SET_CALLBACK message when calling WM_SetCallback().Regards,
Sven -
Thank you!
How do you flip the button 90 and the text on it?
-
Hi,
you could overwrite the button callback function or set a custom skinning function. When it comes to drawing the button text you can display the string rotated with the function GUI_DispStringInRectEx().
C
Display More#include "DIALOG.h" /********************************************************************* * * Static code * ********************************************************************** */ /********************************************************************* * * _ButtonSkin */ static int _ButtonSkin(const WIDGET_ITEM_DRAW_INFO * pInfo) { char acBuffer[32]; GUI_RECT Rect; switch (pInfo->Cmd) { case WIDGET_ITEM_DRAW_BACKGROUND: if (BUTTON_IsPressed(pInfo->hWin)) { GUI_SetBkColor(GUI_GREEN); } else { GUI_SetBkColor(GUI_BLUE); } GUI_Clear(); return 0; case WIDGET_ITEM_DRAW_TEXT: BUTTON_GetText(pInfo->hWin, acBuffer, sizeof(acBuffer)); if (BUTTON_IsPressed(pInfo->hWin)) { GUI_SetColor(GUI_BLUE); } else { GUI_SetColor(GUI_GREEN); } WM_GetClientRect(&Rect); GUI_DispStringInRectEx(acBuffer, &Rect, GUI_TA_HCENTER | GUI_TA_VCENTER, sizeof(acBuffer), GUI_ROTATE_CCW); return 0; default: return BUTTON_DrawSkinFlex(pInfo); } } /********************************************************************* * * _cbButtonTrans */ static void _cbButtonTrans(WM_MESSAGE * pMsg) { char acBuffer[32]; GUI_RECT Rect; switch (pMsg->MsgId) { case WM_PAINT: if (BUTTON_IsPressed(pMsg->hWin)) { GUI_SetBkColor(GUI_GREEN); } else { GUI_SetBkColor(GUI_BLUE); } GUI_Clear(); BUTTON_GetText(pMsg->hWin, acBuffer, sizeof(acBuffer)); if (BUTTON_IsPressed(pMsg->hWin)) { GUI_SetColor(GUI_BLUE); } else { GUI_SetColor(GUI_GREEN); } WM_GetClientRect(&Rect); GUI_DispStringInRectEx(acBuffer, &Rect, GUI_TA_HCENTER | GUI_TA_VCENTER, sizeof(acBuffer), GUI_ROTATE_CCW); break; default: BUTTON_Callback(pMsg); break; } } /********************************************************************* * * _cbBk */ static void _cbBk(WM_MESSAGE * pMsg) { WM_HWIN hItem; int Id; int NCode; switch (pMsg->MsgId) { case WM_PAINT: GUI_DrawGradientH(0, 0, LCD_GetXSize() - 1, LCD_GetYSize() - 1, GUI_BLACK, GUI_LIGHTGRAY); break; default: WM_DefaultProc(pMsg); break; } } /********************************************************************* * * Public code * ********************************************************************** */ /********************************************************************* * * MainTask */ void MainTask(void) { WM_HWIN hButton; WM_HWIN hText; GUI_Init(); WM_MULTIBUF_Enable(1); WM_SetCallback(WM_HBKWIN, _cbBk); hButton = BUTTON_CreateEx(20, 20, 20, 80, WM_HBKWIN, WM_CF_SHOW, 0, GUI_ID_BUTTON0); BUTTON_SetText(hButton, "Button"); WM_SetCallback(hButton, _cbButtonTrans); hButton = BUTTON_CreateEx(50, 20, 20, 80, WM_HBKWIN, WM_CF_SHOW, 0, GUI_ID_BUTTON1); BUTTON_SetText(hButton, "Button"); BUTTON_SetSkin(hButton, _ButtonSkin); while (1) { GUI_Delay(100); } } /*************************** End of file ****************************/
It is not possible to simply rotate the default button. The background wouldn't get rotated.Regards,
Sven -
Thank you!
-
What is the difference between _cbButton and cbButton?
-
I want to rotate the inscription on the button. What's wrong here?
#define ID_WINDOW_0 (GUI_ID_USER + 0x00)
#define ID_BUTTON_0 (GUI_ID_USER + 0x01) // START
#define ID_BUTTON_1 (GUI_ID_USER + 0x02) // STOP
#define ID_BUTTON_2 (GUI_ID_USER + 0x03) // UP
#define ID_BUTTON_3 (GUI_ID_USER + 0x04) // DOWNstatic const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = { {
WINDOW_CreateIndirect, "Window", ID_WINDOW_0, 0, 0, 480, 272,
WM_CF_SHOW, 0 }, { BUTTON_CreateIndirect, "START",
ID_BUTTON_0, 30, 20, 40, 232 }, { BUTTON_CreateIndirect, "STOP",
ID_BUTTON_1, 90, 20, 40, 232 }, { BUTTON_CreateIndirect, "UP",
ID_BUTTON_2, 150, 20, 40, 232 }, { BUTTON_CreateIndirect, "DOWN",
ID_BUTTON_3, 210, 20, 40, 232 } };static void _cbCallback(WM_MESSAGE * pMsg) {
WM_HWIN hWin;
WM_HWIN hItem;int NCode;
int Id;hItem = pMsg->hWin;
switch (pMsg->MsgId) {
case WM_INIT_DIALOG:
WINDOW_SetBkColor(hItem, GUI_BLUE);hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_0);
BUTTON_SetFont(hItem, GUI_FONT_24B_ASCII);
BUTTON_SetText(hItem, "START");
BUTTON_SetTextColor(hItem, BUTTON_CI_PRESSED, GUI_RED);
GUI_DispStringInRectEx("START", hItem, GUI_TA_HCENTER | GUI_TA_VCENTER,
6, GUI_ROTATE_CCW);hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_1);
BUTTON_SetFont(hItem, GUI_FONT_24B_ASCII);
BUTTON_SetText(hItem, "STOP");hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_2);
BUTTON_SetFont(hItem, GUI_FONT_24B_ASCII);
BUTTON_SetText(hItem, "UP");hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_3);
BUTTON_SetFont(hItem, GUI_FONT_24B_ASCII);
BUTTON_SetText(hItem, "DOWN");break;
default:
WM_DefaultProc(pMsg);
break;
}
}WM_HWIN CreateWindow(void) {
WM_HWIN hWin;hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate),
_cbCallback, WM_HBKWIN, 0, 0);
return hWin;
}void MainTask(void) {
CreateWindow();
}
-
Hi,
What is the difference between _cbButton and cbButton?
_cbButtonTrans() is a callback function gets called by emWin if something happens related to the button this callback is set to. This allows you to react different events like touch, or WM_PAINT.
_ButtonSkin() is callback dedicated for drawing. This gets called by the default callback function of a button and allows you to draw the single parts of a button like background and text.
I want to rotate the inscription on the button. What's wrong here?
You have to set either a custom skin or a custom callback for the buttons. Otherwise you can not change the drawing.You can not simply call a drawing function within WM_INIT_DIALOG. Draw functions should be called only within a WM_PAINT event.
C
Display More#include "DIALOG.h" #define ID_WINDOW_0 (GUI_ID_USER + 0x00) #define ID_BUTTON_0 (GUI_ID_USER + 0x01) // START #define ID_BUTTON_1 (GUI_ID_USER + 0x02) // STOP #define ID_BUTTON_2 (GUI_ID_USER + 0x03) // UP #define ID_BUTTON_3 (GUI_ID_USER + 0x04) // DOWN static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = { { WINDOW_CreateIndirect, "Window", ID_WINDOW_0, 0, 0, 480, 272, WM_CF_SHOW, 0 }, { BUTTON_CreateIndirect, "START", ID_BUTTON_0, 30, 20, 40, 232 }, { BUTTON_CreateIndirect, "STOP", ID_BUTTON_1, 90, 20, 40, 232 }, { BUTTON_CreateIndirect, "UP", ID_BUTTON_2, 150, 20, 40, 232 }, { BUTTON_CreateIndirect, "DOWN", ID_BUTTON_3, 210, 20, 40, 232 } }; /********************************************************************* * * _ButtonSkin */ static int _ButtonSkin(const WIDGET_ITEM_DRAW_INFO * pInfo) { char acBuffer[32]; GUI_RECT Rect; const GUI_FONT * pFont; GUI_COLOR Color; switch (pInfo->Cmd) { case WIDGET_ITEM_DRAW_TEXT: BUTTON_GetText(pInfo->hWin, acBuffer, sizeof(acBuffer)); WM_GetClientRect(&Rect); pFont = BUTTON_GetFont(pInfo->hWin); GUI_SetFont(pFont); GUI_SetTextMode(GUI_TM_TRANS); if (BUTTON_IsPressed(pInfo->hWin)) { Color = BUTTON_GetTextColor(pInfo->hWin, BUTTON_CI_PRESSED); } else { Color = BUTTON_GetTextColor(pInfo->hWin, BUTTON_CI_UNPRESSED); } GUI_SetColor(Color); GUI_DispStringInRectEx(acBuffer, &Rect, GUI_TA_HCENTER | GUI_TA_VCENTER, sizeof(acBuffer), GUI_ROTATE_CCW); return 0; default: return BUTTON_DrawSkinFlex(pInfo); } } /********************************************************************* * * _cbCallback */ static void _cbCallback(WM_MESSAGE * pMsg) { WM_HWIN hWin; WM_HWIN hItem; int NCode; int Id; hItem = pMsg->hWin; switch (pMsg->MsgId) { case WM_INIT_DIALOG: WINDOW_SetBkColor(hItem, GUI_BLUE); hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_0); BUTTON_SetFont(hItem, GUI_FONT_24B_ASCII); BUTTON_SetText(hItem, "START"); BUTTON_SetTextColor(hItem, BUTTON_CI_PRESSED, GUI_RED); BUTTON_SetSkin(hItem, _ButtonSkin); hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_1); BUTTON_SetFont(hItem, GUI_FONT_24B_ASCII); BUTTON_SetText(hItem, "STOP"); BUTTON_SetSkin(hItem, _ButtonSkin); hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_2); BUTTON_SetFont(hItem, GUI_FONT_24B_ASCII); BUTTON_SetText(hItem, "UP"); BUTTON_SetSkin(hItem, _ButtonSkin); hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_3); BUTTON_SetFont(hItem, GUI_FONT_24B_ASCII); BUTTON_SetText(hItem, "DOWN"); BUTTON_SetSkin(hItem, _ButtonSkin); break; default: WM_DefaultProc(pMsg); break; } } /********************************************************************* * * CreateWindow */ WM_HWIN CreateWindow(void) { WM_HWIN hWin; hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbCallback, WM_HBKWIN, 0, 0); return hWin; } /********************************************************************* * * _cbBk */ static void _cbBk(WM_MESSAGE * pMsg) { switch (pMsg->MsgId) { case WM_PAINT: GUI_SetBkColor(GUI_BLACK); GUI_Clear(); break; default: WM_DefaultProc(pMsg); break; } } void MainTask(void) { GUI_Init(); WM_MULTIBUF_Enable(1); WM_SetCallback(WM_HBKWIN, _cbBk); CreateWindow(); while (1) { GUI_Delay(100); } }
Regards,
Sven -
Thank you.
-
Can you convert WIDGET EDIT and SPINBOX in a similar way?
-
Hi Andrzej,
I'm not sure what you mean by converting, but if you mean custom drawing a widget then yes, you're able to custom draw all widgets.
This is done by executing the drawing operations in a WM_PAINT case in a callback function. This function will be set to a widget using WM_SetCallback().
Here's a small sample demonstrating how to do this:
C
Display More#include "DIALOG.h" /********************************************************************* * * Static code * ********************************************************************** */ /********************************************************************* * * _cbButton */ static void _cbButton(WM_MESSAGE * pMsg) { GUI_RECT Rect; switch (pMsg->MsgId) { case WM_PAINT: // // Execute drawing operations in WM_PAINT. This is how the button looks. // GUI_SetColor(GUI_GRAY_9A); // // Save dimensions of this window (button) for drawing. // WM_GetClientRect(&Rect); // // Draw something. // GUI_FillRoundedRect(Rect.x0, Rect.y0, Rect.x1, Rect.y1, 3); GUI_SetColor(GUI_BLACK); GUI_SetTextMode(GUI_TM_TRANS); GUI_AA_DrawRoundedRectEx(&Rect, 3); GUI_DispStringInRect("Button", &Rect, GUI_TA_HCENTER | GUI_TA_VCENTER); break; default: WM_DefaultProc(pMsg); break; } } /********************************************************************* * * Public code * ********************************************************************** */ /********************************************************************* * * MainTask */ void MainTask(void) { WM_HWIN hButton; GUI_Init(); WM_SetDesktopColor(GUI_WHITE); // // Create button widget // hButton = BUTTON_CreateEx(20, 20, 120, 40, WM_HBKWIN, WM_CF_SHOW, 0, GUI_ID_BUTTON0); // // Set callback routine to the button // WM_SetCallback(hButton, _cbButton); while (1) { GUI_Delay(100); } } /*************************** End of file ****************************/
Best regards,
Florian
-
Thanks for the clarification. All the time I mean WIDGET with vertical descriptions.
-
Hi
I want to put NUMBER on position x = 250, y = 40. I have the following code. Why can't I do that? How to declare GUI_RECT?
static void _cbCallback(WM_MESSAGE * pMsg) {
WM_HWIN hWin;
WM_HWIN hItem;
int NCode;
int Id;
GUI_RECT Rect = {10, 10, 40, 80};hItem = pMsg->hWin;
switch (pMsg->MsgId) {
case WM_INIT_DIALOG:WINDOW_SetBkColor(hItem, GUI_BLUE);
hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_0);
BUTTON_SetFont(hItem, GUI_FONT_24B_ASCII);
BUTTON_SetText(hItem, "START");
BUTTON_SetSkin(hItem, _ButtonSkin);hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_1);
BUTTON_SetFont(hItem, GUI_FONT_24B_ASCII);
BUTTON_SetText(hItem, "STOP");
BUTTON_SetSkin(hItem, _ButtonSkin);hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_2);
BUTTON_SetFont(hItem, GUI_FONT_24B_ASCII);
BUTTON_SetText(hItem, "UP");
BUTTON_SetTextColor(hItem, BUTTON_CI_PRESSED, GUI_RED);
BUTTON_SetSkin(hItem, _ButtonSkin);hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_3);
BUTTON_SetFont(hItem, GUI_FONT_24B_ASCII);
BUTTON_SetText(hItem, "DOWN");
BUTTON_SetTextColor(hItem, BUTTON_CI_PRESSED, GUI_RED);
BUTTON_SetSkin(hItem, _ButtonSkin);break;
case WM_PAINT:
GUI_DispStringInRectEx("NUMBER", &Rect,
GUI_TA_HCENTER | GUI_TA_VCENTER, 10, GUI_ROTATE_CCW);break;
default:
WM_DefaultProc(pMsg);
break;
}
}/*********************************************************************
*
* CreateWindow
*/
WM_HWIN CreateWindow(void) {
WM_HWIN hWin;hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate),
_cbCallback, WM_HBKWIN, 0, 0);
return hWin;
}void MainTask(void) {
GUI_Init();
WM_MULTIBUF_Enable(1);
CreateWindow();
while (1) {
GUI_Delay(100);
}
} -
-
What does this mean + 40?
-
Hi,
It's the end position in x direction of the rectangle (x0 + 40).
Regards,
Sven -
OK. But I had to set pixel x 2 to get what I wanted: GUI_RECT Rect1 = {0, 0, 640, 120};
I have one more problem. I want to rotate 90 degrees SPINBOX. Can it be done by skinning?
-
Hi Andrzej,
no, rotating widgets is not possible. What you might want to do instead is changing the display orientation instead of rotating each item individually.
You can do this by changing the display driver in the file LCDConf.c. Your hardware uses the Lin driver and you can find a list of available orientation settings in the manual under "33.7.6 GUIDRV_Lin".
Setting the display driver to GUIDRV_LIN_OSX_32 should achieve what you need, if your color depth is 32bpp.
Best regards,
Florian
-
In which file should I put it?
-
Hi Florian
I am using STM32CubeMX. Maybe the axes can be changed there? For now, the proposal with adding the LCDConf.c file reports errors.
Best regards
-
Participate now!
Don’t have an account yet? Register yourself now and be a part of our community!