Still need to wire up MouseMove with the new regions
This commit is contained in:
parent
3709eff34b
commit
b910c85f7f
7 changed files with 82 additions and 33 deletions
|
@ -1,5 +1,5 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
element::{Element, ElementMetadata},
|
element::{Element, ElementMetadata, ParentElement},
|
||||||
frame,
|
frame,
|
||||||
text::ArcCow,
|
text::ArcCow,
|
||||||
themes::rose_pine,
|
themes::rose_pine,
|
||||||
|
|
|
@ -419,7 +419,7 @@ pub trait Element<V: 'static>: 'static {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hoverable(self) -> Hoverable<V, Self>
|
fn hover(self) -> Hoverable<V, Self>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
|
@ -443,6 +443,18 @@ pub trait Element<V: 'static>: 'static {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait ParentElement<V: 'static>: Element<V> {
|
||||||
|
fn child(self, child: impl IntoElement<V>) -> Self
|
||||||
|
where
|
||||||
|
Self: Sized;
|
||||||
|
|
||||||
|
fn children<I, E>(self, children: I) -> Self
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
I: IntoIterator<Item = E>,
|
||||||
|
E: IntoElement<V>;
|
||||||
|
}
|
||||||
|
|
||||||
// Object-safe counterpart of Element used by AnyElement to store elements as trait objects.
|
// Object-safe counterpart of Element used by AnyElement to store elements as trait objects.
|
||||||
trait ElementObject<V> {
|
trait ElementObject<V> {
|
||||||
fn declared_style(&mut self) -> &mut StyleRefinement;
|
fn declared_style(&mut self) -> &mut StyleRefinement;
|
||||||
|
@ -516,19 +528,6 @@ impl<V: 'static> AnyElement<V> {
|
||||||
Ok(node_id)
|
Ok(node_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push_text_style<'a: 'b, 'b>(&mut self, cx: &mut impl RenderContext<'a, 'b, V>) -> bool {
|
|
||||||
let text_style = self
|
|
||||||
.element
|
|
||||||
.computed_style(cx.as_view_context())
|
|
||||||
.text_style();
|
|
||||||
if let Some(text_style) = text_style {
|
|
||||||
cx.push_text_style(cx.text_style().refined(&text_style));
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn paint(&mut self, view: &mut V, cx: &mut PaintContext<V>) -> Result<()> {
|
pub fn paint(&mut self, view: &mut V, cx: &mut PaintContext<V>) -> Result<()> {
|
||||||
let pushed_text_style = self.push_text_style(cx);
|
let pushed_text_style = self.push_text_style(cx);
|
||||||
|
|
||||||
|
@ -586,6 +585,19 @@ impl<V: 'static> AnyElement<V> {
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn push_text_style<'a: 'b, 'b>(&mut self, cx: &mut impl RenderContext<'a, 'b, V>) -> bool {
|
||||||
|
let text_style = self
|
||||||
|
.element
|
||||||
|
.computed_style(cx.as_view_context())
|
||||||
|
.text_style();
|
||||||
|
if let Some(text_style) = text_style {
|
||||||
|
cx.push_text_style(cx.text_style().refined(&text_style));
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<V: 'static> Element<V> for AnyElement<V> {
|
impl<V: 'static> Element<V> for AnyElement<V> {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
element::{
|
element::{
|
||||||
AnyElement, Element, EventHandler, IntoElement, Layout, LayoutContext, NodeId, PaintContext,
|
AnyElement, Element, EventHandler, IntoElement, Layout, LayoutContext, NodeId,
|
||||||
|
PaintContext, ParentElement,
|
||||||
},
|
},
|
||||||
style::{Style, StyleRefinement},
|
style::{Style, StyleRefinement},
|
||||||
};
|
};
|
||||||
|
@ -65,13 +66,13 @@ impl<V: 'static> Element<V> for Frame<V> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<V: 'static> Frame<V> {
|
impl<V: 'static> ParentElement<V> for Frame<V> {
|
||||||
pub fn child(mut self, child: impl IntoElement<V>) -> Self {
|
fn child(mut self, child: impl IntoElement<V>) -> Self {
|
||||||
self.children.push(child.into_any_element());
|
self.children.push(child.into_any_element());
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn children<I, E>(mut self, children: I) -> Self
|
fn children<I, E>(mut self, children: I) -> Self
|
||||||
where
|
where
|
||||||
I: IntoIterator<Item = E>,
|
I: IntoIterator<Item = E>,
|
||||||
E: IntoElement<V>,
|
E: IntoElement<V>,
|
||||||
|
|
|
@ -7,11 +7,15 @@ use gpui::{
|
||||||
};
|
};
|
||||||
use refineable::Refineable;
|
use refineable::Refineable;
|
||||||
|
|
||||||
use crate::{element::Element, style::StyleRefinement};
|
use crate::{
|
||||||
|
element::{Element, ParentElement},
|
||||||
|
style::StyleRefinement,
|
||||||
|
};
|
||||||
|
|
||||||
pub struct Hoverable<V, E> {
|
pub struct Hoverable<V, E> {
|
||||||
hover_style: StyleRefinement,
|
hover_style: StyleRefinement,
|
||||||
computed_style: Option<StyleRefinement>,
|
computed_style: Option<StyleRefinement>,
|
||||||
|
hovered: Rc<Cell<bool>>,
|
||||||
view_type: PhantomData<V>,
|
view_type: PhantomData<V>,
|
||||||
child: E,
|
child: E,
|
||||||
}
|
}
|
||||||
|
@ -21,6 +25,7 @@ impl<V, E> Hoverable<V, E> {
|
||||||
Self {
|
Self {
|
||||||
hover_style: StyleRefinement::default(),
|
hover_style: StyleRefinement::default(),
|
||||||
computed_style: None,
|
computed_style: None,
|
||||||
|
hovered: Default::default(),
|
||||||
view_type: PhantomData,
|
view_type: PhantomData,
|
||||||
child,
|
child,
|
||||||
}
|
}
|
||||||
|
@ -37,8 +42,9 @@ impl<V: 'static, E: Element<V>> Element<V> for Hoverable<V, E> {
|
||||||
fn computed_style(&mut self, cx: &mut ViewContext<V>) -> &StyleRefinement {
|
fn computed_style(&mut self, cx: &mut ViewContext<V>) -> &StyleRefinement {
|
||||||
self.computed_style.get_or_insert_with(|| {
|
self.computed_style.get_or_insert_with(|| {
|
||||||
let mut style = self.child.computed_style(cx).clone();
|
let mut style = self.child.computed_style(cx).clone();
|
||||||
// if hovered
|
if self.hovered.get() {
|
||||||
style.refine(&self.hover_style);
|
style.refine(&self.hover_style);
|
||||||
|
}
|
||||||
style
|
style
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -63,17 +69,24 @@ impl<V: 'static, E: Element<V>> Element<V> for Hoverable<V, E> {
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
let EngineLayout { bounds, order } = layout.from_engine;
|
let EngineLayout { bounds, order } = layout.from_engine;
|
||||||
let window_bounds = RectF::new(Vector2F::zero(), cx.window_size());
|
let window_bounds = RectF::new(Vector2F::zero(), cx.window_size());
|
||||||
let was_hovered = Rc::new(Cell::new(false));
|
let hovered = self.hovered.clone();
|
||||||
|
|
||||||
self.child.paint(layout, view, cx)?;
|
self.child.paint(layout, view, cx)?;
|
||||||
|
|
||||||
|
let mouse_within_bounds = bounds.contains_point(cx.mouse_position());
|
||||||
|
if mouse_within_bounds != hovered.get() {
|
||||||
|
hovered.set(mouse_within_bounds);
|
||||||
|
cx.repaint();
|
||||||
|
}
|
||||||
|
|
||||||
cx.draw_interactive_region(
|
cx.draw_interactive_region(
|
||||||
order,
|
order,
|
||||||
window_bounds,
|
window_bounds,
|
||||||
false,
|
false,
|
||||||
move |view, event: &MouseMove, cx| {
|
move |view, event: &MouseMove, cx| {
|
||||||
let is_hovered = bounds.contains_point(cx.mouse_position());
|
let mouse_within_bounds = bounds.contains_point(cx.mouse_position());
|
||||||
if is_hovered != was_hovered.get() {
|
if mouse_within_bounds != hovered.get() {
|
||||||
was_hovered.set(is_hovered);
|
hovered.set(mouse_within_bounds);
|
||||||
cx.repaint();
|
cx.repaint();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -81,3 +94,23 @@ impl<V: 'static, E: Element<V>> Element<V> for Hoverable<V, E> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<V: 'static, P: ParentElement<V>> ParentElement<V> for Hoverable<V, P> {
|
||||||
|
fn child(mut self, child: impl crate::element::IntoElement<V>) -> Self
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
self.child = self.child.child(child);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn children<I, E>(mut self, children: I) -> Self
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
I: IntoIterator<Item = E>,
|
||||||
|
E: crate::element::IntoElement<V>,
|
||||||
|
{
|
||||||
|
self.child = self.child.children(children);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#![allow(dead_code, unused_variables)]
|
#![allow(dead_code, unused_variables)]
|
||||||
use color::black;
|
use color::black;
|
||||||
use components::button;
|
use components::button;
|
||||||
use element::Element;
|
use element::{Element, ParentElement};
|
||||||
use frame::frame;
|
use frame::frame;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
geometry::{rect::RectF, vector::vec2f},
|
geometry::{rect::RectF, vector::vec2f},
|
||||||
|
@ -50,6 +50,8 @@ fn playground<V: 'static>(theme: &ThemeColors) -> impl Element<V> {
|
||||||
.h_full()
|
.h_full()
|
||||||
.w_half()
|
.w_half()
|
||||||
.fill(theme.success(0.5))
|
.fill(theme.success(0.5))
|
||||||
|
.hover()
|
||||||
|
.fill(theme.error(0.5))
|
||||||
.child(button().label("Hello").click(|_, _, _| println!("click!")))
|
.child(button().label("Hello").click(|_, _, _| println!("click!")))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1890,6 +1890,7 @@ impl AppContext {
|
||||||
|
|
||||||
fn handle_repaint_window_effect(&mut self, window: AnyWindowHandle) {
|
fn handle_repaint_window_effect(&mut self, window: AnyWindowHandle) {
|
||||||
self.update_window(window, |cx| {
|
self.update_window(window, |cx| {
|
||||||
|
cx.layout(false).log_err();
|
||||||
if let Some(scene) = cx.paint().log_err() {
|
if let Some(scene) = cx.paint().log_err() {
|
||||||
cx.window.platform_window.present_scene(scene);
|
cx.window.platform_window.present_scene(scene);
|
||||||
}
|
}
|
||||||
|
@ -3655,12 +3656,6 @@ impl<'a, 'b, 'c, V: 'static> EventContext<'a, 'b, 'c, V> {
|
||||||
pub fn propagate_event(&mut self) {
|
pub fn propagate_event(&mut self) {
|
||||||
self.handled = false;
|
self.handled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn repaint(&mut self) {
|
|
||||||
let window = self.window();
|
|
||||||
self.pending_effects
|
|
||||||
.push_back(Effect::RepaintWindow { window });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b, 'c, V> Deref for EventContext<'a, 'b, 'c, V> {
|
impl<'a, 'b, 'c, V> Deref for EventContext<'a, 'b, 'c, V> {
|
||||||
|
|
|
@ -220,6 +220,12 @@ impl<'a> WindowContext<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn repaint(&mut self) {
|
||||||
|
let window = self.window();
|
||||||
|
self.pending_effects
|
||||||
|
.push_back(Effect::RepaintWindow { window });
|
||||||
|
}
|
||||||
|
|
||||||
pub fn layout_engine(&mut self) -> Option<&mut LayoutEngine> {
|
pub fn layout_engine(&mut self) -> Option<&mut LayoutEngine> {
|
||||||
self.window.layout_engines.last_mut()
|
self.window.layout_engines.last_mut()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue