add alert system
This commit is contained in:
+10
-5
@@ -1,5 +1,5 @@
|
|||||||
use std::{cmp::min, fs::File, io::Write, mem::{replace, swap}};
|
use std::{cmp::min, fs::File, io::Write, mem::{replace, swap}};
|
||||||
|
use ratatui::{style::Stylize, text::Span};
|
||||||
use crate::{BYTES_PER_LINE, app::{App, Mode, PartialAction}, edit_action::EditAction};
|
use crate::{BYTES_PER_LINE, app::{App, Mode, PartialAction}, edit_action::EditAction};
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
@@ -120,11 +120,13 @@ impl App {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const fn quit_if_saved(&mut self) {
|
fn quit_if_saved(&mut self) {
|
||||||
if self.all_changes_saved() {
|
if self.all_changes_saved() {
|
||||||
self.quit();
|
self.quit();
|
||||||
} else {
|
} else {
|
||||||
// TODO: show alert of some kind
|
self.alert_message = Span::from(
|
||||||
|
"there are unsaved changes, use Q to override"
|
||||||
|
).red();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,8 +229,11 @@ impl App {
|
|||||||
self.cursor.collapse();
|
self.cursor.collapse();
|
||||||
}
|
}
|
||||||
|
|
||||||
const fn goto_line_end(&mut self) {
|
fn goto_line_end(&mut self) {
|
||||||
self.cursor.head += BYTES_PER_LINE - 1 - (self.cursor.head % BYTES_PER_LINE);
|
self.cursor.head = min(
|
||||||
|
self.cursor.head + BYTES_PER_LINE - 1 - (self.cursor.head % BYTES_PER_LINE),
|
||||||
|
self.max_contents_index()
|
||||||
|
);
|
||||||
self.cursor.collapse();
|
self.cursor.collapse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+7
-1
@@ -1,6 +1,6 @@
|
|||||||
use std::{env, fs::File, io::Read, path::PathBuf, process::exit};
|
use std::{env, fs::File, io::Read, path::PathBuf, process::exit};
|
||||||
use crossterm::{event::{self, Event, KeyEvent}, terminal::window_size};
|
use crossterm::{event::{self, Event, KeyEvent}, terminal::window_size};
|
||||||
use ratatui::style::Color;
|
use ratatui::{style::Color, text::Span};
|
||||||
use crate::{config::Config, cursor::Cursor, edit_action::EditAction};
|
use crate::{config::Config, cursor::Cursor, edit_action::EditAction};
|
||||||
|
|
||||||
mod widget;
|
mod widget;
|
||||||
@@ -29,6 +29,8 @@ pub struct App {
|
|||||||
// the index *after* the last saved edit action
|
// the index *after* the last saved edit action
|
||||||
pub last_saved_at: Option<usize>,
|
pub last_saved_at: Option<usize>,
|
||||||
|
|
||||||
|
pub alert_message: Span<'static>,
|
||||||
|
|
||||||
pub logs: Vec<String>,
|
pub logs: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,6 +113,8 @@ impl App {
|
|||||||
time_traveling: None,
|
time_traveling: None,
|
||||||
last_saved_at: Some(0),
|
last_saved_at: Some(0),
|
||||||
|
|
||||||
|
alert_message: "".into(),
|
||||||
|
|
||||||
logs: Vec::new(),
|
logs: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -132,6 +136,8 @@ impl App {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn handle_key(&mut self, event: KeyEvent) {
|
fn handle_key(&mut self, event: KeyEvent) {
|
||||||
|
self.alert_message = "".into();
|
||||||
|
|
||||||
if self.partial_action == Some(PartialAction::Replace) {
|
if self.partial_action == Some(PartialAction::Replace) {
|
||||||
if let Some(hex_character) = event.code.as_char() &&
|
if let Some(hex_character) = event.code.as_char() &&
|
||||||
let Some(nybble) = nybble_from_hex(hex_character)
|
let Some(nybble) = nybble_from_hex(hex_character)
|
||||||
|
|||||||
+6
-4
@@ -200,7 +200,7 @@ mod hex {
|
|||||||
let replaced_byte = self.partial_replace.unwrap_or(0) << 4;
|
let replaced_byte = self.partial_replace.unwrap_or(0) << 4;
|
||||||
|
|
||||||
self.render_byte_without_replace_preview(address, replaced_byte)
|
self.render_byte_without_replace_preview(address, replaced_byte)
|
||||||
.fg(Color::Black)
|
.black()
|
||||||
} else {
|
} else {
|
||||||
self.render_byte_without_replace_preview(address, byte)
|
self.render_byte_without_replace_preview(address, byte)
|
||||||
}
|
}
|
||||||
@@ -330,7 +330,7 @@ mod character_panel {
|
|||||||
|
|
||||||
match self.cursor.contains(address) {
|
match self.cursor.contains(address) {
|
||||||
Some(InCursor::Head) => span.bg(Color::select_grey()),
|
Some(InCursor::Head) => span.bg(Color::select_grey()),
|
||||||
Some(InCursor::Rest) => span.bg(Color::DarkGray),
|
Some(InCursor::Rest) => span.on_dark_gray(),
|
||||||
None => span,
|
None => span,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -388,7 +388,9 @@ mod status_line {
|
|||||||
self.render_mode(),
|
self.render_mode(),
|
||||||
" ".into(),
|
" ".into(),
|
||||||
self.render_file_name(),
|
self.render_file_name(),
|
||||||
self.modified_indicator()
|
self.modified_indicator(),
|
||||||
|
" ".into(),
|
||||||
|
self.alert_message.clone()
|
||||||
])
|
])
|
||||||
)
|
)
|
||||||
.bg(Color::ui_grey())
|
.bg(Color::ui_grey())
|
||||||
@@ -396,7 +398,7 @@ mod status_line {
|
|||||||
|
|
||||||
fn render_mode(&self) -> Span<'static> {
|
fn render_mode(&self) -> Span<'static> {
|
||||||
Span::from(self.mode.label())
|
Span::from(self.mode.label())
|
||||||
.fg(Color::Black)
|
.black()
|
||||||
.bg(self.mode.color())
|
.bg(self.mode.color())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,8 +50,6 @@ const CHUNKS_PER_LINE: usize = BYTES_PER_LINE / BYTES_PER_CHUNK;
|
|||||||
// - utf8?
|
// - utf8?
|
||||||
// - diffing
|
// - diffing
|
||||||
|
|
||||||
// TODO: quit should confirm if unsaved changes
|
|
||||||
|
|
||||||
// when AsciiChar is stabilized, use it instead of char everywhere
|
// when AsciiChar is stabilized, use it instead of char everywhere
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|||||||
Reference in New Issue
Block a user