"""Main container widgets of the tagit UI.
Part of the tagit module.
A copy of the license is provided with the project.
Author: Matthias Baumgartner, 2016
"""
# constants
KIVY_IMAGE_CACHE_SIZE = 1000
# imports
from os.path import join, dirname
from kivy.lang import Builder
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import ObjectProperty
from kivy.logger import Logger
from browser import VBrowser
from filter import VFilter
from sidebar import VSidebar
from dialogues import BindingsDialogue
from ..controller.main import CMainWindow, CMainWidget
# Overwrite the cache, after first Image/Loader import
from kivy.uix.image import Image
from kivy.loader import Loader
from kivy.cache import Cache
Cache.register('kv.image', limit=KIVY_IMAGE_CACHE_SIZE, timeout=None)
Cache.register('kv.loader', limit=KIVY_IMAGE_CACHE_SIZE, timeout=None)
# exports
__all__ = ('VMainWindow', 'KIVY_IMAGE_CACHE_SIZE')
# Load kv
Builder.load_file(join(dirname(__file__), 'main.kv'))
# classes
[docs]class VMainWidget(BoxLayout):
"""Main space for images and image search.
Holds the *Browser* and *Filter*. Doesn't do more, actually.
"""
pass
[docs]class VMainWindow(BoxLayout):
"""Collection of all widgets makes this the root for the tagit UI.
If you want the tagit UI, create an app that loads this widget.
>>> settings = ...
>>> model = ...
>>> from tagit.view import VMainWindow
>>> class MyApp(App):
>>> def build(self):
>>> return VMainWindow(settings, model)
>>> app = MyApp()
>>> app.run()
Holds the *MainWidget* and *Sidebar*. Handles keyboard events.
"""
active_widget = ObjectProperty()
__events__ = ('on_keyboard', 'on_key_down', 'on_key_up')
# Event prototypes
def on_key_down(self, (code, key), modifiers): pass
def on_keyboard(self, (code, key), modifiers): pass
def on_key_up(self, (code, key)): pass
def __init__ (self, settings, model, **kwargs):
super(VMainWindow, self).__init__(**kwargs)
self.controller = CMainWindow(self, settings, parent=None)
self.main_widget.controller = self.controller.add_child(CMainWidget, self.main_widget, model=model) # Initializes main_widget # FIXME: Maybe there's another way?
self._forward_keys = True
self.bind(active_widget=self.sidebar.on_widget_change)
self.active_widget = self.main_widget
# Bind key events to controller
self.bind(on_keyboard=self.controller.on_keyboard)
self.bind(on_key_up=self.controller.on_key_up)
self.bind(on_key_down=self.controller.on_key_down)
# activate keybindings
self._enable_keybindings()
def __del__(self):
self._disable_keybindings()
def _enable_keybindings(self):
"""Enables keybindings.
"""
Logger.debug("Enable keybindings")
# This method is preferred over going through request_keyboard
# because through the normal request keyboard access isn't shareable.
# This can lead to conflicts with widgets using the keyboard (e.g. TextInput)
from kivy.core.window import Window
Window.bind(on_key_up=self._on_key_up)
Window.bind(on_key_down=self._on_key_down)
Window.bind(on_keyboard=self._on_keyboard)
def _disable_keybindings(self):
"""Disables keybindings.
"""
Logger.debug("Disable keybindings")
from kivy.core.window import Window
Window.unbind(on_key_up=self._on_key_up)
Window.unbind(on_key_down=self._on_key_down)
Window.unbind(on_keyboard=self._on_keyboard)
def request_exclusive_keyboard(self):
self._forward_keys = False
def release_exclusive_keyboard(self):
self._forward_keys = True
def _on_key_up(self, instance, key, scancode):
self.dispatch('on_key_up', (key, ''))
def _on_key_down(self, instance, key, scancode, codepoint, modifiers):
self.dispatch('on_key_down', (key, ''), modifiers)
def _on_keyboard(self, instance, key, scancode, codepoint, modifiers):
"""Handles keybindings.
Is called when a key press is detected.
WARNING: This method also receives signals intended for other widgets, e.g
the *VFilter* inputs.
*key* : ASCII value
*scancode* : Key code returned by the input provider (e.g. keyboard)
*codepoint* : String representation (if A-Z, a-z)
*modifiers* : 'ctrl', 'shift', 'alt', or any combination thereof, if pressed
"""
if key == 285 and modifiers == ['alt']: # Exit on Alt + F4 (for fullscreen mode!)
from kivy.app import App
App.get_running_app().stop()
if False and self.controller.settings.trace('session', 'debug', False):
Logger.debug('''Keyboard event:
Key : ''' + str(key) + '''
Scancode : ''' + str(scancode) + '''
Codepoint : ''' + str(codepoint) + '''
Modifiers : ''' + str(modifiers) + '''
''')
if self._forward_keys:
self.dispatch('on_keyboard', (key, codepoint), modifiers)
return True
[docs] def display_keybindings(self, bindings):
"""Display an error dialogue."""
dlg = BindingsDialogue(bindings, keyboard_ctrl=self)
dlg.open()
## EOF ##