summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/wargame/source/utils/wgexport.py
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/wargame/source/utils/wgexport.py')
-rwxr-xr-xmacros/latex/contrib/wargame/source/utils/wgexport.py971
1 files changed, 849 insertions, 122 deletions
diff --git a/macros/latex/contrib/wargame/source/utils/wgexport.py b/macros/latex/contrib/wargame/source/utils/wgexport.py
index a09a7e4257..d573b63d36 100755
--- a/macros/latex/contrib/wargame/source/utils/wgexport.py
+++ b/macros/latex/contrib/wargame/source/utils/wgexport.py
@@ -208,6 +208,8 @@ CTRL_SHIFT = CTRL+SHIFT
ALT_SHIFT = ALT+SHIFT
NONE = '\ue004'
NONE_MOD = 0
+
+# --------------------------------------------------------------------
def key(let,mod=CTRL):
'''Encode a key sequence
@@ -220,6 +222,8 @@ def key(let,mod=CTRL):
Modifier mask
'''
return f'{ord(let)},{mod}'
+
+# --------------------------------------------------------------------
#
def hexcolor(s):
if isinstance(s,str):
@@ -241,6 +245,7 @@ def hexcolor(s):
return rgb(int(r*256),int(g*256),int(b*256))
+# --------------------------------------------------------------------
# Colour encoding
def rgb(r,g,b):
'''Encode RGB colour
@@ -261,6 +266,7 @@ def rgb(r,g,b):
'''
return ','.join([str(r),str(g),str(b)])
+# --------------------------------------------------------------------
def rgba(r,g,b,a):
'''Encode RGBA colour
@@ -282,6 +288,7 @@ def rgba(r,g,b,a):
'''
return ','.join([str(r),str(g),str(b),str(a)])
+# --------------------------------------------------------------------
def dumpTree(node,ind=''):
'''Dump the tree of nodes
@@ -296,6 +303,12 @@ def dumpTree(node,ind=''):
for c in node.childNodes:
dumpTree(c,ind+' ')
+# --------------------------------------------------------------------
+def registerElement(cls):
+
+ Element.known_tags[cls.TAG] = cls
+
+
#
# EOF
#
@@ -310,6 +323,8 @@ class Element:
MAP = MODULE + 'map.'
PICKER = MAP + 'boardPicker.'
BOARD = PICKER + 'board.'
+ known_tags = {}
+
def __init__(self,parent,tag,node=None,**kwargs):
'''Create a new element
@@ -429,9 +444,14 @@ class Element:
return {c[key] : c for c in cand}
return cand
- def getParent(self,cls,checkTag=True):
+ def getParent(self,cls=None,checkTag=True):
if self._node.parentNode is None:
return None
+ if cls is None:
+ cls = self.getTagClass(self._node.parentNode.tagName)
+ checkTag = False
+ if cls is None:
+ return None
if checkTag and self._node.parentNode.tagName != cls.TAG:
return None
return cls(self,node=self._node.parentNode)
@@ -440,6 +460,10 @@ class Element:
'''Searches back until we find the parent with the right
class, or none
'''
+ try:
+ iter(cls)
+ except:
+ cls = [cls]
t = {c.TAG: c for c in cls}
p = self._node.parentNode
while p is not None:
@@ -447,6 +471,11 @@ class Element:
if c is not None: return c(self,node=p)
p = p.parentNode
return None
+
+ def getTagClass(self,tag):
+ '''Get class corresponding to the tag'''
+ if tag not in self.known_tags: return None;
+ return self.known_tags[tag]
# ----------------------------------------------------------------
# Adders
@@ -518,7 +547,83 @@ class DummyElement(Element):
'''
super(DummyElement,self).__init__(parent,'Dummy',node=node)
+# --------------------------------------------------------------------
+class ToolbarElement(Element):
+ def __init__(self,
+ parent,
+ tag,
+ node = None,
+ name = '', # Toolbar element name
+ tooltip = '', # Tool tip
+ text = '', # Button text
+ icon = '', # Button icon,
+ hotkey = '', # Named key or key stroke
+ canDisable = False,
+ propertyGate = '',
+ disabledIcon = '',
+ **kwargs):
+ '''Base class for toolbar elements.
+ Parameters
+ ----------
+ parent : Element
+ Parent element if any
+ tag : str
+ Element tag
+ node : XMLNode
+ Possible node - when reading back
+ name : str
+ Name of element (user reminder). If not set, and tooltip is set,
+ set to tooltip
+ toolttip : str
+ Tool tip when hovering. If not set, and name is set, then
+ use name as tooltip.
+ text : str
+ Text of button
+ icon : str
+ Image path for button image
+ hotkey : str
+ Named key or key-sequence
+ canDisable : bool
+ If true, then the element can be disabled
+ propertyGate : str
+ Name of a global property. When this property is `true`,
+ then this element is _disabled_. Note that this _must_ be
+ the name of a property - it cannot be a BeanShell
+ expression.
+ disabledIcon : str
+ Path to image to use when the element is disabled.
+ kwargs : dict
+ Other attributes to set on the element
+ '''
+ if name == '' and tooltip != '': name = tooltip
+ if name != '' and tooltip == '': tooltip = name
+
+ # Build arguments for super class
+ args = {
+ 'node': node,
+ 'name': name,
+ 'icon': icon,
+ 'tooltip': tooltip,
+ 'hotkey': hotkey,
+ 'canDisable': canDisable,
+ 'propertyGate': propertyGate,
+ 'disabledIcon': disabledIcon }
+ bt = kwargs.pop('buttonText',None)
+ # If the element expects buttonText attribute, then do not set
+ # the text attribute - some elements interpret that as a
+ # legacy name attribute,
+ if bt is not None:
+ args['buttonText'] = bt
+ else:
+ args['text'] = text
+ args.update(kwargs)
+
+ super(ToolbarElement,self).__init__(parent,
+ tag,
+ **args)
+ # print('Attributes\n','\n'.join([f'- {k}="{v}"' for k,v in self._node.attributes.items()]))
+
#
# EOF
#
@@ -526,26 +631,28 @@ class DummyElement(Element):
# From globalkey.py
# --------------------------------------------------------------------
-class GlobalKey(Element):
+class GlobalKey(ToolbarElement):
SELECTED = 'MAP|false|MAP|||||0|0||true|Selected|true|EQUALS'
def __init__(self,
parent,
tag,
node = None,
name = '',
+ icon = '',
+ tooltip = '',
buttonHotkey = '',
- hotkey = '',
buttonText = '',
canDisable = False,
+ propertyGate = '',
+ disabledIcon = '',
+ # Local
+ hotkey = '',
deckCount = '-1',
filter = '',
- propertyGate = '',
reportFormat = '',
reportSingle = False,
singleMap = True,
- target = SELECTED,
- tooltip = '',
- icon = ''):
+ target = SELECTED):
'''
Parameters
----------
@@ -569,28 +676,26 @@ class GlobalKey(Element):
Default targets are selected units
'''
- nme = (name if len(name) > 0 else
- tooltip if len(tooltip) > 0 else '')
- tip = (tooltip if len(tooltip) > 0 else
- name if len(name) > 0 else '')
+
super(GlobalKey,self).\
__init__(parent,
tag,
node = node,
- name = nme,
+ name = name,
+ icon = icon,
+ tooltip = tooltip,
buttonHotkey = buttonHotkey, # This hot key
- hotkey = hotkey, # Target hot key
buttonText = buttonText,
canDisable = canDisable,
+ propertyGate = propertyGate,
+ disabledIcon = disabledIcon,
+ hotkey = hotkey, # Target hot key
deckCount = deckCount,
filter = filter,
- propertyGate = propertyGate,
reportFormat = reportFormat,
reportSingle = reportSingle,
singleMap = singleMap,
- target = target,
- tooltip = tip,
- icon = icon)
+ target = target)
#
# EOF
#
@@ -600,7 +705,7 @@ class GlobalKey(Element):
# --------------------------------------------------------------------
class GameElementService:
def getGame(self):
- return self.getParent(Game)
+ return self.getParentOfClass(Game)
# --------------------------------------------------------------------
class GameElement(Element,GameElementService):
@@ -608,23 +713,34 @@ class GameElement(Element,GameElementService):
super(GameElement,self).__init__(game,tag,node=node,**kwargs)
# --------------------------------------------------------------------
-class Notes(GameElement):
+class Notes(ToolbarElement,GameElementService):
TAG = Element.MODULE+'NotesWindow'
def __init__(self,elem,node=None,
- name = 'Notes',
- buttonText = '',
- hotkey = key('N',ALT),
- icon = '/images/notes.gif',
- tooltip = 'Show notes window'):
- super(Notes,self).__init__(elem,self.TAG,node=node,
- name = name,
- buttonText = buttonText,
- hotkey = hotkey,
- icon = icon,
- tooltip = tooltip)
+ name = 'Notes', # Toolbar element name
+ tooltip = 'Show notes window', # Tool tip
+ text = '', # Button text
+ icon = '/images/notes.gif', # Button icon,
+ hotkey = key('N',ALT), # Named key or key stroke
+ canDisable = False,
+ propertyGate = '',
+ disabledIcon = '',
+ description = ''):
+ super(Notes,self).__init__(elem,self.TAG,
+ node = node,
+ name = name,
+ tooltip = tooltip,
+ text = text,
+ icon = icon,
+ hotkey = hotkey,
+ canDisable = canDisable,
+ propertyGate = propertyGate,
+ disabledIcon = disabledIcon,
+ description = description)
def encode(self):
return ['NOTES\t\\','PNOTES']
+registerElement(Notes)
+
# --------------------------------------------------------------------
class PredefinedSetup(GameElement):
TAG = Element.MODULE+'PredefinedSetup'
@@ -673,6 +789,7 @@ class PredefinedSetup(GameElement):
+registerElement(PredefinedSetup)
# --------------------------------------------------------------------
class GlobalTranslatableMessages(GameElement):
@@ -690,11 +807,15 @@ class GlobalTranslatableMessages(GameElement):
super(GlobalTranslatableMessages,self).\
__init__(elem,self.TAG,node=node)
+registerElement(GlobalTranslatableMessages)
+
# --------------------------------------------------------------------
class Language(GameElement):
TAG = 'VASSAL.i18n.Language'
def __init__(self,elem,node=None,**kwargs):
super(Languate,self).__init__(sele,self.TAG,node=none,**kwargs)
+
+registerElement(Language)
# --------------------------------------------------------------------
class Chatter(GameElement):
@@ -712,6 +833,8 @@ class Chatter(GameElement):
Attributes
'''
super(Chatter,self).__init__(elem,self.TAG,node=node,**kwargs)
+
+registerElement(Chatter)
# --------------------------------------------------------------------
class KeyNamer(GameElement):
@@ -730,6 +853,8 @@ class KeyNamer(GameElement):
'''
super(KeyNamer,self).__init__(elem,self.TAG,node=node,**kwargs)
+registerElement(KeyNamer)
+
# --------------------------------------------------------------------
# <VASSAL.build.module.GlobalOptions
@@ -883,6 +1008,7 @@ class GlobalOptions(GameElement):
return retd
+registerElement(GlobalOptions)
# --------------------------------------------------------------------
class Option(Element):
@@ -894,6 +1020,8 @@ class Option(Element):
def getGlobalOptions(self):
return self.getParent(GlobalOptions)
+registerElement(Option)
+
# --------------------------------------------------------------------
class Preference(Element):
PREFS = 'VASSAL.preferences.'
@@ -947,6 +1075,9 @@ class IntPreference(Preference):
default = str(default),
desc = desc,
tab = tab)
+
+registerElement(IntPreference)
+
# --------------------------------------------------------------------
class FloatPreference(Preference):
TAG = Preference.PREFS+'DoublePreference'
@@ -964,6 +1095,9 @@ class FloatPreference(Preference):
default = str(default),
desc = desc,
tab = tab)
+
+registerElement(FloatPreference)
+
# --------------------------------------------------------------------
class BoolPreference(Preference):
TAG = Preference.PREFS+'BooleanPreference'
@@ -982,6 +1116,9 @@ class BoolPreference(Preference):
else 'false'),
desc = desc,
tab = tab)
+
+registerElement(BoolPreference)
+
# --------------------------------------------------------------------
class StrPreference(Preference):
TAG = Preference.PREFS+'StringPreference'
@@ -999,6 +1136,9 @@ class StrPreference(Preference):
default = default,
desc = desc,
tab = tab)
+
+registerElement(StrPreference)
+
# --------------------------------------------------------------------
class TextPreference(Preference):
TAG = Preference.PREFS+'TextPreference'
@@ -1017,6 +1157,9 @@ class TextPreference(Preference):
.replace('\n','&#10;')),
desc = desc,
tab = tab)
+
+registerElement(TextPreference)
+
# --------------------------------------------------------------------
class EnumPreference(Preference):
TAG = Preference.PREFS+'EnumPreference'
@@ -1042,39 +1185,42 @@ class EnumPreference(Preference):
tab = tab,
list = sl)
+
+registerElement(EnumPreference)
+
# --------------------------------------------------------------------
# CurrentMap == &quot;Board&quot;
-class Inventory(GameElement):
+class Inventory(ToolbarElement,GameElementService):
TAG = Element.MODULE+'Inventory'
def __init__(self,doc,node=None,
- canDisable = False,
- centerOnPiece = True,
- disabledIcon = '',
- drawPieces = True,
- foldersOnly = False,
- forwardKeystroke = True,
- groupBy = '',
- hotkey = key('I',ALT),
- icon = '/images/inventory.gif',
- include = '{}',
- launchFunction = 'functionHide',
- leafFormat = '$PieceName$',
- name = '',
- nonLeafFormat = '$PropertyValue$',
- pieceZoom = '0.33',
- pieceZoom2 = '0.5',
- pieceZoom3 = '0.6',
- propertyGate = '',
- refreshHotkey = key('I',ALT_SHIFT),
- showMenu = True,
- sides = '',
- sortFormat = '$PieceName$',
- sortPieces = True,
- sorting = 'alpha',
- text = '',
- tooltip = 'Show inventory of all pieces',
- zoomOn = False):
+ name = '',
+ icon = '/images/inventory.gif',
+ text = '',
+ tooltip = 'Show inventory of all pieces',
+ hotkey = key('I',ALT),
+ canDisable = False,
+ propertyGate = '',
+ disabledIcon = '',
+ centerOnPiece = True,
+ drawPieces = True,
+ foldersOnly = False,
+ forwardKeystroke = True,
+ groupBy = '',
+ include = '{}',
+ launchFunction = 'functionHide',
+ leafFormat = '$PieceName$',
+ nonLeafFormat = '$PropertyValue$',
+ pieceZoom = '0.33',
+ pieceZoom2 = '0.5',
+ pieceZoom3 = '0.6',
+ refreshHotkey = key('I',ALT_SHIFT),
+ showMenu = True,
+ sides = '',
+ sortFormat = '$PieceName$',
+ sortPieces = True,
+ sorting = 'alpha',
+ zoomOn = False):
super(Inventory,self).__init__(doc,self.TAG,node=node,
canDisable = canDisable,
centerOnPiece = centerOnPiece,
@@ -1104,16 +1250,7 @@ class Inventory(GameElement):
tooltip = tooltip,
zoomOn = zoomOn)
-
-
-
-
-
-
-
-
-
-
+registerElement(Inventory)
# --------------------------------------------------------------------
class Prototypes(GameElement):
@@ -1149,17 +1286,21 @@ class Prototypes(GameElement):
'''
return self.getElementsByKey(Prototype,'name',asdict=asdict)
-
-
+registerElement(Prototypes)
# --------------------------------------------------------------------
-class DiceButton(GameElement):
+class DiceButton(ToolbarElement,GameElementService):
TAG=Element.MODULE+'DiceButton'
def __init__(self,elem,node=None,
- addToTotal = 0,
- canDisable = False,
- hotkey = key('6',ALT),
+ name = '1d6',
+ tooltip = 'Roll a 1d6',
+ text = '1d6',
icon = '/images/die.gif',
+ hotkey = key('6',ALT),
+ canDisable = False,
+ propertyGate = '',
+ disabledIcon = '',
+ addToTotal = 0,
keepCount = 1,
keepDice = False,
keepOption = '>',
@@ -1169,19 +1310,16 @@ class DiceButton(GameElement):
lockSides = False,
nDice = 1,
nSides = 6,
- name = '1d6',
plus = 0,
prompt = False,
- propertyGate = '',
- reportFormat = '** $name$ = $result$ *** <$PlayerName$>;',
+ reportFormat = '$name$ = $result$',
reportTotal = False,
- sortDice = False,
- text = '1d6',
- tooltip = 'Roll a 1d6'):
+ sortDice = False):
super(DiceButton,self).\
__init__(elem,self.TAG,node=node,
addToTotal = addToTotal,
canDisable = canDisable,
+ disabledIcon = disabledIcon,
hotkey = hotkey,
icon = icon,
keepCount = keepCount,
@@ -1203,24 +1341,27 @@ class DiceButton(GameElement):
text = text,
tooltip = tooltip)
+registerElement(DiceButton)
+
# --------------------------------------------------------------------
class GameMassKey(GlobalKey,GameElementService):
TAG = Element.MODULE+'GlobalKeyCommand'
def __init__(self,map,node=None,
name = '',
- buttonHotkey = '',
- hotkey = '',
buttonText = '',
+ tooltip = '',
+ icon = '',
canDisable = False,
+ propertyGate = '',
+ disabledIcon = '',
+ buttonHotkey = '',
+ hotkey = '',
deckCount = '-1',
filter = '',
- propertyGate = '',
reportFormat = '',
reportSingle = False,
singleMap = True,
- target = GlobalKey.SELECTED,
- tooltip = '',
- icon = ''):
+ target = GlobalKey.SELECTED):
'''Default targets are selected units'''
super(GameMassKey,self).\
__init__(map,
@@ -1241,6 +1382,8 @@ class GameMassKey(GlobalKey,GameElementService):
tooltip = tooltip,
icon = icon)
+registerElement(GameMassKey)
+
# --------------------------------------------------------------------
class StartupMassKey(GlobalKey,GameElementService):
TAG = Element.MODULE+'StartupGlobalKeyCommand'
@@ -1287,21 +1430,24 @@ class StartupMassKey(GlobalKey,GameElementService):
if node is None:
self['whenToApply'] = whenToApply
+registerElement(StartupMassKey)
+
# --------------------------------------------------------------------
class Menu(GameElement):
TAG = Element.MODULE+'ToolbarMenu'
def __init__(self,
game,
node = None,
+ name = '',
+ tooltip = '',
+ text = '', # Menu name
canDisable = False,
- description = '',
+ propertyGate = '',
disabledIcon = '',
+ description = '',
hotkey = '',
icon = '',
- menuItems = [],# Button texts
- propertyGate = '',
- text = '',# Menu name
- tooltip = ''):
+ menuItems = []):
if len(description) <= 0 and len(tooltip) > 0:
description = tooltip
if len(tooltip) <= 0 and len(description) > 0:
@@ -1310,6 +1456,7 @@ class Menu(GameElement):
__init__(game,
self.TAG,
node = node,
+ name = name,
canDisable = canDisable,
description = description,
disabledIcon = disabledIcon,
@@ -1320,6 +1467,8 @@ class Menu(GameElement):
text = text,
tooltip = tooltip)
+registerElement(Menu)
+
# --------------------------------------------------------------------
class SymbolicDice(GameElement):
@@ -1370,6 +1519,8 @@ class SymbolicDice(GameElement):
def getSymbolicDice(self):
return self.getParent(SymbolicDice)
+registerElement(SymbolicDice)
+
# --------------------------------------------------------------------
class SpecialDie(GameElement):
@@ -1399,8 +1550,7 @@ class SpecialDie(GameElement):
def getSymbolicDice(self):
return self.getParent(SymbolicDice)
-
-
+registerElement(SpecialDie)
# --------------------------------------------------------------------
class DieFace(GameElement):
@@ -1421,6 +1571,9 @@ class DieFace(GameElement):
def getSpecialDie(self):
return self.getParent(SpecialDie)
+
+registerElement(DieFace)
+
#
# EOF
#
@@ -1451,6 +1604,223 @@ class MapElement(Element,MapElementService):
# --------------------------------------------------------------------
+class PieceLayers(MapElement):
+ TAG=Element.MAP+'LayeredPieceCollection'
+ def __init__(self,map,node=None,
+ property = 'PieceLayer',
+ description = '',
+ layerOrder = []):
+ super(PieceLayers,self).__init__(map,self.TAG,node=node,
+ property = property,
+ description = description,
+ layerOrder = ','.join(layerOrder))
+
+ def addControl(self,**kwargs):
+ '''Add `LayerControl` element to this
+
+ Parameters
+ ----------
+ kwargs : dict
+ Dictionary of attribute key-value pairs
+ Returns
+ -------
+ element : LayerControl
+ The added element
+ '''
+ return self.add(LayerControl,**kwargs)
+ def getControls(self,asdict=True):
+ '''Get all `LayerControl` element(s) from this
+
+ Parameters
+ ----------
+ asdict : bool
+ If `True`, return a dictonary that maps name to
+ `LayerControl` elements. If `False`, return a list of all
+ `LayerControl` children.
+
+ Returns
+ -------
+ children : dict or list
+ Dictionary or list of `LayerControl` children
+
+ '''
+ return self.getElementsByKey(LayerControl,'name',asdict)
+
+registerElement(PieceLayers)
+
+# --------------------------------------------------------------------
+class LayerControl(MapElement):
+ TAG=Element.MAP+'LayerControl'
+ CYCLE_UP='Rotate Layer Order Up'
+ CYCLE_DOWN='Rotate Layer Order Down'
+ ENABLE='Make Layer Active'
+ DISABLE='Make Layer Inactive'
+ TOGGLE='Switch Layer between Active and Inactive'
+ RESET='Reset All Layers'
+ def __init__(self,col,node=None,
+ name = '',
+ tooltip = '',
+ text = '',
+ hotkey = '',
+ icon = '',
+ canDisable = False,
+ propertyGate = '', #Property name, disable when property false
+ disabledIcon = '',
+ command = TOGGLE,
+ skip = False,
+ layers = [],
+ description = ''):
+ super(LayerControl,self).__init__(col,self.TAG,node=node,
+ name = name,
+ tooltip = tooltip,
+ text = text,
+ buttonText = text,
+ hotkey = hotkey,
+ icon = icon,
+ canDisable = canDisable,
+ propertyGate = propertyGate,
+ disabledIcon = disabledIcon,
+ command = command,
+ skip = skip,
+ layers = ','.join(layers),
+ description = description)
+
+ def getLayers(self):
+ '''Get map - either a Map or WidgetMap'''
+ return self.getParentOfClass([PieceLayers])
+
+registerElement(LayerControl)
+
+
+# --------------------------------------------------------------------
+class LineOfSight(MapElement):
+ TAG=Element.MAP+'LOS_Thread'
+ ROUND_UP = 'Up'
+ ROUND_DOWN = 'Down'
+ ROUND_NEAREST = 'Nearest whole number'
+ FROM_LOCATION = 'FromLocation'
+ TO_LOCATION = 'ToLocation'
+ CHECK_COUNT = 'NumberOfLocationsChecked'
+ CHECK_LIST = 'AllLocationsChecked'
+ RANGE = 'Range'
+ NEVER = 'Never'
+ ALWAYS = 'Always'
+ WHEN_PERSISTENT = 'When persistent'
+ CTRL_CLICK = 'Cltr-Click & Drag'
+
+ def __init__(self,map,
+ node=None,
+ threadName = 'LOS',
+ hotkey = key('L',ALT),
+ tooltip = 'Trace line of sight',
+ iconName = '/images/thread.gif', #'los-icon.png',
+ label = '',
+ snapLOS = False,
+ snapStart = True,
+ snapEnd = True,
+ report = (f'{{"Range from "+{FROM_LOCATION}'
+ f'+" to "+{TO_LOCATION}+" is "'
+ f'+{RANGE}+" (via "+{CHECK_LIST}+")"}}'),
+ persistent = CTRL_CLICK,
+ persistentIconName = '/images/thread.gif',
+ globl = ALWAYS,
+ losThickness = 3,
+ threadColor = rgb(255,0,0),
+ drawRange = True,
+ # rangeBg = rgb(255,255,255),
+ # rangeFg = rgb(0,0,0),
+ rangeScale = 0,
+ hideCounters = True,
+ hideOpacity = 50,
+ round = ROUND_UP,
+ canDisable = False,
+ propertyGate = '',
+ disabledIcon = ''):
+ '''Make Line of Sight interface
+
+ Parameters
+ ----------
+ threadName : str
+ Name of interface
+ hotkey : str
+ Start LOS key
+ tooltip : str
+ Tool tip text
+ iconName : str
+ Path to button icon
+ label : str
+ Button text
+ snapLOS : bool
+ Wether to snap both ends
+ snapStart : bool
+ Snap to start
+ snapEnd: bool
+ Snap to end
+ report : str
+ Report format
+ persistent : str
+ When persistent
+ persistentIconName : str
+ Icon when persistent(?)
+ globl : str
+ Visisble to opponents
+ losThickness : int
+ Thickness in pixels
+ losColor : str
+ Colour of line
+ drawRange : bool
+ Draw the range next to LOST thread
+ rangeBg : str
+ Range backgroung colour
+ rangeFg : str
+ Range foregrond colour
+ rangeScale : int
+ Scale of range - pixels per unit
+ round : str
+ How to round range
+ hideCounters :bool
+ If true, hide counters while making thread
+ hideOpacity : int
+ Opacity of hidden counters (percent)
+ canDisable : bool
+ IF true, then can be hidden
+ propertyGate : str
+ Name of property. When that property is TRUE, then the
+ interface is disabled. Must be a property name, not an expression.
+ disabledIcon : str
+ Icon to use when disabled
+ '''
+ super(LineOfSight,self).__init__(map,self.TAG,
+ node = node,
+ threadName = threadName,
+ hotkey = hotkey,
+ tooltip = tooltip,
+ iconName = iconName,
+ label = label,
+ snapLOS = snapLOS,
+ snapStart = snapStart,
+ snapEnd = snapEnd,
+ report = report,
+ persistent = persistent,
+ persistentIconName = persistentIconName,
+ losThickness = losThickness,
+ threadColor = threadColor,
+ drawRange = drawRange,
+ #rangeBg = rangeBg,
+ #rangeFg = rangeFg,
+ rangeScale = rangeScale,
+ hideCounters = hideCounters,
+ hideOpacity = hideOpacity,
+ round = round,
+ canDisable = canDisable,
+ propertyGate = propertyGate,
+ disabledIcon = disabledIcon)
+ self.setAttribute('global',globl)
+
+
+registerElement(LineOfSight)
+
+# --------------------------------------------------------------------
class StackMetrics(MapElement):
TAG=Element.MAP+'StackMetrics'
def __init__(self,map,node=None,
@@ -1474,6 +1844,8 @@ class StackMetrics(MapElement):
unexSepY = unexSepY,
up = up)
+registerElement(StackMetrics)
+
# --------------------------------------------------------------------
class ImageSaver(MapElement):
TAG=Element.MAP+'ImageSaver'
@@ -1491,6 +1863,9 @@ class ImageSaver(MapElement):
icon = icon,
propertyGate = propertyGate,
tooltip = tooltip)
+
+registerElement(ImageSaver)
+
# --------------------------------------------------------------------
class TextSaver(MapElement):
TAG=Element.MAP+'TextSaver'
@@ -1509,6 +1884,7 @@ class TextSaver(MapElement):
propertyGate = propertyGate,
tooltip = tooltip)
+registerElement(TextSaver)
# --------------------------------------------------------------------
class ForwardToChatter(MapElement):
@@ -1516,30 +1892,40 @@ class ForwardToChatter(MapElement):
def __init__(self,map,node=None,**kwargs):
super(ForwardToChatter,self).__init__(map,self.TAG,node=node,**kwargs)
+registerElement(ForwardToChatter)
+
# --------------------------------------------------------------------
class MenuDisplayer(MapElement):
TAG=Element.MAP+'MenuDisplayer'
def __init__(self,map,node=None,**kwargs):
super(MenuDisplayer,self).__init__(map,self.TAG,node=node,**kwargs)
+registerElement(MenuDisplayer)
+
# --------------------------------------------------------------------
class MapCenterer(MapElement):
TAG=Element.MAP+'MapCenterer'
def __init__(self,map,node=None,**kwargs):
super(MapCenterer,self).__init__(map,self.TAG,node=node,**kwargs)
+registerElement(MapCenterer)
+
# --------------------------------------------------------------------
class StackExpander(MapElement):
TAG=Element.MAP+'StackExpander'
def __init__(self,map,node=None,**kwargs):
super(StackExpander,self).__init__(map,self.TAG,node=node,**kwargs)
+registerElement(StackExpander)
+
# --------------------------------------------------------------------
class PieceMover(MapElement):
TAG=Element.MAP+'PieceMover'
def __init__(self,map,node=None,**kwargs):
super(PieceMover,self).__init__(map,self.TAG,node=node,**kwargs)
+registerElement(PieceMover)
+
# --------------------------------------------------------------------
class SelectionHighlighters(MapElement):
TAG=Element.MAP+'SelectionHighlighters'
@@ -1547,12 +1933,16 @@ class SelectionHighlighters(MapElement):
super(SelectionHighlighters,self).\
__init__(map,self.TAG,node=node,**kwargs)
+registerElement(SelectionHighlighters)
+
# --------------------------------------------------------------------
class KeyBufferer(MapElement):
TAG=Element.MAP+'KeyBufferer'
def __init__(self,map,node=None,**kwargs):
super(KeyBufferer,self).__init__(map,self.TAG,node=node,**kwargs)
+registerElement(KeyBufferer)
+
# --------------------------------------------------------------------
class HighlightLastMoved(MapElement):
TAG=Element.MAP+'HighlightLastMoved'
@@ -1565,6 +1955,8 @@ class HighlightLastMoved(MapElement):
enabled = enabled,
thickness = thickness)
+registerElement(HighlightLastMoved)
+
# --------------------------------------------------------------------
class CounterDetailViewer(MapElement):
TAG=Element.MAP+'CounterDetailViewer'
@@ -1587,7 +1979,7 @@ class CounterDetailViewer(MapElement):
extraTextPadding = 0,
fgColor = rgb(0,0,0),
fontSize = 9,
- graphicsZoom = 1.0,
+ graphicsZoom = 1.0,# Zoom on counters
hotkey = key('\n',0),
layerList = '',
minDisplayPieces = 2,
@@ -1649,6 +2041,8 @@ class CounterDetailViewer(MapElement):
verticalTopText = verticalTopText,
zoomlevel = zoomlevel)
+registerElement(CounterDetailViewer)
+
# --------------------------------------------------------------------
class GlobalMap(MapElement):
TAG=Element.MAP+'GlobalMap'
@@ -1668,6 +2062,8 @@ class GlobalMap(MapElement):
scale = scale,
tooltip = 'Show/Hide overview window')
+registerElement(GlobalMap)
+
# --------------------------------------------------------------------
class Zoomer(MapElement):
TAG = Element.MAP+'Zoomer'
@@ -1687,6 +2083,7 @@ class Zoomer(MapElement):
zoomOutKey = key('-'),
zoomPickKey = key('='),
zoomStart = 3):
+
'''Zoom start is counting from the back (with default zoom levels,
and zoom start, the default zoom is 1'''
lvls = ','.join([str(z) for z in zoomLevels])
@@ -1707,6 +2104,8 @@ class Zoomer(MapElement):
zoomPickKey = zoomPickKey,
zoomStart = zoomStart)
+registerElement(Zoomer)
+
# --------------------------------------------------------------------
class HidePiecesButton(MapElement):
TAG=Element.MAP+'HidePiecesButton'
@@ -1724,6 +2123,8 @@ class HidePiecesButton(MapElement):
showingIcon = showingIcon,
tooltip = tooltip)
+registerElement(HidePiecesButton)
+
# --------------------------------------------------------------------
class MassKey(GlobalKey,MapElementService):
TAG = Element.MAP+'MassKeyCommand'
@@ -1760,6 +2161,7 @@ class MassKey(GlobalKey,MapElementService):
tooltip = tooltip,
icon = icon)
+registerElement(MassKey)
# --------------------------------------------------------------------
class Flare(MapElement):
@@ -1783,10 +2185,13 @@ class Flare(MapElement):
flarePulsesPerSec = flarePulsesPerSec,
reportFormat = '')
+registerElement(Flare)
+
# --------------------------------------------------------------------
class AtStart(MapElement):
TAG = Element.MODULE+'map.SetupStack'
- def __init__(self,map,node=None,
+ def __init__(self,map,
+ node = None,
name = '',
location = '',
useGridLocation = True,
@@ -1861,6 +2266,8 @@ class AtStart(MapElement):
'''
return self.getElementsWithKey(PieceSlot,'entryName',asdict)
+registerElement(AtStart)
+
#
# EOF
#
@@ -1894,6 +2301,7 @@ class GlobalProperties(Element):
def getProperties(self):
return getElementsByKey(GlobalProperty,'name')
+registerElement(GlobalProperties)
# --------------------------------------------------------------------
class GlobalProperty(Element):
@@ -1919,6 +2327,7 @@ class GlobalProperty(Element):
def getGlobalProperties(self):
return self.getParent(GlobalProperties)
+registerElement(GlobalProperty)
#
# EOF
@@ -2099,7 +2508,8 @@ class TurnTrack(TurnLevel):
return []
-
+registerElement(TurnTrack)
+
# --------------------------------------------------------------------
class TurnCounter(TurnLevel):
TAG = Element.MODULE+"turn.CounterTurnLevel"
@@ -2118,6 +2528,8 @@ class TurnCounter(TurnLevel):
loopLimit = loopLimit,
turnFormat = turnFormat)
+registerElement(TurnCounter)
+
# --------------------------------------------------------------------
class TurnList(TurnLevel):
TAG = Element.MODULE+"turn.ListTurnLevel"
@@ -2135,6 +2547,8 @@ class TurnList(TurnLevel):
configList = configList,
turnFormat = turnFormat)
+registerElement(TurnList)
+
# --------------------------------------------------------------------
class TurnGlobalHotkey(Element):
TAG = Element.MODULE+'turn.TurnGlobalHotkey'
@@ -2172,6 +2586,8 @@ class TurnGlobalHotkey(Element):
'''Get the turn track'''
return self.getParent(TurnTrack)
+registerElement(TurnGlobalHotkey)
+
#
# EOF
#
@@ -2316,6 +2732,7 @@ class Documentation(GameElement):
return txt
+registerElement(Documentation)
# --------------------------------------------------------------------
class AboutScreen(Element):
@@ -2343,6 +2760,8 @@ class AboutScreen(Element):
'''Get Parent element'''
return self.getParent(Documentation)
+registerElement(AboutScreen)
+
# --------------------------------------------------------------------
class BrowserPDFFile(Element):
TAG = Element.MODULE+'documentation.BrowserPDFFile'
@@ -2368,6 +2787,8 @@ class BrowserPDFFile(Element):
'''Get Parent element'''
return self.getParent(Documentation)
+registerElement(BrowserPDFFile)
+
# --------------------------------------------------------------------
class HelpFile(Element):
TAG = Element.MODULE+'documentation.HelpFile'
@@ -2400,6 +2821,8 @@ class HelpFile(Element):
'''Get Parent element'''
return self.getParent(Documentation)
+registerElement(HelpFile)
+
# --------------------------------------------------------------------
class BrowserHelpFile(Element):
TAG = Element.MODULE+'documentation.BrowserHelpFile'
@@ -2427,7 +2850,9 @@ class BrowserHelpFile(Element):
def getDocumentation(self):
'''Get Parent element'''
return self.getParent(Documentation)
-
+
+registerElement(BrowserHelpFile)
+
# --------------------------------------------------------------------
class Tutorial(Element):
TAG = Element.MODULE+'documentation.Tutorial'
@@ -2468,6 +2893,8 @@ class Tutorial(Element):
'''Get Parent element'''
return self.getParent(Documentation)
+registerElement(Tutorial)
+
#
# EOF
@@ -2517,6 +2944,8 @@ class PlayerRoster(GameElement):
'''Encode for save'''
return ['PLAYER\ta\ta\t<observer>']
+registerElement(PlayerRoster)
+
# --------------------------------------------------------------------
class PlayerSide(Element):
TAG = 'entry'
@@ -2540,6 +2969,8 @@ class PlayerSide(Element):
'''Get Parent element'''
return self.getParent(PlayerRoster)
+registerElement(PlayerSide)
+
#
# EOF
@@ -2614,7 +3045,9 @@ class ChessClock(Element):
def getControl(self):
'''Get Parent element'''
return self.getParent(ChessClockControl)
-
+
+registerElement(ChessClock)
+
# ====================================================================
class ChessClockControl(GameElement):
TAG=Element.MODULE+'ChessClockControl'
@@ -2727,6 +3160,7 @@ class ChessClockControl(GameElement):
'''Return dictionary of clocs'''
return self.getElementsByKey(ChessClock,'side',asdict)
+registerElement(ChessClockControl)
#
# EOF
@@ -2961,6 +3395,8 @@ class PieceWindow(GameElement,WidgetElement):
tooltip = tooltip,
icon = icon)
+registerElement(PieceWindow)
+
# --------------------------------------------------------------------
class ComboWidget(Element,WidgetElement):
TAG=Element.WIDGET+'BoxWidget'
@@ -2972,6 +3408,8 @@ class ComboWidget(Element,WidgetElement):
width = width,
height = height)
+registerElement(ComboWidget)
+
# --------------------------------------------------------------------
class TabWidget(Element,WidgetElement):
TAG=Element.WIDGET+'TabWidget'
@@ -2981,6 +3419,8 @@ class TabWidget(Element,WidgetElement):
node = node,
entryName = entryName)
+registerElement(TabWidget)
+
# --------------------------------------------------------------------
class ListWidget(Element,WidgetElement):
TAG=Element.WIDGET+'ListWidget'
@@ -2997,6 +3437,8 @@ class ListWidget(Element,WidgetElement):
scale = scale,
divider = divider)
+registerElement(ListWidget)
+
# --------------------------------------------------------------------
class PanelWidget(Element,WidgetElement):
TAG=Element.WIDGET+'PanelWidget'
@@ -3011,6 +3453,8 @@ class PanelWidget(Element,WidgetElement):
nColumns = nColumns,
vert = vert)
+registerElement(PanelWidget)
+
# --------------------------------------------------------------------
class MapWidget(Element):
TAG=Element.WIDGET+'MapWidget'
@@ -3046,6 +3490,8 @@ class MapWidget(Element):
'''
return self.getElementsByKey(WidgetMap,'mapName',asdict=asdict)
+registerElement(MapWidget)
+
#
# EOF
#
@@ -3258,6 +3704,8 @@ class HexGrid(BaseGrid):
width = self.getZone().getWidth()
return floor(width / self.getDeltaY() + .5)
+registerElement(HexGrid)
+
# --------------------------------------------------------------------
class SquareGrid(BaseGrid):
TAG = Element.BOARD+'SquareGrid'
@@ -3307,6 +3755,8 @@ class SquareGrid(BaseGrid):
width = self.getZone().getWidth()
return floor(width / self.getDeltaX() + .5)
+registerElement(SquareGrid)
+
# --------------------------------------------------------------------
class HexNumbering(BaseNumbering):
TAG = Element.BOARD+'mapgrid.HexGridNumbering'
@@ -3368,6 +3818,8 @@ class HexNumbering(BaseNumbering):
return x,y
+registerElement(HexNumbering)
+
# --------------------------------------------------------------------
class SquareNumbering(BaseNumbering):
TAG = Element.BOARD+'mapgrid.SquareGridNumbering'
@@ -3395,6 +3847,7 @@ class SquareNumbering(BaseNumbering):
return x,y
+registerElement(SquareNumbering)
# --------------------------------------------------------------------
class RegionGrid(Element):
@@ -3452,6 +3905,8 @@ class RegionGrid(Element):
return None
+registerElement(RegionGrid)
+
# --------------------------------------------------------------------
class Region(Element):
TAG = Element.BOARD+'Region'
@@ -3527,6 +3982,8 @@ class Region(Element):
return b.getMap()
return None
+registerElement(Region)
+
#
# EOF
#
@@ -3579,7 +4036,7 @@ class ZonedGrid(Element):
children : list
List of `Highligter` children (even if `single=True`)
'''
- return self.getAllElements(ZonedGridHighliger,single=single)
+ return self.getAllElements(ZonedGridHighlighter,single=single)
def addZone(self,**kwargs):
'''Add a `Zone` element to this
@@ -3607,6 +4064,8 @@ class ZonedGrid(Element):
'''
return self.getElementsByKey(Zone,'name',asdict=asdict)
+registerElement(ZonedGrid)
+
# --------------------------------------------------------------------
class ZonedGridHighlighter(Element):
TAG=Element.BOARD+'mapgrid.ZonedGridHighlighter'
@@ -3614,6 +4073,96 @@ class ZonedGridHighlighter(Element):
super(ZonedGridHighlighter,self).__init__(zoned,self.TAG,node=node)
def getZonedGrid(self): return self.getParent(ZonedGrid)
+ def addZoneHighlight(self,**kwargs):
+ '''Add a `ZoneHighlight` element to this
+
+ Parameters
+ ----------
+ kwargs : dict
+ Dictionary of attribute key-value pairs
+ Returns
+ -------
+ element : ZoneHighlight
+ The added element
+ '''
+ return self.add(ZoneHighlight,**kwargs)
+ def getZoneHighlights(self,asdict=True):
+ '''Get all ZoneHighlight element(s) from this
+
+ Parameters
+ ----------
+ asdict : bool
+ If `True`, return a dictonary that maps key to `Zone` elements. If `False`, return a list of all Zone` children.
+ Returns
+ -------
+ children : dict or list
+ Dictionary or list of `Zone` children
+ '''
+ return self.getElementsByKey(ZoneHighlight,'name',asdict=asdict)
+
+registerElement(ZonedGridHighlighter)
+
+# --------------------------------------------------------------------
+class ZoneHighlight(Element):
+ TAG=Element.BOARD+'mapgrid.ZoneHighlight'
+ FULL='Entire Zone',
+ BORDER='Zone Border',
+ PLAIN='Plain',
+ STRIPED='Striped'
+ CROSS='Crosshatched',
+ TILES='Tiled Image'
+ def __init__(self,
+ highlighters,
+ node = None,
+ name = '',
+ color = rgb(255,0,0),
+ coverage = FULL,
+ width = 1,
+ style = PLAIN,
+ image = '',
+ opacity = 50):
+ super(ZoneHighlight,self).__init__(highlighters,
+ self.TAG,
+ node = node,
+ name = name,
+ color = color,
+ coverage = coverage,
+ width = width,
+ style = style,
+ image = image,
+ opacity = int(opacity))
+ def getZonedGridHighlighter(self):
+ return self.getParent(ZonedGridHighlighter)
+
+
+registerElement(ZoneHighlight)
+
+
+# --------------------------------------------------------------------
+class ZoneProperty(Element):
+ TAG = Element.MODULE+'properties.ZoneProperty'
+ def __init__(self,zone,node=None,
+ name = '',
+ initialValue = '',
+ isNumeric = False,
+ min = "null",
+ max = "null",
+ wrap = False,
+ description = ""):
+ super(ZoneProperty,self).__init__(zone,self.TAG,
+ node = node,
+ name = name,
+ initialValue = initialValue,
+ isNumeric = isNumeric,
+ min = min,
+ max = max,
+ wrap = wrap,
+ description = description)
+
+ def getZone(self):
+ return self.getParent(Zone)
+
+registerElement(ZoneProperty)
# --------------------------------------------------------------------
class Zone(Element):
@@ -3693,6 +4242,19 @@ class Zone(Element):
The added element
'''
return self.add(RegionGrid,**kwargs)
+ def addProperty(self,**kwargs):
+ '''Add a `Property` element to this
+
+ Parameters
+ ----------
+ kwargs : dict
+ Dictionary of attribute key-value pairs
+ Returns
+ -------
+ element : Property
+ The added element
+ '''
+ return self.add(ZoneProperty,**kwargs)
def getHexGrids(self,single=True):
'''Get all or a sole `HexGrid` element(s) from this
@@ -3758,6 +4320,17 @@ class Zone(Element):
if g is not None: return g
return g
+ def getProperties(self):
+ '''Get all `Property` element from this
+
+ Parameters
+ ----------
+ Returns
+ -------
+ children : dict
+ dict of `Property` children
+ '''
+ return getElementsByKey(ZoneProperty,'name')
def getPath(self):
p = self['path'].split(';')
@@ -3785,6 +4358,8 @@ class Zone(Element):
def getYOffset(self):
return self.getBB()[1]
+registerElement(Zone)
+
#
# EOF
#
@@ -3879,6 +4454,8 @@ class BoardPicker(MapElement):
return ret
+registerElement(BoardPicker)
+
# --------------------------------------------------------------------
class Setup(Element):
TAG = 'setup'
@@ -3901,7 +4478,9 @@ class Setup(Element):
self.addText(txt)
def getPicker(self): return self.getParent(BoardPicker)
-
+
+registerElement(Setup)
+
# --------------------------------------------------------------------
class Board(Element):
TAG = Element.PICKER+'Board'
@@ -3982,6 +4561,7 @@ class Board(Element):
return int(self['height'])
return 0
+registerElement(Board)
#
# EOF
@@ -4340,6 +4920,57 @@ class BaseMap(Element):
picker = self.getPicker()
if picker is None: return None
return picker[0].getBoards(asdict=asdict)
+ def getLayers(self,asdict=True):
+ '''Get all `PieceLayer` element(s) from this
+
+ Parameters
+ ----------
+ asdict : bool
+ If `True`, return a dictonary that maps property name
+ `PieceLayers` elements. If `False`, return a list of all
+ `PieceLayers` children.
+
+ Returns
+ -------
+ children : dict or list
+ Dictionary or list of `PieceLayers` children
+
+ '''
+ return self.getElementsByKey(PieceLayers,'property',asdict)
+ def getMenus(self,asdict=True):
+ '''Get all Menu element(s) from this
+
+ Parameters
+ ----------
+ asdict : bool
+ If `True`, return a dictonary that maps key to `Board`
+ elements. If `False`, return a list of all Board`
+ children.
+
+ Returns
+ -------
+ children : dict or list
+ Dictionary or list of `Board` children
+
+ '''
+ return self.getElementsByKey(Menu,'name',asdict)
+ def getLOSs(self,asdict=True):
+ '''Get all Menu element(s) from this
+
+ Parameters
+ ----------
+ asdict : bool
+ If `True`, return a dictonary that maps key to `Board`
+ elements. If `False`, return a list of all Board`
+ children.
+
+ Returns
+ -------
+ children : dict or list
+ Dictionary or list of `Board` children
+
+ '''
+ return self.getElementsByKey(LineOfSight,'threadName',asdict)
def addBoardPicker(self,**kwargs):
'''Add a `BoardPicker` element to this
@@ -4600,6 +5231,47 @@ class BaseMap(Element):
The added element
'''
return self.add(AtStart,**kwargs)
+
+
+ def addLayers(self,**kwargs):
+ '''Add `PieceLayers` element to this
+
+ Parameters
+ ----------
+ kwargs : dict
+ Dictionary of attribute key-value pairs
+ Returns
+ -------
+ element : PieceLayers
+ The added element
+ '''
+ return self.add(PieceLayers,**kwargs)
+ def addMenu(self,**kwargs):
+ '''Add a `Menu` element to this
+
+ Parameters
+ ----------
+ kwargs : dict
+ Dictionary of attribute key-value pairs
+ Returns
+ -------
+ element : Menu
+ The added element
+ '''
+ return self.add(Menu,**kwargs)
+ def addLOS(self,**kwargs):
+ '''Add a `Menu` element to this
+
+ Parameters
+ ----------
+ kwargs : dict
+ Dictionary of attribute key-value pairs
+ Returns
+ -------
+ element : Menu
+ The added element
+ '''
+ return self.add(LineOfSight,**kwargs)
# --------------------------------------------------------------------
class Map(BaseMap):
@@ -4657,7 +5329,9 @@ class Map(BaseMap):
def getGame(self):
return self.getParent(Game)
-
+
+registerElement(Map)
+
# --------------------------------------------------------------------
class WidgetMap(BaseMap):
TAG = Element.WIDGET+'WidgetMap'
@@ -4669,6 +5343,8 @@ class WidgetMap(BaseMap):
def getMapWidget(self):
return self.getParent(MapWidget)
+registerElement(WidgetMap)
+
#
# EOF
@@ -4721,7 +5397,7 @@ class ChartWindow(GameElement,WidgetElement):
'''
return self.getElementsById(Chart,'chartName',asdict=asdict)
-
+registerElement(ChartWindow)
# --------------------------------------------------------------------
class Chart(Element):
@@ -4735,6 +5411,8 @@ class Chart(Element):
description = description,
fileName = fileName)
+registerElement(Chart)
+
#
# EOF
#
@@ -4766,7 +5444,7 @@ class Trait:
this actually holds state that isn't reflected elsewhere in
the DOM. This means that the data here is local to the
object. So when we do
-
+
piece = foo.getPieceSlots()[0]
traits = p.getTraits()
for trait in traits:
@@ -5040,6 +5718,15 @@ class WithTraits(Element):
Identifier
'''
+ last = traits[-1]
+ # A little hackish to use the name of the class, but needed
+ # because of imports into patch scripts.
+ if not isinstance(last,BasicTrait) and \
+ not last.__class__.__name__.endswith('BasicTrait'):
+ from sys import stderr
+ print(f'Warning - last trait NOT a BasicTrait, but a {type(last)}',
+ file=stderr)
+
types = []
states = []
for trait in traits:
@@ -5165,7 +5852,9 @@ class DummyWithTraits(WithTraits):
if parent is not None:
parent.remove(self)
-
+
+registerElement(DummyWithTraits)
+
# --------------------------------------------------------------------
class PieceSlot(WithTraits):
TAG = Element.WIDGET+'PieceSlot'
@@ -5226,6 +5915,7 @@ class PieceSlot(WithTraits):
piece.setTraits(*traits)
return piece
+registerElement(PieceSlot)
# --------------------------------------------------------------------
class Prototype(WithTraits):
@@ -5255,6 +5945,8 @@ class Prototype(WithTraits):
name = name,
description = description)
+registerElement(Prototype)
+
#
# EOF
#
@@ -5262,16 +5954,21 @@ class Prototype(WithTraits):
# From traits/dynamicproperty.py
# --------------------------------------------------------------------
-# Base class for property (piece or global) change traits. Encodes
-# constraints and commands.
+#
+#
class ChangePropertyTrait(Trait):
DIRECT = 'P'
+ INCREMENT = 'I'
def __init__(self,
*commands,
numeric = False,
min = 0,
max = 100,
wrap = False):
+ '''Base class for property (piece or global) change traits.
+
+ Encodes constraints and commands.
+ '''
# assert name is not None and len(name) > 0, \
# 'No name specified for ChangePropertyTriat'
super(ChangePropertyTrait,self).__init__()
@@ -5293,8 +5990,11 @@ class ChangePropertyTrait(Trait):
# print(cmd)
com = cmd[0] + ':' + cmd[1].replace(',',r'\,') + ':' + cmd[2]
if cmd[2] == self.DIRECT:
- com += f'\,'+cmd[3].replace(':',r'\:')
+ com += f'\,'+cmd[3].replace(',',r'\\,').replace(':',r'\:')
+ elif cmd[2] == self.INCREMENT:
+ com += f'\,'+cmd[3].replace(',',r'\\,').replace(':',r'\:')
cmds.append(com)
+ # print(cmds)
return ','.join(cmds)
def decodeCommands(self,commands):
@@ -5305,6 +6005,8 @@ class ChangePropertyTrait(Trait):
# print('parts',parts)
if parts[-1][0] == self.DIRECT:
parts = parts[:-1]+Trait.decodeKeys(parts[-1],',')
+ if parts[-1][0] == self.INCREMENT:
+ parts = parts[:-1]+Trait.decodeKeys(parts[-1],',')
ret.append(parts)
# print(commands,parts)
return ret
@@ -5840,7 +6542,7 @@ class NoStackTrait(Trait):
canStack = False,
ignoreGrid = False,
description = ''):
-
+ '''No stacking trait'''
selectionOptions = (select +
(self.IGNORE_GRID if ignoreGrid else '') +
bandSelect)
@@ -7319,6 +8021,7 @@ class Game(Element):
'''
return self.getAllElements(AtStart,single)
+registerElement(Game)
# --------------------------------------------------------------------
class BasicCommandEncoder(GameElement):
@@ -7326,6 +8029,8 @@ class BasicCommandEncoder(GameElement):
def __init__(self,doc,node=None):
super(BasicCommandEncoder,self).__init__(doc,self.TAG,node=node)
+registerElement(BasicCommandEncoder)
+
#
# EOF
#
@@ -8446,7 +9151,8 @@ class LaTeXExporter(Exporter):
vassalVersion = '3.6.7',
nonato = False,
nochit = False,
- counterScale = 1):
+ counterScale = 1,
+ resolution = 150):
'''Exports a PDF and associated JSON files to a VASSAL module.
Parameters
@@ -8473,6 +9179,8 @@ class LaTeXExporter(Exporter):
Make grids visible
vassalVersion : str
VASSAL version to encode this module for
+ resolution : int
+ Resolution for images (default 150)
'''
self._vmodname = vmodname
self._pdfname = pdfname
@@ -8487,6 +9195,7 @@ class LaTeXExporter(Exporter):
self._vassalVersion = vassalVersion
self._nonato = nonato
self._nochit = nochit
+ self._resolution = resolution
self._counterScale = counterScale
self._battleMark = 'wgBattleMarker'
self._battleMarks = []
@@ -8572,6 +9281,7 @@ class LaTeXExporter(Exporter):
v(f'Tutorial log: {self._tutorial}')
v(f'Patch scripts: {self._patch}')
v(f'Visible grids: {self._visible}')
+ v(f'Resolution: {self._resolution}')
v(f'Scale of counters: {self._counterScale}')
def setup(self):
@@ -8704,6 +9414,7 @@ class LaTeXExporter(Exporter):
args = ['pdftocairo',
'-transp',
'-singlefile',
+ '-r', str(self._resolution),
'-f', str(page),
'-l', str(page),
'-png' ]
@@ -8772,9 +9483,9 @@ class LaTeXExporter(Exporter):
imgsinfo = self.getImagesInfo()
if len(imgsinfo) - 1 != docinfo['Pages']:
- raise RuntimeError(f'Number of pages in {pdfname} '
- f'(doc["Pages"]) not matched in JSON '
- f'{self._infoname} -> {len(imagesinfo)}')
+ raise RuntimeError(f'Number of pages in {self._pdfname} '
+ f'{docinfo["Pages"]} not matched in JSON '
+ f'{self._infoname} -> {len(imgsinfo)}')
with VerboseGuard(f'Converting {docinfo["Pages"]} '
f'pages in {self._pdfname}') as v:
@@ -9126,10 +9837,16 @@ class LaTeXExporter(Exporter):
'property': 'Phase',
'names': self._sides } })
turns.addHotkey(hotkey = self._clearMoved+'Phase',
- name = 'Clear moved markers')
+ name = 'Clear moved markers',
+ reportFormat = (f'{{{self._verbose}?('
+ f'"`Clear all moved markers, "+'
+ f'""):""}}'))
if len(self._battleMarks) > 0:
turns.addHotkey(hotkey = self._clearBattlePhs,
- name = 'Clear battle markers')
+ name = 'Clear battle markers',
+ reportFormat = (f'{{{self._verbose}?('
+ f'"`Clear all battle markers, "+'
+ f'""):""}}'))
self._dice = self._categories\
.get('die-roll',{})
@@ -9153,7 +9870,9 @@ class LaTeXExporter(Exporter):
# f'+" <img src=\'{die}-"+result1'
# f'+".png\' width=24 height=24>"'
f'}}'),
- resultWindow = True);
+ resultWindow = True,
+ windowX = str(int(67 * self._resolution/150)),
+ windowY = str(int(65 * self._resolution/150)));
sdie = symb.addDie(name = die);
for face, fdata in faces.items():
fn = fdata['filename']
@@ -10186,13 +10905,14 @@ class LaTeXExporter(Exporter):
# ----------------------------------------------------------------
def factionTraits(self,faction):
- traits = [ReportTrait(self._eliminateKey,
- self._restoreKey,
- self._trailKey),
+ offX = 36 * self._counterScale * self._resolution/150
+ offY = -38 * self._counterScale * self._resolution/150
+ traits = [#ReportTrait(self._eliminateKey,
+ # self._restoreKey,
+ # self._trailKey),
TrailTrait(),
RotateTrait(),
- MovedTrait(xoff = int( 36 * self._counterScale),
- yoff = int(-38 * self._counterScale)),
+ MovedTrait(xoff = int(offX),yoff = int(offY)),
DeleteTrait(),
SendtoTrait(mapName = 'DeadMap',
boardName = f'{faction} pool',
@@ -11308,7 +12028,10 @@ class LaTeXExporter(Exporter):
pc = p["coords"]
if j == 0: vv(f'',end='')
vv(f'[{pn}] ',end='',flush=True,noindent=True)
-
+
+ if pn.endswith(' flipped'):
+ pn = pn[:-len(' flipped')]
+
x, y = tran(*pc)
r = grid.addRegion(name = pn,
originx = x,
@@ -11499,7 +12222,7 @@ class LaTeXExporter(Exporter):
def addDie(self):
'''Add a `Die` element to the module
'''
- if self._dice is not None:
+ if self._dice is not None and len(self._dice) > 0:
return
self._game.addDiceButton(name = '1d6',
hotkey = self._diceKey)
@@ -11568,6 +12291,9 @@ if __name__ == '__main__':
ap.add_argument('-S','--counter-scale',
type=float, default=1,
help='Scale counters by factor')
+ ap.add_argument('-R','--resolution',
+ type=int, default=150,
+ help='Resolution of images')
args = ap.parse_args()
@@ -11600,6 +12326,7 @@ if __name__ == '__main__':
vassalVersion = args.vassal_version,
nonato = args.no_nato_prototypes,
nochit = args.no_chit_information,
+ resolution = args.resolution,
counterScale = args.counter_scale)
exporter.run()
except Exception as e: