feat(workspace): add option for moving the tab close button to the left

This commit is contained in:
Alex Viscreanu 2023-07-17 21:17:04 +02:00
parent 6793d4b6b8
commit 4efcf492ee
No known key found for this signature in database
4 changed files with 107 additions and 72 deletions

View file

@ -128,9 +128,12 @@
// 4. Save when idle for a certain amount of time: // 4. Save when idle for a certain amount of time:
// "autosave": { "after_delay": {"milliseconds": 500} }, // "autosave": { "after_delay": {"milliseconds": 500} },
"autosave": "off", "autosave": "off",
// Color tab titles based on the git status of the buffer. // Settings related to the editor's tabs
"tabs": { "tabs": {
"git_status": false // Show git status colors in the editor tabs.
"git_status": false,
// Position of the close button on the editor tabs.
"close_position": "right"
}, },
// Whether or not to remove any trailing whitespace from lines of a buffer // Whether or not to remove any trailing whitespace from lines of a buffer
// before saving it. // before saving it.

View file

@ -723,12 +723,12 @@ pub struct Scrollbar {
pub thumb: ContainerStyle, pub thumb: ContainerStyle,
pub width: f32, pub width: f32,
pub min_height_factor: f32, pub min_height_factor: f32,
pub git: FileGitDiffColors, pub git: BufferGitDiffColors,
pub selections: Color, pub selections: Color,
} }
#[derive(Clone, Deserialize, Default, JsonSchema)] #[derive(Clone, Deserialize, Default, JsonSchema)]
pub struct FileGitDiffColors { pub struct BufferGitDiffColors {
pub inserted: Color, pub inserted: Color,
pub modified: Color, pub modified: Color,
pub deleted: Color, pub deleted: Color,

View file

@ -33,11 +33,30 @@ use theme::Theme;
#[derive(Deserialize)] #[derive(Deserialize)]
pub struct ItemSettings { pub struct ItemSettings {
pub git_status: bool, pub git_status: bool,
pub close_position: ClosePosition,
}
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "lowercase")]
pub enum ClosePosition {
Left,
#[default]
Right,
}
impl ClosePosition {
pub fn right(&self) -> bool {
match self {
ClosePosition::Left => false,
ClosePosition::Right => true,
}
}
} }
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema)] #[derive(Clone, Default, Serialize, Deserialize, JsonSchema)]
pub struct ItemSettingsContent { pub struct ItemSettingsContent {
git_status: Option<bool>, git_status: Option<bool>,
close_position: Option<ClosePosition>,
} }
impl Setting for ItemSettings { impl Setting for ItemSettings {

View file

@ -1370,81 +1370,94 @@ impl Pane {
container.border.left = false; container.border.left = false;
} }
Flex::row() let buffer_jewel_element = {
.with_child({ let diameter = 7.0;
let diameter = 7.0; let icon_color = if item.has_conflict(cx) {
let icon_color = if item.has_conflict(cx) { Some(tab_style.icon_conflict)
Some(tab_style.icon_conflict) } else if item.is_dirty(cx) {
} else if item.is_dirty(cx) { Some(tab_style.icon_dirty)
Some(tab_style.icon_dirty) } else {
} else { None
None };
};
Canvas::new(move |scene, bounds, _, _, _| { Canvas::new(move |scene, bounds, _, _, _| {
if let Some(color) = icon_color { if let Some(color) = icon_color {
let square = RectF::new(bounds.origin(), vec2f(diameter, diameter)); let square = RectF::new(bounds.origin(), vec2f(diameter, diameter));
scene.push_quad(Quad { scene.push_quad(Quad {
bounds: square, bounds: square,
background: Some(color), background: Some(color),
border: Default::default(), border: Default::default(),
corner_radius: diameter / 2., corner_radius: diameter / 2.,
}); });
} }
})
.constrained()
.with_width(diameter)
.with_height(diameter)
.aligned()
}) })
.with_child(title.aligned().contained().with_style(ContainerStyle { .constrained()
margin: Margin { .with_width(diameter)
left: tab_style.spacing, .with_height(diameter)
right: tab_style.spacing, .aligned()
..Default::default() };
},
let title_element = title.aligned().contained().with_style(ContainerStyle {
margin: Margin {
left: tab_style.spacing,
right: tab_style.spacing,
..Default::default() ..Default::default()
})) },
.with_child( ..Default::default()
if hovered { });
let item_id = item.id();
enum TabCloseButton {} let close_element = if hovered {
let icon = Svg::new("icons/x_mark_8.svg"); let item_id = item.id();
MouseEventHandler::<TabCloseButton, _>::new(item_id, cx, |mouse_state, _| { enum TabCloseButton {}
if mouse_state.hovered() { let icon = Svg::new("icons/x_mark_8.svg");
icon.with_color(tab_style.icon_close_active) MouseEventHandler::<TabCloseButton, _>::new(item_id, cx, |mouse_state, _| {
} else { if mouse_state.hovered() {
icon.with_color(tab_style.icon_close) icon.with_color(tab_style.icon_close_active)
} } else {
}) icon.with_color(tab_style.icon_close)
.with_padding(Padding::uniform(4.)) }
.with_cursor_style(CursorStyle::PointingHand) })
.on_click(MouseButton::Left, { .with_padding(Padding::uniform(4.))
let pane = pane.clone(); .with_cursor_style(CursorStyle::PointingHand)
move |_, _, cx| { .on_click(MouseButton::Left, {
let pane = pane.clone(); let pane = pane.clone();
cx.window_context().defer(move |cx| { move |_, _, cx| {
if let Some(pane) = pane.upgrade(cx) { let pane = pane.clone();
pane.update(cx, |pane, cx| { cx.window_context().defer(move |cx| {
pane.close_item_by_id(item_id, cx).detach_and_log_err(cx); if let Some(pane) = pane.upgrade(cx) {
}); pane.update(cx, |pane, cx| {
} pane.close_item_by_id(item_id, cx).detach_and_log_err(cx);
}); });
} }
}) });
.into_any_named("close-tab-icon")
.constrained()
} else {
Empty::new().constrained()
} }
.with_width(tab_style.close_icon_width) })
.aligned(), .into_any_named("close-tab-icon")
)
.contained()
.with_style(container)
.constrained() .constrained()
.with_height(tab_style.height) } else {
.into_any() Empty::new().constrained()
}
.with_width(tab_style.close_icon_width)
.aligned();
let close_right = settings::get::<ItemSettings>(cx).close_position.right();
if close_right {
Flex::row()
.with_child(buffer_jewel_element)
.with_child(title_element)
.with_child(close_element)
} else {
Flex::row()
.with_child(close_element)
.with_child(title_element)
.with_child(buffer_jewel_element)
}
.contained()
.with_style(container)
.constrained()
.with_height(tab_style.height)
.into_any()
} }
pub fn render_tab_bar_button< pub fn render_tab_bar_button<