Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upfeat(dragdrop): Add support of Drag and Drop #4270
Conversation
|
It's great to see this PR. Lots of good stuff in here, awesome job! |
|
|
||
| if (src.GetData(DataFormats.FileDrop) is string[] files) | ||
| { | ||
| dst.SetStorageItems(files.Select(StorageFile.GetFileFromPath)); |
robloo
Oct 13, 2020
Contributor
Doing this when the DataPackage is created means that the file will be read as soon as the cursor enters the Uno app. This may not be performance friendly (although the file isn't copied here) and it would be better to use DataPackage.SetDataProvider(). For the macOS platform I use the following code:
dataPackage.SetDataProvider(
StandardDataFormats.StorageItems,
async cancellationToken =>
{
// Convert rom a temp Url (see above example) into an absolute file path
var fileUrl = new NSUrl(tempFileUrl);
var file = await StorageFile.GetFileFromPathAsync(fileUrl.FilePathUrl.AbsoluteString);
var storageItems = new List<IStorageItem>();
storageItems.Add(file);
return storageItems.AsReadOnly();
});
Doing this when the DataPackage is created means that the file will be read as soon as the cursor enters the Uno app. This may not be performance friendly (although the file isn't copied here) and it would be better to use DataPackage.SetDataProvider(). For the macOS platform I use the following code:
dataPackage.SetDataProvider(
StandardDataFormats.StorageItems,
async cancellationToken =>
{
// Convert rom a temp Url (see above example) into an absolute file path
var fileUrl = new NSUrl(tempFileUrl);
var file = await StorageFile.GetFileFromPathAsync(fileUrl.FilePathUrl.AbsoluteString);
var storageItems = new List<IStorageItem>();
storageItems.Add(file);
return storageItems.AsReadOnly();
});
dr1rrb
Oct 15, 2020
Author
Member
With the latest version of the StorageFile, this will actually only create some instances of StorageFile (and it does not create a FileInfo which would indeed have touched the file system). It's even using an internal sync overload which makes it the most lightweight possible I think.
Did you notice any perf issue with this one or it's just theoretical?
With the latest version of the StorageFile, this will actually only create some instances of StorageFile (and it does not create a FileInfo which would indeed have touched the file system). It's even using an internal sync overload which makes it the most lightweight possible I think.
Did you notice any perf issue with this one or it's just theoretical?
robloo
Oct 16, 2020
Contributor
This one was just theoretical :) I did it differently on macOS just to be on the extra-safe side. Perhaps that wasn't necessary but I didn't know the internals of how StorageFile works on all platforms and could see it accessing the file system so wanted to be careful.
This one was just theoretical :) I did it differently on macOS just to be on the extra-safe side. Perhaps that wasn't necessary but I didn't know the internals of how StorageFile works on all platforms and could see it accessing the file system so wanted to be careful.
@robloo Thanks for your contribution to this PR |
|
Not sure if you will see it here faster: The commits in PR #4216 need to be added here to fix the macOS and iOS build issues. |
doc/articles/features/pointers-keyboard-and-other-user-inputs.md
Outdated
Show resolved
Hide resolved
| var copy = new MemoryStream(); | ||
| streamSource.CopyTo(copy); | ||
| copy.Position = 0; | ||
| Stream = copy; |
carldebilly
Oct 16, 2020
Member
You should explain here why you're copying it.
You should explain here why you're copying it.
|
@dr1rrb I realize the DragDropManager may need another method similar to ProcessAborted()/ProcessDropped(). When an external drop is completed outside of Uno we should notify the source UIElement inside Uno to raise DropCompleted. This means the manager really should have a ProcessCompleted(). This could also go inside the other Complete() handling code. Otherwise, maybe the missing functionality should be in ProcessDropped()? Or I'm completely missing something? Either way, DropCompleted is not getting raised inside Uno when an external drop is completed (on macOS at least). As soon as the pointer comes back into Uno the drag is still active even after dropping content externally. |
@robloo On Skia I track them using the lost of the pointer capture ... but you made me realized that I probably don't propagate the actual drop result in that case. So you're right and I would agree that we should add those methods. I'll see if I'm able to fix this afternoon. (If not, I don't consider this as a blocker to merge this PR as anyway the external drag and drop is supported on skia, and this PR is already way to massive to wait more longer) |
|
@dr1rrb OK, I totally understand if this is all getting too big and we just need to merge as-is and fix more later. I'm good with whatever you decide :) |
| var data = await ToDataObject(info.Data, CancellationToken.None); | ||
| var effects = ToDropEffects(info.AllowedOperations); | ||
|
|
||
| DragDrop.DoDragDrop(WpfHost.Current, data, effects); |
robloo
Oct 16, 2020
Contributor
How is Uno notified when the host completes a drop? How is DropCompleted raised? Maybe that comes through the window events (OnHostDrop) again?
How is Uno notified when the host completes a drop? How is DropCompleted raised? Maybe that comes through the window events (OnHostDrop) again?
robloo
Oct 16, 2020
Contributor
Edit: Agree to address this later as needed. (assuming I'm understanding correctly anyway).
Edit: Agree to address this later as needed. (assuming I'm understanding correctly anyway).
…ending, will be removed soon)
|
The build 20718 found UI Test snapshots differences: Details
|
|
The build 20718 found UI Test snapshots differences: Details
|
|
The build 20718 found UI Test snapshots differences: Details
|
|
The build 20718 found UI Test snapshots differences: Details
|
|
The build 20718 found UI Test snapshots differences: Details
|
|
The build 20718 found UI Test snapshots differences: Details
|
| Run(); | ||
| } | ||
|
|
||
| private async void Run() |
| } | ||
| } | ||
|
|
||
| internal void Dispose() // We do not implement IDisposable as it would defer with the UWP contract, and we don't want the app to dispose this request. |
nventive-devops
Oct 19, 2020
Contributor
Codacy found an issue: Either implement 'IDisposable.Dispose', or totally rename this method to prevent confusion.
Codacy found an issue: Either implement 'IDisposable.Dispose', or totally rename this method to prevent confusion.
| //| RoutedEventFlag.DragOver | ||
| //| RoutedEventFlag.Drop | ||
| //| RoutedEventFlag.DropCompleted; | ||
| private const RoutedEventFlag _isDragAndDrop = // 0b0000_0000_0000_0000___0000_0000_0011_1111___0000_0000_0000_0000___0000_0000_0000_0000; |
| // Those events are subscribed for safety, but they are usually useless as: | ||
| // | ||
| // # for internally initiated drag operation: | ||
| // the pointer is (implicitly) captured by the GestureRecognizer when a Drag manipulation is detected; |
| @@ -274,6 +313,49 @@ private ManipulationDelta GetDelta(ManipulationDelta cumulative) | |||
| }; | |||
| } | |||
|
|
|||
| // For pen and mouse this only means down -> * moves out of tap range; | |||
| var that = (UIElement)snd; | ||
| var result = resultTask.IsFaulted | ||
| ? DataPackageOperation.None | ||
| : resultTask.Result; |
| { | ||
| using var enumerator = children.GetEnumerator(); | ||
| while (enumerator.MoveNext() && enumerator.Current != element) | ||
| { |
|
|
||
| // As the pointer args are always bubbling (for to properly update pressed/over state and manipulations), | ||
| // if a parent is CanDrag == true, its gesture recognizer might (should) also trigger the DragStarting. | ||
| // But: (1.) on UWP only the top-most draggable element starts the drag operation; |
|
The build 20801 found UI Test snapshots differences: Details
|
bfcfb79
into
master
GitHub Issue: #1480
Feature
Add support
UIElement.Drag<Starting|Entered|Over|Exited>andUIElement.Drop[Completed]events for inter-app and intra-app drag and drop.What is the current behavior?
Drag and drop is not supported at all.
What is the new behavior?
PR Checklist
Screenshots Compare Test Runresults.