Skip to content

Commit 7365b81

Browse files
committed
WebViewer: restyle map controls into pill + rounded group, fold-out attribution, measure in context menu
1 parent d900962 commit 7365b81

3 files changed

Lines changed: 105 additions & 44 deletions

File tree

frontend/src/index.html

Lines changed: 30 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,12 @@
553553
tracks</li>
554554
<li class="ctx-map noandroid" data-action="startBoxSelect"><i class="timeline_icon"></i>Show tracks in
555555
area</li>
556+
<li class="ctx-map" data-action="toggleMeasurecard"><svg xmlns="http://www.w3.org/2000/svg"
557+
viewBox="0 -960 960 960"
558+
style="width:16px;height:16px;margin-right:8px;fill:currentColor;flex-shrink:0">
559+
<path
560+
d="M160-240q-33 0-56.5-23.5T80-320v-320q0-33 23.5-56.5T160-720h640q33 0 56.5 23.5T880-640v320q0 33-23.5 56.5T800-240H160Zm0-80h640v-320H680v160h-80v-160h-80v160h-80v-160h-80v160h-80v-160H160v320Zm120-160h80-80Zm160 0h80-80Zm160 0h80-80Zm-120 0Z" />
561+
</svg>Measure distance</li>
556562
<li class="ctx-map ctx-removealltracks" data-action="resetTracksFromNow"><i
557563
class="timeline_icon"></i>Reset tracks (from now)</li>
558564
<li class="ctx-map ctx-removealltracks" data-action="deleteAllTracks"><i
@@ -1314,24 +1320,23 @@ <h3>NMEA Decoder</h3>
13141320

13151321

13161322
<div title="Counters"
1317-
class="ol-control ol-unselectable ol-control-custom button-control-box map-button-box nokiosk"
1318-
style="top: 10px; border-radius: 17px;">
1323+
class="ol-control ol-unselectable ol-control-custom button-control-box map-button-box map-pill nokiosk"
1324+
style="top: 10px;">
13191325
<button type="button" data-action="toggleStatcard" class="btn btn-primary map-button"
1320-
style="font-size: 10px; border-radius: 2px; border-top-right-radius: 17px; border-top-left-radius: 17px;">
1326+
style="font-size: 10px;">
13211327
<span id="markerCount">0</span>
13221328
</button>
1323-
<button type="button" data-action="toggleTablecard" class="btn btn-primary map-button"
1324-
style="border-radius: 2px;">
1329+
<button type="button" data-action="toggleTablecard" class="btn btn-primary map-button">
13251330
<svg xmlns="http://www.w3.org/2000/svg" height="12" viewBox="0 -960 960 960" width="12">
13261331
<path
13271332
d="M158-200 82-468q-3-12 2.5-28t23.5-22l52-18v-184q0-33 23.5-56.5T240-800h120v-120h240v120h120q33 0 56.5 23.5T800-720v184l52 18q21 8 25 23.5t1 26.5l-76 268q-50 0-91-23.5T640-280q-30 33-71 56.5T480-200q-48 0-89-23.5T320-280q-30 33-71 56.5T158-200ZM80-40v-80h80q42 0 83-13t77-39q36 26 77 38t83 12q42 0 83-12t77-38q36 26 77 39t83 13h80v80h-80q-42 0-82-10t-78-30q-38 20-78.5 30T480-40q-41 0-81.5-10T320-80q-38 20-78 30t-82 10H80Zm160-522 240-78 240 78v-158H240v158Z" />
13281333
</svg>
13291334
</button>
1330-
<button type="button" data-action="toggleMeasurecard" class="btn btn-primary map-button"
1331-
style="border-radius: 2px; border-bottom-left-radius: 17px; border-bottom-right-radius: 17px;">
1332-
<svg xmlns="http://www.w3.org/2000/svg" height="12px" viewBox="0 -960 960 960" width="12px">
1335+
<button title="Settings" type="button" data-action="mapSettingsContextMenu"
1336+
class="btn btn-primary map-button color-grey">
1337+
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24">
13331338
<path
1334-
d="M160-240q-33 0-56.5-23.5T80-320v-320q0-33 23.5-56.5T160-720h640q33 0 56.5 23.5T880-640v320q0 33-23.5 56.5T800-240H160Zm0-80h640v-320H680v160h-80v-160h-80v160h-80v-160h-80v160h-80v-160H160v320Zm120-160h80-80Zm160 0h80-80Zm160 0h80-80Zm-120 0Z" />
1339+
d="M240-400q-33 0-56.5-23.5T160-480q0-33 23.5-56.5T240-560q33 0 56.5 23.5T320-480q0 33-23.5 56.5T240-400Zm240 0q-33 0-56.5-23.5T400-480q0-33 23.5-56.5T480-560q33 0 56.5 23.5T560-480q0 33-23.5 56.5T480-400Zm240 0q-33 0-56.5-23.5T640-480q0-33 23.5-56.5T720-560q33 0 56.5 23.5T800-480q0 33-23.5 56.5T720-400Z" />
13351340
</svg>
13361341
</button>
13371342

@@ -1366,34 +1371,26 @@ <h3>NMEA Decoder</h3>
13661371
</svg>
13671372
</div>
13681373

1369-
<div title="Settings"
1370-
class="ol-control ol-unselectable ol-control-custom button-control-box map-button-box nokiosk"
1371-
style=" bottom: 140px; border-radius: 5px;">
1372-
<button type="button" data-action="mapSettingsContextMenu"
1373-
class="btn btn-primary map-button color-grey">
1374-
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24">
1375-
<path
1376-
d="M240-400q-33 0-56.5-23.5T160-480q0-33 23.5-56.5T240-560q33 0 56.5 23.5T320-480q0 33-23.5 56.5T240-400Zm240 0q-33 0-56.5-23.5T400-480q0-33 23.5-56.5T480-560q33 0 56.5 23.5T560-480q0 33-23.5 56.5T480-400Zm240 0q-33 0-56.5-23.5T640-480q0-33 23.5-56.5T720-560q33 0 56.5 23.5T800-480q0 33-23.5 56.5T720-400Z" />
1377-
</svg>
1378-
</button>
1374+
<div id="map-attribution-foldout" class="ol-control ol-unselectable map-attribution-foldout"
1375+
style="display: none;">
1376+
<span id="map_attributions"></span>
1377+
</div>
1378+
1379+
<div class="ol-control ol-unselectable ol-control-custom button-control-box map-button-box nokiosk"
1380+
style="bottom: 30px;">
13791381
<button title="Toggle Community Pane" type="button" id="xchange" data-action="toggleCommunityPane"
13801382
class="noandroid btn btn-primary map-button fill-red">
1381-
13821383
<svg xmlns="http://www.w3.org/2000/svg" height="20" viewBox="0 -960 960 960" width="20">
13831384
<path
13841385
d="M475-160q4 0 8-2t6-4l328-328q12-12 17.5-27t5.5-30q0-16-5.5-30.5T817-607L647-777q-11-12-25.5-17.5T591-800q-15 0-30 5.5T534-777l-11 11 74 75q15 14 22 32t7 38q0 42-28.5 70.5T527-522q-20 0-38.5-7T456-550l-75-74-175 175q-3 3-4.5 6.5T200-435q0 8 6 14.5t14 6.5q4 0 8-2t6-4l136-136 56 56-135 136q-3 3-4.5 6.5T285-350q0 8 6 14t14 6q4 0 8-2t6-4l136-135 56 56-135 136q-3 2-4.5 6t-1.5 8q0 8 6 14t14 6q4 0 7.5-1.5t6.5-4.5l136-135 56 56-136 136q-3 3-4.5 6.5T454-180q0 8 6.5 14t14.5 6Zm-1 80q-37 0-65.5-24.5T375-166q-34-5-57-28t-28-57q-34-5-56.5-28.5T206-336q-38-5-62-33t-24-66q0-20 7.5-38.5T149-506l232-231 131 131q2 3 6 4.5t8 1.5q9 0 15-5.5t6-14.5q0-4-1.5-8t-4.5-6L398-777q-11-12-25.5-17.5T342-800q-15 0-30 5.5T285-777L144-635q-9 9-15 21t-8 24q-2 12 0 24.5t8 23.5l-58 58q-17-23-25-50.5T40-590q2-28 14-54.5T87-692l141-141q24-23 53.5-35t60.5-12q31 0 60.5 12t52.5 35l11 11 11-11q24-23 53.5-35t60.5-12q31 0 60.5 12t52.5 35l169 169q23 23 35 53t12 61q0 31-12 60.5T873-437L545-110q-14 14-32.5 22T474-80Zm-99-560Z" />
13851386
</svg>
13861387
</button>
1387-
</div>
1388-
1389-
<div class="ol-control ol-unselectable ol-control-custom button-control-box map-button-box nokiosk"
1390-
style=" bottom: 30px; border-radius: 5px;">
1391-
<button type="button" id="zoom-in" class="btn btn-primary map-button">
1388+
<button title="Zoom in" type="button" id="zoom-in" class="btn btn-primary map-button">
13921389
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24">
13931390
<path d="M440-440H200v-80h240v-240h80v240h240v80H520v240h-80v-240Z" />
13941391
</svg>
13951392
</button>
1396-
<button type="button" id="zoom-out" class="btn btn-primary map-button">
1393+
<button title="Zoom out" type="button" id="zoom-out" class="btn btn-primary map-button">
13971394
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24">
13981395
<path d="M200-440v-80h560v80H200Z" />
13991396
</svg>
@@ -1405,11 +1402,13 @@ <h3>NMEA Decoder</h3>
14051402
d="M480-118 120-398l66-50 294 228 294-228 66 50-360 280Zm0-202L120-600l360-280 360 280-360 280Zm0-280Zm0 178 230-178-230-178-230 178 230 178Z" />
14061403
</svg>
14071404
</button>
1408-
</div>
1409-
1410-
<div class="ol-control ol-unselectable ol-control-custom button-control-box map-button-box"
1411-
style="padding: 3px; bottom: 0px; right: 10px; font-size: 8px; border-radius: 0px;">
1412-
<span id="map_attributions"></span>
1405+
<button title="Map attribution" type="button" data-action="toggleAttribution"
1406+
class="btn btn-primary map-button color-grey">
1407+
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24">
1408+
<path
1409+
d="M440-280h80v-240h-80v240Zm40-320q17 0 28.5-11.5T520-640q0-17-11.5-28.5T480-680q-17 0-28.5 11.5T440-640q0 17 11.5 28.5T480-600Zm0 520q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z" />
1410+
</svg>
1411+
</button>
14131412
</div>
14141413
</div>
14151414
</div>

frontend/src/script.js

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -231,9 +231,10 @@ const ACTIONS = {
231231
openADSBExchangeCard: () => openExt('adsbexchange', card_mmsi),
232232
toggleStatcard: () => toggleStatcard(),
233233
toggleTablecard: () => toggleTablecard(),
234-
mapSettingsContextMenu: (e) => showContextMenu(e, '', '', ['settings', 'center', 'ctx-map']),
234+
mapSettingsContextMenu: (e, d, el) => showContextMenu(e, '', '', ['settings', 'ctx-map'], el),
235235
toggleCommunityPane: () => community.toggleCommunityPane(),
236236
showMapMenu: (e) => showMapMenu(e),
237+
toggleAttribution: () => toggleAttribution(),
237238
mainspaceContextMenu: (e) => showContextMenu(e, 0, '', ['settings']),
238239
plotsContextMenu: (e) => showContextMenu(e, '', 'charts', ['settings', 'ctx-charts']),
239240

@@ -1144,7 +1145,7 @@ function hideContextMenu(event) {
11441145
document.removeEventListener("click", hideContextMenu);
11451146
}
11461147

1147-
function showContextMenu(event, mmsi, type, context) {
1148+
function showContextMenu(event, mmsi, type, context, anchorEl) {
11481149

11491150
if (event && event.preventDefault) {
11501151
event.preventDefault();
@@ -1213,7 +1214,18 @@ function showContextMenu(event, mmsi, type, context) {
12131214

12141215
contextMenu.style.display = "block";
12151216

1216-
if (context.includes("center")) {
1217+
if (anchorEl) {
1218+
// Anchor above the control button (it sits near the bottom edge), so the
1219+
// menu unfurls upward instead of running off-screen.
1220+
contextMenu.style.transform = "none";
1221+
const btn = anchorEl.getBoundingClientRect();
1222+
const rect = contextMenu.getBoundingClientRect();
1223+
let left = Math.max(8, btn.right - rect.width);
1224+
let top = btn.top - rect.height - 8;
1225+
if (top < 8) top = Math.min(btn.bottom + 8, window.innerHeight - rect.height - 8);
1226+
contextMenu.style.left = left + "px";
1227+
contextMenu.style.top = top + "px";
1228+
} else if (context.includes("center")) {
12171229
contextMenu.style.left = "50%";
12181230
contextMenu.style.top = "50%";
12191231
contextMenu.style.transform = "translate(-50%, -50%)";
@@ -3010,9 +3022,9 @@ function showHoverTrack(mmsi) {
30103022
}
30113023

30123024
function toggleAttribution() {
3013-
const attribution = document.getElementById('map_attributions');
3014-
const currentDisplay = attribution.style.display;
3015-
attribution.style.display = currentDisplay === 'none' ? 'block' : 'none';
3025+
const foldout = document.getElementById('map-attribution-foldout');
3026+
if (!foldout) return;
3027+
foldout.style.display = foldout.style.display === 'block' ? 'none' : 'block';
30163028
}
30173029

30183030
function getTooltipContentBinary(mmsiOrBinary) {

frontend/src/style.css

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -639,39 +639,89 @@ td {
639639
}
640640

641641
.map-button-box {
642-
border: 2px solid var(--menu-border-color);
643-
border-radius: 5px;
644642
position: absolute;
645643
right: 10px;
646644
z-index: 1004;
645+
display: flex;
646+
flex-direction: column;
647+
overflow: hidden;
648+
border: 2px solid var(--menu-border-color);
649+
border-radius: 9px;
647650
background-color: var(--menu-background-color);
648651
fill: var(--menu-font-color);
649652
color: var(--menu-font-color);
653+
box-shadow: 0 2px 8px var(--shadow-color);
650654
transition: transform 0.3s ease-out;
651655
}
652656

657+
/* Pill-shaped group (capsule ends) for the top "more tools" controls */
658+
.map-button-box.map-pill {
659+
border-radius: 22px;
660+
}
661+
653662
.map-button-box.active {
654663
transform: translateX(-425px);
655664
}
656665

657666
.map-button {
658-
width: 26px !important;
659-
height: 26px !important;
667+
width: 34px !important;
668+
height: 34px !important;
660669
border: none !important;
661670
margin: 0px !important;
671+
padding: 0 !important;
672+
display: flex !important;
673+
align-items: center !important;
674+
justify-content: center !important;
662675
background-color: var(--menu-background-color) !important;
663676
fill: var(--menu-font-color) !important;
664677
color: var(--menu-font-color) !important;
665-
border-radius: inherit !important;
678+
border-radius: 0 !important;
679+
}
680+
681+
/* Thin divider between stacked buttons within a group */
682+
.map-button+.map-button {
683+
border-top: 1px solid var(--menu-border-color) !important;
684+
}
685+
686+
.map-button:hover {
687+
background-color: var(--menu-border-color) !important;
666688
}
667689

668690
.map-button:focus {
669691
outline: none !important;
670692
}
671693

672694
.map-button svg {
673-
width: 12px !important;
674-
height: 12px !important;
695+
width: 19px !important;
696+
height: 19px !important;
697+
}
698+
699+
/* Top pill holds denser glyphs (ship/ruler) — render them a touch smaller
700+
so they don't look heavier than the bottom group's line icons */
701+
.map-pill .map-button svg {
702+
width: 15px !important;
703+
height: 15px !important;
704+
}
705+
706+
/* Attribution fold-out, opened from the (i) button in the bottom control group */
707+
.map-attribution-foldout {
708+
position: absolute;
709+
right: 54px;
710+
bottom: 30px;
711+
max-width: 260px;
712+
z-index: 1004;
713+
padding: 6px 10px;
714+
border: 1px solid var(--menu-border-color);
715+
border-radius: 8px;
716+
background-color: var(--menu-background-color);
717+
color: var(--menu-font-color);
718+
box-shadow: 0 2px 8px var(--shadow-color);
719+
font-size: 10px;
720+
line-height: 1.4;
721+
}
722+
723+
.map-attribution-foldout a {
724+
color: inherit;
675725
}
676726

677727
#tableselection {}

0 commit comments

Comments
 (0)