mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-24 01:46:31 +00:00
Split Printer::sub_printer into sub-methods
This commit is contained in:
parent
4042a45b8d
commit
8641098781
@ -537,7 +537,7 @@ impl Cursive {
|
|||||||
1
|
1
|
||||||
};
|
};
|
||||||
let id = self.active_screen;
|
let id = self.active_screen;
|
||||||
let sv_printer = printer.offset((0, offset), !selected);
|
let sv_printer = printer.offset((0, offset)).focused(!selected);
|
||||||
|
|
||||||
self.screens[id].draw_bg(&sv_printer);
|
self.screens[id].draw_bg(&sv_printer);
|
||||||
|
|
||||||
@ -545,11 +545,7 @@ impl Cursive {
|
|||||||
// If the menubar is active, nothing else can be.
|
// If the menubar is active, nothing else can be.
|
||||||
// Draw the menubar?
|
// Draw the menubar?
|
||||||
if self.menubar.visible() {
|
if self.menubar.visible() {
|
||||||
let printer = printer.sub_printer(
|
let printer = printer.focused(self.menubar.receive_events());
|
||||||
Vec2::zero(),
|
|
||||||
printer.size,
|
|
||||||
self.menubar.receive_events(),
|
|
||||||
);
|
|
||||||
self.menubar.draw(&printer);
|
self.menubar.draw(&printer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ use theme::{BorderStyle, ColorStyle, Effect, PaletteColor, Style, Theme};
|
|||||||
use unicode_segmentation::UnicodeSegmentation;
|
use unicode_segmentation::UnicodeSegmentation;
|
||||||
use utils::lines::simple::prefix;
|
use utils::lines::simple::prefix;
|
||||||
use vec::Vec2;
|
use vec::Vec2;
|
||||||
|
use with::With;
|
||||||
|
|
||||||
/// Convenient interface to draw on a subset of the screen.
|
/// Convenient interface to draw on a subset of the screen.
|
||||||
pub struct Printer<'a> {
|
pub struct Printer<'a> {
|
||||||
@ -36,6 +37,20 @@ pub struct Printer<'a> {
|
|||||||
backend: &'a backend::Concrete,
|
backend: &'a backend::Concrete,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> Clone for Printer<'a> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Printer {
|
||||||
|
offset: self.offset,
|
||||||
|
content_offset: self.content_offset,
|
||||||
|
size: self.size,
|
||||||
|
focused: self.focused,
|
||||||
|
theme: self.theme,
|
||||||
|
backend: self.backend,
|
||||||
|
new: Rc::clone(&self.new),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> Printer<'a> {
|
impl<'a> Printer<'a> {
|
||||||
/// Creates a new printer on the given window.
|
/// Creates a new printer on the given window.
|
||||||
///
|
///
|
||||||
@ -308,37 +323,73 @@ impl<'a> Printer<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Prints a horizontal delimiter with side border `├` and `┤`.
|
/// Prints a horizontal delimiter with side border `├` and `┤`.
|
||||||
pub fn print_hdelim<T: Into<Vec2>>(&self, start: T, len: usize) {
|
pub fn print_hdelim<T>(&self, start: T, len: usize)
|
||||||
|
where
|
||||||
|
T: Into<Vec2>,
|
||||||
|
{
|
||||||
let start = start.into();
|
let start = start.into();
|
||||||
self.print(start, "├");
|
self.print(start, "├");
|
||||||
self.print_hline(start + (1, 0), len.saturating_sub(2), "─");
|
self.print_hline(start + (1, 0), len.saturating_sub(2), "─");
|
||||||
self.print(start + (len.saturating_sub(1), 0), "┤");
|
self.print(start + (len.saturating_sub(1), 0), "┤");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a printer on a subset of this one's area.
|
/// Returns a sub-printer with the given offset.
|
||||||
pub fn sub_printer<S: Into<Vec2>, T: Into<Vec2>>(
|
pub fn offset<S>(&self, offset: S) -> Printer
|
||||||
&'a self, offset: S, size: T, focused: bool
|
where
|
||||||
) -> Printer<'a> {
|
S: Into<Vec2>,
|
||||||
let size = size.into();
|
{
|
||||||
let offset = offset.into().or_min(self.size);
|
let offset = offset.into();
|
||||||
let available = if !offset.fits_in(self.size) {
|
self.clone().with(|s| {
|
||||||
Vec2::zero()
|
let consumed = Vec2::min(s.content_offset, offset);
|
||||||
} else {
|
|
||||||
Vec2::min(self.size - offset, size)
|
s.content_offset = s.content_offset - consumed;
|
||||||
};
|
s.offset = s.offset + offset - consumed;
|
||||||
Printer {
|
s.size = s.size.saturating_sub(offset);
|
||||||
offset: self.offset + offset,
|
})
|
||||||
// We can't be larger than what remains
|
|
||||||
size: available,
|
|
||||||
focused: self.focused && focused,
|
|
||||||
theme: self.theme,
|
|
||||||
backend: self.backend,
|
|
||||||
new: Rc::clone(&self.new),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a sub-printer with the given offset.
|
/// Returns a new sub-printer inheriting the given focus.
|
||||||
pub fn offset<S: Into<Vec2>>(&self, offset: S, focused: bool) -> Printer {
|
///
|
||||||
self.sub_printer(offset, self.size, focused)
|
/// If `self` is focused and `focused == true`, the child will be focused.
|
||||||
|
///
|
||||||
|
/// Otherwise, he will be unfocused.
|
||||||
|
pub fn focused(&self, focused: bool) -> Self {
|
||||||
|
self.clone().with(|s| {
|
||||||
|
s.focused &= focused;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a new sub-printer with a cropped area.
|
||||||
|
///
|
||||||
|
/// The new printer size will be the minimum of `size` and its current size.
|
||||||
|
///
|
||||||
|
/// Any size reduction happens at the bottom-right.
|
||||||
|
pub fn cropped<S>(&self, size: S) -> Self
|
||||||
|
where
|
||||||
|
S: Into<Vec2>,
|
||||||
|
{
|
||||||
|
self.clone().with(|s| {
|
||||||
|
s.size = Vec2::min(s.size, size);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a new sub-printer with a shrinked area.
|
||||||
|
///
|
||||||
|
/// The printer size will be reduced by the given border from the bottom-right.
|
||||||
|
pub fn shrinked<S>(&self, borders: S) -> Self
|
||||||
|
where
|
||||||
|
S: Into<Vec2>,
|
||||||
|
{
|
||||||
|
self.cropped(self.size.saturating_sub(borders))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a new sub-printer with a content offset.
|
||||||
|
pub fn content_offset<S>(&self, offset: S) -> Self
|
||||||
|
where
|
||||||
|
S: Into<Vec2>,
|
||||||
|
{
|
||||||
|
self.clone().with(|s| {
|
||||||
|
s.content_offset = s.content_offset + offset;
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -269,7 +269,7 @@ impl ScrollBase {
|
|||||||
// Y is the actual coordinate of the line.
|
// Y is the actual coordinate of the line.
|
||||||
// The item ID is then Y + self.start_line
|
// The item ID is then Y + self.start_line
|
||||||
line_drawer(
|
line_drawer(
|
||||||
&printer.sub_printer(Vec2::new(0, y), Vec2::new(w, 1), true),
|
&printer.offset((0, y)).cropped((w, 1)),
|
||||||
y + self.start_line,
|
y + self.start_line,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -371,11 +371,10 @@ impl Dialog {
|
|||||||
// Add some special effect to the focused button
|
// Add some special effect to the focused button
|
||||||
let position = Vec2::new(offset, y);
|
let position = Vec2::new(offset, y);
|
||||||
button.offset.set(position);
|
button.offset.set(position);
|
||||||
button.button.draw(&printer.sub_printer(
|
button.button.draw(&printer
|
||||||
position,
|
.offset(position)
|
||||||
size,
|
.cropped(size)
|
||||||
self.focus == DialogFocus::Button(i),
|
.focused(self.focus == DialogFocus::Button(i)));
|
||||||
));
|
|
||||||
// Keep 1 blank between two buttons
|
// Keep 1 blank between two buttons
|
||||||
offset += size.x + 1;
|
offset += size.x + 1;
|
||||||
// Also keep 1 blank above the buttons
|
// Also keep 1 blank above the buttons
|
||||||
@ -395,11 +394,10 @@ impl Dialog {
|
|||||||
None => return,
|
None => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.content.draw(&printer.sub_printer(
|
self.content.draw(&printer
|
||||||
self.borders.top_left() + self.padding.top_left(),
|
.offset(self.borders.top_left() + self.padding.top_left())
|
||||||
inner_size,
|
.cropped(inner_size)
|
||||||
self.focus == DialogFocus::Content,
|
.focused(self.focus == DialogFocus::Content));
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_title(&self, printer: &Printer) {
|
fn draw_title(&self, printer: &Printer) {
|
||||||
|
@ -327,11 +327,10 @@ impl View for LinearLayout {
|
|||||||
// eprintln!("Printer size: {:?}", printer.size);
|
// eprintln!("Printer size: {:?}", printer.size);
|
||||||
// eprintln!("Child size: {:?}", item.child.size);
|
// eprintln!("Child size: {:?}", item.child.size);
|
||||||
// eprintln!("Offset: {:?}", item.offset);
|
// eprintln!("Offset: {:?}", item.offset);
|
||||||
let printer = &printer.sub_printer(
|
let printer = &printer
|
||||||
self.orientation.make_vec(item.offset, 0),
|
.offset(self.orientation.make_vec(item.offset, 0))
|
||||||
item.child.size,
|
.cropped(item.child.size)
|
||||||
i == self.focus,
|
.focused(i == self.focus);
|
||||||
);
|
|
||||||
item.child.view.draw(printer);
|
item.child.view.draw(printer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -279,7 +279,9 @@ impl View for ListView {
|
|||||||
.draw(printer, |printer, i| match self.children[i] {
|
.draw(printer, |printer, i| match self.children[i] {
|
||||||
ListChild::Row(ref label, ref view) => {
|
ListChild::Row(ref label, ref view) => {
|
||||||
printer.print((0, 0), label);
|
printer.print((0, 0), label);
|
||||||
view.draw(&printer.offset((offset, 0), i == self.focus));
|
view.draw(&printer
|
||||||
|
.offset((offset, 0))
|
||||||
|
.focused(i == self.focus));
|
||||||
}
|
}
|
||||||
ListChild::Delimiter => (),
|
ListChild::Delimiter => (),
|
||||||
});
|
});
|
||||||
|
@ -211,7 +211,7 @@ impl View for MenuPopup {
|
|||||||
let h = self.menu.len();
|
let h = self.menu.len();
|
||||||
// If we're too high, add a vertical offset
|
// If we're too high, add a vertical offset
|
||||||
let offset = self.align.v.get_offset(h, printer.size.y);
|
let offset = self.align.v.get_offset(h, printer.size.y);
|
||||||
let printer = &printer.offset((0, offset), true);
|
let printer = &printer.offset((0, offset));
|
||||||
|
|
||||||
// Start with a box
|
// Start with a box
|
||||||
printer.print_box(Vec2::new(0, 0), printer.size, false);
|
printer.print_box(Vec2::new(0, 0), printer.size, false);
|
||||||
@ -219,8 +219,7 @@ impl View for MenuPopup {
|
|||||||
// We're giving it a reduced size because of borders.
|
// We're giving it a reduced size because of borders.
|
||||||
// But we're keeping the full width,
|
// But we're keeping the full width,
|
||||||
// to integrate horizontal delimiters in the frame.
|
// to integrate horizontal delimiters in the frame.
|
||||||
let size = printer.size - (0, 2);
|
let printer = printer.offset((0, 1)).shrinked((0, 1));
|
||||||
let printer = printer.sub_printer((0, 1), size, true);
|
|
||||||
|
|
||||||
self.scrollbase.draw(&printer, |printer, i| {
|
self.scrollbase.draw(&printer, |printer, i| {
|
||||||
printer.with_selection(i == self.focus, |printer| {
|
printer.with_selection(i == self.focus, |printer| {
|
||||||
|
@ -35,8 +35,7 @@ impl<V: View> ViewWrapper for Panel<V> {
|
|||||||
|
|
||||||
fn wrap_draw(&self, printer: &Printer) {
|
fn wrap_draw(&self, printer: &Printer) {
|
||||||
printer.print_box((0, 0), printer.size, true);
|
printer.print_box((0, 0), printer.size, true);
|
||||||
let size = printer.size.saturating_sub((2, 2));
|
let printer = printer.offset((1, 1)).shrinked((1, 1));
|
||||||
let printer = printer.sub_printer((1, 1), size, true);
|
|
||||||
self.view.draw(&printer);
|
self.view.draw(&printer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,7 +215,7 @@ impl View for ProgressBar {
|
|||||||
printer.with_effect(Effect::Reverse, |printer| {
|
printer.with_effect(Effect::Reverse, |printer| {
|
||||||
printer.print((offset, 0), &label);
|
printer.print((offset, 0), &label);
|
||||||
});
|
});
|
||||||
let printer = &printer.sub_printer((0, 0), (length, 1), true);
|
let printer = &printer.cropped((length, 1));
|
||||||
printer.print_hline((0, 0), length, " ");
|
printer.print_hline((0, 0), length, " ");
|
||||||
printer.print((offset, 0), &label);
|
printer.print((offset, 0), &label);
|
||||||
});
|
});
|
||||||
|
@ -6,12 +6,17 @@ use vec::Vec2;
|
|||||||
pub struct ScrollView<V> {
|
pub struct ScrollView<V> {
|
||||||
inner: V,
|
inner: V,
|
||||||
offset: Vec2,
|
offset: Vec2,
|
||||||
|
|
||||||
|
// Togglable horizontal/vertical scrolling?
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <V> View for ScrollView<V> where V: View {
|
impl <V> View for ScrollView<V> where V: View {
|
||||||
|
|
||||||
fn draw(&self, printer: &Printer) {
|
fn draw(&self, printer: &Printer) {
|
||||||
self.printer.offset
|
// Draw content
|
||||||
self.inner.draw(printer);
|
let printer = printer.content_offset(self.offset);
|
||||||
|
self.inner.draw(&printer);
|
||||||
|
|
||||||
|
// Draw scrollbar?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -703,8 +703,7 @@ impl<T: 'static> View for SelectView<T> {
|
|||||||
} else {
|
} else {
|
||||||
let h = self.items.len();
|
let h = self.items.len();
|
||||||
let offset = self.align.v.get_offset(h, printer.size.y);
|
let offset = self.align.v.get_offset(h, printer.size.y);
|
||||||
let printer =
|
let printer = &printer.offset((0, offset));
|
||||||
&printer.sub_printer(Vec2::new(0, offset), printer.size, true);
|
|
||||||
|
|
||||||
self.scrollbase.draw(printer, |printer, i| {
|
self.scrollbase.draw(printer, |printer, i| {
|
||||||
printer.with_selection(i == self.focus(), |printer| {
|
printer.with_selection(i == self.focus(), |printer| {
|
||||||
|
@ -86,7 +86,7 @@ impl<T: View> ViewWrapper for ShadowView<T> {
|
|||||||
self.left_padding as usize,
|
self.left_padding as usize,
|
||||||
self.top_padding as usize,
|
self.top_padding as usize,
|
||||||
);
|
);
|
||||||
let printer = &printer.offset(offset, true);
|
let printer = &printer.offset(offset);
|
||||||
if printer.theme.shadow {
|
if printer.theme.shadow {
|
||||||
let h = printer.size.y;
|
let h = printer.size.y;
|
||||||
let w = printer.size.x;
|
let w = printer.size.x;
|
||||||
@ -102,11 +102,7 @@ impl<T: View> ViewWrapper for ShadowView<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Draw the view background
|
// Draw the view background
|
||||||
let printer = printer.sub_printer(
|
let printer = printer.shrinked((1,1));
|
||||||
Vec2::zero(),
|
|
||||||
printer.size.saturating_sub((1, 1)),
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
self.view.draw(&printer);
|
self.view.draw(&printer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -420,11 +420,10 @@ impl StackView {
|
|||||||
StackPositionIterator::new(self.layers.iter(), printer.size)
|
StackPositionIterator::new(self.layers.iter(), printer.size)
|
||||||
.enumerate()
|
.enumerate()
|
||||||
{
|
{
|
||||||
v.view.draw(&printer.sub_printer(
|
v.view.draw(&printer
|
||||||
offset,
|
.offset(offset)
|
||||||
v.size,
|
.cropped(v.size)
|
||||||
i + 1 == last,
|
.focused(i + 1 == last));
|
||||||
));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -455,7 +455,7 @@ impl View for TextView {
|
|||||||
let h = self.rows.len();
|
let h = self.rows.len();
|
||||||
// If the content is smaller than the view, align it somewhere.
|
// If the content is smaller than the view, align it somewhere.
|
||||||
let offset = self.align.v.get_offset(h, printer.size.y);
|
let offset = self.align.v.get_offset(h, printer.size.y);
|
||||||
let printer = &printer.offset((0, offset), true);
|
let printer = &printer.offset((0, offset));
|
||||||
|
|
||||||
let content = self.content.lock().unwrap();
|
let content = self.content.lock().unwrap();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user