-*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- ***** BEGIN LICENSE BLOCK ***** Version: MPL 1.1/GPL 2.0/LGPL 2.1 The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. The Original Code is mozilla.org code. The Initial Developer of the Original Code is Netscape Communications Corp. Portions created by the Initial Developer are Copyright (C) 1998 the Initial Developer. All Rights Reserved. Contributor(s): Alternatively, the contents of this file may be used under the terms of either the GNU General Public License Version 2 or later (the "GPL"), or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), in which case the provisions of the GPL or the LGPL are applicable instead of those above. If you wish to allow use of your version of this file only under the terms of either the GPL or the LGPL, and not to allow others to use your version of this file under the terms of the MPL, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the GPL or the LGPL. If you do not delete the provisions above, a recipient may use your version of this file under the terms of any one of the MPL, the GPL or the LGPL. ***** END LICENSE BLOCK ***** This document describes the following classes: LTableHeader LTableViewHeader LTableRowSelector LFlexTableGeometry There is also a description of how they can all be used together at the end. ---- LTableHeader ---- This subclass of LView implements a table header with resizable and movable columns. Column headers are individual panes within the view. These panes are always positioned appropriately to be in line with their columns. The panes are resized horizontally to touch the left and right edges of their columns. The class also supports special appearance for the sorted column, chosen by clicking on a column header. The header does NOT scroll. Columns are always resized proportionally, though columns can be marked as fixed width. The header's image size always matches its frame. ¥ Creation The view has custom PPob and also requires a 'Cols' resource. The data in the PPob specifies the following information: header flags: only 1, kHeaderCanHideColumns 2 bevel trait resource ids: sorted column header, then unsorted reverse modifiers: an event record modifier mask that denotes a reverse-sort selection 'Cols' resource ID: id of 'Cols' resource, with column initialization data, REQUIRED The 'Cols' resource is used to initialize the size and positioning of the header's columns. The header of the resource (SavedHeaderState) is defined in LTableHeader.h. Following the header is an array of ColumnData (also in LTableHeader.h) records, 1 for each column. The header of the resource specifies: # of columns (1-based) index of rightmost visible column (1-based) index of sorted column (1-based, 0 if none) Each ColumnData record specifies: Pane ID of column header, 0 if none Column Width In pixels if fixed size, in % of non-fixed space if resizable Column Position Meaningless in saved state, ignore it. ColumnFlags kColumnDoesNotSort and/or kColumnDoesNotResize ¥ Header and Column Size If a column is fixed-width, it will always have that width. Widths of resizable columns are maintained as percentages of the non-fixed space in the header. When a column is resized, all columns to its right resize proportionally. ¥ Hiding/Showing Columns If the kHeaderCanHideColumns flag is set in the header flags, the view will have a widget at the right edge for hiding and showing columns. ¥ Dragging/Resizing Columns To change the rgn that gets dragged when resizing or moving a column, override ComputeResizeDragRect or ComputeColumnDragRect respectively. ¥ Sorting When the sorted column changes, LTableHeader broadcasts a msg_SortedColumnChanged message, with TableHeaderSortChange parameter. The method GetSortedColumn returns both the index and the header pane ID of the sorted column. ---- LTableViewHeader ---- LTableViewHeader is a subclass of LTableHeader that coordinates changes in the header with an LTableView. When columns are hidden or shown in the header, this class removes/adds columns from/to the table view. When the image size of the header changes, the image size of the table is adjusted as well. When columns are redrawn in the header, they are invalidated for refresh in the table view. This class also overrides ComputeResizeDragRect and ComputeColumnDragRect to create more useful regions when dragging and resizing columns. ---- LTableRowSelector ---- This subclass of LTableSelector selects entire rows. Individual cells cannot be selected. It allows multiple selection and supports that standard shift and command key selection extension semantics. ---- LFlexTableGeometry ---- This subclass of LTableGeometry works in concert with an LTableHeader to compute the position of cells in a table. All rows are of uniform height, and column positions and widths are determined by querying the associated LTableHeader view. ---- Using them together ---- The Dogbert mail window will use these classes all together. A subclass of LTableView (CMessageTableView) sets its geometry to LFlexTableGeometry, and its selector to LTableRowSelector. When drawing a cell, CMessageTableView queries its associate LTableViewHeader to find the pane ID of the column's header. The pane ID's denote which element of the row is drawn in that cell. For instance, a column with header 'subj' contains the message subject. This indirection allows the column order to be changed.