1
0
Fork 0
mirror of https://github.com/shlomif/PySolFC.git synced 2025-04-05 00:02:29 -04:00
This commit is contained in:
Shlomi Fish 2017-04-17 16:26:25 +03:00
parent 589fd65f0a
commit b349234f48
5 changed files with 222 additions and 178 deletions

View file

@ -24,17 +24,11 @@
__all__ = ['HTMLViewer'] __all__ = ['HTMLViewer']
# imports # imports
import os, sys import os
import formatter import sys
import Tkinter import Tkinter
import ttk import ttk
if __name__ == '__main__':
d = os.path.abspath(os.path.join(sys.path[0], '..', '..'))
sys.path.append(d)
import gettext
gettext.install('pysol', d, unicode=True)
# PySol imports # PySol imports
from pysollib.mygettext import _ from pysollib.mygettext import _
from pysollib.mfxutil import Struct from pysollib.mfxutil import Struct
@ -43,12 +37,19 @@ from pysollib.mfxutil import Struct
from tkwidget import MfxMessageDialog from tkwidget import MfxMessageDialog
from statusbar import HtmlStatusbar from statusbar import HtmlStatusbar
from pysollib.ui.tktile.tkhtml import Base_HTMLViewer, REMOTE_PROTOCOLS, tkHTMLWriter, tkHTMLParser from pysollib.ui.tktile.tkhtml import Base_HTMLViewer
if __name__ == '__main__':
d = os.path.abspath(os.path.join(sys.path[0], '..', '..'))
sys.path.append(d)
import gettext
gettext.install('pysol', d, unicode=True)
# ************************************************************************ # ************************************************************************
# * # *
# ************************************************************************ # ************************************************************************
class HTMLViewer(Base_HTMLViewer): class HTMLViewer(Base_HTMLViewer):
symbols_fn = {} # filenames, loaded in Application.loadImages3 symbols_fn = {} # filenames, loaded in Application.loadImages3
symbols_img = {} symbols_img = {}
@ -62,13 +63,14 @@ class HTMLViewer(Base_HTMLViewer):
self.home = home self.home = home
self.url = None self.url = None
self.history = Struct( self.history = Struct(
list = [], list=[],
index = 0, index=0,
) )
self.visited_urls = [] self.visited_urls = []
self.images = {} # need to keep a reference because of garbage collection # need to keep a reference because of garbage collection
self.images = {}
self.defcursor = parent["cursor"] self.defcursor = parent["cursor"]
##self.defcursor = 'xterm' # self.defcursor = 'xterm'
self.handcursor = "hand2" self.handcursor = "hand2"
frame = ttk.Frame(parent, width=640, height=440) frame = ttk.Frame(parent, width=640, height=440)
@ -141,7 +143,6 @@ def tkhtml_main(args):
top.mainloop() top.mainloop()
return 0 return 0
if __name__ == "__main__": if __name__ == "__main__":
sys.exit(tkhtml_main(sys.argv)) sys.exit(tkhtml_main(sys.argv))

View file

@ -38,15 +38,15 @@ import ttk
import tkFont import tkFont
# PySol imports # PySol imports
from pysollib.mygettext import _, n_ from pysollib.mygettext import _
from pysollib.mfxutil import KwStruct from pysollib.mfxutil import KwStruct
from pysollib.mfxutil import format_time from pysollib.mfxutil import format_time
##from pysollib.util import * # from pysollib.util import *
from pysollib.stats import PysolStatsFormatter, ProgressionFormatter from pysollib.stats import PysolStatsFormatter, ProgressionFormatter
from pysollib.settings import TOP_TITLE from pysollib.settings import TOP_TITLE
# Toolkit imports # Toolkit imports
from pysollib.ui.tktile.tkutil import bind, unbind_destroy, loadImage from pysollib.ui.tktile.tkutil import bind, loadImage
from tkwidget import MfxDialog, MfxMessageDialog from tkwidget import MfxDialog, MfxMessageDialog
@ -67,7 +67,7 @@ class StatsDialog(MfxDialog):
self.tkfont = tkFont.Font(parent, self.font) self.tkfont = tkFont.Font(parent, self.font)
self.font_metrics = self.tkfont.metrics() self.font_metrics = self.tkfont.metrics()
style = ttk.Style(parent) style = ttk.Style(parent)
heading_font = style.lookup('Heading', 'font') # treeview heading heading_font = style.lookup('Heading', 'font') # treeview heading
self.heading_tkfont = tkFont.Font(parent, heading_font) self.heading_tkfont = tkFont.Font(parent, heading_font)
self.selected_game = None self.selected_game = None
@ -99,7 +99,7 @@ class StatsDialog(MfxDialog):
if StatsDialog.SELECTED_TAB < len(self.notebook_tabs): if StatsDialog.SELECTED_TAB < len(self.notebook_tabs):
notebook.select(StatsDialog.SELECTED_TAB) notebook.select(StatsDialog.SELECTED_TAB)
bind(notebook, '<<NotebookTabChanged>>', self.tabChanged) bind(notebook, '<<NotebookTabChanged>>', self.tabChanged)
##notebook.enableTraversal() # notebook.enableTraversal()
self.notebook = notebook self.notebook = notebook
focus = self.createButtons(bottom_frame, kw) focus = self.createButtons(bottom_frame, kw)
@ -107,12 +107,13 @@ class StatsDialog(MfxDialog):
self.mainloop(focus, kw.timeout) self.mainloop(focus, kw.timeout)
def initKw(self, kw): def initKw(self, kw):
kw = KwStruct(kw, kw = KwStruct(
strings=((_("&Play this game"), 401), kw,
"sep", _("&OK"), strings=((_("&Play this game"), 401),
(_("&Reset..."), 500)), "sep", _("&OK"),
default=0, (_("&Reset..."), 500)),
separator=False, default=0,
separator=False,
) )
return MfxDialog.initKw(self, kw) return MfxDialog.initKw(self, kw)
@ -134,7 +135,6 @@ class StatsDialog(MfxDialog):
else: else:
reset_button.config(state='disabled') reset_button.config(state='disabled')
def mDone(self, button): def mDone(self, button):
self.selected_game = self.all_games_frame.getSelectedGame() self.selected_game = self.all_games_frame.getSelectedGame()
w = self.notebook.select() w = self.notebook.select()
@ -149,7 +149,8 @@ class StatsDialog(MfxDialog):
MfxDialog.mDone(self, button) MfxDialog.mDone(self, button)
SingleGame_StatsDialog = AllGames_StatsDialog = Top_StatsDialog = ProgressionDialog = StatsDialog SingleGame_StatsDialog = AllGames_StatsDialog = Top_StatsDialog = \
ProgressionDialog = StatsDialog
# ************************************************************************ # ************************************************************************
@ -196,19 +197,19 @@ class SingleGameFrame(ttk.Frame):
if len(i) > len(t): if len(i) > len(t):
t = i t = i
t1 = font.measure(t) t1 = font.measure(t)
## t1 = max(font.measure(_("Won:")), # t1 = max(font.measure(_("Won:")),
## font.measure(_("Lost:")), # font.measure(_("Lost:")),
## font.measure(_("Total:"))) # font.measure(_("Total:")))
t1 += 10 t1 += 10
##t2 = font.measure('99999')+10 # t2 = font.measure('99999')+10
t2 = 45 t2 = 45
##t3 = font.measure('100%')+10 # t3 = font.measure('100%')+10
t3 = 45 t3 = 45
tx = (t0, t0+t1+t2, t0+t1+t2+t3, t0+t1+t2+t3+20) tx = (t0, t0+t1+t2, t0+t1+t2+t3, t0+t1+t2+t3+20)
# #
ls = self.dialog.font_metrics['linespace'] ls = self.dialog.font_metrics['linespace']
ls += 5 ls += 5
#ls = max(ls, 20) # ls = max(ls, 20)
ty = (5, 5+ls, 5+2*ls+15, max(85, 5+3*ls+15)) ty = (5, 5+ls, 5+2*ls+15, max(85, 5+3*ls+15))
# #
self.tab_x, self.tab_y = tx, ty self.tab_x, self.tab_y = tx, ty
@ -225,7 +226,7 @@ class SingleGameFrame(ttk.Frame):
frame = ttk.LabelFrame(self.right_frame, text=text) frame = ttk.LabelFrame(self.right_frame, text=text)
frame.pack(side='top', fill='both', expand=False, padx=20, pady=10) frame.pack(side='top', fill='both', expand=False, padx=20, pady=10)
style = ttk.Style(self.parent) style = ttk.Style(self.parent)
fg = style.lookup('.', 'foreground') or None # use default if fg == '' fg = style.lookup('.', 'foreground') or None # use default if fg == ''
bg = style.lookup('.', 'background') or None bg = style.lookup('.', 'background') or None
self.fg = fg self.fg = fg
# #
@ -265,16 +266,15 @@ class SingleGameFrame(ttk.Frame):
c.create_text(x, ty[1]-dy, text="%d%%" % (100-pw), c.create_text(x, ty[1]-dy, text="%d%%" % (100-pw),
anchor="ne", font=tfont, fill=fg) anchor="ne", font=tfont, fill=fg)
def createPieChart(self, app, won, lost, text): def createPieChart(self, app, won, lost, text):
#c, tfont, fg = self._createChartInit(frame, 300, 100, text) # c, tfont, fg = self._createChartInit(frame, 300, 100, text)
# #
self._createChartInit(text) self._createChartInit(text)
c, tfont, fg = self.canvas, self.dialog.font, self.fg c, tfont = self.canvas, self.dialog.font
pwon, plost = self._getPwon(won, lost) pwon, plost = self._getPwon(won, lost)
# #
#tx = (160, 250, 280) # tx = (160, 250, 280)
#ty = (21, 41, 75) # ty = (21, 41, 75)
# #
tx, ty = self.tab_x, self.tab_y tx, ty = self.tab_x, self.tab_y
x0, y0 = 20, 10 # base coords x0, y0 = 20, 10 # base coords
@ -282,7 +282,7 @@ class SingleGameFrame(ttk.Frame):
h = self.oval_height h = self.oval_height
d = 9 # delta d = 9 # delta
if won + lost > 0: if won + lost > 0:
##s, ewon, elost = 90.0, -360.0 * pwon, -360.0 * plost # s, ewon, elost = 90.0, -360.0 * pwon, -360.0 * plost
s, ewon, elost = 0.0, 360.0 * pwon, 360.0 * plost s, ewon, elost = 0.0, 360.0 * pwon, 360.0 * plost
c.create_arc(x0, y0+d, x0+w, y0+h+d, fill="#007f00", c.create_arc(x0, y0+d, x0+w, y0+h+d, fill="#007f00",
start=s, extent=ewon) start=s, extent=ewon)
@ -328,7 +328,7 @@ class TreeFormatter(PysolStatsFormatter):
self._tabs = self.parent_window.tree_tabs self._tabs = self.parent_window.tree_tabs
return return
tw = 20*self.w tw = 20*self.w
##tw = 160 # tw = 160
self._tabs = [tw] self._tabs = [tw]
measure = self.tkfont.measure measure = self.tkfont.measure
for t in arg[1:]: for t in arg[1:]:
@ -341,9 +341,10 @@ class TreeFormatter(PysolStatsFormatter):
i = 0 i = 0
for column in ('#0',) + self.parent_window.COLUMNS: for column in ('#0',) + self.parent_window.COLUMNS:
text = header[i] text = header[i]
anchor = i == 0 and 'nw' or 'ne' self.tree.heading(
self.tree.heading(column, text=text, column, text=text,
command=lambda par=self.parent_window, col=column: par.headerClick(col)) command=lambda par=self.parent_window, col=column:
par.headerClick(col))
self.tree.column(column, width=16) self.tree.column(column, width=16)
i += 1 i += 1
@ -463,7 +464,7 @@ class AllGamesFrame(ttk.Frame):
sel = self.tree.selection() sel = self.tree.selection()
run_button = self.dialog.buttons[0] run_button = self.dialog.buttons[0]
if sel and len(sel) == 1: if sel and len(sel) == 1:
if sel[0] not in self.games: # "Total" if sel[0] not in self.games: # "Total"
run_button.config(state='disabled') run_button.config(state='disabled')
else: else:
run_button.config(state='normal') run_button.config(state='normal')
@ -479,7 +480,8 @@ class AllGamesFrame(ttk.Frame):
sort_by = 'name' sort_by = 'name'
else: else:
sort_by = column sort_by = column
if self.sort_by == sort_by: return if self.sort_by == sort_by:
return
self.sort_by = sort_by self.sort_by = sort_by
self.fillTreeview(self.player) self.fillTreeview(self.player)
@ -509,7 +511,7 @@ class LogDialog(MfxDialog):
self.font = app.getFont('default') self.font = app.getFont('default')
self.tkfont = tkFont.Font(parent, self.font) self.tkfont = tkFont.Font(parent, self.font)
style = ttk.Style(parent) style = ttk.Style(parent)
heading_font = style.lookup('Heading', 'font') # treeview heading heading_font = style.lookup('Heading', 'font') # treeview heading
self.heading_tkfont = tkFont.Font(parent, heading_font) self.heading_tkfont = tkFont.Font(parent, heading_font)
self.font_metrics = self.tkfont.metrics() self.font_metrics = self.tkfont.metrics()
@ -520,7 +522,7 @@ class LogDialog(MfxDialog):
title = _('Log') title = _('Log')
MfxDialog.__init__(self, parent, title, kw.resizable, kw.default) MfxDialog.__init__(self, parent, title, kw.resizable, kw.default)
##self.selected_game = None # self.selected_game = None
top_frame, bottom_frame = self.createFrames(kw) top_frame, bottom_frame = self.createFrames(kw)
notebook = ttk.Notebook(top_frame) notebook = ttk.Notebook(top_frame)
@ -537,12 +539,12 @@ class LogDialog(MfxDialog):
self.notebook_tabs.append(session_frame._w) self.notebook_tabs.append(session_frame._w)
notebook.select(LogDialog.SELECTED_TAB) notebook.select(LogDialog.SELECTED_TAB)
## bind(notebook, '<<NotebookTabChanged>>', self.tabChanged) # bind(notebook, '<<NotebookTabChanged>>', self.tabChanged)
self.notebook = notebook self.notebook = notebook
focus = self.createButtons(bottom_frame, kw) focus = self.createButtons(bottom_frame, kw)
##self.tabChanged() # configure buttons state # self.tabChanged() # configure buttons state
self.mainloop(focus, kw.timeout) self.mainloop(focus, kw.timeout)
def initKw(self, kw): def initKw(self, kw):
@ -556,7 +558,7 @@ class LogDialog(MfxDialog):
return MfxDialog.initKw(self, kw) return MfxDialog.initKw(self, kw)
def mDone(self, button): def mDone(self, button):
##self.selected_game = self.all_games_frame.getSelectedGame() # self.selected_game = self.all_games_frame.getSelectedGame()
w = self.notebook.select() w = self.notebook.select()
indx = self.notebook_tabs.index(w) indx = self.notebook_tabs.index(w)
LogDialog.SELECTED_TAB = indx LogDialog.SELECTED_TAB = indx
@ -568,6 +570,7 @@ class LogDialog(MfxDialog):
button = 204 button = 204
MfxDialog.mDone(self, button) MfxDialog.mDone(self, button)
FullLog_StatsDialog = SessionLog_StatsDialog = LogDialog FullLog_StatsDialog = SessionLog_StatsDialog = LogDialog
@ -596,6 +599,7 @@ class FullLogFrame(AllGamesFrame):
def treeviewSelected(self, *args): def treeviewSelected(self, *args):
pass pass
def headerClick(self, column): def headerClick(self, column):
pass pass
@ -620,7 +624,8 @@ class Status_StatsDialog(MfxMessageDialog):
n = n + len(s.cards) n = n + len(s.cards)
w1 = (_("Highlight piles: ") + str(stats.highlight_piles) + "\n" + w1 = (_("Highlight piles: ") + str(stats.highlight_piles) + "\n" +
_("Highlight cards: ") + str(stats.highlight_cards) + "\n" + _("Highlight cards: ") + str(stats.highlight_cards) + "\n" +
_("Highlight same rank: ") + str(stats.highlight_samerank) + "\n") _("Highlight same rank: ") +
str(stats.highlight_samerank) + "\n")
if game.s.talon: if game.s.talon:
if game.gameinfo.redeals != 0: if game.gameinfo.redeals != 0:
w2 = w2 + _("\nRedeals: ") + str(game.s.talon.round - 1) w2 = w2 + _("\nRedeals: ") + str(game.s.talon.round - 1)
@ -630,13 +635,14 @@ class Status_StatsDialog(MfxMessageDialog):
if game.s.foundations: if game.s.foundations:
w2 = w2 + _("\nCards in Foundations: ") + str(n) w2 = w2 + _("\nCards in Foundations: ") + str(n)
# #
date = time.strftime("%Y-%m-%d %H:%M", time.localtime(game.gstats.start_time)) date = time.strftime(
"%Y-%m-%d %H:%M", time.localtime(game.gstats.start_time))
MfxMessageDialog.__init__( MfxMessageDialog.__init__(
self, parent, title=_("Game status"), self, parent, title=_("Game status"),
text=game.getTitleName() + "\n" + text=game.getTitleName() + "\n" +
game.getGameNumber(format=1) + "\n" + game.getGameNumber(format=1) + "\n" +
_("Playing time: ") + game.getTime() + "\n" + _("Playing time: ") + game.getTime() + "\n" +
_("Started at: ") + date + "\n\n"+ _("Started at: ") + date + "\n\n" +
_("Moves: ") + str(game.moves.index) + "\n" + _("Moves: ") + str(game.moves.index) + "\n" +
_("Undo moves: ") + str(stats.undo_moves) + "\n" + _("Undo moves: ") + str(stats.undo_moves) + "\n" +
_("Bookmark moves: ") + str(gstats.goto_bookmark_moves) + "\n" + _("Bookmark moves: ") + str(gstats.goto_bookmark_moves) + "\n" +
@ -708,7 +714,8 @@ class _TopDialog(MfxDialog):
l = ttk.Label(**cnf) l = ttk.Label(**cnf)
l.grid(row=row, column=2, sticky='ew') l.grid(row=row, column=2, sticky='ew')
# Start time # Start time
t = time.strftime('%Y-%m-%d %H:%M', time.localtime(i.game_start_time)) t = time.strftime(
'%Y-%m-%d %H:%M', time.localtime(i.game_start_time))
cnf['text'] = t cnf['text'] = t
l = ttk.Label(**cnf) l = ttk.Label(**cnf)
l.grid(row=row, column=3, sticky='ew') l.grid(row=row, column=3, sticky='ew')
@ -727,7 +734,6 @@ class _TopDialog(MfxDialog):
focus = self.createButtons(bottom_frame, kw) focus = self.createButtons(bottom_frame, kw)
self.mainloop(focus, kw.timeout) self.mainloop(focus, kw.timeout)
def initKw(self, kw): def initKw(self, kw):
kw = KwStruct(kw, strings=(_('&OK'),), default=0, separator=True) kw = KwStruct(kw, strings=(_('&OK'),), default=0, separator=True)
return MfxDialog.initKw(self, kw) return MfxDialog.initKw(self, kw)
@ -744,17 +750,17 @@ class TopFrame(ttk.Frame):
left_label.pack(side='left', expand=True, fill='both') left_label.pack(side='left', expand=True, fill='both')
frame = ttk.LabelFrame(self, text=_('Current game'), frame = ttk.LabelFrame(self, text=_('Current game'),
padding=(10,5,10,10)) padding=(10, 5, 10, 10))
frame.pack(side='top', expand=True, fill='x', padx=10, pady=10) frame.pack(side='top', expand=True, fill='x', padx=10, pady=10)
##frame.columnconfigure(0, weight=1) # frame.columnconfigure(0, weight=1)
if not self.createTopFrame(frame, player, gameid): if not self.createTopFrame(frame, player, gameid):
ttk.Label(frame, text=_('No TOP for this game') ttk.Label(frame, text=_('No TOP for this game')
).pack(padx=10, pady=10) ).pack(padx=10, pady=10)
frame = ttk.LabelFrame(self, text=_('All games'), frame = ttk.LabelFrame(self, text=_('All games'),
padding=(10,5,10,10)) padding=(10, 5, 10, 10))
frame.pack(side='top', expand=True, fill='x', padx=10, pady=10) frame.pack(side='top', expand=True, fill='x', padx=10, pady=10)
##frame.columnconfigure(0, weight=1) # frame.columnconfigure(0, weight=1)
if not self.createTopFrame(frame, player, 'all'): if not self.createTopFrame(frame, player, 'all'):
ttk.Label(frame, text=_('No TOP for all games') ttk.Label(frame, text=_('No TOP for all games')
).pack(padx=10, pady=10) ).pack(padx=10, pady=10)
@ -762,9 +768,10 @@ class TopFrame(ttk.Frame):
def createTopFrame(self, frame, player, gameid): def createTopFrame(self, frame, player, gameid):
app = self.app app = self.app
if (player not in app.stats.games_stats or cond = (player not in app.stats.games_stats or
gameid not in app.stats.games_stats[player] or gameid not in app.stats.games_stats[player] or
not app.stats.games_stats[player][gameid].time_result.top): not app.stats.games_stats[player][gameid].time_result.top)
if cond:
return False return False
ttk.Label(frame, text=_('Minimum') ttk.Label(frame, text=_('Minimum')
@ -773,7 +780,7 @@ class TopFrame(ttk.Frame):
).grid(row=0, column=2, padx=5, pady=5) ).grid(row=0, column=2, padx=5, pady=5)
ttk.Label(frame, text=_('Average') ttk.Label(frame, text=_('Average')
).grid(row=0, column=3, padx=5, pady=5) ).grid(row=0, column=3, padx=5, pady=5)
##ttk.Label(frame, text=_('Total')).grid(row=0, column=4) # ttk.Label(frame, text=_('Total')).grid(row=0, column=4)
s = app.stats.games_stats[player][gameid] s = app.stats.games_stats[player][gameid]
@ -801,18 +808,18 @@ class TopFrame(ttk.Frame):
s.total_moves_result.top, s.total_moves_result.top,
), ),
] ]
## if s.score_result.min: # if s.score_result.min:
## ll.append(('Score:', # ll.append(('Score:',
## s.score_result.min, # s.score_result.min,
## s.score_result.max, # s.score_result.max,
## round(s.score_result.average, 2), # round(s.score_result.average, 2),
## s.score_result.top, # s.score_result.top,
## )) # ))
## if s.score_casino_result.min: # if s.score_casino_result.min:
## ll.append(('Casino Score:', # ll.append(('Casino Score:',
## s.score_casino_result.min, # s.score_casino_result.min,
## s.score_casino_result.max, # s.score_casino_result.max,
## round(s.score_casino_result.average, 2), )) # round(s.score_casino_result.average, 2), ))
for l, min, max, avr, tot, top in ll: for l, min, max, avr, tot, top in ll:
ttk.Label(frame, text=l ttk.Label(frame, text=l
).grid(row=row, column=0, padx=5, pady=5) ).grid(row=row, column=0, padx=5, pady=5)
@ -822,7 +829,8 @@ class TopFrame(ttk.Frame):
).grid(row=row, column=2, padx=5, pady=5) ).grid(row=row, column=2, padx=5, pady=5)
ttk.Label(frame, text=str(avr) ttk.Label(frame, text=str(avr)
).grid(row=row, column=3, padx=5, pady=5) ).grid(row=row, column=3, padx=5, pady=5)
##ttk.Label(frame, text=str(tot)).grid(row=row, column=4) # ttk.Label(frame, text=str(tot)).grid(row=row, column=4)
def command(gameid=gameid, top=top): def command(gameid=gameid, top=top):
self.showTop(gameid, top) self.showTop(gameid, top)
b = ttk.Button(frame, text=TOP_TITLE+' ...', b = ttk.Button(frame, text=TOP_TITLE+' ...',
@ -832,7 +840,7 @@ class TopFrame(ttk.Frame):
return True return True
def showTop(self, gameid, top): def showTop(self, gameid, top):
d = _TopDialog(self.dialog.top, TOP_TITLE, self.app, gameid, top) _TopDialog(self.dialog.top, TOP_TITLE, self.app, gameid, top)
# ************************************************************************ # ************************************************************************
@ -862,8 +870,9 @@ class ProgressionFrame(ttk.Frame):
w = max(w, 500) w = max(w, 500)
w = min(w, 600) w = min(w, 600)
self.canvas_width, self.canvas_height = w, 250 self.canvas_width, self.canvas_height = w, 250
if parent.winfo_screenwidth() < 800 or \ cond = parent.winfo_screenwidth() < 800 or \
parent.winfo_screenheight() < 600: parent.winfo_screenheight() < 600
if cond:
self.canvas_width, self.canvas_height = 400, 200 self.canvas_width, self.canvas_height = 400, 200
self.xmargin, self.ymargin = 10, 10 self.xmargin, self.ymargin = 10, 10
self.graph_dx, self.graph_dy = 10, 10 self.graph_dx, self.graph_dy = 10, 10
@ -900,7 +909,7 @@ class ProgressionFrame(ttk.Frame):
('month', _('Last month')), ('month', _('Last month')),
('year', _('Last year')), ('year', _('Last year')),
('all', _('All time')), ('all', _('All time')),
): ):
b = ttk.Radiobutton(label_frame, text=t, variable=var, b = ttk.Radiobutton(label_frame, text=t, variable=var,
value=v, command=self.updateGraph) value=v, command=self.updateGraph)
b.pack(fill='x', expand=True, padx=3, pady=1) b.pack(fill='x', expand=True, padx=3, pady=1)
@ -925,10 +934,9 @@ class ProgressionFrame(ttk.Frame):
variable=self.percent_graph_var) variable=self.percent_graph_var)
b.pack(fill='x', expand=True, padx=3, pady=1) b.pack(fill='x', expand=True, padx=3, pady=1)
#self.createGraph() # self.createGraph()
bind(canvas, '<Map>', self.createGraph) bind(canvas, '<Map>', self.createGraph)
def createGraph(self, event): def createGraph(self, event):
if self.mapped: if self.mapped:
return return
@ -975,24 +983,23 @@ class ProgressionFrame(ttk.Frame):
# caption # caption
d = self.text_height d = self.text_height
x, y = self.xmargin, self.canvas_height-self.ymargin x, y = self.xmargin, self.canvas_height-self.ymargin
id = canvas.create_rectangle(x, y, x+d, y-d, outline='black', canvas.create_rectangle(x, y, x+d, y-d, outline='black',
fill=self.played_color) fill=self.played_color)
x += d+5 x += d+5
canvas.create_text(x, y, anchor='sw', text=_('Played')) canvas.create_text(x, y, anchor='sw', text=_('Played'))
x += measure(_('Played'))+20 x += measure(_('Played'))+20
id = canvas.create_rectangle(x, y, x+d, y-d, outline='black', canvas.create_rectangle(x, y, x+d, y-d, outline='black',
fill=self.won_color) fill=self.won_color)
x += d+5 x += d+5
canvas.create_text(x, y, anchor='sw', text=_('Won')) canvas.create_text(x, y, anchor='sw', text=_('Won'))
x += measure(_('Won'))+20 x += measure(_('Won'))+20
id = canvas.create_rectangle(x, y, x+d, y-d, outline='black', canvas.create_rectangle(x, y, x+d, y-d, outline='black',
fill=self.percent_color) fill=self.percent_color)
x += d+5 x += d+5
canvas.create_text(x, y, anchor='sw', text=_('% won')) canvas.create_text(x, y, anchor='sw', text=_('% won'))
self.updateGraph() self.updateGraph()
def updateGraph(self, *args): def updateGraph(self, *args):
interval = self.variable.get() interval = self.variable.get()
canvas = self.canvas canvas = self.canvas
@ -1030,8 +1037,8 @@ class ProgressionFrame(ttk.Frame):
else: # day.month.year else: # day.month.year
text_width = self.text_width_2 text_width = self.text_width_2
if text is not None and x > xx+text_width+4: if text is not None and x > xx+text_width+4:
##id = canvas.create_line(x, y0, x, y0-5, width=3) # id = canvas.create_line(x, y0, x, y0-5, width=3)
##self.items.append(id) # self.items.append(id)
id = canvas.create_line(x, y0, x, y1, stipple='gray50') id = canvas.create_line(x, y0, x, y1, stipple='gray50')
self.items.append(id) self.items.append(id)
id = canvas.create_text(x, y0+td, anchor='n', text=text) id = canvas.create_text(x, y0+td, anchor='n', text=text)
@ -1068,15 +1075,15 @@ class ProgressionFrame(ttk.Frame):
for res in result: for res in result:
played, won = res[1], res[2] played, won = res[1], res[2]
y = y0 - int(games_resolution*played) y = y0 - int(games_resolution*played)
played_coords += [x,y] played_coords += [x, y]
y = y0 - int(games_resolution*won) y = y0 - int(games_resolution*won)
won_coords += [x,y] won_coords += [x, y]
if played > 0: if played > 0:
percent = int(100.*won/played) percent = int(100.*won/played)
else: else:
percent = 0 percent = 0
y = y0 - int(percent_resolution*percent) y = y0 - int(percent_resolution*percent)
percent_coords += [x,y] percent_coords += [x, y]
x += dx x += dx
if self.played_graph_var.get(): if self.played_graph_var.get():
id = canvas.create_line(fill=self.played_color, width=3, id = canvas.create_line(fill=self.played_color, width=3,
@ -1090,5 +1097,3 @@ class ProgressionFrame(ttk.Frame):
id = canvas.create_line(fill=self.percent_color, width=3, id = canvas.create_line(fill=self.percent_color, width=3,
*percent_coords) *percent_coords)
self.items.append(id) self.items.append(id)

View file

@ -1,6 +1,6 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- mode: python; coding: utf-8; -*- # -*- mode: python; coding: utf-8; -*-
# ---------------------------------------------------------------------------## # ---------------------------------------------------------------------------
# #
# Copyright (C) 1998-2003 Markus Franz Xaver Johannes Oberhumer # Copyright (C) 1998-2003 Markus Franz Xaver Johannes Oberhumer
# Copyright (C) 2003 Mt. Hood Playing Card Co. # Copyright (C) 2003 Mt. Hood Playing Card Co.
@ -19,7 +19,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
# ---------------------------------------------------------------------------## # ---------------------------------------------------------------------------
# imports # imports
import os import os
@ -63,10 +63,12 @@ class MfxTreeBaseNode:
def draw(self, x, y, lastx=None, lasty=None): def draw(self, x, y, lastx=None, lasty=None):
canvas, style = self.tree.canvas, self.tree.style canvas, style = self.tree.canvas, self.tree.style
topleftx = x + style.distx topleftx = x + style.distx
toplefty = y - style.height / 2 #+++ toplefty = y - style.height / 2 # +++
# draw the horizontal line # draw the horizontal line
if lastx is not None: if lastx is not None:
canvas.create_line(x, y, topleftx, y, stipple=style.linestyle, fill=style.linecolor) canvas.create_line(
x, y, topleftx, y, stipple=style.linestyle,
fill=style.linecolor)
# draw myself - ugly, ugly... # draw myself - ugly, ugly...
self.selected = 0 self.selected = 0
self.symbol_id = -1 self.symbol_id = -1
@ -93,7 +95,7 @@ class MfxTreeBaseNode:
# note: I don't use Label + canvas.create_window here # note: I don't use Label + canvas.create_window here
# because it doesn't propagate events to the canvas # because it doesn't propagate events to the canvas
# and has some other re-display annoyances # and has some other re-display annoyances
##print 'style.font:', style.font # print 'style.font:', style.font
self.text_id = canvas.create_text(x+1, y, text=self.text, self.text_id = canvas.create_text(x+1, y, text=self.text,
anchor="w", justify="left", anchor="w", justify="left",
font=style.font, font=style.font,
@ -108,8 +110,9 @@ class MfxTreeBaseNode:
pass pass
elif self.selected: elif self.selected:
b = canvas.bbox(self.text_id) b = canvas.bbox(self.text_id)
self.textrect_id = canvas.create_rectangle(b[0]-1, b[1]-1, b[2]+1, b[3]+1, self.textrect_id = canvas.create_rectangle(
fill=bg, outline="") b[0]-1, b[1]-1, b[2]+1, b[3]+1,
fill=bg, outline="")
canvas.tag_lower(self.textrect_id, self.text_id) canvas.tag_lower(self.textrect_id, self.text_id)
self.tree.nodes[self.textrect_id] = self self.tree.nodes[self.textrect_id] = self
@ -179,7 +182,6 @@ class MfxTreeNode(MfxTreeBaseNode):
fill=style.linecolor) fill=style.linecolor)
return ny return ny
def draw(self, x, y, ilastx=None, ilasty=None): def draw(self, x, y, ilastx=None, ilasty=None):
# draw myself # draw myself
lx, ly, nx, ny = MfxTreeBaseNode.draw(self, x, y, ilastx, ilasty) lx, ly, nx, ny = MfxTreeBaseNode.draw(self, x, y, ilastx, ilasty)
@ -188,7 +190,7 @@ class MfxTreeNode(MfxTreeBaseNode):
childx = nx + style.distx + style.width / 2 childx = nx + style.distx + style.width / 2
childy = ny childy = ny
clastx = nx + style.distx + style.width / 2 clastx = nx + style.distx + style.width / 2
clasty = ly + style.height /2 clasty = ly + style.height / 2
ny = self.drawChildren(childx, childy, clastx, clasty) ny = self.drawChildren(childx, childy, clastx, clasty)
return lx, ly, x, ny return lx, ly, x, ny
@ -239,13 +241,16 @@ class MfxTreeInCanvas(MfxScrolledCanvas):
self.keys = {} self.keys = {}
# #
self.style = self.Style() self.style = self.Style()
##self.style.text_normal_fg = self.canvas.cget("insertbackground") # self.style.text_normal_fg = self.canvas.cget("insertbackground")
#self.style.text_normal_fg = self.canvas.option_get('foreground', '') or self.canvas.cget("insertbackground") # self.style.text_normal_fg = \
#self.style.text_normal_bg = self.canvas.option_get('background', self.canvas.cget("background")) # self.canvas.option_get('foreground', '') or \
# self.canvas.cget("insertbackground")
# self.style.text_normal_bg = self.canvas.option_get(
# 'background', self.canvas.cget("background"))
# #
bind(self.canvas, "<ButtonPress-1>", self.singleClick) bind(self.canvas, "<ButtonPress-1>", self.singleClick)
bind(self.canvas, "<Double-Button-1>", self.doubleClick) bind(self.canvas, "<Double-Button-1>", self.doubleClick)
##bind(self.canvas, "<ButtonRelease-1>", xxx) # bind(self.canvas, "<ButtonRelease-1>", xxx)
self.pack(fill='both', expand=True) self.pack(fill='both', expand=True)
def destroy(self): def destroy(self):
@ -281,10 +286,10 @@ class MfxTreeInCanvas(MfxScrolledCanvas):
raise raise
# set scroll region # set scroll region
bbox = self.canvas.bbox("all") bbox = self.canvas.bbox("all")
##self.canvas.config(scrollregion=bbox) # self.canvas.config(scrollregion=bbox)
##self.canvas.config(scrollregion=(0,0,bbox[2],bbox[3])) # self.canvas.config(scrollregion=(0,0,bbox[2],bbox[3]))
dx, dy = 8, 0 # margins dx, dy = 8, 0 # margins
self.canvas.config(scrollregion=(-dx,-dy,bbox[2]+dx,bbox[3]+dy)) self.canvas.config(scrollregion=(-dx, -dy, bbox[2]+dx, bbox[3]+dy))
self.canvas.config(yscrollincrement=self.style.disty) self.canvas.config(yscrollincrement=self.style.disty)
def clear(self): def clear(self):
@ -374,7 +379,7 @@ class DirectoryBrowser(MfxTreeInCanvas):
return node.subnodes return node.subnodes
# #
dir = node.key dir = node.key
print "Getting %s" % dir print("Getting %s" % dir)
try: try:
filenames = os.listdir(dir) filenames = os.listdir(dir)
filenames.sort() filenames.sort()
@ -383,14 +388,14 @@ class DirectoryBrowser(MfxTreeInCanvas):
contents = [] contents = []
for filename in filenames: for filename in filenames:
self.addNode(contents, node, os.path.join(dir, filename), filename) self.addNode(contents, node, os.path.join(dir, filename), filename)
##print "gotten" # print "gotten"
return contents return contents
def singleClick(self, event=None): def singleClick(self, event=None):
node = self.findNode(event) node = self.findNode(event)
if not node: if not node:
return return
print "Clicked node %s %s" % (node.text, node.key) print("Clicked node %s %s" % (node.text, node.key))
if isinstance(node, MfxTreeLeaf): if isinstance(node, MfxTreeLeaf):
self.updateSelection(key=node.key) self.updateSelection(key=node.key)
elif isinstance(node, MfxTreeNode): elif isinstance(node, MfxTreeNode):
@ -406,5 +411,3 @@ if __name__ == "__main__":
else: else:
app = DirectoryBrowser(tk, ("/", "/home")) app = DirectoryBrowser(tk, ("/", "/home"))
tk.mainloop() tk.mainloop()

View file

@ -1,6 +1,6 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- mode: python; coding: utf-8; -*- # -*- mode: python; coding: utf-8; -*-
# ---------------------------------------------------------------------------## # ---------------------------------------------------------------------------
# #
# Copyright (C) 1998-2003 Markus Franz Xaver Johannes Oberhumer # Copyright (C) 1998-2003 Markus Franz Xaver Johannes Oberhumer
# Copyright (C) 2003 Mt. Hood Playing Card Co. # Copyright (C) 2003 Mt. Hood Playing Card Co.
@ -19,7 +19,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
# ---------------------------------------------------------------------------## # ---------------------------------------------------------------------------
__all__ = ['MfxDialog', __all__ = ['MfxDialog',
'MfxMessageDialog', 'MfxMessageDialog',
@ -32,14 +32,17 @@ __all__ = ['MfxDialog',
] ]
# imports # imports
import sys, os, time, locale import sys
import os
import time
import locale
import Tkinter import Tkinter
import ttk import ttk
import tkFont import tkFont
import traceback import traceback
# PySol imports # PySol imports
from pysollib.mygettext import _, n_ from pysollib.mygettext import _
from pysollib.mfxutil import destruct, kwdefault, KwStruct, openURL from pysollib.mfxutil import destruct, kwdefault, KwStruct, openURL
from pysollib.settings import WIN_SYSTEM from pysollib.settings import WIN_SYSTEM
@ -49,12 +52,15 @@ from pysollib.ui.tktile.tkutil import bind, unbind_destroy
from pysollib.ui.tktile.tkutil import makeToplevel, setTransient from pysollib.ui.tktile.tkutil import makeToplevel, setTransient
from pysollib.ui.tktile.tkcanvas import MfxCanvas from pysollib.ui.tktile.tkcanvas import MfxCanvas
if sys.version_info > (3,):
unicode = str
# ************************************************************************ # ************************************************************************
# * abstract base class for the dialogs in this module # * abstract base class for the dialogs in this module
# ************************************************************************ # ************************************************************************
class MfxDialog: # ex. _ToplevelDialog
class MfxDialog: # ex. _ToplevelDialog
img = {} img = {}
button_img = {} button_img = {}
@ -66,17 +72,17 @@ class MfxDialog: # ex. _ToplevelDialog
self.buttons = [] self.buttons = []
self.accel_keys = {} self.accel_keys = {}
self.top = makeToplevel(parent, title=title) self.top = makeToplevel(parent, title=title)
#self._frame = ttk.Frame(self.top) # self._frame = ttk.Frame(self.top)
#self._frame.pack(expand=True, fill='both') # self._frame.pack(expand=True, fill='both')
self._frame = self.top self._frame = self.top
self.top.wm_resizable(resizable, resizable) self.top.wm_resizable(resizable, resizable)
##w, h = self.top.winfo_screenwidth(), self.top.winfo_screenheight() # w, h = self.top.winfo_screenwidth(), self.top.winfo_screenheight()
##self.top.wm_maxsize(w-4, h-32) # self.top.wm_maxsize(w-4, h-32)
bind(self.top, "WM_DELETE_WINDOW", self.wmDeleteWindow) bind(self.top, "WM_DELETE_WINDOW", self.wmDeleteWindow)
def mainloop(self, focus=None, timeout=0, transient=True): def mainloop(self, focus=None, timeout=0, transient=True):
bind(self.top, "<Escape>", self.mCancel) bind(self.top, "<Escape>", self.mCancel)
bind(self.top, '<Alt-Key>', self.altKeyEvent) # for accelerators bind(self.top, '<Alt-Key>', self.altKeyEvent) # for accelerators
if focus is not None: if focus is not None:
focus.focus() focus.focus()
if transient: if transient:
@ -84,11 +90,13 @@ class MfxDialog: # ex. _ToplevelDialog
try: try:
self.top.grab_set() self.top.grab_set()
except Tkinter.TclError: except Tkinter.TclError:
if traceback: traceback.print_exc() if traceback:
traceback.print_exc()
pass pass
if timeout > 0: if timeout > 0:
self.timer = after(self.top, timeout, self.mTimeout) self.timer = after(self.top, timeout, self.mTimeout)
try: self.top.mainloop() try:
self.top.mainloop()
except SystemExit: except SystemExit:
pass pass
self.destroy() self.destroy()
@ -104,7 +112,7 @@ class MfxDialog: # ex. _ToplevelDialog
def wmDeleteWindow(self, *event): def wmDeleteWindow(self, *event):
self.status = 1 self.status = 1
raise SystemExit raise SystemExit
##return EVENT_HANDLED # return EVENT_HANDLED
def mCancel(self, *event): def mCancel(self, *event):
self.status = 1 self.status = 1
@ -166,7 +174,7 @@ class MfxDialog: # ex. _ToplevelDialog
return top_frame, bottom_frame return top_frame, bottom_frame
def createBitmaps(self, frame, kw): def createBitmaps(self, frame, kw):
if kw.bitmap: ## in ("error", "info", "question", "warning") if kw.bitmap: # in ("error", "info", "question", "warning")
img = self.img.get(kw.bitmap) img = self.img.get(kw.bitmap)
b = ttk.Label(frame, image=img) b = ttk.Label(frame, image=img)
b.pack(side=kw.bitmap_side, b.pack(side=kw.bitmap_side,
@ -192,11 +200,15 @@ class MfxDialog: # ex. _ToplevelDialog
if s: if s:
s = s.replace('&', '') s = s.replace('&', '')
max_len = max(max_len, len(s)) max_len = max(max_len, len(s))
##print s, len(s) # print s, len(s)
if max_len > 12 and WIN_SYSTEM == 'x11': button_width = max_len if max_len > 12 and WIN_SYSTEM == 'x11':
elif max_len > 9 : button_width = max_len+1 button_width = max_len
elif max_len > 6 : button_width = max_len+2 elif max_len > 9:
else : button_width = 8 button_width = max_len+1
elif max_len > 6:
button_width = max_len+2
else:
button_width = 8
# #
for s in kw.strings: for s in kw.strings:
if s is None: if s is None:
@ -220,9 +232,10 @@ class MfxDialog: # ex. _ToplevelDialog
if button < 0: if button < 0:
widget = ttk.Button(frame, text=s, state="disabled") widget = ttk.Button(frame, text=s, state="disabled")
else: else:
widget = ttk.Button(frame, text=s, default="normal", widget = ttk.Button(
command = lambda self=self, button=button: \ frame, text=s, default="normal",
self.mDone(button)) command=lambda self=self, button=button:
self.mDone(button))
if button == kw.default: if button == kw.default:
focus = widget focus = widget
focus.config(default="active") focus.config(default="active")
@ -241,9 +254,11 @@ class MfxDialog: # ex. _ToplevelDialog
# #
if button_img: if button_img:
widget.config(compound='left', image=button_img) widget.config(compound='left', image=button_img)
widget.grid(column=column, row=0, sticky="nse", padx=padx, pady=pady) widget.grid(
column=column, row=0, sticky="nse", padx=padx, pady=pady)
if focus is not None: if focus is not None:
l = lambda event=None, w=focus: w.event_generate('<<Invoke>>') def l(event=None, w=focus):
return w.event_generate('<<Invoke>>')
bind(self.top, "<Return>", l) bind(self.top, "<Return>", l)
bind(self.top, "<KP_Enter>", l) bind(self.top, "<KP_Enter>", l)
# right justify # right justify
@ -283,7 +298,8 @@ class MfxExceptionDialog(MfxMessageDialog):
text = text + "\n" text = text + "\n"
text = text + "\n" text = text + "\n"
if isinstance(ex, EnvironmentError) and ex.filename is not None: if isinstance(ex, EnvironmentError) and ex.filename is not None:
t = "[Errno %s] %s:\n%s" % (ex.errno, ex.strerror, repr(ex.filename)) t = "[Errno %s] %s:\n%s" % \
(ex.errno, ex.strerror, repr(ex.filename))
else: else:
t = str(ex) t = str(ex)
kw.text = text + unicode(t, errors='replace') kw.text = text + unicode(t, errors='replace')
@ -310,7 +326,7 @@ class PysolAboutDialog(MfxMessageDialog):
msg.pack(fill='both', expand=True) msg.pack(fill='both', expand=True)
if sys.version_info >= (2, 4): if sys.version_info >= (2, 4):
##font_name = msg.lookup('TLabel', 'font') # font_name = msg.lookup('TLabel', 'font')
font_name = 'TkDefaultFont' font_name = 'TkDefaultFont'
font = tkFont.Font(parent, name=font_name, exists=True) font = tkFont.Font(parent, name=font_name, exists=True)
font = font.copy() font = font.copy()
@ -436,10 +452,10 @@ class MfxTooltip:
self.timer = None self.timer = None
if self.tooltip or not self.text: if self.tooltip or not self.text:
return return
## if isinstance(self.widget, (ttk.Button, ttk.Checkbutton)): # if isinstance(self.widget, (ttk.Button, ttk.Checkbutton)):
## if self.widget["state"] == 'disabled': # if self.widget["state"] == 'disabled':
## return # return
##x = self.widget.winfo_rootx() # x = self.widget.winfo_rootx()
x = self.widget.winfo_pointerx() x = self.widget.winfo_pointerx()
y = self.widget.winfo_rooty() + self.widget.winfo_height() y = self.widget.winfo_rooty() + self.widget.winfo_height()
x += self.xoffset x += self.xoffset
@ -454,8 +470,9 @@ class MfxTooltip:
self.label.pack(ipadx=1, ipady=1) self.label.pack(ipadx=1, ipady=1)
self.tooltip.wm_geometry("%+d%+d" % (x, y)) self.tooltip.wm_geometry("%+d%+d" % (x, y))
self.tooltip.wm_deiconify() self.tooltip.wm_deiconify()
self.cancel_timer = after(self.widget, self.cancel_timeout, self._leave) self.cancel_timer = after(
##self.tooltip.tkraise() self.widget, self.cancel_timeout, self._leave)
# self.tooltip.tkraise()
# ************************************************************************ # ************************************************************************
@ -482,7 +499,7 @@ class MfxScrolledCanvas:
if vbar: if vbar:
self.createVbar() self.createVbar()
self.bindVbar() self.bindVbar()
###self.canvas.focus_set() # self.canvas.focus_set()
# #
# #
@ -507,7 +524,7 @@ class MfxScrolledCanvas:
tile = app.tabletile_manager.get(i) tile = app.tabletile_manager.get(i)
if tile is None or tile.error: if tile is None or tile.error:
return False return False
##print i, tile # print i, tile
if i == 0: if i == 0:
assert tile.color assert tile.color
assert tile.filename is None assert tile.filename is None
@ -517,19 +534,20 @@ class MfxScrolledCanvas:
assert tile.basename assert tile.basename
if not force: if not force:
if (i == app.tabletile_index and if (i == app.tabletile_index and
tile.color == app.opt.colors['table']): tile.color == app.opt.colors['table']):
return False return False
# #
if not self.canvas.setTile(tile.filename, tile.stretch, tile.save_aspect): if not self.canvas.setTile(tile.filename, tile.stretch,
tile.save_aspect):
tile.error = True tile.error = True
return False return False
if i == 0: if i == 0:
self.canvas.config(bg=tile.color) self.canvas.config(bg=tile.color)
##app.top.config(bg=tile.color) # app.top.config(bg=tile.color)
else: else:
self.canvas.config(bg=app.top_bg) self.canvas.config(bg=app.top_bg)
##app.top.config(bg=app.top_bg) # app.top.config(bg=app.top_bg)
self.canvas.setTextColor(app.opt.colors['text']) self.canvas.setTextColor(app.opt.colors['text'])
@ -549,6 +567,7 @@ class MfxScrolledCanvas:
width = kw.get("width") width = kw.get("width")
height = kw.get("height") height = kw.get("height")
self.frame = ttk.Frame(self.parent, width=width, height=height) self.frame = ttk.Frame(self.parent, width=width, height=height)
def createCanvas(self, kw): def createCanvas(self, kw):
bd = kw['bd'] bd = kw['bd']
kw['bd'] = 0 kw['bd'] = 0
@ -558,24 +577,29 @@ class MfxScrolledCanvas:
frame.grid(row=0, column=0, sticky="news") frame.grid(row=0, column=0, sticky="news")
self.canvas = MfxCanvas(frame, **kw) self.canvas = MfxCanvas(frame, **kw)
self.canvas.pack(expand=True, fill='both') self.canvas.pack(expand=True, fill='both')
def createHbar(self): def createHbar(self):
self.hbar = ttk.Scrollbar(self.frame, takefocus=0, self.hbar = ttk.Scrollbar(self.frame, takefocus=0,
orient="horizontal") orient="horizontal")
self.canvas["xscrollcommand"] = self._setHbar self.canvas["xscrollcommand"] = self._setHbar
self.hbar["command"] = self.canvas.xview self.hbar["command"] = self.canvas.xview
self.hbar.grid(row=1, column=0, sticky="we") self.hbar.grid(row=1, column=0, sticky="we")
self.hbar.grid_remove() self.hbar.grid_remove()
def createVbar(self): def createVbar(self):
self.vbar = ttk.Scrollbar(self.frame, takefocus=0) self.vbar = ttk.Scrollbar(self.frame, takefocus=0)
self.canvas["yscrollcommand"] = self._setVbar self.canvas["yscrollcommand"] = self._setVbar
self.vbar["command"] = self.canvas.yview self.vbar["command"] = self.canvas.yview
self.vbar.grid(row=0, column=1, sticky="ns") self.vbar.grid(row=0, column=1, sticky="ns")
self.vbar.grid_remove() self.vbar.grid_remove()
def bindHbar(self, w=None): def bindHbar(self, w=None):
if w is None: if w is None:
w = self.canvas w = self.canvas
bind(w, "<KeyPress-Left>", self.unit_left) bind(w, "<KeyPress-Left>", self.unit_left)
bind(w, "<KeyPress-Right>", self.unit_right) bind(w, "<KeyPress-Right>", self.unit_right)
def bindVbar(self, w=None): def bindVbar(self, w=None):
if w is None: if w is None:
w = self.canvas w = self.canvas
@ -591,10 +615,10 @@ class MfxScrolledCanvas:
bind(w, '<4>', self.mouse_wheel_up) bind(w, '<4>', self.mouse_wheel_up)
bind(w, '<5>', self.mouse_wheel_down) bind(w, '<5>', self.mouse_wheel_down)
# don't work on Linux # don't work on Linux
#bind(w, '<MouseWheel>', self.mouse_wheel) # bind(w, '<MouseWheel>', self.mouse_wheel)
def mouse_wheel(self, *args): def mouse_wheel(self, *args):
print 'MfxScrolledCanvas.mouse_wheel', args print('MfxScrolledCanvas.mouse_wheel', args)
def _setHbar(self, first, last): def _setHbar(self, first, last):
if self.canvas.busy: if self.canvas.busy:
@ -608,6 +632,7 @@ class MfxScrolledCanvas:
sb.grid() sb.grid()
self.hbar_show = True self.hbar_show = True
sb.set(first, last) sb.set(first, last)
def _setVbar(self, first, last): def _setVbar(self, first, last):
if self.canvas.busy: if self.canvas.busy:
return return
@ -622,34 +647,48 @@ class MfxScrolledCanvas:
sb.set(first, last) sb.set(first, last)
def _xview(self, *args): def _xview(self, *args):
if self.hbar_show: self.canvas.xview(*args) if self.hbar_show:
self.canvas.xview(*args)
return 'break' return 'break'
def _yview(self, *args): def _yview(self, *args):
if self.vbar_show: self.canvas.yview(*args) if self.vbar_show:
self.canvas.yview(*args)
return 'break' return 'break'
def page_up(self, *event): def page_up(self, *event):
return self._yview('scroll', -1, 'page') return self._yview('scroll', -1, 'page')
def page_down(self, *event): def page_down(self, *event):
return self._yview('scroll', 1, 'page') return self._yview('scroll', 1, 'page')
def unit_up(self, *event): def unit_up(self, *event):
return self._yview('scroll', -1, 'unit') return self._yview('scroll', -1, 'unit')
def unit_down(self, *event): def unit_down(self, *event):
return self._yview('scroll', 1, 'unit') return self._yview('scroll', 1, 'unit')
def mouse_wheel_up(self, *event): def mouse_wheel_up(self, *event):
return self._yview('scroll', -5, 'unit') return self._yview('scroll', -5, 'unit')
def mouse_wheel_down(self, *event): def mouse_wheel_down(self, *event):
return self._yview('scroll', 5, 'unit') return self._yview('scroll', 5, 'unit')
def page_left(self, *event): def page_left(self, *event):
return self._xview('scroll', -1, 'page') return self._xview('scroll', -1, 'page')
def page_right(self, *event): def page_right(self, *event):
return self._xview('scroll', 1, 'page') return self._xview('scroll', 1, 'page')
def unit_left(self, *event): def unit_left(self, *event):
return self._xview('scroll', -1, 'unit') return self._xview('scroll', -1, 'unit')
def unit_right(self, *event): def unit_right(self, *event):
return self._xview('scroll', 1, 'unit') return self._xview('scroll', 1, 'unit')
def scroll_top(self, *event): def scroll_top(self, *event):
return self._yview('moveto', 0) return self._yview('moveto', 0)
def scroll_bottom(self, *event): def scroll_bottom(self, *event):
return self._yview('moveto', 1) return self._yview('moveto', 1)
@ -667,7 +706,7 @@ class StackDesc:
self.bindings = [] self.bindings = []
font = game.app.getFont('canvas_small') font = game.app.getFont('canvas_small')
##print self.app.cardset.CARDW, self.app.images.CARDW # print self.app.cardset.CARDW, self.app.images.CARDW
cardw = game.app.images.getSize()[0] cardw = game.app.images.getSize()[0]
x, y = stack.x+cardw/2, stack.y x, y = stack.x+cardw/2, stack.y
text = stack.getHelp()+'\n'+stack.getBaseCard() text = stack.getHelp()+'\n'+stack.getBaseCard()
@ -683,12 +722,12 @@ class StackDesc:
self.id = self.canvas.create_window(x, y, window=frame, anchor='n') self.id = self.canvas.create_window(x, y, window=frame, anchor='n')
self.bindings.append(label.bind('<ButtonPress>', self.bindings.append(label.bind('<ButtonPress>',
self._buttonPressEvent)) self._buttonPressEvent))
##self.bindings.append(label.bind('<Enter>', self._enterEvent)) # self.bindings.append(label.bind('<Enter>', self._enterEvent))
else: else:
self.id = None self.id = None
def _buttonPressEvent(self, *event): def _buttonPressEvent(self, *event):
##self.game.deleteStackDesc() # self.game.deleteStackDesc()
self.frame.tkraise() self.frame.tkraise()
def _enterEvent(self, *event): def _enterEvent(self, *event):
@ -735,17 +774,17 @@ class MyPysolScale:
if 'label' in kw: if 'label' in kw:
self.label_text = kw['label'] self.label_text = kw['label']
width = len(self.label_text)+4 width = len(self.label_text)+4
#width = None # width = None
del kw['label'] del kw['label']
else: else:
self.label_text = None self.label_text = None
width = 3 width = 3
# create widgets # create widgets
side = 'left' # 'top' side = 'left' # 'top'
self.frame = ttk.Frame(parent) self.frame = ttk.Frame(parent)
self.label = ttk.Label(self.frame, anchor='w', self.label = ttk.Label(self.frame, anchor='w',
width=width, padding=(5,0)) width=width, padding=(5, 0))
self.label.pack(side=side, expand=False, fill='x') self.label.pack(side=side, expand=False, fill='x')
self.scale = ttk.Scale(self.frame, **kw) self.scale = ttk.Scale(self.frame, **kw)
self.scale.pack(side=side, expand=True, fill='both', pady=4) self.scale.pack(side=side, expand=True, fill='both', pady=4)
@ -781,6 +820,7 @@ class MyPysolScale:
def pack(self, **kw): def pack(self, **kw):
self.frame.pack(**kw) self.frame.pack(**kw)
def grid(self, **kw): def grid(self, **kw):
self.frame.grid(**kw) self.frame.grid(**kw)
@ -794,6 +834,7 @@ class MyPysolScale:
def get(self): def get(self):
return self.variable.get() return self.variable.get()
def set(self, v): def set(self, v):
self.variable.set(v) self.variable.set(v)
@ -806,7 +847,7 @@ class TkinterScale(Tkinter.Scale):
PysolScale = MyPysolScale PysolScale = MyPysolScale
#PysolScale = TkinterScale # PysolScale = TkinterScale
# ************************************************************************ # ************************************************************************
@ -823,14 +864,8 @@ class PysolCombo(ttk.Combobox):
self.bind('<<ComboboxSelected>>', self._callback) self.bind('<<ComboboxSelected>>', self._callback)
def _callback(self, *args): def _callback(self, *args):
##self.selection_clear() # self.selection_clear()
self.selection_range(0,0) self.selection_range(0, 0)
if self._command is not None: if self._command is not None:
return self._command(*args) return self._command(*args)
return None return None

View file

@ -10,7 +10,7 @@ use String::ShellQuote qw/ shell_quote /;
# my $cmd = shell_quote( 'flake8', '.' ); # my $cmd = shell_quote( 'flake8', '.' );
my $cmd = shell_quote( 'flake8', my $cmd = shell_quote( 'flake8',
grep { not($_ eq './pysollib/pysoltk.py') } glob('./pysollib/*.py ./pysollib/[cmp]*/*.py ./pysollib/tile/{[a-s],ti,to,w}*.py') ); grep { not($_ eq './pysollib/pysoltk.py') } glob('./pysollib/*.py ./pysollib/[cmp]*/*.py ./pysollib/tile/{[a-s],ti,tk,to,w}*.py') );
# TEST # TEST
eq_or_diff( scalar(`$cmd`), '', "flake8 is happy with the code." ); eq_or_diff( scalar(`$cmd`), '', "flake8 is happy with the code." );