mirror of
https://github.com/RGBCube/serenity
synced 2025-07-08 16:47:34 +00:00
Maps: Add markers to map widget
This commit is contained in:
parent
599a37aa0c
commit
dfb54083ee
3 changed files with 61 additions and 4 deletions
BIN
Base/res/graphics/maps/marker-blue.png
Normal file
BIN
Base/res/graphics/maps/marker-blue.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 373 B |
|
@ -59,6 +59,7 @@ MapWidget::MapWidget(Options const& options)
|
||||||
m_request_client = Protocol::RequestClient::try_create().release_value_but_fixme_should_propagate_errors();
|
m_request_client = Protocol::RequestClient::try_create().release_value_but_fixme_should_propagate_errors();
|
||||||
if (options.attribution_enabled)
|
if (options.attribution_enabled)
|
||||||
add_panel({ options.attribution_text, Panel::Position::BottomRight, options.attribution_url, true });
|
add_panel({ options.attribution_text, Panel::Position::BottomRight, options.attribution_url, true });
|
||||||
|
m_marker_image = Gfx::Bitmap::load_from_file("/res/graphics/maps/marker-blue.png"sv).release_value_but_fixme_should_propagate_errors();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapWidget::set_zoom(int zoom)
|
void MapWidget::set_zoom(int zoom)
|
||||||
|
@ -114,6 +115,28 @@ void MapWidget::mousemove_event(GUI::MouseEvent& event)
|
||||||
if (panel.url.has_value() && panel.rect.contains(event.x(), event.y()))
|
if (panel.url.has_value() && panel.rect.contains(event.x(), event.y()))
|
||||||
return set_override_cursor(Gfx::StandardCursor::Hand);
|
return set_override_cursor(Gfx::StandardCursor::Hand);
|
||||||
set_override_cursor(Gfx::StandardCursor::Arrow);
|
set_override_cursor(Gfx::StandardCursor::Arrow);
|
||||||
|
|
||||||
|
// Handle marker tooltip hover
|
||||||
|
double center_tile_x = floor(longitude_to_tile_x(m_center.longitude, m_zoom));
|
||||||
|
double center_tile_y = floor(latitude_to_tile_y(m_center.latitude, m_zoom));
|
||||||
|
double offset_x = (longitude_to_tile_x(m_center.longitude, m_zoom) - center_tile_x) * TILE_SIZE;
|
||||||
|
double offset_y = (latitude_to_tile_y(m_center.latitude, m_zoom) - center_tile_y) * TILE_SIZE;
|
||||||
|
for (auto const& marker : m_markers) {
|
||||||
|
if (!marker.tooltip.has_value())
|
||||||
|
continue;
|
||||||
|
RefPtr<Gfx::Bitmap> marker_image = marker.image ? marker.image : m_marker_image;
|
||||||
|
Gfx::IntRect marker_rect = {
|
||||||
|
static_cast<int>(width() / 2 + (longitude_to_tile_x(marker.latlng.longitude, m_zoom) - center_tile_x) * TILE_SIZE - offset_x) - marker_image->width() / 2,
|
||||||
|
static_cast<int>(height() / 2 + (latitude_to_tile_y(marker.latlng.latitude, m_zoom) - center_tile_y) * TILE_SIZE - offset_y) - marker_image->height(),
|
||||||
|
marker_image->width(),
|
||||||
|
marker_image->height()
|
||||||
|
};
|
||||||
|
if (marker_rect.contains(event.x(), event.y())) {
|
||||||
|
GUI::Application::the()->show_tooltip(marker.tooltip.value().to_deprecated_string(), this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GUI::Application::the()->hide_tooltip();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapWidget::mouseup_event(GUI::MouseEvent& event)
|
void MapWidget::mouseup_event(GUI::MouseEvent& event)
|
||||||
|
@ -246,7 +269,7 @@ void MapWidget::clear_tile_queue()
|
||||||
m_tiles.remove_all_matching([](auto, auto const& value) -> bool { return !value; });
|
m_tiles.remove_all_matching([](auto, auto const& value) -> bool { return !value; });
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapWidget::paint_tiles(GUI::Painter& painter)
|
void MapWidget::paint_map(GUI::Painter& painter)
|
||||||
{
|
{
|
||||||
int center_tile_x = floor(longitude_to_tile_x(m_center.longitude, m_zoom));
|
int center_tile_x = floor(longitude_to_tile_x(m_center.longitude, m_zoom));
|
||||||
int center_tile_y = floor(latitude_to_tile_y(m_center.latitude, m_zoom));
|
int center_tile_y = floor(latitude_to_tile_y(m_center.latitude, m_zoom));
|
||||||
|
@ -323,6 +346,19 @@ void MapWidget::paint_tiles(GUI::Painter& painter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Draw markers
|
||||||
|
for (auto const& marker : m_markers) {
|
||||||
|
RefPtr<Gfx::Bitmap> marker_image = marker.image ? marker.image : m_marker_image;
|
||||||
|
Gfx::IntRect marker_rect = {
|
||||||
|
static_cast<int>(width() / 2 + (longitude_to_tile_x(marker.latlng.longitude, m_zoom) - center_tile_x) * TILE_SIZE - offset_x) - marker_image->width() / 2,
|
||||||
|
static_cast<int>(height() / 2 + (latitude_to_tile_y(marker.latlng.latitude, m_zoom) - center_tile_y) * TILE_SIZE - offset_y) - marker_image->height(),
|
||||||
|
marker_image->width(),
|
||||||
|
marker_image->height()
|
||||||
|
};
|
||||||
|
if (marker_rect.intersects(frame_inner_rect()))
|
||||||
|
painter.blit(marker_rect.location(), *marker_image, { 0, 0, marker_image->width(), marker_image->height() }, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapWidget::paint_scale_line(GUI::Painter& painter, String label, Gfx::IntRect rect)
|
void MapWidget::paint_scale_line(GUI::Painter& painter, String label, Gfx::IntRect rect)
|
||||||
|
@ -400,7 +436,7 @@ void MapWidget::paint_event(GUI::PaintEvent& event)
|
||||||
if (m_connection_failed)
|
if (m_connection_failed)
|
||||||
return painter.draw_text(frame_inner_rect(), "Failed to fetch map tiles :^("sv, Gfx::TextAlignment::Center, panel_foreground_color);
|
return painter.draw_text(frame_inner_rect(), "Failed to fetch map tiles :^("sv, Gfx::TextAlignment::Center, panel_foreground_color);
|
||||||
|
|
||||||
paint_tiles(painter);
|
paint_map(painter);
|
||||||
if (m_scale_enabled)
|
if (m_scale_enabled)
|
||||||
paint_scale(painter);
|
paint_scale(painter);
|
||||||
paint_panels(painter);
|
paint_panels(painter);
|
||||||
|
|
|
@ -48,6 +48,22 @@ public:
|
||||||
int zoom() const { return m_zoom; }
|
int zoom() const { return m_zoom; }
|
||||||
void set_zoom(int zoom);
|
void set_zoom(int zoom);
|
||||||
|
|
||||||
|
struct Marker {
|
||||||
|
LatLng latlng;
|
||||||
|
Optional<String> tooltip {};
|
||||||
|
RefPtr<Gfx::Bitmap> image { nullptr };
|
||||||
|
};
|
||||||
|
void add_marker(Marker const& marker)
|
||||||
|
{
|
||||||
|
m_markers.append(marker);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
void clear_markers()
|
||||||
|
{
|
||||||
|
m_markers.clear();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
struct Panel {
|
struct Panel {
|
||||||
enum class Position {
|
enum class Position {
|
||||||
TopLeft,
|
TopLeft,
|
||||||
|
@ -93,9 +109,12 @@ public:
|
||||||
Download,
|
Download,
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
MapWidget(Options const&);
|
MapWidget(Options const&);
|
||||||
|
|
||||||
|
RefPtr<Protocol::RequestClient> request_client() const { return m_request_client; }
|
||||||
|
|
||||||
|
private:
|
||||||
virtual void doubleclick_event(GUI::MouseEvent&) override;
|
virtual void doubleclick_event(GUI::MouseEvent&) override;
|
||||||
virtual void mousemove_event(GUI::MouseEvent&) override;
|
virtual void mousemove_event(GUI::MouseEvent&) override;
|
||||||
virtual void mousedown_event(GUI::MouseEvent&) override;
|
virtual void mousedown_event(GUI::MouseEvent&) override;
|
||||||
|
@ -109,7 +128,7 @@ private:
|
||||||
void process_tile_queue();
|
void process_tile_queue();
|
||||||
void clear_tile_queue();
|
void clear_tile_queue();
|
||||||
|
|
||||||
void paint_tiles(GUI::Painter&);
|
void paint_map(GUI::Painter&);
|
||||||
void paint_scale_line(GUI::Painter&, String label, Gfx::IntRect rect);
|
void paint_scale_line(GUI::Painter&, String label, Gfx::IntRect rect);
|
||||||
void paint_scale(GUI::Painter&);
|
void paint_scale(GUI::Painter&);
|
||||||
void paint_panels(GUI::Painter&);
|
void paint_panels(GUI::Painter&);
|
||||||
|
@ -131,6 +150,7 @@ private:
|
||||||
RefPtr<Protocol::RequestClient> m_request_client;
|
RefPtr<Protocol::RequestClient> m_request_client;
|
||||||
Vector<RefPtr<Protocol::Request>, TILES_DOWNLOAD_PARALLEL_MAX> m_active_requests;
|
Vector<RefPtr<Protocol::Request>, TILES_DOWNLOAD_PARALLEL_MAX> m_active_requests;
|
||||||
Queue<TileKey, 32> m_tile_queue;
|
Queue<TileKey, 32> m_tile_queue;
|
||||||
|
RefPtr<Gfx::Bitmap> m_marker_image;
|
||||||
String m_tile_layer_url;
|
String m_tile_layer_url;
|
||||||
LatLng m_center;
|
LatLng m_center;
|
||||||
int m_zoom {};
|
int m_zoom {};
|
||||||
|
@ -144,6 +164,7 @@ private:
|
||||||
bool m_first_image_loaded { false };
|
bool m_first_image_loaded { false };
|
||||||
bool m_connection_failed { false };
|
bool m_connection_failed { false };
|
||||||
OrderedHashMap<TileKey, RefPtr<Gfx::Bitmap>> m_tiles;
|
OrderedHashMap<TileKey, RefPtr<Gfx::Bitmap>> m_tiles;
|
||||||
|
Vector<Marker> m_markers;
|
||||||
Vector<Panel> m_panels;
|
Vector<Panel> m_panels;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue