Esempio n. 1
0
// 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);
}
Esempio n. 2
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;
}