diff --git a/src/as/com/threerings/crowd/client/PlaceController.as b/src/as/com/threerings/crowd/client/PlaceController.as index 06f995f13..d564fd5a2 100644 --- a/src/as/com/threerings/crowd/client/PlaceController.as +++ b/src/as/com/threerings/crowd/client/PlaceController.as @@ -21,6 +21,8 @@ package com.threerings.crowd.client { +import com.threerings.util.Controller; + import com.threerings.crowd.data.PlaceConfig; import com.threerings.crowd.data.PlaceObject; import com.threerings.crowd.util.CrowdContext; @@ -33,7 +35,7 @@ import com.threerings.events.ControllerEvent; * constructed and requested to create and display the appopriate user * interface for that place. */ -public /*abstract*/ class PlaceController /*extends Controller*/ +public /*abstract*/ class PlaceController extends Controller { /** * Initializes this place controller with a reference to the context @@ -121,8 +123,8 @@ public /*abstract*/ class PlaceController /*extends Controller*/ _plobj = plobj; if (_view != null ) { - _view.addEventListener( - ControllerEvent.TYPE, handleControllerEvent); + // set it as our controlled panel + setControlledPanel(_view); // let the UI hierarchy know that we've got our place PlaceViewUtil.dispatchWillEnterPlace(_view, plobj); @@ -175,10 +177,10 @@ public /*abstract*/ class PlaceController /*extends Controller*/ // } // }); + setControlledPanel(null); + // let the UI hierarchy know that we're outta here if (_view != null ) { - _view.removeEventListener( - ControllerEvent.TYPE, handleControllerEvent); PlaceViewUtil.dispatchDidLeavePlace(_view, plobj); _ctx.clearPlaceView(_view); _view = null; @@ -187,30 +189,6 @@ public /*abstract*/ class PlaceController /*extends Controller*/ _plobj = null; } - /** - * Handle the specified action that was generated somewhere in our - * view. - * - * @return true if the action has been handled, false otherwise. - */ - public function handleAction (cmd :String, arg :Object) :Boolean - { - Log.getLog(this).warning("Unhandled controller command [cmd=" + cmd + - ", arg=" + arg + "]."); - return false; // by default, no action is handled - } - - /** - * A callback where we listen to ControllerEvents and unwrap - * them for easy handling. - */ - private function handleControllerEvent (event :ControllerEvent) :void - { - if (handleAction(event.command, event.arg)) { - event.stopImmediatePropagation(); - } - } - /** * Handles basic place controller action events. Derived classes * should be sure to call super.handleAction for events diff --git a/src/as/com/threerings/mx/controls/CommandButton.as b/src/as/com/threerings/mx/controls/CommandButton.as new file mode 100644 index 000000000..d0315032f --- /dev/null +++ b/src/as/com/threerings/mx/controls/CommandButton.as @@ -0,0 +1,44 @@ +package com.threerings.mx.controls { + +import flash.events.MouseEvent; + +import mx.controls.Button; + +import com.threerings.events.ControllerEvent; + +/** + * A command button simply dispatches a Controller command (with an optional + * argument) when it is clicked. + */ +public class CommandButton extends Button +{ + /** + * Create a command button. + */ + public function CommandButton (cmd :String = null, arg :Object = null) + { + setCommand(cmd, arg); + } + + /** + * Set the command and argument to be issued when this button is pressed. + */ + public function setCommand (cmd :String, arg :Object = null) :void + { + _cmd = cmd; + _arg = arg; + } + + override protected function clickHandler (event :MouseEvent) :void + { + dispatchEvent(new ControllerEvent(_cmd, _arg)); + event.stopImmediatePropagation(); + } + + /** The command to submit when clicked. */ + protected var _cmd :String; + + /** The argument that accompanies our command. */ + protected var _arg :Object; +} +} diff --git a/src/as/com/threerings/util/Controller.as b/src/as/com/threerings/util/Controller.as new file mode 100644 index 000000000..e1222c59d --- /dev/null +++ b/src/as/com/threerings/util/Controller.as @@ -0,0 +1,58 @@ +package com.threerings.util { + +import flash.events.IEventDispatcher; + +import com.threerings.events.ControllerEvent; + +public class Controller +{ + /** + * Set the panel being controlled. + */ + protected function setControlledPanel (panel :IEventDispatcher) :void + { + if (_panel != null) { + _panel.removeEventListener( + ControllerEvent.TYPE, handleControllerEvent); + } + _panel = panel; + if (_panel != null) { + _panel.addEventListener( + ControllerEvent.TYPE, handleControllerEvent); + } + } + + /** + * Handle an action that was generated by our panel or some child. + * + * @return true if the specified action was handled, false otherwise. + * + * When creating your own controller, override this function and return + * true for any command handled, and call super for any unknown commands. + */ + public function handleAction (cmd :String, arg :Object) :Boolean + { + // TODO: This warning should really be inside the ControllerEvent + // somewhere, and only generated if the event never gets cancelled + Log.getLog(this).warning("Unhandled controller command " + + "[cmd=" + cmd + ", arg=" + arg + "]."); + return false; // not handled + } + + /** + * Private function to handle the controller event and call + * handleAction. + */ + private function handleControllerEvent (event :ControllerEvent) :void + { + if (handleAction(event.command, event.arg)) { + // if we handle the event, stop it from moving outward to another + // controller + event.stopImmediatePropagation(); + } + } + + /** The panel currently being controlled. */ + private var _panel :IEventDispatcher; +} +}