1
0
Fork 0
mirror of https://github.com/shlomif/PySolFC.git synced 2025-04-05 00:02:29 -04:00

Compare commits

...

9 commits

Author SHA1 Message Date
lufebe16
0135e386c2 Android/Kivy:
- Event handling: Pass through for empty stacks.
- Menu entry to reset zoom.
2024-11-12 10:47:35 +01:00
lufebe16
70909f6469 Android/Kivy:
- zoom settings persistence
- event mapping
2024-11-11 11:35:47 +01:00
Joe R
673cb847bc Expose drag cursor option 2024-11-10 18:27:57 -05:00
Joe R
91b1ba9be9 Disallow moving cards from the foundation in Arachnida 2024-11-10 12:20:37 -05:00
lufebe16
2bfc6bdd3d Android/Kivy version
- Zoom: bug fixes and refactoring
2024-11-09 13:50:49 +01:00
Joe R
552585f143 Catch error when a cardset image fails to load 2024-11-08 21:26:23 -05:00
lufebe16
880fb11979 Android version
- Added two finger zoom to main widget.
2024-11-07 09:39:16 +01:00
Joe R
934d82b5f4 Some format cleanup of How to Use help file 2024-11-06 21:52:53 -05:00
Joe R
87a33b72b1 Set full picture and find card dialogs to be always on top 2024-11-06 20:50:15 -05:00
28 changed files with 329 additions and 69 deletions

View file

@ -7,6 +7,14 @@ export GRADLE_OPTS="-Xms1724m -Xmx5048m -Dorg.gradle.jvmargs='-Xms1724m -Xmx5048
echo '### run buildozer'
if [ "$1" == "test" ]
then
echo '### ... release.test'
buildozer --profile test android release
exit 0
fi
if [ "$1" ]
then
echo '### ... release'

View file

@ -441,3 +441,7 @@ warn_on_root = 1
# Then, invoke the command line with the "demo" profile:
#
#buildozer --profile demo android debug
[app@test]
title = PySolFC.test
package.name = pysolfc.test

View file

@ -42,38 +42,18 @@ You can also reach '<i>R</i>' (redo) from there.
Left-handed people may prefer using '<i>L</i>' (auto drop),
'<i>K</i>' (undo) and '<i>J</i>' (deal).
<!--
<h2>Point-and-Click play</h2>
<p>
If you prefer Point-and-Click over Drag-and-Drop you can enable
<i>Quick play</i> and use the right mouse button. See below.
-->
<h2>Automatic play</h2>
<p>
Note that automatic play can spoil the gameplay, so purists should
not enable any option but maybe <i>Auto face up</i>. Also, some games
disable certain features as they would be trivial otherwise.
<p>
Auto face up
<ul type="disc">
<li> Automatically face up all cards.
<li> <i>Auto face up</i> - Automatically face up all cards.
<li> <i>Auto drop</i> - Automatically drop cards to the Foundations.
<li> <i>Auto deal</i> - Automatically deal cards to the Waste stack if it is empty.
<li> <i>Quick play</i> - Use the right mouse button to move piles around quickly.
The logic involved is not too clever on purpose (i.e. it does not consult the hint system).
</ul>
Auto drop
<ul type="disc">
<li> Automatically drop cards to the Foundations.
</ul>
Auto deal
<ul type="disc">
<li> Automatically deal cards to the Waste stack if it is empty.
</ul>
Quick play
<ul type="disc">
<li> Use the right mouse button to move piles around quickly.
The logic involved is not too clever on purpose
(i.e. it does not consult the hint system).
</ul>
<h2>The animation is too slow...</h2>
<p>

View file

@ -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: 2024-10-29 20:05-0400\n"
"PO-Revision-Date: 2024-11-10 18:26-0500\n"
"Last-Translator: H. Schaekel <Holger.Schaekel@web.de>\n"
"Language-Team: German\n"
"Language: de\n"
@ -5452,6 +5452,9 @@ msgstr ""
msgid "&Sticky mouse"
msgstr ""
msgid "D&rag cards cursor"
msgstr ""
#: pysollib/ui/tktile/menubar.py:610
msgid "Use mouse for undo/redo"
msgstr ""

View file

@ -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: 2024-10-29 20:06-0400\n"
"PO-Revision-Date: 2024-11-10 18:25-0500\n"
"Last-Translator: Eric Rausch <neelix570@gmail.com>\n"
"Language-Team: French\n"
"Language: fr\n"
@ -5498,6 +5498,9 @@ msgstr "&Pointer/Cliquer"
msgid "&Sticky mouse"
msgstr "&Sélection"
msgid "D&rag cards cursor"
msgstr ""
#: pysollib/ui/tktile/menubar.py:610
msgid "Use mouse for undo/redo"
msgstr "Souris pour annuler/répéter"

View file

@ -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: 2024-10-29 20:06-0400\n"
"PO-Revision-Date: 2024-11-10 18:25-0500\n"
"Last-Translator: Giuliano Colla <giuliano.colla@gmail.com>\n"
"Language-Team: Italiano <it@li.org>\n"
"Language: it\n"
@ -5563,6 +5563,9 @@ msgstr "&Punta e clicca"
msgid "&Sticky mouse"
msgstr "Mouse &appiccicoso"
msgid "D&rag cards cursor"
msgstr ""
#: pysollib/ui/tktile/menubar.py:610
msgid "Use mouse for undo/redo"
msgstr "Usa il mouse per annulla/ripristina"

View file

@ -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: 2024-10-29 20:06-0400\n"
"PO-Revision-Date: 2024-11-10 18:25-0500\n"
"Last-Translator: Jerzy Trzeciak <artusek@wp.pl>\n"
"Language-Team: Polish <pl@li.org>\n"
"Language: pl\n"
@ -5514,6 +5514,9 @@ msgstr "Wskaż i kliknij"
msgid "&Sticky mouse"
msgstr "Lepka my&sz"
msgid "D&rag cards cursor"
msgstr ""
#: pysollib/ui/tktile/menubar.py:610
msgid "Use mouse for undo/redo"
msgstr "Użyj myszy do cofania/powtarzania"

View file

@ -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: 2024-10-29 20:07-0400\n"
"PO-Revision-Date: 2024-11-10 18:26-0500\n"
"Last-Translator: Matheus Knack <mtknack555@gmail.com>\n"
"Language-Team: \n"
"Language: pt_BR\n"
@ -5520,6 +5520,9 @@ msgstr "&Aponar-e-Clicar"
msgid "&Sticky mouse"
msgstr "&Seleção"
msgid "D&rag cards cursor"
msgstr ""
#: pysollib/ui/tktile/menubar.py:610
msgid "Use mouse for undo/redo"
msgstr "Use mouse para desfazer/refazer"

View file

@ -5246,6 +5246,9 @@ msgstr ""
msgid "&Sticky mouse"
msgstr ""
msgid "D&rag cards cursor"
msgstr ""
#: pysollib/ui/tktile/menubar.py:610
msgid "Use mouse for undo/redo"
msgstr ""

View file

@ -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: 2024-10-29 20:07-0400\n"
"PO-Revision-Date: 2024-11-10 18:24-0500\n"
"Last-Translator: Skomoroh <skomoroh@gmail.com>\n"
"Language-Team: Russian <ru@li.org>\n"
"Language: ru\n"
@ -5588,6 +5588,9 @@ msgstr ""
msgid "&Sticky mouse"
msgstr "&Липкая мышь"
msgid "D&rag cards cursor"
msgstr ""
#: pysollib/ui/tktile/menubar.py:610
msgid "Use mouse for undo/redo"
msgstr "Использовать мышь для отмены/повтора"

View file

@ -46,6 +46,8 @@ from pysollib.pysoltk import TimeoutsDialog
from pysollib.pysoltk import create_find_card_dialog
from pysollib.pysoltk import create_full_picture_dialog
from pysollib.pysoltk import create_solver_dialog
from pysollib.pysoltk import raise_find_card_dialog
from pysollib.pysoltk import raise_full_picture_dialog
from pysollib.settings import DEBUG
from pysollib.settings import PACKAGE_URL, TITLE
from pysollib.settings import TOP_SIZE
@ -534,10 +536,12 @@ class PysolMenubar(PysolMenubarTk):
if self.game.canFindCard():
create_find_card_dialog(self.game.top, self.game,
self.app.getFindCardImagesDir())
raise_find_card_dialog()
def mFullPicture(self, *args):
if self.game.canShowFullPicture():
create_full_picture_dialog(self.game.top, self.game)
raise_full_picture_dialog()
def mSolver(self, *args):
create_solver_dialog(self.game.top, self.app)

View file

@ -53,7 +53,10 @@ from pysollib.pysoltk import PysolStatusbar
from pysollib.pysoltk import SelectCardsetDialogWithPreview
from pysollib.pysoltk import SelectDialogTreeData
from pysollib.pysoltk import destroy_find_card_dialog
from pysollib.pysoltk import destroy_full_picture_dialog
from pysollib.pysoltk import loadImage, wm_withdraw
from pysollib.pysoltk import raise_find_card_dialog
from pysollib.pysoltk import raise_full_picture_dialog
from pysollib.resource import CSI, CardsetManager
from pysollib.resource import Music, MusicManager
from pysollib.resource import Sample, SampleManager
@ -277,6 +280,7 @@ class Application:
#
destroy_help_html()
destroy_find_card_dialog()
destroy_full_picture_dialog()
destroy_solver_dialog()
# update options
self.opt.last_gameid = id_
@ -509,6 +513,10 @@ class Application:
def wm_toggle_fullscreen(self):
self.opt.wm_fullscreen = not self.opt.wm_fullscreen
self.top.attributes("-fullscreen", self.opt.wm_fullscreen)
# Topmost dialogs need to be reset when toggling fullscreen.
raise_find_card_dialog()
raise_full_picture_dialog()
self.top.attributes('-topmost', False)
def loadImages1(self):
# load dialog images

View file

@ -1347,6 +1347,7 @@ class Game(object):
# pause game if root window has been iconified
if self.app and not self.pause:
self.app.menubar.mPause()
# should return EVENT_HANDLED or EVENT_PROPAGATE
_resizeHandlerID = None
@ -1370,6 +1371,7 @@ class Game(object):
if self._resizeHandlerID:
self.canvas.after_cancel(self._resizeHandlerID)
self._resizeHandlerID = self.canvas.after(250, self._resizeHandler)
# should return EVENT_HANDLED or EVENT_PROPAGATE explicitly.
def playSample(self, name, priority=0, loop=0):

View file

@ -260,7 +260,7 @@ class Arachnida(CurdsAndWhey):
s.foundations.append(
AbstractFoundationStack(
x, y, self, suit=ANY_SUIT,
max_accept=0, max_cards=104))
max_accept=0, max_move=0, max_cards=104))
l.createText(s.foundations[0], "s")
# define stack-groups

View file

@ -181,6 +181,8 @@ class Images:
# load face cards
for n in self.cs.getFaceCardNames():
self._card.append(self.__loadCard(n + self.cs.ext))
if self._card[-1] is None:
return 0
self._card[-1].filename = n
if progress:
progress.update(step=pstep)

View file

@ -57,6 +57,7 @@ from pysollib.kivy.LBase import LBase
from pysollib.kivy.LTask import LTask, LTaskQ
from pysollib.kivy.androidperms import requestStoragePerm
from pysollib.kivy.androidrot import AndroidScreenRotation
from pysollib.kivy.tkconst import EVENT_HANDLED, EVENT_PROPAGATE
from pysollib.resource import CSI
if platform != 'android':
@ -792,27 +793,48 @@ class LImageItem(BoxLayout, LBase):
def get_image_type(self):
return self.image_type
'''
NOTE:
The following code binds kivy events to tk-like (?) events used
in common code. There are several problems
- EVENT_HANDLED and EVENT_PROPAGATE constants are defined separately in
different ui implementations, but are used in common code (stack.py,
game/__init__.py, many game implementations: (241 functions!))
- EVENT_PROPAGATE is defined to 'None', which is highly unspecific.
(conditions would evaluate to False, empty returns of event function
implicitly return EVENT_PROPAGATE).
- Most events return EVENT_HANDLED even if they did not change anything
in current situations. I would expect specifically for stack base cards
that they return HANDLE_PROPAGATE if nothing happened.
- stack __defaultclickhandler__ returns EVENT_HANDLED in any case so some
code here is obsolete or for future.
- A pragmatic way to handle this: If an empty stack is still empty
after the click then we propagate otherwise not.
LB241111.
'''
def send_event_pressed_n(self, event, n):
r = EVENT_PROPAGATE
if self.group and n in self.group.bindings:
self.group.bindings[n](event)
r = self.group.bindings[n](event)
return r
def send_event_pressed(self, touch, event):
r = EVENT_PROPAGATE
if touch.is_double_tap:
self.send_event_pressed_n(event, '<Double-1>')
r = self.send_event_pressed_n(event, '<Double-1>')
else:
button = 'left'
if 'button' in touch.profile:
button = touch.button
if button == 'left':
self.send_event_pressed_n(event, '<1>')
return
r = self.send_event_pressed_n(event, '<1>')
if button == 'middle':
self.send_event_pressed_n(event, '<2>')
return
r = self.send_event_pressed_n(event, '<2>')
if button == 'right':
self.send_event_pressed_n(event, '<3>')
return
r = self.send_event_pressed_n(event, '<3>')
return r
def on_touch_down(self, touch):
@ -825,9 +847,6 @@ class LImageItem(BoxLayout, LBase):
if stack.cards[i] == self.card:
print('LCardImage: stack = %s' % stack)
print('LCardImage: touch = %s' % str(touch))
print('grab')
# grab the touch!
touch.grab(self)
ppos, psize = self.game.canvas.KivyToCore(
touch.pos, self.size)
event = LEvent()
@ -835,9 +854,13 @@ class LImageItem(BoxLayout, LBase):
event.y = ppos[1]
self.dragstart = touch.pos
event.cardid = i
self.send_event_pressed(touch, event)
r = self.send_event_pressed(touch, event)
if r == EVENT_HANDLED:
AndroidScreenRotation.lock(toaster=False)
print('grab')
touch.grab(self)
return True
return False
if self.group is not None:
print('LCardImage: self=%s group=%s' % (self, self.group))
@ -847,8 +870,11 @@ class LImageItem(BoxLayout, LBase):
event = LEvent()
event.x = ppos[0]
event.y = ppos[1]
self.group.bindings['<1>'](event)
r = self.group.bindings['<1>'](event)
if r == EVENT_HANDLED:
if len(self.group.stack.cards) > 0:
return True
return False
if self.card is None:
return False
@ -859,12 +885,14 @@ class LImageItem(BoxLayout, LBase):
return False
def send_event_released_1(self, event):
r = EVENT_PROPAGATE
if self.group and '<ButtonRelease-1>' in self.group.bindings:
self.group.bindings['<ButtonRelease-1>'](event)
r = self.group.bindings['<ButtonRelease-1>'](event)
return r
def on_touch_up(self, touch):
if touch.grab_current is self:
# release my grabbed touch!
# ungrab. this stops move events after a drag.
print('ungrab')
touch.ungrab(self)
return True
@ -882,8 +910,10 @@ class LImageItem(BoxLayout, LBase):
event.x = ppos[0]
event.y = ppos[1]
event.cardid = i
self.send_event_released_1(event)
r = self.send_event_released_1(event)
if r == EVENT_HANDLED:
return True
return False
if self.group is not None:
print('LCardImage: self=%s group=%s' % (self, self.group))
@ -893,8 +923,11 @@ class LImageItem(BoxLayout, LBase):
event = LEvent()
event.x = ppos[0]
event.y = ppos[1]
self.group.bindings['<ButtonRelease-1>'](event)
r = self.group.bindings['<ButtonRelease-1>'](event)
if r == EVENT_HANDLED:
if len(self.group.stack.cards) > 0:
return True
return False
if self.card is None:
return False

View file

@ -69,6 +69,10 @@ def connect_game_find_card_dialog(game):
'''
def raise_find_card_dialog():
pass
def destroy_find_card_dialog():
pass
'''

View file

@ -108,6 +108,10 @@ def connect_game_full_picture_dialog(game):
'''
def raise_full_picture_dialog():
pass
def destroy_full_picture_dialog():
pass
'''

View file

@ -38,6 +38,7 @@ from pysollib.kivy.LApp import LTopLevel
from pysollib.kivy.LApp import LTreeNode
from pysollib.kivy.LApp import LTreeRoot
from pysollib.kivy.LObjWrap import LBoolWrap
from pysollib.kivy.LObjWrap import LListWrap
from pysollib.kivy.LObjWrap import LNumWrap
from pysollib.kivy.LObjWrap import LStringWrap
from pysollib.kivy.androidrot import AndroidScreenRotation
@ -386,6 +387,9 @@ class EditMenuDialog(LMenuDialog): # Tools
text=_('Shuffle tiles'), command=self.menubar.mShuffle))
tv.add_node(LTreeNode(
text=_('Deal cards'), command=self.menubar.mDeal))
tv.add_node(LTreeNode(
text=_('Reset zoom'),
command=self.auto_close(self.menubar.mResetZoom)))
self.addCheckNode(tv, None,
_('Pause'),
@ -1531,6 +1535,7 @@ class PysolMenubarTk:
language=LStringWrap(opt, "language"),
save_games_geometry=LBoolWrap(opt, "save_games_geometry"),
pause=LBoolWrap(self, "pause"),
table_zoom=LListWrap(opt, "table_zoom"),
# cards
cardset=LNumWrap(self, "cardset"),
cardback=LNumWrap(self, "cardback"),
@ -2139,6 +2144,9 @@ class PysolMenubarTk:
toast.show(parent=baseWindow, duration=5.0)
self.updateMenus()
def mResetZoom(self, *args):
self.tkopt.table_zoom.value = [1.0, 0.0, 0.0]
def mPause(self, *args):
if not self.game:
return

View file

@ -653,6 +653,21 @@ class MfxCanvas(LImage):
self.bind(pos=self.pos_update_widget)
self.bind(size=self.size_update_widget)
def on_touch_down(self,touch):
ret = False
ret = super(MfxCanvas,self).on_touch_down(touch)
return ret
def on_touch_up(self,touch):
ret = False
ret = super(MfxCanvas,self).on_touch_up(touch)
return ret
def on_touch_move(self,touch):
ret = False
ret = super(MfxCanvas,self).on_touch_move(touch)
return ret
def KivyToCoreP(self, pos, size, scale):
cpos = pos
cpos = (cpos[0] - self.pos[0], self.pos[1] +

View file

@ -371,8 +371,139 @@ class MfxTooltip:
# ************************************************************************
# Kivy implementation of MfxScrolledCanvas.
from kivy.uix.scatterlayout import Scatter # noqa
from kivy.uix.stencilview import StencilView # noqa
from kivy.graphics.transformation import Matrix # noqa
class LScrollFrame(BoxLayout):
class LScatterFrame(Scatter):
def __init__(self, inner, **kw):
super(LScatterFrame, self).__init__(**kw)
self.inner = inner
self.add_widget(inner)
self.bind(pos=self._updatepos)
self.bind(size=self._updatesize)
self.do_rotation = False
self.scale_min = 1.0
self.scale_max = 2.2
self.lock_pos = None
self.offset = None
self.tkopt = None
def set_scale(self,zoom):
scale = zoom[0]
self.transform = Matrix().scale(scale,scale,1)
xoff = zoom[1]
yoff = zoom[2]
self.offset = (xoff,yoff)
def _change_command(self,inst,val):
if self.lock_pos is None:
self.set_scale(val)
def _update(self):
# initialisation
if self.tkopt is None:
app = self.inner.wmain.app
tkopt = None
if app is not None: tkopt = app.menubar.tkopt
if tkopt is not None:
self.tkopt = tkopt
self.set_scale(tkopt.table_zoom.value)
print("table_zoom",tkopt.table_zoom.value)
tkopt.table_zoom.bind(value=self._change_command)
# update
if self.lock_pos is None:
self.lock_pos = "locked"
if self.offset is not None:
dx = round(self.offset[0] * (self.bbox[1][0] - self.size[0]))
dy = round(self.offset[1] * (self.bbox[1][1] - self.size[1]))
self.pos = (self.parent.pos[0]-dx,self.parent.pos[1]-dy)
self.lock_pos = None
print("_update",self.pos,self.size)
def _updatesize(self,instance,value):
self.inner.size = self.size
self._update()
def _updatepos(self,instance,value):
self._update()
def collide_point(self,x,y):
px,py = self.parent.pos
sx,sy = self.parent.size
if (px<=x and x<(px+sx) and py<=y and y<(py+sy)):
return True
return False
def on_touch_down(self, touch):
if touch.is_double_tap: return False
x,y = touch.pos
if self.collide_point(x,y):
return super(LScatterFrame, self).on_touch_down(touch)
return False
def on_touch_up(self, touch):
if touch.grab_current == self:
return super(LScatterFrame, self).on_touch_up(touch)
x,y = touch.pos
if self.collide_point(x,y):
return super(LScatterFrame, self).on_touch_up(touch)
return False
def on_touch_move(self, touch):
ret = False
self.lock_pos = "locked"
ret = super(LScatterFrame, self).on_touch_move(touch)
self.lock_pos = None
return ret
def on_transform_with_touch(self,touch):
self.chk_bnd()
def chk_bnd(self):
# Keep the game on the screen.
# limiting parameters:
pos,size = self.bbox
w,h = size
x,y = pos
px,py = self.parent.pos
sx,sy = self.parent.size
# calculate correction matrix and apply
tm = Matrix()
if (x>px):
tm = tm.multiply(Matrix().translate(px-x,0,0))
if (y>py):
tm = tm.multiply(Matrix().translate(0,py-y,0))
if ((x+w) <= (px+sx)):
tm = tm.multiply(Matrix().translate(px+sx-x-w,0,0))
if ((y+h) <= (py+sy)):
tm = tm.multiply(Matrix().translate(0,py+sy-y-h,0))
self.apply_transform(tm)
# save current offset.
self.offset = None
offx = self.parent.pos[0] - self.pos[0]
offy = self.parent.pos[1] - self.pos[1]
offmx = float(self.bbox[1][0] - self.size[0])
offmy = float(self.bbox[1][1] - self.size[1])
if (offmx>0 and offmy>0):
self.offset = (offx/offmx,offy/offmy)
# update persistent zoom parameters
zoom = self.bbox[1][0]/float(self.size[0])
if self.offset is not None:
zoominfo = [zoom, self.offset[0], self.offset[1]]
else:
zoominfo = [zoom, 0.0, 0.0]
self.tkopt.table_zoom.value = zoominfo
class LScrollFrame(BoxLayout,StencilView):
def __init__(self, **kw):
super(LScrollFrame, self).__init__(orientation="vertical", **kw)
@ -501,22 +632,12 @@ class MfxScrolledCanvas(object):
def createCanvas(self, kw):
logging.info('MfxRoot: createCanvas')
# bd = kw['bd']
kw['bd'] = 0
# relief = kw['relief']
del kw['relief']
# frame = Tkinter.Frame(self.frame, bd=bd, relief=relief)
# frame.grid(row=0, column=0, sticky="news")
'''
self.canvas = MfxCanvas(self.frame, **kw)
self.frame.add_widget(self.canvas)
self.parent.pushWork(self.frame)
'''
self.canvas = MfxCanvas(self.parent, **kw)
self.frame = self.canvas
scatter = LScatterFrame(self.canvas)
self.frame.add_widget(scatter)
self.parent.pushWork('playground', self.frame)
''
# self.canvas.pack(expand=True, fill='both')
def createHbar(self):
pass

View file

@ -143,6 +143,7 @@ solver_iterations_output_step = integer
solver_preset = string
display_win_message = boolean
language = string
table_zoom = list
[sound_samples]
move = boolean
@ -322,6 +323,7 @@ class Options:
# ('favorite_gameid', 'list'),
('display_win_message', 'bool'),
('language', 'str'),
# ('table_zoom', 'list'),
]
def __init__(self):
@ -417,6 +419,7 @@ class Options:
self.translate_game_names = True
self.display_win_message = True
self.language = ''
self.table_zoom = [1.0, 0.0, 0.0]
# sound
self.sound = True
self.sound_mode = 1
@ -668,6 +671,7 @@ class Options:
config['general']['recent_gameid'] = self.recent_gameid
config['general']['favorite_gameid'] = self.favorite_gameid
config['general']['table_zoom'] = self.table_zoom
visible_buttons = [b for b in self.toolbar_vars
if self.toolbar_vars[b]]
config['general']['visible_buttons'] = visible_buttons
@ -813,6 +817,13 @@ class Options:
except Exception:
traceback.print_exc()
table_zoom = self._getOption('general', 'table_zoom', 'list')
if table_zoom is not None:
try:
self.table_zoom = [float(i) for i in table_zoom]
except Exception:
traceback.print_exc()
visible_buttons = self._getOption('general', 'visible_buttons', 'list')
if visible_buttons is not None:
for key in TOOLBAR_BUTTONS:

View file

@ -50,5 +50,9 @@ def connect_game_find_card_dialog(game):
pass
def raise_find_card_dialog():
pass
def destroy_find_card_dialog():
pass

View file

@ -50,5 +50,9 @@ def connect_game_full_picture_dialog(game):
pass
def raise_find_card_dialog():
pass
def destroy_full_picture_dialog():
pass

View file

@ -243,6 +243,14 @@ def connect_game_find_card_dialog(game):
pass
def raise_find_card_dialog():
try:
find_card_dialog.tkraise()
find_card_dialog.attributes("-topmost", True)
except Exception:
pass
def destroy_find_card_dialog():
global find_card_dialog
try:

View file

@ -135,6 +135,14 @@ def connect_game_full_picture_dialog(game):
pass
def raise_full_picture_dialog():
try:
full_picture_dialog.tkraise()
full_picture_dialog.attributes("-topmost", True)
except Exception:
pass
def destroy_full_picture_dialog():
global full_picture_dialog
try:

View file

@ -348,6 +348,7 @@ class PysolMenubarTkCommon:
tree_icon_style=tkinter.StringVar(),
mouse_type=tkinter.StringVar(),
mouse_undo=tkinter.BooleanVar(),
mouse_dragcursor=tkinter.BooleanVar(),
negative_bottom=tkinter.BooleanVar(),
pause=tkinter.BooleanVar(),
theme=tkinter.StringVar(),
@ -422,6 +423,7 @@ class PysolMenubarTkCommon:
tkopt.splashscreen.set(opt.splashscreen)
tkopt.mouse_type.set(opt.mouse_type)
tkopt.mouse_undo.set(opt.mouse_undo)
tkopt.mouse_dragcursor.set(opt.dragcursor)
tkopt.negative_bottom.set(opt.negative_bottom)
for w in TOOLBAR_BUTTONS:
tkopt.toolbar_vars[w].set(opt.toolbar_vars.get(w, False))
@ -851,6 +853,10 @@ class PysolMenubarTkCommon:
value='sticky-mouse',
command=self.mOptMouseType)
submenu.add_separator()
submenu.add_checkbutton(
label=n_("D&rag cards cursor"),
variable=self.tkopt.mouse_dragcursor,
command=self.mOptMouseDragCursor)
submenu.add_checkbutton(
label=n_("Use mouse for undo/redo"),
variable=self.tkopt.mouse_undo,
@ -2013,6 +2019,11 @@ Unsupported game for import.
return
self.app.opt.mouse_type = self.tkopt.mouse_type.get()
def mOptMouseDragCursor(self, *event):
if self._cancelDrag(break_pause=False):
return
self.app.opt.dragcursor = self.tkopt.mouse_dragcursor.get()
def mOptMouseUndo(self, *event):
if self._cancelDrag(break_pause=False):
return

View file

@ -6,8 +6,8 @@ use_bzip2 = 1
[flake8]
extend-ignore = H101,H104,H201,H237,H301,H306,H403,H404,H405,
# remove some most ugly flakes (proposal)
# E231,E302,E305,E701,E741,W293
# remove some most ugly flakes:
E211,E225,E231,E302,E305,E701,E741,W293
[sdist]
force_manifest = 1