main.rs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. use anyhow::{anyhow, bail, Result};
  2. use gtk::{
  3. BoxExt, ButtonExt, ContainerExt, EditableSignals, EntryExt, GtkWindowExt, LabelExt, WidgetExt,
  4. };
  5. use std::cell::RefCell;
  6. use std::rc::Rc;
  7. mod dmc;
  8. struct AppData {
  9. symbol: char,
  10. dmc: Option<dmc::DMC>,
  11. }
  12. impl AppData {
  13. fn draw_to_file(&self) -> Result<()> {
  14. let f = std::fs::File::create("samp.svg")?;
  15. let surf = cairo::SvgSurface::for_stream(100.0, 100.0, f)?;
  16. self.render(&cairo::Context::new(&surf))?;
  17. if let Err(err) = surf.finish_output_stream() {
  18. bail!(err.error);
  19. };
  20. Ok(())
  21. }
  22. fn render(&self, ctx: &cairo::Context) -> Result<()> {
  23. let color = self.color();
  24. ctx.set_source_rgb(color.0, color.1, color.2);
  25. ctx.paint();
  26. ctx.set_source_rgb(0., 0., 0.);
  27. ctx.move_to(0.0, -23.0);
  28. let layout = pangocairo::functions::create_layout(&ctx)
  29. .ok_or_else(|| anyhow!("Could not create layout"))?;
  30. layout.set_width(100 * 1024);
  31. layout.set_alignment(pango::Alignment::Center);
  32. let font = pango::FontDescription::from_string("Fira Sans 92");
  33. layout.set_font_description(Some(&font));
  34. layout.set_text(&self.symbol.to_string());
  35. pangocairo::functions::show_layout(&ctx, &layout);
  36. Ok(())
  37. }
  38. fn color(&self) -> (f64, f64, f64) {
  39. self.dmc
  40. .map(|dmc| dmc.color)
  41. .unwrap_or_else(|| (0.5, 0.5, 0.5))
  42. }
  43. }
  44. #[derive(Clone)]
  45. struct App {
  46. data: Rc<RefCell<AppData>>,
  47. }
  48. impl App {
  49. fn new() -> App {
  50. let app_data = AppData {
  51. symbol: 'X',
  52. dmc: None,
  53. };
  54. let data = Rc::new(RefCell::new(app_data));
  55. App { data }
  56. }
  57. }
  58. fn mk_app() {
  59. let app = App::new();
  60. let window = gtk::Window::new(gtk::WindowType::Toplevel);
  61. window.connect_delete_event(move |_, _| {
  62. gtk::main_quit();
  63. gtk::Inhibit(false)
  64. });
  65. window.set_title("I Am Legend");
  66. window.set_default_size(500, 100);
  67. window.set_resizable(false);
  68. let container = gtk::Box::new(gtk::Orientation::Vertical, 4);
  69. container.pack_start(&mk_icon_choice('A', app.clone()), false, true, 0);
  70. container.pack_start(&mk_icon_choice('B', app.clone()), false, true, 0);
  71. container.pack_start(&mk_icon_choice('C', app.clone()), false, true, 0);
  72. container.pack_start(&mk_icon_choice('D', app.clone()), false, true, 0);
  73. let flow = gtk::Box::new(gtk::Orientation::Horizontal, 2);
  74. flow.pack_start(&container, false, true, 0);
  75. let container = gtk::Box::new(gtk::Orientation::Vertical, 2);
  76. let label = gtk::Label::new(None);
  77. {
  78. let color = gtk::Entry::new();
  79. let app = app.clone();
  80. let window = window.clone();
  81. let label = label.clone();
  82. color.connect_changed(move |s| {
  83. let str = s.get_text();
  84. if let Some(color) = dmc::LOOKUP.get(str.as_str()) {
  85. app.data.borrow_mut().dmc = Some(*color.clone());
  86. label.set_text(color.name);
  87. } else {
  88. app.data.borrow_mut().dmc = None;
  89. label.set_text("");
  90. }
  91. window.queue_draw_area(0, 0, 500, 100);
  92. });
  93. container.pack_start(&color, false, true, 0);
  94. }
  95. {
  96. let button = gtk::Button::with_label("EXPORT IT");
  97. let app = app.clone();
  98. button.connect_clicked(move |_| {
  99. if let Err(err) = app.data.borrow_mut().draw_to_file() {
  100. eprintln!("Error in rendering: {}", err);
  101. }
  102. });
  103. container.pack_start(&button, false, true, 0);
  104. }
  105. container.pack_start(&label, false, true, 0);
  106. flow.pack_start(&container, false, true, 0);
  107. {
  108. let canvas = gtk::DrawingArea::new();
  109. canvas.connect_draw(move |_cv, ctx| {
  110. if let Err(err) = app.data.borrow_mut().render(ctx) {
  111. eprintln!("Error in rendering: {}", err);
  112. }
  113. gtk::Inhibit(false)
  114. });
  115. flow.pack_start(&canvas, true, true, 0);
  116. }
  117. window.add(&flow);
  118. window.show_all();
  119. }
  120. fn mk_icon_choice(choice: char, cell: App) -> gtk::Button {
  121. let button = gtk::Button::with_label(&choice.to_string());
  122. button.connect_clicked(move |_| {
  123. cell.data.borrow_mut().symbol = choice;
  124. println!("Choosing '{}'", choice);
  125. });
  126. button
  127. }
  128. fn main() {
  129. if gtk::init().is_err() {
  130. eprintln!("Failed to initialize GTK application");
  131. } else {
  132. mk_app();
  133. gtk::main();
  134. }
  135. }