Ticket #3715: Initial-Gtk3-Port.diff

File Initial-Gtk3-Port.diff, 43.9 KB (added by humitos, 12 years ago)

This is like a backup of my work in progress migration

  • anim.py

    diff --git a/anim.py b/anim.py
    index 2c19a15..f34406e 100644
    a b  
    1616# along with this program; if not, write to the Free Software
    1717# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    1818
    19 import gobject
     19from gi.repository import GObject
    2020
    2121# Animation timer interval (in msec)
    2222_TIMER_INTERVAL = 20
    class Anim(object): 
    3434    def start(self):
    3535        self._animating = True
    3636        self._update_func()
    37         gobject.timeout_add(_TIMER_INTERVAL, self._timer)
     37        GObject.timeout_add(_TIMER_INTERVAL, self._timer)
    3838
    3939    def stop(self):
    4040        if self._animating:
  • gridwidget.py

    diff --git a/gridwidget.py b/gridwidget.py
    index 8ee3aad..470f37c 100644
    a b import logging 
    2020_logger = logging.getLogger('implode-activity.gridwidget')
    2121
    2222import cairo
    23 import gobject
    24 import gtk
     23from gi.repository import GObject
     24from gi.repository import Gtk
     25from gi.repository import Gdk
    2526import math
    2627import random
    2728import time
    _ANIM_STAGES = [ 
    7980# Animation time scaling factor (in seconds per tick).
    8081_ANIM_SCALE = 0.04
    8182
    82 #import traceback
    83 #def _log_errors(func):
    84 #    # A function decorator to add error logging to selected functions.
    85 #    # (For when GTK eats exceptions).
    86 #    def wrapper(*args, **kwargs):
    87 #        try:
    88 #            return func(*args, **kwargs)
    89 #        except:
    90 #            _logger.debug(traceback.format_exc())
    91 #            raise
    92 #    return wrapper
    93 def _log_errors(func):
    94     return func
    95 
    96 class GridWidget(gtk.DrawingArea):
     83
     84class GridWidget(Gtk.DrawingArea):
    9785    """Gtk widget for rendering the game board."""
    9886
    9987    __gsignals__ = {
    100         'piece-selected'  : (gobject.SIGNAL_RUN_LAST, None, (int, int)),
    101         'undo-key-pressed': (gobject.SIGNAL_RUN_LAST, None, (int,)),
    102         'redo-key-pressed': (gobject.SIGNAL_RUN_LAST, None, (int,)),
    103         'new-key-pressed' : (gobject.SIGNAL_RUN_LAST, None, (int,)),
     88        'piece-selected'  : (GObject.SignalFlags.RUN_LAST, None, (int, int)),
     89        'undo-key-pressed': (GObject.SignalFlags.RUN_LAST, None, (int,)),
     90        'redo-key-pressed': (GObject.SignalFlags.RUN_LAST, None, (int,)),
     91        'new-key-pressed' : (GObject.SignalFlags.RUN_LAST, None, (int,)),
    10492        'button-press-event': 'override',
    10593        'key-press-event': 'override',
    106         'expose-event': 'override',
     94        # 'expose-event': 'override',
     95
     96        # 'draw': 'override',
     97        # 'configure-event': 'override',
     98
    10799        'size-allocate': 'override',
    108100        'motion-notify-event': 'override',
    109101    }
    110102
    111103    def __init__(self, *args, **kwargs):
    112104        super(GridWidget, self).__init__(*args, **kwargs)
    113         self.set_events(gtk.gdk.BUTTON_PRESS_MASK
    114                         | gtk.gdk.POINTER_MOTION_MASK
    115                         | gtk.gdk.KEY_PRESS_MASK)
    116         self.set_flags(gtk.CAN_FOCUS)
     105        self.set_events(Gdk.EventMask.BUTTON_PRESS_MASK
     106                        | Gdk.EventMask.POINTER_MOTION_MASK
     107                        | Gdk.EventMask.KEY_PRESS_MASK)
     108        # self.set_flags(Gtk.CAN_FOCUS)
    117109
    118110        self._board_drawer = BoardDrawer(self._get_size, self._invalidate_rect)
    119111        self._win_drawer = WinDrawer(self._get_size, self._invalidate_rect)
    120112        self._removal_drawer = RemovalDrawer(self._get_size, self._invalidate_rect)
    121113        self._set_current_drawer(self._board_drawer)
    122114
     115        self.connect('draw', self.do_draw_event)
     116
    123117    def _get_size(self):
    124         return (self.allocation.width, self.allocation.height)
     118        return (self.get_allocated_width(), self.get_allocated_height())
    125119
    126120    def _invalidate_rect(self, rect):
    127         if self.window:
    128             self.window.invalidate_rect(rect, True)
     121        if self.get_window():
     122            self.get_window().invalidate_rect(rect, True)
    129123
    130124    def set_board(self, board):
    131125        self._board_drawer.set_board(board)
    class GridWidget(gtk.DrawingArea): 
    141135
    142136    def _invalidate_board(self):
    143137        (width, height) = self._get_size()
    144         self._invalidate_rect(gtk.gdk.Rectangle(0, 0, width, height))
     138        rect = Gdk.Rectangle()
     139        rect.x, rect.y, rect.width, rect.height = (0, 0, width, height)
     140        self._invalidate_rect(rect)
    145141
    146142    def get_win_draw_flag(self):
    147143        return (self._current_drawer is self._win_drawer)
    class GridWidget(gtk.DrawingArea): 
    159155    def select_center_cell(self):
    160156        self._board_drawer.select_center_cell()
    161157
    162     @_log_errors
    163158    def do_button_press_event(self, event):
    164159        # Ignore mouse clicks while animating.
    165160        if self._is_animating():
    166161            return True
    167162        # Ignore double- and triple-clicks.
    168         if event.type != gtk.gdk.BUTTON_PRESS:
     163        if event.type != Gdk.EventType.BUTTON_PRESS:
    169164            return True
    170165        self.grab_focus()
    171166        self._board_drawer.set_mouse_selection(event.x, event.y)
    class GridWidget(gtk.DrawingArea): 
    174169            self.emit('piece-selected', *selected_cell)
    175170        return True
    176171
    177     @_log_errors
    178172    def do_key_press_event(self, event):
    179173        action = KEY_MAP.get(event.keyval, None)
    180174        if action == 'new':
    class GridWidget(gtk.DrawingArea): 
    209203                    else:
    210204                        return False
    211205
    212     @_log_errors
    213206    def do_motion_notify_event(self, event):
    214207        # Ignore mouse motion while animating.
    215208        if self._is_animating():
    class GridWidget(gtk.DrawingArea): 
    219212        else:
    220213            x = event.x
    221214            y = event.y
    222             state = event.state
     215            state = event.get_state()
    223216        self._board_drawer.set_mouse_selection(x, y)
    224217
    225     @_log_errors
    226     def do_expose_event(self, event):
    227         cr = self.window.cairo_create()
     218    def do_draw_event(self, event):
     219        logging.debug('do_draw_event()')
     220        cr = self.get_window().cairo_create()
    228221        cr.rectangle(event.area.x,
    229222                     event.area.y,
    230223                     event.area.width,
    231224                     event.area.height)
    232225        cr.clip()
    233         (width, height) = self.window.get_size()
     226        (width, height) = self.get_window().get_size()
    234227        self._current_drawer.draw(cr, width, height)
    235228
    236     @_log_errors
    237229    def do_size_allocate(self, allocation):
    238         super(GridWidget, self).do_size_allocate(self, allocation)
     230        # super(GridWidget, self).do_size_allocate(self, allocation)
     231        logging.debug('do_size_allocate(): %s, %s', allocation.width, allocation.height)
     232        self.allocation = allocation
    239233        self._current_drawer.resize(allocation.width, allocation.height)
    240234
    241235    def _set_current_drawer(self, drawer):
    class BoardDrawer(object): 
    382376
    383377    def _invalidate_board(self):
    384378        (width, height) = self._get_size_func()
    385         rect = gtk.gdk.Rectangle(0, 0, width, height)
     379        rect = Gdk.Rectangle()
     380        rect.x, rect.y, rect.width, rect.height = (0, 0, width, height)
    386381        self._invalidate_rect_func(rect)
    387382
    388383    def _invalidate_selection(self, selection_coord):
    class BoardDrawer(object): 
    407402        max_x2 = math.ceil( max(pt1[0], pt2[0])) + 1
    408403        min_y2 = math.floor(min(pt1[1], pt2[1])) - 1
    409404        max_y2 = math.ceil( max(pt1[1], pt2[1])) + 1
    410         rect = gtk.gdk.Rectangle(int(min_x2),
     405        rect = Gdk.Rectangle()
     406        rect.x, rect.y, rect.width, rect.height = (int(min_x2),
    411407                                 int(min_y2),
    412408                                 int(max_x2 - min_x2),
    413409                                 int(max_y2 - min_y2))
    class BoardDrawer(object): 
    425421        if not self.board_is_valid():
    426422            self._board_transform = _BoardTransform()
    427423        else:
     424            # logging.debug('width: %s, height: %s | self._board_width: %s, self._board_height: %s',
     425            #               width, height, self._board_width, self._board_height)
    428426            self._board_transform = _BoardTransform()
    429             self._board_transform.setup(width,
    430                                        height,
    431                                        self._board_width,
    432                                        self._board_height)
     427            self._board_transform.setup(width, height, self._board_width,
     428                                        self._board_height)
    433429
    434430    def draw(self, cr, width, height):
    435431        # Draws the widget.
    class RemovalDrawer(object): 
    564560
    565561    def _invalidate_board(self):
    566562        (width, height) = self._get_size_func()
    567         rect = gtk.gdk.Rectangle(0, 0, width, height)
     563        rect = Gdk.Rectangle()
     564        rect.x, rect.y, rect.width, rect.height = (0, 0, width, height)
    568565        self._invalidate_rect_func(rect)
    569566
    570567    def _recalc_game_anim_frames(self):
    class WinDrawer(object): 
    810807
    811808    def _invalidate_board(self):
    812809        (width, height) = self._get_size_func()
    813         rect = gtk.gdk.Rectangle(0, 0, width, height)
     810        rect = Gdk.Rectangle()
     811        rect.x, rect.y, rect.width, rect.height = (0, 0, width, height)
    814812        self._invalidate_rect_func(rect)
    815813
    816814    def _get_win_tiles(self):
  • helpwidget.py

    diff --git a/helpwidget.py b/helpwidget.py
    index af205e6..c4a2919 100644
    a b from __future__ import with_statement 
    2121from gettext import gettext as _
    2222
    2323import cairo
    24 import gobject
    25 import gtk
     24
     25from gi.repository import GObject
     26from gi.repository import Gtk
     27from gi.repository import Gdk
     28from gi.repository import Rsvg
     29
    2630import math
    2731import os
    28 import rsvg
    2932import time
    3033
    3134import board
    from anim import Anim 
    3336from gridwidget import BoardDrawer, RemovalDrawer, WinDrawer
    3437
    3538if 'SUGAR_BUNDLE_PATH' in os.environ:
    36     from sugar.graphics import style
     39    from sugar3.graphics import style
    3740    _DEFAULT_SPACING = style.DEFAULT_SPACING
    3841    _DEFAULT_PADDING = style.DEFAULT_PADDING
    3942    _BG_COLOR = tuple(style.COLOR_SELECTION_GREY.get_rgba()[:3])
    _CLICK_SPEED = 0.2 
    7578# Speed of the mouse, in units (4x3 per screen) per second.
    7679_MOUSE_SPEED = 0.5
    7780
    78 class HelpWidget(gtk.EventBox):
     81class HelpWidget(Gtk.EventBox):
    7982    def __init__(self, icon_file_func, *args, **kwargs):
    8083        super(HelpWidget, self).__init__(*args, **kwargs)
    8184
    82         vbox = gtk.VBox()
     85        vbox = Gtk.VBox()
    8386        self.add(vbox)
    8487
    8588        self._stages = [
    class HelpWidget(gtk.EventBox): 
    9093            _HelpStage5(icon_file_func),
    9194        ]
    9295        self._stage_index = 0
    93         self._notebook = gtk.Notebook()
     96        self._notebook = Gtk.Notebook()
    9497        self._notebook.set_show_tabs(False)
    9598        for stage in self._stages:
    96             self._notebook.append_page(stage)
    97         vbox.pack_start(self._notebook)
     99            self._notebook.append_page(stage, None)
     100        vbox.pack_start(self._notebook, True, True, 0)
    98101
    99102        self._reset_current_stage()
    100103
    class HelpWidget(gtk.EventBox): 
    128131        self._stages[self._stage_index].reset()
    129132
    130133
    131 class _HelpStage(gtk.EventBox):
     134class _HelpStage(Gtk.EventBox):
    132135    # An abstract parent class for objects that represent an animated help
    133136    # screen widget with a description.
    134137    def __init__(self, icon_file_func, *args, **kwargs):
    135138        super(_HelpStage, self).__init__(*args, **kwargs)
    136139
    137         hbox = gtk.HBox()
     140        hbox = Gtk.HBox()
    138141        self.add(hbox)
    139142
    140         vbox = gtk.VBox()
    141         hbox.pack_start(vbox, expand=True, padding=_DEFAULT_SPACING)
     143        vbox = Gtk.VBox()
     144        hbox.pack_start(vbox, expand=True, fill=False,
     145                        padding=_DEFAULT_SPACING)
    142146
    143147        self.preview = _PreviewWidget(icon_file_func)
    144         vbox.pack_start(self.preview, expand=True, padding=_DEFAULT_PADDING)
     148        vbox.pack_start(self.preview, expand=True, fill=False,
     149                        padding=_DEFAULT_PADDING)
    145150
    146         label = gtk.Label(self.get_message())
     151        label = Gtk.Label(label=self.get_message())
    147152        label.set_line_wrap(True)
    148         vbox.pack_start(label, expand=False, padding=_DEFAULT_PADDING)
     153        vbox.pack_start(label, expand=False, fill=False,
     154                        padding=_DEFAULT_PADDING)
    149155
    150156        self.board = None
    151157        self.undo_stack = []
    def _undo(): 
    552558        stage.next_action()
    553559    return action
    554560
    555 class _PreviewWidget(gtk.DrawingArea):
     561class _PreviewWidget(Gtk.DrawingArea):
    556562    __gsignals__ = {
    557         'expose-event': 'override',
     563        # 'expose-event': 'override',
    558564        'size-allocate': 'override',
    559565    }
    560566
    class _PreviewWidget(gtk.DrawingArea): 
    573579
    574580        self._icon_file_func = icon_file_func
    575581
    576         self._preview_rect = gtk.gdk.Rectangle(0, 0, 0, 0)
    577         self._toolbar_rect = gtk.gdk.Rectangle(0, 0, 0, 0)
    578         self._drawer_rect = gtk.gdk.Rectangle(0, 0, 0, 0)
     582        # self._preview_rect = (0, 0, 0, 0)
     583        # self._toolbar_rect = (0, 0, 0, 0)
     584        # self._drawer_rect = (0, 0, 0, 0)
     585
     586        self._preview_rect = Gdk.Rectangle()
     587        self._preview_rect.x = self._preview_rect.y = \
     588            self._preview_rect.width = self._preview_rect.height = 0
     589
     590        self._toolbar_rect = Gdk.Rectangle()
     591        self._toolbar_rect.x = self._toolbar_rect.y = \
     592            self._toolbar_rect.width = self._toolbar_rect.height = 0
     593
     594        self._drawer_rect = Gdk.Rectangle()
     595        self._drawer_rect.x = self._drawer_rect.y = \
     596            self._drawer_rect.width = self._drawer_rect.height = 0
    579597
    580598        self._drawer = self.board_drawer
    581599
    class _PreviewWidget(gtk.DrawingArea): 
    593611        return (self._drawer_rect.width, self._drawer_rect.height)
    594612
    595613    def _invalidate_drawer_rect(self, rect):
    596         if self.window:
     614        if self.get_window():
    597615            (x, y) = (self._drawer_rect.x, self._drawer_rect.y)
    598             offset_rect = gtk.gdk.Rectangle(rect.x + x,
    599                                             rect.y + y,
    600                                             rect.width,
    601                                             rect.height)
    602             self.window.invalidate_rect(offset_rect, True)
     616            rect = Gdk.Rectangle()
     617            rect.x, rect.y, rect.width, rect.height = (
     618                rect.x + x,
     619                rect.y + y,
     620                rect.width,
     621                rect.height)
     622            self.get_window().invalidate_rect(rect, True)
    603623
    604624    def set_drawer(self, drawer):
    605625        self._drawer = drawer
    class _PreviewWidget(gtk.DrawingArea): 
    667687        self._invalidate_client_rect(pixel_x - r, pixel_y - r, r2, r2)
    668688
    669689    def _invalidate_client_rect(self, x, y, width, height):
    670         if self.window:
    671             rect = gtk.gdk.Rectangle(
     690        if self.get_window():
     691            rect = Gdk.Rectangle()
     692            rect.x, rect.y, rect.width, rect.height = (
    672693                int(math.floor(x)) + self._preview_rect.x,
    673694                int(math.floor(y)) + self._preview_rect.y,
    674695                int(math.ceil(width)) + 1,
    675696                int(math.ceil(height)) + 1)
    676             self.window.invalidate_rect(rect, True)
     697            self.get_window().invalidate_rect(rect, True)
    677698
    678699    def _update_mouse_position(self):
    679700        (pixel_x, pixel_y) = self._get_cursor_pixel_coords()
    class _PreviewWidget(gtk.DrawingArea): 
    681702        self.board_drawer.set_mouse_selection(x, y)
    682703
    683704    def do_expose_event(self, event):
    684         cr = self.window.cairo_create()
     705        cr = self.get_window().cairo_create()
    685706        cr.rectangle(event.area.x,
    686707                     event.area.y,
    687708                     event.area.width,
    688709                     event.area.height)
    689710        cr.clip()
    690         (width, height) = self.window.get_size()
     711        (width, height) = self.get_window().get_size()
    691712        self._draw(cr, width, height)
    692713
    693714    def _draw(self, cr, width, height):
    class _PreviewWidget(gtk.DrawingArea): 
    804825        cr.restore()
    805826
    806827    def do_size_allocate(self, allocation):
    807         super(_PreviewWidget, self).do_size_allocate(self, allocation)
     828        # super(_PreviewWidget, self).do_size_allocate(self, allocation)
    808829        (width, height) = (allocation.width, allocation.height)
    809830
    810831        avail_width = width - _DEFAULT_SPACING * 2
    class _PreviewWidget(gtk.DrawingArea): 
    829850        old_width = self._preview_rect.width
    830851        old_height = self._preview_rect.height
    831852
    832         self._preview_rect = gtk.gdk.Rectangle(x_offset,
    833                                                y_offset,
    834                                                actual_width,
    835                                                actual_height)
    836         self._toolbar_rect = gtk.gdk.Rectangle(x_offset,
    837                                                y_offset,
    838                                                actual_width,
    839                                                icon_height)
    840         self._drawer_rect = gtk.gdk.Rectangle(x_offset,
    841                                               y_offset + icon_height,
    842                                               actual_width,
    843                                               board_height)
     853        # self._preview_rect = (x_offset,
     854        #                                        y_offset,
     855        #                                        actual_width,
     856        #                                        actual_height)
     857
     858        self._preview_rect = Gdk.Rectangle()
     859        self._preview_rect.x = x_offset
     860        self._preview_rect.y = y_offset
     861        self._preview_rect.width = actual_width
     862        self._preview_rect.height = actual_height
     863
     864        # self._toolbar_rect = (x_offset,
     865        #                                        y_offset,
     866        #                                        actual_width,
     867        #                                        icon_height)
     868
     869        self.toolbar_rect = Gdk.Rectangle()
     870        self.toolbar_rect.x = x_offset
     871        self.toolbar_rect.y = y_offset
     872        self.toolbar_rect.width = actual_width
     873        self.toolbar_rect.height = icon_height
     874
     875        # self._drawer_rect = (x_offset,
     876        #                                       y_offset + icon_height,
     877        #                                       actual_width,
     878        #                                       board_height)
     879
     880        self._drawer_rect = Gdk.Rectangle()
     881        self._drawer_rect.x = x_offset
     882        self._drawer_rect.y = y_offset + icon_height
     883        self._drawer_rect.width = actual_width
     884        self._drawer_rect.height = board_height
     885
    844886        self.board_drawer.resize(actual_width, board_height)
    845887        self.removal_drawer.resize(actual_width, board_height)
    846888        self.win_drawer.resize(actual_width, board_height)
    def _get_icon_handle(file_path): 
    886928    if file_path not in _icon_handles:
    887929        with open(file_path, 'r') as f:
    888930            data = f.read()
    889         _icon_handles[file_path] = rsvg.Handle(data=data)
     931        _icon_handles[file_path] = Rsvg.Handle.new_from_data(data)
    890932
    891933    return _icon_handles[file_path]
  • implodeactivity.py

    diff --git a/implodeactivity.py b/implodeactivity.py
    index 3e4cb2f..e3a4386 100644
    a b _logger = logging.getLogger('implode-activity') 
    2121
    2222from gettext import gettext as _
    2323
    24 from sugar.activity.activity import Activity, get_bundle_path
    25 from sugar.graphics import style
    26 from sugar.graphics.icon import Icon
    27 from sugar.graphics.radiotoolbutton import RadioToolButton
    28 from sugar.graphics.toolbutton import ToolButton
    29 
    30 try:
    31     # 0.86+ toolbar widgets
    32     from sugar.activity.widgets import ActivityToolbarButton, StopButton
    33     from sugar.graphics.toolbarbox import ToolbarBox, ToolbarButton
    34     _USE_OLD_TOOLBARS = False
    35 except ImportError:
    36     # Pre-0.86 toolbar widgets
    37     from sugar.activity.activity import ActivityToolbox
    38     _USE_OLD_TOOLBARS = True
     24from sugar3.activity.activity import Activity, get_bundle_path
     25from sugar3.graphics import style
     26from sugar3.graphics.icon import Icon
     27from sugar3.graphics.radiotoolbutton import RadioToolButton
     28from sugar3.graphics.toolbutton import ToolButton
     29
     30from sugar3.activity.widgets import ActivityToolbarButton, StopButton
     31from sugar3.graphics.toolbarbox import ToolbarBox, ToolbarButton
    3932
    4033from implodegame import ImplodeGame
    4134from helpwidget import HelpWidget
    4235
    4336import os
    4437
    45 try:
    46     import json
    47     json.dumps
    48 except (ImportError, AttributeError):
    49     import simplejson as json
     38import json
    5039from StringIO import StringIO
    51 import gtk
    52 import gobject
     40from gi.repository import Gtk
     41from gi.repository import GObject
     42from gi.repository import Gdk
    5343
    5444from keymap import KEY_MAP
    5545
    class ImplodeActivity(Activity): 
    6353
    6454        self._game = ImplodeGame()
    6555
    66         game_box = gtk.VBox()
    67         game_box.pack_start(self._game)
     56        game_box = Gtk.VBox()
     57        game_box.pack_start(self._game, True, True, 0)
    6858        self._stuck_strip = _StuckStrip()
    6959
    7060        self._configure_toolbars()
    class ImplodeActivity(Activity): 
    7363
    7464        # Show everything except the stuck strip.
    7565        self.show_all()
    76         game_box.pack_end(self._stuck_strip, expand=False)
     66        game_box.pack_end(self._stuck_strip, expand=False, fill=False, padding=0)
    7767
    7868        self._game.connect('show-stuck', self._show_stuck_cb)
    7969        self._stuck_strip.connect('undo-clicked', self._stuck_undo_cb)
    class ImplodeActivity(Activity): 
    121111        if data:
    122112            self._stuck_strip.show_all()
    123113        else:
    124             if self._stuck_strip.focus_child:
    125                 self._game.grab_focus()
     114            # if self._stuck_strip.focus_child:
     115            #     self._game.grab_focus()
     116            self._game.grab_focus()
    126117            self._stuck_strip.hide()
    127118
    128119    def _stuck_undo_cb(self, state, data=None):
    class ImplodeActivity(Activity): 
    133124        action = KEY_MAP.get(event.keyval, None)
    134125        if action is None:
    135126            return False
    136         if not self._stuck_strip.flags() & gtk.VISIBLE:
     127        if not self._stuck_strip.flags() & Gtk.VISIBLE:
    137128            return True
    138129        if self._game.focus_child:
    139130            if action == 'down':
    class ImplodeActivity(Activity): 
    152143        controls, difficulty selector, help button, and stop button. All
    153144        callbacks are locally defined."""
    154145
    155         if _USE_OLD_TOOLBARS:
    156             toolbox = ActivityToolbox(self)
    157             toolbar = gtk.Toolbar()
    158         else:
    159             toolbar_box = ToolbarBox()
    160             toolbar = toolbar_box.toolbar
     146        toolbar_box = ToolbarBox()
     147        toolbar = toolbar_box.toolbar
    161148
    162             activity_button = ActivityToolbarButton(self)
    163             toolbar_box.toolbar.insert(activity_button, 0)
    164             activity_button.show()
     149        activity_button = ActivityToolbarButton(self)
     150        toolbar_box.toolbar.insert(activity_button, 0)
     151        activity_button.show()
    165152
    166             toolbar.add(gtk.SeparatorToolItem())
     153        toolbar.add(Gtk.SeparatorToolItem())
    167154
    168155        def add_button(icon_name, tooltip, func):
    169156            def callback(source):
    class ImplodeActivity(Activity): 
    176163        add_button('new-game'   , _("New")   , self._game.new_game)
    177164        add_button('replay-game', _("Replay"), self._game.replay_game)
    178165
    179         toolbar.add(gtk.SeparatorToolItem())
     166        toolbar.add(Gtk.SeparatorToolItem())
    180167
    181168        add_button('edit-undo'  , _("Undo")  , self._game.undo)
    182169        add_button('edit-redo'  , _("Redo")  , self._game.redo)
    183170
    184         toolbar.add(gtk.SeparatorToolItem())
     171        toolbar.add(Gtk.SeparatorToolItem())
    185172
    186173        self._levels_buttons = []
    187174        def add_level_button(icon_name, tooltip, numeric_level):
    class ImplodeActivity(Activity): 
    217204        # right now, however.
    218205        add_button('help-icon', _("Help"), _help_clicked_cb)
    219206
    220         if _USE_OLD_TOOLBARS:
    221             toolbox.add_toolbar(_("Game"), toolbar)
    222             toolbox.set_current_toolbar(1)
    223 
    224             self.set_toolbox(toolbox)
    225             toolbox.show()
    226         else:
    227             stop_button = StopButton(self)
    228             stop_button.props.accelerator = '<Ctrl><Shift>Q'
    229             toolbar_box.toolbar.insert(stop_button, -1)
    230             stop_button.show()
     207        stop_button = StopButton(self)
     208        stop_button.props.accelerator = '<Ctrl><Shift>Q'
     209        toolbar_box.toolbar.insert(stop_button, -1)
     210        stop_button.show()
    231211
    232             self.set_toolbar_box(toolbar_box)
    233             toolbar_box.show()
     212        self.set_toolbar_box(toolbar_box)
     213        toolbar_box.show()
    234214
    235215    def _add_expander(self, toolbar, expand=True):
    236216        """Insert a toolbar item which will expand to fill the available
    237217        space."""
    238         separator = gtk.SeparatorToolItem()
     218        separator = Gtk.SeparatorToolItem()
    239219        separator.props.draw = False
    240220        separator.set_expand(expand)
    241221        toolbar.insert(separator, -1)
    242222        separator.show()
    243223
    244224
    245 class _DialogWindow(gtk.Window):
     225class _DialogWindow(Gtk.Window):
    246226    # A base class for a modal dialog window.
    247227    def __init__(self, icon_name, title):
    248228        super(_DialogWindow, self).__init__()
    249229
    250230        self.set_border_width(style.LINE_WIDTH)
    251231        offset = style.GRID_CELL_SIZE
    252         width = gtk.gdk.screen_width() / 2
    253         height = gtk.gdk.screen_height() / 2
     232        width = Gdk.Screen.width() / 2
     233        height = Gdk.Screen.height() / 2
    254234        self.set_size_request(width, height)
    255         self.set_position(gtk.WIN_POS_CENTER_ALWAYS)
     235        self.set_position(Gtk.WindowPosition.CENTER_ALWAYS)
    256236        self.set_decorated(False)
    257237        self.set_resizable(False)
    258238        self.set_modal(True)
    259239
    260         vbox = gtk.VBox()
     240        vbox = Gtk.VBox()
    261241        self.add(vbox)
    262242
    263243        toolbar = _DialogToolbar(icon_name, title)
    264244        toolbar.connect('stop-clicked', self._stop_clicked_cb)
    265         vbox.pack_start(toolbar, False)
     245        vbox.pack_start(toolbar, expand=False, fill=False, padding=0)
    266246
    267         self.content_vbox = gtk.VBox()
     247        self.content_vbox = Gtk.VBox()
    268248        self.content_vbox.set_border_width(style.DEFAULT_SPACING)
    269249        vbox.add(self.content_vbox)
    270250
    class _DialogWindow(gtk.Window): 
    274254        self.destroy()
    275255
    276256    def _realize_cb(self, source):
    277         self.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DIALOG)
    278         self.window.set_accept_focus(True)
     257        self.set_type_hint(Gdk.WindowTypeHint.DIALOG)
     258        self.get_window().set_accept_focus(True)
    279259
    280260
    281261class _HelpWindow(_DialogWindow):
    class _HelpWindow(_DialogWindow): 
    284264        super(_HelpWindow, self).__init__('help-icon', _("Help"))
    285265
    286266        offset = style.GRID_CELL_SIZE
    287         width = gtk.gdk.screen_width() - offset * 2
    288         height = gtk.gdk.screen_height() - offset * 2
     267        width = Gdk.Screen.width() - offset * 2
     268        height = Gdk.Screen.height() - offset * 2
    289269        self.set_size_request(width, height)
    290270
    291271        self._help_widget = HelpWidget(self._icon_file)
    292         self.content_vbox.pack_start(self._help_widget)
     272        self.content_vbox.pack_start(self._help_widget, True, True, 0)
    293273
    294274        self._help_nav_bar = _HelpNavBar()
    295         self.content_vbox.pack_end(self._help_nav_bar,
    296                                    expand=False,
    297                                    padding=style.DEFAULT_SPACING)
     275        self.content_vbox.pack_end(self._help_nav_bar, expand=False,
     276                                   fill=False, padding=style.DEFAULT_SPACING)
    298277
    299278        for (signal_name, callback) in [
    300279                ('forward-clicked', self._forward_clicked_cb),
    class _HelpWindow(_DialogWindow): 
    316295        self._help_widget.replay_stage()
    317296
    318297    def _icon_file(self, icon_name):
    319         theme = gtk.icon_theme_get_default()
     298        theme = Gtk.IconTheme.get_default()
    320299        info = theme.lookup_icon(icon_name, 0, 0)
    321300        return info.get_filename()
    322301
    class _HelpWindow(_DialogWindow): 
    326305        self._help_nav_bar.set_can_next_stage(hw.can_next_stage())
    327306
    328307
    329 class _DialogToolbar(gtk.Toolbar):
     308class _DialogToolbar(Gtk.Toolbar):
    330309    # Displays a dialog window's toolbar, with title, icon, and close box.
    331310    __gsignals__ = {
    332         'stop-clicked'       : (gobject.SIGNAL_RUN_LAST, None, ()),
     311        'stop-clicked'       : (GObject.SignalFlags.RUN_LAST, None, ()),
    333312    }
    334313    def __init__(self, icon_name, title):
    335314        super(_DialogToolbar, self).__init__()
    336315
    337316        icon = Icon()
    338         icon.set_from_icon_name(icon_name, gtk.ICON_SIZE_LARGE_TOOLBAR)
     317        icon.set_from_icon_name(icon_name, Gtk.IconSize.LARGE_TOOLBAR)
    339318        self._add_widget(icon)
    340319
    341320        self._add_separator()
    342321
    343         label = gtk.Label(title)
     322        label = Gtk.Label(label=title)
    344323        self._add_widget(label)
    345324
    346325        self._add_separator(expand=True)
    class _DialogToolbar(gtk.Toolbar): 
    351330        self.add(stop)
    352331
    353332    def _add_separator(self, expand=False):
    354         separator = gtk.SeparatorToolItem()
     333        separator = Gtk.SeparatorToolItem()
    355334        separator.set_expand(expand)
    356335        separator.set_draw(False)
    357336        self.add(separator)
    358337
    359338    def _add_widget(self, widget):
    360         tool_item = gtk.ToolItem()
     339        tool_item = Gtk.ToolItem()
    361340        tool_item.add(widget)
    362341        self.add(tool_item)
    363342
    class _DialogToolbar(gtk.Toolbar): 
    365344        self.emit('stop-clicked')
    366345
    367346
    368 class _HelpNavBar(gtk.HButtonBox):
     347class _HelpNavBar(Gtk.HButtonBox):
    369348    # A widget to display the navigation controls at the bottom of the help
    370349    # dialog.
    371350    __gsignals__ = {
    372         'forward-clicked' : (gobject.SIGNAL_RUN_LAST, None, ()),
    373         'back-clicked'    : (gobject.SIGNAL_RUN_LAST, None, ()),
    374         'reload-clicked'  : (gobject.SIGNAL_RUN_LAST, None, ()),
     351        'forward-clicked' : (GObject.SignalFlags.RUN_LAST, None, ()),
     352        'back-clicked'    : (GObject.SignalFlags.RUN_LAST, None, ()),
     353        'reload-clicked'  : (GObject.SignalFlags.RUN_LAST, None, ()),
    375354    }
    376355
    377356    def __init__(self):
    378357        super(_HelpNavBar, self).__init__()
    379358
    380         self.set_layout(gtk.BUTTONBOX_SPREAD)
     359        self.set_layout(Gtk.ButtonBoxStyle.SPREAD)
    381360
    382361        def add_button(icon_name, tooltip, signal_name):
    383362            icon = Icon()
    384             icon.set_from_icon_name(icon_name, gtk.ICON_SIZE_LARGE_TOOLBAR)
    385             button = gtk.Button()
     363            icon.set_from_icon_name(icon_name, Gtk.IconSize.LARGE_TOOLBAR)
     364            button = Gtk.Button()
    386365            button.set_image(icon)
    387366            button.set_tooltip_text(tooltip)
    388367            self.add(button)
    class _HelpNavBar(gtk.HButtonBox): 
    404383        self._forward_button.set_sensitive(can_next_stage)
    405384
    406385
    407 class _StuckStrip(gtk.HBox):
     386class _StuckStrip(Gtk.HBox):
    408387    __gsignals__ = {
    409         'undo-clicked' : (gobject.SIGNAL_RUN_LAST, None, ()),
     388        'undo-clicked' : (GObject.SignalFlags.RUN_LAST, None, ()),
    410389    }
    411390    def __init__(self, *args, **kwargs):
    412391        super(_StuckStrip, self).__init__(*args, **kwargs)
    413392
    414         spacer1 = gtk.Label('')
    415         self.pack_start(spacer1, expand=True)
     393        spacer1 = Gtk.Label(label='')
     394        self.pack_start(spacer1, True, True, 0)
    416395
    417         spacer2 = gtk.Label('')
    418         self.pack_end(spacer2, expand=True)
     396        spacer2 = Gtk.Label(label='')
     397        self.pack_end(spacer2, expand=True, fill=False, padding=0)
    419398
    420399        self.set_spacing(10)
    421400
    422401        self.set_border_width(10)
    423402
    424         label = gtk.Label(_("Stuck?  You can still solve the puzzle."))
    425         self.pack_start(label, expand=False)
     403        label = Gtk.Label(label=_("Stuck?  You can still solve the puzzle."))
     404        self.pack_start(label, False, True, 0)
    426405
    427406        icon = Icon()
    428         icon.set_from_icon_name('edit-undo', gtk.ICON_SIZE_LARGE_TOOLBAR)
    429         self.button = gtk.Button(stock=gtk.STOCK_UNDO)
     407        icon.set_from_icon_name('edit-undo', Gtk.IconSize.LARGE_TOOLBAR)
     408        self.button = Gtk.Button(stock=Gtk.STOCK_UNDO)
    430409        self.button.set_image(icon)
    431410        self.button.set_label(_("Undo some moves"))
    432         self.pack_end(self.button, expand=False)
     411        self.pack_end(self.button, expand=False, fill=False, padding=0)
    433412
    434413        def callback(source):
    435414            self.emit('undo-clicked')
  • implodegame.py

    diff --git a/implodegame.py b/implodegame.py
    index 60c507c..7841d69 100644
    a b _logger = logging.getLogger('implode-activity.implodegame') 
    2121
    2222from gettext import gettext as _
    2323
    24 import gtk
    25 import gobject
     24from gi.repository import Gtk
     25from gi.repository import GObject
    2626import random
    2727import time
    2828
    _STUCK_DELAY = 0.5 
    3939# state after the player gets stuck, in seconds.
    4040_UNDO_DELAY = 0.3
    4141
    42 class ImplodeGame(gtk.EventBox):
     42class ImplodeGame(Gtk.EventBox):
    4343    """Gtk widget for playing the implode game."""
    4444
    4545    __gsignals__ = {
    46         'show-stuck': (gobject.SIGNAL_RUN_LAST, None, (int,)),
     46        'show-stuck': (GObject.SignalFlags.RUN_LAST, None, (int,)),
    4747    }
    4848
    4949    def __init__(self, *args, **kwargs):
  • keymap.py

    diff --git a/keymap.py b/keymap.py
    index b420ace..0322b22 100644
    a b  
    1616# along with this program; if not, write to the Free Software
    1717# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    1818
    19 import gtk
     19from gi.repository import Gdk
    2020
    2121KEY_MAP = {
    22     gtk.keysyms.KP_Up        : 'up',
    23     gtk.keysyms.KP_Down      : 'down',
    24     gtk.keysyms.KP_Left      : 'left',
    25     gtk.keysyms.KP_Right     : 'right',
    26 
    27     gtk.keysyms.w            : 'up',
    28     gtk.keysyms.s            : 'down',
    29     gtk.keysyms.a            : 'left',
    30     gtk.keysyms.d            : 'right',
    31 
    32     gtk.keysyms.KP_8         : 'up',
    33     gtk.keysyms.KP_2         : 'down',
    34     gtk.keysyms.KP_4         : 'left',
    35     gtk.keysyms.KP_6         : 'right',
    36 
    37     gtk.keysyms.Up           : 'up',
    38     gtk.keysyms.Down         : 'down',
    39     gtk.keysyms.Left         : 'left',
    40     gtk.keysyms.Right        : 'right',
    41 
    42     gtk.keysyms.uparrow      : 'up',
    43     gtk.keysyms.downarrow    : 'down',
    44     gtk.keysyms.leftarrow    : 'left',
    45     gtk.keysyms.rightarrow   : 'right',
    46 
    47     gtk.keysyms.Return       : 'select',
    48     gtk.keysyms.KP_Space     : 'select',
    49     gtk.keysyms.KP_Enter     : 'select',
    50     gtk.keysyms.space        : 'select',
    51     gtk.keysyms.End          : 'select',
    52     gtk.keysyms.KP_End       : 'select',
    53     gtk.keysyms.KP_1         : 'select',
    54     gtk.keysyms.q            : 'select',
    55 
    56     gtk.keysyms.Home         : 'new',
    57     gtk.keysyms.KP_Home      : 'new',
    58     gtk.keysyms.Page_Down    : 'redo',
    59     gtk.keysyms.KP_Page_Down : 'redo',
    60     gtk.keysyms.Page_Up      : 'undo',
    61     gtk.keysyms.KP_Page_Up   : 'undo',
     22    Gdk.KEY_KP_Up        : 'up',
     23    Gdk.KEY_KP_Down      : 'down',
     24    Gdk.KEY_KP_Left      : 'left',
     25    Gdk.KEY_KP_Right     : 'right',
     26
     27    Gdk.KEY_w            : 'up',
     28    Gdk.KEY_s            : 'down',
     29    Gdk.KEY_a            : 'left',
     30    Gdk.KEY_d            : 'right',
     31
     32    Gdk.KEY_KP_8         : 'up',
     33    Gdk.KEY_KP_2         : 'down',
     34    Gdk.KEY_KP_4         : 'left',
     35    Gdk.KEY_KP_6         : 'right',
     36
     37    Gdk.KEY_Up           : 'up',
     38    Gdk.KEY_Down         : 'down',
     39    Gdk.KEY_Left         : 'left',
     40    Gdk.KEY_Right        : 'right',
     41
     42    Gdk.KEY_uparrow      : 'up',
     43    Gdk.KEY_downarrow    : 'down',
     44    Gdk.KEY_leftarrow    : 'left',
     45    Gdk.KEY_rightarrow   : 'right',
     46
     47    Gdk.KEY_Return       : 'select',
     48    Gdk.KEY_KP_Space     : 'select',
     49    Gdk.KEY_KP_Enter     : 'select',
     50    Gdk.KEY_space        : 'select',
     51    Gdk.KEY_End          : 'select',
     52    Gdk.KEY_KP_End       : 'select',
     53    Gdk.KEY_KP_1         : 'select',
     54    Gdk.KEY_q            : 'select',
     55
     56    Gdk.KEY_Home         : 'new',
     57    Gdk.KEY_KP_Home      : 'new',
     58    Gdk.KEY_Page_Down    : 'redo',
     59    Gdk.KEY_KP_Page_Down : 'redo',
     60    Gdk.KEY_Page_Up      : 'undo',
     61    Gdk.KEY_KP_Page_Up   : 'undo',
    6262}
  • setup.py

    diff --git a/setup.py b/setup.py
    index 211f104..cbdf097 100644
    a b  
    11#!/usr/bin/env python
    22
    3 from sugar.activity import bundlebuilder
     3from sugar3.activity import bundlebuilder
    44if __name__ == "__main__":
    55    bundlebuilder.start()
  • sugarless.py

    diff --git a/sugarless.py b/sugarless.py
    index 6a9f3ea..911096d 100644
    a b  
    1919# A stub file for running the application on a sugarless GTK, when the Activity
    2020# framework is not available.
    2121
    22 import pygtk
    23 pygtk.require('2.0')
    24 import gtk
    25 import gobject
     22from gi.repository import Gtk
     23from gi.repository import Gdk
     24from gi.repository import GObject
    2625
    2726import os
    2827
    from keymap import KEY_MAP 
    3231
    3332_DEFAULT_SPACING = 15
    3433
    35 class ImplodeWindow(gtk.Window):
     34class ImplodeWindow(Gtk.Window):
    3635    def __init__(self):
    37         super(ImplodeWindow, self).__init__(gtk.WINDOW_TOPLEVEL)
    38         self.set_geometry_hints(None, min_width=640, min_height=480)
     36        super(ImplodeWindow, self).__init__(Gtk.WindowType.TOPLEVEL)
     37
     38        geometry = Gdk.Geometry()
     39        geometry.min_width = 640
     40        geometry.min_height = 480
     41
     42        self.set_geometry_hints(None, geometry, Gdk.WindowHints.MIN_SIZE)
    3943        self.set_title("Implode")
    4044
    4145        self.connect("delete_event", self._delete_event_cb)
    4246
    43         toolbar = gtk.Toolbar()
     47        toolbar = Gtk.Toolbar()
    4448        self.game = implodegame.ImplodeGame()
    4549
    4650        def add_button(id, func):
    47             button = gtk.ToolButton(id)
     51            button = Gtk.ToolButton(id)
    4852            toolbar.add(button)
    4953
    5054            def callback(source):
    class ImplodeWindow(gtk.Window): 
    5357
    5458            return button
    5559
    56         add_button(gtk.STOCK_NEW, self.game.new_game)
    57         add_button(gtk.STOCK_MEDIA_PREVIOUS, self.game.replay_game)
    58         add_button(gtk.STOCK_UNDO, self.game.undo)
    59         add_button(gtk.STOCK_REDO, self.game.redo)
     60        add_button(Gtk.STOCK_NEW, self.game.new_game)
     61        add_button(Gtk.STOCK_MEDIA_PREVIOUS, self.game.replay_game)
     62        add_button(Gtk.STOCK_UNDO, self.game.undo)
     63        add_button(Gtk.STOCK_REDO, self.game.redo)
    6064
    61         toolbar.add(gtk.SeparatorToolItem())
     65        toolbar.add(Gtk.SeparatorToolItem())
    6266
    6367        radio_buttons = []
    6468        def add_radio_button(label, func):
    65             button = gtk.RadioToolButton()
     69            button = Gtk.RadioToolButton()
    6670            button.set_label(label)
    6771            toolbar.add(button)
    6872            radio_buttons.append(button)
    class ImplodeWindow(gtk.Window): 
    7781        add_radio_button('easy', self._easy_clicked)
    7882        add_radio_button('medium', self._medium_clicked)
    7983        add_radio_button('hard', self._hard_clicked)
    80         for button in radio_buttons[1:]:
    81             button.set_group(radio_buttons[0])
     84        # FIXME:
     85        # for button in radio_buttons[1:]:
     86        #     button.set_group(radio_buttons[0])
    8287
    83         separator = gtk.SeparatorToolItem()
     88        separator = Gtk.SeparatorToolItem()
    8489        separator.set_expand(True)
    8590        separator.set_draw(False)
    8691        toolbar.add(separator)
    8792
    88         add_button(gtk.STOCK_HELP, self._help_clicked)
     93        add_button(Gtk.STOCK_HELP, self._help_clicked)
    8994
    9095        self._stuck_strip = _StuckStrip()
    9196
    92         game_box = gtk.VBox()
    93         game_box.pack_start(self.game)
    94         game_box.pack_end(self._stuck_strip, expand=False)
     97        game_box = Gtk.VBox()
     98        game_box.pack_start(self.game, True, True, 0)
     99        game_box.pack_end(self._stuck_strip, expand=False,
     100                          fill=False, padding=0)
    95101
    96         main_box = gtk.VBox()
    97         main_box.pack_start(toolbar, expand=False)
    98         main_box.pack_end(game_box)
     102        main_box = Gtk.VBox()
     103        main_box.pack_start(toolbar, False, True, 0)
     104        main_box.pack_end(game_box, expand=False, fill=False, padding=0)
    99105        self.add(main_box)
    100106
    101107        # Show everything except the stuck strip.
    class ImplodeWindow(gtk.Window): 
    111117        self.show()
    112118
    113119    def _delete_event_cb(self, window, event):
    114         gtk.main_quit()
     120        Gtk.main_quit()
    115121        return False
    116122
    117123    def _easy_clicked(self):
    class ImplodeWindow(gtk.Window): 
    144150        action = KEY_MAP.get(event.keyval, None)
    145151        if action is None:
    146152            return False
    147         if not self._stuck_strip.flags() & gtk.VISIBLE:
     153        if not self._stuck_strip.flags() & Gtk.VISIBLE:
    148154            return True
    149155        if self.game.focus_child:
    150156            if action == 'down':
    class ImplodeWindow(gtk.Window): 
    158164            return True
    159165        return True
    160166
    161 class _HelpWindow(gtk.Window):
     167class _HelpWindow(Gtk.Window):
    162168    def __init__(self):
    163169        super(_HelpWindow, self).__init__()
    164170
    165171        self.set_size_request(640, 480)
    166         self.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
     172        self.set_position(Gtk.WindowPosition.CENTER_ON_PARENT)
    167173        self.set_modal(True)
    168174
    169         vbox = gtk.VBox()
     175        vbox = Gtk.VBox()
    170176        self.add(vbox)
    171177
    172178        self._help_widget = HelpWidget(self._icon_file)
    173         vbox.pack_start(self._help_widget)
     179        vbox.pack_start(self._help_widget, True, True, 0)
    174180
    175181        self._help_nav_bar = _HelpNavBar()
    176182        vbox.pack_end(self._help_nav_bar,
    class _HelpWindow(gtk.Window): 
    207213        self._help_nav_bar.set_can_next_stage(hw.can_next_stage())
    208214
    209215
    210 class _HelpNavBar(gtk.HButtonBox):
     216class _HelpNavBar(Gtk.HButtonBox):
    211217    __gsignals__ = {
    212         'forward-clicked' : (gobject.SIGNAL_RUN_LAST, None, ()),
    213         'back-clicked'    : (gobject.SIGNAL_RUN_LAST, None, ()),
    214         'reload-clicked'  : (gobject.SIGNAL_RUN_LAST, None, ()),
     218        'forward-clicked' : (GObject.SignalFlags.RUN_LAST, None, ()),
     219        'back-clicked'    : (GObject.SignalFlags.RUN_LAST, None, ()),
     220        'reload-clicked'  : (GObject.SignalFlags.RUN_LAST, None, ()),
    215221    }
    216222
    217223    def __init__(self):
    218224        super(_HelpNavBar, self).__init__()
    219225
    220         self.set_layout(gtk.BUTTONBOX_SPREAD)
     226        self.set_layout(Gtk.ButtonBoxStyle.SPREAD)
    221227
    222228        def add_button(id, signal_name):
    223             button = gtk.Button(stock=id)
     229            button = Gtk.Button(stock=id)
    224230            self.add(button)
    225231
    226232            def callback(source):
    class _HelpNavBar(gtk.HButtonBox): 
    229235
    230236            return button
    231237
    232         self._back_button = add_button(gtk.STOCK_GO_BACK, 'back-clicked')
    233         add_button(gtk.STOCK_MEDIA_PLAY, 'reload-clicked')
    234         self._forward_button = add_button(gtk.STOCK_GO_FORWARD, 'forward-clicked')
     238        self._back_button = add_button(Gtk.STOCK_GO_BACK, 'back-clicked')
     239        add_button(Gtk.STOCK_MEDIA_PLAY, 'reload-clicked')
     240        self._forward_button = add_button(Gtk.STOCK_GO_FORWARD, 'forward-clicked')
    235241
    236242    def set_can_prev_stage(self, can_prev_stage):
    237243        self._back_button.set_sensitive(can_prev_stage)
    class _HelpNavBar(gtk.HButtonBox): 
    240246        self._forward_button.set_sensitive(can_next_stage)
    241247
    242248
    243 class _StuckStrip(gtk.HBox):
     249class _StuckStrip(Gtk.HBox):
    244250    __gsignals__ = {
    245         'undo-clicked' : (gobject.SIGNAL_RUN_LAST, None, ()),
     251        'undo-clicked' : (GObject.SignalFlags.RUN_LAST, None, ()),
    246252    }
    247253    def __init__(self, *args, **kwargs):
    248254        super(_StuckStrip, self).__init__(*args, **kwargs)
    249255
    250         spacer1 = gtk.Label('')
    251         self.pack_start(spacer1, expand=True)
     256        spacer1 = Gtk.Label(label='')
     257        self.pack_start(spacer1, True, True, 0)
    252258
    253         spacer2 = gtk.Label('')
    254         self.pack_end(spacer2, expand=True)
     259        spacer2 = Gtk.Label(label='')
     260        self.pack_end(spacer2, expand=True, fill=False, padding=0)
    255261
    256262        self.set_spacing(10)
    257263
    258264        self.set_border_width(10)
    259265
    260         label = gtk.Label("Stuck?  You can still solve the puzzle.")
    261         self.pack_start(label, expand=False)
     266        label = Gtk.Label(label="Stuck?  You can still solve the puzzle.")
     267        self.pack_start(label, False, True, 0)
    262268
    263         self.button = gtk.Button(stock=gtk.STOCK_UNDO)
     269        self.button = Gtk.Button(stock=Gtk.STOCK_UNDO)
    264270        self.button.set_label("Undo some moves")
    265         self.pack_end(self.button, expand=False)
     271        self.pack_end(self.button, expand=False, fill=False, padding=0)
    266272
    267273        def callback(source):
    268274            self.emit('undo-clicked')
    class _StuckStrip(gtk.HBox): 
    271277
    272278def main():
    273279    w = ImplodeWindow()
    274     gtk.main()
     280    Gtk.main()
    275281
    276282if __name__ == "__main__":
    277283    main()