| 
							- /*
 -   ==============================================================================
 - 
 -    This file is part of the JUCE library - "Jules' Utility Class Extensions"
 -    Copyright 2004-9 by Raw Material Software Ltd.
 - 
 -   ------------------------------------------------------------------------------
 - 
 -    JUCE can be redistributed and/or modified under the terms of the GNU General
 -    Public License (Version 2), as published by the Free Software Foundation.
 -    A copy of the license is included in the JUCE distribution, or can be found
 -    online at www.gnu.org/licenses.
 - 
 -    JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
 -    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 -    A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
 - 
 -   ------------------------------------------------------------------------------
 - 
 -    To release a closed-source product which uses JUCE, commercial licenses are
 -    available: visit www.rawmaterialsoftware.com/juce for more information.
 - 
 -   ==============================================================================
 - */
 - 
 - #include "../jucedemo_headers.h"
 - 
 - 
 - //==============================================================================
 - /**
 -     This class shows how to implement a TableListBoxModel to show in a TableListBox.
 - */
 - class TableDemoComponent    : public Component,
 -                               public TableListBoxModel
 - {
 - public:
 -     //==============================================================================
 -     TableDemoComponent()
 -         : font (14.0f)
 -     {
 -         // Load some data from an embedded XML file..
 -         loadData();
 - 
 -         // Create our table component and add it to this component..
 -         addAndMakeVisible (table = new TableListBox ("demo table", this));
 - 
 -         // give it a border
 -         table->setColour (ListBox::outlineColourId, Colours::grey);
 -         table->setOutlineThickness (1);
 - 
 -         // Add some columns to the table header, based on the column list in our database..
 -         forEachXmlChildElement (*columnList, columnXml)
 -         {
 -             table->getHeader()->addColumn (columnXml->getStringAttribute ("name"),
 -                                            columnXml->getIntAttribute ("columnId"),
 -                                            columnXml->getIntAttribute ("width"),
 -                                            50, 400,
 -                                            TableHeaderComponent::defaultFlags);
 -         }
 - 
 -         // we could now change some initial settings..
 -         table->getHeader()->setSortColumnId (1, true); // sort forwards by the ID column
 -         table->getHeader()->setColumnVisible (7, false); // hide the "length" column until the user shows it
 - 
 -         // un-comment this line to have a go of stretch-to-fit mode
 -         // table->getHeader()->setStretchToFitActive (true);
 - 
 -         table->setMultipleSelectionEnabled (true);
 -     }
 - 
 -     ~TableDemoComponent()
 -     {
 -     }
 - 
 -     //==============================================================================
 -     // This is overloaded from TableListBoxModel, and must return the total number of rows in our table
 -     int getNumRows()
 -     {
 -         return numRows;
 -     }
 - 
 -     // This is overloaded from TableListBoxModel, and should fill in the background of the whole row
 -     void paintRowBackground (Graphics& g, int /*rowNumber*/, int /*width*/, int /*height*/, bool rowIsSelected)
 -     {
 -         if (rowIsSelected)
 -             g.fillAll (Colours::lightblue);
 -     }
 - 
 -     // This is overloaded from TableListBoxModel, and must paint any cells that aren't using custom
 -     // components.
 -     void paintCell (Graphics& g,
 -                     int rowNumber,
 -                     int columnId,
 -                     int width, int height,
 -                     bool /*rowIsSelected*/)
 -     {
 -         g.setColour (Colours::black);
 -         g.setFont (font);
 - 
 -         const XmlElement* rowElement = dataList->getChildElement (rowNumber);
 - 
 -         if (rowElement != 0)
 -         {
 -             const String text (rowElement->getStringAttribute (getAttributeNameForColumnId (columnId)));
 - 
 -             g.drawText (text, 2, 0, width - 4, height, Justification::centredLeft, true);
 -         }
 - 
 -         g.setColour (Colours::black.withAlpha (0.2f));
 -         g.fillRect (width - 1, 0, 1, height);
 -     }
 - 
 -     // This is overloaded from TableListBoxModel, and tells us that the user has clicked a table header
 -     // to change the sort order.
 -     void sortOrderChanged (int newSortColumnId, bool isForwards)
 -     {
 -         if (newSortColumnId != 0)
 -         {
 -             DemoDataSorter sorter (getAttributeNameForColumnId (newSortColumnId), isForwards);
 -             dataList->sortChildElements (sorter);
 - 
 -             table->updateContent();
 -         }
 -     }
 - 
 -     // This is overloaded from TableListBoxModel, and must update any custom components that we're using
 -     Component* refreshComponentForCell (int rowNumber, int columnId, bool /*isRowSelected*/,
 -                                         Component* existingComponentToUpdate)
 -     {
 -         if (columnId == 5) // If it's the ratings column, we'll return our custom component..
 -         {
 -             RatingColumnCustomComponent* ratingsBox = (RatingColumnCustomComponent*) existingComponentToUpdate;
 - 
 -             // If an existing component is being passed-in for updating, we'll re-use it, but
 -             // if not, we'll have to create one.
 -             if (ratingsBox == 0)
 -                 ratingsBox = new RatingColumnCustomComponent (*this);
 - 
 -             ratingsBox->setRowAndColumn (rowNumber, columnId);
 - 
 -             return ratingsBox;
 -         }
 -         else
 -         {
 -             // for any other column, just return 0, as we'll be painting these columns directly.
 - 
 -             jassert (existingComponentToUpdate == 0);
 -             return 0;
 -         }
 -     }
 - 
 -     // This is overloaded from TableListBoxModel, and should choose the best width for the specified
 -     // column.
 -     int getColumnAutoSizeWidth (int columnId)
 -     {
 -         if (columnId == 5)
 -             return 100; // (this is the ratings column, containing a custom component)
 - 
 -         int widest = 32;
 - 
 -         // find the widest bit of text in this column..
 -         for (int i = getNumRows(); --i >= 0;)
 -         {
 -             const XmlElement* rowElement = dataList->getChildElement (i);
 - 
 -             if (rowElement != 0)
 -             {
 -                 const String text (rowElement->getStringAttribute (getAttributeNameForColumnId (columnId)));
 - 
 -                 widest = jmax (widest, font.getStringWidth (text));
 -             }
 -         }
 - 
 -         return widest + 8;
 -     }
 - 
 -     // A couple of quick methods to set and get the "rating" value when the user
 -     // changes the combo box
 -     int getRating (const int rowNumber) const
 -     {
 -         return dataList->getChildElement (rowNumber)->getIntAttribute ("Rating");
 -     }
 - 
 -     void setRating (const int rowNumber, const int newRating)
 -     {
 -         dataList->getChildElement (rowNumber)->setAttribute ("Rating", newRating);
 -     }
 - 
 -     //==============================================================================
 -     void resized()
 -     {
 -         // position our table with a gap around its edge
 -         table->setBoundsInset (BorderSize (8));
 -     }
 - 
 -     //==============================================================================
 -     juce_UseDebuggingNewOperator
 - 
 - private:
 -     ScopedPointer<TableListBox> table;    // the table component itself
 -     Font font;
 - 
 -     ScopedPointer<XmlElement> demoData;   // This is the XML document loaded from the embedded file "demo table data.xml"
 -     XmlElement* columnList; // A pointer to the sub-node of demoData that contains the list of columns
 -     XmlElement* dataList;   // A pointer to the sub-node of demoData that contains the list of data rows
 -     int numRows;            // The number of rows of data we've got
 - 
 -     //==============================================================================
 -     // This is a custom component containing a combo box, which we're going to put inside
 -     // our table's "rating" column.
 -     class RatingColumnCustomComponent    : public Component,
 -                                            public ComboBoxListener
 -     {
 -     public:
 -         RatingColumnCustomComponent (TableDemoComponent& owner_)
 -             : owner (owner_)
 -         {
 -             // just put a combo box inside this component
 -             addAndMakeVisible (&comboBox);
 -             comboBox.addItem ("fab", 1);
 -             comboBox.addItem ("groovy", 2);
 -             comboBox.addItem ("hep", 3);
 -             comboBox.addItem ("neat", 4);
 -             comboBox.addItem ("wild", 5);
 -             comboBox.addItem ("swingin", 6);
 -             comboBox.addItem ("mad for it", 7);
 - 
 -             // when the combo is changed, we'll get a callback.
 -             comboBox.addListener (this);
 -             comboBox.setWantsKeyboardFocus (false);
 -         }
 - 
 -         ~RatingColumnCustomComponent()
 -         {
 -         }
 - 
 -         void resized()
 -         {
 -             comboBox.setBoundsInset (BorderSize (2));
 -         }
 - 
 -         // Our demo code will call this when we may need to update our contents
 -         void setRowAndColumn (const int newRow, const int newColumn)
 -         {
 -             row = newRow;
 -             columnId = newColumn;
 -             comboBox.setSelectedId (owner.getRating (row), true);
 -         }
 - 
 -         void comboBoxChanged (ComboBox* /*comboBoxThatHasChanged*/)
 -         {
 -             owner.setRating (row, comboBox.getSelectedId());
 -         }
 - 
 -     private:
 -         TableDemoComponent& owner;
 -         ComboBox comboBox;
 -         int row, columnId;
 -     };
 - 
 -     //==============================================================================
 -     // A comparator used to sort our data when the user clicks a column header
 -     class DemoDataSorter
 -     {
 -     public:
 -         DemoDataSorter (const String attributeToSort_, bool forwards)
 -             : attributeToSort (attributeToSort_),
 -               direction (forwards ? 1 : -1)
 -         {
 -         }
 - 
 -         int compareElements (XmlElement* first, XmlElement* second) const
 -         {
 -             int result = first->getStringAttribute (attributeToSort)
 -                            .compareLexicographically (second->getStringAttribute (attributeToSort));
 - 
 -             if (result == 0)
 -                 result = first->getStringAttribute ("ID")
 -                            .compareLexicographically (second->getStringAttribute ("ID"));
 - 
 -             return direction * result;
 -         }
 - 
 -     private:
 -         String attributeToSort;
 -         int direction;
 -     };
 - 
 -     //==============================================================================
 -     // this loads the embedded database XML file into memory
 -     void loadData()
 -     {
 -         XmlDocument dataDoc (String ((const char*) BinaryData::demo_table_data_xml));
 -         demoData = dataDoc.getDocumentElement();
 - 
 -         dataList = demoData->getChildByName ("DATA");
 -         columnList = demoData->getChildByName ("COLUMNS");
 - 
 -         numRows = dataList->getNumChildElements();
 -     }
 - 
 -     // (a utility method to search our XML for the attribute that matches a column ID)
 -     const String getAttributeNameForColumnId (const int columnId) const
 -     {
 -         forEachXmlChildElement (*columnList, columnXml)
 -         {
 -             if (columnXml->getIntAttribute ("columnId") == columnId)
 -                 return columnXml->getStringAttribute ("name");
 -         }
 - 
 -         return String::empty;
 -     }
 - };
 - 
 - 
 - //==============================================================================
 - Component* createTableDemo()
 - {
 -     return new TableDemoComponent();
 - }
 
 
  |