Finish all but the styling

This commit is contained in:
Kirill Bulatov
2023-12-20 18:23:08 +02:00
parent 75074c3297
commit 8471a5f80b
3 changed files with 167 additions and 155 deletions
@@ -91,6 +91,14 @@ impl UniformListScrollHandle {
} }
} }
} }
pub fn scroll_top(&self) -> Pixels {
if let Some(state) = &*self.0.borrow() {
-state.scroll_offset.borrow().y
} else {
Pixels::ZERO
}
}
} }
impl Styled for UniformList { impl Styled for UniformList {
+84 -86
View File
@@ -2,17 +2,16 @@ use collections::{HashMap, VecDeque};
use editor::{Editor, EditorElement, EditorEvent, MoveToEnd}; use editor::{Editor, EditorElement, EditorEvent, MoveToEnd};
use futures::{channel::mpsc, StreamExt}; use futures::{channel::mpsc, StreamExt};
use gpui::{ use gpui::{
actions, div, overlay, red, AnchorCorner, AnyElement, AppContext, Context, CursorStyle, Div, actions, div, overlay, red, AnyElement, AppContext, Context, CursorStyle, Div, EventEmitter,
EventEmitter, FocusHandle, FocusableView, InteractiveElement, IntoElement, Model, ModelContext, FocusHandle, FocusableView, InteractiveElement, IntoElement, Model, ModelContext, MouseButton,
MouseButton, OverlayFitMode, ParentElement, Render, Styled, Subscription, View, ViewContext, MouseDownEvent, ParentElement, Render, Styled, Subscription, View, ViewContext, VisualContext,
VisualContext, WeakModel, WindowContext, WeakModel, WindowContext,
}; };
use language::{LanguageServerId, LanguageServerName}; use language::{LanguageServerId, LanguageServerName};
use lsp::IoKind; use lsp::IoKind;
use project::{search::SearchQuery, Project}; use project::{search::SearchQuery, Project};
use std::{borrow::Cow, sync::Arc}; use std::{borrow::Cow, sync::Arc};
use theme::{ActiveTheme, Theme}; use ui::{h_stack, v_stack, Checkbox, Label};
use ui::{h_stack, v_stack, Label};
use workspace::{ use workspace::{
item::{Item, ItemHandle}, item::{Item, ItemHandle},
searchable::{SearchEvent, SearchableItem, SearchableItemHandle}, searchable::{SearchEvent, SearchableItem, SearchableItemHandle},
@@ -83,7 +82,7 @@ actions!(debug, [OpenLanguageServerLogs]);
pub fn init(cx: &mut AppContext) { pub fn init(cx: &mut AppContext) {
let log_store = cx.build_model(|cx| LogStore::new(cx)); let log_store = cx.build_model(|cx| LogStore::new(cx));
cx.observe_new_views(|workspace: &mut Workspace, cx| { cx.observe_new_views(move |workspace: &mut Workspace, cx| {
let project = workspace.project(); let project = workspace.project();
if project.read(cx).is_local() { if project.read(cx).is_local() {
log_store.update(cx, |store, cx| { log_store.update(cx, |store, cx| {
@@ -91,7 +90,8 @@ pub fn init(cx: &mut AppContext) {
}); });
} }
workspace.register_action(|workspace, _: &OpenLanguageServerLogs, cx| { let log_store = log_store.clone();
workspace.register_action(move |workspace, _: &OpenLanguageServerLogs, cx| {
let project = workspace.project().read(cx); let project = workspace.project().read(cx);
if project.is_local() { if project.is_local() {
workspace.add_item( workspace.add_item(
@@ -118,7 +118,7 @@ impl LogStore {
if let Some(this) = this.upgrade() { if let Some(this) = this.upgrade() {
this.update(&mut cx, |this, cx| { this.update(&mut cx, |this, cx| {
this.on_io(project, server_id, io_kind, &message, cx); this.on_io(project, server_id, io_kind, &message, cx);
}); })?;
} }
} }
anyhow::Ok(()) anyhow::Ok(())
@@ -130,7 +130,7 @@ impl LogStore {
pub fn add_project(&mut self, project: &Model<Project>, cx: &mut ModelContext<Self>) { pub fn add_project(&mut self, project: &Model<Project>, cx: &mut ModelContext<Self>) {
let weak_project = project.downgrade(); let weak_project = project.downgrade();
self.projects.insert( self.projects.insert(
weak_project, project.downgrade(),
ProjectState { ProjectState {
servers: HashMap::default(), servers: HashMap::default(),
_subscriptions: [ _subscriptions: [
@@ -184,7 +184,7 @@ impl LogStore {
server_state._io_logs_subscription = server.as_ref().map(|server| { server_state._io_logs_subscription = server.as_ref().map(|server| {
server.on_io(move |io_kind, message| { server.on_io(move |io_kind, message| {
io_tx io_tx
.unbounded_send((weak_project, id, io_kind, message.to_string())) .unbounded_send((weak_project.clone(), id, io_kind, message.to_string()))
.ok(); .ok();
}) })
}); });
@@ -197,7 +197,8 @@ impl LogStore {
if let Some((project, this)) = weak_project.upgrade().zip(this.upgrade()) { if let Some((project, this)) = weak_project.upgrade().zip(this.upgrade()) {
this.update(&mut cx, |this, cx| { this.update(&mut cx, |this, cx| {
this.add_language_server_log(&project, server_id, &params.message, cx); this.add_language_server_log(&project, server_id, &params.message, cx);
}); })
.ok();
} }
} }
}) })
@@ -550,10 +551,10 @@ impl LspLogView {
let language = language.await.ok(); let language = language.await.ok();
buffer.update(&mut cx, |buffer, cx| { buffer.update(&mut cx, |buffer, cx| {
buffer.set_language(language, cx); buffer.set_language(language, cx);
}); })
} }
}) })
.detach(); .detach_and_log_err(cx);
}); });
self.editor = editor; self.editor = editor;
@@ -720,7 +721,6 @@ impl Render for LspLogToolbarItemView {
// } // }
fn render(&mut self, cx: &mut ViewContext<Self>) -> Div { fn render(&mut self, cx: &mut ViewContext<Self>) -> Div {
let theme = cx.theme().clone();
let Some(log_view) = self.log_view.as_ref() else { let Some(log_view) = self.log_view.as_ref() else {
return div(); return div();
}; };
@@ -737,60 +737,60 @@ impl Render for LspLogToolbarItemView {
None None
} }
}); });
let server_selected = current_server.is_some(); // todo!() styling
let _server_selected = current_server.is_some();
enum LspLogScroll {}
enum Menu {}
let lsp_menu = h_stack() let lsp_menu = h_stack()
.child(Self::render_language_server_menu_header(current_server, cx)) .child(Self::render_language_server_menu_header(current_server, cx))
.children(if self.menu_open { .children(if self.menu_open {
Some( Some(
overlay() overlay().child(
.child( v_stack()
v_stack() // todo!()
.scrollable::<LspLogScroll>(0, None, cx) // .scrollable::<LspLogScroll>(0, None, cx)
.children(menu_rows.into_iter().map(|row| { .children(menu_rows.into_iter().map(|row| {
Self::render_language_server_menu_item( Self::render_language_server_menu_item(
row.server_id, row.server_id,
row.server_name, row.server_name,
&row.worktree_root_name, &row.worktree_root_name,
row.rpc_trace_enabled, row.rpc_trace_enabled,
row.logs_selected, row.logs_selected,
row.rpc_trace_selected, row.rpc_trace_selected,
&theme, cx,
cx, )
) }))
})) .on_mouse_down_out(cx.listener(|this, event: &MouseDownEvent, cx| {
.on_down_out(MouseButton::Left, |_, this, cx| { if event.button == MouseButton::Left {
this.menu_open = false; this.menu_open = false;
cx.notify() cx.notify()
}), }
) })),
.with_hoverable(true) ), // todo!()
.with_fit_mode(OverlayFitMode::SwitchAnchor) // .with_hoverable(true)
.with_anchor_corner(AnchorCorner::TopLeft) // .with_fit_mode(OverlayFitMode::SwitchAnchor)
.with_z_index(999) // .with_anchor_corner(AnchorCorner::TopLeft)
.bottom() // .with_z_index(999),
.left(),
) )
} else { } else {
None None
}); });
enum LspCleanupButton {}
let log_cleanup_button = div() let log_cleanup_button = div()
.child(Label::new("Clear")) .child(Label::new("Clear"))
.on_mouse_down(MouseButton::Left, move |_, cx| { .on_mouse_down(
if let Some(log_view) = self.log_view.as_ref() { MouseButton::Left,
log_view.update(cx, |log_view, cx| { cx.listener(move |this, _, cx| {
log_view.editor.update(cx, |editor, cx| { if let Some(log_view) = this.log_view.as_ref() {
editor.set_read_only(false); log_view.update(cx, |log_view, cx| {
editor.clear(cx); log_view.editor.update(cx, |editor, cx| {
editor.set_read_only(true); editor.set_read_only(false);
}); editor.clear(cx);
}) editor.set_read_only(true);
} });
}) })
}
}),
)
.cursor(CursorStyle::PointingHand); .cursor(CursorStyle::PointingHand);
h_stack() h_stack()
@@ -856,8 +856,6 @@ impl LspLogToolbarItemView {
current_server: Option<LogMenuItem>, current_server: Option<LogMenuItem>,
cx: &mut ViewContext<Self>, cx: &mut ViewContext<Self>,
) -> Div { ) -> Div {
let view = cx.view().clone();
enum ToggleMenu {}
let label: Cow<str> = current_server let label: Cow<str> = current_server
.and_then(|row| { .and_then(|row| {
Some( Some(
@@ -878,11 +876,12 @@ impl LspLogToolbarItemView {
div() div()
.child(Label::new(label)) .child(Label::new(label))
.cursor(CursorStyle::PointingHand) .cursor(CursorStyle::PointingHand)
.on_mouse_down(MouseButton::Left, move |_, cx| { .on_mouse_down(
view.update(cx, |view, cx| { MouseButton::Left,
cx.listener(move |view, _, cx| {
view.toggle_menu(cx); view.toggle_menu(cx);
}) }),
}) )
.border_1() .border_1()
.border_color(red()) .border_color(red())
} }
@@ -892,53 +891,52 @@ impl LspLogToolbarItemView {
name: LanguageServerName, name: LanguageServerName,
worktree_root_name: &str, worktree_root_name: &str,
rpc_trace_enabled: bool, rpc_trace_enabled: bool,
logs_selected: bool, // todo!() styling
rpc_trace_selected: bool, _logs_selected: bool,
theme: &Arc<Theme>, _rpc_trace_selected: bool,
cx: &mut ViewContext<Self>, cx: &mut ViewContext<Self>,
) -> Div { ) -> Div {
enum ActivateLog {}
enum ActivateRpcTrace {}
enum LanguageServerCheckbox {}
let view = cx.view().clone();
v_stack() v_stack()
.child(Label::new(format!("{} ({})", name.0, worktree_root_name))) .child(Label::new(format!("{} ({})", name.0, worktree_root_name)))
.child( .child(
div() div()
.child(Label::new(SERVER_LOGS)) .child(Label::new(SERVER_LOGS))
.cursor(CursorStyle::PointingHand) .cursor(CursorStyle::PointingHand)
.on_mouse_down(MouseButton::Left, move |_, cx| { .on_mouse_down(
view.update(cx, |view, cx| { MouseButton::Left,
cx.listener(move |view, _, cx| {
view.show_logs_for_server(id, cx); view.show_logs_for_server(id, cx);
}) }),
}), ),
) )
.child( .child(
h_stack() h_stack()
.child(Label::new(RPC_MESSAGES)) .child(Label::new(RPC_MESSAGES))
.child( .child(
ui::checkbox_with_label::<LanguageServerCheckbox, _, Self, _>( Checkbox::new(
div(),
&theme.welcome.checkbox,
rpc_trace_enabled,
id.0, id.0,
cx, if rpc_trace_enabled {
move |this, enabled, cx| { ui::Selection::Selected
this.toggle_logging_for_server(id, enabled, cx); } else {
ui::Selection::Unselected
}, },
) )
.flex_float(), .on_click(cx.listener(
move |this, selection, cx| {
let enabled = matches!(selection, ui::Selection::Selected);
this.toggle_logging_for_server(id, enabled, cx);
},
)),
) )
.border_1() .border_1()
.border_color(red()) .border_color(red())
.cursor(CursorStyle::PointingHand) .cursor(CursorStyle::PointingHand)
.on_mouse_down(MouseButton::Left, move |_, cx| { .on_mouse_down(
view.update(cx, |view, cx| { MouseButton::Left,
cx.listener(move |view, _, cx| {
view.show_rpc_trace_for_server(id, cx); view.show_rpc_trace_for_server(id, cx);
}) }),
}), ),
) )
.border_1() .border_1()
.border_color(red()) .border_color(red())
+75 -69
View File
@@ -2,13 +2,13 @@ use editor::{scroll::autoscroll::Autoscroll, Anchor, Editor, ExcerptId};
use gpui::{ use gpui::{
actions, div, overlay, red, uniform_list, AnyElement, AppContext, CursorStyle, Div, actions, div, overlay, red, uniform_list, AnyElement, AppContext, CursorStyle, Div,
EventEmitter, FocusHandle, FocusableView, Hsla, InteractiveElement, IntoElement, Model, EventEmitter, FocusHandle, FocusableView, Hsla, InteractiveElement, IntoElement, Model,
MouseButton, ParentElement, Render, Styled, TextStyle, UniformListState, View, ViewContext, MouseButton, MouseDownEvent, MouseMoveEvent, ParentElement, Pixels, Render, Styled, TextStyle,
VisualContext, WeakView, WindowContext, UniformListScrollHandle, View, ViewContext, VisualContext, WeakView, WindowContext,
}; };
use language::{Buffer, OwnedSyntaxLayerInfo, SyntaxLayerInfo}; use language::{Buffer, OwnedSyntaxLayerInfo, SyntaxLayerInfo};
use settings::Settings; use settings::Settings;
use std::{mem, ops::Range}; use std::{mem, ops::Range};
use theme::{ActiveTheme, ThemeSettings}; use theme::{Theme, ThemeSettings};
use tree_sitter::{Node, TreeCursor}; use tree_sitter::{Node, TreeCursor};
use ui::{h_stack, Label}; use ui::{h_stack, Label};
use workspace::{ use workspace::{
@@ -35,9 +35,9 @@ pub fn init(cx: &mut AppContext) {
pub struct SyntaxTreeView { pub struct SyntaxTreeView {
workspace_handle: WeakView<Workspace>, workspace_handle: WeakView<Workspace>,
editor: Option<EditorState>, editor: Option<EditorState>,
mouse_y: Option<f32>, mouse_y: Option<Pixels>,
line_height: Option<f32>, line_height: Option<Pixels>,
list_state: UniformListState, list_scroll_handle: UniformListScrollHandle,
selected_descendant_ix: Option<usize>, selected_descendant_ix: Option<usize>,
hovered_descendant_ix: Option<usize>, hovered_descendant_ix: Option<usize>,
focus_handle: FocusHandle, focus_handle: FocusHandle,
@@ -70,7 +70,7 @@ impl SyntaxTreeView {
) -> Self { ) -> Self {
let mut this = Self { let mut this = Self {
workspace_handle: workspace_handle.clone(), workspace_handle: workspace_handle.clone(),
list_state: UniformListState::default(), list_scroll_handle: UniformListScrollHandle::new(),
editor: None, editor: None,
mouse_y: None, mouse_y: None,
line_height: None, line_height: None,
@@ -204,15 +204,15 @@ impl SyntaxTreeView {
let descendant_ix = cursor.descendant_index(); let descendant_ix = cursor.descendant_index();
self.selected_descendant_ix = Some(descendant_ix); self.selected_descendant_ix = Some(descendant_ix);
self.list_state.scroll_to(ScrollTarget::Show(descendant_ix)); self.list_scroll_handle.scroll_to_item(descendant_ix);
cx.notify(); cx.notify();
Some(()) Some(())
} }
fn handle_click(&mut self, y: f32, cx: &mut ViewContext<SyntaxTreeView>) -> Option<()> { fn handle_click(&mut self, y: Pixels, cx: &mut ViewContext<SyntaxTreeView>) -> Option<()> {
let line_height = self.line_height?; let line_height = self.line_height?;
let ix = ((self.list_state.scroll_top() + y) / line_height) as usize; let ix = ((self.list_scroll_handle.scroll_top() + y) / line_height) as usize;
self.update_editor_with_range_for_descendant_ix(ix, cx, |editor, mut range, cx| { self.update_editor_with_range_for_descendant_ix(ix, cx, |editor, mut range, cx| {
// Put the cursor at the beginning of the node. // Put the cursor at the beginning of the node.
@@ -227,7 +227,7 @@ impl SyntaxTreeView {
fn hover_state_changed(&mut self, cx: &mut ViewContext<SyntaxTreeView>) { fn hover_state_changed(&mut self, cx: &mut ViewContext<SyntaxTreeView>) {
if let Some((y, line_height)) = self.mouse_y.zip(self.line_height) { if let Some((y, line_height)) = self.mouse_y.zip(self.line_height) {
let ix = ((self.list_state.scroll_top() + y) / line_height) as usize; let ix = ((self.list_scroll_handle.scroll_top() + y) / line_height) as usize;
if self.hovered_descendant_ix != Some(ix) { if self.hovered_descendant_ix != Some(ix) {
self.hovered_descendant_ix = Some(ix); self.hovered_descendant_ix = Some(ix);
self.update_editor_with_range_for_descendant_ix(ix, cx, |editor, range, cx| { self.update_editor_with_range_for_descendant_ix(ix, cx, |editor, range, cx| {
@@ -279,29 +279,39 @@ impl SyntaxTreeView {
fn render_node( fn render_node(
cursor: &TreeCursor, cursor: &TreeCursor,
depth: u32, _depth: u32,
selected: bool, selected: bool,
hovered: bool, hovered: bool,
list_hovered: bool, list_hovered: bool,
style: &TextStyle, style: &TextStyle,
editor_theme: &theme::Editor, editor_theme: &Theme,
cx: &AppContext, _cx: &AppContext,
) -> Div { ) -> Div {
let editor_colors = editor_theme.colors();
let node = cursor.node(); let node = cursor.node();
let mut range_style = style.clone(); let mut range_style = style.clone();
let em_width = style.em_width(cx.text_system()); // todo!() styling
let gutter_padding = (em_width * editor_theme.gutter_padding_factor).round(); // let font_id = cx.text_system().font_id(&style.text.font()).unwrap();
// let font_size = style.text.font_size.to_pixels(cx.rem_size());
// let line_height = style.text.line_height_in_pixels(cx.rem_size());
// let em_width = cx
// .text_system()
// .typographic_bounds(font_id, font_size, 'm')
// .unwrap()
// .size
// .width;
// let gutter_padding = (em_width * editor_theme.gutter_padding_factor).round();
range_style.color = editor_theme.line_number; range_style.color = editor_colors.editor_line_number;
let mut anonymous_node_style = style.clone(); let mut anonymous_node_style = style.clone();
let string_color = editor_theme let string_color = editor_theme
.syntax .syntax()
.highlights .highlights
.iter() .iter()
.find_map(|(name, style)| (name == "string").then(|| style.color)?); .find_map(|(name, style)| (name == "string").then(|| style.color)?);
let property_color = editor_theme let property_color = editor_theme
.syntax .syntax()
.highlights .highlights
.iter() .iter()
.find_map(|(name, style)| (name == "property").then(|| style.color)?); .find_map(|(name, style)| (name == "property").then(|| style.color)?);
@@ -330,9 +340,9 @@ impl SyntaxTreeView {
) )
.child(Label::new(format_node_range(node))) .child(Label::new(format_node_range(node)))
.text_bg(if selected { .text_bg(if selected {
editor_theme.selection.selection editor_colors.element_selected
} else if hovered && list_hovered { } else if hovered && list_hovered {
editor_theme.active_line_background editor_colors.element_active
} else { } else {
Hsla::default() Hsla::default()
}) })
@@ -344,37 +354,25 @@ impl SyntaxTreeView {
} }
impl Render for SyntaxTreeView { impl Render for SyntaxTreeView {
// todo!()
// fn ui_name() -> &'static str {
// "SyntaxTreeView"
// }
type Element = Div; type Element = Div;
fn render(&mut self, cx: &mut gpui::ViewContext<'_, Self>) -> Div { fn render(&mut self, cx: &mut gpui::ViewContext<'_, Self>) -> Div {
let settings = ThemeSettings::get_global(cx); let settings = ThemeSettings::get_global(cx);
let font = settings.buffer_font; let font = settings.buffer_font.clone();
let font_size = settings.buffer_font_size(cx); let font_size = settings.buffer_font_size(cx);
let editor_theme = settings.active_theme; let editor_theme = settings.active_theme.clone();
let editor_colors = editor_theme.colors();
let style = TextStyle { let style = TextStyle {
color: editor_theme.text_color, color: editor_colors.text,
font_family_name, font_family: font.family,
font_family_id, font_features: font.features,
font_id, font_weight: font.weight,
font_size, font_style: font.style,
font_properties: Default::default(), ..Default::default()
underline: Default::default(),
font_family: todo!(),
font_features: todo!(),
line_height: todo!(),
font_weight: todo!(),
font_style: todo!(),
background_color: todo!(),
white_space: todo!(),
}; };
let line_height = cx.text_system().line_height(font_size); let line_height = cx.text_style().line_height_in_pixels(font_size);
if Some(line_height) != self.line_height { if Some(line_height) != self.line_height {
self.line_height = Some(line_height); self.line_height = Some(line_height);
self.hover_state_changed(cx); self.hover_state_changed(cx);
@@ -389,12 +387,15 @@ impl Render for SyntaxTreeView {
let layer = layer.clone(); let layer = layer.clone();
let theme = editor_theme.clone(); let theme = editor_theme.clone();
let list_hovered = state.hovered(); // todo!()
// let list_hovered = state.hovered();
let list_hovered = false;
uniform_list( uniform_list(
self.list_state.clone(), cx.view().clone(),
"SyntaxTreeView",
layer.node().descendant_count(), layer.node().descendant_count(),
cx, move |this, range, cx| {
move |this, range, items, cx| { let mut items = Vec::new();
let mut cursor = layer.node().walk(); let mut cursor = layer.node().walk();
let mut descendant_ix = range.start as usize; let mut descendant_ix = range.start as usize;
cursor.goto_descendant(descendant_ix); cursor.goto_descendant(descendant_ix);
@@ -428,17 +429,21 @@ impl Render for SyntaxTreeView {
} }
} }
} }
items
}, },
) )
.on_move(move |event, this, cx| { .track_scroll(self.list_scroll_handle.clone())
let y = event.position.y() - event.region.origin_y(); .on_mouse_move(cx.listener(move |tree_view, event: &MouseMoveEvent, cx| {
this.mouse_y = Some(y); tree_view.mouse_y = Some(event.position.y);
this.hover_state_changed(cx); tree_view.hover_state_changed(cx);
}) }))
.on_mouse_down(MouseButton::Left, move |event, cx| { .on_mouse_down(
let y = event.position.y() - event.region.origin_y(); MouseButton::Left,
self.handle_click(y, cx); cx.listener(move |tree_view, event: &MouseDownEvent, cx| {
}); tree_view.handle_click(event.position.y, cx);
}),
)
.text_bg(editor_colors.background);
} }
div() div()
@@ -490,7 +495,6 @@ impl SyntaxTreeToolbarItemView {
} }
fn render_menu(&mut self, cx: &mut ViewContext<'_, Self>) -> Option<Div> { fn render_menu(&mut self, cx: &mut ViewContext<'_, Self>) -> Option<Div> {
let theme = cx.theme().clone();
let tree_view = self.tree_view.as_ref()?; let tree_view = self.tree_view.as_ref()?;
let tree_view = tree_view.read(cx); let tree_view = tree_view.read(cx);
@@ -508,12 +512,12 @@ impl SyntaxTreeToolbarItemView {
.children(active_buffer.syntax_layers().enumerate().map( .children(active_buffer.syntax_layers().enumerate().map(
|(ix, layer)| Self::render_menu_item(&active_layer, layer, ix, cx), |(ix, layer)| Self::render_menu_item(&active_layer, layer, ix, cx),
)) ))
.on_mouse_down_out(|e, cx| { .on_mouse_down_out(cx.listener(|this, e: &MouseDownEvent, cx| {
if e.button == MouseButton::Left { if e.button == MouseButton::Left {
self.menu_open = false; this.menu_open = false;
cx.notify() cx.notify()
} }
}), })),
) )
})), })),
) )
@@ -540,13 +544,15 @@ impl SyntaxTreeToolbarItemView {
} }
fn render_header(active_layer: &OwnedSyntaxLayerInfo, cx: &mut ViewContext<Self>) -> Div { fn render_header(active_layer: &OwnedSyntaxLayerInfo, cx: &mut ViewContext<Self>) -> Div {
let view = cx.view().clone();
h_stack() h_stack()
.child(Label::new(active_layer.language.name())) .child(Label::new(active_layer.language.name()))
.child(Label::new(format_node_range(active_layer.node()))) .child(Label::new(format_node_range(active_layer.node())))
.on_mouse_down(MouseButton::Left, move |_, cx| { .on_mouse_down(
view.update(cx, |view, cx| view.toggle_menu(cx)); MouseButton::Left,
}) cx.listener(move |view, _, cx| {
view.toggle_menu(cx);
}),
)
.cursor(CursorStyle::PointingHand) .cursor(CursorStyle::PointingHand)
.border_1() .border_1()
.border_color(red()) .border_color(red())
@@ -560,16 +566,16 @@ impl SyntaxTreeToolbarItemView {
) -> Div { ) -> Div {
// todo!() styling // todo!() styling
let _is_selected = layer.node() == active_layer.node(); let _is_selected = layer.node() == active_layer.node();
let view = cx.view().clone();
h_stack() h_stack()
.child(Label::new(layer.language.name().to_string())) .child(Label::new(layer.language.name().to_string()))
.child(Label::new(format_node_range(layer.node()))) .child(Label::new(format_node_range(layer.node())))
.cursor(CursorStyle::PointingHand) .cursor(CursorStyle::PointingHand)
.on_mouse_down(MouseButton::Left, move |_, cx| { .on_mouse_down(
view.update(cx, |view, cx| { MouseButton::Left,
cx.listener(move |view, _, cx| {
view.select_layer(layer_ix, cx); view.select_layer(layer_ix, cx);
}) }),
}) )
.border_1() .border_1()
.border_color(red()) .border_color(red())
} }