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);
}