Difference between revisions of "Context Menu"

From PowerUI
Jump to: navigation, search
 
(9 intermediate revisions by 2 users not shown)
Line 1: Line 1:
Context menus pop up to display one or more options to the user, depending on what it was that they interacted with. They come in a huge variety of shapes and sizes - from radial "Sims style" to ordinary lists that show up when you right click. PowerUI has a built in context menu system which sits on top of the window system enabling templates of context menu's to be easily created and shared.
+
Context menus pop up to display one or more options to the user, depending on what it was that they interacted with. They come in a huge variety of shapes and sizes - from radial "Sims style" to ordinary lists that show up when you right click. PowerUI has a built in context menu system which sits on top of the [[Widget Manager|widget system]] enabling [[Widget Templates|templates of context menu's]] to be easily created and shared.
  
 
== 2D and 3D context menu's ==
 
== 2D and 3D context menu's ==
Line 5: Line 5:
 
Context menu's can be created for either 2D or 3D objects. The flow of both has been made as consistent as possible - essentially, you need to '''respond to the contextmenu event'''.  
 
Context menu's can be created for either 2D or 3D objects. The flow of both has been made as consistent as possible - essentially, you need to '''respond to the contextmenu event'''.  
  
 +
=== 2D ===
  
== 3D ==
+
HTML elements receive a contextmenu event, which you can connect to however you like (usually with addEventListener("contextmenu",..)). Use ContextEvent.add in there too in order to build up the options. For example, you might have an inventory. Each item, when clicked on, generates a context menu with options like "use" or "drop". You'd add each of those via ContextEvent.add.
  
Attach something like this to your GameObject:
+
=== 3D ===
 +
 
 +
Tick '''Window > PowerUI > Handle 3D Input''' and attach something like this to your GameObjects:
  
 
<syntaxhighlight lang="csharp">
 
<syntaxhighlight lang="csharp">
Line 18: Line 21:
  
  
public class MyEventTarget : MonoBehaviour,IEventTarget {
+
public class My3DContextMenu : MonoBehaviour {
 +
 +
public void OnContextMenu(ContextEvent e){
 
 
public bool dispatchEvent(DomEvent e){
+
// *this* GameObject has been asked for a context menu.
 
 
if(e.type!="contextmenu"){
 
return true;
 
}
 
 
// *this* GameObject has been asked for a context menu.
 
ContextEvent context=e as ContextEvent;
 
 
 
// E.g. if this gameObject is some kind of door, then:
 
// E.g. if this gameObject is some kind of door, then:
 
context.add("&Open;",delegate(Option o){
 
context.add("&Open;",delegate(Option o){
 
 
// 'open' gameObject
+
// 'open' the door!
 
 
 
});
 
});
 
// Returning false kills any bubbling:
 
return true;
 
 
 
 
}
 
}
Line 47: Line 42:
 
If you use this approach, note that '''the event will bubble up the scene hierarchy''', in a similar way to it bubbling through the DOM. This way, if PowerUI's input ray hits a collider which is a child of an NPC or a door etc, then it will reach the root NPC object and you'll get a successful handle.
 
If you use this approach, note that '''the event will bubble up the scene hierarchy''', in a similar way to it bubbling through the DOM. This way, if PowerUI's input ray hits a collider which is a child of an NPC or a door etc, then it will reach the root NPC object and you'll get a successful handle.
  
If you don't want to add a script to every gameObject, then instead you can use the GameObject to EventTarget mapper and handle obtaining the event target in a custom way:
+
=== Advanced 3D ===
 +
 
 +
Advanced: If you don't want to add a script to every gameObject, then instead you can use the GameObject to EventTarget mapper and handle obtaining the event target in a custom way:
  
 
<syntaxhighlight lang="csharp">
 
<syntaxhighlight lang="csharp">
Line 66: Line 63:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
For example, you might an NPC class (and that NPC class is an IEventTarget). You'd map the given gameObject through to an NPC instance.
+
For example, you might have an NPC class (and that NPC class is an IEventTarget). You'd map the given gameObject through to an NPC instance.
  
 
The dispatch method is, however, the same as the MonoBehaviour approach (only it would return e.g. context options specific to an NPC).
 
The dispatch method is, however, the same as the MonoBehaviour approach (only it would return e.g. context options specific to an NPC).
 
== 2D ==
 
 
HTML elements receive a contextmenu event, which you can connect to however you like (usually with addEventListener("contextmenu",..)). Use ContextEvent.add in there too in order to build up the options. For example, you might have an inventory. Each item, when clicked on, generates a context menu with options like "use" or "drop". You'd add each of those via ContextEvent.add.
 
  
 
== Setting up the appearance of context menu's ==
 
== Setting up the appearance of context menu's ==
  
ContextEvent has a field called '''window''':
+
ContextEvent has a field called '''template''' - it's the name of one of your [[Widget Templates|widget templates]]:
  
  
Line 85: Line 78:
  
 
// Set the template to use:
 
// Set the template to use:
context.window="windowTemplateName";
+
context.template="widgetTemplateName";
  
 
</syntaxhighlight>
 
</syntaxhighlight>

Latest revision as of 05:11, 19 April 2017

Context menus pop up to display one or more options to the user, depending on what it was that they interacted with. They come in a huge variety of shapes and sizes - from radial "Sims style" to ordinary lists that show up when you right click. PowerUI has a built in context menu system which sits on top of the widget system enabling templates of context menu's to be easily created and shared.

2D and 3D context menu's

Context menu's can be created for either 2D or 3D objects. The flow of both has been made as consistent as possible - essentially, you need to respond to the contextmenu event.

2D

HTML elements receive a contextmenu event, which you can connect to however you like (usually with addEventListener("contextmenu",..)). Use ContextEvent.add in there too in order to build up the options. For example, you might have an inventory. Each item, when clicked on, generates a context menu with options like "use" or "drop". You'd add each of those via ContextEvent.add.

3D

Tick Window > PowerUI > Handle 3D Input and attach something like this to your GameObjects:

using UnityEngine;
using System.Collections;
using Dom;
using ContextMenus;


public class My3DContextMenu : MonoBehaviour {
	
	public void OnContextMenu(ContextEvent e){
	
		// *this* GameObject has been asked for a context menu.
		
		// E.g. if this gameObject is some kind of door, then:
		context.add("&Open;",delegate(Option o){
			
			// 'open' the door!
		
		});
		
	}
	
}

If you use this approach, note that the event will bubble up the scene hierarchy, in a similar way to it bubbling through the DOM. This way, if PowerUI's input ray hits a collider which is a child of an NPC or a door etc, then it will reach the root NPC object and you'll get a successful handle.

Advanced 3D

Advanced: If you don't want to add a script to every gameObject, then instead you can use the GameObject to EventTarget mapper and handle obtaining the event target in a custom way:

// Hook up our mapper:
PowerUI.Input.TargetResolver=delegate(GameObject go,out bool cancelEvent){
	
	// Don't cancel the event:
	cancelEvent=false;
	
	// ..Do whatever you'd like to get hold of some object which implements IEventTarget..
	// (If you don't get a match, that's fine - return null)
	IEventTarget myTarget=null;
	
	return myTarget;
};

For example, you might have an NPC class (and that NPC class is an IEventTarget). You'd map the given gameObject through to an NPC instance.

The dispatch method is, however, the same as the MonoBehaviour approach (only it would return e.g. context options specific to an NPC).

Setting up the appearance of context menu's

ContextEvent has a field called template - it's the name of one of your widget templates:


// Get it as a context event:
ContextEvent context=e as ContextEvent;

// Set the template to use:
context.template="widgetTemplateName";

By default, it's "menulist" - the name of a built in context menu. Conveniently, this approach means different objects can respond with completely different context menu styles too; for example, a 3D NPC might display a radial context menu (like in the Sims) and a 2D item in an inventory displays the default menulist.

Menulist - the built in default

You can find the source for menulist here:

PowerUI\Source\Extras\Context Menus\Built in\Menulist