mapshaper 0.7.60 → 0.7.62
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.
- package/mapshaper.js +2438 -129
- package/package.json +2 -1
- package/www/index.html +12 -6
- package/www/mapshaper-gui.js +7054 -1418
- package/www/mapshaper.js +2438 -129
- package/www/page.css +917 -221
package/www/page.css
CHANGED
|
@@ -577,6 +577,19 @@ textarea:focus {
|
|
|
577
577
|
box-shadow: 0 0 0 2px rgba(212, 168, 0, 0.4);
|
|
578
578
|
}
|
|
579
579
|
|
|
580
|
+
/* The interface is pointer-only. No custom control carries a tabindex, because
|
|
581
|
+
partial keyboard support was worse than none: tabbing reached a few buttons
|
|
582
|
+
and skipped most, and the menus a tab stop could open could not then be
|
|
583
|
+
navigated or dismissed from the keyboard.
|
|
584
|
+
|
|
585
|
+
This is the backstop for what is still focusable of necessity -- a span made
|
|
586
|
+
contenteditable for renaming, an element focused by script -- so that a UA
|
|
587
|
+
focus ring cannot appear over the interface. Text fields are excluded: they
|
|
588
|
+
have to show where the caret is, and the rule above is how they show it. */
|
|
589
|
+
:focus:not(input):not(textarea):not(select) {
|
|
590
|
+
outline: none;
|
|
591
|
+
}
|
|
592
|
+
|
|
580
593
|
::placeholder {
|
|
581
594
|
color: #aaa;
|
|
582
595
|
opacity: 1;
|
|
@@ -1224,8 +1237,9 @@ body.simplify .layer-control-btn {
|
|
|
1224
1237
|
}
|
|
1225
1238
|
|
|
1226
1239
|
.layer-control .no-layer-note {
|
|
1227
|
-
color: #
|
|
1240
|
+
color: #777;
|
|
1228
1241
|
margin: 0 0 5px 0;
|
|
1242
|
+
font-size: 13px;
|
|
1229
1243
|
}
|
|
1230
1244
|
|
|
1231
1245
|
.layer-add-links {
|
|
@@ -1248,6 +1262,11 @@ body.simplify .layer-control-btn {
|
|
|
1248
1262
|
font-weight: bold;
|
|
1249
1263
|
}
|
|
1250
1264
|
|
|
1265
|
+
/* "Draw:", which labels the links that follow it rather than being one */
|
|
1266
|
+
.new-layer-label {
|
|
1267
|
+
color: #777;
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1251
1270
|
.layer-menu .layer-list {
|
|
1252
1271
|
margin-top: -5px;
|
|
1253
1272
|
/* margin: 0 0 7px 0; */
|
|
@@ -1972,6 +1991,7 @@ div.basemap-style-btn.active {
|
|
|
1972
1991
|
|
|
1973
1992
|
.map-layers.add-points,
|
|
1974
1993
|
.map-layers.draw-tool,
|
|
1994
|
+
.map-layers.label-tool,
|
|
1975
1995
|
.map-layers.snip-tool,
|
|
1976
1996
|
.map-layers.ruler-tool {
|
|
1977
1997
|
cursor: crosshair;
|
|
@@ -1981,6 +2001,12 @@ div.basemap-style-btn.active {
|
|
|
1981
2001
|
cursor: default;
|
|
1982
2002
|
}
|
|
1983
2003
|
|
|
2004
|
+
/* Over a label's knot or anchor handle, where a drag moves the handle rather
|
|
2005
|
+
than placing a label or panning the map. */
|
|
2006
|
+
.map-layers.label-handle {
|
|
2007
|
+
cursor: move;
|
|
2008
|
+
}
|
|
2009
|
+
|
|
1984
2010
|
.map-layers.ruler-dragging {
|
|
1985
2011
|
cursor: grabbing;
|
|
1986
2012
|
}
|
|
@@ -2060,23 +2086,181 @@ body.pan.panning .map-layers:not(.drawing) {
|
|
|
2060
2086
|
cursor: pointer;
|
|
2061
2087
|
}
|
|
2062
2088
|
|
|
2063
|
-
.map-layers > svg text.
|
|
2064
|
-
stroke: #
|
|
2089
|
+
.map-layers > svg text.label-style-selected {
|
|
2090
|
+
stroke: #fce300;
|
|
2091
|
+
stroke-opacity: 0.25;
|
|
2065
2092
|
paint-order: stroke fill;
|
|
2066
2093
|
stroke-width: 4px;
|
|
2067
2094
|
stroke-linecap: round;
|
|
2068
2095
|
stroke-linejoin: round;
|
|
2069
2096
|
}
|
|
2070
2097
|
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2098
|
+
/* A path label whose text is longer than its path. Export drops these; the
|
|
2099
|
+
editor keeps them visible and marked, because a hidden label can't be
|
|
2100
|
+
found and so can't be fixed. Same halo convention as the states above. */
|
|
2101
|
+
.map-layers > svg text.label-overflow {
|
|
2102
|
+
stroke: #ff7f2a;
|
|
2103
|
+
stroke-opacity: 0.45;
|
|
2074
2104
|
paint-order: stroke fill;
|
|
2075
2105
|
stroke-width: 4px;
|
|
2076
2106
|
stroke-linecap: round;
|
|
2077
2107
|
stroke-linejoin: round;
|
|
2078
2108
|
}
|
|
2079
2109
|
|
|
2110
|
+
/* --- IN-PLACE LABEL EDITING --- */
|
|
2111
|
+
|
|
2112
|
+
/* The textarea is the model of record for an editing session: it holds focus so
|
|
2113
|
+
that keyboard handling, selection, clipboard and IME all come from the
|
|
2114
|
+
browser. It is invisible but must stay focusable, so it cannot be hidden with
|
|
2115
|
+
display:none or visibility:hidden. */
|
|
2116
|
+
.label-edit-input {
|
|
2117
|
+
position: absolute;
|
|
2118
|
+
z-index: -1;
|
|
2119
|
+
opacity: 0;
|
|
2120
|
+
width: 1px;
|
|
2121
|
+
height: 1em;
|
|
2122
|
+
padding: 0;
|
|
2123
|
+
border: none;
|
|
2124
|
+
resize: none;
|
|
2125
|
+
overflow: hidden;
|
|
2126
|
+
white-space: pre;
|
|
2127
|
+
pointer-events: none;
|
|
2128
|
+
}
|
|
2129
|
+
|
|
2130
|
+
.label-edit-overlay {
|
|
2131
|
+
pointer-events: none;
|
|
2132
|
+
}
|
|
2133
|
+
|
|
2134
|
+
/* Label tool cues: an outline around the object rather than a halo over the
|
|
2135
|
+
glyphs, so that it reads as something you have hold of. A solid line, to
|
|
2136
|
+
distinguish it from the dashed box of a label being typed into -- the two
|
|
2137
|
+
states look different because they behave differently.
|
|
2138
|
+
|
|
2139
|
+
Hover and selection draw the same shapes, because they mean the same thing
|
|
2140
|
+
about the same object; hover is simply lighter. The alternative, highlighting
|
|
2141
|
+
the anchor point on hover and the label on selection, made the two look like
|
|
2142
|
+
different objects. */
|
|
2143
|
+
.label-cue {
|
|
2144
|
+
pointer-events: none;
|
|
2145
|
+
}
|
|
2146
|
+
|
|
2147
|
+
.label-cue-hovered {
|
|
2148
|
+
opacity: 0.4;
|
|
2149
|
+
}
|
|
2150
|
+
|
|
2151
|
+
/* Hairline, like every other reference shape the tool draws: the box says where
|
|
2152
|
+
the label is, and a heavier outline reads as an object in its own right
|
|
2153
|
+
rather than as a mark on one. */
|
|
2154
|
+
.label-cue-box {
|
|
2155
|
+
fill: none;
|
|
2156
|
+
stroke: #3a7ddc;
|
|
2157
|
+
stroke-width: 1px;
|
|
2158
|
+
vector-effect: non-scaling-stroke;
|
|
2159
|
+
}
|
|
2160
|
+
|
|
2161
|
+
/* The anchor is what the text is positioned against, and label-pos can put it
|
|
2162
|
+
well outside the box, so it is worth marking on its own.
|
|
2163
|
+
Drawn as a ring rather than a dot, and beneath the glyphs: a centered label
|
|
2164
|
+
sits right on top of its anchor, and a filled marker would blot out a letter.
|
|
2165
|
+
Same treatment as the path guide's knots, since both are handles. */
|
|
2166
|
+
.label-cue-anchor {
|
|
2167
|
+
fill: #fff;
|
|
2168
|
+
stroke: #3a7ddc;
|
|
2169
|
+
stroke-width: 1.5px;
|
|
2170
|
+
vector-effect: non-scaling-stroke;
|
|
2171
|
+
}
|
|
2172
|
+
|
|
2173
|
+
/* The line between an anchor and the text being dragged away from it, drawn
|
|
2174
|
+
only while that drag is on. Dashed, and a shade lighter than the box: it is
|
|
2175
|
+
the relationship being edited rather than a part of either end. */
|
|
2176
|
+
.label-cue-tether {
|
|
2177
|
+
fill: none;
|
|
2178
|
+
stroke: #3a7ddc;
|
|
2179
|
+
stroke-width: 1px;
|
|
2180
|
+
stroke-dasharray: 2 2;
|
|
2181
|
+
opacity: 0.7;
|
|
2182
|
+
vector-effect: non-scaling-stroke;
|
|
2183
|
+
}
|
|
2184
|
+
|
|
2185
|
+
/* A copy of the baseline the label's text runs along. Unfilled: stroking an
|
|
2186
|
+
open curve must not paint the area it encloses. */
|
|
2187
|
+
.label-cue-curve {
|
|
2188
|
+
fill: none;
|
|
2189
|
+
stroke: #3a7ddc;
|
|
2190
|
+
stroke-width: 1px;
|
|
2191
|
+
stroke-opacity: 0.8;
|
|
2192
|
+
vector-effect: non-scaling-stroke;
|
|
2193
|
+
}
|
|
2194
|
+
|
|
2195
|
+
/* The grab handles on a selected curve, one per knot. Same ring treatment as
|
|
2196
|
+
the anchor marker and the path guide's knots, because all three are handles
|
|
2197
|
+
and a knot is an anchor on a curve.
|
|
2198
|
+
A corner knot is drawn as a square by the renderer; both shapes share this
|
|
2199
|
+
rule, so a corner differs in outline and not in colour. */
|
|
2200
|
+
.label-cue-knot {
|
|
2201
|
+
fill: #fff;
|
|
2202
|
+
stroke: #3a7ddc;
|
|
2203
|
+
stroke-width: 1.5px;
|
|
2204
|
+
vector-effect: non-scaling-stroke;
|
|
2205
|
+
}
|
|
2206
|
+
|
|
2207
|
+
/* Transparent rather than fill:none / stroke:none, because an unpainted shape
|
|
2208
|
+
is not hit-testable. */
|
|
2209
|
+
.label-edit-hit-area {
|
|
2210
|
+
fill: transparent;
|
|
2211
|
+
stroke: none;
|
|
2212
|
+
pointer-events: all;
|
|
2213
|
+
}
|
|
2214
|
+
|
|
2215
|
+
/* The thickened baseline follows the curve, so only its stroke should catch
|
|
2216
|
+
clicks -- filling an open curve would claim the whole area it encloses. */
|
|
2217
|
+
.label-edit-hit-baseline {
|
|
2218
|
+
fill: none;
|
|
2219
|
+
stroke: transparent;
|
|
2220
|
+
pointer-events: stroke;
|
|
2221
|
+
}
|
|
2222
|
+
|
|
2223
|
+
/* The curve a label's text is set along, ghosted while the label is open for
|
|
2224
|
+
editing. Fainter than the guide drawn while the path is being placed, and in
|
|
2225
|
+
the same violet, because it is the same curve at a later stage. */
|
|
2226
|
+
.label-edit-path {
|
|
2227
|
+
fill: none;
|
|
2228
|
+
stroke: #cc6acc;
|
|
2229
|
+
stroke-width: 1.2px;
|
|
2230
|
+
stroke-opacity: 0.4;
|
|
2231
|
+
vector-effect: non-scaling-stroke;
|
|
2232
|
+
}
|
|
2233
|
+
|
|
2234
|
+
/* Shows where an anchored label is even when it has no text -- the state a
|
|
2235
|
+
label is in between being created and being typed into. A path label shows
|
|
2236
|
+
its ghosted curve instead.
|
|
2237
|
+
Solid, not dashed: at the size of an empty label the dashes were most of the
|
|
2238
|
+
outline, which made the box look tentative rather than like a place to type. */
|
|
2239
|
+
.label-edit-box {
|
|
2240
|
+
fill: none;
|
|
2241
|
+
stroke: #cc6acc;
|
|
2242
|
+
stroke-width: 1px;
|
|
2243
|
+
vector-effect: non-scaling-stroke;
|
|
2244
|
+
}
|
|
2245
|
+
|
|
2246
|
+
.label-edit-selection {
|
|
2247
|
+
fill: #cc6acc;
|
|
2248
|
+
fill-opacity: 0.3;
|
|
2249
|
+
stroke: none;
|
|
2250
|
+
}
|
|
2251
|
+
|
|
2252
|
+
.label-edit-caret {
|
|
2253
|
+
stroke: #000;
|
|
2254
|
+
stroke-width: 1.5px;
|
|
2255
|
+
vector-effect: non-scaling-stroke;
|
|
2256
|
+
animation: label-caret-blink 1.1s steps(1) infinite;
|
|
2257
|
+
}
|
|
2258
|
+
|
|
2259
|
+
@keyframes label-caret-blink {
|
|
2260
|
+
0%, 50% { stroke-opacity: 1; }
|
|
2261
|
+
50.01%, 100% { stroke-opacity: 0; }
|
|
2262
|
+
}
|
|
2263
|
+
|
|
2080
2264
|
/* --- MAP BUTTONS --- */
|
|
2081
2265
|
|
|
2082
2266
|
/*.pointer-btn {
|
|
@@ -2174,11 +2358,31 @@ body.pan.panning .map-layers:not(.drawing) {
|
|
|
2174
2358
|
}
|
|
2175
2359
|
|
|
2176
2360
|
.label-style-panel {
|
|
2361
|
+
/* The shape of a field in every style panel: the label panel set them,
|
|
2362
|
+
and the line, polygon and circle panels are drawn from the same parts.
|
|
2363
|
+
A row is only legible when the select, the colour field, the size field
|
|
2364
|
+
and the button beside them are all the same height. */
|
|
2365
|
+
--label-field-height: 22px;
|
|
2366
|
+
--label-field-radius: 4px;
|
|
2367
|
+
--label-field-border: #bbb;
|
|
2368
|
+
/* The narrow column of a split row, wide enough for the longest caption
|
|
2369
|
+
over it -- "Letter spacing", which measures 71px -- and the same in
|
|
2370
|
+
every row of every panel, so that the field edges line up down the
|
|
2371
|
+
whole stack. */
|
|
2372
|
+
--label-split-b-width: 74px;
|
|
2373
|
+
/* Same glyph on native <select>s and the saved-style menu. The custom menu
|
|
2374
|
+
used a CSS triangle; the font menus used the OS arrow. A drawn stroke
|
|
2375
|
+
rather than a filled triangle: it is lighter than the text beside it,
|
|
2376
|
+
which is what a menu's arrow should be. */
|
|
2377
|
+
--label-menu-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='7' viewBox='0 0 10 7'%3E%3Cpath fill='none' stroke='%23666' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round' d='M1 1.5l4 4 4-4'/%3E%3C/svg%3E");
|
|
2177
2378
|
position: absolute;
|
|
2178
2379
|
z-index: 21;
|
|
2179
2380
|
top: 6px;
|
|
2180
2381
|
right: 36px;
|
|
2181
|
-
|
|
2382
|
+
/* Wide enough for a pair of controls side by side, which is what these
|
|
2383
|
+
panels are mostly made of: at 185px the narrow column of a pair was too
|
|
2384
|
+
narrow for its own caption, and "Letter spacing" was clipped. */
|
|
2385
|
+
width: 216px;
|
|
2182
2386
|
padding: 8px 12px 12px;
|
|
2183
2387
|
text-align: left;
|
|
2184
2388
|
background-color: white;
|
|
@@ -2190,7 +2394,7 @@ body.pan.panning .map-layers:not(.drawing) {
|
|
|
2190
2394
|
.label-style-panel button,
|
|
2191
2395
|
.label-style-panel select,
|
|
2192
2396
|
.label-style-panel input {
|
|
2193
|
-
font-size:
|
|
2397
|
+
font-size: 12px;
|
|
2194
2398
|
}
|
|
2195
2399
|
|
|
2196
2400
|
.label-style-panel button.label-style-close {
|
|
@@ -2198,14 +2402,26 @@ body.pan.panning .map-layers:not(.drawing) {
|
|
|
2198
2402
|
}
|
|
2199
2403
|
|
|
2200
2404
|
|
|
2405
|
+
.label-style-panel select,
|
|
2406
|
+
.label-saved-style-btn {
|
|
2407
|
+
background-image: var(--label-menu-chevron);
|
|
2408
|
+
background-repeat: no-repeat;
|
|
2409
|
+
background-position: right 6px center;
|
|
2410
|
+
background-size: 10px 7px;
|
|
2411
|
+
}
|
|
2412
|
+
|
|
2201
2413
|
.label-style-panel select {
|
|
2202
|
-
|
|
2414
|
+
-webkit-appearance: none;
|
|
2415
|
+
appearance: none;
|
|
2416
|
+
padding: 0 20px 0 6px;
|
|
2203
2417
|
}
|
|
2204
2418
|
|
|
2419
|
+
/* The size the app's dialogs title themselves at (.info-box h3), so that a
|
|
2420
|
+
panel pinned over the map is headed like the menus beside it. */
|
|
2205
2421
|
.label-style-panel-title {
|
|
2206
2422
|
position: relative;
|
|
2207
2423
|
font-weight: 600;
|
|
2208
|
-
font-size:
|
|
2424
|
+
font-size: 17px;
|
|
2209
2425
|
}
|
|
2210
2426
|
|
|
2211
2427
|
.label-style-close {
|
|
@@ -2235,9 +2451,13 @@ body.pan.panning .map-layers:not(.drawing) {
|
|
|
2235
2451
|
box-sizing: border-box;
|
|
2236
2452
|
}
|
|
2237
2453
|
|
|
2238
|
-
.label-style-panel select
|
|
2454
|
+
.label-style-panel select,
|
|
2455
|
+
.label-style-panel input[type="text"] {
|
|
2456
|
+
box-sizing: border-box;
|
|
2457
|
+
height: var(--label-field-height);
|
|
2239
2458
|
background-color: white;
|
|
2240
|
-
border: 1px solid
|
|
2459
|
+
border: 1px solid var(--label-field-border);
|
|
2460
|
+
border-radius: var(--label-field-radius);
|
|
2241
2461
|
box-shadow: none;
|
|
2242
2462
|
}
|
|
2243
2463
|
|
|
@@ -2250,10 +2470,6 @@ body.pan.panning .map-layers:not(.drawing) {
|
|
|
2250
2470
|
.label-style-panel input[type="text"] {
|
|
2251
2471
|
-webkit-appearance: none;
|
|
2252
2472
|
appearance: none;
|
|
2253
|
-
background: white;
|
|
2254
|
-
border: 1px solid #999;
|
|
2255
|
-
border-radius: 0;
|
|
2256
|
-
box-shadow: none;
|
|
2257
2473
|
}
|
|
2258
2474
|
|
|
2259
2475
|
.label-style-panel input[type="text"]:focus {
|
|
@@ -2283,277 +2499,616 @@ body.pan.panning .map-layers:not(.drawing) {
|
|
|
2283
2499
|
color: #555;
|
|
2284
2500
|
}
|
|
2285
2501
|
|
|
2286
|
-
.label-saved-style-row select {
|
|
2287
|
-
width: 100%;
|
|
2288
|
-
margin-bottom: 4px;
|
|
2289
|
-
}
|
|
2290
|
-
|
|
2291
|
-
.label-saved-style-row {
|
|
2292
|
-
margin-top: 10px;
|
|
2293
|
-
padding-top: 8px;
|
|
2294
|
-
border-top: 1px solid #ccc;
|
|
2295
|
-
}
|
|
2296
|
-
|
|
2297
|
-
.label-saved-style-row button,
|
|
2298
2502
|
.label-style-row button {
|
|
2299
2503
|
margin-right: 5px;
|
|
2300
2504
|
}
|
|
2301
2505
|
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
align-items: start;
|
|
2307
|
-
}
|
|
2506
|
+
/* Saved styles: a menu that applies one and a button that saves the current
|
|
2507
|
+
one, under a heading. The menu is built from divs rather than being a
|
|
2508
|
+
<select>, because each row carries its own delete button -- see
|
|
2509
|
+
gui-style-preset-control.mjs.
|
|
2308
2510
|
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2511
|
+
A section of the panel like Text and Icon, so the spacing above it is the
|
|
2512
|
+
whitespace those sections are separated by, in the panel that has them, and
|
|
2513
|
+
this margin in the layer panel, which does not. */
|
|
2514
|
+
.label-saved-style-row {
|
|
2515
|
+
margin-top: 11px;
|
|
2314
2516
|
}
|
|
2315
2517
|
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2518
|
+
/* The two controls sit in the panel's A and B columns, on the same grid as a
|
|
2519
|
+
split row: Apply style lines up with the fields and menus above it, and
|
|
2520
|
+
Save current with the narrow column beside them. Every style panel is the
|
|
2521
|
+
same width, so one grid does for all three. */
|
|
2522
|
+
.label-saved-style-controls {
|
|
2523
|
+
display: grid;
|
|
2524
|
+
grid-template-columns: 1fr var(--label-split-b-width);
|
|
2525
|
+
column-gap: 10px;
|
|
2526
|
+
margin-top: 4px;
|
|
2320
2527
|
}
|
|
2321
2528
|
|
|
2322
|
-
|
|
2529
|
+
/* min-width:0 lets the menu shrink to its column: a grid track is otherwise
|
|
2530
|
+
at least as wide as its contents, and the names in the list can be long. */
|
|
2531
|
+
.label-saved-style-menu {
|
|
2323
2532
|
position: relative;
|
|
2533
|
+
min-width: 0;
|
|
2324
2534
|
}
|
|
2325
2535
|
|
|
2326
|
-
|
|
2536
|
+
/* Sized, bordered and lettered like the panel's fields rather than like its
|
|
2537
|
+
19px icon buttons, because that is what these two are: a menu the width of
|
|
2538
|
+
a field, and a button beside it. The type is the fields' own -- these are
|
|
2539
|
+
divs, so the panel's rule for button, select and input does not reach them
|
|
2540
|
+
and they were left at the app's 14px. */
|
|
2541
|
+
.label-saved-style-button {
|
|
2327
2542
|
box-sizing: border-box;
|
|
2328
|
-
|
|
2543
|
+
display: flex;
|
|
2544
|
+
align-items: center;
|
|
2545
|
+
height: var(--label-field-height);
|
|
2546
|
+
padding: 0 6px;
|
|
2547
|
+
border: 1px solid var(--label-field-border);
|
|
2548
|
+
border-radius: var(--label-field-radius);
|
|
2549
|
+
background-color: white;
|
|
2550
|
+
font-size: 12px;
|
|
2551
|
+
color: #000;
|
|
2329
2552
|
cursor: pointer;
|
|
2330
|
-
|
|
2331
|
-
border-radius: 3px;
|
|
2332
|
-
background: #eee;
|
|
2333
|
-
padding: 0;
|
|
2334
|
-
height: 19px;
|
|
2335
|
-
width: 19px;
|
|
2553
|
+
user-select: none;
|
|
2336
2554
|
}
|
|
2337
2555
|
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2556
|
+
/* "Save current" is 63px of SourceSans3 and 68px of the Arial it falls back
|
|
2557
|
+
to, in a column of 74: too near its edges to read as inset from them, so
|
|
2558
|
+
the label is centred and the padding is only what keeps the widest of the
|
|
2559
|
+
two fonts off the border. */
|
|
2560
|
+
.label-saved-style-save {
|
|
2561
|
+
justify-content: center;
|
|
2562
|
+
padding: 0 2px;
|
|
2563
|
+
}
|
|
2564
|
+
|
|
2565
|
+
/* The panel's own disabled look: live colours, faded as a whole. */
|
|
2566
|
+
.label-saved-style-button.disabled {
|
|
2341
2567
|
opacity: 0.45;
|
|
2568
|
+
cursor: default;
|
|
2342
2569
|
}
|
|
2343
2570
|
|
|
2344
|
-
.label-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
height: 19px;
|
|
2348
|
-
margin-right: 5px;
|
|
2349
|
-
padding: 0;
|
|
2350
|
-
vertical-align: top;
|
|
2351
|
-
border: 1px solid #888;
|
|
2352
|
-
cursor: pointer;
|
|
2571
|
+
.label-saved-style-button:hover:not(.disabled),
|
|
2572
|
+
.label-saved-style-button.open {
|
|
2573
|
+
background-color: #f0f0f0;
|
|
2353
2574
|
}
|
|
2354
2575
|
|
|
2355
|
-
.label-
|
|
2356
|
-
|
|
2357
|
-
height: 19px;
|
|
2358
|
-
padding-top: 0;
|
|
2359
|
-
padding-bottom: 0;
|
|
2360
|
-
box-sizing: border-box;
|
|
2361
|
-
vertical-align: top;
|
|
2576
|
+
.label-saved-style-btn {
|
|
2577
|
+
padding-right: 20px;
|
|
2362
2578
|
}
|
|
2363
2579
|
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2580
|
+
/* The label gives way to the chevron rather than running under it. */
|
|
2581
|
+
.label-saved-style-btn span {
|
|
2582
|
+
flex: 1;
|
|
2583
|
+
min-width: 0;
|
|
2584
|
+
overflow: hidden;
|
|
2585
|
+
white-space: nowrap;
|
|
2586
|
+
text-overflow: ellipsis;
|
|
2367
2587
|
}
|
|
2368
2588
|
|
|
2369
|
-
|
|
2370
|
-
|
|
2589
|
+
/* Above the panel's own rows, and free to hang past its bottom edge -- the
|
|
2590
|
+
panel does not clip, and this row is the last thing in it. */
|
|
2591
|
+
.label-saved-style-list {
|
|
2592
|
+
position: absolute;
|
|
2593
|
+
top: 100%;
|
|
2594
|
+
left: 0;
|
|
2595
|
+
/* At least as wide as the menu, and wider if the names need it: the button
|
|
2596
|
+
is only as wide as the space left over beside Save current, and a style
|
|
2597
|
+
name is what the user is trying to read. It can hang over the map --
|
|
2598
|
+
nothing clips it -- but not indefinitely; past that, names ellipsize. */
|
|
2599
|
+
min-width: 100%;
|
|
2600
|
+
width: max-content;
|
|
2601
|
+
max-width: 240px;
|
|
2602
|
+
z-index: 30;
|
|
2603
|
+
margin-top: 2px;
|
|
2604
|
+
padding: 3px 2px;
|
|
2605
|
+
max-height: 40vh;
|
|
2606
|
+
overflow-y: auto;
|
|
2607
|
+
background: white;
|
|
2608
|
+
/* The size of the button it drops from, which is the size of a field. */
|
|
2609
|
+
font-size: 12px;
|
|
2610
|
+
border: 1px solid #bbb;
|
|
2611
|
+
border-radius: var(--label-field-radius);
|
|
2612
|
+
box-shadow: 0 2px 8px rgba(0,0,0,0.18);
|
|
2371
2613
|
}
|
|
2372
2614
|
|
|
2373
|
-
.label-
|
|
2374
|
-
|
|
2375
|
-
|
|
2615
|
+
.label-saved-style-list.drop-up {
|
|
2616
|
+
top: auto;
|
|
2617
|
+
bottom: 100%;
|
|
2618
|
+
margin: 0 0 2px 0;
|
|
2376
2619
|
}
|
|
2377
2620
|
|
|
2378
|
-
.
|
|
2379
|
-
|
|
2621
|
+
.label-saved-style-item {
|
|
2622
|
+
display: flex;
|
|
2623
|
+
align-items: center;
|
|
2380
2624
|
}
|
|
2381
2625
|
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2626
|
+
/* The name is the target for applying, and the highlight stops where it does,
|
|
2627
|
+
so that the row reads as two things to click rather than one with a hazard
|
|
2628
|
+
at the end of it. */
|
|
2629
|
+
.label-saved-style-name {
|
|
2630
|
+
flex: 1;
|
|
2631
|
+
min-width: 0;
|
|
2632
|
+
padding: 3px 4px 3px 8px;
|
|
2633
|
+
border-radius: 3px;
|
|
2634
|
+
color: var(--normal-text);
|
|
2635
|
+
cursor: pointer;
|
|
2636
|
+
overflow: hidden;
|
|
2637
|
+
white-space: nowrap;
|
|
2638
|
+
text-overflow: ellipsis;
|
|
2386
2639
|
}
|
|
2387
2640
|
|
|
2388
|
-
.
|
|
2389
|
-
|
|
2390
|
-
padding-top: 0;
|
|
2391
|
-
border-top: 0;
|
|
2641
|
+
.label-saved-style-name:hover {
|
|
2642
|
+
background: var(--lt-theme-col);
|
|
2392
2643
|
}
|
|
2393
2644
|
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2645
|
+
/* Hidden by visibility rather than left out, so that a name is the same width
|
|
2646
|
+
whether or not the pointer is on it. */
|
|
2647
|
+
.label-saved-style-delete {
|
|
2648
|
+
flex: none;
|
|
2649
|
+
width: 16px;
|
|
2650
|
+
padding: 2px 4px 2px 0;
|
|
2651
|
+
text-align: center;
|
|
2652
|
+
line-height: 1;
|
|
2653
|
+
color: #999;
|
|
2654
|
+
cursor: pointer;
|
|
2655
|
+
visibility: hidden;
|
|
2397
2656
|
}
|
|
2398
2657
|
|
|
2399
|
-
.
|
|
2400
|
-
|
|
2401
|
-
align-items: center;
|
|
2402
|
-
gap: 10px;
|
|
2658
|
+
.label-saved-style-item:hover .label-saved-style-delete {
|
|
2659
|
+
visibility: visible;
|
|
2403
2660
|
}
|
|
2404
2661
|
|
|
2405
|
-
.
|
|
2406
|
-
|
|
2407
|
-
align-items: baseline;
|
|
2408
|
-
gap: 2px;
|
|
2409
|
-
color: #555;
|
|
2662
|
+
.label-saved-style-delete:hover {
|
|
2663
|
+
color: #c00;
|
|
2410
2664
|
}
|
|
2411
2665
|
|
|
2412
|
-
.
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2666
|
+
.label-saved-style-empty {
|
|
2667
|
+
padding: 3px 8px;
|
|
2668
|
+
color: #999;
|
|
2669
|
+
cursor: default;
|
|
2416
2670
|
}
|
|
2417
2671
|
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2672
|
+
/* Two controls on one line: a font style and its size, a colour and its
|
|
2673
|
+
opacity, the icon shapes and the icon's size. Both columns are the same
|
|
2674
|
+
width in every row, rather than each row's right column being sized to
|
|
2675
|
+
whatever it happens to hold -- the panel is a stack of these pairs, and
|
|
2676
|
+
sizing them one row at a time leaves every field edge in a slightly
|
|
2677
|
+
different place.
|
|
2678
|
+
|
|
2679
|
+
Bottom-aligned, so that a caption above one control cannot push it out of
|
|
2680
|
+
line with the control beside it: the icon size has a "Size" over it and the
|
|
2681
|
+
shape buttons beside it have nothing, and the two still have to be level. */
|
|
2682
|
+
.label-split-row {
|
|
2683
|
+
display: grid;
|
|
2684
|
+
grid-template-columns: 1fr var(--label-split-b-width);
|
|
2685
|
+
column-gap: 10px;
|
|
2686
|
+
align-items: end;
|
|
2424
2687
|
}
|
|
2425
2688
|
|
|
2426
|
-
.
|
|
2427
|
-
|
|
2428
|
-
|
|
2689
|
+
.label-split-cell > span,
|
|
2690
|
+
.label-split-cell > .label-style-row-label {
|
|
2691
|
+
display: block;
|
|
2692
|
+
margin-bottom: 2px;
|
|
2429
2693
|
color: #555;
|
|
2430
2694
|
}
|
|
2431
2695
|
|
|
2432
|
-
.
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2696
|
+
/* Captions a couple of sizes down from the values they name. They are read
|
|
2697
|
+
once, when the panel is first met, and the narrow column of a split row is
|
|
2698
|
+
only as wide as the longest of them -- "Letter spacing" is what set it --
|
|
2699
|
+
so quieter captions are also a narrower panel. Direct children only: the
|
|
2700
|
+
colour picker's H/S/B captions are spans in a row too. */
|
|
2701
|
+
.label-style-panel .label-style-row > span,
|
|
2702
|
+
.label-style-panel .label-style-selection-row > span,
|
|
2703
|
+
.label-style-panel .label-split-cell > span,
|
|
2704
|
+
.label-style-panel .label-style-row > .label-style-row-label,
|
|
2705
|
+
.label-style-panel .label-split-cell > .label-style-row-label,
|
|
2706
|
+
.label-style-panel .label-icon-size-caption,
|
|
2707
|
+
.label-style-panel .point-style-note {
|
|
2708
|
+
font-size: 12px;
|
|
2436
2709
|
}
|
|
2437
2710
|
|
|
2438
|
-
.
|
|
2439
|
-
|
|
2440
|
-
align-items: flex-start;
|
|
2441
|
-
gap: 12px;
|
|
2711
|
+
.label-split-row .label-split-cell + .label-split-cell {
|
|
2712
|
+
white-space: nowrap;
|
|
2442
2713
|
}
|
|
2443
2714
|
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2715
|
+
/* Each column's control fills its column: the widths are the grid's to decide
|
|
2716
|
+
now, and a control keeping a width of its own would sit inside its cell
|
|
2717
|
+
rather than lining up with the one above it. */
|
|
2718
|
+
.label-split-cell > select,
|
|
2719
|
+
.label-split-cell > .size-field,
|
|
2720
|
+
.label-split-cell > input[type="text"] {
|
|
2721
|
+
width: 100%;
|
|
2722
|
+
box-sizing: border-box;
|
|
2448
2723
|
}
|
|
2449
2724
|
|
|
2450
|
-
.
|
|
2451
|
-
|
|
2452
|
-
align-items: flex-end;
|
|
2725
|
+
.label-split-cell > .size-field {
|
|
2726
|
+
display: flex;
|
|
2453
2727
|
}
|
|
2454
2728
|
|
|
2455
|
-
.
|
|
2456
|
-
position: relative;
|
|
2457
|
-
white-space: nowrap;
|
|
2729
|
+
.label-style-panel .size-field input.size-field-input {
|
|
2458
2730
|
flex: 1;
|
|
2731
|
+
width: auto;
|
|
2459
2732
|
}
|
|
2460
2733
|
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2734
|
+
/* A grid track is at least as wide as its contents unless told otherwise, and
|
|
2735
|
+
a text input's contents are twenty characters whatever width it is given --
|
|
2736
|
+
without this the colour field pushes the opacity beside it off the panel. */
|
|
2737
|
+
.label-split-row .label-split-cell {
|
|
2738
|
+
min-width: 0;
|
|
2739
|
+
}
|
|
2740
|
+
|
|
2741
|
+
.label-font-style-row select {
|
|
2742
|
+
width: 100%;
|
|
2467
2743
|
box-sizing: border-box;
|
|
2468
2744
|
}
|
|
2469
2745
|
|
|
2470
|
-
|
|
2471
|
-
|
|
2746
|
+
/* Both take their width from the split row's narrow column; a value reads from
|
|
2747
|
+
the left edge of the field, where the caption above it starts. */
|
|
2748
|
+
.label-style-panel .label-opacity-input,
|
|
2749
|
+
.label-style-panel .label-measure-input {
|
|
2750
|
+
padding: 0 4px;
|
|
2751
|
+
vertical-align: top;
|
|
2472
2752
|
}
|
|
2473
2753
|
|
|
2474
|
-
.
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2754
|
+
/* One disabled look for the whole panel. Left to themselves the controls each
|
|
2755
|
+
fade differently -- a select takes the browser's grey, an input with
|
|
2756
|
+
-webkit-appearance: none takes no styling at all, and a widget built from
|
|
2757
|
+
divs takes whatever it was given -- so an inert row ends up in three or four
|
|
2758
|
+
shades. Each control keeps its live colours and the whole thing is faded by
|
|
2759
|
+
the same amount, which also fades its border. */
|
|
2760
|
+
.label-style-panel select:disabled,
|
|
2761
|
+
.label-style-panel input[type="text"]:disabled,
|
|
2762
|
+
.label-style-panel .size-field.disabled,
|
|
2763
|
+
.label-style-panel .label-color-field.disabled,
|
|
2764
|
+
.label-style-panel .label-panel-action-btn.disabled,
|
|
2765
|
+
.label-style-panel .label-btn-group.disabled {
|
|
2766
|
+
opacity: 0.45;
|
|
2767
|
+
color: var(--normal-text);
|
|
2768
|
+
-webkit-text-fill-color: var(--normal-text);
|
|
2769
|
+
background-color: white;
|
|
2770
|
+
border-color: var(--label-field-border);
|
|
2771
|
+
}
|
|
2772
|
+
|
|
2773
|
+
/* Nothing inside an already-faded control fades again: two 0.45s over each
|
|
2774
|
+
other is 0.2, and a widget made of a wrapper and an input -- the size and
|
|
2775
|
+
colour fields -- was coming out half the weight of the plain input beside
|
|
2776
|
+
it. The parts still take their own disabled state, because a disabled input
|
|
2777
|
+
cannot be typed into and a disabled button cannot be pressed; it is only the
|
|
2778
|
+
fading that belongs to the whole. */
|
|
2779
|
+
.label-style-panel .label-btn-group.disabled .label-panel-btn.disabled,
|
|
2780
|
+
.label-style-panel .size-field.disabled .label-panel-btn.disabled,
|
|
2781
|
+
.label-style-panel .size-field.disabled input:disabled,
|
|
2782
|
+
.label-style-panel .label-color-field.disabled input:disabled,
|
|
2783
|
+
.label-style-panel .label-color-field.disabled .label-color-chit.disabled {
|
|
2784
|
+
opacity: 1;
|
|
2785
|
+
color: inherit;
|
|
2478
2786
|
}
|
|
2479
2787
|
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
.layer-style-panel .layer-color-row input[type="text"] {
|
|
2486
|
-
width: 79px;
|
|
2487
|
-
height: 19px;
|
|
2788
|
+
/* Whitespace and a bold heading separate the sections; a rule as well would be
|
|
2789
|
+
a third answer to a question already settled twice. */
|
|
2790
|
+
.label-style-panel .label-style-section + .label-style-section {
|
|
2791
|
+
margin-top: 12px;
|
|
2488
2792
|
padding-top: 0;
|
|
2489
|
-
|
|
2490
|
-
box-sizing: border-box;
|
|
2491
|
-
vertical-align: top;
|
|
2793
|
+
border-top: 0;
|
|
2492
2794
|
}
|
|
2493
2795
|
|
|
2494
|
-
|
|
2796
|
+
/* Baselines, not boxes: the heading and the caption beside it are set at
|
|
2797
|
+
different sizes, and centring their boxes leaves the smaller one's baseline
|
|
2798
|
+
a pixel or two high. The switch has no baseline to share, so it centres on
|
|
2799
|
+
the line itself. */
|
|
2800
|
+
.label-style-panel .label-style-section-title {
|
|
2495
2801
|
display: flex;
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
justify-content: flex-start;
|
|
2802
|
+
align-items: baseline;
|
|
2803
|
+
gap: 8px;
|
|
2499
2804
|
}
|
|
2500
2805
|
|
|
2501
|
-
.
|
|
2502
|
-
|
|
2503
|
-
margin: 0;
|
|
2806
|
+
.label-style-panel .label-style-section-title .label-toggle {
|
|
2807
|
+
align-self: center;
|
|
2504
2808
|
}
|
|
2505
2809
|
|
|
2506
|
-
.
|
|
2507
|
-
.
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2810
|
+
/* .hidden is one class and the rule above is two, so a heading told to hide
|
|
2811
|
+
would go on being laid out. The circle panel hides its Circles heading once
|
|
2812
|
+
the points are circles: the panel's title says so, and the section is the
|
|
2813
|
+
only thing left in it. */
|
|
2814
|
+
.label-style-panel .label-style-section-title.hidden {
|
|
2815
|
+
display: none;
|
|
2816
|
+
}
|
|
2817
|
+
|
|
2818
|
+
/* 15.5px is what the dialogs subhead at (.info-box h4); the weight is the
|
|
2819
|
+
sketch's, which wants these read as headings rather than as captions. */
|
|
2820
|
+
.label-style-panel .label-style-section-name {
|
|
2821
|
+
font-size: 15.5px;
|
|
2822
|
+
color: #222;
|
|
2823
|
+
}
|
|
2824
|
+
|
|
2825
|
+
.label-style-panel .label-style-section-minor .label-style-section-name {
|
|
2826
|
+
font-size: 12px;
|
|
2827
|
+
font-weight: normal;
|
|
2828
|
+
line-height: 1;
|
|
2511
2829
|
color: #555;
|
|
2512
2830
|
}
|
|
2513
2831
|
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2832
|
+
/* Where label text is measured (gui-label-measure.mjs). Off the page rather
|
|
2833
|
+
than display:none, which would give it no layout and its text no box. */
|
|
2834
|
+
.label-measure-svg {
|
|
2835
|
+
position: absolute;
|
|
2836
|
+
left: -10000px;
|
|
2837
|
+
top: -10000px;
|
|
2838
|
+
width: 1px;
|
|
2839
|
+
height: 1px;
|
|
2840
|
+
overflow: hidden;
|
|
2841
|
+
}
|
|
2842
|
+
|
|
2843
|
+
/* Closer to the heading above it than a row usually is, because that heading
|
|
2844
|
+
line carries this row's "Size" caption: the gap between a caption and the
|
|
2845
|
+
field it names is 2px everywhere else in the panel. */
|
|
2846
|
+
.text-style-panel .label-icon-shapes-row {
|
|
2847
|
+
margin-top: 2px;
|
|
2848
|
+
}
|
|
2849
|
+
|
|
2850
|
+
/* Pushed to the right and given the width of a split row's narrow column, so
|
|
2851
|
+
that it sits over the size field a row below it. */
|
|
2852
|
+
.text-style-panel .label-icon-size-caption {
|
|
2853
|
+
width: var(--label-split-b-width);
|
|
2854
|
+
margin-left: auto;
|
|
2855
|
+
font-weight: normal;
|
|
2856
|
+
color: #555;
|
|
2857
|
+
}
|
|
2858
|
+
|
|
2859
|
+
/* Darker than the app's default placeholder. These fields show the value the
|
|
2860
|
+
renderer will use when the property is absent -- 0 and auto are true of the
|
|
2861
|
+
label, they are just not stored on it -- so at #aaa they read as a control
|
|
2862
|
+
that is switched off rather than as an answer. */
|
|
2863
|
+
.label-style-panel ::placeholder {
|
|
2864
|
+
color: #777;
|
|
2520
2865
|
}
|
|
2521
2866
|
|
|
2522
|
-
|
|
2867
|
+
/* Buttons that answer one question share a border and sit flush, the way the
|
|
2868
|
+
size field and its stepper do: four shapes are four answers to "which
|
|
2869
|
+
symbol", not four separate controls. They divide the width of their cell so
|
|
2870
|
+
that the group lines up with the field above or below it. */
|
|
2871
|
+
.label-style-panel .label-btn-group {
|
|
2523
2872
|
display: flex;
|
|
2524
|
-
|
|
2525
|
-
|
|
2873
|
+
box-sizing: border-box;
|
|
2874
|
+
height: var(--label-field-height);
|
|
2875
|
+
border: 1px solid var(--label-field-border);
|
|
2876
|
+
border-radius: var(--label-field-radius);
|
|
2877
|
+
background: white;
|
|
2878
|
+
overflow: hidden;
|
|
2526
2879
|
}
|
|
2527
2880
|
|
|
2528
|
-
.
|
|
2529
|
-
|
|
2530
|
-
|
|
2881
|
+
.label-style-panel .label-btn-group .label-panel-btn {
|
|
2882
|
+
flex: 1;
|
|
2883
|
+
width: auto;
|
|
2884
|
+
height: auto;
|
|
2885
|
+
border: none;
|
|
2886
|
+
border-radius: 0;
|
|
2887
|
+
background: white;
|
|
2531
2888
|
}
|
|
2532
2889
|
|
|
2533
|
-
.
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2890
|
+
.label-style-panel .label-btn-group .label-panel-btn + .label-panel-btn {
|
|
2891
|
+
border-left: 1px solid #e0e0e0;
|
|
2892
|
+
}
|
|
2893
|
+
|
|
2894
|
+
/* Hover leaves the selected button alone. Every hover fill in the panel is
|
|
2895
|
+
lighter than the selection it would sit on, so pointing at the chosen answer
|
|
2896
|
+
made it look less chosen than its neighbours -- and there is nothing to
|
|
2897
|
+
preview anyway, since clicking it changes nothing. */
|
|
2898
|
+
.label-style-panel .label-btn-group .label-panel-btn:hover:not(.disabled):not(.selected) {
|
|
2899
|
+
background: #f0f0f0;
|
|
2900
|
+
}
|
|
2901
|
+
|
|
2902
|
+
/* A grey fill, not the inverse the panel's other buttons use: the glyph is
|
|
2903
|
+
what identifies the choice, and reversing it out makes the selected shape
|
|
2904
|
+
the hardest one to read. */
|
|
2905
|
+
.label-style-panel .label-btn-group .label-panel-btn.selected {
|
|
2906
|
+
background: #dcdcdc;
|
|
2907
|
+
color: black;
|
|
2908
|
+
}
|
|
2909
|
+
|
|
2910
|
+
/* A switch, because whether the label has a symbol at all is a yes/no that the
|
|
2911
|
+
four shapes below it then qualify. Off is a pale track with the knob left,
|
|
2912
|
+
on a dark one with the knob right. */
|
|
2913
|
+
.label-toggle {
|
|
2914
|
+
position: relative;
|
|
2915
|
+
flex: none;
|
|
2916
|
+
width: 26px;
|
|
2917
|
+
height: 15px;
|
|
2918
|
+
border-radius: 8px;
|
|
2919
|
+
background: #ccc;
|
|
2920
|
+
cursor: pointer;
|
|
2921
|
+
user-select: none;
|
|
2922
|
+
transition: background-color 0.12s;
|
|
2923
|
+
}
|
|
2924
|
+
|
|
2925
|
+
.label-toggle-knob {
|
|
2926
|
+
position: absolute;
|
|
2927
|
+
top: 2px;
|
|
2928
|
+
left: 2px;
|
|
2929
|
+
width: 11px;
|
|
2930
|
+
height: 11px;
|
|
2931
|
+
border-radius: 50%;
|
|
2540
2932
|
background: white;
|
|
2933
|
+
box-shadow: 0 1px 2px rgba(0,0,0,0.25);
|
|
2934
|
+
transition: left 0.12s;
|
|
2935
|
+
}
|
|
2936
|
+
|
|
2937
|
+
.label-toggle.on {
|
|
2938
|
+
background: #333;
|
|
2939
|
+
}
|
|
2940
|
+
|
|
2941
|
+
.label-toggle.on .label-toggle-knob {
|
|
2942
|
+
left: 13px;
|
|
2943
|
+
}
|
|
2944
|
+
|
|
2945
|
+
.label-toggle.disabled {
|
|
2946
|
+
opacity: 0.45;
|
|
2947
|
+
cursor: default;
|
|
2948
|
+
}
|
|
2949
|
+
|
|
2950
|
+
.label-style-section-title {
|
|
2951
|
+
margin-top: 11px;
|
|
2952
|
+
font-weight: 600;
|
|
2953
|
+
color: #333;
|
|
2954
|
+
}
|
|
2955
|
+
|
|
2956
|
+
.label-style-section + .label-style-section .label-style-section-title {
|
|
2957
|
+
margin-top: 0;
|
|
2958
|
+
}
|
|
2959
|
+
|
|
2960
|
+
/* The cell a colour field sits in, which is also what its picker hangs from:
|
|
2961
|
+
the picker is wider than the panel, so it opens over the map, and anchoring
|
|
2962
|
+
it to the cell keeps it on the same side of the panel as its field. */
|
|
2963
|
+
.label-color-row {
|
|
2964
|
+
position: relative;
|
|
2965
|
+
}
|
|
2966
|
+
|
|
2967
|
+
.label-panel-btn {
|
|
2968
|
+
box-sizing: border-box;
|
|
2969
|
+
user-select: none;
|
|
2970
|
+
cursor: pointer;
|
|
2971
|
+
border: 1px solid #999;
|
|
2972
|
+
border-radius: 3px;
|
|
2973
|
+
background: #eee;
|
|
2974
|
+
padding: 0;
|
|
2975
|
+
height: 19px;
|
|
2976
|
+
width: 19px;
|
|
2977
|
+
}
|
|
2978
|
+
|
|
2979
|
+
.label-panel-btn.disabled {
|
|
2980
|
+
color: #999;
|
|
2981
|
+
cursor: default;
|
|
2982
|
+
opacity: 0.45;
|
|
2983
|
+
}
|
|
2984
|
+
|
|
2985
|
+
/* A button with a word on it: Clear style, Random fills, Create. The same
|
|
2986
|
+
shape as Save current in the saved styles row, which is the same kind of
|
|
2987
|
+
thing -- a named action, as wide as its name -- and the same height as the
|
|
2988
|
+
fields above it. */
|
|
2989
|
+
.label-panel-action-btn {
|
|
2990
|
+
box-sizing: border-box;
|
|
2991
|
+
display: inline-flex;
|
|
2992
|
+
align-items: center;
|
|
2993
|
+
height: var(--label-field-height);
|
|
2994
|
+
padding: 0 8px;
|
|
2995
|
+
border: 1px solid var(--label-field-border);
|
|
2996
|
+
border-radius: var(--label-field-radius);
|
|
2997
|
+
background-color: white;
|
|
2998
|
+
color: var(--normal-text);
|
|
2541
2999
|
cursor: pointer;
|
|
3000
|
+
user-select: none;
|
|
3001
|
+
}
|
|
3002
|
+
|
|
3003
|
+
.label-panel-action-btn:hover:not(.disabled) {
|
|
3004
|
+
background-color: #f0f0f0;
|
|
3005
|
+
}
|
|
3006
|
+
|
|
3007
|
+
.label-panel-action-btn.disabled {
|
|
3008
|
+
cursor: default;
|
|
3009
|
+
}
|
|
3010
|
+
|
|
3011
|
+
/* Buttons wrap rather than run off the panel: two of them fit on one line in
|
|
3012
|
+
the polygon panel and would not if either name grew. */
|
|
3013
|
+
.label-panel-button-row {
|
|
3014
|
+
display: flex;
|
|
3015
|
+
flex-wrap: wrap;
|
|
3016
|
+
gap: 4px 6px;
|
|
3017
|
+
}
|
|
3018
|
+
|
|
3019
|
+
/* A swatch and its hex value inside one border: the pair is one answer to one
|
|
3020
|
+
question, and a separate button beside a text box reads as two. The swatch
|
|
3021
|
+
keeps its own outline so that white does not disappear into the field. */
|
|
3022
|
+
.label-style-panel .label-color-field {
|
|
3023
|
+
display: flex;
|
|
3024
|
+
align-items: center;
|
|
2542
3025
|
box-sizing: border-box;
|
|
3026
|
+
height: var(--label-field-height);
|
|
3027
|
+
padding: 0 3px;
|
|
3028
|
+
border: 1px solid var(--label-field-border);
|
|
3029
|
+
border-radius: var(--label-field-radius);
|
|
3030
|
+
background: white;
|
|
2543
3031
|
}
|
|
2544
3032
|
|
|
2545
|
-
.
|
|
2546
|
-
|
|
3033
|
+
.label-style-panel .label-color-field:focus-within {
|
|
3034
|
+
border-color: #d3aa00;
|
|
2547
3035
|
}
|
|
2548
3036
|
|
|
2549
|
-
.
|
|
2550
|
-
|
|
3037
|
+
.label-style-panel .label-color-field .label-color-chit {
|
|
3038
|
+
flex: none;
|
|
3039
|
+
width: 13px;
|
|
3040
|
+
height: 13px;
|
|
3041
|
+
margin-right: 6px;
|
|
3042
|
+
border: 1px solid #bbb;
|
|
3043
|
+
border-radius: 2px;
|
|
3044
|
+
}
|
|
3045
|
+
|
|
3046
|
+
.label-style-panel .label-color-field input[type="text"] {
|
|
3047
|
+
flex: 1;
|
|
3048
|
+
width: auto;
|
|
3049
|
+
min-width: 0;
|
|
3050
|
+
height: auto;
|
|
3051
|
+
padding: 0;
|
|
3052
|
+
border: none;
|
|
3053
|
+
border-radius: 0;
|
|
3054
|
+
background: transparent;
|
|
3055
|
+
box-shadow: none;
|
|
2551
3056
|
}
|
|
2552
3057
|
|
|
2553
|
-
.
|
|
3058
|
+
.label-style-panel .label-color-field input[type="text"]:focus {
|
|
3059
|
+
border: none;
|
|
3060
|
+
box-shadow: none;
|
|
3061
|
+
outline: none;
|
|
3062
|
+
}
|
|
3063
|
+
|
|
3064
|
+
.label-style-panel .label-color-field.disabled {
|
|
3065
|
+
opacity: 0.45;
|
|
3066
|
+
}
|
|
3067
|
+
|
|
3068
|
+
.label-color-row .label-color-picker {
|
|
3069
|
+
left: auto;
|
|
3070
|
+
right: 0;
|
|
3071
|
+
}
|
|
3072
|
+
|
|
3073
|
+
.label-color-row .label-color-picker input[type="text"] {
|
|
2554
3074
|
width: 45px;
|
|
2555
3075
|
}
|
|
2556
3076
|
|
|
3077
|
+
.label-css-row input {
|
|
3078
|
+
width: 100%;
|
|
3079
|
+
box-sizing: border-box;
|
|
3080
|
+
}
|
|
3081
|
+
|
|
3082
|
+
/* What a section of this panel says when there is nothing in it to set: the
|
|
3083
|
+
layer is drawn some way this panel cannot edit, or the thing the section is
|
|
3084
|
+
for has to be made in the console. Set like a caption, not like a field's
|
|
3085
|
+
value. */
|
|
3086
|
+
.point-style-note {
|
|
3087
|
+
color: #555;
|
|
3088
|
+
line-height: 1.3;
|
|
3089
|
+
}
|
|
3090
|
+
|
|
3091
|
+
.point-create-labels-row {
|
|
3092
|
+
display: flex;
|
|
3093
|
+
align-items: center;
|
|
3094
|
+
gap: 10px;
|
|
3095
|
+
}
|
|
3096
|
+
|
|
3097
|
+
.point-create-copy-label {
|
|
3098
|
+
display: inline-flex;
|
|
3099
|
+
align-items: center;
|
|
3100
|
+
gap: 4px;
|
|
3101
|
+
margin: 0;
|
|
3102
|
+
color: #555;
|
|
3103
|
+
font-size: 12px;
|
|
3104
|
+
}
|
|
3105
|
+
|
|
3106
|
+
.point-create-copy-label span {
|
|
3107
|
+
display: inline;
|
|
3108
|
+
margin: 0;
|
|
3109
|
+
color: #555;
|
|
3110
|
+
}
|
|
3111
|
+
|
|
2557
3112
|
.label-color-picker {
|
|
2558
3113
|
position: absolute;
|
|
2559
3114
|
z-index: 25;
|
|
@@ -2657,6 +3212,10 @@ body.dragging-color-picker * {
|
|
|
2657
3212
|
margin-left: auto;
|
|
2658
3213
|
}
|
|
2659
3214
|
|
|
3215
|
+
.label-style-selection-row {
|
|
3216
|
+
line-height: 1;
|
|
3217
|
+
}
|
|
3218
|
+
|
|
2660
3219
|
.label-style-selection-row button {
|
|
2661
3220
|
margin-right: 5px;
|
|
2662
3221
|
}
|
|
@@ -2699,17 +3258,66 @@ body.dragging-color-picker * {
|
|
|
2699
3258
|
background: white;
|
|
2700
3259
|
}
|
|
2701
3260
|
|
|
3261
|
+
/* Nine plain squares: a border on each would double the lines in a shape that
|
|
3262
|
+
is nothing but lines, so the cells are filled and the chosen one is dark. */
|
|
3263
|
+
.text-style-panel .label-position-grid {
|
|
3264
|
+
grid-template-columns: repeat(3, 10px);
|
|
3265
|
+
gap: 3px;
|
|
3266
|
+
margin-top: -13px;
|
|
3267
|
+
margin-bottom: 3px;
|
|
3268
|
+
}
|
|
3269
|
+
|
|
3270
|
+
.text-style-panel .label-position-grid .label-panel-btn {
|
|
3271
|
+
width: 10px;
|
|
3272
|
+
height: 10px;
|
|
3273
|
+
border: none;
|
|
3274
|
+
border-radius: 1px;
|
|
3275
|
+
background: #dcdcdc;
|
|
3276
|
+
}
|
|
3277
|
+
|
|
3278
|
+
.text-style-panel .label-position-grid .label-panel-btn:hover:not(.disabled):not(.selected) {
|
|
3279
|
+
background: #c4c4c4;
|
|
3280
|
+
}
|
|
3281
|
+
|
|
3282
|
+
.text-style-panel .label-position-grid .label-panel-btn.selected {
|
|
3283
|
+
background: black;
|
|
3284
|
+
}
|
|
3285
|
+
|
|
3286
|
+
/* The position a dragged label is nearest, which is where it roughly belongs
|
|
3287
|
+
and the cell that puts it back. Between the unlit grey and the lit black,
|
|
3288
|
+
because it is saying something weaker than either: not "here" but "about
|
|
3289
|
+
here, and not exactly". */
|
|
3290
|
+
.text-style-panel .label-position-grid .label-panel-btn.nearest:not(.selected) {
|
|
3291
|
+
background: #a0a0a0;
|
|
3292
|
+
}
|
|
3293
|
+
|
|
3294
|
+
/* The grid and the Fixed/Draggable toggle share the position row, the toggle
|
|
3295
|
+
against the right edge so that it lines up with the fields in the rows
|
|
3296
|
+
above. */
|
|
3297
|
+
.text-style-panel .label-position-row {
|
|
3298
|
+
margin-top: 3px;
|
|
3299
|
+
display: flex;
|
|
3300
|
+
/* align-items: center; */
|
|
3301
|
+
justify-content: space-between;
|
|
3302
|
+
}
|
|
3303
|
+
|
|
3304
|
+
/* Words rather than glyphs, so these segments size to their text instead of
|
|
3305
|
+
splitting the group evenly, and sit in a group narrow enough to read as one
|
|
3306
|
+
control beside the grid. */
|
|
3307
|
+
.text-style-panel .label-drag-mode-buttons .label-panel-btn {
|
|
3308
|
+
display: flex;
|
|
3309
|
+
flex: 0 0 auto;
|
|
3310
|
+
align-items: center;
|
|
3311
|
+
padding: 0 7px;
|
|
3312
|
+
font-size: 12px;
|
|
3313
|
+
}
|
|
3314
|
+
|
|
2702
3315
|
.label-panel-btn.selected {
|
|
2703
3316
|
background-color: black;
|
|
2704
3317
|
border-color: black;
|
|
2705
3318
|
color: white;
|
|
2706
3319
|
}
|
|
2707
3320
|
|
|
2708
|
-
.label-icon-buttons {
|
|
2709
|
-
display: flex;
|
|
2710
|
-
gap: 2px;
|
|
2711
|
-
}
|
|
2712
|
-
|
|
2713
3321
|
.label-icon-buttons .label-panel-btn {
|
|
2714
3322
|
display: flex;
|
|
2715
3323
|
align-items: center;
|
|
@@ -2724,7 +3332,6 @@ body.dragging-color-picker * {
|
|
|
2724
3332
|
stroke: none;
|
|
2725
3333
|
}
|
|
2726
3334
|
|
|
2727
|
-
.label-icon-buttons .label-panel-btn[data-icon="none"] .label-icon-symbol,
|
|
2728
3335
|
.label-icon-buttons .label-panel-btn[data-icon="ring"] .label-icon-symbol {
|
|
2729
3336
|
fill: none;
|
|
2730
3337
|
stroke: currentColor;
|
|
@@ -2737,41 +3344,113 @@ body.dragging-color-picker * {
|
|
|
2737
3344
|
transform: scale(1.4);
|
|
2738
3345
|
}
|
|
2739
3346
|
|
|
2740
|
-
.label-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
line-height: 18px;
|
|
3347
|
+
.label-align-buttons .label-panel-btn {
|
|
3348
|
+
display: flex;
|
|
3349
|
+
align-items: center;
|
|
3350
|
+
justify-content: center;
|
|
2745
3351
|
}
|
|
2746
3352
|
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
3353
|
+
/* Drawn larger than the icon symbols above, which share its viewBox but not
|
|
3354
|
+
its proportions: three rules across the middle are ink over less than half
|
|
3355
|
+
of the box, where a circle or a square fills most of its own, so at the same
|
|
3356
|
+
13px both the glyph and its weight read smaller than the shapes beside it.
|
|
3357
|
+
16px also puts the 16-unit viewBox at one unit per pixel, so the half-pixel
|
|
3358
|
+
baselines the rules are drawn on land where they were meant to. */
|
|
3359
|
+
.label-align-symbol {
|
|
3360
|
+
display: block;
|
|
3361
|
+
width: 16px;
|
|
3362
|
+
height: 16px;
|
|
3363
|
+
fill: none;
|
|
3364
|
+
stroke: currentColor;
|
|
3365
|
+
stroke-width: 1.5;
|
|
3366
|
+
stroke-linecap: round;
|
|
2750
3367
|
}
|
|
2751
3368
|
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
3369
|
+
/* A size field and its stepper share a border and sit flush, so that the three
|
|
3370
|
+
elements read as one control rather than three. The buttons are always
|
|
3371
|
+
visible: they are the primary affordance of the panel's most-used numbers,
|
|
3372
|
+
and revealing them on hover would either reserve their space anyway or
|
|
3373
|
+
overlap the value being adjusted. */
|
|
3374
|
+
.size-field {
|
|
3375
|
+
display: inline-flex;
|
|
3376
|
+
align-items: stretch;
|
|
3377
|
+
box-sizing: border-box;
|
|
3378
|
+
height: var(--label-field-height, 19px);
|
|
3379
|
+
border: 1px solid var(--label-field-border, #999);
|
|
3380
|
+
border-radius: var(--label-field-radius, 3px);
|
|
3381
|
+
background: #fff;
|
|
3382
|
+
overflow: hidden;
|
|
3383
|
+
vertical-align: top;
|
|
2755
3384
|
}
|
|
2756
3385
|
|
|
2757
|
-
.
|
|
2758
|
-
|
|
2759
|
-
margin-right: 0;
|
|
3386
|
+
.size-field.disabled {
|
|
3387
|
+
opacity: 0.45;
|
|
2760
3388
|
}
|
|
2761
3389
|
|
|
2762
|
-
.
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
3390
|
+
/* input.size-field-input, not .size-field-input: the panels give their text
|
|
3391
|
+
inputs a border through an attribute selector, and the field's own border is
|
|
3392
|
+
the one that has to show. */
|
|
3393
|
+
.size-field input.size-field-input {
|
|
3394
|
+
width: 40px;
|
|
3395
|
+
min-width: 0;
|
|
3396
|
+
height: auto;
|
|
3397
|
+
margin: 0;
|
|
3398
|
+
padding: 0 3px;
|
|
3399
|
+
border: none;
|
|
3400
|
+
border-radius: 0;
|
|
3401
|
+
box-shadow: none;
|
|
3402
|
+
background: transparent;
|
|
2768
3403
|
color: black;
|
|
2769
3404
|
}
|
|
2770
3405
|
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
3406
|
+
/* The field shows focus on its outer border, so that the ring cannot be drawn
|
|
3407
|
+
between the input and the stepper it shares an edge with. */
|
|
3408
|
+
.size-field input.size-field-input:focus {
|
|
3409
|
+
outline: none;
|
|
3410
|
+
border: none;
|
|
3411
|
+
box-shadow: none;
|
|
3412
|
+
}
|
|
3413
|
+
|
|
3414
|
+
.size-field:focus-within {
|
|
3415
|
+
border-color: #d3aa00;
|
|
3416
|
+
}
|
|
3417
|
+
|
|
3418
|
+
/* The stepper is inset from the field's border rather than dividing it: the
|
|
3419
|
+
value is the field's content and the arrows are a control within it, which
|
|
3420
|
+
is also how the native spinner reads. */
|
|
3421
|
+
.size-field .size-field-stepper {
|
|
3422
|
+
display: flex;
|
|
3423
|
+
flex-direction: column;
|
|
3424
|
+
margin: 2px 2px 2px 0;
|
|
3425
|
+
border: 1px solid #d6d6d6;
|
|
3426
|
+
border-radius: 2px;
|
|
3427
|
+
background: #f7f7f7;
|
|
3428
|
+
overflow: hidden;
|
|
3429
|
+
}
|
|
3430
|
+
|
|
3431
|
+
/* Half-height buttons, so the pair occupies the width of one: the panel's rows
|
|
3432
|
+
are tight and a size field shares its row with a label. */
|
|
3433
|
+
.size-field .size-field-btn {
|
|
3434
|
+
display: flex;
|
|
3435
|
+
align-items: center;
|
|
3436
|
+
justify-content: center;
|
|
3437
|
+
width: 13px;
|
|
3438
|
+
height: 8px;
|
|
3439
|
+
border: none;
|
|
3440
|
+
border-radius: 0;
|
|
3441
|
+
background: transparent;
|
|
3442
|
+
}
|
|
3443
|
+
|
|
3444
|
+
.size-field .size-field-arrow {
|
|
3445
|
+
display: block;
|
|
3446
|
+
width: 7px;
|
|
3447
|
+
height: 5px;
|
|
3448
|
+
fill: #444;
|
|
3449
|
+
stroke: none;
|
|
3450
|
+
}
|
|
3451
|
+
|
|
3452
|
+
.size-field .size-field-btn:hover:not(.disabled) {
|
|
3453
|
+
background: #e2e2e2;
|
|
2775
3454
|
}
|
|
2776
3455
|
|
|
2777
3456
|
.nav-menu-item,
|
|
@@ -2937,6 +3616,14 @@ body.dragging-color-picker * {
|
|
|
2937
3616
|
transform: translateY(0);
|
|
2938
3617
|
}
|
|
2939
3618
|
|
|
3619
|
+
/* The toolbar being hovered comes forward, so that a tooltip drawn above a
|
|
3620
|
+
button is not painted behind the toolbar stacked over it. The tooltip's own
|
|
3621
|
+
z-index cannot do this: each toolbar is transformed, which makes it a
|
|
3622
|
+
stacking context its descendants cannot escape. */
|
|
3623
|
+
.floating-toolbar:hover {
|
|
3624
|
+
z-index: 1;
|
|
3625
|
+
}
|
|
3626
|
+
|
|
2940
3627
|
.floating-toolbar-content {
|
|
2941
3628
|
display: flex;
|
|
2942
3629
|
align-items: center;
|
|
@@ -2984,6 +3671,15 @@ body.dragging-color-picker * {
|
|
|
2984
3671
|
background-color: #cdebf9;
|
|
2985
3672
|
}
|
|
2986
3673
|
|
|
3674
|
+
/* A toggle button that is currently armed */
|
|
3675
|
+
.floating-toolbar-btn.selected {
|
|
3676
|
+
background-color: #cdebf9;
|
|
3677
|
+
}
|
|
3678
|
+
|
|
3679
|
+
.floating-toolbar-btn.selected svg * {
|
|
3680
|
+
fill: #166689;
|
|
3681
|
+
}
|
|
3682
|
+
|
|
2987
3683
|
.floating-toolbar-btn.disabled {
|
|
2988
3684
|
cursor: default;
|
|
2989
3685
|
}
|