Lightningbeam/GUI/Generic/PaletteView.py

145 lines
4.7 KiB
Python

#--------------------------------------------------------------------------
#
# PyGUI - Palette View - Generic
#
#--------------------------------------------------------------------------
from GUI import export
from GUI.Properties import overridable_property
from GUI import StdColors, GridView
from GUI.GUtils import splitdict
class PaletteView(GridView):
"""A GridView whose cells are identified by a linear index from
left to right and top to bottom. Also provides support for
highlighting one or more selected cells."""
num_items = overridable_property('num_items',
"Total number of items")
items_per_row = overridable_property('items_per_row',
"Number of items displayed in one row")
highlight_style = overridable_property('highlight_style',
"Style of selection highlighting")
highlight_color = overridable_property('highlight_color',
"Color of selection highlighting")
highlight_thickness = overridable_property('highlight_thickness',
"Width of selection highlighting for 'frame' highlight mode")
_highlight_style = 'fill'
_highlight_color = StdColors.selection_backcolor
_highlight_thickness = 4
def __init__(self, num_items, items_per_row, cell_size,
scrolling = '', **kwds):
base_kwds = splitdict(kwds, 'border', scrolling = '')
GridView.__init__(self, num_rows = 0, num_columns = 0,
cell_size = cell_size, **base_kwds)
self._num_items = num_items
self._items_per_row = items_per_row
self._update_num_rows_and_columns()
ew, eh = self.extent
if not self.hscrolling:
self.content_width = ew
if not self.vscrolling:
self.content_height = eh
self.set(**kwds)
def get_num_items(self):
return self._num_items
def set_num_items(self, n):
self._num_items = n
self._update_num_rows_and_columns()
def get_items_per_row(self):
return self.num_columns
def set_items_per_row(self, n):
self._items_per_row = n
self._update_num_rows_and_columns()
def _update_num_rows_and_columns(self):
nc = self._items_per_row
nr = (self._num_items + nc - 1) // nc
self._num_columns = nc
self._num_rows = nr
self._update_extent()
def get_highlight_style(self):
return self._highlight_style
def set_highlight_style(self, x):
self._highlight_style = x
def get_highlight_color(self):
return self._highlight_color
def set_highlight_color(self, x):
self._highlight_color = x
def get_highlight_color(self):
return self._highlight_color
def set_highlight_color(self, x):
self._highlight_color = x
def item_no_of_cell(self, row, col):
i = row * self._items_per_row + col
if 0 <= i < self._num_items:
return i
def cell_of_item_no(self, item_no):
if 0 <= item_no < self._num_items:
return divmod(item_no, self._items_per_row)
def item_rect(self, item_no):
cell = self.cell_of_item_no(item_no)
if cell:
return self.cell_rect(*cell)
def draw_cell(self, canvas, row, col, rect):
i = self.item_no_of_cell(row, col)
if i is not None:
highlight = self.item_is_selected(i)
self.draw_item_and_highlight(canvas, i, rect, highlight)
def draw_item_and_highlight(self, canvas, item_no, rect, highlight):
"""Draw the specified item, with selection highlighting if highlight
is true."""
if highlight:
style = self.highlight_style
if style:
canvas.gsave()
if style == 'fill':
canvas.fillcolor = self.highlight_color
canvas.fill_rect(rect)
else:
canvas.pencolor = self.highlight_color
canvas.pensize = self.highlight_thickness
canvas.frame_rect(rect)
canvas.grestore()
self.draw_item(canvas, item_no, rect)
def draw_item(self, canvas, item_no, rect):
"""Should draw the specified item in the given rect."""
pass
def click_cell(self, row, col, event):
i = self.item_no_of_cell(row, col)
if i is not None:
self.click_item(i, event)
def click_item(self, item_no, event):
"""Called when a mouse_down event has occurred in the indicated item."""
pass
def item_is_selected(self, item_no):
"""Should return true if the indicated item is to be drawn highlighted."""
return False
export(PaletteView)