From 5e832cf63bf780bbcdd6d7b5f5c3346ad32d2a81 Mon Sep 17 00:00:00 2001 From: Joe R Date: Thu, 10 Apr 2025 18:14:45 -0400 Subject: [PATCH] Add auto-scaling to preview mode --- po/de_pysol.po | 10 ++++- po/fr_pysol.po | 10 ++++- po/it_pysol.po | 10 ++++- po/pl_pysol.po | 10 ++++- po/pt_BR_pysol.po | 10 ++++- po/pysol.pot | 8 +++- po/ru_pysol.po | 10 ++++- pysollib/actions.py | 2 + pysollib/game/__init__.py | 8 ++-- pysollib/games/mahjongg/mahjongg.py | 3 +- pysollib/options.py | 5 ++- pysollib/stack.py | 17 +++++---- pysollib/tile/selectcardset.py | 57 ++++++++++++++++++++++++++--- pysollib/tile/selectgame.py | 47 +++++++++++++++++++++--- pysollib/ui/tktile/menubar.py | 17 ++++++++- 15 files changed, 185 insertions(+), 39 deletions(-) diff --git a/po/de_pysol.po b/po/de_pysol.po index de48932b..936cc055 100644 --- a/po/de_pysol.po +++ b/po/de_pysol.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: PySol 0.0.1\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-12-10 10:19-0500\n" -"PO-Revision-Date: 2025-03-14 19:16-0400\n" +"PO-Revision-Date: 2025-04-10 18:09-0400\n" "Last-Translator: H. Schaekel \n" "Language-Team: German\n" "Language: de\n" @@ -4159,6 +4159,9 @@ msgstr "" msgid "Auto scaling" msgstr "automatische Skalierung" +msgid "Preview scaling" +msgstr "" + #: pysollib/tile/selectcardset.py:281 pysollib/tk/selectcardset.py:278 msgid "Preserve aspect ratio" msgstr "Seitenverhältnis beibehalten" @@ -5336,9 +5339,12 @@ msgstr "" msgid "&Auto scaling" msgstr "automatisch skalieren" +msgid "&Preview scaling" +msgstr "" + #, fuzzy #| msgid "Preserve aspect ratio" -msgid "&Preserve aspect ratio" +msgid "Pr&eserve aspect ratio" msgstr "Seitenverhältnis beibehalten" msgid "R&esampling" diff --git a/po/fr_pysol.po b/po/fr_pysol.po index 88321829..14fca86a 100644 --- a/po/fr_pysol.po +++ b/po/fr_pysol.po @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: 1.02\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-12-10 10:19-0500\n" -"PO-Revision-Date: 2025-03-14 19:16-0400\n" +"PO-Revision-Date: 2025-04-10 18:10-0400\n" "Last-Translator: Eric Rausch \n" "Language-Team: French\n" "Language: fr\n" @@ -4210,6 +4210,9 @@ msgstr "Échelle Y:" msgid "Auto scaling" msgstr "Échelle automatique" +msgid "Preview scaling" +msgstr "" + #: pysollib/tile/selectcardset.py:281 pysollib/tk/selectcardset.py:278 msgid "Preserve aspect ratio" msgstr "Conserver le ratio" @@ -5382,9 +5385,12 @@ msgstr "Au&gmenter la taille" msgid "&Auto scaling" msgstr "Échelle &automatique" +msgid "&Preview scaling" +msgstr "" + #, fuzzy #| msgid "Preserve aspect ratio" -msgid "&Preserve aspect ratio" +msgid "Pr&eserve aspect ratio" msgstr "Conserver le ratio" msgid "R&esampling" diff --git a/po/it_pysol.po b/po/it_pysol.po index e727858b..9bd03b73 100644 --- a/po/it_pysol.po +++ b/po/it_pysol.po @@ -12,7 +12,7 @@ msgstr "" "Project-Id-Version: it_pysol\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-12-10 10:19-0500\n" -"PO-Revision-Date: 2025-03-14 19:15-0400\n" +"PO-Revision-Date: 2025-04-10 18:10-0400\n" "Last-Translator: Giuliano Colla \n" "Language-Team: Italiano \n" "Language: it\n" @@ -4273,6 +4273,9 @@ msgstr "" msgid "Auto scaling" msgstr "Gira automatico" +msgid "Preview scaling" +msgstr "" + #: pysollib/tile/selectcardset.py:281 pysollib/tk/selectcardset.py:278 msgid "Preserve aspect ratio" msgstr "" @@ -5449,7 +5452,10 @@ msgstr "" msgid "&Auto scaling" msgstr "Gira automatico" -msgid "&Preserve aspect ratio" +msgid "&Preview scaling" +msgstr "" + +msgid "Pr&eserve aspect ratio" msgstr "" msgid "R&esampling" diff --git a/po/pl_pysol.po b/po/pl_pysol.po index 40e51755..e6c1f988 100644 --- a/po/pl_pysol.po +++ b/po/pl_pysol.po @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: PySolFC\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-12-10 10:19-0500\n" -"PO-Revision-Date: 2025-03-14 19:15-0400\n" +"PO-Revision-Date: 2025-04-10 18:11-0400\n" "Last-Translator: Jerzy Trzeciak \n" "Language-Team: Polish \n" "Language: pl\n" @@ -4227,6 +4227,9 @@ msgstr "" msgid "Auto scaling" msgstr "Automatycznie skalowanie" +msgid "Preview scaling" +msgstr "" + #: pysollib/tile/selectcardset.py:281 pysollib/tk/selectcardset.py:278 msgid "Preserve aspect ratio" msgstr "Zachowaj ratio" @@ -5400,7 +5403,10 @@ msgstr "Resetuj rozmiar kart" msgid "&Auto scaling" msgstr "Automatyczne dopasowanie" -msgid "&Preserve aspect ratio" +msgid "&Preview scaling" +msgstr "" + +msgid "Pr&eserve aspect ratio" msgstr "Zachowaj ratio" msgid "R&esampling" diff --git a/po/pt_BR_pysol.po b/po/pt_BR_pysol.po index 04f563f4..225028d0 100644 --- a/po/pt_BR_pysol.po +++ b/po/pt_BR_pysol.po @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-12-10 10:19-0500\n" -"PO-Revision-Date: 2025-03-14 19:15-0400\n" +"PO-Revision-Date: 2025-04-10 18:11-0400\n" "Last-Translator: Matheus Knack \n" "Language-Team: \n" "Language: pt_BR\n" @@ -4233,6 +4233,9 @@ msgstr "Escala Y:" msgid "Auto scaling" msgstr "Dimensionamento automático" +msgid "Preview scaling" +msgstr "" + #: pysollib/tile/selectcardset.py:281 pysollib/tk/selectcardset.py:278 msgid "Preserve aspect ratio" msgstr "Preservar a proporção" @@ -5404,9 +5407,12 @@ msgstr "&Redefinir o tamanho do carta" msgid "&Auto scaling" msgstr "&Dimensionamento automático" +msgid "&Preview scaling" +msgstr "" + #, fuzzy #| msgid "Preserve aspect ratio" -msgid "&Preserve aspect ratio" +msgid "Pr&eserve aspect ratio" msgstr "&Preservar a proporção" msgid "R&esampling" diff --git a/po/pysol.pot b/po/pysol.pot index 4f265b16..97432ce8 100644 --- a/po/pysol.pot +++ b/po/pysol.pot @@ -4015,6 +4015,9 @@ msgstr "" msgid "Auto scaling" msgstr "" +msgid "Preview scaling" +msgstr "" + #: pysollib/tile/selectcardset.py:281 pysollib/tk/selectcardset.py:278 msgid "Preserve aspect ratio" msgstr "" @@ -5132,7 +5135,10 @@ msgstr "" msgid "&Auto scaling" msgstr "" -msgid "&Preserve aspect ratio" +msgid "&Preview scaling" +msgstr "" + +msgid "Pr&eserve aspect ratio" msgstr "" msgid "R&esampling" diff --git a/po/ru_pysol.po b/po/ru_pysol.po index d4fa4cdd..c92b10c1 100644 --- a/po/ru_pysol.po +++ b/po/ru_pysol.po @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-12-10 10:19-0500\n" -"PO-Revision-Date: 2025-03-14 19:14-0400\n" +"PO-Revision-Date: 2025-04-10 18:12-0400\n" "Last-Translator: Skomoroh \n" "Language-Team: Russian \n" "Language: ru\n" @@ -4282,6 +4282,9 @@ msgstr "Размер по Y:" msgid "Auto scaling" msgstr "Автоматическое изменение размера" +msgid "Preview scaling" +msgstr "" + #: pysollib/tile/selectcardset.py:281 pysollib/tk/selectcardset.py:278 msgid "Preserve aspect ratio" msgstr "Сохранять соотношение сторон" @@ -5472,9 +5475,12 @@ msgstr "&Увеличить размер карт" msgid "&Auto scaling" msgstr "Автоматическое изменение размера" +msgid "&Preview scaling" +msgstr "" + #, fuzzy #| msgid "Preserve aspect ratio" -msgid "&Preserve aspect ratio" +msgid "Pr&eserve aspect ratio" msgstr "Сохранять соотношение сторон" msgid "R&esampling" diff --git a/pysollib/actions.py b/pysollib/actions.py index 65899f30..56593dc5 100644 --- a/pysollib/actions.py +++ b/pysollib/actions.py @@ -223,6 +223,8 @@ class PysolMenubar(PysolMenubarTk): if USE_PIL: self.setMenuState(ms.autoscale, "options.cardsize.preserveaspectratio") + self.setMenuState(ms.autoscale, + "options.cardsize.previewscaling") self.setMenuState(not ms.autoscale, "options.cardsize.increasethecardsize") self.setMenuState(not ms.autoscale, diff --git a/pysollib/game/__init__.py b/pysollib/game/__init__.py index 20f6068b..1b3e0155 100644 --- a/pysollib/game/__init__.py +++ b/pysollib/game/__init__.py @@ -843,8 +843,7 @@ class Game(object): if dealer: dealer() else: - if not self.preview: - self.resizeGame() + self.resizeGame() self.startGame() self.startMoves() for stack in self.allstacks: @@ -1065,6 +1064,9 @@ class Game(object): return 0, 0 def resizeGame(self, card_size_manually=False): + if self.preview and (not self.app.opt.auto_scale or + not self.app.opt.preview_scale): + return # if self.busy: # return if not USE_PIL: @@ -1373,7 +1375,7 @@ class Game(object): return if self._resizeHandlerID: self.canvas.after_cancel(self._resizeHandlerID) - self._resizeHandlerID = self.canvas.after(250, self._resizeHandler) + self._resizeHandlerID = self.canvas.after(300, self._resizeHandler) # should return EVENT_HANDLED or EVENT_PROPAGATE explicitly. def playSample(self, name, priority=0, loop=0): diff --git a/pysollib/games/mahjongg/mahjongg.py b/pysollib/games/mahjongg/mahjongg.py index e50758a3..1058498c 100644 --- a/pysollib/games/mahjongg/mahjongg.py +++ b/pysollib/games/mahjongg/mahjongg.py @@ -386,7 +386,8 @@ class AbstractMahjonggGame(Game): dy = -l.YOFFSET d_x = cs.SHADOW_XOFFSET d_y = cs.SHADOW_YOFFSET - if self.preview: + if self.preview and (not self.app.opt.auto_scale or + not self.app.opt.preview_scale): size_cap, r = 100, 2 if l.CW // r > size_cap or l.CH // r > size_cap: r = max(l.CW, l.CH) // size_cap diff --git a/pysollib/options.py b/pysollib/options.py index e6456fad..d0c87651 100644 --- a/pysollib/options.py +++ b/pysollib/options.py @@ -223,6 +223,7 @@ scale_cards = boolean scale_x = float scale_y = float auto_scale = boolean +preview_scale = boolean spread_stacks = boolean preserve_aspect_ratio = boolean resampling = integer(0, 10) @@ -518,6 +519,7 @@ class Options: self.scale_x = 1.0 self.scale_y = 1.0 self.auto_scale = True + self.preview_scale = True self.spread_stacks = False self.center_layout = True self.preserve_aspect_ratio = True @@ -713,7 +715,7 @@ class Options: else: config['cardsets'][str(key)] = val2 for key in ('scale_cards', 'scale_x', 'scale_y', - 'auto_scale', 'spread_stacks', + 'auto_scale', 'preview_scale', 'spread_stacks', 'preserve_aspect_ratio', 'resampling'): config['cardsets'][key] = getattr(self, key) @@ -898,6 +900,7 @@ class Options: ('scale_x', 'float'), ('scale_y', 'float'), ('auto_scale', 'bool'), + ('preview_scale', 'bool'), ('spread_stacks', 'bool'), ('preserve_aspect_ratio', 'bool'), ('resampling', 'int')): diff --git a/pysollib/stack.py b/pysollib/stack.py index f15efb0e..1307e8b9 100644 --- a/pysollib/stack.py +++ b/pysollib/stack.py @@ -904,14 +904,15 @@ class Stack: if self.images.redeal: move(self.images.redeal) # texts - if self.texts.ncards: - move(self.texts.ncards) - if self.texts.rounds: - move(self.texts.rounds) - if self.texts.redeal: - move(self.texts.redeal) - if self.texts.misc: - move(self.texts.misc) + if not self.game.preview: + if self.texts.ncards: + move(self.texts.ncards) + if self.texts.rounds: + move(self.texts.rounds) + if self.texts.redeal: + move(self.texts.redeal) + if self.texts.misc: + move(self.texts.misc) def basicShallHighlightSameRank(self, card): # by default all open stacks are available for highlighting diff --git a/pysollib/tile/selectcardset.py b/pysollib/tile/selectcardset.py index 125c8261..1ad35034 100644 --- a/pysollib/tile/selectcardset.py +++ b/pysollib/tile/selectcardset.py @@ -358,6 +358,16 @@ class SelectCardsetDialogWithPreview(MfxDialog): check.grid(row=5, column=0, columnspan=2, sticky='ew', padx=padx, pady=pady) # + self.preview_scale = tkinter.BooleanVar() + self.preview_scale.set(app.opt.preview_scale) + self.preview_check = ttk.Checkbutton( + size_frame, text=_('Preview scaling'), + variable=self.preview_scale, + command=self._updateAutoScale + ) + self.preview_check.grid(row=6, column=0, sticky='ew', + padx=padx, pady=pady) + # self.preserve_aspect = tkinter.BooleanVar() self.preserve_aspect.set(app.opt.preserve_aspect_ratio) self.aspect_check = ttk.Checkbutton( @@ -365,7 +375,7 @@ class SelectCardsetDialogWithPreview(MfxDialog): variable=self.preserve_aspect, # command=self._updateScale ) - self.aspect_check.grid(row=6, column=0, sticky='ew', + self.aspect_check.grid(row=7, column=0, sticky='ew', padx=padx, pady=pady) self._updateAutoScale() @@ -376,6 +386,8 @@ class SelectCardsetDialogWithPreview(MfxDialog): left_frame.columnconfigure(0, weight=1) # self.preview = MfxScrolledCanvas(right_frame) + bind(self.preview.parent, '', + lambda e: self._configureHandler()) self.preview.setTile(app, app.tabletile_index, app.opt.tabletile_scale_method, force=True) self.preview.pack(fill='both', expand=True, padx=padx, pady=pady) @@ -384,7 +396,7 @@ class SelectCardsetDialogWithPreview(MfxDialog): self.preview_key = -1 self.preview_images = [] self.scale_images = [] - self.updatePreview(key) + self.updatePreview(key, overrideScale=True) # focus = self.createButtons(bottom_frame, kw) focus = self.tree.frame @@ -472,13 +484,17 @@ class SelectCardsetDialogWithPreview(MfxDialog): def _updateAutoScale(self, v=None): if self.auto_scale.get(): + self.preview_check.config(state='normal') self.aspect_check.config(state='normal') self.scale_x.state('disabled') self.scale_y.state('disabled') else: + self.preview_check.config(state='disabled') self.aspect_check.config(state='disabled') self.scale_x.state('!disabled') self.scale_y.state('!disabled') + if hasattr(self, 'preview_key'): + self.updatePreview() def _updateScale(self, v): self.updatePreview() @@ -578,7 +594,27 @@ class SelectCardsetDialogWithPreview(MfxDialog): self.updatePreview(cardset) self.list["cursor"] = oldcur - def updatePreview(self, key=None): + _resizeHandlerID = None + + def _resizeHandler(self): + self._resizeHandlerID = None + self.updatePreview() + + def _configureHandler(self, event=None): + if False: # if not USE_PIL: + return + if not self.app: + return + if (not self.app.opt.auto_scale and + not self.app.opt.preview_scale): + return + if self._resizeHandlerID: + self.preview.canvas.after_cancel(self._resizeHandlerID) + self._resizeHandlerID = self.preview.canvas.after(300, + self._resizeHandler) + # should return EVENT_HANDLED or EVENT_PROPAGATE explicitly. + + def updatePreview(self, key=None, overrideScale=False): if key == self.preview_key: return if key is None: @@ -611,8 +647,19 @@ class SelectCardsetDialogWithPreview(MfxDialog): return i, x, y, sx, sy, dx, dy = 0, 10, 10, 0, 0, cs.CARDW + 10, cs.CARDH + 10 if USE_PIL: - xf = self.scale_x.get() - yf = self.scale_y.get() + if (self.auto_scale.get() and self.preview_scale.get() + and not overrideScale): + vw = canvas.winfo_width() + vh = canvas.winfo_height() + iw = dx * 4 + ih = dy * 4 + xf = max(float(vw - 10) / iw, .01) + yf = max(float(vh - 10) / ih, .01) + if self.preserve_aspect.get(): + xf = yf = min(xf, yf) + else: + xf = self.scale_x.get() + yf = self.scale_y.get() dx = int(dx*xf) dy = int(dy*yf) self.scale_images = [] diff --git a/pysollib/tile/selectgame.py b/pysollib/tile/selectgame.py index a3a78c57..7f3997d0 100644 --- a/pysollib/tile/selectgame.py +++ b/pysollib/tile/selectgame.py @@ -478,6 +478,8 @@ class SelectGameDialogWithPreview(SelectGameDialog): stats_frame.rowconfigure(6, weight=1) # Canvas self.preview = MfxScrolledCanvas(right_frame) + bind(self.preview.parent, '', + lambda e: self._configureHandler()) self.preview.setTile(app, app.tabletile_index, app.opt.tabletile_scale_method, force=True) self.preview.grid(row=1, column=0, columnspan=3, @@ -723,6 +725,27 @@ class SelectGameDialogWithPreview(SelectGameDialog): self.updatePreview(game) self.list["cursor"] = oldcur + _resizeHandlerID = None + + def _resizeHandler(self): + self._resizeHandlerID = None + self.preview.canvas.config(scrollregion=(0, 0, 0, 0)) + self.preview_game.resizeGame() + + def _configureHandler(self, event=None): + if False: # if not USE_PIL: + return + if not self.app: + return + if (not self.app.opt.auto_scale and + not self.app.opt.preview_scale): + return + if self._resizeHandlerID: + self.preview.canvas.after_cancel(self._resizeHandlerID) + self._resizeHandlerID = self.preview.canvas.after(300, + self._resizeHandler) + # should return EVENT_HANDLED or EVENT_PROPAGATE explicitly. + def updatePreview(self, gameid, animations=10): if gameid == self.preview_key: return @@ -777,9 +800,17 @@ class SelectGameDialogWithPreview(SelectGameDialog): if c: c2 = c.get(cardset.subtype) if c2: - self.preview_app.images = c2[2] + if self.app.opt.auto_scale and self.app.opt.preview_scale: + self.preview_app.images = c2[1] + else: + self.preview_app.images = c2[2] else: - self.preview_app.images = self.app.subsampled_images + if self.app.opt.auto_scale and self.app.opt.preview_scale: + self.preview_app.images = self.app.images + else: + self.preview_app.images = self.app.subsampled_images + if self.app.opt.auto_scale and self.app.opt.preview_scale: + self.preview_app.images.setNegative(self.app.opt.negative_bottom) self.preview_app.audio = None # turn off audio for initial dealing if animations >= 0: @@ -803,10 +834,14 @@ class SelectGameDialogWithPreview(SelectGameDialog): self.preview_game.restoreGameFromBookmark(self.bookmark) else: self.preview_game.newGame(random=random, autoplay=1) - gw, gh = self.preview_game.width, self.preview_game.height - canvas.config(scrollregion=(0, 0, gw, gh)) - canvas.xview_moveto(0) - canvas.yview_moveto(0) + if (not self.app.opt.auto_scale and + not self.app.opt.preview_scale): + gw, gh = self.preview_game.width, self.preview_game.height + canvas.config(scrollregion=(0, 0, gw, gh)) + canvas.xview_moveto(0) + canvas.yview_moveto(0) + else: + canvas.config(scrollregion=(0, 0, 0, 0)) # self.preview_app.audio = self.app.audio if self.app.opt.animations: diff --git a/pysollib/ui/tktile/menubar.py b/pysollib/ui/tktile/menubar.py index 402b4a6e..0c87100d 100644 --- a/pysollib/ui/tktile/menubar.py +++ b/pysollib/ui/tktile/menubar.py @@ -315,6 +315,7 @@ class PysolMenubarTkCommon: pegged_auto_remove=tkinter.BooleanVar(), sound=tkinter.BooleanVar(), auto_scale=tkinter.BooleanVar(), + preview_scale=tkinter.BooleanVar(), preserve_aspect_ratio=tkinter.BooleanVar(), resampling=tkinter.IntVar(), spread_stacks=tkinter.BooleanVar(), @@ -391,6 +392,7 @@ class PysolMenubarTkCommon: tkopt.pegged_auto_remove.set(opt.pegged_auto_remove) tkopt.sound.set(opt.sound) tkopt.auto_scale.set(opt.auto_scale) + tkopt.preview_scale.set(opt.preview_scale) tkopt.preserve_aspect_ratio.set(opt.preserve_aspect_ratio) tkopt.resampling.set(opt.resampling) tkopt.spread_stacks.set(opt.spread_stacks) @@ -760,7 +762,11 @@ class PysolMenubarTkCommon: label=n_("&Auto scaling"), variable=self.tkopt.auto_scale, command=self.mOptAutoScale, accelerator=m+'0') submenu.add_checkbutton( - label=n_("&Preserve aspect ratio"), + label=n_("&Preview scaling"), + variable=self.tkopt.preview_scale, + command=self.mOptPreviewScale) + submenu.add_checkbutton( + label=n_("Pr&eserve aspect ratio"), variable=self.tkopt.preserve_aspect_ratio, command=self.mOptPreserveAspectRatio) submenu.add_separator() @@ -1256,7 +1262,6 @@ class PysolMenubarTkCommon: def _mSelectGameDialog(self, d): if self.game.pause: if self.wasPaused: - self.game.resizeGame() self.game.doPause() if d.status == 0 and d.button == 0 and d.gameid != self.game.id: self.tkopt.gameid.set(d.gameid) @@ -1862,6 +1867,14 @@ Unsupported game for import. self.tkopt.auto_scale.set(auto_scale) self._updateCardSize() + def mOptPreviewScale(self, *event): + if self._cancelDrag(break_pause=True): + return + preview_scale = not self.app.opt.preview_scale + + self.app.opt.preview_scale = preview_scale + self.tkopt.preview_scale.set(preview_scale) + def mOptPreserveAspectRatio(self, *event): if self._cancelDrag(break_pause=True): return