Pronoun templating + example usage UI
This commit is contained in:
parent
e1e747d107
commit
e08573a443
|
@ -569,6 +569,12 @@ dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ryu"
|
||||||
|
version = "1.0.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scopeguard"
|
name = "scopeguard"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
|
@ -580,6 +586,31 @@ name = "serde"
|
||||||
version = "1.0.137"
|
version = "1.0.137"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "61ea8d54c77f8315140a05f4c7237403bf38b72704d031543aa1d16abbf517d1"
|
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]]
|
[[package]]
|
||||||
name = "signal-hook"
|
name = "signal-hook"
|
||||||
|
@ -686,6 +717,16 @@ dependencies = [
|
||||||
"num_threads",
|
"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]]
|
[[package]]
|
||||||
name = "toml"
|
name = "toml"
|
||||||
version = "0.5.9"
|
version = "0.5.9"
|
||||||
|
@ -705,6 +746,8 @@ dependencies = [
|
||||||
"num_enum",
|
"num_enum",
|
||||||
"protocol",
|
"protocol",
|
||||||
"protocol-derive",
|
"protocol-derive",
|
||||||
|
"serde",
|
||||||
|
"tinytemplate",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -16,3 +16,5 @@ cursive = { version = "0.18", default-features = false, features = ["crossterm-b
|
||||||
num_enum = "0.5"
|
num_enum = "0.5"
|
||||||
protocol = { path = "./protocol" }
|
protocol = { path = "./protocol" }
|
||||||
protocol-derive = { path = "./protocol-derive" }
|
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 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> {
|
pub fn make_presets() -> Vec<Pronouns> {
|
||||||
// TODO add more from https://pronoun.is and https://askanonbinary.tumblr.com/pronouns
|
// TODO add more from https://pronoun.is and https://askanonbinary.tumblr.com/pronouns
|
||||||
|
@ -98,4 +105,78 @@ impl Pronouns {
|
||||||
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);
|
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) {
|
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()
|
let presets = SelectView::new()
|
||||||
.with_all(
|
.with_all(
|
||||||
crate::pronouns::make_presets()
|
crate::pronouns::make_presets()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|pronouns| (pronouns.format_full(), pronouns)),
|
.map(|pronouns| (pronouns.format_full(), pronouns)),
|
||||||
)
|
)
|
||||||
.on_submit(|siv, pronouns| {
|
.on_select(|siv, pronouns| Self::update_pronouns_edit(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();
|
|
||||||
})
|
|
||||||
.scrollable();
|
.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")
|
.title("Select Pronouns")
|
||||||
.button("Custom...", |siv| {
|
.button("Custom...", |siv| {
|
||||||
siv.pop_layer();
|
siv.pop_layer();
|
||||||
Self::edit_pronouns(siv);
|
Self::edit_pronouns(siv);
|
||||||
})
|
})
|
||||||
|
.dismiss_button("Ok")
|
||||||
.button("None", |siv| {
|
.button("None", |siv| {
|
||||||
siv.with_user_data(|sender: &mut Sender<EditEvent>| {
|
siv.with_user_data(|sender: &mut Sender<EditEvent>| {
|
||||||
sender.send(EditEvent::Pronouns(None)).unwrap();
|
sender.send(EditEvent::Pronouns(None)).unwrap();
|
||||||
|
@ -140,11 +163,30 @@ impl Tui {
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
siv.pop_layer();
|
siv.pop_layer();
|
||||||
})
|
});
|
||||||
.dismiss_button("Cancel");
|
|
||||||
siv.add_layer(dialog);
|
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) {
|
pub fn edit_pronouns(siv: &mut Cursive) {
|
||||||
let labels = make_vertical_labels(&[
|
let labels = make_vertical_labels(&[
|
||||||
"Case-sensitive:",
|
"Case-sensitive:",
|
||||||
|
@ -157,52 +199,58 @@ impl Tui {
|
||||||
])
|
])
|
||||||
.fixed_width(20);
|
.fixed_width(20);
|
||||||
|
|
||||||
let values = LinearLayout::vertical()
|
let mut 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 columns = LinearLayout::horizontal().child(labels).child(values);
|
let checkboxes = &["case_sensitive_edit", "plural_edit"];
|
||||||
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 pronouns = Pronouns {
|
for name in checkboxes.iter() {
|
||||||
case_sensitive,
|
values.add_child(
|
||||||
plural,
|
Checkbox::new()
|
||||||
subject,
|
.on_change(|siv, _value| {
|
||||||
object,
|
let pronouns = Self::get_edit_pronouns(siv);
|
||||||
possessive,
|
Self::update_pronouns_edit(siv, &pronouns);
|
||||||
possessive_pronoun,
|
})
|
||||||
reflexive,
|
.with_name(*name),
|
||||||
};
|
);
|
||||||
|
}
|
||||||
|
|
||||||
siv.call_on_name("pronouns_text", |view: &mut TextView| {
|
let edit_views = &[
|
||||||
view.set_content(pronouns.format_full());
|
"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();
|
.dismiss_button("Cancel");
|
||||||
|
|
||||||
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();
|
|
||||||
});
|
|
||||||
|
|
||||||
siv.add_layer(dialog);
|
siv.add_layer(dialog);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue