void CtrlrModulatorProcessor::setValueFromHost(const float inValue) { /* called from the audio thread */ { /* first quickly check if we need to change anything at all */ const ScopedReadLock sl (processorLock); const int possibleNewValue = denormalizeValue (inValue, minValue, maxValue); if (possibleNewValue == currentValue) { /* the host told us the same exact value we already have, we won't do anything about it */ triggerAsyncUpdate(); return; } } { /* if we got here the value from the host is new and we need to update things */ const ScopedWriteLock sl(processorLock); /* set the new value for the modulator */ currentValue = denormalizeValue (inValue, minValue, maxValue); /* send a midi message */ sendMidiMessage(); } /* update the modulator ValueTree and tell the GUI about the changes */ triggerAsyncUpdate(); }
void initialise (const String&) override { // initialise our settings file.. PropertiesFile::Options options; options.applicationName = "Juce Audio Plugin Host"; options.filenameSuffix = "settings"; options.osxLibrarySubFolder = "Preferences"; appProperties = new ApplicationProperties(); appProperties->setStorageParameters (options); LookAndFeel::setDefaultLookAndFeel (&lookAndFeel); mainWindow = new MainHostWindow(); mainWindow->setUsingNativeTitleBar (true); commandManager.registerAllCommandsForTarget (this); commandManager.registerAllCommandsForTarget (mainWindow); mainWindow->menuItemsChanged(); // Important note! We're going to use an async update here so that if we need // to re-open a file and instantiate some plugins, it will happen AFTER this // initialisation method has returned. // On Windows this probably won't make a difference, but on OSX there's a subtle event loop // issue that can happen if a plugin runs one of those irritating modal dialogs while it's // being loaded. If that happens inside this method, the OSX event loop seems to be in some // kind of special "initialisation" mode and things get confused. But if we load the plugin // later when the normal event loop is running, everything's fine. triggerAsyncUpdate(); }
void DiauproPluginAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages) { buffer.clear(); if (tagCountdown > 0) { tagCountdown--; diauproNullProcessor.setTag((uint32) 0); }else{ tagCountdown = 100; startTime = Time::getMillisecondCounterHiRes(); diauproNullProcessor.setTag((uint32) 555); } diauproNullProcessor.processBlock(buffer, midiMessages); diauproVCOProcessor.setTag(diauproNullProcessor.getTag()); diauproVCOProcessor.processBlock(buffer, midiMessages); diauproVCAProcessor.setTag(diauproVCOProcessor.getTag()); diauproVCAProcessor.processBlock(buffer, midiMessages); if (diauproVCAProcessor.getTag() > 0) { audioLatency = Time::getMillisecondCounterHiRes() - startTime; } triggerAsyncUpdate (); }
void ComboBox::setText (const String& newText, const bool dontSendChangeMessage) { for (int i = items.size(); --i >= 0;) { const ItemInfo* const item = items.getUnchecked(i); if (item->isRealItem() && item->name == newText) { setSelectedId (item->itemId, dontSendChangeMessage); return; } } lastCurrentId = 0; currentId = 0; if (label->getText() != newText) { label->setText (newText, false); if (! dontSendChangeMessage) triggerAsyncUpdate(); } repaint(); }
MainAppWindow::MainAppWindow() : DocumentWindow (JUCEApplication::getInstance()->getApplicationName(), Colours::lightgrey, DocumentWindow::allButtons) { setUsingNativeTitleBar (true); setResizable (true, false); setResizeLimits (400, 400, 10000, 10000); #if JUCE_IOS || JUCE_ANDROID setFullScreen (true); #else setBounds ((int) (0.1f * getParentWidth()), (int) (0.1f * getParentHeight()), jmax (850, (int) (0.5f * getParentWidth())), jmax (600, (int) (0.7f * getParentHeight()))); #endif contentComponent = new ContentComponent(); setContentNonOwned (contentComponent, false); setVisible (true); // this lets the command manager use keypresses that arrive in our window to send out commands addKeyListener (getApplicationCommandManager().getKeyMappings()); #if JUCE_WINDOWS || JUCE_LINUX || JUCE_MAC taskbarIcon = new DemoTaskbarComponent(); #endif #if JUCE_ANDROID setOpenGLRenderingEngine(); #endif triggerAsyncUpdate(); }
//==================================================================================== void PositionableWaveDisplay::imageChanged (AudioThumbnailImage* changedAudioThumbnailImage) { if (changedAudioThumbnailImage == &audioThumbnailImage) { { const ScopedLock sl (imageLock); cachedImage.clear (cachedImage.getBounds(), backgroundColour); triggerAsyncUpdate(); } AudioFormatReaderSource* readerSource = audioFilePlayer.getAudioFormatReaderSource(); AudioFormatReader* reader = nullptr; if (readerSource != nullptr) reader = readerSource->getAudioFormatReader(); if (reader != nullptr && reader->sampleRate > 0.0 && audioFilePlayer.getLengthInSeconds() > 0.0) { currentSampleRate = reader->sampleRate; fileLength = audioFilePlayer.getLengthInSeconds(); if (fileLength > 0.0) oneOverFileLength = 1.0 / fileLength; refreshCachedImage(); } else { currentSampleRate = 44100; fileLength = 0.0; oneOverFileLength = 1.0; } } }
void ApplicationCommandManager::registerCommand (const ApplicationCommandInfo& newCommand) { // zero isn't a valid command ID! jassert (newCommand.commandID != 0); // the name isn't optional! jassert (newCommand.shortName.isNotEmpty()); if (auto* command = getMutableCommandForID (newCommand.commandID)) { // Trying to re-register the same command ID with different parameters can often indicate a typo. // This assertion is here because I've found it useful catching some mistakes, but it may also cause // false alarms if you're deliberately updating some flags for a command. jassert (newCommand.shortName == getCommandForID (newCommand.commandID)->shortName && newCommand.categoryName == getCommandForID (newCommand.commandID)->categoryName && newCommand.defaultKeypresses == getCommandForID (newCommand.commandID)->defaultKeypresses && (newCommand.flags & (ApplicationCommandInfo::wantsKeyUpDownCallbacks | ApplicationCommandInfo::hiddenFromKeyEditor | ApplicationCommandInfo::readOnlyInKeyEditor)) == (getCommandForID (newCommand.commandID)->flags & (ApplicationCommandInfo::wantsKeyUpDownCallbacks | ApplicationCommandInfo::hiddenFromKeyEditor | ApplicationCommandInfo::readOnlyInKeyEditor))); *command = newCommand; } else { ApplicationCommandInfo* const newInfo = new ApplicationCommandInfo (newCommand); newInfo->flags &= ~ApplicationCommandInfo::isTicked; commands.add (newInfo); keyMappings->resetToDefaultMapping (newCommand.commandID); triggerAsyncUpdate(); } }
void FilenameComponent::setCurrentFile (File newFile, const bool addToRecentlyUsedList, NotificationType notification) { if (enforcedSuffix.isNotEmpty()) newFile = newFile.withFileExtension (enforcedSuffix); if (newFile.getFullPathName() != lastFilename) { lastFilename = newFile.getFullPathName(); if (addToRecentlyUsedList) addRecentlyUsedFile (newFile); filenameBox.setText (lastFilename, dontSendNotification); if (notification != dontSendNotification) { triggerAsyncUpdate(); if (notification == sendNotificationSync) handleUpdateNowIfNeeded(); } } }
void CtrlrUpdateManager::run() { #ifdef LINUX return; #endif _INF("Running update check"); sendChangeMessage(); ScopedPointer <XmlElement> xml(getUpdateData()); if (xml) { _DBG("--------------------------------------------------------------"); _DBG(xml->createDocument(String::empty)); _DBG("--------------------------------------------------------------"); if (xml->getBoolAttribute("update")) { /* new version */ triggerAsyncUpdate(); return; } } sendChangeMessage(); }
ThreadPoolJob::JobStatus EnviIPCRequestJob::runJob() { const ScopedLock sl (jobLock); webInputStream = requestURL.withPOSTData(JSON::toString(requestData)).createInputStream (true, &EnviIPCRequestJob::progressCallback, this, "Client: EnviUI", 2000, &responseHeaders); if (webInputStream) { Result res = JSON::parse (webInputStream->readEntireStreamAsString(), responseData); if (res.wasOk()) { triggerAsyncUpdate(); return (ThreadPoolJob::jobHasFinished); } else { _ERR("Response from server can't be parsed as JSON ["+res.getErrorMessage()+"]"); return (ThreadPoolJob::jobNeedsRunningAgain); } } else { _ERR("Unable to create connection to server"); return (ThreadPoolJob::jobNeedsRunningAgain); } }
void ApplicationCommandManager::registerCommand (const ApplicationCommandInfo& newCommand) { // zero isn't a valid command ID! jassert (newCommand.commandID != 0); // the name isn't optional! jassert (newCommand.shortName.isNotEmpty()); if (getCommandForID (newCommand.commandID) == 0) { ApplicationCommandInfo* const newInfo = new ApplicationCommandInfo (newCommand); newInfo->flags &= ~ApplicationCommandInfo::isTicked; commands.add (newInfo); keyMappings->resetToDefaultMapping (newCommand.commandID); triggerAsyncUpdate(); } else { // trying to re-register the same command with different parameters? jassert (newCommand.shortName == getCommandForID (newCommand.commandID)->shortName && (newCommand.description == getCommandForID (newCommand.commandID)->description || newCommand.description.isEmpty()) && newCommand.categoryName == getCommandForID (newCommand.commandID)->categoryName && newCommand.defaultKeypresses == getCommandForID (newCommand.commandID)->defaultKeypresses && (newCommand.flags & (ApplicationCommandInfo::wantsKeyUpDownCallbacks | ApplicationCommandInfo::hiddenFromKeyEditor | ApplicationCommandInfo::readOnlyInKeyEditor)) == (getCommandForID (newCommand.commandID)->flags & (ApplicationCommandInfo::wantsKeyUpDownCallbacks | ApplicationCommandInfo::hiddenFromKeyEditor | ApplicationCommandInfo::readOnlyInKeyEditor))); } }
void DexedAudioProcessor::setCurrentProgram(int index) { TRACE("setting program %d state", index); if ( lastStateSave + 2 > time(NULL) ) { TRACE("skipping save, storage recall to close"); return; } panic(); index = index > 31 ? 31 : index; unpackProgram(index); lfo.reset(data + 137); currentProgram = index; triggerAsyncUpdate(); // reset parameter display DexedAudioProcessorEditor *editor = (DexedAudioProcessorEditor *) getActiveEditor(); if ( editor == NULL ) { return; } editor->global.setParamMessage(""); panic(); }
void MainContentComponent::handleMidiNote(int midiChannel, int note) { // Display the Note parameters and add/highlight row in table corresponding to the Note _lastCommand = String::formatted("%d: Note [%d]", midiChannel, note); _commandTableModel.addRow(midiChannel, note, false); _rowToSelect = _commandTableModel.getRowForMessage(midiChannel, note, false); triggerAsyncUpdate(); }
void MainContentComponent::handleMidiCC(int midiChannel, int controller, int value) { // Display the CC parameters and add/highlight row in table corresponding to the CC _lastCommand = String::formatted("%d: CC%d [%d]", midiChannel, controller, value); _commandTableModel.addRow(midiChannel, controller, true); _rowToSelect = _commandTableModel.getRowForMessage(midiChannel, controller, true); triggerAsyncUpdate(); }
void ComboBox::sendChange (const NotificationType notification) { if (notification != dontSendNotification) triggerAsyncUpdate(); if (notification == sendNotificationSync) handleUpdateNowIfNeeded(); }
void CodeEditorComponent::deselectAll() { if (selectionStart != selectionEnd) triggerAsyncUpdate(); selectionStart = caretPos; selectionEnd = caretPos; }
void ProfileManager::handleMidiNote(int midi_channel, int note) { const MIDI_Message note_msg{midi_channel, note, false}; if (command_map_) { // return if the command isn't a valid profile-related command if (!command_map_->messageExistsInMap(note_msg)) return; if (command_map_->getCommandforMessage(note_msg) == "Previous Profile") { switch_state_ = SWITCH_STATE::PREV; triggerAsyncUpdate(); } else if (command_map_->getCommandforMessage(note_msg) == "Next Profile") { switch_state_ = SWITCH_STATE::NEXT; triggerAsyncUpdate(); } } }
void Blender::update_clock() { if (m_device) { // handle clock config in GUI thread m_update |= updt_clock; triggerAsyncUpdate(); } }
void run() { if (downloaded.loadFromWebsite()) triggerAsyncUpdate(); else AlertWindow::showMessageBox (AlertWindow::InfoIcon, "Module Update", "Couldn't connect to the JUCE webserver!"); }
ChannelViewport::ChannelViewport(int const deviceIndex_, ValueTree channelsTree_, CriticalSection &lock_) : deviceIndex(deviceIndex_), channelsTree(channelsTree_), lock(lock_) { setViewedComponent(&content); triggerAsyncUpdate(); }
// speaker setup changed by another app void WdmChMapComponent::update_speaker() { if (m_bus) { m_speaker = m_bus->speaker(); m_update |= updt_speaker; triggerAsyncUpdate(); sendActionMessage("speaker config changed"); } }
//============================================================================== void CodeEditorComponent::setTabSize (const int numSpaces, const bool insertSpaces) throw() { useSpacesForTabs = insertSpaces; if (spacesPerTab != numSpaces) { spacesPerTab = numSpaces; triggerAsyncUpdate(); } }
void ProfileManager::handleMidiCC(int midi_channel, int controller, int value) { const MIDI_Message cc{midi_channel, controller, true}; if (command_map_) { // return if the value isn't 0 or 127, or the command isn't a valid // profile-related command if ((value != 127) || !command_map_->messageExistsInMap(cc)) return; if (command_map_->getCommandforMessage(cc) == "Previous Profile") { switch_state_ = SWITCH_STATE::PREV; triggerAsyncUpdate(); } else if (command_map_->getCommandforMessage(cc) == "Next Profile") { switch_state_ = SWITCH_STATE::NEXT; triggerAsyncUpdate(); } } }
Base::Base (Model::Base::Ptr model) : m_model (model) { if (m_model != nullptr) { m_model->addListener (this); triggerAsyncUpdate (); } }
void CodeEditorComponent::moveCaretTo (const CodeDocument::Position& newPos, const bool highlighting) { caretPos = newPos; columnToTryToMaintain = -1; if (highlighting) { if (dragType == notDragging) { if (abs (caretPos.getPosition() - selectionStart.getPosition()) < abs (caretPos.getPosition() - selectionEnd.getPosition())) dragType = draggingSelectionStart; else dragType = draggingSelectionEnd; } if (dragType == draggingSelectionStart) { selectionStart = caretPos; if (selectionEnd.getPosition() < selectionStart.getPosition()) { const CodeDocument::Position temp (selectionStart); selectionStart = selectionEnd; selectionEnd = temp; dragType = draggingSelectionEnd; } } else { selectionEnd = caretPos; if (selectionEnd.getPosition() < selectionStart.getPosition()) { const CodeDocument::Position temp (selectionStart); selectionStart = selectionEnd; selectionEnd = temp; dragType = draggingSelectionStart; } } triggerAsyncUpdate(); } else { deselectAll(); } updateCaretPosition(); scrollToKeepCaretOnScreen(); updateScrollBars(); }
void callTimersSynchronously() { if (! isThreadRunning()) { // (This is relied on by some plugins in cases where the MM has // had to restart and the async callback never started) cancelPendingUpdate(); triggerAsyncUpdate(); } callTimers(); }
void ScrollBar::setCurrentRange (const Range<double>& newRange) { const Range<double> constrainedRange (totalRange.constrainRange (newRange)); if (visibleRange != constrainedRange) { visibleRange = constrainedRange; updateThumbPosition(); triggerAsyncUpdate(); } }
// device_listener callbacks void Blender::mount(tcat::dice::reference<event_device> device) { // call super's mount() first device_listener::mount(device); // which gives us an m_device reference if (m_device) { // handle mixer config in GUI thread m_update |= updt_mount; triggerAsyncUpdate(); } }
// we've been attached to a bus void WdmChMapComponent::mount(tcat::dice::reference<event_bus> bus) { // call super's mount() first bus_listener::mount(bus); // which gives us an m_bus reference if (m_bus) { m_update |= updt_mount; // notification for gui thread m_bus->attach(m_speaker_table); m_bus->attach(m_device_channels); triggerAsyncUpdate(); } }
void childBoundsChanged (Component*) override { if (recursive) { triggerAsyncUpdate(); } else { recursive = true; resizeToFitView(); recursive = true; } }