bodil / vgtk

A declarative desktop UI framework for Rust built on GTK and Gtk-rs
http://bodil.lol/vgtk/
Other
1.05k stars 37 forks source link

TextView/TextBuffer usage #45

Closed alexjg closed 4 years ago

alexjg commented 4 years ago

Hey! First off, thanks for the work you've done here, It's great stuff, you're shaving a particularly large yak in a very elegant way.

I'm trying to figure out how to use a TextView. The particular use case is for real time collaborative text editing. After reading through the GTK reference docs it seems that I need to work with a TextBuffer, i.e I need to install listeners on a TextBuffer and mutate the TextBuffer when receiving changes from other collaborators etc. This seems to indicate that I should use TextBuffer as a property or child of the TextView. I tried a few things like:

<TextView>
    <TextBuffer />
</TextView>

Which didn't work, because TextBuffer is not a widget

Or

<TextView buffer=<TextBuffer />>

Which seemed to raise a syntactical error.

What would be the best way to approach this? I'm happy to get my hands dirty so let me know if there are obvious extensions to the project I could work on which would enable this.

bodil commented 4 years ago

You should be able to use its constructor, eg. <TextView buffer=TextBuffer::new() />, but you'll probably also want to do more to it than constructing it, so you could construct it before the gtk! macro:

let buffer = TextBuffer::new();
buffer.do_things_to_it();
gtk! {
    <TextView buffer=buffer />
}

Because the buffer probably contains essential application state, you might even want to put it in your model (I'm guessing this is probably the best choice here):

struct Model {
    buffer: TextBuffer,
}

fn render(...) {
    gtk! {
        <TextView buffer=self.buffer />
    }
}
alexjg commented 4 years ago

Interesting, this mostly makes sense. How would I wire up the events from the buffer, (e.g the insert-text event). I could pass a crossbeam channel in via a message in the application scope and then when that message is received wire up a handler which fires changes into the channel?

alexjg commented 4 years ago

Okay, that approach worked, I'm going to close, thanks for the help!

bodil commented 4 years ago

I'm curious, are you able to share the code which wires that mechanism up? It's something I've been thinking about trying to make more obvious and ergonomic, and I'm just wondering how bad it ended up looking on your end compared to how easy I imagine it needs to be.

alexjg commented 4 years ago

I'm working on https://github.com/automerge/automerge-rs, which I've just gotten to the point where I can start playing with real applications and I wanted to see how hard it would be to integrate with vgtk. I've got a basic example working and I'm just cleaning it up now, I'll push it in a few hours. Would be very interested in talking more about how to make this easier.

alexjg commented 4 years ago

Okay, here you go. It's still quite messy and right now won't actually build or work without some changes I've made to the automerge codebase. That should be merged later today though. Hopefully it's clear enough what's going on though.

alexjg commented 4 years ago

That example should build and run now.