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

Allow to swap the mouse keys using the ini file.

See: https://sourceforge.net/p/pysolfc/discussion/503708/thread/5d77434ff8/

" PySolFC / Discussion / Open Discussion: Any way to remap mouse buttons? "

We may not have covered all the affected calls to bind().
This commit is contained in:
Shlomi Fish 2020-10-13 17:18:36 +03:00
parent 934db8da3b
commit 7da41a93be
11 changed files with 159 additions and 36 deletions

View file

@ -671,12 +671,19 @@ class Game(object):
print_err('max_rounds <= 1, but talon.texts.rounds is not None: '
'%s' % class_name, 2)
def _calcMouseBind(self, binding_format):
"""docstring for _calcMouseBind"""
return self.app.opt.calcCustomMouseButtonsBinding(binding_format)
def initBindings(self):
# note: a Game is only allowed to bind self.canvas and not to self.top
# bind(self.canvas, "<Double-1>", self.undoHandler)
bind(self.canvas, "<1>", self.undoHandler)
bind(self.canvas, "<2>", self.dropHandler)
bind(self.canvas, "<3>", self.redoHandler)
bind(self.canvas,
self._calcMouseBind("<{mouse_button1}>"), self.undoHandler)
bind(self.canvas,
self._calcMouseBind("<{mouse_button2}>"), self.dropHandler)
bind(self.canvas,
self._calcMouseBind("<{mouse_button3}>"), self.redoHandler)
bind(self.canvas, '<Unmap>', self._unmapHandler)
bind(self.canvas, '<Configure>', self._configureHandler, add=True)

View file

@ -222,6 +222,9 @@ class Mahjongg_RowStack(OpenStack):
for s in self.game.s.rows[self.id+1:]:
s.group.tkraise()
def _calcMouseBind(self, binding_format):
return self.game.app.opt.calcCustomMouseButtonsBinding(binding_format)
# In Mahjongg games type there are a lot of stacks, so we optimize
# and don't create bindings that are not used anyway.
def initBindings(self):
@ -231,9 +234,21 @@ class Mahjongg_RowStack(OpenStack):
# bind(group, "<3>", self._Stack__controlclickEventHandler)
# bind(group, "<Control-1>", self._Stack__controlclickEventHandler)
#
bind(group, "<1>", self.__clickEventHandler)
bind(group, "<3>", self.__controlclickEventHandler)
bind(group, "<Control-1>", self.__controlclickEventHandler)
bind(
group,
self._calcMouseBind("<{mouse_button1}>"),
self.__clickEventHandler
)
bind(
group,
self._calcMouseBind("<{mouse_button3}>"),
self.__controlclickEventHandler
)
bind(
group,
self._calcMouseBind("<Control-{mouse_button1}>"),
self.__controlclickEventHandler
)
# bind(group, "<Enter>", self._Stack__enterEventHandler)
# bind(group, "<Leave>", self._Stack__leaveEventHandler)

View file

@ -60,9 +60,20 @@ class Matrix_RowStack(OpenStack):
# the tile (from Tk's stacking view)
return len(self.cards) - 1
def _calcMouseBind(self, binding_format):
return self.game.app.opt.calcCustomMouseButtonsBinding(binding_format)
def initBindings(self):
bind(self.group, "<1>", self._Stack__clickEventHandler)
bind(self.group, "<Control-1>", self._Stack__controlclickEventHandler)
bind(
self.group,
self._calcMouseBind("<{mouse_button1}>"),
self._Stack__clickEventHandler
)
bind(
self.group,
self._calcMouseBind("<Control-{mouse_button1}>"),
self._Stack__controlclickEventHandler,
)
def getBottomImage(self):
return self.game.app.images.getBlankBottom()

View file

@ -43,6 +43,17 @@ import validate
# * Options
# ************************************************************************
_global_settings = {}
def calcCustomMouseButtonsBinding(binding_format):
assert _global_settings['mouse_button1']
return binding_format.format(
mouse_button1=_global_settings['mouse_button1'],
mouse_button2=_global_settings['mouse_button2'],
mouse_button3=_global_settings['mouse_button3'],
)
configspec = '''
[general]
@ -253,6 +264,9 @@ class Options:
('solver_max_iterations', 'int'),
('solver_iterations_output_step', 'int'),
('solver_preset', 'string'),
('mouse_button1', 'int'),
('mouse_button2', 'int'),
('mouse_button3', 'int'),
# ('toolbar_vars', 'list'),
# ('recent_gameid', 'list'),
# ('favorite_gameid', 'list'),
@ -320,6 +334,9 @@ class Options:
self.num_cards = False
self.helpbar = False
self.splashscreen = True
self.mouse_button1 = 1
self.mouse_button2 = 2
self.mouse_button3 = 3
self.mouse_type = 'drag-n-drop' # or 'sticky-mouse' or 'point-n-click'
self.mouse_undo = False # use mouse for undo/redo
self.negative_bottom = True
@ -751,3 +768,20 @@ class Options:
self.offsets[key] = val
except Exception:
traceback.print_exc()
# mouse buttons swap
def _positive(button):
return max([button, 1])
_global_settings['mouse_button1'] = _positive(self.mouse_button1)
_global_settings['mouse_button2'] = _positive(self.mouse_button2)
_global_settings['mouse_button3'] = _positive(self.mouse_button3)
def calcCustomMouseButtonsBinding(self, binding_format):
"""docstring for calcCustomMouseButtonsBinding"""
def _positive(button):
return max([button, 1])
return binding_format.format(
mouse_button1=_positive(self.mouse_button1),
mouse_button2=_positive(self.mouse_button2),
mouse_button3=_positive(self.mouse_button3),
)

View file

@ -269,22 +269,35 @@ class Stack:
if self.is_visible:
self.initBindings()
def _calcMouseBind(self, binding_format):
return self.game.app.opt.calcCustomMouseButtonsBinding(binding_format)
# bindings {view widgets bind to controller}
def initBindings(self):
group = self.group
bind(group, "<1>", self.__clickEventHandler)
bind(group, self._calcMouseBind("<{mouse_button1}>"),
self.__clickEventHandler)
# bind(group, "<B1-Motion>", self.__motionEventHandler)
bind(group, "<Motion>", self.__motionEventHandler)
bind(group, "<ButtonRelease-1>", self.__releaseEventHandler)
bind(group, "<Control-1>", self.__controlclickEventHandler)
bind(group, "<Shift-1>", self.__shiftclickEventHandler)
bind(group, "<Double-1>", self.__doubleclickEventHandler)
bind(group, "<3>", self.__rightclickEventHandler)
bind(group, "<2>", self.__middleclickEventHandler)
bind(group, "<Control-3>", self.__middleclickEventHandler)
# bind(group, "<Control-2>", self.__controlmiddleclickEventHandler)
# bind(group, "<Shift-3>", self.__shiftrightclickEventHandler)
# bind(group, "<Double-2>", "")
bind(group, self._calcMouseBind("<ButtonRelease-{mouse_button1}>"),
self.__releaseEventHandler)
bind(group, self._calcMouseBind("<Control-{mouse_button1}>"),
self.__controlclickEventHandler)
bind(group, self._calcMouseBind("<Shift-{mouse_button1}>"),
self.__shiftclickEventHandler)
bind(group, self._calcMouseBind("<Double-{mouse_button1}>"),
self.__doubleclickEventHandler)
bind(group, self._calcMouseBind("<{mouse_button3}>"),
self.__rightclickEventHandler)
bind(group, self._calcMouseBind("<{mouse_button2}>"),
self.__middleclickEventHandler)
bind(group, self._calcMouseBind("<Control-{mouse_button3}>"),
self.__middleclickEventHandler)
# bind(group, self._calcMouseBind(
# "<Control-{mouse_button2}>"), self.__controlmiddleclickEventHandler)
# bind(group, self._calcMouseBind("<Shift-{mouse_button3}>"),
# self.__shiftrightclickEventHandler)
# bind(group, self._calcMouseBind("<Double-{mouse_button2}>"), "")
bind(group, "<Enter>", self.__enterEventHandler)
bind(group, "<Leave>", self.__leaveEventHandler)

View file

@ -244,9 +244,20 @@ class MfxTreeInCanvas(MfxScrolledCanvas):
# 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)
from pysollib.options import calcCustomMouseButtonsBinding
bind(
self.canvas,
calcCustomMouseButtonsBinding("<ButtonPress-{mouse_button1}>"),
self.singleClick
)
bind(
self.canvas,
calcCustomMouseButtonsBinding("<Double-Button-{mouse_button1}>"),
self.doubleClick
)
# bind(self.canvas,
# calcCustomMouseButtonsBinding(
# "<ButtonRelease-{mouse_button1}>"), xxx)
self.pack(fill='both', expand=True)
def destroy(self):

View file

@ -320,7 +320,11 @@ class PysolAboutDialog(MfxMessageDialog):
url_label = ttk.Label(frame, text=kw.url, font=font,
foreground='blue', cursor='hand2')
url_label.pack()
url_label.bind('<1>', self._urlClicked)
from pysollib.options import calcCustomMouseButtonsBinding
url_label.bind(
calcCustomMouseButtonsBinding('<{mouse_button1}>'),
self._urlClicked
)
#
focus = self.createButtons(bottom_frame, kw)
self.mainloop(focus, kw.timeout)

View file

@ -158,6 +158,7 @@ class PysolToolbarTk:
def __init__(self, top, menubar, dir,
size=0, relief='flat', compound='none'):
from pysollib.options import calcCustomMouseButtonsBinding
self.top = top
self.menubar = menubar
self.side = -1
@ -192,7 +193,10 @@ class PysolToolbarTk:
):
if label is None:
sep = self._createSeparator()
sep.bind("<3>", self.rightclickHandler)
sep.bind(
calcCustomMouseButtonsBinding("<{mouse_button3}>"),
self.rightclickHandler
)
elif label == 'Pause':
self._createButton(label, f, check=True, tooltip=t)
else:
@ -209,8 +213,14 @@ class PysolToolbarTk:
self._createLabel("player", label=n_('Player'),
tooltip=_("Player options"))
#
self.player_label.bind("<1>", self.mOptPlayerOptions)
self.frame.bind("<3>", self.rightclickHandler)
self.player_label.bind(
calcCustomMouseButtonsBinding("<{mouse_button1}>"),
self.mOptPlayerOptions
)
self.frame.bind(
calcCustomMouseButtonsBinding("<{mouse_button3}>"),
self.rightclickHandler
)
#
self.setCompound(compound, force=True)

View file

@ -487,7 +487,12 @@ class AllGames_StatsDialog(MfxDialog):
self.nodes = {}
self.canvas = self.sc.canvas
self.canvas.dialog = self
bind(self.canvas, "<1>", self.singleClick)
from pysollib.options import calcCustomMouseButtonsBinding
bind(
self.canvas,
calcCustomMouseButtonsBinding("<{mouse_button1}>"),
self.singleClick
)
self.fillCanvas(player, title)
bbox = self.canvas.bbox("all")
# print bbox

View file

@ -171,7 +171,17 @@ class PysolToolbarTk:
#
self.frame = tkinter.Frame(top, relief=TkSettings.toolbar_relief,
bd=TkSettings.toolbar_borderwidth)
#
from pysollib.options import calcCustomMouseButtonsBinding
def _bind2sep(sep):
sep.bind(
calcCustomMouseButtonsBinding("<{mouse_button1}>"),
self.clickHandler)
sep.bind(
calcCustomMouseButtonsBinding("<{mouse_button3}>"),
self.rightclickHandler)
for label, f, t in (
(n_("New"), self.mNewGame, _("New game")),
(n_("Restart"), self.mRestart, _("Restart the\ncurrent game")),
@ -192,8 +202,7 @@ class PysolToolbarTk:
):
if label is None:
sep = self._createSeparator()
sep.bind("<1>", self.clickHandler)
sep.bind("<3>", self.rightclickHandler)
_bind2sep(sep)
elif label == 'Pause':
self._createButton(label, f, check=True, tooltip=t)
else:
@ -201,17 +210,17 @@ class PysolToolbarTk:
self.pause_button.config(variable=menubar.tkopt.pause)
sep = self._createFlatSeparator()
sep.bind("<1>", self.clickHandler)
sep.bind("<3>", self.rightclickHandler)
_bind2sep(sep)
self._createLabel("player", label=n_('Player'),
tooltip=_("Player options"))
#
self.player_label.bind("<1>", self.mOptPlayerOptions)
self.player_label.bind(
calcCustomMouseButtonsBinding("<{mouse_button1}>"),
self.mOptPlayerOptions)
# self.player_label.bind("<3>",self.mOptPlayerOptions)
self.popup = MfxMenu(master=None, label=n_('Toolbar'), tearoff=0)
createToolbarMenu(menubar, self.popup)
self.frame.bind("<1>", self.clickHandler)
self.frame.bind("<3>", self.rightclickHandler)
_bind2sep(self.frame)
#
self.setCompound(compound, force=True)

View file

@ -104,7 +104,11 @@ class tkHTMLWriter(formatter.NullWriter):
url = self.anchor[0]
tag = "href_" + url
self.text.tag_add(tag, self.anchor_mark, "insert")
self.text.tag_bind(tag, "<1>", self.createCallback(url))
from pysollib.options import calcCustomMouseButtonsBinding
self.text.tag_bind(
tag,
calcCustomMouseButtonsBinding("<{mouse_button1}>"),
self.createCallback(url))
self.text.tag_bind(
tag, "<Enter>", lambda e: self.anchor_enter(url))
self.text.tag_bind(tag, "<Leave>", self.anchor_leave)