Merge branch 'main' into theme-improvements
This commit is contained in:
commit
bcc554a3db
76 changed files with 4053 additions and 1557 deletions
|
@ -13,8 +13,9 @@ use gpui::{
|
|||
},
|
||||
impl_actions, impl_internal_actions,
|
||||
platform::{CursorStyle, NavigationDirection},
|
||||
AppContext, AsyncAppContext, Entity, ModelHandle, MutableAppContext, PromptLevel, Quad,
|
||||
RenderContext, Task, View, ViewContext, ViewHandle, WeakViewHandle,
|
||||
AppContext, AsyncAppContext, Entity, ModelHandle, MouseButton, MouseButtonEvent,
|
||||
MutableAppContext, PromptLevel, Quad, RenderContext, Task, View, ViewContext, ViewHandle,
|
||||
WeakViewHandle,
|
||||
};
|
||||
use project::{Project, ProjectEntryId, ProjectPath};
|
||||
use serde::Deserialize;
|
||||
|
@ -71,10 +72,10 @@ const MAX_NAVIGATION_HISTORY_LEN: usize = 1024;
|
|||
|
||||
pub fn init(cx: &mut MutableAppContext) {
|
||||
cx.add_action(|pane: &mut Pane, action: &ActivateItem, cx| {
|
||||
pane.activate_item(action.0, true, true, cx);
|
||||
pane.activate_item(action.0, true, true, false, cx);
|
||||
});
|
||||
cx.add_action(|pane: &mut Pane, _: &ActivateLastItem, cx| {
|
||||
pane.activate_item(pane.items.len() - 1, true, true, cx);
|
||||
pane.activate_item(pane.items.len() - 1, true, true, false, cx);
|
||||
});
|
||||
cx.add_action(|pane: &mut Pane, _: &ActivatePrevItem, cx| {
|
||||
pane.activate_prev_item(cx);
|
||||
|
@ -288,7 +289,7 @@ impl Pane {
|
|||
{
|
||||
let prev_active_item_index = pane.active_item_index;
|
||||
pane.nav_history.borrow_mut().set_mode(mode);
|
||||
pane.activate_item(index, true, true, cx);
|
||||
pane.activate_item(index, true, true, false, cx);
|
||||
pane.nav_history
|
||||
.borrow_mut()
|
||||
.set_mode(NavigationMode::Normal);
|
||||
|
@ -380,7 +381,7 @@ impl Pane {
|
|||
&& item.project_entry_ids(cx).as_slice() == &[project_entry_id]
|
||||
{
|
||||
let item = item.boxed_clone();
|
||||
pane.activate_item(ix, true, focus_item, cx);
|
||||
pane.activate_item(ix, true, focus_item, true, cx);
|
||||
return Some(item);
|
||||
}
|
||||
}
|
||||
|
@ -404,9 +405,11 @@ impl Pane {
|
|||
cx: &mut ViewContext<Workspace>,
|
||||
) {
|
||||
// Prevent adding the same item to the pane more than once.
|
||||
// If there is already an active item, reorder the desired item to be after it
|
||||
// and activate it.
|
||||
if let Some(item_ix) = pane.read(cx).items.iter().position(|i| i.id() == item.id()) {
|
||||
pane.update(cx, |pane, cx| {
|
||||
pane.activate_item(item_ix, activate_pane, focus_item, cx)
|
||||
pane.activate_item(item_ix, activate_pane, focus_item, true, cx)
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
@ -426,7 +429,7 @@ impl Pane {
|
|||
};
|
||||
|
||||
pane.items.insert(item_ix, item);
|
||||
pane.activate_item(item_ix, activate_pane, focus_item, cx);
|
||||
pane.activate_item(item_ix, activate_pane, focus_item, false, cx);
|
||||
cx.notify();
|
||||
});
|
||||
}
|
||||
|
@ -465,13 +468,31 @@ impl Pane {
|
|||
|
||||
pub fn activate_item(
|
||||
&mut self,
|
||||
index: usize,
|
||||
mut index: usize,
|
||||
activate_pane: bool,
|
||||
focus_item: bool,
|
||||
move_after_current_active: bool,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) {
|
||||
use NavigationMode::{GoingBack, GoingForward};
|
||||
if index < self.items.len() {
|
||||
if move_after_current_active {
|
||||
// If there is already an active item, reorder the desired item to be after it
|
||||
// and activate it.
|
||||
if self.active_item_index != index && self.active_item_index < self.items.len() {
|
||||
let pane_to_activate = self.items.remove(index);
|
||||
if self.active_item_index < index {
|
||||
index = self.active_item_index + 1;
|
||||
} else if self.active_item_index < self.items.len() + 1 {
|
||||
index = self.active_item_index;
|
||||
// Index is less than active_item_index. Reordering will decrement the
|
||||
// active_item_index, so adjust it accordingly
|
||||
self.active_item_index = index - 1;
|
||||
}
|
||||
self.items.insert(index, pane_to_activate);
|
||||
}
|
||||
}
|
||||
|
||||
let prev_active_item_ix = mem::replace(&mut self.active_item_index, index);
|
||||
if prev_active_item_ix != self.active_item_index
|
||||
|| matches!(self.nav_history.borrow().mode, GoingBack | GoingForward)
|
||||
|
@ -502,7 +523,7 @@ impl Pane {
|
|||
} else if self.items.len() > 0 {
|
||||
index = self.items.len() - 1;
|
||||
}
|
||||
self.activate_item(index, true, true, cx);
|
||||
self.activate_item(index, true, true, false, cx);
|
||||
}
|
||||
|
||||
pub fn activate_next_item(&mut self, cx: &mut ViewContext<Self>) {
|
||||
|
@ -512,7 +533,7 @@ impl Pane {
|
|||
} else {
|
||||
index = 0;
|
||||
}
|
||||
self.activate_item(index, true, true, cx);
|
||||
self.activate_item(index, true, true, false, cx);
|
||||
}
|
||||
|
||||
pub fn close_active_item(
|
||||
|
@ -641,10 +662,13 @@ impl Pane {
|
|||
pane.update(&mut cx, |pane, cx| {
|
||||
if let Some(item_ix) = pane.items.iter().position(|i| i.id() == item.id()) {
|
||||
if item_ix == pane.active_item_index {
|
||||
if item_ix + 1 < pane.items.len() {
|
||||
pane.activate_next_item(cx);
|
||||
} else if item_ix > 0 {
|
||||
// Activate the previous item if possible.
|
||||
// This returns the user to the previously opened tab if they closed
|
||||
// a ne item they just navigated to.
|
||||
if item_ix > 0 {
|
||||
pane.activate_prev_item(cx);
|
||||
} else if item_ix + 1 < pane.items.len() {
|
||||
pane.activate_next_item(cx);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -712,7 +736,7 @@ impl Pane {
|
|||
|
||||
if has_conflict && can_save {
|
||||
let mut answer = pane.update(cx, |pane, cx| {
|
||||
pane.activate_item(item_ix, true, true, cx);
|
||||
pane.activate_item(item_ix, true, true, false, cx);
|
||||
cx.prompt(
|
||||
PromptLevel::Warning,
|
||||
CONFLICT_MESSAGE,
|
||||
|
@ -733,7 +757,7 @@ impl Pane {
|
|||
});
|
||||
let should_save = if should_prompt_for_save && !will_autosave {
|
||||
let mut answer = pane.update(cx, |pane, cx| {
|
||||
pane.activate_item(item_ix, true, true, cx);
|
||||
pane.activate_item(item_ix, true, true, false, cx);
|
||||
cx.prompt(
|
||||
PromptLevel::Warning,
|
||||
DIRTY_MESSAGE,
|
||||
|
@ -840,8 +864,10 @@ impl Pane {
|
|||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let mut row = Flex::row().scrollable::<Tabs, _>(1, autoscroll, cx);
|
||||
for (ix, item) in self.items.iter().enumerate() {
|
||||
for (ix, (item, detail)) in self.items.iter().zip(self.tab_details(cx)).enumerate() {
|
||||
let detail = if detail == 0 { None } else { Some(detail) };
|
||||
let is_active = ix == self.active_item_index;
|
||||
|
||||
row.add_child({
|
||||
|
@ -850,7 +876,7 @@ impl Pane {
|
|||
} else {
|
||||
theme.workspace.tab.clone()
|
||||
};
|
||||
let title = item.tab_content(&tab_style, cx);
|
||||
let title = item.tab_content(detail, &tab_style, cx);
|
||||
|
||||
let mut style = if is_active {
|
||||
theme.workspace.active_tab.clone()
|
||||
|
@ -930,9 +956,9 @@ impl Pane {
|
|||
)
|
||||
.with_padding(Padding::uniform(4.))
|
||||
.with_cursor_style(CursorStyle::PointingHand)
|
||||
.on_click({
|
||||
.on_click(MouseButton::Left, {
|
||||
let pane = pane.clone();
|
||||
move |_, _, cx| {
|
||||
move |_, cx| {
|
||||
cx.dispatch_action(CloseItem {
|
||||
item_id,
|
||||
pane: pane.clone(),
|
||||
|
@ -953,7 +979,7 @@ impl Pane {
|
|||
.with_style(style.container)
|
||||
.boxed()
|
||||
})
|
||||
.on_mouse_down(move |_, cx| {
|
||||
.on_mouse_down(MouseButton::Left, move |_, cx| {
|
||||
cx.dispatch_action(ActivateItem(ix));
|
||||
})
|
||||
.boxed()
|
||||
|
@ -971,6 +997,43 @@ impl Pane {
|
|||
row.boxed()
|
||||
})
|
||||
}
|
||||
|
||||
fn tab_details(&self, cx: &AppContext) -> Vec<usize> {
|
||||
let mut tab_details = (0..self.items.len()).map(|_| 0).collect::<Vec<_>>();
|
||||
|
||||
let mut tab_descriptions = HashMap::default();
|
||||
let mut done = false;
|
||||
while !done {
|
||||
done = true;
|
||||
|
||||
// Store item indices by their tab description.
|
||||
for (ix, (item, detail)) in self.items.iter().zip(&tab_details).enumerate() {
|
||||
if let Some(description) = item.tab_description(*detail, cx) {
|
||||
if *detail == 0
|
||||
|| Some(&description) != item.tab_description(detail - 1, cx).as_ref()
|
||||
{
|
||||
tab_descriptions
|
||||
.entry(description)
|
||||
.or_insert(Vec::new())
|
||||
.push(ix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If two or more items have the same tab description, increase their level
|
||||
// of detail and try again.
|
||||
for (_, item_ixs) in tab_descriptions.drain() {
|
||||
if item_ixs.len() > 1 {
|
||||
done = false;
|
||||
for ix in item_ixs {
|
||||
tab_details[ix] += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tab_details
|
||||
}
|
||||
}
|
||||
|
||||
impl Entity for Pane {
|
||||
|
@ -1017,9 +1080,12 @@ impl View for Pane {
|
|||
},
|
||||
)
|
||||
.with_cursor_style(CursorStyle::PointingHand)
|
||||
.on_mouse_down(|position, cx| {
|
||||
cx.dispatch_action(DeploySplitMenu { position });
|
||||
})
|
||||
.on_mouse_down(
|
||||
MouseButton::Left,
|
||||
|MouseButtonEvent { position, .. }, cx| {
|
||||
cx.dispatch_action(DeploySplitMenu { position });
|
||||
},
|
||||
)
|
||||
.boxed(),
|
||||
)
|
||||
.constrained()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue