mirror of
https://github.com/shlomif/PySolFC.git
synced 2025-04-05 00:02:29 -04:00
* improved drag-n-drop marking cards
? some experiments with change cursor if cards can/can't be moved git-svn-id: https://pysolfc.svn.sourceforge.net/svnroot/pysolfc/PySolFC/trunk@123 39dd0a4e-7c14-0410-91b3-c4f2d318f732
This commit is contained in:
parent
fd69d8a0ba
commit
c1d13fc8d1
8 changed files with 76 additions and 44 deletions
|
@ -353,7 +353,8 @@ class AbstractShisenGame(AbstractMahjonggGame):
|
||||||
|
|
||||||
# create other stacks
|
# create other stacks
|
||||||
y = l.YM + dyy
|
y = l.YM + dyy
|
||||||
s.foundations.append(Shisen_Foundation(-l.XS, y, self))
|
s.foundations.append(Shisen_Foundation(-l.XS-self.canvas.xmargin,
|
||||||
|
y, self))
|
||||||
self.texts.info = MfxCanvasText(self.canvas,
|
self.texts.info = MfxCanvasText(self.canvas,
|
||||||
self.width - l.XM - ti_width, y,
|
self.width - l.XM - ti_width, y,
|
||||||
anchor="nw", font=font)
|
anchor="nw", font=font)
|
||||||
|
|
|
@ -51,6 +51,8 @@ EVENT_PROPAGATE = 0
|
||||||
CURSOR_DRAG = gdk.HAND1
|
CURSOR_DRAG = gdk.HAND1
|
||||||
CURSOR_WATCH = gdk.WATCH
|
CURSOR_WATCH = gdk.WATCH
|
||||||
CURSOR_DOWN_ARROW = gdk.SB_DOWN_ARROW
|
CURSOR_DOWN_ARROW = gdk.SB_DOWN_ARROW
|
||||||
|
CURSOR_CAN_MOVE = gdk.HAND2
|
||||||
|
CURSOR_NO_MOVE = gdk.DOT
|
||||||
|
|
||||||
TOOLBAR_BUTTONS = (
|
TOOLBAR_BUTTONS = (
|
||||||
"new",
|
"new",
|
||||||
|
|
|
@ -100,12 +100,14 @@ from util import ACE, KING, SUITS
|
||||||
from util import ANY_SUIT, ANY_COLOR, ANY_RANK, NO_RANK
|
from util import ANY_SUIT, ANY_COLOR, ANY_RANK, NO_RANK
|
||||||
from util import NO_REDEAL, UNLIMITED_REDEALS, VARIABLE_REDEALS
|
from util import NO_REDEAL, UNLIMITED_REDEALS, VARIABLE_REDEALS
|
||||||
from pysoltk import EVENT_HANDLED, EVENT_PROPAGATE
|
from pysoltk import EVENT_HANDLED, EVENT_PROPAGATE
|
||||||
from pysoltk import CURSOR_DRAG, CURSOR_DOWN_ARROW, ANCHOR_NW, ANCHOR_SE
|
from pysoltk import CURSOR_DRAG, CURSOR_DOWN_ARROW, CURSOR_CAN_MOVE, CURSOR_NO_MOVE
|
||||||
|
from pysoltk import ANCHOR_NW, ANCHOR_SE
|
||||||
from pysoltk import bind, unbind_destroy
|
from pysoltk import bind, unbind_destroy
|
||||||
from pysoltk import after, after_idle, after_cancel
|
from pysoltk import after, after_idle, after_cancel
|
||||||
from pysoltk import MfxCanvasGroup, MfxCanvasImage, MfxCanvasRectangle, MfxCanvasText, MfxCanvasLine
|
from pysoltk import MfxCanvasGroup, MfxCanvasImage, MfxCanvasRectangle, MfxCanvasText, MfxCanvasLine
|
||||||
from pysoltk import Card
|
from pysoltk import Card
|
||||||
from pysoltk import get_text_width
|
from pysoltk import get_text_width
|
||||||
|
from pysoltk import markImage
|
||||||
from settings import TOOLKIT
|
from settings import TOOLKIT
|
||||||
from settings import DEBUG
|
from settings import DEBUG
|
||||||
|
|
||||||
|
@ -316,6 +318,7 @@ class Stack:
|
||||||
view.is_open = -1
|
view.is_open = -1
|
||||||
view.can_hide_cards = -1
|
view.can_hide_cards = -1
|
||||||
view.max_shadow_cards = -1
|
view.max_shadow_cards = -1
|
||||||
|
view.current_cursor = ''
|
||||||
view.cursor_changed = False
|
view.cursor_changed = False
|
||||||
|
|
||||||
def destruct(self):
|
def destruct(self):
|
||||||
|
@ -986,6 +989,8 @@ class Stack:
|
||||||
return self.__defaultClickEventHandler(event, self.shiftrightclickHandler)
|
return self.__defaultClickEventHandler(event, self.shiftrightclickHandler)
|
||||||
|
|
||||||
def __motionEventHandler(self, event):
|
def __motionEventHandler(self, event):
|
||||||
|
##if not self.game.drag.stack:
|
||||||
|
## self._setMotionCursor(event)
|
||||||
if not self.game.drag.stack or not self is self.game.drag.stack:
|
if not self.game.drag.stack or not self is self.game.drag.stack:
|
||||||
return EVENT_PROPAGATE
|
return EVENT_PROPAGATE
|
||||||
if self.game.demo:
|
if self.game.demo:
|
||||||
|
@ -1023,6 +1028,7 @@ class Stack:
|
||||||
if self.acceptsCards(self.game.drag.stack,
|
if self.acceptsCards(self.game.drag.stack,
|
||||||
self.game.drag.cards):
|
self.game.drag.cards):
|
||||||
self.game.canvas.config(cursor=CURSOR_DOWN_ARROW)
|
self.game.canvas.config(cursor=CURSOR_DOWN_ARROW)
|
||||||
|
self.current_cursor = CURSOR_DOWN_ARROW
|
||||||
self.cursor_changed = True
|
self.cursor_changed = True
|
||||||
else:
|
else:
|
||||||
after_idle(self.canvas, self.game.showHelp,
|
after_idle(self.canvas, self.game.showHelp,
|
||||||
|
@ -1037,6 +1043,7 @@ class Stack:
|
||||||
return EVENT_HANDLED
|
return EVENT_HANDLED
|
||||||
if self.cursor_changed:
|
if self.cursor_changed:
|
||||||
self.game.canvas.config(cursor='')
|
self.game.canvas.config(cursor='')
|
||||||
|
self.current_cursor = ''
|
||||||
self.cursor_changed = False
|
self.cursor_changed = False
|
||||||
drag_stack = self.game.drag.stack
|
drag_stack = self.game.drag.stack
|
||||||
if self is drag_stack:
|
if self is drag_stack:
|
||||||
|
@ -1283,13 +1290,11 @@ class Stack:
|
||||||
y1 = y1 + self.game.app.images.CARDH
|
y1 = y1 + self.game.app.images.CARDH
|
||||||
xx0, yy0 = x0, y0
|
xx0, yy0 = x0, y0
|
||||||
w, h = x1-x0, y1-y0
|
w, h = x1-x0, y1-y0
|
||||||
m = max(w, h)
|
|
||||||
#
|
#
|
||||||
Image = None
|
Image = None
|
||||||
if TOOLKIT == 'tk':
|
if TOOLKIT == 'tk':
|
||||||
try:
|
try:
|
||||||
import Image, ImageTk
|
import Image, ImageTk
|
||||||
from ImageDraw import ImageDraw
|
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
##Image = None
|
##Image = None
|
||||||
|
@ -1307,43 +1312,33 @@ class Stack:
|
||||||
## drag.shadows.append(l)
|
## drag.shadows.append(l)
|
||||||
return
|
return
|
||||||
#
|
#
|
||||||
mask = Image.new('RGBA', (w, h))
|
shade = Image.new('RGBA', (w, h))
|
||||||
for c in cards:
|
for c in cards:
|
||||||
x, y = self.getPositionFor(c)
|
x, y = self.getPositionFor(c)
|
||||||
x, y = x-xx0, y-yy0
|
x, y = x-xx0, y-yy0
|
||||||
im = c.item._image._pil_image
|
im = c._active_image._pil_image
|
||||||
mask.paste(im, (x, y), im)
|
shade.paste(im, (x, y), im)
|
||||||
#
|
#
|
||||||
shade = Image.new('RGBA', (w, h))
|
shade = markImage(shade)
|
||||||
draw = ImageDraw(shade, 'RGBA')
|
tkshade = ImageTk.PhotoImage(shade)
|
||||||
color = 'black'
|
|
||||||
d = 8
|
|
||||||
## y0, y1 = 0, h
|
|
||||||
## for x0 in range(-m, m, d):
|
|
||||||
## x1 = x0+h
|
|
||||||
## draw.line((x0, y0, x1, y1), fill=color, width=1)
|
|
||||||
## draw.line((x1, y0, x0, y1), fill=color, width=1)
|
|
||||||
for i in xrange(0, m, d):
|
|
||||||
x0, x1 = i, m
|
|
||||||
y0, y1 = 0, m-i
|
|
||||||
draw.line((x0, y0, x1, y1), fill=color, width=1)
|
|
||||||
x0, x1 = 0, m-i
|
|
||||||
y0, y1 = i, m
|
|
||||||
draw.line((x0, y0, x1, y1), fill=color, width=1)
|
|
||||||
x0, x1 = m-i, 0
|
|
||||||
y0, y1 = 0, m-i
|
|
||||||
draw.line((x0, y0, x1, y1), fill=color, width=1)
|
|
||||||
x0, x1 = m, i
|
|
||||||
y0, y1 = i, m
|
|
||||||
draw.line((x0, y0, x1, y1), fill=color, width=1)
|
|
||||||
|
|
||||||
sh2 = Image.composite(shade, mask, mask)
|
|
||||||
tkshade = ImageTk.PhotoImage(sh2)
|
|
||||||
im = MfxCanvasImage(self.game.canvas, xx0, yy0,
|
im = MfxCanvasImage(self.game.canvas, xx0, yy0,
|
||||||
image=tkshade, anchor=ANCHOR_NW,
|
image=tkshade, anchor=ANCHOR_NW,
|
||||||
group=self.group)
|
group=self.group)
|
||||||
drag.shadows.append(im)
|
drag.shadows.append(im)
|
||||||
|
|
||||||
|
def _setMotionCursor(self, event):
|
||||||
|
if not event:
|
||||||
|
return
|
||||||
|
self.cursor_changed = True
|
||||||
|
i = self._findCard(event)
|
||||||
|
if i < 0 or not self.canMoveCards(self.cards[i:]):
|
||||||
|
if self.current_cursor != CURSOR_NO_MOVE:
|
||||||
|
self.game.canvas.config(cursor=CURSOR_NO_MOVE)
|
||||||
|
self.current_cursor = CURSOR_NO_MOVE
|
||||||
|
else:
|
||||||
|
if self.current_cursor != CURSOR_CAN_MOVE:
|
||||||
|
self.game.canvas.config(cursor=CURSOR_CAN_MOVE)
|
||||||
|
self.current_cursor = CURSOR_CAN_MOVE
|
||||||
|
|
||||||
def _stopDrag(self):
|
def _stopDrag(self):
|
||||||
drag = self.game.drag
|
drag = self.game.drag
|
||||||
|
@ -1364,7 +1359,7 @@ class Stack:
|
||||||
# finish a drag operation
|
# finish a drag operation
|
||||||
def finishDrag(self, event=None):
|
def finishDrag(self, event=None):
|
||||||
if self.game.app.opt.dragcursor:
|
if self.game.app.opt.dragcursor:
|
||||||
self.game.canvas.config(cursor=self.game.app.top_cursor)
|
self.game.canvas.config(cursor='')
|
||||||
drag = self.game.drag.copy()
|
drag = self.game.drag.copy()
|
||||||
self._stopDrag()
|
self._stopDrag()
|
||||||
if drag.cards:
|
if drag.cards:
|
||||||
|
@ -1377,7 +1372,7 @@ class Stack:
|
||||||
# cancel a drag operation
|
# cancel a drag operation
|
||||||
def cancelDrag(self, event=None):
|
def cancelDrag(self, event=None):
|
||||||
if self.game.app.opt.dragcursor:
|
if self.game.app.opt.dragcursor:
|
||||||
self.game.canvas.config(cursor=self.game.app.top_cursor)
|
self.game.canvas.config(cursor='')
|
||||||
drag = self.game.drag.copy()
|
drag = self.game.drag.copy()
|
||||||
self._stopDrag()
|
self._stopDrag()
|
||||||
if drag.cards:
|
if drag.cards:
|
||||||
|
|
|
@ -490,8 +490,7 @@ class PysolMenubar(PysolMenubarActions):
|
||||||
menu.add_command(label=n_("&Colors..."), command=self.mOptColors)
|
menu.add_command(label=n_("&Colors..."), command=self.mOptColors)
|
||||||
menu.add_command(label=n_("Time&outs..."), command=self.mOptTimeouts)
|
menu.add_command(label=n_("Time&outs..."), command=self.mOptTimeouts)
|
||||||
menu.add_separator()
|
menu.add_separator()
|
||||||
submenu = MfxMenu(menu, label=n_("Set t&heme"))
|
self.createThemesMenu(menu)
|
||||||
self.createThemesMenu(submenu)
|
|
||||||
submenu = MfxMenu(menu, label=n_("&Toolbar"))
|
submenu = MfxMenu(menu, label=n_("&Toolbar"))
|
||||||
createToolbarMenu(self, submenu)
|
createToolbarMenu(self, submenu)
|
||||||
submenu = MfxMenu(menu, label=n_("Stat&usbar"))
|
submenu = MfxMenu(menu, label=n_("Stat&usbar"))
|
||||||
|
@ -1318,6 +1317,7 @@ the next time you restart """)+PACKAGE,
|
||||||
self.app.opt.tile_theme = theme
|
self.app.opt.tile_theme = theme
|
||||||
|
|
||||||
def createThemesMenu(self, menu):
|
def createThemesMenu(self, menu):
|
||||||
|
submenu = MfxMenu(menu, label=n_("Set t&heme"))
|
||||||
style = Tkinter.Style(self.top)
|
style = Tkinter.Style(self.top)
|
||||||
all_themes = list(style.theme_names())
|
all_themes = list(style.theme_names())
|
||||||
all_themes.sort()
|
all_themes.sort()
|
||||||
|
@ -1335,6 +1335,6 @@ the next time you restart """)+PACKAGE,
|
||||||
n = tn[t]
|
n = tn[t]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
n = t.capitalize()
|
n = t.capitalize()
|
||||||
menu.add_radiobutton(label=n, variable=self.tkopt.theme,
|
submenu.add_radiobutton(label=n, variable=self.tkopt.theme,
|
||||||
value=t, command=self.mOptTheme)
|
value=t, command=self.mOptTheme)
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,8 @@ __all__ = ['tkversion',
|
||||||
'CURSOR_DRAG',
|
'CURSOR_DRAG',
|
||||||
'CURSOR_WATCH',
|
'CURSOR_WATCH',
|
||||||
'CURSOR_DOWN_ARROW',
|
'CURSOR_DOWN_ARROW',
|
||||||
|
'CURSOR_CAN_MOVE',
|
||||||
|
'CURSOR_NO_MOVE',
|
||||||
'ANCHOR_CENTER',
|
'ANCHOR_CENTER',
|
||||||
'ANCHOR_N',
|
'ANCHOR_N',
|
||||||
'ANCHOR_NW',
|
'ANCHOR_NW',
|
||||||
|
@ -87,6 +89,8 @@ EVENT_PROPAGATE = None
|
||||||
CURSOR_DRAG = "hand1"
|
CURSOR_DRAG = "hand1"
|
||||||
CURSOR_WATCH = "watch"
|
CURSOR_WATCH = "watch"
|
||||||
CURSOR_DOWN_ARROW = 'sb_down_arrow'
|
CURSOR_DOWN_ARROW = 'sb_down_arrow'
|
||||||
|
CURSOR_CAN_MOVE = 'hand2'
|
||||||
|
CURSOR_NO_MOVE = 'dot'
|
||||||
|
|
||||||
ANCHOR_CENTER = Tkinter.CENTER
|
ANCHOR_CENTER = Tkinter.CENTER
|
||||||
ANCHOR_N = Tkinter.N
|
ANCHOR_N = Tkinter.N
|
||||||
|
|
|
@ -51,6 +51,7 @@ __all__ = ['wm_withdraw',
|
||||||
#'fillImage',
|
#'fillImage',
|
||||||
'createImage',
|
'createImage',
|
||||||
'shadowImage',
|
'shadowImage',
|
||||||
|
'markImage',
|
||||||
'get_text_width',
|
'get_text_width',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -63,6 +64,7 @@ try:
|
||||||
# PIL
|
# PIL
|
||||||
import Image
|
import Image
|
||||||
import ImageTk
|
import ImageTk
|
||||||
|
import ImageOps
|
||||||
except ImportError:
|
except ImportError:
|
||||||
Image = None
|
Image = None
|
||||||
|
|
||||||
|
@ -355,11 +357,23 @@ def shadowImage(image):
|
||||||
if not hasattr(image, '_pil_image'):
|
if not hasattr(image, '_pil_image'):
|
||||||
return None
|
return None
|
||||||
im = image._pil_image
|
im = image._pil_image
|
||||||
sh = Image.new('RGBA', im.size, 'black')
|
#color, factor = 'black', 0.2
|
||||||
tmp = Image.blend(im, sh, 0.2)
|
color, factor = '#3896f8', 0.3
|
||||||
|
sh = Image.new('RGBA', im.size, color)
|
||||||
|
tmp = Image.blend(im, sh, factor)
|
||||||
out = Image.composite(tmp, im, im)
|
out = Image.composite(tmp, im, im)
|
||||||
return PIL_Image(image=out)
|
return PIL_Image(image=out)
|
||||||
|
|
||||||
|
def markImage(image):
|
||||||
|
assert Image
|
||||||
|
if 1: # shadow
|
||||||
|
color, factor = '#6ae400', 0.3
|
||||||
|
sh = Image.new('RGBA', image.size, color)
|
||||||
|
tmp = Image.blend(image, sh, factor)
|
||||||
|
else: # negate
|
||||||
|
tmp = ImageOps.invert(image.convert('RGB'))
|
||||||
|
out = Image.composite(tmp, image, image)
|
||||||
|
return out
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
# // font utils
|
# // font utils
|
||||||
|
@ -368,5 +382,3 @@ def shadowImage(image):
|
||||||
def get_text_width(text, font, root=None):
|
def get_text_width(text, font, root=None):
|
||||||
return Font(root=root, font=font).measure(text)
|
return Font(root=root, font=font).measure(text)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,8 @@ __all__ = ['tkversion',
|
||||||
'CURSOR_DRAG',
|
'CURSOR_DRAG',
|
||||||
'CURSOR_WATCH',
|
'CURSOR_WATCH',
|
||||||
'CURSOR_DOWN_ARROW',
|
'CURSOR_DOWN_ARROW',
|
||||||
|
'CURSOR_CAN_MOVE',
|
||||||
|
'CURSOR_NO_MOVE',
|
||||||
'ANCHOR_CENTER',
|
'ANCHOR_CENTER',
|
||||||
'ANCHOR_N',
|
'ANCHOR_N',
|
||||||
'ANCHOR_NW',
|
'ANCHOR_NW',
|
||||||
|
@ -85,6 +87,8 @@ EVENT_PROPAGATE = None
|
||||||
CURSOR_DRAG = "hand1"
|
CURSOR_DRAG = "hand1"
|
||||||
CURSOR_WATCH = "watch"
|
CURSOR_WATCH = "watch"
|
||||||
CURSOR_DOWN_ARROW = 'sb_down_arrow'
|
CURSOR_DOWN_ARROW = 'sb_down_arrow'
|
||||||
|
CURSOR_CAN_MOVE = 'hand2'
|
||||||
|
CURSOR_NO_MOVE = 'dot'
|
||||||
|
|
||||||
ANCHOR_CENTER = Tkinter.CENTER
|
ANCHOR_CENTER = Tkinter.CENTER
|
||||||
ANCHOR_N = Tkinter.N
|
ANCHOR_N = Tkinter.N
|
||||||
|
|
|
@ -51,6 +51,7 @@ __all__ = ['wm_withdraw',
|
||||||
#'fillImage',
|
#'fillImage',
|
||||||
'createImage',
|
'createImage',
|
||||||
'shadowImage',
|
'shadowImage',
|
||||||
|
'markImage',
|
||||||
'get_text_width',
|
'get_text_width',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -63,6 +64,7 @@ try:
|
||||||
# PIL
|
# PIL
|
||||||
import Image
|
import Image
|
||||||
import ImageTk
|
import ImageTk
|
||||||
|
import ImageOps
|
||||||
except ImportError:
|
except ImportError:
|
||||||
Image = None
|
Image = None
|
||||||
|
|
||||||
|
@ -355,11 +357,23 @@ def shadowImage(image):
|
||||||
if not hasattr(image, '_pil_image'):
|
if not hasattr(image, '_pil_image'):
|
||||||
return None
|
return None
|
||||||
im = image._pil_image
|
im = image._pil_image
|
||||||
sh = Image.new('RGBA', im.size, 'black')
|
#color, factor = 'black', 0.2
|
||||||
tmp = Image.blend(im, sh, 0.2)
|
color, factor = '#3896f8', 0.3
|
||||||
|
sh = Image.new('RGBA', im.size, color)
|
||||||
|
tmp = Image.blend(im, sh, factor)
|
||||||
out = Image.composite(tmp, im, im)
|
out = Image.composite(tmp, im, im)
|
||||||
return PIL_Image(image=out)
|
return PIL_Image(image=out)
|
||||||
|
|
||||||
|
def markImage(image):
|
||||||
|
assert Image
|
||||||
|
if 1: # shadow
|
||||||
|
color, factor = '#6ae400', 0.3
|
||||||
|
sh = Image.new('RGBA', image.size, color)
|
||||||
|
tmp = Image.blend(image, sh, factor)
|
||||||
|
else: # negate
|
||||||
|
tmp = ImageOps.invert(image.convert('RGB'))
|
||||||
|
out = Image.composite(tmp, image, image)
|
||||||
|
return out
|
||||||
|
|
||||||
# /***********************************************************************
|
# /***********************************************************************
|
||||||
# // font utils
|
# // font utils
|
||||||
|
|
Loading…
Add table
Reference in a new issue