Pronoun templating + example usage UI
This commit is contained in:
parent
e1e747d107
commit
e08573a443
|
@ -569,6 +569,12 @@ dependencies = [
|
|||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
|
@ -580,6 +586,31 @@ name = "serde"
|
|||
version = "1.0.137"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.137"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f26faba0c3959972377d3b2d306ee9f71faee9714294e41bb777f83f88578be"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.81"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook"
|
||||
|
@ -686,6 +717,16 @@ dependencies = [
|
|||
"num_threads",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinytemplate"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.5.9"
|
||||
|
@ -705,6 +746,8 @@ dependencies = [
|
|||
"num_enum",
|
||||
"protocol",
|
||||
"protocol-derive",
|
||||
"serde",
|
||||
"tinytemplate",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
@ -16,3 +16,5 @@ cursive = { version = "0.18", default-features = false, features = ["crossterm-b
|
|||
num_enum = "0.5"
|
||||
protocol = { path = "./protocol" }
|
||||
protocol-derive = { path = "./protocol-derive" }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
tinytemplate = "1.2.1"
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
warning: associated function is never used: `format_short`
|
||||
--> src/pronouns.rs:71:12
|
||||
|
|
||||
71 | pub fn format_short(&self) -> String {
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(dead_code)]` on by default
|
||||
|
||||
warning: field is never read: `edit_receiver`
|
||||
--> src/tui.rs:17:5
|
||||
|
|
||||
17 | edit_receiver: Receiver<EditEvent>,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: field is never read: `identity`
|
||||
--> src/tui.rs:18:5
|
||||
|
|
||||
18 | identity: Identity,
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: `udp-mud` (bin "udp-mud") generated 3 warnings
|
||||
Finished release [optimized] target(s) in 0.05s
|
||||
Running `target/release/udp-mud --username server --bind-addr '0.0.0.0:54321' --connect '98.43.173.90:54321'`
|
|
@ -1,4 +1,11 @@
|
|||
use protocol_derive::{Decode, Encode};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
pub const EXAMPLE_USAGE: &str = "{S} went to the park.
|
||||
I went with {o}.
|
||||
{S} brought {p} frisbee.
|
||||
At least I think it was {pp}.
|
||||
{S} threw the frisbee to {r}.";
|
||||
|
||||
pub fn make_presets() -> Vec<Pronouns> {
|
||||
// TODO add more from https://pronoun.is and https://askanonbinary.tumblr.com/pronouns
|
||||
|
@ -98,4 +105,78 @@ impl Pronouns {
|
|||
pronouns
|
||||
}
|
||||
}
|
||||
|
||||
pub fn make_table(&self) -> PronounTable {
|
||||
let capitalize = |s: &String| {
|
||||
if self.case_sensitive {
|
||||
s.to_string()
|
||||
} else if s.len() > 0 {
|
||||
let mut capitalized = s.get(0..1).unwrap().to_uppercase().to_string();
|
||||
capitalized.push_str(&s[1..]);
|
||||
capitalized.to_string()
|
||||
} else {
|
||||
"".to_string()
|
||||
}
|
||||
};
|
||||
|
||||
PronounTable {
|
||||
case_sensitive: self.case_sensitive,
|
||||
plural: self.plural,
|
||||
subject: self.subject.clone(),
|
||||
object: self.object.clone(),
|
||||
possessive: self.possessive.clone(),
|
||||
possessive_pronoun: self.possessive_pronoun.clone(),
|
||||
reflexive: self.reflexive.clone(),
|
||||
subject_capitalized: capitalize(&self.subject),
|
||||
object_capitalized: capitalize(&self.object),
|
||||
possessive_capitalized: capitalize(&self.possessive),
|
||||
possessive_pronoun_capitalized: capitalize(&self.possessive_pronoun),
|
||||
reflexive_capitalized: capitalize(&self.reflexive),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn make_example_usage(&self) -> String {
|
||||
let table = self.make_table();
|
||||
let mut tt = tinytemplate::TinyTemplate::new();
|
||||
tt.set_default_formatter(&tinytemplate::format_unescaped);
|
||||
tt.add_template("example_usage", EXAMPLE_USAGE).unwrap();
|
||||
tt.render("example_usage", &table).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
/// Baked pronoun lookup table for formatting messages.
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
pub struct PronounTable {
|
||||
pub case_sensitive: bool,
|
||||
pub plural: bool,
|
||||
|
||||
#[serde(rename = "s")]
|
||||
pub subject: String,
|
||||
|
||||
#[serde(rename = "o")]
|
||||
pub object: String,
|
||||
|
||||
#[serde(rename = "p")]
|
||||
pub possessive: String,
|
||||
|
||||
#[serde(rename = "pp")]
|
||||
pub possessive_pronoun: String,
|
||||
|
||||
#[serde(rename = "r")]
|
||||
pub reflexive: String,
|
||||
|
||||
#[serde(rename = "S")]
|
||||
pub subject_capitalized: String,
|
||||
|
||||
#[serde(rename = "O")]
|
||||
pub object_capitalized: String,
|
||||
|
||||
#[serde(rename = "P")]
|
||||
pub possessive_capitalized: String,
|
||||
|
||||
#[serde(rename = "PP")]
|
||||
pub possessive_pronoun_capitalized: String,
|
||||
|
||||
#[serde(rename = "R")]
|
||||
pub reflexive_capitalized: String,
|
||||
}
|
||||
|
|
164
src/tui.rs
164
src/tui.rs
|
@ -103,34 +103,57 @@ impl Tui {
|
|||
siv.add_layer(dialog);
|
||||
}
|
||||
|
||||
fn make_example_usage_panel() -> impl View {
|
||||
let text = TextView::new("Highlight a pronoun set to preview its usage!")
|
||||
.with_name("pronoun_example_text")
|
||||
.fixed_width(50)
|
||||
.scrollable();
|
||||
Panel::new(text).title("Example Usage")
|
||||
}
|
||||
|
||||
fn update_pronouns_edit(siv: &mut Cursive, pronouns: &Pronouns) {
|
||||
siv.call_on_name("pronoun_example_text", |view: &mut TextView| {
|
||||
view.set_content(pronouns.make_example_usage());
|
||||
});
|
||||
|
||||
siv.with_user_data(|sender: &mut Sender<EditEvent>| {
|
||||
sender
|
||||
.send(EditEvent::Pronouns(Some(pronouns.clone())))
|
||||
.unwrap();
|
||||
});
|
||||
|
||||
siv.call_on_name("pronouns_text", |view: &mut TextView| {
|
||||
view.set_content(pronouns.format_full());
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
pub fn select_pronouns(siv: &mut Cursive) {
|
||||
let example = TextView::new("Highlight a pronoun set to preview its usage!")
|
||||
.with_name("pronoun_example_text")
|
||||
.fixed_width(35)
|
||||
.scrollable();
|
||||
|
||||
let presets = SelectView::new()
|
||||
.with_all(
|
||||
crate::pronouns::make_presets()
|
||||
.into_iter()
|
||||
.map(|pronouns| (pronouns.format_full(), pronouns)),
|
||||
)
|
||||
.on_submit(|siv, pronouns| {
|
||||
siv.with_user_data(|sender: &mut Sender<EditEvent>| {
|
||||
sender
|
||||
.send(EditEvent::Pronouns(Some(pronouns.clone())))
|
||||
.unwrap();
|
||||
});
|
||||
|
||||
siv.call_on_name("pronouns_text", |view: &mut TextView| {
|
||||
view.set_content(pronouns.format_full());
|
||||
})
|
||||
.unwrap();
|
||||
siv.pop_layer();
|
||||
})
|
||||
.on_select(|siv, pronouns| Self::update_pronouns_edit(siv, pronouns))
|
||||
.scrollable();
|
||||
|
||||
let dialog = Dialog::around(presets)
|
||||
let layout = LinearLayout::horizontal()
|
||||
.child(Panel::new(presets).title("Presets"))
|
||||
.child(Panel::new(example).title("Example Usage"));
|
||||
|
||||
let dialog = Dialog::around(layout)
|
||||
.title("Select Pronouns")
|
||||
.button("Custom...", |siv| {
|
||||
siv.pop_layer();
|
||||
Self::edit_pronouns(siv);
|
||||
})
|
||||
.dismiss_button("Ok")
|
||||
.button("None", |siv| {
|
||||
siv.with_user_data(|sender: &mut Sender<EditEvent>| {
|
||||
sender.send(EditEvent::Pronouns(None)).unwrap();
|
||||
|
@ -140,11 +163,30 @@ impl Tui {
|
|||
})
|
||||
.unwrap();
|
||||
siv.pop_layer();
|
||||
})
|
||||
.dismiss_button("Cancel");
|
||||
});
|
||||
siv.add_layer(dialog);
|
||||
}
|
||||
|
||||
fn get_edit_pronouns(siv: &mut Cursive) -> Pronouns {
|
||||
let case_sensitive = get_checkbox_contents(siv, "case_sensitive_edit");
|
||||
let plural = get_checkbox_contents(siv, "plural_edit");
|
||||
let subject = get_edit_contents(siv, "subject_edit");
|
||||
let object = get_edit_contents(siv, "object_edit");
|
||||
let possessive = get_edit_contents(siv, "possessive_edit");
|
||||
let possessive_pronoun = get_edit_contents(siv, "possessive_pronoun_edit");
|
||||
let reflexive = get_edit_contents(siv, "reflexive_edit");
|
||||
|
||||
Pronouns {
|
||||
case_sensitive,
|
||||
plural,
|
||||
subject,
|
||||
object,
|
||||
possessive,
|
||||
possessive_pronoun,
|
||||
reflexive,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn edit_pronouns(siv: &mut Cursive) {
|
||||
let labels = make_vertical_labels(&[
|
||||
"Case-sensitive:",
|
||||
|
@ -157,52 +199,58 @@ impl Tui {
|
|||
])
|
||||
.fixed_width(20);
|
||||
|
||||
let values = LinearLayout::vertical()
|
||||
.child(Checkbox::new().with_name("case_sensitive_edit"))
|
||||
.child(Checkbox::new().with_name("plural_edit"))
|
||||
.child(EditView::new().with_name("subject_edit"))
|
||||
.child(EditView::new().with_name("object_edit"))
|
||||
.child(EditView::new().with_name("possessive_edit"))
|
||||
.child(EditView::new().with_name("possessive_pronoun_edit"))
|
||||
.child(EditView::new().with_name("reflexive_edit"))
|
||||
.fixed_width(12);
|
||||
let mut values = LinearLayout::vertical();
|
||||
|
||||
let columns = LinearLayout::horizontal().child(labels).child(values);
|
||||
let mut dialog = Dialog::around(columns);
|
||||
dialog.set_title("Edit Pronouns");
|
||||
dialog.add_button("Ok", |siv| {
|
||||
let case_sensitive = get_checkbox_contents(siv, "case_sensitive_edit");
|
||||
let plural = get_checkbox_contents(siv, "plural_edit");
|
||||
let subject = get_edit_contents(siv, "subject_edit");
|
||||
let object = get_edit_contents(siv, "object_edit");
|
||||
let possessive = get_edit_contents(siv, "possessive_edit");
|
||||
let possessive_pronoun = get_edit_contents(siv, "possessive_pronoun_edit");
|
||||
let reflexive = get_edit_contents(siv, "reflexive_edit");
|
||||
let checkboxes = &["case_sensitive_edit", "plural_edit"];
|
||||
|
||||
let pronouns = Pronouns {
|
||||
case_sensitive,
|
||||
plural,
|
||||
subject,
|
||||
object,
|
||||
possessive,
|
||||
possessive_pronoun,
|
||||
reflexive,
|
||||
};
|
||||
for name in checkboxes.iter() {
|
||||
values.add_child(
|
||||
Checkbox::new()
|
||||
.on_change(|siv, _value| {
|
||||
let pronouns = Self::get_edit_pronouns(siv);
|
||||
Self::update_pronouns_edit(siv, &pronouns);
|
||||
})
|
||||
.with_name(*name),
|
||||
);
|
||||
}
|
||||
|
||||
siv.call_on_name("pronouns_text", |view: &mut TextView| {
|
||||
view.set_content(pronouns.format_full());
|
||||
let edit_views = &[
|
||||
"subject_edit",
|
||||
"object_edit",
|
||||
"possessive_edit",
|
||||
"possessive_pronoun_edit",
|
||||
"reflexive_edit",
|
||||
];
|
||||
|
||||
for name in edit_views.iter() {
|
||||
values.add_child(
|
||||
EditView::new()
|
||||
.on_edit(|siv, _text, _cursor| {
|
||||
let pronouns = Self::get_edit_pronouns(siv);
|
||||
Self::update_pronouns_edit(siv, &pronouns);
|
||||
})
|
||||
.with_name(*name),
|
||||
);
|
||||
}
|
||||
|
||||
let edit_layout = Panel::new(
|
||||
LinearLayout::horizontal()
|
||||
.child(labels)
|
||||
.child(values.fixed_width(12)),
|
||||
);
|
||||
|
||||
let example = Self::make_example_usage_panel();
|
||||
|
||||
let layout = LinearLayout::horizontal().child(edit_layout).child(example);
|
||||
|
||||
let dialog = Dialog::around(layout)
|
||||
.title("Edit Pronouns")
|
||||
.button("Ok", |siv| {
|
||||
let pronouns = Self::get_edit_pronouns(siv);
|
||||
Self::update_pronouns_edit(siv, &pronouns);
|
||||
siv.pop_layer();
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
siv.with_user_data(|sender: &mut Sender<EditEvent>| {
|
||||
sender.send(EditEvent::Pronouns(Some(pronouns))).unwrap();
|
||||
});
|
||||
|
||||
siv.pop_layer();
|
||||
});
|
||||
dialog.add_button("Cancel", |siv| {
|
||||
siv.pop_layer().unwrap();
|
||||
});
|
||||
.dismiss_button("Cancel");
|
||||
|
||||
siv.add_layer(dialog);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue