Finish all but the styling
This commit is contained in:
@@ -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 {
|
||||||
|
|||||||
@@ -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, ¶ms.message, cx);
|
this.add_language_server_log(&project, server_id, ¶ms.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())
|
||||||
|
|||||||
@@ -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())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user