Track focus shenanigans with context menu
Co-Authored-By: Max Brunsfeld <max@zed.dev>
This commit is contained in:
parent
970c7b8987
commit
79e6dedb7a
3 changed files with 15 additions and 32 deletions
|
@ -5,7 +5,7 @@ use gpui::{
|
||||||
FontStyle, FontWeight, HighlightStyle, Hsla, InteractiveElement, InteractiveElementState,
|
FontStyle, FontWeight, HighlightStyle, Hsla, InteractiveElement, InteractiveElementState,
|
||||||
IntoElement, LayoutId, Model, ModelContext, ModifiersChangedEvent, MouseButton, Pixels,
|
IntoElement, LayoutId, Model, ModelContext, ModifiersChangedEvent, MouseButton, Pixels,
|
||||||
PlatformInputHandler, Point, Rgba, ShapedLine, Size, StatefulInteractiveElement, Styled,
|
PlatformInputHandler, Point, Rgba, ShapedLine, Size, StatefulInteractiveElement, Styled,
|
||||||
TextRun, TextStyle, TextSystem, UnderlineStyle, View, WhiteSpace, WindowContext,
|
TextRun, TextStyle, TextSystem, UnderlineStyle, WhiteSpace, WindowContext,
|
||||||
};
|
};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use language::CursorShape;
|
use language::CursorShape;
|
||||||
|
@ -27,8 +27,6 @@ use ui::Tooltip;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::{fmt::Debug, ops::RangeInclusive};
|
use std::{fmt::Debug, ops::RangeInclusive};
|
||||||
|
|
||||||
use crate::TerminalView;
|
|
||||||
|
|
||||||
///The information generated during layout that is necessary for painting
|
///The information generated during layout that is necessary for painting
|
||||||
pub struct LayoutState {
|
pub struct LayoutState {
|
||||||
cells: Vec<LayoutCell>,
|
cells: Vec<LayoutCell>,
|
||||||
|
@ -149,7 +147,6 @@ impl LayoutRect {
|
||||||
///We need to keep a reference to the view for mouse events, do we need it for any other terminal stuff, or can we move that to connection?
|
///We need to keep a reference to the view for mouse events, do we need it for any other terminal stuff, or can we move that to connection?
|
||||||
pub struct TerminalElement {
|
pub struct TerminalElement {
|
||||||
terminal: Model<Terminal>,
|
terminal: Model<Terminal>,
|
||||||
terminal_view: View<TerminalView>,
|
|
||||||
focus: FocusHandle,
|
focus: FocusHandle,
|
||||||
focused: bool,
|
focused: bool,
|
||||||
cursor_visible: bool,
|
cursor_visible: bool,
|
||||||
|
@ -168,7 +165,6 @@ impl StatefulInteractiveElement for TerminalElement {}
|
||||||
impl TerminalElement {
|
impl TerminalElement {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
terminal: Model<Terminal>,
|
terminal: Model<Terminal>,
|
||||||
terminal_view: View<TerminalView>,
|
|
||||||
focus: FocusHandle,
|
focus: FocusHandle,
|
||||||
focused: bool,
|
focused: bool,
|
||||||
cursor_visible: bool,
|
cursor_visible: bool,
|
||||||
|
@ -176,7 +172,6 @@ impl TerminalElement {
|
||||||
) -> TerminalElement {
|
) -> TerminalElement {
|
||||||
TerminalElement {
|
TerminalElement {
|
||||||
terminal,
|
terminal,
|
||||||
terminal_view,
|
|
||||||
focused,
|
focused,
|
||||||
focus: focus.clone(),
|
focus: focus.clone(),
|
||||||
cursor_visible,
|
cursor_visible,
|
||||||
|
@ -774,18 +769,11 @@ impl Element for TerminalElement {
|
||||||
(layout_id, interactive_state)
|
(layout_id, interactive_state)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn paint(
|
fn paint(self, bounds: Bounds<Pixels>, state: &mut Self::State, cx: &mut WindowContext<'_>) {
|
||||||
mut self,
|
|
||||||
bounds: Bounds<Pixels>,
|
|
||||||
state: &mut Self::State,
|
|
||||||
cx: &mut WindowContext<'_>,
|
|
||||||
) {
|
|
||||||
let mut layout = self.compute_layout(bounds, cx);
|
let mut layout = self.compute_layout(bounds, cx);
|
||||||
|
|
||||||
let theme = cx.theme();
|
let theme = cx.theme();
|
||||||
|
|
||||||
let dispatch_context = self.terminal_view.read(cx).dispatch_context(cx);
|
|
||||||
self.interactivity().key_context = Some(dispatch_context);
|
|
||||||
cx.paint_quad(
|
cx.paint_quad(
|
||||||
bounds,
|
bounds,
|
||||||
Default::default(),
|
Default::default(),
|
||||||
|
|
|
@ -632,7 +632,6 @@ impl Render for TerminalView {
|
||||||
|
|
||||||
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
|
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
|
||||||
let terminal_handle = self.terminal.clone();
|
let terminal_handle = self.terminal.clone();
|
||||||
let this_view = cx.view().clone();
|
|
||||||
|
|
||||||
let self_id = cx.entity_id();
|
let self_id = cx.entity_id();
|
||||||
let focused = self.focus_handle.is_focused(cx);
|
let focused = self.focus_handle.is_focused(cx);
|
||||||
|
@ -640,22 +639,25 @@ impl Render for TerminalView {
|
||||||
div()
|
div()
|
||||||
.size_full()
|
.size_full()
|
||||||
.relative()
|
.relative()
|
||||||
|
.track_focus(&self.focus_handle)
|
||||||
|
.key_context(self.dispatch_context(cx))
|
||||||
|
.on_action(cx.listener(TerminalView::send_text))
|
||||||
|
.on_action(cx.listener(TerminalView::send_keystroke))
|
||||||
|
.on_action(cx.listener(TerminalView::copy))
|
||||||
|
.on_action(cx.listener(TerminalView::paste))
|
||||||
|
.on_action(cx.listener(TerminalView::clear))
|
||||||
|
.on_action(cx.listener(TerminalView::show_character_palette))
|
||||||
|
.on_action(cx.listener(TerminalView::select_all))
|
||||||
|
.on_focus_in(cx.listener(Self::focus_in))
|
||||||
|
.on_focus_out(cx.listener(Self::focus_out))
|
||||||
|
.on_key_down(cx.listener(Self::key_down))
|
||||||
.child(
|
.child(
|
||||||
div()
|
div()
|
||||||
.z_index(0)
|
.z_index(0)
|
||||||
.absolute()
|
.absolute()
|
||||||
.size_full()
|
.size_full()
|
||||||
.on_key_down(cx.listener(Self::key_down))
|
|
||||||
.on_action(cx.listener(TerminalView::send_text))
|
|
||||||
.on_action(cx.listener(TerminalView::send_keystroke))
|
|
||||||
.on_action(cx.listener(TerminalView::copy))
|
|
||||||
.on_action(cx.listener(TerminalView::paste))
|
|
||||||
.on_action(cx.listener(TerminalView::clear))
|
|
||||||
.on_action(cx.listener(TerminalView::show_character_palette))
|
|
||||||
.on_action(cx.listener(TerminalView::select_all))
|
|
||||||
.child(TerminalElement::new(
|
.child(TerminalElement::new(
|
||||||
terminal_handle,
|
terminal_handle,
|
||||||
this_view,
|
|
||||||
self.focus_handle.clone(),
|
self.focus_handle.clone(),
|
||||||
focused,
|
focused,
|
||||||
self.should_show_cursor(focused, cx),
|
self.should_show_cursor(focused, cx),
|
||||||
|
@ -675,9 +677,6 @@ impl Render for TerminalView {
|
||||||
.anchor(gpui::AnchorCorner::TopLeft)
|
.anchor(gpui::AnchorCorner::TopLeft)
|
||||||
.child(menu.clone())
|
.child(menu.clone())
|
||||||
}))
|
}))
|
||||||
.track_focus(&self.focus_handle)
|
|
||||||
.on_focus_in(cx.listener(Self::focus_in))
|
|
||||||
.on_focus_out(cx.listener(Self::focus_out))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -239,7 +239,6 @@ impl Render for ContextMenu {
|
||||||
action,
|
action,
|
||||||
} => {
|
} => {
|
||||||
let handler = handler.clone();
|
let handler = handler.clone();
|
||||||
let dismiss = cx.listener(|_, _, cx| cx.emit(DismissEvent));
|
|
||||||
|
|
||||||
let label_element = if let Some(icon) = icon {
|
let label_element = if let Some(icon) = icon {
|
||||||
h_stack()
|
h_stack()
|
||||||
|
@ -263,10 +262,7 @@ impl Render for ContextMenu {
|
||||||
})),
|
})),
|
||||||
)
|
)
|
||||||
.selected(Some(ix) == self.selected_index)
|
.selected(Some(ix) == self.selected_index)
|
||||||
.on_click(move |event, cx| {
|
.on_click(move |_, cx| handler(cx))
|
||||||
handler(cx);
|
|
||||||
dismiss(event, cx)
|
|
||||||
})
|
|
||||||
.into_any_element()
|
.into_any_element()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue