Start getting pane focus code ported

This commit is contained in:
Julia
2023-11-30 10:47:28 -05:00
parent d551b41aae
commit 591299b4c7
3 changed files with 93 additions and 27 deletions
+21 -22
View File
@@ -1,6 +1,6 @@
use gpui::{
div, Div, Element, EventEmitter, InteractiveElement, IntoElement, ParentElement, Render,
Stateful, StatefulInteractiveElement, StyledText, Subscription, ViewContext, WeakView,
Div, Element, EventEmitter, InteractiveElement, IntoElement, ParentElement, Render, Stateful,
StatefulInteractiveElement, Styled, StyledText, Subscription, ViewContext, WeakView,
};
use itertools::Itertools;
use theme::ActiveTheme;
@@ -18,7 +18,7 @@ pub struct Breadcrumbs {
pane_focused: bool,
active_item: Option<Box<dyn ItemHandle>>,
subscription: Option<Subscription>,
workspace: WeakView<Workspace>,
_workspace: WeakView<Workspace>,
}
impl Breadcrumbs {
@@ -27,7 +27,7 @@ impl Breadcrumbs {
pane_focused: false,
active_item: Default::default(),
subscription: Default::default(),
workspace: workspace.weak_handle(),
_workspace: workspace.weak_handle(),
}
}
}
@@ -39,45 +39,44 @@ impl Render for Breadcrumbs {
type Element = Stateful<Div>;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
let id = "breadcrumbs";
let default_style = cx.text_style();
let div = h_stack().id("breadcrumbs").bg(gpui::red());
let active_item = match &self.active_item {
Some(active_item) => active_item,
None => return div().id(id),
None => return div,
};
let not_editor = active_item.downcast::<editor::Editor>().is_none();
let breadcrumbs = match active_item.breadcrumbs(cx.theme(), cx) {
Some(breadcrumbs) => breadcrumbs,
None => return div().id(id),
None => return div,
}
.into_iter()
.map(|breadcrumb| {
StyledText::new(breadcrumb.text)
.with_highlights(&default_style, breadcrumb.highlights.unwrap_or_default())
.with_highlights(&cx.text_style(), breadcrumb.highlights.unwrap_or_default())
.into_any()
});
let crumbs = h_stack().children(Itertools::intersperse_with(breadcrumbs, || {
let crumbs = div.children(Itertools::intersperse_with(breadcrumbs, || {
Label::new(" › ").into_any_element()
}));
if not_editor || !self.pane_focused {
return crumbs.id(id);
return crumbs;
}
let this = cx.view().downgrade();
crumbs.id(id).on_click(move |_, cx| {
this.update(cx, |this, cx| {
if let Some(workspace) = this.workspace.upgrade() {
workspace.update(cx, |_workspace, _cx| {
todo!("outline::toggle");
// outline::toggle(workspace, &Default::default(), cx)
})
}
})
.ok();
// let this = cx.view().downgrade();
crumbs.on_click(move |_, _cx| {
todo!("outline::toggle");
// this.update(cx, |this, cx| {
// if let Some(workspace) = this.workspace.upgrade() {
// workspace.update(cx, |_workspace, _cx| {
// outline::toggle(workspace, &Default::default(), cx)
// })
// }
// })
// .ok();
})
}
}
+71 -5
View File
@@ -7,9 +7,9 @@ use crate::{
use anyhow::Result;
use collections::{HashMap, HashSet, VecDeque};
use gpui::{
actions, prelude::*, Action, AppContext, AsyncWindowContext, Div, EntityId, EventEmitter,
FocusHandle, Focusable, FocusableView, Model, Pixels, Point, PromptLevel, Render, Task, View,
ViewContext, VisualContext, WeakView, WindowContext,
actions, prelude::*, Action, AnyWeakView, AppContext, AsyncWindowContext, Div, EntityId,
EventEmitter, FocusHandle, Focusable, FocusableView, Model, Pixels, Point, PromptLevel, Render,
Task, View, ViewContext, VisualContext, WeakView, WindowContext,
};
use parking_lot::Mutex;
use project2::{Project, ProjectEntryId, ProjectPath};
@@ -143,13 +143,18 @@ impl fmt::Debug for Event {
}
}
struct FocusedView {
view: AnyWeakView,
focus_handle: FocusHandle,
}
pub struct Pane {
focus_handle: FocusHandle,
items: Vec<Box<dyn ItemHandle>>,
activation_history: Vec<EntityId>,
zoomed: bool,
active_item_index: usize,
// last_focused_view_by_item: HashMap<usize, AnyWeakViewHandle>,
last_focused_view_by_item: HashMap<EntityId, FocusHandle>,
autoscroll: bool,
nav_history: NavHistory,
toolbar: View<Toolbar>,
@@ -306,7 +311,7 @@ impl Pane {
activation_history: Vec::new(),
zoomed: false,
active_item_index: 0,
// last_focused_view_by_item: Default::default(),
last_focused_view_by_item: Default::default(),
autoscroll: false,
nav_history: NavHistory(Arc::new(Mutex::new(NavHistoryState {
mode: NavigationMode::Normal,
@@ -395,6 +400,53 @@ impl Pane {
self.focus_handle.contains_focused(cx)
}
fn focus_in(&mut self, cx: &mut ViewContext<Self>) {
println!("focus_in");
if !self.has_focus(cx) {
cx.emit(Event::Focus);
cx.notify();
}
self.toolbar.update(cx, |toolbar, cx| {
toolbar.focus_changed(true, cx);
});
if let Some(active_item) = self.active_item() {
if self.focus_handle.is_focused(cx) {
// Pane was focused directly. We need to either focus a view inside the active item,
// or focus the active item itself
if let Some(weak_last_focused_view) =
self.last_focused_view_by_item.get(&active_item.item_id())
{
weak_last_focused_view.focus(cx);
// if let Some(last_focused_view) = weak_last_focused_view.upgrade() {
// last_focused_view.cx.focus(&last_focused_view);
// return;
// } else {
// self.last_focused_view_by_item.remove(&active_item.id());
// }
}
active_item.focus_handle(cx).focus(cx);
// todo!() Do this once we have tab bar context menu
// } else if !self.tab_bar_context_menu.handle.is_focused() {
} else if let Some(focused) = cx.focused() {
self.last_focused_view_by_item
.insert(active_item.item_id(), focused);
}
}
}
fn focus_out(&mut self, cx: &mut ViewContext<Self>) {
println!("focus_out");
self.toolbar.update(cx, |toolbar, cx| {
toolbar.focus_changed(false, cx);
});
cx.notify();
}
pub fn active_item_index(&self) -> usize {
self.active_item_index
}
@@ -1936,9 +1988,23 @@ impl Render for Pane {
type Element = Focusable<Div>;
fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
let this = cx.view().downgrade();
v_stack()
.key_context("Pane")
.track_focus(&self.focus_handle)
.on_focus_in({
let this = this.clone();
move |event, cx| {
this.update(cx, |this, cx| this.focus_in(cx)).ok();
}
})
.on_focus_out({
let this = this.clone();
move |event, cx| {
this.update(cx, |this, cx| this.focus_out(cx)).ok();
}
})
.on_action(cx.listener(|pane: &mut Pane, _: &SplitLeft, cx| {
pane.split(SplitDirection::Left, cx)
}))
+1
View File
@@ -289,6 +289,7 @@ impl<T: ToolbarItemView> ToolbarItemViewHandle for View<T> {
}
fn focus_changed(&mut self, pane_focused: bool, cx: &mut WindowContext) {
println!("focus changed, pane_focused: {pane_focused}");
self.update(cx, |this, cx| {
this.pane_focus_update(pane_focused, cx);
cx.notify();