Custom Right Click or Context Menu in Flex/Flash AS3

Posted: May 31st, 2009 | Author: danny | Filed under: Flex | 9 Comments »

UPDATE: Please see comments for a bug, and a work around.

I’ve created a small little library for creating a right click menu in flash:

This works not only on the top level components, but also on nested components. In the example you can right click on each button and see a custom menu.

Demo:

Some Links:
AS3 Right Click Context Menu Right, Click To View Source

Context Menu Source In Zip File

MIT Licensed

package
{
	import flash.events.ContextMenuEvent;
	import flash.events.MouseEvent;
	import flash.ui.ContextMenuItem;
 
	import mx.core.Application;
	import mx.core.UIComponent;
 
	public class RightClickMenu
	{
		public var MenuContents:Array = new Array ();
 
		public  function RightClickMenu(){}
 
		public function AddItem (name:String, func:Function):void
		{
			MenuContents.push({Name:name, Func:func});
		}
 
		public function AssignRightClick (uiComponent:UIComponent):void
		{
			uiComponent.addEventListener(MouseEvent.MOUSE_OVER, genEnableMenu (uiComponent));
			uiComponent.addEventListener(MouseEvent.MOUSE_MOVE, disableMenu);
		}
 
		/* Assignment */
		private function ResetContextMenu (event:MouseEvent):void
		{	//remove menu
			Application.application.contextMenu.customItems = new Array ();
			//remove this function
			Application.application.removeEventListener(MouseEvent.MOUSE_MOVE, ResetContextMenu);
		}
 
		private function disableMenu(event:MouseEvent):void
		{
			//Stop the mouse move event from propagating to the application level, where we remove the menu
			event.stopImmediatePropagation();
		}
 
		private function genEnableMenu (uiComponent:UIComponent):Function
		{
			return function (event:MouseEvent):void
			{
				//add event listener to remove the menu on mouse move
				Application.application.addEventListener(MouseEvent.MOUSE_MOVE, ResetContextMenu);			
 
				//hide current menu
				Application.application.contextMenu.hideBuiltInItems();
 
				//remove menu (ifyou right click and then move, this may not be killed.
				Application.application.contextMenu.customItems = new Array ();				
 
				//create new menu
				for (var i:Number in MenuContents)
				{
					var menuItem:ContextMenuItem = new ContextMenuItem(MenuContents[i].Name);
					menuItem.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT, MenuContents[i].Func);
					Application.application.contextMenu.customItems.push(menuItem);
				}
			}
		}
 
		private function genClickCall (func:Function):Function
		{
			return function (event:ContextMenuEvent):void
			{
				func()
				ResetContextMenu(null);
			}
 
		}
 
	}
}

To use the class 1) Create an instance of it, 2) Populate it, 3) bind it to the component.

		<![CDATA[
			import mx.controls.Alert;
 
			private function appComplete ():void
			{
				var menu1:RightClickMenu = new RightClickMenu ();
				menu1.AddItem("B1", function ():void{Alert.show("B1");});
				menu1.AddItem("B1-A", function ():void{Alert.show("B1-A");});
				menu1.AssignRightClick(b1);
 
				var menu2:RightClickMenu = new RightClickMenu ();
				menu2.AddItem("B2", function ():void{Alert.show("B2");});
				menu2.AssignRightClick(b2);
 
				var menu3:RightClickMenu = new RightClickMenu ();
				menu3.AddItem("B3", function ():void{Alert.show("B3");});
				menu3.AssignRightClick(b3);		
 
			}
		]]>

Exposing CouchDB to the World

Posted: May 29th, 2009 | Author: danny | Filed under: couchdb | 2 Comments »

To allow non-local connections to couchdb is quite easy.

To allow non local access, modify


/usr/local/etc/couchdb/default.ini

so that

bind_address = 0.0.0.0


Snippet from Planned Chaos

Posted: May 13th, 2009 | Author: danny | Filed under: Uncategorized | No Comments »

Here’s an excellent description that captures the essence of government much more clearly than than Paine’s eloquent line:

“Society in every state is a blessing, but government, even in its best state, is but a necessary evil; in its worst state, an intolerable one.”

Perhaps because it speaks so simply, Planned Chaos by Ludwig Von Mises, Chapter 6: The Liberation of Demons (Page 63)

State and government are nothing else than the social apparatus of violent coercion and repression. Such an apparatus, the police power, is indispensable in order to prevent antisocial individuals and bands from destroying social cooperation. Violent prevention and suppression of antisocial activities benefit the whole of society and each of its members. But violence and oppression are nonetheless evils and corrupt those in charge of their application. It is necessary to restrict the power of those in office lest they become absolute despots. Society cannot exist without an apparatus of violence coercion. But neither can it exist if the office holders are irresponsible tyrants free to inflict harm upon those they dislike.

And by antisocial he doesn’t mean what is covered by the ASBOs


Heidegger, AI, All Around

Posted: May 11th, 2009 | Author: danny | Filed under: Uncategorized | No Comments »

So today, I found one of my books on Heidegger, my ipod played a heidegger lecture on random, and I stumbled across a Heidegger video on reddit, so I figured I’d post the lecture. It’s by Hubert Dreyfus, and in at about 30 minutes in he starts talking about limits to symbolic artificial intelligence — It’s really good here’s the link: http://webcast.berkeley.edu/stream.php?type=download&webcastid=20429

The entire series of lectures, which is really good so far — I still have a lot left, is at: http://webcast.berkeley.edu/course_details.php?seriesid=1906978475


CouchDB & CouchApp Managing Design Documents

Posted: May 11th, 2009 | Author: danny | Filed under: couchdb, riot | 1 Comment »

I’ve been working with CouchDB and I was never really happy with how I was managing/version controlling my design documents.  Luckily, I read about CouchApp — I had initially thought it was a tool for developing CouchDB hosted appilcations, but now know that it can be used to at a very basic level to make it easy to control my desgin documents.  Here are a few notes that might make it easy for others to get started; I’m still learning this tool, so this may not be the optimal procedure (also, I’m not using any of the advanced features of CouchApp [e.g. macros], but will in the future).

There are two ways of using CouchApp  to push design documents to CouchDb: 1.  Generating the design document from multiple files (preferred), and 2. Generating the views from a single JSON file.

Generating the Design Document from its Component Pieces

  1. Install CouchDB & CouchApp – Both are easy to install and well documented, so need for any additional notes.
  2. The directory structure used is used to hold the atomic pieces of the design document and should have a structure as follows:
    • {myapp} – app directory
    • {myapp}/{sampledesign} — design document name
    • {myapp}/{sampledesign}/views — directory that holds views
    • {myapp}/{sampledesign}/views/{viewname}/ — view name
    • {myapp}/{sampledesign}/views/{viewname}/map.js — map function
    • {myapp}/{sampledesign}/views/{viewname}/reduce.js — reduce function

    We create a directory for the application {myapp}, we  then create a directory to hold our design document {sampledesign}, and last we create a directory for our view {viewname}.  Each view must contain one map.js file, and can (optional) contain one reduce.js file.

  3. In this example we’re only going to create a map function, so map.js should look like:
            //This is a simple function that doesn't do anything
            //useful, but will work on all CouchDB databases.
            function(doc) {
               emit(doc._id, doc);
            }
  4. To generate the design document and push it into CouchDB: Go to the {myapp} directory run the following command (for this example assume: {myapp} = myapp and {sampledesing} = mydesigndoc ):

    couchapp push mydesigndoc http://127.0.0.1:5984/myapp

  5. To view the generate design document you can go to  http://localhost:5984/_utils/document.html?myapp/_design/mydesigndoc#source (the following url is for a db named myapp with a design document named mydesigndoc)

And that’s all there is to it.  You can develop and version control the design documents.

Alternate: Generating the views from a single JSON file.

  1. Install CouchDB & CouchApp – Both are easy to install and well documented, so need for any additional notes.
  2. Create a directory to store the design documents: “myapp/_design”  (this directory can be anything)
  3. Create a directory for each design document: “myapp/_desgin/design_document”
  4. Inside the design document create a JSON file named views (views.json) : “myapp/_design/design_document/views.json”
  5. The contents of thee view document should be a JSON document containing view objects with map and reduce functions. For example, see the code listing below we have the view test with a map function.  Note: This is a useless view, but it will work on any CouchDB database.
    {
       "views": {
           "test": {
            "map": "function(doc) {\n    emit(doc._id, doc);\n}\n"
           }
       }
    }
  6. From the “_design” directory run the following command:

    couchapp push {desgin_document_dir} http://127.0.0.1:5984/{dbname}

    where {dbname} is the name of your db and {design_document_dir} is the name of the design document directory , so if my database was named: “myapp”  and the design document dir was named: “sampledesign” it would look like:

    couchapp push sampledesign http://127.0.0.1:5984/myapp

    Note: If you are unsure of what the view json structure is you can create your views using Futon which is installed at: http://localhost:5984/_utils/ by creating a temporary view, saving it, and then navigating to the design document it created.  http://localhost:5984/_utils/document.html?myapp/_design/sampledesign#source (the following url is for a db named myapp with a design document named sampledesign)

After following those steps you can easily push json documents to couchdb and use whatever version controll system that you’d like; however, there is a better way of laying out the files.

So there you have it, a quick introduction to the two ways of using CouchApp to manage CouchDB Documents.