JUCE-7.0.12-0-g4f43011b96 JUCE-7.0.12-0-g4f43011b96
JUCE — C++ application framework with suport for VST, VST3, LV2 audio plug-ins

« « « Anklang Documentation
Loading...
Searching...
No Matches
juce_TableHeaderComponent.cpp
Go to the documentation of this file.
1 /*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 By using JUCE, you agree to the terms of both the JUCE 7 End-User License
11 Agreement and JUCE Privacy Policy.
12
13 End User License Agreement: www.juce.com/juce-7-licence
14 Privacy Policy: www.juce.com/juce-privacy-policy
15
16 Or: You may also use this code under the terms of the GPL v3 (see
17 www.gnu.org/licenses).
18
19 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
20 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
21 DISCLAIMED.
22
23 ==============================================================================
24*/
25
26namespace juce
27{
28
30{
31public:
32 DragOverlayComp (const Image& i) : image (i)
33 {
34 image.duplicateIfShared();
35 image.multiplyAllAlphas (0.8f);
36 setAlwaysOnTop (true);
37 }
38
39 void paint (Graphics& g) override
40 {
41 g.drawImage (image, getLocalBounds().toFloat());
42 }
43
44 Image image;
45
47};
48
49
50//==============================================================================
55
57{
58 dragOverlayComp.reset();
59}
60
61//==============================================================================
63{
64 menuActive = hasMenu;
65}
66
67bool TableHeaderComponent::isPopupMenuActive() const { return menuActive; }
68
69
70//==============================================================================
72{
74 {
75 int num = 0;
76
77 for (auto* c : columns)
78 if (c->isVisible())
79 ++num;
80
81 return num;
82 }
83
84 return columns.size();
85}
86
88{
89 if (auto* ci = getInfoForId (columnId))
90 return ci->getTitle();
91
92 return {};
93}
94
95void TableHeaderComponent::setColumnName (const int columnId, const String& newName)
96{
97 if (auto* ci = getInfoForId (columnId))
98 {
99 if (ci->getTitle() != newName)
100 {
101 ci->setTitle (newName);
102 sendColumnsChanged();
103 }
104 }
105}
106
108 int columnId,
109 int width,
110 int minimumWidth,
111 int maximumWidth,
112 int propertyFlags,
113 int insertIndex)
114{
115 // can't have a duplicate or zero ID!
116 jassert (columnId != 0 && getIndexOfColumnId (columnId, false) < 0);
117 jassert (width > 0);
118
119 auto ci = new ColumnInfo();
120 ci->setTitle (columnName);
121 ci->id = columnId;
122 ci->width = width;
123 ci->lastDeliberateWidth = width;
124 ci->minimumWidth = minimumWidth;
125 ci->maximumWidth = maximumWidth >= 0 ? maximumWidth : std::numeric_limits<int>::max();
126 jassert (ci->maximumWidth >= ci->minimumWidth);
127 ci->propertyFlags = propertyFlags;
128
129 auto* added = columns.insert (insertIndex, ci);
131 added->setVisible ((propertyFlags & visible) != 0);
132
133 resized();
134 sendColumnsChanged();
135}
136
138{
139 auto index = getIndexOfColumnId (columnIdToRemove, false);
140
141 if (index >= 0)
142 {
143 columns.remove (index);
144 sortChanged = true;
145 sendColumnsChanged();
146 }
147}
148
150{
151 if (columns.size() > 0)
152 {
153 columns.clear();
154 sendColumnsChanged();
155 }
156}
157
159{
161 newIndex = visibleIndexToTotalIndex (newIndex);
162
163 if (columns[currentIndex] != nullptr && currentIndex != newIndex)
164 {
165 columns.move (currentIndex, newIndex);
166 sendColumnsChanged();
167 }
168}
169
171{
172 if (auto* ci = getInfoForId (columnId))
173 return ci->width;
174
175 return 0;
176}
177
179{
180 if (auto* ci = getInfoForId (columnId))
181 {
182 const auto newWidthToUse = jlimit (ci->minimumWidth, ci->maximumWidth, newWidth);
183
184 if (ci->width != newWidthToUse)
185 {
186 auto numColumns = getNumColumns (true);
187
188 ci->lastDeliberateWidth = ci->width = newWidthToUse;
189
190 if (stretchToFit)
191 {
192 auto index = getIndexOfColumnId (columnId, true) + 1;
193
194 if (isPositiveAndBelow (index, numColumns))
195 {
196 auto x = getColumnPosition (index).getX();
197
198 if (lastDeliberateWidth == 0)
199 lastDeliberateWidth = getTotalWidth();
200
201 resizeColumnsToFit (visibleIndexToTotalIndex (index), lastDeliberateWidth - x);
202 }
203 }
204
205 resized();
206 repaint();
207 columnsResized = true;
209 }
210 }
211}
212
213//==============================================================================
215{
216 int n = 0;
217
218 for (auto* c : columns)
219 {
220 if ((! onlyCountVisibleColumns) || c->isVisible())
221 {
222 if (c->id == columnId)
223 return n;
224
225 ++n;
226 }
227 }
228
229 return -1;
230}
231
233{
235 index = visibleIndexToTotalIndex (index);
236
237 if (auto* ci = columns [index])
238 return ci->id;
239
240 return 0;
241}
242
244{
245 int x = 0, width = 0, n = 0;
246
247 for (auto* c : columns)
248 {
249 x += width;
250
251 if (c->isVisible())
252 {
253 width = c->width;
254
255 if (n++ == index)
256 break;
257 }
258 else
259 {
260 width = 0;
261 }
262 }
263
264 return { x, 0, width, getHeight() };
265}
266
268{
269 if (xToFind >= 0)
270 {
271 int x = 0;
272
273 for (auto* ci : columns)
274 {
275 if (ci->isVisible())
276 {
277 x += ci->width;
278
279 if (xToFind < x)
280 return ci->id;
281 }
282 }
283 }
284
285 return 0;
286}
287
289{
290 int w = 0;
291
292 for (auto* c : columns)
293 if (c->isVisible())
294 w += c->width;
295
296 return w;
297}
298
300{
301 stretchToFit = shouldStretchToFit;
302 lastDeliberateWidth = getTotalWidth();
303 resized();
304}
305
307{
308 return stretchToFit;
309}
310
312{
313 if (stretchToFit && getWidth() > 0
314 && columnIdBeingResized == 0 && columnIdBeingDragged == 0)
315 {
316 lastDeliberateWidth = targetTotalWidth;
317 resizeColumnsToFit (0, targetTotalWidth);
318 }
319}
320
321void TableHeaderComponent::resizeColumnsToFit (int firstColumnIndex, int targetTotalWidth)
322{
325
326 for (int i = firstColumnIndex; i < columns.size(); ++i)
327 {
328 auto* ci = columns.getUnchecked (i);
329
330 if (ci->isVisible())
331 sor.addItem (ci->lastDeliberateWidth, ci->minimumWidth, ci->maximumWidth);
332 }
333
334 sor.resizeToFit (targetTotalWidth);
335 int visIndex = 0;
336
337 for (int i = firstColumnIndex; i < columns.size(); ++i)
338 {
339 auto* ci = columns.getUnchecked (i);
340
341 if (ci->isVisible())
342 {
343 auto newWidth = jlimit (ci->minimumWidth, ci->maximumWidth,
344 (int) std::floor (sor.getItemSize (visIndex++)));
345
346 if (newWidth != ci->width)
347 {
348 ci->width = newWidth;
349 resized();
350 repaint();
351 columnsResized = true;
353 }
354 }
355 }
356}
357
359{
360 if (auto* ci = getInfoForId (columnId))
361 {
362 if (shouldBeVisible != ci->isVisible())
363 {
364 ci->setVisible (shouldBeVisible);
365 sendColumnsChanged();
366 resized();
367 }
368 }
369}
370
372{
373 if (auto* ci = getInfoForId (columnId))
374 return ci->isVisible();
375
376 return false;
377}
378
379//==============================================================================
381{
383 {
384 for (auto* c : columns)
385 c->propertyFlags &= ~(sortedForwards | sortedBackwards);
386
387 if (auto* ci = getInfoForId (columnId))
388 ci->propertyFlags |= (sortForwards ? sortedForwards : sortedBackwards);
389
390 reSortTable();
391 }
392}
393
395{
396 for (auto* c : columns)
397 if ((c->propertyFlags & (sortedForwards | sortedBackwards)) != 0)
398 return c->id;
399
400 return 0;
401}
402
404{
405 for (auto* c : columns)
406 if ((c->propertyFlags & (sortedForwards | sortedBackwards)) != 0)
407 return (c->propertyFlags & sortedForwards) != 0;
408
409 return true;
410}
411
413{
414 sortChanged = true;
415 resized();
416 repaint();
418}
419
420//==============================================================================
422{
423 String s;
424
425 XmlElement doc ("TABLELAYOUT");
426
427 doc.setAttribute ("sortedCol", getSortColumnId());
428 doc.setAttribute ("sortForwards", isSortedForwards());
429
430 for (auto* ci : columns)
431 {
432 auto* e = doc.createNewChildElement ("COLUMN");
433 e->setAttribute ("id", ci->id);
434 e->setAttribute ("visible", ci->isVisible());
435 e->setAttribute ("width", ci->width);
436 }
437
438 return doc.toString (XmlElement::TextFormat().singleLine().withoutHeader());
439}
440
442{
443 if (auto storedXML = parseXMLIfTagMatches (storedVersion, "TABLELAYOUT"))
444 {
445 int index = 0;
446
447 for (auto* col : storedXML->getChildIterator())
448 {
449 auto tabId = col->getIntAttribute ("id");
450
451 if (auto* ci = getInfoForId (tabId))
452 {
453 columns.move (columns.indexOf (ci), index);
454 ci->width = col->getIntAttribute ("width");
455 setColumnVisible (tabId, col->getBoolAttribute ("visible"));
456 }
457
458 ++index;
459 }
460
461 columnsResized = true;
462 sendColumnsChanged();
463
464 setSortColumnId (storedXML->getIntAttribute ("sortedCol"),
465 storedXML->getBoolAttribute ("sortForwards", true));
466 }
467}
468
469//==============================================================================
471{
472 listeners.addIfNotAlreadyThere (newListener);
473}
474
476{
477 listeners.removeFirstMatchingValue (listenerToRemove);
478}
479
480//==============================================================================
482{
483 if (auto* ci = getInfoForId (columnId))
484 if ((ci->propertyFlags & sortable) != 0 && ! mods.isPopupMenu())
485 setSortColumnId (columnId, (ci->propertyFlags & sortedForwards) == 0);
486}
487
488void TableHeaderComponent::addMenuItems (PopupMenu& menu, const int /*columnIdClicked*/)
489{
490 for (auto* ci : columns)
491 if ((ci->propertyFlags & appearsOnColumnMenu) != 0)
492 menu.addItem (ci->id, ci->getTitle(),
493 (ci->propertyFlags & (sortedForwards | sortedBackwards)) == 0,
494 isColumnVisible (ci->id));
495}
496
497void TableHeaderComponent::reactToMenuItem (const int menuReturnId, const int /*columnIdClicked*/)
498{
499 if (getIndexOfColumnId (menuReturnId, false) >= 0)
501}
502
503void TableHeaderComponent::drawColumnHeader (Graphics& g, LookAndFeel& lf, const ColumnInfo& ci)
504{
505 // Only paint columns that are visible
506 if (! ci.isVisible())
507 return;
508
509 // If this column is being dragged, it shouldn't be drawn in the table header
510 if (ci.id == columnIdBeingDragged && dragOverlayComp != nullptr && dragOverlayComp->isVisible())
511 return;
512
513 // There's no point drawing this column header if no part of it is visible
514 if (! g.getClipBounds()
517 return;
518
520
521 g.setOrigin (ci.getX(), ci.getY());
522 g.reduceClipRegion (0, 0, ci.width, ci.getHeight());
523
524 lf.drawTableHeaderColumn (g, *this, ci.getTitle(), ci.id, ci.width, getHeight(),
525 ci.id == columnIdUnderMouse,
526 ci.id == columnIdUnderMouse && isMouseButtonDown(),
527 ci.propertyFlags);
528}
529
531{
532 auto& lf = getLookAndFeel();
533
534 lf.drawTableHeaderBackground (g, *this);
535
536 for (auto* ci : columns)
537 drawColumnHeader (g, lf, *ci);
538}
539
541{
542 int x = 0;
543
544 for (auto* ci : columns)
545 {
546 const auto widthToUse = ci->isVisible() ? ci->width : 0;
547 ci->setBounds (x, 0, widthToUse, getHeight());
548 x += widthToUse;
549 }
550}
551
552void TableHeaderComponent::mouseMove (const MouseEvent& e) { updateColumnUnderMouse (e); }
553void TableHeaderComponent::mouseEnter (const MouseEvent& e) { updateColumnUnderMouse (e); }
554void TableHeaderComponent::mouseExit (const MouseEvent&) { setColumnUnderMouse (0); }
555
557{
558 resized();
559 repaint();
560 columnIdBeingResized = 0;
561 columnIdBeingDragged = 0;
562
563 if (columnIdUnderMouse != 0)
564 {
565 draggingColumnOffset = e.x - getColumnPosition (getIndexOfColumnId (columnIdUnderMouse, true)).getX();
566
567 if (e.mods.isPopupMenu())
568 columnClicked (columnIdUnderMouse, e.mods);
569 }
570
571 if (menuActive && e.mods.isPopupMenu())
572 showColumnChooserMenu (columnIdUnderMouse);
573}
574
576{
577 if (columnIdBeingResized == 0
578 && columnIdBeingDragged == 0
580 && ! e.mods.isPopupMenu())
581 {
582 dragOverlayComp.reset();
583
584 columnIdBeingResized = getResizeDraggerAt (e.getMouseDownX());
585
586 if (columnIdBeingResized != 0)
587 {
588 if (auto* ci = getInfoForId (columnIdBeingResized))
589 initialColumnWidth = ci->width;
590 else
592 }
593 else
594 {
595 beginDrag (e);
596 }
597 }
598
599 if (columnIdBeingResized != 0)
600 {
601 if (auto* ci = getInfoForId (columnIdBeingResized))
602 {
603 auto w = jlimit (ci->minimumWidth, ci->maximumWidth,
604 initialColumnWidth + e.getDistanceFromDragStartX());
605
606 if (stretchToFit)
607 {
608 // prevent us dragging a column too far right if we're in stretch-to-fit mode
609 int minWidthOnRight = 0;
610
611 for (int i = getIndexOfColumnId (columnIdBeingResized, false) + 1; i < columns.size(); ++i)
612 if (columns.getUnchecked (i)->isVisible())
613 minWidthOnRight += columns.getUnchecked (i)->minimumWidth;
614
615 auto currentPos = getColumnPosition (getIndexOfColumnId (columnIdBeingResized, true));
616 w = jmax (ci->minimumWidth, jmin (w, lastDeliberateWidth - minWidthOnRight - currentPos.getX()));
617 }
618
619 setColumnWidth (columnIdBeingResized, w);
620 }
621 }
622 else if (columnIdBeingDragged != 0)
623 {
624 if (e.y >= -50 && e.y < getHeight() + 50)
625 {
626 if (dragOverlayComp != nullptr)
627 {
628 dragOverlayComp->setVisible (true);
629 dragOverlayComp->setBounds (jlimit (0,
630 jmax (0, getTotalWidth() - dragOverlayComp->getWidth()),
631 e.x - draggingColumnOffset),
632 0,
633 dragOverlayComp->getWidth(),
634 getHeight());
635
636 for (int i = columns.size(); --i >= 0;)
637 {
638 const int currentIndex = getIndexOfColumnId (columnIdBeingDragged, true);
640
641 if (newIndex > 0)
642 {
643 // if the previous column isn't draggable, we can't move our column
644 // past it, because that'd change the undraggable column's position..
645 auto* previous = columns.getUnchecked (newIndex - 1);
646
647 if ((previous->propertyFlags & draggable) != 0)
648 {
651
652 if (std::abs (dragOverlayComp->getX() - leftOfPrevious)
653 < std::abs (dragOverlayComp->getRight() - rightOfCurrent))
654 {
655 --newIndex;
656 }
657 }
658 }
659
660 if (newIndex < columns.size() - 1)
661 {
662 // if the next column isn't draggable, we can't move our column
663 // past it, because that'd change the undraggable column's position..
664 auto* nextCol = columns.getUnchecked (newIndex + 1);
665
666 if ((nextCol->propertyFlags & draggable) != 0)
667 {
670
671 if (std::abs (dragOverlayComp->getX() - leftOfCurrent)
672 > std::abs (dragOverlayComp->getRight() - rightOfNext))
673 {
674 ++newIndex;
675 }
676 }
677 }
678
679 if (newIndex != currentIndex)
680 moveColumn (columnIdBeingDragged, newIndex);
681 else
682 break;
683 }
684 }
685 }
686 else
687 {
688 endDrag (draggingColumnOriginalIndex);
689 }
690 }
691}
692
693void TableHeaderComponent::beginDrag (const MouseEvent& e)
694{
695 if (columnIdBeingDragged == 0)
696 {
697 columnIdBeingDragged = getColumnIdAtX (e.getMouseDownX());
698
699 auto* ci = getInfoForId (columnIdBeingDragged);
700
701 if (ci == nullptr || (ci->propertyFlags & draggable) == 0)
702 {
703 columnIdBeingDragged = 0;
704 }
705 else
706 {
707 draggingColumnOriginalIndex = getIndexOfColumnId (columnIdBeingDragged, true);
708
709 auto columnRect = getColumnPosition (draggingColumnOriginalIndex);
710 auto temp = columnIdBeingDragged;
711 columnIdBeingDragged = 0;
712
713 dragOverlayComp.reset (new DragOverlayComp (createComponentSnapshot (columnRect, false, 2.0f)));
714 addAndMakeVisible (dragOverlayComp.get());
715 columnIdBeingDragged = temp;
716
717 dragOverlayComp->setBounds (columnRect);
718
719 for (int i = listeners.size(); --i >= 0;)
720 {
721 listeners.getUnchecked (i)->tableColumnDraggingChanged (this, columnIdBeingDragged);
722 i = jmin (i, listeners.size() - 1);
723 }
724 }
725 }
726}
727
728void TableHeaderComponent::endDrag (const int finalIndex)
729{
730 if (columnIdBeingDragged != 0)
731 {
732 moveColumn (columnIdBeingDragged, finalIndex);
733
734 columnIdBeingDragged = 0;
735 resized();
736 repaint();
737
738 for (int i = listeners.size(); --i >= 0;)
739 {
740 listeners.getUnchecked (i)->tableColumnDraggingChanged (this, 0);
741 i = jmin (i, listeners.size() - 1);
742 }
743 }
744}
745
747{
748 mouseDrag (e);
749
750 for (auto* c : columns)
751 if (c->isVisible())
752 c->lastDeliberateWidth = c->width;
753
754 columnIdBeingResized = 0;
755 resized();
756 repaint();
757
758 endDrag (getIndexOfColumnId (columnIdBeingDragged, true));
759
760 updateColumnUnderMouse (e);
761
762 if (columnIdUnderMouse != 0 && ! (e.mouseWasDraggedSinceMouseDown() || e.mods.isPopupMenu()))
763 columnClicked (columnIdUnderMouse, e.mods);
764
765 dragOverlayComp.reset();
766}
767
769{
770 if (columnIdBeingResized != 0 || (getResizeDraggerAt (getMouseXYRelative().getX()) != 0 && ! isMouseButtonDown()))
772
774}
775
776//==============================================================================
777
778TableHeaderComponent::ColumnInfo* TableHeaderComponent::getInfoForId (int id) const
779{
780 for (auto* c : columns)
781 if (c->id == id)
782 return c;
783
784 return nullptr;
785}
786
787int TableHeaderComponent::visibleIndexToTotalIndex (const int visibleIndex) const
788{
789 int n = 0;
790
791 for (int i = 0; i < columns.size(); ++i)
792 {
793 if (columns.getUnchecked (i)->isVisible())
794 {
795 if (n == visibleIndex)
796 return i;
797
798 ++n;
799 }
800 }
801
802 return -1;
803}
804
805void TableHeaderComponent::sendColumnsChanged()
806{
807 if (stretchToFit && lastDeliberateWidth > 0)
808 resizeAllColumnsToFit (lastDeliberateWidth);
809
810 resized();
811 repaint();
812 columnsChanged = true;
814}
815
816void TableHeaderComponent::handleAsyncUpdate()
817{
818 const bool changed = columnsChanged || sortChanged;
819 const bool sized = columnsResized || changed;
820 const bool sorted = sortChanged;
821 columnsChanged = false;
822 columnsResized = false;
823 sortChanged = false;
824
825 if (sorted)
826 {
827 for (int i = listeners.size(); --i >= 0;)
828 {
829 listeners.getUnchecked (i)->tableSortOrderChanged (this);
830 i = jmin (i, listeners.size() - 1);
831 }
832 }
833
834 if (changed)
835 {
836 for (int i = listeners.size(); --i >= 0;)
837 {
838 listeners.getUnchecked (i)->tableColumnsChanged (this);
839 i = jmin (i, listeners.size() - 1);
840 }
841 }
842
843 if (sized)
844 {
845 for (int i = listeners.size(); --i >= 0;)
846 {
847 listeners.getUnchecked (i)->tableColumnsResized (this);
848 i = jmin (i, listeners.size() - 1);
849 }
850 }
851}
852
853int TableHeaderComponent::getResizeDraggerAt (const int mouseX) const
854{
856 {
857 const int draggableDistance = 3;
858 int x = 0;
859
860 for (auto* ci : columns)
861 {
862 if (ci->isVisible())
863 {
864 if (std::abs (mouseX - (x + ci->width)) <= draggableDistance
865 && (ci->propertyFlags & resizable) != 0)
866 return ci->id;
867
868 x += ci->width;
869 }
870 }
871 }
872
873 return 0;
874}
875
876void TableHeaderComponent::setColumnUnderMouse (const int newCol)
877{
878 if (newCol != columnIdUnderMouse)
879 {
880 columnIdUnderMouse = newCol;
881 repaint();
882 }
883}
884
885void TableHeaderComponent::updateColumnUnderMouse (const MouseEvent& e)
886{
887 setColumnUnderMouse (reallyContains (e.getPosition(), true) && getResizeDraggerAt (e.x) == 0
888 ? getColumnIdAtX (e.x) : 0);
889}
890
891static void tableHeaderMenuCallback (int result, TableHeaderComponent* tableHeader, int columnIdClicked)
892{
893 if (tableHeader != nullptr && result != 0)
894 tableHeader->reactToMenuItem (result, columnIdClicked);
895}
896
898{
899 PopupMenu m;
901
902 if (m.getNumItems() > 0)
903 {
905
907 ModalCallbackFunction::forComponent (tableHeaderMenuCallback, this, columnIdClicked));
908 }
909}
910
914
915//==============================================================================
917{
918 return std::make_unique<AccessibilityHandler> (*this, AccessibilityRole::tableHeader);
919}
920
921std::unique_ptr<AccessibilityHandler> TableHeaderComponent::ColumnInfo::createAccessibilityHandler()
922{
923 return std::make_unique<AccessibilityHandler> (*this, AccessibilityRole::tableHeader);
924}
925
926} // namespace juce
void triggerAsyncUpdate()
Causes the callback to be triggered at a later time.
The base class for all JUCE user-interface objects.
bool isMouseButtonDown(bool includeChildren=false) const
Returns true if the mouse button is currently held down in this component.
virtual MouseCursor getMouseCursor()
Returns the mouse cursor shape to use when the mouse is over this component.
Image createComponentSnapshot(Rectangle< int > areaToGrab, bool clipImageToComponentBounds=true, float scaleFactor=1.0f)
Generates a snapshot of part of this component.
bool reallyContains(Point< int > localPoint, bool returnTrueIfWithinAChild)
Returns true if a given point lies in this component, taking any overlapping siblings into account.
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.
int getX() const noexcept
Returns the x coordinate of the component's left edge.
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.
void repaint()
Marks the whole component as needing to be redrawn.
@ 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 getWidth() const noexcept
Returns the component's width in pixels.
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.
void addChildComponent(Component *child, int zOrder=-1)
Adds a child component to this one.
Uses RAII to save and restore the state of a graphics context.
A graphics context, used for drawing a component or image.
void drawImage(const Image &imageToDraw, int destX, int destY, int destWidth, int destHeight, int sourceX, int sourceY, int sourceWidth, int sourceHeight, bool fillAlphaChannelWithCurrentBrush=false) const
Draws part of an image, rescaling it to fit in a given target region.
bool reduceClipRegion(int x, int y, int width, int height)
Intersects the current clipping region with another region.
Rectangle< int > getClipBounds() const
Returns the position of the bounding box for the current clipping region.
void setOrigin(Point< int > newOrigin)
Moves the position of the context's origin.
Holds a fixed-size bitmap.
Definition juce_Image.h:58
void multiplyAllAlphas(float amountToMultiplyBy)
Changes the overall opacity of the image.
void duplicateIfShared()
Makes sure that no other Image objects share the same underlying data as this one.
LookAndFeel objects define the appearance of all the JUCE widgets, and subclasses can be used to appl...
static ModalComponentManager::Callback * forComponent(void(*functionToCall)(int, ComponentType *), ComponentType *component)
This is a utility function to create a ModalComponentManager::Callback that will call a static functi...
Represents the state of the mouse buttons and modifier keys.
bool isPopupMenu() const noexcept
Checks whether the user is trying to launch a pop-up menu.
Represents a mouse cursor image.
@ LeftRightResizeCursor
An arrow pointing left and right.
Contains position and status information about a mouse event.
const ModifierKeys mods
The key modifiers associated with the event.
int getMouseDownX() const noexcept
Returns the x coordinate of the last place that a mouse was pressed.
const int x
The x-position of the mouse when the event occurred.
bool mouseWasDraggedSinceMouseDown() const noexcept
Returns true if the user seems to be performing a drag gesture.
const int y
The y-position of the mouse when the event occurred.
int getDistanceFromDragStartX() const noexcept
Returns the difference between the mouse's current x position and where it was when the button was la...
int size() const noexcept
Returns the number of items currently in the array.
ObjectClass * getUnchecked(int index) const noexcept
Returns a pointer to the object at this index in the array, without checking whether the index is in-...
void remove(int indexToRemove, bool deleteObject=true)
Removes an object from the array.
void clear(bool deleteObjects=true)
Clears the array, optionally deleting the objects inside it first.
int indexOf(const ObjectClass *objectToLookFor) const noexcept
Finds the index of an object which might be in the array.
void move(int currentIndex, int newIndex) noexcept
Moves one of the objects to a different position.
ObjectClass * insert(int indexToInsertAt, ObjectClass *newObject)
Inserts a new object into the array at the given index.
Class used to create a set of options to pass to the show() method.
Creates and displays a popup-menu.
void showMenuAsync(const Options &options)
Runs the menu asynchronously.
int getNumItems() const noexcept
Returns the number of items that the menu currently contains.
void setLookAndFeel(LookAndFeel *newLookAndFeel)
Specifies a look-and-feel for the menu and any sub-menus that it has.
A general-purpose range object, that simply represents any linear range with a start and end point.
Definition juce_Range.h:40
constexpr bool intersects(Range other) const noexcept
Returns true if the given range intersects this one.
Definition juce_Range.h:232
Manages a rectangle and allows geometric operations to be performed on it.
ValueType getRight() const noexcept
Returns the x coordinate of the rectangle's right-hand-side.
Range< ValueType > getHorizontalRange() const noexcept
Returns the rectangle's left and right positions as a Range.
ValueType getX() const noexcept
Returns the x coordinate of the rectangle's left-hand-side.
A utility class for fitting a set of objects whose sizes can vary between a minimum and maximum size,...
The JUCE String class!
Definition juce_String.h:53
void paint(Graphics &g) override
Components can override this method to draw their content.
Receives events from a TableHeaderComponent when columns are resized, moved, etc.
virtual void tableColumnDraggingChanged(TableHeaderComponent *tableHeader, int columnIdNowBeingDragged)
This is called when the user begins or ends dragging one of the columns around.
A component that displays a strip of column headings for a table, and allows these to be resized,...
void setColumnVisible(int columnId, bool shouldBeVisible)
Shows or hides a column.
int getIndexOfColumnId(int columnId, bool onlyCountVisibleColumns) const
Returns the index of a given column.
int getColumnIdOfIndex(int index, bool onlyCountVisibleColumns) const
Returns the ID of the column at a given index.
void removeListener(Listener *listenerToRemove)
Removes a previously-registered listener.
std::unique_ptr< AccessibilityHandler > createAccessibilityHandler() override
Override this method to return a custom AccessibilityHandler for this component.
void reSortTable()
Triggers a re-sort of the table according to the current sort-column.
void setColumnName(int columnId, const String &newName)
Changes the name of a column.
void mouseExit(const MouseEvent &) override
Called when the mouse moves out of a component.
virtual void addMenuItems(PopupMenu &menu, int columnIdClicked)
This can be overridden to add custom items to the pop-up menu.
void paint(Graphics &) override
Components can override this method to draw their content.
void mouseDrag(const MouseEvent &) override
Called when the mouse is moved while a button is held down.
virtual void showColumnChooserMenu(int columnIdClicked)
Can be overridden for more control over the pop-up menu behaviour.
void mouseEnter(const MouseEvent &) override
Called when the mouse first enters a component.
virtual void columnClicked(int columnId, const ModifierKeys &mods)
This can be overridden to handle a mouse-click on one of the column headers.
virtual void reactToMenuItem(int menuReturnId, int columnIdClicked)
Override this to handle any custom items that you have added to the pop-up menu with an addMenuItems(...
String getColumnName(int columnId) const
Returns the name for a column.
int getColumnWidth(int columnId) const
Returns the width of one of the columns.
void removeColumn(int columnIdToRemove)
Removes a column with the given ID.
void moveColumn(int columnId, int newVisibleIndex)
Moves a column to a different index in the table.
void restoreFromString(const String &storedVersion)
Restores the state of the table, based on a string previously created with toString().
TableHeaderComponent()
Creates an empty table header.
~TableHeaderComponent() override
Destructor.
void mouseUp(const MouseEvent &) override
Called when a mouse button is released.
bool isStretchToFitActive() const
Returns true if stretch-to-fit has been enabled.
void resizeAllColumnsToFit(int targetTotalWidth)
If stretch-to-fit is enabled, this will resize all the columns to make them fit into the specified wi...
int getSortColumnId() const
Returns the column ID by which the table is currently sorted, or 0 if it is unsorted.
void removeAllColumns()
Deletes all columns from the table.
int getNumColumns(bool onlyCountVisibleColumns) const
Returns the number of columns in the table.
void resized() override
Called when this component's size has been changed.
MouseCursor getMouseCursor() override
Returns the mouse cursor shape to use when the mouse is over this component.
void mouseMove(const MouseEvent &) override
Called when the mouse moves inside a component.
@ sortable
If this is set, then clicking on the column header will set it to be the sort column,...
@ visible
If this is set, the column will be shown; if not, it will be hidden until the user enables it with th...
@ draggable
If this is set, the column can be dragged around to change its order in the table.
@ sortedForwards
If this is set, the column is currently the one by which the table is sorted (forwards).
@ appearsOnColumnMenu
If this is set, the column will be shown on the pop-up menu allowing it to be hidden/shown.
@ sortedBackwards
If this is set, the column is currently the one by which the table is sorted (backwards).
@ resizable
If this is set, the column can be resized by dragging it.
void setSortColumnId(int columnId, bool sortForwards)
Changes the column which is the sort column.
String toString() const
Returns a string that encapsulates the table's current layout.
void setStretchToFitActive(bool shouldStretchToFit)
If set to true, this indicates that the columns should be expanded or shrunk to fill the entire width...
Rectangle< int > getColumnPosition(int index) const
Returns the rectangle containing of one of the columns.
void addColumn(const String &columnName, int columnId, int width, int minimumWidth=30, int maximumWidth=-1, int propertyFlags=defaultFlags, int insertIndex=-1)
Adds a column to the table.
int getColumnIdAtX(int xToFind) const
Finds the column ID at a given x-position in the component.
int getTotalWidth() const
Returns the total width of all the visible columns in the table.
void addListener(Listener *newListener)
Adds a listener to be informed about things that happen to the header.
bool isColumnVisible(int columnId) const
Returns true if this column is currently visible.
bool isPopupMenuActive() const
Returns true if the pop-up menu is enabled.
void mouseDown(const MouseEvent &) override
Called when a mouse button is pressed.
bool isSortedForwards() const
Returns true if the table is currently sorted forwards, or false if it's backwards.
void setColumnWidth(int columnId, int newWidth)
Changes the width of a column.
void setPopupMenuActive(bool hasMenu)
Enables or disables the pop-up menu.
Used to build a tree of elements representing an XML document.
T floor(T... args)
#define jassert(expression)
Platform-independent assertion macro.
#define JUCE_DECLARE_NON_COPYABLE(className)
This is a shorthand macro for deleting a class's copy constructor and copy assignment operator.
#define jassertfalse
This will always cause an assertion failure.
T max(T... args)
JUCE Namespace.
constexpr Type jmin(Type a, Type b)
Returns the smaller of two values.
std::unique_ptr< XmlElement > parseXMLIfTagMatches(const String &textToParse, StringRef requiredTag)
Does an inexpensive check to see whether the top-level element has the given tag name,...
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.
Type unalignedPointerCast(void *ptr) noexcept
Casts a pointer to another type via void*, which suppresses the cast-align warning which sometimes ar...
Definition juce_Memory.h:88
bool isPositiveAndBelow(Type1 valueToTest, Type2 upperLimit) noexcept
Returns true if a value is at least zero, and also below a specified upper limit.
A struct containing options for formatting the text when representing an XML element as a string.
TextFormat withoutHeader() const
returns a copy of this format with the addDefaultHeader flag set to false.
TextFormat singleLine() const
returns a copy of this format with newLineChars set to nullptr.