I want to update a cairo drawing inside a DrawingArea. I tried to achieve this by calling DrawingArea::connect_draw(...)
with a new function as the parameter. My issue is that it does not replace the original drawing function, but calls both when showing the window.
Here is an example
extern crate cairo;
extern crate gio;
extern crate gtk;
use gio::prelude::*;
use gtk::prelude::*;
fn main() {
let application = gtk::Application::new(Some("com.example"), Default::default())
.expect("Initialization failed...");
application.connect_activate(|app| {
build_ui(app);
});
application.run(&vec![]);
}
fn build_ui(application: >k::Application) {
let window = get_window(application);
let drawing_area = Box::new(gtk::DrawingArea::new)();
// Set drawing function
drawing_area.connect_draw(|_, ctx| draw(ctx, 0.5, 2.0));
// Change drawing function
drawing_area.connect_draw(|_, ctx| draw(ctx, 0.9, 1.0)); // <-- Why is this not working as expected?
window.add(&drawing_area);
window.show_all();
}
fn get_window(application: >k::Application) -> gtk::ApplicationWindow {
let window = gtk::ApplicationWindow::new(application);
window.set_default_size(500i32, 500i32);
// Set transparency
set_visual(&window, None);
window.connect_screen_changed(set_visual);
window.set_app_paintable(true);
window
}
fn draw(ctx: &cairo::Context, param1: f64, param2: f64) -> gtk::Inhibit {
ctx.scale(500f64, 500f64);
ctx.set_source_rgba(1.0, 0.2, 0.2, param1);
ctx.arc(0.5, 0.5, 0.2, 0.0, 3.1414 * param2);
ctx.fill();
Inhibit(false)
}
fn set_visual(window: >k::ApplicationWindow, _screen: Option<&gdk::Screen>) {
if let Some(screen) = window.get_screen() {
if let Some(ref visual) = screen.get_rgba_visual() {
window.set_visual(Some(visual));
}
}
}
I expect half a circle to be shown. Yet the old, full circle is still there, even though I tried to replace connect_draw. How can I properly replace this?