ryanmcgrath/cacao

NSTextView and NSDocument

jasoneveleth opened this issue · 9 comments

I'm trying to learn rust by writing a simple plain text editor. I followed this tutorial in Swift and I have a working prototype. I'm trying to port it to rust using your library, but I can't find NSTextView or NSDocument. In the README you mention:

Each UI control contains a objc field, which you can use as an escape hatch - if the control doesn't support something, you're free to drop to the Objective-C runtime yourself and handle it.

I'm new to UI development on the mac, but it seems like there are several way forwards here:

  1. I can try to use the Objective-C runtime to get NSTextView and NSDocument (I don't know if this even makes sense)
  2. I can try to read how you implemented TextField (which I saw bindings for) and try to copy what you did there
  3. Maybe I'm misunderstanding something and it's actually simple to do

I saw in this example that you said

A Window Controller is backed by NSWindowController, and typically used in scenarios where
you might have documents (backed by NSDocument) that you're working with.

So it seems like you plan on supporting a Document Based App use-case.

It would be very helpful to me if you could point me in the right direction, or provide an example document based app example (maybe along the lines of the tutorial linked earlier). If this is too much to ask, you can also just close this issue without comment. Thanks for you time!

EDIT: clarity

Yup, this is pretty much just a case of those things not being necessarily ported yet. You probably want an approach that's a mix of 1 and 2.

If you look at e.g view/mod.rs and view/appkit.rs you can begin to see how I tend to wrap these things with regards to the delegate pattern and associated callback linking. I don't have the time at the moment to do this myself, but if you give it a whirl and have questions, feel free to use this issue as a tracking document or make a PR eventually. :)

(If view seems overly complex at the moment, text/label/mod.rs & text/label/appkit.rs might be more digestable~)

Sorry it took me so long to follow up. I think I've taken on too much at once (rust, mac os api, and ui/ux).

I tried to copy the code from examples/text_input.rs to make a very similar example for the TextView. I made a new directory src/textview to hold mod.rs, trait.rs and appkit.rs. I've stolen most of the code as a mixture of src/view and src/label, and changed everything to say TextView. Everything seems to compile correctly, except that the window that appears doesn't have a textview.

I've tried putting print statements in the call backs and my TextViewDelegate and it seems to be registered properly. The call backs in the TextView itself for editing don't fire. I don't know where to go from here. I think part of the issue is I don't understand how we are actually interfacing with Objective-C. I'm using msg_send!() macros a lot in my appkit.rs but I don't know how to test to see if any of them are working.

If you're willing, I'll submit a pull request so maybe you or other people can look at what I've done wrong. If not, I'll close this issue and try a more familiar front end for my rust text editor. Thank you for your time!

Feel free to open a PR or link a sample repo, I'm happy to take a look. :)

Checkout the textview branch of my fork.

I'll have to look more over the weekend, but at a glance, you're calling new to create your NSTextView - as far as I know that's not going to allocate text storage behind the scenes. To get the simplest version working I would probably just call it like:

(pseudo-code, you can dig around for the imports)

let zero: CGRect = Rect::zero().into();
let alloc: id = msg_send![class, alloc];
msg_send![alloc, initWithFrame:zero]

If memory serves correct you may also have to fiddle with AutoLayout for it - it also looks like you're pinning content to content, you probably want to pin input to content anchors instead.

You were right, my auto layout was messed up. I fixed it and tested it with a normal view and now it should work properly.

I also realized I was calling the wrong functions for registering the class. Or maybe they were correct and just poorly named.

My plan is to try to closely compare with the view module until I can see the textview showing up with a background color.

Closing this for now, but feel free to reopen if you end up with more questions~

I also really need this, so can we consider reopening?

It can be open, sure - but for this particular thing I'm mostly looking for people who will issue a PR. I don't have the time for this particular piece myself. I may get to it in the future if it crosses over with something I'm building though.