from pygame import Rect, draw
from grid_view import GridView
from utils import frame_rect
from theme import ThemeProperty
[docs]class PaletteView(GridView):
# nrows int No. of displayed rows
# ncols int No. of displayed columns
#
# Abstract methods:
#
# num_items() --> no. of items
# draw_item(surface, item_no, rect)
# click_item(item_no, event)
# item_is_selected(item_no) --> bool
sel_width = ThemeProperty('sel_width')
zebra_color = ThemeProperty('zebra_color')
scroll_button_size = ThemeProperty('scroll_button_size')
scroll_button_color = ThemeProperty('scroll_button_color')
highlight_style = ThemeProperty('highlight_style')
# 'frame' or 'fill' or 'reverse' or None
def __init__(self, cell_size, nrows, ncols, scrolling=False, **kwds):
GridView.__init__(self, cell_size, nrows, ncols, **kwds)
self.scrolling = scrolling
if scrolling:
d = self.scroll_button_size
#l = self.width
#b = self.height
self.width += d
#self.scroll_up_rect = Rect(l, 0, d, d).inflate(-4, -4)
#self.scroll_down_rect = Rect(l, b - d, d, d).inflate(-4, -4)
self.scroll = 0
self.dragging_hover = False
self.scroll_rel = 0
[docs] def draw(self, surface):
GridView.draw(self, surface)
u = False
d = False
if self.can_scroll_up():
u = True
self.draw_scroll_up_button(surface)
if self.can_scroll_down():
d = True
self.draw_scroll_down_button(surface)
if u or d:
self.draw_scrollbar(surface)
[docs] def draw_cell(self, surface, row, col, rect):
i = self.cell_to_item_no(row, col)
if i is not None:
highlight = self.item_is_selected(i)
self.draw_item_and_highlight(surface, i, rect, highlight)
[docs] def draw_item_and_highlight(self, surface, i, rect, highlight):
if not i % 2 and "Header" not in str(type(self)):
surface.fill(self.zebra_color, rect)
if highlight:
self.draw_prehighlight(surface, i, rect)
if highlight and self.highlight_style == 'reverse':
fg = self.inherited('bg_color') or self.sel_color
else:
fg = self.fg_color
self.draw_item_with(surface, i, rect, fg)
if highlight:
self.draw_posthighlight(surface, i, rect)
[docs] def draw_item_with(self, surface, i, rect, fg):
old_fg = self.fg_color
self.fg_color = fg
try:
self.draw_item(surface, i, rect)
finally:
self.fg_color = old_fg
[docs] def draw_prehighlight(self, surface, i, rect):
if self.highlight_style == 'reverse':
color = self.fg_color
else:
color = self.sel_color
self.draw_prehighlight_with(surface, i, rect, color)
[docs] def draw_prehighlight_with(self, surface, i, rect, color):
style = self.highlight_style
if style == 'frame':
frame_rect(surface, color, rect, self.sel_width)
elif style == 'fill' or style == 'reverse':
surface.fill(color, rect)
[docs] def draw_posthighlight(self, surface, i, rect):
pass
[docs] def mouse_down(self, event):
if event.button == 1:
if self.scrolling:
p = event.local
if self.scrollbar_rect().collidepoint(p):
self.dragging_hover = True
return
elif self.scroll_up_rect().collidepoint(p):
self.scroll_up()
return
elif self.scroll_down_rect().collidepoint(p):
self.scroll_down()
return
if event.button == 4:
self.scroll_up()
if event.button == 5:
self.scroll_down()
GridView.mouse_down(self, event)
[docs] def mouse_drag(self, event):
if self.dragging_hover:
self.scroll_rel += event.rel[1]
sub = self.scroll_up_rect().bottom
t = self.scroll_down_rect().top
d = t - sub
# Get the total row number (n).
n = self.num_items() / getattr(getattr(self, 'parent', None), 'num_cols', lambda: 1)()
# Get the displayed row number (v)
s = float(d) / n
if abs(self.scroll_rel) >= s:
if self.scroll_rel > 0:
self.scroll_down(delta=int(abs(self.scroll_rel) / s))
else:
self.scroll_up(delta=int(abs(self.scroll_rel) / s))
self.scroll_rel = 0
[docs] def mouse_up(self, event):
if event.button == 1:
if self.dragging_hover:
self.dragging_hover = False
self.scroll_rel = 0
[docs] def items_per_page(self):
return self.num_rows() * self.num_cols()
[docs] def click_cell(self, row, col, event):
i = self.cell_to_item_no(row, col)
if i is not None:
self.click_item(i, event)
[docs] def cell_to_item_no(self, row, col):
i = self.scroll + row * self.num_cols() + col
if 0 <= i < self.num_items():
return i
else:
return None
[docs] def num_rows(self):
ch = self.cell_size[1]
if ch:
return self.height // ch
else:
return 0
[docs] def num_cols(self):
width = self.width
if self.scrolling:
width -= self.scroll_button_size
cw = self.cell_size[0]
if cw:
return width // cw
else:
return 0
[docs] def item_is_selected(self, n):
return False
[docs] def click_item(self, n, e):
pass