- Overview
- Project Architecture
- Installation and Setup
- Core Components
- Event System
- Properties and Styling
- Usage Guide
- Testing
- API Reference
- Contributing
WinR is a Rust library designed for developing Windows-style GUI applications. The library provides a modular, component-oriented framework that enables the creation of robust user interfaces for Windows applications.
- Component-oriented architecture: Modular system based on reusable components
- Advanced event system: Event handling with weak references to prevent memory leaks
- CSS-like properties: Sizing, positioning, margin and padding system similar to CSS
- Serialization: Complete support for serialization/deserialization with Serde
- Integrated testing: Complete testing framework for components and serialization
- Windows API Integration: Native integration with Windows API
- Rust Edition 2024
- Serde: For serialization and deserialization
- Windows API: For native Windows integration
- Regex: For text processing and validations
The project is organized into clearly defined modules:
src/
├── core/ # Library core
│ ├── components/ # Component system
│ │ ├── base_component.rs
│ │ ├── elements/ # UI Elements (Button, Icon, Link)
│ │ ├── layouts/ # Layout systems
│ │ ├── properties/ # Component properties
│ │ └── styles/ # Style system
│ ├── ui/ # User interface system
│ │ ├── elements/ # Advanced UI elements
│ │ └── systems/ # UI systems (layout, theme, navigation)
│ ├── utils/ # Utilities
│ │ ├── functions.rs
│ │ └── traits/ # Fundamental traits
│ └── window/ # Window and event system
│ └── events/
├── testing/ # Testing framework
│ ├── blackbox/
│ ├── run/
│ └── serialization/
└── lib.rs
- Rust 1.75+ (Edition 2024)
- Windows 10/11
- Visual Studio Build Tools (for Windows API)
[dependencies]
WinR = { path = "path/to/WinR" }[dependencies]
regex = "1.11.1"
serde = { version = "1.0.219", features = ["derive"] }
serde_json = "1.0.140"
windows = "0.61.3"The BaseComponent is the base class for all components in WinR. It provides fundamental functionalities such as:
- Unique ID: Each component has a unique identifier
- Positioning system: Position, Size, Margin, Padding
- Calculated boundaries: Automatic bounds based on sizing mode
- Event system: Integration with EventSystem
- Serialization: Complete Serde support
pub enum BoundarySizingMode {
ContentBox, // Without margin or padding
BorderBox, // Includes padding, excludes margin
MarginBox, // Includes margin and padding
}use WinR::core::components::base_component::BaseComponent;
use WinR::core::components::properties::{Size, Position, Margin, Padding};
let size = Size::new(200, 100);
let position = Position::new(10, 20);
let margin = Margin::uniform(5);
let padding = Padding::uniform(10);
let mut component = BaseComponent::new(
size,
position,
margin,
padding,
event_system
);Button component with icon support and click events.
pub struct Button {
icon: Option<(Icon, IconPosition)>,
text: String,
enabled: bool,
on_click: Option<Box<dyn Fn()>>,
}Features:
- Customizable text
- Optional icons (Start/End position)
- Enabled/disabled state
- Click callback
Integrated icon system for UI elements.
Link component with navigation.
The event system uses weak references to prevent memory leaks and provides a robust pub/sub system.
pub enum Event {
// Component events
ComponentAdded,
ComponentRemoved,
ComponentResized,
ComponentMoved,
ComponentPaddingChanged,
ComponentMarginChanged,
ComponentVisibilityChanged,
// Window events
WindowOpened,
WindowClosed,
WindowFocused,
WindowMaximized,
WindowMinimized,
WindowResized,
WindowMoved,
WindowTitleChanged,
WindowIconChanged,
// Input events
KeyPressed,
KeyReleased,
MouseButtonPressed,
MouseButtonReleased,
MouseMoved,
MouseScrolled,
// Animation events
AnimationStarted,
AnimationCompleted,
AnimationTransitionStarted,
AnimationTransitionEnded,
// Form events
FieldFocused,
FieldFocusedLost,
FieldValueChanged,
// System events
RenderRequested,
UpdateRequested,
}use WinR::core::utils::traits::event_listener::EventListener;
use WinR::core::window::events::types::Event;
struct MyComponent {
// ... fields
}
impl EventListener for MyComponent {
fn on_event(&mut self, event: &Event, caller_id: usize) {
match event {
Event::ComponentResized => {
// Handle resize
},
Event::MouseButtonPressed => {
// Handle mouse click
},
_ => {}
}
}
}// Subscribe a component to events
event_system.borrow_mut().subscribe(
Event::ComponentResized,
Rc::downgrade(&component_rc)
);
// Emit an event
event_system.borrow_mut().emit(Event::ComponentResized, component_id);pub struct Size {
height: u16,
width: u16,
}
// Usage
let size = Size::new(200, 100)
.with_width(250)
.with_height(150);pub struct Position {
x: u16,
y: u16,
}
// Usage
let position = Position::new(10, 20)
.in_x(50)
.in_y(100);// Uniform margin
let margin = Margin::uniform(10);
// Individual margin
let margin = Margin {
top: 5,
right: 10,
bottom: 5,
left: 10,
};The graphics module includes:
- ActionState: Interaction states (Normal, Hover, Pressed, Disabled)
- Background: Background configuration
- Border: Border system
- Color: Color handling
- Gradient: Linear and radial gradients
The boundaries system automatically calculates component bounds based on:
- Component position
- Component size
- Applied margin
- Applied padding
- Selected BoundarySizingMode
use std::{cell::RefCell, rc::Rc};
use WinR::core::{
components::{
base_component::BaseComponent,
properties::{Size, Position, Margin, Padding}
},
window::events::event_system::EventSystem
};
fn create_basic_component() -> BaseComponent {
let event_system = Rc::new(RefCell::new(EventSystem::default()));
let component = BaseComponent::new(
Size::new(200, 100),
Position::new(10, 10),
Margin::uniform(5),
Padding::uniform(10),
event_system
);
component
}// Create event system
let event_system = Rc::new(RefCell::new(EventSystem::default()));
// Create component
let mut component = BaseComponent::new(
Size::new(100, 50),
Position::new(0, 0),
Margin::default(),
Padding::default(),
event_system.clone()
);
// Events are automatically emitted when changing properties
component.set_size(Size::new(150, 75)); // Emits Event::ComponentResized
component.set_position(Position::new(20, 30)); // Emits Event::ComponentMoveduse serde_json;
// Serialize component
let component = create_basic_component();
let json = serde_json::to_string(&component).unwrap();
// Deserialize component
let mut deserialized: BaseComponent = serde_json::from_str(&json).unwrap();
// Re-inject event system after deserializing
deserialized.inyect_event_system(event_system);WinR includes a complete testing framework organized into three modules:
Located in src/testing/serialization/, includes tests for:
- background_tests.rs: Background properties testing
- border_tests.rs: Border properties testing
- color_tests.rs: Color system testing
- gradient_tests.rs: Gradient testing
- margin_tests.rs: Margin testing
- overflow_tests.rs: Overflow testing
- padding_tests.rs: Padding testing
- position_tests.rs: Positioning testing
- size_tests.rs: Size testing
# Run all tests
cargo test
# Run specific serialization tests
cargo test serialization
# Run tests with detailed output
cargo test -- --nocapture#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_component_creation() {
let event_system = Rc::new(RefCell::new(EventSystem::default()));
let component = BaseComponent::new(
Size::new(100, 50),
Position::new(10, 20),
Margin::uniform(5),
Padding::uniform(8),
event_system
);
assert_eq!(component.size().width(), 100);
assert_eq!(component.size().height(), 50);
assert_eq!(component.position().x(), 10);
assert_eq!(component.position().y(), 20);
}
}new(size, position, margin, padding, event_system) -> Self
set_size(size: Size)- EmitsComponentResizedset_position(position: Position)- EmitsComponentMovedset_margin(margin: Margin)- EmitsComponentMarginChangedset_padding(padding: Padding)- EmitsComponentPaddingChangedset_visible(visible: bool)- EmitsComponentVisibilityChanged
size() -> &Sizeposition() -> &Positionmargin() -> &Marginpadding() -> &Paddingbounds() -> Option<&Boundaries>id() -> &usizevisible() -> &boolsizing_mode() -> BoundarySizingMode
calculate_bounds()- Recalculates boundaries based on sizing_modeinyect_event_system(event_system)- Re-injects the event system
get_next_id() -> usize- Gets the next unique IDsubscribe<L: EventListener>(event: Event, listener: Weak<RefCell<L>>)- Subscribes a listeneremit(event: Event, caller_id: usize)- Emits an eventcleanup()- Cleans up removed listeners
pub trait EventListener {
fn on_event(&mut self, event: &Event, caller_id: usize);
}// Located in utils/traits/renderable.rs
// For implementing component rendering// Located in utils/traits/style_merge.rs
// For CSS-like style merging- Implemented through EventSystem
- Weak references prevent memory leaks
- Automatic cleanup of dead listeners
- BaseComponent as common base
- Specialization through specific elements
- Composition over inheritance
- Chainable methods in Size, Position
- Fluent component construction
- Serde integration for persistence
- Skip non-serializable fields (event_system)
- Re-injection pattern for restoring references
- Use of
Rc<RefCell<>>for shared ownership - Weak references in event system
- Automatic listener cleanup
- Automatic filtering of dead listeners
- Manual cleanup available
- Unique IDs for efficient identification
- Lazy boundary calculation
- Automatic invalidation when changing properties
- Different sizing modes for optimization
- Complete theme system
- Animations and transitions
- Advanced layout managers
- More UI elements (TextBox, ComboBox, etc.)
- Data binding system
- Custom drawing support
- Event system optimization
- Better Windows API integration
- Interactive documentation
- More complete examples
- Fork the repository
- Create feature branch:
git checkout -b feature/new-feature - Write tests for new functionality
- Implement the functionality
- Ensure all tests pass:
cargo test - Commit with descriptive messages
- Push to branch:
git push origin feature/new-feature - Create Pull Request
- Follow Rust conventions (rustfmt)
- Document all public APIs
- Include tests for new functionality
- Maintain backward compatibility when possible
- New UI components: Expand the element library
- Optimizations: Improve event system performance
- Documentation: Improve examples and guides
- Testing: Expand test coverage
- Windows Integration: Improve native integration
This project is under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) License. See the License.md file for more details.
- Issues: Report bugs and request features on GitHub
- Discussions: For questions and general discussions
- Documentation: This documentation is updated regularly
Documentation automatically generated for WinR v0.1.0