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
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
use crate::data::input_state::InputState;
use crate::data::pointing::{KusaPoint, KusaSize};
use crate::grid::Grid;
use crate::paint_tool::circle_nib::CircleNib;
use crate::paint_tool::pen::*;
use crate::paint_tool::point_nib::PointNib;
use crate::paint_tool::screen_to_table;
use crate::paint_tool::square_nib::SquareNib;
use crate::paint_tool::Nib;
use crate::paint_tool::PaintOperation;
use crate::paint_tool::PaintTool;
use crate::piston_wrapper::kusa_image::KusaImage;
use crate::settings::Settings;
use crate::write_k_image;
use crate::KusaApp;
use piston_window::*;
pub fn show_window(app: &KusaApp, mut settings: Settings, k_image: &mut KusaImage) {
let opengl = OpenGL::V3_2;
let width = settings.canvas_margin_left
+ settings.image_width as f64 * settings.canvas_cell_size
+ settings.canvas_margin_right;
let height = settings.canvas_margin_top
+ settings.image_height as f64 * settings.canvas_cell_size
+ settings.canvas_margin_bottom;
let mut window: PistonWindow = WindowSettings::new("piston: image", [width, height])
.exit_on_esc(true)
.graphics_api(opengl)
.build()
.unwrap();
// let texture = create_texture(&settings.image_file, &mut window);
let mut input_state = InputState::default();
let mut k_mouse_cursor = KusaPoint::default();
let mut paint_tool = Pen {};
let paint_nib: &dyn Nib = match settings.paint_nib.as_str() {
"Point" => &(PointNib {}) as &dyn Nib,
"Square" => &(SquareNib {}) as &dyn Nib,
"Circle" => &(CircleNib {}) as &dyn Nib,
_ => &(SquareNib {}) as &dyn Nib,
};
let assets = find_folder::Search::ParentsThenKids(3, 3)
.for_folder("assets")
.unwrap();
//println!("{:?}", assets);
let mut glyphs = window
.load_font(assets.join("font/NotoSans-Medium.ttf"))
.unwrap();
let mut count_to_reload: u64 = 0;
let mut count_to_save: u64 = 0;
// Event loop.
window.set_lazy(true);
// フレームではなく、イベントが起こると1つ進む(^~^)?
while let Some(e) = window.next() {
//println!("Trace | window.next() time={}", count_to_reload); // FPSが分からん(^~^)
if count_to_reload % 120 == 119 {
// ミリ秒の取り方が分からなかったぜ☆(^~^)
// イベント・ループの中で ファイル入出力するのは クソだが 使い慣れてないんで仕方ないぜ☆(^~^)
// 設定ファイルを監視するぜ☆(^~^)
println!("Debug | Reload settings");
settings = match Settings::load(&app.settings_path) {
Ok(x) => x,
Err(why) => panic!("Settings load fail: {}", why),
};
paint_tool = match settings.paint_tool.as_str() {
"Pen" => Pen {},
_ => Pen {},
};
//println!(
// "Trace | Load settings☆(^~^) paint_tool=|{}|",
// settings.paint_tool
//);
count_to_reload = 0;
} else {
count_to_reload += 1;
}
// マウスカーソルの座標を補足するぜ☆(^~^)
e.mouse_cursor(|screen_coord| {
k_mouse_cursor = KusaPoint::from_coord(screen_coord);
});
// 📖 [Event](http://docs.piston.rs/piston_window/piston_window/enum.Event.html)
// ⚡Mouse button pressed
// 📖 [PressEvent](https://docs.piston.rs/piston_window/piston_window/trait.PressEvent.html)
if let Some(_button) = e.press_args() {
input_state.is_mouse_pressed = true;
input_state.pressed_point = k_mouse_cursor.clone();
//println!("Trace | ボタンが押されたぜ☆(^~^) {:?}", pressed_pos);
input_state.previous_point.x = input_state.pressed_point.x;
input_state.previous_point.y = input_state.pressed_point.y;
paint_tool.on_mouse_pressed(&settings, paint_nib, &input_state, k_image);
}
// TODO ⚡Mouse move
// 📖 [MouseRelativeEvent](https://docs.piston.rs/piston_window/piston_window/trait.MouseRelativeEvent.html)
if let Some(coord) = e.mouse_relative_args() {
let dx = coord[0];
let dy = coord[1];
if input_state.is_mouse_pressed {
input_state.moved_vector.x += dx;
input_state.moved_vector.y += dy;
//println!(
// "Trace | マウス移動中☆(^~^) ({:?}, {:?}) ({:?}, {:?})",
// dx, dy, pressed_pos.x, pressed_pos.y
//);
}
if paint_tool.on_mouse_moved(&settings, paint_nib, &input_state, k_image) {
if input_state.is_mouse_pressed {
// 更新
input_state.previous_point.x += input_state.moved_vector.x;
input_state.previous_point.y += input_state.moved_vector.y;
input_state.moved_vector.x = 0.0;
input_state.moved_vector.y = 0.0;
}
}
}
// ⚡Mouse button released
// 📖 [ReleaseEvent](https://docs.piston.rs/piston_window/piston_window/trait.ReleaseEvent.html)
if let Some(_button) = e.release_args() {
//println!("Trace | ボタンを離したぜ☆(^~^)");
paint_tool.on_mouse_released(&settings, &input_state, k_image);
input_state.is_mouse_pressed = false;
input_state.pressed_point.x = 0.0;
input_state.pressed_point.y = 0.0;
input_state.moved_vector.x = 0.0;
input_state.moved_vector.y = 0.0;
input_state.previous_point.x = 0.0;
input_state.previous_point.y = 0.0;
}
// ⚡Window paint
window.draw_2d(&e, |c, g, device| {
clear([1.0; 4], g);
/*
// 画像を丸ごと再描画します。
image(&texture, c.transform.zoom(settings.canvas_zoom), g);
*/
// 点を1個描くぜ☆(^~^)データとしての保存は別のところでやってるぜ☆(^~^)
// let sizing = KusaSize::diff(&cursor, &pressed_pos);
/*
if sizing.is_longer_width() {
// 横幅の方が長ければ。
for col in 1..(sizing.long_len() + 1) {
let y = sizing.get_a() * col as f64;
rectangle(
[1.0, 0.0, 0.0, 1.0], // red
[
pressed_pos.x + sizing.width,
pressed_pos.y + y,
100.0,
100.0,
],
c.transform,
g,
);
}
} else {
// 縦幅の方が長いか同じなら。
for row in 1..(sizing.long_len() + 1) {
let x = sizing.get_a() * row as f64;
rectangle(
[1.0, 0.0, 0.0, 1.0], // red
[
pressed_pos.x + x,
pressed_pos.y + sizing.height,
100.0,
100.0,
],
c.transform,
g,
);
}
}
*/
// 各マスに色を打っていくぜ☆(^~^)
PaintOperation::draw_image(&settings, &k_image, &c, g);
// TODO 今引こうとしている線を、データに描き込まずに画面に表示したいぜ☆(^~^)
// グリッド
let canvas_size = KusaSize {
width: settings.image_width as f64 * settings.canvas_cell_size,
height: settings.image_height as f64 * settings.canvas_cell_size,
};
Grid::draw(&settings, &canvas_size, &c, g);
if k_image.dirty && count_to_save % 128 == 0 {
// 保存
write_k_image(k_image, &settings.image_file);
count_to_save = 0;
} else {
count_to_save += 1;
}
// 情報表示(^~^)
{
let mut info_str = "".to_string();
// 画像の保存がまだなら表示(^~^)
if k_image.dirty {
info_str += "Unsaved ";
}
// 座標を表示したいぜ☆(^~^)
let coord = screen_to_table(&settings, &k_mouse_cursor);
info_str += &format!("Table({}, {}) ", coord.x, coord.y);
// 表示(^~^)
text::Text::new_color([0.0, 0.0, 0.0, 1.0], 32)
.draw(
&info_str,
&mut glyphs,
&c.draw_state,
c.transform.trans(10.0, 30.0), // y位置を揃えるのはむずかしいぜ☆(^~^)
g,
)
.unwrap();
}
// Update glyphs before rendering.
glyphs.factory.encoder.flush(device);
});
}
}