Skip to content

Commit

Permalink
Update scoring panel for 2024.
Browse files Browse the repository at this point in the history
  • Loading branch information
patfair committed May 17, 2024
1 parent 1b1552e commit 9a40ca7
Show file tree
Hide file tree
Showing 5 changed files with 244 additions and 305 deletions.
124 changes: 49 additions & 75 deletions static/css/scoring_panel.css
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ body {
.container {
padding-top: 1vw;
width: 100%;
max-width: none;
height: 100%;
display: flex;
flex-direction: column;
Expand All @@ -38,6 +39,7 @@ body {
background-color: #223;
}
#matchName {
margin-bottom: 0.5vw;
font-size: 2vw;
}
.scoring-section {
Expand Down Expand Up @@ -73,98 +75,70 @@ body {
.boolean[data-value="true"] {
background-color: #263;
}
.endgame-status[data-value="0"] {
background-color: #333;
}
.endgame-status[data-value="1"] {
background-color: #652;
}
.endgame-status[data-value="2"] {
background-color: #263;
}
.charge-station-level[data-value="false"] {
background-color: #622;
#postMatchMessage {
height: 5vw;
display: none;
align-items: center;
font-size: 1.5vw;
color: #c90;
}
.charge-station-level[data-value="true"] {
background-color: #263;
#commitMatchScore {
height: 5vw;
display: none;
align-items: center;
}
#grid {
width: 100%;
margin-top: 1.5vw;
margin-bottom: 1.5vw;
display: flex;
flex-direction: column;
#commitMatchScore>button {
font-size: 1vw;
}
.grid-row {
width: 100%;
#stage {
position: relative;
display: flex;
justify-content: center;
}
.grid-node {
width: 10vw;
display: flex;
flex-direction: column;
align-items: center;
border: 1px solid #ccc;
padding: 0.5vw;
margin-top: -1px;
margin-left: -1px;
}
.grid-node[data-node="2"], .grid-node[data-node="5"] {
margin-right: 1vw;
#stageGraphic {
margin-top: 9vw;
height: 30vw;
color: #999;
}
.grid-node-auto {
width: 4vw;
height: 2vw;
margin-bottom: 0.5vw;
.stage-side {
position: absolute;
top: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
border-radius: 0.5vw;
background-color: #333;
color: #ccc;
}
.grid-node-auto[data-value="true"] {
background-color: #263;
width: 16vw;
height: 8vw;
border: 0.5px solid #111;
}
.grid-node-states {
.stage-side-col {
display: flex;
flex-wrap: wrap;
justify-content: space-around;
flex-direction: column;
flex-grow: 1;
height: 100%;
}
.grid-node-button {
width: 4vw;
height: 4vw;
.stage-side-col div {
display: flex;
justify-content: center;
align-items: center;
opacity: 0.4;
}
.grid-node-button[data-value="true"] {
border: 2px solid #aaa;
border-radius: 0.5vw;
opacity: 1;
}
.grid-node-button img {
width: 90%;
flex-grow: 1;
font-size: 1.5vw;
background-color: #333;
border: 0.5px solid #111;
}
#chargeStation {
width: 70vw;
justify-content: space-between;
align-items: center;
#stageLeft {
top: 20vw;
left: -8.5vw;
}
#postMatchMessage {
height: 5vw;
display: none;
align-items: center;
font-size: 1.5vw;
color: #c90;
#centerStage {
top: 0.5vw;
left: 9.3vw;
}
#commitMatchScore {
height: 5vw;
display: none;
align-items: center;
#stageRight {
top: 20vw;
left: 25.9vw;
}
#commitMatchScore>button {
font-size: 1vw;
#park {
top: 13vw;
left: 12.2vw;
width: 9vw;
}
57 changes: 16 additions & 41 deletions static/js/scoring_panel.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ let alliance;
const handleMatchLoad = function(data) {
$("#matchName").text(data.Match.LongName);
if (alliance === "red") {
$("#team1").text(data.Match.Red1);
$("#team2").text(data.Match.Red2);
$("#team3").text(data.Match.Red3);
$(".team-1").text(data.Match.Red1);
$(".team-2").text(data.Match.Red2);
$(".team-3").text(data.Match.Red3);
} else {
$("#team1").text(data.Match.Blue1);
$("#team2").text(data.Match.Blue2);
$("#team3").text(data.Match.Blue3);
$(".team-1").text(data.Match.Blue1);
$(".team-2").text(data.Match.Blue2);
$(".team-3").text(data.Match.Blue3);
}
};

Expand Down Expand Up @@ -50,33 +50,20 @@ const handleRealtimeScore = function(data) {

for (let i = 0; i < 3; i++) {
const i1 = i + 1;
$(`#mobilityStatus${i1}>.value`).text(score.MobilityStatuses[i] ? "Yes" : "No");
$("#mobilityStatus" + i1).attr("data-value", score.MobilityStatuses[i]);
$("#autoDockStatus" + i1 + ">.value").text(score.AutoDockStatuses[i] ? "Yes" : "No");
$("#autoDockStatus" + i1).attr("data-value", score.AutoDockStatuses[i]);
$("#endgameStatus" + i1 + ">.value").text(getEndgameStatusText(score.EndgameStatuses[i]));
$("#endgameStatus" + i1).attr("data-value", score.EndgameStatuses[i]);
}

$("#autoChargeStationLevel>.value").text(score.AutoChargeStationLevel ? "Level" : "Not Level");
$("#autoChargeStationLevel").attr("data-value", score.AutoChargeStationLevel);
$("#endgameChargeStationLevel>.value").text(score.EndgameChargeStationLevel ? "Level" : "Not Level");
$("#endgameChargeStationLevel").attr("data-value", score.EndgameChargeStationLevel);

for (let i = 0; i < 3; i++) {
for (let j = 0; j < 9; j++) {
$(`#gridAutoScoringRow${i}Node${j}`).attr("data-value", score.Grid.AutoScoring[i][j]);
$(`#gridNodeStatesRow${i}Node${j}`).children().each(function() {
const element = $(this);
element.attr("data-value", element.attr("data-node-state") === score.Grid.Nodes[i][j].toString());
});
}
$(`#leaveStatus${i1}>.value`).text(score.LeaveStatuses[i] ? "Yes" : "No");
$(`#leaveStatus${i1}`).attr("data-value", score.LeaveStatuses[i]);
$(`#parkTeam${i1}`).attr("data-value", score.EndgameStatuses[i] === 1);
$(`#stageSide0Team${i1}`).attr("data-value", score.EndgameStatuses[i] === 2);
$(`#stageSide1Team${i1}`).attr("data-value", score.EndgameStatuses[i] === 3);
$(`#stageSide2Team${i1}`).attr("data-value", score.EndgameStatuses[i] === 4);
$(`#stageSide${i}Microphone`).attr("data-value", score.MicrophoneStatuses[i]);
$(`#stageSide${i}Trap`).attr("data-value", score.TrapStatuses[i]);
}
};

// Handles an element click and sends the appropriate websocket message.
const handleClick = function(command, teamPosition = 0, gridRow = 0, gridNode = 0, nodeState = 0) {
websocket.send(command, {TeamPosition: teamPosition, GridRow: gridRow, GridNode: gridNode, NodeState: nodeState});
const handleClick = function(command, teamPosition = 0, stageIndex = 0) {
websocket.send(command, {TeamPosition: teamPosition, StageIndex: stageIndex});
};

// Sends a websocket message to indicate that the score for this alliance is ready.
Expand All @@ -86,18 +73,6 @@ const commitMatchScore = function() {
$("#commitMatchScore").hide();
};

// Returns the display text corresponding to the given integer endgame status value.
const getEndgameStatusText = function(level) {
switch (level) {
case 1:
return "Park";
case 2:
return "Dock";
default:
return "None";
}
};

$(function() {
alliance = window.location.href.split("/").slice(-1)[0];
$("#alliance").attr("data-alliance", alliance);
Expand Down
86 changes: 33 additions & 53 deletions templates/scoring_panel.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,44 +11,41 @@
<div class="scoring-section">
<div class="scoring-header">
<div>&nbsp;</div>
<div>Mobility</div>
<div>Auto Dock</div>
<div>Endgame</div>
<div>Leave</div>
</div>
{{range $i := seq 3}}
<div>
<div id="team{{$i}}" class="team robot-field"></div>
<div id="mobilityStatus{{$i}}" class="boolean robot-field" onclick="handleClick('mobilityStatus', {{$i}});">
<div class="value"></div>
</div>
<div id="autoDockStatus{{$i}}" class="boolean robot-field" onclick="handleClick('autoDockStatus', {{$i}});">
<div class="value"></div>
</div>
<div id="endgameStatus{{$i}}" class="endgame-status robot-field"
onclick="handleClick('endgameStatus', {{$i}});">
<div class="team team-{{$i}} robot-field"></div>
<div id="leaveStatus{{$i}}" class="boolean robot-field" onclick="handleClick('leave', {{$i}});">
<div class="value"></div>
</div>
</div>
{{end}}
</div>
<div id="chargeStation" class="scoring-section">
<div id="autoChargeStationLevel" class="charge-station-level robot-field"
onclick="handleClick('autoChargeStationLevel');">
<div class="value"></div>
</div>
<div>Auto</div>
<div>Charge Station</div>
<div>Endgame</div>
<div id="endgameChargeStationLevel" class="charge-station-level robot-field"
onclick="handleClick('endgameChargeStationLevel');">
<div class="value"></div>
<div id="stage">
<svg id="stageGraphic" viewBox="0 4 100 90">
<polygon points="5,5 95,5 50,78" fill="none" stroke="currentColor" stroke-width="0.2" />
<text x="50" y="7.5" text-anchor="middle" font-size="2" fill="currentColor">Center</text>
<text x="50" y="9.5" text-anchor="middle" font-size="2" fill="currentColor">Stage</text>
<text x="30" y="38" text-anchor="middle" font-size="2" fill="currentColor">Stage</text>
<text x="30" y="40" text-anchor="middle" font-size="2" fill="currentColor">Left</text>
<text x="69" y="38" text-anchor="middle" font-size="2" fill="currentColor">Stage</text>
<text x="69" y="40" text-anchor="middle" font-size="2" fill="currentColor">Right</text>
<text x="50" y="15" text-anchor="middle" font-size="2" fill="currentColor">Park</text>
<line x1="5" y1="85" x2="95" y2="85" stroke="currentColor" stroke-width="0.2" />
<text x="50" y="87.5" text-anchor="middle" font-size="2" fill="currentColor">Alliance Wall</text>
</svg>
<div id="stageLeft" class="stage-side">{{template "stageSide" dict "index" 0}}</div>
<div id="centerStage" class="stage-side">{{template "stageSide" dict "index" 1}}</div>
<div id="stageRight" class="stage-side">{{template "stageSide" dict "index" 2}}</div>
<div id="park" class="stage-side">
<div class="stage-side-col">
<div id="parkTeam1" class="team-1 boolean" onclick="handleClick('park', 1);"></div>
<div id="parkTeam2" class="team-2 boolean" onclick="handleClick('park', 2);"></div>
<div id="parkTeam3" class="team-3 boolean" onclick="handleClick('park', 3);"></div>
</div>
</div>
</div>
<div id="grid">
{{template "gridRow" dict "rowIndex" 2 "validNodeStates" (index .ValidGridNodeStates 2)}}
{{template "gridRow" dict "rowIndex" 1 "validNodeStates" (index .ValidGridNodeStates 1)}}
{{template "gridRow" dict "rowIndex" 0 "validNodeStates" (index .ValidGridNodeStates 0)}}
</div>
</div>
<div id="commitMatchScore">
<button type="button" class="btn btn-primary" onclick="commitMatchScore();">
Expand All @@ -66,31 +63,14 @@
<script src="/static/js/match_timing.js"></script>
<script src="/static/js/scoring_panel.js"></script>
{{end}}
{{define "gridRow"}}
<div class="grid-row">
{{range $i, $validStates := .validNodeStates}}
{{template "gridNode" dict "rowIndex" $.rowIndex "nodeIndex" $i "validStates" $validStates}}
{{end}}
{{define "stageSide"}}
<div class="stage-side-col">
<div id="stageSide{{.index}}Team1" class="team-1 boolean" onclick="handleClick('onStage', 1, {{.index}});"></div>
<div id="stageSide{{.index}}Team2" class="team-2 boolean" onclick="handleClick('onStage', 2, {{.index}});"></div>
<div id="stageSide{{.index}}Team3" class="team-3 boolean" onclick="handleClick('onStage', 3, {{.index}});"></div>
</div>
{{end}}
{{define "gridNode"}}
<div class="grid-node" data-node="{{.nodeIndex}}">
<div id="gridAutoScoringRow{{$.rowIndex}}Node{{$.nodeIndex}}" class="grid-node-auto"
onclick="handleClick('gridAutoScoring', 0, {{$.rowIndex}}, {{$.nodeIndex}})">
Auto
</div>
<div id="gridNodeStatesRow{{$.rowIndex}}Node{{$.nodeIndex}}" class="grid-node-states">
{{range $i, $state := .validStates}}
{{if ne $state "Empty"}}
{{template "gridNodeButton" dict "i" $i "state" $state "rowIndex" $.rowIndex "nodeIndex" $.nodeIndex}}
{{end}}
{{end}}
</div>
</div>
{{end}}
{{define "gridNodeButton"}}
<div class="grid-node-button" data-node-state="{{nodeStateToInt .i}}"
onclick="handleClick('gridNode', 0, {{.rowIndex}}, {{.nodeIndex}}, {{nodeStateToInt .i}})">
<img src="/static/img/node_states/{{.state}}.svg" />
<div class="stage-side-col">
<div id="stageSide{{.index}}Microphone" class="boolean" onclick="handleClick('microphone', 0, {{.index}});">Mic</div>
<div id="stageSide{{.index}}Trap" class="boolean" onclick="handleClick('trap', 0, {{.index}});">Trap</div>
</div>
{{end}}
Loading

0 comments on commit 9a40ca7

Please sign in to comment.