Compare commits
4 Commits
git-graph
...
update-rec
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1d64b5adc7 | ||
|
|
bb0dacc347 | ||
|
|
cdbfb8f04c | ||
|
|
5c6668e572 |
@@ -108,6 +108,12 @@
|
|||||||
"confirm_quit": false,
|
"confirm_quit": false,
|
||||||
// Whether to restore last closed project when fresh Zed instance is opened.
|
// Whether to restore last closed project when fresh Zed instance is opened.
|
||||||
"restore_on_startup": "last_session",
|
"restore_on_startup": "last_session",
|
||||||
|
// Whether to reuse the current window when opening a recent project
|
||||||
|
// or create a new window.
|
||||||
|
//
|
||||||
|
// If the project is already open in another window, that window will be
|
||||||
|
// focused, regardless of this setting.
|
||||||
|
"open_recent_project": "open_in_new_window",
|
||||||
// Size of the drop target in the editor.
|
// Size of the drop target in the editor.
|
||||||
"drop_target_size": 0.2,
|
"drop_target_size": 0.2,
|
||||||
// Whether the window should be closed when using 'close active item' on a window with no tabs.
|
// Whether the window should be closed when using 'close active item' on a window with no tabs.
|
||||||
|
|||||||
@@ -5613,6 +5613,7 @@ impl Editor {
|
|||||||
} else {
|
} else {
|
||||||
Color::Default
|
Color::Default
|
||||||
}),
|
}),
|
||||||
|
None,
|
||||||
true,
|
true,
|
||||||
),
|
),
|
||||||
))
|
))
|
||||||
|
|||||||
@@ -5784,6 +5784,7 @@ fn inline_completion_accept_indicator(
|
|||||||
&accept_keystroke.modifiers,
|
&accept_keystroke.modifiers,
|
||||||
PlatformStyle::platform(),
|
PlatformStyle::platform(),
|
||||||
Some(Color::Default),
|
Some(Color::Default),
|
||||||
|
None,
|
||||||
false,
|
false,
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1309,6 +1309,7 @@ impl PickerDelegate for FileFinderDelegate {
|
|||||||
let context = self.focus_handle.clone();
|
let context = self.focus_handle.clone();
|
||||||
Some(
|
Some(
|
||||||
h_flex()
|
h_flex()
|
||||||
|
.id("recent-projects-footer")
|
||||||
.w_full()
|
.w_full()
|
||||||
.p_2()
|
.p_2()
|
||||||
.gap_2()
|
.gap_2()
|
||||||
|
|||||||
@@ -21,7 +21,10 @@ use std::{
|
|||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
};
|
};
|
||||||
use ui::{prelude::*, tooltip_container, KeyBinding, ListItem, ListItemSpacing, Tooltip};
|
use ui::{
|
||||||
|
prelude::*, tooltip_container, ElevationIndex, KeyBinding, KeybindingHint, KeybindingPosition,
|
||||||
|
ListItem, ListItemSpacing, Tooltip,
|
||||||
|
};
|
||||||
use util::{paths::PathExt, ResultExt};
|
use util::{paths::PathExt, ResultExt};
|
||||||
use workspace::{
|
use workspace::{
|
||||||
CloseIntent, ModalView, OpenOptions, SerializedWorkspaceLocation, Workspace, WorkspaceId,
|
CloseIntent, ModalView, OpenOptions, SerializedWorkspaceLocation, Workspace, WorkspaceId,
|
||||||
@@ -110,6 +113,7 @@ impl RecentProjects {
|
|||||||
cx: &mut Context<Workspace>,
|
cx: &mut Context<Workspace>,
|
||||||
) {
|
) {
|
||||||
let weak = cx.entity().downgrade();
|
let weak = cx.entity().downgrade();
|
||||||
|
|
||||||
workspace.toggle_modal(window, cx, |window, cx| {
|
workspace.toggle_modal(window, cx, |window, cx| {
|
||||||
let delegate = RecentProjectsDelegate::new(weak, create_new_window, true);
|
let delegate = RecentProjectsDelegate::new(weak, create_new_window, true);
|
||||||
|
|
||||||
@@ -177,21 +181,8 @@ impl EventEmitter<DismissEvent> for RecentProjectsDelegate {}
|
|||||||
impl PickerDelegate for RecentProjectsDelegate {
|
impl PickerDelegate for RecentProjectsDelegate {
|
||||||
type ListItem = ListItem;
|
type ListItem = ListItem;
|
||||||
|
|
||||||
fn placeholder_text(&self, window: &mut Window, _: &mut App) -> Arc<str> {
|
fn placeholder_text(&self, _window: &mut Window, _: &mut App) -> Arc<str> {
|
||||||
let (create_window, reuse_window) = if self.create_new_window {
|
Arc::from("Open recent project")
|
||||||
(
|
|
||||||
window.keystroke_text_for(&menu::Confirm),
|
|
||||||
window.keystroke_text_for(&menu::SecondaryConfirm),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
(
|
|
||||||
window.keystroke_text_for(&menu::SecondaryConfirm),
|
|
||||||
window.keystroke_text_for(&menu::Confirm),
|
|
||||||
)
|
|
||||||
};
|
|
||||||
Arc::from(format!(
|
|
||||||
"{reuse_window} reuses this window, {create_window} opens a new one",
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn match_count(&self) -> usize {
|
fn match_count(&self) -> usize {
|
||||||
@@ -268,9 +259,9 @@ impl PickerDelegate for RecentProjectsDelegate {
|
|||||||
let (candidate_workspace_id, candidate_workspace_location) =
|
let (candidate_workspace_id, candidate_workspace_location) =
|
||||||
&self.workspaces[selected_match.candidate_id];
|
&self.workspaces[selected_match.candidate_id];
|
||||||
let replace_current_window = if self.create_new_window {
|
let replace_current_window = if self.create_new_window {
|
||||||
secondary
|
|
||||||
} else {
|
|
||||||
!secondary
|
!secondary
|
||||||
|
} else {
|
||||||
|
secondary
|
||||||
};
|
};
|
||||||
workspace
|
workspace
|
||||||
.update(cx, |workspace, cx| {
|
.update(cx, |workspace, cx| {
|
||||||
@@ -353,7 +344,7 @@ impl PickerDelegate for RecentProjectsDelegate {
|
|||||||
|
|
||||||
fn no_matches_text(&self, _window: &mut Window, _cx: &mut App) -> SharedString {
|
fn no_matches_text(&self, _window: &mut Window, _cx: &mut App) -> SharedString {
|
||||||
if self.workspaces.is_empty() {
|
if self.workspaces.is_empty() {
|
||||||
"Recently opened projects will show up here".into()
|
"No recent projects".into()
|
||||||
} else {
|
} else {
|
||||||
"No matches".into()
|
"No matches".into()
|
||||||
}
|
}
|
||||||
@@ -424,13 +415,14 @@ impl PickerDelegate for RecentProjectsDelegate {
|
|||||||
.child(
|
.child(
|
||||||
IconButton::new("delete", IconName::Close)
|
IconButton::new("delete", IconName::Close)
|
||||||
.icon_size(IconSize::Small)
|
.icon_size(IconSize::Small)
|
||||||
|
.icon_color(Color::Muted)
|
||||||
.on_click(cx.listener(move |this, _event, window, cx| {
|
.on_click(cx.listener(move |this, _event, window, cx| {
|
||||||
cx.stop_propagation();
|
cx.stop_propagation();
|
||||||
window.prevent_default();
|
window.prevent_default();
|
||||||
|
|
||||||
this.delegate.delete_recent_project(ix, window, cx)
|
this.delegate.delete_recent_project(ix, window, cx)
|
||||||
}))
|
}))
|
||||||
.tooltip(Tooltip::text("Delete from Recent Projects...")),
|
.tooltip(Tooltip::text("Remove")),
|
||||||
)
|
)
|
||||||
.into_any_element();
|
.into_any_element();
|
||||||
|
|
||||||
@@ -460,24 +452,55 @@ impl PickerDelegate for RecentProjectsDelegate {
|
|||||||
.w_full()
|
.w_full()
|
||||||
.p_2()
|
.p_2()
|
||||||
.gap_2()
|
.gap_2()
|
||||||
.justify_end()
|
.justify_between()
|
||||||
.border_t_1()
|
.border_t_1()
|
||||||
.border_color(cx.theme().colors().border_variant)
|
.border_color(cx.theme().colors().border_variant)
|
||||||
.child(
|
.child(
|
||||||
Button::new("remote", "Open Remote Folder")
|
h_flex()
|
||||||
.key_binding(KeyBinding::for_action(&OpenRemote, window))
|
.w_full()
|
||||||
.on_click(|_, window, cx| {
|
.gap_2()
|
||||||
window.dispatch_action(OpenRemote.boxed_clone(), cx)
|
.when_some(
|
||||||
}),
|
KeyBinding::for_action(&menu::Confirm, window),
|
||||||
|
|this, keybinding| {
|
||||||
|
this.child(
|
||||||
|
KeybindingHint::with_suffix(keybinding, "open")
|
||||||
|
.elevation(ElevationIndex::ModalSurface)
|
||||||
|
.size(px(14.)),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.when_some(
|
||||||
|
KeyBinding::for_action(&menu::SecondaryConfirm, window),
|
||||||
|
|this, keybinding| {
|
||||||
|
this.child(
|
||||||
|
KeybindingHint::with_suffix(keybinding, "swap")
|
||||||
|
.elevation(ElevationIndex::ModalSurface)
|
||||||
|
.size(px(14.)),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
Button::new("local", "Open Local Folder")
|
h_flex()
|
||||||
.key_binding(KeyBinding::for_action(&workspace::Open, window))
|
.gap_2()
|
||||||
.on_click(|_, window, cx| {
|
.child(
|
||||||
window.dispatch_action(workspace::Open.boxed_clone(), cx)
|
Button::new("remote", "Open Remote…")
|
||||||
}),
|
.key_binding(KeyBinding::for_action(&OpenRemote, window))
|
||||||
|
.key_binding_position(KeybindingPosition::Start)
|
||||||
|
.on_click(|_, window, cx| {
|
||||||
|
window.dispatch_action(OpenRemote.boxed_clone(), cx)
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.child(
|
||||||
|
Button::new("local", "Open…")
|
||||||
|
.key_binding(KeyBinding::for_action(&workspace::Open, window))
|
||||||
|
.key_binding_position(KeybindingPosition::Start)
|
||||||
|
.on_click(|_, window, cx| {
|
||||||
|
window.dispatch_action(workspace::Open.boxed_clone(), cx)
|
||||||
|
}),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.into_any(),
|
.into_any_element(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,9 @@ use ui::{
|
|||||||
IconSize, IconWithIndicator, Indicator, PopoverMenu, Tooltip,
|
IconSize, IconWithIndicator, Indicator, PopoverMenu, Tooltip,
|
||||||
};
|
};
|
||||||
use util::ResultExt;
|
use util::ResultExt;
|
||||||
use workspace::{notifications::NotifyResultExt, Workspace};
|
use workspace::{
|
||||||
|
notifications::NotifyResultExt, OpenRecentProjectBehavior, Workspace, WorkspaceSettings,
|
||||||
|
};
|
||||||
use zed_actions::{OpenBrowser, OpenRecent, OpenRemote};
|
use zed_actions::{OpenBrowser, OpenRecent, OpenRemote};
|
||||||
use zeta::ZedPredictBanner;
|
use zeta::ZedPredictBanner;
|
||||||
|
|
||||||
@@ -451,6 +453,9 @@ impl TitleBar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_project_name(&self, cx: &mut Context<Self>) -> impl IntoElement {
|
pub fn render_project_name(&self, cx: &mut Context<Self>) -> impl IntoElement {
|
||||||
|
let settings = WorkspaceSettings::get_global(cx);
|
||||||
|
let open_recent_behavior = settings.open_recent_project;
|
||||||
|
|
||||||
let name = {
|
let name = {
|
||||||
let mut names = self.project.read(cx).visible_worktrees(cx).map(|worktree| {
|
let mut names = self.project.read(cx).visible_worktrees(cx).map(|worktree| {
|
||||||
let worktree = worktree.read(cx);
|
let worktree = worktree.read(cx);
|
||||||
@@ -474,7 +479,10 @@ impl TitleBar {
|
|||||||
Tooltip::for_action(
|
Tooltip::for_action(
|
||||||
"Recent Projects",
|
"Recent Projects",
|
||||||
&zed_actions::OpenRecent {
|
&zed_actions::OpenRecent {
|
||||||
create_new_window: false,
|
create_new_window: matches!(
|
||||||
|
open_recent_behavior,
|
||||||
|
OpenRecentProjectBehavior::OpenInNewWindow
|
||||||
|
),
|
||||||
},
|
},
|
||||||
window,
|
window,
|
||||||
cx,
|
cx,
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ mod image;
|
|||||||
mod indent_guides;
|
mod indent_guides;
|
||||||
mod indicator;
|
mod indicator;
|
||||||
mod keybinding;
|
mod keybinding;
|
||||||
|
mod keybinding_hint;
|
||||||
mod label;
|
mod label;
|
||||||
mod list;
|
mod list;
|
||||||
mod modal;
|
mod modal;
|
||||||
@@ -47,6 +48,7 @@ pub use image::*;
|
|||||||
pub use indent_guides::*;
|
pub use indent_guides::*;
|
||||||
pub use indicator::*;
|
pub use indicator::*;
|
||||||
pub use keybinding::*;
|
pub use keybinding::*;
|
||||||
|
pub use keybinding_hint::*;
|
||||||
pub use label::*;
|
pub use label::*;
|
||||||
pub use list::*;
|
pub use list::*;
|
||||||
pub use modal::*;
|
pub use modal::*;
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
use gpui::{AnyView, DefiniteLength};
|
use gpui::{AnyView, DefiniteLength};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
prelude::*, Color, DynamicSpacing, ElevationIndex, IconPosition, KeyBinding, TintColor,
|
prelude::*, Color, DynamicSpacing, ElevationIndex, IconPosition, KeyBinding,
|
||||||
|
KeybindingPosition, TintColor,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
ButtonCommon, ButtonLike, ButtonSize, ButtonStyle, IconName, IconSize, Label, LineHeightStyle,
|
ButtonCommon, ButtonLike, ButtonSize, ButtonStyle, IconName, IconSize, Label, LineHeightStyle,
|
||||||
@@ -92,6 +93,7 @@ pub struct Button {
|
|||||||
selected_icon: Option<IconName>,
|
selected_icon: Option<IconName>,
|
||||||
selected_icon_color: Option<Color>,
|
selected_icon_color: Option<Color>,
|
||||||
key_binding: Option<KeyBinding>,
|
key_binding: Option<KeyBinding>,
|
||||||
|
keybinding_position: KeybindingPosition,
|
||||||
alpha: Option<f32>,
|
alpha: Option<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,6 +119,7 @@ impl Button {
|
|||||||
selected_icon: None,
|
selected_icon: None,
|
||||||
selected_icon_color: None,
|
selected_icon_color: None,
|
||||||
key_binding: None,
|
key_binding: None,
|
||||||
|
keybinding_position: KeybindingPosition::default(),
|
||||||
alpha: None,
|
alpha: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -187,6 +190,15 @@ impl Button {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the position of the keybinding relative to the button label.
|
||||||
|
///
|
||||||
|
/// This method allows you to specify where the keybinding should be displayed
|
||||||
|
/// in relation to the button's label.
|
||||||
|
pub fn key_binding_position(mut self, position: KeybindingPosition) -> Self {
|
||||||
|
self.keybinding_position = position;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets the alpha property of the color of label.
|
/// Sets the alpha property of the color of label.
|
||||||
pub fn alpha(mut self, alpha: f32) -> Self {
|
pub fn alpha(mut self, alpha: f32) -> Self {
|
||||||
self.alpha = Some(alpha);
|
self.alpha = Some(alpha);
|
||||||
@@ -412,6 +424,10 @@ impl RenderOnce for Button {
|
|||||||
})
|
})
|
||||||
.child(
|
.child(
|
||||||
h_flex()
|
h_flex()
|
||||||
|
.when(
|
||||||
|
self.keybinding_position == KeybindingPosition::Start,
|
||||||
|
|this| this.flex_row_reverse(),
|
||||||
|
)
|
||||||
.gap(DynamicSpacing::Base06.rems(cx))
|
.gap(DynamicSpacing::Base06.rems(cx))
|
||||||
.justify_between()
|
.justify_between()
|
||||||
.child(
|
.child(
|
||||||
|
|||||||
@@ -38,6 +38,13 @@ pub trait ButtonCommon: Clickable + Disableable {
|
|||||||
fn layer(self, elevation: ElevationIndex) -> Self;
|
fn layer(self, elevation: ElevationIndex) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
|
||||||
|
pub enum KeybindingPosition {
|
||||||
|
Start,
|
||||||
|
#[default]
|
||||||
|
End,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Default)]
|
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Default)]
|
||||||
pub enum IconPosition {
|
pub enum IconPosition {
|
||||||
#[default]
|
#[default]
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ pub enum IconSize {
|
|||||||
Medium,
|
Medium,
|
||||||
/// 48px
|
/// 48px
|
||||||
XLarge,
|
XLarge,
|
||||||
|
Custom(Pixels),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IconSize {
|
impl IconSize {
|
||||||
@@ -80,6 +81,7 @@ impl IconSize {
|
|||||||
IconSize::Small => rems_from_px(14.),
|
IconSize::Small => rems_from_px(14.),
|
||||||
IconSize::Medium => rems_from_px(16.),
|
IconSize::Medium => rems_from_px(16.),
|
||||||
IconSize::XLarge => rems_from_px(48.),
|
IconSize::XLarge => rems_from_px(48.),
|
||||||
|
IconSize::Custom(size) => rems_from_px(size.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,6 +98,8 @@ impl IconSize {
|
|||||||
IconSize::Small => DynamicSpacing::Base02.px(cx),
|
IconSize::Small => DynamicSpacing::Base02.px(cx),
|
||||||
IconSize::Medium => DynamicSpacing::Base02.px(cx),
|
IconSize::Medium => DynamicSpacing::Base02.px(cx),
|
||||||
IconSize::XLarge => DynamicSpacing::Base02.px(cx),
|
IconSize::XLarge => DynamicSpacing::Base02.px(cx),
|
||||||
|
// TODO: Wire into dynamic spacing
|
||||||
|
IconSize::Custom(size) => px(size.into()),
|
||||||
};
|
};
|
||||||
|
|
||||||
(icon_size, padding)
|
(icon_size, padding)
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ pub struct KeyBinding {
|
|||||||
|
|
||||||
/// The [`PlatformStyle`] to use when displaying this keybinding.
|
/// The [`PlatformStyle`] to use when displaying this keybinding.
|
||||||
platform_style: PlatformStyle,
|
platform_style: PlatformStyle,
|
||||||
|
size: Option<Pixels>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KeyBinding {
|
impl KeyBinding {
|
||||||
@@ -47,6 +48,7 @@ impl KeyBinding {
|
|||||||
Self {
|
Self {
|
||||||
key_binding,
|
key_binding,
|
||||||
platform_style: PlatformStyle::platform(),
|
platform_style: PlatformStyle::platform(),
|
||||||
|
size: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,6 +57,12 @@ impl KeyBinding {
|
|||||||
self.platform_style = platform_style;
|
self.platform_style = platform_style;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the size for this [`KeyBinding`].
|
||||||
|
pub fn size(mut self, size: Pixels) -> Self {
|
||||||
|
self.size = Some(size);
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RenderOnce for KeyBinding {
|
impl RenderOnce for KeyBinding {
|
||||||
@@ -83,9 +91,12 @@ impl RenderOnce for KeyBinding {
|
|||||||
&keystroke.modifiers,
|
&keystroke.modifiers,
|
||||||
self.platform_style,
|
self.platform_style,
|
||||||
None,
|
None,
|
||||||
|
self.size,
|
||||||
false,
|
false,
|
||||||
))
|
))
|
||||||
.map(|el| el.child(render_key(&keystroke, self.platform_style, None)))
|
.map(|el| {
|
||||||
|
el.child(render_key(&keystroke, self.platform_style, None, self.size))
|
||||||
|
})
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -94,11 +105,14 @@ pub fn render_key(
|
|||||||
keystroke: &Keystroke,
|
keystroke: &Keystroke,
|
||||||
platform_style: PlatformStyle,
|
platform_style: PlatformStyle,
|
||||||
color: Option<Color>,
|
color: Option<Color>,
|
||||||
|
size: Option<Pixels>,
|
||||||
) -> AnyElement {
|
) -> AnyElement {
|
||||||
let key_icon = icon_for_key(keystroke, platform_style);
|
let key_icon = icon_for_key(keystroke, platform_style);
|
||||||
match key_icon {
|
match key_icon {
|
||||||
Some(icon) => KeyIcon::new(icon, color).into_any_element(),
|
Some(icon) => KeyIcon::new(icon, color).size(size).into_any_element(),
|
||||||
None => Key::new(capitalize(&keystroke.key), color).into_any_element(),
|
None => Key::new(capitalize(&keystroke.key), color)
|
||||||
|
.size(size)
|
||||||
|
.into_any_element(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,6 +144,7 @@ pub fn render_modifiers(
|
|||||||
modifiers: &Modifiers,
|
modifiers: &Modifiers,
|
||||||
platform_style: PlatformStyle,
|
platform_style: PlatformStyle,
|
||||||
color: Option<Color>,
|
color: Option<Color>,
|
||||||
|
size: Option<Pixels>,
|
||||||
standalone: bool,
|
standalone: bool,
|
||||||
) -> impl Iterator<Item = AnyElement> {
|
) -> impl Iterator<Item = AnyElement> {
|
||||||
enum KeyOrIcon {
|
enum KeyOrIcon {
|
||||||
@@ -200,8 +215,8 @@ pub fn render_modifiers(
|
|||||||
PlatformStyle::Windows => vec![modifier.windows, KeyOrIcon::Key("+")],
|
PlatformStyle::Windows => vec![modifier.windows, KeyOrIcon::Key("+")],
|
||||||
})
|
})
|
||||||
.map(move |key_or_icon| match key_or_icon {
|
.map(move |key_or_icon| match key_or_icon {
|
||||||
KeyOrIcon::Key(key) => Key::new(key, color).into_any_element(),
|
KeyOrIcon::Key(key) => Key::new(key, color).size(size).into_any_element(),
|
||||||
KeyOrIcon::Icon(icon) => KeyIcon::new(icon, color).into_any_element(),
|
KeyOrIcon::Icon(icon) => KeyIcon::new(icon, color).size(size).into_any_element(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,26 +224,26 @@ pub fn render_modifiers(
|
|||||||
pub struct Key {
|
pub struct Key {
|
||||||
key: SharedString,
|
key: SharedString,
|
||||||
color: Option<Color>,
|
color: Option<Color>,
|
||||||
|
size: Option<Pixels>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RenderOnce for Key {
|
impl RenderOnce for Key {
|
||||||
fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
|
fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
|
||||||
let single_char = self.key.len() == 1;
|
let single_char = self.key.len() == 1;
|
||||||
|
let size = self.size.unwrap_or(px(14.));
|
||||||
|
let size_f32: f32 = size.into();
|
||||||
|
|
||||||
div()
|
div()
|
||||||
.py_0()
|
.py_0()
|
||||||
.map(|this| {
|
.map(|this| {
|
||||||
if single_char {
|
if single_char {
|
||||||
this.w(rems_from_px(14.))
|
this.w(size).flex().flex_none().justify_center()
|
||||||
.flex()
|
|
||||||
.flex_none()
|
|
||||||
.justify_center()
|
|
||||||
} else {
|
} else {
|
||||||
this.px_0p5()
|
this.px_0p5()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.h(rems_from_px(14.))
|
.h(rems_from_px(size_f32))
|
||||||
.text_ui(cx)
|
.text_size(size)
|
||||||
.line_height(relative(1.))
|
.line_height(relative(1.))
|
||||||
.text_color(self.color.unwrap_or(Color::Muted).color(cx))
|
.text_color(self.color.unwrap_or(Color::Muted).color(cx))
|
||||||
.child(self.key.clone())
|
.child(self.key.clone())
|
||||||
@@ -240,27 +255,47 @@ impl Key {
|
|||||||
Self {
|
Self {
|
||||||
key: key.into(),
|
key: key.into(),
|
||||||
color,
|
color,
|
||||||
|
size: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn size(mut self, size: impl Into<Option<Pixels>>) -> Self {
|
||||||
|
self.size = size.into();
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(IntoElement)]
|
#[derive(IntoElement)]
|
||||||
pub struct KeyIcon {
|
pub struct KeyIcon {
|
||||||
icon: IconName,
|
icon: IconName,
|
||||||
color: Option<Color>,
|
color: Option<Color>,
|
||||||
|
size: Option<Pixels>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RenderOnce for KeyIcon {
|
impl RenderOnce for KeyIcon {
|
||||||
fn render(self, _window: &mut Window, _cx: &mut App) -> impl IntoElement {
|
fn render(self, window: &mut Window, _cx: &mut App) -> impl IntoElement {
|
||||||
|
let size = self
|
||||||
|
.size
|
||||||
|
.unwrap_or(IconSize::Small.rems().to_pixels(window.rem_size()));
|
||||||
|
|
||||||
Icon::new(self.icon)
|
Icon::new(self.icon)
|
||||||
.size(IconSize::XSmall)
|
.size(IconSize::Custom(size))
|
||||||
.color(self.color.unwrap_or(Color::Muted))
|
.color(self.color.unwrap_or(Color::Muted))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KeyIcon {
|
impl KeyIcon {
|
||||||
pub fn new(icon: IconName, color: Option<Color>) -> Self {
|
pub fn new(icon: IconName, color: Option<Color>) -> Self {
|
||||||
Self { icon, color }
|
Self {
|
||||||
|
icon,
|
||||||
|
color,
|
||||||
|
size: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn size(mut self, size: impl Into<Option<Pixels>>) -> Self {
|
||||||
|
self.size = size.into();
|
||||||
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
307
crates/ui/src/components/keybinding_hint.rs
Normal file
307
crates/ui/src/components/keybinding_hint.rs
Normal file
@@ -0,0 +1,307 @@
|
|||||||
|
use crate::{h_flex, prelude::*};
|
||||||
|
use crate::{ElevationIndex, KeyBinding};
|
||||||
|
use gpui::{point, App, BoxShadow, IntoElement, Window};
|
||||||
|
use smallvec::smallvec;
|
||||||
|
|
||||||
|
/// Represents a hint for a keybinding, optionally with a prefix and suffix.
|
||||||
|
///
|
||||||
|
/// This struct allows for the creation and customization of a keybinding hint,
|
||||||
|
/// which can be used to display keyboard shortcuts or commands in a user interface.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use ui::prelude::*;
|
||||||
|
///
|
||||||
|
/// let hint = KeybindingHint::new(KeyBinding::from_str("Ctrl+S"))
|
||||||
|
/// .prefix("Save:")
|
||||||
|
/// .size(Pixels::from(14.0));
|
||||||
|
/// ```
|
||||||
|
#[derive(Debug, IntoElement, Clone)]
|
||||||
|
pub struct KeybindingHint {
|
||||||
|
prefix: Option<SharedString>,
|
||||||
|
suffix: Option<SharedString>,
|
||||||
|
keybinding: KeyBinding,
|
||||||
|
size: Option<Pixels>,
|
||||||
|
elevation: Option<ElevationIndex>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl KeybindingHint {
|
||||||
|
/// Creates a new `KeybindingHint` with the specified keybinding.
|
||||||
|
///
|
||||||
|
/// This method initializes a new `KeybindingHint` instance with the given keybinding,
|
||||||
|
/// setting all other fields to their default values.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use ui::prelude::*;
|
||||||
|
///
|
||||||
|
/// let hint = KeybindingHint::new(KeyBinding::from_str("Ctrl+C"));
|
||||||
|
/// ```
|
||||||
|
pub fn new(keybinding: KeyBinding) -> Self {
|
||||||
|
Self {
|
||||||
|
prefix: None,
|
||||||
|
suffix: None,
|
||||||
|
keybinding,
|
||||||
|
size: None,
|
||||||
|
elevation: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a new `KeybindingHint` with a prefix and keybinding.
|
||||||
|
///
|
||||||
|
/// This method initializes a new `KeybindingHint` instance with the given prefix and keybinding,
|
||||||
|
/// setting all other fields to their default values.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use ui::prelude::*;
|
||||||
|
///
|
||||||
|
/// let hint = KeybindingHint::with_prefix("Copy:", KeyBinding::from_str("Ctrl+C"));
|
||||||
|
/// ```
|
||||||
|
pub fn with_prefix(prefix: impl Into<SharedString>, keybinding: KeyBinding) -> Self {
|
||||||
|
Self {
|
||||||
|
prefix: Some(prefix.into()),
|
||||||
|
suffix: None,
|
||||||
|
keybinding,
|
||||||
|
size: None,
|
||||||
|
elevation: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a new `KeybindingHint` with a keybinding and suffix.
|
||||||
|
///
|
||||||
|
/// This method initializes a new `KeybindingHint` instance with the given keybinding and suffix,
|
||||||
|
/// setting all other fields to their default values.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use ui::prelude::*;
|
||||||
|
///
|
||||||
|
/// let hint = KeybindingHint::with_suffix(KeyBinding::from_str("Ctrl+V"), "Paste");
|
||||||
|
/// ```
|
||||||
|
pub fn with_suffix(keybinding: KeyBinding, suffix: impl Into<SharedString>) -> Self {
|
||||||
|
Self {
|
||||||
|
prefix: None,
|
||||||
|
suffix: Some(suffix.into()),
|
||||||
|
keybinding,
|
||||||
|
size: None,
|
||||||
|
elevation: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the prefix for the keybinding hint.
|
||||||
|
///
|
||||||
|
/// This method allows adding or changing the prefix text that appears before the keybinding.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use ui::prelude::*;
|
||||||
|
///
|
||||||
|
/// let hint = KeybindingHint::new(KeyBinding::from_str("Ctrl+X"))
|
||||||
|
/// .prefix("Cut:");
|
||||||
|
/// ```
|
||||||
|
pub fn prefix(mut self, prefix: impl Into<SharedString>) -> Self {
|
||||||
|
self.prefix = Some(prefix.into());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the suffix for the keybinding hint.
|
||||||
|
///
|
||||||
|
/// This method allows adding or changing the suffix text that appears after the keybinding.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use ui::prelude::*;
|
||||||
|
///
|
||||||
|
/// let hint = KeybindingHint::new(KeyBinding::from_str("Ctrl+F"))
|
||||||
|
/// .suffix("Find");
|
||||||
|
/// ```
|
||||||
|
pub fn suffix(mut self, suffix: impl Into<SharedString>) -> Self {
|
||||||
|
self.suffix = Some(suffix.into());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the size of the keybinding hint.
|
||||||
|
///
|
||||||
|
/// This method allows specifying the size of the keybinding hint in pixels.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use ui::prelude::*;
|
||||||
|
///
|
||||||
|
/// let hint = KeybindingHint::new(KeyBinding::from_str("Ctrl+Z"))
|
||||||
|
/// .size(Pixels::from(16.0));
|
||||||
|
/// ```
|
||||||
|
pub fn size(mut self, size: impl Into<Option<Pixels>>) -> Self {
|
||||||
|
self.size = size.into();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the elevation of the keybinding hint.
|
||||||
|
///
|
||||||
|
/// This method allows specifying the elevation index for the keybinding hint,
|
||||||
|
/// which affects its visual appearance in terms of depth or layering.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use ui::prelude::*;
|
||||||
|
///
|
||||||
|
/// let hint = KeybindingHint::new(KeyBinding::from_str("Ctrl+A"))
|
||||||
|
/// .elevation(ElevationIndex::new(1));
|
||||||
|
/// ```
|
||||||
|
pub fn elevation(mut self, elevation: impl Into<Option<ElevationIndex>>) -> Self {
|
||||||
|
self.elevation = elevation.into();
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RenderOnce for KeybindingHint {
|
||||||
|
fn render(self, window: &mut Window, cx: &mut App) -> impl IntoElement {
|
||||||
|
let colors = cx.theme().colors().clone();
|
||||||
|
|
||||||
|
let size = self
|
||||||
|
.size
|
||||||
|
.unwrap_or(TextSize::XSmall.rems(cx).to_pixels(window.rem_size()));
|
||||||
|
let kb_size = size - px(2.0);
|
||||||
|
let kb_bg = if let Some(elevation) = self.elevation {
|
||||||
|
elevation.on_elevation_bg(cx)
|
||||||
|
} else {
|
||||||
|
theme::color_alpha(colors.element_background, 0.6)
|
||||||
|
};
|
||||||
|
|
||||||
|
h_flex()
|
||||||
|
.items_center()
|
||||||
|
.gap_0p5()
|
||||||
|
.font_buffer(cx)
|
||||||
|
.text_size(size)
|
||||||
|
.text_color(colors.text_muted)
|
||||||
|
.children(self.prefix)
|
||||||
|
.child(
|
||||||
|
h_flex()
|
||||||
|
.items_center()
|
||||||
|
.rounded_md()
|
||||||
|
.px_0p5()
|
||||||
|
.mr_0p5()
|
||||||
|
.border_1()
|
||||||
|
.border_color(kb_bg)
|
||||||
|
.bg(kb_bg.opacity(0.8))
|
||||||
|
.shadow(smallvec![BoxShadow {
|
||||||
|
color: cx.theme().colors().editor_background.opacity(0.8),
|
||||||
|
offset: point(px(0.), px(1.)),
|
||||||
|
blur_radius: px(0.),
|
||||||
|
spread_radius: px(0.),
|
||||||
|
}])
|
||||||
|
.child(self.keybinding.size(kb_size)),
|
||||||
|
)
|
||||||
|
.children(self.suffix)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ComponentPreview for KeybindingHint {
|
||||||
|
fn description() -> impl Into<Option<&'static str>> {
|
||||||
|
"Used to display hint text for keyboard shortcuts. Can have a prefix and suffix."
|
||||||
|
}
|
||||||
|
|
||||||
|
fn examples(window: &mut Window, _cx: &mut App) -> Vec<ComponentExampleGroup<Self>> {
|
||||||
|
let home_fallback = gpui::KeyBinding::new("home", menu::SelectFirst, None);
|
||||||
|
let home = KeyBinding::for_action(&menu::SelectFirst, window)
|
||||||
|
.unwrap_or(KeyBinding::new(home_fallback));
|
||||||
|
|
||||||
|
let end_fallback = gpui::KeyBinding::new("end", menu::SelectLast, None);
|
||||||
|
let end = KeyBinding::for_action(&menu::SelectLast, window)
|
||||||
|
.unwrap_or(KeyBinding::new(end_fallback));
|
||||||
|
|
||||||
|
let enter_fallback = gpui::KeyBinding::new("enter", menu::Confirm, None);
|
||||||
|
let enter = KeyBinding::for_action(&menu::Confirm, window)
|
||||||
|
.unwrap_or(KeyBinding::new(enter_fallback));
|
||||||
|
|
||||||
|
let escape_fallback = gpui::KeyBinding::new("escape", menu::Cancel, None);
|
||||||
|
let escape = KeyBinding::for_action(&menu::Cancel, window)
|
||||||
|
.unwrap_or(KeyBinding::new(escape_fallback));
|
||||||
|
|
||||||
|
vec![
|
||||||
|
example_group_with_title(
|
||||||
|
"Basic",
|
||||||
|
vec![
|
||||||
|
single_example(
|
||||||
|
"With Prefix",
|
||||||
|
KeybindingHint::with_prefix("Go to Start:", home.clone()),
|
||||||
|
),
|
||||||
|
single_example(
|
||||||
|
"With Suffix",
|
||||||
|
KeybindingHint::with_suffix(end.clone(), "Go to End"),
|
||||||
|
),
|
||||||
|
single_example(
|
||||||
|
"With Prefix and Suffix",
|
||||||
|
KeybindingHint::new(enter.clone())
|
||||||
|
.prefix("Confirm:")
|
||||||
|
.suffix("Execute selected action"),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
example_group_with_title(
|
||||||
|
"Sizes",
|
||||||
|
vec![
|
||||||
|
single_example(
|
||||||
|
"Small",
|
||||||
|
KeybindingHint::new(home.clone())
|
||||||
|
.size(Pixels::from(12.0))
|
||||||
|
.prefix("Small:"),
|
||||||
|
),
|
||||||
|
single_example(
|
||||||
|
"Medium",
|
||||||
|
KeybindingHint::new(end.clone())
|
||||||
|
.size(Pixels::from(16.0))
|
||||||
|
.suffix("Medium"),
|
||||||
|
),
|
||||||
|
single_example(
|
||||||
|
"Large",
|
||||||
|
KeybindingHint::new(enter.clone())
|
||||||
|
.size(Pixels::from(20.0))
|
||||||
|
.prefix("Large:")
|
||||||
|
.suffix("Size"),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
example_group_with_title(
|
||||||
|
"Elevations",
|
||||||
|
vec![
|
||||||
|
single_example(
|
||||||
|
"Surface",
|
||||||
|
KeybindingHint::new(home.clone())
|
||||||
|
.elevation(ElevationIndex::Surface)
|
||||||
|
.prefix("Surface:"),
|
||||||
|
),
|
||||||
|
single_example(
|
||||||
|
"Elevated Surface",
|
||||||
|
KeybindingHint::new(end.clone())
|
||||||
|
.elevation(ElevationIndex::ElevatedSurface)
|
||||||
|
.suffix("Elevated"),
|
||||||
|
),
|
||||||
|
single_example(
|
||||||
|
"Editor Surface",
|
||||||
|
KeybindingHint::new(enter.clone())
|
||||||
|
.elevation(ElevationIndex::EditorSurface)
|
||||||
|
.prefix("Editor:")
|
||||||
|
.suffix("Surface"),
|
||||||
|
),
|
||||||
|
single_example(
|
||||||
|
"Modal Surface",
|
||||||
|
KeybindingHint::new(escape.clone())
|
||||||
|
.elevation(ElevationIndex::ModalSurface)
|
||||||
|
.prefix("Modal:")
|
||||||
|
.suffix("Escape"),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,7 +6,7 @@ use ui::{
|
|||||||
element_cell, prelude::*, string_cell, utils::calculate_contrast_ratio, AudioStatus,
|
element_cell, prelude::*, string_cell, utils::calculate_contrast_ratio, AudioStatus,
|
||||||
Availability, Avatar, AvatarAudioStatusIndicator, AvatarAvailabilityIndicator, ButtonLike,
|
Availability, Avatar, AvatarAudioStatusIndicator, AvatarAvailabilityIndicator, ButtonLike,
|
||||||
Checkbox, CheckboxWithLabel, ContentGroup, DecoratedIcon, ElevationIndex, Facepile,
|
Checkbox, CheckboxWithLabel, ContentGroup, DecoratedIcon, ElevationIndex, Facepile,
|
||||||
IconDecoration, Indicator, Switch, Table, TintColor, Tooltip,
|
IconDecoration, Indicator, KeybindingHint, Switch, Table, TintColor, Tooltip,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{Item, Workspace};
|
use crate::{Item, Workspace};
|
||||||
@@ -403,6 +403,7 @@ impl ThemePreview {
|
|||||||
.child(Button::render_component_previews(window, cx))
|
.child(Button::render_component_previews(window, cx))
|
||||||
.child(Checkbox::render_component_previews(window, cx))
|
.child(Checkbox::render_component_previews(window, cx))
|
||||||
.child(CheckboxWithLabel::render_component_previews(window, cx))
|
.child(CheckboxWithLabel::render_component_previews(window, cx))
|
||||||
|
.child(KeybindingHint::render_component_previews(window, cx))
|
||||||
.child(ContentGroup::render_component_previews(window, cx))
|
.child(ContentGroup::render_component_previews(window, cx))
|
||||||
.child(DecoratedIcon::render_component_previews(window, cx))
|
.child(DecoratedIcon::render_component_previews(window, cx))
|
||||||
.child(Facepile::render_component_previews(window, cx))
|
.child(Facepile::render_component_previews(window, cx))
|
||||||
|
|||||||
@@ -95,7 +95,8 @@ use ui::prelude::*;
|
|||||||
use util::{paths::SanitizedPath, serde::default_true, ResultExt, TryFutureExt};
|
use util::{paths::SanitizedPath, serde::default_true, ResultExt, TryFutureExt};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
pub use workspace_settings::{
|
pub use workspace_settings::{
|
||||||
AutosaveSetting, RestoreOnStartupBehavior, TabBarSettings, WorkspaceSettings,
|
AutosaveSetting, OpenRecentProjectBehavior, RestoreOnStartupBehavior, TabBarSettings,
|
||||||
|
WorkspaceSettings,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::notifications::NotificationId;
|
use crate::notifications::NotificationId;
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ pub struct WorkspaceSettings {
|
|||||||
pub show_call_status_icon: bool,
|
pub show_call_status_icon: bool,
|
||||||
pub autosave: AutosaveSetting,
|
pub autosave: AutosaveSetting,
|
||||||
pub restore_on_startup: RestoreOnStartupBehavior,
|
pub restore_on_startup: RestoreOnStartupBehavior,
|
||||||
|
pub open_recent_project: OpenRecentProjectBehavior,
|
||||||
pub drop_target_size: f32,
|
pub drop_target_size: f32,
|
||||||
pub when_closing_with_no_tabs: CloseWindowWhenNoItems,
|
pub when_closing_with_no_tabs: CloseWindowWhenNoItems,
|
||||||
pub use_system_path_prompts: bool,
|
pub use_system_path_prompts: bool,
|
||||||
@@ -83,6 +84,19 @@ pub enum RestoreOnStartupBehavior {
|
|||||||
LastSession,
|
LastSession,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Default, Serialize, Deserialize, JsonSchema)]
|
||||||
|
#[serde(rename_all = "snake_case")]
|
||||||
|
pub enum OpenRecentProjectBehavior {
|
||||||
|
/// Swap the current project with the selected recent project, reusing the
|
||||||
|
/// current window. If the project is already open in another window, focus
|
||||||
|
/// that window instead.
|
||||||
|
SwapProjects,
|
||||||
|
/// Open the selected recent project in a new window. If the project is
|
||||||
|
/// already open in another window, focus that window instead.
|
||||||
|
#[default]
|
||||||
|
OpenInNewWindow,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema)]
|
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema)]
|
||||||
pub struct WorkspaceSettingsContent {
|
pub struct WorkspaceSettingsContent {
|
||||||
/// Active pane styling settings.
|
/// Active pane styling settings.
|
||||||
@@ -113,6 +127,14 @@ pub struct WorkspaceSettingsContent {
|
|||||||
/// Values: none, last_workspace, last_session
|
/// Values: none, last_workspace, last_session
|
||||||
/// Default: last_session
|
/// Default: last_session
|
||||||
pub restore_on_startup: Option<RestoreOnStartupBehavior>,
|
pub restore_on_startup: Option<RestoreOnStartupBehavior>,
|
||||||
|
/// Whether to reuse the current window when opening a recent project
|
||||||
|
/// or create a new window.
|
||||||
|
///
|
||||||
|
/// If the project is already open in another window, that window will be
|
||||||
|
/// focused, regardless of this setting.
|
||||||
|
///
|
||||||
|
/// Default: false
|
||||||
|
pub open_recent_project: Option<OpenRecentProjectBehavior>,
|
||||||
/// The size of the workspace split drop targets on the outer edges.
|
/// The size of the workspace split drop targets on the outer edges.
|
||||||
/// Given as a fraction that will be multiplied by the smaller dimension of the workspace.
|
/// Given as a fraction that will be multiplied by the smaller dimension of the workspace.
|
||||||
///
|
///
|
||||||
|
|||||||
Reference in New Issue
Block a user