mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-23 17:35:00 +00:00
rustfmt
This commit is contained in:
parent
5c3c750033
commit
1ad515e5f0
@ -19,7 +19,11 @@ use cursive::views::Canvas;
|
||||
fn main() {
|
||||
let mut siv = Cursive::new();
|
||||
|
||||
siv.add_layer(Canvas::new(()).with_draw(draw).fixed_size((20, 10)));
|
||||
siv.add_layer(
|
||||
Canvas::new(())
|
||||
.with_draw(draw)
|
||||
.fixed_size((20, 10)),
|
||||
);
|
||||
|
||||
siv.add_global_callback('q', |s| s.quit());
|
||||
|
||||
|
@ -9,7 +9,11 @@ use cursive::traits::*;
|
||||
|
||||
fn main() {
|
||||
let mut siv = Cursive::new();
|
||||
siv.add_layer(KeyCodeView::new(10).full_width().fixed_height(10));
|
||||
siv.add_layer(
|
||||
KeyCodeView::new(10)
|
||||
.full_width()
|
||||
.fixed_height(10),
|
||||
);
|
||||
|
||||
siv.run();
|
||||
}
|
||||
|
@ -87,8 +87,11 @@ impl View for BufferView {
|
||||
|
||||
fn draw(&self, printer: &Printer) {
|
||||
// Print the end of the buffer
|
||||
for (i, line) in
|
||||
self.buffer.iter().rev().take(printer.size.y).enumerate()
|
||||
for (i, line) in self.buffer
|
||||
.iter()
|
||||
.rev()
|
||||
.take(printer.size.y)
|
||||
.enumerate()
|
||||
{
|
||||
printer.print((0, printer.size.y - 1 - i), line);
|
||||
}
|
||||
|
@ -12,7 +12,10 @@ fn main() {
|
||||
let mut siv = Cursive::new();
|
||||
|
||||
let mut styled = StyledString::plain("Isn't ");
|
||||
styled.append(StyledString::styled("that ", Color::Dark(BaseColor::Red)));
|
||||
styled.append(StyledString::styled(
|
||||
"that ",
|
||||
Color::Dark(BaseColor::Red),
|
||||
));
|
||||
styled.append(StyledString::styled(
|
||||
"cool?",
|
||||
Style::from(Color::Light(BaseColor::Blue)).combine(Effect::Bold),
|
||||
|
@ -64,7 +64,8 @@ impl Board {
|
||||
}
|
||||
|
||||
fn get_mut(&mut self, pos: Vec2) -> Option<&mut Cell> {
|
||||
self.cell_id(pos).map(move |i| &mut self.cells[i])
|
||||
self.cell_id(pos)
|
||||
.map(move |i| &mut self.cells[i])
|
||||
}
|
||||
|
||||
pub fn cell_id(&self, pos: Vec2) -> Option<usize> {
|
||||
|
@ -189,7 +189,9 @@ impl cursive::view::View for BoardView {
|
||||
Cell::Unknown => "[]",
|
||||
Cell::Flag => "()",
|
||||
Cell::Visible(n) => {
|
||||
[" ", " 1", " 2", " 3", " 4", " 5", " 6", " 7", " 8"][n]
|
||||
[
|
||||
" ", " 1", " 2", " 3", " 4", " 5", " 6", " 7", " 8"
|
||||
][n]
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -87,7 +87,11 @@ fn phase_2(s: &mut Cursive) {
|
||||
// Let's prepare the progress bars...
|
||||
let mut linear = LinearLayout::vertical();
|
||||
for c in &counters {
|
||||
linear.add_child(ProgressBar::new().max(n_max).with_value(c.clone()));
|
||||
linear.add_child(
|
||||
ProgressBar::new()
|
||||
.max(n_max)
|
||||
.with_value(c.clone()),
|
||||
);
|
||||
}
|
||||
|
||||
s.pop_layer();
|
||||
|
@ -38,6 +38,10 @@ fn on_edit(siv: &mut Cursive, _content: &str, _cursor: usize) {
|
||||
let matches = edit_1.get_content() == edit_2.get_content();
|
||||
|
||||
siv.call_on_id("match", |v: &mut TextView| {
|
||||
v.set_content(if matches { "match" } else { "no match" })
|
||||
v.set_content(if matches {
|
||||
"match"
|
||||
} else {
|
||||
"no match"
|
||||
})
|
||||
});
|
||||
}
|
||||
|
@ -19,7 +19,9 @@ fn main() {
|
||||
);
|
||||
|
||||
// We'll add a find feature!
|
||||
siv.add_layer(Dialog::info("Hint: press Ctrl-F to find in text!"));
|
||||
siv.add_layer(Dialog::info(
|
||||
"Hint: press Ctrl-F to find in text!",
|
||||
));
|
||||
|
||||
siv.add_global_callback(Event::CtrlChar('f'), |s| {
|
||||
// When Ctrl-F is pressed, show the Find popup.
|
||||
|
@ -6,7 +6,8 @@ use cursive::views::{Dialog, TextView};
|
||||
fn main() {
|
||||
let mut siv = Cursive::new();
|
||||
// You can load a theme from a file at runtime for fast development.
|
||||
siv.load_theme_file("assets/style.toml").unwrap();
|
||||
siv.load_theme_file("assets/style.toml")
|
||||
.unwrap();
|
||||
|
||||
// Or you can directly load it from a string for easy deployment.
|
||||
// siv.load_theme(include_str!("../assets/style.toml")).unwrap();
|
||||
|
@ -8,7 +8,9 @@ fn main() {
|
||||
let mut siv = Cursive::new();
|
||||
|
||||
let layout = LinearLayout::vertical()
|
||||
.child(TextView::new("This is a dynamic theme example!"))
|
||||
.child(TextView::new(
|
||||
"This is a dynamic theme example!",
|
||||
))
|
||||
.child(EditView::new().content("Woo! colors!").style(
|
||||
ColorStyle::new(
|
||||
Color::Rgb(200, 150, 150),
|
||||
|
@ -252,9 +252,11 @@ impl backend::Backend for Concrete {
|
||||
position: self.mouse_position,
|
||||
offset: Vec2::zero(),
|
||||
},
|
||||
BltEvent::KeyPressed { key, ctrl, shift } => {
|
||||
self.blt_keycode_to_ev(key, shift, ctrl)
|
||||
}
|
||||
BltEvent::KeyPressed {
|
||||
key,
|
||||
ctrl,
|
||||
shift,
|
||||
} => self.blt_keycode_to_ev(key, shift, ctrl),
|
||||
// TODO: there's no Key::Shift/Ctrl for w/e reason
|
||||
BltEvent::ShiftPressed => Event::Refresh,
|
||||
BltEvent::ControlPressed => Event::Refresh,
|
||||
|
@ -13,7 +13,9 @@ mod pan;
|
||||
pub use self::pan::*;
|
||||
|
||||
fn split_i32(code: i32) -> Vec<u8> {
|
||||
(0..4).map(|i| ((code >> (8 * i)) & 0xFF) as u8).collect()
|
||||
(0..4)
|
||||
.map(|i| ((code >> (8 * i)) & 0xFF) as u8)
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn fill_key_codes<F>(target: &mut HashMap<i32, Event>, f: F)
|
||||
|
@ -184,7 +184,9 @@ impl backend::Backend for Concrete {
|
||||
// (Mouse move when a button is pressed).
|
||||
// Replacing 1002 with 1003 would give us ANY mouse move.
|
||||
print!("\x1B[?1002h");
|
||||
stdout().flush().expect("could not flush stdout");
|
||||
stdout()
|
||||
.flush()
|
||||
.expect("could not flush stdout");
|
||||
|
||||
Concrete {
|
||||
current_style: Cell::new(ColorPair::from_256colors(0, 0)),
|
||||
@ -210,7 +212,9 @@ impl backend::Backend for Concrete {
|
||||
|
||||
fn finish(&mut self) {
|
||||
print!("\x1B[?1002l");
|
||||
stdout().flush().expect("could not flush stdout");
|
||||
stdout()
|
||||
.flush()
|
||||
.expect("could not flush stdout");
|
||||
ncurses::endwin();
|
||||
}
|
||||
|
||||
|
@ -153,7 +153,9 @@ impl backend::Backend for Concrete {
|
||||
// (Mouse move when a button is pressed).
|
||||
// Replacing 1002 with 1003 would give us ANY mouse move.
|
||||
print!("\x1B[?1002h");
|
||||
stdout().flush().expect("could not flush stdout");
|
||||
stdout()
|
||||
.flush()
|
||||
.expect("could not flush stdout");
|
||||
|
||||
Concrete {
|
||||
current_style: Cell::new(ColorPair::from_256colors(0, 0)),
|
||||
@ -176,7 +178,9 @@ impl backend::Backend for Concrete {
|
||||
|
||||
fn finish(&mut self) {
|
||||
print!("\x1B[?1002l");
|
||||
stdout().flush().expect("could not flush stdout");
|
||||
stdout()
|
||||
.flush()
|
||||
.expect("could not flush stdout");
|
||||
pancurses::endwin();
|
||||
}
|
||||
|
||||
|
@ -168,7 +168,11 @@ impl backend::Backend for Concrete {
|
||||
}
|
||||
|
||||
fn finish(&mut self) {
|
||||
print!("{}{}", termion::cursor::Show, termion::cursor::Goto(1, 1));
|
||||
print!(
|
||||
"{}{}",
|
||||
termion::cursor::Show,
|
||||
termion::cursor::Goto(1, 1)
|
||||
);
|
||||
print!(
|
||||
"{}[49m{}[39m{}",
|
||||
27 as char,
|
||||
|
@ -119,7 +119,8 @@ impl Cursive {
|
||||
|
||||
/// Selects the menubar.
|
||||
pub fn select_menubar(&mut self) {
|
||||
self.menubar.take_focus(direction::Direction::none());
|
||||
self.menubar
|
||||
.take_focus(direction::Direction::none());
|
||||
}
|
||||
|
||||
/// Sets the menubar autohide feature.
|
||||
@ -480,7 +481,8 @@ impl Cursive {
|
||||
pub fn reposition_layer(
|
||||
&mut self, layer: LayerPosition, position: Position
|
||||
) {
|
||||
self.screen_mut().reposition_layer(layer, position);
|
||||
self.screen_mut()
|
||||
.reposition_layer(layer, position);
|
||||
}
|
||||
|
||||
// Handles a key event when it was ignored by the current view
|
||||
@ -507,7 +509,11 @@ impl Cursive {
|
||||
|
||||
fn layout(&mut self) {
|
||||
let size = self.screen_size();
|
||||
let offset = if self.menubar.autohide { 0 } else { 1 };
|
||||
let offset = if self.menubar.autohide {
|
||||
0
|
||||
} else {
|
||||
1
|
||||
};
|
||||
let size = size.saturating_sub((0, offset));
|
||||
self.screen_mut().layout(size);
|
||||
}
|
||||
@ -525,7 +531,11 @@ impl Cursive {
|
||||
let selected = self.menubar.receive_events();
|
||||
|
||||
// Print the stackview background before the menubar
|
||||
let offset = if self.menubar.autohide { 0 } else { 1 };
|
||||
let offset = if self.menubar.autohide {
|
||||
0
|
||||
} else {
|
||||
1
|
||||
};
|
||||
let id = self.active_screen;
|
||||
let sv_printer = printer.offset((0, offset), !selected);
|
||||
|
||||
@ -609,7 +619,9 @@ impl Cursive {
|
||||
}
|
||||
|
||||
if let Event::Mouse {
|
||||
event, position, ..
|
||||
event,
|
||||
position,
|
||||
..
|
||||
} = event
|
||||
{
|
||||
if event.grabs_focus() && !self.menubar.autohide
|
||||
@ -628,8 +640,14 @@ impl Cursive {
|
||||
if self.menubar.receive_events() {
|
||||
self.menubar.on_event(event).process(self);
|
||||
} else {
|
||||
let offset = if self.menubar.autohide { 0 } else { 1 };
|
||||
match self.screen_mut().on_event(event.relativized((0, offset))) {
|
||||
let offset = if self.menubar.autohide {
|
||||
0
|
||||
} else {
|
||||
1
|
||||
};
|
||||
match self.screen_mut()
|
||||
.on_event(event.relativized((0, offset)))
|
||||
{
|
||||
// If the event was ignored,
|
||||
// it is our turn to play with it.
|
||||
EventResult::Ignored => self.on_event(event),
|
||||
|
@ -351,7 +351,10 @@ impl Event {
|
||||
where
|
||||
V: Into<Vec2>,
|
||||
{
|
||||
if let Event::Mouse { ref mut offset, .. } = *self {
|
||||
if let Event::Mouse {
|
||||
ref mut offset, ..
|
||||
} = *self
|
||||
{
|
||||
*offset = *offset + top_left;
|
||||
}
|
||||
}
|
||||
|
@ -224,8 +224,16 @@ impl<'a> Printer<'a> {
|
||||
self.with_low_border(invert, |s| {
|
||||
s.print(start + size.keep_x(), "┐");
|
||||
s.print(start + size, "┘");
|
||||
s.print_hline(start + (1, 0) + size.keep_y(), size.x - 1, "─");
|
||||
s.print_vline(start + (0, 1) + size.keep_x(), size.y - 1, "│");
|
||||
s.print_hline(
|
||||
start + (1, 0) + size.keep_y(),
|
||||
size.x - 1,
|
||||
"─",
|
||||
);
|
||||
s.print_vline(
|
||||
start + (0, 1) + size.keep_x(),
|
||||
size.y - 1,
|
||||
"│",
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
10
src/rect.rs
10
src/rect.rs
@ -1,6 +1,5 @@
|
||||
//! Rectangles on the 2D character grid.
|
||||
use std::ops::Add;
|
||||
|
||||
use vec::Vec2;
|
||||
|
||||
/// A non-empty rectangle on the 2D grid.
|
||||
@ -23,7 +22,9 @@ where
|
||||
}
|
||||
|
||||
impl<T> Add<T> for Rect
|
||||
where T: Into<Vec2> {
|
||||
where
|
||||
T: Into<Vec2>,
|
||||
{
|
||||
type Output = Rect;
|
||||
|
||||
fn add(mut self, rhs: T) -> Self {
|
||||
@ -91,7 +92,10 @@ impl Rect {
|
||||
}
|
||||
|
||||
/// Adds the given offset to this rectangle.
|
||||
pub fn offset<V>(&mut self, offset: V) where V: Into<Vec2> {
|
||||
pub fn offset<V>(&mut self, offset: V)
|
||||
where
|
||||
V: Into<Vec2>,
|
||||
{
|
||||
let offset = offset.into();
|
||||
self.top_left = self.top_left + offset;
|
||||
self.bottom_right = self.bottom_right + offset;
|
||||
|
@ -152,8 +152,10 @@ impl Color {
|
||||
Some(Color::Rgb(r as u8, g as u8, b as u8))
|
||||
} else if value.len() == 3 {
|
||||
// RGB values between 0 and 5 maybe?
|
||||
let rgb: Vec<_> =
|
||||
value.chars().map(|c| c as i16 - '0' as i16).collect();
|
||||
let rgb: Vec<_> = value
|
||||
.chars()
|
||||
.map(|c| c as i16 - '0' as i16)
|
||||
.collect();
|
||||
if rgb.iter().all(|&i| i >= 0 && i < 6) {
|
||||
Some(Color::RgbLowRes(
|
||||
rgb[0] as u8,
|
||||
|
@ -33,7 +33,10 @@ impl ColorStyle {
|
||||
|
||||
/// Application background, where no view is present.
|
||||
pub fn background() -> Self {
|
||||
Self::new(PaletteColor::Background, PaletteColor::Background)
|
||||
Self::new(
|
||||
PaletteColor::Background,
|
||||
PaletteColor::Background,
|
||||
)
|
||||
}
|
||||
|
||||
/// Color used by view shadows. Only background matters.
|
||||
@ -73,7 +76,10 @@ impl ColorStyle {
|
||||
|
||||
/// Highlight color for inactive views (not in focus).
|
||||
pub fn highlight_inactive() -> Self {
|
||||
Self::new(PaletteColor::View, PaletteColor::HighlightInactive)
|
||||
Self::new(
|
||||
PaletteColor::View,
|
||||
PaletteColor::HighlightInactive,
|
||||
)
|
||||
}
|
||||
|
||||
/// Return the color pair that this style represents.
|
||||
|
@ -62,14 +62,26 @@ pub(crate) fn load_table(palette: &mut Palette, table: &toml::value::Table) {
|
||||
&mut palette[PaletteColor::Background],
|
||||
table.get("background"),
|
||||
);
|
||||
load_color(&mut palette[PaletteColor::Shadow], table.get("shadow"));
|
||||
load_color(&mut palette[PaletteColor::View], table.get("view"));
|
||||
load_color(&mut palette[PaletteColor::Primary], table.get("primary"));
|
||||
load_color(
|
||||
&mut palette[PaletteColor::Shadow],
|
||||
table.get("shadow"),
|
||||
);
|
||||
load_color(
|
||||
&mut palette[PaletteColor::View],
|
||||
table.get("view"),
|
||||
);
|
||||
load_color(
|
||||
&mut palette[PaletteColor::Primary],
|
||||
table.get("primary"),
|
||||
);
|
||||
load_color(
|
||||
&mut palette[PaletteColor::Secondary],
|
||||
table.get("secondary"),
|
||||
);
|
||||
load_color(&mut palette[PaletteColor::Tertiary], table.get("tertiary"));
|
||||
load_color(
|
||||
&mut palette[PaletteColor::Tertiary],
|
||||
table.get("tertiary"),
|
||||
);
|
||||
load_color(
|
||||
&mut palette[PaletteColor::TitlePrimary],
|
||||
table.get("title_primary"),
|
||||
@ -134,9 +146,9 @@ fn load_color(target: &mut Color, value: Option<&toml::Value>) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
toml::Value::Array(ref array) => {
|
||||
array.iter().any(|item| load_color(target, Some(item)))
|
||||
}
|
||||
toml::Value::Array(ref array) => array
|
||||
.iter()
|
||||
.any(|item| load_color(target, Some(item))),
|
||||
_ => false,
|
||||
}
|
||||
} else {
|
||||
|
@ -70,6 +70,10 @@ impl<'a> Iterator for LinesIterator<'a> {
|
||||
|
||||
let width = row.width;
|
||||
|
||||
Some(Row { start, end, width })
|
||||
Some(Row {
|
||||
start,
|
||||
end,
|
||||
width,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -47,7 +47,10 @@ where
|
||||
}
|
||||
|
||||
// Skip empty spans
|
||||
if self.source.spans()[self.current_span].as_ref().is_empty() {
|
||||
if self.source.spans()[self.current_span]
|
||||
.as_ref()
|
||||
.is_empty()
|
||||
{
|
||||
self.current_span += 1;
|
||||
return self.next();
|
||||
}
|
||||
@ -120,9 +123,13 @@ where
|
||||
self.current_span += 1;
|
||||
|
||||
// Skip empty spans
|
||||
while let Some(true) =
|
||||
self.source.spans().get(self.current_span).map(|span| {
|
||||
span.as_ref().resolve(self.source.source()).is_empty()
|
||||
while let Some(true) = self.source
|
||||
.spans()
|
||||
.get(self.current_span)
|
||||
.map(|span| {
|
||||
span.as_ref()
|
||||
.resolve(self.source.source())
|
||||
.is_empty()
|
||||
}) {
|
||||
self.current_span += 1;
|
||||
}
|
||||
|
@ -76,8 +76,11 @@ where
|
||||
self.width
|
||||
};
|
||||
|
||||
let mut chunks =
|
||||
prefix(&mut self.iter, allowed_width, &mut self.chunk_offset);
|
||||
let mut chunks = prefix(
|
||||
&mut self.iter,
|
||||
allowed_width,
|
||||
&mut self.chunk_offset,
|
||||
);
|
||||
|
||||
// println!("Chunks..: {:?}", chunks);
|
||||
|
||||
@ -162,6 +165,9 @@ where
|
||||
|
||||
// TODO: merge consecutive segments of the same span
|
||||
|
||||
Some(Row { segments, width })
|
||||
Some(Row {
|
||||
segments,
|
||||
width,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,9 @@ fn input() -> StyledString {
|
||||
text.append(StyledString::styled("didn't", Effect::Bold));
|
||||
text.append(StyledString::plain(" say "));
|
||||
text.append(StyledString::styled("half", Effect::Italic));
|
||||
text.append(StyledString::plain(" the things people say I did."));
|
||||
text.append(StyledString::plain(
|
||||
" the things people say I did.",
|
||||
));
|
||||
text.append(StyledString::plain("\n"));
|
||||
text.append(StyledString::plain("\n"));
|
||||
text.append(StyledString::plain(" - A. Einstein"));
|
||||
|
@ -139,8 +139,10 @@ Attention
|
||||
====
|
||||
I *really* love __Cursive__!";
|
||||
let spans = parse_spans(input);
|
||||
let spans: Vec<_> =
|
||||
spans.iter().map(|span| span.resolve(input)).collect();
|
||||
let spans: Vec<_> = spans
|
||||
.iter()
|
||||
.map(|span| span.resolve(input))
|
||||
.collect();
|
||||
|
||||
// println!("{:?}", spans);
|
||||
assert_eq!(
|
||||
|
@ -1,5 +1,5 @@
|
||||
use vec::Vec2;
|
||||
use std::ops::{Add, Div, Mul, Sub};
|
||||
use vec::Vec2;
|
||||
|
||||
/// Four values representing each direction.
|
||||
#[derive(Clone, Copy)]
|
||||
@ -52,19 +52,28 @@ impl Margins {
|
||||
}
|
||||
|
||||
impl From<(usize, usize, usize, usize)> for Margins {
|
||||
fn from((left, right, top, bottom): (usize, usize, usize, usize)) -> Margins {
|
||||
fn from(
|
||||
(left, right, top, bottom): (usize, usize, usize, usize)
|
||||
) -> Margins {
|
||||
Margins::new(left, right, top, bottom)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<(i32, i32, i32, i32)> for Margins {
|
||||
fn from((left, right, top, bottom): (i32, i32, i32, i32)) -> Margins {
|
||||
(left as usize, right as usize, top as usize, bottom as usize).into()
|
||||
(
|
||||
left as usize,
|
||||
right as usize,
|
||||
top as usize,
|
||||
bottom as usize,
|
||||
).into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<((i32, i32), (i32, i32))> for Margins {
|
||||
fn from(((left, right), (top, bottom)): ((i32, i32), (i32, i32))) -> Margins {
|
||||
fn from(
|
||||
((left, right), (top, bottom)): ((i32, i32), (i32, i32))
|
||||
) -> Margins {
|
||||
(left, right, top, bottom).into()
|
||||
}
|
||||
}
|
||||
@ -131,5 +140,3 @@ impl Mul<usize> for Margins {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -14,13 +14,19 @@ impl Position {
|
||||
/// Returns a position absolute on both axis.
|
||||
pub fn absolute<T: Into<Vec2>>(offset: T) -> Self {
|
||||
let offset = offset.into();
|
||||
Position::new(Offset::Absolute(offset.x), Offset::Absolute(offset.y))
|
||||
Position::new(
|
||||
Offset::Absolute(offset.x),
|
||||
Offset::Absolute(offset.y),
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns a position relative to the parent on both axis.
|
||||
pub fn parent<T: Into<XY<isize>>>(offset: T) -> Self {
|
||||
let offset = offset.into();
|
||||
Position::new(Offset::Parent(offset.x), Offset::Parent(offset.y))
|
||||
Position::new(
|
||||
Offset::Parent(offset.x),
|
||||
Offset::Parent(offset.y),
|
||||
)
|
||||
}
|
||||
|
||||
/// Computes the offset required to draw a view.
|
||||
@ -42,8 +48,10 @@ impl Position {
|
||||
let parent = parent.into();
|
||||
|
||||
Vec2::new(
|
||||
self.x.compute_offset(size.x, available.x, parent.x),
|
||||
self.y.compute_offset(size.y, available.y, parent.y),
|
||||
self.x
|
||||
.compute_offset(size.x, available.x, parent.x),
|
||||
self.y
|
||||
.compute_offset(size.y, available.y, parent.y),
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -73,9 +81,10 @@ impl Offset {
|
||||
match *self {
|
||||
Offset::Center => (available - size) / 2,
|
||||
Offset::Absolute(offset) => min(offset, available - size),
|
||||
Offset::Parent(offset) => {
|
||||
min((parent as isize + offset) as usize, available - size)
|
||||
}
|
||||
Offset::Parent(offset) => min(
|
||||
(parent as isize + offset) as usize,
|
||||
available - size,
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -90,11 +99,29 @@ mod tests {
|
||||
#[test]
|
||||
fn test_center() {
|
||||
let c = Position::center();
|
||||
assert_eq!(Vec2::new(2, 1), c.compute_offset((1, 1), (5, 3), (0, 0)));
|
||||
assert_eq!(Vec2::new(2, 0), c.compute_offset((1, 3), (5, 3), (0, 0)));
|
||||
assert_eq!(Vec2::new(1, 1), c.compute_offset((3, 1), (5, 3), (0, 0)));
|
||||
assert_eq!(Vec2::new(0, 1), c.compute_offset((5, 1), (5, 3), (0, 0)));
|
||||
assert_eq!(Vec2::new(0, 0), c.compute_offset((5, 3), (5, 3), (0, 0)));
|
||||
assert_eq!(Vec2::new(0, 0), c.compute_offset((5, 3), (3, 1), (0, 0)));
|
||||
assert_eq!(
|
||||
Vec2::new(2, 1),
|
||||
c.compute_offset((1, 1), (5, 3), (0, 0))
|
||||
);
|
||||
assert_eq!(
|
||||
Vec2::new(2, 0),
|
||||
c.compute_offset((1, 3), (5, 3), (0, 0))
|
||||
);
|
||||
assert_eq!(
|
||||
Vec2::new(1, 1),
|
||||
c.compute_offset((3, 1), (5, 3), (0, 0))
|
||||
);
|
||||
assert_eq!(
|
||||
Vec2::new(0, 1),
|
||||
c.compute_offset((5, 1), (5, 3), (0, 0))
|
||||
);
|
||||
assert_eq!(
|
||||
Vec2::new(0, 0),
|
||||
c.compute_offset((5, 3), (5, 3), (0, 0))
|
||||
);
|
||||
assert_eq!(
|
||||
Vec2::new(0, 0),
|
||||
c.compute_offset((5, 3), (3, 1), (0, 0))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -91,8 +91,10 @@ impl ScrollBase {
|
||||
// eprintln!("Setting heights: {} in {}", content_height, view_height);
|
||||
|
||||
if self.scrollable() {
|
||||
self.start_line =
|
||||
min(self.start_line, self.content_height - self.view_height);
|
||||
self.start_line = min(
|
||||
self.start_line,
|
||||
self.content_height - self.view_height,
|
||||
);
|
||||
} else {
|
||||
self.start_line = 0;
|
||||
}
|
||||
@ -249,11 +251,16 @@ impl ScrollBase {
|
||||
return;
|
||||
}
|
||||
// Print the content in a sub_printer
|
||||
let max_y =
|
||||
min(self.view_height, self.content_height - self.start_line);
|
||||
let max_y = min(
|
||||
self.view_height,
|
||||
self.content_height - self.start_line,
|
||||
);
|
||||
let w = if self.scrollable() {
|
||||
// We have to remove the bar width and the padding.
|
||||
printer.size.x.saturating_sub(1 + self.right_padding)
|
||||
printer
|
||||
.size
|
||||
.x
|
||||
.saturating_sub(1 + self.right_padding)
|
||||
} else {
|
||||
printer.size.x
|
||||
};
|
||||
@ -305,7 +312,10 @@ impl ScrollBase {
|
||||
|
||||
/// Returns the height of the scrollbar thumb.
|
||||
pub fn scrollbar_thumb_height(&self) -> usize {
|
||||
max(1, self.view_height * self.view_height / self.content_height)
|
||||
max(
|
||||
1,
|
||||
self.view_height * self.view_height / self.content_height,
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns the y position of the scrollbar thumb.
|
||||
|
@ -10,7 +10,9 @@ new_default!(ViewPath);
|
||||
impl ViewPath {
|
||||
/// Creates a new empty path.
|
||||
pub fn new() -> Self {
|
||||
ViewPath { path: Vec::new() }
|
||||
ViewPath {
|
||||
path: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a path from the given item.
|
||||
|
@ -91,7 +91,8 @@ pub trait ViewWrapper: 'static {
|
||||
|
||||
/// Wraps the `needs_relayout` method.
|
||||
fn wrap_needs_relayout(&self) -> bool {
|
||||
self.with_view(|v| v.needs_relayout()).unwrap_or(true)
|
||||
self.with_view(|v| v.needs_relayout())
|
||||
.unwrap_or(true)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,12 +96,20 @@ impl<T: View> BoxView<T> {
|
||||
|
||||
/// Wraps `view` in a new `BoxView` with fixed width.
|
||||
pub fn with_fixed_width(width: usize, view: T) -> Self {
|
||||
BoxView::new(SizeConstraint::Fixed(width), SizeConstraint::Free, view)
|
||||
BoxView::new(
|
||||
SizeConstraint::Fixed(width),
|
||||
SizeConstraint::Free,
|
||||
view,
|
||||
)
|
||||
}
|
||||
|
||||
/// Wraps `view` in a new `BoxView` with fixed height.
|
||||
pub fn with_fixed_height(height: usize, view: T) -> Self {
|
||||
BoxView::new(SizeConstraint::Free, SizeConstraint::Fixed(height), view)
|
||||
BoxView::new(
|
||||
SizeConstraint::Free,
|
||||
SizeConstraint::Fixed(height),
|
||||
view,
|
||||
)
|
||||
}
|
||||
|
||||
/// Wraps `view` in a `BoxView` which will take all available space.
|
||||
@ -192,7 +200,8 @@ impl<T: View> ViewWrapper for BoxView<T> {
|
||||
wrap_impl!(self.view: T);
|
||||
|
||||
fn wrap_required_size(&mut self, req: Vec2) -> Vec2 {
|
||||
let req = self.size.zip_map(req, SizeConstraint::available);
|
||||
let req = self.size
|
||||
.zip_map(req, SizeConstraint::available);
|
||||
let child_size = self.view.required_size(req);
|
||||
|
||||
let result = self.size
|
||||
@ -234,58 +243,142 @@ mod tests {
|
||||
fn min_size() {
|
||||
let mut min_w = DummyView.full_screen().min_width(5);
|
||||
|
||||
assert_eq!(Vec2::new(5, 1), min_w.required_size(Vec2::new(1, 1)));
|
||||
assert_eq!(Vec2::new(5, 10), min_w.required_size(Vec2::new(1, 10)));
|
||||
assert_eq!(Vec2::new(10, 1), min_w.required_size(Vec2::new(10, 1)));
|
||||
assert_eq!(Vec2::new(10, 10), min_w.required_size(Vec2::new(10, 10)));
|
||||
assert_eq!(
|
||||
Vec2::new(5, 1),
|
||||
min_w.required_size(Vec2::new(1, 1))
|
||||
);
|
||||
assert_eq!(
|
||||
Vec2::new(5, 10),
|
||||
min_w.required_size(Vec2::new(1, 10))
|
||||
);
|
||||
assert_eq!(
|
||||
Vec2::new(10, 1),
|
||||
min_w.required_size(Vec2::new(10, 1))
|
||||
);
|
||||
assert_eq!(
|
||||
Vec2::new(10, 10),
|
||||
min_w.required_size(Vec2::new(10, 10))
|
||||
);
|
||||
|
||||
let mut min_h = DummyView.full_screen().min_height(5);
|
||||
|
||||
assert_eq!(Vec2::new(1, 5), min_h.required_size(Vec2::new(1, 1)));
|
||||
assert_eq!(Vec2::new(1, 10), min_h.required_size(Vec2::new(1, 10)));
|
||||
assert_eq!(Vec2::new(10, 5), min_h.required_size(Vec2::new(10, 1)));
|
||||
assert_eq!(Vec2::new(10, 10), min_h.required_size(Vec2::new(10, 10)));
|
||||
assert_eq!(
|
||||
Vec2::new(1, 5),
|
||||
min_h.required_size(Vec2::new(1, 1))
|
||||
);
|
||||
assert_eq!(
|
||||
Vec2::new(1, 10),
|
||||
min_h.required_size(Vec2::new(1, 10))
|
||||
);
|
||||
assert_eq!(
|
||||
Vec2::new(10, 5),
|
||||
min_h.required_size(Vec2::new(10, 1))
|
||||
);
|
||||
assert_eq!(
|
||||
Vec2::new(10, 10),
|
||||
min_h.required_size(Vec2::new(10, 10))
|
||||
);
|
||||
|
||||
let mut min_s = DummyView.full_screen().min_size((5, 5));
|
||||
|
||||
assert_eq!(Vec2::new(5, 5), min_s.required_size(Vec2::new(1, 1)));
|
||||
assert_eq!(Vec2::new(5, 10), min_s.required_size(Vec2::new(1, 10)));
|
||||
assert_eq!(Vec2::new(10, 5), min_s.required_size(Vec2::new(10, 1)));
|
||||
assert_eq!(Vec2::new(10, 10), min_s.required_size(Vec2::new(10, 10)));
|
||||
assert_eq!(
|
||||
Vec2::new(5, 5),
|
||||
min_s.required_size(Vec2::new(1, 1))
|
||||
);
|
||||
assert_eq!(
|
||||
Vec2::new(5, 10),
|
||||
min_s.required_size(Vec2::new(1, 10))
|
||||
);
|
||||
assert_eq!(
|
||||
Vec2::new(10, 5),
|
||||
min_s.required_size(Vec2::new(10, 1))
|
||||
);
|
||||
assert_eq!(
|
||||
Vec2::new(10, 10),
|
||||
min_s.required_size(Vec2::new(10, 10))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn max_size() {
|
||||
let mut max_w = DummyView.full_screen().max_width(5);
|
||||
|
||||
assert_eq!(Vec2::new(1, 1), max_w.required_size(Vec2::new(1, 1)));
|
||||
assert_eq!(Vec2::new(1, 10), max_w.required_size(Vec2::new(1, 10)));
|
||||
assert_eq!(Vec2::new(5, 1), max_w.required_size(Vec2::new(10, 1)));
|
||||
assert_eq!(Vec2::new(5, 10), max_w.required_size(Vec2::new(10, 10)));
|
||||
assert_eq!(
|
||||
Vec2::new(1, 1),
|
||||
max_w.required_size(Vec2::new(1, 1))
|
||||
);
|
||||
assert_eq!(
|
||||
Vec2::new(1, 10),
|
||||
max_w.required_size(Vec2::new(1, 10))
|
||||
);
|
||||
assert_eq!(
|
||||
Vec2::new(5, 1),
|
||||
max_w.required_size(Vec2::new(10, 1))
|
||||
);
|
||||
assert_eq!(
|
||||
Vec2::new(5, 10),
|
||||
max_w.required_size(Vec2::new(10, 10))
|
||||
);
|
||||
|
||||
let mut max_h = DummyView.full_screen().max_height(5);
|
||||
|
||||
assert_eq!(Vec2::new(1, 1), max_h.required_size(Vec2::new(1, 1)));
|
||||
assert_eq!(Vec2::new(1, 5), max_h.required_size(Vec2::new(1, 10)));
|
||||
assert_eq!(Vec2::new(10, 1), max_h.required_size(Vec2::new(10, 1)));
|
||||
assert_eq!(Vec2::new(10, 5), max_h.required_size(Vec2::new(10, 10)));
|
||||
assert_eq!(
|
||||
Vec2::new(1, 1),
|
||||
max_h.required_size(Vec2::new(1, 1))
|
||||
);
|
||||
assert_eq!(
|
||||
Vec2::new(1, 5),
|
||||
max_h.required_size(Vec2::new(1, 10))
|
||||
);
|
||||
assert_eq!(
|
||||
Vec2::new(10, 1),
|
||||
max_h.required_size(Vec2::new(10, 1))
|
||||
);
|
||||
assert_eq!(
|
||||
Vec2::new(10, 5),
|
||||
max_h.required_size(Vec2::new(10, 10))
|
||||
);
|
||||
|
||||
let mut max_s = DummyView.full_screen().max_size((5, 5));
|
||||
|
||||
assert_eq!(Vec2::new(1, 1), max_s.required_size(Vec2::new(1, 1)));
|
||||
assert_eq!(Vec2::new(1, 5), max_s.required_size(Vec2::new(1, 10)));
|
||||
assert_eq!(Vec2::new(5, 1), max_s.required_size(Vec2::new(10, 1)));
|
||||
assert_eq!(Vec2::new(5, 5), max_s.required_size(Vec2::new(10, 10)));
|
||||
assert_eq!(
|
||||
Vec2::new(1, 1),
|
||||
max_s.required_size(Vec2::new(1, 1))
|
||||
);
|
||||
assert_eq!(
|
||||
Vec2::new(1, 5),
|
||||
max_s.required_size(Vec2::new(1, 10))
|
||||
);
|
||||
assert_eq!(
|
||||
Vec2::new(5, 1),
|
||||
max_s.required_size(Vec2::new(10, 1))
|
||||
);
|
||||
assert_eq!(
|
||||
Vec2::new(5, 5),
|
||||
max_s.required_size(Vec2::new(10, 10))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn full_screen() {
|
||||
let mut full = DummyView.full_screen();
|
||||
|
||||
assert_eq!(Vec2::new(1, 1), full.required_size(Vec2::new(1, 1)));
|
||||
assert_eq!(Vec2::new(1, 10), full.required_size(Vec2::new(1, 10)));
|
||||
assert_eq!(Vec2::new(10, 1), full.required_size(Vec2::new(10, 1)));
|
||||
assert_eq!(Vec2::new(10, 10), full.required_size(Vec2::new(10, 10)));
|
||||
assert_eq!(
|
||||
Vec2::new(1, 1),
|
||||
full.required_size(Vec2::new(1, 1))
|
||||
);
|
||||
assert_eq!(
|
||||
Vec2::new(1, 10),
|
||||
full.required_size(Vec2::new(1, 10))
|
||||
);
|
||||
assert_eq!(
|
||||
Vec2::new(10, 1),
|
||||
full.required_size(Vec2::new(10, 1))
|
||||
);
|
||||
assert_eq!(
|
||||
Vec2::new(10, 10),
|
||||
full.required_size(Vec2::new(10, 10))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -248,7 +248,11 @@ impl Dialog {
|
||||
pub fn buttons_mut<'a>(
|
||||
&'a mut self
|
||||
) -> Box<'a + Iterator<Item = &'a mut Button>> {
|
||||
Box::new(self.buttons.iter_mut().map(|b| &mut b.button.view))
|
||||
Box::new(
|
||||
self.buttons
|
||||
.iter_mut()
|
||||
.map(|b| &mut b.button.view),
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns currently focused element
|
||||
|
@ -367,7 +367,8 @@ impl EditView {
|
||||
self.offset = 0;
|
||||
self.set_cursor(len);
|
||||
|
||||
self.make_edit_cb().unwrap_or_else(Callback::dummy)
|
||||
self.make_edit_cb()
|
||||
.unwrap_or_else(Callback::dummy)
|
||||
}
|
||||
|
||||
/// Get the current text.
|
||||
@ -419,7 +420,8 @@ impl EditView {
|
||||
|
||||
self.keep_cursor_in_view();
|
||||
|
||||
self.make_edit_cb().unwrap_or_else(Callback::dummy)
|
||||
self.make_edit_cb()
|
||||
.unwrap_or_else(Callback::dummy)
|
||||
}
|
||||
|
||||
/// Remove the character at the current cursor position.
|
||||
@ -434,7 +436,8 @@ impl EditView {
|
||||
|
||||
self.keep_cursor_in_view();
|
||||
|
||||
self.make_edit_cb().unwrap_or_else(Callback::dummy)
|
||||
self.make_edit_cb()
|
||||
.unwrap_or_else(Callback::dummy)
|
||||
}
|
||||
|
||||
fn make_edit_cb(&self) -> Option<Callback> {
|
||||
|
@ -58,7 +58,10 @@ impl<T: View + 'static> ViewWrapper for IdView<T> {
|
||||
where
|
||||
F: FnOnce(&mut Self::V) -> R,
|
||||
{
|
||||
self.view.try_borrow_mut().ok().map(|mut v| f(&mut *v))
|
||||
self.view
|
||||
.try_borrow_mut()
|
||||
.ok()
|
||||
.map(|mut v| f(&mut *v))
|
||||
}
|
||||
|
||||
fn into_inner(mut self) -> Result<Self::V, Self>
|
||||
|
@ -81,8 +81,10 @@ impl<'a, T: Deref<Target = Child>, I: Iterator<Item = T>> Iterator
|
||||
|
||||
// eprintln!("Available: {}", self.available);
|
||||
|
||||
let length =
|
||||
min(self.available, *child.size.get(self.orientation));
|
||||
let length = min(
|
||||
self.available,
|
||||
*child.size.get(self.orientation),
|
||||
);
|
||||
|
||||
// Allocated width
|
||||
self.available = self.available.saturating_sub(length);
|
||||
@ -173,7 +175,9 @@ impl LinearLayout {
|
||||
|
||||
/// Returns a mutable reference to a child.
|
||||
pub fn get_child_mut(&mut self, i: usize) -> Option<&mut View> {
|
||||
self.children.get_mut(i).map(|child| &mut *child.view)
|
||||
self.children
|
||||
.get_mut(i)
|
||||
.map(|child| &mut *child.view)
|
||||
}
|
||||
|
||||
// If the cache can be used, return the cached size.
|
||||
@ -222,21 +226,27 @@ impl LinearLayout {
|
||||
} else {
|
||||
self.children.len()
|
||||
};
|
||||
Box::new(self.children[..end].iter_mut().enumerate().rev())
|
||||
Box::new(
|
||||
self.children[..end]
|
||||
.iter_mut()
|
||||
.enumerate()
|
||||
.rev(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn move_focus(&mut self, source: direction::Direction) -> EventResult {
|
||||
let i = if let Some(i) =
|
||||
source.relative(self.orientation).and_then(|rel| {
|
||||
let i = if let Some(i) = source.relative(self.orientation).and_then(
|
||||
|rel| {
|
||||
// The iterator starts at the focused element.
|
||||
// We don't want that one.
|
||||
self.iter_mut(true, rel)
|
||||
.skip(1)
|
||||
.filter_map(|p| try_focus(p, source))
|
||||
.next()
|
||||
}) {
|
||||
},
|
||||
) {
|
||||
i
|
||||
} else {
|
||||
return EventResult::Ignored;
|
||||
@ -281,7 +291,9 @@ impl LinearLayout {
|
||||
let child_size = item.child.size.get(self.orientation);
|
||||
|
||||
if (item.offset + child_size > position)
|
||||
&& item.child.view.take_focus(direction::Direction::none())
|
||||
&& item.child
|
||||
.view
|
||||
.take_focus(direction::Direction::none())
|
||||
{
|
||||
// eprintln!("It's a match!");
|
||||
self.focus = i;
|
||||
@ -348,7 +360,9 @@ impl View for LinearLayout {
|
||||
// Every item has the same size orthogonal to the layout
|
||||
item.child.size.set_axis_from(o.swap(), &size);
|
||||
|
||||
item.child.view.layout(size.with_axis(o, item.length));
|
||||
item.child
|
||||
.view
|
||||
.layout(size.with_axis(o, item.length));
|
||||
}
|
||||
}
|
||||
|
||||
@ -425,7 +439,11 @@ impl View for LinearLayout {
|
||||
let mut overweight: Vec<(usize, usize)> = ideal_sizes
|
||||
.iter()
|
||||
.map(|v| self.orientation.get(v))
|
||||
.zip(min_sizes.iter().map(|v| self.orientation.get(v)))
|
||||
.zip(
|
||||
min_sizes
|
||||
.iter()
|
||||
.map(|v| self.orientation.get(v)),
|
||||
)
|
||||
.map(|(a, b)| a.saturating_sub(b))
|
||||
.enumerate()
|
||||
.collect();
|
||||
@ -512,7 +530,9 @@ impl View for LinearLayout {
|
||||
);
|
||||
let item = iterator.nth(self.focus).unwrap();
|
||||
let offset = self.orientation.make_vec(item.offset, 0);
|
||||
item.child.view.on_event(event.relativized(offset))
|
||||
item.child
|
||||
.view
|
||||
.on_event(event.relativized(offset))
|
||||
};
|
||||
match result {
|
||||
EventResult::Ignored => match event {
|
||||
@ -577,7 +597,11 @@ impl View for LinearLayout {
|
||||
}
|
||||
|
||||
fn important_area(&self, _: Vec2) -> Rect {
|
||||
let mut iterator = ChildIterator::new(self.children.iter(), self.orientation, usize::max_value());
|
||||
let mut iterator = ChildIterator::new(
|
||||
self.children.iter(),
|
||||
self.orientation,
|
||||
usize::max_value(),
|
||||
);
|
||||
let item = iterator.nth(self.focus).unwrap();
|
||||
|
||||
let rect = item.child.view.important_area(item.child.size);
|
||||
|
@ -93,8 +93,10 @@ impl ListView {
|
||||
/// Adds a view to the end of the list.
|
||||
pub fn add_child<V: View + 'static>(&mut self, label: &str, mut view: V) {
|
||||
view.take_focus(direction::Direction::none());
|
||||
self.children
|
||||
.push(ListChild::Row(label.to_string(), Box::new(view)));
|
||||
self.children.push(ListChild::Row(
|
||||
label.to_string(),
|
||||
Box::new(view),
|
||||
));
|
||||
}
|
||||
|
||||
/// Removes all children from this view.
|
||||
@ -166,7 +168,12 @@ impl ListView {
|
||||
} else {
|
||||
self.children.len()
|
||||
};
|
||||
Box::new(self.children[..end].iter_mut().enumerate().rev())
|
||||
Box::new(
|
||||
self.children[..end]
|
||||
.iter_mut()
|
||||
.enumerate()
|
||||
.rev(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -303,7 +310,8 @@ impl View for ListView {
|
||||
|
||||
fn layout(&mut self, size: Vec2) {
|
||||
self.last_size = size;
|
||||
self.scrollbase.set_heights(size.y, self.children.len());
|
||||
self.scrollbase
|
||||
.set_heights(size.y, self.children.len());
|
||||
|
||||
// We'll show 2 columns: the labels, and the views.
|
||||
let label_width = self.children
|
||||
@ -314,14 +322,21 @@ impl View for ListView {
|
||||
.unwrap_or(0);
|
||||
|
||||
let spacing = 1;
|
||||
let scrollbar_width = if self.children.len() > size.y { 2 } else { 0 };
|
||||
let scrollbar_width = if self.children.len() > size.y {
|
||||
2
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
let available = size.x
|
||||
.saturating_sub(label_width + spacing + scrollbar_width);
|
||||
|
||||
debug!("Available: {}", available);
|
||||
|
||||
for child in self.children.iter_mut().filter_map(ListChild::view) {
|
||||
for child in self.children
|
||||
.iter_mut()
|
||||
.filter_map(ListChild::view)
|
||||
{
|
||||
child.layout(Vec2::new(available, 1));
|
||||
}
|
||||
}
|
||||
@ -340,7 +355,8 @@ impl View for ListView {
|
||||
} if position
|
||||
.checked_sub(offset)
|
||||
.map(|position| {
|
||||
self.scrollbase.start_drag(position, self.last_size.x)
|
||||
self.scrollbase
|
||||
.start_drag(position, self.last_size.x)
|
||||
})
|
||||
.unwrap_or(false) =>
|
||||
{
|
||||
@ -375,7 +391,8 @@ impl View for ListView {
|
||||
if let ListChild::Row(_, ref mut view) = self.children[self.focus] {
|
||||
// If self.focus < self.scrollbase.start_line, it means the focus is not
|
||||
// in view. Something's fishy, so don't send the event.
|
||||
if let Some(y) = self.focus.checked_sub(self.scrollbase.start_line)
|
||||
if let Some(y) = self.focus
|
||||
.checked_sub(self.scrollbase.start_line)
|
||||
{
|
||||
let offset = (labels_width + 1, y);
|
||||
let result = view.on_event(event.relativized(offset));
|
||||
@ -399,12 +416,10 @@ impl View for ListView {
|
||||
Event::Key(Key::PageDown) => {
|
||||
self.move_focus(10, direction::Direction::up())
|
||||
}
|
||||
Event::Key(Key::Home) | Event::Ctrl(Key::Home) => {
|
||||
self.move_focus(
|
||||
Event::Key(Key::Home) | Event::Ctrl(Key::Home) => self.move_focus(
|
||||
usize::max_value(),
|
||||
direction::Direction::back(),
|
||||
)
|
||||
}
|
||||
),
|
||||
Event::Key(Key::End) | Event::Ctrl(Key::End) => self.move_focus(
|
||||
usize::max_value(),
|
||||
direction::Direction::front(),
|
||||
@ -457,7 +472,10 @@ impl View for ListView {
|
||||
&mut self, selector: &Selector,
|
||||
mut callback: Box<FnMut(&mut Any) + 'a>,
|
||||
) {
|
||||
for view in self.children.iter_mut().filter_map(ListChild::view) {
|
||||
for view in self.children
|
||||
.iter_mut()
|
||||
.filter_map(ListChild::view)
|
||||
{
|
||||
view.call_on_any(selector, Box::new(|any| callback(any)));
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,9 @@ impl MenuPopup {
|
||||
MenuPopup {
|
||||
menu: menu,
|
||||
focus: 0,
|
||||
scrollbase: ScrollBase::new().scrollbar_offset(1).right_padding(0),
|
||||
scrollbase: ScrollBase::new()
|
||||
.scrollbar_offset(1)
|
||||
.right_padding(0),
|
||||
align: Align::top_left(),
|
||||
on_dismiss: None,
|
||||
on_action: None,
|
||||
@ -137,8 +139,7 @@ impl MenuPopup {
|
||||
|
||||
fn make_subtree_cb(&self, tree: &Rc<MenuTree>) -> EventResult {
|
||||
let tree = Rc::clone(tree);
|
||||
let max_width = 4
|
||||
+ self.menu
|
||||
let max_width = 4 + self.menu
|
||||
.children
|
||||
.iter()
|
||||
.map(Self::item_width)
|
||||
@ -250,8 +251,7 @@ impl View for MenuPopup {
|
||||
|
||||
fn required_size(&mut self, req: Vec2) -> Vec2 {
|
||||
// We can't really shrink our items here, so it's not flexible.
|
||||
let w = 4
|
||||
+ self.menu
|
||||
let w = 4 + self.menu
|
||||
.children
|
||||
.iter()
|
||||
.map(Self::item_width)
|
||||
@ -318,7 +318,8 @@ impl View for MenuPopup {
|
||||
&& position
|
||||
.checked_sub(offset + (0, 1))
|
||||
.map(|position| {
|
||||
self.scrollbase.start_drag(position, self.last_size.x)
|
||||
self.scrollbase
|
||||
.start_drag(position, self.last_size.x)
|
||||
})
|
||||
.unwrap_or(false) =>
|
||||
{
|
||||
@ -397,7 +398,9 @@ impl View for MenuPopup {
|
||||
|
||||
fn layout(&mut self, size: Vec2) {
|
||||
self.last_size = size;
|
||||
self.scrollbase
|
||||
.set_heights(size.y.saturating_sub(2), self.menu.children.len());
|
||||
self.scrollbase.set_heights(
|
||||
size.y.saturating_sub(2),
|
||||
self.menu.children.len(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -237,7 +237,9 @@ fn show_child(s: &mut Cursive, offset: Vec2, menu: Rc<MenuTree>) {
|
||||
s.pop_layer();
|
||||
s.select_menubar();
|
||||
// Act as if we sent "Right" then "Down"
|
||||
s.menubar().on_event(Event::Key(Key::Right)).process(s);
|
||||
s.menubar()
|
||||
.on_event(Event::Key(Key::Right))
|
||||
.process(s);
|
||||
if let EventResult::Consumed(Some(cb)) =
|
||||
s.menubar().on_event(Event::Key(Key::Down))
|
||||
{
|
||||
@ -248,7 +250,9 @@ fn show_child(s: &mut Cursive, offset: Vec2, menu: Rc<MenuTree>) {
|
||||
s.pop_layer();
|
||||
s.select_menubar();
|
||||
// Act as if we sent "Left" then "Down"
|
||||
s.menubar().on_event(Event::Key(Key::Left)).process(s);
|
||||
s.menubar()
|
||||
.on_event(Event::Key(Key::Left))
|
||||
.process(s);
|
||||
if let EventResult::Consumed(Some(cb)) =
|
||||
s.menubar().on_event(Event::Key(Key::Down))
|
||||
{
|
||||
|
@ -55,7 +55,10 @@ impl<T> RadioGroup<T> {
|
||||
&mut self, value: T, label: S
|
||||
) -> RadioButton<T> {
|
||||
let count = self.state.borrow().values.len();
|
||||
self.state.borrow_mut().values.push(Rc::new(value));
|
||||
self.state
|
||||
.borrow_mut()
|
||||
.values
|
||||
.push(Rc::new(value));
|
||||
RadioButton::new(Rc::clone(&self.state), count, label.into())
|
||||
}
|
||||
|
||||
|
@ -257,7 +257,8 @@ impl<T: 'static> SelectView<T> {
|
||||
self.focus.set(focus - 1);
|
||||
}
|
||||
|
||||
self.make_select_cb().unwrap_or_else(Callback::dummy)
|
||||
self.make_select_cb()
|
||||
.unwrap_or_else(Callback::dummy)
|
||||
}
|
||||
|
||||
/// Chainable variant of add_item
|
||||
@ -340,7 +341,8 @@ impl<T: 'static> SelectView<T> {
|
||||
self.focus.set(i);
|
||||
self.scrollbase.scroll_to(i);
|
||||
|
||||
self.make_select_cb().unwrap_or_else(Callback::dummy)
|
||||
self.make_select_cb()
|
||||
.unwrap_or_else(Callback::dummy)
|
||||
}
|
||||
|
||||
/// Sets the selection to the given position.
|
||||
@ -374,7 +376,8 @@ impl<T: 'static> SelectView<T> {
|
||||
let focus = self.focus();
|
||||
self.scrollbase.scroll_to(focus);
|
||||
|
||||
self.make_select_cb().unwrap_or_else(Callback::dummy)
|
||||
self.make_select_cb()
|
||||
.unwrap_or_else(Callback::dummy)
|
||||
}
|
||||
|
||||
/// Moves the selection down by the given number of rows.
|
||||
@ -387,7 +390,8 @@ impl<T: 'static> SelectView<T> {
|
||||
let focus = self.focus();
|
||||
self.scrollbase.scroll_to(focus);
|
||||
|
||||
self.make_select_cb().unwrap_or_else(Callback::dummy)
|
||||
self.make_select_cb()
|
||||
.unwrap_or_else(Callback::dummy)
|
||||
}
|
||||
|
||||
// Low-level focus change. Does not fix scrollbase.
|
||||
@ -398,7 +402,10 @@ impl<T: 'static> SelectView<T> {
|
||||
|
||||
// Low-level focus change. Does not fix scrollbase.
|
||||
fn focus_down(&mut self, n: usize) {
|
||||
let focus = min(self.focus() + n, self.items.len().saturating_sub(1));
|
||||
let focus = min(
|
||||
self.focus() + n,
|
||||
self.items.len().saturating_sub(1),
|
||||
);
|
||||
self.focus.set(focus);
|
||||
}
|
||||
|
||||
@ -419,9 +426,8 @@ impl<T: 'static> SelectView<T> {
|
||||
Event::Key(Key::PageUp) => self.focus_up(10),
|
||||
Event::Key(Key::PageDown) => self.focus_down(10),
|
||||
Event::Key(Key::Home) => self.focus.set(0),
|
||||
Event::Key(Key::End) => {
|
||||
self.focus.set(self.items.len().saturating_sub(1))
|
||||
}
|
||||
Event::Key(Key::End) => self.focus
|
||||
.set(self.items.len().saturating_sub(1)),
|
||||
Event::Mouse {
|
||||
event: MouseEvent::WheelDown,
|
||||
..
|
||||
@ -445,7 +451,8 @@ impl<T: 'static> SelectView<T> {
|
||||
} if position
|
||||
.checked_sub(offset)
|
||||
.map(|position| {
|
||||
self.scrollbase.start_drag(position, self.last_size.x)
|
||||
self.scrollbase
|
||||
.start_drag(position, self.last_size.x)
|
||||
})
|
||||
.unwrap_or(false) =>
|
||||
{
|
||||
@ -754,7 +761,8 @@ impl<T: 'static> View for SelectView<T> {
|
||||
self.last_size = size;
|
||||
|
||||
if !self.popup {
|
||||
self.scrollbase.set_heights(size.y, self.items.len());
|
||||
self.scrollbase
|
||||
.set_heights(size.y, self.items.len());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,10 @@ impl<T: View> ShadowView<T> {
|
||||
}
|
||||
|
||||
fn top_left_padding(&self) -> Vec2 {
|
||||
Vec2::new(self.left_padding as usize, self.top_padding as usize)
|
||||
Vec2::new(
|
||||
self.left_padding as usize,
|
||||
self.top_padding as usize,
|
||||
)
|
||||
}
|
||||
|
||||
/// If set, adds an empty column to the left of the view.
|
||||
@ -56,7 +59,8 @@ impl<T: View> ViewWrapper for ShadowView<T> {
|
||||
fn wrap_required_size(&mut self, req: Vec2) -> Vec2 {
|
||||
// Make sure req >= offset
|
||||
let offset = self.padding();
|
||||
self.view.required_size(req.saturating_sub(offset)) + offset
|
||||
self.view
|
||||
.required_size(req.saturating_sub(offset)) + offset
|
||||
}
|
||||
|
||||
fn wrap_layout(&mut self, size: Vec2) {
|
||||
@ -78,8 +82,10 @@ impl<T: View> ViewWrapper for ShadowView<T> {
|
||||
}
|
||||
|
||||
// Skip the first row/column
|
||||
let offset =
|
||||
Vec2::new(self.left_padding as usize, self.top_padding as usize);
|
||||
let offset = Vec2::new(
|
||||
self.left_padding as usize,
|
||||
self.top_padding as usize,
|
||||
);
|
||||
let printer = &printer.offset(offset, true);
|
||||
if printer.theme.shadow {
|
||||
let h = printer.size.y;
|
||||
|
@ -65,9 +65,13 @@ impl<T: View> ChildWrapper<T> {
|
||||
fn unwrap(self) -> T {
|
||||
match self {
|
||||
// ShadowView::into_inner and Layer::into_inner can never fail.
|
||||
ChildWrapper::Shadow(shadow) => {
|
||||
shadow.into_inner().ok().unwrap().into_inner().ok().unwrap()
|
||||
}
|
||||
ChildWrapper::Shadow(shadow) => shadow
|
||||
.into_inner()
|
||||
.ok()
|
||||
.unwrap()
|
||||
.into_inner()
|
||||
.ok()
|
||||
.unwrap(),
|
||||
ChildWrapper::Plain(layer) => layer.into_inner().ok().unwrap(),
|
||||
}
|
||||
}
|
||||
@ -212,7 +216,9 @@ impl StackView {
|
||||
/// Returns a reference to the layer at the given position.
|
||||
pub fn get(&self, pos: LayerPosition) -> Option<&View> {
|
||||
let i = self.get_index(pos);
|
||||
self.layers.get(i).map(|child| child.view.get_inner())
|
||||
self.layers
|
||||
.get(i)
|
||||
.map(|child| child.view.get_inner())
|
||||
}
|
||||
|
||||
/// Returns a mutable reference to the layer at the given position.
|
||||
@ -325,7 +331,10 @@ impl StackView {
|
||||
|
||||
/// Returns the size for each layer in this view.
|
||||
pub fn layer_sizes(&self) -> Vec<Vec2> {
|
||||
self.layers.iter().map(|layer| layer.size).collect()
|
||||
self.layers
|
||||
.iter()
|
||||
.map(|layer| layer.size)
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn get_index(&self, pos: LayerPosition) -> usize {
|
||||
|
@ -35,7 +35,9 @@ pub struct TextArea {
|
||||
}
|
||||
|
||||
fn make_rows(text: &str, width: usize) -> Vec<Row> {
|
||||
LinesIterator::new(text, width).show_spaces().collect()
|
||||
LinesIterator::new(text, width)
|
||||
.show_spaces()
|
||||
.collect()
|
||||
}
|
||||
|
||||
new_default!(TextArea);
|
||||
@ -252,7 +254,8 @@ impl TextArea {
|
||||
|
||||
fn compute_rows(&mut self, size: Vec2) {
|
||||
self.soft_compute_rows(size);
|
||||
self.scrollbase.set_heights(size.y, self.rows.len());
|
||||
self.scrollbase
|
||||
.set_heights(size.y, self.rows.len());
|
||||
}
|
||||
|
||||
fn backspace(&mut self) {
|
||||
@ -349,11 +352,16 @@ impl TextArea {
|
||||
let last_byte = self.content[self.cursor..]
|
||||
.find('\n')
|
||||
.map(|i| 1 + i + self.cursor);
|
||||
let last_row = last_byte
|
||||
.map_or(self.rows.len(), |last_byte| self.row_at(last_byte));
|
||||
let last_row = last_byte.map_or(self.rows.len(), |last_byte| {
|
||||
self.row_at(last_byte)
|
||||
});
|
||||
let last_byte = last_byte.unwrap_or_else(|| self.content.len());
|
||||
|
||||
debug!("Content: `{}` (len={})", self.content, self.content.len());
|
||||
debug!(
|
||||
"Content: `{}` (len={})",
|
||||
self.content,
|
||||
self.content.len()
|
||||
);
|
||||
debug!("start/end: {}/{}", first_byte, last_byte);
|
||||
debug!("start/end rows: {}/{}", first_row, last_row);
|
||||
|
||||
@ -387,11 +395,14 @@ impl TextArea {
|
||||
|
||||
// Otherwise, replace stuff.
|
||||
let affected_rows = first_row..last_row;
|
||||
let replacement_rows =
|
||||
new_rows.into_iter().map(|row| row.shifted(first_byte));
|
||||
self.rows.splice(affected_rows, replacement_rows);
|
||||
let replacement_rows = new_rows
|
||||
.into_iter()
|
||||
.map(|row| row.shifted(first_byte));
|
||||
self.rows
|
||||
.splice(affected_rows, replacement_rows);
|
||||
self.fix_ghost_row();
|
||||
self.scrollbase.set_heights(size.y, self.rows.len());
|
||||
self.scrollbase
|
||||
.set_heights(size.y, self.rows.len());
|
||||
}
|
||||
}
|
||||
|
||||
@ -404,10 +415,18 @@ impl View for TextArea {
|
||||
// (we always keep a space at the end)
|
||||
// And y = number of rows
|
||||
debug!("{:?}", self.rows);
|
||||
let scroll_width = if self.rows.len() > constraint.y { 1 } else { 0 };
|
||||
let scroll_width = if self.rows.len() > constraint.y {
|
||||
1
|
||||
} else {
|
||||
0
|
||||
};
|
||||
Vec2::new(
|
||||
scroll_width + 1
|
||||
+ self.rows.iter().map(|r| r.width).max().unwrap_or(1),
|
||||
+ self.rows
|
||||
.iter()
|
||||
.map(|r| r.width)
|
||||
.max()
|
||||
.unwrap_or(1),
|
||||
self.rows.len(),
|
||||
)
|
||||
}
|
||||
@ -518,7 +537,8 @@ impl View for TextArea {
|
||||
} if position
|
||||
.checked_sub(offset)
|
||||
.map(|position| {
|
||||
self.scrollbase.start_drag(position, self.last_size.x)
|
||||
self.scrollbase
|
||||
.start_drag(position, self.last_size.x)
|
||||
})
|
||||
.unwrap_or(false) =>
|
||||
{
|
||||
|
@ -305,7 +305,11 @@ impl TextView {
|
||||
where
|
||||
S: Into<StyledString>,
|
||||
{
|
||||
self.content.lock().unwrap().content.append(content.into());
|
||||
self.content
|
||||
.lock()
|
||||
.unwrap()
|
||||
.content
|
||||
.append(content.into());
|
||||
self.invalidate();
|
||||
}
|
||||
|
||||
@ -509,7 +513,8 @@ impl View for TextView {
|
||||
} if position
|
||||
.checked_sub(offset)
|
||||
.map(|position| {
|
||||
self.scrollbase.start_drag(position, self.last_size.x)
|
||||
self.scrollbase
|
||||
.start_drag(position, self.last_size.x)
|
||||
})
|
||||
.unwrap_or(false) =>
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user