This repository has been archived on 2024-06-13. You can view files and clone it, but cannot push or open issues or pull requests.
mcedit/albow/table_view.py

184 lines
5.4 KiB
Python

#
# Albow - Table View
#
from itertools import izip
from pygame import Rect
from layout import Column
from palette_view import PaletteView
from utils import blit_in_rect
class TableView(Column):
columns = []
header_font = None
header_fg_color = None
header_bg_color = None
header_spacing = 5
column_margin = 2
def __init__(self, nrows=15, height=None,
header_height=None, row_height=None,
scrolling=True, **kwds):
columns = self.predict_attr(kwds, 'columns')
if row_height is None:
font = self.predict_font(kwds)
row_height = font.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 height:
nrows = height // row_height
self.rows = rows = TableRowView(row_size, nrows or 10, scrolling=scrolling)
contents.append(rows)
s = self.header_spacing
Column.__init__(self, contents, align='l', spacing=s, **kwds)
if header:
header.font = self.header_font or self.font
header.fg_color = fg_color = self.header_fg_color or self.fg_color
header.bg_color = 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, surf, i, cell_rect, column):
self.draw_text_cell(surf, i, column.title, cell_rect,
column.alignment, self.font)
def draw_table_cell(self, surf, i, data, cell_rect, column):
text = column.format(data)
self.draw_text_cell(surf, i, text, cell_rect, column.alignment, self.font)
def draw_text_cell(self, surf, i, data, cell_rect, align, font):
buf = font.render(unicode(data), True, self.fg_color)
blit_in_rect(surf, buf, cell_rect, align)
def row_is_selected(self, n):
return False
def click_row(self, n, e):
pass
def click_column_header(self, col):
print "click_column_header: ", col
def click_header(self, n, e):
x, y = self.global_to_local(e.pos)
width = 0
for col in self.columns:
width += col.width
if x < width:
return self.click_column_header(col)
class TableColumn(object):
# title string
# width int
# alignment 'l' or 'c' or 'r'
# formatter func(data) -> string
# format_string string Used by default formatter
format_string = "%s"
def __init__(self, title, width, align='l', fmt=None):
self.title = title
self.width = width
self.alignment = align
if fmt:
if isinstance(fmt, (str, unicode)):
self.format_string = fmt
else:
self.formatter = fmt
def format(self, data):
if data is not None:
return self.formatter(data)
else:
return ""
def formatter(self, data):
return self.format_string % data
class TableRowBase(PaletteView):
def __init__(self, cell_size, nrows, scrolling):
PaletteView.__init__(self, cell_size, nrows, 1, scrolling=scrolling)
def num_items(self):
return self.parent.num_rows()
def draw_item(self, surf, row, row_rect):
table = self.parent
height = row_rect.height
row_data = self.row_data(row)
for i, x, width, column, cell_data in table.column_info(row_data):
cell_rect = Rect(x + self.margin, row_rect.top, width, height)
self.draw_table_cell(surf, row, cell_data, cell_rect, column)
def row_data(self, row):
return self.parent.row_data(row)
def draw_table_cell(self, surf, i, data, cell_rect, column):
self.parent.draw_table_cell(surf, i, data, cell_rect, column)
class TableRowView(TableRowBase):
highlight_style = 'fill'
vstretch = True
def item_is_selected(self, n):
return self.parent.row_is_selected(n)
def click_item(self, n, e):
self.parent.click_row(n, e)
class TableHeaderView(TableRowBase):
def __init__(self, width, height):
TableRowBase.__init__(self, (width, height), 1, False)
# def row_data(self, row):
# return [c.title for c in self.parent.columns]
# def draw_table_cell(self, surf, i, text, cell_rect, column):
# self.parent.draw_header_cell(surf, i, text, cell_rect, column)
def row_data(self, row):
None
def draw_table_cell(self, surf, i, data, cell_rect, column):
self.parent.draw_header_cell(surf, i, cell_rect, column)
def click_item(self, n, e):
self.parent.click_header(n, e)