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
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
|
/*!
* \file vdr_menu.h
* \brief Implements menu handling for broswing media libraries within VDR
*
* \version $Revision: 1.13 $
* \date $Date$
* \author Ralf Klueber, Lars von Wedel, Andreas Kellner, Wolfgang Rohdewald
* \author Responsible author: $Author$
*
* $Id$
*/
#ifndef _VDR_MENU_H
#define _VDR_MENU_H
#include <string>
// #include <list>
#include <vector>
#include <osd.h>
#include <plugin.h>
#include <status.h>
#include "vdr_actions.h"
#include "vdr_player.h"
//! \brief play a selection, aborting what is currently played
//! \param select if true, play only what the current position selects
void Play(mgSelection *sel,const bool select=false);
void showmessage(const char *msg,int duration=2);
void showimportcount(unsigned int count);
class cCommands;
class mgSelection;
class mgMenu;
class mgMainMenu;
class mgIncrementalSearch;
//! \brief if a player is running, return it
mgPlayerControl * PlayerControl ();
//! \brief callback class, monitors state changes in vdr
class mgStatus : public cStatus
{
private:
//! \brief the mgMainMenu that wants to be notified
mgMainMenu *main;
public:
//! \brief default constructor
mgStatus(mgMainMenu* m) { main = m;}
protected:
//! \brief the event we want to know about
virtual void OsdCurrentItem(const char *Text);
};
/*!
* \brief the muggle main OSD
*/
class mgMainMenu:public cOsdMenu
{
private:
mgSelection *m_treesel;
mgSelection *m_playsel;
mgSelection *m_collectionsel;
char *m_message;
void showMessage();
void LoadExternalCommands();
vector<mgOrder*> orders;
unsigned int m_current_order;
void DumpOrders(mgValmap& nv);
void LoadOrders(mgValmap& nv);
mgMenu *m_root;
bool m_save_warned;
public:
void AddOrder();
void DeleteOrder();
void AddOrderActions(mgMenu *m);
unsigned int getCurrentOrder() { return m_current_order; }
mgOrder* getOrder(unsigned int idx);
void setOrder(mgSelection *sel, unsigned int idx);
mgSelection *moveselection;
mgActions CurrentType();
//! \brief syntactic sugar: expose the protected cOsdMenu::SetHelp
void SetHelpKeys(const char *Red,const char *Green, const char *Yellow, const char *Blue) { SetHelp(Red,Green,Yellow,Blue); }
//! \brief callback object, lets vdr notify us about OSD changes
mgStatus *m_Status;
//! \brief play the play selection, abort ongoing instant play
void PlayQueue();
//! \brief instant play the selection, abort ongoing queue playing
void PlayInstant(const bool select=false);
//! \brief true if we are browsing m_collectionsel
bool UsingCollection;
//! \brief the different menus, the last one is active
vector < mgMenu * >Menus;
//! \brief true if an item from the "playing" selection is being played
bool queue_playing;
//! \brief true if an item is being instant played
bool instant_playing;
//! \brief parent menu if any
mgMenu * Parent ();
//! \brief default constructor
mgMainMenu ();
//! \brief default destructor
~mgMainMenu ();
//! \brief save the entire muggle state
void SaveState();
//! \brief adds a new mgMenu to the stack
void AddMenu (mgMenu * m,unsigned int position=0);
//! \brief initializes using values from nv
void InitMapFromSetup (mgValmap& nv);
//! \brief main entry point, called from vdr
eOSState ProcessKey (eKeys Key);
//! \brief from now on use the normal selection
void UseNormalSelection ()
{
UsingCollection= false;
}
//! \brief from now on use the collection selection
void UseCollectionSelection ()
{
UsingCollection= true;
}
//! \brief this is the collection things will be added to
std::string default_collection;
/*! \brief this is the "now playing" collection translated in
* the current language. When changing the OSD language, this
* collection will NOT be renamed in the data base, but a new
* empty collection will be started. The collection for the
* previous language will stay, so the user can copy from the
* old one to the new one.
*/
std::string play_collection;
/*! \brief selects a certain line on the OSD and displays the OSD
*/
void DisplayGoto ();
//! \brief external commands
cCommands *external_commands;
//! \brief Actions can set newmenu which will then be displayed next
mgMenu *newmenu;
//! \brief Actions can set newstate which will then be returned to main vdr
eOSState newstate;
//! \brief Actions can set forcerefresh. This will force a redisplay of the OSD
bool forcerefresh;
//! \brief show a message. Can be called by actions. It will
// only be shown at the end of the next mgMainMenu::ProcessKey
// because that might do forcerefresh which overwrites the message
void Message (const char *msg) { m_message = strdup(msg); }
void Message1 (const char *msg, const char *arg1);
void Message1 (const char *msg, std::string arg1) { Message1(msg,arg1.c_str()); }
//! \brief Actions can request a new position. -1 means none wanted
int newposition;
//! \brief clears the screen, sets a title and the hotkey flag
void InitOsd (std::string title,const bool hashotkeys);
#if VDRVERSNUM >= 10307
//! \brief expose the protected DisplayMenu() from cOsdMenu
cSkinDisplayMenu *DisplayMenu(void)
{
return cOsdMenu::DisplayMenu();
}
#endif
//! \brief expose the protected cOsdMenu::hk()
const char *hk (const char *s)
{
return cOsdMenu::hk (s);
}
//! \brief the current selection
mgSelection* selection () const
{
if (UsingCollection)
return m_collectionsel;
else
return m_treesel;
}
//! \brief the collection selection
mgSelection* collselection() const
{
return m_collectionsel;
}
//! \brief the "now playing" selection
mgSelection* playselection () const
{
return m_playsel;
}
//! \brief true if the cursor is placed in the collection list
bool ShowingCollections();
//! \brief true if the cursor is placed on the default collection
bool DefaultCollectionSelected();
//! \brief true if the cursor is placed in the default collection
bool CollectionEntered(std::string name);
void AddItem(mgAction *a);
void CollectionChanged(std::string name);
void CloseMenu();
void RefreshTitle();
};
//! \brief a generic muggle menu
class mgMenu
{
private:
mgMainMenu* m_osd;
const char *HKey(const mgActions act,mgActions on);
protected:
unsigned int m_prevpos;
bool m_prevUsingCollection;
eOSState ExecuteButton(eKeys key);
//! \brief adds the wanted action to the OSD menu
// \param hotkey if true, add this as a hotkey
void AddAction(const mgActions action, mgActions on = mgActions(0),const bool hotkey=true);
//! \brief add an external action, always with hotkey
void AddExternalAction(const mgActions action, const char *title);
//! \brief adds entries for all selected data base items to the OSD menu.
// If this is the list of collections, appends a command for collection
// creation.
void AddSelectionItems (mgSelection *sel,mgActions act = actEntry);
//! \brief the name of the blue button depends of where we are
int m_parent_index;
std::string m_parent_name;
public:
/*! sets the correct help keys.
* \todo without data from mysql, no key is shown,
* not even yellow or blue
*/
void SetHelpKeys(mgActions on = mgActions(0));
//! \brief generates an object for the wanted action
mgAction* GenerateAction(const mgActions action,mgActions on);
//! \brief executes the wanted action
eOSState ExecuteAction (const mgActions action, const mgActions on);
//! \brief sets the pointer to the owning mgMainMenu
void setosd (mgMainMenu* osd);
void setParentIndex(int idx) { m_parent_index = idx; }
int getParentIndex() { return m_parent_index; }
void setParentName(std::string name) { m_parent_name = name; }
std::string getParentName() { return m_parent_name; }
//! \brief the pointer to the owning mgMainMenu
mgMainMenu* osd () const
{
return m_osd;
}
//! \brief the currently active selection of the owning mgMainMenu
mgSelection* selection () const
{
return osd ()->selection ();
}
//! \brief the playselection of the owning mgMainMenu
mgSelection* playselection () const
{
return osd ()->playselection ();
}
mgMenu ();
virtual ~ mgMenu ()
{
}
//! \brief computes the title
virtual std::string Title() const = 0;
//! \brief clears the screen, sets a title and the hotkey flag
void InitOsd (const bool hashotkeys=true);
//! \brief display OSD and go to osd()->newposition
void Display ();
//! \brief BuildOsd() should be abstract but then we cannot compile
virtual void BuildOsd ()
{
}
/*! \brief Process() should be abstract but then we cannot compile.
* \return Process may decide that we want another screen to be displayed.
* If the mgMenu* returned is not "this", the caller will use the return
* value for a new display. If NULL is returned, the caller will display
* the previous menu.
*/
virtual eOSState Process (eKeys Key);
//! \brief the ID of the action defined by the red button.
mgActions TreeRedAction;
mgActions CollRedAction;
//! \brief the ID of the action defined by the green button.
mgActions TreeGreenAction;
mgActions CollGreenAction;
//! \brief the action defined by the yellow button.
mgActions TreeYellowAction;
mgActions CollYellowAction;
//! \brief the action defined by the blue button.
mgActions TreeBlueAction;
mgActions CollBlueAction;
};
//! \brief an mgMenu class for navigating through the data base
class mgTree:public mgMenu
{
public:
mgTree();
//! \brief computes the title
std::string Title() const;
bool UpdateIncrementalSearch( eKeys key );
void TerminateIncrementalSearch( bool remain_on_current );
protected:
void BuildOsd ();
private:
void UpdateSearchPosition();
mgIncrementalSearch *m_incsearch;
std::string m_filter;
int m_start_position;
};
//! \brief an mgMenu class for submenus
class mgSubmenu:public mgMenu
{
public:
mgSubmenu::mgSubmenu();
//! \brief computes the title
std::string Title() const;
protected:
void BuildOsd ();
};
//! \brief an mgMenu class for selecting an order
class mgMenuOrders:public mgMenu
{
public:
//! \brief computes the title
std::string Title() const;
protected:
void BuildOsd ();
};
class mgMenuOrder : public mgMenu
{
public:
mgMenuOrder();
~mgMenuOrder();
//! \brief computes the title
std::string Title() const;
bool ChangeOrder(eKeys key);
void SaveOrder();
protected:
void BuildOsd ();
private:
void AddKeyActions(mgMenu *m,mgOrder *o);
mgOrder * m_order;
int m_orderbycount;
vector<int> m_keytypes;
vector < vector <const char*> > m_keynames;
};
//! \brief an mgMenu class for selecting a collection
class mgTreeCollSelector:public mgMenu
{
public:
mgTreeCollSelector();
~mgTreeCollSelector();
//! \brief computes the title
std::string Title() const;
protected:
void BuildOsd ();
virtual mgActions coll_action() = 0;
std::string m_title;
};
class mgTreeAddToCollSelector:public mgTreeCollSelector
{
public:
//! \brief computes the title
mgTreeAddToCollSelector(std::string title);
protected:
virtual mgActions coll_action() { return actAddCollEntry; }
};
//! \brief an mgMenu class for selecting a collection
class mgTreeRemoveFromCollSelector:public mgTreeCollSelector
{
public:
//! \brief computes the title
mgTreeRemoveFromCollSelector(std::string title);
protected:
virtual mgActions coll_action() { return actRemoveCollEntry; }
};
#endif
|