ui: move box drawing to src/terminal
No logical reason for it not to be in the terminal module anymore (the set_and_join* functions predate the terminal module which is why they weren't there to begin with).async
parent
f131e01bfc
commit
d6e3c51b07
|
@ -27,6 +27,7 @@
|
|||
|
||||
use super::*;
|
||||
use crate::melib::text_processing::{TextProcessing, Truncate};
|
||||
use crate::terminal::boundaries::*;
|
||||
|
||||
pub mod mail;
|
||||
pub use crate::mail::*;
|
||||
|
@ -46,32 +47,6 @@ use fnv::FnvHashMap;
|
|||
use uuid::Uuid;
|
||||
|
||||
use super::{Key, StatusEvent, UIEvent};
|
||||
/// The upper and lower boundary char.
|
||||
const HORZ_BOUNDARY: char = 'β';
|
||||
/// The left and right boundary char.
|
||||
const VERT_BOUNDARY: char = 'β';
|
||||
|
||||
/// The top-left corner
|
||||
const _TOP_LEFT_CORNER: char = 'β';
|
||||
/// The top-right corner
|
||||
const _TOP_RIGHT_CORNER: char = 'β';
|
||||
/// The bottom-left corner
|
||||
const _BOTTOM_LEFT_CORNER: char = 'β';
|
||||
/// The bottom-right corner
|
||||
const _BOTTOM_RIGHT_CORNER: char = 'β';
|
||||
|
||||
const LIGHT_VERTICAL_AND_RIGHT: char = 'β';
|
||||
|
||||
const _LIGHT_VERTICAL_AND_LEFT: char = 'β€';
|
||||
|
||||
const LIGHT_DOWN_AND_HORIZONTAL: char = 'β¬';
|
||||
|
||||
const LIGHT_UP_AND_HORIZONTAL: char = 'β΄';
|
||||
|
||||
const _DOUBLE_DOWN_AND_RIGHT: char = 'β';
|
||||
const _DOUBLE_DOWN_AND_LEFT: char = 'β';
|
||||
const _DOUBLE_UP_AND_LEFT: char = 'β';
|
||||
const _DOUBLE_UP_AND_RIGHT: char = 'β';
|
||||
|
||||
type ComponentId = Uuid;
|
||||
|
||||
|
@ -104,312 +79,3 @@ pub trait Component: Display + Debug + Send {
|
|||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn bin_to_ch(b: u32) -> char {
|
||||
match b {
|
||||
0b0001 => 'βΆ',
|
||||
0b0010 => 'β΅',
|
||||
0b0011 => 'β',
|
||||
0b0100 => 'β΄',
|
||||
0b0101 => 'β',
|
||||
0b0110 => 'β',
|
||||
0b0111 => 'β΄',
|
||||
0b1000 => 'β·',
|
||||
0b1001 => 'β',
|
||||
0b1010 => 'β',
|
||||
0b1011 => 'β',
|
||||
0b1100 => 'β',
|
||||
0b1101 => 'β¬',
|
||||
0b1110 => 'β€',
|
||||
0b1111 => 'βΌ',
|
||||
_ => unsafe { std::hint::unreachable_unchecked() },
|
||||
}
|
||||
}
|
||||
|
||||
fn ch_to_bin(ch: char) -> Option<u32> {
|
||||
match ch {
|
||||
'β' => Some(0b0011),
|
||||
'β' => Some(0b0101),
|
||||
'β' => Some(0b0110),
|
||||
'β΄' => Some(0b0111),
|
||||
'β' => Some(0b1001),
|
||||
|
||||
'β' => Some(0b1010),
|
||||
|
||||
'β' => Some(0b1011),
|
||||
'β' => Some(0b1100),
|
||||
'β¬' => Some(0b1101),
|
||||
|
||||
'β€' => Some(0b1110),
|
||||
|
||||
'βΌ' => Some(0b1111),
|
||||
'β·' => Some(0b1000),
|
||||
|
||||
'β΅' => Some(0b0010),
|
||||
'β΄' => Some(0b0100),
|
||||
'βΆ' => Some(0b0001),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::never_loop)]
|
||||
fn set_and_join_vert(grid: &mut CellBuffer, idx: Pos) -> u32 {
|
||||
let (x, y) = idx;
|
||||
let mut bin_set = 0b1010;
|
||||
/* Check left side
|
||||
*
|
||||
* 1
|
||||
* -> 2 β 0
|
||||
* 3
|
||||
*/
|
||||
loop {
|
||||
if x > 0 {
|
||||
if let Some(cell) = grid.get_mut(x - 1, y) {
|
||||
if let Some(adj) = ch_to_bin(cell.ch()) {
|
||||
if (adj & 0b0001) > 0 {
|
||||
bin_set |= 0b0100;
|
||||
break;
|
||||
} else if adj == 0b0100 {
|
||||
cell.set_ch(bin_to_ch(0b0101));
|
||||
cell.set_fg(Color::Byte(240));
|
||||
bin_set |= 0b0100;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
bin_set &= 0b1011;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check right side
|
||||
*
|
||||
* 1
|
||||
* 2 β 0 <-
|
||||
* 3
|
||||
*/
|
||||
loop {
|
||||
if let Some(cell) = grid.get_mut(x + 1, y) {
|
||||
if let Some(adj) = ch_to_bin(cell.ch()) {
|
||||
if (adj & 0b0100) > 0 {
|
||||
bin_set |= 0b0001;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
bin_set &= 0b1110;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set upper side
|
||||
*
|
||||
* 1 <-
|
||||
* 2 β 0
|
||||
* 3
|
||||
*/
|
||||
loop {
|
||||
if y > 0 {
|
||||
if let Some(cell) = grid.get_mut(x, y - 1) {
|
||||
if let Some(adj) = ch_to_bin(cell.ch()) {
|
||||
cell.set_ch(bin_to_ch(adj | 0b1000));
|
||||
cell.set_fg(Color::Byte(240));
|
||||
} else {
|
||||
bin_set &= 0b1101;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set bottom side
|
||||
*
|
||||
* 1
|
||||
* 2 β 0
|
||||
* 3 <-
|
||||
*/
|
||||
loop {
|
||||
if let Some(cell) = grid.get_mut(x, y + 1) {
|
||||
if let Some(adj) = ch_to_bin(cell.ch()) {
|
||||
cell.set_ch(bin_to_ch(adj | 0b0010));
|
||||
cell.set_fg(Color::Byte(240));
|
||||
} else {
|
||||
bin_set &= 0b0111;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if bin_set == 0 {
|
||||
bin_set = 0b1010;
|
||||
}
|
||||
|
||||
bin_set
|
||||
}
|
||||
|
||||
#[allow(clippy::never_loop)]
|
||||
fn set_and_join_horz(grid: &mut CellBuffer, idx: Pos) -> u32 {
|
||||
let (x, y) = idx;
|
||||
let mut bin_set = 0b0101;
|
||||
/* Check upper side
|
||||
*
|
||||
* 1 <-
|
||||
* 2 β 0
|
||||
* 3
|
||||
*/
|
||||
loop {
|
||||
if y > 0 {
|
||||
if let Some(cell) = grid.get_mut(x, y - 1) {
|
||||
if let Some(adj) = ch_to_bin(cell.ch()) {
|
||||
if (adj & 0b1000) > 0 {
|
||||
bin_set |= 0b0010;
|
||||
break;
|
||||
} else if adj == 0b0010 {
|
||||
bin_set |= 0b0010;
|
||||
cell.set_ch(bin_to_ch(0b1010));
|
||||
cell.set_fg(Color::Byte(240));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
bin_set &= 0b1101;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check bottom side
|
||||
*
|
||||
* 1
|
||||
* 2 β 0
|
||||
* 3 <-
|
||||
*/
|
||||
loop {
|
||||
if let Some(cell) = grid.get_mut(x, y + 1) {
|
||||
if let Some(adj) = ch_to_bin(cell.ch()) {
|
||||
if (adj & 0b0010) > 0 {
|
||||
bin_set |= 0b1000;
|
||||
break;
|
||||
} else if adj == 0b1000 {
|
||||
bin_set |= 0b1000;
|
||||
cell.set_ch(bin_to_ch(0b1010));
|
||||
cell.set_fg(Color::Byte(240));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
bin_set &= 0b0111;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set left side
|
||||
*
|
||||
* 1
|
||||
* -> 2 β 0
|
||||
* 3
|
||||
*/
|
||||
loop {
|
||||
if x > 0 {
|
||||
if let Some(cell) = grid.get_mut(x - 1, y) {
|
||||
if let Some(adj) = ch_to_bin(cell.ch()) {
|
||||
cell.set_ch(bin_to_ch(adj | 0b0001));
|
||||
cell.set_fg(Color::Byte(240));
|
||||
} else {
|
||||
bin_set &= 0b1011;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set right side
|
||||
*
|
||||
* 1
|
||||
* 2 β 0 <-
|
||||
* 3
|
||||
*/
|
||||
loop {
|
||||
if let Some(cell) = grid.get_mut(x + 1, y) {
|
||||
if let Some(adj) = ch_to_bin(cell.ch()) {
|
||||
cell.set_ch(bin_to_ch(adj | 0b0100));
|
||||
cell.set_fg(Color::Byte(240));
|
||||
} else {
|
||||
bin_set &= 0b1110;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if bin_set == 0 {
|
||||
bin_set = 0b0101;
|
||||
}
|
||||
|
||||
bin_set
|
||||
}
|
||||
|
||||
pub enum BoxBoundary {
|
||||
Horizontal,
|
||||
Vertical,
|
||||
}
|
||||
|
||||
pub(crate) fn set_and_join_box(grid: &mut CellBuffer, idx: Pos, ch: BoxBoundary) {
|
||||
/* Connected sides:
|
||||
*
|
||||
* 1
|
||||
* 2 c 0
|
||||
* 3
|
||||
*
|
||||
* #3210
|
||||
* 0b____
|
||||
*/
|
||||
|
||||
if grid.ascii_drawing {
|
||||
grid[idx].set_ch(match ch {
|
||||
BoxBoundary::Vertical => '|',
|
||||
BoxBoundary::Horizontal => '-',
|
||||
});
|
||||
|
||||
grid[idx].set_fg(Color::Byte(240));
|
||||
return;
|
||||
}
|
||||
|
||||
let bin_set = match ch {
|
||||
BoxBoundary::Vertical => set_and_join_vert(grid, idx),
|
||||
BoxBoundary::Horizontal => set_and_join_horz(grid, idx),
|
||||
};
|
||||
|
||||
grid[idx].set_ch(bin_to_ch(bin_set));
|
||||
grid[idx].set_fg(Color::Byte(240));
|
||||
}
|
||||
|
||||
pub fn create_box(grid: &mut CellBuffer, area: Area) {
|
||||
if !is_valid_area!(area) {
|
||||
return;
|
||||
}
|
||||
let upper_left = upper_left!(area);
|
||||
let bottom_right = bottom_right!(area);
|
||||
|
||||
if !grid.ascii_drawing {
|
||||
for x in get_x(upper_left)..get_x(bottom_right) {
|
||||
grid[(x, get_y(upper_left))].set_ch(HORZ_BOUNDARY);
|
||||
grid[(x, get_y(bottom_right))].set_ch(HORZ_BOUNDARY);
|
||||
grid[(x, get_y(bottom_right))].set_fg(Color::Byte(240));
|
||||
}
|
||||
|
||||
for y in get_y(upper_left)..get_y(bottom_right) {
|
||||
grid[(get_x(upper_left), y)].set_ch(VERT_BOUNDARY);
|
||||
grid[(get_x(bottom_right), y)].set_ch(VERT_BOUNDARY);
|
||||
grid[(get_x(bottom_right), y)].set_fg(Color::Byte(240));
|
||||
}
|
||||
set_and_join_box(grid, upper_left, BoxBoundary::Horizontal);
|
||||
set_and_join_box(
|
||||
grid,
|
||||
set_x(upper_left, get_x(bottom_right)),
|
||||
BoxBoundary::Horizontal,
|
||||
);
|
||||
set_and_join_box(
|
||||
grid,
|
||||
set_y(upper_left, get_y(bottom_right)),
|
||||
BoxBoundary::Vertical,
|
||||
);
|
||||
set_and_join_box(grid, bottom_right, BoxBoundary::Vertical);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1758,24 +1758,6 @@ pub fn clear_area(grid: &mut CellBuffer, area: Area) {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn center_area(area: Area, (width, height): (usize, usize)) -> Area {
|
||||
let mid_x = { std::cmp::max(width!(area) / 2, width / 2) - width / 2 };
|
||||
let mid_y = { std::cmp::max(height!(area) / 2, height / 2) - height / 2 };
|
||||
|
||||
let (upper_x, upper_y) = upper_left!(area);
|
||||
let (max_x, max_y) = bottom_right!(area);
|
||||
(
|
||||
(
|
||||
std::cmp::min(max_x, upper_x + mid_x),
|
||||
std::cmp::min(max_y, upper_y + mid_y),
|
||||
),
|
||||
(
|
||||
std::cmp::min(max_x, upper_x + mid_x + width),
|
||||
std::cmp::min(max_y, upper_y + mid_y + height),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
pub mod ansi {
|
||||
//! Create a `CellBuffer` from a string slice containing ANSI escape codes.
|
||||
use super::{Cell, CellBuffer, Color};
|
||||
|
@ -2065,3 +2047,374 @@ impl RowIterator {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub use boundaries::create_box;
|
||||
pub mod boundaries {
|
||||
use super::*;
|
||||
/// The upper and lower boundary char.
|
||||
pub(crate) const HORZ_BOUNDARY: char = 'β';
|
||||
/// The left and right boundary char.
|
||||
pub(crate) const VERT_BOUNDARY: char = 'β';
|
||||
|
||||
/// The top-left corner
|
||||
pub(crate) const _TOP_LEFT_CORNER: char = 'β';
|
||||
/// The top-right corner
|
||||
pub(crate) const _TOP_RIGHT_CORNER: char = 'β';
|
||||
/// The bottom-left corner
|
||||
pub(crate) const _BOTTOM_LEFT_CORNER: char = 'β';
|
||||
/// The bottom-right corner
|
||||
pub(crate) const _BOTTOM_RIGHT_CORNER: char = 'β';
|
||||
|
||||
pub(crate) const LIGHT_VERTICAL_AND_RIGHT: char = 'β';
|
||||
|
||||
pub(crate) const _LIGHT_VERTICAL_AND_LEFT: char = 'β€';
|
||||
|
||||
pub(crate) const LIGHT_DOWN_AND_HORIZONTAL: char = 'β¬';
|
||||
|
||||
pub(crate) const LIGHT_UP_AND_HORIZONTAL: char = 'β΄';
|
||||
|
||||
pub(crate) const _DOUBLE_DOWN_AND_RIGHT: char = 'β';
|
||||
pub(crate) const _DOUBLE_DOWN_AND_LEFT: char = 'β';
|
||||
pub(crate) const _DOUBLE_UP_AND_LEFT: char = 'β';
|
||||
pub(crate) const _DOUBLE_UP_AND_RIGHT: char = 'β';
|
||||
|
||||
fn bin_to_ch(b: u32) -> char {
|
||||
match b {
|
||||
0b0001 => 'βΆ',
|
||||
0b0010 => 'β΅',
|
||||
0b0011 => 'β',
|
||||
0b0100 => 'β΄',
|
||||
0b0101 => 'β',
|
||||
0b0110 => 'β',
|
||||
0b0111 => 'β΄',
|
||||
0b1000 => 'β·',
|
||||
0b1001 => 'β',
|
||||
0b1010 => 'β',
|
||||
0b1011 => 'β',
|
||||
0b1100 => 'β',
|
||||
0b1101 => 'β¬',
|
||||
0b1110 => 'β€',
|
||||
0b1111 => 'βΌ',
|
||||
_ => unsafe { std::hint::unreachable_unchecked() },
|
||||
}
|
||||
}
|
||||
|
||||
fn ch_to_bin(ch: char) -> Option<u32> {
|
||||
match ch {
|
||||
'β' => Some(0b0011),
|
||||
'β' => Some(0b0101),
|
||||
'β' => Some(0b0110),
|
||||
'β΄' => Some(0b0111),
|
||||
'β' => Some(0b1001),
|
||||
|
||||
'β' => Some(0b1010),
|
||||
|
||||
'β' => Some(0b1011),
|
||||
'β' => Some(0b1100),
|
||||
'β¬' => Some(0b1101),
|
||||
|
||||
'β€' => Some(0b1110),
|
||||
|
||||
'βΌ' => Some(0b1111),
|
||||
'β·' => Some(0b1000),
|
||||
|
||||
'β΅' => Some(0b0010),
|
||||
'β΄' => Some(0b0100),
|
||||
'βΆ' => Some(0b0001),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::never_loop)]
|
||||
fn set_and_join_vert(grid: &mut CellBuffer, idx: Pos) -> u32 {
|
||||
let (x, y) = idx;
|
||||
let mut bin_set = 0b1010;
|
||||
/* Check left side
|
||||
*
|
||||
* 1
|
||||
* -> 2 β 0
|
||||
* 3
|
||||
*/
|
||||
loop {
|
||||
if x > 0 {
|
||||
if let Some(cell) = grid.get_mut(x - 1, y) {
|
||||
if let Some(adj) = ch_to_bin(cell.ch()) {
|
||||
if (adj & 0b0001) > 0 {
|
||||
bin_set |= 0b0100;
|
||||
break;
|
||||
} else if adj == 0b0100 {
|
||||
cell.set_ch(bin_to_ch(0b0101));
|
||||
cell.set_fg(Color::Byte(240));
|
||||
bin_set |= 0b0100;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
bin_set &= 0b1011;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check right side
|
||||
*
|
||||
* 1
|
||||
* 2 β 0 <-
|
||||
* 3
|
||||
*/
|
||||
loop {
|
||||
if let Some(cell) = grid.get_mut(x + 1, y) {
|
||||
if let Some(adj) = ch_to_bin(cell.ch()) {
|
||||
if (adj & 0b0100) > 0 {
|
||||
bin_set |= 0b0001;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
bin_set &= 0b1110;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set upper side
|
||||
*
|
||||
* 1 <-
|
||||
* 2 β 0
|
||||
* 3
|
||||
*/
|
||||
loop {
|
||||
if y > 0 {
|
||||
if let Some(cell) = grid.get_mut(x, y - 1) {
|
||||
if let Some(adj) = ch_to_bin(cell.ch()) {
|
||||
cell.set_ch(bin_to_ch(adj | 0b1000));
|
||||
cell.set_fg(Color::Byte(240));
|
||||
} else {
|
||||
bin_set &= 0b1101;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set bottom side
|
||||
*
|
||||
* 1
|
||||
* 2 β 0
|
||||
* 3 <-
|
||||
*/
|
||||
loop {
|
||||
if let Some(cell) = grid.get_mut(x, y + 1) {
|
||||
if let Some(adj) = ch_to_bin(cell.ch()) {
|
||||
cell.set_ch(bin_to_ch(adj | 0b0010));
|
||||
cell.set_fg(Color::Byte(240));
|
||||
} else {
|
||||
bin_set &= 0b0111;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if bin_set == 0 {
|
||||
bin_set = 0b1010;
|
||||
}
|
||||
|
||||
bin_set
|
||||
}
|
||||
|
||||
#[allow(clippy::never_loop)]
|
||||
fn set_and_join_horz(grid: &mut CellBuffer, idx: Pos) -> u32 {
|
||||
let (x, y) = idx;
|
||||
let mut bin_set = 0b0101;
|
||||
/* Check upper side
|
||||
*
|
||||
* 1 <-
|
||||
* 2 β 0
|
||||
* 3
|
||||
*/
|
||||
loop {
|
||||
if y > 0 {
|
||||
if let Some(cell) = grid.get_mut(x, y - 1) {
|
||||
if let Some(adj) = ch_to_bin(cell.ch()) {
|
||||
if (adj & 0b1000) > 0 {
|
||||
bin_set |= 0b0010;
|
||||
break;
|
||||
} else if adj == 0b0010 {
|
||||
bin_set |= 0b0010;
|
||||
cell.set_ch(bin_to_ch(0b1010));
|
||||
cell.set_fg(Color::Byte(240));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
bin_set &= 0b1101;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check bottom side
|
||||
*
|
||||
* 1
|
||||
* 2 β 0
|
||||
* 3 <-
|
||||
*/
|
||||
loop {
|
||||
if let Some(cell) = grid.get_mut(x, y + 1) {
|
||||
if let Some(adj) = ch_to_bin(cell.ch()) {
|
||||
if (adj & 0b0010) > 0 {
|
||||
bin_set |= 0b1000;
|
||||
break;
|
||||
} else if adj == 0b1000 {
|
||||
bin_set |= 0b1000;
|
||||
cell.set_ch(bin_to_ch(0b1010));
|
||||
cell.set_fg(Color::Byte(240));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
bin_set &= 0b0111;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set left side
|
||||
*
|
||||
* 1
|
||||
* -> 2 β 0
|
||||
* 3
|
||||
*/
|
||||
loop {
|
||||
if x > 0 {
|
||||
if let Some(cell) = grid.get_mut(x - 1, y) {
|
||||
if let Some(adj) = ch_to_bin(cell.ch()) {
|
||||
cell.set_ch(bin_to_ch(adj | 0b0001));
|
||||
cell.set_fg(Color::Byte(240));
|
||||
} else {
|
||||
bin_set &= 0b1011;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set right side
|
||||
*
|
||||
* 1
|
||||
* 2 β 0 <-
|
||||
* 3
|
||||
*/
|
||||
loop {
|
||||
if let Some(cell) = grid.get_mut(x + 1, y) {
|
||||
if let Some(adj) = ch_to_bin(cell.ch()) {
|
||||
cell.set_ch(bin_to_ch(adj | 0b0100));
|
||||
cell.set_fg(Color::Byte(240));
|
||||
} else {
|
||||
bin_set &= 0b1110;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if bin_set == 0 {
|
||||
bin_set = 0b0101;
|
||||
}
|
||||
|
||||
bin_set
|
||||
}
|
||||
|
||||
pub(crate) enum BoxBoundary {
|
||||
Horizontal,
|
||||
Vertical,
|
||||
}
|
||||
|
||||
pub(crate) fn set_and_join_box(grid: &mut CellBuffer, idx: Pos, ch: BoxBoundary) {
|
||||
/* Connected sides:
|
||||
*
|
||||
* 1
|
||||
* 2 c 0
|
||||
* 3
|
||||
*
|
||||
* #3210
|
||||
* 0b____
|
||||
*/
|
||||
|
||||
if grid.ascii_drawing {
|
||||
grid[idx].set_ch(match ch {
|
||||
BoxBoundary::Vertical => '|',
|
||||
BoxBoundary::Horizontal => '-',
|
||||
});
|
||||
|
||||
grid[idx].set_fg(Color::Byte(240));
|
||||
return;
|
||||
}
|
||||
|
||||
let bin_set = match ch {
|
||||
BoxBoundary::Vertical => set_and_join_vert(grid, idx),
|
||||
BoxBoundary::Horizontal => set_and_join_horz(grid, idx),
|
||||
};
|
||||
|
||||
grid[idx].set_ch(bin_to_ch(bin_set));
|
||||
grid[idx].set_fg(Color::Byte(240));
|
||||
}
|
||||
|
||||
/// Puts boundaries in `area`.
|
||||
/// Returns the inner area of the created box.
|
||||
pub fn create_box(grid: &mut CellBuffer, area: Area) -> Area {
|
||||
if !is_valid_area!(area) {
|
||||
return ((0, 0), (0, 0));
|
||||
}
|
||||
let upper_left = upper_left!(area);
|
||||
let bottom_right = bottom_right!(area);
|
||||
|
||||
if !grid.ascii_drawing {
|
||||
for x in get_x(upper_left)..get_x(bottom_right) {
|
||||
grid[(x, get_y(upper_left))]
|
||||
.set_ch(HORZ_BOUNDARY)
|
||||
.set_fg(Color::Byte(240));
|
||||
grid[(x, get_y(bottom_right))]
|
||||
.set_ch(HORZ_BOUNDARY)
|
||||
.set_fg(Color::Byte(240));
|
||||
}
|
||||
|
||||
for y in get_y(upper_left)..get_y(bottom_right) {
|
||||
grid[(get_x(upper_left), y)]
|
||||
.set_ch(VERT_BOUNDARY)
|
||||
.set_fg(Color::Byte(240));
|
||||
grid[(get_x(bottom_right), y)]
|
||||
.set_ch(VERT_BOUNDARY)
|
||||
.set_fg(Color::Byte(240));
|
||||
}
|
||||
set_and_join_box(grid, upper_left, BoxBoundary::Horizontal);
|
||||
set_and_join_box(
|
||||
grid,
|
||||
set_x(upper_left, get_x(bottom_right)),
|
||||
BoxBoundary::Horizontal,
|
||||
);
|
||||
set_and_join_box(
|
||||
grid,
|
||||
set_y(upper_left, get_y(bottom_right)),
|
||||
BoxBoundary::Vertical,
|
||||
);
|
||||
set_and_join_box(grid, bottom_right, BoxBoundary::Vertical);
|
||||
}
|
||||
|
||||
(
|
||||
(
|
||||
std::cmp::min(
|
||||
get_x(upper_left) + 2,
|
||||
std::cmp::min(get_x(upper_left) + 1, get_x(bottom_right)),
|
||||
),
|
||||
std::cmp::min(
|
||||
get_y(upper_left) + 2,
|
||||
std::cmp::min(get_y(upper_left) + 1, get_y(bottom_right)),
|
||||
),
|
||||
),
|
||||
(
|
||||
std::cmp::max(
|
||||
get_x(bottom_right).saturating_sub(2),
|
||||
std::cmp::max(get_x(bottom_right).saturating_sub(1), get_x(upper_left)),
|
||||
),
|
||||
std::cmp::max(
|
||||
get_y(bottom_right).saturating_sub(2),
|
||||
std::cmp::max(get_y(bottom_right).saturating_sub(1), get_y(upper_left)),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -137,3 +137,47 @@ macro_rules! is_valid_area {
|
|||
!(get_y(upper_left) > get_y(bottom_right) || get_x(upper_left) > get_x(bottom_right))
|
||||
}};
|
||||
}
|
||||
|
||||
/// Place box given by `(width, height)` in center of `area`
|
||||
pub fn center_area(area: Area, (width, height): (usize, usize)) -> Area {
|
||||
let mid_x = { std::cmp::max(width!(area) / 2, width / 2) - width / 2 };
|
||||
let mid_y = { std::cmp::max(height!(area) / 2, height / 2) - height / 2 };
|
||||
|
||||
let (upper_x, upper_y) = upper_left!(area);
|
||||
let (max_x, max_y) = bottom_right!(area);
|
||||
(
|
||||
(
|
||||
std::cmp::min(max_x, upper_x + mid_x),
|
||||
std::cmp::min(max_y, upper_y + mid_y),
|
||||
),
|
||||
(
|
||||
std::cmp::min(max_x, upper_x + mid_x + width),
|
||||
std::cmp::min(max_y, upper_y + mid_y + height),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
/// Place box given by `(width, height)` in corner of `area`
|
||||
pub fn place_in_area(area: Area, (width, height): (usize, usize), upper: bool, left: bool) -> Area {
|
||||
let (upper_x, upper_y) = upper_left!(area);
|
||||
let (max_x, max_y) = bottom_right!(area);
|
||||
let x = if upper {
|
||||
upper_x + 2
|
||||
} else {
|
||||
max_x.saturating_sub(2).saturating_sub(width)
|
||||
};
|
||||
|
||||
let y = if left {
|
||||
upper_y + 2
|
||||
} else {
|
||||
max_y.saturating_sub(2).saturating_sub(height)
|
||||
};
|
||||
|
||||
(
|
||||
(std::cmp::min(x, max_x), std::cmp::min(y, max_y)),
|
||||
(
|
||||
std::cmp::min(x + width, max_x),
|
||||
std::cmp::min(y + height, max_y),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
Loadingβ¦
Reference in New Issue