summaryrefslogtreecommitdiff
path: root/render1.rs
diff options
context:
space:
mode:
authorNamilskyy <alive6863@gmail.com>2025-04-01 22:29:47 +0300
committerNamilskyy <alive6863@gmail.com>2025-04-01 22:31:49 +0300
commitc9bca4946f43629e9b5a3f6549dc3851c6e713b3 (patch)
tree5548312adc31c3299f1c74d7b0dee6589ff0214e /render1.rs
parent0b069b828d117655053bd8972e32424ec78cbdb5 (diff)
Implemented the scrolling fucntion
Diffstat (limited to 'render1.rs')
-rw-r--r--render1.rs117
1 files changed, 117 insertions, 0 deletions
diff --git a/render1.rs b/render1.rs
new file mode 100644
index 0000000..3f92c20
--- /dev/null
+++ b/render1.rs
@@ -0,0 +1,117 @@
+use std::io;
+use ratatui::{
+ layout::{Constraint, Direction, Layout},
+ style::{Color, Style},
+ text::{Line, Span},
+ widgets::{
+ Block, Borders, Paragraph, ScrollbarState, Scrollbar, ScrollbarOrientation,
+ },
+ Terminal,
+ prelude::Alignment,
+ symbols,
+};
+
+pub fn draw(
+ terminal: &mut Terminal<impl ratatui::backend::Backend>,
+ data: &[u8],
+ cursor: usize,
+ filename: &str,
+ scrollbar_state: &mut ScrollbarState,
+) -> io::Result<()> {
+ terminal.draw(|frame| {
+ let size = frame.size();
+ let layout = Layout::default()
+ .direction(Direction::Vertical)
+ .constraints([Constraint::Min(1), Constraint::Length(1)])
+ .split(size);
+
+ // Исправление: Устанавливаем длину содержимого скролла
+ let content_length = data.len() * 2; // 2 символа на байт
+ scrollbar_state.content_length(content_length);
+
+ let visible_lines = layout[0].height as usize;
+ scrollbar_state.viewport_content_length(visible_lines);
+
+ let lines: Vec<Line> = data.chunks(16).enumerate().map(|(i, chunk)| {
+ let addr = Span::raw(format!("{:08x} │ ", i * 16));
+ let mut hex: Vec<Span> = Vec::new();
+ let mut ascii_repr = String::new();
+
+ for (j, &byte) in chunk.iter().enumerate() {
+ let hex_str = format!("{:02x}", byte);
+ let byte_index = i * 16 + j; // Индекс байта в данных
+ let cursor_byte = cursor / 2; // Байт, на котором находится курсор
+
+ for (k, ch) in hex_str.chars().enumerate() {
+ let cur_idx = byte_index * 2 + k; // Индекс символа в hex-строке
+ let style = if cur_idx == cursor {
+ Style::default().bg(Color::White).fg(Color::Black)
+ } else {
+ Style::default()
+ };
+ hex.push(Span::styled(ch.to_string(), style));
+ }
+
+ if j < 15 {
+ let space = if j % 4 == 3 { " " } else { " " };
+ hex.push(Span::raw(space));
+ }
+
+ ascii_repr.push(if byte.is_ascii_graphic() || byte == b' ' {
+ byte as char
+ } else {
+ '.'
+ });
+ }
+
+ let missing_bytes = 16 - chunk.len();
+ let padding = missing_bytes * 3;
+ let spaces = " ".repeat(padding);
+
+ let ascii = Span::raw(format!("{} │ {}", spaces, ascii_repr));
+
+ Line::from(
+ vec![addr]
+ .into_iter()
+ .chain(hex)
+ .chain(std::iter::once(ascii))
+ .collect::<Vec<_>>()
+ )
+ }).collect();
+
+ frame.render_widget(
+ Paragraph::new(lines).block(Block::default().borders(Borders::ALL)),
+ layout[0]
+ );
+
+ frame.render_stateful_widget(
+ Scrollbar::default()
+ .orientation(ScrollbarOrientation::VerticalRight)
+ .symbols(symbols::scrollbar::VERTICAL),
+ layout[0],
+ scrollbar_state,
+ );
+
+ // Исправление: Корректное вычисление прогресса
+ let progress = if data.is_empty() {
+ 100
+ } else {
+ let cursor_byte = cursor / 2;
+ (cursor_byte * 100).saturating_div(data.len())
+ };
+
+ let status_text = format!(
+ "{} \t 0x{:08x} \t {:3}%",
+ filename,
+ cursor / 2,
+ progress
+ );
+
+ let status_bar = Paragraph::new(
+ Line::from(Span::raw(status_text))
+ ).alignment(Alignment::Center);
+
+ frame.render_widget(status_bar, layout[1]);
+ })?;
+ Ok(())
+} \ No newline at end of file