From 6b23f7463667d1e95bb60024c2f9543655c26ef2 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Fri, 8 Sep 2023 16:08:31 -0600 Subject: [PATCH 01/10] Checkpoint --- crates/collab_ui/src/collab_panel.rs | 8 +- crates/collab_ui/src/collab_titlebar_item.rs | 9 +- crates/collab_ui/src/face_pile.rs | 10 +- crates/editor/src/element.rs | 365 ++++++++---------- crates/editor/src/hover_popover.rs | 8 +- crates/gpui/examples/corner_radii.rs | 25 +- crates/gpui/examples/text.rs | 6 +- crates/gpui/src/app.rs | 11 + crates/gpui/src/app/window.rs | 13 +- crates/gpui/src/elements.rs | 20 +- crates/gpui/src/elements/align.rs | 5 +- crates/gpui/src/elements/canvas.rs | 9 +- crates/gpui/src/elements/clipped.rs | 14 +- crates/gpui/src/elements/component.rs | 7 +- crates/gpui/src/elements/constrained_box.rs | 11 +- crates/gpui/src/elements/container.rs | 29 +- crates/gpui/src/elements/empty.rs | 3 +- crates/gpui/src/elements/expanded.rs | 7 +- crates/gpui/src/elements/flex.rs | 23 +- crates/gpui/src/elements/hook.rs | 6 +- crates/gpui/src/elements/image.rs | 8 +- crates/gpui/src/elements/keystroke_label.rs | 3 +- crates/gpui/src/elements/label.rs | 11 +- crates/gpui/src/elements/list.rs | 30 +- .../gpui/src/elements/mouse_event_handler.rs | 33 +- crates/gpui/src/elements/overlay.rs | 39 +- crates/gpui/src/elements/resizable.rs | 111 +++--- crates/gpui/src/elements/stack.rs | 9 +- crates/gpui/src/elements/svg.rs | 7 +- crates/gpui/src/elements/text.rs | 20 +- crates/gpui/src/elements/tooltip.rs | 10 +- crates/gpui/src/elements/uniform_list.rs | 11 +- crates/gpui/src/scene.rs | 63 ++- crates/gpui/src/text_layout.rs | 21 +- crates/gpui2/src/adapter.rs | 3 +- crates/gpui2/src/elements/div.rs | 6 +- crates/gpui2/src/elements/img.rs | 2 +- crates/gpui2/src/elements/svg.rs | 2 +- crates/gpui2/src/elements/text.rs | 8 +- crates/gpui2/src/paint_context.rs | 10 +- crates/gpui2/src/style.rs | 4 +- crates/gpui_macros/src/gpui_macros.rs | 3 +- crates/terminal_view/src/terminal_element.rs | 44 +-- crates/workspace/src/pane.rs | 16 +- .../src/pane/dragged_item_receiver.rs | 17 +- crates/workspace/src/pane_group.rs | 17 +- crates/workspace/src/shared_screen.rs | 4 +- crates/workspace/src/status_bar.rs | 11 +- crates/workspace/src/workspace.rs | 4 +- 49 files changed, 489 insertions(+), 627 deletions(-) diff --git a/crates/collab_ui/src/collab_panel.rs b/crates/collab_ui/src/collab_panel.rs index fba10c61bad9b31b145e3b515423891bedae6972..8e0252ec608a6e113db5b39fefb86b99e95ed07c 100644 --- a/crates/collab_ui/src/collab_panel.rs +++ b/crates/collab_ui/src/collab_panel.rs @@ -2434,14 +2434,14 @@ fn render_tree_branch( let cap_height = row_style.cap_height(font_cache); let baseline_offset = row_style.baseline_offset(font_cache) + (size.y() - line_height) / 2.; - Canvas::new(move |scene, bounds, _, _, _| { - scene.paint_layer(None, |scene| { + Canvas::new(move |bounds, _, _, cx| { + cx.paint_layer(None, |cx| { let start_x = bounds.min_x() + (bounds.width() / 2.) - (branch_style.width / 2.); let end_x = bounds.max_x(); let start_y = bounds.min_y(); let end_y = bounds.min_y() + baseline_offset - (cap_height / 2.); - scene.push_quad(gpui::Quad { + cx.scene().push_quad(gpui::Quad { bounds: RectF::from_points( vec2f(start_x, start_y), vec2f( @@ -2453,7 +2453,7 @@ fn render_tree_branch( border: gpui::Border::default(), corner_radii: (0.).into(), }); - scene.push_quad(gpui::Quad { + cx.scene().push_quad(gpui::Quad { bounds: RectF::from_points( vec2f(start_x, end_y), vec2f(end_x, end_y + branch_style.width), diff --git a/crates/collab_ui/src/collab_titlebar_item.rs b/crates/collab_ui/src/collab_titlebar_item.rs index 6c34b7021ee37b51843015642f6f5f05166868ed..8f3a434a830a3adc254302ae38e60357c8d3d4a1 100644 --- a/crates/collab_ui/src/collab_titlebar_item.rs +++ b/crates/collab_ui/src/collab_titlebar_item.rs @@ -13,8 +13,8 @@ use gpui::{ geometry::{rect::RectF, vector::vec2f, PathBuilder}, json::{self, ToJson}, platform::{CursorStyle, MouseButton}, - AppContext, Entity, ImageData, LayoutContext, ModelHandle, PaintContext, SceneBuilder, - Subscription, View, ViewContext, ViewHandle, WeakViewHandle, + AppContext, Entity, ImageData, LayoutContext, ModelHandle, PaintContext, Subscription, View, + ViewContext, ViewHandle, WeakViewHandle, }; use picker::PickerEvent; use project::{Project, RepositoryEntry}; @@ -1172,12 +1172,11 @@ impl Element for AvatarRibbon { fn paint( &mut self, - scene: &mut SceneBuilder, bounds: RectF, _: RectF, _: &mut Self::LayoutState, _: &mut CollabTitlebarItem, - _: &mut PaintContext, + cx: &mut PaintContext, ) -> Self::PaintState { let mut path = PathBuilder::new(); path.reset(bounds.lower_left()); @@ -1188,7 +1187,7 @@ impl Element for AvatarRibbon { path.line_to(bounds.upper_right() - vec2f(bounds.height(), 0.)); path.curve_to(bounds.lower_right(), bounds.upper_right()); path.line_to(bounds.lower_left()); - scene.push_path(path.build(self.color, None)); + cx.scene().push_path(path.build(self.color, None)); } fn rect_for_text_range( diff --git a/crates/collab_ui/src/face_pile.rs b/crates/collab_ui/src/face_pile.rs index a86b2576869b5d2e3b695ae41d073bf6fa631812..835d730d95ab7471714e04b3ab5ca58d2a5b6800 100644 --- a/crates/collab_ui/src/face_pile.rs +++ b/crates/collab_ui/src/face_pile.rs @@ -7,7 +7,7 @@ use gpui::{ }, json::ToJson, serde_json::{self, json}, - AnyElement, Axis, Element, LayoutContext, PaintContext, SceneBuilder, View, ViewContext, + AnyElement, Axis, Element, LayoutContext, PaintContext, View, ViewContext, }; pub(crate) struct FacePile { @@ -53,7 +53,6 @@ impl Element for FacePile { fn paint( &mut self, - scene: &mut SceneBuilder, bounds: RectF, visible_bounds: RectF, _layout: &mut Self::LayoutState, @@ -69,9 +68,10 @@ impl Element for FacePile { let size = face.size(); origin_x -= size.x(); let origin_y = origin_y + (bounds.height() - size.y()) / 2.0; - scene.paint_layer(None, |scene| { - face.paint(scene, vec2f(origin_x, origin_y), visible_bounds, view, cx); - }); + + cx.scene().push_layer(None); + face.paint(vec2f(origin_x, origin_y), visible_bounds, view, cx); + cx.scene().pop_layer(); origin_x += self.overlap; } diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 2d157761bfacee8ea1e94ded56b4009d1323fc50..942b4550bcd52417bb431fd1bb62e1628446f258 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -33,7 +33,7 @@ use gpui::{ platform::{CursorStyle, Modifiers, MouseButton, MouseButtonEvent, MouseMovedEvent}, text_layout::{self, Line, RunStyle, TextLayoutCache}, AnyElement, Axis, CursorRegion, Element, EventContext, FontCache, LayoutContext, MouseRegion, - PaintContext, Quad, SceneBuilder, SizeConstraint, ViewContext, WindowContext, + PaintContext, Quad, SizeConstraint, ViewContext, WindowContext, }; use itertools::Itertools; use json::json; @@ -131,7 +131,6 @@ impl EditorElement { } fn attach_mouse_handlers( - scene: &mut SceneBuilder, position_map: &Arc, has_popovers: bool, visible_bounds: RectF, @@ -141,124 +140,124 @@ impl EditorElement { cx: &mut ViewContext, ) { enum EditorElementMouseHandlers {} - scene.push_mouse_region( - MouseRegion::new::( - cx.view_id(), - cx.view_id(), - visible_bounds, - ) - .on_down(MouseButton::Left, { - let position_map = position_map.clone(); - move |event, editor, cx| { - if !Self::mouse_down( - editor, - event.platform_event, - position_map.as_ref(), - text_bounds, - gutter_bounds, - cx, - ) { - cx.propagate_event(); - } - } - }) - .on_down(MouseButton::Right, { - let position_map = position_map.clone(); - move |event, editor, cx| { - if !Self::mouse_right_down( - editor, - event.position, - position_map.as_ref(), - text_bounds, - cx, - ) { - cx.propagate_event(); + let view_id = cx.view_id(); + cx.scene().push_mouse_region( + MouseRegion::new::(view_id, view_id, visible_bounds) + .on_down(MouseButton::Left, { + let position_map = position_map.clone(); + move |event, editor, cx| { + if !Self::mouse_down( + editor, + event.platform_event, + position_map.as_ref(), + text_bounds, + gutter_bounds, + cx, + ) { + cx.propagate_event(); + } } - } - }) - .on_up(MouseButton::Left, { - let position_map = position_map.clone(); - move |event, editor, cx| { - if !Self::mouse_up( - editor, - event.position, - event.cmd, - event.shift, - event.alt, - position_map.as_ref(), - text_bounds, - cx, - ) { - cx.propagate_event() + }) + .on_down(MouseButton::Right, { + let position_map = position_map.clone(); + move |event, editor, cx| { + if !Self::mouse_right_down( + editor, + event.position, + position_map.as_ref(), + text_bounds, + cx, + ) { + cx.propagate_event(); + } } - } - }) - .on_drag(MouseButton::Left, { - let position_map = position_map.clone(); - move |event, editor, cx| { - if event.end { - return; + }) + .on_up(MouseButton::Left, { + let position_map = position_map.clone(); + move |event, editor, cx| { + if !Self::mouse_up( + editor, + event.position, + event.cmd, + event.shift, + event.alt, + position_map.as_ref(), + text_bounds, + cx, + ) { + cx.propagate_event() + } } + }) + .on_drag(MouseButton::Left, { + let position_map = position_map.clone(); + move |event, editor, cx| { + if event.end { + return; + } - if !Self::mouse_dragged( - editor, - event.platform_event, - position_map.as_ref(), - text_bounds, - cx, - ) { - cx.propagate_event() + if !Self::mouse_dragged( + editor, + event.platform_event, + position_map.as_ref(), + text_bounds, + cx, + ) { + cx.propagate_event() + } } - } - }) - .on_move({ - let position_map = position_map.clone(); - move |event, editor, cx| { - if !Self::mouse_moved( - editor, - event.platform_event, - &position_map, - text_bounds, - cx, - ) { - cx.propagate_event() + }) + .on_move({ + let position_map = position_map.clone(); + move |event, editor, cx| { + if !Self::mouse_moved( + editor, + event.platform_event, + &position_map, + text_bounds, + cx, + ) { + cx.propagate_event() + } } - } - }) - .on_move_out(move |_, editor: &mut Editor, cx| { - if has_popovers { - hide_hover(editor, cx); - } - }) - .on_scroll({ - let position_map = position_map.clone(); - move |event, editor, cx| { - if !Self::scroll( - editor, - event.position, - *event.delta.raw(), - event.delta.precise(), - &position_map, - bounds, - cx, - ) { - cx.propagate_event() + }) + .on_move_out(move |_, editor: &mut Editor, cx| { + if has_popovers { + hide_hover(editor, cx); } - } - }), + }) + .on_scroll({ + let position_map = position_map.clone(); + move |event, editor, cx| { + if !Self::scroll( + editor, + event.position, + *event.delta.raw(), + event.delta.precise(), + &position_map, + bounds, + cx, + ) { + cx.propagate_event() + } + } + }), ); enum GutterHandlers {} - scene.push_mouse_region( - MouseRegion::new::(cx.view_id(), cx.view_id() + 1, gutter_bounds) - .on_hover(|hover, editor: &mut Editor, cx| { + let view_id = cx.view_id(); + let region_id = cx.view_id() + 1; + cx.scene().push_mouse_region( + MouseRegion::new::(view_id, region_id, gutter_bounds).on_hover( + |hover, editor: &mut Editor, cx| { editor.gutter_hover( &GutterHover { hovered: hover.started, }, cx, ); - }), + }, + ), ) } @@ -528,21 +527,21 @@ impl EditorElement { fn paint_background( &self, - scene: &mut SceneBuilder, gutter_bounds: RectF, text_bounds: RectF, layout: &LayoutState, + cx: &mut ViewContext, ) { let bounds = gutter_bounds.union_rect(text_bounds); let scroll_top = layout.position_map.snapshot.scroll_position().y() * layout.position_map.line_height; - scene.push_quad(Quad { + cx.scene().push_quad(Quad { bounds: gutter_bounds, background: Some(self.style.gutter_background), border: Border::new(0., Color::transparent_black()).into(), corner_radii: Default::default(), }); - scene.push_quad(Quad { + cx.scene().push_quad(Quad { bounds: text_bounds, background: Some(self.style.background), border: Border::new(0., Color::transparent_black()).into(), @@ -570,7 +569,7 @@ impl EditorElement { bounds.width(), layout.position_map.line_height * (end_row - start_row + 1) as f32, ); - scene.push_quad(Quad { + cx.scene().push_quad(Quad { bounds: RectF::new(origin, size), background: Some(self.style.active_line_background), border: Border::default().into(), @@ -590,7 +589,7 @@ impl EditorElement { bounds.width(), layout.position_map.line_height * highlighted_rows.len() as f32, ); - scene.push_quad(Quad { + cx.scene().push_quad(Quad { bounds: RectF::new(origin, size), background: Some(self.style.highlighted_line_background), border: Border::default().into(), @@ -617,7 +616,7 @@ impl EditorElement { } else { self.style.wrap_guide }; - scene.push_quad(Quad { + cx.scene().push_quad(Quad { bounds: RectF::new( vec2f(x, text_bounds.origin_y()), vec2f(1., text_bounds.height()), @@ -632,7 +631,6 @@ impl EditorElement { fn paint_gutter( &mut self, - scene: &mut SceneBuilder, bounds: RectF, visible_bounds: RectF, layout: &mut LayoutState, @@ -650,7 +648,7 @@ impl EditorElement { ); if show_gutter { - Self::paint_diff_hunks(scene, bounds, layout, cx); + Self::paint_diff_hunks(bounds, layout, cx); } for (ix, line) in layout.line_number_layouts.iter().enumerate() { @@ -661,7 +659,7 @@ impl EditorElement { ix as f32 * line_height - (scroll_top % line_height), ); - line.paint(scene, line_origin, visible_bounds, line_height, cx); + line.paint(line_origin, visible_bounds, line_height, cx); } } @@ -678,7 +676,7 @@ impl EditorElement { let indicator_origin = bounds.origin() + position + centering_offset; - indicator.paint(scene, indicator_origin, visible_bounds, editor, cx); + indicator.paint(indicator_origin, visible_bounds, editor, cx); } } @@ -687,22 +685,11 @@ impl EditorElement { let mut y = *row as f32 * line_height - scroll_top; x += ((layout.gutter_padding + layout.gutter_margin) - indicator.size().x()) / 2.; y += (line_height - indicator.size().y()) / 2.; - indicator.paint( - scene, - bounds.origin() + vec2f(x, y), - visible_bounds, - editor, - cx, - ); + indicator.paint(bounds.origin() + vec2f(x, y), visible_bounds, editor, cx); } } - fn paint_diff_hunks( - scene: &mut SceneBuilder, - bounds: RectF, - layout: &mut LayoutState, - cx: &mut ViewContext, - ) { + fn paint_diff_hunks(bounds: RectF, layout: &mut LayoutState, cx: &mut ViewContext) { let diff_style = &theme::current(cx).editor.diff.clone(); let line_height = layout.position_map.line_height; @@ -721,7 +708,7 @@ impl EditorElement { let highlight_size = vec2f(width * 2., end_y - start_y); let highlight_bounds = RectF::new(highlight_origin, highlight_size); - scene.push_quad(Quad { + cx.scene().push_quad(Quad { bounds: highlight_bounds, background: Some(diff_style.modified), border: Border::new(0., Color::transparent_black()).into(), @@ -754,7 +741,7 @@ impl EditorElement { let highlight_size = vec2f(width * 2., end_y - start_y); let highlight_bounds = RectF::new(highlight_origin, highlight_size); - scene.push_quad(Quad { + cx.scene().push_quad(Quad { bounds: highlight_bounds, background: Some(diff_style.deleted), border: Border::new(0., Color::transparent_black()).into(), @@ -776,7 +763,7 @@ impl EditorElement { let highlight_size = vec2f(width * 2., end_y - start_y); let highlight_bounds = RectF::new(highlight_origin, highlight_size); - scene.push_quad(Quad { + cx.scene().push_quad(Quad { bounds: highlight_bounds, background: Some(color), border: Border::new(0., Color::transparent_black()).into(), @@ -787,7 +774,6 @@ impl EditorElement { fn paint_text( &mut self, - scene: &mut SceneBuilder, bounds: RectF, visible_bounds: RectF, layout: &mut LayoutState, @@ -804,9 +790,9 @@ impl EditorElement { let line_end_overshoot = 0.15 * layout.position_map.line_height; let whitespace_setting = editor.buffer.read(cx).settings_at(0, cx).show_whitespaces; - scene.push_layer(Some(bounds)); + cx.scene().push_layer(Some(bounds)); - scene.push_cursor_region(CursorRegion { + cx.scene().push_cursor_region(CursorRegion { bounds, style: if !editor.link_go_to_definition_state.definitions.is_empty() { CursorStyle::PointingHand @@ -819,7 +805,6 @@ impl EditorElement { self.style.folds.ellipses.corner_radius_factor * layout.position_map.line_height; for (id, range, color) in layout.fold_ranges.iter() { self.paint_highlighted_range( - scene, range.clone(), *color, fold_corner_radius, @@ -829,6 +814,7 @@ impl EditorElement { scroll_top, scroll_left, bounds, + cx, ); for bound in range_to_bounds( @@ -840,7 +826,7 @@ impl EditorElement { line_end_overshoot, &layout.position_map, ) { - scene.push_cursor_region(CursorRegion { + cx.scene().push_cursor_region(CursorRegion { bounds: bound, style: CursorStyle::PointingHand, }); @@ -851,8 +837,9 @@ impl EditorElement { .to_point(&layout.position_map.snapshot.display_snapshot) .row; - scene.push_mouse_region( - MouseRegion::new::(cx.view_id(), *id as usize, bound) + let view_id = cx.view_id(); + cx.scene().push_mouse_region( + MouseRegion::new::(view_id, *id as usize, bound) .on_click(MouseButton::Left, move |_, editor: &mut Editor, cx| { editor.unfold_at(&UnfoldAt { buffer_row }, cx) }) @@ -864,7 +851,6 @@ impl EditorElement { for (range, color) in &layout.highlighted_ranges { self.paint_highlighted_range( - scene, range.clone(), *color, 0., @@ -874,6 +860,7 @@ impl EditorElement { scroll_top, scroll_left, bounds, + cx, ); } @@ -891,7 +878,6 @@ impl EditorElement { for selection in selections { self.paint_highlighted_range( - scene, selection.range.clone(), selection_style.selection, corner_radius, @@ -901,6 +887,7 @@ impl EditorElement { scroll_top, scroll_left, bounds, + cx, ); if selection.is_local && !selection.range.is_empty() { @@ -980,7 +967,6 @@ impl EditorElement { layout, row, scroll_top, - scene, content_origin, scroll_left, visible_text_bounds, @@ -992,14 +978,14 @@ impl EditorElement { } } - scene.paint_layer(Some(bounds), |scene| { - for cursor in cursors { - cursor.paint(scene, content_origin, cx); - } - }); + cx.scene().push_layer(Some(bounds)); + for cursor in cursors { + cursor.paint(content_origin, cx); + } + cx.scene().pop_layer(); if let Some((position, context_menu)) = layout.context_menu.as_mut() { - scene.push_stacking_context(None, None); + cx.scene().push_stacking_context(None, None); let cursor_row_layout = &layout.position_map.line_layouts[(position.row() - start_row) as usize].line; let x = cursor_row_layout.x_for_index(position.column() as usize) - scroll_left; @@ -1019,18 +1005,17 @@ impl EditorElement { } context_menu.paint( - scene, list_origin, RectF::from_points(Vector2F::zero(), vec2f(f32::MAX, f32::MAX)), // Let content bleed outside of editor editor, cx, ); - scene.pop_stacking_context(); + cx.scene().pop_stacking_context(); } if let Some((position, hover_popovers)) = layout.hover_popovers.as_mut() { - scene.push_stacking_context(None, None); + cx.scene().push_stacking_context(None, None); // This is safe because we check on layout whether the required row is available let hovered_row_layout = @@ -1061,7 +1046,6 @@ impl EditorElement { } hover_popover.paint( - scene, popover_origin, RectF::from_points(Vector2F::zero(), vec2f(f32::MAX, f32::MAX)), // Let content bleed outside of editor editor, @@ -1083,7 +1067,6 @@ impl EditorElement { } hover_popover.paint( - scene, popover_origin, RectF::from_points(Vector2F::zero(), vec2f(f32::MAX, f32::MAX)), // Let content bleed outside of editor editor, @@ -1094,10 +1077,10 @@ impl EditorElement { } } - scene.pop_stacking_context(); + cx.scene().pop_stacking_context(); } - scene.pop_layer(); + cx.scene().pop_layer(); } fn scrollbar_left(&self, bounds: &RectF) -> f32 { @@ -1106,11 +1089,10 @@ impl EditorElement { fn paint_scrollbar( &mut self, - scene: &mut SceneBuilder, bounds: RectF, layout: &mut LayoutState, - cx: &mut ViewContext, editor: &Editor, + cx: &mut ViewContext, ) { enum ScrollbarMouseHandlers {} if layout.mode != EditorMode::Full { @@ -1147,7 +1129,7 @@ impl EditorElement { let thumb_bounds = RectF::from_points(vec2f(left, thumb_top), vec2f(right, thumb_bottom)); if layout.show_scrollbars { - scene.push_quad(Quad { + cx.scene().push_quad(Quad { bounds: track_bounds, border: style.track.border.into(), background: style.track.background_color, @@ -1177,7 +1159,7 @@ impl EditorElement { } let bounds = RectF::from_points(vec2f(left, start_y), vec2f(right, end_y)); - scene.push_quad(Quad { + cx.scene().push_quad(Quad { bounds, background: Some(color), border: border.into(), @@ -1237,7 +1219,7 @@ impl EditorElement { left: true, }; - scene.push_quad(Quad { + cx.scene().push_quad(Quad { bounds, background: Some(color), border: border.into(), @@ -1246,7 +1228,7 @@ impl EditorElement { } } - scene.push_quad(Quad { + cx.scene().push_quad(Quad { bounds: thumb_bounds, border: style.thumb.border.into(), background: style.thumb.background_color, @@ -1254,12 +1236,13 @@ impl EditorElement { }); } - scene.push_cursor_region(CursorRegion { + cx.scene().push_cursor_region(CursorRegion { bounds: track_bounds, style: CursorStyle::Arrow, }); - scene.push_mouse_region( - MouseRegion::new::(cx.view_id(), cx.view_id(), track_bounds) + let region_id = cx.view_id(); + cx.scene().push_mouse_region( + MouseRegion::new::(region_id, region_id, track_bounds) .on_move(move |event, editor: &mut Editor, cx| { if event.pressed_button.is_none() { editor.scroll_manager.show_scrollbar(cx); @@ -1305,7 +1288,6 @@ impl EditorElement { #[allow(clippy::too_many_arguments)] fn paint_highlighted_range( &self, - scene: &mut SceneBuilder, range: Range, color: Color, corner_radius: f32, @@ -1315,6 +1297,7 @@ impl EditorElement { scroll_top: f32, scroll_left: f32, bounds: RectF, + cx: &mut ViewContext, ) { let start_row = layout.visible_display_row_range.start; let end_row = layout.visible_display_row_range.end; @@ -1358,13 +1341,12 @@ impl EditorElement { .collect(), }; - highlighted_range.paint(bounds, scene); + highlighted_range.paint(bounds, cx); } } fn paint_blocks( &mut self, - scene: &mut SceneBuilder, bounds: RectF, visible_bounds: RectF, layout: &mut LayoutState, @@ -1384,9 +1366,7 @@ impl EditorElement { if !matches!(block.style, BlockStyle::Sticky) { origin += vec2f(-scroll_left, 0.); } - block - .element - .paint(scene, origin, visible_bounds, editor, cx); + block.element.paint(origin, visible_bounds, editor, cx); } } @@ -2022,7 +2002,6 @@ impl LineWithInvisibles { layout: &LayoutState, row: u32, scroll_top: f32, - scene: &mut SceneBuilder, content_origin: Vector2F, scroll_left: f32, visible_text_bounds: RectF, @@ -2035,7 +2014,6 @@ impl LineWithInvisibles { let line_y = row as f32 * line_height - scroll_top; self.line.paint( - scene, content_origin + vec2f(-scroll_left, line_y), visible_text_bounds, line_height, @@ -2049,7 +2027,6 @@ impl LineWithInvisibles { scroll_left, line_y, row, - scene, visible_bounds, line_height, whitespace_setting, @@ -2065,7 +2042,6 @@ impl LineWithInvisibles { scroll_left: f32, line_y: f32, row: u32, - scene: &mut SceneBuilder, visible_bounds: RectF, line_height: f32, whitespace_setting: ShowWhitespaceSetting, @@ -2097,7 +2073,7 @@ impl LineWithInvisibles { continue; } } - invisible_symbol.paint(scene, origin, visible_bounds, line_height, cx); + invisible_symbol.paint(origin, visible_bounds, line_height, cx); } } } @@ -2590,7 +2566,6 @@ impl Element for EditorElement { fn paint( &mut self, - scene: &mut SceneBuilder, bounds: RectF, visible_bounds: RectF, layout: &mut Self::LayoutState, @@ -2598,7 +2573,7 @@ impl Element for EditorElement { cx: &mut PaintContext, ) -> Self::PaintState { let visible_bounds = bounds.intersection(visible_bounds).unwrap_or_default(); - scene.push_layer(Some(visible_bounds)); + cx.scene().push_layer(Some(visible_bounds)); let gutter_bounds = RectF::new(bounds.origin(), layout.gutter_size); let text_bounds = RectF::new( @@ -2607,7 +2582,6 @@ impl Element for EditorElement { ); Self::attach_mouse_handlers( - scene, &layout.position_map, layout.hover_popovers.is_some(), visible_bounds, @@ -2617,20 +2591,19 @@ impl Element for EditorElement { cx, ); - self.paint_background(scene, gutter_bounds, text_bounds, layout); + self.paint_background(gutter_bounds, text_bounds, layout, cx); if layout.gutter_size.x() > 0. { - self.paint_gutter(scene, gutter_bounds, visible_bounds, layout, editor, cx); + self.paint_gutter(gutter_bounds, visible_bounds, layout, editor, cx); } - self.paint_text(scene, text_bounds, visible_bounds, layout, editor, cx); + self.paint_text(text_bounds, visible_bounds, layout, editor, cx); - scene.push_layer(Some(bounds)); + cx.scene().push_layer(Some(bounds)); if !layout.blocks.is_empty() { - self.paint_blocks(scene, bounds, visible_bounds, layout, editor, cx); + self.paint_blocks(bounds, visible_bounds, layout, editor, cx); } - self.paint_scrollbar(scene, bounds, layout, cx, &editor); - scene.pop_layer(); - - scene.pop_layer(); + self.paint_scrollbar(bounds, layout, &editor, cx); + cx.scene().pop_layer(); + cx.scene().pop_layer(); } fn rect_for_text_range( @@ -2873,7 +2846,7 @@ impl Cursor { ) } - pub fn paint(&self, scene: &mut SceneBuilder, origin: Vector2F, cx: &mut WindowContext) { + pub fn paint(&self, origin: Vector2F, cx: &mut WindowContext) { let bounds = match self.shape { CursorShape::Bar => RectF::new(self.origin + origin, vec2f(2.0, self.line_height)), CursorShape::Block | CursorShape::Hollow => RectF::new( @@ -2888,14 +2861,14 @@ impl Cursor { //Draw background or border quad if matches!(self.shape, CursorShape::Hollow) { - scene.push_quad(Quad { + cx.scene().push_quad(Quad { bounds, background: None, border: Border::all(1., self.color).into(), corner_radii: Default::default(), }); } else { - scene.push_quad(Quad { + cx.scene().push_quad(Quad { bounds, background: Some(self.color), border: Default::default(), @@ -2904,7 +2877,7 @@ impl Cursor { } if let Some(block_text) = &self.block_text { - block_text.paint(scene, self.origin + origin, bounds, self.line_height, cx); + block_text.paint(self.origin + origin, bounds, self.line_height, cx); } } @@ -2929,17 +2902,17 @@ pub struct HighlightedRangeLine { } impl HighlightedRange { - pub fn paint(&self, bounds: RectF, scene: &mut SceneBuilder) { + pub fn paint(&self, bounds: RectF, cx: &mut WindowContext) { if self.lines.len() >= 2 && self.lines[0].start_x > self.lines[1].end_x { - self.paint_lines(self.start_y, &self.lines[0..1], bounds, scene); + self.paint_lines(self.start_y, &self.lines[0..1], bounds, cx); self.paint_lines( self.start_y + self.line_height, &self.lines[1..], bounds, - scene, + cx, ); } else { - self.paint_lines(self.start_y, &self.lines, bounds, scene); + self.paint_lines(self.start_y, &self.lines, bounds, cx); } } @@ -2948,7 +2921,7 @@ impl HighlightedRange { start_y: f32, lines: &[HighlightedRangeLine], bounds: RectF, - scene: &mut SceneBuilder, + cx: &mut WindowContext, ) { if lines.is_empty() { return; @@ -3046,7 +3019,7 @@ impl HighlightedRange { } path.line_to(first_top_right - top_curve_width); - scene.push_path(path.build(self.color, Some(bounds))); + cx.scene().push_path(path.build(self.color, Some(bounds))); } } @@ -3368,11 +3341,9 @@ mod tests { ); // Don't panic. - let mut scene = SceneBuilder::new(1.0); let bounds = RectF::new(Default::default(), size); editor.update(cx, |editor, cx| { element.paint( - &mut scene, bounds, bounds, &mut state, diff --git a/crates/editor/src/hover_popover.rs b/crates/editor/src/hover_popover.rs index 2f278ce262f6dd3e0910b022e6956f26c9bdfa6b..3d5b1d21134c90554cbb273f7d058e3db621ad07 100644 --- a/crates/editor/src/hover_popover.rs +++ b/crates/editor/src/hover_popover.rs @@ -691,15 +691,15 @@ impl InfoPopover { .with_highlights(rendered_content.highlights.clone()) .with_custom_runs( rendered_content.region_ranges.clone(), - move |ix, bounds, scene, _| { + move |ix, bounds, cx| { region_id += 1; let region = regions[ix].clone(); if let Some(url) = region.link_url { - scene.push_cursor_region(CursorRegion { + cx.scene().push_cursor_region(CursorRegion { bounds, style: CursorStyle::PointingHand, }); - scene.push_mouse_region( + cx.scene().push_mouse_region( MouseRegion::new::(view_id, region_id, bounds) .on_click::( MouseButton::Left, @@ -708,7 +708,7 @@ impl InfoPopover { ); } if region.code { - scene.push_quad(gpui::Quad { + cx.scene().push_quad(gpui::Quad { bounds, background: Some(code_span_background_color), border: Default::default(), diff --git a/crates/gpui/examples/corner_radii.rs b/crates/gpui/examples/corner_radii.rs index 1f33917529e55545a2d290699b255b1587cf32c5..8e5393e31a1428e0cc79d27f1f9e21d4cf0307c6 100644 --- a/crates/gpui/examples/corner_radii.rs +++ b/crates/gpui/examples/corner_radii.rs @@ -49,22 +49,21 @@ impl gpui::Element for CornersElement { fn paint( &mut self, - scene: &mut gpui::SceneBuilder, bounds: pathfinder_geometry::rect::RectF, _: pathfinder_geometry::rect::RectF, _: &mut Self::LayoutState, _: &mut V, - _: &mut gpui::PaintContext, + cx: &mut gpui::PaintContext, ) -> Self::PaintState { - scene.push_quad(Quad { + cx.scene().push_quad(Quad { bounds, background: Some(Color::white()), ..Default::default() }); - scene.push_layer(None); + cx.scene().push_layer(None); - scene.push_quad(Quad { + cx.scene().push_quad(Quad { bounds: RectF::new(vec2f(100., 100.), vec2f(100., 100.)), background: Some(Color::red()), border: Default::default(), @@ -74,7 +73,7 @@ impl gpui::Element for CornersElement { }, }); - scene.push_quad(Quad { + cx.scene().push_quad(Quad { bounds: RectF::new(vec2f(200., 100.), vec2f(100., 100.)), background: Some(Color::green()), border: Default::default(), @@ -84,7 +83,7 @@ impl gpui::Element for CornersElement { }, }); - scene.push_quad(Quad { + cx.scene().push_quad(Quad { bounds: RectF::new(vec2f(100., 200.), vec2f(100., 100.)), background: Some(Color::blue()), border: Default::default(), @@ -94,7 +93,7 @@ impl gpui::Element for CornersElement { }, }); - scene.push_quad(Quad { + cx.scene().push_quad(Quad { bounds: RectF::new(vec2f(200., 200.), vec2f(100., 100.)), background: Some(Color::yellow()), border: Default::default(), @@ -104,7 +103,7 @@ impl gpui::Element for CornersElement { }, }); - scene.push_shadow(Shadow { + cx.scene().push_shadow(Shadow { bounds: RectF::new(vec2f(400., 100.), vec2f(100., 100.)), corner_radii: gpui::scene::CornerRadii { bottom_right: 20., @@ -114,8 +113,8 @@ impl gpui::Element for CornersElement { color: Color::black(), }); - scene.push_layer(None); - scene.push_quad(Quad { + cx.scene().push_layer(None); + cx.scene().push_quad(Quad { bounds: RectF::new(vec2f(400., 100.), vec2f(100., 100.)), background: Some(Color::red()), border: Default::default(), @@ -125,8 +124,8 @@ impl gpui::Element for CornersElement { }, }); - scene.pop_layer(); - scene.pop_layer(); + cx.scene().pop_layer(); + cx.scene().pop_layer(); } fn rect_for_text_range( diff --git a/crates/gpui/examples/text.rs b/crates/gpui/examples/text.rs index bda70a49dc00954c5872d580c4dbadb58ce86e42..bc62d75ec26e4a4f8a1b6a95fa60dddf28298dd8 100644 --- a/crates/gpui/examples/text.rs +++ b/crates/gpui/examples/text.rs @@ -62,12 +62,12 @@ impl gpui::View for TextView { }, ) .with_highlights(vec![(17..26, underline), (34..40, underline)]) - .with_custom_runs(vec![(17..26), (34..40)], move |ix, bounds, scene, _| { - scene.push_cursor_region(CursorRegion { + .with_custom_runs(vec![(17..26), (34..40)], move |ix, bounds, cx| { + cx.scene().push_cursor_region(CursorRegion { bounds, style: CursorStyle::PointingHand, }); - scene.push_mouse_region( + cx.scene().push_mouse_region( MouseRegion::new::(view_id, ix, bounds).on_click::( MouseButton::Left, move |_, _, _| { diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 34af24030768df600a735ac9fdb02dcb6d7cb14c..7f2af36a90f1872f7b4b3017984663160cf7185e 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -28,6 +28,7 @@ use collections::{hash_map::Entry, BTreeMap, HashMap, HashSet, VecDeque}; use derive_more::Deref; pub use menu::*; use parking_lot::Mutex; +use pathfinder_geometry::rect::RectF; use platform::Event; use postage::oneshot; #[cfg(any(test, feature = "test-support"))] @@ -3571,6 +3572,16 @@ impl<'a, 'b, 'c, V> PaintContext<'a, 'b, 'c, V> { pub fn new(view_context: &'c mut ViewContext<'a, 'b, V>) -> Self { Self { view_context } } + + pub fn paint_layer(&mut self, clip_bounds: Option, f: F) -> R + where + F: FnOnce(&mut Self) -> R, + { + self.scene().push_layer(clip_bounds); + let result = f(self); + self.scene().pop_layer(); + result + } } impl<'a, 'b, 'c, V> Deref for PaintContext<'a, 'b, 'c, V> { diff --git a/crates/gpui/src/app/window.rs b/crates/gpui/src/app/window.rs index 27ccbdcf7a29a9add172eb7d5c0f55ac10f0f481..63462abad991dd6d4f7a3abb72c494cfd86cedec 100644 --- a/crates/gpui/src/app/window.rs +++ b/crates/gpui/src/app/window.rs @@ -55,6 +55,7 @@ pub struct Window { pub(crate) invalidation: Option, pub(crate) platform_window: Box, pub(crate) rendered_views: HashMap>, + scene: SceneBuilder, pub(crate) text_style_stack: Vec, pub(crate) theme_stack: Vec>, pub(crate) new_parents: HashMap, @@ -98,6 +99,7 @@ impl Window { inspector_enabled: false, platform_window, rendered_views: Default::default(), + scene: SceneBuilder::new(), text_style_stack: Vec::new(), theme_stack: Vec::new(), new_parents: HashMap::default(), @@ -241,6 +243,10 @@ impl<'a> WindowContext<'a> { .push_back(Effect::RepaintWindow { window }); } + pub fn scene(&mut self) -> &mut SceneBuilder { + &mut self.window.scene + } + pub fn enable_inspector(&mut self) { self.window.inspector_enabled = true; } @@ -1080,9 +1086,7 @@ impl<'a> WindowContext<'a> { let root_view_id = self.window.root_view().id(); let mut rendered_root = self.window.rendered_views.remove(&root_view_id).unwrap(); - let mut scene_builder = SceneBuilder::new(scale_factor); rendered_root.paint( - &mut scene_builder, Vector2F::zero(), RectF::from_points(Vector2F::zero(), window_size), self, @@ -1092,7 +1096,7 @@ impl<'a> WindowContext<'a> { .insert(root_view_id, rendered_root); self.window.text_layout_cache.finish_frame(); - let mut scene = scene_builder.build(); + let mut scene = self.window.scene.build(scale_factor); self.window.cursor_regions = scene.cursor_regions(); self.window.mouse_regions = scene.mouse_regions(); self.window.event_handlers = scene.take_event_handlers(); @@ -1696,7 +1700,6 @@ impl Element for ChildView { fn paint( &mut self, - scene: &mut SceneBuilder, bounds: RectF, visible_bounds: RectF, _: &mut Self::LayoutState, @@ -1705,7 +1708,7 @@ impl Element for ChildView { ) { if let Some(mut rendered_view) = cx.window.rendered_views.remove(&self.view_id) { rendered_view - .paint(scene, bounds.origin(), visible_bounds, cx) + .paint(bounds.origin(), visible_bounds, cx) .log_err(); cx.window.rendered_views.insert(self.view_id, rendered_view); } else { diff --git a/crates/gpui/src/elements.rs b/crates/gpui/src/elements.rs index 790581eb9f4af667618db984e51836c37e064bca..9924db0f1a9657e0fe3108ae351c7fc223731759 100644 --- a/crates/gpui/src/elements.rs +++ b/crates/gpui/src/elements.rs @@ -34,8 +34,8 @@ use crate::{ rect::RectF, vector::{vec2f, Vector2F}, }, - json, Action, Entity, LayoutContext, PaintContext, SceneBuilder, SizeConstraint, TypeTag, View, - ViewContext, WeakViewHandle, WindowContext, + json, Action, Entity, LayoutContext, PaintContext, SizeConstraint, TypeTag, View, ViewContext, + WeakViewHandle, WindowContext, }; use anyhow::{anyhow, Result}; use core::panic; @@ -64,7 +64,6 @@ pub trait Element: 'static { fn paint( &mut self, - scene: &mut SceneBuilder, bounds: RectF, visible_bounds: RectF, layout: &mut Self::LayoutState, @@ -265,7 +264,6 @@ trait AnyElementState { fn paint( &mut self, - scene: &mut SceneBuilder, origin: Vector2F, visible_bounds: RectF, view: &mut V, @@ -346,7 +344,6 @@ impl> AnyElementState for ElementState { fn paint( &mut self, - scene: &mut SceneBuilder, origin: Vector2F, visible_bounds: RectF, view: &mut V, @@ -361,7 +358,6 @@ impl> AnyElementState for ElementState { } => { let bounds = RectF::new(origin, size); let paint = element.paint( - scene, bounds, visible_bounds, &mut layout, @@ -386,7 +382,6 @@ impl> AnyElementState for ElementState { } => { let bounds = RectF::new(origin, bounds.size()); let paint = element.paint( - scene, bounds, visible_bounds, &mut layout, @@ -522,13 +517,12 @@ impl AnyElement { pub fn paint( &mut self, - scene: &mut SceneBuilder, origin: Vector2F, visible_bounds: RectF, view: &mut V, cx: &mut PaintContext, ) { - self.state.paint(scene, origin, visible_bounds, view, cx); + self.state.paint(origin, visible_bounds, view, cx); } pub fn rect_for_text_range( @@ -584,14 +578,13 @@ impl Element for AnyElement { fn paint( &mut self, - scene: &mut SceneBuilder, bounds: RectF, visible_bounds: RectF, _: &mut Self::LayoutState, view: &mut V, cx: &mut PaintContext, ) -> Self::PaintState { - self.paint(scene, bounds.origin(), visible_bounds, view, cx); + self.paint(bounds.origin(), visible_bounds, view, cx); } fn rect_for_text_range( @@ -647,7 +640,6 @@ pub trait AnyRootElement { fn layout(&mut self, constraint: SizeConstraint, cx: &mut WindowContext) -> Result; fn paint( &mut self, - scene: &mut SceneBuilder, origin: Vector2F, visible_bounds: RectF, cx: &mut WindowContext, @@ -675,7 +667,6 @@ impl AnyRootElement for RootElement { fn paint( &mut self, - scene: &mut SceneBuilder, origin: Vector2F, visible_bounds: RectF, cx: &mut WindowContext, @@ -687,8 +678,7 @@ impl AnyRootElement for RootElement { view.update(cx, |view, cx| { let mut cx = PaintContext::new(cx); - self.element - .paint(scene, origin, visible_bounds, view, &mut cx); + self.element.paint(origin, visible_bounds, view, &mut cx); Ok(()) }) } diff --git a/crates/gpui/src/elements/align.rs b/crates/gpui/src/elements/align.rs index 1312c336fb352751e06be7310648dffae62c7e27..e79b37299d3380232cdfda11109b65f8ed1a5451 100644 --- a/crates/gpui/src/elements/align.rs +++ b/crates/gpui/src/elements/align.rs @@ -1,7 +1,6 @@ use crate::{ geometry::{rect::RectF, vector::Vector2F}, - json, AnyElement, Element, LayoutContext, PaintContext, SceneBuilder, SizeConstraint, - ViewContext, + json, AnyElement, Element, LayoutContext, PaintContext, SizeConstraint, ViewContext, }; use json::ToJson; @@ -65,7 +64,6 @@ impl Element for Align { fn paint( &mut self, - scene: &mut SceneBuilder, bounds: RectF, visible_bounds: RectF, _: &mut Self::LayoutState, @@ -79,7 +77,6 @@ impl Element for Align { let child_target = child_center + child_center * self.alignment; self.child.paint( - scene, bounds.origin() - (child_target - my_target), visible_bounds, view, diff --git a/crates/gpui/src/elements/canvas.rs b/crates/gpui/src/elements/canvas.rs index d169efb3d967705c40bcaca8b0de1222b5c6cad5..93cc0bdfdbb03fbc779dbb4c05cadb8b705819e9 100644 --- a/crates/gpui/src/elements/canvas.rs +++ b/crates/gpui/src/elements/canvas.rs @@ -3,7 +3,7 @@ use std::marker::PhantomData; use super::Element; use crate::{ json::{self, json}, - PaintContext, SceneBuilder, ViewContext, + PaintContext, ViewContext, }; use json::ToJson; use pathfinder_geometry::{ @@ -15,7 +15,7 @@ pub struct Canvas(F, PhantomData); impl Canvas where - F: FnMut(&mut SceneBuilder, RectF, RectF, &mut V, &mut ViewContext), + F: FnMut(RectF, RectF, &mut V, &mut PaintContext), { pub fn new(f: F) -> Self { Self(f, PhantomData) @@ -24,7 +24,7 @@ where impl Element for Canvas where - F: 'static + FnMut(&mut SceneBuilder, RectF, RectF, &mut V, &mut ViewContext), + F: 'static + FnMut(RectF, RectF, &mut V, &mut PaintContext), { type LayoutState = (); type PaintState = (); @@ -50,14 +50,13 @@ where fn paint( &mut self, - scene: &mut SceneBuilder, bounds: RectF, visible_bounds: RectF, _: &mut Self::LayoutState, view: &mut V, cx: &mut PaintContext, ) -> Self::PaintState { - self.0(scene, bounds, visible_bounds, view, cx) + self.0(bounds, visible_bounds, view, cx) } fn rect_for_text_range( diff --git a/crates/gpui/src/elements/clipped.rs b/crates/gpui/src/elements/clipped.rs index 64f22515b3f19a7e779b1322d92bec24451705ab..e521794f3c49a82a124eed3a3d28cef3431b9a64 100644 --- a/crates/gpui/src/elements/clipped.rs +++ b/crates/gpui/src/elements/clipped.rs @@ -3,10 +3,7 @@ use std::ops::Range; use pathfinder_geometry::{rect::RectF, vector::Vector2F}; use serde_json::json; -use crate::{ - json, AnyElement, Element, LayoutContext, PaintContext, SceneBuilder, SizeConstraint, - ViewContext, -}; +use crate::{json, AnyElement, Element, LayoutContext, PaintContext, SizeConstraint, ViewContext}; pub struct Clipped { child: AnyElement, @@ -33,17 +30,16 @@ impl Element for Clipped { fn paint( &mut self, - scene: &mut SceneBuilder, bounds: RectF, visible_bounds: RectF, _: &mut Self::LayoutState, view: &mut V, cx: &mut PaintContext, ) -> Self::PaintState { - scene.paint_layer(Some(bounds), |scene| { - self.child - .paint(scene, bounds.origin(), visible_bounds, view, cx) - }) + cx.scene().push_layer(Some(bounds)); + let state = self.child.paint(bounds.origin(), visible_bounds, view, cx); + cx.scene().pop_layer(); + state } fn rect_for_text_range( diff --git a/crates/gpui/src/elements/component.rs b/crates/gpui/src/elements/component.rs index c8800d18a16aafde2a8841bbd60a640f907f981e..48f139e7935feab9b1da4f47aa963a232097b92b 100644 --- a/crates/gpui/src/elements/component.rs +++ b/crates/gpui/src/elements/component.rs @@ -2,9 +2,7 @@ use std::{any::Any, marker::PhantomData}; use pathfinder_geometry::{rect::RectF, vector::Vector2F}; -use crate::{ - AnyElement, Element, LayoutContext, PaintContext, SceneBuilder, SizeConstraint, ViewContext, -}; +use crate::{AnyElement, Element, LayoutContext, PaintContext, SizeConstraint, ViewContext}; use super::Empty; @@ -300,7 +298,6 @@ impl + 'static> Element for ComponentAdap fn paint( &mut self, - scene: &mut SceneBuilder, bounds: RectF, visible_bounds: RectF, _: &mut Self::LayoutState, @@ -310,7 +307,7 @@ impl + 'static> Element for ComponentAdap self.element .as_mut() .expect("Layout should always be called before paint") - .paint(scene, bounds.origin(), visible_bounds, view, cx) + .paint(bounds.origin(), visible_bounds, view, cx) } fn rect_for_text_range( diff --git a/crates/gpui/src/elements/constrained_box.rs b/crates/gpui/src/elements/constrained_box.rs index 495b6c69dc40f80520be12afcb7d412a3015e8d3..fe49bd091987983faba0f3953cd274ac583cc334 100644 --- a/crates/gpui/src/elements/constrained_box.rs +++ b/crates/gpui/src/elements/constrained_box.rs @@ -5,8 +5,7 @@ use serde_json::json; use crate::{ geometry::{rect::RectF, vector::Vector2F}, - json, AnyElement, Element, LayoutContext, PaintContext, SceneBuilder, SizeConstraint, - ViewContext, + json, AnyElement, Element, LayoutContext, PaintContext, SizeConstraint, ViewContext, }; pub struct ConstrainedBox { @@ -152,17 +151,15 @@ impl Element for ConstrainedBox { fn paint( &mut self, - scene: &mut SceneBuilder, bounds: RectF, visible_bounds: RectF, _: &mut Self::LayoutState, view: &mut V, cx: &mut PaintContext, ) -> Self::PaintState { - scene.paint_layer(Some(visible_bounds), |scene| { - self.child - .paint(scene, bounds.origin(), visible_bounds, view, cx); - }) + cx.scene().push_layer(Some(visible_bounds)); + self.child.paint(bounds.origin(), visible_bounds, view, cx); + cx.scene().pop_layer(); } fn rect_for_text_range( diff --git a/crates/gpui/src/elements/container.rs b/crates/gpui/src/elements/container.rs index 82bf260fe15dfb8e29c7799a87f8a76d6f1ef6d3..6a0f860594d01099dd709e86388d74cf65c7c5b2 100644 --- a/crates/gpui/src/elements/container.rs +++ b/crates/gpui/src/elements/container.rs @@ -10,7 +10,7 @@ use crate::{ json::ToJson, platform::CursorStyle, scene::{self, CornerRadii, CursorRegion, Quad}, - AnyElement, Element, LayoutContext, PaintContext, SceneBuilder, SizeConstraint, ViewContext, + AnyElement, Element, LayoutContext, PaintContext, SizeConstraint, ViewContext, }; use schemars::JsonSchema; use serde::Deserialize; @@ -387,7 +387,6 @@ impl Element for Container { fn paint( &mut self, - scene: &mut SceneBuilder, bounds: RectF, visible_bounds: RectF, _: &mut Self::LayoutState, @@ -400,7 +399,7 @@ impl Element for Container { ); if let Some(shadow) = self.style.shadow.as_ref() { - scene.push_shadow(scene::Shadow { + cx.scene().push_shadow(scene::Shadow { bounds: quad_bounds + shadow.offset, corner_radii: self.style.corner_radii, sigma: shadow.blur, @@ -410,7 +409,7 @@ impl Element for Container { if let Some(hit_bounds) = quad_bounds.intersection(visible_bounds) { if let Some(style) = self.style.cursor { - scene.push_cursor_region(CursorRegion { + cx.scene().push_cursor_region(CursorRegion { bounds: hit_bounds, style, }); @@ -421,26 +420,25 @@ impl Element for Container { quad_bounds.origin() + vec2f(self.style.padding.left, self.style.padding.top); if self.style.border.overlay { - scene.push_quad(Quad { + cx.scene().push_quad(Quad { bounds: quad_bounds, background: self.style.background_color, border: Default::default(), corner_radii: self.style.corner_radii.into(), }); - self.child - .paint(scene, child_origin, visible_bounds, view, cx); + self.child.paint(child_origin, visible_bounds, view, cx); - scene.push_layer(None); - scene.push_quad(Quad { + cx.scene().push_layer(None); + cx.scene().push_quad(Quad { bounds: quad_bounds, background: self.style.overlay_color, border: self.style.border.into(), corner_radii: self.style.corner_radii.into(), }); - scene.pop_layer(); + cx.scene().pop_layer(); } else { - scene.push_quad(Quad { + cx.scene().push_quad(Quad { bounds: quad_bounds, background: self.style.background_color, border: self.style.border.into(), @@ -452,18 +450,17 @@ impl Element for Container { self.style.border.left_width(), self.style.border.top_width(), ); - self.child - .paint(scene, child_origin, visible_bounds, view, cx); + self.child.paint(child_origin, visible_bounds, view, cx); if self.style.overlay_color.is_some() { - scene.push_layer(None); - scene.push_quad(Quad { + cx.scene().push_layer(None); + cx.scene().push_quad(Quad { bounds: quad_bounds, background: self.style.overlay_color, border: Default::default(), corner_radii: self.style.corner_radii.into(), }); - scene.pop_layer(); + cx.scene().pop_layer(); } } } diff --git a/crates/gpui/src/elements/empty.rs b/crates/gpui/src/elements/empty.rs index 04b1c70213489cf0acd3b7b1d8151d45d905441f..021c58ecba61eb5561dc032602387ee58e4bab29 100644 --- a/crates/gpui/src/elements/empty.rs +++ b/crates/gpui/src/elements/empty.rs @@ -6,7 +6,7 @@ use crate::{ vector::{vec2f, Vector2F}, }, json::{json, ToJson}, - LayoutContext, PaintContext, SceneBuilder, ViewContext, + LayoutContext, PaintContext, ViewContext, }; use crate::{Element, SizeConstraint}; @@ -52,7 +52,6 @@ impl Element for Empty { fn paint( &mut self, - _: &mut SceneBuilder, _: RectF, _: RectF, _: &mut Self::LayoutState, diff --git a/crates/gpui/src/elements/expanded.rs b/crates/gpui/src/elements/expanded.rs index ad6682d2a9a2ff2ed9b40df489c2d4100c8191a8..0baab03ed875ee6f0ae024a0d9a9224da66d8a61 100644 --- a/crates/gpui/src/elements/expanded.rs +++ b/crates/gpui/src/elements/expanded.rs @@ -2,8 +2,7 @@ use std::ops::Range; use crate::{ geometry::{rect::RectF, vector::Vector2F}, - json, AnyElement, Element, LayoutContext, PaintContext, SceneBuilder, SizeConstraint, - ViewContext, + json, AnyElement, Element, LayoutContext, PaintContext, SizeConstraint, ViewContext, }; use serde_json::json; @@ -57,15 +56,13 @@ impl Element for Expanded { fn paint( &mut self, - scene: &mut SceneBuilder, bounds: RectF, visible_bounds: RectF, _: &mut Self::LayoutState, view: &mut V, cx: &mut PaintContext, ) -> Self::PaintState { - self.child - .paint(scene, bounds.origin(), visible_bounds, view, cx); + self.child.paint(bounds.origin(), visible_bounds, view, cx); } fn rect_for_text_range( diff --git a/crates/gpui/src/elements/flex.rs b/crates/gpui/src/elements/flex.rs index 80dfb0625cd581407801148a5df7ee2046eae596..37cb512bd36ba93a9a9c53901013140dbfa9e750 100644 --- a/crates/gpui/src/elements/flex.rs +++ b/crates/gpui/src/elements/flex.rs @@ -2,8 +2,8 @@ use std::{any::Any, cell::Cell, f32::INFINITY, ops::Range, rc::Rc}; use crate::{ json::{self, ToJson, Value}, - AnyElement, Axis, Element, ElementStateHandle, LayoutContext, PaintContext, SceneBuilder, - SizeConstraint, Vector2FExt, ViewContext, + AnyElement, Axis, Element, ElementStateHandle, LayoutContext, PaintContext, SizeConstraint, + Vector2FExt, ViewContext, }; use pathfinder_geometry::{ rect::RectF, @@ -260,7 +260,6 @@ impl Element for Flex { fn paint( &mut self, - scene: &mut SceneBuilder, bounds: RectF, visible_bounds: RectF, remaining_space: &mut Self::LayoutState, @@ -272,14 +271,14 @@ impl Element for Flex { let mut remaining_space = *remaining_space; let overflowing = remaining_space < 0.; if overflowing { - scene.push_layer(Some(visible_bounds)); + cx.scene().push_layer(Some(visible_bounds)); } - if let Some(scroll_state) = &self.scroll_state { - scene.push_mouse_region( - crate::MouseRegion::new::(scroll_state.1, 0, bounds) + if let Some((scroll_state, id)) = &self.scroll_state { + let scroll_state = scroll_state.read(cx).clone(); + cx.scene().push_mouse_region( + crate::MouseRegion::new::(*id, 0, bounds) .on_scroll({ - let scroll_state = scroll_state.0.read(cx).clone(); let axis = self.axis; move |e, _: &mut V, cx| { if remaining_space < 0. { @@ -358,7 +357,7 @@ impl Element for Flex { aligned_child_origin }; - child.paint(scene, aligned_child_origin, visible_bounds, view, cx); + child.paint(aligned_child_origin, visible_bounds, view, cx); match self.axis { Axis::Horizontal => child_origin += vec2f(child.size().x() + self.spacing, 0.0), @@ -367,7 +366,7 @@ impl Element for Flex { } if overflowing { - scene.pop_layer(); + cx.scene().pop_layer(); } } @@ -451,15 +450,13 @@ impl Element for FlexItem { fn paint( &mut self, - scene: &mut SceneBuilder, bounds: RectF, visible_bounds: RectF, _: &mut Self::LayoutState, view: &mut V, cx: &mut PaintContext, ) -> Self::PaintState { - self.child - .paint(scene, bounds.origin(), visible_bounds, view, cx) + self.child.paint(bounds.origin(), visible_bounds, view, cx) } fn rect_for_text_range( diff --git a/crates/gpui/src/elements/hook.rs b/crates/gpui/src/elements/hook.rs index 579c2b682f41f37b19b5e587f8acdf3ea30012c4..c3fa0946f39f4c59b7a3977914d316c8669b6a96 100644 --- a/crates/gpui/src/elements/hook.rs +++ b/crates/gpui/src/elements/hook.rs @@ -3,7 +3,7 @@ use std::ops::Range; use crate::{ geometry::{rect::RectF, vector::Vector2F}, json::json, - AnyElement, Element, LayoutContext, PaintContext, SceneBuilder, SizeConstraint, ViewContext, + AnyElement, Element, LayoutContext, PaintContext, SizeConstraint, ViewContext, }; pub struct Hook { @@ -47,15 +47,13 @@ impl Element for Hook { fn paint( &mut self, - scene: &mut SceneBuilder, bounds: RectF, visible_bounds: RectF, _: &mut Self::LayoutState, view: &mut V, cx: &mut PaintContext, ) { - self.child - .paint(scene, bounds.origin(), visible_bounds, view, cx); + self.child.paint(bounds.origin(), visible_bounds, view, cx); } fn rect_for_text_range( diff --git a/crates/gpui/src/elements/image.rs b/crates/gpui/src/elements/image.rs index aabf5469371ba17f9e34784cfbff5c3c92eb8d96..c1dbe33e68880645251273777143ff522590bfae 100644 --- a/crates/gpui/src/elements/image.rs +++ b/crates/gpui/src/elements/image.rs @@ -5,8 +5,7 @@ use crate::{ vector::{vec2f, Vector2F}, }, json::{json, ToJson}, - scene, Element, ImageData, LayoutContext, PaintContext, SceneBuilder, SizeConstraint, - ViewContext, + scene, Element, ImageData, LayoutContext, PaintContext, SizeConstraint, ViewContext, }; use schemars::JsonSchema; use serde::Deserialize; @@ -92,15 +91,14 @@ impl Element for Image { fn paint( &mut self, - scene: &mut SceneBuilder, bounds: RectF, _: RectF, layout: &mut Self::LayoutState, _: &mut V, - _: &mut PaintContext, + cx: &mut PaintContext, ) -> Self::PaintState { if let Some(data) = layout { - scene.push_image(scene::Image { + cx.scene().push_image(scene::Image { bounds, border: self.style.border.into(), corner_radii: self.style.corner_radius.into(), diff --git a/crates/gpui/src/elements/keystroke_label.rs b/crates/gpui/src/elements/keystroke_label.rs index 48a3971658d4ea4ca4d7c866b49d62dd228d92a6..cb473eeb087a239fdaa54176ad65aa46a21995e1 100644 --- a/crates/gpui/src/elements/keystroke_label.rs +++ b/crates/gpui/src/elements/keystroke_label.rs @@ -61,14 +61,13 @@ impl Element for KeystrokeLabel { fn paint( &mut self, - scene: &mut SceneBuilder, bounds: RectF, visible_bounds: RectF, element: &mut AnyElement, view: &mut V, cx: &mut PaintContext, ) { - element.paint(scene, bounds.origin(), visible_bounds, view, cx); + element.paint(bounds.origin(), visible_bounds, view, cx); } fn rect_for_text_range( diff --git a/crates/gpui/src/elements/label.rs b/crates/gpui/src/elements/label.rs index 281c2ce9b8de7736722cdc338e1558b45ef1146d..54d89bdaecedfedbaf1a2aa862867f7ab1af5208 100644 --- a/crates/gpui/src/elements/label.rs +++ b/crates/gpui/src/elements/label.rs @@ -8,7 +8,7 @@ use crate::{ }, json::{ToJson, Value}, text_layout::{Line, RunStyle}, - Element, LayoutContext, PaintContext, SceneBuilder, SizeConstraint, ViewContext, + Element, LayoutContext, PaintContext, SizeConstraint, ViewContext, }; use schemars::JsonSchema; use serde::Deserialize; @@ -158,7 +158,6 @@ impl Element for Label { fn paint( &mut self, - scene: &mut SceneBuilder, bounds: RectF, visible_bounds: RectF, line: &mut Self::LayoutState, @@ -166,13 +165,7 @@ impl Element for Label { cx: &mut PaintContext, ) -> Self::PaintState { let visible_bounds = bounds.intersection(visible_bounds).unwrap_or_default(); - line.paint( - scene, - bounds.origin(), - visible_bounds, - bounds.size().y(), - cx, - ) + line.paint(bounds.origin(), visible_bounds, bounds.size().y(), cx) } fn rect_for_text_range( diff --git a/crates/gpui/src/elements/list.rs b/crates/gpui/src/elements/list.rs index bcb80d8c7ecc60335045e36e664eaccadd5a9c32..e1052e9f8c3daeb7a16263d8cda85550d7442180 100644 --- a/crates/gpui/src/elements/list.rs +++ b/crates/gpui/src/elements/list.rs @@ -4,8 +4,7 @@ use crate::{ vector::{vec2f, Vector2F}, }, json::json, - AnyElement, Element, LayoutContext, MouseRegion, PaintContext, SceneBuilder, SizeConstraint, - ViewContext, + AnyElement, Element, LayoutContext, MouseRegion, PaintContext, SizeConstraint, ViewContext, }; use std::{cell::RefCell, collections::VecDeque, fmt::Debug, ops::Range, rc::Rc}; use sum_tree::{Bias, SumTree}; @@ -250,7 +249,6 @@ impl Element for List { fn paint( &mut self, - scene: &mut SceneBuilder, bounds: RectF, visible_bounds: RectF, scroll_top: &mut ListOffset, @@ -258,9 +256,10 @@ impl Element for List { cx: &mut PaintContext, ) { let visible_bounds = visible_bounds.intersection(bounds).unwrap_or_default(); - scene.push_layer(Some(visible_bounds)); - scene.push_mouse_region( - MouseRegion::new::(cx.view_id(), 0, bounds).on_scroll({ + cx.scene().push_layer(Some(visible_bounds)); + let view_id = cx.view_id(); + cx.scene() + .push_mouse_region(MouseRegion::new::(view_id, 0, bounds).on_scroll({ let state = self.state.clone(); let height = bounds.height(); let scroll_top = scroll_top.clone(); @@ -274,17 +273,14 @@ impl Element for List { cx, ) } - }), - ); + })); let state = &mut *self.state.0.borrow_mut(); for (element, origin) in state.visible_elements(bounds, scroll_top) { - element - .borrow_mut() - .paint(scene, origin, visible_bounds, view, cx); + element.borrow_mut().paint(origin, visible_bounds, view, cx); } - scene.pop_layer(); + cx.scene().pop_layer(); } fn rect_for_text_range( @@ -957,15 +953,7 @@ mod tests { (self.size, ()) } - fn paint( - &mut self, - _: &mut SceneBuilder, - _: RectF, - _: RectF, - _: &mut (), - _: &mut V, - _: &mut PaintContext, - ) { + fn paint(&mut self, _: RectF, _: RectF, _: &mut (), _: &mut V, _: &mut PaintContext) { unimplemented!() } diff --git a/crates/gpui/src/elements/mouse_event_handler.rs b/crates/gpui/src/elements/mouse_event_handler.rs index b1140a696045705a01af7f9f6cba89fc28401394..0b073f4f0f059441504b41408d05abe517293959 100644 --- a/crates/gpui/src/elements/mouse_event_handler.rs +++ b/crates/gpui/src/elements/mouse_event_handler.rs @@ -11,7 +11,7 @@ use crate::{ MouseHover, MouseMove, MouseMoveOut, MouseScrollWheel, MouseUp, MouseUpOut, }, AnyElement, Element, EventContext, LayoutContext, MouseRegion, MouseState, PaintContext, - SceneBuilder, SizeConstraint, TypeTag, ViewContext, + SizeConstraint, TypeTag, ViewContext, }; use serde_json::json; use std::ops::Range; @@ -236,26 +236,21 @@ impl MouseEventHandler { .round_out() } - fn paint_regions( - &self, - scene: &mut SceneBuilder, - bounds: RectF, - visible_bounds: RectF, - cx: &mut ViewContext, - ) { + fn paint_regions(&self, bounds: RectF, visible_bounds: RectF, cx: &mut ViewContext) { let visible_bounds = visible_bounds.intersection(bounds).unwrap_or_default(); let hit_bounds = self.hit_bounds(visible_bounds); if let Some(style) = self.cursor_style { - scene.push_cursor_region(CursorRegion { + cx.scene().push_cursor_region(CursorRegion { bounds: hit_bounds, style, }); } - scene.push_mouse_region( + let view_id = cx.view_id(); + cx.scene().push_mouse_region( MouseRegion::from_handlers( self.tag, - cx.view_id(), + view_id, self.region_id, hit_bounds, self.handlers.clone(), @@ -282,7 +277,6 @@ impl Element for MouseEventHandler { fn paint( &mut self, - scene: &mut SceneBuilder, bounds: RectF, visible_bounds: RectF, _: &mut Self::LayoutState, @@ -290,16 +284,13 @@ impl Element for MouseEventHandler { cx: &mut PaintContext, ) -> Self::PaintState { if self.above { - self.child - .paint(scene, bounds.origin(), visible_bounds, view, cx); - - scene.paint_layer(None, |scene| { - self.paint_regions(scene, bounds, visible_bounds, cx); - }); + self.child.paint(bounds.origin(), visible_bounds, view, cx); + cx.scene().push_layer(None); + self.paint_regions(bounds, visible_bounds, cx); + cx.scene().pop_layer(); } else { - self.paint_regions(scene, bounds, visible_bounds, cx); - self.child - .paint(scene, bounds.origin(), visible_bounds, view, cx); + self.paint_regions(bounds, visible_bounds, cx); + self.child.paint(bounds.origin(), visible_bounds, view, cx); } } diff --git a/crates/gpui/src/elements/overlay.rs b/crates/gpui/src/elements/overlay.rs index 14d19e802c0ea15b314f209418fdaa4f25af5644..f8d4708623c2ffdaf0f54128cced0da6a52bb362 100644 --- a/crates/gpui/src/elements/overlay.rs +++ b/crates/gpui/src/elements/overlay.rs @@ -3,8 +3,8 @@ use std::ops::Range; use crate::{ geometry::{rect::RectF, vector::Vector2F}, json::ToJson, - AnyElement, Axis, Element, LayoutContext, MouseRegion, PaintContext, SceneBuilder, - SizeConstraint, ViewContext, + AnyElement, Axis, Element, LayoutContext, MouseRegion, PaintContext, SizeConstraint, + ViewContext, }; use serde_json::json; @@ -138,7 +138,6 @@ impl Element for Overlay { fn paint( &mut self, - scene: &mut SceneBuilder, bounds: RectF, _: RectF, size: &mut Self::LayoutState, @@ -213,25 +212,23 @@ impl Element for Overlay { OverlayFitMode::None => {} } - scene.paint_stacking_context(None, self.z_index, |scene| { - if self.hoverable { - enum OverlayHoverCapture {} - // Block hovers in lower stacking contexts - scene.push_mouse_region(MouseRegion::new::( - cx.view_id(), - cx.view_id(), - bounds, + cx.scene().push_stacking_context(None, self.z_index); + if self.hoverable { + enum OverlayHoverCapture {} + // Block hovers in lower stacking contexts + let view_id = cx.view_id(); + cx.scene() + .push_mouse_region(MouseRegion::new::( + view_id, view_id, bounds, )); - } - - self.child.paint( - scene, - bounds.origin(), - RectF::new(Vector2F::zero(), cx.window_size()), - view, - cx, - ); - }); + } + self.child.paint( + bounds.origin(), + RectF::new(Vector2F::zero(), cx.window_size()), + view, + cx, + ); + cx.scene().pop_stacking_context(); } fn rect_for_text_range( diff --git a/crates/gpui/src/elements/resizable.rs b/crates/gpui/src/elements/resizable.rs index 3c2febcce34572b2e50ae5ea0077ac339c072fd7..e67ad70304140eea1e7590a1b1bfac1f672fdb85 100644 --- a/crates/gpui/src/elements/resizable.rs +++ b/crates/gpui/src/elements/resizable.rs @@ -7,7 +7,7 @@ use serde_json::json; use crate::{ geometry::rect::RectF, platform::{CursorStyle, MouseButton}, - AnyElement, AppContext, Axis, Element, LayoutContext, MouseRegion, PaintContext, SceneBuilder, + AnyElement, AppContext, Axis, Element, LayoutContext, MouseRegion, PaintContext, SizeConstraint, TypeTag, View, ViewContext, }; @@ -112,70 +112,70 @@ impl Element for Resizable { fn paint( &mut self, - scene: &mut SceneBuilder, bounds: pathfinder_geometry::rect::RectF, visible_bounds: pathfinder_geometry::rect::RectF, constraint: &mut SizeConstraint, view: &mut V, cx: &mut PaintContext, ) -> Self::PaintState { - scene.push_stacking_context(None, None); + cx.scene().push_stacking_context(None, None); let handle_region = self.handle_side.of_rect(bounds, self.handle_size); enum ResizeHandle {} - scene.push_mouse_region( - MouseRegion::new::( - cx.view_id(), - self.handle_side as usize, - handle_region, - ) - .on_down(MouseButton::Left, |_, _: &mut V, _| {}) // This prevents the mouse down event from being propagated elsewhere - .on_click(MouseButton::Left, { - let on_resize = self.on_resize.clone(); - move |click, v, cx| { - if click.click_count == 2 { - on_resize.borrow_mut()(v, None, cx); + let view_id = cx.view_id(); + cx.scene().push_mouse_region( + MouseRegion::new::(view_id, self.handle_side as usize, handle_region) + .on_down(MouseButton::Left, |_, _: &mut V, _| {}) // This prevents the mouse down event from being propagated elsewhere + .on_click(MouseButton::Left, { + let on_resize = self.on_resize.clone(); + move |click, v, cx| { + if click.click_count == 2 { + on_resize.borrow_mut()(v, None, cx); + } } - } - }) - .on_drag(MouseButton::Left, { - let bounds = bounds.clone(); - let side = self.handle_side; - let prev_size = side.relevant_component(bounds.size()); - let min_size = side.relevant_component(constraint.min); - let max_size = side.relevant_component(constraint.max); - let on_resize = self.on_resize.clone(); - let tag = self.tag; - move |event, view: &mut V, cx| { - if event.end { - return; + }) + .on_drag(MouseButton::Left, { + let bounds = bounds.clone(); + let side = self.handle_side; + let prev_size = side.relevant_component(bounds.size()); + let min_size = side.relevant_component(constraint.min); + let max_size = side.relevant_component(constraint.max); + let on_resize = self.on_resize.clone(); + let tag = self.tag; + move |event, view: &mut V, cx| { + if event.end { + return; + } + + let Some((bounds, _)) = get_bounds(tag, cx) else { + return; + }; + + let new_size_raw = match side { + // Handle on top side of element => Element is on bottom + HandleSide::Top => { + bounds.height() + bounds.origin_y() - event.position.y() + } + // Handle on right side of element => Element is on left + HandleSide::Right => event.position.x() - bounds.lower_left().x(), + // Handle on left side of element => Element is on the right + HandleSide::Left => { + bounds.width() + bounds.origin_x() - event.position.x() + } + // Handle on bottom side of element => Element is on the top + HandleSide::Bottom => event.position.y() - bounds.lower_left().y(), + }; + + let new_size = min_size.max(new_size_raw).min(max_size).round(); + if new_size != prev_size { + on_resize.borrow_mut()(view, Some(new_size), cx); + } } - - let Some((bounds, _)) = get_bounds(tag, cx) else { - return; - }; - - let new_size_raw = match side { - // Handle on top side of element => Element is on bottom - HandleSide::Top => bounds.height() + bounds.origin_y() - event.position.y(), - // Handle on right side of element => Element is on left - HandleSide::Right => event.position.x() - bounds.lower_left().x(), - // Handle on left side of element => Element is on the right - HandleSide::Left => bounds.width() + bounds.origin_x() - event.position.x(), - // Handle on bottom side of element => Element is on the top - HandleSide::Bottom => event.position.y() - bounds.lower_left().y(), - }; - - let new_size = min_size.max(new_size_raw).min(max_size).round(); - if new_size != prev_size { - on_resize.borrow_mut()(view, Some(new_size), cx); - } - } - }), + }), ); - scene.push_cursor_region(crate::CursorRegion { + cx.scene().push_cursor_region(crate::CursorRegion { bounds: handle_region, style: match self.handle_side.axis() { Axis::Horizontal => CursorStyle::ResizeLeftRight, @@ -183,10 +183,9 @@ impl Element for Resizable { }, }); - scene.pop_stacking_context(); + cx.scene().pop_stacking_context(); - self.child - .paint(scene, bounds.origin(), visible_bounds, view, cx); + self.child.paint(bounds.origin(), visible_bounds, view, cx); } fn rect_for_text_range( @@ -249,7 +248,6 @@ impl Element for BoundsProvider { fn paint( &mut self, - scene: &mut crate::SceneBuilder, bounds: pathfinder_geometry::rect::RectF, visible_bounds: pathfinder_geometry::rect::RectF, _: &mut Self::LayoutState, @@ -260,8 +258,7 @@ impl Element for BoundsProvider { map.0.insert(TypeTag::new::

(), (bounds, visible_bounds)); }); - self.child - .paint(scene, bounds.origin(), visible_bounds, view, cx) + self.child.paint(bounds.origin(), visible_bounds, view, cx) } fn rect_for_text_range( diff --git a/crates/gpui/src/elements/stack.rs b/crates/gpui/src/elements/stack.rs index e73e2f0b4024c42a0bc583856009fa30c36c5517..72f129b1da3646eb212e98888b6d6e27d61a0a58 100644 --- a/crates/gpui/src/elements/stack.rs +++ b/crates/gpui/src/elements/stack.rs @@ -3,7 +3,7 @@ use std::ops::Range; use crate::{ geometry::{rect::RectF, vector::Vector2F}, json::{self, json, ToJson}, - AnyElement, Element, LayoutContext, PaintContext, SceneBuilder, SizeConstraint, ViewContext, + AnyElement, Element, LayoutContext, PaintContext, SizeConstraint, ViewContext, }; /// Element which renders it's children in a stack on top of each other. @@ -52,7 +52,6 @@ impl Element for Stack { fn paint( &mut self, - scene: &mut SceneBuilder, bounds: RectF, visible_bounds: RectF, _: &mut Self::LayoutState, @@ -60,9 +59,9 @@ impl Element for Stack { cx: &mut PaintContext, ) -> Self::PaintState { for child in &mut self.children { - scene.paint_layer(None, |scene| { - child.paint(scene, bounds.origin(), visible_bounds, view, cx); - }); + cx.scene().push_layer(None); + child.paint(bounds.origin(), visible_bounds, view, cx); + cx.scene().pop_layer(); } } diff --git a/crates/gpui/src/elements/svg.rs b/crates/gpui/src/elements/svg.rs index 0d5bcd59e4a74545f23dd79aa1bd536df505967a..c81e5a2892f43582129c2858411a713e25a3e49b 100644 --- a/crates/gpui/src/elements/svg.rs +++ b/crates/gpui/src/elements/svg.rs @@ -7,7 +7,7 @@ use crate::{ rect::RectF, vector::{vec2f, Vector2F}, }, - scene, Element, LayoutContext, SceneBuilder, SizeConstraint, ViewContext, + scene, Element, LayoutContext, SizeConstraint, ViewContext, }; use schemars::JsonSchema; use serde_derive::Deserialize; @@ -69,15 +69,14 @@ impl Element for Svg { fn paint( &mut self, - scene: &mut SceneBuilder, bounds: RectF, _visible_bounds: RectF, svg: &mut Self::LayoutState, _: &mut V, - _: &mut PaintContext, + cx: &mut PaintContext, ) { if let Some(svg) = svg.clone() { - scene.push_icon(scene::Icon { + cx.scene().push_icon(scene::Icon { bounds, svg, path: self.path.clone(), diff --git a/crates/gpui/src/elements/text.rs b/crates/gpui/src/elements/text.rs index 3f5888345604a32138a60c4969e853472d502330..224397d067f2adabd3ff0fa96634f0f2f11152c3 100644 --- a/crates/gpui/src/elements/text.rs +++ b/crates/gpui/src/elements/text.rs @@ -7,8 +7,8 @@ use crate::{ }, json::{ToJson, Value}, text_layout::{Line, RunStyle, ShapedBoundary}, - AppContext, Element, FontCache, LayoutContext, PaintContext, SceneBuilder, SizeConstraint, - TextLayoutCache, ViewContext, + Element, FontCache, LayoutContext, PaintContext, SizeConstraint, TextLayoutCache, ViewContext, + WindowContext, }; use log::warn; use serde_json::json; @@ -21,7 +21,7 @@ pub struct Text { highlights: Option, HighlightStyle)]>>, custom_runs: Option<( Box<[Range]>, - Box, + Box, )>, } @@ -58,7 +58,7 @@ impl Text { pub fn with_custom_runs( mut self, runs: impl Into]>>, - callback: impl 'static + FnMut(usize, RectF, &mut SceneBuilder, &mut AppContext), + callback: impl 'static + FnMut(usize, RectF, &mut WindowContext), ) -> Self { self.custom_runs = Some((runs.into(), Box::new(callback))); self @@ -166,7 +166,6 @@ impl Element for Text { fn paint( &mut self, - scene: &mut SceneBuilder, bounds: RectF, visible_bounds: RectF, layout: &mut Self::LayoutState, @@ -175,7 +174,7 @@ impl Element for Text { ) -> Self::PaintState { let mut origin = bounds.origin(); let empty = Vec::new(); - let mut callback = |_, _, _: &mut SceneBuilder, _: &mut AppContext| {}; + let mut callback = |_, _, _: &mut WindowContext| {}; let mouse_runs; let custom_run_callback; @@ -202,7 +201,6 @@ impl Element for Text { if boundaries.intersects(visible_bounds) { if self.soft_wrap { line.paint_wrapped( - scene, origin, visible_bounds, layout.line_height, @@ -210,7 +208,7 @@ impl Element for Text { cx, ); } else { - line.paint(scene, origin, visible_bounds, layout.line_height, cx); + line.paint(origin, visible_bounds, layout.line_height, cx); } } @@ -248,7 +246,7 @@ impl Element for Text { *run_origin, glyph_origin + vec2f(0., layout.line_height), ); - custom_run_callback(*run_ix, bounds, scene, cx); + custom_run_callback(*run_ix, bounds, cx); *run_origin = vec2f(origin.x(), glyph_origin.y() + layout.line_height); } @@ -264,7 +262,7 @@ impl Element for Text { run_origin, glyph_origin + vec2f(0., layout.line_height), ); - custom_run_callback(run_ix, bounds, scene, cx); + custom_run_callback(run_ix, bounds, cx); custom_runs.next(); } @@ -294,7 +292,7 @@ impl Element for Text { run_origin, line_end + vec2f(0., layout.line_height), ); - custom_run_callback(run_ix, bounds, scene, cx); + custom_run_callback(run_ix, bounds, cx); if end_offset == run_end_offset { custom_runs.next(); } diff --git a/crates/gpui/src/elements/tooltip.rs b/crates/gpui/src/elements/tooltip.rs index d3a1db713e6af4570cf9754e5ccd58cb7d3fe96a..1c521751f9c5db0b3bebb0788d260deb1851ea2f 100644 --- a/crates/gpui/src/elements/tooltip.rs +++ b/crates/gpui/src/elements/tooltip.rs @@ -6,8 +6,8 @@ use crate::{ fonts::TextStyle, geometry::{rect::RectF, vector::Vector2F}, json::json, - Action, Axis, ElementStateHandle, LayoutContext, PaintContext, SceneBuilder, SizeConstraint, - Task, TypeTag, ViewContext, + Action, Axis, ElementStateHandle, LayoutContext, PaintContext, SizeConstraint, Task, TypeTag, + ViewContext, }; use schemars::JsonSchema; use serde::Deserialize; @@ -204,17 +204,15 @@ impl Element for Tooltip { fn paint( &mut self, - scene: &mut SceneBuilder, bounds: RectF, visible_bounds: RectF, _: &mut Self::LayoutState, view: &mut V, cx: &mut PaintContext, ) { - self.child - .paint(scene, bounds.origin(), visible_bounds, view, cx); + self.child.paint(bounds.origin(), visible_bounds, view, cx); if let Some(tooltip) = self.tooltip.as_mut() { - tooltip.paint(scene, bounds.origin(), visible_bounds, view, cx); + tooltip.paint(bounds.origin(), visible_bounds, view, cx); } } diff --git a/crates/gpui/src/elements/uniform_list.rs b/crates/gpui/src/elements/uniform_list.rs index c7279d6389623c9b801f09961977e9759b94595b..e75e13438695169a226679ee50cfeaeece782830 100644 --- a/crates/gpui/src/elements/uniform_list.rs +++ b/crates/gpui/src/elements/uniform_list.rs @@ -6,7 +6,7 @@ use crate::{ }, json::{self, json}, platform::ScrollWheelEvent, - AnyElement, LayoutContext, MouseRegion, PaintContext, SceneBuilder, ViewContext, + AnyElement, LayoutContext, MouseRegion, PaintContext, ViewContext, }; use json::ToJson; use std::{cell::RefCell, cmp, ops::Range, rc::Rc}; @@ -272,7 +272,6 @@ impl Element for UniformList { fn paint( &mut self, - scene: &mut SceneBuilder, bounds: RectF, visible_bounds: RectF, layout: &mut Self::LayoutState, @@ -281,9 +280,9 @@ impl Element for UniformList { ) -> Self::PaintState { let visible_bounds = visible_bounds.intersection(bounds).unwrap_or_default(); - scene.push_layer(Some(visible_bounds)); + cx.scene().push_layer(Some(visible_bounds)); - scene.push_mouse_region( + cx.scene().push_mouse_region( MouseRegion::new::(self.view_id, 0, visible_bounds).on_scroll({ let scroll_max = layout.scroll_max; let state = self.state.clone(); @@ -312,11 +311,11 @@ impl Element for UniformList { ); for item in &mut layout.items { - item.paint(scene, item_origin, visible_bounds, view, cx); + item.paint(item_origin, visible_bounds, view, cx); item_origin += vec2f(0.0, layout.item_height); } - scene.pop_layer(); + cx.scene().pop_layer(); } fn rect_for_text_range( diff --git a/crates/gpui/src/scene.rs b/crates/gpui/src/scene.rs index e8b9936d8109c6c3acf22d156e8f360034218f16..9557c6fe910953eacf5d6f7cb6a7113fb43fe239 100644 --- a/crates/gpui/src/scene.rs +++ b/crates/gpui/src/scene.rs @@ -26,7 +26,6 @@ pub use mouse_event::*; pub use mouse_region::*; pub struct SceneBuilder { - scale_factor: f32, stacking_contexts: Vec, active_stacking_context_stack: Vec, /// Used by the gpui2 crate. @@ -245,43 +244,36 @@ impl Scene { } impl SceneBuilder { - pub fn new(scale_factor: f32) -> Self { - let stacking_context = StackingContext::new(None, 0); - SceneBuilder { - scale_factor, - stacking_contexts: vec![stacking_context], - active_stacking_context_stack: vec![0], + pub fn new() -> Self { + let mut this = SceneBuilder { + stacking_contexts: Vec::new(), + active_stacking_context_stack: Vec::new(), #[cfg(debug_assertions)] - mouse_region_ids: Default::default(), + mouse_region_ids: HashSet::default(), event_handlers: Vec::new(), - } + }; + this.clear(); + this } - pub fn build(mut self) -> Scene { - self.stacking_contexts - .sort_by_key(|context| context.z_index); - Scene { - scale_factor: self.scale_factor, - stacking_contexts: self.stacking_contexts, - event_handlers: self.event_handlers, - } + pub fn clear(&mut self) { + self.stacking_contexts.clear(); + self.stacking_contexts.push(StackingContext::new(None, 0)); + self.active_stacking_context_stack.clear(); + self.active_stacking_context_stack.push(0); } - pub fn scale_factor(&self) -> f32 { - self.scale_factor - } + pub fn build(&mut self, scale_factor: f32) -> Scene { + let mut stacking_contexts = std::mem::take(&mut self.stacking_contexts); + stacking_contexts.sort_by_key(|context| context.z_index); + let event_handlers = std::mem::take(&mut self.event_handlers); + self.clear(); - pub fn paint_stacking_context( - &mut self, - clip_bounds: Option, - z_index: Option, - f: F, - ) where - F: FnOnce(&mut Self), - { - self.push_stacking_context(clip_bounds, z_index); - f(self); - self.pop_stacking_context(); + Scene { + scale_factor, + stacking_contexts, + event_handlers, + } } pub fn push_stacking_context(&mut self, clip_bounds: Option, z_index: Option) { @@ -297,15 +289,6 @@ impl SceneBuilder { assert!(!self.active_stacking_context_stack.is_empty()); } - pub fn paint_layer(&mut self, clip_bounds: Option, f: F) - where - F: FnOnce(&mut Self), - { - self.push_layer(clip_bounds); - f(self); - self.pop_layer(); - } - pub fn push_layer(&mut self, clip_bounds: Option) { self.active_stacking_context().push_layer(clip_bounds); } diff --git a/crates/gpui/src/text_layout.rs b/crates/gpui/src/text_layout.rs index d287d639abfb27e31c75d23afcf1604f5eb5ab40..97f4b7a12d7a2aa95159dc049e57c6b5a4eb2e21 100644 --- a/crates/gpui/src/text_layout.rs +++ b/crates/gpui/src/text_layout.rs @@ -9,7 +9,6 @@ use crate::{ platform::FontSystem, scene, window::WindowContext, - SceneBuilder, }; use ordered_float::OrderedFloat; use parking_lot::{Mutex, RwLock, RwLockUpgradableReadGuard}; @@ -284,7 +283,6 @@ impl Line { pub fn paint( &self, - scene: &mut SceneBuilder, origin: Vector2F, visible_bounds: RectF, line_height: f32, @@ -347,7 +345,7 @@ impl Line { } if let Some((underline_origin, underline_style)) = finished_underline { - scene.push_underline(scene::Underline { + cx.scene().push_underline(scene::Underline { origin: underline_origin, width: glyph_origin.x() - underline_origin.x(), thickness: underline_style.thickness.into(), @@ -357,14 +355,14 @@ impl Line { } if glyph.is_emoji { - scene.push_image_glyph(scene::ImageGlyph { + cx.scene().push_image_glyph(scene::ImageGlyph { font_id: run.font_id, font_size: self.layout.font_size, id: glyph.id, origin: glyph_origin, }); } else { - scene.push_glyph(scene::Glyph { + cx.scene().push_glyph(scene::Glyph { font_id: run.font_id, font_size: self.layout.font_size, id: glyph.id, @@ -377,7 +375,7 @@ impl Line { if let Some((underline_start, underline_style)) = underline.take() { let line_end_x = origin.x() + self.layout.width; - scene.push_underline(scene::Underline { + cx.scene().push_underline(scene::Underline { origin: underline_start, width: line_end_x - underline_start.x(), color: underline_style.color.unwrap(), @@ -389,7 +387,6 @@ impl Line { pub fn paint_wrapped( &self, - scene: &mut SceneBuilder, origin: Vector2F, visible_bounds: RectF, line_height: f32, @@ -417,7 +414,7 @@ impl Line { { boundaries.next(); if let Some((underline_origin, underline_style)) = underline { - scene.push_underline(scene::Underline { + cx.scene().push_underline(scene::Underline { origin: underline_origin, width: glyph_origin.x() - underline_origin.x(), thickness: underline_style.thickness.into(), @@ -461,7 +458,7 @@ impl Line { } if let Some((underline_origin, underline_style)) = finished_underline { - scene.push_underline(scene::Underline { + cx.scene().push_underline(scene::Underline { origin: underline_origin, width: glyph_origin.x() - underline_origin.x(), thickness: underline_style.thickness.into(), @@ -477,14 +474,14 @@ impl Line { ); if glyph_bounds.intersects(visible_bounds) { if glyph.is_emoji { - scene.push_image_glyph(scene::ImageGlyph { + cx.scene().push_image_glyph(scene::ImageGlyph { font_id: run.font_id, font_size: self.layout.font_size, id: glyph.id, origin: glyph_bounds.origin() + baseline_offset, }); } else { - scene.push_glyph(scene::Glyph { + cx.scene().push_glyph(scene::Glyph { font_id: run.font_id, font_size: self.layout.font_size, id: glyph.id, @@ -498,7 +495,7 @@ impl Line { if let Some((underline_origin, underline_style)) = underline.take() { let line_end_x = glyph_origin.x() + self.layout.width - prev_position; - scene.push_underline(scene::Underline { + cx.scene().push_underline(scene::Underline { origin: underline_origin, width: line_end_x - underline_origin.x(), thickness: underline_style.thickness.into(), diff --git a/crates/gpui2/src/adapter.rs b/crates/gpui2/src/adapter.rs index d1bc7ac290e3b9ac44eb3e54e8951cbf4a0aba29..e0b5483d06634cee5addd851769dc0ddd2b11281 100644 --- a/crates/gpui2/src/adapter.rs +++ b/crates/gpui2/src/adapter.rs @@ -36,7 +36,6 @@ impl gpui::Element for AdapterElement { fn paint( &mut self, - scene: &mut gpui::SceneBuilder, bounds: RectF, _visible_bounds: RectF, layout_data: &mut Option<(LayoutEngine, LayoutId)>, @@ -45,7 +44,7 @@ impl gpui::Element for AdapterElement { ) -> Self::PaintState { let (layout_engine, layout_id) = layout_data.take().unwrap(); legacy_cx.push_layout_engine(layout_engine); - let mut cx = PaintContext::new(legacy_cx, scene); + let mut cx = PaintContext::new(legacy_cx); self.0.paint(view, bounds.origin(), &mut cx); *layout_data = legacy_cx.pop_layout_engine().zip(Some(layout_id)); debug_assert!(layout_data.is_some()); diff --git a/crates/gpui2/src/elements/div.rs b/crates/gpui2/src/elements/div.rs index f32b22434a87a2db3601af0477d4ae07ab15c379..598b564ab1704e219aa91f519a98b53ef1ae17c7 100644 --- a/crates/gpui2/src/elements/div.rs +++ b/crates/gpui2/src/elements/div.rs @@ -88,7 +88,7 @@ impl Element for Div { // TODO: Support only one dimension being hidden let mut pop_layer = false; if style.overflow.y != Overflow::Visible || style.overflow.x != Overflow::Visible { - cx.scene.push_layer(Some(bounds)); + cx.scene().push_layer(Some(bounds)); pop_layer = true; } @@ -97,7 +97,7 @@ impl Element for Div { } if pop_layer { - cx.scene.pop_layer(); + cx.scene().pop_layer(); } style.paint_foreground(bounds, cx); @@ -221,7 +221,7 @@ impl Div { let hovered = bounds.contains_point(cx.mouse_position()); if hovered { let rem_size = cx.rem_size(); - cx.scene.push_quad(scene::Quad { + cx.scene().push_quad(scene::Quad { bounds, background: Some(hsla(0., 0., 1., 0.05).into()), border: gpui::Border { diff --git a/crates/gpui2/src/elements/img.rs b/crates/gpui2/src/elements/img.rs index a4934c54155eb649c4b975980b90289832add82e..829a6d111655480b270a3a7d75a86ee579d1b0fb 100644 --- a/crates/gpui2/src/elements/img.rs +++ b/crates/gpui2/src/elements/img.rs @@ -70,7 +70,7 @@ impl Element for Img { .and_then(ResultExt::log_err) { let rem_size = cx.rem_size(); - cx.scene.push_image(scene::Image { + cx.scene().push_image(scene::Image { bounds, border: gpui::Border { color: style.border_color.unwrap_or_default().into(), diff --git a/crates/gpui2/src/elements/svg.rs b/crates/gpui2/src/elements/svg.rs index ebf06178aa8c174c63fc65c7adc6e7c694f7ac0e..c17cdbe3c6675c0992a9c9e66d4de47736123620 100644 --- a/crates/gpui2/src/elements/svg.rs +++ b/crates/gpui2/src/elements/svg.rs @@ -63,7 +63,7 @@ impl Element for Svg { color: Rgba::from(fill_color).into(), }; - cx.scene.push_icon(icon); + cx.scene().push_icon(icon); } } } diff --git a/crates/gpui2/src/elements/text.rs b/crates/gpui2/src/elements/text.rs index 97b911201acd4897d5e4c92594de23eb6564f354..3b3acb45231e1ef0678735c51fd0b3aa198da38c 100644 --- a/crates/gpui2/src/elements/text.rs +++ b/crates/gpui2/src/elements/text.rs @@ -92,13 +92,7 @@ impl Element for Text { // TODO: We haven't added visible bounds to the new element system yet, so this is a placeholder. let visible_bounds = bounds; - line.paint( - cx.scene, - bounds.origin(), - visible_bounds, - line_height, - cx.legacy_cx, - ); + line.paint(bounds.origin(), visible_bounds, line_height, cx.legacy_cx); } } diff --git a/crates/gpui2/src/paint_context.rs b/crates/gpui2/src/paint_context.rs index 0760b13cd33396b3d8c14e907c7ea8dc46eca1ae..9f8548d51927b07b80a6dcc6ca8775c8e5c78ba3 100644 --- a/crates/gpui2/src/paint_context.rs +++ b/crates/gpui2/src/paint_context.rs @@ -11,15 +11,11 @@ pub struct PaintContext<'a, 'b, 'c, 'd, V> { #[deref] #[deref_mut] pub(crate) legacy_cx: &'d mut LegacyPaintContext<'a, 'b, 'c, V>, - pub(crate) scene: &'d mut gpui::SceneBuilder, } impl<'a, 'b, 'c, 'd, V: 'static> PaintContext<'a, 'b, 'c, 'd, V> { - pub fn new( - legacy_cx: &'d mut LegacyPaintContext<'a, 'b, 'c, V>, - scene: &'d mut gpui::SceneBuilder, - ) -> Self { - Self { legacy_cx, scene } + pub fn new(legacy_cx: &'d mut LegacyPaintContext<'a, 'b, 'c, V>) -> Self { + Self { legacy_cx } } pub fn on_event( @@ -29,7 +25,7 @@ impl<'a, 'b, 'c, 'd, V: 'static> PaintContext<'a, 'b, 'c, 'd, V> { ) { let view = self.weak_handle(); - self.scene.event_handlers.push(EventHandler { + self.scene().event_handlers.push(EventHandler { order, handler: Rc::new(move |event, window_cx| { if let Some(view) = view.upgrade(window_cx) { diff --git a/crates/gpui2/src/style.rs b/crates/gpui2/src/style.rs index 790cea6614caf9878060f6d8de60b26451f6df87..8a02dda5d76afd62ee9ae4e0d7262bfefcd190e3 100644 --- a/crates/gpui2/src/style.rs +++ b/crates/gpui2/src/style.rs @@ -167,7 +167,7 @@ impl Style { pub fn paint_background(&self, bounds: RectF, cx: &mut PaintContext) { let rem_size = cx.rem_size(); if let Some(color) = self.fill.as_ref().and_then(Fill::color) { - cx.scene.push_quad(gpui::Quad { + cx.scene().push_quad(gpui::Quad { bounds, background: Some(color.into()), corner_radii: self.corner_radii.to_gpui(bounds.size(), rem_size), @@ -183,7 +183,7 @@ impl Style { if let Some(color) = self.border_color { let border = self.border_widths.to_pixels(rem_size); if !border.is_empty() { - cx.scene.push_quad(gpui::Quad { + cx.scene().push_quad(gpui::Quad { bounds, background: None, corner_radii: self.corner_radii.to_gpui(bounds.size(), rem_size), diff --git a/crates/gpui_macros/src/gpui_macros.rs b/crates/gpui_macros/src/gpui_macros.rs index 16f293afbe286bcf2529125909e317ea5811fa82..b712aace69f493a537ae06bba098e580e87b7c36 100644 --- a/crates/gpui_macros/src/gpui_macros.rs +++ b/crates/gpui_macros/src/gpui_macros.rs @@ -338,14 +338,13 @@ pub fn element_derive(input: TokenStream) -> TokenStream { fn paint( &mut self, - scene: &mut gpui::SceneBuilder, bounds: gpui::geometry::rect::RectF, visible_bounds: gpui::geometry::rect::RectF, element: &mut gpui::elements::AnyElement, view: &mut V, cx: &mut gpui::PaintContext, ) { - element.paint(scene, bounds.origin(), visible_bounds, view, cx); + element.paint(bounds.origin(), visible_bounds, view, cx); } fn rect_for_text_range( diff --git a/crates/terminal_view/src/terminal_element.rs b/crates/terminal_view/src/terminal_element.rs index b3d87f531ad5794b86f4b56dbe307e3078a5ffd3..7892dfe70e64f791db9a28254121e4ea63d96514 100644 --- a/crates/terminal_view/src/terminal_element.rs +++ b/crates/terminal_view/src/terminal_element.rs @@ -11,8 +11,8 @@ use gpui::{ serde_json::json, text_layout::{Line, RunStyle}, AnyElement, Element, EventContext, FontCache, LayoutContext, ModelContext, MouseRegion, - PaintContext, Quad, SceneBuilder, SizeConstraint, TextLayoutCache, ViewContext, - WeakModelHandle, + PaintContext, Quad, SizeConstraint, TextLayoutCache, ViewContext, WeakModelHandle, + WindowContext, }; use itertools::Itertools; use language::CursorShape; @@ -86,12 +86,11 @@ impl LayoutCell { fn paint( &self, - scene: &mut SceneBuilder, origin: Vector2F, layout: &LayoutState, visible_bounds: RectF, _view: &mut TerminalView, - cx: &mut ViewContext, + cx: &mut WindowContext, ) { let pos = { let point = self.point; @@ -102,7 +101,7 @@ impl LayoutCell { }; self.text - .paint(scene, pos, visible_bounds, layout.size.line_height, cx); + .paint(pos, visible_bounds, layout.size.line_height, cx); } } @@ -132,11 +131,10 @@ impl LayoutRect { fn paint( &self, - scene: &mut SceneBuilder, origin: Vector2F, layout: &LayoutState, _view: &mut TerminalView, - _cx: &mut ViewContext, + cx: &mut ViewContext, ) { let position = { let point = self.point; @@ -150,7 +148,7 @@ impl LayoutRect { layout.size.line_height, ); - scene.push_quad(Quad { + cx.scene().push_quad(Quad { bounds: RectF::new(position, size), background: Some(self.color), border: Default::default(), @@ -387,7 +385,6 @@ impl TerminalElement { fn attach_mouse_handlers( &self, - scene: &mut SceneBuilder, origin: Vector2F, visible_bounds: RectF, mode: TermMode, @@ -518,7 +515,7 @@ impl TerminalElement { ) } - scene.push_mouse_region(region); + cx.scene().push_mouse_region(region); } } @@ -733,7 +730,6 @@ impl Element for TerminalElement { fn paint( &mut self, - scene: &mut SceneBuilder, bounds: RectF, visible_bounds: RectF, layout: &mut Self::LayoutState, @@ -745,13 +741,13 @@ impl Element for TerminalElement { //Setup element stuff let clip_bounds = Some(visible_bounds); - scene.paint_layer(clip_bounds, |scene| { + cx.paint_layer(clip_bounds, |cx| { let origin = bounds.origin() + vec2f(layout.gutter, 0.); // Elements are ephemeral, only at paint time do we know what could be clicked by a mouse - self.attach_mouse_handlers(scene, origin, visible_bounds, layout.mode, cx); + self.attach_mouse_handlers(origin, visible_bounds, layout.mode, cx); - scene.push_cursor_region(gpui::CursorRegion { + cx.scene().push_cursor_region(gpui::CursorRegion { bounds, style: if layout.hyperlink_tooltip.is_some() { CursorStyle::PointingHand @@ -760,9 +756,9 @@ impl Element for TerminalElement { }, }); - scene.paint_layer(clip_bounds, |scene| { + cx.paint_layer(clip_bounds, |cx| { //Start with a background color - scene.push_quad(Quad { + cx.scene().push_quad(Quad { bounds: RectF::new(bounds.origin(), bounds.size()), background: Some(layout.background_color), border: Default::default(), @@ -770,12 +766,12 @@ impl Element for TerminalElement { }); for rect in &layout.rects { - rect.paint(scene, origin, layout, view, cx) + rect.paint(origin, layout, view, cx); } }); //Draw Highlighted Backgrounds - scene.paint_layer(clip_bounds, |scene| { + cx.paint_layer(clip_bounds, |cx| { for (relative_highlighted_range, color) in layout.relative_highlighted_ranges.iter() { if let Some((start_y, highlighted_range_lines)) = @@ -789,29 +785,29 @@ impl Element for TerminalElement { //Copied from editor. TODO: move to theme or something corner_radius: 0.15 * layout.size.line_height, }; - hr.paint(bounds, scene); + hr.paint(bounds, cx); } } }); //Draw the text cells - scene.paint_layer(clip_bounds, |scene| { + cx.paint_layer(clip_bounds, |cx| { for cell in &layout.cells { - cell.paint(scene, origin, layout, visible_bounds, view, cx); + cell.paint(origin, layout, visible_bounds, view, cx); } }); //Draw cursor if self.cursor_visible { if let Some(cursor) = &layout.cursor { - scene.paint_layer(clip_bounds, |scene| { - cursor.paint(scene, origin, cx); + cx.paint_layer(clip_bounds, |cx| { + cursor.paint(origin, cx); }) } } if let Some(element) = &mut layout.hyperlink_tooltip { - element.paint(scene, origin, visible_bounds, view, cx) + element.paint(origin, visible_bounds, view, cx) } }); } diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index fe3173ac9b92dbe27a4b4c3d36987c8c6b0ab634..d31f0d9749b3af4ac0d36d00803232607d92b842 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -1440,10 +1440,10 @@ impl Pane { None }; - Canvas::new(move |scene, bounds, _, _, _| { + Canvas::new(move |bounds, _, _, cx| { if let Some(color) = icon_color { let square = RectF::new(bounds.origin(), vec2f(diameter, diameter)); - scene.push_quad(Quad { + cx.scene().push_quad(Quad { bounds: square, background: Some(color), border: Default::default(), @@ -2007,7 +2007,6 @@ impl Element for PaneBackdrop { fn paint( &mut self, - scene: &mut gpui::SceneBuilder, bounds: RectF, visible_bounds: RectF, _: &mut Self::LayoutState, @@ -2018,14 +2017,14 @@ impl Element for PaneBackdrop { let visible_bounds = bounds.intersection(visible_bounds).unwrap_or_default(); - scene.push_quad(gpui::Quad { + cx.scene().push_quad(gpui::Quad { bounds: RectF::new(bounds.origin(), bounds.size()), background: Some(background), ..Default::default() }); let child_view_id = self.child_view; - scene.push_mouse_region( + cx.scene().push_mouse_region( MouseRegion::new::(child_view_id, 0, visible_bounds).on_down( gpui::platform::MouseButton::Left, move |_, _: &mut V, cx| { @@ -2035,10 +2034,9 @@ impl Element for PaneBackdrop { ), ); - scene.paint_layer(Some(bounds), |scene| { - self.child - .paint(scene, bounds.origin(), visible_bounds, view, cx) - }) + cx.scene().push_layer(Some(bounds)); + self.child.paint(bounds.origin(), visible_bounds, view, cx); + cx.scene().pop_layer(); } fn rect_for_text_range( diff --git a/crates/workspace/src/pane/dragged_item_receiver.rs b/crates/workspace/src/pane/dragged_item_receiver.rs index bbe391b5b543dbc698385c10d34f4f6f8e946505..e4d0a636b825b1c8016bf9f013c6ba40e20d71f0 100644 --- a/crates/workspace/src/pane/dragged_item_receiver.rs +++ b/crates/workspace/src/pane/dragged_item_receiver.rs @@ -50,7 +50,7 @@ where Stack::new() .with_child(render_child(state, cx)) .with_children(drag_position.map(|drag_position| { - Canvas::new(move |scene, bounds, _, _, cx| { + Canvas::new(move |bounds, _, _, cx| { if bounds.contains_point(drag_position) { let overlay_region = split_margin .and_then(|split_margin| { @@ -60,14 +60,15 @@ where .map(|(dir, margin)| dir.along_edge(bounds, margin)) .unwrap_or(bounds); - scene.paint_stacking_context(None, None, |scene| { - scene.push_quad(Quad { - bounds: overlay_region, - background: Some(overlay_color(cx)), - border: Default::default(), - corner_radii: Default::default(), - }); + cx.scene().push_stacking_context(None, None); + let background = overlay_color(cx); + cx.scene().push_quad(Quad { + bounds: overlay_region, + background: Some(background), + border: Default::default(), + corner_radii: Default::default(), }); + cx.scene().pop_stacking_context(); } }) })) diff --git a/crates/workspace/src/pane_group.rs b/crates/workspace/src/pane_group.rs index aa6ca143dfc4b982f8d458e19112edfe47c13387..9747bda2d5fe93c39c8bc55c83746f6a1c7e42e3 100644 --- a/crates/workspace/src/pane_group.rs +++ b/crates/workspace/src/pane_group.rs @@ -595,7 +595,7 @@ mod element { platform::{CursorStyle, MouseButton}, scene::MouseDrag, AnyElement, Axis, CursorRegion, Element, EventContext, LayoutContext, MouseRegion, - PaintContext, RectFExt, SceneBuilder, SizeConstraint, Vector2FExt, ViewContext, + PaintContext, RectFExt, SizeConstraint, Vector2FExt, ViewContext, }; use crate::{ @@ -851,7 +851,6 @@ mod element { fn paint( &mut self, - scene: &mut SceneBuilder, bounds: RectF, visible_bounds: RectF, remaining_space: &mut Self::LayoutState, @@ -863,7 +862,7 @@ mod element { let overflowing = *remaining_space < 0.; if overflowing { - scene.push_layer(Some(visible_bounds)); + cx.scene().push_layer(Some(visible_bounds)); } let mut child_origin = bounds.origin(); @@ -874,7 +873,7 @@ mod element { let mut children_iter = self.children.iter_mut().enumerate().peekable(); while let Some((ix, child)) = children_iter.next() { let child_start = child_origin.clone(); - child.paint(scene, child_origin, visible_bounds, view, cx); + child.paint(child_origin, visible_bounds, view, cx); bounding_boxes.push(Some(RectF::new(child_origin, child.size()))); @@ -884,7 +883,7 @@ mod element { } if can_resize && children_iter.peek().is_some() { - scene.push_stacking_context(None, None); + cx.scene().push_stacking_context(None, None); let handle_origin = match self.axis { Axis::Horizontal => child_origin - vec2f(HANDLE_HITBOX_SIZE / 2., 0.0), @@ -907,7 +906,7 @@ mod element { Axis::Vertical => CursorStyle::ResizeUpDown, }; - scene.push_cursor_region(CursorRegion { + cx.scene().push_cursor_region(CursorRegion { bounds: handle_bounds, style, }); @@ -940,14 +939,14 @@ mod element { } } }); - scene.push_mouse_region(mouse_region); + cx.scene().push_mouse_region(mouse_region); - scene.pop_stacking_context(); + cx.scene().pop_stacking_context(); } } if overflowing { - scene.pop_layer(); + cx.scene().pop_layer(); } } diff --git a/crates/workspace/src/shared_screen.rs b/crates/workspace/src/shared_screen.rs index 10a466cb61b92fdb98c1114126bc12cc43df0252..7b97174dfee71eb2ea43514f2fea4b26e7a308f0 100644 --- a/crates/workspace/src/shared_screen.rs +++ b/crates/workspace/src/shared_screen.rs @@ -73,14 +73,14 @@ impl View for SharedScreen { let frame = self.frame.clone(); MouseEventHandler::new::(0, cx, |_, cx| { - Canvas::new(move |scene, bounds, _, _, _| { + Canvas::new(move |bounds, _, _, cx| { if let Some(frame) = frame.clone() { let size = constrain_size_preserving_aspect_ratio( bounds.size(), vec2f(frame.width() as f32, frame.height() as f32), ); let origin = bounds.origin() + (bounds.size() / 2.) - size / 2.; - scene.push_surface(gpui::platform::mac::Surface { + cx.scene().push_surface(gpui::platform::mac::Surface { bounds: RectF::new(origin, size), image_buffer: frame.image(), }); diff --git a/crates/workspace/src/status_bar.rs b/crates/workspace/src/status_bar.rs index 81925f309030a6217c2ce0fa2796fd0f249bbbcc..c05b93ff9559bcd98714f4660e1e4e8f9b227393 100644 --- a/crates/workspace/src/status_bar.rs +++ b/crates/workspace/src/status_bar.rs @@ -8,8 +8,8 @@ use gpui::{ vector::{vec2f, Vector2F}, }, json::{json, ToJson}, - AnyElement, AnyViewHandle, Entity, LayoutContext, PaintContext, SceneBuilder, SizeConstraint, - Subscription, View, ViewContext, ViewHandle, WindowContext, + AnyElement, AnyViewHandle, Entity, LayoutContext, PaintContext, SizeConstraint, Subscription, + View, ViewContext, ViewHandle, WindowContext, }; pub trait StatusItemView: View { @@ -226,7 +226,6 @@ impl Element for StatusBarElement { fn paint( &mut self, - scene: &mut SceneBuilder, bounds: RectF, visible_bounds: RectF, _: &mut Self::LayoutState, @@ -237,12 +236,10 @@ impl Element for StatusBarElement { let visible_bounds = bounds.intersection(visible_bounds).unwrap_or_default(); let left_origin = vec2f(bounds.lower_left().x(), origin_y); - self.left - .paint(scene, left_origin, visible_bounds, view, cx); + self.left.paint(left_origin, visible_bounds, view, cx); let right_origin = vec2f(bounds.upper_right().x() - self.right.size().x(), origin_y); - self.right - .paint(scene, right_origin, visible_bounds, view, cx); + self.right.paint(right_origin, visible_bounds, view, cx); } fn rect_for_text_range( diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index be8148256d0b0f294bbeeafbcfb59e47ec4862d7..953a52928173601c962307074746fd8717755215 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -3626,13 +3626,13 @@ fn notify_of_new_dock(workspace: &WeakViewHandle, cx: &mut AsyncAppCo "Looking for the dock? Try ctrl-`!\nshift-escape now zooms your pane.", text, ) - .with_custom_runs(vec![26..32, 34..46], |_, bounds, scene, cx| { + .with_custom_runs(vec![26..32, 34..46], |_, bounds, cx| { let code_span_background_color = settings::get::(cx) .theme .editor .document_highlight_read_background; - scene.push_quad(gpui::Quad { + cx.scene().push_quad(gpui::Quad { bounds, background: Some(code_span_background_color), border: Default::default(), From 8dd6fcc18625bdeae9280a9fe111a0205ac6fcf5 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Fri, 8 Sep 2023 22:16:12 -0400 Subject: [PATCH 02/10] Add icon_button --- crates/storybook/src/component/icon_button.rs | 54 +++++++++++++++++++ crates/storybook/src/component/mod.rs | 1 + crates/storybook/src/storybook.rs | 3 +- crates/storybook/src/workspace.rs | 16 +++++- 4 files changed, 71 insertions(+), 3 deletions(-) create mode 100644 crates/storybook/src/component/icon_button.rs create mode 100644 crates/storybook/src/component/mod.rs diff --git a/crates/storybook/src/component/icon_button.rs b/crates/storybook/src/component/icon_button.rs new file mode 100644 index 0000000000000000000000000000000000000000..9e8df098be0616b03ac533f6f3455aa10e428d59 --- /dev/null +++ b/crates/storybook/src/component/icon_button.rs @@ -0,0 +1,54 @@ +use crate::theme::theme; +use gpui2::elements::svg; +use gpui2::style::{StyleHelpers, Styleable}; +use gpui2::{elements::div, IntoElement}; +use gpui2::{Element, ParentElement, ViewContext}; + +#[derive(Element)] +struct IconButton { + path: &'static str, + variant: Variant, +} + +#[derive(PartialEq)] +pub enum Variant { + Ghost, + Filled, +} + +pub fn icon_button(path: &'static str, variant: Variant) -> impl Element { + IconButton { path, variant } +} + +impl IconButton { + fn render(&mut self, _: &mut V, cx: &mut ViewContext) -> impl IntoElement { + let theme = theme(cx); + let mut div = div(); + + if self.variant == Variant::Filled { + div = div.fill(theme.middle.base.default.background); + } + + div.w_7() + .h_6() + .flex() + .items_center() + .justify_center() + .rounded_md() + .border() + .border_color(theme.middle.base.default.background) + .hover() + .fill(theme.middle.base.hovered.background) + .border_color(theme.middle.variant.hovered.border) + .active() + .fill(theme.middle.base.pressed.background) + .border_color(theme.middle.variant.pressed.border) + .child( + svg() + .path(self.path) + .w_4() + .h_4() + .fill(theme.middle.variant.default.foreground), + ) + } +} diff --git a/crates/storybook/src/component/mod.rs b/crates/storybook/src/component/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..e26b06c8ddba01bdc522f6d8c1aa5d6263276be0 --- /dev/null +++ b/crates/storybook/src/component/mod.rs @@ -0,0 +1 @@ +pub(crate) mod icon_button; diff --git a/crates/storybook/src/storybook.rs b/crates/storybook/src/storybook.rs index 04e1038988fc640d54a2d1d289319af7c832d7c2..7f9aa8667238cc8865027830829985ffaa704436 100644 --- a/crates/storybook/src/storybook.rs +++ b/crates/storybook/src/storybook.rs @@ -10,6 +10,7 @@ use settings::{default_settings, SettingsStore}; use simplelog::SimpleLogger; mod collab_panel; +mod component; mod components; mod element_ext; mod theme; @@ -40,7 +41,7 @@ fn main() { }, |cx| { view(|cx| { - cx.enable_inspector(); + // cx.enable_inspector(); storybook(&mut ViewContext::new(cx)) }) }, diff --git a/crates/storybook/src/workspace.rs b/crates/storybook/src/workspace.rs index d9f9c22fcb41f73856c8ebb6be9b0d0024d48780..441a4c68fa1f8078d131f26e97e771d36d2b20ba 100644 --- a/crates/storybook/src/workspace.rs +++ b/crates/storybook/src/workspace.rs @@ -1,4 +1,8 @@ -use crate::{collab_panel::collab_panel, theme::theme}; +use crate::{ + collab_panel::collab_panel, + component::icon_button::{icon_button, Variant}, + theme::theme, +}; use gpui2::{ elements::{div, div::ScrollState, img, svg}, style::{StyleHelpers, Styleable}, @@ -38,7 +42,15 @@ impl WorkspaceElement { .flex_row() .overflow_hidden() .child(collab_panel(self.left_scroll_state.clone())) - .child(div().h_full().flex_1()) + .child( + div().h_full().flex_1().child( + div() + .w_24() + .h_24() + .child(icon_button("icons/plus.svg", Variant::Ghost)) + .child(icon_button("icons/x.svg", Variant::Filled)), + ), + ) .child(collab_panel(self.right_scroll_state.clone())), ) .child(statusbar()) From 5ad9a6bb3c8c198296d62424ae0ef4be08ce4fae Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Sat, 9 Sep 2023 11:29:31 -0400 Subject: [PATCH 03/10] Add docs for `styleable_helpers` proc macros --- crates/gpui2_macros/src/styleable_helpers.rs | 163 +++++++++---------- 1 file changed, 81 insertions(+), 82 deletions(-) diff --git a/crates/gpui2_macros/src/styleable_helpers.rs b/crates/gpui2_macros/src/styleable_helpers.rs index ae7b2d3b1b8dcc13eeaacadf00cbe2cfd0cd716c..121e3fe12b78fbc7d5efbb688154198c042a989d 100644 --- a/crates/gpui2_macros/src/styleable_helpers.rs +++ b/crates/gpui2_macros/src/styleable_helpers.rs @@ -28,24 +28,24 @@ fn generate_methods() -> Vec { let mut methods = Vec::new(); for (prefix, auto_allowed, fields) in box_prefixes() { - for (suffix, length_tokens) in box_suffixes() { + for (suffix, length_tokens, doc_string) in box_suffixes() { if auto_allowed || suffix != "auto" { - let method = generate_method(prefix, suffix, &fields, length_tokens); + let method = generate_method(prefix, suffix, &fields, length_tokens, doc_string); methods.push(method); } } } for (prefix, fields) in corner_prefixes() { - for (suffix, radius_tokens) in corner_suffixes() { - let method = generate_method(prefix, suffix, &fields, radius_tokens); + for (suffix, radius_tokens, doc_string) in corner_suffixes() { + let method = generate_method(prefix, suffix, &fields, radius_tokens, doc_string); methods.push(method); } } for (prefix, fields) in border_prefixes() { - for (suffix, width_tokens) in border_suffixes() { - let method = generate_method(prefix, suffix, &fields, width_tokens); + for (suffix, width_tokens, doc_string) in border_suffixes() { + let method = generate_method(prefix, suffix, &fields, width_tokens, doc_string); methods.push(method); } } @@ -58,6 +58,7 @@ fn generate_method( suffix: &'static str, fields: &Vec, length_tokens: TokenStream2, + doc_string: &'static str, ) -> TokenStream2 { let method_name = if suffix.is_empty() { format_ident!("{}", prefix) @@ -75,6 +76,7 @@ fn generate_method( .collect::>(); let method = quote! { + #[doc = #doc_string] fn #method_name(mut self) -> Self where Self: std::marker::Sized { let mut style = self.declared_style(); #(#field_assignments)* @@ -160,55 +162,52 @@ fn box_prefixes() -> Vec<(&'static str, bool, Vec)> { ] } -fn box_suffixes() -> Vec<(&'static str, TokenStream2)> { +fn box_suffixes() -> Vec<(&'static str, TokenStream2, &'static str)> { vec![ - ("0", quote! { pixels(0.) }), - ("0p5", quote! { rems(0.125) }), - ("1", quote! { rems(0.25) }), - ("1p5", quote! { rems(0.375) }), - ("2", quote! { rems(0.5) }), - ("2p5", quote! { rems(0.625) }), - ("3", quote! { rems(0.75) }), - ("3p5", quote! { rems(0.875) }), - ("4", quote! { rems(1.) }), - ("5", quote! { rems(1.25) }), - ("6", quote! { rems(1.5) }), - ("7", quote! { rems(1.75) }), - ("8", quote! { rems(2.0) }), - ("9", quote! { rems(2.25) }), - ("10", quote! { rems(2.5) }), - ("11", quote! { rems(2.75) }), - ("12", quote! { rems(3.) }), - ("16", quote! { rems(4.) }), - ("20", quote! { rems(5.) }), - ("24", quote! { rems(6.) }), - ("32", quote! { rems(8.) }), - ("40", quote! { rems(10.) }), - ("48", quote! { rems(12.) }), - ("56", quote! { rems(14.) }), - ("64", quote! { rems(16.) }), - ("72", quote! { rems(18.) }), - ("80", quote! { rems(20.) }), - ("96", quote! { rems(24.) }), - ("auto", quote! { auto() }), - ("px", quote! { pixels(1.) }), - ("full", quote! { relative(1.) }), - ("1_2", quote! { relative(0.5) }), - ("1_3", quote! { relative(1./3.) }), - ("2_3", quote! { relative(2./3.) }), - ("1_4", quote! { relative(0.25) }), - ("2_4", quote! { relative(0.5) }), - ("3_4", quote! { relative(0.75) }), - ("1_5", quote! { relative(0.2) }), - ("2_5", quote! { relative(0.4) }), - ("3_5", quote! { relative(0.6) }), - ("4_5", quote! { relative(0.8) }), - ("1_6", quote! { relative(1./6.) }), - ("5_6", quote! { relative(5./6.) }), - ("1_12", quote! { relative(1./12.) }), - // ("screen_50", quote! { DefiniteLength::Vh(50.0) }), - // ("screen_75", quote! { DefiniteLength::Vh(75.0) }), - // ("screen", quote! { DefiniteLength::Vh(100.0) }), + ("0", quote! { pixels(0.) }, "0px"), + ("0p5", quote! { rems(0.125) }, "2px (0.125rem)"), + ("1", quote! { rems(0.25) }, "4px (0.25rem)"), + ("1p5", quote! { rems(0.375) }, "6px (0.375rem)"), + ("2", quote! { rems(0.5) }, "8px (0.5rem)"), + ("2p5", quote! { rems(0.625) }, "10px (0.625rem)"), + ("3", quote! { rems(0.75) }, "12px (0.75rem)"), + ("3p5", quote! { rems(0.875) }, "14px (0.875rem)"), + ("4", quote! { rems(1.) }, "16px (1rem)"), + ("5", quote! { rems(1.25) }, "20px (1.25rem)"), + ("6", quote! { rems(1.5) }, "24px (1.5rem)"), + ("7", quote! { rems(1.75) }, "28px (1.77rem)"), + ("8", quote! { rems(2.0) }, "32px (2rem)"), + ("9", quote! { rems(2.25) }, "36px (2.25rem)"), + ("10", quote! { rems(2.5) }, "40px (2.5rem)"), + ("11", quote! { rems(2.75) }, "44px (2.75rem)"), + ("12", quote! { rems(3.) }, "48px (3rem)"), + ("16", quote! { rems(4.) }, "64px (4rem)"), + ("20", quote! { rems(5.) }, "80px (5rem)"), + ("24", quote! { rems(6.) }, "96px (6rem)"), + ("32", quote! { rems(8.) }, "128px (8rem)"), + ("40", quote! { rems(10.) }, "160px (10rem)"), + ("48", quote! { rems(12.) }, "192px (12rem)"), + ("56", quote! { rems(14.) }, "224px (14rem)"), + ("64", quote! { rems(16.) }, "256px (16rem)"), + ("72", quote! { rems(18.) }, "288px (18rem)"), + ("80", quote! { rems(20.) }, "320px (20rem)"), + ("96", quote! { rems(24.) }, "384px (24rem)"), + ("auto", quote! { auto() }, "Auto"), + ("px", quote! { pixels(1.) }, "1px"), + ("full", quote! { relative(1.) }, "100%"), + ("1_2", quote! { relative(0.5) }, "50% (1/2)"), + ("1_3", quote! { relative(1./3.) }, "33% (1/3)"), + ("2_3", quote! { relative(2./3.) }, "66% (2/3)"), + ("1_4", quote! { relative(0.25) }, "25% (1/4)"), + ("2_4", quote! { relative(0.5) }, "50% (2/4)"), + ("3_4", quote! { relative(0.75) }, "75% (3/4)"), + ("1_5", quote! { relative(0.2) }, "20% (1/5)"), + ("2_5", quote! { relative(0.4) }, "40% (2/5)"), + ("3_5", quote! { relative(0.6) }, "60% (3/5)"), + ("4_5", quote! { relative(0.8) }, "80% (4/5)"), + ("1_6", quote! { relative(1./6.) }, "16% (1/6)"), + ("5_6", quote! { relative(5./6.) }, "80% (5/6)"), + ("1_12", quote! { relative(1./12.) }, "8% (1/12)"), ] } @@ -258,16 +257,16 @@ fn corner_prefixes() -> Vec<(&'static str, Vec)> { ] } -fn corner_suffixes() -> Vec<(&'static str, TokenStream2)> { +fn corner_suffixes() -> Vec<(&'static str, TokenStream2, &'static str)> { vec![ - ("none", quote! { pixels(0.) }), - ("sm", quote! { rems(0.125) }), - ("md", quote! { rems(0.25) }), - ("lg", quote! { rems(0.5) }), - ("xl", quote! { rems(0.75) }), - ("2xl", quote! { rems(1.) }), - ("3xl", quote! { rems(1.5) }), - ("full", quote! { pixels(9999.) }), + ("none", quote! { pixels(0.) }, "0px"), + ("sm", quote! { rems(0.125) }, "2px (0.125rem)"), + ("md", quote! { rems(0.25) }, "4px (0.25rem)"), + ("lg", quote! { rems(0.5) }, "8px (0.5rem)"), + ("xl", quote! { rems(0.75) }, "12px (0.75rem)"), + ("2xl", quote! { rems(1.) }, "16px (1rem)"), + ("3xl", quote! { rems(1.5) }, "24px (1.5rem)"), + ("full", quote! { pixels(9999.) }, "9999px"), ] } @@ -303,25 +302,25 @@ fn border_prefixes() -> Vec<(&'static str, Vec)> { ] } -fn border_suffixes() -> Vec<(&'static str, TokenStream2)> { +fn border_suffixes() -> Vec<(&'static str, TokenStream2, &'static str)> { vec![ - ("", quote! { pixels(1.) }), - ("0", quote! { pixels(0.) }), - ("1", quote! { pixels(1.) }), - ("2", quote! { pixels(2.) }), - ("3", quote! { pixels(3.) }), - ("4", quote! { pixels(4.) }), - ("5", quote! { pixels(5.) }), - ("6", quote! { pixels(6.) }), - ("7", quote! { pixels(7.) }), - ("8", quote! { pixels(8.) }), - ("9", quote! { pixels(9.) }), - ("10", quote! { pixels(10.) }), - ("11", quote! { pixels(11.) }), - ("12", quote! { pixels(12.) }), - ("16", quote! { pixels(16.) }), - ("20", quote! { pixels(20.) }), - ("24", quote! { pixels(24.) }), - ("32", quote! { pixels(32.) }), + ("", quote! { pixels(1.)}, "1px"), + ("0", quote! { pixels(0.)}, "0px"), + ("1", quote! { pixels(1.) }, "1px"), + ("2", quote! { pixels(2.) }, "2px"), + ("3", quote! { pixels(3.) }, "3px"), + ("4", quote! { pixels(4.) }, "4px"), + ("5", quote! { pixels(5.) }, "5px"), + ("6", quote! { pixels(6.) }, "6px"), + ("7", quote! { pixels(7.) }, "7px"), + ("8", quote! { pixels(8.) }, "8px"), + ("9", quote! { pixels(9.) }, "9px"), + ("10", quote! { pixels(10.) }, "10px"), + ("11", quote! { pixels(11.) }, "11px"), + ("12", quote! { pixels(12.) }, "12px"), + ("16", quote! { pixels(16.) }, "16px"), + ("20", quote! { pixels(20.) }, "20px"), + ("24", quote! { pixels(24.) }, "24px"), + ("32", quote! { pixels(32.) }, "32px"), ] } From 69f380b689f0eddcdcc660ecea73e647fb509681 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Sat, 9 Sep 2023 11:30:35 -0400 Subject: [PATCH 04/10] Fix doc typo --- crates/gpui2_macros/src/styleable_helpers.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/gpui2_macros/src/styleable_helpers.rs b/crates/gpui2_macros/src/styleable_helpers.rs index 121e3fe12b78fbc7d5efbb688154198c042a989d..d5d76ff33b195254ad99ce75a4dbdd33abfdc6b3 100644 --- a/crates/gpui2_macros/src/styleable_helpers.rs +++ b/crates/gpui2_macros/src/styleable_helpers.rs @@ -175,7 +175,7 @@ fn box_suffixes() -> Vec<(&'static str, TokenStream2, &'static str)> { ("4", quote! { rems(1.) }, "16px (1rem)"), ("5", quote! { rems(1.25) }, "20px (1.25rem)"), ("6", quote! { rems(1.5) }, "24px (1.5rem)"), - ("7", quote! { rems(1.75) }, "28px (1.77rem)"), + ("7", quote! { rems(1.75) }, "28px (1.75rem)"), ("8", quote! { rems(2.0) }, "32px (2rem)"), ("9", quote! { rems(2.25) }, "36px (2.25rem)"), ("10", quote! { rems(2.5) }, "40px (2.5rem)"), From 9bb8eae9850b12906c7798800dee04ccf17a37bd Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Sat, 9 Sep 2023 13:38:57 -0400 Subject: [PATCH 05/10] init `tab_bar` --- crates/storybook/src/component/icon_button.rs | 20 ++--- crates/storybook/src/component/mod.rs | 1 + crates/storybook/src/component/tab.rs | 56 ++++++++++++ crates/storybook/src/module/mod.rs | 1 + crates/storybook/src/module/tab_bar.rs | 89 +++++++++++++++++++ crates/storybook/src/storybook.rs | 1 + crates/storybook/src/workspace.rs | 30 +++---- 7 files changed, 171 insertions(+), 27 deletions(-) create mode 100644 crates/storybook/src/component/tab.rs create mode 100644 crates/storybook/src/module/mod.rs create mode 100644 crates/storybook/src/module/tab_bar.rs diff --git a/crates/storybook/src/component/icon_button.rs b/crates/storybook/src/component/icon_button.rs index 9e8df098be0616b03ac533f6f3455aa10e428d59..50241acbe8ef09544ab23a7230fa62c7058af10f 100644 --- a/crates/storybook/src/component/icon_button.rs +++ b/crates/storybook/src/component/icon_button.rs @@ -7,16 +7,16 @@ use gpui2::{Element, ParentElement, ViewContext}; #[derive(Element)] struct IconButton { path: &'static str, - variant: Variant, + variant: ButtonVariant, } #[derive(PartialEq)] -pub enum Variant { +pub enum ButtonVariant { Ghost, Filled, } -pub fn icon_button(path: &'static str, variant: Variant) -> impl Element { +pub fn icon_button(path: &'static str, variant: ButtonVariant) -> impl Element { IconButton { path, variant } } @@ -25,8 +25,8 @@ impl IconButton { let theme = theme(cx); let mut div = div(); - if self.variant == Variant::Filled { - div = div.fill(theme.middle.base.default.background); + if self.variant == ButtonVariant::Filled { + div = div.fill(theme.highest.base.default.background); } div.w_7() @@ -35,20 +35,16 @@ impl IconButton { .items_center() .justify_center() .rounded_md() - .border() - .border_color(theme.middle.base.default.background) .hover() - .fill(theme.middle.base.hovered.background) - .border_color(theme.middle.variant.hovered.border) + .fill(theme.highest.base.hovered.background) .active() - .fill(theme.middle.base.pressed.background) - .border_color(theme.middle.variant.pressed.border) + .fill(theme.highest.base.pressed.background) .child( svg() .path(self.path) .w_4() .h_4() - .fill(theme.middle.variant.default.foreground), + .fill(theme.highest.variant.default.foreground), ) } } diff --git a/crates/storybook/src/component/mod.rs b/crates/storybook/src/component/mod.rs index e26b06c8ddba01bdc522f6d8c1aa5d6263276be0..c45b936e9624305448466817d07fa9a127bd2794 100644 --- a/crates/storybook/src/component/mod.rs +++ b/crates/storybook/src/component/mod.rs @@ -1 +1,2 @@ pub(crate) mod icon_button; +pub(crate) mod tab; diff --git a/crates/storybook/src/component/tab.rs b/crates/storybook/src/component/tab.rs new file mode 100644 index 0000000000000000000000000000000000000000..91a0fb1be1c9b08dcae6c5cb32b2cfb57d6329d0 --- /dev/null +++ b/crates/storybook/src/component/tab.rs @@ -0,0 +1,56 @@ +use crate::theme::theme; +use gpui2::elements::svg; +use gpui2::style::{StyleHelpers, Styleable}; +use gpui2::{elements::div, IntoElement}; +use gpui2::{Element, ParentElement, ViewContext}; + +#[derive(Element)] +struct Tab { + title: &'static str, + active: bool, +} + +pub fn tab(title: &'static str, active: bool) -> impl Element { + Tab { title, active } +} + +impl Tab { + fn render(&mut self, _: &mut V, cx: &mut ViewContext) -> impl IntoElement { + let theme = theme(cx); + + div() + .px_2() + .py_0p5() + .flex() + .items_center() + .justify_center() + .rounded_lg() + .fill(if self.active { + theme.highest.on.default.background + } else { + theme.highest.base.default.background + }) + .hover() + .fill(if self.active { + theme.highest.on.hovered.background + } else { + theme.highest.base.hovered.background + }) + .active() + .fill(if self.active { + theme.highest.on.pressed.background + } else { + theme.highest.base.pressed.background + }) + .child( + div() + .text_sm() + .text_color(if self.active { + theme.highest.base.default.foreground + } else { + theme.highest.variant.default.foreground + }) + .child(self.title), + ) + } +} diff --git a/crates/storybook/src/module/mod.rs b/crates/storybook/src/module/mod.rs new file mode 100644 index 0000000000000000000000000000000000000000..078db8e167826c50fdd2e31aa55db0c3f8e2ac74 --- /dev/null +++ b/crates/storybook/src/module/mod.rs @@ -0,0 +1 @@ +pub(crate) mod tab_bar; diff --git a/crates/storybook/src/module/tab_bar.rs b/crates/storybook/src/module/tab_bar.rs new file mode 100644 index 0000000000000000000000000000000000000000..24f96337a03d161c4bab0286c093b8b475da7fd5 --- /dev/null +++ b/crates/storybook/src/module/tab_bar.rs @@ -0,0 +1,89 @@ +use std::marker::PhantomData; + +use crate::component::icon_button::{icon_button, ButtonVariant}; +use crate::component::tab::tab; +use crate::theme::theme; +use gpui2::elements::div::ScrollState; +use gpui2::style::StyleHelpers; +use gpui2::{elements::div, IntoElement}; +use gpui2::{Element, ParentElement, ViewContext}; + +#[derive(Element)] +pub struct TabBar { + view_type: PhantomData, + scroll_state: ScrollState, +} + +pub fn tab_bar(scroll_state: ScrollState) -> TabBar { + TabBar { + view_type: PhantomData, + scroll_state, + } +} + +impl TabBar { + fn render(&mut self, _: &mut V, cx: &mut ViewContext) -> impl IntoElement { + let theme = theme(cx); + + div() + .w_full() + .flex() + .items_center() + .fill(theme.highest.base.default.background) + // Left Side + .child( + div() + .px_1() + .flex() + // Nate + // This isn't what I wanted, but I wanted to try to get at least SOME x overflow scroll working + // Ideally this should be on the "Tabs" div below + // So only the tabs scroll, and the nav buttons stay pinned left, and the other controls stay pinned right + .overflow_x_scroll(self.scroll_state.clone()) + .gap_2() + // Nav Buttons + .child( + div() + .flex() + .items_center() + .gap_px() + .child(icon_button("icons/arrow_left.svg", ButtonVariant::Ghost)) + .child(icon_button("icons/arrow_right.svg", ButtonVariant::Ghost)), + ) + // Tabs + .child( + div() + .py_1() + .flex() + .items_center() + .gap_px() + .child(tab("Cargo.toml", false)) + .child(tab("Channels Panel", true)) + .child(tab("channels_panel.rs", false)) + .child(tab("workspace.rs", false)) + .child(tab("icon_button.rs", false)) + .child(tab("storybook.rs", false)) + .child(tab("theme.rs", false)) + .child(tab("theme_registry.rs", false)) + .child(tab("styleable_helpers.rs", false)), + ), + ) + // Right Side + .child( + div() + .px_1() + .flex() + .flex_initial() + .gap_2() + // Nav Buttons + .child( + div() + .flex() + .items_center() + .gap_px() + .child(icon_button("icons/plus.svg", ButtonVariant::Ghost)) + .child(icon_button("icons/split.svg", ButtonVariant::Ghost)), + ), + ) + } +} diff --git a/crates/storybook/src/storybook.rs b/crates/storybook/src/storybook.rs index 7f9aa8667238cc8865027830829985ffaa704436..ed6f11e074193da265f59a887c7e781b4e98eb87 100644 --- a/crates/storybook/src/storybook.rs +++ b/crates/storybook/src/storybook.rs @@ -11,6 +11,7 @@ use simplelog::SimpleLogger; mod collab_panel; mod component; +mod module; mod components; mod element_ext; mod theme; diff --git a/crates/storybook/src/workspace.rs b/crates/storybook/src/workspace.rs index 441a4c68fa1f8078d131f26e97e771d36d2b20ba..bbdfb22788c77871777cd0b3f233d2e92c196d2c 100644 --- a/crates/storybook/src/workspace.rs +++ b/crates/storybook/src/workspace.rs @@ -1,8 +1,4 @@ -use crate::{ - collab_panel::collab_panel, - component::icon_button::{icon_button, Variant}, - theme::theme, -}; +use crate::{collab_panel::collab_panel, module::tab_bar::tab_bar, theme::theme}; use gpui2::{ elements::{div, div::ScrollState, img, svg}, style::{StyleHelpers, Styleable}, @@ -13,6 +9,7 @@ use gpui2::{ struct WorkspaceElement { left_scroll_state: ScrollState, right_scroll_state: ScrollState, + tab_bar_scroll_state: ScrollState, } pub fn workspace() -> impl Element { @@ -41,17 +38,20 @@ impl WorkspaceElement { .flex() .flex_row() .overflow_hidden() - .child(collab_panel(self.left_scroll_state.clone())) + // .child(collab_panel(self.left_scroll_state.clone())) .child( - div().h_full().flex_1().child( - div() - .w_24() - .h_24() - .child(icon_button("icons/plus.svg", Variant::Ghost)) - .child(icon_button("icons/x.svg", Variant::Filled)), - ), - ) - .child(collab_panel(self.right_scroll_state.clone())), + div() + .h_full() + .flex_1() + .fill(theme.highest.base.default.background) + .child( + div() + .flex() + .flex_col() + .flex_1() + .child(tab_bar(self.tab_bar_scroll_state.clone())), + ), + ), // .child(collab_panel(self.right_scroll_state.clone())), ) .child(statusbar()) } From e84e791dde16cb9171a509755ed80587ca4e56e7 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Sat, 9 Sep 2023 17:51:23 -0400 Subject: [PATCH 06/10] Checkpoint --- crates/storybook/src/module/tab_bar.rs | 25 +++++++++++++++---------- crates/storybook/src/storybook.rs | 4 ++-- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/crates/storybook/src/module/tab_bar.rs b/crates/storybook/src/module/tab_bar.rs index 24f96337a03d161c4bab0286c093b8b475da7fd5..c3d145ed83c369e84ea9b7cc5a0d0ff45f856b3c 100644 --- a/crates/storybook/src/module/tab_bar.rs +++ b/crates/storybook/src/module/tab_bar.rs @@ -29,17 +29,15 @@ impl TabBar { .w_full() .flex() .items_center() + .overflow_hidden() + .justify_between() .fill(theme.highest.base.default.background) // Left Side .child( div() .px_1() .flex() - // Nate - // This isn't what I wanted, but I wanted to try to get at least SOME x overflow scroll working - // Ideally this should be on the "Tabs" div below - // So only the tabs scroll, and the nav buttons stay pinned left, and the other controls stay pinned right - .overflow_x_scroll(self.scroll_state.clone()) + .flex_none() .gap_2() // Nav Buttons .child( @@ -49,14 +47,21 @@ impl TabBar { .gap_px() .child(icon_button("icons/arrow_left.svg", ButtonVariant::Ghost)) .child(icon_button("icons/arrow_right.svg", ButtonVariant::Ghost)), - ) - // Tabs + ), + ) + // Tabs + .child( + div() + .flex_1() + .py_1() + .overflow_hidden() + .items_center() + .fill(theme.highest.accent.default.background) .child( div() - .py_1() .flex() - .items_center() .gap_px() + .overflow_x_scroll(self.scroll_state.clone()) .child(tab("Cargo.toml", false)) .child(tab("Channels Panel", true)) .child(tab("channels_panel.rs", false)) @@ -73,7 +78,7 @@ impl TabBar { div() .px_1() .flex() - .flex_initial() + .flex_none() .gap_2() // Nav Buttons .child( diff --git a/crates/storybook/src/storybook.rs b/crates/storybook/src/storybook.rs index ed6f11e074193da265f59a887c7e781b4e98eb87..9a7868a9e75e5b0726123f9d538b5795369671b7 100644 --- a/crates/storybook/src/storybook.rs +++ b/crates/storybook/src/storybook.rs @@ -11,9 +11,9 @@ use simplelog::SimpleLogger; mod collab_panel; mod component; -mod module; mod components; mod element_ext; +mod module; mod theme; mod workspace; @@ -36,7 +36,7 @@ fn main() { cx.add_window( gpui2::WindowOptions { - bounds: WindowBounds::Fixed(RectF::new(vec2f(0., 0.), vec2f(1400., 900.))), + bounds: WindowBounds::Fixed(RectF::new(vec2f(0., 0.), vec2f(700., 900.))), center: true, ..Default::default() }, From 2774eae21aea56036cf48a067d91e535911fa22c Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Mon, 11 Sep 2023 10:36:49 -0400 Subject: [PATCH 07/10] Checkpoint --- crates/storybook/src/component/icon_button.rs | 3 +- crates/storybook/src/component/tab.rs | 1 - crates/storybook/src/module/tab_bar.rs | 41 +++++++------------ crates/storybook/src/storybook.rs | 2 +- crates/storybook/src/workspace.rs | 7 ++-- 5 files changed, 22 insertions(+), 32 deletions(-) diff --git a/crates/storybook/src/component/icon_button.rs b/crates/storybook/src/component/icon_button.rs index 50241acbe8ef09544ab23a7230fa62c7058af10f..91c61b363da78ec6baa41474961768b33b5e6e04 100644 --- a/crates/storybook/src/component/icon_button.rs +++ b/crates/storybook/src/component/icon_button.rs @@ -23,10 +23,11 @@ pub fn icon_button(path: &'static str, variant: ButtonVariant) -> im impl IconButton { fn render(&mut self, _: &mut V, cx: &mut ViewContext) -> impl IntoElement { let theme = theme(cx); + let mut div = div(); if self.variant == ButtonVariant::Filled { - div = div.fill(theme.highest.base.default.background); + div = div.fill(theme.highest.negative.default.background); } div.w_7() diff --git a/crates/storybook/src/component/tab.rs b/crates/storybook/src/component/tab.rs index 91a0fb1be1c9b08dcae6c5cb32b2cfb57d6329d0..4aae374f802466d672a0b16b66f63e3f424bb831 100644 --- a/crates/storybook/src/component/tab.rs +++ b/crates/storybook/src/component/tab.rs @@ -1,5 +1,4 @@ use crate::theme::theme; -use gpui2::elements::svg; use gpui2::style::{StyleHelpers, Styleable}; use gpui2::{elements::div, IntoElement}; use gpui2::{Element, ParentElement, ViewContext}; diff --git a/crates/storybook/src/module/tab_bar.rs b/crates/storybook/src/module/tab_bar.rs index c3d145ed83c369e84ea9b7cc5a0d0ff45f856b3c..8dc2e8cfd43d613a784622e9482f48f928067ac9 100644 --- a/crates/storybook/src/module/tab_bar.rs +++ b/crates/storybook/src/module/tab_bar.rs @@ -28,10 +28,6 @@ impl TabBar { div() .w_full() .flex() - .items_center() - .overflow_hidden() - .justify_between() - .fill(theme.highest.base.default.background) // Left Side .child( div() @@ -49,29 +45,22 @@ impl TabBar { .child(icon_button("icons/arrow_right.svg", ButtonVariant::Ghost)), ), ) - // Tabs .child( - div() - .flex_1() - .py_1() - .overflow_hidden() - .items_center() - .fill(theme.highest.accent.default.background) - .child( - div() - .flex() - .gap_px() - .overflow_x_scroll(self.scroll_state.clone()) - .child(tab("Cargo.toml", false)) - .child(tab("Channels Panel", true)) - .child(tab("channels_panel.rs", false)) - .child(tab("workspace.rs", false)) - .child(tab("icon_button.rs", false)) - .child(tab("storybook.rs", false)) - .child(tab("theme.rs", false)) - .child(tab("theme_registry.rs", false)) - .child(tab("styleable_helpers.rs", false)), - ), + div().w_0().flex_1().h_full().child( + div() + .flex() + .gap_px() + .overflow_x_scroll(self.scroll_state.clone()) + .child(tab("Cargo.toml", false)) + .child(tab("Channels Panel", true)) + .child(tab("channels_panel.rs", false)) + .child(tab("workspace.rs", false)) + .child(tab("icon_button.rs", false)) + .child(tab("storybook.rs", false)) + .child(tab("theme.rs", false)) + .child(tab("theme_registry.rs", false)) + .child(tab("styleable_helpers.rs", false)), + ), ) // Right Side .child( diff --git a/crates/storybook/src/storybook.rs b/crates/storybook/src/storybook.rs index 9a7868a9e75e5b0726123f9d538b5795369671b7..1d44129ea838d68560a0035f63589e704a9c197b 100644 --- a/crates/storybook/src/storybook.rs +++ b/crates/storybook/src/storybook.rs @@ -36,7 +36,7 @@ fn main() { cx.add_window( gpui2::WindowOptions { - bounds: WindowBounds::Fixed(RectF::new(vec2f(0., 0.), vec2f(700., 900.))), + bounds: WindowBounds::Fixed(RectF::new(vec2f(0., 0.), vec2f(1600., 900.))), center: true, ..Default::default() }, diff --git a/crates/storybook/src/workspace.rs b/crates/storybook/src/workspace.rs index bbdfb22788c77871777cd0b3f233d2e92c196d2c..ca55f9d3cc1fd7b642a7515fb244ac6156d62ebd 100644 --- a/crates/storybook/src/workspace.rs +++ b/crates/storybook/src/workspace.rs @@ -38,7 +38,7 @@ impl WorkspaceElement { .flex() .flex_row() .overflow_hidden() - // .child(collab_panel(self.left_scroll_state.clone())) + .child(collab_panel(self.left_scroll_state.clone())) .child( div() .h_full() @@ -50,8 +50,9 @@ impl WorkspaceElement { .flex_col() .flex_1() .child(tab_bar(self.tab_bar_scroll_state.clone())), - ), - ), // .child(collab_panel(self.right_scroll_state.clone())), + ) + .child(collab_panel(self.right_scroll_state.clone())), + ), ) .child(statusbar()) } From 917884ffaf9a59e41b08badd9f9f72e1f57d75ed Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Mon, 11 Sep 2023 11:05:10 -0400 Subject: [PATCH 08/10] Restructure storybook modules and components Co-Authored-By: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com> --- crates/storybook/src/component/mod.rs | 2 -- crates/storybook/src/components.rs | 6 ++++++ .../storybook/src/{component => components}/icon_button.rs | 2 +- crates/storybook/src/{component => components}/tab.rs | 2 +- crates/storybook/src/module/mod.rs | 1 - crates/storybook/src/modules.rs | 3 +++ crates/storybook/src/{module => modules}/tab_bar.rs | 3 +-- crates/storybook/src/storybook.rs | 3 +-- crates/storybook/src/workspace.rs | 2 +- 9 files changed, 14 insertions(+), 10 deletions(-) delete mode 100644 crates/storybook/src/component/mod.rs rename crates/storybook/src/{component => components}/icon_button.rs (97%) rename crates/storybook/src/{component => components}/tab.rs (98%) delete mode 100644 crates/storybook/src/module/mod.rs create mode 100644 crates/storybook/src/modules.rs rename crates/storybook/src/{module => modules}/tab_bar.rs (96%) diff --git a/crates/storybook/src/component/mod.rs b/crates/storybook/src/component/mod.rs deleted file mode 100644 index c45b936e9624305448466817d07fa9a127bd2794..0000000000000000000000000000000000000000 --- a/crates/storybook/src/component/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub(crate) mod icon_button; -pub(crate) mod tab; diff --git a/crates/storybook/src/components.rs b/crates/storybook/src/components.rs index 1aafefc1a6a0a89728f64b6c6299e8c68ef1cc20..d07c2651a02b81a63f02873484752eabdae1971e 100644 --- a/crates/storybook/src/components.rs +++ b/crates/storybook/src/components.rs @@ -4,6 +4,12 @@ use gpui2::{ }; use std::{marker::PhantomData, rc::Rc}; +mod icon_button; +mod tab; + +pub(crate) use icon_button::{icon_button, ButtonVariant}; +pub(crate) use tab::tab; + struct ButtonHandlers { click: Option)>>, } diff --git a/crates/storybook/src/component/icon_button.rs b/crates/storybook/src/components/icon_button.rs similarity index 97% rename from crates/storybook/src/component/icon_button.rs rename to crates/storybook/src/components/icon_button.rs index 91c61b363da78ec6baa41474961768b33b5e6e04..5cdddd655a995473226cec741bc4b1ded071fd89 100644 --- a/crates/storybook/src/component/icon_button.rs +++ b/crates/storybook/src/components/icon_button.rs @@ -5,7 +5,7 @@ use gpui2::{elements::div, IntoElement}; use gpui2::{Element, ParentElement, ViewContext}; #[derive(Element)] -struct IconButton { +pub(crate) struct IconButton { path: &'static str, variant: ButtonVariant, } diff --git a/crates/storybook/src/component/tab.rs b/crates/storybook/src/components/tab.rs similarity index 98% rename from crates/storybook/src/component/tab.rs rename to crates/storybook/src/components/tab.rs index 4aae374f802466d672a0b16b66f63e3f424bb831..eeb4a0b8a67ff75165a3423704161cb48b339192 100644 --- a/crates/storybook/src/component/tab.rs +++ b/crates/storybook/src/components/tab.rs @@ -4,7 +4,7 @@ use gpui2::{elements::div, IntoElement}; use gpui2::{Element, ParentElement, ViewContext}; #[derive(Element)] -struct Tab { +pub(crate) struct Tab { title: &'static str, active: bool, } diff --git a/crates/storybook/src/module/mod.rs b/crates/storybook/src/module/mod.rs deleted file mode 100644 index 078db8e167826c50fdd2e31aa55db0c3f8e2ac74..0000000000000000000000000000000000000000 --- a/crates/storybook/src/module/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub(crate) mod tab_bar; diff --git a/crates/storybook/src/modules.rs b/crates/storybook/src/modules.rs new file mode 100644 index 0000000000000000000000000000000000000000..bc8ba73b08f8fe51f218076570e6182796c75f0f --- /dev/null +++ b/crates/storybook/src/modules.rs @@ -0,0 +1,3 @@ +mod tab_bar; + +pub(crate) use tab_bar::tab_bar; diff --git a/crates/storybook/src/module/tab_bar.rs b/crates/storybook/src/modules/tab_bar.rs similarity index 96% rename from crates/storybook/src/module/tab_bar.rs rename to crates/storybook/src/modules/tab_bar.rs index 8dc2e8cfd43d613a784622e9482f48f928067ac9..75bc7e86d6cc4c0345926ce3555049d25f4bd578 100644 --- a/crates/storybook/src/module/tab_bar.rs +++ b/crates/storybook/src/modules/tab_bar.rs @@ -1,7 +1,6 @@ use std::marker::PhantomData; -use crate::component::icon_button::{icon_button, ButtonVariant}; -use crate::component::tab::tab; +use crate::components::{icon_button, tab, ButtonVariant}; use crate::theme::theme; use gpui2::elements::div::ScrollState; use gpui2::style::StyleHelpers; diff --git a/crates/storybook/src/storybook.rs b/crates/storybook/src/storybook.rs index 1d44129ea838d68560a0035f63589e704a9c197b..1b40bc2dc482cf2bad94d8d2a662202cc8bbd2ef 100644 --- a/crates/storybook/src/storybook.rs +++ b/crates/storybook/src/storybook.rs @@ -10,10 +10,9 @@ use settings::{default_settings, SettingsStore}; use simplelog::SimpleLogger; mod collab_panel; -mod component; mod components; mod element_ext; -mod module; +mod modules; mod theme; mod workspace; diff --git a/crates/storybook/src/workspace.rs b/crates/storybook/src/workspace.rs index ca55f9d3cc1fd7b642a7515fb244ac6156d62ebd..b2d71608feda5039180a3f7a422f29dbbd6df6cd 100644 --- a/crates/storybook/src/workspace.rs +++ b/crates/storybook/src/workspace.rs @@ -1,4 +1,4 @@ -use crate::{collab_panel::collab_panel, module::tab_bar::tab_bar, theme::theme}; +use crate::{collab_panel::collab_panel, modules::tab_bar, theme::theme}; use gpui2::{ elements::{div, div::ScrollState, img, svg}, style::{StyleHelpers, Styleable}, From 1376115db2d5376ef2807bc6622737889dc3560f Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Mon, 11 Sep 2023 11:40:03 -0400 Subject: [PATCH 09/10] Use `enabled` for active tabs --- crates/storybook/src/components/icon_button.rs | 3 +-- crates/storybook/src/components/tab.rs | 14 +++++++------- crates/storybook/src/modules/tab_bar.rs | 2 +- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/crates/storybook/src/components/icon_button.rs b/crates/storybook/src/components/icon_button.rs index 5cdddd655a995473226cec741bc4b1ded071fd89..0a9b2ca285345aaca7bd91b1ff22990b0a8be407 100644 --- a/crates/storybook/src/components/icon_button.rs +++ b/crates/storybook/src/components/icon_button.rs @@ -25,9 +25,8 @@ impl IconButton { let theme = theme(cx); let mut div = div(); - if self.variant == ButtonVariant::Filled { - div = div.fill(theme.highest.negative.default.background); + div = div.fill(theme.highest.on.default.background); } div.w_7() diff --git a/crates/storybook/src/components/tab.rs b/crates/storybook/src/components/tab.rs index eeb4a0b8a67ff75165a3423704161cb48b339192..b945e113e555104e064044292f0017a449aaeb8f 100644 --- a/crates/storybook/src/components/tab.rs +++ b/crates/storybook/src/components/tab.rs @@ -6,11 +6,11 @@ use gpui2::{Element, ParentElement, ViewContext}; #[derive(Element)] pub(crate) struct Tab { title: &'static str, - active: bool, + enabled: bool, } -pub fn tab(title: &'static str, active: bool) -> impl Element { - Tab { title, active } +pub fn tab(title: &'static str, enabled: bool) -> impl Element { + Tab { title, enabled } } impl Tab { @@ -24,19 +24,19 @@ impl Tab { .items_center() .justify_center() .rounded_lg() - .fill(if self.active { + .fill(if self.enabled { theme.highest.on.default.background } else { theme.highest.base.default.background }) .hover() - .fill(if self.active { + .fill(if self.enabled { theme.highest.on.hovered.background } else { theme.highest.base.hovered.background }) .active() - .fill(if self.active { + .fill(if self.enabled { theme.highest.on.pressed.background } else { theme.highest.base.pressed.background @@ -44,7 +44,7 @@ impl Tab { .child( div() .text_sm() - .text_color(if self.active { + .text_color(if self.enabled { theme.highest.base.default.foreground } else { theme.highest.variant.default.foreground diff --git a/crates/storybook/src/modules/tab_bar.rs b/crates/storybook/src/modules/tab_bar.rs index 75bc7e86d6cc4c0345926ce3555049d25f4bd578..06029c5dc223c0d4852c1250c3d67c2c669b2876 100644 --- a/crates/storybook/src/modules/tab_bar.rs +++ b/crates/storybook/src/modules/tab_bar.rs @@ -40,7 +40,7 @@ impl TabBar { .flex() .items_center() .gap_px() - .child(icon_button("icons/arrow_left.svg", ButtonVariant::Ghost)) + .child(icon_button("icons/arrow_left.svg", ButtonVariant::Filled)) .child(icon_button("icons/arrow_right.svg", ButtonVariant::Ghost)), ), ) From 04fc9d2d3352bc772182dec839c625228b2059d1 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Mon, 11 Sep 2023 11:42:54 -0400 Subject: [PATCH 10/10] Fix incorrect workspace order --- crates/storybook/src/workspace.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/storybook/src/workspace.rs b/crates/storybook/src/workspace.rs index b2d71608feda5039180a3f7a422f29dbbd6df6cd..c37b3f16ea3abac79ab659e4f3fe138e4017d20a 100644 --- a/crates/storybook/src/workspace.rs +++ b/crates/storybook/src/workspace.rs @@ -50,9 +50,9 @@ impl WorkspaceElement { .flex_col() .flex_1() .child(tab_bar(self.tab_bar_scroll_state.clone())), - ) - .child(collab_panel(self.right_scroll_state.clone())), - ), + ), + ) + .child(collab_panel(self.right_scroll_state.clone())), ) .child(statusbar()) }