Friday, July 21st 2017, 10:45am UTC+2

You are not logged in.

  • Login
  • Register

Date of registration: Jun 9th 2017

Posts: 5

1

Sunday, June 25th 2017, 2:12pm

Dropwdown Event WM_NOTIFICATION_CLICKED not received

Hey, i'd like to create a dropdown. SO i used the GUI Builder to create the skeleton code.

My idea is: when the user presses the dropdown the list is supposed to expand, when the user presses somewhere outside the dropdown, the list should collapse.

Now i'm only receiving WM_NOTIFICATION_LOST_FOCUS events in my callback routine. The Event WM_NOTIFICATION_CLICKED never occurs. Does anybody know why?


Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
/*********************************************************************
 *                                                                	*
 *            	SEGGER Microcontroller GmbH & Co. KG            	*
 *    	Solutions for real time microcontroller applications    	*
 *                                                                	*
 **********************************************************************
 *                                                                	*
 * C-file generated by:                                           	*
 *                                                                	*
 *    	GUI_Builder for emWin version 5.32                      	*
 *    	Compiled Oct  8 2015, 11:59:02                          	*
 *    	(c) 2015 Segger Microcontroller GmbH & Co. KG           	*
 *                                                                	*
 **********************************************************************
 *                                                                	*
 *    	Internet: www.segger.com  Support: support@segger.com   	*
 *                                                                	*
 **********************************************************************
 */

// USER START (Optionally insert additional includes)
#include "FramewinDLG_new.h"
#include "cmsis_os.h"
// USER END

/*********************************************************************
 *
 *   	Defines
 *
 **********************************************************************
 */
#define ID_FRAMEWIN_0 (GUI_ID_USER + 0x00)
#define ID_DROPDOWN_0 (GUI_ID_USER + 0x04)

// USER START (Optionally insert additional defines)
///Maximale Breite des Displays
#define X_MAX 240

///Maximale Höhe des Displays
#define Y_MAX 320

//
// Recommended memory to run the sample with adequate performance
//
#define RECOMMENDED_MEMORY (1024L * 2)

// USER END

/*********************************************************************
 *
 *   	Static data
 *
 **********************************************************************
 */

// USER START (Optionally insert additional static data)
// USER END
/*********************************************************************
 *
 *   	_aDialogCreate
 */
static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] =
	{
		{ FRAMEWIN_CreateIndirect, "Framewin", ID_FRAMEWIN_0, 0, 0, X_MAX, Y_MAX, 0, 0x0, 0 },
		{ DROPDOWN_CreateIndirect, "Dropdown_menu", ID_DROPDOWN_0, 0, 0, 144, 25, 0, 0x0, 0 },
	// USER START (Optionally insert additional widgets)
	// USER END
		};

/*********************************************************************
 *
 *   	Static code
 *
 **********************************************************************
 */

// USER START (Optionally insert additional static code)
// USER END
/*********************************************************************
 *
 *   	_cbDialog
 */
static void _cbDialog(WM_MESSAGE * pMsg)
{

	//TODO weg
	volatile uint8_t test = 0;

	WM_HWIN hItem;
	int NCode;
	int Id;
	// USER START (Optionally insert additional variables)
	// USER END

	switch (pMsg->MsgId)
	{
	case WM_INIT_DIALOG:
		//
		// Initialization of 'Dropdown_menu'
		//
		hItem = WM_GetDialogItem(pMsg->hWin, ID_DROPDOWN_0);
		DROPDOWN_SetFont(hItem, GUI_FONT_20_1);
		DROPDOWN_AddString(hItem, "Show Menue");
		DROPDOWN_AddString(hItem, "Show Ike");
		DROPDOWN_AddString(hItem, "Show Sensor Values");
		// USER START (Optionally insert additional code for further widget initialization)
		// USER END
		break;
	case WM_NOTIFY_PARENT:

		test++;
		test += 11;
		test -= 9;
		Id = WM_GetId(pMsg->hWinSrc);
		NCode = pMsg->Data.v;
		switch (Id)
		{
		case ID_DROPDOWN_0: // Notifications sent by 'Dropdown_menu'
			switch (NCode)
			{
			case WM_NOTIFICATION_CLICKED:
				// USER START (Optionally insert code for reacting on notification message)
				hItem = WM_GetDialogItem(pMsg->hWin, ID_DROPDOWN_0);

				test++;
				test += 4;
				test--;

				DROPDOWN_Expand(hItem);
				// USER END
				break;
			case WM_NOTIFICATION_RELEASED:
				// USER START (Optionally insert code for reacting on notification message)
				// USER END
				break;
			case WM_NOTIFICATION_SEL_CHANGED:
				// USER START (Optionally insert code for reacting on notification message)
				// USER END
				break;
				// USER START (Optionally insert additional code for further notification handling)
			case WM_NOTIFICATION_LOST_FOCUS:

				// USER START (Optionally insert code for reacting on notification message)
				hItem = WM_GetDialogItem(pMsg->hWin, ID_DROPDOWN_0);

				test++;
				test += 4;
				test--;

				DROPDOWN_Collapse(hItem);

				// USER END
			}
			break;
			// USER START (Optionally insert additional code for further Ids)
			// USER END
		}
		break;
		// USER START (Optionally insert additional message handling)
		// USER END
	default:
		WM_DefaultProc(pMsg);
		break;
	}
}

/*********************************************************************
 *
 *   	Public code
 *
 **********************************************************************
 */
/*********************************************************************
 *
 *   	CreateFramewin
 */
WM_HWIN CreateFramewin_new(void)
{
	WM_HWIN hWin;

	//
	// Check if recommended memory for the sample is available
	//
	if (GUI_ALLOC_GetNumFreeBytes() < RECOMMENDED_MEMORY)
	{
		GUI_ErrorOut("Not enough memory available.");
		return 0;
	}

	hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
	return hWin;
}

// USER START (Optionally insert additional public code)
// USER END

/*************************** End of file ****************************/


my display thread looks like this

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
void DisplayThread(void const * argument)
{

	//Display Init.
	GUI_Init();


	CreateFramewin_new();

   

	const size_t nMax = 32;
	uint8_t * touchcoords[nMax];

	for (;;)
	{




		snprintf((char *) touchcoords, nMax, "X: %04d, Y: %04d", touchX, touchY);
		GUI_DispStringAt((char *) touchcoords, 0, 0);

		WM_Exec();

		osDelay(500);

	}
}


The GUI_TOUCH_StoreStateEx() is called in a separate thread every 25ms to get the newest touched coordinates (that part works, since i'm receiving events)

Now my question is, how can i expand the dropdown list when pressing on it?

Thx for your help :)

SEGGER - Schoenen

Super Moderator

Date of registration: Aug 13th 2015

Posts: 327

2

Monday, July 10th 2017, 3:36pm

Hi,

I tested you application but it caused a crash because of an endless loop generated with the functions DROPDOWN_Expand/Collapse(). Below is the application slightly changed. Now the DROPDOWN widget closes if anywhere outside the widget a pressed event occures.

C/C++ Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#include "DIALOG.h"

/*********************************************************************
*
*	Defines
*
**********************************************************************
*/
#define ID_FRAMEWIN_0 (GUI_ID_USER + 0x00)
#define ID_DROPDOWN_0 (GUI_ID_USER + 0x04)

// USER START (Optionally insert additional defines)
///Maximale Breite des Displays
#define X_MAX 240

///Maximale Höhe des Displays
#define Y_MAX 320

/*********************************************************************
*
*	Static data
*
**********************************************************************
*/
/*********************************************************************
*
*	_aDialogCreate
*/
static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
  { FRAMEWIN_CreateIndirect, "Framewin", ID_FRAMEWIN_0, 0, 0, X_MAX, Y_MAX, 0, 0x0, 0 },
  { DROPDOWN_CreateIndirect, "Dropdown_menu", ID_DROPDOWN_0, 0, 0, 144, 80, 0, 0x0, 0 },
};

static WM_HWIN _hDropDown;

/*********************************************************************
*
*	Static code
*
**********************************************************************
*/

/*********************************************************************
*
*	_cbDialog
*/
static void _cbDialog(WM_MESSAGE * pMsg) {
  WM_HWIN hItem;
  int NCode;
  int Id;

  switch (pMsg->MsgId) {
  case WM_INIT_DIALOG:
	//
	// Initialization of 'Dropdown_menu'
	//
	_hDropDown = hItem = WM_GetDialogItem(pMsg->hWin, ID_DROPDOWN_0);
	DROPDOWN_SetFont(hItem, GUI_FONT_20_1);
	DROPDOWN_AddString(hItem, "Show Menue");
	DROPDOWN_AddString(hItem, "Show Ike");
	DROPDOWN_AddString(hItem, "Show Sensor Values");
	break;
  case WM_NOTIFY_PARENT:
	Id = WM_GetId(pMsg->hWinSrc);
	NCode = pMsg->Data.v;
	switch (Id)
	{
	case ID_DROPDOWN_0: // Notifications sent by 'Dropdown_menu'
  	switch (NCode) {
  	case WM_NOTIFICATION_CLICKED:
    	break;
  	case WM_NOTIFICATION_RELEASED:
    	break;
  	case WM_NOTIFICATION_SEL_CHANGED:
    	break;
  	case WM_NOTIFICATION_LOST_FOCUS:
    	break;
  	}
  	break;
	}
	break;
  default:
	WM_DefaultProc(pMsg);
	break;
  }
}

/*********************************************************************
*
*	CreateFramewin
*/
static void _PidHook(GUI_PID_STATE * pState) {
  WM_HWIN hListBox;

  //
  // Check if pState is not a null pointer
  //
  if (pState) {
	//
	// Get the LISTBOX attached to the dropdown, if it not 0 the DROPDOWN is expansed
	//
	hListBox = DROPDOWN_GetListbox(_hDropDown);
	if (hListBox) {
  	//
  	// If PID is pressed..
  	//
  	if (pState->Pressed) {
    	//
    	// .. and the window under the input is not the DROPDOWN
    	// or the LISTBOX widget, close the DROPDOWN.
    	//
    	if ((hListBox   != WM_Screen2hWin(pState->x, pState->y)) &&
        	(_hDropDown != WM_Screen2hWin(pState->x, pState->y))) {
      	DROPDOWN_Collapse(_hDropDown);
    	}
  	}
	}
  }
}

/*********************************************************************
*
*	Public code
*
**********************************************************************
*/
/*********************************************************************
*
*	CreateFramewin
*/
WM_HWIN CreateFramewin_new(void) {
  WM_HWIN hWin;

  hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
  return hWin;
}

/*********************************************************************
*
*   	Public code
*
**********************************************************************
*/
void MainTask(void) {
  GUI_Init();
  CreateFramewin_new();
  GUI_PID_SetHook(_PidHook);
  while(1) {
	GUI_Delay(1000);
  }
}


In WM_INIT_DIALOG we remember the handle of the DROPDOWN widget and check in _PidHook if the input is outside the DROPDOWN widget and outside the attached LISTBOX widget.
After setting the _PidHook function it gets called each time a new PID input gets passed to emWin.

Depending on the emWin version you are using the function GUI_PID_SetHook() might not be available (it was introduced with version 5.38). If this the case try to call GUI_PID__SetHook() instead (it works almost the same but gets called after the PID input is passed to emWin).

Regards,
Sven

Date of registration: Jun 9th 2017

Posts: 5

3

Sunday, July 16th 2017, 11:14pm

hey
big thx for your great help. :)
I have been working with your solution this weekend and it works very well. :D
Based on your solution i was able to implement my own menu.
I couldn't figure out, what emWin Version ST is using, but it didn't support GUI_PID_SetHook(), but GUI_PID__SetHook() works fine as well :)

SEGGER - Schoenen

Super Moderator

Date of registration: Aug 13th 2015

Posts: 327

4

Wednesday, July 19th 2017, 4:57pm

Hi,

to get the emWin version search for GUI_Version.h. In that file is a define like:

#define GUI_VERSION 54011

The version above would V5.40k.

Regards,
Sven

Date of registration: Jun 9th 2017

Posts: 5

5

Yesterday, 10:30pm

hey,
thx for the info :)
ST uses #define GUI_VERSION 53202 =>V5.32.
Seems like a rather old version :|