diff --git a/pysollib/app.py b/pysollib/app.py index b3fb4f7e..8032d75e 100644 --- a/pysollib/app.py +++ b/pysollib/app.py @@ -65,7 +65,7 @@ from pysoltk import PysolMenubar from pysoltk import PysolProgressBar from pysoltk import PysolToolbar from pysoltk import PysolStatusbar, HelpStatusbar -from pysoltk import SelectCardsetByTypeDialogWithPreview +from pysoltk import SelectCardsetDialogWithPreview from pysoltk import SelectDialogTreeData from pysoltk import tkHTMLViewer from pysoltk import TOOLBAR_BUTTONS @@ -770,10 +770,6 @@ class Application: self.intro.progress.destroy() destruct(self.intro.progress) self.intro.progress = None - if TOOLKIT == 'gtk': - ## FIXME - self.top.update_idletasks() - self.top.show_now() # prepare game autoplay = 0 if self.nextgame.loadedgame is not None: @@ -1155,7 +1151,7 @@ Please select a %s type %s. def __selectCardsetDialog(self, t): key = self.cardset.index - d = SelectCardsetByTypeDialogWithPreview( + d = SelectCardsetDialogWithPreview( self.top, title=_("Please select a %s type %s") % (t[0], CARDSET), app=self, manager=self.cardset_manager, key=key, strings=(None, _("&OK"), _("&Cancel")), default=1) diff --git a/pysollib/game.py b/pysollib/game.py index e35e8839..85a2ef2a 100644 --- a/pysollib/game.py +++ b/pysollib/game.py @@ -426,6 +426,12 @@ class Game: wm_map(self.top, maximized=self.app.opt.wm_maximized) self.top.busyUpdate() self.stopSamples() + # + if TOOLKIT == 'gtk': + ## FIXME + if self.top: + self.top.update_idletasks() + self.top.show_now() # let's go self.moves.state = self.S_INIT self.startGame() @@ -503,6 +509,12 @@ class Game: self.stats.update_time = time.time() self.busy = old_busy # + if TOOLKIT == 'gtk': + ## FIXME + if self.top: + self.top.update_idletasks() + self.top.show_now() + # self.startPlayTimer() # restore a bookmarked game (e.g. after changing the cardset) @@ -548,6 +560,7 @@ class Game: # with another game from there def quitGame(self, id=0, random=None, loadedgame=None, startdemo=0, bookmark=0, holdgame=0): + print 'quitGame' self.updateTime() if bookmark: id, random = self.id, self.random diff --git a/pysollib/pysolgtk/card.py b/pysollib/pysolgtk/card.py index d89fca57..7d9f5e10 100644 --- a/pysollib/pysolgtk/card.py +++ b/pysollib/pysolgtk/card.py @@ -116,14 +116,14 @@ class _TwoImageCard(_HideableCard): if not self.face_up: self.__back.hide() self.__face.show() - self.tkraise(unhide) + ##self.tkraise(unhide) self.face_up = 1 def showBack(self, unhide=1): if self.face_up: self.__face.hide() self.__back.show() - self.tkraise(unhide) + ##self.tkraise(unhide) self.face_up = 0 def updateCardBackground(self, image): @@ -133,5 +133,5 @@ class _TwoImageCard(_HideableCard): # choose the implementation Card = _TwoImageCard -Card = _OneImageCard +#Card = _OneImageCard # FIXME: this implementation lost any cards (bug?) diff --git a/pysollib/pysolgtk/menubar.py b/pysollib/pysolgtk/menubar.py index 9a048d35..0223101b 100644 --- a/pysollib/pysolgtk/menubar.py +++ b/pysollib/pysolgtk/menubar.py @@ -45,7 +45,6 @@ from pysollib.settings import PACKAGE from tkutil import setTransient from tkutil import color_tk2gtk, color_gtk2tk from selectcardset import SelectCardsetDialogWithPreview -from selectcardset import SelectCardsetByTypeDialogWithPreview from selecttile import SelectTileDialogWithPreview from selectgame import SelectGameDialogWithPreview @@ -87,66 +86,153 @@ class PysolMenubar(PysolMenubarActions): def createMenubar(self): entries = ( - ('newgame', gtk.STOCK_NEW, ltk2gtk('&New game'), 'N', ltk2gtk('New game'), self.mNewGame), - ('open', gtk.STOCK_OPEN, ltk2gtk('&Open...'), 'O', ltk2gtk('Open a\nsaved game'), self.mOpen), - ('restart', gtk.STOCK_REFRESH, ltk2gtk('&Restart'), 'G', ltk2gtk('Restart the\ncurrent game'), self.mRestart), - ('save', gtk.STOCK_SAVE, ltk2gtk('&Save'), 'S', ltk2gtk('Save game'), self.mSave), - ('undo', gtk.STOCK_UNDO, ltk2gtk('&Undo'), 'Z', ltk2gtk('Undo'), self.mUndo), - ('redo', gtk.STOCK_REDO, ltk2gtk('&Redo'), 'R', ltk2gtk('Redo'), self.mRedo), - ('autodrop',gtk.STOCK_JUMP_TO, ltk2gtk('&Auto drop'), 'A', ltk2gtk('Auto drop'), self.mDrop), - ('stats', gtk.STOCK_HOME, ltk2gtk('Stats'), None, ltk2gtk('Statistics'), self.mStatus), - ('rules', gtk.STOCK_HELP, ltk2gtk('Rules'), 'F1', ltk2gtk('Rules'), self.mHelpRules), - ('quit', gtk.STOCK_QUIT, ltk2gtk('&Quit'), 'Q', ltk2gtk('Quit PySol'), self.mQuit), - ('file', None, ltk2gtk('&File')), - ('selectgame', None, ltk2gtk('Select &game')), - ('edit', None, ltk2gtk('&Edit')), - ('game', None, ltk2gtk('&Game')), - ('assist', None, ltk2gtk('&Assist')), - ('options', None, ltk2gtk('&Options')), - ("automaticplay", None, ltk2gtk("&Automatic play")), + ### toolbar + ('newgame', gtk.STOCK_NEW, + ltk2gtk('&New game'), 'N', + ltk2gtk('New game'), + self.mNewGame), + ('open', gtk.STOCK_OPEN, + ltk2gtk('&Open...'), 'O', + ltk2gtk('Open a\nsaved game'), + self.mOpen), + ('restart', gtk.STOCK_REFRESH, + ltk2gtk('&Restart'), 'G', + ltk2gtk('Restart the\ncurrent game'), + self.mRestart), + ('save', gtk.STOCK_SAVE, + ltk2gtk('&Save'), 'S', + ltk2gtk('Save game'), + self.mSave), + ('undo', gtk.STOCK_UNDO, + ltk2gtk('&Undo'), 'Z', + ltk2gtk('Undo'), + self.mUndo), + ('redo', gtk.STOCK_REDO, + ltk2gtk('&Redo'), 'R', + ltk2gtk('Redo'), + self.mRedo), + ('autodrop', gtk.STOCK_JUMP_TO, + ltk2gtk('&Auto drop'), 'A', + ltk2gtk('Auto drop'), + self.mDrop), + ('stats', gtk.STOCK_INDEX, + ltk2gtk('Stats'), None, + ltk2gtk('Statistics'), + self.mStatus), + ('rules', gtk.STOCK_HELP, + ltk2gtk('Rules'), 'F1', + ltk2gtk('Rules'), + self.mHelpRules), + ('quit', gtk.STOCK_QUIT, + ltk2gtk('&Quit'), 'Q', + ltk2gtk('Quit PySol'), + self.mQuit), - ('animations', None, ltk2gtk('A&nimations')), - ('help', None, ltk2gtk('&Help')), + ### menus + ('file', None, ltk2gtk('&File')), + ('selectgame', None, ltk2gtk('Select &game')), + ('edit', None, ltk2gtk('&Edit')), + ('game', None, ltk2gtk('&Game')), + ('assist', None, ltk2gtk('&Assist')), + ('options', None, ltk2gtk('&Options')), + ('assistlevel', None, ltk2gtk("Assist &level")), + ("automaticplay", None, ltk2gtk("&Automatic play")), + ('animations', None, ltk2gtk('A&nimations')), + ('help', None, ltk2gtk('&Help')), - ('playablepreview', None, ltk2gtk('Playable pre&view...'), 'V', None, self.mSelectGameDialogWithPreview), - ('selectgamebynumber', None, ltk2gtk('Select game by nu&mber...'), None, None, self.mSelectGameById), - ('saveas', None, ltk2gtk('Save &as...'), None, None, self.m), - ('redoall', None, ltk2gtk('Redo &all'), None, None, self.mRedoAll), - ('dealcards', None, ltk2gtk('&Deal cards'), 'D', None, self.mDeal), - ('status', None, ltk2gtk('S&tatus...'), 'T', None, self.mStatus), - ('hint', None, ltk2gtk('&Hint'), 'H', None, self.mHint), - ('highlightpiles', None, ltk2gtk('Highlight p&iles'), None, None, self.mHighlightPiles), - ('demo', None,ltk2gtk('&Demo'), 'D',None,self.mDemo), - ('demoallgames', None,ltk2gtk('Demo (&all games)'), None,None,self.mMixedDemo), - ('playeroptions',None,ltk2gtk('&Player options...'),None,None,self.mOptPlayerOptions), - ('tabletile', None,ltk2gtk('Table t&ile...'), None,None,self.mOptTableTile), - ('contents', None,ltk2gtk('&Contents'),'F1',None,self.mHelp), - ('aboutpysol', None,ltk2gtk('&About ')+PACKAGE+'...', None,None,self.mHelpAbout), -) + ### menuitems + ('playablepreview', None, + ltk2gtk('Playable pre&view...'), 'V', + None, self.mSelectGameDialogWithPreview), + ('selectgamebynumber', None, + ltk2gtk('Select game by nu&mber...'), None, + None, self.mSelectGameById), + ('saveas', None, + ltk2gtk('Save &as...'), None, + None, self.m), + ('redoall', None, + ltk2gtk('Redo &all'), None, + None, self.mRedoAll), + ('dealcards', None, + ltk2gtk('&Deal cards'), 'D', + None, self.mDeal), + ('status', None, + ltk2gtk('S&tatus...'), 'T', + None, self.mStatus), + ('hint', None, + ltk2gtk('&Hint'), 'H', + None, self.mHint), + ('highlightpiles', None, + ltk2gtk('Highlight p&iles'), None, + None, self.mHighlightPiles), + ('demo', None, + ltk2gtk('&Demo'), 'D', + None,self.mDemo), + ('demoallgames', None, + ltk2gtk('Demo (&all games)'), None, + None,self.mMixedDemo), + ('playeroptions', None, + ltk2gtk('&Player options...'), None, + None,self.mOptPlayerOptions), + ('tabletile', None, + ltk2gtk('Table t&ile...'), None, + None,self.mOptTableTile), + ('cardset', None, + ltk2gtk('Cards&et...'), 'E', + None, self.mSelectCardsetDialog), + ('contents', None, + ltk2gtk('&Contents'), 'F1', + None, self.mHelp), + ('aboutpysol', None, + ltk2gtk('&About ')+PACKAGE+'...', + None,None,self.mHelpAbout), + ('updateall', None, + 'Redraw Game', 'L', + None, + self.updateAll), + ) # - toggle_entries = ( - ('pause', gtk.STOCK_STOP, ltk2gtk('&Pause'), 'P', ltk2gtk('Pause game'), self.mPause), - ('optautodrop', None, ltk2gtk('A&uto drop'), None, None, self.mOptAutoDrop), - ('autofaceup', None, ltk2gtk('Auto &face up'), None, None, self.mOptAutoFaceUp), - ("autodeal", None, ltk2gtk("Auto &deal"), None, None, self.mOptAutoDeal), - ("quickplay", None, ltk2gtk('&Quick play'), None, None, self.mOptQuickPlay), - - ('highlightmatchingcards', None, ltk2gtk('Highlight &matching cards'), None, None, self.mOptEnableHighlightCards), - ('cardshadow', None, ltk2gtk('Card shado&w'), None, None, self.mOptShadow), - ('shadelegalmoves', None, ltk2gtk('Shade &legal moves'), None, None, self.mOptShade), - -) + toggle_entries = [ + ('pause', # name + gtk.STOCK_STOP, ltk2gtk('&Pause'), # stock, label + 'P', ltk2gtk('Pause game'), # accelerator, tooltip + self.mPause, # callback + False, # initial value + ), ] + for label, name, opt_name in ( + ('A&uto drop', 'optautodrop', 'autodrop'), + ('Auto &face up', '', 'autofaceup'), + ('Auto &deal', '', 'autodeal'), + ('&Quick play', '', 'quickplay'), + ('Enable &undo', '', 'undo'), + ('Enable &bookmarks' , '', 'bookmarks'), + ('Enable &hint', '', 'hint'), + ('Enable highlight p&iles', '', 'highlight_piles'), + ('Enable highlight &cards', '', 'highlight_cards'), + ('Enable highlight same &rank', '', 'highlight_samerank'), + ('Highlight &no matching', '', 'highlight_not_matching'), + ('Card shado&w', '', 'shadow'), + ('Shade &legal moves', '', 'shade'), + ): + if not name: + name = re.sub(r"[^0-9a-zA-Z]", "", label).lower() + toggle_entries.append( + (name, + None, ltk2gtk(label), + None, None, + lambda w, opt_name=opt_name: self.mOptToggle(w, opt_name), + getattr(self.app.opt, opt_name))) # animations_entries = ( - ('animationnone', None, ltk2gtk('&None'), None, None, 0), - ('animationfast', None, ltk2gtk('&Fast'), None, None, 1), - ('animationtimer', None, ltk2gtk('&Timer based'), None, None, 2), - ('animationslow', None, ltk2gtk('&Slow'), None, None, 3), - ('animationveryslow', None, ltk2gtk('&Very slow'), None, None, 4), - ) + ('animationnone', None, ltk2gtk('&None'), None, None, 0), + ('animationfast', None, ltk2gtk('&Fast'), None, None, 1), + ('animationtimer', None, ltk2gtk('&Timer based'), None, None, 2), + ('animationslow', None, ltk2gtk('&Slow'), None, None, 3), + ('animationveryslow', None, ltk2gtk('&Very slow'), None, None, 4), + ) # ui_info = ''' @@ -170,6 +256,8 @@ class PysolMenubar(PysolMenubarActions): + + @@ -196,9 +284,18 @@ class PysolMenubar(PysolMenubarActions): - + + + + + + + + + + @@ -395,8 +492,6 @@ class PysolMenubar(PysolMenubarActions): self.updateMenus() - def mOptCardset(self, *args): - pass def mOptTableTile(self, *args): if self._cancelDrag(break_pause=False): return @@ -469,3 +564,29 @@ class PysolMenubar(PysolMenubarActions): self.game.quitGame(d.gameid, random=d.random) + def mSelectCardsetDialog(self, *event): + if self._cancelDrag(break_pause=False): return + key = self.app.nextgame.cardset.index + d = SelectCardsetDialogWithPreview(self.top, title=_("Select cardset"), + app=self.app, manager=self.app.cardset_manager, key=key) + cs = self.app.cardset_manager.get(d.key) + if cs is None or d.key == self.app.cardset.index: + return + if d.status == 0 and d.button in (0, 1) and d.key >= 0: + self.app.nextgame.cardset = cs + if d.button == 0: + self._cancelDrag() + self.game.endGame(bookmark=1) + self.game.quitGame(bookmark=1) + self.app.opt.games_geometry = {} # clear saved games geometry + + + def mOptToggle(self, w, opt): + ##print 'mOptToggle:', opt, w.get_active() + if self._cancelDrag(break_pause=False): return + self.app.opt.__dict__[opt] = w.get_active() + + + def updateAll(self, *event): + self.app.canvas.updateAll() + diff --git a/pysollib/pysolgtk/playeroptionsdialog.py b/pysollib/pysolgtk/playeroptionsdialog.py index 7f556c9e..3b14fee0 100644 --- a/pysollib/pysolgtk/playeroptionsdialog.py +++ b/pysollib/pysolgtk/playeroptionsdialog.py @@ -65,7 +65,6 @@ class PlayerOptionsDialog(MfxDialog): completion = gtk.EntryCompletion() self.player_entry.set_completion(completion) model = gtk.ListStore(gobject.TYPE_STRING) - print '>>', app.getAllUserNames() for name in app.getAllUserNames(): iter = model.append() model.set(iter, 0, name) diff --git a/pysollib/pysolgtk/pysoltree.py b/pysollib/pysolgtk/pysoltree.py new file mode 100644 index 00000000..eea69282 --- /dev/null +++ b/pysollib/pysolgtk/pysoltree.py @@ -0,0 +1,125 @@ +##---------------------------------------------------------------------------## +## +## PySol -- a Python Solitaire game +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; see the file COPYING. +## If not, write to the Free Software Foundation, Inc., +## 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +## +##---------------------------------------------------------------------------## + + +# imports +import os, re, sys, types +import gtk, gobject + +# PySol imports + +# Toolkit imports + + +# /*********************************************************************** +# // +# ************************************************************************/ + +class PysolTreeView: + + _expanded_rows = [] + _selected_row = None + _vadjustment_position = None + + def __init__(self, parent, store, **kw): + # + sw = gtk.ScrolledWindow() + self.scrolledwindow = sw + sw.show() + self.sw_vadjustment = sw.get_vadjustment() + sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + # + treeview = gtk.TreeView(store) + self.treeview = treeview + treeview.show() + sw.add(treeview) + treeview.set_rules_hint(True) + treeview.set_headers_visible(False) + renderer = gtk.CellRendererText() + renderer.set_property('xalign', 0.0) + column = gtk.TreeViewColumn('Column Name', renderer, text=0) + column.set_clickable(True) + treeview.append_column(column) + selection = treeview.get_selection() + selection.connect('changed', parent.showSelected) + treeview.connect('unrealize', self._unrealizeEvent) + + self._restoreSettings() + + + def _unrealizeEvent(self, w): + self._saveSettings() + + + def _saveSettings(self): + self._saveExpandedRows() + selection = self.treeview.get_selection() + model, path = selection.get_selected_rows() + if path: + PysolTreeView._selected_row = path[0] + PysolTreeView._vadjustment_position = self.sw_vadjustment.get_value() + + def _restoreSettings(self): + self._loadExpandedRows() + if self._selected_row: + selection = self.treeview.get_selection() + ##selection.select_path(self._selected_row) + ##selection.unselect_all() + gtk.idle_add(selection.select_path, self._selected_row) + if self._vadjustment_position is not None: + ##self.sw_vadjustment.set_value(self._vadjustment_position) + gtk.idle_add(self.sw_vadjustment.set_value, + self._vadjustment_position) + + + def _saveExpandedRows(self): + treeview = self.treeview + PysolTreeView._expanded_rows = [] + treeview.map_expanded_rows( + lambda tv, path, self=self: + PysolTreeView._expanded_rows.append(path)) + + def _loadExpandedRows(self): + for path in self._expanded_rows: + self.treeview.expand_to_path(path) + + + def getSelected(self): + selection = self.treeview.get_selection() + model, path = selection.get_selected_rows() + if not path: + return None + iter = model.get_iter(path[0]) + index = model.get_value(iter, 1) + return index + + + def unselectAll(self): + selection = self.treeview.get_selection() + selection.unselect_all() + + + + + + + + diff --git a/pysollib/pysolgtk/selectcardset.py b/pysollib/pysolgtk/selectcardset.py index 6464647d..75776ee7 100644 --- a/pysollib/pysolgtk/selectcardset.py +++ b/pysollib/pysolgtk/selectcardset.py @@ -32,10 +32,17 @@ # imports import os, re, sys, types -from gtk import * +import gtk, gobject + +# PySol imports +from pysollib.resource import CSI +from pysollib.mfxutil import kwdefault # Toolkit imports from tkwidget import MfxDialog +from pysoltree import PysolTreeView +from tkcanvas import MfxCanvas, MfxCanvasImage +from tkutil import loadImage # /*********************************************************************** @@ -43,8 +50,221 @@ from tkwidget import MfxDialog # ************************************************************************/ class SelectCardsetDialogWithPreview(MfxDialog): - pass + _cardset_store = None + + def __init__(self, parent, title, app, manager, key=None, **kw): + kw = self.initKw(kw) + MfxDialog.__init__(self, parent, title, **kw) + # + top_box, bottom_box = self.createHBox() + # + if key is None: + key = manager.getSelected() + self.app = app + self.manager = manager + self.key = key + self.preview_key = -1 + self.all_keys = [] + + if self._cardset_store is None: + self._createStore() + + #padx, pady = kw.padx, kw.pady + padx, pady = 5, 5 + # left + # paned + hpaned = gtk.HPaned() + self.hpaned = hpaned + hpaned.show() + top_box.pack_start(hpaned, expand=True, fill=True) + # tree + treeview = PysolTreeView(self, self._cardset_store) + self.treeview = treeview + hpaned.pack1(treeview.scrolledwindow, True, True) + ##treeview.treeview.expand_all() + # right + sw = gtk.ScrolledWindow() + sw.show() + sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + hpaned.pack2(sw, True, True) + ##self.scrolledwindow = sw + # + self.preview = MfxCanvas(self) + self.preview.show() + sw.add(self.preview) + #hpaned.pack2(self.preview, True, True) + self.preview.setTile(app, app.tabletile_index, force=True) + # + hpaned.set_position(240) + + self.createButtons(bottom_box, kw) + + ##~self.updatePreview(key) + + self.show_all() + gtk.main() + + + def _selectCardset(self, all_cardsets, selecter): + if selecter is None: + return [(cs.index, cs.name) for cs in all_cardsets] + return [(cs.index, cs.name) for cs in all_cardsets if selecter(cs)] + + + def _addCardsets(self, store, root_iter, root_label, cardsets): + iter = store.append(root_iter) + store.set(iter, 0, root_label, 1, -1) + for index, name in cardsets: + child_iter = store.append(iter) + ##~ name = gettext(name) + store.set(child_iter, 0, name, 1, index) + + + def _addCardsetsByType(self, store, root_label, all_cardsets, + cardset_types, selecter_type, registered): + manager = self.manager + root_iter = store.append(None) + store.set(root_iter, 0, root_label, 1, -1) + items = cardset_types.items() + items.sort(lambda a, b: cmp(a[1], b[1])) + added = False + for key, label in items: + if not getattr(manager, registered).has_key(key): + continue + cardsets = [] + for cs in all_cardsets: + si = getattr(cs.si, selecter_type) + if type(si) is int: # type + if key == si: + cardsets.append((cs.index, cs.name)) + else: # style, nationality, date + if key in si: + cardsets.append((cs.index, cs.name)) + if cardsets: + added = True + self._addCardsets(store, root_iter, label, cardsets) + if added: + selecter = lambda cs, selecter_type=selecter_type: \ + not getattr(cs.si, selecter_type) + cs = self._selectCardset(all_cardsets, selecter) + if cs: + self._addCardsets(store, root_iter, _('Uncategorized'), cs) + else: + iter = store.append(root_iter) + store.set(iter, 0, _('(no cardsets)'), 1, -1) + + def _createStore(self): + store = gtk.TreeStore(gobject.TYPE_STRING, + gobject.TYPE_INT) + manager = self.manager + all_cardsets = manager.getAllSortedByName() + all_cardsets = filter(lambda obj: not obj.error, all_cardsets) + + cs = self._selectCardset(all_cardsets, None) + self._addCardsets(store, None, 'All cadsets', cs) + + root_iter = store.append(None) + store.set(root_iter, 0, _('by Size'), 1, -1) + for label, selecter in ( + (_("Tiny cardsets"), lambda cs: cs.si.size == CSI.SIZE_TINY), + (_("Small cardsets"), lambda cs: cs.si.size == CSI.SIZE_SMALL), + (_("Medium cardsets"), lambda cs: cs.si.size == CSI.SIZE_MEDIUM), + (_("Large cardsets"), lambda cs: cs.si.size == CSI.SIZE_LARGE), + (_("XLarge cardsets"), lambda cs: cs.si.size == CSI.SIZE_XLARGE),): + cs = self._selectCardset(all_cardsets, selecter) + if cs: + self._addCardsets(store, root_iter, label, cs) + + self._addCardsetsByType(store, _('by Type'), all_cardsets, + CSI.TYPE, 'type', 'registered_types') + self._addCardsetsByType(store, _('by Style'), all_cardsets, + CSI.STYLE, 'styles', 'registered_styles') + self._addCardsetsByType(store, _('by Nationality'), all_cardsets, + CSI.NATIONALITY, 'nationalities', + 'registered_nationalities') + self._addCardsetsByType(store, _('by Date'), all_cardsets, + CSI.DATE, 'dates', 'registered_dates') + + self._cardset_store = store + + + def getSelected(self): + index = self.treeview.getSelected() + if index < 0: + return None + return index + + + def showSelected(self, w): + key = self.getSelected() + if not key is None: + self.updatePreview(key) + pass + + + def updatePreview(self, key): + if key == self.preview_key: + return + canvas = self.preview + canvas.deleteAllItems() + self.preview_images = [] + cs = self.manager.get(key) + if not cs: + self.preview_key = -1 + return + names, columns = cs.getPreviewCardNames() + try: + #???names, columns = cs.getPreviewCardNames() + for n in names: + f = os.path.join(cs.dir, n + cs.ext) + self.preview_images.append(loadImage(file=f)) + except: + self.preview_key = -1 + self.preview_images = [] + return + i, x, y, sx, sy, dx, dy = 0, 10, 10, 0, 0, cs.CARDW + 10, cs.CARDH + 10 + for image in self.preview_images: + MfxCanvasImage(canvas, x, y, anchor="nw", image=image) + sx, sy = max(x, sx), max(y, sy) + i = i + 1 + if i % columns == 0: + x, y = 10, y + dy + else: + x = x + dx + canvas.config(width=sx+dx, height=sy+dy) + canvas.set_scroll_region(0, 0, sx+dx, sy+dy) + self.preview_key = key + + + def initKw(self, kw): + kwdefault(kw, + strings=(_("&Load"), _("&Cancel"), _("&Info..."),), + default=1, + resizable=1, + padx=10, pady=10, + width=600, height=400, + ) + return MfxDialog.initKw(self, kw) + + + def createInfo(self): + pass + + + def done(self, button): + b = button.get_data('user_data') + if b == 2: + self.createInfo() + return + if b == 0: + self.key = self.getSelected() + if not self.key: + self.key = self.preview_key + self.status = 0 + self.button = b + self.hide() + self.quit() + + -class SelectCardsetByTypeDialogWithPreview(SelectCardsetDialogWithPreview): - pass diff --git a/pysollib/pysolgtk/selectgame.py b/pysollib/pysolgtk/selectgame.py index 0c54618f..f297d209 100644 --- a/pysollib/pysolgtk/selectgame.py +++ b/pysollib/pysolgtk/selectgame.py @@ -52,6 +52,7 @@ from pysollib.resource import CSI from tkutil import unbind_destroy from tkwidget import MfxDialog from tkcanvas import MfxCanvas, MfxCanvasText +from pysoltree import PysolTreeView gettext = _ @@ -89,25 +90,8 @@ class SelectGameDialogWithPreview(MfxDialog): hpaned.show() top_box.pack_start(hpaned, expand=True, fill=True) # left - sw = gtk.ScrolledWindow() - sw.show() - self.sw_vadjustment = sw.get_vadjustment() - hpaned.pack1(sw, True, True) - sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) - # tree - treeview = gtk.TreeView(self.game_store) - self.treeview = treeview - treeview.show() - sw.add(treeview) - treeview.set_rules_hint(True) - treeview.set_headers_visible(False) - renderer = gtk.CellRendererText() - renderer.set_property('xalign', 0.0) - column = gtk.TreeViewColumn('Games', renderer, text=0) - column.set_clickable(True) - treeview.append_column(column) - selection = treeview.get_selection() - selection.connect('changed', self.showSelected) + self.treeview = PysolTreeView(self, self.game_store) + hpaned.pack1(self.treeview.scrolledwindow, True, True) # right table = gtk.Table(2, 2, False) table.show() @@ -228,8 +212,6 @@ class SelectGameDialogWithPreview(MfxDialog): name = gettext(name) store.set(child_iter, 0, name, 1, id) - #def _addNode(self, store, root_iter, root_label, games): - def _selectGames(self, all_games, selecter): # return list of tuples (gameid, gamename) @@ -350,9 +332,7 @@ class SelectGameDialogWithPreview(MfxDialog): kwdefault(kw, strings=(_("&Select"), _("&Rules"), _("&Cancel"),), default=0, - ##padx=10, pady=10, width=600, height=400, - ##~ buttonpadx=10, buttonpady=5, ) return MfxDialog.initKw(self, kw) @@ -365,49 +345,25 @@ class SelectGameDialogWithPreview(MfxDialog): def _saveSettings(self): SelectGameDialogWithPreview._geometry = self.get_size() - self._saveExpandedRows() SelectGameDialogWithPreview._paned_position = self.hpaned.get_position() - selection = self.treeview.get_selection() - model, path = selection.get_selected_rows() - if path: - print 'save selected:', path - SelectGameDialogWithPreview._selected_row = path[0] - SelectGameDialogWithPreview._vadjustment_position = self.sw_vadjustment.get_value() def _restoreSettings(self): if self._geometry: self.resize(self._geometry[0], self._geometry[1]) - self._loadExpandedRows() self.hpaned.set_position(self._paned_position) - if self._selected_row: - selection = self.treeview.get_selection() - ##selection.select_path(self._selected_row) - ##selection.unselect_all() - gtk.idle_add(selection.select_path, self._selected_row) - if self._vadjustment_position is not None: - ##self.sw_vadjustment.set_value(self._vadjustment_position) - gtk.idle_add(self.sw_vadjustment.set_value, - self._vadjustment_position) - def _getSelected(self): - selection = self.treeview.get_selection() - model, path = selection.get_selected_rows() - if not path: - return None - iter = model.get_iter(path[0]) - index = model.get_value(iter, 1) + def getSelected(self): + index = self.treeview.getSelected() if index < 0: return None return index - def showSelected(self, w): - id = self._getSelected() + id = self.getSelected() if id: self.updatePreview(id) - ##self.updateInfo(id) def deletePreview(self, destroy=0): @@ -568,28 +524,16 @@ class SelectGameDialogWithPreview(MfxDialog): text_label.set_text(str(t)) #self.info_labels[n].config(text=t) - def _saveExpandedRows(self): - treeview = self.treeview - SelectGameDialogWithPreview._expanded_rows = [] - treeview.map_expanded_rows( - lambda tv, path, self=self: - SelectGameDialogWithPreview._expanded_rows.append(path)) - print self._expanded_rows - - def _loadExpandedRows(self): - for path in self._expanded_rows: - self.treeview.expand_to_path(path) - def done(self, button): button = button.get_data("user_data") print 'done', button if button == 0: # Ok or double click - id = self._getSelected() + id = self.getSelected() if id: self.gameid = id ##~ self.tree.n_expansions = 1 # save xyview in any case if button == 1: # Rules - id = self._getSelected() + id = self.getSelected() if id: doc = self.app.getGameRulesFilename(id) if not doc: diff --git a/pysollib/pysolgtk/selecttile.py b/pysollib/pysolgtk/selecttile.py index 4cb3b9bd..91fd3e8b 100644 --- a/pysollib/pysolgtk/selecttile.py +++ b/pysollib/pysolgtk/selecttile.py @@ -26,16 +26,17 @@ import gobject, gtk from gtk import gdk -## # PySol imports +# PySol imports ## from pysollib.mfxutil import destruct, Struct, KwStruct from pysollib.resource import CSI -from pysollib.mfxutil import kwdefault, KwStruct +from pysollib.mfxutil import kwdefault # Toolkit imports ## from tkutil import loadImage from tkwidget import MfxDialog from tkcanvas import MfxCanvas from tkutil import setTransient +from pysoltree import PysolTreeView class SelectTileDialogWithPreview(MfxDialog): @@ -54,38 +55,22 @@ class SelectTileDialogWithPreview(MfxDialog): self.preview_key = -1 self.all_keys = [] self.table_color = app.opt.table_color - - sw = gtk.ScrolledWindow() - sw.set_shadow_type(gtk.SHADOW_ETCHED_IN) - sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) - top_box.pack_start(sw) - + # paned + hpaned = gtk.HPaned() + self.hpaned = hpaned + hpaned.show() + top_box.pack_start(hpaned, expand=True, fill=True) # - model = self._create_tree_model(manager, key) - treeview = gtk.TreeView(model) - treeview.set_rules_hint(True) - treeview.set_headers_visible(False) - - renderer = gtk.CellRendererText() - renderer.set_property('xalign', 0.0) - - column = gtk.TreeViewColumn('Tiles', renderer, text=0) - column.set_clickable(True) - treeview.append_column(column) - - sw.add(treeview) - treeview.expand_all() - - selection = treeview.get_selection() - selection.connect('changed', self.treeview_show_selected) - - treeview.connect('row-activated', self.row_activated) + model = self._createStore(manager, key) + treeview = PysolTreeView(self, model) self.treeview = treeview - + hpaned.pack1(treeview.scrolledwindow, True, True) + treeview.treeview.expand_all() # self.preview = MfxCanvas(top_box) # width=w2 - top_box.pack_end(self.preview) + hpaned.pack2(self.preview, True, True) self.preview.show() + hpaned.set_position(240) self.createButtons(bottom_box, kw) @@ -95,28 +80,24 @@ class SelectTileDialogWithPreview(MfxDialog): gtk.main() - def _getSelected(self): - selection = self.treeview.get_selection() - model, path = selection.get_selected_rows() - if not path: - return None - iter = model.get_iter(path[0]) - index = model.get_value(iter, 1) + def rowActivated(self, w, row, col): + # FIXME + print 'row-activated-event', row, col + + + def getSelected(self): + index = self.treeview.getSelected() if index < 0: return None return self.all_keys[index] - def row_activated(self, w, row, col): - print 'row_activated_event', row, col - - - def treeview_show_selected(self, w): - key = self._getSelected() + def showSelected(self, w): + key = self.getSelected() self.updatePreview(key) - def _create_tree_model(self, manager, key): + def _createStore(self, manager, key): self.all_keys = [] index = 0 # @@ -156,18 +137,18 @@ class SelectTileDialogWithPreview(MfxDialog): def updatePreview(self, key): - ##print 'updatePreview:', key + ##print 'updatePreview:', key, type(key) if key is None: return if key == self.preview_key: return canvas = self.preview - canvas.deleteAllItems() + ##canvas.deleteAllItems() if type(key) is str: # solid color canvas.config(bg=key) - ##canvas.setTile(None) - ##canvas.setTextColor(None) + canvas.setBackgroundImage(None) + canvas.setTextColor(None) self.preview_key = key self.table_color = key else: @@ -186,7 +167,6 @@ class SelectTileDialogWithPreview(MfxDialog): resizable=1, padx=10, pady=10, width=600, height=400, - ##~ buttonpadx=10, buttonpady=5, ) return MfxDialog.initKw(self, kw) @@ -196,12 +176,11 @@ class SelectTileDialogWithPreview(MfxDialog): c = '#%02x%02x%02x' % (c.red/256, c.green/256, c.blue/256) d.destroy() self.updatePreview(c) - selection = self.treeview.get_selection() - selection.unselect_all() + self.treeview.unselectAll() def createColorsel(self): - win = gtk.ColorSelectionDialog('Select table color') + win = gtk.ColorSelectionDialog(_('Select table color')) win.help_button.destroy() win.set_position(gtk.WIN_POS_CENTER_ON_PARENT) if type(self.preview_key) is str: @@ -222,7 +201,7 @@ class SelectTileDialogWithPreview(MfxDialog): self.createColorsel() return if b == 0: - self.key = self._getSelected() + self.key = self.getSelected() if not self.key: self.key = self.preview_key self.status = 0 diff --git a/pysollib/pysolgtk/tkcanvas.py b/pysollib/pysolgtk/tkcanvas.py index 2875d3b4..90b6572d 100644 --- a/pysollib/pysolgtk/tkcanvas.py +++ b/pysollib/pysolgtk/tkcanvas.py @@ -76,19 +76,17 @@ class _CanvasItem: def __init__(self, canvas): self.canvas = canvas canvas._all_items.append(self) - self._group = None def addtag(self, group): ##print self, 'addtag' ##~ assert isinstance(group._item, CanvasGroup) self._item.reparent(group._item) - self._group = group def dtag(self, group): ##print self, 'dtag' ##~ assert isinstance(group._item, CanvasGroup) ##self._item.reparent(self.canvas.root()) - self._group = None + pass def bind(self, sequence, func, add=None): bind(self._item, sequence, func, add) @@ -103,33 +101,23 @@ class _CanvasItem: self._item = None def lower(self, positions=None): - print "lower", self._item, positions - if positions is None: - if self._group: - self._group._item.lower_to_bottom() - ##self._item.lower_to_bottom() - else: - self._item.lower_to_bottom() - else: - print self, 'lower', positions - ##~ assert type(positions) is types.IntType and positions > 0 - self._item.lower(positions) + return # used for reordered shadow; don't need? +## if positions is None: +## self._item.lower_to_bottom() +## self._item.get_property('parent').raise_to_top() +## else: +## ##~ assert type(positions) is types.IntType and positions > 0 +## self._item.lower(positions) def tkraise(self, positions=None): - ##print "tkraise", self._group, self._item.get_property('parent') #self._item, positions + ##print 'tkraise', positions if positions is None: self._item.raise_to_top() self._item.get_property('parent').raise_to_top() -## if self._group: -## self._group._item.raise_to_top() -## ##self._item.raise_to_top() -## else: -## self._item.raise_to_top() else: - print self, 'tkraise', positions + print self, 'tkraise', positions # don't used? ##~ assert type(positions) is types.IntType and positions > 0 - ##~ self._item.raise_(positions) - self._item.raise_to_top() + self._item.raise_(positions) def move(self, x, y): self._item.move(x, y) @@ -165,6 +153,7 @@ class MfxCanvasImage(_CanvasItem): width=image.width(), height=image.height(), anchor=anchor) + self._item.show() def config(self, image): ##~ assert isinstance(image.im, GdkImlib.Image) @@ -194,16 +183,19 @@ class MfxCanvasLine(_CanvasItem): self._item = canvas.root().add(gnome.canvas.CanvasLine, points=points, **kwargs) self._item.show() - canvas.show_all() + #canvas.show_all() class MfxCanvasRectangle(_CanvasItem): - def __init__(self, canvas, x1, y1, x2, y2, width, fill, outline): + def __init__(self, canvas, x1, y1, x2, y2, + width=0, fill=None, outline=None): _CanvasItem.__init__(self, canvas) - kw = {'x1': x1, 'x2': x2, 'y1': y1, 'y2': y2, 'width_pixels': width} - if fill: kw['fill_color'] = fill + kw = {'x1': x1, 'x2': x2, 'y1': y1, 'y2': y2} + if width: kw['width_pixels'] = width + if fill: kw['fill_color'] = fill if outline: kw['outline_color'] = outline self._item = canvas.root().add(gnome.canvas.CanvasRect, **kw) + self._item.show() class MfxCanvasText(_CanvasItem): @@ -223,6 +215,7 @@ class MfxCanvasText(_CanvasItem): self[k] = v self.text_format = None canvas._text_items.append(self) + self._item.show() def __setitem__(self, key, value): if key == 'fill': @@ -241,7 +234,7 @@ class MfxCanvasText(_CanvasItem): def __getitem__(self, key): if key == 'text': # FIXME - return "" + return self._item.get_property('text') else: raise AttributeError, key cget = __getitem__ @@ -330,12 +323,12 @@ class MfxCanvas(gnome.canvas.Canvas): def configure(self, **kw): height, width = -1, -1 for k, v in kw.items(): - if k == "background" or k == "bg": + if k in ("background", "bg"): ##print 'configure: bg:', v c = self.get_colormap().alloc_color(v) self.style.bg[gtk.STATE_NORMAL] = c ##~ self.set_style(self.style) - self.queue_draw() + ##~ self.queue_draw() elif k == "cursor": ##~ w = self.window ##~ if w: @@ -445,10 +438,15 @@ class MfxCanvas(gnome.canvas.Canvas): self.realize() ##return False - self.setBackgroundImage(filename, stretch) + gtk.idle_add(self.setBackgroundImage, filename, stretch) - def setBackgroundImage(self, filename, stretch): + def setBackgroundImage(self, filename, stretch=False): print 'setBackgroundImage', filename + if filename is None: + if self.__tileimage: + self.__tileimage.destroy() + self.__tileimage = None + return width, height = self.get_size() pixbuf = gtk.gdk.pixbuf_new_from_file(filename) @@ -509,6 +507,19 @@ class MfxCanvas(gnome.canvas.Canvas): self.update_now() pass + def updateAll(self): + print 'Canvas - updateAll', + for i in self._all_items: + i._item.hide() + self.update_now() + n = 0 + for i in self._all_items: + i._item.show() + print n, i + n += 1 + self.update_now() + #self.window.invalidate_rect((0, 0, 400, 400), True) + def grid(self, *args, **kw): self.top.table.attach(self, diff --git a/pysollib/pysolgtk/tkconst.py b/pysollib/pysolgtk/tkconst.py index a6dae2b0..df733e72 100644 --- a/pysollib/pysolgtk/tkconst.py +++ b/pysollib/pysolgtk/tkconst.py @@ -31,9 +31,12 @@ # imports -import sys +##import sys + from gtk import gdk +from gtk import ANCHOR_NW, ANCHOR_SW, ANCHOR_NE, ANCHOR_SE + # /*********************************************************************** # // constants diff --git a/pysollib/pysolgtk/tkwidget.py b/pysollib/pysolgtk/tkwidget.py index 1cef442c..974853b9 100644 --- a/pysollib/pysolgtk/tkwidget.py +++ b/pysollib/pysolgtk/tkwidget.py @@ -51,8 +51,8 @@ from pysollib.mfxutil import kwdefault, KwStruct class _MyDialog(gtk.Dialog): def __init__(self): gtk.Dialog.__init__(self) - style = self.get_style().copy() - self.set_style(style) + ##~ style = self.get_style().copy() + ##~ self.set_style(style) self.connect("destroy", self.quit) self.connect("delete_event", self.quit) diff --git a/pysollib/pysolgtk/tkwrap.py b/pysollib/pysolgtk/tkwrap.py index a11f3977..2b8065b7 100644 --- a/pysollib/pysolgtk/tkwrap.py +++ b/pysollib/pysolgtk/tkwrap.py @@ -124,17 +124,24 @@ class _MfxToplevel(gtk.Window): # FIXME return gdk.LEFT_PTR return self.get_window().get_cursor(v) + elif attr in ("background", "bg"): + c = self.style.bg[gtk.STATE_NORMAL] + c = '#%02x%02x%02x' % (c.red/256, c.green/256, c.blue/256) + return c print "Toplevel cget:", attr ##~ raise AttributeError, attr + return None def configure(self, **kw): height, width = -1, -1 for k, v in kw.items(): - if k == "background" or k == "bg": - c = self.get_colormap().alloc_color(v) - self.style.bg[gtk.STATE_NORMAL] = c + if k in ("background", "bg"): + ##print "Toplevel configure: bg" + ##~ c = self.get_colormap().alloc_color(v) + ##~ self.style.bg[gtk.STATE_NORMAL] = c ##~ self.set_style(self.style) - self.queue_draw() + ##~ self.queue_draw() + pass elif k == "cursor": self.setCursor(v) elif k == "height": diff --git a/pysollib/tk/selectcardset.py b/pysollib/tk/selectcardset.py index 8612ea36..17fc322a 100644 --- a/pysollib/tk/selectcardset.py +++ b/pysollib/tk/selectcardset.py @@ -33,7 +33,7 @@ ## ##---------------------------------------------------------------------------## -__all__ = ['SelectCardsetByTypeDialogWithPreview'] +__all__ = ['SelectCardsetDialogWithPreview'] # imports import os, re, sys, types, Tkinter