mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 13:18:13 +00:00
Maps: Add MapsSettings with multiple tile providers options
This commit is contained in:
parent
264782557e
commit
aed25991e6
14 changed files with 379 additions and 15 deletions
32
Base/home/anon/.config/MapsTileProviders.json
Normal file
32
Base/home/anon/.config/MapsTileProviders.json
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "OpenStreetMap (Local labels)",
|
||||||
|
"url_format": "https://tile.openstreetmap.org/{}/{}/{}.png",
|
||||||
|
"attribution_text": "© OpenStreetMap contributors",
|
||||||
|
"attribution_url": "https://www.openstreetmap.org/copyright"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "OpenStreetMap (German labels)",
|
||||||
|
"url_format": "https://tile.openstreetmap.de/{}/{}/{}.png",
|
||||||
|
"attribution_text": "© OpenStreetMap contributors",
|
||||||
|
"attribution_url": "https://www.openstreetmap.org/copyright"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "OpenStreetMap (French labels)",
|
||||||
|
"url_format": "https://a.tile.openstreetmap.fr/osmfr/{}/{}/{}.png",
|
||||||
|
"attribution_text": "© OpenStreetMap contributors",
|
||||||
|
"attribution_url": "https://www.openstreetmap.fr/copyright"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "OpenStreetMap (Humanitarian map style)",
|
||||||
|
"url_format": "https://a.tile.openstreetmap.fr/hot/{}/{}/{}.png",
|
||||||
|
"attribution_text": "© OpenStreetMap contributors",
|
||||||
|
"attribution_url": "https://www.openstreetmap.fr/copyright"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "OpenStreetMap (Topographical map style)",
|
||||||
|
"url_format": "https://a.tile.opentopomap.org/{}/{}/{}.png",
|
||||||
|
"attribution_text": "© OpenStreetMap contributors",
|
||||||
|
"attribution_url": "https://www.opentopomap.org/credits"
|
||||||
|
}
|
||||||
|
]
|
6
Base/res/apps/MapsSettings.af
Normal file
6
Base/res/apps/MapsSettings.af
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
[App]
|
||||||
|
Name=Maps Settings
|
||||||
|
Executable=/bin/MapsSettings
|
||||||
|
Category=Settings
|
||||||
|
Description=Configure the Maps application
|
||||||
|
ExcludeFromSystemMenu=true
|
|
@ -26,6 +26,7 @@ add_subdirectory(Magnifier)
|
||||||
add_subdirectory(Mail)
|
add_subdirectory(Mail)
|
||||||
add_subdirectory(MailSettings)
|
add_subdirectory(MailSettings)
|
||||||
add_subdirectory(Maps)
|
add_subdirectory(Maps)
|
||||||
|
add_subdirectory(MapsSettings)
|
||||||
add_subdirectory(MouseSettings)
|
add_subdirectory(MouseSettings)
|
||||||
add_subdirectory(NetworkSettings)
|
add_subdirectory(NetworkSettings)
|
||||||
add_subdirectory(PartitionEditor)
|
add_subdirectory(PartitionEditor)
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
|
|
||||||
#include "MapWidget.h"
|
#include "MapWidget.h"
|
||||||
#include <AK/URL.h>
|
#include <AK/URL.h>
|
||||||
|
#include <Applications/MapsSettings/Defaults.h>
|
||||||
|
#include <LibConfig/Client.h>
|
||||||
#include <LibDesktop/Launcher.h>
|
#include <LibDesktop/Launcher.h>
|
||||||
#include <LibGUI/Action.h>
|
#include <LibGUI/Action.h>
|
||||||
#include <LibGUI/Application.h>
|
#include <LibGUI/Application.h>
|
||||||
|
@ -51,7 +53,7 @@ double MapWidget::LatLng::distance_to(LatLng const& other) const
|
||||||
|
|
||||||
// MapWidget class
|
// MapWidget class
|
||||||
MapWidget::MapWidget(Options const& options)
|
MapWidget::MapWidget(Options const& options)
|
||||||
: m_tile_layer_url(options.tile_layer_url)
|
: m_tile_provider(options.tile_provider)
|
||||||
, m_center(options.center)
|
, m_center(options.center)
|
||||||
, m_zoom(options.zoom)
|
, m_zoom(options.zoom)
|
||||||
, m_context_menu_enabled(options.context_menu_enabled)
|
, m_context_menu_enabled(options.context_menu_enabled)
|
||||||
|
@ -60,9 +62,13 @@ MapWidget::MapWidget(Options const& options)
|
||||||
, m_attribution_enabled(options.attribution_enabled)
|
, m_attribution_enabled(options.attribution_enabled)
|
||||||
{
|
{
|
||||||
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 });
|
auto attribution_text = options.attribution_text.value_or(MUST(String::from_deprecated_string(Config::read_string("Maps"sv, "MapWidget"sv, "TileProviderAttributionText"sv, Maps::default_tile_provider_attribution_text))));
|
||||||
|
URL attribution_url = options.attribution_url.value_or(URL(Config::read_string("Maps"sv, "MapWidget"sv, "TileProviderAttributionUrl"sv, Maps::default_tile_provider_attribution_url)));
|
||||||
|
add_panel({ attribution_text, Panel::Position::BottomRight, attribution_url, "attribution"_string });
|
||||||
|
}
|
||||||
m_marker_image = Gfx::Bitmap::load_from_file("/res/graphics/maps/marker-blue.png"sv).release_value_but_fixme_should_propagate_errors();
|
m_marker_image = Gfx::Bitmap::load_from_file("/res/graphics/maps/marker-blue.png"sv).release_value_but_fixme_should_propagate_errors();
|
||||||
|
m_default_tile_provider = MUST(String::from_deprecated_string(Config::read_string("Maps"sv, "MapWidget"sv, "TileProviderUrlFormat"sv, Maps::default_tile_provider_url_format)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapWidget::set_zoom(int zoom)
|
void MapWidget::set_zoom(int zoom)
|
||||||
|
@ -72,6 +78,42 @@ void MapWidget::set_zoom(int zoom)
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MapWidget::config_string_did_change(StringView domain, StringView group, StringView key, StringView value)
|
||||||
|
{
|
||||||
|
if (domain != "Maps" || group != "MapWidget")
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (key == "TileProviderUrlFormat") {
|
||||||
|
// When config tile provider changes clear all active requests and loaded tiles
|
||||||
|
m_default_tile_provider = MUST(String::from_utf8(value));
|
||||||
|
m_first_image_loaded = false;
|
||||||
|
m_active_requests.clear();
|
||||||
|
m_tiles.clear();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key == "TileProviderAttributionText") {
|
||||||
|
// Update attribution panel text when it exists
|
||||||
|
for (auto& panel : m_panels) {
|
||||||
|
if (panel.name == "attribution") {
|
||||||
|
panel.text = MUST(String::from_utf8(value));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key == "TileProviderAttributionUrl") {
|
||||||
|
// Update attribution panel url when it exists
|
||||||
|
for (auto& panel : m_panels) {
|
||||||
|
if (panel.name == "attribution") {
|
||||||
|
panel.url = URL(value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void MapWidget::doubleclick_event(GUI::MouseEvent& event)
|
void MapWidget::doubleclick_event(GUI::MouseEvent& event)
|
||||||
{
|
{
|
||||||
int new_zoom = event.shift() ? m_zoom - 1 : m_zoom + 1;
|
int new_zoom = event.shift() ? m_zoom - 1 : m_zoom + 1;
|
||||||
|
@ -261,7 +303,7 @@ void MapWidget::process_tile_queue()
|
||||||
HashMap<DeprecatedString, DeprecatedString> headers;
|
HashMap<DeprecatedString, DeprecatedString> headers;
|
||||||
headers.set("User-Agent", "SerenityOS Maps");
|
headers.set("User-Agent", "SerenityOS Maps");
|
||||||
headers.set("Accept", "image/png");
|
headers.set("Accept", "image/png");
|
||||||
URL url(MUST(String::formatted(m_tile_layer_url, tile_key.zoom, tile_key.x, tile_key.y)));
|
URL url(MUST(String::formatted(m_tile_provider.value_or(m_default_tile_provider), tile_key.zoom, tile_key.x, tile_key.y)));
|
||||||
auto request = m_request_client->start_request("GET", url, headers, {});
|
auto request = m_request_client->start_request("GET", url, headers, {});
|
||||||
VERIFY(!request.is_null());
|
VERIFY(!request.is_null());
|
||||||
|
|
||||||
|
|
|
@ -8,13 +8,15 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <AK/Queue.h>
|
#include <AK/Queue.h>
|
||||||
|
#include <LibConfig/Listener.h>
|
||||||
#include <LibGUI/Frame.h>
|
#include <LibGUI/Frame.h>
|
||||||
#include <LibGUI/Menu.h>
|
#include <LibGUI/Menu.h>
|
||||||
#include <LibGUI/Painter.h>
|
#include <LibGUI/Painter.h>
|
||||||
#include <LibProtocol/Request.h>
|
#include <LibProtocol/Request.h>
|
||||||
#include <LibProtocol/RequestClient.h>
|
#include <LibProtocol/RequestClient.h>
|
||||||
|
|
||||||
class MapWidget : public GUI::Frame {
|
class MapWidget : public GUI::Frame
|
||||||
|
, public Config::Listener {
|
||||||
C_OBJECT(MapWidget);
|
C_OBJECT(MapWidget);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -26,15 +28,15 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Options {
|
struct Options {
|
||||||
String tile_layer_url { "https://tile.openstreetmap.org/{}/{}/{}.png"_string };
|
Optional<String> tile_provider {};
|
||||||
LatLng center;
|
LatLng center;
|
||||||
int zoom;
|
int zoom;
|
||||||
bool context_menu_enabled { true };
|
bool context_menu_enabled { true };
|
||||||
bool scale_enabled { true };
|
bool scale_enabled { true };
|
||||||
int scale_max_width { 100 };
|
int scale_max_width { 100 };
|
||||||
bool attribution_enabled { true };
|
bool attribution_enabled { true };
|
||||||
String attribution_text { "© OpenStreetMap contributors"_string };
|
Optional<String> attribution_text {};
|
||||||
URL attribution_url { "https://www.openstreetmap.org/copyright"sv };
|
Optional<URL> attribution_url {};
|
||||||
};
|
};
|
||||||
|
|
||||||
LatLng center() const { return m_center; }
|
LatLng center() const { return m_center; }
|
||||||
|
@ -76,7 +78,7 @@ public:
|
||||||
String text;
|
String text;
|
||||||
Position position;
|
Position position;
|
||||||
Optional<URL> url {};
|
Optional<URL> url {};
|
||||||
bool persistent { false };
|
Optional<String> name {};
|
||||||
Gfx::IntRect rect { 0, 0, 0, 0 };
|
Gfx::IntRect rect { 0, 0, 0, 0 };
|
||||||
};
|
};
|
||||||
void add_panel(Panel const& panel)
|
void add_panel(Panel const& panel)
|
||||||
|
@ -84,9 +86,9 @@ public:
|
||||||
m_panels.append(panel);
|
m_panels.append(panel);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
void clear_panels()
|
void remove_panels_with_name(StringView name)
|
||||||
{
|
{
|
||||||
m_panels.remove_all_matching([](auto const& panel) { return !panel.persistent; });
|
m_panels.remove_all_matching([name](auto const& panel) { return panel.name == name; });
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,6 +119,7 @@ protected:
|
||||||
RefPtr<Protocol::RequestClient> request_client() const { return m_request_client; }
|
RefPtr<Protocol::RequestClient> request_client() const { return m_request_client; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
virtual void config_string_did_change(StringView domain, StringView group, StringView key, StringView value) override;
|
||||||
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;
|
||||||
|
@ -154,7 +157,8 @@ private:
|
||||||
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;
|
RefPtr<Gfx::Bitmap> m_marker_image;
|
||||||
String m_tile_layer_url;
|
Optional<String> m_tile_provider;
|
||||||
|
String m_default_tile_provider;
|
||||||
LatLng m_center;
|
LatLng m_center;
|
||||||
int m_zoom {};
|
int m_zoom {};
|
||||||
bool m_context_menu_enabled {};
|
bool m_context_menu_enabled {};
|
||||||
|
|
|
@ -73,5 +73,6 @@ void UsersMapWidget::add_users_to_map()
|
||||||
|
|
||||||
add_panel({ MUST(String::formatted("{} users are already registered", m_users.value().size())),
|
add_panel({ MUST(String::formatted("{} users are already registered", m_users.value().size())),
|
||||||
Panel::Position::TopRight,
|
Panel::Position::TopRight,
|
||||||
{ { "https://github.com/SerenityOS/user-map" } } });
|
{ { "https://github.com/SerenityOS/user-map" } },
|
||||||
|
"users"_string });
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ public:
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
clear_markers();
|
clear_markers();
|
||||||
clear_panels();
|
remove_panels_with_name("users"sv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <LibGUI/BoxLayout.h>
|
#include <LibGUI/BoxLayout.h>
|
||||||
#include <LibGUI/Icon.h>
|
#include <LibGUI/Icon.h>
|
||||||
#include <LibGUI/Menu.h>
|
#include <LibGUI/Menu.h>
|
||||||
|
#include <LibGUI/Process.h>
|
||||||
#include <LibGUI/ToolbarContainer.h>
|
#include <LibGUI/ToolbarContainer.h>
|
||||||
#include <LibGUI/Window.h>
|
#include <LibGUI/Window.h>
|
||||||
|
|
||||||
|
@ -19,16 +20,19 @@ static int constexpr MAP_ZOOM_DEFAULT = 3;
|
||||||
|
|
||||||
ErrorOr<int> serenity_main(Main::Arguments arguments)
|
ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
{
|
{
|
||||||
TRY(Core::System::pledge("stdio recvfd sendfd rpath unix"));
|
TRY(Core::System::pledge("stdio recvfd sendfd rpath unix proc exec"));
|
||||||
|
|
||||||
auto app = TRY(GUI::Application::create(arguments));
|
auto app = TRY(GUI::Application::create(arguments));
|
||||||
|
|
||||||
|
TRY(Core::System::unveil("/bin/MapsSettings", "x"));
|
||||||
TRY(Core::System::unveil("/res", "r"));
|
TRY(Core::System::unveil("/res", "r"));
|
||||||
TRY(Core::System::unveil("/tmp/session/%sid/portal/config", "rw"));
|
TRY(Core::System::unveil("/tmp/session/%sid/portal/config", "rw"));
|
||||||
TRY(Core::System::unveil("/tmp/session/%sid/portal/launch", "rw"));
|
TRY(Core::System::unveil("/tmp/session/%sid/portal/launch", "rw"));
|
||||||
TRY(Core::System::unveil("/tmp/session/%sid/portal/request", "rw"));
|
TRY(Core::System::unveil("/tmp/session/%sid/portal/request", "rw"));
|
||||||
TRY(Core::System::unveil(nullptr, nullptr));
|
TRY(Core::System::unveil(nullptr, nullptr));
|
||||||
|
|
||||||
|
Config::monitor_domain("Maps");
|
||||||
|
|
||||||
auto app_icon = TRY(GUI::Icon::try_create_default_icon("app-maps"sv));
|
auto app_icon = TRY(GUI::Icon::try_create_default_icon("app-maps"sv));
|
||||||
auto window = GUI::Window::construct();
|
auto window = GUI::Window::construct();
|
||||||
window->set_title("Maps");
|
window->set_title("Maps");
|
||||||
|
@ -56,6 +60,11 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
|
|
||||||
// Main menu actions
|
// Main menu actions
|
||||||
auto file_menu = window->add_menu("&File"_string);
|
auto file_menu = window->add_menu("&File"_string);
|
||||||
|
auto open_settings_action = GUI::Action::create("Maps &Settings", { Mod_Ctrl, Key_Comma }, TRY(Gfx::Bitmap::load_from_file("/res/icons/16x16/app-settings.png"sv)), [window](GUI::Action const&) {
|
||||||
|
GUI::Process::spawn_or_show_error(window, "/bin/MapsSettings"sv);
|
||||||
|
});
|
||||||
|
file_menu->add_action(open_settings_action);
|
||||||
|
file_menu->add_separator();
|
||||||
file_menu->add_action(GUI::CommonActions::make_quit_action([](auto&) { GUI::Application::the()->quit(); }));
|
file_menu->add_action(GUI::CommonActions::make_quit_action([](auto&) { GUI::Application::the()->quit(); }));
|
||||||
|
|
||||||
auto view_menu = window->add_menu("&View"_string);
|
auto view_menu = window->add_menu("&View"_string);
|
||||||
|
@ -89,6 +98,8 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
toolbar->add_action(zoom_in_action);
|
toolbar->add_action(zoom_in_action);
|
||||||
toolbar->add_action(zoom_out_action);
|
toolbar->add_action(zoom_out_action);
|
||||||
toolbar->add_action(reset_zoom_action);
|
toolbar->add_action(reset_zoom_action);
|
||||||
|
toolbar->add_separator();
|
||||||
|
toolbar->add_action(open_settings_action);
|
||||||
|
|
||||||
window->show();
|
window->show();
|
||||||
|
|
||||||
|
|
16
Userland/Applications/MapsSettings/CMakeLists.txt
Normal file
16
Userland/Applications/MapsSettings/CMakeLists.txt
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
serenity_component(
|
||||||
|
MapsSettings
|
||||||
|
RECOMMENDED
|
||||||
|
TARGETS MapsSettings
|
||||||
|
)
|
||||||
|
|
||||||
|
compile_gml(MapsSettingsWidget.gml MapsSettingsWidgetGML.cpp)
|
||||||
|
|
||||||
|
set(SOURCES
|
||||||
|
main.cpp
|
||||||
|
MapsSettingsWidgetGML.cpp
|
||||||
|
MapsSettingsWidget.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
serenity_app(MapsSettings ICON app-maps)
|
||||||
|
target_link_libraries(MapsSettings PRIVATE LibConfig LibCore LibGfx LibGUI LibMain)
|
17
Userland/Applications/MapsSettings/Defaults.h
Normal file
17
Userland/Applications/MapsSettings/Defaults.h
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023, Bastiaan van der Plaat <bastiaan.v.d.plaat@gmail.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <AK/StringView.h>
|
||||||
|
|
||||||
|
namespace Maps {
|
||||||
|
|
||||||
|
static constexpr StringView default_tile_provider_url_format = "https://tile.openstreetmap.org/{}/{}/{}.png"sv;
|
||||||
|
static constexpr StringView default_tile_provider_attribution_text = "© OpenStreetMap contributors"sv;
|
||||||
|
static constexpr StringView default_tile_provider_attribution_url = "https://www.openstreetmap.org/copyright"sv;
|
||||||
|
|
||||||
|
}
|
107
Userland/Applications/MapsSettings/MapsSettingsWidget.cpp
Normal file
107
Userland/Applications/MapsSettings/MapsSettingsWidget.cpp
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023, Bastiaan van der Plaat <bastiaan.v.d.plaat@gmail.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "MapsSettingsWidget.h"
|
||||||
|
#include "Defaults.h"
|
||||||
|
#include <LibConfig/Client.h>
|
||||||
|
#include <LibGUI/ComboBox.h>
|
||||||
|
#include <LibGUI/JsonArrayModel.h>
|
||||||
|
#include <LibGUI/TextBox.h>
|
||||||
|
#include <LibGUI/Widget.h>
|
||||||
|
|
||||||
|
namespace MapsSettings {
|
||||||
|
|
||||||
|
ErrorOr<NonnullRefPtr<MapsSettingsWidget>> MapsSettingsWidget::create()
|
||||||
|
{
|
||||||
|
auto widget = TRY(try_create());
|
||||||
|
TRY(widget->setup());
|
||||||
|
return widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapsSettingsWidget::apply_settings()
|
||||||
|
{
|
||||||
|
// Tile Provider
|
||||||
|
if (m_is_custom_tile_provider) {
|
||||||
|
Config::write_string("Maps"sv, "MapWidget"sv, "TileProviderUrlFormat"sv, m_custom_tile_provider_textbox->text());
|
||||||
|
Config::remove_key("Maps"sv, "MapWidget"sv, "TileProviderAttributionText"sv);
|
||||||
|
Config::remove_key("Maps"sv, "MapWidget"sv, "TileProviderAttributionUrl"sv);
|
||||||
|
} else {
|
||||||
|
auto tile_provider_url_format = m_tile_provider_combobox->model()->index(m_tile_provider_combobox->selected_index(), 1).data().to_deprecated_string();
|
||||||
|
Config::write_string("Maps"sv, "MapWidget"sv, "TileProviderUrlFormat"sv, tile_provider_url_format);
|
||||||
|
auto tile_provider_attribution_text = m_tile_provider_combobox->model()->index(m_tile_provider_combobox->selected_index(), 2).data().to_deprecated_string();
|
||||||
|
Config::write_string("Maps"sv, "MapWidget"sv, "TileProviderAttributionText"sv, tile_provider_attribution_text);
|
||||||
|
auto tile_provider_attribution_url = m_tile_provider_combobox->model()->index(m_tile_provider_combobox->selected_index(), 3).data().to_deprecated_string();
|
||||||
|
Config::write_string("Maps"sv, "MapWidget"sv, "TileProviderAttributionUrl"sv, tile_provider_attribution_url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapsSettingsWidget::reset_default_values()
|
||||||
|
{
|
||||||
|
set_tile_provider(Maps::default_tile_provider_url_format);
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorOr<void> MapsSettingsWidget::setup()
|
||||||
|
{
|
||||||
|
// Tile Provider
|
||||||
|
Vector<GUI::JsonArrayModel::FieldSpec> tile_provider_fields;
|
||||||
|
tile_provider_fields.empend("name", "Name"_string, Gfx::TextAlignment::CenterLeft);
|
||||||
|
tile_provider_fields.empend("url_format", "URL format"_string, Gfx::TextAlignment::CenterLeft);
|
||||||
|
tile_provider_fields.empend("attribution_text", "Attribution text"_string, Gfx::TextAlignment::CenterLeft);
|
||||||
|
tile_provider_fields.empend("attribution_url", "Attribution URL"_string, Gfx::TextAlignment::CenterLeft);
|
||||||
|
auto tile_providers = GUI::JsonArrayModel::create(DeprecatedString::formatted("{}/MapsTileProviders.json", Core::StandardPaths::config_directory()), move(tile_provider_fields));
|
||||||
|
tile_providers->invalidate();
|
||||||
|
|
||||||
|
Vector<JsonValue> custom_tile_provider;
|
||||||
|
custom_tile_provider.append("Custom...");
|
||||||
|
custom_tile_provider.append("");
|
||||||
|
custom_tile_provider.append("");
|
||||||
|
custom_tile_provider.append("");
|
||||||
|
TRY(tile_providers->add(move(custom_tile_provider)));
|
||||||
|
|
||||||
|
m_tile_provider_combobox = *find_descendant_of_type_named<GUI::ComboBox>("tile_provider_combobox");
|
||||||
|
m_tile_provider_combobox->set_model(move(tile_providers));
|
||||||
|
m_tile_provider_combobox->set_only_allow_values_from_model(true);
|
||||||
|
|
||||||
|
m_custom_tile_provider_group = *find_descendant_of_type_named<GUI::Widget>("custom_tile_provider_group");
|
||||||
|
|
||||||
|
m_custom_tile_provider_textbox = *find_descendant_of_type_named<GUI::TextBox>("custom_tile_provider_textbox");
|
||||||
|
m_custom_tile_provider_textbox->set_placeholder(Maps::default_tile_provider_url_format);
|
||||||
|
m_custom_tile_provider_textbox->on_change = [&]() { set_modified(true); };
|
||||||
|
|
||||||
|
m_tile_provider_combobox->on_change = [&](DeprecatedString const&, GUI::ModelIndex const& index) {
|
||||||
|
auto tile_provider_url_format = m_tile_provider_combobox->model()->index(index.row(), 1).data().to_deprecated_string();
|
||||||
|
m_is_custom_tile_provider = tile_provider_url_format.is_empty();
|
||||||
|
m_custom_tile_provider_group->set_enabled(m_is_custom_tile_provider);
|
||||||
|
set_modified(true);
|
||||||
|
};
|
||||||
|
set_tile_provider(Config::read_string("Maps"sv, "MapWidget"sv, "TileProviderUrlFormat"sv, Maps::default_tile_provider_url_format));
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapsSettingsWidget::set_tile_provider(StringView tile_provider_url_format)
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
for (int index = 0; index < m_tile_provider_combobox->model()->row_count(); index++) {
|
||||||
|
auto url_format = m_tile_provider_combobox->model()->index(index, 1).data().to_deprecated_string();
|
||||||
|
if (url_format == tile_provider_url_format) {
|
||||||
|
m_tile_provider_combobox->set_selected_index(index, GUI::AllowCallback::No);
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
m_is_custom_tile_provider = true;
|
||||||
|
m_custom_tile_provider_textbox->set_text(tile_provider_url_format, GUI::AllowCallback::No);
|
||||||
|
m_tile_provider_combobox->set_selected_index(m_tile_provider_combobox->model()->row_count() - 1, GUI::AllowCallback::No);
|
||||||
|
m_custom_tile_provider_group->set_enabled(true);
|
||||||
|
} else {
|
||||||
|
m_custom_tile_provider_group->set_enabled(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
58
Userland/Applications/MapsSettings/MapsSettingsWidget.gml
Normal file
58
Userland/Applications/MapsSettings/MapsSettingsWidget.gml
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
@MapsSettings::MapsSettingsWidget {
|
||||||
|
fill_with_background_color: true
|
||||||
|
layout: @GUI::VerticalBoxLayout {
|
||||||
|
margins: [8]
|
||||||
|
}
|
||||||
|
|
||||||
|
@GUI::GroupBox {
|
||||||
|
title: "Tile Provider"
|
||||||
|
fixed_height: 104
|
||||||
|
layout: @GUI::VerticalBoxLayout {
|
||||||
|
margins: [16, 8, 8]
|
||||||
|
spacing: 2
|
||||||
|
}
|
||||||
|
|
||||||
|
@GUI::Widget {
|
||||||
|
layout: @GUI::HorizontalBoxLayout {
|
||||||
|
spacing: 16
|
||||||
|
}
|
||||||
|
|
||||||
|
@GUI::ImageWidget {
|
||||||
|
fixed_width: 32
|
||||||
|
fixed_height: 32
|
||||||
|
bitmap: "/res/icons/32x32/search-engine.png"
|
||||||
|
}
|
||||||
|
|
||||||
|
@GUI::Label {
|
||||||
|
text: "Tile Provider:"
|
||||||
|
text_alignment: "CenterLeft"
|
||||||
|
fixed_width: 110
|
||||||
|
}
|
||||||
|
|
||||||
|
@GUI::ComboBox {
|
||||||
|
name: "tile_provider_combobox"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@GUI::Widget {
|
||||||
|
layout: @GUI::HorizontalBoxLayout {
|
||||||
|
spacing: 16
|
||||||
|
}
|
||||||
|
name: "custom_tile_provider_group"
|
||||||
|
|
||||||
|
@GUI::Widget {
|
||||||
|
fixed_width: 32
|
||||||
|
}
|
||||||
|
|
||||||
|
@GUI::Label {
|
||||||
|
text: "Enter URL template:"
|
||||||
|
text_alignment: "CenterLeft"
|
||||||
|
fixed_width: 110
|
||||||
|
}
|
||||||
|
|
||||||
|
@GUI::TextBox {
|
||||||
|
name: "custom_tile_provider_textbox"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
35
Userland/Applications/MapsSettings/MapsSettingsWidget.h
Normal file
35
Userland/Applications/MapsSettings/MapsSettingsWidget.h
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023, Bastiaan van der Plaat <bastiaan.v.d.plaat@gmail.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <LibGUI/SettingsWindow.h>
|
||||||
|
|
||||||
|
namespace MapsSettings {
|
||||||
|
|
||||||
|
class MapsSettingsWidget final : public GUI::SettingsWindow::Tab {
|
||||||
|
C_OBJECT_ABSTRACT(MapsSettingsWidget)
|
||||||
|
|
||||||
|
public:
|
||||||
|
static ErrorOr<NonnullRefPtr<MapsSettingsWidget>> create();
|
||||||
|
|
||||||
|
virtual void apply_settings() override;
|
||||||
|
virtual void reset_default_values() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
MapsSettingsWidget() = default;
|
||||||
|
static ErrorOr<NonnullRefPtr<MapsSettingsWidget>> try_create();
|
||||||
|
|
||||||
|
ErrorOr<void> setup();
|
||||||
|
void set_tile_provider(StringView url);
|
||||||
|
|
||||||
|
RefPtr<GUI::ComboBox> m_tile_provider_combobox;
|
||||||
|
RefPtr<GUI::Widget> m_custom_tile_provider_group;
|
||||||
|
RefPtr<GUI::TextBox> m_custom_tile_provider_textbox;
|
||||||
|
bool m_is_custom_tile_provider { false };
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
34
Userland/Applications/MapsSettings/main.cpp
Normal file
34
Userland/Applications/MapsSettings/main.cpp
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023, Bastiaan van der Plaat <bastiaan.v.d.plaat@gmail.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "MapsSettingsWidget.h"
|
||||||
|
#include <LibConfig/Client.h>
|
||||||
|
#include <LibCore/System.h>
|
||||||
|
#include <LibGUI/Application.h>
|
||||||
|
#include <LibGUI/Icon.h>
|
||||||
|
#include <LibGUI/SettingsWindow.h>
|
||||||
|
#include <LibMain/Main.h>
|
||||||
|
|
||||||
|
ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||||
|
{
|
||||||
|
TRY(Core::System::pledge("stdio recvfd sendfd rpath unix"));
|
||||||
|
|
||||||
|
auto app = TRY(GUI::Application::create(arguments));
|
||||||
|
|
||||||
|
TRY(Core::System::unveil("/res", "r"));
|
||||||
|
TRY(Core::System::unveil("/home", "r"));
|
||||||
|
TRY(Core::System::unveil("/tmp/session/%sid/portal/config", "rw"));
|
||||||
|
TRY(Core::System::unveil(nullptr, nullptr));
|
||||||
|
|
||||||
|
auto app_icon = GUI::Icon::default_icon("app-maps"sv);
|
||||||
|
auto window = TRY(GUI::SettingsWindow::create("Maps Settings", GUI::SettingsWindow::ShowDefaultsButton::Yes));
|
||||||
|
window->set_icon(app_icon.bitmap_for_size(16));
|
||||||
|
|
||||||
|
(void)TRY(window->add_tab(TRY(MapsSettings::MapsSettingsWidget::create()), "Maps"_string, "maps"sv));
|
||||||
|
|
||||||
|
window->show();
|
||||||
|
return app->exec();
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue