ElementDataGridRow.h

00001 /*
00002  * This source file is part of libRocket, the HTML/CSS Interface Middleware
00003  *
00004  * For the latest information, see http://www.librocket.com
00005  *
00006  * Copyright (c) 2008-2010 CodePoint Ltd, Shift Technology Ltd
00007  *
00008  * Permission is hereby granted, free of charge, to any person obtaining a copy
00009  * of this software and associated documentation files (the "Software"), to deal
00010  * in the Software without restriction, including without limitation the rights
00011  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00012  * copies of the Software, and to permit persons to whom the Software is
00013  * furnished to do so, subject to the following conditions:
00014  *
00015  * The above copyright notice and this permission notice shall be included in
00016  * all copies or substantial portions of the Software.
00017  * 
00018  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00019  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00020  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00021  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00022  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00023  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00024  * THE SOFTWARE.
00025  *
00026  */
00027 
00028 #ifndef ROCKETCONTROLSELEMENTDATAGRIDROW_H
00029 #define ROCKETCONTROLSELEMENTDATAGRIDROW_H
00030 
00031 #include <Rocket/Controls/Header.h>
00032 #include <Rocket/Controls/DataSourceListener.h>
00033 #include <Rocket/Controls/DataQuery.h>
00034 #include <Rocket/Core/Element.h>
00035 #include <queue>
00036 
00037 namespace Rocket {
00038 namespace Controls {
00039 
00040 class ElementDataGrid;
00041 
00048 class ROCKETCONTROLS_API ElementDataGridRow : public Core::Element, public DataSourceListener
00049 {
00050 friend class ElementDataGrid;
00051 
00052 public:
00053         ElementDataGridRow(const Rocket::Core::String& tag);
00054         virtual ~ElementDataGridRow();
00055 
00056         void Initialise(ElementDataGrid* parent_grid, ElementDataGridRow* parent_row = NULL, int child_index = -1, ElementDataGridRow* header_row = NULL, int depth = -1);
00057         void SetChildIndex(int child_index);
00058         int GetDepth();
00059 
00060         void SetDataSource(const Rocket::Core::String& data_source_name);
00061 
00064         bool UpdateChildren();
00065 
00067         int GetNumLoadedChildren();
00068 
00069         // Removes all the child cells and fetches them again from the data
00070         // source.
00071         void RefreshRows();
00072 
00074         bool IsRowExpanded();
00076         void ExpandRow();
00078         void CollapseRow();
00080         void ToggleRow();
00081 
00083         int GetParentRelativeIndex();
00085         int GetTableRelativeIndex();
00087         ElementDataGridRow* GetParentRow();
00089         ElementDataGrid* GetParentGrid();
00090 
00091 protected:
00092         virtual void OnDataSourceDestroy(DataSource* data_source);
00093         virtual void OnRowAdd(DataSource* data_source, const Rocket::Core::String& table, int first_row_added, int num_rows_added);
00094         virtual void OnRowRemove(DataSource* data_source, const Rocket::Core::String& table, int first_row_removed, int num_rows_removed);
00095         virtual void OnRowChange(DataSource* data_source, const Rocket::Core::String& table, int first_row_changed, int num_rows_changed);
00096         virtual void OnRowChange(DataSource* data_source, const Rocket::Core::String& table);
00097 
00098 private:
00099         typedef std::queue< ElementDataGridRow* > RowQueue;
00100         typedef std::vector< ElementDataGridRow* > RowList;
00101 
00102         // Called when a row change (addition or removal) occurs in one of our
00103         // children. Causes the table row index to be dirtied on all following
00104         // children.
00105         void ChildChanged(int child_index);
00106         // Checks if any columns are dependent on the number of children
00107         // present, and refreshes them from the data source if they are.
00108         void RefreshChildDependentCells();
00109 
00110         // Forces the row to recalculate its relative table index the next time
00111         // it is requested.
00112         void DirtyTableRelativeIndex();
00113         // Works out what the table relative index is for a given child.
00114         int GetChildTableRelativeIndex(int child_index);
00115 
00116         // Adds children underneath this row, and fetches their contents (and
00117         // possible children) from the row's data source. If first_row is left
00118         // as the default -1, the rows are appended at the end of the list.
00119         void AddChildren(int first_row_added = -1, int num_rows_added = 1);
00120         // Removes this rows children, and their children, etc, from the table.
00121         // If the num_rows_removed parameter is left as the -1 default, it'll
00122         // default to the rest of the children after the first row.
00123         void RemoveChildren(int first_row_removed = 0, int num_rows_removed = -1);
00124         // Returns the number of rows under this row (children, grandchildren, etc)
00125         int GetNumDescendants();
00126 
00127         // Adds or refreshes the cell contents, and undirties the row's cells.
00128         void Load(const Rocket::Controls::DataQuery& row_information);
00129         // Finds all children that have cell information missing (either though being
00130         // refreshed or not being loaded yet) and reloads them.
00131         void LoadChildren(float time_slice);
00132         // Loads a specific set of children. Called by the above function.
00133         void LoadChildren(int first_row_to_load, int num_rows_to_load, Rocket::Core::Time time_slice);
00134 
00135         // If the cells need reloading, this takes care of it. If any children
00136         // need updating, they are added to the queue.
00137         void UpdateCellsAndChildren(RowQueue& dirty_rows);
00138 
00139         // Sets the dirty_cells flag on this row, and lets our ancestors know.
00140         void DirtyCells();
00141         // Sets the dirty children flag on this row and the row's ancestors.
00142         void DirtyRow();
00143         // This row has one or more cells that need loading.
00144         bool dirty_cells;
00145         // This row has one or more children that have either dirty flag set.
00146         bool dirty_children;
00147 
00148         // Shows this row, and, if this was was expanded before it was hidden, its children as well.
00149         void Show();
00150         // Hides this row and all descendants.
00151         void Hide();
00152         bool row_expanded;
00153 
00154         int table_relative_index;
00155         bool table_relative_index_dirty;
00156 
00157         ElementDataGrid* parent_grid;
00158 
00159         ElementDataGridRow* parent_row;
00160         int child_index;
00161         int depth;
00162 
00163         RowList children;
00164 
00165         // The data source and table that the children are fetched from.
00166         DataSource* data_source;
00167         Rocket::Core::String data_table;
00168 };
00169 
00170 }
00171 }
00172 
00173 #endif