#[cfg(feature = "mac_touchbar")]
mod touchbar;
#[cfg(feature = "mac_touchbar")]
-use self::touchbar::{Touchbar, TouchbarTrait};
+use self::touchbar::{Touchbar, TouchbarTrait, TScrubberData};
#[cfg(not(feature = "mac_touchbar"))]
struct Touchbar {}
#[cfg(not(feature = "mac_touchbar"))]
use self::rustnsobject::{NSObj, NSObjTrait, NSObjCallbackTrait};
use std::sync::mpsc::Sender;
+use std::sync::mpsc::channel;
use std::ptr;
+use std::rc::Rc;
use std::cell::Cell;
+use std::cell::RefCell;
+use std::borrow::BorrowMut;
use std::ffi::CStr;
use std::thread::sleep;
use std::time::Duration;
label: Cell<u64>,
devices: Vec<String>,
+ scrubber: Rc<Scrubber>,
}
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."];
-fn scrub_count(context: *const u32, item: touchbar::ItemId) -> u32 {
- info!("MOD GOT SCRUBBER COUNT REQUEST");
- let context = context as *const OSXStatusBar;
- unsafe {
- (*context).devices.len() as u32
- }
+struct Scrubber {
+ devices: RefCell<Vec<String>>,
+ touch_tx: Sender<(touchbar::ItemId,u32)>,
}
-fn scrub_text(context: *const u32, item: touchbar::ItemId, idx: u32) -> String {
- let context = context as *const OSXStatusBar;
- unsafe {
+
+impl TScrubberData for Scrubber {
+ fn count(&self, item: touchbar::ItemId) -> u32 {
+ let dev = self.devices.borrow();
+ let len = (*dev).len();
+ info!("MOD GOT SCRUBBER COUNT REQUEST {}", len);
+ self.devices.borrow().len() as u32
+ }
+ fn text(&self, item: touchbar::ItemId, idx: u32) -> String {
info!("MOD GOT SCRUBBER TEXT REQUEST {}", idx);
- //"froop".to_string()
- (*context).devices[idx as usize].to_string()
+ self.devices.borrow()[idx as usize].to_string()
}
-}
-fn scrub_width(context: *const u32, item: touchbar::ItemId, idx: u32) -> u32 {
- info!("scrub_width {} {:?}", idx, context);
- // 10px per character + some padding seems to work nicely for the default
- // font. no idea what it's like on other machines. does the touchbar
- // font change? ¯\_(ツ)_/¯
- unsafe {
- let context = context as *const OSXStatusBar;
- info!("context: {:?}", context);
- let context: &OSXStatusBar = &*context;
- info!("get len");
- let devices: &Vec<String> = &context.devices;
- info!("got devices");
- info!("devices ptr: {:?}", devices as *const Vec<String>);
- info!("devices len: {}", devices.len());
- info!("{:?}", devices);
- let ref s = (*context).devices[idx as usize];
- info!("get string {}", s);
- let len = s.len() as u32;
- info!("got len {}", len);
+ fn width(&self, item: touchbar::ItemId, idx: u32) -> u32 {
+ info!("scrub_width {}", idx);
+ // 10px per character + some padding seems to work nicely for the default
+ // font. no idea what it's like on other machines. does the touchbar
+ // font change? ¯\_(ツ)_/¯
+ let len = self.devices.borrow()[idx as usize].len() as u32;
let width = len * 8 + 20;
info!("Width for {}: {}", len, width);
width
}
-}
-fn scrub_touch(context: *const u32, item: touchbar::ItemId, idx: u32) {
+ fn touch(&self, item: touchbar::ItemId, idx: u32) {
+ info!("scrub touch: {}", idx);
+ self.touch_tx.send((item, idx));
+ }
}
impl TStatusBar for OSXStatusBar {
let mut bar;
unsafe {
let app = NSApp();
+ let (touch_tx,touch_rx) = channel::<(touchbar::ItemId,u32)>();
let status_bar = NSStatusBar::systemStatusBar(nil);
let date_cls = Class::get("NSDate").unwrap();
+ let scrubber = Rc::new(Scrubber {
+ devices: RefCell::new(vec!["one".to_string(), "two".to_string(),
+ "a little bit longer one".to_string(),
+ "three".to_string(),
+ "this one is really quite a bit longer than the others".to_string()]),
+ //Vec::<String>::new(),
+ touch_tx: touch_tx,
+ });
bar = OSXStatusBar {
app: app,
status_bar_item: status_bar.statusItemWithLength_(NSVariableStatusItemLength),
run_date: msg_send![date_cls, distantPast],
label: Cell::new(0),
devices: Vec::new(),
+ scrubber: scrubber.clone(),
};
// Don't become foreground app on launch
bar.app.setActivationPolicy_(NSApplicationActivationPolicyAccessory);
let b3id = bar.touchbar.create_button(nil, text, Box::new(move |_| {}));
bar.touchbar.add_items_to_bar(popid, vec![b3id]);
- let l1id = bar.touchbar.create_label();
- bar.label.set(l1id);
-
for item in ITEMS {
bar.devices.push(item.to_string());
}
info!("devices: {:?}", (&bar.devices) as *const Vec<String>);
let bar_ptr = &bar as *const OSXStatusBar as *const u32;
info!("bar ptr: {:?}", bar_ptr);
+ //let testfn: Box<FnMut()> = Box::new(bar.test);
+ let scrubber1 = scrubber.clone();
+ let scrubber2 = scrubber.clone();
+ let scrubber3 = scrubber.clone();
+ let scrubber4 = scrubber.clone();
let s1id = bar.touchbar.create_text_scrubber(
- bar_ptr,
- scrub_count,
- scrub_text,
- scrub_width,
- scrub_touch);
+ Box::new(move |s| { scrubber1.count(s) }),
+ Box::new(move |s,i| { scrubber2.text(s,i) }),
+ Box::new(move |s,i| { scrubber3.width(s,i) }),
+ Box::new(move |s,i| { scrubber4.touch(s,i) }),
+ );
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);
bar.touchbar.enable();
}
bar
- }
+ }
fn touchbar(&mut self) {
info!("Touchbar fucker!");
- info!("devices: {:?}", (&self.devices) as *const Vec<String>);
- let bar_ptr = self as *const OSXStatusBar as *const u32;
- info!("bar ptr: {:?}", bar_ptr);
+ self.scrubber.devices.borrow_mut().push("a new device!".to_string());
+ let l1id = self.label.get();
+ //self.touchbar.select_scrubber_item(l1id, 0);
+ self.touchbar.refresh_scrubber(l1id);
+ //self.touchbar.update_label(l1id);
unsafe {
- let l1id = self.label.get();
- self.touchbar.update_label(l1id);
//let barid = self.touchbar.create_bar();
//let text = NSString::alloc(nil).init_str("hi1");
}
}
+pub trait TScrubberData {
+ fn count(&self, item: ItemId) -> u32;
+ fn text(&self, item: ItemId, idx: u32) -> String;
+ fn width(&self, item: ItemId, idx: u32) -> u32;
+ fn touch(&self, item: ItemId, idx: u32);
+}
+
+//use std::rc::Rc;
+
struct Scrubber {
+ //struct Scrubber<T> where T: TScrubberData {
+ //data: Rc<T>,
count_cb: ScrubberCountFn,
text_cb: ScrubberTextFn,
width_cb: ScrubberWidthFn,
touch_cb: ScrubberTouchFn,
- context: *const u32,
_item: ItemId,
_scrubber: ItemId,
_ident: Ident,
fn create_label(&mut self) -> ItemId;
fn update_label(&mut self, label_id: ItemId);
fn create_text_scrubber(&mut self,
- context: *const u32,
count_fn: ScrubberCountFn,
text_fn: ScrubberTextFn,
width_fn: ScrubberWidthFn,
touch_fn: ScrubberTouchFn) -> ItemId;
fn select_scrubber_item(&mut self, scrub_id: ItemId, index: u32);
+ fn refresh_scrubber(&mut self, scrub_id: ItemId);
fn create_button(&mut self, image: *mut Object, text: *mut Object, cb: ButtonCb) -> ItemId;
}
-pub type ScrubberCountFn = fn(*const u32, ItemId) -> u32;
-pub type ScrubberTextFn = fn(*const u32, ItemId, u32) -> String;
-pub type ScrubberWidthFn = fn(*const u32, ItemId, u32) -> u32;
-pub type ScrubberTouchFn = fn(*const u32, ItemId, u32);
+//pub type ScrubberCountFn = fn(*const u32, ItemId) -> u32;
+//pub type ScrubberTextFn = fn(*const u32, ItemId, u32) -> String;
+//pub type ScrubberWidthFn = fn(*const u32, ItemId, u32) -> u32;
+//pub type ScrubberTouchFn = fn(*const u32, ItemId, u32);
+
+pub type ScrubberCountFn = Box<Fn(ItemId) -> u32>;
+pub type ScrubberTextFn = Box<Fn(ItemId, u32) -> String>;
+pub type ScrubberWidthFn = Box<Fn(ItemId, u32) -> u32>;
+pub type ScrubberTouchFn = Box<Fn(ItemId, u32)>;
+
impl RustTouchbarDelegateWrapper {
fn generate_ident(&mut self) -> u64 {
}
}
fn create_text_scrubber(&mut self,
- context: *const u32,
count_fn: ScrubberCountFn,
text_fn: ScrubberTextFn,
width_fn: ScrubberWidthFn,
count_cb: count_fn,
width_cb: width_fn,
touch_cb: touch_fn,
- context: context,
_ident: ident as u64,
_item: item as u64,
_scrubber: scrubber as u64,
let _:() = msg_send![scrubber, setSelectedIndex: index];
}
}
+ fn refresh_scrubber(&mut self, scrub_id: ItemId) {
+ 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 _:() = msg_send![scrubber, reloadData];
+ }
+ }
fn create_button(&mut self, image: *mut Object, text: *mut Object, cb: ButtonCb) -> ItemId {
unsafe {
let ident = self.generate_ident();
let scrubber = scrub as *mut Object;
let scrub_struct = wrapper.scrubber_obj_map.get(&scrub).unwrap();
let item = scrub_struct._item;
- (scrub_struct.count_cb)(scrub_struct.context, item)
+ (scrub_struct.count_cb)(item)
}
}
extern fn objc_scrubber_view_for_item_at_index(this: &mut Object, _cmd: Sel,
let ident = scrub_struct._ident as *mut Object;
let view: *mut Object = msg_send![scrubber,
makeItemWithIdentifier:ident owner:nil];
- let text = (scrub_struct.text_cb)(scrub_struct.context, item, idx);
+ let text = (scrub_struct.text_cb)(item, idx);
let text_field: *mut Object = msg_send![view, textField];
let objc_text: *mut Object = NSString::alloc(nil).init_str(&text);
let _:() = msg_send![text_field, setStringValue: objc_text];
let scrub_struct = wrapper.scrubber_obj_map.get(&scrub).unwrap();
let item = scrub_struct._item;
info!("scrubber item size call CB");
- let width = (scrub_struct.width_cb)(scrub_struct.context, item, idx);
+ let width = (scrub_struct.width_cb)(item, idx);
NSSize::new(width as f64, 30.)
}
}
extern fn objc_scrubber_did_select_item_at_index(this: &mut Object, _cmd: Sel,
- _scrub: u64, _idx: u32) {
+ scrub: u64, idx: u32) {
info!("scrubber selected");
+ unsafe {
+ let ptr: u64 = *this.get_ivar("_rust_wrapper");
+ let wrapper = &mut *(ptr as *mut RustTouchbarDelegateWrapper);
+ let scrubber = scrub as *mut Object;
+ let scrub_struct = wrapper.scrubber_obj_map.get(&scrub).unwrap();
+ let item = scrub_struct._item;
+ (scrub_struct.touch_cb)(item, idx);
+ }
}
extern fn objc_popbar(this: &mut Object, _cmd: Sel, sender: u64) {
info!("Popbar push: {}", sender as u64);