Re: Auto-sized table cells, for macOS

2017-03-17 Thread Daryle Walker

> On Mar 14, 2017, at 11:33 PM, Quincey Morris 
>  wrote:
> 
> On Mar 14, 2017, at 18:26 , Daryle Walker  > wrote:
>> 
>> You’d think that this would be a solved problem….
> 
> It sort of is. I think you can find a solution on stackoverflow.com 
>  (which is where I got the idea from IIRC) but you 
> have to wade through the out of date stuff to pick out a modern way of doing 
> it. Here’s the code I came up with (for an outline view, table view should be 
> similar):

I meant from the people at Apple HQ. Besides those who intentionally want 
truncating behavior, wouldn’t “expand to show all text” be the expected 
default? The current default isn’t friendly to end users.

>>  func resizeListItem (_ listItem: RecentObjectValue, cell: 
>> NSTableCellView, width: CGFloat, resizedRows: NSMutableIndexSet? = nil)
>>  {
>>  cell.objectValue = listItem
>>  
>>  cell.textField?.preferredMaxLayoutWidth = width - 2
>>  cell.needsUpdateConstraints = true
>>  cell.layoutSubtreeIfNeeded ()
>>  
>>  let rowHeight = cell.fittingSize.height
>>  
>>  guard listItem.rowHeight != rowHeight else { return }
>>  
>>  listItem.rowHeight = rowHeight
>>  let row = recentsListView.row (forItem: listItem)
>>  
>>  guard row >= 0, let rows = resizedRows else { return }
>>  
>>  rows.add (row)
>>  }
> 
> The listItem parameter is a custom struct that contains the actual data 
> displayed in the row (the data model of the outline view, in effect), but it 
> also caches the row height. The resizedRows parameter just accumulates an 
> optional set of changed heights for a subsequent “noteHeightOfRowsChanged”. 
> The cell parameter is created once for measuring purposes, in viewDidLoad:
> 
>>  /* view controller instance variable */ headerCell = 
>> recentsListView.make (withIdentifier: "HeaderCell", owner: self) as! 
>> NSTableCellView
>>  let headerConstraint = NSLayoutConstraint (item: headerCell, 
>> attribute: .height, relatedBy: .greaterThanOrEqual, toItem: nil, attribute: 
>> .notAnAttribute, multiplier: 1, constant: 17)
>>  NSLayoutConstraint.activate ([headerConstraint])
> 
> The only other thing you need is a strategy for deciding when to recalculate 
> the heights. When the column width changes, obviously, as well as for 
> inserted rows, but there might be other cases as well.

Unfortunately, you didn’t provide your Stack Overflow sources. I made my first 
attempt after reading :

> // Increase the row height to fit all the text (instead of the first 
> line).
> func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat 
> {
> precondition(tableView === self.headerTableView)
> 
> var height = tableView.rowHeight
> let nameColumn = tableView.tableColumn(withIdentifier: 
> Names.nameColumnIdentifier)!
> let bodyColumn = tableView.tableColumn(withIdentifier: 
> Names.bodyColumnIdentifier)!
> let field = (self.headerArrayController.arrangedObjects as! 
> NSArray).object(at: row) as! RawHeaderField
> let attributes = [NSFontAttributeName: NSFont.systemFont(ofSize: 0)]
> let nameString = NSAttributedString(string: field.name, attributes: 
> attributes)
> let bodyString = NSAttributedString(string: field.body, attributes: 
> attributes)
> for (string, column) in [(nameString, nameColumn), (bodyString, 
> bodyColumn)] {
> let frame = NSRect(x: 0.0, y: 0.0, width: column.width, height: 
> .greatestFiniteMagnitude)
> let view = NSTextView(frame: frame)
> view.textStorage?.setAttributedString(string)
> view.isHorizontallyResizable = false
> view.sizeToFit()
> height = max(height, view.frame.size.height /*+ 20*/)
> }
> 
> return height
> }

But it only establishes the row heights once, at start but never after any 
resizes (column or whole-table). It still is short on some long lines. (Is it 
because I use word-wrap, instead of by character, for that column?) Also, I 
hard-coded the font to match what the table has. Is there any way to read what 
the cell template has? (“NSTableView.view(something)” can generate a view for a 
given row and column, but Apple specifically barred it (with an 
assert/exception) during this method.)

— 
Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT mac DOT com 


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-de

Re: NSTableView column sizes

2017-03-17 Thread Daryle Walker
The effect I don’t like about the default code is that when the last column’s 
width is set to fill out the table, it’s only set for the current set of 
widths. As soon as you narrow an earlier column, the last column’s right border 
becomes visible. I want the last column to always max out, no matter how 
earlier columns are resized.

> On Mar 15, 2017, at 4:38 PM, Quincey Morris 
>  wrote:
> 
> On Mar 15, 2017, at 06:51 , Stephane Sudre  > wrote:
>> 
>> the Column Sizing option
> 
> Remember too that each column has its own sizing options that operate in 
> conjunction with the table view’s options. For each column, you can decide 
> whether the column participates in autoresizing (separately from whether it 
> is user resizable), and you can set minimum and maximum widths.
> 
> You can do most reasonable things with these combinations of options, without 
> having to resort to programmatic adjustment.

— 
Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT mac DOT com 

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

programmatically tell when spotlight/mds is indexing

2017-03-17 Thread sqwarqDev
I have an app that uses MSMetadataQuery. As expected, this returns very fast 
results. However, there is an edge case when Spotlight chooses to re-index the 
whole disk (indicated in Spotlight's GUI by the blue progress bar underneath 
during a search).

When this happens my app’s search is severely delayed to the point where users 
think that it’s hung. 
Accordingly, I’d like to offer a warning to the user that the search may be 
lengthy whenever I detect that Spotlight is reindexing the disk. The question 
is how can this be determined?

mdutil has a status flag, but all this tells us is whether indexing is enabled 
for a named volume. It does not return anything about Spotlight’s current 
activity. 

Any suggestions?


Best


Phil
@sqwarq
___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Calculating intrinsicContentSize for a NSTextField

2017-03-17 Thread Jeremy Hughes
I have a text field that I want to grow and shrink while it is being edited.

In order to do that, I have overridden intrinsicContentSize and textDidChange 
in a subclass of NSTextField:

override var intrinsicContentSize: NSSize
{
if let cell = cell, cell.wraps
{
let size = CGSize(width: bounds.size.width, height: 
CGFloat.greatestFiniteMagnitude)

let _ = attributedStringValue

let cellSize = cell.cellSize(forBounds: CGRect(origin: 
CGPoint(), size: size))

return cellSize
}
else
{
return super.intrinsicContentSize
}
}

override func textDidChange(_ notification: Notification)
{
super.textDidChange(notification)

invalidateIntrinsicContentSize()
}

This works, but if I remove the call to attributedStringValue (whose result is 
discarded) the result of the following line fails to reflect changes in the 
bounds of the text, and the field fails to grow or shrink.

Presumably, calling attributedStringValue has a side effect which changes the 
way that cellSize:forBounds: is calculated.

Is there a way that I can get cellSize:forBounds: to return the correct value 
without relying on this side effect?

An alternative way of calculating the intrinsic content size would be to use:

attributedStringValue.boundingRect(with: size, options: .usesLineFragmentOrigin)

but this fails to take account of cell insets.

Jeremy


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com


Re: Auto-sized table cells, for macOS

2017-03-17 Thread Quincey Morris
On Mar 17, 2017, at 01:45 , Daryle Walker  wrote:
> 
> Besides those who intentionally want truncating behavior, wouldn’t “expand to 
> show all text” be the expected default? The current default isn’t friendly to 
> end users.

I’m a bit puzzled about what you’re expecting. You asked about determining row 
heights in a table. In that case, the current default is to use fixed row 
heights, and that is the expected default for table rows, regardless of the 
kind of content in them.

So, you’re talking about text in isolation, which is a different issue.

> Unfortunately, you didn’t provide your Stack Overflow sources.

Because it doesn’t provide a clean working solution, so I was trying to save 
you the work of reinventing that particular wheel.

> I made my first attempt after reading 
>  >:
> 
>> // Increase the row height to fit all the text (instead of the first 
>> line).
>> func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> 
>> CGFloat {
>> precondition(tableView === self.headerTableView)
>> 
>> var height = tableView.rowHeight
>> let nameColumn = tableView.tableColumn(withIdentifier: 
>> Names.nameColumnIdentifier)!
>> let bodyColumn = tableView.tableColumn(withIdentifier: 
>> Names.bodyColumnIdentifier)!
>> let field = (self.headerArrayController.arrangedObjects as! 
>> NSArray).object(at: row) as! RawHeaderField
>> let attributes = [NSFontAttributeName: NSFont.systemFont(ofSize: 0)]
>> let nameString = NSAttributedString(string: field.name, attributes: 
>> attributes)
>> let bodyString = NSAttributedString(string: field.body, attributes: 
>> attributes)
>> for (string, column) in [(nameString, nameColumn), (bodyString, 
>> bodyColumn)] {
>> let frame = NSRect(x: 0.0, y: 0.0, width: column.width, height: 
>> .greatestFiniteMagnitude)
>> let view = NSTextView(frame: frame)
>> view.textStorage?.setAttributedString(string)
>> view.isHorizontallyResizable = false
>> view.sizeToFit()
>> height = max(height, view.frame.size.height /*+ 20*/)
>> }
>> 
>> return height
>> }

This isn’t what you want, for two entirely separate reasons.

1. Assuming you’re using view-based table views (and if you’re not, you really 
should be), then you don’t want the height of the text, you want the height of 
the cell (NSTableCellView) that contains your text in a subview. The whole 
point is that you leverage autolayout to get the NSTableCellView to compute the 
text height for you. Furthermore, the text is placed *within* the cell, so the 
height of the NSTableCellView may be bigger than the height of the text, or (in 
general) the cell might contain other views that need to be taken into account.

2. You shouldn’t be using a NSTextView, but a NSTextField. A text view 
typically is placed within a fixed height frame, wrapped in a scroll view, so 
the concept of an intrinsic height is problematic. What is your actual cell 
structure, text view or text field?

> But it only establishes the row heights once, at start but never after any 
> resizes (column or whole-table).

As I said before, you have to watch for column width changes and recalculate 
your heights accordingly. There is no automatic way of handling variable 
heights on the Mac that matches the way it can be done on iOS.

> It still is short on some long lines. (Is it because I use word-wrap, instead 
> of by character, for that column?) Also, I hard-coded the font to match what 
> the table has. Is there any way to read what the cell template has? 
> (“NSTableView.view(something)” can generate a view for a given row and 
> column, but Apple specifically barred it (with an assert/exception) during 
> this method.)

Using autolayout on the cell as a whole will avoid all of these issues for the 
text in particular. You’ll get the metrics as implied by the way your text 
field is configured.

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Menu Item Shortcuts Without Menu Items?

2017-03-17 Thread Frank D. Engel, Jr.
Thanks to those who answered; the "alternate" property is doing what I 
need it to.


The delegate method sounds good too, but I wasn't able to get that to 
work for some reason - I may go back and look at that more closely in 
the future but for now I think I'm content with the possible limitation 
described.



On 3/16/2017 16:12, Kyle Sluder wrote:


On Mon, Mar 13, 2017, at 04:50 PM, Ken Thomases wrote:

On Mar 13, 2017, at 5:12 PM, Frank D. Engel, Jr. 
wrote:

I need to create the equivalent of a menu item shortcut, but without the menu 
item... or, to assign two different shortcuts to the same menu item.

More precisely: I have a menu item with a shortcut of Command+L.

I need Command+Shift+L to do exactly the same thing, but it doesn't look right 
having two copies of the menu item just to support a second shortcut.

Mark the second menu item as an alternate.  That is, set its "alternate"
property to true.  It will "hide" in the same slot of the menu as the
other item and only show when the extra modifier (Shift, in this case) is
pressed.

One downside of this approach might be that the menu item appears twice
in VoiceOver. (I haven’t tried it myself.)

A more targeted approach might be to attach a delegate to the menu that
contains the aliased item, and implement
-menuHasKeyEquivalent:forEvent:target:action: to return the Command+L
menu item’s target and action if it sees Command+Shift+L.

--Kyle Sluder


Cheers,
Ken

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/fde101%40fjrhome.net

This email sent to fde...@fjrhome.net



___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Calculating intrinsicContentSize for a NSTextField

2017-03-17 Thread Daryle Walker

> On Mar 17, 2017, at 1:18 PM, Jeremy Hughes  
> wrote:
> 
> I have a text field that I want to grow and shrink while it is being edited.
> 
> In order to do that, I have overridden intrinsicContentSize and textDidChange 
> in a subclass of NSTextField:
> 
[SNIP]
> 
> This works, but if I remove the call to attributedStringValue (whose result 
> is discarded) the result of the following line fails to reflect changes in 
> the bounds of the text, and the field fails to grow or shrink.
> 
> Presumably, calling attributedStringValue has a side effect which changes the 
> way that cellSize:forBounds: is calculated.

Looking at the “attributedStringValue” docs, "validate​Editing()” is called as 
the side effect.

> Is there a way that I can get cellSize:forBounds: to return the correct value 
> without relying on this side effect?
> 
> An alternative way of calculating the intrinsic content size would be to use:
> 
> attributedStringValue.boundingRect(with: size, options: 
> .usesLineFragmentOrigin)
> 
> but this fails to take account of cell insets.

— 
Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT mac DOT com 


___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Re: Auto-sized table cells, for macOS

2017-03-17 Thread Daryle Walker

— 
Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT mac DOT com 

> On Mar 17, 2017, at 2:24 PM, Quincey Morris 
>  wrote:
> 
> On Mar 17, 2017, at 01:45 , Daryle Walker  > wrote:
>> 
>> I made my first attempt after reading 
>> > >:
>> 
>>> // Increase the row height to fit all the text (instead of the first 
>>> line).
>>> func tableView(_ tableView: NSTableView, heightOfRow row: Int) -> 
>>> CGFloat {
>>> precondition(tableView === self.headerTableView)
>>> 
>>> var height = tableView.rowHeight
>>> let nameColumn = tableView.tableColumn(withIdentifier: 
>>> Names.nameColumnIdentifier)!
>>> let bodyColumn = tableView.tableColumn(withIdentifier: 
>>> Names.bodyColumnIdentifier)!
>>> let field = (self.headerArrayController.arrangedObjects as! 
>>> NSArray).object(at: row) as! RawHeaderField
>>> let attributes = [NSFontAttributeName: NSFont.systemFont(ofSize: 0)]
>>> let nameString = NSAttributedString(string: field.name, attributes: 
>>> attributes)
>>> let bodyString = NSAttributedString(string: field.body, attributes: 
>>> attributes)
>>> for (string, column) in [(nameString, nameColumn), (bodyString, 
>>> bodyColumn)] {
>>> let frame = NSRect(x: 0.0, y: 0.0, width: column.width, height: 
>>> .greatestFiniteMagnitude)
>>> let view = NSTextView(frame: frame)
>>> view.textStorage?.setAttributedString(string)
>>> view.isHorizontallyResizable = false
>>> view.sizeToFit()
>>> height = max(height, view.frame.size.height /*+ 20*/)
>>> }
>>> 
>>> return height
>>> }
> 
> This isn’t what you want, for two entirely separate reasons.
> 
> 1. Assuming you’re using view-based table views (and if you’re not, you 
> really should be), then you don’t want the height of the text, you want the 
> height of the cell (NSTableCellView) that contains your text in a subview. 
> The whole point is that you leverage autolayout to get the NSTableCellView to 
> compute the text height for you. Furthermore, the text is placed *within* the 
> cell, so the height of the NSTableCellView may be bigger than the height of 
> the text, or (in general) the cell might contain other views that need to be 
> taken into account.
> 
> 2. You shouldn’t be using a NSTextView, but a NSTextField. A text view 
> typically is placed within a fixed height frame, wrapped in a scroll view, so 
> the concept of an intrinsic height is problematic. What is your actual cell 
> structure, text view or text field?

It’s whatever NSTableCellView uses as a default, so… NSTextField.

…

I just tried something from a recent post by Jeremy Hughes:

//=
class WrappingTextField: NSTextField {

override var intrinsicContentSize: NSSize {
guard let cell = self.cell, cell.wraps else { return 
super.intrinsicContentSize }

self.validateEditing()
return cell.cellSize(forBounds: NSRect(x: 0, y: 0, width: 
self.bounds.width, height: .greatestFiniteMagnitude))
}

override func textDidChange(_ notification: Notification) {
super.textDidChange(notification)
self.invalidateIntrinsicContentSize()
}

}

//=

I put this class as the table-cell’s type and took out the table delegate but 
kept the constraints of the text field to match those of the cell. No change 
(so far). I did debug printouts to the Xcode console, and there are changes. 
All the sizes from “super" are “(-1.0, 17.0)”, but the new sizes vary in widths 
and height. The table isn’t using the new values, though.


>> But it only establishes the row heights once, at start but never after any 
>> resizes (column or whole-table).
> 
> As I said before, you have to watch for column width changes and recalculate 
> your heights accordingly. There is no automatic way of handling variable 
> heights on the Mac that matches the way it can be done on iOS.
> 
>> It still is short on some long lines. (Is it because I use word-wrap, 
>> instead of by character, for that column?) Also, I hard-coded the font to 
>> match what the table has. Is there any way to read what the cell template 
>> has? (“NSTableView.view(something)” can generate a view for a given row and 
>> column, but Apple specifically barred it (with an assert/exception) during 
>> this method.)
> 
> Using autolayout on the cell as a whole will avoid all of these issues for 
> the text in particular. You’ll get the metrics as implied by the way your 
> text field is configured.

___

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archiv