Skip to content

Instantly share code, notes, and snippets.

@simlay
Last active April 21, 2020 23:26
Show Gist options
  • Save simlay/b4d60dfe96523f2741d3c2466d4cb44d to your computer and use it in GitHub Desktop.
Save simlay/b4d60dfe96523f2741d3c2466d4cb44d to your computer and use it in GitHub Desktop.
EventHandler.rs
use winit::{
event::{StartCause, Event, WindowEvent},
event_loop::{ControlFlow, EventLoop},
window::{
WindowBuilder,
Window
},
platform::ios::{
WindowExtIOS,
EventLoopExtIOS,
WindowBuilderExtIOS,
},
};
use dispatch::{Queue};
use std::{
sync::{
mpsc::{
channel,
Sender,
},
},
};
use uikit_sys::{
self,
//UIView,
//UIViewController,
UIView_UIViewRendering,
UIView_UIViewHierarchy,
UIView_UIViewGeometry,
UISwitch,
IUISwitch,
UIView,
IUIView,
IUIColor,
UIColor,
CGRect,
CGPoint,
CGSize,
id,
};
pub fn main() -> ! {
debug_init();
log::debug!("STARTING THE APP!");
let event_loop = EventLoop::new();
let window : Window = WindowBuilder::new()
.with_title("UIKit Rust App")
.with_maximized(true)
.build(&event_loop)
.expect("Failed to build window");
window.request_redraw();
let (sender, receiver) = channel();
event_loop.run(move |event: Event<()>, _, control_flow: &mut ControlFlow| {
//println!("{:?}", event);
*control_flow = ControlFlow::Wait;
match event {
Event::NewEvents(StartCause::Init) => {
let root_view: UIView = UIView(window.ui_view() as id );
unsafe {
let color = UIColor::alloc();
let background = UIColor(color.initWithRed_green_blue_alpha_(0.1, 1.0, 2.0, 2.0));
root_view.setBackgroundColor_(background.0);
}
let root_view: UIView = UIView(window.ui_view() as id );
add_views(root_view);
add_switch(root_view, sender.clone());
}
Event::LoopDestroyed => return,
Event::RedrawRequested(_) => {
}
Event::WindowEvent { ref event, .. } => match event {
WindowEvent::Resized(_logical_size) => {
//window.request_redraw();
}
WindowEvent::Touch(_touch) => {
},
WindowEvent::CloseRequested => {
*control_flow = ControlFlow::Exit
}
_ => (),
},
_ => (),
}
})
}
fn add_views(root_view: UIView) {
add_rect(root_view);
add_input(root_view);
}
fn add_rect(root_view: UIView) {
let rect = CGRect {
origin: CGPoint {
x: 10.0,
y: 20.0
},
size: CGSize {
height: 20.0,
width: 20.0,
}
};
unsafe {
let rect = {
let foo : UIView = UIView(UIView::alloc().initWithFrame_(rect));
let yellow = UIColor(UIColor::yellowColor());
foo.setBackgroundColor_(yellow.0);
foo.setUserInteractionEnabled_(true);
foo
};
root_view.addSubview_(rect.0);
}
}
fn add_input(root_view: UIView) {
use uikit_sys::{
UITextView,
IUITextView,
};
let input_rect = CGRect {
origin: CGPoint {
x: 10.0,
y: 50.0
},
size: CGSize {
width: 200.0,
height: 200.0,
}
};
unsafe {
let input = {
let foo = UITextView(
UITextView::alloc().initWithFrame_textContainer_(
input_rect,
0 as id,
)
);
foo
};
root_view.addSubview_(input.0);
}
}
use objc::{
declare::ClassDecl,
runtime::{
Object,
Class,
Sel,
},
};
use core::ffi::c_void;
#[repr(transparent)]
struct EventHandler(pub id);
impl EventHandler {
fn new<F>(func: &mut F) -> Self
where F: FnMut() + Send + 'static
{
let func = func as *mut F as *mut c_void;
let obj = unsafe {
let obj: id = msg_send![Self::class::<F>(), alloc];
let obj: id = msg_send![obj, init];
(*obj).set_ivar::<*mut c_void>("closure", func);
obj
};
Self(obj)
}
extern fn event<F>(this: &Object, _cmd: Sel)
where F: FnMut() + Send + 'static
{
unsafe {
let func = *this.get_ivar::<*mut c_void>("closure") as *mut F;
(*func)();
}
}
fn class<F>() -> &'static Class
where F: FnMut() + Send + 'static
{
let cls_name = "RustHandler";
match Class::get(cls_name) {
Some(cls) => cls,
None => {
let superclass = class!(NSObject);
let mut decl = ClassDecl::new(cls_name, superclass).unwrap();
unsafe {
decl.add_method(
sel!(sendEvent),
Self::event::<F> as extern "C" fn(&Object, Sel),
);
decl.add_ivar::<*mut c_void>(
"closure",
);
}
decl.register()
}
}
}
}
fn add_switch(root_view: UIView, _sender: Sender<i32>) {
use uikit_sys::IUIControl;
let mut foo : i32 = 0;
println!("THIS is foo = {:?}!", foo);
let toggle_handler = EventHandler::new(&mut move ||{
println!("THIS IS THE PASSED IN CLOSURE! foo = {:?}!", foo);
foo += 1;
});
unsafe {
let switch = UISwitch(
IUISwitch::initWithFrame_(
UISwitch::alloc(),
CGRect {
origin: CGPoint {
x: 10.0,
y: 250.0
},
size: CGSize {
height: 20.0,
width: 20.0,
}
}
)
);
switch.addTarget_action_forControlEvents_(
toggle_handler.0,
sel!(sendEvent),
uikit_sys::UIControlEvents_UIControlEventValueChanged,
);
root_view.addSubview_(switch.0);
}
}
fn debug_init() {
color_backtrace::install_with_settings(
color_backtrace::Settings::new().verbosity(color_backtrace::Verbosity::Full),
);
pretty_env_logger::init();
std::env::set_var("RUST_LOG", "DEBUG");
std::env::set_var("RUST_BACKTRACE", "full");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment