From dfb54083ee5e595f856a861d2f3475aaf722653c Mon Sep 17 00:00:00 2001 From: Bastiaan van der Plaat Date: Tue, 5 Sep 2023 19:24:39 +0200 Subject: [PATCH] Maps: Add markers to map widget --- Base/res/graphics/maps/marker-blue.png | Bin 0 -> 373 bytes Userland/Applications/Maps/MapWidget.cpp | 40 +++++++++++++++++++++-- Userland/Applications/Maps/MapWidget.h | 25 ++++++++++++-- 3 files changed, 61 insertions(+), 4 deletions(-) create mode 100644 Base/res/graphics/maps/marker-blue.png diff --git a/Base/res/graphics/maps/marker-blue.png b/Base/res/graphics/maps/marker-blue.png new file mode 100644 index 0000000000000000000000000000000000000000..822042fbd6d9a3b47505ff8afefb6723f2d64e62 GIT binary patch literal 373 zcmV-*0gC>KP)KeoO{)Cr?B;igw_^19zmrL zN)Mp%Af7;}l89C%(NGAb)r=`LD|Y8jBFK_C>?!u^{^$Gz(4jrxg}wXRT_B(b$As(FWz*Ht5Q%qq-&?vWCFhqSp^D2`u@VYtlU9k-JZVUkCS(ITNQyTDG>at| zkg|5j4SFqIj&GDZAHRb%&hZ7-G9_&jryxn-B5QvF0yaha21rn&Jm*q688;|3mMHwG zM`qR^g5uk1P#9(SrvR}vdj%XjMR8mMkvaZy>ey)j_`G@q2mNTaxQ0mvSZw|Pp>JBQ T=)lw?00000NkvXXu0mjf(dL{X literal 0 HcmV?d00001 diff --git a/Userland/Applications/Maps/MapWidget.cpp b/Userland/Applications/Maps/MapWidget.cpp index 56153353c1..3ae2b8911a 100644 --- a/Userland/Applications/Maps/MapWidget.cpp +++ b/Userland/Applications/Maps/MapWidget.cpp @@ -59,6 +59,7 @@ MapWidget::MapWidget(Options const& options) m_request_client = Protocol::RequestClient::try_create().release_value_but_fixme_should_propagate_errors(); if (options.attribution_enabled) 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) @@ -114,6 +115,28 @@ void MapWidget::mousemove_event(GUI::MouseEvent& event) if (panel.url.has_value() && panel.rect.contains(event.x(), event.y())) return set_override_cursor(Gfx::StandardCursor::Hand); 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 marker_image = marker.image ? marker.image : m_marker_image; + Gfx::IntRect marker_rect = { + static_cast(width() / 2 + (longitude_to_tile_x(marker.latlng.longitude, m_zoom) - center_tile_x) * TILE_SIZE - offset_x) - marker_image->width() / 2, + static_cast(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) @@ -246,7 +269,7 @@ void MapWidget::clear_tile_queue() 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_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 marker_image = marker.image ? marker.image : m_marker_image; + Gfx::IntRect marker_rect = { + static_cast(width() / 2 + (longitude_to_tile_x(marker.latlng.longitude, m_zoom) - center_tile_x) * TILE_SIZE - offset_x) - marker_image->width() / 2, + static_cast(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) @@ -400,7 +436,7 @@ void MapWidget::paint_event(GUI::PaintEvent& event) if (m_connection_failed) 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) paint_scale(painter); paint_panels(painter); diff --git a/Userland/Applications/Maps/MapWidget.h b/Userland/Applications/Maps/MapWidget.h index 260215e890..285568fbdd 100644 --- a/Userland/Applications/Maps/MapWidget.h +++ b/Userland/Applications/Maps/MapWidget.h @@ -48,6 +48,22 @@ public: int zoom() const { return m_zoom; } void set_zoom(int zoom); + struct Marker { + LatLng latlng; + Optional tooltip {}; + RefPtr image { nullptr }; + }; + void add_marker(Marker const& marker) + { + m_markers.append(marker); + update(); + } + void clear_markers() + { + m_markers.clear(); + update(); + } + struct Panel { enum class Position { TopLeft, @@ -93,9 +109,12 @@ public: Download, }; -private: +protected: MapWidget(Options const&); + RefPtr request_client() const { return m_request_client; } + +private: virtual void doubleclick_event(GUI::MouseEvent&) override; virtual void mousemove_event(GUI::MouseEvent&) override; virtual void mousedown_event(GUI::MouseEvent&) override; @@ -109,7 +128,7 @@ private: void process_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(GUI::Painter&); void paint_panels(GUI::Painter&); @@ -131,6 +150,7 @@ private: RefPtr m_request_client; Vector, TILES_DOWNLOAD_PARALLEL_MAX> m_active_requests; Queue m_tile_queue; + RefPtr m_marker_image; String m_tile_layer_url; LatLng m_center; int m_zoom {}; @@ -144,6 +164,7 @@ private: bool m_first_image_loaded { false }; bool m_connection_failed { false }; OrderedHashMap> m_tiles; + Vector m_markers; Vector m_panels; };