Ticket #3715: First-Working-Version.diff

File First-Working-Version.diff, 46.1 KB (added by humitos, 12 years ago)

First Gtk3 working version

  • 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..9be9010 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,)),
    104         'button-press-event': 'override',
    105         'key-press-event': 'override',
    106         'expose-event': 'override',
    107         'size-allocate': 'override',
    108         'motion-notify-event': 'override',
     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,)),
    10992    }
    11093
    11194    def __init__(self, *args, **kwargs):
    11295        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)
     96
     97        # self.set_flags(Gtk.CAN_FOCUS)
    11798
    11899        self._board_drawer = BoardDrawer(self._get_size, self._invalidate_rect)
    119100        self._win_drawer = WinDrawer(self._get_size, self._invalidate_rect)
    120         self._removal_drawer = RemovalDrawer(self._get_size, self._invalidate_rect)
     101        self._removal_drawer = RemovalDrawer(self._get_size,
     102                                             self._invalidate_rect)
    121103        self._set_current_drawer(self._board_drawer)
    122104
     105        self.connect('draw', self._draw_event_cb)
     106        self.connect('configure-event', self._configure_event_cb)
     107
     108        # self.connect('motion_notify_event', self.do_motion_notify_event)
     109        self.connect('button-press-event', self._button_press_event_cb)
     110
     111        self.set_events(Gdk.EventMask.BUTTON_PRESS_MASK
     112                        | Gdk.EventMask.POINTER_MOTION_MASK
     113                        | Gdk.EventMask.KEY_PRESS_MASK)
     114
    123115    def _get_size(self):
    124         return (self.allocation.width, self.allocation.height)
     116        return (self.get_allocated_width(), self.get_allocated_height())
     117        # return (self.allocation.width, self.allocation.height)
    125118
    126119    def _invalidate_rect(self, rect):
    127         if self.window:
    128             self.window.invalidate_rect(rect, True)
     120        if self.get_window():
     121            self.get_window().invalidate_rect(rect, True)
    129122
    130123    def set_board(self, board):
    131124        self._board_drawer.set_board(board)
    class GridWidget(gtk.DrawingArea): 
    141134
    142135    def _invalidate_board(self):
    143136        (width, height) = self._get_size()
    144         self._invalidate_rect(gtk.gdk.Rectangle(0, 0, width, height))
     137        rect = Gdk.Rectangle()
     138        rect.x, rect.y, rect.width, rect.height = (0, 0, width, height)
     139        self._invalidate_rect(rect)
    145140
    146141    def get_win_draw_flag(self):
    147142        return (self._current_drawer is self._win_drawer)
    class GridWidget(gtk.DrawingArea): 
    159154    def select_center_cell(self):
    160155        self._board_drawer.select_center_cell()
    161156
    162     @_log_errors
    163     def do_button_press_event(self, event):
     157    def _button_press_event_cb(self, widget, event):
    164158        # Ignore mouse clicks while animating.
    165159        if self._is_animating():
    166160            return True
    167161        # Ignore double- and triple-clicks.
    168         if event.type != gtk.gdk.BUTTON_PRESS:
     162        if event.type != Gdk.EventType.BUTTON_PRESS:
    169163            return True
    170164        self.grab_focus()
    171165        self._board_drawer.set_mouse_selection(event.x, event.y)
    class GridWidget(gtk.DrawingArea): 
    174168            self.emit('piece-selected', *selected_cell)
    175169        return True
    176170
    177     @_log_errors
    178171    def do_key_press_event(self, event):
    179172        action = KEY_MAP.get(event.keyval, None)
    180173        if action == 'new':
    class GridWidget(gtk.DrawingArea): 
    209202                    else:
    210203                        return False
    211204
    212     @_log_errors
    213205    def do_motion_notify_event(self, event):
    214206        # Ignore mouse motion while animating.
    215207        if self._is_animating():
    class GridWidget(gtk.DrawingArea): 
    219211        else:
    220212            x = event.x
    221213            y = event.y
    222             state = event.state
     214            state = event.get_state()
    223215        self._board_drawer.set_mouse_selection(x, y)
    224216
    225     @_log_errors
    226     def do_expose_event(self, event):
    227         cr = self.window.cairo_create()
    228         cr.rectangle(event.area.x,
    229                      event.area.y,
    230                      event.area.width,
    231                      event.area.height)
     217    def _draw_event_cb(self, widget, cr):
     218        # README: maybe this is no the best way to do it because we
     219        # are re-drawing all the screen but I didn't find another way
     220        # to do this (this was changed on the Gtk3 porting)
     221        width, height = (800, 546)
     222        cr.rectangle(0, 0, width, height)
    232223        cr.clip()
    233         (width, height) = self.window.get_size()
    234224        self._current_drawer.draw(cr, width, height)
    235225
    236     @_log_errors
    237     def do_size_allocate(self, allocation):
    238         super(GridWidget, self).do_size_allocate(self, allocation)
    239         self._current_drawer.resize(allocation.width, allocation.height)
     226    def _configure_event_cb(self, widget, event):
     227        self._current_drawer.resize(event.width, event.height)
    240228
    241229    def _set_current_drawer(self, drawer):
    242230        self._current_drawer = drawer
    class BoardDrawer(object): 
    295283    """Object to manage drawing of the game board."""
    296284
    297285    def __init__(self, get_size_func, invalidate_rect_func, *args, **kwargs):
    298         super(BoardDrawer, self).__init__(*args, **kwargs)
     286        # super(BoardDrawer, self).__init__(*args, **kwargs)
    299287        self._board = None
    300288        self._board_width = 0
    301289        self._board_height = 0
    class BoardDrawer(object): 
    382370
    383371    def _invalidate_board(self):
    384372        (width, height) = self._get_size_func()
    385         rect = gtk.gdk.Rectangle(0, 0, width, height)
     373        rect = Gdk.Rectangle()
     374        rect.x, rect.y, rect.width, rect.height = (0, 0, width, height)
    386375        self._invalidate_rect_func(rect)
    387376
    388377    def _invalidate_selection(self, selection_coord):
    class BoardDrawer(object): 
    407396        max_x2 = math.ceil( max(pt1[0], pt2[0])) + 1
    408397        min_y2 = math.floor(min(pt1[1], pt2[1])) - 1
    409398        max_y2 = math.ceil( max(pt1[1], pt2[1])) + 1
    410         rect = gtk.gdk.Rectangle(int(min_x2),
     399        rect = Gdk.Rectangle()
     400        rect.x, rect.y, rect.width, rect.height = (int(min_x2),
    411401                                 int(min_y2),
    412402                                 int(max_x2 - min_x2),
    413403                                 int(max_y2 - min_y2))
    class BoardDrawer(object): 
    426416            self._board_transform = _BoardTransform()
    427417        else:
    428418            self._board_transform = _BoardTransform()
    429             self._board_transform.setup(width,
    430                                        height,
    431                                        self._board_width,
    432                                        self._board_height)
     419            self._board_transform.setup(width, height, self._board_width,
     420                                        self._board_height)
    433421
    434422    def draw(self, cr, width, height):
    435423        # Draws the widget.
    class RemovalDrawer(object): 
    511499    """Object to manage the drawing of the animation of removing blocks."""
    512500
    513501    def __init__(self, get_size_func, invalidate_rect_func, *args, **kwargs):
    514         super(RemovalDrawer, self).__init__(*args, **kwargs)
     502        # super(RemovalDrawer, self).__init__(*args, **kwargs)
    515503        self._board = None
    516504        self._board_width = 0
    517505        self._board_height = 0
    class RemovalDrawer(object): 
    564552
    565553    def _invalidate_board(self):
    566554        (width, height) = self._get_size_func()
    567         rect = gtk.gdk.Rectangle(0, 0, width, height)
     555        rect = Gdk.Rectangle()
     556        rect.x, rect.y, rect.width, rect.height = (0, 0, width, height)
    568557        self._invalidate_rect_func(rect)
    569558
    570559    def _recalc_game_anim_frames(self):
    class WinDrawer(object): 
    742731    """Object to manage the drawing of the win animation."""
    743732
    744733    def __init__(self, get_size_func, invalidate_rect_func, *args, **kwargs):
    745         super(WinDrawer, self).__init__(*args, **kwargs)
     734        # super(WinDrawer, self).__init__(*args, **kwargs)
    746735
    747736        self._anim_time = 0.0
    748737
    class WinDrawer(object): 
    810799
    811800    def _invalidate_board(self):
    812801        (width, height) = self._get_size_func()
    813         rect = gtk.gdk.Rectangle(0, 0, width, height)
     802        rect = Gdk.Rectangle()
     803        rect.x, rect.y, rect.width, rect.height = (0, 0, width, height)
    814804        self._invalidate_rect_func(rect)
    815805
    816806    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..db4937b 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):
     34import logging
     35LOG_FILENAME = '/tmp/logging_example.out'
     36logging.basicConfig(filename=LOG_FILENAME, level=logging.DEBUG)
     37
     38logging.debug('This message should go to the log file')
     39
     40
     41class ImplodeWindow(Gtk.Window):
    3642    def __init__(self):
    37         super(ImplodeWindow, self).__init__(gtk.WINDOW_TOPLEVEL)
    38         self.set_geometry_hints(None, min_width=640, min_height=480)
     43        super(ImplodeWindow, self).__init__(Gtk.WindowType.TOPLEVEL)
     44
     45        geometry = Gdk.Geometry()
     46        geometry.min_width = 640
     47        geometry.min_height = 480
     48
     49        self.set_geometry_hints(None, geometry, Gdk.WindowHints.MIN_SIZE)
    3950        self.set_title("Implode")
    4051
    4152        self.connect("delete_event", self._delete_event_cb)
    4253
    43         toolbar = gtk.Toolbar()
     54        toolbar = Gtk.Toolbar()
    4455        self.game = implodegame.ImplodeGame()
    4556
    4657        def add_button(id, func):
    47             button = gtk.ToolButton(id)
     58            button = Gtk.ToolButton(id)
    4859            toolbar.add(button)
    4960
    5061            def callback(source):
    class ImplodeWindow(gtk.Window): 
    5364
    5465            return button
    5566
    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)
     67        add_button(Gtk.STOCK_NEW, self.game.new_game)
     68        add_button(Gtk.STOCK_MEDIA_PREVIOUS, self.game.replay_game)
     69        add_button(Gtk.STOCK_UNDO, self.game.undo)
     70        add_button(Gtk.STOCK_REDO, self.game.redo)
    6071
    61         toolbar.add(gtk.SeparatorToolItem())
     72        toolbar.add(Gtk.SeparatorToolItem())
    6273
    6374        radio_buttons = []
    6475        def add_radio_button(label, func):
    65             button = gtk.RadioToolButton()
     76            button = Gtk.RadioToolButton()
    6677            button.set_label(label)
    6778            toolbar.add(button)
    6879            radio_buttons.append(button)
    class ImplodeWindow(gtk.Window): 
    7788        add_radio_button('easy', self._easy_clicked)
    7889        add_radio_button('medium', self._medium_clicked)
    7990        add_radio_button('hard', self._hard_clicked)
    80         for button in radio_buttons[1:]:
    81             button.set_group(radio_buttons[0])
     91        # FIXME:
     92        # for button in radio_buttons[1:]:
     93        #     button.set_group(radio_buttons[0])
    8294
    83         separator = gtk.SeparatorToolItem()
     95        separator = Gtk.SeparatorToolItem()
    8496        separator.set_expand(True)
    8597        separator.set_draw(False)
    8698        toolbar.add(separator)
    8799
    88         add_button(gtk.STOCK_HELP, self._help_clicked)
     100        add_button(Gtk.STOCK_HELP, self._help_clicked)
    89101
    90102        self._stuck_strip = _StuckStrip()
    91103
    92         game_box = gtk.VBox()
    93         game_box.pack_start(self.game)
    94         game_box.pack_end(self._stuck_strip, expand=False)
     104        game_box = Gtk.VBox()
     105        game_box.pack_start(self.game, True, True, 0)
     106        game_box.pack_end(self._stuck_strip, expand=False,
     107                          fill=False, padding=0)
    95108
    96         main_box = gtk.VBox()
    97         main_box.pack_start(toolbar, expand=False)
    98         main_box.pack_end(game_box)
     109        main_box = Gtk.VBox()
     110        main_box.pack_start(toolbar, False, True, 0)
     111        main_box.pack_end(game_box, expand=False, fill=False, padding=0)
    99112        self.add(main_box)
    100113
    101114        # Show everything except the stuck strip.
    class ImplodeWindow(gtk.Window): 
    111124        self.show()
    112125
    113126    def _delete_event_cb(self, window, event):
    114         gtk.main_quit()
     127        Gtk.main_quit()
    115128        return False
    116129
    117130    def _easy_clicked(self):
    class ImplodeWindow(gtk.Window): 
    132145        if data:
    133146            self._stuck_strip.show_all()
    134147        else:
    135             if self._stuck_strip.focus_child:
    136                 self.game.grab_focus()
     148            # if self._stuck_strip.focus_child:
     149            self.game.grab_focus()
    137150            self._stuck_strip.hide()
    138151
    139152    def _stuck_undo_cb(self, state, data=None):
    class ImplodeWindow(gtk.Window): 
    144157        action = KEY_MAP.get(event.keyval, None)
    145158        if action is None:
    146159            return False
    147         if not self._stuck_strip.flags() & gtk.VISIBLE:
     160        if not self._stuck_strip.flags() & Gtk.VISIBLE:
    148161            return True
    149162        if self.game.focus_child:
    150163            if action == 'down':
    class ImplodeWindow(gtk.Window): 
    158171            return True
    159172        return True
    160173
    161 class _HelpWindow(gtk.Window):
     174class _HelpWindow(Gtk.Window):
    162175    def __init__(self):
    163176        super(_HelpWindow, self).__init__()
    164177
    165178        self.set_size_request(640, 480)
    166         self.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
     179        self.set_position(Gtk.WindowPosition.CENTER_ON_PARENT)
    167180        self.set_modal(True)
    168181
    169         vbox = gtk.VBox()
     182        vbox = Gtk.VBox()
    170183        self.add(vbox)
    171184
    172185        self._help_widget = HelpWidget(self._icon_file)
    173         vbox.pack_start(self._help_widget)
     186        vbox.pack_start(self._help_widget, True, True, 0)
    174187
    175188        self._help_nav_bar = _HelpNavBar()
    176189        vbox.pack_end(self._help_nav_bar,
    177                       expand=False)
     190                      expand=False, fill=False,
     191                      padding=0)
    178192
    179193        for (signal_name, callback) in [
    180194                ('forward-clicked', self._forward_clicked_cb),
    class _HelpWindow(gtk.Window): 
    207221        self._help_nav_bar.set_can_next_stage(hw.can_next_stage())
    208222
    209223
    210 class _HelpNavBar(gtk.HButtonBox):
     224class _HelpNavBar(Gtk.HButtonBox):
    211225    __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, ()),
     226        'forward-clicked' : (GObject.SignalFlags.RUN_LAST, None, ()),
     227        'back-clicked'    : (GObject.SignalFlags.RUN_LAST, None, ()),
     228        'reload-clicked'  : (GObject.SignalFlags.RUN_LAST, None, ()),
    215229    }
    216230
    217231    def __init__(self):
    218232        super(_HelpNavBar, self).__init__()
    219233
    220         self.set_layout(gtk.BUTTONBOX_SPREAD)
     234        self.set_layout(Gtk.ButtonBoxStyle.SPREAD)
    221235
    222236        def add_button(id, signal_name):
    223             button = gtk.Button(stock=id)
     237            button = Gtk.Button(stock=id)
    224238            self.add(button)
    225239
    226240            def callback(source):
    class _HelpNavBar(gtk.HButtonBox): 
    229243
    230244            return button
    231245
    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')
     246        self._back_button = add_button(Gtk.STOCK_GO_BACK, 'back-clicked')
     247        add_button(Gtk.STOCK_MEDIA_PLAY, 'reload-clicked')
     248        self._forward_button = add_button(Gtk.STOCK_GO_FORWARD, 'forward-clicked')
    235249
    236250    def set_can_prev_stage(self, can_prev_stage):
    237251        self._back_button.set_sensitive(can_prev_stage)
    class _HelpNavBar(gtk.HButtonBox): 
    240254        self._forward_button.set_sensitive(can_next_stage)
    241255
    242256
    243 class _StuckStrip(gtk.HBox):
     257class _StuckStrip(Gtk.HBox):
    244258    __gsignals__ = {
    245         'undo-clicked' : (gobject.SIGNAL_RUN_LAST, None, ()),
     259        'undo-clicked' : (GObject.SignalFlags.RUN_LAST, None, ()),
    246260    }
    247261    def __init__(self, *args, **kwargs):
    248262        super(_StuckStrip, self).__init__(*args, **kwargs)
    249263
    250         spacer1 = gtk.Label('')
    251         self.pack_start(spacer1, expand=True)
     264        spacer1 = Gtk.Label(label='')
     265        self.pack_start(spacer1, True, True, 0)
    252266
    253         spacer2 = gtk.Label('')
    254         self.pack_end(spacer2, expand=True)
     267        spacer2 = Gtk.Label(label='')
     268        self.pack_end(spacer2, expand=True, fill=False, padding=0)
    255269
    256270        self.set_spacing(10)
    257271
    258272        self.set_border_width(10)
    259273
    260         label = gtk.Label("Stuck?  You can still solve the puzzle.")
    261         self.pack_start(label, expand=False)
     274        label = Gtk.Label(label="Stuck?  You can still solve the puzzle.")
     275        self.pack_start(label, False, True, 0)
    262276
    263         self.button = gtk.Button(stock=gtk.STOCK_UNDO)
     277        self.button = Gtk.Button(stock=Gtk.STOCK_UNDO)
    264278        self.button.set_label("Undo some moves")
    265         self.pack_end(self.button, expand=False)
     279        self.pack_end(self.button, expand=False, fill=False, padding=0)
    266280
    267281        def callback(source):
    268282            self.emit('undo-clicked')
    class _StuckStrip(gtk.HBox): 
    271285
    272286def main():
    273287    w = ImplodeWindow()
    274     gtk.main()
     288    Gtk.main()
    275289
    276290if __name__ == "__main__":
    277291    main()