Merge branch 'master' of git+ssh://guillaume@dev.laptop.org/git/sugar

This commit is contained in:
Guillaume Desmottes 2007-02-23 17:30:33 +01:00
commit b9fb0f73f1
17 changed files with 195 additions and 86 deletions

View File

@ -20,7 +20,7 @@ from view.BuddyMenu import BuddyMenu
class BuddyIcon(CanvasIcon): class BuddyIcon(CanvasIcon):
def __init__(self, shell, menu_shell, buddy): def __init__(self, shell, menu_shell, buddy):
CanvasIcon.__init__(self, icon_name='theme:stock-buddy', CanvasIcon.__init__(self, icon_name='theme:stock-buddy',
color=buddy.get_color()) xo_color=buddy.get_color())
self._shell = shell self._shell = shell
self._buddy = buddy self._buddy = buddy
@ -30,7 +30,7 @@ class BuddyIcon(CanvasIcon):
def _buddy_presence_change_cb(self, buddy, color=None): def _buddy_presence_change_cb(self, buddy, color=None):
# Update the icon's color when the buddy comes and goes # Update the icon's color when the buddy comes and goes
self.set_property('color', buddy.get_color()) self.props.xo_color = buddy.get_color()
def set_popup_distance(self, distance): def set_popup_distance(self, distance):
self._popup_distance = distance self._popup_distance = distance

View File

@ -31,12 +31,6 @@ class ActivityButton(IconButton):
self._activity = activity self._activity = activity
self._popup_context = popup_context self._popup_context = popup_context
def _mouse_motion_event_cb(self, item, event):
if event.detail == hippo.MOTION_DETAIL_ENTER:
self.set_property('color', self._prelight_color)
elif event.detail == hippo.MOTION_DETAIL_LEAVE:
self.set_property('color', self._normal_color)
def get_bundle_id(self): def get_bundle_id(self):
return self._activity.get_service_name() return self._activity.get_service_name()
@ -47,7 +41,7 @@ class InviteButton(IconButton):
def __init__(self, activity, invite): def __init__(self, activity, invite):
IconButton.__init__(self, icon_name=activity.get_icon()) IconButton.__init__(self, icon_name=activity.get_icon())
self.props.color = activity.get_color() self.props.xo_color = activity.get_color()
self._invite = invite self._invite = invite
def get_activity_id(self): def get_activity_id(self):

View File

@ -48,7 +48,7 @@ class ActivityButton(IconButton):
icon_name = self._activity_model.get_icon_name() icon_name = self._activity_model.get_icon_name()
icon_color = self._activity_model.get_icon_color() icon_color = self._activity_model.get_icon_color()
IconButton.__init__(self, icon_name=icon_name, color=icon_color) IconButton.__init__(self, icon_name=icon_name, xo_color=icon_color)
def get_popup(self): def get_popup(self):
menu = ActivityMenu(self._activity_model) menu = ActivityMenu(self._activity_model)

View File

@ -70,7 +70,7 @@ class FriendView(hippo.CanvasBox):
name = self._get_new_icon_name(activity) name = self._get_new_icon_name(activity)
if name: if name:
self._activity_icon.props.icon_name = name self._activity_icon.props.icon_name = name
self._activity_icon.props.color = buddy.get_color() self._activity_icon.props.xo_color = buddy.get_color()
if not self._activity_icon_visible: if not self._activity_icon_visible:
self.append(self._activity_icon, hippo.PACK_EXPAND) self.append(self._activity_icon, hippo.PACK_EXPAND)
self._activity_icon_visible = True self._activity_icon_visible = True
@ -85,4 +85,4 @@ class FriendView(hippo.CanvasBox):
self._buddy_activity_changed_cb(buddy, None) self._buddy_activity_changed_cb(buddy, None)
def _buddy_color_changed_cb(self, buddy, color): def _buddy_color_changed_cb(self, buddy, color):
self._activity_icon.props.color = buddy.get_color() self._activity_icon.props.xo_color = buddy.get_color()

View File

@ -19,6 +19,7 @@ import math
import hippo import hippo
from sugar.graphics import units from sugar.graphics import units
from sugar.graphics import color
from sugar.graphics.xocolor import XoColor from sugar.graphics.xocolor import XoColor
from view.home.activitiesdonut import ActivitiesDonut from view.home.activitiesdonut import ActivitiesDonut
@ -59,7 +60,11 @@ class HomeBox(hippo.CanvasBox, hippo.CanvasItem):
if self._donut: if self._donut:
self.remove(self._donut) self.remove(self._donut)
self._donut = None self._donut = None
self._my_icon.props.color = XoColor('insensitive') self._my_icon.props.stroke_color = color.BUTTON_INACTIVE
self._my_icon.props.fill_color = \
color.BUTTON_INACTIVE_BACKGROUND
self._my_icon.props.background_color = \
color.BUTTON_INACTIVE_BACKGROUND
def do_allocate(self, width, height, origin_changed): def do_allocate(self, width, height, origin_changed):
hippo.CanvasBox.do_allocate(self, width, height, origin_changed) hippo.CanvasBox.do_allocate(self, width, height, origin_changed)

View File

@ -33,7 +33,7 @@ class ActivityView(SnowflakeBox):
self._icons = {} self._icons = {}
icon = CanvasIcon(icon_name=model.get_icon_name(), icon = CanvasIcon(icon_name=model.get_icon_name(),
color=model.get_color(), box_width=80) xo_color=model.get_color(), box_width=80)
icon.connect('activated', self._clicked_cb) icon.connect('activated', self._clicked_cb)
self.append(icon, hippo.PACK_FIXED) self.append(icon, hippo.PACK_FIXED)
self.set_root(icon) self.set_root(icon)

View File

@ -21,4 +21,4 @@ class MyIcon(CanvasIcon):
def __init__(self, scale): def __init__(self, scale):
CanvasIcon.__init__(self, scale=scale, CanvasIcon.__init__(self, scale=scale,
icon_name='theme:stock-buddy', icon_name='theme:stock-buddy',
color=profile.get_color()) xo_color=profile.get_color())

View File

@ -55,7 +55,7 @@ class ActivityIcon(CanvasIcon):
self._level = self._level_max self._level = self._level_max
color = self._icon_colors[self._level] color = self._icon_colors[self._level]
CanvasIcon.__init__(self, icon_name=icon_name, color=color, CanvasIcon.__init__(self, icon_name=icon_name, xo_color=color,
scale=units.MEDIUM_ICON_SCALE, cache=True) scale=units.MEDIUM_ICON_SCALE, cache=True)
self._activity = activity self._activity = activity
@ -103,7 +103,7 @@ class ActivityIcon(CanvasIcon):
self._direction = 1 self._direction = 1
self._level = 0 self._level = 0
self.props.color = self._icon_colors[self._level] self.props.xo_color = self._icon_colors[self._level]
self.emit_paint_needed(0, 0, -1, -1) self.emit_paint_needed(0, 0, -1, -1)
return True return True
@ -113,7 +113,7 @@ class ActivityIcon(CanvasIcon):
self._launched = True self._launched = True
self.cleanup() self.cleanup()
self._level = 100.0 self._level = 100.0
self.props.color = self._orig_color self.props.xo_color = self._orig_color
self.emit_paint_needed(0, 0, -1, -1) self.emit_paint_needed(0, 0, -1, -1)
def get_launched(self): def get_launched(self):

View File

@ -42,16 +42,14 @@ if len(sys.argv) == 1:
else: else:
program = sys.argv[1] program = sys.argv[1]
# Various things in sugar currently depend on the screen size being in if gtk.gdk.screen_width() < 1200 or gtk.gdk.screen_height() < 900:
# a width:height porportion of 4:3. fullscreen = True
width = height = -1 width = -1
if gtk.gdk.screen_width() / 4 * 3 == gtk.gdk.screen_height(): height = -1
fullscreen = (gtk.gdk.screen_width() <= 1200 or
gtk.gdk.screen_height() <= 900)
else: else:
fullscreen = False fullscreen = False
height = min(900, gtk.gdk.screen_height() - 50) width = 1200
width = height * 4 / 3 height = 900
emulator = Emulator(width, height, fullscreen) emulator = Emulator(width, height, fullscreen)
emulator.start() emulator.start()

View File

@ -105,4 +105,4 @@ class Activity(gtk.Window):
self._pservice.unregister_service(self._service) self._pservice.unregister_service(self._service)
def get_bundle_path(): def get_bundle_path():
return os.environ['SUGAR_BUNDLE_BUNDLE_PATH'] return os.environ['SUGAR_BUNDLE_PATH']

View File

@ -27,29 +27,28 @@ import time
from sugar.graphics.timeline import Timeline from sugar.graphics.timeline import Timeline
from sugar.graphics.popup import Popup from sugar.graphics.popup import Popup
from sugar.graphics import color from sugar.graphics import color
from sugar.graphics.xocolor import XoColor
from sugar.graphics import font from sugar.graphics import font
from sugar.graphics import units from sugar.graphics import units
class _IconCacheIcon: class _IconCacheIcon:
def __init__(self, name, color, now): def __init__(self, name, fill_color, stroke_color, now):
self.data_size = None self.data_size = None
self.handle = self._read_icon_data(name, color) self.handle = self._read_icon_data(name, fill_color, stroke_color)
self.last_used = now self.last_used = now
self.usage_count = 1 self.usage_count = 1
def _read_icon_data(self, filename, color): def _read_icon_data(self, filename, fill_color, stroke_color):
icon_file = open(filename, 'r') icon_file = open(filename, 'r')
data = icon_file.read() data = icon_file.read()
icon_file.close() icon_file.close()
if color: if fill_color:
fill = color.get_fill_color() entity = '<!ENTITY fill_color "%s">' % fill_color
stroke = color.get_stroke_color()
entity = '<!ENTITY fill_color "%s">' % fill
data = re.sub('<!ENTITY fill_color .*>', entity, data) data = re.sub('<!ENTITY fill_color .*>', entity, data)
entity = '<!ENTITY stroke_color "%s">' % stroke if stroke_color:
entity = '<!ENTITY stroke_color "%s">' % stroke_color
data = re.sub('<!ENTITY stroke_color .*>', entity, data) data = re.sub('<!ENTITY stroke_color .*>', entity, data)
self.data_size = len(data) self.data_size = len(data)
@ -104,15 +103,15 @@ class _IconCache:
self._cache_size -= self._icons[evict_key].data_size self._cache_size -= self._icons[evict_key].data_size
del self._icons[evict_key] del self._icons[evict_key]
def get_handle(self, name, color): def get_handle(self, name, fill_color, stroke_color):
if name == None: if name == None:
return None return None
if name[0:6] == "theme:": if name[0:6] == "theme:":
name = self._get_real_name_from_theme(name[6:]) name = self._get_real_name_from_theme(name[6:])
if color: if fill_color or stroke_color:
key = (name, color.to_string()) key = (name, fill_color, stroke_color)
else: else:
key = name key = name
@ -125,7 +124,7 @@ class _IconCache:
icon.usage_count += 1 icon.usage_count += 1
icon.last_used = now icon.last_used = now
else: else:
icon = _IconCacheIcon(name, color, now) icon = _IconCacheIcon(name, fill_color, stroke_color, now)
self._icons[key] = icon self._icons[key] = icon
self._cache_size += icon.data_size self._cache_size += icon.data_size
return icon.handle return icon.handle
@ -135,9 +134,13 @@ class CanvasIcon(hippo.CanvasBox, hippo.CanvasItem):
__gtype_name__ = 'CanvasIcon' __gtype_name__ = 'CanvasIcon'
__gproperties__ = { __gproperties__ = {
'icon-name': (str, None, None, None, 'icon-name' : (str, None, None, None,
gobject.PARAM_READWRITE), gobject.PARAM_READWRITE),
'color' : (object, None, None, 'xo-color' : (object, None, None,
gobject.PARAM_READWRITE),
'fill-color' : (object, None, None,
gobject.PARAM_READWRITE),
'stroke-color' : (object, None, None,
gobject.PARAM_READWRITE), gobject.PARAM_READWRITE),
'scale' : (float, None, None, 'scale' : (float, None, None,
0.0, 1024.0, 1.0, 0.0, 1024.0, 1.0,
@ -154,7 +157,8 @@ class CanvasIcon(hippo.CanvasBox, hippo.CanvasItem):
self._buffers = {} self._buffers = {}
self._cur_buffer = None self._cur_buffer = None
self._scale = 1.0 self._scale = 1.0
self._color = None self._fill_color = None
self._stroke_color = None
self._icon_name = None self._icon_name = None
self._cache = False self._cache = False
self._handle = None self._handle = None
@ -186,10 +190,21 @@ class CanvasIcon(hippo.CanvasBox, hippo.CanvasItem):
self._icon_name = value self._icon_name = value
self._handle = None self._handle = None
self.emit_paint_needed(0, 0, -1, -1) self.emit_paint_needed(0, 0, -1, -1)
elif pspec.name == 'color': elif pspec.name == 'xo-color':
if self._color != value and not self._cache: self.props.fill_color = color.HTMLColor(value.get_fill_color())
self.props.stroke_color = color.HTMLColor(value.get_stroke_color())
elif pspec.name == 'fill-color':
if self._fill_color != value:
if not self._cache:
self._clear_buffers() self._clear_buffers()
self._color = value self._fill_color = value
self._handle = None
self.emit_paint_needed(0, 0, -1, -1)
elif pspec.name == 'stroke-color':
if self._stroke_color != value:
if not self._cache:
self._clear_buffers()
self._stroke_color = value
self._handle = None self._handle = None
self.emit_paint_needed(0, 0, -1, -1) self.emit_paint_needed(0, 0, -1, -1)
elif pspec.name == 'scale': elif pspec.name == 'scale':
@ -205,19 +220,38 @@ class CanvasIcon(hippo.CanvasBox, hippo.CanvasItem):
def _get_handle(self): def _get_handle(self):
if not self._handle: if not self._handle:
cache = CanvasIcon._cache cache = CanvasIcon._cache
self._handle = cache.get_handle(self._icon_name, self._color)
fill_color = None
if self._fill_color:
fill_color = self._fill_color.get_html()
stroke_color = None
if self._stroke_color:
stroke_color = self._stroke_color.get_html()
self._handle = cache.get_handle(self._icon_name, fill_color,
stroke_color)
return self._handle return self._handle
def _get_current_buffer_key(self): def _get_current_buffer_key(self):
return (self._icon_name, self._color, self._scale) return (self._icon_name, self._fill_color, self._stroke_color, self._scale)
def do_get_property(self, pspec): def do_get_property(self, pspec):
if pspec.name == 'scale': if pspec.name == 'scale':
return self._scale return self._scale
elif pspec.name == 'icon-name': elif pspec.name == 'icon-name':
return self._icon_name return self._icon_name
elif pspec.name == 'color': elif pspec.name == 'xo-color':
return self._color if self._stroke_color and self._fill_color:
xo_color = XoColor('%s,%s' % (self._stroke_color.get_html(),
self._fill_color.get_html()))
return xo_color
else:
return None
elif pspec.name == 'fill-color':
return self._fill_color
elif pspec.name == 'stroke-color':
return self._stroke_color
elif pspec.name == 'cache': elif pspec.name == 'cache':
return self._cache return self._cache
elif pspec.name == 'tooltip': elif pspec.name == 'tooltip':

View File

@ -60,11 +60,18 @@ class RGBColor(object):
return gtk.gdk.Color(int(self._r * 65535), int(self._g * 65535), return gtk.gdk.Color(int(self._r * 65535), int(self._g * 65535),
int(self._b * 65535)) int(self._b * 65535))
class SystemColor(RGBColor): def get_html(self):
def __init__(self, color_id): return '#%x%x%x' % (self._r * 255, self._g * 255, self._b * 255)
rgb = _html_to_rgb(_system_colors[color_id])
class HTMLColor(RGBColor):
def __init__(self, html_color):
rgb = _html_to_rgb(html_color)
RGBColor.__init__(self, *rgb) RGBColor.__init__(self, *rgb)
class SystemColor(HTMLColor):
def __init__(self, color_id):
HTMLColor.__init__(self, _system_colors[color_id])
RED = RGBColor(1.0, 0.0, 0.0) RED = RGBColor(1.0, 0.0, 0.0)
GREEN = RGBColor(0.0, 1.0, 0.0) GREEN = RGBColor(0.0, 1.0, 0.0)
BLUE = RGBColor(0.0, 0.0, 1.0) BLUE = RGBColor(0.0, 0.0, 1.0)

View File

@ -44,14 +44,13 @@ class IconButton(CanvasIcon):
CanvasIcon.__init__(self, cache=True, **kwargs) CanvasIcon.__init__(self, cache=True, **kwargs)
if self.props.color:
self._normal_color = self.props.color
else:
self._normal_color = XoColor('white')
self.props.color = self._normal_color
self._prelight_color = profile.get_color() self._prelight_color = profile.get_color()
self._inactive_color = XoColor('#808080,#424242') self._inactive_color = XoColor('#808080,#424242')
self._normal_color = XoColor('white')
if not self.props.xo_color:
self.props.xo_color = self._normal_color
self._set_size(STANDARD_SIZE) self._set_size(STANDARD_SIZE)
self.connect('button-press-event', self._button_press_event_cb) self.connect('button-press-event', self._button_press_event_cb)
@ -74,9 +73,9 @@ class IconButton(CanvasIcon):
elif pspec.name == 'active': elif pspec.name == 'active':
self._active = value self._active = value
if self._active: if self._active:
self.props.color = self._normal_color self.props.xo_color = self._normal_color
else: else:
self.props.color = self._inactive_color self.props.xo_color = self._inactive_color
else: else:
CanvasIcon.do_set_property(self, pspec, value) CanvasIcon.do_set_property(self, pspec, value)

View File

@ -49,7 +49,7 @@ class MenuItem(hippo.CanvasBox):
icon = CanvasIcon(icon_name=icon_name, icon = CanvasIcon(icon_name=icon_name,
scale=units.SMALL_ICON_SCALE) scale=units.SMALL_ICON_SCALE)
if icon_color: if icon_color:
icon.props.color = icon_color icon.props.xo_color = icon_color
self.append(icon) self.append(icon)
self._canvas_text = hippo.CanvasText(text=label) self._canvas_text = hippo.CanvasText(text=label)

View File

@ -1,20 +1,92 @@
# Copyright (C) 2006, Red Hat, Inc.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
""" Units conversions and constants
The purpose of the module is to keep Sugar independent from the
screen size, factory and DPI. There a few use cases that needs
to be considered:
- The XO display. The screen DPI is 201 and the screen
resolution is 1200x900. The screen factor is 4:3.
- The Sugar emulator runned on traditional screens. Resolution
is variable, ranging from 800x600 up to 1200x900. The DPI
is usually but not necessarily 96. The screen factor is
either 4:3 or 16:9
- Other embedded devices. DPI, screen resolution and screen
factor are variable.
To achieve the goal a few rules needs to be respected when
writing code for Sugar:
- Never use absolute positioning. Use the layout facilities
provided by HippoCanvas. If you need custom layouts make
sure they adapt to different screen resolutions.
- Never specify sizes, fonts, borders or padding using pixels.
Instead use the device independt units provided by this
module.
We are currently providing the following resolution independent
units:
- Points.
- Grid. One cell of the screen grid as specificed by the HIG.
- Microgrid. One microcell of the screen grid as
specificed by the HIG.
- A set of icon sizes as specified by the HIG (standard, small,
medium, large, xlarge).
Just scaling UI elements on the base of the screen DPI is not
enough to provide a good experience. For example on smaller
screens smaller fonts or icons might be acceptable to gain
screen aestate. For this reason a constant zoom factor is
applied to all the transformation from resolution independent
units to device units.
"""
import gtk import gtk
import _sugar import _sugar
_screen_factor = gtk.gdk.screen_width() / 1200.0 _MAX_ZOOM_FACTOR = 1.5
_ZOOM_CONSTANT = 600.0
STANDARD_ICON_SCALE = 1.0 * _screen_factor def _compute_zoom_factor():
SMALL_ICON_SCALE = 0.5 * _screen_factor screen_width = gtk.gdk.screen_width()
MEDIUM_ICON_SCALE = 1.5 * _screen_factor if _sugar.get_screen_dpi() == 201.0 and screen_width == 1200:
LARGE_ICON_SCALE = 2.0 * _screen_factor return 1.0
XLARGE_ICON_SCALE = 3.0 * _screen_factor else:
return min(_MAX_ZOOM_FACTOR, screen_width / _ZOOM_CONSTANT)
_dpi_factor = float(_sugar.get_screen_dpi()) / 201.0
_zoom_factor = _compute_zoom_factor()
STANDARD_ICON_SCALE = 1.0 * _dpi_factor * _zoom_factor
SMALL_ICON_SCALE = 0.5 * _dpi_factor * _zoom_factor
MEDIUM_ICON_SCALE = 1.5 * _dpi_factor * _zoom_factor
LARGE_ICON_SCALE = 2.0 * _dpi_factor * _zoom_factor
XLARGE_ICON_SCALE = 3.0 * _dpi_factor * _zoom_factor
def points_to_pixels(points): def points_to_pixels(points):
return points * _sugar.get_screen_dpi() / 72.0 * _screen_factor return int(points * _zoom_factor)
def grid_to_pixels(units): def grid_to_pixels(units):
return units * gtk.gdk.screen_width() / 16 return int(units * 75.0 * _dpi_factor * _zoom_factor)
def microgrid_to_pixels(units): def microgrid_to_pixels(units):
return units * gtk.gdk.screen_width() / 80 return int(units * 15.0 * _dpi_factor * _zoom_factor)

View File

@ -33,14 +33,14 @@ from sugar.graphics.canvasicon import CanvasIcon
def _create_snowflake(parent, children): def _create_snowflake(parent, children):
color = XoColor() color = XoColor()
icon = CanvasIcon(size=40, color=color, icon = CanvasIcon(size=40, xo_color=color,
icon_name='activity-groupchat') icon_name='activity-groupchat')
parent.append(icon, hippo.PACK_FIXED) parent.append(icon, hippo.PACK_FIXED)
parent.set_root(icon) parent.set_root(icon)
for i in range(0, children): for i in range(0, children):
color = XoColor() color = XoColor()
icon = CanvasIcon(size=60, color=color, icon = CanvasIcon(size=60, xo_color=color,
icon_name='stock-buddy') icon_name='stock-buddy')
parent.append(icon, hippo.PACK_FIXED) parent.append(icon, hippo.PACK_FIXED)

View File

@ -33,7 +33,7 @@ from sugar.graphics.canvasicon import CanvasIcon
def _create_icon(): def _create_icon():
color = XoColor() color = XoColor()
icon = CanvasIcon(size=100, color=color, icon = CanvasIcon(size=100, xo_color=color,
icon_name='stock-buddy') icon_name='stock-buddy')
box.add_item(icon) box.add_item(icon)