From 3f792924ddf4dba301d06e496ac6e29296fbd4e9 Mon Sep 17 00:00:00 2001 From: flavio Date: Fri, 09 Nov 2012 23:58:22 +0000 Subject: Gtk 3 Port Base --- diff --git a/.gitignore b/.gitignore index 4751f37..38de751 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ .sweets +*.pyc +*.pyo +*.bak diff --git a/activity.py b/activity.py index c13156d..50a80ca 100644 --- a/activity.py +++ b/activity.py @@ -12,26 +12,33 @@ # 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 gi +from gi.repository import Gtk from gettext import gettext as _ -from sugar.graphics.toggletoolbutton import ToggleToolButton -from sugar.graphics.toolbutton import ToolButton +from sugar3.graphics.toggletoolbutton import ToggleToolButton +from sugar3.graphics.toolbutton import ToolButton +from sugar3.activity.widgets import ActivityToolbarButton +from sugar3.activity.widgets import StopButton from toolkit.activity import SharedActivity from toolkit.temposlider import TempoSlider from toolkit.toolbarbox import ToolbarBox -from toolkit.activity_widgets import * +#from toolkit.activity_widgets import * import model import montage import lessons +#import theme from messenger import Messenger, SERVICE -from theme import * + class flipsticksActivity(SharedActivity): + def __init__(self, handle): - self.notebook = gtk.Notebook() + + self.notebook = Gtk.Notebook() + SharedActivity.__init__(self, self.notebook, SERVICE, handle) self.notebook.show() @@ -39,10 +46,10 @@ class flipsticksActivity(SharedActivity): self.notebook.props.show_tabs = False self.montage = montage.View(self) - self.notebook.append_page(self.montage) + self.notebook.append_page(self.montage, Gtk.Label('')) self.lessons = lessons.View() self.lessons.show() - self.notebook.append_page(self.lessons) + self.notebook.append_page(self.lessons, Gtk.Label('')) toolbox = ToolbarBox() toolbox.show() @@ -54,18 +61,18 @@ class flipsticksActivity(SharedActivity): lessons_button.set_tooltip(_('Lessons')) toolbox.toolbar.insert(lessons_button, -1) - separator = gtk.SeparatorToolItem() + separator = Gtk.SeparatorToolItem() separator.set_draw(False) toolbox.toolbar.insert(separator, -1) - self.notebook_toolbar = gtk.Notebook() + self.notebook_toolbar = Gtk.Notebook() self.notebook_toolbar.props.show_border = False self.notebook_toolbar.props.show_tabs = False - self.notebook_toolbar.append_page(MontageToolbar(self.montage)) - self.notebook_toolbar.append_page(LessonsToolbar()) + self.notebook_toolbar.append_page(MontageToolbar(self.montage), Gtk.Label('')) + self.notebook_toolbar.append_page(LessonsToolbar(), Gtk.Label('')) self.notebook_toolbar.show() - notebook_item = gtk.ToolItem() + notebook_item = Gtk.ToolItem() notebook_item.set_expand(True) notebook_item.add(self.notebook_toolbar) notebook_item.show() @@ -91,46 +98,49 @@ class flipsticksActivity(SharedActivity): self.notebook_toolbar.set_current_page(page) self.notebook.set_current_page(page) -class MontageToolbar(gtk.Toolbar): +class MontageToolbar(Gtk.Toolbar): + def __init__(self, montage): - gtk.Toolbar.__init__(self) + + Gtk.Toolbar.__init__(self) + self.montage = montage # edit buttons setframe = ToolButton('dialog-ok') setframe.connect('clicked', self._setframe_cb) - setframe.set_tooltip(_('Set frame')) + setframe.set_tooltip_text(_('Set frame')) self.insert(setframe, -1) - clearframe = ToolButton('gtk-delete') + clearframe = ToolButton('Gtk-delete') clearframe.connect('clicked', self._clearframe_cb) - clearframe.set_tooltip(_('Clear frame')) + clearframe.set_tooltip_text(_('Clear frame')) self.insert(clearframe, -1) - resetframe = ToolButton('gtk-cancel') + resetframe = ToolButton('Gtk-cancel') resetframe.connect('clicked', self._resetframe_cb) - resetframe.set_tooltip(_('Reset')) + resetframe.set_tooltip_text(_('Reset')) self.insert(resetframe, -1) - separator = gtk.SeparatorToolItem() + separator = Gtk.SeparatorToolItem() self.insert(separator,-1) # play/pause buttons - play_img_1 = gtk.Image() + play_img_1 = Gtk.Image() play_img_1.set_from_icon_name('media-playback-start-back', - gtk.ICON_SIZE_LARGE_TOOLBAR) - pause_img_1 = gtk.Image() + Gtk.IconSize.LARGE_TOOLBAR) + pause_img_1 = Gtk.Image() pause_img_1.set_from_icon_name('media-playback-pause', - gtk.ICON_SIZE_LARGE_TOOLBAR) + Gtk.IconSize.LARGE_TOOLBAR) - play_img_2 = gtk.Image() + play_img_2 = Gtk.Image() play_img_2.set_from_icon_name('media-playback-start', - gtk.ICON_SIZE_LARGE_TOOLBAR) - pause_img_2 = gtk.Image() + Gtk.IconSize.LARGE_TOOLBAR) + pause_img_2 = Gtk.Image() pause_img_2.set_from_icon_name('media-playback-pause', - gtk.ICON_SIZE_LARGE_TOOLBAR) + Gtk.IconSize.LARGE_TOOLBAR) paly_1 = ToggleToolButton('media-playback-start-back') play_2 = ToggleToolButton('media-playback-start') @@ -139,13 +149,13 @@ class MontageToolbar(gtk.Toolbar): (paly_1, play_2), (play_img_1, pause_img_1), self.montage.playbackwards) self.insert(paly_1, -1) - paly_1.set_tooltip(_('Play backward / Pause')) + paly_1.set_tooltip_text(_('Play backward / Pause')) play_2.connect('toggled', self._play_cb, (play_2, paly_1), (play_img_2, pause_img_2), self.montage.playforwards) self.insert(play_2, -1) - play_2.set_tooltip(_('Play forward / Pause')) + play_2.set_tooltip_text(_('Play forward / Pause')) # tempo button @@ -153,18 +163,18 @@ class MontageToolbar(gtk.Toolbar): tempo.adjustment.connect("value-changed", self._tempo_cb) tempo.set_size_request(200, -1) tempo.set_value(50) - tempo_item = gtk.ToolItem() + tempo_item = Gtk.ToolItem() tempo_item.add(tempo) self.insert(tempo_item, -1) - separator = gtk.SeparatorToolItem() + separator = Gtk.SeparatorToolItem() self.insert(separator,-1) # export buttons exportframe = ToolButton('image') exportframe.connect('clicked', self._exportframe_cb) - exportframe.set_tooltip(_('Snapshot')) + exportframe.set_tooltip_text(_('Snapshot')) self.insert(exportframe, -1) self.show_all() @@ -182,7 +192,7 @@ class MontageToolbar(gtk.Toolbar): self.montage.reset() def _tempo_cb(self, widget): - self.montage.setplayspeed(widget.value) + self.montage.setplayspeed(widget.get_value()) def _play_cb(self, widget, buttons, images, play): if widget.get_active(): @@ -195,13 +205,13 @@ class MontageToolbar(gtk.Toolbar): widget.set_icon_widget(images[0]) self.montage.stop() -class LessonsToolbar(gtk.Toolbar): +class LessonsToolbar(Gtk.Toolbar): def __init__(self): - gtk.Toolbar.__init__(self) + Gtk.Toolbar.__init__(self) self._mask = False for lesson in lessons.THEMES: - button = gtk.ToggleToolButton() + button = Gtk.ToggleToolButton() button.set_label(lesson.name) button.connect('clicked', self._lessons_cb, lesson) self.insert(button, -1) diff --git a/lessons.py b/lessons.py index 82ee0f4..c317409 100644 --- a/lessons.py +++ b/lessons.py @@ -13,12 +13,14 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA import os -import gtk +import gi +from gi.repository import Gtk +from gi.repository import Gdk import locale import logging from glob import glob -from sugar.activity.activity import get_bundle_path +from sugar3.activity.activity import get_bundle_path import theme @@ -36,37 +38,37 @@ class Lesson: def change(self): View.notebook.set_current_page(self.index) -class View(gtk.EventBox): +class View(Gtk.EventBox): notebook = None def __init__(self): - gtk.EventBox.__init__(self) + Gtk.EventBox.__init__(self) - View.notebook = gtk.Notebook() + View.notebook = Gtk.Notebook() View.notebook.props.show_border = False View.notebook.props.show_tabs = False self.add(View.notebook) for i in THEMES: - view = gtk.TextView() + view = Gtk.TextView() view.get_buffer().set_text(i.text) - view.set_wrap_mode(gtk.WRAP_WORD) + view.set_wrap_mode(Gtk.WrapMode.WORD) view.set_editable(False) - view_box = gtk.EventBox() + view_box = Gtk.EventBox() view_box.add(view) - view_box.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(theme.WHITE)) + view_box.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse(theme.WHITE)) view_box.props.border_width = 10 - border_box = gtk.EventBox() + border_box = Gtk.EventBox() border_box.add(view_box) - border_box.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(theme.WHITE)) + border_box.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse(theme.WHITE)) - scrolled_window = gtk.ScrolledWindow() - scrolled_window.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC) + scrolled_window = Gtk.ScrolledWindow() + scrolled_window.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) scrolled_window.add_with_viewport(border_box) - View.notebook.append_page(scrolled_window) + View.notebook.append_page(scrolled_window, Gtk.Label('')) self.show_all() diff --git a/messenger.py b/messenger.py index 25ffc71..ecef8c7 100644 --- a/messenger.py +++ b/messenger.py @@ -24,7 +24,7 @@ try: except (ImportError, AttributeError): import simplejson as json -from sugar.presence import presenceservice +from sugar3.presence import presenceservice import model diff --git a/montage.py b/montage.py index 4664bb2..1295a3c 100644 --- a/montage.py +++ b/montage.py @@ -18,14 +18,15 @@ ### (c) 2007 World Wide Workshop Foundation import os -import gtk +import gi +from gi.repository import Gtk +from gi.repository import Gdk +from gi.repository import GObject import math -import gobject import logging -from gobject import SIGNAL_RUN_FIRST, TYPE_PYOBJECT from gettext import gettext as _ -from sugar.activity.activity import get_bundle_path +from sugar3.activity.activity import get_bundle_path import model import screenflip @@ -36,9 +37,10 @@ from theme import * logger = logging.getLogger('flipsticks') -class View(gtk.EventBox): +class View(Gtk.EventBox): __gsignals__ = { - 'frame-changed': (SIGNAL_RUN_FIRST, None, [TYPE_PYOBJECT])} + 'frame-changed': (GObject.SIGNAL_RUN_FIRST, + GObject.TYPE_NONE, [GObject.TYPE_PYOBJECT])} def set_keyframe(self, value): i, key = value @@ -49,7 +51,7 @@ class View(gtk.EventBox): model.keys[i] = key self.restore() - keyframe = gobject.property(type=object, getter=None, setter=set_keyframe) + keyframe = GObject.property(type=object, getter=None, setter=set_keyframe) def reset(self): self.key.reset() @@ -69,12 +71,12 @@ class View(gtk.EventBox): def setplayspeed(self, value): self.waittime = int((100 - value) * 5) if self.playing: - gobject.source_remove(self.playing) - self.playing = gobject.timeout_add(self.waittime, self.playframe) + GObject.source_remove(self.playing) + self.playing = GObject.timeout_add(self.waittime, self.playframe) def playbackwards(self): if self.playing: - gobject.source_remove(self.playing) + GObject.source_remove(self.playing) self.frames = kinematic.makeframes() fsecs = self.frames.keys() @@ -86,11 +88,11 @@ class View(gtk.EventBox): self.playingbackwards = True logger.debug('playbackwards speed=%s' % self.waittime) - self.playing = gobject.timeout_add(self.waittime, self.playframe) + self.playing = GObject.timeout_add(self.waittime, self.playframe) def playforwards(self): if self.playing: - gobject.source_remove(self.playing) + GObject.source_remove(self.playing) self.frames = kinematic.makeframes() fsecs = self.frames.keys() @@ -102,13 +104,13 @@ class View(gtk.EventBox): logger.debug('playforwards speed=%s' % self.waittime) self.playingbackwards = False - self.playing = gobject.timeout_add(self.waittime, self.playframe) + self.playing = GObject.timeout_add(self.waittime, self.playframe) def stop(self): if not self.playing: return - gobject.source_remove(self.playing) + GObject.source_remove(self.playing) self.playing = None # set the main window to the keyframe @@ -118,38 +120,49 @@ class View(gtk.EventBox): self.updateentrybox() def exportframe(self): + self.frames = kinematic.makeframes() fsecs = self.frames.keys() firstpixindex = fsecs[0] - x, y, width, height = self.mfdraw.get_allocation() - pixmap = gtk.gdk.Pixmap(self.mfdraw.window, width, height) - self._draw_frame(fsecs[0], pixmap) - pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, width, height) - gtk.gdk.Pixbuf.get_from_drawable(pixbuf, pixmap, pixmap.get_colormap(), 0, 0, 0, 0, width, height) + rect = self.mfdraw.get_allocation() + # FIXME: There is no longer Pixmap + #pixmap = Gdk.Pixmap(self.mfdraw.window, rect.width, rect.height) + #self._draw_frame(fsecs[0], pixmap) + #pixbuf = Gdk.Pixbuf(Gdk.RGBA, False, 8, rect.width, rect.height) + #Gdk.Pixbuf.get_from_drawable(pixbuf, pixmap, pixmap.get_colormap(), + #0, 0, 0, 0, rect.width, rect.height) - model.screen_shot(pixbuf) + #model.screen_shot(pixbuf) def restore(self): self.drawkeyframe() self.syncmaintokf() self.updateentrybox() - def expose_event(self, widget, event): - x, y, width, height = event.area - widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL], - self.pixmap, x, y, x, y, width, height) + def expose_event(self, widget, context): + + rect = widget.get_allocation() + # FIXME: AttributeError: 'X11Window' object has no attribute 'draw_drawable' + #widget.get_property('window').draw_drawable(widget.get_style().fg_gc[Gtk.StateType.NORMAL], + # self.pixmap, rect.x, rect.y, + # rect.x, rect.y, rect.width, rect.height) return False - def kf_expose_event(self, widget, event): - x, y, width, height = event.area - widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL], - self.kfpixmap, x, y, x, y, width, height) + def kf_expose_event(self, widget, context): + + rect = widget.get_allocation() + # FIXME: AttributeError: 'X11Window' object has no attribute 'draw_drawable' + #widget.window.draw_drawable(widget.get_style().fg_gc[Gtk.StateType.NORMAL], + # self.kfpixmap, rect.x, rect.y, + # rect.x, rect.y, rect.width, rect.height) return False def configure_event(self, widget, event): - x, y, width, height = self.mfdraw.get_allocation() - self.pixmap = gtk.gdk.Pixmap(self.mfdraw.window, width, height) + + rect = self.mfdraw.get_allocation() + # FIXME: AttributeError: 'gi.repository.Gdk' object has no attribute 'Pixmap' + #self.pixmap = Gdk.Pixmap(self.mfdraw.window, rect.width, rect.height) self.drawmainframe() return True @@ -158,13 +171,18 @@ class View(gtk.EventBox): return True def motion_notify_event(self, widget, event): + if event.is_hint: - x, y, state = event.window.get_pointer() + # FIXME: ValueError: too many values to unpack + #x, y, state = event.window.get_pointer() + state = False + else: x = event.x y = event.y state = event.state - if state & gtk.gdk.BUTTON1_MASK and self.pixmap != None: + + if state & Gdk.EventMask.BUTTON1_MOTION_MASK and self.pixmap != None: if self.jointpressed: if _inarea(widget, x, y): #self.key.joints[self.jointpressed] = (x,y) # old hack way @@ -238,13 +256,18 @@ class View(gtk.EventBox): return True def kf_motion_notify_event(self, widget, event): + if event.is_hint: - x, y, state = event.window.get_pointer() + # FIXME: ValueError: too many values to unpack + # x, y, state = event.window.get_pointer() + state = False + else: x = event.x y = event.y state = event.state - if state & gtk.gdk.BUTTON1_MASK and self.pixmap != None: + + if state & Gdk.EventMask.BUTTON1_MOTION_MASK and self.pixmap != None: if self.kfpressed >= 0: if _inarea(widget, x, y): xdiff = int(x - self.kf_mouse_pos) @@ -254,12 +277,12 @@ class View(gtk.EventBox): frame.move(xdiff) if self._emit_move_handle: - gobject.source_remove(self._emit_move_handle) + GObject.source_remove(self._emit_move_handle) if self._emit_move_key != self.kfpressed: self._emit_move(self._emit_move_key) self._emit_move_key = self.kfpressed - self._emit_move_handle = gobject.timeout_add( + self._emit_move_handle = GObject.timeout_add( MOVEMIT_TIMEOUT, self._emit_move, self.kfpressed) @@ -391,7 +414,9 @@ class View(gtk.EventBox): def drawmainframe(self): if not self.pixmap: return - + # FIXME: AttributeError: 'flipsticksActivity' object has no attribute 'window' + #area = self.get_root_window()#self.toplevel.window + ''' area = self.toplevel.window drawgc = area.new_gc() drawgc.line_width = 3 @@ -402,9 +427,9 @@ class View(gtk.EventBox): black = cm.alloc_color('black') blue = cm.alloc_color('blue') green = cm.alloc_color('green') - drawgc.fill = gtk.gdk.SOLID + drawgc.fill = Gdk.SOLID x, y, width, height = self.mfdraw.get_allocation() - #self.pixmap = gtk.gdk.Pixmap(self.mfdraw.window, width, height) + #self.pixmap = Gdk.Pixmap(self.mfdraw.window, width, height) # clear area drawgc.set_foreground(white) self.pixmap.draw_rectangle(drawgc, True, 0, 0, width, height) @@ -440,7 +465,8 @@ class View(gtk.EventBox): drawgc.set_foreground(red) self.pixmap.draw_arc(drawgc, True, x - 5, y - 5, 10, 10, 0, 360 * 64) drawgc.set_foreground(black) - self.mfdraw.queue_draw() + self.mfdraw.queue_draw()''' + pass def drawstickman(self, drawgc, pixmap, middle, joints, hsize, rhsize, lhsize): leftarm = [middle, joints['leftshoulder'], joints['leftelbow'], joints['lefthand']] @@ -466,7 +492,10 @@ class View(gtk.EventBox): pixmap.draw_arc(drawgc, True, x - int(lhsize / 2.0), y - int(lhsize / 2.0), lhsize, lhsize, 0, 360 * 64) def drawkeyframe(self): - area = self.toplevel.window + + # FIXME: AttributeError: 'flipsticksActivity' object has no attribute 'window' + #area = self.get_root_window()#self.toplevel.window + ''' drawgc = area.new_gc() drawgc.line_width = 2 cm = drawgc.get_colormap() @@ -478,9 +507,9 @@ class View(gtk.EventBox): pink = cm.alloc_color(PINK) bgcolor = cm.alloc_color(BACKGROUND) darkgreen = cm.alloc_color(BUTTON_BACKGROUND) - drawgc.fill = gtk.gdk.SOLID + drawgc.fill = Gdk.SOLID x, y, width, height = self.kfdraw.get_allocation() - self.kfpixmap = gtk.gdk.Pixmap(self.kfdraw.window, width, height) + self.kfpixmap = Gdk.Pixmap(self.kfdraw.window, width, height) # clear area drawgc.set_foreground(bgcolor) self.kfpixmap.draw_rectangle(drawgc, True, 0, 0, width, height) @@ -517,10 +546,13 @@ class View(gtk.EventBox): lhsize = int(model.keys[i].parts['LEFT HAND'] * 0.2) self.drawstickman(drawgc, self.kfpixmap, (x, y), model.keys[i].scaled_joints, hsize, rhsize, lhsize) #self.kfpixmap.draw_arc(drawgc,True,x-5,y-5,10,10,0,360*64) - self.kfdraw.queue_draw() + self.kfdraw.queue_draw()''' + pass def drawfp(self): - area = self.toplevel.window + # FIXME: AttributeError: 'flipsticksActivity' object has no attribute 'window' + #area = self.get_root_window()#self.toplevel.window + ''' drawgc = area.new_gc() drawgc.line_width = 1 cm = drawgc.get_colormap() @@ -532,29 +564,30 @@ class View(gtk.EventBox): pink = cm.alloc_color(PINK) bgcolor = cm.alloc_color(BACKGROUND) darkgreen = cm.alloc_color(BUTTON_BACKGROUND) - drawgc.fill = gtk.gdk.SOLID + drawgc.fill = Gdk.SOLID x, y, width, height = self.fpdraw.get_allocation() - self.fppixmap = gtk.gdk.Pixmap(self.fpdraw.window, width, height) + self.fppixmap = Gdk.Pixmap(self.fpdraw.window, width, height) # clear area drawgc.set_foreground(white) self.fppixmap.draw_rectangle(drawgc, True, 0, 0, width, height) - self.fpdraw.queue_draw() + self.fpdraw.queue_draw()''' + pass def selectstick(self, widget, event, data=None): if data: if self.stickselected: ebox = self.stickbuttons[self.stickselected] - ebox.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(BUTTON_BACKGROUND)) + ebox.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse(BUTTON_BACKGROUND)) label = ebox.get_child() - label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(BUTTON_FOREGROUND)) + label.modify_fg(Gtk.StateType.NORMAL, Gdk.color_parse(BUTTON_FOREGROUND)) self.stickselected = data self.selectstickebox() def selectstickebox(self): ebox = self.stickbuttons[self.stickselected] - ebox.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(BUTTON_FOREGROUND)) + ebox.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse(BUTTON_FOREGROUND)) label = ebox.get_child() - label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(BUTTON_BACKGROUND)) + label.modify_fg(Gtk.StateType.NORMAL, Gdk.color_parse(BUTTON_BACKGROUND)) if self.stickselected in self.key.sticks: size = self.key.sticks[self.stickselected][1] @@ -576,7 +609,7 @@ class View(gtk.EventBox): self.size_adj.set_value(size) def __init__(self, activity): - gtk.EventBox.__init__(self) + Gtk.EventBox.__init__(self) self.playing = False self.playingbackwards = False @@ -602,165 +635,169 @@ class View(gtk.EventBox): # screen - self.mfdraw = gtk.DrawingArea() - self.mfdraw.connect('expose_event', self.expose_event) + self.mfdraw = Gtk.DrawingArea() + self.mfdraw.connect('draw', self.expose_event) self.mfdraw.connect('configure_event', self.configure_event) self.mfdraw.connect('motion_notify_event', self.motion_notify_event) self.mfdraw.connect('button_press_event', self.button_press_event) self.mfdraw.connect('button_release_event', self.button_release_event) - self.mfdraw.set_events(gtk.gdk.EXPOSURE_MASK - | gtk.gdk.LEAVE_NOTIFY_MASK - | gtk.gdk.BUTTON_PRESS_MASK - | gtk.gdk.BUTTON_RELEASE_MASK - | gtk.gdk.POINTER_MOTION_MASK - | gtk.gdk.POINTER_MOTION_HINT_MASK) + self.mfdraw.set_events(Gdk.EventMask.EXPOSURE_MASK + | Gdk.EventMask.LEAVE_NOTIFY_MASK + | Gdk.EventMask.BUTTON_PRESS_MASK + | Gdk.EventMask.BUTTON_RELEASE_MASK + | Gdk.EventMask.POINTER_MOTION_MASK + | Gdk.EventMask.POINTER_MOTION_HINT_MASK) self.mfdraw.set_size_request(DRAWWIDTH, DRAWHEIGHT) - screen_box = gtk.EventBox() - screen_box.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(BACKGROUND)) + screen_box = Gtk.EventBox() + screen_box.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse(BACKGROUND)) screen_box.set_border_width(PAD / 2) screen_box.add(self.mfdraw) - screen_pink = gtk.EventBox() - screen_pink.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(PINK)) + screen_pink = Gtk.EventBox() + screen_pink.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse(PINK)) screen_pink.set_border_width(PAD) screen_pink.add(screen_box) # keyframes - self.kfdraw = gtk.DrawingArea() + self.kfdraw = Gtk.DrawingArea() self.kfdraw.set_size_request(KEYFRAMEWIDTH, KEYFRAMEHEIGHT) - self.kfdraw.connect('expose_event', self.kf_expose_event) + self.kfdraw.connect('draw', self.kf_expose_event) self.kfdraw.connect('configure_event', self.kf_configure_event) self.kfdraw.connect('motion_notify_event', self.kf_motion_notify_event) self.kfdraw.connect('button_press_event', self.kf_button_press_event) self.kfdraw.connect('button_release_event', self.kf_button_release_event) - self.kfdraw.set_events(gtk.gdk.EXPOSURE_MASK - | gtk.gdk.LEAVE_NOTIFY_MASK - | gtk.gdk.BUTTON_PRESS_MASK - | gtk.gdk.BUTTON_RELEASE_MASK - | gtk.gdk.POINTER_MOTION_MASK - | gtk.gdk.POINTER_MOTION_HINT_MASK) - - kfdraw_box = gtk.EventBox() + self.kfdraw.set_events(Gdk.EventMask.EXPOSURE_MASK + | Gdk.EventMask.LEAVE_NOTIFY_MASK + | Gdk.EventMask.BUTTON_PRESS_MASK + | Gdk.EventMask.BUTTON_RELEASE_MASK + | Gdk.EventMask.POINTER_MOTION_MASK + | Gdk.EventMask.POINTER_MOTION_HINT_MASK) + + kfdraw_box = Gtk.EventBox() kfdraw_box.set_border_width(PAD) kfdraw_box.add(self.kfdraw) # control box - angle_box = gtk.HBox() - anglelabel = gtk.Label(_('Angle:')) - anglelabel.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(BUTTON_BACKGROUND)) + angle_box = Gtk.HBox() + anglelabel = Gtk.Label(_('Angle:')) + anglelabel.modify_fg(Gtk.StateType.NORMAL, Gdk.color_parse(BUTTON_BACKGROUND)) anglelabel.set_size_request(60, -1) angle_box.pack_start(anglelabel, False, False, 5) - self.angleentry = gtk.Entry() + self.angleentry = Gtk.Entry() self.angleentry.set_max_length(3) self.angleentry.set_width_chars(3) self.angleentry.connect('activate', self.enterangle_callback, self.angleentry) - self.angleentry.modify_bg(gtk.STATE_INSENSITIVE, - gtk.gdk.color_parse(BUTTON_FOREGROUND)) + self.angleentry.modify_bg(Gtk.StateType.INSENSITIVE, + Gdk.color_parse(BUTTON_FOREGROUND)) angle_box.pack_start(self.angleentry, False, False, 0) - self.anglel_adj = gtk.Adjustment(0, 0, 360, 1, 60, 0) + self.anglel_adj = Gtk.Adjustment(0, 0, 360, 1, 60, 0) self.anglel_adj.connect('value_changed', self._anglel_adj_cb) - self.anglel_slider = gtk.HScale(self.anglel_adj) + self.anglel_slider = Gtk.HScale() + self.anglel_slider.set_adjustment(self.anglel_adj) self.anglel_slider.set_draw_value(False) for state, color in COLOR_BG_BUTTONS: - self.anglel_slider.modify_bg(state, gtk.gdk.color_parse(color)) - angle_box.pack_start(self.anglel_slider) + self.anglel_slider.modify_bg(state, Gdk.color_parse(color)) + angle_box.pack_start(self.anglel_slider, False, False, 0) - size_box = gtk.HBox() - sizelabel = gtk.Label(_('Size:')) - sizelabel.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(BUTTON_BACKGROUND)) + size_box = Gtk.HBox() + sizelabel = Gtk.Label(_('Size:')) + sizelabel.modify_fg(Gtk.StateType.NORMAL, Gdk.color_parse(BUTTON_BACKGROUND)) sizelabel.set_size_request(60, -1) size_box.pack_start(sizelabel, False, False, 5) - self.sizeentry = gtk.Entry() + self.sizeentry = Gtk.Entry() self.sizeentry.set_max_length(3) self.sizeentry.set_width_chars(3) self.sizeentry.connect('activate', self.enterlen_callback, self.sizeentry) - self.sizeentry.modify_bg(gtk.STATE_INSENSITIVE, - gtk.gdk.color_parse(BUTTON_FOREGROUND)) + self.sizeentry.modify_bg(Gtk.StateType.INSENSITIVE, + Gdk.color_parse(BUTTON_FOREGROUND)) size_box.pack_start(self.sizeentry, False, False, 0) - self.size_adj = gtk.Adjustment(0, 0, 200, 1, 30, 0) + self.size_adj = Gtk.Adjustment(0, 0, 200, 1, 30, 0) self.size_adj.connect('value_changed', self._size_adj_cb) - size_slider = gtk.HScale(self.size_adj) + size_slider = Gtk.HScale() + size_slider.set_adjustment(self.size_adj) size_slider.set_draw_value(False) for state, color in COLOR_BG_BUTTONS: - size_slider.modify_bg(state, gtk.gdk.color_parse(color)) - size_box.pack_start(size_slider) + size_slider.modify_bg(state, Gdk.color_parse(color)) + size_box.pack_start(size_slider, False, False, 0) - control_head_box = gtk.VBox() - control_head_box.pack_start(angle_box) - control_head_box.pack_start(size_box) + control_head_box = Gtk.VBox() + control_head_box.pack_start(angle_box, False, False, 0) + control_head_box.pack_start(size_box, False, False, 0) - control_head = gtk.EventBox() - control_head.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(BUTTON_FOREGROUND)) + control_head = Gtk.EventBox() + control_head.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse(BUTTON_FOREGROUND)) control_head.add(control_head_box) - control_options = gtk.VBox() + control_options = Gtk.VBox() self.stickbuttons = {} self.sticklabels = {} for stickpartname in LABELLIST: - label = gtk.Label(STRINGS[stickpartname]) - label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.color_parse(BUTTON_FOREGROUND)) + label = Gtk.Label(STRINGS[stickpartname]) + label.modify_fg(Gtk.StateType.NORMAL, Gdk.color_parse(BUTTON_FOREGROUND)) self.sticklabels[stickpartname] = label - ebox = gtk.EventBox() - ebox.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(BUTTON_BACKGROUND)) - ebox.set_events(gtk.gdk.BUTTON_PRESS_MASK) + ebox = Gtk.EventBox() + ebox.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse(BUTTON_BACKGROUND)) + ebox.set_events(Gdk.EventMask.BUTTON_PRESS_MASK) ebox.connect('button_press_event', self.selectstick, stickpartname) ebox.add(label) self.stickbuttons[stickpartname] = ebox control_options.pack_start(ebox, False, False, 0) self.selectstickebox() - control_scroll = gtk.ScrolledWindow() - control_scroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC) + control_scroll = Gtk.ScrolledWindow() + control_scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) control_scroll.add_with_viewport(control_options) - control_options.get_parent().modify_bg(gtk.STATE_NORMAL, - gtk.gdk.color_parse(BUTTON_BACKGROUND)) + control_options.get_parent().modify_bg(Gtk.StateType.NORMAL, + Gdk.color_parse(BUTTON_BACKGROUND)) - control_box = gtk.VBox() + control_box = Gtk.VBox() control_box.pack_start(control_head, False, False, 0) - control_box.pack_start(control_scroll) + control_box.pack_start(control_scroll, False, False, 0) - control_bg = gtk.EventBox() - control_bg.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(BUTTON_BACKGROUND)) + control_bg = Gtk.EventBox() + control_bg.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse(BUTTON_BACKGROUND)) control_bg.set_border_width(PAD / 2) control_bg.add(control_box) - control_pink = gtk.EventBox() - control_pink.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(PINK)) + control_pink = Gtk.EventBox() + control_pink.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse(PINK)) control_pink.set_border_width(PAD) control_pink.add(control_bg) # left control box - logo = gtk.Image() + logo = Gtk.Image() logo.set_from_file(os.path.join(self.iconsdir, 'logo.png')) - leftbox = gtk.VBox() - leftbox.pack_start(logo, False, False) - leftbox.pack_start(control_pink) + leftbox = Gtk.VBox() + leftbox.pack_start(logo, False, False, 0) + leftbox.pack_start(control_pink, False, False, 0) # desktop - hdesktop = gtk.HBox() - hdesktop.pack_start(leftbox, False) - hdesktop.pack_start(screen_pink, False, False) + hdesktop = Gtk.HBox() + hdesktop.pack_start(leftbox, False, False, 0) + hdesktop.pack_start(screen_pink, False, False, 0) - desktop = gtk.VBox() - desktop.pack_start(hdesktop) + desktop = Gtk.VBox() + desktop.pack_start(hdesktop, False, False, 0) desktop.pack_start(kfdraw_box, False, False, 0) - greenbox = gtk.EventBox() - greenbox.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(BACKGROUND)) + greenbox = Gtk.EventBox() + greenbox.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse(BACKGROUND)) greenbox.set_border_width(PAD / 2) greenbox.add(desktop) - self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(YELLOW)) + self.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse(YELLOW)) self.add(greenbox) self.show_all() def _draw_frame(self, index, pixmap): + # FIXME: AttributeError: 'X11Window' object has no attribute 'new_gc' + ''' joints = self.frames[index].joints parts = self.frames[index].parts # draw on the main drawing area @@ -770,9 +807,9 @@ class View(gtk.EventBox): cm = drawgc.get_colormap() white = cm.alloc_color('white') black = cm.alloc_color('black') - drawgc.fill = gtk.gdk.SOLID + drawgc.fill = Gdk.SOLID x, y, width, height = self.mfdraw.get_allocation() - #pixmap = gtk.gdk.Pixmap(self.mfdraw.window, width, height) + #pixmap = Gdk.Pixmap(self.mfdraw.window, width, height) # clear area drawgc.set_foreground(white) pixmap.draw_rectangle(drawgc, True, 0, 0, width, height) @@ -782,7 +819,8 @@ class View(gtk.EventBox): middle = self.frames[index].middle rhsize = parts['RIGHT HAND'] lhsize = parts['LEFT HAND'] - self.drawstickman(drawgc, pixmap, middle, joints, hsize, rhsize, lhsize) + self.drawstickman(drawgc, pixmap, middle, joints, hsize, rhsize, lhsize)''' + pass def _inkeyframe(self, x, y): dy = math.pow(abs(y - KEYFRAMEHEIGHT / 2), 2) @@ -798,11 +836,11 @@ class View(gtk.EventBox): return -1 def _anglel_adj_cb(self, adj): - self.angleentry.set_text(str(int(adj.value))) + self.angleentry.set_text(str(int(adj.get_value()))) self.enterangle_callback(None, self.angleentry) def _size_adj_cb(self, adj): - self.sizeentry.set_text(str(int(adj.value))) + self.sizeentry.set_text(str(int(adj.get_value()))) self.enterlen_callback(None, self.sizeentry) def _emit_move(self, key): diff --git a/setup.py b/setup.py index 019d64e..61a2f86 100755 --- a/setup.py +++ b/setup.py @@ -16,5 +16,5 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -from sugar.activity import bundlebuilder +from sugar3.activity import bundlebuilder bundlebuilder.start() diff --git a/theme.py b/theme.py index 993c261..6d1fe86 100644 --- a/theme.py +++ b/theme.py @@ -12,10 +12,12 @@ # 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 gi +from gi.repository import Gtk +from gi.repository import GdkX11 from gettext import gettext as _ -from sugar.graphics import style +from sugar3.graphics import style GRAY = "#B7B7B7" # gray PINK = "#FF0099" # pink @@ -26,25 +28,25 @@ BACKGROUND = "#66CC00" # light green BUTTON_FOREGROUND = "#CCFB99" # very light green BUTTON_BACKGROUND = "#027F01" # dark green COLOR_FG_BUTTONS = ( - (gtk.STATE_NORMAL,"#CCFF99"), - (gtk.STATE_ACTIVE,"#CCFF99"), - (gtk.STATE_PRELIGHT,"#CCFF99"), - (gtk.STATE_SELECTED,"#CCFF99"), - (gtk.STATE_INSENSITIVE,"#CCFF99"), + (Gtk.StateType.NORMAL,"#CCFF99"), + (Gtk.StateType.ACTIVE,"#CCFF99"), + (Gtk.StateType.PRELIGHT,"#CCFF99"), + (Gtk.StateType.SELECTED,"#CCFF99"), + (Gtk.StateType.INSENSITIVE,"#CCFF99"), ) # very light green COLOR_BG_BUTTONS = ( - (gtk.STATE_NORMAL,"#027F01"), - (gtk.STATE_ACTIVE,"#CCFF99"), - (gtk.STATE_PRELIGHT,"#016D01"), - (gtk.STATE_SELECTED,"#CCFF99"), - (gtk.STATE_INSENSITIVE,"#027F01"), + (Gtk.StateType.NORMAL,"#027F01"), + (Gtk.StateType.ACTIVE,"#CCFF99"), + (Gtk.StateType.PRELIGHT,"#016D01"), + (Gtk.StateType.SELECTED,"#CCFF99"), + (Gtk.StateType.INSENSITIVE,"#027F01"), ) OLD_COLOR_BG_BUTTONS = ( - (gtk.STATE_NORMAL,"#027F01"), - (gtk.STATE_ACTIVE,"#014D01"), - (gtk.STATE_PRELIGHT,"#016D01"), - (gtk.STATE_SELECTED,"#027F01"), - (gtk.STATE_INSENSITIVE,"#027F01"), + (Gtk.StateType.NORMAL,"#027F01"), + (Gtk.StateType.ACTIVE,"#014D01"), + (Gtk.StateType.PRELIGHT,"#016D01"), + (Gtk.StateType.SELECTED,"#027F01"), + (Gtk.StateType.INSENSITIVE,"#027F01"), ) STRINGS = { 'size' : _('Size'), @@ -76,11 +78,12 @@ PAD = 10 LOGO_WIDTH = 276 TOLLBAR_HEIGHT = style.LARGE_ICON_SIZE -KEYFRAMEWIDTH = gtk.gdk.screen_width() - PAD*3 +screen = GdkX11.X11Screen() +KEYFRAMEWIDTH = int(screen.width()) - PAD*3 KEYFRAMEHEIGHT = 80 -DRAWWIDTH = gtk.gdk.screen_width() - LOGO_WIDTH - PAD*4 -DRAWHEIGHT = gtk.gdk.screen_height() - KEYFRAMEHEIGHT - PAD*6 - TOLLBAR_HEIGHT +DRAWWIDTH = int(screen.width()) - LOGO_WIDTH - PAD*4 +DRAWHEIGHT = int(screen.height()) - KEYFRAMEHEIGHT - PAD*6 - TOLLBAR_HEIGHT KEYFRAMES = [] KEYFRAMES_NUMBER = 5 diff --git a/toolkit/activity.py b/toolkit/activity.py index 1512610..29c848a 100644 --- a/toolkit/activity.py +++ b/toolkit/activity.py @@ -16,14 +16,15 @@ """Extend sugar-toolkit activity class""" -import gtk import logging import telepathy -import gobject +import gi +from gi.repository import Gtk +from gi.repository import Gdk -from sugar.activity import activity -from sugar.presence.sugartubeconn import SugarTubeConnection -from sugar.graphics.alert import ConfirmationAlert, NotifyAlert +from sugar3.activity import activity +from sugar3.presence.sugartubeconn import SugarTubeConnection +from sugar3.graphics.alert import ConfirmationAlert, NotifyAlert _NEW_INSTANCE = 0 @@ -40,9 +41,11 @@ class CursorFactory: self.__dict__ = self.__shared_state def get_cursor(self, cur_type): + if not self.cursors.has_key(cur_type): - cur = gtk.gdk.Cursor(cur_type) + cur = Gdk.Cursor(cur_type) self.cursors[cur_type] = cur + return self.cursors[cur_type] @@ -76,7 +79,7 @@ class Activity(activity.Activity): Subclass should implement this method to save activity data. """ raise NotImplementedError - + def on_save_instance(self, cb, *args): """ Register callback which will be invoked before save_instance """ self.__on_save_instance.append((cb, args)) @@ -99,22 +102,28 @@ class Activity(activity.Activity): pass def set_toolbar_box(self, toolbox): + if hasattr(activity.Activity, 'set_toolbar_box'): activity.Activity.set_toolbar_box(self, toolbox) + else: self.set_toolbox(toolbox) def get_toolbar_box(self): + if hasattr(activity.Activity, 'get_toolbar_box'): return activity.Activity.get_toolbar_box(self) + else: return self.get_toolbox() toolbar_box = property(get_toolbar_box, set_toolbar_box) def get_shared_activity(self): + if hasattr(activity.Activity, 'get_shared_activity'): return activity.Activity.get_shared_activity(self) + else: return self._shared_activity @@ -135,7 +144,7 @@ class Activity(activity.Activity): def response(alert, response_id, self, cb, *cb_args): self.remove_alert(alert) - if response_id is gtk.RESPONSE_OK: + if response_id is Gtk.ResponseType.OK: cb(*cb_args) alert.connect('response', response, self, cb, *cb_args) @@ -146,12 +155,13 @@ class Activity(activity.Activity): return self._cursor def set_cursor(self, cursor): - if not isinstance(cursor, gtk.gdk.Cursor): + + if not isinstance(cursor, Gdk.Cursor): cursor = CursorFactory().get_cursor(cursor) if self._cursor != cursor: self._cursor = cursor - self.window.set_cursor(self._cursor) + self.get_property('window').set_cursor(self._cursor) def __init__(self, canvas, handle): """ @@ -168,6 +178,7 @@ class Activity(activity.Activity): if handle.object_id: self.__state = _NEW_INSTANCE + else: self.__state = _NEW_INSTANCE @@ -176,14 +187,15 @@ class Activity(activity.Activity): self.__on_save_instance = [] self._cursor = None - self.set_cursor(gtk.gdk.LEFT_PTR) + self.set_cursor(Gdk.CursorType.LEFT_PTR) # XXX do it after(possible) read_file() invoking # have to rely on calling read_file() from map_cb in sugar-toolkit - canvas.connect_after('map', self.__map_canvasactivity_cb) + #canvas.connect_after('map', self.__map_canvasactivity_cb) self.set_canvas(canvas) - + def __instance(self): + logging.debug('Activity.__instance') if self.__resume_filename: @@ -193,6 +205,7 @@ class Activity(activity.Activity): for i in self.__postponed_share: self.share_instance(*i) + self.__postponed_share = [] self.__state = _POST_INSTANCE @@ -205,6 +218,7 @@ class Activity(activity.Activity): if self.__state == _NEW_INSTANCE: self.__state = _PRE_INSTANCE + elif self.__state == _PRE_INSTANCE: self.__instance(); @@ -212,30 +226,37 @@ class Activity(activity.Activity): """Subclass should not override this method""" for cb, args in self.__on_save_instance: cb(*args) + self.save_instance(filepath) def __map_canvasactivity_cb(self, widget): + logging.debug('Activity.__map_canvasactivity_cb state=%s' % \ self.__state) if self.__state == _NEW_INSTANCE: self.__instance() + elif self.__state == _NEW_INSTANCE: self.__state = _PRE_INSTANCE + elif self.__state == _PRE_INSTANCE: self.__instance(); return False def _share(self, tube_conn, initiator): + logging.debug('Activity._share state=%s' % self.__state) if self.__state == _NEW_INSTANCE: self.__postponed_share.append((tube_conn, initiator)) self.__state = _PRE_INSTANCE + elif self.__state == _PRE_INSTANCE: self.__postponed_share.append((tube_conn, initiator)) - self.__instance(); + self.__instance() + elif self.__state == _POST_INSTANCE: self.share_instance(tube_conn, initiator) @@ -265,14 +286,16 @@ class SharedActivity(Activity): self.connect('shared', self._shared_cb) # Owner.props.key - if self._shared_activity: + if self.shared_activity: # We are joining the activity self.connect('joined', self._joined_cb) + if self.get_shared(): # We've already joined self._joined_cb() def _shared_cb(self, activity): + logging.debug('My activity was shared') self.__initiator = True self._sharing_setup() @@ -282,7 +305,8 @@ class SharedActivity(Activity): self.service, {}) def _joined_cb(self, activity): - if not self._shared_activity: + + if not self.shared_activity: return logging.debug('Joined an existing shared activity') @@ -296,17 +320,20 @@ class SharedActivity(Activity): error_handler=self._list_tubes_error_cb) def _sharing_setup(self): - if self._shared_activity is None: + + if self.shared_activity is None: logging.error('Failed to share or join activity') return - self._conn = self._shared_activity.telepathy_conn - self._tubes_chan = self._shared_activity.telepathy_tubes_chan - self._text_chan = self._shared_activity.telepathy_text_chan + + self._conn = self.shared_activity.telepathy_conn + self._tubes_chan = self.shared_activity.telepathy_tubes_chan + self._text_chan = self.shared_activity.telepathy_text_chan self._tubes_chan[telepathy.CHANNEL_TYPE_TUBES].connect_to_signal( - 'NewTube', self._new_tube_cb) + 'NewTube', self._new_tube_cb) def _list_tubes_reply_cb(self, tubes): + for tube_info in tubes: self._new_tube_cb(*tube_info) @@ -314,15 +341,17 @@ class SharedActivity(Activity): logging.error('ListTubes() failed: %s', e) def _new_tube_cb(self, id, initiator, type, service, params, state): + logging.debug('New tube: ID=%d initator=%d type=%d service=%s ' - 'params=%r state=%d', id, initiator, type, service, - params, state) + 'params=%r state=%d', id, initiator, type, service, + params, state) if (type == telepathy.TUBE_TYPE_DBUS and - service == self.service): + service == self.service): + if state == telepathy.TUBE_STATE_LOCAL_PENDING: self._tubes_chan[telepathy.CHANNEL_TYPE_TUBES] \ - .AcceptDBusTube(id) + .AcceptDBusTube(id) tube_conn = SugarTubeConnection(self._conn, self._tubes_chan[telepathy.CHANNEL_TYPE_TUBES], id, diff --git a/toolkit/activity_widgets.py b/toolkit/activity_widgets.py index 9195af5..e58f368 100644 --- a/toolkit/activity_widgets.py +++ b/toolkit/activity_widgets.py @@ -15,33 +15,40 @@ # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. -import gtk -import gobject +import gi +from gi.repository import Gtk +from gi.repository import Gdk +from gi.repository import GObject +from gi.repository import GdkX11 import gettext -from sugar import profile -from sugar.graphics.toolbutton import ToolButton -from sugar.graphics.radiotoolbutton import RadioToolButton -from sugar.graphics.toolbox import Toolbox -from sugar.graphics.xocolor import XoColor -from sugar.graphics.icon import Icon -from sugar.bundle.activitybundle import ActivityBundle +from sugar3 import profile +from sugar3.graphics.toolbutton import ToolButton +from sugar3.graphics.radiotoolbutton import RadioToolButton +from sugar3.graphics.toolbox import Toolbox +from sugar3.graphics.xocolor import XoColor +from sugar3.graphics.icon import Icon +from sugar3.bundle.activitybundle import ActivityBundle -from toolkit.toolbarbox import ToolbarButton -from toolkit.radiopalette import RadioPalette -from toolkit.radiopalette import RadioMenuButton -from sugar.graphics import style +from toolbarbox import ToolbarButton +from radiopalette import RadioPalette +from radiopalette import RadioMenuButton -_ = lambda msg: gettext.dgettext('sugar-toolkit', msg) +from sugar3.graphics import style +_ = lambda msg: gettext.dgettext('sugar3-toolkit', msg) + +# FIXME: This module is not being used. def _create_activity_icon(metadata): + if metadata.get('icon-color', ''): color = XoColor(metadata['icon-color']) + else: color = profile.get_color() - from sugar.activity.activity import get_bundle_path + from sugar3.activity.activity import get_bundle_path bundle = ActivityBundle(get_bundle_path()) icon = Icon(file=bundle.get_icon(), xo_color=color) @@ -50,8 +57,9 @@ def _create_activity_icon(metadata): class ActivityButton(ToolButton): - def __init__(self, activity, **kwargs): - ToolButton.__init__(self, **kwargs) + def __init__(self, activity): + + ToolButton.__init__(self) icon = _create_activity_icon(activity.metadata) self.set_icon_widget(icon) @@ -66,7 +74,8 @@ class ActivityButton(ToolButton): class ActivityToolbarButton(ToolbarButton): - def __init__(self, activity, **kwargs): + def __init__(self, activity): + toolbar = ActivityToolbar(activity, orientation_left=True) toolbar.stop.hide() @@ -79,7 +88,8 @@ class ActivityToolbarButton(ToolbarButton): class StopButton(ToolButton): - def __init__(self, activity, **kwargs): + def __init__(self, activity): + ToolButton.__init__(self, 'activity-stop', **kwargs) self.props.tooltip = _('Stop') self.props.accelerator = 'Q' @@ -91,36 +101,41 @@ class StopButton(ToolButton): class UndoButton(ToolButton): - def __init__(self, **kwargs): - ToolButton.__init__(self, 'edit-undo', **kwargs) + def __init__(self): + + ToolButton.__init__(self, 'edit-undo') self.props.tooltip = _('Undo') self.props.accelerator = 'Z' class RedoButton(ToolButton): - def __init__(self, **kwargs): - ToolButton.__init__(self, 'edit-redo', **kwargs) + def __init__(self): + + ToolButton.__init__(self, 'edit-redo') self.props.tooltip = _('Redo') class CopyButton(ToolButton): - def __init__(self, **kwargs): - ToolButton.__init__(self, 'edit-copy', **kwargs) + def __init__(self): + + ToolButton.__init__(self, 'edit-copy') self.props.tooltip = _('Copy') class PasteButton(ToolButton): - def __init__(self, **kwargs): - ToolButton.__init__(self, 'edit-paste', **kwargs) + def __init__(self): + + ToolButton.__init__(self, 'edit-paste') self.props.tooltip = _('Paste') class ShareButton(RadioMenuButton): - def __init__(self, activity, **kwargs): + def __init__(self, activity): + palette = RadioPalette() self.private = RadioToolButton( @@ -137,7 +152,7 @@ class ShareButton(RadioMenuButton): activity.connect('shared', self.__update_share_cb) activity.connect('joined', self.__update_share_cb) - RadioMenuButton.__init__(self, **kwargs) + RadioMenuButton.__init__(self) self.props.palette = palette if activity.props.max_participants == 1: self.props.sensitive = False @@ -146,29 +161,35 @@ class ShareButton(RadioMenuButton): activity.share() def __update_share_cb(self, activity): + self.neighborhood.handler_block(self._neighborhood_handle) + try: if activity.get_shared(): self.private.props.sensitive = False self.neighborhood.props.sensitive = False self.neighborhood.props.active = True + else: self.private.props.sensitive = True self.neighborhood.props.sensitive = True self.private.props.active = True + finally: self.neighborhood.handler_unblock(self._neighborhood_handle) -class TitleEntry(gtk.ToolItem): +class TitleEntry(Gtk.ToolItem): - def __init__(self, activity, **kwargs): - gtk.ToolItem.__init__(self) + def __init__(self, activity): + + Gtk.ToolItem.__init__(self) self.set_expand(False) self._update_title_sid = None - self.entry = gtk.Entry(**kwargs) - self.entry.set_size_request(int(gtk.gdk.screen_width() / 3), -1) + self.entry = Gtk.Entry() + screen = GdkX11.X11Screen() + self.entry.set_size_request(int(screen.width() / 3), -1) self.entry.set_text(activity.metadata['title']) self.entry.connect('changed', self.__title_changed_cb, activity) self.entry.show() @@ -177,18 +198,21 @@ class TitleEntry(gtk.ToolItem): activity.metadata.connect('updated', self.__jobject_updated_cb) def modify_bg(self, state, color): - gtk.ToolItem.modify_bg(self, state, color) + + Gtk.ToolItem.modify_bg(self, state, color) self.entry.modify_bg(state, color) def __jobject_updated_cb(self, jobject): self.entry.set_text(jobject['title']) def __title_changed_cb(self, entry, activity): + if not self._update_title_sid: - self._update_title_sid = gobject.timeout_add_seconds( - 1, self.__update_title_cb, activity) + self._update_title_sid = GObject.timeout_add_seconds( + 1, self.__update_title_cb, activity) def __update_title_cb(self, activity): + title = self.entry.get_text() activity.metadata['title'] = title @@ -203,30 +227,34 @@ class TitleEntry(gtk.ToolItem): return False -class DescriptionItem(gtk.ToolItem): +class DescriptionItem(Gtk.ToolItem): - def __init__(self, activity, **kwargs): - gtk.ToolItem.__init__(self) + def __init__(self, activity): + + Gtk.ToolItem.__init__(self) description_button = ToolButton('edit-description') description_button.show() - description_button.set_tooltip(_('Description')) + description_button.set_tooltip_text(_('Description')) self._palette = description_button.get_palette() - description_box = gtk.HBox() - sw = gtk.ScrolledWindow() - sw.set_size_request(int(gtk.gdk.screen_width() / 2), + description_box = Gtk.HBox() + sw = Gtk.ScrolledWindow() + screen = GdkX11.X11Screen() + sw.set_size_request(int(screen.width() / 2), 2 * style.GRID_CELL_SIZE) - sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) - self._text_view = gtk.TextView() + sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) + self._text_view = Gtk.TextView() self._text_view.set_left_margin(style.DEFAULT_PADDING) self._text_view.set_right_margin(style.DEFAULT_PADDING) - text_buffer = gtk.TextBuffer() + text_buffer = Gtk.TextBuffer() + if 'description' in activity.metadata: text_buffer.set_text(activity.metadata['description']) + self._text_view.set_buffer(text_buffer) self._text_view.connect('focus-out-event', - self.__description_changed_cb, activity) + self.__description_changed_cb, activity) sw.add(self._text_view) description_box.pack_start(sw, False, True, 0) self._palette.set_content(description_box) @@ -234,23 +262,28 @@ class DescriptionItem(gtk.ToolItem): self.add(description_button) description_button.connect('clicked', - self.__description_button_clicked_cb) + self.__description_button_clicked_cb) activity.metadata.connect('updated', self.__jobject_updated_cb) def _get_text_from_buffer(self): + buf = self._text_view.get_buffer() start_iter = buf.get_start_iter() end_iter = buf.get_end_iter() return buf.get_text(start_iter, end_iter, False) def __jobject_updated_cb(self, jobject): + if self._text_view.has_focus(): return + if 'description' not in jobject: return + if self._get_text_from_buffer() == jobject['description']: return + buf = self._text_view.get_buffer() buf.set_text(jobject['description']) @@ -258,6 +291,7 @@ class DescriptionItem(gtk.ToolItem): self._palette.popup(immediate=True, state=1) def __description_changed_cb(self, widget, event, activity): + description = self._get_text_from_buffer() if 'description' in activity.metadata and \ description == activity.metadata['description']: @@ -268,7 +302,7 @@ class DescriptionItem(gtk.ToolItem): return False -class ActivityToolbar(gtk.Toolbar): +class ActivityToolbar(Gtk.Toolbar): """The Activity toolbar with the Journal entry title, sharing, and Stop buttons @@ -277,7 +311,8 @@ class ActivityToolbar(gtk.Toolbar): """ def __init__(self, activity, orientation_left=False): - gtk.Toolbar.__init__(self) + + Gtk.Toolbar.__init__(self) self._activity = activity @@ -288,7 +323,7 @@ class ActivityToolbar(gtk.Toolbar): self.title = title_button.entry if orientation_left == False: - separator = gtk.SeparatorToolItem() + separator = Gtk.SeparatorToolItem() separator.props.draw = False separator.set_expand(True) self.insert(separator, -1) @@ -308,7 +343,7 @@ class ActivityToolbar(gtk.Toolbar): self.stop.show() -class EditToolbar(gtk.Toolbar): +class EditToolbar(Gtk.Toolbar): """Provides the standard edit toolbar for Activities. Members: @@ -343,7 +378,7 @@ class EditToolbar(gtk.Toolbar): """ def __init__(self): - gtk.Toolbar.__init__(self) + Gtk.Toolbar.__init__(self) self.undo = UndoButton() self.insert(self.undo, -1) @@ -353,7 +388,7 @@ class EditToolbar(gtk.Toolbar): self.insert(self.redo, -1) self.redo.show() - self.separator = gtk.SeparatorToolItem() + self.separator = Gtk.SeparatorToolItem() self.separator.set_draw(True) self.insert(self.separator, -1) self.separator.show() @@ -387,6 +422,7 @@ class ActivityToolbox(Toolbox): """ def __init__(self, activity): + Toolbox.__init__(self) self._activity_toolbar = ActivityToolbar(activity) diff --git a/toolkit/chooser.py b/toolkit/chooser.py index e957fd7..841ad86 100644 --- a/toolkit/chooser.py +++ b/toolkit/chooser.py @@ -16,11 +16,13 @@ """Object chooser method""" -import gtk +import gi +from gi.repository import Gtk + import logging -from sugar import mime -from sugar.graphics.objectchooser import ObjectChooser +from sugar3 import mime +from sugar3.graphics.objectchooser import ObjectChooser TEXT = hasattr(mime, 'GENERIC_TYPE_TEXT') and mime.GENERIC_TYPE_TEXT or None IMAGE = hasattr(mime, 'GENERIC_TYPE_IMAGE') and mime.GENERIC_TYPE_IMAGE or None @@ -39,7 +41,7 @@ def pick(cb=None, default=None, parent=None, what=None): * jobject, if object was choosen and cb is None * default, otherwise - NOTE: 'what' makes sense only for sugar >= 0.84 + NOTE: 'what' makes sense only for sugar3 >= 0.84 """ what = what and {'what_filter': what} or {} chooser = ObjectChooser(parent=parent, **what) @@ -48,7 +50,7 @@ def pick(cb=None, default=None, parent=None, what=None): out = None try: - if chooser.run() == gtk.RESPONSE_ACCEPT: + if chooser.run() == Gtk.ResponseType.ACCEPT: jobject = chooser.get_selected_object() logging.debug('ObjectChooser: %r' % jobject) diff --git a/toolkit/combobox.py b/toolkit/combobox.py index d021106..ff0ab3f 100644 --- a/toolkit/combobox.py +++ b/toolkit/combobox.py @@ -20,22 +20,26 @@ STABLE. """ -import gobject -import gtk +import gi +from gi.repository import GObject +from gi.repository import Gtk +from gi.repository import GdkPixbuf +# FIXME: This class is not being used. -class ComboBox(gtk.ComboBox): +class ComboBox(Gtk.ComboBox): def __init__(self): - gtk.ComboBox.__init__(self) + + Gtk.ComboBox.__init__(self) self._text_renderer = None self._icon_renderer = None - model = gtk.ListStore(gobject.TYPE_PYOBJECT, - gobject.TYPE_STRING, - gtk.gdk.Pixbuf, - gobject.TYPE_BOOLEAN) + model = Gtk.ListStore(GObject.TYPE_PYOBJECT, + GObject.TYPE_STRING, + GdkPixbuf.Pixbuf, + GObject.TYPE_BOOLEAN) self.set_model(model) self.set_row_separator_func(self._is_separator) @@ -56,15 +60,18 @@ class ComboBox(gtk.ComboBox): return None return row[0] - value = gobject.property( + value = GObject.property( type=object, getter=get_value, setter=None) def _get_real_name_from_theme(self, name, size): - icon_theme = gtk.icon_theme_get_default() - width, height = gtk.icon_size_lookup(size) + + icon_theme = Gtk.icon_theme_get_default() + width, height = Gtk.icon_size_lookup(size) info = icon_theme.lookup_icon(name, max(width, height), 0) + if not info: raise ValueError("Icon '" + name + "' not found.") + fname = info.get_filename() del info return fname @@ -90,62 +97,71 @@ class ComboBox(gtk.ComboBox): self.get_model().append(item) def set_item(self, action_id, text=None, icon_name=None, file_name=None): + for i, value in enumerate(self.get_model()): if value[0] == action_id: item = self._item_new(action_id, text, icon_name, file_name) iter = self.get_model().iter_nth_child(None, i) + if text is not None: self.get_model().set(iter, 1, item[1]) + if icon_name is not None or file_name is not None: self.get_model().set(iter, 2, item[2]) + return True return False def select(self, action_id=None, text=None): + if action_id is not None: column = 0 value = action_id + elif text is not None: column = 1 value = text + else: return for i, item in enumerate(self.get_model()): if item[column] != value: continue + self.set_active(i) break def _item_new(self, action_id, text, icon_name, file_name): + if not self._icon_renderer and (icon_name or file_name): - self._icon_renderer = gtk.CellRendererPixbuf() + self._icon_renderer = Gtk.CellRendererPixbuf() settings = self.get_settings() - w, h = gtk.icon_size_lookup_for_settings( - settings, gtk.ICON_SIZE_MENU) + w, h = Gtk.icon_size_lookup_for_settings( + settings, Gtk.IconSize.MENU) self._icon_renderer.props.stock_size = max(w, h) - self.pack_start(self._icon_renderer, False) + self.pack_start(self._icon_renderer, False, False, 0) self.add_attribute(self._icon_renderer, 'pixbuf', 2) if not self._text_renderer and text: - self._text_renderer = gtk.CellRendererText() - self.pack_end(self._text_renderer, True) + self._text_renderer = Gtk.CellRendererText() + self.pack_end(self._text_renderer, True, True, 0) self.add_attribute(self._text_renderer, 'text', 1) if icon_name or file_name: if text: - size = gtk.ICON_SIZE_MENU + size = Gtk.IconSize.MENU else: - size = gtk.ICON_SIZE_LARGE_TOOLBAR - width, height = gtk.icon_size_lookup(size) + size = Gtk.IconSize.LARGE_TOOLBAR + width, height = Gtk.icon_size_lookup(size) if icon_name: file_name = self._get_real_name_from_theme(icon_name, size) - pixbuf = gtk.gdk.pixbuf_new_from_file_at_size( - file_name, width, height) + pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size( + file_name, width, height) else: pixbuf = None diff --git a/toolkit/internals/palettewindow.py b/toolkit/internals/palettewindow.py index d8c4326..50fc567 100644 --- a/toolkit/internals/palettewindow.py +++ b/toolkit/internals/palettewindow.py @@ -23,41 +23,50 @@ STABLE. import logging -import gtk -import gobject -import hippo +import gi +from gi.repository import Gtk +from gi.repository import Gdk +from gi.repository import GObject +# FIXME: We do not use hippo +#import hippo -from sugar.graphics import palettegroup -from sugar.graphics import animator -from sugar.graphics import style +from sugar3.graphics import palettegroup +from sugar3.graphics import animator +from sugar3.graphics import style def _calculate_gap(a, b): """Helper function to find the gap position and size of widget a""" # Test for each side if the palette and invoker are # adjacent to each other. + gap = True if a.y + a.height == b.y: - gap_side = gtk.POS_BOTTOM + gap_side = Gtk.PositionType.BOTTOM + elif a.x + a.width == b.x: - gap_side = gtk.POS_RIGHT + gap_side = Gtk.PositionType.RIGHT + elif a.x == b.x + b.width: - gap_side = gtk.POS_LEFT + gap_side = Gtk.PositionType.LEFT + elif a.y == b.y + b.height: - gap_side = gtk.POS_TOP + gap_side = Gtk.PositionType.TOP + else: gap = False if gap: - if gap_side == gtk.POS_BOTTOM or gap_side == gtk.POS_TOP: + if gap_side == Gtk.PositionType.BOTTOM or gap_side == Gtk.PositionType.TOP: gap_start = min(a.width, max(0, b.x - a.x)) gap_size = max(0, min(a.width, - (b.x + b.width) - a.x) - gap_start) - elif gap_side == gtk.POS_RIGHT or gap_side == gtk.POS_LEFT: + (b.x + b.width) - a.x) - gap_start) + + elif gap_side == Gtk.PositionType.RIGHT or gap_side == Gtk.PositionType.LEFT: gap_start = min(a.height, max(0, b.y - a.y)) gap_size = max(0, min(a.height, - (b.y + b.height) - a.y) - gap_start) + (b.y + b.height) - a.y) - gap_start) if gap and gap_size > 0: return (gap_side, gap_start, gap_size) @@ -65,11 +74,11 @@ def _calculate_gap(a, b): return False -class MouseSpeedDetector(gobject.GObject): +class MouseSpeedDetector(GObject.GObject): __gsignals__ = { - 'motion-slow': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])), - 'motion-fast': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])), + 'motion-slow': (GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE, ([])), + 'motion-fast': (GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE, ([])), } _MOTION_SLOW = 1 @@ -80,7 +89,7 @@ class MouseSpeedDetector(gobject.GObject): delay in msec threshold in pixels (per tick of 'delay' msec)""" - gobject.GObject.__init__(self) + GObject.GObject.__init__(self) self._threshold = thresh self._parent = parent @@ -90,37 +99,48 @@ class MouseSpeedDetector(gobject.GObject): self._mouse_pos = None def start(self): + self.stop() self._mouse_pos = self._get_mouse_position() - self._timeout_hid = gobject.timeout_add(self._delay, self._timer_cb) + self._timeout_hid = GObject.timeout_add(self._delay, self._timer_cb) def stop(self): + if self._timeout_hid is not None: - gobject.source_remove(self._timeout_hid) + GObject.source_remove(self._timeout_hid) + self._state = None def _get_mouse_position(self): - display = gtk.gdk.display_get_default() + + display = Gdk.display_get_default() screen_, x, y, mask_ = display.get_pointer() + return (x, y) def _detect_motion(self): + oldx, oldy = self._mouse_pos (x, y) = self._get_mouse_position() self._mouse_pos = (x, y) dist2 = (oldx - x)**2 + (oldy - y)**2 + if dist2 > self._threshold**2: return True + else: return False def _timer_cb(self): + motion = self._detect_motion() + if motion and self._state != self._MOTION_FAST: self.emit('motion-fast') self._state = self._MOTION_FAST + elif not motion and self._state != self._MOTION_SLOW: self.emit('motion-slow') self._state = self._MOTION_SLOW @@ -128,15 +148,16 @@ class MouseSpeedDetector(gobject.GObject): return True -class PaletteWindow(gtk.Window): +class PaletteWindow(Gtk.Window): __gsignals__ = { - 'popup': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])), - 'popdown': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])), - 'activate': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])), + 'popup': (GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE, ([])), + 'popdown': (GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE, ([])), + 'activate': (GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE, ([])), } - def __init__(self, **kwargs): + def __init__(self): + self._group_id = None self._invoker = None self._invoker_hids = [] @@ -152,14 +173,14 @@ class PaletteWindow(gtk.Window): self._popdown_anim = animator.Animator(0.6, 10) self._popdown_anim.add(_PopdownAnimation(self)) - gobject.GObject.__init__(self, **kwargs) + GObject.GObject.__init__(self) self.set_decorated(False) self.set_resizable(False) # Just assume xthickness and ythickness are the same self.set_border_width(self.get_style().xthickness) - accel_group = gtk.AccelGroup() + accel_group = Gtk.AccelGroup() self.set_data('sugar-accel-group', accel_group) self.add_accel_group(accel_group) @@ -176,14 +197,17 @@ class PaletteWindow(gtk.Window): self._mouse_detector.connect('motion-slow', self._mouse_slow_cb) def __destroy_cb(self, palette): + self.set_group_id(None) def set_invoker(self, invoker): + for hid in self._invoker_hids[:]: self._invoker.disconnect(hid) self._invoker_hids.remove(hid) self._invoker = invoker + if invoker is not None: self._invoker_hids.append(self._invoker.connect( 'mouse-enter', self._invoker_mouse_enter_cb)) @@ -193,20 +217,26 @@ class PaletteWindow(gtk.Window): 'right-click', self._invoker_right_click_cb)) def get_invoker(self): + return self._invoker - invoker = gobject.property(type=object, - getter=get_invoker, - setter=set_invoker) + invoker = GObject.property( + type=object, + getter=get_invoker, + setter=set_invoker) def __realize_cb(self, widget): - self.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DIALOG) + + #self.window.set_type_hint(Gdk.WINDOW_TYPE_HINT_DIALOG) + self.window.set_type_hint(Gdk.WindowType.POPUP) def _mouse_slow_cb(self, widget): + self._mouse_detector.stop() self._palette_do_popup() def _palette_do_popup(self): + immediate = False if self.is_up(): @@ -222,30 +252,37 @@ class PaletteWindow(gtk.Window): self.popup(immediate=immediate) def is_up(self): + return self._up def set_group_id(self, group_id): + if self._group_id: group = palettegroup.get_group(self._group_id) group.remove(self) + if group_id: self._group_id = group_id group = palettegroup.get_group(group_id) group.add(self) def get_group_id(self): + return self._group_id - group_id = gobject.property(type=str, - getter=get_group_id, - setter=set_group_id) + group_id = GObject.property( + type=str, + getter=get_group_id, + setter=set_group_id) def do_size_request(self, requisition): - gtk.Window.do_size_request(self, requisition) + + Gtk.Window.do_size_request(self, requisition) requisition.width = max(requisition.width, style.GRID_CELL_SIZE * 2) def do_size_allocate(self, allocation): - gtk.Window.do_size_allocate(self, allocation) + + Gtk.Window.do_size_allocate(self, allocation) if self._old_alloc is None or \ self._old_alloc.x != allocation.x or \ @@ -268,6 +305,7 @@ class PaletteWindow(gtk.Window): palette = self.get_rect() gap = _calculate_gap(palette, invoker) + else: gap = False @@ -275,18 +313,19 @@ class PaletteWindow(gtk.Window): wstyle = self.get_style() if gap: - wstyle.paint_box_gap(event.window, gtk.STATE_PRELIGHT, - gtk.SHADOW_IN, event.area, self, "palette", - 0, 0, allocation.width, allocation.height, - gap[0], gap[1], gap[2]) + wstyle.paint_box_gap(event.window, Gtk.StateType.PRELIGHT, + Gtk.ShadowType.IN, event.area, self, "palette", + 0, 0, allocation.width, allocation.height, + gap[0], gap[1], gap[2]) + else: - wstyle.paint_box(event.window, gtk.STATE_PRELIGHT, - gtk.SHADOW_IN, event.area, self, "palette", - 0, 0, allocation.width, allocation.height) + wstyle.paint_box(event.window, Gtk.StateType.PRELIGHT, + Gtk.ShadowType.IN, event.area, self, "palette", + 0, 0, allocation.width, allocation.height) # Fall trough to the container expose handler. # (Leaving out the window expose handler which redraws everything) - gtk.Bin.do_expose_event(self, event) + Gtk.Bin.do_expose_event(self, event) def update_position(self): invoker = self._invoker @@ -360,13 +399,13 @@ class PaletteWindow(gtk.Window): self.popup(immediate=True) def __enter_notify_event_cb(self, widget, event): - if event.detail != gtk.gdk.NOTIFY_INFERIOR and \ - event.mode == gtk.gdk.CROSSING_NORMAL: + if event.detail != Gdk.NotifyType.INFERIOR and \ + event.mode == Gdk.CROSSING_NORMAL: self.on_enter(event) def __leave_notify_event_cb(self, widget, event): - if event.detail != gtk.gdk.NOTIFY_INFERIOR and \ - event.mode == gtk.gdk.CROSSING_NORMAL: + if event.detail != Gdk.NotifyType.INFERIOR and \ + event.mode == Gdk.CROSSING_NORMAL: self.on_leave(event) def __show_cb(self, widget): @@ -393,7 +432,7 @@ class PaletteWindow(gtk.Window): y = win_y + rectangle.y width, height = self.size_request() - return gtk.gdk.Rectangle(x, y, width, height) + return Gdk.Rectangle(x, y, width, height) def get_palette_state(self): return self._palette_state @@ -429,13 +468,13 @@ class _PopdownAnimation(animator.Animation): self._palette.popdown(immediate=True) -class Invoker(gobject.GObject): +class Invoker(GObject.GObject): __gsignals__ = { - 'mouse-enter': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])), - 'mouse-leave': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])), - 'right-click': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])), - 'focus-out': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([])), + 'mouse-enter': (GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE, ([])), + 'mouse-leave': (GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE, ([])), + 'right-click': (GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE, ([])), + 'focus-out': (GObject.SIGNAL_RUN_FIRST, GObject.TYPE_NONE, ([])), } ANCHORED = 0 @@ -447,12 +486,13 @@ class Invoker(gobject.GObject): LEFT = [(-1.0, 0.0, 0.0, 0.0), (-1.0, -1.0, 0.0, 1.0)] def __init__(self): - gobject.GObject.__init__(self) + GObject.GObject.__init__(self) self.parent = None - self._screen_area = gtk.gdk.Rectangle(0, 0, gtk.gdk.screen_width(), - gtk.gdk.screen_height()) + self._screen_area = Gdk.Rectangle(0, 0, + Gdk.screen_width(), + Gdk.screen_height()) self._position_hint = self.ANCHORED self._cursor_x = -1 self._cursor_y = -1 @@ -474,7 +514,7 @@ class Invoker(gobject.GObject): invoker_valign = alignment[3] if self._cursor_x == -1 or self._cursor_y == -1: - display = gtk.gdk.display_get_default() + display = Gdk.display_get_default() screen_, x, y, mask_ = display.get_pointer() self._cursor_x = x self._cursor_y = y @@ -483,9 +523,9 @@ class Invoker(gobject.GObject): rect = self.get_rect() else: dist = style.PALETTE_CURSOR_DISTANCE - rect = gtk.gdk.Rectangle(self._cursor_x - dist, - self._cursor_y - dist, - dist * 2, dist * 2) + rect = Gdk.Rectangle(self._cursor_x - dist, + self._cursor_y - dist, + dist * 2, dist * 2) palette_width, palette_height = palette_dim @@ -495,8 +535,8 @@ class Invoker(gobject.GObject): y = rect.y + rect.height * invoker_valign + \ palette_height * palette_valign - return gtk.gdk.Rectangle(int(x), int(y), - palette_width, palette_height) + return Gdk.Rectangle(int(x), int(y), + palette_width, palette_height) def _in_screen(self, rect): return rect.x >= self._screen_area.x and \ @@ -526,13 +566,16 @@ class Invoker(gobject.GObject): return self.BOTTOM + self.RIGHT + self.TOP + self.LEFT def get_position_for_alignment(self, alignment, palette_dim): + rect = self._get_position_for_alignment(alignment, palette_dim) if self._in_screen(rect): return rect + else: return None def get_position(self, palette_dim): + alignment = self.get_alignment(palette_dim) rect = self._get_position_for_alignment(alignment, palette_dim) @@ -548,8 +591,10 @@ class Invoker(gobject.GObject): return rect def get_alignment(self, palette_dim): + best_alignment = None best_area = -1 + for alignment in self._get_alignments(): pos = self._get_position_for_alignment(alignment, palette_dim) if self._in_screen(pos): @@ -617,8 +662,10 @@ class Invoker(gobject.GObject): self._cursor_y = -1 def _ensure_palette_exists(self): + if self.parent and self.palette is None: palette = self.parent.create_palette() + if palette is not None: self.palette = palette @@ -637,6 +684,7 @@ class Invoker(gobject.GObject): return self._palette def set_palette(self, palette): + if self._palette is not None: self._palette.popdown(immediate=True) @@ -648,13 +696,14 @@ class Invoker(gobject.GObject): if self._palette: self._palette.props.invoker = self - palette = gobject.property( + palette = GObject.property( type=object, setter=set_palette, getter=get_palette) class WidgetInvoker(Invoker): def __init__(self, parent=None, widget=None): + Invoker.__init__(self) self._widget = None @@ -666,8 +715,10 @@ class WidgetInvoker(Invoker): self.attach_widget(parent, widget) def attach_widget(self, parent, widget=None): + if widget: self._widget = widget + else: self._widget = parent @@ -683,36 +734,41 @@ class WidgetInvoker(Invoker): self.attach(parent) def detach(self): + Invoker.detach(self) self._widget.disconnect(self._enter_hid) self._widget.disconnect(self._leave_hid) self._widget.disconnect(self._release_hid) def get_rect(self): + allocation = self._widget.get_allocation() if self._widget.window is not None: x, y = self._widget.window.get_origin() + else: logging.warning( "Trying to position palette with invoker that's not realized.") x = 0 y = 0 - if self._widget.flags() & gtk.NO_WINDOW: + if self._widget.flags() & Gtk.NO_WINDOW: x += allocation.x y += allocation.y width = allocation.width height = allocation.height - return gtk.gdk.Rectangle(x, y, width, height) + return Gdk.Rectangle(x, y, width, height) def has_rectangle_gap(self): return True def draw_rectangle(self, event, palette): - if self._widget.flags() & gtk.NO_WINDOW: + + if self._widget.flags() & Gtk.NO_WINDOW: x, y = self._widget.allocation.x, self._widget.allocation.y + else: x = y = 0 @@ -720,18 +776,18 @@ class WidgetInvoker(Invoker): gap = _calculate_gap(self.get_rect(), palette.get_rect()) if gap: - wstyle.paint_box_gap(event.window, gtk.STATE_PRELIGHT, - gtk.SHADOW_IN, event.area, self._widget, - "palette-invoker", x, y, - self._widget.allocation.width, - self._widget.allocation.height, - gap[0], gap[1], gap[2]) + wstyle.paint_box_gap(event.window, Gtk.SateType.PRELIGHT, + Gtk.ShadowType.IN, event.area, self._widget, + "palette-invoker", x, y, + self._widget.allocation.width, + self._widget.allocation.height, + gap[0], gap[1], gap[2]) else: - wstyle.paint_box(event.window, gtk.STATE_PRELIGHT, - gtk.SHADOW_IN, event.area, self._widget, - "palette-invoker", x, y, - self._widget.allocation.width, - self._widget.allocation.height) + wstyle.paint_box(event.window, Gtk.StateType.PRELIGHT, + Gtk.ShadowType.IN, event.area, self._widget, + "palette-invoker", x, y, + self._widget.allocation.width, + self._widget.allocation.height) def __enter_notify_event_cb(self, widget, event): self.notify_mouse_enter() @@ -740,9 +796,11 @@ class WidgetInvoker(Invoker): self.notify_mouse_leave() def __button_release_event_cb(self, widget, event): + if event.button == 3: self.notify_right_click() return True + else: return False @@ -759,7 +817,7 @@ class WidgetInvoker(Invoker): def _get_widget(self): return self._widget - widget = gobject.property(type=object, getter=_get_widget, setter=None) + widget = GObject.property(type=object, getter=_get_widget, setter=None) class CanvasInvoker(Invoker): @@ -780,9 +838,9 @@ class CanvasInvoker(Invoker): self._item = parent self._motion_hid = self._item.connect('motion-notify-event', - self.__motion_notify_event_cb) + self.__motion_notify_event_cb) self._release_hid = self._item.connect('button-release-event', - self.__button_release_event_cb) + self.__button_release_event_cb) def detach(self): Invoker.detach(self) @@ -797,15 +855,16 @@ class CanvasInvoker(Invoker): if context: x, y = context.translate_to_screen(self._item) width, height = self._item.get_allocation() - return gtk.gdk.Rectangle(x, y, width, height) + return Gdk.Rectangle(x, y, width, height) else: - return gtk.gdk.Rectangle() + return Gdk.Rectangle() def __motion_notify_event_cb(self, button, event): - if event.detail == hippo.MOTION_DETAIL_ENTER: - self.notify_mouse_enter() - elif event.detail == hippo.MOTION_DETAIL_LEAVE: - self.notify_mouse_leave() + # FIXME: We do not use hippo + #if event.detail == hippo.MOTION_DETAIL_ENTER: + # self.notify_mouse_enter() + #elif event.detail == hippo.MOTION_DETAIL_LEAVE: + # self.notify_mouse_leave() return False @@ -817,7 +876,9 @@ class CanvasInvoker(Invoker): return False def get_toplevel(self): - return hippo.get_canvas_for_item(self._item).get_toplevel() + # FIXME: We do not use hippo + #return hippo.get_canvas_for_item(self._item).get_toplevel() + pass class ToolInvoker(WidgetInvoker): @@ -836,7 +897,7 @@ class ToolInvoker(WidgetInvoker): if parent is None: return WidgetInvoker._get_alignments() - if parent.get_orientation() is gtk.ORIENTATION_HORIZONTAL: + if parent.get_orientation() is Gtk.Orientation.HORIZONTAL: return self.BOTTOM + self.TOP else: return self.LEFT + self.RIGHT @@ -845,6 +906,7 @@ class ToolInvoker(WidgetInvoker): class CellRendererInvoker(Invoker): def __init__(self): + Invoker.__init__(self) self._position_hint = self.AT_CURSOR @@ -860,11 +922,11 @@ class CellRendererInvoker(Invoker): self._cell_renderer = cell_renderer self._motion_hid = tree_view.connect('motion-notify-event', - self.__motion_notify_event_cb) + self.__motion_notify_event_cb) self._leave_hid = tree_view.connect('leave-notify-event', - self.__leave_notify_event_cb) + self.__leave_notify_event_cb) self._release_hid = tree_view.connect('button-release-event', - self.__button_release_event_cb) + self.__button_release_event_cb) self.attach(cell_renderer) @@ -875,53 +937,65 @@ class CellRendererInvoker(Invoker): self._tree_view.disconnect(self._release_hid) def get_rect(self): + allocation = self._tree_view.get_allocation() if self._tree_view.window is not None: x, y = self._tree_view.window.get_origin() + else: logging.warning( "Trying to position palette with invoker that's not realized.") x = 0 y = 0 - if self._tree_view.flags() & gtk.NO_WINDOW: + if self._tree_view.flags() & Gtk.NO_WINDOW: x += allocation.x y += allocation.y width = allocation.width height = allocation.height - return gtk.gdk.Rectangle(x, y, width, height) + return Gdk.Rectangle(x, y, width, height) def __motion_notify_event_cb(self, widget, event): + if event.window != widget.get_bin_window(): return + if self._point_in_cell_renderer(event.x, event.y): tree_view = self._tree_view path, column_, x_, y_ = tree_view.get_path_at_pos(int(event.x), - int(event.y)) + int(event.y)) + if path != self.path: if self.path is not None: self._redraw_path(self.path) + if path is not None: self._redraw_path(path) + if self.palette is not None: self.palette.popdown(immediate=True) self.palette = None + self.path = path self.notify_mouse_enter() + else: if self.path is not None: self._redraw_path(self.path) + self.path = None self.notify_mouse_leave() def _redraw_path(self, path): + for column in self._tree_view.get_columns(): if self._cell_renderer in column.get_cell_renderers(): break + area = self._tree_view.get_background_area(path, column) x, y = \ self._tree_view.convert_bin_window_to_widget_coords(area.x, area.y) @@ -931,22 +1005,26 @@ class CellRendererInvoker(Invoker): self.notify_mouse_leave() def __button_release_event_cb(self, widget, event): + if event.button == 1 and self._point_in_cell_renderer(event.x, event.y): tree_view = self._tree_view path, column_, x_, y_ = tree_view.get_path_at_pos(int(event.x), - int(event.y)) + int(event.y)) self._cell_renderer.emit('clicked', path) # So the treeview receives it and knows a drag isn't going on return False + if event.button == 3 and self._point_in_cell_renderer(event.x, event.y): self.notify_right_click() return True + else: return False def _point_in_cell_renderer(self, event_x, event_y): + pos = self._tree_view.get_path_at_pos(int(event_x), int(event_y)) if pos is None: return False @@ -958,6 +1036,7 @@ class CellRendererInvoker(Invoker): cell_x, cell_width = column.cell_get_position(cell_renderer) if x > cell_x and x < (cell_x + cell_width): return True + return False return False diff --git a/toolkit/pixbuf.py b/toolkit/pixbuf.py index c3bb7d1..c9b9a78 100644 --- a/toolkit/pixbuf.py +++ b/toolkit/pixbuf.py @@ -18,14 +18,17 @@ import re import cStringIO -import gtk -import rsvg import cairo import logging -from sugar.graphics import style -from sugar.graphics.xocolor import XoColor, is_valid -from sugar.util import LRU +import gi +from gi.repository import Gtk +from gi.repository import GdkPixbuf +from gi.repository import Rsvg + +from sugar3.graphics import style +from sugar3.graphics.xocolor import XoColor, is_valid +from sugar3.util import LRU def to_file(pixbuf): @@ -47,20 +50,23 @@ def to_str(pixbuf): def from_str(str): """Convert string to pixbuf object""" - loader = gtk.gdk.pixbuf_loader_new_with_mime_type('image/png') + loader = GdkPixbuf.PixbufLoader.new_with_mime_type('image/png') try: loader.write(str) + except Exception, e: logging.error('pixbuf.from_str: %s' % e) return None + finally: loader.close() return loader.get_pixbuf() -def at_size_with_ratio(pixbuf, width, height, type=gtk.gdk.INTERP_BILINEAR): +def at_size_with_ratio(pixbuf, width, height, type=GdkPixbuf.InterpType.BILINEAR): + image_width = pixbuf.get_width() image_height = pixbuf.get_height() @@ -71,6 +77,7 @@ def at_size_with_ratio(pixbuf, width, height, type=gtk.gdk.INTERP_BILINEAR): if ratio_width != ratio: ratio_width = ratio width = int(image_width * ratio) + elif ratio_height != ratio: ratio_height = ratio height = int(image_height * ratio) @@ -82,7 +89,7 @@ def from_svg_at_size(filename=None, width=None, height=None, handle=None, """Scale and load SVG into pixbuf""" if not handle: - handle = rsvg.Handle(filename) + handle = Rsvg.Handle(filename) dimensions = handle.get_dimension_data() icon_width = dimensions[0] @@ -97,6 +104,7 @@ def from_svg_at_size(filename=None, width=None, height=None, handle=None, if ratio_width != ratio: ratio_width = ratio width = int(icon_width * ratio) + elif ratio_height != ratio: ratio_height = ratio height = int(icon_height * ratio) @@ -109,7 +117,7 @@ def from_svg_at_size(filename=None, width=None, height=None, handle=None, context.scale(ratio_width, ratio_height) handle.render_cairo(context) - loader = gtk.gdk.pixbuf_loader_new_with_mime_type('image/png') + loader = GdkPixbuf.PixbufLoader.new_with_mime_type('image/png') surface.write_to_png(loader) loader.close() diff --git a/toolkit/radiopalette.py b/toolkit/radiopalette.py index 9c902b1..ccbaa6e 100644 --- a/toolkit/radiopalette.py +++ b/toolkit/radiopalette.py @@ -15,16 +15,18 @@ # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. -import gtk +import gi +from gi.repository import Gtk -from sugar.graphics.toolbutton import ToolButton -from sugar.graphics.palette import Palette +from sugar3.graphics.toolbutton import ToolButton +from sugar3.graphics.palette import Palette class RadioMenuButton(ToolButton): - def __init__(self, **kwargs): - ToolButton.__init__(self, **kwargs) + def __init__(self): + + ToolButton.__init__(self) self.selected_button = None if self.props.palette: @@ -34,18 +36,23 @@ class RadioMenuButton(ToolButton): self.connect('notify::palette', self.__palette_cb) def _do_clicked(self): + if self.palette is None: return + if self.palette.is_up() and \ self.palette.palette_state == Palette.SECONDARY: self.palette.popdown(immediate=True) + else: self.palette.popup(immediate=True) self.palette.props.invoker.emit('right-click') def __palette_cb(self, widget, pspec): + if not isinstance(self.props.palette, RadioPalette): return + self.props.palette.update_button() def __clicked_cb(self, button): @@ -54,10 +61,12 @@ class RadioMenuButton(ToolButton): class RadioToolsButton(RadioMenuButton): - def __init__(self, **kwargs): - RadioMenuButton.__init__(self, **kwargs) + def __init__(self): + + RadioMenuButton.__init__(self) def _do_clicked(self): + if not self.selected_button: return self.selected_button.emit('clicked') @@ -65,14 +74,16 @@ class RadioToolsButton(RadioMenuButton): class RadioPalette(Palette): - def __init__(self, **kwargs): - Palette.__init__(self, **kwargs) + def __init__(self): + + Palette.__init__(self) - self.button_box = gtk.HBox() + self.button_box = Gtk.HBox() self.button_box.show() self.set_content(self.button_box) def append(self, button, label): + children = self.button_box.get_children() if button.palette is not None: @@ -80,17 +91,19 @@ class RadioPalette(Palette): button.show() button.connect('clicked', self.__clicked_cb) - self.button_box.pack_start(button, fill=False) + self.button_box.pack_start(button, False, False, 0) button.palette_label = label if not children: self.__clicked_cb(button) def update_button(self): + for i in self.button_box.get_children(): self.__clicked_cb(i) def __clicked_cb(self, button): + if not button.get_active(): return @@ -99,8 +112,10 @@ class RadioPalette(Palette): if self.props.invoker is not None: parent = self.props.invoker.parent + else: parent = None + if not isinstance(parent, RadioMenuButton): return diff --git a/toolkit/scrolledbox.py b/toolkit/scrolledbox.py index c95dae0..3653f4f 100644 --- a/toolkit/scrolledbox.py +++ b/toolkit/scrolledbox.py @@ -12,28 +12,35 @@ # 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 gi +from gi.repository import Gtk +from gi.repository import Gdk -from sugar.graphics.icon import Icon +from sugar3.graphics.icon import Icon -class ScrollButton(gtk.ToolButton): +class ScrollButton(Gtk.ToolButton): + def __init__(self, icon_name): - gtk.ToolButton.__init__(self) + + Gtk.ToolButton.__init__(self) icon = Icon(icon_name = icon_name, - icon_size=gtk.ICON_SIZE_SMALL_TOOLBAR) + icon_size=Gtk.IconSize.SMALL_TOOLBAR) # The alignment is a hack to work around gtk.ToolButton code # that sets the icon_size when the icon_widget is a gtk.Image - alignment = gtk.Alignment(0.5, 0.5) + alignment = Gtk.Alignment() + alignment.set(0.0, 0.0, 0.5, 0.5) alignment.add(icon) self.set_icon_widget(alignment) -class ScrolledBox(gtk.EventBox): +class ScrolledBox(Gtk.EventBox): + def __init__(self, orientation, - arrows_policy=gtk.POLICY_AUTOMATIC, - scroll_policy=gtk.POLICY_AUTOMATIC): + arrows_policy=Gtk.PolicyType.AUTOMATIC, + scroll_policy=Gtk.PolicyType.AUTOMATIC): - gtk.EventBox.__init__(self) + Gtk.EventBox.__init__(self) + self.orientation = orientation self._viewport = None self._abox = None @@ -44,68 +51,83 @@ class ScrolledBox(gtk.EventBox): self._left = None self._right = None - if orientation == gtk.ORIENTATION_HORIZONTAL: - box = gtk.HBox() + if orientation == Gtk.Orientation.HORIZONTAL: + box = Gtk.HBox() + else: - box = gtk.VBox() - if self._arrows_policy == gtk.POLICY_AUTOMATIC: + box = Gtk.VBox() + + if self._arrows_policy == Gtk.PolicyType.AUTOMATIC: box.connect("size-allocate", self._box_allocate_cb) self.add(box) - if self._arrows_policy != gtk.POLICY_NEVER: - if orientation == gtk.ORIENTATION_HORIZONTAL: + if self._arrows_policy != Gtk.PolicyType.NEVER: + if orientation == Gtk.Orientation.HORIZONTAL: self._left = ScrollButton('go-left') + else: self._left = ScrollButton('go-up') + self._left.connect('clicked', self._scroll_cb, - gtk.gdk.SCROLL_LEFT) + Gdk.ScrollDirection.LEFT) box.pack_start(self._left, False, False, 0) - self._scrolled = gtk.ScrolledWindow() - if orientation == gtk.ORIENTATION_HORIZONTAL: - self._scrolled.set_policy(scroll_policy, gtk.POLICY_NEVER) + self._scrolled = Gtk.ScrolledWindow() + if orientation == Gtk.Orientation.HORIZONTAL: + self._scrolled.set_policy(scroll_policy, Gtk.PolicyType.NEVER) else: - self._scrolled.set_policy(gtk.POLICY_NEVER, scroll_policy) + self._scrolled.set_policy(Gtk.PolicyType.NEVER, scroll_policy) + self._scrolled.connect('scroll-event', self._scroll_event_cb) box.pack_start(self._scrolled, True, True, 0) - if orientation == gtk.ORIENTATION_HORIZONTAL: + if orientation == Gtk.Orientation.HORIZONTAL: self._adj = self._scrolled.get_hadjustment() + else: self._adj = self._scrolled.get_vadjustment() + self._adj.connect('changed', self._scroll_changed_cb) self._adj.connect('value-changed', self._scroll_changed_cb) - if self._arrows_policy != gtk.POLICY_NEVER: - if orientation == gtk.ORIENTATION_HORIZONTAL: + if self._arrows_policy != Gtk.PolicyType.NEVER: + if orientation == Gtk.Orientation.HORIZONTAL: self._right = ScrollButton('go-right') + else: self._right = ScrollButton('go-down') + self._right.connect('clicked', self._scroll_cb, - gtk.gdk.SCROLL_RIGHT) + Gdk.ScrollDirection.RIGHT) box.pack_start(self._right, False, False, 0) def modify_fg(self, state, bg): - gtk.EventBox.modify_fg(self, state, bg) + + Gtk.EventBox.modify_fg(self, state, bg) self._viewport.get_parent().modify_fg(state, bg) def modify_bg(self, state, bg): - gtk.EventBox.modify_bg(self, state, bg) + + Gtk.EventBox.modify_bg(self, state, bg) self._viewport.get_parent().modify_bg(state, bg) def set_viewport(self, widget): + if widget == self._viewport: return + if self._viewport and self._aviewport_sig: self._viewport.disconnect(self._aviewport_sig) + self._viewport = widget - if self._arrows_policy == gtk.POLICY_AUTOMATIC: + if self._arrows_policy == Gtk.PolicyType.AUTOMATIC: self._aviewport_sig = self._viewport.connect('size-allocate', - self._viewport_allocate_cb) + self._viewport_allocate_cb) self._scrolled.add_with_viewport(widget) def get_viewport_allocation(self): + alloc = self._scrolled.get_allocation() alloc.x -= self._adj.get_value() return alloc @@ -114,6 +136,7 @@ class ScrolledBox(gtk.EventBox): return self._adj def _box_allocate_cb(self, w, a): + self._abox = a self._update_arrows() @@ -124,52 +147,63 @@ class ScrolledBox(gtk.EventBox): def _update_arrows(self): if not self._abox or not self._aviewport: return - if self.orientation == gtk.ORIENTATION_HORIZONTAL: + if self.orientation == Gtk.Orientation.HORIZONTAL: show_flag = self._abox.width < self._aviewport.width + else: show_flag = self._abox.height < self._aviewport.height if show_flag: self._left.show() self._right.show() + else: self._left.hide() self._right.hide() def _scroll_event_cb(self, widget, event): - if self.orientation == gtk.ORIENTATION_HORIZONTAL: - if event.direction == gtk.gdk.SCROLL_UP: - event.direction = gtk.gdk.SCROLL_LEFT - if event.direction == gtk.gdk.SCROLL_DOWN: - event.direction = gtk.gdk.SCROLL_RIGHT + + if self.orientation == Gtk.Orientation.HORIZONTAL: + if event.direction == Gdk.ScrollDirection.UP: + event.direction = Gdk.ScrollDirection.LEFT + + if event.direction == Gdk.ScrollDirection.DOWN: + event.direction = Gdk.ScrollDirection.RIGHT + else: - if event.direction == gtk.gdk.SCROLL_LEFT: - event.direction = gtk.gdk.SCROLL_UP - if event.direction == gtk.gdk.SCROLL_RIGHT: - event.direction = gtk.gdk.SCROLL_DOWN + if event.direction == Gdk.ScrollDirection.LEFT: + event.direction = Gdk.ScrollDirection.UP + + if event.direction == Gdk.ScrollDirection.RIGHT: + event.direction = Gdk.ScrollDirection.DOWN - if self._scroll_policy == gtk.POLICY_NEVER: + if self._scroll_policy == Gtk.PolicyType.NEVER: self._scroll_cb(None, event.direction) return False def _scroll_cb(self, widget, direction): - if direction in (gtk.gdk.SCROLL_LEFT, gtk.gdk.SCROLL_UP): + + if direction in (Gdk.ScrollDirection.LEFT, Gdk.ScrollDirection.UP): val = max(self._adj.get_property('lower'), self._adj.get_value() - - self._adj.get_property('page_increment')) + - self._adj.get_property('page_increment')) + else: val = min(self._adj.get_property('upper') - - self._adj.get_property('page_size'), - self._adj.get_value() - + self._adj.get_property('page_increment')) + - self._adj.get_property('page_size'), + self._adj.get_value() + + self._adj.get_property('page_increment')) self._adj.set_value(val) def _scroll_changed_cb(self, widget): + val = self._adj.get_value() + if self._left: if val == 0: self._left.set_sensitive(False) + else: self._left.set_sensitive(True) @@ -177,13 +211,16 @@ class ScrolledBox(gtk.EventBox): if val >= self._adj.get_property('upper') - \ self._adj.get_property('page_size'): self._right.set_sensitive(False) + else: self._right.set_sensitive(True) class HScrolledBox(ScrolledBox): - def __init__(self, **kwargs): - ScrolledBox.__init__(self, gtk.ORIENTATION_HORIZONTAL, **kwargs) + + def __init__(self): + ScrolledBox.__init__(self, Gtk.Orientation.HORIZONTAL) class VScrolledBox(ScrolledBox): - def __init__(self, **kwargs): - ScrolledBox.__init__(self, gtk.ORIENTATION_VERTICAL, **kwargs) + + def __init__(self): + ScrolledBox.__init__(self, Gtk.Orientation.VERTICAL) diff --git a/toolkit/tarball.py b/toolkit/tarball.py index 0a4a1b2..30483ea 100644 --- a/toolkit/tarball.py +++ b/toolkit/tarball.py @@ -20,7 +20,6 @@ import os import time import tarfile import cStringIO -import gtk import zipfile import tempfile import shutil @@ -64,8 +63,10 @@ class Tarball: """ def __init__(self, name=None, mode='r', mtime=None): + if not mode.startswith('r') or tarfile.is_tarfile(name): self.__tar = tarfile.TarFile(name=name, mode=mode) + else: # convert for tar @@ -85,6 +86,7 @@ class Tarball: tar.close() self.__tar = tarfile.TarFile(name=tmp_name, mode=mode) + finally: tmp_fo.close() os.unlink(tmp_name) @@ -92,6 +94,7 @@ class Tarball: if mtime: self.mtime = mtime + else: self.mtime = time.time() @@ -106,8 +109,10 @@ class Tarball: def read(self, arcname): """Returns sring with content of given file from tarball.""" file_o = self.__tar.extractfile(arcname.encode('utf8')) + if not file_o: return None + out = file_o.read() file_o.close() return out diff --git a/toolkit/temposlider.py b/toolkit/temposlider.py index 44b23d2..d2bf3ad 100644 --- a/toolkit/temposlider.py +++ b/toolkit/temposlider.py @@ -14,46 +14,54 @@ # Widget was copy&pasted from TamTam activities -import gtk -import rsvg +import gi +from gi.repository import Gtk +from gi.repository import GdkPixbuf +from gi.repository import Rsvg + import cairo -from sugar.graphics import style +from sugar3.graphics import style -class TempoSlider(gtk.HBox): +class TempoSlider(Gtk.HBox): + def __init__(self, min_value, max_value): - gtk.HBox.__init__(self) + + Gtk.HBox.__init__(self) self._pixbuf = [None] * 8 - self._image = gtk.Image() + self._image = Gtk.Image() self._image.show() # used to store tempo updates while the slider is active self._delayed = 0 self._active = False - self.adjustment = gtk.Adjustment(min_value, min_value, max_value, - (max_value - min_value) / 8, (max_value - min_value) / 8, 0) + self.adjustment = Gtk.Adjustment(min_value, min_value, max_value, + (max_value - min_value) / 8, (max_value - min_value) / 8, 0) self._adjustment_h = self.adjustment.connect('value-changed', self._changed_cb) - slider = gtk.HScale(adjustment = self.adjustment) + slider = Gtk.HScale(adjustment = self.adjustment) slider.show() slider.set_draw_value(False) slider.connect("button-press-event", self._press_cb) slider.connect("button-release-event", self._release_cb) - self.pack_start(slider, True, True) - self.pack_end(self._image, False, False) + self.pack_start(slider, True, True, 0) + self.pack_end(self._image, False, False, 0) def set_value(self, tempo, quiet = False): + if self._active: self._delayed = tempo + elif quiet: self.adjustment.handler_block(self._adjustment_h) self.adjustment.set_value(tempo) self._update(tempo) self.adjustment.handler_unblock(self._adjustment_h) + else: self.adjustment.set_value(tempo) @@ -61,20 +69,23 @@ class TempoSlider(gtk.HBox): self._update(widget.get_value()) def _update(self, tempo): + def map_range(value, ilower, iupper, olower, oupper): if value == iupper: return oupper + return olower + int((oupper-olower+1) * (value-ilower) / - float(iupper-ilower)) + float(iupper-ilower)) - img = map_range(tempo, self.adjustment.lower, - self.adjustment.upper, 0, 7) + img = map_range(tempo, self.adjustment.get_lower(), + self.adjustment.get_upper(), 0, 7) if not self._pixbuf[img]: - svg = rsvg.Handle(data=IMAGE[img]) + svg = Rsvg.Handle() + svg.new_from_data(IMAGE[img]) self._pixbuf[img] = _from_svg_at_size(handle=svg, - width=style.STANDARD_ICON_SIZE, - height=style.STANDARD_ICON_SIZE) + width=style.STANDARD_ICON_SIZE, + height=style.STANDARD_ICON_SIZE) self._image.set_from_pixbuf(self._pixbuf[img]) @@ -82,6 +93,7 @@ class TempoSlider(gtk.HBox): self._active = True def _release_cb(self, widget, event): + self._active = False if self._delayed != 0: self.set_value(self._delayed, True) @@ -92,24 +104,30 @@ def _from_svg_at_size(filename=None, width=None, height=None, handle=None, """ import from pixbuf.py """ if not handle: - handle = rsvg.Handle(filename) - - dimensions = handle.get_dimension_data() - icon_width = dimensions[0] - icon_height = dimensions[1] - - if icon_width != width or icon_height != height: + svg = Rsvg.Handle() + svg.new_from_file(IMAGE[img]) + + dimensions = handle.get_dimensions() + icon_width = dimensions.height + icon_height = dimensions.width + + if (icon_width != width or icon_height != height) and \ + icon_width != 0 and icon_height != 0: + ratio_width = float(width) / icon_width ratio_height = float(height) / icon_height if keep_ratio: ratio = min(ratio_width, ratio_height) + if ratio_width != ratio: ratio_width = ratio width = int(icon_width * ratio) + elif ratio_height != ratio: ratio_height = ratio height = int(icon_height * ratio) + else: ratio_width = 1 ratio_height = 1 @@ -119,7 +137,7 @@ def _from_svg_at_size(filename=None, width=None, height=None, handle=None, context.scale(ratio_width, ratio_height) handle.render_cairo(context) - loader = gtk.gdk.pixbuf_loader_new_with_mime_type('image/png') + loader = GdkPixbuf.PixbufLoader.new_with_mime_type('image/png') surface.write_to_png(loader) loader.close() diff --git a/toolkit/toolbarbox.py b/toolkit/toolbarbox.py index 7172b8b..923bed1 100644 --- a/toolkit/toolbarbox.py +++ b/toolkit/toolbarbox.py @@ -15,12 +15,13 @@ # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. -import gtk -import gobject +import gi +from gi.repository import Gtk +from gi.repository import GObject -from sugar.graphics import style -from sugar.graphics.toolbutton import ToolButton -from sugar.graphics import palettegroup +from sugar3.graphics import style +from sugar3.graphics.toolbutton import ToolButton +from sugar3.graphics import palettegroup from toolkit.internals.palettewindow import PaletteWindow from toolkit.internals.palettewindow import ToolInvoker @@ -31,8 +32,9 @@ _LINE_WIDTH = 2 class ToolbarButton(ToolButton): - def __init__(self, page=None, **kwargs): - ToolButton.__init__(self, **kwargs) + def __init__(self, page=None): + + ToolButton.__init__(self) self.page_widget = None @@ -43,31 +45,36 @@ class ToolbarButton(ToolButton): self.connect('size-allocate', self.__size_allocate_cb) def get_toolbar_box(self): + if not hasattr(self.parent, 'owner'): return None + return self.parent.owner toolbar_box = property(get_toolbar_box) def get_page(self): + if self.page_widget is None: return None + return _get_embedded_page(self.page_widget) def set_page(self, page): + if page is None: self.page_widget = None return self.page_widget, alignment_ = _embed_page(_Box, page) - w_, h = gtk.icon_size_lookup(gtk.ICON_SIZE_LARGE_TOOLBAR) + w_, h = Gtk.icon_size_lookup(Gtk.IconSize.LARGE_TOOLBAR) page.show() if self.props.palette is None: self.props.palette = _ToolbarPalette(invoker=ToolInvoker(self)) self._move_page_to_palette() - page = gobject.property(type=object, getter=get_page, setter=set_page) + page = GObject.property(type=object, getter=get_page, setter=set_page) def is_in_palette(self): return self.page is not None and \ @@ -97,14 +104,15 @@ class ToolbarButton(ToolButton): if box.expanded_button.window is not None: # need to redraw it to erase arrow box.expanded_button.window.invalidate_rect(None, True) + box.expanded_button.set_expanded(False) box.expanded_button = self self._unparent() - self.modify_bg(gtk.STATE_NORMAL, box.background) + self.modify_bg(Gtk.StateType.NORMAL, box.background) _setup_page(self.page_widget, box.background, box.props.padding) - box.pack_start(self.page_widget) + box.pack_start(self.page_widget, False, False, 0) def _move_page_to_palette(self): if self.is_in_palette(): @@ -121,50 +129,53 @@ class ToolbarButton(ToolButton): self.page_widget.parent.remove(self.page_widget) def do_expose_event(self, event): + if not self.is_expanded() or self.props.palette is not None and \ self.props.palette.is_up(): ToolButton.do_expose_event(self, event) - _paint_arrow(self, event, gtk.ARROW_DOWN) + _paint_arrow(self, event, Gtk.ArrowType.DOWN) return alloc = self.allocation self.get_style().paint_box(event.window, - gtk.STATE_NORMAL, gtk.SHADOW_IN, event.area, self, + Gtk.StateType.NORMAL, Gtk.ShadowType.IN, event.area, self, 'palette-invoker', alloc.x, 0, alloc.width, alloc.height + _LINE_WIDTH) - if self.child.state != gtk.STATE_PRELIGHT: + if self.child.state != Gtk.StateType.PRELIGHT: self.get_style().paint_box(event.window, - gtk.STATE_NORMAL, gtk.SHADOW_NONE, event.area, self, None, - alloc.x + _LINE_WIDTH, _LINE_WIDTH, - alloc.width - _LINE_WIDTH * 2, alloc.height) + Gtk.StateType.NORMAL, Gtk.ShadowType.NONE, event.area, self, None, + alloc.x + _LINE_WIDTH, _LINE_WIDTH, + alloc.width - _LINE_WIDTH * 2, alloc.height) - gtk.ToolButton.do_expose_event(self, event) - _paint_arrow(self, event, gtk.ARROW_UP) + Gtk.ToolButton.do_expose_event(self, event) + _paint_arrow(self, event, Gtk.ArrowType.UP) def __size_allocate_cb(self, button, allocation): if self.page_widget is not None: self.page_widget.set_size_request(-1, allocation.height) -class ToolbarBox(gtk.VBox): +class ToolbarBox(Gtk.VBox): def __init__(self, padding=style.TOOLBOX_HORIZONTAL_PADDING): - gtk.VBox.__init__(self) + + Gtk.VBox.__init__(self) + self._expanded_button_index = -1 self.background = None - self._toolbar = gtk.Toolbar() + self._toolbar = Gtk.Toolbar() self._toolbar.owner = self self._toolbar.connect('remove', self.__remove_cb) self._toolbar_widget, self._toolbar_alignment = \ - _embed_page(gtk.EventBox, self._toolbar) - self.pack_start(self._toolbar_widget) + _embed_page(Gtk.EventBox, self._toolbar) + self.pack_start(self._toolbar_widget, False, False, 0) self.props.padding = padding - self.modify_bg(gtk.STATE_NORMAL, + self.modify_bg(Gtk.StateType.NORMAL, style.COLOR_TOOLBAR_GREY.get_gdk_color()) def get_toolbar(self): @@ -173,14 +184,18 @@ class ToolbarBox(gtk.VBox): toolbar = property(get_toolbar) def get_expanded_button(self): + if self._expanded_button_index == -1: return None + return self.toolbar.get_nth_item(self._expanded_button_index) def set_expanded_button(self, button): + if not button in self.toolbar: self._expanded_button_index = -1 return + self._expanded_button_index = self.toolbar.get_item_index(button) expanded_button = property(get_expanded_button, set_expanded_button) @@ -191,19 +206,24 @@ class ToolbarBox(gtk.VBox): def set_padding(self, pad): self._toolbar_alignment.set_padding(0, 0, pad, pad) - padding = gobject.property(type=object, + padding = GObject.property(type=object, getter=get_padding, setter=set_padding) def modify_bg(self, state, color): - if state == gtk.STATE_NORMAL: + + if state == Gtk.StateType.NORMAL: self.background = color + self._toolbar_widget.modify_bg(state, color) self.toolbar.modify_bg(state, color) def __remove_cb(self, sender, button): + if not isinstance(button, ToolbarButton): return + button.popdown() + if button == self.expanded_button: self.remove(button.page_widget) self._expanded_button_index = -1 @@ -211,8 +231,9 @@ class ToolbarBox(gtk.VBox): class _ToolbarPalette(PaletteWindow): - def __init__(self, **kwargs): - PaletteWindow.__init__(self, **kwargs) + def __init__(self): + + PaletteWindow.__init__(self) self.set_border_width(0) self._has_focus = False @@ -242,24 +263,30 @@ class _ToolbarPalette(PaletteWindow): self._set_focus(False) def _set_focus(self, new_focus): + self._has_focus = new_focus + if not self._has_focus: group = palettegroup.get_group('default') if not group.is_up(): self.popdown() def do_size_request(self, requisition): - gtk.Window.do_size_request(self, requisition) + + Gtk.Window.do_size_request(self, requisition) requisition.width = max(requisition.width, - gtk.gdk.screen_width()) + Gdk.screen_width()) def popup(self, immediate=False): + button = self.expanded_button + if button.is_expanded(): return + box = button.toolbar_box _setup_page(button.page_widget, style.COLOR_BLACK.get_gdk_color(), - box.props.padding) + box.props.padding) PaletteWindow.popup(self, immediate) def __group_popdown_cb(self, group): @@ -267,52 +294,59 @@ class _ToolbarPalette(PaletteWindow): self.popdown(immediate=True) -class _Box(gtk.EventBox): +class _Box(Gtk.EventBox): def __init__(self): - gtk.EventBox.__init__(self) + + Gtk.EventBox.__init__(self) self.connect('expose-event', self.do_expose_event) self.set_app_paintable(True) def do_expose_event(self, widget, event): + if self.parent.expanded_button is None: return + alloc = self.parent.expanded_button.allocation self.get_style().paint_box(event.window, - gtk.STATE_NORMAL, gtk.SHADOW_IN, event.area, self, - 'palette-invoker', -_LINE_WIDTH, 0, - self.allocation.width + _LINE_WIDTH * 2, - self.allocation.height + _LINE_WIDTH) + Gtk.StateType.NORMAL, Gtk.ShadowType.IN, event.area, self, + 'palette-invoker', -_LINE_WIDTH, 0, + self.allocation.width + _LINE_WIDTH * 2, + self.allocation.height + _LINE_WIDTH) + self.get_style().paint_box(event.window, - gtk.STATE_NORMAL, gtk.SHADOW_NONE, event.area, self, None, - alloc.x + _LINE_WIDTH, 0, - alloc.width - _LINE_WIDTH * 2, _LINE_WIDTH) + Gtk.StateType.NORMAL, Gtk.ShadowType.NONE, event.area, self, None, + alloc.x + _LINE_WIDTH, 0, + alloc.width - _LINE_WIDTH * 2, _LINE_WIDTH) def _setup_page(page_widget, color, hpad): + vpad = _LINE_WIDTH page_widget.child.set_padding(vpad, vpad, hpad, hpad) page = _get_embedded_page(page_widget) - page.modify_bg(gtk.STATE_NORMAL, color) - if isinstance(page, gtk.Container): + page.modify_bg(Gtk.StateType.NORMAL, color) + + if isinstance(page, Gtk.Container): for i in page.get_children(): - i.modify_bg(gtk.STATE_INSENSITIVE, color) + i.modify_bg(Gtk.StateType.INSENSITIVE, color) - page_widget.modify_bg(gtk.STATE_NORMAL, color) - page_widget.modify_bg(gtk.STATE_PRELIGHT, color) + page_widget.modify_bg(Gtk.StateType.NORMAL, color) + page_widget.modify_bg(Gtk.StateType.PRELIGHT, color) def _embed_page(box_class, page): page.show() - alignment = gtk.Alignment(0.0, 0.0, 1.0, 1.0) + alignment = Gtk.Alignment() + alignment.set(0.0, 0.0, 1.0, 1.0) alignment.add(page) alignment.show() page_widget = box_class() - page_widget.modify_bg(gtk.STATE_ACTIVE, - style.COLOR_BUTTON_GREY.get_gdk_color()) + page_widget.modify_bg(Gtk.StateType.ACTIVE, + style.COLOR_BUTTON_GREY.get_gdk_color()) page_widget.add(alignment) page_widget.show() @@ -329,5 +363,5 @@ def _paint_arrow(widget, event, arrow_type): y = alloc.y + alloc.height - int(_ARROW_SIZE * .85) widget.get_style().paint_arrow(event.window, - gtk.STATE_NORMAL, gtk.SHADOW_NONE, event.area, widget, - None, arrow_type, True, x, y, _ARROW_SIZE, _ARROW_SIZE) + Gtk.StateType.NORMAL, Gtk.ShadowType.NONE, event.area, widget, + None, arrow_type, True, x, y, _ARROW_SIZE, _ARROW_SIZE) diff --git a/toolkit/toolitem.py b/toolkit/toolitem.py index e490c22..945495e 100644 --- a/toolkit/toolitem.py +++ b/toolkit/toolitem.py @@ -17,30 +17,30 @@ """A set of toolitem widets""" -import gtk -import gobject +import gi +from gi.repository import Gtk +from gi.repository import GObject -from sugar.graphics import style +from sugar3.graphics import style -from toolkit.combobox import ComboBox +# FIXME: This class is not being used. +class ToolWidget(Gtk.ToolItem): - -class ToolWidget(gtk.ToolItem): - - def __init__(self, **kwargs): + def __init__(self): + self._widget = None self._label = None self._label_text = None - self._box = gtk.HBox(False, style.DEFAULT_SPACING) + self._box = Gtk.HBox(False, style.DEFAULT_SPACING) - gobject.GObject.__init__(self, **kwargs) + GObject.GObject.__init__(self) self.props.border_width = style.DEFAULT_PADDING self._box.show() self.add(self._box) if self.label is None: - self.label = gtk.Label() + self.label = Gtk.Label() def get_label_text(self): return self._label_text @@ -50,30 +50,34 @@ class ToolWidget(gtk.ToolItem): if self.label is not None and value: self.label.set_text(self._label_text) - label_text = gobject.property(getter=get_label_text, setter=set_label_text) + label_text = GObject.property(getter=get_label_text, setter=set_label_text) def get_label(self): return self._label def set_label(self, label): + if self._label is not None: self._box.remove(self._label) + self._label = label - self._box.pack_start(label, False) + self._box.pack_start(label, False, False, 0) self._box.reorder_child(label, 0) label.show() self.set_label_text(self._label_text) - label = gobject.property(getter=get_label, setter=set_label) + label = GObject.property(getter=get_label, setter=set_label) def get_widget(self): return self._widget def set_widget(self, widget): + if self._widget is not None: self._box.remove(self._widget) + self._widget = widget - self._box.pack_end(widget) + self._box.pack_end(widget, False, False, 0) widget.show() - widget = gobject.property(getter=get_widget, setter=set_widget) + widget = GObject.property(getter=get_widget, setter=set_widget) -- cgit v0.9.1