Re: Custom NSFormatter classes

2010-01-04 Thread Henri Häkkinen
Hello again Patric and others.

I have another question related to the previous one.

I now have the following things:
* Foo model class
* FooFormatter class which converts Foo objects into string representations
* User interface with NSTableView which uses the FooFormatter in a text field 
cell

What I would like to do next (yet not sure how to do it) is to have a context 
menu attached to the table view with menu items calling actions on a Foo object 
underneath the mouse cursor. Lets consider that the Foo class has something 
like the following:

- (IBAction)setOneDot:(id)sender;
- (IBAction)setTwoDots:(id)sender;
- (IBAction)setThreeDots:(id)sender;

And the context menu would have items like One dot, Two dots and Three 
dots which would call those actions.

The problem here is that target-action relationships can't be bound in the 
Interface Builder, since target is not known until the user presses right mouse 
on the table view. I am guessing that the best solution would be to subclass 
NSCell or NSTextFieldCell and then override some method to handle the mouse 
event?

Or maybe this could be done with some sort of Cocoa Bindings trickery to have 
those menu items call directly on the setDots: method of the Foo class, without 
having to implement a separate action for each setXXXDot(s) ? How about 
displaying a checkmark on the menu item for the current state?


On Jan 3, 2010, at 1:58 PM, Patrick Mau wrote:

 Hallo Henri
 
 Your assumption about how formatters should work are correct. To provide a 
 useful answer
 I have setup a mini project here, because I have stumbled over a detail I did 
 not now:
 
 http://public.me.com/pmau
 
 I took your approach and implemted a minimal datasource and a Foo object.
 This is not a great example, but here's what II did not know:
 
 When you wire up the formatter to the text field cell in IB,
 setFormatter is called on the TextFieldCell, which in turn will
 call your formatting code withe the cell's title:
 
 run
 [Switching to process 7123]
 Running…
 2010-01-03 12:39:47.790 Formatter[7123:a0f] NSCFString Cell Title
 2010-01-03 12:39:47.810 Formatter[7123:a0f] Foo Foo: 0x1139291d0
 2010-01-03 12:39:47.811 Formatter[7123:a0f] Foo Foo: 0x1151000a0
 2010-01-03 12:39:47.811 Formatter[7123:a0f] Foo Foo: 0x1151000b0
 
 Therefore you have too prepare to receive at least one object, which is not 
 Foo.
 
 Interestingly, I could not find that little detail in the documentation.
 
 If you want to return an instance Foo from your datasource, it is much more 
 convenient to write
 your own NSCell subclass, because you can control editing and formatting much 
 easier.
 You can even use an attached formatter that you setup in IB, passing it a 
 property of Foo.
 
 All the best,
 Patrick
 
 
 On Jan 3, 2010, at 1:47 , Henri Häkkinen wrote:
 
 Hello.
 
 I have an array of custom Foo objects which I would need to display in an 
 NSTableView object. I implement the data source delegate like this:
 
 - (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
  return [arrayOfFoos count];
 }
 
 - (id)tableView:(NSTableView *)tableView 
 objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger) row {
  return [arrayOfFoos objectAtIndex:row];
 }
 
 Then I have NSFormatter subclass FooFormatter which takes in a Foo object 
 and converts it to a string. This formatter object is attached to the 
 formatter property of the TextFieldCell class in the NSTableView's table 
 column. The FooFormatter is like this:
 
 @implementation FooFormatter
 
 - (NSString *)stringForObjectValue:(id)anObject {
  if ([anObject isKindOfClass:[Foo class]] == NO) {
  [NSException raise:NSInvalidArgumentException format:@Wrong 
 object];
  }
  Foo *foo = (Foo *)anObject;
  NSString *string;
  // ... convert foo into string ...
  return string;
 }
 
 @end
 
 I am assuming here that the object returned by the data source 
 objectValueForTableColumn: is passed to the formatter's 
 stringForObjectValue: before it is displayed in the text field cell -- this 
 seems not to be the case. I would like to keep formatting of Foo objects 
 separate from the data source (if possible) since I intend to implement 
 multiple different FooFormatter derived classes suited for different 
 situations.
 
 The Cocoa docs seem to be a little low on details on how these NSFormatter 
 objects are supposed to work. Can anybody give me any insight? Would be 
 appreciated. Thanks.
 
 ___
 
 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:
 http://lists.apple.com/mailman/options/cocoa-dev/pmau%40me.com
 
 This email sent to p...@me.com
 

___

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

Please do not 

Re: Custom NSFormatter classes

2010-01-04 Thread Patrick Mau
Hallo Henri

I have updated the Formatter to include a context menu
for the TableView.

http://public.me.com/pmau

Since you don't know the target, you could wire them up to the FirstResponder
object in IB.

Look at the inspector panel for FirstResponder, you can add actions there.
Since the TableView is not subclassed, the first responder in this case is
the Application Delegate. This is where I implemented the actions.

This is not how I would recommend implementing, but it should give you an idea.

Please read

http://developer.apple.com/Mac/library/documentation/Cocoa/Conceptual/MenuList/Articles/EnablingMenuItems.html

It explains how the responder chain is searched and how enabling items works.

In my example:

* NSTableView does not implent it,
* The NSWinow does not implement it
* The widow delegate does not
* The Application delegate does (Bingo!)

You could look at the [window firstResponder] in the action method,
this would yield the TableView.

You could then mis-use the Datasource and forward the action there.
(You can get the selected rows there, too.)

You could subclass the NSTableView, implementing your actions there.

You could embed the TableView in a custom view subclass to handle actions and 
so on.

You could use a custom Controller as your FilesOwner and bind actions there in 
IB.

I hope you get the idea.
Patrick

PS: I don't mind answering, but my quick hacks will not necessarily improve 
your coding ;)
Please read a lot of documents about FirstResponder, FilesOwner and see what 
fits your needs.




On Jan 4, 2010, at 19:14 , Henri Häkkinen wrote:

 Hello again Patric and others.
 
 I have another question related to the previous one.
 
 I now have the following things:
 * Foo model class
 * FooFormatter class which converts Foo objects into string representations
 * User interface with NSTableView which uses the FooFormatter in a text field 
 cell
 
 What I would like to do next (yet not sure how to do it) is to have a context 
 menu attached to the table view with menu items calling actions on a Foo 
 object underneath the mouse cursor. Lets consider that the Foo class has 
 something like the following:
 
 - (IBAction)setOneDot:(id)sender;
 - (IBAction)setTwoDots:(id)sender;
 - (IBAction)setThreeDots:(id)sender;
 
 And the context menu would have items like One dot, Two dots and Three 
 dots which would call those actions.
 
 The problem here is that target-action relationships can't be bound in the 
 Interface Builder, since target is not known until the user presses right 
 mouse on the table view. I am guessing that the best solution would be to 
 subclass NSCell or NSTextFieldCell and then override some method to handle 
 the mouse event?
 
 Or maybe this could be done with some sort of Cocoa Bindings trickery to have 
 those menu items call directly on the setDots: method of the Foo class, 
 without having to implement a separate action for each setXXXDot(s) ? How 
 about displaying a checkmark on the menu item for the current state?
 
 
 On Jan 3, 2010, at 1:58 PM, Patrick Mau wrote:
 
 Hallo Henri
 
 Your assumption about how formatters should work are correct. To provide a 
 useful answer
 I have setup a mini project here, because I have stumbled over a detail I 
 did not now:
 
 http://public.me.com/pmau
 
 I took your approach and implemted a minimal datasource and a Foo object.
 This is not a great example, but here's what II did not know:
 
 When you wire up the formatter to the text field cell in IB,
 setFormatter is called on the TextFieldCell, which in turn will
 call your formatting code withe the cell's title:
 
 run
 [Switching to process 7123]
 Running…
 2010-01-03 12:39:47.790 Formatter[7123:a0f] NSCFString Cell Title
 2010-01-03 12:39:47.810 Formatter[7123:a0f] Foo Foo: 0x1139291d0
 2010-01-03 12:39:47.811 Formatter[7123:a0f] Foo Foo: 0x1151000a0
 2010-01-03 12:39:47.811 Formatter[7123:a0f] Foo Foo: 0x1151000b0
 
 Therefore you have too prepare to receive at least one object, which is not 
 Foo.
 
 Interestingly, I could not find that little detail in the documentation.
 
 If you want to return an instance Foo from your datasource, it is much more 
 convenient to write
 your own NSCell subclass, because you can control editing and formatting 
 much easier.
 You can even use an attached formatter that you setup in IB, passing it a 
 property of Foo.
 
 All the best,
 Patrick
 
 
 On Jan 3, 2010, at 1:47 , Henri Häkkinen wrote:
 
 Hello.
 
 I have an array of custom Foo objects which I would need to display in an 
 NSTableView object. I implement the data source delegate like this:
 
 - (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
 return [arrayOfFoos count];
 }
 
 - (id)tableView:(NSTableView *)tableView 
 objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger) row {
 return [arrayOfFoos objectAtIndex:row];
 }
 
 Then I have NSFormatter subclass FooFormatter which takes in a Foo object 
 and converts it to a string. 

Re: Custom NSFormatter classes

2010-01-04 Thread Henri Häkkinen
Thanks for your answer again, Patrick.

By the way, what is the general opinion about the Cocoa Bindings technology 
among Mac developers? I have been looking into it lately and while it looks 
very neat I have found it troublesome to actually put it into practical use. I 
am contemplating whether or not to adopt it into my projects, or to just use 
target-action mechanism which seems to be easier to use even though it requires 
a bit more glue coding.

___

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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


Re: Custom NSFormatter classes

2010-01-04 Thread Matthew Lindfield Seager
On Tuesday, January 5, 2010, Henri Häkkinen  wrote:
 Thanks for your answer again, Patrick.

 By the way, what is the general opinion about the Cocoa Bindings technology 
 among Mac developers?

Don't confuse my uninformed opinion with the general opinion but it
appears to be an 80% technology... 80% of the time (particularly for
simple cases) it works well  saves a bit of effort.

For the remaining 20% it varies significantly; sometimes you can bend
it, prod it and squish it to mostly fit... Sometimes you waste several
hours bending, prodding  squishing only to realise those several
hours of effort (assuming you were successful) saved you five or ten
minutes of glue coding.

My difficulty is knowing which situation is which. Plus often you will
get both situations in the one project...

Regards,
Matt
___

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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


Re: Custom NSFormatter classes

2010-01-03 Thread Patrick Mau
Hallo Henri

Your assumption about how formatters should work are correct. To provide a 
useful answer
I have setup a mini project here, because I have stumbled over a detail I did 
not now:

http://public.me.com/pmau

I took your approach and implemted a minimal datasource and a Foo object.
This is not a great example, but here's what II did not know:

When you wire up the formatter to the text field cell in IB,
setFormatter is called on the TextFieldCell, which in turn will
call your formatting code withe the cell's title:

run
[Switching to process 7123]
Running…
2010-01-03 12:39:47.790 Formatter[7123:a0f] NSCFString Cell Title
2010-01-03 12:39:47.810 Formatter[7123:a0f] Foo Foo: 0x1139291d0
2010-01-03 12:39:47.811 Formatter[7123:a0f] Foo Foo: 0x1151000a0
2010-01-03 12:39:47.811 Formatter[7123:a0f] Foo Foo: 0x1151000b0

Therefore you have too prepare to receive at least one object, which is not 
Foo.

Interestingly, I could not find that little detail in the documentation.

If you want to return an instance Foo from your datasource, it is much more 
convenient to write
your own NSCell subclass, because you can control editing and formatting much 
easier.
You can even use an attached formatter that you setup in IB, passing it a 
property of Foo.

All the best,
Patrick


On Jan 3, 2010, at 1:47 , Henri Häkkinen wrote:

 Hello.
 
 I have an array of custom Foo objects which I would need to display in an 
 NSTableView object. I implement the data source delegate like this:
 
 - (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
   return [arrayOfFoos count];
 }
 
 - (id)tableView:(NSTableView *)tableView 
 objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger) row {
   return [arrayOfFoos objectAtIndex:row];
 }
 
 Then I have NSFormatter subclass FooFormatter which takes in a Foo object and 
 converts it to a string. This formatter object is attached to the formatter 
 property of the TextFieldCell class in the NSTableView's table column. The 
 FooFormatter is like this:
 
 @implementation FooFormatter
 
 - (NSString *)stringForObjectValue:(id)anObject {
   if ([anObject isKindOfClass:[Foo class]] == NO) {
   [NSException raise:NSInvalidArgumentException format:@Wrong 
 object];
   }
   Foo *foo = (Foo *)anObject;
   NSString *string;
   // ... convert foo into string ...
   return string;
 }
 
 @end
 
 I am assuming here that the object returned by the data source 
 objectValueForTableColumn: is passed to the formatter's stringForObjectValue: 
 before it is displayed in the text field cell -- this seems not to be the 
 case. I would like to keep formatting of Foo objects separate from the data 
 source (if possible) since I intend to implement multiple different 
 FooFormatter derived classes suited for different situations.
 
 The Cocoa docs seem to be a little low on details on how these NSFormatter 
 objects are supposed to work. Can anybody give me any insight? Would be 
 appreciated. Thanks.
 
 ___
 
 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:
 http://lists.apple.com/mailman/options/cocoa-dev/pmau%40me.com
 
 This email sent to p...@me.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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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


Re: Custom NSFormatter classes

2010-01-03 Thread Henri Häkkinen
Hello Patric.

I was able to get the NSFormatter subclass to work properly by ignoring all 
non-Foo objects sent to it. The Cocoa docs are indeed lacking in this respect 
as there is no mentioning that the cell's title will first be sent. To me this 
feels a bit odd anyway since I can think of no reason why should the 
NSFormatter be concerned about it.

Subclassing an NSCell class seemed to me a bit overcomplicated for this task so 
I am going with the NSFormatter. Thanks for the suggestion though.

On Jan 3, 2010, at 1:58 PM, Patrick Mau wrote:

 Hallo Henri
 
 Your assumption about how formatters should work are correct. To provide a 
 useful answer
 I have setup a mini project here, because I have stumbled over a detail I did 
 not now:
 
 http://public.me.com/pmau
 
 I took your approach and implemted a minimal datasource and a Foo object.
 This is not a great example, but here's what II did not know:
 
 When you wire up the formatter to the text field cell in IB,
 setFormatter is called on the TextFieldCell, which in turn will
 call your formatting code withe the cell's title:
 
 run
 [Switching to process 7123]
 Running…
 2010-01-03 12:39:47.790 Formatter[7123:a0f] NSCFString Cell Title
 2010-01-03 12:39:47.810 Formatter[7123:a0f] Foo Foo: 0x1139291d0
 2010-01-03 12:39:47.811 Formatter[7123:a0f] Foo Foo: 0x1151000a0
 2010-01-03 12:39:47.811 Formatter[7123:a0f] Foo Foo: 0x1151000b0
 
 Therefore you have too prepare to receive at least one object, which is not 
 Foo.
 
 Interestingly, I could not find that little detail in the documentation.
 
 If you want to return an instance Foo from your datasource, it is much more 
 convenient to write
 your own NSCell subclass, because you can control editing and formatting much 
 easier.
 You can even use an attached formatter that you setup in IB, passing it a 
 property of Foo.
 
 All the best,
 Patrick

___

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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


Custom NSFormatter classes

2010-01-02 Thread Henri Häkkinen
Hello.

I have an array of custom Foo objects which I would need to display in an 
NSTableView object. I implement the data source delegate like this:

- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
return [arrayOfFoos count];
}

- (id)tableView:(NSTableView *)tableView 
objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger) row {
return [arrayOfFoos objectAtIndex:row];
}

Then I have NSFormatter subclass FooFormatter which takes in a Foo object and 
converts it to a string. This formatter object is attached to the formatter 
property of the TextFieldCell class in the NSTableView's table column. The 
FooFormatter is like this:

@implementation FooFormatter

- (NSString *)stringForObjectValue:(id)anObject {
if ([anObject isKindOfClass:[Foo class]] == NO) {
[NSException raise:NSInvalidArgumentException format:@Wrong 
object];
}
Foo *foo = (Foo *)anObject;
NSString *string;
// ... convert foo into string ...
return string;
}

@end

I am assuming here that the object returned by the data source 
objectValueForTableColumn: is passed to the formatter's stringForObjectValue: 
before it is displayed in the text field cell -- this seems not to be the case. 
I would like to keep formatting of Foo objects separate from the data source 
(if possible) since I intend to implement multiple different FooFormatter 
derived classes suited for different situations.

The Cocoa docs seem to be a little low on details on how these NSFormatter 
objects are supposed to work. Can anybody give me any insight? Would be 
appreciated. Thanks.

___

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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