screen: add new screen module, that can be used for simulating different screen sizes/density/dpi.

This commit is contained in:
Mathieu Virbel 2012-11-02 18:06:35 +01:00
parent f1cfe335dc
commit 7e3f193d60
3 changed files with 151 additions and 27 deletions

View File

@ -369,6 +369,10 @@ if not environ.get('KIVY_DOC_INCLUDE'):
Logger.info('Core: Kivy configuration saved.')
sys.exit(0)
# configure all activated modules
from kivy.modules import Modules
Modules.configure()
# android hooks: force fullscreen and add android touch input provider
if platform() == 'android':
from kivy.config import Config

View File

@ -113,7 +113,9 @@ class ModuleBase:
def import_module(self, name):
try:
module = __import__(name=name, fromlist='.')
modname = 'kivy.modules.{0}'.format(name)
module = __import__(name=modname)
module = sys.modules[modname]
except ImportError:
Logger.exception('Modules: unable to import <%s>' % name)
raise
@ -130,38 +132,17 @@ class ModuleBase:
def activate_module(self, name, win):
'''Activate a module on a window'''
if not name in self.mods:
if name not in self.mods:
Logger.warning('Modules: Module <%s> not found' % name)
return
if not 'module' in self.mods[name]:
try:
self.import_module(name)
except ImportError:
return
module = self.mods[name]['module']
if not self.mods[name]['activated']:
# convert configuration like:
# -m mjpegserver:port=8080,fps=8
# and pass it in context.config token
config = dict()
args = Config.get('modules', name)
if args != '':
values = Config.get('modules', name).split(',')
for value in values:
x = value.split('=', 1)
if len(x) == 1:
config[x[0]] = True
else:
config[x[0]] = x[1]
msg = 'Modules: Start <%s> with config %s' % (name, str(config))
context = self.mods[name]['context']
msg = 'Modules: Start <{0}> with config {1}'.format(
name, context)
Logger.debug(msg)
self.mods[name]['context'].config = config
module.start(win, self.mods[name]['context'])
module.start(win, context)
def deactivate_module(self, name, win):
'''Deactivate a module from a window'''
@ -196,6 +177,45 @@ class ModuleBase:
for name in modules_to_activate:
self.activate_module(name, win)
def configure(self):
'''(internal) Configure all the modules before using it.
'''
modules_to_configure = map(lambda x: x[0], Config.items('modules'))
for name in modules_to_configure:
if name not in self.mods:
Logger.warning('Modules: Module <%s> not found' % name)
continue
self._configure_module(name)
def _configure_module(self, name):
if 'module' not in self.mods[name]:
try:
self.import_module(name)
except ImportError:
return
# convert configuration like:
# -m mjpegserver:port=8080,fps=8
# and pass it in context.config token
config = dict()
args = Config.get('modules', name)
if args != '':
values = Config.get('modules', name).split(',')
for value in values:
x = value.split('=', 1)
if len(x) == 1:
config[x[0]] = True
else:
config[x[0]] = x[1]
self.mods[name]['context'].config = config
# call configure if module have one
if hasattr(self.mods[name]['module'], 'configure'):
self.mods[name]['module'].configure(config)
def usage_list(self):
print
print 'Available modules'

100
kivy/modules/screen.py Normal file
View File

@ -0,0 +1,100 @@
'''
Screen
======
This module change some environement and configuration to match the density /
dpi / screensize of a specific devices.
To see a list of the available screenid, just run::
python main.py -m screen
Simulate a medium-density screen as Motolora Droid 2::
python main.py -m screen,droid2
Simulate a high-density screen as HTC One X, in portrait::
python main.py -m screen,onex,portrait
Simulate the iPad 2 screen::
python main.py -m screen,ipad
'''
import sys
from os import environ
from kivy.config import Config
from kivy.logger import Logger
# taken from http://en.wikipedia.org/wiki/List_of_displays_by_pixel_density
devices = {
# device: (name, width, height, dpi, density)
'onex': ('HTC One X', 1280, 720, 312, 2),
's3': ('Galaxy SIII', 1280, 720, 306, 2),
'droid2': ('Motolora Droid 2', 854, 480, 240, 1.5),
'xoom': ('Motolora Xoom', 1280, 800, 149, 1),
'ipad': ('iPad (1 and 2)', 1024, 768, 132, 1),
'ipad3': ('iPad 3', 2048, 1536, 264, 2),
'iphone4': ('iPhone 4', 640, 960, 326, 2),
'iphone5': ('iPhone 5', 640, 1136, 326, 2),
}
def start(win, ctx):
pass
def stop(win, ctx):
pass
def apply_device(device, scale, orientation):
name, width, height, dpi, density = devices[device]
if orientation == 'portrait':
width, height = height, width
Logger.info('Screen: Apply screen settings for {0}'.format(name))
Logger.info('Screen: size={0}x{1} dpi={2} density={3} '
'orientation={4}'.format(width, height, dpi, density, orientation))
environ['KIVY_METRICS_DENSITY'] = str(density)
environ['KIVY_DPI'] = str(dpi)
Config.set('graphics', 'width', str(width))
Config.set('graphics', 'height', str(height))
Config.set('graphics', 'fullscreen', '0')
Config.set('graphics', 'show_mousecursor', '1')
def usage(device=None):
if device:
Logger.error('Screen: The specified device ({0}) is unknow.',
device)
print '\nModule usage: python main.py -m screen,deviceid[,orientation]\n'
print 'Availables devices:\n'
print '{0:12} {1:<22} {2:<8} {3:<8} {4:<5} {5:<8}'.format(
'Device ID', 'Name', 'Width', 'Height', 'DPI', 'Density')
for device, info in devices.iteritems():
print '{0:12} {1:<22} {2:<8} {3:<8} {4:<5} {5:<8}'.format(
device, *info)
print '\n'
print 'Simulate a medium-density screen as Motolora Droid 2:\n'
print ' python main.py -m screen,droid2\n'
print 'Simulate a high-density screen as HTC One X, in portrait:\n'
print ' python main.py -m screen,onex,portrait\n'
print 'Simulate the iPad 2 screen\n'
print ' python main.py -m screen,ipad\n'
sys.exit(1)
def configure(ctx):
scale = ctx.pop('scale', None)
orientation = 'landscape'
ctx.pop('landscape', None)
if ctx.pop('portrait', None):
orientation = 'portrait'
if not ctx:
return usage(None)
device = ctx.keys()[0]
if device not in devices:
return usage('')
apply_device(device, scale, orientation)