Beispiel #1
0
// 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;
}
UWORD lister_listerpopup(Lister *lister,UWORD code)
{
	short a,num=0;
	UWORD res;
	PopUpHandle *menu;
	PopUpItem *item;
	PopUpExt *ext;

	// Allocate menu handle
	if (!(menu=PopUpNewHandle((ULONG)lister,lister->backdrop_info->callback,&locale)))
		return (UWORD)-1;

	// Build default lister popup
	for (a=0;lister_popup_data[a];a+=2)
	{
		if (lister_popup_data[a]==(UWORD)-1)
			PopUpSeparator(menu);
		else
		if ((item=PopUpNewItem(menu,lister_popup_data[a],lister_popup_data[a+1],0)))
		{
			// Kludge for 'lock position'
			if (item->id==MENU_LISTER_LOCK_POS)
				item->flags|=POPUPF_CHECKIT|((lister->flags&LISTERF_LOCK_POS)?POPUPF_CHECKED:0);
		}
	}

	// Clear 'separator' flag
	menu->ph_Flags&=~POPHF_SEP;

	// Lock extension list
	lock_listlock(&GUI->popupext_list,FALSE);

	// Go through list
	for (ext=(PopUpExt *)GUI->popupext_list.list.lh_Head;
		ext->pe_Node.ln_Succ;
		ext=(PopUpExt *)ext->pe_Node.ln_Succ)
	{
		// Lister?
		if (ext->pe_Type==POPUP_LISTER2)
		{
			// Check custom handler
			if (!(ext->pe_Flags&POPUPEXTF_HANDLER) ||
				strcmp(ext->pe_Command,lister->cur_buffer->buf_CustomHandler)==0)
			{
				// Add a separator if needed
				if (!(menu->ph_Flags&POPHF_SEP))
					PopUpSeparator(menu);

				// Allocate item
				if ((item=PopUpNewItem(
					menu,
					(ULONG)ext->pe_Menu,
					MENU_EXTENSION+num,
					POPUPF_STRING)))
				{
					// Set data pointer
					item->data=ext;
					++num;
				}
			}
		}
	}

	// Do popup menu
	item=0;
	if ((res=DoPopUpMenu(lister->window,&menu->ph_Menu,&item,code))!=(UWORD)-1 &&
		res>=MENU_EXTENSION)
	{
		// Got valid pointer?
		if (item && item->data)
		{
			PopUpExt *ext=(PopUpExt *)item->data;

			// Custom handler in lister?
			if (strcmp(lister->cur_buffer->buf_CustomHandler,ext->pe_Command)==0)
			{
				// Send message
				rexx_handler_msg(
					0,
					lister->cur_buffer,
					RXMF_WARN,
					HA_String,0,ext->pe_Menu,
					HA_Value,1,lister,
					TAG_END);
			}

			// Normal extension
			else
			{
				// Call popup function
				popup_run_func(item->data,0,0,lister);
			}

			// Clear result code
			res=(UWORD)-1;
		}
	}

	// Unlock extension list
	unlock_listlock(&GUI->popupext_list);

	// Free menu data
	PopUpFreeHandle(menu);
	return res;
}