// Build user menu void display_build_user_menu(void) { Cfg_Button *button; AppEntry *appmenu; short count=0,tool_count=0; // Lock menus GetSemaphore(&GUI->user_menu_lock,SEMF_SHARED,0); // Free existing menu FreeVec(GUI->user_menu_data); // Got user menu? if (GUI->user_menu) { // Go through user menu for (button=(Cfg_Button *)GUI->user_menu->buttons.lh_Head; button->node.ln_Succ; button=(Cfg_Button *)button->node.ln_Succ) { // Title? if (button->button.flags&BUTNF_TITLE) ++count; // Otherwise else { Cfg_ButtonFunction *func; short num; // First item, default title? if (count==0) count=1; // Add this item ++count; // Go through functions for (func=(Cfg_ButtonFunction *)button->function_list.mlh_Head,num=0; func->node.ln_Succ; func=(Cfg_ButtonFunction *)func->node.ln_Succ) { // Ignore function if empty if ((!function_label(func) || !*function_label(func)) && IsListEmpty((struct List *)&func->instructions)) continue; // Skip first function until we know there's more if (num>0) { // Increment count ++count; if (num==1) ++count; } // Increment function count ++num; } } } } // Showing Tools menu? if (environment->env->display_options&DISPOPTF_SHOW_TOOLS && !(GUI->flags&GUIF_NO_TOOLS_MENU)) { // Lock AppList appmenu=LockAppList(); // Count tool (app) menus while ((appmenu=NextAppEntry(appmenu,APP_MENU)) && (++tool_count)<63); // Unlock AppList UnlockAppList(); // Add tools title if (tool_count>0) ++count; } // Add end node ++count; // Allocate data for user menus if ((GUI->user_menu_data=AllocVec(sizeof(MenuData)*(count+tool_count),MEMF_CLEAR))) { short num=0; // Got a user menu? if (GUI->user_menu) { short item; // Go through user menu for (button=(Cfg_Button *)GUI->user_menu->buttons.lh_Head,item=0; button->node.ln_Succ; button=(Cfg_Button *)button->node.ln_Succ,item++) { Cfg_ButtonFunction *func; short title=0; // Title? if (button->button.flags&BUTNF_TITLE) title=1; // Otherwise else { // First item, default title? if (item==0) title=2; } // Need to do title? if (title) { // Get button function if (title==1) func=(Cfg_ButtonFunction *) FindFunctionType((struct List *)&button->function_list,FTYPE_LEFT_BUTTON); else func=0; // Fill in data GUI->user_menu_data[num].type=NM_TITLE; GUI->user_menu_data[num].id=(ULONG)func; if (func) { if (!(GUI->user_menu_data[num].name=(ULONG)function_label(func))) GUI->user_menu_data[num].name=(ULONG)GUI->null_string; } else GUI->user_menu_data[num].name=(ULONG)GetString(&locale,MSG_USER_MENU); GUI->user_menu_data[num].flags=MENUFLAG_TEXT_STRING; ++num; } // Real function? if (title!=1) { Cfg_ButtonFunction *first=0; short type=NM_ITEM; short tot; // Go through functions for (func=(Cfg_ButtonFunction *)button->function_list.mlh_Head,tot=0; func->node.ln_Succ; func=(Cfg_ButtonFunction *)func->node.ln_Succ) { // Ignore function if empty if ((!function_label(func) || !*function_label(func)) && IsListEmpty((struct List *)&func->instructions)) continue; // On the second function? if (tot==1) { // Did the first function have instructions? if (!(IsListEmpty((struct List *)&first->instructions))) { // Use it again func=first; } } // Fill in menu data GUI->user_menu_data[num].type=type; GUI->user_menu_data[num].id=(ULONG)func; // Bar label? if (function_label(func) && strncmp(function_label(func),"---",3)==0) GUI->user_menu_data[num].name=(ULONG)NM_BARLABEL; // Normal function else { // Get name if (!(GUI->user_menu_data[num].name=(ULONG)function_label(func))) GUI->user_menu_data[num].name=(ULONG)GUI->null_string; GUI->user_menu_data[num].flags=MENUFLAG_TEXT_STRING; // Does function have a right-amiga hotkey? if (func->function.qual&IEQUALIFIER_RCOMMAND) { char key; // Convert from rawkey if (ConvertRawKey(func->function.code,0,&key)) { unsigned short qual; // For letters, shift is always down if (key>='a' && key<='z') qual=IEQUALIFIER_LSHIFT; // Otherwise, it might be down else qual=func->function.qual&IEQUAL_ANYSHIFT; // Convert again if (ConvertRawKey(func->function.code,qual,&key)) { // Set flags for hotkey GUI->user_menu_data[num].flags|=MENUFLAG_USE_SEQ; GUI->user_menu_data[num].flags|=MENUFLAG_MAKE_SEQ(key); } } } } // Change type to sub-item type=NM_SUB; ++num; // Remember first function if (!first) first=func; // Increment count ++tot; } } } } // Tool menu? if (tool_count>0) { short tot=0; // Build tool title GUI->user_menu_data[num].type=NM_TITLE; GUI->user_menu_data[num].id=MENU_TOOL_MENU; GUI->user_menu_data[num++].name=MSG_TOOL_MENU; // Lock AppList appmenu=LockAppList(); // Fill in tool menus while ((appmenu=NextAppEntry(appmenu,APP_MENU)) && (++tot)<63) { // Fill in menu data GUI->user_menu_data[num].type=NM_ITEM; GUI->user_menu_data[num].id=(ULONG)appmenu; // Separator? if (strncmp(appmenu->text,"---",3)==0) { GUI->user_menu_data[num].name=(ULONG)NM_BARLABEL; } // Normal string else { GUI->user_menu_data[num].name=(ULONG)appmenu->text; GUI->user_menu_data[num].flags=MENUFLAG_TEXT_STRING; } // Increment count ++num; } // Unlock AppList UnlockAppList(); } // Last menu GUI->user_menu_data[num].type=NM_END; } // Go through fixed menus, look for NM_NEXT for (count=0;dopus_menus[count].type!=NM_NEXT;count++); // Point fixed menus on to user menu dopus_menus[count].name=(ULONG)GUI->user_menu_data; // Unlock menus FreeSemaphore(&GUI->user_menu_lock); }
// Build PopUp menu from a button bank PopUpHandle *popup_from_bank(Cfg_ButtonBank *bank,short *last_id) { PopUpHandle *handle; PopUpItem *item=0; Cfg_Button *button; short id,depth=0; if (last_id) *last_id=0; // No bank? if (!bank) return 0; // Create handle if (!(handle=PopUpNewHandle(0,0,&locale))) return 0; // Go through menu bank for (button=(Cfg_Button *)bank->buttons.lh_Head,id=0; button->node.ln_Succ; button=(Cfg_Button *)button->node.ln_Succ) { Cfg_ButtonFunction *func; Cfg_Instruction *ins; char *label; BOOL sep=FALSE; short ins_count; /* KPrintF("button flags %lx (title %lx item %lx sub %lx)\n",button->button.flags, button->button.flags&BUTNF_TITLE,button->button.flags&BUTNF_ITEM,button->button.flags&BUTNF_SUB); for (func=(Cfg_ButtonFunction *)button->function_list.mlh_Head;func->node.ln_Succ;func=(Cfg_ButtonFunction *)func->node.ln_Succ) { Cfg_Instruction *ins; KPrintF("name %s label %s flags %lx type %ld\n",func->node.ln_Name,func->label,func->function.flags2,func->function.func_type); for (ins=(Cfg_Instruction *)func->instructions.mlh_Head;ins->node.mln_Succ;ins=(Cfg_Instruction *)ins->node.mln_Succ) KPrintF("\t%ld %s\n",ins->type,ins->string); } KPrintF("------------\n"); */ // Get first function func=(Cfg_ButtonFunction *)button->function_list.mlh_Head; if (!func->node.ln_Succ) continue; // Count the instructions for (ins=(Cfg_Instruction *)func->instructions.mlh_Head,ins_count=0;ins->node.mln_Succ;ins=(Cfg_Instruction *)ins->node.mln_Succ) { // Increment count if not a label if (ins->type!=INST_LABEL) ++ins_count; } // Get label pointer, see if this is a separator if (!(label=function_label(func)) || !*label) continue; if (strncmp(label,"---",3)==0) sep=TRUE; // Menu title? if (button->button.flags&BUTNF_TITLE) { // End existing sub-menu if (depth==1) { PopUpEndSub(handle); depth=0; } // Separator? if (sep) PopUpSeparator(handle); // Add a new item else if (item=PopUpNewItem(handle,(ULONG)label,id++,POPUPF_STRING)) { // Save pointer to function in item data item->data=func; } continue; } // Entering item? if (depth==0 && item) { // Store item data in userdata field (since subitem info will overwrite data field) item->userdata=item->data; item->flags|=POPUPF_USERDATA; // Go into sub-item if (PopUpItemSub(handle,item)) item->flags|=POPUPF_SUB; depth=1; } // Separator? if (sep) PopUpSeparator(handle); // Empty function, with sub-items? else if (ins_count<1 && func->node.ln_Succ->ln_Succ) { // Add parent item if (item=PopUpNewItem(handle,(ULONG)label,id++,POPUPF_STRING|POPUPF_SUB|POPUPF_USERDATA)) { // Initialise item for sub-items item->userdata=func; if (PopUpItemSub(handle,item)) { // Go through sub-items for (func=(Cfg_ButtonFunction *)func->node.ln_Succ; func->node.ln_Succ; func=(Cfg_ButtonFunction *)func->node.ln_Succ) { // Get label pointer, see if this is a separator if (!(label=function_label(func)) || !*label) continue; if (strncmp(label,"---",3)==0) PopUpSeparator(handle); else if (item=PopUpNewItem(handle,(ULONG)label,id++,POPUPF_STRING)) { // Save pointer to function in item data item->data=func; } } // End sub-items PopUpEndSub(handle); } } } // Create item else if (item=PopUpNewItem(handle,(ULONG)label,id++,POPUPF_STRING)) { // Save pointer to function in item data item->data=func; } } // End existing sub-menu if (depth==1) PopUpEndSub(handle); // Set flags if (bank->window.flags&BTNWF_NO_SCALE_IMAGES) handle->ph_Menu.flags|=POPUPMF_NO_SCALE; else handle->ph_Menu.flags&=~POPUPMF_NO_SCALE; // Return ID if (last_id) *last_id=id; return handle; }