Start porting the base WINGs widget type to Rust.
Porting WINGs widgets to Rust will require using some WINGs abstractions. One of them is the base widget type, which is implemented by giving all widgets a common layout (with the first two fields always being the same basic types).
This commit is contained in:
@@ -8,7 +8,8 @@ RUST_SOURCES = \
|
||||
src/lib.rs \
|
||||
src/list.rs \
|
||||
src/pango_extras.rs \
|
||||
src/screen.rs
|
||||
src/screen.rs \
|
||||
src/widget.rs
|
||||
|
||||
RUST_EXTRA = \
|
||||
Cargo.lock \
|
||||
|
||||
@@ -9,3 +9,4 @@ pub mod font;
|
||||
pub mod list;
|
||||
pub(crate) mod pango_extras;
|
||||
pub mod screen;
|
||||
pub mod widget;
|
||||
|
||||
57
WINGs/wings-rs/src/widget.rs
Normal file
57
WINGs/wings-rs/src/widget.rs
Normal file
@@ -0,0 +1,57 @@
|
||||
//! Common WINGs widget fields.
|
||||
//!
|
||||
//! WINGs widgets all have a [`WINGsP::WMView`] object that tracks common attributes
|
||||
//! like size and location and a [`WINGsP::W_Class`] field that identifies the widget
|
||||
//! type (button, list, etc.). This module provides access to these fields.
|
||||
//!
|
||||
//! ## Rust rewrite notes
|
||||
//!
|
||||
//! The original WINGs implementation uses casting and a common layout for
|
||||
//! "primitive" widget structs, such that the first two fields are always a
|
||||
//! `W_Class` and a `*mut WMView`. We rely on this convention when implementing
|
||||
//! [`Widget`] for widgets that are defined in C.
|
||||
use crate::WINGsP;
|
||||
use std::{
|
||||
ptr::NonNull,
|
||||
};
|
||||
|
||||
/// Base WINGs widget type.
|
||||
///
|
||||
/// All primitive widgets (like buttons and lists) should implement this.
|
||||
pub trait Widget {
|
||||
fn class(&self) -> WINGsP::W_Class;
|
||||
fn view(&self) -> NonNull<WINGsP::WMView>;
|
||||
}
|
||||
|
||||
/// Common widget header fields. It should be safe to cast opaque WINGs widget
|
||||
/// structs defined in C to this type to access these fields. Before writing
|
||||
/// code that casts anything to this, double-check the widget definition!
|
||||
#[repr(C)]
|
||||
struct WidgetLike {
|
||||
class: WINGsP::W_Class,
|
||||
view: *mut WINGsP::WMView,
|
||||
}
|
||||
|
||||
/// Casts `$widget` to [`WidgetLike`]. Provided for convenience.
|
||||
///
|
||||
/// ## Safety
|
||||
///
|
||||
/// The caller of this macro is responsible for ensuring that the layout of `$widget` is compatible
|
||||
/// with `WidgetLike`.
|
||||
macro_rules! impl_widget {
|
||||
($widget:ty) => {
|
||||
impl Widget for $widget {
|
||||
fn class(&self) -> crate::WINGsP::W_Class {
|
||||
unsafe { ::std::mem::transmute::<&$widget, &WidgetLike>(self).class }
|
||||
}
|
||||
|
||||
fn view(&self) -> ::std::ptr::NonNull<WINGsP::WMView> {
|
||||
let widget = unsafe { ::std::mem::transmute::<&$widget, &WidgetLike>(self) };
|
||||
NonNull::new(widget.view).expect("WMView field of widget struct cannot be null")
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_widget!(WINGsP::WMWindow);
|
||||
impl_widget!(WINGsP::WMFrame);
|
||||
Reference in New Issue
Block a user