mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-24 17:28:40 +00:00
Add settings for removing the assistant and collaboration panel buttons
Add a not-logged-in state to the collaboration panel co-authored-by: max <max@zed.dev>
This commit is contained in:
parent
e37e76fc0b
commit
8980a9f1c1
10 changed files with 195 additions and 115 deletions
|
@ -122,13 +122,17 @@
|
||||||
// Amount of indentation for nested items.
|
// Amount of indentation for nested items.
|
||||||
"indent_size": 20
|
"indent_size": 20
|
||||||
},
|
},
|
||||||
"channels_panel": {
|
"collaboration_panel": {
|
||||||
|
// Whether to show the collaboration panel button in the status bar.
|
||||||
|
"button": true,
|
||||||
// Where to dock channels panel. Can be 'left' or 'right'.
|
// Where to dock channels panel. Can be 'left' or 'right'.
|
||||||
"dock": "left",
|
"dock": "left",
|
||||||
// Default width of the channels panel.
|
// Default width of the channels panel.
|
||||||
"default_width": 240
|
"default_width": 240
|
||||||
},
|
},
|
||||||
"assistant": {
|
"assistant": {
|
||||||
|
// Whether to show the assistant panel button in the status bar.
|
||||||
|
"button": true,
|
||||||
// Where to dock the assistant. Can be 'left', 'right' or 'bottom'.
|
// Where to dock the assistant. Can be 'left', 'right' or 'bottom'.
|
||||||
"dock": "right",
|
"dock": "right",
|
||||||
// Default width when the assistant is docked to the left or right.
|
// Default width when the assistant is docked to the left or right.
|
||||||
|
@ -220,7 +224,9 @@
|
||||||
"copilot": {
|
"copilot": {
|
||||||
// The set of glob patterns for which copilot should be disabled
|
// The set of glob patterns for which copilot should be disabled
|
||||||
// in any matching file.
|
// in any matching file.
|
||||||
"disabled_globs": [".env"]
|
"disabled_globs": [
|
||||||
|
".env"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
// Settings specific to journaling
|
// Settings specific to journaling
|
||||||
"journal": {
|
"journal": {
|
||||||
|
|
|
@ -192,6 +192,7 @@ impl AssistantPanel {
|
||||||
old_dock_position = new_dock_position;
|
old_dock_position = new_dock_position;
|
||||||
cx.emit(AssistantPanelEvent::DockPositionChanged);
|
cx.emit(AssistantPanelEvent::DockPositionChanged);
|
||||||
}
|
}
|
||||||
|
cx.notify();
|
||||||
})];
|
})];
|
||||||
|
|
||||||
this
|
this
|
||||||
|
@ -790,8 +791,10 @@ impl Panel for AssistantPanel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn icon_path(&self) -> &'static str {
|
fn icon_path(&self, cx: &WindowContext) -> Option<&'static str> {
|
||||||
"icons/robot_14.svg"
|
settings::get::<AssistantSettings>(cx)
|
||||||
|
.button
|
||||||
|
.then(|| "icons/robot_14.svg")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn icon_tooltip(&self) -> (String, Option<Box<dyn Action>>) {
|
fn icon_tooltip(&self) -> (String, Option<Box<dyn Action>>) {
|
||||||
|
|
|
@ -13,6 +13,7 @@ pub enum AssistantDockPosition {
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
pub struct AssistantSettings {
|
pub struct AssistantSettings {
|
||||||
|
pub button: bool,
|
||||||
pub dock: AssistantDockPosition,
|
pub dock: AssistantDockPosition,
|
||||||
pub default_width: f32,
|
pub default_width: f32,
|
||||||
pub default_height: f32,
|
pub default_height: f32,
|
||||||
|
@ -20,6 +21,7 @@ pub struct AssistantSettings {
|
||||||
|
|
||||||
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug)]
|
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug)]
|
||||||
pub struct AssistantSettingsContent {
|
pub struct AssistantSettingsContent {
|
||||||
|
pub button: Option<bool>,
|
||||||
pub dock: Option<AssistantDockPosition>,
|
pub dock: Option<AssistantDockPosition>,
|
||||||
pub default_width: Option<f32>,
|
pub default_width: Option<f32>,
|
||||||
pub default_height: Option<f32>,
|
pub default_height: Option<f32>,
|
||||||
|
|
|
@ -27,7 +27,7 @@ use gpui::{
|
||||||
Subscription, Task, View, ViewContext, ViewHandle, WeakViewHandle,
|
Subscription, Task, View, ViewContext, ViewHandle, WeakViewHandle,
|
||||||
};
|
};
|
||||||
use menu::{Confirm, SelectNext, SelectPrev};
|
use menu::{Confirm, SelectNext, SelectPrev};
|
||||||
use panel_settings::{ChannelsPanelDockPosition, ChannelsPanelSettings};
|
use panel_settings::{CollaborationPanelDockPosition, CollaborationPanelSettings};
|
||||||
use project::{Fs, Project};
|
use project::{Fs, Project};
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
use settings::SettingsStore;
|
use settings::SettingsStore;
|
||||||
|
@ -65,7 +65,7 @@ impl_actions!(collab_panel, [RemoveChannel, NewChannel, AddMember]);
|
||||||
const CHANNELS_PANEL_KEY: &'static str = "ChannelsPanel";
|
const CHANNELS_PANEL_KEY: &'static str = "ChannelsPanel";
|
||||||
|
|
||||||
pub fn init(_client: Arc<Client>, cx: &mut AppContext) {
|
pub fn init(_client: Arc<Client>, cx: &mut AppContext) {
|
||||||
settings::register::<panel_settings::ChannelsPanelSettings>(cx);
|
settings::register::<panel_settings::CollaborationPanelSettings>(cx);
|
||||||
contact_finder::init(cx);
|
contact_finder::init(cx);
|
||||||
channel_modal::init(cx);
|
channel_modal::init(cx);
|
||||||
|
|
||||||
|
@ -95,6 +95,7 @@ pub struct CollabPanel {
|
||||||
entries: Vec<ListEntry>,
|
entries: Vec<ListEntry>,
|
||||||
selection: Option<usize>,
|
selection: Option<usize>,
|
||||||
user_store: ModelHandle<UserStore>,
|
user_store: ModelHandle<UserStore>,
|
||||||
|
client: Arc<Client>,
|
||||||
channel_store: ModelHandle<ChannelStore>,
|
channel_store: ModelHandle<ChannelStore>,
|
||||||
project: ModelHandle<Project>,
|
project: ModelHandle<Project>,
|
||||||
match_candidates: Vec<StringMatchCandidate>,
|
match_candidates: Vec<StringMatchCandidate>,
|
||||||
|
@ -320,6 +321,7 @@ impl CollabPanel {
|
||||||
match_candidates: Vec::default(),
|
match_candidates: Vec::default(),
|
||||||
collapsed_sections: Vec::default(),
|
collapsed_sections: Vec::default(),
|
||||||
workspace: workspace.weak_handle(),
|
workspace: workspace.weak_handle(),
|
||||||
|
client: workspace.app_state().client.clone(),
|
||||||
list_state,
|
list_state,
|
||||||
};
|
};
|
||||||
this.update_entries(cx);
|
this.update_entries(cx);
|
||||||
|
@ -334,6 +336,7 @@ impl CollabPanel {
|
||||||
old_dock_position = new_dock_position;
|
old_dock_position = new_dock_position;
|
||||||
cx.emit(Event::DockPositionChanged);
|
cx.emit(Event::DockPositionChanged);
|
||||||
}
|
}
|
||||||
|
cx.notify();
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1862,6 +1865,31 @@ impl View for CollabPanel {
|
||||||
fn render(&mut self, cx: &mut gpui::ViewContext<'_, '_, Self>) -> gpui::AnyElement<Self> {
|
fn render(&mut self, cx: &mut gpui::ViewContext<'_, '_, Self>) -> gpui::AnyElement<Self> {
|
||||||
let theme = &theme::current(cx).collab_panel;
|
let theme = &theme::current(cx).collab_panel;
|
||||||
|
|
||||||
|
if self.user_store.read(cx).current_user().is_none() {
|
||||||
|
enum LogInButton {}
|
||||||
|
|
||||||
|
return Flex::column()
|
||||||
|
.with_child(
|
||||||
|
MouseEventHandler::<LogInButton, _>::new(0, cx, |state, _| {
|
||||||
|
let button = theme.log_in_button.style_for(state);
|
||||||
|
Label::new("Sign in to collaborate", button.text.clone())
|
||||||
|
.contained()
|
||||||
|
.with_style(button.container)
|
||||||
|
})
|
||||||
|
.on_click(MouseButton::Left, |_, this, cx| {
|
||||||
|
let client = this.client.clone();
|
||||||
|
cx.spawn(|_, cx| async move {
|
||||||
|
client.authenticate_and_connect(true, &cx).await.log_err()
|
||||||
|
})
|
||||||
|
.detach();
|
||||||
|
})
|
||||||
|
.with_cursor_style(CursorStyle::PointingHand),
|
||||||
|
)
|
||||||
|
.contained()
|
||||||
|
.with_style(theme.container)
|
||||||
|
.into_any();
|
||||||
|
}
|
||||||
|
|
||||||
enum PanelFocus {}
|
enum PanelFocus {}
|
||||||
MouseEventHandler::<PanelFocus, _>::new(0, cx, |_, cx| {
|
MouseEventHandler::<PanelFocus, _>::new(0, cx, |_, cx| {
|
||||||
Stack::new()
|
Stack::new()
|
||||||
|
@ -1901,9 +1929,9 @@ impl View for CollabPanel {
|
||||||
|
|
||||||
impl Panel for CollabPanel {
|
impl Panel for CollabPanel {
|
||||||
fn position(&self, cx: &gpui::WindowContext) -> DockPosition {
|
fn position(&self, cx: &gpui::WindowContext) -> DockPosition {
|
||||||
match settings::get::<ChannelsPanelSettings>(cx).dock {
|
match settings::get::<CollaborationPanelSettings>(cx).dock {
|
||||||
ChannelsPanelDockPosition::Left => DockPosition::Left,
|
CollaborationPanelDockPosition::Left => DockPosition::Left,
|
||||||
ChannelsPanelDockPosition::Right => DockPosition::Right,
|
CollaborationPanelDockPosition::Right => DockPosition::Right,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1912,13 +1940,15 @@ impl Panel for CollabPanel {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_position(&mut self, position: DockPosition, cx: &mut ViewContext<Self>) {
|
fn set_position(&mut self, position: DockPosition, cx: &mut ViewContext<Self>) {
|
||||||
settings::update_settings_file::<ChannelsPanelSettings>(
|
settings::update_settings_file::<CollaborationPanelSettings>(
|
||||||
self.fs.clone(),
|
self.fs.clone(),
|
||||||
cx,
|
cx,
|
||||||
move |settings| {
|
move |settings| {
|
||||||
let dock = match position {
|
let dock = match position {
|
||||||
DockPosition::Left | DockPosition::Bottom => ChannelsPanelDockPosition::Left,
|
DockPosition::Left | DockPosition::Bottom => {
|
||||||
DockPosition::Right => ChannelsPanelDockPosition::Right,
|
CollaborationPanelDockPosition::Left
|
||||||
|
}
|
||||||
|
DockPosition::Right => CollaborationPanelDockPosition::Right,
|
||||||
};
|
};
|
||||||
settings.dock = Some(dock);
|
settings.dock = Some(dock);
|
||||||
},
|
},
|
||||||
|
@ -1927,7 +1957,7 @@ impl Panel for CollabPanel {
|
||||||
|
|
||||||
fn size(&self, cx: &gpui::WindowContext) -> f32 {
|
fn size(&self, cx: &gpui::WindowContext) -> f32 {
|
||||||
self.width
|
self.width
|
||||||
.unwrap_or_else(|| settings::get::<ChannelsPanelSettings>(cx).default_width)
|
.unwrap_or_else(|| settings::get::<CollaborationPanelSettings>(cx).default_width)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_size(&mut self, size: f32, cx: &mut ViewContext<Self>) {
|
fn set_size(&mut self, size: f32, cx: &mut ViewContext<Self>) {
|
||||||
|
@ -1936,8 +1966,10 @@ impl Panel for CollabPanel {
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn icon_path(&self) -> &'static str {
|
fn icon_path(&self, cx: &gpui::WindowContext) -> Option<&'static str> {
|
||||||
"icons/radix/person.svg"
|
settings::get::<CollaborationPanelSettings>(cx)
|
||||||
|
.button
|
||||||
|
.then(|| "icons/radix/person.svg")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn icon_tooltip(&self) -> (String, Option<Box<dyn gpui::Action>>) {
|
fn icon_tooltip(&self) -> (String, Option<Box<dyn gpui::Action>>) {
|
||||||
|
|
|
@ -5,27 +5,29 @@ use settings::Setting;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
|
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub enum ChannelsPanelDockPosition {
|
pub enum CollaborationPanelDockPosition {
|
||||||
Left,
|
Left,
|
||||||
Right,
|
Right,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
pub struct ChannelsPanelSettings {
|
pub struct CollaborationPanelSettings {
|
||||||
pub dock: ChannelsPanelDockPosition,
|
pub button: bool,
|
||||||
|
pub dock: CollaborationPanelDockPosition,
|
||||||
pub default_width: f32,
|
pub default_width: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug)]
|
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug)]
|
||||||
pub struct ChannelsPanelSettingsContent {
|
pub struct CollaborationPanelSettingsContent {
|
||||||
pub dock: Option<ChannelsPanelDockPosition>,
|
pub button: Option<bool>,
|
||||||
|
pub dock: Option<CollaborationPanelDockPosition>,
|
||||||
pub default_width: Option<f32>,
|
pub default_width: Option<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Setting for ChannelsPanelSettings {
|
impl Setting for CollaborationPanelSettings {
|
||||||
const KEY: Option<&'static str> = Some("channels_panel");
|
const KEY: Option<&'static str> = Some("collaboration_panel");
|
||||||
|
|
||||||
type FileContent = ChannelsPanelSettingsContent;
|
type FileContent = CollaborationPanelSettingsContent;
|
||||||
|
|
||||||
fn load(
|
fn load(
|
||||||
default_value: &Self::FileContent,
|
default_value: &Self::FileContent,
|
||||||
|
|
|
@ -1657,8 +1657,8 @@ impl workspace::dock::Panel for ProjectPanel {
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn icon_path(&self) -> &'static str {
|
fn icon_path(&self, _: &WindowContext) -> Option<&'static str> {
|
||||||
"icons/folder_tree_16.svg"
|
Some("icons/folder_tree_16.svg")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn icon_tooltip(&self) -> (String, Option<Box<dyn Action>>) {
|
fn icon_tooltip(&self) -> (String, Option<Box<dyn Action>>) {
|
||||||
|
|
|
@ -396,8 +396,8 @@ impl Panel for TerminalPanel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn icon_path(&self) -> &'static str {
|
fn icon_path(&self, _: &WindowContext) -> Option<&'static str> {
|
||||||
"icons/terminal_12.svg"
|
Some("icons/terminal_12.svg")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn icon_tooltip(&self) -> (String, Option<Box<dyn Action>>) {
|
fn icon_tooltip(&self) -> (String, Option<Box<dyn Action>>) {
|
||||||
|
|
|
@ -220,6 +220,7 @@ pub struct CopilotAuthAuthorized {
|
||||||
pub struct CollabPanel {
|
pub struct CollabPanel {
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub container: ContainerStyle,
|
pub container: ContainerStyle,
|
||||||
|
pub log_in_button: Interactive<ContainedText>,
|
||||||
pub channel_hash: Icon,
|
pub channel_hash: Icon,
|
||||||
pub channel_modal: ChannelModal,
|
pub channel_modal: ChannelModal,
|
||||||
pub user_query_editor: FieldEditor,
|
pub user_query_editor: FieldEditor,
|
||||||
|
|
|
@ -14,7 +14,7 @@ pub trait Panel: View {
|
||||||
fn set_position(&mut self, position: DockPosition, cx: &mut ViewContext<Self>);
|
fn set_position(&mut self, position: DockPosition, cx: &mut ViewContext<Self>);
|
||||||
fn size(&self, cx: &WindowContext) -> f32;
|
fn size(&self, cx: &WindowContext) -> f32;
|
||||||
fn set_size(&mut self, size: f32, cx: &mut ViewContext<Self>);
|
fn set_size(&mut self, size: f32, cx: &mut ViewContext<Self>);
|
||||||
fn icon_path(&self) -> &'static str;
|
fn icon_path(&self, cx: &WindowContext) -> Option<&'static str>;
|
||||||
fn icon_tooltip(&self) -> (String, Option<Box<dyn Action>>);
|
fn icon_tooltip(&self) -> (String, Option<Box<dyn Action>>);
|
||||||
fn icon_label(&self, _: &WindowContext) -> Option<String> {
|
fn icon_label(&self, _: &WindowContext) -> Option<String> {
|
||||||
None
|
None
|
||||||
|
@ -51,7 +51,7 @@ pub trait PanelHandle {
|
||||||
fn set_active(&self, active: bool, cx: &mut WindowContext);
|
fn set_active(&self, active: bool, cx: &mut WindowContext);
|
||||||
fn size(&self, cx: &WindowContext) -> f32;
|
fn size(&self, cx: &WindowContext) -> f32;
|
||||||
fn set_size(&self, size: f32, cx: &mut WindowContext);
|
fn set_size(&self, size: f32, cx: &mut WindowContext);
|
||||||
fn icon_path(&self, cx: &WindowContext) -> &'static str;
|
fn icon_path(&self, cx: &WindowContext) -> Option<&'static str>;
|
||||||
fn icon_tooltip(&self, cx: &WindowContext) -> (String, Option<Box<dyn Action>>);
|
fn icon_tooltip(&self, cx: &WindowContext) -> (String, Option<Box<dyn Action>>);
|
||||||
fn icon_label(&self, cx: &WindowContext) -> Option<String>;
|
fn icon_label(&self, cx: &WindowContext) -> Option<String>;
|
||||||
fn has_focus(&self, cx: &WindowContext) -> bool;
|
fn has_focus(&self, cx: &WindowContext) -> bool;
|
||||||
|
@ -98,8 +98,8 @@ where
|
||||||
self.update(cx, |this, cx| this.set_active(active, cx))
|
self.update(cx, |this, cx| this.set_active(active, cx))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn icon_path(&self, cx: &WindowContext) -> &'static str {
|
fn icon_path(&self, cx: &WindowContext) -> Option<&'static str> {
|
||||||
self.read(cx).icon_path()
|
self.read(cx).icon_path(cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn icon_tooltip(&self, cx: &WindowContext) -> (String, Option<Box<dyn Action>>) {
|
fn icon_tooltip(&self, cx: &WindowContext) -> (String, Option<Box<dyn Action>>) {
|
||||||
|
@ -490,8 +490,9 @@ impl View for PanelButtons {
|
||||||
.map(|item| (item.panel.clone(), item.context_menu.clone()))
|
.map(|item| (item.panel.clone(), item.context_menu.clone()))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
Flex::row()
|
Flex::row()
|
||||||
.with_children(panels.into_iter().enumerate().map(
|
.with_children(panels.into_iter().enumerate().filter_map(
|
||||||
|(panel_ix, (view, context_menu))| {
|
|(panel_ix, (view, context_menu))| {
|
||||||
|
let icon_path = view.icon_path(cx)?;
|
||||||
let is_active = is_open && panel_ix == active_ix;
|
let is_active = is_open && panel_ix == active_ix;
|
||||||
let (tooltip, tooltip_action) = if is_active {
|
let (tooltip, tooltip_action) = if is_active {
|
||||||
(
|
(
|
||||||
|
@ -505,94 +506,96 @@ impl View for PanelButtons {
|
||||||
} else {
|
} else {
|
||||||
view.icon_tooltip(cx)
|
view.icon_tooltip(cx)
|
||||||
};
|
};
|
||||||
Stack::new()
|
Some(
|
||||||
.with_child(
|
Stack::new()
|
||||||
MouseEventHandler::<Self, _>::new(panel_ix, cx, |state, cx| {
|
.with_child(
|
||||||
let style = button_style.in_state(is_active);
|
MouseEventHandler::<Self, _>::new(panel_ix, cx, |state, cx| {
|
||||||
|
let style = button_style.in_state(is_active);
|
||||||
|
|
||||||
let style = style.style_for(state);
|
let style = style.style_for(state);
|
||||||
Flex::row()
|
Flex::row()
|
||||||
.with_child(
|
.with_child(
|
||||||
Svg::new(view.icon_path(cx))
|
Svg::new(icon_path)
|
||||||
.with_color(style.icon_color)
|
.with_color(style.icon_color)
|
||||||
.constrained()
|
.constrained()
|
||||||
.with_width(style.icon_size)
|
.with_width(style.icon_size)
|
||||||
.aligned(),
|
|
||||||
)
|
|
||||||
.with_children(if let Some(label) = view.icon_label(cx) {
|
|
||||||
Some(
|
|
||||||
Label::new(label, style.label.text.clone())
|
|
||||||
.contained()
|
|
||||||
.with_style(style.label.container)
|
|
||||||
.aligned(),
|
.aligned(),
|
||||||
)
|
)
|
||||||
} else {
|
.with_children(if let Some(label) = view.icon_label(cx) {
|
||||||
None
|
Some(
|
||||||
})
|
Label::new(label, style.label.text.clone())
|
||||||
.constrained()
|
.contained()
|
||||||
.with_height(style.icon_size)
|
.with_style(style.label.container)
|
||||||
.contained()
|
.aligned(),
|
||||||
.with_style(style.container)
|
|
||||||
})
|
|
||||||
.with_cursor_style(CursorStyle::PointingHand)
|
|
||||||
.on_click(MouseButton::Left, {
|
|
||||||
let tooltip_action =
|
|
||||||
tooltip_action.as_ref().map(|action| action.boxed_clone());
|
|
||||||
move |_, this, cx| {
|
|
||||||
if let Some(tooltip_action) = &tooltip_action {
|
|
||||||
let window_id = cx.window_id();
|
|
||||||
let view_id = this.workspace.id();
|
|
||||||
let tooltip_action = tooltip_action.boxed_clone();
|
|
||||||
cx.spawn(|_, mut cx| async move {
|
|
||||||
cx.dispatch_action(
|
|
||||||
window_id,
|
|
||||||
view_id,
|
|
||||||
&*tooltip_action,
|
|
||||||
)
|
)
|
||||||
.ok();
|
} else {
|
||||||
|
None
|
||||||
})
|
})
|
||||||
.detach();
|
.constrained()
|
||||||
}
|
.with_height(style.icon_size)
|
||||||
}
|
.contained()
|
||||||
})
|
.with_style(style.container)
|
||||||
.on_click(MouseButton::Right, {
|
})
|
||||||
let view = view.clone();
|
.with_cursor_style(CursorStyle::PointingHand)
|
||||||
let menu = context_menu.clone();
|
.on_click(MouseButton::Left, {
|
||||||
move |_, _, cx| {
|
let tooltip_action =
|
||||||
const POSITIONS: [DockPosition; 3] = [
|
tooltip_action.as_ref().map(|action| action.boxed_clone());
|
||||||
DockPosition::Left,
|
move |_, this, cx| {
|
||||||
DockPosition::Right,
|
if let Some(tooltip_action) = &tooltip_action {
|
||||||
DockPosition::Bottom,
|
let window_id = cx.window_id();
|
||||||
];
|
let view_id = this.workspace.id();
|
||||||
|
let tooltip_action = tooltip_action.boxed_clone();
|
||||||
menu.update(cx, |menu, cx| {
|
cx.spawn(|_, mut cx| async move {
|
||||||
let items = POSITIONS
|
cx.dispatch_action(
|
||||||
.into_iter()
|
window_id,
|
||||||
.filter(|position| {
|
view_id,
|
||||||
*position != dock_position
|
&*tooltip_action,
|
||||||
&& view.position_is_valid(*position, cx)
|
|
||||||
})
|
|
||||||
.map(|position| {
|
|
||||||
let view = view.clone();
|
|
||||||
ContextMenuItem::handler(
|
|
||||||
format!("Dock {}", position.to_label()),
|
|
||||||
move |cx| view.set_position(position, cx),
|
|
||||||
)
|
)
|
||||||
|
.ok();
|
||||||
})
|
})
|
||||||
.collect();
|
.detach();
|
||||||
menu.show(Default::default(), menu_corner, items, cx);
|
}
|
||||||
})
|
}
|
||||||
}
|
})
|
||||||
})
|
.on_click(MouseButton::Right, {
|
||||||
.with_tooltip::<Self>(
|
let view = view.clone();
|
||||||
panel_ix,
|
let menu = context_menu.clone();
|
||||||
tooltip,
|
move |_, _, cx| {
|
||||||
tooltip_action,
|
const POSITIONS: [DockPosition; 3] = [
|
||||||
tooltip_style.clone(),
|
DockPosition::Left,
|
||||||
cx,
|
DockPosition::Right,
|
||||||
),
|
DockPosition::Bottom,
|
||||||
)
|
];
|
||||||
.with_child(ChildView::new(&context_menu, cx))
|
|
||||||
|
menu.update(cx, |menu, cx| {
|
||||||
|
let items = POSITIONS
|
||||||
|
.into_iter()
|
||||||
|
.filter(|position| {
|
||||||
|
*position != dock_position
|
||||||
|
&& view.position_is_valid(*position, cx)
|
||||||
|
})
|
||||||
|
.map(|position| {
|
||||||
|
let view = view.clone();
|
||||||
|
ContextMenuItem::handler(
|
||||||
|
format!("Dock {}", position.to_label()),
|
||||||
|
move |cx| view.set_position(position, cx),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
menu.show(Default::default(), menu_corner, items, cx);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.with_tooltip::<Self>(
|
||||||
|
panel_ix,
|
||||||
|
tooltip,
|
||||||
|
tooltip_action,
|
||||||
|
tooltip_style.clone(),
|
||||||
|
cx,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.with_child(ChildView::new(&context_menu, cx)),
|
||||||
|
)
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
.contained()
|
.contained()
|
||||||
|
@ -702,8 +705,8 @@ pub mod test {
|
||||||
self.size = size;
|
self.size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn icon_path(&self) -> &'static str {
|
fn icon_path(&self, _: &WindowContext) -> Option<&'static str> {
|
||||||
"icons/test_panel.svg"
|
Some("icons/test_panel.svg")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn icon_tooltip(&self) -> (String, Option<Box<dyn Action>>) {
|
fn icon_tooltip(&self) -> (String, Option<Box<dyn Action>>) {
|
||||||
|
|
|
@ -67,6 +67,37 @@ export default function contacts_panel(): any {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
channel_modal: channel_modal(),
|
channel_modal: channel_modal(),
|
||||||
|
log_in_button: interactive({
|
||||||
|
base: {
|
||||||
|
background: background(theme.middle),
|
||||||
|
border: border(theme.middle, "active"),
|
||||||
|
corner_radius: 4,
|
||||||
|
margin: {
|
||||||
|
top: 16,
|
||||||
|
left: 16,
|
||||||
|
right: 16,
|
||||||
|
},
|
||||||
|
padding: {
|
||||||
|
top: 3,
|
||||||
|
bottom: 3,
|
||||||
|
left: 7,
|
||||||
|
right: 7,
|
||||||
|
},
|
||||||
|
...text(theme.middle, "sans", "default", { size: "sm" }),
|
||||||
|
},
|
||||||
|
state: {
|
||||||
|
hovered: {
|
||||||
|
...text(theme.middle, "sans", "default", { size: "sm" }),
|
||||||
|
background: background(theme.middle, "hovered"),
|
||||||
|
border: border(theme.middle, "active"),
|
||||||
|
},
|
||||||
|
clicked: {
|
||||||
|
...text(theme.middle, "sans", "default", { size: "sm" }),
|
||||||
|
background: background(theme.middle, "pressed"),
|
||||||
|
border: border(theme.middle, "active"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
background: background(layer),
|
background: background(layer),
|
||||||
padding: {
|
padding: {
|
||||||
top: 12,
|
top: 12,
|
||||||
|
|
Loading…
Reference in a new issue