git_ui: Commit modal editor cleanup (#25645)
- Fixes cursor style in the commit modal - Use commit button instead of kb hint - Update layout to scale better for large commit messages No message:  Long Message:   Release Notes: - N/A
This commit is contained in:
parent
bab65011b4
commit
1f80f58104
2 changed files with 148 additions and 294 deletions
|
@ -1,28 +1,57 @@
|
||||||
#![allow(unused, dead_code)]
|
// #![allow(unused, dead_code)]
|
||||||
|
|
||||||
use crate::git_panel::{commit_message_editor, GitPanel};
|
use crate::git_panel::{commit_message_editor, GitPanel};
|
||||||
use crate::repository_selector::RepositorySelector;
|
|
||||||
use anyhow::Result;
|
|
||||||
use git::Commit;
|
use git::Commit;
|
||||||
use language::language_settings::LanguageSettings;
|
use panel::{panel_button, panel_editor_style, panel_filled_button};
|
||||||
use language::Buffer;
|
|
||||||
use panel::{
|
|
||||||
panel_button, panel_editor_container, panel_editor_style, panel_filled_button,
|
|
||||||
panel_icon_button,
|
|
||||||
};
|
|
||||||
use settings::Settings;
|
|
||||||
use theme::ThemeSettings;
|
|
||||||
use ui::{prelude::*, KeybindingHint, Tooltip};
|
use ui::{prelude::*, KeybindingHint, Tooltip};
|
||||||
|
|
||||||
use editor::{Direction, Editor, EditorElement, EditorMode, EditorSettings, MultiBuffer};
|
use editor::{Editor, EditorElement};
|
||||||
use gpui::*;
|
use gpui::*;
|
||||||
use project::git::Repository;
|
use util::ResultExt;
|
||||||
use project::{Fs, Project};
|
use workspace::{
|
||||||
use std::sync::Arc;
|
dock::{Dock, PanelHandle},
|
||||||
use workspace::dock::{Dock, DockPosition, PanelHandle};
|
ModalView, Workspace,
|
||||||
use workspace::{ModalView, Workspace};
|
};
|
||||||
|
|
||||||
// actions!(commit_modal, [NextSuggestion, PrevSuggestion]);
|
// nate: It is a pain to get editors to size correctly and not overflow.
|
||||||
|
//
|
||||||
|
// this can get replaced with a simple flex layout with more time/a more thoughtful approach.
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
pub struct ModalContainerProperties {
|
||||||
|
pub modal_width: f32,
|
||||||
|
pub editor_height: f32,
|
||||||
|
pub footer_height: f32,
|
||||||
|
pub container_padding: f32,
|
||||||
|
pub modal_border_radius: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ModalContainerProperties {
|
||||||
|
pub fn new(window: &Window, preferred_char_width: usize) -> Self {
|
||||||
|
let container_padding = 5.0;
|
||||||
|
|
||||||
|
// Calculate width based on character width
|
||||||
|
let mut modal_width = 460.0;
|
||||||
|
let style = window.text_style().clone();
|
||||||
|
let font_id = window.text_system().resolve_font(&style.font());
|
||||||
|
let font_size = style.font_size.to_pixels(window.rem_size());
|
||||||
|
|
||||||
|
if let Ok(em_width) = window.text_system().em_width(font_id, font_size) {
|
||||||
|
modal_width = preferred_char_width as f32 * em_width.0 + (container_padding * 2.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Self {
|
||||||
|
modal_width,
|
||||||
|
editor_height: 300.0,
|
||||||
|
footer_height: 24.0,
|
||||||
|
container_padding,
|
||||||
|
modal_border_radius: 12.0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn editor_border_radius(&self) -> Pixels {
|
||||||
|
px(self.modal_border_radius - self.container_padding / 2.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn init(cx: &mut App) {
|
pub fn init(cx: &mut App) {
|
||||||
cx.observe_new(|workspace: &mut Workspace, window, cx| {
|
cx.observe_new(|workspace: &mut Workspace, window, cx| {
|
||||||
|
@ -38,8 +67,7 @@ pub struct CommitModal {
|
||||||
git_panel: Entity<GitPanel>,
|
git_panel: Entity<GitPanel>,
|
||||||
commit_editor: Entity<Editor>,
|
commit_editor: Entity<Editor>,
|
||||||
restore_dock: RestoreDock,
|
restore_dock: RestoreDock,
|
||||||
current_suggestion: Option<usize>,
|
properties: ModalContainerProperties,
|
||||||
suggested_messages: Vec<SharedString>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Focusable for CommitModal {
|
impl Focusable for CommitModal {
|
||||||
|
@ -58,12 +86,15 @@ impl ModalView for CommitModal {
|
||||||
self.git_panel.update(cx, |git_panel, cx| {
|
self.git_panel.update(cx, |git_panel, cx| {
|
||||||
git_panel.set_modal_open(false, cx);
|
git_panel.set_modal_open(false, cx);
|
||||||
});
|
});
|
||||||
self.restore_dock.dock.update(cx, |dock, cx| {
|
self.restore_dock
|
||||||
if let Some(active_index) = self.restore_dock.active_index {
|
.dock
|
||||||
dock.activate_panel(active_index, window, cx)
|
.update(cx, |dock, cx| {
|
||||||
}
|
if let Some(active_index) = self.restore_dock.active_index {
|
||||||
dock.set_open(self.restore_dock.is_open, window, cx)
|
dock.activate_panel(active_index, window, cx)
|
||||||
});
|
}
|
||||||
|
dock.set_open(self.restore_dock.is_open, window, cx)
|
||||||
|
})
|
||||||
|
.log_err();
|
||||||
workspace::DismissDecision::Dismiss(true)
|
workspace::DismissDecision::Dismiss(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,13 +106,13 @@ struct RestoreDock {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CommitModal {
|
impl CommitModal {
|
||||||
pub fn register(workspace: &mut Workspace, _: &mut Window, cx: &mut Context<Workspace>) {
|
pub fn register(workspace: &mut Workspace, _: &mut Window, _cx: &mut Context<Workspace>) {
|
||||||
workspace.register_action(|workspace, _: &Commit, window, cx| {
|
workspace.register_action(|workspace, _: &Commit, window, cx| {
|
||||||
let Some(git_panel) = workspace.panel::<GitPanel>(cx) else {
|
let Some(git_panel) = workspace.panel::<GitPanel>(cx) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let (can_commit, conflict) = git_panel.update(cx, |git_panel, cx| {
|
let (can_commit, conflict) = git_panel.update(cx, |git_panel, _cx| {
|
||||||
let can_commit = git_panel.can_commit();
|
let can_commit = git_panel.can_commit();
|
||||||
let conflict = git_panel.has_unstaged_conflicts();
|
let conflict = git_panel.has_unstaged_conflicts();
|
||||||
(can_commit, conflict)
|
(can_commit, conflict)
|
||||||
|
@ -151,145 +182,56 @@ impl CommitModal {
|
||||||
|
|
||||||
let focus_handle = commit_editor.focus_handle(cx);
|
let focus_handle = commit_editor.focus_handle(cx);
|
||||||
|
|
||||||
cx.on_focus_out(&focus_handle, window, |this, _, window, cx| {
|
cx.on_focus_out(&focus_handle, window, |_, _, _, cx| {
|
||||||
cx.emit(DismissEvent);
|
cx.emit(DismissEvent);
|
||||||
})
|
})
|
||||||
.detach();
|
.detach();
|
||||||
|
|
||||||
|
let properties = ModalContainerProperties::new(window, 50);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
git_panel,
|
git_panel,
|
||||||
commit_editor,
|
commit_editor,
|
||||||
restore_dock,
|
restore_dock,
|
||||||
current_suggestion: None,
|
properties,
|
||||||
suggested_messages: vec![],
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns container `(width, x padding, border radius)`
|
|
||||||
fn container_properties(&self, window: &mut Window, cx: &mut Context<Self>) -> (f32, f32, f32) {
|
|
||||||
// TODO: Let's set the width based on your set wrap guide if possible
|
|
||||||
|
|
||||||
// let settings = EditorSettings::get_global(cx);
|
|
||||||
|
|
||||||
// let first_wrap_guide = self
|
|
||||||
// .commit_editor
|
|
||||||
// .read(cx)
|
|
||||||
// .wrap_guides(cx)
|
|
||||||
// .iter()
|
|
||||||
// .next()
|
|
||||||
// .map(|(guide, active)| if *active { Some(*guide) } else { None })
|
|
||||||
// .flatten();
|
|
||||||
|
|
||||||
// let preferred_width = if let Some(guide) = first_wrap_guide {
|
|
||||||
// guide
|
|
||||||
// } else {
|
|
||||||
// 80
|
|
||||||
// };
|
|
||||||
|
|
||||||
let border_radius = 16.0;
|
|
||||||
|
|
||||||
let preferred_width = 50; // (chars wide)
|
|
||||||
|
|
||||||
let mut width = 460.0;
|
|
||||||
let padding_x = 16.0;
|
|
||||||
|
|
||||||
let mut snapshot = self
|
|
||||||
.commit_editor
|
|
||||||
.update(cx, |editor, cx| editor.snapshot(window, cx));
|
|
||||||
let style = window.text_style().clone();
|
|
||||||
|
|
||||||
let font_id = window.text_system().resolve_font(&style.font());
|
|
||||||
let font_size = style.font_size.to_pixels(window.rem_size());
|
|
||||||
let line_height = style.line_height_in_pixels(window.rem_size());
|
|
||||||
if let Ok(em_width) = window.text_system().em_width(font_id, font_size) {
|
|
||||||
width = preferred_width as f32 * em_width.0 + (padding_x * 2.0);
|
|
||||||
cx.notify();
|
|
||||||
}
|
|
||||||
|
|
||||||
// cx.notify();
|
|
||||||
|
|
||||||
(width, padding_x, border_radius)
|
|
||||||
}
|
|
||||||
|
|
||||||
// fn cycle_suggested_messages(&mut self, direction: Direction, cx: &mut Context<Self>) {
|
|
||||||
// let new_index = match direction {
|
|
||||||
// Direction::Next => {
|
|
||||||
// (self.current_suggestion.unwrap_or(0) + 1).rem_euclid(self.suggested_messages.len())
|
|
||||||
// }
|
|
||||||
// Direction::Prev => {
|
|
||||||
// (self.current_suggestion.unwrap_or(0) + self.suggested_messages.len() - 1)
|
|
||||||
// .rem_euclid(self.suggested_messages.len())
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
// self.current_suggestion = Some(new_index);
|
|
||||||
|
|
||||||
// cx.notify();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn next_suggestion(&mut self, _: &NextSuggestion, window: &mut Window, cx: &mut Context<Self>) {
|
|
||||||
// self.current_suggestion = Some(1);
|
|
||||||
// self.apply_suggestion(window, cx);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn prev_suggestion(&mut self, _: &PrevSuggestion, window: &mut Window, cx: &mut Context<Self>) {
|
|
||||||
// self.current_suggestion = Some(0);
|
|
||||||
// self.apply_suggestion(window, cx);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn set_commit_message(&mut self, message: &str, window: &mut Window, cx: &mut Context<Self>) {
|
|
||||||
// self.commit_editor.update(cx, |editor, cx| {
|
|
||||||
// editor.set_text(message.to_string(), window, cx)
|
|
||||||
// });
|
|
||||||
// self.current_suggestion = Some(0);
|
|
||||||
// cx.notify();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn apply_suggestion(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
|
||||||
// let suggested_messages = self.suggested_messages.clone();
|
|
||||||
|
|
||||||
// if let Some(suggestion) = self.current_suggestion {
|
|
||||||
// let suggested_message = &suggested_messages[suggestion];
|
|
||||||
|
|
||||||
// self.set_commit_message(suggested_message, window, cx);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// cx.notify();
|
|
||||||
// }
|
|
||||||
|
|
||||||
fn commit_editor_element(&self, window: &mut Window, cx: &mut Context<Self>) -> EditorElement {
|
fn commit_editor_element(&self, window: &mut Window, cx: &mut Context<Self>) -> EditorElement {
|
||||||
let mut editor = self.commit_editor.clone();
|
|
||||||
|
|
||||||
let editor_style = panel_editor_style(true, window, cx);
|
let editor_style = panel_editor_style(true, window, cx);
|
||||||
|
|
||||||
EditorElement::new(&self.commit_editor, editor_style)
|
EditorElement::new(&self.commit_editor, editor_style)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_commit_editor(
|
pub fn render_commit_editor(
|
||||||
&self,
|
&self,
|
||||||
name_and_email: Option<(SharedString, SharedString)>,
|
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) -> impl IntoElement {
|
) -> impl IntoElement {
|
||||||
let (width, padding_x, modal_border_radius) = self.container_properties(window, cx);
|
let properties = self.properties;
|
||||||
|
let padding_t = 3.0;
|
||||||
|
let padding_b = 6.0;
|
||||||
|
// magic number for editor not to overflow the container??
|
||||||
|
let extra_space_hack = 1.5 * window.line_height();
|
||||||
|
|
||||||
let border_radius = modal_border_radius - padding_x / 2.0;
|
v_flex()
|
||||||
|
.h(px(properties.editor_height + padding_b + padding_t) + extra_space_hack)
|
||||||
|
.w_full()
|
||||||
|
.flex_none()
|
||||||
|
.rounded(properties.editor_border_radius())
|
||||||
|
.overflow_hidden()
|
||||||
|
.px_1p5()
|
||||||
|
.pt(px(padding_t))
|
||||||
|
.pb(px(padding_b))
|
||||||
|
.child(
|
||||||
|
div()
|
||||||
|
.h(px(properties.editor_height))
|
||||||
|
.w_full()
|
||||||
|
.child(self.commit_editor_element(window, cx)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
let editor = self.commit_editor.clone();
|
fn render_footer(&self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||||
let editor_focus_handle = editor.focus_handle(cx);
|
let git_panel = self.git_panel.clone();
|
||||||
|
|
||||||
let settings = ThemeSettings::get_global(cx);
|
|
||||||
let line_height = relative(settings.buffer_line_height.value())
|
|
||||||
.to_pixels(settings.buffer_font_size(cx).into(), window.rem_size());
|
|
||||||
|
|
||||||
let mut snapshot = self
|
|
||||||
.commit_editor
|
|
||||||
.update(cx, |editor, cx| editor.snapshot(window, cx));
|
|
||||||
let style = window.text_style().clone();
|
|
||||||
|
|
||||||
let font_id = window.text_system().resolve_font(&style.font());
|
|
||||||
let font_size = style.font_size.to_pixels(window.rem_size());
|
|
||||||
let line_height = style.line_height_in_pixels(window.rem_size());
|
|
||||||
let em_width = window.text_system().em_width(font_id, font_size);
|
|
||||||
|
|
||||||
let (branch, tooltip, commit_label, co_authors) =
|
let (branch, tooltip, commit_label, co_authors) =
|
||||||
self.git_panel.update(cx, |git_panel, cx| {
|
self.git_panel.update(cx, |git_panel, cx| {
|
||||||
|
@ -327,8 +269,6 @@ impl CommitModal {
|
||||||
}))
|
}))
|
||||||
.style(ButtonStyle::Transparent);
|
.style(ButtonStyle::Transparent);
|
||||||
|
|
||||||
let changes_count = self.git_panel.read(cx).total_staged_count();
|
|
||||||
|
|
||||||
let close_kb_hint =
|
let close_kb_hint =
|
||||||
if let Some(close_kb) = ui::KeyBinding::for_action(&menu::Cancel, window, cx) {
|
if let Some(close_kb) = ui::KeyBinding::for_action(&menu::Cancel, window, cx) {
|
||||||
Some(
|
Some(
|
||||||
|
@ -339,151 +279,44 @@ impl CommitModal {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let fake_commit_kb =
|
let (panel_editor_focus_handle, can_commit) = git_panel.update(cx, |git_panel, cx| {
|
||||||
ui::KeyBinding::new(gpui::KeyBinding::new("cmd-enter", gpui::NoAction, None), cx);
|
(git_panel.editor_focus_handle(cx), git_panel.can_commit())
|
||||||
|
|
||||||
let commit_hint =
|
|
||||||
KeybindingHint::new(fake_commit_kb, cx.theme().colors().editor_background)
|
|
||||||
.suffix(commit_label);
|
|
||||||
|
|
||||||
let focus_handle = self.focus_handle(cx);
|
|
||||||
|
|
||||||
// let next_suggestion_kb =
|
|
||||||
// ui::KeyBinding::for_action_in(&NextSuggestion, &focus_handle.clone(), window, cx);
|
|
||||||
// let next_suggestion_hint = next_suggestion_kb.map(|kb| {
|
|
||||||
// KeybindingHint::new(kb, cx.theme().colors().editor_background).suffix("Next Suggestion")
|
|
||||||
// });
|
|
||||||
|
|
||||||
// let prev_suggestion_kb =
|
|
||||||
// ui::KeyBinding::for_action_in(&PrevSuggestion, &focus_handle.clone(), window, cx);
|
|
||||||
// let prev_suggestion_hint = prev_suggestion_kb.map(|kb| {
|
|
||||||
// KeybindingHint::new(kb, cx.theme().colors().editor_background)
|
|
||||||
// .suffix("Previous Suggestion")
|
|
||||||
// });
|
|
||||||
|
|
||||||
v_flex()
|
|
||||||
.id("editor-container")
|
|
||||||
.bg(cx.theme().colors().editor_background)
|
|
||||||
.flex_1()
|
|
||||||
.size_full()
|
|
||||||
.rounded(px(border_radius))
|
|
||||||
.overflow_hidden()
|
|
||||||
.border_1()
|
|
||||||
.border_color(cx.theme().colors().border_variant)
|
|
||||||
.py_2()
|
|
||||||
.px_3()
|
|
||||||
.on_click(cx.listener(move |_, _: &ClickEvent, window, _cx| {
|
|
||||||
window.focus(&editor_focus_handle);
|
|
||||||
}))
|
|
||||||
.child(
|
|
||||||
div()
|
|
||||||
.size_full()
|
|
||||||
.flex_1()
|
|
||||||
.child(self.commit_editor_element(window, cx)),
|
|
||||||
)
|
|
||||||
.child(
|
|
||||||
h_flex()
|
|
||||||
.group("commit_editor_footer")
|
|
||||||
.flex_none()
|
|
||||||
.w_full()
|
|
||||||
.items_center()
|
|
||||||
.justify_between()
|
|
||||||
.w_full()
|
|
||||||
.pt_2()
|
|
||||||
.pb_0p5()
|
|
||||||
.gap_1()
|
|
||||||
.child(h_flex().gap_1().child(branch_selector).children(co_authors))
|
|
||||||
.child(div().flex_1())
|
|
||||||
.child(
|
|
||||||
h_flex()
|
|
||||||
.opacity(0.7)
|
|
||||||
.group_hover("commit_editor_footer", |this| this.opacity(1.0))
|
|
||||||
.items_center()
|
|
||||||
.justify_end()
|
|
||||||
.flex_none()
|
|
||||||
.px_1()
|
|
||||||
.gap_4()
|
|
||||||
.children(close_kb_hint)
|
|
||||||
// .children(next_suggestion_hint)
|
|
||||||
.child(commit_hint),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn render_footer(&self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
|
||||||
let (branch, tooltip, title, co_authors) = self.git_panel.update(cx, |git_panel, cx| {
|
|
||||||
let branch = git_panel
|
|
||||||
.active_repository
|
|
||||||
.as_ref()
|
|
||||||
.and_then(|repo| {
|
|
||||||
repo.read(cx)
|
|
||||||
.repository_entry
|
|
||||||
.branch()
|
|
||||||
.map(|b| b.name.clone())
|
|
||||||
})
|
|
||||||
.unwrap_or_else(|| "<no branch>".into());
|
|
||||||
let tooltip = if git_panel.has_staged_changes() {
|
|
||||||
"Commit staged changes"
|
|
||||||
} else {
|
|
||||||
"Commit changes to tracked files"
|
|
||||||
};
|
|
||||||
let title = if git_panel.has_staged_changes() {
|
|
||||||
"Commit"
|
|
||||||
} else {
|
|
||||||
"Commit All"
|
|
||||||
};
|
|
||||||
let co_authors = git_panel.render_co_authors(cx);
|
|
||||||
(branch, tooltip, title, co_authors)
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let branch_selector = panel_button(branch)
|
let commit_button = panel_filled_button(commit_label)
|
||||||
.icon(IconName::GitBranch)
|
.tooltip(move |window, cx| {
|
||||||
.icon_size(IconSize::Small)
|
Tooltip::for_action_in(tooltip, &Commit, &panel_editor_focus_handle, window, cx)
|
||||||
.icon_color(Color::Muted)
|
})
|
||||||
.icon_position(IconPosition::Start)
|
.disabled(!can_commit)
|
||||||
.tooltip(Tooltip::for_action_title(
|
.on_click(cx.listener(move |this, _: &ClickEvent, window, cx| {
|
||||||
"Switch Branch",
|
this.git_panel
|
||||||
&zed_actions::git::Branch,
|
.update(cx, |git_panel, cx| git_panel.commit_changes(window, cx));
|
||||||
))
|
cx.emit(DismissEvent);
|
||||||
.on_click(cx.listener(|_, _, window, cx| {
|
}));
|
||||||
window.dispatch_action(zed_actions::git::Branch.boxed_clone(), cx);
|
|
||||||
}))
|
|
||||||
.style(ButtonStyle::Transparent);
|
|
||||||
|
|
||||||
let changes_count = self.git_panel.read(cx).total_staged_count();
|
|
||||||
|
|
||||||
let close_kb_hint =
|
|
||||||
if let Some(close_kb) = ui::KeyBinding::for_action(&menu::Cancel, window, cx) {
|
|
||||||
Some(
|
|
||||||
KeybindingHint::new(close_kb, cx.theme().colors().editor_background)
|
|
||||||
.suffix("Cancel"),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
h_flex()
|
h_flex()
|
||||||
.items_center()
|
.group("commit_editor_footer")
|
||||||
.h(px(36.0))
|
.flex_none()
|
||||||
.w_full()
|
.w_full()
|
||||||
|
.items_center()
|
||||||
.justify_between()
|
.justify_between()
|
||||||
.px_3()
|
.w_full()
|
||||||
.child(h_flex().child(branch_selector))
|
.h(px(self.properties.footer_height))
|
||||||
|
.gap_1()
|
||||||
|
.child(h_flex().gap_1().child(branch_selector).children(co_authors))
|
||||||
|
.child(div().flex_1())
|
||||||
.child(
|
.child(
|
||||||
h_flex().gap_1p5().children(co_authors).child(
|
h_flex()
|
||||||
Button::new("stage-button", title)
|
.items_center()
|
||||||
.tooltip(Tooltip::for_action_title(tooltip, &git::Commit))
|
.justify_end()
|
||||||
.on_click(cx.listener(|this, _, window, cx| {
|
.flex_none()
|
||||||
this.commit(&Default::default(), window, cx);
|
.px_1()
|
||||||
})),
|
.gap_4()
|
||||||
),
|
.children(close_kb_hint)
|
||||||
|
.child(commit_button),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn border_radius(&self) -> f32 {
|
|
||||||
8.0
|
|
||||||
}
|
|
||||||
|
|
||||||
fn dismiss(&mut self, _: &menu::Cancel, _: &mut Window, cx: &mut Context<Self>) {
|
fn dismiss(&mut self, _: &menu::Cancel, _: &mut Window, cx: &mut Context<Self>) {
|
||||||
cx.emit(DismissEvent);
|
cx.emit(DismissEvent);
|
||||||
}
|
}
|
||||||
|
@ -496,33 +329,50 @@ impl CommitModal {
|
||||||
|
|
||||||
impl Render for CommitModal {
|
impl Render for CommitModal {
|
||||||
fn render(&mut self, window: &mut Window, cx: &mut Context<'_, Self>) -> impl IntoElement {
|
fn render(&mut self, window: &mut Window, cx: &mut Context<'_, Self>) -> impl IntoElement {
|
||||||
let (width, _, border_radius) = self.container_properties(window, cx);
|
let properties = self.properties;
|
||||||
|
let width = px(properties.modal_width);
|
||||||
|
let container_padding = px(properties.container_padding);
|
||||||
|
let border_radius = properties.modal_border_radius;
|
||||||
|
let editor_focus_handle = self.commit_editor.focus_handle(cx);
|
||||||
|
|
||||||
v_flex()
|
v_flex()
|
||||||
.id("commit-modal")
|
.id("commit-modal")
|
||||||
.key_context("GitCommit")
|
.key_context("GitCommit")
|
||||||
.elevation_3(cx)
|
|
||||||
.overflow_hidden()
|
|
||||||
.on_action(cx.listener(Self::dismiss))
|
.on_action(cx.listener(Self::dismiss))
|
||||||
.on_action(cx.listener(Self::commit))
|
.on_action(cx.listener(Self::commit))
|
||||||
// .on_action(cx.listener(Self::next_suggestion))
|
.elevation_3(cx)
|
||||||
// .on_action(cx.listener(Self::prev_suggestion))
|
.overflow_hidden()
|
||||||
|
.flex_none()
|
||||||
.relative()
|
.relative()
|
||||||
.justify_between()
|
|
||||||
.bg(cx.theme().colors().elevated_surface_background)
|
.bg(cx.theme().colors().elevated_surface_background)
|
||||||
.rounded(px(border_radius))
|
.rounded(px(border_radius))
|
||||||
.border_1()
|
.border_1()
|
||||||
.border_color(cx.theme().colors().border)
|
.border_color(cx.theme().colors().border)
|
||||||
.w(px(width))
|
.w(width)
|
||||||
.h(px(360.))
|
.p(container_padding)
|
||||||
.flex_1()
|
|
||||||
.overflow_hidden()
|
|
||||||
.child(
|
.child(
|
||||||
v_flex()
|
v_flex()
|
||||||
.flex_1()
|
.id("editor-container")
|
||||||
|
.justify_between()
|
||||||
.p_2()
|
.p_2()
|
||||||
.child(self.render_commit_editor(None, window, cx)),
|
.size_full()
|
||||||
|
.gap_2()
|
||||||
|
.rounded(properties.editor_border_radius())
|
||||||
|
.overflow_hidden()
|
||||||
|
.cursor_text()
|
||||||
|
.bg(cx.theme().colors().editor_background)
|
||||||
|
.border_1()
|
||||||
|
.border_color(cx.theme().colors().border_variant)
|
||||||
|
.on_click(cx.listener(move |_, _: &ClickEvent, window, _cx| {
|
||||||
|
window.focus(&editor_focus_handle);
|
||||||
|
}))
|
||||||
|
.child(
|
||||||
|
div()
|
||||||
|
.flex_1()
|
||||||
|
.size_full()
|
||||||
|
.child(self.render_commit_editor(window, cx)),
|
||||||
|
)
|
||||||
|
.child(self.render_footer(window, cx)),
|
||||||
)
|
)
|
||||||
// .child(self.render_footer(window, cx))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -621,6 +621,10 @@ impl GitPanel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn editor_focus_handle(&self, cx: &mut Context<Self>) -> FocusHandle {
|
||||||
|
self.commit_editor.focus_handle(cx).clone()
|
||||||
|
}
|
||||||
|
|
||||||
fn focus_editor(&mut self, _: &FocusEditor, window: &mut Window, cx: &mut Context<Self>) {
|
fn focus_editor(&mut self, _: &FocusEditor, window: &mut Window, cx: &mut Context<Self>) {
|
||||||
self.commit_editor.update(cx, |editor, cx| {
|
self.commit_editor.update(cx, |editor, cx| {
|
||||||
window.focus(&editor.focus_handle(cx));
|
window.focus(&editor.focus_handle(cx));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue