mirror of
https://github.com/gitui-org/gitui
synced 2026-05-24 09:28:21 +00:00
141 lines
3.4 KiB
Rust
141 lines
3.4 KiB
Rust
use crate::{clear::Clear, git_utils, tui_utils};
|
|
use crossterm::event::{Event, KeyCode};
|
|
use std::borrow::Cow;
|
|
use tui::{
|
|
backend::Backend,
|
|
layout::{Alignment, Rect},
|
|
style::{Color, Style},
|
|
widgets::{Block, Borders, Paragraph, Text, Widget},
|
|
Frame,
|
|
};
|
|
|
|
///
|
|
pub struct CommandInfo {
|
|
pub name: String,
|
|
pub enabled: bool,
|
|
}
|
|
|
|
///
|
|
pub trait UIElement {
|
|
///
|
|
fn draw<B: Backend>(&self, f: &mut Frame<B>, rect: Rect);
|
|
///
|
|
fn commands(&self) -> Vec<CommandInfo>;
|
|
///
|
|
fn event(&mut self, ev: Event) -> bool;
|
|
///
|
|
fn is_visible(&self) -> bool;
|
|
///
|
|
fn hide(&mut self);
|
|
///
|
|
fn show(&mut self);
|
|
}
|
|
|
|
#[derive(Default)]
|
|
pub struct UICommit {
|
|
msg: String,
|
|
// focused: bool,
|
|
visible: bool,
|
|
}
|
|
|
|
impl UIElement for UICommit {
|
|
fn draw<B: Backend>(&self, f: &mut Frame<B>, _rect: Rect) {
|
|
if self.visible {
|
|
let txt = if self.msg.len() > 0 {
|
|
[Text::Raw(Cow::from(self.msg.clone()))]
|
|
} else {
|
|
[Text::Styled(
|
|
Cow::from("type commit message.."),
|
|
Style::default().fg(Color::DarkGray),
|
|
)]
|
|
};
|
|
|
|
Clear::new(
|
|
Paragraph::new(txt.iter())
|
|
.block(Block::default().title("Commit").borders(Borders::ALL))
|
|
.alignment(Alignment::Left),
|
|
)
|
|
.render(f, tui_utils::centered_rect(60, 20, f.size()));
|
|
}
|
|
}
|
|
|
|
fn commands(&self) -> Vec<CommandInfo> {
|
|
if !self.visible {
|
|
vec![CommandInfo {
|
|
name: "Commit [c]".to_string(),
|
|
enabled: !git_utils::index_empty(),
|
|
}]
|
|
} else {
|
|
vec![
|
|
CommandInfo {
|
|
name: "Commit [enter]".to_string(),
|
|
enabled: self.can_commit(),
|
|
},
|
|
CommandInfo {
|
|
name: "Close [esc]".to_string(),
|
|
enabled: true,
|
|
},
|
|
]
|
|
}
|
|
}
|
|
|
|
fn event(&mut self, ev: Event) -> bool {
|
|
if self.visible {
|
|
if let Event::Key(e) = ev {
|
|
return match e.code {
|
|
KeyCode::Esc => {
|
|
self.hide();
|
|
true
|
|
}
|
|
KeyCode::Char(c) => {
|
|
self.msg.push(c);
|
|
true
|
|
}
|
|
KeyCode::Enter if self.can_commit() => {
|
|
self.commit();
|
|
true
|
|
}
|
|
KeyCode::Backspace if self.msg.len() > 0 => {
|
|
self.msg.pop().unwrap();
|
|
true
|
|
}
|
|
_ => false,
|
|
};
|
|
}
|
|
} else {
|
|
if ev == Event::Key(KeyCode::Char('c').into()) {
|
|
if !git_utils::index_empty() {
|
|
self.show();
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
false
|
|
}
|
|
|
|
fn is_visible(&self) -> bool {
|
|
self.visible
|
|
}
|
|
|
|
fn hide(&mut self) {
|
|
self.visible = false
|
|
}
|
|
|
|
fn show(&mut self) {
|
|
self.visible = true
|
|
}
|
|
}
|
|
|
|
impl UICommit {
|
|
fn commit(&mut self) {
|
|
git_utils::commit(&self.msg);
|
|
self.msg.clear();
|
|
|
|
self.hide();
|
|
}
|
|
|
|
fn can_commit(&self) -> bool {
|
|
self.msg.len() > 0
|
|
}
|
|
}
|