git_ui: Design Polish (#26361)
Polish PR - [ ] Horizontal scrollbar for git panel - [ ] Allow shift clicking a checkbox in any section to stage the whole section - [ ] Clean up design of no changes/pending push state in panel - [x] Ensure checkbox placeholder dot is centered in the checkbox - [x] Improve spacing between elements in git panel entries - [x] Update git branch icon to match branch selector text when disabled - [x] Truncate last commit message less aggressively in panel - [x] Clean up new panel header design - [x] Remove `_background` version control keys (backgrounds are derived from the foreground colors) ### Previous message truncation: Before:  After:  ### Make branch icon match when menu is disabled Before:  After:  Release Notes: - N/A *or* Added/Fixed/Improved ... --------- Co-authored-by: Cole Miller <cole@zed.dev> Co-authored-by: Cole Miller <m@cole-miller.net> Co-authored-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
This commit is contained in:
parent
63091459d8
commit
976fc3ee97
9 changed files with 180 additions and 156 deletions
|
@ -41,7 +41,8 @@ use language_model::{
|
||||||
use menu::{Confirm, SecondaryConfirm, SelectFirst, SelectLast, SelectNext, SelectPrevious};
|
use menu::{Confirm, SecondaryConfirm, SelectFirst, SelectLast, SelectNext, SelectPrevious};
|
||||||
use multi_buffer::ExcerptInfo;
|
use multi_buffer::ExcerptInfo;
|
||||||
use panel::{
|
use panel::{
|
||||||
panel_editor_container, panel_editor_style, panel_filled_button, panel_icon_button, PanelHeader,
|
panel_button, panel_editor_container, panel_editor_style, panel_filled_button,
|
||||||
|
panel_icon_button, PanelHeader,
|
||||||
};
|
};
|
||||||
use project::{
|
use project::{
|
||||||
git::{GitEvent, Repository},
|
git::{GitEvent, Repository},
|
||||||
|
@ -103,13 +104,13 @@ enum TrashCancel {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn git_panel_context_menu(
|
fn git_panel_context_menu(
|
||||||
focus_handle: Option<FocusHandle>,
|
focus_handle: FocusHandle,
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut App,
|
cx: &mut App,
|
||||||
) -> Entity<ContextMenu> {
|
) -> Entity<ContextMenu> {
|
||||||
ContextMenu::build(window, cx, |context_menu, _, _| {
|
ContextMenu::build(window, cx, |context_menu, _, _| {
|
||||||
context_menu
|
context_menu
|
||||||
.when_some(focus_handle, |el, focus_handle| el.context(focus_handle))
|
.context(focus_handle)
|
||||||
.action("Stage All", StageAll.boxed_clone())
|
.action("Stage All", StageAll.boxed_clone())
|
||||||
.action("Unstage All", UnstageAll.boxed_clone())
|
.action("Unstage All", UnstageAll.boxed_clone())
|
||||||
.separator()
|
.separator()
|
||||||
|
@ -2309,6 +2310,18 @@ impl GitPanel {
|
||||||
self.has_staged_changes()
|
self.has_staged_changes()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn render_overflow_menu(&self, id: impl Into<ElementId>) -> impl IntoElement {
|
||||||
|
let focus_handle = self.focus_handle.clone();
|
||||||
|
PopoverMenu::new(id.into())
|
||||||
|
.trigger(
|
||||||
|
IconButton::new("overflow-menu-trigger", IconName::EllipsisVertical)
|
||||||
|
.icon_size(IconSize::Small)
|
||||||
|
.icon_color(Color::Muted),
|
||||||
|
)
|
||||||
|
.menu(move |window, cx| Some(git_panel_context_menu(focus_handle.clone(), window, cx)))
|
||||||
|
.anchor(Corner::TopRight)
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn render_generate_commit_message_button(
|
pub(crate) fn render_generate_commit_message_button(
|
||||||
&self,
|
&self,
|
||||||
cx: &Context<Self>,
|
cx: &Context<Self>,
|
||||||
|
@ -2458,9 +2471,17 @@ impl GitPanel {
|
||||||
tooltip = "git add --all ."
|
tooltip = "git add --all ."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let change_string = match self.entry_count {
|
||||||
|
0 => "No Changes".to_string(),
|
||||||
|
1 => "1 Change".to_string(),
|
||||||
|
_ => format!("{} Changes", self.entry_count),
|
||||||
|
};
|
||||||
|
|
||||||
self.panel_header_container(window, cx)
|
self.panel_header_container(window, cx)
|
||||||
|
.px_2()
|
||||||
.child(
|
.child(
|
||||||
Button::new("diff", "Open Diff")
|
panel_button(change_string)
|
||||||
|
.color(Color::Muted)
|
||||||
.tooltip(Tooltip::for_action_title_in(
|
.tooltip(Tooltip::for_action_title_in(
|
||||||
"Open diff",
|
"Open diff",
|
||||||
&Diff,
|
&Diff,
|
||||||
|
@ -2473,8 +2494,9 @@ impl GitPanel {
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.child(div().flex_grow()) // spacer
|
.child(div().flex_grow()) // spacer
|
||||||
|
.child(self.render_overflow_menu("overflow_menu"))
|
||||||
.child(
|
.child(
|
||||||
Button::new("stage-unstage-all", text)
|
panel_filled_button(text)
|
||||||
.tooltip(Tooltip::for_action_title_in(
|
.tooltip(Tooltip::for_action_title_in(
|
||||||
tooltip,
|
tooltip,
|
||||||
action.as_ref(),
|
action.as_ref(),
|
||||||
|
@ -2631,15 +2653,14 @@ impl GitPanel {
|
||||||
.items_center()
|
.items_center()
|
||||||
.py_2()
|
.py_2()
|
||||||
.px(px(8.))
|
.px(px(8.))
|
||||||
// .bg(cx.theme().colors().background)
|
|
||||||
// .border_t_1()
|
|
||||||
.border_color(cx.theme().colors().border)
|
.border_color(cx.theme().colors().border)
|
||||||
.gap_1p5()
|
.gap_1p5()
|
||||||
.child(
|
.child(
|
||||||
div()
|
div()
|
||||||
.flex_grow()
|
.flex_grow()
|
||||||
.overflow_hidden()
|
.overflow_hidden()
|
||||||
.max_w(relative(0.6))
|
.items_center()
|
||||||
|
.max_w(relative(0.85))
|
||||||
.h_full()
|
.h_full()
|
||||||
.child(
|
.child(
|
||||||
Label::new(commit.subject.clone())
|
Label::new(commit.subject.clone())
|
||||||
|
@ -2946,7 +2967,7 @@ impl GitPanel {
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) {
|
) {
|
||||||
let context_menu = git_panel_context_menu(Some(self.focus_handle.clone()), window, cx);
|
let context_menu = git_panel_context_menu(self.focus_handle.clone(), window, cx);
|
||||||
self.set_context_menu(context_menu, position, window, cx);
|
self.set_context_menu(context_menu, position, window, cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2993,6 +3014,9 @@ impl GitPanel {
|
||||||
let marked = self.marked_entries.contains(&ix);
|
let marked = self.marked_entries.contains(&ix);
|
||||||
let status_style = GitPanelSettings::get_global(cx).status_style;
|
let status_style = GitPanelSettings::get_global(cx).status_style;
|
||||||
let status = entry.status;
|
let status = entry.status;
|
||||||
|
let modifiers = self.current_modifiers;
|
||||||
|
let shift_held = modifiers.shift;
|
||||||
|
|
||||||
let has_conflict = status.is_conflicted();
|
let has_conflict = status.is_conflicted();
|
||||||
let is_modified = status.is_modified();
|
let is_modified = status.is_modified();
|
||||||
let is_deleted = status.is_deleted();
|
let is_deleted = status.is_deleted();
|
||||||
|
@ -3078,7 +3102,7 @@ impl GitPanel {
|
||||||
.px(rems(0.75)) // ~12px
|
.px(rems(0.75)) // ~12px
|
||||||
.overflow_hidden()
|
.overflow_hidden()
|
||||||
.flex_none()
|
.flex_none()
|
||||||
.gap(DynamicSpacing::Base04.rems(cx))
|
.gap_1p5()
|
||||||
.bg(base_bg)
|
.bg(base_bg)
|
||||||
.hover(|this| this.bg(hover_bg))
|
.hover(|this| this.bg(hover_bg))
|
||||||
.active(|this| this.bg(active_bg))
|
.active(|this| this.bg(active_bg))
|
||||||
|
@ -3123,6 +3147,7 @@ impl GitPanel {
|
||||||
.flex_none()
|
.flex_none()
|
||||||
.occlude()
|
.occlude()
|
||||||
.cursor_pointer()
|
.cursor_pointer()
|
||||||
|
.ml_neg_0p5()
|
||||||
.child(
|
.child(
|
||||||
Checkbox::new(checkbox_id, is_staged)
|
Checkbox::new(checkbox_id, is_staged)
|
||||||
.disabled(!has_write_access)
|
.disabled(!has_write_access)
|
||||||
|
@ -3144,17 +3169,35 @@ impl GitPanel {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.tooltip(move |window, cx| {
|
.tooltip(move |window, cx| {
|
||||||
let tooltip_name = if entry_staging.is_fully_staged() {
|
let is_staged = entry_staging.is_fully_staged();
|
||||||
"Unstage"
|
|
||||||
|
let action = if is_staged { "Unstage" } else { "Stage" };
|
||||||
|
let tooltip_name = if shift_held {
|
||||||
|
format!("{} section", action)
|
||||||
} else {
|
} else {
|
||||||
"Stage"
|
action.to_string()
|
||||||
};
|
};
|
||||||
|
|
||||||
Tooltip::for_action(tooltip_name, &ToggleStaged, window, cx)
|
let meta = if shift_held {
|
||||||
|
format!(
|
||||||
|
"Release shift to {} single entry",
|
||||||
|
action.to_lowercase()
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
format!("Shift click to {} section", action.to_lowercase())
|
||||||
|
};
|
||||||
|
|
||||||
|
Tooltip::with_meta(
|
||||||
|
tooltip_name,
|
||||||
|
Some(&ToggleStaged),
|
||||||
|
meta,
|
||||||
|
window,
|
||||||
|
cx,
|
||||||
|
)
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.child(git_status_icon(status, cx))
|
.child(git_status_icon(status))
|
||||||
.child(
|
.child(
|
||||||
h_flex()
|
h_flex()
|
||||||
.items_center()
|
.items_center()
|
||||||
|
@ -3456,27 +3499,11 @@ impl PanelRepoFooter {
|
||||||
git_panel: None,
|
git_panel: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_overflow_menu(&self, id: impl Into<ElementId>, cx: &App) -> impl IntoElement {
|
|
||||||
let focus_handle = self
|
|
||||||
.git_panel
|
|
||||||
.as_ref()
|
|
||||||
.map(|git_panel| git_panel.focus_handle(cx));
|
|
||||||
PopoverMenu::new(id.into())
|
|
||||||
.trigger(
|
|
||||||
IconButton::new("overflow-menu-trigger", IconName::EllipsisVertical)
|
|
||||||
.icon_size(IconSize::Small)
|
|
||||||
.icon_color(Color::Muted),
|
|
||||||
)
|
|
||||||
.menu(move |window, cx| Some(git_panel_context_menu(focus_handle.clone(), window, cx)))
|
|
||||||
.anchor(Corner::TopRight)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RenderOnce for PanelRepoFooter {
|
impl RenderOnce for PanelRepoFooter {
|
||||||
fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
|
fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement {
|
||||||
let active_repo = self.active_repository.clone();
|
let active_repo = self.active_repository.clone();
|
||||||
let overflow_menu_id: SharedString = format!("overflow-menu-{}", active_repo).into();
|
|
||||||
let repo_selector_trigger = Button::new("repo-selector", active_repo)
|
let repo_selector_trigger = Button::new("repo-selector", active_repo)
|
||||||
.style(ButtonStyle::Transparent)
|
.style(ButtonStyle::Transparent)
|
||||||
.size(ButtonSize::None)
|
.size(ButtonSize::None)
|
||||||
|
@ -3565,7 +3592,11 @@ impl RenderOnce for PanelRepoFooter {
|
||||||
div().child(
|
div().child(
|
||||||
Icon::new(IconName::GitBranchSmall)
|
Icon::new(IconName::GitBranchSmall)
|
||||||
.size(IconSize::Small)
|
.size(IconSize::Small)
|
||||||
.color(Color::Muted),
|
.color(if single_repo {
|
||||||
|
Color::Disabled
|
||||||
|
} else {
|
||||||
|
Color::Muted
|
||||||
|
}),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.child(repo_selector)
|
.child(repo_selector)
|
||||||
|
@ -3584,7 +3615,6 @@ impl RenderOnce for PanelRepoFooter {
|
||||||
.gap_1()
|
.gap_1()
|
||||||
.flex_shrink_0()
|
.flex_shrink_0()
|
||||||
.children(spinner)
|
.children(spinner)
|
||||||
.child(self.render_overflow_menu(overflow_menu_id, cx))
|
|
||||||
.when_some(branch, |this, branch| {
|
.when_some(branch, |this, branch| {
|
||||||
let mut focus_handle = None;
|
let mut focus_handle = None;
|
||||||
if let Some(git_panel) = self.git_panel.as_ref() {
|
if let Some(git_panel) = self.git_panel.as_ref() {
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
use ::settings::Settings;
|
use ::settings::Settings;
|
||||||
use git::{
|
use git::{
|
||||||
repository::{Branch, Upstream, UpstreamTracking, UpstreamTrackingStatus},
|
repository::{Branch, Upstream, UpstreamTracking, UpstreamTrackingStatus},
|
||||||
status::FileStatus,
|
status::{FileStatus, StatusCode, UnmergedStatus, UnmergedStatusCode},
|
||||||
};
|
};
|
||||||
use git_panel_settings::GitPanelSettings;
|
use git_panel_settings::GitPanelSettings;
|
||||||
use gpui::{App, Entity, FocusHandle};
|
use gpui::{App, Entity, FocusHandle};
|
||||||
use project::Project;
|
use project::Project;
|
||||||
use project_diff::ProjectDiff;
|
use project_diff::ProjectDiff;
|
||||||
use ui::{ActiveTheme, Color, Icon, IconName, IntoElement, SharedString};
|
use ui::prelude::*;
|
||||||
use workspace::Workspace;
|
use workspace::Workspace;
|
||||||
|
|
||||||
mod askpass_modal;
|
mod askpass_modal;
|
||||||
|
@ -86,30 +86,8 @@ pub fn init(cx: &mut App) {
|
||||||
.detach();
|
.detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add updated status colors to theme
|
pub fn git_status_icon(status: FileStatus) -> impl IntoElement {
|
||||||
pub fn git_status_icon(status: FileStatus, cx: &App) -> impl IntoElement {
|
GitStatusIcon::new(status)
|
||||||
let (icon_name, color) = if status.is_conflicted() {
|
|
||||||
(
|
|
||||||
IconName::Warning,
|
|
||||||
cx.theme().colors().version_control_conflict,
|
|
||||||
)
|
|
||||||
} else if status.is_deleted() {
|
|
||||||
(
|
|
||||||
IconName::SquareMinus,
|
|
||||||
cx.theme().colors().version_control_deleted,
|
|
||||||
)
|
|
||||||
} else if status.is_modified() {
|
|
||||||
(
|
|
||||||
IconName::SquareDot,
|
|
||||||
cx.theme().colors().version_control_modified,
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
(
|
|
||||||
IconName::SquarePlus,
|
|
||||||
cx.theme().colors().version_control_added,
|
|
||||||
)
|
|
||||||
};
|
|
||||||
Icon::new(icon_name).color(Color::Custom(color))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn can_push_and_pull(project: &Entity<Project>, cx: &App) -> bool {
|
fn can_push_and_pull(project: &Entity<Project>, cx: &App) -> bool {
|
||||||
|
@ -465,3 +443,79 @@ mod remote_button {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(IntoElement, IntoComponent)]
|
||||||
|
#[component(scope = "Version Control")]
|
||||||
|
pub struct GitStatusIcon {
|
||||||
|
status: FileStatus,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GitStatusIcon {
|
||||||
|
pub fn new(status: FileStatus) -> Self {
|
||||||
|
Self { status }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RenderOnce for GitStatusIcon {
|
||||||
|
fn render(self, _window: &mut ui::Window, cx: &mut App) -> impl IntoElement {
|
||||||
|
let status = self.status;
|
||||||
|
|
||||||
|
let (icon_name, color) = if status.is_conflicted() {
|
||||||
|
(
|
||||||
|
IconName::Warning,
|
||||||
|
cx.theme().colors().version_control_conflict,
|
||||||
|
)
|
||||||
|
} else if status.is_deleted() {
|
||||||
|
(
|
||||||
|
IconName::SquareMinus,
|
||||||
|
cx.theme().colors().version_control_deleted,
|
||||||
|
)
|
||||||
|
} else if status.is_modified() {
|
||||||
|
(
|
||||||
|
IconName::SquareDot,
|
||||||
|
cx.theme().colors().version_control_modified,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
(
|
||||||
|
IconName::SquarePlus,
|
||||||
|
cx.theme().colors().version_control_added,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
Icon::new(icon_name).color(Color::Custom(color))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// View this component preview using `workspace: open component-preview`
|
||||||
|
impl ComponentPreview for GitStatusIcon {
|
||||||
|
fn preview(_window: &mut Window, _cx: &mut App) -> AnyElement {
|
||||||
|
fn tracked_file_status(code: StatusCode) -> FileStatus {
|
||||||
|
FileStatus::Tracked(git::status::TrackedStatus {
|
||||||
|
index_status: code,
|
||||||
|
worktree_status: code,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
let modified = tracked_file_status(StatusCode::Modified);
|
||||||
|
let added = tracked_file_status(StatusCode::Added);
|
||||||
|
let deleted = tracked_file_status(StatusCode::Deleted);
|
||||||
|
let conflict = UnmergedStatus {
|
||||||
|
first_head: UnmergedStatusCode::Updated,
|
||||||
|
second_head: UnmergedStatusCode::Updated,
|
||||||
|
}
|
||||||
|
.into();
|
||||||
|
|
||||||
|
v_flex()
|
||||||
|
.gap_6()
|
||||||
|
.children(vec![example_group(vec![
|
||||||
|
single_example("Modified", GitStatusIcon::new(modified).into_any_element()),
|
||||||
|
single_example("Added", GitStatusIcon::new(added).into_any_element()),
|
||||||
|
single_example("Deleted", GitStatusIcon::new(deleted).into_any_element()),
|
||||||
|
single_example(
|
||||||
|
"Conflicted",
|
||||||
|
GitStatusIcon::new(conflict).into_any_element(),
|
||||||
|
),
|
||||||
|
])])
|
||||||
|
.into_any_element()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -18,8 +18,6 @@ pub trait PanelHeader: workspace::Panel {
|
||||||
.w_full()
|
.w_full()
|
||||||
.px_1()
|
.px_1()
|
||||||
.flex_none()
|
.flex_none()
|
||||||
.border_b_1()
|
|
||||||
.border_color(cx.theme().colors().border)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -136,14 +136,10 @@ impl ThemeColors {
|
||||||
terminal_ansi_dim_white: neutral().light().step_11(),
|
terminal_ansi_dim_white: neutral().light().step_11(),
|
||||||
link_text_hover: orange().light().step_10(),
|
link_text_hover: orange().light().step_10(),
|
||||||
version_control_added: ADDED_COLOR,
|
version_control_added: ADDED_COLOR,
|
||||||
version_control_added_background: ADDED_COLOR.opacity(0.1),
|
|
||||||
version_control_deleted: REMOVED_COLOR,
|
version_control_deleted: REMOVED_COLOR,
|
||||||
version_control_deleted_background: REMOVED_COLOR.opacity(0.1),
|
|
||||||
version_control_modified: MODIFIED_COLOR,
|
version_control_modified: MODIFIED_COLOR,
|
||||||
version_control_modified_background: MODIFIED_COLOR.opacity(0.1),
|
|
||||||
version_control_renamed: MODIFIED_COLOR,
|
version_control_renamed: MODIFIED_COLOR,
|
||||||
version_control_conflict: orange().light().step_12(),
|
version_control_conflict: orange().light().step_12(),
|
||||||
version_control_conflict_background: orange().light().step_12().opacity(0.1),
|
|
||||||
version_control_ignored: gray().light().step_12(),
|
version_control_ignored: gray().light().step_12(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -253,14 +249,10 @@ impl ThemeColors {
|
||||||
terminal_ansi_dim_white: neutral().dark().step_10(),
|
terminal_ansi_dim_white: neutral().dark().step_10(),
|
||||||
link_text_hover: orange().dark().step_10(),
|
link_text_hover: orange().dark().step_10(),
|
||||||
version_control_added: ADDED_COLOR,
|
version_control_added: ADDED_COLOR,
|
||||||
version_control_added_background: ADDED_COLOR.opacity(0.1),
|
|
||||||
version_control_deleted: REMOVED_COLOR,
|
version_control_deleted: REMOVED_COLOR,
|
||||||
version_control_deleted_background: REMOVED_COLOR.opacity(0.1),
|
|
||||||
version_control_modified: MODIFIED_COLOR,
|
version_control_modified: MODIFIED_COLOR,
|
||||||
version_control_modified_background: MODIFIED_COLOR.opacity(0.1),
|
|
||||||
version_control_renamed: MODIFIED_COLOR,
|
version_control_renamed: MODIFIED_COLOR,
|
||||||
version_control_conflict: orange().dark().step_12(),
|
version_control_conflict: orange().dark().step_12(),
|
||||||
version_control_conflict_background: orange().dark().step_12().opacity(0.1),
|
|
||||||
version_control_ignored: gray().dark().step_12(),
|
version_control_ignored: gray().dark().step_12(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -190,14 +190,10 @@ pub(crate) fn zed_default_dark() -> Theme {
|
||||||
editor_foreground: hsla(218. / 360., 14. / 100., 71. / 100., 1.),
|
editor_foreground: hsla(218. / 360., 14. / 100., 71. / 100., 1.),
|
||||||
link_text_hover: blue,
|
link_text_hover: blue,
|
||||||
version_control_added: ADDED_COLOR,
|
version_control_added: ADDED_COLOR,
|
||||||
version_control_added_background: ADDED_COLOR.opacity(0.1),
|
|
||||||
version_control_deleted: REMOVED_COLOR,
|
version_control_deleted: REMOVED_COLOR,
|
||||||
version_control_deleted_background: REMOVED_COLOR.opacity(0.1),
|
|
||||||
version_control_modified: MODIFIED_COLOR,
|
version_control_modified: MODIFIED_COLOR,
|
||||||
version_control_modified_background: MODIFIED_COLOR.opacity(0.1),
|
|
||||||
version_control_renamed: MODIFIED_COLOR,
|
version_control_renamed: MODIFIED_COLOR,
|
||||||
version_control_conflict: crate::orange().light().step_12(),
|
version_control_conflict: crate::orange().light().step_12(),
|
||||||
version_control_conflict_background: crate::orange().light().step_12().opacity(0.1),
|
|
||||||
version_control_ignored: crate::gray().light().step_12(),
|
version_control_ignored: crate::gray().light().step_12(),
|
||||||
},
|
},
|
||||||
status: StatusColors {
|
status: StatusColors {
|
||||||
|
|
|
@ -557,26 +557,14 @@ pub struct ThemeColorsContent {
|
||||||
#[serde(rename = "version_control.added")]
|
#[serde(rename = "version_control.added")]
|
||||||
pub version_control_added: Option<String>,
|
pub version_control_added: Option<String>,
|
||||||
|
|
||||||
/// Added version control background color.
|
|
||||||
#[serde(rename = "version_control.added_background")]
|
|
||||||
pub version_control_added_background: Option<String>,
|
|
||||||
|
|
||||||
/// Deleted version control color.
|
/// Deleted version control color.
|
||||||
#[serde(rename = "version_control.deleted")]
|
#[serde(rename = "version_control.deleted")]
|
||||||
pub version_control_deleted: Option<String>,
|
pub version_control_deleted: Option<String>,
|
||||||
|
|
||||||
/// Deleted version control background color.
|
|
||||||
#[serde(rename = "version_control.deleted_background")]
|
|
||||||
pub version_control_deleted_background: Option<String>,
|
|
||||||
|
|
||||||
/// Modified version control color.
|
/// Modified version control color.
|
||||||
#[serde(rename = "version_control.modified")]
|
#[serde(rename = "version_control.modified")]
|
||||||
pub version_control_modified: Option<String>,
|
pub version_control_modified: Option<String>,
|
||||||
|
|
||||||
/// Modified version control background color.
|
|
||||||
#[serde(rename = "version_control.modified_background")]
|
|
||||||
pub version_control_modified_background: Option<String>,
|
|
||||||
|
|
||||||
/// Renamed version control color.
|
/// Renamed version control color.
|
||||||
#[serde(rename = "version_control.renamed")]
|
#[serde(rename = "version_control.renamed")]
|
||||||
pub version_control_renamed: Option<String>,
|
pub version_control_renamed: Option<String>,
|
||||||
|
@ -585,10 +573,6 @@ pub struct ThemeColorsContent {
|
||||||
#[serde(rename = "version_control.conflict")]
|
#[serde(rename = "version_control.conflict")]
|
||||||
pub version_control_conflict: Option<String>,
|
pub version_control_conflict: Option<String>,
|
||||||
|
|
||||||
/// Conflict version control background color.
|
|
||||||
#[serde(rename = "version_control.conflict_background")]
|
|
||||||
pub version_control_conflict_background: Option<String>,
|
|
||||||
|
|
||||||
/// Ignored version control color.
|
/// Ignored version control color.
|
||||||
#[serde(rename = "version_control.ignored")]
|
#[serde(rename = "version_control.ignored")]
|
||||||
pub version_control_ignored: Option<String>,
|
pub version_control_ignored: Option<String>,
|
||||||
|
@ -1000,26 +984,14 @@ impl ThemeColorsContent {
|
||||||
.version_control_added
|
.version_control_added
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|color| try_parse_color(color).ok()),
|
.and_then(|color| try_parse_color(color).ok()),
|
||||||
version_control_added_background: self
|
|
||||||
.version_control_added_background
|
|
||||||
.as_ref()
|
|
||||||
.and_then(|color| try_parse_color(color).ok()),
|
|
||||||
version_control_deleted: self
|
version_control_deleted: self
|
||||||
.version_control_deleted
|
.version_control_deleted
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|color| try_parse_color(color).ok()),
|
.and_then(|color| try_parse_color(color).ok()),
|
||||||
version_control_deleted_background: self
|
|
||||||
.version_control_deleted_background
|
|
||||||
.as_ref()
|
|
||||||
.and_then(|color| try_parse_color(color).ok()),
|
|
||||||
version_control_modified: self
|
version_control_modified: self
|
||||||
.version_control_modified
|
.version_control_modified
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|color| try_parse_color(color).ok()),
|
.and_then(|color| try_parse_color(color).ok()),
|
||||||
version_control_modified_background: self
|
|
||||||
.version_control_modified_background
|
|
||||||
.as_ref()
|
|
||||||
.and_then(|color| try_parse_color(color).ok()),
|
|
||||||
version_control_renamed: self
|
version_control_renamed: self
|
||||||
.version_control_renamed
|
.version_control_renamed
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
@ -1028,10 +1000,6 @@ impl ThemeColorsContent {
|
||||||
.version_control_conflict
|
.version_control_conflict
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|color| try_parse_color(color).ok()),
|
.and_then(|color| try_parse_color(color).ok()),
|
||||||
version_control_conflict_background: self
|
|
||||||
.version_control_conflict_background
|
|
||||||
.as_ref()
|
|
||||||
.and_then(|color| try_parse_color(color).ok()),
|
|
||||||
version_control_ignored: self
|
version_control_ignored: self
|
||||||
.version_control_ignored
|
.version_control_ignored
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
|
|
@ -246,22 +246,14 @@ pub struct ThemeColors {
|
||||||
|
|
||||||
/// Represents an added entry or hunk in vcs, like git.
|
/// Represents an added entry or hunk in vcs, like git.
|
||||||
pub version_control_added: Hsla,
|
pub version_control_added: Hsla,
|
||||||
/// Represents the line background of an added entry or hunk in vcs, like git.
|
|
||||||
pub version_control_added_background: Hsla,
|
|
||||||
/// Represents a deleted entry in version control systems.
|
/// Represents a deleted entry in version control systems.
|
||||||
pub version_control_deleted: Hsla,
|
pub version_control_deleted: Hsla,
|
||||||
/// Represents the background color for deleted entries in version control systems.
|
|
||||||
pub version_control_deleted_background: Hsla,
|
|
||||||
/// Represents a modified entry in version control systems.
|
/// Represents a modified entry in version control systems.
|
||||||
pub version_control_modified: Hsla,
|
pub version_control_modified: Hsla,
|
||||||
/// Represents the background color for modified entries in version control systems.
|
|
||||||
pub version_control_modified_background: Hsla,
|
|
||||||
/// Represents a renamed entry in version control systems.
|
/// Represents a renamed entry in version control systems.
|
||||||
pub version_control_renamed: Hsla,
|
pub version_control_renamed: Hsla,
|
||||||
/// Represents a conflicting entry in version control systems.
|
/// Represents a conflicting entry in version control systems.
|
||||||
pub version_control_conflict: Hsla,
|
pub version_control_conflict: Hsla,
|
||||||
/// Represents the background color for conflicting entries in version control systems.
|
|
||||||
pub version_control_conflict_background: Hsla,
|
|
||||||
/// Represents an ignored entry in version control systems.
|
/// Represents an ignored entry in version control systems.
|
||||||
pub version_control_ignored: Hsla,
|
pub version_control_ignored: Hsla,
|
||||||
}
|
}
|
||||||
|
@ -366,14 +358,10 @@ pub enum ThemeColorField {
|
||||||
TerminalAnsiDimWhite,
|
TerminalAnsiDimWhite,
|
||||||
LinkTextHover,
|
LinkTextHover,
|
||||||
VersionControlAdded,
|
VersionControlAdded,
|
||||||
VersionControlAddedBackground,
|
|
||||||
VersionControlDeleted,
|
VersionControlDeleted,
|
||||||
VersionControlDeletedBackground,
|
|
||||||
VersionControlModified,
|
VersionControlModified,
|
||||||
VersionControlModifiedBackground,
|
|
||||||
VersionControlRenamed,
|
VersionControlRenamed,
|
||||||
VersionControlConflict,
|
VersionControlConflict,
|
||||||
VersionControlConflictBackground,
|
|
||||||
VersionControlIgnored,
|
VersionControlIgnored,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -485,20 +473,10 @@ impl ThemeColors {
|
||||||
ThemeColorField::TerminalAnsiDimWhite => self.terminal_ansi_dim_white,
|
ThemeColorField::TerminalAnsiDimWhite => self.terminal_ansi_dim_white,
|
||||||
ThemeColorField::LinkTextHover => self.link_text_hover,
|
ThemeColorField::LinkTextHover => self.link_text_hover,
|
||||||
ThemeColorField::VersionControlAdded => self.version_control_added,
|
ThemeColorField::VersionControlAdded => self.version_control_added,
|
||||||
ThemeColorField::VersionControlAddedBackground => self.version_control_added_background,
|
|
||||||
ThemeColorField::VersionControlDeleted => self.version_control_deleted,
|
ThemeColorField::VersionControlDeleted => self.version_control_deleted,
|
||||||
ThemeColorField::VersionControlDeletedBackground => {
|
|
||||||
self.version_control_deleted_background
|
|
||||||
}
|
|
||||||
ThemeColorField::VersionControlModified => self.version_control_modified,
|
ThemeColorField::VersionControlModified => self.version_control_modified,
|
||||||
ThemeColorField::VersionControlModifiedBackground => {
|
|
||||||
self.version_control_modified_background
|
|
||||||
}
|
|
||||||
ThemeColorField::VersionControlRenamed => self.version_control_renamed,
|
ThemeColorField::VersionControlRenamed => self.version_control_renamed,
|
||||||
ThemeColorField::VersionControlConflict => self.version_control_conflict,
|
ThemeColorField::VersionControlConflict => self.version_control_conflict,
|
||||||
ThemeColorField::VersionControlConflictBackground => {
|
|
||||||
self.version_control_conflict_background
|
|
||||||
}
|
|
||||||
ThemeColorField::VersionControlIgnored => self.version_control_ignored,
|
ThemeColorField::VersionControlIgnored => self.version_control_ignored,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,7 @@ use crate::{
|
||||||
prelude::*, Color, DynamicSpacing, ElevationIndex, IconPosition, KeyBinding,
|
prelude::*, Color, DynamicSpacing, ElevationIndex, IconPosition, KeyBinding,
|
||||||
KeybindingPosition, TintColor,
|
KeybindingPosition, TintColor,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{ButtonCommon, ButtonLike, ButtonSize, ButtonStyle, IconName, IconSize, Label};
|
||||||
ButtonCommon, ButtonLike, ButtonSize, ButtonStyle, IconName, IconSize, Label, LineHeightStyle,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::button_icon::ButtonIcon;
|
use super::button_icon::ButtonIcon;
|
||||||
|
|
||||||
|
@ -448,7 +446,6 @@ impl RenderOnce for Button {
|
||||||
.color(label_color)
|
.color(label_color)
|
||||||
.size(self.label_size.unwrap_or_default())
|
.size(self.label_size.unwrap_or_default())
|
||||||
.when_some(self.alpha, |this, alpha| this.alpha(alpha))
|
.when_some(self.alpha, |this, alpha| this.alpha(alpha))
|
||||||
.line_height_style(LineHeightStyle::UiLabel)
|
|
||||||
.when(self.truncate, |this| this.truncate()),
|
.when(self.truncate, |this| this.truncate()),
|
||||||
)
|
)
|
||||||
.children(self.key_binding),
|
.children(self.key_binding),
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use gpui::{
|
use gpui::{
|
||||||
div, hsla, prelude::*, AnyElement, AnyView, CursorStyle, ElementId, Hsla, IntoElement, Styled,
|
div, hsla, prelude::*, AnyElement, AnyView, ElementId, Hsla, IntoElement, Styled, Window,
|
||||||
Window,
|
|
||||||
};
|
};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
@ -141,14 +140,14 @@ impl Checkbox {
|
||||||
|
|
||||||
match self.style.clone() {
|
match self.style.clone() {
|
||||||
ToggleStyle::Ghost => cx.theme().colors().border,
|
ToggleStyle::Ghost => cx.theme().colors().border,
|
||||||
ToggleStyle::ElevationBased(elevation) => elevation.on_elevation_bg(cx),
|
ToggleStyle::ElevationBased(_) => cx.theme().colors().border,
|
||||||
ToggleStyle::Custom(color) => color.opacity(0.3),
|
ToggleStyle::Custom(color) => color.opacity(0.3),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// container size
|
/// container size
|
||||||
pub fn container_size(cx: &App) -> Rems {
|
pub fn container_size() -> Pixels {
|
||||||
DynamicSpacing::Base20.rems(cx)
|
px(20.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,21 +156,21 @@ impl RenderOnce for Checkbox {
|
||||||
let group_id = format!("checkbox_group_{:?}", self.id);
|
let group_id = format!("checkbox_group_{:?}", self.id);
|
||||||
let color = if self.disabled {
|
let color = if self.disabled {
|
||||||
Color::Disabled
|
Color::Disabled
|
||||||
} else if self.placeholder {
|
|
||||||
Color::Placeholder
|
|
||||||
} else {
|
} else {
|
||||||
Color::Selected
|
Color::Selected
|
||||||
};
|
};
|
||||||
let icon = match self.toggle_state {
|
let icon = match self.toggle_state {
|
||||||
ToggleState::Selected => Some(if self.placeholder {
|
ToggleState::Selected => {
|
||||||
Icon::new(IconName::Circle)
|
if self.placeholder {
|
||||||
.size(IconSize::XSmall)
|
None
|
||||||
.color(color)
|
} else {
|
||||||
} else {
|
Some(
|
||||||
Icon::new(IconName::Check)
|
Icon::new(IconName::Check)
|
||||||
.size(IconSize::Small)
|
.size(IconSize::Small)
|
||||||
.color(color)
|
.color(color),
|
||||||
}),
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
ToggleState::Indeterminate => {
|
ToggleState::Indeterminate => {
|
||||||
Some(Icon::new(IconName::Dash).size(IconSize::Small).color(color))
|
Some(Icon::new(IconName::Dash).size(IconSize::Small).color(color))
|
||||||
}
|
}
|
||||||
|
@ -180,8 +179,9 @@ impl RenderOnce for Checkbox {
|
||||||
|
|
||||||
let bg_color = self.bg_color(cx);
|
let bg_color = self.bg_color(cx);
|
||||||
let border_color = self.border_color(cx);
|
let border_color = self.border_color(cx);
|
||||||
|
let hover_border_color = border_color.alpha(0.7);
|
||||||
|
|
||||||
let size = Self::container_size(cx);
|
let size = Self::container_size();
|
||||||
|
|
||||||
let checkbox = h_flex()
|
let checkbox = h_flex()
|
||||||
.id(self.id.clone())
|
.id(self.id.clone())
|
||||||
|
@ -195,22 +195,27 @@ impl RenderOnce for Checkbox {
|
||||||
.flex_none()
|
.flex_none()
|
||||||
.justify_center()
|
.justify_center()
|
||||||
.items_center()
|
.items_center()
|
||||||
.m(DynamicSpacing::Base04.px(cx))
|
.m_1()
|
||||||
.size(DynamicSpacing::Base16.rems(cx))
|
.size_4()
|
||||||
.rounded_xs()
|
.rounded_xs()
|
||||||
.bg(bg_color)
|
.bg(bg_color)
|
||||||
.border_1()
|
.border_1()
|
||||||
.border_color(border_color)
|
.border_color(border_color)
|
||||||
.when(self.disabled, |this| {
|
.when(self.disabled, |this| this.cursor_not_allowed())
|
||||||
this.cursor(CursorStyle::OperationNotAllowed)
|
|
||||||
})
|
|
||||||
.when(self.disabled, |this| {
|
.when(self.disabled, |this| {
|
||||||
this.bg(cx.theme().colors().element_disabled.opacity(0.6))
|
this.bg(cx.theme().colors().element_disabled.opacity(0.6))
|
||||||
})
|
})
|
||||||
.when(!self.disabled, |this| {
|
.when(!self.disabled, |this| {
|
||||||
this.group_hover(group_id.clone(), |el| {
|
this.group_hover(group_id.clone(), |el| el.border_color(hover_border_color))
|
||||||
el.bg(cx.theme().colors().element_hover)
|
})
|
||||||
})
|
.when(self.placeholder, |this| {
|
||||||
|
this.child(
|
||||||
|
div()
|
||||||
|
.flex_none()
|
||||||
|
.rounded_full()
|
||||||
|
.bg(color.color(cx).alpha(0.5))
|
||||||
|
.size(px(4.)),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.children(icon),
|
.children(icon),
|
||||||
);
|
);
|
||||||
|
@ -522,6 +527,12 @@ impl ComponentPreview for Checkbox {
|
||||||
Checkbox::new("checkbox_unselected", ToggleState::Unselected)
|
Checkbox::new("checkbox_unselected", ToggleState::Unselected)
|
||||||
.into_any_element(),
|
.into_any_element(),
|
||||||
),
|
),
|
||||||
|
single_example(
|
||||||
|
"Placeholder",
|
||||||
|
Checkbox::new("checkbox_indeterminate", ToggleState::Selected)
|
||||||
|
.placeholder(true)
|
||||||
|
.into_any_element(),
|
||||||
|
),
|
||||||
single_example(
|
single_example(
|
||||||
"Indeterminate",
|
"Indeterminate",
|
||||||
Checkbox::new("checkbox_indeterminate", ToggleState::Indeterminate)
|
Checkbox::new("checkbox_indeterminate", ToggleState::Indeterminate)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue