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']
# imports
import os, sys
import formatter
import os
import sys
import Tkinter
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
from pysollib.mygettext import _
from pysollib.mfxutil import Struct
@ -43,12 +37,19 @@ from pysollib.mfxutil import Struct
from tkwidget import MfxMessageDialog
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):
symbols_fn = {} # filenames, loaded in Application.loadImages3
symbols_img = {}
@ -62,13 +63,14 @@ class HTMLViewer(Base_HTMLViewer):
self.home = home
self.url = None
self.history = Struct(
list = [],
index = 0,
list=[],
index=0,
)
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 = 'xterm'
# self.defcursor = 'xterm'
self.handcursor = "hand2"
frame = ttk.Frame(parent, width=640, height=440)
@ -141,7 +143,6 @@ def tkhtml_main(args):
top.mainloop()
return 0
if __name__ == "__main__":
sys.exit(tkhtml_main(sys.argv))

View file

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

View file

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

View file

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

View file

@ -10,7 +10,7 @@ use String::ShellQuote qw/ shell_quote /;
# 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
eq_or_diff( scalar(`$cmd`), '', "flake8 is happy with the code." );