mod.rs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. mod canvas;
  2. mod picker;
  3. use gdk;
  4. use gtk::{
  5. self,
  6. BoxExt,
  7. EntryExt,
  8. ContainerExt,
  9. HeaderBarExt,
  10. PanedExt,
  11. WindowExt,
  12. WidgetExt,
  13. DialogExt,
  14. FileChooserExt,
  15. ButtonExt,
  16. };
  17. use std::process;
  18. use constants;
  19. use strings;
  20. use self::canvas::HexGridCanvas;
  21. use self::picker::Picker;
  22. /// The `App` is the main window that contains everything
  23. pub struct App {
  24. pub window: gtk::Window,
  25. pub canvas: HexGridCanvas,
  26. pub container: gtk::Paned,
  27. pub toolbar: Toolbar,
  28. pub header: Header,
  29. }
  30. impl App {
  31. fn new() -> App {
  32. let window = gtk::Window::new(gtk::WindowType::Toplevel);
  33. let container = gtk::Paned::new(gtk::Orientation::Horizontal);
  34. let header = Header::new();
  35. let canvas = HexGridCanvas::new();
  36. window.add_events(gdk::POINTER_MOTION_MASK.bits() as i32);
  37. window.set_titlebar(&header.container);
  38. window.set_title(constants::PROGRAM_NAME);
  39. window.set_wmclass(
  40. constants::PROGRAM_SLUG,
  41. constants::PROGRAM_NAME,
  42. );
  43. gtk::Window::set_default_icon_name("iconname");
  44. window.connect_delete_event(move |_, _| {
  45. gtk::main_quit();
  46. gtk::Inhibit(false)
  47. });
  48. let toolbar = Toolbar::new();
  49. container.pack1(&canvas.canvas, true, true);
  50. container.pack2(&toolbar.toolbar, false, true);
  51. window.add(&container);
  52. App { window, header, canvas, toolbar, container }
  53. }
  54. pub fn run() {
  55. if gtk::init().is_err() {
  56. eprintln!("Failed to initialize GTK application");
  57. process::exit(1);
  58. }
  59. let app = App::new();
  60. app.window.show_all();
  61. gtk::main();
  62. }
  63. }
  64. // HEADER
  65. /// The `Header` is the top toolbar; it contains buttons for opening
  66. /// and saving documents as well as document status
  67. pub struct Header {
  68. pub container: gtk::HeaderBar,
  69. pub open_btn: gtk::Button,
  70. pub save_btn: gtk::Button,
  71. pub save_as_btn: gtk::Button,
  72. }
  73. impl Header {
  74. fn new() -> Header {
  75. let container = gtk::HeaderBar::new();
  76. container.set_title(constants::PROGRAM_NAME);
  77. container.set_show_close_button(true);
  78. let open_btn = gtk::Button::new_with_label(
  79. strings::OPEN_BTN
  80. );
  81. let save_btn = gtk::Button::new_with_label(
  82. strings::SAVE_BTN,
  83. );
  84. let save_as_btn = gtk::Button::new_with_label(
  85. strings::SAVE_AS_BTN,
  86. );
  87. container.pack_start(&open_btn);
  88. container.pack_end(&save_btn);
  89. container.pack_end(&save_as_btn);
  90. open_btn.connect_clicked(Header::do_open);
  91. open_btn.connect_clicked(Header::do_save);
  92. open_btn.connect_clicked(Header::do_save);
  93. Header { container, open_btn, save_btn, save_as_btn }
  94. }
  95. fn do_open(_: &gtk::Button) {
  96. let open_dialog = gtk::FileChooserDialog::new(
  97. Some("Open"),
  98. Some(&gtk::Window::new(gtk::WindowType::Popup)),
  99. gtk::FileChooserAction::Open,
  100. );
  101. open_dialog.add_button(
  102. strings::CANCEL_DIALOG_BTN,
  103. gtk::ResponseType::Cancel.into(),
  104. );
  105. open_dialog.add_button(
  106. strings::OPEN_DIALOG_BTN,
  107. gtk::ResponseType::Ok.into(),
  108. );
  109. // if open_dialog.run() == gtk::ResponseType::Ok.into() {
  110. // println!("got {:?}", open_dialog.get_filename());
  111. // }
  112. open_dialog.destroy();
  113. }
  114. fn do_save(_: &gtk::Button) {
  115. let save_dialog = gtk::FileChooserDialog::new(
  116. Some("Open"),
  117. Some(&gtk::Window::new(gtk::WindowType::Popup)),
  118. gtk::FileChooserAction::Open,
  119. );
  120. save_dialog.add_button(
  121. strings::CANCEL_DIALOG_BTN,
  122. gtk::ResponseType::Cancel.into(),
  123. );
  124. save_dialog.add_button(
  125. strings::OPEN_DIALOG_BTN,
  126. gtk::ResponseType::Ok.into(),
  127. );
  128. // if save_dialog.run() == gtk::ResponseType::Ok.into() {
  129. // println!("got {:?}", save_dialog.get_filename());
  130. // }
  131. save_dialog.destroy();
  132. }
  133. }
  134. /// The `Toolbar` is the pane on the right that contains tileset
  135. /// information: this includes tileset info like width, height, and
  136. /// source image, as well as the tile picker for elsewhere
  137. pub struct Toolbar {
  138. toolbar: gtk::Box,
  139. tile_width: gtk::Entry,
  140. tile_height: gtk::Entry,
  141. load_tileset_btn: gtk::Button,
  142. picker: Picker,
  143. }
  144. impl Toolbar {
  145. fn new() -> Toolbar {
  146. let container = gtk::Box::new(gtk::Orientation::Vertical, 5);
  147. let tile_label = gtk::Label::new(
  148. strings::TILESET_LABEL,
  149. );
  150. let tile_width = gtk::Entry::new();
  151. tile_width.set_text("16");
  152. let tile_height = gtk::Entry::new();
  153. tile_height.set_text("16");
  154. let load_tileset_btn = gtk::Button::new_with_label(
  155. strings::TILESET_LOAD_BTN,
  156. );
  157. let picker = Picker::new();
  158. container.pack_start(&tile_label, false, true, 0);
  159. container.pack_start(&tile_width, false, true, 0);
  160. container.pack_start(&tile_height, false, true, 0);
  161. container.pack_start(&load_tileset_btn, false, true, 0);
  162. container.pack_start(&picker.canvas, false, true, 0);
  163. Toolbar {
  164. toolbar: container,
  165. tile_width,
  166. tile_height,
  167. load_tileset_btn,
  168. picker,
  169. }
  170. }
  171. }