pub fn get_data(&self) -> &Data {
&self.data
}
- pub fn is_editing(&self) -> bool {
- self.editor.is_some()
- }
pub fn set_text(&mut self, text: &str) {
self.data.update(text);
self.menuline =
}
}
+impl<Data: EditableMenuLineData> RenderableMenuLine
+ for EditableMenuLine<Data>
+{
+ fn render_menu_line(&self, rc: &mut RenderContext) -> Vec<ColouredString> {
+ vec![self.render(rc.w, &mut rc.cursorpos, rc.lines.len())]
+ }
+ fn is_editing(&self) -> bool {
+ self.editor.is_some()
+ }
+}
+
impl<Data: EditableMenuLineData> MenuKeypressLineGeneral
for EditableMenuLine<Data>
{
struct YourOptionsMenu {
title: FileHeader,
- normal_status: FileStatusLineFinal,
- edit_status: FileStatusLineFinal,
c: YourOptionsMenuContents,
}
#[derive_adhoc(MenuContents)]
struct YourOptionsMenuContents {
el_display_name: EditableMenuLine<String>, // N
+ #[adhoc(MenuContents(blank_line))]
cl_default_vis: CyclingMenuLine<Visibility>,
el_default_language: EditableMenuLine<Option<String>>,
cl_default_sensitive: CyclingMenuLine<bool>,
+ #[adhoc(MenuContents(blank_line))]
cl_locked: CyclingMenuLine<bool>,
cl_hide_collections: CyclingMenuLine<bool>,
cl_discoverable: CyclingMenuLine<bool>,
cl_indexable: CyclingMenuLine<bool>,
+ #[adhoc(MenuContents(blank_line))]
cl_bot: CyclingMenuLine<bool>,
// fields (harder because potentially open-ended number of them)
// note (bio) (harder because flip to an editor)
"HHHHHHHHHHHHHHHHHHHKKKHHKHHKH",
));
- let normal_status = FileStatusLine::new()
- .add(Return, "Back", 10)
- .add(Space, "Submit Changes", 15)
- .finalise();
- let edit_status = FileStatusLine::new()
- .message("Edit line and press Return")
- .finalise();
-
let el_display_name = EditableMenuLine::new(
Pr('N'),
ColouredString::plain("Display name: "),
cl_indexable,
};
c.fix_widths();
- let menu = YourOptionsMenu {
- title,
- normal_status,
- edit_status,
- c,
- };
+ let menu = YourOptionsMenu { title, c };
Ok(menu)
}
w: usize,
h: usize,
) -> (Vec<ColouredString>, CursorPosition) {
- let mut lines = Vec::new();
- let mut cursorpos = CursorPosition::End;
- lines.extend_from_slice(&self.title.render(w));
- lines.extend_from_slice(&BlankLine::render_static());
- lines.push(self.c.el_display_name.render(
- w,
- &mut cursorpos,
- lines.len(),
- ));
- lines.extend_from_slice(&BlankLine::render_static());
- lines.extend_from_slice(&self.c.cl_default_vis.render(w));
- lines.push(self.c.el_default_language.render(
- w,
- &mut cursorpos,
- lines.len(),
- ));
- lines.extend_from_slice(&self.c.cl_default_sensitive.render(w));
- lines.extend_from_slice(&BlankLine::render_static());
- lines.extend_from_slice(&self.c.cl_locked.render(w));
- lines.extend_from_slice(&self.c.cl_hide_collections.render(w));
- lines.extend_from_slice(&self.c.cl_discoverable.render(w));
- lines.extend_from_slice(&self.c.cl_indexable.render(w));
- lines.extend_from_slice(&BlankLine::render_static());
- lines.extend_from_slice(&self.c.cl_bot.render(w));
-
- while lines.len() + 1 < h {
- lines.extend_from_slice(&BlankLine::render_static());
- }
+ let mut rc = RenderContext::new(w);
- if self.c.el_display_name.is_editing()
- || self.c.el_default_language.is_editing()
- {
- lines.extend_from_slice(&self.edit_status.render(w));
- } else {
- lines.extend_from_slice(&self.normal_status.render(w));
- }
+ rc.extend(self.title.render(w));
+ rc.extend(BlankLine::render_static());
+ rc.add_menu_contents(&self.c);
+ rc.pad_add_editing_status(&self.c, h);
- (lines, cursorpos)
+ rc.finish()
}
fn handle_keypress(
use super::client::{Client, ClientError};
use super::coloured_string::*;
use super::html;
-use super::tui::{LogicalAction, OurKey};
+use super::tui::{CursorPosition, LogicalAction, OurKey};
use super::types::*;
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
);
}
+pub struct RenderContext {
+ pub lines: Vec<ColouredString>,
+ pub w: usize,
+ pub cursorpos: CursorPosition,
+}
+
+impl RenderContext {
+ pub fn new(w: usize) -> Self {
+ RenderContext {
+ w,
+ lines: vec![],
+ cursorpos: CursorPosition::End,
+ }
+ }
+ pub fn add_menu_contents(&mut self, c: &impl MenuContents) {
+ c.render(self);
+ }
+ pub fn pad_add_editing_status(&mut self, c: &impl MenuContents, h: usize) {
+ while self.lines.len() + 1 < h {
+ self.extend(BlankLine::render_static());
+ }
+
+ if c.is_editing() {
+ let edit_status = FileStatusLine::new()
+ .message("Edit line and press Return")
+ .finalise();
+
+ self.extend(edit_status.render(self.w));
+ } else {
+ let normal_status = FileStatusLine::new()
+ .add(OurKey::Return, "Back", 10)
+ .add(OurKey::Space, "Submit Changes", 15)
+ .finalise();
+
+ self.extend(normal_status.render(self.w));
+ }
+ }
+ pub fn finish(self) -> (Vec<ColouredString>, CursorPosition) {
+ (self.lines, self.cursorpos)
+ }
+}
+
+impl Extend<ColouredString> for RenderContext {
+ fn extend<II>(&mut self, ls: II)
+ where
+ II: IntoIterator<Item = ColouredString>,
+ {
+ self.lines.extend(ls)
+ }
+}
+
pub trait MenuContents {
fn fix_widths(&mut self) -> (usize, usize);
+ fn render(&self, rc: &mut RenderContext);
+ fn is_editing(&self) -> bool;
}
define_derive_adhoc! {
$( self.$fname.ensure_widths(lmaxwid, rmaxwid); )
(lmaxwid, rmaxwid)
}
+
+ fn render(&self, rc: &mut RenderContext) {
+ $(
+ ${if fmeta(MenuContents(blank_line)) {
+ rc.extend(BlankLine::render_static());
+ }}
+
+ {
+ let l = self.$fname.render_menu_line(rc);
+ rc.extend(l);
+ }
+ )
+ }
+ fn is_editing(&self) -> bool {
+ $(
+ self.$fname.is_editing() ||
+ )
+ false
+ }
}
}
+pub trait RenderableMenuLine {
+ fn render_menu_line(&self, rc: &mut RenderContext) -> Vec<ColouredString>;
+ fn is_editing(&self) -> bool;
+}
+
pub struct MenuKeypressLine {
keypress: Keypress,
lwid: usize,
}
}
+impl<Value: Eq + Copy> RenderableMenuLine for CyclingMenuLine<Value> {
+ fn render_menu_line(&self, rc: &mut RenderContext) -> Vec<ColouredString> {
+ self.render(rc.w)
+ }
+ fn is_editing(&self) -> bool {
+ false
+ }
+}
+
#[test]
fn test_menu_keypress() {
let mut mk = MenuKeypressLine::new(