main.rs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. use anyhow::{anyhow, bail, Result};
  2. use gio::prelude::{ApplicationExt, ApplicationExtManual};
  3. use gtk::{
  4. Application, ApplicationWindow, BoxExt, Button, ButtonExt, ContainerExt, GtkWindowExt,
  5. WidgetExt,
  6. };
  7. use std::cell::RefCell;
  8. use std::rc::Rc;
  9. struct AppData {
  10. symbol: char,
  11. color: (f64, f64, f64),
  12. }
  13. impl AppData {
  14. fn draw_to_file(&self) -> Result<()> {
  15. let f = std::fs::File::create("samp.svg")?;
  16. let surf = cairo::SvgSurface::for_stream(100.0, 100.0, f)?;
  17. self.render(&cairo::Context::new(&surf))?;
  18. if let Err(err) = surf.finish_output_stream() {
  19. bail!(err.error);
  20. };
  21. Ok(())
  22. }
  23. fn render(&self, ctx: &cairo::Context) -> Result<()> {
  24. ctx.set_source_rgb(self.color.0, self.color.1, self.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. }
  39. #[derive(Clone)]
  40. struct App {
  41. data: Rc<RefCell<AppData>>,
  42. }
  43. impl App {
  44. fn new() -> App {
  45. let app_data = AppData {
  46. symbol: 'X',
  47. color: (0.5, 0.5, 0.5),
  48. };
  49. let data = Rc::new(RefCell::new(app_data));
  50. App { data }
  51. }
  52. }
  53. fn mk_app(app: &gtk::Application) {
  54. let window = ApplicationWindow::new(app);
  55. let app = App::new();
  56. window.set_title("I Am Legend");
  57. let container = gtk::Box::new(gtk::Orientation::Vertical, 4);
  58. container.pack_start(&mk_icon_choice('A', app.clone()), false, true, 0);
  59. container.pack_start(&mk_icon_choice('B', app.clone()), false, true, 0);
  60. container.pack_start(&mk_icon_choice('C', app.clone()), false, true, 0);
  61. container.pack_start(&mk_icon_choice('D', app.clone()), false, true, 0);
  62. let flow = gtk::Box::new(gtk::Orientation::Horizontal, 2);
  63. flow.pack_start(&container, false, true, 0);
  64. let button = Button::with_label("Click me!");
  65. flow.pack_start(&button, false, true, 0);
  66. let canvas = gtk::DrawingArea::new();
  67. let copy = app.clone();
  68. canvas.connect_draw(move |_cv, ctx| {
  69. if let Err(err) = copy.data.borrow_mut().render(ctx) {
  70. eprintln!("Error in rendering: {}", err);
  71. }
  72. gtk::Inhibit(false)
  73. });
  74. flow.pack_start(&canvas, true, true, 0);
  75. button.connect_clicked(move |_| {
  76. if let Err(err) = app.data.borrow_mut().draw_to_file() {
  77. eprintln!("Error in rendering: {}", err);
  78. }
  79. });
  80. window.add(&flow);
  81. window.show_all();
  82. }
  83. fn mk_icon_choice(choice: char, cell: App) -> gtk::Button {
  84. let button = gtk::Button::with_label(&choice.to_string());
  85. button.connect_clicked(move |_| {
  86. cell.data.borrow_mut().symbol = choice;
  87. println!("Choosing '{}'", choice);
  88. });
  89. button
  90. }
  91. fn main() {
  92. let application =
  93. Application::new(Some("com.github.gtk-rs.examples.basic"), Default::default())
  94. .expect("failed to initialize GTK application");
  95. application.connect_activate(|app| {
  96. mk_app(app);
  97. });
  98. application.run(&[]);
  99. }