This commit is contained in:
Nathan Sobo 2023-04-12 06:51:03 -06:00
parent d9e4136b02
commit b54f08db77
22 changed files with 374 additions and 300 deletions

View File

@ -314,14 +314,14 @@ impl View for ActivityIndicator {
"ActivityIndicator"
}
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox {
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
let Content {
icon,
message,
action,
} = self.content_to_render(cx);
let mut element = MouseEventHandler::<Self>::new(0, cx, |state, cx| {
let mut element = MouseEventHandler::<Self, _>::new(0, cx, |state, cx| {
let theme = &cx
.global::<Settings>()
.theme

View File

@ -26,13 +26,13 @@ impl View for UpdateNotification {
"UpdateNotification"
}
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> gpui::ElementBox {
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> gpui::ElementBox<Self> {
let theme = cx.global::<Settings>().theme.clone();
let theme = &theme.update_notification;
let app_name = cx.global::<ReleaseChannel>().display_name();
MouseEventHandler::<ViewReleaseNotes>::new(0, cx, |state, cx| {
MouseEventHandler::<ViewReleaseNotes, _>::new(0, cx, |state, cx| {
Flex::column()
.with_child(
Flex::row()
@ -50,7 +50,7 @@ impl View for UpdateNotification {
.boxed(),
)
.with_child(
MouseEventHandler::<Cancel>::new(0, cx, |state, _| {
MouseEventHandler::<Cancel, _>::new(0, cx, |state, _| {
let style = theme.dismiss_button.style_for(state, false);
Svg::new("icons/x_mark_8.svg")
.with_color(style.color)
@ -65,7 +65,9 @@ impl View for UpdateNotification {
.boxed()
})
.with_padding(Padding::uniform(5.))
.on_click(MouseButton::Left, move |_, cx| cx.dispatch_action(Cancel))
.on_click(MouseButton::Left, move |_, _, cx| {
cx.dispatch_action(Cancel)
})
.aligned()
.constrained()
.with_height(cx.font_cache().line_height(theme.message.text.font_size))
@ -87,7 +89,7 @@ impl View for UpdateNotification {
.boxed()
})
.with_cursor_style(CursorStyle::PointingHand)
.on_click(MouseButton::Left, |_, cx| {
.on_click(MouseButton::Left, |_, _, cx| {
cx.dispatch_action(ViewReleaseNotes)
})
.boxed()

View File

@ -91,7 +91,7 @@ impl View for CopilotButton {
"CopilotButton"
}
fn render(&mut self, cx: &mut ViewContext<'_, Self>) -> ElementBox {
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
let settings = cx.global::<Settings>();
if !settings.enable_copilot_integration {
@ -111,7 +111,7 @@ impl View for CopilotButton {
Stack::new()
.with_child(
MouseEventHandler::<Self>::new(0, cx, {
MouseEventHandler::<Self, _>::new(0, cx, {
let theme = theme.clone();
let status = status.clone();
move |state, _cx| {

View File

@ -86,7 +86,7 @@ impl View for ProjectDiagnosticsEditor {
"ProjectDiagnosticsEditor"
}
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox {
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
if self.path_states.is_empty() {
let theme = &cx.global::<Settings>().theme.project_diagnostics;
Label::new("No problems in workspace", theme.empty_message.clone())
@ -509,7 +509,7 @@ impl Item for ProjectDiagnosticsEditor {
_detail: Option<usize>,
style: &theme::Tab,
cx: &AppContext,
) -> ElementBox {
) -> ElementBox<Pane> {
render_summary(
&self.summary,
&style.label.text,
@ -691,7 +691,7 @@ pub(crate) fn render_summary(
summary: &DiagnosticSummary,
text_style: &TextStyle,
theme: &theme::ProjectDiagnostics,
) -> ElementBox {
) -> ElementBox<Pane> {
if summary.error_count == 0 && summary.warning_count == 0 {
Label::new("No problems", text_style.clone()).boxed()
} else {
@ -1186,7 +1186,7 @@ mod tests {
let name = match block {
TransformBlock::Custom(block) => block
.render(&mut BlockContext {
cx,
view_context: cx,
anchor_x: 0.,
scroll_x: 0.,
gutter_padding: 0.,

View File

@ -84,14 +84,14 @@ impl View for DiagnosticIndicator {
"DiagnosticIndicator"
}
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox {
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
enum Summary {}
enum Message {}
let tooltip_style = cx.global::<Settings>().theme.tooltip.clone();
let in_progress = !self.in_progress_checks.is_empty();
let mut element = Flex::row().with_child(
MouseEventHandler::<Summary>::new(0, cx, |state, cx| {
MouseEventHandler::<Summary, _>::new(0, cx, |state, cx| {
let style = cx
.global::<Settings>()
.theme
@ -189,7 +189,7 @@ impl View for DiagnosticIndicator {
} else if let Some(diagnostic) = &self.current_diagnostic {
let message_style = style.diagnostic_message.clone();
element.add_child(
MouseEventHandler::<Message>::new(1, cx, |state, _| {
MouseEventHandler::<Message, _>::new(1, cx, |state, _| {
Label::new(
diagnostic.message.split('\n').next().unwrap().to_string(),
message_style.style_for(state, false).text.clone(),

View File

@ -2,7 +2,7 @@ use super::{
wrap_map::{self, WrapEdit, WrapPoint, WrapSnapshot},
TextHighlights,
};
use crate::{Anchor, ExcerptId, ExcerptRange, ToPoint as _};
use crate::{Anchor, Editor, ExcerptId, ExcerptRange, ToPoint as _};
use collections::{Bound, HashMap, HashSet};
use gpui::{fonts::HighlightStyle, ElementBox, ViewContext};
use language::{BufferSnapshot, Chunk, Patch, Point};
@ -50,7 +50,7 @@ struct BlockRow(u32);
#[derive(Copy, Clone, Debug, Default, Eq, Ord, PartialOrd, PartialEq)]
struct WrapRow(u32);
pub type RenderBlock = Arc<dyn Fn(&mut BlockContext) -> ElementBox>;
pub type RenderBlock = Arc<dyn Fn(&mut BlockContext) -> ElementBox<Editor>>;
pub struct Block {
id: BlockId,
@ -69,7 +69,7 @@ where
pub position: P,
pub height: u8,
pub style: BlockStyle,
pub render: Arc<dyn Fn(&mut BlockContext) -> ElementBox>,
pub render: Arc<dyn Fn(&mut BlockContext) -> ElementBox<Editor>>,
pub disposition: BlockDisposition,
}
@ -80,8 +80,8 @@ pub enum BlockStyle {
Sticky,
}
pub struct BlockContext<'a, 'b> {
pub cx: &'b mut ViewContext<'a, crate::Editor>,
pub struct BlockContext<'a, 'b, 'c, 'd> {
pub view_context: &'d mut ViewContext<'a, 'b, 'c, Editor>,
pub anchor_x: f32,
pub scroll_x: f32,
pub gutter_width: f32,
@ -932,22 +932,22 @@ impl BlockDisposition {
}
}
impl<'a, 'b> Deref for BlockContext<'a, 'b> {
type Target = ViewContext<'a, crate::Editor>;
impl<'a, 'b, 'c, 'd> Deref for BlockContext<'a, 'b, 'c, 'd> {
type Target = ViewContext<'a, 'b, 'c, Editor>;
fn deref(&self) -> &Self::Target {
self.cx
self.view_context
}
}
impl<'a, 'b> DerefMut for BlockContext<'a, 'b> {
impl DerefMut for BlockContext<'_, '_, '_, '_> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.cx
self.view_context
}
}
impl Block {
pub fn render(&self, cx: &mut BlockContext) -> ElementBox {
pub fn render(&self, cx: &mut BlockContext) -> ElementBox<Editor> {
self.render.lock()(cx)
}

View File

@ -722,7 +722,7 @@ impl ContextMenu {
cursor_position: DisplayPoint,
style: EditorStyle,
cx: &mut ViewContext<Editor>,
) -> (DisplayPoint, ElementBox) {
) -> (DisplayPoint, ElementBox<Editor>) {
match self {
ContextMenu::Completions(menu) => (cursor_position, menu.render(style, cx)),
ContextMenu::CodeActions(menu) => menu.render(cursor_position, style, cx),
@ -774,7 +774,7 @@ impl CompletionsMenu {
!self.matches.is_empty()
}
fn render(&self, style: EditorStyle, cx: &mut ViewContext<Editor>) -> ElementBox {
fn render(&self, style: EditorStyle, cx: &mut ViewContext<Editor>) -> ElementBox<Editor> {
enum CompletionTag {}
let completions = self.completions.clone();
@ -791,7 +791,7 @@ impl CompletionsMenu {
let completion = &completions[mat.candidate_id];
let item_ix = start_ix + ix;
items.push(
MouseEventHandler::<CompletionTag>::new(
MouseEventHandler::<CompletionTag, _>::new(
mat.candidate_id,
cx,
|state, _| {
@ -820,7 +820,7 @@ impl CompletionsMenu {
},
)
.with_cursor_style(CursorStyle::PointingHand)
.on_down(MouseButton::Left, move |_, cx| {
.on_down(MouseButton::Left, move |_, _, cx| {
cx.dispatch_action(ConfirmCompletion {
item_ix: Some(item_ix),
});
@ -951,7 +951,7 @@ impl CodeActionsMenu {
mut cursor_position: DisplayPoint,
style: EditorStyle,
cx: &mut ViewContext<Editor>,
) -> (DisplayPoint, ElementBox) {
) -> (DisplayPoint, ElementBox<Editor>) {
enum ActionTag {}
let container_style = style.autocomplete.container;
@ -966,7 +966,7 @@ impl CodeActionsMenu {
for (ix, action) in actions[range].iter().enumerate() {
let item_ix = start_ix + ix;
items.push(
MouseEventHandler::<ActionTag>::new(item_ix, cx, |state, _| {
MouseEventHandler::<ActionTag, _>::new(item_ix, cx, |state, _| {
let item_style = if item_ix == selected_item {
style.autocomplete.selected_item
} else if state.hovered() {
@ -982,7 +982,7 @@ impl CodeActionsMenu {
.boxed()
})
.with_cursor_style(CursorStyle::PointingHand)
.on_down(MouseButton::Left, move |_, cx| {
.on_down(MouseButton::Left, move |_, _, cx| {
cx.dispatch_action(ConfirmCodeAction {
item_ix: Some(item_ix),
});
@ -2929,18 +2929,18 @@ impl Editor {
style: &EditorStyle,
active: bool,
cx: &mut ViewContext<Self>,
) -> Option<ElementBox> {
) -> Option<ElementBox<Self>> {
if self.available_code_actions.is_some() {
enum CodeActions {}
Some(
MouseEventHandler::<CodeActions>::new(0, cx, |state, _| {
MouseEventHandler::<CodeActions, _>::new(0, cx, |state, _| {
Svg::new("icons/bolt_8.svg")
.with_color(style.code_actions.indicator.style_for(state, active).color)
.boxed()
})
.with_cursor_style(CursorStyle::PointingHand)
.with_padding(Padding::uniform(3.))
.on_down(MouseButton::Left, |_, cx| {
.on_down(MouseButton::Left, |_, _, cx| {
cx.dispatch_action(ToggleCodeActions {
deployed_from_indicator: true,
});
@ -2960,7 +2960,7 @@ impl Editor {
line_height: f32,
gutter_margin: f32,
cx: &mut ViewContext<Self>,
) -> Vec<Option<ElementBox>> {
) -> Vec<Option<ElementBox<Self>>> {
enum FoldIndicators {}
let style = style.folds.clone();
@ -2972,10 +2972,10 @@ impl Editor {
fold_data
.map(|(fold_status, buffer_row, active)| {
(active || gutter_hovered || fold_status == FoldStatus::Folded).then(|| {
MouseEventHandler::<FoldIndicators>::new(
MouseEventHandler::<FoldIndicators, _>::new(
ix as usize,
cx,
|mouse_state, _| -> ElementBox {
|mouse_state, _| -> ElementBox<Editor> {
Svg::new(match fold_status {
FoldStatus::Folded => style.folded_icon.clone(),
FoldStatus::Foldable => style.foldable_icon.clone(),
@ -3002,7 +3002,7 @@ impl Editor {
.with_cursor_style(CursorStyle::PointingHand)
.with_padding(Padding::uniform(3.))
.on_click(MouseButton::Left, {
move |_, cx| {
move |_, _, cx| {
cx.dispatch_any_action(match fold_status {
FoldStatus::Folded => Box::new(UnfoldAt { buffer_row }),
FoldStatus::Foldable => Box::new(FoldAt { buffer_row }),
@ -3028,7 +3028,7 @@ impl Editor {
cursor_position: DisplayPoint,
style: EditorStyle,
cx: &mut ViewContext<Editor>,
) -> Option<(DisplayPoint, ElementBox)> {
) -> Option<(DisplayPoint, ElementBox<Editor>)> {
self.context_menu
.as_ref()
.map(|menu| menu.render(cursor_position, style, cx))
@ -3911,7 +3911,7 @@ impl Editor {
pub fn paste(&mut self, _: &Paste, cx: &mut ViewContext<Self>) {
self.transact(cx, |this, cx| {
if let Some(item) = cx.as_mut().read_from_clipboard() {
if let Some(item) = cx.read_from_clipboard() {
let mut clipboard_text = Cow::Borrowed(item.text());
if let Some(mut clipboard_selections) = item.metadata::<Vec<ClipboardSelection>>() {
let old_selections = this.selections.all::<usize>(cx);
@ -5793,7 +5793,7 @@ impl Editor {
self.pending_rename.as_ref()
}
fn format(&mut self, _: &Format, cx: &mut ViewContext<'_, Self>) -> Option<Task<Result<()>>> {
fn format(&mut self, _: &Format, cx: &mut ViewContext<Self>) -> Option<Task<Result<()>>> {
let project = match &self.project {
Some(project) => project.clone(),
None => return None,
@ -5806,7 +5806,7 @@ impl Editor {
&mut self,
project: ModelHandle<Project>,
trigger: FormatTrigger,
cx: &mut ViewContext<'_, Self>,
cx: &mut ViewContext<Self>,
) -> Task<Result<()>> {
let buffer = self.buffer().clone();
let buffers = buffer.read(cx).all_buffers();
@ -6795,7 +6795,7 @@ impl Entity for Editor {
}
impl View for Editor {
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox {
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
let style = self.style(cx);
let font_changed = self.display_map.update(cx, |map, cx| {
map.set_fold_ellipses_color(style.folds.ellipses.text_color);
@ -6804,7 +6804,7 @@ impl View for Editor {
if font_changed {
let handle = self.handle.clone();
cx.defer(move |cx: &mut ViewContext<Editor>| {
cx.defer(move |_, cx: &mut ViewContext<Editor>| {
if let Some(editor) = handle.upgrade(cx) {
editor.update(cx, |editor, cx| {
hide_hover(editor, &HideHover, cx);

View File

@ -31,8 +31,8 @@ use gpui::{
json::{self, ToJson},
platform::{CursorStyle, Modifiers, MouseButton, MouseButtonEvent, MouseMovedEvent},
text_layout::{self, Line, RunStyle, TextLayoutCache},
AppContext, Axis, Border, CursorRegion, Element, ElementBox, MouseRegion, Quad, SceneBuilder,
SizeConstraint, ViewContext, WeakViewHandle,
AppContext, Axis, Border, CursorRegion, Element, ElementBox, EventContext, MouseRegion, Quad,
SceneBuilder, SizeConstraint, ViewContext, WeakViewHandle, WindowContext,
};
use itertools::Itertools;
use json::json;
@ -98,10 +98,6 @@ impl EditorElement {
}
}
fn view<'a>(&self, cx: &'a AppContext) -> &'a Editor {
self.view.upgrade(cx).unwrap().read(cx)
}
fn update_view<F, T>(&self, cx: &mut AppContext, f: F) -> T
where
F: FnOnce(&mut Editor, &mut ViewContext<Editor>) -> T,
@ -114,6 +110,7 @@ impl EditorElement {
}
fn attach_mouse_handlers(
scene: &mut SceneBuilder,
view: &WeakViewHandle<Editor>,
position_map: &Arc<PositionMap>,
has_popovers: bool,
@ -121,14 +118,14 @@ impl EditorElement {
text_bounds: RectF,
gutter_bounds: RectF,
bounds: RectF,
cx: &mut PaintContext,
cx: &mut ViewContext<Editor>,
) {
enum EditorElementMouseHandlers {}
scene.push_mouse_region(
MouseRegion::new::<EditorElementMouseHandlers>(view.id(), view.id(), visible_bounds)
.on_down(MouseButton::Left, {
let position_map = position_map.clone();
move |e, cx| {
move |e, _, cx| {
if !Self::mouse_down(
e.platform_event,
position_map.as_ref(),
@ -142,7 +139,7 @@ impl EditorElement {
})
.on_down(MouseButton::Right, {
let position_map = position_map.clone();
move |e, cx| {
move |e, _, cx| {
if !Self::mouse_right_down(
e.position,
position_map.as_ref(),
@ -156,7 +153,7 @@ impl EditorElement {
.on_up(MouseButton::Left, {
let view = view.clone();
let position_map = position_map.clone();
move |e, cx| {
move |e, _, cx| {
if !Self::mouse_up(
view.clone(),
e.position,
@ -173,7 +170,7 @@ impl EditorElement {
.on_drag(MouseButton::Left, {
let view = view.clone();
let position_map = position_map.clone();
move |e, cx| {
move |e, _, cx| {
if !Self::mouse_dragged(
view.clone(),
e.platform_event,
@ -187,20 +184,20 @@ impl EditorElement {
})
.on_move({
let position_map = position_map.clone();
move |e, cx| {
move |e, _, cx| {
if !Self::mouse_moved(e.platform_event, &position_map, text_bounds, cx) {
cx.propagate_event()
}
}
})
.on_move_out(move |_, cx| {
.on_move_out(move |_, _: &mut Editor, cx| {
if has_popovers {
cx.dispatch_action(HideHover);
}
})
.on_scroll({
let position_map = position_map.clone();
move |e, cx| {
move |e, _, cx| {
if !Self::scroll(
e.position,
*e.delta.raw(),
@ -218,7 +215,7 @@ impl EditorElement {
enum GutterHandlers {}
scene.push_mouse_region(
MouseRegion::new::<GutterHandlers>(view.id(), view.id() + 1, gutter_bounds).on_hover(
|hover, cx| {
|hover, _: &mut Editor, cx| {
cx.dispatch_action(GutterHover {
hovered: hover.started,
})
@ -244,7 +241,7 @@ impl EditorElement {
position_map: &PositionMap,
text_bounds: RectF,
gutter_bounds: RectF,
cx: &mut EventContext,
cx: &mut EventContext<Editor>,
) -> bool {
if gutter_bounds.contains_point(position) {
click_count = 3; // Simulate triple-click when clicking the gutter to select lines
@ -279,7 +276,7 @@ impl EditorElement {
position: Vector2F,
position_map: &PositionMap,
text_bounds: RectF,
cx: &mut EventContext,
cx: &mut EventContext<Editor>,
) -> bool {
if !text_bounds.contains_point(position) {
return false;
@ -298,9 +295,9 @@ impl EditorElement {
shift: bool,
position_map: &PositionMap,
text_bounds: RectF,
cx: &mut EventContext,
cx: &mut EventContext<Editor>,
) -> bool {
let view = view.upgrade(cx.app).unwrap().read(cx.app);
let view = view.upgrade(cx).unwrap().read(cx);
let end_selection = view.has_pending_selection();
let pending_nonempty_selections = view.has_pending_nonempty_selection();
@ -334,7 +331,7 @@ impl EditorElement {
}: MouseMovedEvent,
position_map: &PositionMap,
text_bounds: RectF,
cx: &mut EventContext,
cx: &mut EventContext<Editor>,
) -> bool {
// This will be handled more correctly once https://github.com/zed-industries/zed/issues/1218 is completed
// Don't trigger hover popover if mouse is hovering over context menu
@ -355,7 +352,7 @@ impl EditorElement {
shift_held: shift,
});
let view = view.upgrade(cx.app).unwrap().read(cx.app);
let view = view.upgrade(cx).unwrap().read(cx);
if view.has_pending_selection() {
let mut scroll_delta = Vector2F::zero();
@ -480,7 +477,7 @@ impl EditorElement {
border: Border::new(0., Color::transparent_black()),
corner_radius: 0.,
});
c.push_quad(Quad {
scene.push_quad(Quad {
bounds: text_bounds,
background: Some(self.style.background),
border: Border::new(0., Color::transparent_black()),
@ -545,7 +542,7 @@ impl EditorElement {
visible_bounds: RectF,
layout: &mut LayoutState,
editor: &mut Editor,
cx: &mut PaintContext,
cx: &mut ViewContext<Editor>,
) {
let line_height = layout.position_map.line_height;
@ -561,7 +558,7 @@ impl EditorElement {
);
if show_gutter {
Self::paint_diff_hunks(bounds, layout, cx);
Self::paint_diff_hunks(scene, bounds, layout, cx);
}
for (ix, line) in layout.line_number_layouts.iter().enumerate() {
@ -608,7 +605,12 @@ impl EditorElement {
}
}
fn paint_diff_hunks(bounds: RectF, layout: &mut LayoutState, cx: &mut PaintContext) {
fn paint_diff_hunks(
scene: &mut SceneBuilder,
bounds: RectF,
layout: &mut LayoutState,
cx: &mut ViewContext<Editor>,
) {
let diff_style = &cx.global::<Settings>().theme.editor.diff.clone();
let line_height = layout.position_map.line_height;
@ -698,11 +700,10 @@ impl EditorElement {
visible_bounds: RectF,
layout: &mut LayoutState,
editor: &mut Editor,
cx: &mut PaintContext,
cx: &mut ViewContext<Editor>,
) {
let view = self.view(cx.app);
let style = &self.style;
let local_replica_id = view.replica_id(cx);
let local_replica_id = editor.replica_id(cx);
let scroll_position = layout.position_map.snapshot.scroll_position();
let start_row = layout.visible_display_row_range.start;
let scroll_top = scroll_position.y() * layout.position_map.line_height;
@ -715,7 +716,7 @@ impl EditorElement {
scene.push_cursor_region(CursorRegion {
bounds,
style: if !view.link_go_to_definition_state.definitions.is_empty() {
style: if !editor.link_go_to_definition_state.definitions.is_empty() {
CursorStyle::PointingHand
} else {
CursorStyle::IBeam
@ -761,7 +762,7 @@ impl EditorElement {
scene.push_mouse_region(
MouseRegion::new::<FoldMarkers>(self.view.id(), *id as usize, bound)
.on_click(MouseButton::Left, move |_, cx| {
.on_click(MouseButton::Left, move |_, _: &mut Editor, cx| {
cx.dispatch_action(UnfoldAt { buffer_row })
})
.with_notify_on_hover(true)
@ -807,7 +808,7 @@ impl EditorElement {
cx,
);
if view.show_local_cursors(cx) || *replica_id != local_replica_id {
if editor.show_local_cursors(cx) || *replica_id != local_replica_id {
let cursor_position = selection.head;
if layout
.visible_display_row_range
@ -834,7 +835,7 @@ impl EditorElement {
cursor_row_layout.font_for_index(cursor_column)?;
let text = character.to_string();
Some(cx.text_layout_cache.layout_str(
Some(cx.text_layout_cache().layout_str(
&text,
cursor_row_layout.font_size(),
&[(
@ -905,8 +906,8 @@ impl EditorElement {
// Snap the right edge of the list to the right edge of the window if
// its horizontal bounds overflow.
if list_origin.x() + list_width > cx.window_size.x() {
list_origin.set_x((cx.window_size.x() - list_width).max(0.));
if list_origin.x() + list_width > cx.window_size().x() {
list_origin.set_x((cx.window_size().x() - list_width).max(0.));
}
if list_origin.y() + list_height > bounds.max_y() {
@ -1059,7 +1060,7 @@ impl EditorElement {
MouseRegion::new::<ScrollbarMouseHandlers>(view.id(), view.id(), track_bounds)
.on_move({
let view = view.clone();
move |_, cx| {
move |_, _: &mut Editor, cx| {
if let Some(view) = view.upgrade(cx.deref_mut()) {
view.update(cx.deref_mut(), |view, cx| {
view.scroll_manager.show_scrollbar(cx);
@ -1070,7 +1071,7 @@ impl EditorElement {
.on_down(MouseButton::Left, {
let view = view.clone();
let row_range = row_range.clone();
move |e, cx| {
move |e, _: &mut Editor, cx| {
let y = e.position.y();
if let Some(view) = view.upgrade(cx.deref_mut()) {
view.update(cx.deref_mut(), |view, cx| {
@ -1092,7 +1093,7 @@ impl EditorElement {
})
.on_drag(MouseButton::Left, {
let view = view.clone();
move |e, cx| {
move |e, _: &mut Editor, cx| {
let y = e.prev_mouse_position.y();
let new_y = e.position.y();
if thumb_top < y && y < thumb_bottom {
@ -1127,7 +1128,7 @@ impl EditorElement {
scroll_top: f32,
scroll_left: f32,
bounds: RectF,
cx: &mut ViewContext<Self>,
cx: &mut ViewContext<Editor>,
) {
let start_row = layout.visible_display_row_range.start;
let end_row = layout.visible_display_row_range.end;
@ -1182,7 +1183,7 @@ impl EditorElement {
visible_bounds: RectF,
layout: &mut LayoutState,
editor: &mut Editor,
cx: &mut PaintContext,
cx: &mut ViewContext<Editor>,
) {
let scroll_position = layout.position_map.snapshot.scroll_position();
let scroll_left = scroll_position.x() * layout.position_map.em_width;
@ -1203,11 +1204,11 @@ impl EditorElement {
}
}
fn max_line_number_width(&self, snapshot: &EditorSnapshot, cx: &LayoutContext) -> f32 {
fn max_line_number_width(&self, snapshot: &EditorSnapshot, cx: &ViewContext<Editor>) -> f32 {
let digit_count = (snapshot.max_buffer_row() as f32).log10().floor() as usize + 1;
let style = &self.style;
cx.text_layout_cache
cx.text_layout_cache()
.layout_str(
"1".repeat(digit_count).as_str(),
style.text.font_size,
@ -1252,7 +1253,7 @@ impl EditorElement {
active_rows: &BTreeMap<u32, bool>,
is_singleton: bool,
snapshot: &EditorSnapshot,
cx: &LayoutContext,
cx: &ViewContext<Editor>,
) -> (
Vec<Option<text_layout::Line>>,
Vec<Option<(FoldStatus, BufferRow, bool)>>,
@ -1277,7 +1278,7 @@ impl EditorElement {
if include_line_numbers {
line_number.clear();
write!(&mut line_number, "{}", buffer_row + 1).unwrap();
line_number_layouts.push(Some(cx.text_layout_cache.layout_str(
line_number_layouts.push(Some(cx.text_layout_cache().layout_str(
&line_number,
style.text.font_size,
&[(
@ -1312,7 +1313,7 @@ impl EditorElement {
&mut self,
rows: Range<u32>,
snapshot: &EditorSnapshot,
cx: &LayoutContext,
cx: &ViewContext<Editor>,
) -> Vec<text_layout::Line> {
if rows.start >= rows.end {
return Vec::new();
@ -1335,7 +1336,7 @@ impl EditorElement {
.take(rows.len());
placeholder_lines
.map(|line| {
cx.text_layout_cache.layout_str(
cx.text_layout_cache().layout_str(
line,
placeholder_style.font_size,
&[(
@ -1395,8 +1396,8 @@ impl EditorElement {
layout_highlighted_chunks(
chunks,
&style.text,
cx.text_layout_cache,
cx.font_cache,
cx.text_layout_cache(),
cx.font_cache(),
MAX_LINE_LEN,
rows.len() as usize,
)
@ -1419,7 +1420,7 @@ impl EditorElement {
line_layouts: &[text_layout::Line],
include_root: bool,
editor: &mut Editor,
cx: &mut LayoutContext,
cx: &mut ViewContext<Editor>,
) -> (f32, Vec<BlockLayout>) {
let tooltip_style = cx.global::<Settings>().theme.tooltip.clone();
let scroll_x = snapshot.scroll_anchor.offset.x();
@ -1441,20 +1442,18 @@ impl EditorElement {
line_layouts[(align_to.row() - rows.start) as usize]
.x_for_index(align_to.column() as usize)
} else {
layout_line(align_to.row(), snapshot, style, cx.text_layout_cache)
layout_line(align_to.row(), snapshot, style, cx.text_layout_cache())
.x_for_index(align_to.column() as usize)
};
cx.render(&editor, |_, cx| {
block.render(&mut BlockContext {
cx,
anchor_x,
gutter_padding,
line_height,
scroll_x,
gutter_width,
em_width,
})
block.render(&mut BlockContext {
view_context: cx,
anchor_x,
gutter_padding,
line_height,
scroll_x,
gutter_width,
em_width,
})
}
TransformBlock::ExcerptHeader {
@ -1480,36 +1479,34 @@ impl EditorElement {
};
enum JumpIcon {}
cx.render(&editor, |_, cx| {
MouseEventHandler::<JumpIcon>::new(id.into(), cx, |state, _| {
let style = style.jump_icon.style_for(state, false);
Svg::new("icons/arrow_up_right_8.svg")
.with_color(style.color)
.constrained()
.with_width(style.icon_width)
.aligned()
.contained()
.with_style(style.container)
.constrained()
.with_width(style.button_width)
.with_height(style.button_width)
.boxed()
})
.with_cursor_style(CursorStyle::PointingHand)
.on_click(MouseButton::Left, move |_, cx| {
cx.dispatch_action(jump_action.clone())
})
.with_tooltip::<JumpIcon, _>(
id.into(),
"Jump to Buffer".to_string(),
Some(Box::new(crate::OpenExcerpts)),
tooltip_style.clone(),
cx,
)
.aligned()
.flex_float()
.boxed()
MouseEventHandler::<JumpIcon, _>::new(id.into(), cx, |state, _| {
let style = style.jump_icon.style_for(state, false);
Svg::new("icons/arrow_up_right_8.svg")
.with_color(style.color)
.constrained()
.with_width(style.icon_width)
.aligned()
.contained()
.with_style(style.container)
.constrained()
.with_width(style.button_width)
.with_height(style.button_width)
.boxed()
})
.with_cursor_style(CursorStyle::PointingHand)
.on_click(MouseButton::Left, move |_, _, cx| {
cx.dispatch_action(jump_action.clone())
})
.with_tooltip::<JumpIcon>(
id.into(),
"Jump to Buffer".to_string(),
Some(Box::new(crate::OpenExcerpts)),
tooltip_style.clone(),
cx,
)
.aligned()
.flex_float()
.boxed()
});
if *starts_new_buffer {
@ -1614,31 +1611,32 @@ impl EditorElement {
}
}
impl Element for EditorElement {
impl Element<Editor> for EditorElement {
type LayoutState = LayoutState;
type PaintState = ();
fn layout(
&mut self,
constraint: SizeConstraint,
cx: &mut LayoutContext,
editor: &mut Editor,
cx: &mut ViewContext<Editor>,
) -> (Vector2F, Self::LayoutState) {
let mut size = constraint.max;
if size.x().is_infinite() {
unimplemented!("we don't yet handle an infinite width constraint on buffer elements");
}
let snapshot = self.snapshot(cx.app);
let snapshot = self.snapshot(cx);
let style = self.style.clone();
let line_height = style.text.line_height(cx.font_cache);
let line_height = style.text.line_height(cx.font_cache());
let gutter_padding;
let gutter_width;
let gutter_margin;
if snapshot.mode == EditorMode::Full {
gutter_padding = style.text.em_width(cx.font_cache) * style.gutter_padding_factor;
gutter_padding = style.text.em_width(cx.font_cache()) * style.gutter_padding_factor;
gutter_width = self.max_line_number_width(&snapshot, cx) + gutter_padding * 2.0;
gutter_margin = -style.text.descent(cx.font_cache);
gutter_margin = -style.text.descent(cx.font_cache());
} else {
gutter_padding = 0.0;
gutter_width = 0.0;
@ -1646,10 +1644,10 @@ impl Element for EditorElement {
};
let text_width = size.x() - gutter_width;
let em_width = style.text.em_width(cx.font_cache);
let em_advance = style.text.em_advance(cx.font_cache);
let em_width = style.text.em_width(cx.font_cache());
let em_advance = style.text.em_advance(cx.font_cache());
let overscroll = vec2f(em_width, 0.);
let snapshot = self.update_view(cx.app, |view, cx| {
let snapshot = self.update_view(cx, |view, cx| {
view.set_visible_line_count(size.y() / line_height);
let editor_width = text_width - gutter_margin - overscroll.x() - em_width;
@ -1686,7 +1684,7 @@ impl Element for EditorElement {
let gutter_size = vec2f(gutter_width, size.y());
let text_size = vec2f(text_width, size.y());
let (autoscroll_horizontally, mut snapshot) = self.update_view(cx.app, |view, cx| {
let (autoscroll_horizontally, mut snapshot) = self.update_view(cx, |view, cx| {
let autoscroll_horizontally = view.autoscroll_vertically(size.y(), line_height, cx);
let snapshot = view.snapshot(cx);
(autoscroll_horizontally, snapshot)
@ -1728,7 +1726,7 @@ impl Element for EditorElement {
let mut show_scrollbars = false;
let mut include_root = false;
let mut is_singleton = false;
self.update_view(cx.app, |view, cx| {
self.update_view(cx, |view, cx| {
is_singleton = view.is_singleton(cx);
let display_map = view.display_map.update(cx, |map, cx| map.snapshot(cx));
@ -1859,11 +1857,11 @@ impl Element for EditorElement {
snapshot.longest_row(),
&snapshot,
&style,
cx.text_layout_cache,
cx.text_layout_cache(),
)
.width();
let scroll_width = longest_line_width.max(max_visible_line_width) + overscroll.x();
let em_width = style.text.em_width(cx.font_cache);
let em_width = style.text.em_width(cx.font_cache());
let (scroll_width, blocks) = self.layout_blocks(
start_row..end_row,
&snapshot,
@ -1886,7 +1884,7 @@ impl Element for EditorElement {
max_row as f32,
);
self.update_view(cx.app, |view, cx| {
self.update_view(cx, |view, cx| {
let clamped = view.scroll_manager.clamp_scroll_left(scroll_max.x());
let autoscrolled = if autoscroll_horizontally {
@ -1911,47 +1909,52 @@ impl Element for EditorElement {
let mut code_actions_indicator = None;
let mut hover = None;
let mut mode = EditorMode::Full;
let mut fold_indicators = cx.render(&self.view.upgrade(cx).unwrap(), |view, cx| {
let newest_selection_head = view
let mut fold_indicators = {
let newest_selection_head = editor
.selections
.newest::<usize>(cx)
.head()
.to_display_point(&snapshot);
let style = view.style(cx);
let style = editor.style(cx);
if (start_row..end_row).contains(&newest_selection_head.row()) {
if view.context_menu_visible() {
if editor.context_menu_visible() {
context_menu =
view.render_context_menu(newest_selection_head, style.clone(), cx);
editor.render_context_menu(newest_selection_head, style.clone(), cx);
}
let active = matches!(view.context_menu, Some(crate::ContextMenu::CodeActions(_)));
let active = matches!(
editor.context_menu,
Some(crate::ContextMenu::CodeActions(_))
);
code_actions_indicator = view
code_actions_indicator = editor
.render_code_actions_indicator(&style, active, cx)
.map(|indicator| (newest_selection_head.row(), indicator));
}
let visible_rows = start_row..start_row + line_layouts.len() as u32;
hover = view.hover_state.render(&snapshot, &style, visible_rows, cx);
mode = view.mode;
hover = editor
.hover_state
.render(&snapshot, &style, visible_rows, cx);
mode = editor.mode;
view.render_fold_indicators(
editor.render_fold_indicators(
fold_statuses,
&style,
view.gutter_hovered,
editor.gutter_hovered,
line_height,
gutter_margin,
cx,
)
});
};
if let Some((_, context_menu)) = context_menu.as_mut() {
context_menu.layout(
SizeConstraint {
min: Vector2F::zero(),
max: vec2f(
cx.window_size.x() * 0.7,
cx.window_size().x() * 0.7,
(12. * line_height).min((size.y() - line_height) / 2.),
),
},
@ -1978,6 +1981,7 @@ impl Element for EditorElement {
Axis::Vertical,
line_height * style.code_actions.vertical_scale,
),
editor,
cx,
);
}
@ -1997,6 +2001,7 @@ impl Element for EditorElement {
.max(MIN_POPOVER_LINE_HEIGHT * line_height), // Apply minimum height of 4 lines
),
},
editor,
cx,
);
}
@ -2041,10 +2046,12 @@ impl Element for EditorElement {
fn paint(
&mut self,
scene: &mut SceneBuilder,
bounds: RectF,
visible_bounds: RectF,
layout: &mut Self::LayoutState,
cx: &mut PaintContext,
editor: &mut Editor,
cx: &mut ViewContext<Editor>,
) -> Self::PaintState {
let visible_bounds = bounds.intersection(visible_bounds).unwrap_or_default();
scene.push_layer(Some(visible_bounds));
@ -2056,6 +2063,7 @@ impl Element for EditorElement {
);
Self::attach_mouse_handlers(
scene,
&self.view,
&layout.position_map,
layout.hover_popovers.is_some(),
@ -2089,7 +2097,8 @@ impl Element for EditorElement {
_: RectF,
layout: &Self::LayoutState,
_: &Self::PaintState,
_: &gpui::MeasurementContext,
_: &Editor,
_: &ViewContext<Editor>,
) -> Option<RectF> {
let text_bounds = RectF::new(
bounds.origin() + vec2f(layout.gutter_size.x(), 0.0),
@ -2132,7 +2141,8 @@ impl Element for EditorElement {
bounds: RectF,
_: &Self::LayoutState,
_: &Self::PaintState,
_: &gpui::DebugContext,
_: &Editor,
_: &ViewContext<Editor>,
) -> json::Value {
json!({
"type": "BufferElement",
@ -2162,10 +2172,10 @@ pub struct LayoutState {
scrollbar_row_range: Range<f32>,
show_scrollbars: bool,
max_row: u32,
context_menu: Option<(DisplayPoint, ElementBox)>,
code_actions_indicator: Option<(u32, ElementBox)>,
hover_popovers: Option<(DisplayPoint, Vec<ElementBox>)>,
fold_indicators: Vec<Option<ElementBox>>,
context_menu: Option<(DisplayPoint, ElementBox<Editor>)>,
code_actions_indicator: Option<(u32, ElementBox<Editor>)>,
hover_popovers: Option<(DisplayPoint, Vec<ElementBox<Editor>>)>,
fold_indicators: Vec<Option<ElementBox<Editor>>>,
}
pub struct PositionMap {
@ -2216,7 +2226,7 @@ impl PositionMap {
struct BlockLayout {
row: u32,
element: ElementBox,
element: ElementBox<Editor>,
style: BlockStyle,
}
@ -2287,7 +2297,7 @@ impl Cursor {
)
}
pub fn paint(&self, scene: &mut SceneBuilder, origin: Vector2F, cx: &mut AppContext) {
pub fn paint(&self, scene: &mut SceneBuilder, 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(

View File

@ -283,7 +283,7 @@ impl HoverState {
style: &EditorStyle,
visible_rows: Range<u32>,
cx: &mut ViewContext<Editor>,
) -> Option<(DisplayPoint, Vec<ElementBox>)> {
) -> Option<(DisplayPoint, Vec<ElementBox<Editor>>)> {
// If there is a diagnostic, position the popovers based on that.
// Otherwise use the start of the hover range
let anchor = self
@ -323,9 +323,9 @@ pub struct InfoPopover {
}
impl InfoPopover {
pub fn render(&self, style: &EditorStyle, cx: &mut ViewContext<Editor>) -> ElementBox {
MouseEventHandler::<InfoPopover>::new(0, cx, |_, cx| {
let mut flex = Flex::new(Axis::Vertical).scrollable::<HoverBlock, _>(1, None, cx);
pub fn render(&self, style: &EditorStyle, cx: &mut ViewContext<Editor>) -> ElementBox<Editor> {
MouseEventHandler::<InfoPopover, _>::new(0, cx, |_, cx| {
let mut flex = Flex::new(Axis::Vertical).scrollable::<HoverBlock>(1, None, cx);
flex.extend(self.contents.iter().map(|content| {
let languages = self.project.read(cx).languages();
if let Some(language) = content.language.clone().and_then(|language| {
@ -360,7 +360,7 @@ impl InfoPopover {
.with_style(style.hover_popover.container)
.boxed()
})
.on_move(|_, _| {}) // Consume move events so they don't reach regions underneath.
.on_move(|_, _, _| {}) // Consume move events so they don't reach regions underneath.
.with_cursor_style(CursorStyle::Arrow)
.with_padding(Padding {
bottom: HOVER_POPOVER_GAP,
@ -378,7 +378,7 @@ pub struct DiagnosticPopover {
}
impl DiagnosticPopover {
pub fn render(&self, style: &EditorStyle, cx: &mut ViewContext<Editor>) -> ElementBox {
pub fn render(&self, style: &EditorStyle, cx: &mut ViewContext<Editor>) -> ElementBox<Editor> {
enum PrimaryDiagnostic {}
let mut text_style = style.hover_popover.prose.clone();
@ -394,7 +394,7 @@ impl DiagnosticPopover {
let tooltip_style = cx.global::<Settings>().theme.tooltip.clone();
MouseEventHandler::<DiagnosticPopover>::new(0, cx, |_, _| {
MouseEventHandler::<DiagnosticPopover, _>::new(0, cx, |_, _| {
Text::new(self.local_diagnostic.diagnostic.message.clone(), text_style)
.with_soft_wrap(true)
.contained()
@ -406,12 +406,12 @@ impl DiagnosticPopover {
bottom: HOVER_POPOVER_GAP,
..Default::default()
})
.on_move(|_, _| {}) // Consume move events so they don't reach regions underneath.
.on_click(MouseButton::Left, |_, cx| {
.on_move(|_, _, _| {}) // Consume move events so they don't reach regions underneath.
.on_click(MouseButton::Left, |_, _, cx| {
cx.dispatch_action(GoToDiagnostic)
})
.with_cursor_style(CursorStyle::PointingHand)
.with_tooltip::<PrimaryDiagnostic, _>(
.with_tooltip::<PrimaryDiagnostic>(
0,
"Go To Diagnostic".to_string(),
Some(Box::new(crate::GoToDiagnostic)),

View File

@ -8,7 +8,7 @@ use collections::HashSet;
use futures::future::try_join_all;
use gpui::{
elements::*, geometry::vector::vec2f, AppContext, Entity, ModelHandle, Subscription, Task,
View, ViewContext, ViewContext, ViewHandle, WeakViewHandle,
View, ViewContext, ViewHandle, WeakViewHandle,
};
use language::{
proto::serialize_anchor as serialize_text_anchor, Bias, Buffer, OffsetRangeExt, Point,
@ -526,7 +526,7 @@ impl Item for Editor {
detail: Option<usize>,
style: &theme::Tab,
cx: &AppContext,
) -> ElementBox {
) -> ElementBox<Pane> {
Flex::row()
.with_child(
Label::new(self.title(cx).to_string(), style.label.clone())
@ -606,7 +606,7 @@ impl Item for Editor {
self.report_event("save editor", cx);
let format = self.perform_format(project.clone(), FormatTrigger::Save, cx);
let buffers = self.buffer().clone().read(cx).all_buffers();
cx.as_mut().spawn(|mut cx| async move {
cx.spawn(|_, mut cx| async move {
format.await?;
if buffers.len() == 1 {
@ -727,7 +727,7 @@ impl Item for Editor {
ToolbarItemLocation::PrimaryLeft { flex: None }
}
fn breadcrumbs(&self, theme: &theme::Theme, cx: &AppContext) -> Option<Vec<ElementBox>> {
fn breadcrumbs(&self, theme: &theme::Theme, cx: &AppContext) -> Option<Vec<ElementBox<Pane>>> {
let cursor = self.selections.newest_anchor().head();
let multibuffer = &self.buffer().read(cx);
let (buffer_id, symbols) =
@ -1078,7 +1078,7 @@ impl View for CursorPosition {
"CursorPosition"
}
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox {
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
if let Some(position) = self.position {
let theme = &cx.global::<Settings>().theme.workspace.status_bar;
let mut text = format!("{},{}", position.row + 1, position.column + 1);

View File

@ -156,7 +156,7 @@ impl View for GoToLine {
"GoToLine"
}
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox {
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
let theme = &cx.global::<Settings>().theme.picker;
let label = format!(

View File

@ -12,9 +12,10 @@ use crate::{
},
text_layout::TextLayoutCache,
util::post_inc,
AnyView, AnyViewHandle, AppContext, Element, ElementBox, Entity, ModelContext, ModelHandle,
MouseRegion, MouseRegionId, ParentId, ReadView, RenderParams, SceneBuilder, UpdateModel, View,
ViewContext, ViewHandle, WindowInvalidation,
AnyView, AnyViewHandle, AnyWeakViewHandle, AppContext, Element, ElementBox, Entity,
ModelContext, ModelHandle, MouseRegion, MouseRegionId, ParentId, ReadView, RenderParams,
SceneBuilder, UpdateModel, UpgradeViewHandle, View, ViewContext, ViewHandle, WeakViewHandle,
WindowInvalidation,
};
use anyhow::bail;
use collections::{HashMap, HashSet};
@ -121,10 +122,10 @@ impl DerefMut for WindowContext<'_, '_> {
}
impl UpdateModel for WindowContext<'_, '_> {
fn update_model<M: Entity, R>(
fn update_model<T: Entity, R>(
&mut self,
handle: &ModelHandle<M>,
update: &mut dyn FnMut(&mut M, &mut ModelContext<M>) -> R,
handle: &ModelHandle<T>,
update: &mut dyn FnMut(&mut T, &mut ModelContext<T>) -> R,
) -> R {
self.app_context.update_model(handle, update)
}
@ -136,6 +137,16 @@ impl ReadView for WindowContext<'_, '_> {
}
}
impl UpgradeViewHandle for WindowContext<'_, '_> {
fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
self.app_context.upgrade_view_handle(handle)
}
fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle> {
self.app_context.upgrade_any_view_handle(handle)
}
}
impl<'a: 'b, 'b> WindowContext<'a, 'b> {
pub fn new(app_context: &'a mut AppContext, window: &'b mut Window, window_id: usize) -> Self {
Self {

View File

@ -29,7 +29,7 @@ pub mod json;
pub mod keymap_matcher;
pub mod platform;
pub use gpui_macros::test;
pub use window::{Axis, SizeConstraint, Vector2FExt};
pub use window::{Axis, SizeConstraint, Vector2FExt, WindowContext};
pub use anyhow;
pub use serde_json;

View File

@ -11,7 +11,11 @@ use collections::HashMap;
use pathfinder_geometry::rect::RectF;
use smallvec::SmallVec;
use crate::{platform::MouseButton, window::WindowContext, ReadView, View, ViewContext};
use crate::{
platform::MouseButton, window::WindowContext, AnyModelHandle, AnyViewHandle,
AnyWeakModelHandle, AnyWeakViewHandle, Entity, ModelHandle, ReadView, UpgradeModelHandle,
UpgradeViewHandle, View, ViewContext, ViewHandle, WeakModelHandle, WeakViewHandle,
};
use super::{
mouse_event::{
@ -240,6 +244,33 @@ impl<V: View> ReadView for EventContext<'_, '_, '_, '_, V> {
}
}
impl<V: View> UpgradeModelHandle for EventContext<'_, '_, '_, '_, V> {
fn upgrade_model_handle<T: Entity>(
&self,
handle: &WeakModelHandle<T>,
) -> Option<ModelHandle<T>> {
self.view_context.upgrade_model_handle(handle)
}
fn model_handle_is_upgradable<T: Entity>(&self, handle: &WeakModelHandle<T>) -> bool {
self.view_context.model_handle_is_upgradable(handle)
}
fn upgrade_any_model_handle(&self, handle: &AnyWeakModelHandle) -> Option<AnyModelHandle> {
self.view_context.upgrade_any_model_handle(handle)
}
}
impl<V: View> UpgradeViewHandle for EventContext<'_, '_, '_, '_, V> {
fn upgrade_view_handle<T: View>(&self, handle: &WeakViewHandle<T>) -> Option<ViewHandle<T>> {
self.view_context.upgrade_view_handle(handle)
}
fn upgrade_any_view_handle(&self, handle: &AnyWeakViewHandle) -> Option<AnyViewHandle> {
self.view_context.upgrade_any_view_handle(handle)
}
}
pub type HandlerCallback = Rc<dyn Fn(MouseEvent, &mut dyn Any, &mut WindowContext, usize) -> bool>;
#[derive(Clone, PartialEq, Eq, Hash)]

View File

@ -4,8 +4,8 @@ use gpui::{
geometry::vector::{vec2f, Vector2F},
keymap_matcher::KeymapContext,
platform::{CursorStyle, MouseButton},
AnyViewHandle, AppContext, Axis, Entity, MouseState, Task, View, ViewContext, ViewHandle,
WeakViewHandle,
AnyViewHandle, AppContext, Axis, ElementBox, Entity, MouseState, Task, View, ViewContext,
ViewHandle, WeakViewHandle,
};
use menu::{Cancel, Confirm, SelectFirst, SelectIndex, SelectLast, SelectNext, SelectPrev};
use parking_lot::Mutex;
@ -33,7 +33,7 @@ pub trait PickerDelegate: View {
state: &mut MouseState,
selected: bool,
cx: &AppContext,
) -> ElementBox;
) -> ElementBox<Self>;
fn center_selection_after_match_updates(&self) -> bool {
false
}
@ -48,11 +48,11 @@ impl<D: PickerDelegate> View for Picker<D> {
"Picker"
}
fn render(&mut self, cx: &mut ViewContext<Self>) -> gpui::ElementBox {
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
let theme = (self.theme.lock())(&cx.global::<settings::Settings>().theme);
let query = self.query(cx);
let delegate = self.delegate.clone();
let match_count = if let Some(delegate) = delegate.upgrade(cx.app) {
let match_count = if let Some(delegate) = delegate.upgrade(cx) {
delegate.read(cx).match_count()
} else {
0
@ -97,15 +97,15 @@ impl<D: PickerDelegate> View for Picker<D> {
let selected_ix = delegate.read(cx).selected_index();
range.end = cmp::min(range.end, delegate.read(cx).match_count());
items.extend(range.map(move |ix| {
MouseEventHandler::<D>::new(ix, cx, |state, cx| {
MouseEventHandler::<D, _>::new(ix, cx, |state, cx| {
delegate
.read(cx)
.render_match(ix, state, ix == selected_ix, cx)
})
// Capture mouse events
.on_down(MouseButton::Left, |_, _| {})
.on_up(MouseButton::Left, |_, _| {})
.on_click(MouseButton::Left, move |_, cx| {
.on_down(MouseButton::Left, |_, _, _| {})
.on_up(MouseButton::Left, |_, _, _| {})
.on_click(MouseButton::Left, move |_, _, cx| {
cx.dispatch_action(SelectIndex(ix))
})
.with_cursor_style(CursorStyle::PointingHand)

View File

@ -1098,7 +1098,7 @@ impl ProjectPanel {
row_container_style: ContainerStyle,
style: &ProjectPanelEntry,
cx: &mut ViewContext<V>,
) -> ElementBox {
) -> ElementBox<V> {
let kind = details.kind;
let show_editor = details.is_editing && !details.is_processing;
@ -1155,8 +1155,8 @@ impl ProjectPanel {
dragged_entry_destination: &mut Option<Arc<Path>>,
theme: &theme::ProjectPanel,
cx: &mut ViewContext<Self>,
) -> ElementBox {
let this = cx.handle();
) -> ElementBox<Self> {
let this = cx.handle().downgrade();
let kind = details.kind;
let path = details.path.clone();
let padding = theme.container.padding.left + details.depth as f32 * theme.indent_width;
@ -1171,7 +1171,7 @@ impl ProjectPanel {
let show_editor = details.is_editing && !details.is_processing;
MouseEventHandler::<Self>::new(entry_id.to_usize(), cx, |state, cx| {
MouseEventHandler::<Self, _>::new(entry_id.to_usize(), cx, |state, cx| {
let mut style = entry_style.style_for(state, details.is_selected).clone();
if cx
@ -1201,7 +1201,7 @@ impl ProjectPanel {
cx,
)
})
.on_click(MouseButton::Left, move |e, cx| {
.on_click(MouseButton::Left, move |e, _, cx| {
if !show_editor {
if kind == EntryKind::Dir {
cx.dispatch_action(ToggleExpanded(entry_id))
@ -1213,13 +1213,13 @@ impl ProjectPanel {
}
}
})
.on_down(MouseButton::Right, move |e, cx| {
.on_down(MouseButton::Right, move |e, _, cx| {
cx.dispatch_action(DeployContextMenu {
entry_id,
position: e.position,
})
})
.on_up(MouseButton::Left, move |_, cx| {
.on_up(MouseButton::Left, move |_, _, cx| {
if let Some((_, dragged_entry)) = cx
.global::<DragAndDrop<Workspace>>()
.currently_dragged::<ProjectEntryId>(cx.window_id())
@ -1231,14 +1231,14 @@ impl ProjectPanel {
});
}
})
.on_move(move |_, cx| {
.on_move(move |_, _, cx| {
if cx
.global::<DragAndDrop<Workspace>>()
.currently_dragged::<ProjectEntryId>(cx.window_id())
.is_some()
{
if let Some(this) = this.upgrade(cx.app) {
this.update(cx.app, |this, _| {
if let Some(this) = this.upgrade(cx) {
this.update(cx, |this, _, _| {
this.dragged_entry_destination = if matches!(kind, EntryKind::File(_)) {
path.parent().map(|parent| Arc::from(parent))
} else {
@ -1251,7 +1251,7 @@ impl ProjectPanel {
.as_draggable(entry_id, {
let row_container_style = theme.dragged_entry.container;
move |_, cx: &mut ViewContext<Workspace>| {
move |_, _, cx: &mut ViewContext<Workspace>| {
let theme = cx.global::<Settings>().theme.clone();
Self::render_entry_visual_element(
&details,
@ -1273,7 +1273,7 @@ impl View for ProjectPanel {
"ProjectPanel"
}
fn render(&mut self, cx: &mut gpui::ViewContext<'_, Self>) -> gpui::ElementBox {
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> gpui::ElementBox<Self> {
enum ProjectPanel {}
let theme = &cx.global::<Settings>().theme.project_panel;
let mut container_style = theme.container;
@ -1285,7 +1285,7 @@ impl View for ProjectPanel {
if has_worktree {
Stack::new()
.with_child(
MouseEventHandler::<ProjectPanel>::new(0, cx, |_, cx| {
MouseEventHandler::<ProjectPanel, _>::new(0, cx, |_, cx| {
UniformList::new(
self.list.clone(),
self.visible_entries
@ -1317,7 +1317,7 @@ impl View for ProjectPanel {
.expanded()
.boxed()
})
.on_down(MouseButton::Right, move |e, cx| {
.on_down(MouseButton::Right, move |e, _, cx| {
// When deploying the context menu anywhere below the last project entry,
// act as if the user clicked the root of the last worktree.
if let Some(entry_id) = last_worktree_root_id {
@ -1334,7 +1334,7 @@ impl View for ProjectPanel {
} else {
Flex::column()
.with_child(
MouseEventHandler::<Self>::new(2, cx, {
MouseEventHandler::<Self, _>::new(2, cx, {
let button_style = theme.open_project_button.clone();
let context_menu_item_style =
cx.global::<Settings>().theme.context_menu.item.clone();
@ -1353,7 +1353,7 @@ impl View for ProjectPanel {
.boxed()
}
})
.on_click(MouseButton::Left, move |_, cx| {
.on_click(MouseButton::Left, move |_, _, cx| {
cx.dispatch_action(workspace::Open)
})
.with_cursor_style(CursorStyle::PointingHand)

View File

@ -91,7 +91,7 @@ impl View for BufferSearchBar {
}
}
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox {
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
let theme = cx.global::<Settings>().theme.clone();
let editor_container = if self.query_contains_error {
theme.search.invalid_editor
@ -324,7 +324,7 @@ impl BufferSearchBar {
icon: &'static str,
option: SearchOption,
cx: &mut ViewContext<Self>,
) -> Option<ElementBox> {
) -> Option<ElementBox<Self>> {
if !option_supported {
return None;
}
@ -332,7 +332,7 @@ impl BufferSearchBar {
let tooltip_style = cx.global::<Settings>().theme.tooltip.clone();
let is_active = self.is_search_option_enabled(option);
Some(
MouseEventHandler::<Self>::new(option as usize, cx, |state, cx| {
MouseEventHandler::<Self, _>::new(option as usize, cx, |state, cx| {
let style = cx
.global::<Settings>()
.theme
@ -344,11 +344,11 @@ impl BufferSearchBar {
.with_style(style.container)
.boxed()
})
.on_click(MouseButton::Left, move |_, cx| {
.on_click(MouseButton::Left, move |_, _, cx| {
cx.dispatch_any_action(option.to_toggle_action())
})
.with_cursor_style(CursorStyle::PointingHand)
.with_tooltip::<Self, _>(
.with_tooltip::<Self, _, _>(
option as usize,
format!("Toggle {}", option.label()),
Some(option.to_toggle_action()),
@ -364,7 +364,7 @@ impl BufferSearchBar {
icon: &'static str,
direction: Direction,
cx: &mut ViewContext<Self>,
) -> ElementBox {
) -> ElementBox<Self> {
let action: Box<dyn Action>;
let tooltip;
match direction {
@ -380,7 +380,7 @@ impl BufferSearchBar {
let tooltip_style = cx.global::<Settings>().theme.tooltip.clone();
enum NavButton {}
MouseEventHandler::<NavButton>::new(direction as usize, cx, |state, cx| {
MouseEventHandler::<NavButton, _>::new(direction as usize, cx, |state, cx| {
let style = cx
.global::<Settings>()
.theme
@ -394,10 +394,10 @@ impl BufferSearchBar {
})
.on_click(MouseButton::Left, {
let action = action.boxed_clone();
move |_, cx| cx.dispatch_any_action(action.boxed_clone())
mov_, _, cx| cx.dispatch_any_action(action.boxed_clone())
})
.with_cursor_style(CursorStyle::PointingHand)
.with_tooltip::<NavButton, _>(
.with_tooltip::<NavButton,_ _,, _>(
direction as usize,
tooltip.to_string(),
Some(action),
@ -407,13 +407,17 @@ impl BufferSearchBar {
.boxed()
}
fn render_close_button(&self, theme: &theme::Search, cx: &mut ViewContext<Self>) -> ElementBox {
fn render_close_button(
&self,
theme: &theme::Search,
cx: &mut ViewContext<Self>,
) -> ElementBox<Self> {
let action = Box::new(Dismiss);
let tooltip = "Dismiss Buffer Search";
let tooltip_style = cx.global::<Settings>().theme.tooltip.clone();
enum CloseButton {}
MouseEventHandler::<CloseButton>::new(0, cx, |state, _| {
MouseEventHandler::<CloseButton, _>::new(0, cx, |state, _| {
let style = theme.dismiss_button.style_for(state, false);
Svg::new("icons/x_mark_8.svg")
.with_color(style.color)
@ -428,10 +432,10 @@ impl BufferSearchBar {
})
.on_click(MouseButton::Left, {
let action = action.boxed_clone();
move |_, cx| cx.dispatch_any_action(action.boxed_clone())
move |_, _, _, cx| cx.dispatch_any_action(action.boxed_clone())
})
.with_cursor_style(CursorStyle::PointingHand)
.with_tooltip::<CloseButton, _>(0, tooltip.to_string(), Some(action), tooltip_style, cx)
.with_tooltip::<CloseButton>(0, tooltip.to_string(), Some(action), tooltip_style, cx)
.boxed()
}

View File

@ -177,7 +177,7 @@ impl View for ProjectSearchView {
"ProjectSearchView"
}
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox {
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
let model = &self.model.read(cx);
if model.match_ranges.is_empty() {
enum Status {}
@ -190,7 +190,7 @@ impl View for ProjectSearchView {
} else {
"No results"
};
MouseEventHandler::<Status>::new(0, cx, |_, _| {
MouseEventHandler::<Status, _>::new(0, cx, |_, _| {
Label::new(text, theme.search.results_status.clone())
.aligned()
.contained()
@ -198,7 +198,7 @@ impl View for ProjectSearchView {
.flex(1., true)
.boxed()
})
.on_down(MouseButton::Left, |_, cx| {
.on_down(MouseButton::Left, |_, _, _, cx| {
cx.focus_parent_view();
})
.boxed()
@ -249,7 +249,7 @@ impl Item for ProjectSearchView {
_detail: Option<usize>,
tab_theme: &theme::Tab,
cx: &AppContext,
) -> ElementBox {
) -> ElementBox<Pane> {
Flex::row()
.with_child(
Svg::new("icons/magnifying_glass_12.svg")
@ -364,7 +364,7 @@ impl Item for ProjectSearchView {
}
}
fn breadcrumbs(&self, theme: &theme::Theme, cx: &AppContext) -> Option<Vec<ElementBox>> {
fn breadcrumbs(&self, theme: &theme::Theme, cx: &AppContext) -> Option<Vec<ElementBox<Pane>>> {
self.results_editor.breadcrumbs(theme, cx)
}
@ -747,7 +747,7 @@ impl ProjectSearchBar {
icon: &'static str,
direction: Direction,
cx: &mut ViewContext<Self>,
) -> ElementBox {
) -> ElementBox<Self> {
let action: Box<dyn Action>;
let tooltip;
match direction {
@ -763,7 +763,7 @@ impl ProjectSearchBar {
let tooltip_style = cx.global::<Settings>().theme.tooltip.clone();
enum NavButton {}
MouseEventHandler::<NavButton>::new(direction as usize, cx, |state, cx| {
MouseEventHandler::<NavButton, _>::new(direction as usize, cx, |state, cx| {
let style = &cx
.global::<Settings>()
.theme
@ -775,13 +775,12 @@ impl ProjectSearchBar {
.with_style(style.container)
.boxed()
})
.on_click(MouseButton::Left, {
.on_click(MouseButton::Le {
let action = action.boxed_clone();
move |_, cx| cx.dispatch_any_action(action.boxed_clone())
})
move |_, _, cx| cx.dispatch_any_action(action.boxed_clone())
_, })
.with_cursor_style(CursorStyle::PointingHand)
.with_tooltip::<NavButton, _>(
direction as usize,
.with_tooltip::<NavButton, _ direction as usize,
tooltip.to_string(),
Some(action),
tooltip_style,
@ -795,10 +794,10 @@ impl ProjectSearchBar {
icon: &'static str,
option: SearchOption,
cx: &mut ViewContext<Self>,
) -> ElementBox {
) -> ElementBox<Self> {
let tooltip_style = cx.global::<Settings>().theme.tooltip.clone();
let is_active = self.is_option_enabled(option, cx);
MouseEventHandler::<Self>::new(option as usize, cx, |state, cx| {
MouseEventHandler::<Self, _>::new(option as usize, cx, |state, cx| {
let style = &cx
.global::<Settings>()
.theme
@ -810,11 +809,11 @@ impl ProjectSearchBar {
.with_style(style.container)
.boxed()
})
.on_click(MouseButton::Left, move |_, cx| {
.on_click(MouseButton::Left, move |_, _, cx| {
cx.dispatch_any_action(option.to_toggle_action())
})
.with_cursor_style(CursorStyle::PointingHand)
.with_tooltip::<Self, _>(
.with_tooltip::<Self>(
option as usize,
format!("Toggle {}", option.label()),
Some(option.to_toggle_action()),
@ -847,7 +846,7 @@ impl View for ProjectSearchBar {
"ProjectSearchBar"
}
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox {
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
if let Some(search) = self.active_project_search.as_ref() {
let search = search.read(cx);
let theme = cx.global::<Settings>().theme.clone();

View File

@ -42,7 +42,7 @@ impl View for TerminalButton {
"TerminalButton"
}
fn render(&mut self, cx: &mut ViewContext<'_, Self>) -> ElementBox {
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
let workspace = self.workspace.upgrade(cx);
let project = match workspace {
Some(workspace) => workspace.read(cx).project().read(cx),
@ -62,7 +62,7 @@ impl View for TerminalButton {
Stack::new()
.with_child(
MouseEventHandler::<Self>::new(0, cx, {
MouseEventHandler::<Self, _>::new(0, cx, {
let theme = theme.clone();
move |state, _cx| {
let style = theme
@ -96,7 +96,7 @@ impl View for TerminalButton {
}
})
.with_cursor_style(CursorStyle::PointingHand)
.on_click(MouseButton::Left, move |_, cx| {
.on_click(MouseButton::Left, move |_, _, cx| {
if has_terminals {
cx.dispatch_action(DeployTerminalMenu);
} else {
@ -105,7 +105,7 @@ impl View for TerminalButton {
}
};
})
.with_tooltip::<Self, _>(
.with_tooltip::<Self>(
0,
"Show Terminal".into(),
Some(Box::new(FocusDock)),

View File

@ -100,7 +100,7 @@ impl LayoutCell {
};
self.text
.paint(pos, visible_bounds, layout.size.line_height, view, cx);
.paint(scene, pos, visible_bounds, layout.size.line_height, cx);
}
}
@ -128,7 +128,14 @@ impl LayoutRect {
}
}
fn paint(&self, origin: Vector2F, layout: &LayoutState, cx: &mut PaintContext) {
fn paint(
&self,
scene: &mut SceneBuilder,
origin: Vector2F,
layout: &LayoutState,
view: &mut TerminalView,
cx: &mut ViewContext<TerminalView>,
) {
let position = {
let point = self.point;
vec2f(
@ -363,11 +370,11 @@ impl TerminalElement {
connection: WeakModelHandle<Terminal>,
origin: Vector2F,
f: impl Fn(&mut Terminal, Vector2F, E, &mut ModelContext<Terminal>),
) -> impl Fn(E, &mut EventContext) {
move |event, cx| {
) -> impl Fn(E, &mut TerminalView, &mut EventContext<TerminalView>) {
move |event, _: &mut TerminalView, cx| {
cx.focus_parent_view();
if let Some(conn_handle) = connection.upgrade(cx.app) {
conn_handle.update(cx.app, |terminal, cx| {
if let Some(conn_handle) = connection.upgrade(cx) {
conn_handle.update(cx, |terminal, cx| {
f(terminal, origin, event, cx);
cx.notify();
@ -378,6 +385,7 @@ impl TerminalElement {
fn attach_mouse_handlers(
&self,
scene: &mut SceneBuilder,
origin: Vector2F,
view_id: usize,
visible_bounds: RectF,
@ -402,10 +410,10 @@ impl TerminalElement {
),
)
// Update drag selections
.on_drag(MouseButton::Left, move |event, cx| {
.on_drag(MouseButton::Left, move |event, _, cx| {
if cx.is_parent_view_focused() {
if let Some(conn_handle) = connection.upgrade(cx.app) {
conn_handle.update(cx.app, |terminal, cx| {
if let Some(conn_handle) = connection.upgrade(cx) {
conn_handle.update(cx, |terminal, cx| {
terminal.mouse_drag(event, origin);
cx.notify();
})
@ -424,9 +432,9 @@ impl TerminalElement {
),
)
// Context menu
.on_click(MouseButton::Right, move |e, cx| {
let mouse_mode = if let Some(conn_handle) = connection.upgrade(cx.app) {
conn_handle.update(cx.app, |terminal, _cx| terminal.mouse_mode(e.shift))
.on_click(MouseButton::Right, move |e, _, cx| {
let mouse_mode = if let Some(conn_handle) = connection.upgrade(cx) {
conn_handle.update(cx, |terminal, _cx| terminal.mouse_mode(e.shift))
} else {
// If we can't get the model handle, probably can't deploy the context menu
true
@ -437,20 +445,19 @@ impl TerminalElement {
});
}
})
.on_move(move |event, cx| {
.on_move(move |event, _, cx| {
if cx.is_parent_view_focused() {
if let Some(conn_handle) = connection.upgrade(cx.app) {
conn_handle.update(cx.app, |terminal, cx| {
if let Some(conn_handle) = connection.upgrade(cx) {
conn_handle.update(cx, |terminal, cx| {
terminal.mouse_move(&event, origin);
cx.notify();
})
}
}
})
.on_scroll(move |event, cx| {
// cx.focus_parent_view();
if let Some(conn_handle) = connection.upgrade(cx.app) {
conn_handle.update(cx.app, |terminal, cx| {
.on_scroll(move |event, _, cx| {
if let Some(conn_handle) = connection.upgrade(cx) {
conn_handle.update(cx, |terminal, cx| {
terminal.scroll_wheel(event, origin);
cx.notify();
})
@ -548,7 +555,7 @@ impl TerminalElement {
}
}
impl Element for TerminalElement {
impl Element<TerminalView> for TerminalElement {
type LayoutState = LayoutState;
type PaintState = ();
@ -584,7 +591,7 @@ impl Element for TerminalElement {
let background_color = terminal_theme.background;
let terminal_handle = self.terminal.upgrade(cx).unwrap();
let last_hovered_hyperlink = terminal_handle.update(cx.app, |terminal, cx| {
let last_hovered_hyperlink = terminal_handle.update(cx, |terminal, cx| {
terminal.set_size(dimensions);
terminal.try_sync(cx);
terminal.last_content.last_hovered_hyperlink.clone()
@ -724,6 +731,7 @@ impl Element for TerminalElement {
bounds: RectF,
visible_bounds: RectF,
layout: &mut Self::LayoutState,
view: &mut TerminalView,
cx: &mut ViewContext<TerminalView>,
) -> Self::PaintState {
let visible_bounds = bounds.intersection(visible_bounds).unwrap_or_default();
@ -735,7 +743,14 @@ impl Element for TerminalElement {
let origin = bounds.origin() + vec2f(layout.size.cell_width, 0.);
// Elements are ephemeral, only at paint time do we know what could be clicked by a mouse
self.attach_mouse_handlers(origin, self.view.id(), visible_bounds, layout.mode, cx);
self.attach_mouse_handlers(
origin,
self.view.id(),
visible_bounds,
layout.mode,
view,
cx,
);
scene.push_cursor_region(gpui::CursorRegion {
bounds,
@ -756,7 +771,7 @@ impl Element for TerminalElement {
});
for rect in &layout.rects {
rect.paint(origin, layout, cx)
rect.paint(scene, origin, layout, view, cx)
}
});
@ -797,7 +812,7 @@ impl Element for TerminalElement {
}
if let Some(element) = &mut layout.hyperlink_tooltip {
Element<TerminalView>::paint(element, scene, origin, visible_bounds, view, cx)
Element::paint(element, scene, origin, visible_bounds, view, view, cx)
}
});
}
@ -808,10 +823,11 @@ impl Element for TerminalElement {
fn debug(
&self,
_bounds: RectF,
_layout: &Self::LayoutState,
_paint: &Self::PaintState,
_cx: &gpui::DebugContext,
_: RectF,
_: &Self::LayoutState,
_: &Self::PaintState,
_: &TerminalView,
_: &gpui::ViewContext<TerminalView>,
) -> gpui::serde_json::Value {
json!({
"type": "TerminalElement",
@ -825,7 +841,8 @@ impl Element for TerminalElement {
_: RectF,
layout: &Self::LayoutState,
_: &Self::PaintState,
_: &gpui::MeasurementContext,
_: &TerminalView,
_: &gpui::ViewContext<TerminalView>,
) -> Option<RectF> {
// Use the same origin that's passed to `Cursor::paint` in the paint
// method bove.

View File

@ -236,7 +236,7 @@ impl TerminalView {
cx.notify();
}
pub fn should_show_cursor(&self, focused: bool, cx: &mut gpui::ViewContext<'_, Self>) -> bool {
pub fn should_show_cursor(&self, focused: bool, cx: &mut gpui::ViewContext<Self>) -> bool {
//Don't blink the cursor when not focused, blinking is disabled, or paused
if !focused
|| !self.blinking_on
@ -384,7 +384,7 @@ impl View for TerminalView {
"Terminal"
}
fn render(&mut self, cx: &mut gpui::ViewContext<'_, Self>) -> ElementBox {
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> ElementBox<Self> {
let terminal_handle = self.terminal.clone().downgrade();
let self_id = cx.view_id();
@ -544,7 +544,7 @@ impl Item for TerminalView {
_detail: Option<usize>,
tab_theme: &theme::Tab,
cx: &gpui::AppContext,
) -> ElementBox {
) -> ElementBox<Pane> {
let title = self.terminal().read(cx).title();
Flex::row()
@ -606,7 +606,7 @@ impl Item for TerminalView {
ToolbarItemLocation::PrimaryLeft { flex: None }
}
fn breadcrumbs(&self, theme: &theme::Theme, cx: &AppContext) -> Option<Vec<ElementBox>> {
fn breadcrumbs(&self, theme: &theme::Theme, cx: &AppContext) -> Option<Vec<ElementBox<Pane>>> {
Some(vec![Text::new(
self.terminal().read(cx).breadcrumb_text.clone(),
theme.workspace.breadcrumbs.default.text.clone(),

View File

@ -34,11 +34,11 @@ impl ThemeTestbench {
workspace.add_item(Box::new(view), cx);
}
fn render_ramps(color_scheme: &ColorScheme) -> Flex {
fn display_ramp(ramp: &Vec<Color>) -> ElementBox {
fn render_ramps(color_scheme: &ColorScheme) -> Flex<Self> {
fn display_ramp(ramp: &Vec<Color>) -> ElementBox<ThemeTestbench> {
Flex::row()
.with_children(ramp.iter().cloned().map(|color| {
Canvas::new(move |bounds, _, cx| {
Canvas::new(move |scene, bounds, _, _, _| {
scene.push_quad(Quad {
bounds,
background: Some(color),
@ -67,8 +67,8 @@ impl ThemeTestbench {
fn render_layer(
layer_index: usize,
layer: &Layer,
cx: &mut ViewContext<'_, Self>,
) -> Container {
cx: &mut ViewContext<Self>,
) -> Container<Self> {
Flex::column()
.with_child(
Self::render_button_set(0, layer_index, "base", &layer.base, cx)
@ -123,8 +123,8 @@ impl ThemeTestbench {
layer_index: usize,
set_name: &'static str,
style_set: &StyleSet,
cx: &mut ViewContext<'_, Self>,
) -> Flex {
cx: &mut ViewContext<Self>,
) -> Flex<Self> {
Flex::row()
.with_child(Self::render_button(
set_index * 6,
@ -182,10 +182,10 @@ impl ThemeTestbench {
text: &'static str,
style_set: &StyleSet,
style_override: Option<fn(&StyleSet) -> &Style>,
cx: &mut ViewContext<'_, Self>,
) -> ElementBox {
cx: &mut ViewContext<Self>,
) -> ElementBox<Self> {
enum TestBenchButton {}
MouseEventHandler::<TestBenchButton>::new(layer_index + button_index, cx, |state, cx| {
MouseEventHandler::<TestBenchButton, _>::new(layer_index + button_index, cx, |state, cx| {
let style = if let Some(style_override) = style_override {
style_override(&style_set)
} else if state.clicked().is_some() {
@ -230,7 +230,7 @@ impl ThemeTestbench {
.boxed()
}
fn render_label(text: String, style: &Style, cx: &mut ViewContext<'_, Self>) -> Label {
fn render_label(text: String, style: &Style, cx: &mut ViewContext<Self>) -> Label {
let settings = cx.global::<Settings>();
let font_cache = cx.font_cache();
let family_id = settings.buffer_font_family;
@ -262,7 +262,7 @@ impl View for ThemeTestbench {
"ThemeTestbench"
}
fn render(&mut self, cx: &mut gpui::ViewContext<'_, Self>) -> gpui::ElementBox {
fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> ElementBox<Self> {
let color_scheme = &cx.global::<Settings>().theme.clone().color_scheme;
Flex::row()
@ -303,7 +303,7 @@ impl Item for ThemeTestbench {
_: Option<usize>,
style: &theme::Tab,
_: &AppContext,
) -> gpui::ElementBox {
) -> ElementBox<Pane> {
Label::new("Theme Testbench", style.label.clone())
.aligned()
.contained()