Detailed changes
@@ -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<ActiveCall>, Vec<Subscription>)>,
- parent_workspace: WeakView<Workspace>,
}
impl Call {
- pub fn new(
- parent_workspace: WeakView<Workspace>,
- cx: &mut ViewContext<'_, Workspace>,
- ) -> Box<dyn CallHandler> {
+ pub fn new(cx: &mut ViewContext<'_, Workspace>) -> Box<dyn CallHandler> {
let mut active_call = None;
if cx.has_global::<Model<ActiveCall>>() {
let call = cx.global::<Model<ActiveCall>>().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<Project>,
cx: &mut ViewContext<Workspace>,
) -> 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;
@@ -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<RemoteVideoTrack>,
frame: Option<Frame>,
- // temporary addition just to render something interactive.
- current_frame_id: usize,
pub peer_id: PeerId,
user: Arc<User>,
nav_history: Option<ItemNavHistory>,
@@ -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<Div>;
+
fn render(&mut self, _: &mut ViewContext<Self>) -> 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<Self>) -> AnyElement<Self> {
-// enum Focus {}
-
-// let frame = self.frame.clone();
-// MouseEventHandler::new::<Focus, _>(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<SharedString> {
@@ -117,25 +86,14 @@ impl Item for SharedScreen {
}
fn tab_content(&self, _: Option<usize>, _: &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<Self>) {
@@ -147,12 +147,20 @@ impl InteractiveElement for Img {
}
fn preserve_aspect_ratio(bounds: Bounds<Pixels>, image_size: Size<DevicePixels>) -> Bounds<Pixels> {
- 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 {
@@ -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<Workspace>) -> Option<(bool, bool)> {
+ fn peer_state(
+ &mut self,
+ id: PeerId,
+ project: &Model<Project>,
+ cx: &mut ViewContext<Workspace>,
+ ) -> 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<Workspace>) -> Option<(bool, bool)>;
+ fn peer_state(
+ &mut self,
+ id: PeerId,
+ project: &Model<Project>,
+ cx: &mut ViewContext<Workspace>,
+ ) -> Option<(bool, bool)>;
fn shared_screen_for_peer(
&self,
peer_id: PeerId,
@@ -546,7 +556,7 @@ struct FollowerState {
enum WorkspaceBounds {}
-type CallFactory = fn(WeakView<Workspace>, &mut ViewContext<Workspace>) -> Box<dyn CallHandler>;
+type CallFactory = fn(&mut ViewContext<Workspace>) -> Box<dyn CallHandler>;
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));