I have a hierarchical tree implemented using ListBox. I implemented item reordering method by holding an item and dragging it around.
To do this I intercept item's Hold, ManipulationDelta and ManipulationCompleted events. Because Listbox's ScrollViewer is in ManipulationMode = ManipulationMode.System by default, I need to set it to ManipulationMode.Control to disable it temporarily to be able to drag my item around.
If I won't do that, scrollviewer intercepts my ManipulationDelta events so when user tries to drag the item, he scrolls the scrollviewer instead and my item stays in fixed position.
Normally, after user drops the item i want to set it back to ManipulationMode.System (if I don't the tree structure scrolling remains laggy because item's template is somewhat heavy/complex).
private void ElementHold(object sender, GestureEventArgs e) {
....
_scrollViewer.HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled;
_scrollViewer.VerticalScrollBarVisibility = ScrollBarVisibility.Disabled;
// works ok
_scrollViewer.SetValue(ScrollViewer.ManipulationModeProperty, ManipulationMode.Control);
}
private void ElementManipulationCompleted(object sender, ManipulationCompletedEventArgs e) {
_scrollViewer.HorizontalScrollBarVisibility = ScrollBarVisibility.Auto;
_scrollViewer.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
// ▼ this doesn't seem to work.
// ▼ In the debugger ManipulationMode has correct value but scrolling
// ▼ still lags which means that scrollviewer stays in Control mode.
_scrollViewer.SetValue(ScrollViewer.ManipulationModeProperty, ManipulationMode.System);
}
I've read that I can't switch ManipulationMode after ApplyTemplate() was called, but I also read that it should be possible if done by setting via dependency property instead of standard property.
What am I doing wrong here? Is it impossible to go back to System mode? If I go to other page and back to this one scrollViewer still lags. Only app restart works.
Just set UseOptimizedManipulationRouting="False" to dragging item control to prevent Routing event to scrollviewer
Related
I'm using GWT PopupPanel to display a popup above a button when user clicks it.
I am setting popup's position and showing it like so:
panel.setPopupPosition(leftPos, topPos);
panel.show();
However, when I inspect the popup's top value after it shows, I see that it is positions slightly lower than what I assigned it.
The issue may be that setPopupPosition changes the values that are passed in:
// Account for the difference between absolute position and the
// body's positioning context.
left -= Document.get().getBodyOffsetLeft();
top -= Document.get().getBodyOffsetTop();
How can I make sure the GWT PopupPanel's position is exactly the values I gave it? setPopupPosition() seems to really be the only way to set the position, but it does some manipulation (which is unnecessary for my use case) to the positions I pass in.
You can use direct access to popup's DOM element to adjust PopupPanel position. But it should be done after calling show() and before making popup visible. Otherwise, you'll may see some "jump" effects.
Example:
PopupPanel popupPanel = new PopupPanel();
...
// this callback will be called after PopupPanel.show(), but before it is shown
popupPanel.setPopupPositionAndShow(new PositionCallback() {
#Override
public void setPosition(int offsetWidth, int offsetHeight) {
Style style = popupPanel.getElement().getStyle();
style.setLeft(100, Unit.PX);
style.setTop(100, Unit.PX);
}
});
I have a spark List control that shows a side-list on ListEvent.ITEM_ROLL_OVER event. Basicaly it shows the contents of the item you are hovering. I would be also using ListEvent.ITEM_ROLL_OUT to hide it again but I want the user to be able to click on it (the sidelist) too.
So, i use MouseEvent.ROLL_OUT and check the event.relatedObject's id to see where the cursor went. I added an invisible Rectangle overlaying the sidelist that's a bit larger so it gains focus 1st. But it doesn't.
Googling around, I think that the Spark Rectangle cant gain focus as it doesn't implement InteractiveObject. What should I use?
My logic:
protected function listOUT(event:MouseEvent):void
{
var obj:Object = event.relatedObject;
if (obj.id != "focusRect")
{
sidelist.visible = false;
}
}
My struggle is to keep the side-list visible if the user moves the cursor from the main list to the sidelist.
Any other suggestions outside my approach are also welcome.
Update
(image link)
Red are the invisible Buttons
On roll_over select the item in the mainlist, display the sidelist
based on the selecteditem in the mainlist.
Hide the sidelist when there is no item selected in the main list.
Deselect items inthe mainlist if the sidelist loses focus.
Furthermore mx.core.UIComponent is the lightest component that dispatches focus events.
I need to show a popup layer on a scene, creating a semi-transparent background layer that will also prevent touch events propagation. I am using the latest cocos2d-x v. 3.0-alpha-0.
What I want to achieve is a popup layer that fully handles touches (eg. buttons, menu items, scroll views, etc.), laying on a background layer (for design purposes), that covers the current scene. All items in the scene should not respond to touches any more.
Is this achievable using the new EventDispatcher class? I've been able to disable all touches to the main scene, but all instances of MenuItem that live in the scene are still touchable and active.
How can I achieve this? And, also, how can I create a touch listener that prevents all touches to the main scene but not to the popup?
You can disable menu items by setting setDisable property of menuitems to false.
Example
_menuItem->setEnabled(false);
For Layers use setTouchEnabled property
_backGroungLayer->setTouchEnabled(false);
Make sure that popup layer is not child of layer you want to disable.
To disable all items in menus do this
Suppose _menu contain various menuitems.
CCARRAY_FOREACH(_menu->getChildren(), item)
{
item.isEnabled=NO;
}
if you want to disable selected items just give them tags.There is no need to make any list.
I had the same problem and solved it with mm. It was dirty, but it worked:
Create a button using ccui.button.
Set the button size to your screen size.
Add this button as a background to your popup layer.
This will prevent any thing behind it being clicked.
By default, all CCMenu's have a set priority (kCCMenuHandlerPriority = -128) in cocos2d 2.1. So in a class (usually a CCNode descendant) that wants to swallow everything and preempt anything i do like in this dialog sequencer example below :
- (void)onEnter {
backdrop_.visible = self.isBackDropShown;
MPLOG(#"Adding self as a swallower touch delegate, above the rest of the planet.");
[[[CCDirector sharedDirector] touchDispatcher] addTargetedDelegate:self priority:_dialogTouchPriority swallowsTouches:YES];
for (CCMenu *mn in _menus) {
mn.touchPriotity = _dialogTouchPriority -1 ;
}
[super onEnter];
}
where _dialogTouchPriority is kCCMenuHandlerPriority-1 by default. It will be served before everything 'below'. It is a bad hack (cocos2d internals could be changed and break this), i know , but bullet proof. Use carefully, make certain you only ever have one of these in your scene.
I'm currently design an application that when a button is pressed it expands to display further information. A major issue I am faced with is that if the button is pressed whilst contracting so that it expands again, the co-ordinates are saved from when it was clicked, meaning it will never return to its original state.
I either need a way of disabling the mouse click on the button whilst the TweenMax is doing its job in contracting the button, or by extracting the coordinates from an array.
I've managed to get the array of coordinates from my menu class into the main class, but can't work out the best way in order to stop the problem from occurring.
--
expand = false;
(run menu function)
item.addEventListener(MouseEvent.CLICK, boxExCo);
private function boxExCo(e:MouseEvent):void
{
if (!expand)
{
selectedBox = e.target as Box;
boxX = selectedBox.x;
boxY = selectedBox.y;
expand = true;
TweenMax.to.... (expand)
}
else
{
expand = false;
TweenMax.to... (contract to coordinates)
}
}
You need to use item.removeEventListener(MouseEvent.CLICK, boxExCo); when you no longer want the event to be able to fire, and then just add it back on using
item.addEventListener(MouseEvent.CLICK, boxExCo); when you want the event to be able to fire again.
Once you start your tween max, remove the event.
Once it is finished, add the event back on.
I have a JFrame with a JTextArea: by clicking on this TextArea a JPopupMenu appears with two items "Clear" and "Save".
private void jTextArea1MousePressed(java.awt.event.MouseEvent evt) {
jPopupMenu1.setVisible(true);
}
My question is: this popup always appears at position (0,0) but I would like to show pop where mouse is clicked, inside or relative to the TextArea.
I have try setLocation(x,y) but this methods always prompt in a fixed location and it is not what I am seeking for, and it is not available a method such as setLocationRelativeTo(JTextArea());
don't use a mouseListener as trigger to show the popup, instead use the JComponent componentPopupMenu property, like
myTextArea.setComponentPopupMenu(myPopupMenu)
Doing so will show the popup on right click at the mouse position by default. It has the additional benefit of covering keyboard triggered (LAF dependend, F10 on win) popup requests as well.
If for some reason you really need to manually show the popup, the method you're looking for is
myPopup.show(myTextArea, x, y)