mirror of
https://github.com/zed-industries/zed.git
synced 2024-09-21 03:18:47 +03:00
Render the search UI on a separate row from the breadcrumbs
- In project search, render it above the breadcrumbs - In buffer search, render it below Co-Authored-By: Antonio Scandurra <me@as-cii.com> Co-Authored-By: Max Brunsfeld <maxbrunsfeld@gmail.com>
This commit is contained in:
parent
0453dd1101
commit
8bfac63e0d
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -727,6 +727,7 @@ dependencies = [
|
|||||||
"editor",
|
"editor",
|
||||||
"gpui",
|
"gpui",
|
||||||
"language",
|
"language",
|
||||||
|
"search",
|
||||||
"theme",
|
"theme",
|
||||||
"workspace",
|
"workspace",
|
||||||
]
|
]
|
||||||
|
@ -12,6 +12,7 @@ collections = { path = "../collections" }
|
|||||||
editor = { path = "../editor" }
|
editor = { path = "../editor" }
|
||||||
gpui = { path = "../gpui" }
|
gpui = { path = "../gpui" }
|
||||||
language = { path = "../language" }
|
language = { path = "../language" }
|
||||||
|
search = { path = "../search" }
|
||||||
theme = { path = "../theme" }
|
theme = { path = "../theme" }
|
||||||
workspace = { path = "../workspace" }
|
workspace = { path = "../workspace" }
|
||||||
|
|
||||||
|
@ -3,9 +3,10 @@ use gpui::{
|
|||||||
elements::*, AppContext, Entity, RenderContext, Subscription, View, ViewContext, ViewHandle,
|
elements::*, AppContext, Entity, RenderContext, Subscription, View, ViewContext, ViewHandle,
|
||||||
};
|
};
|
||||||
use language::{BufferSnapshot, OutlineItem};
|
use language::{BufferSnapshot, OutlineItem};
|
||||||
|
use search::ProjectSearchView;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use theme::SyntaxTheme;
|
use theme::SyntaxTheme;
|
||||||
use workspace::{ItemHandle, Settings, ToolbarItemView};
|
use workspace::{ItemHandle, Settings, ToolbarItemLocation, ToolbarItemView};
|
||||||
|
|
||||||
pub struct Breadcrumbs {
|
pub struct Breadcrumbs {
|
||||||
editor: Option<ViewHandle<Editor>>,
|
editor: Option<ViewHandle<Editor>>,
|
||||||
@ -83,17 +84,29 @@ impl ToolbarItemView for Breadcrumbs {
|
|||||||
&mut self,
|
&mut self,
|
||||||
active_pane_item: Option<&dyn ItemHandle>,
|
active_pane_item: Option<&dyn ItemHandle>,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) {
|
) -> ToolbarItemLocation {
|
||||||
|
cx.notify();
|
||||||
self.editor_subscription = None;
|
self.editor_subscription = None;
|
||||||
self.editor = None;
|
self.editor = None;
|
||||||
if let Some(editor) = active_pane_item.and_then(|i| i.act_as::<Editor>(cx)) {
|
if let Some(item) = active_pane_item {
|
||||||
self.editor_subscription = Some(cx.subscribe(&editor, |_, _, event, cx| match event {
|
if let Some(editor) = item.act_as::<Editor>(cx) {
|
||||||
editor::Event::BufferEdited => cx.notify(),
|
self.editor_subscription =
|
||||||
editor::Event::SelectionsChanged { local } if *local => cx.notify(),
|
Some(cx.subscribe(&editor, |_, _, event, cx| match event {
|
||||||
_ => {}
|
editor::Event::BufferEdited => cx.notify(),
|
||||||
}));
|
editor::Event::SelectionsChanged { local } if *local => cx.notify(),
|
||||||
self.editor = Some(editor);
|
_ => {}
|
||||||
|
}));
|
||||||
|
self.editor = Some(editor);
|
||||||
|
if item.downcast::<ProjectSearchView>().is_some() {
|
||||||
|
ToolbarItemLocation::Secondary
|
||||||
|
} else {
|
||||||
|
ToolbarItemLocation::PrimaryLeft
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ToolbarItemLocation::Hidden
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ToolbarItemLocation::Hidden
|
||||||
}
|
}
|
||||||
cx.notify();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,13 +8,17 @@ use gpui::{
|
|||||||
use language::OffsetRangeExt;
|
use language::OffsetRangeExt;
|
||||||
use project::search::SearchQuery;
|
use project::search::SearchQuery;
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
use workspace::{ItemHandle, Pane, Settings, ToolbarItemView};
|
use workspace::{ItemHandle, Pane, Settings, ToolbarItemLocation, ToolbarItemView};
|
||||||
|
|
||||||
action!(Deploy, bool);
|
action!(Deploy, bool);
|
||||||
action!(Dismiss);
|
action!(Dismiss);
|
||||||
action!(FocusEditor);
|
action!(FocusEditor);
|
||||||
action!(ToggleSearchOption, SearchOption);
|
action!(ToggleSearchOption, SearchOption);
|
||||||
|
|
||||||
|
pub enum Event {
|
||||||
|
UpdateLocation,
|
||||||
|
}
|
||||||
|
|
||||||
pub fn init(cx: &mut MutableAppContext) {
|
pub fn init(cx: &mut MutableAppContext) {
|
||||||
cx.add_bindings([
|
cx.add_bindings([
|
||||||
Binding::new("cmd-f", Deploy(true), Some("Editor && mode == full")),
|
Binding::new("cmd-f", Deploy(true), Some("Editor && mode == full")),
|
||||||
@ -57,7 +61,7 @@ pub struct BufferSearchBar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Entity for BufferSearchBar {
|
impl Entity for BufferSearchBar {
|
||||||
type Event = ();
|
type Event = Event;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl View for BufferSearchBar {
|
impl View for BufferSearchBar {
|
||||||
@ -70,70 +74,66 @@ impl View for BufferSearchBar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn render(&mut self, cx: &mut RenderContext<Self>) -> ElementBox {
|
fn render(&mut self, cx: &mut RenderContext<Self>) -> ElementBox {
|
||||||
if self.dismissed || self.active_editor.is_none() {
|
let theme = cx.global::<Settings>().theme.clone();
|
||||||
Empty::new().boxed()
|
let editor_container = if self.query_contains_error {
|
||||||
|
theme.search.invalid_editor
|
||||||
} else {
|
} else {
|
||||||
let theme = cx.global::<Settings>().theme.clone();
|
theme.search.editor.input.container
|
||||||
let editor_container = if self.query_contains_error {
|
};
|
||||||
theme.search.invalid_editor
|
Flex::row()
|
||||||
} else {
|
.with_child(
|
||||||
theme.search.editor.input.container
|
Flex::row()
|
||||||
};
|
.with_child(ChildView::new(&self.query_editor).flex(1., true).boxed())
|
||||||
Flex::row()
|
.with_children(self.active_editor.as_ref().and_then(|editor| {
|
||||||
.with_child(
|
let matches = self.editors_with_matches.get(&editor.downgrade())?;
|
||||||
Flex::row()
|
let message = if let Some(match_ix) = self.active_match_index {
|
||||||
.with_child(ChildView::new(&self.query_editor).flex(1., true).boxed())
|
format!("{}/{}", match_ix + 1, matches.len())
|
||||||
.with_children(self.active_editor.as_ref().and_then(|editor| {
|
} else {
|
||||||
let matches = self.editors_with_matches.get(&editor.downgrade())?;
|
"No matches".to_string()
|
||||||
let message = if let Some(match_ix) = self.active_match_index {
|
};
|
||||||
format!("{}/{}", match_ix + 1, matches.len())
|
|
||||||
} else {
|
|
||||||
"No matches".to_string()
|
|
||||||
};
|
|
||||||
|
|
||||||
Some(
|
Some(
|
||||||
Label::new(message, theme.search.match_index.text.clone())
|
Label::new(message, theme.search.match_index.text.clone())
|
||||||
.contained()
|
.contained()
|
||||||
.with_style(theme.search.match_index.container)
|
.with_style(theme.search.match_index.container)
|
||||||
.aligned()
|
.aligned()
|
||||||
.boxed(),
|
.boxed(),
|
||||||
)
|
)
|
||||||
}))
|
}))
|
||||||
.contained()
|
.contained()
|
||||||
.with_style(editor_container)
|
.with_style(editor_container)
|
||||||
.aligned()
|
.aligned()
|
||||||
.constrained()
|
.constrained()
|
||||||
.with_max_width(theme.search.editor.max_width)
|
.with_max_width(theme.search.editor.max_width)
|
||||||
.boxed(),
|
.boxed(),
|
||||||
)
|
)
|
||||||
.with_child(
|
.with_child(
|
||||||
Flex::row()
|
Flex::row()
|
||||||
.with_child(self.render_nav_button("<", Direction::Prev, cx))
|
.with_child(self.render_nav_button("<", Direction::Prev, cx))
|
||||||
.with_child(self.render_nav_button(">", Direction::Next, cx))
|
.with_child(self.render_nav_button(">", Direction::Next, cx))
|
||||||
.aligned()
|
.aligned()
|
||||||
.boxed(),
|
.boxed(),
|
||||||
)
|
)
|
||||||
.with_child(
|
.with_child(
|
||||||
Flex::row()
|
Flex::row()
|
||||||
.with_child(self.render_search_option(
|
.with_child(self.render_search_option("Case", SearchOption::CaseSensitive, cx))
|
||||||
"Case",
|
.with_child(self.render_search_option("Word", SearchOption::WholeWord, cx))
|
||||||
SearchOption::CaseSensitive,
|
.with_child(self.render_search_option("Regex", SearchOption::Regex, cx))
|
||||||
cx,
|
.contained()
|
||||||
))
|
.with_style(theme.search.option_button_group)
|
||||||
.with_child(self.render_search_option("Word", SearchOption::WholeWord, cx))
|
.aligned()
|
||||||
.with_child(self.render_search_option("Regex", SearchOption::Regex, cx))
|
.boxed(),
|
||||||
.contained()
|
)
|
||||||
.with_style(theme.search.option_button_group)
|
.named("search bar")
|
||||||
.aligned()
|
|
||||||
.boxed(),
|
|
||||||
)
|
|
||||||
.named("search bar")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToolbarItemView for BufferSearchBar {
|
impl ToolbarItemView for BufferSearchBar {
|
||||||
fn set_active_pane_item(&mut self, item: Option<&dyn ItemHandle>, cx: &mut ViewContext<Self>) {
|
fn set_active_pane_item(
|
||||||
|
&mut self,
|
||||||
|
item: Option<&dyn ItemHandle>,
|
||||||
|
cx: &mut ViewContext<Self>,
|
||||||
|
) -> ToolbarItemLocation {
|
||||||
cx.notify();
|
cx.notify();
|
||||||
self.active_editor_subscription.take();
|
self.active_editor_subscription.take();
|
||||||
self.active_editor.take();
|
self.active_editor.take();
|
||||||
@ -145,9 +145,21 @@ impl ToolbarItemView for BufferSearchBar {
|
|||||||
Some(cx.subscribe(&editor, Self::on_active_editor_event));
|
Some(cx.subscribe(&editor, Self::on_active_editor_event));
|
||||||
self.active_editor = Some(editor);
|
self.active_editor = Some(editor);
|
||||||
self.update_matches(false, cx);
|
self.update_matches(false, cx);
|
||||||
return;
|
if !self.dismissed {
|
||||||
|
return ToolbarItemLocation::Secondary;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ToolbarItemLocation::Hidden
|
||||||
|
}
|
||||||
|
|
||||||
|
fn location_for_event(&self, _: &Self::Event, _: ToolbarItemLocation) -> ToolbarItemLocation {
|
||||||
|
if self.active_editor.is_some() && !self.dismissed {
|
||||||
|
ToolbarItemLocation::Secondary
|
||||||
|
} else {
|
||||||
|
ToolbarItemLocation::Hidden
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,6 +198,7 @@ impl BufferSearchBar {
|
|||||||
if let Some(active_editor) = self.active_editor.as_ref() {
|
if let Some(active_editor) = self.active_editor.as_ref() {
|
||||||
cx.focus(active_editor);
|
cx.focus(active_editor);
|
||||||
}
|
}
|
||||||
|
cx.emit(Event::UpdateLocation);
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,6 +247,7 @@ impl BufferSearchBar {
|
|||||||
|
|
||||||
self.dismissed = false;
|
self.dismissed = false;
|
||||||
cx.notify();
|
cx.notify();
|
||||||
|
cx.emit(Event::UpdateLocation);
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,9 @@ use std::{
|
|||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
};
|
};
|
||||||
use util::ResultExt as _;
|
use util::ResultExt as _;
|
||||||
use workspace::{Item, ItemNavHistory, Pane, Settings, ToolbarItemView, Workspace};
|
use workspace::{
|
||||||
|
Item, ItemNavHistory, Pane, Settings, ToolbarItemLocation, ToolbarItemView, Workspace,
|
||||||
|
};
|
||||||
|
|
||||||
action!(Deploy);
|
action!(Deploy);
|
||||||
action!(Search);
|
action!(Search);
|
||||||
@ -56,7 +58,7 @@ struct ProjectSearch {
|
|||||||
active_query: Option<SearchQuery>,
|
active_query: Option<SearchQuery>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ProjectSearchView {
|
pub struct ProjectSearchView {
|
||||||
model: ModelHandle<ProjectSearch>,
|
model: ModelHandle<ProjectSearch>,
|
||||||
query_editor: ViewHandle<Editor>,
|
query_editor: ViewHandle<Editor>,
|
||||||
results_editor: ViewHandle<Editor>,
|
results_editor: ViewHandle<Editor>,
|
||||||
@ -136,7 +138,7 @@ impl ProjectSearch {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ViewEvent {
|
pub enum ViewEvent {
|
||||||
UpdateTab,
|
UpdateTab,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -748,14 +750,17 @@ impl ToolbarItemView for ProjectSearchBar {
|
|||||||
&mut self,
|
&mut self,
|
||||||
active_pane_item: Option<&dyn workspace::ItemHandle>,
|
active_pane_item: Option<&dyn workspace::ItemHandle>,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) {
|
) -> ToolbarItemLocation {
|
||||||
|
cx.notify();
|
||||||
self.subscription = None;
|
self.subscription = None;
|
||||||
self.active_project_search = None;
|
self.active_project_search = None;
|
||||||
if let Some(search) = active_pane_item.and_then(|i| i.downcast::<ProjectSearchView>()) {
|
if let Some(search) = active_pane_item.and_then(|i| i.downcast::<ProjectSearchView>()) {
|
||||||
self.subscription = Some(cx.observe(&search, |_, _, cx| cx.notify()));
|
self.subscription = Some(cx.observe(&search, |_, _, cx| cx.notify()));
|
||||||
self.active_project_search = Some(search);
|
self.active_project_search = Some(search);
|
||||||
|
ToolbarItemLocation::PrimaryLeft
|
||||||
|
} else {
|
||||||
|
ToolbarItemLocation::Hidden
|
||||||
}
|
}
|
||||||
cx.notify();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
pub use buffer_search::BufferSearchBar;
|
pub use buffer_search::BufferSearchBar;
|
||||||
use editor::{Anchor, MultiBufferSnapshot};
|
use editor::{Anchor, MultiBufferSnapshot};
|
||||||
use gpui::{action, MutableAppContext};
|
use gpui::{action, MutableAppContext};
|
||||||
pub use project_search::ProjectSearchBar;
|
pub use project_search::{ProjectSearchBar, ProjectSearchView};
|
||||||
use std::{
|
use std::{
|
||||||
cmp::{self, Ordering},
|
cmp::{self, Ordering},
|
||||||
ops::Range,
|
ops::Range,
|
||||||
|
@ -9,22 +9,38 @@ pub trait ToolbarItemView: View {
|
|||||||
&mut self,
|
&mut self,
|
||||||
active_pane_item: Option<&dyn crate::ItemHandle>,
|
active_pane_item: Option<&dyn crate::ItemHandle>,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
);
|
) -> ToolbarItemLocation;
|
||||||
|
|
||||||
|
fn location_for_event(
|
||||||
|
&self,
|
||||||
|
_event: &Self::Event,
|
||||||
|
current_location: ToolbarItemLocation,
|
||||||
|
) -> ToolbarItemLocation {
|
||||||
|
current_location
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trait ToolbarItemViewHandle {
|
trait ToolbarItemViewHandle {
|
||||||
|
fn id(&self) -> usize;
|
||||||
fn to_any(&self) -> AnyViewHandle;
|
fn to_any(&self) -> AnyViewHandle;
|
||||||
fn set_active_pane_item(
|
fn set_active_pane_item(
|
||||||
&self,
|
&self,
|
||||||
active_pane_item: Option<&dyn ItemHandle>,
|
active_pane_item: Option<&dyn ItemHandle>,
|
||||||
cx: &mut MutableAppContext,
|
cx: &mut MutableAppContext,
|
||||||
);
|
) -> ToolbarItemLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
|
pub enum ToolbarItemLocation {
|
||||||
|
Hidden,
|
||||||
|
PrimaryLeft,
|
||||||
|
PrimaryRight,
|
||||||
|
Secondary,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Toolbar {
|
pub struct Toolbar {
|
||||||
active_pane_item: Option<Box<dyn ItemHandle>>,
|
active_pane_item: Option<Box<dyn ItemHandle>>,
|
||||||
left_items: Vec<Box<dyn ToolbarItemViewHandle>>,
|
items: Vec<(Box<dyn ToolbarItemViewHandle>, ToolbarItemLocation)>,
|
||||||
right_items: Vec<Box<dyn ToolbarItemViewHandle>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Entity for Toolbar {
|
impl Entity for Toolbar {
|
||||||
@ -38,26 +54,50 @@ impl View for Toolbar {
|
|||||||
|
|
||||||
fn render(&mut self, cx: &mut RenderContext<Self>) -> ElementBox {
|
fn render(&mut self, cx: &mut RenderContext<Self>) -> ElementBox {
|
||||||
let theme = &cx.global::<Settings>().theme.workspace.toolbar;
|
let theme = &cx.global::<Settings>().theme.workspace.toolbar;
|
||||||
Flex::row()
|
|
||||||
.with_children(self.left_items.iter().map(|i| {
|
let mut primary_left_items = Vec::new();
|
||||||
ChildView::new(i.as_ref())
|
let mut primary_right_items = Vec::new();
|
||||||
.aligned()
|
let mut secondary_item = None;
|
||||||
.contained()
|
|
||||||
.with_margin_right(theme.item_spacing)
|
for (item, position) in &self.items {
|
||||||
.boxed()
|
match position {
|
||||||
}))
|
ToolbarItemLocation::Hidden => {}
|
||||||
.with_children(self.right_items.iter().map(|i| {
|
ToolbarItemLocation::PrimaryLeft => primary_left_items.push(item),
|
||||||
ChildView::new(i.as_ref())
|
ToolbarItemLocation::PrimaryRight => primary_right_items.push(item),
|
||||||
.aligned()
|
ToolbarItemLocation::Secondary => secondary_item = Some(item),
|
||||||
.contained()
|
}
|
||||||
.with_margin_left(theme.item_spacing)
|
}
|
||||||
.flex_float()
|
|
||||||
|
Flex::column()
|
||||||
|
.with_child(
|
||||||
|
Flex::row()
|
||||||
|
.with_children(primary_left_items.iter().map(|i| {
|
||||||
|
ChildView::new(i.as_ref())
|
||||||
|
.aligned()
|
||||||
|
.contained()
|
||||||
|
.with_margin_right(theme.item_spacing)
|
||||||
|
.boxed()
|
||||||
|
}))
|
||||||
|
.with_children(primary_right_items.iter().map(|i| {
|
||||||
|
ChildView::new(i.as_ref())
|
||||||
|
.aligned()
|
||||||
|
.contained()
|
||||||
|
.with_margin_left(theme.item_spacing)
|
||||||
|
.flex_float()
|
||||||
|
.boxed()
|
||||||
|
}))
|
||||||
|
.constrained()
|
||||||
|
.with_height(theme.height)
|
||||||
|
.boxed(),
|
||||||
|
)
|
||||||
|
.with_children(secondary_item.map(|item| {
|
||||||
|
ChildView::new(item.as_ref())
|
||||||
|
.constrained()
|
||||||
|
.with_height(theme.height)
|
||||||
.boxed()
|
.boxed()
|
||||||
}))
|
}))
|
||||||
.contained()
|
.contained()
|
||||||
.with_style(theme.container)
|
.with_style(theme.container)
|
||||||
.constrained()
|
|
||||||
.with_height(theme.height)
|
|
||||||
.boxed()
|
.boxed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -66,49 +106,58 @@ impl Toolbar {
|
|||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
active_pane_item: None,
|
active_pane_item: None,
|
||||||
left_items: Default::default(),
|
items: Default::default(),
|
||||||
right_items: Default::default(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_left_item<T>(&mut self, item: ViewHandle<T>, cx: &mut ViewContext<Self>)
|
pub fn add_item<T>(&mut self, item: ViewHandle<T>, cx: &mut ViewContext<Self>)
|
||||||
where
|
where
|
||||||
T: 'static + ToolbarItemView,
|
T: 'static + ToolbarItemView,
|
||||||
{
|
{
|
||||||
item.set_active_pane_item(self.active_pane_item.as_deref(), cx);
|
let location = item.set_active_pane_item(self.active_pane_item.as_deref(), cx);
|
||||||
self.left_items.push(Box::new(item));
|
cx.subscribe(&item, |this, item, event, cx| {
|
||||||
cx.notify();
|
if let Some((_, current_location)) =
|
||||||
}
|
this.items.iter_mut().find(|(i, _)| i.id() == item.id())
|
||||||
|
{
|
||||||
pub fn add_right_item<T>(&mut self, item: ViewHandle<T>, cx: &mut ViewContext<Self>)
|
let new_location = item.read(cx).location_for_event(event, *current_location);
|
||||||
where
|
if new_location != *current_location {
|
||||||
T: 'static + ToolbarItemView,
|
*current_location = new_location;
|
||||||
{
|
cx.notify();
|
||||||
item.set_active_pane_item(self.active_pane_item.as_deref(), cx);
|
}
|
||||||
self.right_items.push(Box::new(item));
|
}
|
||||||
|
})
|
||||||
|
.detach();
|
||||||
|
self.items.push((Box::new(item), dbg!(location)));
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_active_pane_item(
|
pub fn set_active_pane_item(
|
||||||
&mut self,
|
&mut self,
|
||||||
item: Option<&dyn ItemHandle>,
|
pane_item: Option<&dyn ItemHandle>,
|
||||||
cx: &mut ViewContext<Self>,
|
cx: &mut ViewContext<Self>,
|
||||||
) {
|
) {
|
||||||
self.active_pane_item = item.map(|item| item.boxed_clone());
|
self.active_pane_item = pane_item.map(|item| item.boxed_clone());
|
||||||
for tool in self.left_items.iter().chain(&self.right_items) {
|
for (toolbar_item, current_location) in self.items.iter_mut() {
|
||||||
tool.set_active_pane_item(item, cx);
|
let new_location = toolbar_item.set_active_pane_item(pane_item, cx);
|
||||||
|
if new_location != *current_location {
|
||||||
|
*current_location = new_location;
|
||||||
|
cx.notify();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn item_of_type<T: ToolbarItemView>(&self) -> Option<ViewHandle<T>> {
|
pub fn item_of_type<T: ToolbarItemView>(&self) -> Option<ViewHandle<T>> {
|
||||||
self.left_items
|
self.items
|
||||||
.iter()
|
.iter()
|
||||||
.chain(&self.right_items)
|
.find_map(|(item, _)| item.to_any().downcast())
|
||||||
.find_map(|tool| tool.to_any().downcast())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ToolbarItemView> ToolbarItemViewHandle for ViewHandle<T> {
|
impl<T: ToolbarItemView> ToolbarItemViewHandle for ViewHandle<T> {
|
||||||
|
fn id(&self) -> usize {
|
||||||
|
self.id()
|
||||||
|
}
|
||||||
|
|
||||||
fn to_any(&self) -> AnyViewHandle {
|
fn to_any(&self) -> AnyViewHandle {
|
||||||
self.into()
|
self.into()
|
||||||
}
|
}
|
||||||
@ -117,10 +166,10 @@ impl<T: ToolbarItemView> ToolbarItemViewHandle for ViewHandle<T> {
|
|||||||
&self,
|
&self,
|
||||||
active_pane_item: Option<&dyn ItemHandle>,
|
active_pane_item: Option<&dyn ItemHandle>,
|
||||||
cx: &mut MutableAppContext,
|
cx: &mut MutableAppContext,
|
||||||
) {
|
) -> ToolbarItemLocation {
|
||||||
self.update(cx, |this, cx| {
|
self.update(cx, |this, cx| {
|
||||||
this.set_active_pane_item(active_pane_item, cx)
|
this.set_active_pane_item(active_pane_item, cx)
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ use std::{
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
use theme::{Theme, ThemeRegistry};
|
use theme::{Theme, ThemeRegistry};
|
||||||
pub use toolbar::ToolbarItemView;
|
pub use toolbar::{ToolbarItemLocation, ToolbarItemView};
|
||||||
use util::ResultExt;
|
use util::ResultExt;
|
||||||
|
|
||||||
type ProjectItemBuilders = HashMap<
|
type ProjectItemBuilders = HashMap<
|
||||||
|
@ -111,12 +111,11 @@ pub fn build_workspace(
|
|||||||
pane.update(cx, |pane, cx| {
|
pane.update(cx, |pane, cx| {
|
||||||
pane.toolbar().update(cx, |toolbar, cx| {
|
pane.toolbar().update(cx, |toolbar, cx| {
|
||||||
let breadcrumbs = cx.add_view(|_| Breadcrumbs::new());
|
let breadcrumbs = cx.add_view(|_| Breadcrumbs::new());
|
||||||
toolbar.add_left_item(breadcrumbs, cx);
|
toolbar.add_item(breadcrumbs, cx);
|
||||||
|
|
||||||
let buffer_search_bar = cx.add_view(|cx| BufferSearchBar::new(cx));
|
let buffer_search_bar = cx.add_view(|cx| BufferSearchBar::new(cx));
|
||||||
toolbar.add_right_item(buffer_search_bar, cx);
|
toolbar.add_item(buffer_search_bar, cx);
|
||||||
let project_search_bar = cx.add_view(|_| ProjectSearchBar::new());
|
let project_search_bar = cx.add_view(|_| ProjectSearchBar::new());
|
||||||
toolbar.add_right_item(project_search_bar, cx);
|
toolbar.add_item(project_search_bar, cx);
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user