workspace: Add settings to dim inactive panes and highlight active pane (#18968)

Closes #12529
Closes #8639

Release Notes:

- Added option to dim inactive panes
([#12529](https://github.com/zed-industries/zed/issues/12529))
- Added option to highlight active pane with a border
([#8639](https://github.com/zed-industries/zed/issues/8639))

BREAKING: `active_pane_magnification` value is no longer used, it should
be migrated to `active_pane_modifiers.magnification`


![panes](https://github.com/user-attachments/assets/b19959bc-4c06-4320-be36-412113143af5)

> note: don't know much rust, so I wouldn't be surprised if stuff can be
done much better, happy to update things after the review.
Also, wasn't sure about introducing the new object in the settings, but
it felt better than adding two more keys to the root, let me know what
you think and if there's a better way to do this. Also happy to get
feedback on the text itself, as I didn't spend much thinking how to
document this.
This commit is contained in:
Alex Viscreanu 2024-11-05 16:26:07 +01:00 committed by GitHub
parent b8501199c2
commit bc3550d991
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 108 additions and 18 deletions

View file

@ -68,9 +68,17 @@
"ui_font_size": 16,
// How much to fade out unused code.
"unnecessary_code_fade": 0.3,
// The factor to grow the active pane by. Defaults to 1.0
// which gives the same size as all other panes.
"active_pane_magnification": 1.0,
// Active pane styling settings.
"active_pane_modifiers": {
// The factor to grow the active pane by. Defaults to 1.0
// which gives the same size as all other panes.
"magnification": 1.0,
// Inset border size of the active pane, in pixels.
"border_size": 0.0,
// Opacity of the inactive panes. 0 means transparent, 1 means opaque.
// Values are clamped to the [0.0, 1.0] range.
"inactive_opacity": 1.0
},
// The direction that you want to split panes horizontally. Defaults to "up"
"pane_split_direction_horizontal": "up",
// The direction that you want to split panes horizontally. Defaults to "left"

View file

@ -867,12 +867,10 @@ mod element {
debug_assert!(flexes.len() == len);
debug_assert!(flex_values_in_bounds(flexes.as_slice()));
let magnification_value = WorkspaceSettings::get(None, cx).active_pane_magnification;
let active_pane_magnification = if magnification_value == 1. {
None
} else {
Some(magnification_value)
};
let active_pane_magnification = WorkspaceSettings::get(None, cx)
.active_pane_modifiers
.magnification
.and_then(|val| if val == 1.0 { None } else { Some(val) });
let total_flex = if let Some(flex) = active_pane_magnification {
self.children.len() as f32 - 1. + flex
@ -910,6 +908,7 @@ mod element {
origin,
size: child_size,
};
bounding_boxes.push(Some(child_bounds));
child.layout_as_root(child_size.into(), cx);
child.prepaint_at(origin, cx);
@ -944,7 +943,54 @@ mod element {
child.element.paint(cx);
}
let overlay_opacity = WorkspaceSettings::get(None, cx)
.active_pane_modifiers
.inactive_opacity
.map(|val| val.clamp(0.0, 1.0))
.and_then(|val| (val <= 1.).then_some(val));
let mut overlay_background = cx.theme().colors().editor_background;
if let Some(opacity) = overlay_opacity {
overlay_background.fade_out(opacity);
}
let overlay_border = WorkspaceSettings::get(None, cx)
.active_pane_modifiers
.border_size
.and_then(|val| (val >= 0.).then_some(val));
for (ix, child) in &mut layout.children.iter_mut().enumerate() {
if overlay_opacity.is_some() || overlay_border.is_some() {
// the overlay has to be painted in origin+1px with size width-1px
// in order to accommodate the divider between panels
let overlay_bounds = Bounds {
origin: child
.bounds
.origin
.apply_along(Axis::Horizontal, |val| val + Pixels(1.)),
size: child
.bounds
.size
.apply_along(Axis::Horizontal, |val| val - Pixels(1.)),
};
if overlay_opacity.is_some() && self.active_pane_ix != Some(ix) {
cx.paint_quad(gpui::fill(overlay_bounds, overlay_background));
}
if let Some(border) = overlay_border {
if self.active_pane_ix == Some(ix) {
cx.paint_quad(gpui::quad(
overlay_bounds,
0.,
gpui::transparent_black(),
border,
cx.theme().colors().border_selected,
));
}
}
}
if let Some(handle) = child.handle.as_mut() {
let cursor_style = match self.axis {
Axis::Vertical => CursorStyle::ResizeRow,

View file

@ -7,7 +7,7 @@ use settings::{Settings, SettingsSources};
#[derive(Deserialize)]
pub struct WorkspaceSettings {
pub active_pane_magnification: f32,
pub active_pane_modifiers: ActivePanelModifiers,
pub pane_split_direction_horizontal: PaneSplitDirectionHorizontal,
pub pane_split_direction_vertical: PaneSplitDirectionVertical,
pub centered_layout: CenteredLayoutSettings,
@ -21,6 +21,30 @@ pub struct WorkspaceSettings {
pub command_aliases: HashMap<String, String>,
}
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub struct ActivePanelModifiers {
/// Scale by which to zoom the active pane.
/// When set to 1.0, the active pane has the same size as others,
/// but when set to a larger value, the active pane takes up more space.
///
/// Default: `1.0`
pub magnification: Option<f32>,
/// Size of the border surrounding the active pane.
/// When set to 0, the active pane doesn't have any border.
/// The border is drawn inset.
///
/// Default: `0.0`
pub border_size: Option<f32>,
/// Opacity of inactive panels.
/// When set to 1.0, the inactive panes have the same opacity as the active one.
/// If set to 0, the inactive panes content will not be visible at all.
/// Values are clamped to the [0.0, 1.0] range.
///
/// Default: `1.0`
pub inactive_opacity: Option<f32>,
}
#[derive(Copy, Clone, Default, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum CloseWindowWhenNoItems {
@ -57,12 +81,8 @@ pub enum RestoreOnStartupBehavior {
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema)]
pub struct WorkspaceSettingsContent {
/// Scale by which to zoom the active pane.
/// When set to 1.0, the active pane has the same size as others,
/// but when set to a larger value, the active pane takes up more space.
///
/// Default: `1.0`
pub active_pane_magnification: Option<f32>,
/// Active pane styling settings.
pub active_pane_modifiers: Option<ActivePanelModifiers>,
// Direction to split horizontally.
//
// Default: "up"

View file

@ -29,10 +29,26 @@ Extensions that provide language servers may also provide default settings for t
# Settings
## Active Pane Magnification
## Active Pane Modifiers
Styling settings applied to the active pane.
### Magnification
- Description: Scale by which to zoom the active pane. When set to `1.0`, the active pane has the same size as others, but when set to a larger value, the active pane takes up more space.
- Setting: `active_pane_magnification`
- Setting: `magnification`
- Default: `1.0`
### Border size
- Description: Size of the border surrounding the active pane. When set to 0, the active pane doesn't have any border. The border is drawn inset.
- Setting: `border_size`
- Default: `0.0`
### Inactive Opacity
- Description: Opacity of inactive panels. When set to 1.0, the inactive panes have the same opacity as the active one. If set to 0, the inactive panes content will not be visible at all. Values are clamped to the [0.0, 1.0] range.
- Setting: `inactive_opacity`
- Default: `1.0`
**Options**