I've heard of events and SO answers "bubbling up", but what has all that got to do with bubbles?
Event bubbling is the idea of information moving up through a deep structure, when proper design dictates that normally information should only flow downward.
In very basic terms, think of a single object. Properly designed, this object should only know about its own child objects. It should have no direct interaction with its parent. Its children and parent objects, in turn, should follow the same rules. In effect, this means that information can only flow downward - a parent can invoke a method, send data into or extract data from its child, but the child cannot forcibly do the same to its parent.
Think of what happens when you blow an air bubble underwater - you don't have to push the air towards the surface - you simply release it and it moves on its own. The same concept applies to event bubbling - deeper controls simply "release" their information - usually via an event - and it "floats" up the chain without directly invoking anything.
With regard to a website like Stackoverflow (or practically any kind of site), the concept of bubbling is the same. Obviously each individual post ought not directly put itself on the home page, but when a single post has been updated, that event is released from the deepest point in the hierarchy - a single post - and floats up to eventually the top level, where it is dealt with (choosing whether or not to display on the home page).
If you are asking about the term, I guess it is an analogy to an event 'bubbling' up to the top, like an air bubble does in liquid.
If you are asking what event bubbling is it is an event that is caught by one object that will refire it to any other objects that are listening to it.
To quote a good article here
... a technique called event bubbling
that allows a child control to
propagate events up its containment
hierarchy. Event bubbling enables
events to be raised from a more
convenient location in the controls
hierarchy and allows event handlers to
be attached to the original control as
well as to the control that exposes
the bubbled event.
Related
I'm working on a custom cross platform UI library that needs a synchronous "ShowPopup" method that shows a popup, runs an event loop until it's finished and automatically cancels when clicking outside the popup or pressing escape. Keyboard, mouse and scroll wheel events need to be dispatched to the popup but other events (paint, draw, timers etc...) need to be dispatched to their regular targets while the loop runs.
Edit: for clarification, by popup, I mean this kind of menu style popup window, not an alert/dialog etc...
On Windows I've implemented this fairly simply by calling GetMessage/DispatchMessage and filtering and dispatching messages as appropriate. Works fine.
I've much less experience with Cocoa/OS X however and finding the whole event loop/dispatch paradigm a bit confusing. I've seen the following article which explains how to implement a mouse tracking loop which is very similar to what I need:
http://stpeterandpaul.ca/tiger/documentation/Cocoa/Conceptual/EventOverview/HandlingMouseEvents/chapter_5_section_4.html
but... there's some things about this that concern me.
The linked article states: "the application’s main thread is unable to process any other requests during an event-tracking loop and timers might not fire". Might not? Why not, when not, how to make sure they do?
The docs for nextEventMatchingMask:untilDate:inMode:dequeue: states "events that do not match one of the specified event types are left in the queue.". That seems a little odd. Does this mean that if an event loop only asks for mouse events then any pressed keys will be processed once the loop finishes? That'd be weird.
Is it possible to peek at a message in the event queue without removing it. eg: the Windows version of my library uses this to close the popup when it's clicked outside, but leaves the click event in the queue so that clicking outside the popup on a another button doesn't require a second click.
I've read and re-read about run loop modes but still don't really get it. A good explanation of what these are for would be great.
Are there any other good examples of implementing an event loop for a popup. Even better would be pseudo-code for what the built in NSApplication run loop does.
Another way of putting all this... what's the Cocoa equivalent of Windows' PeekMessage(..., PM_REMOVE), PeekMessage(..., PM_NOREMOVE) and DispatchMessage().
Any help greatly appreciated.
What exactly is a "popup" as you're using the term? That term means different things in different GUI APIs. Is it just a modal dialog window?
Update for edits to question:
It seems you just want to implement a custom menu. Apple provides a sample project, CustomMenus, which illustrates that technique. It's a companion to one of the WWDC 2010 session videos, Session 145, "Key Event Handling in Cocoa Applications".
Depending on exactly what you need to achieve, you might want to use an NSAlert. Alternatively, you can use a custom window and just run it modally using the -runModalForWindow: method of NSApplication.
To meet your requirement of ending the modal session when the user clicks outside of the window, you could use a local event monitor. There's even an example of just such functionality in the (modern, current) Cocoa Event Handling Guide: Monitoring Events.
All of that said, here are (hopefully no longer relevant) answers to your specific questions:
The linked article states: "the application’s main thread is unable to process any other requests during an event-tracking loop and
timers might not fire". Might not? Why not, when not, how to make
sure they do?
Because timers are scheduled in a particular run loop mode or set of modes. See the answer to question 4, below. You would typically use the event-tracking mode when running an event-tracking loop, so timers which are not scheduled in that mode will not run.
You could use the default mode for your event-tracking loop, but it really isn't a good idea. It might cause unexpected re-entrancy.
Assuming your pop-up is similar to a modal window, you should probably use NSModalPanelRunLoopMode.
The docs for nextEventMatchingMask:untilDate:inMode:dequeue:
states "events that do not match one of the specified event types are
left in the queue.". That seems a little odd. Does this mean that if
an event loop only asks for mouse events then any pressed keys will be
processed once the loop finishes? That'd be weird.
Yes, that's what it means. It's up to you to prevent that weird outcome. If you were to read a version of the Cocoa Event Handling Guide from this decade, you'd find there's a section on how to deal with this. ;-P
Is it possible to peek at a message in the event queue without removing it. eg: the Windows version of my library uses this to close
the popup when it's clicked outside, but leaves the click event in the
queue so that clicking outside the popup on a another button doesn't
require a second click.
Yes. Did you notice the "dequeue:" parameter of nextEventMatchingMask:untilDate:inMode:dequeue:? If you pass NO for that, then the event is left in the queue.
I've read and re-read about run loop modes but still don't really get it. A good explanation of what these are for would be great.
It's hard to know what to tell you without knowing what you're confused about and how the Apple guide failed you.
Are you familiar with handling multiple asynchronous communication channels using a loop around select(), poll(), epoll(), or kevent()? It's kind of like that, but a bit more automated. Not only do you build a data structure which lists the input sources you want to monitor and what specific events on those input sources you're interested in, but each input source also has a callback associated with it. Running the run loop is like calling one of the above functions to wait for input but also, when input arrives, calling the callback associated with the source to handle that input. You can run a single turn of that loop, run it until a specific time, or even run it indefinitely.
With run loops, the input sources can be organized into sets. The sets are called "modes" and identified by name (i.e. a string). When you run a run loop, you specify which set of input sources it should monitor by specifying which mode it should run in. The other input sources are still known to the run loop, but just ignored temporarily.
The -nextEventMatchingMask:untilDate:inMode:dequeue: method is, more or less, running the thread's run loop internally. In addition to whatever input sources were already present in the run loop, it temporarily adds an input source to monitor events from the windowing system, including mouse and key events.
Are there any other good examples of implementing an event loop for a popup. Even better would be pseudo-code for what the built in
NSApplication run loop does.
There's old Apple sample code, which is actually their implementation of GLUT. It provides a subclass of NSApplication and overrides the -run method. When you strip away some stuff that's only relevant for application start-up or GLUT, it's pretty simple. It's just a loop around -nextEventMatchingMask:... and -sendEvent:.
Perhaps hoping in a miracle, but let's try :-)
MyControl derives from Control. Its ControlTemplate contains
<ContentPresenter ContentTemplate="{TemplateBinding EditorTemplate}"/>
(Other details are omitted.)
Derived controls supply suitable EditorTemplate. For example MyTextControl specifies template consisting of a TextBox. (With proper bindings, of course.)
I won't describe what works (most scenarios), but what does not:
A collapsed MyTextControl instance is created. Later on this control is made visible. Here is what happens:
MyTextControl instance created, set to Collapsed
MyTextControl.Loaded event: At this moment the visual tree contains MyTextControl with no children.
In the Loaded handler I call ApplyTemplate(). In turn the visual tree is modified to MyTextControl -> ContentPresenter. That's all, no more children.
Stil in Loaded handler, I assign Loaded handler to the ContentPresenter.
Sometimes later the control is made visible. Its visual tree gets populated by TextBox internals: Border -> ContentControl -> ContentPresenter -> internal TextBoxView. In other words the control just works.
The problem is that the ContentPresenter Loaded handler was not called, i.e. I am not able to identify the moment when the control is ready.
I tried an alternative solution, i.e. instead of forcing ApplyTemplate() I simply waited in MyControl.OnApplyTemplate(). The sequence:
MyTextControl instance created, set to Collapsed
In the Loaded handler the visual tree contains MyTextControl with no children.
The control is made visible.
In OnApplyTemplate() the visual tree is MyTextControl->ContentPresenter.
Stil in OnApplyTemplate(), I assign Loaded handler to the ContentPresenter.
The rest is as before. The visual tree is populated by TextBox internals (the control works), but the above handler gets not called.
Does anybody know a way how to identify the moment when the control is fully loaded?
Note that I did the above with several other MyControl-derived controls. For each of them one of the above scenarios worked (sometimes one, sometimes another), but the TextBox-based control is the first one where I am not able to identify moment of loading.
Also note that this problem does not happen when the control is visible for all the time.
Ok, I'll answer myself. My current conclusion after 1 day and dozens of tests is that Loaded event is for birds. It happens on various stages of the control life cycle and in case of composite controls there is no warranty that the control is fully functional. In some cases it might be not fired at all.
Forcing template building by calling ApplyTemplate() is no solution either as in some cases it may result in building partial control tree.
OnApplyTemplate suffers similar problems - it might be called when only partial control tree is built.
After acknowledging the above statements I decided to give a try to LayoutUpdated event. I set up the handler in OnApplyTemplate() (I tried to use latest possible moment) and investigated the control tree. As a first approximation it seems to be sufficient to check if the ContentPresenter has children. If so, we'll say that the control is loaded and unregister LayoutUpdated handler. A more sofisticated test could be used, but the trivial one I just described is working for wide range of controls.
Originally I was afraid that the LayoutUpdated solution will be inefficient, but it looks like (using the described organization) the first handler call is exactly the place when the control is "loaded".
It is said in the docs, that EventDispatcher's dispatchEvent "...dispatches an event into the event flow". The phrase is nice-looking and doesn't really explain anything.
Say, we have two listeners waiting for an event "A" on object "a", so what behaviour do we have to expect on calling:
a.dispatchEvent("A")?
Would both listeners be called immediately, before return from distpatchEvent? Or they will be queued in some internal flash player queue and will be processed by entering the next frame? Can we rely on some defined behaviour of flash player here or the behaviour is undefined? How one should read "dispatches an event to event flow"? The question is important since in practice it affects the control flow of the code.
It all depends on your display list hierarchy.
Flash's event structure is based on its internal event model.
The Stage will be the first object
notified, and then the event will
trickle down the display list until
it reaches its target. This phase is
called the capture phase. To enable it, set useCapture to
true on an event listener. Do note
that it's pointless to do so unless
the object listening is a parent of
the object targeting the event. This
is called event intercepting.
The next phase is the target
phase. This is the behavior most
commonly known with events. The
targeted display object (the one the
has a listener for the event) will
receive the event and carry out the
code in the listener.
The final phase is called the
bubbling phase. This is when the event bubbles up the display list
after the event has been received. Event bubbling is very important for
dispatching custom events, as you'll
need to know how to listen for
events dispatched by an object's
children.
When dispatching an event, I generally use this syntax (Event.CHANGE is just a common example):
Object.dispatchEvent(new Event("CHANGE", true, false));
The Object is the object you're dispatching from. The first parameter is the event you're dispatching. The second is the bubbles parameter. The final is the cancelable property. Event.cancelable is used to prevent the default action of an event (IE: a mouse click) via Event.preventDefault().
Reference:
Chapter 21 of Colin Moock's
Essential Actionscript 3.0
EventDispatcher.dispatchEvent()
Event.cancelable
Just use Signals instead :P
https://github.com/robertpenner/as3-signals/wiki
No but really, they're very easy to use and understand, a great addition to the AS3 toolbox.
You can also learn a lot about how native AS3 events work by reading Rob Penner's critiques (scroll down to bottom of wiki page)
New to GWT here...
I'm using the UIBinder approach to layout an app, somewhat in the style of the GWT Mail sample. The app starts with a DockLayoutPanel added to RootLayoutPanel within the onModuleLoad() method. The DockLayoutPanel has a static North and a static South, using a custom center widget defined like:
public class BigLayoutWidget extends ResizeComposite {
...
}
This custom widget is laid out using BigLayoutWidget.ui.xml, which in turn consists of a TabLayoutPanel (3 tabs), the first of which contains a SplitLayoutPanel divided into WEST (Shortcuts.ui.xml) and CENTER (Workpanel.ui.xml). Shortcuts, in turn, consists of a StackLayoutPanel with 3 stacks, each defined in its own ui.xml file.
I want click events within one of Shortcuts' individual stacks to change the contents of Workpanel, but so far I've only been able to manipulate widgets within the same class. Using the simplest case, I can't get a button click w/in Shortcuts to clear the contents of Workpanel or make WorkPanel non-visible.
A few questions...
Is ResizeComposite the right type of class to extend for this? I'm following the approach from the Mail example for TopPanel, MailList, etc, so maybe not?
How can I make these clicks manipulate the contents of panels in which they do NOT reside?
Are listeners no longer recommended for handling events? I thought I saw somewhere during compilation that ClickHandlers are used these days, and the click listener "subscription" approach is being deprecated (I'm mostly using #UiHandler annotations)
Is there an easy way to get a handle to specific elements in my app/page? (Applying the "ID" field in the UI.XML file generates a deprecation warning). I'm looking for something like a document.getElementById() that get me a handle to specific elements. If that exists, how do I set the handle/ID on the element, and how can I then call that element by name/id?
Note that I have the layout itself pretty well nailed; it's the interaction from one ui.xml modularized panel to the next that I can't quite get.
Thanks in advance.
If you don't have a use for resizing events than just use Composite
What you want is what the GWT devs called message bus (implemented as HandlerManager). You can get a nice explanation in the widely discussed (for example, on the GWT Google Group, just search for 'mvp') presentation by Ray Ryan from Google I/O 2009 which can be found here. Basically, you "broadcast" an event on that message bus and then a Widget listening for that event gets the message and does its stuff.
Yep, *Handlers are the current way of handling events - the usage is basically the same so migration shouldn't be a problem (docs). They changed it so that they could introduce custom fields in the future, without breaking existing code.
If you've set an id for any DOM element (for Widgets I use someWidget.getElement().setId(id), usually in combination with DOM.createUniqueId()) you can get it via GWT.get(String id). You'll get then a RootPanel which you'll have to cast to the right Widget class - as you can see it can get a little 'hackish' (what if you change the type of the Widget by that id? Exceptions, or worse), so I'd recommend sticking with MVP (see the first point) and communicating via the message bus. Remember however, that sometimes it's also good to aggregate - not everything has to be handled via the message bus :)
Bottom line is I'd recommend embracing MVP (and History) as soon as possible - it makes GWT development much easier and less messy :) (I know from experience, that with time the code starts to look like a nightmare, if you don't divide it into presentation, view, etc.)
Say you're building a Tetris game. As any proper programmer, you have your view logic on one side, and your business logic on the other side; probably a full-on MVC going on.
When the model sends its update(), the view redraws itself, as expected.
But then... if you wanted to add, say, an animation to vanish a line, how would you implement that in the view?
Make any assumptions you want---excepting that "Everything is properly encapsulated".
Personally, I would separate draw the screen as often as possible, even if there was no update of the block position. So I would have a loop somewhere with an "update" and a "render" part. Update plays the ball to the logic which does or does not any update of positions and/or block removal. Render plays the ball to the graphics part, which draws the blocks where they should be.
Now if there are lines to erase, the logic knows and can mark those lines to be removed. I assume here, that every piece consists of 4 single blocks and any of these blocks is a single object. Now when this block has the "die"-flag set, you may take some render-parts to vanish the block (let's say, 500ms to explode). After this time, the object may be disposed and the block a line above falls down. Why 500ms? Well, you should definitely use time-based movement as this keeps the game speed the same on different computers.
Btw, there are already so called game engines which provide such an update-render-loop. For example XNA, if you go the .NET line. You may also code your own engine but beware, it's not an easy task and it's very time consuming. I did this once and don't expect it to be an engine like the Source Engine ;-)
Most games execute a loop that constantly redraws the view of the game as fast as possible, rather than waiting for a change in the model state and then refreshing the view.
If you like the model view pattern, then it might work well for the view to continue to draw some types of objects after they are removed from the model, fading them out over a few milliseconds.
Another approach would be to combine class MVC with something like differential execution - the 'view' is a model of what is presented, but the drawing code compares the stream of events the 'view' creates with the stream from the previous rendering. So if in one stream there's a line, and the next there isn't, the drawing code can animate the difference. This allows the drawing to be abstracted away from the view . Frequently the 'view' in MVC is a collection of widgets, rather than being something which draws the display directly, so you end up with nested MVC hierarchies anyway: the application is MVC ( data model, view objects, app controller ), where the view object has a collection of widgets each of which is MVC ( widget state (eg button pressed ), look and feel/toolkit binding, mapping of toolkit events -> widget state ).
I've often wondered this myself.
My own thoughts have been along this line:
1) The view is given the state of the blocks (shape, yada-yada), but with extra "transitional" data:
2) The fact that a line must be removed is encoded in the state, NOT computed in the view.
3) The view knows how to draw transitions now:
No change: state is the same for this particular block
Change from "falling" to "locked": state is "locked in" (by a dropping block)
Change from "locked" to "remove": state is "removed" (by a line completion)
Change from "falling" to "remove": state is "removed", but old state was "falling"
Its interesting to think of a game as an MVC. Thats a perspective I've never taken (for some odd reason), but definitely an intriguing one that makes a lot of sense. Assuming you do implement your Tetris game with an MVC, I think there are two things you might want to take into account in regards to communication between your controller and your view: There is state, and there are events.
Your controller is obviously the central point of interaction for the user. When they issue keyboard commands, your controller will interpret them, and make the appropriate state adjustments. However, sometimes the game will enter a state that coincides with a particular event...such as filling a line with blocks that should now be removed.
Scoregraphic has given you a great foundation. Your view should operate on a fixed cycle to maintain consistent speed across computers. But in addition to updating the screen to render new state, it should also have a queue of events that it can perform animations in response to. In the case of filling lines in Tetris, your controller could issue strongly typed event objects that derive from some kind of base event type into the view event queue, which could then be used by the view to perform the appropriate animated responses.