Merge branch 'main' into rename
This commit is contained in:
commit
514d69e83d
15 changed files with 131 additions and 173 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -5738,7 +5738,7 @@ checksum = "ec7a2a501ed189703dba8b08142f057e887dfc4b2cc4db2d343ac6376ba3e0b9"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zed"
|
name = "zed"
|
||||||
version = "0.15.1"
|
version = "0.15.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"async-recursion",
|
"async-recursion",
|
||||||
|
|
|
@ -325,10 +325,7 @@ impl ChatPanel {
|
||||||
enum SignInPromptLabel {}
|
enum SignInPromptLabel {}
|
||||||
|
|
||||||
Align::new(
|
Align::new(
|
||||||
MouseEventHandler::new::<SignInPromptLabel, _, _, _>(
|
MouseEventHandler::new::<SignInPromptLabel, _, _>(0, cx, |mouse_state, _| {
|
||||||
cx.view_id(),
|
|
||||||
cx,
|
|
||||||
|mouse_state, _| {
|
|
||||||
Label::new(
|
Label::new(
|
||||||
"Sign in to use chat".to_string(),
|
"Sign in to use chat".to_string(),
|
||||||
if mouse_state.hovered {
|
if mouse_state.hovered {
|
||||||
|
@ -338,8 +335,7 @@ impl ChatPanel {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.boxed()
|
.boxed()
|
||||||
},
|
})
|
||||||
)
|
|
||||||
.with_cursor_style(CursorStyle::PointingHand)
|
.with_cursor_style(CursorStyle::PointingHand)
|
||||||
.on_click(move |cx| {
|
.on_click(move |cx| {
|
||||||
let rpc = rpc.clone();
|
let rpc = rpc.clone();
|
||||||
|
|
|
@ -27,7 +27,6 @@ impl ContactsPanel {
|
||||||
1000.,
|
1000.,
|
||||||
{
|
{
|
||||||
let app_state = app_state.clone();
|
let app_state = app_state.clone();
|
||||||
let view_id = cx.view_id();
|
|
||||||
move |ix, cx| {
|
move |ix, cx| {
|
||||||
let user_store = app_state.user_store.read(cx);
|
let user_store = app_state.user_store.read(cx);
|
||||||
let contacts = user_store.contacts().clone();
|
let contacts = user_store.contacts().clone();
|
||||||
|
@ -36,7 +35,6 @@ impl ContactsPanel {
|
||||||
&contacts[ix],
|
&contacts[ix],
|
||||||
current_user_id,
|
current_user_id,
|
||||||
app_state.clone(),
|
app_state.clone(),
|
||||||
view_id,
|
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -58,7 +56,6 @@ impl ContactsPanel {
|
||||||
collaborator: &Contact,
|
collaborator: &Contact,
|
||||||
current_user_id: Option<u64>,
|
current_user_id: Option<u64>,
|
||||||
app_state: Arc<AppState>,
|
app_state: Arc<AppState>,
|
||||||
view_id: usize,
|
|
||||||
cx: &mut LayoutContext,
|
cx: &mut LayoutContext,
|
||||||
) -> ElementBox {
|
) -> ElementBox {
|
||||||
let theme = &app_state.settings.borrow().theme.contacts_panel;
|
let theme = &app_state.settings.borrow().theme.contacts_panel;
|
||||||
|
@ -159,8 +156,8 @@ impl ContactsPanel {
|
||||||
let is_shared = project.is_shared;
|
let is_shared = project.is_shared;
|
||||||
let app_state = app_state.clone();
|
let app_state = app_state.clone();
|
||||||
|
|
||||||
MouseEventHandler::new::<ContactsPanel, _, _, _>(
|
MouseEventHandler::new::<ContactsPanel, _, _>(
|
||||||
view_id,
|
project_id as usize,
|
||||||
cx,
|
cx,
|
||||||
|mouse_state, _| {
|
|mouse_state, _| {
|
||||||
let style = match (project.is_shared, mouse_state.hovered) {
|
let style = match (project.is_shared, mouse_state.hovered) {
|
||||||
|
|
|
@ -57,7 +57,7 @@ impl View for DiagnosticSummary {
|
||||||
let theme = &self.settings.borrow().theme.project_diagnostics;
|
let theme = &self.settings.borrow().theme.project_diagnostics;
|
||||||
|
|
||||||
let in_progress = self.in_progress;
|
let in_progress = self.in_progress;
|
||||||
MouseEventHandler::new::<Tag, _, _, _>(cx.view_id(), cx, |_, _| {
|
MouseEventHandler::new::<Tag, _, _>(0, cx, |_, _| {
|
||||||
if in_progress {
|
if in_progress {
|
||||||
Label::new(
|
Label::new(
|
||||||
"Checking... ".to_string(),
|
"Checking... ".to_string(),
|
||||||
|
|
|
@ -530,7 +530,6 @@ impl ContextMenu {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CompletionsMenu {
|
struct CompletionsMenu {
|
||||||
editor_id: usize,
|
|
||||||
id: CompletionId,
|
id: CompletionId,
|
||||||
initial_position: Anchor,
|
initial_position: Anchor,
|
||||||
buffer: ModelHandle<Buffer>,
|
buffer: ModelHandle<Buffer>,
|
||||||
|
@ -568,7 +567,6 @@ impl CompletionsMenu {
|
||||||
let settings = build_settings(cx);
|
let settings = build_settings(cx);
|
||||||
let completions = self.completions.clone();
|
let completions = self.completions.clone();
|
||||||
let matches = self.matches.clone();
|
let matches = self.matches.clone();
|
||||||
let editor_id = self.editor_id;
|
|
||||||
let selected_item = self.selected_item;
|
let selected_item = self.selected_item;
|
||||||
UniformList::new(self.list.clone(), matches.len(), move |range, items, cx| {
|
UniformList::new(self.list.clone(), matches.len(), move |range, items, cx| {
|
||||||
let settings = build_settings(cx);
|
let settings = build_settings(cx);
|
||||||
|
@ -577,8 +575,8 @@ impl CompletionsMenu {
|
||||||
let completion = &completions[mat.candidate_id];
|
let completion = &completions[mat.candidate_id];
|
||||||
let item_ix = start_ix + ix;
|
let item_ix = start_ix + ix;
|
||||||
items.push(
|
items.push(
|
||||||
MouseEventHandler::new::<CompletionTag, _, _, _>(
|
MouseEventHandler::new::<CompletionTag, _, _>(
|
||||||
(editor_id, mat.candidate_id),
|
mat.candidate_id,
|
||||||
cx,
|
cx,
|
||||||
|state, _| {
|
|state, _| {
|
||||||
let item_style = if item_ix == selected_item {
|
let item_style = if item_ix == selected_item {
|
||||||
|
@ -675,7 +673,6 @@ impl CompletionsMenu {
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct CodeActionsMenu {
|
struct CodeActionsMenu {
|
||||||
editor_id: usize,
|
|
||||||
actions: Arc<[CodeAction]>,
|
actions: Arc<[CodeAction]>,
|
||||||
buffer: ModelHandle<Buffer>,
|
buffer: ModelHandle<Buffer>,
|
||||||
selected_item: usize,
|
selected_item: usize,
|
||||||
|
@ -712,7 +709,6 @@ impl CodeActionsMenu {
|
||||||
|
|
||||||
let settings = build_settings(cx);
|
let settings = build_settings(cx);
|
||||||
let actions = self.actions.clone();
|
let actions = self.actions.clone();
|
||||||
let editor_id = self.editor_id;
|
|
||||||
let selected_item = self.selected_item;
|
let selected_item = self.selected_item;
|
||||||
let element =
|
let element =
|
||||||
UniformList::new(self.list.clone(), actions.len(), move |range, items, cx| {
|
UniformList::new(self.list.clone(), actions.len(), move |range, items, cx| {
|
||||||
|
@ -721,10 +717,7 @@ impl CodeActionsMenu {
|
||||||
for (ix, action) in actions[range].iter().enumerate() {
|
for (ix, action) in actions[range].iter().enumerate() {
|
||||||
let item_ix = start_ix + ix;
|
let item_ix = start_ix + ix;
|
||||||
items.push(
|
items.push(
|
||||||
MouseEventHandler::new::<ActionTag, _, _, _>(
|
MouseEventHandler::new::<ActionTag, _, _>(item_ix, cx, |state, _| {
|
||||||
(editor_id, item_ix),
|
|
||||||
cx,
|
|
||||||
|state, _| {
|
|
||||||
let item_style = if item_ix == selected_item {
|
let item_style = if item_ix == selected_item {
|
||||||
settings.style.autocomplete.selected_item
|
settings.style.autocomplete.selected_item
|
||||||
} else if state.hovered {
|
} else if state.hovered {
|
||||||
|
@ -733,16 +726,12 @@ impl CodeActionsMenu {
|
||||||
settings.style.autocomplete.item
|
settings.style.autocomplete.item
|
||||||
};
|
};
|
||||||
|
|
||||||
Text::new(
|
Text::new(action.lsp_action.title.clone(), settings.style.text.clone())
|
||||||
action.lsp_action.title.clone(),
|
|
||||||
settings.style.text.clone(),
|
|
||||||
)
|
|
||||||
.with_soft_wrap(false)
|
.with_soft_wrap(false)
|
||||||
.contained()
|
.contained()
|
||||||
.with_style(item_style)
|
.with_style(item_style)
|
||||||
.boxed()
|
.boxed()
|
||||||
},
|
})
|
||||||
)
|
|
||||||
.with_cursor_style(CursorStyle::PointingHand)
|
.with_cursor_style(CursorStyle::PointingHand)
|
||||||
.on_mouse_down(move |cx| {
|
.on_mouse_down(move |cx| {
|
||||||
cx.dispatch_action(ConfirmCodeAction(Some(item_ix)));
|
cx.dispatch_action(ConfirmCodeAction(Some(item_ix)));
|
||||||
|
@ -1955,7 +1944,6 @@ impl Editor {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut menu = CompletionsMenu {
|
let mut menu = CompletionsMenu {
|
||||||
editor_id: this.id(),
|
|
||||||
id,
|
id,
|
||||||
initial_position: position,
|
initial_position: position,
|
||||||
match_candidates: completions
|
match_candidates: completions
|
||||||
|
@ -2138,7 +2126,6 @@ impl Editor {
|
||||||
if let Some((buffer, actions)) = this.available_code_actions.clone() {
|
if let Some((buffer, actions)) = this.available_code_actions.clone() {
|
||||||
this.show_context_menu(
|
this.show_context_menu(
|
||||||
ContextMenu::CodeActions(CodeActionsMenu {
|
ContextMenu::CodeActions(CodeActionsMenu {
|
||||||
editor_id: this.handle.id(),
|
|
||||||
buffer,
|
buffer,
|
||||||
actions,
|
actions,
|
||||||
selected_item: Default::default(),
|
selected_item: Default::default(),
|
||||||
|
@ -2293,7 +2280,7 @@ impl Editor {
|
||||||
enum Tag {}
|
enum Tag {}
|
||||||
let style = (self.build_settings)(cx).style;
|
let style = (self.build_settings)(cx).style;
|
||||||
Some(
|
Some(
|
||||||
MouseEventHandler::new::<Tag, _, _, _>(cx.view_id(), cx, |_, _| {
|
MouseEventHandler::new::<Tag, _, _>(0, cx, |_, _| {
|
||||||
Svg::new("icons/zap.svg")
|
Svg::new("icons/zap.svg")
|
||||||
.with_color(style.code_actions_indicator)
|
.with_color(style.code_actions_indicator)
|
||||||
.boxed()
|
.boxed()
|
||||||
|
|
|
@ -227,7 +227,7 @@ impl FindBar {
|
||||||
) -> ElementBox {
|
) -> ElementBox {
|
||||||
let theme = &self.settings.borrow().theme.find;
|
let theme = &self.settings.borrow().theme.find;
|
||||||
let is_active = self.is_mode_enabled(mode);
|
let is_active = self.is_mode_enabled(mode);
|
||||||
MouseEventHandler::new::<Self, _, _, _>((cx.view_id(), mode as usize), cx, |state, _| {
|
MouseEventHandler::new::<Self, _, _>(mode as usize, cx, |state, _| {
|
||||||
let style = match (is_active, state.hovered) {
|
let style = match (is_active, state.hovered) {
|
||||||
(false, false) => &theme.mode_button,
|
(false, false) => &theme.mode_button,
|
||||||
(false, true) => &theme.hovered_mode_button,
|
(false, true) => &theme.hovered_mode_button,
|
||||||
|
@ -251,10 +251,8 @@ impl FindBar {
|
||||||
cx: &mut RenderContext<Self>,
|
cx: &mut RenderContext<Self>,
|
||||||
) -> ElementBox {
|
) -> ElementBox {
|
||||||
let theme = &self.settings.borrow().theme.find;
|
let theme = &self.settings.borrow().theme.find;
|
||||||
MouseEventHandler::new::<Self, _, _, _>(
|
enum NavButton {}
|
||||||
(cx.view_id(), 10 + direction as usize),
|
MouseEventHandler::new::<NavButton, _, _>(direction as usize, cx, |state, _| {
|
||||||
cx,
|
|
||||||
|state, _| {
|
|
||||||
let style = if state.hovered {
|
let style = if state.hovered {
|
||||||
&theme.hovered_mode_button
|
&theme.hovered_mode_button
|
||||||
} else {
|
} else {
|
||||||
|
@ -264,8 +262,7 @@ impl FindBar {
|
||||||
.contained()
|
.contained()
|
||||||
.with_style(style.container)
|
.with_style(style.container)
|
||||||
.boxed()
|
.boxed()
|
||||||
},
|
})
|
||||||
)
|
|
||||||
.on_click(move |cx| cx.dispatch_action(GoToMatch(direction)))
|
.on_click(move |cx| cx.dispatch_action(GoToMatch(direction)))
|
||||||
.with_cursor_style(CursorStyle::PointingHand)
|
.with_cursor_style(CursorStyle::PointingHand)
|
||||||
.boxed()
|
.boxed()
|
||||||
|
|
|
@ -116,6 +116,26 @@ pub trait UpdateView {
|
||||||
T: View;
|
T: View;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait ElementStateContext: DerefMut<Target = MutableAppContext> {
|
||||||
|
fn current_view_id(&self) -> usize;
|
||||||
|
|
||||||
|
fn element_state<Tag: 'static, T: 'static + Default>(
|
||||||
|
&mut self,
|
||||||
|
element_id: usize,
|
||||||
|
) -> ElementStateHandle<T> {
|
||||||
|
let id = ElementStateId {
|
||||||
|
view_id: self.current_view_id(),
|
||||||
|
element_id,
|
||||||
|
tag: TypeId::of::<Tag>(),
|
||||||
|
};
|
||||||
|
self.cx
|
||||||
|
.element_states
|
||||||
|
.entry(id)
|
||||||
|
.or_insert_with(|| Box::new(T::default()));
|
||||||
|
ElementStateHandle::new(id, self.frame_count, &self.cx.ref_counts)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub trait Action: 'static + AnyAction {
|
pub trait Action: 'static + AnyAction {
|
||||||
type Argument: 'static + Clone;
|
type Argument: 'static + Clone;
|
||||||
}
|
}
|
||||||
|
@ -1414,23 +1434,6 @@ impl MutableAppContext {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn element_state<Tag: 'static, T: 'static + Default>(
|
|
||||||
&mut self,
|
|
||||||
id: ElementStateId,
|
|
||||||
) -> ElementStateHandle<T> {
|
|
||||||
let key = (TypeId::of::<Tag>(), id);
|
|
||||||
self.cx
|
|
||||||
.element_states
|
|
||||||
.entry(key)
|
|
||||||
.or_insert_with(|| Box::new(T::default()));
|
|
||||||
ElementStateHandle::new(
|
|
||||||
TypeId::of::<Tag>(),
|
|
||||||
id,
|
|
||||||
self.frame_count,
|
|
||||||
&self.cx.ref_counts,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remove_dropped_entities(&mut self) {
|
fn remove_dropped_entities(&mut self) {
|
||||||
loop {
|
loop {
|
||||||
let (dropped_models, dropped_views, dropped_element_states) =
|
let (dropped_models, dropped_views, dropped_element_states) =
|
||||||
|
@ -1850,7 +1853,7 @@ pub struct AppContext {
|
||||||
models: HashMap<usize, Box<dyn AnyModel>>,
|
models: HashMap<usize, Box<dyn AnyModel>>,
|
||||||
views: HashMap<(usize, usize), Box<dyn AnyView>>,
|
views: HashMap<(usize, usize), Box<dyn AnyView>>,
|
||||||
windows: HashMap<usize, Window>,
|
windows: HashMap<usize, Window>,
|
||||||
element_states: HashMap<(TypeId, ElementStateId), Box<dyn Any>>,
|
element_states: HashMap<ElementStateId, Box<dyn Any>>,
|
||||||
background: Arc<executor::Background>,
|
background: Arc<executor::Background>,
|
||||||
ref_counts: Arc<Mutex<RefCounts>>,
|
ref_counts: Arc<Mutex<RefCounts>>,
|
||||||
font_cache: Arc<FontCache>,
|
font_cache: Arc<FontCache>,
|
||||||
|
@ -2607,6 +2610,12 @@ impl<V: View> ReadView for RenderContext<'_, V> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<V: View> ElementStateContext for RenderContext<'_, V> {
|
||||||
|
fn current_view_id(&self) -> usize {
|
||||||
|
self.view_id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<M> AsRef<AppContext> for ViewContext<'_, M> {
|
impl<M> AsRef<AppContext> for ViewContext<'_, M> {
|
||||||
fn as_ref(&self) -> &AppContext {
|
fn as_ref(&self) -> &AppContext {
|
||||||
&self.app.cx
|
&self.app.cx
|
||||||
|
@ -2687,6 +2696,12 @@ impl<V: View> UpdateView for ViewContext<'_, V> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<V: View> ElementStateContext for ViewContext<'_, V> {
|
||||||
|
fn current_view_id(&self) -> usize {
|
||||||
|
self.view_id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub trait Handle<T> {
|
pub trait Handle<T> {
|
||||||
type Weak: 'static;
|
type Weak: 'static;
|
||||||
fn id(&self) -> usize;
|
fn id(&self) -> usize;
|
||||||
|
@ -3430,41 +3445,24 @@ impl<T> Hash for WeakViewHandle<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct ElementStateId(usize, usize);
|
pub struct ElementStateId {
|
||||||
|
view_id: usize,
|
||||||
impl From<usize> for ElementStateId {
|
element_id: usize,
|
||||||
fn from(id: usize) -> Self {
|
tag: TypeId,
|
||||||
Self(id, 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<(usize, usize)> for ElementStateId {
|
|
||||||
fn from(id: (usize, usize)) -> Self {
|
|
||||||
Self(id.0, id.1)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ElementStateHandle<T> {
|
pub struct ElementStateHandle<T> {
|
||||||
value_type: PhantomData<T>,
|
value_type: PhantomData<T>,
|
||||||
tag_type_id: TypeId,
|
|
||||||
id: ElementStateId,
|
id: ElementStateId,
|
||||||
ref_counts: Weak<Mutex<RefCounts>>,
|
ref_counts: Weak<Mutex<RefCounts>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: 'static> ElementStateHandle<T> {
|
impl<T: 'static> ElementStateHandle<T> {
|
||||||
fn new(
|
fn new(id: ElementStateId, frame_id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
|
||||||
tag_type_id: TypeId,
|
ref_counts.lock().inc_element_state(id, frame_id);
|
||||||
id: ElementStateId,
|
|
||||||
frame_id: usize,
|
|
||||||
ref_counts: &Arc<Mutex<RefCounts>>,
|
|
||||||
) -> Self {
|
|
||||||
ref_counts
|
|
||||||
.lock()
|
|
||||||
.inc_element_state(tag_type_id, id, frame_id);
|
|
||||||
Self {
|
Self {
|
||||||
value_type: PhantomData,
|
value_type: PhantomData,
|
||||||
tag_type_id,
|
|
||||||
id,
|
id,
|
||||||
ref_counts: Arc::downgrade(ref_counts),
|
ref_counts: Arc::downgrade(ref_counts),
|
||||||
}
|
}
|
||||||
|
@ -3472,7 +3470,7 @@ impl<T: 'static> ElementStateHandle<T> {
|
||||||
|
|
||||||
pub fn read<'a>(&self, cx: &'a AppContext) -> &'a T {
|
pub fn read<'a>(&self, cx: &'a AppContext) -> &'a T {
|
||||||
cx.element_states
|
cx.element_states
|
||||||
.get(&(self.tag_type_id, self.id))
|
.get(&self.id)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.downcast_ref()
|
.downcast_ref()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
@ -3482,17 +3480,12 @@ impl<T: 'static> ElementStateHandle<T> {
|
||||||
where
|
where
|
||||||
C: DerefMut<Target = MutableAppContext>,
|
C: DerefMut<Target = MutableAppContext>,
|
||||||
{
|
{
|
||||||
let mut element_state = cx
|
let mut element_state = cx.deref_mut().cx.element_states.remove(&self.id).unwrap();
|
||||||
.deref_mut()
|
|
||||||
.cx
|
|
||||||
.element_states
|
|
||||||
.remove(&(self.tag_type_id, self.id))
|
|
||||||
.unwrap();
|
|
||||||
let result = f(element_state.downcast_mut().unwrap(), cx);
|
let result = f(element_state.downcast_mut().unwrap(), cx);
|
||||||
cx.deref_mut()
|
cx.deref_mut()
|
||||||
.cx
|
.cx
|
||||||
.element_states
|
.element_states
|
||||||
.insert((self.tag_type_id, self.id), element_state);
|
.insert(self.id, element_state);
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3500,9 +3493,7 @@ impl<T: 'static> ElementStateHandle<T> {
|
||||||
impl<T> Drop for ElementStateHandle<T> {
|
impl<T> Drop for ElementStateHandle<T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
if let Some(ref_counts) = self.ref_counts.upgrade() {
|
if let Some(ref_counts) = self.ref_counts.upgrade() {
|
||||||
ref_counts
|
ref_counts.lock().dec_element_state(self.id);
|
||||||
.lock()
|
|
||||||
.dec_element_state(self.tag_type_id, self.id);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3600,10 +3591,10 @@ impl Drop for Subscription {
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct RefCounts {
|
struct RefCounts {
|
||||||
entity_counts: HashMap<usize, usize>,
|
entity_counts: HashMap<usize, usize>,
|
||||||
element_state_counts: HashMap<(TypeId, ElementStateId), ElementStateRefCount>,
|
element_state_counts: HashMap<ElementStateId, ElementStateRefCount>,
|
||||||
dropped_models: HashSet<usize>,
|
dropped_models: HashSet<usize>,
|
||||||
dropped_views: HashSet<(usize, usize)>,
|
dropped_views: HashSet<(usize, usize)>,
|
||||||
dropped_element_states: HashSet<(TypeId, ElementStateId)>,
|
dropped_element_states: HashSet<ElementStateId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ElementStateRefCount {
|
struct ElementStateRefCount {
|
||||||
|
@ -3634,8 +3625,8 @@ impl RefCounts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn inc_element_state(&mut self, tag_type_id: TypeId, id: ElementStateId, frame_id: usize) {
|
fn inc_element_state(&mut self, id: ElementStateId, frame_id: usize) {
|
||||||
match self.element_state_counts.entry((tag_type_id, id)) {
|
match self.element_state_counts.entry(id) {
|
||||||
Entry::Occupied(mut entry) => {
|
Entry::Occupied(mut entry) => {
|
||||||
let entry = entry.get_mut();
|
let entry = entry.get_mut();
|
||||||
if entry.frame_id == frame_id || entry.ref_count >= 2 {
|
if entry.frame_id == frame_id || entry.ref_count >= 2 {
|
||||||
|
@ -3649,7 +3640,7 @@ impl RefCounts {
|
||||||
ref_count: 1,
|
ref_count: 1,
|
||||||
frame_id,
|
frame_id,
|
||||||
});
|
});
|
||||||
self.dropped_element_states.remove(&(tag_type_id, id));
|
self.dropped_element_states.remove(&id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3672,13 +3663,12 @@ impl RefCounts {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dec_element_state(&mut self, tag_type_id: TypeId, id: ElementStateId) {
|
fn dec_element_state(&mut self, id: ElementStateId) {
|
||||||
let key = (tag_type_id, id);
|
let entry = self.element_state_counts.get_mut(&id).unwrap();
|
||||||
let entry = self.element_state_counts.get_mut(&key).unwrap();
|
|
||||||
entry.ref_count -= 1;
|
entry.ref_count -= 1;
|
||||||
if entry.ref_count == 0 {
|
if entry.ref_count == 0 {
|
||||||
self.element_state_counts.remove(&key);
|
self.element_state_counts.remove(&id);
|
||||||
self.dropped_element_states.insert(key);
|
self.dropped_element_states.insert(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3691,7 +3681,7 @@ impl RefCounts {
|
||||||
) -> (
|
) -> (
|
||||||
HashSet<usize>,
|
HashSet<usize>,
|
||||||
HashSet<(usize, usize)>,
|
HashSet<(usize, usize)>,
|
||||||
HashSet<(TypeId, ElementStateId)>,
|
HashSet<ElementStateId>,
|
||||||
) {
|
) {
|
||||||
(
|
(
|
||||||
std::mem::take(&mut self.dropped_models),
|
std::mem::take(&mut self.dropped_models),
|
||||||
|
|
|
@ -5,11 +5,10 @@ use crate::{
|
||||||
vector::{vec2f, Vector2F},
|
vector::{vec2f, Vector2F},
|
||||||
},
|
},
|
||||||
platform::CursorStyle,
|
platform::CursorStyle,
|
||||||
CursorStyleHandle, DebugContext, Element, ElementBox, ElementStateHandle, ElementStateId,
|
CursorStyleHandle, DebugContext, Element, ElementBox, ElementStateContext, ElementStateHandle,
|
||||||
Event, EventContext, LayoutContext, MutableAppContext, PaintContext, SizeConstraint,
|
Event, EventContext, LayoutContext, PaintContext, SizeConstraint,
|
||||||
};
|
};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use std::ops::DerefMut;
|
|
||||||
|
|
||||||
pub struct MouseEventHandler {
|
pub struct MouseEventHandler {
|
||||||
state: ElementStateHandle<MouseState>,
|
state: ElementStateHandle<MouseState>,
|
||||||
|
@ -30,14 +29,13 @@ pub struct MouseState {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MouseEventHandler {
|
impl MouseEventHandler {
|
||||||
pub fn new<Tag, F, C, Id>(id: Id, cx: &mut C, render_child: F) -> Self
|
pub fn new<Tag, C, F>(id: usize, cx: &mut C, render_child: F) -> Self
|
||||||
where
|
where
|
||||||
Tag: 'static,
|
Tag: 'static,
|
||||||
|
C: ElementStateContext,
|
||||||
F: FnOnce(&MouseState, &mut C) -> ElementBox,
|
F: FnOnce(&MouseState, &mut C) -> ElementBox,
|
||||||
C: DerefMut<Target = MutableAppContext>,
|
|
||||||
Id: Into<ElementStateId>,
|
|
||||||
{
|
{
|
||||||
let state_handle = cx.element_state::<Tag, _>(id.into());
|
let state_handle = cx.element_state::<Tag, _>(id);
|
||||||
let child = state_handle.update(cx, |state, cx| render_child(state, cx));
|
let child = state_handle.update(cx, |state, cx| render_child(state, cx));
|
||||||
Self {
|
Self {
|
||||||
state: state_handle,
|
state: state_handle,
|
||||||
|
|
|
@ -7,8 +7,8 @@ use crate::{
|
||||||
platform::Event,
|
platform::Event,
|
||||||
text_layout::TextLayoutCache,
|
text_layout::TextLayoutCache,
|
||||||
Action, AnyAction, AnyModelHandle, AnyViewHandle, AnyWeakModelHandle, AssetCache, ElementBox,
|
Action, AnyAction, AnyModelHandle, AnyViewHandle, AnyWeakModelHandle, AssetCache, ElementBox,
|
||||||
Entity, FontSystem, ModelHandle, ReadModel, ReadView, Scene, UpgradeModelHandle,
|
ElementStateContext, Entity, FontSystem, ModelHandle, ReadModel, ReadView, Scene,
|
||||||
UpgradeViewHandle, View, ViewHandle, WeakModelHandle, WeakViewHandle,
|
UpgradeModelHandle, UpgradeViewHandle, View, ViewHandle, WeakModelHandle, WeakViewHandle,
|
||||||
};
|
};
|
||||||
use pathfinder_geometry::vector::{vec2f, Vector2F};
|
use pathfinder_geometry::vector::{vec2f, Vector2F};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
@ -292,6 +292,12 @@ impl<'a> UpgradeViewHandle for LayoutContext<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> ElementStateContext for LayoutContext<'a> {
|
||||||
|
fn current_view_id(&self) -> usize {
|
||||||
|
*self.view_stack.last().unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct PaintContext<'a> {
|
pub struct PaintContext<'a> {
|
||||||
rendered_views: &'a mut HashMap<usize, ElementBox>,
|
rendered_views: &'a mut HashMap<usize, ElementBox>,
|
||||||
pub scene: &'a mut Scene,
|
pub scene: &'a mut Scene,
|
||||||
|
|
|
@ -104,7 +104,7 @@ impl View for Select {
|
||||||
Default::default()
|
Default::default()
|
||||||
};
|
};
|
||||||
let mut result = Flex::column().with_child(
|
let mut result = Flex::column().with_child(
|
||||||
MouseEventHandler::new::<Header, _, _, _>(self.handle.id(), cx, |mouse_state, cx| {
|
MouseEventHandler::new::<Header, _, _>(self.handle.id(), cx, |mouse_state, cx| {
|
||||||
Container::new((self.render_item)(
|
Container::new((self.render_item)(
|
||||||
self.selected_item_ix,
|
self.selected_item_ix,
|
||||||
ItemType::Header,
|
ItemType::Header,
|
||||||
|
@ -132,8 +132,8 @@ impl View for Select {
|
||||||
let selected_item_ix = this.selected_item_ix;
|
let selected_item_ix = this.selected_item_ix;
|
||||||
range.end = range.end.min(this.item_count);
|
range.end = range.end.min(this.item_count);
|
||||||
items.extend(range.map(|ix| {
|
items.extend(range.map(|ix| {
|
||||||
MouseEventHandler::new::<Item, _, _, _>(
|
MouseEventHandler::new::<Item, _, _>(
|
||||||
(handle.id(), ix),
|
ix,
|
||||||
cx,
|
cx,
|
||||||
|mouse_state, cx| {
|
|mouse_state, cx| {
|
||||||
(handle.read(cx).render_item)(
|
(handle.read(cx).render_item)(
|
||||||
|
|
|
@ -476,7 +476,7 @@ impl ProjectPanel {
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) -> ElementBox {
|
) -> ElementBox {
|
||||||
let is_dir = details.is_dir;
|
let is_dir = details.is_dir;
|
||||||
MouseEventHandler::new::<Self, _, _, _>((cx.view_id(), entry.entry_id), cx, |state, _| {
|
MouseEventHandler::new::<Self, _, _>(entry.entry_id, cx, |state, _| {
|
||||||
let style = match (details.is_selected, state.hovered) {
|
let style = match (details.is_selected, state.hovered) {
|
||||||
(false, false) => &theme.entry,
|
(false, false) => &theme.entry,
|
||||||
(false, true) => &theme.hovered_entry,
|
(false, true) => &theme.hovered_entry,
|
||||||
|
|
|
@ -466,7 +466,7 @@ impl Pane {
|
||||||
let theme = &settings.theme;
|
let theme = &settings.theme;
|
||||||
|
|
||||||
enum Tabs {}
|
enum Tabs {}
|
||||||
let tabs = MouseEventHandler::new::<Tabs, _, _, _>(cx.view_id(), cx, |mouse_state, cx| {
|
let tabs = MouseEventHandler::new::<Tabs, _, _>(0, cx, |mouse_state, cx| {
|
||||||
let mut row = Flex::row();
|
let mut row = Flex::row();
|
||||||
for (ix, (_, item_view)) in self.item_views.iter().enumerate() {
|
for (ix, (_, item_view)) in self.item_views.iter().enumerate() {
|
||||||
let is_active = ix == self.active_item_index;
|
let is_active = ix == self.active_item_index;
|
||||||
|
@ -543,7 +543,7 @@ impl Pane {
|
||||||
let item_id = item_view.id();
|
let item_id = item_view.id();
|
||||||
enum TabCloseButton {}
|
enum TabCloseButton {}
|
||||||
let icon = Svg::new("icons/x.svg");
|
let icon = Svg::new("icons/x.svg");
|
||||||
MouseEventHandler::new::<TabCloseButton, _, _, _>(
|
MouseEventHandler::new::<TabCloseButton, _, _>(
|
||||||
item_id,
|
item_id,
|
||||||
cx,
|
cx,
|
||||||
|mouse_state, _| {
|
|mouse_state, _| {
|
||||||
|
|
|
@ -83,10 +83,7 @@ impl Sidebar {
|
||||||
&theme.item
|
&theme.item
|
||||||
};
|
};
|
||||||
enum SidebarButton {}
|
enum SidebarButton {}
|
||||||
MouseEventHandler::new::<SidebarButton, _, _, _>(
|
MouseEventHandler::new::<SidebarButton, _, _>(item.view.id(), cx, |_, _| {
|
||||||
item.view.id(),
|
|
||||||
cx,
|
|
||||||
|_, _| {
|
|
||||||
ConstrainedBox::new(
|
ConstrainedBox::new(
|
||||||
Align::new(
|
Align::new(
|
||||||
ConstrainedBox::new(
|
ConstrainedBox::new(
|
||||||
|
@ -101,8 +98,7 @@ impl Sidebar {
|
||||||
)
|
)
|
||||||
.with_height(theme.height)
|
.with_height(theme.height)
|
||||||
.boxed()
|
.boxed()
|
||||||
},
|
})
|
||||||
)
|
|
||||||
.with_cursor_style(CursorStyle::PointingHand)
|
.with_cursor_style(CursorStyle::PointingHand)
|
||||||
.on_mouse_down(move |cx| {
|
.on_mouse_down(move |cx| {
|
||||||
cx.dispatch_action(ToggleSidebarItem(SidebarItemId {
|
cx.dispatch_action(ToggleSidebarItem(SidebarItemId {
|
||||||
|
@ -161,7 +157,7 @@ impl Sidebar {
|
||||||
) -> ElementBox {
|
) -> ElementBox {
|
||||||
let width = self.width.clone();
|
let width = self.width.clone();
|
||||||
let side = self.side;
|
let side = self.side;
|
||||||
MouseEventHandler::new::<Self, _, _, _>((cx.view_id(), self.side.id()), cx, |_, _| {
|
MouseEventHandler::new::<Self, _, _>(side as usize, cx, |_, _| {
|
||||||
Container::new(Empty::new().boxed())
|
Container::new(Empty::new().boxed())
|
||||||
.with_style(self.theme(settings).resize_handle)
|
.with_style(self.theme(settings).resize_handle)
|
||||||
.boxed()
|
.boxed()
|
||||||
|
@ -184,12 +180,3 @@ impl Sidebar {
|
||||||
.boxed()
|
.boxed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Side {
|
|
||||||
fn id(self) -> usize {
|
|
||||||
match self {
|
|
||||||
Side::Left => 0,
|
|
||||||
Side::Right => 1,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1191,7 +1191,7 @@ impl Workspace {
|
||||||
if let Some(avatar) = user.and_then(|user| user.avatar.clone()) {
|
if let Some(avatar) = user.and_then(|user| user.avatar.clone()) {
|
||||||
self.render_avatar(avatar, replica_id, theme)
|
self.render_avatar(avatar, replica_id, theme)
|
||||||
} else {
|
} else {
|
||||||
MouseEventHandler::new::<Authenticate, _, _, _>(cx.view_id(), cx, |state, _| {
|
MouseEventHandler::new::<Authenticate, _, _>(0, cx, |state, _| {
|
||||||
let style = if state.hovered {
|
let style = if state.hovered {
|
||||||
&theme.workspace.titlebar.hovered_sign_in_prompt
|
&theme.workspace.titlebar.hovered_sign_in_prompt
|
||||||
} else {
|
} else {
|
||||||
|
@ -1252,7 +1252,7 @@ impl Workspace {
|
||||||
theme.workspace.titlebar.share_icon_color
|
theme.workspace.titlebar.share_icon_color
|
||||||
};
|
};
|
||||||
Some(
|
Some(
|
||||||
MouseEventHandler::new::<Share, _, _, _>(cx.view_id(), cx, |_, _| {
|
MouseEventHandler::new::<Share, _, _>(0, cx, |_, _| {
|
||||||
Align::new(
|
Align::new(
|
||||||
ConstrainedBox::new(
|
ConstrainedBox::new(
|
||||||
Svg::new("icons/broadcast-24.svg").with_color(color).boxed(),
|
Svg::new("icons/broadcast-24.svg").with_color(color).boxed(),
|
||||||
|
|
|
@ -3,7 +3,7 @@ authors = ["Nathan Sobo <nathansobo@gmail.com>"]
|
||||||
description = "The fast, collaborative code editor."
|
description = "The fast, collaborative code editor."
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
name = "zed"
|
name = "zed"
|
||||||
version = "0.15.1"
|
version = "0.15.2"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
name = "zed"
|
name = "zed"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue