Take an Into<AnyViewHandle> in ChildView::new

Co-Authored-By: Nathan Sobo <nathan@zed.dev>
Co-Authored-By: Max Brunsfeld <max@zed.dev>
This commit is contained in:
Antonio Scandurra 2022-01-27 17:52:36 +01:00
parent dbf48d2a5b
commit e7d4c385d5
12 changed files with 69 additions and 56 deletions

View File

@ -217,7 +217,7 @@ impl ChatPanel {
let theme = &self.settings.borrow().theme; let theme = &self.settings.borrow().theme;
Flex::column() Flex::column()
.with_child( .with_child(
Container::new(ChildView::new(self.channel_select.id()).boxed()) Container::new(ChildView::new(&self.channel_select).boxed())
.with_style(theme.chat_panel.channel_select.container) .with_style(theme.chat_panel.channel_select.container)
.boxed(), .boxed(),
) )
@ -282,7 +282,7 @@ impl ChatPanel {
fn render_input_box(&self) -> ElementBox { fn render_input_box(&self) -> ElementBox {
let theme = &self.settings.borrow().theme; let theme = &self.settings.borrow().theme;
Container::new(ChildView::new(self.input_editor.id()).boxed()) Container::new(ChildView::new(&self.input_editor).boxed())
.with_style(theme.chat_panel.input_editor.container) .with_style(theme.chat_panel.input_editor.container)
.boxed() .boxed()
} }

View File

@ -111,7 +111,7 @@ impl View for ProjectDiagnosticsEditor {
.with_style(theme.container) .with_style(theme.container)
.boxed() .boxed()
} else { } else {
ChildView::new(self.editor.id()).boxed() ChildView::new(&self.editor).boxed()
} }
} }

View File

@ -76,7 +76,7 @@ impl View for FileFinder {
Container::new( Container::new(
Flex::new(Axis::Vertical) Flex::new(Axis::Vertical)
.with_child( .with_child(
Container::new(ChildView::new(self.query_editor.id()).boxed()) Container::new(ChildView::new(&self.query_editor).boxed())
.with_style(settings.theme.selector.input_editor.container) .with_style(settings.theme.selector.input_editor.container)
.boxed(), .boxed(),
) )

View File

@ -181,7 +181,7 @@ impl View for GoToLine {
Container::new( Container::new(
Flex::new(Axis::Vertical) Flex::new(Axis::Vertical)
.with_child( .with_child(
Container::new(ChildView::new(self.line_editor.id()).boxed()) Container::new(ChildView::new(&self.line_editor).boxed())
.with_style(theme.input_editor.container) .with_style(theme.input_editor.container)
.boxed(), .boxed(),
) )

View File

@ -6,8 +6,8 @@ use crate::{
json::{self, ToJson}, json::{self, ToJson},
platform::Event, platform::Event,
text_layout::TextLayoutCache, text_layout::TextLayoutCache,
Action, AnyAction, AssetCache, ElementBox, Entity, FontSystem, ModelHandle, ReadModel, Action, AnyAction, AnyViewHandle, AssetCache, ElementBox, Entity, FontSystem, ModelHandle,
ReadView, Scene, View, ViewHandle, ReadModel, ReadView, Scene, View, ViewHandle,
}; };
use pathfinder_geometry::vector::{vec2f, Vector2F}; use pathfinder_geometry::vector::{vec2f, Vector2F};
use serde_json::json; use serde_json::json;
@ -462,8 +462,10 @@ pub struct ChildView {
} }
impl ChildView { impl ChildView {
pub fn new(view_id: usize) -> Self { pub fn new(view: impl Into<AnyViewHandle>) -> Self {
Self { view_id } Self {
view_id: view.into().id(),
}
} }
} }

View File

@ -80,7 +80,7 @@ impl View for OutlineView {
Flex::new(Axis::Vertical) Flex::new(Axis::Vertical)
.with_child( .with_child(
Container::new(ChildView::new(self.query_editor.id()).boxed()) Container::new(ChildView::new(&self.query_editor).boxed())
.with_style(settings.theme.selector.input_editor.container) .with_style(settings.theme.selector.input_editor.container)
.boxed(), .boxed(),
) )

View File

@ -299,7 +299,7 @@ impl View for ThemeSelector {
ConstrainedBox::new( ConstrainedBox::new(
Container::new( Container::new(
Flex::new(Axis::Vertical) Flex::new(Axis::Vertical)
.with_child(ChildView::new(self.query_editor.id()).boxed()) .with_child(ChildView::new(&self.query_editor).boxed())
.with_child(Flexible::new(1.0, false, self.render_matches(cx)).boxed()) .with_child(Flexible::new(1.0, false, self.render_matches(cx)).boxed())
.boxed(), .boxed(),
) )

View File

@ -516,7 +516,7 @@ impl View for Pane {
if let Some(active_item) = self.active_item() { if let Some(active_item) = self.active_item() {
Flex::column() Flex::column()
.with_child(self.render_tabs(cx)) .with_child(self.render_tabs(cx))
.with_child(ChildView::new(active_item.id()).flexible(1., true).boxed()) .with_child(ChildView::new(active_item).flexible(1., true).boxed())
.named("pane") .named("pane")
} else { } else {
Empty::new().named("pane") Empty::new().named("pane")

View File

@ -1,43 +1,45 @@
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use gpui::{elements::*, Axis}; use gpui::{elements::*, Axis, ViewHandle};
use theme::Theme; use theme::Theme;
use crate::Pane;
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq)]
pub struct PaneGroup { pub struct PaneGroup {
root: Member, root: Member,
} }
impl PaneGroup { impl PaneGroup {
pub fn new(pane_id: usize) -> Self { pub fn new(pane: ViewHandle<Pane>) -> Self {
Self { Self {
root: Member::Pane(pane_id), root: Member::Pane(pane),
} }
} }
pub fn split( pub fn split(
&mut self, &mut self,
old_pane_id: usize, old_pane: &ViewHandle<Pane>,
new_pane_id: usize, new_pane: &ViewHandle<Pane>,
direction: SplitDirection, direction: SplitDirection,
) -> Result<()> { ) -> Result<()> {
match &mut self.root { match &mut self.root {
Member::Pane(pane_id) => { Member::Pane(pane) => {
if *pane_id == old_pane_id { if pane == old_pane {
self.root = Member::new_axis(old_pane_id, new_pane_id, direction); self.root = Member::new_axis(old_pane.clone(), new_pane.clone(), direction);
Ok(()) Ok(())
} else { } else {
Err(anyhow!("Pane not found")) Err(anyhow!("Pane not found"))
} }
} }
Member::Axis(axis) => axis.split(old_pane_id, new_pane_id, direction), Member::Axis(axis) => axis.split(old_pane, new_pane, direction),
} }
} }
pub fn remove(&mut self, pane_id: usize) -> Result<bool> { pub fn remove(&mut self, pane: &ViewHandle<Pane>) -> Result<bool> {
match &mut self.root { match &mut self.root {
Member::Pane(_) => Ok(false), Member::Pane(_) => Ok(false),
Member::Axis(axis) => { Member::Axis(axis) => {
if let Some(last_pane) = axis.remove(pane_id)? { if let Some(last_pane) = axis.remove(pane)? {
self.root = last_pane; self.root = last_pane;
} }
Ok(true) Ok(true)
@ -53,11 +55,15 @@ impl PaneGroup {
#[derive(Clone, Debug, Eq, PartialEq)] #[derive(Clone, Debug, Eq, PartialEq)]
enum Member { enum Member {
Axis(PaneAxis), Axis(PaneAxis),
Pane(usize), Pane(ViewHandle<Pane>),
} }
impl Member { impl Member {
fn new_axis(old_pane_id: usize, new_pane_id: usize, direction: SplitDirection) -> Self { fn new_axis(
old_pane: ViewHandle<Pane>,
new_pane: ViewHandle<Pane>,
direction: SplitDirection,
) -> Self {
use Axis::*; use Axis::*;
use SplitDirection::*; use SplitDirection::*;
@ -67,16 +73,16 @@ impl Member {
}; };
let members = match direction { let members = match direction {
Up | Left => vec![Member::Pane(new_pane_id), Member::Pane(old_pane_id)], Up | Left => vec![Member::Pane(new_pane), Member::Pane(old_pane)],
Down | Right => vec![Member::Pane(old_pane_id), Member::Pane(new_pane_id)], Down | Right => vec![Member::Pane(old_pane), Member::Pane(new_pane)],
}; };
Member::Axis(PaneAxis { axis, members }) Member::Axis(PaneAxis { axis, members })
} }
pub fn render<'a>(&self, theme: &Theme) -> ElementBox { pub fn render(&self, theme: &Theme) -> ElementBox {
match self { match self {
Member::Pane(view_id) => ChildView::new(*view_id).boxed(), Member::Pane(pane) => ChildView::new(pane).boxed(),
Member::Axis(axis) => axis.render(theme), Member::Axis(axis) => axis.render(theme),
} }
} }
@ -91,8 +97,8 @@ struct PaneAxis {
impl PaneAxis { impl PaneAxis {
fn split( fn split(
&mut self, &mut self,
old_pane_id: usize, old_pane: &ViewHandle<Pane>,
new_pane_id: usize, new_pane: &ViewHandle<Pane>,
direction: SplitDirection, direction: SplitDirection,
) -> Result<()> { ) -> Result<()> {
use SplitDirection::*; use SplitDirection::*;
@ -100,23 +106,24 @@ impl PaneAxis {
for (idx, member) in self.members.iter_mut().enumerate() { for (idx, member) in self.members.iter_mut().enumerate() {
match member { match member {
Member::Axis(axis) => { Member::Axis(axis) => {
if axis.split(old_pane_id, new_pane_id, direction).is_ok() { if axis.split(old_pane, new_pane, direction).is_ok() {
return Ok(()); return Ok(());
} }
} }
Member::Pane(pane_id) => { Member::Pane(pane) => {
if *pane_id == old_pane_id { if pane == old_pane {
if direction.matches_axis(self.axis) { if direction.matches_axis(self.axis) {
match direction { match direction {
Up | Left => { Up | Left => {
self.members.insert(idx, Member::Pane(new_pane_id)); self.members.insert(idx, Member::Pane(new_pane.clone()));
} }
Down | Right => { Down | Right => {
self.members.insert(idx + 1, Member::Pane(new_pane_id)); self.members.insert(idx + 1, Member::Pane(new_pane.clone()));
} }
} }
} else { } else {
*member = Member::new_axis(old_pane_id, new_pane_id, direction); *member =
Member::new_axis(old_pane.clone(), new_pane.clone(), direction);
} }
return Ok(()); return Ok(());
} }
@ -126,13 +133,13 @@ impl PaneAxis {
Err(anyhow!("Pane not found")) Err(anyhow!("Pane not found"))
} }
fn remove(&mut self, pane_id_to_remove: usize) -> Result<Option<Member>> { fn remove(&mut self, pane_to_remove: &ViewHandle<Pane>) -> Result<Option<Member>> {
let mut found_pane = false; let mut found_pane = false;
let mut remove_member = None; let mut remove_member = None;
for (idx, member) in self.members.iter_mut().enumerate() { for (idx, member) in self.members.iter_mut().enumerate() {
match member { match member {
Member::Axis(axis) => { Member::Axis(axis) => {
if let Ok(last_pane) = axis.remove(pane_id_to_remove) { if let Ok(last_pane) = axis.remove(pane_to_remove) {
if let Some(last_pane) = last_pane { if let Some(last_pane) = last_pane {
*member = last_pane; *member = last_pane;
} }
@ -140,8 +147,8 @@ impl PaneAxis {
break; break;
} }
} }
Member::Pane(pane_id) => { Member::Pane(pane) => {
if *pane_id == pane_id_to_remove { if pane == pane_to_remove {
found_pane = true; found_pane = true;
remove_member = Some(idx); remove_member = Some(idx);
break; break;

View File

@ -136,7 +136,7 @@ impl Sidebar {
container.add_child( container.add_child(
Hook::new( Hook::new(
ConstrainedBox::new(ChildView::new(active_item.id()).boxed()) ConstrainedBox::new(ChildView::new(active_item).boxed())
.with_max_width(*self.width.borrow()) .with_max_width(*self.width.borrow())
.boxed(), .boxed(),
) )

View File

@ -1,7 +1,7 @@
use crate::{ItemViewHandle, Pane, Settings}; use crate::{ItemViewHandle, Pane, Settings};
use gpui::{ use gpui::{
elements::*, ElementBox, Entity, MutableAppContext, RenderContext, Subscription, View, elements::*, AnyViewHandle, ElementBox, Entity, MutableAppContext, RenderContext, Subscription,
ViewContext, ViewHandle, View, ViewContext, ViewHandle,
}; };
use postage::watch; use postage::watch;
@ -14,7 +14,7 @@ pub trait StatusItemView: View {
} }
trait StatusItemViewHandle { trait StatusItemViewHandle {
fn id(&self) -> usize; fn to_any(&self) -> AnyViewHandle;
fn set_active_pane_item( fn set_active_pane_item(
&self, &self,
active_pane_item: Option<&dyn ItemViewHandle>, active_pane_item: Option<&dyn ItemViewHandle>,
@ -45,13 +45,13 @@ impl View for StatusBar {
.with_children( .with_children(
self.left_items self.left_items
.iter() .iter()
.map(|i| ChildView::new(i.id()).aligned().boxed()), .map(|i| ChildView::new(i.as_ref()).aligned().boxed()),
) )
.with_child(Empty::new().flexible(1., true).boxed()) .with_child(Empty::new().flexible(1., true).boxed())
.with_children( .with_children(
self.right_items self.right_items
.iter() .iter()
.map(|i| ChildView::new(i.id()).aligned().boxed()), .map(|i| ChildView::new(i.as_ref()).aligned().boxed()),
) )
.contained() .contained()
.with_style(theme.container) .with_style(theme.container)
@ -111,8 +111,8 @@ impl StatusBar {
} }
impl<T: StatusItemView> StatusItemViewHandle for ViewHandle<T> { impl<T: StatusItemView> StatusItemViewHandle for ViewHandle<T> {
fn id(&self) -> usize { fn to_any(&self) -> AnyViewHandle {
self.id() self.into()
} }
fn set_active_pane_item( fn set_active_pane_item(
@ -125,3 +125,9 @@ impl<T: StatusItemView> StatusItemViewHandle for ViewHandle<T> {
}); });
} }
} }
impl Into<AnyViewHandle> for &dyn StatusItemViewHandle {
fn into(self) -> AnyViewHandle {
self.to_any()
}
}

View File

@ -599,7 +599,7 @@ impl Workspace {
Workspace { Workspace {
modal: None, modal: None,
weak_self: cx.weak_handle(), weak_self: cx.weak_handle(),
center: PaneGroup::new(pane.id()), center: PaneGroup::new(pane.clone()),
panes: vec![pane.clone()], panes: vec![pane.clone()],
active_pane: pane.clone(), active_pane: pane.clone(),
status_bar, status_bar,
@ -1048,15 +1048,13 @@ impl Workspace {
new_pane.update(cx, |new_pane, cx| new_pane.add_item_view(clone, cx)); new_pane.update(cx, |new_pane, cx| new_pane.add_item_view(clone, cx));
} }
} }
self.center self.center.split(&pane, &new_pane, direction).unwrap();
.split(pane.id(), new_pane.id(), direction)
.unwrap();
cx.notify(); cx.notify();
new_pane new_pane
} }
fn remove_pane(&mut self, pane: ViewHandle<Pane>, cx: &mut ViewContext<Self>) { fn remove_pane(&mut self, pane: ViewHandle<Pane>, cx: &mut ViewContext<Self>) {
if self.center.remove(pane.id()).unwrap() { if self.center.remove(&pane).unwrap() {
self.panes.retain(|p| p != &pane); self.panes.retain(|p| p != &pane);
self.activate_pane(self.panes.last().unwrap().clone(), cx); self.activate_pane(self.panes.last().unwrap().clone(), cx);
} }
@ -1287,7 +1285,7 @@ impl View for Workspace {
Flexible::new(1., true, self.center.render(&settings.theme)) Flexible::new(1., true, self.center.render(&settings.theme))
.boxed(), .boxed(),
) )
.with_child(ChildView::new(self.status_bar.id()).boxed()) .with_child(ChildView::new(&self.status_bar).boxed())
.flexible(1., true) .flexible(1., true)
.boxed(), .boxed(),
); );
@ -1298,7 +1296,7 @@ impl View for Workspace {
content.add_child(self.right_sidebar.render(&settings, cx)); content.add_child(self.right_sidebar.render(&settings, cx));
content.boxed() content.boxed()
}) })
.with_children(self.modal.as_ref().map(|m| ChildView::new(m.id()).boxed())) .with_children(self.modal.as_ref().map(|m| ChildView::new(m).boxed()))
.flexible(1.0, true) .flexible(1.0, true)
.boxed(), .boxed(),
) )