Detailed changes
@@ -43,6 +43,8 @@ where
state: UniformListState,
item_count: usize,
append_items: F,
+ padding_top: f32,
+ padding_bottom: f32,
}
impl<F> UniformList<F>
@@ -54,9 +56,21 @@ where
state,
item_count,
append_items,
+ padding_top: 0.,
+ padding_bottom: 0.,
}
}
+ pub fn with_padding_top(mut self, padding: f32) -> Self {
+ self.padding_top = padding;
+ self
+ }
+
+ pub fn with_padding_bottom(mut self, padding: f32) -> Self {
+ self.padding_bottom = padding;
+ self
+ }
+
fn scroll(
&self,
_: Vector2F,
@@ -84,7 +98,7 @@ where
}
if let Some(item_ix) = state.scroll_to.take() {
- let item_top = item_ix as f32 * item_height;
+ let item_top = self.padding_top + item_ix as f32 * item_height;
let item_bottom = item_top + item_height;
if item_top < state.scroll_top {
@@ -137,11 +151,16 @@ where
size.set_y(size.y().min(scroll_height).max(constraint.min.y()));
}
- scroll_max = (item_height * self.item_count as f32 - size.y()).max(0.);
+ let scroll_height =
+ item_height * self.item_count as f32 + self.padding_top + self.padding_bottom;
+ scroll_max = (scroll_height - size.y()).max(0.);
self.autoscroll(scroll_max, size.y(), item_height);
items.clear();
- let start = cmp::min((self.scroll_top() / item_height) as usize, self.item_count);
+ let start = cmp::min(
+ ((self.scroll_top() - self.padding_top) / item_height) as usize,
+ self.item_count,
+ );
let end = cmp::min(
self.item_count,
start + (size.y() / item_height).ceil() as usize + 1,
@@ -173,8 +192,11 @@ where
) -> Self::PaintState {
cx.scene.push_layer(Some(bounds));
- let mut item_origin =
- bounds.origin() - vec2f(0.0, self.state.scroll_top() % layout.item_height);
+ let mut item_origin = bounds.origin()
+ - vec2f(
+ 0.,
+ (self.state.scroll_top() - self.padding_top) % layout.item_height,
+ );
for item in &mut layout.items {
item.paint(item_origin, visible_bounds, cx);
@@ -18,6 +18,7 @@ padding = { right = 4 }
width = 16
[workspace.tab]
+height = 34
text = "$text.2"
padding = { left = 12, right = 12 }
icon_width = 8
@@ -26,10 +27,11 @@ icon_close = "$text.2.color"
icon_close_active = "$text.0.color"
icon_dirty = "$status.info"
icon_conflict = "$status.warn"
-border = { left = true, bottom = true, width = 1, color = "$border.0" }
+border = { left = true, bottom = true, width = 1, color = "$border.0", overlay = true }
[workspace.active_tab]
extends = "$workspace.tab"
+border.bottom = false
background = "$surface.1"
text = "$text.0"
@@ -41,13 +43,14 @@ border = { right = true, width = 1, color = "$border.0" }
padding = { left = 1 }
background = "$border.0"
-[workspace.sidebar.icon]
-color = "$text.2.color"
-height = 18
+[workspace.sidebar.item]
+icon_color = "$text.2.color"
+icon_size = 18
+height = "$workspace.tab.height"
-[workspace.sidebar.active_icon]
-extends = "$workspace.sidebar.icon"
-color = "$text.0.color"
+[workspace.sidebar.active_item]
+extends = "$workspace.sidebar.item"
+icon_color = "$text.0.color"
[workspace.left_sidebar]
extends = "$workspace.sidebar"
@@ -58,7 +61,7 @@ extends = "$workspace.sidebar"
border = { width = 1, color = "$border.0", left = true }
[panel]
-padding = 12
+padding = { top = 12, left = 12, bottom = 12, right = 12 }
[chat_panel]
extends = "$panel"
@@ -161,12 +164,11 @@ corner_radius = 6
[project_panel]
extends = "$panel"
-padding = 0
-entry_base_padding = "$panel.padding"
+padding.top = 6 # ($workspace.tab.height - $project_panel.entry.height) / 2
[project_panel.entry]
text = "$text.1"
-padding = { top = 3, bottom = 3 }
+height = 22
icon_color = "$text.3.color"
icon_size = 8
icon_spacing = 8
@@ -507,11 +507,15 @@ impl ProjectPanel {
Label::new(details.filename, style.text.clone())
.contained()
.with_margin_left(style.icon_spacing)
+ .aligned()
+ .left()
.boxed(),
)
+ .constrained()
+ .with_height(theme.entry.height)
.contained()
.with_style(style.container)
- .with_padding_left(theme.entry_base_padding + details.depth as f32 * 20.)
+ .with_padding_left(theme.container.padding.left + details.depth as f32 * 20.)
.boxed()
},
)
@@ -534,6 +538,8 @@ impl View for ProjectPanel {
fn render(&mut self, _: &mut gpui::RenderContext<'_, Self>) -> gpui::ElementBox {
let settings = self.settings.clone();
+ let mut container_style = settings.borrow().theme.project_panel.container;
+ let padding = std::mem::take(&mut container_style.padding);
let handle = self.handle.clone();
UniformList::new(
self.list.clone(),
@@ -551,8 +557,10 @@ impl View for ProjectPanel {
})
},
)
+ .with_padding_top(padding.top)
+ .with_padding_bottom(padding.bottom)
.contained()
- .with_style(self.settings.borrow().theme.project_panel.container)
+ .with_style(container_style)
.boxed()
}
@@ -67,6 +67,7 @@ pub struct OfflineIcon {
#[derive(Clone, Deserialize)]
pub struct Tab {
+ pub height: f32,
#[serde(flatten)]
pub container: ContainerStyle,
#[serde(flatten)]
@@ -84,14 +85,15 @@ pub struct Sidebar {
#[serde(flatten)]
pub container: ContainerStyle,
pub width: f32,
- pub icon: SidebarIcon,
- pub active_icon: SidebarIcon,
+ pub item: SidebarItem,
+ pub active_item: SidebarItem,
pub resize_handle: ContainerStyle,
}
#[derive(Deserialize)]
-pub struct SidebarIcon {
- pub color: Color,
+pub struct SidebarItem {
+ pub icon_color: Color,
+ pub icon_size: f32,
pub height: f32,
}
@@ -107,18 +109,18 @@ pub struct ChatPanel {
pub hovered_sign_in_prompt: TextStyle,
}
-#[derive(Deserialize)]
+#[derive(Debug, Deserialize)]
pub struct ProjectPanel {
#[serde(flatten)]
pub container: ContainerStyle,
- pub entry_base_padding: f32,
pub entry: ProjectPanelEntry,
pub hovered_entry: ProjectPanelEntry,
pub selected_entry: ProjectPanelEntry,
}
-#[derive(Deserialize)]
+#[derive(Debug, Deserialize)]
pub struct ProjectPanelEntry {
+ pub height: f32,
#[serde(flatten)]
pub container: ContainerStyle,
pub text: TextStyle,
@@ -2,12 +2,11 @@ use super::{ItemViewHandle, SplitDirection};
use crate::settings::Settings;
use gpui::{
action,
- color::Color,
elements::*,
geometry::{rect::RectF, vector::vec2f},
keymap::Binding,
platform::CursorStyle,
- Border, Entity, MutableAppContext, Quad, RenderContext, View, ViewContext, ViewHandle,
+ Entity, MutableAppContext, Quad, RenderContext, View, ViewContext, ViewHandle,
};
use postage::watch;
use std::{cmp, path::Path, sync::Arc};
@@ -180,10 +179,6 @@ impl Pane {
fn render_tabs(&self, cx: &mut RenderContext<Self>) -> ElementBox {
let settings = self.settings.borrow();
let theme = &settings.theme;
- let line_height = cx.font_cache().line_height(
- theme.workspace.tab.label.text.font_id,
- theme.workspace.tab.label.text.font_size,
- );
enum Tabs {}
let tabs = MouseEventHandler::new::<Tabs, _, _, _>(0, cx, |mouse_state, cx| {
@@ -202,12 +197,11 @@ impl Pane {
title.push('…');
}
- let mut style = theme.workspace.tab.clone();
- if is_active {
- style = theme.workspace.active_tab.clone();
- style.container.border.bottom = false;
- style.container.padding.bottom += style.container.border.width;
- }
+ let mut style = if is_active {
+ theme.workspace.active_tab.clone()
+ } else {
+ theme.workspace.tab.clone()
+ };
if ix == 0 {
style.container.border.left = false;
}
@@ -319,26 +313,11 @@ impl Pane {
})
}
- // Ensure there's always a minimum amount of space after the last tab,
- // so that the tab's border doesn't abut the window's border.
- let mut border = Border::bottom(1.0, Color::default());
- border.color = theme.workspace.tab.container.border.color;
-
- row.add_child(
- ConstrainedBox::new(
- Container::new(Empty::new().boxed())
- .with_border(border)
- .boxed(),
- )
- .with_min_width(20.)
- .named("fixed-filler"),
- );
-
row.add_child(
Expanded::new(
0.0,
Container::new(Empty::new().boxed())
- .with_border(border)
+ .with_border(theme.workspace.tab.container.border)
.boxed(),
)
.named("filler"),
@@ -348,7 +327,7 @@ impl Pane {
});
ConstrainedBox::new(tabs.boxed())
- .with_height(line_height + 16.)
+ .with_height(theme.workspace.tab.height)
.named("tabs")
}
}
@@ -68,11 +68,6 @@ impl Sidebar {
pub fn render(&self, settings: &Settings, cx: &mut RenderContext<Workspace>) -> ElementBox {
let side = self.side;
- let theme = &settings.theme;
- let line_height = cx.font_cache().line_height(
- theme.workspace.tab.label.text.font_id,
- theme.workspace.tab.label.text.font_size,
- );
let theme = self.theme(settings);
ConstrainedBox::new(
@@ -80,9 +75,9 @@ impl Sidebar {
Flex::column()
.with_children(self.items.iter().enumerate().map(|(item_index, item)| {
let theme = if Some(item_index) == self.active_item_ix {
- &theme.active_icon
+ &theme.active_item
} else {
- &theme.icon
+ &theme.item
};
enum SidebarButton {}
MouseEventHandler::new::<SidebarButton, _, _, _>(
@@ -93,15 +88,15 @@ impl Sidebar {
Align::new(
ConstrainedBox::new(
Svg::new(item.icon_path)
- .with_color(theme.color)
+ .with_color(theme.icon_color)
.boxed(),
)
- .with_height(theme.height)
+ .with_height(theme.icon_size)
.boxed(),
)
.boxed(),
)
- .with_height(line_height + 16.0)
+ .with_height(theme.height)
.boxed()
},
)