cacao icon indicating copy to clipboard operation
cacao copied to clipboard

NSTextView and NSDocument

Open jasoneveleth opened this issue 2 years ago • 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

jasoneveleth avatar Aug 21 '22 03:08 jasoneveleth

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~)

ryanmcgrath avatar Aug 21 '22 03:08 ryanmcgrath

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!

jasoneveleth avatar Sep 01 '22 05:09 jasoneveleth

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

ryanmcgrath avatar Sep 01 '22 05:09 ryanmcgrath

Checkout the textview branch of my fork.

jasoneveleth avatar Sep 01 '22 14:09 jasoneveleth

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.

ryanmcgrath avatar Sep 01 '22 21:09 ryanmcgrath

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.

jasoneveleth avatar Sep 02 '22 00:09 jasoneveleth

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

ryanmcgrath avatar Oct 12 '22 18:10 ryanmcgrath

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

WeetHet avatar Dec 16 '22 19:12 WeetHet

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.

ryanmcgrath avatar Dec 16 '22 20:12 ryanmcgrath