foobar2000 SDK  2015-08-03
playback_state.cpp
Go to the documentation of this file.
1 #include "stdafx.h"
2 #include "resource.h"
3 
4 class CPlaybackStateDemo : public CDialogImpl<CPlaybackStateDemo>, private play_callback_impl_base {
5 public:
6  enum {IDD = IDD_PLAYBACK_STATE};
7 
9  MSG_WM_INITDIALOG(OnInitDialog)
12  COMMAND_HANDLER_EX(IDC_PLAY, BN_CLICKED, OnPlayClicked)
13  COMMAND_HANDLER_EX(IDC_PAUSE, BN_CLICKED, OnPauseClicked)
14  COMMAND_HANDLER_EX(IDC_STOP, BN_CLICKED, OnStopClicked)
15  COMMAND_HANDLER_EX(IDC_PREV, BN_CLICKED, OnPrevClicked)
16  COMMAND_HANDLER_EX(IDC_NEXT, BN_CLICKED, OnNextClicked)
17  COMMAND_HANDLER_EX(IDC_RAND, BN_CLICKED, OnRandClicked)
18  MSG_WM_CONTEXTMENU(OnContextMenu)
19  END_MSG_MAP()
20 private:
21 
22  // Playback callback methods.
23  void on_playback_starting(play_control::t_track_command p_command,bool p_paused) {update();}
26  void on_playback_seek(double p_time) {update();}
27  void on_playback_pause(bool p_state) {update();}
29  void on_playback_dynamic_info(const file_info & p_info) {update();}
31  void on_playback_time(double p_time) {update();}
32  void on_volume_change(float p_new_val) {}
33 
34  void update();
35 
36  void OnPatternChange(UINT, int, CWindow);
37  void OnCancel(UINT, int, CWindow);
38 
39  void OnPlayClicked(UINT, int, CWindow) {m_playback_control->start();}
40  void OnStopClicked(UINT, int, CWindow) {m_playback_control->stop();}
41  void OnPauseClicked(UINT, int, CWindow) {m_playback_control->toggle_pause();}
45 
46  void OnContextMenu(CWindow wnd, CPoint point);
47 
48  BOOL OnInitDialog(CWindow, LPARAM);
49 
50  titleformat_object::ptr m_script;
51 
53 };
54 
55 void CPlaybackStateDemo::OnCancel(UINT, int, CWindow) {
56  DestroyWindow();
57 }
58 
59 void CPlaybackStateDemo::OnPatternChange(UINT, int, CWindow) {
60  m_script.release(); // pattern has changed, force script recompilation
61  update();
62 }
63 
65  update();
66  SetDlgItemText(IDC_PATTERN, _T("%codec% | %bitrate% kbps | %samplerate% Hz | %channels% | %playback_time%[ / %length%]$if(%ispaused%, | paused,)"));
67  ::ShowWindowCentered(*this,GetParent()); // Function declared in SDK helpers.
68  return TRUE;
69 }
70 
72  if (m_script.is_empty()) {
73  pfc::string8 pattern;
74  uGetDlgItemText(*this, IDC_PATTERN, pattern);
75  static_api_ptr_t<titleformat_compiler>()->compile_safe_ex(m_script, pattern);
76  }
78  if (m_playback_control->playback_format_title(NULL, state, m_script, NULL, playback_control::display_level_all)) {
79  //Succeeded already.
80  } else if (m_playback_control->is_playing()) {
81  //Starting playback but not done opening the first track yet.
82  state = "Opening...";
83  } else {
84  state = "Stopped.";
85  }
86  uSetDlgItemText(*this, IDC_STATE, state);
87 }
88 
89 void CPlaybackStateDemo::OnContextMenu(CWindow wnd, CPoint point) {
90  try {
91  if (wnd == GetDlgItem(IDC_CONTEXTMENU)) {
92 
93  // handle the context menu key case - center the menu
94  if (point == CPoint(-1, -1)) {
95  CRect rc;
96  WIN32_OP(wnd.GetWindowRect(&rc));
97  point = rc.CenterPoint();
98  }
99 
100  metadb_handle_list items;
101 
102  { // note: we would normally just use contextmenu_manager::init_context_now_playing(), but we go the "make the list ourselves" route to demonstrate how to invoke the menu for arbitrary items.
103  metadb_handle_ptr item;
104  if (m_playback_control->get_now_playing(item)) items += item;
105  }
106 
107  CMenuDescriptionHybrid menudesc(*this); //this class manages all the voodoo necessary for descriptions of our menu items to show in the status bar.
108 
110  CMenu menu;
111  WIN32_OP(menu.CreatePopupMenu());
112  enum {
113  ID_TESTCMD = 1,
114  ID_CM_BASE,
115  };
116  menu.AppendMenu(MF_STRING, ID_TESTCMD, _T("Test command"));
117  menudesc.Set(ID_TESTCMD, "This is a test command.");
118  menu.AppendMenu(MF_SEPARATOR);
119 
120  if (items.get_count() > 0) {
121  api->init_context(items, 0);
122  api->win32_build_menu(menu, ID_CM_BASE, ~0);
123  menudesc.SetCM(api.get_ptr(), ID_CM_BASE, ~0);
124  } else {
125  menu.AppendMenu(MF_STRING|MF_GRAYED|MF_DISABLED, (UINT)0, _T("No items selected"));
126  }
127 
128  int cmd = menu.TrackPopupMenu(TPM_RIGHTBUTTON|TPM_NONOTIFY|TPM_RETURNCMD,point.x,point.y,menudesc,0);
129  if (cmd > 0) {
130  if (cmd >= ID_CM_BASE) {
131  api->execute_by_id(cmd - ID_CM_BASE);
132  } else switch(cmd) {
133  case ID_TESTCMD:
134  popup_message::g_show("Blah!", "Test");
135  break;
136  }
137  }
138 
139  }
140  } catch(std::exception const & e) {
141  console::complain("Context menu failure", e); //rare
142  }
143 }
144 
146  try {
147  // ImplementModelessTracking registers our dialog to receive dialog messages thru main app loop's IsDialogMessage().
148  // CWindowAutoLifetime creates the window in the constructor (taking the parent window as a parameter) and deletes the object when the window has been destroyed (through WTL's OnFinalMessage).
150  } catch(std::exception const & e) {
151  popup_message::g_complain("Dialog creation failure", e);
152  }
153 }
t_interface * get_ptr() const
Definition: service.h:541
void OnPauseClicked(UINT, int, CWindow)
void on_playback_dynamic_info_track(const file_info &p_info)
Per-track dynamic info (stream track titles etc) change. Happens less often than on_playback_dynamic_...
BOOL SHARED_EXPORT uSetDlgItemText(HWND wnd, UINT id, const char *p_text)
Implementation helper.
Definition: play_callback.h:70
OnPatternChange BN_CLICKED
void OnPrevClicked(UINT, int, CWindow)
void on_playback_edited(metadb_handle_ptr p_track)
Called when currently played file gets edited.
void on_playback_dynamic_info(const file_info &p_info)
Dynamic info (VBR bitrate etc) change.
void OnStopClicked(UINT, int, CWindow)
typedef BOOL(WINAPI *pPowerSetRequest_t)(__in HANDLE PowerRequest
static_api_ptr_t< playback_control > m_playback_control
BOOL SHARED_EXPORT uGetDlgItemText(HWND wnd, UINT id, pfc::string_base &out)
OnPatternChange COMMAND_HANDLER_EX(IDCANCEL, BN_CLICKED, OnCancel) COMMAND_HANDLER_EX(IDC_PLAY
t_size get_count() const
Definition: list.h:365
Plays the next track from the current playlist according to the current playback order.
display_level_titles + timing + VBR bitrate display etc
void on_playback_time(double p_time)
Called every second, for time display.
void RunPlaybackStateDemo()
void complain(const char *what, const char *msg)
Definition: console.cpp:21
static BOOL ShowWindowCentered(CWindow wnd, CWindow wndParent)
Provides control for various playback-related operations. All methods provided by this interface work...
void Set(unsigned id, const char *desc)
Definition: misc.h:63
Main interface class for information about some playable object.
Definition: file_info.h:73
void on_playback_pause(bool p_state)
Called on pause/unpause.
void on_volume_change(float p_new_val)
User changed volume settings. Possibly called when not playing.
string8_fastalloc string_formatter
Definition: string_base.h:615
void on_playback_new_track(metadb_handle_ptr p_track)
Playback advanced to new track.
void OnCancel(UINT, int, CWindow)
BOOL OnInitDialog(CWindow, LPARAM)
void on_playback_seek(double p_time)
User has seeked to specific time.
void OnRandClicked(UINT, int, CWindow)
static void g_show(const char *p_msg, const char *p_title, t_icon p_icon=icon_information)
Static helper function instantiating the service and activating the message dialog. See show() for description of parameters.
Definition: popup_message.h:26
std::exception exception
Definition: primitives.h:193
void on_playback_stop(play_control::t_stop_reason p_reason)
Playback stopped.
void OnPlayClicked(UINT, int, CWindow)
void SetCM(contextmenu_manager::ptr mgr, unsigned base, unsigned max)
Definition: misc.h:65
HWND get_main_window()
Retrieves main app window. WARNING: this is provided for parent of dialog windows and such only; usin...
static void g_complain(const char *what)
void OnNextClicked(UINT, int, CWindow)
void OnPatternChange(UINT, int, CWindow)
void OnContextMenu(CWindow wnd, CPoint point)
BEGIN_MSG_MAP(CPlaybackStateDemo) MSG_WM_INITDIALOG(OnInitDialog) COMMAND_HANDLER_EX(IDC_PATTERN
Plays a random track from the current playlist.
titleformat_object::ptr m_script
void on_playback_starting(play_control::t_track_command p_command, bool p_paused)
Playback process is being initialized. on_playback_new_track() should be called soon after this when ...
Definition: play_callback.h:83
Plays the previous track from the current playlist according to the current playback order...