29static int getItemDepth (
const TreeViewItem* item)
31 if (item ==
nullptr || item->getOwnerView() ==
nullptr)
34 auto depth = item->getOwnerView()->isRootItemVisible() ? 0 : -1;
36 for (
auto* parent = item->getParentItem(); parent !=
nullptr; parent = parent->getParentItem())
49 customComponent (item.createItemComponent())
51 if (hasCustomComponent())
57 item.draw (g,
getWidth(), mouseIsOverButton);
62 if (hasCustomComponent())
71 void setMouseIsOverButton (
bool isOver)
73 mouseIsOverButton = isOver;
84 return item.getTooltip();
95 getAccessibilityActions (comp),
96 { std::make_unique<ItemCellInterface> (comp) }),
101 String getTitle()
const override
103 return itemComponent.getRepresentedItem().getAccessibilityName();
106 String getHelp()
const override
108 return itemComponent.getRepresentedItem().getTooltip();
111 AccessibleState getCurrentState()
const override
113 auto& treeItem = itemComponent.getRepresentedItem();
117 if (
auto* tree = treeItem.getOwnerView())
119 if (tree->isMultiSelectEnabled())
125 if (treeItem.mightContainSubItems())
129 if (treeItem.isOpen())
135 if (treeItem.isSelected())
148 return getItemDepth (&itemComponent.getRepresentedItem());
169 if (
auto* component = tree->getItemComponent (
subItem))
170 return component->getAccessibilityHandler();
181 if (
auto* tree = itemComponent.getRepresentedItem().
getOwnerView())
182 return tree->getAccessibilityHandler();
194 auto onFocus = [&itemComponent]
196 auto& treeItem = itemComponent.getRepresentedItem();
198 if (
auto* tree = treeItem.getOwnerView())
199 tree->scrollToKeepItemVisible (&treeItem);
202 auto onPress = [&itemComponent]
212 auto onToggle = [&itemComponent, onFocus]
216 auto isSelected = handler->getCurrentState().isSelected();
221 itemComponent.getRepresentedItem().
setSelected (! isSelected,
true);
233 ItemComponent& itemComponent;
235 static MouseEvent generateMouseEvent (ItemComponent&
itemComp, ModifierKeys mods)
250 if (hasCustomComponent() && customComponent->getAccessibilityHandler() !=
nullptr)
253 return std::make_unique<ItemAccessibilityHandler> (*
this);
256 bool hasCustomComponent()
const noexcept {
return customComponent.get() !=
nullptr; }
261 bool mouseIsOverButton =
false;
286 return itemComponent->getRepresentedItem().getTooltip();
301 auto iter =
std::find_if (itemComponents.cbegin(), itemComponents.cend(),
304 return c->getBounds().contains (p);
307 if (iter != itemComponents.cend())
313 ItemComponent* getComponentForItem (
const TreeViewItem* item)
const
315 const auto iter =
std::find_if (itemComponents.begin(), itemComponents.end(),
316 [item] (
const auto& c)
318 return &c->getRepresentedItem() == item;
321 if (iter != itemComponents.end())
327 void itemBeingDeleted (
const TreeViewItem* item)
329 const auto iter =
std::find_if (itemComponents.begin(), itemComponents.end(),
330 [item] (
const auto& c)
332 return &c->getRepresentedItem() == item;
335 if (iter != itemComponents.end())
337 if (itemUnderMouse == iter->get())
338 itemUnderMouse =
nullptr;
340 if (isMouseDraggingInChildComp (*(iter->get())))
341 owner.hideDragHighlight();
343 itemComponents.erase (iter);
347 const TreeViewItem* getItemForItemComponent (
const Component* comp)
const
349 const auto iter = itemForItemComponent.find (comp);
350 return iter != itemForItemComponent.cend() ? iter->second :
nullptr;
353 void updateComponents()
357 for (
auto* treeItem : getAllVisibleItems())
359 if (
auto*
itemComp = getComponentForItem (treeItem))
366 itemForItemComponent.emplace (
newComp.get(), treeItem);
369 newComp->addMouseListener (
this, treeItem->customComponentUsesTreeViewMouseHandler());
372 itemComponents.push_back (std::move (
newComp));
382 && ! isMouseDraggingInChildComp (*item);
386 itemComponents.erase (iter, itemComponents.end());
388 for (
auto& comp : itemComponents)
390 auto& treeItem = comp->getRepresentedItem();
391 comp->setBounds ({ 0, treeItem.y,
getWidth(), treeItem.itemHeight });
397 struct ScopedDisableViewportScroll
399 explicit ScopedDisableViewportScroll (ItemComponent& c)
402 item->setViewportIgnoreDragFlag (
true);
405 ~ScopedDisableViewportScroll()
408 item->setViewportIgnoreDragFlag (
false);
422 void mouseDownInternal (
const MouseEvent& e)
424 updateItemUnderMouse (e);
427 scopedScrollDisabler = nullopt;
428 needSelectionOnMouseUp =
false;
433 if (
auto* itemComponent = getItemComponentAt (e.getPosition()))
435 auto& item = itemComponent->getRepresentedItem();
436 auto pos = item.getItemPosition (
false);
440 if (e.x < pos.getX() && owner.openCloseButtonsVisible)
444 item.setOpen (! item.isOpen());
450 item.setSelected (
true,
true);
451 else if (item.isSelected())
452 needSelectionOnMouseUp = ! e.mods.isPopupMenu();
454 selectBasedOnModifiers (item, e.mods);
456 if (e.x >= pos.getX())
457 item.itemClicked (e.withNewPosition (e.position - pos.getPosition().toFloat()));
462 void mouseUpInternal (
const MouseEvent& e)
464 updateItemUnderMouse (e);
466 if (
isEnabled() && needSelectionOnMouseUp && e.mouseWasClicked())
467 if (
auto* itemComponent = getItemComponentAt (e.getPosition()))
468 selectBasedOnModifiers (itemComponent->getRepresentedItem(), e.mods);
471 void mouseDoubleClickInternal (
const MouseEvent& e)
473 if (
isEnabled() && e.getNumberOfClicks() != 3)
475 if (
auto* itemComponent = getItemComponentAt (e.getPosition()))
477 auto& item = itemComponent->getRepresentedItem();
478 auto pos = item.getItemPosition (
false);
480 if (e.x >= pos.getX() || ! owner.openCloseButtonsVisible)
481 item.itemDoubleClicked (e.withNewPosition (e.position - pos.getPosition().toFloat()));
486 void mouseDragInternal (
const MouseEvent& e)
489 && ! (isDragging || e.mouseWasClicked()
490 || e.getDistanceFromDragStart() < 5
491 || e.mods.isPopupMenu()))
495 if (
auto* itemComponent = getItemComponentAt (e.getMouseDownPosition()))
497 auto& item = itemComponent->getRepresentedItem();
498 auto pos = item.getItemPosition (
false);
500 if (e.getMouseDownX() >= pos.getX())
508 pos.setSize (pos.getWidth(), item.itemHeight);
517 auto imageOffset = pos.getPosition() - e.getPosition();
520 scopedScrollDisabler.emplace (*itemComponent);
534 void mouseMoveInternal (
const MouseEvent& e) { updateItemUnderMouse (e); }
535 void mouseExitInternal (
const MouseEvent& e) { updateItemUnderMouse (e); }
537 static bool isMouseDraggingInChildComp (
const Component& comp)
539 for (
auto&
ms : Desktop::getInstance().getMouseSources())
547 void updateItemUnderMouse (
const MouseEvent& e)
549 if (! owner.openCloseButtonsVisible)
552 auto*
newItem = [
this, &e]() -> ItemComponent*
554 if (
auto* itemComponent = getItemComponentAt (e.getPosition()))
556 auto& item = itemComponent->getRepresentedItem();
558 if (item.mightContainSubItems())
560 const auto xPos = item.getItemPosition (
false).getX();
563 return itemComponent;
572 if (itemUnderMouse !=
nullptr)
573 itemUnderMouse->setMouseIsOverButton (
false);
576 newItem->setMouseIsOverButton (
true);
582 void handleAsyncUpdate()
override
584 owner.updateVisibleItems();
588 void selectBasedOnModifiers (TreeViewItem& item,
const ModifierKeys
modifiers)
608 auto ourRow = item.getRowNumberInTree();
620 item.setSelected ((!
cmd) || ! item.isSelected(), !
cmd);
624 static TreeViewItem* getNextVisibleItem (TreeViewItem* item,
bool forwards)
626 if (item ==
nullptr || item->ownerView ==
nullptr)
629 auto*
nextItem = item->ownerView->getItemOnRow (item->getRowNumberInTree() + (forwards ? 1 : -1));
631 return nextItem == item->ownerView->rootItem && ! item->ownerView->rootItemVisible ?
nullptr
635 template <
typename Fn>
636 static void forEachDepthFirst (TreeViewItem* item,
bool includeItem,
Fn&& callback)
642 for (
auto i = 0; i < item->getNumSubItems(); ++i)
643 forEachDepthFirst (item->getSubItem (i),
true, callback);
649 forEachDepthFirst (owner.rootItem, owner.rootItemVisible, [&] (
auto*) { ++count; });
653 forEachDepthFirst (owner.rootItem, owner.rootItemVisible, [&] (
auto* item) { allItems.push_back (item); });
660 if (owner.rootItem ==
nullptr)
669 return item->y + item->getItemHeight() < y;
693 : itemForItemComponent (&map) {}
695 void operator() (ItemComponent* ptr)
const
697 itemForItemComponent->erase (ptr);
712 ItemComponent* itemUnderMouse =
nullptr;
713 Optional<ScopedDisableViewportScroll> scopedScrollDisabler;
714 bool isDragging =
false, needSelectionOnMouseUp =
false;
733 structureChanged =
true;
740 if (tree->keyPressed (key))
751 enum class Async { yes, no };
755 needsRecalculating =
true;
770 void handleAsyncUpdate()
override
780 if (
auto* root = owner.rootItem)
782 const auto startY = owner.rootItemVisible ? 0 : -root->itemHeight;
784 root->updatePositions (
startY);
786 root->totalHeight +
startY);
793 updateComponents (
false);
802 if (
auto* content = getContentComp())
807 content->updateComponents();
815 bool structureChanged =
false, needsRecalculating =
false;
835 if (rootItem !=
nullptr)
836 rootItem->setOwnerView (
nullptr);
843 if (rootItem !=
nullptr && (defaultOpenness || ! rootItemVisible))
849 viewport->recalculatePositions (TreeViewport::Async::no, {});
863 if (rootItem !=
nullptr && (defaultOpenness || ! rootItemVisible))
869 updateVisibleItems();
889 return indentSize >= 0 ? indentSize
898 updateVisibleItems();
912 updateVisibleItems();
918 return viewport.get();
924 if (rootItem !=
nullptr)
925 rootItem->deselectAllRecursively (
nullptr);
935 return rootItem !=
nullptr ? rootItem->getSelectedItemWithIndex (index) :
nullptr;
940 return rootItem !=
nullptr ? (rootItem->getNumRows() - (rootItemVisible ? 0 : 1)) : 0;
945 if (! rootItemVisible)
948 if (rootItem !=
nullptr && index >= 0)
949 return rootItem->getItemOnRow (index);
956 if (
auto* contentComp = viewport->getContentComp())
957 if (
auto* itemComponent = contentComp->getItemComponentAt (contentComp->getLocalPoint (
this,
Point<int> (0, y))))
958 return &itemComponent->getRepresentedItem();
965 if (rootItem ==
nullptr)
973 return viewport->getContentComp()->getComponentForItem (item);
985 addAllSelectedItemIds (item->
getSubItem (i), parent);
990 if (rootItem !=
nullptr)
995 rootOpenness->setAttribute (
"scrollPos", viewport->getViewPositionY());
1007 if (rootItem !=
nullptr)
1015 for (
auto* e :
newState.getChildWithTagNameIterator (
"SELECTED"))
1016 if (
auto* item = rootItem->findItemFromIdentifierString (e->getStringAttribute (
"id")))
1021 ? std::make_optional<Point<int>> (viewport->getViewPositionX(),
newState.getIntAttribute (
"scrollPos"))
1024 updateVisibleItems (std::move (
scrollPos));
1037 updateVisibleItems();
1088 if (item !=
nullptr && item->ownerView ==
this)
1090 updateVisibleItems();
1092 item = item->getDeepestOpenParentItem();
1095 auto viewTop = viewport->getViewPositionY();
1099 viewport->setViewPosition (viewport->getViewPositionX(), y);
1101 else if (y + item->itemHeight >
viewTop + viewport->getViewHeight())
1103 viewport->setViewPosition (viewport->getViewPositionX(),
1104 (y + item->itemHeight) - viewport->getViewHeight());
1109bool TreeView::toggleOpenSelectedItem()
1123void TreeView::moveOutOfSelectedItem()
1135 if ((! rootItemVisible) && parent == rootItem)
1138 if (parent !=
nullptr)
1140 parent->setSelected (
true,
true);
1147void TreeView::moveIntoSelectedItem()
1158void TreeView::moveByPages (
int numPages)
1162 auto pos = currentItem->getItemPosition (
false);
1164 auto currentRow = currentItem->getRowNumberInTree();
1171 if (currentItem ==
nullptr)
1174 auto y = currentItem->getItemPosition (
false).getY();
1179 auto newRow = currentItem->getRowNumberInTree();
1191 if (rootItem !=
nullptr)
1209 viewport->recalculatePositions (TreeViewport::Async::yes, std::move (
viewportPosition));
1220 if (item !=
nullptr)
1269 insertIndex = root->getNumSubItems();
1270 pos = root->getItemPosition (
true).getBottomLeft();
1277 int insertIndex = 0;
1291 void setTargetPosition (
const InsertPoint& insertPos,
const int width)
noexcept
1293 lastItem = insertPos.item;
1294 lastIndex = insertPos.insertIndex;
1296 setBounds (insertPos.pos.
x - offset, insertPos.pos.
y - offset,
1297 width - (insertPos.pos.
x - offset),
getHeight());
1304 p.
addEllipse (2.0f, 2.0f, h - 4.0f, h - 4.0f);
1329 void setTargetPosition (
TreeViewItem*
const item)
noexcept
1348 viewport = std::make_unique<TreeViewport> (*
this);
1358 if (rootItem !=
nullptr)
1359 rootItem->setOwnerView (
nullptr);
1363void TreeView::showDragHighlight (
const InsertPoint& insertPos)
noexcept
1365 beginDragAutoRepeat (100);
1367 if (dragInsertPointHighlight ==
nullptr)
1369 dragInsertPointHighlight = std::make_unique<InsertPointHighlight>();
1370 dragTargetGroupHighlight = std::make_unique<TargetGroupHighlight>();
1372 addAndMakeVisible (dragInsertPointHighlight.get());
1373 addAndMakeVisible (dragTargetGroupHighlight.get());
1376 dragInsertPointHighlight->setTargetPosition (insertPos, viewport->getViewWidth());
1377 dragTargetGroupHighlight->setTargetPosition (insertPos.item);
1380void TreeView::hideDragHighlight() noexcept
1382 dragInsertPointHighlight =
nullptr;
1383 dragTargetGroupHighlight =
nullptr;
1386void TreeView::handleDrag (
const StringArray& files,
const SourceDetails&
dragSourceDetails)
1393 if (insertPos.item !=
nullptr)
1395 if (
scrolled || dragInsertPointHighlight ==
nullptr
1396 || dragInsertPointHighlight->lastItem != insertPos.item
1397 || dragInsertPointHighlight->lastIndex != insertPos.insertIndex)
1399 if (files.size() > 0 ? insertPos.item->isInterestedInFileDrag (files)
1401 showDragHighlight (insertPos);
1403 hideDragHighlight();
1408 hideDragHighlight();
1412void TreeView::handleDrop (
const StringArray& files,
const SourceDetails&
dragSourceDetails)
1414 hideDragHighlight();
1418 if (insertPos.item ==
nullptr)
1419 insertPos.item = rootItem;
1421 if (insertPos.item !=
nullptr)
1423 if (files.size() > 0)
1425 if (insertPos.item->isInterestedInFileDrag (files))
1426 insertPos.item->
filesDropped (files, insertPos.insertIndex);
1454 hideDragHighlight();
1479 hideDragHighlight();
1493 explicit TableInterface (
TreeView& treeViewToWrap) : treeView (treeViewToWrap) {}
1496 int getNumColumns()
const override {
return 1; }
1506 return itemComp->getAccessibilityHandler();
1518 auto* item = getItemForHandler (handler);
1520 if (item ==
nullptr)
1525 return rowNumber != -1 ? makeOptional (
Span { rowNumber, 1 })
1531 return Span { 0, 1 };
1543 if (
auto* result = treeView.viewport->getContentComp()->getItemForItemComponent (comp))
1554 return std::make_unique<AccessibilityHandler> (*
this,
1555 AccessibilityRole::tree,
1569 if (ownerView !=
nullptr)
1570 ownerView->viewport->getContentComp()->itemBeingDeleted (
this);
1584 return subItems.size();
1589 return subItems[index];
1594 if (ownerView !=
nullptr)
1596 if (! subItems.isEmpty())
1598 removeAllSubItemsFromList();
1604 removeAllSubItemsFromList();
1608void TreeViewItem::removeAllSubItemsFromList()
1610 for (
int i = subItems.size(); --i >= 0;)
1611 removeSubItemFromList (i,
true);
1618 newItem->parentItem =
nullptr;
1619 newItem->setOwnerView (ownerView);
1627 if (ownerView !=
nullptr)
1633 newItem->itemOpennessChanged (
true);
1640 newItem->itemOpennessChanged (
true);
1647 if (ownerView !=
nullptr)
1649 if (removeSubItemFromList (index,
deleteItem))
1658bool TreeViewItem::removeSubItemFromList (
int index,
bool deleteItem)
1660 if (
auto* child = subItems[index])
1662 child->parentItem =
nullptr;
1691 if (openness == Openness::opennessDefault)
1692 return ownerView !=
nullptr && ownerView->defaultOpenness;
1694 return openness == Openness::opennessOpen;
1701 : Openness::opennessClosed);
1704bool TreeViewItem::isFullyOpen()
const noexcept
1709 for (
auto* i : subItems)
1710 if (! i->isFullyOpen())
1716void TreeViewItem::restoreToDefaultOpenness()
1731 for (
auto* i : subItems)
1743 getTopLevelItem()->deselectAllRecursively (
this);
1749 if (ownerView !=
nullptr)
1756 if (
auto*
itemHandler = itemComponent->getAccessibilityHandler())
1776 .drawTreeviewPlusMinusBox (g, area, backgroundColour,
isOpen(), isMouseOver);
1814 return tooltipString.isNotEmpty()
1849 auto width = itemWidth;
1851 if (ownerView !=
nullptr && width < 0)
1852 width = ownerView->viewport->getViewWidth() -
indentX;
1857 r -= ownerView->viewport->getViewPosition();
1864 if (ownerView !=
nullptr)
1865 ownerView->updateVisibleItems();
1872 component->repaint();
1877 return parentItem ==
nullptr
1881void TreeViewItem::updatePositions (
int newY)
1885 totalHeight = itemHeight;
1887 totalWidth =
jmax (itemWidth, 0) + getIndentX();
1891 newY += totalHeight;
1893 for (
auto* i : subItems)
1895 i->updatePositions (
newY);
1896 newY += i->totalHeight;
1897 totalHeight += i->totalHeight;
1898 totalWidth =
jmax (totalWidth, i->totalWidth);
1903const TreeViewItem* TreeViewItem::getDeepestOpenParentItem()
const noexcept
1905 auto* result =
this;
1908 while (item->parentItem !=
nullptr)
1910 item = item->parentItem;
1919void TreeViewItem::setOwnerView (TreeView*
const newOwner)
noexcept
1923 for (
auto* i : subItems)
1930int TreeViewItem::getIndentX()
const noexcept
1932 if (ownerView ==
nullptr)
1935 int x = ownerView->rootItemVisible ? 1 : 0;
1937 if (! ownerView->openCloseButtonsVisible)
1940 for (
auto* p = parentItem; p !=
nullptr; p = p->parentItem)
1956bool TreeViewItem::areLinesDrawn()
const
1958 return drawLinesSet ? drawLinesInside
1959 : (ownerView !=
nullptr && ownerView->
getLookAndFeel().areLinesDrawnForTreeView (*ownerView));
1964 return parentItem ==
nullptr
1965 || parentItem->subItems.getLast() ==
this;
1970 return parentItem ==
nullptr ? 0
1971 : parentItem->subItems.indexOf (
this);
1976 return parentItem ==
nullptr ?
this
1977 : parentItem->getTopLevelItem();
1980int TreeViewItem::getNumRows()
const noexcept
1985 for (
auto* i : subItems)
1986 num += i->getNumRows();
1991TreeViewItem* TreeViewItem::getItemOnRow (
int index)
noexcept
1996 if (index > 0 && isOpen())
2000 for (
auto* i : subItems)
2005 auto numRows = i->getNumRows();
2008 return i->getItemOnRow (index);
2017int TreeViewItem::countSelectedItemsRecursively (
int depth)
const noexcept
2019 int total = isSelected() ? 1 : 0;
2022 for (
auto* i : subItems)
2023 total += i->countSelectedItemsRecursively (depth - 1);
2028TreeViewItem* TreeViewItem::getSelectedItemWithIndex (
int index)
noexcept
2040 for (
auto* i : subItems)
2042 if (
auto* found = i->getSelectedItemWithIndex (index))
2045 index -= i->countSelectedItemsRecursively (-1);
2054 if (parentItem !=
nullptr && ownerView !=
nullptr)
2056 if (! parentItem->
isOpen())
2061 auto ourIndex = parentItem->subItems.indexOf (
this);
2065 n += parentItem->subItems [
ourIndex]->getNumRows();
2067 if (parentItem->parentItem ==
nullptr
2068 && ! ownerView->rootItemVisible)
2080 drawLinesSet =
true;
2083static String escapeSlashesInTreeViewItemName (
const String& s)
2092 if (parentItem !=
nullptr)
2095 return s +
"/" + escapeSlashesInTreeViewItemName (
getUniqueName());
2112 for (
auto* i : subItems)
2137 auto id = n->getStringAttribute (
"id");
2139 for (
int i = 0; i < items.
size(); ++i)
2143 if (
ti->getUniqueName() == id)
2145 ti->restoreOpennessState (*n);
2153 for (
auto* i : items)
2154 i->restoreToDefaultOpenness();
2167 if (name.isNotEmpty())
2173 if (
canReturnNull && ownerView !=
nullptr && ownerView->defaultOpenness && isFullyOpen())
2176 e = std::make_unique<XmlElement> (
"OPEN");
2178 for (
int i = subItems.size(); --i >= 0;)
2179 e->prependChildElement (subItems.getUnchecked (i)->getOpennessState (
true).release());
2183 if (
canReturnNull && ownerView !=
nullptr && ! ownerView->defaultOpenness)
2186 e = std::make_unique<XmlElement> (
"CLOSED");
2189 e->setAttribute (
"id", name);
2200TreeViewItem::OpennessRestorer::OpennessRestorer (TreeViewItem& item)
2201 : treeViewItem (item),
2202 oldOpenness (item.getOpennessState())
2206TreeViewItem::OpennessRestorer::~OpennessRestorer()
2208 if (oldOpenness !=
nullptr)
2214 if (ownerView ==
nullptr)
2217 const auto indent = getIndentX();
2218 const auto itemW = (itemWidth < 0 || drawsInRightMargin) ? width - indent : itemWidth;
2221 Graphics::ScopedSaveState
ss (g);
2222 g.setOrigin (indent, 0);
2224 if (g.reduceClipRegion (drawsInLeftMargin ? -indent : 0, 0,
2225 drawsInLeftMargin ?
itemW + indent :
itemW, itemHeight))
2231 : ownerView->findColour (TreeView::evenItemsColourId));
2233 paintItem (g, itemWidth < 0 ? width - indent : itemWidth, itemHeight);
2237 const auto halfH = (
float) itemHeight * 0.5f;
2239 const auto depth = getItemDepth (
this);
2241 if (depth >= 0 && ownerView->openCloseButtonsVisible)
2244 const auto parentLinesDrawn = parentItem !=
nullptr && parentItem->areLinesDrawn();
2253 auto* p = parentItem;
2256 while (p !=
nullptr && --d >= 0)
2260 if ((p->parentItem ==
nullptr || p->parentItem->areLinesDrawn()) && ! p->isLastOfSiblings())
2261 p->paintVerticalConnectingLine (g,
Line<float> (x, 0, x, (
float) itemHeight));
2272 backgroundColour.isTransparent() ? Colours::white : backgroundColour,
A simple wrapper for building a collection of supported accessibility actions and corresponding callb...
An abstract interface which represents a UI element that supports a cell interface.
Base class for accessible Components.
virtual AccessibleState getCurrentState() const
Returns the current state of the UI element.
const Component & getComponent() const noexcept
Returns the Component that this handler represents.
An abstract interface which represents a UI element that supports a table interface.
AccessibleState withExpandable() const noexcept
Sets the expandable flag and returns the new state.
AccessibleState withAccessibleOffscreen() const noexcept
Sets the accessible offscreen flag and returns the new state.
AccessibleState withSelectable() const noexcept
Sets the selectable flag and returns the new state.
AccessibleState withSelected() const noexcept
Sets the selected flag and returns the new state.
AccessibleState withExpanded() const noexcept
Sets the expanded flag and returns the new state.
AccessibleState withCollapsed() const noexcept
Sets the collapsed flag and returns the new state.
AccessibleState withMultiSelectable() const noexcept
Sets the multiSelectable flag and returns the new state.
Holds a resizable array of primitive or copy-by-value objects.
ElementType getUnchecked(int index) const
Returns one of the elements in the array, without checking the index passed in.
void addArray(const Type *elementsToAdd, int numElementsToAdd)
Adds elements from an array to the end of this array.
int size() const noexcept
Returns the current number of elements in the array.
void remove(int indexToRemove)
Removes an element from the array.
Has a callback method that is triggered asynchronously.
void triggerAsyncUpdate()
Causes the callback to be triggered at a later time.
Represents a colour, also including a transparency value.
The base class for all JUCE user-interface objects.
void setInterceptsMouseClicks(bool allowClicksOnThisComponent, bool allowClicksOnChildComponents) noexcept
Changes the default return value for the hitTest() method.
Component * getParentComponent() const noexcept
Returns the component which this component is inside.
Image createComponentSnapshot(Rectangle< int > areaToGrab, bool clipImageToComponentBounds=true, float scaleFactor=1.0f)
Generates a snapshot of part of this component.
bool isOpaque() const noexcept
Returns true if no parts of this component are transparent.
void setFocusContainerType(FocusContainerType containerType) noexcept
Sets whether this component is a container for components that can have their focus traversed,...
int getHeight() const noexcept
Returns the component's height in pixels.
static float JUCE_CALLTYPE getApproximateScaleFactorForComponent(const Component *targetComponent)
Returns the approximate scale factor for a given component by traversing its parent hierarchy and app...
void addAndMakeVisible(Component *child, int zOrder=-1)
Adds a child component to this one, and also makes the child visible if it isn't already.
void setAlwaysOnTop(bool shouldStayOnTop)
Sets whether the component should always be kept at the front of its siblings.
AccessibilityHandler * getAccessibilityHandler()
Returns the accessibility handler for this component, or nullptr if this component is not accessible.
void setOpaque(bool shouldBeOpaque)
Indicates whether any parts of the component might be transparent.
void repaint()
Marks the whole component as needing to be redrawn.
Component() noexcept
Creates a component.
@ focusContainer
The component will act as a top-level component within which focus is passed around.
Point< int > getMouseXYRelative() const
Returns the mouse's current position, relative to this component.
int getY() const noexcept
Returns the y coordinate of the top of this component.
bool isParentOf(const Component *possibleChild) const noexcept
Checks whether a component is anywhere inside this component or its children.
void setBounds(int x, int y, int width, int height)
Changes the component's position and size.
void setSize(int newWidth, int newHeight)
Changes the size of the component.
void setWantsKeyboardFocus(bool wantsFocus) noexcept
Sets a flag to indicate whether this component wants keyboard focus or not.
Colour findColour(int colourID, bool inheritFromParent=false) const
Looks for a colour that has been registered with the given colour ID number.
int getWidth() const noexcept
Returns the component's width in pixels.
bool isEnabled() const noexcept
Returns true if the component (and all its parents) are enabled.
LookAndFeel & getLookAndFeel() const noexcept
Finds the appropriate look-and-feel to use for this component.
Rectangle< int > getLocalBounds() const noexcept
Returns the component's bounds, relative to its own origin.
int getParentHeight() const noexcept
Returns the height of the component's parent.
MouseInputSource getMainMouseSource() const noexcept
Returns the main mouse input device that the system is using.
static Desktop &JUCE_CALLTYPE getInstance()
There's only one desktop object, and this method will return it.
static DragAndDropContainer * findParentDragContainerFor(Component *childComponent)
Utility to find the DragAndDropContainer for a given Component.
Contains details about the source of a drag-and-drop operation.
A graphics context, used for drawing a component or image.
void setColour(Colour newColour)
Changes the current drawing colour.
void drawLine(float startX, float startY, float endX, float endY) const
Draws a line between two points.
void strokePath(const Path &path, const PathStrokeType &strokeType, const AffineTransform &transform={}) const
Draws a path's outline using the currently selected colour or brush.
void fillAll() const
Fills the context's entire clip region with the current colour or brush.
void drawRoundedRectangle(float x, float y, float width, float height, float cornerSize, float lineThickness) const
Uses the current colour or brush to draw the outline of a rectangle with rounded corners.
Represents a key press, including any modifier keys that are needed.
static const int homeKey
key-code for the home key
static const int upKey
key-code for the cursor-up key
static const int endKey
key-code for the end key
static const int rightKey
key-code for the cursor-right key
static const int downKey
key-code for the cursor-down key
static const int returnKey
key-code for the return key
static const int leftKey
key-code for the cursor-left key
static const int pageUpKey
key-code for the page-up key
static const int pageDownKey
key-code for the page-down key
@ leftButtonModifier
Left mouse button flag.
@ popupMenuClickModifier
Popup menu flag - on windows this is the same as rightButtonModifier, on the Mac it's the same as (ri...
Contains position and status information about a mouse event.
MouseEvent getEventRelativeTo(Component *newComponent) const noexcept
Creates a version of this event that is relative to a different component.
Describes a type of stroke used to render a solid outline along a path.
A path is a sequence of lines and curves that may either form a closed shape or be open-ended.
void startNewSubPath(float startX, float startY)
Begins a new subpath with a given starting position.
void addEllipse(float x, float y, float width, float height)
Adds an ellipse to the path.
void lineTo(float endX, float endY)
Adds a line from the shape's last position to a new end-point.
A pair of (x, y) coordinates.
ValueType y
The point's Y coordinate.
ValueType x
The point's X coordinate.
Manages a rectangle and allows geometric operations to be performed on it.
Rectangle withHeight(ValueType newHeight) const noexcept
Returns a rectangle which has the same position and width as this one, but with a different height.
Rectangle< float > toFloat() const noexcept
Casts this rectangle to a Rectangle<float>.
Point< ValueType > getTopLeft() const noexcept
Returns the rectangle's top-left position as a Point.
Rectangle withWidth(ValueType newWidth) const noexcept
Returns a rectangle which has the same position and height as this one, but with a different width.
A non-owning view over contiguous objects stored in an Array or vector or other similar container.
A special array for holding a list of strings.
int size() const noexcept
Returns the number of strings in the array.
String replaceCharacter(juce_wchar characterToReplace, juce_wchar characterToInsertInstead) const
Returns a string with all occurrences of a character replaced with a different one.
static Time JUCE_CALLTYPE getCurrentTime() noexcept
Returns a Time object that is set to the current system time.
virtual bool canBeSelected() const
You can override this method to return false if you don't want to allow the user to select this item.
TreeView * getOwnerView() const noexcept
Returns the TreeView to which this item belongs.
virtual String getUniqueName() const
Returns a string to uniquely identify this item.
void removeSubItem(int index, bool deleteItem=true)
Removes one of the sub-items.
bool isSelected() const noexcept
True if this item is currently selected.
void setDrawsInRightMargin(bool canDrawInRightMargin) noexcept
Sets a flag to indicate that the item wants to be allowed to draw all the way across to the right edg...
void clearSubItems()
Removes any sub-items.
virtual void itemDropped(const DragAndDropTarget::SourceDetails &dragSourceDetails, int insertIndex)
When a things are dropped into this item, this callback is invoked.
void setDrawsInLeftMargin(bool canDrawInLeftMargin) noexcept
Sets a flag to indicate that the item wants to be allowed to draw all the way across to the left edge...
int getNumSubItems() const noexcept
Returns the number of sub-items that have been added to this item.
virtual bool mightContainSubItems()=0
Tells the tree whether this item can potentially be opened.
virtual void itemClicked(const MouseEvent &)
Called when the user clicks on this item.
void setOpenness(Openness newOpenness)
Opens or closes the item.
int getIndexInParent() const noexcept
Returns the index of this item in its parent's sub-items.
virtual void paintItem(Graphics &g, int width, int height)
Draws the item's contents.
virtual void itemDoubleClicked(const MouseEvent &)
Called when the user double-clicks on this item.
virtual int getItemWidth() const
Must return the width required by this item.
void restoreOpennessState(const XmlElement &xml)
Restores the openness of this item and all its sub-items from a saved state.
virtual bool isInterestedInDragSource(const DragAndDropTarget::SourceDetails &dragSourceDetails)
If you want your item to act as a DragAndDropTarget, implement this method and return true.
virtual void paintOpenCloseButton(Graphics &, const Rectangle< float > &area, Colour backgroundColour, bool isMouseOver)
Draws the item's open/close button.
virtual void paintHorizontalConnectingLine(Graphics &, const Line< float > &line)
Draws the line that connects this item to the vertical line extending below its parent.
virtual void itemOpennessChanged(bool isNowOpen)
Called when an item is opened or closed.
bool isOpen() const noexcept
True if this item is currently open in the TreeView.
void setLinesDrawnForSubItems(bool shouldDrawLines) noexcept
Changes whether lines are drawn to connect any sub-items to this item.
void treeHasChanged() const noexcept
Sends a signal to the TreeView to make it refresh itself.
int getRowNumberInTree() const noexcept
Returns the row number of this item in the tree.
void setOpen(bool shouldBeOpen)
Opens or closes the item.
TreeViewItem()
Constructor.
void repaintItem() const
Sends a repaint message to redraw just this item.
Openness getOpenness() const noexcept
Returns the openness state of this item.
virtual int getItemHeight() const
Must return the height required by this item.
virtual bool isInterestedInFileDrag(const StringArray &files)
If you want your item to be able to have files drag-and-dropped onto it, implement this method and re...
std::unique_ptr< XmlElement > getOpennessState() const
Saves the current state of open/closed nodes so it can be restored later.
virtual ~TreeViewItem()
Destructor.
virtual void ownerViewChanged(TreeView *newOwner)
Called when the owner view changes.
virtual void itemSelectionChanged(bool isNowSelected)
Called when the item is selected or deselected.
virtual void filesDropped(const StringArray &files, int insertIndex)
When files are dropped into this item, this callback is invoked.
virtual String getTooltip()
The item can return a tool tip string here if it wants to.
void addSubItem(TreeViewItem *newItem, int insertPosition=-1)
Adds a sub-item.
bool isLastOfSiblings() const noexcept
Returns true if this item is the last of its parent's sub-items.
TreeViewItem * getSubItem(int index) const noexcept
Returns one of the item's sub-items.
virtual String getAccessibilityName()
Use this to set the name for this item that will be read out by accessibility clients.
TreeViewItem * getParentItem() const noexcept
Returns the item within which this item is contained.
Openness
An enum of states to describe the explicit or implicit openness of an item.
String getItemIdentifierString() const
Creates a string that can be used to uniquely retrieve this item in the tree.
virtual var getDragSourceDescription()
To allow items from your TreeView to be dragged-and-dropped, implement this method.
Rectangle< int > getItemPosition(bool relativeToTreeViewTopLeft) const noexcept
Returns the rectangle that this item occupies.
virtual void paintVerticalConnectingLine(Graphics &, const Line< float > &line)
Draws the line that extends vertically up towards one of its parents, or down to one of its children.
bool areAllParentsOpen() const noexcept
Returns true if all the item's parent nodes are open.
void setSelected(bool shouldBeSelected, bool deselectOtherItemsFirst, NotificationType shouldNotify=sendNotification)
Selects or deselects the item.
void mouseDoubleClick(const MouseEvent &e) override
Called when a mouse button has been double-clicked on a component.
void mouseDown(const MouseEvent &e) override
Called when a mouse button is pressed.
void mouseMove(const MouseEvent &e) override
Called when the mouse moves inside a component.
void mouseDrag(const MouseEvent &e) override
Called when the mouse is moved while a button is held down.
String getTooltip() override
Returns the string that this object wants to show as its tooltip.
void mouseUp(const MouseEvent &e) override
Called when a mouse button is released.
void resized() override
Called when this component's size has been changed.
void mouseExit(const MouseEvent &e) override
Called when the mouse moves out of a component.
void paint(Graphics &g) override
Components can override this method to draw their content.
std::vector< const AccessibilityHandler * > getDisclosedRows() const override
Returns a list of the accessibility elements that are disclosed by this element, if any.
const AccessibilityHandler * getTableHandler() const override
Returns the AccessibilityHandler of the table which contains the cell.
int getDisclosureLevel() const override
Returns the indentation level for the cell.
void paint(Graphics &g) override
Components can override this method to draw their content.
void resized() override
Called when this component's size has been changed.
String getTooltip() override
Returns the string that this object wants to show as its tooltip.
void paint(Graphics &g) override
Components can override this method to draw their content.
void visibleAreaChanged(const Rectangle< int > &newVisibleArea) override
Callback method that is called when the visible area changes.
bool keyPressed(const KeyPress &key) override
Called when a key is pressed.
TreeViewItem * findItemFromIdentifierString(const String &identifierString) const
Searches the tree for an item with the specified identifier.
bool isInterestedInFileDrag(const StringArray &) override
Callback to check whether this target is interested in the set of files being offered.
void scrollToKeepItemVisible(const TreeViewItem *item)
Tries to scroll the tree so that this item is on-screen somewhere.
TreeViewItem * getSelectedItem(int index) const noexcept
Returns one of the selected items in the tree.
Component * getItemComponent(const TreeViewItem *item) const
Returns the component that currently represents a given TreeViewItem.
void filesDropped(const StringArray &, int, int) override
Callback to indicate that the user has dropped the files onto this component.
TreeViewItem * getItemOnRow(int index) const
Returns the item on a particular row of the tree.
void colourChanged() override
This method is called when a colour is changed by the setColour() method, or when the look-and-feel i...
@ dragAndDropIndicatorColourId
The colour to use for the drag-and-drop target position indicator.
@ oddItemsColourId
The colour to use to fill the background of the odd numbered items.
@ linesColourId
The colour to draw the lines with.
@ selectedItemBackgroundColourId
The colour to use to fill the background of any selected items.
@ backgroundColourId
A background colour to fill the component with.
TreeViewItem * getRootItem() const noexcept
Returns the tree's root item.
void moveSelectedRow(int deltaRows)
Moves the selected row up or down by the specified number of rows.
void setDefaultOpenness(bool isOpenByDefault)
Sets whether items are open or closed by default.
int getNumRowsInTree() const
Returns the number of rows the tree is using, depending on which items are open.
TreeView(const String &componentName={})
Creates an empty TreeView.
TreeViewItem * getItemAt(int yPosition) const noexcept
Returns the item that contains a given y-position relative to the top of the TreeView component.
Viewport * getViewport() const noexcept
Returns the TreeView's Viewport object.
void fileDragMove(const StringArray &, int, int) override
Callback to indicate that the user is dragging some files over this component.
void clearSelectedItems()
Deselects any items that are currently selected.
void resized() override
Called when this component's size has been changed.
std::unique_ptr< AccessibilityHandler > createAccessibilityHandler() override
Override this method to return a custom AccessibilityHandler for this component.
void paint(Graphics &) override
Components can override this method to draw their content.
void itemDragEnter(const SourceDetails &) override
Callback to indicate that something is being dragged over this component.
void restoreOpennessState(const XmlElement &newState, bool restoreStoredSelection)
Restores a previously saved arrangement of open/closed nodes.
bool isInterestedInDragSource(const SourceDetails &) override
Callback to check whether this target is interested in the type of object being dragged.
std::unique_ptr< XmlElement > getOpennessState(bool alsoIncludeScrollPosition) const
Saves the current state of open/closed nodes so it can be restored later.
bool keyPressed(const KeyPress &) override
Called when a key is pressed.
void fileDragEnter(const StringArray &, int, int) override
Callback to indicate that some files are being dragged over this component.
bool isMultiSelectEnabled() const noexcept
Returns whether multi-select has been enabled for the tree.
int getNumSelectedItems(int maximumDepthToSearchTo=-1) const noexcept
Returns the number of items that are currently selected.
void itemDropped(const SourceDetails &) override
Callback to indicate that the user has dropped something onto this component.
void enablementChanged() override
Callback to indicate that this component has been enabled or disabled.
void itemDragMove(const SourceDetails &) override
Callback to indicate that the user is dragging something over this component.
void setIndentSize(int newIndentSize)
Changes the distance by which each nested level of the tree is indented.
void fileDragExit(const StringArray &) override
Callback to indicate that the mouse has moved away from this component.
int getIndentSize() noexcept
Returns the number of pixels by which each nested level of the tree is indented.
void setOpenCloseButtonsVisible(bool shouldBeVisible)
Sets a flag to indicate whether to hide the open/close buttons.
void deleteRootItem()
This will remove and delete the current root item.
~TreeView() override
Destructor.
void setMultiSelectEnabled(bool canMultiSelect)
This sets a flag to indicate that the tree can be used for multi-selection.
void itemDragExit(const SourceDetails &) override
Callback to indicate that something has been dragged off the edge of this component.
void setRootItem(TreeViewItem *newRootItem)
Sets the item that is displayed in the TreeView.
void setRootItemVisible(bool shouldBeVisible)
Changes whether the tree's root item is shown or not.
A Viewport is used to contain a larger child component, and allows the child to be automatically scro...
Component * getViewedComponent() const noexcept
Returns the component that's currently being used inside the Viewport.
bool keyPressed(const KeyPress &) override
Called when a key is pressed.
void setViewPosition(int xPixelsOffset, int yPixelsOffset)
Changes the position of the viewed component.
int getMaximumVisibleWidth() const
Returns the width available within this component for the contents.
Used to build a tree of elements representing an XML document.
XmlElement * createNewChildElement(StringRef tagName)
Creates a new element with the given name and returns it, after adding it as a child element.
bool hasTagName(StringRef possibleTagName) const noexcept
Tests whether this element has a particular tag name.
Iterator< GetNextElement > getChildIterator() const
Allows iterating the children of an XmlElement using range-for syntax.
void setAttribute(const Identifier &attributeName, const String &newValue)
Adds a named attribute to the element.
A variant class, that can be used to hold a range of primitive values.
constexpr Type jmax(Type a, Type b)
Returns the larger of two values.
Type jlimit(Type lowerLimit, Type upperLimit, Type valueToConstrain) noexcept
Constrains a value to keep it within a given range.
@ rowSelectionChanged
Indicates that the selection of rows in a list or table has changed.
@ structureChanged
Indicates that the structure of the UI elements has changed in a significant way.
NotificationType
These enums are used in various classes to indicate whether a notification event should be sent out.
@ dontSendNotification
No notification message should be sent.
Type unalignedPointerCast(void *ptr) noexcept
Casts a pointer to another type via void*, which suppresses the cast-align warning which sometimes ar...
@ showMenu
Represents the user showing a contextual menu for a UI element.
@ focus
Indicates that the UI element has received focus.
@ toggle
Represents a "toggle" action.
@ press
Represents a "press" action.
AccessibilityRole
The list of available roles for an AccessibilityHandler object.
Utility struct which holds one or more accessibility interfaces.