Render remote participant's screen preserving aspect ratio
This commit is contained in:
parent
46635956f4
commit
bf98300547
3 changed files with 56 additions and 34 deletions
|
@ -495,7 +495,7 @@ pub trait ParentElement<'a>: Extend<ElementBox> + Sized {
|
||||||
|
|
||||||
impl<'a, T> ParentElement<'a> for T where T: Extend<ElementBox> {}
|
impl<'a, T> ParentElement<'a> for T where T: Extend<ElementBox> {}
|
||||||
|
|
||||||
fn constrain_size_preserving_aspect_ratio(max_size: Vector2F, size: Vector2F) -> Vector2F {
|
pub fn constrain_size_preserving_aspect_ratio(max_size: Vector2F, size: Vector2F) -> Vector2F {
|
||||||
if max_size.x().is_infinite() && max_size.y().is_infinite() {
|
if max_size.x().is_infinite() && max_size.y().is_infinite() {
|
||||||
size
|
size
|
||||||
} else if max_size.x().is_infinite() || max_size.x() / max_size.y() > size.x() / size.y() {
|
} else if max_size.x().is_infinite() || max_size.x() / max_size.y() > size.x() / size.y() {
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
use crate::{FollowerStatesByLeader, JoinProject, Pane, Workspace};
|
use crate::{FollowerStatesByLeader, JoinProject, Pane, Workspace};
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
use call::ActiveCall;
|
use call::{ActiveCall, ParticipantLocation};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
elements::*, Axis, Border, CursorStyle, ModelHandle, MouseButton, RenderContext, ViewHandle,
|
elements::*,
|
||||||
|
geometry::{rect::RectF, vector::vec2f},
|
||||||
|
Axis, Border, CursorStyle, ModelHandle, MouseButton, RenderContext, ViewHandle,
|
||||||
};
|
};
|
||||||
use project::Project;
|
use project::Project;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
@ -130,18 +132,45 @@ impl Member {
|
||||||
Some((collaborator.replica_id, participant))
|
Some((collaborator.replica_id, participant))
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut border = Border::default();
|
let border = if let Some((replica_id, _)) = leader.as_ref() {
|
||||||
|
let leader_color = theme.editor.replica_selection_style(*replica_id).cursor;
|
||||||
let prompt = if let Some((replica_id, leader)) = leader {
|
let mut border = Border::all(theme.workspace.leader_border_width, leader_color);
|
||||||
let leader_color = theme.editor.replica_selection_style(replica_id).cursor;
|
|
||||||
border = Border::all(theme.workspace.leader_border_width, leader_color);
|
|
||||||
border
|
border
|
||||||
.color
|
.color
|
||||||
.fade_out(1. - theme.workspace.leader_border_opacity);
|
.fade_out(1. - theme.workspace.leader_border_opacity);
|
||||||
border.overlay = true;
|
border.overlay = true;
|
||||||
|
border
|
||||||
|
} else {
|
||||||
|
Border::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
let content = if leader.as_ref().map_or(false, |(_, leader)| {
|
||||||
|
leader.location == ParticipantLocation::External && !leader.tracks.is_empty()
|
||||||
|
}) {
|
||||||
|
let (_, leader) = leader.unwrap();
|
||||||
|
let track = leader.tracks.values().next().unwrap();
|
||||||
|
let frame = track.frame().cloned();
|
||||||
|
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::mac::Surface {
|
||||||
|
bounds: RectF::new(origin, size),
|
||||||
|
image_buffer: frame,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.boxed()
|
||||||
|
} else {
|
||||||
|
ChildView::new(pane, cx).boxed()
|
||||||
|
};
|
||||||
|
|
||||||
|
let prompt = if let Some((_, leader)) = leader {
|
||||||
match leader.location {
|
match leader.location {
|
||||||
call::ParticipantLocation::SharedProject {
|
ParticipantLocation::SharedProject {
|
||||||
project_id: leader_project_id,
|
project_id: leader_project_id,
|
||||||
} => {
|
} => {
|
||||||
if Some(leader_project_id) == project.read(cx).remote_id() {
|
if Some(leader_project_id) == project.read(cx).remote_id() {
|
||||||
|
@ -186,7 +215,7 @@ impl Member {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
call::ParticipantLocation::UnsharedProject => Some(
|
ParticipantLocation::UnsharedProject => Some(
|
||||||
Label::new(
|
Label::new(
|
||||||
format!(
|
format!(
|
||||||
"{} is viewing an unshared Zed project",
|
"{} is viewing an unshared Zed project",
|
||||||
|
@ -201,35 +230,28 @@ impl Member {
|
||||||
.right()
|
.right()
|
||||||
.boxed(),
|
.boxed(),
|
||||||
),
|
),
|
||||||
call::ParticipantLocation::External => {
|
ParticipantLocation::External => Some(
|
||||||
let frame = leader
|
Label::new(
|
||||||
.tracks
|
format!(
|
||||||
.values()
|
"{} is viewing a window outside of Zed",
|
||||||
.next()
|
leader.user.github_login
|
||||||
.and_then(|track| track.frame())
|
),
|
||||||
.cloned();
|
theme.workspace.external_location_message.text.clone(),
|
||||||
return Canvas::new(move |bounds, _, cx| {
|
)
|
||||||
if let Some(frame) = frame.clone() {
|
.contained()
|
||||||
cx.scene.push_surface(gpui::mac::Surface {
|
.with_style(theme.workspace.external_location_message.container)
|
||||||
bounds,
|
.aligned()
|
||||||
image_buffer: frame,
|
.bottom()
|
||||||
});
|
.right()
|
||||||
}
|
.boxed(),
|
||||||
})
|
),
|
||||||
.boxed();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
Stack::new()
|
Stack::new()
|
||||||
.with_child(
|
.with_child(Container::new(content).with_border(border).boxed())
|
||||||
ChildView::new(pane, cx)
|
|
||||||
.contained()
|
|
||||||
.with_border(border)
|
|
||||||
.boxed(),
|
|
||||||
)
|
|
||||||
.with_children(prompt)
|
.with_children(prompt)
|
||||||
.boxed()
|
.boxed()
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,7 @@ export default function workspace(theme: Theme) {
|
||||||
...text(theme, "sans", "primary", { size: "lg" }),
|
...text(theme, "sans", "primary", { size: "lg" }),
|
||||||
},
|
},
|
||||||
externalLocationMessage: {
|
externalLocationMessage: {
|
||||||
background: backgroundColor(theme, "info"),
|
background: backgroundColor(theme, "on500Info"),
|
||||||
border: border(theme, "secondary"),
|
border: border(theme, "secondary"),
|
||||||
cornerRadius: 6,
|
cornerRadius: 6,
|
||||||
padding: 12,
|
padding: 12,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue