Skip to main content

cotis_raylib/
lib.rs

1//! Raylib-backed renderer for the [Cotis](https://crates.io/crates/cotis) UI ecosystem.
2//!
3//! `cotis-raylib` implements Cotis's `CotisRenderer` and `CotisRendererAsync` traits
4//! (from `cotis::renders`) on top of [raylib](https://crates.io/crates/raylib) 6.x.
5//! It is the primary render backend used by `cotis-layout` examples.
6//!
7//! # Quick start
8//!
9//! For interactive applications, create a [`crate::renderer::RaylibRender`] and wire it into
10//! `CotisApp` (from `cotis::cotis_app`) with a layout manager and pipe:
11//!
12//! ```rust,ignore
13//! use cotis::cotis_app::CotisApp;
14//! use cotis_layout::preamble::CotisLayoutManager;
15//! use cotis_pipes::cotis_layout_pipes::CotisLayoutToRenderListPipeForGenerics;
16//! use cotis_raylib::prelude::RaylibRender;
17//! use cotis_utils::math::Dimensions;
18//!
19//! let renderer = RaylibRender::auto_start();
20//! let manager = CotisLayoutManager::new(Dimensions::new(1000.0, 800.0));
21//! let mut app = CotisApp::new(renderer, manager, CotisLayoutToRenderListPipeForGenerics);
22//! // app.compute_frame(...);
23//! // while !app.render().window_should_close() { ... }
24//! ```
25//!
26//! Shipped examples use [`crate::renderer::RaylibRender`] directly (not `RayTestRender` from the
27//! `test_render` module). Run from the repository root:
28//!
29//! ```text
30//! cargo run -p cotis-raylib --example basic_example
31//! ```
32//!
33//! # Recommended imports
34//!
35//! Use [`prelude`] for the common entry-point types:
36//!
37//! ```rust,no_run
38//! use cotis_raylib::prelude::{PathBasedImage, RaylibRender, RayRenderHandle};
39//! ```
40//!
41//! # Rendering model
42//!
43//! [`crate::renderer::RaylibRender`] draws two kinds of command streams:
44//!
45//! - [`cotis_defaults::render_commands::render_t_list::RenderTList`] — typed heterogeneous command lists
46//!   produced by layout pipes. Images are preloaded into the renderer cache before drawing.
47//! - [`Box<dyn crate::drawables::RaylibDrawable>`] — custom drawables; implement
48//!   [`crate::drawables::RaylibDrawable`] for types not covered by `cotis-defaults` commands.
49//!
50//! Extend drawing with [`crate::drawables::RaylibDrawable::scale_by`] (used by `RayTestRender` when the
51//! `test-render` feature is enabled) and [`crate::drawables::RaylibDrawable::preload_generic_images`]
52//! for path-based images.
53//!
54//! # Images
55//!
56//! Path-based assets use [`crate::cotis_defaults_images::PathBasedImage`] (or `JPEGImage`, `PNGImage`,
57//! `SVGImage` from `cotis_defaults::generic_image`).
58//! [`crate::renderer::RaylibRender::translate_generic_image`] loads textures into an internal cache
59//! keyed by file path. `SVGImage` is a semantic path tag only — raylib loads raster data from the path;
60//! true vector SVG rendering is not implemented.
61//!
62//! # Fonts
63//!
64//! Call [`crate::renderer::RaylibRender::load_font_and_keep`] or
65//! [`crate::renderer::RaylibRender::load_font_ex_and_keep`] at startup.
66//! The returned ID (0-based, assigned in load order) is stored in `TextConfig::font_id`
67//! (`cotis_defaults::element_configs::text_config::TextConfig`).
68//! Additional pixel sizes are loaded lazily at the start of each frame.
69//!
70//! # Features
71//!
72//! | Feature | Effect |
73//! |---------|--------|
74//! | `test-render` | Exposes the `test_render` module for scaled/headless-style testing. |
75//! | `complex-color` | Enables gradient and layered fills (requires `cotis-defaults/complex_color`). |
76//!
77//! # Thread safety
78//!
79//! The raylib handle is wrapped in `Arc<Mutex<RayRenderHandle>>` ([`crate::renderer::RayRenderHandle`])
80//! so it can be shared for input polling. `RaylibThread` (from the `raylib` crate) is owned by
81//! [`crate::renderer::RaylibRender`] and must be used for drawing on the thread that created the window.
82//! All mutex locks **panic** if the mutex is poisoned.
83//!
84//! # When to use `RayTestRender`
85//!
86//! With the `test-render` feature, `RayTestRender` wraps [`crate::renderer::RaylibRender`] to render at a logical resolution while keeping a smaller physical
87//! window (`dimensions / scale`). Use it for CI snapshots and headless-style tests — not as the default
88//! for interactive applications.
89
90#![cfg_attr(docsrs, feature(doc_cfg))]
91
92pub mod prelude {
93    //! Convenient re-exports for application code.
94    //!
95    //! Typical import:
96    //!
97    //! ```rust,no_run
98    //! use cotis_raylib::prelude::{PathBasedImage, RaylibRender};
99    //! ```
100    //!
101    //! - [`RaylibRender`](crate::renderer::RaylibRender) — main window renderer and `CotisRenderer` implementation.
102    //! - [`RayRenderHandle`](crate::renderer::RayRenderHandle) — mutex-guarded raylib handle for input polling.
103    //! - [`PathBasedImage`](crate::cotis_defaults_images::PathBasedImage) — unified path-based image enum.
104    //! - `JPEGImage`, `PNGImage`, `SVGImage` — per-format path wrappers from `cotis-defaults`.
105
106    pub use crate::cotis_defaults_images::PathBasedImage;
107    pub use crate::renderer::RayRenderHandle;
108    pub use crate::renderer::RaylibRender;
109    pub use cotis_defaults::generic_image::{JPEGImage, PNGImage, SVGImage};
110}
111
112pub mod renderer;
113
114pub mod functions_raylib;
115
116pub mod drawables;
117
118pub mod text;
119
120pub mod raylib_images;
121
122pub mod cotis_defaults_images;
123
124pub mod fonts;
125
126#[cfg(feature = "complex-color")]
127mod color_paint;
128
129/// Scaled rendering wrapper for tests (requires `test-render` feature).
130#[cfg(feature = "test-render")]
131pub mod test_render;
132
133pub mod interactivity;
134
135pub mod cotis;