Remove lock from element states
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
parent
d5b7e2d4e3
commit
53dc08dfc5
14 changed files with 143 additions and 104 deletions
|
@ -28,7 +28,7 @@ impl gpui::View for TextView {
|
|||
"View"
|
||||
}
|
||||
|
||||
fn render(&self, _: &gpui::RenderContext<Self>) -> gpui::ElementBox {
|
||||
fn render(&self, _: &mut gpui::RenderContext<Self>) -> gpui::ElementBox {
|
||||
TextElement.boxed()
|
||||
}
|
||||
}
|
||||
|
|
156
gpui/src/app.rs
156
gpui/src/app.rs
|
@ -5,13 +5,12 @@ use crate::{
|
|||
platform::{self, Platform, PromptLevel, WindowOptions},
|
||||
presenter::Presenter,
|
||||
util::{post_inc, timeout},
|
||||
AssetCache, AssetSource, ClipboardItem, EventContext, FontCache, PathPromptOptions,
|
||||
TextLayoutCache,
|
||||
AssetCache, AssetSource, ClipboardItem, FontCache, PathPromptOptions, TextLayoutCache,
|
||||
};
|
||||
use anyhow::{anyhow, Result};
|
||||
use async_task::Task;
|
||||
use keymap::MatchResult;
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
use parking_lot::Mutex;
|
||||
use platform::Event;
|
||||
use postage::{mpsc, sink::Sink as _, stream::Stream as _};
|
||||
use smol::prelude::*;
|
||||
|
@ -38,7 +37,7 @@ pub trait Entity: 'static {
|
|||
|
||||
pub trait View: Entity + Sized {
|
||||
fn ui_name() -> &'static str;
|
||||
fn render(&self, cx: &RenderContext<'_, Self>) -> ElementBox;
|
||||
fn render(&self, cx: &mut RenderContext<'_, Self>) -> ElementBox;
|
||||
fn on_focus(&mut self, _: &mut ViewContext<Self>) {}
|
||||
fn on_blur(&mut self, _: &mut ViewContext<Self>) {}
|
||||
fn keymap_context(&self, _: &AppContext) -> keymap::Context {
|
||||
|
@ -681,7 +680,7 @@ impl MutableAppContext {
|
|||
models: Default::default(),
|
||||
views: Default::default(),
|
||||
windows: Default::default(),
|
||||
values: Default::default(),
|
||||
element_states: Default::default(),
|
||||
ref_counts: Arc::new(Mutex::new(RefCounts::default())),
|
||||
background,
|
||||
font_cache,
|
||||
|
@ -1308,11 +1307,26 @@ impl MutableAppContext {
|
|||
handle
|
||||
}
|
||||
|
||||
pub fn element_state<Tag: 'static, T: 'static + Default>(
|
||||
&mut self,
|
||||
id: usize,
|
||||
) -> 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.cx.ref_counts)
|
||||
}
|
||||
|
||||
fn remove_dropped_entities(&mut self) {
|
||||
loop {
|
||||
let (dropped_models, dropped_views, dropped_values) =
|
||||
let (dropped_models, dropped_views, dropped_element_states) =
|
||||
self.cx.ref_counts.lock().take_dropped();
|
||||
if dropped_models.is_empty() && dropped_views.is_empty() && dropped_values.is_empty() {
|
||||
if dropped_models.is_empty()
|
||||
&& dropped_views.is_empty()
|
||||
&& dropped_element_states.is_empty()
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1346,9 +1360,8 @@ impl MutableAppContext {
|
|||
}
|
||||
}
|
||||
|
||||
let mut values = self.cx.values.write();
|
||||
for key in dropped_values {
|
||||
values.remove(&key);
|
||||
for key in dropped_element_states {
|
||||
self.cx.element_states.remove(&key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1667,7 +1680,7 @@ pub struct AppContext {
|
|||
models: HashMap<usize, Box<dyn AnyModel>>,
|
||||
views: HashMap<(usize, usize), Box<dyn AnyView>>,
|
||||
windows: HashMap<usize, Window>,
|
||||
values: RwLock<HashMap<(TypeId, usize), Box<dyn Any>>>,
|
||||
element_states: HashMap<(TypeId, usize), Box<dyn Any>>,
|
||||
background: Arc<executor::Background>,
|
||||
ref_counts: Arc<Mutex<RefCounts>>,
|
||||
font_cache: Arc<FontCache>,
|
||||
|
@ -1698,15 +1711,6 @@ impl AppContext {
|
|||
pub fn platform(&self) -> &Arc<dyn Platform> {
|
||||
&self.platform
|
||||
}
|
||||
|
||||
pub fn value<Tag: 'static, T: 'static + Default>(&self, id: usize) -> ValueHandle<T> {
|
||||
let key = (TypeId::of::<Tag>(), id);
|
||||
self.values
|
||||
.write()
|
||||
.entry(key)
|
||||
.or_insert_with(|| Box::new(T::default()));
|
||||
ValueHandle::new(TypeId::of::<Tag>(), id, &self.ref_counts)
|
||||
}
|
||||
}
|
||||
|
||||
impl ReadModel for AppContext {
|
||||
|
@ -1875,7 +1879,7 @@ where
|
|||
) -> ElementBox {
|
||||
View::render(
|
||||
self,
|
||||
&RenderContext {
|
||||
&mut RenderContext {
|
||||
window_id,
|
||||
view_id,
|
||||
app: cx,
|
||||
|
@ -2269,10 +2273,16 @@ impl AsRef<AppContext> for &AppContext {
|
|||
}
|
||||
|
||||
impl<V: View> Deref for RenderContext<'_, V> {
|
||||
type Target = AppContext;
|
||||
type Target = MutableAppContext;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.app
|
||||
self.app
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: View> DerefMut for RenderContext<'_, V> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
self.app
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2964,16 +2974,16 @@ impl<T> Clone for WeakViewHandle<T> {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct ValueHandle<T> {
|
||||
pub struct ElementStateHandle<T> {
|
||||
value_type: PhantomData<T>,
|
||||
tag_type_id: TypeId,
|
||||
id: usize,
|
||||
ref_counts: Weak<Mutex<RefCounts>>,
|
||||
}
|
||||
|
||||
impl<T: 'static> ValueHandle<T> {
|
||||
impl<T: 'static> ElementStateHandle<T> {
|
||||
fn new(tag_type_id: TypeId, id: usize, ref_counts: &Arc<Mutex<RefCounts>>) -> Self {
|
||||
ref_counts.lock().inc_value(tag_type_id, id);
|
||||
ref_counts.lock().inc_element_state(tag_type_id, id);
|
||||
Self {
|
||||
value_type: PhantomData,
|
||||
tag_type_id,
|
||||
|
@ -2982,41 +2992,39 @@ impl<T: 'static> ValueHandle<T> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn read<R>(&self, cx: &AppContext, f: impl FnOnce(&T) -> R) -> R {
|
||||
f(cx.values
|
||||
.read()
|
||||
pub fn read<'a>(&self, cx: &'a AppContext) -> &'a T {
|
||||
cx.element_states
|
||||
.get(&(self.tag_type_id, self.id))
|
||||
.unwrap()
|
||||
.downcast_ref()
|
||||
.unwrap())
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
pub fn update<R>(
|
||||
&self,
|
||||
cx: &mut EventContext,
|
||||
f: impl FnOnce(&mut T, &mut EventContext) -> R,
|
||||
) -> R {
|
||||
let mut value = cx
|
||||
.app
|
||||
pub fn update<C, R>(&self, cx: &mut C, f: impl FnOnce(&mut T, &mut C) -> R) -> R
|
||||
where
|
||||
C: DerefMut<Target = MutableAppContext>,
|
||||
{
|
||||
let mut element_state = cx
|
||||
.deref_mut()
|
||||
.cx
|
||||
.values
|
||||
.write()
|
||||
.element_states
|
||||
.remove(&(self.tag_type_id, self.id))
|
||||
.unwrap();
|
||||
let result = f(value.downcast_mut().unwrap(), cx);
|
||||
cx.app
|
||||
let result = f(element_state.downcast_mut().unwrap(), cx);
|
||||
cx.deref_mut()
|
||||
.cx
|
||||
.values
|
||||
.write()
|
||||
.insert((self.tag_type_id, self.id), value);
|
||||
.element_states
|
||||
.insert((self.tag_type_id, self.id), element_state);
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Drop for ValueHandle<T> {
|
||||
impl<T> Drop for ElementStateHandle<T> {
|
||||
fn drop(&mut self) {
|
||||
if let Some(ref_counts) = self.ref_counts.upgrade() {
|
||||
ref_counts.lock().dec_value(self.tag_type_id, self.id);
|
||||
ref_counts
|
||||
.lock()
|
||||
.dec_element_state(self.tag_type_id, self.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3080,10 +3088,10 @@ impl Drop for Subscription {
|
|||
#[derive(Default)]
|
||||
struct RefCounts {
|
||||
entity_counts: HashMap<usize, usize>,
|
||||
value_counts: HashMap<(TypeId, usize), usize>,
|
||||
element_state_counts: HashMap<(TypeId, usize), usize>,
|
||||
dropped_models: HashSet<usize>,
|
||||
dropped_views: HashSet<(usize, usize)>,
|
||||
dropped_values: HashSet<(TypeId, usize)>,
|
||||
dropped_element_states: HashSet<(TypeId, usize)>,
|
||||
}
|
||||
|
||||
impl RefCounts {
|
||||
|
@ -3107,8 +3115,11 @@ impl RefCounts {
|
|||
}
|
||||
}
|
||||
|
||||
fn inc_value(&mut self, tag_type_id: TypeId, id: usize) {
|
||||
*self.value_counts.entry((tag_type_id, id)).or_insert(0) += 1;
|
||||
fn inc_element_state(&mut self, tag_type_id: TypeId, id: usize) {
|
||||
*self
|
||||
.element_state_counts
|
||||
.entry((tag_type_id, id))
|
||||
.or_insert(0) += 1;
|
||||
}
|
||||
|
||||
fn dec_model(&mut self, model_id: usize) {
|
||||
|
@ -3129,13 +3140,13 @@ impl RefCounts {
|
|||
}
|
||||
}
|
||||
|
||||
fn dec_value(&mut self, tag_type_id: TypeId, id: usize) {
|
||||
fn dec_element_state(&mut self, tag_type_id: TypeId, id: usize) {
|
||||
let key = (tag_type_id, id);
|
||||
let count = self.value_counts.get_mut(&key).unwrap();
|
||||
let count = self.element_state_counts.get_mut(&key).unwrap();
|
||||
*count -= 1;
|
||||
if *count == 0 {
|
||||
self.value_counts.remove(&key);
|
||||
self.dropped_values.insert(key);
|
||||
self.element_state_counts.remove(&key);
|
||||
self.dropped_element_states.insert(key);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3152,11 +3163,14 @@ impl RefCounts {
|
|||
) {
|
||||
let mut dropped_models = HashSet::new();
|
||||
let mut dropped_views = HashSet::new();
|
||||
let mut dropped_values = HashSet::new();
|
||||
let mut dropped_element_states = HashSet::new();
|
||||
std::mem::swap(&mut self.dropped_models, &mut dropped_models);
|
||||
std::mem::swap(&mut self.dropped_views, &mut dropped_views);
|
||||
std::mem::swap(&mut self.dropped_values, &mut dropped_values);
|
||||
(dropped_models, dropped_views, dropped_values)
|
||||
std::mem::swap(
|
||||
&mut self.dropped_element_states,
|
||||
&mut dropped_element_states,
|
||||
);
|
||||
(dropped_models, dropped_views, dropped_element_states)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3314,7 +3328,7 @@ mod tests {
|
|||
}
|
||||
|
||||
impl super::View for View {
|
||||
fn render<'a>(&self, _: &RenderContext<Self>) -> ElementBox {
|
||||
fn render<'a>(&self, _: &mut RenderContext<Self>) -> ElementBox {
|
||||
Empty::new().boxed()
|
||||
}
|
||||
|
||||
|
@ -3378,7 +3392,7 @@ mod tests {
|
|||
}
|
||||
|
||||
impl super::View for View {
|
||||
fn render<'a>(&self, _: &RenderContext<Self>) -> ElementBox {
|
||||
fn render<'a>(&self, _: &mut RenderContext<Self>) -> ElementBox {
|
||||
let mouse_down_count = self.mouse_down_count.clone();
|
||||
EventHandler::new(Empty::new().boxed())
|
||||
.on_mouse_down(move |_| {
|
||||
|
@ -3440,7 +3454,7 @@ mod tests {
|
|||
"View"
|
||||
}
|
||||
|
||||
fn render<'a>(&self, _: &RenderContext<Self>) -> ElementBox {
|
||||
fn render<'a>(&self, _: &mut RenderContext<Self>) -> ElementBox {
|
||||
Empty::new().boxed()
|
||||
}
|
||||
}
|
||||
|
@ -3480,7 +3494,7 @@ mod tests {
|
|||
}
|
||||
|
||||
impl super::View for View {
|
||||
fn render<'a>(&self, _: &RenderContext<Self>) -> ElementBox {
|
||||
fn render<'a>(&self, _: &mut RenderContext<Self>) -> ElementBox {
|
||||
Empty::new().boxed()
|
||||
}
|
||||
|
||||
|
@ -3536,7 +3550,7 @@ mod tests {
|
|||
}
|
||||
|
||||
impl super::View for View {
|
||||
fn render<'a>(&self, _: &RenderContext<Self>) -> ElementBox {
|
||||
fn render<'a>(&self, _: &mut RenderContext<Self>) -> ElementBox {
|
||||
Empty::new().boxed()
|
||||
}
|
||||
|
||||
|
@ -3586,7 +3600,7 @@ mod tests {
|
|||
}
|
||||
|
||||
impl super::View for View {
|
||||
fn render<'a>(&self, _: &RenderContext<Self>) -> ElementBox {
|
||||
fn render<'a>(&self, _: &mut RenderContext<Self>) -> ElementBox {
|
||||
Empty::new().boxed()
|
||||
}
|
||||
|
||||
|
@ -3630,7 +3644,7 @@ mod tests {
|
|||
}
|
||||
|
||||
impl super::View for View {
|
||||
fn render<'a>(&self, _: &RenderContext<Self>) -> ElementBox {
|
||||
fn render<'a>(&self, _: &mut RenderContext<Self>) -> ElementBox {
|
||||
Empty::new().boxed()
|
||||
}
|
||||
|
||||
|
@ -3677,7 +3691,7 @@ mod tests {
|
|||
}
|
||||
|
||||
impl super::View for View {
|
||||
fn render<'a>(&self, _: &RenderContext<Self>) -> ElementBox {
|
||||
fn render<'a>(&self, _: &mut RenderContext<Self>) -> ElementBox {
|
||||
Empty::new().boxed()
|
||||
}
|
||||
|
||||
|
@ -3735,7 +3749,7 @@ mod tests {
|
|||
}
|
||||
|
||||
impl View for ViewA {
|
||||
fn render<'a>(&self, _: &RenderContext<Self>) -> ElementBox {
|
||||
fn render<'a>(&self, _: &mut RenderContext<Self>) -> ElementBox {
|
||||
Empty::new().boxed()
|
||||
}
|
||||
|
||||
|
@ -3753,7 +3767,7 @@ mod tests {
|
|||
}
|
||||
|
||||
impl View for ViewB {
|
||||
fn render<'a>(&self, _: &RenderContext<Self>) -> ElementBox {
|
||||
fn render<'a>(&self, _: &mut RenderContext<Self>) -> ElementBox {
|
||||
Empty::new().boxed()
|
||||
}
|
||||
|
||||
|
@ -3849,7 +3863,7 @@ mod tests {
|
|||
}
|
||||
|
||||
impl super::View for View {
|
||||
fn render<'a>(&self, _: &RenderContext<Self>) -> ElementBox {
|
||||
fn render<'a>(&self, _: &mut RenderContext<Self>) -> ElementBox {
|
||||
Empty::new().boxed()
|
||||
}
|
||||
|
||||
|
@ -3984,7 +3998,7 @@ mod tests {
|
|||
"test view"
|
||||
}
|
||||
|
||||
fn render(&self, _: &RenderContext<Self>) -> ElementBox {
|
||||
fn render(&self, _: &mut RenderContext<Self>) -> ElementBox {
|
||||
Empty::new().boxed()
|
||||
}
|
||||
}
|
||||
|
@ -4029,7 +4043,7 @@ mod tests {
|
|||
"test view"
|
||||
}
|
||||
|
||||
fn render(&self, _: &RenderContext<Self>) -> ElementBox {
|
||||
fn render(&self, _: &mut RenderContext<Self>) -> ElementBox {
|
||||
Empty::new().boxed()
|
||||
}
|
||||
}
|
||||
|
@ -4052,7 +4066,7 @@ mod tests {
|
|||
"test view"
|
||||
}
|
||||
|
||||
fn render(&self, _: &RenderContext<Self>) -> ElementBox {
|
||||
fn render(&self, _: &mut RenderContext<Self>) -> ElementBox {
|
||||
Empty::new().boxed()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -496,7 +496,7 @@ mod tests {
|
|||
"TestView"
|
||||
}
|
||||
|
||||
fn render(&self, _: &RenderContext<'_, Self>) -> ElementBox {
|
||||
fn render(&self, _: &mut RenderContext<'_, Self>) -> ElementBox {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
use std::ops::DerefMut;
|
||||
|
||||
use crate::{
|
||||
geometry::{rect::RectF, vector::Vector2F},
|
||||
AppContext, DebugContext, Element, ElementBox, Event, EventContext, LayoutContext,
|
||||
PaintContext, SizeConstraint, ValueHandle,
|
||||
DebugContext, Element, ElementBox, ElementStateHandle, Event, EventContext, LayoutContext,
|
||||
MutableAppContext, PaintContext, SizeConstraint,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
pub struct MouseEventHandler {
|
||||
state: ValueHandle<MouseState>,
|
||||
state: ElementStateHandle<MouseState>,
|
||||
child: ElementBox,
|
||||
click_handler: Option<Box<dyn FnMut(&mut EventContext)>>,
|
||||
drag_handler: Option<Box<dyn FnMut(Vector2F, &mut EventContext)>>,
|
||||
|
@ -20,14 +22,14 @@ pub struct MouseState {
|
|||
}
|
||||
|
||||
impl MouseEventHandler {
|
||||
pub fn new<Tag, F>(id: usize, cx: &AppContext, render_child: F) -> Self
|
||||
pub fn new<Tag, F, C>(id: usize, cx: &mut C, render_child: F) -> Self
|
||||
where
|
||||
Tag: 'static,
|
||||
F: FnOnce(MouseState) -> ElementBox,
|
||||
F: FnOnce(&MouseState, &mut C) -> ElementBox,
|
||||
C: DerefMut<Target = MutableAppContext>,
|
||||
{
|
||||
let state_handle = cx.value::<Tag, _>(id);
|
||||
let state = state_handle.read(cx.as_ref(), |state| *state);
|
||||
let child = render_child(state);
|
||||
let state_handle = cx.element_state::<Tag, _>(id);
|
||||
let child = state_handle.update(cx, |state, cx| render_child(state, cx));
|
||||
Self {
|
||||
state: state_handle,
|
||||
child,
|
||||
|
|
|
@ -11,6 +11,7 @@ use pathfinder_geometry::vector::{vec2f, Vector2F};
|
|||
use serde_json::json;
|
||||
use std::{
|
||||
collections::{HashMap, HashSet},
|
||||
ops::{Deref, DerefMut},
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
|
@ -269,6 +270,20 @@ impl<'a> EventContext<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> Deref for EventContext<'a> {
|
||||
type Target = MutableAppContext;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.app
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> DerefMut for EventContext<'a> {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
self.app
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DebugContext<'a> {
|
||||
rendered_views: &'a HashMap<usize, ElementBox>,
|
||||
pub font_cache: &'a FontCache,
|
||||
|
|
|
@ -1620,7 +1620,7 @@ mod tests {
|
|||
"empty view"
|
||||
}
|
||||
|
||||
fn render<'a>(&self, _: &gpui::RenderContext<Self>) -> gpui::ElementBox {
|
||||
fn render(&self, _: &mut gpui::RenderContext<Self>) -> gpui::ElementBox {
|
||||
gpui::Element::boxed(gpui::elements::Empty)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -99,7 +99,7 @@ impl ChatPanel {
|
|||
cx.notify();
|
||||
}
|
||||
|
||||
fn render_channel_name(&self, cx: &RenderContext<Self>) -> ElementBox {
|
||||
fn render_channel_name(&self, cx: &mut RenderContext<Self>) -> ElementBox {
|
||||
let settings = self.settings.borrow();
|
||||
let theme = &settings.theme.chat_panel;
|
||||
if let Some((channel, _)) = self.active_channel.as_ref() {
|
||||
|
@ -121,7 +121,7 @@ impl ChatPanel {
|
|||
}
|
||||
}
|
||||
|
||||
fn render_active_channel_messages(&self, cx: &RenderContext<Self>) -> ElementBox {
|
||||
fn render_active_channel_messages(&self, cx: &mut RenderContext<Self>) -> ElementBox {
|
||||
let messages = if let Some((channel, _)) = self.active_channel.as_ref() {
|
||||
let channel = channel.read(cx);
|
||||
let now = OffsetDateTime::now_utc();
|
||||
|
@ -202,7 +202,7 @@ impl View for ChatPanel {
|
|||
"ChatPanel"
|
||||
}
|
||||
|
||||
fn render(&self, cx: &RenderContext<Self>) -> ElementBox {
|
||||
fn render(&self, cx: &mut RenderContext<Self>) -> ElementBox {
|
||||
let theme = &self.settings.borrow().theme;
|
||||
Container::new(
|
||||
Flex::column()
|
||||
|
|
|
@ -2522,7 +2522,7 @@ impl Entity for Editor {
|
|||
}
|
||||
|
||||
impl View for Editor {
|
||||
fn render<'a>(&self, _: &RenderContext<Self>) -> ElementBox {
|
||||
fn render<'a>(&self, _: &mut RenderContext<Self>) -> ElementBox {
|
||||
EditorElement::new(self.handle.clone()).boxed()
|
||||
}
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ impl View for FileFinder {
|
|||
"FileFinder"
|
||||
}
|
||||
|
||||
fn render(&self, _: &RenderContext<Self>) -> ElementBox {
|
||||
fn render(&self, _: &mut RenderContext<Self>) -> ElementBox {
|
||||
let settings = self.settings.borrow();
|
||||
|
||||
Align::new(
|
||||
|
|
|
@ -13,7 +13,7 @@ impl View for ProjectBrowser {
|
|||
"ProjectBrowser"
|
||||
}
|
||||
|
||||
fn render(&self, _: &gpui::RenderContext<'_, Self>) -> gpui::ElementBox {
|
||||
fn render(&self, _: &mut gpui::RenderContext<'_, Self>) -> gpui::ElementBox {
|
||||
Empty::new().boxed()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -200,7 +200,7 @@ impl ThemeSelector {
|
|||
}
|
||||
}
|
||||
|
||||
fn render_matches(&self, cx: &RenderContext<Self>) -> ElementBox {
|
||||
fn render_matches(&self, cx: &mut RenderContext<Self>) -> ElementBox {
|
||||
if self.matches.is_empty() {
|
||||
let settings = self.settings.borrow();
|
||||
return Container::new(
|
||||
|
@ -269,7 +269,7 @@ impl View for ThemeSelector {
|
|||
"ThemeSelector"
|
||||
}
|
||||
|
||||
fn render(&self, cx: &RenderContext<Self>) -> ElementBox {
|
||||
fn render(&self, cx: &mut RenderContext<Self>) -> ElementBox {
|
||||
let settings = self.settings.borrow();
|
||||
|
||||
Align::new(
|
||||
|
|
|
@ -944,7 +944,7 @@ impl View for Workspace {
|
|||
"Workspace"
|
||||
}
|
||||
|
||||
fn render(&self, cx: &RenderContext<Self>) -> ElementBox {
|
||||
fn render(&self, cx: &mut RenderContext<Self>) -> ElementBox {
|
||||
let settings = self.settings.borrow();
|
||||
Container::new(
|
||||
Flex::column()
|
||||
|
|
|
@ -6,8 +6,7 @@ use gpui::{
|
|||
elements::*,
|
||||
geometry::{rect::RectF, vector::vec2f},
|
||||
keymap::Binding,
|
||||
AppContext, Border, Entity, MutableAppContext, Quad, RenderContext, View, ViewContext,
|
||||
ViewHandle,
|
||||
Border, Entity, MutableAppContext, Quad, RenderContext, View, ViewContext, ViewHandle,
|
||||
};
|
||||
use postage::watch;
|
||||
use std::{cmp, path::Path, sync::Arc};
|
||||
|
@ -175,7 +174,7 @@ impl Pane {
|
|||
cx.emit(Event::Split(direction));
|
||||
}
|
||||
|
||||
fn render_tabs(&self, cx: &AppContext) -> ElementBox {
|
||||
fn render_tabs(&self, cx: &mut RenderContext<Self>) -> ElementBox {
|
||||
let settings = self.settings.borrow();
|
||||
let theme = &settings.theme;
|
||||
let line_height = cx.font_cache().line_height(
|
||||
|
@ -194,7 +193,7 @@ impl Pane {
|
|||
row.add_child(
|
||||
Expanded::new(
|
||||
1.0,
|
||||
MouseEventHandler::new::<Tab, _>(item.id(), cx, |mouse_state| {
|
||||
MouseEventHandler::new::<Tab, _, _>(item.id(), cx, |mouse_state, cx| {
|
||||
let title = item.title(cx);
|
||||
|
||||
let mut border = border.clone();
|
||||
|
@ -299,7 +298,7 @@ impl Pane {
|
|||
is_dirty: bool,
|
||||
has_conflict: bool,
|
||||
theme: &theme::Theme,
|
||||
cx: &AppContext,
|
||||
cx: &mut RenderContext<Self>,
|
||||
) -> ElementBox {
|
||||
enum TabCloseButton {}
|
||||
|
||||
|
@ -318,7 +317,7 @@ impl Pane {
|
|||
let close_color = current_color.unwrap_or(theme.workspace.tab.icon_close);
|
||||
let icon = Svg::new("icons/x.svg").with_color(close_color);
|
||||
|
||||
MouseEventHandler::new::<TabCloseButton, _>(item_id, cx, |mouse_state| {
|
||||
MouseEventHandler::new::<TabCloseButton, _, _>(item_id, cx, |mouse_state, _| {
|
||||
if mouse_state.hovered {
|
||||
Container::new(icon.with_color(Color::white()).boxed())
|
||||
.with_background_color(if mouse_state.clicked {
|
||||
|
@ -370,7 +369,7 @@ impl View for Pane {
|
|||
"Pane"
|
||||
}
|
||||
|
||||
fn render<'a>(&self, cx: &RenderContext<Self>) -> ElementBox {
|
||||
fn render(&self, cx: &mut RenderContext<Self>) -> ElementBox {
|
||||
if let Some(active_item) = self.active_item() {
|
||||
Flex::column()
|
||||
.with_child(self.render_tabs(cx))
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use super::Workspace;
|
||||
use crate::Settings;
|
||||
use gpui::{action, elements::*, AnyViewHandle, AppContext};
|
||||
use gpui::{action, elements::*, AnyViewHandle, MutableAppContext, RenderContext};
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
pub struct Sidebar {
|
||||
|
@ -56,7 +57,7 @@ impl Sidebar {
|
|||
.map(|item| &item.view)
|
||||
}
|
||||
|
||||
pub fn render(&self, settings: &Settings, cx: &AppContext) -> ElementBox {
|
||||
pub fn render(&self, settings: &Settings, cx: &mut RenderContext<Workspace>) -> ElementBox {
|
||||
let side = self.side;
|
||||
let theme = &settings.theme;
|
||||
let line_height = cx.font_cache().line_height(
|
||||
|
@ -73,7 +74,7 @@ impl Sidebar {
|
|||
&settings.theme.workspace.sidebar_icon
|
||||
};
|
||||
enum SidebarButton {}
|
||||
MouseEventHandler::new::<SidebarButton, _>(item.view.id(), cx, |_| {
|
||||
MouseEventHandler::new::<SidebarButton, _, _>(item.view.id(), cx, |_, _| {
|
||||
ConstrainedBox::new(
|
||||
Align::new(
|
||||
ConstrainedBox::new(
|
||||
|
@ -98,7 +99,11 @@ impl Sidebar {
|
|||
.boxed()
|
||||
}
|
||||
|
||||
pub fn render_active_item(&self, settings: &Settings, cx: &AppContext) -> Option<ElementBox> {
|
||||
pub fn render_active_item(
|
||||
&self,
|
||||
settings: &Settings,
|
||||
cx: &mut MutableAppContext,
|
||||
) -> Option<ElementBox> {
|
||||
if let Some(active_item) = self.active_item() {
|
||||
let mut container = Flex::row();
|
||||
if matches!(self.side, Side::Right) {
|
||||
|
@ -118,10 +123,14 @@ impl Sidebar {
|
|||
}
|
||||
}
|
||||
|
||||
fn render_resize_handle(&self, settings: &Settings, cx: &AppContext) -> ElementBox {
|
||||
fn render_resize_handle(
|
||||
&self,
|
||||
settings: &Settings,
|
||||
mut cx: &mut MutableAppContext,
|
||||
) -> ElementBox {
|
||||
let width = self.width.clone();
|
||||
let side = self.side;
|
||||
MouseEventHandler::new::<Self, _>(self.side.id(), cx, |_| {
|
||||
MouseEventHandler::new::<Self, _, _>(self.side.id(), &mut cx, |_, _| {
|
||||
Container::new(Empty::new().boxed())
|
||||
.with_style(&settings.theme.workspace.sidebar.resize_handle)
|
||||
.boxed()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue