Add TAL-Reverb-II plugin to test
[juce-lv2.git] / juce / source / extras / JuceDemo / Source / demos / TableDemo.cpp
blob03b5471fb68f0a0d4bd8fe955e3f0b8d8bf716c5
1 /*
2 ==============================================================================
4 This file is part of the JUCE library - "Jules' Utility Class Extensions"
5 Copyright 2004-9 by Raw Material Software Ltd.
7 ------------------------------------------------------------------------------
9 JUCE can be redistributed and/or modified under the terms of the GNU General
10 Public License (Version 2), as published by the Free Software Foundation.
11 A copy of the license is included in the JUCE distribution, or can be found
12 online at www.gnu.org/licenses.
14 JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 ------------------------------------------------------------------------------
20 To release a closed-source product which uses JUCE, commercial licenses are
21 available: visit www.rawmaterialsoftware.com/juce for more information.
23 ==============================================================================
26 #include "../jucedemo_headers.h"
29 //==============================================================================
30 /**
31 This class shows how to implement a TableListBoxModel to show in a TableListBox.
33 class TableDemoComponent : public Component,
34 public TableListBoxModel
36 public:
37 //==============================================================================
38 TableDemoComponent()
39 : font (14.0f)
41 // Load some data from an embedded XML file..
42 loadData();
44 // Create our table component and add it to this component..
45 addAndMakeVisible (&table);
46 table.setModel (this);
48 // give it a border
49 table.setColour (ListBox::outlineColourId, Colours::grey);
50 table.setOutlineThickness (1);
52 // Add some columns to the table header, based on the column list in our database..
53 forEachXmlChildElement (*columnList, columnXml)
55 table.getHeader().addColumn (columnXml->getStringAttribute ("name"),
56 columnXml->getIntAttribute ("columnId"),
57 columnXml->getIntAttribute ("width"),
58 50, 400,
59 TableHeaderComponent::defaultFlags);
62 // we could now change some initial settings..
63 table.getHeader().setSortColumnId (1, true); // sort forwards by the ID column
64 table.getHeader().setColumnVisible (7, false); // hide the "length" column until the user shows it
66 // un-comment this line to have a go of stretch-to-fit mode
67 // table.getHeader().setStretchToFitActive (true);
69 table.setMultipleSelectionEnabled (true);
72 ~TableDemoComponent()
76 //==============================================================================
77 // This is overloaded from TableListBoxModel, and must return the total number of rows in our table
78 int getNumRows()
80 return numRows;
83 // This is overloaded from TableListBoxModel, and should fill in the background of the whole row
84 void paintRowBackground (Graphics& g, int /*rowNumber*/, int /*width*/, int /*height*/, bool rowIsSelected)
86 if (rowIsSelected)
87 g.fillAll (Colours::lightblue);
90 // This is overloaded from TableListBoxModel, and must paint any cells that aren't using custom
91 // components.
92 void paintCell (Graphics& g,
93 int rowNumber,
94 int columnId,
95 int width, int height,
96 bool /*rowIsSelected*/)
98 g.setColour (Colours::black);
99 g.setFont (font);
101 const XmlElement* rowElement = dataList->getChildElement (rowNumber);
103 if (rowElement != 0)
105 const String text (rowElement->getStringAttribute (getAttributeNameForColumnId (columnId)));
107 g.drawText (text, 2, 0, width - 4, height, Justification::centredLeft, true);
110 g.setColour (Colours::black.withAlpha (0.2f));
111 g.fillRect (width - 1, 0, 1, height);
114 // This is overloaded from TableListBoxModel, and tells us that the user has clicked a table header
115 // to change the sort order.
116 void sortOrderChanged (int newSortColumnId, bool isForwards)
118 if (newSortColumnId != 0)
120 DemoDataSorter sorter (getAttributeNameForColumnId (newSortColumnId), isForwards);
121 dataList->sortChildElements (sorter);
123 table.updateContent();
127 // This is overloaded from TableListBoxModel, and must update any custom components that we're using
128 Component* refreshComponentForCell (int rowNumber, int columnId, bool /*isRowSelected*/,
129 Component* existingComponentToUpdate)
131 if (columnId == 5) // If it's the ratings column, we'll return our custom component..
133 RatingColumnCustomComponent* ratingsBox = (RatingColumnCustomComponent*) existingComponentToUpdate;
135 // If an existing component is being passed-in for updating, we'll re-use it, but
136 // if not, we'll have to create one.
137 if (ratingsBox == 0)
138 ratingsBox = new RatingColumnCustomComponent (*this);
140 ratingsBox->setRowAndColumn (rowNumber, columnId);
142 return ratingsBox;
144 else
146 // for any other column, just return 0, as we'll be painting these columns directly.
148 jassert (existingComponentToUpdate == 0);
149 return 0;
153 // This is overloaded from TableListBoxModel, and should choose the best width for the specified
154 // column.
155 int getColumnAutoSizeWidth (int columnId)
157 if (columnId == 5)
158 return 100; // (this is the ratings column, containing a custom component)
160 int widest = 32;
162 // find the widest bit of text in this column..
163 for (int i = getNumRows(); --i >= 0;)
165 const XmlElement* rowElement = dataList->getChildElement (i);
167 if (rowElement != 0)
169 const String text (rowElement->getStringAttribute (getAttributeNameForColumnId (columnId)));
171 widest = jmax (widest, font.getStringWidth (text));
175 return widest + 8;
178 // A couple of quick methods to set and get the "rating" value when the user
179 // changes the combo box
180 int getRating (const int rowNumber) const
182 return dataList->getChildElement (rowNumber)->getIntAttribute ("Rating");
185 void setRating (const int rowNumber, const int newRating)
187 dataList->getChildElement (rowNumber)->setAttribute ("Rating", newRating);
190 //==============================================================================
191 void resized()
193 // position our table with a gap around its edge
194 table.setBoundsInset (BorderSize<int> (8));
198 private:
199 TableListBox table; // the table component itself
200 Font font;
202 ScopedPointer<XmlElement> demoData; // This is the XML document loaded from the embedded file "demo table data.xml"
203 XmlElement* columnList; // A pointer to the sub-node of demoData that contains the list of columns
204 XmlElement* dataList; // A pointer to the sub-node of demoData that contains the list of data rows
205 int numRows; // The number of rows of data we've got
207 //==============================================================================
208 // This is a custom component containing a combo box, which we're going to put inside
209 // our table's "rating" column.
210 class RatingColumnCustomComponent : public Component,
211 public ComboBoxListener
213 public:
214 RatingColumnCustomComponent (TableDemoComponent& owner_)
215 : owner (owner_)
217 // just put a combo box inside this component
218 addAndMakeVisible (&comboBox);
219 comboBox.addItem ("fab", 1);
220 comboBox.addItem ("groovy", 2);
221 comboBox.addItem ("hep", 3);
222 comboBox.addItem ("neat", 4);
223 comboBox.addItem ("wild", 5);
224 comboBox.addItem ("swingin", 6);
225 comboBox.addItem ("mad for it", 7);
227 // when the combo is changed, we'll get a callback.
228 comboBox.addListener (this);
229 comboBox.setWantsKeyboardFocus (false);
232 ~RatingColumnCustomComponent()
236 void resized()
238 comboBox.setBoundsInset (BorderSize<int> (2));
241 // Our demo code will call this when we may need to update our contents
242 void setRowAndColumn (const int newRow, const int newColumn)
244 row = newRow;
245 columnId = newColumn;
246 comboBox.setSelectedId (owner.getRating (row), true);
249 void comboBoxChanged (ComboBox* /*comboBoxThatHasChanged*/)
251 owner.setRating (row, comboBox.getSelectedId());
254 private:
255 TableDemoComponent& owner;
256 ComboBox comboBox;
257 int row, columnId;
260 //==============================================================================
261 // A comparator used to sort our data when the user clicks a column header
262 class DemoDataSorter
264 public:
265 DemoDataSorter (const String attributeToSort_, bool forwards)
266 : attributeToSort (attributeToSort_),
267 direction (forwards ? 1 : -1)
271 int compareElements (XmlElement* first, XmlElement* second) const
273 int result = first->getStringAttribute (attributeToSort)
274 .compareLexicographically (second->getStringAttribute (attributeToSort));
276 if (result == 0)
277 result = first->getStringAttribute ("ID")
278 .compareLexicographically (second->getStringAttribute ("ID"));
280 return direction * result;
283 private:
284 String attributeToSort;
285 int direction;
288 //==============================================================================
289 // this loads the embedded database XML file into memory
290 void loadData()
292 XmlDocument dataDoc (String ((const char*) BinaryData::demo_table_data_xml));
293 demoData = dataDoc.getDocumentElement();
295 dataList = demoData->getChildByName ("DATA");
296 columnList = demoData->getChildByName ("COLUMNS");
298 numRows = dataList->getNumChildElements();
301 // (a utility method to search our XML for the attribute that matches a column ID)
302 const String getAttributeNameForColumnId (const int columnId) const
304 forEachXmlChildElement (*columnList, columnXml)
306 if (columnXml->getIntAttribute ("columnId") == columnId)
307 return columnXml->getStringAttribute ("name");
310 return String::empty;
313 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TableDemoComponent);
317 //==============================================================================
318 Component* createTableDemo()
320 return new TableDemoComponent();