mirror of
https://github.com/zed-industries/zed.git
synced 2024-11-12 19:11:23 +03:00
Allow toggling sections in contacts panel by clicking on them
This commit is contained in:
parent
f54d74eda9
commit
77b524c83e
@ -8,7 +8,7 @@ use fuzzy::{match_strings, StringMatchCandidate};
|
||||
use gpui::{
|
||||
elements::*,
|
||||
geometry::{rect::RectF, vector::vec2f},
|
||||
impl_actions,
|
||||
impl_actions, impl_internal_actions,
|
||||
platform::CursorStyle,
|
||||
AppContext, Element, ElementBox, Entity, LayoutContext, ModelHandle, MutableAppContext,
|
||||
RenderContext, Subscription, View, ViewContext, ViewHandle, WeakViewHandle,
|
||||
@ -28,6 +28,8 @@ impl_actions!(
|
||||
[RequestContact, RemoveContact, RespondToContactRequest]
|
||||
);
|
||||
|
||||
impl_internal_actions!(contacts_panel, [ToggleExpanded]);
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, PartialOrd, Ord)]
|
||||
enum Section {
|
||||
Requests,
|
||||
@ -44,6 +46,9 @@ enum ContactEntry {
|
||||
ContactProject(Arc<Contact>, usize),
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct ToggleExpanded(Section);
|
||||
|
||||
pub struct ContactsPanel {
|
||||
entries: Vec<ContactEntry>,
|
||||
match_candidates: Vec<StringMatchCandidate>,
|
||||
@ -78,6 +83,7 @@ pub fn init(cx: &mut MutableAppContext) {
|
||||
cx.add_action(ContactsPanel::select_next);
|
||||
cx.add_action(ContactsPanel::select_prev);
|
||||
cx.add_action(ContactsPanel::confirm);
|
||||
cx.add_action(ContactsPanel::toggle_expanded);
|
||||
}
|
||||
|
||||
impl ContactsPanel {
|
||||
@ -140,7 +146,7 @@ impl ContactsPanel {
|
||||
match &this.entries[ix] {
|
||||
ContactEntry::Header(section) => {
|
||||
let is_collapsed = this.collapsed_sections.contains(§ion);
|
||||
Self::render_header(*section, theme, is_selected, is_collapsed)
|
||||
Self::render_header(*section, theme, is_selected, is_collapsed, cx)
|
||||
}
|
||||
ContactEntry::IncomingRequest(user) => Self::render_contact_request(
|
||||
user.clone(),
|
||||
@ -203,7 +209,10 @@ impl ContactsPanel {
|
||||
theme: &theme::ContactsPanel,
|
||||
is_selected: bool,
|
||||
is_collapsed: bool,
|
||||
cx: &mut LayoutContext,
|
||||
) -> ElementBox {
|
||||
enum Header {}
|
||||
|
||||
let header_style = theme.header_row.style_for(&Default::default(), is_selected);
|
||||
let text = match section {
|
||||
Section::Requests => "Requests",
|
||||
@ -211,36 +220,41 @@ impl ContactsPanel {
|
||||
Section::Offline => "Offline",
|
||||
};
|
||||
let icon_size = theme.section_icon_size;
|
||||
Flex::row()
|
||||
.with_child(
|
||||
Svg::new(if is_collapsed {
|
||||
"icons/disclosure-closed.svg"
|
||||
} else {
|
||||
"icons/disclosure-open.svg"
|
||||
})
|
||||
.with_color(header_style.text.color)
|
||||
.constrained()
|
||||
.with_max_width(icon_size)
|
||||
.with_max_height(icon_size)
|
||||
.aligned()
|
||||
.constrained()
|
||||
.with_width(icon_size)
|
||||
.boxed(),
|
||||
)
|
||||
.with_child(
|
||||
Label::new(text.to_string(), header_style.text.clone())
|
||||
MouseEventHandler::new::<Header, _, _>(section as usize, cx, |_, _| {
|
||||
Flex::row()
|
||||
.with_child(
|
||||
Svg::new(if is_collapsed {
|
||||
"icons/disclosure-closed.svg"
|
||||
} else {
|
||||
"icons/disclosure-open.svg"
|
||||
})
|
||||
.with_color(header_style.text.color)
|
||||
.constrained()
|
||||
.with_max_width(icon_size)
|
||||
.with_max_height(icon_size)
|
||||
.aligned()
|
||||
.left()
|
||||
.contained()
|
||||
.with_margin_left(theme.contact_username.container.margin.left)
|
||||
.flex(1., true)
|
||||
.constrained()
|
||||
.with_width(icon_size)
|
||||
.boxed(),
|
||||
)
|
||||
.constrained()
|
||||
.with_height(theme.row_height)
|
||||
.contained()
|
||||
.with_style(header_style.container)
|
||||
.boxed()
|
||||
)
|
||||
.with_child(
|
||||
Label::new(text.to_string(), header_style.text.clone())
|
||||
.aligned()
|
||||
.left()
|
||||
.contained()
|
||||
.with_margin_left(theme.contact_username.container.margin.left)
|
||||
.flex(1., true)
|
||||
.boxed(),
|
||||
)
|
||||
.constrained()
|
||||
.with_height(theme.row_height)
|
||||
.contained()
|
||||
.with_style(header_style.container)
|
||||
.boxed()
|
||||
})
|
||||
.with_cursor_style(CursorStyle::PointingHand)
|
||||
.on_click(move |_, cx| cx.dispatch_action(ToggleExpanded(section)))
|
||||
.boxed()
|
||||
}
|
||||
|
||||
fn render_contact(
|
||||
@ -716,13 +730,8 @@ impl ContactsPanel {
|
||||
if let Some(entry) = self.entries.get(selection) {
|
||||
match entry {
|
||||
ContactEntry::Header(section) => {
|
||||
if let Some(ix) = self.collapsed_sections.iter().position(|s| s == section)
|
||||
{
|
||||
self.collapsed_sections.remove(ix);
|
||||
} else {
|
||||
self.collapsed_sections.push(*section);
|
||||
}
|
||||
self.update_entries(cx);
|
||||
let section = *section;
|
||||
self.toggle_expanded(&ToggleExpanded(section), cx);
|
||||
}
|
||||
ContactEntry::ContactProject(contact, project_ix) => {
|
||||
cx.dispatch_global_action(JoinProject {
|
||||
@ -733,9 +742,18 @@ impl ContactsPanel {
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
fn toggle_expanded(&mut self, action: &ToggleExpanded, cx: &mut ViewContext<Self>) {
|
||||
let section = action.0;
|
||||
if let Some(ix) = self.collapsed_sections.iter().position(|s| *s == section) {
|
||||
self.collapsed_sections.remove(ix);
|
||||
} else {
|
||||
self.collapsed_sections.push(section);
|
||||
}
|
||||
self.update_entries(cx);
|
||||
}
|
||||
}
|
||||
|
||||
impl SidebarItem for ContactsPanel {
|
||||
|
Loading…
Reference in New Issue
Block a user