diff --git a/pysollib/acard.py b/pysollib/acard.py index 510b3270..f2ac72a5 100644 --- a/pysollib/acard.py +++ b/pysollib/acard.py @@ -95,6 +95,7 @@ class AbstractCard: return self.hide_stack is not None def moveTo(self, x, y): + ##print 'moveTo', x, y # Move the card to absolute position (x, y). dx, dy = 0, 0 if self.game.app.opt.randomize_place: diff --git a/pysollib/app.py b/pysollib/app.py index cd06d797..3a34b466 100644 --- a/pysollib/app.py +++ b/pysollib/app.py @@ -661,13 +661,13 @@ class Application: self.top.grid_rowconfigure(1, weight=1) self.setTile(self.tabletile_index, force=True) # create the toolbar + dir = self.getToolbarImagesDir() + self.toolbar = PysolToolbar(self.top, dir=dir, + size=self.opt.toolbar_size, + relief=self.opt.toolbar_relief, + compound=self.opt.toolbar_compound) + self.toolbar.show(self.opt.toolbar) if TOOLKIT == 'tk': - dir = self.getToolbarImagesDir() - self.toolbar = PysolToolbar(self.top, dir=dir, - size=self.opt.toolbar_size, - relief=self.opt.toolbar_relief, - compound=self.opt.toolbar_compound) - self.toolbar.show(self.opt.toolbar) for w, v in self.opt.toolbar_vars.items(): self.toolbar.config(w, v) # @@ -807,8 +807,7 @@ class Application: # free game def freeGame(self): # disconnect from game - if self.toolbar: ##~ - self.toolbar.connectGame(None, None) + self.toolbar.connectGame(None, None) self.menubar.connectGame(None) # clean up the canvas self.canvas.deleteAllItems() diff --git a/pysollib/game.py b/pysollib/game.py index 975921ba..4b1353d1 100644 --- a/pysollib/game.py +++ b/pysollib/game.py @@ -181,41 +181,7 @@ class Game: assert hasattr(self.s.talon, "round") assert hasattr(self.s.talon, "max_rounds") if self.app.debug: - class_name = self.__class__.__name__ - if self.s.foundations: - ncards = 0 - for stack in self.s.foundations: - ncards += stack.cap.max_cards - if ncards != self.gameinfo.ncards: - print 'WARNING: invalid sum of foundations.max_cards:', \ - class_name, ncards, self.gameinfo.ncards - if self.s.rows: - from stack import AC_RowStack, UD_AC_RowStack, \ - SS_RowStack, UD_SS_RowStack, \ - RK_RowStack, UD_RK_RowStack, \ - Spider_AC_RowStack, Spider_SS_RowStack - r = self.s.rows[0] - for c, f in ( - ((Spider_AC_RowStack, Spider_SS_RowStack), - (self._shallHighlightMatch_RK, - self._shallHighlightMatch_RKW)), - ((AC_RowStack, UD_AC_RowStack), - (self._shallHighlightMatch_AC, - self._shallHighlightMatch_ACW)), - ((SS_RowStack, UD_SS_RowStack), - (self._shallHighlightMatch_SS, - self._shallHighlightMatch_SSW)), - ((RK_RowStack, UD_RK_RowStack), - (self._shallHighlightMatch_RK, - self._shallHighlightMatch_RKW)),): - if isinstance(r, c): - if not self.shallHighlightMatch in f: - print 'WARNING: shallHighlightMatch is not valid:', \ - class_name, r.__class__ - if r.cap.mod == 13 and self.shallHighlightMatch != f[1]: - print 'WARNING: shallHighlightMatch is not valid (wrap):', \ - class_name, r.__class__ - break + self._checkGame() # optimize regions self.optimizeRegions() # create cards @@ -243,6 +209,45 @@ class Game: ##print timer self.showHelp() # just in case + + def _checkGame(self): + class_name = self.__class__.__name__ + if self.s.foundations: + ncards = 0 + for stack in self.s.foundations: + ncards += stack.cap.max_cards + if ncards != self.gameinfo.ncards: + print 'WARNING: invalid sum of foundations.max_cards:', \ + class_name, ncards, self.gameinfo.ncards + if self.s.rows: + from stack import AC_RowStack, UD_AC_RowStack, \ + SS_RowStack, UD_SS_RowStack, \ + RK_RowStack, UD_RK_RowStack, \ + Spider_AC_RowStack, Spider_SS_RowStack + r = self.s.rows[0] + for c, f in ( + ((Spider_AC_RowStack, Spider_SS_RowStack), + (self._shallHighlightMatch_RK, + self._shallHighlightMatch_RKW)), + ((AC_RowStack, UD_AC_RowStack), + (self._shallHighlightMatch_AC, + self._shallHighlightMatch_ACW)), + ((SS_RowStack, UD_SS_RowStack), + (self._shallHighlightMatch_SS, + self._shallHighlightMatch_SSW)), + ((RK_RowStack, UD_RK_RowStack), + (self._shallHighlightMatch_RK, + self._shallHighlightMatch_RKW)),): + if isinstance(r, c): + if not self.shallHighlightMatch in f: + print 'WARNING: shallHighlightMatch is not valid:', \ + class_name, r.__class__ + if r.cap.mod == 13 and self.shallHighlightMatch != f[1]: + print 'WARNING: shallHighlightMatch is not valid (wrap):', \ + class_name, r.__class__ + break + + def initBindings(self): # note: a Game is only allowed to bind self.canvas and not to self.top ##bind(self.canvas, "<1>", self.clickHandler) @@ -768,6 +773,7 @@ class Game: return EVENT_PROPAGATE def undoHandler(self, event): + if not self.app: return EVENT_PROPAGATE # FIXME (GTK) self._defaultHandler() if self.app.opt.mouse_undo and not self.event_handled: self.app.menubar.mUndo() @@ -775,6 +781,7 @@ class Game: return EVENT_PROPAGATE def redoHandler(self, event): + if not self.app: return EVENT_PROPAGATE # FIXME (GTK) self._defaultHandler() if self.app.opt.mouse_undo and not self.event_handled: self.app.menubar.mRedo() diff --git a/pysollib/pysolgtk/menubar.py b/pysollib/pysolgtk/menubar.py index 77054ded..48606bd2 100644 --- a/pysollib/pysolgtk/menubar.py +++ b/pysollib/pysolgtk/menubar.py @@ -31,11 +31,10 @@ # imports -import math, os, re, string, sys +import os, re, sys import gtk from gtk import gdk -TRUE, FALSE = True, False # PySol imports from pysollib.gamedb import GI @@ -57,23 +56,32 @@ from selectcardset import SelectCardsetByTypeDialogWithPreview class PysolMenubar(PysolMenubarActions): def __init__(self, app, top, progress=None): PysolMenubarActions.__init__(self, app, top) - self.menus = None - self.menu_items = None + self.progress = progress + ##self.menus = None + ##self.menu_items = None # create menus - menubar, accel = self.createMenus() - # additional key bindings - ### FIXME - ###self.accel.add("Space", None, None, None, None) - # delete the old menubar - # set the menubar - ##~ accel.attach(self.top) - top.add_accel_group(accel) - w = menubar.get_widget('
') - self.top.vbox.pack_start(w, expand=FALSE, fill=FALSE) - self.top.vbox.reorder_child(w, 0) - self.__menubar = menubar - self.__accel = accel - self.menus = menubar + menubar = self.createMenubar() + self.top.table.attach(menubar, + 0, 1, 0, 1, + gtk.EXPAND | gtk.FILL, 0, + 0, 0); + menubar.show() + + +## menubar, accel = self.createMenus() +## # additional key bindings +## ### FIXME +## ###self.accel.add("Space", None, None, None, None) +## # delete the old menubar +## # set the menubar +## ##~ accel.attach(self.top) +## top.add_accel_group(accel) +## w = menubar.get_widget('
') +## self.top.vbox.pack_start(w, expand=FALSE, fill=FALSE) +## self.top.vbox.reorder_child(w, 0) +## self.__menubar = menubar +## self.__accel = accel +## self.menus = menubar # @@ -84,141 +92,301 @@ class PysolMenubar(PysolMenubarActions): ##print args pass - def _initItemFactory(self): - self.menu_items = ( - ("/_File", None, None, 0, ""), - ("/File/", None, None, 0, ""), - ("/File/_New Game", "N", self.mNewGame, 0, ""), - ("/File/Select _game", None, None, 0, ""), - ) + def createMenubar(self): - # - # /File/Select game - # + entries = ( + ('New', gtk.STOCK_NEW, '_New', 'N', 'New game', self.mNewGame), + ('Open', gtk.STOCK_OPEN, '_Open', 'O', 'Open a\nsaved game', self.mOpen), + ('Restart', gtk.STOCK_REFRESH, '_Restart', 'G', 'Restart the\ncurrent game', self.mRestart), + ('Save', gtk.STOCK_SAVE, '_Save', 'S', 'Save game', self.mSave), + ('Undo', gtk.STOCK_UNDO, 'Undo', 'Z', 'Undo', self.mUndo), + ('Redo', gtk.STOCK_REDO, 'Redo', 'R', 'Redo', self.mRedo), + ('Autodrop',gtk.STOCK_JUMP_TO, '_Auto drop', 'A', 'Auto drop', self.mDrop), + ('Stats', gtk.STOCK_EXECUTE, 'Stats', None, 'Statistics', self.mStatus), + ('Rules', gtk.STOCK_HELP, 'Rules', None, 'Rules', self.mHelpRules), + ('Quit', gtk.STOCK_QUIT, 'Quit', 'Q', 'Quit PySol', self.mQuit), - mi, radio = [], "" - games = self.app.gdb.getGamesIdSortedByName() + ("FileMenu", None, "_File" ), + ("SelectGame", None, "Select _game"), + ("EditMenu", None, '_Edit'), + ("GameMenu", None, "_Game"), + ("AssistMenu", None, "_Assist"), + ("OptionsMenu", None, "_Options"), + ("HelpMenu", None, "_Help"), + + ('SelectGameByNumber', None, "Select game by number...", None, None, self.mSelectGameById), + ("SaveAs", None, 'Save _as...', None, None, self.m), + ("RedoAll", None, 'Redo _all', None, None, self.mRedoAll), + ("DealCards", None, '_Deal cards', "D", None, self.mDeal), + ("Status", None, 'S_tatus...', "T", None, self.mStatus), + ("Hint", None, '_Hint', "H", None, self.mHint), + ("HighlightPiles", None, 'Highlight _piles', None, None, self.mHighlightPiles), + ("Demo", None, '_Demo', "D", None, self.mDemo), + ("DemoAllGames", None, 'Demo (all games)', None, None, self.mMixedDemo), + ("Contents", None, '_Contents', 'F1', None, self.mHelp), + ("About", None, '_About PySol...', None, None, self.mHelpAbout), +) + + toggle_entries = ( + ("Confirm", None, '_Confirm', None, None, self.mOptConfirm), + ("Autoplay", None, 'Auto_play', "P", None, self.mOptAutoDrop), + ("AutomaticFaceUp", None,'_Automatic _face up', "F", None, self.mOptAutoFaceUp), + ("HighlightMatchingCards", None, 'Highlight _matching cards', None, None, self.mOptEnableHighlightCards), + ("CardShadow", None, 'Card shadow', None, None, self.mOptShadow), + ("ShadeLegalMoves", None, 'Shade legal moves', None, None, self.mOptShade), + +) + + ui_info = ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +''' + # + ui_manager = gtk.UIManager() + ui_manager_id = ui_manager.add_ui_from_string(ui_info) + + action_group = gtk.ActionGroup("PySolActions") + action_group.add_actions(entries) + action_group.add_toggle_actions(toggle_entries) + + ui_manager.insert_action_group(action_group, 0) + self.top.add_accel_group(ui_manager.get_accel_group()) + self.top.ui_manager = ui_manager + menubar = ui_manager.get_widget("/MenuBar") + + games = map(self.app.gdb.get, self.app.gdb.getGamesIdSortedByName()) + + menu_item = ui_manager.get_widget("/MenuBar/FileMenu/SelectGame") + menu_item.show() + menu = gtk.Menu() + menu_item.set_submenu(menu) + self._addSelectAllGameSubMenu(games, menu, self.mSelectGame) + + return menubar + + + def _createSubMenu(self, menu, label): + menu_item = gtk.MenuItem(label) + menu.add(menu_item) + menu_item.show() + submenu = gtk.Menu() + menu_item.set_submenu(submenu) + return submenu + + def _addSelectGameSubMenu(self, games, menu, command, group): + for g in games: + label = g.name + menu_item = gtk.RadioMenuItem(group, label) + group = menu_item + menu.add(menu_item) + menu_item.show() + menu_item.connect('toggled', command, g.id) + + def _addSelectAllGameSubMenu(self, games, menu, command): + cb_max = gdk.screen_height()/20 + n, d = 0, cb_max i = 0 - path = "/File/Select game" - columnbreak = 25 - n = 0 - mm = [] - t1 = t2 = None - for id in games: - if t1 is None: - t1 = self.app.getGameMenuitemName(id)[:3] - if n == columnbreak: - t2 = self.app.getGameMenuitemName(id)[:3] - pp = '%s/%s-%s' % (path, t1, t2) - mi.append((pp, None, None, 0, '')) - for m in mm: - p = '%s/%s' % (pp, m[0]) - mi.append((p, None, self.mSelectGame, m[1], radio)) - if radio[0] == '<': - radio = re.sub('_', '', p) - n = 0 - mm = [] - t1 = t2 + group = None + while True: + if self.progress: self.progress.update(step=1) + i += 1 + if not games[n:n+d]: + break + m = min(n+d-1, len(games)-1) + label = games[n].name[:3]+' - '+games[m].name[:3] + submenu = self._createSubMenu(menu, label=label) + group = self._addSelectGameSubMenu(games[n:n+d], submenu, + command, group) + n += d - mm.append((self.app.getGameMenuitemName(id), id)) - n += 1 - t2 = self.app.getGameMenuitemName(id)[:3] - pp = '%s/%s-%s' % (path, t1, t2) - mi.append((pp, None, None, 0, '')) - for m in mm: - p = '%s/%s' % (pp, m[0]) - mi.append((p, None, self.mSelectGame, m[1], radio)) +## def _initItemFactory(self): +## self.menu_items = ( +## ("/_File", None, None, 0, ""), +## ("/File/", None, None, 0, ""), +## ("/File/_New Game", "N", self.mNewGame, 0, ""), +## ("/File/Select _game", None, None, 0, ""), +## ) - self.menu_items = self.menu_items + tuple(mi) - self.tkopt.gameid.path = radio +## # +## # /File/Select game +## # - # - # - # +## mi, radio = [], "" +## games = self.app.gdb.getGamesIdSortedByName() +## i = 0 +## path = "/File/Select game" +## columnbreak = 25 +## n = 0 +## mm = [] +## t1 = t2 = None +## for id in games: +## if t1 is None: +## t1 = self.app.getGameMenuitemName(id)[:3] +## if n == columnbreak: +## t2 = self.app.getGameMenuitemName(id)[:3] +## pp = '%s/%s-%s' % (path, t1, t2) +## mi.append((pp, None, None, 0, '')) +## for m in mm: +## p = '%s/%s' % (pp, m[0]) +## mi.append((p, None, self.mSelectGame, m[1], radio)) +## if radio[0] == '<': +## radio = re.sub('_', '', p) +## n = 0 +## mm = [] +## t1 = t2 - self.menu_items = self.menu_items + ( - ("/File/Select game by number...", None, self.mSelectGameById, 0, ""), - ("/File/", None, None, 0, ""), - ("/File/_Open", "O", self.m, 0, ""), - ("/File/_Save", "S", self.mSave, 0, ""), - ("/File/Save _as...", None, self.m, 0, ""), - ("/File/", None, None, 0, ""), - ("/File/_Quit", "Q", self.mQuit, 0, ""), - ("/_Edit", None, None, 0, ""), - ("/Edit/", None, None, 0, ""), - ("/Edit/_Undo", "Z", self.mUndo, 0, ""), - ("/Edit/_Redo", "R", self.mRedo, 0, ""), - ("/Edit/Redo _all", None, self.mRedoAll, 0, ""), - ("/Edit/", None, None, 0, ""), - ("/Edit/Restart _game", "G", self.mRestart, 0, ""), - ("/_Game", None, None, 0, ""), - ("/Game/", None, None, 0, ""), - ("/Game/_Deal cards", "D", self.mDeal, 0, ""), - ("/Game/_Auto drop", "A", self.mDrop, 0, ""), - ("/Game/", None, None, 0, ""), - ("/Game/S_tatus...", "T", self.mStatus, 0, ""), - ("/_Assist", None, None, 0, ""), - ("/Assist/", None, None, 0, ""), - ("/Assist/_Hint", "H", self.mHint, 0, ""), - ("/Assist/Highlight _piles", "Shift", self.mHighlightPiles, 0, ""), - ("/Assist/", None, None, 0, ""), - ("/Assist/_Demo", "D", self.mDemo, 0, ""), - ("/Assist/Demo (all games)", "", self.mMixedDemo, 0, ""), - ("/_Options", None, None, 0, ""), - ("/Options/", None, None, 0, ""), - ("/Options/_Confirm", None, self.mOptConfirm, 0, ""), - ("/Options/Auto_play", "P", self.mOptAutoDrop, 0, ""), - ("/Options/_Automatic _face up", "F", self.mOptAutoFaceUp, 0, ""), - ("/Options/Highlight _matching cards", None, self.mOptEnableHighlightCards, 0, ""), - ("/Options/", None, None, 0, ""), - ) +## mm.append((self.app.getGameMenuitemName(id), id)) +## n += 1 - mi, radio = [], "" - path = "/Options/Cards_et" - mi.append((path, None, None, 0, "")) - for i in range(self.app.cardset_manager.len()): - columnbreak = i > 0 and (i % 25) == 0 - p = path + '/' + self.app.cardset_manager.get(i).name - mi.append((p, None, self.mOptCardset, i, radio)) - if radio[0] == '<': - radio = re.sub('_', '', p) - self.menu_items = self.menu_items + tuple(mi) -## self.tkopt.cardset.path = radio +## t2 = self.app.getGameMenuitemName(id)[:3] +## pp = '%s/%s-%s' % (path, t1, t2) +## mi.append((pp, None, None, 0, '')) +## for m in mm: +## p = '%s/%s' % (pp, m[0]) +## mi.append((p, None, self.mSelectGame, m[1], radio)) - self.menu_items = self.menu_items + ( - ("/Options/Table color...", None, self.mOptTableColor, 0, ""), - ) +## self.menu_items = self.menu_items + tuple(mi) +## self.tkopt.gameid.path = radio - mi, radio = [], "" - path = "/Options/_Animations" - mi.append((path, None, None, 0, "")) - i = 0 - for k in ("_None", "_Fast", "_Timer based"): - p = path + '/' + k - mi.append((p, None, self.mOptAnimations, i, radio)) - if radio[0] == '<': - radio = re.sub('_', '', p) - i = i + 1 - self.menu_items = self.menu_items + tuple(mi) - self.tkopt.animations.path = radio +## # +## # +## # - self.menu_items = self.menu_items + ( - ("/Options/Card shadow", None, self.mOptShadow, 0, ""), - ("/Options/Shade legal moves", None, self.mOptShade, 0, ""), - ("/Options/", None, None, 0, ""), - ("/Options/_Hint options...", None, self.mOptHintOptions, 0, ""), - ("/Options/_Demo options...", None, self.mOptDemoOptions, 0, ""), - ("/_Help", None, None, 0, ""), - ("/Help/", None, None, 0, ""), - ("/Help/_Contents", "F1", self.mHelp, 0, ""), - ("/Help/_Rules", None, self.mHelpRules, 0, ""), - ("/Help/", None, None, 0, ""), - ("/Help/_About PySol...", None, self.mHelpAbout, 0, ""), - ) +## self.menu_items = self.menu_items + ( +## ("/File/Select game by number...", None, self.mSelectGameById, 0, ""), +## ("/File/", None, None, 0, ""), +## ("/File/_Open", "O", self.m, 0, ""), +## ("/File/_Save", "S", self.mSave, 0, ""), +## ("/File/Save _as...", None, self.m, 0, ""), +## ("/File/", None, None, 0, ""), +## ("/File/_Quit", "Q", self.mQuit, 0, ""), +## ("/_Edit", None, None, 0, ""), +## ("/Edit/", None, None, 0, ""), +## ("/Edit/_Undo", "Z", self.mUndo, 0, ""), +## ("/Edit/_Redo", "R", self.mRedo, 0, ""), +## ("/Edit/Redo _all", None, self.mRedoAll, 0, ""), +## ("/Edit/", None, None, 0, ""), +## ("/Edit/Restart _game", "G", self.mRestart, 0, ""), +## ("/_Game", None, None, 0, ""), +## ("/Game/", None, None, 0, ""), +## ("/Game/_Deal cards", "D", self.mDeal, 0, ""), +## ("/Game/_Auto drop", "A", self.mDrop, 0, ""), +## ("/Game/", None, None, 0, ""), +## ("/Game/S_tatus...", "T", self.mStatus, 0, ""), +## ("/_Assist", None, None, 0, ""), +## ("/Assist/", None, None, 0, ""), +## ("/Assist/_Hint", "H", self.mHint, 0, ""), +## ("/Assist/Highlight _piles", "Shift", self.mHighlightPiles, 0, ""), +## ("/Assist/", None, None, 0, ""), +## ("/Assist/_Demo", "D", self.mDemo, 0, ""), +## ("/Assist/Demo (all games)", "", self.mMixedDemo, 0, ""), +## ("/_Options", None, None, 0, ""), +## ("/Options/", None, None, 0, ""), +## ("/Options/_Confirm", None, self.mOptConfirm, 0, ""), +## ("/Options/Auto_play", "P", self.mOptAutoDrop, 0, ""), +## ("/Options/_Automatic _face up", "F", self.mOptAutoFaceUp, 0, ""), +## ("/Options/Highlight _matching cards", None, self.mOptEnableHighlightCards, 0, ""), +## ("/Options/", None, None, 0, ""), +## ) + +## mi, radio = [], "" +## path = "/Options/Cards_et" +## mi.append((path, None, None, 0, "")) +## for i in range(self.app.cardset_manager.len()): +## columnbreak = i > 0 and (i % 25) == 0 +## p = path + '/' + self.app.cardset_manager.get(i).name +## mi.append((p, None, self.mOptCardset, i, radio)) +## if radio[0] == '<': +## radio = re.sub('_', '', p) +## self.menu_items = self.menu_items + tuple(mi) +## ## self.tkopt.cardset.path = radio + +## self.menu_items = self.menu_items + ( +## ("/Options/Table color...", None, self.mOptTableColor, 0, ""), +## ) + +## mi, radio = [], "" +## path = "/Options/_Animations" +## mi.append((path, None, None, 0, "")) +## i = 0 +## for k in ("_None", "_Fast", "_Timer based"): +## p = path + '/' + k +## mi.append((p, None, self.mOptAnimations, i, radio)) +## if radio[0] == '<': +## radio = re.sub('_', '', p) +## i = i + 1 +## self.menu_items = self.menu_items + tuple(mi) +## self.tkopt.animations.path = radio + +## self.menu_items = self.menu_items + ( +## ("/Options/Card shadow", None, self.mOptShadow, 0, ""), +## ("/Options/Shade legal moves", None, self.mOptShade, 0, ""), +## ("/Options/", None, None, 0, ""), +## ("/Options/_Hint options...", None, self.mOptHintOptions, 0, ""), +## ("/Options/_Demo options...", None, self.mOptDemoOptions, 0, ""), +## ("/_Help", None, None, 0, ""), +## ("/Help/", None, None, 0, ""), +## ("/Help/_Contents", "F1", self.mHelp, 0, ""), +## ("/Help/_Rules", None, self.mHelpRules, 0, ""), +## ("/Help/", None, None, 0, ""), +## ("/Help/_About PySol...", None, self.mHelpAbout, 0, ""), +## ) def createMenus(self): + return self._initUI() + if not self.menu_items: self._initItemFactory() accel = gtk.AccelGroup() @@ -289,7 +457,7 @@ class PysolMenubar(PysolMenubarActions): def updateFavoriteGamesMenu(self, *args): pass -## def mSelectGame(self, gameid, menuitem): -## if menuitem.get_active(): -## self._mSelectGame(gameid) + def mSelectGame(self, menu_item, game_id): + if menu_item.get_active(): + self._mSelectGame(game_id) diff --git a/pysollib/pysolgtk/progressbar.py b/pysollib/pysolgtk/progressbar.py index 957c1d2e..39b9afaa 100644 --- a/pysollib/pysolgtk/progressbar.py +++ b/pysollib/pysolgtk/progressbar.py @@ -51,6 +51,7 @@ class PysolProgressBar: height=25, show_text=1, norm=1): self.parent = parent self.percent = 0 + self.steps_sum = 0 self.norm = norm self.top = makeToplevel(parent, title=title) self.top.set_position(gtk.WIN_POS_CENTER) @@ -62,7 +63,11 @@ class PysolProgressBar: hbox = gtk.HBox(spacing=5) hbox.set_border_width(10) hbox.show() - self.top.vbox.pack_start(hbox, FALSE, FALSE) + self.top.table.attach(hbox, + 0, 1, 0, 1, + 0, 0, + 0, 0) + # hbox-1: image ## if images and images[0]: ## im = images[0].clone() @@ -112,19 +117,23 @@ class PysolProgressBar: pass def update(self, percent=None, step=1): + ##self.steps_sum += step + ##print self.steps_sum, self.norm + step = step/self.norm if percent is None: - self.percent = self.percent + step + self.percent += step elif percent > self.percent: self.percent = percent - self.percent = min(100, max(0, self.percent)) - self.pbar.set_fraction(self.percent / 100.0) - self.pbar.set_text(str(int(self.percent))+'%') + percent = int(self.percent) + percent = min(100, max(0, percent)) + self.pbar.set_fraction(percent / 100.0) + self.pbar.set_text(str(percent)+'%') ##~ self.pbar.update(self.percent / 100.0) self.update_idletasks() def update_idletasks(self): while gtk.events_pending(): - gtk.mainiteration() + gtk.main_iteration() def wmDeleteWindow(self, *args): return TRUE @@ -163,7 +172,7 @@ def progressbar_main(args): im = loadImage(os.path.join(os.pardir, os.pardir, 'data', 'images', 'jokers', 'joker07_40_774.gif')) images = (im, im) pb = TestProgressBar(root, images=images) - mainloop() + main() return 0 if __name__ == '__main__': diff --git a/pysollib/pysolgtk/tkcanvas.py b/pysollib/pysolgtk/tkcanvas.py index c1c5b716..0868b0ec 100644 --- a/pysollib/pysolgtk/tkcanvas.py +++ b/pysollib/pysolgtk/tkcanvas.py @@ -70,25 +70,31 @@ from tkutil import anchor_tk2gtk, loadImage, bind # ************************************************************************/ class _CanvasItem: + def __init__(self, canvas): self.canvas = canvas + canvas._all_items.append(self) + def addtag(self, group): + ##print self, 'addtag' ##~ assert isinstance(group._item, CanvasGroup) self._item.reparent(group._item) + def dtag(self, group): + pass + ##print self, 'dtag' + ##~ assert isinstance(group._item, CanvasGroup) + ##self._item.reparent(self.canvas.root()) + def bind(self, sequence, func, add=None): bind(self._item, sequence, func, add) def bbox(self): ## FIXME return (0, 0, 0, 0) - def dtag(self, group): - ##~ assert isinstance(group._item, CanvasGroup) - self._item.reparent(self.canvas.root()) def delete(self): if self._item is not None: self._item.destroy() self._item = None - def hide(self): - self._item.hide() + def lower(self, positions=None): ##print "lower", self._item, positions if positions is None: @@ -97,19 +103,26 @@ class _CanvasItem: ##~ assert type(positions) is types.IntType and positions > 0 ##~ self._item.lower(positions) pass - def move(self, x, y): - self._item.move(x, y) - def show(self): - self._item.show() def tkraise(self, positions=None): ##print "tkraise", self._item, positions if positions is None: self._item.raise_to_top() else: + print 'tkraise', positions ##~ assert type(positions) is types.IntType and positions > 0 ##~ self._item.raise_(positions) + self._item.raise_to_top() pass + def move(self, x, y): + self._item.move(x, y) + moveTo = move + + def show(self): + self._item.show() + def hide(self): + self._item.hide() + class MfxCanvasGroup(_CanvasItem): def __init__(self, canvas): @@ -121,7 +134,8 @@ class MfxCanvasGroup(_CanvasItem): class MfxCanvasImage(_CanvasItem): def __init__(self, canvas, x, y, image, anchor=gtk.ANCHOR_NW): _CanvasItem.__init__(self, canvas) - anchor = anchor_tk2gtk(anchor) + if type(anchor) is str: + anchor = anchor_tk2gtk(anchor) self._item = canvas.root().add(gnome.canvas.CanvasPixbuf, x=x, y=y, pixbuf=image.pixbuf, @@ -151,6 +165,7 @@ class MfxCanvasRectangle(_CanvasItem): class MfxCanvasText(_CanvasItem): def __init__(self, canvas, x, y, anchor=gtk.ANCHOR_NW, preview=-1, **kw): + _CanvasItem.__init__(self, canvas) if preview < 0: preview = canvas.preview if preview > 1: @@ -197,21 +212,27 @@ class MfxCanvas(gnome.canvas.Canvas): self.preview = 0 # Tkinter compat self.items = {} + self._all_items = [] + self._text_items = [] # private self.__tileimage = None self.__tiles = [] # friend MfxCanvasText self._text_color = '#000000' - self._text_items = [] # gnome.canvas.Canvas.__init__(self) - self.style = self.get_style().copy() + style = self.get_style().copy() if bg is not None: c = self.get_colormap().alloc(bg) - self.style.bg[gtk.STATE_NORMAL] = c - self.set_style(self.style) - self.set_scroll_region(0, 0, gdk.screen_width(), gdk.screen_height()) - top.vbox.pack_start(self) + style.bg[gtk.STATE_NORMAL] = c + self.set_style(style) + ##self.set_scroll_region(0, 0, gdk.screen_width(), gdk.screen_height()) + top.table.attach(self, + 0, 1, 2, 3, + gtk.EXPAND | gtk.FILL, gtk.EXPAND | gtk.FILL, + 0, 0) + + ## self.top = top self.xmargin, self.ymargin = 0, 0 @@ -237,7 +258,7 @@ class MfxCanvas(gnome.canvas.Canvas): height, width = -1, -1 for k, v in kw.items(): if k == "background" or k == "bg": - print 'configure: bg:', v + ##print 'configure: bg:', v c = self.get_colormap().alloc_color(v) self.style.bg[gtk.STATE_NORMAL] = c ##~ self.set_style(self.style) @@ -266,8 +287,11 @@ class MfxCanvas(gnome.canvas.Canvas): # PySol extension # delete all CanvasItems, but keep the background and top tiles def deleteAllItems(self): - ## FIXME - pass + for i in self._all_items: + if i._item: + i._item.destroy() + ##i._item = None + self._all_items = [] # PySol extension def findCard(self, stack, event): @@ -326,6 +350,11 @@ class MfxCanvas(gnome.canvas.Canvas): ### FIXME: should use style.bg_pixmap ???? def _setTile(self, image, stretch=False): + self.realize() + self.show_now() + sw, sh = self.get_size() + print self.get_size() + return try: if image and type(image) is types.StringType: image = loadImage(image) @@ -356,15 +385,31 @@ class MfxCanvas(gnome.canvas.Canvas): pass def update_idletasks(self): + ##print 'MfxCanvas.update_idletasks' self.update_now() + ##gdk.window_process_all_updates() + self.show_now() def grid(self, *args, **kw): - pass + #print '1 >->', self.window + if self.window: + #print '2 >->', self.window + self.window.resize(self._width, self._height) def setInitialSize(self, width, height): + print 'setInitialSize:', width, height + self._width, self._height = width, height self.set_size_request(width, height) - if self.window: - self.window.resize(width, height) + #self.set_size(width, height) + #self.queue_resize() + self.set_scroll_region(0,0,width,height) + #if self.window: + # self.window.resize(width, height) +class MfxScrolledCanvas(MfxCanvas): + def __init__(self, parent, hbar=2, vbar=2, **kw): + MfxCanvas.__init__(self, parent) + self.canvas = self + diff --git a/pysollib/pysolgtk/tkutil.py b/pysollib/pysolgtk/tkutil.py index cc2325ee..8d15f50f 100644 --- a/pysollib/pysolgtk/tkutil.py +++ b/pysollib/pysolgtk/tkutil.py @@ -60,10 +60,10 @@ def makeToplevel(parent, title=None, class_=None, gtkclass=gtk.Window): window = gtkclass() ##~ window.style = window.get_style().copy() ##~ window.set_style(window.style) - if not hasattr(window, 'vbox'): - window.vbox = gtk.VBox() - window.vbox.show() - window.add(window.vbox) + if not hasattr(window, 'table'): + window.table = gtk.Table(1, 4, False) + window.table.show() + window.add(window.table) window.realize() # needed for set_icon_name() if title: window.set_title(title) diff --git a/pysollib/pysolgtk/tkwidget.py b/pysollib/pysolgtk/tkwidget.py index 8abaaf83..67b72101 100644 --- a/pysollib/pysolgtk/tkwidget.py +++ b/pysollib/pysolgtk/tkwidget.py @@ -40,7 +40,6 @@ TRUE, FALSE = True, False # Toolkit imports from tkutil import makeToplevel, setTransient, wm_withdraw -from tkcanvas import MfxCanvas # /*********************************************************************** @@ -61,7 +60,7 @@ class _MyDialog(gtk.Dialog): def quit(self, *args): self.hide() self.destroy() - gtk.mainquit() + gtk.main_quit() class MfxDialog(_MyDialog): @@ -74,20 +73,22 @@ class MfxDialog(_MyDialog): font=None, buttonfont=None, padx='20', pady='20', - bitmap=None, bitmap_side='left', bitmap_padx=20, bitmap_pady=20, - image=None, image_side='left', image_padx=10, image_pady=20): + bitmap=None, bitmap_side='left', + bitmap_padx=20, bitmap_pady=20, + image=None, image_side='left', + image_padx=10, image_pady=20): _MyDialog.__init__(self) self.status = 1 self.button = -1 bitmap = None self.init(parent, text, strings, default, bitmap, TRUE) #font = "Times-14" - if font: - self.style.font = load_font(font) - self.set_style(self.style) +## if font: +## self.style.font = load_font(font) +## self.set_style(self.style) self.set_title(title) self.show() - gtk.mainloop() + gtk.main() def init(self, parent, message="", buttons=(), default=-1, pixmap=None, modal=TRUE): @@ -173,7 +174,7 @@ class MfxSimpleEntry(_MyDialog): self.entry.set_text(str(value)) self.set_title(title) self.show() - gtk.mainloop() + gtk.main() def init(self, parent, message="", modal=TRUE): if modal: @@ -208,11 +209,6 @@ class MfxSimpleEntry(_MyDialog): self.quit() -class MfxScrolledCanvas(MfxCanvas): - def __init__(self, parent, hbar=2, vbar=2, **kw): - MfxCanvas.__init__(self, parent) - self.canvas = self - diff --git a/pysollib/pysolgtk/tkwrap.py b/pysollib/pysolgtk/tkwrap.py index e25d2f7a..92a0d66d 100644 --- a/pysollib/pysolgtk/tkwrap.py +++ b/pysollib/pysolgtk/tkwrap.py @@ -35,7 +35,6 @@ import os, sys, time, types import gtk from gtk import gdk -TRUE, FALSE = True, False # PySol imports ## from pysollib.images import Images @@ -61,12 +60,12 @@ class MfxCheckMenuItem: self.path = path self.value = None def get(self): - print 'MfxCheckMenuItem.get:', self.path + ##print 'MfxCheckMenuItem.get:', self.path if self.path is None: return 0 w = self.menubar.menus.get_widget(self.path) return w.active def set(self, value): - print 'MfxCheckMenuItem.set:', value, self.path + ##print 'MfxCheckMenuItem.set:', value, self.path if self.path is None: return if not value or value == 'false': value = 0 assert type(value) is types.IntType and 0 <= value <= 1 @@ -78,7 +77,7 @@ class MfxCheckMenuItem: class MfxRadioMenuItem(MfxCheckMenuItem): def get(self): - print 'MfxRadioMenuItem.get:', self.path, self.value + ##print 'MfxRadioMenuItem.get:', self.path, self.value if self.path is None: return 0 w = self.menubar.menus.get_widget(self.path) #from pprint import pprint @@ -88,7 +87,7 @@ class MfxRadioMenuItem(MfxCheckMenuItem): #print w.__dict__ return self.value def set(self, value): - print 'MfxRadioMenuItem.set:', value, self.path + ##print 'MfxRadioMenuItem.set:', value, self.path if self.path is None: return if not value or value == 'false': value = 0 assert type(value) is types.IntType and 0 <= value @@ -112,9 +111,12 @@ class _MfxToplevel(gtk.Window): gtk.Window.__init__(self, type=gtk.WINDOW_TOPLEVEL) ##~ self.style = self.get_style().copy() self.set_style(self.style) - self.vbox = gtk.VBox() - self.vbox.show() - self.add(self.vbox) + #self.vbox = gtk.VBox() + #self.vbox.show() + #self.add(self.vbox) + self.table = gtk.Table(3, 5, False) + self.add(self.table) + self.table.show() self.realize() def cget(self, attr): @@ -143,18 +145,21 @@ class _MfxToplevel(gtk.Window): print "Toplevel configure:", k, v raise AttributeError, k if height > 0 and width > 0: + print 'configure: size:', width, height ## FIXME #self.set_default_size(width, height) - self.set_size_request(width, height) + #self.set_size_request(width, height) #self.set_geometry_hints(base_width=width, base_height=height) + pass + config = configure def mainloop(self): - gtk.mainloop() # the global function + gtk.main() # the global function def mainquit(self): - gtk.mainquit() # the global function + gtk.main_quit() # the global function def screenshot(self, filename): pass @@ -170,8 +175,9 @@ class _MfxToplevel(gtk.Window): self.update_idletasks() def update_idletasks(self): + ##print '_MfxToplevel.update_idletasks' while gtk.events_pending(): - gtk.mainiteration(TRUE) + gtk.main_iteration(True) def winfo_ismapped(self): # FIXME @@ -197,7 +203,8 @@ class _MfxToplevel(gtk.Window): def wm_geometry(self, newGeometry=None): ##print 'wm_geometry', newGeometry if newGeometry == '': - self.resize(1, 1) + self.reshow_with_initial_size() + ##self.resize(1, 1) else: w, h = newGeometry self.resize(w, h) @@ -231,20 +238,23 @@ class _MfxToplevel(gtk.Window): def wm_title(self, title): self.set_title(title) + def tkraise(self): + self.present() + def option_add(self, *args): - print self, 'option_add' + ##print self, 'option_add' pass def option_get(self, *args): - print self, 'option_get' + ##print self, 'option_get' return None def grid_columnconfigure(self, *args, **kw): - print self, 'grid_columnconfigure' + ##print self, 'grid_columnconfigure' pass def grid_rowconfigure(self, *args, **kw): - print self, 'grid_rowconfigure' + ##print self, 'grid_rowconfigure' pass def interruptSleep(self, *args, **kw): @@ -252,7 +262,7 @@ class _MfxToplevel(gtk.Window): pass def wm_state(self): - print self, 'wm_state' + ##print self, 'wm_state' pass @@ -291,4 +301,4 @@ class MfxRoot(_MfxToplevel): else: ##self.after_idle(self.quit) pass - return TRUE + return True diff --git a/pysollib/pysolgtk/toolbar.py b/pysollib/pysolgtk/toolbar.py index 76f6c9e4..92053988 100644 --- a/pysollib/pysolgtk/toolbar.py +++ b/pysollib/pysolgtk/toolbar.py @@ -41,54 +41,80 @@ TRUE, FALSE = True, False from pysollib.actions import PysolToolbarActions + # /*********************************************************************** # // # ************************************************************************/ class PysolToolbar(PysolToolbarActions): - def __init__(self, top, dir, relief=0): + def __init__(self, top, dir, size=0, relief=0, compound=None): + PysolToolbarActions.__init__(self) self.top = top self.dir = dir self.side = -1 - self.toolbar = gtk.Toolbar(ORIENTATION_HORIZONTAL, TOOLBAR_ICONS) - self.bg = top.get_style().bg[STATE_NORMAL] + self.toolbar = gtk.Toolbar(gtk.ORIENTATION_HORIZONTAL, + gtk.TOOLBAR_ICONS) + + #self.bg = top.get_style().bg[gtk.STATE_NORMAL] + ui_info = ''' + + + + + + + + + + + + + + + + + + +''' + ui_manager = self.top.ui_manager # created in menubar.py + ui_manager_id = ui_manager.add_ui_from_string(ui_info) + + toolbar = ui_manager.get_widget("/ToolBar") + toolbar.set_tooltips(True) + toolbar.set_style(gtk.TOOLBAR_ICONS) + toolbar.show() + + top.table.attach(toolbar, + 0, 1, 1, 2, + gtk.EXPAND | gtk.FILL, 0, + 0, 0) + toolbar.show() + + - self._createButton('new', self.mNewGame, tooltip='New game') - self._createButton('open', self.mOpen , tooltip='Open a \nsaved game') - self._createSeparator() - self._createButton('restart', self.mRestart, tooltip='Restart the \ncurrent game') - self._createButton('save', self.mSave, tooltip='Save game') - self._createSeparator() - self._createButton('undo', self.mUndo, tooltip='Undo') - self._createButton('redo', self.mRedo, tooltip='Redo') - self._createButton('autodrop',self.mDrop, tooltip='Auto drop') - self._createSeparator() - self._createButton('stats', self.mStatus, tooltip='Statistics') - self._createButton('rules', self.mHelpRules, tooltip='Rules') - self._createSeparator() - self._createButton('quit', self.mQuit, tooltip='Quit PySol') - self._createSeparator() # no longer needed self.bg = None # - top.vbox.pack_start(self.toolbar, FALSE, FALSE) + # util - def _createButton(self, name, command, padx=0, tooltip=None): -## file = os.path.join(self.dir, name+".gif") -## im = GdkImlib.Image(file) -## im.render() -## pixmap = im.make_pixmap() -## if tooltip: tooltip = re.sub(r'\n', '', tooltip) + def _createButton(self, name, command, padx=0, stock=None, tooltip=None): + ##button = self.toolbar.append_item(name, tooltip, "", stock, command) + ##button = self.toolbar.insert_stock(stock, tooltip, '', command, None, -1) + image = gtk.Image() + image.set_from_stock(stock, gtk.ICON_SIZE_SMALL_TOOLBAR) -##append_item(text, tooltip_text, tooltip_private_text, icon, callback, user_data=None) - - button = self.toolbar.append_item(name, tooltip, "", None, command) + button = gtk.ToolButton(None, name) + button.set_tooltip(tooltip) + #button.set_relief(gtk.RELIEF_NONE) + #button.connect('activate', command) + self.toolbar.insert(button, -1) setattr(self, name + "_button", button) + def _createLabel(self, name, padx=0, side='IGNORE', tooltip=None): ## FIXME: append_widget pass @@ -110,6 +136,9 @@ class PysolToolbar(PysolToolbarActions): def getSide(self): return self.side + def getSize(self): + return 0 + def hide(self, resize=1): self.show(None, resize) @@ -158,7 +187,7 @@ class TestToolbar(PysolToolbar): self.updateText(player="Player\nPySol") self.undo_button.set_state(STATE_INSENSITIVE) def mQuit(self, *args): - mainquit() + gtk.main_quit() def toolbar_main(args): from tkwrap import MfxRoot diff --git a/pysollib/stack.py b/pysollib/stack.py index 389e92d4..e33e9a23 100644 --- a/pysollib/stack.py +++ b/pysollib/stack.py @@ -485,6 +485,7 @@ class Stack: if update_positions: for c in model.cards[card_index:]: view._position(c) + if update: view.updateText() if self.is_filled: @@ -1044,8 +1045,8 @@ class Stack: i = self._findCard(event) if i < 0 or not self.canMoveCards(self.cards[i:]): return - if self.is_filled: - self.items.shade_item.config(state='hidden') + if self.is_filled and self.items.shade_item: + self.items.shade_item.hide() x_offset, y_offset = self.cards[i].x, self.cards[i].y if sound: self.game.playSample("startdrag") @@ -1275,8 +1276,8 @@ class Stack: drag.shadows = [] drag.stack = None drag.cards = [] - if self.is_filled: - self.items.shade_item.config(state='normal') + if self.is_filled and self.items.shade_item: + self.items.shade_item.show() self.items.shade_item.tkraise() # finish a drag operation diff --git a/pysollib/tk/tkcanvas.py b/pysollib/tk/tkcanvas.py index 6a9b3d3d..c97a73c7 100644 --- a/pysollib/tk/tkcanvas.py +++ b/pysollib/tk/tkcanvas.py @@ -80,6 +80,10 @@ class MfxCanvasImage(Canvas.ImageItem): def moveTo(self, x, y): c = self.coords() self.move(x - int(c[0]), y - int(c[1])) + def show(self): + self.config(state='normal') + def hide(self): + self.config(state='hidden') MfxCanvasLine = Canvas.Line