Created
October 28, 2024 19:34
-
-
Save 2tvenom/05c868e506a80696cc4bef7005c02453 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use crate::outline::{data_source::OutlineViewDataSource, delegate::OutlineViewDelegate}; | |
use crate::AppDelegate; | |
use objc2::__framework_prelude::ProtocolObject; | |
use objc2::rc::{Retained, Weak}; | |
use objc2::{declare_class, msg_send_id, sel, ClassType, DeclaredClass, MainThreadOnly}; | |
use objc2_app_kit::{ | |
NSButton, NSColor, NSOutlineView, NSScrollView, NSSplitViewController, NSSplitViewItem, | |
NSViewController, | |
}; | |
use objc2_foundation::{ns_string, MainThreadMarker, NSObjectProtocol}; | |
use std::cell::OnceCell; | |
use std::ops::Deref; | |
#[derive(Debug)] | |
pub struct SplitViewIvars { | |
app_delegate: OnceCell<Retained<AppDelegate>>, | |
outline_view_data_source: OnceCell<Retained<OutlineViewDataSource>>, | |
outline_view_delegate: OnceCell<Retained<OutlineViewDelegate>>, | |
} | |
declare_class!( | |
#[derive(Debug)] | |
pub struct SplitViewController; | |
unsafe impl ClassType for SplitViewController { | |
type Super = NSViewController; | |
const NAME: &'static str = "SecondViewController"; | |
} | |
impl DeclaredClass for SplitViewController { | |
type Ivars = SplitViewIvars; | |
} | |
unsafe impl NSObjectProtocol for SplitViewController {} | |
unsafe impl SplitViewController { | |
#[method(loadView)] | |
fn load_view(&self) { | |
let mtm = MainThreadMarker::from(self); | |
self._load_view(mtm) | |
} | |
} | |
); | |
impl SplitViewController { | |
pub fn new(mtm: MainThreadMarker, app: Retained<AppDelegate>) -> Retained<Self> { | |
let this = mtm.alloc(); | |
let app_once: OnceCell<Retained<AppDelegate>> = OnceCell::new(); | |
app_once.set(app).expect("app already initialized"); | |
let this = this.set_ivars(SplitViewIvars { | |
app_delegate: app_once, | |
outline_view_data_source: OnceCell::default(), | |
outline_view_delegate: OnceCell::default(), | |
}); | |
unsafe { msg_send_id![super(this), init] } | |
} | |
fn _load_view(&self, mtm: MainThreadMarker) { | |
let color = unsafe { | |
NSColor::colorWithDisplayP3Red_green_blue_alpha(31. / 255., 33. / 255., 35. / 255., 1.) | |
}; | |
let data_source = OutlineViewDataSource::new(mtm); | |
self.ivars() | |
.outline_view_data_source | |
.set(data_source.clone()) | |
.expect("error set outline datasource"); | |
let data_source_obj = ProtocolObject::from_ref(data_source.deref()); | |
let delegate = OutlineViewDelegate::new(mtm); | |
self.ivars() | |
.outline_view_delegate | |
.set(delegate.clone()) | |
.expect("error set outline delegate"); | |
let delegate_obj = ProtocolObject::from_ref(delegate.deref()); | |
let ov = unsafe { | |
let ov = NSOutlineView::init(mtm.alloc()); | |
ov.setBackgroundColor(&color); | |
ov.setHeaderView(None); | |
ov.setDataSource(Some(data_source_obj)); | |
ov.setDelegate(Some(delegate_obj)); | |
ov | |
}; | |
let sc = unsafe { | |
let scroll = NSScrollView::init(mtm.alloc()); | |
scroll.setDocumentView(Some(&ov)); | |
scroll.setBackgroundColor(&color); | |
scroll | |
}; | |
let sidebar = unsafe { | |
let vc = NSViewController::init(mtm.alloc()); | |
vc.setView(&sc); | |
let s = NSSplitViewItem::init(mtm.alloc()); | |
s.setAllowsFullHeightLayout(true); | |
s.setMinimumThickness(100.); | |
s.setMaximumThickness(200.); | |
s.setCanCollapse(true); | |
s.setViewController(&vc); | |
s | |
}; | |
let detail = unsafe { | |
let v = NSScrollView::new(mtm); | |
v.setBackgroundColor(&color); | |
let b1 = NSButton::buttonWithTitle_target_action( | |
ns_string!("second view button 1"), | |
Some(self.ivars().app_delegate.get().unwrap()), | |
Some(sel!(action1:)), | |
mtm, | |
); | |
v.addSubview(&b1); | |
let vc = NSViewController::init(mtm.alloc()); | |
vc.setView(&v); | |
let detail = NSSplitViewItem::init(mtm.alloc()); | |
detail.setViewController(&vc); | |
detail.setAllowsFullHeightLayout(true); | |
detail | |
}; | |
let split = unsafe { | |
let s = NSSplitViewController::init(mtm.alloc()); | |
s.view().setWantsLayer(true); | |
s.addSplitViewItem(&sidebar); | |
s.addSplitViewItem(&detail); | |
s | |
}; | |
unsafe { self.setView(&split.view()) } | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use objc2::rc::Retained; | |
use objc2::runtime::{AnyObject, NSObject, NSObjectProtocol}; | |
use objc2::{class, declare_class, msg_send_id, ClassType, DeclaredClass, MainThreadOnly}; | |
use objc2_app_kit::{NSOutlineView, NSOutlineViewDataSource, NSTableColumn}; | |
use objc2_foundation::{MainThreadMarker, NSInteger, NSString}; | |
declare_class!( | |
#[derive(Debug)] | |
pub struct OutlineViewDataSource; | |
unsafe impl ClassType for OutlineViewDataSource { | |
type Super = NSObject; | |
type ThreadKind = dyn MainThreadOnly; | |
const NAME: &'static str = "OutlineViewDataSource"; | |
} | |
impl DeclaredClass for OutlineViewDataSource {} | |
unsafe impl NSObjectProtocol for OutlineViewDataSource {} | |
unsafe impl NSOutlineViewDataSource for OutlineViewDataSource { | |
#[method(outlineView:numberOfChildrenOfItem:)] | |
unsafe fn outline_view_number_of_children_of_item( | |
&self, | |
_: &NSOutlineView, | |
item: Option<&AnyObject>, | |
) -> NSInteger { | |
if let Some(item) = item { | |
0 | |
} else { | |
5 | |
} | |
} | |
#[method_id(outlineView:child:ofItem:)] | |
unsafe fn outline_view_child_of_item( | |
&self, | |
_: &NSOutlineView, | |
_: NSInteger, | |
item: Option<&AnyObject>, | |
) -> Retained<AnyObject> { | |
let key: Retained<AnyObject> = unsafe { msg_send_id![class!(NSString), new] }; | |
key | |
} | |
#[method(outlineView:isItemExpandable:)] | |
unsafe fn outline_view_is_item_expandable( | |
&self, | |
_: &NSOutlineView, | |
item: &AnyObject, | |
) -> bool { | |
false | |
} | |
#[method_id(outlineView:objectValueForTableColumn:byItem:)] | |
unsafe fn outline_view_object_value_for_table_column_by_item( | |
&self, | |
outline_view: &NSOutlineView, | |
table_column: Option<&NSTableColumn>, | |
item: Option<&AnyObject>, | |
) -> Option<Retained<AnyObject>> { | |
let key: Retained<AnyObject> = unsafe { msg_send_id![class!(NSString), new] }; | |
Some(key) | |
} | |
} | |
); | |
impl OutlineViewDataSource { | |
pub fn new(mtm: MainThreadMarker) -> Retained<Self> { | |
let this = mtm.alloc(); | |
unsafe { msg_send_id![this, init] } | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::ops::Deref; | |
use objc2::rc::{Retained, Weak}; | |
use objc2::runtime::{AnyObject, NSObject, NSObjectProtocol}; | |
use objc2::{declare_class, msg_send_id, ClassType, DeclaredClass, MainThreadOnly, Message}; | |
use objc2_app_kit::{NSCell, NSControlTextEditingDelegate, NSOutlineView, NSOutlineViewDelegate, NSTableCellView, NSTableColumn, NSTextField, NSView}; | |
use objc2_foundation::{ns_string, CGFloat, MainThreadMarker, NSString}; | |
use crate::outline::item::OutlineItem; | |
declare_class!( | |
#[derive(Debug)] | |
pub struct OutlineViewDelegate; | |
unsafe impl ClassType for OutlineViewDelegate { | |
type Super = NSObject; | |
type ThreadKind = dyn MainThreadOnly; | |
const NAME: &'static str = "OutlineViewDelegate"; | |
} | |
impl DeclaredClass for OutlineViewDelegate {} | |
unsafe impl NSObjectProtocol for OutlineViewDelegate {} | |
unsafe impl NSControlTextEditingDelegate for OutlineViewDelegate {} | |
unsafe impl NSOutlineViewDelegate for OutlineViewDelegate { | |
#[method(outlineView:heightOfRowByItem:)] | |
unsafe fn outline_view_height_of_row_by_item( | |
&self, | |
_: &NSOutlineView, | |
item: &AnyObject, | |
) -> CGFloat { | |
println!("outline_view_height_of_row_by_item:"); | |
30. | |
} | |
#[method_id(outlineView:viewForTableColumn:item:)] | |
unsafe fn outline_view_view_for_table_column_item( | |
&self, | |
a: &NSOutlineView, | |
b: Option<&NSTableColumn>, | |
o: &AnyObject, | |
) -> Option<Retained<NSView>> { | |
println!("outline_view: "); | |
unsafe { | |
let t = NSTextField::new(MainThreadMarker::from(self)); | |
t.setStringValue(ns_string!("dummy")); | |
t.sizeToFit(); | |
let cell = NSTableCellView::new(MainThreadMarker::from(self)); | |
cell.setTextField(Some(&t)); | |
cell.superview() | |
} | |
} | |
} | |
); | |
impl OutlineViewDelegate { | |
pub fn new(mtm: MainThreadMarker) -> Retained<Self> { | |
let this = mtm.alloc(); | |
unsafe { msg_send_id![this, init] } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment