mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-23 17:35:00 +00:00
Use StyledString in SelectView
This commit is contained in:
parent
612c7d9ea7
commit
6b278495d5
@ -84,9 +84,24 @@ impl<'a, 'b> Printer<'a, 'b> {
|
||||
.clear(self.theme.palette[PaletteColor::Background]);
|
||||
}
|
||||
|
||||
/// Prints some styled text at the given position.
|
||||
pub fn print_styled<S>(
|
||||
&self, start: S, text: ::utils::span::SpannedStr<'_, Style>,
|
||||
) where
|
||||
S: Into<Vec2>,
|
||||
{
|
||||
let Vec2 { mut x, y } = start.into();
|
||||
for span in text.spans() {
|
||||
self.with_style(*span.attr, |printer| {
|
||||
printer.print((x, y), span.content);
|
||||
x += span.content.width();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: use &mut self? We don't *need* it, but it may make sense.
|
||||
// We don't want people to start calling prints in parallel?
|
||||
/// Prints some text at the given position relative to the window.
|
||||
/// Prints some text at the given position
|
||||
pub fn print<S: Into<Vec2>>(&self, start: S, text: &str) {
|
||||
// Where we are asked to start printing. Oh boy.
|
||||
let start = start.into();
|
||||
|
@ -3,6 +3,7 @@
|
||||
//! This module defines various structs describing a span of text from a
|
||||
//! larger string.
|
||||
use std::borrow::Cow;
|
||||
use unicode_width::UnicodeWidthStr;
|
||||
|
||||
/// A string with associated spans.
|
||||
///
|
||||
@ -117,11 +118,12 @@ where
|
||||
}
|
||||
|
||||
/// Gives access to the parsed styled spans.
|
||||
pub fn spans(&self) -> Vec<Span<'a, T>> {
|
||||
self.spans
|
||||
.iter()
|
||||
.map(|span| span.resolve(self.source))
|
||||
.collect()
|
||||
pub fn spans<'b>(&'b self) -> impl Iterator<Item = Span<'a, T>> + 'b
|
||||
where
|
||||
'a: 'b,
|
||||
{
|
||||
let source = self.source;
|
||||
self.spans.iter().map(move |span| span.resolve(source))
|
||||
}
|
||||
|
||||
/// Returns a reference to the indexed spans.
|
||||
@ -232,12 +234,9 @@ impl<T> SpannedString<T> {
|
||||
}
|
||||
|
||||
/// Gives access to the parsed styled spans.
|
||||
#[cfg_attr(feature = "cargo-clippy", allow(needless_lifetimes))]
|
||||
pub fn spans<'a>(&'a self) -> Vec<Span<'a, T>> {
|
||||
self.spans
|
||||
.iter()
|
||||
.map(|span| span.resolve(&self.source))
|
||||
.collect()
|
||||
pub fn spans<'a>(&'a self) -> impl Iterator<Item = Span<'a, T>> {
|
||||
let source = &self.source;
|
||||
self.spans.iter().map(move |span| span.resolve(source))
|
||||
}
|
||||
|
||||
/// Returns a reference to the indexed spans.
|
||||
@ -256,6 +255,13 @@ impl<T> SpannedString<T> {
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.source.is_empty() || self.spans.is_empty()
|
||||
}
|
||||
|
||||
/// Returns the width taken by this string.
|
||||
///
|
||||
/// This is the sum of the width of each span.
|
||||
pub fn width(&self) -> usize {
|
||||
self.spans().map(|s| s.content.width()).sum()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> From<&'a SpannedString<T>> for SpannedStr<'a, T> {
|
||||
|
@ -8,7 +8,7 @@ use std::cell::Cell;
|
||||
use std::cmp::min;
|
||||
use std::rc::Rc;
|
||||
use theme::ColorStyle;
|
||||
use unicode_width::UnicodeWidthStr;
|
||||
use utils::markup::StyledString;
|
||||
use vec::Vec2;
|
||||
use view::{Position, View};
|
||||
use views::MenuPopup;
|
||||
@ -253,7 +253,7 @@ impl<T: 'static> SelectView<T> {
|
||||
}
|
||||
|
||||
/// Adds a item to the list, with given label and value.
|
||||
pub fn add_item<S: Into<String>>(&mut self, label: S, value: T) {
|
||||
pub fn add_item<S: Into<StyledString>>(&mut self, label: S, value: T) {
|
||||
self.items.push(Item::new(label.into(), value));
|
||||
}
|
||||
|
||||
@ -267,13 +267,13 @@ impl<T: 'static> SelectView<T> {
|
||||
/// assert_eq!(select.get_item(0), Some(("Short", &1)));
|
||||
/// ```
|
||||
pub fn get_item(&self, i: usize) -> Option<(&str, &T)> {
|
||||
self.items
|
||||
.get(i)
|
||||
.map(|item| (item.label.as_ref(), &*item.value))
|
||||
self.iter().nth(i)
|
||||
}
|
||||
|
||||
/// Gets a mut item at given idx or None.
|
||||
pub fn get_item_mut(&mut self, i: usize) -> Option<(&mut String, &mut T)> {
|
||||
pub fn get_item_mut(
|
||||
&mut self, i: usize,
|
||||
) -> Option<(&mut StyledString, &mut T)> {
|
||||
if i >= self.items.len() {
|
||||
None
|
||||
} else {
|
||||
@ -293,7 +293,7 @@ impl<T: 'static> SelectView<T> {
|
||||
pub fn iter(&self) -> impl Iterator<Item = (&str, &T)> {
|
||||
self.items
|
||||
.iter()
|
||||
.map(|item| (item.label.as_str(), &*item.value))
|
||||
.map(|item| (item.label.source(), &*item.value))
|
||||
}
|
||||
|
||||
/// Removes an item from the list.
|
||||
@ -315,7 +315,7 @@ impl<T: 'static> SelectView<T> {
|
||||
/// the right.
|
||||
pub fn insert_item<S>(&mut self, index: usize, label: S, value: T)
|
||||
where
|
||||
S: Into<String>,
|
||||
S: Into<StyledString>,
|
||||
{
|
||||
self.items.insert(index, Item::new(label.into(), value));
|
||||
}
|
||||
@ -328,7 +328,7 @@ impl<T: 'static> SelectView<T> {
|
||||
/// Adds all items from from an iterator.
|
||||
pub fn add_all<S, I>(&mut self, iter: I)
|
||||
where
|
||||
S: Into<String>,
|
||||
S: Into<StyledString>,
|
||||
I: IntoIterator<Item = (S, T)>,
|
||||
{
|
||||
for (s, t) in iter {
|
||||
@ -351,7 +351,7 @@ impl<T: 'static> SelectView<T> {
|
||||
let l = self.items[i].label.width();
|
||||
let x = self.align.h.get_offset(l, printer.size.x);
|
||||
printer.print_hline((0, 0), x, " ");
|
||||
printer.print((x, 0), &self.items[i].label);
|
||||
printer.print_styled((x, 0), (&self.items[i].label).into());
|
||||
if l < printer.size.x {
|
||||
assert!((l + x) <= printer.size.x);
|
||||
printer.print_hline((x + l, 0), printer.size.x - (l + x), " ");
|
||||
@ -554,7 +554,7 @@ impl<T: 'static> SelectView<T> {
|
||||
let focus = Rc::clone(&self.focus);
|
||||
let on_submit = self.on_submit.as_ref().cloned();
|
||||
let value = Rc::clone(&item.value);
|
||||
tree.add_leaf(item.label.clone(), move |s| {
|
||||
tree.add_leaf(item.label.source(), move |s| {
|
||||
// TODO: What if an item was removed in the meantime?
|
||||
focus.set(i);
|
||||
if let Some(ref on_submit) = on_submit {
|
||||
@ -570,7 +570,7 @@ impl<T: 'static> SelectView<T> {
|
||||
// This is the offset for the label text.
|
||||
// We'll want to show the popup so that the text matches.
|
||||
// It'll be soo cool.
|
||||
let item_length = self.items[focus].label.len();
|
||||
let item_length = self.items[focus].label.width();
|
||||
let text_offset = (self.last_size.x.saturating_sub(item_length)) / 2;
|
||||
// The total offset for the window is:
|
||||
// * the last absolute offset at which we drew this view
|
||||
@ -698,9 +698,9 @@ impl<T: 'static> View for SelectView<T> {
|
||||
let label = &self.items[self.focus()].label;
|
||||
|
||||
// And center the text?
|
||||
let offset = HAlign::Center.get_offset(label.len(), x + 1);
|
||||
let offset = HAlign::Center.get_offset(label.width(), x + 1);
|
||||
|
||||
printer.print((offset, 0), label);
|
||||
printer.print_styled((offset, 0), label.into());
|
||||
});
|
||||
} else {
|
||||
// Non-popup mode: we always print the entire list.
|
||||
@ -772,15 +772,13 @@ impl<T: 'static> View for SelectView<T> {
|
||||
|
||||
// We wrap each value in a `Rc` and add a label
|
||||
struct Item<T> {
|
||||
label: String,
|
||||
label: StyledString,
|
||||
value: Rc<T>,
|
||||
}
|
||||
|
||||
impl<T> Item<T> {
|
||||
fn new(label: String, value: T) -> Self {
|
||||
Item {
|
||||
label,
|
||||
value: Rc::new(value),
|
||||
}
|
||||
fn new(label: StyledString, value: T) -> Self {
|
||||
let value = Rc::new(value);
|
||||
Item { label, value }
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user