From 0cfacbebc56c54cc657030e2de2337e0b7d09384 Mon Sep 17 00:00:00 2001 From: Mathieu Virbel Date: Wed, 8 Aug 2012 19:51:28 +0200 Subject: [PATCH] dpi: first commit to implement measurement parsing directly in NumericProperty + dpi in Window/EventLoop --- kivy/base.py | 18 ++++++++++++++++ kivy/core/window/__init__.py | 6 ++++++ kivy/properties.pxd | 3 ++- kivy/properties.pyx | 41 ++++++++++++++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 1 deletion(-) diff --git a/kivy/base.py b/kivy/base.py index d9aa1cf2f..04f455db6 100644 --- a/kivy/base.py +++ b/kivy/base.py @@ -19,6 +19,7 @@ from kivy.config import Config from kivy.logger import Logger from kivy.clock import Clock from kivy.event import EventDispatcher +from kivy.utils import platform # private vars EventLoop = None @@ -85,6 +86,7 @@ class EventLoopBase(EventDispatcher): def __init__(self): super(EventLoopBase, self).__init__() + self._dpi = None self.quit = False self.input_events = [] self.postproc_modules = [] @@ -103,6 +105,22 @@ class EventLoopBase(EventDispatcher): ''' return self.me_list + @property + def dpi(self): + '''Return the DPI of the screen. + + .. versionadded:: 1.4.0 + ''' + if self._dpi is None: + # first call, resolve the dpi + plat = platform() + if plat == 'android': + self._dpi = self.get_dpi() + else: + self.ensure_window() + self._dpi = self.window.get_dpi() + return self._dpi + def ensure_window(self): '''Ensure that we have an window ''' diff --git a/kivy/core/window/__init__.py b/kivy/core/window/__init__.py index 833fc3021..39f8731da 100755 --- a/kivy/core/window/__init__.py +++ b/kivy/core/window/__init__.py @@ -804,6 +804,12 @@ class WindowBase(EventDispatcher): ''' pass + def get_dpi(self): + '''Return the DPI of the screen. If the implementation doesn't support + any DPI lookup, it will just return 75. + ''' + return 75. + def configure_keyboards(self): # Configure how to provide keyboards (virtual or not) diff --git a/kivy/properties.pxd b/kivy/properties.pxd index 47ba06247..dc5faf96b 100644 --- a/kivy/properties.pxd +++ b/kivy/properties.pxd @@ -15,7 +15,8 @@ cdef class Property: cpdef dispatch(self, obj) cdef class NumericProperty(Property): - pass + cdef float parse_str(self, value) + cdef float parse_list(self, value, ext) cdef class StringProperty(Property): pass diff --git a/kivy/properties.pyx b/kivy/properties.pyx index 39713ed6a..c9b45496c 100644 --- a/kivy/properties.pyx +++ b/kivy/properties.pyx @@ -153,6 +153,9 @@ __all__ = ('Property', from weakref import ref +EventLoop = None + + cdef class Property: '''Base class for building more complex properties. @@ -349,6 +352,44 @@ cdef class NumericProperty(Property): obj.__class__.__name__, self.name)) + cdef convert(self, obj, x): + tp = type(x) + if tp is int or tp is float: + return x + if tp is tuple or tp is list: + if len(x) != 2: + raise ValueError('%s.%s must have 2 components' % ( + obj.__class__.__name__, + self.name)) + return self.parse_list(x[0], x[1]) + elif tp is str: + return self.parse_str(x) + else: + raise ValueError('%s.%s have an invalid format' % ( + obj.__class__.__name__, + self.name)) + + cdef float parse_str(self, value): + return self.parse_list(value[:-2], value[-2:]) + + cdef float parse_list(self, value, ext): + # 1in = 2.54cm = 25.4mm = 72pt = 12pc + global EventLoop + if EventLoop is None: + from kivy.base import EventLoop + cdef float rv = float(value) + cdef float dpi = EventLoop.dpi + if ext == 'in': + return rv * dpi + elif ext == 'px': + return rv + elif ext == 'pt': + return rv * dpi / 72. + elif ext == 'cm': + return rv * dpi / 2.54 + elif ext == 'mm': + return rv * dpi / 25.4 + cdef class StringProperty(Property): '''Property that represents a string value.