Maps · View: host tiles, pins and a popup, a picker, coordinates
maps::MapView lays the host's tile for each zoom, column and row in Web Mercator, the nearest cut scaled past the zooms it serves, on whole pixels. gpui packs pictures in its atlas without padding and samples them linearly, so each tile draws with a one-pixel rim copied from its own edge, one of its pixels larger each side and clipped, and no seam shows. A drag, the wheel or the arrows pan; Command-wheel, + and - or its buttons zoom about the pointer or the center; the owner keeps the viewport. MapMarker pins take a press and Enter when the map hears them; MapPopup opens toward the map's larger half and stays inside it, closing by its button or Escape. LocationPicker picks the place under a center crosshair; CoordinateDisplay writes degrees or degrees, minutes and seconds with tabular figures and a copy button. The gallery's tiles are Natural Earth's countries, cut z0 to z3 by scripts/tiles.py.
No files matched your search
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 9.1 KiB |
|
After Width: | Height: | Size: 230 B |
|
After Width: | Height: | Size: 7.0 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 9.7 KiB |
|
After Width: | Height: | Size: 9.2 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 7.9 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 6.5 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 4.8 KiB |
|
After Width: | Height: | Size: 206 B |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 7.6 KiB |
|
After Width: | Height: | Size: 678 B |
|
After Width: | Height: | Size: 256 B |
|
After Width: | Height: | Size: 206 B |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 6.1 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 5.3 KiB |
|
After Width: | Height: | Size: 7.0 KiB |
|
After Width: | Height: | Size: 206 B |
|
After Width: | Height: | Size: 206 B |
|
After Width: | Height: | Size: 5.3 KiB |
|
After Width: | Height: | Size: 513 B |
|
After Width: | Height: | Size: 7.8 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 7.0 KiB |
|
After Width: | Height: | Size: 7.7 KiB |
|
After Width: | Height: | Size: 5.8 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 7.7 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 206 B |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 7.5 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 206 B |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 513 B |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 9.3 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 513 B |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 7.2 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 9.4 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 513 B |
|
After Width: | Height: | Size: 206 B |
|
After Width: | Height: | Size: 5.7 KiB |
|
After Width: | Height: | Size: 9.5 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 4.5 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
@@ -0,0 +1,150 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use ely_gpui_component::{
|
||||
maps::{
|
||||
CoordFormat, CoordinateDisplay, LatLon, LocationPicker, MapMarker, MapPopup, MapView,
|
||||
MapViewport, Tile,
|
||||
},
|
||||
theme::ActiveTheme,
|
||||
};
|
||||
use gpui::{
|
||||
AnyElement, App, ImageSource, IntoElement, ParentElement, SharedString, Styled, Window, div, px,
|
||||
};
|
||||
|
||||
use super::Page;
|
||||
use crate::probe::probe;
|
||||
use crate::script::Step;
|
||||
use crate::ui::{keep, section, set, specimen, specimens};
|
||||
|
||||
pub const PAGE: Page = Page {
|
||||
number: 41,
|
||||
slug: "maps",
|
||||
title: "Maps",
|
||||
summary: "Tiles the host supplies, pins with a popup, a picker's crosshair. The land is Natural Earth's.",
|
||||
render,
|
||||
script: &[
|
||||
Step::Click("world-map"),
|
||||
Step::Key("tab"),
|
||||
Step::Key("enter"),
|
||||
Step::Wait(300),
|
||||
Step::Shot("popup"),
|
||||
Step::Key("escape"),
|
||||
Step::Key("="),
|
||||
Step::Wait(300),
|
||||
Step::Shot("zoomed"),
|
||||
Step::Click("picker"),
|
||||
Step::Key("right"),
|
||||
Step::Key("down"),
|
||||
Step::Wait(300),
|
||||
Step::Shot("picked"),
|
||||
],
|
||||
};
|
||||
|
||||
const TILES: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/examples/gallery/assets/tiles");
|
||||
const ATTRIBUTION: &str = "Land: Natural Earth";
|
||||
|
||||
const CITIES: [(&str, &str, f64, f64, usize); 6] = [
|
||||
("london", "London", 51.5072, -0.1276, 0),
|
||||
("new-york", "New York", 40.7128, -74.006, 3),
|
||||
("sao-paulo", "São Paulo", -23.5505, -46.6333, 5),
|
||||
("cape-town", "Cape Town", -33.9249, 18.4241, 2),
|
||||
("tokyo", "Tokyo", 35.6762, 139.6503, 4),
|
||||
("sydney", "Sydney", -33.8688, 151.2093, 1),
|
||||
];
|
||||
|
||||
/// The gallery's tiles, cut from Natural Earth by `scripts/tiles.py`.
|
||||
fn tile(tile: Tile) -> ImageSource {
|
||||
PathBuf::from(format!("{TILES}/{}/{}/{}.png", tile.z, tile.x, tile.y)).into()
|
||||
}
|
||||
|
||||
fn render(window: &mut Window, cx: &mut App) -> AnyElement {
|
||||
div()
|
||||
.child(world(window, cx))
|
||||
.child(coordinates(cx))
|
||||
.child(picker(cx))
|
||||
.into_any_element()
|
||||
}
|
||||
|
||||
fn world(window: &mut Window, cx: &mut App) -> impl IntoElement + use<> {
|
||||
let open = keep("map-open", || None::<SharedString>, window, cx);
|
||||
let shown = open.read(cx).clone();
|
||||
let markers = CITIES.map(|(key, name, lat, lon, hue)| {
|
||||
MapMarker::new(key, LatLon::new(lat, lon))
|
||||
.label(name)
|
||||
.hue(hue)
|
||||
});
|
||||
let popup = shown.as_ref().map(|key| {
|
||||
let (_, name, lat, lon, _) = *CITIES
|
||||
.iter()
|
||||
.find(|(each, ..)| *each == key.as_ref())
|
||||
.expect("a listed city");
|
||||
let closed = open.clone();
|
||||
MapPopup::new(LatLon::new(lat, lon), name)
|
||||
.child(
|
||||
CoordinateDisplay::new("map-popup-place", LatLon::new(lat, lon))
|
||||
.format(CoordFormat::Dms),
|
||||
)
|
||||
.on_close(move |_, cx| set(&closed, None, cx))
|
||||
});
|
||||
let map = MapView::new("world-map", MapViewport::new(LatLon::new(20.0, 10.0), 1.2))
|
||||
.tiles(tile)
|
||||
.tile_zooms(0, 3)
|
||||
.attribution(ATTRIBUTION)
|
||||
.markers(markers)
|
||||
.on_marker(move |key, _, cx| set(&open, Some(key.clone()), cx));
|
||||
let map = match popup {
|
||||
Some(popup) => map.popup(popup),
|
||||
None => map,
|
||||
};
|
||||
section(
|
||||
"MapView · MapMarker · MapPopup",
|
||||
"Tiles come from the host by zoom, column and row; past the zooms it cuts, the nearest scales. Drag or scroll to pan, Command-scroll or the buttons to zoom; focused, the arrows pan and + and - zoom. A pin opens its popup; Escape closes it.",
|
||||
cx,
|
||||
)
|
||||
.child(probe("world-map", div().w(px(720.0)).h(px(360.0)).child(map)))
|
||||
}
|
||||
|
||||
fn coordinates(cx: &App) -> impl IntoElement + use<> {
|
||||
let place = LatLon::new(-33.9249, 18.4241);
|
||||
section(
|
||||
"CoordinateDisplay",
|
||||
"A place in degrees or in degrees, minutes and seconds, with its hemispheres; figures keep one width, and the button copies it.",
|
||||
cx,
|
||||
)
|
||||
.child(
|
||||
specimens()
|
||||
.child(specimen("decimal", CoordinateDisplay::new("coords-decimal", place), cx))
|
||||
.child(specimen(
|
||||
"degrees, minutes, seconds",
|
||||
CoordinateDisplay::new("coords-dms", place).format(CoordFormat::Dms),
|
||||
cx,
|
||||
)),
|
||||
)
|
||||
}
|
||||
|
||||
fn picker(cx: &App) -> impl IntoElement + use<> {
|
||||
let muted = cx.theme().colors.fg_muted;
|
||||
let map = MapView::new(
|
||||
"picker-map",
|
||||
MapViewport::new(LatLon::new(48.8566, 2.3522), 3.0),
|
||||
)
|
||||
.tiles(tile)
|
||||
.tile_zooms(0, 3)
|
||||
.attribution(ATTRIBUTION);
|
||||
section(
|
||||
"LocationPicker",
|
||||
"The place under the crosshair is the pick: pan by pointer or keys, and the owner hears each move.",
|
||||
cx,
|
||||
)
|
||||
.child(
|
||||
probe(
|
||||
"picker",
|
||||
div().w(px(480.0)).h(px(320.0)).child(
|
||||
LocationPicker::new("picker", map)
|
||||
.format(CoordFormat::Dms)
|
||||
.on_pick(|at, _, _| log::info!("maps demo: picked {:.4}, {:.4}", at.lat, at.lon)),
|
||||
),
|
||||
),
|
||||
)
|
||||
.child(div().text_color(muted).child("The pick reaches the owner as it moves; the log shows it."))
|
||||
}
|
||||
@@ -23,6 +23,7 @@ mod interaction;
|
||||
mod layout;
|
||||
mod lists;
|
||||
mod mail;
|
||||
mod maps;
|
||||
mod media;
|
||||
mod menus;
|
||||
mod messaging;
|
||||
@@ -94,6 +95,7 @@ pub const ALL: &[Page] = &[
|
||||
interaction::PAGE,
|
||||
theme::PAGE,
|
||||
i18n::PAGE,
|
||||
maps::PAGE,
|
||||
];
|
||||
|
||||
pub use i18n::install as install_i18n;
|
||||
|
||||