Ticket #3715: First-Working-Version.diff
File First-Working-Version.diff, 46.1 KB (added by humitos, 11 years ago) |
---|
-
anim.py
diff --git a/anim.py b/anim.py index 2c19a15..f34406e 100644
a b 16 16 # along with this program; if not, write to the Free Software 17 17 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 18 19 import gobject19 from gi.repository import GObject 20 20 21 21 # Animation timer interval (in msec) 22 22 _TIMER_INTERVAL = 20 … … class Anim(object): 34 34 def start(self): 35 35 self._animating = True 36 36 self._update_func() 37 gobject.timeout_add(_TIMER_INTERVAL, self._timer)37 GObject.timeout_add(_TIMER_INTERVAL, self._timer) 38 38 39 39 def stop(self): 40 40 if self._animating: -
gridwidget.py
diff --git a/gridwidget.py b/gridwidget.py index 8ee3aad..9be9010 100644
a b import logging 20 20 _logger = logging.getLogger('implode-activity.gridwidget') 21 21 22 22 import cairo 23 import gobject 24 import gtk 23 from gi.repository import GObject 24 from gi.repository import Gtk 25 from gi.repository import Gdk 25 26 import math 26 27 import random 27 28 import time … … _ANIM_STAGES = [ 79 80 # Animation time scaling factor (in seconds per tick). 80 81 _ANIM_SCALE = 0.04 81 82 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 84 class GridWidget(Gtk.DrawingArea): 97 85 """Gtk widget for rendering the game board.""" 98 86 99 87 __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,)), 109 92 } 110 93 111 94 def __init__(self, *args, **kwargs): 112 95 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) 117 98 118 99 self._board_drawer = BoardDrawer(self._get_size, self._invalidate_rect) 119 100 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) 121 103 self._set_current_drawer(self._board_drawer) 122 104 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 123 115 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) 125 118 126 119 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) 129 122 130 123 def set_board(self, board): 131 124 self._board_drawer.set_board(board) … … class GridWidget(gtk.DrawingArea): 141 134 142 135 def _invalidate_board(self): 143 136 (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) 145 140 146 141 def get_win_draw_flag(self): 147 142 return (self._current_drawer is self._win_drawer) … … class GridWidget(gtk.DrawingArea): 159 154 def select_center_cell(self): 160 155 self._board_drawer.select_center_cell() 161 156 162 @_log_errors 163 def do_button_press_event(self, event): 157 def _button_press_event_cb(self, widget, event): 164 158 # Ignore mouse clicks while animating. 165 159 if self._is_animating(): 166 160 return True 167 161 # Ignore double- and triple-clicks. 168 if event.type != gtk.gdk.BUTTON_PRESS:162 if event.type != Gdk.EventType.BUTTON_PRESS: 169 163 return True 170 164 self.grab_focus() 171 165 self._board_drawer.set_mouse_selection(event.x, event.y) … … class GridWidget(gtk.DrawingArea): 174 168 self.emit('piece-selected', *selected_cell) 175 169 return True 176 170 177 @_log_errors178 171 def do_key_press_event(self, event): 179 172 action = KEY_MAP.get(event.keyval, None) 180 173 if action == 'new': … … class GridWidget(gtk.DrawingArea): 209 202 else: 210 203 return False 211 204 212 @_log_errors213 205 def do_motion_notify_event(self, event): 214 206 # Ignore mouse motion while animating. 215 207 if self._is_animating(): … … class GridWidget(gtk.DrawingArea): 219 211 else: 220 212 x = event.x 221 213 y = event.y 222 state = event. state214 state = event.get_state() 223 215 self._board_drawer.set_mouse_selection(x, y) 224 216 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) 232 223 cr.clip() 233 (width, height) = self.window.get_size()234 224 self._current_drawer.draw(cr, width, height) 235 225 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) 240 228 241 229 def _set_current_drawer(self, drawer): 242 230 self._current_drawer = drawer … … class BoardDrawer(object): 295 283 """Object to manage drawing of the game board.""" 296 284 297 285 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) 299 287 self._board = None 300 288 self._board_width = 0 301 289 self._board_height = 0 … … class BoardDrawer(object): 382 370 383 371 def _invalidate_board(self): 384 372 (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) 386 375 self._invalidate_rect_func(rect) 387 376 388 377 def _invalidate_selection(self, selection_coord): … … class BoardDrawer(object): 407 396 max_x2 = math.ceil( max(pt1[0], pt2[0])) + 1 408 397 min_y2 = math.floor(min(pt1[1], pt2[1])) - 1 409 398 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), 411 401 int(min_y2), 412 402 int(max_x2 - min_x2), 413 403 int(max_y2 - min_y2)) … … class BoardDrawer(object): 426 416 self._board_transform = _BoardTransform() 427 417 else: 428 418 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) 433 421 434 422 def draw(self, cr, width, height): 435 423 # Draws the widget. … … class RemovalDrawer(object): 511 499 """Object to manage the drawing of the animation of removing blocks.""" 512 500 513 501 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) 515 503 self._board = None 516 504 self._board_width = 0 517 505 self._board_height = 0 … … class RemovalDrawer(object): 564 552 565 553 def _invalidate_board(self): 566 554 (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) 568 557 self._invalidate_rect_func(rect) 569 558 570 559 def _recalc_game_anim_frames(self): … … class WinDrawer(object): 742 731 """Object to manage the drawing of the win animation.""" 743 732 744 733 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) 746 735 747 736 self._anim_time = 0.0 748 737 … … class WinDrawer(object): 810 799 811 800 def _invalidate_board(self): 812 801 (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) 814 804 self._invalidate_rect_func(rect) 815 805 816 806 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 21 21 from gettext import gettext as _ 22 22 23 23 import cairo 24 import gobject 25 import gtk 24 25 from gi.repository import GObject 26 from gi.repository import Gtk 27 from gi.repository import Gdk 28 from gi.repository import Rsvg 29 26 30 import math 27 31 import os 28 import rsvg29 32 import time 30 33 31 34 import board … … from anim import Anim 33 36 from gridwidget import BoardDrawer, RemovalDrawer, WinDrawer 34 37 35 38 if 'SUGAR_BUNDLE_PATH' in os.environ: 36 from sugar .graphics import style39 from sugar3.graphics import style 37 40 _DEFAULT_SPACING = style.DEFAULT_SPACING 38 41 _DEFAULT_PADDING = style.DEFAULT_PADDING 39 42 _BG_COLOR = tuple(style.COLOR_SELECTION_GREY.get_rgba()[:3]) … … _CLICK_SPEED = 0.2 75 78 # Speed of the mouse, in units (4x3 per screen) per second. 76 79 _MOUSE_SPEED = 0.5 77 80 78 class HelpWidget( gtk.EventBox):81 class HelpWidget(Gtk.EventBox): 79 82 def __init__(self, icon_file_func, *args, **kwargs): 80 83 super(HelpWidget, self).__init__(*args, **kwargs) 81 84 82 vbox = gtk.VBox()85 vbox = Gtk.VBox() 83 86 self.add(vbox) 84 87 85 88 self._stages = [ … … class HelpWidget(gtk.EventBox): 90 93 _HelpStage5(icon_file_func), 91 94 ] 92 95 self._stage_index = 0 93 self._notebook = gtk.Notebook()96 self._notebook = Gtk.Notebook() 94 97 self._notebook.set_show_tabs(False) 95 98 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) 98 101 99 102 self._reset_current_stage() 100 103 … … class HelpWidget(gtk.EventBox): 128 131 self._stages[self._stage_index].reset() 129 132 130 133 131 class _HelpStage( gtk.EventBox):134 class _HelpStage(Gtk.EventBox): 132 135 # An abstract parent class for objects that represent an animated help 133 136 # screen widget with a description. 134 137 def __init__(self, icon_file_func, *args, **kwargs): 135 138 super(_HelpStage, self).__init__(*args, **kwargs) 136 139 137 hbox = gtk.HBox()140 hbox = Gtk.HBox() 138 141 self.add(hbox) 139 142 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) 142 146 143 147 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) 145 150 146 label = gtk.Label(self.get_message())151 label = Gtk.Label(label=self.get_message()) 147 152 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) 149 155 150 156 self.board = None 151 157 self.undo_stack = [] … … def _undo(): 552 558 stage.next_action() 553 559 return action 554 560 555 class _PreviewWidget( gtk.DrawingArea):561 class _PreviewWidget(Gtk.DrawingArea): 556 562 __gsignals__ = { 557 'expose-event': 'override',563 # 'expose-event': 'override', 558 564 'size-allocate': 'override', 559 565 } 560 566 … … class _PreviewWidget(gtk.DrawingArea): 573 579 574 580 self._icon_file_func = icon_file_func 575 581 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 579 597 580 598 self._drawer = self.board_drawer 581 599 … … class _PreviewWidget(gtk.DrawingArea): 593 611 return (self._drawer_rect.width, self._drawer_rect.height) 594 612 595 613 def _invalidate_drawer_rect(self, rect): 596 if self. window:614 if self.get_window(): 597 615 (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) 603 623 604 624 def set_drawer(self, drawer): 605 625 self._drawer = drawer … … class _PreviewWidget(gtk.DrawingArea): 667 687 self._invalidate_client_rect(pixel_x - r, pixel_y - r, r2, r2) 668 688 669 689 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 = ( 672 693 int(math.floor(x)) + self._preview_rect.x, 673 694 int(math.floor(y)) + self._preview_rect.y, 674 695 int(math.ceil(width)) + 1, 675 696 int(math.ceil(height)) + 1) 676 self. window.invalidate_rect(rect, True)697 self.get_window().invalidate_rect(rect, True) 677 698 678 699 def _update_mouse_position(self): 679 700 (pixel_x, pixel_y) = self._get_cursor_pixel_coords() … … class _PreviewWidget(gtk.DrawingArea): 681 702 self.board_drawer.set_mouse_selection(x, y) 682 703 683 704 def do_expose_event(self, event): 684 cr = self. window.cairo_create()705 cr = self.get_window().cairo_create() 685 706 cr.rectangle(event.area.x, 686 707 event.area.y, 687 708 event.area.width, 688 709 event.area.height) 689 710 cr.clip() 690 (width, height) = self. window.get_size()711 (width, height) = self.get_window().get_size() 691 712 self._draw(cr, width, height) 692 713 693 714 def _draw(self, cr, width, height): … … class _PreviewWidget(gtk.DrawingArea): 804 825 cr.restore() 805 826 806 827 def do_size_allocate(self, allocation): 807 super(_PreviewWidget, self).do_size_allocate(self, allocation)828 # super(_PreviewWidget, self).do_size_allocate(self, allocation) 808 829 (width, height) = (allocation.width, allocation.height) 809 830 810 831 avail_width = width - _DEFAULT_SPACING * 2 … … class _PreviewWidget(gtk.DrawingArea): 829 850 old_width = self._preview_rect.width 830 851 old_height = self._preview_rect.height 831 852 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 844 886 self.board_drawer.resize(actual_width, board_height) 845 887 self.removal_drawer.resize(actual_width, board_height) 846 888 self.win_drawer.resize(actual_width, board_height) … … def _get_icon_handle(file_path): 886 928 if file_path not in _icon_handles: 887 929 with open(file_path, 'r') as f: 888 930 data = f.read() 889 _icon_handles[file_path] = rsvg.Handle(data=data)931 _icon_handles[file_path] = Rsvg.Handle.new_from_data(data) 890 932 891 933 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') 21 21 22 22 from gettext import gettext as _ 23 23 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 24 from sugar3.activity.activity import Activity, get_bundle_path 25 from sugar3.graphics import style 26 from sugar3.graphics.icon import Icon 27 from sugar3.graphics.radiotoolbutton import RadioToolButton 28 from sugar3.graphics.toolbutton import ToolButton 29 30 from sugar3.activity.widgets import ActivityToolbarButton, StopButton 31 from sugar3.graphics.toolbarbox import ToolbarBox, ToolbarButton 39 32 40 33 from implodegame import ImplodeGame 41 34 from helpwidget import HelpWidget 42 35 43 36 import os 44 37 45 try: 46 import json 47 json.dumps 48 except (ImportError, AttributeError): 49 import simplejson as json 38 import json 50 39 from StringIO import StringIO 51 import gtk 52 import gobject 40 from gi.repository import Gtk 41 from gi.repository import GObject 42 from gi.repository import Gdk 53 43 54 44 from keymap import KEY_MAP 55 45 … … class ImplodeActivity(Activity): 63 53 64 54 self._game = ImplodeGame() 65 55 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) 68 58 self._stuck_strip = _StuckStrip() 69 59 70 60 self._configure_toolbars() … … class ImplodeActivity(Activity): 73 63 74 64 # Show everything except the stuck strip. 75 65 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) 77 67 78 68 self._game.connect('show-stuck', self._show_stuck_cb) 79 69 self._stuck_strip.connect('undo-clicked', self._stuck_undo_cb) … … class ImplodeActivity(Activity): 121 111 if data: 122 112 self._stuck_strip.show_all() 123 113 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() 126 117 self._stuck_strip.hide() 127 118 128 119 def _stuck_undo_cb(self, state, data=None): … … class ImplodeActivity(Activity): 133 124 action = KEY_MAP.get(event.keyval, None) 134 125 if action is None: 135 126 return False 136 if not self._stuck_strip.flags() & gtk.VISIBLE:127 if not self._stuck_strip.flags() & Gtk.VISIBLE: 137 128 return True 138 129 if self._game.focus_child: 139 130 if action == 'down': … … class ImplodeActivity(Activity): 152 143 controls, difficulty selector, help button, and stop button. All 153 144 callbacks are locally defined.""" 154 145 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 161 148 162 163 164 149 activity_button = ActivityToolbarButton(self) 150 toolbar_box.toolbar.insert(activity_button, 0) 151 activity_button.show() 165 152 166 toolbar.add(gtk.SeparatorToolItem())153 toolbar.add(Gtk.SeparatorToolItem()) 167 154 168 155 def add_button(icon_name, tooltip, func): 169 156 def callback(source): … … class ImplodeActivity(Activity): 176 163 add_button('new-game' , _("New") , self._game.new_game) 177 164 add_button('replay-game', _("Replay"), self._game.replay_game) 178 165 179 toolbar.add( gtk.SeparatorToolItem())166 toolbar.add(Gtk.SeparatorToolItem()) 180 167 181 168 add_button('edit-undo' , _("Undo") , self._game.undo) 182 169 add_button('edit-redo' , _("Redo") , self._game.redo) 183 170 184 toolbar.add( gtk.SeparatorToolItem())171 toolbar.add(Gtk.SeparatorToolItem()) 185 172 186 173 self._levels_buttons = [] 187 174 def add_level_button(icon_name, tooltip, numeric_level): … … class ImplodeActivity(Activity): 217 204 # right now, however. 218 205 add_button('help-icon', _("Help"), _help_clicked_cb) 219 206 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() 231 211 232 233 212 self.set_toolbar_box(toolbar_box) 213 toolbar_box.show() 234 214 235 215 def _add_expander(self, toolbar, expand=True): 236 216 """Insert a toolbar item which will expand to fill the available 237 217 space.""" 238 separator = gtk.SeparatorToolItem()218 separator = Gtk.SeparatorToolItem() 239 219 separator.props.draw = False 240 220 separator.set_expand(expand) 241 221 toolbar.insert(separator, -1) 242 222 separator.show() 243 223 244 224 245 class _DialogWindow( gtk.Window):225 class _DialogWindow(Gtk.Window): 246 226 # A base class for a modal dialog window. 247 227 def __init__(self, icon_name, title): 248 228 super(_DialogWindow, self).__init__() 249 229 250 230 self.set_border_width(style.LINE_WIDTH) 251 231 offset = style.GRID_CELL_SIZE 252 width = gtk.gdk.screen_width() / 2253 height = gtk.gdk.screen_height() / 2232 width = Gdk.Screen.width() / 2 233 height = Gdk.Screen.height() / 2 254 234 self.set_size_request(width, height) 255 self.set_position( gtk.WIN_POS_CENTER_ALWAYS)235 self.set_position(Gtk.WindowPosition.CENTER_ALWAYS) 256 236 self.set_decorated(False) 257 237 self.set_resizable(False) 258 238 self.set_modal(True) 259 239 260 vbox = gtk.VBox()240 vbox = Gtk.VBox() 261 241 self.add(vbox) 262 242 263 243 toolbar = _DialogToolbar(icon_name, title) 264 244 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) 266 246 267 self.content_vbox = gtk.VBox()247 self.content_vbox = Gtk.VBox() 268 248 self.content_vbox.set_border_width(style.DEFAULT_SPACING) 269 249 vbox.add(self.content_vbox) 270 250 … … class _DialogWindow(gtk.Window): 274 254 self.destroy() 275 255 276 256 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) 279 259 280 260 281 261 class _HelpWindow(_DialogWindow): … … class _HelpWindow(_DialogWindow): 284 264 super(_HelpWindow, self).__init__('help-icon', _("Help")) 285 265 286 266 offset = style.GRID_CELL_SIZE 287 width = gtk.gdk.screen_width() - offset * 2288 height = gtk.gdk.screen_height() - offset * 2267 width = Gdk.Screen.width() - offset * 2 268 height = Gdk.Screen.height() - offset * 2 289 269 self.set_size_request(width, height) 290 270 291 271 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) 293 273 294 274 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) 298 277 299 278 for (signal_name, callback) in [ 300 279 ('forward-clicked', self._forward_clicked_cb), … … class _HelpWindow(_DialogWindow): 316 295 self._help_widget.replay_stage() 317 296 318 297 def _icon_file(self, icon_name): 319 theme = gtk.icon_theme_get_default()298 theme = Gtk.IconTheme.get_default() 320 299 info = theme.lookup_icon(icon_name, 0, 0) 321 300 return info.get_filename() 322 301 … … class _HelpWindow(_DialogWindow): 326 305 self._help_nav_bar.set_can_next_stage(hw.can_next_stage()) 327 306 328 307 329 class _DialogToolbar( gtk.Toolbar):308 class _DialogToolbar(Gtk.Toolbar): 330 309 # Displays a dialog window's toolbar, with title, icon, and close box. 331 310 __gsignals__ = { 332 'stop-clicked' : ( gobject.SIGNAL_RUN_LAST, None, ()),311 'stop-clicked' : (GObject.SignalFlags.RUN_LAST, None, ()), 333 312 } 334 313 def __init__(self, icon_name, title): 335 314 super(_DialogToolbar, self).__init__() 336 315 337 316 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) 339 318 self._add_widget(icon) 340 319 341 320 self._add_separator() 342 321 343 label = gtk.Label(title)322 label = Gtk.Label(label=title) 344 323 self._add_widget(label) 345 324 346 325 self._add_separator(expand=True) … … class _DialogToolbar(gtk.Toolbar): 351 330 self.add(stop) 352 331 353 332 def _add_separator(self, expand=False): 354 separator = gtk.SeparatorToolItem()333 separator = Gtk.SeparatorToolItem() 355 334 separator.set_expand(expand) 356 335 separator.set_draw(False) 357 336 self.add(separator) 358 337 359 338 def _add_widget(self, widget): 360 tool_item = gtk.ToolItem()339 tool_item = Gtk.ToolItem() 361 340 tool_item.add(widget) 362 341 self.add(tool_item) 363 342 … … class _DialogToolbar(gtk.Toolbar): 365 344 self.emit('stop-clicked') 366 345 367 346 368 class _HelpNavBar( gtk.HButtonBox):347 class _HelpNavBar(Gtk.HButtonBox): 369 348 # A widget to display the navigation controls at the bottom of the help 370 349 # dialog. 371 350 __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, ()), 375 354 } 376 355 377 356 def __init__(self): 378 357 super(_HelpNavBar, self).__init__() 379 358 380 self.set_layout( gtk.BUTTONBOX_SPREAD)359 self.set_layout(Gtk.ButtonBoxStyle.SPREAD) 381 360 382 361 def add_button(icon_name, tooltip, signal_name): 383 362 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() 386 365 button.set_image(icon) 387 366 button.set_tooltip_text(tooltip) 388 367 self.add(button) … … class _HelpNavBar(gtk.HButtonBox): 404 383 self._forward_button.set_sensitive(can_next_stage) 405 384 406 385 407 class _StuckStrip( gtk.HBox):386 class _StuckStrip(Gtk.HBox): 408 387 __gsignals__ = { 409 'undo-clicked' : ( gobject.SIGNAL_RUN_LAST, None, ()),388 'undo-clicked' : (GObject.SignalFlags.RUN_LAST, None, ()), 410 389 } 411 390 def __init__(self, *args, **kwargs): 412 391 super(_StuckStrip, self).__init__(*args, **kwargs) 413 392 414 spacer1 = gtk.Label('')415 self.pack_start(spacer1, expand=True)393 spacer1 = Gtk.Label(label='') 394 self.pack_start(spacer1, True, True, 0) 416 395 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) 419 398 420 399 self.set_spacing(10) 421 400 422 401 self.set_border_width(10) 423 402 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) 426 405 427 406 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) 430 409 self.button.set_image(icon) 431 410 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) 433 412 434 413 def callback(source): 435 414 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') 21 21 22 22 from gettext import gettext as _ 23 23 24 import gtk25 import gobject24 from gi.repository import Gtk 25 from gi.repository import GObject 26 26 import random 27 27 import time 28 28 … … _STUCK_DELAY = 0.5 39 39 # state after the player gets stuck, in seconds. 40 40 _UNDO_DELAY = 0.3 41 41 42 class ImplodeGame( gtk.EventBox):42 class ImplodeGame(Gtk.EventBox): 43 43 """Gtk widget for playing the implode game.""" 44 44 45 45 __gsignals__ = { 46 'show-stuck': ( gobject.SIGNAL_RUN_LAST, None, (int,)),46 'show-stuck': (GObject.SignalFlags.RUN_LAST, None, (int,)), 47 47 } 48 48 49 49 def __init__(self, *args, **kwargs): -
keymap.py
diff --git a/keymap.py b/keymap.py index b420ace..0322b22 100644
a b 16 16 # along with this program; if not, write to the Free Software 17 17 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 18 19 import gtk19 from gi.repository import Gdk 20 20 21 21 KEY_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', 62 62 } -
setup.py
diff --git a/setup.py b/setup.py index 211f104..cbdf097 100644
a b 1 1 #!/usr/bin/env python 2 2 3 from sugar .activity import bundlebuilder3 from sugar3.activity import bundlebuilder 4 4 if __name__ == "__main__": 5 5 bundlebuilder.start() -
sugarless.py
diff --git a/sugarless.py b/sugarless.py index 6a9f3ea..db4937b 100644
a b 19 19 # A stub file for running the application on a sugarless GTK, when the Activity 20 20 # framework is not available. 21 21 22 import pygtk 23 pygtk.require('2.0') 24 import gtk 25 import gobject 22 from gi.repository import Gtk 23 from gi.repository import Gdk 24 from gi.repository import GObject 26 25 27 26 import os 28 27 … … from keymap import KEY_MAP 32 31 33 32 _DEFAULT_SPACING = 15 34 33 35 class ImplodeWindow(gtk.Window): 34 import logging 35 LOG_FILENAME = '/tmp/logging_example.out' 36 logging.basicConfig(filename=LOG_FILENAME, level=logging.DEBUG) 37 38 logging.debug('This message should go to the log file') 39 40 41 class ImplodeWindow(Gtk.Window): 36 42 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) 39 50 self.set_title("Implode") 40 51 41 52 self.connect("delete_event", self._delete_event_cb) 42 53 43 toolbar = gtk.Toolbar()54 toolbar = Gtk.Toolbar() 44 55 self.game = implodegame.ImplodeGame() 45 56 46 57 def add_button(id, func): 47 button = gtk.ToolButton(id)58 button = Gtk.ToolButton(id) 48 59 toolbar.add(button) 49 60 50 61 def callback(source): … … class ImplodeWindow(gtk.Window): 53 64 54 65 return button 55 66 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) 60 71 61 toolbar.add( gtk.SeparatorToolItem())72 toolbar.add(Gtk.SeparatorToolItem()) 62 73 63 74 radio_buttons = [] 64 75 def add_radio_button(label, func): 65 button = gtk.RadioToolButton()76 button = Gtk.RadioToolButton() 66 77 button.set_label(label) 67 78 toolbar.add(button) 68 79 radio_buttons.append(button) … … class ImplodeWindow(gtk.Window): 77 88 add_radio_button('easy', self._easy_clicked) 78 89 add_radio_button('medium', self._medium_clicked) 79 90 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]) 82 94 83 separator = gtk.SeparatorToolItem()95 separator = Gtk.SeparatorToolItem() 84 96 separator.set_expand(True) 85 97 separator.set_draw(False) 86 98 toolbar.add(separator) 87 99 88 add_button( gtk.STOCK_HELP, self._help_clicked)100 add_button(Gtk.STOCK_HELP, self._help_clicked) 89 101 90 102 self._stuck_strip = _StuckStrip() 91 103 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) 95 108 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) 99 112 self.add(main_box) 100 113 101 114 # Show everything except the stuck strip. … … class ImplodeWindow(gtk.Window): 111 124 self.show() 112 125 113 126 def _delete_event_cb(self, window, event): 114 gtk.main_quit()127 Gtk.main_quit() 115 128 return False 116 129 117 130 def _easy_clicked(self): … … class ImplodeWindow(gtk.Window): 132 145 if data: 133 146 self._stuck_strip.show_all() 134 147 else: 135 if self._stuck_strip.focus_child:136 148 # if self._stuck_strip.focus_child: 149 self.game.grab_focus() 137 150 self._stuck_strip.hide() 138 151 139 152 def _stuck_undo_cb(self, state, data=None): … … class ImplodeWindow(gtk.Window): 144 157 action = KEY_MAP.get(event.keyval, None) 145 158 if action is None: 146 159 return False 147 if not self._stuck_strip.flags() & gtk.VISIBLE:160 if not self._stuck_strip.flags() & Gtk.VISIBLE: 148 161 return True 149 162 if self.game.focus_child: 150 163 if action == 'down': … … class ImplodeWindow(gtk.Window): 158 171 return True 159 172 return True 160 173 161 class _HelpWindow( gtk.Window):174 class _HelpWindow(Gtk.Window): 162 175 def __init__(self): 163 176 super(_HelpWindow, self).__init__() 164 177 165 178 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) 167 180 self.set_modal(True) 168 181 169 vbox = gtk.VBox()182 vbox = Gtk.VBox() 170 183 self.add(vbox) 171 184 172 185 self._help_widget = HelpWidget(self._icon_file) 173 vbox.pack_start(self._help_widget )186 vbox.pack_start(self._help_widget, True, True, 0) 174 187 175 188 self._help_nav_bar = _HelpNavBar() 176 189 vbox.pack_end(self._help_nav_bar, 177 expand=False) 190 expand=False, fill=False, 191 padding=0) 178 192 179 193 for (signal_name, callback) in [ 180 194 ('forward-clicked', self._forward_clicked_cb), … … class _HelpWindow(gtk.Window): 207 221 self._help_nav_bar.set_can_next_stage(hw.can_next_stage()) 208 222 209 223 210 class _HelpNavBar( gtk.HButtonBox):224 class _HelpNavBar(Gtk.HButtonBox): 211 225 __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, ()), 215 229 } 216 230 217 231 def __init__(self): 218 232 super(_HelpNavBar, self).__init__() 219 233 220 self.set_layout( gtk.BUTTONBOX_SPREAD)234 self.set_layout(Gtk.ButtonBoxStyle.SPREAD) 221 235 222 236 def add_button(id, signal_name): 223 button = gtk.Button(stock=id)237 button = Gtk.Button(stock=id) 224 238 self.add(button) 225 239 226 240 def callback(source): … … class _HelpNavBar(gtk.HButtonBox): 229 243 230 244 return button 231 245 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') 235 249 236 250 def set_can_prev_stage(self, can_prev_stage): 237 251 self._back_button.set_sensitive(can_prev_stage) … … class _HelpNavBar(gtk.HButtonBox): 240 254 self._forward_button.set_sensitive(can_next_stage) 241 255 242 256 243 class _StuckStrip( gtk.HBox):257 class _StuckStrip(Gtk.HBox): 244 258 __gsignals__ = { 245 'undo-clicked' : ( gobject.SIGNAL_RUN_LAST, None, ()),259 'undo-clicked' : (GObject.SignalFlags.RUN_LAST, None, ()), 246 260 } 247 261 def __init__(self, *args, **kwargs): 248 262 super(_StuckStrip, self).__init__(*args, **kwargs) 249 263 250 spacer1 = gtk.Label('')251 self.pack_start(spacer1, expand=True)264 spacer1 = Gtk.Label(label='') 265 self.pack_start(spacer1, True, True, 0) 252 266 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) 255 269 256 270 self.set_spacing(10) 257 271 258 272 self.set_border_width(10) 259 273 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) 262 276 263 self.button = gtk.Button(stock=gtk.STOCK_UNDO)277 self.button = Gtk.Button(stock=Gtk.STOCK_UNDO) 264 278 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) 266 280 267 281 def callback(source): 268 282 self.emit('undo-clicked') … … class _StuckStrip(gtk.HBox): 271 285 272 286 def main(): 273 287 w = ImplodeWindow() 274 gtk.main()288 Gtk.main() 275 289 276 290 if __name__ == "__main__": 277 291 main()