First go at the new intro screen, work in progress.
This commit is contained in:
parent
e4bce9271a
commit
9dab5fffaf
@ -14,281 +14,38 @@
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
import gtk, gobject
|
||||
import os
|
||||
from ConfigParser import ConfigParser
|
||||
from gettext import gettext as _
|
||||
|
||||
import gtk
|
||||
import gobject
|
||||
import dbus
|
||||
import hippo
|
||||
import logging
|
||||
from gettext import gettext as _
|
||||
|
||||
import os
|
||||
from ConfigParser import ConfigParser
|
||||
|
||||
from sugar import env
|
||||
|
||||
from sugar.graphics import units
|
||||
from sugar.graphics import style
|
||||
from sugar.graphics import color
|
||||
from sugar.graphics import iconbutton
|
||||
from sugar.graphics.canvasentry import CanvasEntry
|
||||
|
||||
import colorpicker
|
||||
|
||||
_VIDEO_WIDTH = units.points_to_pixels(160)
|
||||
_VIDEO_HEIGHT = units.points_to_pixels(120)
|
||||
|
||||
class IntroImage(gtk.EventBox):
|
||||
__gtype_name__ = "IntroImage"
|
||||
|
||||
class _NamePage(hippo.CanvasBox):
|
||||
def __init__(self, **kwargs):
|
||||
gtk.EventBox.__init__(self, **kwargs)
|
||||
self._image = gtk.Image()
|
||||
self.add(self._image)
|
||||
hippo.CanvasBox.__init__(self, xalign=hippo.ALIGNMENT_CENTER,
|
||||
spacing=style.DEFAULT_SPACING,
|
||||
orientation=hippo.ORIENTATION_HORIZONTAL,
|
||||
**kwargs)
|
||||
|
||||
def set_pixbuf(self, pixbuf):
|
||||
if pixbuf:
|
||||
self._image.set_from_pixbuf(pixbuf)
|
||||
else:
|
||||
self._image.clear()
|
||||
label = hippo.CanvasText(text=_("Name:"))
|
||||
self.append(label)
|
||||
|
||||
self._entry = CanvasEntry(box_width=style.zoom(300))
|
||||
self._entry.props.widget.set_max_length(45)
|
||||
self.append(self._entry)
|
||||
|
||||
class IntroFallbackVideo(gtk.EventBox):
|
||||
__gtype_name__ = "IntroFallbackVideo"
|
||||
|
||||
__gsignals__ = {
|
||||
'pixbuf': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([gobject.TYPE_PYOBJECT])),
|
||||
}
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
gtk.EventBox.__init__(self, **kwargs)
|
||||
self._image = gtk.Image()
|
||||
self._image.set_from_stock(gtk.STOCK_OPEN, -1)
|
||||
self.add(self._image)
|
||||
self._image.show()
|
||||
self.connect('button-press-event', self._button_press_event_cb)
|
||||
|
||||
def play(self):
|
||||
pass
|
||||
|
||||
def stop(self):
|
||||
pass
|
||||
|
||||
def _button_press_event_cb(self, widget, event):
|
||||
filt = gtk.FileFilter()
|
||||
filt.add_pixbuf_formats()
|
||||
chooser = gtk.FileChooserDialog(_("Pick a buddy picture"), \
|
||||
buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
|
||||
chooser.set_filter(filt)
|
||||
resp = chooser.run()
|
||||
if resp == gtk.RESPONSE_ACCEPT:
|
||||
fname = chooser.get_filename()
|
||||
self.load_image(fname)
|
||||
chooser.hide()
|
||||
chooser.destroy()
|
||||
return True
|
||||
|
||||
def load_image(self, path):
|
||||
pixbuf = gtk.gdk.pixbuf_new_from_file(path)
|
||||
self.emit('pixbuf', pixbuf)
|
||||
|
||||
class VideoBox(hippo.CanvasBox, hippo.CanvasItem):
|
||||
__gtype_name__ = "SugarVideoBox"
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
hippo.CanvasBox.__init__(self, **kwargs)
|
||||
self.props.orientation = hippo.ORIENTATION_HORIZONTAL
|
||||
self._pixbuf = None
|
||||
|
||||
self._label = hippo.CanvasText(text=_("My Picture:"),
|
||||
xalign=hippo.ALIGNMENT_START,
|
||||
padding_right=units.grid_to_pixels(0.5))
|
||||
self._label.props.color = color.LABEL_TEXT.get_int()
|
||||
self._label.props.font_desc = style.FONT_NORMAL.get_pango_desc()
|
||||
self.append(self._label)
|
||||
|
||||
# check for camera and if not generate a .jpg
|
||||
has_webcam = False
|
||||
try:
|
||||
sys_bus = dbus.SystemBus()
|
||||
hal_obj = sys_bus.get_object ('org.freedesktop.Hal', '/org/freedesktop/Hal/Manager')
|
||||
hal = dbus.Interface (hal_obj, 'org.freedesktop.Hal.Manager')
|
||||
|
||||
udis = hal.FindDeviceByCapability ('video4linux')
|
||||
|
||||
# check for the olpc specific camera
|
||||
if not udis:
|
||||
udis = hal.FindDeviceStringMatch('info.linux.driver','cafe1000-ccic')
|
||||
|
||||
if udis:
|
||||
has_webcam = True
|
||||
|
||||
finally:
|
||||
if has_webcam:
|
||||
import glive
|
||||
self._video = glive.LiveVideoSlot(_VIDEO_WIDTH, _VIDEO_HEIGHT)
|
||||
else:
|
||||
self._video = IntroFallbackVideo()
|
||||
|
||||
self._video.set_size_request(_VIDEO_WIDTH, _VIDEO_HEIGHT)
|
||||
self._video.connect('pixbuf', self._new_pixbuf_cb)
|
||||
|
||||
self._video_widget = hippo.CanvasWidget()
|
||||
self._video_widget.props.widget = self._video
|
||||
self.append(self._video_widget)
|
||||
gobject.idle_add(self._video.play)
|
||||
|
||||
self._img = IntroImage()
|
||||
self._img.set_size_request(_VIDEO_WIDTH, _VIDEO_HEIGHT)
|
||||
self._img.connect('button-press-event', self._clear_image_cb)
|
||||
self._img_widget = hippo.CanvasWidget()
|
||||
self._img_widget.props.widget = self._img
|
||||
|
||||
if not has_webcam:
|
||||
path = os.path.join(os.path.dirname(__file__),
|
||||
'default-picture.png')
|
||||
self._video.load_image(path)
|
||||
|
||||
def _clear_image_cb(self, widget, event):
|
||||
del self._pixbuf
|
||||
self._pixbuf = None
|
||||
self.remove(self._img_widget)
|
||||
self._img.set_pixbuf(None)
|
||||
|
||||
self.append(self._video_widget)
|
||||
self._video.play()
|
||||
|
||||
def _new_pixbuf_cb(self, widget, pixbuf):
|
||||
if self._pixbuf:
|
||||
del self._pixbuf
|
||||
self._pixbuf = pixbuf
|
||||
self._video.stop()
|
||||
self.remove(self._video_widget)
|
||||
|
||||
scaled = pixbuf.scale_simple(_VIDEO_WIDTH, _VIDEO_HEIGHT, gtk.gdk.INTERP_BILINEAR)
|
||||
self._img.set_pixbuf(scaled)
|
||||
self._img.show_all()
|
||||
self.append(self._img_widget)
|
||||
|
||||
def get_pixbuf(self):
|
||||
return self._pixbuf
|
||||
|
||||
class EntryBox(hippo.CanvasBox, hippo.CanvasItem):
|
||||
__gtype_name__ = "SugarEntryBox"
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
hippo.CanvasBox.__init__(self, **kwargs)
|
||||
self.props.orientation = hippo.ORIENTATION_HORIZONTAL
|
||||
|
||||
self._label = hippo.CanvasText(text=_("My Name:"),
|
||||
xalign=hippo.ALIGNMENT_START,
|
||||
padding_right=units.grid_to_pixels(0.5))
|
||||
self._label.props.color = color.LABEL_TEXT.get_int()
|
||||
self._label.props.font_desc = style.FONT_NORMAL.get_pango_desc()
|
||||
self.append(self._label)
|
||||
|
||||
self._entry = gtk.Entry()
|
||||
self._entry.set_max_length(45)
|
||||
entry_item = hippo.CanvasWidget(widget=self._entry)
|
||||
self.append(entry_item)
|
||||
|
||||
def get_text(self):
|
||||
return self._entry.props.text
|
||||
|
||||
def flash_label(self):
|
||||
"""Briefly flashes the label to draw the user's attention to the
|
||||
control"""
|
||||
|
||||
old_fg_color = color.LABEL_TEXT.get_int()
|
||||
old_bg_color = 0x000000ff # background color set above
|
||||
r,g,b,a = color.LABEL_TEXT.get_rgba()
|
||||
fg_opposite = color.RGBColor(1 - r, 1 - g, 1 - b)
|
||||
bg_opposite = color.RGBColor(1, 1, 1)
|
||||
|
||||
self._label.props.color = fg_opposite.get_int()
|
||||
self._label.props.background_color = bg_opposite.get_int()
|
||||
|
||||
gobject.timeout_add(200, self._flash_reset, old_fg_color, old_bg_color)
|
||||
|
||||
def _flash_reset(self, old_fg_color, old_bg_color):
|
||||
self._label.props.color = old_fg_color
|
||||
self._label.props.background_color = old_bg_color
|
||||
return False
|
||||
|
||||
|
||||
class ColorBox(hippo.CanvasBox, hippo.CanvasItem):
|
||||
__gtype_name__ = "SugarColorBox"
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
hippo.CanvasBox.__init__(self, **kwargs)
|
||||
self.props.orientation = hippo.ORIENTATION_HORIZONTAL
|
||||
self._color = None
|
||||
|
||||
self._label = hippo.CanvasText(text=_("My Color:"),
|
||||
xalign=hippo.ALIGNMENT_START,
|
||||
padding_right=units.grid_to_pixels(0.5))
|
||||
self._label.props.color = color.LABEL_TEXT.get_int()
|
||||
self._label.props.font_desc = style.FONT_NORMAL.get_pango_desc()
|
||||
self.append(self._label)
|
||||
|
||||
self._cp = colorpicker.ColorPicker()
|
||||
self._cp.connect('color', self._new_color_cb)
|
||||
self.append(self._cp)
|
||||
|
||||
self._color = self._cp.get_color()
|
||||
|
||||
def _new_color_cb(self, widget, color):
|
||||
self._color = color
|
||||
|
||||
def get_color(self):
|
||||
return self._color
|
||||
|
||||
class IntroBox(hippo.CanvasBox, hippo.CanvasItem):
|
||||
__gtype_name__ = 'SugarIntroBox'
|
||||
|
||||
__gsignals__ = {
|
||||
'ok': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
|
||||
([gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT]))
|
||||
}
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
hippo.CanvasBox.__init__(self, **kwargs)
|
||||
self._pixbuf = None
|
||||
|
||||
#self._video_box = VideoBox(xalign=hippo.ALIGNMENT_CENTER,
|
||||
# yalign=hippo.ALIGNMENT_START,
|
||||
# padding_bottom=units.grid_to_pixels(0.5))
|
||||
#self.append(self._video_box)
|
||||
|
||||
self._entry_box = EntryBox(xalign=hippo.ALIGNMENT_CENTER,
|
||||
padding_bottom=units.grid_to_pixels(0.5))
|
||||
self.append(self._entry_box)
|
||||
|
||||
self._color_box = ColorBox(xalign=hippo.ALIGNMENT_CENTER,
|
||||
padding_bottom=units.grid_to_pixels(0.5))
|
||||
self.append(self._color_box)
|
||||
|
||||
self._ok = iconbutton.IconButton(icon_name="theme:go-next",
|
||||
padding_bottom=units.grid_to_pixels(0.5))
|
||||
self._ok.connect('activated', self._ok_activated)
|
||||
self.append(self._ok)
|
||||
|
||||
def _ok_activated(self, item):
|
||||
#pixbuf = self._video_box.get_pixbuf()
|
||||
path = os.path.join(os.path.dirname(__file__),
|
||||
'default-picture.png')
|
||||
pixbuf = gtk.gdk.pixbuf_new_from_file(path)
|
||||
name = self._entry_box.get_text()
|
||||
color = self._color_box.get_color()
|
||||
|
||||
name = self._check_nickname(name)
|
||||
|
||||
if name is None:
|
||||
self._entry_box.flash_label()
|
||||
return
|
||||
|
||||
if not pixbuf or not name or not color:
|
||||
print "not one of pixbuf(%r), name(%r), or color(%r)"
|
||||
return
|
||||
|
||||
self.emit('ok', pixbuf, name, color)
|
||||
def get_name(self):
|
||||
return self._check_nickname(self._entry.props.text)
|
||||
|
||||
def _check_nickname(self, name):
|
||||
"""Returns None if a bad nickname, returns the corrected nickname
|
||||
@ -304,27 +61,112 @@ class IntroBox(hippo.CanvasBox, hippo.CanvasItem):
|
||||
|
||||
return name
|
||||
|
||||
class _ColorPage(hippo.CanvasBox):
|
||||
def __init__(self, **kwargs):
|
||||
hippo.CanvasBox.__init__(self, xalign=hippo.ALIGNMENT_CENTER,
|
||||
spacing=style.DEFAULT_SPACING,
|
||||
yalign=hippo.ALIGNMENT_CENTER,
|
||||
**kwargs)
|
||||
self._color = None
|
||||
|
||||
self._label = hippo.CanvasText(text=_("Click to change color:"),
|
||||
xalign=hippo.ALIGNMENT_CENTER)
|
||||
self.append(self._label)
|
||||
|
||||
self._cp = colorpicker.ColorPicker(xalign=hippo.ALIGNMENT_CENTER)
|
||||
self._cp.connect('color', self._new_color_cb)
|
||||
self.append(self._cp)
|
||||
|
||||
self._color = self._cp.get_color()
|
||||
|
||||
def _new_color_cb(self, widget, color):
|
||||
self._color = color
|
||||
|
||||
def get_color(self):
|
||||
return self._color
|
||||
|
||||
class _IntroBox(hippo.CanvasBox):
|
||||
__gsignals__ = {
|
||||
'done': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE,
|
||||
([gobject.TYPE_PYOBJECT, gobject.TYPE_PYOBJECT,
|
||||
gobject.TYPE_PYOBJECT]))
|
||||
}
|
||||
|
||||
PAGE_NAME = 0
|
||||
PAGE_COLOR = 1
|
||||
|
||||
PAGE_FIRST = PAGE_NAME
|
||||
PAGE_LAST = PAGE_COLOR
|
||||
|
||||
def __init__(self):
|
||||
hippo.CanvasBox.__init__(self, padding=style.zoom(30))
|
||||
|
||||
self._page = self.PAGE_NAME
|
||||
|
||||
page_color = style.COLOR_PANEL_GREY.get_int()
|
||||
self._name_page = _NamePage(background_color=page_color)
|
||||
self._color_page = _ColorPage(background_color=page_color)
|
||||
|
||||
self._setup_page()
|
||||
|
||||
def _setup_page(self):
|
||||
self.remove_all()
|
||||
|
||||
if self._page == self.PAGE_NAME:
|
||||
self.append(self._name_page, hippo.PACK_EXPAND)
|
||||
elif self._page == self.PAGE_COLOR:
|
||||
self.append(self._color_page, hippo.PACK_EXPAND)
|
||||
|
||||
button_box = hippo.CanvasBox(orientation=hippo.ORIENTATION_HORIZONTAL)
|
||||
|
||||
if self._page != self.PAGE_FIRST:
|
||||
back_button = hippo.CanvasButton(text=_('Back'))
|
||||
back_button.connect('activated', self._done_activated_cb)
|
||||
button_box.append(back_button)
|
||||
|
||||
spacer = hippo.CanvasBox()
|
||||
button_box.append(spacer, hippo.PACK_EXPAND)
|
||||
|
||||
if self._page == self.PAGE_LAST:
|
||||
done_button = hippo.CanvasButton(text=_('Done'))
|
||||
done_button.connect('activated', self._done_activated_cb)
|
||||
button_box.append(done_button)
|
||||
else:
|
||||
next_button = hippo.CanvasButton(text=_('Next'))
|
||||
next_button.connect('activated', self._next_activated_cb)
|
||||
button_box.append(next_button)
|
||||
|
||||
self.append(button_box)
|
||||
|
||||
def _back_activated_cb(self, item):
|
||||
self._page -= 1
|
||||
self._setup_page()
|
||||
|
||||
def _next_activated_cb(self, item):
|
||||
self._page += 1
|
||||
self._setup_page()
|
||||
|
||||
def _done_activated_cb(self, item):
|
||||
path = os.path.join(os.path.dirname(__file__), 'default-picture.png')
|
||||
pixbuf = gtk.gdk.pixbuf_new_from_file(path)
|
||||
name = self._name_page.get_name()
|
||||
color = self._color_page.get_color()
|
||||
|
||||
self.emit('done', pixbuf, name, color)
|
||||
|
||||
class IntroWindow(gtk.Window):
|
||||
def __init__(self):
|
||||
gtk.Window.__init__(self)
|
||||
self.set_default_size(gtk.gdk.screen_width(),
|
||||
gtk.gdk.screen_height())
|
||||
self.realize()
|
||||
self.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DESKTOP)
|
||||
|
||||
self._canvas = hippo.Canvas()
|
||||
self._intro_box = IntroBox(background_color=0x000000ff,
|
||||
yalign=hippo.ALIGNMENT_START,
|
||||
padding_top=units.grid_to_pixels(2),
|
||||
padding_left=units.grid_to_pixels(3),
|
||||
padding_right=units.grid_to_pixels(3))
|
||||
self._intro_box.connect('ok', self._ok_cb)
|
||||
self._intro_box = _IntroBox()
|
||||
self._intro_box.connect('done', self._done_cb)
|
||||
self._canvas.set_root(self._intro_box)
|
||||
self.add(self._canvas)
|
||||
self._canvas.show_all()
|
||||
|
||||
def _ok_cb(self, widget, pixbuf, name, color):
|
||||
self.add(self._canvas)
|
||||
self._canvas.show()
|
||||
|
||||
def _done_cb(self, box, pixbuf, name, color):
|
||||
self.hide()
|
||||
gobject.idle_add(self._create_profile, pixbuf, name, color)
|
||||
|
||||
@ -367,6 +209,6 @@ class IntroWindow(gtk.Window):
|
||||
|
||||
if __name__ == "__main__":
|
||||
w = IntroWindow()
|
||||
w.show_all()
|
||||
w.show()
|
||||
w.connect('destroy', gtk.main_quit)
|
||||
gtk.main()
|
||||
|
@ -25,7 +25,7 @@ def _get_screen_dpi():
|
||||
def _compute_zoom_factor():
|
||||
return gtk.gdk.screen_width() / 1200.0
|
||||
|
||||
def _zoom(units):
|
||||
def zoom(units):
|
||||
return int(ZOOM_FACTOR * units)
|
||||
|
||||
def _compute_font_height(font):
|
||||
@ -47,6 +47,40 @@ class Font(object):
|
||||
def get_pango_desc(self):
|
||||
return pango.FontDescription(self._desc)
|
||||
|
||||
class Color(object):
|
||||
def __init__(self, color, alpha=0):
|
||||
self._r, self._g, self._b = self._html_to_rgb(color)
|
||||
self._a = alpha
|
||||
|
||||
def get_rgba(self):
|
||||
return (self._r, self._g, self._b, self._a)
|
||||
|
||||
def get_int(self):
|
||||
return int(self._a * 255) + (int(self._b * 255) << 8) + \
|
||||
(int(self._g * 255) << 16) + (int(self._r * 255) << 24)
|
||||
|
||||
def get_gdk_color(self):
|
||||
return gtk.gdk.Color(int(self._r * 65535), int(self._g * 65535),
|
||||
int(self._b * 65535))
|
||||
|
||||
def get_html(self):
|
||||
return '#%02x%02x%02x' % (self._r * 255, self._g * 255, self._b * 255)
|
||||
|
||||
def _html_to_rgb(self, html_color):
|
||||
""" #RRGGBB -> (r, g, b) tuple (in float format) """
|
||||
|
||||
html_color = html_color.strip()
|
||||
if html_color[0] == '#':
|
||||
html_color = html_color[1:]
|
||||
if len(html_color) != 6:
|
||||
raise ValueError, "input #%s is not in #RRGGBB format" % html_color
|
||||
|
||||
r, g, b = html_color[:2], html_color[2:4], html_color[4:]
|
||||
r, g, b = [int(n, 16) for n in (r, g, b)]
|
||||
r, g, b = (r / 255.0, g / 255.0, b / 255.0)
|
||||
|
||||
return (r, g, b)
|
||||
|
||||
_XO_DPI = 200.0
|
||||
|
||||
_FOCUS_LINE_WIDTH = 2
|
||||
@ -54,14 +88,18 @@ _TAB_CURVATURE = 1
|
||||
|
||||
ZOOM_FACTOR = _compute_zoom_factor()
|
||||
|
||||
FONT_SIZE = _zoom(7 * _XO_DPI / _get_screen_dpi())
|
||||
DEFAULT_SPACING = zoom(6)
|
||||
|
||||
FONT_SIZE = zoom(7 * _XO_DPI / _get_screen_dpi())
|
||||
FONT_NORMAL = Font('Bitstream Vera Sans %d' % FONT_SIZE)
|
||||
FONT_BOLD = Font('Bitstream Vera Sans bold %d' % FONT_SIZE)
|
||||
FONT_NORMAL_H = _compute_font_height(FONT_NORMAL)
|
||||
FONT_BOLD_H = _compute_font_height(FONT_BOLD)
|
||||
|
||||
TOOLBOX_SEPARATOR_HEIGHT = _zoom(9)
|
||||
TOOLBOX_HORIZONTAL_PADDING = _zoom(75)
|
||||
TOOLBOX_TAB_VBORDER = int((_zoom(36) - FONT_NORMAL_H - _FOCUS_LINE_WIDTH) / 2)
|
||||
TOOLBOX_TAB_HBORDER = _zoom(15) - _FOCUS_LINE_WIDTH - _TAB_CURVATURE
|
||||
TOOLBOX_TAB_LABEL_WIDTH = _zoom(150 - 15 * 2)
|
||||
TOOLBOX_SEPARATOR_HEIGHT = zoom(9)
|
||||
TOOLBOX_HORIZONTAL_PADDING = zoom(75)
|
||||
TOOLBOX_TAB_VBORDER = int((zoom(36) - FONT_NORMAL_H - _FOCUS_LINE_WIDTH) / 2)
|
||||
TOOLBOX_TAB_HBORDER = zoom(15) - _FOCUS_LINE_WIDTH - _TAB_CURVATURE
|
||||
TOOLBOX_TAB_LABEL_WIDTH = zoom(150 - 15 * 2)
|
||||
|
||||
COLOR_PANEL_GREY = Color('#C0C0C0')
|
||||
|
Loading…
Reference in New Issue
Block a user