Use Page Width when printing NSTableView instead of the view width - objective-c

This seems like it should be simple...
I have a basic NSTableView in a window. The window is arbitrarily resizable (width + height). The tableview is pinned to the edges of the window and it has a single column that contains view-based table rows. The table rows have content pinned to the left and right edges of the cells, so as you resize the width of the window, you are effectively adjusting how much white space is in the middle of the cell.
I'm now trying to implement printing for this tableview. When I set up the NSPrintOperation, I'm passing my tableview subclass as the view to print. My desired result is this: I want the width of the tableview to be resized to the width of the page (regardless of how wide the window is right now on screen). I don't want to adjust the scaling factor (because that affects width + height) - I simply want the result to be as if I manually resized my window to exactly match the width of a printed page and then hit "print".
I've tried setting horizontalPagination to .fitPagination - but the problem there is that seems to apply a scaling factor to the width + height (which means if the window is currently "very wide", it makes the row height really small as it compensates for the width).
I've tried overriding adjustPageWidthNew:left:right:limit: in my tableview subclass - but that never gets called.
I suppose I could create a duplicate tableview and re-set it up exactly like the one I have on screen, but that feels like overkill when the view I want is already good to go - I just need to temporarily resize the width while I'm printing.
Any ideas?

Related

How to calculate the correct location of a vertical NSRulerMarker?

What is the correct formula for the location of an NSRulerMarker on a vertical NSRulerView, if the client view is flipped?
The situation: I have a view (let's call it the "main view") that is embedded in an NSScrollView with rulers, and it has subviews. The user can drag these subviews around, and while dragging, I want to indicate the current position on the rulers.
The main view is flipped: The zero point is top-left.
The horizontal position is pretty simple:
NSPoint scroll = myScrollView.documentVisibleRect.origin;
NSRect rect = mySubView.frame;
rulerMarkerDragLeft.markerLocation = rect.origin.x - scroll.x;
However the same method for the vertical position...
rulerMarkerDragTop.markerLocation = rect.origin.y - scroll.y;
does not work. The marker is only in the correct position when the scrollview has been scrolled down to the extreme bottom. For every n points scrolled back up, the marker location is n points too high. This is independent of the main view's size or the size of the visible area.
I can't seem to wrap my head around this problem; I guess there is a value I need to subtract from my result that expresses how far up the scrollview has been scrolled (or rather, how much further it can be scrolled down), but I don't think I can derive that value from myScrollView.documentVisibleRect...?
I may have overlooked something simple, but I can't find the solution.
Edit 2022-11-02 17:17 CET: Found the problem. I had set the NSRulerViews clientView to the contentView of the window. I am now setting it to the "main view" (ie. the view inside the scroll view), and now it works "automagically": I just set the marker locations to the subviews frame, no correction for scroll position or anything else needed.
The solution was simple: the ruler views' clientView needs to be set to the view that is inside the scroll view, not the main content view of the window.
The positioning of the ruler markers is now very straightforward: you just use the local coordinates inside the view, ie. the subviews' frame values.
No correction for scroll position, view height or such necessary.
My mistake was assigning the window's main content view as the rulers' clientView.

NSFullSizeContentViewWindowMask and title/toolbar height?

I am attempting to implement something similar to Safari where the window's style mask is set to NSFullSizeContentViewWindowMask so the NSToolBar and title bar blur the background view.
This works fine, however I have a view that I need to not be clipped by the toolbar/titlebar, similar to how Safari's WebView has an initial top padding that doesn't cover the content when the view is unschooled.
My attempted solution was to create a dummy NSView which the unclipped views align their top value to, then changing the height constant of the dummy view to the height of the titlebar/toolbar. The issue, however, is that there seems to be no way to calculate the height of the toolbar.
This suggests that I calculate the height by subtracting the height of the contentView from the height of the window, but that only works (returns 0 otherwise as the two heights are equal) if I don't use NSFullSizeContentViewWindowMask which I want to use for the blurring effect.
Am I overlooking something simple, or is there no simple way to accomplish this?
Check NSWindow's contentLayoutRect property.

custom view-based nstableview resizing

I have an NSView class, which draws it's contents on a CALayer. These NSView classes are held in an NSTableView which has a single column. I need to make it so the NSTableView adjusts it's size to fit the contents of the NSViews it contains, which can have variable widths, i.e. the NSTableView needs to have the same width as the widest cell. This in turn will allow the user to scroll if the cells' widths are larger than the available area.
Think of it like a multitrack audio editor, where each view is a track, but the tracks can have different lengths.
At the moment, the NSView cells seem to adjust width automatically to the size of the table column, so I can see two possibilities: One is to make it so the cell NSViews set their width, and somehow have this promulgate everywhere else. The other is to have the tableview or nstablecolumn set its width based on the maximum width. I have tried setting the NSTableColumn width and minWidth, but this doesn't seem to work (it doesn't always adjust to the correct size, if the size is big).
Any suggestions or help to make this work?
If you're using CALayer (lets call it root layer) to draw the view contents, try to create another CALayer which will be a child of the root layer (this would be the audio track). You can set the size of the child layer independently and also you will know which one is biggest.
Root layer will always be as big as the table view, as you said:"NSView cells seem to adjust width automatically to the size of the table column" - don't try to change root layer size, but child layer size.
Once you determine the widest child just change table view frame to be the same width.

Resize NSTableView or NSScrollView depending on number of rows in table

I have a view-based NSTableView which is embedded in an NSScrollView. It has custom cells that are x number of pixels high. The NSScrollView is the same size as the panel that it is a subview of. I want to resize the entire NSTableView depending on how many rows are in the table.
Everything is working except the resizing. Resizing the scroll view manually in IB seems to have the desired affect, but NSSrollView does not seem to have a class method to resize its view (like NSView has setFrame). Should I be resizing the scollview, the tableview, both, or something else? Does NSScrollView have a setFrame method or similar that I am missing?
Thanks.
Before you try to do it programmatically, make sure you have the outline view's autosizing masks set up properly in the nib file. It sounds like you simply want the outline view (and its scroll view) to always remain the same size as the window that it's inside.
By default, the autosizing masks of an NSScrollView/NSOutlineView combo that you place into a window looks like the following:
In other words, it's set up to always remain the same size as it is now, no matter how large you resize the window to be.
What you want to do is to change the autosizing masks to look like in the image below:
To do that, you click in the white autosizing box wherever there's a dotted red line to toggle it into a solid red line. Once it's configured that way, the scroll view (and table view) will always (automatically) be resized to be the same size as the window that it's in.
There may also be a way to achieve this using Lion's new "auto layout" feature, but I'll have to leave that to someone who has more experience with it.
In case you really need to do this (such as when you want all rows to fit in the scrollview alleviating the need to scroll) and the scroll view is only a portion of the window/view you can do:
[[myTableView enclosingScrollView] setFrame:newFrameRect];
scrollview.frame = CGRrectMake(x, y, w, h);

How to make a side-scrolling object?

I would like to make a side-scrolling object that is only 200 pixels wide and 50 pixels tall. This side-scrolling object would contain five different objects that, when scrolled into the middle, act as if selected. How could I go about doing this?
I want sort of the same effect that the iPhone home screen has where it latches on to a page when you slide it. Instead of latching on to the pages though, I want it to latch on to my five different objects.
The side-scrolling behavior is achieved with a UIScrollView with pagingEnabled set to YES. Set the scroll view's width to the size of your pages. Your scroll view delegate can calculate which object is on screen by dividing contentOffset.x by the scroll view's width.
If you want to show several items on the screen at once but still page between the individual items--think of the way the iWork apps show multiple documents, for example--there are three steps involved:
Set the scroll view's width to the width of the objects, not the width of the screen.
Set the scroll view's clipsToBounds property to NO so it displays the objects that aren't within the scroll view's frame.
Subclass UIScrollView and override -pointInside:withEvent: to return YES if the point is within the area you want to respond to touches within. (For example, if you want to respond to touches within the entire width of the screen, just ignore x and make sure y is between the top and bottom of the view.) Use this subclass instead of a standard UIScrollView.