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

This commit is contained in:
Guillaume Desmottes 2007-02-28 17:02:52 +01:00
commit 31fa414e42
15 changed files with 251 additions and 99 deletions

View File

@ -19,19 +19,71 @@
#include <stdlib.h>
#include <gdk/gdkx.h>
#include <gdk/gdkscreen.h>
#include <gtk/gtksettings.h>
#include "sugar-utils.h"
/* Ported from mozilla nsDeviceContextGTK.cpp */
static gint
get_gtk_settings_dpi(void)
{
GtkSettings *settings = gtk_settings_get_default();
GParamSpec *spec;
gint dpi = 0;
spec = g_object_class_find_property(
G_OBJECT_GET_CLASS(G_OBJECT(settings)), "gtk-xft-dpi");
if (spec) {
g_object_get(G_OBJECT(settings),
"gtk-xft-dpi", &dpi,
NULL);
}
return (int)(dpi / 1024.0 + 0.5);
}
static gint
get_xft_dpi(void)
{
char *val = XGetDefault(GDK_DISPLAY(), "Xft", "dpi");
if (val) {
char *e;
double d = strtod(val, &e);
if (e != val)
return (int)(d + 0.5);
}
return 0;
}
static int
get_dpi_from_physical_resolution(void)
{
float screen_width_in;
screen_width_in = (float)(gdk_screen_width_mm()) / 25.4f;
return (int)((float)(gdk_screen_width()) / screen_width_in + 0.5);
}
gint
sugar_get_screen_dpi(void)
{
char *val = XGetDefault (GDK_DISPLAY(), "Xft", "dpi");
if (val) {
char *e;
double d = strtod(val, &e);
if (d > 0.0)
return (int)(d+0.5);
int dpi;
dpi = get_gtk_settings_dpi();
if (dpi == 0) {
dpi = get_xft_dpi();
}
return 96;
if (dpi == 0) {
dpi = get_dpi_from_physical_resolution();
}
return dpi;
}

View File

@ -47,13 +47,6 @@ class ClipboardIcon(CanvasIcon):
self.props.xo_color = XoColor("#000000,#424242")
else:
self.props.xo_color = XoColor("#000000,#FFFFFF")
def _activity_create_success_cb(self, handler, activity):
activity.start(util.unique_id())
activity.execute("open_document", [self._object_id])
def _activity_create_error_cb(self, handler, err):
pass
def _open_file(self):
if self._percent < 100 or not self._activity:
@ -61,10 +54,7 @@ class ClipboardIcon(CanvasIcon):
logging.debug("_icon_activated_cb: " + self._object_id)
# Launch the activity to handle this item
handler = activityfactory.create(self._activity)
handler.connect('success', self._activity_create_success_cb)
handler.connect('error', self._activity_create_error_cb)
activityfactory.create_with_uri(self._activity, self._object_id)
def _icon_activated_cb(self, icon):
self._open_file()

View File

@ -1,6 +1,11 @@
from view.devices import deviceview
from sugar.graphics import canvasicon
class DeviceView(deviceview.DeviceView):
_ICON_NAME = 'device-battery'
class DeviceView(canvasicon.CanvasIcon):
def __init__(self, model):
deviceview.DeviceView.__init__(self, model)
self.props.icon_name = 'theme:stock-close'
canvasicon.CanvasIcon.__init__(self)
self._model = model
icon_name = canvasicon.get_icon_state(_ICON_NAME, 60)
self.props.icon_name = icon_name

View File

@ -1,10 +1,5 @@
from sugar.graphics.canvasicon import CanvasIcon
class DeviceView(CanvasIcon):
def __init__(self, model):
CanvasIcon.__init__(self)
self.model = model
def create(model):
name = 'view.devices.' + model.get_type()

View File

@ -15,20 +15,16 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
from view.devices import deviceview
from sugar.graphics import canvasicon
from sugar.graphics import color
from model.devices import wirelessnetwork
from view.pulsingicon import PulsingIcon
_strength_to_icon = {
(0, 20) : 'stock-net-wireless-00',
(21, 40) : 'stock-net-wireless-21-40',
(41, 60) : 'stock-net-wireless-41-60',
(61, 80) : 'stock-net-wireless-61-80',
(81, 100) : 'stock-net-wireless-81-100'
}
_ICON_NAME = 'device-network-wireless'
class DeviceView(deviceview.DeviceView):
class DeviceView(PulsingIcon):
def __init__(self, model):
deviceview.DeviceView.__init__(self, model)
PulsingIcon.__init__(self)
self._model = model
model.connect('notify::name', self._name_changed_cb)
@ -52,18 +48,20 @@ class DeviceView(deviceview.DeviceView):
self.props.tooltip = self._model.props.name
def _update_icon(self):
strength = self._model.props.strength
for interval in _strength_to_icon.keys():
if strength >= interval[0] and strength <= interval[1]:
stock_name = _strength_to_icon[interval]
self.props.icon_name = 'theme:' + stock_name
icon_name = canvasicon.get_icon_state(
_ICON_NAME, self._model.props.strength)
if icon_name:
self.props.icon_name = icon_name
def _update_state(self):
# FIXME Change icon colors once we have real icons
state = self._model.props.state
if state == wirelessnetwork.STATE_ACTIVATING:
self.props.background_color = 0xFF0000FF
self.props.fill_color = color.ICON_FILL_INACTIVE
self.props.stroke_color = color.ICON_STROKE_INACTIVE
elif state == wirelessnetwork.STATE_ACTIVATED:
self.props.background_color = 0x00FF00FF
self.props.fill_color = None
self.props.stroke_color = None
elif state == wirelessnetwork.STATE_INACTIVE:
self.props.background_color = 0x00000000
self.props.fill_color = color.ICON_FILL_INACTIVE
self.props.stroke_color = color.ICON_STROKE_INACTIVE

View File

@ -22,21 +22,18 @@ import gobject
from sugar.graphics.spreadbox import SpreadBox
from sugar.graphics.snowflakebox import SnowflakeBox
from sugar.graphics.canvasicon import CanvasIcon
from sugar.graphics import color
from sugar.graphics import canvasicon
from model import accesspointmodel
from hardware import hardwaremanager
from view.BuddyIcon import BuddyIcon
from view.pulsingicon import PulsingIcon
_strength_to_icon = {
(0, 20) : 'stock-net-wireless-00',
(21, 40) : 'stock-net-wireless-21-40',
(41, 60) : 'stock-net-wireless-41-60',
(61, 80) : 'stock-net-wireless-61-80',
(81, 100) : 'stock-net-wireless-81-100'
}
_ICON_NAME = 'device-network-wireless'
class AccessPointView(CanvasIcon):
class AccessPointView(PulsingIcon):
def __init__(self, model):
CanvasIcon.__init__(self)
PulsingIcon.__init__(self)
self._model = model
self.connect('activated', self._activate_cb)
@ -45,6 +42,11 @@ class AccessPointView(CanvasIcon):
model.connect('notify::name', self._name_changed_cb)
model.connect('notify::state', self._state_changed_cb)
self.props.colors = [
[ None, None ],
[ color.ICON_FILL_INACTIVE, color.ICON_STROKE_INACTIVE ]
]
self._update_icon()
self._update_name()
self._update_state()
@ -69,20 +71,22 @@ class AccessPointView(CanvasIcon):
self.props.tooltip = self._model.props.name
def _update_icon(self):
strength = self._model.props.strength
for interval in _strength_to_icon.keys():
if strength >= interval[0] and strength <= interval[1]:
stock_name = _strength_to_icon[interval]
self.props.icon_name = 'theme:' + stock_name
icon_name = canvasicon.get_icon_state(
_ICON_NAME, self._model.props.strength)
if icon_name:
self.props.icon_name = icon_name
def _update_state(self):
# FIXME Change icon colors once we have real icons
if self._model.props.state == accesspointmodel.STATE_CONNECTING:
self.props.background_color = 0xFF0000FF
self.props.pulsing = True
elif self._model.props.state == accesspointmodel.STATE_CONNECTED:
self.props.background_color = 0x00FF00FF
self.props.pulsing = False
self.props.fill_color = None
self.props.stroke_color = None
elif self._model.props.state == accesspointmodel.STATE_NOTCONNECTED:
self.props.background_color = 0x00000000
self.props.pulsing = False
self.props.fill_color = color.ICON_FILL_INACTIVE
self.props.stroke_color = color.ICON_STROKE_INACTIVE
class ActivityView(SnowflakeBox):
def __init__(self, shell, menu_shell, model):

78
shell/view/pulsingicon.py Normal file
View File

@ -0,0 +1,78 @@
# Copyright (C) 2006, Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
import gobject
from sugar.graphics.canvasicon import CanvasIcon
class PulsingIcon(CanvasIcon):
__gproperties__ = {
'colors' : (object, None, None,
gobject.PARAM_READWRITE),
'pulsing' : (bool, None, None, False,
gobject.PARAM_READWRITE)
}
def __init__(self, **kwargs):
self._pulsing = False
self._colors = None
self._pulse_sid = 0
self._pos = 0
CanvasIcon.__init__(self, **kwargs)
def do_set_property(self, pspec, value):
CanvasIcon.do_set_property(self, pspec, value)
if pspec.name == 'pulsing':
self._pulsing = value
if self._pulsing:
self._start()
else:
self._stop()
elif pspec.name == 'colors':
self._colors = value
self._pos = 0
def do_get_property(self, pspec):
CanvasIcon.do_get_property(self, pspec, value)
if pspec.name == 'pulsing':
return self._pulsing
elif pspec.name == 'colors':
return self._colors
def _pulse_timeout(self):
if not self._colors:
return
self.props.stroke_color = self._colors[self._pos][0]
self.props.fill_color = self._colors[self._pos][1]
self._pos += 1
if self._pos == len(self._colors):
self._pos = 0
return True
def _start(self):
if self._pulse_sid == 0:
self._pulse_sid = gobject.timeout_add(1000, self._pulse_timeout)
def _stop(self):
if self._pulse_sid:
gobject.source_remove(self._pulse_sid)
self._pulse_sid = 0

View File

@ -36,6 +36,7 @@ else:
from sugar import env
from sugar import util
from sugar.emulator import Emulator
import _sugar
if len(sys.argv) == 1:
program = 'sugar-shell'
@ -51,7 +52,9 @@ else:
width = 1200
height = 900
emulator = Emulator(width, height, fullscreen)
dpi = min(_sugar.get_screen_dpi(), 96)
emulator = Emulator(width, height, fullscreen, dpi)
emulator.start()
if sourcedir:

View File

@ -78,7 +78,7 @@ class MatchboxProcess(Process):
return 'Matchbox'
class XephyrProcess(Process):
def __init__(self, width, height, fullscreen):
def __init__(self, width, height, fullscreen, dpi):
self._display = get_display_number()
cmd = 'Xephyr :%d -ac ' % (self._display)
@ -88,6 +88,9 @@ class XephyrProcess(Process):
if width > 0 and height > 0:
cmd += ' -screen %dx%d' % (width, height)
if dpi > 0:
cmd += ' -dpi %d' % (dpi)
Process.__init__(self, cmd)
def get_name(self):
@ -100,15 +103,16 @@ class XephyrProcess(Process):
class Emulator(object):
"""The OLPC emulator"""
def __init__(self, width, height, fullscreen):
def __init__(self, width, height, fullscreen, dpi):
self._fullscreen = fullscreen
self._width = width
self._height = height
self._dpi = dpi
def start(self):
try:
process = XephyrProcess(self._width, self._height,
self._fullscreen)
self._fullscreen, self._dpi)
process.start()
except:
print 'Cannot run the emulator. You need to install Xephyr'

View File

@ -415,3 +415,15 @@ class CanvasIcon(hippo.CanvasBox, hippo.CanvasItem):
Override this method for adding prelighting behavior.
"""
pass
def get_icon_state(base_name, perc):
step = 5
strength = round(perc / step) * step
icon_theme = gtk.icon_theme_get_default()
while strength <= 100:
icon_name = '%s-%03d' % (base_name, strength)
if icon_theme.has_icon(icon_name):
return 'theme:' + icon_name
strength = strength + step

View File

@ -21,7 +21,9 @@ _system_colors = {
'button-hover' : '#808080',
'button-background-hover' : '#000000',
'button-inactive' : '#808080',
'button-background-inactive' : '#424242'
'button-background-inactive' : '#424242',
'icon-stroke-inactive' : '#757575',
'icon-fill-inactive' : '#9D9FA1'
}
def _html_to_rgb(html_color):
@ -100,3 +102,5 @@ BUTTON_HOVER = SystemColor('button-hover')
BUTTON_BACKGROUND_HOVER = SystemColor('button-background-hover')
BUTTON_INACTIVE = SystemColor('button-inactive')
BUTTON_BACKGROUND_INACTIVE = SystemColor('button-background-inactive')
ICON_FILL_INACTIVE = SystemColor('icon-fill-inactive')
ICON_STROKE_INACTIVE = SystemColor('icon-stroke-inactive')

View File

@ -39,31 +39,33 @@ class Entry(hippo.CanvasBox, hippo.CanvasItem):
'button-activated': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([int]))
}
def __init__(self, text=''):
hippo.CanvasBox.__init__(self, orientation=hippo.ORIENTATION_HORIZONTAL)
self.props.yalign = hippo.ALIGNMENT_CENTER
self._buttons = {}
self._round_box = RoundBox()
self._round_box.props.border_color = color.FRAME_BORDER.get_int()
self.append(self._round_box, hippo.PACK_EXPAND)
def __init__(self, **kwargs):
self._entry = self.create_entry()
self._entry.props.text = ''
self._entry.props.has_frame = False
self._entry.props.text = text
self._update_colors(focused=False)
self._entry.modify_text(gtk.STATE_SELECTED,
color.BLACK.get_gdk_color())
self._entry.connect('focus-in-event', self._entry_focus_in_event_cb)
self._entry.connect('focus-out-event', self._entry_focus_out_event_cb)
self._entry.connect('activate', self._entry_activate_cb)
self._entry.modify_font(font.DEFAULT.get_pango_desc())
hippo.CanvasBox.__init__(self, **kwargs)
self.props.orientation = hippo.ORIENTATION_HORIZONTAL
self.props.yalign = hippo.ALIGNMENT_CENTER
self._buttons = {}
self._round_box = RoundBox()
self._round_box.props.border_color = color.FRAME_BORDER.get_int()
self.append(self._round_box, hippo.PACK_EXPAND)
self._canvas_widget = hippo.CanvasWidget()
self._canvas_widget.props.widget = self._entry
self._round_box.append(self._canvas_widget, hippo.PACK_EXPAND)
self._update_colors(focused=False)
def create_entry(self):
"""
Subclasses can override this method in order to provide a different
@ -84,10 +86,16 @@ class Entry(hippo.CanvasBox, hippo.CanvasItem):
self._buttons[button] = action_id
def do_set_property(self, pspec, value):
self._entry.set_property(pspec.name, value)
if pspec.name in [param.name for param in self._entry.props]:
self._entry.set_property(pspec.name, value)
else:
hippo.CanvasBox.set_property(self, pspec.name, value)
def do_get_property(self, pspec):
return self._entry.get_property(pspec.name)
if pspec.name in [param.name for param in self._entry.props]:
return self._entry.get_property(pspec.name)
else:
return hippo.CanvasBox.get_property(self, pspec.name)
def _entry_focus_in_event_cb(self, widget, event):
self._update_colors(focused=True)

View File

@ -3,8 +3,8 @@ import pango
from sugar.graphics import units
_system_fonts = {
'default' : 'Bitstream Vera Sans %d' % units.points_to_pixels(9),
'default-bold' : 'Bitstream Vera Sans bold %d' % units.points_to_pixels(9)
'default' : 'Bitstream Vera Sans %dpx' % units.points_to_pixels(9),
'default-bold' : 'Bitstream Vera Sans bold %dpx' % units.points_to_pixels(9)
}
class Font(object):

View File

@ -43,16 +43,17 @@ class IconButton(CanvasIcon):
CanvasIcon.__init__(self, cache=True, **kwargs)
if not self.props.fill_color:
if self._active:
self.props.fill_color = color.BUTTON_BACKGROUND_NORMAL
if not self.props.stroke_color:
self.props.stroke_color = color.BUTTON_NORMAL
self.props.background_color = color.BUTTON_BACKGROUND_NORMAL.get_int()
self.props.background_color = \
color.BUTTON_BACKGROUND_NORMAL.get_int()
else:
self.props.fill_color = color.BUTTON_BACKGROUND_INACTIVE
self.props.stroke_color = color.BUTTON_INACTIVE
self.props.background_color = \
color.BUTTON_BACKGROUND_INACTIVE.get_int()
self._normal_fill_color = self.props.fill_color
self._normal_stroke_color = self.props.stroke_color
self._normal_background_color = self.props.background_color
self._set_size(STANDARD_SIZE)
self.connect('button-press-event',
@ -76,13 +77,11 @@ class IconButton(CanvasIcon):
elif pspec.name == 'active':
self._active = value
if self._active:
self.props.fill_color = self._normal_fill_color
self.props.stroke_color = self._normal_stroke_color
self.props.background_color = self._normal_background_color
self.props.fill_color = color.BUTTON_BACKGROUND_NORMAL
self.props.stroke_color = color.BUTTON_NORMAL
else:
self.props.fill_color = color.BUTTON_BACKGROUND_INACTIVE
self.props.stroke_color = color.BUTTON_INACTIVE
self.props.background_color = color.BUTTON_BACKGROUND_INACTIVE.get_int()
else:
CanvasIcon.do_set_property(self, pspec, value)
@ -104,5 +103,5 @@ class IconButton(CanvasIcon):
if self._active:
self.props.background_color = color.BLACK.get_int()
else:
if self._active:
self.props.background_color = self._normal_background_color
self.props.background_color = \
color.BUTTON_BACKGROUND_NORMAL.get_int()

View File

@ -1,6 +1,6 @@
VERSION=0.63
DATE=`date +%Y%m%d`
RELEASE=2.23
RELEASE=2.25
TARBALL=sugar-$VERSION-$RELEASE.${DATE}git.tar.bz2
rm sugar-$VERSION.tar.bz2