Scaler for Retina screen - darkopevec/kivy GitHub Wiki
- author: Mathieu Virbel
- kivy: >= 1.3.0
On Retina screen (iOS / iPad 3), the resolution is high (> 2000px) with an high DPI. Kivy currently don't support DPI, and then, all the text will look very tiny etc. We don't have anything for properly handling DPI and the moment, so you could use that Scaler class. You might do some change in order to use it.
#!python
# Put in your App.build() method
from kivy.utils import platform
from scaler import Scaler
class MyApp(App):
def build(self):
# construct your app here
self.root = MyRootWidget()
# special case for retina display, high dpi is not well handled
# in kivy. use scatter to "zoom in"
from kivy.core.window import Window
self._scaler = None
if platform() == 'ios' and (
Window.width > 2000 or Window.height > 2000):
self._scaler = Scaler(
size=Window.size, scale=2)
Window.add_widget(self._scaler)
# add the widget to Window or scaler
parent = self._scaler or Window
parent.add_widget(self.root)
#!python
from kivy.uix.widget import Widget
from kivy.properties import NumericProperty, ObjectProperty
from kivy.base import EventLoop
from kivy.lang import Builder
class Scaler(Widget):
scale = NumericProperty(2)
container = ObjectProperty(None)
def __init__(self, **kwargs):
from kivy.base import EventLoop
from kivy.lang import Builder
Builder.load_string('''
<Scaler>:
container: container
canvas.before:
PushMatrix
Scale:
scale: root.scale
canvas.after:
PopMatrix
FloatLayout:
id: container
size: root.width / root.scale, root.height / root.scale
''')
super(Scaler, self).__init__(**kwargs)
EventLoop.add_postproc_module(self)
def get_parent_window(self):
return self.container
def add_widget(self, widget):
if self.container is not None:
return self.container.add_widget(widget)
return super(Scaler, self).add_widget(widget)
def remove_widget(self, widget):
if self.container is not None:
return self.container.remove_widget(widget)
return super(Scaler, self).remove_widget(widget)
def process_to_local(self, x, y, relative=False):
if x is None:
return None, None
s = float(self.scale)
return x / s, y / s
def process(self, events):
transform = self.process_to_local
transformed = []
for etype, event in events:
# you might have a move and up event in the same process
# then avoid the double-transformation
if event in transformed:
continue
transformed.append(event)
event.sx, event.sy = transform(event.sx, event.sy)
if etype == 'begin':
event.osx, event.osy = transform(event.osx, event.osy)
else:
# update the delta
event.dsx = event.sx - event.psx
event.dsy = event.sy - event.psy
return events
##Comments Add your comments here ...
Is this relevant anymore now that kivy includes kivy.metrics? - Winston Oct 2013