Start work to add container queries to gpui
This commit is contained in:
parent
b3969ed427
commit
4ba9259890
4 changed files with 112 additions and 4 deletions
|
@ -21,6 +21,7 @@ impl Render for HolyGrailExample {
|
||||||
|
|
||||||
div()
|
div()
|
||||||
.gap_1()
|
.gap_1()
|
||||||
|
.id("Random")
|
||||||
.grid()
|
.grid()
|
||||||
.bg(rgb(0x505050))
|
.bg(rgb(0x505050))
|
||||||
.size(px(500.0))
|
.size(px(500.0))
|
||||||
|
@ -37,7 +38,9 @@ impl Render for HolyGrailExample {
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
block(gpui::red())
|
block(gpui::red())
|
||||||
.col_span(1)
|
.id("Table of contents")
|
||||||
|
.row_span(1)
|
||||||
|
.container_3xs(|style| style.col_span(1).row_span_auto())
|
||||||
.h_56()
|
.h_56()
|
||||||
.child("Table of contents"),
|
.child("Table of contents"),
|
||||||
)
|
)
|
||||||
|
@ -49,8 +52,10 @@ impl Render for HolyGrailExample {
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
block(gpui::blue())
|
block(gpui::blue())
|
||||||
.col_span(1)
|
.id("Ads")
|
||||||
.row_span(3)
|
.col_span(3)
|
||||||
|
.row_span(1)
|
||||||
|
.container_3xs(|style| style.col_span(1).row_span(3))
|
||||||
.child("AD :(")
|
.child("AD :(")
|
||||||
.text_color(gpui::white()),
|
.text_color(gpui::white()),
|
||||||
)
|
)
|
||||||
|
|
|
@ -648,6 +648,61 @@ pub trait InteractiveElement: Sized {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Apply the given style when container width is is less than or equal to 256.0 Pixels
|
||||||
|
fn container_3xs(mut self, f: impl Fn(StyleRefinement) -> StyleRefinement + 'static) -> Self {
|
||||||
|
self.container_query_with(256.0, f)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Apply the given style when container width is is less than or equal to 288.0 Pixels
|
||||||
|
fn container_2xs(mut self, f: impl Fn(StyleRefinement) -> StyleRefinement + 'static) -> Self {
|
||||||
|
self.container_query_with(288.0, f)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Apply the given style when container width is is less than or equal to 320.0 Pixels
|
||||||
|
fn container_xs(mut self, f: impl Fn(StyleRefinement) -> StyleRefinement + 'static) -> Self {
|
||||||
|
self.container_query_with(320.0, f)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Apply the given style when container width is is less than or equal to 384.0 Pixels
|
||||||
|
fn container_sm(mut self, f: impl Fn(StyleRefinement) -> StyleRefinement + 'static) -> Self {
|
||||||
|
self.container_query_with(384.0, f)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Apply the given style when container width is is less than or equal to 448.0 Pixels
|
||||||
|
fn container_md(mut self, f: impl Fn(StyleRefinement) -> StyleRefinement + 'static) -> Self {
|
||||||
|
self.container_query_with(448.0, f)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Apply the given style when container width is is less than or equal to 512.0 Pixels
|
||||||
|
fn container_lg(mut self, f: impl Fn(StyleRefinement) -> StyleRefinement + 'static) -> Self {
|
||||||
|
self.container_query_with(512.0, f)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Apply the given style when container width is is less than or equal to 576.0 Pixels
|
||||||
|
fn container_xl(mut self, f: impl Fn(StyleRefinement) -> StyleRefinement + 'static) -> Self {
|
||||||
|
self.container_query_with(576.0, f)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Apply the given style when width is less than or equal to the current value
|
||||||
|
fn container_query_with(
|
||||||
|
mut self,
|
||||||
|
width: impl Into<Pixels>,
|
||||||
|
f: impl Fn(StyleRefinement) -> StyleRefinement + 'static,
|
||||||
|
) -> Self {
|
||||||
|
let width = width.into();
|
||||||
|
|
||||||
|
self.interactivity()
|
||||||
|
.container_queries
|
||||||
|
.push(Box::new(move |layout_width, style| {
|
||||||
|
if layout_width >= width {
|
||||||
|
f(style)
|
||||||
|
} else {
|
||||||
|
style
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Apply the given style to this element when the mouse hovers over a group member
|
/// Apply the given style to this element when the mouse hovers over a group member
|
||||||
fn group_hover(
|
fn group_hover(
|
||||||
mut self,
|
mut self,
|
||||||
|
@ -1464,6 +1519,7 @@ pub struct Interactivity {
|
||||||
pub(crate) click_listeners: Vec<ClickListener>,
|
pub(crate) click_listeners: Vec<ClickListener>,
|
||||||
pub(crate) drag_listener: Option<(Arc<dyn Any>, DragListener)>,
|
pub(crate) drag_listener: Option<(Arc<dyn Any>, DragListener)>,
|
||||||
pub(crate) hover_listener: Option<Box<dyn Fn(&bool, &mut Window, &mut App)>>,
|
pub(crate) hover_listener: Option<Box<dyn Fn(&bool, &mut Window, &mut App)>>,
|
||||||
|
pub(crate) container_queries: Vec<Box<dyn Fn(Pixels, StyleRefinement) -> StyleRefinement>>,
|
||||||
pub(crate) tooltip_builder: Option<TooltipBuilder>,
|
pub(crate) tooltip_builder: Option<TooltipBuilder>,
|
||||||
pub(crate) window_control: Option<WindowControlArea>,
|
pub(crate) window_control: Option<WindowControlArea>,
|
||||||
pub(crate) hitbox_behavior: HitboxBehavior,
|
pub(crate) hitbox_behavior: HitboxBehavior,
|
||||||
|
@ -1556,7 +1612,22 @@ impl Interactivity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let style = self.compute_style_internal(None, element_state.as_mut(), window, cx);
|
let mut style =
|
||||||
|
self.compute_style_internal(None, element_state.as_mut(), window, cx);
|
||||||
|
|
||||||
|
let mut style_refinement = StyleRefinement::default();
|
||||||
|
|
||||||
|
if let Some(element_state) = element_state.as_ref()
|
||||||
|
&& let Some(bounds) = element_state.cached_bounds
|
||||||
|
{
|
||||||
|
let current_width = bounds.size.width;
|
||||||
|
|
||||||
|
for query in self.container_queries.iter() {
|
||||||
|
style_refinement = query(current_width, style_refinement);
|
||||||
|
}
|
||||||
|
|
||||||
|
style.refine(&style_refinement);
|
||||||
|
}
|
||||||
let layout_id = f(style, window, cx);
|
let layout_id = f(style, window, cx);
|
||||||
(layout_id, element_state)
|
(layout_id, element_state)
|
||||||
},
|
},
|
||||||
|
@ -1738,6 +1809,10 @@ impl Interactivity {
|
||||||
let mut element_state =
|
let mut element_state =
|
||||||
element_state.map(|element_state| element_state.unwrap_or_default());
|
element_state.map(|element_state| element_state.unwrap_or_default());
|
||||||
|
|
||||||
|
if let Some(element_state) = element_state.as_mut() {
|
||||||
|
element_state.cached_bounds = Some(bounds);
|
||||||
|
}
|
||||||
|
|
||||||
let style = self.compute_style_internal(hitbox, element_state.as_mut(), window, cx);
|
let style = self.compute_style_internal(hitbox, element_state.as_mut(), window, cx);
|
||||||
|
|
||||||
#[cfg(any(feature = "test-support", test))]
|
#[cfg(any(feature = "test-support", test))]
|
||||||
|
@ -2517,6 +2592,7 @@ pub struct InteractiveElementState {
|
||||||
pub(crate) pending_mouse_down: Option<Rc<RefCell<Option<MouseDownEvent>>>>,
|
pub(crate) pending_mouse_down: Option<Rc<RefCell<Option<MouseDownEvent>>>>,
|
||||||
pub(crate) scroll_offset: Option<Rc<RefCell<Point<Pixels>>>>,
|
pub(crate) scroll_offset: Option<Rc<RefCell<Point<Pixels>>>>,
|
||||||
pub(crate) active_tooltip: Option<Rc<RefCell<Option<ActiveTooltip>>>>,
|
pub(crate) active_tooltip: Option<Rc<RefCell<Option<ActiveTooltip>>>>,
|
||||||
|
pub(crate) cached_bounds: Option<Bounds<Pixels>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether or not the element or a group that contains it is clicked by the mouse.
|
/// Whether or not the element or a group that contains it is clicked by the mouse.
|
||||||
|
|
|
@ -271,6 +271,9 @@ pub struct Style {
|
||||||
/// The grid location of this element
|
/// The grid location of this element
|
||||||
pub grid_location: Option<GridLocation>,
|
pub grid_location: Option<GridLocation>,
|
||||||
|
|
||||||
|
/// The container name (used for container queries)
|
||||||
|
pub container_name: Option<SharedString>,
|
||||||
|
|
||||||
/// Whether to draw a red debugging outline around this element
|
/// Whether to draw a red debugging outline around this element
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
pub debug: bool,
|
pub debug: bool,
|
||||||
|
@ -778,6 +781,7 @@ impl Default for Style {
|
||||||
grid_rows: None,
|
grid_rows: None,
|
||||||
grid_cols: None,
|
grid_cols: None,
|
||||||
grid_location: None,
|
grid_location: None,
|
||||||
|
container_name: None,
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
debug: false,
|
debug: false,
|
||||||
|
|
|
@ -701,6 +701,13 @@ pub trait Styled: Sized {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the column span of this element to auto.
|
||||||
|
fn col_span_auto(mut self) -> Self {
|
||||||
|
let grid_location = self.style().grid_location_mut();
|
||||||
|
grid_location.column = GridPlacement::Auto..GridPlacement::Auto;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets the row start of this element.
|
/// Sets the row start of this element.
|
||||||
fn row_start(mut self, start: i16) -> Self {
|
fn row_start(mut self, start: i16) -> Self {
|
||||||
let grid_location = self.style().grid_location_mut();
|
let grid_location = self.style().grid_location_mut();
|
||||||
|
@ -722,6 +729,13 @@ pub trait Styled: Sized {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the row span to auto
|
||||||
|
fn row_span_auto(mut self) -> Self {
|
||||||
|
let grid_location = self.style().grid_location_mut();
|
||||||
|
grid_location.row = GridPlacement::Auto..GridPlacement::Auto;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets the row end of this element to "auto"
|
/// Sets the row end of this element to "auto"
|
||||||
fn row_end_auto(mut self) -> Self {
|
fn row_end_auto(mut self) -> Self {
|
||||||
let grid_location = self.style().grid_location_mut();
|
let grid_location = self.style().grid_location_mut();
|
||||||
|
@ -743,6 +757,15 @@ pub trait Styled: Sized {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the container name of this element.
|
||||||
|
fn container_name(mut self, name: SharedString) -> Self {
|
||||||
|
let container_name = &mut self.style().container_name;
|
||||||
|
if container_name.is_none() {
|
||||||
|
*container_name = Some(name);
|
||||||
|
} // todo! Add a debug assert here so there can only be one container name per element
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Draws a debug border around this element.
|
/// Draws a debug border around this element.
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
fn debug(mut self) -> Self {
|
fn debug(mut self) -> Self {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue