const ResizableBorderComponent::Zone ResizableBorderComponent::Zone::fromPositionOnBorder (const Rectangle<int>& totalSize, const BorderSize<int>& border, const Point<int>& position) { int z = 0; if (totalSize.contains (position) && ! border.subtractedFrom (totalSize).contains (position)) { const int minW = jmax (totalSize.getWidth() / 10, jmin (10, totalSize.getWidth() / 3)); if (position.x < jmax (border.getLeft(), minW) && border.getLeft() > 0) z |= left; else if (position.x >= totalSize.getWidth() - jmax (border.getRight(), minW) && border.getRight() > 0) z |= right; const int minH = jmax (totalSize.getHeight() / 10, jmin (10, totalSize.getHeight() / 3)); if (position.y < jmax (border.getTop(), minH) && border.getTop() > 0) z |= top; else if (position.y >= totalSize.getHeight() - jmax (border.getBottom(), minH) && border.getBottom() > 0) z |= bottom; } return Zone (z); }
void GraphComponent::setNodeDisplayName(BasePlugin* plugin, GraphNodeComponent* node, const String& newName) { plugin->setInstanceName(newName); node->setText(newName); int w = plugin->getIntValue (PROP_GRAPHWSIZE, defaultNodeWidth); int h = plugin->getIntValue (PROP_GRAPHHSIZE, defaultNodeHeight); int numIns = plugin->getNumInputs () + plugin->getNumMidiInputs (); int numOuts = plugin->getNumOutputs () + plugin->getNumMidiOutputs (); if (leftToRight) { h = jmax (h, (jmax (numIns, numOuts) + 1) * 16); const int textHeight = currentFont.getStringWidth (plugin->getInstanceName()); h = jmax (h, 16 + jmin (textHeight, 300)); } else { w = jmax (w, (jmax (numIns, numOuts) + 1) * 16); const int textWidth = currentFont.getStringWidth (plugin->getInstanceName()); w = jmax (w, 16 + jmin (textWidth, 300)); } int wSize = w; if (wSize < 0) wSize = defaultNodeWidth; int hSize = h; if (hSize < 0) hSize = defaultNodeHeight; String pluginTooltip = plugin->getInstanceName (); node->setTooltip (pluginTooltip); plugin->setValue (PROP_GRAPHWSIZE, wSize); plugin->setValue (PROP_GRAPHHSIZE, hSize); node->setSize (wSize, hSize); }
//============================================================================== void CPUInformation::initialise() noexcept { numCpus = jmax ((int) 1, (int) sysconf (_SC_NPROCESSORS_ONLN)); }
bool BufferingAudioSource::readNextBufferChunk() { int64 newBVS, newBVE, sectionToReadStart, sectionToReadEnd; { const ScopedLock sl (bufferStartPosLock); if (wasSourceLooping != isLooping()) { wasSourceLooping = isLooping(); bufferValidStart = 0; bufferValidEnd = 0; } newBVS = jmax ((int64) 0, nextPlayPos); newBVE = newBVS + buffer.getNumSamples() - 4; sectionToReadStart = 0; sectionToReadEnd = 0; const int maxChunkSize = 2048; if (newBVS < bufferValidStart || newBVS >= bufferValidEnd) { newBVE = jmin (newBVE, newBVS + maxChunkSize); sectionToReadStart = newBVS; sectionToReadEnd = newBVE; bufferValidStart = 0; bufferValidEnd = 0; } else if (std::abs ((int) (newBVS - bufferValidStart)) > 512 || std::abs ((int) (newBVE - bufferValidEnd)) > 512) { newBVE = jmin (newBVE, bufferValidEnd + maxChunkSize); sectionToReadStart = bufferValidEnd; sectionToReadEnd = newBVE; bufferValidStart = newBVS; bufferValidEnd = jmin (bufferValidEnd, newBVE); } } if (sectionToReadStart == sectionToReadEnd) return false; jassert (buffer.getNumSamples() > 0); const int bufferIndexStart = (int) (sectionToReadStart % buffer.getNumSamples()); const int bufferIndexEnd = (int) (sectionToReadEnd % buffer.getNumSamples()); if (bufferIndexStart < bufferIndexEnd) { readBufferSection (sectionToReadStart, (int) (sectionToReadEnd - sectionToReadStart), bufferIndexStart); } else { const int initialSize = buffer.getNumSamples() - bufferIndexStart; readBufferSection (sectionToReadStart, initialSize, bufferIndexStart); readBufferSection (sectionToReadStart + initialSize, (int) (sectionToReadEnd - sectionToReadStart) - initialSize, 0); } { const ScopedLock sl2 (bufferStartPosLock); bufferValidStart = newBVS; bufferValidEnd = newBVE; } bufferReadyEvent.signal(); return true; }
void CodeDocument::remove (const int startPos, const int endPos, const bool undoable) { if (endPos <= startPos) return; if (undoable) { undoManager.perform (new CodeDocumentDeleteAction (*this, startPos, endPos)); } else { Position startPosition (this, startPos); Position endPosition (this, endPos); maximumLineLength = -1; const int firstAffectedLine = startPosition.getLineNumber(); const int endLine = endPosition.getLineNumber(); int lastAffectedLine = firstAffectedLine + 1; CodeDocumentLine* const firstLine = lines.getUnchecked (firstAffectedLine); if (firstAffectedLine == endLine) { firstLine->line = firstLine->line.substring (0, startPosition.getIndexInLine()) + firstLine->line.substring (endPosition.getIndexInLine()); firstLine->updateLength(); } else { lastAffectedLine = lines.size(); CodeDocumentLine* const lastLine = lines.getUnchecked (endLine); jassert (lastLine != nullptr); firstLine->line = firstLine->line.substring (0, startPosition.getIndexInLine()) + lastLine->line.substring (endPosition.getIndexInLine()); firstLine->updateLength(); int numLinesToRemove = endLine - firstAffectedLine; lines.removeRange (firstAffectedLine + 1, numLinesToRemove); } int i; for (i = firstAffectedLine + 1; i < lines.size(); ++i) { CodeDocumentLine* const l = lines.getUnchecked (i); const CodeDocumentLine* const previousLine = lines.getUnchecked (i - 1); l->lineStartInFile = previousLine->lineStartInFile + previousLine->lineLength; } checkLastLineStatus(); const int totalChars = getNumCharacters(); for (i = 0; i < positionsToMaintain.size(); ++i) { CodeDocument::Position* p = positionsToMaintain.getUnchecked(i); if (p->getPosition() > startPosition.getPosition()) p->setPosition (jmax (startPos, p->getPosition() + startPos - endPos)); if (p->getPosition() > totalChars) p->setPosition (totalChars); } sendListenerChangeMessage (firstAffectedLine, lastAffectedLine); } }
void Sequencer::setNoteLength (int noteLength_) { noteLength = jmax(noteLength_, 1); }
//============================================================================== bool ListBox::keyPressed (const KeyPress& key) { const int numVisibleRows = viewport->getHeight() / getRowHeight(); const bool multiple = multipleSelection && (lastRowSelected >= 0) && (key.getModifiers().isShiftDown() || key.getModifiers().isCtrlDown() || key.getModifiers().isCommandDown()); if (key.isKeyCode (KeyPress::upKey)) { if (multiple) selectRangeOfRows (lastRowSelected, lastRowSelected - 1); else selectRow (jmax (0, lastRowSelected - 1)); } else if (key.isKeyCode (KeyPress::returnKey) && isRowSelected (lastRowSelected)) { if (model != nullptr) model->returnKeyPressed (lastRowSelected); } else if (key.isKeyCode (KeyPress::pageUpKey)) { if (multiple) selectRangeOfRows (lastRowSelected, lastRowSelected - numVisibleRows); else selectRow (jmax (0, jmax (0, lastRowSelected) - numVisibleRows)); } else if (key.isKeyCode (KeyPress::pageDownKey)) { if (multiple) selectRangeOfRows (lastRowSelected, lastRowSelected + numVisibleRows); else selectRow (jmin (totalItems - 1, jmax (0, lastRowSelected) + numVisibleRows)); } else if (key.isKeyCode (KeyPress::homeKey)) { if (multiple && key.getModifiers().isShiftDown()) selectRangeOfRows (lastRowSelected, 0); else selectRow (0); } else if (key.isKeyCode (KeyPress::endKey)) { if (multiple && key.getModifiers().isShiftDown()) selectRangeOfRows (lastRowSelected, totalItems - 1); else selectRow (totalItems - 1); } else if (key.isKeyCode (KeyPress::downKey)) { if (multiple) selectRangeOfRows (lastRowSelected, lastRowSelected + 1); else selectRow (jmin (totalItems - 1, jmax (0, lastRowSelected) + 1)); } else if ((key.isKeyCode (KeyPress::deleteKey) || key.isKeyCode (KeyPress::backspaceKey)) && isRowSelected (lastRowSelected)) { if (model != nullptr) model->deleteKeyPressed (lastRowSelected); } else if (multiple && key == KeyPress ('a', ModifierKeys::commandModifier, 0)) { selectRangeOfRows (0, std::numeric_limits<int>::max()); } else { return false; } return true; }
void TabbedButtonBar::resized() { int depth = getWidth(); int length = getHeight(); if (orientation == TabsAtTop || orientation == TabsAtBottom) std::swap (depth, length); const int overlap = getLookAndFeel().getTabButtonOverlap (depth) + getLookAndFeel().getTabButtonSpaceAroundImage() * 2; int i, totalLength = overlap; int numVisibleButtons = tabs.size(); for (i = 0; i < tabs.size(); ++i) { TabBarButton* const tb = tabs.getUnchecked(i)->component; totalLength += tb->getBestTabLength (depth) - overlap; tb->overlapPixels = overlap / 2; } double scale = 1.0; if (totalLength > length) scale = jmax (minimumScale, length / (double) totalLength); const bool isTooBig = totalLength * scale > length; int tabsButtonPos = 0; if (isTooBig) { if (extraTabsButton == nullptr) { addAndMakeVisible (extraTabsButton = getLookAndFeel().createTabBarExtrasButton()); extraTabsButton->addListener (behindFrontTab); extraTabsButton->setAlwaysOnTop (true); extraTabsButton->setTriggeredOnMouseDown (true); } const int buttonSize = jmin (proportionOfWidth (0.7f), proportionOfHeight (0.7f)); extraTabsButton->setSize (buttonSize, buttonSize); if (orientation == TabsAtTop || orientation == TabsAtBottom) { tabsButtonPos = getWidth() - buttonSize / 2 - 1; extraTabsButton->setCentrePosition (tabsButtonPos, getHeight() / 2); } else { tabsButtonPos = getHeight() - buttonSize / 2 - 1; extraTabsButton->setCentrePosition (getWidth() / 2, tabsButtonPos); } totalLength = 0; for (i = 0; i < tabs.size(); ++i) { TabBarButton* const tb = tabs.getUnchecked(i)->component; const int newLength = totalLength + tb->getBestTabLength (depth); if (i > 0 && newLength * minimumScale > tabsButtonPos) { totalLength += overlap; break; } numVisibleButtons = i + 1; totalLength = newLength - overlap; } scale = jmax (minimumScale, tabsButtonPos / (double) totalLength); } else { extraTabsButton = nullptr; } int pos = 0; TabBarButton* frontTab = nullptr; for (i = 0; i < tabs.size(); ++i) { TabBarButton* const tb = getTabButton (i); if (tb != nullptr) { const int bestLength = roundToInt (scale * tb->getBestTabLength (depth)); if (i < numVisibleButtons) { if (orientation == TabsAtTop || orientation == TabsAtBottom) tb->setBounds (pos, 0, bestLength, getHeight()); else tb->setBounds (0, pos, getWidth(), bestLength); tb->toBack(); if (i == currentTabIndex) frontTab = tb; tb->setVisible (true); } else { tb->setVisible (false); } pos += bestLength - overlap; } } behindFrontTab->setBounds (getLocalBounds()); if (frontTab != nullptr) { frontTab->toFront (false); behindFrontTab->toBehind (frontTab); } }
static String getLinkedFile (const String& file) { HeapBlock<char> buffer (8194); const int numBytes = (int) readlink (file.toRawUTF8(), buffer, 8192); return String::fromUTF8 (buffer, jmax (0, numBytes)); };
//============================================================================== void BubbleComponent::setPosition (const Rectangle<int>& rectangleToPointTo) { Rectangle<int> availableSpace (getParentComponent() != nullptr ? getParentComponent()->getLocalBounds() : getParentMonitorArea()); int x = 0; int y = 0; int w = 150; int h = 30; getContentSize (w, h); w += 30; h += 30; const float edgeIndent = 2.0f; const int arrowLength = jmin (10, h / 3, w / 3); int spaceAbove = ((allowablePlacements & above) != 0) ? jmax (0, rectangleToPointTo.getY() - availableSpace.getY()) : -1; int spaceBelow = ((allowablePlacements & below) != 0) ? jmax (0, availableSpace.getBottom() - rectangleToPointTo.getBottom()) : -1; int spaceLeft = ((allowablePlacements & left) != 0) ? jmax (0, rectangleToPointTo.getX() - availableSpace.getX()) : -1; int spaceRight = ((allowablePlacements & right) != 0) ? jmax (0, availableSpace.getRight() - rectangleToPointTo.getRight()) : -1; // look at whether the component is elongated, and if so, try to position next to its longer dimension. if (rectangleToPointTo.getWidth() > rectangleToPointTo.getHeight() * 2 && (spaceAbove > h + 20 || spaceBelow > h + 20)) { spaceLeft = spaceRight = 0; } else if (rectangleToPointTo.getWidth() < rectangleToPointTo.getHeight() / 2 && (spaceLeft > w + 20 || spaceRight > w + 20)) { spaceAbove = spaceBelow = 0; } if (jmax (spaceAbove, spaceBelow) >= jmax (spaceLeft, spaceRight)) { x = rectangleToPointTo.getX() + (rectangleToPointTo.getWidth() - w) / 2; arrowTipX = w * 0.5f; content.setSize (w, h - arrowLength); if (spaceAbove >= spaceBelow) { // above y = rectangleToPointTo.getY() - h; content.setPosition (0, 0); arrowTipY = h - edgeIndent; side = 2; } else { // below y = rectangleToPointTo.getBottom(); content.setPosition (0, arrowLength); arrowTipY = edgeIndent; side = 0; } } else { y = rectangleToPointTo.getY() + (rectangleToPointTo.getHeight() - h) / 2; arrowTipY = h * 0.5f; content.setSize (w - arrowLength, h); if (spaceLeft > spaceRight) { // on the left x = rectangleToPointTo.getX() - w; content.setPosition (0, 0); arrowTipX = w - edgeIndent; side = 3; } else { // on the right x = rectangleToPointTo.getRight(); content.setPosition (arrowLength, 0); arrowTipX = edgeIndent; side = 1; } } setBounds (x, y, w, h); }
void AudioFormatReader::readMaxLevels (int64 startSampleInFile, int64 numSamples, float& lowestLeft, float& highestLeft, float& lowestRight, float& highestRight) { if (numSamples <= 0) { lowestLeft = 0; lowestRight = 0; highestLeft = 0; highestRight = 0; return; } const int bufferSize = (int) jmin (numSamples, (int64) 4096); HeapBlock<int> tempSpace ((size_t) bufferSize * 2 + 64); int* tempBuffer[3]; tempBuffer[0] = tempSpace.getData(); tempBuffer[1] = tempSpace.getData() + bufferSize; tempBuffer[2] = 0; if (usesFloatingPointData) { float lmin = 1.0e6f; float lmax = -lmin; float rmin = lmin; float rmax = lmax; while (numSamples > 0) { const int numToDo = (int) jmin (numSamples, (int64) bufferSize); read (tempBuffer, 2, startSampleInFile, numToDo, false); numSamples -= numToDo; startSampleInFile += numToDo; float bufMin, bufMax; findMinAndMax (reinterpret_cast<float*> (tempBuffer[0]), numToDo, bufMin, bufMax); lmin = jmin (lmin, bufMin); lmax = jmax (lmax, bufMax); if (numChannels > 1) { findMinAndMax (reinterpret_cast<float*> (tempBuffer[1]), numToDo, bufMin, bufMax); rmin = jmin (rmin, bufMin); rmax = jmax (rmax, bufMax); } } if (numChannels <= 1) { rmax = lmax; rmin = lmin; } lowestLeft = lmin; highestLeft = lmax; lowestRight = rmin; highestRight = rmax; } else { int lmax = std::numeric_limits<int>::min(); int lmin = std::numeric_limits<int>::max(); int rmax = std::numeric_limits<int>::min(); int rmin = std::numeric_limits<int>::max(); while (numSamples > 0) { const int numToDo = (int) jmin (numSamples, (int64) bufferSize); if (! read (tempBuffer, 2, startSampleInFile, numToDo, false)) break; numSamples -= numToDo; startSampleInFile += numToDo; for (int j = (int) numChannels; --j >= 0;) { int bufMin, bufMax; findMinAndMax (tempBuffer[j], numToDo, bufMin, bufMax); if (j == 0) { lmax = jmax (lmax, bufMax); lmin = jmin (lmin, bufMin); } else { rmax = jmax (rmax, bufMax); rmin = jmin (rmin, bufMin); } } } if (numChannels <= 1) { rmax = lmax; rmin = lmin; } lowestLeft = lmin / (float) std::numeric_limits<int>::max(); highestLeft = lmax / (float) std::numeric_limits<int>::max(); lowestRight = rmin / (float) std::numeric_limits<int>::max(); highestRight = rmax / (float) std::numeric_limits<int>::max(); } }
JUCE_COMRESULT DrawGlyphRun (void* clientDrawingContext, FLOAT baselineOriginX, FLOAT baselineOriginY, DWRITE_MEASURING_MODE, DWRITE_GLYPH_RUN const* glyphRun, DWRITE_GLYPH_RUN_DESCRIPTION const* runDescription, IUnknown* clientDrawingEffect) { TextLayout* const layout = static_cast<TextLayout*> (clientDrawingContext); if (baselineOriginY != lastOriginY) { lastOriginY = baselineOriginY; ++currentLine; if (currentLine >= layout->getNumLines()) { jassert (currentLine == layout->getNumLines()); TextLayout::Line* const newLine = new TextLayout::Line(); layout->addLine (newLine); newLine->lineOrigin = Point<float> (baselineOriginX, baselineOriginY); } } TextLayout::Line& glyphLine = layout->getLine (currentLine); DWRITE_FONT_METRICS dwFontMetrics; glyphRun->fontFace->GetMetrics (&dwFontMetrics); glyphLine.ascent = jmax (glyphLine.ascent, scaledFontSize (dwFontMetrics.ascent, dwFontMetrics, glyphRun)); glyphLine.descent = jmax (glyphLine.descent, scaledFontSize (dwFontMetrics.descent, dwFontMetrics, glyphRun)); String fontFamily, fontStyle; getFontFamilyAndStyle (glyphRun, fontFamily, fontStyle); TextLayout::Run* const glyphRunLayout = new TextLayout::Run (Range<int> (runDescription->textPosition, runDescription->textPosition + runDescription->stringLength), glyphRun->glyphCount); glyphLine.runs.add (glyphRunLayout); glyphRun->fontFace->GetMetrics (&dwFontMetrics); const float totalHeight = std::abs ((float) dwFontMetrics.ascent) + std::abs ((float) dwFontMetrics.descent); const float fontHeightToEmSizeFactor = (float) dwFontMetrics.designUnitsPerEm / totalHeight; glyphRunLayout->font = Font (fontFamily, fontStyle, glyphRun->fontEmSize / fontHeightToEmSizeFactor); glyphRunLayout->colour = getColourOf (static_cast<ID2D1SolidColorBrush*> (clientDrawingEffect)); const Point<float> lineOrigin (layout->getLine (currentLine).lineOrigin); float x = baselineOriginX - lineOrigin.x; for (UINT32 i = 0; i < glyphRun->glyphCount; ++i) { const float advance = glyphRun->glyphAdvances[i]; if ((glyphRun->bidiLevel & 1) != 0) x -= advance; // RTL text glyphRunLayout->glyphs.add (TextLayout::Glyph (glyphRun->glyphIndices[i], Point<float> (x, baselineOriginY - lineOrigin.y), advance)); if ((glyphRun->bidiLevel & 1) == 0) x += advance; // LTR text } return S_OK; }
int read (void* buffer, int bytesToRead) override { if (finished || isError()) return 0; if (isChunked && ! readingChunk) { if (position >= chunkEnd) { const ScopedValueSetter<bool> setter (readingChunk, true, false); MemoryOutputStream chunkLengthBuffer; char c = 0; if (chunkEnd > 0) { if (read (&c, 1) != 1 || c != '\r' || read (&c, 1) != 1 || c != '\n') { finished = true; return 0; } } while (chunkLengthBuffer.getDataSize() < 512 && ! (finished || isError())) { if (read (&c, 1) != 1) { finished = true; return 0; } if (c == '\r') continue; if (c == '\n') break; chunkLengthBuffer.writeByte (c); } const int64 chunkSize = chunkLengthBuffer.toString().trimStart().getHexValue64(); if (chunkSize == 0) { finished = true; return 0; } chunkEnd += chunkSize; } if (bytesToRead > chunkEnd - position) bytesToRead = static_cast<int> (chunkEnd - position); } fd_set readbits; FD_ZERO (&readbits); FD_SET (socketHandle, &readbits); struct timeval tv; tv.tv_sec = jmax (1, timeOutMs / 1000); tv.tv_usec = 0; if (select (socketHandle + 1, &readbits, 0, 0, &tv) <= 0) return 0; // (timeout) const int bytesRead = jmax (0, (int) recv (socketHandle, buffer, (size_t) bytesToRead, MSG_WAITALL)); if (bytesRead == 0) finished = true; if (! readingChunk) position += bytesRead; return bytesRead; }
void GlyphArrangement::splitLines (const String& text, Font font, int startIndex, float x, float y, float width, float height, int maximumLines, float lineWidth, Justification layout, float minimumHorizontalScale) { const int length = text.length(); const int originalStartIndex = startIndex; int numLines = 1; if (length <= 12 && ! text.containsAnyOf (" -\t\r\n")) maximumLines = 1; maximumLines = jmin (maximumLines, length); while (numLines < maximumLines) { ++numLines; const float newFontHeight = height / (float) numLines; if (newFontHeight < font.getHeight()) { font.setHeight (jmax (8.0f, newFontHeight)); removeRangeOfGlyphs (startIndex, -1); addLineOfText (font, text, x, y); lineWidth = glyphs.getReference (glyphs.size() - 1).getRight() - glyphs.getReference (startIndex).getLeft(); } // Try to estimate the point at which there are enough lines to fit the text, // allowing for unevenness in the lengths due to differently sized words. const float lineLengthUnevennessAllowance = 80.0f; if (numLines > (lineWidth + lineLengthUnevennessAllowance) / width || newFontHeight < 8.0f) break; } if (numLines < 1) numLines = 1; float lineY = y; float widthPerLine = lineWidth / numLines; for (int line = 0; line < numLines; ++line) { int i = startIndex; float lineStartX = glyphs.getReference (startIndex).getLeft(); if (line == numLines - 1) { widthPerLine = width; i = glyphs.size(); } else { while (i < glyphs.size()) { lineWidth = (glyphs.getReference (i).getRight() - lineStartX); if (lineWidth > widthPerLine) { // got to a point where the line's too long, so skip forward to find a // good place to break it.. const int searchStartIndex = i; while (i < glyphs.size()) { if ((glyphs.getReference (i).getRight() - lineStartX) * minimumHorizontalScale < width) { if (glyphs.getReference (i).isWhitespace() || glyphs.getReference (i).getCharacter() == '-') { ++i; break; } } else { // can't find a suitable break, so try looking backwards.. i = searchStartIndex; for (int back = 1; back < jmin (7, i - startIndex - 1); ++back) { if (glyphs.getReference (i - back).isWhitespace() || glyphs.getReference (i - back).getCharacter() == '-') { i -= back - 1; break; } } break; } ++i; } break; } ++i; } int wsStart = i; while (wsStart > 0 && glyphs.getReference (wsStart - 1).isWhitespace()) --wsStart; int wsEnd = i; while (wsEnd < glyphs.size() && glyphs.getReference (wsEnd).isWhitespace()) ++wsEnd; removeRangeOfGlyphs (wsStart, wsEnd - wsStart); i = jmax (wsStart, startIndex + 1); } i -= fitLineIntoSpace (startIndex, i - startIndex, x, lineY, width, font.getHeight(), font, layout.getOnlyHorizontalFlags() | Justification::verticallyCentred, minimumHorizontalScale); startIndex = i; lineY += font.getHeight(); if (startIndex >= glyphs.size()) break; } justifyGlyphs (originalStartIndex, glyphs.size() - originalStartIndex, x, y, width, height, layout.getFlags() & ~Justification::horizontallyJustified); }
my::Parameters my::Torus::_sampled(const int & i, const int & j)const throw(std::logic_error, std::invalid_argument) { _preSampled("Torus", "path angle", "tube angle", "[0,imax()-1]", "[0, jmax()-1]", i, imax()-1, j, jmax()-1); float pathAngle, tubeAngle; float pathAngleStep, tubeAngleStep; pathAngleStep = my::Constant::pi / _nbSlices; tubeAngleStep = my::Constant::pi / (_nbStacks+1); pathAngle = i*pathAngleStep; tubeAngle = j*tubeAngleStep; return my::Parameters(pathAngle, tubeAngle); }
inline int getPeak() const noexcept { return jmax (std::abs ((int) values[0]), std::abs ((int) values[1])); }
double AudioThumbnail::getProportionComplete() const noexcept { return jlimit (0.0, 1.0, numSamplesFinished / (double) jmax ((int64) 1, totalSamples)); }
bool update (CodeDocument& document, int lineNum, CodeDocument::Iterator& source, CodeTokeniser* analyser, const int spacesPerTab, const CodeDocument::Position& selectionStart, const CodeDocument::Position& selectionEnd) { OwnedArray <SyntaxToken> newTokens; if (analyser == 0) { newTokens.add (new SyntaxToken (document.getLine (lineNum), -1)); } else if (lineNum < document.getNumLines()) { const CodeDocument::Position pos (&document, lineNum, 0); createTokens (pos.getPosition(), pos.getLineText(), source, analyser, newTokens); } replaceTabsWithSpaces (newTokens, spacesPerTab); int newHighlightStart = 0; int newHighlightEnd = 0; if (selectionStart.getLineNumber() <= lineNum && selectionEnd.getLineNumber() >= lineNum) { const String line (document.getLine (lineNum)); CodeDocument::Position lineStart (&document, lineNum, 0), lineEnd (&document, lineNum + 1, 0); newHighlightStart = indexToColumn (jmax (0, selectionStart.getPosition() - lineStart.getPosition()), line, spacesPerTab); newHighlightEnd = indexToColumn (jmin (lineEnd.getPosition() - lineStart.getPosition(), selectionEnd.getPosition() - lineStart.getPosition()), line, spacesPerTab); } if (newHighlightStart != highlightColumnStart || newHighlightEnd != highlightColumnEnd) { highlightColumnStart = newHighlightStart; highlightColumnEnd = newHighlightEnd; } else { if (tokens.size() == newTokens.size()) { bool allTheSame = true; for (int i = newTokens.size(); --i >= 0;) { if (*tokens.getUnchecked(i) != *newTokens.getUnchecked(i)) { allTheSame = false; break; } } if (allTheSame) return false; } } tokens.swapWithArray (newTokens); return true; }
ListBoxRowComponent* getComponentForRow (const int row) const noexcept { return rows [row % jmax (1, rows.size())]; }
int CallOutBox::getBorderSize() const noexcept { return jmax (getLookAndFeel().getCallOutBoxBorderSize (*this), (int) arrowSize); }
//============================================================================== void ListBox::setRowHeight (const int newHeight) { rowHeight = jmax (1, newHeight); viewport->setSingleStepSizes (20, rowHeight); updateContent(); }
bool SubregionStream::setPosition (int64 newPosition) { return source->setPosition (jmax ((int64) 0, newPosition + startPositionInSourceStream)); }
void Sequencer::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages) { AudioPlayHead::CurrentPositionInfo pos (pluginAudioProcessor->lastPosInfo); // If we aren't playing... if (! pos.isPlaying) { if (noteOffs.size() > 0) { // Send any upcoming note-off events Array<NoteOff*> notesToRemove; for (int i = 0; i < noteOffs.size(); i++) { int noteNumber = noteOffs[i]->noteNumber; MidiMessage m2 = MidiMessage::noteOff (1, noteNumber); midiMessages.addEvent (m2, 0); playingNotes.set (noteNumber, false); notesToRemove.add (noteOffs[i]); } for (int i = 0; i < notesToRemove.size(); i++) { // Remove the event from the note-off event list // (We do this in two steps so that the noteOffs array isn't modified inside a loop) noteOffs.removeObject (notesToRemove[i], true); } } return; } double ppq = pos.ppqPosition; double timeInSeconds = pos.timeInSeconds; double bpm = pos.bpm; //if (primary) { SharedState::getInstance()->setPpqPosition (ppq); SharedState::getInstance()->setTimeInSeconds (timeInSeconds); SharedState::getInstance()->setBpm (bpm); //} /* int numerator = pos.timeSigNumerator; int denominator = pos.timeSigDenominator; const int ppqPerBar = (numerator * 4 / denominator); // e.g. 4 if 4/4 const double beats = (fmod (ppq, ppqPerBar) / ppqPerBar) * numerator; const int bar = ((int) ppq) / ppqPerBar + 1; const int beat = ((int) beats) + 1; const int ticks = ((int) (fmod (beats, 1.0) * 960.0)); */ double tickCountPrecise = fmod (ppq * speed * ticksPerCol, getTotalCols() * ticksPerCol); tickCount = (int)tickCountPrecise; lastPlayheadColPrecise = tickCountPrecise / ticksPerCol; jassert (lastPlayheadColPrecise >= 0.0) jassert (lastPlayheadColPrecise <= 16.0) //if (primary) { SharedState::getInstance()->setPlayheadColPrecise (lastPlayheadColPrecise); //} if (tickCount != lastTickCount) { lastTickCount = tickCount; // Check if we should be degrading... int panelIndex = pluginAudioProcessor->getPanelIndex(); int state = SharedState::getInstance()->getState(panelIndex); if (state == Panel::DEGRADING_SLOW || state == Panel::DEGRADING_FAST) { // degrade at most once per tempo sweep, in column 0 if (getPlayheadCol() == 0) { if (!columnZeroDegradeUpdate) { SharedState::getInstance()->degradeStep(panelIndex); columnZeroDegradeUpdate = true; } } else { columnZeroDegradeUpdate = false; } } else { columnZeroDegradeUpdate = false; if (state == Panel::ACTIVE) { if (SharedState::kDegradeAfterInactiveSec > 0 && (SharedState::getInstance()->getLastTouchElapsedMs(panelIndex) >= SharedState::kDegradeAfterInactiveSec * 1000)) { DBG(String(Time::currentTimeMillis()) + " " + "Start degrading panel " + String(panelIndex)); SharedState::getInstance()->startDegrade(panelIndex); } } } // Update starfield if necessary if (SharedState::getInstance()->getStarFieldActive()) { // bug:67 - for production running, we could assert that the following is true: // SharedState::getInstance()->allAttracting() // but that won't work if someone turns on the star field by hand via the sequencer GUI if (pluginAudioProcessor->getPanelIndex() == 0) { SharedState::getInstance()->updateStarField(); } } bool playCol = false; // play the current column of notes? float velocity = 0.9f; // Swing... // If we're on an odd column if (getPlayheadCol() % 2 != 0) { // If we've waited for enough ticks for the swing if (tickCount == (getPlayheadCol() * ticksPerCol) + swingTicks) { playCol = true; } } else { // Else we're on an even column // If we're on the first tick of the column... if (tickCount % ticksPerCol == 0) { playCol = true; } } // Calculate the latency double beatsPerSec = bpm * speed * ticksPerCol / 60.0; double secPerBeat = 1.0 / beatsPerSec; double tickOffset = tickCountPrecise - tickCount; int tickOffsetSamples = tickOffset * secPerBeat * sampleRate; tickOffsetSamples = jmax (buffer.getNumSamples() - tickOffsetSamples - 1, 0); // Send any upcoming note-off events Array<NoteOff*> notesToRemove; for (int i = 0; i < noteOffs.size(); i++) { if (noteOffs[i]->tick == tickCount) { int noteNumber = noteOffs[i]->noteNumber; MidiMessage m2 = MidiMessage::noteOff (1, noteNumber); midiMessages.addEvent (m2, tickOffsetSamples); playingNotes.set (noteNumber, false); notesToRemove.add (noteOffs[i]); } } for (int i = 0; i < notesToRemove.size(); i++) { // Remove the event from the note-off event list // (We do this in two steps so that the noteOffs array isn't modified inside a loop) noteOffs.removeObject (notesToRemove[i], true); } // If we should play the current column of notes if (playCol) { int panelIndex = pluginAudioProcessor->getPanelIndex(); int tabIndex = pluginAudioProcessor->getTabIndex(); for (int i = 0; i < getTotalRows(); i++) { Cell* cell = getCellAt (panelIndex, tabIndex, i, getPlayheadCol()); if (cell->isOn()) { int noteNumber = cell->getNoteNumber(); // If this note is currently playing if (playingNotes[noteNumber] == true) { Array<NoteOff*> notesToRemove; // Remove any pending note-offs for (int j = 0; j < noteOffs.size(); j++) { if (noteOffs[j]->noteNumber == noteNumber) { notesToRemove.add (noteOffs[j]); } } for (int j = 0; j < notesToRemove.size(); j++) { noteOffs.removeObject (notesToRemove[j], true); } // Send a note-off before retriggering MidiMessage m = MidiMessage::noteOff (1, noteNumber); midiMessages.addEvent (m, tickOffsetSamples); playingNotes.set (noteNumber, false); } // Play this note MidiMessage m = MidiMessage::noteOn (1, noteNumber, velocity); midiMessages.addEvent (m, tickOffsetSamples); playingNotes.set (noteNumber, true); // Add an upcoming note-off event NoteOff* no; noteOffs.add (no = new NoteOff()); no->tick = (tickCount + noteLength) % (ticksPerCol * getTotalCols()); no->noteNumber = noteNumber; } } } } }
void setText (const String& newText) { document.perform (new SetFocusOrderAction (component, *document.getComponentLayout(), jmax (0, newText.getIntValue())), "Change focus order"); }
void HighResolutionTimer::startTimer (int periodMs) { pimpl->start (jmax (1, periodMs)); }
void AudioDeviceManager::audioDeviceIOCallbackInt (const float** inputChannelData, int numInputChannels, float** outputChannelData, int numOutputChannels, int numSamples) { const ScopedLock sl (audioCallbackLock); if (inputLevelMeasurementEnabledCount > 0 && numInputChannels > 0) { for (int j = 0; j < numSamples; ++j) { float s = 0; for (int i = 0; i < numInputChannels; ++i) s += std::abs (inputChannelData[i][j]); s /= numInputChannels; const double decayFactor = 0.99992; if (s > inputLevel) inputLevel = s; else if (inputLevel > 0.001f) inputLevel *= decayFactor; else inputLevel = 0; } } else { inputLevel = 0; } if (callbacks.size() > 0) { const double callbackStartTime = Time::getMillisecondCounterHiRes(); tempBuffer.setSize (jmax (1, numOutputChannels), jmax (1, numSamples), false, false, true); callbacks.getUnchecked(0)->audioDeviceIOCallback (inputChannelData, numInputChannels, outputChannelData, numOutputChannels, numSamples); float** const tempChans = tempBuffer.getArrayOfChannels(); for (int i = callbacks.size(); --i > 0;) { callbacks.getUnchecked(i)->audioDeviceIOCallback (inputChannelData, numInputChannels, tempChans, numOutputChannels, numSamples); for (int chan = 0; chan < numOutputChannels; ++chan) { const float* const src = tempChans [chan]; float* const dst = outputChannelData [chan]; if (src != nullptr && dst != nullptr) for (int j = 0; j < numSamples; ++j) dst[j] += src[j]; } } const double msTaken = Time::getMillisecondCounterHiRes() - callbackStartTime; const double filterAmount = 0.2; cpuUsageMs += filterAmount * (msTaken - cpuUsageMs); } else { for (int i = 0; i < numOutputChannels; ++i) zeromem (outputChannelData[i], sizeof (float) * (size_t) numSamples); } if (testSound != nullptr) { const int numSamps = jmin (numSamples, testSound->getNumSamples() - testSoundPosition); const float* const src = testSound->getSampleData (0, testSoundPosition); for (int i = 0; i < numOutputChannels; ++i) for (int j = 0; j < numSamps; ++j) outputChannelData [i][j] += src[j]; testSoundPosition += numSamps; if (testSoundPosition >= testSound->getNumSamples()) testSound = nullptr; } }
void AlertWindow::updateLayout (const bool onlyIncreaseSize) { const int titleH = 24; const int iconWidth = 80; const Font font (getLookAndFeel().getAlertWindowMessageFont()); const int wid = jmax (font.getStringWidth (text), font.getStringWidth (getName())); const int sw = (int) std::sqrt (font.getHeight() * wid); int w = jmin (300 + sw * 2, (int) (getParentWidth() * 0.7f)); const int edgeGap = 10; const int labelHeight = 18; int iconSpace = 0; AttributedString attributedText; attributedText.append (getName(), font.withHeight (font.getHeight() * 1.1f).boldened()); if (text.isNotEmpty()) attributedText.append ("\n\n" + text, font); attributedText.setColour (findColour (textColourId)); if (alertIconType == NoIcon) { attributedText.setJustification (Justification::centredTop); textLayout.createLayoutWithBalancedLineLengths (attributedText, (float) w); } else { attributedText.setJustification (Justification::topLeft); textLayout.createLayoutWithBalancedLineLengths (attributedText, (float) w); iconSpace = iconWidth; } w = jmax (350, (int) textLayout.getWidth() + iconSpace + edgeGap * 4); w = jmin (w, (int) (getParentWidth() * 0.7f)); const int textLayoutH = (int) textLayout.getHeight(); const int textBottom = 16 + titleH + textLayoutH; int h = textBottom; int buttonW = 40; int i; for (i = 0; i < buttons.size(); ++i) buttonW += 16 + buttons.getUnchecked(i)->getWidth(); w = jmax (buttonW, w); h += (textBoxes.size() + comboBoxes.size() + progressBars.size()) * 50; if (buttons.size() > 0) h += 20 + buttons.getUnchecked(0)->getHeight(); for (i = customComps.size(); --i >= 0;) { Component* c = customComps.getUnchecked(i); w = jmax (w, (c->getWidth() * 100) / 80); h += 10 + c->getHeight(); if (c->getName().isNotEmpty()) h += labelHeight; } for (i = textBlocks.size(); --i >= 0;) { const AlertTextComp* const ac = static_cast <const AlertTextComp*> (textBlocks.getUnchecked(i)); w = jmax (w, ac->getPreferredWidth()); } w = jmin (w, (int) (getParentWidth() * 0.7f)); for (i = textBlocks.size(); --i >= 0;) { AlertTextComp* const ac = static_cast <AlertTextComp*> (textBlocks.getUnchecked(i)); ac->updateLayout ((int) (w * 0.8f)); h += ac->getHeight() + 10; } h = jmin (getParentHeight() - 50, h); if (onlyIncreaseSize) { w = jmax (w, getWidth()); h = jmax (h, getHeight()); } if (! isVisible()) { centreAroundComponent (associatedComponent, w, h); } else { const int cx = getX() + getWidth() / 2; const int cy = getY() + getHeight() / 2; setBounds (cx - w / 2, cy - h / 2, w, h); } textArea.setBounds (edgeGap, edgeGap, w - (edgeGap * 2), h - edgeGap); const int spacer = 16; int totalWidth = -spacer; for (i = buttons.size(); --i >= 0;) totalWidth += buttons.getUnchecked(i)->getWidth() + spacer; int x = (w - totalWidth) / 2; int y = (int) (getHeight() * 0.95f); for (i = 0; i < buttons.size(); ++i) { TextButton* const c = buttons.getUnchecked(i); int ny = proportionOfHeight (0.95f) - c->getHeight(); c->setTopLeftPosition (x, ny); if (ny < y) y = ny; x += c->getWidth() + spacer; c->toFront (false); } y = textBottom; for (i = 0; i < allComps.size(); ++i) { Component* const c = allComps.getUnchecked(i); h = 22; const int comboIndex = comboBoxes.indexOf (dynamic_cast <ComboBox*> (c)); if (comboIndex >= 0 && comboBoxNames [comboIndex].isNotEmpty()) y += labelHeight; const int tbIndex = textBoxes.indexOf (dynamic_cast <TextEditor*> (c)); if (tbIndex >= 0 && textboxNames[tbIndex].isNotEmpty()) y += labelHeight; if (customComps.contains (c)) { if (c->getName().isNotEmpty()) y += labelHeight; c->setTopLeftPosition (proportionOfWidth (0.1f), y); h = c->getHeight(); } else if (textBlocks.contains (c)) { c->setTopLeftPosition ((getWidth() - c->getWidth()) / 2, y); h = c->getHeight(); } else { c->setBounds (proportionOfWidth (0.1f), y, proportionOfWidth (0.8f), h); } y += h + 10; } setWantsKeyboardFocus (getNumChildComponents() == 0); }
void CodeDocument::remove (const int startPos, const int endPos, const bool undoable) { if (endPos <= startPos) return; if (undoable) { undoManager.perform (new CodeDocumentDeleteAction (*this, startPos, endPos)); } else { Position startPosition (*this, startPos); Position endPosition (*this, endPos); maximumLineLength = -1; const int firstAffectedLine = startPosition.getLineNumber(); const int endLine = endPosition.getLineNumber(); CodeDocumentLine& firstLine = *lines.getUnchecked (firstAffectedLine); if (firstAffectedLine == endLine) { firstLine.line = firstLine.line.substring (0, startPosition.getIndexInLine()) + firstLine.line.substring (endPosition.getIndexInLine()); firstLine.updateLength(); } else { CodeDocumentLine& lastLine = *lines.getUnchecked (endLine); firstLine.line = firstLine.line.substring (0, startPosition.getIndexInLine()) + lastLine.line.substring (endPosition.getIndexInLine()); firstLine.updateLength(); int numLinesToRemove = endLine - firstAffectedLine; lines.removeRange (firstAffectedLine + 1, numLinesToRemove); } for (int i = firstAffectedLine + 1; i < lines.size(); ++i) { CodeDocumentLine& l = *lines.getUnchecked (i); const CodeDocumentLine& previousLine = *lines.getUnchecked (i - 1); l.lineStartInFile = previousLine.lineStartInFile + previousLine.lineLength; } checkLastLineStatus(); const int totalChars = getNumCharacters(); for (int i = 0; i < positionsToMaintain.size(); ++i) { CodeDocument::Position& p = *positionsToMaintain.getUnchecked(i); if (p.getPosition() > startPosition.getPosition()) p.setPosition (jmax (startPos, p.getPosition() + startPos - endPos)); if (p.getPosition() > totalChars) p.setPosition (totalChars); } listeners.call (&CodeDocument::Listener::codeDocumentTextDeleted, startPos, endPos); } }
void mouseDrag (const MouseEvent& e) override { if (canMoveTransport()) transportSource.setPosition (jmax (0.0, xToTime ((float) e.x))); }
bool refillCache (const int numSamples, double startTime, const double endTime, const double rate, const int numChans, const int sampsPerThumbSample, LevelDataSource* levelData, const OwnedArray<ThumbData>& chans) { const double timePerPixel = (endTime - startTime) / numSamples; if (numSamples <= 0 || timePerPixel <= 0.0 || rate <= 0) { invalidate(); return false; } if (numSamples == numSamplesCached && numChannelsCached == numChans && startTime == cachedStart && timePerPixel == cachedTimePerPixel && ! cacheNeedsRefilling) { return ! cacheNeedsRefilling; } numSamplesCached = numSamples; numChannelsCached = numChans; cachedStart = startTime; cachedTimePerPixel = timePerPixel; cacheNeedsRefilling = false; ensureSize (numSamples); if (timePerPixel * rate <= sampsPerThumbSample && levelData != nullptr) { int sample = roundToInt (startTime * rate); Array<float> levels; int i; for (i = 0; i < numSamples; ++i) { const int nextSample = roundToInt ((startTime + timePerPixel) * rate); if (sample >= 0) { if (sample >= levelData->lengthInSamples) break; levelData->getLevels (sample, jmax (1, nextSample - sample), levels); const int totalChans = jmin (levels.size() / 2, numChannelsCached); for (int chan = 0; chan < totalChans; ++chan) getData (chan, i)->setFloat (levels.getUnchecked (chan * 2), levels.getUnchecked (chan * 2 + 1)); } startTime += timePerPixel; sample = nextSample; } numSamplesCached = i; } else { jassert (chans.size() == numChannelsCached); for (int channelNum = 0; channelNum < numChannelsCached; ++channelNum) { ThumbData* channelData = chans.getUnchecked (channelNum); MinMaxValue* cacheData = getData (channelNum, 0); const double timeToThumbSampleFactor = rate / (double) sampsPerThumbSample; startTime = cachedStart; int sample = roundToInt (startTime * timeToThumbSampleFactor); for (int i = numSamples; --i >= 0;) { const int nextSample = roundToInt ((startTime + timePerPixel) * timeToThumbSampleFactor); channelData->getMinMax (sample, nextSample, *cacheData); ++cacheData; startTime += timePerPixel; sample = nextSample; } } } return true; }