summary history branches tags files
commit:d9b427a412bb020756a8cb1f36c1cd4beb2072dd
author:Trevor Bentley
committer:Trevor Bentley
date:Mon Jul 10 14:48:21 2017 +0200
parents:be5d0997c29236b5f1f56599a7b3cb837ca18690
Buttons call up the stack
diff --git a/src/osx/mod.rs b/src/osx/mod.rs
line changes: +58/-12
index dd1fc47..c632ac0
--- a/src/osx/mod.rs
+++ b/src/osx/mod.rs
@@ -38,7 +38,7 @@ use self::cocoa::appkit::{NSApp,
 
 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;
@@ -70,18 +70,43 @@ pub struct OSXStatusBar {
     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();
@@ -104,7 +129,12 @@ impl TScrubberData for Scrubber {
     }
     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
+        });
     }
 }
 
@@ -114,10 +144,10 @@ impl TStatusBar for OSXStatusBar {
         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(),
@@ -135,6 +165,7 @@ impl TStatusBar for OSXStatusBar {
                 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(),
             };
@@ -190,26 +221,32 @@ impl TStatusBar for OSXStatusBar {
 
             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();
         }
@@ -333,6 +370,15 @@ impl TStatusBar for OSXStatusBar {
     }
     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

diff --git a/src/osx/touchbar.rs b/src/osx/touchbar.rs
line changes: +13/-4
index 104f4f1..5519f7c
--- a/src/osx/touchbar.rs
+++ b/src/osx/touchbar.rs
@@ -63,6 +63,7 @@ pub struct RustTouchbarDelegateWrapper {
     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>;
@@ -116,6 +117,7 @@ impl TouchbarTrait for Touchbar {
             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;
@@ -290,9 +292,10 @@ impl TouchbarTrait for Touchbar {
         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 {
@@ -331,6 +334,7 @@ impl TouchbarTrait for Touchbar {
 
             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
         }
     }
@@ -481,9 +485,14 @@ impl INSObject for ObjcAppDelegate {
                 //
                 //}
             }
-            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];