Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/src/jarabe/journal/browse/smoothtable.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/jarabe/journal/browse/smoothtable.py')
-rw-r--r--src/jarabe/journal/browse/smoothtable.py111
1 files changed, 89 insertions, 22 deletions
diff --git a/src/jarabe/journal/browse/smoothtable.py b/src/jarabe/journal/browse/smoothtable.py
index 8962a11..c797745 100644
--- a/src/jarabe/journal/browse/smoothtable.py
+++ b/src/jarabe/journal/browse/smoothtable.py
@@ -28,7 +28,7 @@ class SmoothTable(gtk.Container):
[gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT]),
}
- def __init__(self, rows, columns, new_widget):
+ def __init__(self, rows, columns, new_cell, fill_in):
assert(rows and columns)
self._rows = []
@@ -39,20 +39,22 @@ class SmoothTable(gtk.Container):
self._cell_height = 0
self._reordered = None
self._last_allocation = None
+ self._fill_in = fill_in
gtk.Container.__init__(self)
- cell_no = 0
for y in range(rows + 2):
row = []
for x in range(columns):
- cell = new_widget()
+ cell = new_cell()
+ cell.show()
cell.set_parent(self)
cell.size_allocate(gtk.gdk.Rectangle(-1, -1))
- cell_no += 1
row.append(cell)
self._rows.append(row)
+ self.connect('key-press-event', self.__key_press_event_cb)
+
def get_columns(self):
return len(self._rows[0])
@@ -63,15 +65,19 @@ class SmoothTable(gtk.Container):
rows = property(get_rows)
- def get_head(self):
- if self._adj is None:
- return 0
- return int(self._adj.value) - int(self._adj.value) % self._cell_height
+ def get_frame(self):
+ if self._adj is None or self._cell_height == 0:
+ return (0, 0)
+ top = int(self._adj.value / self._cell_height)
+ return (top * self.columns, (top + self.rows) * self.columns - 1)
+
+ frame = property(get_frame)
- head = property(get_head)
+ def get_bin_rows(self):
+ return self._bin_rows
- def set_count(self, count):
- self._bin_rows = max(0, math.ceil(float(count) / len(self._rows[0])))
+ def set_bin_rows(self, bin_rows):
+ self._bin_rows = bin_rows
if self._adj is not None:
self._setup_adjustment(force=True)
@@ -79,6 +85,14 @@ class SmoothTable(gtk.Container):
self._bin_window.resize(self.allocation.width,
int(self._adj.upper))
+ bin_rows = property(get_bin_rows, set_bin_rows)
+
+ def goto(self, row):
+ if self._adj is None:
+ return
+ self._adj.props.value = row * self._cell_height
+ self._adj.value_changed()
+
def do_realize(self):
self.set_flags(gtk.REALIZED)
@@ -208,9 +222,10 @@ class SmoothTable(gtk.Container):
def _allocate_row(self, row, cell_y):
cell_x = 0
cell_no = cell_y / self._cell_height * self.columns
+ cell_row = cell_y / self._cell_height
- for cell in row:
- self.emit('fill-in', cell, cell_no)
+ for cell_column, cell in enumerate(row):
+ self._fill_in(cell, cell_row, cell_column)
callocation = gtk.gdk.Rectangle(cell_x, cell_y)
callocation.width = self.allocation.width / self.columns
@@ -220,8 +235,24 @@ class SmoothTable(gtk.Container):
cell_x += callocation.width
cell_no += 1
+ def _get_head(self):
+ if self._adj is None:
+ return 0
+ return int(self._adj.value) - int(self._adj.value) % self._cell_height
+
def __adjustment_value_changed_cb(self, sender=None):
- if not self.flags() & gtk.REALIZED:
+ if not self.flags() & gtk.REALIZED or self._cell_height == 0:
+ return
+
+ if self._adj.value < 0:
+ self._adj.value = 0
+ self._adj.value_changed()
+ return
+
+ bottom = self._adj.upper - (self.rows * self._cell_height)
+ if self._adj.value > bottom:
+ self._adj.value = bottom
+ self._adj.value_changed()
return
spare_rows = []
@@ -248,8 +279,8 @@ class SmoothTable(gtk.Container):
else:
bisect.insort_right(visible_rows, IndexedRow(row))
- if not visible_rows or \
- len(visible_rows) < self.rows + (self.head != visible_rows[0]):
+ if not visible_rows or len(visible_rows) < self.rows + \
+ (self._get_head() != visible_rows[0]):
self._reordered = self.allocation
def insert_spare_row(cell_y, end_y):
@@ -261,7 +292,7 @@ class SmoothTable(gtk.Container):
self._allocate_row(row, cell_y)
cell_y = cell_y + self._cell_height
- cell_y = self.head
+ cell_y = self._get_head()
for i in visible_rows:
insert_spare_row(cell_y, i.row[0].allocation.y)
cell_y = i.row[0].allocation.y + i.row[0].allocation.height
@@ -270,21 +301,57 @@ class SmoothTable(gtk.Container):
self._bin_window.move(0, int(-self._adj.value))
self.window.process_updates(True)
+ def __key_press_event_cb(self, widget, event):
+ if self._adj is None or self._cell_height == 0:
+ return
+
+ page = self.rows * self._cell_height
+ uplimit = self._adj.upper - page
+
+ if event.keyval == gtk.keysyms.Up:
+ self._adj.value -= self._cell_height
+
+ elif event.keyval == gtk.keysyms.Down:
+ self._adj.value += min(uplimit - self._adj.value, self._cell_height)
+
+ elif event.keyval in (gtk.keysyms.Page_Up, gtk.keysyms.KP_Page_Up):
+ self._adj.value -= min(self._adj.value, page)
+
+ elif event.keyval in (gtk.keysyms.Page_Down, gtk.keysyms.KP_Page_Down):
+ self._adj.value += min(uplimit - self._adj.value, page)
+
+ elif event.keyval in (gtk.keysyms.Home, gtk.keysyms.KP_Home):
+ self._adj.value = 0
+
+ elif event.keyval in (gtk.keysyms.End, gtk.keysyms.KP_End):
+ self._adj.value = uplimit
+
+ else:
+ return False
+
+ return True
+
SmoothTable.set_set_scroll_adjustments_signal('set-scroll-adjustments')
if __name__ == '__main__':
+ import random
+
window = gtk.Window()
scrolled = gtk.ScrolledWindow()
scrolled.set_policy(gtk.POLICY_ALWAYS, gtk.POLICY_ALWAYS)
window.add(scrolled)
- def cb(sender, button, offset):
- button.props.label = str(offset)
- table = SmoothTable(3, 3, gtk.Button)
- table.connect('fill-in', cb)
- table.set_count(100)
+ def fill_in(cell, row, column):
+ cell.props.label = '%s:%s' % (row, column)
+ table = SmoothTable(3, 3, gtk.Button, fill_in)
+ table.bin_rows = 100
scrolled.add(table)
+ for row in table._rows:
+ for cell in row:
+ cell.connect('clicked',
+ lambda button: table.goto(random.randint(0, 100)))
+
window.show_all()
gtk.main()