aboutsummaryrefslogtreecommitdiffstats
path: root/tagit/tiles
diff options
context:
space:
mode:
Diffstat (limited to 'tagit/tiles')
-rw-r--r--tagit/tiles/__init__.py57
-rw-r--r--tagit/tiles/browser_tags.py108
-rw-r--r--tagit/tiles/buttons.py50
-rw-r--r--tagit/tiles/cursor_tags.py60
-rw-r--r--tagit/tiles/decoration.kv87
-rw-r--r--tagit/tiles/decoration.py77
-rw-r--r--tagit/tiles/geo.py140
-rw-r--r--tagit/tiles/info.py85
-rw-r--r--tagit/tiles/selection_tags.py60
-rw-r--r--tagit/tiles/tile.kv45
-rw-r--r--tagit/tiles/tile.py85
11 files changed, 854 insertions, 0 deletions
diff --git a/tagit/tiles/__init__.py b/tagit/tiles/__init__.py
new file mode 100644
index 0000000..f51ee2a
--- /dev/null
+++ b/tagit/tiles/__init__.py
@@ -0,0 +1,57 @@
+"""
+
+Part of the tagit module.
+A copy of the license is provided with the project.
+Author: Matthias Baumgartner, 2022
+"""
+# standard imports
+import typing
+
+# tagit imports
+from tagit.utils.builder import BuilderBase
+
+# inner-module imports
+from .browser_tags import BrowserTags
+from .buttons import Buttons
+from .cursor_tags import CursorTags
+#from .entity_histogram import EntityHistogram
+from .geo import Map
+from .info import Info
+#from .libsummary import LibSummary
+#from .searchtree import Searchtree
+from .selection_tags import SelectionTags
+#from .suggested_tags import SuggestedTags
+#from .tag_distribution import TagDistribution
+#from .tag_histogram import TagHistogram
+#from .tag_tree import TagTree
+#from .tagcloud import Tagcloud
+#from .venn import Venn
+
+# exports
+__all__: typing.Sequence[str] = (
+ 'TileBuilder',
+ )
+
+
+## code ##
+
+class TileBuilder(BuilderBase):
+ _factories = {
+ 'BrowserTags': BrowserTags,
+ 'Buttons': Buttons,
+ 'CursorTags': CursorTags,
+# 'EntityHistogram': EntityHistogram,
+ 'Geo': Map,
+ 'Info': Info,
+# 'LibSummary': LibSummary,
+# 'Searchtree': Searchtree,
+ 'SelectionTags': SelectionTags,
+# 'SuggestedTags': SuggestedTags,
+# 'TagDistribution': TagDistribution,
+# 'TagHistogram': TagHistogram,
+# 'TagTree': TagTree,
+# 'Tagcloud': Tagcloud,
+# 'Venn': Venn,
+ }
+
+## EOF ##
diff --git a/tagit/tiles/browser_tags.py b/tagit/tiles/browser_tags.py
new file mode 100644
index 0000000..3a9c25f
--- /dev/null
+++ b/tagit/tiles/browser_tags.py
@@ -0,0 +1,108 @@
+"""
+
+Part of the tagit module.
+A copy of the license is provided with the project.
+Author: Matthias Baumgartner, 2022
+"""
+# standard imports
+from functools import reduce
+import operator
+
+# kivy imports
+from kivy.lang import Builder
+
+# tagit imports
+from tagit.widgets.browser import BrowserAwareMixin
+
+# inner-module imports
+from .tile import TileWithLabel
+
+# exports
+__all__ = ('BrowserTags', )
+
+
+## code ##
+
+# load kv
+Builder.load_string('''
+<BrowserTags>:
+ title: 'Tags'
+ tooltip: 'Tags of displayed items.'
+''')
+
+# classes
+class BrowserTags(TileWithLabel, BrowserAwareMixin):
+ """Show tags of displayed items. Tags of selected items are highlighted."""
+
+ displayed = None
+
+ def on_browser(self, sender, browser):
+ # remove old binding
+ if self.browser is not None:
+ self.browser.unbind(cursor=self.update)
+ self.browser.unbind(selection=self.update)
+ self.browser.unbind(items=self.on_items)
+ # add new binding
+ self.browser = browser
+ if self.browser is not None:
+ self.browser.bind(cursor=self.update)
+ self.browser.bind(selection=self.update)
+ self.browser.bind(items=self.on_items)
+ # populate displayed first, then update
+ self.on_items(browser, browser.items)
+ self.update()
+
+ def __del__(self):
+ if self.browser is not None:
+ self.browser.unbind(cursor=self.update)
+ self.browser.unbind(selection=self.update)
+ self.browser.unbind(items=self.on_items)
+ self.browser = None
+
+ def on_items(self, browser, items):
+ # unfold
+ items = browser.unfold(items)
+ # get tags
+ self.displayed = items.tag.label(node=False)
+ # update view
+ self.update()
+
+ def update(self, *args):
+ if not self.visible:
+ self.text = ''
+
+ elif self.displayed is None:
+ self.on_items(self.root.browser, self.root.browser.items)
+ # calls update again with not-None self.displayed
+
+ else:
+ browser = self.root.browser
+
+ # handle cursor
+ if browser.cursor is None:
+ cursor = set()
+ else:
+ cursor = browser.cursor.tag.label()
+
+ # handle selection
+ if len(browser.selection) == 0:
+ selected = set()
+ else:
+ selection = reduce(operator.add, browser.selection)
+ selected = selection.tag.label(node=False)
+
+ # assemble tag list
+ tags = []
+ for tag in sorted(self.displayed | selected | cursor):
+ pretty = tag
+ if tag in cursor:
+ pretty = f'[b]{pretty}[/b]' # bold
+ if tag in selected:
+ pretty = f'[color=#415bCD]{pretty}[/color]' # blue color
+
+ tags.append(pretty)
+
+ # Apply prefix and display
+ self.text = ', '.join(tags)
+
+## EOF ##
diff --git a/tagit/tiles/buttons.py b/tagit/tiles/buttons.py
new file mode 100644
index 0000000..2a13911
--- /dev/null
+++ b/tagit/tiles/buttons.py
@@ -0,0 +1,50 @@
+"""
+
+Part of the tagit module.
+A copy of the license is provided with the project.
+Author: Matthias Baumgartner, 2022
+
+"""
+# kivy imports
+from kivy.lang import Builder
+import kivy.properties as kp
+
+# inner-module imports
+from .tile import Tile
+
+# exports
+__all__ = ('Buttons', )
+
+## code ##
+
+# load kv
+# NOTE: ButtonDock doesn't need to be imported... why?!
+Builder.load_string('''
+<Buttons>:
+ title: 'Actions'
+ tooltip: 'Some buttons'
+
+ # content
+ slim: False
+ btns: btns
+ ButtonDock:
+ root: root.root
+ orientation: 'lr-tb'
+ id: btns
+ # space between childs
+ spacing: (5, 0) if root.slim else (30, 5)
+ # space between ButtonDock and its children
+ padding: (0, 0) if root.slim else (10, 5)
+''')
+
+# classes
+class Buttons(Tile):
+ """A container for buttons to trigger some action."""
+ buttons = kp.ListProperty()
+
+ def update(self):
+ if self.visible and len(self.btns.children) == 0:
+ self.btns.clear_widgets()
+ self.btns.populate(self.buttons)
+
+## EOF ##
diff --git a/tagit/tiles/cursor_tags.py b/tagit/tiles/cursor_tags.py
new file mode 100644
index 0000000..2ab2f30
--- /dev/null
+++ b/tagit/tiles/cursor_tags.py
@@ -0,0 +1,60 @@
+"""
+
+Part of the tagit module.
+A copy of the license is provided with the project.
+Author: Matthias Baumgartner, 2022
+"""
+# kivy imports
+from kivy.lang import Builder
+
+# tagit imports
+from tagit.widgets.browser import BrowserAwareMixin
+
+# inner-module imports
+from .tile import TileWithLabel
+
+# exports
+__all__ = ('CursorTags', )
+
+
+## code ##
+
+# load kv
+Builder.load_string('''
+<CursorTags>:
+ title: "Cursor's tags"
+ tooltip: 'Tags at the cursor'
+''')
+
+
+# classes
+class CursorTags(TileWithLabel, BrowserAwareMixin):
+ """Show tags of cursor item."""
+
+ def on_browser(self, sender, browser):
+ # remove old binding
+ if self.browser is not None:
+ self.browser.unbind(cursor=self.update)
+ # add new binding
+ self.browser = browser
+ if self.browser is not None:
+ self.browser.bind(cursor=self.update)
+ self.update()
+
+ def __del__(self):
+ if self.browser is not None:
+ self.browser.unbind(cursor=self.update)
+ self.browser = None
+
+ def update(self, *args):
+ cursor = self.root.browser.cursor
+ if not self.visible or cursor is None:
+ # no cursor, nothing to do
+ self.text = ''
+ else:
+ tags = cursor.tag.label()
+ tags = {tag.title() for tag in tags} # nice display
+ tags = sorted(tags)
+ self.text = ', '.join(tags)
+
+## EOF ##
diff --git a/tagit/tiles/decoration.kv b/tagit/tiles/decoration.kv
new file mode 100644
index 0000000..ae7e49d
--- /dev/null
+++ b/tagit/tiles/decoration.kv
@@ -0,0 +1,87 @@
+
+# NOTE:
+# TileDecoration assumes as *cbox* property that identifies the widget
+# to which the main content will be added.
+
+<TileDecorationVanilla>:
+ cbox: cbox
+
+ RelativeLayout:
+ id: cbox
+
+<TileDecorationBorder>:
+ cbox: cbox
+
+ canvas.after:
+ # tile shadow
+ Color:
+ rgb: 0.2,0.2,0.2
+ Line:
+ rectangle: self.x+5,self.y+5,self.width-10,self.height-10
+ width: 2
+
+ Color:
+ rgb: 0.6,0.6,0.6
+ Line:
+ rectangle: self.x+7,self.y+7,self.width-14,self.height-14
+ width: 1
+
+ RelativeLayout:
+ id: cbox
+ pos: 15, 15
+ size: root.width-30, root.height-30
+ size_hint: None, None
+
+<TileDecorationFilledRectangle>:
+ cbox: cbox
+
+ Label:
+ text: root.client.title
+ size: root.width, 20
+ size_hint: None, None
+ pos: 0, root.height - self.height - 5
+
+ RelativeLayout:
+ id: cbox
+ pos: 5, 5
+ size: root.width-10, root.height-30
+ size_hint: None, None
+
+ canvas.before:
+ Color:
+ rgba: 1,0,0,0.5
+ Rectangle:
+ pos: 0, 0
+ size: self.size
+
+
+<TileDecorationRoundedBorder>:
+ cbox: cbox
+
+ Label:
+ text: root.client.title
+ size: root.width, 20
+ size_hint: None, None
+ pos: 0, root.height - self.height - 3
+
+ RelativeLayout:
+ id: cbox
+ pos: 5, 3
+ size: root.width-10, root.height-30
+ size_hint: None, None
+
+ canvas.before:
+ Color:
+ rgb: 0xc5/256, 0xc9/256, 0xc7/256
+ RoundedRectangle:
+ pos: self.pos
+ #radius: [10, 10, 10, 10]
+ size: self.size
+ Color:
+ rgb: 0x1c/256, 0x1b/256, 0x22/256 # FIXME: re-use from MainWindow?
+ RoundedRectangle:
+ pos: self.pos[0] + 2, self.pos[1] + 2
+ radius: [5, 5, 5, 5]
+ size: self.size[0] - 4, self.size[1] - 4
+
+## EOF ##
diff --git a/tagit/tiles/decoration.py b/tagit/tiles/decoration.py
new file mode 100644
index 0000000..c772f64
--- /dev/null
+++ b/tagit/tiles/decoration.py
@@ -0,0 +1,77 @@
+"""
+
+Part of the tagit module.
+A copy of the license is provided with the project.
+Author: Matthias Baumgartner, 2022
+"""
+# standard imports
+import os
+import typing
+
+# kivy imports
+from kivy.lang import Builder
+from kivy.uix.relativelayout import RelativeLayout
+import kivy.properties as kp
+
+# exports
+__all__: typing.Sequence[str] = (
+ 'TileDecorationBorder',
+ 'TileDecorationRoundedBorder',
+ 'TileDecorationFilledRectangle',
+ 'TileDecorationVanilla',
+ )
+
+
+## code ##
+
+# load kv
+Builder.load_file(os.path.join(os.path.dirname(__file__), 'decoration.kv'))
+
+# classes
+class TileDecoration(RelativeLayout):
+
+ cbox = kp.ObjectProperty(None)
+ client = kp.ObjectProperty(None)
+
+ def __repr__(self):
+ return f'{self.__class__.__name__}({self.client})'
+
+ def on_cbox(self, wx, cbox):
+ if cbox is not None and len(cbox.children) == 0:
+ cbox.add_widget(self.client)
+
+ @property
+ def default_size(self):
+ return self.client.default_size
+
+
+class TileDecorationVanilla(TileDecoration):
+ pass
+
+
+class TileDecorationFilledRectangle(TileDecoration):
+ @property
+ def default_size(self):
+ width, height = self.client.default_size
+ width = None if width is None else width + 10
+ height = None if height is None else height + 30
+ return width, height
+
+
+class TileDecorationBorder(TileDecoration):
+ @property
+ def default_size(self):
+ width, height = self.client.default_size
+ width = None if width is None else width + 30
+ height = None if height is None else height + 30
+ return width, height
+
+class TileDecorationRoundedBorder(TileDecoration):
+ @property
+ def default_size(self):
+ width, height = self.client.default_size
+ width = None if width is None else width + 30
+ height = None if height is None else height + 30
+ return width, height
+
+## EOF ##
diff --git a/tagit/tiles/geo.py b/tagit/tiles/geo.py
new file mode 100644
index 0000000..796a1c2
--- /dev/null
+++ b/tagit/tiles/geo.py
@@ -0,0 +1,140 @@
+"""
+
+Part of the tagit module.
+A copy of the license is provided with the project.
+Author: Matthias Baumgartner, 2022
+"""
+# standard imports
+import os
+
+# kivy ipmorts
+from kivy.lang import Builder
+from kivy.uix.label import Label
+import kivy.properties as kp
+
+# tagit imports
+# NOTE: the following line segfaults:
+# mapview.source.py:128:self.dp_tile_size = min(dp(self.tile_size), self.tile_size * 2)
+# setting it to a static value (e.g. 256) works.
+from tagit.external.kivy_garden.mapview import MapView, MapMarkerPopup
+from tagit.utils import ns
+from tagit.widgets.browser import BrowserAwareMixin
+
+# inner-module imports
+from .tile import Tile
+
+# exports
+__all__ = ('Map', )
+
+
+## code ##
+
+Builder.load_string('''
+<Map>:
+ # meta
+ title: "Map"
+ tooltip: 'Location of an item'
+ # content
+ map_: map_
+ MapView:
+ id: map_
+ zoom: 9
+
+<MapLabel>:
+ size: self.texture_size
+ size_hint: None, None
+ padding: 5, 5
+ font_size: '15sp'
+
+ canvas.before:
+ # background
+ Color:
+ rgba: 0,0,0,0.6
+ RoundedRectangle:
+ size: self.size
+ pos: self.pos
+ radius: [10] # keep in sync with the line's radius
+ # border
+ Color:
+ rgba: 0,0,0,1
+ Line:
+ rounded_rectangle: self.x, self.y, self.width, self.height, 10
+''')
+
+class MapLabel(Label):
+ pass
+
+class Map(Tile, BrowserAwareMixin):
+ """Draw a map which indicates visible items' locations."""
+
+ # list of map markers
+ markers = kp.ListProperty()
+
+ def on_browser(self, sender, browser):
+ """Bind to browser properties."""
+ # remove old binding
+ if self.browser is not None:
+ self.browser.unbind(cursor=self.update)
+ self.browser.unbind(items=self.update_markers)
+ # add new binding
+ self.browser = browser
+ if self.browser is not None:
+ self.browser.bind(cursor=self.update)
+ self.browser.bind(items=self.update_markers)
+ # initial calls
+ self.update_markers()
+ self.update()
+
+ def __del__(self):
+ if self.browser is not None:
+ self.browser.unbind(cursor=self.update)
+ self.browser.unbind(items=self.update_markers)
+ self.browser = None
+
+ def update_markers(self, *args):
+ """Draw markers for all browser items."""
+ # remove old markers
+ for mark in self.markers:
+ self.map_.remove_marker(mark)
+ self.markers.clear()
+
+ # get view data
+ data = self.root.browser.unfold(self.root.browser.items).get(
+ ns.bse.filename,
+ ns.bse.latitude,
+ ns.bse.longitude,
+ node=True,
+ )
+
+ # draw new markers
+ for ent, vdict in data.items():
+ if ns.bse.latitude not in vdict:
+ continue
+ if ns.bse.longitude not in vdict:
+ continue
+ # TODO: cluster points, one marker for multiple items
+ lat = vdict[ns.bse.latitude]
+ lon = vdict[ns.bse.longitude]
+ # create popup marker
+ mark = MapMarkerPopup(lat=lat, lon=lon)
+ text = vdict.get(ns.bse.filename,
+ ', '.join(os.path.basename(guid) for guid in ent.guids))
+ mark.add_widget(MapLabel(text=text))
+ # add marker
+ self.markers.append(mark)
+ self.map_.add_marker(mark)
+
+ def update(self, *args):
+ """Focus the map on the cursor."""
+ if not self.visible:
+ return
+
+ cursor = self.root.browser.cursor
+ if cursor is not None:
+ coords = cursor.get(ns.bse.latitude, ns.bse.longitude)
+ if set(coords.keys()) == {ns.bse.latitude, ns.bse.longitude}:
+ lat = coords[ns.bse.latitude]
+ lon = coords[ns.bse.longitude]
+ self.map_.center_on(lat, lon)
+
+## EOF ##
diff --git a/tagit/tiles/info.py b/tagit/tiles/info.py
new file mode 100644
index 0000000..9555b35
--- /dev/null
+++ b/tagit/tiles/info.py
@@ -0,0 +1,85 @@
+"""
+
+Part of the tagit module.
+A copy of the license is provided with the project.
+Author: Matthias Baumgartner, 2022
+"""
+# standard imports
+from collections import OrderedDict
+
+# kivy imports
+from kivy.lang import Builder
+
+# tagit imports
+from tagit.utils import ttime, ns, magnitude_fmt
+from tagit.widgets.browser import BrowserAwareMixin
+from tagit.widgets.session import StorageAwareMixin
+
+# inner-module imports
+from .tile import TileTabular
+
+# exports
+__all__ = ('Info', )
+
+
+## code ##
+
+# load kv
+Builder.load_string('''
+<Info>:
+ title: 'Item info'
+ tooltip: 'Key properties of the cursor item'
+ # assuming 7 info items
+ #default_size: None, 7*self.font_size + 6*5
+ keywidth: min(75, self.width * 0.4)
+''')
+
+
+# classes
+class Info(TileTabular, BrowserAwareMixin, StorageAwareMixin):
+ """Show essential attributes about the cursor."""
+
+ def on_root(self, wx, root):
+ BrowserAwareMixin.on_root(self, wx, root)
+ StorageAwareMixin.on_root(self, wx, root)
+
+ def on_browser(self, sender, browser):
+ # remove old binding
+ if self.browser is not None:
+ self.browser.unbind(cursor=self.update)
+ # add new binding
+ self.browser = browser
+ if self.browser is not None:
+ self.browser.bind(cursor=self.update)
+ self.update()
+
+ def __del__(self):
+ if self.browser is not None:
+ self.browser.unbind(cursor=self.update)
+ self.browser = None
+
+ def on_predicate_modified(self, *args):
+ self.update()
+
+ def update(self, *args):
+ cursor = self.root.browser.cursor
+ if not self.visible or cursor is None:
+ # invisible or no cursor, nothing to show
+ self.tabledata = OrderedDict({})
+
+ else:
+ preds = cursor.get(
+ ns.bsfs.Node().t_created,
+ ns.bse.filesize,
+ ns.bse.filename,
+ (ns.bse.tag, ns.bst.label),
+ )
+ self.tabledata = OrderedDict({
+ 'Date' : ttime.from_timestamp_utc(
+ preds.get(ns.bsfs.Node().t_created, ttime.timestamp_min)).strftime('%d.%m.%y %H:%M'),
+ 'Filesize' : magnitude_fmt(preds.get(ns.bse.filesize, 0)),
+ 'Filename' : preds.get(ns.bse.filename, 'n/a'),
+ 'Tags' : ', '.join(sorted(preds.get((ns.bse.tag, ns.bst.label), [' ']))),
+ })
+
+## EOF ##
diff --git a/tagit/tiles/selection_tags.py b/tagit/tiles/selection_tags.py
new file mode 100644
index 0000000..7951cfe
--- /dev/null
+++ b/tagit/tiles/selection_tags.py
@@ -0,0 +1,60 @@
+"""
+
+Part of the tagit module.
+A copy of the license is provided with the project.
+Author: Matthias Baumgartner, 2022
+"""
+# kivy imports
+from kivy.lang import Builder
+
+# tagit imports
+from tagit.widgets.browser import BrowserAwareMixin
+
+# inner-module imports
+from .tile import TileWithLabel
+
+# exports
+__all__ = ('SelectionTags', )
+
+
+## code ##
+
+# load kv
+Builder.load_string('''
+<SelectionTags>:
+ title: "Selection's tags"
+ default_size: None, 50
+''')
+
+# classes
+class SelectionTags(TileWithLabel, BrowserAwareMixin):
+ """Show tags of selected items."""
+
+ def on_browser(self, sender, browser):
+ # remove old binding
+ if self.browser is not None:
+ self.browser.unbind(selection=self.update)
+ # add new binding
+ self.browser = browser
+ if self.browser is not None:
+ self.browser.bind(selection=self.update)
+ self.update()
+
+ def __del__(self):
+ if self.browser is not None:
+ self.browser.unbind(selection=self.update)
+ self.browser = None
+
+ def update(self, *args):
+ browser = self.root.browser
+ selection = browser.unfold(browser.selection)
+ if not self.visible or len(selection) == 0:
+ # nothing selected, nothing to do
+ self.text = ''
+ else:
+ tags = selection.tag.label(node=False)
+ tags = {tag.title() for tag in tags} # nice display
+ tags = sorted(tags)
+ self.text = ', '.join(tags)
+
+## EOF ##
diff --git a/tagit/tiles/tile.kv b/tagit/tiles/tile.kv
new file mode 100644
index 0000000..fcd9821
--- /dev/null
+++ b/tagit/tiles/tile.kv
@@ -0,0 +1,45 @@
+
+<Tile>:
+ title: ''
+ tooltip: ''
+ default_size: None, None
+
+<TileTabular>:
+ # config
+ font_size: sp(15)
+ keywidth: 0.5
+
+ # table
+ rows: rows
+ TileTabularLine:
+ id: rows
+ orientation: 'tb-lr'
+ size_hint: 1, 1
+
+<TileTabularLine@StackLayout>:
+ spacing: 10
+
+<TileTabularRow>:
+ orientation: 'horizontal'
+ size_hint: 1, None
+ height: self.minimum_height
+ spacing: 10
+
+<TileTabularCell>:
+ valign: 'top'
+ height: self.texture_size[1]
+ text_size: self.width, None
+
+<TileWithLabel>:
+ text: ''
+ text_align: 'left', 'top'
+ font_size: sp(15)
+ Label:
+ text: root.text
+ markup: True
+ text_size: root.size
+ font_size: root.font_size
+ halign: root.text_align[0]
+ valign: root.text_align[1]
+
+## EOF ##
diff --git a/tagit/tiles/tile.py b/tagit/tiles/tile.py
new file mode 100644
index 0000000..981d45b
--- /dev/null
+++ b/tagit/tiles/tile.py
@@ -0,0 +1,85 @@
+"""
+
+Part of the tagit module.
+A copy of the license is provided with the project.
+Author: Matthias Baumgartner, 2022
+"""
+# standard imports
+import os
+
+# kivy imports
+from kivy.lang import Builder
+from kivy.uix.boxlayout import BoxLayout
+from kivy.uix.label import Label
+from kivy.uix.relativelayout import RelativeLayout
+import kivy.properties as kp
+
+# exports
+__all__ = ('Tile', 'TileWithLabel', 'TileTabular')
+
+
+## code ##
+
+# load kv
+Builder.load_file(os.path.join(os.path.dirname(__file__), 'tile.kv'))
+
+# classes
+class Tile(RelativeLayout):
+ visible = kp.BooleanProperty(False)
+ root = kp.ObjectProperty(None)
+
+ def on_visible(self, wx, visible):
+ if visible:
+ self.update()
+
+ def update(self, *args, **kwargs):
+ abstract()
+
+
+class TileWithLabel(Tile):
+ pass
+
+class TileTabularRow(BoxLayout):
+ pass
+
+class TileTabularCell(Label):
+ pass
+
+class TileTabular(Tile):
+
+ tabledata = kp.ObjectProperty()
+ keywidth = kp.NumericProperty(0.5)
+
+ def on_tabledata(self, wx, data):
+ # set items
+ self.rows.clear_widgets()
+ for t_key, t_value in data.items():
+ # row
+ row = TileTabularRow()
+ # left column (keys)
+ key = TileTabularCell(
+ text=t_key,
+ halign='right',
+ font_size = self.font_size,
+ size_hint=(None, 1),
+ width=self.width * self.keywidth if self.keywidth < 1 else self.keywidth,
+ )
+ # right column (values)
+ value = TileTabularCell(
+ text=str(t_value),
+ halign='left',
+ font_size = self.font_size,
+ size_hint=(1, None),
+ )
+ # adjust key's width and height dynamically.
+ # value's width and height are adjusted automatically
+ self.bind(width=lambda wx, width, key=key: setattr(key, 'width',
+ width * self.keywidth if self.keywidth < 1 else self.keywidth))
+ key.bind(height=lambda wx, height, key=key: setattr(key, 'text_size',
+ (key.width, height)))
+ # add widgets
+ row.add_widget(key)
+ row.add_widget(value)
+ self.rows.add_widget(row)
+
+## EOF ##