On Sep 8, 2014, at 4:21 AM, Daryle Walker <dary...@mac.com> wrote:

> The test value and the target menu were always the same. Four runs of double 
> NULL then four more with Today’s sub-menu (Sep. 8). So the transformer always 
> returns YES and every per-day history menu item (and sub-menu) is hidden. How 
> do I get “dayItem.submenu” to be the operand for the transformer? Did I mess 
> up the binding? Or the transformer’s very design? Where did those 4 NULL runs 
> come from?
> 
> …
> 
> Oh, for that last question, it’s because the “sourceMenu” property starts as 
> NIL and I don’t change it until I create the per-day menus. It would have to 
> be that way since I set the property to the sub-menu of the newest day 
> (unless it’s before Today).

I can’t change the operand, so I had to change the operation:

> @interface MyObjectIdentityTransformer : NSValueTransformer
> 
> //! Starts as nil; the instance to be compared.
> @property (nonatomic) id  compared;
> 
> @end
> 
> @implementation MyObjectIdentityTransformer
> 
> + (Class)transformedValueClass {
>     return [NSNumber class];
> }
> 
> + (BOOL)allowsReverseTransformation {
>     return NO;
> }
> 
> - (id)transformedValue:(id)value {
>     return [NSNumber numberWithBool:(self.compared == value)];
> }
> 
> @end
> 
> static inline
> NSMenuItem *  CreateMenuItemForDay(NSCalendarDate *day, NSDateFormatter 
> *format) {
>     NSString * const   dayTitle = [format stringFromDate:day];
>     NSMenu * const   daySubmenu = [[NSMenu alloc] initWithTitle:dayTitle];
>     NSMenuItem * const  dayItem = [[NSMenuItem alloc] initWithTitle:dayTitle 
> action:NULL keyEquivalent:@""];
> 
>     dayItem.representedObject = day;
>     dayItem.submenu = daySubmenu;
> 
>     // Attach a binding to let the menu item auto-hide when used as the Today 
> menu item.
>     MyAppDelegate * const           appDelegate = [NSApp delegate];
>     MyObjectIdentityTransformer * const  transformer = 
> [[MyObjectIdentityTransformer alloc] init];
> 
>     transformer.compared = dayItem.submenu;
>     [dayItem bind:NSHiddenBinding 
> toObject:appDelegate.myOverflowMenuController withKeyPath:MyKeyPathSourceMenu 
>  options:@{NSValueTransformerBindingOption: transformer}];
>     return dayItem;
> }

Each point of a binding is described by two aspects: an object and a (not 
necessarily direct) attribute of the object. In the 
-bind:toObject:withKeyPath:options: method, the bound point is the receiver and 
first argument and the source point is the second and third arguments. When 
using a value transformer in forward mode, the operand is always the source 
point. So when I had the transformer as an attribute of the source point, both 
the operand and the stored menu were always the same: the current Today menu. 
Now I have the transformer associated with the per-day menu item (i.e. the 
bound point), so I compare its sub-menu with the current Today menu (the 
operand).

I was going to change the menu item’s representedObject to store the 
transformer, but then I realized that since the value transformer is part of a 
NSDictionary, the dictionary will do a retain and so I can make the transformer 
a loosely-associated object.

— 
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

Reply via email to