i am developing a Gtk# based application which uses a custom widget derived from Gtk.Bin. For some reason not known to me, it does not receive mouse movement events. The code below is never called:
[GLib.ConnectBefore]
protected override bool OnMotionNotifyEvent (Gdk.EventMotion evnt)
{
Console.Out.WriteLine( "Mouse move!" );
return base.OnMotionNotifyEvent (evnt);
}
I have also extended the Event mask of the widget to receive all events (in the constructor):
AddEvents(( int ) Gdk.EventMask.AllEventsMask );
Any ideas?
Gtk.Bin is a windowless container so it does not receive mouse events by default.
You can create a Gdk.Window manually in your subclass in order to receive mouse events, or the easier path is to subclass Gtk.EventBox, which is a Gtk.Bin subclass designed for this purpose by internally creating its own Gdk window.
Related
I'm attempting to dynamically add Manipulation Events to a ManipulationHandler that is being added to child objects of a parent. The parent object will be what the user is inspecting, but the user will be able to grab parts off of the parent and inspect them more closely. (i.e. you can look at an engine (parent object), but if you want to inspect the pistons (child objects) you can grab them and look at them)
Instead of having to go into every child object and manually add it in Unity I'd like to be able to add the parent object and just procedurally add the ManipulationHandler and ManipulationEvents on start or awake.
So far I have the following code for adding the ManipulationHandler script, but to add the ManipulationEvent I'm not sure how to set up the pointers so I can use the script and function I want from the source:
gameObject.AddComponent<ManipulationHandler>();
ManipulationHandler handler = gameObject.GetComponent<ManipulationHandler>();
ManipulationEvent newevent = new ManipulationEvent();
ManipulationEventData eventdata = new ManipulationEventData();
eventdata.ManipulationSource = gameObject;
The program works when I grab the objects, but I'd like to add manipulation events when I grab them so I can display additional data.
I see there's a getter and setter for Pointer in ManipulationEventData, but I'm not sure how to instantiate IMixedRealityPointer and how to get it to work. I'm also not sure if that's the object I actually need to accomplish what I'd like to accomplish.
I apologize in advance if I've missed something obvious. I'm new to MRTK.
Thanks!
The ManipulationHandler has four callback events among them OnManipulationStarted and OnManipulationEnded you can simply add listeners to. (see UnityEvent.AddListener)
Unless I understood your question wrong you don't have to instantiate any IMixedRealityPointer. You don't create the event data yourself but rather the ManipulationHandler feeds these events with the current event data including the interacting pointer information. The ManipulationHandler uses OnPointerDown and OnPointerDragged and OnPointerUp via the IMixedRealityPointerHandler interface in order to manage the interacting pointers and invokes the according events where needed.
Instead of using AddComponent followed by GetComponent directly store and use the return value of AddComponent which will be the reference of the newly added Component. MRTK also has an extension method
T EnsureComponent<T>(this Component component) where T : Component
so that you can simply use e.g.
var handler = this.EnsureComponent<ManipulationHandler>();
which internally first checks whether the component already exists, and if not it adds it.
Note that in order to enable near interactions you will also need a NearInteractionGrabbable so you should add this one too.
You also will have to make sure that your objects have some sort of Collider attached to the same GameObject as the NearInteractionGrabbable.
...
gameObject.transform.EnsureComponnet<NearInteractionGrabbable>();
var handler = gameObject.transform.EnsureComponnet<ManipulationHandler>();
handler.OnManipulationStarted.AddListener(HandleOnManipulationStarted);
handler.OnManipulationEnded.AddListener(HandleOnManipulationEnded);
...
/// <summary>
/// If you need it later you need to store the pointer since unfortunately in
/// OnManipulationEnded the <see cref="ManipulationEventData.Pointer"/> is null
/// (no idea why they do it this way :D )
/// </summary>
private IMixedRealityPointer _pointer;
private void HandleOnManipulationStarted(ManipulationEventData eventData)
{
_pointer = eventData.Pointer;
// whatever shall happen when manipulation started
}
private void HandleOnManipulationEnded(ManipulationEventData eventData)
{
// whatever shall happen when manipulation ended
}
Note: I am not sure if this thing you are trying to achieve is possible with this architecture ... it is very possible that nesting various ManipulationHanlder leads to strange behavior here and there. Especially very small parts will be almost impossible to grab ...
I want to create a helper for TCustomQuery, TQuery, TTable and so on... With a LastRecordPosition property, which I will get with OnBeforeScroll setting that property from RecNo.
How do I create that trigger in that helper class to catch the event without interfere in an user's OnBeforePost if he/she needs one?
I use FireDAC or ZeosLib for older versions.
To intercept the OnBeforeScroll event without interfering with the user's OnBeforeScroll event handler, you need to override each component's virtual DoBeforeScroll() method. However, a class helper cannot override any virtual methods of the class it is helping. So, you will have to instead either:
write new classes that are derived from each base component class you want to intercept (type TMyCustomQuery = class(TCustomQuery), etc), and then the user must use those new component classes in their code instead of the originals.
(XE and later only) use Delphi's TVirtualMethodInterceptor class to hook the virtual DoBeforeScroll() method of specific component object instances (not the classes themselves) without having to write any derived classes.
The alternative is to write a class, possibly a Generic class, that the user has to instantiate for each component object instance, and the class can then subclass its associated component (possibly with RTTI) to capture and replace the user's OnBeforeScroll event handler with its own, and then its event handler can call the user's event handler when needed.
I've added a KeyUpHandler to a Button object as follows:
button.addKeyUpHandler(new KeyUpHandler() {
#Override
public void onKeyUp(final KeyUpEvent event1) {
if (event.isDownArrow()) {
counter++;
}
}
});
However, when I debug with SuperDev mode step by step, there are two calls to the onKeyUp where the initial calls has always counter's initial value (0 in this case) and second call has the latest -maintained- value of counter. The method where I added the logic of onKeyUp is also marked as synchronized. I also tried to call removeHandler() method of HandlerRegistration right after onKeyUp is called. The result was that the mentioned two calls happened after first key up event, but when I did another key up event only one more call happened and further key up events area didn't happen. I assume this is sth related with superdev mode or there is some internal overhead after the compilation. What is the correct way of adding any event handlers at GWT? Do we need to always take care of each handler by calling removeHandler() method of HandlerRegistration?
Re: your comment about multiple calls for click/mouseup/keyup
The browser "helps" for the click handler by firing it whenever any event would effectively click, either mousedown, then mouseup but no move, or various touch or keyboard events. Consider calling preventDefault() on an event you have already handled and you don't want the browser to further look at - for example, if you call this on mouseup and keyup, then those particular actions should never result in click events going off.
Is there an overview about all handlers and their corresponding containers in GWT? Whenever I try to add a handler to a container, I have to check, whether the handler fires an event or not (the JavaDoc does not provide useful information about this). For example a ResizeHandler:
SplitLayoutPanel splitLayoutPanel = new SplitLayoutPanel() {
#Override
public void onResize() {
super.onResize();
System.out.println("onResize");
}
};
splitLayoutPanel.addHandler(new ResizeHandler() {
#Override
public void onResize(ResizeEvent event) {
System.out.println("resize");
}
}, ResizeEvent.getType());
Overwriting the onResize()-method (1. example) gives an information, if the splitter changes, but if I add a ResizeHandler (2. example), I do not get any call of the onResize-method. I don't understand why and don't find the documentation why the handler is not allowed in this container.
I search for an overview of all available handlers, together with their possible containers and event, when they will be fired.
Usually there will be a more specific addHandler method. For example, Button has addClickHandler(ClickHandler). The interface that defines that method is HasClickHandlers, so you can look out for that, for example.
If the event doesn't have it's own addXyzHandler method, it probably won't be supported very well. In that case, it's usually pretty easy to subclass the widget and add support for that handler yourself.
If you add a handler using addHandler() on a Widget, you have to ensure the underlying DOM element could catch matching event. If yes, you also have to tell your Widget to sink this event using
void com.google.gwt.user.client.ui.Widget.sinkEvents(int eventBitsToAdd)
where eventBitsToAdd is a constant from com.google.gwt.user.client.Event.
AFAIK ONRESIZE event is not yet supported natively. So as I said yesterday, you have to implement your mouse handlers and gesture, or override a slider ;-)
i learned how to implement my own SuggestionOracle("AuSuggestOracle") and own
Suggestions("AuMultiWordSuggestion"). In my case the suggestion object
is constructed with a DTO. On a selection event i need this dto (or
some fields of it) to react appropriate.
I implemented a widget containing 3 suggest boxes with this special
oracle and some logic between them. Now i want to apply MVP pattern -
split this widget in presenter and view.
At the moment the presenters display interface look like that:
public interface Display {
HasSelectionHandlers<Suggestion> getFedLand();
HasSelectionHandlers<Suggestion> getCounty();
HasSelectionHandlers<Suggestion> getCommunity();
AuSuggestOracle getFedLandOracle();
AuSuggestOracle getCountyOracle();
AuSuggestOracle getCommunityOracle();
void clearCounty();
void clearCommunity();
void activateForm();
Widget asWidget();
}
the problem is the implicit knowledge about my model in methods
returning "AuSuggestOracle". so my question is how to get the view/
interface "humble". in my case the displayed suggestion-strings are
ambiguous and i need at least the "id" of a selected item to know what
DTObject is selected.
The way I got around this is by leaving out the getters for the Oracle since once my presenter sets it my view doesn't need any information about it. So, my interface looked like this:
public interface Display {
...
void setSuggestionOracle(SuggestOracle oracle);
HasSelectionHandlers<SuggestOracle.Suggestion> getSelectionListener();
}
The problem I encountered was being able to add the suggestion to the SuggestBox after it was instantiated. To get around this, I initialized with a blank SuggestBox and then removed it from the view, updated in, and inserted it back into position.
After that, you can write your handler (in the presenter) to check if the suggestion is an instance of your custom suggestion and your presenter can handle the selection and push the relevant information back down to your view.
By doing this, all your view knows is that it will be taking generic suggestions for something, and that at some later time it will be updating with information (which will be as a result of the suggestion, but the view is to 'humble' to know that).