Use static instruction for highlighted row

Instead of all this adding/removing of canvas instructions nonsense
simple add a static "highlighted" rectangle to each row and make its
size very small when there's no mouse over.

Mad props to @tshirtman for showing me the light :D
kivy_mainline_and_py3.8
Tyler Goodlet 2018-11-24 15:41:53 -05:00
parent 488bdb34be
commit a8a5e836b9
2 changed files with 37 additions and 53 deletions

View File

@ -31,7 +31,7 @@ class HoverBehavior(object):
super(HoverBehavior, self).__init__(**kwargs) super(HoverBehavior, self).__init__(**kwargs)
def on_mouse_pos(self, *args): def on_mouse_pos(self, *args):
# do proceed if I'm not displayed <=> If have no parent # don't proceed if I'm not displayed <=> If have no parent
if not self.get_root_window(): if not self.get_root_window():
return return
pos = args[1] pos = args[1]

View File

@ -19,7 +19,6 @@ from kivy.lang import Builder
from kivy import utils from kivy import utils
from kivy.app import async_runTouchApp from kivy.app import async_runTouchApp
from kivy.core.window import Window from kivy.core.window import Window
from kivy.graphics import Color, Rectangle, RoundedRectangle
from ..log import get_logger from ..log import get_logger
from .pager import PagerView from .pager import PagerView
@ -121,6 +120,14 @@ _kv = (f'''
# self here refers to the widget i.e Row(GridLayout) # self here refers to the widget i.e Row(GridLayout)
pos: self.pos pos: self.pos
size: self.size size: self.size
# row higlighting on mouse over
Color:
rgba: {_i3_rgba}
RoundedRectangle:
size: self.width, self.height if self.hovered else 1
pos: self.pos
radius: (10,)
# part of the `PagerView` # part of the `PagerView`
@ -133,51 +140,17 @@ _kv = (f'''
''') ''')
class HighlightRowHoverable(HoverBehavior): class Cell(Button):
def on_enter(self): """Data cell: the fundemental widget.
"""Highlight row on enter.
"""
log.debug(
f"Entered cell {self} through {self.border_point}")
row = self
if row.mouse_over or row.is_header:
return
# add draw instructions ``key`` is the column name index value.
color = row._color = Color(*_i3_rgba) """
rect = row._rect = RoundedRectangle( def __init__(self, key=None, **kwargs):
size=row.size, super(Cell, self).__init__(**kwargs)
pos=row.pos, self.key = key
radius=(10,)
)
# add to canvas
canvas = row.canvas
if row._rect not in canvas.before.children:
canvas.before.add(color)
canvas.before.add(rect)
# mark row as being "selected"
row.mouse_over = True
def on_leave(self):
"""Un-highlight row on exit.
"""
log.debug(
f"Left cell {self} through {self.border_point}")
row = self
if not row.mouse_over or row.is_header:
return
canvas = row.canvas
# remove instructions from canvas
if row._color in canvas.before.children:
canvas.before.remove(row._color)
canvas.before.remove(row._rect)
# mark row as being "un-selected"
row.mouse_over = False
class HeaderCell(Button): class HeaderCell(Cell):
"""Column header cell label. """Column header cell label.
""" """
def on_press(self, value=None): def on_press(self, value=None):
@ -210,11 +183,6 @@ class HeaderCell(Button):
self.background_color = self.color self.background_color = self.color
class Cell(Button):
"""Data cell.
"""
class BidAskLayout(StackLayout): class BidAskLayout(StackLayout):
"""Cell which houses three buttons containing a last, bid, and ask in a """Cell which houses three buttons containing a last, bid, and ask in a
single unit oriented with the last 2 under the first. single unit oriented with the last 2 under the first.
@ -273,7 +241,7 @@ class BidAskLayout(StackLayout):
return [self.last, self.bid, self.ask] return [self.last, self.bid, self.ask]
class Row(GridLayout, HighlightRowHoverable): class Row(GridLayout, HoverBehavior):
"""A grid for displaying a row of ticker quote data. """A grid for displaying a row of ticker quote data.
The row fields can be updated using the ``fields`` property which will in The row fields can be updated using the ``fields`` property which will in
@ -321,20 +289,20 @@ class Row(GridLayout, HighlightRowHoverable):
# these cells have already been added to the `BidAskLayout` # these cells have already been added to the `BidAskLayout`
continue continue
else: else:
cell = self._append_cell(val, header=header) cell = self._append_cell(val, key, header=header)
cell.key = key cell.key = key
self._cell_widgets[key] = cell self._cell_widgets[key] = cell
def get_cell(self, key): def get_cell(self, key):
return self._cell_widgets[key] return self._cell_widgets[key]
def _append_cell(self, text, header=False): def _append_cell(self, text, key, header=False):
if not len(self._cell_widgets) < self.cols: if not len(self._cell_widgets) < self.cols:
raise ValueError(f"Can not append more then {self.cols} cells") raise ValueError(f"Can not append more then {self.cols} cells")
# header cells just have a different colour # header cells just have a different colour
celltype = HeaderCell if header else Cell celltype = HeaderCell if header else Cell
cell = celltype(text=str(text)) cell = celltype(text=str(text), key=key)
cell.is_header = header cell.is_header = header
cell.row = self cell.row = self
self.add_widget(cell) self.add_widget(cell)
@ -368,6 +336,22 @@ class Row(GridLayout, HighlightRowHoverable):
self._last_record = record self._last_record = record
return cells return cells
# mouse over handlers
def on_enter(self):
"""Highlight layout on enter.
"""
log.debug(
f"Entered row {type(self)} through {self.border_point}")
# don't highlight header row
if getattr(self, 'is_header', None):
self.hovered = False
def on_leave(self):
"""Un-highlight layout on exit.
"""
log.debug(
f"Left row {type(self)} through {self.border_point}")
class TickerTable(GridLayout): class TickerTable(GridLayout):
"""A grid for displaying ticker quote records as a table. """A grid for displaying ticker quote records as a table.