#![allow(unused_imports)]
use crate::buf::BufferArc;
use crate::buf::BufferManager;
use crate::buf::text::Text;
use crate::hl::ColorSchemeManager;
use crate::prelude::*;
use crate::syntax::SyntaxManager;
use crate::ui::canvas::Canvas;
use crate::ui::canvas::CanvasArc;
use crate::ui::tree::Node;
use crate::ui::tree::NodeId;
use crate::ui::tree::Tree;
use crate::ui::tree::TreeArc;
use crate::ui::viewport::Viewport;
use crate::ui::viewport::ViewportArc;
use crate::ui::widget::WidgetContext;
use crate::ui::widget::Widgetable;
use crate::ui::widget::window::Window;
use crate::ui::widget::window::content::WindowContent;
use crate::ui::widget::window::opt::WindowOptions;
use std::sync::Arc;
use taffy::Style;
use taffy::prelude::FromLength;
use taffy::prelude::FromPercent;
pub fn make_window(
terminal_size: U16Size,
buffer: BufferArc,
window_options: WindowOptions,
) -> (Tree, NodeId) {
let tree_style = Style {
size: taffy::Size {
width: taffy::prelude::length(terminal_size.width()),
height: taffy::prelude::length(terminal_size.height()),
},
..Default::default()
};
let mut tree = Tree::new(tree_style).unwrap();
tree.set_global_local_options(window_options);
let window_style = Style {
size: taffy::Size {
height: taffy::prelude::percent(1.0_f32),
width: taffy::prelude::percent(1.0_f32),
},
..Default::default()
};
let window_id = tree
.new_window_with_parent(
tree.root_id(),
window_style,
*tree.global_local_options(),
Arc::downgrade(&buffer),
)
.unwrap();
(tree, window_id)
}
pub fn make_viewport(
terminal_size: U16Size,
window_options: WindowOptions,
buffer: BufferArc,
start_line_idx: usize,
start_column_idx: usize,
) -> ViewportArc {
let buffer = lock!(buffer);
let actual_shape = rect_from_size!(terminal_size);
let actual_shape = rect_as!(actual_shape, u16);
let actual_size = actual_shape.size();
let viewport = Viewport::view(
&window_options,
buffer.text(),
&actual_size,
start_line_idx,
start_column_idx,
);
Viewport::to_arc(viewport)
}
pub fn make_canvas(
terminal_size: U16Size,
window_options: WindowOptions,
buffer: BufferArc,
viewport: ViewportArc,
) -> Canvas {
let style = Style {
size: taffy::Size {
width: taffy::prelude::length(terminal_size.width()),
height: taffy::prelude::length(terminal_size.height()),
},
..Default::default()
};
let mut tree = Tree::new(style).unwrap();
tree.set_global_local_options(window_options);
let style = Style {
size: taffy::Size {
height: taffy::prelude::percent(1.0_f32),
width: taffy::prelude::percent(1.0_f32),
},
..Default::default()
};
let window_id = tree
.new_window_with_parent(
tree.root_id(),
style,
*tree.global_local_options(),
Arc::downgrade(&buffer),
)
.unwrap();
tree.set_editable_viewport(window_id, viewport);
let content_id = match tree.node(window_id).unwrap() {
Node::Window(window) => window.content_id(),
_ => unreachable!(),
};
let mut canvas = Canvas::new(terminal_size);
let syntax_mgr = SyntaxManager::to_arc(SyntaxManager::new());
let cs_mgr = ColorSchemeManager::to_arc(ColorSchemeManager::new());
let context = WidgetContext::new(syntax_mgr, cs_mgr);
match tree.node(content_id).unwrap() {
Node::WindowContent(content) => content.draw(&mut canvas, &context),
_ => unreachable!(),
}
canvas
}
pub fn make_tree_canvas(tree: TreeArc, terminal_size: U16Size) -> CanvasArc {
let canvas = Canvas::new(terminal_size);
let canvas = Canvas::to_arc(canvas);
let syntax_mgr = SyntaxManager::to_arc(SyntaxManager::new());
let cs_mgr = ColorSchemeManager::to_arc(ColorSchemeManager::new());
let context = WidgetContext::new(syntax_mgr, cs_mgr);
let tree = lock!(tree);
tree.draw(canvas.clone(), &context);
canvas
}
pub fn assert_canvas(actual: &Canvas, expect: &[&str]) {
let actual = actual
.frame()
.raw_symbols()
.iter()
.map(|cs| cs.join(""))
.collect::<Vec<_>>();
info!("actual:{}", actual.len());
for a in actual.iter() {
info!("{:?}", a);
}
info!("expect:{}", expect.len());
for e in expect.iter() {
info!("{:?}", e);
}
assert_eq!(
actual.len(),
expect.len(),
"actual.len() ({}) == expect.len() ({})",
actual.len(),
expect.len()
);
for i in 0..actual.len() {
let e = &expect[i];
let a = &actual[i];
info!("i-{}, actual[{}]:{:?}, expect[{}]:{:?}", i, i, a, i, e);
assert_eq!(
e.len(),
a.len(),
"expect[{}].len() ({}) == actual[{}].len() ({})",
i,
e.len(),
i,
a.len()
);
assert_eq!(e, a, "expect[{}] ({:?}) == actual[{}] ({:?})", i, e, i, a);
}
}
pub fn assert_viewport(
text: &Text,
actual: &Viewport,
expect_rows: &Vec<&str>,
expect_start_line: usize,
expect_end_line: usize,
expect_start_fills: &BTreeMap<usize, usize>,
expect_end_fills: &BTreeMap<usize, usize>,
) {
info!(
"actual start_line/end_line:{:?}/{:?}",
actual.start_line_idx(),
actual.end_line_idx()
);
info!(
"expect start_line/end_line:{:?}/{:?}",
expect_start_line, expect_end_line
);
for (k, v) in actual.lines().iter() {
info!("actual line[{:?}]: {:?}", k, v);
}
for (i, e) in expect_rows.iter().enumerate() {
info!("expect row[{}]:{:?}", i, e);
}
assert_eq!(
expect_start_fills.len(),
expect_end_fills.len(),
"`expect_start_fills.len()` == `expect_end_fills.len()`"
);
for (k, start_v) in expect_start_fills.iter() {
let end_v = expect_end_fills.get(k).unwrap();
info!(
"expect start_fills/end_fills line[{}]:{:?}/{:?}",
k, start_v, end_v
);
}
assert_eq!(
actual.start_line_idx(),
expect_start_line,
"`actual.start_line_idx()` == `expect_start_line` ({})",
expect_start_line
);
assert_eq!(
actual.end_line_idx(),
expect_end_line,
"`actual.end_line_idx()` == `expect_end_line`"
);
if actual.lines().is_empty() {
assert!(
actual.end_line_idx() <= actual.start_line_idx(),
"`actual.end_line_idx()` <= `actual.start_line_idx()`"
);
} else {
let (first_line_idx, _first_line_viewport) =
actual.lines().first().unwrap();
let (last_line_idx, _last_line_viewport) = actual.lines().last().unwrap();
assert_eq!(
*first_line_idx,
actual.start_line_idx(),
"`*first_line_idx` ({}) == `actual.start_line_idx()`",
first_line_idx
);
assert_eq!(
*last_line_idx,
actual.end_line_idx() - 1,
"`*last_line_idx` ({}) == `actual.end_line_idx() - 1`",
last_line_idx
);
}
assert_eq!(
actual.end_line_idx() - actual.start_line_idx(),
actual.lines().len(),
"`actual.end_line_idx() - actual.start_line_idx()` == `actual.lines().len()`"
);
assert_eq!(
actual.end_line_idx() - actual.start_line_idx(),
expect_start_fills.len(),
"`actual.end_line_idx() - actual.start_line_idx()` == `expect_start_fills.len()`"
);
assert_eq!(
actual.end_line_idx() - actual.start_line_idx(),
expect_end_fills.len(),
"`actual.end_line_idx() - actual.start_line_idx()` == `expect_end_fills.len()`"
);
let buflines = text.rope().lines_at(actual.start_line_idx());
let total_lines = expect_end_line - expect_start_line;
for (l, line) in buflines.enumerate() {
if l >= total_lines {
break;
}
let actual_line_idx = l + expect_start_line;
let line_viewport = actual.lines().get(&actual_line_idx).unwrap();
info!(
"l-{:?}, actual_line_idx:{}, line_viewport:{:?}",
l, actual_line_idx, line_viewport
);
info!(
"start_filled_cols expect:{:?}, actual:{}",
expect_start_fills.get(&actual_line_idx),
line_viewport.start_filled_cols()
);
assert_eq!(
line_viewport.start_filled_cols(),
*expect_start_fills.get(&actual_line_idx).unwrap(),
"line_viewport.start_filled_cols() == *expect_start_fills.get({}).unwrap()",
actual_line_idx
);
info!(
"end_filled_cols expect:{:?}, actual:{}",
expect_end_fills.get(&actual_line_idx),
line_viewport.end_filled_cols()
);
assert_eq!(
line_viewport.end_filled_cols(),
*expect_end_fills.get(&actual_line_idx).unwrap(),
"line_viewport.end_filled_cols() == *expect_end_fills.get({}).unwrap()",
actual_line_idx
);
let rows = &line_viewport.rows();
for (r, row) in rows.iter() {
info!("row-index-{:?}, row:{:?}", r, row);
if r > rows.first().unwrap().0 {
let prev_r = r - 1;
let prev_row = rows.get(&prev_r).unwrap();
info!(
"row-{:?}, current[{}]:{:?}, previous[{}]:{:?}",
r, r, row, prev_r, prev_row
);
}
if r < rows.last().unwrap().0 {
let next_r = r + 1;
let next_row = rows.get(&next_r).unwrap();
info!(
"row-{:?}, current[{}]:{:?}, next[{}]:{:?}",
r, r, row, next_r, next_row
);
}
let mut payload = String::new();
for c_idx in row.start_char_idx()..row.end_char_idx() {
let c = line.get_char(c_idx).unwrap();
payload.push(c);
}
info!(
"row-{:?}, payload actual:{:?}, expect:{:?}",
r, payload, expect_rows[*r as usize]
);
assert_eq!(
payload, expect_rows[*r as usize],
"payload == expect_rows[*{} as usize]",
*r
);
}
}
}