@@ -91,6 +91,10 @@ jobs:
|
|||||||
restore-keys: conan-${{ runner.os }}-
|
restore-keys: conan-${{ runner.os }}-
|
||||||
- name: Configure native release
|
- name: Configure native release
|
||||||
run: python3 modulus.py configure --target x86_64_gcc12_release
|
run: python3 modulus.py configure --target x86_64_gcc12_release
|
||||||
|
- name: Check code style
|
||||||
|
run: |
|
||||||
|
python3 -m pip install --no-cache-dir -r build/build_tools/docker/format-requirements.txt
|
||||||
|
python3 modulus.py format --check
|
||||||
- name: Build native release
|
- name: Build native release
|
||||||
run: python3 modulus.py build --target x86_64_gcc12_release
|
run: python3 modulus.py build --target x86_64_gcc12_release
|
||||||
- name: Test native release
|
- name: Test native release
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ Luma uses Modulus for shared build tooling, Boost.JSON, and raylib integration.
|
|||||||
|
|
||||||
## Build
|
## Build
|
||||||
|
|
||||||
|
Code style is managed by Modulus: run `./modulus.py format` or `./modulus.py format --check`. The generated Neovim integration uses the same pinned container formatter for C++ and Python, including existing format-on-save toggles. Configure first to prepare tooling; customize `tooling.editor.clang_format` and `tooling.format.exclude` in `modulus.json`, not generated editor files. See the shared Modulus README for the compact layout and no-alias policy.
|
||||||
|
|
||||||
Configure, build, and test the default target:
|
Configure, build, and test the default target:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
|
|||||||
@@ -40,15 +40,12 @@ class luma_conan(conan.ConanFile):
|
|||||||
"tests/*.cpp",
|
"tests/*.cpp",
|
||||||
"tests/*.hpp",
|
"tests/*.hpp",
|
||||||
)
|
)
|
||||||
|
|
||||||
def config_options(self):
|
def config_options(self):
|
||||||
if self.settings.os == "Windows":
|
if self.settings.os == "Windows":
|
||||||
del self.options.fPIC
|
del self.options.fPIC
|
||||||
|
|
||||||
def configure(self):
|
def configure(self):
|
||||||
if self.options.shared:
|
if self.options.shared:
|
||||||
del self.options.fPIC
|
del self.options.fPIC
|
||||||
|
|
||||||
def requirements(self):
|
def requirements(self):
|
||||||
self.requires(
|
self.requires(
|
||||||
"modulus/latest",
|
"modulus/latest",
|
||||||
@@ -58,7 +55,6 @@ class luma_conan(conan.ConanFile):
|
|||||||
"with_raylib": True,
|
"with_raylib": True,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
def generate(self):
|
def generate(self):
|
||||||
deps = conan.tools.cmake.CMakeDeps(self)
|
deps = conan.tools.cmake.CMakeDeps(self)
|
||||||
deps.generate()
|
deps.generate()
|
||||||
@@ -68,14 +64,12 @@ class luma_conan(conan.ConanFile):
|
|||||||
toolchain.variables["BUILD_SHARED_LIBS"] = bool(self.options.shared)
|
toolchain.variables["BUILD_SHARED_LIBS"] = bool(self.options.shared)
|
||||||
toolchain.variables["BUILD_TESTING"] = bool(self.options.with_tests)
|
toolchain.variables["BUILD_TESTING"] = bool(self.options.with_tests)
|
||||||
toolchain.generate()
|
toolchain.generate()
|
||||||
|
|
||||||
def build(self):
|
def build(self):
|
||||||
cmake = conan.tools.cmake.CMake(self)
|
cmake = conan.tools.cmake.CMake(self)
|
||||||
cmake.configure()
|
cmake.configure()
|
||||||
cmake.build()
|
cmake.build()
|
||||||
if self.options.with_tests and conan.tools.build.can_run(self):
|
if self.options.with_tests and conan.tools.build.can_run(self):
|
||||||
cmake.test(target="check")
|
cmake.test(target="check")
|
||||||
|
|
||||||
def package_id(self):
|
def package_id(self):
|
||||||
self.info.options.rm_safe("with_tests")
|
self.info.options.rm_safe("with_tests")
|
||||||
for requirement in (
|
for requirement in (
|
||||||
@@ -85,11 +79,9 @@ class luma_conan(conan.ConanFile):
|
|||||||
):
|
):
|
||||||
if requirement in self.info.requires.pkg_names:
|
if requirement in self.info.requires.pkg_names:
|
||||||
self.info.requires.remove(requirement)
|
self.info.requires.remove(requirement)
|
||||||
|
|
||||||
def package(self):
|
def package(self):
|
||||||
cmake = conan.tools.cmake.CMake(self)
|
cmake = conan.tools.cmake.CMake(self)
|
||||||
cmake.install()
|
cmake.install()
|
||||||
|
|
||||||
def package_info(self):
|
def package_info(self):
|
||||||
self.cpp_info.set_property(
|
self.cpp_info.set_property(
|
||||||
"cmake_file_name",
|
"cmake_file_name",
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include <modulus.hpp>
|
#include <modulus.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace luma {
|
namespace luma {
|
||||||
|
|
||||||
enum class easing {
|
enum class easing {
|
||||||
|
|||||||
@@ -23,7 +23,9 @@
|
|||||||
namespace luma {
|
namespace luma {
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
struct application_core;
|
struct application_core;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct frame_stats {
|
struct frame_stats {
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include <luma/render.hpp>
|
#include <luma/render.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace luma {
|
namespace luma {
|
||||||
|
|
||||||
class renderer_resources {
|
class renderer_resources {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include <luma/theme.hpp>
|
#include <luma/theme.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace luma {
|
namespace luma {
|
||||||
|
|
||||||
struct display_config {
|
struct display_config {
|
||||||
|
|||||||
@@ -6,10 +6,13 @@
|
|||||||
|
|
||||||
#include <luma/geometry.hpp>
|
#include <luma/geometry.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace luma {
|
namespace luma {
|
||||||
|
|
||||||
class draw_context;
|
class draw_context;
|
||||||
|
|
||||||
struct theme;
|
struct theme;
|
||||||
|
|
||||||
struct touch_event;
|
struct touch_event;
|
||||||
|
|
||||||
class control {
|
class control {
|
||||||
|
|||||||
@@ -76,7 +76,6 @@ public:
|
|||||||
std::weak_ptr<void> lifetime{};
|
std::weak_ptr<void> lifetime{};
|
||||||
std::function<void()> callback{};
|
std::function<void()> callback{};
|
||||||
};
|
};
|
||||||
|
|
||||||
text_input_state(luma::text_field_options options, std::function<void(std::string)> on_change);
|
text_input_state(luma::text_field_options options, std::function<void(std::string)> on_change);
|
||||||
auto snapshot() const -> luma::text_field_options;
|
auto snapshot() const -> luma::text_field_options;
|
||||||
auto text() const -> std::string;
|
auto text() const -> std::string;
|
||||||
@@ -162,7 +161,6 @@ template <typename... CONTROLS>
|
|||||||
auto luma::children(CONTROLS &&...controls) -> std::expected<std::vector<std::unique_ptr<luma::control>>, modulus::error> {
|
auto luma::children(CONTROLS &&...controls) -> std::expected<std::vector<std::unique_ptr<luma::control>>, modulus::error> {
|
||||||
auto result = std::vector<std::unique_ptr<luma::control>>{};
|
auto result = std::vector<std::unique_ptr<luma::control>>{};
|
||||||
result.reserve(sizeof...(controls));
|
result.reserve(sizeof...(controls));
|
||||||
|
|
||||||
auto append = [&result](auto &&input) -> std::expected<void, modulus::error> {
|
auto append = [&result](auto &&input) -> std::expected<void, modulus::error> {
|
||||||
auto child = luma::detail::normalize_child(std::forward<decltype(input)>(input));
|
auto child = luma::detail::normalize_child(std::forward<decltype(input)>(input));
|
||||||
if (!child) {
|
if (!child) {
|
||||||
@@ -171,13 +169,13 @@ auto luma::children(CONTROLS&&... controls) -> std::expected<std::vector<std::un
|
|||||||
result.push_back(std::move(*child));
|
result.push_back(std::move(*child));
|
||||||
return {};
|
return {};
|
||||||
};
|
};
|
||||||
|
|
||||||
auto status = std::expected<void, modulus::error>{};
|
auto status = std::expected<void, modulus::error>{};
|
||||||
([&] {
|
([&] {
|
||||||
if (status) {
|
if (status) {
|
||||||
status = append(std::forward<CONTROLS>(controls));
|
status = append(std::forward<CONTROLS>(controls));
|
||||||
}
|
}
|
||||||
}(), ...);
|
}(),
|
||||||
|
...);
|
||||||
if (!status) {
|
if (!status) {
|
||||||
return modulus::fail<std::vector<std::unique_ptr<luma::control>>>(status.error());
|
return modulus::fail<std::vector<std::unique_ptr<luma::control>>>(status.error());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include <modulus.hpp>
|
#include <modulus.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace luma::detail {
|
namespace luma::detail {
|
||||||
|
|
||||||
constexpr std::int32_t error_invalid_argument{1};
|
constexpr std::int32_t error_invalid_argument{1};
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include <modulus.hpp>
|
#include <modulus.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace luma {
|
namespace luma {
|
||||||
|
|
||||||
struct point {
|
struct point {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include <luma/geometry.hpp>
|
#include <luma/geometry.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace luma {
|
namespace luma {
|
||||||
|
|
||||||
enum class touch_phase {
|
enum class touch_phase {
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#include <luma/control.hpp>
|
#include <luma/control.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace luma {
|
namespace luma {
|
||||||
|
|
||||||
enum class dialog_result {
|
enum class dialog_result {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include <luma/geometry.hpp>
|
#include <luma/geometry.hpp>
|
||||||
#include <luma/theme.hpp>
|
#include <luma/theme.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace luma {
|
namespace luma {
|
||||||
|
|
||||||
struct texture_info {
|
struct texture_info {
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include <luma/control.hpp>
|
#include <luma/control.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace luma {
|
namespace luma {
|
||||||
|
|
||||||
class router {
|
class router {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include <modulus.hpp>
|
#include <modulus.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace luma {
|
namespace luma {
|
||||||
|
|
||||||
struct color {
|
struct color {
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include <luma/control.hpp>
|
#include <luma/control.hpp>
|
||||||
#include <luma/geometry.hpp>
|
#include <luma/geometry.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace luma {
|
namespace luma {
|
||||||
|
|
||||||
class window_manager;
|
class window_manager;
|
||||||
|
|||||||
+6
-2
@@ -16,6 +16,7 @@ COMMANDS = (
|
|||||||
"package",
|
"package",
|
||||||
"lsp",
|
"lsp",
|
||||||
"clangd",
|
"clangd",
|
||||||
|
"format",
|
||||||
)
|
)
|
||||||
COMMON_DIR = pathlib.Path("build") / "build_common"
|
COMMON_DIR = pathlib.Path("build") / "build_common"
|
||||||
TOOLS_DIR = pathlib.Path("build") / "build_tools"
|
TOOLS_DIR = pathlib.Path("build") / "build_tools"
|
||||||
@@ -60,6 +61,9 @@ def runtime_ready(root):
|
|||||||
and (root / TOOLS_DIR / "clangd.py").is_file()
|
and (root / TOOLS_DIR / "clangd.py").is_file()
|
||||||
and (root / RUNTIME_DIR / "modulus" / "cli.py").is_file()
|
and (root / RUNTIME_DIR / "modulus" / "cli.py").is_file()
|
||||||
and (root / RUNTIME_DIR / "modulus" / "export.py").is_file()
|
and (root / RUNTIME_DIR / "modulus" / "export.py").is_file()
|
||||||
|
and (root / TOOLS_DIR / "format.py").is_file()
|
||||||
|
and (root / RUNTIME_DIR / "modulus" / "formatting.py").is_file()
|
||||||
|
and (root / RUNTIME_DIR / "modulus" / "format_layout.py").is_file()
|
||||||
)
|
)
|
||||||
|
|
||||||
def optional_credentials():
|
def optional_credentials():
|
||||||
@@ -340,9 +344,9 @@ def ensure_runtime(root):
|
|||||||
|
|
||||||
def delegate(command, argv):
|
def delegate(command, argv):
|
||||||
root = repo_root()
|
root = repo_root()
|
||||||
if command == "clangd":
|
if command in {"clangd", "format"}:
|
||||||
if not runtime_ready(root):
|
if not runtime_ready(root):
|
||||||
print("Modulus clangd tooling is missing; run ./modulus.py configure first", file=sys.stderr)
|
print(f"Modulus {command} tooling is missing; run ./modulus.py configure first", file=sys.stderr)
|
||||||
return 1
|
return 1
|
||||||
else:
|
else:
|
||||||
ensure_runtime(root)
|
ensure_runtime(root)
|
||||||
|
|||||||
+1
-4
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include <luma/detail/errors.hpp>
|
#include <luma/detail/errors.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
auto invalid(std::string message) -> std::expected<void, modulus::error> {
|
auto invalid(std::string message) -> std::expected<void, modulus::error> {
|
||||||
@@ -104,12 +105,10 @@ auto luma::animation_graph::tick(std::chrono::steady_clock::duration delta) -> s
|
|||||||
if (ticking_) {
|
if (ticking_) {
|
||||||
return internal("animation graph is already ticking");
|
return internal("animation graph is already ticking");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto active = std::move(animations_);
|
auto active = std::move(animations_);
|
||||||
animations_.clear();
|
animations_.clear();
|
||||||
ticking_ = true;
|
ticking_ = true;
|
||||||
clear_requested_ = false;
|
clear_requested_ = false;
|
||||||
|
|
||||||
auto fail_tick = [this](std::expected<void, modulus::error> status) {
|
auto fail_tick = [this](std::expected<void, modulus::error> status) {
|
||||||
ticking_ = false;
|
ticking_ = false;
|
||||||
clear_requested_ = false;
|
clear_requested_ = false;
|
||||||
@@ -117,7 +116,6 @@ auto luma::animation_graph::tick(std::chrono::steady_clock::duration delta) -> s
|
|||||||
pending_.clear();
|
pending_.clear();
|
||||||
return status;
|
return status;
|
||||||
};
|
};
|
||||||
|
|
||||||
for (auto &running : active) {
|
for (auto &running : active) {
|
||||||
running.elapsed += delta;
|
running.elapsed += delta;
|
||||||
auto duration = std::chrono::duration_cast<std::chrono::steady_clock::duration>(running.animation.duration);
|
auto duration = std::chrono::duration_cast<std::chrono::steady_clock::duration>(running.animation.duration);
|
||||||
@@ -160,7 +158,6 @@ auto luma::animation_graph::tick(std::chrono::steady_clock::duration delta) -> s
|
|||||||
}
|
}
|
||||||
animations_.push_back(std::move(running));
|
animations_.push_back(std::move(running));
|
||||||
}
|
}
|
||||||
|
|
||||||
ticking_ = false;
|
ticking_ = false;
|
||||||
for (auto &operation : pending_) {
|
for (auto &operation : pending_) {
|
||||||
if (operation.kind == luma::animation_graph::pending_kind::CLEAR) {
|
if (operation.kind == luma::animation_graph::pending_kind::CLEAR) {
|
||||||
|
|||||||
+24
-28
@@ -38,6 +38,7 @@
|
|||||||
#include <luma/render.hpp>
|
#include <luma/render.hpp>
|
||||||
#include <luma/routing.hpp>
|
#include <luma/routing.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace luma::detail {
|
namespace luma::detail {
|
||||||
|
|
||||||
struct application_core {
|
struct application_core {
|
||||||
@@ -75,7 +76,6 @@ namespace {
|
|||||||
struct font_key {
|
struct font_key {
|
||||||
std::string path{};
|
std::string path{};
|
||||||
std::int32_t size{};
|
std::int32_t size{};
|
||||||
|
|
||||||
auto operator==(font_key const &other) const -> std::bool_t;
|
auto operator==(font_key const &other) const -> std::bool_t;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -298,11 +298,9 @@ auto dispatch_to_ui(std::shared_ptr<luma::detail::application_core> const& core,
|
|||||||
if (!core) {
|
if (!core) {
|
||||||
return unavailable<VALUE>("application is not initialized");
|
return unavailable<VALUE>("application is not initialized");
|
||||||
}
|
}
|
||||||
|
|
||||||
auto task = std::decay_t<TASK>{std::forward<TASK>(input)};
|
auto task = std::decay_t<TASK>{std::forward<TASK>(input)};
|
||||||
auto should_post = false;
|
auto should_post = false;
|
||||||
auto wait_for_startup = false;
|
auto wait_for_startup = false;
|
||||||
|
|
||||||
{
|
{
|
||||||
auto lock = std::unique_lock{core->lifecycle_mutex};
|
auto lock = std::unique_lock{core->lifecycle_mutex};
|
||||||
if (core->stopping.load(std::memory_order_acquire)) {
|
if (core->stopping.load(std::memory_order_acquire)) {
|
||||||
@@ -317,7 +315,6 @@ auto dispatch_to_ui(std::shared_ptr<luma::detail::application_core> const& core,
|
|||||||
should_post = running && accepting;
|
should_post = running && accepting;
|
||||||
wait_for_startup = running && !accepting;
|
wait_for_startup = running && !accepting;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!should_post || wait_for_startup) {
|
if (!should_post || wait_for_startup) {
|
||||||
auto immediate_lock = std::scoped_lock{core->immediate_mutex};
|
auto immediate_lock = std::scoped_lock{core->immediate_mutex};
|
||||||
auto lock = std::unique_lock{core->lifecycle_mutex};
|
auto lock = std::unique_lock{core->lifecycle_mutex};
|
||||||
@@ -337,7 +334,6 @@ auto dispatch_to_ui(std::shared_ptr<luma::detail::application_core> const& core,
|
|||||||
}
|
}
|
||||||
should_post = true;
|
should_post = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto future = std::future<std::expected<VALUE, modulus::error>>{};
|
auto future = std::future<std::expected<VALUE, modulus::error>>{};
|
||||||
auto promise = std::make_shared<std::promise<std::expected<VALUE, modulus::error>>>();
|
auto promise = std::make_shared<std::promise<std::expected<VALUE, modulus::error>>>();
|
||||||
future = promise->get_future();
|
future = promise->get_future();
|
||||||
@@ -364,7 +360,6 @@ auto dispatch_to_ui(std::shared_ptr<luma::detail::application_core> const& core,
|
|||||||
} catch (...) {
|
} catch (...) {
|
||||||
return internal<VALUE>("failed to queue UI task");
|
return internal<VALUE>("failed to queue UI task");
|
||||||
}
|
}
|
||||||
|
|
||||||
return future.get();
|
return future.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -543,7 +538,8 @@ auto font_key_hash::operator()(font_key const& key) const noexcept -> std::size_
|
|||||||
return seed;
|
return seed;
|
||||||
}
|
}
|
||||||
|
|
||||||
scope_exit::scope_exit(std::function<void()> action) : action_{std::move(action)} {}
|
scope_exit::scope_exit(std::function<void()> action)
|
||||||
|
: action_{std::move(action)} {}
|
||||||
|
|
||||||
scope_exit::~scope_exit() {
|
scope_exit::~scope_exit() {
|
||||||
if (!active_ || !action_) {
|
if (!active_ || !action_) {
|
||||||
@@ -576,7 +572,8 @@ auto drawing_scope::end() -> void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ui_traversal_scope::ui_traversal_scope(luma::detail::application_core& core) : core_{core} {
|
ui_traversal_scope::ui_traversal_scope(luma::detail::application_core &core)
|
||||||
|
: core_{core} {
|
||||||
++core_.traversal_depth;
|
++core_.traversal_depth;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -586,7 +583,8 @@ ui_traversal_scope::~ui_traversal_scope() {
|
|||||||
flush_retired_controls(core_);
|
flush_retired_controls(core_);
|
||||||
}
|
}
|
||||||
|
|
||||||
raylib_texture::raylib_texture(std::shared_ptr<raylib_resource_state::texture_record> record, std::shared_ptr<raylib_resource_state> state) : record_{std::move(record)}, state_{std::move(state)} {
|
raylib_texture::raylib_texture(std::shared_ptr<raylib_resource_state::texture_record> record, std::shared_ptr<raylib_resource_state> state)
|
||||||
|
: record_{std::move(record)}, state_{std::move(state)} {
|
||||||
assert(record_ != nullptr);
|
assert(record_ != nullptr);
|
||||||
assert(record_->texture.id != 0);
|
assert(record_->texture.id != 0);
|
||||||
assert(record_->texture.width > 0);
|
assert(record_->texture.width > 0);
|
||||||
@@ -623,7 +621,8 @@ auto raylib_texture::native() const -> Texture2D {
|
|||||||
return record_->texture;
|
return record_->texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
raylib_resources::raylib_resources(std::shared_ptr<raylib_resource_state> state) : state_{std::move(state)} {
|
raylib_resources::raylib_resources(std::shared_ptr<raylib_resource_state> state)
|
||||||
|
: state_{std::move(state)} {
|
||||||
assert(state_ != nullptr);
|
assert(state_ != nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -652,7 +651,8 @@ auto raylib_resources::state() const -> std::shared_ptr<raylib_resource_state> {
|
|||||||
return state_;
|
return state_;
|
||||||
}
|
}
|
||||||
|
|
||||||
raylib_draw_context::raylib_draw_context(std::shared_ptr<raylib_resource_state> state) : state_{std::move(state)} {
|
raylib_draw_context::raylib_draw_context(std::shared_ptr<raylib_resource_state> state)
|
||||||
|
: state_{std::move(state)} {
|
||||||
assert(state_ != nullptr);
|
assert(state_ != nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -663,7 +663,8 @@ auto raylib_draw_context::fill_rect(luma::rect bounds, luma::color color) -> voi
|
|||||||
.y = bounds.y,
|
.y = bounds.y,
|
||||||
.width = bounds.width,
|
.width = bounds.width,
|
||||||
.height = bounds.height,
|
.height = bounds.height,
|
||||||
}, to_raylib(color));
|
},
|
||||||
|
to_raylib(color));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto raylib_draw_context::stroke_rect(luma::rect bounds, std::float32_t thickness, luma::color color) -> void {
|
auto raylib_draw_context::stroke_rect(luma::rect bounds, std::float32_t thickness, luma::color color) -> void {
|
||||||
@@ -674,7 +675,8 @@ auto raylib_draw_context::stroke_rect(luma::rect bounds, std::float32_t thicknes
|
|||||||
.y = bounds.y,
|
.y = bounds.y,
|
||||||
.width = bounds.width,
|
.width = bounds.width,
|
||||||
.height = bounds.height,
|
.height = bounds.height,
|
||||||
}, thickness, to_raylib(color));
|
},
|
||||||
|
thickness, to_raylib(color));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto raylib_draw_context::stroke_line(luma::point from, luma::point to, std::float32_t thickness, luma::color color) -> void {
|
auto raylib_draw_context::stroke_line(luma::point from, luma::point to, std::float32_t thickness, luma::color color) -> void {
|
||||||
@@ -728,7 +730,8 @@ auto raylib_draw_context::draw_text(std::string_view text, luma::point origin, l
|
|||||||
DrawTextEx(font, owned.c_str(), {
|
DrawTextEx(font, owned.c_str(), {
|
||||||
.x = origin.x,
|
.x = origin.x,
|
||||||
.y = origin.y,
|
.y = origin.y,
|
||||||
}, style.size, 1.0F, to_raylib(color));
|
},
|
||||||
|
style.size, 1.0F, to_raylib(color));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto raylib_draw_context::draw_texture(luma::texture const &texture, luma::rect source, luma::rect destination, luma::color tint) -> void {
|
auto raylib_draw_context::draw_texture(luma::texture const &texture, luma::rect source, luma::rect destination, luma::color tint) -> void {
|
||||||
@@ -791,9 +794,11 @@ auto raylib_draw_context::measure_text(std::string_view text, luma::text_style c
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
luma::detail::application_core::application_core(luma::application_config value) : ui_strand{boost::asio::make_strand(ui_context)}, config{std::move(value)} {}
|
luma::detail::application_core::application_core(luma::application_config value)
|
||||||
|
: ui_strand{boost::asio::make_strand(ui_context)}, config{std::move(value)} {}
|
||||||
|
|
||||||
luma::application::application(luma::application_config config) : core_{std::make_shared<luma::detail::application_core>(std::move(config))} {
|
luma::application::application(luma::application_config config)
|
||||||
|
: core_{std::make_shared<luma::detail::application_core>(std::move(config))} {
|
||||||
assert(core_ != nullptr);
|
assert(core_ != nullptr);
|
||||||
install_retire_handlers(core_);
|
install_retire_handlers(core_);
|
||||||
core_->windows.bind_layout_invalidator(make_layout_invalidator(core_));
|
core_->windows.bind_layout_invalidator(make_layout_invalidator(core_));
|
||||||
@@ -888,9 +893,7 @@ auto luma::application::pop_route() -> std::expected<void, modulus::error> {
|
|||||||
|
|
||||||
auto luma::application::current_route() const -> std::expected<std::string, modulus::error> {
|
auto luma::application::current_route() const -> std::expected<std::string, modulus::error> {
|
||||||
auto core = core_snapshot();
|
auto core = core_snapshot();
|
||||||
return dispatch_to_ui<std::string>(core, [core] {
|
return dispatch_to_ui<std::string>(core, [core] { return modulus::success(std::string{core->router.current_route()}); }, false);
|
||||||
return modulus::success(std::string{core->router.current_route()});
|
|
||||||
}, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto luma::application::add_animation(luma::animation animation) -> std::expected<void, modulus::error> {
|
auto luma::application::add_animation(luma::animation animation) -> std::expected<void, modulus::error> {
|
||||||
@@ -910,9 +913,7 @@ auto luma::application::clear_animations() -> std::expected<void, modulus::error
|
|||||||
|
|
||||||
auto luma::application::animations_empty() const -> std::expected<std::bool_t, modulus::error> {
|
auto luma::application::animations_empty() const -> std::expected<std::bool_t, modulus::error> {
|
||||||
auto core = core_snapshot();
|
auto core = core_snapshot();
|
||||||
return dispatch_to_ui<std::bool_t>(core, [core] {
|
return dispatch_to_ui<std::bool_t>(core, [core] { return modulus::success(core->animations.empty()); }, false);
|
||||||
return modulus::success(core->animations.empty());
|
|
||||||
}, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto luma::application::open_window(luma::window_options options, std::unique_ptr<luma::control> content) -> std::expected<std::uint64_t, modulus::error> {
|
auto luma::application::open_window(luma::window_options options, std::unique_ptr<luma::control> content) -> std::expected<std::uint64_t, modulus::error> {
|
||||||
@@ -981,8 +982,7 @@ auto luma::application::load_texture(std::string path) -> std::expected<std::sha
|
|||||||
if (!core->renderer_active.load(std::memory_order_acquire) || !core->assets) {
|
if (!core->renderer_active.load(std::memory_order_acquire) || !core->assets) {
|
||||||
return unavailable<std::shared_ptr<luma::texture>>("texture loading requires an active renderer");
|
return unavailable<std::shared_ptr<luma::texture>>("texture loading requires an active renderer");
|
||||||
}
|
}
|
||||||
return core->assets->texture(path);
|
return core->assets->texture(path); }, false);
|
||||||
}, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto luma::application::request_layout() -> std::expected<void, modulus::error> {
|
auto luma::application::request_layout() -> std::expected<void, modulus::error> {
|
||||||
@@ -1100,7 +1100,6 @@ auto luma::application::run() -> std::expected<void, modulus::error> {
|
|||||||
core->running.store(true, std::memory_order_release);
|
core->running.store(true, std::memory_order_release);
|
||||||
core->accepting_tasks.store(false, std::memory_order_release);
|
core->accepting_tasks.store(false, std::memory_order_release);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto resource_state = std::shared_ptr<raylib_resource_state>{};
|
auto resource_state = std::shared_ptr<raylib_resource_state>{};
|
||||||
auto window_ready = false;
|
auto window_ready = false;
|
||||||
[[maybe_unused]] auto cleanup = scope_exit{[&core, &resource_state, &window_ready] {
|
[[maybe_unused]] auto cleanup = scope_exit{[&core, &resource_state, &window_ready] {
|
||||||
@@ -1123,7 +1122,6 @@ auto luma::application::run() -> std::expected<void, modulus::error> {
|
|||||||
}
|
}
|
||||||
finish_run(*core);
|
finish_run(*core);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
InitWindow(core->config.display.width, core->config.display.height, core->config.title.c_str());
|
InitWindow(core->config.display.width, core->config.display.height, core->config.title.c_str());
|
||||||
if (!IsWindowReady()) {
|
if (!IsWindowReady()) {
|
||||||
return unavailable<void>("failed to initialize raylib window");
|
return unavailable<void>("failed to initialize raylib window");
|
||||||
@@ -1135,7 +1133,6 @@ auto luma::application::run() -> std::expected<void, modulus::error> {
|
|||||||
auto current_target_fps = core->config.display.target_fps;
|
auto current_target_fps = core->config.display.target_fps;
|
||||||
auto const idle_fps = core->config.display.idle_fps;
|
auto const idle_fps = core->config.display.idle_fps;
|
||||||
SetTargetFPS(current_target_fps);
|
SetTargetFPS(current_target_fps);
|
||||||
|
|
||||||
resource_state = std::make_shared<raylib_resource_state>();
|
resource_state = std::make_shared<raylib_resource_state>();
|
||||||
resource_state->ui_thread = std::this_thread::get_id();
|
resource_state->ui_thread = std::this_thread::get_id();
|
||||||
resource_state->active.store(true, std::memory_order_release);
|
resource_state->active.store(true, std::memory_order_release);
|
||||||
@@ -1147,7 +1144,6 @@ auto luma::application::run() -> std::expected<void, modulus::error> {
|
|||||||
core->accepting_tasks.store(true, std::memory_order_release);
|
core->accepting_tasks.store(true, std::memory_order_release);
|
||||||
}
|
}
|
||||||
startup_lock.unlock();
|
startup_lock.unlock();
|
||||||
|
|
||||||
auto context = raylib_draw_context{resource_state};
|
auto context = raylib_draw_context{resource_state};
|
||||||
auto previous_touches = std::unordered_map<std::int32_t, luma::point>{};
|
auto previous_touches = std::unordered_map<std::int32_t, luma::point>{};
|
||||||
auto previous_frame = std::chrono::steady_clock::now();
|
auto previous_frame = std::chrono::steady_clock::now();
|
||||||
|
|||||||
+3
-1
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include <luma/detail/errors.hpp>
|
#include <luma/detail/errors.hpp>
|
||||||
|
|
||||||
|
|
||||||
struct luma::asset_cache::in_flight_load {
|
struct luma::asset_cache::in_flight_load {
|
||||||
std::condition_variable ready{};
|
std::condition_variable ready{};
|
||||||
std::thread::id owner{};
|
std::thread::id owner{};
|
||||||
@@ -23,7 +24,8 @@ struct luma::asset_cache::in_flight_load {
|
|||||||
std::bool_t done{false};
|
std::bool_t done{false};
|
||||||
};
|
};
|
||||||
|
|
||||||
luma::asset_cache::asset_cache(luma::renderer_resources& resources) : resources_{&resources} {
|
luma::asset_cache::asset_cache(luma::renderer_resources &resources)
|
||||||
|
: resources_{&resources} {
|
||||||
assert(resources_ != nullptr);
|
assert(resources_ != nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-4
@@ -15,13 +15,13 @@
|
|||||||
#include <luma/detail/errors.hpp>
|
#include <luma/detail/errors.hpp>
|
||||||
#include <luma/theme.hpp>
|
#include <luma/theme.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr auto json_options = modulus::json_config::options{
|
constexpr auto json_options = modulus::json_config::options{
|
||||||
.category = "luma",
|
.category = "luma",
|
||||||
.invalid_argument_code = luma::detail::error_invalid_argument,
|
.invalid_argument_code = luma::detail::error_invalid_argument,
|
||||||
.not_found_code = luma::detail::error_not_found
|
.not_found_code = luma::detail::error_not_found};
|
||||||
};
|
|
||||||
|
|
||||||
auto invalid_display(std::string message) -> std::expected<luma::display_config, modulus::error> {
|
auto invalid_display(std::string message) -> std::expected<luma::display_config, modulus::error> {
|
||||||
assert(!message.empty());
|
assert(!message.empty());
|
||||||
@@ -93,7 +93,8 @@ auto luma::parse_display_config(boost::json::value const& value) -> std::expecte
|
|||||||
"target_fps",
|
"target_fps",
|
||||||
"idle_fps",
|
"idle_fps",
|
||||||
"fullscreen",
|
"fullscreen",
|
||||||
}, "display", json_options);
|
},
|
||||||
|
"display", json_options);
|
||||||
if (!unknown) {
|
if (!unknown) {
|
||||||
return invalid_display(std::string{unknown.error().message()});
|
return invalid_display(std::string{unknown.error().message()});
|
||||||
}
|
}
|
||||||
@@ -160,7 +161,8 @@ auto luma::parse_application_config(boost::json::value const& value) -> std::exp
|
|||||||
"display",
|
"display",
|
||||||
"touch",
|
"touch",
|
||||||
"theme",
|
"theme",
|
||||||
}, "application config", json_options);
|
},
|
||||||
|
"application config", json_options);
|
||||||
if (!unknown) {
|
if (!unknown) {
|
||||||
return invalid_application(std::string{unknown.error().message()});
|
return invalid_application(std::string{unknown.error().message()});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include <modulus.hpp>
|
#include <modulus.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
auto valid_rect(luma::rect value) -> std::bool_t {
|
auto valid_rect(luma::rect value) -> std::bool_t {
|
||||||
|
|||||||
+46
-30
@@ -27,14 +27,14 @@
|
|||||||
#include <luma/render.hpp>
|
#include <luma/render.hpp>
|
||||||
#include <luma/theme.hpp>
|
#include <luma/theme.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr auto panel_padding = luma::edge_insets{
|
constexpr auto panel_padding = luma::edge_insets{
|
||||||
.left = 8.0F,
|
.left = 8.0F,
|
||||||
.top = 8.0F,
|
.top = 8.0F,
|
||||||
.right = 8.0F,
|
.right = 8.0F,
|
||||||
.bottom = 8.0F
|
.bottom = 8.0F};
|
||||||
};
|
|
||||||
constexpr auto scroll_drag_threshold = std::float32_t{6.0F};
|
constexpr auto scroll_drag_threshold = std::float32_t{6.0F};
|
||||||
|
|
||||||
class label_control final : public luma::control {
|
class label_control final : public luma::control {
|
||||||
@@ -359,7 +359,8 @@ auto fit_rect(luma::rect bounds, luma::texture_info info, luma::image_fit fit) -
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
label_control::label_control(std::string text) : text_{std::move(text)} {
|
label_control::label_control(std::string text)
|
||||||
|
: text_{std::move(text)} {
|
||||||
assert(!text_.empty());
|
assert(!text_.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -375,10 +376,12 @@ auto label_control::draw(luma::draw_context& context, luma::theme const& theme)
|
|||||||
context.draw_text(text_, {
|
context.draw_text(text_, {
|
||||||
.x = bounds().x,
|
.x = bounds().x,
|
||||||
.y = bounds().y,
|
.y = bounds().y,
|
||||||
}, theme.body, enabled() ? theme.text : theme.text_muted);
|
},
|
||||||
|
theme.body, enabled() ? theme.text : theme.text_muted);
|
||||||
}
|
}
|
||||||
|
|
||||||
button_control::button_control(std::string text, std::function<void()> on_click) : text_{std::move(text)}, on_click_{std::move(on_click)} {
|
button_control::button_control(std::string text, std::function<void()> on_click)
|
||||||
|
: text_{std::move(text)}, on_click_{std::move(on_click)} {
|
||||||
assert(!text_.empty());
|
assert(!text_.empty());
|
||||||
assert(on_click_);
|
assert(on_click_);
|
||||||
}
|
}
|
||||||
@@ -390,7 +393,8 @@ auto button_control::measure(luma::draw_context& context, luma::theme const& the
|
|||||||
return luma::clamp({
|
return luma::clamp({
|
||||||
.width = text_size.width + 32.0F,
|
.width = text_size.width + 32.0F,
|
||||||
.height = std::max(std::float32_t{48}, text_size.height + std::float32_t{16}),
|
.height = std::max(std::float32_t{48}, text_size.height + std::float32_t{16}),
|
||||||
}, limits);
|
},
|
||||||
|
limits);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto button_control::draw(luma::draw_context &context, luma::theme const &theme) const -> void {
|
auto button_control::draw(luma::draw_context &context, luma::theme const &theme) const -> void {
|
||||||
@@ -434,7 +438,8 @@ auto button_control::focusable() const -> std::bool_t {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
text_field_control::text_field_control(std::shared_ptr<luma::text_input_state> input) : input_{std::move(input)} {
|
text_field_control::text_field_control(std::shared_ptr<luma::text_input_state> input)
|
||||||
|
: input_{std::move(input)} {
|
||||||
assert(input_ != nullptr);
|
assert(input_ != nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -453,7 +458,8 @@ auto text_field_control::measure(luma::draw_context& context, luma::theme const&
|
|||||||
cached_size_ = luma::clamp({
|
cached_size_ = luma::clamp({
|
||||||
.width = std::max(std::float32_t{240}, measured.width + std::float32_t{24}),
|
.width = std::max(std::float32_t{240}, measured.width + std::float32_t{24}),
|
||||||
.height = std::max(std::float32_t{48}, measured.height + std::float32_t{16}),
|
.height = std::max(std::float32_t{48}, measured.height + std::float32_t{16}),
|
||||||
}, limits);
|
},
|
||||||
|
limits);
|
||||||
return cached_size_;
|
return cached_size_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -470,7 +476,8 @@ auto text_field_control::draw(luma::draw_context& context, luma::theme const& th
|
|||||||
context.draw_text(text, {
|
context.draw_text(text, {
|
||||||
.x = bounds().x + 12.0F,
|
.x = bounds().x + 12.0F,
|
||||||
.y = bounds().y + 8.0F,
|
.y = bounds().y + 8.0F,
|
||||||
}, theme.body, options.text.empty() ? theme.text_muted : theme.text);
|
},
|
||||||
|
theme.body, options.text.empty() ? theme.text_muted : theme.text);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto text_field_control::handle_touch(luma::touch_event const &event) -> std::bool_t {
|
auto text_field_control::handle_touch(luma::touch_event const &event) -> std::bool_t {
|
||||||
@@ -513,12 +520,14 @@ auto text_field_control::focusable() const -> std::bool_t {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
soft_keyboard_control::soft_keyboard_control(luma::keyboard_layout layout, std::function<void(std::string)> on_text, std::function<void()> on_enter) : layout_{std::move(layout)}, on_text_{std::move(on_text)}, on_enter_{std::move(on_enter)} {
|
soft_keyboard_control::soft_keyboard_control(luma::keyboard_layout layout, std::function<void(std::string)> on_text, std::function<void()> on_enter)
|
||||||
|
: layout_{std::move(layout)}, on_text_{std::move(on_text)}, on_enter_{std::move(on_enter)} {
|
||||||
assert(!layout_.rows.empty());
|
assert(!layout_.rows.empty());
|
||||||
assert(on_text_);
|
assert(on_text_);
|
||||||
}
|
}
|
||||||
|
|
||||||
soft_keyboard_control::soft_keyboard_control(luma::keyboard_layout layout, std::shared_ptr<luma::text_input_state> input, std::function<void()> on_enter) : layout_{std::move(layout)}, on_enter_{std::move(on_enter)}, input_{std::move(input)} {
|
soft_keyboard_control::soft_keyboard_control(luma::keyboard_layout layout, std::shared_ptr<luma::text_input_state> input, std::function<void()> on_enter)
|
||||||
|
: layout_{std::move(layout)}, on_enter_{std::move(on_enter)}, input_{std::move(input)} {
|
||||||
assert(!layout_.rows.empty());
|
assert(!layout_.rows.empty());
|
||||||
assert(input_ != nullptr);
|
assert(input_ != nullptr);
|
||||||
}
|
}
|
||||||
@@ -528,7 +537,8 @@ auto soft_keyboard_control::measure(luma::draw_context&, luma::theme const&, lum
|
|||||||
return luma::clamp({
|
return luma::clamp({
|
||||||
.width = 640.0F,
|
.width = 640.0F,
|
||||||
.height = static_cast<std::float32_t>(layout_.rows.size()) * 56.0F,
|
.height = static_cast<std::float32_t>(layout_.rows.size()) * 56.0F,
|
||||||
}, limits);
|
},
|
||||||
|
limits);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto soft_keyboard_control::draw(luma::draw_context &context, luma::theme const &theme) const -> void {
|
auto soft_keyboard_control::draw(luma::draw_context &context, luma::theme const &theme) const -> void {
|
||||||
@@ -551,7 +561,8 @@ auto soft_keyboard_control::draw(luma::draw_context& context, luma::theme const&
|
|||||||
context.draw_text(row[column_index].label, {
|
context.draw_text(row[column_index].label, {
|
||||||
.x = rect.x + 12.0F,
|
.x = rect.x + 12.0F,
|
||||||
.y = rect.y + 10.0F,
|
.y = rect.y + 10.0F,
|
||||||
}, theme.body, theme.text);
|
},
|
||||||
|
theme.body, theme.text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -604,7 +615,8 @@ auto soft_keyboard_control::handle_touch(luma::touch_event const& event) -> std:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
panel_control::panel_control(std::vector<std::unique_ptr<luma::control>> children) : children_{std::move(children)} {}
|
panel_control::panel_control(std::vector<std::unique_ptr<luma::control>> children)
|
||||||
|
: children_{std::move(children)} {}
|
||||||
|
|
||||||
auto panel_control::measure(luma::draw_context &context, luma::theme const &theme, luma::constraints limits) -> luma::size {
|
auto panel_control::measure(luma::draw_context &context, luma::theme const &theme, luma::constraints limits) -> luma::size {
|
||||||
assert(finite_constraints(limits));
|
assert(finite_constraints(limits));
|
||||||
@@ -658,7 +670,8 @@ auto panel_control::bind_layout_invalidator(std::function<void()> invalidator) -
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
spacer_control::spacer_control(luma::size value) : value_{value} {
|
spacer_control::spacer_control(luma::size value)
|
||||||
|
: value_{value} {
|
||||||
assert(finite_size(value_));
|
assert(finite_size(value_));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -669,7 +682,8 @@ auto spacer_control::measure(luma::draw_context&, luma::theme const&, luma::cons
|
|||||||
|
|
||||||
auto spacer_control::draw(luma::draw_context &, luma::theme const &) const -> void {}
|
auto spacer_control::draw(luma::draw_context &, luma::theme const &) const -> void {}
|
||||||
|
|
||||||
progress_bar_control::progress_bar_control(std::float32_t value) : value_{std::clamp(value, std::float32_t{}, std::float32_t{1})} {
|
progress_bar_control::progress_bar_control(std::float32_t value)
|
||||||
|
: value_{std::clamp(value, std::float32_t{}, std::float32_t{1})} {
|
||||||
assert(std::isfinite(value));
|
assert(std::isfinite(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -678,7 +692,8 @@ auto progress_bar_control::measure(luma::draw_context&, luma::theme const&, luma
|
|||||||
return luma::clamp({
|
return luma::clamp({
|
||||||
.width = 160.0F,
|
.width = 160.0F,
|
||||||
.height = 16.0F,
|
.height = 16.0F,
|
||||||
}, limits);
|
},
|
||||||
|
limits);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto progress_bar_control::draw(luma::draw_context &context, luma::theme const &theme) const -> void {
|
auto progress_bar_control::draw(luma::draw_context &context, luma::theme const &theme) const -> void {
|
||||||
@@ -688,10 +703,12 @@ auto progress_bar_control::draw(luma::draw_context& context, luma::theme const&
|
|||||||
.y = bounds().y,
|
.y = bounds().y,
|
||||||
.width = bounds().width * value_,
|
.width = bounds().width * value_,
|
||||||
.height = bounds().height,
|
.height = bounds().height,
|
||||||
}, theme.accent);
|
},
|
||||||
|
theme.accent);
|
||||||
}
|
}
|
||||||
|
|
||||||
image_control::image_control(std::shared_ptr<luma::texture> texture, luma::image_fit fit) : texture_{std::move(texture)}, fit_{fit} {
|
image_control::image_control(std::shared_ptr<luma::texture> texture, luma::image_fit fit)
|
||||||
|
: texture_{std::move(texture)}, fit_{fit} {
|
||||||
assert(texture_ != nullptr);
|
assert(texture_ != nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -704,7 +721,8 @@ auto image_control::measure(luma::draw_context&, luma::theme const&, luma::const
|
|||||||
return luma::clamp({
|
return luma::clamp({
|
||||||
.width = static_cast<std::float32_t>(info.width),
|
.width = static_cast<std::float32_t>(info.width),
|
||||||
.height = static_cast<std::float32_t>(info.height),
|
.height = static_cast<std::float32_t>(info.height),
|
||||||
}, limits);
|
},
|
||||||
|
limits);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto image_control::draw(luma::draw_context &context, luma::theme const &theme) const -> void {
|
auto image_control::draw(luma::draw_context &context, luma::theme const &theme) const -> void {
|
||||||
@@ -721,7 +739,8 @@ auto image_control::draw(luma::draw_context& context, luma::theme const& theme)
|
|||||||
context.draw_texture(*texture_, source, fit_rect(bounds(), info, fit_), theme.text);
|
context.draw_texture(*texture_, source, fit_rect(bounds(), info, fit_), theme.text);
|
||||||
}
|
}
|
||||||
|
|
||||||
linear_control::linear_control(luma::direction direction, std::vector<std::unique_ptr<luma::control>> children, std::float32_t gap, luma::alignment align) : direction_{direction}, children_{std::move(children)}, gap_{gap}, align_{align} {
|
linear_control::linear_control(luma::direction direction, std::vector<std::unique_ptr<luma::control>> children, std::float32_t gap, luma::alignment align)
|
||||||
|
: direction_{direction}, children_{std::move(children)}, gap_{gap}, align_{align} {
|
||||||
assert(std::isfinite(gap_));
|
assert(std::isfinite(gap_));
|
||||||
assert(gap_ >= 0.0F);
|
assert(gap_ >= 0.0F);
|
||||||
}
|
}
|
||||||
@@ -818,8 +837,8 @@ auto linear_control::bind_layout_invalidator(std::function<void()> invalidator)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stack_control::stack_control(std::vector<std::unique_ptr<luma::control>> children)
|
||||||
stack_control::stack_control(std::vector<std::unique_ptr<luma::control>> children) : children_{std::move(children)} {}
|
: children_{std::move(children)} {}
|
||||||
|
|
||||||
auto stack_control::measure(luma::draw_context &context, luma::theme const &theme, luma::constraints limits) -> luma::size {
|
auto stack_control::measure(luma::draw_context &context, luma::theme const &theme, luma::constraints limits) -> luma::size {
|
||||||
assert(finite_constraints(limits));
|
assert(finite_constraints(limits));
|
||||||
@@ -868,8 +887,8 @@ auto stack_control::bind_layout_invalidator(std::function<void()> invalidator) -
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scroll_view_control::scroll_view_control(std::unique_ptr<luma::control> child, std::bool_t vertical, std::bool_t horizontal)
|
||||||
scroll_view_control::scroll_view_control(std::unique_ptr<luma::control> child, std::bool_t vertical, std::bool_t horizontal) : child_{std::move(child)}, vertical_{vertical}, horizontal_{horizontal} {
|
: child_{std::move(child)}, vertical_{vertical}, horizontal_{horizontal} {
|
||||||
assert(child_ != nullptr);
|
assert(child_ != nullptr);
|
||||||
assert(vertical_ || horizontal_);
|
assert(vertical_ || horizontal_);
|
||||||
}
|
}
|
||||||
@@ -938,13 +957,11 @@ auto scroll_view_control::handle_point(luma::touch_event const& event, luma::tou
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto found = touches_.find(point.id);
|
auto found = touches_.find(point.id);
|
||||||
if (found == touches_.end()) {
|
if (found == touches_.end()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto &state = found->second;
|
auto &state = found->second;
|
||||||
|
|
||||||
if (point.phase == luma::touch_phase::MOVE) {
|
if (point.phase == luma::touch_phase::MOVE) {
|
||||||
auto delta = luma::point{
|
auto delta = luma::point{
|
||||||
.x = point.position.x - state.last.x,
|
.x = point.position.x - state.last.x,
|
||||||
@@ -994,7 +1011,6 @@ auto scroll_view_control::handle_point(luma::touch_event const& event, luma::tou
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (point.phase == luma::touch_phase::UP || point.phase == luma::touch_phase::CANCEL) {
|
if (point.phase == luma::touch_phase::UP || point.phase == luma::touch_phase::CANCEL) {
|
||||||
auto const scrolling = scroll_id_ == point.id && dragging_;
|
auto const scrolling = scroll_id_ == point.id && dragging_;
|
||||||
if (state.child_active) {
|
if (state.child_active) {
|
||||||
@@ -1015,7 +1031,6 @@ auto scroll_view_control::handle_point(luma::touch_event const& event, luma::tou
|
|||||||
touches_.erase(found);
|
touches_.erase(found);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1135,7 +1150,8 @@ auto collect_layout_listeners(std::vector<luma::text_input_state::layout_listene
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
luma::text_input_state::text_input_state(luma::text_field_options options, std::function<void(std::string)> on_change) : options_{std::move(options)}, on_change_{std::move(on_change)} {
|
luma::text_input_state::text_input_state(luma::text_field_options options, std::function<void(std::string)> on_change)
|
||||||
|
: options_{std::move(options)}, on_change_{std::move(on_change)} {
|
||||||
assert(options_.max_length > 0);
|
assert(options_.max_length > 0);
|
||||||
assert(on_change_);
|
assert(on_change_);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include <modulus.hpp>
|
#include <modulus.hpp>
|
||||||
|
|
||||||
|
|
||||||
auto luma::detail::make_error(std::int32_t code, std::string message, modulus::source_location location) -> modulus::error {
|
auto luma::detail::make_error(std::int32_t code, std::string message, modulus::source_location location) -> modulus::error {
|
||||||
return modulus::make_error("luma", code, std::move(message), location);
|
return modulus::make_error("luma", code, std::move(message), location);
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-5
@@ -17,6 +17,7 @@
|
|||||||
#include <luma/render.hpp>
|
#include <luma/render.hpp>
|
||||||
#include <luma/theme.hpp>
|
#include <luma/theme.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
class scope_exit {
|
class scope_exit {
|
||||||
@@ -89,7 +90,8 @@ auto draw_button(luma::draw_context& context, luma::theme const& theme, luma::re
|
|||||||
context.draw_text(text, {
|
context.draw_text(text, {
|
||||||
.x = bounds.x + (bounds.width - measured.width) * 0.5F,
|
.x = bounds.x + (bounds.width - measured.width) * 0.5F,
|
||||||
.y = bounds.y + (bounds.height - measured.height) * 0.5F,
|
.y = bounds.y + (bounds.height - measured.height) * 0.5F,
|
||||||
}, theme.body, theme.text);
|
},
|
||||||
|
theme.body, theme.text);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto first_point_inside(luma::touch_event const &event, luma::rect bounds, luma::touch_phase phase) -> luma::touch_point const * {
|
auto first_point_inside(luma::touch_event const &event, luma::rect bounds, luma::touch_phase phase) -> luma::touch_point const * {
|
||||||
@@ -116,7 +118,8 @@ auto throw_if_failed(std::expected<void, modulus::error> const& status) -> void
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
scope_exit::scope_exit(std::function<void()> action) : action_{std::move(action)} {}
|
scope_exit::scope_exit(std::function<void()> action)
|
||||||
|
: action_{std::move(action)} {}
|
||||||
|
|
||||||
scope_exit::~scope_exit() {
|
scope_exit::~scope_exit() {
|
||||||
if (action_) {
|
if (action_) {
|
||||||
@@ -126,7 +129,8 @@ scope_exit::~scope_exit() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
luma::overlay_host::overlay_host(std::unique_ptr<luma::control> content) : content_{std::move(content)} {
|
luma::overlay_host::overlay_host(std::unique_ptr<luma::control> content)
|
||||||
|
: content_{std::move(content)} {
|
||||||
assert(content_ != nullptr);
|
assert(content_ != nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -278,7 +282,8 @@ auto luma::overlay_host::draw(luma::draw_context& context, luma::theme const& th
|
|||||||
context.draw_text(title, {
|
context.draw_text(title, {
|
||||||
.x = dialog.x + 16.0F,
|
.x = dialog.x + 16.0F,
|
||||||
.y = dialog.y + 16.0F,
|
.y = dialog.y + 16.0F,
|
||||||
}, theme.title, theme.text);
|
},
|
||||||
|
theme.title, theme.text);
|
||||||
body->draw(context, theme);
|
body->draw(context, theme);
|
||||||
auto has_cancel = !cancel_text.empty();
|
auto has_cancel = !cancel_text.empty();
|
||||||
if (has_cancel) {
|
if (has_cancel) {
|
||||||
@@ -297,7 +302,8 @@ auto luma::overlay_host::draw(luma::draw_context& context, luma::theme const& th
|
|||||||
context.draw_text(toasts_.front().message, {
|
context.draw_text(toasts_.front().message, {
|
||||||
.x = toast_bounds.x + 16.0F,
|
.x = toast_bounds.x + 16.0F,
|
||||||
.y = toast_bounds.y + 10.0F,
|
.y = toast_bounds.y + 10.0F,
|
||||||
}, theme.body, theme.text);
|
},
|
||||||
|
theme.body, theme.text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include <luma/detail/errors.hpp>
|
#include <luma/detail/errors.hpp>
|
||||||
|
|
||||||
|
|
||||||
auto luma::router::register_route(std::string name, std::function<std::expected<std::unique_ptr<luma::control>, modulus::error>()> factory) -> std::expected<void, modulus::error> {
|
auto luma::router::register_route(std::string name, std::function<std::expected<std::unique_ptr<luma::control>, modulus::error>()> factory) -> std::expected<void, modulus::error> {
|
||||||
if (name.empty()) {
|
if (name.empty()) {
|
||||||
return luma::detail::fail<void>(luma::detail::error_invalid_argument, "route name must not be empty");
|
return luma::detail::fail<void>(luma::detail::error_invalid_argument, "route name must not be empty");
|
||||||
|
|||||||
+8
-5
@@ -16,13 +16,13 @@
|
|||||||
|
|
||||||
#include <luma/detail/errors.hpp>
|
#include <luma/detail/errors.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr auto json_options = modulus::json_config::options{
|
constexpr auto json_options = modulus::json_config::options{
|
||||||
.category = "luma",
|
.category = "luma",
|
||||||
.invalid_argument_code = luma::detail::error_invalid_argument,
|
.invalid_argument_code = luma::detail::error_invalid_argument,
|
||||||
.not_found_code = luma::detail::error_not_found
|
.not_found_code = luma::detail::error_not_found};
|
||||||
};
|
|
||||||
|
|
||||||
auto invalid_color(std::string message) -> std::expected<luma::color, modulus::error> {
|
auto invalid_color(std::string message) -> std::expected<luma::color, modulus::error> {
|
||||||
assert(!message.empty());
|
assert(!message.empty());
|
||||||
@@ -73,7 +73,8 @@ auto apply_text_style(boost::json::object const& object, std::char_t const* name
|
|||||||
"font",
|
"font",
|
||||||
"size",
|
"size",
|
||||||
"line_height",
|
"line_height",
|
||||||
}, name, json_options);
|
},
|
||||||
|
name, json_options);
|
||||||
if (!unknown) {
|
if (!unknown) {
|
||||||
return modulus::fail<void>(unknown.error());
|
return modulus::fail<void>(unknown.error());
|
||||||
}
|
}
|
||||||
@@ -157,7 +158,8 @@ auto luma::parse_color(boost::json::value const& value) -> std::expected<luma::c
|
|||||||
"g",
|
"g",
|
||||||
"b",
|
"b",
|
||||||
"a",
|
"a",
|
||||||
}, "color", json_options);
|
},
|
||||||
|
"color", json_options);
|
||||||
if (!unknown) {
|
if (!unknown) {
|
||||||
return invalid_color(std::string{unknown.error().message()});
|
return invalid_color(std::string{unknown.error().message()});
|
||||||
}
|
}
|
||||||
@@ -212,7 +214,8 @@ auto luma::parse_theme(boost::json::value const& value) -> std::expected<luma::t
|
|||||||
"title",
|
"title",
|
||||||
"radius",
|
"radius",
|
||||||
"spacing",
|
"spacing",
|
||||||
}, "theme", json_options);
|
},
|
||||||
|
"theme", json_options);
|
||||||
if (!unknown) {
|
if (!unknown) {
|
||||||
return invalid_theme(std::string{unknown.error().message()});
|
return invalid_theme(std::string{unknown.error().message()});
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-4
@@ -19,6 +19,7 @@
|
|||||||
#include <luma/render.hpp>
|
#include <luma/render.hpp>
|
||||||
#include <luma/theme.hpp>
|
#include <luma/theme.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
class scope_exit {
|
class scope_exit {
|
||||||
@@ -84,7 +85,8 @@ auto make_event(luma::touch_event const& event, luma::touch_point point) -> luma
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
scope_exit::scope_exit(std::function<void()> action) : action_{std::move(action)} {}
|
scope_exit::scope_exit(std::function<void()> action)
|
||||||
|
: action_{std::move(action)} {}
|
||||||
|
|
||||||
scope_exit::~scope_exit() {
|
scope_exit::~scope_exit() {
|
||||||
if (action_) {
|
if (action_) {
|
||||||
@@ -94,7 +96,8 @@ scope_exit::~scope_exit() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
luma::window::window(std::uint64_t id, luma::window_options options, std::unique_ptr<luma::control> content) : id_{id}, options_{std::move(options)}, content_{std::move(content)} {
|
luma::window::window(std::uint64_t id, luma::window_options options, std::unique_ptr<luma::control> content)
|
||||||
|
: id_{id}, options_{std::move(options)}, content_{std::move(content)} {
|
||||||
assert(id_ != 0);
|
assert(id_ != 0);
|
||||||
assert(finite_rect(options_.bounds));
|
assert(finite_rect(options_.bounds));
|
||||||
assert(content_ != nullptr);
|
assert(content_ != nullptr);
|
||||||
@@ -335,7 +338,8 @@ auto luma::window_manager::draw(luma::draw_context& context, luma::theme const&
|
|||||||
context.draw_text(window->options().title, {
|
context.draw_text(window->options().title, {
|
||||||
.x = title.x + 8.0F,
|
.x = title.x + 8.0F,
|
||||||
.y = title.y + window_title_vertical_padding,
|
.y = title.y + window_title_vertical_padding,
|
||||||
}, theme.body, theme.text);
|
},
|
||||||
|
theme.body, theme.text);
|
||||||
}
|
}
|
||||||
context.stroke_rect(bounds, 1.0F, theme.border);
|
context.stroke_rect(bounds, 1.0F, theme.border);
|
||||||
}
|
}
|
||||||
@@ -368,7 +372,6 @@ auto luma::window_manager::handle_touch(luma::touch_event const& event) -> std::
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto current = windows_.rbegin(); current != windows_.rend(); ++current) {
|
for (auto current = windows_.rbegin(); current != windows_.rend(); ++current) {
|
||||||
assert(*current != nullptr);
|
assert(*current != nullptr);
|
||||||
if (!(*current)->visible()) {
|
if (!(*current)->visible()) {
|
||||||
|
|||||||
+69
-33
@@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#include <test.hpp>
|
#include <test.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
struct fake_draw_context final : public luma::draw_context {
|
struct fake_draw_context final : public luma::draw_context {
|
||||||
@@ -268,7 +269,8 @@ auto fake_draw_context::measure_text(std::string_view text, luma::text_style con
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fixed_control::fixed_control(luma::size value) : value_{value} {}
|
fixed_control::fixed_control(luma::size value)
|
||||||
|
: value_{value} {}
|
||||||
|
|
||||||
auto fixed_control::measure(luma::draw_context &, luma::theme const &, luma::constraints) -> luma::size {
|
auto fixed_control::measure(luma::draw_context &, luma::theme const &, luma::constraints) -> luma::size {
|
||||||
return value_;
|
return value_;
|
||||||
@@ -292,7 +294,8 @@ auto fixed_control::handle_touch(luma::touch_event const& event) -> std::bool_t
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
counting_control::counting_control(luma::size value) : value_{value} {}
|
counting_control::counting_control(luma::size value)
|
||||||
|
: value_{value} {}
|
||||||
|
|
||||||
auto counting_control::measure(luma::draw_context &, luma::theme const &, luma::constraints) -> luma::size {
|
auto counting_control::measure(luma::draw_context &, luma::theme const &, luma::constraints) -> luma::size {
|
||||||
++measure_count;
|
++measure_count;
|
||||||
@@ -325,7 +328,8 @@ auto filling_control::measure(luma::draw_context&, luma::theme const&, luma::con
|
|||||||
return luma::clamp({
|
return luma::clamp({
|
||||||
.width = 20.0F,
|
.width = 20.0F,
|
||||||
.height = 20.0F,
|
.height = 20.0F,
|
||||||
}, limits);
|
},
|
||||||
|
limits);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto filling_control::arrange(luma::rect bounds) -> void {
|
auto filling_control::arrange(luma::rect bounds) -> void {
|
||||||
@@ -337,7 +341,8 @@ auto filling_control::draw(luma::draw_context& context, luma::theme const&) cons
|
|||||||
context.fill_rect(bounds(), {});
|
context.fill_rect(bounds(), {});
|
||||||
}
|
}
|
||||||
|
|
||||||
fake_texture::fake_texture(std::int32_t width, std::int32_t height) : info_{.width = width, .height = height} {}
|
fake_texture::fake_texture(std::int32_t width, std::int32_t height)
|
||||||
|
: info_{.width = width, .height = height} {}
|
||||||
|
|
||||||
auto fake_texture::info() const -> luma::texture_info {
|
auto fake_texture::info() const -> luma::texture_info {
|
||||||
return info_;
|
return info_;
|
||||||
@@ -414,7 +419,8 @@ auto recording_control::handle_touch(luma::touch_event const& event) -> std::boo
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy_probe_control::destroy_probe_control(std::shared_ptr<lifetime_state> state) : state_{std::move(state)} {}
|
destroy_probe_control::destroy_probe_control(std::shared_ptr<lifetime_state> state)
|
||||||
|
: state_{std::move(state)} {}
|
||||||
|
|
||||||
destroy_probe_control::~destroy_probe_control() {
|
destroy_probe_control::~destroy_probe_control() {
|
||||||
state_->destroyed = true;
|
state_->destroyed = true;
|
||||||
@@ -432,7 +438,8 @@ auto destroy_probe_control::measure(luma::draw_context&, luma::theme const&, lum
|
|||||||
|
|
||||||
auto destroy_probe_control::draw(luma::draw_context &, luma::theme const &) const -> void {}
|
auto destroy_probe_control::draw(luma::draw_context &, luma::theme const &) const -> void {}
|
||||||
|
|
||||||
closing_window_control::closing_window_control(luma::window_manager& manager, std::uint64_t& id, std::shared_ptr<lifetime_state> state) : manager_{manager}, id_{id}, state_{std::move(state)} {}
|
closing_window_control::closing_window_control(luma::window_manager &manager, std::uint64_t &id, std::shared_ptr<lifetime_state> state)
|
||||||
|
: manager_{manager}, id_{id}, state_{std::move(state)} {}
|
||||||
|
|
||||||
closing_window_control::~closing_window_control() {
|
closing_window_control::~closing_window_control() {
|
||||||
state_->destroyed = true;
|
state_->destroyed = true;
|
||||||
@@ -458,7 +465,8 @@ auto closing_window_control::handle_touch(luma::touch_event const&) -> std::bool
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
opening_window_control::opening_window_control(luma::window_manager& manager, std::shared_ptr<lifetime_state> state) : manager_{manager}, state_{std::move(state)} {}
|
opening_window_control::opening_window_control(luma::window_manager &manager, std::shared_ptr<lifetime_state> state)
|
||||||
|
: manager_{manager}, state_{std::move(state)} {}
|
||||||
|
|
||||||
auto opening_window_control::measure(luma::draw_context &, luma::theme const &, luma::constraints) -> luma::size {
|
auto opening_window_control::measure(luma::draw_context &, luma::theme const &, luma::constraints) -> luma::size {
|
||||||
return {
|
return {
|
||||||
@@ -478,7 +486,8 @@ auto opening_window_control::handle_touch(luma::touch_event const&) -> std::bool
|
|||||||
.width = 50.0F,
|
.width = 50.0F,
|
||||||
.height = 50.0F,
|
.height = 50.0F,
|
||||||
},
|
},
|
||||||
}, std::make_unique<recording_control>());
|
},
|
||||||
|
std::make_unique<recording_control>());
|
||||||
state_->status_ok = opened.has_value();
|
state_->status_ok = opened.has_value();
|
||||||
if (opened) {
|
if (opened) {
|
||||||
state_->opened_id = *opened;
|
state_->opened_id = *opened;
|
||||||
@@ -487,7 +496,8 @@ auto opening_window_control::handle_touch(luma::touch_event const&) -> std::bool
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
updating_window_control::updating_window_control(luma::window_manager& manager, std::uint64_t& id, std::shared_ptr<lifetime_state> state) : manager_{manager}, id_{id}, state_{std::move(state)} {}
|
updating_window_control::updating_window_control(luma::window_manager &manager, std::uint64_t &id, std::shared_ptr<lifetime_state> state)
|
||||||
|
: manager_{manager}, id_{id}, state_{std::move(state)} {}
|
||||||
|
|
||||||
auto updating_window_control::measure(luma::draw_context &, luma::theme const &, luma::constraints) -> luma::size {
|
auto updating_window_control::measure(luma::draw_context &, luma::theme const &, luma::constraints) -> luma::size {
|
||||||
return {
|
return {
|
||||||
@@ -513,7 +523,8 @@ auto updating_window_control::handle_touch(luma::touch_event const&) -> std::boo
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
closing_dialog_control::closing_dialog_control(luma::overlay_host& host, std::shared_ptr<lifetime_state> state, close_phase phase) : host_{host}, state_{std::move(state)}, phase_{phase} {}
|
closing_dialog_control::closing_dialog_control(luma::overlay_host &host, std::shared_ptr<lifetime_state> state, close_phase phase)
|
||||||
|
: host_{host}, state_{std::move(state)}, phase_{phase} {}
|
||||||
|
|
||||||
closing_dialog_control::~closing_dialog_control() {
|
closing_dialog_control::~closing_dialog_control() {
|
||||||
state_->destroyed = true;
|
state_->destroyed = true;
|
||||||
@@ -558,7 +569,8 @@ auto closing_dialog_control::close_if(close_phase phase) const -> void {
|
|||||||
state_->in_handle = false;
|
state_->in_handle = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
replacing_root_invalidate_control::replacing_root_invalidate_control(luma::application& app, std::shared_ptr<lifetime_state> state) : app_{app}, state_{std::move(state)} {}
|
replacing_root_invalidate_control::replacing_root_invalidate_control(luma::application &app, std::shared_ptr<lifetime_state> state)
|
||||||
|
: app_{app}, state_{std::move(state)} {}
|
||||||
|
|
||||||
replacing_root_invalidate_control::~replacing_root_invalidate_control() {
|
replacing_root_invalidate_control::~replacing_root_invalidate_control() {
|
||||||
state_->destroyed = true;
|
state_->destroyed = true;
|
||||||
@@ -584,7 +596,8 @@ auto replacing_root_invalidate_control::invalidate_layout() -> void {
|
|||||||
state_->in_handle = false;
|
state_->in_handle = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
closing_window_invalidate_control::closing_window_invalidate_control(luma::window_manager& manager, std::uint64_t& id, std::shared_ptr<lifetime_state> state) : manager_{manager}, id_{id}, state_{std::move(state)} {}
|
closing_window_invalidate_control::closing_window_invalidate_control(luma::window_manager &manager, std::uint64_t &id, std::shared_ptr<lifetime_state> state)
|
||||||
|
: manager_{manager}, id_{id}, state_{std::move(state)} {}
|
||||||
|
|
||||||
closing_window_invalidate_control::~closing_window_invalidate_control() {
|
closing_window_invalidate_control::~closing_window_invalidate_control() {
|
||||||
state_->destroyed = true;
|
state_->destroyed = true;
|
||||||
@@ -599,6 +612,7 @@ auto closing_window_invalidate_control::measure(luma::draw_context&, luma::theme
|
|||||||
.height = 20.0F,
|
.height = 20.0F,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
auto closing_window_invalidate_control::draw(luma::draw_context &, luma::theme const &) const -> void {}
|
auto closing_window_invalidate_control::draw(luma::draw_context &, luma::theme const &) const -> void {}
|
||||||
|
|
||||||
auto closing_window_invalidate_control::invalidate_layout() -> void {
|
auto closing_window_invalidate_control::invalidate_layout() -> void {
|
||||||
@@ -835,7 +849,8 @@ BOOST_AUTO_TEST_CASE(text_controls_measure_with_supplied_theme) {
|
|||||||
BOOST_TEST(large_button.height > small_button.height);
|
BOOST_TEST(large_button.height > small_button.height);
|
||||||
auto field = luma::text_field({
|
auto field = luma::text_field({
|
||||||
.text = "Scale",
|
.text = "Scale",
|
||||||
}, [](std::string) {});
|
},
|
||||||
|
[](std::string) {});
|
||||||
BOOST_REQUIRE(field);
|
BOOST_REQUIRE(field);
|
||||||
auto small_field = (*field)->measure(context, small, {
|
auto small_field = (*field)->measure(context, small, {
|
||||||
.max = {
|
.max = {
|
||||||
@@ -882,6 +897,7 @@ BOOST_AUTO_TEST_CASE(application_dispatch_serializes_concurrent_callers) {
|
|||||||
BOOST_REQUIRE(result);
|
BOOST_REQUIRE(result);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &thread : threads) {
|
for (auto &thread : threads) {
|
||||||
thread.join();
|
thread.join();
|
||||||
}
|
}
|
||||||
@@ -959,7 +975,8 @@ BOOST_AUTO_TEST_CASE(custom_control_unique_ptr_overloads_are_unambiguous) {
|
|||||||
auto children = luma::children(std::make_unique<fixed_control>(luma::size{
|
auto children = luma::children(std::make_unique<fixed_control>(luma::size{
|
||||||
.width = 10.0F,
|
.width = 10.0F,
|
||||||
.height = 10.0F,
|
.height = 10.0F,
|
||||||
}), luma::label("Label"));
|
}),
|
||||||
|
luma::label("Label"));
|
||||||
BOOST_REQUIRE(children);
|
BOOST_REQUIRE(children);
|
||||||
BOOST_TEST(children->size() == 2U);
|
BOOST_TEST(children->size() == 2U);
|
||||||
}
|
}
|
||||||
@@ -969,7 +986,8 @@ BOOST_AUTO_TEST_CASE(factory_validation_returns_errors) {
|
|||||||
BOOST_TEST(!luma::button("OK", {}));
|
BOOST_TEST(!luma::button("OK", {}));
|
||||||
BOOST_TEST(!luma::text_field({
|
BOOST_TEST(!luma::text_field({
|
||||||
.max_length = 0,
|
.max_length = 0,
|
||||||
}, [](std::string) {}));
|
},
|
||||||
|
[](std::string) {}));
|
||||||
BOOST_TEST(!luma::image(nullptr));
|
BOOST_TEST(!luma::image(nullptr));
|
||||||
BOOST_TEST(!luma::image(std::make_shared<fake_texture>(0, 16)));
|
BOOST_TEST(!luma::image(std::make_shared<fake_texture>(0, 16)));
|
||||||
BOOST_TEST(!luma::scroll_view(std::unique_ptr<luma::control>{}));
|
BOOST_TEST(!luma::scroll_view(std::unique_ptr<luma::control>{}));
|
||||||
@@ -1066,7 +1084,8 @@ BOOST_AUTO_TEST_CASE(text_input_state_filters_modes_and_keyboard_updates_bound_f
|
|||||||
auto input = luma::make_text_input({
|
auto input = luma::make_text_input({
|
||||||
.mode = luma::text_input_mode::INTEGER,
|
.mode = luma::text_input_mode::INTEGER,
|
||||||
.max_length = 3,
|
.max_length = 3,
|
||||||
}, [&](std::string text) {
|
},
|
||||||
|
[&](std::string text) {
|
||||||
changes.push_back(std::move(text));
|
changes.push_back(std::move(text));
|
||||||
});
|
});
|
||||||
BOOST_REQUIRE(input);
|
BOOST_REQUIRE(input);
|
||||||
@@ -1089,7 +1108,8 @@ BOOST_AUTO_TEST_CASE(text_input_state_filters_modes_and_keyboard_updates_bound_f
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}, *input);
|
},
|
||||||
|
*input);
|
||||||
BOOST_REQUIRE(keyboard);
|
BOOST_REQUIRE(keyboard);
|
||||||
(*keyboard)->arrange({
|
(*keyboard)->arrange({
|
||||||
.x = 0.0F,
|
.x = 0.0F,
|
||||||
@@ -1129,7 +1149,8 @@ BOOST_AUTO_TEST_CASE(text_input_state_filters_modes_and_keyboard_updates_bound_f
|
|||||||
BOOST_AUTO_TEST_CASE(decimal_text_input_accepts_one_decimal_point) {
|
BOOST_AUTO_TEST_CASE(decimal_text_input_accepts_one_decimal_point) {
|
||||||
auto input = luma::make_text_input({
|
auto input = luma::make_text_input({
|
||||||
.mode = luma::text_input_mode::DECIMAL,
|
.mode = luma::text_input_mode::DECIMAL,
|
||||||
}, [](std::string) {});
|
},
|
||||||
|
[](std::string) {});
|
||||||
BOOST_REQUIRE(input);
|
BOOST_REQUIRE(input);
|
||||||
BOOST_REQUIRE((*input)->append("1.5"));
|
BOOST_REQUIRE((*input)->append("1.5"));
|
||||||
BOOST_TEST(!(*input)->append("."));
|
BOOST_TEST(!(*input)->append("."));
|
||||||
@@ -1150,7 +1171,8 @@ BOOST_AUTO_TEST_CASE(text_input_callback_exceptions_return_errors) {
|
|||||||
BOOST_AUTO_TEST_CASE(text_input_state_notifies_bound_layout_invalidator) {
|
BOOST_AUTO_TEST_CASE(text_input_state_notifies_bound_layout_invalidator) {
|
||||||
auto input = luma::make_text_input({
|
auto input = luma::make_text_input({
|
||||||
.text = "a",
|
.text = "a",
|
||||||
}, [](std::string) {});
|
},
|
||||||
|
[](std::string) {});
|
||||||
BOOST_REQUIRE(input);
|
BOOST_REQUIRE(input);
|
||||||
auto field = luma::text_field(*input);
|
auto field = luma::text_field(*input);
|
||||||
BOOST_REQUIRE(field);
|
BOOST_REQUIRE(field);
|
||||||
@@ -1172,7 +1194,8 @@ BOOST_AUTO_TEST_CASE(text_input_state_notifies_bound_layout_invalidator) {
|
|||||||
BOOST_AUTO_TEST_CASE(text_field_layout_invalidator_propagates_through_containers) {
|
BOOST_AUTO_TEST_CASE(text_field_layout_invalidator_propagates_through_containers) {
|
||||||
auto input = luma::make_text_input({
|
auto input = luma::make_text_input({
|
||||||
.text = "a",
|
.text = "a",
|
||||||
}, [](std::string) {});
|
},
|
||||||
|
[](std::string) {});
|
||||||
BOOST_REQUIRE(input);
|
BOOST_REQUIRE(input);
|
||||||
auto field = luma::text_field(*input);
|
auto field = luma::text_field(*input);
|
||||||
BOOST_REQUIRE(field);
|
BOOST_REQUIRE(field);
|
||||||
@@ -1407,7 +1430,8 @@ BOOST_AUTO_TEST_CASE(window_manager_captures_touch_by_id) {
|
|||||||
.width = 100.0F,
|
.width = 100.0F,
|
||||||
.height = 100.0F,
|
.height = 100.0F,
|
||||||
},
|
},
|
||||||
}, std::move(content));
|
},
|
||||||
|
std::move(content));
|
||||||
BOOST_REQUIRE(id);
|
BOOST_REQUIRE(id);
|
||||||
BOOST_TEST(*id != 0U);
|
BOOST_TEST(*id != 0U);
|
||||||
BOOST_TEST(manager.handle_touch({
|
BOOST_TEST(manager.handle_touch({
|
||||||
@@ -1459,7 +1483,8 @@ BOOST_AUTO_TEST_CASE(window_set_bounds_validates_release_inputs) {
|
|||||||
.width = 100.0F,
|
.width = 100.0F,
|
||||||
.height = 100.0F,
|
.height = 100.0F,
|
||||||
},
|
},
|
||||||
}, std::make_unique<recording_control>());
|
},
|
||||||
|
std::make_unique<recording_control>());
|
||||||
BOOST_REQUIRE(id);
|
BOOST_REQUIRE(id);
|
||||||
auto *window = manager.find(*id);
|
auto *window = manager.find(*id);
|
||||||
BOOST_REQUIRE(window != nullptr);
|
BOOST_REQUIRE(window != nullptr);
|
||||||
@@ -1497,7 +1522,8 @@ BOOST_AUTO_TEST_CASE(window_manager_uses_decorated_client_area_for_content) {
|
|||||||
.width = 100.0F,
|
.width = 100.0F,
|
||||||
.height = 80.0F,
|
.height = 80.0F,
|
||||||
},
|
},
|
||||||
}, std::move(content));
|
},
|
||||||
|
std::move(content));
|
||||||
BOOST_REQUIRE(id);
|
BOOST_REQUIRE(id);
|
||||||
manager.measure(context, theme, {
|
manager.measure(context, theme, {
|
||||||
.max = {
|
.max = {
|
||||||
@@ -1541,7 +1567,8 @@ BOOST_AUTO_TEST_CASE(window_manager_uses_theme_body_line_height_for_decorated_ch
|
|||||||
.width = 100.0F,
|
.width = 100.0F,
|
||||||
.height = 100.0F,
|
.height = 100.0F,
|
||||||
},
|
},
|
||||||
}, std::move(content));
|
},
|
||||||
|
std::move(content));
|
||||||
BOOST_REQUIRE(id);
|
BOOST_REQUIRE(id);
|
||||||
manager.measure(context, theme, {
|
manager.measure(context, theme, {
|
||||||
.max = {
|
.max = {
|
||||||
@@ -1583,7 +1610,8 @@ BOOST_AUTO_TEST_CASE(window_manager_skips_hidden_windows_during_measure) {
|
|||||||
.height = 80.0F,
|
.height = 80.0F,
|
||||||
},
|
},
|
||||||
.visible = false,
|
.visible = false,
|
||||||
}, std::move(content));
|
},
|
||||||
|
std::move(content));
|
||||||
BOOST_REQUIRE(id);
|
BOOST_REQUIRE(id);
|
||||||
manager.measure(context, theme, {
|
manager.measure(context, theme, {
|
||||||
.max = {
|
.max = {
|
||||||
@@ -1612,7 +1640,8 @@ BOOST_AUTO_TEST_CASE(window_manager_id_mutators_validate_and_update_windows) {
|
|||||||
.width = 100.0F,
|
.width = 100.0F,
|
||||||
.height = 100.0F,
|
.height = 100.0F,
|
||||||
},
|
},
|
||||||
}, std::make_unique<recording_control>());
|
},
|
||||||
|
std::make_unique<recording_control>());
|
||||||
BOOST_REQUIRE(id);
|
BOOST_REQUIRE(id);
|
||||||
BOOST_TEST(!manager.set_bounds(0, {
|
BOOST_TEST(!manager.set_bounds(0, {
|
||||||
.x = 1.0F,
|
.x = 1.0F,
|
||||||
@@ -1650,7 +1679,8 @@ BOOST_AUTO_TEST_CASE(window_manager_find_pointer_is_stable_across_open_and_reord
|
|||||||
.width = 10.0F,
|
.width = 10.0F,
|
||||||
.height = 10.0F,
|
.height = 10.0F,
|
||||||
},
|
},
|
||||||
}, std::make_unique<recording_control>());
|
},
|
||||||
|
std::make_unique<recording_control>());
|
||||||
BOOST_REQUIRE(first);
|
BOOST_REQUIRE(first);
|
||||||
auto *first_ptr = manager.find(*first);
|
auto *first_ptr = manager.find(*first);
|
||||||
BOOST_REQUIRE(first_ptr != nullptr);
|
BOOST_REQUIRE(first_ptr != nullptr);
|
||||||
@@ -1663,7 +1693,8 @@ BOOST_AUTO_TEST_CASE(window_manager_find_pointer_is_stable_across_open_and_reord
|
|||||||
.width = 10.0F,
|
.width = 10.0F,
|
||||||
.height = 10.0F,
|
.height = 10.0F,
|
||||||
},
|
},
|
||||||
}, std::make_unique<recording_control>());
|
},
|
||||||
|
std::make_unique<recording_control>());
|
||||||
BOOST_REQUIRE(opened);
|
BOOST_REQUIRE(opened);
|
||||||
}
|
}
|
||||||
BOOST_TEST(manager.find(*first) == first_ptr);
|
BOOST_TEST(manager.find(*first) == first_ptr);
|
||||||
@@ -1683,7 +1714,8 @@ BOOST_AUTO_TEST_CASE(window_manager_defers_reentrant_close_until_touch_returns)
|
|||||||
.width = 100.0F,
|
.width = 100.0F,
|
||||||
.height = 100.0F,
|
.height = 100.0F,
|
||||||
},
|
},
|
||||||
}, std::make_unique<closing_window_control>(manager, id, state));
|
},
|
||||||
|
std::make_unique<closing_window_control>(manager, id, state));
|
||||||
BOOST_REQUIRE(opened);
|
BOOST_REQUIRE(opened);
|
||||||
id = *opened;
|
id = *opened;
|
||||||
BOOST_TEST(manager.handle_touch({
|
BOOST_TEST(manager.handle_touch({
|
||||||
@@ -1716,7 +1748,8 @@ BOOST_AUTO_TEST_CASE(window_manager_defers_reentrant_close_until_invalidation_re
|
|||||||
.width = 100.0F,
|
.width = 100.0F,
|
||||||
.height = 100.0F,
|
.height = 100.0F,
|
||||||
},
|
},
|
||||||
}, std::make_unique<closing_window_invalidate_control>(manager, id, state));
|
},
|
||||||
|
std::make_unique<closing_window_invalidate_control>(manager, id, state));
|
||||||
BOOST_REQUIRE(opened);
|
BOOST_REQUIRE(opened);
|
||||||
id = *opened;
|
id = *opened;
|
||||||
manager.invalidate_layout();
|
manager.invalidate_layout();
|
||||||
@@ -1737,7 +1770,8 @@ BOOST_AUTO_TEST_CASE(window_manager_defers_reentrant_open_and_returns_reserved_i
|
|||||||
.width = 100.0F,
|
.width = 100.0F,
|
||||||
.height = 100.0F,
|
.height = 100.0F,
|
||||||
},
|
},
|
||||||
}, std::make_unique<opening_window_control>(manager, state));
|
},
|
||||||
|
std::make_unique<opening_window_control>(manager, state));
|
||||||
BOOST_REQUIRE(opened);
|
BOOST_REQUIRE(opened);
|
||||||
BOOST_TEST(manager.handle_touch({
|
BOOST_TEST(manager.handle_touch({
|
||||||
.points = {
|
.points = {
|
||||||
@@ -1769,7 +1803,8 @@ BOOST_AUTO_TEST_CASE(window_manager_defers_reentrant_bounds_and_visibility_updat
|
|||||||
.width = 100.0F,
|
.width = 100.0F,
|
||||||
.height = 100.0F,
|
.height = 100.0F,
|
||||||
},
|
},
|
||||||
}, std::make_unique<updating_window_control>(manager, id, state));
|
},
|
||||||
|
std::make_unique<updating_window_control>(manager, id, state));
|
||||||
BOOST_REQUIRE(opened);
|
BOOST_REQUIRE(opened);
|
||||||
id = *opened;
|
id = *opened;
|
||||||
BOOST_TEST(manager.handle_touch({
|
BOOST_TEST(manager.handle_touch({
|
||||||
@@ -1803,7 +1838,8 @@ BOOST_AUTO_TEST_CASE(application_window_facade_validates_pre_run_calls) {
|
|||||||
.width = 100.0F,
|
.width = 100.0F,
|
||||||
.height = 100.0F,
|
.height = 100.0F,
|
||||||
},
|
},
|
||||||
}, std::make_unique<recording_control>());
|
},
|
||||||
|
std::make_unique<recording_control>());
|
||||||
BOOST_REQUIRE(opened);
|
BOOST_REQUIRE(opened);
|
||||||
BOOST_REQUIRE(app.set_window_bounds(*opened, {
|
BOOST_REQUIRE(app.set_window_bounds(*opened, {
|
||||||
.x = 5.0F,
|
.x = 5.0F,
|
||||||
|
|||||||
Reference in New Issue
Block a user