FROM : Pascal Pochet
DATE : Sun Jul 23 09:49:37 2006
Le 23-juil.-06 à 08:09, James Bucanek a écrit :
> Is it possible (or even better yet, has someone already written it)
> to implement a menu item like the Finder's color label selector?
>
> I'd like to do something similar in both the main menubar and a
> contextual pop-menu.
>
> I assumed that this would be fait accompli, but several hours of
> searching the Internet, list archives, and developer code examples
> only resulted in two other posts asking the same question (both
> went unanswered), no documentation on how one would accomplish
> this, and no code samples.
>
> I did find an old Carbon project named MenuViews which purports to
> implement this (I can't tell, because the project won't build). But
> even if it did, I'm not optimistic that I could use it in a Cocoa
> application.
>
MenuViews compiles fine as Universal binary…
but it generates a lot of "deprecated" warning…
To integrate it in a Cocoa project, you have to change
LabelItemView.cp into a LabelItemView.mm to be able to mix with some
Objective-C code…
the other changes are quite minimal:
extern OSStatus HILabelViewCreate( MenuRef inMenu, MenuItemIndex
inMenuItem, HIViewRef inMenuContentView, HIViewRef* outView );
->
extern OSStatus HILabelViewCreate( MenuRef inMenu, MenuItemIndex
inMenuItem, HIViewRef inMenuContentView, HIViewRef* outView, id
target, SEL action );
(the action should be something like:
- (void)handleLabelSelected:(NSNumber *)inValue
but of course you could change it to fit your needs: just adapt
HILabelView::ControlHit to pass the parameter you would like…
)
OSStatus
HILabelViewCreate( MenuRef inMenu, MenuItemIndex inMenuItem,
HIViewRef inMenuContentView, HIViewRef* outView, id target, SEL action )
{
return HILabelView::Create( inMenu, inMenuItem, inMenuContentView,
outView, target, action );
}
OSStatus
HILabelView::Create(
MenuRef inMenu,
MenuItemIndex inMenuItem,
HIViewRef inMenuContentView,
HIViewRef* outView,
id inTarget ,
SEL inAction )
{
OSStatus err = noErr;
EventRef event = CreateInitializationEvent(); // create
initialization event
require_action( event != NULL, CantCreateEvent, err =
eventInternalErr );
// add extra parameters
if ( inMenu != NULL )
SetEventParameter( event, kEventParamMenuRef, typeMenuRef, sizeof
( inMenu ), &inMenu );
if ( inMenuItem != 0 )
SetEventParameter( event, kEventParamMenuItemIndex,
typeMenuItemIndex, sizeof( inMenuItem ), &inMenuItem );
if ( inMenuContentView != 0 )
SetEventParameter( event, kEventParamControlRef, typeControlRef,
sizeof( inMenuContentView ), &inMenuContentView );
SetEventParameter( event, 'targ', typeVoidPtr, sizeof( inTarget ),
&inTarget );
SetEventParameter( event, 'acti', typeVoidPtr, sizeof( inAction ),
&inAction );
// register the subclass
static bool sRegistered = false;
if( !sRegistered )
{
RegisterSubclass( kTViewHILabelViewClassID, Construct );
sRegistered = true;
}
// instantiate the object
err = HIObjectCreate( kTViewHILabelViewClassID, event,
(HIObjectRef*) outView );
ReleaseEvent( event );
CantCreateEvent:
return err;
}
OSStatus
HILabelView::Initialize(
TCarbonEvent& inEvent )
{
...
if ( fMenu != NULL )
{
...
inEvent.GetParameter( 'targ', typeVoidPtr, sizeof( id ), &fTarget );
inEvent.GetParameter( 'acti', typeVoidPtr, sizeof( SEL ),
&fSelector );
}
CantInitBaseClass:
return err;
}
in class HILabelView
add the fields
id fTarget ;
SEL fSelector ;
And
OSStatus
HILabelView::ControlHit( HIViewPartCode inPart, UInt32 inModifiers )
{
UInt32 oldSelected = fSelected;
// here the labels are ORed, (NOT Finder-like) : change to fit your
needs…
if ( inPart == 1 )
fSelected = 0;
else
fSelected ^= 1 << ( inPart - 1 );
if ( oldSelected != fSelected ) {
HIViewSetNeedsDisplay( GetViewRef(), true );
if (fTarget)
objc_msgSend(fTarget, fSelector, [NSNumber
numberWithInt:fSelected]) ;
}
return noErr;
}
Pascal Pochet
<email_removed>
DATE : Sun Jul 23 09:49:37 2006
Le 23-juil.-06 à 08:09, James Bucanek a écrit :
> Is it possible (or even better yet, has someone already written it)
> to implement a menu item like the Finder's color label selector?
>
> I'd like to do something similar in both the main menubar and a
> contextual pop-menu.
>
> I assumed that this would be fait accompli, but several hours of
> searching the Internet, list archives, and developer code examples
> only resulted in two other posts asking the same question (both
> went unanswered), no documentation on how one would accomplish
> this, and no code samples.
>
> I did find an old Carbon project named MenuViews which purports to
> implement this (I can't tell, because the project won't build). But
> even if it did, I'm not optimistic that I could use it in a Cocoa
> application.
>
MenuViews compiles fine as Universal binary…
but it generates a lot of "deprecated" warning…
To integrate it in a Cocoa project, you have to change
LabelItemView.cp into a LabelItemView.mm to be able to mix with some
Objective-C code…
the other changes are quite minimal:
extern OSStatus HILabelViewCreate( MenuRef inMenu, MenuItemIndex
inMenuItem, HIViewRef inMenuContentView, HIViewRef* outView );
->
extern OSStatus HILabelViewCreate( MenuRef inMenu, MenuItemIndex
inMenuItem, HIViewRef inMenuContentView, HIViewRef* outView, id
target, SEL action );
(the action should be something like:
- (void)handleLabelSelected:(NSNumber *)inValue
but of course you could change it to fit your needs: just adapt
HILabelView::ControlHit to pass the parameter you would like…
)
OSStatus
HILabelViewCreate( MenuRef inMenu, MenuItemIndex inMenuItem,
HIViewRef inMenuContentView, HIViewRef* outView, id target, SEL action )
{
return HILabelView::Create( inMenu, inMenuItem, inMenuContentView,
outView, target, action );
}
OSStatus
HILabelView::Create(
MenuRef inMenu,
MenuItemIndex inMenuItem,
HIViewRef inMenuContentView,
HIViewRef* outView,
id inTarget ,
SEL inAction )
{
OSStatus err = noErr;
EventRef event = CreateInitializationEvent(); // create
initialization event
require_action( event != NULL, CantCreateEvent, err =
eventInternalErr );
// add extra parameters
if ( inMenu != NULL )
SetEventParameter( event, kEventParamMenuRef, typeMenuRef, sizeof
( inMenu ), &inMenu );
if ( inMenuItem != 0 )
SetEventParameter( event, kEventParamMenuItemIndex,
typeMenuItemIndex, sizeof( inMenuItem ), &inMenuItem );
if ( inMenuContentView != 0 )
SetEventParameter( event, kEventParamControlRef, typeControlRef,
sizeof( inMenuContentView ), &inMenuContentView );
SetEventParameter( event, 'targ', typeVoidPtr, sizeof( inTarget ),
&inTarget );
SetEventParameter( event, 'acti', typeVoidPtr, sizeof( inAction ),
&inAction );
// register the subclass
static bool sRegistered = false;
if( !sRegistered )
{
RegisterSubclass( kTViewHILabelViewClassID, Construct );
sRegistered = true;
}
// instantiate the object
err = HIObjectCreate( kTViewHILabelViewClassID, event,
(HIObjectRef*) outView );
ReleaseEvent( event );
CantCreateEvent:
return err;
}
OSStatus
HILabelView::Initialize(
TCarbonEvent& inEvent )
{
...
if ( fMenu != NULL )
{
...
inEvent.GetParameter( 'targ', typeVoidPtr, sizeof( id ), &fTarget );
inEvent.GetParameter( 'acti', typeVoidPtr, sizeof( SEL ),
&fSelector );
}
CantInitBaseClass:
return err;
}
in class HILabelView
add the fields
id fTarget ;
SEL fSelector ;
And
OSStatus
HILabelView::ControlHit( HIViewPartCode inPart, UInt32 inModifiers )
{
UInt32 oldSelected = fSelected;
// here the labels are ORed, (NOT Finder-like) : change to fit your
needs…
if ( inPart == 1 )
fSelected = 0;
else
fSelected ^= 1 << ( inPart - 1 );
if ( oldSelected != fSelected ) {
HIViewSetNeedsDisplay( GetViewRef(), true );
if (fTarget)
objc_msgSend(fTarget, fSelector, [NSNumber
numberWithInt:fSelected]) ;
}
return noErr;
}
Pascal Pochet
<email_removed>






Cocoa mail archive

