mapshaper 0.7.61 → 0.7.63
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 +3905 -832
- package/package.json +2 -1
- package/www/index.html +25 -7
- package/www/mapshaper-gui.js +14429 -7104
- package/www/mapshaper.js +3905 -832
- package/www/page.css +1364 -264
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; */
|
|
@@ -1265,6 +1284,26 @@ body.simplify .layer-control-btn {
|
|
|
1265
1284
|
cursor: pointer;
|
|
1266
1285
|
}
|
|
1267
1286
|
|
|
1287
|
+
.map-frame-section {
|
|
1288
|
+
border-top: 1px solid #ddd;
|
|
1289
|
+
margin-top: 8px;
|
|
1290
|
+
padding-top: 7px;
|
|
1291
|
+
}
|
|
1292
|
+
|
|
1293
|
+
.map-frame-heading h3 {
|
|
1294
|
+
margin: 0 0 1px 0;
|
|
1295
|
+
}
|
|
1296
|
+
|
|
1297
|
+
.map-frame-list .layer-item {
|
|
1298
|
+
cursor: pointer;
|
|
1299
|
+
}
|
|
1300
|
+
|
|
1301
|
+
.map-frame-empty {
|
|
1302
|
+
cursor: pointer;
|
|
1303
|
+
font-size: 12px;
|
|
1304
|
+
padding: 7px 4px 4px;
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1268
1307
|
.pin-all img,
|
|
1269
1308
|
.layer-item img
|
|
1270
1309
|
{
|
|
@@ -1972,6 +2011,7 @@ div.basemap-style-btn.active {
|
|
|
1972
2011
|
|
|
1973
2012
|
.map-layers.add-points,
|
|
1974
2013
|
.map-layers.draw-tool,
|
|
2014
|
+
.map-layers.label-tool,
|
|
1975
2015
|
.map-layers.snip-tool,
|
|
1976
2016
|
.map-layers.ruler-tool {
|
|
1977
2017
|
cursor: crosshair;
|
|
@@ -1981,6 +2021,12 @@ div.basemap-style-btn.active {
|
|
|
1981
2021
|
cursor: default;
|
|
1982
2022
|
}
|
|
1983
2023
|
|
|
2024
|
+
/* Over a label's knot or anchor handle, where a drag moves the handle rather
|
|
2025
|
+
than placing a label or panning the map. */
|
|
2026
|
+
.map-layers.label-handle {
|
|
2027
|
+
cursor: move;
|
|
2028
|
+
}
|
|
2029
|
+
|
|
1984
2030
|
.map-layers.ruler-dragging {
|
|
1985
2031
|
cursor: grabbing;
|
|
1986
2032
|
}
|
|
@@ -2020,6 +2066,41 @@ body.pan.panning .map-layers:not(.drawing) {
|
|
|
2020
2066
|
overflow: visible;
|
|
2021
2067
|
}
|
|
2022
2068
|
|
|
2069
|
+
.map-layers > svg.preview-overlay {
|
|
2070
|
+
top: 0;
|
|
2071
|
+
left: 0;
|
|
2072
|
+
z-index: 15;
|
|
2073
|
+
pointer-events: none;
|
|
2074
|
+
overflow: hidden;
|
|
2075
|
+
}
|
|
2076
|
+
|
|
2077
|
+
.map-layers > svg.preview-background-overlay {
|
|
2078
|
+
top: 0;
|
|
2079
|
+
left: 0;
|
|
2080
|
+
pointer-events: none;
|
|
2081
|
+
overflow: hidden;
|
|
2082
|
+
}
|
|
2083
|
+
|
|
2084
|
+
.preview-outside-mask {
|
|
2085
|
+
fill: rgba(24, 28, 32, 0.38);
|
|
2086
|
+
fill: #999;
|
|
2087
|
+
fill: #000;
|
|
2088
|
+
opacity: 0.85;
|
|
2089
|
+
opacity: 0.3;
|
|
2090
|
+
fill-rule: evenodd;
|
|
2091
|
+
}
|
|
2092
|
+
|
|
2093
|
+
.preview-page-border {
|
|
2094
|
+
fill: none;
|
|
2095
|
+
stroke: rgba(30, 30, 30, 0.9);
|
|
2096
|
+
stroke-width: 1.5px;
|
|
2097
|
+
vector-effect: non-scaling-stroke;
|
|
2098
|
+
}
|
|
2099
|
+
|
|
2100
|
+
.preview-page-neatline {
|
|
2101
|
+
pointer-events: none;
|
|
2102
|
+
}
|
|
2103
|
+
|
|
2023
2104
|
.ruler-line {
|
|
2024
2105
|
fill: none;
|
|
2025
2106
|
stroke: #cc35a5;
|
|
@@ -2060,23 +2141,181 @@ body.pan.panning .map-layers:not(.drawing) {
|
|
|
2060
2141
|
cursor: pointer;
|
|
2061
2142
|
}
|
|
2062
2143
|
|
|
2063
|
-
.map-layers > svg text.
|
|
2064
|
-
stroke: #
|
|
2144
|
+
.map-layers > svg text.label-style-selected {
|
|
2145
|
+
stroke: #fce300;
|
|
2146
|
+
stroke-opacity: 0.25;
|
|
2065
2147
|
paint-order: stroke fill;
|
|
2066
2148
|
stroke-width: 4px;
|
|
2067
2149
|
stroke-linecap: round;
|
|
2068
2150
|
stroke-linejoin: round;
|
|
2069
2151
|
}
|
|
2070
2152
|
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2153
|
+
/* A path label whose text is longer than its path. Export drops these; the
|
|
2154
|
+
editor keeps them visible and marked, because a hidden label can't be
|
|
2155
|
+
found and so can't be fixed. Same halo convention as the states above. */
|
|
2156
|
+
.map-layers > svg text.label-overflow {
|
|
2157
|
+
stroke: #ff7f2a;
|
|
2158
|
+
stroke-opacity: 0.45;
|
|
2074
2159
|
paint-order: stroke fill;
|
|
2075
2160
|
stroke-width: 4px;
|
|
2076
2161
|
stroke-linecap: round;
|
|
2077
2162
|
stroke-linejoin: round;
|
|
2078
2163
|
}
|
|
2079
2164
|
|
|
2165
|
+
/* --- IN-PLACE LABEL EDITING --- */
|
|
2166
|
+
|
|
2167
|
+
/* The textarea is the model of record for an editing session: it holds focus so
|
|
2168
|
+
that keyboard handling, selection, clipboard and IME all come from the
|
|
2169
|
+
browser. It is invisible but must stay focusable, so it cannot be hidden with
|
|
2170
|
+
display:none or visibility:hidden. */
|
|
2171
|
+
.label-edit-input {
|
|
2172
|
+
position: absolute;
|
|
2173
|
+
z-index: -1;
|
|
2174
|
+
opacity: 0;
|
|
2175
|
+
width: 1px;
|
|
2176
|
+
height: 1em;
|
|
2177
|
+
padding: 0;
|
|
2178
|
+
border: none;
|
|
2179
|
+
resize: none;
|
|
2180
|
+
overflow: hidden;
|
|
2181
|
+
white-space: pre;
|
|
2182
|
+
pointer-events: none;
|
|
2183
|
+
}
|
|
2184
|
+
|
|
2185
|
+
.label-edit-overlay {
|
|
2186
|
+
pointer-events: none;
|
|
2187
|
+
}
|
|
2188
|
+
|
|
2189
|
+
/* Label tool cues: an outline around the object rather than a halo over the
|
|
2190
|
+
glyphs, so that it reads as something you have hold of. A solid line, to
|
|
2191
|
+
distinguish it from the dashed box of a label being typed into -- the two
|
|
2192
|
+
states look different because they behave differently.
|
|
2193
|
+
|
|
2194
|
+
Hover and selection draw the same shapes, because they mean the same thing
|
|
2195
|
+
about the same object; hover is simply lighter. The alternative, highlighting
|
|
2196
|
+
the anchor point on hover and the label on selection, made the two look like
|
|
2197
|
+
different objects. */
|
|
2198
|
+
.label-cue {
|
|
2199
|
+
pointer-events: none;
|
|
2200
|
+
}
|
|
2201
|
+
|
|
2202
|
+
.label-cue-hovered {
|
|
2203
|
+
opacity: 0.4;
|
|
2204
|
+
}
|
|
2205
|
+
|
|
2206
|
+
/* Hairline, like every other reference shape the tool draws: the box says where
|
|
2207
|
+
the label is, and a heavier outline reads as an object in its own right
|
|
2208
|
+
rather than as a mark on one. */
|
|
2209
|
+
.label-cue-box {
|
|
2210
|
+
fill: none;
|
|
2211
|
+
stroke: #3a7ddc;
|
|
2212
|
+
stroke-width: 1px;
|
|
2213
|
+
vector-effect: non-scaling-stroke;
|
|
2214
|
+
}
|
|
2215
|
+
|
|
2216
|
+
/* The anchor is what the text is positioned against, and label-pos can put it
|
|
2217
|
+
well outside the box, so it is worth marking on its own.
|
|
2218
|
+
Drawn as a ring rather than a dot, and beneath the glyphs: a centered label
|
|
2219
|
+
sits right on top of its anchor, and a filled marker would blot out a letter.
|
|
2220
|
+
Same treatment as the path guide's knots, since both are handles. */
|
|
2221
|
+
.label-cue-anchor {
|
|
2222
|
+
fill: #fff;
|
|
2223
|
+
stroke: #3a7ddc;
|
|
2224
|
+
stroke-width: 1.5px;
|
|
2225
|
+
vector-effect: non-scaling-stroke;
|
|
2226
|
+
}
|
|
2227
|
+
|
|
2228
|
+
/* The line between an anchor and the text being dragged away from it, drawn
|
|
2229
|
+
only while that drag is on. Dashed, and a shade lighter than the box: it is
|
|
2230
|
+
the relationship being edited rather than a part of either end. */
|
|
2231
|
+
.label-cue-tether {
|
|
2232
|
+
fill: none;
|
|
2233
|
+
stroke: #3a7ddc;
|
|
2234
|
+
stroke-width: 1px;
|
|
2235
|
+
stroke-dasharray: 2 2;
|
|
2236
|
+
opacity: 0.7;
|
|
2237
|
+
vector-effect: non-scaling-stroke;
|
|
2238
|
+
}
|
|
2239
|
+
|
|
2240
|
+
/* A copy of the baseline the label's text runs along. Unfilled: stroking an
|
|
2241
|
+
open curve must not paint the area it encloses. */
|
|
2242
|
+
.label-cue-curve {
|
|
2243
|
+
fill: none;
|
|
2244
|
+
stroke: #3a7ddc;
|
|
2245
|
+
stroke-width: 1px;
|
|
2246
|
+
stroke-opacity: 0.8;
|
|
2247
|
+
vector-effect: non-scaling-stroke;
|
|
2248
|
+
}
|
|
2249
|
+
|
|
2250
|
+
/* The grab handles on a selected curve, one per knot. Same ring treatment as
|
|
2251
|
+
the anchor marker and the path guide's knots, because all three are handles
|
|
2252
|
+
and a knot is an anchor on a curve.
|
|
2253
|
+
A corner knot is drawn as a square by the renderer; both shapes share this
|
|
2254
|
+
rule, so a corner differs in outline and not in colour. */
|
|
2255
|
+
.label-cue-knot {
|
|
2256
|
+
fill: #fff;
|
|
2257
|
+
stroke: #3a7ddc;
|
|
2258
|
+
stroke-width: 1.5px;
|
|
2259
|
+
vector-effect: non-scaling-stroke;
|
|
2260
|
+
}
|
|
2261
|
+
|
|
2262
|
+
/* Transparent rather than fill:none / stroke:none, because an unpainted shape
|
|
2263
|
+
is not hit-testable. */
|
|
2264
|
+
.label-edit-hit-area {
|
|
2265
|
+
fill: transparent;
|
|
2266
|
+
stroke: none;
|
|
2267
|
+
pointer-events: all;
|
|
2268
|
+
}
|
|
2269
|
+
|
|
2270
|
+
/* The thickened baseline follows the curve, so only its stroke should catch
|
|
2271
|
+
clicks -- filling an open curve would claim the whole area it encloses. */
|
|
2272
|
+
.label-edit-hit-baseline {
|
|
2273
|
+
fill: none;
|
|
2274
|
+
stroke: transparent;
|
|
2275
|
+
pointer-events: stroke;
|
|
2276
|
+
}
|
|
2277
|
+
|
|
2278
|
+
/* The curve a label's text is set along, ghosted while the label is open for
|
|
2279
|
+
editing. Fainter than the guide drawn while the path is being placed, and in
|
|
2280
|
+
the same violet, because it is the same curve at a later stage. */
|
|
2281
|
+
.label-edit-path {
|
|
2282
|
+
fill: none;
|
|
2283
|
+
stroke: #cc6acc;
|
|
2284
|
+
stroke-width: 1.2px;
|
|
2285
|
+
stroke-opacity: 0.4;
|
|
2286
|
+
vector-effect: non-scaling-stroke;
|
|
2287
|
+
}
|
|
2288
|
+
|
|
2289
|
+
/* Shows where an anchored label is even when it has no text -- the state a
|
|
2290
|
+
label is in between being created and being typed into. A path label shows
|
|
2291
|
+
its ghosted curve instead.
|
|
2292
|
+
Solid, not dashed: at the size of an empty label the dashes were most of the
|
|
2293
|
+
outline, which made the box look tentative rather than like a place to type. */
|
|
2294
|
+
.label-edit-box {
|
|
2295
|
+
fill: none;
|
|
2296
|
+
stroke: #cc6acc;
|
|
2297
|
+
stroke-width: 1px;
|
|
2298
|
+
vector-effect: non-scaling-stroke;
|
|
2299
|
+
}
|
|
2300
|
+
|
|
2301
|
+
.label-edit-selection {
|
|
2302
|
+
fill: #cc6acc;
|
|
2303
|
+
fill-opacity: 0.3;
|
|
2304
|
+
stroke: none;
|
|
2305
|
+
}
|
|
2306
|
+
|
|
2307
|
+
.label-edit-caret {
|
|
2308
|
+
stroke: #000;
|
|
2309
|
+
stroke-width: 1.5px;
|
|
2310
|
+
vector-effect: non-scaling-stroke;
|
|
2311
|
+
animation: label-caret-blink 1.1s steps(1) infinite;
|
|
2312
|
+
}
|
|
2313
|
+
|
|
2314
|
+
@keyframes label-caret-blink {
|
|
2315
|
+
0%, 50% { stroke-opacity: 1; }
|
|
2316
|
+
50.01%, 100% { stroke-opacity: 0; }
|
|
2317
|
+
}
|
|
2318
|
+
|
|
2080
2319
|
/* --- MAP BUTTONS --- */
|
|
2081
2320
|
|
|
2082
2321
|
/*.pointer-btn {
|
|
@@ -2151,12 +2390,12 @@ body.pan.panning .map-layers:not(.drawing) {
|
|
|
2151
2390
|
position: relative;
|
|
2152
2391
|
cursor:pointer;
|
|
2153
2392
|
/* padding: 3px 3px 5px 3px; */
|
|
2154
|
-
padding: 4px
|
|
2393
|
+
padding: 3px 4px;
|
|
2155
2394
|
line-height: 1;
|
|
2156
2395
|
}
|
|
2157
2396
|
|
|
2158
2397
|
.nav-btn.menu-btn {
|
|
2159
|
-
padding-top:
|
|
2398
|
+
padding-top: 2px;
|
|
2160
2399
|
}
|
|
2161
2400
|
|
|
2162
2401
|
.nav-btn.selected {
|
|
@@ -2173,12 +2412,111 @@ body.pan.panning .map-layers:not(.drawing) {
|
|
|
2173
2412
|
fill: white;
|
|
2174
2413
|
}
|
|
2175
2414
|
|
|
2415
|
+
.nav-btn.preview-toggle {
|
|
2416
|
+
align-items: center;
|
|
2417
|
+
box-sizing: border-box;
|
|
2418
|
+
display: flex;
|
|
2419
|
+
height: 28px;
|
|
2420
|
+
justify-content: center;
|
|
2421
|
+
margin-top: 2px;
|
|
2422
|
+
padding-bottom: 0;
|
|
2423
|
+
padding-top: 1px;
|
|
2424
|
+
}
|
|
2425
|
+
|
|
2426
|
+
.preview-toggle svg {
|
|
2427
|
+
display: block;
|
|
2428
|
+
height: 16px;
|
|
2429
|
+
transform: translateY(-1px);
|
|
2430
|
+
width: 16px;
|
|
2431
|
+
}
|
|
2432
|
+
|
|
2433
|
+
.preview-readout {
|
|
2434
|
+
position: absolute;
|
|
2435
|
+
z-index: 20;
|
|
2436
|
+
top: 6px;
|
|
2437
|
+
left: 50%;
|
|
2438
|
+
transform: translateX(-50%);
|
|
2439
|
+
background: rgba(255, 255, 255, 0.96);
|
|
2440
|
+
border: 1px solid #ddd;
|
|
2441
|
+
border-radius: 5px;
|
|
2442
|
+
box-shadow: 0 1px 5px rgba(0,0,0,0.12);
|
|
2443
|
+
color: #333;
|
|
2444
|
+
cursor: pointer;
|
|
2445
|
+
font-size: 12px;
|
|
2446
|
+
line-height: 15px;
|
|
2447
|
+
padding: 3px 7px;
|
|
2448
|
+
white-space: nowrap;
|
|
2449
|
+
}
|
|
2450
|
+
|
|
2451
|
+
.preview-readout-arrow {
|
|
2452
|
+
color: #777;
|
|
2453
|
+
font-size: 16px;
|
|
2454
|
+
font-weight: bold;
|
|
2455
|
+
line-height: 9px;
|
|
2456
|
+
margin-left: 6px;
|
|
2457
|
+
position: relative;
|
|
2458
|
+
top: -1px;
|
|
2459
|
+
}
|
|
2460
|
+
|
|
2461
|
+
.preview-scale-menu {
|
|
2462
|
+
position: absolute;
|
|
2463
|
+
z-index: 1;
|
|
2464
|
+
display: none;
|
|
2465
|
+
pointer-events: none;
|
|
2466
|
+
padding: 5px 0;
|
|
2467
|
+
background-color: white;
|
|
2468
|
+
top: calc(100% + 4px);
|
|
2469
|
+
right: 0;
|
|
2470
|
+
text-align: right;
|
|
2471
|
+
white-space: nowrap;
|
|
2472
|
+
border-radius: 6px;
|
|
2473
|
+
border: 1px solid #ddd;
|
|
2474
|
+
box-shadow: 0 1px 7px rgba(0,0,0,0.12);
|
|
2475
|
+
}
|
|
2476
|
+
|
|
2477
|
+
.preview-readout.open .preview-scale-menu {
|
|
2478
|
+
display: block;
|
|
2479
|
+
pointer-events: inherit;
|
|
2480
|
+
}
|
|
2481
|
+
|
|
2482
|
+
.preview-scale-menu-item {
|
|
2483
|
+
color: #555;
|
|
2484
|
+
padding: 3px 9px;
|
|
2485
|
+
white-space: nowrap;
|
|
2486
|
+
cursor: pointer;
|
|
2487
|
+
}
|
|
2488
|
+
|
|
2489
|
+
.preview-scale-menu-item:hover {
|
|
2490
|
+
color: black;
|
|
2491
|
+
background: var(--lt-theme-col);
|
|
2492
|
+
}
|
|
2493
|
+
|
|
2176
2494
|
.label-style-panel {
|
|
2495
|
+
/* The shape of a field in every style panel: the label panel set them,
|
|
2496
|
+
and the line, polygon and circle panels are drawn from the same parts.
|
|
2497
|
+
A row is only legible when the select, the colour field, the size field
|
|
2498
|
+
and the button beside them are all the same height. */
|
|
2499
|
+
--label-field-height: 22px;
|
|
2500
|
+
--label-field-radius: 4px;
|
|
2501
|
+
--label-field-border: #bbb;
|
|
2502
|
+
/* The narrow column of a split row, wide enough for the longest caption
|
|
2503
|
+
over it -- "Letter spacing", which measures 71px -- and the same in
|
|
2504
|
+
every row of every panel, so that the field edges line up down the
|
|
2505
|
+
whole stack. */
|
|
2506
|
+
--label-split-b-width: 74px;
|
|
2507
|
+
/* Same glyph on native <select>s and the saved-style menu. The custom menu
|
|
2508
|
+
used a CSS triangle; the font menus used the OS arrow. A drawn stroke
|
|
2509
|
+
rather than a filled triangle: it is lighter than the text beside it,
|
|
2510
|
+
which is what a menu's arrow should be. */
|
|
2511
|
+
--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
2512
|
position: absolute;
|
|
2178
2513
|
z-index: 21;
|
|
2179
2514
|
top: 6px;
|
|
2180
2515
|
right: 36px;
|
|
2181
|
-
|
|
2516
|
+
/* Wide enough for a pair of controls side by side, which is what these
|
|
2517
|
+
panels are mostly made of: at 185px the narrow column of a pair was too
|
|
2518
|
+
narrow for its own caption, and "Letter spacing" was clipped. */
|
|
2519
|
+
width: 216px;
|
|
2182
2520
|
padding: 8px 12px 12px;
|
|
2183
2521
|
text-align: left;
|
|
2184
2522
|
background-color: white;
|
|
@@ -2190,375 +2528,896 @@ body.pan.panning .map-layers:not(.drawing) {
|
|
|
2190
2528
|
.label-style-panel button,
|
|
2191
2529
|
.label-style-panel select,
|
|
2192
2530
|
.label-style-panel input {
|
|
2193
|
-
font-size:
|
|
2531
|
+
font-size: 12px;
|
|
2194
2532
|
}
|
|
2195
2533
|
|
|
2196
2534
|
.label-style-panel button.label-style-close {
|
|
2197
2535
|
font-size: 16px; /* close button icon */
|
|
2198
2536
|
}
|
|
2199
2537
|
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
padding: 1px 0;
|
|
2538
|
+
.frame-properties-popup {
|
|
2539
|
+
width: 264px;
|
|
2203
2540
|
}
|
|
2204
2541
|
|
|
2205
|
-
.label-style-panel
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2542
|
+
.frame-properties-form.label-style-panel,
|
|
2543
|
+
.frame-create-form.label-style-panel {
|
|
2544
|
+
background: transparent;
|
|
2545
|
+
border: 0;
|
|
2546
|
+
border-radius: 0;
|
|
2547
|
+
box-shadow: none;
|
|
2548
|
+
box-sizing: border-box;
|
|
2549
|
+
max-height: none;
|
|
2550
|
+
overflow: visible;
|
|
2551
|
+
padding: 0;
|
|
2552
|
+
position: static;
|
|
2553
|
+
width: 100%;
|
|
2209
2554
|
}
|
|
2210
2555
|
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
font-size: 16px;
|
|
2218
|
-
line-height: 1;
|
|
2556
|
+
/* Three columns on the appearance rows: the neatline's width sits with the
|
|
2557
|
+
colour and opacity it applies to, and the background row leaves the last
|
|
2558
|
+
column empty rather than pushing a lone field onto a line of its own. */
|
|
2559
|
+
.frame-properties-form .label-split-row {
|
|
2560
|
+
column-gap: 8px;
|
|
2561
|
+
grid-template-columns: 1fr 54px 54px;
|
|
2219
2562
|
}
|
|
2220
2563
|
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2564
|
+
/* Wide enough for "Aspect ratio", and fixed rather than auto so that the ratio
|
|
2565
|
+
at the top of the panel lines up with the details at the bottom, which are a
|
|
2566
|
+
separate grid. */
|
|
2567
|
+
.frame-property-detail-row {
|
|
2568
|
+
display: grid;
|
|
2569
|
+
font-size: 12px;
|
|
2570
|
+
gap: 6px;
|
|
2571
|
+
grid-template-columns: 66px 1fr;
|
|
2572
|
+
margin-top: 6px;
|
|
2224
2573
|
}
|
|
2225
2574
|
|
|
2226
|
-
.
|
|
2227
|
-
.label-style-row-label {
|
|
2228
|
-
display: block;
|
|
2229
|
-
/* margin-bottom: 3px; */
|
|
2575
|
+
.frame-property-detail-row > span:first-child {
|
|
2230
2576
|
color: #555;
|
|
2231
2577
|
}
|
|
2232
2578
|
|
|
2233
|
-
.
|
|
2234
|
-
|
|
2235
|
-
box-sizing: border-box;
|
|
2579
|
+
.frame-property-detail-value {
|
|
2580
|
+
overflow-wrap: anywhere;
|
|
2236
2581
|
}
|
|
2237
2582
|
|
|
2238
|
-
.
|
|
2239
|
-
|
|
2240
|
-
border: 1px solid #999;
|
|
2241
|
-
box-shadow: none;
|
|
2583
|
+
.frame-create-popup {
|
|
2584
|
+
width: 264px;
|
|
2242
2585
|
}
|
|
2243
2586
|
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2587
|
+
/* The field tips are drawn above the "?" that opens them, which the box's own
|
|
2588
|
+
overflow would clip. The dialog is three rows and two buttons and never has
|
|
2589
|
+
anything to scroll. */
|
|
2590
|
+
.alert-box.frame-create-box {
|
|
2591
|
+
overflow: visible;
|
|
2248
2592
|
}
|
|
2249
2593
|
|
|
2250
|
-
.
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2594
|
+
/* A field and the "?" beside it. The field itself is a .frame-field-row, shared
|
|
2595
|
+
with Frame properties, so that the dialog that creates a frame and the panel
|
|
2596
|
+
that edits it look like one program. The gap matches the option rows below,
|
|
2597
|
+
so that every field ends on the same vertical and the tips line up. */
|
|
2598
|
+
.frame-create-row {
|
|
2599
|
+
align-items: center;
|
|
2600
|
+
display: flex;
|
|
2601
|
+
gap: 8px;
|
|
2602
|
+
margin-top: 6px;
|
|
2257
2603
|
}
|
|
2258
2604
|
|
|
2259
|
-
.
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
outline: none;
|
|
2605
|
+
.frame-create-row > .frame-field-row {
|
|
2606
|
+
flex: 1;
|
|
2607
|
+
min-width: 0;
|
|
2263
2608
|
}
|
|
2264
2609
|
|
|
2265
|
-
.
|
|
2266
|
-
|
|
2267
|
-
|
|
2610
|
+
/* float is what the static tips in index.html are placed with; here the row is
|
|
2611
|
+
a flex container, which ignores it. */
|
|
2612
|
+
.frame-create-popup .tip-button {
|
|
2613
|
+
flex: none;
|
|
2614
|
+
float: none;
|
|
2615
|
+
margin-top: 0;
|
|
2616
|
+
margin-left: 0;
|
|
2617
|
+
width: 12px;
|
|
2268
2618
|
}
|
|
2269
2619
|
|
|
2270
|
-
|
|
2620
|
+
/* The button names what it does and is as wide as its name, so the two options
|
|
2621
|
+
are left-aligned at a common width rather than sized by their labels. */
|
|
2622
|
+
.frame-create-option-row {
|
|
2623
|
+
align-items: center;
|
|
2271
2624
|
display: flex;
|
|
2272
|
-
|
|
2273
|
-
|
|
2625
|
+
gap: 8px;
|
|
2626
|
+
margin-top: 6px;
|
|
2274
2627
|
}
|
|
2275
2628
|
|
|
2276
|
-
|
|
2277
|
-
|
|
2629
|
+
/* flex: none, or the margin field beside the first button shrinks it and the
|
|
2630
|
+
two options stop looking like peers. */
|
|
2631
|
+
.frame-create-option-row > .dialog-btn {
|
|
2632
|
+
box-sizing: border-box;
|
|
2633
|
+
flex: none;
|
|
2634
|
+
margin: 0;
|
|
2635
|
+
text-align: center;
|
|
2636
|
+
width: 130px;
|
|
2278
2637
|
}
|
|
2279
2638
|
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2639
|
+
/* Stretches so that the margin field ends where the fields above it do: the
|
|
2640
|
+
row is shorter than they are, and a ragged right edge reads as unfinished
|
|
2641
|
+
rather than as deliberate grouping. */
|
|
2642
|
+
.frame-create-margin {
|
|
2643
|
+
align-items: center;
|
|
2644
|
+
display: flex;
|
|
2645
|
+
flex: 1;
|
|
2646
|
+
gap: 6px;
|
|
2647
|
+
min-width: 0; /* a flex item defaults to min-width:auto and will not shrink below its field */
|
|
2648
|
+
}
|
|
2649
|
+
|
|
2650
|
+
.frame-create-margin > span {
|
|
2283
2651
|
color: #555;
|
|
2652
|
+
font-size: 12px;
|
|
2284
2653
|
}
|
|
2285
2654
|
|
|
2286
|
-
.
|
|
2287
|
-
|
|
2288
|
-
|
|
2655
|
+
.frame-create-margin > input {
|
|
2656
|
+
box-sizing: border-box;
|
|
2657
|
+
flex: 1;
|
|
2658
|
+
min-width: 0;
|
|
2289
2659
|
}
|
|
2290
2660
|
|
|
2291
|
-
.
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2661
|
+
.frame-field-row {
|
|
2662
|
+
align-items: center;
|
|
2663
|
+
display: flex;
|
|
2664
|
+
gap: 8px;
|
|
2295
2665
|
}
|
|
2296
2666
|
|
|
2297
|
-
.
|
|
2298
|
-
|
|
2299
|
-
margin-right: 5px;
|
|
2667
|
+
.frame-field-row > span {
|
|
2668
|
+
flex: 0 0 82px;
|
|
2300
2669
|
}
|
|
2301
2670
|
|
|
2302
|
-
.
|
|
2671
|
+
.frame-field-row > input,
|
|
2672
|
+
.frame-field-row > select {
|
|
2673
|
+
flex: 1;
|
|
2674
|
+
min-width: 0;
|
|
2675
|
+
}
|
|
2676
|
+
|
|
2677
|
+
.frame-field-row > .label-panel-action-btn {
|
|
2678
|
+
flex: none;
|
|
2679
|
+
}
|
|
2680
|
+
|
|
2681
|
+
/* Two class names, because .label-style-row's display:block is declared later
|
|
2682
|
+
in this file and a single class would lose to it -- which is what stacked
|
|
2683
|
+
width and height down the panel at full width instead of pairing them. */
|
|
2684
|
+
.label-style-row.frame-size-row {
|
|
2685
|
+
align-items: end;
|
|
2303
2686
|
display: grid;
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
align-items: start;
|
|
2687
|
+
gap: 6px;
|
|
2688
|
+
grid-template-columns: 1fr 1fr 54px;
|
|
2307
2689
|
}
|
|
2308
2690
|
|
|
2309
|
-
.
|
|
2310
|
-
|
|
2691
|
+
.frame-input-cell > span {
|
|
2692
|
+
color: #555;
|
|
2693
|
+
font-size: 12px;
|
|
2694
|
+
}
|
|
2695
|
+
|
|
2696
|
+
.frame-input-cell > input {
|
|
2697
|
+
box-sizing: border-box;
|
|
2698
|
+
width: 100%;
|
|
2699
|
+
}
|
|
2700
|
+
|
|
2701
|
+
.frame-units-select {
|
|
2702
|
+
width: 54px;
|
|
2703
|
+
}
|
|
2704
|
+
|
|
2705
|
+
.export-frame-info {
|
|
2706
|
+
color: #555;
|
|
2707
|
+
font-size: 12px;
|
|
2708
|
+
margin: 8px 0 12px;
|
|
2709
|
+
}
|
|
2710
|
+
|
|
2711
|
+
.label-style-panel select,
|
|
2712
|
+
.label-saved-style-btn {
|
|
2713
|
+
background-image: var(--label-menu-chevron);
|
|
2714
|
+
background-repeat: no-repeat;
|
|
2715
|
+
background-position: right 6px center;
|
|
2716
|
+
background-size: 10px 7px;
|
|
2717
|
+
}
|
|
2718
|
+
|
|
2719
|
+
.label-style-panel select {
|
|
2720
|
+
-webkit-appearance: none;
|
|
2721
|
+
appearance: none;
|
|
2722
|
+
padding: 0 20px 0 6px;
|
|
2723
|
+
}
|
|
2724
|
+
|
|
2725
|
+
/* The size the app's dialogs title themselves at (.info-box h3), so that a
|
|
2726
|
+
panel pinned over the map is headed like the menus beside it. */
|
|
2727
|
+
.label-style-panel-title {
|
|
2728
|
+
position: relative;
|
|
2729
|
+
font-weight: 600;
|
|
2730
|
+
font-size: 17px;
|
|
2731
|
+
}
|
|
2732
|
+
|
|
2733
|
+
.label-style-close {
|
|
2734
|
+
position: absolute;
|
|
2735
|
+
right: -5px;
|
|
2736
|
+
border: 0;
|
|
2737
|
+
background: transparent;
|
|
2738
|
+
cursor: pointer;
|
|
2739
|
+
font-size: 16px;
|
|
2740
|
+
line-height: 1;
|
|
2741
|
+
}
|
|
2742
|
+
|
|
2743
|
+
.label-style-row {
|
|
2311
2744
|
display: block;
|
|
2312
|
-
margin-
|
|
2745
|
+
margin-top: 7px;
|
|
2746
|
+
}
|
|
2747
|
+
|
|
2748
|
+
.label-style-row span,
|
|
2749
|
+
.label-style-row-label {
|
|
2750
|
+
display: block;
|
|
2751
|
+
/* margin-bottom: 3px; */
|
|
2313
2752
|
color: #555;
|
|
2314
2753
|
}
|
|
2315
2754
|
|
|
2316
|
-
.label-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
white-space: nowrap;
|
|
2755
|
+
.label-style-row select {
|
|
2756
|
+
width: 100%;
|
|
2757
|
+
box-sizing: border-box;
|
|
2320
2758
|
}
|
|
2321
2759
|
|
|
2322
|
-
.label-
|
|
2760
|
+
.label-style-panel select,
|
|
2761
|
+
.label-style-panel input[type="text"] {
|
|
2762
|
+
box-sizing: border-box;
|
|
2763
|
+
height: var(--label-field-height);
|
|
2764
|
+
background-color: white;
|
|
2765
|
+
border: 1px solid var(--label-field-border);
|
|
2766
|
+
border-radius: var(--label-field-radius);
|
|
2767
|
+
box-shadow: none;
|
|
2768
|
+
}
|
|
2769
|
+
|
|
2770
|
+
.label-style-panel select:focus {
|
|
2771
|
+
border-color: #d3aa00;
|
|
2772
|
+
box-shadow: none;
|
|
2773
|
+
outline: none;
|
|
2774
|
+
}
|
|
2775
|
+
|
|
2776
|
+
.label-style-panel input[type="text"] {
|
|
2777
|
+
-webkit-appearance: none;
|
|
2778
|
+
appearance: none;
|
|
2779
|
+
}
|
|
2780
|
+
|
|
2781
|
+
.label-style-panel input[type="text"]:focus {
|
|
2782
|
+
border-color: #d3aa00;
|
|
2783
|
+
box-shadow: none;
|
|
2784
|
+
outline: none;
|
|
2785
|
+
}
|
|
2786
|
+
|
|
2787
|
+
.label-create-expression-row input {
|
|
2788
|
+
width: 100%;
|
|
2789
|
+
box-sizing: border-box;
|
|
2790
|
+
}
|
|
2791
|
+
|
|
2792
|
+
.label-create-copy-row {
|
|
2793
|
+
display: flex;
|
|
2794
|
+
align-items: flex-start;
|
|
2795
|
+
gap: 5px;
|
|
2796
|
+
}
|
|
2797
|
+
|
|
2798
|
+
.label-create-copy-row input {
|
|
2799
|
+
margin-top: 1px;
|
|
2800
|
+
}
|
|
2801
|
+
|
|
2802
|
+
.label-create-copy-row span {
|
|
2803
|
+
display: inline;
|
|
2804
|
+
margin: 0;
|
|
2805
|
+
color: #555;
|
|
2806
|
+
}
|
|
2807
|
+
|
|
2808
|
+
.label-style-row button {
|
|
2809
|
+
margin-right: 5px;
|
|
2810
|
+
}
|
|
2811
|
+
|
|
2812
|
+
/* Saved styles: a menu that applies one and a button that saves the current
|
|
2813
|
+
one, under a heading. The menu is built from divs rather than being a
|
|
2814
|
+
<select>, because each row carries its own delete button -- see
|
|
2815
|
+
gui-style-preset-control.mjs.
|
|
2816
|
+
|
|
2817
|
+
A section of the panel like Text and Icon, so the spacing above it is the
|
|
2818
|
+
whitespace those sections are separated by, in the panel that has them, and
|
|
2819
|
+
this margin in the layer panel, which does not. */
|
|
2820
|
+
.label-saved-style-row {
|
|
2821
|
+
margin-top: 11px;
|
|
2822
|
+
}
|
|
2823
|
+
|
|
2824
|
+
/* The two controls sit in the panel's A and B columns, on the same grid as a
|
|
2825
|
+
split row: Apply style lines up with the fields and menus above it, and
|
|
2826
|
+
Save current with the narrow column beside them. Every style panel is the
|
|
2827
|
+
same width, so one grid does for all three. */
|
|
2828
|
+
.label-saved-style-controls {
|
|
2829
|
+
display: grid;
|
|
2830
|
+
grid-template-columns: 1fr var(--label-split-b-width);
|
|
2831
|
+
column-gap: 10px;
|
|
2832
|
+
margin-top: 4px;
|
|
2833
|
+
}
|
|
2834
|
+
|
|
2835
|
+
/* min-width:0 lets the menu shrink to its column: a grid track is otherwise
|
|
2836
|
+
at least as wide as its contents, and the names in the list can be long. */
|
|
2837
|
+
.label-saved-style-menu {
|
|
2323
2838
|
position: relative;
|
|
2839
|
+
min-width: 0;
|
|
2324
2840
|
}
|
|
2325
2841
|
|
|
2326
|
-
|
|
2842
|
+
/* Sized, bordered and lettered like the panel's fields rather than like its
|
|
2843
|
+
19px icon buttons, because that is what these two are: a menu the width of
|
|
2844
|
+
a field, and a button beside it. The type is the fields' own -- these are
|
|
2845
|
+
divs, so the panel's rule for button, select and input does not reach them
|
|
2846
|
+
and they were left at the app's 14px. */
|
|
2847
|
+
.label-saved-style-button {
|
|
2327
2848
|
box-sizing: border-box;
|
|
2328
|
-
|
|
2849
|
+
display: flex;
|
|
2850
|
+
align-items: center;
|
|
2851
|
+
height: var(--label-field-height);
|
|
2852
|
+
padding: 0 6px;
|
|
2853
|
+
border: 1px solid var(--label-field-border);
|
|
2854
|
+
border-radius: var(--label-field-radius);
|
|
2855
|
+
background-color: white;
|
|
2856
|
+
font-size: 12px;
|
|
2857
|
+
color: #000;
|
|
2329
2858
|
cursor: pointer;
|
|
2330
|
-
|
|
2859
|
+
user-select: none;
|
|
2860
|
+
}
|
|
2861
|
+
|
|
2862
|
+
/* "Save current" is 63px of SourceSans3 and 68px of the Arial it falls back
|
|
2863
|
+
to, in a column of 74: too near its edges to read as inset from them, so
|
|
2864
|
+
the label is centred and the padding is only what keeps the widest of the
|
|
2865
|
+
two fonts off the border. */
|
|
2866
|
+
.label-saved-style-save {
|
|
2867
|
+
justify-content: center;
|
|
2868
|
+
padding: 0 2px;
|
|
2869
|
+
}
|
|
2870
|
+
|
|
2871
|
+
/* The panel's own disabled look: live colours, faded as a whole. */
|
|
2872
|
+
.label-saved-style-button.disabled {
|
|
2873
|
+
opacity: 0.45;
|
|
2874
|
+
cursor: default;
|
|
2875
|
+
}
|
|
2876
|
+
|
|
2877
|
+
.label-saved-style-button:hover:not(.disabled),
|
|
2878
|
+
.label-saved-style-button.open {
|
|
2879
|
+
background-color: #f0f0f0;
|
|
2880
|
+
}
|
|
2881
|
+
|
|
2882
|
+
.label-saved-style-btn {
|
|
2883
|
+
padding-right: 20px;
|
|
2884
|
+
}
|
|
2885
|
+
|
|
2886
|
+
/* The label gives way to the chevron rather than running under it. */
|
|
2887
|
+
.label-saved-style-btn span {
|
|
2888
|
+
flex: 1;
|
|
2889
|
+
min-width: 0;
|
|
2890
|
+
overflow: hidden;
|
|
2891
|
+
white-space: nowrap;
|
|
2892
|
+
text-overflow: ellipsis;
|
|
2893
|
+
}
|
|
2894
|
+
|
|
2895
|
+
/* Above the panel's own rows, and free to hang past its bottom edge -- the
|
|
2896
|
+
panel does not clip, and this row is the last thing in it. */
|
|
2897
|
+
.label-saved-style-list {
|
|
2898
|
+
position: absolute;
|
|
2899
|
+
top: 100%;
|
|
2900
|
+
left: 0;
|
|
2901
|
+
/* At least as wide as the menu, and wider if the names need it: the button
|
|
2902
|
+
is only as wide as the space left over beside Save current, and a style
|
|
2903
|
+
name is what the user is trying to read. It can hang over the map --
|
|
2904
|
+
nothing clips it -- but not indefinitely; past that, names ellipsize. */
|
|
2905
|
+
min-width: 100%;
|
|
2906
|
+
width: max-content;
|
|
2907
|
+
max-width: 240px;
|
|
2908
|
+
z-index: 30;
|
|
2909
|
+
margin-top: 2px;
|
|
2910
|
+
padding: 3px 2px;
|
|
2911
|
+
max-height: 40vh;
|
|
2912
|
+
overflow-y: auto;
|
|
2913
|
+
background: white;
|
|
2914
|
+
/* The size of the button it drops from, which is the size of a field. */
|
|
2915
|
+
font-size: 12px;
|
|
2916
|
+
border: 1px solid #bbb;
|
|
2917
|
+
border-radius: var(--label-field-radius);
|
|
2918
|
+
box-shadow: 0 2px 8px rgba(0,0,0,0.18);
|
|
2919
|
+
}
|
|
2920
|
+
|
|
2921
|
+
.label-saved-style-list.drop-up {
|
|
2922
|
+
top: auto;
|
|
2923
|
+
bottom: 100%;
|
|
2924
|
+
margin: 0 0 2px 0;
|
|
2925
|
+
}
|
|
2926
|
+
|
|
2927
|
+
.label-saved-style-item {
|
|
2928
|
+
display: flex;
|
|
2929
|
+
align-items: center;
|
|
2930
|
+
}
|
|
2931
|
+
|
|
2932
|
+
/* The name is the target for applying, and the highlight stops where it does,
|
|
2933
|
+
so that the row reads as two things to click rather than one with a hazard
|
|
2934
|
+
at the end of it. */
|
|
2935
|
+
.label-saved-style-name {
|
|
2936
|
+
flex: 1;
|
|
2937
|
+
min-width: 0;
|
|
2938
|
+
padding: 3px 4px 3px 8px;
|
|
2331
2939
|
border-radius: 3px;
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2940
|
+
color: var(--normal-text);
|
|
2941
|
+
cursor: pointer;
|
|
2942
|
+
overflow: hidden;
|
|
2943
|
+
white-space: nowrap;
|
|
2944
|
+
text-overflow: ellipsis;
|
|
2336
2945
|
}
|
|
2337
2946
|
|
|
2338
|
-
.label-
|
|
2947
|
+
.label-saved-style-name:hover {
|
|
2948
|
+
background: var(--lt-theme-col);
|
|
2949
|
+
}
|
|
2950
|
+
|
|
2951
|
+
/* Hidden by visibility rather than left out, so that a name is the same width
|
|
2952
|
+
whether or not the pointer is on it. */
|
|
2953
|
+
.label-saved-style-delete {
|
|
2954
|
+
flex: none;
|
|
2955
|
+
width: 16px;
|
|
2956
|
+
padding: 2px 4px 2px 0;
|
|
2957
|
+
text-align: center;
|
|
2958
|
+
line-height: 1;
|
|
2959
|
+
color: #999;
|
|
2960
|
+
cursor: pointer;
|
|
2961
|
+
visibility: hidden;
|
|
2962
|
+
}
|
|
2963
|
+
|
|
2964
|
+
.label-saved-style-item:hover .label-saved-style-delete {
|
|
2965
|
+
visibility: visible;
|
|
2966
|
+
}
|
|
2967
|
+
|
|
2968
|
+
.label-saved-style-delete:hover {
|
|
2969
|
+
color: #c00;
|
|
2970
|
+
}
|
|
2971
|
+
|
|
2972
|
+
.label-saved-style-empty {
|
|
2973
|
+
padding: 3px 8px;
|
|
2339
2974
|
color: #999;
|
|
2340
2975
|
cursor: default;
|
|
2341
|
-
opacity: 0.45;
|
|
2342
2976
|
}
|
|
2343
2977
|
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2978
|
+
/* Two controls on one line: a font style and its size, a colour and its
|
|
2979
|
+
opacity, the icon shapes and the icon's size. Both columns are the same
|
|
2980
|
+
width in every row, rather than each row's right column being sized to
|
|
2981
|
+
whatever it happens to hold -- the panel is a stack of these pairs, and
|
|
2982
|
+
sizing them one row at a time leaves every field edge in a slightly
|
|
2983
|
+
different place.
|
|
2984
|
+
|
|
2985
|
+
Bottom-aligned, so that a caption above one control cannot push it out of
|
|
2986
|
+
line with the control beside it: the icon size has a "Size" over it and the
|
|
2987
|
+
shape buttons beside it have nothing, and the two still have to be level. */
|
|
2988
|
+
.label-split-row {
|
|
2989
|
+
display: grid;
|
|
2990
|
+
grid-template-columns: 1fr var(--label-split-b-width);
|
|
2991
|
+
column-gap: 10px;
|
|
2992
|
+
align-items: end;
|
|
2353
2993
|
}
|
|
2354
2994
|
|
|
2355
|
-
.label-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2995
|
+
.label-split-cell > span,
|
|
2996
|
+
.label-split-cell > .label-style-row-label {
|
|
2997
|
+
display: block;
|
|
2998
|
+
margin-bottom: 2px;
|
|
2999
|
+
color: #555;
|
|
3000
|
+
}
|
|
3001
|
+
|
|
3002
|
+
/* Captions a couple of sizes down from the values they name. They are read
|
|
3003
|
+
once, when the panel is first met, and the narrow column of a split row is
|
|
3004
|
+
only as wide as the longest of them -- "Letter spacing" is what set it --
|
|
3005
|
+
so quieter captions are also a narrower panel. Direct children only: the
|
|
3006
|
+
colour picker's H/S/B captions are spans in a row too. */
|
|
3007
|
+
.label-style-panel .label-style-row > span,
|
|
3008
|
+
.label-style-panel .label-style-selection-row > span,
|
|
3009
|
+
.label-style-panel .label-split-cell > span,
|
|
3010
|
+
.label-style-panel .label-style-row > .label-style-row-label,
|
|
3011
|
+
.label-style-panel .label-split-cell > .label-style-row-label,
|
|
3012
|
+
.label-style-panel .label-icon-size-caption,
|
|
3013
|
+
.label-style-panel .point-style-note {
|
|
3014
|
+
font-size: 12px;
|
|
3015
|
+
}
|
|
3016
|
+
|
|
3017
|
+
.label-split-row .label-split-cell + .label-split-cell {
|
|
3018
|
+
white-space: nowrap;
|
|
3019
|
+
}
|
|
3020
|
+
|
|
3021
|
+
/* Each column's control fills its column: the widths are the grid's to decide
|
|
3022
|
+
now, and a control keeping a width of its own would sit inside its cell
|
|
3023
|
+
rather than lining up with the one above it. */
|
|
3024
|
+
.label-split-cell > select,
|
|
3025
|
+
.label-split-cell > .size-field,
|
|
3026
|
+
.label-split-cell > input[type="text"] {
|
|
3027
|
+
width: 100%;
|
|
2360
3028
|
box-sizing: border-box;
|
|
2361
|
-
vertical-align: top;
|
|
2362
3029
|
}
|
|
2363
3030
|
|
|
2364
|
-
.label-
|
|
2365
|
-
|
|
2366
|
-
right: 0;
|
|
3031
|
+
.label-split-cell > .size-field {
|
|
3032
|
+
display: flex;
|
|
2367
3033
|
}
|
|
2368
3034
|
|
|
2369
|
-
.label-
|
|
2370
|
-
|
|
3035
|
+
.label-style-panel .size-field input.size-field-input {
|
|
3036
|
+
flex: 1;
|
|
3037
|
+
width: auto;
|
|
2371
3038
|
}
|
|
2372
3039
|
|
|
2373
|
-
|
|
3040
|
+
/* A grid track is at least as wide as its contents unless told otherwise, and
|
|
3041
|
+
a text input's contents are twenty characters whatever width it is given --
|
|
3042
|
+
without this the colour field pushes the opacity beside it off the panel. */
|
|
3043
|
+
.label-split-row .label-split-cell {
|
|
3044
|
+
min-width: 0;
|
|
3045
|
+
}
|
|
3046
|
+
|
|
3047
|
+
.label-font-style-row select {
|
|
2374
3048
|
width: 100%;
|
|
2375
3049
|
box-sizing: border-box;
|
|
2376
3050
|
}
|
|
2377
3051
|
|
|
2378
|
-
|
|
2379
|
-
|
|
3052
|
+
/* Both take their width from the split row's narrow column; a value reads from
|
|
3053
|
+
the left edge of the field, where the caption above it starts. */
|
|
3054
|
+
.label-style-panel .label-opacity-input,
|
|
3055
|
+
.label-style-panel .label-measure-input {
|
|
3056
|
+
padding: 0 4px;
|
|
3057
|
+
vertical-align: top;
|
|
2380
3058
|
}
|
|
2381
3059
|
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
3060
|
+
/* One disabled look for the whole panel. Left to themselves the controls each
|
|
3061
|
+
fade differently -- a select takes the browser's grey, an input with
|
|
3062
|
+
-webkit-appearance: none takes no styling at all, and a widget built from
|
|
3063
|
+
divs takes whatever it was given -- so an inert row ends up in three or four
|
|
3064
|
+
shades. Each control keeps its live colours and the whole thing is faded by
|
|
3065
|
+
the same amount, which also fades its border. */
|
|
3066
|
+
.label-style-panel select:disabled,
|
|
3067
|
+
.label-style-panel input[type="text"]:disabled,
|
|
3068
|
+
.label-style-panel .size-field.disabled,
|
|
3069
|
+
.label-style-panel .label-color-field.disabled,
|
|
3070
|
+
.label-style-panel .label-panel-action-btn.disabled,
|
|
3071
|
+
.label-style-panel .label-btn-group.disabled {
|
|
3072
|
+
opacity: 0.45;
|
|
3073
|
+
color: var(--normal-text);
|
|
3074
|
+
-webkit-text-fill-color: var(--normal-text);
|
|
3075
|
+
background-color: white;
|
|
3076
|
+
border-color: var(--label-field-border);
|
|
3077
|
+
}
|
|
3078
|
+
|
|
3079
|
+
/* Nothing inside an already-faded control fades again: two 0.45s over each
|
|
3080
|
+
other is 0.2, and a widget made of a wrapper and an input -- the size and
|
|
3081
|
+
colour fields -- was coming out half the weight of the plain input beside
|
|
3082
|
+
it. The parts still take their own disabled state, because a disabled input
|
|
3083
|
+
cannot be typed into and a disabled button cannot be pressed; it is only the
|
|
3084
|
+
fading that belongs to the whole. */
|
|
3085
|
+
.label-style-panel .label-btn-group.disabled .label-panel-btn.disabled,
|
|
3086
|
+
.label-style-panel .size-field.disabled .label-panel-btn.disabled,
|
|
3087
|
+
.label-style-panel .size-field.disabled input:disabled,
|
|
3088
|
+
.label-style-panel .label-color-field.disabled input:disabled,
|
|
3089
|
+
.label-style-panel .label-color-field.disabled .label-color-chit.disabled {
|
|
3090
|
+
opacity: 1;
|
|
3091
|
+
color: inherit;
|
|
2386
3092
|
}
|
|
2387
3093
|
|
|
2388
|
-
|
|
2389
|
-
|
|
3094
|
+
/* Whitespace and a bold heading separate the sections; a rule as well would be
|
|
3095
|
+
a third answer to a question already settled twice. */
|
|
3096
|
+
.label-style-panel .label-style-section + .label-style-section {
|
|
3097
|
+
margin-top: 12px;
|
|
2390
3098
|
padding-top: 0;
|
|
2391
3099
|
border-top: 0;
|
|
2392
3100
|
}
|
|
2393
3101
|
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
3102
|
+
/* Baselines, not boxes: the heading and the caption beside it are set at
|
|
3103
|
+
different sizes, and centring their boxes leaves the smaller one's baseline
|
|
3104
|
+
a pixel or two high. The switch has no baseline to share, so it centres on
|
|
3105
|
+
the line itself. */
|
|
3106
|
+
.label-style-panel .label-style-section-title {
|
|
3107
|
+
display: flex;
|
|
3108
|
+
align-items: baseline;
|
|
3109
|
+
gap: 8px;
|
|
2397
3110
|
}
|
|
2398
3111
|
|
|
2399
|
-
.
|
|
2400
|
-
|
|
2401
|
-
align-items: center;
|
|
2402
|
-
gap: 10px;
|
|
3112
|
+
.label-style-panel .label-style-section-title .label-toggle {
|
|
3113
|
+
align-self: center;
|
|
2403
3114
|
}
|
|
2404
3115
|
|
|
2405
|
-
.
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
3116
|
+
/* .hidden is one class and the rule above is two, so a heading told to hide
|
|
3117
|
+
would go on being laid out. The circle panel hides its Circles heading once
|
|
3118
|
+
the points are circles: the panel's title says so, and the section is the
|
|
3119
|
+
only thing left in it. */
|
|
3120
|
+
.label-style-panel .label-style-section-title.hidden {
|
|
3121
|
+
display: none;
|
|
2410
3122
|
}
|
|
2411
3123
|
|
|
2412
|
-
.
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
3124
|
+
/* 15.5px is what the dialogs subhead at (.info-box h4); the weight is the
|
|
3125
|
+
sketch's, which wants these read as headings rather than as captions. */
|
|
3126
|
+
.label-style-panel .label-style-section-name {
|
|
3127
|
+
font-size: 15.5px;
|
|
3128
|
+
color: #222;
|
|
2416
3129
|
}
|
|
2417
3130
|
|
|
2418
|
-
.
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
margin: 0;
|
|
3131
|
+
.label-style-panel .label-style-section-minor .label-style-section-name {
|
|
3132
|
+
font-size: 12px;
|
|
3133
|
+
font-weight: normal;
|
|
3134
|
+
line-height: 1;
|
|
2423
3135
|
color: #555;
|
|
2424
3136
|
}
|
|
2425
3137
|
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
3138
|
+
/* Where label text is measured (gui-label-measure.mjs). Off the page rather
|
|
3139
|
+
than display:none, which would give it no layout and its text no box. */
|
|
3140
|
+
.label-measure-svg {
|
|
3141
|
+
position: absolute;
|
|
3142
|
+
left: -10000px;
|
|
3143
|
+
top: -10000px;
|
|
3144
|
+
width: 1px;
|
|
3145
|
+
height: 1px;
|
|
3146
|
+
overflow: hidden;
|
|
3147
|
+
}
|
|
3148
|
+
|
|
3149
|
+
/* Closer to the heading above it than a row usually is, because that heading
|
|
3150
|
+
line carries this row's "Size" caption: the gap between a caption and the
|
|
3151
|
+
field it names is 2px everywhere else in the panel. */
|
|
3152
|
+
.text-style-panel .label-icon-shapes-row {
|
|
3153
|
+
margin-top: 2px;
|
|
3154
|
+
}
|
|
3155
|
+
|
|
3156
|
+
/* Pushed to the right and given the width of a split row's narrow column, so
|
|
3157
|
+
that it sits over the size field a row below it. */
|
|
3158
|
+
.text-style-panel .label-icon-size-caption {
|
|
3159
|
+
width: var(--label-split-b-width);
|
|
3160
|
+
margin-left: auto;
|
|
3161
|
+
font-weight: normal;
|
|
2429
3162
|
color: #555;
|
|
2430
3163
|
}
|
|
2431
3164
|
|
|
2432
|
-
.
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
3165
|
+
/* Darker than the app's default placeholder. These fields show the value the
|
|
3166
|
+
renderer will use when the property is absent -- 0 and auto are true of the
|
|
3167
|
+
label, they are just not stored on it -- so at #aaa they read as a control
|
|
3168
|
+
that is switched off rather than as an answer. */
|
|
3169
|
+
.label-style-panel ::placeholder {
|
|
3170
|
+
color: #777;
|
|
2436
3171
|
}
|
|
2437
3172
|
|
|
2438
|
-
|
|
3173
|
+
/* Buttons that answer one question share a border and sit flush, the way the
|
|
3174
|
+
size field and its stepper do: four shapes are four answers to "which
|
|
3175
|
+
symbol", not four separate controls. They divide the width of their cell so
|
|
3176
|
+
that the group lines up with the field above or below it. */
|
|
3177
|
+
.label-style-panel .label-btn-group {
|
|
2439
3178
|
display: flex;
|
|
2440
|
-
|
|
2441
|
-
|
|
3179
|
+
box-sizing: border-box;
|
|
3180
|
+
height: var(--label-field-height);
|
|
3181
|
+
border: 1px solid var(--label-field-border);
|
|
3182
|
+
border-radius: var(--label-field-radius);
|
|
3183
|
+
background: white;
|
|
3184
|
+
overflow: hidden;
|
|
2442
3185
|
}
|
|
2443
3186
|
|
|
2444
|
-
.
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
3187
|
+
.label-style-panel .label-btn-group .label-panel-btn {
|
|
3188
|
+
flex: 1;
|
|
3189
|
+
width: auto;
|
|
3190
|
+
height: auto;
|
|
3191
|
+
border: none;
|
|
3192
|
+
border-radius: 0;
|
|
3193
|
+
background: white;
|
|
2448
3194
|
}
|
|
2449
3195
|
|
|
2450
|
-
.
|
|
2451
|
-
|
|
2452
|
-
align-items: flex-end;
|
|
3196
|
+
.label-style-panel .label-btn-group .label-panel-btn + .label-panel-btn {
|
|
3197
|
+
border-left: 1px solid #e0e0e0;
|
|
2453
3198
|
}
|
|
2454
3199
|
|
|
2455
|
-
.
|
|
3200
|
+
/* Hover leaves the selected button alone. Every hover fill in the panel is
|
|
3201
|
+
lighter than the selection it would sit on, so pointing at the chosen answer
|
|
3202
|
+
made it look less chosen than its neighbours -- and there is nothing to
|
|
3203
|
+
preview anyway, since clicking it changes nothing. */
|
|
3204
|
+
.label-style-panel .label-btn-group .label-panel-btn:hover:not(.disabled):not(.selected) {
|
|
3205
|
+
background: #f0f0f0;
|
|
3206
|
+
}
|
|
3207
|
+
|
|
3208
|
+
/* A grey fill, not the inverse the panel's other buttons use: the glyph is
|
|
3209
|
+
what identifies the choice, and reversing it out makes the selected shape
|
|
3210
|
+
the hardest one to read. */
|
|
3211
|
+
.label-style-panel .label-btn-group .label-panel-btn.selected {
|
|
3212
|
+
background: #dcdcdc;
|
|
3213
|
+
color: black;
|
|
3214
|
+
}
|
|
3215
|
+
|
|
3216
|
+
/* A switch, because whether the label has a symbol at all is a yes/no that the
|
|
3217
|
+
four shapes below it then qualify. Off is a pale track with the knob left,
|
|
3218
|
+
on a dark one with the knob right. */
|
|
3219
|
+
.label-toggle {
|
|
2456
3220
|
position: relative;
|
|
2457
|
-
|
|
2458
|
-
|
|
3221
|
+
flex: none;
|
|
3222
|
+
width: 26px;
|
|
3223
|
+
height: 15px;
|
|
3224
|
+
border-radius: 8px;
|
|
3225
|
+
background: #ccc;
|
|
3226
|
+
cursor: pointer;
|
|
3227
|
+
user-select: none;
|
|
3228
|
+
transition: background-color 0.12s;
|
|
3229
|
+
}
|
|
3230
|
+
|
|
3231
|
+
.label-toggle-knob {
|
|
3232
|
+
position: absolute;
|
|
3233
|
+
top: 2px;
|
|
3234
|
+
left: 2px;
|
|
3235
|
+
width: 11px;
|
|
3236
|
+
height: 11px;
|
|
3237
|
+
border-radius: 50%;
|
|
3238
|
+
background: white;
|
|
3239
|
+
box-shadow: 0 1px 2px rgba(0,0,0,0.25);
|
|
3240
|
+
transition: left 0.12s;
|
|
3241
|
+
}
|
|
3242
|
+
|
|
3243
|
+
.label-toggle.on {
|
|
3244
|
+
background: #333;
|
|
3245
|
+
}
|
|
3246
|
+
|
|
3247
|
+
.label-toggle.on .label-toggle-knob {
|
|
3248
|
+
left: 13px;
|
|
3249
|
+
}
|
|
3250
|
+
|
|
3251
|
+
.label-toggle.disabled {
|
|
3252
|
+
opacity: 0.45;
|
|
3253
|
+
cursor: default;
|
|
3254
|
+
}
|
|
3255
|
+
|
|
3256
|
+
.label-style-section-title {
|
|
3257
|
+
margin-top: 11px;
|
|
3258
|
+
font-weight: 600;
|
|
3259
|
+
color: #333;
|
|
3260
|
+
}
|
|
3261
|
+
|
|
3262
|
+
.label-style-section + .label-style-section .label-style-section-title {
|
|
3263
|
+
margin-top: 0;
|
|
3264
|
+
}
|
|
3265
|
+
|
|
3266
|
+
/* The cell a colour field sits in, which is also what its picker hangs from:
|
|
3267
|
+
the picker is wider than the panel, so it opens over the map, and anchoring
|
|
3268
|
+
it to the cell keeps it on the same side of the panel as its field. */
|
|
3269
|
+
.label-color-row {
|
|
3270
|
+
position: relative;
|
|
3271
|
+
}
|
|
3272
|
+
|
|
3273
|
+
.label-panel-btn {
|
|
3274
|
+
box-sizing: border-box;
|
|
3275
|
+
user-select: none;
|
|
3276
|
+
cursor: pointer;
|
|
3277
|
+
border: 1px solid #999;
|
|
3278
|
+
border-radius: 3px;
|
|
3279
|
+
background: #eee;
|
|
3280
|
+
padding: 0;
|
|
3281
|
+
height: 19px;
|
|
3282
|
+
width: 19px;
|
|
3283
|
+
}
|
|
3284
|
+
|
|
3285
|
+
.label-panel-btn.disabled {
|
|
3286
|
+
color: #999;
|
|
3287
|
+
cursor: default;
|
|
3288
|
+
opacity: 0.45;
|
|
2459
3289
|
}
|
|
2460
3290
|
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
padding-bottom: 0;
|
|
3291
|
+
/* A button with a word on it: Clear style, Random fills, Create. The same
|
|
3292
|
+
shape as Save current in the saved styles row, which is the same kind of
|
|
3293
|
+
thing -- a named action, as wide as its name -- and the same height as the
|
|
3294
|
+
fields above it. */
|
|
3295
|
+
.label-panel-action-btn {
|
|
2467
3296
|
box-sizing: border-box;
|
|
3297
|
+
display: inline-flex;
|
|
3298
|
+
align-items: center;
|
|
3299
|
+
height: var(--label-field-height);
|
|
3300
|
+
padding: 0 8px;
|
|
3301
|
+
border: 1px solid var(--label-field-border);
|
|
3302
|
+
border-radius: var(--label-field-radius);
|
|
3303
|
+
background-color: white;
|
|
3304
|
+
color: var(--normal-text);
|
|
3305
|
+
cursor: pointer;
|
|
3306
|
+
user-select: none;
|
|
2468
3307
|
}
|
|
2469
3308
|
|
|
2470
|
-
.
|
|
2471
|
-
|
|
3309
|
+
.label-panel-action-btn:hover:not(.disabled) {
|
|
3310
|
+
background-color: #f0f0f0;
|
|
2472
3311
|
}
|
|
2473
3312
|
|
|
2474
|
-
.
|
|
2475
|
-
|
|
2476
|
-
align-items: flex-start;
|
|
2477
|
-
gap: 12px;
|
|
3313
|
+
.label-panel-action-btn.disabled {
|
|
3314
|
+
cursor: default;
|
|
2478
3315
|
}
|
|
2479
3316
|
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
3317
|
+
/* Buttons wrap rather than run off the panel: two of them fit on one line in
|
|
3318
|
+
the polygon panel and would not if either name grew. */
|
|
3319
|
+
.label-panel-button-row {
|
|
3320
|
+
display: flex;
|
|
3321
|
+
flex-wrap: wrap;
|
|
3322
|
+
gap: 4px 6px;
|
|
2483
3323
|
}
|
|
2484
3324
|
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
3325
|
+
/* A swatch and its hex value inside one border: the pair is one answer to one
|
|
3326
|
+
question, and a separate button beside a text box reads as two. The swatch
|
|
3327
|
+
keeps its own outline so that white does not disappear into the field. */
|
|
3328
|
+
.label-style-panel .label-color-field {
|
|
3329
|
+
display: flex;
|
|
3330
|
+
align-items: center;
|
|
2490
3331
|
box-sizing: border-box;
|
|
2491
|
-
|
|
3332
|
+
height: var(--label-field-height);
|
|
3333
|
+
padding: 0 3px;
|
|
3334
|
+
border: 1px solid var(--label-field-border);
|
|
3335
|
+
border-radius: var(--label-field-radius);
|
|
3336
|
+
background: white;
|
|
2492
3337
|
}
|
|
2493
3338
|
|
|
2494
|
-
.
|
|
2495
|
-
|
|
2496
|
-
gap: 6px;
|
|
2497
|
-
align-items: flex-start;
|
|
2498
|
-
justify-content: flex-start;
|
|
3339
|
+
.label-style-panel .label-color-field:focus-within {
|
|
3340
|
+
border-color: #d3aa00;
|
|
2499
3341
|
}
|
|
2500
3342
|
|
|
2501
|
-
.
|
|
2502
|
-
|
|
2503
|
-
|
|
3343
|
+
.label-style-panel .label-color-field .label-color-chit {
|
|
3344
|
+
flex: none;
|
|
3345
|
+
width: 13px;
|
|
3346
|
+
height: 13px;
|
|
3347
|
+
margin-right: 6px;
|
|
3348
|
+
border: 1px solid #bbb;
|
|
3349
|
+
border-radius: 2px;
|
|
2504
3350
|
}
|
|
2505
3351
|
|
|
2506
|
-
.
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
3352
|
+
.label-style-panel .label-color-field input[type="text"] {
|
|
3353
|
+
flex: 1;
|
|
3354
|
+
width: auto;
|
|
3355
|
+
min-width: 0;
|
|
3356
|
+
height: auto;
|
|
3357
|
+
padding: 0;
|
|
3358
|
+
border: none;
|
|
3359
|
+
border-radius: 0;
|
|
3360
|
+
background: transparent;
|
|
3361
|
+
box-shadow: none;
|
|
2512
3362
|
}
|
|
2513
3363
|
|
|
2514
|
-
.
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
padding-bottom: 0;
|
|
2519
|
-
box-sizing: border-box;
|
|
3364
|
+
.label-style-panel .label-color-field input[type="text"]:focus {
|
|
3365
|
+
border: none;
|
|
3366
|
+
box-shadow: none;
|
|
3367
|
+
outline: none;
|
|
2520
3368
|
}
|
|
2521
3369
|
|
|
2522
|
-
.
|
|
2523
|
-
|
|
2524
|
-
align-items: center;
|
|
2525
|
-
gap: 2px;
|
|
3370
|
+
.label-style-panel .label-color-field.disabled {
|
|
3371
|
+
opacity: 0.45;
|
|
2526
3372
|
}
|
|
2527
3373
|
|
|
2528
|
-
.
|
|
2529
|
-
|
|
2530
|
-
line-height: 18px;
|
|
3374
|
+
.label-color-row .label-color-picker input[type="text"] {
|
|
3375
|
+
width: 45px;
|
|
2531
3376
|
}
|
|
2532
3377
|
|
|
2533
|
-
.
|
|
2534
|
-
|
|
2535
|
-
width: 30px;
|
|
2536
|
-
min-height: 17px;
|
|
2537
|
-
line-height: 17px;
|
|
2538
|
-
text-align: center;
|
|
2539
|
-
border: 1px solid #999;
|
|
2540
|
-
background: white;
|
|
2541
|
-
cursor: pointer;
|
|
3378
|
+
.label-css-row input {
|
|
3379
|
+
width: 100%;
|
|
2542
3380
|
box-sizing: border-box;
|
|
2543
3381
|
}
|
|
2544
3382
|
|
|
2545
|
-
|
|
2546
|
-
|
|
3383
|
+
/* What a section of this panel says when there is nothing in it to set: the
|
|
3384
|
+
layer is drawn some way this panel cannot edit, or the thing the section is
|
|
3385
|
+
for has to be made in the console. Set like a caption, not like a field's
|
|
3386
|
+
value. */
|
|
3387
|
+
.point-style-note {
|
|
3388
|
+
color: #555;
|
|
3389
|
+
line-height: 1.3;
|
|
2547
3390
|
}
|
|
2548
3391
|
|
|
2549
|
-
.
|
|
2550
|
-
display:
|
|
3392
|
+
.point-create-labels-row {
|
|
3393
|
+
display: flex;
|
|
3394
|
+
align-items: center;
|
|
3395
|
+
gap: 10px;
|
|
2551
3396
|
}
|
|
2552
3397
|
|
|
2553
|
-
.
|
|
2554
|
-
|
|
3398
|
+
.point-create-copy-label {
|
|
3399
|
+
display: inline-flex;
|
|
3400
|
+
align-items: center;
|
|
3401
|
+
gap: 4px;
|
|
3402
|
+
margin: 0;
|
|
3403
|
+
color: #555;
|
|
3404
|
+
font-size: 12px;
|
|
3405
|
+
}
|
|
3406
|
+
|
|
3407
|
+
.point-create-copy-label span {
|
|
3408
|
+
display: inline;
|
|
3409
|
+
margin: 0;
|
|
3410
|
+
color: #555;
|
|
2555
3411
|
}
|
|
2556
3412
|
|
|
3413
|
+
/* Fixed rather than absolute so that a panel inside a scrolling box cannot trap
|
|
3414
|
+
the picker: Frame properties lives in an .alert-box that scrolls its
|
|
3415
|
+
overflow, which clipped the picker into the panel instead of letting it float
|
|
3416
|
+
over it. ColorPicker sets top/left from the field it belongs to when it
|
|
3417
|
+
opens. */
|
|
2557
3418
|
.label-color-picker {
|
|
2558
|
-
position:
|
|
3419
|
+
position: fixed;
|
|
2559
3420
|
z-index: 25;
|
|
2560
|
-
top: 48px;
|
|
2561
|
-
right: 0;
|
|
2562
3421
|
padding: 8px;
|
|
2563
3422
|
background: white;
|
|
2564
3423
|
border: 1px solid #ddd;
|
|
@@ -2657,6 +3516,10 @@ body.dragging-color-picker * {
|
|
|
2657
3516
|
margin-left: auto;
|
|
2658
3517
|
}
|
|
2659
3518
|
|
|
3519
|
+
.label-style-selection-row {
|
|
3520
|
+
line-height: 1;
|
|
3521
|
+
}
|
|
3522
|
+
|
|
2660
3523
|
.label-style-selection-row button {
|
|
2661
3524
|
margin-right: 5px;
|
|
2662
3525
|
}
|
|
@@ -2699,17 +3562,66 @@ body.dragging-color-picker * {
|
|
|
2699
3562
|
background: white;
|
|
2700
3563
|
}
|
|
2701
3564
|
|
|
3565
|
+
/* Nine plain squares: a border on each would double the lines in a shape that
|
|
3566
|
+
is nothing but lines, so the cells are filled and the chosen one is dark. */
|
|
3567
|
+
.text-style-panel .label-position-grid {
|
|
3568
|
+
grid-template-columns: repeat(3, 10px);
|
|
3569
|
+
gap: 3px;
|
|
3570
|
+
margin-top: -13px;
|
|
3571
|
+
margin-bottom: 3px;
|
|
3572
|
+
}
|
|
3573
|
+
|
|
3574
|
+
.text-style-panel .label-position-grid .label-panel-btn {
|
|
3575
|
+
width: 10px;
|
|
3576
|
+
height: 10px;
|
|
3577
|
+
border: none;
|
|
3578
|
+
border-radius: 1px;
|
|
3579
|
+
background: #dcdcdc;
|
|
3580
|
+
}
|
|
3581
|
+
|
|
3582
|
+
.text-style-panel .label-position-grid .label-panel-btn:hover:not(.disabled):not(.selected) {
|
|
3583
|
+
background: #c4c4c4;
|
|
3584
|
+
}
|
|
3585
|
+
|
|
3586
|
+
.text-style-panel .label-position-grid .label-panel-btn.selected {
|
|
3587
|
+
background: black;
|
|
3588
|
+
}
|
|
3589
|
+
|
|
3590
|
+
/* The position a dragged label is nearest, which is where it roughly belongs
|
|
3591
|
+
and the cell that puts it back. Between the unlit grey and the lit black,
|
|
3592
|
+
because it is saying something weaker than either: not "here" but "about
|
|
3593
|
+
here, and not exactly". */
|
|
3594
|
+
.text-style-panel .label-position-grid .label-panel-btn.nearest:not(.selected) {
|
|
3595
|
+
background: #a0a0a0;
|
|
3596
|
+
}
|
|
3597
|
+
|
|
3598
|
+
/* The grid and the Fixed/Draggable toggle share the position row, the toggle
|
|
3599
|
+
against the right edge so that it lines up with the fields in the rows
|
|
3600
|
+
above. */
|
|
3601
|
+
.text-style-panel .label-position-row {
|
|
3602
|
+
margin-top: 3px;
|
|
3603
|
+
display: flex;
|
|
3604
|
+
/* align-items: center; */
|
|
3605
|
+
justify-content: space-between;
|
|
3606
|
+
}
|
|
3607
|
+
|
|
3608
|
+
/* Words rather than glyphs, so these segments size to their text instead of
|
|
3609
|
+
splitting the group evenly, and sit in a group narrow enough to read as one
|
|
3610
|
+
control beside the grid. */
|
|
3611
|
+
.text-style-panel .label-drag-mode-buttons .label-panel-btn {
|
|
3612
|
+
display: flex;
|
|
3613
|
+
flex: 0 0 auto;
|
|
3614
|
+
align-items: center;
|
|
3615
|
+
padding: 0 7px;
|
|
3616
|
+
font-size: 12px;
|
|
3617
|
+
}
|
|
3618
|
+
|
|
2702
3619
|
.label-panel-btn.selected {
|
|
2703
3620
|
background-color: black;
|
|
2704
3621
|
border-color: black;
|
|
2705
3622
|
color: white;
|
|
2706
3623
|
}
|
|
2707
3624
|
|
|
2708
|
-
.label-icon-buttons {
|
|
2709
|
-
display: flex;
|
|
2710
|
-
gap: 2px;
|
|
2711
|
-
}
|
|
2712
|
-
|
|
2713
3625
|
.label-icon-buttons .label-panel-btn {
|
|
2714
3626
|
display: flex;
|
|
2715
3627
|
align-items: center;
|
|
@@ -2724,7 +3636,6 @@ body.dragging-color-picker * {
|
|
|
2724
3636
|
stroke: none;
|
|
2725
3637
|
}
|
|
2726
3638
|
|
|
2727
|
-
.label-icon-buttons .label-panel-btn[data-icon="none"] .label-icon-symbol,
|
|
2728
3639
|
.label-icon-buttons .label-panel-btn[data-icon="ring"] .label-icon-symbol {
|
|
2729
3640
|
fill: none;
|
|
2730
3641
|
stroke: currentColor;
|
|
@@ -2737,41 +3648,113 @@ body.dragging-color-picker * {
|
|
|
2737
3648
|
transform: scale(1.4);
|
|
2738
3649
|
}
|
|
2739
3650
|
|
|
2740
|
-
.label-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
line-height: 18px;
|
|
3651
|
+
.label-align-buttons .label-panel-btn {
|
|
3652
|
+
display: flex;
|
|
3653
|
+
align-items: center;
|
|
3654
|
+
justify-content: center;
|
|
2745
3655
|
}
|
|
2746
3656
|
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
3657
|
+
/* Drawn larger than the icon symbols above, which share its viewBox but not
|
|
3658
|
+
its proportions: three rules across the middle are ink over less than half
|
|
3659
|
+
of the box, where a circle or a square fills most of its own, so at the same
|
|
3660
|
+
13px both the glyph and its weight read smaller than the shapes beside it.
|
|
3661
|
+
16px also puts the 16-unit viewBox at one unit per pixel, so the half-pixel
|
|
3662
|
+
baselines the rules are drawn on land where they were meant to. */
|
|
3663
|
+
.label-align-symbol {
|
|
3664
|
+
display: block;
|
|
3665
|
+
width: 16px;
|
|
3666
|
+
height: 16px;
|
|
3667
|
+
fill: none;
|
|
3668
|
+
stroke: currentColor;
|
|
3669
|
+
stroke-width: 1.5;
|
|
3670
|
+
stroke-linecap: round;
|
|
2750
3671
|
}
|
|
2751
3672
|
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
3673
|
+
/* A size field and its stepper share a border and sit flush, so that the three
|
|
3674
|
+
elements read as one control rather than three. The buttons are always
|
|
3675
|
+
visible: they are the primary affordance of the panel's most-used numbers,
|
|
3676
|
+
and revealing them on hover would either reserve their space anyway or
|
|
3677
|
+
overlap the value being adjusted. */
|
|
3678
|
+
.size-field {
|
|
3679
|
+
display: inline-flex;
|
|
3680
|
+
align-items: stretch;
|
|
3681
|
+
box-sizing: border-box;
|
|
3682
|
+
height: var(--label-field-height, 19px);
|
|
3683
|
+
border: 1px solid var(--label-field-border, #999);
|
|
3684
|
+
border-radius: var(--label-field-radius, 3px);
|
|
3685
|
+
background: #fff;
|
|
3686
|
+
overflow: hidden;
|
|
3687
|
+
vertical-align: top;
|
|
2755
3688
|
}
|
|
2756
3689
|
|
|
2757
|
-
.
|
|
2758
|
-
|
|
2759
|
-
margin-right: 0;
|
|
3690
|
+
.size-field.disabled {
|
|
3691
|
+
opacity: 0.45;
|
|
2760
3692
|
}
|
|
2761
3693
|
|
|
2762
|
-
.
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
3694
|
+
/* input.size-field-input, not .size-field-input: the panels give their text
|
|
3695
|
+
inputs a border through an attribute selector, and the field's own border is
|
|
3696
|
+
the one that has to show. */
|
|
3697
|
+
.size-field input.size-field-input {
|
|
3698
|
+
width: 40px;
|
|
3699
|
+
min-width: 0;
|
|
3700
|
+
height: auto;
|
|
3701
|
+
margin: 0;
|
|
3702
|
+
padding: 0 3px;
|
|
3703
|
+
border: none;
|
|
3704
|
+
border-radius: 0;
|
|
3705
|
+
box-shadow: none;
|
|
3706
|
+
background: transparent;
|
|
2768
3707
|
color: black;
|
|
2769
3708
|
}
|
|
2770
3709
|
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
3710
|
+
/* The field shows focus on its outer border, so that the ring cannot be drawn
|
|
3711
|
+
between the input and the stepper it shares an edge with. */
|
|
3712
|
+
.size-field input.size-field-input:focus {
|
|
3713
|
+
outline: none;
|
|
3714
|
+
border: none;
|
|
3715
|
+
box-shadow: none;
|
|
3716
|
+
}
|
|
3717
|
+
|
|
3718
|
+
.size-field:focus-within {
|
|
3719
|
+
border-color: #d3aa00;
|
|
3720
|
+
}
|
|
3721
|
+
|
|
3722
|
+
/* The stepper is inset from the field's border rather than dividing it: the
|
|
3723
|
+
value is the field's content and the arrows are a control within it, which
|
|
3724
|
+
is also how the native spinner reads. */
|
|
3725
|
+
.size-field .size-field-stepper {
|
|
3726
|
+
display: flex;
|
|
3727
|
+
flex-direction: column;
|
|
3728
|
+
margin: 2px 2px 2px 0;
|
|
3729
|
+
border: 1px solid #d6d6d6;
|
|
3730
|
+
border-radius: 2px;
|
|
3731
|
+
background: #f7f7f7;
|
|
3732
|
+
overflow: hidden;
|
|
3733
|
+
}
|
|
3734
|
+
|
|
3735
|
+
/* Half-height buttons, so the pair occupies the width of one: the panel's rows
|
|
3736
|
+
are tight and a size field shares its row with a label. */
|
|
3737
|
+
.size-field .size-field-btn {
|
|
3738
|
+
display: flex;
|
|
3739
|
+
align-items: center;
|
|
3740
|
+
justify-content: center;
|
|
3741
|
+
width: 13px;
|
|
3742
|
+
height: 8px;
|
|
3743
|
+
border: none;
|
|
3744
|
+
border-radius: 0;
|
|
3745
|
+
background: transparent;
|
|
3746
|
+
}
|
|
3747
|
+
|
|
3748
|
+
.size-field .size-field-arrow {
|
|
3749
|
+
display: block;
|
|
3750
|
+
width: 7px;
|
|
3751
|
+
height: 5px;
|
|
3752
|
+
fill: #444;
|
|
3753
|
+
stroke: none;
|
|
3754
|
+
}
|
|
3755
|
+
|
|
3756
|
+
.size-field .size-field-btn:hover:not(.disabled) {
|
|
3757
|
+
background: #e2e2e2;
|
|
2775
3758
|
}
|
|
2776
3759
|
|
|
2777
3760
|
.nav-menu-item,
|
|
@@ -2937,6 +3920,14 @@ body.dragging-color-picker * {
|
|
|
2937
3920
|
transform: translateY(0);
|
|
2938
3921
|
}
|
|
2939
3922
|
|
|
3923
|
+
/* The toolbar being hovered comes forward, so that a tooltip drawn above a
|
|
3924
|
+
button is not painted behind the toolbar stacked over it. The tooltip's own
|
|
3925
|
+
z-index cannot do this: each toolbar is transformed, which makes it a
|
|
3926
|
+
stacking context its descendants cannot escape. */
|
|
3927
|
+
.floating-toolbar:hover {
|
|
3928
|
+
z-index: 1;
|
|
3929
|
+
}
|
|
3930
|
+
|
|
2940
3931
|
.floating-toolbar-content {
|
|
2941
3932
|
display: flex;
|
|
2942
3933
|
align-items: center;
|
|
@@ -2967,6 +3958,16 @@ body.dragging-color-picker * {
|
|
|
2967
3958
|
height: 24px;
|
|
2968
3959
|
}
|
|
2969
3960
|
|
|
3961
|
+
.floating-toolbar-btn.text-btn {
|
|
3962
|
+
font-size: 12px;
|
|
3963
|
+
padding: 0 7px;
|
|
3964
|
+
width: auto;
|
|
3965
|
+
/* The toolbar is a flex row, which would otherwise squeeze a two-word
|
|
3966
|
+
label onto two lines and leave the button taller than its neighbours. */
|
|
3967
|
+
flex: none;
|
|
3968
|
+
white-space: nowrap;
|
|
3969
|
+
}
|
|
3970
|
+
|
|
2970
3971
|
.floating-toolbar-btn svg * {
|
|
2971
3972
|
fill: var(--theme-col);
|
|
2972
3973
|
transition: fill 100ms ease;
|
|
@@ -2984,6 +3985,30 @@ body.dragging-color-picker * {
|
|
|
2984
3985
|
background-color: #cdebf9;
|
|
2985
3986
|
}
|
|
2986
3987
|
|
|
3988
|
+
/* A toggle button that is currently armed */
|
|
3989
|
+
.floating-toolbar-btn.selected {
|
|
3990
|
+
background-color: #cdebf9;
|
|
3991
|
+
}
|
|
3992
|
+
|
|
3993
|
+
.floating-toolbar-btn.selected svg * {
|
|
3994
|
+
fill: #166689;
|
|
3995
|
+
}
|
|
3996
|
+
|
|
3997
|
+
/* An icon button's blue wash goes with its themed icon, but a text button is
|
|
3998
|
+
grey and takes the grey the panels' action buttons use. A selected button
|
|
3999
|
+
keeps its own background while hovered rather than flashing back to grey. */
|
|
4000
|
+
.floating-toolbar-btn.text-btn:hover:not(.disabled):not(.selected) {
|
|
4001
|
+
background-color: #f0f0f0;
|
|
4002
|
+
}
|
|
4003
|
+
|
|
4004
|
+
.floating-toolbar-btn.text-btn:active:not(.disabled):not(.selected) {
|
|
4005
|
+
background-color: #e5e5e5;
|
|
4006
|
+
}
|
|
4007
|
+
|
|
4008
|
+
.floating-toolbar-btn.text-btn.selected {
|
|
4009
|
+
background-color: #e5e5e5;
|
|
4010
|
+
}
|
|
4011
|
+
|
|
2987
4012
|
.floating-toolbar-btn.disabled {
|
|
2988
4013
|
cursor: default;
|
|
2989
4014
|
}
|
|
@@ -2992,8 +4017,83 @@ body.dragging-color-picker * {
|
|
|
2992
4017
|
fill: #b8c4ca;
|
|
2993
4018
|
}
|
|
2994
4019
|
|
|
2995
|
-
/*
|
|
2996
|
-
|
|
4020
|
+
/* A captioned control: a segmented mode switch or a short typed value. The
|
|
4021
|
+
caption is what lets the control be read at a glance, so it is always shown
|
|
4022
|
+
rather than hidden behind a tooltip. */
|
|
4023
|
+
.floating-toolbar-group {
|
|
4024
|
+
position: relative;
|
|
4025
|
+
display: flex;
|
|
4026
|
+
align-items: center;
|
|
4027
|
+
flex: none;
|
|
4028
|
+
gap: 5px;
|
|
4029
|
+
margin: 0 4px;
|
|
4030
|
+
}
|
|
4031
|
+
|
|
4032
|
+
.floating-toolbar-caption {
|
|
4033
|
+
font-size: 12px;
|
|
4034
|
+
color: #808080;
|
|
4035
|
+
white-space: nowrap;
|
|
4036
|
+
user-select: none;
|
|
4037
|
+
}
|
|
4038
|
+
|
|
4039
|
+
/* Both modes stay visible inside a single outlined well, so the lit one reads
|
|
4040
|
+
as the current state rather than as the result of clicking. */
|
|
4041
|
+
.floating-toolbar-segments {
|
|
4042
|
+
display: flex;
|
|
4043
|
+
align-items: center;
|
|
4044
|
+
background-color: #f0f0f0;
|
|
4045
|
+
border-radius: 6px;
|
|
4046
|
+
padding: 2px;
|
|
4047
|
+
gap: 2px;
|
|
4048
|
+
}
|
|
4049
|
+
|
|
4050
|
+
.floating-toolbar-segments .floating-toolbar-btn {
|
|
4051
|
+
height: 22px;
|
|
4052
|
+
border-radius: 4px;
|
|
4053
|
+
}
|
|
4054
|
+
|
|
4055
|
+
/* A segment sits on the well rather than on the toolbar, so its hover has to
|
|
4056
|
+
darken past the well's own grey to register. */
|
|
4057
|
+
.floating-toolbar-segments .floating-toolbar-btn:hover:not(.disabled):not(.selected) {
|
|
4058
|
+
background-color: #e4e4e4;
|
|
4059
|
+
}
|
|
4060
|
+
|
|
4061
|
+
.floating-toolbar-segments .floating-toolbar-btn.selected {
|
|
4062
|
+
background-color: #fff;
|
|
4063
|
+
color: #166689;
|
|
4064
|
+
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12);
|
|
4065
|
+
}
|
|
4066
|
+
|
|
4067
|
+
.floating-toolbar-field {
|
|
4068
|
+
cursor: default;
|
|
4069
|
+
}
|
|
4070
|
+
|
|
4071
|
+
.floating-toolbar-field input[type=text] {
|
|
4072
|
+
width: 48px;
|
|
4073
|
+
height: 22px;
|
|
4074
|
+
box-sizing: border-box;
|
|
4075
|
+
font-size: 12px;
|
|
4076
|
+
padding: 0 5px;
|
|
4077
|
+
border: 1px solid #ddd;
|
|
4078
|
+
border-radius: 4px;
|
|
4079
|
+
background-color: #fff;
|
|
4080
|
+
color: var(--dark-text-col);
|
|
4081
|
+
-webkit-appearance: none;
|
|
4082
|
+
appearance: none;
|
|
4083
|
+
outline: none;
|
|
4084
|
+
}
|
|
4085
|
+
|
|
4086
|
+
/* The same flat focus as the panels: the border turns gold and the global
|
|
4087
|
+
input rule's glow is suppressed. */
|
|
4088
|
+
.floating-toolbar-field input[type=text]:focus {
|
|
4089
|
+
border-color: #d3aa00;
|
|
4090
|
+
box-shadow: none;
|
|
4091
|
+
outline: none;
|
|
4092
|
+
}
|
|
4093
|
+
|
|
4094
|
+
/* Tooltip shown above the button (or captioned control) on hover */
|
|
4095
|
+
.floating-toolbar-btn[data-tooltip]:hover:not(.disabled)::after,
|
|
4096
|
+
.floating-toolbar-group[data-tooltip]:hover::after {
|
|
2997
4097
|
content: attr(data-tooltip);
|
|
2998
4098
|
position: absolute;
|
|
2999
4099
|
bottom: calc(100% + 8px);
|