Multiple Documents in a Single Window in Cocoa
Asked Answered
D

4

9

I want to write an application which may have multiple documents in a single window via a tabbed interface. Should I avoid the NSDocument architecture (the Cocoa Document-based Application template)? As far as I can tell, it supports only one or more window per document but not vice versa.

I have been wrestling with this question for a while and have already built much of my application on the NSDocument architecture but I cannot figure out a good way to associate multiple documents with a single window.

EDIT: I want to have project document windows in addition to basic document windows. At this level of complexity, would it still be worth hacking the NSDocument architecture? Did Apple write Xcode (which works this way) using the NSDocument architecture?

Danseur answered 12/7, 2009 at 20:46 Comment(3)
it appears that xcode does indeed use NSDocument, but the window that has the multiple tabs in the project is just one document (the projects)Ragwort
also, a really fun tool to poke around in cocoa apps to see how they do it is F-Script fscript.orgRagwort
@cobbal: Interesting. Does that imply that text files are not represented as NSDocuments?Danseur
I
3

I tried shoehorning an NSDocument app into a single window tabbed interface a few years ago, and ended up so frustrated after a few months I went back and refactored out the document architecture pieces. It's not impossible, but you end up working around so many problems that the final result barely resembles a proper NSDocument app. It's better to just rewrite the bits you do need, than end up with a lot of code just to subvert the Cocoa frameworks.

Incised answered 13/7, 2009 at 12:53 Comment(1)
It's not really much code as you can read from my guide here.Cissoid
T
6

I have the same kind of project — different independent documents that I want to present in a single window, with a sidebar that allows switching between documents — so I have done a little bit of searching myself.

I just found an interesting lead by reading Cocoadev's Document Based App With One Window For All Documents reference. It appears, from MikeTrent's answer, that using NSDocument is a very viable way to go. You just need subclassing NSDocumentController.

I also like Abhi's idea to use a borderless child window.

Trangtranquada answered 28/7, 2012 at 18:28 Comment(2)
The first link is brokenSim
Perhaps they were in May, but now they're working fine.Trangtranquada
P
4

Using an NSDocument-based architecture isn't necessarily a bad idea in this case; but it might require quite a bit of haquery.

It is quite likely that you will have to not only subclass NSDocument, but also it's more rarely subclassed sibling NSDocumentController. Once this is done, it should be a simple matter to hijack and avoid calls to -makeWindowControllers and other window-related methods, allowing you to wrap the document "windows" in whatever fashion you please, but still retain the benefits of the document-based application.

Phaih answered 12/7, 2009 at 20:55 Comment(0)
I
3

I tried shoehorning an NSDocument app into a single window tabbed interface a few years ago, and ended up so frustrated after a few months I went back and refactored out the document architecture pieces. It's not impossible, but you end up working around so many problems that the final result barely resembles a proper NSDocument app. It's better to just rewrite the bits you do need, than end up with a lot of code just to subvert the Cocoa frameworks.

Incised answered 13/7, 2009 at 12:53 Comment(1)
It's not really much code as you can read from my guide here.Cissoid
S
3

Another technique, which I haven't tried yet but plan to, is to have a borderless window for each document. This way one document has one window, which may or may not be visible.

Then, have a wrapper window containing the actual window border, and any controls to switch between which borderless document window/windows are visible. The document window is a child window of the wrapper, which ensures both will be linked when a window is moved/minimised/closed/etc.

For each borderless document window, the wrapper window has a placeholder view that, when resized, will resize the document window, and also inject the document window's view into the responder chain (any event sent to the placeholder view, will be sent to the document window's view before being passed on to the placeholder's parent view).

There are still some minor details to work out, but I think this approach will work well.

Shelba answered 5/2, 2012 at 18:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.