void ColumnFileBrowserContents::selectedFileChanged (const File& file) { // if last column clicked add new column if (columns[activeColumn] == columns.getLast()) { addColumn (file); } else // otherwise remove uneeded columns and change last { for (int i = 0; i < columns.size(); i++) { if (columns[activeColumn] == columns[i]) { const int numColumnsToRemove = columns.size() - i - (file.isDirectory() ? 1 : 0); removeColumn (numColumnsToRemove); if (file.isDirectory()) columns.getLast()->setRoot (file); break; } } resized(); } // stick to edges of viewport if (getWidth() < viewport->getWidth()) { viewport->setViewPosition (0, 0); } else if (file.exists() || (getRight() < viewport->getRight())) { const int ammountToSubtract = viewport->getRight() - getRight(); viewport->setViewPosition (viewport->getViewPositionX() - ammountToSubtract, 0); } }
bool ColumnFileBrowserContents::addColumn (const File& rootDirectory) { if (rootDirectory.isDirectory() && rootDirectory.exists()) { const int startingWidth = columns.getLast()->getWidth(); columns.add (new BrowserColumn (filesToDisplay)); addAndMakeVisible (columns.getLast()); columns.getLast()->setLookAndFeel (inactiveLookAndFeel); columns.getLast()->setRoot (rootDirectory); columns.getLast()->setSize (startingWidth, 50); columns.getLast()->addListener (this); columns.getLast()->addChangeListener (this); columns.getLast()->addComponentListener (this); resized(); return true; } return false; }
void RecordNode::setParameter(int parameterIndex, float newValue) { //editor->updateParameterButtons(parameterIndex); // 0 = stop recording // 1 = start recording // 2 = toggle individual channel (0.0f = OFF, anything else = ON) if (parameterIndex == 1) { // std::cout << "START RECORDING." << std::endl; if (newDirectoryNeeded) { createNewDirectory(); recordingNumber = 0; experimentNumber = 1; settingsNeeded = true; EVERY_ENGINE->directoryChanged(); } else { recordingNumber++; // increment recording number within this directory } if (!rootFolder.exists()) { rootFolder.createDirectory(); } if (settingsNeeded) { String settingsFileName = rootFolder.getFullPathName() + File::separator + "settings" + ((experimentNumber > 1) ? "_" + String(experimentNumber) : String::empty) + ".xml"; AccessClass::getEditorViewport()->saveState(File(settingsFileName), m_lastSettingsText); settingsNeeded = false; } m_recordThread->setFileComponents(rootFolder, experimentNumber, recordingNumber); channelMap.clear(); int totChans = channelPointers.size(); OwnedArray<RecordProcessorInfo> procInfo; Array<int> chanProcessorMap; Array<int> chanOrderinProc; int lastProcessor = -1; int procIndex = -1; int chanProcOrder = 0; for (int ch = 0; ch < totChans; ++ch) { Channel* chan = channelPointers[ch]; if (chan->getRecordState()) { channelMap.add(ch); //This is bassed on the assumption that all channels from the same processor are added contiguously //If this behaviour changes, this check should be most thorough if (chan->nodeId != lastProcessor) { lastProcessor = chan->nodeId; RecordProcessorInfo* pi = new RecordProcessorInfo(); pi->processorId = chan->nodeId; procInfo.add(pi); procIndex++; chanProcOrder = 0; } procInfo.getLast()->recordedChannels.add(channelMap.size()-1); chanProcessorMap.add(procIndex); chanOrderinProc.add(chanProcOrder); chanProcOrder++; } } std::cout << "Num Recording Processors: " << procInfo.size() << std::endl; int numRecordedChannels = channelMap.size(); //WARNING: If at some point we record at more that one recordEngine at once, we should change this, as using OwnedArrays only works for the first EVERY_ENGINE->setChannelMapping(channelMap, chanProcessorMap, chanOrderinProc, procInfo); m_recordThread->setChannelMap(channelMap); m_dataQueue->setChannels(numRecordedChannels); m_eventQueue->reset(); m_spikeQueue->reset(); m_recordThread->setFirstBlockFlag(false); setFirstBlock = false; m_recordThread->startThread(); isRecording = true; hasRecorded = true; } else if (parameterIndex == 0) { std::cout << "STOP RECORDING." << std::endl; if (isRecording) { isRecording = false; // close the writing thread. m_recordThread->signalThreadShouldExit(); m_recordThread->waitForThreadToExit(2000); while (m_recordThread->isThreadRunning()) { std::cerr << "RecordEngine timeout" << std::endl; if (AlertWindow::showOkCancelBox(AlertWindow::WarningIcon, "Record Thread timeout", "The recording thread is taking too long to close.\nThis could mean there is still data waiting to be written in the buffer, but it normally " "shouldn't take this long.\nYou can either wait a bit more or forcefully close the thread. Note that data might be lost or corrupted" "if forcibly closing the thread.", "Stop the thread", "Wait a bit more")) { m_recordThread->stopThread(100); m_recordThread->forceCloseFiles(); } else { m_recordThread->waitForThreadToExit(2000); } } } } else if (parameterIndex == 2) { if (isProcessing) { std::cout << "Toggling channel " << currentChannel << std::endl; if (isRecording) { //Toggling channels while recording isn't allowed. Code shouldn't reach here. //In case it does, display an error and exit. CoreServices::sendStatusMessage("Toggling record channels while recording is not allowed"); std::cout << "ERROR: Wrong code section reached\n Toggling record channels while recording is not allowed." << std::endl; return; } if (newValue == 0.0f) { channelPointers[currentChannel]->setRecordState(false); } else { channelPointers[currentChannel]->setRecordState(true); } } } }
//============================================================================== bool UndoManager::perform (UndoableAction* const command_, const String& actionName) { if (command_ != 0) { ScopedPointer<UndoableAction> command (command_); if (actionName.isNotEmpty()) currentTransactionName = actionName; if (reentrancyCheck) { jassertfalse; // don't call perform() recursively from the UndoableAction::perform() or // undo() methods, or else these actions won't actually get done. return false; } else if (command->perform()) { OwnedArray<UndoableAction>* commandSet = transactions [nextIndex - 1]; if (commandSet != 0 && ! newTransaction) { UndoableAction* lastAction = commandSet->getLast(); if (lastAction != 0) { UndoableAction* coalescedAction = lastAction->createCoalescedAction (command); if (coalescedAction != 0) { command = coalescedAction; totalUnitsStored -= lastAction->getSizeInUnits(); commandSet->removeLast(); } } } else { commandSet = new OwnedArray<UndoableAction>(); transactions.insert (nextIndex, commandSet); transactionNames.insert (nextIndex, currentTransactionName); ++nextIndex; } totalUnitsStored += command->getSizeInUnits(); commandSet->add (command.release()); newTransaction = false; while (nextIndex < transactions.size()) { const OwnedArray <UndoableAction>* const lastSet = transactions.getLast(); for (int i = lastSet->size(); --i >= 0;) totalUnitsStored -= lastSet->getUnchecked (i)->getSizeInUnits(); transactions.removeLast(); transactionNames.remove (transactionNames.size() - 1); } while (nextIndex > 0 && totalUnitsStored > maxNumUnitsToKeep && transactions.size() > minimumTransactionsToKeep) { const OwnedArray <UndoableAction>* const firstSet = transactions.getFirst(); for (int i = firstSet->size(); --i >= 0;) totalUnitsStored -= firstSet->getUnchecked (i)->getSizeInUnits(); jassert (totalUnitsStored >= 0); // something fishy going on if this fails! transactions.remove (0); transactionNames.remove (0); --nextIndex; } sendChangeMessage(); return true; } } return false; }