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()
|
||||
.gap_1()
|
||||
.id("Random")
|
||||
.grid()
|
||||
.bg(rgb(0x505050))
|
||||
.size(px(500.0))
|
||||
|
@ -37,7 +38,9 @@ impl Render for HolyGrailExample {
|
|||
)
|
||||
.child(
|
||||
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()
|
||||
.child("Table of contents"),
|
||||
)
|
||||
|
@ -49,8 +52,10 @@ impl Render for HolyGrailExample {
|
|||
)
|
||||
.child(
|
||||
block(gpui::blue())
|
||||
.col_span(1)
|
||||
.row_span(3)
|
||||
.id("Ads")
|
||||
.col_span(3)
|
||||
.row_span(1)
|
||||
.container_3xs(|style| style.col_span(1).row_span(3))
|
||||
.child("AD :(")
|
||||
.text_color(gpui::white()),
|
||||
)
|
||||
|
|
|
@ -648,6 +648,61 @@ pub trait InteractiveElement: Sized {
|
|||
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
|
||||
fn group_hover(
|
||||
mut self,
|
||||
|
@ -1464,6 +1519,7 @@ pub struct Interactivity {
|
|||
pub(crate) click_listeners: Vec<ClickListener>,
|
||||
pub(crate) drag_listener: Option<(Arc<dyn Any>, DragListener)>,
|
||||
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) window_control: Option<WindowControlArea>,
|
||||
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);
|
||||
(layout_id, element_state)
|
||||
},
|
||||
|
@ -1738,6 +1809,10 @@ impl Interactivity {
|
|||
let mut element_state =
|
||||
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);
|
||||
|
||||
#[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) scroll_offset: Option<Rc<RefCell<Point<Pixels>>>>,
|
||||
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.
|
||||
|
|
|
@ -271,6 +271,9 @@ pub struct Style {
|
|||
/// The grid location of this element
|
||||
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
|
||||
#[cfg(debug_assertions)]
|
||||
pub debug: bool,
|
||||
|
@ -778,6 +781,7 @@ impl Default for Style {
|
|||
grid_rows: None,
|
||||
grid_cols: None,
|
||||
grid_location: None,
|
||||
container_name: None,
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
debug: false,
|
||||
|
|
|
@ -701,6 +701,13 @@ pub trait Styled: Sized {
|
|||
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.
|
||||
fn row_start(mut self, start: i16) -> Self {
|
||||
let grid_location = self.style().grid_location_mut();
|
||||
|
@ -722,6 +729,13 @@ pub trait Styled: Sized {
|
|||
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"
|
||||
fn row_end_auto(mut self) -> Self {
|
||||
let grid_location = self.style().grid_location_mut();
|
||||
|
@ -743,6 +757,15 @@ pub trait Styled: Sized {
|
|||
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.
|
||||
#[cfg(debug_assertions)]
|
||||
fn debug(mut self) -> Self {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue