# Copyright (C) 2009, Aleksey Lim # # 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 gtk import pango import hippo import logging from gettext import gettext as _ import sugar.graphics.style as style from sugar.graphics.roundbox import CanvasRoundBox from sugar.graphics.toggletoolbutton import ToggleToolButton import eye import glasses import mouth import face import messenger from chatbox import ChatBox logger = logging.getLogger('speak') BUDDY_SIZE = min(100, min(gtk.gdk.screen_width(), gtk.gdk.screen_height() - style.LARGE_ICON_SIZE) / 5) BUDDY_PAD = 5 BUDDIES_WIDTH = int(BUDDY_SIZE * 2.5) BUDDIES_COLOR = style.COLOR_SELECTION_GREY ENTRY_COLOR = style.COLOR_PANEL_GREY ENTRY_XPAD = 0 ENTRY_YPAD = 7 class View(hippo.Canvas): def __init__(self): hippo.Canvas.__init__(self) self.messenger = None self.me = None self.quiet = False self._buddies = {} # buddies box self._buddies_list = hippo.CanvasBox( background_color = BUDDIES_COLOR.get_int(), box_width = BUDDIES_WIDTH, padding = ENTRY_YPAD, spacing = ENTRY_YPAD ) self._buddies_box = hippo.CanvasScrollbars() self._buddies_box.set_policy(hippo.ORIENTATION_HORIZONTAL, hippo.SCROLLBAR_NEVER) self._buddies_box.set_root(self._buddies_list) # chat entry self._chat = ChatBox() self.me, my_face_widget = self._new_face(self._chat.owner, ENTRY_COLOR) chat_post = gtk.TextView() chat_post.modify_bg(gtk.STATE_INSENSITIVE, style.COLOR_WHITE.get_gdk_color()) chat_post.modify_base(gtk.STATE_INSENSITIVE, style.COLOR_WHITE.get_gdk_color()) chat_post.connect('key-press-event', self._key_press_cb) chat_post.props.wrap_mode = gtk.WRAP_WORD_CHAR chat_post.set_size_request(-1, BUDDY_SIZE - ENTRY_YPAD * 2) chat_post_box = CanvasRoundBox( background_color = style.COLOR_WHITE.get_int(), padding_left = ENTRY_XPAD, padding_right = ENTRY_XPAD, padding_top = ENTRY_YPAD, padding_bottom = ENTRY_YPAD ) chat_post_box.props.border_color = ENTRY_COLOR.get_int() chat_post_box.append(hippo.CanvasWidget(widget=chat_post), hippo.PACK_EXPAND) chat_entry = CanvasRoundBox( background_color = ENTRY_COLOR.get_int(), padding_left = ENTRY_XPAD, padding_right = ENTRY_XPAD, padding_top = ENTRY_YPAD, padding_bottom = ENTRY_YPAD, spacing = ENTRY_YPAD ) chat_entry.props.orientation = hippo.ORIENTATION_HORIZONTAL chat_entry.props.border_color = style.COLOR_WHITE.get_int() chat_entry.append(my_face_widget) chat_entry.append(chat_post_box, hippo.PACK_EXPAND) chat_box = hippo.CanvasBox( orientation = hippo.ORIENTATION_VERTICAL, background_color = style.COLOR_WHITE.get_int(), ) chat_box.append(self._chat, hippo.PACK_EXPAND) chat_box.append(chat_entry) # desk self._desk = hippo.CanvasBox() self._desk.props.orientation = hippo.ORIENTATION_HORIZONTAL self._desk.append(chat_box, hippo.PACK_EXPAND) self.set_root(self._desk) def update(self, status): self.me.update(status) if self.messenger: self.messenger.post(None) def post(self, buddy, status, text): i = self._buddies.get(buddy) if not i: self._add_buddy(buddy) i = self._buddies[buddy] face = i['face'] lang_box = i['lang'] if status: face.update(status) if lang_box: lang_box.props.text = status.voice.friendlyname if text: self._chat.add_text(buddy, text) if not self.quiet: # and self.props.window \ # and self.props.window.is_visible(): face.say(text) def farewell(self, buddy): i = self._buddies.get(buddy) if not i: logger.debug('farewell: cannot find buddy %s' % buddy.props.nick) return self._buddies_list.remove(i['box']) del self._buddies[buddy] if len(self._buddies) == 0: self._desk.remove(self._buddies_box) def shut_up(self): for i in self._buddies.values(): i['face'].shut_up(); self.me.shut_up(); def _add_buddy(self, buddy): box = hippo.CanvasBox( orientation = hippo.ORIENTATION_HORIZONTAL, background_color = BUDDIES_COLOR.get_int(), spacing = ENTRY_YPAD ) buddy_face, buddy_widget = self._new_face(buddy, BUDDIES_COLOR) char_box = hippo.CanvasBox( orientation = hippo.ORIENTATION_VERTICAL, ) nick = hippo.CanvasText( text = buddy.props.nick, xalign = hippo.ALIGNMENT_START, yalign = hippo.ALIGNMENT_START ) lang = hippo.CanvasText( text = '', xalign = hippo.ALIGNMENT_START, yalign = hippo.ALIGNMENT_START ) char_box.append(nick) char_box.append(lang) box.append(buddy_widget) box.append(char_box, hippo.PACK_EXPAND) self._buddies[buddy] = { 'box': box, 'face': buddy_face, 'lang': lang } self._buddies_list.append(box) if len(self._buddies) == 1: self._desk.append(self._buddies_box) def _key_press_cb(self, widget, event): if event.keyval == gtk.keysyms.Return: if not (event.state & gtk.gdk.CONTROL_MASK): text = widget.get_buffer().props.text if text: self._chat.add_text(None, text) widget.get_buffer().props.text = '' if not self.quiet: self.me.say(text) if self.messenger: self.messenger.post(text) return True return False def _new_face(self, buddy, color): stroke_color, fill_color = buddy.props.color.split(',') stroke_color = style.Color(stroke_color) fill_color = style.Color(fill_color) buddy_face = face.View(fill_color) buddy_face.show_all() inner = CanvasRoundBox( background_color = fill_color.get_int(), ) inner.props.border_color = fill_color.get_int() inner.append(hippo.CanvasWidget(widget=buddy_face), hippo.PACK_EXPAND) inner.props.border = BUDDY_PAD outer = CanvasRoundBox( background_color = stroke_color.get_int(), box_width = BUDDY_SIZE, box_height = BUDDY_SIZE, ) outer.props.border_color = stroke_color.get_int() outer.append(inner, hippo.PACK_EXPAND) outer.props.border = BUDDY_PAD return (buddy_face, outer) def look_at(self): self.me.look_at() for i in self._buddies.values(): i['face'].look_at()