diff --git a/crates/call2/src/call2.rs b/crates/call2/src/call2.rs index df7dd847cf3413a410ce17b87f1c89efa2e2905e..a93305772312cab3624f995e0dd49751554867e1 100644 --- a/crates/call2/src/call2.rs +++ b/crates/call2/src/call2.rs @@ -15,7 +15,7 @@ use collections::HashSet; use futures::{channel::oneshot, future::Shared, Future, FutureExt}; use gpui::{ AppContext, AsyncAppContext, Context, EventEmitter, Model, ModelContext, PromptLevel, - Subscription, Task, View, ViewContext, VisualContext, WeakModel, WeakView, WindowHandle, + Subscription, Task, View, ViewContext, VisualContext, WeakModel, WindowHandle, }; pub use participant::ParticipantLocation; use postage::watch; @@ -557,24 +557,17 @@ pub fn report_call_event_for_channel( pub struct Call { active_call: Option<(Model, Vec)>, - parent_workspace: WeakView, } impl Call { - pub fn new( - parent_workspace: WeakView, - cx: &mut ViewContext<'_, Workspace>, - ) -> Box { + pub fn new(cx: &mut ViewContext<'_, Workspace>) -> Box { let mut active_call = None; if cx.has_global::>() { let call = cx.global::>().clone(); let subscriptions = vec![cx.subscribe(&call, Self::on_active_call_event)]; active_call = Some((call, subscriptions)); } - Box::new(Self { - active_call, - parent_workspace, - }) + Box::new(Self { active_call }) } fn on_active_call_event( workspace: &mut Workspace, @@ -597,6 +590,7 @@ impl CallHandler for Call { fn peer_state( &mut self, leader_id: PeerId, + project: &Model, cx: &mut ViewContext, ) -> Option<(bool, bool)> { let (call, _) = self.active_call.as_ref()?; @@ -608,12 +602,7 @@ impl CallHandler for Call { match participant.location { ParticipantLocation::SharedProject { project_id } => { leader_in_this_app = true; - leader_in_this_project = Some(project_id) - == self - .parent_workspace - .update(cx, |this, cx| this.project().read(cx).remote_id()) - .log_err() - .flatten(); + leader_in_this_project = Some(project_id) == project.read(cx).remote_id(); } ParticipantLocation::UnsharedProject => { leader_in_this_app = true; diff --git a/crates/call2/src/shared_screen.rs b/crates/call2/src/shared_screen.rs index 58d8445f8f0ef242ba563eeca76d2c3da5d78030..c38ebeac021d59c810fc27ff528ddc773f9642f4 100644 --- a/crates/call2/src/shared_screen.rs +++ b/crates/call2/src/shared_screen.rs @@ -3,10 +3,12 @@ use anyhow::Result; use client::{proto::PeerId, User}; use futures::StreamExt; use gpui::{ - div, img, AppContext, Div, Element, EventEmitter, FocusHandle, FocusableView, ParentElement, - Render, SharedString, Styled, Task, View, ViewContext, VisualContext, WindowContext, + div, img, AppContext, Div, Element, EventEmitter, FocusHandle, Focusable, FocusableView, + InteractiveElement, ParentElement, Render, SharedString, Styled, Task, View, ViewContext, + VisualContext, WindowContext, }; use std::sync::{Arc, Weak}; +use ui::{h_stack, Icon, IconElement}; use workspace::{item::Item, ItemNavHistory, WorkspaceId}; pub enum Event { @@ -16,8 +18,6 @@ pub enum Event { pub struct SharedScreen { track: Weak, frame: Option, - // temporary addition just to render something interactive. - current_frame_id: usize, pub peer_id: PeerId, user: Arc, nav_history: Option, @@ -51,7 +51,6 @@ impl SharedScreen { Ok(()) }), focus: cx.focus_handle(), - current_frame_id: 0, } } } @@ -65,46 +64,16 @@ impl FocusableView for SharedScreen { } } impl Render for SharedScreen { - type Element = Div; + type Element = Focusable
; + fn render(&mut self, _: &mut ViewContext) -> Self::Element { - let frame = self.frame.clone(); - // let frame_id = self.current_frame_id; - // self.current_frame_id = self.current_frame_id.wrapping_add(1); - div() - .size_full() - .children(frame.map(|frame| img(frame.image()).w_full())) + div().track_focus(&self.focus).size_full().children( + self.frame + .as_ref() + .map(|frame| img(frame.image()).size_full()), + ) } } -// impl View for SharedScreen { -// fn ui_name() -> &'static str { -// "SharedScreen" -// } - -// fn render(&mut self, cx: &mut ViewContext) -> AnyElement { -// enum Focus {} - -// let frame = self.frame.clone(); -// MouseEventHandler::new::(0, cx, |_, cx| { -// Canvas::new(move |bounds, _, _, cx| { -// if let Some(frame) = frame.clone() { -// let size = constrain_size_preserving_aspect_ratio( -// bounds.size(), -// vec2f(frame.width() as f32, frame.height() as f32), -// ); -// let origin = bounds.origin() + (bounds.size() / 2.) - size / 2.; -// cx.scene().push_surface(gpui::platform::mac::Surface { -// bounds: RectF::new(origin, size), -// image_buffer: frame.image(), -// }); -// } -// }) -// .contained() -// .with_style(theme::current(cx).shared_screen) -// }) -// .on_down(MouseButton::Left, |_, _, cx| cx.focus_parent()) -// .into_any() -// } -// } impl Item for SharedScreen { fn tab_tooltip_text(&self, _: &AppContext) -> Option { @@ -117,25 +86,14 @@ impl Item for SharedScreen { } fn tab_content(&self, _: Option, _: &WindowContext<'_>) -> gpui::AnyElement { - div().child("Shared screen").into_any() - // Flex::row() - // .with_child( - // Svg::new("icons/desktop.svg") - // .with_color(style.label.text.color) - // .constrained() - // .with_width(style.type_icon_width) - // .aligned() - // .contained() - // .with_margin_right(style.spacing), - // ) - // .with_child( - // Label::new( - // format!("{}'s screen", self.user.github_login), - // style.label.clone(), - // ) - // .aligned(), - // ) - // .into_any() + h_stack() + .gap_1() + .child(IconElement::new(Icon::Screen)) + .child(SharedString::from(format!( + "{}'s screen", + self.user.github_login + ))) + .into_any() } fn set_nav_history(&mut self, history: ItemNavHistory, _: &mut ViewContext) { diff --git a/crates/gpui2/src/elements/img.rs b/crates/gpui2/src/elements/img.rs index dd59ddb17c9365c4868839a62202f8c1d671b2fc..e519a93e64d5205bd70b2c5f08458ab5a5180c28 100644 --- a/crates/gpui2/src/elements/img.rs +++ b/crates/gpui2/src/elements/img.rs @@ -147,12 +147,20 @@ impl InteractiveElement for Img { } fn preserve_aspect_ratio(bounds: Bounds, image_size: Size) -> Bounds { - let new_size = if bounds.size.width > bounds.size.height { - let ratio = u32::from(image_size.height) as f32 / u32::from(image_size.width) as f32; - size(bounds.size.width, bounds.size.width * ratio) + let image_size = image_size.map(|dimension| Pixels::from(u32::from(dimension))); + let image_ratio = image_size.width / image_size.height; + let bounds_ratio = bounds.size.width / bounds.size.height; + + let new_size = if bounds_ratio > image_ratio { + size( + image_size.width * (bounds.size.height / image_size.height), + bounds.size.height, + ) } else { - let ratio = u32::from(image_size.width) as f32 / u32::from(image_size.height) as f32; - size(bounds.size.width * ratio, bounds.size.height) + size( + bounds.size.width, + image_size.height * (bounds.size.width / image_size.width), + ) }; Bounds { diff --git a/crates/workspace2/src/workspace2.rs b/crates/workspace2/src/workspace2.rs index 23907f8dae882f0780e5a8ad351a96f74129c363..cbd3e4309cd9a3e3aa38a1dd6645cc3b22a05505 100644 --- a/crates/workspace2/src/workspace2.rs +++ b/crates/workspace2/src/workspace2.rs @@ -326,7 +326,12 @@ pub struct TestCallHandler; #[cfg(any(test, feature = "test-support"))] impl CallHandler for TestCallHandler { - fn peer_state(&mut self, id: PeerId, cx: &mut ViewContext) -> Option<(bool, bool)> { + fn peer_state( + &mut self, + id: PeerId, + project: &Model, + cx: &mut ViewContext, + ) -> Option<(bool, bool)> { None } @@ -409,7 +414,7 @@ impl AppState { workspace_store, node_runtime: FakeNodeRuntime::new(), build_window_options: |_, _, _| Default::default(), - call_factory: |_, _| Box::new(TestCallHandler), + call_factory: |_| Box::new(TestCallHandler), }) } } @@ -468,7 +473,12 @@ pub enum Event { #[async_trait(?Send)] pub trait CallHandler { - fn peer_state(&mut self, id: PeerId, cx: &mut ViewContext) -> Option<(bool, bool)>; + fn peer_state( + &mut self, + id: PeerId, + project: &Model, + cx: &mut ViewContext, + ) -> Option<(bool, bool)>; fn shared_screen_for_peer( &self, peer_id: PeerId, @@ -546,7 +556,7 @@ struct FollowerState { enum WorkspaceBounds {} -type CallFactory = fn(WeakView, &mut ViewContext) -> Box; +type CallFactory = fn(&mut ViewContext) -> Box; impl Workspace { pub fn new( workspace_id: WorkspaceId, @@ -760,7 +770,7 @@ impl Workspace { last_leaders_by_pane: Default::default(), window_edited: false, - call_handler: (app_state.call_factory)(weak_handle.clone(), cx), + call_handler: (app_state.call_factory)(cx), database_id: workspace_id, app_state, _observe_current_user, @@ -2884,7 +2894,7 @@ impl Workspace { cx.notify(); let (leader_in_this_project, leader_in_this_app) = - self.call_handler.peer_state(leader_id, cx)?; + self.call_handler.peer_state(leader_id, &self.project, cx)?; let mut items_to_activate = Vec::new(); for (pane, state) in &self.follower_states { if state.leader_id != leader_id { @@ -3385,7 +3395,7 @@ impl Workspace { fs: project.read(cx).fs().clone(), build_window_options: |_, _, _| Default::default(), node_runtime: FakeNodeRuntime::new(), - call_factory: |_, _| Box::new(TestCallHandler), + call_factory: |_| Box::new(TestCallHandler), }); let workspace = Self::new(0, project, app_state, cx); workspace.active_pane.update(cx, |pane, cx| pane.focus(cx));