Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Implement DMGestureRecognizer to start/stop directmanipluation on scrollveiwer#1305

Merged
yiyang-msft merged 9 commits into
developfrom
Gesture
Nov 4, 2016
Merged

Implement DMGestureRecognizer to start/stop directmanipluation on scrollveiwer#1305
yiyang-msft merged 9 commits into
developfrom
Gesture

Conversation

@yiyang-msft

@yiyang-msft yiyang-msft commented Nov 2, 2016

Copy link
Copy Markdown
Contributor

Implement DMGestureRecognizer to start/stop direct manipluation on XAML Scrollveiwer so that gestures attached to subviews within a UIScrollview can be properly triggered. and at the same time, direct manipulation can be triggered if no other gestured are recognized.


This change is Reviewable

…llviewer

so that other gestures attached to subviews inside UIScrollview can be properly triggered
Comment thread Frameworks/UIKit/UIView.mm Outdated
int count = (i == 0) ? gestureCount : dmGestureCount;
for (int k = 0; k < count; k++) {
UIGestureRecognizer* curgesture = recognizers[i];
UIGestureRecognizer* curgesture = ( i==0 ) ? recognizers[k] : dmrecognizers[k];

@DHowett-MSFT DHowett-MSFT Nov 3, 2016

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please format! #Resolved

Comment thread Frameworks/UIKit/UIScrollView.mm Outdated
BOOL _isZooming;
BOOL _isZoomingToRect;

// Dimanip gesture recognizer, used for detecting if Dimanip should start or not

@DHowett-MSFT DHowett-MSFT Nov 3, 2016

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dimanip [](start = 57, length = 7)

nit: Shouldn't these be DManip, not Dimanip? #Resolved

- (void)dealloc {
_zoomView = nil;
_dmGesture = nil;

@DHowett-MSFT DHowett-MSFT Nov 3, 2016

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You do not need to set StrongId instances to nil. #Resolved

Comment thread Frameworks/UIKit/UIScrollView.mm Outdated
return [_UIScrollViewCALayer class];
}

void _setManipulationMode(UIScrollView* self, WUXIManipulationModes mode, BOOL recursive) {

@DHowett-MSFT DHowett-MSFT Nov 3, 2016

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_setManipulationMode [](start = 5, length = 20)

Make this static?

It could also be a method.. #Resolved

while (toLayer.superlayer != nil) {
toLayer = toLayer.superlayer;
}
}

@jaredhms jaredhms Nov 3, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought you weren't including the changes to this file? #Pending

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i can revert the change here and wait for your change to come in. but this is going to leave corresponding issue hanging around a little longer given ux/uxe will probably take longer to arrive develop. On the other hand, for the merge conflicts that is going to occur if I leave this change here, you can just reject mine and accept yours when merging since you already have equivalent? Let me know what you think. I can do either.


In reply to: 86420400 [](ancestors = 86420400)

};

@interface UIPanGestureRecognizer()
-(const std::vector<TouchInfo>&)getTouches;

@jaredhms jaredhms Nov 3, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getTouches [](start = 36, length = 10)

shouldn't this be _getTouches since it's private/internal? #Resolved

Comment thread Frameworks/UIKit/UIScrollView.mm Outdated
static const bool DEBUG_DELEGATE = DEBUG_ALL || false;
static const bool DEBUG_INSETS = DEBUG_ALL || false;
static const bool DEBUG_ZOOM = DEBUG_ALL || false;
static const bool DEBUG_DMGesture = DEBUG_ALL || false;

@jaredhms jaredhms Nov 3, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DEBUG_DMGesture [](start = 18, length = 15)

nit: nobody will know what 'dm' is when they come by later. Can we call this DEBUG_DMANIP_GESTURE? #Resolved

Comment thread Frameworks/UIKit/UIScrollView.mm Outdated
BOOL _isZoomingToRect;

// Dimanip gesture recognizer, used for detecting if Dimanip should start or not
StrongId<_UIDMPanGestureRecognizer> _dmGesture;

@jaredhms jaredhms Nov 3, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_dmGesture [](start = 40, length = 10)

nit: _dManipGesture #Resolved

Comment thread Frameworks/UIKit/UIScrollView.mm Outdated
_scrollViewer.minZoomFactor = 1.0f;
_scrollViewer.zoomMode = WXCZoomModeDisabled;

// setting transparent background

@jaredhms jaredhms Nov 3, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setting transparent background [](start = 7, length = 30)

...'so we can receive touch input' #Resolved

#import "Starboard.h"
#import "UIGestureRecognizerInternal.h"
#import "UIPanGestureRecognizerInternal.h"
#import "_UIDMPanGestureRecognizer.h"

@jaredhms jaredhms Nov 3, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DM [](start = 12, length = 2)

Everywhere you use 'DM', can we use something more descriptive - maybe DManip? #Resolved

}

static void commonInit(UIPanGestureRecognizer* self) {
[self _setDragSlack:7.0f];

@jaredhms jaredhms Nov 3, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[self _setDragSlack:7.0f]; [](start = 1, length = 29)

why 7.0f? can you add a comment for this? #Resolved

Comment thread Frameworks/UIKit/UIView.mm Outdated
if (g_resetAllTrackingGestures) {
g_resetAllTrackingGestures = FALSE;
// Find gesture recognizers in the heirarchy, back-first
// Find gesture recognizers in the heirarchy, back-first

@jaredhms jaredhms Nov 3, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

heirarchy [](start = 43, length = 9)

super-nit: hierarchy #Resolved

Comment thread Frameworks/UIKit/UIView.mm Outdated
const static int MAXIMUM_DMGESTURE_ALLOW = 16;

UIGestureRecognizer* recognizers[MAXIMUM_GESTURE_ALLOW];
UIGestureRecognizer* dmrecognizers[MAXIMUM_DMGESTURE_ALLOW];

@jaredhms jaredhms Nov 3, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dm [](start = 25, length = 2)

more use of 'dm' - could definitely use more descriptive names across all of these files/file names/etc. #Resolved

Comment thread Frameworks/UIKit/UIView.mm Outdated
if (dmGestureCount < MAXIMUM_DMGESTURE_ALLOW) {
dmrecognizers[dmGestureCount++] = curgesture;
} else {
TraceWarning(TAG, L"DMGestures exceed maxinum allowed, ignoring the rest");

@jaredhms jaredhms Nov 3, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maxinum [](start = 54, length = 7)

nit: maximum #Resolved

@jaredhms

jaredhms commented Nov 3, 2016

Copy link
Copy Markdown
Contributor

Do we already have an existing test for this in XamlCatalog or WoCCatalog? #Resolved

for (int i = 0; i < viewDepth; i++) {
// sendTouch to gesture for state transiton
BOOL gestureOnGoing = NO;
for (int i = 0; i < gestureCount; i++) {

@jaredhms jaredhms Nov 3, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you should be able to do range-based for loops over both of these gesture arrays #Resolved

Comment thread Frameworks/UIKit/UIView.mm Outdated

// scanning DM Getures, if a gestures is on going, cancel DM Gestures
// otherwise, send Touch to DM gestures
for (int i = 0; i < dmGestureCount; i++) {

@jaredhms jaredhms Nov 3, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for (int i = 0; i < dmGestureCount; i++) { [](start = 3, length = 43)

nit: range-based for here, too #Resolved

[dmGesture performSelector:eventName withObject:[NSMutableSet setWithObject:touch] withObject:event];
if (DEBUG_GESTURES) {
TraceVerbose(TAG, L"Send Touch with phase=%d to DMGesture %hs.", touch.phase, object_getClassName(dmGesture));
}

@jaredhms jaredhms Nov 3, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: why not move this into the above 'if' and ditch the 'send' variable? #WontFix

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the current form is actually better. notice default is true. If remove send, the conditional clause becomes much more complex and not clear.


In reply to: 86438414 [](ancestors = 86438414)

Comment thread Frameworks/UIKit/UIView.mm Outdated
UIGestureRecognizerState state = (UIGestureRecognizerState)[curgesture state];
// Removed/reset failed/done gestures, including gestures and DMGestures
for (int i = 0; i < 2; i++) {
int count = (i == 0) ? gestureCount : dmGestureCount;

@jaredhms jaredhms Nov 3, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kind of strange; how about pulling this out into a shared function or lambda that gets called for both arrays? #Resolved

Comment thread Frameworks/UIKit/UIScrollView.mm Outdated

// setting transparent background so we can receive touch input
WUColor* convertedColor = ConvertUIColorToWUColor([UIColor clearColor]);
WUXMSolidColorBrush* brush = [WUXMSolidColorBrush makeInstanceWithColor:convertedColor];

@jaredhms jaredhms Nov 3, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about just setting directly to the projected transparent brush rather than creating a UIColor only to convert to the projected type? Something like [WUXMSolidColorBrush makeInstanceWithColor:[WUColor transparent]] ? #Resolved

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

at which point you could just do _contentCanvas.background = [WUXMSolidColorBrush makeInstanceWithColor:[WUColor transparent]]


In reply to: 86439907 [](ancestors = 86439907)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

like that


In reply to: 86440003 [](ancestors = 86440003,86439907)

Comment thread Frameworks/QuartzCore/CALayer.mm Outdated
// get the backing xaml UIElement for toLayer
WXUIElement* toLayerElement = _getBackingXamlElementForCALayer(toLayer);

// set up transform from xaml elment in fromLayer to xaml element in toLayer

@oliversa-msft oliversa-msft Nov 3, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo - element #Resolved

Comment thread Frameworks/UIKit/UIScrollView.mm Outdated
[self _setManipulationMode:WUXIManipulationModesSystem recursive:YES];

const std::vector<TouchInfo>& pointers = [gesture _getTouches];
for (size_t i = 0; i < pointers.size(); ++i) {

@jaredhms jaredhms Nov 3, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for (size_t i = 0; i < pointers.size(); ++i) { [](start = 2, length = 48)

range-based for #Resolved

Comment thread Frameworks/UIKit/UIScrollView.mm Outdated
// start Direct manipuation only if active touch presents
if (touch.phase != UITouchPhaseCancelled && touch->_routedEventArgs.pointer.pointerDeviceType == WDIPointerDeviceTypeTouch) {
if (![WXFrameworkElement tryStartDirectManipulation:touch->_routedEventArgs.pointer]) {
TraceWarning(TAG, L"DManip didn't start");

@jaredhms jaredhms Nov 3, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

didn't [](start = 43, length = 6)

nit: 'failed to' might be more clear #Resolved

@yiyang-msft

Copy link
Copy Markdown
Contributor Author

yes, we do. In WoCcatalog, the textview is a good example of gesture attached to subview get fired first and DM will be cancelled. and also, when DM gesture started, it can be chained to upper UIScrollview as well.


In reply to: 258266383 [](ancestors = 258266383)

- (void)scrollViewDidZoom:(UIScrollView*)aScrollView {
// don't have to do anything special to centralize the imageView after zoom when zoomFactor is less than 1
// xaml scrollview does that automatically now
CGFloat offsetX = (scrollView.bounds.size.width > scrollView.contentSize.width) ?

@yiyang-msft yiyang-msft Nov 4, 2016

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CGFloat [](start = 4, length = 7)

accidental, i will revert. #Resolved

return didRecognize;
}

- (const std::vector<TouchInfo>&)_getTouches {

@oliversa-msft oliversa-msft Nov 3, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of interest, why is it a reference and not just a copy? #Resolved

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

copies are wasteful


In reply to: 86441503 [](ancestors = 86441503)

@oliversa-msft oliversa-msft Nov 4, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However, if this case is it also why we need to keep the StrongId<> around? If we did make a copy are things cleaner? #Pending

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you mean StrongId _routedEventArgs;? StrongId here is to make sure UITouch has the same life time for routedEventArgs, as we see in multiple-finger gesture cases, routedEventArgs can be become invalid though UITouch is still valid. Still a mystery to figure out why. But copy won't solve this problem either plus add additional cost.


In reply to: 86604604 [](ancestors = 86604604)

Comment thread Frameworks/UIKit/UIScrollView.mm Outdated
const std::vector<TouchInfo>& pointers = [gesture _getTouches];
for (size_t i = 0; i < pointers.size(); ++i) {
UITouch* touch = pointers[i].touch;
// start Direct manipuation only if active touch presents

@oliversa-msft oliversa-msft Nov 3, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm really bad at this but my eyes are drawn to capitalization changes - direct manipulation is what you used above. #Resolved

Comment thread Frameworks/UIKit/UIScrollView.mm Outdated
for (size_t i = 0; i < pointers.size(); ++i) {
UITouch* touch = pointers[i].touch;
// start Direct manipuation only if active touch presents
if (touch.phase != UITouchPhaseCancelled && touch->_routedEventArgs.pointer.pointerDeviceType == WDIPointerDeviceTypeTouch) {

@oliversa-msft oliversa-msft Nov 3, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is _routedEventArgs.pointer guaranteed to be populated and non-null? #Resolved

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes


In reply to: 86442520 [](ancestors = 86442520)

Comment thread Frameworks/UIKit/UIView.mm Outdated
g_curGesturesDict = [NSMutableDictionary new];

UIGestureRecognizer* recognizers[128];
const static int MAXIMUM_GESTURE_ALLOW = 128;

@oliversa-msft oliversa-msft Nov 3, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Super nit: MAXIMUM_GESTURE_ALLOWED #Resolved

@oliversa-msft oliversa-msft dismissed their stale review November 4, 2016 17:29

Wrong button pressed

Comment thread Frameworks/UIKit/UIScrollView.mm Outdated
static const bool DEBUG_DELEGATE = DEBUG_ALL || false;
static const bool DEBUG_INSETS = DEBUG_ALL || false;
static const bool DEBUG_ZOOM = DEBUG_ALL || false;
static const bool DEBUG_DMANIP_GESTURE = DEBUG_ALL || true;

@jaredhms jaredhms Nov 4, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

true [](start = 54, length = 4)

set back to false before pushing? #Resolved

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah.


In reply to: 86598268 [](ancestors = 86598268)

Comment thread Frameworks/UIKit/UIScrollView.mm Outdated
const std::vector<TouchInfo>& pointers = [gesture _getTouches];
for (auto const& pointer : pointers) {
UITouch* touch = pointer.touch;
// start Direct manipuation only if active touch presents

@jaredhms jaredhms Nov 4, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

manipuation [](start = 24, length = 11)

nit: Typo #Resolved

// setting it to 7.0 which is slightly larger than 6.0 which is used
// by PanGestureRecognizer, this is to ensure PanGestureRecognizer kicks
// in first before us.
[self _setDragSlack:7.0f];

@jaredhms jaredhms Nov 4, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: maybe we should expose this off of a private UIPanGestureRecognizer property, so we can just +1 here? #Resolved

Comment thread Frameworks/UIKit/UIView.mm Outdated

#import <math.h>
#import <string>
#import <array>

@jaredhms jaredhms Nov 4, 2016

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove? sorry for the noise! :/ #Resolved

@jaredhms

jaredhms commented Nov 4, 2016

Copy link
Copy Markdown
Contributor

:shipit:

@yiyang-msft yiyang-msft merged commit d6e3a6f into develop Nov 4, 2016
@yiyang-msft yiyang-msft deleted the Gesture branch November 4, 2016 21:00
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants