Upgrade JobsView component to new TUI API

Signed-off-by: Manos Pitsidianakis <manos@pitsidianak.is>
pull/312/head
Manos Pitsidianakis 6 months ago
parent 28fa66cc2a
commit 5dd71ef1cd
No known key found for this signature in database
GPG Key ID: 7729C7707F7E09D0

@ -19,7 +19,7 @@
* along with meli. If not, see <http://www.gnu.org/licenses/>. * along with meli. If not, see <http://www.gnu.org/licenses/>.
*/ */
use std::{borrow::Cow, cmp}; use std::borrow::Cow;
use indexmap::IndexMap; use indexmap::IndexMap;
@ -146,118 +146,160 @@ impl JobManager {
self.min_width = [hdr!(0), hdr!(1), hdr!(2), hdr!(3), hdr!(4)]; self.min_width = [hdr!(0), hdr!(1), hdr!(2), hdr!(3), hdr!(4)];
for c in self.entries.values() { for c in self.entries.values() {
/* title */ // title
self.min_width[0] = cmp::max(self.min_width[0], c.id.to_string().len()); self.min_width[0] = self.min_width[0].max(c.id.to_string().len());
/* desc */ // desc
self.min_width[1] = cmp::max(self.min_width[1], c.desc.len()); self.min_width[1] = self.min_width[1].max(c.desc.len());
} }
self.min_width[2] = "1970-01-01 00:00:00".len(); self.min_width[2] = "1970-01-01 00:00:00".len();
self.min_width[3] = self.min_width[2]; self.min_width[3] = self.min_width[2];
/* name column */ // name column
self.data_columns.columns[0] = _ = self.data_columns.columns[0].resize_with_context(
CellBuffer::new_with_context(self.min_width[0], self.length, None, context); self.min_width[0],
/* path column */ self.length,
self.data_columns.columns[1] = context,
CellBuffer::new_with_context(self.min_width[1], self.length, None, context); );
/* size column */ self.data_columns.columns[0].grid_mut().clear(None);
self.data_columns.columns[2] = // path column
CellBuffer::new_with_context(self.min_width[2], self.length, None, context); _ = self.data_columns.columns[1].resize_with_context(
/* subscribed column */ self.min_width[1],
self.data_columns.columns[3] = self.length,
CellBuffer::new_with_context(self.min_width[3], self.length, None, context); context,
self.data_columns.columns[4] = );
CellBuffer::new_with_context(self.min_width[4], self.length, None, context); self.data_columns.columns[1].grid_mut().clear(None);
// size column
_ = self.data_columns.columns[2].resize_with_context(
self.min_width[2],
self.length,
context,
);
self.data_columns.columns[2].grid_mut().clear(None);
// subscribed column
_ = self.data_columns.columns[3].resize_with_context(
self.min_width[3],
self.length,
context,
);
self.data_columns.columns[3].grid_mut().clear(None);
_ = self.data_columns.columns[4].resize_with_context(
self.min_width[4],
self.length,
context,
);
self.data_columns.columns[4].grid_mut().clear(None);
for (idx, e) in self.entries.values().enumerate() { for (idx, e) in self.entries.values().enumerate() {
self.data_columns.columns[0].write_string( {
&e.id.to_string(), let area = self.data_columns.columns[0].area().nth_row(idx);
self.theme_default.fg, self.data_columns.columns[0].grid_mut().write_string(
self.theme_default.bg, &e.id.to_string(),
self.theme_default.attrs, self.theme_default.fg,
((0, idx), (self.min_width[0], idx)), self.theme_default.bg,
None, self.theme_default.attrs,
); area,
None,
self.data_columns.columns[1].write_string( );
&e.desc, }
self.theme_default.fg,
self.theme_default.bg,
self.theme_default.attrs,
((0, idx), (self.min_width[1], idx)),
None,
);
self.data_columns.columns[2].write_string( {
&datetime::timestamp_to_string(e.started, Some(RFC3339_DATETIME_AND_SPACE), true), let area = self.data_columns.columns[1].area().nth_row(idx);
self.theme_default.fg, self.data_columns.columns[1].grid_mut().write_string(
self.theme_default.bg, &e.desc,
self.theme_default.attrs, self.theme_default.fg,
((0, idx), (self.min_width[2], idx)), self.theme_default.bg,
None, self.theme_default.attrs,
); area,
None,
);
}
self.data_columns.columns[3].write_string( {
&if let Some(t) = e.finished { let area = self.data_columns.columns[2].area().nth_row(idx);
Cow::Owned(datetime::timestamp_to_string( self.data_columns.columns[2].grid_mut().write_string(
t, &datetime::timestamp_to_string(
e.started,
Some(RFC3339_DATETIME_AND_SPACE), Some(RFC3339_DATETIME_AND_SPACE),
true, true,
)) ),
} else { self.theme_default.fg,
Cow::Borrowed("null") self.theme_default.bg,
}, self.theme_default.attrs,
self.theme_default.fg, area,
self.theme_default.bg, None,
self.theme_default.attrs, );
((0, idx), (self.min_width[3], idx)), }
None,
);
self.data_columns.columns[4].write_string( {
&if e.finished.is_some() { let area = self.data_columns.columns[3].area().nth_row(idx);
Cow::Owned(format!("{:?}", e.succeeded)) self.data_columns.columns[3].grid_mut().write_string(
} else { &if let Some(t) = e.finished {
Cow::Borrowed("-") Cow::Owned(datetime::timestamp_to_string(
}, t,
self.theme_default.fg, Some(RFC3339_DATETIME_AND_SPACE),
self.theme_default.bg, true,
self.theme_default.attrs, ))
((0, idx), (self.min_width[4], idx)), } else {
None, Cow::Borrowed("null")
); },
self.theme_default.fg,
self.theme_default.bg,
self.theme_default.attrs,
area,
None,
);
}
{
let area = self.data_columns.columns[4].area().nth_row(idx);
self.data_columns.columns[4].grid_mut().write_string(
&if e.finished.is_some() {
Cow::Owned(format!("{:?}", e.succeeded))
} else {
Cow::Borrowed("-")
},
self.theme_default.fg,
self.theme_default.bg,
self.theme_default.attrs,
area,
None,
);
}
} }
if self.length == 0 { if self.length == 0 {
let message = "No jobs.".to_string(); let message = "No jobs.".to_string();
self.data_columns.columns[0] = if self.data_columns.columns[0].resize_with_context(message.len(), self.length, context)
CellBuffer::new_with_context(message.len(), self.length, None, context); {
self.data_columns.columns[0].write_string( let area = self.data_columns.columns[0].area();
&message, self.data_columns.columns[0].grid_mut().write_string(
self.theme_default.fg, &message,
self.theme_default.bg, self.theme_default.fg,
self.theme_default.attrs, self.theme_default.bg,
((0, 0), (message.len() - 1, 0)), self.theme_default.attrs,
None, area,
); None,
);
}
} }
} }
fn draw_list(&mut self, grid: &mut CellBuffer, area: Area, context: &mut Context) { fn draw_list(&mut self, grid: &mut CellBuffer, area: Area, context: &mut Context) {
let (upper_left, bottom_right) = area; let rows = area.height();
if rows == 0 {
return;
}
if self.length == 0 { if self.length == 0 {
grid.clear_area(area, self.theme_default); grid.clear_area(area, self.theme_default);
grid.copy_area( grid.copy_area(
&self.data_columns.columns[0], self.data_columns.columns[0].grid(),
area, area,
((0, 0), pos_dec(self.data_columns.columns[0].size(), (1, 1))), self.data_columns.columns[0].area(),
); );
context.dirty_areas.push_back(area); context.dirty_areas.push_back(area);
return; return;
} }
let rows = get_y(bottom_right) - get_y(upper_left) + 1;
if let Some(mvm) = self.movement.take() { if let Some(mvm) = self.movement.take() {
match mvm { match mvm {
@ -284,7 +326,20 @@ impl JobManager {
self.new_cursor_pos = (self.length / rows) * rows; self.new_cursor_pos = (self.length / rows) * rows;
} }
} }
PageMovement::Right(_) | PageMovement::Left(_) => {} PageMovement::Right(amount) => {
self.data_columns.x_offset += amount;
self.data_columns.x_offset = self.data_columns.x_offset.min(
self.data_columns
.widths
.iter()
.map(|w| w + 2)
.sum::<usize>()
.saturating_sub(2),
);
}
PageMovement::Left(amount) => {
self.data_columns.x_offset = self.data_columns.x_offset.saturating_sub(amount);
}
PageMovement::Home => { PageMovement::Home => {
self.new_cursor_pos = 0; self.new_cursor_pos = 0;
} }
@ -320,8 +375,8 @@ impl JobManager {
))); )));
} }
/* If cursor position has changed, remove the highlight from the previous // If cursor position has changed, remove the highlight from the previous
* position and apply it in the new one. */ // position and apply it in the new one.
if self.cursor_pos != self.new_cursor_pos && prev_page_no == page_no { if self.cursor_pos != self.new_cursor_pos && prev_page_no == page_no {
let old_cursor_pos = self.cursor_pos; let old_cursor_pos = self.cursor_pos;
self.cursor_pos = self.new_cursor_pos; self.cursor_pos = self.new_cursor_pos;
@ -348,27 +403,21 @@ impl JobManager {
self.new_cursor_pos = self.length - 1; self.new_cursor_pos = self.length - 1;
self.cursor_pos = self.new_cursor_pos; self.cursor_pos = self.new_cursor_pos;
} }
/* Page_no has changed, so draw new page */ // Page_no has changed, so draw new page
_ = self _ = self
.data_columns .data_columns
.recalc_widths((area.width(), area.height()), top_idx); .recalc_widths((area.width(), area.height()), top_idx);
grid.clear_area(area, self.theme_default); grid.clear_area(area, self.theme_default);
/* copy table columns */ // copy table columns
self.data_columns self.data_columns
.draw(grid, top_idx, self.cursor_pos, grid.bounds_iter(area)); .draw(grid, top_idx, self.cursor_pos, grid.bounds_iter(area));
/* highlight cursor */ // highlight cursor
grid.change_theme(area.nth_row(self.cursor_pos % rows), self.highlight_theme); grid.change_theme(area.nth_row(self.cursor_pos % rows), self.highlight_theme);
/* clear gap if available height is more than count of entries */ // clear gap if available height is more than count of entries
if top_idx + rows > self.length { if top_idx + rows > self.length {
grid.clear_area( grid.change_theme(area.skip_rows(self.length - top_idx), self.theme_default);
(
pos_inc(upper_left, (0, self.length - top_idx)),
bottom_right,
),
self.theme_default,
);
} }
context.dirty_areas.push_back(area); context.dirty_areas.push_back(area);
} }
@ -382,45 +431,43 @@ impl Component for JobManager {
if !self.initialized { if !self.initialized {
self.initialize(context); self.initialize(context);
} }
let area = area.nth_row(0); if self.dirty {
// Draw column headers. let area = area.nth_row(0);
grid.clear_area(area, self.theme_default); // Draw column headers.
let mut x_offset = 0; grid.clear_area(area, self.theme_default);
let (upper_left, bottom_right) = area; let mut x_offset = 0;
for (i, (h, w)) in Self::HEADERS.iter().zip(self.min_width).enumerate() { for (i, (h, w)) in Self::HEADERS.iter().zip(self.min_width).enumerate() {
grid.write_string(
h,
self.theme_default.fg,
self.theme_default.bg,
self.theme_default.attrs | Attr::BOLD,
(pos_inc(upper_left, (x_offset, 0)), bottom_right),
None,
);
if self.sort_col as usize == i {
use SortOrder::*;
let arrow = match (grid.ascii_drawing, self.sort_order) {
(true, Asc) => DataColumns::<5>::ARROW_UP_ASCII,
(true, Desc) => DataColumns::<5>::ARROW_DOWN_ASCII,
(false, Asc) => DataColumns::<5>::ARROW_UP,
(false, Desc) => DataColumns::<5>::ARROW_DOWN,
};
grid.write_string( grid.write_string(
arrow, h,
self.theme_default.fg, self.theme_default.fg,
self.theme_default.bg, self.theme_default.bg,
self.theme_default.attrs, self.theme_default.attrs | Attr::BOLD,
(pos_inc(upper_left, (x_offset + h.len(), 0)), bottom_right), area.skip_cols(x_offset),
None, None,
); );
if self.sort_col as usize == i {
use SortOrder::*;
let arrow = match (grid.ascii_drawing, self.sort_order) {
(true, Asc) => DataColumns::<5>::ARROW_UP_ASCII,
(true, Desc) => DataColumns::<5>::ARROW_DOWN_ASCII,
(false, Asc) => DataColumns::<5>::ARROW_UP,
(false, Desc) => DataColumns::<5>::ARROW_DOWN,
};
grid.write_string(
arrow,
self.theme_default.fg,
self.theme_default.bg,
self.theme_default.attrs,
area.skip_cols(x_offset + h.len()),
None,
);
}
x_offset += w + 2;
} }
x_offset += w + 2; context.dirty_areas.push_back(area);
} }
context.dirty_areas.push_back(area);
// Draw entry rows. self.draw_list(grid, area.skip_rows(1), context);
if let Some(area) = area.skip_rows(1) {
self.draw_list(grid, area, context);
}
self.dirty = false; self.dirty = false;
} }

@ -88,8 +88,8 @@ pub mod notifications;
//pub mod mailbox_management; //pub mod mailbox_management;
//pub use mailbox_management::*; //pub use mailbox_management::*;
//pub mod jobs_view; pub mod jobs_view;
//pub use jobs_view::*; pub use jobs_view::*;
#[cfg(feature = "svgscreenshot")] #[cfg(feature = "svgscreenshot")]
pub mod svg; pub mod svg;

@ -2302,10 +2302,10 @@ impl Component for Listing {
return true; return true;
} }
UIEvent::Action(Action::Tab(ManageJobs)) => { UIEvent::Action(Action::Tab(ManageJobs)) => {
//let mgr = JobManager::new(context); let mgr = JobManager::new(context);
//context context
// .replies .replies
// .push_back(UIEvent::Action(Tab(New(Some(Box::new(mgr)))))); .push_back(UIEvent::Action(Tab(New(Some(Box::new(mgr))))));
return true; return true;
} }
UIEvent::Action(Action::Compose(ComposeAction::Mailto(ref mailto))) => { UIEvent::Action(Action::Compose(ComposeAction::Mailto(ref mailto))) => {

Loading…
Cancel
Save