aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Baumgartner <dev@igsor.net>2023-01-07 16:26:26 +0100
committerMatthias Baumgartner <dev@igsor.net>2023-01-07 16:26:26 +0100
commit37f1ac3f456b6677d9ce14274f3987ccda752f03 (patch)
tree23b93bcb1eb04300ffce2e73d8017937d95ffdca
parent3aebfcba6afd5a882f02e55e442580fe0290c776 (diff)
downloadtagit-37f1ac3f456b6677d9ce14274f3987ccda752f03.tar.gz
tagit-37f1ac3f456b6677d9ce14274f3987ccda752f03.tar.bz2
tagit-37f1ac3f456b6677d9ce14274f3987ccda752f03.zip
browser and misc actions
-rw-r--r--.gitignore3
-rw-r--r--tagit/actions/__init__.py60
-rw-r--r--tagit/actions/action.kv45
-rw-r--r--tagit/actions/action.py257
-rw-r--r--tagit/actions/browser.kv99
-rw-r--r--tagit/actions/browser.py628
-rw-r--r--tagit/actions/misc.py3
-rw-r--r--tagit/apps/port-config.yaml6
-rw-r--r--tagit/assets/icons/kivy/browser-0.pngbin0 -> 7317 bytes
-rw-r--r--tagit/assets/icons/kivy/browser.atlas1
-rw-r--r--tagit/assets/icons/scalable/README5
-rw-r--r--tagit/assets/icons/scalable/browser/cursor_down.svg164
-rw-r--r--tagit/assets/icons/scalable/browser/cursor_first.svg155
-rw-r--r--tagit/assets/icons/scalable/browser/cursor_last.svg154
-rw-r--r--tagit/assets/icons/scalable/browser/cursor_left.svg159
-rw-r--r--tagit/assets/icons/scalable/browser/cursor_right.svg163
-rw-r--r--tagit/assets/icons/scalable/browser/cursor_up.svg163
-rw-r--r--tagit/assets/icons/scalable/browser/next_page.svg164
-rw-r--r--tagit/assets/icons/scalable/browser/previous_page.svg164
-rw-r--r--tagit/assets/icons/scalable/browser/scroll_down.svg147
-rw-r--r--tagit/assets/icons/scalable/browser/scroll_up.svg147
-rw-r--r--tagit/assets/icons/scalable/browser/select.svg291
-rw-r--r--tagit/assets/icons/scalable/browser/select_add.svg169
-rw-r--r--tagit/assets/icons/scalable/browser/select_all.svg158
-rw-r--r--tagit/assets/icons/scalable/browser/select_invert.svg255
-rw-r--r--tagit/assets/icons/scalable/browser/select_multi.svg158
-rw-r--r--tagit/assets/icons/scalable/browser/select_none.svg158
-rw-r--r--tagit/assets/icons/scalable/browser/select_range.svg312
-rw-r--r--tagit/assets/icons/scalable/browser/select_single.svg158
-rw-r--r--tagit/assets/icons/scalable/browser/select_sub.svg162
-rw-r--r--tagit/assets/icons/scalable/browser/zoom_in.svg241
-rw-r--r--tagit/assets/icons/scalable/browser/zoom_out.svg241
-rw-r--r--tagit/config/port-config.yaml115
-rw-r--r--tagit/utils/shared.py17
34 files changed, 4972 insertions, 150 deletions
diff --git a/.gitignore b/.gitignore
index cbef470..f9c6fcf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,6 +32,9 @@ tagit/external/setproperty/setproperty.c
tagit/external/setproperty/setproperty.cpython*
# assets
+tagit/assets/icons/kivy/browser/
+tagit/assets/icons/kivy/misc/
+tagit/assets/icons/kivy/planes/
## EOF ##
diff --git a/tagit/actions/__init__.py b/tagit/actions/__init__.py
index ecff701..876ca1f 100644
--- a/tagit/actions/__init__.py
+++ b/tagit/actions/__init__.py
@@ -11,7 +11,7 @@ import typing
from tagit.utils.builder import BuilderBase
# inner-module imports
-#from . import browser
+from . import browser
from . import filter
from . import grouping
#from . import library
@@ -32,30 +32,30 @@ __all__: typing.Sequence[str] = (
class ActionBuilder(BuilderBase):
_factories = {
## browser
- #'NextPage': browser.NextPage,
- #'PreviousPage': browser.PreviousPage,
- #'ScrollDown': browser.ScrollDown,
- #'ScrollUp': browser.ScrollUp,
- #'JumpToPage': browser.JumpToPage,
- #'SetCursor': browser.SetCursor,
- #'ZoomIn': browser.ZoomIn,
- #'ZoomOut': browser.ZoomOut,
- #'JumpToCursor': browser.JumpToCursor,
- #'MoveCursorFirst': browser.MoveCursorFirst,
- #'MoveCursorLast': browser.MoveCursorLast,
- #'MoveCursorUp': browser.MoveCursorUp,
- #'MoveCursorDown': browser.MoveCursorDown,
- #'MoveCursorLeft': browser.MoveCursorLeft,
- #'MoveCursorRight': browser.MoveCursorRight,
- #'SelectRange': browser.SelectRange,
- #'SelectAdditive': browser.SelectAdditive,
- #'SelectSubtractive': browser.SelectSubtractive,
- #'SelectMulti': browser.SelectMulti,
- #'SelectSingle': browser.SelectSingle,
- #'SelectAll': browser.SelectAll,
- #'SelectNone': browser.SelectNone,
- #'SelectInvert': browser.SelectInvert,
- #'Select': browser.Select,
+ 'NextPage': browser.NextPage,
+ 'PreviousPage': browser.PreviousPage,
+ 'ScrollDown': browser.ScrollDown,
+ 'ScrollUp': browser.ScrollUp,
+ 'JumpToPage': browser.JumpToPage,
+ 'SetCursor': browser.SetCursor,
+ 'ZoomIn': browser.ZoomIn,
+ 'ZoomOut': browser.ZoomOut,
+ 'JumpToCursor': browser.JumpToCursor,
+ 'MoveCursorFirst': browser.MoveCursorFirst,
+ 'MoveCursorLast': browser.MoveCursorLast,
+ 'MoveCursorUp': browser.MoveCursorUp,
+ 'MoveCursorDown': browser.MoveCursorDown,
+ 'MoveCursorLeft': browser.MoveCursorLeft,
+ 'MoveCursorRight': browser.MoveCursorRight,
+ 'SelectRange': browser.SelectRange,
+ 'SelectAdditive': browser.SelectAdditive,
+ 'SelectSubtractive': browser.SelectSubtractive,
+ 'SelectMulti': browser.SelectMulti,
+ 'SelectSingle': browser.SelectSingle,
+ 'SelectAll': browser.SelectAll,
+ 'SelectNone': browser.SelectNone,
+ 'SelectInvert': browser.SelectInvert,
+ 'Select': browser.Select,
## filter
#'AddToken': filter.AddToken,
#'RemoveToken': filter.RemoveToken,
@@ -84,14 +84,14 @@ class ActionBuilder(BuilderBase):
#'SyncObjects': library.SyncObjects,
#'ItemExport': library.ItemExport,
## misc
- #'ShellDrop': misc.ShellDrop,
- #'OpenExternal': misc.OpenExternal,
- #'Menu': misc.Menu,
+ 'ShellDrop': misc.ShellDrop,
+ 'OpenExternal': misc.OpenExternal,
+ 'Menu': misc.Menu,
'ShowConsole': misc.ShowConsole,
'ShowHelp': misc.ShowHelp,
'ShowSettings': misc.ShowSettings,
- #'ClipboardCopy': misc.ClipboardCopy,
- #'ClipboardPaste': misc.ClipboardPaste,
+ 'ClipboardCopy': misc.ClipboardCopy,
+ 'ClipboardPaste': misc.ClipboardPaste,
## objects
#'RotateLeft': objects.RotateLeft,
#'RotateRight': objects.RotateRight,
diff --git a/tagit/actions/action.kv b/tagit/actions/action.kv
new file mode 100644
index 0000000..5352964
--- /dev/null
+++ b/tagit/actions/action.kv
@@ -0,0 +1,45 @@
+
+<Action>:
+ # internas
+ orientation: 'horizontal'
+
+ # responsiveness
+ # *touch_trigger* is enabled automatically if an image or text is shown.
+ # If that is undesired, *touch_trigger* has to be disabled **after** the
+ # declaration of *show*.
+ key_trigger: True
+ touch_trigger: False
+
+ # size
+ # By default the width expands as necessary. To get a fixed width,
+ # set the width manually or via size_hint_x and set *autowidth* to False.
+ # If something is shown, *height* is automatically set to *default_height*
+ # unless specified otherwise in by the caller.
+ default_height: 30
+ size: 0, 0
+ size_hint: None, None
+ autowidth: True
+
+ # behaviour
+ # The default is that no buttons are shown and touch triggers are disabled.
+ # NOTE: Callers need to declare show **last** to ensure that all other
+ # properties are set. The only exception is *touch_trigger* which has
+ # to be disabled **after** show.
+ show: []
+
+ # decoration
+ canvas.before:
+ Color:
+ rgba: 17 / 255, 32 / 255, 148 / 255, self.selected_alpha
+ Rectangle:
+ pos: self.x, self.y + 1
+ size: self.size
+
+ canvas.after:
+ Color:
+ rgba: 17 / 255, 32 / 255, 148 / 255, self.selected_alpha
+ Line:
+ width: 2
+ rectangle: self.x, self.y, self.width, self.height
+
+ ## EOF ##
diff --git a/tagit/actions/action.py b/tagit/actions/action.py
new file mode 100644
index 0000000..e8866ce
--- /dev/null
+++ b/tagit/actions/action.py
@@ -0,0 +1,257 @@
+"""Button for proxy actions.
+
+Part of the tagit module.
+A copy of the license is provided with the project.
+Author: Matthias Baumgartner, 2022
+"""
+# standard imports
+import logging
+import os
+
+# kivy imports
+from kivy import metrics
+from kivy.animation import Animation
+from kivy.lang import Builder
+from kivy.uix.behaviors import ButtonBehavior
+from kivy.uix.boxlayout import BoxLayout
+from kivy.uix.image import Image
+from kivy.uix.label import Label
+import kivy.properties as kp
+
+# tagit imports
+from tagit.external.tooltip import Tooltip
+
+# exports
+__all__ = ('Action', )
+
+
+## code ##
+
+logger = logging.getLogger(__name__)
+
+# load kv
+Builder.load_file(os.path.join(os.path.dirname(__file__), 'action.kv'))
+
+class Action(ButtonBehavior, BoxLayout, Tooltip):
+ """
+
+ An Action can be triggered in three ways:
+ * Touch event: Clicking or touching on the button
+ * Key event: Entering a keyboard shortcut
+ * Single-shot: Programmatically triggered once, without UI attachment
+
+ For the last, use the *single_shot* classmethod.
+
+ For the first two, declare the Action in a kv file or in code.
+ Note that the remarks below about kv do not apply if the object is
+ created in code.
+
+
+ When an Action is declared in kv, two restrictions apply (also see
+ examples below):
+ * To disable touch_trigger, it must be declared last
+ * show must be declared after all other properties
+
+ Enable key triggers, but hide the Action in the UI:
+ Action:
+ show: []
+
+ Action:
+ # alias for the one above
+
+ Show text, image, or both, with default height and the width
+ stretched as necessary:
+ Action:
+ show: 'text',
+
+ Action:
+ show: 'image',
+
+ Action:
+ show: 'text', 'image'
+
+ Action:
+ width: 200 # has no effect unless autowidth is False
+ show: 'image', 'text'
+
+ Make the Action larger:
+ Action:
+ # increased height. The image width scales accordingly
+ height: 80
+ show: 'image', 'text'
+
+ Action:
+ # scales to parent widget's width
+ autowidth: False
+ size_hint_x: 1
+ show: 'image', 'text'
+
+ Action:
+ # fixed width and height
+ width: 150
+ height: 80
+ autowidth: False
+ show: 'image', 'text' # must be declared **last**
+
+ Show the button but disable touch events:
+ Action:
+ height: 80
+ show: 'image', 'text'
+ touch_trigger: False # must be declared **after** show
+
+ Do the same in code:
+ >>> Action(
+ ... size=(130, 80),
+ ... autowidth=False,
+ ... show=('image', 'text'),
+ ... text='foobar',
+ ... touch_trigger=False)
+
+ """
+ # content
+ tooltip = kp.StringProperty()
+ source = kp.StringProperty()
+ text = kp.StringProperty()
+
+ # visibility flags
+ show = kp.ListProperty([])
+
+ # sizing
+ default_height = kp.NumericProperty(30)
+ autowidth = kp.BooleanProperty(True)
+
+ # responsiveness
+ key_trigger = kp.BooleanProperty(True)
+ touch_trigger = kp.BooleanProperty(True)
+
+ # required such that properties can be set via constructor
+ font_size = kp.StringProperty("15sp")
+ # FIXME: Check why I have to pass size instead of height/width
+ height = kp.NumericProperty(0)
+ width = kp.NumericProperty(0)
+
+ # internal properties
+ root = kp.ObjectProperty(None)
+ selected_alpha = kp.NumericProperty(0)
+ _image = kp.ObjectProperty(None)
+ _label = kp.ObjectProperty(None)
+
+ def __init__(self, **kwargs):
+ show = kwargs.pop('show', [])
+ touch_trigger = kwargs.pop('touch_trigger', None)
+ super(Action, self).__init__(**kwargs)
+ # delay such that on_show is executed once the other
+ # properties are set
+ self.show = show
+ if touch_trigger is not None:
+ self.touch_trigger = touch_trigger
+
+ ## display
+
+ def on_show(self, wx, show):
+ if self._image is not None:
+ self.remove_widget(self._image)
+ if self._label is not None:
+ self.remove_widget(self._label)
+
+ if 'image' in show:
+ self.height = self.default_height if self.height == 0 else self.height
+ self.touch_trigger = True
+ self._image = Image(
+ source=self.source,
+ # size
+ height=self.height,
+ width=self.height, # square image
+ size_hint=(None, None),
+ )
+ self.add_widget(self._image)
+ if self.autowidth:
+ self.width = self.height
+ if 'text' in show:
+ self.height = self.default_height if self.height == 0 else self.height
+ self.touch_trigger = True
+ self._label = Label(
+ # text
+ text=self.text,
+ halign='left',
+ valign='middle',
+ padding=(metrics.dp(10), 0),
+ # size
+ font_size=self.font_size,
+ height=self.height,
+ size_hint=(None, None),
+ )
+ self._label.bind(texture_size=self.on_texture_size)
+ self.add_widget(self._label)
+
+ def on_size(self, wx, size):
+ for child in self.children:
+ child.height = self.height
+ if isinstance(child, Image):
+ child.width = self.height
+ elif not self.autowidth: # must be the label
+ self.on_texture_size(child, None)
+
+ def on_texture_size(self, label, texture_size):
+ if self.autowidth:
+ # adapt the width to the label's width
+ self.width = max(0, sum([child.width for child in self.children]))
+ else:
+ # adapt the label's width
+ others = sum([child.width for child in self.children if child != label])
+ label.width = self.width - others
+ label.height = self.height
+ label.text_size = (self.width - others, self.height)
+
+ def on_tooltip(self, callee, text):
+ self.set_tooltip(text)
+
+
+ ## properties
+
+ @property
+ def cfg(self):
+ return self.root.session.cfg
+
+
+ ## action triggering
+
+ @classmethod
+ def single_shot(cls, root, *args, **kwargs):
+ #logger.info(f'action: {cls.__name__}, {args}, {kwargs}')
+ root.action_log.append(str(cls.__name__))
+ return cls(root=root).apply(*args, **kwargs)
+
+ def on_root(self, wx, root):
+ root.keys.bind(on_press=self.on_keyboard)
+
+ def on_press(self):
+ self.selected_alpha = 1
+
+ def on_release(self):
+ if self.touch_trigger:
+ Animation(selected_alpha=0, d=.25, t='out_quad').start(self)
+ #logger.info(f'action: {type(self).__name__}')
+ self.root.action_log.append(str(type(self).__name__))
+ self.apply()
+
+ def on_keyboard(self, wx, evt):
+ if self.key_trigger and self.ktrigger(evt):
+ #logger.info(f'action: {type(self).__name__}')
+ self.root.action_log.append(str(type(self).__name__))
+ self.apply()
+ # stop the event from further processing
+ return True
+
+
+ ## interfaces for subtypes
+
+ def ktrigger(self, evt):
+ """Return True if the action should be triggered by keyboard event *evt*."""
+ return False
+
+ def apply(self, *args, **kwargs):
+ """Execute the action."""
+ pass
+
+## EOF ##
diff --git a/tagit/actions/browser.kv b/tagit/actions/browser.kv
new file mode 100644
index 0000000..adcfbd6
--- /dev/null
+++ b/tagit/actions/browser.kv
@@ -0,0 +1,99 @@
+#:import resource_find kivy.resources.resource_find
+
+<NextPage>:
+ source: resource_find('atlas://browser/next_page')
+ tooltip: 'One page down'
+
+<PreviousPage>:
+ source: resource_find('atlas://browser/previous_page')
+ tooltip: 'One page up'
+
+<ScrollUp>:
+ source: resource_find('atlas://browser/scroll_up')
+ tooltip: 'One row up'
+
+<ScrollDown>:
+ source: resource_find('atlas://browser/scroll_down')
+ tooltip: 'One row down'
+
+<JumpToPage>:
+ source: resource_find('atlas://browser/jump_to_page')
+ tooltip: 'Jump to a specified page'
+
+<ZoomIn>:
+ source: resource_find('atlas://browser/zoom_in')
+ tooltip: 'Zoom in'
+
+<ZoomOut>:
+ source: resource_find('atlas://browser/zoom_out')
+ tooltip: 'Zoom out'
+
+<JumpToCursor>:
+ source: resource_find('atlas://browser/jump_to_cursor')
+ tooltip: 'Jump to cursor'
+
+<SetCursor>:
+ source: resource_find('atlas://browser/set_cursor')
+ tooltip: 'Set the cursor'
+
+<MoveCursorFirst>:
+ source: resource_find('atlas://browser/cursor_first')
+ tooltip: 'Go to first image'
+
+<MoveCursorLast>:
+ source: resource_find('atlas://browser/cursor_last')
+ tooltip: 'Go to last image'
+
+<MoveCursorUp>:
+ source: resource_find('atlas://browser/cursor_up')
+ tooltip: 'Cursor up'
+
+<MoveCursorDown>:
+ source: resource_find('atlas://browser/cursor_down')
+ tooltip: 'Cursor down'
+
+<MoveCursorLeft>:
+ source: resource_find('atlas://browser/cursor_left')
+ tooltip: 'Cursor left'
+
+<MoveCursorRight>:
+ source: resource_find('atlas://browser/cursor_right')
+ tooltip: 'Cursor right'
+
+<SelectAll>:
+ source: resource_find('atlas://browser/select_all')
+ tooltip: 'Select all'
+
+<SelectNone>:
+ source: resource_find('atlas://browser/select_none')
+ tooltip: 'Clear selection'
+
+<SelectInvert>:
+ source: resource_find('atlas://browser/select_invert')
+ tooltip: 'Invert selection'
+
+<SelectSingle>:
+ source: resource_find('atlas://browser/select_single')
+ tooltip: 'Select one'
+
+<SelectMulti>:
+ source: resource_find('atlas://browser/select_multi')
+ tooltip: 'Select many'
+
+<SelectAdditive>:
+ source: resource_find('atlas://browser/select_add')
+ tooltip: 'Add to selection'
+
+<SelectSubtractive>:
+ source: resource_find('atlas://browser/select_sub')
+ tooltip: 'Remove from selection'
+
+<SelectRange>:
+ source: resource_find('atlas://browser/select_range')
+ tooltip: 'Select range'
+
+<Select>:
+ source: resource_find('atlas://browser/select')
+ tooltip: 'Select/deselect an item'
+
+## EOF ##
diff --git a/tagit/actions/browser.py b/tagit/actions/browser.py
new file mode 100644
index 0000000..2eaead8
--- /dev/null
+++ b/tagit/actions/browser.py
@@ -0,0 +1,628 @@
+"""
+
+Part of the tagit module.
+A copy of the license is provided with the project.
+Author: Matthias Baumgartner, 2022
+"""
+# standard imports
+import math
+import os
+
+# kivy imports
+from kivy.lang import Builder
+import kivy.properties as kp
+
+# tagit imports
+from tagit import config, dialogues
+from tagit.utils import clamp
+from tagit.widgets import Binding
+
+# inner-module imports
+from .action import Action
+
+# exports
+__all__ = []
+
+
+## code ##
+
+# load kv
+Builder.load_file(os.path.join(os.path.dirname(__file__), 'browser.kv'))
+
+# classes
+
+class NextPage(Action):
+ """Scroll one page downwards without moving the cursor."""
+ text = kp.StringProperty('Next page')
+
+ def ktrigger(self, evt):
+ return Binding.check(evt, self.cfg('bindings', 'browser', 'page_next'))
+
+ def apply(self):
+ with self.root.browser as browser:
+ browser.offset = clamp(browser.offset + browser.page_size, browser.max_offset)
+
+
+class PreviousPage(Action):
+ """Scroll one page upwards without moving the cursor."""
+ text = kp.StringProperty('Previous page')
+ def ktrigger(self, evt):
+ return Binding.check(evt, self.cfg('bindings', 'browser', 'page_prev'))
+
+ def apply(self):
+ with self.root.browser as browser:
+ browser.offset = max(browser.offset - browser.page_size, 0)
+
+
+class ScrollUp(Action):
+ """Scroll one row up without moving the cursor."""
+ text = kp.StringProperty('Scroll up')
+
+ def ktrigger(self, evt):
+ return Binding.check(evt, self.cfg('bindings', 'browser', 'scroll_up'))
+
+ def on_touch_down(self, touch):
+ scrollcfg = self.cfg('ui', 'standalone', 'browser', 'scroll')
+ scrolldir = 'scrolldown' if scrollcfg == 'mouse' else 'scrollup'
+ if self.root.browser.collide_point(*touch.pos) \
+ and not self.root.keys.ctrl_pressed:
+ if touch.button == scrolldir:
+ self.apply()
+ return super(ScrollUp, self).on_touch_down(touch)
+
+ def apply(self):
+ with self.root.browser as browser:
+ browser.offset = clamp(browser.offset - browser.cols, browser.max_offset)
+
+
+class ScrollDown(Action):
+ """Scroll one row down without moving the cursor."""
+ text = kp.StringProperty('Scroll down')
+
+ def ktrigger(self, evt):
+ return Binding.check(evt, self.cfg('bindings', 'browser', 'scroll_down'))
+
+ def on_touch_down(self, touch):
+ scrollcfg = self.cfg('ui', 'standalone', 'browser', 'scroll')
+ scrolldir = 'scrollup' if scrollcfg == 'mouse' else 'scrolldown'
+ if self.root.browser.collide_point(*touch.pos) \
+ and not self.root.keys.ctrl_pressed:
+ if touch.button == scrolldir:
+ self.apply()
+ return super(ScrollDown, self).on_touch_down(touch)
+
+ def apply(self):
+ with self.root.browser as browser:
+ browser.offset = clamp(browser.offset + browser.cols, browser.max_offset)
+
+
+class JumpToPage(Action):
+ """Jump to a specified offset."""
+ text = kp.StringProperty('Go to page')
+
+ def apply(self, offset=None):
+ if offset is None:
+ browser = self.root.browser
+ dlg = dialogues.NumericInput(lo=0, hi=browser.max_offset, init_value=browser.offset)
+ dlg.bind(on_ok=lambda wx: self.set_offset(wx.value))
+ dlg.open()
+ else:
+ self.set_offset(offset)
+
+ def set_offset(self, offset):
+ with self.root.browser as browser:
+ browser.offset = clamp(offset, browser.max_offset)
+
+class ZoomIn(Action):
+ """Decrease the grid size."""
+ text = kp.StringProperty('Zoom in')
+
+ def ktrigger(self, evt):
+ return Binding.check(evt, self.cfg('bindings', 'browser', 'zoom_in'))
+
+ # TODO: zoom by gesture
+
+ def on_touch_down(self, touch): # not triggered (but ScrollDown is!)
+ if self.root.browser.collide_point(*touch.pos) \
+ and self.root.keys.ctrl_pressed:
+ if touch.button == 'scrolldown':
+ self.apply()
+ return super(ZoomIn, self).on_touch_down(touch)
+
+ def apply(self):
+ with self.root.browser as browser:
+ step = self.cfg('ui', 'standalone', 'browser', 'zoom_step')
+ if browser.gridmode == browser.GRIDMODE_LIST:
+ cols = browser.cols
+ else:
+ cols = max(1, browser.cols - step)
+ rows = max(1, browser.rows - step)
+ # TODO: Zoom to center? (adjust offset)
+ if cols != browser.cols or rows != browser.rows:
+ # clear widgets first, otherwise GridLayout will
+ # complain about too many childrens.
+ browser.clear_widgets()
+ # adjust the grid size
+ browser.cols = cols
+ browser.rows = rows
+
+
+class ZoomOut(Action):
+ """Increase the grid size."""
+ text = kp.StringProperty('Zoom out')
+
+ def ktrigger(self, evt):
+ return Binding.check(evt, self.cfg('bindings', 'browser', 'zoom_out'))
+
+ # TODO: zoom by gesture
+
+ def on_touch_down(self, touch):
+ if self.root.browser.collide_point(*touch.pos) \
+ and self.root.keys.ctrl_pressed:
+ if touch.button == 'scrollup':
+ self.apply()
+ return super(ZoomOut, self).on_touch_down(touch)
+
+ def apply(self):
+ with self.root.browser as browser:
+ # TODO: Zoom from center? (adjust offset)
+ step = self.cfg('ui', 'standalone', 'browser', 'zoom_step')
+ # get maxcols
+ maxcols = self.cfg('ui', 'standalone', 'browser', 'maxcols')
+ maxcols = float('inf') if maxcols <= 0 else maxcols
+ # get maxrows
+ maxrows = self.cfg('ui', 'standalone', 'browser', 'maxrows')
+ maxrows = float('inf') if maxrows <= 0 else maxrows
+ # set cols/rows
+ if browser.gridmode != browser.GRIDMODE_LIST:
+ browser.cols = min(browser.cols + step, maxcols)
+ browser.rows = min(browser.rows + step, maxrows)
+ # adjust offset to ensure that one full page is visible
+ browser.offset = clamp(browser.offset, browser.max_offset)
+
+
+class JumpToCursor(Action):
+ """Focus the field of view at the cursor."""
+ text = kp.StringProperty('Find cursor')
+
+ def apply(self):
+ with self.root.browser as browser:
+ if browser.cursor is None:
+ # cursor not set, nothing to do
+ pass
+ else:
+ idx = browser.items.index(browser.cursor)
+ if idx < browser.offset:
+ # cursor is above view, scroll up such that the cursor
+ # is in the first row.
+ offset = math.floor(idx / browser.cols) * browser.cols
+ browser.offset = clamp(offset, browser.max_offset)
+ elif browser.offset + browser.page_size <= idx:
+ # cursor is below view, scroll down such that the cursor
+ # is in the last row.
+ offset = math.floor(idx / browser.cols) * browser.cols
+ offset -= (browser.page_size - browser.cols)
+ browser.offset = clamp(offset, browser.max_offset)
+ else:
+ # cursor is visible, nothing to do
+ pass
+
+
+class SetCursor(Action):
+ """Set the cursor to a specific item."""
+ text = kp.StringProperty('Set cursor')
+
+ def apply(self, obj):
+ with self.root.browser as browser:
+ browser.cursor = obj
+ self.root.trigger('JumpToCursor')
+ # is invoked via mouse click only, hence
+ # the item selection should always toggle
+ self.root.trigger('Select', browser.cursor)
+
+
+class MoveCursorFirst(Action):
+ """Set the cursor to the first item."""
+ text = kp.StringProperty('First')
+
+ def ktrigger(self, evt):
+ return Binding.check(evt, self.cfg('bindings', 'browser', 'go_first'))
+
+ def apply(self):
+ with self.root.browser as browser:
+ if browser.n_items == 0:
+ # browser is empty, nothing to do
+ pass
+ else:
+ # set cursor to first item
+ old = browser.cursor
+ browser.cursor = browser.items[0]
+ # scroll to first page if need be
+ self.root.trigger('JumpToCursor')
+ # fix selection
+ if browser.select_mode != browser.SELECT_MULTI and \
+ (browser.select_mode != browser.SELECT_SINGLE or old != browser.cursor):
+ self.root.trigger('Select', browser.cursor)
+
+
+class MoveCursorLast(Action):
+ """Set the cursor to the last item."""
+ text = kp.StringProperty('Last')
+
+ def ktrigger(self, evt):
+ return Binding.check(evt, self.cfg('bindings', 'browser', 'go_last'))
+
+ def apply(self):
+ with self.root.browser as browser:
+ if browser.n_items == 0:
+ # browser is empty, nothing to do
+ pass
+ else:
+ # set cursor to last item
+ old = browser.cursor
+ browser.cursor = browser.items[-1]
+ # scroll to last page if need be
+ self.root.trigger('JumpToCursor')
+ # fix selection
+ if browser.select_mode != browser.SELECT_MULTI and \
+ (browser.select_mode != browser.SELECT_SINGLE or old != browser.cursor):
+ self.root.trigger('Select', browser.cursor)
+
+
+class MoveCursorUp(Action):
+ """Move the cursor one item upwards. Scroll if needbe."""
+ text = kp.StringProperty('Cursor up')
+
+ def ktrigger(self, evt):
+ return Binding.check(evt, self.cfg('bindings', 'browser', 'cursor_up'))
+
+ def apply(self):
+ with self.root.browser as browser:
+ if browser.n_items == 0:
+ # browser is empty, nothing to do
+ pass
+ elif browser.cursor is None:
+ # cursor wasn't set before. Set to last item
+ self.root.trigger('MoveCursorLast')
+ else:
+ # move cursor one row up
+ old = browser.items.index(browser.cursor)
+ # check if the cursor is in the first row already
+ if old < browser.cols: return # first row already
+ # move cursor up
+ new = clamp(old - browser.cols, browser.n_items - 1)
+ browser.cursor = browser.items[new]
+ # fix field of view
+ self.root.trigger('JumpToCursor')
+ # fix selection
+ if browser.select_mode != browser.SELECT_MULTI and \
+ (browser.select_mode != browser.SELECT_SINGLE or old != new):
+ self.root.trigger('Select', browser.cursor)
+
+
+class MoveCursorDown(Action):
+ """Move the cursor one item downwards. Scroll if needbe."""
+ text = kp.StringProperty('Cursor down')
+
+ def ktrigger(self, evt):
+ return Binding.check(evt, self.cfg('bindings', 'browser', 'cursor_down'))
+
+ def apply(self):
+ with self.root.browser as browser:
+ if browser.n_items == 0:
+ # browser is empty, nothing to do
+ pass
+ elif browser.cursor is None:
+ # cursor wasn't set before. Set to first item
+ self.root.trigger('MoveCursorFirst')
+ else:
+ # move cursor one row down
+ old = browser.items.index(browser.cursor)
+ # check if the cursor is in the last row already
+ last_row = browser.n_items % browser.cols
+ last_row = last_row if last_row > 0 else browser.cols
+ if old >= browser.n_items - last_row: return # last row already
+ # move cursor down
+ new = clamp(old + browser.cols, browser.n_items - 1)
+ browser.cursor = browser.items[new]
+ # fix field of view
+ self.root.trigger('JumpToCursor')
+ # fix selection
+ if browser.select_mode != browser.SELECT_MULTI and \
+ (browser.select_mode != browser.SELECT_SINGLE or old != new):
+ self.root.trigger('Select', browser.cursor)
+
+
+class MoveCursorLeft(Action):
+ """Move the cursor to the previous item."""
+ text = kp.StringProperty('Cursor left')
+
+ def ktrigger(self, evt):
+ return Binding.check(evt, self.cfg('bindings', 'browser', 'cursor_left'))
+
+ def apply(self):
+ with self.root.browser as browser:
+ if browser.n_items == 0:
+ # browser is empty, nothing to do
+ pass
+ elif browser.cursor is None:
+ # cursor wasn't set before. Set to the last item
+ self.root.trigger('MoveCursorLast')
+ else:
+ # move cursor one position to the left
+ old = browser.items.index(browser.cursor)
+ new = clamp(old - 1, browser.n_items - 1)
+ browser.cursor = browser.items[new]
+ self.root.trigger('JumpToCursor')
+ # fix selection
+ if browser.select_mode != browser.SELECT_MULTI and \
+ (browser.select_mode != browser.SELECT_SINGLE or old != new):
+ self.root.trigger('Select', browser.cursor)
+
+
+class MoveCursorRight(Action):
+ """Move the cursor to the next item."""
+ text = kp.StringProperty('Cursor right')
+
+ def ktrigger(self, evt):
+ return Binding.check(evt, self.cfg('bindings', 'browser', 'cursor_right'))
+
+ def apply(self):
+ with self.root.browser as browser:
+ if browser.n_items == 0:
+ # browser is empty, nothing to do
+ pass
+ elif browser.cursor is None:
+ # cursor wasn't set before. Set to the last item
+ self.root.trigger('MoveCursorFirst')
+ else:
+ # move cursor one position to the right
+ old = browser.items.index(browser.cursor)
+ new = clamp(old + 1, browser.n_items - 1)
+ browser.cursor = browser.items[new]
+ self.root.trigger('JumpToCursor')
+ # fix selection
+ if browser.select_mode != browser.SELECT_MULTI and \
+ (browser.select_mode != browser.SELECT_SINGLE or old != new):
+ self.root.trigger('Select', browser.cursor)
+
+
+class SelectAll(Action):
+ """Select all items."""
+ text = kp.StringProperty('Select all')
+
+ def ktrigger(self, evt):
+ return Binding.check(evt, self.cfg('bindings', 'browser', 'select_all'))
+
+ def apply(self):
+ with self.root.browser as browser:
+ browser.selection = browser.items.as_set().copy()
+
+
+class SelectNone(Action):
+ """Clear the selection."""
+ text = kp.StringProperty('Clear selection')
+
+ def ktrigger(self, evt):
+ return Binding.check(evt, self.cfg('bindings', 'browser', 'select_none'))
+
+ def apply(self):
+ with self.root.browser as browser:
+ browser.selection = set()
+
+
+class SelectInvert(Action):
+ """Invert the selection."""
+ text = kp.StringProperty('Invert selection')
+
+ def apply(self):
+ with self.root.browser as browser:
+ browser.selection = browser.items.as_set() - browser.selection
+
+
+class SelectSingle(Action):
+ """Select only the cursor."""
+ text = kp.StringProperty('Select one')
+
+ def apply(self):
+ with self.root.browser as browser:
+ browser.select_mode = browser.SELECT_SINGLE
+
+
+class SelectAdditive(Action):
+ """Set the selection mode to additive select."""
+ text = kp.StringProperty('Always select')
+
+ def apply(self):
+ with self.root.browser as browser:
+ browser.select_mode = browser.SELECT_ADDITIVE
+
+
+class SelectSubtractive(Action):
+ """Set the selection mode to subtractive select."""
+ text = kp.StringProperty('Always deselect')
+
+ def apply(self):
+ with self.root.browser as browser:
+ browser.select_mode = browser.SELECT_SUBTRACTIVE
+
+
+class SelectMulti(Action):
+ """Set the selection mode to random access."""
+ text = kp.StringProperty('Select many')
+ browser = kp.ObjectProperty(None, allownone=True)
+
+ def ktrigger(self, evt):
+ key, _, _ = evt
+ if key in self.root.keys.modemap[self.root.keys.MODIFIERS_CTRL]:
+ self.browser = self.root.browser
+ self.apply()
+
+ def on_root(self, wx, root):
+ super(SelectMulti, self).on_root(wx, root)
+ root.keys.bind(on_release=self.on_key_up)
+
+ def on_key_up(self, wx, key):
+ if key in self.root.keys.modemap[self.root.keys.MODIFIERS_CTRL]:
+ if self.browser is not None:
+ with self.browser as browser:
+ if browser.select_mode & browser.SELECT_MULTI:
+ browser.select_mode -= browser.SELECT_MULTI
+
+ def apply(self):
+ with self.root.browser as browser:
+ browser.select_mode |= browser.SELECT_MULTI
+
+
+class SelectRange(Action):
+ """Set the selection mode to range select."""
+ text = kp.StringProperty('Select range')
+ browser = kp.ObjectProperty(None, allownone=True)
+
+ def ktrigger(self, evt):
+ key, _, _ = evt
+ if key in self.root.keys.modemap[self.root.keys.MODIFIERS_SHIFT]:
+ self.browser = self.root.browser
+ self.apply()
+
+ def on_root(self, wx, root):
+ super(SelectRange, self).on_root(wx, root)
+ root.keys.bind(on_release=self.on_key_up)
+
+ def on_key_up(self, wx, key):
+ if key in self.root.keys.modemap[self.root.keys.MODIFIERS_SHIFT]:
+ if self.browser is not None:
+ with self.browser as browser:
+ if browser.select_mode & browser.SELECT_RANGE:
+ browser.select_mode -= browser.SELECT_RANGE
+ browser.range_base = set()
+ browser.range_origin = None
+
+ def apply(self):
+ with self.root.browser as browser:
+ browser.select_mode |= browser.SELECT_RANGE
+ browser.range_base = browser.selection.copy()
+ idx = None if browser.cursor is None else browser.items.index(browser.cursor)
+ browser.range_origin = idx
+
+
+class Select(Action):
+ """Select or deselect an item. How the selection changes depends on the selection mode."""
+ text = kp.StringProperty('Select')
+
+ def ktrigger(self, evt):
+ return Binding.check(evt, self.cfg('bindings', 'browser', 'select'))
+
+ def apply(self, obj=None):
+ with self.root.browser as browser:
+ obj = obj if obj is not None else browser.cursor
+
+ if obj is None:
+ # nothing to do
+ pass
+
+ elif browser.select_mode & browser.SELECT_ADDITIVE:
+ browser.selection.add(obj)
+
+ elif browser.select_mode & browser.SELECT_SUBTRACTIVE:
+ if obj in browser.selection:
+ browser.selection.remove(obj)
+
+ elif browser.select_mode & browser.SELECT_RANGE:
+ idx = browser.items.index(obj)
+ lo = min(idx, browser.range_origin)
+ hi = max(idx, browser.range_origin)
+ browser.selection = browser.range_base | set(browser.items[lo:hi+1])
+
+ elif browser.select_mode & browser.SELECT_MULTI:
+ # Toggle
+ if obj in browser.selection:
+ browser.selection.remove(obj)
+ else:
+ browser.selection.add(obj)
+
+ elif browser.select_mode == 0: #elif browser.select_mode & browser.SELECT_SINGLE:
+ # Toggle
+ if obj in browser.selection:
+ browser.selection = set()
+ else:
+ browser.selection = {obj}
+
+
+## config ##
+
+config.declare(('ui', 'standalone', 'browser', 'maxcols'), config.Unsigned(), 0,
+ __name__, 'Column maximum', 'Maximal number of columns. This guards against aggressive zooming, because the application may become unresponsive if too many preview images are shown on the same page. A value of Infinity means that no limit is enforced.')
+
+config.declare(('ui', 'standalone', 'browser', 'maxrows'), config.Unsigned(), 0,
+ __name__, 'Row maximum', 'Maximal number of rows. This guards against aggressive zooming, because the application may become unresponsive if too many preview images are shown on the same page. A value of Infinity means that no limit is enforced.')
+
+config.declare(('ui', 'standalone', 'browser', 'zoom_step'), config.Unsigned(), 1,
+ __name__, 'Zoom step', 'Controls by how much the gridsize is increased or decreased when zoomed in or out. Affects both dimensions (cols/rows) in grid mode.')
+
+config.declare(('ui', 'standalone', 'browser', 'scroll'), config.Enum('mouse', 'touch'), 'mouse',
+ __name__, 'Inverted scroll', 'To scroll downwards, one can either move the fingers in an upward direction (touch) or use the scroll wheel in a downward direction (mouse).')
+
+# keybindings
+
+config.declare(('bindings', 'browser', 'page_next'),
+ config.Keybind(), Binding.simple(Binding.PGDN),
+ __name__, NextPage.text.defaultvalue, NextPage.__doc__)
+
+config.declare(('bindings', 'browser', 'page_prev'),
+ config.Keybind(), Binding.simple(Binding.PGUP),
+ __name__, PreviousPage.text.defaultvalue, PreviousPage.__doc__)
+
+config.declare(('bindings', 'browser', 'scroll_up'),
+ config.Keybind(), Binding.simple('k', None, Binding.mALL),
+ __name__, ScrollUp.text.defaultvalue, ScrollUp.__doc__)
+
+config.declare(('bindings', 'browser', 'scroll_down'),
+ config.Keybind(), Binding.simple('j', None, Binding.mALL),
+ __name__, ScrollDown.text.defaultvalue, ScrollDown.__doc__)
+
+config.declare(('bindings', 'browser', 'zoom_in'),
+ config.Keybind(), Binding.simple('+'),
+ __name__, ZoomIn.text.defaultvalue, ZoomIn.__doc__)
+
+config.declare(('bindings', 'browser', 'zoom_out'),
+ config.Keybind(), Binding.simple('-'),
+ __name__, ZoomOut.text.defaultvalue, ZoomOut.__doc__)
+
+config.declare(('bindings', 'browser', 'go_first'),
+ config.Keybind(), Binding.simple(Binding.HOME),
+ __name__, MoveCursorFirst.text.defaultvalue, MoveCursorFirst.__doc__)
+
+config.declare(('bindings', 'browser', 'go_last'),
+ config.Keybind(), Binding.simple(Binding.END),
+ __name__, MoveCursorLast.text.defaultvalue, MoveCursorLast.__doc__)
+
+config.declare(('bindings', 'browser', 'cursor_up'),
+ config.Keybind(), Binding.simple(Binding.UP),
+ __name__, MoveCursorUp.text.defaultvalue, MoveCursorUp.__doc__)
+
+config.declare(('bindings', 'browser', 'cursor_down'),
+ config.Keybind(), Binding.simple(Binding.DOWN),
+ __name__, MoveCursorDown.text.defaultvalue, MoveCursorDown.__doc__)
+
+config.declare(('bindings', 'browser', 'cursor_left'),
+ config.Keybind(), Binding.simple(Binding.LEFT),
+ __name__, MoveCursorLeft.text.defaultvalue, MoveCursorLeft.__doc__)
+
+config.declare(('bindings', 'browser', 'cursor_right'),
+ config.Keybind(), Binding.simple(Binding.RIGHT),
+ __name__, MoveCursorRight.text.defaultvalue, MoveCursorRight.__doc__)
+
+config.declare(('bindings', 'browser', 'select_all'),
+ config.Keybind(), Binding.simple('a', Binding.mCTRL, Binding.mREST),
+ __name__, SelectAll.text.defaultvalue, SelectAll.__doc__)
+
+config.declare(('bindings', 'browser', 'select_none'),
+ config.Keybind(), Binding.simple('a', (Binding.mCTRL, Binding.mSHIFT), Binding.mREST),
+ __name__, SelectNone.text.defaultvalue, SelectNone.__doc__)
+
+config.declare(('bindings', 'browser', 'select'),
+ config.Keybind(), Binding.simple(Binding.SPACEBAR),
+ __name__, Select.text.defaultvalue, Select.__doc__)
+
+## EOF ##
diff --git a/tagit/actions/misc.py b/tagit/actions/misc.py
index dc939ca..c0f960e 100644
--- a/tagit/actions/misc.py
+++ b/tagit/actions/misc.py
@@ -16,8 +16,7 @@ import webbrowser
# tagit imports
from tagit import config
-#from tagit.io_.sync import export # FIXME: mb/port
-#from tagit.utils import fileopen # FIXME: mb/port
+from tagit.utils import fileopen
from tagit.widgets import Binding
# inner-module imports
diff --git a/tagit/apps/port-config.yaml b/tagit/apps/port-config.yaml
index ac0d242..7ca03ae 100644
--- a/tagit/apps/port-config.yaml
+++ b/tagit/apps/port-config.yaml
@@ -15,9 +15,9 @@ ui:
maxcols: 8
maxrows: 8
buttondocks:
- sidebar_left: []
- #- Menu
- #- ShowDashboard
+ sidebar_left:
+ - Menu
+ - ShowDashboard
#- AddTag
#- EditTag
#- CreateGroup
diff --git a/tagit/assets/icons/kivy/browser-0.png b/tagit/assets/icons/kivy/browser-0.png
new file mode 100644
index 0000000..2c049d2
--- /dev/null
+++ b/tagit/assets/icons/kivy/browser-0.png
Binary files differ
diff --git a/tagit/assets/icons/kivy/browser.atlas b/tagit/assets/icons/kivy/browser.atlas
new file mode 100644
index 0000000..5f15d55
--- /dev/null
+++ b/tagit/assets/icons/kivy/browser.atlas
@@ -0,0 +1 @@
+{"browser-0.png": {"cursor_down": [2, 0, 30, 30], "cursor_first": [34, 0, 30, 30], "cursor_last": [66, 0, 30, 30], "cursor_left": [98, 0, 30, 30], "cursor_right": [130, 0, 30, 30], "cursor_up": [162, 0, 30, 30], "next_page": [194, 0, 30, 30], "previous_page": [226, 0, 30, 30], "scroll_down": [258, 0, 30, 30], "scroll_up": [290, 0, 30, 30], "select_add": [322, 0, 30, 30], "select_all": [354, 0, 30, 30], "select_invert": [386, 0, 30, 30], "select_multi": [418, 0, 30, 30], "select_none": [450, 0, 30, 30], "select": [482, 0, 30, 30], "select_range": [514, 0, 30, 30], "select_single": [546, 0, 30, 30], "select_sub": [578, 0, 30, 30], "zoom_in": [610, 0, 30, 30], "zoom_out": [642, 0, 30, 30]}} \ No newline at end of file
diff --git a/tagit/assets/icons/scalable/README b/tagit/assets/icons/scalable/README
new file mode 100644
index 0000000..7c17504
--- /dev/null
+++ b/tagit/assets/icons/scalable/README
@@ -0,0 +1,5 @@
+
+internal.svg is derived work from:
+ https://commons.wikimedia.org/wiki/File:Jolly-Roger.svg
+ by RootOfAllLight
+
diff --git a/tagit/assets/icons/scalable/browser/cursor_down.svg b/tagit/assets/icons/scalable/browser/cursor_down.svg
new file mode 100644
index 0000000..b75b288
--- /dev/null
+++ b/tagit/assets/icons/scalable/browser/cursor_down.svg
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100mm"
+ height="100mm"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92.3 (2405546, 2018-03-11)"
+ sodipodi:docname="cursor_down.svg"
+ inkscape:export-filename="../../kivy/browser/cursor_down.png"
+ inkscape:export-xdpi="7.6199999"
+ inkscape:export-ydpi="7.6199999">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1.979899"
+ inkscape:cx="183.64532"
+ inkscape:cy="182.16579"
+ inkscape:document-units="mm"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:snap-global="true"
+ inkscape:snap-bbox="true"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0"
+ inkscape:window-width="1920"
+ inkscape:window-height="1031"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ inkscape:window-maximized="1"
+ inkscape:pagecheckerboard="true"
+ units="mm"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="true"
+ inkscape:object-paths="true"
+ inkscape:snap-intersection-paths="true"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:snap-midpoints="true"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
+ inkscape:snap-text-baseline="true"
+ inkscape:snap-page="true"
+ showborder="true">
+ <sodipodi:guide
+ orientation="0,1"
+ position="13.637059,643.40404"
+ id="guide3788"
+ inkscape:locked="false" />
+ <sodipodi:guide
+ position="188.97638,188.97638"
+ orientation="0,1"
+ id="guide1099"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="188.97638,188.97638"
+ orientation="1,0"
+ id="guide1101"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="233.588,370"
+ orientation="1,0"
+ id="guide1107"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="144.36496,311.42857"
+ orientation="1,0"
+ id="guide1109"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="-77.142857,144.36496"
+ orientation="0,1"
+ id="guide1111"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="5.000315,233.58779"
+ orientation="0,1"
+ id="guide1113"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="-305.71429,497.85714"
+ orientation="0,1"
+ id="guide822"
+ inkscape:locked="false" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-167.28122,-322.85977)">
+ <g
+ id="g845"
+ transform="matrix(0,1,1,0,-155.57855,155.57855)">
+ <path
+ inkscape:transform-center-y="3.8269577e-06"
+ transform="matrix(0.77742888,0,0,0.88132688,181.59692,74.405789)"
+ inkscape:transform-center-x="-71.079211"
+ d="m 467.74318,496.33157 -150.23098,86.73589 -150.23097,86.7359 0,-173.47179 0,-173.47179 150.23097,86.73591 z"
+ inkscape:randomized="0"
+ inkscape:rounded="0"
+ inkscape:flatsided="false"
+ sodipodi:arg2="1.0471976"
+ sodipodi:arg1="0"
+ sodipodi:r2="100.15398"
+ sodipodi:r1="200.30797"
+ sodipodi:cy="496.33157"
+ sodipodi:cx="267.43521"
+ sodipodi:sides="3"
+ id="path2995"
+ style="fill:#c8c8c8;fill-opacity:1;stroke:none;stroke-width:2.19086838;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ sodipodi:type="star" />
+ <rect
+ y="496.479"
+ x="167.28122"
+ height="30.714285"
+ width="144.36497"
+ id="rect820"
+ style="opacity:1;fill:#c8c8c8;fill-opacity:1;stroke:none;stroke-width:39.62062454;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:fill markers stroke" />
+ </g>
+ </g>
+</svg>
diff --git a/tagit/assets/icons/scalable/browser/cursor_first.svg b/tagit/assets/icons/scalable/browser/cursor_first.svg
new file mode 100644
index 0000000..57d878e
--- /dev/null
+++ b/tagit/assets/icons/scalable/browser/cursor_first.svg
@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100mm"
+ height="100mm"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92.3 (2405546, 2018-03-11)"
+ sodipodi:docname="cursor_first.svg"
+ inkscape:export-filename="../../kivy/browser/cursor_first.png"
+ inkscape:export-xdpi="7.6199999"
+ inkscape:export-ydpi="7.6199999">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1.4"
+ inkscape:cx="104.09835"
+ inkscape:cy="254.99343"
+ inkscape:document-units="mm"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:snap-global="true"
+ inkscape:snap-bbox="true"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0"
+ inkscape:window-width="1920"
+ inkscape:window-height="1031"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ inkscape:window-maximized="1"
+ inkscape:pagecheckerboard="true"
+ units="mm"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="true"
+ inkscape:object-paths="true"
+ inkscape:snap-intersection-paths="true"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:snap-midpoints="true"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
+ inkscape:snap-text-baseline="true"
+ inkscape:snap-page="true">
+ <sodipodi:guide
+ orientation="0,1"
+ position="13.637059,643.40404"
+ id="guide3788"
+ inkscape:locked="false" />
+ <sodipodi:guide
+ position="188.97638,188.97638"
+ orientation="0,1"
+ id="guide1099"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="188.97638,188.97638"
+ orientation="1,0"
+ id="guide1101"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="233.588,370"
+ orientation="1,0"
+ id="guide1107"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="144.36496,311.42857"
+ orientation="1,0"
+ id="guide1109"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="-77.142857,144.36496"
+ orientation="0,1"
+ id="guide1111"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="5.000315,233.58779"
+ orientation="0,1"
+ id="guide1113"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-167.28122,-322.85977)">
+ <path
+ sodipodi:type="star"
+ style="fill:#c8c8c8;fill-opacity:1;stroke:none;stroke-width:2.19086838;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path2995"
+ sodipodi:sides="3"
+ sodipodi:cx="267.43521"
+ sodipodi:cy="496.33157"
+ sodipodi:r1="200.30797"
+ sodipodi:r2="100.15398"
+ sodipodi:arg1="0"
+ sodipodi:arg2="1.0471976"
+ inkscape:flatsided="false"
+ inkscape:rounded="0"
+ inkscape:randomized="0"
+ d="m 467.74318,496.33157 -150.23098,86.73589 -150.23097,86.7359 0,-173.47179 0,-173.47179 150.23097,86.73591 z"
+ inkscape:transform-center-x="-87.858587"
+ transform="matrix(-0.96095331,0,0,-1.0893781,705.98338,1052.5288)"
+ inkscape:transform-center-y="1.8482077e-06" />
+ <rect
+ style="fill:#c8c8c8;fill-opacity:1;stroke:none;stroke-width:2.62828088;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect3798"
+ width="57.780041"
+ height="377.95276"
+ x="-225.06128"
+ y="-700.8125"
+ transform="scale(-1)" />
+ </g>
+</svg>
diff --git a/tagit/assets/icons/scalable/browser/cursor_last.svg b/tagit/assets/icons/scalable/browser/cursor_last.svg
new file mode 100644
index 0000000..ffe7449
--- /dev/null
+++ b/tagit/assets/icons/scalable/browser/cursor_last.svg
@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100mm"
+ height="100mm"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92.3 (2405546, 2018-03-11)"
+ sodipodi:docname="cursor_last.svg"
+ inkscape:export-filename="../../kivy/browser/cursor_last.png"
+ inkscape:export-xdpi="7.6199999"
+ inkscape:export-ydpi="7.6199999">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1.4"
+ inkscape:cx="104.09835"
+ inkscape:cy="254.99343"
+ inkscape:document-units="mm"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:snap-global="true"
+ inkscape:snap-bbox="true"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0"
+ inkscape:window-width="1920"
+ inkscape:window-height="1031"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ inkscape:window-maximized="1"
+ inkscape:pagecheckerboard="true"
+ units="mm"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="true"
+ inkscape:object-paths="true"
+ inkscape:snap-intersection-paths="true"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:snap-midpoints="true"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
+ inkscape:snap-text-baseline="true"
+ inkscape:snap-page="true">
+ <sodipodi:guide
+ orientation="0,1"
+ position="13.637059,643.40404"
+ id="guide3788"
+ inkscape:locked="false" />
+ <sodipodi:guide
+ position="188.97638,188.97638"
+ orientation="0,1"
+ id="guide1099"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="188.97638,188.97638"
+ orientation="1,0"
+ id="guide1101"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="233.588,370"
+ orientation="1,0"
+ id="guide1107"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="144.36496,311.42857"
+ orientation="1,0"
+ id="guide1109"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="-77.142857,144.36496"
+ orientation="0,1"
+ id="guide1111"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="5.000315,233.58779"
+ orientation="0,1"
+ id="guide1113"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-167.28122,-322.85977)">
+ <path
+ sodipodi:type="star"
+ style="fill:#c8c8c8;fill-opacity:1;stroke:none;stroke-width:2.19086838;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path2995"
+ sodipodi:sides="3"
+ sodipodi:cx="267.43521"
+ sodipodi:cy="496.33157"
+ sodipodi:r1="200.30797"
+ sodipodi:r2="100.15398"
+ sodipodi:arg1="0"
+ sodipodi:arg2="1.0471976"
+ inkscape:flatsided="false"
+ inkscape:rounded="0"
+ inkscape:randomized="0"
+ d="m 467.74318,496.33157 -150.23098,86.73589 -150.23097,86.7359 0,-173.47179 0,-173.47179 150.23097,86.73591 z"
+ inkscape:transform-center-x="-87.858587"
+ transform="matrix(0.96095331,0,0,1.0893781,6.5317797,-28.856589)"
+ inkscape:transform-center-y="1.8482077e-06" />
+ <rect
+ style="fill:#c8c8c8;fill-opacity:1;stroke:none;stroke-width:2.62828088;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect3798"
+ width="57.780041"
+ height="377.95276"
+ x="487.45389"
+ y="322.85974" />
+ </g>
+</svg>
diff --git a/tagit/assets/icons/scalable/browser/cursor_left.svg b/tagit/assets/icons/scalable/browser/cursor_left.svg
new file mode 100644
index 0000000..d1877f8
--- /dev/null
+++ b/tagit/assets/icons/scalable/browser/cursor_left.svg
@@ -0,0 +1,159 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100mm"
+ height="100mm"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92.3 (2405546, 2018-03-11)"
+ sodipodi:docname="cursor_left.svg"
+ inkscape:export-filename="../../kivy/browser/scroll_down.png"
+ inkscape:export-xdpi="7.6199999"
+ inkscape:export-ydpi="7.6199999">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1.979899"
+ inkscape:cx="183.64532"
+ inkscape:cy="262.978"
+ inkscape:document-units="mm"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:snap-global="true"
+ inkscape:snap-bbox="true"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0"
+ inkscape:window-width="1920"
+ inkscape:window-height="1031"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ inkscape:window-maximized="1"
+ inkscape:pagecheckerboard="true"
+ units="mm"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="true"
+ inkscape:object-paths="true"
+ inkscape:snap-intersection-paths="true"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:snap-midpoints="true"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
+ inkscape:snap-text-baseline="true"
+ inkscape:snap-page="true">
+ <sodipodi:guide
+ orientation="0,1"
+ position="13.637059,643.40404"
+ id="guide3788"
+ inkscape:locked="false" />
+ <sodipodi:guide
+ position="188.97638,188.97638"
+ orientation="0,1"
+ id="guide1099"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="188.97638,188.97638"
+ orientation="1,0"
+ id="guide1101"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="233.588,370"
+ orientation="1,0"
+ id="guide1107"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="144.36496,311.42857"
+ orientation="1,0"
+ id="guide1109"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="-77.142857,144.36496"
+ orientation="0,1"
+ id="guide1111"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="5.000315,233.58779"
+ orientation="0,1"
+ id="guide1113"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="-305.71429,497.85714"
+ orientation="0,1"
+ id="guide822"
+ inkscape:locked="false" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-167.28122,-322.85977)">
+ <path
+ sodipodi:type="star"
+ style="fill:#c8c8c8;fill-opacity:1;stroke:none;stroke-width:2.19086838;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path2995"
+ sodipodi:sides="3"
+ sodipodi:cx="267.43521"
+ sodipodi:cy="496.33157"
+ sodipodi:r1="200.30797"
+ sodipodi:r2="100.15398"
+ sodipodi:arg1="0"
+ sodipodi:arg2="1.0471976"
+ inkscape:flatsided="false"
+ inkscape:rounded="0"
+ inkscape:randomized="0"
+ d="m 467.74318,496.33157 -150.23098,86.73589 -150.23097,86.7359 0,-173.47179 0,-173.47179 150.23097,86.73591 z"
+ inkscape:transform-center-x="-71.079211"
+ transform="matrix(0.77742888,0,0,0.88132688,181.59692,74.405789)"
+ inkscape:transform-center-y="3.8269577e-06" />
+ <rect
+ style="opacity:1;fill:#c8c8c8;fill-opacity:1;stroke:none;stroke-width:39.62062454;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:fill markers stroke"
+ id="rect820"
+ width="144.36497"
+ height="30.714285"
+ x="167.28122"
+ y="496.479" />
+ </g>
+</svg>
diff --git a/tagit/assets/icons/scalable/browser/cursor_right.svg b/tagit/assets/icons/scalable/browser/cursor_right.svg
new file mode 100644
index 0000000..bfe235d
--- /dev/null
+++ b/tagit/assets/icons/scalable/browser/cursor_right.svg
@@ -0,0 +1,163 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100mm"
+ height="100mm"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92.3 (2405546, 2018-03-11)"
+ sodipodi:docname="cursor_right.svg"
+ inkscape:export-filename="../../kivy/browser/cursor_right.png"
+ inkscape:export-xdpi="7.6199999"
+ inkscape:export-ydpi="7.6199999">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1.979899"
+ inkscape:cx="183.64532"
+ inkscape:cy="262.978"
+ inkscape:document-units="mm"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:snap-global="true"
+ inkscape:snap-bbox="true"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0"
+ inkscape:window-width="1920"
+ inkscape:window-height="1031"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ inkscape:window-maximized="1"
+ inkscape:pagecheckerboard="true"
+ units="mm"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="true"
+ inkscape:object-paths="true"
+ inkscape:snap-intersection-paths="true"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:snap-midpoints="true"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
+ inkscape:snap-text-baseline="true"
+ inkscape:snap-page="true">
+ <sodipodi:guide
+ orientation="0,1"
+ position="13.637059,643.40404"
+ id="guide3788"
+ inkscape:locked="false" />
+ <sodipodi:guide
+ position="188.97638,188.97638"
+ orientation="0,1"
+ id="guide1099"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="188.97638,188.97638"
+ orientation="1,0"
+ id="guide1101"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="233.588,370"
+ orientation="1,0"
+ id="guide1107"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="144.36496,311.42857"
+ orientation="1,0"
+ id="guide1109"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="-77.142857,144.36496"
+ orientation="0,1"
+ id="guide1111"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="5.000315,233.58779"
+ orientation="0,1"
+ id="guide1113"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="-305.71429,497.85714"
+ orientation="0,1"
+ id="guide822"
+ inkscape:locked="false" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-167.28122,-322.85977)">
+ <g
+ id="g845"
+ transform="rotate(180,356.2576,511.83615)">
+ <path
+ inkscape:transform-center-y="3.8269577e-06"
+ transform="matrix(0.77742888,0,0,0.88132688,181.59692,74.405789)"
+ inkscape:transform-center-x="-71.079211"
+ d="m 467.74318,496.33157 -150.23098,86.73589 -150.23097,86.7359 0,-173.47179 0,-173.47179 150.23097,86.73591 z"
+ inkscape:randomized="0"
+ inkscape:rounded="0"
+ inkscape:flatsided="false"
+ sodipodi:arg2="1.0471976"
+ sodipodi:arg1="0"
+ sodipodi:r2="100.15398"
+ sodipodi:r1="200.30797"
+ sodipodi:cy="496.33157"
+ sodipodi:cx="267.43521"
+ sodipodi:sides="3"
+ id="path2995"
+ style="fill:#c8c8c8;fill-opacity:1;stroke:none;stroke-width:2.19086838;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ sodipodi:type="star" />
+ <rect
+ y="496.479"
+ x="167.28122"
+ height="30.714285"
+ width="144.36497"
+ id="rect820"
+ style="opacity:1;fill:#c8c8c8;fill-opacity:1;stroke:none;stroke-width:39.62062454;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:fill markers stroke" />
+ </g>
+ </g>
+</svg>
diff --git a/tagit/assets/icons/scalable/browser/cursor_up.svg b/tagit/assets/icons/scalable/browser/cursor_up.svg
new file mode 100644
index 0000000..907c16c
--- /dev/null
+++ b/tagit/assets/icons/scalable/browser/cursor_up.svg
@@ -0,0 +1,163 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100mm"
+ height="100mm"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92.3 (2405546, 2018-03-11)"
+ sodipodi:docname="cursor_up.svg"
+ inkscape:export-filename="../../kivy/browser/cursor_up.png"
+ inkscape:export-xdpi="7.6199999"
+ inkscape:export-ydpi="7.6199999">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1.979899"
+ inkscape:cx="183.64532"
+ inkscape:cy="222.57189"
+ inkscape:document-units="mm"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:snap-global="true"
+ inkscape:snap-bbox="true"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0"
+ inkscape:window-width="1920"
+ inkscape:window-height="1031"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ inkscape:window-maximized="1"
+ inkscape:pagecheckerboard="true"
+ units="mm"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="true"
+ inkscape:object-paths="true"
+ inkscape:snap-intersection-paths="true"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:snap-midpoints="true"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
+ inkscape:snap-text-baseline="true"
+ inkscape:snap-page="true">
+ <sodipodi:guide
+ orientation="0,1"
+ position="13.637059,643.40404"
+ id="guide3788"
+ inkscape:locked="false" />
+ <sodipodi:guide
+ position="188.97638,188.97638"
+ orientation="0,1"
+ id="guide1099"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="188.97638,188.97638"
+ orientation="1,0"
+ id="guide1101"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="233.588,370"
+ orientation="1,0"
+ id="guide1107"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="144.36496,311.42857"
+ orientation="1,0"
+ id="guide1109"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="-77.142857,144.36496"
+ orientation="0,1"
+ id="guide1111"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="5.000315,233.58779"
+ orientation="0,1"
+ id="guide1113"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="-305.71429,497.85714"
+ orientation="0,1"
+ id="guide822"
+ inkscape:locked="false" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-167.28122,-322.85977)">
+ <g
+ id="g845"
+ transform="rotate(-90,356.2576,511.83615)">
+ <path
+ inkscape:transform-center-y="3.8269577e-06"
+ transform="matrix(0.77742888,0,0,0.88132688,181.59692,74.405789)"
+ inkscape:transform-center-x="-71.079211"
+ d="m 467.74318,496.33157 -150.23098,86.73589 -150.23097,86.7359 0,-173.47179 0,-173.47179 150.23097,86.73591 z"
+ inkscape:randomized="0"
+ inkscape:rounded="0"
+ inkscape:flatsided="false"
+ sodipodi:arg2="1.0471976"
+ sodipodi:arg1="0"
+ sodipodi:r2="100.15398"
+ sodipodi:r1="200.30797"
+ sodipodi:cy="496.33157"
+ sodipodi:cx="267.43521"
+ sodipodi:sides="3"
+ id="path2995"
+ style="fill:#c8c8c8;fill-opacity:1;stroke:none;stroke-width:2.19086838;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ sodipodi:type="star" />
+ <rect
+ y="496.479"
+ x="167.28122"
+ height="30.714285"
+ width="144.36497"
+ id="rect820"
+ style="opacity:1;fill:#c8c8c8;fill-opacity:1;stroke:none;stroke-width:39.62062454;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:fill markers stroke" />
+ </g>
+ </g>
+</svg>
diff --git a/tagit/assets/icons/scalable/browser/next_page.svg b/tagit/assets/icons/scalable/browser/next_page.svg
new file mode 100644
index 0000000..77f4488
--- /dev/null
+++ b/tagit/assets/icons/scalable/browser/next_page.svg
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100mm"
+ height="100mm"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92.3 (2405546, 2018-03-11)"
+ sodipodi:docname="next_page.svg"
+ inkscape:export-filename="../../kivy/browser/template.png"
+ inkscape:export-xdpi="7.6199999"
+ inkscape:export-ydpi="7.6199999">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="0.98994949"
+ inkscape:cx="-105.2055"
+ inkscape:cy="381.61002"
+ inkscape:document-units="mm"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:snap-global="true"
+ inkscape:snap-bbox="true"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0"
+ inkscape:window-width="1920"
+ inkscape:window-height="1031"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ inkscape:window-maximized="1"
+ inkscape:pagecheckerboard="true"
+ units="mm"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="true"
+ inkscape:object-paths="true"
+ inkscape:snap-intersection-paths="true"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:snap-midpoints="true"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
+ inkscape:snap-text-baseline="true"
+ inkscape:snap-page="true"
+ inkscape:lockguides="false">
+ <sodipodi:guide
+ orientation="0,1"
+ position="13.637059,643.40404"
+ id="guide3788"
+ inkscape:locked="false" />
+ <sodipodi:guide
+ position="188.97638,188.97638"
+ orientation="0,1"
+ id="guide1099"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="188.97638,188.97638"
+ orientation="1,0"
+ id="guide1101"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="233.588,370"
+ orientation="1,0"
+ id="guide1107"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="144.36496,311.42857"
+ orientation="1,0"
+ id="guide1109"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="-77.142857,144.36496"
+ orientation="0,1"
+ id="guide1111"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="5.000315,233.58779"
+ orientation="0,1"
+ id="guide1113"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-167.28122,-322.85977)">
+ <path
+ sodipodi:type="star"
+ style="fill:#c8c8c8;fill-opacity:1;stroke:none;stroke-width:4;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path2995"
+ sodipodi:sides="3"
+ sodipodi:cx="-334.38327"
+ sodipodi:cy="361.73682"
+ sodipodi:r1="365.71429"
+ sodipodi:r2="182.85715"
+ sodipodi:arg1="0"
+ sodipodi:arg2="1.0471976"
+ inkscape:flatsided="false"
+ inkscape:rounded="0"
+ inkscape:randomized="0"
+ d="m 31.331024,361.73682 -274.285724,158.35894 -274.28572,158.35893 0,-316.71788 0,-316.717863 274.28573,158.358943 z"
+ inkscape:transform-center-x="-91.42857"
+ transform="matrix(0.34523871,0,0,0.5917254,345.85263,296.22092)" />
+ <path
+ sodipodi:type="star"
+ style="fill:#c8c8c8;fill-opacity:1;stroke:none;stroke-width:4;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path2995-8"
+ sodipodi:sides="3"
+ sodipodi:cx="211.80305"
+ sodipodi:cy="367.03107"
+ sodipodi:r1="365.71429"
+ sodipodi:r2="182.85715"
+ sodipodi:arg1="0"
+ sodipodi:arg2="1.0471976"
+ inkscape:flatsided="false"
+ inkscape:rounded="0"
+ inkscape:randomized="0"
+ d="M 577.51735,367.03107 303.23162,525.39001 28.945908,683.74894 l 0,-316.71788 0,-316.717863 274.285732,158.358943 z"
+ inkscape:transform-center-x="-91.42857"
+ transform="matrix(0.34523871,0,0,0.5917254,345.85263,296.22092)" />
+ </g>
+</svg>
diff --git a/tagit/assets/icons/scalable/browser/previous_page.svg b/tagit/assets/icons/scalable/browser/previous_page.svg
new file mode 100644
index 0000000..82eaa21
--- /dev/null
+++ b/tagit/assets/icons/scalable/browser/previous_page.svg
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100mm"
+ height="100mm"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92.3 (2405546, 2018-03-11)"
+ sodipodi:docname="previous_page.svg"
+ inkscape:export-filename="../../kivy/browser/previous_page.png"
+ inkscape:export-xdpi="7.6199999"
+ inkscape:export-ydpi="7.6199999">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="0.98994949"
+ inkscape:cx="-105.2055"
+ inkscape:cy="381.61002"
+ inkscape:document-units="mm"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:snap-global="true"
+ inkscape:snap-bbox="true"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0"
+ inkscape:window-width="1920"
+ inkscape:window-height="1031"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ inkscape:window-maximized="1"
+ inkscape:pagecheckerboard="true"
+ units="mm"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="true"
+ inkscape:object-paths="true"
+ inkscape:snap-intersection-paths="true"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:snap-midpoints="true"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
+ inkscape:snap-text-baseline="true"
+ inkscape:snap-page="true"
+ inkscape:lockguides="false">
+ <sodipodi:guide
+ orientation="0,1"
+ position="13.637059,643.40404"
+ id="guide3788"
+ inkscape:locked="false" />
+ <sodipodi:guide
+ position="188.97638,188.97638"
+ orientation="0,1"
+ id="guide1099"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="188.97638,188.97638"
+ orientation="1,0"
+ id="guide1101"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="233.588,370"
+ orientation="1,0"
+ id="guide1107"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="144.36496,311.42857"
+ orientation="1,0"
+ id="guide1109"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="-77.142857,144.36496"
+ orientation="0,1"
+ id="guide1111"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="5.000315,233.58779"
+ orientation="0,1"
+ id="guide1113"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-167.28122,-322.85977)">
+ <path
+ sodipodi:type="star"
+ style="fill:#c8c8c8;fill-opacity:1;stroke:none;stroke-width:4;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path2995"
+ sodipodi:sides="3"
+ sodipodi:cx="-334.38327"
+ sodipodi:cy="361.73682"
+ sodipodi:r1="365.71429"
+ sodipodi:r2="182.85715"
+ sodipodi:arg1="0"
+ sodipodi:arg2="1.0471976"
+ inkscape:flatsided="false"
+ inkscape:rounded="0"
+ inkscape:randomized="0"
+ d="m 31.331024,361.73682 -274.285724,158.35894 -274.28572,158.35893 0,-316.71788 0,-316.717863 274.28573,158.358943 z"
+ inkscape:transform-center-x="91.42857"
+ transform="matrix(-0.34523871,0,0,0.5917254,366.66256,296.22092)" />
+ <path
+ sodipodi:type="star"
+ style="fill:#c8c8c8;fill-opacity:1;stroke:none;stroke-width:4;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path2995-8"
+ sodipodi:sides="3"
+ sodipodi:cx="211.80305"
+ sodipodi:cy="367.03107"
+ sodipodi:r1="365.71429"
+ sodipodi:r2="182.85715"
+ sodipodi:arg1="0"
+ sodipodi:arg2="1.0471976"
+ inkscape:flatsided="false"
+ inkscape:rounded="0"
+ inkscape:randomized="0"
+ d="M 577.51735,367.03107 303.23162,525.39001 28.945908,683.74894 l 0,-316.71788 0,-316.717863 274.285732,158.358943 z"
+ inkscape:transform-center-x="91.42857"
+ transform="matrix(-0.34523871,0,0,0.5917254,366.66256,296.22092)" />
+ </g>
+</svg>
diff --git a/tagit/assets/icons/scalable/browser/scroll_down.svg b/tagit/assets/icons/scalable/browser/scroll_down.svg
new file mode 100644
index 0000000..443eb0a
--- /dev/null
+++ b/tagit/assets/icons/scalable/browser/scroll_down.svg
@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100mm"
+ height="100mm"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92.3 (2405546, 2018-03-11)"
+ sodipodi:docname="scroll_down.svg"
+ inkscape:export-filename="../../kivy/browser/scroll_down.png"
+ inkscape:export-xdpi="7.6199999"
+ inkscape:export-ydpi="7.6199999">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1.4"
+ inkscape:cx="-5.5445071"
+ inkscape:cy="252.13629"
+ inkscape:document-units="mm"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:snap-global="true"
+ inkscape:snap-bbox="true"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0"
+ inkscape:window-width="1920"
+ inkscape:window-height="1031"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ inkscape:window-maximized="1"
+ inkscape:pagecheckerboard="true"
+ units="mm"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="true"
+ inkscape:object-paths="true"
+ inkscape:snap-intersection-paths="true"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:snap-midpoints="true"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
+ inkscape:snap-text-baseline="true"
+ inkscape:snap-page="true">
+ <sodipodi:guide
+ orientation="0,1"
+ position="13.637059,643.40404"
+ id="guide3788"
+ inkscape:locked="false" />
+ <sodipodi:guide
+ position="188.97638,188.97638"
+ orientation="0,1"
+ id="guide1099"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="188.97638,188.97638"
+ orientation="1,0"
+ id="guide1101"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="233.588,370"
+ orientation="1,0"
+ id="guide1107"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="144.36496,311.42857"
+ orientation="1,0"
+ id="guide1109"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="-77.142857,144.36496"
+ orientation="0,1"
+ id="guide1111"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="5.000315,233.58779"
+ orientation="0,1"
+ id="guide1113"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-167.28122,-322.85977)">
+ <path
+ sodipodi:type="star"
+ style="fill:#c8c8c8;fill-opacity:1;stroke:none;stroke-width:2.19086838;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path2995"
+ sodipodi:sides="3"
+ sodipodi:cx="267.43521"
+ sodipodi:cy="496.33157"
+ sodipodi:r1="200.30797"
+ sodipodi:r2="100.15398"
+ sodipodi:arg1="0"
+ sodipodi:arg2="1.0471976"
+ inkscape:flatsided="false"
+ inkscape:rounded="0"
+ inkscape:randomized="0"
+ d="m 467.74318,496.33157 -150.23098,86.73589 -150.23097,86.7359 0,-173.47179 0,-173.47179 150.23097,86.73591 z"
+ inkscape:transform-center-x="-87.858587"
+ transform="matrix(0.96095331,0,0,1.0893781,51.143197,-28.856601)"
+ inkscape:transform-center-y="1.8482077e-06" />
+ </g>
+</svg>
diff --git a/tagit/assets/icons/scalable/browser/scroll_up.svg b/tagit/assets/icons/scalable/browser/scroll_up.svg
new file mode 100644
index 0000000..3f965f7
--- /dev/null
+++ b/tagit/assets/icons/scalable/browser/scroll_up.svg
@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100mm"
+ height="100mm"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92.3 (2405546, 2018-03-11)"
+ sodipodi:docname="scroll_up.svg"
+ inkscape:export-filename="../../kivy/browser/scroll_up.png"
+ inkscape:export-xdpi="7.6199999"
+ inkscape:export-ydpi="7.6199999">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1.4"
+ inkscape:cx="-5.5445071"
+ inkscape:cy="252.13629"
+ inkscape:document-units="mm"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:snap-global="true"
+ inkscape:snap-bbox="true"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0"
+ inkscape:window-width="1920"
+ inkscape:window-height="1031"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ inkscape:window-maximized="1"
+ inkscape:pagecheckerboard="true"
+ units="mm"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="true"
+ inkscape:object-paths="true"
+ inkscape:snap-intersection-paths="true"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:snap-midpoints="true"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
+ inkscape:snap-text-baseline="true"
+ inkscape:snap-page="true">
+ <sodipodi:guide
+ orientation="0,1"
+ position="13.637059,643.40404"
+ id="guide3788"
+ inkscape:locked="false" />
+ <sodipodi:guide
+ position="188.97638,188.97638"
+ orientation="0,1"
+ id="guide1099"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="188.97638,188.97638"
+ orientation="1,0"
+ id="guide1101"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="233.588,370"
+ orientation="1,0"
+ id="guide1107"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="144.36496,311.42857"
+ orientation="1,0"
+ id="guide1109"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="-77.142857,144.36496"
+ orientation="0,1"
+ id="guide1111"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="5.000315,233.58779"
+ orientation="0,1"
+ id="guide1113"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-167.28122,-322.85977)">
+ <path
+ sodipodi:type="star"
+ style="fill:#c8c8c8;fill-opacity:1;stroke:none;stroke-width:2.19086838;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path2995"
+ sodipodi:sides="3"
+ sodipodi:cx="267.43521"
+ sodipodi:cy="496.33157"
+ sodipodi:r1="200.30797"
+ sodipodi:r2="100.15398"
+ sodipodi:arg1="0"
+ sodipodi:arg2="1.0471976"
+ inkscape:flatsided="false"
+ inkscape:rounded="0"
+ inkscape:randomized="0"
+ d="m 467.74318,496.33157 -150.23098,86.73589 -150.23097,86.7359 0,-173.47179 0,-173.47179 150.23097,86.73591 z"
+ inkscape:transform-center-x="87.858589"
+ transform="matrix(-0.96095331,0,0,1.0893781,661.372,-28.856601)"
+ inkscape:transform-center-y="1.8482077e-06" />
+ </g>
+</svg>
diff --git a/tagit/assets/icons/scalable/browser/select.svg b/tagit/assets/icons/scalable/browser/select.svg
new file mode 100644
index 0000000..2f1ded2
--- /dev/null
+++ b/tagit/assets/icons/scalable/browser/select.svg
@@ -0,0 +1,291 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100mm"
+ height="100mm"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92.3 (2405546, 2018-03-11)"
+ sodipodi:docname="select.svg"
+ inkscape:export-filename="../../kivy/browser/select.png"
+ inkscape:export-xdpi="7.6199999"
+ inkscape:export-ydpi="7.6199999">
+ <defs
+ id="defs4">
+ <marker
+ inkscape:stockid="Arrow2Send"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="Arrow2Send"
+ style="overflow:visible;"
+ inkscape:isstock="true">
+ <path
+ id="path1058"
+ style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#c8c8c8;stroke-opacity:1;fill:#c8c8c8;fill-opacity:1"
+ d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
+ transform="scale(0.3) rotate(180) translate(-2.3,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Send"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="marker1609"
+ style="overflow:visible;"
+ inkscape:isstock="true">
+ <path
+ id="path1607"
+ d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
+ transform="scale(0.2) rotate(180) translate(6,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Send"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="marker1527"
+ style="overflow:visible;"
+ inkscape:isstock="true">
+ <path
+ id="path1525"
+ d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
+ transform="scale(0.2) rotate(180) translate(6,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Send"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="marker1475"
+ style="overflow:visible;"
+ inkscape:isstock="true">
+ <path
+ id="path1473"
+ d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
+ transform="scale(0.2) rotate(180) translate(6,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow2Mend"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="Arrow2Mend"
+ style="overflow:visible;"
+ inkscape:isstock="true">
+ <path
+ id="path1052"
+ style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
+ d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
+ transform="scale(0.6) rotate(180) translate(0,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow2Sstart"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="Arrow2Sstart"
+ style="overflow:visible"
+ inkscape:isstock="true">
+ <path
+ id="path1055"
+ style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
+ d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
+ transform="scale(0.3) translate(-2.3,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Send"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="marker1335"
+ style="overflow:visible;"
+ inkscape:isstock="true">
+ <path
+ id="path1333"
+ d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
+ transform="scale(0.2) rotate(180) translate(6,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Send"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="Arrow1Send"
+ style="overflow:visible;"
+ inkscape:isstock="true">
+ <path
+ id="path1040"
+ d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
+ transform="scale(0.2) rotate(180) translate(6,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Mend"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="Arrow1Mend"
+ style="overflow:visible;"
+ inkscape:isstock="true">
+ <path
+ id="path1034"
+ d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
+ transform="scale(0.4) rotate(180) translate(10,0)" />
+ </marker>
+ <inkscape:path-effect
+ effect="bspline"
+ id="path-effect1023"
+ is_visible="true"
+ weight="33.333333"
+ steps="2"
+ helper_size="0"
+ apply_no_weight="true"
+ apply_with_weight="true"
+ only_selected="false" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1.979899"
+ inkscape:cx="66.103038"
+ inkscape:cy="189.53698"
+ inkscape:document-units="mm"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:snap-global="true"
+ inkscape:snap-bbox="true"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0"
+ inkscape:window-width="1920"
+ inkscape:window-height="1031"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ inkscape:window-maximized="1"
+ inkscape:pagecheckerboard="true"
+ units="mm"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="true"
+ inkscape:object-paths="true"
+ inkscape:snap-intersection-paths="true"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:snap-midpoints="true"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
+ inkscape:snap-text-baseline="true"
+ inkscape:snap-page="true"
+ inkscape:lockguides="false">
+ <sodipodi:guide
+ orientation="0,1"
+ position="13.637059,643.40404"
+ id="guide3788"
+ inkscape:locked="false" />
+ <sodipodi:guide
+ position="188.97638,188.97638"
+ orientation="0,1"
+ id="guide1099"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="188.97638,188.97638"
+ orientation="1,0"
+ id="guide1101"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="-25.75889,207.87402"
+ orientation="0,1"
+ id="guide837"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="-43.941635,170.07874"
+ orientation="0,1"
+ id="guide854"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="170.07874,284.018"
+ orientation="1,0"
+ id="guide877"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="207.87402,258.09397"
+ orientation="1,0"
+ id="guide879"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="102.53048,247.56521"
+ orientation="0,1"
+ id="guide914"
+ inkscape:locked="false" />
+ <sodipodi:guide
+ position="85.03952,130.38754"
+ orientation="0,1"
+ id="guide916"
+ inkscape:locked="false" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-167.28122,-322.85977)">
+ <rect
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#c8c8c8;fill-opacity:1;fill-rule:nonzero;stroke:#c8c8c8;stroke-width:13.7840004;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:23.10000038;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ id="rect4136-3-5"
+ width="156.29443"
+ height="103.39367"
+ x="174.17352"
+ y="460.13931" />
+ <rect
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#c8c8c8;stroke-width:13.7840004;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:23.10000038;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ id="rect4136-3-5-3"
+ width="156.29443"
+ height="103.39367"
+ x="382.04724"
+ y="460.13931" />
+ </g>
+</svg>
diff --git a/tagit/assets/icons/scalable/browser/select_add.svg b/tagit/assets/icons/scalable/browser/select_add.svg
new file mode 100644
index 0000000..a7d771c
--- /dev/null
+++ b/tagit/assets/icons/scalable/browser/select_add.svg
@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100mm"
+ height="100mm"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92.3 (2405546, 2018-03-11)"
+ sodipodi:docname="select_add.svg"
+ inkscape:export-filename="../../kivy/browser/select_add.png"
+ inkscape:export-xdpi="7.6199999"
+ inkscape:export-ydpi="7.6199999">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1.979899"
+ inkscape:cx="62.016423"
+ inkscape:cy="199.39131"
+ inkscape:document-units="mm"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:snap-global="true"
+ inkscape:snap-bbox="true"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0"
+ inkscape:window-width="1920"
+ inkscape:window-height="1031"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ inkscape:window-maximized="1"
+ inkscape:pagecheckerboard="true"
+ units="mm"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="true"
+ inkscape:object-paths="true"
+ inkscape:snap-intersection-paths="true"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:snap-midpoints="true"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
+ inkscape:snap-text-baseline="true"
+ inkscape:snap-page="true"
+ inkscape:lockguides="false">
+ <sodipodi:guide
+ orientation="0,1"
+ position="13.637059,643.40404"
+ id="guide3788"
+ inkscape:locked="false" />
+ <sodipodi:guide
+ position="188.97638,188.97638"
+ orientation="0,1"
+ id="guide1099"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="188.97638,188.97638"
+ orientation="1,0"
+ id="guide1101"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="-25.75889,207.87402"
+ orientation="0,1"
+ id="guide837"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="-43.941635,170.07874"
+ orientation="0,1"
+ id="guide854"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="170.07874,284.018"
+ orientation="1,0"
+ id="guide877"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="207.87402,258.09397"
+ orientation="1,0"
+ id="guide879"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="102.53048,247.56521"
+ orientation="0,1"
+ id="guide914"
+ inkscape:locked="false" />
+ <sodipodi:guide
+ position="85.03952,130.38754"
+ orientation="0,1"
+ id="guide916"
+ inkscape:locked="false" />
+ <sodipodi:guide
+ position="292.91339,281.32748"
+ orientation="1,0"
+ id="guide918"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-167.28122,-322.85977)">
+ <rect
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#c8c8c8;fill-opacity:1;fill-rule:nonzero;stroke:#c8c8c8;stroke-width:13.7840004;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:23.10000038;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ id="rect4136-3-5"
+ width="156.29443"
+ height="103.39367"
+ x="174.17352"
+ y="460.13931" />
+ <rect
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#c8c8c8;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:17.84657669;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:23.10000038;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ id="rect4136-7-5"
+ width="29.217978"
+ height="117.93987"
+ x="446.58844"
+ y="452.86621" />
+ <rect
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#c8c8c8;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:17.84657669;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:23.10000038;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ id="rect4136-7-5-2"
+ width="29.217978"
+ height="117.93987"
+ x="-526.44513"
+ y="402.22751"
+ transform="rotate(-90)" />
+ </g>
+</svg>
diff --git a/tagit/assets/icons/scalable/browser/select_all.svg b/tagit/assets/icons/scalable/browser/select_all.svg
new file mode 100644
index 0000000..21f9fe5
--- /dev/null
+++ b/tagit/assets/icons/scalable/browser/select_all.svg
@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100mm"
+ height="100mm"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92.3 (2405546, 2018-03-11)"
+ sodipodi:docname="select_all.svg"
+ inkscape:export-filename="../../kivy/browser/select_all.png"
+ inkscape:export-xdpi="7.6199999"
+ inkscape:export-ydpi="7.6199999">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1.979899"
+ inkscape:cx="139.54563"
+ inkscape:cy="201.41162"
+ inkscape:document-units="mm"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:snap-global="true"
+ inkscape:snap-bbox="true"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0"
+ inkscape:window-width="1920"
+ inkscape:window-height="1031"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ inkscape:window-maximized="1"
+ inkscape:pagecheckerboard="true"
+ units="mm"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="true"
+ inkscape:object-paths="true"
+ inkscape:snap-intersection-paths="true"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:snap-midpoints="true"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
+ inkscape:snap-text-baseline="true"
+ inkscape:snap-page="true"
+ inkscape:lockguides="false">
+ <sodipodi:guide
+ orientation="0,1"
+ position="13.637059,643.40404"
+ id="guide3788"
+ inkscape:locked="false" />
+ <sodipodi:guide
+ position="188.97638,188.97638"
+ orientation="0,1"
+ id="guide1099"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="188.97638,188.97638"
+ orientation="1,0"
+ id="guide1101"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="-25.75889,207.87402"
+ orientation="0,1"
+ id="guide837"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="-43.941635,170.07874"
+ orientation="0,1"
+ id="guide854"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="170.07874,284.018"
+ orientation="1,0"
+ id="guide877"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="207.87402,258.09397"
+ orientation="1,0"
+ id="guide879"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-167.28122,-322.85977)">
+ <rect
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#c8c8c8;fill-opacity:1;fill-rule:nonzero;stroke:#c8c8c8;stroke-width:13.78430176;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:23.10000038;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ id="rect4136-3-5"
+ width="156.29443"
+ height="103.39367"
+ x="174.17337"
+ y="382.65268" />
+ <rect
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#c8c8c8;fill-opacity:1;fill-rule:nonzero;stroke:#c8c8c8;stroke-width:13.78430176;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:23.10000038;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ id="rect4136-3-5-2"
+ width="156.29443"
+ height="103.39367"
+ x="382.04739"
+ y="382.65268" />
+ <rect
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#c8c8c8;fill-opacity:1;fill-rule:nonzero;stroke:#c8c8c8;stroke-width:13.78430176;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:23.10000038;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ id="rect4136-3-5-9"
+ width="156.29443"
+ height="103.39367"
+ x="174.17337"
+ y="537.62592" />
+ <rect
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#c8c8c8;fill-opacity:1;fill-rule:nonzero;stroke:#c8c8c8;stroke-width:13.78430176;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:23.10000038;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ id="rect4136-3-5-1"
+ width="156.29443"
+ height="103.39367"
+ x="382.04739"
+ y="537.62592" />
+ </g>
+</svg>
diff --git a/tagit/assets/icons/scalable/browser/select_invert.svg b/tagit/assets/icons/scalable/browser/select_invert.svg
new file mode 100644
index 0000000..9f7ba65
--- /dev/null
+++ b/tagit/assets/icons/scalable/browser/select_invert.svg
@@ -0,0 +1,255 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100mm"
+ height="100mm"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92.3 (2405546, 2018-03-11)"
+ sodipodi:docname="select_invert.svg"
+ inkscape:export-filename="../../kivy/browser/select_invert.png"
+ inkscape:export-xdpi="7.6199999"
+ inkscape:export-ydpi="7.6199999">
+ <defs
+ id="defs4">
+ <marker
+ inkscape:stockid="Arrow2Mend"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="Arrow2Mend"
+ style="overflow:visible;"
+ inkscape:isstock="true">
+ <path
+ id="path935"
+ style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#c8c8c8;stroke-opacity:1;fill:#c8c8c8;fill-opacity:1"
+ d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
+ transform="scale(0.6) rotate(180) translate(0,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow2Lend"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="Arrow2Lend"
+ style="overflow:visible;"
+ inkscape:isstock="true">
+ <path
+ id="path929"
+ style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
+ d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
+ transform="scale(1.1) rotate(180) translate(1,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Send"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="Arrow1Send"
+ style="overflow:visible;"
+ inkscape:isstock="true">
+ <path
+ id="path923"
+ d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
+ transform="scale(0.2) rotate(180) translate(6,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Mend"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="Arrow1Mend"
+ style="overflow:visible;"
+ inkscape:isstock="true">
+ <path
+ id="path917"
+ d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
+ transform="scale(0.4) rotate(180) translate(10,0)" />
+ </marker>
+ <inkscape:path-effect
+ effect="bspline"
+ id="path-effect906"
+ is_visible="true"
+ weight="33.333333"
+ steps="2"
+ helper_size="0"
+ apply_no_weight="true"
+ apply_with_weight="true"
+ only_selected="false" />
+ <marker
+ inkscape:stockid="Arrow2Mend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow2Mend-3"
+ style="overflow:visible"
+ inkscape:isstock="true">
+ <path
+ inkscape:connector-curvature="0"
+ id="path935-6"
+ style="fill:#c8c8c8;fill-opacity:1;fill-rule:evenodd;stroke:#c8c8c8;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+ transform="scale(-0.6)" />
+ </marker>
+ <inkscape:path-effect
+ effect="bspline"
+ id="path-effect906-7"
+ is_visible="true"
+ weight="33.333333"
+ steps="2"
+ helper_size="0"
+ apply_no_weight="true"
+ apply_with_weight="true"
+ only_selected="false" />
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath1751-3">
+ <path
+ style="fill:#0cc8c8;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 167.28122,700.81253 545.23398,322.85977 H 167.28122 Z"
+ id="path1753-5"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath1780">
+ <rect
+ style="opacity:1;fill:#c8c8c8;fill-opacity:1;stroke:none;stroke-width:30;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:fill markers stroke"
+ id="rect1782"
+ width="377.95276"
+ height="377.95276"
+ x="167.28122"
+ y="322.85977"
+ clip-path="url(#clipPath1751-3)"
+ transform="rotate(180,356.2576,511.83615)" />
+ </clipPath>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1.979899"
+ inkscape:cx="183.64532"
+ inkscape:cy="182.16579"
+ inkscape:document-units="mm"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:snap-global="true"
+ inkscape:snap-bbox="true"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0"
+ inkscape:window-width="1920"
+ inkscape:window-height="1031"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ inkscape:window-maximized="1"
+ inkscape:pagecheckerboard="true"
+ units="mm"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="true"
+ inkscape:object-paths="true"
+ inkscape:snap-intersection-paths="true"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:snap-midpoints="true"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
+ inkscape:snap-text-baseline="true"
+ inkscape:snap-page="true"
+ showborder="true">
+ <sodipodi:guide
+ orientation="0,1"
+ position="13.637059,643.40404"
+ id="guide3788"
+ inkscape:locked="false" />
+ <sodipodi:guide
+ position="188.97638,188.97638"
+ orientation="0,1"
+ id="guide1099"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="188.97638,188.97638"
+ orientation="1,0"
+ id="guide1101"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="233.588,370"
+ orientation="1,0"
+ id="guide1107"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="144.36496,311.42857"
+ orientation="1,0"
+ id="guide1109"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="5.000315,233.58779"
+ orientation="0,1"
+ id="guide1113"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="-305.71429,497.85714"
+ orientation="0,1"
+ id="guide822"
+ inkscape:locked="false" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-167.28122,-322.85977)">
+ <circle
+ style="opacity:1;fill:#c8c8c8;fill-opacity:1;stroke:none;stroke-width:30;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:fill markers stroke"
+ id="path1743"
+ cx="347.08838"
+ cy="516.96478"
+ r="103.03556"
+ clip-path="url(#clipPath1780)"
+ transform="translate(9.1692211,-5.1286368)" />
+ <path
+ style="fill:#c8c8c8;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 0 0 L 0 377.95312 L 116.16406 261.78906 A 103.03556 103.03556 0 0 1 85.941406 188.97656 A 103.03556 103.03556 0 0 1 188.97656 85.941406 A 103.03556 103.03556 0 0 1 261.78711 116.16602 L 377.95312 0 L 0 0 z "
+ transform="translate(167.28122,322.85977)"
+ id="path1895" />
+ </g>
+</svg>
diff --git a/tagit/assets/icons/scalable/browser/select_multi.svg b/tagit/assets/icons/scalable/browser/select_multi.svg
new file mode 100644
index 0000000..5912429
--- /dev/null
+++ b/tagit/assets/icons/scalable/browser/select_multi.svg
@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100mm"
+ height="100mm"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92.3 (2405546, 2018-03-11)"
+ sodipodi:docname="select_multi.svg"
+ inkscape:export-filename="../../kivy/browser/select_multi.png"
+ inkscape:export-xdpi="7.6199999"
+ inkscape:export-ydpi="7.6199999">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1.979899"
+ inkscape:cx="139.54563"
+ inkscape:cy="201.41162"
+ inkscape:document-units="mm"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:snap-global="true"
+ inkscape:snap-bbox="true"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0"
+ inkscape:window-width="1920"
+ inkscape:window-height="1031"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ inkscape:window-maximized="1"
+ inkscape:pagecheckerboard="true"
+ units="mm"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="true"
+ inkscape:object-paths="true"
+ inkscape:snap-intersection-paths="true"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:snap-midpoints="true"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
+ inkscape:snap-text-baseline="true"
+ inkscape:snap-page="true"
+ inkscape:lockguides="false">
+ <sodipodi:guide
+ orientation="0,1"
+ position="13.637059,643.40404"
+ id="guide3788"
+ inkscape:locked="false" />
+ <sodipodi:guide
+ position="188.97638,188.97638"
+ orientation="0,1"
+ id="guide1099"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="188.97638,188.97638"
+ orientation="1,0"
+ id="guide1101"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="-25.75889,207.87402"
+ orientation="0,1"
+ id="guide837"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="-43.941635,170.07874"
+ orientation="0,1"
+ id="guide854"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="170.07874,284.018"
+ orientation="1,0"
+ id="guide877"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="207.87402,258.09397"
+ orientation="1,0"
+ id="guide879"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-167.28122,-322.85977)">
+ <rect
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#c8c8c8;fill-opacity:1;fill-rule:nonzero;stroke:#c8c8c8;stroke-width:13.7840004;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:23.10000038;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ id="rect4136-3-5"
+ width="156.29443"
+ height="103.39367"
+ x="174.17337"
+ y="382.65268" />
+ <rect
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#c8c8c8;fill-opacity:1;fill-rule:nonzero;stroke:#c8c8c8;stroke-width:13.7840004;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:23.10000038;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ id="rect4136-3-5-2"
+ width="156.29443"
+ height="103.39367"
+ x="382.04739"
+ y="382.65268" />
+ <rect
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#c8c8c8;stroke-width:13.7840004;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:23.10000038;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ id="rect4136-3-5-9"
+ width="156.29443"
+ height="103.39367"
+ x="174.17337"
+ y="537.62592" />
+ <rect
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#c8c8c8;fill-opacity:1;fill-rule:nonzero;stroke:#c8c8c8;stroke-width:13.7840004;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:23.10000038;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ id="rect4136-3-5-1"
+ width="156.29443"
+ height="103.39367"
+ x="382.04739"
+ y="537.62592" />
+ </g>
+</svg>
diff --git a/tagit/assets/icons/scalable/browser/select_none.svg b/tagit/assets/icons/scalable/browser/select_none.svg
new file mode 100644
index 0000000..e0d807b
--- /dev/null
+++ b/tagit/assets/icons/scalable/browser/select_none.svg
@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100mm"
+ height="100mm"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92.3 (2405546, 2018-03-11)"
+ sodipodi:docname="select_none.svg"
+ inkscape:export-filename="../../kivy/browser/select_none.png"
+ inkscape:export-xdpi="7.6199999"
+ inkscape:export-ydpi="7.6199999">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1.979899"
+ inkscape:cx="62.016423"
+ inkscape:cy="199.39131"
+ inkscape:document-units="mm"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:snap-global="true"
+ inkscape:snap-bbox="true"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0"
+ inkscape:window-width="1920"
+ inkscape:window-height="1031"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ inkscape:window-maximized="1"
+ inkscape:pagecheckerboard="true"
+ units="mm"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="true"
+ inkscape:object-paths="true"
+ inkscape:snap-intersection-paths="true"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:snap-midpoints="true"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
+ inkscape:snap-text-baseline="true"
+ inkscape:snap-page="true"
+ inkscape:lockguides="false">
+ <sodipodi:guide
+ orientation="0,1"
+ position="13.637059,643.40404"
+ id="guide3788"
+ inkscape:locked="false" />
+ <sodipodi:guide
+ position="188.97638,188.97638"
+ orientation="0,1"
+ id="guide1099"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="188.97638,188.97638"
+ orientation="1,0"
+ id="guide1101"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="-25.75889,207.87402"
+ orientation="0,1"
+ id="guide837"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="-43.941635,170.07874"
+ orientation="0,1"
+ id="guide854"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="170.07874,284.018"
+ orientation="1,0"
+ id="guide877"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="207.87402,258.09397"
+ orientation="1,0"
+ id="guide879"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-167.28122,-322.85977)">
+ <rect
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#c8c8c8;stroke-width:13.7840004;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:23.10000038;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ id="rect4136-3-5"
+ width="156.29443"
+ height="103.39367"
+ x="174.17337"
+ y="382.65268" />
+ <rect
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#c8c8c8;stroke-width:13.7840004;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:23.10000038;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ id="rect4136-3-5-2"
+ width="156.29443"
+ height="103.39367"
+ x="382.04739"
+ y="382.65268" />
+ <rect
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#c8c8c8;stroke-width:13.7840004;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:23.10000038;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ id="rect4136-3-5-9"
+ width="156.29443"
+ height="103.39367"
+ x="174.17337"
+ y="537.62592" />
+ <rect
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#c8c8c8;stroke-width:13.7840004;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:23.10000038;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ id="rect4136-3-5-1"
+ width="156.29443"
+ height="103.39367"
+ x="382.04739"
+ y="537.62592" />
+ </g>
+</svg>
diff --git a/tagit/assets/icons/scalable/browser/select_range.svg b/tagit/assets/icons/scalable/browser/select_range.svg
new file mode 100644
index 0000000..e3aa805
--- /dev/null
+++ b/tagit/assets/icons/scalable/browser/select_range.svg
@@ -0,0 +1,312 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100mm"
+ height="100mm"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92.3 (2405546, 2018-03-11)"
+ sodipodi:docname="select_range.svg"
+ inkscape:export-filename="../../kivy/browser/select_range.png"
+ inkscape:export-xdpi="7.6199999"
+ inkscape:export-ydpi="7.6199999">
+ <defs
+ id="defs4">
+ <marker
+ inkscape:stockid="Arrow2Send"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="Arrow2Send"
+ style="overflow:visible;"
+ inkscape:isstock="true">
+ <path
+ id="path1058"
+ style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#c8c8c8;stroke-opacity:1;fill:#c8c8c8;fill-opacity:1"
+ d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
+ transform="scale(0.3) rotate(180) translate(-2.3,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Send"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="marker1609"
+ style="overflow:visible;"
+ inkscape:isstock="true">
+ <path
+ id="path1607"
+ d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
+ transform="scale(0.2) rotate(180) translate(6,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Send"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="marker1527"
+ style="overflow:visible;"
+ inkscape:isstock="true">
+ <path
+ id="path1525"
+ d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
+ transform="scale(0.2) rotate(180) translate(6,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Send"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="marker1475"
+ style="overflow:visible;"
+ inkscape:isstock="true">
+ <path
+ id="path1473"
+ d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
+ transform="scale(0.2) rotate(180) translate(6,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow2Mend"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="Arrow2Mend"
+ style="overflow:visible;"
+ inkscape:isstock="true">
+ <path
+ id="path1052"
+ style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
+ d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
+ transform="scale(0.6) rotate(180) translate(0,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow2Sstart"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="Arrow2Sstart"
+ style="overflow:visible"
+ inkscape:isstock="true">
+ <path
+ id="path1055"
+ style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
+ d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
+ transform="scale(0.3) translate(-2.3,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Send"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="marker1335"
+ style="overflow:visible;"
+ inkscape:isstock="true">
+ <path
+ id="path1333"
+ d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
+ transform="scale(0.2) rotate(180) translate(6,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Send"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="Arrow1Send"
+ style="overflow:visible;"
+ inkscape:isstock="true">
+ <path
+ id="path1040"
+ d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
+ transform="scale(0.2) rotate(180) translate(6,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Mend"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="Arrow1Mend"
+ style="overflow:visible;"
+ inkscape:isstock="true">
+ <path
+ id="path1034"
+ d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
+ transform="scale(0.4) rotate(180) translate(10,0)" />
+ </marker>
+ <inkscape:path-effect
+ effect="bspline"
+ id="path-effect1023"
+ is_visible="true"
+ weight="33.333333"
+ steps="2"
+ helper_size="0"
+ apply_no_weight="true"
+ apply_with_weight="true"
+ only_selected="false" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="2.8"
+ inkscape:cx="89.108921"
+ inkscape:cy="176.88932"
+ inkscape:document-units="mm"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:snap-global="true"
+ inkscape:snap-bbox="true"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0"
+ inkscape:window-width="1920"
+ inkscape:window-height="1031"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ inkscape:window-maximized="1"
+ inkscape:pagecheckerboard="true"
+ units="mm"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="true"
+ inkscape:object-paths="true"
+ inkscape:snap-intersection-paths="true"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:snap-midpoints="true"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
+ inkscape:snap-text-baseline="true"
+ inkscape:snap-page="true"
+ inkscape:lockguides="false">
+ <sodipodi:guide
+ orientation="0,1"
+ position="13.637059,643.40404"
+ id="guide3788"
+ inkscape:locked="false" />
+ <sodipodi:guide
+ position="188.97638,188.97638"
+ orientation="0,1"
+ id="guide1099"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="188.97638,188.97638"
+ orientation="1,0"
+ id="guide1101"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="-25.75889,207.87402"
+ orientation="0,1"
+ id="guide837"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="-43.941635,170.07874"
+ orientation="0,1"
+ id="guide854"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="170.07874,284.018"
+ orientation="1,0"
+ id="guide877"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="207.87402,258.09397"
+ orientation="1,0"
+ id="guide879"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="102.53048,247.56521"
+ orientation="0,1"
+ id="guide914"
+ inkscape:locked="false" />
+ <sodipodi:guide
+ position="85.03952,130.38754"
+ orientation="0,1"
+ id="guide916"
+ inkscape:locked="false" />
+ <sodipodi:guide
+ position="292.91339,281.32748"
+ orientation="1,0"
+ id="guide918"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="329.83559,230.81985"
+ orientation="1,0"
+ inkscape:locked="false"
+ id="guide1811"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-167.28122,-322.85977)">
+ <rect
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#c8c8c8;fill-opacity:1;fill-rule:nonzero;stroke:#c8c8c8;stroke-width:13.7840004;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:23.10000038;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ id="rect4136-3-5"
+ width="156.29443"
+ height="103.39367"
+ x="174.17352"
+ y="460.13931" />
+ <rect
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#c8c8c8;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:17.84657669;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:23.10000038;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ id="rect4136-7-5-2"
+ width="29.217978"
+ height="117.93987"
+ x="516.01599"
+ y="452.86621" />
+ <path
+ style="fill:none;stroke:#c8c8c8;stroke-width:18.90862083;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Send)"
+ d="m 356.2576,511.83615 c 37.38613,0 74.77137,0 112.15571,0"
+ id="path1021"
+ inkscape:connector-curvature="0"
+ inkscape:path-effect="#path-effect1023"
+ inkscape:original-d="m 356.2576,511.83615 c 37.38613,-10e-4 74.77137,-10e-4 112.15571,0" />
+ </g>
+</svg>
diff --git a/tagit/assets/icons/scalable/browser/select_single.svg b/tagit/assets/icons/scalable/browser/select_single.svg
new file mode 100644
index 0000000..6b9ab45
--- /dev/null
+++ b/tagit/assets/icons/scalable/browser/select_single.svg
@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100mm"
+ height="100mm"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92.3 (2405546, 2018-03-11)"
+ sodipodi:docname="select_single.svg"
+ inkscape:export-filename="../../kivy/browser/select_single.png"
+ inkscape:export-xdpi="7.6199999"
+ inkscape:export-ydpi="7.6199999">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1.979899"
+ inkscape:cx="62.016423"
+ inkscape:cy="199.39131"
+ inkscape:document-units="mm"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:snap-global="true"
+ inkscape:snap-bbox="true"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0"
+ inkscape:window-width="1920"
+ inkscape:window-height="1031"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ inkscape:window-maximized="1"
+ inkscape:pagecheckerboard="true"
+ units="mm"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="true"
+ inkscape:object-paths="true"
+ inkscape:snap-intersection-paths="true"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:snap-midpoints="true"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
+ inkscape:snap-text-baseline="true"
+ inkscape:snap-page="true"
+ inkscape:lockguides="false">
+ <sodipodi:guide
+ orientation="0,1"
+ position="13.637059,643.40404"
+ id="guide3788"
+ inkscape:locked="false" />
+ <sodipodi:guide
+ position="188.97638,188.97638"
+ orientation="0,1"
+ id="guide1099"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="188.97638,188.97638"
+ orientation="1,0"
+ id="guide1101"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="-25.75889,207.87402"
+ orientation="0,1"
+ id="guide837"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="-43.941635,170.07874"
+ orientation="0,1"
+ id="guide854"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="170.07874,284.018"
+ orientation="1,0"
+ id="guide877"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="207.87402,258.09397"
+ orientation="1,0"
+ id="guide879"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-167.28122,-322.85977)">
+ <rect
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#c8c8c8;fill-opacity:1;fill-rule:nonzero;stroke:#c8c8c8;stroke-width:13.7840004;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:23.10000038;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ id="rect4136-3-5"
+ width="156.29443"
+ height="103.39367"
+ x="174.17337"
+ y="382.65268" />
+ <rect
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#c8c8c8;stroke-width:13.7840004;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:23.10000038;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ id="rect4136-3-5-2"
+ width="156.29443"
+ height="103.39367"
+ x="382.04739"
+ y="382.65268" />
+ <rect
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#c8c8c8;stroke-width:13.7840004;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:23.10000038;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ id="rect4136-3-5-9"
+ width="156.29443"
+ height="103.39367"
+ x="174.17337"
+ y="537.62592" />
+ <rect
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#c8c8c8;stroke-width:13.7840004;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:23.10000038;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ id="rect4136-3-5-1"
+ width="156.29443"
+ height="103.39367"
+ x="382.04739"
+ y="537.62592" />
+ </g>
+</svg>
diff --git a/tagit/assets/icons/scalable/browser/select_sub.svg b/tagit/assets/icons/scalable/browser/select_sub.svg
new file mode 100644
index 0000000..724e4d0
--- /dev/null
+++ b/tagit/assets/icons/scalable/browser/select_sub.svg
@@ -0,0 +1,162 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100mm"
+ height="100mm"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92.3 (2405546, 2018-03-11)"
+ sodipodi:docname="select_sub.svg"
+ inkscape:export-filename="../../kivy/browser/select_sub.png"
+ inkscape:export-xdpi="7.6199999"
+ inkscape:export-ydpi="7.6199999">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="2.8"
+ inkscape:cx="89.108921"
+ inkscape:cy="176.88932"
+ inkscape:document-units="mm"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:snap-global="true"
+ inkscape:snap-bbox="true"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0"
+ inkscape:window-width="1920"
+ inkscape:window-height="1031"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ inkscape:window-maximized="1"
+ inkscape:pagecheckerboard="true"
+ units="mm"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="true"
+ inkscape:object-paths="true"
+ inkscape:snap-intersection-paths="true"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:snap-midpoints="true"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
+ inkscape:snap-text-baseline="true"
+ inkscape:snap-page="true"
+ inkscape:lockguides="false">
+ <sodipodi:guide
+ orientation="0,1"
+ position="13.637059,643.40404"
+ id="guide3788"
+ inkscape:locked="false" />
+ <sodipodi:guide
+ position="188.97638,188.97638"
+ orientation="0,1"
+ id="guide1099"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="188.97638,188.97638"
+ orientation="1,0"
+ id="guide1101"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="-25.75889,207.87402"
+ orientation="0,1"
+ id="guide837"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="-43.941635,170.07874"
+ orientation="0,1"
+ id="guide854"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="170.07874,284.018"
+ orientation="1,0"
+ id="guide877"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="207.87402,258.09397"
+ orientation="1,0"
+ id="guide879"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="102.53048,247.56521"
+ orientation="0,1"
+ id="guide914"
+ inkscape:locked="false" />
+ <sodipodi:guide
+ position="85.03952,130.38754"
+ orientation="0,1"
+ id="guide916"
+ inkscape:locked="false" />
+ <sodipodi:guide
+ position="292.91339,281.32748"
+ orientation="1,0"
+ id="guide918"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-167.28122,-322.85977)">
+ <rect
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#c8c8c8;fill-opacity:1;fill-rule:nonzero;stroke:#c8c8c8;stroke-width:13.7840004;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:23.10000038;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ id="rect4136-3-5"
+ width="156.29443"
+ height="103.39367"
+ x="174.17352"
+ y="460.13931" />
+ <rect
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#c8c8c8;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:17.84657669;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:23.10000038;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ id="rect4136-7-5-2"
+ width="29.217978"
+ height="117.93987"
+ x="-526.44513"
+ y="402.22751"
+ transform="rotate(-90)" />
+ </g>
+</svg>
diff --git a/tagit/assets/icons/scalable/browser/zoom_in.svg b/tagit/assets/icons/scalable/browser/zoom_in.svg
new file mode 100644
index 0000000..f61660c
--- /dev/null
+++ b/tagit/assets/icons/scalable/browser/zoom_in.svg
@@ -0,0 +1,241 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100mm"
+ height="100mm"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92.3 (2405546, 2018-03-11)"
+ sodipodi:docname="zoom_in.svg"
+ inkscape:export-filename="../../kivy/browser/zoom_in.png"
+ inkscape:export-xdpi="7.6199999"
+ inkscape:export-ydpi="7.6199999">
+ <defs
+ id="defs4">
+ <marker
+ inkscape:stockid="Arrow2Mend"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="Arrow2Mend"
+ style="overflow:visible;"
+ inkscape:isstock="true">
+ <path
+ id="path935"
+ style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#c8c8c8;stroke-opacity:1;fill:#c8c8c8;fill-opacity:1"
+ d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
+ transform="scale(0.6) rotate(180) translate(0,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow2Lend"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="Arrow2Lend"
+ style="overflow:visible;"
+ inkscape:isstock="true">
+ <path
+ id="path929"
+ style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
+ d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
+ transform="scale(1.1) rotate(180) translate(1,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Send"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="Arrow1Send"
+ style="overflow:visible;"
+ inkscape:isstock="true">
+ <path
+ id="path923"
+ d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
+ transform="scale(0.2) rotate(180) translate(6,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Mend"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="Arrow1Mend"
+ style="overflow:visible;"
+ inkscape:isstock="true">
+ <path
+ id="path917"
+ d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
+ transform="scale(0.4) rotate(180) translate(10,0)" />
+ </marker>
+ <inkscape:path-effect
+ effect="bspline"
+ id="path-effect906"
+ is_visible="true"
+ weight="33.333333"
+ steps="2"
+ helper_size="0"
+ apply_no_weight="true"
+ apply_with_weight="true"
+ only_selected="false" />
+ <marker
+ inkscape:stockid="Arrow2Mend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow2Mend-3"
+ style="overflow:visible"
+ inkscape:isstock="true">
+ <path
+ inkscape:connector-curvature="0"
+ id="path935-6"
+ style="fill:#c8c8c8;fill-opacity:1;fill-rule:evenodd;stroke:#c8c8c8;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+ transform="scale(-0.6)" />
+ </marker>
+ <inkscape:path-effect
+ effect="bspline"
+ id="path-effect906-7"
+ is_visible="true"
+ weight="33.333333"
+ steps="2"
+ helper_size="0"
+ apply_no_weight="true"
+ apply_with_weight="true"
+ only_selected="false" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1.979899"
+ inkscape:cx="183.64532"
+ inkscape:cy="182.16579"
+ inkscape:document-units="mm"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:snap-global="true"
+ inkscape:snap-bbox="true"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0"
+ inkscape:window-width="1920"
+ inkscape:window-height="1031"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ inkscape:window-maximized="1"
+ inkscape:pagecheckerboard="true"
+ units="mm"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="true"
+ inkscape:object-paths="true"
+ inkscape:snap-intersection-paths="true"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:snap-midpoints="true"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
+ inkscape:snap-text-baseline="true"
+ inkscape:snap-page="true"
+ showborder="true">
+ <sodipodi:guide
+ orientation="0,1"
+ position="13.637059,643.40404"
+ id="guide3788"
+ inkscape:locked="false" />
+ <sodipodi:guide
+ position="188.97638,188.97638"
+ orientation="0,1"
+ id="guide1099"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="188.97638,188.97638"
+ orientation="1,0"
+ id="guide1101"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="233.588,370"
+ orientation="1,0"
+ id="guide1107"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="144.36496,311.42857"
+ orientation="1,0"
+ id="guide1109"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="-77.142857,144.36496"
+ orientation="0,1"
+ id="guide1111"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="5.000315,233.58779"
+ orientation="0,1"
+ id="guide1113"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="-305.71429,497.85714"
+ orientation="0,1"
+ id="guide822"
+ inkscape:locked="false" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-167.28122,-322.85977)">
+ <path
+ style="fill:none;stroke:#c8c8c8;stroke-width:23.83593559;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend)"
+ d="M 179.3116,688.76623 C 229.41562,638.77017 279.51884,588.77492 329.62126,538.78045"
+ id="path904"
+ inkscape:connector-curvature="0"
+ inkscape:path-effect="#path-effect906"
+ inkscape:original-d="M 179.3116,688.76623 C 229.41562,638.77017 279.51883,588.77491 329.62126,538.78045" />
+ <path
+ style="fill:none;stroke:#c8c8c8;stroke-width:23.83593559;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend-3)"
+ d="M 533.22005,334.92184 C 483.11603,384.9179 433.01281,434.91315 382.91039,484.90762"
+ id="path904-5"
+ inkscape:connector-curvature="0"
+ inkscape:path-effect="#path-effect906-7"
+ inkscape:original-d="M 533.22005,334.92184 C 483.11603,384.9179 433.01282,434.91316 382.91039,484.90762" />
+ </g>
+</svg>
diff --git a/tagit/assets/icons/scalable/browser/zoom_out.svg b/tagit/assets/icons/scalable/browser/zoom_out.svg
new file mode 100644
index 0000000..3d45b40
--- /dev/null
+++ b/tagit/assets/icons/scalable/browser/zoom_out.svg
@@ -0,0 +1,241 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100mm"
+ height="100mm"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92.3 (2405546, 2018-03-11)"
+ sodipodi:docname="zoom_out.svg"
+ inkscape:export-filename="../../kivy/browser/zoom_out.png"
+ inkscape:export-xdpi="7.6199999"
+ inkscape:export-ydpi="7.6199999">
+ <defs
+ id="defs4">
+ <marker
+ inkscape:stockid="Arrow2Mend"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="Arrow2Mend"
+ style="overflow:visible;"
+ inkscape:isstock="true">
+ <path
+ id="path935"
+ style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#c8c8c8;stroke-opacity:1;fill:#c8c8c8;fill-opacity:1"
+ d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
+ transform="scale(0.6) rotate(180) translate(0,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow2Lend"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="Arrow2Lend"
+ style="overflow:visible;"
+ inkscape:isstock="true">
+ <path
+ id="path929"
+ style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1"
+ d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
+ transform="scale(1.1) rotate(180) translate(1,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Send"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="Arrow1Send"
+ style="overflow:visible;"
+ inkscape:isstock="true">
+ <path
+ id="path923"
+ d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
+ transform="scale(0.2) rotate(180) translate(6,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Mend"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="Arrow1Mend"
+ style="overflow:visible;"
+ inkscape:isstock="true">
+ <path
+ id="path917"
+ d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1;fill:#000000;fill-opacity:1"
+ transform="scale(0.4) rotate(180) translate(10,0)" />
+ </marker>
+ <inkscape:path-effect
+ effect="bspline"
+ id="path-effect906"
+ is_visible="true"
+ weight="33.333333"
+ steps="2"
+ helper_size="0"
+ apply_no_weight="true"
+ apply_with_weight="true"
+ only_selected="false" />
+ <marker
+ inkscape:stockid="Arrow2Mend"
+ orient="auto"
+ refY="0"
+ refX="0"
+ id="Arrow2Mend-3"
+ style="overflow:visible"
+ inkscape:isstock="true">
+ <path
+ inkscape:connector-curvature="0"
+ id="path935-6"
+ style="fill:#c8c8c8;fill-opacity:1;fill-rule:evenodd;stroke:#c8c8c8;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+ transform="scale(-0.6)" />
+ </marker>
+ <inkscape:path-effect
+ effect="bspline"
+ id="path-effect906-7"
+ is_visible="true"
+ weight="33.333333"
+ steps="2"
+ helper_size="0"
+ apply_no_weight="true"
+ apply_with_weight="true"
+ only_selected="false" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1.979899"
+ inkscape:cx="183.64532"
+ inkscape:cy="182.16579"
+ inkscape:document-units="mm"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:snap-global="true"
+ inkscape:snap-bbox="true"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0"
+ inkscape:window-width="1920"
+ inkscape:window-height="1031"
+ inkscape:window-x="0"
+ inkscape:window-y="25"
+ inkscape:window-maximized="1"
+ inkscape:pagecheckerboard="true"
+ units="mm"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="true"
+ inkscape:object-paths="true"
+ inkscape:snap-intersection-paths="true"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:snap-midpoints="true"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
+ inkscape:snap-text-baseline="true"
+ inkscape:snap-page="true"
+ showborder="true">
+ <sodipodi:guide
+ orientation="0,1"
+ position="13.637059,643.40404"
+ id="guide3788"
+ inkscape:locked="false" />
+ <sodipodi:guide
+ position="188.97638,188.97638"
+ orientation="0,1"
+ id="guide1099"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="188.97638,188.97638"
+ orientation="1,0"
+ id="guide1101"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="233.588,370"
+ orientation="1,0"
+ id="guide1107"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="144.36496,311.42857"
+ orientation="1,0"
+ id="guide1109"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="-77.142857,144.36496"
+ orientation="0,1"
+ id="guide1111"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="5.000315,233.58779"
+ orientation="0,1"
+ id="guide1113"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="-305.71429,497.85714"
+ orientation="0,1"
+ id="guide822"
+ inkscape:locked="false" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-167.28122,-322.85977)">
+ <path
+ style="fill:none;stroke:#c8c8c8;stroke-width:23.83593559;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend)"
+ d="M 368.29607,499.79793 C 418.40009,449.80187 468.50331,399.80662 518.60573,349.81215"
+ id="path904"
+ inkscape:connector-curvature="0"
+ inkscape:path-effect="#path-effect906"
+ inkscape:original-d="M 368.29607,499.79793 C 418.40009,449.80187 468.5033,399.80661 518.60573,349.81215" />
+ <path
+ style="fill:none;stroke:#c8c8c8;stroke-width:23.83593559;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Mend-3)"
+ d="M 344.24368,523.89823 C 294.13966,573.89429 244.03644,623.88955 193.93401,673.88401"
+ id="path904-5"
+ inkscape:connector-curvature="0"
+ inkscape:path-effect="#path-effect906-7"
+ inkscape:original-d="M 344.24368,523.89823 C 294.13966,573.89429 244.03644,623.88955 193.93401,673.88401" />
+ </g>
+</svg>
diff --git a/tagit/config/port-config.yaml b/tagit/config/port-config.yaml
deleted file mode 100644
index d05a498..0000000
--- a/tagit/config/port-config.yaml
+++ /dev/null
@@ -1,115 +0,0 @@
-session:
- first_start: false
- paths:
- searchlog: ~/.tagit.log
-storage:
- index:
- preview_size:
- - 50
- - 200
- - 400
-ui:
- standalone:
- plane: browsing
- browser:
- maxcols: 8
- maxrows: 8
- buttondocks:
- sidebar_left: []
- #- Menu
- #- ShowDashboard
- #- AddTag
- #- EditTag
- #- CreateGroup
- #- DissolveGroup
- #- SelectAll
- #- SelectNone
- #- SelectInvert
- #- SelectAdditive
- #- SelectSubtractive
- #- SelectSingle
- #- SelectMulti
- #- SelectRange
- context:
- app:
- - ShowSettings
- - ShowHelp
- - ShowConsole
- - ShowBrowsing
- # browser:
- # - ZoomIn
- # - ZoomOut
- # clipboard:
- # - ClipboardCopy
- # - ClipboardPaste
- # grouping:
- # - CreateGroup
- # - DissolveGroup
- # - AddToGroup
- # - RepresentGroup
- # - RemoveFromGroup
- # root:
- # - CloseSessionAndExit
- # search:
- # - ShowSelected
- # - RemoveSelected
- # select:
- # - SelectAll
- # - SelectNone
- # - SelectInvert
- # - SelectSingle
- # - SelectMulti
- # - SelectRange
- # - SelectAdditive
- # - SelectSubtractive
- # session:
- # - SaveSession
- # - SaveSessionAs
- # - ItemExport
- # - ImportObjects
- # tagging:
- # - AddTag
- # - EditTag
- # - SetRank1
- # - SetRank3
- # - SetRank5
- search:
- sort_blacklist:
- - entity
- - flash
- - latitude
- - longitude
- - mime
- - author
- - camera
- - attributes
- # FIXME: mb/port/tabs
- #tabs:
- # max: 2
- tiledocks:
- dashboard: {}
- #Buttons:
- # buttons:
- # - ShowBrowsing
- # - CreateSession
- # - CreateTempSession
- # - LoadSession
- # - ReloadSession
- # - ImportObjects
- # - SaveSession
- # - SaveSessionAs
- # - ItemExport
- # - UpdateSelectedObjects
- # - SyncSelectedObjects
- # - ShowHelp
- # - ShowSettings
- #Hints: {}
- #LibSummary: {}
- #Searchtree: {}
- #TagHistogram: {}
- #Tagcloud: {}
- sidebar_right: {}
- #CursorTags: {}
- #Info: {}
- #Venn: {}
- window_size: 1024x768
diff --git a/tagit/utils/shared.py b/tagit/utils/shared.py
index 82fe672..0d496ed 100644
--- a/tagit/utils/shared.py
+++ b/tagit/utils/shared.py
@@ -10,14 +10,17 @@ from collections import namedtuple
import logging
import os
import pkgutil
+import platform
import re
import typing
+import warnings
# exports
__all__: typing.Sequence[str] = (
'Resolution',
'Struct',
'clamp',
+ 'fileopen',
'flatten',
'fst',
'import_all',
@@ -123,4 +126,18 @@ def is_hex(string):
except TypeError:
return False
+def fileopen(pth):
+ """Open a file in the preferred application as a subprocess.
+ This operation is platform dependent.
+ """
+ try:
+ binopen = {
+ "Linux" : "xdg-open", # Linux
+ "darwin" : "open", # MAX OS X
+ "Windows" : "start", # Windows
+ }.get(platform.system())
+ subprocess.call((binopen, pth))
+ except KeyError:
+ warnings.warn('Unknown platform {}'.format(platform.system()))
+
## EOF ##