pywargame 0.3.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pywargame/__init__.py +2 -0
- pywargame/common/__init__.py +3 -0
- pywargame/common/collector.py +87 -0
- pywargame/common/dicedraw.py +363 -0
- pywargame/common/drawdice.py +40 -0
- pywargame/common/singleton.py +22 -0
- pywargame/common/test.py +25 -0
- pywargame/common/verbose.py +59 -0
- pywargame/common/verboseguard.py +53 -0
- pywargame/cyberboard/__init__.py +18 -0
- pywargame/cyberboard/archive.py +283 -0
- pywargame/cyberboard/base.py +63 -0
- pywargame/cyberboard/board.py +462 -0
- pywargame/cyberboard/cell.py +200 -0
- pywargame/cyberboard/collect.py +49 -0
- pywargame/cyberboard/collectgbx0pwd.py +30 -0
- pywargame/cyberboard/collectgbxext.py +30 -0
- pywargame/cyberboard/collectgsnexp.py +32 -0
- pywargame/cyberboard/collectgsnext.py +30 -0
- pywargame/cyberboard/draw.py +396 -0
- pywargame/cyberboard/exporter.py +1132 -0
- pywargame/cyberboard/extractor.py +240 -0
- pywargame/cyberboard/features.py +17 -0
- pywargame/cyberboard/gamebox.py +81 -0
- pywargame/cyberboard/gbxexp.py +76 -0
- pywargame/cyberboard/gbxext.py +64 -0
- pywargame/cyberboard/gsnexp.py +147 -0
- pywargame/cyberboard/gsnext.py +59 -0
- pywargame/cyberboard/head.py +111 -0
- pywargame/cyberboard/image.py +76 -0
- pywargame/cyberboard/main.py +47 -0
- pywargame/cyberboard/mark.py +102 -0
- pywargame/cyberboard/palette.py +36 -0
- pywargame/cyberboard/piece.py +169 -0
- pywargame/cyberboard/player.py +36 -0
- pywargame/cyberboard/scenario.py +115 -0
- pywargame/cyberboard/testgrid.py +156 -0
- pywargame/cyberboard/tile.py +121 -0
- pywargame/cyberboard/tray.py +68 -0
- pywargame/cyberboard/windows.py +41 -0
- pywargame/cyberboard/zeropwd.py +45 -0
- pywargame/cyberboard.py +2728 -0
- pywargame/gbx0pwd.py +2776 -0
- pywargame/gbxextract.py +2795 -0
- pywargame/gsnexport.py +16499 -0
- pywargame/gsnextract.py +2790 -0
- pywargame/latex/__init__.py +2 -0
- pywargame/latex/collect.py +34 -0
- pywargame/latex/latexexporter.py +4010 -0
- pywargame/latex/main.py +184 -0
- pywargame/vassal/__init__.py +66 -0
- pywargame/vassal/base.py +139 -0
- pywargame/vassal/board.py +243 -0
- pywargame/vassal/buildfile.py +60 -0
- pywargame/vassal/chart.py +79 -0
- pywargame/vassal/chessclock.py +197 -0
- pywargame/vassal/collect.py +98 -0
- pywargame/vassal/collectpatch.py +28 -0
- pywargame/vassal/command.py +21 -0
- pywargame/vassal/documentation.py +322 -0
- pywargame/vassal/dumpcollect.py +28 -0
- pywargame/vassal/dumpvsav.py +28 -0
- pywargame/vassal/element.py +439 -0
- pywargame/vassal/exporter.py +89 -0
- pywargame/vassal/extension.py +101 -0
- pywargame/vassal/folder.py +103 -0
- pywargame/vassal/game.py +940 -0
- pywargame/vassal/gameelements.py +1091 -0
- pywargame/vassal/globalkey.py +127 -0
- pywargame/vassal/globalproperty.py +433 -0
- pywargame/vassal/grid.py +573 -0
- pywargame/vassal/map.py +1061 -0
- pywargame/vassal/mapelements.py +1020 -0
- pywargame/vassal/merge.py +57 -0
- pywargame/vassal/merger.py +460 -0
- pywargame/vassal/moduledata.py +275 -0
- pywargame/vassal/mrgcollect.py +31 -0
- pywargame/vassal/patch.py +44 -0
- pywargame/vassal/patchcollect.py +28 -0
- pywargame/vassal/player.py +83 -0
- pywargame/vassal/save.py +495 -0
- pywargame/vassal/skel.py +380 -0
- pywargame/vassal/trait.py +224 -0
- pywargame/vassal/traits/__init__.py +36 -0
- pywargame/vassal/traits/area.py +50 -0
- pywargame/vassal/traits/basic.py +35 -0
- pywargame/vassal/traits/calculatedproperty.py +22 -0
- pywargame/vassal/traits/cargo.py +29 -0
- pywargame/vassal/traits/click.py +41 -0
- pywargame/vassal/traits/clone.py +28 -0
- pywargame/vassal/traits/delete.py +24 -0
- pywargame/vassal/traits/deselect.py +32 -0
- pywargame/vassal/traits/dynamicproperty.py +112 -0
- pywargame/vassal/traits/globalcommand.py +55 -0
- pywargame/vassal/traits/globalhotkey.py +26 -0
- pywargame/vassal/traits/globalproperty.py +54 -0
- pywargame/vassal/traits/hide.py +67 -0
- pywargame/vassal/traits/label.py +76 -0
- pywargame/vassal/traits/layer.py +105 -0
- pywargame/vassal/traits/mark.py +20 -0
- pywargame/vassal/traits/mask.py +85 -0
- pywargame/vassal/traits/mat.py +26 -0
- pywargame/vassal/traits/moved.py +35 -0
- pywargame/vassal/traits/movefixed.py +51 -0
- pywargame/vassal/traits/nonrect.py +95 -0
- pywargame/vassal/traits/nostack.py +55 -0
- pywargame/vassal/traits/place.py +104 -0
- pywargame/vassal/traits/prototype.py +20 -0
- pywargame/vassal/traits/report.py +34 -0
- pywargame/vassal/traits/restrictaccess.py +28 -0
- pywargame/vassal/traits/restrictcommand.py +32 -0
- pywargame/vassal/traits/return.py +40 -0
- pywargame/vassal/traits/rotate.py +62 -0
- pywargame/vassal/traits/sendto.py +59 -0
- pywargame/vassal/traits/sheet.py +129 -0
- pywargame/vassal/traits/skel.py +9 -0
- pywargame/vassal/traits/stack.py +28 -0
- pywargame/vassal/traits/submenu.py +27 -0
- pywargame/vassal/traits/trail.py +61 -0
- pywargame/vassal/traits/trigger.py +72 -0
- pywargame/vassal/turn.py +272 -0
- pywargame/vassal/upgrade.py +191 -0
- pywargame/vassal/vmod.py +323 -0
- pywargame/vassal/vsav.py +100 -0
- pywargame/vassal/widget.py +358 -0
- pywargame/vassal/withtraits.py +634 -0
- pywargame/vassal/xml.py +4 -0
- pywargame/vassal/zone.py +399 -0
- pywargame/vassal.py +12500 -0
- pywargame/vmodpatch.py +12548 -0
- pywargame/vsavdump.py +12533 -0
- pywargame/vslmerge.py +13015 -0
- pywargame/wgexport.py +16689 -0
- pywargame/ztexport.py +14351 -0
- pywargame/zuntzu/__init__.py +5 -0
- pywargame/zuntzu/base.py +82 -0
- pywargame/zuntzu/collect.py +38 -0
- pywargame/zuntzu/countersheet.py +250 -0
- pywargame/zuntzu/dicehand.py +48 -0
- pywargame/zuntzu/exporter.py +936 -0
- pywargame/zuntzu/gamebox.py +154 -0
- pywargame/zuntzu/map.py +36 -0
- pywargame/zuntzu/piece.py +37 -0
- pywargame/zuntzu/scenario.py +208 -0
- pywargame/zuntzu/ztexp.py +115 -0
- pywargame-0.3.1.dist-info/METADATA +353 -0
- pywargame-0.3.1.dist-info/RECORD +150 -0
- pywargame-0.3.1.dist-info/WHEEL +5 -0
- pywargame-0.3.1.dist-info/licenses/LICENSE +5 -0
- pywargame-0.3.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,1020 @@
|
|
1
|
+
## BEGIN_IMPORT
|
2
|
+
from common import VerboseGuard
|
3
|
+
from . base import *
|
4
|
+
from . element import Element
|
5
|
+
from . withtraits import *
|
6
|
+
from . globalkey import *
|
7
|
+
## END_IMPORT
|
8
|
+
|
9
|
+
# --------------------------------------------------------------------
|
10
|
+
class MapElementService:
|
11
|
+
def getMap(self):
|
12
|
+
'''Get map - either a Map or WidgetMap'''
|
13
|
+
## BEGIN_IMPORT
|
14
|
+
from . map import WidgetMap, Map
|
15
|
+
## END_IMPORT
|
16
|
+
return self.getParentOfClass([WidgetMap,Map])
|
17
|
+
# if self._parent is None:
|
18
|
+
# return None
|
19
|
+
#
|
20
|
+
# if 'WidgetMap' in self._parent.tagName:
|
21
|
+
# return self.getParent(WidgetMap)
|
22
|
+
#
|
23
|
+
# return self.getParent(Map)
|
24
|
+
def getGame(self):
|
25
|
+
m = self.getMap()
|
26
|
+
if m is not None: return m.getGame()
|
27
|
+
return None
|
28
|
+
|
29
|
+
# --------------------------------------------------------------------
|
30
|
+
class MapElement(Element,MapElementService):
|
31
|
+
def __init__(self,map,tag,node=None,**kwargs):
|
32
|
+
super(MapElement,self).__init__(map,tag,node=node,**kwargs)
|
33
|
+
|
34
|
+
|
35
|
+
# --------------------------------------------------------------------
|
36
|
+
class PieceLayers(MapElement):
|
37
|
+
TAG=Element.MAP+'LayeredPieceCollection'
|
38
|
+
UNIQUE = ['property']
|
39
|
+
def __init__(self,map,node=None,
|
40
|
+
property = 'PieceLayer',
|
41
|
+
description = '',
|
42
|
+
layerOrder = []):
|
43
|
+
super(PieceLayers,self).__init__(map,self.TAG,node=node,
|
44
|
+
property = property,
|
45
|
+
description = description,
|
46
|
+
layerOrder = ','.join(layerOrder))
|
47
|
+
|
48
|
+
def addControl(self,**kwargs):
|
49
|
+
'''Add `LayerControl` element to this
|
50
|
+
|
51
|
+
Parameters
|
52
|
+
----------
|
53
|
+
kwargs : dict
|
54
|
+
Dictionary of attribute key-value pairs
|
55
|
+
|
56
|
+
Returns
|
57
|
+
-------
|
58
|
+
element : LayerControl
|
59
|
+
The added element
|
60
|
+
'''
|
61
|
+
return self.add(LayerControl,**kwargs)
|
62
|
+
def getControls(self,asdict=True):
|
63
|
+
'''Get all `LayerControl` element(s) from this
|
64
|
+
|
65
|
+
Parameters
|
66
|
+
----------
|
67
|
+
asdict : bool
|
68
|
+
If `True`, return a dictonary that maps name to
|
69
|
+
`LayerControl` elements. If `False`, return a list of all
|
70
|
+
`LayerControl` children.
|
71
|
+
|
72
|
+
Returns
|
73
|
+
-------
|
74
|
+
children : dict or list
|
75
|
+
Dictionary or list of `LayerControl` children
|
76
|
+
|
77
|
+
'''
|
78
|
+
return self.getElementsByKey(LayerControl,'name',asdict)
|
79
|
+
|
80
|
+
registerElement(PieceLayers)
|
81
|
+
|
82
|
+
# --------------------------------------------------------------------
|
83
|
+
class LayerControl(MapElement):
|
84
|
+
TAG=Element.MAP+'LayerControl'
|
85
|
+
CYCLE_UP='Rotate Layer Order Up'
|
86
|
+
CYCLE_DOWN='Rotate Layer Order Down'
|
87
|
+
ENABLE='Make Layer Active'
|
88
|
+
DISABLE='Make Layer Inactive'
|
89
|
+
TOGGLE='Switch Layer between Active and Inactive'
|
90
|
+
RESET='Reset All Layers'
|
91
|
+
UNIQUE = ['name']
|
92
|
+
def __init__(self,col,node=None,
|
93
|
+
name = '',
|
94
|
+
tooltip = '',
|
95
|
+
text = '',
|
96
|
+
hotkey = '',
|
97
|
+
icon = '',
|
98
|
+
canDisable = False,
|
99
|
+
propertyGate = '', #Property name, disable when property false
|
100
|
+
disabledIcon = '',
|
101
|
+
command = TOGGLE,
|
102
|
+
skip = False,
|
103
|
+
layers = [],
|
104
|
+
description = ''):
|
105
|
+
super(LayerControl,self).__init__(col,self.TAG,node=node,
|
106
|
+
name = name,
|
107
|
+
tooltip = tooltip,
|
108
|
+
text = text,
|
109
|
+
buttonText = text,
|
110
|
+
hotkey = hotkey,
|
111
|
+
icon = icon,
|
112
|
+
canDisable = canDisable,
|
113
|
+
propertyGate = propertyGate,
|
114
|
+
disabledIcon = disabledIcon,
|
115
|
+
command = command,
|
116
|
+
skip = skip,
|
117
|
+
layers = ','.join(layers),
|
118
|
+
description = description)
|
119
|
+
|
120
|
+
def getLayers(self):
|
121
|
+
'''Get map - either a Map or WidgetMap'''
|
122
|
+
return self.getParentOfClass([PieceLayers])
|
123
|
+
|
124
|
+
registerElement(LayerControl)
|
125
|
+
|
126
|
+
|
127
|
+
# --------------------------------------------------------------------
|
128
|
+
class LineOfSight(MapElement):
|
129
|
+
TAG=Element.MAP+'LOS_Thread'
|
130
|
+
ROUND_UP = 'Up'
|
131
|
+
ROUND_DOWN = 'Down'
|
132
|
+
ROUND_NEAREST = 'Nearest whole number'
|
133
|
+
FROM_LOCATION = 'FromLocation'
|
134
|
+
TO_LOCATION = 'ToLocation'
|
135
|
+
CHECK_COUNT = 'NumberOfLocationsChecked'
|
136
|
+
CHECK_LIST = 'AllLocationsChecked'
|
137
|
+
RANGE = 'Range'
|
138
|
+
NEVER = 'Never'
|
139
|
+
ALWAYS = 'Always'
|
140
|
+
WHEN_PERSISTENT = 'When persistent'
|
141
|
+
CTRL_CLICK = 'Cltr-Click & Drag'
|
142
|
+
UNIQUE = ['threadName']
|
143
|
+
|
144
|
+
def __init__(self,map,
|
145
|
+
node=None,
|
146
|
+
threadName = 'LOS',
|
147
|
+
hotkey = key('L',ALT),
|
148
|
+
tooltip = 'Trace line of sight',
|
149
|
+
iconName = '/images/thread.gif', #'los-icon.png',
|
150
|
+
label = '',
|
151
|
+
snapLOS = False,
|
152
|
+
snapStart = True,
|
153
|
+
snapEnd = True,
|
154
|
+
report = (f'{{"Range from "+{FROM_LOCATION}'
|
155
|
+
f'+" to "+{TO_LOCATION}+" is "'
|
156
|
+
f'+{RANGE}+" (via "+{CHECK_LIST}+")"}}'),
|
157
|
+
persistent = CTRL_CLICK,
|
158
|
+
persistentIconName = '/images/thread.gif',
|
159
|
+
globl = ALWAYS,
|
160
|
+
losThickness = 3,
|
161
|
+
threadColor = rgb(255,0,0),
|
162
|
+
drawRange = True,
|
163
|
+
# rangeBg = rgb(255,255,255),
|
164
|
+
# rangeFg = rgb(0,0,0),
|
165
|
+
rangeScale = 0,
|
166
|
+
hideCounters = True,
|
167
|
+
hideOpacity = 50,
|
168
|
+
round = ROUND_UP,
|
169
|
+
canDisable = False,
|
170
|
+
propertyGate = '',
|
171
|
+
disabledIcon = ''):
|
172
|
+
'''Make Line of Sight interface
|
173
|
+
|
174
|
+
Parameters
|
175
|
+
----------
|
176
|
+
threadName : str
|
177
|
+
Name of interface
|
178
|
+
hotkey : str
|
179
|
+
Start LOS key
|
180
|
+
tooltip : str
|
181
|
+
Tool tip text
|
182
|
+
iconName : str
|
183
|
+
Path to button icon
|
184
|
+
label : str
|
185
|
+
Button text
|
186
|
+
snapLOS : bool
|
187
|
+
Wether to snap both ends
|
188
|
+
snapStart : bool
|
189
|
+
Snap to start
|
190
|
+
snapEnd: bool
|
191
|
+
Snap to end
|
192
|
+
report : str
|
193
|
+
Report format
|
194
|
+
persistent : str
|
195
|
+
When persistent
|
196
|
+
persistentIconName : str
|
197
|
+
Icon when persistent(?)
|
198
|
+
globl : str
|
199
|
+
Visisble to opponents
|
200
|
+
losThickness : int
|
201
|
+
Thickness in pixels
|
202
|
+
losColor : str
|
203
|
+
Colour of line
|
204
|
+
drawRange : bool
|
205
|
+
Draw the range next to LOST thread
|
206
|
+
rangeBg : str
|
207
|
+
Range backgroung colour
|
208
|
+
rangeFg : str
|
209
|
+
Range foregrond colour
|
210
|
+
rangeScale : int
|
211
|
+
Scale of range - pixels per unit
|
212
|
+
round : str
|
213
|
+
How to round range
|
214
|
+
hideCounters :bool
|
215
|
+
If true, hide counters while making thread
|
216
|
+
hideOpacity : int
|
217
|
+
Opacity of hidden counters (percent)
|
218
|
+
canDisable : bool
|
219
|
+
IF true, then can be hidden
|
220
|
+
propertyGate : str
|
221
|
+
Name of property. When that property is TRUE, then the
|
222
|
+
interface is disabled. Must be a property name, not an expression.
|
223
|
+
disabledIcon : str
|
224
|
+
Icon to use when disabled
|
225
|
+
'''
|
226
|
+
super(LineOfSight,self).__init__(map,self.TAG,
|
227
|
+
node = node,
|
228
|
+
threadName = threadName,
|
229
|
+
hotkey = hotkey,
|
230
|
+
tooltip = tooltip,
|
231
|
+
iconName = iconName,
|
232
|
+
label = label,
|
233
|
+
snapLOS = snapLOS,
|
234
|
+
snapStart = snapStart,
|
235
|
+
snapEnd = snapEnd,
|
236
|
+
report = report,
|
237
|
+
persistent = persistent,
|
238
|
+
persistentIconName = persistentIconName,
|
239
|
+
losThickness = losThickness,
|
240
|
+
threadColor = threadColor,
|
241
|
+
drawRange = drawRange,
|
242
|
+
#rangeBg = rangeBg,
|
243
|
+
#rangeFg = rangeFg,
|
244
|
+
rangeScale = rangeScale,
|
245
|
+
hideCounters = hideCounters,
|
246
|
+
hideOpacity = hideOpacity,
|
247
|
+
round = round,
|
248
|
+
canDisable = canDisable,
|
249
|
+
propertyGate = propertyGate,
|
250
|
+
disabledIcon = disabledIcon)
|
251
|
+
self.setAttribute('global',globl)
|
252
|
+
|
253
|
+
|
254
|
+
registerElement(LineOfSight)
|
255
|
+
|
256
|
+
# --------------------------------------------------------------------
|
257
|
+
class StackMetrics(MapElement):
|
258
|
+
TAG=Element.MAP+'StackMetrics'
|
259
|
+
def __init__(self,map,node=None,
|
260
|
+
bottom = key('(',0),
|
261
|
+
down = key('%',0),
|
262
|
+
top = key('&',0),
|
263
|
+
up = key("'",0),
|
264
|
+
disabled = False,
|
265
|
+
exSepX = 6, # Expanded (after double click)
|
266
|
+
exSepY = 18, # Expanded (after double click)
|
267
|
+
unexSepX = 8, # Compact
|
268
|
+
unexSepY = 16): # Compact
|
269
|
+
super(StackMetrics,self).__init__(map,self.TAG,node=node,
|
270
|
+
bottom = bottom,
|
271
|
+
disabled = disabled,
|
272
|
+
down = down,
|
273
|
+
exSepX = exSepX,
|
274
|
+
exSepY = exSepY,
|
275
|
+
top = top,
|
276
|
+
unexSepX = unexSepX,
|
277
|
+
unexSepY = unexSepY,
|
278
|
+
up = up)
|
279
|
+
|
280
|
+
registerElement(StackMetrics)
|
281
|
+
|
282
|
+
# --------------------------------------------------------------------
|
283
|
+
class ImageSaver(MapElement):
|
284
|
+
TAG=Element.MAP+'ImageSaver'
|
285
|
+
def __init__(self,map,node=None,
|
286
|
+
buttonText = '',
|
287
|
+
canDisable = False,
|
288
|
+
hotkey = '',
|
289
|
+
icon = '/images/camera.gif',
|
290
|
+
propertyGate = '',
|
291
|
+
tooltip = 'Save map as PNG image'):
|
292
|
+
super(ImageSaver,self).__init__(map,self.TAG,node=node,
|
293
|
+
buttonText = buttonText,
|
294
|
+
canDisable = canDisable,
|
295
|
+
hotkey = hotkey,
|
296
|
+
icon = icon,
|
297
|
+
propertyGate = propertyGate,
|
298
|
+
tooltip = tooltip)
|
299
|
+
|
300
|
+
registerElement(ImageSaver)
|
301
|
+
|
302
|
+
# --------------------------------------------------------------------
|
303
|
+
class TextSaver(MapElement):
|
304
|
+
TAG=Element.MAP+'TextSaver'
|
305
|
+
def __init__(self,map,node=None,
|
306
|
+
buttonText = '',
|
307
|
+
canDisable = False,
|
308
|
+
hotkey = '',
|
309
|
+
icon = '/images/camera.gif',
|
310
|
+
propertyGate = '',
|
311
|
+
tooltip = 'Save map as text'):
|
312
|
+
super(TextSaver,self).__init__(map,self.TAG,node=node,
|
313
|
+
buttonText = buttonText,
|
314
|
+
canDisable = canDisable,
|
315
|
+
hotkey = hotkey,
|
316
|
+
icon = icon,
|
317
|
+
propertyGate = propertyGate,
|
318
|
+
tooltip = tooltip)
|
319
|
+
|
320
|
+
registerElement(TextSaver)
|
321
|
+
|
322
|
+
# --------------------------------------------------------------------
|
323
|
+
class ForwardToChatter(MapElement):
|
324
|
+
TAG=Element.MAP+'ForwardToChatter'
|
325
|
+
def __init__(self,map,node=None,**kwargs):
|
326
|
+
super(ForwardToChatter,self).__init__(map,self.TAG,node=node,**kwargs)
|
327
|
+
|
328
|
+
registerElement(ForwardToChatter)
|
329
|
+
|
330
|
+
# --------------------------------------------------------------------
|
331
|
+
class MenuDisplayer(MapElement):
|
332
|
+
TAG=Element.MAP+'MenuDisplayer'
|
333
|
+
def __init__(self,map,node=None,**kwargs):
|
334
|
+
super(MenuDisplayer,self).__init__(map,self.TAG,node=node,**kwargs)
|
335
|
+
|
336
|
+
registerElement(MenuDisplayer)
|
337
|
+
|
338
|
+
# --------------------------------------------------------------------
|
339
|
+
class MapCenterer(MapElement):
|
340
|
+
TAG=Element.MAP+'MapCenterer'
|
341
|
+
def __init__(self,map,node=None,**kwargs):
|
342
|
+
super(MapCenterer,self).__init__(map,self.TAG,node=node,**kwargs)
|
343
|
+
|
344
|
+
registerElement(MapCenterer)
|
345
|
+
|
346
|
+
# --------------------------------------------------------------------
|
347
|
+
class StackExpander(MapElement):
|
348
|
+
TAG=Element.MAP+'StackExpander'
|
349
|
+
def __init__(self,map,node=None,**kwargs):
|
350
|
+
super(StackExpander,self).__init__(map,self.TAG,node=node,**kwargs)
|
351
|
+
|
352
|
+
registerElement(StackExpander)
|
353
|
+
|
354
|
+
# --------------------------------------------------------------------
|
355
|
+
class PieceMover(MapElement):
|
356
|
+
TAG=Element.MAP+'PieceMover'
|
357
|
+
def __init__(self,map,node=None,**kwargs):
|
358
|
+
super(PieceMover,self).__init__(map,self.TAG,node=node,**kwargs)
|
359
|
+
|
360
|
+
registerElement(PieceMover)
|
361
|
+
|
362
|
+
# --------------------------------------------------------------------
|
363
|
+
class SelectionHighlighters(MapElement):
|
364
|
+
TAG=Element.MAP+'SelectionHighlighters'
|
365
|
+
def __init__(self,map,node=None,**kwargs):
|
366
|
+
super(SelectionHighlighters,self).\
|
367
|
+
__init__(map,self.TAG,node=node,**kwargs)
|
368
|
+
|
369
|
+
registerElement(SelectionHighlighters)
|
370
|
+
|
371
|
+
# --------------------------------------------------------------------
|
372
|
+
class KeyBufferer(MapElement):
|
373
|
+
TAG=Element.MAP+'KeyBufferer'
|
374
|
+
def __init__(self,map,node=None,**kwargs):
|
375
|
+
super(KeyBufferer,self).__init__(map,self.TAG,node=node,**kwargs)
|
376
|
+
|
377
|
+
registerElement(KeyBufferer)
|
378
|
+
|
379
|
+
# --------------------------------------------------------------------
|
380
|
+
class HighlightLastMoved(MapElement):
|
381
|
+
TAG=Element.MAP+'HighlightLastMoved'
|
382
|
+
def __init__(self,map,node=None,
|
383
|
+
color = rgb(255,0,0),
|
384
|
+
enabled = True,
|
385
|
+
thickness = 2):
|
386
|
+
super(HighlightLastMoved,self).__init__(map,self.TAG,node=node,
|
387
|
+
color = color,
|
388
|
+
enabled = enabled,
|
389
|
+
thickness = thickness)
|
390
|
+
|
391
|
+
registerElement(HighlightLastMoved)
|
392
|
+
|
393
|
+
# --------------------------------------------------------------------
|
394
|
+
class CounterDetailViewer(MapElement):
|
395
|
+
TAG=Element.MAP+'CounterDetailViewer'
|
396
|
+
TOP_LAYER = 'from top-most layer only'
|
397
|
+
ALL_LAYERS = 'from all layers'
|
398
|
+
INC_LAYERS = 'from listed layers only'
|
399
|
+
EXC_LAYERS = 'from layers other than those listed'
|
400
|
+
FILTER = 'by using a property filter'
|
401
|
+
ALWAYS = 'always'
|
402
|
+
NEVER = 'never'
|
403
|
+
IF_ONE = 'ifOne'
|
404
|
+
UNIQUE = ['description']
|
405
|
+
def __init__(self,map,node=None,
|
406
|
+
borderWidth = 0, # Horizontal padding between pieces
|
407
|
+
borderThickness = 2, # Outer border thickness
|
408
|
+
borderInnerThickness = 2, # Inner borders thickness
|
409
|
+
borderColor = None,
|
410
|
+
centerAll = False,
|
411
|
+
centerText = False,
|
412
|
+
centerPiecesVertically = True,
|
413
|
+
combineCounterSummary = False,
|
414
|
+
counterReportFormat = '',
|
415
|
+
delay = 700,
|
416
|
+
description = '',
|
417
|
+
display = TOP_LAYER,
|
418
|
+
emptyHexReportForma = '$LocationName$',
|
419
|
+
enableHTML = True,
|
420
|
+
extraTextPadding = 0,
|
421
|
+
bgColor = None,
|
422
|
+
fgColor = rgb(0,0,0),
|
423
|
+
fontSize = 11,
|
424
|
+
graphicsZoom = 1.0,# Zoom on counters
|
425
|
+
hotkey = key('\n'),
|
426
|
+
layerList = [],
|
427
|
+
minDisplayPieces = 2,
|
428
|
+
propertyFilter = '',
|
429
|
+
showDeck = False,
|
430
|
+
showDeckDepth = 1,
|
431
|
+
showDeckMasked = False,
|
432
|
+
showMoveSelected = False,
|
433
|
+
showNoStack = False,
|
434
|
+
showNonMovable = False,
|
435
|
+
showOverlap = False,
|
436
|
+
showgraph = True,
|
437
|
+
showgraphsingle = False,
|
438
|
+
showtext = True,
|
439
|
+
showtextsingle = False,
|
440
|
+
stretchWidthSummary = False,
|
441
|
+
summaryReportFormat = '$LocationName$',
|
442
|
+
unrotatePieces = False,
|
443
|
+
version = 4,
|
444
|
+
verticalOffset = 2,
|
445
|
+
verticalTopText = 0,
|
446
|
+
zoomlevel = 1.0,
|
447
|
+
stopAfterShowing = False,
|
448
|
+
showTerrainBeneath = NEVER,
|
449
|
+
showTerrainSnappy = True,
|
450
|
+
showTerrainWidth = 120,
|
451
|
+
showTerrainHeight = 120,
|
452
|
+
showTerrainZoom = None,
|
453
|
+
showTerrainText = ''
|
454
|
+
): # showTerrain attributes
|
455
|
+
|
456
|
+
bg = '' if bgColor is None else bgColor
|
457
|
+
fg = '' if fgColor is None else fgColor
|
458
|
+
bc = '' if borderColor is None else borderColor
|
459
|
+
ll = ','.join(layerList)
|
460
|
+
showTerrainZoom = zoomlevel if showTerrainZoom == None else showTerrainZoom
|
461
|
+
super(CounterDetailViewer,self)\
|
462
|
+
.__init__(map,self.TAG,node=node,
|
463
|
+
borderWidth = borderWidth,
|
464
|
+
borderThickness = borderThickness,
|
465
|
+
borderInnerThickness = borderInnerThickness,
|
466
|
+
borderColor = bc,
|
467
|
+
centerAll = centerAll,
|
468
|
+
centerText = centerText,
|
469
|
+
centerPiecesVertically = centerPiecesVertically,
|
470
|
+
combineCounterSummary = combineCounterSummary,
|
471
|
+
counterReportFormat = counterReportFormat,
|
472
|
+
delay = delay,
|
473
|
+
description = description,
|
474
|
+
display = display, # How to show from layers
|
475
|
+
emptyHexReportForma = emptyHexReportForma,
|
476
|
+
enableHTML = enableHTML,
|
477
|
+
extraTextPadding = extraTextPadding,
|
478
|
+
bgColor = bg,
|
479
|
+
fgColor = fg,
|
480
|
+
fontSize = fontSize,
|
481
|
+
graphicsZoom = graphicsZoom, # pieces at zoom
|
482
|
+
hotkey = hotkey,
|
483
|
+
layerList = ll,
|
484
|
+
minDisplayPieces = minDisplayPieces,
|
485
|
+
propertyFilter = propertyFilter,
|
486
|
+
showDeck = showDeck,
|
487
|
+
showDeckDepth = showDeckDepth,
|
488
|
+
showDeckMasked = showDeckMasked,
|
489
|
+
showMoveSelectde = showMoveSelected,
|
490
|
+
showNoStack = showNoStack,
|
491
|
+
showNonMovable = showNonMovable,
|
492
|
+
showOverlap = showOverlap,
|
493
|
+
showgraph = showgraph,
|
494
|
+
showgraphsingle = showgraphsingle,
|
495
|
+
showtext = showtext,
|
496
|
+
showtextsingle = showtextsingle,
|
497
|
+
stretchWidthSummary = stretchWidthSummary,
|
498
|
+
summaryReportFormat = summaryReportFormat,
|
499
|
+
unrotatePieces = unrotatePieces,
|
500
|
+
version = version,
|
501
|
+
verticalOffset = verticalOffset,
|
502
|
+
verticalTopText = verticalTopText,
|
503
|
+
zoomlevel = zoomlevel,
|
504
|
+
stopAfterShowing = stopAfterShowing,
|
505
|
+
showTerrainBeneath = showTerrainBeneath,
|
506
|
+
showTerrainSnappy = showTerrainSnappy,
|
507
|
+
showTerrainWidth = showTerrainWidth,
|
508
|
+
showTerrainHeight = showTerrainHeight,
|
509
|
+
showTerrainZoom = showTerrainZoom,
|
510
|
+
showTerrainText = showTerrainText)
|
511
|
+
|
512
|
+
registerElement(CounterDetailViewer)
|
513
|
+
|
514
|
+
# --------------------------------------------------------------------
|
515
|
+
class GlobalMap(MapElement):
|
516
|
+
TAG=Element.MAP+'GlobalMap'
|
517
|
+
def __init__(self,map,node=None,
|
518
|
+
buttonText = '',
|
519
|
+
color = rgb(255,0,0),
|
520
|
+
hotkey = key('O',CTRL_SHIFT),
|
521
|
+
icon = '/images/overview.gif',
|
522
|
+
scale = 0.2,
|
523
|
+
tooltip = 'Show/Hide overview window'):
|
524
|
+
super(GlobalMap,self).\
|
525
|
+
__init__(map,self.TAG,node=node,
|
526
|
+
buttonText = buttonText,
|
527
|
+
color = color,
|
528
|
+
hotkey = hotkey,
|
529
|
+
icon = icon,
|
530
|
+
scale = scale,
|
531
|
+
tooltip = 'Show/Hide overview window')
|
532
|
+
|
533
|
+
registerElement(GlobalMap)
|
534
|
+
|
535
|
+
# --------------------------------------------------------------------
|
536
|
+
class Zoomer(MapElement):
|
537
|
+
TAG = Element.MAP+'Zoomer'
|
538
|
+
def __init__(self,map,node=None,
|
539
|
+
inButtonText = '',
|
540
|
+
inIconName = '/images/zoomIn.gif',
|
541
|
+
inTooltip = 'Zoom in',
|
542
|
+
outButtonText = '',
|
543
|
+
outIconName = '/images/zoomOut.gif',
|
544
|
+
outTooltip = 'Zoom out',
|
545
|
+
pickButtonText = '',
|
546
|
+
pickIconName = '/images/zoom.png',
|
547
|
+
pickTooltip = 'Select Zoom',
|
548
|
+
zoomInKey = key('=',CTRL_SHIFT),
|
549
|
+
zoomLevels = [0.2,0.25,0.333,0.4,0.5,
|
550
|
+
0.555,0.625,0.75,1.0,1.25,1.6],
|
551
|
+
zoomOutKey = key('-'),
|
552
|
+
zoomPickKey = key('='),
|
553
|
+
zoomStart = 3):
|
554
|
+
|
555
|
+
'''Zoom start is counting from the back (with default zoom levels,
|
556
|
+
and zoom start, the default zoom is 1'''
|
557
|
+
lvls = ','.join([str(z) for z in zoomLevels])
|
558
|
+
super(Zoomer,self).\
|
559
|
+
__init__(map,self.TAG,node=node,
|
560
|
+
inButtonText = inButtonText,
|
561
|
+
inIconName = inIconName,
|
562
|
+
inTooltip = inTooltip,
|
563
|
+
outButtonText = outButtonText,
|
564
|
+
outIconName = outIconName,
|
565
|
+
outTooltip = outTooltip,
|
566
|
+
pickButtonText = pickButtonText,
|
567
|
+
pickIconName = pickIconName,
|
568
|
+
pickTooltip = pickTooltip,
|
569
|
+
zoomInKey = zoomInKey,
|
570
|
+
zoomLevels = lvls,
|
571
|
+
zoomOutKey = zoomOutKey,
|
572
|
+
zoomPickKey = zoomPickKey,
|
573
|
+
zoomStart = zoomStart)
|
574
|
+
|
575
|
+
registerElement(Zoomer)
|
576
|
+
|
577
|
+
# --------------------------------------------------------------------
|
578
|
+
class HidePiecesButton(MapElement):
|
579
|
+
TAG=Element.MAP+'HidePiecesButton'
|
580
|
+
def __init__(self,map,node=None,
|
581
|
+
buttonText = '',
|
582
|
+
hiddenIcon = '/images/globe_selected.gif',
|
583
|
+
hotkey = key('O'),
|
584
|
+
showingIcon = '/images/globe_unselected.gif',
|
585
|
+
tooltip = 'Hide all pieces on this map'):
|
586
|
+
super(HidePiecesButton,self).\
|
587
|
+
__init__(map,self.TAG,node=node,
|
588
|
+
buttonText = buttonText,
|
589
|
+
hiddenIcon = hiddenIcon,
|
590
|
+
hotkey = hotkey,
|
591
|
+
showingIcon = showingIcon,
|
592
|
+
tooltip = tooltip)
|
593
|
+
|
594
|
+
registerElement(HidePiecesButton)
|
595
|
+
|
596
|
+
# --------------------------------------------------------------------
|
597
|
+
class MassKey(GlobalKey,MapElementService):
|
598
|
+
TAG = Element.MAP+'MassKeyCommand'
|
599
|
+
UNIQUE = ['name']
|
600
|
+
def __init__(self,map,node=None,
|
601
|
+
name = '',
|
602
|
+
buttonHotkey = '',
|
603
|
+
hotkey = '',
|
604
|
+
buttonText = '',
|
605
|
+
canDisable = False,
|
606
|
+
deckCount = '-1',
|
607
|
+
filter = '',
|
608
|
+
propertyGate = '',
|
609
|
+
reportFormat = '',
|
610
|
+
reportSingle = False,
|
611
|
+
singleMap = True,
|
612
|
+
target = GlobalKey.SELECTED,
|
613
|
+
tooltip = '',
|
614
|
+
icon = ''):
|
615
|
+
'''Default targets are selected units'''
|
616
|
+
super(MassKey,self).\
|
617
|
+
__init__(map,self.TAG,node=node,
|
618
|
+
name = name,
|
619
|
+
buttonHotkey = buttonHotkey, # This hot key
|
620
|
+
hotkey = hotkey, # Target hot key
|
621
|
+
buttonText = buttonText,
|
622
|
+
canDisable = canDisable,
|
623
|
+
deckCount = deckCount,
|
624
|
+
filter = filter,
|
625
|
+
propertyGate = propertyGate,
|
626
|
+
reportFormat = reportFormat,
|
627
|
+
reportSingle = reportSingle,
|
628
|
+
singleMap = singleMap,
|
629
|
+
target = target,
|
630
|
+
tooltip = tooltip,
|
631
|
+
icon = icon)
|
632
|
+
|
633
|
+
registerElement(MassKey)
|
634
|
+
|
635
|
+
# --------------------------------------------------------------------
|
636
|
+
class Flare(MapElement):
|
637
|
+
TAG=Element.MAP+'Flare'
|
638
|
+
def __init__(self,map,node=None,
|
639
|
+
circleColor = rgb(255,0,0),
|
640
|
+
circleScale = True,
|
641
|
+
circleSize = 100,
|
642
|
+
flareKey = 'keyAlt',
|
643
|
+
flareName = 'Map Flare',
|
644
|
+
flarePulses = 6,
|
645
|
+
flarePulsesPerSec = 3,
|
646
|
+
reportFormat = ''):
|
647
|
+
super(Flare,self).__init__(map,self.TAG,node=node,
|
648
|
+
circleColor = circleColor,
|
649
|
+
circleScale = circleScale,
|
650
|
+
circleSize = circleSize,
|
651
|
+
flareKey = flareKey,
|
652
|
+
flareName = flareName,
|
653
|
+
flarePulses = flarePulses,
|
654
|
+
flarePulsesPerSec = flarePulsesPerSec,
|
655
|
+
reportFormat = '')
|
656
|
+
|
657
|
+
registerElement(Flare)
|
658
|
+
|
659
|
+
# --------------------------------------------------------------------
|
660
|
+
class Deck(MapElement):
|
661
|
+
TAG = Element.MODULE+'map.DrawPile'
|
662
|
+
ALWAYS = 'Always'
|
663
|
+
NEVER = 'Never',
|
664
|
+
VIA_MOUSE2 = 'Via right-click Menu'
|
665
|
+
UNIQUE = ['name','owningBoard']
|
666
|
+
def __init__(self,map,
|
667
|
+
node = None,
|
668
|
+
name = 'deckName',
|
669
|
+
owningBoard = '',
|
670
|
+
x = 0, # int
|
671
|
+
y = 0, # int
|
672
|
+
width = 200, # int
|
673
|
+
height = 200, # int
|
674
|
+
#
|
675
|
+
allowMultiple = False,
|
676
|
+
drawMultipleMessage = 'Draw multiple cards',
|
677
|
+
#
|
678
|
+
allowSelect = False,
|
679
|
+
drawSpecificMessage = 'Draw specific cards',
|
680
|
+
selectDisplayProperty = '$BasicName$',
|
681
|
+
selectSortProperty = 'BasicName',
|
682
|
+
#
|
683
|
+
faceDown = ALWAYS,#ALWAYS,VIA_MOUSE2
|
684
|
+
faceFlipHotkey = key('F'),
|
685
|
+
faceDownFormat = '',
|
686
|
+
faceDownHotkey = '',
|
687
|
+
faceDownMessage = 'Face down',
|
688
|
+
faceUpHotkey = '',
|
689
|
+
faceUpMessage = 'Face up',
|
690
|
+
faceUpReportFormat = '',
|
691
|
+
drawFaceUp = False,
|
692
|
+
#
|
693
|
+
shuffle = VIA_MOUSE2,#ALWAYS,NEVER
|
694
|
+
shuffleCommand = 'Shuffle',
|
695
|
+
shuffleFormat = '$playerSide$ shuffles $deckName$',
|
696
|
+
shuffleHotkey = key('S',ALT),
|
697
|
+
#
|
698
|
+
reversible = False,
|
699
|
+
reverseCommand = 'Reverse',
|
700
|
+
reverseFormat = '',
|
701
|
+
reverseHotkey = '',
|
702
|
+
#
|
703
|
+
draw = True,
|
704
|
+
color = rgb(255,51,51),
|
705
|
+
hotkeyOnEmpty = False,
|
706
|
+
emptyHotkey = key(NONE,0)+',DeckEmpty',
|
707
|
+
#
|
708
|
+
reshufflable = False,
|
709
|
+
reshuffleCommand = '',
|
710
|
+
reshuffleHotkey = '',
|
711
|
+
reshuffleMessage = '',
|
712
|
+
reshuffleTarget = '',
|
713
|
+
#
|
714
|
+
canSave = False,
|
715
|
+
saveHotkey = '',
|
716
|
+
saveMessage = 'Save Deck',
|
717
|
+
saveReportFormat = 'Deck Saved',
|
718
|
+
loadHotkey = '',
|
719
|
+
loadMessage = 'Load Deck',
|
720
|
+
loadReportFormat = 'Deck Loaded',
|
721
|
+
#
|
722
|
+
maxStack = 15,
|
723
|
+
#
|
724
|
+
expressionCounting = False,
|
725
|
+
countExpressions = '',
|
726
|
+
#
|
727
|
+
restrictExpression = '',
|
728
|
+
restrictOption = False,
|
729
|
+
#
|
730
|
+
deckOwners = '',
|
731
|
+
deckRestrictAccess = False
|
732
|
+
): # int
|
733
|
+
pass
|
734
|
+
super(Deck,self).\
|
735
|
+
__init__(map,self.TAG,node=node,
|
736
|
+
name = name,
|
737
|
+
owningBoard = owningBoard,
|
738
|
+
x = int(x), # int
|
739
|
+
y = int(y), # int
|
740
|
+
width = int(width), # int
|
741
|
+
height = int(height), # int
|
742
|
+
#
|
743
|
+
allowMultiple = allowMultiple,
|
744
|
+
drawMultipleMessage = drawMultipleMessage,
|
745
|
+
#
|
746
|
+
allowSelect = allowSelect,
|
747
|
+
drawSpecificMessage = drawSpecificMessage,
|
748
|
+
selectDisplayProperty = selectDisplayProperty,
|
749
|
+
selectSortProperty = selectSortProperty,
|
750
|
+
#
|
751
|
+
faceDown = faceDown,
|
752
|
+
faceFlipHotkey = faceFlipHotkey,
|
753
|
+
faceDownFormat = faceDownFormat,
|
754
|
+
faceDownHotkey = faceDownHotkey,
|
755
|
+
faceDownMessage = faceDownMessage,
|
756
|
+
faceUpHotkey = faceUpHotkey,
|
757
|
+
faceUpMessage = faceUpMessage,
|
758
|
+
faceUpReportFormat = faceUpReportFormat,
|
759
|
+
drawFaceUp = drawFaceUp,
|
760
|
+
#
|
761
|
+
shuffle = shuffle,
|
762
|
+
shuffleCommand = shuffleCommand,
|
763
|
+
shuffleFormat = shuffleFormat,
|
764
|
+
shuffleHotkey = shuffleHotkey,
|
765
|
+
#
|
766
|
+
reversible = reversible,
|
767
|
+
reverseCommand = reverseCommand,
|
768
|
+
reverseFormat = reverseFormat,
|
769
|
+
reverseHotkey = reverseHotkey,
|
770
|
+
#
|
771
|
+
draw = draw,
|
772
|
+
color = color,
|
773
|
+
hotkeyOnEmpty = hotkeyOnEmpty,
|
774
|
+
emptyHotkey = emptyHotkey,
|
775
|
+
#
|
776
|
+
reshufflable = reshufflable,
|
777
|
+
reshuffleCommand = reshuffleCommand,
|
778
|
+
reshuffleHotkey = reshuffleHotkey,
|
779
|
+
reshuffleMessage = reshuffleMessage,
|
780
|
+
reshuffleTarget = reshuffleTarget,
|
781
|
+
#
|
782
|
+
canSave = canSave,
|
783
|
+
saveHotkey = saveHotkey,
|
784
|
+
saveMessage = saveMessage,
|
785
|
+
saveReportFormat = saveReportFormat,
|
786
|
+
loadHotkey = loadHotkey,
|
787
|
+
loadMessage = loadMessage,
|
788
|
+
loadReportFormat = loadReportFormat,
|
789
|
+
#
|
790
|
+
maxStack = maxStack,
|
791
|
+
#
|
792
|
+
expressionCounting = expressionCounting,
|
793
|
+
countExpressions = countExpressions,
|
794
|
+
#
|
795
|
+
restrictExpression = restrictExpression,
|
796
|
+
restrictOption = restrictOption,
|
797
|
+
#
|
798
|
+
deckOwners = deckOwners,
|
799
|
+
deckRestrictAccess = deckRestrictAccess
|
800
|
+
)
|
801
|
+
|
802
|
+
def addCard(self,**kwargs):
|
803
|
+
'''Add a `Card` element to this
|
804
|
+
|
805
|
+
Parameters
|
806
|
+
----------
|
807
|
+
kwargs : dict
|
808
|
+
Dictionary of attribute key-value pairs
|
809
|
+
|
810
|
+
Returns
|
811
|
+
-------
|
812
|
+
element : Card
|
813
|
+
The added element
|
814
|
+
'''
|
815
|
+
if not isinstance(card,CardSlot):
|
816
|
+
print(f'Trying to add {type(card)} to Deck')
|
817
|
+
return None
|
818
|
+
|
819
|
+
p = card.clone(self)
|
820
|
+
# self._node.appendChild(p._node)
|
821
|
+
return p
|
822
|
+
def addFolder(self,**kwargs):
|
823
|
+
'''Add a `ModuleFolder` element to this
|
824
|
+
|
825
|
+
Parameters
|
826
|
+
----------
|
827
|
+
kwargs : dict
|
828
|
+
Dictionary of attribute key-value pairs
|
829
|
+
|
830
|
+
Returns
|
831
|
+
-------
|
832
|
+
element : ModuleFolder
|
833
|
+
The added element
|
834
|
+
'''
|
835
|
+
return self.add(DeckFolder,**kwargs)
|
836
|
+
|
837
|
+
def getCards(self,asdict=True):
|
838
|
+
'''Get all Card element(s) from this
|
839
|
+
|
840
|
+
Parameters
|
841
|
+
----------
|
842
|
+
asdict : bool
|
843
|
+
If `True`, return a dictonary that maps key to `Card`
|
844
|
+
elements. If `False`, return a list of all Card`
|
845
|
+
children.
|
846
|
+
|
847
|
+
Returns
|
848
|
+
-------
|
849
|
+
children : dict or list
|
850
|
+
Dictionary or list of `Card` children
|
851
|
+
|
852
|
+
'''
|
853
|
+
return self.getElementsByKey(CardSlot,'entryName',asdict)
|
854
|
+
def getFolders(self,asdict=True):
|
855
|
+
'''Get all Menu element(s) from this
|
856
|
+
|
857
|
+
Parameters
|
858
|
+
----------
|
859
|
+
asdict : bool
|
860
|
+
If `True`, return a dictonary that maps key to `Folder`
|
861
|
+
elements. If `False`, return a list of all `Folder`
|
862
|
+
children.
|
863
|
+
|
864
|
+
Returns
|
865
|
+
-------
|
866
|
+
children : dict or list
|
867
|
+
Dictionary or list of `Folder` children
|
868
|
+
|
869
|
+
'''
|
870
|
+
return self.getElementsByKey(DeckFolder,'name',asdict)
|
871
|
+
|
872
|
+
|
873
|
+
registerElement(Deck)
|
874
|
+
|
875
|
+
|
876
|
+
# --------------------------------------------------------------------
|
877
|
+
class AtStart(MapElement):
|
878
|
+
TAG = Element.MODULE+'map.SetupStack'
|
879
|
+
UNIQUE = ['name','location','owningBoard']
|
880
|
+
def __init__(self,map,
|
881
|
+
node = None,
|
882
|
+
name = '',
|
883
|
+
location = '',
|
884
|
+
useGridLocation = True,
|
885
|
+
owningBoard = '',
|
886
|
+
x = 0,
|
887
|
+
y = 0):
|
888
|
+
'''Pieces are existing PieceSlot elements
|
889
|
+
|
890
|
+
|
891
|
+
Parameters
|
892
|
+
----------
|
893
|
+
node : xml.minidom.Node
|
894
|
+
Existing node or None
|
895
|
+
name : str
|
896
|
+
Name of node
|
897
|
+
location : str
|
898
|
+
Where the at-start element is put if `useGridLocation`
|
899
|
+
useGridLocation : bool
|
900
|
+
If true, use maps grid
|
901
|
+
owningBoard : str
|
902
|
+
Board that owns the at-start (can be empty)
|
903
|
+
x : float
|
904
|
+
Coordinate (ignored if `useGridLocation`)
|
905
|
+
y : float
|
906
|
+
Coordinate (ignored if `useGridLocation`)
|
907
|
+
'''
|
908
|
+
super(AtStart,self).\
|
909
|
+
__init__(map,self.TAG,node=node,
|
910
|
+
name = name,
|
911
|
+
location = location,
|
912
|
+
owningBoard = owningBoard,
|
913
|
+
useGridLocation = useGridLocation,
|
914
|
+
x = x,
|
915
|
+
y = y)
|
916
|
+
|
917
|
+
def addPieces(self,*pieces):
|
918
|
+
'''Add a `Pieces` element to this
|
919
|
+
|
920
|
+
Parameters
|
921
|
+
----------
|
922
|
+
kwargs : dict
|
923
|
+
Dictionary of attribute key-value pairs
|
924
|
+
|
925
|
+
Returns
|
926
|
+
-------
|
927
|
+
element : Pieces
|
928
|
+
The added element
|
929
|
+
'''
|
930
|
+
# copy pieces here
|
931
|
+
copies = []
|
932
|
+
for p in pieces:
|
933
|
+
c = self.addPiece(p)
|
934
|
+
if c is not None:
|
935
|
+
copies.append(c)
|
936
|
+
return copies
|
937
|
+
|
938
|
+
def addPiece(self,piece):
|
939
|
+
'''Add a `Piece` element to this
|
940
|
+
|
941
|
+
Parameters
|
942
|
+
----------
|
943
|
+
kwargs : dict
|
944
|
+
Dictionary of attribute key-value pairs
|
945
|
+
|
946
|
+
Returns
|
947
|
+
-------
|
948
|
+
element : Piece
|
949
|
+
The added element
|
950
|
+
'''
|
951
|
+
if not isinstance(piece,WithTraitsSlot):
|
952
|
+
# Next is a bit of a hack - not nice
|
953
|
+
if piece.__class__.__name__ not in ['PieceSlot','CardSlot']:
|
954
|
+
print(f'Trying to add {type(piece)} to AtStart, '
|
955
|
+
f'not a {isinstance(piece,WithTraitsSlot)}')
|
956
|
+
return None
|
957
|
+
|
958
|
+
p = piece.clone(self)
|
959
|
+
# self._node.appendChild(p._node)
|
960
|
+
return p
|
961
|
+
|
962
|
+
def getPieces(self,asdict=True):
|
963
|
+
'''Get all Piece element(s) from this
|
964
|
+
|
965
|
+
Parameters
|
966
|
+
----------
|
967
|
+
asdict : bool
|
968
|
+
If `True`, return a dictonary that maps key to `Piece`
|
969
|
+
elements. If `False`, return a list of all Piece`
|
970
|
+
children.
|
971
|
+
|
972
|
+
Returns
|
973
|
+
-------
|
974
|
+
children : dict or list
|
975
|
+
Dictionary or list of `Piece` children
|
976
|
+
|
977
|
+
'''
|
978
|
+
return self.getElementsByKey(PieceSlot,'entryName',asdict)
|
979
|
+
|
980
|
+
registerElement(AtStart)
|
981
|
+
|
982
|
+
# --------------------------------------------------------------------
|
983
|
+
class ForwardKeys(MapElement):
|
984
|
+
TAG = Element.MODULE+'map.ForwardToKeyBuffer'
|
985
|
+
def __init__(self,map,
|
986
|
+
node = None):
|
987
|
+
'''Forward keys to key buffer from where it is distributed to
|
988
|
+
selected pieces. Don't know how I missed this!
|
989
|
+
|
990
|
+
'''
|
991
|
+
|
992
|
+
super(ForwardKeys,self).\
|
993
|
+
__init__(map,self.TAG,node=node)
|
994
|
+
|
995
|
+
registerElement(ForwardKeys)
|
996
|
+
|
997
|
+
# --------------------------------------------------------------------
|
998
|
+
class Scroller(MapElement):
|
999
|
+
TAG = Element.MODULE+'map.Scroller'
|
1000
|
+
ALWAYS = 'always'
|
1001
|
+
NEVER = 'never'
|
1002
|
+
PROMPT = 'prompt'
|
1003
|
+
def __init__(self,map,
|
1004
|
+
node = None,
|
1005
|
+
useArrows = PROMPT):
|
1006
|
+
'''This component listens to key events on a Map window and
|
1007
|
+
scrolls the map. Depending on the useArrows attribute, will
|
1008
|
+
use number keypad or arrow keys, or will offer a preferences
|
1009
|
+
setting for the user to choose
|
1010
|
+
'''
|
1011
|
+
|
1012
|
+
super(Scroller,self).\
|
1013
|
+
__init__(map,self.TAG,node=node,
|
1014
|
+
useArrows = useArrows)
|
1015
|
+
|
1016
|
+
registerElement(Scroller)
|
1017
|
+
|
1018
|
+
#
|
1019
|
+
# EOF
|
1020
|
+
#
|