1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
//! Pack layout - a geometry manager for arranging widgets.
//!
//! * also see the Tk [manual](http://www.tcl-lang.org/man/tcl8.6/TkCmd/pack.htm)
//!
//! The pack-layout is used in a "builder" style to layout a single widget:
//!
//! ```ignore
//! widget.pack()
//! .OPTION(VALUE) // 0 or more
//! .layout();
//! ```
//!
//! 1. `pack` is called first, to get the PackLayout instance.
//! 2. `layout` must be called last, to perform the layout.
//! 3. zero or more options are added to the PackLayout, to control the position
//! and layout of the widget.
use super::widget;
use super::wish;
/// Refers to the settings for a PackLayout.
///
/// Apart from `layout`, the methods on this struct set the values of different
/// options in a builder style: call `layout` to finish the layout.
///
#[derive(Clone, Debug)]
pub struct PackLayout {
id: String,
after: Option<String>,
anchor: widget::Anchor,
before: Option<String>,
expand: bool,
fill: widget::PackFill,
inside: Option<String>,
ipadx: Option<u64>,
ipady: Option<u64>,
padx: Option<u64>,
pady: Option<u64>,
side: widget::PackSide
}
impl PackLayout {
pub(super) fn new(wid: &str) -> PackLayout {
PackLayout {
id: String::from(wid),
after: None,
anchor: widget::Anchor::Centre,
before: None,
expand: false,
fill: widget::PackFill::None,
inside: None,
ipadx: None,
ipady: None,
padx: None,
pady: None,
side: widget::PackSide::Top,
}
}
/// Inserts this widget after given widget in its container and
/// in its packing order.
pub fn after(&mut self, widget: &impl widget::TkWidget) -> &mut Self {
self.after = Some(String::from(widget.id()));
self
}
/// Specifies position of this widget with respect to its container.
pub fn anchor(&mut self, value: widget::Anchor) -> &mut Self {
self.anchor = value;
self
}
/// Inserts this widget before given widget in its container and
/// in its packing order.
pub fn before(&mut self, widget: &impl widget::TkWidget) -> &mut Self {
self.before = Some(String::from(widget.id()));
self
}
/// Specifies whether widget should expand to fit its container.
pub fn expand(&mut self, value: bool) -> &mut Self {
self.expand = value;
self
}
/// Specifies how widget should expand to fill its container.
pub fn fill(&mut self, value: widget::PackFill) -> &mut Self {
self.fill = value;
self
}
/// Inserts this widget into container of given widget at the end of
/// its packing order.
pub fn inside(&mut self, widget: &impl widget::TkWidget) -> &mut Self {
self.inside = Some(String::from(widget.id()));
self
}
/// Horizontal padding (inside content border).
pub fn ipadx(&mut self, pad: u64) -> &mut Self {
self.ipadx = Some(pad);
self
}
/// Vertical padding (inside content border).
pub fn ipady(&mut self, pad: u64) -> &mut Self {
self.ipady = Some(pad);
self
}
/// Horizontal padding (outside content border).
pub fn padx(&mut self, pad: u64) -> &mut Self {
self.padx = Some(pad);
self
}
/// Vertical padding (outside content border).
pub fn pady(&mut self, pad: u64) -> &mut Self {
self.pady = Some(pad);
self
}
/// Specifies side of container that the widget is packed against.
pub fn side(&mut self, value: widget::PackSide) -> &mut Self {
self.side = value;
self
}
/// Called last to finally create the layout with the parameter values
/// set up by the builder.
pub fn layout(&self) {
let mut msg = format!("pack {} ", self.id);
if let Some(after) = &self.after {
msg.push_str(&format!("-after {} ", after));
}
msg.push_str(&format!("-anchor {} ", self.anchor));
if let Some(before) = &self.before {
msg.push_str(&format!("-before {} ", before));
}
if self.expand {
msg.push_str("-expand 1 ");
} else {
msg.push_str("-expand 0 ");
}
msg.push_str(&format!("-fill {} ", self.fill));
if let Some(inside) = &self.inside {
msg.push_str(&format!("-inside {} ", inside));
}
if let Some(pad) = self.ipadx {
msg.push_str(&format!("-ipadx {} ", pad));
}
if let Some(pad) = self.ipady {
msg.push_str(&format!("-ipady {} ", pad));
}
if let Some(pad) = self.padx {
msg.push_str(&format!("-padx {} ", pad));
}
if let Some(pad) = self.pady {
msg.push_str(&format!("-pady {} ", pad));
}
msg.push_str(&format!("-side {} ", self.side));
wish::tell_wish(&msg);
}
}
/// Common functions for widgets that can be arranged using GridLayouts
pub trait TkPackLayout: widget::TkWidget {
/// Creates a PackLayout instance for placing this widget within its parent
fn pack(&self) -> PackLayout {
PackLayout::new(self.id())
}
/// Sets properties for widget layout
fn pack_configure(&self, option: &str, value: &str) {
let msg = format!("pack configure {} -{} {{{}}}", self.id(), option, value);
wish::tell_wish(&msg);
}
/// Removes this widget from layout
fn pack_forget(&self) {
let msg = format!("pack forget {}", self.id());
wish::tell_wish(&msg);
}
}