@@ -28,7 +28,15 @@ namespace Menu
28
28
static Menu * const menu_main[] =
29
29
{
30
30
&menu_osc[0 ],
31
+ #if NUM_OSCILLATORS >= 2
31
32
&menu_osc[1 ],
33
+ #if NUM_OSCILLATORS >= 3
34
+ &menu_osc[2 ],
35
+ #if NUM_OSCILLATORS >= 4
36
+ &menu_osc[3 ],
37
+ #endif
38
+ #endif
39
+ #endif
32
40
&menu_lfo,
33
41
&menu_flt,
34
42
&menu_amp,
@@ -57,7 +65,7 @@ namespace Menu
57
65
Page active_page = PAGE_MAIN;
58
66
59
67
// active menu
60
- int active_menu = MAIN_OSC1 ;
68
+ int active_menu = 0 ;
61
69
int save_menu[PAGE_COUNT];
62
70
63
71
// menu attributes
@@ -120,11 +128,23 @@ namespace Menu
120
128
// update a linear time property
121
129
float const time_step[] = { 1 , 10 , 100 , 1000 };
122
130
131
+ // initialize the menu system
132
+ void Init ()
133
+ {
134
+ for (int page = 0 ; page < ARRAY_SIZE (page_info); ++page)
135
+ {
136
+ for (int i = 0 ; i < page_info[page].count ; ++i)
137
+ {
138
+ page_info[page].menu [i]->menu = i;
139
+ }
140
+ }
141
+ }
142
+
123
143
// set the active page
124
144
void SetActivePage (HANDLE hOut, Page page)
125
145
{
126
146
// clear the area
127
- static DWORD const size = (49 - page_pos.Y ) * 80 ;
147
+ static DWORD const size = (WINDOW_HEIGHT - 1 - page_pos.Y ) * WINDOW_WIDTH ;
128
148
DWORD written;
129
149
FillConsoleOutputCharacter (hOut, 0 , size, page_pos, &written);
130
150
FillConsoleOutputAttribute (hOut, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE, size, page_pos, &written);
@@ -164,24 +184,36 @@ namespace Menu
164
184
SetActiveMenu (hOut, active_menu > 0 ? active_menu - 1 : page_info[active_page].count - 1 );
165
185
}
166
186
167
- // menu input handler
187
+ // menu key press handler
168
188
void Handler (HANDLE hOut, WORD key, DWORD modifiers)
169
189
{
170
190
page_info[active_page].menu [active_menu]->Handler (hOut, key, modifiers);
171
191
}
172
192
193
+ // menu mouse click handler
194
+ void Click (HANDLE hOut, COORD pos)
195
+ {
196
+ // try dispatching to menus
197
+ for (int menu = 0 ; menu < page_info[active_page].count ; ++menu)
198
+ {
199
+ if (page_info[active_page].menu [menu]->Click (hOut, pos))
200
+ break ;
201
+ }
202
+ }
203
+
204
+
173
205
// print menu title bar
174
206
void Menu::PrintTitle (HANDLE hOut, bool enable, DWORD flags, char const *on_text, char const *off_text)
175
207
{
176
208
// print menu name
177
209
WORD const attrib = title_attrib[enable][flags];
178
- PrintConsoleWithAttribute (hOut, pos, attrib, " %-15s " , name);
210
+ PrintConsoleWithAttribute (hOut, { rect. Left , rect. Top }, attrib, " F%d %-*s " , menu + 1 , rect. Right - rect. Left - 3 , name);
179
211
180
212
// print component enabled
181
213
if (char const *text = enable ? on_text : off_text)
182
214
{
183
215
WORD const enable_attrib = (attrib & 0xF8 ) | (enable ? FOREGROUND_GREEN : (flags ? FOREGROUND_RED : 0 ));
184
- PrintConsoleWithAttribute (hOut, { pos. X + 15 , pos. Y }, enable_attrib, text);
216
+ PrintConsoleWithAttribute (hOut, { rect. Right - 3 , rect. Top }, enable_attrib, text);
185
217
}
186
218
}
187
219
@@ -196,26 +228,26 @@ namespace Menu
196
228
WORD const attrib = item_attrib[flags];
197
229
PrintConsoleWithAttribute (hOut, pos, attrib, format, value);
198
230
}
199
- void PrintItemBool (HANDLE hOut, COORD pos, DWORD flags, char const *format, bool value)
231
+ void PrintItemBool (HANDLE hOut, COORD pos, SHORT width, DWORD flags, char const *format, bool value)
200
232
{
201
233
WORD const attrib = item_attrib[flags];
202
234
PrintConsoleWithAttribute (hOut, pos, attrib, format);
203
235
WORD const value_attrib = (attrib & 0xF8 ) | (value ? FOREGROUND_GREEN : FOREGROUND_RED);
204
236
char const *value_text = value ? " ON" : " OFF" ;
205
- PrintConsoleWithAttribute (hOut, { pos.X + 15 , pos.Y }, value_attrib, value_text);
237
+ PrintConsoleWithAttribute (hOut, { pos.X + width - 3 , pos.Y }, value_attrib, value_text);
206
238
}
207
239
208
240
// print marker
209
- static void PrintMarker (HANDLE hOut, COORD pos , CHAR_INFO left, CHAR_INFO right)
241
+ void Menu:: PrintMarker (HANDLE hOut, int index , CHAR_INFO left, CHAR_INFO right)
210
242
{
211
243
static COORD const zero = { 0 , 0 };
212
244
static COORD const size = { 1 , 1 };
213
245
SMALL_RECT region;
214
246
215
- region.Left = region.Right = pos. X - 1 ;
216
- region.Top = region.Bottom = pos. Y ;
247
+ region.Left = region.Right = rect. Left - 1 ;
248
+ region.Top = region.Bottom = rect. Top + SHORT ( index ) ;
217
249
WriteConsoleOutput (hOut, &left, size, zero, ®ion);
218
- region.Left = region.Right = pos. X + 18 ;
250
+ region.Left = region.Right = rect. Right ;
219
251
WriteConsoleOutput (hOut, &right, size, zero, ®ion);
220
252
}
221
253
@@ -225,60 +257,56 @@ namespace Menu
225
257
static CHAR_INFO const marker_blank = { 0 , FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE };
226
258
227
259
// show selection marker on an item
228
- static inline void ShowMarker (HANDLE hOut, COORD pos )
260
+ inline void Menu:: ShowMarker (HANDLE hOut, int index )
229
261
{
230
- PrintMarker (hOut, pos , marker_left, marker_right);
262
+ PrintMarker (hOut, index , marker_left, marker_right);
231
263
}
232
264
233
265
// hide selection marker on an item
234
- static inline void HideMarker (HANDLE hOut, COORD pos )
266
+ inline void Menu:: HideMarker (HANDLE hOut, int index )
235
267
{
236
- PrintMarker (hOut, pos , marker_blank, marker_blank);
268
+ PrintMarker (hOut, index , marker_blank, marker_blank);
237
269
}
238
270
239
271
// print the whole menu
240
272
void Menu::Print (HANDLE hOut)
241
273
{
242
- COORD p = pos;
243
- p.Y += SHORT (item);
244
-
245
274
int flags[2 ];
246
275
if (active_menu >= 0 && this == page_info[active_page].menu [active_menu])
247
276
{
248
- ShowMarker (hOut, p );
277
+ ShowMarker (hOut, item );
249
278
flags[0 ] = 1 ; flags[1 ] = 2 ;
250
279
}
251
280
else
252
281
{
253
- HideMarker (hOut, p );
282
+ HideMarker (hOut, item );
254
283
flags[0 ] = 0 ; flags[1 ] = 0 ;
255
284
}
256
285
257
- p.Y = pos.Y ;
258
286
for (int i = 0 ; i < count; ++i)
259
287
{
260
- Print (i, hOut, p, flags[item == i]);
261
- ++p.Y ;
288
+ Print (i, hOut, { rect.Left , rect.Top + SHORT (i) }, flags[item == i]);
262
289
}
263
290
}
264
291
265
- // general menu handler
292
+ // general key press handler
266
293
void Menu::Handler (HANDLE hOut, WORD key, DWORD modifiers)
267
294
{
268
295
int sign;
296
+ COORD pos = { rect.Left , rect.Top };
269
297
COORD p = pos;
270
298
switch (key)
271
299
{
272
300
case VK_UP:
273
301
case VK_DOWN:
274
302
sign = key == VK_DOWN ? 1 : -1 ;
275
303
p.Y = pos.Y + SHORT (item);
276
- HideMarker (hOut, p );
304
+ HideMarker (hOut, item );
277
305
Print (item, hOut, p, 1 );
278
306
item = (item + count + sign) % count;
279
307
p.Y = pos.Y + SHORT (item);
280
308
Print (item, hOut, p, 2 );
281
- ShowMarker (hOut, p );
309
+ ShowMarker (hOut, item );
282
310
break ;
283
311
284
312
case VK_LEFT:
@@ -290,4 +318,18 @@ namespace Menu
290
318
break ;
291
319
}
292
320
}
321
+
322
+ // general mouse click handler
323
+ bool Menu::Click (HANDLE hOut, COORD pos)
324
+ {
325
+ if (!Inside (pos))
326
+ return false ;
327
+ SetActiveMenu (hOut, menu);
328
+ HideMarker (hOut, item);
329
+ Print (item, hOut, { rect.Left , rect.Top + SHORT (item) }, 1 );
330
+ item = Clamp (pos.Y - rect.Top , 0 , count - 1 );
331
+ Print (item, hOut, { rect.Left , rect.Top + SHORT (item) }, 2 );
332
+ ShowMarker (hOut, item);
333
+ return true ;
334
+ }
293
335
}
0 commit comments