Allow multiple levels of shading in the turn track.

master
Pacman Ghost 2 years ago
parent 729c6e306d
commit d165bfdefd
  1. 9
      vasl_templates/webapp/data/default-template-pack/turn_track.j2
  2. 3
      vasl_templates/webapp/main.py
  3. 33
      vasl_templates/webapp/static/snippets.js
  4. 58
      vasl_templates/webapp/static/turn_track.js
  5. 46
      vasl_templates/webapp/tests/test_turn_track.py

@ -28,6 +28,9 @@ td.half-turn {
{% if TURN_TRACK_PREVIEW_MODE %}
body { margin: 0 ; }
body ::selection {}
body ::moz-selection {}
body { user-select: none ; }
.reinforce1, .reinforce2 { opacity: 0 ; }
.flag-click { width: 13px ; height: 13px ; cursor: pointer ; }
.shading-click { cursor: pointer ; }
@ -63,13 +66,13 @@ function onShadingClick( turnNo ) {
{% for turnSquare in row %}
<td id="turn-square-{{turnSquare[0]}}"
{%if turnSquare[0] == TURN_TRACK_HALF_TURN%} class="half-turn" {%endif%}
{% if turnSquare[1] %} style="background-color:{{TURN_TRACK_SHADING_COLOR}};" {%endif%}
{% if turnSquare[3] %} style="background-color:{{turnSquare[3]}};" {%endif%}
>
<table style="width:100%;height:100%;"> <tr>
<td id="flag-{{turnSquare[0]}}_1" width="100%"
class = {% if turnSquare[2] %} "reinforce1" {%else%} "no-reinforce" {%endif%}
class = {% if turnSquare[1] %} "reinforce1" {%else%} "no-reinforce" {%endif%}
>
{% if TURN_TRACK_PREVIEW_MODE %}
<div class="flag-click"
@ -91,7 +94,7 @@ function onShadingClick( turnNo ) {
</td>
<td id="flag-{{turnSquare[0]}}_2" width="100%"
class = {% if turnSquare[3] and turnSquare[0] != TURN_TRACK_HALF_TURN %} "reinforce2" {%else%} "no-reinforce" {%endif%}
class = {% if turnSquare[2] and turnSquare[0] != TURN_TRACK_HALF_TURN %} "reinforce2" {%else%} "no-reinforce" {%endif%}
>
{% if TURN_TRACK_PREVIEW_MODE and turnSquare[0] != TURN_TRACK_HALF_TURN %}
<div class="flag-click"

@ -75,6 +75,7 @@ _APP_CONFIG_DEFAULTS = { # Bodhgaya, India (APR/19)
"ONLINE_COUNTER_IMAGES_URL_TEMPLATE": "https://raw.githubusercontent.com/vasl-developers/vasl/develop/dist/images/{{PATH}}", #pylint: disable=line-too-long
"ONLINE_EXTN_COUNTER_IMAGES_URL_TEMPLATE": "http://vasl-templates.org/services/counter/{{EXTN_ID}}/{{PATH}}",
"ASA_UPLOAD_URL": "https://aslscenarioarchive.com/rest/update/{ID}?user={USER}&token={TOKEN}",
"TURN_TRACK_SHADING_COLORS": [ "#e0e0e0", "#c0c0c0" ],
}
@app.route( "/app-config" )
@ -99,6 +100,8 @@ def get_app_config():
}
if isinstance( vals["THEATERS"], str ):
vals["THEATERS"] = vals["THEATERS"].split()
if isinstance( vals["TURN_TRACK_SHADING_COLORS"], str ):
vals["TURN_TRACK_SHADING_COLORS"] = vals["TURN_TRACK_SHADING_COLORS"].split()
for key in [ "APP_NAME", "APP_VERSION", "APP_DESCRIPTION", "APP_HOME_URL" ]:
vals[ key ] = getattr( vasl_templates.webapp.config.constants, key )

@ -519,6 +519,7 @@ function make_turn_track_params( params )
// generate the data for each turn track square
var turnTrackSquares=[], nTurnTrackSquares=0 ;
var shadings = parseTurnTrackShadings( args.shadings ) ;
var nRows = Math.ceil( args.nTurns / args.width ) ;
for ( var row=0 ; row < nRows ; ++row ) {
turnTrackSquares.push( [] ) ;
@ -530,14 +531,15 @@ function make_turn_track_params( params )
turnNo = 1 + row * args.width + col ;
if ( turnNo > args.nTurns )
break ;
var val = [ turnNo,
args.shading[turnNo] ? true : false,
var vals = [ turnNo,
args.reinforce2[turnNo] ? true : false,
args.reinforce1[turnNo] ? true : false,
] ;
if ( params.TURN_TRACK.SWAP_PLAYERS )
val = [ val[0], val[1], val[3], val[2] ] ;
turnTrackSquares[ turnTrackSquares.length-1 ].push( val ) ;
vals = [ vals[0], vals[2], vals[1] ] ;
if ( shadings[turnNo] )
vals.push( gAppConfig.TURN_TRACK_SHADING_COLORS[ shadings[turnNo] - 1 ] ) ;
turnTrackSquares[ turnTrackSquares.length-1 ].push( vals ) ;
nTurnTrackSquares += 1 ;
}
}
@ -550,7 +552,6 @@ function make_turn_track_params( params )
params.TURN_TRACK_HALF_TURN_IMAGE_URL = forceLocalImages ?
make_app_url( "/static/images/turn-track-half-turn.png", true ) :
params.IMAGES_BASE_URL + "/turn-track-half-turn.png" ;
params.TURN_TRACK_SHADING_COLOR = TURN_TRACK_SHADING_COLOR ;
// NOTE: The convention is that player 1 sets up first, player 2 moves first,
// so swapping players actually maps turn track player 1 to the real player 1.
// NOTE: We generate the player flag URL's instead of using params.PLAYER_FLAG_1/2
@ -567,12 +568,16 @@ function make_turn_track_params( params )
function parseTurnTrackParams( params )
{
function parseCommaList( reinf ) {
var turnFlags = {} ;
function parseCommaList( reinf, verbatim ) {
var turnFlags = verbatim ? [] : {} ;
reinf.split( "," ).forEach( function( turnNo ) {
turnNo = parseInt( turnNo.trim() ) ;
if ( ! isNaN( turnNo ) )
turnFlags[ turnNo ] = true ;
if ( verbatim )
turnFlags.push( turnNo.trim() ) ;
else {
turnNo = parseInt( turnNo.trim() ) ;
if ( ! isNaN( turnNo ) )
turnFlags[ turnNo ] = true ;
}
} ) ;
return turnFlags ;
}
@ -588,13 +593,13 @@ function parseTurnTrackParams( params )
var width = params.TURN_TRACK.WIDTH ;
if ( width === "" )
width = vertical ? 1 : nTurns ;
var shading = parseCommaList( params.TURN_TRACK.SHADING ) ;
var reinforce1 = parseCommaList( params.TURN_TRACK.REINFORCEMENTS_1 ) ;
var reinforce2 = parseCommaList( params.TURN_TRACK.REINFORCEMENTS_2 ) ;
var shadings = parseCommaList( params.TURN_TRACK.SHADING, true ) ;
var reinforce1 = parseCommaList( params.TURN_TRACK.REINFORCEMENTS_1, false ) ;
var reinforce2 = parseCommaList( params.TURN_TRACK.REINFORCEMENTS_2, false ) ;
return {
nTurns: nTurns, halfTurn: halfTurn,
vertical: vertical, width: width, shading: shading,
vertical: vertical, width: width, shadings: shadings,
reinforce1: reinforce1, reinforce2: reinforce2
} ;
}

@ -1,12 +1,11 @@
DEFAULT_TURN_TRACK_TURNS_MIN = 6 ;
DEFAULT_TURN_TRACK_TURNS_MAX = 10 ;
TURN_TRACK_SHADING_COLOR = "#e0e0e0" ;
// NOTE: Reinforcement flags get clipped on turn 100, but this is unlikely to be an issue :-/
_MAX_TURN_TRACK_TURNS = 100 ;
gTurnTrackReinforcements = null ;
gTurnTrackShading = null ;
gTurnTrackShadings = null ;
// --------------------------------------------------------------------
@ -16,7 +15,7 @@ function editTurnTrackSettings()
var $dlg, $iframe, iframeSeqNo=0 ;
// FUDGE! This should work as a local variable, but causes a weird problem where it doesn't get reset properly :-/
gTurnTrackReinforcements = null ;
gTurnTrackShading = null ;
gTurnTrackShadings = null ;
function loadControls() {
// load the dialog controls
@ -37,7 +36,7 @@ function editTurnTrackSettings()
var params = updatePreview( false ) ;
var args = parseTurnTrackParams( params ) ;
gTurnTrackReinforcements = { 1: args.reinforce1, 2: args.reinforce2 } ;
gTurnTrackShading = args.shading ;
gTurnTrackShadings = parseTurnTrackShadings( args.shadings ) ;
// update the UI
updateUI() ;
}
@ -54,7 +53,7 @@ function editTurnTrackSettings()
$panel.find( "input[name='TURN_TRACK_REINFORCEMENTS_1']" ).val( "" ) ;
$panel.find( "input[name='TURN_TRACK_REINFORCEMENTS_2']" ).val( "" ) ;
gTurnTrackReinforcements = null ;
gTurnTrackShading = null ;
gTurnTrackShadings = null ;
loadControls() ;
}
} ) ;
@ -150,16 +149,27 @@ function editTurnTrackSettings()
function onShadingClick( turnNo ) {
// NOTE: This method gets called by a click handler in the snippet HTML.
// toggle the turn track square's shading
if ( gTurnTrackShading[turnNo] )
delete gTurnTrackShading[turnNo] ;
else
gTurnTrackShading[turnNo] = true ;
$panel.find( "input[name='TURN_TRACK_SHADING']" ).val(
Object.keys( gTurnTrackShading ).join( "," )
) ;
$iframe.contents().find( "#turn-square-" + turnNo ).css( {
"background-color": gTurnTrackShading && gTurnTrackShading[turnNo] ? TURN_TRACK_SHADING_COLOR : "inherit"
// determine the new shading strength
var strength = gTurnTrackShadings[turnNo] || 0 ;
var col ;
if ( ++strength <= gAppConfig.TURN_TRACK_SHADING_COLORS.length ) {
gTurnTrackShadings[turnNo] = strength ;
col = gAppConfig.TURN_TRACK_SHADING_COLORS[ strength-1 ] ;
} else {
delete gTurnTrackShadings[turnNo] ;
col = "inherit" ;
}
// update the saved setting
var shadings = [] ;
Object.keys( gTurnTrackShadings ).forEach( function( key ) {
var strength = gTurnTrackShadings[key] ;
for ( var i=1 ; i < strength ; ++i )
key += "+" ;
shadings.push( key ) ;
} ) ;
$panel.find( "input[name='TURN_TRACK_SHADING']" ).val( shadings.join( "," ) ) ;
// update the turn square in the UI
$iframe.contents().find( "#turn-square-" + turnNo ).css( { "background-color": col } ) ;
}
function updateFlag( turnNo, playerNo ) {
@ -322,6 +332,26 @@ function updateTurnTrackNTurns( nTurns )
}
}
function parseTurnTrackShadings( shadings ) {
// NOTE: A turn track shading setting consists of a number (the turn number),
// followed by 0 or more plus signs (to indicate a darker shading color).
var shadingTable = {} ;
shadings.forEach( function( shading ) {
var strength = 1 ;
while ( shading.length > 0 && shading.substr( shading.length-1 ) === "+" ) {
strength += 1 ;
shading = shading.substr( 0, shading.length-1 ) ;
}
if ( strength > gAppConfig.TURN_TRACK_SHADING_COLORS.length )
return ;
var turnNo = parseInt( shading ) ;
if ( isNaN( turnNo ) )
return ;
shadingTable[turnNo] = strength ;
} ) ;
return shadingTable ;
}
function formatTurnTrackOption( opt ) {
// format the turn track <option> element
if ( opt.id === "(show-dialog)" )

@ -1,5 +1,8 @@
""" Test the turn track functionality. """
import os
import re
from selenium.webdriver.support.ui import Select
from selenium.webdriver.common.keys import Keys
@ -8,6 +11,13 @@ from vasl_templates.webapp.tests.utils import \
SwitchFrame, unload_table, wait_for, wait_for_elem, wait_for_clipboard, find_child
from vasl_templates.webapp.tests.test_scenario_persistence import load_scenario, save_scenario
# extract the turn track shading colors
_TURN_TRACK_SHADING_COLORS = {}
with open( os.path.join( os.path.dirname(__file__), "../main.py" ), "r", encoding="ascii" ) as fp:
mo = re.search( r'"TURN_TRACK_SHADING_COLORS": \[ (.+) \]', fp.read(), flags=re.MULTILINE )
for mo2 in re.finditer( '"#[0-9a-f]{6}"', mo.group(1) ):
_TURN_TRACK_SHADING_COLORS[ mo2.group()[1:-1] ] = len(_TURN_TRACK_SHADING_COLORS) + 1
# ---------------------------------------------------------------------
def test_turn_track_basic( webapp, webdriver ):
@ -141,8 +151,8 @@ def test_turn_track_shading( webapp, webdriver ):
_toggle_shading( 2 )
_toggle_shading( 7 )
assert _generate_turn_track_snippet( dlg ) == [
[ (1,None,None,True), (2,None,None,True), (3,None,None),
(4,None,None), (5,None,None) , (6,None,None), (7,None,None,True)
[ (1,None,None,"shading1"), (2,None,None,"shading1"), (3,None,None),
(4,None,None), (5,None,None) , (6,None,None), (7,None,None,"shading1")
]
]
@ -152,8 +162,20 @@ def test_turn_track_shading( webapp, webdriver ):
_toggle_shading( 3 )
_toggle_shading( 7 )
assert _generate_turn_track_snippet( dlg ) == [
[ (1,None,None), (2,None,None,True), (3,None,None,True),
(4,None,None), (5,None,None) , (6,None,None), (7,None,None)
[ (1,None,None,"shading2"), (2,None,None,"shading1"), (3,None,None,"shading1"),
(4,None,None), (5,None,None) , (6,None,None), (7,None,None,"shading2")
]
]
# change the shading for some turn track squares, then check the snippet
with SwitchFrame( webdriver, "#turn-track-preview" ):
_toggle_shading( 1 )
_toggle_shading( 3 )
_toggle_shading( 2 )
_toggle_shading( 2 )
assert _generate_turn_track_snippet( dlg ) == [
[ (1,None,None), (2,None,None), (3,None,None,"shading2"),
(4,None,None), (5,None,None) , (6,None,None), (7,None,None,"shading2")
]
]
@ -181,6 +203,7 @@ def test_turn_track_persistence( webapp, webdriver ):
_toggle_reinf( 3, 2 )
_toggle_shading( 2 )
_toggle_shading( 4 )
_toggle_shading( 4 )
_change_turn_track_width( dlg, 4 )
_swap_turn_track_players( dlg )
_change_turn_track_direction( dlg )
@ -188,7 +211,7 @@ def test_turn_track_persistence( webapp, webdriver ):
# check the snippet
expected = [
[ (1,None,"player2"), (3,"player1","player2"), (5,None,None), (7,None,None) ],
[ (2,"player1",None,True) , (4,None,None,True), (6,None,None) ]
[ (2,"player1",None,"shading1") , (4,None,None,"shading2"), (6,None,None) ]
]
wait_for( 2,
lambda: _generate_turn_track_snippet( dlg ) == expected
@ -200,7 +223,7 @@ def test_turn_track_persistence( webapp, webdriver ):
assert saved_scenario["TURN_TRACK"] == {
"NTURNS": "6.5",
"WIDTH": "4", "VERTICAL": True, "SWAP_PLAYERS": True,
"SHADING": "2,4",
"SHADING": "2,4+",
"REINFORCEMENTS_1": "2,3", "REINFORCEMENTS_2": "1,3",
}
assert _generate_turn_track_snippet( None ) == expected
@ -310,8 +333,15 @@ def _generate_turn_track_snippet( dlg ):
get_reinforce_class( cells[2] ),
)
# check if the square is shaded
if any( s.startswith( "background-color:" ) for s in square.xpath( ".//@style" ) ):
vals = ( *vals, True )
cols = [ s for s in square.xpath( ".//@style" ) if s.startswith( "background-color:" ) ]
if cols:
assert len(cols) == 1
col = cols[0][17:]
assert col.endswith( ";" )
col = col[:-1]
shading = _TURN_TRACK_SHADING_COLORS.get( col )
assert shading, "Can't find turn track shading color: {}".format( shading )
vals = ( *vals, "shading{}".format( shading ) )
return vals
# unload the snippet contents

Loading…
Cancel
Save