DESCRIPTION

The module provides classes for several abstraction layers
of grid representation. The classes hierarchy is as follows:

AbstractGridViewer
AbstractGrid
GridViewer
Grid

The root class, "Prima::AbstractGridViewer", provides common
interface, while by itself it is not directly usable.
The main differences between classes
are centered around the way the cell data are stored. The simplest
organization of a text-only cell, provided by "Prima::Grid",
stores data as a two-dimensional array of text scalars. More elaborated storage
and representation types are not realized, and the programmer is urged
to use the more abstract classes to derive own mechanisms.
To organize an item storage, different from "Prima::Grid", it is
usually enough to overload either the "Stringify", "Measure",
and "DrawCell" events, or their method counterparts: "get_cell_text",
"columnWidth", "rowHeight", and "draw_items".

The grid widget is designed to contain cells of variable extents, of two types, normal and
indent. The indent rows and columns are displayed in grid margins, and their
cell are drawn with distinguished colors.
An example use for a bottom indent row is a sum row in a spreadsheet application;
the top indent row can be used for displaying columns' headers. The normal cells
can be selected by the user, scrolled, and selected. The cell selection
can only contain rectangular areas, and therefore is operated with
two integer pairs with the beginning and the end of the selection.

The widget operates in two visual scrolling modes; when the space allows,
the scrollbars affect the leftmost and the topmost cell. When the widget is
not large enough to accommodate at least one cell and all indent cells, the layout
is scrolled pixel-wise. These modes are named 'cell' and 'pixel', after the scrolling
units.

The widget allows the interactive changing of cell widths and heights by dragging
the grid lines between the cells.

Prima::AbstractGridViewer

"Prima::AbstractGridViewer", the base for all grid widgets in the module,
provides interface to generic grid browsing functionality,
plus functionality for text-oriented grids. The class is not usable directly.

"Prima::AbstractGridViewer" is a descendant of "Prima::GroupScroller",
and some properties are not described here. See ``Prima::GroupScroller'' in Prima::IntUtils.

Properties

allowChangeCellHeight BOOLEAN

If 1, the user is allowed to change vertical extents of cells by dragging the
horizontal grid lines. Prerequisites to the options are:
the lines must be set visible via "drawHGrid" property, "constantCellHeight"
property set to 0, and the changes to the vertical extents can be recorded
via "SetExtent" notification.

Default value: 0

allowChangeCellWidth BOOLEAN

If 1, the user is allowed to change horizontal extents of cells by dragging the
horizontal grid lines. Prerequisites to the options are:
the lines must be set visible via "drawVGrid" property, "constantCellWidth"
property set to 0, and the changes to the horizontal extents can be recorded
via "SetExtent" notification.

Default value: 0

cellIndents X1, Y1, X2, Y2

Marks the marginal rows and columns as 'indent' cells. The indent cells
are drawn with another color pair ( see indentCellColor, indentCellBackColor ),
cannot be selected and scrolled. X1 and X2 correspond to amount of indent columns,
and Y1 and Y2, - to the indent rows.

"leftCell" and "topCell" do not count the indent cells as the leftmost or topmost
visible cell; in other words, X1 and Y1 are minimal values for "leftCell" and "topCell"
properties.

Default value: 0,0,0,0

clipCells INTEGER

A three-state integer property, that governs the way clipping is applied
when cells are drawn. Depending on kind of graphic in cells, the clipping
may be necessary, or unnecessary.

If the value is 1, the clipping is applied for every column drawn, as the
default drawing routines proceed column-wise. If the value is 2, the clipping
as applied for every cell. This setting reduces the drawing speed significantly.
If the value is 0, no clipping is applied.

This property is destined for custom-drawn grid widgets, when it is the
developer's task to decide what kind of clipping suits better. Text grid
widgets, "Prima::AbstractGrid" and "Prima::Grid", are safe with "clipCells"
set to 1.

Default value: 1

columns INTEGER

Sets number of columns, including the indent columns. The number of
columns must be larger than the number of indent columns.

Default value: 0.

columnWidth COLUMN [ WIDTH ]

A run-time property, selects width of a column. To acquire or set
the width, "Measure" and "SetExtent" notifications can be invoked.
Result of "Measure" may be cached internally using "cache_geometry_requests"
method.

The width does not include widths of eventual vertical grid lines.

If "constantCellWidth" is defined, the property is used as its alias.

constantCellHeight HEIGHT

If defined, all rows have equal height, HEIGHT pixels. If "undef",
rows have different heights.

Default value: undef

constantCellWidth WIDTH

If defined, all rows have equal width, WIDTH pixels. If "undef",
columns have different widths.

The property selects the breadth of area around the grid lines, that
reacts on grid-dragging mouse events. The minimal value, 0, marks
only grid lines as the drag area, but makes the dragging operation inconvenient
for the user.
Larger values make the dragging more convenient, but increase the chance that
the user will not be able to select too narrow cells with the mouse.

Default value: 3

indentCellBackColor COLOR

Selects the background color of indent cells.

Default value: "cl::Gray" .

indentCellColor

Selects the foreground color of indent cells.

Default value: "cl::Gray" .

leftCell INTEGER

Selects index of the leftmost visible normal cell.

multiSelect BOOLEAN

If 1, the normal cells in an arbitrary rectangular area can be marked
as selected ( see selection ). If 0, only one cell at a time
can be selected.

Default value: 0

rows INTEGER

Sets number of rows, including the indent rows. The number of
rows must be larger than the number of indent rows.

Default value: 0.

topCell

Selects index of the topmost visible normal cell.

rowHeight INTEGER

A run-time property, selects height of a row. To acquire or set
the height, "Measure" and "SetExtent" notifications can be invoked.
Result of "Measure" may be cached internally using "cache_geometry_requests"
method.

The height does not include widths of eventual horizontal grid lines.

If "constantCellHeight" is defined, the property is used as its alias.

selection X1, Y1, X2, Y2

If "multiSelect" is 1, governs the extents of a rectangular area, that
contains selected cells. If no such area is present, selection
is (-1,-1,-1,-1), and "has_selection" returns 0 .

If "multiSelect" is 0, in get-mode returns the focused cell, and discards
the parameters in the set-mode.

Methods

cache_geometry_requests CACHE

If CACHE is 1, starts caching results of "Measure" notification, thus lighting the
subsequent "columnWidth" and "rowHeight" calls; if CACHE is 0, flushes the cache.

If a significant geometry change was during the caching, the cache is not updated, so it is the
caller's responsibility to flush the cache.

deselect_all

Nullifies the selection, if "multiSelect" is 1.

draw_cells CANVAS, COLUMNS, ROWS, AREA

A bulk draw routine, called from "onPaint" to draw cells.
AREA is an array of four integers with inclusive-inclusive
coordinates of the widget inferior without borders and scrollbars
( result of get_active_area(2) call; see ``get_active_area'' in Prima::IntUtils ).

COLUMNS and ROWS are structures that reflect the columns and rows of the cells
to be drawn. Each item in these corresponds to a column or row, and is an
array with the following layout:

The coordinates are in inclusive-inclusive coordinate system, and
do not include eventual grid space, nor gaps between indent and
normal cells. By default, internal arrays "{colsDraw}" and
"{rowsDraw}" are passed as COLUMNS and ROWS parameters.

In "Prima::AbstractGrid" and "Prima::Grid" classes <draw_cells> is overloaded to
transfer the call to "std_draw_text_cells", the text-oriented optimized routine.

A bulk routine for drawing text cells, called from "std_draw_text_cells" .

SCREEN_RECTANGLES and CELL_RECTANGLES are arrays, where each item is a rectangle
with exterior of a cell. SCREEN_RECTANGLES contains rectangles that cover the
cell visible area; CELL_RECTANGLES contains rectangles that span the cell extents
disregarding its eventual partial visibility. For example, a 100-pixel cell with
only its left half visible, would contain corresponding arrays [150,150,200,250]
in SCREEN_RECTANGLES, and [150,150,250,250] in CELL_RECTANGLES.

CELL_INDECES contains arrays of the cell coordinates; each array item is an array of
integer pair where item 0 is column, and item 1 is row of the cell.

FONT_HEIGHT is a current font height value, cached since "draw_text_cells" is
often used for text operations and may require vertical text justification.

get_cell_area [ WIDTH, HEIGHT ]

Returns screen area in inclusive-inclusive pixel coordinates, that is used
to display normal cells. The extensions are related to the current size of a widget,
however, can be overridden by specifying WIDTH and HEIGHT.

get_cell_text COLUMN, ROW

Returns text string assigned to cell in COLUMN and ROW.
Since the class does not assume the item storage organization,
the text is queried via "Stringify" notification.

get_range AXIS, INDEX

Returns a pair of integers, minimal and maximal breadth of INDEXth column
or row in pixels. If AXIS is 1, the rows are queried; if 0, the columns.

The method calls "GetRange" notification.

get_screen_cell_info COLUMN, ROW

Returns information about a cell in COLUMN and ROW, if it is currently visible.
The returned parameters are indexed by "gsci::XXX" constants,
and explained below:

gsci::COL_INDEX - visual column number where the cell displayed
gsci::ROW_INDEX - visual row number where the cell displayed
gsci::V_FULL - cell is fully visible
gsci::V_LEFT - inclusive-inclusive rectangle of the visible
gsci::V_BOTTOM part of the cell. These four indices are grouped
gsci::V_RIGHT under list constant, gsci::V_RECT.
gsci::V_TOP
gsci::LEFT - inclusive-inclusive rectangle of the cell, as if
gsci::BOTTOM it is fully visible. These four indices are grouped
gsci::RIGHT under list constant, gsci::RECT. If gsci::V_FULL
gsci::TOP is 1, these values are identical to these in gsci::V_RECT.

If the cell is not visible, returns empty array.

has_selection

Returns a boolean value, indicating whether the grid contains a selection (1) or not (0).

point2cell X, Y, [ OMIT_GRID = 0 ]

Return information about point X, Y in widget coordinates. The method
returns two integers, CX and CY, with cell coordinates, and
eventual HINTS hash, with more information about pixe localtion. If OMIT_GRID is set to 1
and the pixel belongs to a grid, the pixels is treated a part of adjacent cell.
The call syntax:

( $CX, $CY, %HINTS) = $self->point2cell( $X, $Y);

If the pixel lies within cell boundaries by either coordinate, CX and/or CY
are correspondingly set to cell column and/or row. When the pixel is outside
cell space, CX and/or CY are set to -1.

HINTS may contain the following values:

"x" and "y"

If 0, the coordinate lies within boundaries of a cell.

If -1, the coordinate is on the left/top to the cell body.

If +1, the coordinate is on the right/bottom to the cell body, but within
the widget.

If +2, the coordinate is on the right/bottom to the cell body, but outside
the widget.

"x_type" and "y_type"

Present when "x" or "y" values are 0.

If 0, the cell is a normal cell.

If -1, the cell is left/top indent cell.

If +1, the cell is right/bottom indent cell.

"x_grid" and "y_grid"

If 1, the point is over a grid line. This case can only happen when OMIT_GRID is 0.
If "allowChangeCellHeight" and/or "allowChangeCellWidth" are set, treats also
"gridGravity"-broad pixels strips on both sides of the line as the grid area.

Also values of "x_left"/"x_right" or "y_bottom"/"y_top" might be set.

"x_left"/"x_right" and "y_bottom"/"y_top"

Present together with "x_grid" or "y_grid". Select indices of
cells adjacent to the grid line.

"x_gap" and "y_gap"

If 1, the point is within a gap between the last normal cell and the first
right/bottom indent cell.

"normal"

If 1, the point lies within the boundaries of a normal cell.

"indent"

If 1, the point lies within the boundaries of an indent cell.

"grid"

If 1, the point is over a grid line.

"exterior"

If 1, the point is in inoperable area or outside the widget boundaries.

redraw_cell X, Y

Repaints cell with coordinates X and Y.

reset

Recalculates internal geometry variables.

select_all

Marks all cells as selected, if "multiSelect" is 1.

std_draw_text_cells CANVAS, COLUMNS, ROWS, AREA

An optimized bulk routine for text-oriented grid widgets. The optimization
is achieved under assumption that each cell is drawn with two colors only,
so the color switching can be reduced.

Events

Called when a cell with COLUMN and ROW coordinates is to be drawn on CANVAS.
SCREEN_RECT is a cell rectangle in widget coordinates,
where the item is to be drawn. CELL_RECT is same as SCREEN_RECT, but calculated
as if the cell is fully visible.

SELECTED and FOCUSED are boolean
flags, if the cell must be drawn correspondingly in selected and
focused states.

Prima::AbstractGrid

Exactly the same as its ascendant, "Prima::AbstractGridViewer",
except that it does not propagate "DrawItem" message,
assuming that the items must be drawn as text.

Prima::GridViewer

The class implements cells data and geometry storage mechanism, but leaves
the cell data format to the programmer. The cells are accessible via
"cells" property and several other helper routines.

The cell data are stored in an array, where each item corresponds to a row,
and contains array of scalars, where each corresponds to a column. All
data managing routines, that accept two-dimensional arrays, assume that
the columns arrays are of the same widths.

For example, "[[1,2,3]]]" is a valid one-row, three-column structure, and
"[[1,2],[2,3],[3,4]]" is a valid three-row, two-column structure.
The structure "[[1],[2,3],[3,4]]" is invalid, since its first row has
one column, while the others have two.

"Prima::GridViewer" is derived from "Prima::AbstractGridViewer".

Properties

allowChangeCellHeight

Default value: 1

allowChangeCellWidth

Default value: 1

cell COLUMN, ROW, [ DATA ]

Run-time property. Selects the data in cell with COLUMN and ROW coordinates.

cells [ ARRAY ]

The property accepts or returns all cells as a two-dimensional
rectangular array or scalars.