co-authored-by: conrad <conrad@zed.dev>
co-authored-by: Nathan <nathan@zed.dev>
This commit is contained in:
Mikayla
2023-11-20 14:46:01 -08:00
co-authored by conrad Nathan
parent 6985b70859
commit 2c4d83c9af
96 changed files with 1926 additions and 1955 deletions
+16 -10
View File
@@ -1,7 +1,7 @@
use crate::{
point, px, size, AnyElement, AvailableSpace, Bounds, Element, ElementId, InteractiveElement,
InteractiveElementState, Interactivity, LayoutId, Pixels, Point, RenderOnce, Size,
StyleRefinement, Styled, WindowContext,
InteractiveElementState, Interactivity, LayoutId, Pixels, Point, Render, RenderOnce, Size,
StyleRefinement, Styled, View, ViewContext, WindowContext,
};
use smallvec::SmallVec;
use std::{cell::RefCell, cmp, ops::Range, rc::Rc};
@@ -10,30 +10,36 @@ use taffy::style::Overflow;
/// uniform_list provides lazy rendering for a set of items that are of uniform height.
/// When rendered into a container with overflow-y: hidden and a fixed (or max) height,
/// uniform_list will only render the visibile subset of items.
pub fn uniform_list<I, R>(
pub fn uniform_list<I, R, V>(
view: View<V>,
id: I,
item_count: usize,
f: impl 'static + Fn(Range<usize>, &mut WindowContext) -> Vec<R>,
f: impl 'static + Fn(&mut V, Range<usize>, &mut ViewContext<V>) -> Vec<R>,
) -> UniformList
where
I: Into<ElementId>,
R: RenderOnce,
V: Render,
{
let id = id.into();
let mut style = StyleRefinement::default();
style.overflow.y = Some(Overflow::Hidden);
let render_range = move |range, cx: &mut WindowContext| {
view.update(cx, |this, cx| {
f(this, range, cx)
.into_iter()
.map(|component| component.render_into_any())
.collect()
})
};
UniformList {
id: id.clone(),
style,
item_count,
item_to_measure_index: 0,
render_items: Box::new(move |visible_range, cx| {
f(visible_range, cx)
.into_iter()
.map(|component| component.render_into_any())
.collect()
}),
render_items: Box::new(render_range),
interactivity: Interactivity {
element_id: Some(id.into()),
..Default::default()
+5 -3
View File
@@ -1,4 +1,6 @@
use crate::{AsyncWindowContext, Bounds, Pixels, PlatformInputHandler, View, ViewContext};
use crate::{
AsyncWindowContext, Bounds, Pixels, PlatformInputHandler, View, ViewContext, WindowContext,
};
use std::ops::Range;
/// Implement this trait to allow views to handle textual input when implementing an editor, field, etc.
@@ -43,9 +45,9 @@ pub struct ElementInputHandler<V> {
impl<V: 'static> ElementInputHandler<V> {
/// Used in [Element::paint] with the element's bounds and a view context for its
/// containing view.
pub fn new(element_bounds: Bounds<Pixels>, cx: &mut ViewContext<V>) -> Self {
pub fn new(element_bounds: Bounds<Pixels>, view: View<V>, cx: &mut WindowContext) -> Self {
ElementInputHandler {
view: cx.view().clone(),
view,
element_bounds,
cx: cx.to_async(),
}
-44
View File
@@ -309,50 +309,6 @@ where
}
}
// pub struct RenderViewWith<E, V> {
// view: View<V>,
// element: Option<E>,
// }
// impl<E> Element for RenderViewWith<E>
// where
// E: 'static + Element,
// {
// type State = Option<AnyElement>;
// fn layout(
// &mut self,
// _: Option<Self::State>,
// cx: &mut WindowContext,
// ) -> (LayoutId, Self::State) {
// self.view.update(cx, |view, cx| {
// let mut element = self.element.take().unwrap().into_any();
// let layout_id = element.layout(view, cx);
// (layout_id, Some(element))
// })
// }
// fn paint(self, _: Bounds<Pixels>, element: &mut Self::ElementState, cx: &mut WindowContext) {
// element.paint(cx)
// }
// }
// impl<E> RenderOnce for RenderViewWith<E>
// where
// E: 'static + Element<V>,
// ParentV: 'static,
// {
// type Element = Self;
// fn element_id(&self) -> Option<ElementId> {
// self.element.as_ref().unwrap().element_id()
// }
// fn render_once(self) -> Self::Element {
// self
// }
// }
mod any_view {
use crate::{AnyElement, AnyView, BorrowWindow, Element, LayoutId, Render, WindowContext};
+42 -26
View File
@@ -1437,7 +1437,27 @@ impl<'a> WindowContext<'a> {
.bindings_for_action(action)
}
///========== ELEMENT RELATED FUNCTIONS ===========
pub fn listener_for<V: Render, E>(
&self,
view: &View<V>,
f: impl Fn(&mut V, &E, &mut ViewContext<V>) + 'static,
) -> impl Fn(&E, &mut WindowContext) + 'static {
let view = view.downgrade();
move |e: &E, cx: &mut WindowContext| {
view.update(cx, |view, cx| f(view, e, cx)).ok();
}
}
pub fn constructor_for<V: Render, R>(
&self,
view: &View<V>,
f: impl Fn(&mut V, &mut ViewContext<V>) -> R + 'static,
) -> impl Fn(&mut WindowContext) -> R + 'static {
let view = view.clone();
move |cx: &mut WindowContext| view.update(cx, |view, cx| f(view, cx))
}
//========== ELEMENT RELATED FUNCTIONS ===========
pub fn with_key_dispatch<R>(
&mut self,
context: KeyContext,
@@ -1477,6 +1497,21 @@ impl<'a> WindowContext<'a> {
listener(event, cx);
}));
}
/// Set an input handler, such as [ElementInputHandler], which interfaces with the
/// platform to receive textual input with proper integration with concerns such
/// as IME interactions.
pub fn handle_input(
&mut self,
focus_handle: &FocusHandle,
input_handler: impl PlatformInputHandler,
) {
if focus_handle.is_focused(self) {
self.window
.platform_window
.set_input_handler(Box::new(input_handler));
}
}
}
impl Context for WindowContext<'_> {
@@ -1658,6 +1693,10 @@ pub trait BorrowWindow: BorrowMut<Window> + BorrowMut<AppContext> {
self.borrow_mut()
}
fn app(&self) -> &AppContext {
self.borrow()
}
fn window(&self) -> &Window {
self.borrow()
}
@@ -2241,21 +2280,6 @@ impl<'a, V: 'static> ViewContext<'a, V> {
});
}
/// Set an input handler, such as [ElementInputHandler], which interfaces with the
/// platform to receive textual input with proper integration with concerns such
/// as IME interactions.
pub fn handle_input(
&mut self,
focus_handle: &FocusHandle,
input_handler: impl PlatformInputHandler,
) {
if focus_handle.is_focused(self) {
self.window
.platform_window
.set_input_handler(Box::new(input_handler));
}
}
pub fn emit<Evt>(&mut self, event: Evt)
where
Evt: 'static,
@@ -2287,19 +2311,11 @@ impl<'a, V: 'static> ViewContext<'a, V> {
&self,
f: impl Fn(&mut V, &E, &mut ViewContext<V>) + 'static,
) -> impl Fn(&E, &mut WindowContext) + 'static {
let view = self.view().clone();
let view = self.view().downgrade();
move |e: &E, cx: &mut WindowContext| {
view.update(cx, |view, cx| f(view, e, cx));
view.update(cx, |view, cx| f(view, e, cx)).ok();
}
}
pub fn constructor<R>(
&self,
f: impl Fn(&mut V, &mut ViewContext<V>) -> R + 'static,
) -> impl Fn(&mut WindowContext) -> R {
let view = self.view().clone();
move |cx: &mut WindowContext| view.update(cx, |view, cx| f(view, cx))
}
}
impl<V> Context for ViewContext<'_, V> {