diff --git a/meson.build b/meson.build index eb433d3..5cab9d0 100755 --- a/meson.build +++ b/meson.build @@ -144,6 +144,7 @@ src = [ 'src/App.cpp', 'src/GUI/MainFrame.cpp', + 'src/GUI/TransportControls.cpp', 'src/GUI/WaveformViewer.cpp', 'src/GUI/Dialogs/Settings.cpp', diff --git a/src/GUI/Dialogs/Settings.cpp b/src/GUI/Dialogs/Settings.cpp index 81792e6..0ebe625 100644 --- a/src/GUI/Dialogs/Settings.cpp +++ b/src/GUI/Dialogs/Settings.cpp @@ -19,7 +19,7 @@ */ #include "GUI/Dialogs/Settings.hpp" -#include "Utility/ControlID_Enums.hpp" +#include "Utility/ControlIDs.hpp" #include "Utility/Serialize.hpp" #include "Utility/Log.hpp" #include "Utility/Paths.hpp" diff --git a/src/GUI/Dialogs/TagEditor.cpp b/src/GUI/Dialogs/TagEditor.cpp index d09338f..993a595 100644 --- a/src/GUI/Dialogs/TagEditor.cpp +++ b/src/GUI/Dialogs/TagEditor.cpp @@ -18,7 +18,7 @@ * along with this program. If not, see . */ -#include "Utility/ControlID_Enums.hpp" +#include "Utility/ControlIDs.hpp" #include "Utility/SH_Event.hpp" #include "Utility/Log.hpp" #include "Utility/Paths.hpp" diff --git a/src/GUI/MainFrame.cpp b/src/GUI/MainFrame.cpp index ffe1b6e..d83d532 100644 --- a/src/GUI/MainFrame.cpp +++ b/src/GUI/MainFrame.cpp @@ -22,7 +22,7 @@ #include "GUI/Dialogs/Settings.hpp" #include "GUI/Dialogs/TagEditor.hpp" #include "Database/Database.hpp" -#include "Utility/ControlID_Enums.hpp" +#include "Utility/ControlIDs.hpp" #include "Utility/Paths.hpp" #include "Utility/Tags.hpp" #include "Utility/Sample.hpp" @@ -140,7 +140,6 @@ MainFrame::MainFrame() m_TopPanelMainSizer = new wxBoxSizer(wxVERTICAL); m_BottomRightPanelMainSizer = new wxBoxSizer(wxVERTICAL); - m_BrowserControlSizer = new wxBoxSizer(wxHORIZONTAL); m_WaveformDisplaySizer = new wxBoxSizer(wxHORIZONTAL); m_HivesMainSizer = new wxBoxSizer(wxVERTICAL); @@ -230,78 +229,6 @@ MainFrame::MainFrame() m_TopSplitter->SplitHorizontally(m_TopPanel, m_BottomSplitter); m_BottomSplitter->SplitVertically(m_BottomLeftPanel, m_BottomRightPanel); - m_TopControlsPanel = new wxPanel(m_TopPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, - wxTAB_TRAVERSAL | wxNO_BORDER); - - // Looping region controls - if (m_Theme.IsDark()) - m_LoopABButton = new wxBitmapToggleButton(m_TopControlsPanel, BC_LoopABButton, - static_cast(ICON_AB_LIGHT_16px), - wxDefaultPosition, wxDefaultSize, 0); - else - m_LoopABButton = new wxBitmapToggleButton(m_TopControlsPanel, BC_LoopABButton, - static_cast(ICON_AB_DARK_16px), - wxDefaultPosition, wxDefaultSize, 0); - - m_LoopABButton->SetToolTip(_("Loop selected region")); - - // Initializing browser controls on top panel. - m_AutoPlayCheck = new wxCheckBox(m_TopControlsPanel, BC_Autoplay, _("Autoplay"), - wxDefaultPosition, wxDefaultSize, wxCHK_2STATE); - m_AutoPlayCheck->SetToolTip(_("Autoplay")); - m_VolumeSlider = new wxSlider(m_TopControlsPanel, BC_Volume, 100, 0, 100, - wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL); - m_VolumeSlider->SetToolTip(_("Volume")); - m_VolumeSlider->SetMinSize(wxSize(120, -1)); - m_VolumeSlider->SetMaxSize(wxSize(120, -1)); - m_SamplePosition = new wxStaticText(m_TopControlsPanel, BC_SamplePosition, "--:--/--:--", - wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE_HORIZONTAL); - - // Initialize browser control buttons - if (m_Theme.IsDark()) - { - m_PlayButton = new wxBitmapButton(m_TopControlsPanel, BC_Play, - wxBitmapBundle::FromBitmap(static_cast - (ICON_PLAY_LIGHT_16px)), - wxDefaultPosition, wxDefaultSize, 0); - m_LoopButton = new wxBitmapToggleButton(m_TopControlsPanel, BC_Loop, - static_cast(ICON_LOOP_LIGHT_16px), - wxDefaultPosition, wxDefaultSize, 0); - m_StopButton = new wxBitmapButton(m_TopControlsPanel, BC_Stop, - wxBitmapBundle::FromBitmap(static_cast - (ICON_STOP_LIGHT_16px)), - wxDefaultPosition, wxDefaultSize, 0); - m_MuteButton = new wxBitmapToggleButton(m_TopControlsPanel, BC_Mute, - static_cast(ICON_MUTE_LIGHT_16px), - wxDefaultPosition, wxDefaultSize, 0); - } - else - { - m_PlayButton = new wxBitmapButton(m_TopControlsPanel, BC_Play, - wxBitmapBundle::FromBitmap(static_cast - (ICON_PLAY_DARK_16px)), - wxDefaultPosition, wxDefaultSize, 0); - m_LoopButton = new wxBitmapToggleButton(m_TopControlsPanel, BC_Loop, - static_cast(ICON_LOOP_DARK_16px), - wxDefaultPosition, wxDefaultSize, 0); - m_StopButton = new wxBitmapButton(m_TopControlsPanel, BC_Stop, - wxBitmapBundle::FromBitmap(static_cast - (ICON_STOP_DARK_16px)), - wxDefaultPosition, wxDefaultSize, 0); - m_MuteButton = new wxBitmapToggleButton(m_TopControlsPanel, BC_Mute, - static_cast(ICON_MUTE_DARK_16px), - wxDefaultPosition, wxDefaultSize, 0); - } - - m_PlayButton->SetToolTip(_("Play")); - m_LoopButton->SetToolTip(_("Loop")); - m_StopButton->SetToolTip(_("Stop")); - m_MuteButton->SetToolTip(_("Mute")); - - m_SettingsButton = new wxButton(m_TopControlsPanel, BC_Settings, _("Settings"), - wxDefaultPosition, wxDefaultSize, 0); - m_SettingsButton->SetToolTip(_("Settings")); - // Initializing wxSearchCtrl on bottom panel. m_SearchBox = new wxSearchCtrl(m_BottomRightPanel, BC_Search, _("Search for samples.."), wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER); @@ -413,7 +340,8 @@ MainFrame::MainFrame() SH_LOG_ERROR("Error! Cannot initialize database {}", e.what()); } - m_TopWaveformPanel = new WaveformViewer(m_TopPanel, *m_Library, *m_MediaCtrl, *m_Database); + m_TransportControls = new TransportControls(m_TopPanel, *m_Library, *m_MediaCtrl, *m_Timer); + m_WaveformViewer = new WaveformViewer(m_TopPanel, *m_Library, *m_MediaCtrl, *m_Database); // Binding events. Bind(wxEVT_MENU, &MainFrame::OnSelectAddFile, this, MN_AddFile); @@ -437,15 +365,10 @@ MainFrame::MainFrame() Bind(wxEVT_DIRCTRL_FILEACTIVATED, &MainFrame::OnClickDirCtrl, this, BC_DirCtrl); Bind(wxEVT_TREE_BEGIN_DRAG, &MainFrame::OnDragFromDirCtrl, this, m_DirCtrl->GetTreeCtrl()->GetId()); - Bind(wxEVT_BUTTON, &MainFrame::OnClickPlay, this, BC_Play); - Bind(wxEVT_TOGGLEBUTTON, &MainFrame::OnClickLoop, this, BC_Loop); - Bind(wxEVT_BUTTON, &MainFrame::OnClickStop, this, BC_Stop); - Bind(wxEVT_TOGGLEBUTTON, &MainFrame::OnClickMute, this, BC_Mute); + Bind(SampleHive::SH_EVT_CALL_FUNC_PLAY, &MainFrame::OnRecieveCallFunctionPlay, this); + Bind(wxEVT_MEDIA_FINISHED, &MainFrame::OnMediaFinished, this, BC_MediaCtrl); Bind(wxEVT_BUTTON, &MainFrame::OnClickSettings, this, BC_Settings); - Bind(wxEVT_CHECKBOX, &MainFrame::OnCheckAutoplay, this, BC_Autoplay); - Bind(wxEVT_SCROLL_THUMBTRACK, &MainFrame::OnSlideVolume, this, BC_Volume); - Bind(wxEVT_SCROLL_THUMBRELEASE, &MainFrame::OnReleaseVolumeSlider, this, BC_Volume); Bind(wxEVT_TIMER, &MainFrame::UpdateElapsedTime, this); @@ -483,20 +406,8 @@ MainFrame::MainFrame() m_TopSizer->Add(m_TopSplitter, 1, wxALL | wxEXPAND, 0); - m_BrowserControlSizer->Add(m_PlayButton, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2); - m_BrowserControlSizer->Add(m_StopButton, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2); - m_BrowserControlSizer->Add(m_LoopButton, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2); - m_BrowserControlSizer->Add(m_LoopABButton, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2); - m_BrowserControlSizer->Add(m_SettingsButton, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2); - m_BrowserControlSizer->Add(0,0,1, wxALL | wxEXPAND, 0); - m_BrowserControlSizer->Add(m_SamplePosition, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2); - m_BrowserControlSizer->Add(30,0,0, wxALL | wxEXPAND, 0); - m_BrowserControlSizer->Add(m_MuteButton, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2); - m_BrowserControlSizer->Add(m_VolumeSlider, 1, wxALL | wxALIGN_CENTER_VERTICAL, 2); - m_BrowserControlSizer->Add(m_AutoPlayCheck, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2); - - m_TopPanelMainSizer->Add(m_TopWaveformPanel, 1, wxALL | wxEXPAND, 2); - m_TopPanelMainSizer->Add(m_TopControlsPanel, 0, wxALL | wxEXPAND, 2); + m_TopPanelMainSizer->Add(m_WaveformViewer, 1, wxALL | wxEXPAND, 2); + m_TopPanelMainSizer->Add(m_TransportControls, 0, wxALL | wxEXPAND, 2); m_BottomLeftPanelMainSizer->Add(m_Notebook, 1, wxALL | wxEXPAND, 0); @@ -529,14 +440,9 @@ MainFrame::MainFrame() m_TopSizer->SetSizeHints(m_MainPanel); m_TopSizer->Layout(); - m_TopControlsPanel->SetSizer(m_BrowserControlSizer); - m_BrowserControlSizer->Fit(m_TopControlsPanel); - m_BrowserControlSizer->SetSizeHints(m_TopControlsPanel); - m_BrowserControlSizer->Layout(); - - m_TopWaveformPanel->SetSizer(m_WaveformDisplaySizer); - m_WaveformDisplaySizer->Fit(m_TopWaveformPanel); - m_WaveformDisplaySizer->SetSizeHints(m_TopWaveformPanel); + m_WaveformViewer->SetSizer(m_WaveformDisplaySizer); + m_WaveformDisplaySizer->Fit(m_WaveformViewer); + m_WaveformDisplaySizer->SetSizeHints(m_WaveformViewer); m_WaveformDisplaySizer->Layout(); // Sizer for TopPanel @@ -590,7 +496,7 @@ void MainFrame::OnClickSettings(wxCommandEvent& event) } if (settings->IsWaveformColourChanged()) { - m_TopWaveformPanel->ResetDC(); + m_WaveformViewer->ResetDC(); } break; case wxID_CANCEL: @@ -937,71 +843,9 @@ void MainFrame::OnDragFromLibrary(wxDataViewEvent& event) SH_LOG_DEBUG("Started dragging '{}'.", sample_path); } -void MainFrame::OnClickPlay(wxCommandEvent& event) -{ - bStopped = false; - - int selected_row = m_Library->GetSelectedRow(); - - if (selected_row < 0) - return; - - wxString selection = m_Library->GetTextValue(selected_row, 1); - - wxString sample_path = GetFilenamePathAndExtension(selection).Path; - - if (bLoopPointsSet && m_LoopABButton->GetValue()) - PlaySample(sample_path.ToStdString(), selection.ToStdString(), true, m_LoopA.ToDouble(), wxFromStart); - else - PlaySample(sample_path.ToStdString(), selection.ToStdString()); -} - -void MainFrame::OnClickLoop(wxCommandEvent& event) -{ - Serializer serializer; - - bLoop = m_LoopButton->GetValue(); - - serializer.SerializeMediaOptions("loop", bLoop); -} - -void MainFrame::OnClickStop(wxCommandEvent& event) -{ - m_MediaCtrl->Stop(); - - bStopped = true; - - if (m_Timer->IsRunning()) - m_Timer->Stop(); - - m_SamplePosition->SetLabel("--:--/--:--"); - - this->SetStatusText(_("Stopped"), 1); -} - -void MainFrame::OnClickMute(wxCommandEvent& event) -{ - Serializer serializer; - - if (m_MuteButton->GetValue()) - { - m_MediaCtrl->SetVolume(0.0); - bMuted = true; - - serializer.SerializeMediaOptions("muted", bMuted); - } - else - { - m_MediaCtrl->SetVolume(double(m_VolumeSlider->GetValue()) / 100); - bMuted = false; - - serializer.SerializeMediaOptions("muted", bMuted); - } -} - void MainFrame::OnMediaFinished(wxMediaEvent& event) { - if (bLoop) + if (m_TransportControls->CanLoop()) { if (!m_MediaCtrl->Play()) { @@ -1019,7 +863,7 @@ void MainFrame::OnMediaFinished(wxMediaEvent& event) SH_LOG_DEBUG("TIMER STOPPED"); } - m_SamplePosition->SetLabel("--:--/--:--"); + m_TransportControls->SetSamplePositionText("--:--/--:--"); PopStatusText(1); this->SetStatusText(_("Stopped"), 1); } @@ -1043,64 +887,17 @@ void MainFrame::UpdateElapsedTime(wxTimerEvent& event) duration.Printf(wxT("%2i:%02i"), total_min, total_sec); position.Printf(wxT("%2i:%02i"), current_min, current_sec); - m_SamplePosition->SetLabel(wxString::Format(wxT("%s/%s"), position.c_str(), duration.c_str())); + m_TransportControls->SetSamplePositionText(wxString::Format(wxT("%s/%s"), + position.c_str(), duration.c_str())); - m_TopControlsPanel->Refresh(); - m_TopWaveformPanel->Refresh(); + m_TransportControls->Refresh(); + m_WaveformViewer->Refresh(); - if (bLoopPointsSet && m_LoopABButton->GetValue()) + if (bLoopPointsSet && m_TransportControls->IsLoopABOn()) if (static_cast(m_MediaCtrl->Tell()) >= m_LoopB.ToDouble()) m_MediaCtrl->Seek(m_LoopA.ToDouble(), wxFromStart); } -void MainFrame::OnCheckAutoplay(wxCommandEvent& event) -{ - Serializer serializer; - - if (m_AutoPlayCheck->GetValue()) - { - bAutoplay = true; - - serializer.SerializeMediaOptions("autoplay", bAutoplay); - } - else - { - bAutoplay = false; - - serializer.SerializeMediaOptions("autoplay", bAutoplay); - } -} - -void MainFrame::OnSlideVolume(wxScrollEvent& event) -{ - m_MediaCtrl->SetVolume(double(m_VolumeSlider->GetValue()) / 100); - - PushStatusText(wxString::Format(_("Volume: %d"), m_VolumeSlider->GetValue()), 1); -} - -void MainFrame::OnReleaseVolumeSlider(wxScrollEvent& event) -{ - Serializer serializer; - - serializer.SerializeMediaVolume(m_VolumeSlider->GetValue()); - - int selected_row = m_Library->GetSelectedRow(); - - if (selected_row < 0) - return; - - wxString selection = m_Library->GetTextValue(selected_row, 1); - - // Wait a second then remove the status from statusbar - wxSleep(1); - PopStatusText(1); - - if (m_MediaCtrl->GetState() == wxMEDIASTATE_STOPPED) - this->SetStatusText(_("Stopped"), 1); - else - PushStatusText(wxString::Format(_("Now playing: %s"), selection), 1); -} - void MainFrame::OnClickLibrary(wxDataViewEvent& event) { int selected_row = m_Library->ItemToRow(event.GetItem()); @@ -1116,9 +913,9 @@ void MainFrame::OnClickLibrary(wxDataViewEvent& event) } // Update the waveform bitmap - m_TopWaveformPanel->ResetDC(); + m_WaveformViewer->ResetDC(); - m_LoopABButton->SetValue(false); + m_TransportControls->SetLoopABValue(false); if (m_Timer->IsRunning()) { @@ -1145,9 +942,9 @@ void MainFrame::OnClickLibrary(wxDataViewEvent& event) { ClearLoopPoints(); - if (bAutoplay) + if (m_TransportControls->CanAutoplay()) { - if (bLoopPointsSet && m_LoopABButton->GetValue()) + if (bLoopPointsSet && m_TransportControls->IsLoopABOn()) PlaySample(sample_path.ToStdString(), selection.ToStdString(), true, m_LoopA.ToDouble(), wxFromStart); else @@ -2591,21 +2388,6 @@ void MainFrame::LoadConfigFile() int height = 600, width = 800; - bAutoplay = serializer.DeserializeMediaOptions("autoplay"); - bLoop = serializer.DeserializeMediaOptions("loop"); - bMuted = serializer.DeserializeMediaOptions("muted"); - - m_AutoPlayCheck->SetValue(bAutoplay); - m_LoopButton->SetValue(bLoop); - m_MuteButton->SetValue(bMuted); - - m_VolumeSlider->SetValue(serializer.DeserializeMediaVolume()); - - if (!bMuted) - m_MediaCtrl->SetVolume(double(m_VolumeSlider->GetValue()) / 100); - else - m_MediaCtrl->SetVolume(0.0); - width = serializer.DeserializeWinSize().first; height = serializer.DeserializeWinSize().second; @@ -2933,7 +2715,7 @@ void MainFrame::OnSelectPreferences(wxCommandEvent& event) } if (settings->IsWaveformColourChanged()) { - m_TopWaveformPanel->ResetDC(); + m_WaveformViewer->ResetDC(); } break; case wxID_CANCEL: @@ -3100,7 +2882,7 @@ void MainFrame::OnRecieveLoopPoints(SampleHive::SH_LoopPointsEvent& event) SH_LOG_INFO(wxString::Format(_("Loop points set: A: %2i:%02i, B: %2i:%02i"), loopA_min, loopA_sec, loopB_min, loopB_sec)); - m_LoopABButton->SetValue(true); + m_TransportControls->SetLoopABValue(true); bLoopPointsSet = true; } @@ -3141,6 +2923,18 @@ void MainFrame::OnRecieveTimerStopStatus(SampleHive::SH_TimerEvent& event) m_Timer->Stop(); } +void MainFrame::OnRecieveCallFunctionPlay(SampleHive::SH_CallFunctionEvent& event) +{ + wxString selection = event.GetSlection(); + + wxString sample_path = GetFilenamePathAndExtension(selection).Path; + + if (bLoopPointsSet && m_TransportControls->IsLoopABOn()) + PlaySample(sample_path.ToStdString(), selection.ToStdString(), true, m_LoopA.ToDouble(), wxFromStart); + else + PlaySample(sample_path.ToStdString(), selection.ToStdString()); +} + void MainFrame::ClearLoopPoints() { m_LoopA = 0; diff --git a/src/GUI/MainFrame.hpp b/src/GUI/MainFrame.hpp index eb53aa2..8737582 100644 --- a/src/GUI/MainFrame.hpp +++ b/src/GUI/MainFrame.hpp @@ -21,6 +21,7 @@ #pragma once #include "Database/Database.hpp" +#include "GUI/TransportControls.hpp" #include "GUI/WaveformViewer.hpp" #include "SampleHiveConfig.hpp" #include "Utility/Serialize.hpp" @@ -119,21 +120,11 @@ class MainFrame : public wxFrame // ------------------------------------------------------------------- // Top panel controls wxPanel* m_TopPanel; - WaveformViewer* m_TopWaveformPanel; - wxPanel* m_TopControlsPanel; + TransportControls* m_TransportControls; + WaveformViewer* m_WaveformViewer; wxBoxSizer* m_TopSizer; wxBoxSizer* m_TopPanelMainSizer; wxBoxSizer* m_WaveformDisplaySizer; - wxBoxSizer* m_BrowserControlSizer; - wxBitmapButton* m_PlayButton; - wxBitmapToggleButton* m_LoopButton; - wxBitmapButton* m_StopButton; - wxButton* m_SettingsButton; - wxBitmapToggleButton* m_MuteButton; - wxBitmapToggleButton* m_LoopABButton; - wxStaticText* m_SamplePosition; - wxSlider* m_VolumeSlider; - wxCheckBox* m_AutoPlayCheck; // ------------------------------------------------------------------- // Left panel controls @@ -188,10 +179,6 @@ class MainFrame : public wxFrame private: // ------------------------------------------------------------------- - bool bAutoplay = false; - bool bLoop = false; - bool bMuted = false; - bool bStopped = false; bool bFiltered = false; bool bShowMenuBar = false; bool bShowStatusBar = false; @@ -200,14 +187,7 @@ class MainFrame : public wxFrame private: // ------------------------------------------------------------------- // Top panel control handlers - void OnClickPlay(wxCommandEvent& event); - void OnClickLoop(wxCommandEvent& event); - void OnClickStop(wxCommandEvent& event); - void OnClickMute(wxCommandEvent& event); void OnMediaFinished(wxMediaEvent& event); - void OnCheckAutoplay(wxCommandEvent& event); - void OnSlideVolume(wxScrollEvent& event); - void OnReleaseVolumeSlider(wxScrollEvent& event); void OnClickSettings(wxCommandEvent& event); // ------------------------------------------------------------------- @@ -286,6 +266,7 @@ class MainFrame : public wxFrame void OnRecieveSetStatusBarStatus(SampleHive::SH_StatusBarStatusEvent& event); void OnRecieveInfoBarStatus(SampleHive::SH_InfoBarMessageEvent& event); void OnRecieveTimerStopStatus(SampleHive::SH_TimerEvent& event); + void OnRecieveCallFunctionPlay(SampleHive::SH_CallFunctionEvent& event); // ------------------------------------------------------------------- void LoadDatabase(); diff --git a/src/GUI/TransportControls.cpp b/src/GUI/TransportControls.cpp new file mode 100644 index 0000000..1c6dadf --- /dev/null +++ b/src/GUI/TransportControls.cpp @@ -0,0 +1,301 @@ +#include "GUI/TransportControls.hpp" +#include "Utility/ControlIDs.hpp" +#include "Utility/SH_Event.hpp" +#include "Utility/Serialize.hpp" +#include "Utility/Log.hpp" +#include "Utility/Paths.hpp" + +TransportControls::TransportControls(wxWindow* window, wxDataViewListCtrl& library, + wxMediaCtrl& mediaCtrl, wxTimer& timer) + : wxPanel(window, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL | wxNO_BORDER), + m_Library(library), m_MediaCtrl(mediaCtrl), m_Timer(timer) +{ + m_pMainSizer = new wxBoxSizer(wxHORIZONTAL); + + // Looping region controls + if (m_Theme.IsDark()) + m_pLoopABButton = new wxBitmapToggleButton(this, BC_LoopABButton, + static_cast(ICON_AB_LIGHT_16px), + wxDefaultPosition, wxDefaultSize, 0); + else + m_pLoopABButton = new wxBitmapToggleButton(this, BC_LoopABButton, + static_cast(ICON_AB_DARK_16px), + wxDefaultPosition, wxDefaultSize, 0); + m_pLoopABButton->SetToolTip(_("Loop selected region")); + + // Autoplay checkbox + m_pAutoPlayCheck = new wxCheckBox(this, BC_Autoplay, _("Autoplay"), + wxDefaultPosition, wxDefaultSize, wxCHK_2STATE); + m_pAutoPlayCheck->SetToolTip(_("Autoplay")); + + // Volume slider + m_pVolumeSlider = new wxSlider(this, BC_Volume, 100, 0, 100, + wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL); + m_pVolumeSlider->SetToolTip(_("Volume")); + m_pVolumeSlider->SetMinSize(wxSize(120, -1)); + m_pVolumeSlider->SetMaxSize(wxSize(120, -1)); + + // Sample position static text + m_pSamplePosition = new wxStaticText(this, BC_SamplePosition, "--:--/--:--", + wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE_HORIZONTAL); + + // Transport control buttons + if (m_Theme.IsDark()) + { + m_pPlayButton = new wxBitmapButton(this, BC_Play, + wxBitmapBundle::FromBitmap(static_cast + (ICON_PLAY_LIGHT_16px)), + wxDefaultPosition, wxDefaultSize, 0); + m_pLoopButton = new wxBitmapToggleButton(this, BC_Loop, + static_cast(ICON_LOOP_LIGHT_16px), + wxDefaultPosition, wxDefaultSize, 0); + m_pStopButton = new wxBitmapButton(this, BC_Stop, + wxBitmapBundle::FromBitmap(static_cast + (ICON_STOP_LIGHT_16px)), + wxDefaultPosition, wxDefaultSize, 0); + m_pMuteButton = new wxBitmapToggleButton(this, BC_Mute, + static_cast(ICON_MUTE_LIGHT_16px), + wxDefaultPosition, wxDefaultSize, 0); + } + else + { + m_pPlayButton = new wxBitmapButton(this, BC_Play, + wxBitmapBundle::FromBitmap(static_cast + (ICON_PLAY_DARK_16px)), + wxDefaultPosition, wxDefaultSize, 0); + m_pLoopButton = new wxBitmapToggleButton(this, BC_Loop, + static_cast(ICON_LOOP_DARK_16px), + wxDefaultPosition, wxDefaultSize, 0); + m_pStopButton = new wxBitmapButton(this, BC_Stop, + wxBitmapBundle::FromBitmap(static_cast + (ICON_STOP_DARK_16px)), + wxDefaultPosition, wxDefaultSize, 0); + m_pMuteButton = new wxBitmapToggleButton(this, BC_Mute, + static_cast(ICON_MUTE_DARK_16px), + wxDefaultPosition, wxDefaultSize, 0); + } + + m_pPlayButton->SetToolTip(_("Play")); + m_pLoopButton->SetToolTip(_("Loop")); + m_pStopButton->SetToolTip(_("Stop")); + m_pMuteButton->SetToolTip(_("Mute")); + + // m_pSettingsButton = new wxButton(this, BC_Settings, _("Settings"), + // wxDefaultPosition, wxDefaultSize, 0); + // m_pSettingsButton->SetToolTip(_("Settings")); + + m_pMainSizer->Add(m_pPlayButton, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2); + m_pMainSizer->Add(m_pStopButton, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2); + m_pMainSizer->Add(m_pLoopButton, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2); + m_pMainSizer->Add(m_pLoopABButton, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2); + // m_pMainSizer->Add(m_pSettingsButton, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2); + m_pMainSizer->Add(0,0,1, wxALL | wxEXPAND, 0); + m_pMainSizer->Add(m_pSamplePosition, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2); + m_pMainSizer->Add(30,0,0, wxALL | wxEXPAND, 0); + m_pMainSizer->Add(m_pMuteButton, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2); + m_pMainSizer->Add(m_pVolumeSlider, 1, wxALL | wxALIGN_CENTER_VERTICAL, 2); + m_pMainSizer->Add(m_pAutoPlayCheck, 0, wxALL | wxALIGN_CENTER_VERTICAL, 2); + + this->SetSizer(m_pMainSizer); + m_pMainSizer->Fit(this); + m_pMainSizer->SetSizeHints(this); + m_pMainSizer->Layout(); + + Bind(wxEVT_BUTTON, &TransportControls::OnClickPlay, this, BC_Play); + Bind(wxEVT_TOGGLEBUTTON, &TransportControls::OnClickLoop, this, BC_Loop); + Bind(wxEVT_BUTTON, &TransportControls::OnClickStop, this, BC_Stop); + Bind(wxEVT_TOGGLEBUTTON, &TransportControls::OnClickMute, this, BC_Mute); + // Bind(wxEVT_BUTTON, &Controls::OnClickSettings, this, BC_Settings); + Bind(wxEVT_CHECKBOX, &TransportControls::OnCheckAutoplay, this, BC_Autoplay); + Bind(wxEVT_SCROLL_THUMBTRACK, &TransportControls::OnSlideVolume, this, BC_Volume); + Bind(wxEVT_SCROLL_THUMBRELEASE, &TransportControls::OnReleaseVolumeSlider, this, BC_Volume); + + // Load control values from config file + LoadConfigFile(); +} + +void TransportControls::OnClickPlay(wxCommandEvent& event) +{ + m_bStopped = false; + + int selected_row = m_Library.GetSelectedRow(); + + if (selected_row < 0) + return; + + wxString selection = m_Library.GetTextValue(selected_row, 1); + + // Send custom event to MainFrame to play the sample + SendCallFunctionPlay(selection); +} + +void TransportControls::OnClickLoop(wxCommandEvent& event) +{ + Serializer serializer; + + m_bLoop = m_pLoopButton->GetValue(); + + serializer.SerializeMediaOptions("loop", m_bLoop); +} + +void TransportControls::OnClickStop(wxCommandEvent& event) +{ + if (!m_MediaCtrl.Stop()) + SH_LOG_ERROR("Error! Unable to stop media."); + + m_bStopped = true; + + // Send custom event to MainFrame to stop the timer + SendTimerStopStatus(); + + m_pSamplePosition->SetLabel("--:--/--:--"); + + // Send custom event to MainFrame to set the statusbar status + SendSetStatusBarStatus(_("Stopped"), 1); +} + +void TransportControls::OnClickMute(wxCommandEvent& event) +{ + Serializer serializer; + + if (m_pMuteButton->GetValue()) + { + m_MediaCtrl.SetVolume(0.0); + m_bMuted = true; + + serializer.SerializeMediaOptions("muted", m_bMuted); + } + else + { + m_MediaCtrl.SetVolume(double(m_pVolumeSlider->GetValue()) / 100); + m_bMuted = false; + + serializer.SerializeMediaOptions("muted", m_bMuted); + } +} + +void TransportControls::OnCheckAutoplay(wxCommandEvent& event) +{ + Serializer serializer; + + if (m_pAutoPlayCheck->GetValue()) + { + m_bAutoplay = true; + + serializer.SerializeMediaOptions("autoplay", m_bAutoplay); + } + else + { + m_bAutoplay = false; + + serializer.SerializeMediaOptions("autoplay", m_bAutoplay); + } +} + +void TransportControls::OnSlideVolume(wxScrollEvent& event) +{ + m_MediaCtrl.SetVolume(double(m_pVolumeSlider->GetValue()) / 100); + + // Send custom event to MainFrame to push status to statusbar + SendPushStatusBarStatus(wxString::Format(_("Volume: %d"), m_pVolumeSlider->GetValue()), 1); +} + +void TransportControls::OnReleaseVolumeSlider(wxScrollEvent& event) +{ + Serializer serializer; + + serializer.SerializeMediaVolume(m_pVolumeSlider->GetValue()); + + int selected_row = m_Library.GetSelectedRow(); + + if (selected_row < 0) + return; + + wxString selection = m_Library.GetTextValue(selected_row, 1); + + // Wait a second then remove the status from statusbar + wxSleep(1); + + // Send custom event to MainFrame to pop status from statusbar + SendPopStatusBarStatus(1); + + if (m_MediaCtrl.GetState() == wxMEDIASTATE_STOPPED) + SendSetStatusBarStatus(_("Stopped"), 1); + else + SendPushStatusBarStatus(wxString::Format(_("Now playing: %s"), selection), 1); +} + +void TransportControls::LoadConfigFile() +{ + Serializer serializer; + + SH_LOG_INFO("Reading transport control values.."); + + m_bAutoplay = serializer.DeserializeMediaOptions("autoplay"); + m_bLoop = serializer.DeserializeMediaOptions("loop"); + m_bMuted = serializer.DeserializeMediaOptions("muted"); + + m_pAutoPlayCheck->SetValue(m_bAutoplay); + m_pLoopButton->SetValue(m_bLoop); + m_pMuteButton->SetValue(m_bMuted); + + m_pVolumeSlider->SetValue(serializer.DeserializeMediaVolume()); + + if (!m_bMuted) + m_MediaCtrl.SetVolume(double(m_pVolumeSlider->GetValue()) / 100); + else + m_MediaCtrl.SetVolume(0.0); +} + +void TransportControls::SendPushStatusBarStatus(const wxString& msg, int section) +{ + SampleHive::SH_StatusBarStatusEvent event(SampleHive::SH_EVT_STATUSBAR_STATUS_PUSH, this->GetId()); + event.SetEventObject(this); + + event.SetPushMessageAndSection({ msg, section }); + + HandleWindowEvent(event); +} + +void TransportControls::SendPopStatusBarStatus(int section) +{ + SampleHive::SH_StatusBarStatusEvent event(SampleHive::SH_EVT_STATUSBAR_STATUS_POP, this->GetId()); + event.SetEventObject(this); + + event.SetPopMessageSection(section); + + HandleWindowEvent(event); +} + +void TransportControls::SendSetStatusBarStatus(const wxString& text, int section) +{ + SampleHive::SH_StatusBarStatusEvent event(SampleHive::SH_EVT_STATUSBAR_STATUS_SET, this->GetId()); + event.SetEventObject(this); + + event.SetStatusTextAndSection({ text, section }); + + HandleWindowEvent(event); +} + +void TransportControls::SendCallFunctionPlay(const wxString& selection) +{ + SampleHive::SH_CallFunctionEvent event(SampleHive::SH_EVT_CALL_FUNC_PLAY, this->GetId()); + event.SetEventObject(this); + + event.SetSelection(selection); + + HandleWindowEvent(event); +} + +void TransportControls::SendTimerStopStatus() +{ + SampleHive::SH_TimerEvent event(SampleHive::SH_EVT_TIMER_STOP, this->GetId()); + event.SetEventObject(this); + + HandleWindowEvent(event); +} + +TransportControls::~TransportControls() +{ + +} diff --git a/src/GUI/TransportControls.hpp b/src/GUI/TransportControls.hpp new file mode 100644 index 0000000..1a71e7b --- /dev/null +++ b/src/GUI/TransportControls.hpp @@ -0,0 +1,107 @@ +#pragma once + +#include "wx/bmpbuttn.h" +#include "wx/button.h" +#include "wx/checkbox.h" +#include "wx/dataview.h" +#include "wx/event.h" +#include "wx/mediactrl.h" +#include "wx/settings.h" +#include "wx/sizer.h" +#include "wx/slider.h" +#include "wx/stattext.h" +#include "wx/tglbtn.h" +#include "wx/panel.h" +#include "wx/timer.h" +#include "wx/window.h" + +class TransportControls : public wxPanel +{ + public: + // ------------------------------------------------------------------- + TransportControls(wxWindow* window, wxDataViewListCtrl& library, wxMediaCtrl& mediaCtrl, wxTimer& timer); + ~TransportControls(); + + public: + // ------------------------------------------------------------------- + bool IsLoopABOn() const { return m_pLoopABButton->GetValue(); } + + // ------------------------------------------------------------------- + inline bool CanAutoplay() const { return m_bAutoplay; }; + inline bool CanLoop() const { return m_bLoop; }; + inline bool IsMuted() const { return m_bMuted; }; + inline bool IsStopped() const { return m_bStopped; }; + + // ------------------------------------------------------------------- + void SetLoopABValue(bool value) { m_pLoopABButton->SetValue(value); } + + // ------------------------------------------------------------------- + void SetCanAutoplay(bool autoplay) { m_bAutoplay = autoplay; } + void SetCanLoop(bool loop) { m_bLoop = loop; } + void SetIsMuted(bool muted) { m_bMuted = muted; } + void SetIsStopped(bool stopped) { m_bStopped = stopped; } + + // ------------------------------------------------------------------- + inline wxString GetSamplePositionText() const { return m_pSamplePosition->GetLabelText(); } + + // ------------------------------------------------------------------- + void SetSamplePositionText(const wxString& text) { m_pSamplePosition->SetLabel(text); } + + private: + // ------------------------------------------------------------------- + // Event handlers + void OnClickPlay(wxCommandEvent& event); + void OnClickLoop(wxCommandEvent& event); + void OnClickStop(wxCommandEvent& event); + void OnClickMute(wxCommandEvent& event); + void OnClickSettings(wxCommandEvent& event); + void OnCheckAutoplay(wxCommandEvent& event); + void OnSlideVolume(wxScrollEvent& event); + void OnReleaseVolumeSlider(wxScrollEvent& event); + + private: + // ------------------------------------------------------------------- + // Custom events for sending infomation to MainFrame + void SendPushStatusBarStatus(const wxString& msg, int section); + void SendSetStatusBarStatus(const wxString& msg, int section); + void SendPopStatusBarStatus(int section); + void SendCallFunctionPlay(const wxString& selection); + void SendTimerStopStatus(); + + private: + // ------------------------------------------------------------------- + // Load control values from config file + void LoadConfigFile(); + + private: + // ------------------------------------------------------------------- + wxDataViewListCtrl& m_Library; + wxMediaCtrl& m_MediaCtrl; + wxTimer& m_Timer; + + private: + // ------------------------------------------------------------------- + bool m_bAutoplay = false; + bool m_bLoop = false; + bool m_bMuted = false; + bool m_bStopped = false; + + private: + // ------------------------------------------------------------------- + wxBitmapButton* m_pPlayButton = nullptr; + wxBitmapToggleButton* m_pLoopButton = nullptr; + wxBitmapButton* m_pStopButton = nullptr; + wxButton* m_pSettingsButton = nullptr; + wxBitmapToggleButton* m_pMuteButton = nullptr; + wxBitmapToggleButton* m_pLoopABButton = nullptr; + wxStaticText* m_pSamplePosition = nullptr; + wxSlider* m_pVolumeSlider = nullptr; + wxCheckBox* m_pAutoPlayCheck = nullptr; + + // ------------------------------------------------------------------- + wxBoxSizer* m_pMainSizer = nullptr; + + private: + // ------------------------------------------------------------------- + wxSystemAppearance m_Theme = wxSystemSettings::GetAppearance(); +}; diff --git a/src/Utility/ControlID_Enums.hpp b/src/Utility/ControlIDs.hpp similarity index 100% rename from src/Utility/ControlID_Enums.hpp rename to src/Utility/ControlIDs.hpp diff --git a/src/Utility/SH_Event.cpp b/src/Utility/SH_Event.cpp index 6c62342..bf8bd52 100644 --- a/src/Utility/SH_Event.cpp +++ b/src/Utility/SH_Event.cpp @@ -101,4 +101,17 @@ namespace SampleHive } wxDEFINE_EVENT(SH_EVT_TIMER_STOP, SH_TimerEvent); + + SH_CallFunctionEvent::SH_CallFunctionEvent(wxEventType eventType, int winId) + : wxCommandEvent(eventType, winId) + { + + } + + SH_CallFunctionEvent::~SH_CallFunctionEvent() + { + + } + + wxDEFINE_EVENT(SH_EVT_CALL_FUNC_PLAY, SH_CallFunctionEvent); } diff --git a/src/Utility/SH_Event.hpp b/src/Utility/SH_Event.hpp index d2baf58..1d26635 100644 --- a/src/Utility/SH_Event.hpp +++ b/src/Utility/SH_Event.hpp @@ -146,4 +146,23 @@ namespace SampleHive }; wxDECLARE_EVENT(SH_EVT_TIMER_STOP, SH_TimerEvent); + + class SH_CallFunctionEvent : public wxCommandEvent + { + public: + SH_CallFunctionEvent(wxEventType eventType, int winId); + ~SH_CallFunctionEvent(); + + public: + virtual wxEvent* Clone() const { return new SH_CallFunctionEvent(*this); } + + public: + wxString GetSlection() { return m_Selection; } + void SetSelection(const wxString& selection) { m_Selection = selection; } + + private: + wxString m_Selection; + }; + + wxDECLARE_EVENT(SH_EVT_CALL_FUNC_PLAY, SH_CallFunctionEvent); }