Skip to content

Instantly share code, notes, and snippets.

@toshimasa-nanaki
Created December 19, 2018 13:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save toshimasa-nanaki/58e686e3ccc6b9871aba415a17755a2c to your computer and use it in GitHub Desktop.
Save toshimasa-nanaki/58e686e3ccc6b9871aba415a17755a2c to your computer and use it in GitHub Desktop.
Rust 電卓アプリ ボタン生成をfor文にまとめる
//クレートとして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