use self::rustnsobject::{NSObj, NSObjTrait, NSObjCallbackTrait};
-use std::sync::mpsc::Sender;
+use std::sync::mpsc::{Sender, Receiver};
use std::sync::mpsc::channel;
use std::ptr;
run_mode: *mut objc::runtime::Object,
run_date: *mut objc::runtime::Object,
+ touch_rx: Receiver<TouchbarCommand>,
label: Cell<u64>,
- scrubber: Rc<Scrubber>,
+ scrubber: Rc<TouchbarHandler>,
}
const ITEMS: &'static [&'static str] = &["a rather longer first one", "one","two","much longer than two","three", "seventeen", "A speaker with a very long name is not an impossible thing."];
-struct Scrubber {
+#[derive(Serialize, Deserialize, Debug)]
+enum TouchbarEvent {
+ Play,
+ SelectDevice,
+}
+
+#[derive(Serialize, Deserialize, Debug)]
+struct TouchbarCommand {
+ event: TouchbarEvent,
+ item: touchbar::ItemId,
+ value: Option<u32>,
+}
+
+struct TouchbarHandler {
devices: RefCell<Vec<String>>,
- touch_tx: Sender<(touchbar::ItemId,u32)>,
+ touch_tx: Sender<TouchbarCommand>,
+}
+
+impl TouchbarHandler {
+ fn play(&self, item: touchbar::ItemId) {
+ info!("Handler BUTTON: {}", item);
+ self.touch_tx.send(TouchbarCommand {
+ event: TouchbarEvent::Play,
+ item: item,
+ value: None
+ });
+ }
}
-impl TScrubberData for Scrubber {
+impl TScrubberData for TouchbarHandler {
fn count(&self, item: touchbar::ItemId) -> u32 {
let dev = self.devices.borrow();
let len = (*dev).len();
}
fn touch(&self, item: touchbar::ItemId, idx: u32) {
info!("scrub touch: {}", idx);
- self.touch_tx.send((item, idx));
+
+ self.touch_tx.send(TouchbarCommand {
+ event: TouchbarEvent::SelectDevice,
+ item: item,
+ value: None
+ });
}
}
let mut bar;
unsafe {
let app = NSApp();
- let (touch_tx,touch_rx) = channel::<(touchbar::ItemId,u32)>();
+ let (touch_tx,touch_rx) = channel::<TouchbarCommand>();
let status_bar = NSStatusBar::systemStatusBar(nil);
let date_cls = Class::get("NSDate").unwrap();
- let scrubber = Rc::new(Scrubber {
+ let scrubber = Rc::new(TouchbarHandler {
devices: RefCell::new(vec!["one".to_string(), "two".to_string(),
"a little bit longer one".to_string(),
"three".to_string(),
run_count: Cell::new(0),
run_mode: NSString::alloc(nil).init_str("kCFRunLoopDefaultMode"),
run_date: msg_send![date_cls, distantPast],
+ touch_rx: touch_rx,
label: Cell::new(0),
scrubber: scrubber.clone(),
};
let barid = bar.touchbar.create_bar();
let text = NSString::alloc(nil).init_str("hi1");
- let b1id = bar.touchbar.create_button(nil, text, Box::new(move |_| {}));
+ let scrub1 = scrubber.clone();
+ //let b1id = bar.touchbar.create_button(nil, text, Box::new(move |_| {}));
+ let b1id = bar.touchbar.create_button(nil, text, Box::new(move |s| {scrub1.play(s)}));
let text = NSString::alloc(nil).init_str("hi2");
let b2id = bar.touchbar.create_button(nil, text, Box::new(move |_| {}));
+ let s2id = bar.touchbar.create_text_scrubber(scrubber.clone());
+ bar.touchbar.select_scrubber_item(s2id, 3);
+
let popid = bar.touchbar.create_bar();
let p1id = bar.touchbar.create_popover_item(popid);
let text = NSString::alloc(nil).init_str("hi3");
let b3id = bar.touchbar.create_button(nil, text, Box::new(move |_| {}));
- bar.touchbar.add_items_to_bar(popid, vec![b3id]);
+ bar.touchbar.add_items_to_bar(popid, vec![b3id, s2id]);
let s1id = bar.touchbar.create_text_scrubber(scrubber.clone());
bar.touchbar.select_scrubber_item(s1id, 1);
let l1id = bar.touchbar.create_label();
- bar.label.set(s1id);
- //bar.touchbar.add_items_to_bar(barid, vec![b1id, b2id, p1id]);
bar.touchbar.add_items_to_bar(barid, vec![b1id, b2id, p1id, l1id, s1id]);
bar.touchbar.set_bar_as_root(barid);
+ // for fuckery
+ bar.label.set(s1id);
+
let _: () = msg_send![app, finishLaunching];
bar.touchbar.enable();
}
}
fn run(&mut self, block: bool) {
loop {
+ if let Ok(cmd) = self.touch_rx.try_recv() {
+ match cmd.event {
+ TouchbarEvent::Play => {
+ info!("PLAY on main thread");
+
+ },
+ _ => {}
+ }
+ }
unsafe {
let run_count = self.run_count.get();
// Create a new release pool every once in a while, draining the old one
bar_obj_map: BTreeMap<ItemId, Ident>,
control_obj_map: BTreeMap<ItemId, ItemId>,
scrubber_obj_map: BTreeMap<ItemId, Scrubber>,
+ button_cb_map: BTreeMap<ItemId, ButtonCb>,
}
pub type Touchbar = Box<RustTouchbarDelegateWrapper>;
bar_obj_map: BTreeMap::<ItemId, Ident>::new(),
control_obj_map: BTreeMap::<ItemId, ItemId>::new(),
scrubber_obj_map: BTreeMap::<ItemId, Scrubber>::new(),
+ button_cb_map: BTreeMap::<ItemId, ButtonCb>::new(),
});
unsafe {
let ptr: u64 = &*rust as *const RustTouchbarDelegateWrapper as u64;
unsafe {
let item = scrub_id as *mut Object;
let scrubber: *mut Object = msg_send![item, view];
- //let layout: *mut Object = msg_send![scrubber, scrubberLayout];
- //let _:() = msg_send![layout, invalidateLayout];
+ let sel_idx: u32 = msg_send![scrubber, selectedIndex];
let _:() = msg_send![scrubber, reloadData];
+ // reload clears the selected item. re-select it.
+ let _:() = msg_send![scrubber, setSelectedIndex: sel_idx];
}
}
fn create_button(&mut self, image: *mut Object, text: *mut Object, cb: ButtonCb) -> ItemId {
self.bar_obj_map.insert(item as u64, ident as u64);
self.control_obj_map.insert(btn as u64, item as u64);
+ self.button_cb_map.insert(btn as u64, cb);
item as u64
}
}
//
//}
}
- extern fn objc_button(_this: &mut Object, _cmd: Sel, _sender: u64) {
- let sender = _sender as *mut Object;
+ extern fn objc_button(this: &mut Object, _cmd: Sel, sender: u64) {
info!("Button push: {}", sender as u64);
+ unsafe {
+ let ptr: u64 = *this.get_ivar("_rust_wrapper");
+ let wrapper = &mut *(ptr as *mut RustTouchbarDelegateWrapper);
+ let ref cb = *wrapper.button_cb_map.get(&sender).unwrap();
+ cb(sender);
+ }
//unsafe {
//let slider: *mut Object = msg_send![sender, slider];
//let val: u32 = msg_send![slider, intValue];