Skip to content

Instantly share code, notes, and snippets.

@njam
Created October 28, 2018 17:54
Show Gist options
  • Save njam/1b36ba58d7401865dabd302fc37543da to your computer and use it in GitHub Desktop.
Save njam/1b36ba58d7401865dabd302fc37543da to your computer and use it in GitHub Desktop.
extern crate gtk;
extern crate gio;
extern crate glib;
#[macro_use]
extern crate relm;
#[macro_use]
extern crate relm_derive;
use relm::{Relm, Update, Widget};
use gio::prelude::*;
use gio::FileExt;
use gtk::prelude::*;
use gtk::{Window, WindowType};
use std::rc::Rc;
use std::cell::RefCell;
fn main() {
struct WindowList {
gtk_app: gtk::Application,
components: Vec<relm::Component<MyWin>>,
}
impl WindowList {
pub fn new(gtk_app: gtk::Application) -> WindowList {
WindowList {
gtk_app,
components: Vec::new(),
}
}
pub fn create_window(&mut self) {
let component: relm::Component<MyWin> = relm::init(()).expect("Cannot init window.");
{
let window: &gtk::Window = component.widget();
window.set_application(&self.gtk_app);
}
self.components.push(component);
}
}
let appid = "com.example.my-test";
let gtk_app: gtk::Application = gtk::Application::new(appid, gio::ApplicationFlags::HANDLES_OPEN).expect("Cannot create GtkApplication");
let window_list = Rc::new(RefCell::new(WindowList::new(gtk_app.clone())));
{
gtk_app.connect_startup(move |_| {
println!("DEBUG: startup");
});
}
{
let window_list = window_list.clone();
gtk_app.connect_activate(move |_app| {
println!("DEBUG: activate");
window_list.borrow_mut().create_window();
});
}
{
let window_list = window_list.clone();
gtk_app.connect_open(move |_app, files, _| {
for file in files {
println!("DEBUG: open {:?}", file.get_path().expect("File has no path"));
window_list.borrow_mut().create_window();
}
});
}
let args: Vec<String> = std::env::args().collect();
gtk_app.run(&args[..]);
}
struct MyModel {
counter: i64,
}
impl MyModel {
fn new() -> Self {
MyModel { counter: 0 }
}
fn increment(&mut self) {
self.counter += 1;
}
}
#[derive(Msg)]
enum MyMsg {
Increment,
}
struct MyWin {
model: MyModel,
window: Window,
label: gtk::Label,
}
impl Update for MyWin {
type Model = MyModel;
type ModelParam = ();
type Msg = MyMsg;
fn model(_relm: &Relm<Self>, _param: Self::ModelParam) -> Self::Model {
MyModel::new()
}
fn update(&mut self, event: Self::Msg) {
match event {
MyMsg::Increment => {
self.model.increment();
self.label.set_text(&format!("Click count: {}", self.model.counter));
}
}
}
}
impl Widget for MyWin {
type Root = Window;
fn root(&self) -> Self::Root {
self.window.clone()
}
fn view(relm: &Relm<Self>, model: Self::Model) -> Self {
let window = Window::new(WindowType::Toplevel);
window.set_title("My Title");
let container = gtk::Box::new(gtk::Orientation::Vertical, 10);
window.add(&container);
let label = gtk::Label::new("Click count: 0");
container.add(&label);
let button = gtk::Button::new_with_label("Click me");
container.add(&button);
connect!(relm, button, connect_clicked(_), MyMsg::Increment);
window.show_all();
MyWin { model, window, label }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment