Hello to everyone,
I'm working with emWin simulator and trying to implement a simple speedo- (or any other-) meter, just an abstract scale on the background and a needle moving under that scale.
My idea is to use GUIBuilder for creating a window, placing a scale image and placing a needle image vertically upwards using IMAGE widget.
After that I create a memory device as a source device for vertical needle and draw the needle image into this device from array (dta) generated by GUIBuilder.
Next I create a second memory device as a destination for turned needle and set background colors as transparent in both devices.
Next I create a PROGBAR widget under the scale with the same size as a second destination memory device. This PROGBAR is needed just for setting a value and triggering its WM_PAINT message and rotating the needle within the borders of this PROGBAR according to its value using memory devices instead of showing a real PROGBAR.
My problems are:
- memory devices have no transparency (the dest device with the black background);
- artifacts (old needle position) when rotating the needle.
Can anyone help with my problem.
Thanks for your time.
LCD size in simulation is 1024x768.
NUM_BUFFERS is 3.
My simple code:
Main.c:
Display All
Some code in WindowMeterDLG.c (attached):
Display All
I'm working with emWin simulator and trying to implement a simple speedo- (or any other-) meter, just an abstract scale on the background and a needle moving under that scale.
My idea is to use GUIBuilder for creating a window, placing a scale image and placing a needle image vertically upwards using IMAGE widget.
After that I create a memory device as a source device for vertical needle and draw the needle image into this device from array (dta) generated by GUIBuilder.
Next I create a second memory device as a destination for turned needle and set background colors as transparent in both devices.
Next I create a PROGBAR widget under the scale with the same size as a second destination memory device. This PROGBAR is needed just for setting a value and triggering its WM_PAINT message and rotating the needle within the borders of this PROGBAR according to its value using memory devices instead of showing a real PROGBAR.
My problems are:
- memory devices have no transparency (the dest device with the black background);
- artifacts (old needle position) when rotating the needle.
Can anyone help with my problem.
Thanks for your time.
LCD size in simulation is 1024x768.
NUM_BUFFERS is 3.
My simple code:
Main.c:
C Source Code: Main.c
- #include "GUI.h"
- #include "DIALOG.h"
- #include "IMAGE_Private.h"
- #define RECOMMENDED_MEMORY (1024L * 5)
- WM_HWIN CreateWindowMeter(void);
- void MainTask(void) {
- GUI_Init();
- WM_MULTIBUF_Enable(1);
- //
- // Check if recommended memory for the sample is available
- //
- if (GUI_ALLOC_GetNumFreeBytes() < RECOMMENDED_MEMORY) {
- GUI_ErrorOut("Not enough memory available.");
- return;
- }
- CreateWindowMeter();
- while(1)
- {
- GUI_Delay(50);
- }
- }
Some code in WindowMeterDLG.c (attached):
C Source Code: WindowMeterDLG.c
- ...
- GUI_MEMDEV_Handle hMemArrowSrc, hMemArrowDst;
- PROGBAR_Handle hProgbar;
- GUI_RECT pRect1, pRect2;
- int Val, dVal;
- WM_HTIMER hTimer;
- ...
- static void _cbProgbar(WM_MESSAGE * pMsg) {
- GUI_RECT pRect;
- int Val;
- switch (pMsg->MsgId) {
- case WM_PAINT:
- // get the relative coordinates of the PROGBAR area
- WM_GetClientRect(&pRect);
- // get the PROGBAR value
- Val = PROGBAR_GetValue(pMsg->hWin);
- // select the dest device
- GUI_MEMDEV_Select(hMemArrowDst);
- // clear it with transparency
- GUI_SetBkColor(GUI_TRANSPARENT);
- GUI_Clear();
- // rotate the source device and save the result in dest device
- GUI_MEMDEV_Rotate(hMemArrowSrc, hMemArrowDst, pRect1.y1 + 1 - pRect1.x1 - 1, 0, (90 - Val * 180 / 100) * 1000, 1000);
- // select lcd
- GUI_MEMDEV_Select(0);
- // get the absolute coordinates of the PROGBAR area
- WM_GetWindowRect(&pRect);
- // show the rotated needle
- GUI_MEMDEV_WriteAt(hMemArrowDst, pRect.x0, pRect.y0);
- break;
- default:
- PROGBAR_Callback(pMsg);
- break;
- }
- }
- static void _cbDialog(WM_MESSAGE * pMsg) {
- const void * pData;
- WM_HWIN hItem;
- U32 FileSize;
- // USER START (Optionally insert additional variables)
- int val;
- // USER END
- switch (pMsg->MsgId) {
- case WM_INIT_DIALOG:
- //
- // Initialization of 'WindowMeter'
- //
- hItem = pMsg->hWin;
- WINDOW_SetBkColor(hItem, GUI_MAKE_COLOR(0x00472D16));
- //
- // Initialization of 'ImageMeterBckgnd'
- //
- hItem = WM_GetDialogItem(pMsg->hWin, ID_IMAGE_0);
- pData = _GetImageById(ID_IMAGE_0_IMAGE_0, &FileSize);
- IMAGE_SetDTA(hItem, pData, FileSize);
- //
- // Initialization of 'Image'
- //
- hItem = WM_GetDialogItem(pMsg->hWin, ID_IMAGE_1);
- pData = _GetImageById(ID_IMAGE_1_IMAGE_0, &FileSize);
- IMAGE_SetDTA(hItem, pData, FileSize);
- // USER START (Optionally insert additional code for further widget initialization)
- hItem = WM_GetDialogItem(pMsg->hWin, ID_IMAGE_1); // get the needle image widget handlder
- WM_HideWin(hItem); // hide it, don't need anymore
- WM_GetClientRectEx(hItem, &pRect1); // get the relative coordinates
- WM_GetWindowRectEx(hItem, &pRect2); // and the absolute coordinates of the image for memory devices
- // create a source and dest devices
- hMemArrowSrc = GUI_MEMDEV_Create(0, 0, pRect1.x1 + 1, pRect1.y1 * 2 - pRect1.x1 + 1);
- hMemArrowDst = GUI_MEMDEV_Create(0, 0, GUI_MEMDEV_GetYSize(hMemArrowSrc), GUI_MEMDEV_GetYSize(hMemArrowSrc) / 2 + (pRect1.x1 + 1) / 2);
- // copy the vertical needle image to the source device
- GUI_MEMDEV_Select(hMemArrowSrc);
- GUI_SetBkColor(GUI_TRANSPARENT); // make it transparent
- GUI_Clear();
- GUI_DrawStreamedBitmapAuto(_acImage_1, 0, 0); // copy the image
- GUI_MEMDEV_Select(0); // select lcd
- // create a progbar under the scale with the size of dest device
- hProgbar = PROGBAR_Create(pRect2.x0 - WM_GetWinSizeY(hItem) + WM_GetWinSizeX(hItem), pRect2.y0, GUI_MEMDEV_GetYSize(hMemArrowSrc), GUI_MEMDEV_GetYSize(hMemArrowSrc), WM_CF_SHOW);
- WM_AttachWindow(hProgbar, pMsg->hWin); // attach to the current window
- WM_SetHasTrans(hProgbar); // hide it
- WM_SetCallback(hProgbar, _cbProgbar); // for handling WM_PAINT message
- dVal = 1; // for incrementing / decrementing the PROGBAR value
- hTimer = WM_CreateTimer(pMsg->hWin, 0, 50, 0); // for changing the PROGBAR value every 50 ms
- // USER END
- break;
- // USER START (Optionally insert additional message handling)
- case WM_TIMER:
- Val += dVal; // incrementing / decrementing the PROGBAR value
- if ((Val > 100) || (Val < 0))
- dVal = -dVal; // change the sign for incrementing / decrementing
- PROGBAR_SetValue(hProgbar, Val); // set the PROGBAR value
- WM_RestartTimer(hTimer, 50); // restart the timer
- break;
- // USER END
- default:
- WM_DefaultProc(pMsg);
- break;
- }
- }
The post was edited 10 times, last by LexaGB ().