KeyEntryWindow (KeyMappingEditorComponent& kec) : AlertWindow (TRANS("New key-mapping"), TRANS("Please press a key combination now..."), AlertWindow::NoIcon), owner (kec) { addButton (TRANS("OK"), 1); addButton (TRANS("Cancel"), 0); // (avoid return + escape keys getting processed by the buttons..) for (int i = getNumChildComponents(); --i >= 0;) getChildComponent (i)->setWantsKeyboardFocus (false); setWantsKeyboardFocus (true); grabKeyboardFocus(); }
void Node::getPinPos (const int index, const bool isInput, float& x, float& y) { for (int i = 0; i < getNumChildComponents (); ++i) { Pin* const pin = dynamic_cast<Pin*>(getChildComponent (i)); if (pin != nullptr && pin->Index == index && isInput == pin->IsInput) { x = getX () + pin->getX () + pin->getWidth () * 0.5f; y = getY () + pin->getY () + pin->getHeight () * 0.5f; break; } } }
ResizableWindow::~ResizableWindow() { // Don't delete or remove the resizer components yourself! They're managed by the // ResizableWindow, and you should leave them alone! You may have deleted them // accidentally by careless use of deleteAllChildren()..? jassert (resizableCorner == nullptr || getIndexOfChildComponent (resizableCorner) >= 0); jassert (resizableBorder == nullptr || getIndexOfChildComponent (resizableBorder) >= 0); resizableCorner = nullptr; resizableBorder = nullptr; clearContentComponent(); // have you been adding your own components directly to this window..? tut tut tut. // Read the instructions for using a ResizableWindow! jassert (getNumChildComponents() == 0); }
void resized() { for (int i = 0; i < getNumChildComponents(); ++i) { PinComponent* const pc = dynamic_cast <PinComponent*> (getChildComponent(i)); if (pc != nullptr) { const int total = pc->isInput ? numIns : numOuts; const int index = pc->index == FilterGraph::midiChannelNumber ? (total - 1) : pc->index; pc->setBounds (proportionOfWidth ((1 + index) / (total + 1.0f)) - pinSize / 2, pc->isInput ? 0 : (getHeight() - pinSize), pinSize, pinSize); } } }
//================================================================================================================== void ComponentLayoutEditor::findLassoItemsInArea (Array <ComponentOverlay*>& results, const Rectangle<int>& area) { const Rectangle<int> lasso (area); for (int i = 0; i < getNumChildComponents() - 1; i++) { ComponentOverlay* c = (ComponentOverlay*)getChildComponent (i); if (c->getBounds().intersects (lasso)) { results.addIfNotAlreadyThere (c); selectedComponents.addToSelection (c); } else selectedComponents.deselect (c); } }
ConnectorComponent* GraphEditorPanel::getComponentForConnection (const AudioProcessorGraph::Connection& conn) const { for (int i = getNumChildComponents(); --i >= 0;) { ConnectorComponent* const c = dynamic_cast <ConnectorComponent*> (getChildComponent (i)); if (c != nullptr && c->sourceFilterID == conn.sourceNodeId && c->destFilterID == conn.destNodeId && c->sourceFilterChannel == conn.sourceChannelIndex && c->destFilterChannel == conn.destChannelIndex) { return c; } } return nullptr; }
void SliderBank::updateBoundsX() { minBoundX = 1000000; maxBoundX = 0; for (int i = getNumChildComponents(); --i >= 0;) { MicronSlider* slider = dynamic_cast<MicronSlider*>(getChildComponent(i)); if (slider && slider->isVisible()) { const int sliderLeftEdge = slider->getBounds().getX() - 5; const int sliderRightEdge = slider->getBounds().getRight() + 5; if (sliderLeftEdge < minBoundX) minBoundX = sliderLeftEdge; if (sliderRightEdge > maxBoundX) maxBoundX = sliderRightEdge; } } }
Component* MultiDocumentPanel::getContainerComp (Component* c) const { if (mode == FloatingWindows) { for (int i = 0; i < getNumChildComponents(); ++i) { MultiDocumentPanelWindow* const dw = dynamic_cast <MultiDocumentPanelWindow*> (getChildComponent (i)); if (dw != nullptr && dw->getContentComponent() == c) { c = dw; break; } } } return c; }
void MultiDocumentPanel::componentNameChanged (Component&) { if (mode == FloatingWindows) { for (int i = 0; i < getNumChildComponents(); ++i) { MultiDocumentPanelWindow* const dw = dynamic_cast <MultiDocumentPanelWindow*> (getChildComponent (i)); if (dw != nullptr) dw->setName (dw->getContentComponent()->getName()); } } else if (tabComponent != nullptr) { for (int i = tabComponent->getNumTabs(); --i >= 0;) tabComponent->setTabName (i, tabComponent->getTabContentComponent (i)->getName()); } }
void FilterComponent::resized() { for (int i = 0; i < getNumChildComponents(); ++i) { if (PinComponent* const pc = dynamic_cast <PinComponent*> (getChildComponent(i))) { const int total = pc->isInput ? numIns : numOuts; const int index = pc->index == PMixDocument::midiChannelNumber ? (total - 1) : pc->index; pc->setBounds(PINS_LEFT_OFFSET + (index * OFFSET_BETWEEN_PINS), pc->isInput ? 0 : (getHeight() - pinSize), pinSize, pinSize); } } if (filterName != nullptr) filterName->setBounds(0, pinSize, getWidth(), 20); if (editor != nullptr) editor->setBounds(10, pinSize + filterName->getHeight(), getWidth()-20, getHeight() - pinSize - pinSize - 10 - filterName->getHeight()); }
PinComponent* GraphEditorPanel::findPinAt (const int x, const int y) const { for (int i = getNumChildComponents(); --i >= 0;) { FilterComponent* const fc = dynamic_cast <FilterComponent*> (getChildComponent (i)); if (fc != nullptr) { PinComponent* const pin = dynamic_cast <PinComponent*> (fc->getComponentAt (x - fc->getX(), y - fc->getY())); if (pin != nullptr) return pin; } } return nullptr; }
void dragKeyHeldDown (const bool isKeyDown) { if (isSpaceDown != isKeyDown) { isSpaceDown = isKeyDown; if (isSpaceDown) { auto dc = new DraggerOverlayComp(); addAndMakeVisible (dc); dc->setBounds (getLocalBounds()); } else { for (int i = getNumChildComponents(); --i >= 0;) std::unique_ptr<DraggerOverlayComp> deleter (dynamic_cast<DraggerOverlayComp*> (getChildComponent (i))); } } }
~MissingItemsComponent() { if (owner != nullptr) { for (int i = 0; i < getNumChildComponents(); ++i) { ToolbarItemComponent* const tc = dynamic_cast <ToolbarItemComponent*> (getChildComponent (i)); if (tc != nullptr) { tc->setVisible (false); const int index = oldIndexes.remove (i); owner->addChildComponent (tc, index); --i; } } owner->resized(); } }
//TODO : implement correct version void updateFromTransactionsMapForRow(QueryEntry *qe, std::map<String, String> rowUpdates, int row, bool dView, bool edit) { setDetailedView(dView); resized(); this->row = row; for (int i=0; i<getNumChildComponents(); i++) { TextEditor *te = dynamic_cast<TextEditor*>(getChildComponent(i)); if (te) { const StringArray key = (qe != nullptr) ? qe->getFieldFromRow(row, owner.getKeyField()) : StringArray(); if (key.size() && (rowUpdates.find(te->getName()) != rowUpdates.end())) { te->setText(rowUpdates[te->getName()]); } else { te->setText(qe->getFieldFromRow(row, owner.fieldNames.indexOf(te->getName()))); } te->setEnabled(edit); } } }
void PaintRoutineEditor::refreshAllElements() { for (int i = getNumChildComponents(); --i >= 0;) if (PaintElement* const e = dynamic_cast<PaintElement*> (getChildComponent (i))) if (! graphics.containsElement (e)) removeChildComponent (e); Component* last = nullptr; for (int i = graphics.getNumElements(); --i >= 0;) { PaintElement* const e = graphics.getElement (i); addAndMakeVisible (e); if (last != nullptr) e->toBehind (last); else e->toFront (false); last = e; } updateChildBounds(); if (grid.updateFromDesign (document)) repaint(); if (currentBackgroundColour != graphics.getBackgroundColour()) { currentBackgroundColour = graphics.getBackgroundColour(); repaint(); } if (componentOverlayOpacity != document.getComponentOverlayOpacity()) { componentOverlay = Image(); componentOverlayOpacity = document.getComponentOverlayOpacity(); repaint(); } }
//============================================================================== void MultiDocumentPanel::setLayoutMode (const LayoutMode newLayoutMode) { if (mode != newLayoutMode) { mode = newLayoutMode; if (mode == FloatingWindows) { tabComponent = nullptr; } else { for (int i = getNumChildComponents(); --i >= 0;) { MultiDocumentPanelWindow* const dw = dynamic_cast <MultiDocumentPanelWindow*> (getChildComponent (i)); if (dw != nullptr) { dw->getContentComponent()->getProperties().set ("mdiDocumentPos_", dw->getWindowStateAsString()); dw->clearContentComponent(); delete dw; } } } resized(); const Array <Component*> tempComps (components); components.clear(); for (int i = 0; i < tempComps.size(); ++i) { Component* const c = tempComps.getUnchecked(i); addDocument (c, Colour ((uint32) static_cast <int> (c->getProperties().getWithDefault ("mdiDocumentBkg_", (int) Colours::white.getARGB()))), MultiDocHelpers::shouldDeleteComp (c)); } } }
MicronSlider* SliderBank::findSliderAtPos(const Point<int>& pos) { MicronSlider* closestSlider = 0; float closestDist = 1e6; for (int i = getNumChildComponents(); --i >= 0;) { MicronSlider* slider = dynamic_cast<MicronSlider*>(getChildComponent(i)); if (slider && slider->isVisible()) { const int SLIGHT_X_ADJUSTMENT = 2; float sliderDist = abs( slider->getBounds().getCentre().getX()+SLIGHT_X_ADJUSTMENT - pos.getX() ); // if ( slider == prevSlider ) // sliderDist *= 0.75f; if ( sliderDist < closestDist ) { closestDist = sliderDist; closestSlider = slider; } } } return closestSlider; }
ValueTree DrawableComposite::createValueTree (ComponentBuilder::ImageProvider* imageProvider) const { ValueTree tree (valueTreeType); ValueTreeWrapper v (tree); v.setID (getComponentID()); v.setBoundingBox (bounds, nullptr); ValueTree childList (v.getChildListCreating (nullptr)); for (int i = 0; i < getNumChildComponents(); ++i) { const Drawable* const d = dynamic_cast <const Drawable*> (getChildComponent(i)); jassert (d != nullptr); // You can't save a mix of Drawables and normal components! childList.addChild (d->createValueTree (imageProvider), -1, nullptr); } v.getMarkerListCreating (true, nullptr).readFrom (markersX, nullptr); v.getMarkerListCreating (false, nullptr).readFrom (markersY, nullptr); return tree; }
void GenericEditor::switchCollapsedState() { if (!getProcessor()->isMerger() && !getProcessor()->isSplitter()) { if (isCollapsed) { // open it up desiredWidth = originalWidth; isCollapsed = false; } else { originalWidth = desiredWidth; desiredWidth = 25; isCollapsed = true; } for (int i = 0; i < getNumChildComponents(); i++) { Component* c = getChildComponent(i); c->setVisible(!isCollapsed); } if (channelSelector != nullptr) { if (!drawerOpen) channelSelector->setVisible(false); } collapsedStateChanged(); AccessClass::getEditorViewport()->refreshEditors(); } }
//============================================================================== SliderBank::SliderBank (MicronauAudioProcessor *owner, MicronauAudioProcessorEditor *parent) { for (int i = 0; i < 33; ++i) { const int SLIDER_SPACING = 11; const int SLIDER_WIDTH = 11; const int SLIDER_HEIGHT = 100; ext_slider *newSlider = new ext_slider(owner, 633+i); parent->addSlider(newSlider); newSlider->addListener(parent); newSlider->setBounds (i*SLIDER_SPACING, 0, SLIDER_WIDTH, SLIDER_HEIGHT); newSlider->setRange (-100, 100, 0.1); newSlider->setSliderStyle (Slider::LinearVertical); newSlider->setTextBoxStyle (Slider::NoTextBox, false, 80, 20); newSlider->addListener (this); sliders[i] = newSlider; addAndMakeVisible ( newSlider ); } setSize (400, 300); lockedSliderBeingDragged = 0; prevSlider = 0; resettingValuesToDefault = false; setBroadStrokesMode(true); resetDoubleClickTimer(); // disable any clicks from getting to children. setInterceptsMouseClicks (true, false); for (int i = getNumChildComponents(); --i >= 0;) getChildComponent(i)->setInterceptsMouseClicks(false, false); updateBoundsX(); }
bool MultiDocumentPanel::closeDocument (Component* component, const bool checkItsOkToCloseFirst) { if (components.contains (component)) { if (checkItsOkToCloseFirst && ! tryToCloseDocument (component)) return false; component->removeComponentListener (this); const bool shouldDelete = MultiDocHelpers::shouldDeleteComp (component); component->getProperties().remove ("mdiDocumentDelete_"); component->getProperties().remove ("mdiDocumentBkg_"); if (mode == FloatingWindows) { for (int i = getNumChildComponents(); --i >= 0;) { MultiDocumentPanelWindow* const dw = dynamic_cast <MultiDocumentPanelWindow*> (getChildComponent (i)); if (dw != nullptr && dw->getContentComponent() == component) { ScopedPointer<MultiDocumentPanelWindow> (dw)->clearContentComponent(); break; } } if (shouldDelete) delete component; components.removeValue (component); if (isFullscreenWhenOneDocument() && components.size() == 1) { for (int i = getNumChildComponents(); --i >= 0;) { ScopedPointer<MultiDocumentPanelWindow> dw (dynamic_cast <MultiDocumentPanelWindow*> (getChildComponent (i))); if (dw != nullptr) dw->clearContentComponent(); } addAndMakeVisible (components.getFirst()); } } else { jassert (components.indexOf (component) >= 0); if (tabComponent != nullptr) { for (int i = tabComponent->getNumTabs(); --i >= 0;) if (tabComponent->getTabContentComponent (i) == component) tabComponent->removeTab (i); } else { removeChildComponent (component); } if (shouldDelete) delete component; if (tabComponent != nullptr && tabComponent->getNumTabs() <= numDocsBeforeTabsUsed) tabComponent = nullptr; components.removeValue (component); if (components.size() > 0 && tabComponent == nullptr) addAndMakeVisible (components.getFirst()); } resized(); activeDocumentChanged(); } else { jassertfalse; } return true; }
void PaintRoutineEditor::removeAllElementComps() { for (int i = getNumChildComponents(); --i >= 0;) if (PaintElement* const e = dynamic_cast<PaintElement*> (getChildComponent (i))) removeChildComponent (e); }
void ComponentLayoutEditor::refreshAllComponents() { for (int i = getNumChildComponents(); --i >= 0;) { ScopedPointer<ComponentOverlayComponent> overlay (dynamic_cast <ComponentOverlayComponent*> (getChildComponent (i))); if (overlay != nullptr && layout.containsComponent (overlay->target)) overlay.release(); } for (int i = subCompHolder->getNumChildComponents(); --i >= 0;) { Component* const comp = subCompHolder->getChildComponent (i); if (! layout.containsComponent (comp)) subCompHolder->removeChildComponent (comp); } Component* lastComp = nullptr; Component* lastOverlay = nullptr; for (int i = layout.getNumComponents(); --i >= 0;) { Component* const c = layout.getComponent (i); jassert (c != nullptr); ComponentOverlayComponent* overlay = getOverlayCompFor (c); bool isNewOverlay = false; if (overlay == 0) { ComponentTypeHandler* const handler = ComponentTypeHandler::getHandlerFor (*c); jassert (handler != nullptr); overlay = handler->createOverlayComponent (c, layout); addAndMakeVisible (overlay); isNewOverlay = true; } if (lastOverlay != nullptr) overlay->toBehind (lastOverlay); else overlay->toFront (false); lastOverlay = overlay; subCompHolder->addAndMakeVisible (c); if (lastComp != nullptr) c->toBehind (lastComp); else c->toFront (false); lastComp = c; c->setWantsKeyboardFocus (false); c->setFocusContainer (true); if (isNewOverlay) overlay->updateBoundsToMatchTarget(); } if (grid.updateFromDesign (document)) subCompHolder->repaint(); subCompHolder->setBounds (getComponentArea()); subCompHolder->resized(); }
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 ComponentLayoutEditor::updateOverlayPositions() { for (int i = getNumChildComponents(); --i >= 0;) if (ComponentOverlayComponent* const overlay = dynamic_cast <ComponentOverlayComponent*> (getChildComponent (i))) overlay->updateBoundsToMatchTarget(); }
int Channels::getNumChannels() { return getNumChildComponents() - GUI::N_STATIC_CHANNELS_CHILDREN ; }
~NormalTestComponent() override { for (int i = getNumChildComponents(); --i >= 0;) removeChildComponent (i); }
int Mixer::getNumDynamicMixers() { return getNumChildComponents() - GUI::N_STATIC_MIXER_CHILDREN ; }
void paint (Graphics& g) { const TwindyTabbedComponent* const t = (const TwindyTabbedComponent*) getParentComponent(); if (t != 0) { #if JUCE_NEW const Rectangle<int> thisBounds (0, 0, getWidth(), getHeight()); #else const Rectangle thisBounds (0, 0, getWidth(), getHeight()); #endif int i; for (i = 0; i < getNumChildComponents(); ++i) { TwindyTabbedComponentBasicTab* const c = (TwindyTabbedComponentBasicTab*) getChildComponent (i); if (c != (TwindyTabbedComponentBasicTab*)t->tabList [t->currentTab]) { const float indent = 2.0f; float x1 = (float)c->getX(); float y1 = (float)c->getY(); float x2 = x1 + c->getWidth(); float y2 = y1 + c->getHeight(); if (c->getBounds().intersects (thisBounds)) { if (t->orientation == TwindyTabbedComponent::TabsAtTop) { y1 += indent; y2 += 100.0f; } else if (t->orientation == TwindyTabbedComponent::TabsAtBottom) { y2 -= indent; y1 -= 100.0f; } else if (t->orientation == TwindyTabbedComponent::TabsAtLeft) { x1 += indent; x2 += 100.0f; } else if (t->orientation == TwindyTabbedComponent::TabsAtRight) { x2 -= indent; x1 -= 100.0f; } Path p; p.addRoundedRectangle (x1 + t->normalOutlineThickness, y1 + t->normalOutlineThickness, x2 - x1 - t->normalOutlineThickness* 2.0f, y2 - y1 - t->normalOutlineThickness * 2.0f, t->cornerSize); g.setColour (t->deselectedTabCol); g.fillPath (p); g.setColour (t->normalOutlineCol); g.strokePath (p, PathStrokeType (t->normalOutlineThickness)); } } } AffineTransform trans; trans = trans.translated ((float)t->getScreenX() - getScreenX(), (float)t->getScreenY() - getScreenY()); g.setColour (t->fillCol); g.fillPath (t->outlineShape, trans); g.setColour (t->selectedOutlineCol); g.fillPath (t->strokedOutline, trans); } }
void TabbedButtonBar::resized() { const double minimumScale = 0.7; int depth = getWidth(); int length = getHeight(); if (orientation == TabsAtTop || orientation == TabsAtBottom) swapVariables (depth, length); const int overlap = getLookAndFeel().getTabButtonOverlap (depth) + getLookAndFeel().getTabButtonSpaceAroundImage() * 2; int i, totalLength = overlap; int numVisibleButtons = tabs.size(); for (i = 0; i < getNumChildComponents(); ++i) { TabBarButton* const tb = dynamic_cast <TabBarButton*> (getChildComponent (i)); if (tb != 0) { 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 == 0) { addAndMakeVisible (extraTabsButton = getLookAndFeel().createTabBarExtrasButton()); extraTabsButton->addButtonListener (this); 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 = getTabButton (i); if (tb != 0) { 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 { deleteAndZero (extraTabsButton); } int pos = 0; TabBarButton* frontTab = 0; for (i = 0; i < tabs.size(); ++i) { TabBarButton* const tb = getTabButton (i); if (tb != 0) { 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 (tb->tabIndex == currentTabIndex) frontTab = tb; tb->setVisible (true); } else { tb->setVisible (false); } pos += bestLength - overlap; } } behindFrontTab->setBounds (0, 0, getWidth(), getHeight()); if (frontTab != 0) { frontTab->toFront (false); behindFrontTab->toBehind (frontTab); } }