dpi: implement sp(), and add Metrics class in kivy.metrics: expose dpi, dpi_rounded, fontscale, density

This commit is contained in:
Mathieu Virbel 2012-11-01 13:52:42 +01:00
parent 9d7779d0d2
commit 2dbc1cf3cc
7 changed files with 108 additions and 76 deletions

View File

@ -106,56 +106,6 @@ class EventLoopBase(EventDispatcher):
'''
return self.me_list
@reify
def dpi(self):
'''Return the DPI of the screen. Depending of the platform, the DPI can
be taken from the Window provider (Desktop mainly), or from
platform-specific module (like android/ios).
On desktop, you can overload the value returned by the Window object
(96 by default), by setting the environ KIVY_DPI::
KIVY_DPI=200 python main.py
.. versionadded:: 1.4.0
'''
custom_dpi = environ.get('KIVY_DPI')
if custom_dpi:
return float(custom_dpi)
plat = platform()
if plat == 'android':
import android
return android.get_dpi()
# for all other platforms..
self.ensure_window()
return self.window.dpi
@reify
def dpi_rounded(self):
'''Return the dpi of the screen, rounded to the nearest of 120, 160,
240, 320.
.. versionadded:: 1.5.0
'''
dpi = self.dpi
if dpi < 140:
return 120
elif dpi < 200:
return 160
elif dpi < 280:
return 240
return 320
@reify
def dpi_density(self):
if platform() == 'android':
import jnius
Hardware = jnius.autoclass('org.renpy.android.Hardware')
return Hardware.metrics.scaledDensity
return float(environ.get('KIVY_DPI_DENSITY', '1.0'))
def ensure_window(self):
'''Ensure that we have an window
'''

View File

@ -140,7 +140,7 @@ class MarkupLabel(MarkupLabelBase):
elif item[:6] == '[size=':
item = item[6:-1]
try:
if item[-2:] in ('px', 'pt', 'in', 'cm', 'mm', 'dp'):
if item[-2:] in ('px', 'pt', 'in', 'cm', 'mm', 'dp', 'sp'):
size = dpi2px(item[:-2], item[-2:])
else:
size = int(item)

View File

@ -109,7 +109,7 @@
background_normal: 'atlas://data/images/defaulttheme/tab_btn'
background_down: 'atlas://data/images/defaulttheme/tab_btn_pressed'
border: (8, 8, 8, 8)
font_size: '14dp'
font_size: '14sp'
<TextInput>:
@ -326,7 +326,7 @@
Label:
text: unicode(ctx.get_nice_size())
font_size: '11dp'
font_size: '11sp'
color: .8, .8, .8, 1
size: 100, 16
pos: root.pos
@ -358,7 +358,7 @@
size_hint_y: None
height: self.texture_size[1]
y: pb.center_y - self.height - 8
font_size: '13dp'
font_size: '13sp'
color: (.8, .8, .8, .8)
AnchorLayout:
@ -521,8 +521,8 @@
size_hint_x: .66
id: labellayout
markup: True
text: '{0}\n[size=13dp][color=999999]{1}[/color][/size]{2}'.format(root.title or '', root.desc or '', self.font_size)
font_size: '15dp'
text: '{0}\n[size=13sp][color=999999]{1}[/color][/size]{2}'.format(root.title or '', root.desc or '', self.font_size)
font_size: '15sp'
text_size: self.width - 32, None
BoxLayout:
@ -541,26 +541,26 @@
Label:
text: str(root.value)
pos: root.pos
font_size: '15dp'
font_size: '15sp'
<SettingPath>:
Label:
text: str(root.value)
pos: root.pos
font_size: '15dp'
font_size: '15sp'
<SettingOptions>:
Label:
text: str(root.value)
pos: root.pos
font_size: '15dp'
font_size: '15sp'
<SettingTitle>:
text_size: self.width - 32, None
size_hint_y: None
height: max(dp(20), self.texture_size[1] + dp(20))
color: (.9, .9, .9, 1)
font_size: '15dp'
font_size: '15sp'
canvas:
Color:
rgba: .15, .15, .15, .5
@ -577,7 +577,7 @@
size_hint: 1, None
text_size: self.width - 32, None
height: self.texture_size[1] + dp(20)
font_size: '15dp'
font_size: '15sp'
canvas.before:
Color:
rgba: 47 / 255., 167 / 255., 212 / 255., int(self.selected)
@ -597,7 +597,7 @@
text_size: self.width - 32, None
height: max(50, self.texture_size[1] + 20)
color: (.5, .5, .5, 1)
font_size: '15dp'
font_size: '15sp'
canvas.after:
Color:
@ -641,7 +641,7 @@
height: max(50, self.texture_size[1] + dp(20))
pos: root.x + dp(10), root.y + dp(10)
on_release: root.dispatch('on_close')
font_size: '15dp'
font_size: '15sp'
ScrollView:
do_scroll_x: False

View File

@ -6,8 +6,10 @@ This module give you access to multiple display values, and some conversion
functions.
'''
__all__ = ('pt', 'inch', 'cm', 'mm', 'dp')
__all__ = ('metrics', 'Metrics', 'pt', 'inch', 'cm', 'mm', 'dp')
from os import environ
from kivy.utils import reify, platform
from kivy.properties import dpi2px
def pt(value):
@ -25,3 +27,81 @@ def mm(value):
def dp(value):
return dpi2px(value, 'dp')
def sp(value):
return dpi2px(value, 'sp')
class Metrics(object):
@reify
def dpi(self):
'''Return the DPI of the screen. Depending of the platform, the DPI can
be taken from the Window provider (Desktop mainly), or from
platform-specific module (like android/ios).
On desktop, you can overload the value returned by the Window object
(96 by default), by setting the environ KIVY_DPI::
KIVY_DPI=200 python main.py
.. versionadded:: 1.4.0
'''
custom_dpi = environ.get('KIVY_DPI')
if custom_dpi:
return float(custom_dpi)
if platform() == 'android':
import android
return android.get_dpi()
# for all other platforms..
from kivy.base import EventLoop
EventLoop.ensure_window()
return EventLoop.window.dpi
@reify
def dpi_rounded(self):
'''Return the dpi of the screen, rounded to the nearest of 120, 160,
240, 320.
.. versionadded:: 1.5.0
'''
dpi = self.dpi
if dpi < 140:
return 120
elif dpi < 200:
return 160
elif dpi < 280:
return 240
return 320
@reify
def density(self):
custom_density = environ.get('KIVY_METRICS_DENSITY')
if custom_density:
return float(custom_density)
if platform() == 'android':
import jnius
Hardware = jnius.autoclass('org.renpy.android.Hardware')
return Hardware.metrics.scaledDensity
return 1.0
@reify
def fontscale(self):
custom_fontscale = environ.get('KIVY_METRICS_FONTSCALE')
if custom_fontscale:
return float(custom_fontscale)
if platform() == 'android':
import jnius
PythonActivity = jnius.autoclass('org.renpy.android.PythonActivity')
config = PythonActivity.mActivity.getResources().getConfiguration()
return config.fontScale
return 1.0
#: default instance of :class:`Metrics`, used everywhere in the code
metrics = Metrics()

View File

@ -174,24 +174,26 @@ __all__ = ('Property',
from weakref import ref
cdef float g_dpi = -1
cdef float g_dpi_rounded = -1
cdef float g_dpi_density = -1
cdef float g_density = -1
cdef float g_fontscale = -1
cpdef float dpi2px(value, ext):
# 1in = 2.54cm = 25.4mm = 72pt = 12pc
global g_dpi, g_dpi_rounded, g_dpi_density
global g_dpi, g_density, g_fontscale
if g_dpi == -1:
from kivy.base import EventLoop
g_dpi = EventLoop.dpi
g_dpi_rounded = EventLoop.dpi_rounded
g_dpi_density = EventLoop.dpi_density
from kivy.metrics import metrics
g_dpi = metrics.dpi
g_density = metrics.density
g_fontscale = metrics.fontscale
cdef float rv = float(value)
if ext == 'in':
return rv * g_dpi
elif ext == 'px':
return rv
elif ext == 'dp':
return rv * g_dpi_density
return rv * g_density
elif ext == 'sp':
return rv * g_density * g_fontscale
elif ext == 'pt':
return rv * g_dpi / 72.
elif ext == 'cm':

View File

@ -15,7 +15,7 @@ strings::
l = Label(text='Multi\\nLine')
# size
l = Label(text='Hello world', font_size='20dp')
l = Label(text='Hello world', font_size='20sp')
Markup text
-----------
@ -268,7 +268,7 @@ class Label(Widget):
'DroidSans'.
'''
font_size = NumericProperty('14dp')
font_size = NumericProperty('14sp')
'''Font size of the text, in pixels.
:data:`font_size` is a :class:`~kivy.properties.NumericProperty`, default to
@ -373,7 +373,7 @@ class Label(Widget):
l = Label(text='Hello world')
# l.texture is good
l.font_size = '50dp'
l.font_size = '50sp'
# l.texture is not updated yet
l.update_texture()
# l.texture is good now.

View File

@ -1708,7 +1708,7 @@ class TextInput(Widget):
'DroidSans'.
'''
font_size = NumericProperty('13dp')
font_size = NumericProperty('13sp')
'''Font size of the text, in pixels.
:data:`font_size` is a :class:`~kivy.properties.NumericProperty`, default to