Skip to main content
Known Participant
October 8, 2009
Answered

Creating Popup Context Menu's

  • October 8, 2009
  • 1 reply
  • 2813 views

I am trying to make a pop menu ("conext menu"?) when the user right clicks on a selected path object. I have looked through the docs and found that the basic suite claims to be able to do this. Using the create function, I see that it doesn't do anything noticable. I have tried passing the ADMListRef object that buffers the reference to the menu to the List Suite, but I can't seem to get it to do anything.

How do you make/add to menu's that the user gets when they right click?

Am I on the right track?

Is there any better documentation on these suites that I can look to for answers?

Thanks in advance,

Jeremy

This topic has been closed for replies.
Correct answer A. Patterson

Ok, I've got the menu but for some reason notfications are being sent back to the Item, not the entry/list's. This is what I have so far

In the dialog i create the Item:

g->cMenu = sADMDialog->CreateItem(reference,kADMUniqueItemID,kADMPopupMenuType,&button,ChanMenuInit,NULL,0);

The item is a button with an arrow that points to the right. when clicked it pops a menu out to the right that has two columns.

The Item's init function is this:

static

ADMErr ADMAPI ChanMenuInit(ADMItemRef inItem){

g->list = sADMItem->GetList(inItem);

for(int

i = 0; i < g->numChannels; i ++){

g->MenuItems = sADMEntry->Create(g->list);

}

sADMList->SetNotifyProc(g->list,MenuChannelCatch);

sADMEntry->SetText(g->MenuItems[1],

"1");

sADMEntry->SetText(g->MenuItems[2],

"2");

sADMEntry->SetText(g->MenuItems[3],

"3");

sADMEntry->SetText(g->MenuItems[4],

"4");

sADMEntry->SetText(g->MenuItems[5],

"5");

return

kNoErr;

}

This shoudl create 5 Entries into the list (which it does); however, each entry is blank with no value. When clicked a notifier for the button is triggered, not the list (I put the button notifier after noticing that that the list wasn't doing anything). I'm probibly missing some kind of Init procedure, any ideas?


Well, I don't use the same method for creating my pop-up menu. I do something slightly different, and maybe it makes a difference. I should note that I'm using the IADM* objects too, so there may be subtle differences -- they generally wrap to the obvious suite call though. Note also that I'm updating a list based on other events, so you can probably ignore clearing part

--------- snip ---------

IADMItem button(GetItem(kChangeMapViewButton));

IADMList list(button.GetList());

const int count = list.NumberOfEntries(); 

// clear list
for (int i = 0; i < count; i++) {
  list.RemoveEntry(0);
}

// get my view list (what the views are is unimportant to you!)

const CString kSentToTemplate = QObject::tr("Switch to \"%1\"");
MapViewList::iterator index;

for (index = viewList.begin(); index != viewList.end(); ++index) {
  int position = list.NumberOfEntries();
  IADMEntry entry(list.InsertEntry(position));
  CMapView* view = *index;

  // CPlatformString is my own home-cooked class for converting between our

  // internal string object & Adobe's ASUnicode (returned via au_atr())
  CPlatformString text = kSentToTemplate.arg(view->GetName());
  entry.SetText(text.au_str());
  entry.SetUserData((void*)view);
  entry.SetID(position);
}

--------- snip ---------

I think that setting the ID is critical to actually knowing which menuitem was hit -- I think they're all zero by default, which is part of the problem. I could be wrong though. I remember I wrestled with this a fair bit before I got it right. It maybe that asking for the ActiveEntry() is sufficient (as you'll see below). Still, setting an ID that means something is bound to be useful if you're not using the Get/SetUserData() calls.

To determine which entry was clicked, I respond to the item changed notifier (which you said you're getting). That looks kind of like this:

--------- snip ---------

IADMItem button(GetItem(kChangeMapViewButton));
IADMList list(button.GetList());

ADMEntryRef entryRef = list.GetActiveEntry();

if (entryRef) {
  IADMEntry entry(entryRef);

  // I'm using the user data so I don't actually care which entry was clicked
  void* data = entry.GetUserData();

  // you could ask for the ID at this point and that would tell you the index into the list;

  // nothing stops you from making the IDs whatever you want though, if they're

  // hard-coded

  const int id = entry.GetID();

  // respond

}

--------- snip ---------

FYI, the button in question is of type "ADM Popup Menu Type", at least in my resource file. I'm pretty sure that corresponds to a type in the ADMItem.h header if you search for it though. I don't know if you're using the same type of button or not though. Still, it's likely very similar.

1 reply

A. Patterson
Inspiring
October 8, 2009

Illustrator has no support for context menus of any kind unfortunately. I'm curious though, what suite did you find that you think provides this support? From what you're describing it sounds like you're talking about pop-up menus from certain widgets, or perhaps the fly-out menu for a panel.

At any rate, I sympathize -- I've wanted to customize those context menus forever but I'm afraid short of hacking in with OS-level calls (and I'm not reccommending that!) there's no way to change those.

zabadorAuthor
Known Participant
October 9, 2009

The ADMBasicSuite10 us defined in the documentation as:

struct  ADMBasicSuite10 This suite provides utility functions that allow you to work with platform string and cursor resources, tool tips, and context menus. More..

Maybe I have a diffrent definition of a context menu. What im looking for is the ability to right click a vector shape, have a menu there where I can preform some action. Is that at all possible?

Jeremy

A. Patterson
A. PattersonCorrect answer
Inspiring
October 16, 2009

Ok, I've got the menu but for some reason notfications are being sent back to the Item, not the entry/list's. This is what I have so far

In the dialog i create the Item:

g->cMenu = sADMDialog->CreateItem(reference,kADMUniqueItemID,kADMPopupMenuType,&button,ChanMenuInit,NULL,0);

The item is a button with an arrow that points to the right. when clicked it pops a menu out to the right that has two columns.

The Item's init function is this:

static

ADMErr ADMAPI ChanMenuInit(ADMItemRef inItem){

g->list = sADMItem->GetList(inItem);

for(int

i = 0; i < g->numChannels; i ++){

g->MenuItems = sADMEntry->Create(g->list);

}

sADMList->SetNotifyProc(g->list,MenuChannelCatch);

sADMEntry->SetText(g->MenuItems[1],

"1");

sADMEntry->SetText(g->MenuItems[2],

"2");

sADMEntry->SetText(g->MenuItems[3],

"3");

sADMEntry->SetText(g->MenuItems[4],

"4");

sADMEntry->SetText(g->MenuItems[5],

"5");

return

kNoErr;

}

This shoudl create 5 Entries into the list (which it does); however, each entry is blank with no value. When clicked a notifier for the button is triggered, not the list (I put the button notifier after noticing that that the list wasn't doing anything). I'm probibly missing some kind of Init procedure, any ideas?


Well, I don't use the same method for creating my pop-up menu. I do something slightly different, and maybe it makes a difference. I should note that I'm using the IADM* objects too, so there may be subtle differences -- they generally wrap to the obvious suite call though. Note also that I'm updating a list based on other events, so you can probably ignore clearing part

--------- snip ---------

IADMItem button(GetItem(kChangeMapViewButton));

IADMList list(button.GetList());

const int count = list.NumberOfEntries(); 

// clear list
for (int i = 0; i < count; i++) {
  list.RemoveEntry(0);
}

// get my view list (what the views are is unimportant to you!)

const CString kSentToTemplate = QObject::tr("Switch to \"%1\"");
MapViewList::iterator index;

for (index = viewList.begin(); index != viewList.end(); ++index) {
  int position = list.NumberOfEntries();
  IADMEntry entry(list.InsertEntry(position));
  CMapView* view = *index;

  // CPlatformString is my own home-cooked class for converting between our

  // internal string object & Adobe's ASUnicode (returned via au_atr())
  CPlatformString text = kSentToTemplate.arg(view->GetName());
  entry.SetText(text.au_str());
  entry.SetUserData((void*)view);
  entry.SetID(position);
}

--------- snip ---------

I think that setting the ID is critical to actually knowing which menuitem was hit -- I think they're all zero by default, which is part of the problem. I could be wrong though. I remember I wrestled with this a fair bit before I got it right. It maybe that asking for the ActiveEntry() is sufficient (as you'll see below). Still, setting an ID that means something is bound to be useful if you're not using the Get/SetUserData() calls.

To determine which entry was clicked, I respond to the item changed notifier (which you said you're getting). That looks kind of like this:

--------- snip ---------

IADMItem button(GetItem(kChangeMapViewButton));
IADMList list(button.GetList());

ADMEntryRef entryRef = list.GetActiveEntry();

if (entryRef) {
  IADMEntry entry(entryRef);

  // I'm using the user data so I don't actually care which entry was clicked
  void* data = entry.GetUserData();

  // you could ask for the ID at this point and that would tell you the index into the list;

  // nothing stops you from making the IDs whatever you want though, if they're

  // hard-coded

  const int id = entry.GetID();

  // respond

}

--------- snip ---------

FYI, the button in question is of type "ADM Popup Menu Type", at least in my resource file. I'm pretty sure that corresponds to a type in the ADMItem.h header if you search for it though. I don't know if you're using the same type of button or not though. Still, it's likely very similar.