+ wxMediaPlayerNotebookPage* currentpage =
+ (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage();
+
+ if (currentpage->m_playlist->GetItemCount() == 0)
+ return;
+
+ wxInt32 nLastSelectedItem = -1;
+ while(true)
+ {
+ wxInt32 nSelectedItem = currentpage->m_playlist->GetNextItem(nLastSelectedItem,
+ wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
+ if (nSelectedItem == -1)
+ break;
+ nLastSelectedItem = nSelectedItem;
+ currentpage->m_playlist->SetItemState(nSelectedItem, 0, wxLIST_STATE_SELECTED);
+ }
+
+ if (nLastSelectedItem == -1)
+ {
+ //nothing selected, default to the file before the currently playing one
+ if(currentpage->m_nLastFileId == 0)
+ nLastSelectedItem = currentpage->m_playlist->GetItemCount() - 1;
+ else
+ nLastSelectedItem = currentpage->m_nLastFileId - 1;
+ }
+ else if (nLastSelectedItem == 0)
+ nLastSelectedItem = currentpage->m_playlist->GetItemCount() - 1;
+ else
+ nLastSelectedItem -= 1;
+
+ if(nLastSelectedItem == currentpage->m_nLastFileId)
+ return; //already playing... nothing to do
+
+ wxListItem listitem;
+ listitem.SetId(nLastSelectedItem);
+ listitem.SetMask(wxLIST_MASK_TEXT | wxLIST_MASK_DATA);
+ currentpage->m_playlist->GetItem(listitem);
+ listitem.SetMask(listitem.GetMask() | wxLIST_MASK_STATE);
+ listitem.SetState(listitem.GetState() | wxLIST_STATE_SELECTED);
+ currentpage->m_playlist->SetItem(listitem);
+
+ wxASSERT(listitem.GetData());
+ DoPlayFile((*((wxString*) listitem.GetData())));
+}
+
+// ----------------------------------------------------------------------------
+// wxMediaPlayerFrame::OnNext
+//
+// Tedious wxListCtrl stuff. Goes to next song in list, or if at the
+// end goes to the first in the list.
+// ----------------------------------------------------------------------------
+void wxMediaPlayerFrame::OnNext(wxCommandEvent& WXUNUSED(event))
+{
+ wxMediaPlayerNotebookPage* currentpage =
+ (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage();
+
+ if (currentpage->m_playlist->GetItemCount() == 0)
+ return;
+
+ wxInt32 nLastSelectedItem = -1;
+ while(true)
+ {
+ wxInt32 nSelectedItem = currentpage->m_playlist->GetNextItem(nLastSelectedItem,
+ wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
+ if (nSelectedItem == -1)
+ break;
+ nLastSelectedItem = nSelectedItem;
+ currentpage->m_playlist->SetItemState(nSelectedItem, 0, wxLIST_STATE_SELECTED);
+ }
+
+ if (nLastSelectedItem == -1)
+ {
+ if(currentpage->m_nLastFileId == currentpage->m_playlist->GetItemCount() - 1)
+ nLastSelectedItem = 0;
+ else
+ nLastSelectedItem = currentpage->m_nLastFileId + 1;
+ }
+ else if (nLastSelectedItem == currentpage->m_playlist->GetItemCount() - 1)
+ nLastSelectedItem = 0;
+ else
+ nLastSelectedItem += 1;
+
+ if(nLastSelectedItem == currentpage->m_nLastFileId)
+ return; //already playing... nothing to do
+
+ wxListItem listitem;
+ listitem.SetMask(wxLIST_MASK_TEXT | wxLIST_MASK_DATA);
+ listitem.SetId(nLastSelectedItem);
+ currentpage->m_playlist->GetItem(listitem);
+ listitem.SetMask(listitem.GetMask() | wxLIST_MASK_STATE);
+ listitem.SetState(listitem.GetState() | wxLIST_STATE_SELECTED);
+ currentpage->m_playlist->SetItem(listitem);
+
+ wxASSERT(listitem.GetData());
+ DoPlayFile((*((wxString*) listitem.GetData())));
+}
+
+
+// ----------------------------------------------------------------------------
+// wxMediaPlayerFrame::OnVolumeDown
+//
+// Lowers the volume of the media control by 10%
+// ----------------------------------------------------------------------------
+void wxMediaPlayerFrame::OnVolumeDown(wxCommandEvent& WXUNUSED(event))
+{
+ wxMediaPlayerNotebookPage* currentpage =
+ (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage();
+
+ double dVolume = currentpage->m_mediactrl->GetVolume();
+ currentpage->m_mediactrl->SetVolume(dVolume < 0.1 ? 0.0 : dVolume - .1);
+}
+
+// ----------------------------------------------------------------------------
+// wxMediaPlayerFrame::OnVolumeUp
+//
+// Increases the volume of the media control by 10%
+// ----------------------------------------------------------------------------
+void wxMediaPlayerFrame::OnVolumeUp(wxCommandEvent& WXUNUSED(event))
+{
+ wxMediaPlayerNotebookPage* currentpage =
+ (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage();
+
+ double dVolume = currentpage->m_mediactrl->GetVolume();
+ currentpage->m_mediactrl->SetVolume(dVolume > 0.9 ? 1.0 : dVolume + .1);
+}
+
+// ----------------------------------------------------------------------------
+// wxMediaPlayerFrame::OnPageChange
+//
+// Called when the user changes the current notebook page shown
+// ----------------------------------------------------------------------------
+void wxMediaPlayerFrame::OnPageChange(wxNotebookEvent& WXUNUSED(event))
+{
+ ResetStatus();
+}
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+//
+// wxMediaPlayerTimer
+//
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+// ----------------------------------------------------------------------------
+// wxMediaPlayerTimer::Notify
+//
+// 1) Update our slider with the position were are in in the media
+// 2) Update our status bar with the base text from wxMediaPlayerFrame::ResetStatus,
+// append some non-static (changing) info to it, then set the
+// status bar text to that result
+// ----------------------------------------------------------------------------
+void wxMediaPlayerTimer::Notify()
+{
+ wxMediaPlayerNotebookPage* currentpage =
+ (wxMediaPlayerNotebookPage*) m_frame->m_notebook->GetCurrentPage();
+
+ if(currentpage)
+ {
+ // if the slider is being dragged then update it with the song position
+ if(currentpage->IsBeingDragged() == false)
+ {
+ long lPosition = (long)( currentpage->m_mediactrl->Tell() / 1000 );
+ currentpage->m_slider->SetValue(lPosition);
+ }
+
+ // update guage with value from slider
+ currentpage->m_gauge->SetValue(currentpage->m_slider->GetValue());
+#if wxUSE_STATUSBAR
+ m_frame->SetStatusText(wxString::Format(
+ wxT("%s Pos:%u State:%s Loops:%i D/T:[%i]/[%i] V:%i%%"),
+ m_frame->m_basestatus.c_str(),
+ currentpage->m_slider->GetValue(),
+ wxGetMediaStateText(currentpage->m_mediactrl->GetState()),
+ currentpage->m_nLoops,
+ (int)currentpage->m_mediactrl->GetDownloadProgress(),
+ (int)currentpage->m_mediactrl->GetDownloadTotal(),
+ (int)(currentpage->m_mediactrl->GetVolume() * 100)));
+#endif // wxUSE_STATUSBAR
+ }
+}
+
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+//
+// wxMediaPlayerNotebookPage
+//
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+// ----------------------------------------------------------------------------
+// wxMediaPlayerNotebookPage Constructor
+//
+// Creates a media control and slider and adds it to this panel,
+// along with some sizers for positioning
+// ----------------------------------------------------------------------------
+wxMediaPlayerNotebookPage::wxMediaPlayerNotebookPage(wxMediaPlayerFrame* parentFrame,
+ wxNotebook* theBook,
+ const wxString& szBackend)
+ : wxPanel(theBook, wxID_ANY),
+ m_nLastFileId(-1),
+ m_nLoops(0),
+ m_bLoop(false),
+ m_bIsBeingDragged(false),
+ m_parentFrame(parentFrame)
+{
+
+ //
+ // Layout
+ //
+ // [wxMediaCtrl]
+ // [playlist]
+ // [5 control buttons]
+ // [slider]
+ // [gauge]
+ //
+
+ //
+ // Create and attach the sizer
+ //
+ wxFlexGridSizer* sizer = new wxFlexGridSizer(2, 1, 0, 0);
+ this->SetSizer(sizer);
+ this->SetAutoLayout(true);
+ sizer->AddGrowableRow(0);
+ sizer->AddGrowableCol(0);
+
+ //
+ // Create our media control
+ //
+ m_mediactrl = new wxMediaCtrl();
+
+ // Make sure creation was successful
+ bool bOK = m_mediactrl->Create(this, wxID_MEDIACTRL, wxEmptyString,
+ wxDefaultPosition, wxDefaultSize, 0,
+//you could specify a macrod backend here like
+//wxMEDIABACKEND_QUICKTIME);
+ szBackend);
+//you could change the cursor here like
+// m_mediactrl->SetCursor(wxCURSOR_BLANK);
+//note that this may not effect it if SetPlayerControls
+//is set to something else than wxMEDIACTRLPLAYERCONTROLS_NONE
+ wxASSERT_MSG(bOK, wxT("Could not create media control!"));
+ wxUnusedVar(bOK);
+
+ sizer->Add(m_mediactrl, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 5);
+
+ //
+ // Create the playlist/listctrl
+ //
+ m_playlist = new wxMediaPlayerListCtrl();
+ m_playlist->Create(this, wxID_LISTCTRL, wxDefaultPosition,
+ wxDefaultSize,
+ wxLC_REPORT //wxLC_LIST
+ | wxSUNKEN_BORDER);
+
+ // Set the background of our listctrl to white
+ m_playlist->SetBackgroundColour(wxColour(255,255,255));
+
+ // The layout of the headers of the listctrl are like
+ // | | File | Length
+ //
+ // Where Column one is a character representing the state the file is in:
+ // * - not the current file
+ // E - Error has occured
+ // > - Currently Playing
+ // [] - Stopped
+ // || - Paused
+ // (( - Volume Down 10%
+ // )) - Volume Up 10%
+ //
+ // Column two is the name of the file
+ //
+ // Column three is the length in seconds of the file
+ m_playlist->InsertColumn(0,_(""), wxLIST_FORMAT_CENTER, 20);
+ m_playlist->InsertColumn(1,_("File"), wxLIST_FORMAT_LEFT, /*wxLIST_AUTOSIZE_USEHEADER*/305);
+ m_playlist->InsertColumn(2,_("Length"), wxLIST_FORMAT_CENTER, 75);
+
+#if wxUSE_DRAG_AND_DROP
+ m_playlist->SetDropTarget(new wxPlayListDropTarget(*m_playlist));
+#endif
+
+ sizer->Add(m_playlist, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 5);
+
+ //
+ // Create the control buttons
+ // TODO/FIXME/HACK: This part about sizers is really a nice hack
+ // and probably isn't proper
+ //
+ wxBoxSizer* horsizer1 = new wxBoxSizer(wxHORIZONTAL);
+ wxBoxSizer* vertsizer = new wxBoxSizer(wxHORIZONTAL);
+
+ m_prevButton = new wxButton();
+ m_playButton = new wxButton();
+ m_stopButton = new wxButton();
+ m_nextButton = new wxButton();
+ m_vdButton = new wxButton();
+ m_vuButton = new wxButton();
+
+ m_prevButton->Create(this, wxID_BUTTONPREV, wxT("|<"));
+ m_playButton->Create(this, wxID_BUTTONPLAY, wxT(">"));
+ m_stopButton->Create(this, wxID_BUTTONSTOP, wxT("[]"));
+ m_nextButton->Create(this, wxID_BUTTONNEXT, wxT(">|"));
+ m_vdButton->Create(this, wxID_BUTTONVD, wxT("(("));
+ m_vuButton->Create(this, wxID_BUTTONVU, wxT("))"));
+ vertsizer->Add(m_prevButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
+ vertsizer->Add(m_playButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
+ vertsizer->Add(m_stopButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
+ vertsizer->Add(m_nextButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
+ vertsizer->Add(m_vdButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
+ vertsizer->Add(m_vuButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
+ horsizer1->Add(vertsizer, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
+ sizer->Add(horsizer1, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
+
+
+ //
+ // Create our slider
+ //
+ m_slider = new wxSlider(this, wxID_SLIDER, 0, //init
+ 0, //start
+ 0, //end
+ wxDefaultPosition, wxDefaultSize,
+ wxSL_HORIZONTAL );
+ sizer->Add(m_slider, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND , 5);
+
+
+ //
+ // Create the gauge
+ //
+ m_gauge = new wxGauge();
+ m_gauge->Create(this, wxID_GAUGE, 0, wxDefaultPosition, wxDefaultSize,
+ wxGA_HORIZONTAL | wxGA_SMOOTH);
+ sizer->Add(m_gauge, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND , 5);
+
+ //
+ // ListCtrl events
+ //
+ this->Connect( wxID_LISTCTRL, wxEVT_COMMAND_LIST_ITEM_ACTIVATED,
+ wxListEventHandler(wxMediaPlayerFrame::OnChangeSong),
+ (wxObject*)0, parentFrame);
+
+ //
+ // Slider events
+ //
+ this->Connect(wxID_SLIDER, wxEVT_SCROLL_THUMBTRACK,
+ wxScrollEventHandler(wxMediaPlayerNotebookPage::OnBeginSeek));
+ this->Connect(wxID_SLIDER, wxEVT_SCROLL_THUMBRELEASE,
+ wxScrollEventHandler(wxMediaPlayerNotebookPage::OnEndSeek));
+
+ //
+ // Media Control events
+ //
+ this->Connect(wxID_MEDIACTRL, wxEVT_MEDIA_FINISHED,
+ wxMediaEventHandler(wxMediaPlayerNotebookPage::OnMediaFinished));
+ this->Connect(wxID_MEDIACTRL, wxEVT_MEDIA_LOADED,
+ wxMediaEventHandler(wxMediaPlayerFrame::OnMediaLoaded),
+ (wxObject*)0, parentFrame);
+
+ //
+ // Button events
+ //
+ this->Connect( wxID_BUTTONPREV, wxEVT_COMMAND_BUTTON_CLICKED,
+ wxCommandEventHandler(wxMediaPlayerFrame::OnPrev),
+ (wxObject*)0, parentFrame);
+ this->Connect( wxID_BUTTONPLAY, wxEVT_COMMAND_BUTTON_CLICKED,
+ wxCommandEventHandler(wxMediaPlayerFrame::OnPlay),
+ (wxObject*)0, parentFrame);
+ this->Connect( wxID_BUTTONSTOP, wxEVT_COMMAND_BUTTON_CLICKED,
+ wxCommandEventHandler(wxMediaPlayerFrame::OnStop),
+ (wxObject*)0, parentFrame);
+ this->Connect( wxID_BUTTONNEXT, wxEVT_COMMAND_BUTTON_CLICKED,
+ wxCommandEventHandler(wxMediaPlayerFrame::OnNext),
+ (wxObject*)0, parentFrame);
+ this->Connect( wxID_BUTTONVD, wxEVT_COMMAND_BUTTON_CLICKED,
+ wxCommandEventHandler(wxMediaPlayerFrame::OnVolumeDown),
+ (wxObject*)0, parentFrame);
+ this->Connect( wxID_BUTTONVU, wxEVT_COMMAND_BUTTON_CLICKED,
+ wxCommandEventHandler(wxMediaPlayerFrame::OnVolumeUp),
+ (wxObject*)0, parentFrame);
+}
+
+// ----------------------------------------------------------------------------
+// MyNotebook::OnBeginSeek
+//
+// Sets m_bIsBeingDragged to true to stop the timer from changing the position
+// of our slider
+// ----------------------------------------------------------------------------
+void wxMediaPlayerNotebookPage::OnBeginSeek(wxScrollEvent& WXUNUSED(event))
+{
+ m_bIsBeingDragged = true;
+}
+
+// ----------------------------------------------------------------------------
+// MyNotebook::OnEndSeek
+//
+// Called from file->seek.
+// Called when the user moves the slider -
+// seeks to a position within the media
+// then sets m_bIsBeingDragged to false to ok the timer to change the position
+// ----------------------------------------------------------------------------
+void wxMediaPlayerNotebookPage::OnEndSeek(wxScrollEvent& WXUNUSED(event))
+{
+ if( m_mediactrl->Seek(
+ m_slider->GetValue() * 1000
+ ) == wxInvalidOffset )