From 1efcf645c99b6ab3b790b770d0eded0109803639 Mon Sep 17 00:00:00 2001 From: bill-auger Date: Oct 26 2018 14:47:21 +0000 Subject: file browser, clip lists, and device selector in tabbed widget --- diff --git a/Source/Constants/GuiConstants.cpp b/Source/Constants/GuiConstants.cpp index 3084b1c..1a16aa2 100644 --- a/Source/Constants/GuiConstants.cpp +++ b/Source/Constants/GuiConstants.cpp @@ -35,7 +35,6 @@ const uint8 GUI::TITLEBAR_H = 24 ; const uint16 GUI::WINDOW_W = 768 - BORDERS_W ; // jucer 766 const uint16 GUI::WINDOW_H = 768 - BORDERS_W - TITLEBAR_H ; // jucer 742 const Colour GUI::WINDOW_BG_COLOR = Colour(0xFF404040) ; -const Colour GUI::BROWSER_BG_COLOR = Colour(0xFF606060) ; const int GUI::TITLEBAR_BTNS = DocumentWindow::allButtons ; // Waveform @@ -54,6 +53,25 @@ const String GUI::FULL_WAVEFORM_ID = "full-waveform" ; const String GUI::CLIP_WAVEFORM_ID = "clip-waveform" ; const String GUI::NO_FILE_TEXT = "(No audio file selected)" ; +// TabbedComponent +const int GUI::FILE_BROWSER_IDX = 0 ; +const int GUI::CLIPS_IDX = 1 ; +const int GUI::COMPILATIONS_IDX = 2 ; +const int GUI::DEVICE_SELECTOR_IDX = 3 ; + +// FileBrowserComponent +const Colour GUI::TABPANEL_BG_COLOR = Colour(0xFF303030) ; +const Colour GUI::TABPANEL_FG_COLOR = Colour(0xFF808080) ; +const Colour GUI::FILEPATH_BG_COLOR = Colour(0xFF606060) ; +const Colour GUI::FILEPATH_FG_COLOR = Colour(0xFFFFFFFF) ; +const Colour GUI::FILEPATH_ARROW_COLOR = Colour(0xFF80FF80) ; +const Colour GUI::FILENAME_BG_COLOR = Colour(0xFF000000) ; +const Colour GUI::FILENAME_FG_COLOR = Colour(0xFFFFFFFF) ; +const Colour GUI::BROWSER_BG_COLOR = Colour(0xFF000000) ; +const Colour GUI::BROWSER_FG_COLOR = Colour(0xFFFFFFFF) ; +const Colour GUI::BROWSER_SELECTED_BG_COLOR = Colour(0xFF404040) ; +const Colour GUI::BROWSER_SELECTED_FG_COLOR = Colour(0xFF40FF40) ; + // user messages const String GUI::DEVICE_ERROR_TITLE = "Audio Device Error" ; const String GUI::DEVICE_ERROR_MSG = "Audio Device Error\n\nCan not find a usable audio playback device" ; diff --git a/Source/Constants/GuiConstants.h b/Source/Constants/GuiConstants.h index 5c2d5d2..2d21cac 100644 --- a/Source/Constants/GuiConstants.h +++ b/Source/Constants/GuiConstants.h @@ -43,7 +43,6 @@ public: static const uint16 WINDOW_W ; static const uint16 WINDOW_H ; static const Colour WINDOW_BG_COLOR ; - static const Colour BROWSER_BG_COLOR ; static const int TITLEBAR_BTNS ; // Waveform @@ -62,6 +61,25 @@ public: static const String CLIP_WAVEFORM_ID ; static const String NO_FILE_TEXT ; + // TabbedComponent + static const int FILE_BROWSER_IDX ; + static const int CLIPS_IDX ; + static const int COMPILATIONS_IDX ; + static const int DEVICE_SELECTOR_IDX ; + + // FileBrowserComponent + static const Colour TABPANEL_BG_COLOR ; + static const Colour TABPANEL_FG_COLOR ; + static const Colour FILEPATH_BG_COLOR ; + static const Colour FILEPATH_FG_COLOR ; + static const Colour FILEPATH_ARROW_COLOR ; + static const Colour FILENAME_BG_COLOR ; + static const Colour FILENAME_FG_COLOR ; + static const Colour BROWSER_BG_COLOR ; + static const Colour BROWSER_FG_COLOR ; + static const Colour BROWSER_SELECTED_BG_COLOR ; + static const Colour BROWSER_SELECTED_FG_COLOR ; + // user messages static const String DEVICE_ERROR_TITLE ; static const String DEVICE_ERROR_MSG ; diff --git a/Source/Models/AudioTagTooStore.cpp b/Source/Models/AudioTagTooStore.cpp index bbf6d68..3cfe888 100644 --- a/Source/Models/AudioTagTooStore.cpp +++ b/Source/Models/AudioTagTooStore.cpp @@ -346,3 +346,19 @@ DEBUG_TRACE_SET_CONFIG return is_valid ; } + +void AudioTagTooStore::createClip(String& audio_filename , double begin_time , double end_time) +{ +DBG("AudioTagTooStore::createClip() audio_filename=" + audio_filename + + " begin_time=" + String(begin_time) + + " end_time=" + String(end_time) ) ; + + Identifier clip_id = STORE::FilterId(audio_filename + '-' + + String(begin_time) + '-' + + String(end_time ) + '-' ) ; + ValueTree clip = ValueTree(clip_id) ; + setProperty(clip , STORE::FILENAME_KEY , audio_filename) ; + setProperty(clip , STORE::BEGIN_TIME_KEY , begin_time ) ; + setProperty(clip , STORE::END_TIME_KEY , end_time ) ; + this->root.addChild(clip , -1 , nullptr) ; +} diff --git a/Source/Models/AudioTagTooStore.h b/Source/Models/AudioTagTooStore.h index bfd2692..2f857cb 100644 --- a/Source/Models/AudioTagTooStore.h +++ b/Source/Models/AudioTagTooStore.h @@ -83,6 +83,7 @@ private: bool isKnownProperty(ValueTree node , const Identifier& key) ; void setProperty (ValueTree node , const Identifier& key , const var value) ; bool setConfig (ValueTree config_node , const Identifier& key , const var value) ; + void createClip (String audio_filename , double begin_time , double end_time) ; // configuration/persistence File storageFile ; diff --git a/Source/Views/MainContent.cpp b/Source/Views/MainContent.cpp index b9026e5..510f32b 100644 --- a/Source/Views/MainContent.cpp +++ b/Source/Views/MainContent.cpp @@ -55,7 +55,7 @@ //============================================================================== MainContent::MainContent () - : audioFileFilter(MEDIA::IMPORT_WAVEFILE_MASK , String("*") , MEDIA::IMPORT_WAVEFILE_DESC) , directoryList(&audioFileFilter , workerThread) , workerThread(APP::WORKER_THREAD_NAME) + : audioFileFilter(MEDIA::IMPORT_WAVEFILE_MASK , String("*") , MEDIA::IMPORT_WAVEFILE_DESC) , workerThread(APP::WORKER_THREAD_NAME) { //[Constructor_pre] You can add your own custom stuff here.. @@ -69,10 +69,10 @@ MainContent::MainContent () clipWaveform.reset (new Waveform (formatManager , transportSource , fineFps)); addAndMakeVisible (clipWaveform.get()); - groupComponent.reset (new GroupComponent ("new group", - String())); - addAndMakeVisible (groupComponent.get()); - groupComponent->setColour (GroupComponent::outlineColourId, Colour (0x00000000)); + controlsGroup.reset (new GroupComponent (String(), + String())); + addAndMakeVisible (controlsGroup.get()); + controlsGroup->setColour (GroupComponent::outlineColourId, Colour (0x00000000)); headButton.reset (new TextButton (String())); addAndMakeVisible (headButton.get()); @@ -82,21 +82,31 @@ MainContent::MainContent () addAndMakeVisible (transportButton.get()); transportButton->setButtonText (TRANS("Play")); + clipButton.reset (new TextButton (String())); + addAndMakeVisible (clipButton.get()); + clipButton->setButtonText (TRANS("Clip")); + clipButton->addListener (this); + tailButton.reset (new TextButton (String())); addAndMakeVisible (tailButton.get()); tailButton->setButtonText (TRANS("Tail")); - fileTree.reset (new FileTreeComponent (directoryList)); - addAndMakeVisible (fileTree.get()); - - deviceSelector.reset (new AudioDeviceSelectorComponent (deviceManager , 0 , 0 , 2 , 2 , false , false , true , false)); - addAndMakeVisible (deviceSelector.get()); + tabPanel.reset (new TabbedComponent (TabbedButtonBar::TabsAtTop)); + addAndMakeVisible (tabPanel.get()); + tabPanel->setTabBarDepth (30); + tabPanel->addTab (TRANS("Files"), Colour (0xff404040), new FileBrowserComponent ((FileBrowserComponent::openMode | FileBrowserComponent::canSelectFiles) , this->workingDir , &(this->audioFileFilter) , nullptr), true); + tabPanel->addTab (TRANS("Clips"), Colour (0xff404040), new TreeView(), true); + tabPanel->addTab (TRANS("Compilations"), Colour (0xff404040), new TreeView(), true); + tabPanel->addTab (TRANS("Devices"), Colour (0xff404040), new AudioDeviceSelectorComponent (deviceManager , 0 , 0 , 2 , 2 , false , false , true , false), true); + tabPanel->setCurrentTabIndex (0); statusbar.reset (new Statusbar()); addAndMakeVisible (statusbar.get()); + //[UserPreSize] + this->fileBrowser = static_cast(this->tabPanel->getTabContentComponent(GUI::FILE_BROWSER_IDX)) ; this->storage.reset(new AudioTagTooStore()) ; this->fullWaveform->setName(GUI::FULL_WAVEFORM_ID) ; @@ -104,7 +114,20 @@ MainContent::MainContent () this->waveforms.push_back(this->fullWaveform.get()) ; this->waveforms.push_back(this->clipWaveform.get()) ; - this->fileTree->setColour(FileTreeComponent::backgroundColourId , GUI::BROWSER_BG_COLOR) ; + this->tabPanel->setColour(TabbedComponent::backgroundColourId , GUI::TABPANEL_BG_COLOR) ; + this->tabPanel->setColour(TabbedComponent::outlineColourId , GUI::TABPANEL_FG_COLOR) ; + this->fileBrowser->setColour(FileBrowserComponent::currentPathBoxBackgroundColourId , GUI::FILEPATH_BG_COLOR ) ; + this->fileBrowser->setColour(FileBrowserComponent::currentPathBoxTextColourId , GUI::FILEPATH_FG_COLOR ) ; + this->fileBrowser->setColour(FileBrowserComponent::currentPathBoxArrowColourId , GUI::FILEPATH_ARROW_COLOR) ; + this->fileBrowser->setColour(FileBrowserComponent::filenameBoxBackgroundColourId , GUI::FILENAME_BG_COLOR ) ; + this->fileBrowser->setColour(FileBrowserComponent::filenameBoxTextColourId , GUI::FILENAME_FG_COLOR ) ; + + FileListComponent* file_list = static_cast(this->fileBrowser->getDisplayComponent() ) ; + file_list->setColour(ListBox::backgroundColourId , GUI::BROWSER_BG_COLOR ) ; + file_list->setColour(ListBox::textColourId , Colour(0xFF2020FF)) ; // nfg + file_list->setColour(DirectoryContentsDisplayComponent::textColourId , GUI::BROWSER_FG_COLOR ) ; + file_list->setColour(DirectoryContentsDisplayComponent::highlightColourId , GUI::BROWSER_SELECTED_BG_COLOR) ; + file_list->setColour(DirectoryContentsDisplayComponent::highlightedTextColourId , GUI::BROWSER_SELECTED_FG_COLOR) ; //[/UserPreSize] @@ -113,10 +136,8 @@ MainContent::MainContent () //[Constructor] You can add your own custom stuff here.. - this->directoryList .setDirectory(this->workingDir , true , true) ; this->formatManager .registerBasicFormats() ; this->audioSourcePlayer.setSource(&transportSource) ; - this->directoryList .setDirectory(File::getSpecialLocation(File::userHomeDirectory) , true , true) ; this->headButton ->addListener (this); this->transportButton->addListener (this); @@ -125,7 +146,7 @@ MainContent::MainContent () this->deviceManager .addChangeListener(this) ; this->clipWaveform ->addChangeListener(this) ; this->transportSource .addChangeListener(this) ; - this->fileTree ->addListener (this) ; + this->fileBrowser ->addListener (this) ; this->storage->root .addListener (this) ; // initialize stored state @@ -158,7 +179,7 @@ MainContent::~MainContent() this->deviceManager .removeAudioCallback(&audioSourcePlayer) ; this->deviceManager .removeChangeListener(this) ; this->transportSource .removeChangeListener(this) ; - this->fileTree ->removeListener (this) ; + this->fileBrowser ->removeListener (this) ; this->storage->root .removeListener (this) ; this->storage = nullptr ; @@ -167,12 +188,12 @@ MainContent::~MainContent() fullWaveform = nullptr; clipWaveform = nullptr; - groupComponent = nullptr; + controlsGroup = nullptr; headButton = nullptr; transportButton = nullptr; + clipButton = nullptr; tailButton = nullptr; - fileTree = nullptr; - deviceSelector = nullptr; + tabPanel = nullptr; statusbar = nullptr; @@ -211,14 +232,13 @@ void MainContent::resized() fullWaveform->setBounds ((getWidth() / 2) - ((getWidth() - 32) / 2), 16, getWidth() - 32, 120); clipWaveform->setBounds ((getWidth() / 2) - ((getWidth() - 32) / 2), 16 + 120 - -8, getWidth() - 32, 120); - groupComponent->setBounds ((getWidth() / 2) - ((getWidth() - 32) / 2), (16 + 120 - -8) + 120 - -8, getWidth() - 32, 24); - headButton->setBounds ((getWidth() / 2) + -150 - (150 / 2), (16 + 120 - -8) + 120 - -8, 150, 24); - transportButton->setBounds ((getWidth() / 2) - (150 / 2), (16 + 120 - -8) + 120 - -8, 150, 24); - tailButton->setBounds ((getWidth() / 2) + 150 - (150 / 2), (16 + 120 - -8) + 120 - -8, 150, 24); - fileTree->setBounds ((getWidth() / 2) - ((getWidth() - 32) / 2), ((16 + 120 - -8) + 120 - -8) + 24 - -8, getWidth() - 32, proportionOfHeight (0.3900f)); - deviceSelector->setBounds ((getWidth() / 2) - ((getWidth() - 32) / 2), ((16 + 120 - -8) + 120 - -8) + 24 - -8, getWidth() - 32, proportionOfHeight (0.3900f)); + controlsGroup->setBounds ((getWidth() / 2) - ((getWidth() - 32) / 2), (16 + 120 - -8) + 120 - -8, getWidth() - 32, 24); + headButton->setBounds (((getWidth() / 2) - ((getWidth() - 32) / 2)) + (getWidth() - 32) / 2 + -100 - 100, ((16 + 120 - -8) + 120 - -8) + 0, 100, 24); + transportButton->setBounds (((getWidth() / 2) - ((getWidth() - 32) / 2)) + (getWidth() - 32) / 2 - 100, ((16 + 120 - -8) + 120 - -8) + 0, 100, 24); + clipButton->setBounds (((getWidth() / 2) - ((getWidth() - 32) / 2)) + (getWidth() - 32) / 2, ((16 + 120 - -8) + 120 - -8) + 0, 100, 24); + tailButton->setBounds (((getWidth() / 2) - ((getWidth() - 32) / 2)) + (getWidth() - 32) / 2 + 100, ((16 + 120 - -8) + 120 - -8) + 0, 100, 24); + tabPanel->setBounds ((getWidth() / 2) - ((getWidth() - 32) / 2), ((16 + 120 - -8) + 120 - -8) + 24 - -8, getWidth() - 32, getHeight() - 358); statusbar->setBounds ((getWidth() / 2) - ((getWidth() - 16) / 2), getHeight() - 8 - 32, getWidth() - 16, 32); - //[UserResized] Add your own custom resize handling here.. //[/UserResized] } @@ -228,7 +248,7 @@ void MainContent::resized() void MainContent::paintOverChildren(Graphics& g) { - if (this->clipWaveform->getZoomFactor() < 1.0) return ; + if (this->clipWaveform->getZoomFactor() == 1.0) return ; Rectangle full_wave_head_bounds = getLocalArea(this->fullWaveform.get() , this->fullWaveform->getHeadMarkerBounds()) ; Rectangle full_wave_tail_bounds = getLocalArea(this->fullWaveform.get() , this->fullWaveform->getTailMarkerBounds()) ; @@ -294,6 +314,7 @@ void MainContent::buttonClicked(Button* a_button) { if (a_button == this->headButton .get()) setHeadMarker() ; else if (a_button == this->transportButton.get()) toggleTransport() ; + else if (a_button == this->clipButton .get()) createClip() ; else if (a_button == this->tailButton .get()) setTailMarker() ; } @@ -335,7 +356,7 @@ void MainContent::updateTransportButton() bool is_rolling = this->transportSource.isPlaying() ; if (!is_rolling) this->transportSource.setPosition(this->clipWaveform->getHeadTime()) ; - transportButton->setButtonText((is_rolling) ? "Stop" : "Start") ; + transportButton->setButtonText((is_rolling) ? "Stop" : "Play") ; transportButton->setToggleState(is_rolling , juce::dontSendNotification) ; } @@ -351,7 +372,14 @@ void MainContent::setTailMarker() for (Waveform* waveform : this->waveforms) waveform->resetPosition() ; } -void MainContent::selectionChanged() { loadUrl(this->fileTree->getSelectedFile()) ; } +bool MainContent::createClip() +{ + this->storage->createClip(this->audioFilename , + this->fullWaveform->getHeadTime() , + this->fullWaveform->getHeadTime() ) ; +} + +void MainContent::selectionChanged() { loadUrl(this->fileBrowser->getSelectedFile(0)) ; } void MainContent::changeListenerCallback(ChangeBroadcaster* source) { @@ -359,13 +387,18 @@ void MainContent::changeListenerCallback(ChangeBroadcaster* source) else if (source == &(this->transportSource) ) updateTransportButton() ; else if (source == &(this->deviceManager ) ) { - bool is_device_initialized = this->deviceManager.getCurrentAudioDevice() != nullptr ; - - if (is_device_initialized) this->storage->storeConfig(this->deviceManager.createStateXml()) ; - else AlertWindow::showMessageBox(AlertWindow::WarningIcon , GUI::DEVICE_ERROR_TITLE , - GUI::DEVICE_ERROR_MSG ) ; - this->fileTree ->setVisible( is_device_initialized) ; - this->deviceSelector->setVisible(!is_device_initialized) ; + bool is_device_ready = this->deviceManager.getCurrentAudioDevice() != nullptr ; + int tab_pane_idx = (!is_device_ready ) ? GUI::DEVICE_SELECTOR_IDX : + (File(this->projectFilename).exists()) ? GUI::COMPILATIONS_IDX : + (File(this->audioFilename ).exists()) ? GUI::CLIPS_IDX : + GUI::FILE_BROWSER_IDX ; + + if (is_device_ready) this->storage->storeConfig(this->deviceManager.createStateXml()) ; + else AlertWindow::showMessageBox(AlertWindow::WarningIcon , + GUI::DEVICE_ERROR_TITLE , + GUI::DEVICE_ERROR_MSG ) ; + + this->tabPanel->setCurrentTabIndex(tab_pane_idx) ; } } @@ -383,7 +416,7 @@ BEGIN_JUCER_METADATA @@ -396,27 +429,42 @@ BEGIN_JUCER_METADATA - + + explicitFocusOrder="0" pos="-100Cr 0 100 24" posRelativeX="f42caa46057f2a0" + posRelativeY="f42caa46057f2a0" buttonText="Head" connectedEdges="0" + needsCallback="0" radioGroupId="0"/> + explicitFocusOrder="0" pos="0Cr 0 100 24" posRelativeX="f42caa46057f2a0" + posRelativeY="f42caa46057f2a0" buttonText="Play" connectedEdges="0" + needsCallback="0" radioGroupId="0"/> + - - - + explicitFocusOrder="0" pos="100C 0 100 24" posRelativeX="f42caa46057f2a0" + posRelativeY="f42caa46057f2a0" buttonText="Tail" connectedEdges="0" + needsCallback="0" radioGroupId="0"/> + + + + + + + END_JUCER_METADATA diff --git a/Source/Views/MainContent.h b/Source/Views/MainContent.h index 47641d7..c6a4e4b 100644 --- a/Source/Views/MainContent.h +++ b/Source/Views/MainContent.h @@ -62,9 +62,10 @@ private: //[UserVariables] -- You can add your own custom variables in this section. WildcardFileFilter audioFileFilter ; - DirectoryContentsList directoryList ; TimeSliceThread workerThread ; + FileBrowserComponent* fileBrowser ; File workingDir ; + String projectFilename ; String audioFilename ; AudioFormatManager formatManager ; AudioSourcePlayer audioSourcePlayer ; @@ -110,12 +111,12 @@ private: //============================================================================== std::unique_ptr fullWaveform; std::unique_ptr clipWaveform; - std::unique_ptr groupComponent; + std::unique_ptr controlsGroup; std::unique_ptr headButton; std::unique_ptr transportButton; + std::unique_ptr clipButton; std::unique_ptr tailButton; - std::unique_ptr fileTree; - std::unique_ptr deviceSelector; + std::unique_ptr tabPanel; std::unique_ptr statusbar;