Created
December 19, 2018 13:35
-
-
Save toshimasa-nanaki/58e686e3ccc6b9871aba415a17755a2c to your computer and use it in GitHub Desktop.
Rust 電卓アプリ ボタン生成をfor文にまとめる
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//クレートとしてconrodを読み込む | |
#[macro_use] extern crate conrod; | |
fn main() { | |
//featureモジュールのmain関数呼び出し | |
feature::main(); | |
} | |
//モジュール | |
mod feature { | |
//conrodで利用するものを宣言 | |
use conrod::backend::glium::glium::{self, Surface}; | |
use conrod::{self, widget, widget_ids, Labelable, Positionable, Sizeable, Widget}; | |
struct ButtonInfo { | |
widget_id2: conrod::widget::Id, | |
label: String, | |
value: char, | |
} | |
//publicなmain関数 | |
pub fn main() { | |
//画面の横縦サイズ宣言 | |
const WIDTH: u32 = 400; | |
const HEIGHT: u32 = 600; | |
//ループイベントオブジェクトを生成 | |
let mut events_loop = glium::glutin::EventsLoop::new(); | |
//gliumを使ってディスプレイ用のオブジェクトを作る | |
let window = glium::glutin::WindowBuilder::new() | |
.with_title("Calculator") | |
.with_dimensions((WIDTH, HEIGHT).into()); | |
let context = glium::glutin::ContextBuilder::new() | |
.with_vsync(true) | |
.with_multisampling(4); | |
let display = glium::Display::new(window, context, &events_loop).unwrap(); | |
// UIの組み立て | |
let mut ui = conrod::UiBuilder::new([WIDTH as f64, HEIGHT as f64]).build(); | |
// ウィジェットIDの生成 | |
widget_ids!(struct Ids { text, button1, button2, button3, button4, button5, button6, button7, button8, button9, button0, button_point, button_eq, button_plus, button_minus, button_multi, button_divide, textbox }); | |
let ids = Ids::new(ui.widget_id_generator()); | |
let button_map = vec![ | |
vec![ | |
ButtonInfo { | |
widget_id2: ids.button7, | |
label: "7".to_string(), | |
value: '7', | |
}, | |
ButtonInfo { | |
widget_id2: ids.button8, | |
label: "8".to_string(), | |
value: '8', | |
}, | |
ButtonInfo { | |
widget_id2: ids.button9, | |
label: "9".to_string(), | |
value: '9', | |
}, | |
ButtonInfo { | |
widget_id2: ids.button_divide, | |
label: "÷".to_string(), | |
value: '/', | |
}, | |
], | |
vec![ | |
ButtonInfo { | |
widget_id2: ids.button4, | |
label: "4".to_string(), | |
value: '4', | |
}, | |
ButtonInfo { | |
widget_id2: ids.button5, | |
label: "5".to_string(), | |
value: '5', | |
}, | |
ButtonInfo { | |
widget_id2: ids.button6, | |
label: "6".to_string(), | |
value: '6', | |
}, | |
ButtonInfo { | |
widget_id2: ids.button_multi, | |
label: "×".to_string(), | |
value: '*', | |
}, | |
], | |
vec![ | |
ButtonInfo { | |
widget_id2: ids.button1, | |
label: "1".to_string(), | |
value: '1', | |
}, | |
ButtonInfo { | |
widget_id2: ids.button2, | |
label: "2".to_string(), | |
value: '2', | |
}, | |
ButtonInfo { | |
widget_id2: ids.button3, | |
label: "3".to_string(), | |
value: '3', | |
}, | |
ButtonInfo { | |
widget_id2: ids.button_minus, | |
label: "ー".to_string(), | |
value: '-', | |
}, | |
], | |
vec![ | |
ButtonInfo { | |
widget_id2: ids.button0, | |
label: "0".to_string(), | |
value: '0', | |
}, | |
ButtonInfo { | |
widget_id2: ids.button_point, | |
label: ".".to_string(), | |
value: '.', | |
}, | |
ButtonInfo { | |
widget_id2: ids.button_eq, | |
label: "=".to_string(), | |
value: '=', | |
}, | |
ButtonInfo { | |
widget_id2: ids.button_plus, | |
label: "+".to_string(), | |
value: '+', | |
}, | |
], | |
]; | |
// フォントファイルの読み込み | |
const FONT_PATH: &'static str = | |
concat!(env!("CARGO_MANIFEST_DIR"), "/assets/fonts/ipag.ttf"); | |
ui.fonts.insert_from_file(FONT_PATH).unwrap(); | |
// gliumで描くためのオブジェクト | |
let mut renderer = conrod::backend::glium::Renderer::new(&display).unwrap(); | |
// ウィジェットと画像をマッピングさせたマップ(今は使わない) | |
let image_map = conrod::image::Map::<glium::texture::Texture2d>::new(); | |
let mut events = Vec::new(); | |
let mut num = vec![]; | |
let mut str_num: String = "".to_string(); | |
//無限ループ(イベントを待つ人) | |
'render: loop { | |
events.clear(); | |
// 最新のフレームからイベントをすべて取得する | |
events_loop.poll_events(|event| { | |
events.push(event); | |
}); | |
// イベントが取得できるまで待つ。 | |
if events.is_empty() { | |
events_loop.run_forever(|event| { | |
events.push(event); | |
glium::glutin::ControlFlow::Break | |
}); | |
} | |
// 取得したイベントを処理する | |
for event in events.drain(..) { | |
//表示されたWindow上でクローズボタンが押された場合などの処理。 | |
match event.clone() { | |
glium::glutin::Event::WindowEvent { event, .. } => match event { | |
glium::glutin::WindowEvent::CloseRequested | |
| glium::glutin::WindowEvent::KeyboardInput { | |
input: | |
glium::glutin::KeyboardInput { | |
virtual_keycode: Some(glium::glutin::VirtualKeyCode::Escape), | |
.. | |
}, | |
.. | |
} => break 'render, | |
_ => (), | |
}, | |
_ => (), | |
}; | |
// winitイベントをconrodイベントに変換する。 | |
let input = match conrod::backend::winit::convert_event(event, &display) { | |
None => continue, | |
Some(input) => input, | |
}; | |
// UIでハンドリング(これでButtonをクリックしたときのイベントとかを検知できる) | |
ui.handle_event(input); | |
// ウィジェットをUIにセットする | |
let ui = &mut ui.set_widgets(); | |
//計算表示 | |
widget::TextBox::new(&str_num) | |
.w_h(400.0, 40.0) | |
.top_left_of(ui.window) | |
.set(ids.textbox, ui); | |
let mut h = 1.0; | |
let mut w = 1.0; | |
for button_row in &button_map { | |
w = 1.0; | |
for button in button_row { | |
if widget::Button::new() | |
.w_h(40.0, 40.0) | |
.x_y(w * 70.0 - ui.win_w / 2.0, ui.win_h / 2.0 - h * 70.0) | |
.label(&button.label) | |
.label_font_size(16) | |
.set(button.widget_id2, ui) | |
.was_clicked() | |
{ | |
match button.value { | |
'=' => println!("equals"), | |
_ => { | |
num.push(button.value); | |
str_num.push_str(&button.label); | |
} | |
} | |
} | |
w = w + 1.0; | |
} | |
h = h + 1.0; | |
} | |
} | |
// uiが変わった場合に再描画する | |
if let Some(primitives) = ui.draw_if_changed() { | |
renderer.fill(&display, primitives, &image_map); | |
let mut target = display.draw(); | |
target.clear_color(0.0, 0.0, 0.0, 1.0); //背景色 | |
renderer.draw(&display, &mut target, &image_map).unwrap(); | |
target.finish().unwrap(); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment