diff options
author | Maciej Zygmanowski <sppmacd@pm.me> | 2021-08-02 11:56:05 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-08-23 01:41:53 +0200 |
commit | 3597b6eb9d5a6d2197cbe1c42cf1ec073d9f891e (patch) | |
tree | 6a82258a408f36d80d314208072925a14a0f87d8 /Userland/Libraries | |
parent | 0363cd3d551753e435b9765f49ea2e7d7bc18a27 (diff) | |
download | serenity-3597b6eb9d5a6d2197cbe1c42cf1ec073d9f891e.zip |
WindowServer+LibGfx: Move CursorParams to LibGfx
They will be used by MouseSettings in the next commit.
Diffstat (limited to 'Userland/Libraries')
-rw-r--r-- | Userland/Libraries/LibGfx/CMakeLists.txt | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibGfx/CursorParams.cpp | 100 | ||||
-rw-r--r-- | Userland/Libraries/LibGfx/CursorParams.h | 37 |
3 files changed, 138 insertions, 0 deletions
diff --git a/Userland/Libraries/LibGfx/CMakeLists.txt b/Userland/Libraries/LibGfx/CMakeLists.txt index b16f1caf50..92625cace3 100644 --- a/Userland/Libraries/LibGfx/CMakeLists.txt +++ b/Userland/Libraries/LibGfx/CMakeLists.txt @@ -8,6 +8,7 @@ set(SOURCES ClassicStylePainter.cpp ClassicWindowTheme.cpp Color.cpp + CursorParams.cpp DDSLoader.cpp DisjointRectSet.cpp Emoji.cpp diff --git a/Userland/Libraries/LibGfx/CursorParams.cpp b/Userland/Libraries/LibGfx/CursorParams.cpp new file mode 100644 index 0000000000..31ae7105ae --- /dev/null +++ b/Userland/Libraries/LibGfx/CursorParams.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <AK/Format.h> +#include <AK/LexicalPath.h> +#include <LibGfx/Bitmap.h> +#include <LibGfx/CursorParams.h> + +namespace Gfx { + +CursorParams CursorParams::parse_from_filename(StringView const& cursor_path, Gfx::IntPoint const& default_hotspot) +{ + LexicalPath path(cursor_path); + auto file_title = path.title(); + auto last_dot_in_title = file_title.find_last('.'); + if (!last_dot_in_title.has_value() || last_dot_in_title.value() == 0) { + // No encoded params in filename. Not an error, we'll just use defaults + return { default_hotspot }; + } + auto params_str = file_title.substring_view(last_dot_in_title.value() + 1); + + CursorParams params(default_hotspot); + bool in_display_scale_part = false; + for (size_t i = 0; i + 1 < params_str.length() && !in_display_scale_part;) { + auto property = params_str[i++]; + + auto value = [&]() -> Optional<size_t> { + size_t k = i; + while (k < params_str.length()) { + auto ch = params_str[k]; + if (ch < '0' || ch > '9') + break; + k++; + } + if (k == i) + return {}; + auto parsed_number = params_str.substring_view(i, k - i).to_uint(); + if (!parsed_number.has_value()) + return {}; + i = k; + return parsed_number.value(); + }(); + if (!value.has_value()) { + dbgln("Failed to parse value for property '{}' from parsed cursor path: {}", property, cursor_path); + return { default_hotspot }; + } + switch (property) { + case 'x': + params.m_hotspot.set_x(value.value()); + params.m_have_hotspot = true; + break; + case 'y': + params.m_hotspot.set_y(value.value()); + params.m_have_hotspot = true; + break; + case 'f': + if (value.value() > 1) + params.m_frames = value.value(); + break; + case 't': + if (value.value() >= 100 && value.value() <= 1000) + params.m_frame_ms = value.value(); + else + dbgln("Cursor frame rate outside of valid range (100-1000ms)"); + break; + case '-': + in_display_scale_part = true; + break; + default: + dbgln("Ignore unknown property '{}' with value {} parsed from cursor path: {}", property, value.value(), cursor_path); + return { default_hotspot }; + } + } + + return params; +} + +CursorParams CursorParams::constrained(Gfx::Bitmap const& bitmap) const +{ + CursorParams params(*this); + auto rect = bitmap.rect(); + if (params.m_frames > 1) { + if (rect.width() % params.m_frames == 0) { + rect.set_width(rect.width() / (int)params.m_frames); + } else { + dbgln("Cannot divide cursor dimensions {} into {} frames", rect, params.m_frames); + params.m_frames = 1; + } + } + if (params.m_have_hotspot) + params.m_hotspot.constrain(rect); + else + params.m_hotspot = rect.center(); + return params; +} + +} diff --git a/Userland/Libraries/LibGfx/CursorParams.h b/Userland/Libraries/LibGfx/CursorParams.h new file mode 100644 index 0000000000..d3bbd07945 --- /dev/null +++ b/Userland/Libraries/LibGfx/CursorParams.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <AK/StringView.h> +#include <LibGfx/Point.h> + +namespace Gfx { + +class CursorParams { +public: + static CursorParams parse_from_filename(StringView const&, Gfx::IntPoint const&); + + CursorParams() = default; + + CursorParams(Gfx::IntPoint const& hotspot) + : m_hotspot(hotspot) + { + } + CursorParams constrained(Gfx::Bitmap const&) const; + + Gfx::IntPoint const& hotspot() const { return m_hotspot; } + unsigned frames() const { return m_frames; } + unsigned frame_ms() const { return m_frame_ms; } + +private: + Gfx::IntPoint m_hotspot; + unsigned m_frames { 1 }; + unsigned m_frame_ms { 0 }; + bool m_have_hotspot { false }; +}; + +} |