diff --git a/README.md b/README.md index 08d5d87..d5bedda 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,16 @@

- Sample Hive + sample-hive-icon

-

Sample Hive

+

SampleHive

A simple, modern audio sample browser/manager for GNU/Linux. - Sample Hive + sample-hive-logo


-## What is Sample Hive? +## What is SampleHive? -Sample Hive let's you manage your audio samples in a nice and simple way, just add a directory where you store all your samples, or drag and drop a directory on it to add samples to it, and it will help sort, search, play and view some information about the sample. You can also drag and drop from Sample Hive to other applications. +SampleHive let's you manage your audio samples in a nice and simple way, just add a directory where you store all your samples, or drag and drop a directory on it to add samples to it, and it will help sort, search, play and view some information about the sample. You can also drag and drop from SampleHive to other applications. ![Screenshot of SampleHive](assets/screenshots/screenshot-hive.png) @@ -27,9 +27,9 @@ On Ubuntu and Ubuntu based distributions, sudo apt install libwxbase3.0-dev libwxgtk-media3.0-gtk3-dev libwxgtk3.0-gtk3-dev wx3.0-headers libwxsvg-dev libwxsvg3 libsqlite3-dev libyaml-cpp-dev libtagc0-dev libtag1-dev libtagc0 libexif-dev ``` -You might also need to install `git`, `meson` and `g++` as well, if you don't already have them installed in order to compile Sample Hive. +You might also need to install `git`, `meson` and `g++` as well, if you don't already have them installed in order to compile SampleHive. -## How to build Sample Hive? +## How to build SampleHive? Download the source code from this repository or use a git clone: @@ -39,19 +39,28 @@ cd sample-hive meson build ninja -C build ``` - -## How to run Sample Hive? -To run Sample Hive: +## How to run SampleHive? + +To run SampleHive: ``` cd build ./SampleHive ``` -## Some keybindings -// TODO +## Are there any keybindings for SampleHive? -## Can I configure Sample Hive? +There are few pre-defined keybindings for SampleHive that you can use, such as -Sample Hive comes with a `config.yaml` file, that you can edit to change some settings for it. +| KEYBIND | ACTION | +|---------+--------------------------| +| P | Play the selected sample | +| L | Toggle loop on/off | +| M | Toggle mute on/off | +| S | Stop the playing sample | +| O | Open the settings dialog | + +## Can I configure SampleHive? + +SampleHive comes with a `config.yaml` file, that you can edit to change some settings for it. diff --git a/src/App.cpp b/src/App.cpp index aa1a61a..9bb7378 100644 --- a/src/App.cpp +++ b/src/App.cpp @@ -1,7 +1,14 @@ #include "App.hpp" +#include "ControlID_Enums.hpp" #include +#include +#include #include +#include +#include +#include +#include #include wxIMPLEMENT_APP(App); @@ -39,3 +46,160 @@ bool App::OnInit() m_Frame->Show(true); return true; } + +int App::FilterEvent(wxEvent& event) +{ + if(event.GetEventType() == wxEVT_KEY_DOWN) + { + wxWindow* focusedWindow = wxWindow::FindFocus(); + if(focusedWindow != NULL) + { + const wxString& className = focusedWindow->GetClassInfo()->GetClassName(); + + wxLogDebug("Focused window: %s", className); + + // if SearchCtrl or TreeCtrl has focus, let all keys through + if(className == wxT("wxSearchCtrl")) + { + wxLogDebug("SearchCtrl focused skipping key filtering"); + return wxEventFilter::Event_Skip; + } + else if(className == wxT("wxTreeCtrl")) + { + wxLogDebug("TreeCtrl focused skipping key filtering"); + return wxEventFilter::Event_Skip; + } + } + + wxKeyEvent* keyEvent = wxDynamicCast(&event, wxKeyEvent); + + if(keyEvent != NULL) + { + switch (keyEvent->GetKeyCode()) + { + case WXK_SPACE: + { + wxCommandEvent playEvent(wxEVT_BUTTON); + + playEvent.SetId(BC_Play); + playEvent.SetEventObject(m_Frame->m_PlayButton); + + m_Frame->OnClickPlay(playEvent); + + wxLogDebug("Space pressed"); + + return wxEventFilter::Event_Processed; + + break; + } + case 'A': + { + wxCommandEvent autoplayEvent(wxEVT_CHECKBOX); + autoplayEvent.SetId(BC_Autoplay); + + autoplayEvent.SetEventObject(m_Frame->m_AutoPlayCheck); + + if (m_Frame->m_AutoPlayCheck->GetValue()) + m_Frame->m_AutoPlayCheck->SetValue(false); + else + m_Frame->m_AutoPlayCheck->SetValue(true); + + m_Frame->OnCheckAutoplay(autoplayEvent); + + wxLogDebug("A pressed"); + + return wxEventFilter::Event_Processed; + + break; + } + case 'L': + { + wxCommandEvent loopEvent(wxEVT_TOGGLEBUTTON); + + loopEvent.SetId(BC_Loop); + loopEvent.SetEventObject(m_Frame->m_LoopButton); + + if (m_Frame->m_LoopButton->GetValue()) + m_Frame->m_LoopButton->SetValue(false); + else + m_Frame->m_LoopButton->SetValue(true); + + m_Frame->OnClickLoop(loopEvent); + + wxLogDebug("L pressed"); + + return wxEventFilter::Event_Processed; + + break; + } + case 'M': + { + wxCommandEvent muteEvent(wxEVT_TOGGLEBUTTON); + + muteEvent.SetId(BC_Mute); + muteEvent.SetEventObject(m_Frame->m_MuteButton); + + if (m_Frame->m_MuteButton->GetValue()) + m_Frame->m_MuteButton->SetValue(false); + else + m_Frame->m_MuteButton->SetValue(true); + + m_Frame->OnClickMute(muteEvent); + + wxLogDebug("M pressed"); + + return wxEventFilter::Event_Processed; + + break; + } + case 'O': + { + wxCommandEvent settingsEvent(wxEVT_BUTTON); + + settingsEvent.SetId(BC_Settings); + settingsEvent.SetEventObject(m_Frame->m_SettingsButton); + + m_Frame->OnClickSettings(settingsEvent); + + wxLogDebug("O pressed"); + + return wxEventFilter::Event_Processed; + + break; + } + case 'P': + { + wxCommandEvent playEvent(wxEVT_BUTTON); + + playEvent.SetId(BC_Play); + playEvent.SetEventObject(m_Frame->m_PlayButton); + + m_Frame->OnClickPlay(playEvent); + + wxLogDebug("P pressed"); + + return wxEventFilter::Event_Processed; + + break; + } + case 'S': + { + wxCommandEvent stopEvent(wxEVT_BUTTON); + + stopEvent.SetId(BC_Stop); + stopEvent.SetEventObject(m_Frame->m_StopButton); + + m_Frame->OnClickStop(stopEvent); + + wxLogDebug("S pressed"); + + return wxEventFilter::Event_Processed; + + break; + } + } + } + } + + return -1; +} diff --git a/src/App.hpp b/src/App.hpp index a973270..5f3eaf4 100644 --- a/src/App.hpp +++ b/src/App.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include "MainFrame.hpp" @@ -13,6 +14,9 @@ class App : public wxApp private: MainFrame* m_Frame = nullptr; - public: + private: virtual bool OnInit(); + + private: + int FilterEvent(wxEvent& event); }; diff --git a/src/MainFrame.cpp b/src/MainFrame.cpp index 3f9e24e..c2d00cc 100644 --- a/src/MainFrame.cpp +++ b/src/MainFrame.cpp @@ -224,16 +224,16 @@ MainFrame::MainFrame() Bind(wxEVT_BUTTON, &MainFrame::OnClickCollectionAdd, this, BC_CollectionViewAdd); Bind(wxEVT_BUTTON, &MainFrame::OnClickCollectionRemove, this, BC_CollectionViewRemove); - // Setting up keybindings - wxAcceleratorEntry entries[5]; - entries[0].Set(wxACCEL_NORMAL, (int) 'P', BC_Play); - entries[1].Set(wxACCEL_NORMAL, (int) 'L', BC_Loop); - entries[2].Set(wxACCEL_NORMAL, (int) 'S', BC_Stop); - entries[3].Set(wxACCEL_NORMAL, (int) 'M', BC_Mute); - entries[4].Set(wxACCEL_NORMAL, (int) 'O', BC_Settings); + // // Setting up keybindings + // wxAcceleratorEntry entries[5]; + // entries[0].Set(wxACCEL_NORMAL, (int) 'P', BC_Play); + // entries[1].Set(wxACCEL_NORMAL, (int) 'L', BC_Loop); + // entries[2].Set(wxACCEL_NORMAL, (int) 'S', BC_Stop); + // entries[3].Set(wxACCEL_NORMAL, (int) 'M', BC_Mute); + // entries[4].Set(wxACCEL_NORMAL, (int) 'O', BC_Settings); - wxAcceleratorTable accel(5, entries); - this->SetAcceleratorTable(accel); + // wxAcceleratorTable accel(5, entries); + // this->SetAcceleratorTable(accel); // Adding widgets to their sizers m_MainSizer->Add(m_MainPanel, 1, wxALL | wxEXPAND, 0); diff --git a/src/MainFrame.hpp b/src/MainFrame.hpp index 0b88356..a7d96a7 100644 --- a/src/MainFrame.hpp +++ b/src/MainFrame.hpp @@ -202,4 +202,6 @@ class MainFrame : public wxFrame void CreateWatcher(); // wxString TagLibTowx(const TagLib::String& in); + + friend class App; };