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" "ActivityIndicator"
} }
fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox { fn render(&mut self, cx: &mut ViewContext<Self>) -> ElementBox<Self> {
let Content { let Content {
icon, icon,
message, message,
action, action,
} = self.content_to_render(cx); } = 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 let theme = &cx
.global::<Settings>() .global::<Settings>()
.theme .theme

View File

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

View File

@ -91,7 +91,7 @@ impl View for CopilotButton {
"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>(); let settings = cx.global::<Settings>();
if !settings.enable_copilot_integration { if !settings.enable_copilot_integration {
@ -111,7 +111,7 @@ impl View for CopilotButton {
Stack::new() Stack::new()
.with_child( .with_child(
MouseEventHandler::<Self>::new(0, cx, { MouseEventHandler::<Self, _>::new(0, cx, {
let theme = theme.clone(); let theme = theme.clone();
let status = status.clone(); let status = status.clone();
move |state, _cx| { move |state, _cx| {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -156,7 +156,7 @@ impl View for GoToLine {
"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 theme = &cx.global::<Settings>().theme.picker;
let label = format!( let label = format!(

View File

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

View File

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

View File

@ -11,7 +11,11 @@ use collections::HashMap;
use pathfinder_geometry::rect::RectF; use pathfinder_geometry::rect::RectF;
use smallvec::SmallVec; 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::{ use super::{
mouse_event::{ 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>; pub type HandlerCallback = Rc<dyn Fn(MouseEvent, &mut dyn Any, &mut WindowContext, usize) -> bool>;
#[derive(Clone, PartialEq, Eq, Hash)] #[derive(Clone, PartialEq, Eq, Hash)]

View File

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

View File

@ -1098,7 +1098,7 @@ impl ProjectPanel {
row_container_style: ContainerStyle, row_container_style: ContainerStyle,
style: &ProjectPanelEntry, style: &ProjectPanelEntry,
cx: &mut ViewContext<V>, cx: &mut ViewContext<V>,
) -> ElementBox { ) -> ElementBox<V> {
let kind = details.kind; let kind = details.kind;
let show_editor = details.is_editing && !details.is_processing; let show_editor = details.is_editing && !details.is_processing;
@ -1155,8 +1155,8 @@ impl ProjectPanel {
dragged_entry_destination: &mut Option<Arc<Path>>, dragged_entry_destination: &mut Option<Arc<Path>>,
theme: &theme::ProjectPanel, theme: &theme::ProjectPanel,
cx: &mut ViewContext<Self>, cx: &mut ViewContext<Self>,
) -> ElementBox { ) -> ElementBox<Self> {
let this = cx.handle(); let this = cx.handle().downgrade();
let kind = details.kind; let kind = details.kind;
let path = details.path.clone(); let path = details.path.clone();
let padding = theme.container.padding.left + details.depth as f32 * theme.indent_width; 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; 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(); let mut style = entry_style.style_for(state, details.is_selected).clone();
if cx if cx
@ -1201,7 +1201,7 @@ impl ProjectPanel {
cx, cx,
) )
}) })
.on_click(MouseButton::Left, move |e, cx| { .on_click(MouseButton::Left, move |e, _, cx| {
if !show_editor { if !show_editor {
if kind == EntryKind::Dir { if kind == EntryKind::Dir {
cx.dispatch_action(ToggleExpanded(entry_id)) 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 { cx.dispatch_action(DeployContextMenu {
entry_id, entry_id,
position: e.position, position: e.position,
}) })
}) })
.on_up(MouseButton::Left, move |_, cx| { .on_up(MouseButton::Left, move |_, _, cx| {
if let Some((_, dragged_entry)) = cx if let Some((_, dragged_entry)) = cx
.global::<DragAndDrop<Workspace>>() .global::<DragAndDrop<Workspace>>()
.currently_dragged::<ProjectEntryId>(cx.window_id()) .currently_dragged::<ProjectEntryId>(cx.window_id())
@ -1231,14 +1231,14 @@ impl ProjectPanel {
}); });
} }
}) })
.on_move(move |_, cx| { .on_move(move |_, _, cx| {
if cx if cx
.global::<DragAndDrop<Workspace>>() .global::<DragAndDrop<Workspace>>()
.currently_dragged::<ProjectEntryId>(cx.window_id()) .currently_dragged::<ProjectEntryId>(cx.window_id())
.is_some() .is_some()
{ {
if let Some(this) = this.upgrade(cx.app) { if let Some(this) = this.upgrade(cx) {
this.update(cx.app, |this, _| { this.update(cx, |this, _, _| {
this.dragged_entry_destination = if matches!(kind, EntryKind::File(_)) { this.dragged_entry_destination = if matches!(kind, EntryKind::File(_)) {
path.parent().map(|parent| Arc::from(parent)) path.parent().map(|parent| Arc::from(parent))
} else { } else {
@ -1251,7 +1251,7 @@ impl ProjectPanel {
.as_draggable(entry_id, { .as_draggable(entry_id, {
let row_container_style = theme.dragged_entry.container; 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(); let theme = cx.global::<Settings>().theme.clone();
Self::render_entry_visual_element( Self::render_entry_visual_element(
&details, &details,
@ -1273,7 +1273,7 @@ impl View for ProjectPanel {
"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 {} enum ProjectPanel {}
let theme = &cx.global::<Settings>().theme.project_panel; let theme = &cx.global::<Settings>().theme.project_panel;
let mut container_style = theme.container; let mut container_style = theme.container;
@ -1285,7 +1285,7 @@ impl View for ProjectPanel {
if has_worktree { if has_worktree {
Stack::new() Stack::new()
.with_child( .with_child(
MouseEventHandler::<ProjectPanel>::new(0, cx, |_, cx| { MouseEventHandler::<ProjectPanel, _>::new(0, cx, |_, cx| {
UniformList::new( UniformList::new(
self.list.clone(), self.list.clone(),
self.visible_entries self.visible_entries
@ -1317,7 +1317,7 @@ impl View for ProjectPanel {
.expanded() .expanded()
.boxed() .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, // When deploying the context menu anywhere below the last project entry,
// act as if the user clicked the root of the last worktree. // act as if the user clicked the root of the last worktree.
if let Some(entry_id) = last_worktree_root_id { if let Some(entry_id) = last_worktree_root_id {
@ -1334,7 +1334,7 @@ impl View for ProjectPanel {
} else { } else {
Flex::column() Flex::column()
.with_child( .with_child(
MouseEventHandler::<Self>::new(2, cx, { MouseEventHandler::<Self, _>::new(2, cx, {
let button_style = theme.open_project_button.clone(); let button_style = theme.open_project_button.clone();
let context_menu_item_style = let context_menu_item_style =
cx.global::<Settings>().theme.context_menu.item.clone(); cx.global::<Settings>().theme.context_menu.item.clone();
@ -1353,7 +1353,7 @@ impl View for ProjectPanel {
.boxed() .boxed()
} }
}) })
.on_click(MouseButton::Left, move |_, cx| { .on_click(MouseButton::Left, move |_, _, cx| {
cx.dispatch_action(workspace::Open) cx.dispatch_action(workspace::Open)
}) })
.with_cursor_style(CursorStyle::PointingHand) .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 theme = cx.global::<Settings>().theme.clone();
let editor_container = if self.query_contains_error { let editor_container = if self.query_contains_error {
theme.search.invalid_editor theme.search.invalid_editor
@ -324,7 +324,7 @@ impl BufferSearchBar {
icon: &'static str, icon: &'static str,
option: SearchOption, option: SearchOption,
cx: &mut ViewContext<Self>, cx: &mut ViewContext<Self>,
) -> Option<ElementBox> { ) -> Option<ElementBox<Self>> {
if !option_supported { if !option_supported {
return None; return None;
} }
@ -332,7 +332,7 @@ impl BufferSearchBar {
let tooltip_style = cx.global::<Settings>().theme.tooltip.clone(); let tooltip_style = cx.global::<Settings>().theme.tooltip.clone();
let is_active = self.is_search_option_enabled(option); let is_active = self.is_search_option_enabled(option);
Some( Some(
MouseEventHandler::<Self>::new(option as usize, cx, |state, cx| { MouseEventHandler::<Self, _>::new(option as usize, cx, |state, cx| {
let style = cx let style = cx
.global::<Settings>() .global::<Settings>()
.theme .theme
@ -344,11 +344,11 @@ impl BufferSearchBar {
.with_style(style.container) .with_style(style.container)
.boxed() .boxed()
}) })
.on_click(MouseButton::Left, move |_, cx| { .on_click(MouseButton::Left, move |_, _, cx| {
cx.dispatch_any_action(option.to_toggle_action()) cx.dispatch_any_action(option.to_toggle_action())
}) })
.with_cursor_style(CursorStyle::PointingHand) .with_cursor_style(CursorStyle::PointingHand)
.with_tooltip::<Self, _>( .with_tooltip::<Self, _, _>(
option as usize, option as usize,
format!("Toggle {}", option.label()), format!("Toggle {}", option.label()),
Some(option.to_toggle_action()), Some(option.to_toggle_action()),
@ -364,7 +364,7 @@ impl BufferSearchBar {
icon: &'static str, icon: &'static str,
direction: Direction, direction: Direction,
cx: &mut ViewContext<Self>, cx: &mut ViewContext<Self>,
) -> ElementBox { ) -> ElementBox<Self> {
let action: Box<dyn Action>; let action: Box<dyn Action>;
let tooltip; let tooltip;
match direction { match direction {
@ -380,7 +380,7 @@ impl BufferSearchBar {
let tooltip_style = cx.global::<Settings>().theme.tooltip.clone(); let tooltip_style = cx.global::<Settings>().theme.tooltip.clone();
enum NavButton {} enum NavButton {}
MouseEventHandler::<NavButton>::new(direction as usize, cx, |state, cx| { MouseEventHandler::<NavButton, _>::new(direction as usize, cx, |state, cx| {
let style = cx let style = cx
.global::<Settings>() .global::<Settings>()
.theme .theme
@ -394,10 +394,10 @@ impl BufferSearchBar {
}) })
.on_click(MouseButton::Left, { .on_click(MouseButton::Left, {
let action = action.boxed_clone(); 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_cursor_style(CursorStyle::PointingHand)
.with_tooltip::<NavButton, _>( .with_tooltip::<NavButton,_ _,, _>(
direction as usize, direction as usize,
tooltip.to_string(), tooltip.to_string(),
Some(action), Some(action),
@ -407,13 +407,17 @@ impl BufferSearchBar {
.boxed() .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 action = Box::new(Dismiss);
let tooltip = "Dismiss Buffer Search"; let tooltip = "Dismiss Buffer Search";
let tooltip_style = cx.global::<Settings>().theme.tooltip.clone(); let tooltip_style = cx.global::<Settings>().theme.tooltip.clone();
enum CloseButton {} enum CloseButton {}
MouseEventHandler::<CloseButton>::new(0, cx, |state, _| { MouseEventHandler::<CloseButton, _>::new(0, cx, |state, _| {
let style = theme.dismiss_button.style_for(state, false); let style = theme.dismiss_button.style_for(state, false);
Svg::new("icons/x_mark_8.svg") Svg::new("icons/x_mark_8.svg")
.with_color(style.color) .with_color(style.color)
@ -428,10 +432,10 @@ impl BufferSearchBar {
}) })
.on_click(MouseButton::Left, { .on_click(MouseButton::Left, {
let action = action.boxed_clone(); 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_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() .boxed()
} }

View File

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

View File

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

View File

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

View File

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

View File

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