use super::grid;
use super::image;
use super::pack;
use super::widget;
use super::wish;
#[derive(Clone, Debug, PartialEq)]
pub struct TkCanvas {
pub id: String,
}
#[derive(Clone, Debug, PartialEq)]
pub struct TkCanvasArc {
pub canvas: String,
pub id: String,
}
#[derive(Clone, Debug, PartialEq)]
pub struct TkCanvasImage {
pub canvas: String,
pub id: String,
}
#[derive(Clone, Debug, PartialEq)]
pub struct TkCanvasLine {
pub canvas: String,
pub id: String,
}
#[derive(Clone, Debug, PartialEq)]
pub struct TkCanvasOval {
pub canvas: String,
pub id: String,
}
#[derive(Clone, Debug, PartialEq)]
pub struct TkCanvasPolygon {
pub canvas: String,
pub id: String,
}
#[derive(Clone, Debug, PartialEq)]
pub struct TkCanvasRectangle {
pub canvas: String,
pub id: String,
}
#[derive(Clone, Debug, PartialEq)]
pub struct TkCanvasText {
pub canvas: String,
pub id: String,
}
#[derive(Clone, Debug, PartialEq)]
pub struct TkCanvasWidget {
pub canvas: String,
pub id: String,
}
pub fn make_canvas(parent: &impl widget::TkWidget) -> TkCanvas {
let id = wish::next_wid(parent.id());
let msg = format!("canvas {}", id);
wish::tell_wish(&msg);
TkCanvas { id }
}
impl widget::TkWidget for TkCanvas {
fn id(&self) -> &str {
&self.id
}
}
impl grid::TkGridLayout for TkCanvas {}
impl pack::TkPackLayout for TkCanvas {}
impl TkCanvas {
pub fn background(&self, colour: &str) {
widget::configure(&self.id, "background", colour);
}
pub fn border_width(&self, width: u64) {
widget::configure(&self.id, "borderwidth", &width.to_string());
}
pub fn configure_tag(&self, tag: &str, option: &str, value: &str) {
let msg = format!(
"{} itemconfigure {} -{} {{{}}}",
&self.id, tag, option, value
);
wish::tell_wish(&msg);
}
pub fn create_arc(&self, (x1, y1): (u64, u64), (x2, y2): (u64, u64)) -> TkCanvasArc {
let msg = format!(
"puts [{} create arc {} {} {} {}] ; flush stdout",
&self.id, x1, y1, x2, y2
);
let id = wish::ask_wish(&msg);
TkCanvasArc {
canvas: self.id.clone(),
id,
}
}
pub fn create_image(&self, (x, y): (u64, u64), image: &image::TkImage) -> TkCanvasImage {
let msg = format!(
"puts [{} create image {} {} {}] ; flush stdout",
&self.id, x, y, &image.id
);
let id = wish::ask_wish(&msg);
TkCanvasImage {
canvas: self.id.clone(),
id,
}
}
pub fn create_line(&self, points: &[(u64, u64)]) -> TkCanvasLine {
let mut line_defn = String::new();
for (x, y) in points {
line_defn.push_str(&format!("{} {} ", x, y));
}
let msg = format!(
"puts [{} create line {}] ; flush stdout",
&self.id, &line_defn
);
let id = wish::ask_wish(&msg);
TkCanvasLine {
canvas: self.id.clone(),
id,
}
}
pub fn create_oval(&self, (x1, y1): (u64, u64), (x2, y2): (u64, u64)) -> TkCanvasOval {
let msg = format!(
"puts [{} create oval {} {} {} {}] ; flush stdout",
&self.id, x1, y1, x2, y2
);
let id = wish::ask_wish(&msg);
TkCanvasOval {
canvas: self.id.clone(),
id,
}
}
pub fn create_polygon(&self, points: &[(u64, u64)]) -> TkCanvasPolygon {
let mut line_defn = String::new();
for (x, y) in points {
line_defn.push_str(&format!("{} {} ", x, y));
}
let msg = format!(
"puts [{} create polygon {}] ; flush stdout",
&self.id, &line_defn
);
let id = wish::ask_wish(&msg);
TkCanvasPolygon {
canvas: self.id.clone(),
id,
}
}
pub fn create_rectangle(&self, (x1, y1): (u64, u64), (x2, y2): (u64, u64)) -> TkCanvasRectangle {
let msg = format!(
"puts [{} create rectangle {} {} {} {}] ; flush stdout",
&self.id, x1, y1, x2, y2
);
let id = wish::ask_wish(&msg);
TkCanvasRectangle {
canvas: self.id.clone(),
id,
}
}
pub fn create_text(&self, (x, y): (u64, u64), text: &str) -> TkCanvasText {
let msg = format!(
"puts [{} create text {} {} {{{}}}] ; flush stdout",
&self.id, x, y, text
);
let id = wish::ask_wish(&msg);
TkCanvasText {
canvas: self.id.clone(),
id,
}
}
pub fn create_widget(&self, (x, y): (u64, u64), widget: &impl widget::TkWidget) -> TkCanvasWidget {
let msg = format!(
"puts [{} create window {} {} {}] ; flush stdout",
&self.id,
x,
y,
widget.id()
);
let id = wish::ask_wish(&msg);
TkCanvasWidget {
canvas: self.id.clone(),
id,
}
}
pub fn delete(&self, item: &impl TkCanvasItem) {
let msg = format!("{} delete {}", &self.id, item.id());
wish::tell_wish(&msg);
}
pub fn height(&self, height: u64) {
widget::configure(&self.id, "height", &height.to_string());
}
pub fn relief(&self, value: widget::Relief) {
widget::configure(&self.id, "relief", &value.to_string());
}
pub fn state(&self, value: widget::State) {
widget::configure(&self.id, "state", &value.to_string());
}
pub fn width(&self, width: u64) {
widget::configure(&self.id, "width", &width.to_string());
}
}
pub trait TkCanvasItem {
fn canvas(&self) -> &str;
fn id(&self) -> &str;
fn bind(&self, pattern: &str, command: impl Fn(widget::TkEvent) + Send + 'static) {
let tag_pattern = format!("{}{}{}", self.canvas(), self.id(), pattern);
wish::add_callback1_event(&tag_pattern, wish::mk_callback1_event(command));
let msg = format!(
"{} bind {} {} {{ puts cb1e:{}:%x:%y:%X:%Y:%h:%w:%k:%K:%b ; flush stdout }}",
self.canvas(),
self.id(),
pattern,
tag_pattern
);
wish::tell_wish(&msg);
}
fn configure(&self, option: &str, value: &str) {
let msg = format!(
"{} itemconfigure {} -{} {{{}}}",
self.canvas(),
self.id(),
option,
value
);
wish::tell_wish(&msg);
}
}
pub trait TkCanvasTags: TkCanvasItem {
fn add_tag(&self, tag: &str) {
let msg = format!("{} addtag {} withtag {}", &self.canvas(), tag, &self.id());
wish::tell_wish(&msg);
}
fn delete_tag(&self, tag: &str) {
let msg = format!("{} dtag {} {}", &self.canvas(), &self.id(), tag);
wish::tell_wish(&msg);
}
fn get_tags(&self) -> Vec<String> {
let msg = format!("{} gettags {}", &self.canvas(), &self.id());
let tags = wish::ask_wish(&msg);
let mut result: Vec<String> = vec![];
for tag in tags.split_whitespace() {
result.push(String::from(tag));
}
result
}
}
pub enum TkArrowWhere {
Both,
First,
Last,
None,
}
pub enum TkArcStyle {
Arc,
Chord,
PieSlice,
}
pub enum TkCapStyle {
Butt,
Projecting,
Round,
}
pub enum TkDash {
Dot,
Dash,
DashDot,
DashDotDot,
}
pub enum TkJoinStyle {
Bevel,
Miter,
Round,
}
impl TkCanvasItem for TkCanvasArc {
fn canvas(&self) -> &str {
&self.canvas
}
fn id(&self) -> &str {
&self.id
}
}
impl TkCanvasTags for TkCanvasArc {}
impl TkCanvasArc {
pub fn dash(&self, dash: TkDash) {
let dash = match dash {
TkDash::Dot => ".",
TkDash::Dash => "-",
TkDash::DashDot => "-.",
TkDash::DashDotDot => "-..",
};
self.configure("dash", dash);
}
pub fn fill(&self, colour: &str) {
self.configure("fill", colour);
}
pub fn outline(&self, colour: &str) {
self.configure("outline", colour);
}
pub fn width(&self, value: u64) {
self.configure("width", &value.to_string());
}
pub fn extent(&self, degrees: u64) {
self.configure("extent", °rees.to_string());
}
pub fn start(&self, degrees: u64) {
self.configure("start", °rees.to_string());
}
pub fn style(&self, value: TkArcStyle) {
let value = match value {
TkArcStyle::Arc => "arc",
TkArcStyle::Chord => "chord",
TkArcStyle::PieSlice => "pieslice",
};
self.configure("style", value);
}
}
impl TkCanvasItem for TkCanvasImage {
fn canvas(&self) -> &str {
&self.canvas
}
fn id(&self) -> &str {
&self.id
}
}
impl TkCanvasTags for TkCanvasImage {}
impl TkCanvasImage {
pub fn anchor(&self, value: widget::Anchor) {
self.configure("anchor", &value.to_string());
}
}
impl TkCanvasItem for TkCanvasLine {
fn canvas(&self) -> &str {
&self.canvas
}
fn id(&self) -> &str {
&self.id
}
}
impl TkCanvasTags for TkCanvasLine {}
impl TkCanvasLine {
pub fn colour(&self, colour: &str) {
self.configure("fill", colour);
}
pub fn dash(&self, dash: TkDash) {
let dash = match dash {
TkDash::Dot => ".",
TkDash::Dash => "-",
TkDash::DashDot => "-.",
TkDash::DashDotDot => "-..",
};
self.configure("dash", dash);
}
pub fn width(&self, value: u64) {
self.configure("width", &value.to_string());
}
pub fn arrow(&self, value: TkArrowWhere) {
let value = match value {
TkArrowWhere::Both => "both",
TkArrowWhere::First => "first",
TkArrowWhere::Last => "last",
TkArrowWhere::None => "none",
};
self.configure("arrow", value);
}
pub fn arrow_shape(&self, v1: u64, v2: u64, v3: u64) {
let msg = format!("{{{} {} {} }}", v1, v2, v3);
self.configure("arrowshape", &msg);
}
pub fn cap_style(&self, value: TkCapStyle) {
let value = match value {
TkCapStyle::Butt => "butt",
TkCapStyle::Projecting => "projecting",
TkCapStyle::Round => "round",
};
self.configure("capstyle", value);
}
pub fn join_style(&self, value: TkJoinStyle) {
let value = match value {
TkJoinStyle::Bevel => "bevel",
TkJoinStyle::Miter => "miter",
TkJoinStyle::Round => "round",
};
self.configure("joinstyle", value);
}
}
impl TkCanvasItem for TkCanvasOval {
fn canvas(&self) -> &str {
&self.canvas
}
fn id(&self) -> &str {
&self.id
}
}
impl TkCanvasTags for TkCanvasOval {}
impl TkCanvasOval {
pub fn dash(&self, dash: TkDash) {
let dash = match dash {
TkDash::Dot => ".",
TkDash::Dash => "-",
TkDash::DashDot => "-.",
TkDash::DashDotDot => "-..",
};
self.configure("dash", dash);
}
pub fn fill(&self, colour: &str) {
self.configure("fill", colour);
}
pub fn outline(&self, colour: &str) {
self.configure("outline", colour);
}
pub fn width(&self, value: u64) {
self.configure("width", &value.to_string());
}
}
impl TkCanvasItem for TkCanvasPolygon {
fn canvas(&self) -> &str {
&self.canvas
}
fn id(&self) -> &str {
&self.id
}
}
impl TkCanvasTags for TkCanvasPolygon {}
impl TkCanvasPolygon {
pub fn dash(&self, dash: TkDash) {
let dash = match dash {
TkDash::Dot => ".",
TkDash::Dash => "-",
TkDash::DashDot => "-.",
TkDash::DashDotDot => "-..",
};
self.configure("dash", dash);
}
pub fn fill(&self, colour: &str) {
self.configure("fill", colour);
}
pub fn outline(&self, colour: &str) {
self.configure("outline", colour);
}
pub fn width(&self, value: u64) {
self.configure("width", &value.to_string());
}
pub fn join_style(&self, value: TkJoinStyle) {
let value = match value {
TkJoinStyle::Bevel => "bevel",
TkJoinStyle::Miter => "miter",
TkJoinStyle::Round => "round",
};
self.configure("joinstyle", value);
}
}
impl TkCanvasItem for TkCanvasRectangle {
fn canvas(&self) -> &str {
&self.canvas
}
fn id(&self) -> &str {
&self.id
}
}
impl TkCanvasTags for TkCanvasRectangle {}
impl TkCanvasRectangle {
pub fn dash(&self, dash: TkDash) {
let dash = match dash {
TkDash::Dot => ".",
TkDash::Dash => "-",
TkDash::DashDot => "-.",
TkDash::DashDotDot => "-..",
};
self.configure("dash", dash);
}
pub fn fill(&self, colour: &str) {
self.configure("fill", colour);
}
pub fn outline(&self, colour: &str) {
self.configure("outline", colour);
}
pub fn width(&self, value: u64) {
self.configure("width", &value.to_string());
}
}
impl TkCanvasItem for TkCanvasText {
fn canvas(&self) -> &str {
&self.canvas
}
fn id(&self) -> &str {
&self.id
}
}
impl TkCanvasTags for TkCanvasText {}
impl TkCanvasText {
pub fn anchor(&self, value: widget::Anchor) {
self.configure("anchor", &value.to_string());
}
pub fn colour(&self, colour: &str) {
self.configure("fill", colour);
}
pub fn angle(&self, degrees: f64) {
let degrees = degrees.max(0.0);
let degrees = degrees.min(360.0);
self.configure("angle", °rees.to_string());
}
pub fn font(&self, definition: &str) {
self.configure("font", definition);
}
pub fn justify(&self, value: widget::Justify) {
widget::configure(&self.id, "justify", &value.to_string());
}
pub fn text(&self, value: &str) {
self.configure("text", value);
}
pub fn underline(&self, index: u64) {
self.configure("underline", &index.to_string());
}
pub fn width(&self, value: i64) {
self.configure("width", &value.to_string());
}
}
impl TkCanvasItem for TkCanvasWidget {
fn canvas(&self) -> &str {
&self.canvas
}
fn id(&self) -> &str {
&self.id
}
}
impl TkCanvasTags for TkCanvasWidget {}
impl TkCanvasWidget {
pub fn anchor(&self, value: widget::Anchor) {
self.configure("anchor", &value.to_string());
}
}