Detailed changes
@@ -3,8 +3,8 @@ use futures::StreamExt;
use gpui::{
elements::*,
geometry::{rect::RectF, vector::vec2f},
- impl_internal_actions, Entity, MouseButton, MutableAppContext, RenderContext, View,
- ViewContext, WindowBounds, WindowKind, WindowOptions,
+ impl_internal_actions, CursorStyle, Entity, MouseButton, MutableAppContext, RenderContext,
+ View, ViewContext, WindowBounds, WindowKind, WindowOptions,
};
use settings::Settings;
use util::ResultExt;
@@ -24,11 +24,17 @@ pub fn init(cx: &mut MutableAppContext) {
}
if let Some(incoming_call) = incoming_call {
+ const PADDING: f32 = 16.;
+ let screen_size = cx.platform().screen_size();
+ let window_size = vec2f(304., 64.);
let (window_id, _) = cx.add_window(
WindowOptions {
- bounds: WindowBounds::Fixed(RectF::new(vec2f(0., 0.), vec2f(300., 400.))),
+ bounds: WindowBounds::Fixed(RectF::new(
+ vec2f(screen_size.x() - window_size.x() - PADDING, PADDING),
+ window_size,
+ )),
titlebar: None,
- center: true,
+ center: false,
kind: WindowKind::PopUp,
is_movable: false,
},
@@ -84,22 +90,40 @@ impl IncomingCallNotification {
fn render_caller(&self, cx: &mut RenderContext<Self>) -> ElementBox {
let theme = &cx.global::<Settings>().theme.incoming_call_notification;
Flex::row()
- .with_children(
- self.call
- .caller
- .avatar
- .clone()
- .map(|avatar| Image::new(avatar).with_style(theme.caller_avatar).boxed()),
- )
+ .with_children(self.call.caller.avatar.clone().map(|avatar| {
+ Image::new(avatar)
+ .with_style(theme.caller_avatar)
+ .aligned()
+ .boxed()
+ }))
.with_child(
- Label::new(
- self.call.caller.github_login.clone(),
- theme.caller_username.text.clone(),
- )
- .contained()
- .with_style(theme.caller_username.container)
- .boxed(),
+ Flex::column()
+ .with_child(
+ Label::new(
+ self.call.caller.github_login.clone(),
+ theme.caller_username.text.clone(),
+ )
+ .contained()
+ .with_style(theme.caller_username.container)
+ .boxed(),
+ )
+ .with_child(
+ Label::new(
+ "Incoming Zed call...".into(),
+ theme.caller_message.text.clone(),
+ )
+ .contained()
+ .with_style(theme.caller_message.container)
+ .boxed(),
+ )
+ .contained()
+ .with_style(theme.caller_metadata)
+ .aligned()
+ .boxed(),
)
+ .contained()
+ .with_style(theme.caller_container)
+ .flex(1., true)
.boxed()
}
@@ -107,33 +131,46 @@ impl IncomingCallNotification {
enum Accept {}
enum Decline {}
- Flex::row()
+ Flex::column()
.with_child(
MouseEventHandler::<Accept>::new(0, cx, |_, cx| {
let theme = &cx.global::<Settings>().theme.incoming_call_notification;
Label::new("Accept".to_string(), theme.accept_button.text.clone())
+ .aligned()
.contained()
.with_style(theme.accept_button.container)
.boxed()
})
+ .with_cursor_style(CursorStyle::PointingHand)
.on_click(MouseButton::Left, |_, cx| {
cx.dispatch_action(RespondToCall { accept: true });
})
+ .flex(1., true)
.boxed(),
)
.with_child(
MouseEventHandler::<Decline>::new(0, cx, |_, cx| {
let theme = &cx.global::<Settings>().theme.incoming_call_notification;
Label::new("Decline".to_string(), theme.decline_button.text.clone())
+ .aligned()
.contained()
.with_style(theme.decline_button.container)
.boxed()
})
+ .with_cursor_style(CursorStyle::PointingHand)
.on_click(MouseButton::Left, |_, cx| {
cx.dispatch_action(RespondToCall { accept: false });
})
+ .flex(1., true)
.boxed(),
)
+ .constrained()
+ .with_width(
+ cx.global::<Settings>()
+ .theme
+ .incoming_call_notification
+ .button_width,
+ )
.boxed()
}
}
@@ -148,9 +185,17 @@ impl View for IncomingCallNotification {
}
fn render(&mut self, cx: &mut RenderContext<Self>) -> gpui::ElementBox {
- Flex::column()
+ let background = cx
+ .global::<Settings>()
+ .theme
+ .incoming_call_notification
+ .background;
+ Flex::row()
.with_child(self.render_caller(cx))
.with_child(self.render_buttons(cx))
+ .contained()
+ .with_background_color(background)
+ .expanded()
.boxed()
}
}
@@ -44,6 +44,8 @@ pub trait Platform: Send + Sync {
fn unhide_other_apps(&self);
fn quit(&self);
+ fn screen_size(&self) -> Vector2F;
+
fn open_window(
&self,
id: usize,
@@ -2,7 +2,9 @@ use super::{
event::key_to_native, status_item::StatusItem, BoolExt as _, Dispatcher, FontSystem, Window,
};
use crate::{
- executor, keymap,
+ executor,
+ geometry::vector::{vec2f, Vector2F},
+ keymap,
platform::{self, CursorStyle},
Action, ClipboardItem, Event, Menu, MenuItem,
};
@@ -12,7 +14,7 @@ use cocoa::{
appkit::{
NSApplication, NSApplicationActivationPolicy::NSApplicationActivationPolicyRegular,
NSEventModifierFlags, NSMenu, NSMenuItem, NSModalResponse, NSOpenPanel, NSPasteboard,
- NSPasteboardTypeString, NSSavePanel, NSWindow,
+ NSPasteboardTypeString, NSSavePanel, NSScreen, NSWindow,
},
base::{id, nil, selector, YES},
foundation::{
@@ -485,6 +487,14 @@ impl platform::Platform for MacPlatform {
}
}
+ fn screen_size(&self) -> Vector2F {
+ unsafe {
+ let screen = NSScreen::mainScreen(nil);
+ let frame = NSScreen::frame(screen);
+ vec2f(frame.size.width as f32, frame.size.height as f32)
+ }
+ }
+
fn open_window(
&self,
id: usize,
@@ -131,6 +131,10 @@ impl super::Platform for Platform {
fn quit(&self) {}
+ fn screen_size(&self) -> Vector2F {
+ vec2f(1024., 768.)
+ }
+
fn open_window(
&self,
_: usize,
@@ -479,8 +479,14 @@ pub struct ProjectSharedNotification {
#[derive(Deserialize, Default)]
pub struct IncomingCallNotification {
+ #[serde(default)]
+ pub background: Color,
+ pub caller_container: ContainerStyle,
pub caller_avatar: ImageStyle,
+ pub caller_metadata: ContainerStyle,
pub caller_username: ContainedText,
+ pub caller_message: ContainedText,
+ pub button_width: f32,
pub accept_button: ContainedText,
pub decline_button: ContainedText,
}
@@ -1,22 +1,38 @@
import Theme from "../themes/common/theme";
-import { text } from "./components";
+import { backgroundColor, borderColor, text } from "./components";
export default function incomingCallNotification(theme: Theme): Object {
- const avatarSize = 12;
+ const avatarSize = 32;
return {
+ background: backgroundColor(theme, 300),
+ callerContainer: {
+ padding: 12,
+ },
callerAvatar: {
height: avatarSize,
width: avatarSize,
- cornerRadius: 6,
+ cornerRadius: avatarSize / 2,
+ },
+ callerMetadata: {
+ margin: { left: 10 },
},
callerUsername: {
- ...text(theme, "sans", "primary", { size: "xs" }),
+ ...text(theme, "sans", "active", { size: "sm", weight: "bold" }),
+ margin: { top: -3 },
+ },
+ callerMessage: {
+ ...text(theme, "sans", "secondary", { size: "xs" }),
+ margin: { top: -3 },
},
+ buttonWidth: 96,
acceptButton: {
- ...text(theme, "sans", "primary", { size: "xs" })
+ background: backgroundColor(theme, "ok", "active"),
+ border: { left: true, bottom: true, width: 1, color: borderColor(theme, "primary") },
+ ...text(theme, "sans", "ok", { size: "xs", weight: "extra_bold" })
},
declineButton: {
- ...text(theme, "sans", "primary", { size: "xs" })
+ border: { left: true, width: 1, color: borderColor(theme, "primary") },
+ ...text(theme, "sans", "error", { size: "xs", weight: "extra_bold" })
},
};
}