Make titlebar taller and position traffic lights accordingly
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
parent
c4dac3c6b1
commit
d08ec438ed
3 changed files with 65 additions and 3 deletions
|
@ -105,6 +105,7 @@ pub struct WindowOptions<'a> {
|
||||||
pub bounds: RectF,
|
pub bounds: RectF,
|
||||||
pub title: Option<&'a str>,
|
pub title: Option<&'a str>,
|
||||||
pub titlebar_appears_transparent: bool,
|
pub titlebar_appears_transparent: bool,
|
||||||
|
pub traffic_light_position: Option<Vector2F>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct PathPromptOptions {
|
pub struct PathPromptOptions {
|
||||||
|
@ -155,6 +156,7 @@ impl<'a> Default for WindowOptions<'a> {
|
||||||
bounds: RectF::new(Default::default(), vec2f(1024.0, 768.0)),
|
bounds: RectF::new(Default::default(), vec2f(1024.0, 768.0)),
|
||||||
title: Default::default(),
|
title: Default::default(),
|
||||||
titlebar_appears_transparent: Default::default(),
|
titlebar_appears_transparent: Default::default(),
|
||||||
|
traffic_light_position: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,8 @@ use crate::{
|
||||||
use block::ConcreteBlock;
|
use block::ConcreteBlock;
|
||||||
use cocoa::{
|
use cocoa::{
|
||||||
appkit::{
|
appkit::{
|
||||||
NSApplication, NSBackingStoreBuffered, NSScreen, NSView, NSViewHeightSizable,
|
CGPoint, NSApplication, NSBackingStoreBuffered, NSScreen, NSView, NSViewHeightSizable,
|
||||||
NSViewWidthSizable, NSWindow, NSWindowStyleMask,
|
NSViewWidthSizable, NSWindow, NSWindowButton, NSWindowStyleMask,
|
||||||
},
|
},
|
||||||
base::{id, nil},
|
base::{id, nil},
|
||||||
foundation::{NSAutoreleasePool, NSInteger, NSSize, NSString},
|
foundation::{NSAutoreleasePool, NSInteger, NSSize, NSString},
|
||||||
|
@ -66,6 +66,10 @@ unsafe fn build_classes() {
|
||||||
sel!(sendEvent:),
|
sel!(sendEvent:),
|
||||||
send_event as extern "C" fn(&Object, Sel, id),
|
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.add_method(sel!(close), close_window as extern "C" fn(&Object, Sel));
|
||||||
decl.register()
|
decl.register()
|
||||||
};
|
};
|
||||||
|
@ -139,6 +143,7 @@ struct WindowState {
|
||||||
command_queue: metal::CommandQueue,
|
command_queue: metal::CommandQueue,
|
||||||
last_fresh_keydown: Option<(Keystroke, String)>,
|
last_fresh_keydown: Option<(Keystroke, String)>,
|
||||||
layer: id,
|
layer: id,
|
||||||
|
traffic_light_position: Option<Vector2F>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Window {
|
impl Window {
|
||||||
|
@ -204,12 +209,14 @@ impl Window {
|
||||||
command_queue: device.new_command_queue(),
|
command_queue: device.new_command_queue(),
|
||||||
last_fresh_keydown: None,
|
last_fresh_keydown: None,
|
||||||
layer,
|
layer,
|
||||||
|
traffic_light_position: options.traffic_light_position,
|
||||||
})));
|
})));
|
||||||
|
|
||||||
(*native_window).set_ivar(
|
(*native_window).set_ivar(
|
||||||
WINDOW_STATE_IVAR,
|
WINDOW_STATE_IVAR,
|
||||||
Rc::into_raw(window.0.clone()) as *const c_void,
|
Rc::into_raw(window.0.clone()) as *const c_void,
|
||||||
);
|
);
|
||||||
|
native_window.setDelegate_(native_window);
|
||||||
(*native_view).set_ivar(
|
(*native_view).set_ivar(
|
||||||
WINDOW_STATE_IVAR,
|
WINDOW_STATE_IVAR,
|
||||||
Rc::into_raw(window.0.clone()) as *const c_void,
|
Rc::into_raw(window.0.clone()) as *const c_void,
|
||||||
|
@ -243,6 +250,7 @@ impl Window {
|
||||||
native_window.center();
|
native_window.center();
|
||||||
native_window.makeKeyAndOrderFront_(nil);
|
native_window.makeKeyAndOrderFront_(nil);
|
||||||
|
|
||||||
|
window.0.borrow().move_traffic_light();
|
||||||
pool.drain();
|
pool.drain();
|
||||||
|
|
||||||
window
|
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 {
|
impl platform::WindowContext for WindowState {
|
||||||
fn size(&self) -> Vector2F {
|
fn size(&self) -> Vector2F {
|
||||||
let NSSize { width, height, .. } =
|
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) {
|
extern "C" fn close_window(this: &Object, _: Sel) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let close_callback = {
|
let close_callback = {
|
||||||
|
|
|
@ -142,6 +142,7 @@ fn window_options() -> WindowOptions<'static> {
|
||||||
bounds: RectF::new(vec2f(0., 0.), vec2f(1024., 768.)),
|
bounds: RectF::new(vec2f(0., 0.), vec2f(1024., 768.)),
|
||||||
title: None,
|
title: None,
|
||||||
titlebar_appears_transparent: true,
|
titlebar_appears_transparent: true,
|
||||||
|
traffic_light_position: Some(vec2f(8., 8.)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -952,7 +953,7 @@ impl View for Workspace {
|
||||||
Flex::column()
|
Flex::column()
|
||||||
.with_child(
|
.with_child(
|
||||||
ConstrainedBox::new(Empty::new().boxed())
|
ConstrainedBox::new(Empty::new().boxed())
|
||||||
.with_height(cx.titlebar_height)
|
.with_height(32.)
|
||||||
.named("titlebar"),
|
.named("titlebar"),
|
||||||
)
|
)
|
||||||
.with_child(
|
.with_child(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue