Formatting
publish / publish (push) Successful in 15m37s

This commit is contained in:
khodowany
2026-09-14 23:56:06 -05:00
parent 86cf029ad7
commit bb96aaf95d
30 changed files with 1030 additions and 950 deletions
+4
View File
@@ -91,6 +91,10 @@ jobs:
restore-keys: conan-${{ runner.os }}-
- name: Configure native 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
run: python3 modulus.py build --target x86_64_gcc12_release
- name: Test native release
+2
View File
@@ -6,6 +6,8 @@ Luma uses Modulus for shared build tooling, Boost.JSON, and raylib integration.
## 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:
```sh
-8
View File
@@ -40,15 +40,12 @@ class luma_conan(conan.ConanFile):
"tests/*.cpp",
"tests/*.hpp",
)
def config_options(self):
if self.settings.os == "Windows":
del self.options.fPIC
def configure(self):
if self.options.shared:
del self.options.fPIC
def requirements(self):
self.requires(
"modulus/latest",
@@ -58,7 +55,6 @@ class luma_conan(conan.ConanFile):
"with_raylib": True,
},
)
def generate(self):
deps = conan.tools.cmake.CMakeDeps(self)
deps.generate()
@@ -68,14 +64,12 @@ class luma_conan(conan.ConanFile):
toolchain.variables["BUILD_SHARED_LIBS"] = bool(self.options.shared)
toolchain.variables["BUILD_TESTING"] = bool(self.options.with_tests)
toolchain.generate()
def build(self):
cmake = conan.tools.cmake.CMake(self)
cmake.configure()
cmake.build()
if self.options.with_tests and conan.tools.build.can_run(self):
cmake.test(target="check")
def package_id(self):
self.info.options.rm_safe("with_tests")
for requirement in (
@@ -85,11 +79,9 @@ class luma_conan(conan.ConanFile):
):
if requirement in self.info.requires.pkg_names:
self.info.requires.remove(requirement)
def package(self):
cmake = conan.tools.cmake.CMake(self)
cmake.install()
def package_info(self):
self.cpp_info.set_property(
"cmake_file_name",
+1
View File
@@ -7,6 +7,7 @@
#include <modulus.hpp>
namespace luma {
enum class easing {
+2
View File
@@ -23,7 +23,9 @@
namespace luma {
namespace detail {
struct application_core;
}
struct frame_stats {
+1
View File
@@ -11,6 +11,7 @@
#include <luma/render.hpp>
namespace luma {
class renderer_resources {
+1
View File
@@ -10,6 +10,7 @@
#include <luma/theme.hpp>
namespace luma {
struct display_config {
+3
View File
@@ -6,10 +6,13 @@
#include <luma/geometry.hpp>
namespace luma {
class draw_context;
struct theme;
struct touch_event;
class control {
+2 -4
View File
@@ -76,7 +76,6 @@ public:
std::weak_ptr<void> lifetime{};
std::function<void()> callback{};
};
text_input_state(luma::text_field_options options, std::function<void(std::string)> on_change);
auto snapshot() const -> luma::text_field_options;
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 result = std::vector<std::unique_ptr<luma::control>>{};
result.reserve(sizeof...(controls));
auto append = [&result](auto &&input) -> std::expected<void, modulus::error> {
auto child = luma::detail::normalize_child(std::forward<decltype(input)>(input));
if (!child) {
@@ -171,13 +169,13 @@ auto luma::children(CONTROLS&&... controls) -> std::expected<std::vector<std::un
result.push_back(std::move(*child));
return {};
};
auto status = std::expected<void, modulus::error>{};
([&] {
if (status) {
status = append(std::forward<CONTROLS>(controls));
}
}(), ...);
}(),
...);
if (!status) {
return modulus::fail<std::vector<std::unique_ptr<luma::control>>>(status.error());
}
+1
View File
@@ -7,6 +7,7 @@
#include <modulus.hpp>
namespace luma::detail {
constexpr std::int32_t error_invalid_argument{1};
+1
View File
@@ -5,6 +5,7 @@
#include <modulus.hpp>
namespace luma {
struct point {
+1
View File
@@ -6,6 +6,7 @@
#include <luma/geometry.hpp>
namespace luma {
enum class touch_phase {
+1
View File
@@ -14,6 +14,7 @@
#include <luma/control.hpp>
namespace luma {
enum class dialog_result {
+1
View File
@@ -8,6 +8,7 @@
#include <luma/geometry.hpp>
#include <luma/theme.hpp>
namespace luma {
struct texture_info {
+1
View File
@@ -11,6 +11,7 @@
#include <luma/control.hpp>
namespace luma {
class router {
+1
View File
@@ -8,6 +8,7 @@
#include <modulus.hpp>
namespace luma {
struct color {
+1
View File
@@ -13,6 +13,7 @@
#include <luma/control.hpp>
#include <luma/geometry.hpp>
namespace luma {
class window_manager;
+6 -2
View File
@@ -16,6 +16,7 @@ COMMANDS = (
"package",
"lsp",
"clangd",
"format",
)
COMMON_DIR = pathlib.Path("build") / "build_common"
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 / RUNTIME_DIR / "modulus" / "cli.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():
@@ -340,9 +344,9 @@ def ensure_runtime(root):
def delegate(command, argv):
root = repo_root()
if command == "clangd":
if command in {"clangd", "format"}:
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
else:
ensure_runtime(root)
+1 -4
View File
@@ -11,6 +11,7 @@
#include <luma/detail/errors.hpp>
namespace {
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_) {
return internal("animation graph is already ticking");
}
auto active = std::move(animations_);
animations_.clear();
ticking_ = true;
clear_requested_ = false;
auto fail_tick = [this](std::expected<void, modulus::error> status) {
ticking_ = false;
clear_requested_ = false;
@@ -117,7 +116,6 @@ auto luma::animation_graph::tick(std::chrono::steady_clock::duration delta) -> s
pending_.clear();
return status;
};
for (auto &running : active) {
running.elapsed += delta;
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));
}
ticking_ = false;
for (auto &operation : pending_) {
if (operation.kind == luma::animation_graph::pending_kind::CLEAR) {
+24 -28
View File
@@ -38,6 +38,7 @@
#include <luma/render.hpp>
#include <luma/routing.hpp>
namespace luma::detail {
struct application_core {
@@ -75,7 +76,6 @@ namespace {
struct font_key {
std::string path{};
std::int32_t size{};
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) {
return unavailable<VALUE>("application is not initialized");
}
auto task = std::decay_t<TASK>{std::forward<TASK>(input)};
auto should_post = false;
auto wait_for_startup = false;
{
auto lock = std::unique_lock{core->lifecycle_mutex};
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;
wait_for_startup = running && !accepting;
}
if (!should_post || wait_for_startup) {
auto immediate_lock = std::scoped_lock{core->immediate_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;
}
auto future = std::future<std::expected<VALUE, modulus::error>>{};
auto promise = std::make_shared<std::promise<std::expected<VALUE, modulus::error>>>();
future = promise->get_future();
@@ -364,7 +360,6 @@ auto dispatch_to_ui(std::shared_ptr<luma::detail::application_core> const& core,
} catch (...) {
return internal<VALUE>("failed to queue UI task");
}
return future.get();
}
@@ -543,7 +538,8 @@ auto font_key_hash::operator()(font_key const& key) const noexcept -> std::size_
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() {
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;
}
@@ -586,7 +583,8 @@ ui_traversal_scope::~ui_traversal_scope() {
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_->texture.id != 0);
assert(record_->texture.width > 0);
@@ -623,7 +621,8 @@ auto raylib_texture::native() const -> Texture2D {
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);
}
@@ -652,7 +651,8 @@ auto raylib_resources::state() const -> std::shared_ptr<raylib_resource_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);
}
@@ -663,7 +663,8 @@ auto raylib_draw_context::fill_rect(luma::rect bounds, luma::color color) -> voi
.y = bounds.y,
.width = bounds.width,
.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 {
@@ -674,7 +675,8 @@ auto raylib_draw_context::stroke_rect(luma::rect bounds, std::float32_t thicknes
.y = bounds.y,
.width = bounds.width,
.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 {
@@ -728,7 +730,8 @@ auto raylib_draw_context::draw_text(std::string_view text, luma::point origin, l
DrawTextEx(font, owned.c_str(), {
.x = origin.x,
.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 {
@@ -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);
install_retire_handlers(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 core = core_snapshot();
return dispatch_to_ui<std::string>(core, [core] {
return modulus::success(std::string{core->router.current_route()});
}, false);
return dispatch_to_ui<std::string>(core, [core] { return modulus::success(std::string{core->router.current_route()}); }, false);
}
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 core = core_snapshot();
return dispatch_to_ui<std::bool_t>(core, [core] {
return modulus::success(core->animations.empty());
}, false);
return dispatch_to_ui<std::bool_t>(core, [core] { 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> {
@@ -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) {
return unavailable<std::shared_ptr<luma::texture>>("texture loading requires an active renderer");
}
return core->assets->texture(path);
}, false);
return core->assets->texture(path); }, false);
}
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->accepting_tasks.store(false, std::memory_order_release);
}
auto resource_state = std::shared_ptr<raylib_resource_state>{};
auto window_ready = false;
[[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);
}};
InitWindow(core->config.display.width, core->config.display.height, core->config.title.c_str());
if (!IsWindowReady()) {
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 const idle_fps = core->config.display.idle_fps;
SetTargetFPS(current_target_fps);
resource_state = std::make_shared<raylib_resource_state>();
resource_state->ui_thread = std::this_thread::get_id();
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);
}
startup_lock.unlock();
auto context = raylib_draw_context{resource_state};
auto previous_touches = std::unordered_map<std::int32_t, luma::point>{};
auto previous_frame = std::chrono::steady_clock::now();
+3 -1
View File
@@ -16,6 +16,7 @@
#include <luma/detail/errors.hpp>
struct luma::asset_cache::in_flight_load {
std::condition_variable ready{};
std::thread::id owner{};
@@ -23,7 +24,8 @@ struct luma::asset_cache::in_flight_load {
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);
}
+6 -4
View File
@@ -15,13 +15,13 @@
#include <luma/detail/errors.hpp>
#include <luma/theme.hpp>
namespace {
constexpr auto json_options = modulus::json_config::options{
.category = "luma",
.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> {
assert(!message.empty());
@@ -93,7 +93,8 @@ auto luma::parse_display_config(boost::json::value const& value) -> std::expecte
"target_fps",
"idle_fps",
"fullscreen",
}, "display", json_options);
},
"display", json_options);
if (!unknown) {
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",
"touch",
"theme",
}, "application config", json_options);
},
"application config", json_options);
if (!unknown) {
return invalid_application(std::string{unknown.error().message()});
}
+1
View File
@@ -7,6 +7,7 @@
#include <modulus.hpp>
namespace {
auto valid_rect(luma::rect value) -> std::bool_t {
+46 -30
View File
@@ -27,14 +27,14 @@
#include <luma/render.hpp>
#include <luma/theme.hpp>
namespace {
constexpr auto panel_padding = luma::edge_insets{
.left = 8.0F,
.top = 8.0F,
.right = 8.0F,
.bottom = 8.0F
};
.bottom = 8.0F};
constexpr auto scroll_drag_threshold = std::float32_t{6.0F};
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());
}
@@ -375,10 +376,12 @@ auto label_control::draw(luma::draw_context& context, luma::theme const& theme)
context.draw_text(text_, {
.x = bounds().x,
.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(on_click_);
}
@@ -390,7 +393,8 @@ auto button_control::measure(luma::draw_context& context, luma::theme const& the
return luma::clamp({
.width = text_size.width + 32.0F,
.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 {
@@ -434,7 +438,8 @@ auto button_control::focusable() const -> std::bool_t {
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);
}
@@ -453,7 +458,8 @@ auto text_field_control::measure(luma::draw_context& context, luma::theme const&
cached_size_ = luma::clamp({
.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}),
}, limits);
},
limits);
return cached_size_;
}
@@ -470,7 +476,8 @@ auto text_field_control::draw(luma::draw_context& context, luma::theme const& th
context.draw_text(text, {
.x = bounds().x + 12.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 {
@@ -513,12 +520,14 @@ auto text_field_control::focusable() const -> std::bool_t {
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(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(input_ != nullptr);
}
@@ -528,7 +537,8 @@ auto soft_keyboard_control::measure(luma::draw_context&, luma::theme const&, lum
return luma::clamp({
.width = 640.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 {
@@ -551,7 +561,8 @@ auto soft_keyboard_control::draw(luma::draw_context& context, luma::theme const&
context.draw_text(row[column_index].label, {
.x = rect.x + 12.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;
}
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 {
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_));
}
@@ -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 {}
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));
}
@@ -678,7 +692,8 @@ auto progress_bar_control::measure(luma::draw_context&, luma::theme const&, luma
return luma::clamp({
.width = 160.0F,
.height = 16.0F,
}, limits);
},
limits);
}
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,
.width = bounds().width * value_,
.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);
}
@@ -704,7 +721,8 @@ auto image_control::measure(luma::draw_context&, luma::theme const&, luma::const
return luma::clamp({
.width = static_cast<std::float32_t>(info.width),
.height = static_cast<std::float32_t>(info.height),
}, limits);
},
limits);
}
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);
}
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(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) : children_{std::move(children)} {}
stack_control::stack_control(std::vector<std::unique_ptr<luma::control>> children)
: children_{std::move(children)} {}
auto stack_control::measure(luma::draw_context &context, luma::theme const &theme, luma::constraints limits) -> luma::size {
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) : child_{std::move(child)}, vertical_{vertical}, horizontal_{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} {
assert(child_ != nullptr);
assert(vertical_ || horizontal_);
}
@@ -938,13 +957,11 @@ auto scroll_view_control::handle_point(luma::touch_event const& event, luma::tou
}
return true;
}
auto found = touches_.find(point.id);
if (found == touches_.end()) {
return false;
}
auto &state = found->second;
if (point.phase == luma::touch_phase::MOVE) {
auto delta = luma::point{
.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;
}
if (point.phase == luma::touch_phase::UP || point.phase == luma::touch_phase::CANCEL) {
auto const scrolling = scroll_id_ == point.id && dragging_;
if (state.child_active) {
@@ -1015,7 +1031,6 @@ auto scroll_view_control::handle_point(luma::touch_event const& event, luma::tou
touches_.erase(found);
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(on_change_);
}
+1
View File
@@ -5,6 +5,7 @@
#include <modulus.hpp>
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);
}
+11 -5
View File
@@ -17,6 +17,7 @@
#include <luma/render.hpp>
#include <luma/theme.hpp>
namespace {
class scope_exit {
@@ -89,7 +90,8 @@ auto draw_button(luma::draw_context& context, luma::theme const& theme, luma::re
context.draw_text(text, {
.x = bounds.x + (bounds.width - measured.width) * 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 * {
@@ -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() {
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);
}
@@ -278,7 +282,8 @@ auto luma::overlay_host::draw(luma::draw_context& context, luma::theme const& th
context.draw_text(title, {
.x = dialog.x + 16.0F,
.y = dialog.y + 16.0F,
}, theme.title, theme.text);
},
theme.title, theme.text);
body->draw(context, theme);
auto has_cancel = !cancel_text.empty();
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, {
.x = toast_bounds.x + 16.0F,
.y = toast_bounds.y + 10.0F,
}, theme.body, theme.text);
},
theme.body, theme.text);
}
}
+1
View File
@@ -10,6 +10,7 @@
#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> {
if (name.empty()) {
return luma::detail::fail<void>(luma::detail::error_invalid_argument, "route name must not be empty");
+8 -5
View File
@@ -16,13 +16,13 @@
#include <luma/detail/errors.hpp>
namespace {
constexpr auto json_options = modulus::json_config::options{
.category = "luma",
.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> {
assert(!message.empty());
@@ -73,7 +73,8 @@ auto apply_text_style(boost::json::object const& object, std::char_t const* name
"font",
"size",
"line_height",
}, name, json_options);
},
name, json_options);
if (!unknown) {
return modulus::fail<void>(unknown.error());
}
@@ -157,7 +158,8 @@ auto luma::parse_color(boost::json::value const& value) -> std::expected<luma::c
"g",
"b",
"a",
}, "color", json_options);
},
"color", json_options);
if (!unknown) {
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",
"radius",
"spacing",
}, "theme", json_options);
},
"theme", json_options);
if (!unknown) {
return invalid_theme(std::string{unknown.error().message()});
}
+7 -4
View File
@@ -19,6 +19,7 @@
#include <luma/render.hpp>
#include <luma/theme.hpp>
namespace {
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() {
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(finite_rect(options_.bounds));
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, {
.x = title.x + 8.0F,
.y = title.y + window_title_vertical_padding,
}, theme.body, theme.text);
},
theme.body, theme.text);
}
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;
}
for (auto current = windows_.rbegin(); current != windows_.rend(); ++current) {
assert(*current != nullptr);
if (!(*current)->visible()) {
+69 -33
View File
@@ -22,6 +22,7 @@
#include <test.hpp>
namespace {
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 {
return value_;
@@ -292,7 +294,8 @@ auto fixed_control::handle_touch(luma::touch_event const& event) -> std::bool_t
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 {
++measure_count;
@@ -325,7 +328,8 @@ auto filling_control::measure(luma::draw_context&, luma::theme const&, luma::con
return luma::clamp({
.width = 20.0F,
.height = 20.0F,
}, limits);
},
limits);
}
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(), {});
}
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 {
return info_;
@@ -414,7 +419,8 @@ auto recording_control::handle_touch(luma::touch_event const& event) -> std::boo
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() {
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 {}
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() {
state_->destroyed = true;
@@ -458,7 +465,8 @@ auto closing_window_control::handle_touch(luma::touch_event const&) -> std::bool
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 {
return {
@@ -478,7 +486,8 @@ auto opening_window_control::handle_touch(luma::touch_event const&) -> std::bool
.width = 50.0F,
.height = 50.0F,
},
}, std::make_unique<recording_control>());
},
std::make_unique<recording_control>());
state_->status_ok = opened.has_value();
if (opened) {
state_->opened_id = *opened;
@@ -487,7 +496,8 @@ auto opening_window_control::handle_touch(luma::touch_event const&) -> std::bool
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 {
return {
@@ -513,7 +523,8 @@ auto updating_window_control::handle_touch(luma::touch_event const&) -> std::boo
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() {
state_->destroyed = true;
@@ -558,7 +569,8 @@ auto closing_dialog_control::close_if(close_phase phase) const -> void {
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() {
state_->destroyed = true;
@@ -584,7 +596,8 @@ auto replacing_root_invalidate_control::invalidate_layout() -> void {
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() {
state_->destroyed = true;
@@ -599,6 +612,7 @@ auto closing_window_invalidate_control::measure(luma::draw_context&, luma::theme
.height = 20.0F,
};
}
auto closing_window_invalidate_control::draw(luma::draw_context &, luma::theme const &) const -> 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);
auto field = luma::text_field({
.text = "Scale",
}, [](std::string) {});
},
[](std::string) {});
BOOST_REQUIRE(field);
auto small_field = (*field)->measure(context, small, {
.max = {
@@ -882,6 +897,7 @@ BOOST_AUTO_TEST_CASE(application_dispatch_serializes_concurrent_callers) {
BOOST_REQUIRE(result);
});
}
for (auto &thread : threads) {
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{
.width = 10.0F,
.height = 10.0F,
}), luma::label("Label"));
}),
luma::label("Label"));
BOOST_REQUIRE(children);
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::text_field({
.max_length = 0,
}, [](std::string) {}));
},
[](std::string) {}));
BOOST_TEST(!luma::image(nullptr));
BOOST_TEST(!luma::image(std::make_shared<fake_texture>(0, 16)));
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({
.mode = luma::text_input_mode::INTEGER,
.max_length = 3,
}, [&](std::string text) {
},
[&](std::string text) {
changes.push_back(std::move(text));
});
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);
(*keyboard)->arrange({
.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) {
auto input = luma::make_text_input({
.mode = luma::text_input_mode::DECIMAL,
}, [](std::string) {});
},
[](std::string) {});
BOOST_REQUIRE(input);
BOOST_REQUIRE((*input)->append("1.5"));
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) {
auto input = luma::make_text_input({
.text = "a",
}, [](std::string) {});
},
[](std::string) {});
BOOST_REQUIRE(input);
auto field = luma::text_field(*input);
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) {
auto input = luma::make_text_input({
.text = "a",
}, [](std::string) {});
},
[](std::string) {});
BOOST_REQUIRE(input);
auto field = luma::text_field(*input);
BOOST_REQUIRE(field);
@@ -1407,7 +1430,8 @@ BOOST_AUTO_TEST_CASE(window_manager_captures_touch_by_id) {
.width = 100.0F,
.height = 100.0F,
},
}, std::move(content));
},
std::move(content));
BOOST_REQUIRE(id);
BOOST_TEST(*id != 0U);
BOOST_TEST(manager.handle_touch({
@@ -1459,7 +1483,8 @@ BOOST_AUTO_TEST_CASE(window_set_bounds_validates_release_inputs) {
.width = 100.0F,
.height = 100.0F,
},
}, std::make_unique<recording_control>());
},
std::make_unique<recording_control>());
BOOST_REQUIRE(id);
auto *window = manager.find(*id);
BOOST_REQUIRE(window != nullptr);
@@ -1497,7 +1522,8 @@ BOOST_AUTO_TEST_CASE(window_manager_uses_decorated_client_area_for_content) {
.width = 100.0F,
.height = 80.0F,
},
}, std::move(content));
},
std::move(content));
BOOST_REQUIRE(id);
manager.measure(context, theme, {
.max = {
@@ -1541,7 +1567,8 @@ BOOST_AUTO_TEST_CASE(window_manager_uses_theme_body_line_height_for_decorated_ch
.width = 100.0F,
.height = 100.0F,
},
}, std::move(content));
},
std::move(content));
BOOST_REQUIRE(id);
manager.measure(context, theme, {
.max = {
@@ -1583,7 +1610,8 @@ BOOST_AUTO_TEST_CASE(window_manager_skips_hidden_windows_during_measure) {
.height = 80.0F,
},
.visible = false,
}, std::move(content));
},
std::move(content));
BOOST_REQUIRE(id);
manager.measure(context, theme, {
.max = {
@@ -1612,7 +1640,8 @@ BOOST_AUTO_TEST_CASE(window_manager_id_mutators_validate_and_update_windows) {
.width = 100.0F,
.height = 100.0F,
},
}, std::make_unique<recording_control>());
},
std::make_unique<recording_control>());
BOOST_REQUIRE(id);
BOOST_TEST(!manager.set_bounds(0, {
.x = 1.0F,
@@ -1650,7 +1679,8 @@ BOOST_AUTO_TEST_CASE(window_manager_find_pointer_is_stable_across_open_and_reord
.width = 10.0F,
.height = 10.0F,
},
}, std::make_unique<recording_control>());
},
std::make_unique<recording_control>());
BOOST_REQUIRE(first);
auto *first_ptr = manager.find(*first);
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,
.height = 10.0F,
},
}, std::make_unique<recording_control>());
},
std::make_unique<recording_control>());
BOOST_REQUIRE(opened);
}
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,
.height = 100.0F,
},
}, std::make_unique<closing_window_control>(manager, id, state));
},
std::make_unique<closing_window_control>(manager, id, state));
BOOST_REQUIRE(opened);
id = *opened;
BOOST_TEST(manager.handle_touch({
@@ -1716,7 +1748,8 @@ BOOST_AUTO_TEST_CASE(window_manager_defers_reentrant_close_until_invalidation_re
.width = 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);
id = *opened;
manager.invalidate_layout();
@@ -1737,7 +1770,8 @@ BOOST_AUTO_TEST_CASE(window_manager_defers_reentrant_open_and_returns_reserved_i
.width = 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_TEST(manager.handle_touch({
.points = {
@@ -1769,7 +1803,8 @@ BOOST_AUTO_TEST_CASE(window_manager_defers_reentrant_bounds_and_visibility_updat
.width = 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);
id = *opened;
BOOST_TEST(manager.handle_touch({
@@ -1803,7 +1838,8 @@ BOOST_AUTO_TEST_CASE(application_window_facade_validates_pre_run_calls) {
.width = 100.0F,
.height = 100.0F,
},
}, std::make_unique<recording_control>());
},
std::make_unique<recording_control>());
BOOST_REQUIRE(opened);
BOOST_REQUIRE(app.set_window_bounds(*opened, {
.x = 5.0F,