Step 10: Design Display GUI using SEGGER emWin Graphics Library
Step 10.1: Design Audio Player GUI using GUI Builder utility
1
Use the SEGGER emWin Graphics Library GUI Builder utility to create a basic GUI layout for the Audio Player Window. Navigate to harmony-install-dir/utilities/segger/emwin and open the GUIBuilder utility.
Widget selection bar:
- Contains all available widgets of the GUI Builder. They can be added by a single click into the Widget selection bar on the desired widget, or by dragging them into the editor area.
Object tree:
- Shows all currently loaded dialogs and their child widgets. It can be used for selecting a widget by clicking on the associated entry.
Widget properties:
- Shows the properties of each widget and can be used for editing them.
Editor:
- Shows the currently selected dialog. It can be used to place and resize the dialog and its widgets.
2
You will add an "Audio Player" window that will act as a container for other widgets.
- From the Widget selection bar, scroll to the extreme right and click on the Window widget.
- In the widget properties, modify the Name property of the widget to "audio_player".
- Modify the xSize to 480 and ySize to 272. These values correspond to the width and height in pixels, of the display module on the MEB II board.
The WINDOW widget is used to create a dialog window from a resource table. It should be used if the dialog should not look like a frame window. The window widget acts as background and as a container for child windows
7
Next, you will add a "Repeat Track" button. You will use this button to loop/un-loop track list or put a single track in continuous loop mode.
- Click on the Button widget.
- In the Widget properties, modify the Name to "Repeat Button"
- Modify the xPos to 5 and yPos to 210.
- Modify the xSize to 40 and ySize to 40.
8
Add a "Shuffle Track" button. You will use this button to turn on shuffling of tracks in the track list. This will be achieved by generating a random number to select the next track to play.
- Click on the Button widget.
- In the Widget properties, modify the Name to "Shuffle Button"
- Modify the xPos to 50 and yPos to 210.
- Modify the xSize to 40 and ySize to 40.
11
Add a "Settings button". You will use the Settings button to select between SD Card/Flash Drive medias, Show/Hide Playlist and change background.
- Click on the Button widget.
- In the Widget properties, modify the Name to "Settings Button"
- Modify the xPos to 425 and yPos to 203.
- Modify the xSize to 50 and ySize to 50.
13
Add a track seek-bar. The track seek-bar will allow you to seek the track either in forward or reverse direction.
- Click on the Slider widget.
- In the Widget properties, modify the Name to "Track Slider"
- Modify the xPos to 38 and yPos to 171.
- Modify the xSize to 400 and ySize to 19.
Note that you have overlapped the track progress bar with the track see-bar. The z-order of widget creation will ensure that when pressed, the touch events are handled by the slider widget and not the progress bar.
Z-order is an ordering of overlapping two-dimensional objects. When two widgets overlap, their Z-order determines which one appears on top of the other. The widget created at the last is the topmost widget.
19
You have added all the widgets for the "audio_player" window. Go to the menu bar and click File > Save to save the project.
The project will be saved as a C file: audio_playerDLG.c at the location of the GUI builder utility: harmony-install-dir/utilities/segger/emwin
Step 10.2: Design Audio Player Settings GUI using GUI Builder utility
1
You may choose to continue using the currently open GUI Builder utility to create the Settings window. In case you have closed the GUI Builder utility, re-open it from the harmony-install-dir/utilities/segger/emwin path, click File > Open and open the audio_playerDLG.c file from harmony-install-dir/utilities/segger/emwin location. The GUI Builder utility will create a separate C file for each window/dialog.
2
You will add a settings window that will act as a container for other widgets.
- From the Widget selection bar, scroll to the extreme right and click on the Window widget.
- In the widget properties, modify the Name property of the widget to "settings_window".
- Modify the xPos to 320 and yPos to 10. Note that the window will be positioned to these absolute co-ordinates.
- Modify the xSize to 155 and ySize to 148.
3
You will add a toggle switch. The toggle switch is basically a button widget which will be customized through code in the paint event for the button widget, to make the button widget appear and function like a toggle switch
- Click on the Button widget.
- In the widget properties, modify the Name property of the widget to "Switch 1".
- Modify the xPos to 80 and yPos to 3.
Note that these co-ordinates are relative to the window widget which acts as a container for these child widgets. This is the case with all the widgets in "audio_player" window, but is more evident here, since the xPos and yPos co-ordinates for the settings window are not set (0,0).
- Modify the xSize to 70 and ySize to 32.
6
You will add text for switch 1.
- Click on the Text widget.
- In the widget properties, modify the Name property of the widget to "Mode".
Unless set by using the TEXT_SetText API, the text widget will show the string set for the Name property as text string.
- Modify the xPos to 7 and yPos to 14.
- Modify the xSize to 70 and ySize to 15.
9
You have added all the widgets for the Settings window. Go to the menu bar and click on the File > Save.. button to save the project.
The project will be saved as a C file: settings_windowDLG.c at the location of the GUI builder utility: harmony-install-dir/utilities/segger/emwin
Step 10.3: Analyze the C files generated by the GUI Builder utility
1
Open audio_playerDLG.c from harmony-install-dir/utilities/segger/emwin.
2
In order to be able to separate all widgets from each other IDs are assigned to widgets. To make sure that every widget has its unique Id, predefined symbols may be used. emWin provides a list of predefined symbols for each widget (example, for button widget: GUI_ID_BUTTON0 - GUI_ID_BUTTON9). If the predefined symbols do not match ones requirements, custom unique IDs may be defined as follows:
The names of some of the macros (Widget IDs) have been modified in the solution and development files. This is done for better readability and easy identification of widgets based on their IDs. For example, ID_BUTTON_1 used for the track shuffle button, is renamed to ID_SHUFFLE_BUTTON
3
Two basic things are required to create a dialog box: a resource table that defines the widgets to be included, and a dialog procedure which defines the initial values for the widgets as well as their behavior. Once both items exist, you need only a single function call (GUI_CreateDialogBox() or GUI_ExecDialogBox()) to actually create the dialog.
- Resource Table
The file defines a resource table which specifies all the widgets to be included in the dialog. You can manually add widgets to the resource table by using the <WIDGET>_CreateIndirect() function for indirect creation.
- Dialog Procedure
A Dialog Procedure is a call back that is registered during dialog creation. This call back is called by the emWin library. The action performed by the callback routine depends on the type of message it receives. The call back allows initialization of the widgets (under the WM_INIT_DIALOG message passed to the callback), handle the notifications (events) generated by various widgets (under the WM_NOTIFY_PARENT message passed to the callback), and to define the interactions between the widgets.
In addition to this, the WM_PAINT message allows the callback routine to redraw (thereby customize) the contents of the window.
4
Each file contains a creation routine at the end named Create<Widget name>(). These routines create the recording dialog. These routines must be called to initialize and display the dialog on the screen. The GUI_CreateDialogBox routine takes a reference to the resource table (_aDialogCreate) and a reference to the dialog procedure (_cbDialog). As you will see later, the dialog creation routine GUI_CreateDialogBox must be registered with the SEGGER emWin GUI wrapper during initialization which will then call the dialog creation routine.
Your application will add the creation routines for both main window and settings window under a single window creation routine and register it with the SEGGER emWin GUI wrapper.
Step 10.4: Use Bitmap Converter utility to create image assets
1
The Bitmap Converter utility is used to convert BMP, PNG or GIF files into the desired emWin bitmap format. The utility supports color conversion, which is used as a tool to reduce memory consumption. The Bitmap Converter also supports other simple functions such as:
- Scaling the bitmap size,
- Flipping the bitmap horizontally or vertically,
- Rotating the bitmap
- Inverting the bitmap indices or colors
The tool output can be a C file which can directly be compiled and linked with the project.
Open BmpCvt.exe from harmony-install-dir/utilities/segger/emwin.
2
Using the BmpCvt utility you will perform color conversion on a play button image to reduce its memory size. In addition, you will select a color for transparency. Transparency means that the selected color will not produce any output.
Copy the resources folder from
harmony-install-dir/apps/training/middleware/emwin_media_player/emwin_media_player_lab/dev_files/ to
harmony-install-dir/apps/training/middleware/dev/emwin_media_player/emwin_media_player_lab/firmware/src.
The resources folder contains the images that will be applied to various button widgets.
Also, create a emwin_gui folder under
/training/middleware/dev/emwin_media_player/emwin_media_player_lab/firmware/src.
You will save the converted C files in this folder.
On the BmpCvt utility click on File->Open… and navigate to harmony-install-dir/apps/training/middleware/dev/emwin_media_player/emwin_media_player_lab/firmware/src/resources
to open the playButton_75_75.bmp file.
3
You will reduce the memory size by performing a color conversion.
On the BmpCvt utility, click on Image > Convert to > Best palette + transparency
You will get a warning saying that the image contains 1613 colors; in paletized mode no more than 256 colors can be stored and that this will degrade the image quality. This indicates that the image originally contains 1613 colors. Converting it to a palette-based image will reduce the number of colors in the image to 256. Palette based images maintain the color information in the form of an index into an array of colors (known as the palette). The array of colors in this case will be limited to 256 colors. So, instead of saving each pixel information as a 16-bit color it is stored as an 8-bit index into the array of colors, thereby resulting in a significant reduction in size.
Acknowledge the warning message by clicking on Yes.
The Colors: 256 shows the array of 256 colors that are now present in the converted image.
4
You will select a color that needs to be transparent. The selected color will not produce any output.
Transparency is implemented by setting the color at index 0 in the color palette to the color that is selected for transparency.
On the BmpCvt utility, click on Image > Transparency
A pop-up will ask for the color to make transparent. From the drop-down box, select the color at Index 0: 000000 and click OK. The color 0x000000 corresponds to the color black. This will make all instances of black color in the image transparent.
For the above to work, the image that must be displayed must not have the black color. Use an image editor tool to set the color to make transparent to a color that is not used in the image.
5
Click on File > Save As and save the image as "C" bitmap file (*.C) in the Save as type drop down box. Save the C file playButton_75_75.c to the emwin_gui folder created under
/training/middleware/dev/emwin_media_player/emwin_media_player_lab/firmware/src.
A pop-up will ask for Format Specification. Select the 8 bit per pixel and click OK.
6
Open the generated playButton_75_75.c from
/training/middleware/dev/emwin_media_player/emwin_media_player_lab/firmware/src/emwin_gui.
The file contains:
- An array containing 256 colors (1) that are part of the image. The index 0 into the array is set to the color to be made transparent (black color - 0x000000).
- Next, it contains information of the palette in a structure (2). Note that the HasTrans bit field is set to 1.
- The image bit map (3) only contains index into the array of colors.
- Finally, it contains an image bitmap information in a structure (4).
7
All the other images in the resources folder can be converted to C file in a similar manner. You can either convert them using the tool or copy all the converted C files available in the dev_files/emwin_gui folder under the /training/middleware/emwin_media_player/emwin_media_player_lab/ folder, to your project folder training/middleware/dev/emwin_media_player/emwin_media_player_lab/firmware/src/emwin_gui.
Step 10.5: Customize Volume Slider Widget
1
The SEGGER emWin graphics library allows custom rendering of widgets. This can be achieved by registering a callback for window and/or window objects (widgets) and then responding appropriately to the events received by the registered callback.
2
If the behavior of a widget has to be changed, or if the functionality of a window needs to be enhanced to meet custom needs, we recommend you overwrite the internal callback function. This is done in a few simple steps:
- Creating a custom callback function:
The first step is to implement a function using the following prototype:
- Messages:
The second step is to implement a response to certain messages. Since custom callback functions do not need to handle all possible messages, it is recommended to make use of a switch / case condition.
- Processing the default callback:
The third step is to make sure all messages which are not handled by the custom callback function, are handled by the internal (default) callback function. The recommended way to do this is to use the default case of the switch / case condition to call the internal callback function. The internal callback functions for widgets are named <WIDGET>_Callback().
- Setting the custom callback function to be used
The last step to do is to register the newly created callback function to be used by a window or widget. This is done with a simple call of WM_SetCallback().
3
You will see how to customize the rendering of the volume slider widget. The below figure shows how the default slider will be customized.
- The first step is to implement a callback function for the slider widget that will be called by the emWin graphics library. The below figure shows the callback for the slider widget. The callback receives a WM_MESSAGE structure and handles the WM_PAINT event. All other events are handled by the default event handler for the widget by a call to:
The callback function is registered during the initialization of the widgets under the WM_INIT_DIALOG event received by the _cbDialog callback function registered with the audio_player dialog box creation routine. You will also register widget specific data by a call to SLIDER_SetUserData() which can be then retrieved by a call to SLIDER_GetUserData(). This allows a single slider callback routine to (cbVolSlider() in your case) be used for multiple slider widget instances (for example you may use the same callback for a volume slider and the seek bar). In the callback the slider data for which the callback is called can be retrieved by a call to
where, pMsg->hWin is the window handle.
- The custom rendering is implemented in the cbVolSlider() callback, under the WM_PAINT event. The WM_GetClientRect() returns the relative coordinates of the slider widget (x0=0, y0=0) to (x1=99, y1=34). The current value of the slider is determined by a call to SLIDER_GetValue(). The active region of the slider is drawn by a call to GUI_FillRect() which renders a filled rectangle based on the active color set by a call to GUI_SetColor(). The remaining portion of the slider is filled with inactive color. A slider knob is rendered by a call to GUI_FillCircle().
3
Similarly, you will implement custom rendering of other widgets by implementing their callbacks and handling the WM_PAINT event when the callback is called by emWin. You will also register the callback by a call to WM_SetCallback(). You may refer to the audio_playerDLG.c and settings_windowDLG.c files available under training/middleware/emwin_media_player/emwin_media_player_lab/dev_files/emwin_gui.
Alternatively, you may copy these files to your project directory:
training/middleware/dev/emwin_media_player/emwin_media_player_lab/firmware/src/emwin_gui.
Step 10.6: Respond to Widget Events
1
When a widget is clicked, released or moved etc., emWin informs its parent window that something has changed in one of its child widgets. These messages are typically sent by widgets to their parent windows to give them a chance to respond to the event.
2
For the volume slider widget, whenever the slider is clicked (WM_NOTIFICATION_CLICKED event) or released (WM_NOTIFICATION_RELEASED event), the registered callback (cbDialog()) of the the volume slider's parent widget receives WM_NOTIFY_PARENT event. The WM_MESSAGE received by the cbDialog() contains more information on the child widget and its event type. The MsgId contains the message type - WM_NOTIFY_PARENT. The Data.v value of the message contains the notification code of the message (WM_NOTIFICATION_CLICKED / WM_NOTIFICATION_RELEASED) and the widget ID can be obtained by a call to the WM_GetId() API. The below figure shows the code snippet for slider event handling.
In addition to the clicked and released events, the slider widget also receives the WM_NOTIFICATION_VALUE_CHANGED event whenever the slider value is changed. The clicked and released events are called only when the user presses/releases the widget on the touch screen. If the clicked/released event results in a change in the slider value, the value changed event is also generated. However, the value changed event is generated even when the slider value is changed by the application code by a call to the SLIDER_SetValue() API.
3
Similarly, for other widgets, emWin will send the WM_NOTIFY_PARENT event to the respective widget's parent in its registered callback. You will write your event handling code to respond to the widget's events. Refer to the audio_playerDLG.c and settings_windowDLG.c files under
training/middleware/emwin_media_player/emwin_media_palyer_lab/dev_files/emwin_gui.
Alternatively, you may copy these files from:
training/middleware/emwin_media_player/emwin_media_player_lab/dev_files/emwin_gui
to your project directory
training/middleware/dev/emwin_media_player/emwin_media_player_lab/firmware/src/emwin_gui.
Table of Contents
|