GithubHelp home page GithubHelp logo

Comments (13)

gkoz avatar gkoz commented on July 25, 2024 1

Here's a macro that will clone the variables for you: http://is.gd/xQlEHR
It'd be nice to integrate the macro with closures a little more but I'm not sure how to do that yet.

from gtk.

anfractuosity avatar anfractuosity commented on July 25, 2024 1

I'm just having a little problem with this macro,

I can do https://play.rust-lang.org/?gist=7ad1859c73cd05a19e2c&version=stable which works fine.

But the following

macro_rules! clone {
    ($($n:ident),+ ; $b:expr) => (
            {
            $(let $n = $n.clone();)+
                    $b
            }
        );
}

librarylbl.connect_button_press_event(clone!(scroll,libraryview,newrecipeview;move |_,_|{
    Inhibit(true)
}));    

newrecipelbl.connect_button_press_event(clone!(scroll,libraryview,newrecipeview;move |_,_|{
    Inhibit(true)
}));    

Results in:

Global is external, but doesn't have external or weak linkage!
i8 (%closure.6*, i128, %"17.gdk::events::EventButton"*)* @_ZN7example4main12closure.4542E
invalid linkage type for function declaration
i8 (%closure.6*, i128, %"17.gdk::events::EventButton"*)* @_ZN7example4main12closure.4542E
Global is external, but doesn't have external or weak linkage!
i8 (%closure.7*, i128, %"17.gdk::events::EventButton"*)* @_ZN7example4main12closure.4559E
invalid linkage type for function declaration
i8 (%closure.7*, i128, %"17.gdk::events::EventButton"*)* @_ZN7example4main12closure.4559E
LLVM ERROR: Broken module found, compilation aborted!

from gtk.

GuillaumeGomez avatar GuillaumeGomez commented on July 25, 2024

You have to use Rc<RefCell<T>> objects to modify objects within the closures. For example:

let libraryview : Rc<RefCell<Viewport>> = Rc::new(RefCell::new(builder.get_object("libraryview").unwrap()));
let scroll : Rc<RefCell<ScrolledWindow>> = Rc::new(RefCell::new(builder.get_object("mainscroll").unwrap()));

let b_libraryview = libraryview.clone();
let b_libraryview2 = libraryview.clone();
let b_scroll = scroll.clone();
let b_scroll2 = scroll.clone();
librarylbl.connect_button_press_event(move |_,_,| {
    (*b_scroll.borrow_mut()).remove(b_libraryview.borrow());
    Inhibit(true)
}); 

newrecipelbl.connect_button_press_event(move|_,_| {
    (*b_scroll2.borrow_mut()).remove(b_libraryview2.borrow());
    Inhibit(true)
});

(Or nearby).

from gtk.

gkoz avatar gkoz commented on July 25, 2024

@GuillaumeGomez You don't have to do that for refcounted types (particularly, any widgets) because they already are a kind of Rc<RefCell<X>> underneath. You just need to clone them.

I'd also look into cloning the closure as well. This might work:

        let libraryview : Viewport = builder.get_object("libraryview").unwrap();
        let scroll : ScrolledWindow = builder.get_object("mainscroll").unwrap();

        let env = (scroll.clone(), library_view.clone());
        let handler = move |_,_| {
            let (ref scroll, ref library_view) = env;
            scroll.remove(libraryview);
            Inhibit(true)
        };

        librarylbl.connect_button_press_event(handler.clone()); 
        newrecipelbl.connect_button_press_event(handler);

from gtk.

GuillaumeGomez avatar GuillaumeGomez commented on July 25, 2024

I didn't pay attention. Thanks for correcting me @gkoz.

from gtk.

anfractuosity avatar anfractuosity commented on July 25, 2024

When trying to clone the closure I got

 error: type `[closure src/hymntoninkasi.rs:92:22: 95:4]` does not implement any method in scope named `clone`

I'm wondering, is cloning each widget the only way to do this? As i'm going to use a number of
.connect_button_press_event's with closures accessing the same widgets, so the code will get quite verbose, if I have to clone them all.

from gtk.

gkoz avatar gkoz commented on July 25, 2024

When trying to clone the closure I got

I was mistaken then, you can't clone a closure :(
You could make a wrapper around Fn that would hide some boilerplate, but implementing Fn is impossible in stable Rust.

I'm wondering, is cloning each widget the only way to do this?

Currently closures have unbounded ('static) lifetimes so they need to own the variables they close over -- that's why you need to move the variables into them and can't capture references. The lack of a clone variant of move might be a shortcoming in Rust that needs to be addressed.

One can always try to design some clever macros ;)

from gtk.

anfractuosity avatar anfractuosity commented on July 25, 2024

Cheers! Really appreciate your help

from gtk.

gkoz avatar gkoz commented on July 25, 2024

Interesting! Does Rust nightly produce the same error?

from gtk.

anfractuosity avatar anfractuosity commented on July 25, 2024

Just about to try that :)

Edit: Yup, it's fixed in nightly, and compiles fine

from gtk.

anfractuosity avatar anfractuosity commented on July 25, 2024

This is slightly off-topic but I'm just wondering I'm doing the following:

        librarylbl.connect_button_press_event(clone!(scroll,libraryview,newrecipeview;move |_,_|{
            scroll.remove(&libraryview);
            scroll.remove(&newrecipeview);
            libraryview.reparent(&scroll);
            Inhibit(true)
        }));    

        newrecipelbl.connect_button_press_event(clone!(scroll,libraryview,newrecipeview;move |_,_|{
            scroll.remove(&libraryview);
            scroll.remove(&newrecipeview);
            newrecipeview.reparent(&scroll);
            Inhibit(true)
        }));    

So when I click the 'newrecipelbl' I get the newrecipeview shown in the GtkScrolledWindow, and when I click 'librarylbl' I get the libraryview shown in the GtkScrolledWindow.

This works, if i click each of these buttons once, but as soon as I press one more than once.

I get

(hymntoninkasi:27267): Gtk-CRITICAL **: gtk_widget_reparent: assertion 'priv->parent != NULL' failed

Which seems odd, as I've removed the elements from the scrolled window, as far as I can tell.

from gtk.

gkoz avatar gkoz commented on July 25, 2024

I'll probably need a full working sample to play with.

from gtk.

anfractuosity avatar anfractuosity commented on July 25, 2024

I managed to solve it through re-parenting the view port to an offscreen window :)

    librarylbl.connect_button_press_event(clone!(scroll,libraryview,newrecipeview;move |_,_|{
            newrecipeview.reparent(&rwindow);
            libraryview.reparent(&scroll);
            Inhibit(true)
    }));    

    newrecipelbl.connect_button_press_event(clone!(scroll,libraryview,newrecipeview;move |_,_|{
            libraryview.reparent(&lwindow);
            newrecipeview.reparent(&scroll);
            Inhibit(true)
    }));        

from gtk.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.