Module albow.table.TableView

Source code
from pygame import font
from pygame import Surface
from pygame import Rect

from pygame.event import Event

from albow.layout.Column import Column
from albow.utils import blit_in_rect

from albow.table.TableHeaderView import TableHeaderView
from albow.table.TableRowView import TableRowView
from albow.table.TableColumn import TableColumn


class TableView(Column):
    """
    A TableView provides a tabular view of data having a fixed number of columns and a variable number of rows. There
    may be a header providing titles for the columns. There is provision for scrolling and for allowing the user
    to select rows.

    An auxiliary class TableColumn is used to configure the formatting of the headers and data.

    By default, all headers and data are displayed textually, but this can be changed by overriding methods
    of the TableView.
    """
    columns: TableColumn = []
    """
    A list of TableColumn instances describing the columns of the table.
    """
    header_font: font = None
    """
    Font in which to display the column headers.
    """
    header_fg_color = None
    """
    Foreground colour of the column headers.
    """
    header_bg_color = None
    """
    Background colour of the column headers, or None.
    """
    header_spacing = 5
    """
    Space to leave between the header and the rows.  Default is 5 pixels
    """
    column_margin = 2
    """
    Space to leave either side of the contents of a column. Default is 2 pixels
    """

    def __init__(self, nrows=None, theHeight=None, header_height=None, row_height=None, scrolling=True, **kwds):
        """

        The TableView is initialized with a width and height determined as follows:

        - The initial width is calculated from the information in the *columns* attribute.
        - The initial height, excluding the header, is determined either directly by the height parameter or by the
          row height and number of rows *nrows*. If no *row_height* is specified, it is calculated from the size of
          the font.
        - The height of the header is determined by ''header_height'', or the size of the header font.


        Args:
            nrows:  The # of rows

            theHeight:

            header_height: If None use the size of the header font

            row_height:

            scrolling:   If scrolling is true, the table will display scrolling arrows.

            **kwds:
        """
        columns = self.predict_attr(kwds, 'columns')

        if row_height is None:
            predictedFont = self.predict_font(kwds)
            row_height    = predictedFont.get_linesize()

        if header_height is None:
            header_height = row_height
        row_width = 0
        if columns:
            for column in columns:
                row_width += column.width
            row_width += 2 * self.column_margin * len(columns)
        contents = []
        header = None
        if header_height:
            header = TableHeaderView(row_width, header_height)
            contents.append(header)
        row_size = (row_width, row_height)

        if not nrows and theHeight:
            nrows = theHeight // row_height
        rows = TableRowView(row_size, nrows or 10, scrolling=scrolling)
        contents.append(rows)
        s = self.header_spacing
        #
        # Python 3 update
        #
        # Column.__init__(self, contents, align = 'l', spacing = s, **kwds)
        super().__init__(contents, align='l', spacing=s, **kwds)
        if header:
            header.font = self.header_font or self.font
            header.fg_color = self.header_fg_color or self.fg_color
            header.bg_color = self.header_bg_color or self.bg_color
        rows.font = self.font
        rows.fg_color = self.fg_color
        rows.bg_color = self.bg_color
        rows.sel_color = self.sel_color

    def column_info(self, row_data):
        columns = self.columns
        m = self.column_margin
        d = 2 * m
        x = 0
        for i, column in enumerate(columns):
            width = column.width
            if row_data:
                data = row_data[i]
            else:
                data = None
            yield i, x + m, width - d, column, data
            x += width

    def draw_header_cell(self, theSurface: Surface, cell_rect: Rect, theTableColumn: TableColumn):
        """
        Draws the header of TableColumn
        By default, the column's title is displayed
        using the header_font and the alignment specified by coldesc.
        Args:
            theSurface:       The pygame surface to use

            cell_rect: The rect is the rectangle corresponding to the header area,

            theTableColumn:  The table column header to render

        """
        self.draw_text_cell(theSurface, theTableColumn.title, cell_rect, theTableColumn.alignment, self.font)

    def draw_table_cell(self, surf: Surface, data: str, cell_rect: Rect, tableColumn: TableColumn):
        """
        Draws a cell of the table. data is the data item to be displayed, rect is the rectangle corresponding to the
        cell, By default, the data is formatted as
        specified by TableColumn's format_string and rendered using the widget's font.

        Args:
            surf:       The pygame Surface

            data:   The data to display

            cell_rect: The rect is the rectangle corresponding to the header area,

            tableColumn:  The table column header to render
        """
        text = tableColumn.format(data)
        self.draw_text_cell(surf, text, cell_rect, tableColumn.alignment, self.font)

    def draw_text_cell(self, theSurface: Surface, data, cell_rect: Rect, align: str, theFont: font):
        """

        Args:
            theSurface:
            data:
            cell_rect:
            align:
            theFont:

        """

        buf: Surface = theFont.render(str(data), True, self.fg_color)
        blit_in_rect(theSurface, buf, cell_rect, align)

    #
    #  Abstract methods follow
    #
    def click_row(self, theRowNumber: int, theEvent: Event):
        """
        Called when theRowNumber is clicked. The default implementation does nothing.

        Args:
            theRowNumber: The 'clicked' row number

            theEvent:  The associated event

        """
        pass

    def row_is_selected(self, theRowNumber: int, theEvent: Event = None) -> bool:
        """
        Should return true if *theRowNumber* is considered selected. The default implementation
        always returns *False*.  *StarStar*, 'quotequote'
        Args:
            theRowNumber:  The selected row number to check

            theEvent:  The associated pygame event

        Returns: *True* if selected, else *False*

        """
        return False

    def num_rows(self) -> int:
        """

        Returns:  The # of rows
        """
        pass

    def row_data(self, theRowNumber: int):
        """

        Should return a sequence of data items for row number n. The data items may be of any type, provided they
        can be formatted as specified by the corresponding TableColumn. Must be implemented.

        Args:
            theRowNumber: A row number

        Returns:  Row data

        """
        pass

Classes

class TableView (nrows=None, theHeight=None, header_height=None, row_height=None, scrolling=True, **kwds)

A TableView provides a tabular view of data having a fixed number of columns and a variable number of rows. There may be a header providing titles for the columns. There is provision for scrolling and for allowing the user to select rows.

An auxiliary class TableColumn is used to configure the formatting of the headers and data.

By default, all headers and data are displayed textually, but this can be changed by overriding methods of the TableView.

The TableView is initialized with a width and height determined as follows:

  • The initial width is calculated from the information in the columns attribute.
  • The initial height, excluding the header, is determined either directly by the height parameter or by the row height and number of rows nrows. If no row_height is specified, it is calculated from the size of the font.
  • The height of the header is determined by ''header_height'', or the size of the header font.

Args

nrows
The # of rows

theHeight:

header_height
If None use the size of the header font

row_height:

scrolling
If scrolling is true, the table will display scrolling arrows.

**kwds:

Source code
class TableView(Column):
    """
    A TableView provides a tabular view of data having a fixed number of columns and a variable number of rows. There
    may be a header providing titles for the columns. There is provision for scrolling and for allowing the user
    to select rows.

    An auxiliary class TableColumn is used to configure the formatting of the headers and data.

    By default, all headers and data are displayed textually, but this can be changed by overriding methods
    of the TableView.
    """
    columns: TableColumn = []
    """
    A list of TableColumn instances describing the columns of the table.
    """
    header_font: font = None
    """
    Font in which to display the column headers.
    """
    header_fg_color = None
    """
    Foreground colour of the column headers.
    """
    header_bg_color = None
    """
    Background colour of the column headers, or None.
    """
    header_spacing = 5
    """
    Space to leave between the header and the rows.  Default is 5 pixels
    """
    column_margin = 2
    """
    Space to leave either side of the contents of a column. Default is 2 pixels
    """

    def __init__(self, nrows=None, theHeight=None, header_height=None, row_height=None, scrolling=True, **kwds):
        """

        The TableView is initialized with a width and height determined as follows:

        - The initial width is calculated from the information in the *columns* attribute.
        - The initial height, excluding the header, is determined either directly by the height parameter or by the
          row height and number of rows *nrows*. If no *row_height* is specified, it is calculated from the size of
          the font.
        - The height of the header is determined by ''header_height'', or the size of the header font.


        Args:
            nrows:  The # of rows

            theHeight:

            header_height: If None use the size of the header font

            row_height:

            scrolling:   If scrolling is true, the table will display scrolling arrows.

            **kwds:
        """
        columns = self.predict_attr(kwds, 'columns')

        if row_height is None:
            predictedFont = self.predict_font(kwds)
            row_height    = predictedFont.get_linesize()

        if header_height is None:
            header_height = row_height
        row_width = 0
        if columns:
            for column in columns:
                row_width += column.width
            row_width += 2 * self.column_margin * len(columns)
        contents = []
        header = None
        if header_height:
            header = TableHeaderView(row_width, header_height)
            contents.append(header)
        row_size = (row_width, row_height)

        if not nrows and theHeight:
            nrows = theHeight // row_height
        rows = TableRowView(row_size, nrows or 10, scrolling=scrolling)
        contents.append(rows)
        s = self.header_spacing
        #
        # Python 3 update
        #
        # Column.__init__(self, contents, align = 'l', spacing = s, **kwds)
        super().__init__(contents, align='l', spacing=s, **kwds)
        if header:
            header.font = self.header_font or self.font
            header.fg_color = self.header_fg_color or self.fg_color
            header.bg_color = self.header_bg_color or self.bg_color
        rows.font = self.font
        rows.fg_color = self.fg_color
        rows.bg_color = self.bg_color
        rows.sel_color = self.sel_color

    def column_info(self, row_data):
        columns = self.columns
        m = self.column_margin
        d = 2 * m
        x = 0
        for i, column in enumerate(columns):
            width = column.width
            if row_data:
                data = row_data[i]
            else:
                data = None
            yield i, x + m, width - d, column, data
            x += width

    def draw_header_cell(self, theSurface: Surface, cell_rect: Rect, theTableColumn: TableColumn):
        """
        Draws the header of TableColumn
        By default, the column's title is displayed
        using the header_font and the alignment specified by coldesc.
        Args:
            theSurface:       The pygame surface to use

            cell_rect: The rect is the rectangle corresponding to the header area,

            theTableColumn:  The table column header to render

        """
        self.draw_text_cell(theSurface, theTableColumn.title, cell_rect, theTableColumn.alignment, self.font)

    def draw_table_cell(self, surf: Surface, data: str, cell_rect: Rect, tableColumn: TableColumn):
        """
        Draws a cell of the table. data is the data item to be displayed, rect is the rectangle corresponding to the
        cell, By default, the data is formatted as
        specified by TableColumn's format_string and rendered using the widget's font.

        Args:
            surf:       The pygame Surface

            data:   The data to display

            cell_rect: The rect is the rectangle corresponding to the header area,

            tableColumn:  The table column header to render
        """
        text = tableColumn.format(data)
        self.draw_text_cell(surf, text, cell_rect, tableColumn.alignment, self.font)

    def draw_text_cell(self, theSurface: Surface, data, cell_rect: Rect, align: str, theFont: font):
        """

        Args:
            theSurface:
            data:
            cell_rect:
            align:
            theFont:

        """

        buf: Surface = theFont.render(str(data), True, self.fg_color)
        blit_in_rect(theSurface, buf, cell_rect, align)

    #
    #  Abstract methods follow
    #
    def click_row(self, theRowNumber: int, theEvent: Event):
        """
        Called when theRowNumber is clicked. The default implementation does nothing.

        Args:
            theRowNumber: The 'clicked' row number

            theEvent:  The associated event

        """
        pass

    def row_is_selected(self, theRowNumber: int, theEvent: Event = None) -> bool:
        """
        Should return true if *theRowNumber* is considered selected. The default implementation
        always returns *False*.  *StarStar*, 'quotequote'
        Args:
            theRowNumber:  The selected row number to check

            theEvent:  The associated pygame event

        Returns: *True* if selected, else *False*

        """
        return False

    def num_rows(self) -> int:
        """

        Returns:  The # of rows
        """
        pass

    def row_data(self, theRowNumber: int):
        """

        Should return a sequence of data items for row number n. The data items may be of any type, provided they
        can be formatted as specified by the corresponding TableColumn. Must be implemented.

        Args:
            theRowNumber: A row number

        Returns:  Row data

        """
        pass

Ancestors

Subclasses

  • albow.demo.views.DemoTableView.DemoTableView

Class variables

var column_margin

Space to leave either side of the contents of a column. Default is 2 pixels

var columns

A list of TableColumn instances describing the columns of the table.

var header_bg_color

Background colour of the column headers, or None.

var header_fg_color

Foreground colour of the column headers.

var header_font

Font in which to display the column headers.

var header_spacing

Space to leave between the header and the rows. Default is 5 pixels

Methods

def click_row(self, theRowNumber, theEvent)

Called when theRowNumber is clicked. The default implementation does nothing.

Args

theRowNumber
The 'clicked' row number
theEvent
The associated event
Source code
def click_row(self, theRowNumber: int, theEvent: Event):
    """
    Called when theRowNumber is clicked. The default implementation does nothing.

    Args:
        theRowNumber: The 'clicked' row number

        theEvent:  The associated event

    """
    pass
def column_info(self, row_data)
Source code
def column_info(self, row_data):
    columns = self.columns
    m = self.column_margin
    d = 2 * m
    x = 0
    for i, column in enumerate(columns):
        width = column.width
        if row_data:
            data = row_data[i]
        else:
            data = None
        yield i, x + m, width - d, column, data
        x += width
def draw_header_cell(self, theSurface, cell_rect, theTableColumn)

Draws the header of TableColumn By default, the column's title is displayed using the header_font and the alignment specified by coldesc.

Args

theSurface

The pygame surface to use

cell_rect
The rect is the rectangle corresponding to the header area,
theTableColumn
The table column header to render
Source code
def draw_header_cell(self, theSurface: Surface, cell_rect: Rect, theTableColumn: TableColumn):
    """
    Draws the header of TableColumn
    By default, the column's title is displayed
    using the header_font and the alignment specified by coldesc.
    Args:
        theSurface:       The pygame surface to use

        cell_rect: The rect is the rectangle corresponding to the header area,

        theTableColumn:  The table column header to render

    """
    self.draw_text_cell(theSurface, theTableColumn.title, cell_rect, theTableColumn.alignment, self.font)
def draw_table_cell(self, surf, data, cell_rect, tableColumn)

Draws a cell of the table. data is the data item to be displayed, rect is the rectangle corresponding to the cell, By default, the data is formatted as specified by TableColumn's format_string and rendered using the widget's font.

Args

surf

The pygame Surface

data
The data to display
cell_rect
The rect is the rectangle corresponding to the header area,
tableColumn
The table column header to render
Source code
def draw_table_cell(self, surf: Surface, data: str, cell_rect: Rect, tableColumn: TableColumn):
    """
    Draws a cell of the table. data is the data item to be displayed, rect is the rectangle corresponding to the
    cell, By default, the data is formatted as
    specified by TableColumn's format_string and rendered using the widget's font.

    Args:
        surf:       The pygame Surface

        data:   The data to display

        cell_rect: The rect is the rectangle corresponding to the header area,

        tableColumn:  The table column header to render
    """
    text = tableColumn.format(data)
    self.draw_text_cell(surf, text, cell_rect, tableColumn.alignment, self.font)
def draw_text_cell(self, theSurface, data, cell_rect, align, theFont)

Args

theSurface: data: cell_rect: align: theFont:

Source code
def draw_text_cell(self, theSurface: Surface, data, cell_rect: Rect, align: str, theFont: font):
    """

    Args:
        theSurface:
        data:
        cell_rect:
        align:
        theFont:

    """

    buf: Surface = theFont.render(str(data), True, self.fg_color)
    blit_in_rect(theSurface, buf, cell_rect, align)
def num_rows(self)

Returns: The # of rows

Source code
def num_rows(self) -> int:
    """

    Returns:  The # of rows
    """
    pass
def row_data(self, theRowNumber)

Should return a sequence of data items for row number n. The data items may be of any type, provided they can be formatted as specified by the corresponding TableColumn. Must be implemented.

Args

theRowNumber
A row number
Returns :  Row data
 
Source code
def row_data(self, theRowNumber: int):
    """

    Should return a sequence of data items for row number n. The data items may be of any type, provided they
    can be formatted as specified by the corresponding TableColumn. Must be implemented.

    Args:
        theRowNumber: A row number

    Returns:  Row data

    """
    pass
def row_is_selected(self, theRowNumber, theEvent=None)

Should return true if theRowNumber is considered selected. The default implementation always returns False. StarStar, 'quotequote'

Args

theRowNumber
The selected row number to check
theEvent
The associated pygame event
Returns : True if selected, else False
 
Source code
def row_is_selected(self, theRowNumber: int, theEvent: Event = None) -> bool:
    """
    Should return true if *theRowNumber* is considered selected. The default implementation
    always returns *False*.  *StarStar*, 'quotequote'
    Args:
        theRowNumber:  The selected row number to check

        theEvent:  The associated pygame event

    Returns: *True* if selected, else *False*

    """
    return False

Inherited members