Skip to content

Commit

Permalink
update ui items
Browse files Browse the repository at this point in the history
- add modules `ui::service::{self, crossterm, miniquad}`.
- add items: `CrosstermService`, `MiniquadService`, `MiniquadWindow`, `MiniquadEventHandlerExt`.
- re-export a few `miniquad` items.
- enable `ui··` flag via ui-related dependencies.
- make ui dependencies version-specific.
- misc. refactors.
- update docs.
  • Loading branch information
joseluis committed Feb 4, 2025
1 parent 0d62a5f commit 48e4780
Show file tree
Hide file tree
Showing 9 changed files with 240 additions and 12 deletions.
6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -640,7 +640,8 @@ optional = true # unsafe
default-features = false # 8 https://docs.rs/crate/const-str/latest/features

[dependencies.crossterm] # https://crates.io/crates/crossterm
version = "0.28" # ✓ https://github.com/crossterm-rs/crossterm/blob/master/CHANGELOG.md
# In sync with src::ui::service::crossterm::service
version = "0.28.1" # ✓ https://github.com/crossterm-rs/crossterm/blob/master/CHANGELOG.md
optional = true # unsafe
default-features = false # 9 https://docs.rs/crate/crossterm/latest/features
features = ["bracketed-paste", "events"]
Expand Down Expand Up @@ -732,9 +733,12 @@ default-features = false # 7 https://docs.rs/crate/midir/latest/features
# INSTALL: libasound2-dev

[dependencies.miniquad] # https://crates.io/crates/miniquad
# In sync with src::ui::service::miniquad::service
version = "0.4.7" # ✗ https://github.com/not-fl3/miniquad/commits/master/
optional = true # unsafe
default-features = false # 1 https://docs.rs/crate/miniquad/latest/features
# WAIT: [update conf module to derive more traits](https://github.com/not-fl3/miniquad/pull/523)
# WAIT: [use AtomicPtr in NATIVE_DISPLAY](https://github.com/not-fl3/miniquad/pull/525)

[dependencies.nc] # https://crates.io/crates/nc
version = "0.9.5" # ✗ https://github.com/XuShaohua/nc/commits/main/
Expand Down
4 changes: 3 additions & 1 deletion DOCS/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@
- xifer: `DataValue*`, `DataType*`, `DataRaw*`, `NoData`, `Base`, `Crockford`, `Rfc4648`, `Rfc4648Hex`.
- sys: `DirApple`, `DirWindows`, `DirUnix`, `DirXdg`, `LogConfig`,
- ui: `UiCap`, `UiCapImage`, `UiCapInput`, `UiCapSound`, `UiCapSystem`, `UiCapWindow`.
- `CrosstermService`.
- `MiniquadService`, `MiniquadEventHandlerExt`.
- namespaces: `Iter`, `Log`.
- new macros: `maybe!`, `xorshift_custom!`.
- new modules:
- `data::{codec::{self, radix}, list, key, table, uid, xipher}`.
- `lang::{c}`.
- `sys::{log, net}`.
- `ui::service`.
- `ui::service::{self, crossterm, miniquad}`.
- new macro arms:
- `str!`: `ip_addr`.
- new methods:
Expand Down
5 changes: 4 additions & 1 deletion build/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,10 @@ mod reflection {
};
pub const UI: FlagsFeatures = FlagsFeatures {
flags: &["ui··"],
features: &["ui", "layout"]
features: &[
"ui", "layout",
"dep_crossterm", "dep_fltk", "dep_girls", "dep_miniquad", "dep_sdl2", "dep_sdl3",
]
};
pub const WORK: FlagsFeatures = FlagsFeatures {
flags: &["work··"],
Expand Down
7 changes: 2 additions & 5 deletions src/ui/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,8 @@

#[cfg(ui··)]
crate::items! {
#[cfg_attr(feature = "nightly_doc", doc(cfg(ui··)))]
mod error;

#[cfg_attr(feature = "nightly_doc", doc(cfg(ui··)))]
pub mod service; // UiService*, ...
pub mod service; // UiService*, UiCap*
}

#[cfg(feature = "layout")]
Expand All @@ -29,7 +26,7 @@ crate::items! { // structural access: _mods, _all,
#[cfg(ui··)]
pub use super::error::*;
}
pub(super) mod _pub_mods { #![allow(unused)]
mod _pub_mods { #![allow(unused)]
#[cfg(feature = "layout")]
pub use super::layout::_all::*;

Expand Down
6 changes: 3 additions & 3 deletions src/ui/service/cap/definitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub struct UiCap {
pub window: Option<UiCapWindow>,
}

/// Image-related capabilities.
/// Image capabilities.
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct UiCapImage {
/// Maximum bitmap size, in native pixels.
Expand All @@ -41,7 +41,7 @@ pub struct UiCapImage {
// pub palette_size: u16,
}

/// General Input capabilities.
/// Input capabilities.
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct UiCapInput {
/// Gamepad input capabilities.
Expand All @@ -56,7 +56,7 @@ pub struct UiCapInput {
pub touchscreen: bool,
}

/// Sound and music related capabilities.
/// Sound capabilities.
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct UiCapSound {
/// Sound playback capabilities.
Expand Down
20 changes: 20 additions & 0 deletions src/ui/service/crossterm/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// devela::ui::service::crossterm
//
//! `crossterm` Ui service.
//

mod service;
// mod events;

crate::items! { // structural access: _mods, _all
#[allow(unused)]
pub use _mods::*;

mod _mods {
pub use super::service::*;
}
pub(super) mod _all { #![allow(unused)]
#[doc(inline)]
pub use super::_mods::*;
}
}
159 changes: 159 additions & 0 deletions src/ui/service/crossterm/service.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
// devela::ui::service::crossterm::service
//
//! Defines [`CrosstermService`].
//
// ISSUES
// - WAIT: [add Event::Terminate](https://github.com/crossterm-rs/crossterm/issues/554)
// - WAIT: [support ctrl+z + fg](https://github.com/crossterm-rs/crossterm/issues/494)
//
// TODO
// - window refresh, render

use ::crossterm::{event, execute, terminal};

// use core::time::Duration;
use std::io;

use crate::{
IoError, UiCap, UiCapImage, /* Event, EventSource, */ UiCapInput,
/* Window, */ UiCapWindow, UiService,
};

/// `crossterm`'s UI service.
//
// https://docs.rs/crossterm/latest/crossterm/terminal/index.html
pub struct CrosstermService;
// { raw_mode: bool, }

// TODO
// impl Drop for CrosstermService {
// fn drop(&mut self) {
// if self.raw_mode {
// self.set_raw_mode(false);
// }
// }
// }

impl CrosstermService {
/// Creates a new `CrosstermService`.
pub fn new() -> Result<Self, IoError> {
Ok(Self { /* raw_mode: false */ })
}

/// Tells whether the raw mode is enabled.
//
// https://docs.rs/crossterm/latest/crossterm/terminal/fn.is_raw_mode_enabled.html
#[inline]
pub fn is_raw_mode(&self) -> Result<bool, IoError> {
terminal::is_raw_mode_enabled()
}

/// Enables the raw mode.
//
// https://docs.rs/crossterm/latest/crossterm/terminal/fn.enable_raw_mode.html
#[inline]
pub fn enable_raw_mode(&self) -> Result<(), IoError> {
terminal::enable_raw_mode()
}

/// Disables the raw mode.
//
// https://docs.rs/crossterm/latest/crossterm/terminal/fn.disable_raw_mode.html
#[inline]
pub fn disable_raw_mode(&self) -> Result<(), IoError> {
terminal::disable_raw_mode()
}

/// Switches to the alternate screen.
//
// https://docs.rs/crossterm/latest/crossterm/terminal/struct.EnterAlternateScreen.html
pub fn enter_alternate_screen(&self) -> Result<(), IoError> {
Ok(execute!(io::stdout(), terminal::EnterAlternateScreen)?)
}

/// Switches back to the main screen.
//
// https://docs.rs/crossterm/latest/crossterm/terminal/struct.LeaveAlternateScreen.html
pub fn leave_alternate_screen(&self) -> Result<(), IoError> {
Ok(execute!(io::stdout(), terminal::EnterAlternateScreen)?)
}

/// Enables receiving mouse events.
//
// https://docs.rs/crossterm/latest/crossterm/event/struct.EnableMouseCapture.html
pub fn enable_mouse(&mut self) -> Result<(), IoError> {
Ok(execute!(io::stdout(), event::EnableMouseCapture)?)
}
/// Disables receiving mouse events.
//
// https://docs.rs/crossterm/latest/crossterm/event/struct.DisableMouseCapture.html
pub fn disable_mouse(&mut self) -> Result<(), IoError> {
Ok(execute!(io::stdout(), event::DisableMouseCapture)?)
}

// TODO
// /// Enables bracketed paste mode.
// //
// // https://docs.rs/crossterm/latest/crossterm/event/struct.EnableBracketedPaste.html
// pub fn enable_bracketed_paste(&self) -> Result<(), IoError> {
// Ok(execute!(io::stdout(), event::EnableBracketedPaste)?)
// }
//
// /// Disables bracketed paste mode.
// //
// // https://docs.rs/crossterm/latest/crossterm/event/struct.DisableBracketedPaste.html
// pub fn disable_bracketed_paste(&self) -> Result<(), IoError> {
// Ok(execute!(io::stdout(), event::DisableBracketedPaste)?)
// }

/// Enables focus change mode.
//
// https://docs.rs/crossterm/latest/crossterm/event/struct.EnableFocusChange.html
pub fn enable_focus_change(&self) -> Result<(), IoError> {
Ok(execute!(io::stdout(), event::EnableFocusChange)?)
}

/// Disables focus change mode.
//
// https://docs.rs/crossterm/latest/crossterm/event/struct.DisableFocusChange.html
pub fn disable_focus_change(&self) -> Result<(), IoError> {
Ok(execute!(io::stdout(), event::DisableFocusChange)?)
}
}

impl UiService for CrosstermService {
fn capabilities(&self) -> UiCap {
let image = Some(UiCapImage {
rgb: true,
// palette_change: false,
// palette_size: ::crossterm::style::available_color_count(),
..Default::default()
});

let input = Some(UiCapInput { keyboard: true, mouse: true, ..Default::default() });

// let text_grid = Some(UiCapTextGridCap {
// // we don't unknown
// cell_size: None,
// // https://github.com/crossterm-rs/crossterm/issues/166
// // custom_cell_size: false,
// // // https://github.com/crossterm-rs/crossterm/issues/677
// // unicode: true,
// // ..Default::default()
// });

let window = Some(UiCapWindow { multi: false });

UiCap {
image,
input,
// text_grid,
window,
..Default::default()
}
}

fn version(&self) -> (u32, u32, u32) {
(0, 28, 1)
}
}
28 changes: 28 additions & 0 deletions src/ui/service/miniquad/reexports.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// devela::ui::service::miniquad::reexports
//
//!
//

use crate::reexport;

/* structs */

reexport! { "dep_miniquad", "miniquad", miniquad::conf,
doc: "Describes a hardware and platform-specific setup.",
@Conf as MiniquadConf
}
reexport! { "dep_miniquad", "miniquad", miniquad::conf,
doc: "Platform-specific settings.",
@Platform as MiniquadPlatform
}

/* traits */

reexport! { "dep_miniquad", "miniquad", miniquad,
doc: "Defines how an application responds to events in miniquad.",
@EventHandler as MiniquadEventHandler
}
reexport! { "dep_miniquad", "miniquad", miniquad::graphics,
doc: "Low-level interface for rendering operations in miniquad.",
@RenderingBackend as MiniquadRenderingBackend
}
17 changes: 16 additions & 1 deletion src/ui/service/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,31 @@
mod cap;
mod definition;

#[cfg(feature = "dep_crossterm")]
#[cfg_attr(feature = "nightly_doc", doc(cfg(feature = "dep_crossterm")))]
pub mod crossterm;
#[cfg(feature = "dep_miniquad")]
#[cfg_attr(feature = "nightly_doc", doc(cfg(feature = "dep_miniquad")))]
pub mod miniquad;

crate::items! { // structural access: _mods, _all
#[allow(unused)]
pub use _mods::*;
#[allow(unused)] #[doc(hidden, no_inline)]
pub use _pub_mods::*;

mod _mods {
#[cfg(ui··)]
pub use super::{cap::*, definition::*};
}
mod _pub_mods { #![allow(unused)]
#[cfg(feature = "dep_crossterm")]
pub use super::crossterm::_all::*;
#[cfg(feature = "dep_miniquad")]
pub use super::miniquad::_all::*;
}
pub(super) mod _all { #![allow(unused)]
#[doc(inline)]
pub use super::_mods::*;
pub use super::{_mods::*, _pub_mods::*};
}
}

0 comments on commit 48e4780

Please sign in to comment.