mirror of
https://git.meli.delivery/meli/meli
synced 2024-11-10 19:10:57 +00:00
mail/composer: add scrollbars
This commit is contained in:
parent
1e7b40e6b3
commit
3949cecb75
@ -642,7 +642,7 @@ impl Component for ContactList {
|
|||||||
let mut draft: Draft = Draft::default();
|
let mut draft: Draft = Draft::default();
|
||||||
*draft.headers_mut().get_mut("To").unwrap() =
|
*draft.headers_mut().get_mut("To").unwrap() =
|
||||||
format!("{} <{}>", &card.name(), &card.email());
|
format!("{} <{}>", &card.name(), &card.email());
|
||||||
let mut composer = Composer::new(account_hash, context);
|
let mut composer = Composer::with_account(account_hash, context);
|
||||||
composer.set_draft(draft);
|
composer.set_draft(draft);
|
||||||
context
|
context
|
||||||
.replies
|
.replies
|
||||||
|
@ -98,33 +98,6 @@ pub struct Composer {
|
|||||||
id: ComponentId,
|
id: ComponentId,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Composer {
|
|
||||||
fn default() -> Self {
|
|
||||||
let mut pager = Pager::default();
|
|
||||||
pager.set_reflow(text_processing::Reflow::FormatFlowed);
|
|
||||||
Composer {
|
|
||||||
reply_context: None,
|
|
||||||
account_hash: 0,
|
|
||||||
|
|
||||||
cursor: Cursor::Headers,
|
|
||||||
|
|
||||||
pager,
|
|
||||||
draft: Draft::default(),
|
|
||||||
form: FormWidget::default(),
|
|
||||||
|
|
||||||
mode: ViewMode::Edit,
|
|
||||||
#[cfg(feature = "gpgme")]
|
|
||||||
gpg_state: gpg::GpgComposeState::new(),
|
|
||||||
dirty: true,
|
|
||||||
has_changes: false,
|
|
||||||
embed_area: ((0, 0), (0, 0)),
|
|
||||||
embed: None,
|
|
||||||
initialized: false,
|
|
||||||
id: ComponentId::new_v4(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum ViewMode {
|
enum ViewMode {
|
||||||
Discard(Uuid, UIDialog<char>),
|
Discard(Uuid, UIDialog<char>),
|
||||||
@ -174,11 +147,32 @@ impl fmt::Display for Composer {
|
|||||||
|
|
||||||
impl Composer {
|
impl Composer {
|
||||||
const DESCRIPTION: &'static str = "composing";
|
const DESCRIPTION: &'static str = "composing";
|
||||||
pub fn new(account_hash: AccountHash, context: &Context) -> Self {
|
pub fn new(context: &Context) -> Self {
|
||||||
|
let mut pager = Pager::new(context);
|
||||||
|
pager.set_show_scrollbar(true);
|
||||||
|
Composer {
|
||||||
|
reply_context: None,
|
||||||
|
account_hash: 0,
|
||||||
|
cursor: Cursor::Headers,
|
||||||
|
pager,
|
||||||
|
draft: Draft::default(),
|
||||||
|
form: FormWidget::default(),
|
||||||
|
mode: ViewMode::Edit,
|
||||||
|
#[cfg(feature = "gpgme")]
|
||||||
|
gpg_state: gpg::GpgComposeState::new(),
|
||||||
|
dirty: true,
|
||||||
|
has_changes: false,
|
||||||
|
embed_area: ((0, 0), (0, 0)),
|
||||||
|
embed: None,
|
||||||
|
initialized: false,
|
||||||
|
id: ComponentId::new_v4(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_account(account_hash: AccountHash, context: &Context) -> Self {
|
||||||
let mut ret = Composer {
|
let mut ret = Composer {
|
||||||
account_hash,
|
account_hash,
|
||||||
id: ComponentId::new_v4(),
|
..Composer::new(context)
|
||||||
..Default::default()
|
|
||||||
};
|
};
|
||||||
for (h, v) in
|
for (h, v) in
|
||||||
account_settings!(context[account_hash].composing.default_header_values).iter()
|
account_settings!(context[account_hash].composing.default_header_values).iter()
|
||||||
@ -194,8 +188,6 @@ impl Composer {
|
|||||||
format!("meli {}", option_env!("CARGO_PKG_VERSION").unwrap_or("0.0")),
|
format!("meli {}", option_env!("CARGO_PKG_VERSION").unwrap_or("0.0")),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
ret.pager
|
|
||||||
.set_colors(crate::conf::value(context, "theme_default"));
|
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,7 +197,7 @@ impl Composer {
|
|||||||
bytes: &[u8],
|
bytes: &[u8],
|
||||||
context: &Context,
|
context: &Context,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let mut ret = Composer::default();
|
let mut ret = Composer::with_account(account_hash, context);
|
||||||
let envelope: EnvelopeRef = context.accounts[&account_hash].collection.get_env(env_hash);
|
let envelope: EnvelopeRef = context.accounts[&account_hash].collection.get_env(env_hash);
|
||||||
|
|
||||||
ret.draft = Draft::edit(&envelope, bytes)?;
|
ret.draft = Draft::edit(&envelope, bytes)?;
|
||||||
@ -220,7 +212,7 @@ impl Composer {
|
|||||||
context: &mut Context,
|
context: &mut Context,
|
||||||
reply_to_all: bool,
|
reply_to_all: bool,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut ret = Composer::new(coordinates.0, context);
|
let mut ret = Composer::with_account(coordinates.0, context);
|
||||||
let account = &context.accounts[&coordinates.0];
|
let account = &context.accounts[&coordinates.0];
|
||||||
let envelope = account.collection.get_env(coordinates.2);
|
let envelope = account.collection.get_env(coordinates.2);
|
||||||
let subject = envelope.subject();
|
let subject = envelope.subject();
|
||||||
@ -676,8 +668,8 @@ impl Component for Composer {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let body_area = (
|
let body_area = (
|
||||||
pos_inc(upper_left, (mid + 1, header_height + 1)),
|
pos_inc(upper_left, (mid, header_height + 1)),
|
||||||
pos_dec(bottom_right, (mid, 4 + attachments_no)),
|
pos_dec(bottom_right, (mid, 5 + attachments_no)),
|
||||||
);
|
);
|
||||||
|
|
||||||
let (x, y) = write_string_to_grid(
|
let (x, y) = write_string_to_grid(
|
||||||
@ -763,13 +755,24 @@ impl Component for Composer {
|
|||||||
self.embed_area = (upper_left!(header_area), bottom_right!(body_area));
|
self.embed_area = (upper_left!(header_area), bottom_right!(body_area));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !self.mode.is_edit_attachments() {
|
||||||
|
self.pager.set_dirty(true);
|
||||||
|
if self.pager.size().0 > width!(body_area) {
|
||||||
|
self.pager.set_initialised(false);
|
||||||
|
}
|
||||||
|
self.pager.draw(grid, body_area, context);
|
||||||
|
}
|
||||||
|
|
||||||
match self.cursor {
|
match self.cursor {
|
||||||
Cursor::Headers => {
|
Cursor::Headers => {
|
||||||
change_colors(
|
change_colors(
|
||||||
grid,
|
grid,
|
||||||
(
|
(
|
||||||
set_y(upper_left!(body_area), get_y(bottom_right!(body_area))),
|
pos_dec(upper_left!(body_area), (1, 0)),
|
||||||
bottom_right!(body_area),
|
pos_dec(
|
||||||
|
set_y(upper_left!(body_area), get_y(bottom_right!(body_area))),
|
||||||
|
(1, 0),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
theme_default.fg,
|
theme_default.fg,
|
||||||
theme_default.bg,
|
theme_default.bg,
|
||||||
@ -779,8 +782,11 @@ impl Component for Composer {
|
|||||||
change_colors(
|
change_colors(
|
||||||
grid,
|
grid,
|
||||||
(
|
(
|
||||||
set_y(upper_left!(body_area), get_y(bottom_right!(body_area))),
|
pos_dec(upper_left!(body_area), (1, 0)),
|
||||||
bottom_right!(body_area),
|
pos_dec(
|
||||||
|
set_y(upper_left!(body_area), get_y(bottom_right!(body_area))),
|
||||||
|
(1, 0),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
theme_default.fg,
|
theme_default.fg,
|
||||||
Color::Byte(237),
|
Color::Byte(237),
|
||||||
@ -789,11 +795,6 @@ impl Component for Composer {
|
|||||||
Cursor::Sign | Cursor::Encrypt | Cursor::Attachments => {}
|
Cursor::Sign | Cursor::Encrypt | Cursor::Attachments => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.mode.is_edit_attachments() {
|
|
||||||
self.pager.set_dirty(true);
|
|
||||||
self.pager.draw(grid, body_area, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
match self.mode {
|
match self.mode {
|
||||||
ViewMode::Edit | ViewMode::Embed => {}
|
ViewMode::Edit | ViewMode::Embed => {}
|
||||||
ViewMode::EditAttachments { ref mut widget } => {
|
ViewMode::EditAttachments { ref mut widget } => {
|
||||||
|
@ -1211,7 +1211,7 @@ impl Component for Listing {
|
|||||||
if shortcut!(k == shortcuts[Listing::DESCRIPTION]["new_mail"]) =>
|
if shortcut!(k == shortcuts[Listing::DESCRIPTION]["new_mail"]) =>
|
||||||
{
|
{
|
||||||
let account_hash = context.accounts[self.cursor_pos.0].hash();
|
let account_hash = context.accounts[self.cursor_pos.0].hash();
|
||||||
let composer = Composer::new(account_hash, context);
|
let composer = Composer::with_account(account_hash, context);
|
||||||
context
|
context
|
||||||
.replies
|
.replies
|
||||||
.push_back(UIEvent::Action(Tab(New(Some(Box::new(composer))))));
|
.push_back(UIEvent::Action(Tab(New(Some(Box::new(composer))))));
|
||||||
|
@ -2143,7 +2143,8 @@ impl Component for MailView {
|
|||||||
{
|
{
|
||||||
if let Ok(mailto) = Mailto::try_from(list_post_addr) {
|
if let Ok(mailto) = Mailto::try_from(list_post_addr) {
|
||||||
let draft: Draft = mailto.into();
|
let draft: Draft = mailto.into();
|
||||||
let mut composer = Composer::new(self.coordinates.0, context);
|
let mut composer =
|
||||||
|
Composer::with_account(self.coordinates.0, context);
|
||||||
composer.set_draft(draft);
|
composer.set_draft(draft);
|
||||||
context.replies.push_back(UIEvent::Action(Tab(New(Some(
|
context.replies.push_back(UIEvent::Action(Tab(New(Some(
|
||||||
Box::new(composer),
|
Box::new(composer),
|
||||||
|
@ -570,8 +570,7 @@ impl ThreadView {
|
|||||||
|
|
||||||
self.highlight_line(grid, dest_area, src_area, idx);
|
self.highlight_line(grid, dest_area, src_area, idx);
|
||||||
if rows < visibles.len() {
|
if rows < visibles.len() {
|
||||||
ScrollBar::draw(
|
ScrollBar::default().draw(
|
||||||
ScrollBar::default(),
|
|
||||||
grid,
|
grid,
|
||||||
(
|
(
|
||||||
upper_left!(area),
|
upper_left!(area),
|
||||||
@ -624,8 +623,7 @@ impl ThreadView {
|
|||||||
|
|
||||||
self.highlight_line(grid, dest_area, src_area, entry_idx);
|
self.highlight_line(grid, dest_area, src_area, entry_idx);
|
||||||
if rows < visibles.len() {
|
if rows < visibles.len() {
|
||||||
ScrollBar::draw(
|
ScrollBar::default().draw(
|
||||||
ScrollBar::default(),
|
|
||||||
grid,
|
grid,
|
||||||
(
|
(
|
||||||
upper_left!(area),
|
upper_left!(area),
|
||||||
|
@ -316,10 +316,7 @@ impl Component for StatusBar {
|
|||||||
}
|
}
|
||||||
let hist_height = std::cmp::min(15, self.auto_complete.suggestions().len());
|
let hist_height = std::cmp::min(15, self.auto_complete.suggestions().len());
|
||||||
let hist_area = if height < self.auto_complete.suggestions().len() {
|
let hist_area = if height < self.auto_complete.suggestions().len() {
|
||||||
let mut scrollbar = ScrollBar::default();
|
ScrollBar::default().set_show_arrows(false).draw(
|
||||||
scrollbar.set_show_arrows(false);
|
|
||||||
scrollbar.set_block_character(Some('▌'));
|
|
||||||
scrollbar.draw(
|
|
||||||
grid,
|
grid,
|
||||||
(
|
(
|
||||||
(
|
(
|
||||||
|
@ -37,6 +37,7 @@ pub struct Pager {
|
|||||||
|
|
||||||
colors: ThemeAttribute,
|
colors: ThemeAttribute,
|
||||||
initialised: bool,
|
initialised: bool,
|
||||||
|
show_scrollbar: bool,
|
||||||
content: CellBuffer,
|
content: CellBuffer,
|
||||||
text_lines: (usize, Vec<String>),
|
text_lines: (usize, Vec<String>),
|
||||||
movement: Option<PageMovement>,
|
movement: Option<PageMovement>,
|
||||||
@ -51,6 +52,23 @@ impl fmt::Display for Pager {
|
|||||||
|
|
||||||
impl Pager {
|
impl Pager {
|
||||||
pub const DESCRIPTION: &'static str = "pager";
|
pub const DESCRIPTION: &'static str = "pager";
|
||||||
|
pub fn new(context: &Context) -> Self {
|
||||||
|
let mut ret = Pager::default();
|
||||||
|
ret.minimum_width = context.settings.pager.minimum_width;
|
||||||
|
ret.set_colors(crate::conf::value(context, "theme_default"))
|
||||||
|
.set_reflow(if context.settings.pager.split_long_lines {
|
||||||
|
Reflow::All
|
||||||
|
} else {
|
||||||
|
Reflow::No
|
||||||
|
});
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_show_scrollbar(&mut self, new_val: bool) -> &mut Self {
|
||||||
|
self.show_scrollbar = new_val;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_colors(&mut self, new_val: ThemeAttribute) -> &mut Self {
|
pub fn set_colors(&mut self, new_val: ThemeAttribute) -> &mut Self {
|
||||||
self.colors = new_val;
|
self.colors = new_val;
|
||||||
self
|
self
|
||||||
@ -61,6 +79,11 @@ impl Pager {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_initialised(&mut self, new_val: bool) -> &mut Self {
|
||||||
|
self.initialised = new_val;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn reflow(&self) -> Reflow {
|
pub fn reflow(&self) -> Reflow {
|
||||||
self.reflow
|
self.reflow
|
||||||
}
|
}
|
||||||
@ -264,13 +287,13 @@ impl Component for Pager {
|
|||||||
width = self.minimum_width;
|
width = self.minimum_width;
|
||||||
}
|
}
|
||||||
|
|
||||||
let lines: &[String] = if self.text_lines.0 == width.saturating_sub(2) {
|
let lines: &[String] = if self.text_lines.0 == width.saturating_sub(4) {
|
||||||
&self.text_lines.1
|
&self.text_lines.1
|
||||||
} else {
|
} else {
|
||||||
let lines = self
|
let lines = self
|
||||||
.text
|
.text
|
||||||
.split_lines_reflow(self.reflow, Some(width.saturating_sub(2)));
|
.split_lines_reflow(self.reflow, Some(width.saturating_sub(4)));
|
||||||
self.text_lines = (width.saturating_sub(2), lines);
|
self.text_lines = (width.saturating_sub(4), lines);
|
||||||
&self.text_lines.1
|
&self.text_lines.1
|
||||||
};
|
};
|
||||||
let height = lines.len() + 2;
|
let height = lines.len() + 2;
|
||||||
@ -344,30 +367,36 @@ impl Component for Pager {
|
|||||||
self.cursor.1 = self.cursor.1.saturating_sub(height * multiplier);
|
self.cursor.1 = self.cursor.1.saturating_sub(height * multiplier);
|
||||||
}
|
}
|
||||||
PageMovement::Down(amount) => {
|
PageMovement::Down(amount) => {
|
||||||
if self.cursor.1 + amount < self.height {
|
if self.cursor.1 + amount + 1 < self.height {
|
||||||
self.cursor.1 += amount;
|
self.cursor.1 += amount;
|
||||||
|
} else {
|
||||||
|
self.cursor.1 = self.height.saturating_sub(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PageMovement::PageDown(multiplier) => {
|
PageMovement::PageDown(multiplier) => {
|
||||||
if self.cursor.1 + height * multiplier < self.height {
|
if self.cursor.1 + height * multiplier + 1 < self.height {
|
||||||
self.cursor.1 += height * multiplier;
|
self.cursor.1 += height * multiplier;
|
||||||
|
} else if self.cursor.1 + height * multiplier > self.height {
|
||||||
|
self.cursor.1 = self.height - 1;
|
||||||
|
} else {
|
||||||
|
self.cursor.1 = (self.height / height) * height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PageMovement::Right(multiplier) => {
|
PageMovement::Right(amount) => {
|
||||||
let offset = width!(area) / 3;
|
if self.cursor.0 + amount + 1 < self.width {
|
||||||
if self.cursor.0 + offset * multiplier < self.content.size().0 {
|
self.cursor.0 += amount;
|
||||||
self.cursor.0 += offset * multiplier;
|
} else {
|
||||||
|
self.cursor.0 = self.width.saturating_sub(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PageMovement::Left(multiplier) => {
|
PageMovement::Left(amount) => {
|
||||||
let offset = width!(area) / 3;
|
self.cursor.0 = self.cursor.0.saturating_sub(amount);
|
||||||
self.cursor.0 = self.cursor.0.saturating_sub(offset * multiplier);
|
|
||||||
}
|
}
|
||||||
PageMovement::Home => {
|
PageMovement::Home => {
|
||||||
self.cursor.1 = 0;
|
self.cursor.1 = 0;
|
||||||
}
|
}
|
||||||
PageMovement::End => {
|
PageMovement::End => {
|
||||||
self.cursor.1 = (self.height / height) * height;
|
self.cursor.1 = self.height.saturating_sub(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -397,7 +426,13 @@ impl Component for Pager {
|
|||||||
|
|
||||||
clear_area(grid, area, crate::conf::value(context, "theme_default"));
|
clear_area(grid, area, crate::conf::value(context, "theme_default"));
|
||||||
let (width, height) = self.content.size();
|
let (width, height) = self.content.size();
|
||||||
let (cols, rows) = (width!(area), height!(area));
|
let (mut cols, mut rows) = (width!(area), height!(area));
|
||||||
|
if self.show_scrollbar && rows < height {
|
||||||
|
cols -= 1;
|
||||||
|
}
|
||||||
|
if self.show_scrollbar && cols < width {
|
||||||
|
rows -= 1;
|
||||||
|
}
|
||||||
self.cursor = (
|
self.cursor = (
|
||||||
std::cmp::min(width.saturating_sub(cols), self.cursor.0),
|
std::cmp::min(width.saturating_sub(cols), self.cursor.0),
|
||||||
std::cmp::min(height.saturating_sub(rows), self.cursor.1),
|
std::cmp::min(height.saturating_sub(rows), self.cursor.1),
|
||||||
@ -417,6 +452,32 @@ impl Component for Pager {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
if self.show_scrollbar && rows + 1 < height {
|
||||||
|
ScrollBar::default().set_show_arrows(true).draw(
|
||||||
|
grid,
|
||||||
|
(
|
||||||
|
set_x(upper_left!(area), get_x(bottom_right!(area))),
|
||||||
|
bottom_right!(area),
|
||||||
|
),
|
||||||
|
context,
|
||||||
|
self.cursor.1,
|
||||||
|
rows,
|
||||||
|
height,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if self.show_scrollbar && cols + 1 < width {
|
||||||
|
ScrollBar::default().set_show_arrows(true).draw_horizontal(
|
||||||
|
grid,
|
||||||
|
(
|
||||||
|
set_y(upper_left!(area), get_y(bottom_right!(area))),
|
||||||
|
bottom_right!(area),
|
||||||
|
),
|
||||||
|
context,
|
||||||
|
self.cursor.0,
|
||||||
|
cols,
|
||||||
|
width,
|
||||||
|
);
|
||||||
|
}
|
||||||
context.dirty_areas.push_back(area);
|
context.dirty_areas.push_back(area);
|
||||||
}
|
}
|
||||||
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
fn process_event(&mut self, event: &mut UIEvent, context: &mut Context) -> bool {
|
||||||
|
@ -980,19 +980,17 @@ impl AutoComplete {
|
|||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct ScrollBar {
|
pub struct ScrollBar {
|
||||||
show_arrows: bool,
|
pub show_arrows: bool,
|
||||||
block_character: Option<char>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ScrollBar {
|
impl ScrollBar {
|
||||||
pub fn set_show_arrows(&mut self, flag: bool) {
|
pub fn set_show_arrows(&mut self, new_val: bool) -> &mut Self {
|
||||||
self.show_arrows = flag;
|
self.show_arrows = new_val;
|
||||||
}
|
self
|
||||||
pub fn set_block_character(&mut self, val: Option<char>) {
|
|
||||||
self.block_character = val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw(
|
pub fn draw(
|
||||||
self,
|
&mut self,
|
||||||
grid: &mut CellBuffer,
|
grid: &mut CellBuffer,
|
||||||
area: Area,
|
area: Area,
|
||||||
context: &Context,
|
context: &Context,
|
||||||
@ -1007,17 +1005,17 @@ impl ScrollBar {
|
|||||||
if height < 3 {
|
if height < 3 {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if self.show_arrows {
|
|
||||||
height -= height;
|
|
||||||
}
|
|
||||||
clear_area(grid, area, crate::conf::value(context, "theme_default"));
|
clear_area(grid, area, crate::conf::value(context, "theme_default"));
|
||||||
|
|
||||||
let visible_ratio: f32 = (std::cmp::min(visible_rows, length) as f32) / (length as f32);
|
let visible_ratio: f32 = (std::cmp::min(visible_rows, length) as f32) / (length as f32);
|
||||||
let scrollbar_height = std::cmp::max((visible_ratio * (height as f32)) as usize, 1);
|
let scrollbar_height = std::cmp::max((visible_ratio * (height as f32)) as usize, 1);
|
||||||
|
if self.show_arrows {
|
||||||
|
height -= 3;
|
||||||
|
}
|
||||||
let scrollbar_offset = {
|
let scrollbar_offset = {
|
||||||
let temp = (((pos as f32) / (length as f32)) * (height as f32)) as usize;
|
let temp = (((pos as f32) / (length as f32)) * (height as f32)) as usize;
|
||||||
if temp + scrollbar_height >= height {
|
if scrollbar_height + temp > height {
|
||||||
height - scrollbar_height
|
height.saturating_sub(scrollbar_height)
|
||||||
} else {
|
} else {
|
||||||
temp
|
temp
|
||||||
}
|
}
|
||||||
@ -1025,24 +1023,77 @@ impl ScrollBar {
|
|||||||
let (mut upper_left, bottom_right) = area;
|
let (mut upper_left, bottom_right) = area;
|
||||||
|
|
||||||
if self.show_arrows {
|
if self.show_arrows {
|
||||||
grid[upper_left].set_ch('▴');
|
grid[upper_left]
|
||||||
upper_left = (upper_left.0, upper_left.1 + 1);
|
.set_ch('▄')
|
||||||
|
.set_fg(crate::conf::value(context, "widgets.options.highlighted").bg);
|
||||||
|
upper_left = pos_inc(upper_left, (0, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
for y in get_y(upper_left)..(get_y(upper_left) + scrollbar_offset) {
|
upper_left = pos_inc(upper_left, (0, scrollbar_offset));
|
||||||
grid[set_y(upper_left, y)].set_ch(' ');
|
for _ in 0..=scrollbar_height {
|
||||||
}
|
grid[upper_left].set_bg(crate::conf::value(context, "widgets.options.highlighted").bg);
|
||||||
for y in (get_y(upper_left) + scrollbar_offset)
|
upper_left = pos_inc(upper_left, (0, 1));
|
||||||
..=(get_y(upper_left) + scrollbar_offset + scrollbar_height)
|
|
||||||
{
|
|
||||||
grid[set_y(upper_left, y)].set_ch(self.block_character.unwrap_or('█'));
|
|
||||||
}
|
|
||||||
for y in (get_y(upper_left) + scrollbar_offset + scrollbar_height + 1)..get_y(bottom_right)
|
|
||||||
{
|
|
||||||
grid[set_y(upper_left, y)].set_ch(' ');
|
|
||||||
}
|
}
|
||||||
if self.show_arrows {
|
if self.show_arrows {
|
||||||
grid[set_x(bottom_right, get_x(upper_left))].set_ch('▾');
|
grid[pos_dec(bottom_right, (0, 1))]
|
||||||
|
.set_ch('▀')
|
||||||
|
.set_fg(crate::conf::value(context, "widgets.options.highlighted").bg)
|
||||||
|
.set_bg(crate::conf::value(context, "theme_default").bg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw_horizontal(
|
||||||
|
&mut self,
|
||||||
|
grid: &mut CellBuffer,
|
||||||
|
area: Area,
|
||||||
|
context: &Context,
|
||||||
|
pos: usize,
|
||||||
|
visible_cols: usize,
|
||||||
|
length: usize,
|
||||||
|
) {
|
||||||
|
if length == 0 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let mut width = width!(area);
|
||||||
|
if width < 3 {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
clear_area(grid, area, crate::conf::value(context, "theme_default"));
|
||||||
|
|
||||||
|
let visible_ratio: f32 = (std::cmp::min(visible_cols, length) as f32) / (length as f32);
|
||||||
|
let scrollbar_width = std::cmp::max((visible_ratio * (width as f32)) as usize, 1);
|
||||||
|
if self.show_arrows {
|
||||||
|
width -= 3;
|
||||||
|
}
|
||||||
|
let scrollbar_offset = {
|
||||||
|
let temp = (((pos as f32) / (length as f32)) * (width as f32)) as usize;
|
||||||
|
if scrollbar_width + temp > width {
|
||||||
|
width.saturating_sub(scrollbar_width)
|
||||||
|
} else {
|
||||||
|
temp
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let (mut upper_left, bottom_right) = area;
|
||||||
|
|
||||||
|
if self.show_arrows {
|
||||||
|
grid[upper_left]
|
||||||
|
.set_ch('▐')
|
||||||
|
.set_fg(crate::conf::value(context, "widgets.options.highlighted").bg);
|
||||||
|
upper_left = pos_inc(upper_left, (1, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
upper_left = pos_inc(upper_left, (scrollbar_offset, 0));
|
||||||
|
for _ in 0..=scrollbar_width {
|
||||||
|
grid[upper_left]
|
||||||
|
.set_ch('█')
|
||||||
|
.set_fg(crate::conf::value(context, "widgets.options.highlighted").bg);
|
||||||
|
upper_left = pos_inc(upper_left, (1, 0));
|
||||||
|
}
|
||||||
|
if self.show_arrows {
|
||||||
|
grid[pos_dec(bottom_right, (1, 0))]
|
||||||
|
.set_ch('▌')
|
||||||
|
.set_fg(crate::conf::value(context, "widgets.options.highlighted").bg)
|
||||||
|
.set_bg(crate::conf::value(context, "theme_default").bg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user