Commit Graph
3875 Commits
Author SHA1 Message Date
Manjunath PaparajuandSameh Khamis 129b35e470 Show the rail highlight at icon size when a first panel opens
Opening a panel from the labelled rail folds its pills to icons over a few
frames, and the highlight faded in at a pill's width and then shrank, as
did the open button's own fill. The highlight now appears only once the
open button is an icon again (square), its size changes at once rather
than easing, and the open button carries no fill of its own.

Co-authored-by: Sameh Khamis <[email protected]>
2026-11-14 13:41:07 -08:00
Manjunath PaparajuandSameh Khamis 9261279639 Drop a held edge-scroll step when the motion turns or the pointer moves to the other rail
Co-authored-by: Sameh Khamis <[email protected]>
2026-11-14 13:41:07 -08:00
Manjunath PaparajuandSameh Khamis 81f3602134 Hold an edge-scroll step that comes too soon instead of dropping it
A scroll that reached a step within 500 ms of the last one was used up
without stepping, so mouse wheel notches 300 ms apart stepped only every
other notch and a second swipe inside the gap did nothing. Such a step now
waits and fires once the gap has passed (one held at most, skipped if the
pointer has left the strip), and the held timer is cleared on teardown.
A comment naming the items cockpit hides is corrected.

Co-authored-by: Sameh Khamis <[email protected]>
2026-11-14 13:41:07 -08:00
Manjunath PaparajuandSameh Khamis 422a11d9a4 Give a rail's open icon its own island
With a panel open, a rail's glass is drawn in pieces: one around the open
icon and one for each run of icons above and below it, with a small break
between them. The icons keep their places; the rail's icon spacing grows
from 2 px to 12 px to leave room for the break. The shadow rule for the
old lifted icon is removed.

Co-authored-by: Sameh Khamis <[email protected]>
2026-11-14 13:41:07 -08:00
Manjunath PaparajuandSameh Khamis 9cc2a1811b Leave at least half a second between edge-scroll steps
A scroll that would step a rail again within 500 ms of the last step is
used up without stepping, so panels never switch back to back.

Co-authored-by: Sameh Khamis <[email protected]>
2026-11-14 13:41:07 -08:00
Manjunath PaparajuandSameh Khamis b090937e5f Keep rail icons in place and move only the highlight
The left rail no longer lifts its open icon out beside the panel title or
reorders the rest behind it. Every icon keeps its place, open or not, and
the rail's shared highlight slides to the open one, on both rails.

The rail also holds one height whichever panel is open: its offset now
allows for the stack rising by a different amount for a tall panel than at
rest.

Co-authored-by: Sameh Khamis <[email protected]>
2026-11-14 13:41:07 -08:00
Manjunath PaparajuandSameh Khamis 59ffa87535 Keep the left rail's order when its open item is lifted out
Co-authored-by: Sameh Khamis <[email protected]>
2026-11-14 13:41:07 -08:00
Manjunath PaparajuandSameh Khamis b080857c35 Make one scroll at a rail's edge step one panel
A swipe is still speeding up when it first steps, and that rise in speed was
read as a fresh flick, so one swipe could step two panels. A flick now
counts only after the gesture has clearly slowed and a short moment after a
step; a mouse wheel notch still steps each time.

The rest of a gesture that has stepped is used up even when the pointer is
no longer in the strip, so its coasting does not zoom the globe or scroll
what opened under it. The strip is never wider than a rail's own column, a
panel in either stack keeps its own scrolling, and the slide classes come
off without an animation to end them (reduced motion).

Co-authored-by: Sameh Khamis <[email protected]>
2026-11-14 13:41:07 -08:00
Manjunath PaparajuandSameh Khamis 7ee047961b Move Visual to the left rail and let panels sit at the screen edge
The left rail holds Data Layers, Utilities, Authoring and Visual; the right
rail holds Context, CCTV and Street Level. A button in each panel header
moves that side's panels to the screen edge, with the rail as a row above
them, and scrolling at a screen edge steps through a rail's panels. An open
right panel starts just under the HUD readouts, and Context and CCTV take
the column's full height. The right rail stays level with the left column's
top whichever left panel is open, in both layouts.

Co-authored-by: Sameh Khamis <[email protected]>
2026-11-14 13:41:07 -08:00
Sameh Khamis f0a8b1193a Merge pull request #1734 from bilawalsidhu/transit/route-type-models
Draw transit vehicles as trolleybuses, cable cars, funiculars, gondolas and monorails
2026-11-14 12:38:06 -08:00
Sameh Khamis dd15223109 Class only PID's trolleybus lines as trolleybuses, and name the new modes in the plural for voice
PID's routes.txt types lines 51, 52, 53, 58, 59, 232 and 275 as
trolleybuses (route type 11); the rest of 50 to 59 stay buses, as before.
Voice now also knows trolleybuses, gondolas, cable cars, funiculars and
monorails.
2026-11-14 12:22:30 -08:00
Sameh Khamis 96cefa28b3 Number the transit route type changelog fragment for #1734 2026-11-14 12:03:54 -08:00
Sameh Khamis 39c89d563b Draw transit vehicles as trolleybuses, cable cars, funiculars, gondolas and monorails
The transit layer knew five modes, so a trolleybus drew as a bus, a
funicular as a train and a coach as a city bus. The GTFS basic route types
are now modes of their own (trolleybus, cable_tram, monorail, funicular,
aerial_lift), each with an icon, colour, detection tier, card word, voice
name, speed ceiling and fleet model.

A vehicle record may carry its route's GTFS route_type as routeType. It
settles the mode after the feed's fleet hint and before its route hint, and
picks the finer model (a coach for 200, a high-speed set for 101) when the
type is a kind of the vehicle's mode. Retained history classifies epochs
through transitModeFor too, so trails join the live vehicle.

Route hints from each operator's routes.txt: Prague's trolleybus lines
(51-59, 232, 275) and Petrin funicular, and the trams, trolleybuses and
metro lines of Bucharest, Cluj-Napoca and Turin. A feed may also name
route corrections that outrank the route type: Le Havre's routes.txt types
its funicular (8-FUNI) as a bus, so it is corrected to a funicular.
2026-11-14 12:03:12 -08:00
Sameh Khamis 250f0e20c3 Merge pull request #1733 from bilawalsidhu/fleet/aid-to-navigation-buoys
Draw aids to navigation as buoys
2026-11-14 11:27:46 -08:00
Sameh Khamis 52507a0755 Draw no buoy for a virtual aid to navigation
A virtual aid (AIS message 21's VirtualAtoN flag) is a mark broadcast
where nothing physical stands, so drawing it as a buoy showed a mark
that is not there. The vessel source record now carries `virtual`
(false unless a source says true; any source may set it), AISStream
sets it from VirtualAtoN, and the vessel layer keeps such an aid's
disc: vesselModelSpec returns null for it and the layer gathers no
model item for it. Its card, selected card and readout add VIRTUAL
after its kind.
2026-11-14 11:07:13 -08:00
Sameh Khamis 9ae121c7c0 Number the buoy models changelog fragment for #1733 2026-11-14 11:02:14 -08:00
Sameh Khamis 6c7fe48f40 Show an aid to navigation's kind, not a speed or heading
A buoy's card, selected card and HUD readout showed "0.0KT · 135°" from
whatever its source reported. A fixed mark has neither, so they now show
its kind alone, whole ("CARDINAL MARK N", which the 14-character type cut
read as "CARDINAL MARK "), in the bone white of its disc.

isAidToNavigation now knows every kind an aid report names ("Light, with
sectors", "Fixed structure off shore" had no aid word), leaves out a
"Buoy Layer" as it does a tender, and matches each type text once: the
vessel layer asks per vessel on its rotation pass, which now skips the
aid discs it never turns.

Aid rows no longer cost ships their place: aisStreamRows lists every
vessel ahead of every aid, so the layer's 12,000-row request never drops
a ship for a buoy, and vessels_in_area (and the brief built on it)
counts ships only. An aid's name runs on into its NameExtension.
2026-11-14 10:02:59 -08:00
Sameh Khamis 279aedb2f4 Draw aids to navigation as buoys
A buoy, beacon, RACON, light or IALA mark in the vessel feed was drawn
as a ship. A vessel record whose type names one, or whose MMSI is an
aid-to-navigation station's (99MIDxxxx), is now isAidToNavigation and
vesselModelSpec draws it as the fleet set's buoy of its mark (cardinal
N/E/S/W, port or starboard hand, safe water, isolated danger, special
mark; a red can when the type names no mark), at its built size and
flagged fixed so its model does not turn to a heading. Its icon is a
disc instead of a chevron.

AISStream now subscribes to AidsToNavigationReport by default, and the
server names each report's aid type code (0 to 31) as its kind instead
of reading it as a ship type.
2026-11-14 09:54:01 -08:00
Sameh Khamis f24abfc88f Merge pull request #1732 from bilawalsidhu/fix/adsblol-true-heading
fix(flights): an aircraft with no ground track faces its true heading, not north
2026-11-14 09:10:58 -08:00
Sameh Khamis 58776a6976 Merge branch 'main' into fix/adsblol-true-heading 2026-11-14 09:00:30 -08:00
Sameh Khamis 391e33b0d5 Merge pull request #1731 from bilawalsidhu/fleet/aircraft-mesh-colours
Draw aircraft models in their own mesh colours
2026-11-14 08:54:44 -08:00
Sameh Khamis deb42b38f7 Add the changelog fragment 2026-11-14 08:49:48 -08:00
Sameh Khamis fd06272e37 fix(flights): an aircraft with no ground track faces its true heading, not north
readsb rows (adsb.lol and a local dump1090 receiver) often send no track for
an aircraft on the ground, only its true heading. The track then read as
missing and the aircraft was drawn facing north, so one taxiing south looked
like it was moving backwards. Each normalizer now falls back to true_heading,
never the magnetic heading.
2026-11-14 08:49:29 -08:00
Sameh Khamis a3611caddb Fix the Local ADS-B model test name 2026-11-14 08:25:05 -08:00
Sameh Khamis 4d81d3be3a Describe aircraft models in their mesh colours in the docs 2026-11-14 08:24:51 -08:00
Sameh Khamis c2c196ab1e Add the changelog fragment 2026-11-14 08:06:59 -08:00
Sameh Khamis 8cb096fc21 Draw aircraft models in their own mesh colours
Every aircraft model (Flights, Military Flights, Local ADS-B) mixed 94% of a
flat class colour over its mesh, so airliners drew as white silhouettes and
military ones as amber. Models now use HIGHLIGHT: white leaves the mesh's own
colours as built, and the tracked and emergency colours tint the mesh without
hiding its paint. The IR boost still draws them flat white.
2026-11-14 08:06:51 -08:00
Sameh Khamis 3934be9ff9 Merge pull request #1730 from bilawalsidhu/fleet/airport-vehicle-models
Rebuild the airport vehicle models with real shapes
2026-11-14 07:45:39 -08:00
Sameh Khamis c73c5c4eb6 Add the changelog fragment 2026-11-13 23:43:17 -08:00
Sameh Khamis 491c50ed18 Rebuild the airport vehicle models with real shapes
The car, van, fire truck and pushback tug were stacked boxes. The car is now an
operations SUV (rounded body, glass house with a sloped windscreen, roof light
bar, grille and lamps), the van a high-roof panel van, the fire truck an airport
crash tender with roof and bumper turrets on three axles, and the pushback a low
chamfered tug with a glazed cab. All stand on the ground at their built size.
Their trail anchors are measured again.
2026-11-13 23:43:09 -08:00
Sameh Khamis c5cf579174 Merge pull request #1729 from bilawalsidhu/fleet/ground-vehicles
Draw airport ground vehicles by callsign and ground stations as a radio mast
2026-11-13 21:38:58 -08:00
Sameh Khamis 332551ec84 Add the changelog fragment 2026-11-13 21:20:48 -08:00
Sameh Khamis 6e655b801d feat(fleet): draw airport ground vehicles by callsign and ground stations as a radio mast
Feeds carry many airport ground vehicles (type ZVEH) and ground stations
(GRND) that were drawn as the generic plane, some at the 10 km airborne
default.

- types.json gains aircraft_callsign rules: a ZVEH callsign starting FIRE is
  a fire truck, PUSH/TUG a pushback tug, DEICER/SQUID/SQB a van, else a car.
  GRND draws a new 11.8 m radio mast (other/radio_mast.glb).
- resolveAircraft and aircraftModelSpec take the callsign; a matched rule
  names the model outright, ahead of the type's class model.
- The layer spec cache keys such types by the rule matched, so it holds at
  most one entry per rule.
- These models (catalog category `other`) draw at their built size, as such
  models already do, and a
  contact with no altitude whose model is one now stands on the ground; the
  feed's own type is kept for such contacts, as no airframe lookup knows it.
- Local ADS-B passes the callsign too.
2026-11-13 21:20:16 -08:00
Sameh Khamis 083da40d88 Merge pull request #1686 from ZloyS/denis/cockpit-subject-providers
feat(cockpit): application cockpit subjects
2026-11-13 19:06:18 -08:00
Sameh Khamis 16d163a886 Merge branch 'main' into denis/cockpit-subject-providers 2026-11-13 18:58:00 -08:00
Sameh Khamis c653b3878d Merge pull request #1723 from bilawalsidhu/fix/cctv-panel-collapse-on-disable
Collapse the CCTV panel when the layer is switched off
2026-11-13 18:57:54 -08:00
Sameh Khamis 53cbd55181 Merge branch 'main' into fix/cctv-panel-collapse-on-disable 2026-11-13 18:47:22 -08:00
Sameh Khamis a91a89ec1c Merge pull request #1579 from bilawalsidhu/german/map-render-error-state
Show a recoverable notice when the globe stops drawing
2026-11-13 18:47:16 -08:00
Sameh Khamis c43bf103d6 Merge branch 'main' into german/map-render-error-state 2026-11-13 18:37:03 -08:00
Sameh Khamis 6c55daf9ac fix(transit): a held vehicle's snapshot height is its drawn marker's while the frame pass places it
Near the ground the marker follows the terrain sampled between two reports,
which a straight blend of the reports' floors misses over uneven ground.
2026-11-13 18:36:42 -08:00
Sameh Khamis 9b46692c64 Suspend only the layers Context isolation is switching off
The session snapshot recorded a user's switch only after the CCTV panel had
already rendered the layer off, so a first switch-off by the user inside
Contacts, or after a partly failed restore, still kept the panel open.
Context controls now hold the layers _clearLayersOutsideContextMode is
switching off while its transitions run; suspendsLayer reads that set, and
the snapshot is no longer consulted.
2026-11-13 18:32:57 -08:00
Sameh Khamis 4bb7b411e9 fix(cockpit): a provider's subject rides where it is drawn, and the documented provider rides a moving train
- A frame with no speedMps gets an exact anchor: an inertial one ran on at
  zero speed and closed at 0.75 m/s, so the camera fell kilometres behind a
  moving train. The docs example now passes speedMps and anchor: 'exact',
  a name for its HUD, and isEntryAllowed for a train bound to its line.
- Transit's snapshot height is the floor where playback draws the vehicle,
  not the newest report's floor uphill, and null while that floor is cold,
  so a view waits for the surface instead of standing on the ellipsoid.
- Rail's direction follows playback once it has placed the train: a report
  that runs back (a reversal, or GPS jitter) no longer turns the view
  while the drawn train still runs forward.
- A frame's id is trimmed as the candidate's is.
- A double-click on the selected vessel no longer enters an application's
  subject that took entry after it.
- The docs import from gods-eye-view/..., the package's name.
2026-11-13 18:23:50 -08:00
Sameh Khamis 9d01f8df77 Show no notice for a lost context on a page that must not reload, and log each render error once
An inline panel that lost its WebGL context showed the panel runtime's own
notice and, over it, an alert dialog with no buttons that it could not act
on. With allowReload false a lost context now clears the notice and shows
none, as the docs already said. keepPanelRendering no longer logs render
errors itself: the render failure notice logs each one. Name the Cesium
private fields finishRaise and reportThrown rely on, and the version they
were checked against.
2026-11-13 18:16:07 -08:00
Sameh Khamis f0ee1b95ca Collapse the CCTV panel when the user switches CCTV off inside Contacts
Turning a layer on does not leave Contacts, so a user could turn CCTV back
on inside the mode and off again; the layer was still in the session
snapshot and the panel stayed open on an empty frame. The snapshot now
records every layer the user switched during the session, and
suspendsLayer is true only for a layer isolation switched off that the
user has not touched since.
2026-11-13 18:12:44 -08:00
Said Turksever f29b0b2639 Keep the CCTV panel through Context isolation, and collapse through the panel chrome
Contacts and Space Missions switch CCTV off to isolate themselves and restore
it on the way out: the panel and its share preference now stay as they are for
that round trip, as they do for Clear selected data layers. The controls no
longer read the collapsed class before asking: the panel chrome tells a panel
the accordion folded from one whose saved state is closed.

The camera controls gate asserts the collapse, reopens CCTV from the right
rail before switching it back on, and runs a Contacts entry and exit with the
panel open.
2026-11-13 17:46:43 +00:00
Said Turksever 7f18943ec4 docs: CCTV panel collapse on switch-off, and changelog fragment 2026-11-13 17:27:22 +00:00
Said Turksever 0325805eb0 Collapse the CCTV panel when the layer is switched off
The panel opened itself when a camera became active, but nothing closed it
when the layer went off: it stayed expanded, empty, and its meta line still
described the last camera. The collapse runs only on the on-to-off change, so a
panel opened by hand while the layer is off stays open, and a context-mode
layer clear keeps the panel as Radio does.
2026-11-13 17:26:34 +00:00
German Khokhlov 73bd952736 Share one render loop fixture across the render failure tests
Four test files built the same widget on CesiumWidget.prototype, viewer
proxy, store and notice; renderLoopFixture.mjs now does it once. The notice
test drives Cesium.Event instead of a hand-made double. frameEvents() drops
tileset.tileLoad, which Cesium raises inside its own error handling, and the
notice no longer guards a viewer without a canvas or requestRender.
2026-11-13 20:16:08 +04:00
Sameh Khamis 7df581765d Merge pull request #1715 from bilawalsidhu/sameh/vessel-typical-length
Draw a vessel of unknown length at its ship type's typical size
2026-11-13 07:52:52 -08:00
Denis Groshev 974023510f fix(rail, transit): a train or vehicle a first-person view holds draws no 3D model either, since the view's eye is inside it; let go, its model draws again
The fleet models (#1714) draw nearby trains and vehicles under the 3D toggle. A
held one now leaves out its model as it does its icon, as the Vessels layer does
for its bridge subject: its model item is hidden, and handing the visual back
to its icon keeps the icon hidden while held. Tests drive each layer with the
real fleet-model layer and a stubbed glTF loader; both fail without the fix.
2026-11-13 16:43:50 +01:00