Fix pane splitting panic (#3381)
Also opens the window on startup. Release Notes: -
This commit is contained in:
commit
f01a04a8e0
8 changed files with 90 additions and 50 deletions
|
@ -1550,7 +1550,7 @@ mod tests {
|
||||||
block_id: ix,
|
block_id: ix,
|
||||||
editor_style: &editor::EditorStyle::default(),
|
editor_style: &editor::EditorStyle::default(),
|
||||||
})
|
})
|
||||||
.element_id()?
|
.inner_id()?
|
||||||
.try_into()
|
.try_into()
|
||||||
.ok()?,
|
.ok()?,
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ impl Render for DiagnosticIndicator {
|
||||||
};
|
};
|
||||||
|
|
||||||
h_stack()
|
h_stack()
|
||||||
.id(cx.entity_id())
|
.id("diagnostic-indicator")
|
||||||
.on_action(cx.listener(Self::go_to_next_diagnostic))
|
.on_action(cx.listener(Self::go_to_next_diagnostic))
|
||||||
.rounded_md()
|
.rounded_md()
|
||||||
.flex_none()
|
.flex_none()
|
||||||
|
|
|
@ -432,10 +432,6 @@ impl AnyElement {
|
||||||
AnyElement(Box::new(Some(DrawableElement::new(element))) as Box<dyn ElementObject>)
|
AnyElement(Box::new(Some(DrawableElement::new(element))) as Box<dyn ElementObject>)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn element_id(&self) -> Option<ElementId> {
|
|
||||||
self.0.element_id()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn layout(&mut self, cx: &mut WindowContext) -> LayoutId {
|
pub fn layout(&mut self, cx: &mut WindowContext) -> LayoutId {
|
||||||
self.0.layout(cx)
|
self.0.layout(cx)
|
||||||
}
|
}
|
||||||
|
@ -467,6 +463,10 @@ impl AnyElement {
|
||||||
pub fn into_any(self) -> AnyElement {
|
pub fn into_any(self) -> AnyElement {
|
||||||
AnyElement::new(self)
|
AnyElement::new(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn inner_id(&self) -> Option<ElementId> {
|
||||||
|
self.0.element_id()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Element for AnyElement {
|
impl Element for AnyElement {
|
||||||
|
@ -490,7 +490,7 @@ impl RenderOnce for AnyElement {
|
||||||
type Element = Self;
|
type Element = Self;
|
||||||
|
|
||||||
fn element_id(&self) -> Option<ElementId> {
|
fn element_id(&self) -> Option<ElementId> {
|
||||||
AnyElement::element_id(self)
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_once(self) -> Self::Element {
|
fn render_once(self) -> Self::Element {
|
||||||
|
|
|
@ -248,7 +248,7 @@ impl<V: 'static + Render> RenderOnce for View<V> {
|
||||||
type Element = View<V>;
|
type Element = View<V>;
|
||||||
|
|
||||||
fn element_id(&self) -> Option<ElementId> {
|
fn element_id(&self) -> Option<ElementId> {
|
||||||
Some(self.model.entity_id.into())
|
Some(ElementId::from_entity_id(self.model.entity_id))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_once(self) -> Self::Element {
|
fn render_once(self) -> Self::Element {
|
||||||
|
@ -260,7 +260,7 @@ impl RenderOnce for AnyView {
|
||||||
type Element = Self;
|
type Element = Self;
|
||||||
|
|
||||||
fn element_id(&self) -> Option<ElementId> {
|
fn element_id(&self) -> Option<ElementId> {
|
||||||
Some(self.model.entity_id.into())
|
Some(ElementId::from_entity_id(self.model.entity_id))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_once(self) -> Self::Element {
|
fn render_once(self) -> Self::Element {
|
||||||
|
@ -308,27 +308,23 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
mod any_view {
|
mod any_view {
|
||||||
use crate::{AnyElement, AnyView, BorrowWindow, Element, LayoutId, Render, WindowContext};
|
use crate::{AnyElement, AnyView, Element, LayoutId, Render, WindowContext};
|
||||||
|
|
||||||
pub(crate) fn layout<V: 'static + Render>(
|
pub(crate) fn layout<V: 'static + Render>(
|
||||||
view: &AnyView,
|
view: &AnyView,
|
||||||
cx: &mut WindowContext,
|
cx: &mut WindowContext,
|
||||||
) -> (LayoutId, AnyElement) {
|
) -> (LayoutId, AnyElement) {
|
||||||
cx.with_element_id(Some(view.model.entity_id), |cx| {
|
let view = view.clone().downcast::<V>().unwrap();
|
||||||
let view = view.clone().downcast::<V>().unwrap();
|
let mut element = view.update(cx, |view, cx| view.render(cx).into_any());
|
||||||
let mut element = view.update(cx, |view, cx| view.render(cx).into_any());
|
let layout_id = element.layout(cx);
|
||||||
let layout_id = element.layout(cx);
|
(layout_id, element)
|
||||||
(layout_id, element)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn paint<V: 'static + Render>(
|
pub(crate) fn paint<V: 'static + Render>(
|
||||||
view: &AnyView,
|
_view: &AnyView,
|
||||||
element: AnyElement,
|
element: AnyElement,
|
||||||
cx: &mut WindowContext,
|
cx: &mut WindowContext,
|
||||||
) {
|
) {
|
||||||
cx.with_element_id(Some(view.model.entity_id), |cx| {
|
element.paint(cx);
|
||||||
element.paint(cx);
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -230,9 +230,15 @@ pub struct Window {
|
||||||
pub(crate) focus: Option<FocusId>,
|
pub(crate) focus: Option<FocusId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) struct ElementStateBox {
|
||||||
|
inner: Box<dyn Any>,
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
type_name: &'static str,
|
||||||
|
}
|
||||||
|
|
||||||
// #[derive(Default)]
|
// #[derive(Default)]
|
||||||
pub(crate) struct Frame {
|
pub(crate) struct Frame {
|
||||||
pub(crate) element_states: HashMap<GlobalElementId, Box<dyn Any>>,
|
pub(crate) element_states: HashMap<GlobalElementId, ElementStateBox>,
|
||||||
mouse_listeners: HashMap<TypeId, Vec<(StackingOrder, AnyMouseListener)>>,
|
mouse_listeners: HashMap<TypeId, Vec<(StackingOrder, AnyMouseListener)>>,
|
||||||
pub(crate) dispatch_tree: DispatchTree,
|
pub(crate) dispatch_tree: DispatchTree,
|
||||||
pub(crate) focus_listeners: Vec<AnyFocusListener>,
|
pub(crate) focus_listeners: Vec<AnyFocusListener>,
|
||||||
|
@ -1815,10 +1821,37 @@ pub trait BorrowWindow: BorrowMut<Window> + BorrowMut<AppContext> {
|
||||||
.remove(&global_id)
|
.remove(&global_id)
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
|
let ElementStateBox {
|
||||||
|
inner,
|
||||||
|
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
type_name
|
||||||
|
} = any;
|
||||||
// Using the extra inner option to avoid needing to reallocate a new box.
|
// Using the extra inner option to avoid needing to reallocate a new box.
|
||||||
let mut state_box = any
|
let mut state_box = inner
|
||||||
.downcast::<Option<S>>()
|
.downcast::<Option<S>>()
|
||||||
.expect("invalid element state type for id");
|
.map_err(|_| {
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
{
|
||||||
|
anyhow!(
|
||||||
|
"invalid element state type for id, requested_type {:?}, actual type: {:?}",
|
||||||
|
std::any::type_name::<S>(),
|
||||||
|
type_name
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(debug_assertions))]
|
||||||
|
{
|
||||||
|
anyhow!(
|
||||||
|
"invalid element state type for id, requested_type {:?}",
|
||||||
|
std::any::type_name::<S>(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// Actual: Option<AnyElement> <- View
|
||||||
|
// Requested: () <- AnyElemet
|
||||||
let state = state_box
|
let state = state_box
|
||||||
.take()
|
.take()
|
||||||
.expect("element state is already on the stack");
|
.expect("element state is already on the stack");
|
||||||
|
@ -1827,14 +1860,27 @@ pub trait BorrowWindow: BorrowMut<Window> + BorrowMut<AppContext> {
|
||||||
cx.window_mut()
|
cx.window_mut()
|
||||||
.current_frame
|
.current_frame
|
||||||
.element_states
|
.element_states
|
||||||
.insert(global_id, state_box);
|
.insert(global_id, ElementStateBox {
|
||||||
|
inner: state_box,
|
||||||
|
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
type_name
|
||||||
|
});
|
||||||
result
|
result
|
||||||
} else {
|
} else {
|
||||||
let (result, state) = f(None, cx);
|
let (result, state) = f(None, cx);
|
||||||
cx.window_mut()
|
cx.window_mut()
|
||||||
.current_frame
|
.current_frame
|
||||||
.element_states
|
.element_states
|
||||||
.insert(global_id, Box::new(Some(state)));
|
.insert(global_id,
|
||||||
|
ElementStateBox {
|
||||||
|
inner: Box::new(Some(state)),
|
||||||
|
|
||||||
|
#[cfg(debug_assertions)]
|
||||||
|
type_name: std::any::type_name::<S>()
|
||||||
|
}
|
||||||
|
|
||||||
|
);
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -2599,6 +2645,12 @@ pub enum ElementId {
|
||||||
FocusHandle(FocusId),
|
FocusHandle(FocusId),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ElementId {
|
||||||
|
pub(crate) fn from_entity_id(entity_id: EntityId) -> Self {
|
||||||
|
ElementId::View(entity_id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl TryInto<SharedString> for ElementId {
|
impl TryInto<SharedString> for ElementId {
|
||||||
type Error = anyhow::Error;
|
type Error = anyhow::Error;
|
||||||
|
|
||||||
|
@ -2611,12 +2663,6 @@ impl TryInto<SharedString> for ElementId {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<EntityId> for ElementId {
|
|
||||||
fn from(id: EntityId) -> Self {
|
|
||||||
ElementId::View(id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<usize> for ElementId {
|
impl From<usize> for ElementId {
|
||||||
fn from(id: usize) -> Self {
|
fn from(id: usize) -> Self {
|
||||||
ElementId::Integer(id)
|
ElementId::Integer(id)
|
||||||
|
|
|
@ -717,12 +717,9 @@ impl Render for PanelButtons {
|
||||||
&& panel.position_is_valid(position, cx)
|
&& panel.position_is_valid(position, cx)
|
||||||
{
|
{
|
||||||
let panel = panel.clone();
|
let panel = panel.clone();
|
||||||
menu = menu.entry(
|
menu = menu.entry(position.to_label(), move |_, cx| {
|
||||||
format!("Dock {}", position.to_label()),
|
panel.set_position(position, cx);
|
||||||
move |_, cx| {
|
})
|
||||||
panel.set_position(position, cx);
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
menu
|
menu
|
||||||
|
|
|
@ -1350,7 +1350,7 @@ impl Pane {
|
||||||
let id = item.item_id();
|
let id = item.item_id();
|
||||||
|
|
||||||
div()
|
div()
|
||||||
.id(item.item_id())
|
.id(ix)
|
||||||
.invisible()
|
.invisible()
|
||||||
.group_hover("", |style| style.visible())
|
.group_hover("", |style| style.visible())
|
||||||
.child(
|
.child(
|
||||||
|
@ -1382,7 +1382,7 @@ impl Pane {
|
||||||
|
|
||||||
div()
|
div()
|
||||||
.group("")
|
.group("")
|
||||||
.id(item.item_id())
|
.id(ix)
|
||||||
.cursor_pointer()
|
.cursor_pointer()
|
||||||
.when_some(item.tab_tooltip_text(cx), |div, text| {
|
.when_some(item.tab_tooltip_text(cx), |div, text| {
|
||||||
div.tooltip(move |cx| cx.build_view(|cx| Tooltip::new(text.clone())).into())
|
div.tooltip(move |cx| cx.build_view(|cx| Tooltip::new(text.clone())).into())
|
||||||
|
|
|
@ -210,7 +210,7 @@ impl Member {
|
||||||
// Some(pane)
|
// Some(pane)
|
||||||
// };
|
// };
|
||||||
|
|
||||||
div().size_full().child(pane.clone())
|
div().size_full().child(pane.clone()).into_any()
|
||||||
|
|
||||||
// Stack::new()
|
// Stack::new()
|
||||||
// .with_child(pane_element.contained().with_border(leader_border))
|
// .with_child(pane_element.contained().with_border(leader_border))
|
||||||
|
@ -226,15 +226,17 @@ impl Member {
|
||||||
// .bg(cx.theme().colors().editor)
|
// .bg(cx.theme().colors().editor)
|
||||||
// .children();
|
// .children();
|
||||||
}
|
}
|
||||||
Member::Axis(axis) => axis.render(
|
Member::Axis(axis) => axis
|
||||||
project,
|
.render(
|
||||||
basis + 1,
|
project,
|
||||||
follower_states,
|
basis + 1,
|
||||||
active_pane,
|
follower_states,
|
||||||
zoomed,
|
active_pane,
|
||||||
app_state,
|
zoomed,
|
||||||
cx,
|
app_state,
|
||||||
),
|
cx,
|
||||||
|
)
|
||||||
|
.into_any(),
|
||||||
}
|
}
|
||||||
|
|
||||||
// enum FollowIntoExternalProject {}
|
// enum FollowIntoExternalProject {}
|
||||||
|
@ -551,7 +553,6 @@ impl PaneAxis {
|
||||||
project: &Model<Project>,
|
project: &Model<Project>,
|
||||||
basis: usize,
|
basis: usize,
|
||||||
follower_states: &HashMap<View<Pane>, FollowerState>,
|
follower_states: &HashMap<View<Pane>, FollowerState>,
|
||||||
|
|
||||||
active_pane: &View<Pane>,
|
active_pane: &View<Pane>,
|
||||||
zoomed: Option<&AnyWeakView>,
|
zoomed: Option<&AnyWeakView>,
|
||||||
app_state: &Arc<AppState>,
|
app_state: &Arc<AppState>,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue