Source code for albow.palette_view

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 scroll_up_rect(self): d = self.scroll_button_size r = Rect(0, 0, d, d) m = self.margin r.top = m r.right = self.width - m r.inflate_ip(-4, -4) return r
[docs] def scroll_down_rect(self): d = self.scroll_button_size r = Rect(0, 0, d, d) m = self.margin r.bottom = self.height - m r.right = self.width - m r.inflate_ip(-4, -4) return r
[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_scroll_up_button(self, surface): r = self.scroll_up_rect() c = self.scroll_button_color draw.polygon(surface, c, [r.bottomleft, r.midtop, r.bottomright])
[docs] def draw_scroll_down_button(self, surface): r = self.scroll_down_rect() c = self.scroll_button_color draw.polygon(surface, c, [r.topleft, r.midbottom, r.topright])
[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 scroll_up(self, delta=1): if self.can_scroll_up(): self.scroll -= delta
[docs] def scroll_down(self, delta=1): if self.can_scroll_down(): self.scroll += delta
[docs] def scroll_to_item(self, n): i = max(0, min(n, self.num_items() - 1)) p = self.items_per_page() self.scroll = p * (i // p)
[docs] def can_scroll_up(self): return self.scrolling and self.scroll > 0
[docs] def can_scroll_down(self): return self.scrolling and self.scroll + self.items_per_page() < self.num_items()
[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
[docs] def scrollbar_rect(self): # Get the distance between the scroll buttons (d) 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) v = self.num_rows() s = float(d) / n h = s * v if type(h) == float: if h - int(h) > 0: h += 1 top = max(sub, sub + (s * self.scroll) + self.scroll_rel) r = Rect(0, top, self.scroll_button_size, h) m = self.margin r.right = self.width - m r.bottom = min(r.bottom, t) r.inflate_ip(-4, -4) if r.h < 1: r.h = int(h) return r
[docs] def draw_scrollbar(self, surface): r = self.scrollbar_rect() c = map(lambda x: min(255, max(0, x + 10)), self.scroll_button_color) draw.rect(surface, c, r)