[Sugar-devel] [Chat 1/2] Remove use of hippo (1)
godiard at sugarlabs.org
godiard at sugarlabs.org
Thu Jan 5 08:52:05 EST 2012
From: Gonzalo Odiard <godiard at gmail.com>
This patch remove the use of CanvasBox containers but does not
support smiles and the links are managed by the standard gtk procedure.
Smiles and links will be implemented in the next patch.
Signed-by-off: Gonzalo Odiard <gonzalo at laptop.org>
---
activity.py | 5 +-
chat/box.py | 174 +++++++++++++++++++++++++++++-------------------------
chat/roundbox.py | 96 ++++++++++++++++++++++++++++++
3 files changed, 190 insertions(+), 85 deletions(-)
create mode 100644 chat/roundbox.py
diff --git a/activity.py b/activity.py
index 7d239cc..18ce996 100644
--- a/activity.py
+++ b/activity.py
@@ -14,7 +14,6 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-import hippo
import gtk
import logging
import cjson
@@ -267,14 +266,12 @@ class Chat(activity.Activity):
self.entry = entry
self.chatbox = ChatBox()
- canvas = hippo.Canvas()
- canvas.set_root(self.chatbox)
hbox = gtk.HBox()
hbox.add(entry)
box = gtk.VBox(homogeneous=False)
- box.pack_start(canvas)
+ box.pack_start(self.chatbox)
box.pack_start(hbox, expand=False)
return box
diff --git a/chat/box.py b/chat/box.py
index a05015c..c3db97d 100644
--- a/chat/box.py
+++ b/chat/box.py
@@ -25,13 +25,11 @@ from gettext import gettext as _
from os.path import join
import gtk
-import hippo
import pango
import cairo
from sugar.graphics import style
-from sugar.graphics.roundbox import CanvasRoundBox
-from sugar.graphics.palette import Palette, CanvasInvoker
+from sugar.graphics.palette import Palette
from sugar.presence import presenceservice
from sugar.graphics.menuitem import MenuItem
from sugar.activity.activity import get_activity_root, show_object_in_journal
@@ -40,6 +38,7 @@ from sugar.datastore import datastore
from sugar import profile
from chat import smilies
+from chat.roundbox import RoundBox
_URL_REGEXP = re.compile('((http|ftp)s?://)?'
@@ -47,10 +46,33 @@ _URL_REGEXP = re.compile('((http|ftp)s?://)?'
'(:[1-9][0-9]{0,4})?(/[-a-zA-Z0-9/%~@&_+=;:,.?#]*[a-zA-Z0-9/])?')
-class ChatBox(hippo.CanvasScrollbars):
+class ColorLabel(gtk.Label):
+
+ def __init__(self, text, color=None):
+ self._color = color
+ if self._color is not None:
+ text = '<span foreground="%s">' % self._color.get_html() + \
+ text + '</span>'
+ gtk.Label.__init__(self)
+ self.set_use_markup(True)
+ self.set_markup(text)
+
+
+class LinkLabel(ColorLabel):
+
+ def __init__(self, text, color=None):
+ self.text = '<a href="%s">' % text + \
+ text + '</a>'
+ ColorLabel.__init__(self, self.text, color)
+
+ def create_palette(self):
+ return _URLMenu(self.text)
+
+
+class ChatBox(gtk.ScrolledWindow):
def __init__(self):
- hippo.CanvasScrollbars.__init__(self)
+ gtk.ScrolledWindow.__init__(self)
self.owner = presenceservice.get_instance().get_owner()
@@ -62,16 +84,16 @@ class ChatBox(hippo.CanvasScrollbars):
self._last_msg = None
self._chat_log = ''
- self._conversation = hippo.CanvasBox(
- spacing=0,
- box_width=-1, # natural width
- background_color=style.COLOR_WHITE.get_int())
+ self._conversation = gtk.VBox()
+ self._conversation.set_homogeneous(False)
+ #self._conversation.background_color=style.COLOR_WHITE
+ #spacing=0,
+ #box_width=-1, # natural width
+ #background_color=style.COLOR_WHITE.get_int())
- self.set_policy(hippo.ORIENTATION_HORIZONTAL,
- hippo.SCROLLBAR_NEVER)
- self.set_root(self._conversation)
-
- vadj = self.props.widget.get_vadjustment()
+ self.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
+ self.add_with_viewport(self._conversation)
+ vadj = self.get_vadjustment()
vadj.connect('changed', self._scroll_changed_cb)
vadj.connect('value-changed', self._scroll_value_changed_cb)
@@ -89,7 +111,6 @@ class ChatBox(hippo.CanvasScrollbars):
False: show what buddy said
True: show what buddy did
- hippo layout:
.------------- rb ---------------.
| +name_vbox+ +----msg_vbox----+ |
| | | | | |
@@ -102,7 +123,6 @@ class ChatBox(hippo.CanvasScrollbars):
| | +------------+ | |
| +----------------+ |
`--------------------------------'
- ###Warning hippocanvas dependency###
"""
if not buddy:
buddy = self.owner
@@ -123,13 +143,13 @@ class ChatBox(hippo.CanvasScrollbars):
color_fill_rgba = style.Color(color_fill_html).get_rgba()
color_fill_gray = (color_fill_rgba[0] + color_fill_rgba[1] +
color_fill_rgba[2]) / 3
- color_stroke = style.Color(color_stroke_html).get_int()
- color_fill = style.Color(color_fill_html).get_int()
+ color_stroke = style.Color(color_stroke_html)
+ color_fill = style.Color(color_fill_html)
if color_fill_gray < 0.5:
- text_color = style.COLOR_WHITE.get_int()
+ text_color = style.COLOR_WHITE
else:
- text_color = style.COLOR_BLACK.get_int()
+ text_color = style.COLOR_BLACK
self._add_log(nick, color, text, status_message)
@@ -150,32 +170,25 @@ class ChatBox(hippo.CanvasScrollbars):
if not new_msg:
rb = self._last_msg
msg_vbox = rb.get_children()[1]
- msg_hbox = hippo.CanvasBox(
- box_width=-1, # natural width
- orientation=hippo.ORIENTATION_HORIZONTAL)
- msg_vbox.append(msg_hbox)
+ msg_hbox = gtk.HBox()
+ msg_hbox.show()
+ msg_vbox.pack_start(msg_hbox, True, True)
else:
- rb = CanvasRoundBox(background_color=color_fill,
- border_color=color_stroke,
- box_width=-1, # natural width
- padding=4)
- rb.props.border_color = color_stroke # Bug #3742
+ rb = RoundBox()
+ rb.background_color = color_fill
+ rb.border_color = color_stroke
self._last_msg = rb
self._last_msg_sender = buddy
if not status_message:
- name = hippo.CanvasText(text=nick + ': ', color=text_color)
- name_vbox = hippo.CanvasBox(
- box_width=-1,
- orientation=hippo.ORIENTATION_VERTICAL)
- name_vbox.append(name)
- rb.append(name_vbox)
- msg_vbox = hippo.CanvasBox(
- orientation=hippo.ORIENTATION_VERTICAL)
- rb.append(msg_vbox)
- msg_hbox = hippo.CanvasBox(
- orientation=hippo.ORIENTATION_HORIZONTAL)
- msg_vbox.append(msg_hbox)
+ name = ColorLabel(text=nick + ': ', color=text_color)
+ name_vbox = gtk.VBox()
+ name_vbox.pack_start(name, False, False)
+ rb.pack_start(name_vbox, False, False)
+ msg_vbox = gtk.VBox()
+ rb.pack_start(msg_vbox, False, False)
+ msg_hbox = gtk.HBox()
+ msg_vbox.pack_start(msg_hbox, False, False)
if status_message:
self._last_msg_sender = None
@@ -185,46 +198,49 @@ class ChatBox(hippo.CanvasScrollbars):
# there is a URL in the text
starttext = text[:match.start()]
if starttext:
- message = hippo.CanvasText(
+ message = ColorLabel(
text=starttext,
- size_mode=hippo.CANVAS_SIZE_WRAP_WORD,
- color=text_color,
- xalign=hippo.ALIGNMENT_START)
- msg_hbox.append(message)
+ color=text_color)
+ msg_hbox.pack_start(message, True, True)
+ message.show()
url = text[match.start():match.end()]
- message = _CanvasLink(
+ message = LinkLabel(
text=url,
color=text_color)
- attrs = pango.AttrList()
- attrs.insert(pango.AttrUnderline(pango.UNDERLINE_SINGLE, 0, 32767))
- message.set_property("attributes", attrs)
- message.connect('activated', self._link_activated_cb)
+ message.connect('activate-link', self._link_activated_cb)
- # call interior magic which should mean just:
- # CanvasInvoker().parent = message
- CanvasInvoker(message)
+ align = gtk.Alignment(xalign=0.0, yalign=0.0, xscale=0.0,
+ yscale=0.0)
+ align.add(message)
- msg_hbox.append(message)
+ msg_hbox.pack_start(align, True, True)
+ msg_hbox.show()
text = text[match.end():]
match = _URL_REGEXP.search(text)
if text:
for word in smilies.parse(text):
if isinstance(word, cairo.ImageSurface):
+ pass
+ # TODO:
+ """
item = hippo.CanvasImage(
image=word,
border=0,
border_color=style.COLOR_BUTTON_GREY.get_int(),
xalign=hippo.ALIGNMENT_CENTER,
yalign=hippo.ALIGNMENT_CENTER)
+ """
else:
- item = hippo.CanvasText(
+ item = ColorLabel(
text=word,
- size_mode=hippo.CANVAS_SIZE_WRAP_WORD,
- color=text_color,
- xalign=hippo.ALIGNMENT_START)
- msg_hbox.append(item)
+ color=text_color)
+ item.show()
+ align = gtk.Alignment(xalign=0.0, yalign=0.0, xscale=0.0,
+ yscale=0.0)
+ align.add(item)
+ msg_hbox.pack_start(align, True, True)
# Order of boxes for RTL languages:
if lang_rtl:
@@ -233,9 +249,11 @@ class ChatBox(hippo.CanvasScrollbars):
rb.reverse()
if new_msg:
- box = hippo.CanvasBox(padding=2)
- box.append(rb)
- self._conversation.append(box)
+ box = RoundBox() # TODO: padding=2)
+ box.show()
+ box.pack_start(rb, True, True)
+ self._conversation.pack_start(box, False, False)
+ self._conversation.show_all()
def add_separator(self, timestamp):
"""Add whitespace and timestamp between chat sessions."""
@@ -248,15 +266,17 @@ class ChatBox(hippo.CanvasScrollbars):
time.strptime(timestamp, "%b %d %H:%M:%S")[1:]
timestamp_seconds = time.mktime(time_with_previous_year)
- message = hippo.CanvasText(
+ message = ColorLabel(
text=timestamp_to_elapsed_string(timestamp_seconds),
- color=style.COLOR_BUTTON_GREY.get_int(),
- font_desc=style.FONT_NORMAL.get_pango_desc(),
- xalign=hippo.ALIGNMENT_CENTER)
-
- box = hippo.CanvasBox(padding=2)
- box.append(message)
- self._conversation.append(box)
+ color=style.COLOR_BUTTON_GREY)
+
+ box = gtk.HBox()
+ box.show()
+ align = gtk.Alignment(xalign=0.5, yalign=0.0, xscale=0.0, yscale=0.0)
+ box.pack_start(align, True, True)
+ align.add(message)
+ box.show_all()
+ self._conversation.pack_start(box, False, False)
self.add_log_timestamp(timestamp)
self._last_msg_sender = None
@@ -306,9 +326,10 @@ class ChatBox(hippo.CanvasScrollbars):
adj.set_value(adj.upper - adj.page_size)
self._scroll_value = adj.get_value()
- def _link_activated_cb(self, link):
+ def _link_activated_cb(self, label, link):
url = _url_check_protocol(link.props.text)
self._show_via_journal(url)
+ return False
def _show_via_journal(self, url):
"""Ask the journal to display a URL"""
@@ -332,15 +353,6 @@ class ChatBox(hippo.CanvasScrollbars):
os.unlink(file_path)
-class _CanvasLink(hippo.CanvasLink):
-
- def __init__(self, **kwargs):
- hippo.CanvasLink.__init__(self, **kwargs)
-
- def create_palette(self):
- return _URLMenu(self.props.text)
-
-
class _URLMenu(Palette):
def __init__(self, url):
diff --git a/chat/roundbox.py b/chat/roundbox.py
new file mode 100644
index 0000000..71298dd
--- /dev/null
+++ b/chat/roundbox.py
@@ -0,0 +1,96 @@
+import math
+import gtk
+from sugar.graphics import style
+
+
+class RoundBox(gtk.HBox):
+ __gtype_name__ = 'RoundBox'
+
+ _BORDER_DEFAULT = style.LINE_WIDTH
+
+ def __init__(self, **kwargs):
+ gtk.HBox.__init__(self, **kwargs)
+
+ self._radius = style.zoom(10)
+ self.border = self._BORDER_DEFAULT
+ self.border_color = style.COLOR_BLACK
+ self.background_color = None
+ self.set_reallocate_redraws(True)
+ self.set_resize_mode(gtk.RESIZE_PARENT)
+ self.connect("expose_event", self.__expose_cb)
+ self.connect("add", self.__add_cb)
+
+ def __add_cb(self, child, params):
+ child.set_border_width(style.zoom(5))
+
+ def __size_allocate_cb(self, widget, allocation):
+ self._x = allocation.x
+ self._y = allocation.y
+ self._width = allocation.width
+ self._height = allocation.height
+
+ def __expose_cb(self, widget, event):
+ context = widget.window.cairo_create()
+
+ # set a clip region for the expose event
+ context.rectangle(event.area.x, event.area.y,
+ event.area.width, event.area.height)
+ context.clip()
+ self.draw(context)
+ return False
+
+ def draw(self, cr):
+ rect = self.get_allocation()
+ x = rect.x + self._BORDER_DEFAULT / 2
+ y = rect.y + self._BORDER_DEFAULT / 2
+ width = rect.width - self._BORDER_DEFAULT
+ height = rect.height - self._BORDER_DEFAULT
+
+ cr.move_to(x + self._radius, y)
+ cr.arc(x + width - self._radius, y + self._radius,
+ self._radius, math.pi * 1.5, math.pi * 2)
+ cr.arc(x + width - self._radius, y + height - self._radius,
+ self._radius, 0, math.pi * 0.5)
+ cr.arc(x + self._radius, y + height - self._radius,
+ self._radius, math.pi * 0.5, math.pi)
+ cr.arc(x + self._radius, y + self._radius, self._radius,
+ math.pi, math.pi * 1.5)
+ cr.close_path()
+
+ if self.background_color is not None:
+ r, g, b, a = self.background_color.get_rgba()
+ cr.set_source_rgb(r, g, b)
+ cr.fill_preserve()
+
+ if self.border_color is not None:
+ r, g, b, a = self.border_color.get_rgba()
+ cr.set_source_rgb(r, g, b)
+ cr.set_line_width(self.border)
+ cr.stroke()
+
+if __name__ == '__main__':
+
+ win = gtk.Window()
+ win.connect('destroy', gtk.main_quit)
+ win.set_default_size(450, 550)
+ vbox = gtk.VBox()
+
+ box1 = RoundBox()
+ vbox.add(box1)
+ label1 = gtk.Label("Test 1")
+ box1.add(label1)
+
+ rbox = RoundBox()
+ rbox.background_color = style.Color('#FF0000')
+ vbox.add(rbox)
+ label2 = gtk.Label("Test 2")
+ rbox.add(label2)
+
+ bbox = RoundBox()
+ bbox.background_color = style.Color('#aaff33')
+ bbox.border_color = style.Color('#ff3300')
+ vbox.add(bbox)
+
+ win.add(vbox)
+ win.show_all()
+ gtk.main()
--
1.7.7.5
More information about the Sugar-devel
mailing list