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
use canvas;
use color::{Color, black, white};
use position::{Margin, Padding, Position, HorizontalAlign, VerticalAlign};
use rustc_serialize::{json, Encodable, Decodable};
use std::borrow::ToOwned;
use std::error::Error;
use std::fs::File;
use std::path::Path;
use std::str;
use widget::{button};
#[derive(Debug, Clone, RustcEncodable, RustcDecodable)]
pub struct Theme {
pub name: String,
pub padding: Padding,
pub margin: Margin,
pub position: Position,
pub align: Align,
pub background_color: Color,
pub shape_color: Color,
pub frame_color: Color,
pub frame_width: f64,
pub label_color: Color,
pub font_size_large: u32,
pub font_size_medium: u32,
pub font_size_small: u32,
pub maybe_canvas_split: Option<canvas::split::Style>,
pub maybe_button: Option<button::Style>,
}
#[derive(Debug, Clone, RustcEncodable, RustcDecodable)]
pub struct Align {
pub horizontal: HorizontalAlign,
pub vertical: VerticalAlign,
}
impl Theme {
pub fn default() -> Theme {
Theme {
name: "Demo Theme".to_string(),
padding: Padding {
top: 0.0,
bottom: 0.0,
left: 0.0,
right: 0.0,
},
margin: Margin {
top: 0.0,
bottom: 0.0,
left: 0.0,
right: 0.0,
},
position: Position::default(),
align: Align {
horizontal: HorizontalAlign::Left,
vertical: VerticalAlign::Top,
},
background_color: black(),
shape_color: white(),
frame_color: black(),
frame_width: 1.0,
label_color: black(),
font_size_large: 26,
font_size_medium: 18,
font_size_small: 12,
maybe_canvas_split: None,
maybe_button: None,
}
}
pub fn load(path: &str) -> Result<Theme, String> {
let mut file = match File::open(&Path::new(path)) {
Ok(file) => file,
Err(e) => return Err(format!("Failed to open file for Theme: {}",
Error::description(&e))),
};
let mut contents = Vec::new();
if let Err(e) = ::std::io::Read::read_to_end(&mut file, &mut contents) {
return Err(format!("Failed to load Theme correctly: {}",
Error::description(&e)));
}
let json_object = match json::Json::from_str(str::from_utf8(&contents[..]).unwrap()) {
Ok(json_object) => json_object,
Err(e) => return Err(format!("Failed to construct json_object from str: {}",
Error::description(&e))),
};
let mut decoder = json::Decoder::new(json_object);
let theme = match Decodable::decode(&mut decoder) {
Ok(theme) => Ok(theme),
Err(e) => Err(format!("Failed to construct Theme from json decoder: {}",
Error::description(&e))),
};
theme
}
pub fn save(&self, path: &str) -> Result<(), String> {
let json_string = match json::encode(self) {
Ok(x) => x,
Err(e) => return Err(e.description().to_owned())
};
let mut file = match File::create(&Path::new(path)) {
Ok(file) => file,
Err(e) => return Err(format!("Failed to create a File at the given path: {}",
Error::description(&e)))
};
match ::std::io::Write::write_all(&mut file, json_string.as_bytes()) {
Ok(()) => Ok(()),
Err(e) => Err(format!("Theme failed to save correctly: {}", Error::description(&e))),
}
}
}