NAME:

Widget: XGrid


SYNOPSIS:

use Tk::XGrid( -initialrows=>value, -initialcols=>value );


DIRECTORY/FILE/INSTALLATION:

Just drop the file and the 3 xpm-images into the Tk directory (_perldir_/lib/site/Tk).


DESCRIPTION:

This widget is a little spreadsheet-like grid of texts.

It was developed for working as a embeded table in my text-processor project 'e:doc'. It offers a set of Labels that are organised in rows and column yousing the grid layout manager.

If you click on a cell, the Label is replaced by a Text widget for editing the cells content.

You can resize the columns and the rows by dragging the resize-grips with the mouse.

You can define multiple 'cell-styles' that can be applied to each cell. This way you can change properties like 'background', 'foreground', 'relief', 'font' etc.


DEFINITIONS:


Indexes:

The column- and row-indexes are integers between 1 and $widget->cols() or $widget->rows().


Cell styles:

If you do not define own styles, there will exist a style 'BASE' that is used for all cells.

If you want to change some settings of this style 'BASE', overwrite them using the method ``define_style'.

If you do define other styles too AND want a changed style 'BASE', redefine the style 'BASE' first.


STATUS:

Coding: 80% done

Documentation: up-to-date


ATTRIBUTES:

Do not set/read them directly, use the Get/Set methods instead.

[... Attribute list missing here ...]


METHODS:


Class Methods:


ClassInit($class, $parentwindow)

The initialisation of the class XGrid and calls ClassInit() of the SUPER class (Frame). Maybe I should create the images here and not in Populate().


Constructors:


Populate

$object = XGrid(%options);

This 'constructor' sets the options of the new object of the class XGrid.

The binding of events and the creation of the associated Baloonhelp is done here too.

The keys/values in %options:

(+) '-initialrows': The number of rows that should be there initially [Only evaluated at widget creation time, later changes are useless].

(+) '-initialcols': The number of cols that should be there initially [Only evaluated at widget creation time, later changes are useless].


Destructors:


DESTROY

The standard automatically called PERL destructor for objects.


Public data methods (=Get/Set methods):


_rows

$rows = $object->rows(); #gets the number of rows

$object->rows($rows); #sets the number of rows (Only for internal use, to add rows you can only use the methods 'add_row' and 'insert_row')


cols

$cols = $object->cols(); #gets the number of columns

$object->cols($cols); #sets the number of columns (Only for internal use, to add columns you can only use the methods 'add_col' and 'insert_col')


Other public methods:


add_row

@array_of_widgets = $object->add_row( [$row_height] );

This function adds a row at the bottom of the table.

The function returns an array of widget-references. The first element is a reference to the row-header (class ``Frame''), the other elements are the cell-widgets (class ``Text'') starting from the very left to the right.

Parameters:

(+) $row_height: The height of the new row


add_col

@array_of_widgets = $object->add_col( [$col_width] );

This function adds a column at the very right of the table.

The function returns an array of widget-references. The first element is a reference to the column-header (class ``Frame''), the other elements are the cell-widgets (class ``Text'') starting from the top to the bottom.

Parameters:

(+) $col_width: The width of the new column


activate_cell

$object->activate_cell($col, $row);

This method activates the specified cell and deactivates the former active cell (if there was an active cell before).

Parameters:

(+) $col: The column that contains the cell

(+) $row: The row that contains the cell


deactivate_cell

$object->deactivate_cell([$col, $row]);

This method deactivates the specified cell if its currently activated.

If both parameters are undef or omitted, the current active cell will be deactivated.

Parameters:

(+) $col: The column that contains the cell

(+) $row: The row that contains the cell


put

$object->put($col, $row, $text);

Put some text into a cell

Parameters:

(+) $col: The column that contains the cell

(+) $row: The row that contains the cell

(+) $text: The text to be displayed there


get

my $text = $object->put($col, $row);

Get the content (text) of a cell.

The function returns the text of the cell.

Parameters:

(+) $col: The column that contains the cell

(+) $row: The row that contains the cell


define_style

$object->define_style($style_name, $options);

Defines a new style for a cell.

Parameters:

(+) $style_name: The name for the style. If there is already a style with this name, it's overwritten.

(+) $options: A reference to a hash holding the options for that style.

Possible options are: '-background', '-foreground', '-relief', '-borderwidth', '-font', '-justify'[, '-anchor'(this is ignored in the active-mode)]

If you do not set an option explecitly, the default option from the default style 'BASE' will be taken.

If you want other default options, just overwrite 'BASE' as the first style.


set_cell_style

$object->set_cell_style($col, $row, $style_name);

This method changes the cell to the given style.

Parameters:

(+) $col: The column that contains the cell

(+) $row: The row that contains the cell

(+) $style_name: The name of the style


get_cell_style

my $style_name = $object->get_cell_style($col, $row);

This method retruns the style of the cell.

Parameters:

(+) $col: The column that contains the cell

(+) $row: The row that contains the cell


style_list

my @style_names = $object->style_list();

Returns an array of all defined styles in the table


delete_style

$object->delete_style($style_name);

Deletes the style from the list of available styles. All settings for that style are deleted as well. Cells containing that style are changed to style 'BASE'.


get_col_width

my $width = $object->get_column_width($col);

Returns the actual width of the column.

Parameters:

(+) $col: The column index


set_col_width

$object->set_column_width($col, $width);

Changes the column to this width (in pixels).

Parameters:

(+) $col: The column index

(+) $width: The width the column should have


get_row_height

my $height = $object->get_row_height($row);

Returns the actual height of the row.

Parameters:

(+) $row: The row index


set_row_height

$object->set_row_height($row, $height);

Changes the row to this height (in pixels).

Parameters:

(+) $row: The row index

(+) $height: The height the row should have


delete_col

$object->delete_col($col);

Deletes the column from the table. All columns right of this column are moved one step to the left.

Parameters:

(+) $col: The column index


delete_row

$object->delete_row($row);

Deletes the row from the table. All rows below this row are moved one step upward.

Parameters:

(+) $row: The row index


insert_col

$object->insert_col($col_index);

Inserts a new column at the specified column index. The column that is there before inserting and all columns below this row are moved one step to the right.

This method is slower than the method 'add_col' because of the managing and moving of the existing columnss below the index.

Parameters:

(+) $col_index: The column index


insert_row

$object->insert_row($row_index);

Inserts a new row at the specified row index. The row that is there before inserting and all rows below this row are moved one step downwards.

This method is slower than the method 'add_row' because of the managing and moving of the existing rows below the index.

Parameters:

(+) $row_index: The row index


clear_col

$object->clear_col($col, $do_clear_styles)

This method clears the content of the column. If $do_clear_styles is set to 1, the stales are cleared too.

Parameters:

(+) $col: The index of the column (starting with 1, column 0 is reserved for the headers)

(+) $do_clear_styles: If 1, styles are cleared too


clear_row

$object->clear_row($row, $do_clear_styles)

This method clears the content of the row. If $do_clear_styles is set to 1, the stales are cleared too.

Parameters:

(+) $row: The index of the row (starting with 1, row 0 is reserved for the headers)

(+) $do_clear_styles: If 1, styles are cleared too


set_col_style

$object->set_col_style($col, $style_name)

This method sets a style in a whole column.

Parameters:

(+) $col: The index of the column (starting with 1, column 0 is reserved for the headers)

(+) $style_name: The name of the style to be set


set_row_style

$object->set_row_style($row, $style_name)

This method sets a style in a whole row.

Parameters:

(+) $row: The index of the row (starting with 1, row 0 is reserved for the headers)

(+) $style_name: The name of the style to be set


set_table_style

$object->set_table_style($style_name)

This method sets a style in the whole table.

Parameters:

(+) $style_name: The name of the style to be set


Private methods:

DO NOT USE THESE METHODS !

This methods are described here for the use of widget developer, who plan to extend this class or want to derive from it.


_create_cell

$ref_widget = $object->_create_cell($col, $row [,$col_width, $row_height, $do_grid] );

This function creates a cell with an embeded Text widget in the table

The function returns a reference to that widget.

Parameters:

(+) $col: The index of the col (starting with 1, column 0 is reserved for the headers)

(+) $row: The index of the row (starting with 1, row 0 is reserved for the headers)

(+) $col_width: The width of the column (OPTIONAL, if undef, the width will be taken from the width of the column header)

(+) $row_height: The height of the row (OPTIONAL, if undef, the height will be taken from the width of the row header)

(+) $do_grid: 1 if the cell should be automatically gridded, 0 or undef if this should not happen automatically


_nav_key_released

$object->_nav_key_released();

This is the callback for cursor keys, 'tab', 'return'/'enter', 'home' and 'end' keys.


_col_heading_mouse_button1_pressed

$object->_col_heading_mouse_button1_pressed();

This is the callback for pressing the left mousebutton on a column-heading


_col_heading_mouse_button1_released

$object->_col_heading_mouse_button1_released();

This is the callback for releasing the left mousebutton on a column-heading


_col_heading_popup

This is the callback for presing the right mouse button on a column heading.

This displays the column-popup menu.


_row_heading_mouse_button1_pressed

$object->_row_heading_mouse_button1_pressed();

This is the callback for pressing the left mousebutton on a row-heading


_row_heading_mouse_button1_released

$object->_row_heading_mouse_button1_released();

This is the callback for releasing the left mousebutton on a row-heading


_row_heading_popup

This is the callback for presing the right mouse button on a row heading.

This displays the row-popup menu.


_cell_popup

This is the callback for presing the right mouse button on a cell

This displays the cell-popup menu.


_table_popup

This is the callback for presing the right mouse button on the 'table'-button (the one on the upper left).

This displays the table-popup menu.


_create_balloonhelp

$ref_baloon = _create_balloonhelp($ref_widget, $text, $status, $ref_statusbar);

Creates a balloonhelp and associates it with the widget

The functions returns a reference to the created balloon widget.

Parameters:

(+) $ref_widget: A reference to the widget

(+) $text: The text do be displayed in the balloon

(+) $state: The state of the balloon ('balloon', 'status', 'both', 'none'). Default is 'balloon'

(+) $ref_statusbar: A reference for the statusbar(Label) that should display the balloonhelp's text, if state is 'status' or 'both', else set it to undef


_activate_cell

$object->_activate_cell($col, $row);

Is called when a cell gets activated by user entry (Key or Mouse)

Parameters:

(+) $col: The column that contains the cell

(+) $row: The row that contains the cell


_deactivate_cell

$object->_deactivate_cell($col, $row);

Is called when a cell gets deactivated by user entry (Key or Mouse)

Parameters:

(+) $col: The column that contains the cell

(+) $row: The row that contains the cell


_test_cell

$object->_test_cell($col, $row, $calling_sub);

Test if the cell exists and print an error message if not.

The function returns 1 if the cell exists or undef if not.

Parameters:

(+) $col: The column that contains the cell

(+) $row: The row that contains the cell

(+) $calling_sub: The name of the function that called (For the error message)


_configure_text_entry

$object->_configure_text_entry($style_name);

Change the display style of the Text widget

Parameters:

(+) $style_name: The name of the style to be set


_configure_label_entry

$object->_configure_label_entry($col, $row, $style_name);

Change the display style of the cell. (The label there).

Parameters:

(+) $col: The column that contains the cell

(+) $row: The row that contains the cell

(+) $style_name: The name of the style to be set


_show_left_upper_cell

$object->_show_left_upper_cell();

Changes the display so that the cell in the very left column and in the first row is displayed.


_show_right_bottom_cell

$object->_show_right_bottom_cell();

Changes the display so that the cell in the very right column and in the last row is displayed.


_move_cols

$object->_move_cols($start_col, $end_col, $offset);

Moves the ranges specified by $start_col and $end_col.

Parameters:

(+) $start_col: The left column in the range to be moved

(+) $end_col: The right column in the range to be moved

(+) $offset: How many cols the range should be moved. Positive values shift to the right, negative values shift to the left. The range is not allowed to exceed the borders of the table, otherwise it gives an ERROR.

This means that $offset has to be more than ($start_col * -1) and less than ($self->cols() - $end_col)


_move_rows

$object->_move_rows($start_row, $end_row, $offset);

Moves the ranges specified by $start_row and $end_row.

Parameters:

(+) $start_row: The upper row in the range to be moved

(+) $end_row: The lower row in the range to be moved

(+) $offset: How many rows the range should be moved. Positive values shift downwards, negative values shift upwards. The range is not allowed to exceed the borders of the table, otherwise it gives an ERROR.

This means that $offset has to be more than ($start_row * -1) and less than ($self->rows() - $end_row)


BINDINGS:

Ctrl + Up = Move to the cell above the active one cell.

Ctrl + Down = Move to the cell under the atcive one cell.

Ctrl + Left = Move to the cell left of the atcive one cell.

Ctrl + Right = Move to the cell right of the atcive one cell.

Ctrl + Home = Move to the upper left corner of the table

Ctrl + End = Move to the lower right corner of the table


KNOWN BUGS:

This widget is to slow in creating the cells !

Everything more than a table of 12x30 cells on a Celeron366 is beyond my patience.


REQUIREMENTS:

Nothing except Perl and perl/Tk (should work with ptk 800.016+).


STILL MISSING:

(+) Speed improvements (especially in building up the cols/rows).

(+) Possibility to select a range of cells.

(+) Do not 'hardcode' the default cell_width and cell_height that is used, define two new options for that.

(+) Clipboard functionality that copies the selected range (including cell-styles of course).

(+) Adding more options for Populate (Examples: Turning on/off of the headers [-showheaders=>0/1], the background- and foregroundcolor of the selected cell [-activecellbackground, -activecellforeground], allowing to specify other images for the resizing grips [-hgripimage, -vgripimage, -tableimage], ... ).

(+) Doing all of this 'ConfigSpecs', 'Adveritse', 'Delegate stuff'

(+) Allowing to add items+callbacks to the table-, column-, row- and cell-menus , to replace or to hide them totally.

(+) Loading from comma- , semicolon- and tab-separated lists and saving into these formats too.

(+) Column- and rowspan for cells

(+) Writing a better doc.


LICENSE:

This widget is licensed the same way as Perl itself.


AUTHOR:

Copyright by Thomas Schmickl, Graz, Austria, email: schmickl@nextra.at, faultier@nextra.at or edoc@nextra.at.

If these emailadresses are expired some day, try to contact me via: office@foto-schmickl.at and write ``For Thomas Schmickl:'' into the subject line.