Make titlebar taller and position traffic lights accordingly

Co-Authored-By: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
Antonio Scandurra 2021-09-07 18:37:45 +02:00
parent c4dac3c6b1
commit d08ec438ed
3 changed files with 65 additions and 3 deletions

View file

@ -105,6 +105,7 @@ pub struct WindowOptions<'a> {
pub bounds: RectF,
pub title: Option<&'a str>,
pub titlebar_appears_transparent: bool,
pub traffic_light_position: Option<Vector2F>,
}
pub struct PathPromptOptions {
@ -155,6 +156,7 @@ impl<'a> Default for WindowOptions<'a> {
bounds: RectF::new(Default::default(), vec2f(1024.0, 768.0)),
title: Default::default(),
titlebar_appears_transparent: Default::default(),
traffic_light_position: Default::default(),
}
}
}

View file

@ -8,8 +8,8 @@ use crate::{
use block::ConcreteBlock;
use cocoa::{
appkit::{
NSApplication, NSBackingStoreBuffered, NSScreen, NSView, NSViewHeightSizable,
NSViewWidthSizable, NSWindow, NSWindowStyleMask,
CGPoint, NSApplication, NSBackingStoreBuffered, NSScreen, NSView, NSViewHeightSizable,
NSViewWidthSizable, NSWindow, NSWindowButton, NSWindowStyleMask,
},
base::{id, nil},
foundation::{NSAutoreleasePool, NSInteger, NSSize, NSString},
@ -66,6 +66,10 @@ unsafe fn build_classes() {
sel!(sendEvent:),
send_event as extern "C" fn(&Object, Sel, id),
);
decl.add_method(
sel!(windowDidResize:),
window_did_resize as extern "C" fn(&Object, Sel, id),
);
decl.add_method(sel!(close), close_window as extern "C" fn(&Object, Sel));
decl.register()
};
@ -139,6 +143,7 @@ struct WindowState {
command_queue: metal::CommandQueue,
last_fresh_keydown: Option<(Keystroke, String)>,
layer: id,
traffic_light_position: Option<Vector2F>,
}
impl Window {
@ -204,12 +209,14 @@ impl Window {
command_queue: device.new_command_queue(),
last_fresh_keydown: None,
layer,
traffic_light_position: options.traffic_light_position,
})));
(*native_window).set_ivar(
WINDOW_STATE_IVAR,
Rc::into_raw(window.0.clone()) as *const c_void,
);
native_window.setDelegate_(native_window);
(*native_view).set_ivar(
WINDOW_STATE_IVAR,
Rc::into_raw(window.0.clone()) as *const c_void,
@ -243,6 +250,7 @@ impl Window {
native_window.center();
native_window.makeKeyAndOrderFront_(nil);
window.0.borrow().move_traffic_light();
pool.drain();
window
@ -343,6 +351,52 @@ impl platform::WindowContext for Window {
}
}
impl WindowState {
fn move_traffic_light(&self) {
if let Some(traffic_light_position) = self.traffic_light_position {
let titlebar_height = self.titlebar_height();
unsafe {
let close_button: id = msg_send![
self.native_window,
standardWindowButton: NSWindowButton::NSWindowCloseButton
];
let min_button: id = msg_send![
self.native_window,
standardWindowButton: NSWindowButton::NSWindowMiniaturizeButton
];
let zoom_button: id = msg_send![
self.native_window,
standardWindowButton: NSWindowButton::NSWindowZoomButton
];
let mut close_button_frame: CGRect = msg_send![close_button, frame];
let mut min_button_frame: CGRect = msg_send![min_button, frame];
let mut zoom_button_frame: CGRect = msg_send![zoom_button, frame];
let mut origin = vec2f(
traffic_light_position.x(),
titlebar_height
- traffic_light_position.y()
- close_button_frame.size.height as f32,
);
let button_spacing =
(min_button_frame.origin.x - close_button_frame.origin.x) as f32;
close_button_frame.origin = CGPoint::new(origin.x() as f64, origin.y() as f64);
let _: () = msg_send![close_button, setFrame: close_button_frame];
origin.set_x(origin.x() + button_spacing);
min_button_frame.origin = CGPoint::new(origin.x() as f64, origin.y() as f64);
let _: () = msg_send![min_button, setFrame: min_button_frame];
origin.set_x(origin.x() + button_spacing);
zoom_button_frame.origin = CGPoint::new(origin.x() as f64, origin.y() as f64);
let _: () = msg_send![zoom_button, setFrame: zoom_button_frame];
}
}
}
}
impl platform::WindowContext for WindowState {
fn size(&self) -> Vector2F {
let NSSize { width, height, .. } =
@ -462,6 +516,11 @@ extern "C" fn send_event(this: &Object, _: Sel, native_event: id) {
}
}
extern "C" fn window_did_resize(this: &Object, _: Sel, _: id) {
let window_state = unsafe { get_window_state(this) };
window_state.as_ref().borrow().move_traffic_light();
}
extern "C" fn close_window(this: &Object, _: Sel) {
unsafe {
let close_callback = {

View file

@ -142,6 +142,7 @@ fn window_options() -> WindowOptions<'static> {
bounds: RectF::new(vec2f(0., 0.), vec2f(1024., 768.)),
title: None,
titlebar_appears_transparent: true,
traffic_light_position: Some(vec2f(8., 8.)),
}
}
@ -952,7 +953,7 @@ impl View for Workspace {
Flex::column()
.with_child(
ConstrainedBox::new(Empty::new().boxed())
.with_height(cx.titlebar_height)
.with_height(32.)
.named("titlebar"),
)
.with_child(