Open dabreegster opened 2 years ago
I thought about the bike tool's new mode shift thing. It's got tooltips for certain roads, and I've thought about clicking to show sample routes there, so it seems like a candidate for this.
But then I realized that this, and loads of the simulation layers, use ColorDiscrete
and ColorNetwork
as attempts to refactor the problem of just drawing a bunch of basemap objects in a special way. If they were switched over to this new API, they could get much simpler, and also take advantage of new features easily! For example, the parking layer shows a heatmap of capacity -- what if was as easy as .tooltip(format!("{} / {} spots", free, total))
to add an unzoomed tooltip, or clicking unzoomed to open up the info panel set to the parking-over-time plot?
Styling: Similar to the benefits of the massive button refactor, this could be a chance to consolidate the million ad-hoc ways we have of styling different roads, buildings, etc!
widgetry now has pretty good abstractions for handling most "screen-space" interactions, with nice APIs like the button builders. But the world of "map-space" objects is the wild west -- just ad-hoc code for figuring out what exists, hovering, selecting, dragging, tooltips, z-ordering. Can we do better?
Use cases
All of these have some kind of hovering behavior.
World
abstraction)MapspaceTooltips
)InputWaypoints
and now alternate routes, snapping)And I'm sure I've missed some.
An extreme take: Almost no app code should call
ctx.redo_mouseover()
, but there are... >50 callers right now!What makes this stuff hard?
Caching and maintaining state -- when you hover or select something different, we usually want to draw something, maybe add a tooltip. Ad-hoc right now.
When hovering or actively dragging a draggable object, we still want to allow zooming, but not panning.
Dragging is complicated and buggy. In the route tool, if you drag a waypoint close to an alternate path, stuff breaks. Z-ordering there is implicit in the code, has to match in
event
anddraw
. Conflicts between waypoints and alt paths.Ideas
Extend
map_editor
'sWorld
abstraction. There'll be something for aState
that knows about all of the map-space objects. Objects are:What's in a world?
In most of the use cases, the map-space stuff is "extra" objects on top of the basemap. The basemap stuff is mostly managed by
map_gui
, which has its own system for managing these kinds of concerns. Except there are also some places that "subset" the basemap objects:mouseover_unzoomed_buildings
or doing further filtering (like no editing service roads or light rail)Hot take:
app.primary.current_selection
is a bad idea? I count around 30 places that reset it toNone
when entering/leaving the state. I think the world of selectable objects shouldn't be shared App-wide. Most states should control this more directly.How to drag "correctly"
1) Bail out if the cursor isn't in map-space 2) Go through all the objects, maybe start a drag 3) Only then allow normal canvas movement (not while hovering on something that's draggable)
Where's the state live?
The
World
approach is to be generic over some ID type. Shoving in custom data for the objects is an option, or letting theState
manage it and map things. (Hey, we're inventing parts of ECS...)Similar to
Panel
s, could we make do with strings, or do we need IDs? Could the world container thing assign its own opaque IDs and make the caller do the mapping?Should we subsume chunks of
map_gui
?Stepping back,
DrawMap
solves lots of these problems too. Should we try to subsume it?Things that're maybe different (but maybe not):
Delegation
We have a few places in the code where different logical components all shove their widgets in a single
Panel
, so we do scary dances to try to delegate outcomes. Will we have the same problems? Think about the route tool --InputWaypoints
is a common thing, living alongside the one-off alt route clickables.Prior art
Any good ideas from Leaflet, mapbox, other game engine APIs?