extended Drag&Drop functionality
#1
Hi,

I recently started working on extending the drag&drop functionality of xbmc...

I started with working on "In list drag&drop". By that I mean that the user can just drag an item in a list to another position in that same list. of course that is only available in a few windows. Right now it's implemented in Favorites and the Music/Video Playlists (those are the windows where i know that there are "Move item up/down" context menus. If I missed a window, please let me know.

What should this enhanced bring:
Step 1: In list dragging
  • Actually move the file item that has been dragged (Already working)
  • Let the skinner define a "drag handle" - that should be a visible representation of the item being dragged and will automatically follow the users mouse pointer. (Already working. In the screenshot that's the little thumbnail under the mouse)
  • Let the skinner define a "drag hint" - that should be an indication on where the item would be dropped right now, if the user released the mouse. (Right now that's a hardcoded DrawRect(), so it still needs to be made skinnable. Also there is a bug in calculated the correct position of this item)
  • Let the skinner change the visual appearence of the list item being dragged. (already working. In the skin I just added "...draging" to the label, but I'm sure there are more useful things that could be done Wink
Here is a screenshot of how it currently looks like when dragging in the favourites dialog:
Image

Step 2: all guicontrols can act as drop regions.
Let the user define a guicontrol as "dropable" via some sort of <dropable>KIND_OF_DROPABLE</dropable> and allow the skinner to execute a function when a listitem gets dropped over it via <ondrop>AddToFavourites</ondrop>
Also it might be nice, if the skinner could change the appearance of the drag handle depending on where the user is hovering right now... that way he could add a little plus sign to indicate the dragged item would be added to the favourites, if released right now.
Here is an example screenshot
Image

So, this thread is basically just an FYI that I'm working on this and also to get some feedback if anyone has suggestions on additonal ideas (can't promise, that I will do them).

Btw: I have applied for GSoC 2013, so is this an appropriate application task?

Here is the branch: https://github.com/Fice/xbmc/commits/in_list_dragging
Reply
#2
Nice idea. I think this would be much more usable with touch than with mouse Wink

Couple of suggestions:
1. Please, don't put item swapping handling in GUIWindow* . In future we want to be able to fill containers with items outside of their dedicate window (in example - we want to be able to put container with favourites in home screen), coding this in GUIWindow* would cause such containers lack drag&drop.

This could be done in IDirectory level (CPlaylistDirectory is already there, Favourites would need moving to IDirectory).

I very (and I mean veeeeery) briefly looked on your changes, so not sure if this isn't some leftover, but adding
Code:
+            <dragable>favourites</dragable>
+            <dragable>playlist</dragable>
to skins is not the way to go. It's not skin responsibility to know what can be dragged (and reordered).

2. DragHint: instead of showing indicator where item would be, how about actual moving that item while dragging and reorder list on the fly (actual changes would be applied on drag finish). This would look even cooler with some animations there Smile

Step 2 - there is quite potential in this one - f.e. dragging item in list could cause additional bar/dialog to appear with available UPnP Renderers, literally moving item into renderer ;P or one could drop item in playlist - this would be cool also.

Great initiative Smile
Always read the XBMC online-manual, FAQ and search the forums before posting.
Do NOT e-mail Team-XBMC members asking for support. Read/follow the forum rules.
For troubleshooting and bug reporting, make sure you read this first

My previous forum/trac nickname: grajen3
Reply
#3
Yes, it is meant for touch devices, but i don't have a tablet (yet) Wink

1. Ok, will try to move as much out of CGUIWindow* as possible...
Couple of questions
  • Who should be responsible for setting container->SetReorderable()? Right now I added a IsReorderable virtual function to IDirectory (default implementation returns false, so FavouritesDirectory and Playlists will overwrite that and return true). Is there a way for a GUIBaseContainer to find out if his content came from an IDirectory->IsReoderable()==true?!?
  • I take it, that IDirectory is not responsible for actually sorting the list items? so I'm not sure how reliable I could implement the MoveItem() functions in there... will have to see
  • CFavourites (now called CFavouritesDirectory) now implements the IDirectory interface. I also " if (strProtocol == "favourites") return new CFavouritesDirectory();" to the Factory method... anything else that I need to do?

Concerning the <dragable> and <dropable> stuff: These are not leftovers (but they are for step 2, not step 1)
lets assume a skinner adds a drop area that will upload pictures to flickr...
so he has a control with:
<ondrop>ExecuteScript(script.flickr.upload, dragndrop.item.path)</ondrop>
He would of course only add it to the Picture Windows...
But now we have the problem, that there could be home videos in the picture listing, but the script.flickr.upload script can only handle images.
That's why I thought a skinner could add <dragable>flickr_script</dragable> only to the picture list items
and then <dropable>flickr_script</dropable> to the drop area... It would be cool if xbmc could automatically deduct (from the ondrop action) if an item can be dropped there. That might be possible with simple built in actions but would be very difficult when it comes to scripts etc....

2. DragHint: Well, that probably is one of those personal preference things ^^. I personally would prefer a Drag Hint.
How about, i check if a skinner defined a <dragHint> and if so, do what I suggested, if not then just do the instant reodering thingie.
That would make the in-list-dragging usable right away, without any work for skinners... but they could still do it, if they want to

Stuff like the "Sent to UPnP Renderer" drop areas are exactly what I had in mind Wink

EDIT: forgot my 3rd question Wink
Reply
#4
(2013-04-01, 16:58)Fice Wrote: So, this thread is basically just an FYI that I'm working on this and also to get some feedback if anyone has suggestions on additonal ideas (can't promise, that I will do them).

An idea. The "choose art" window in the movie info dialog.
This window shows actual arts: banner, poster, fanart....
if it were possible to combine this window with the another one that open for download new art, the user could drag & drop the art to download to the type of art desired. Furthermore, if the movie set art were displayed in the choose art, the user could pick it from here,too.

Anyway I think this idea is beyond the scope of this thread. Rather it is a feature suggest but the idea occurred to me while reading this thread
Reply
#5
@narvatu: From what I understand you want two lists and the ability to drag&drop between them? I have that use case in mind and I don't see any big issues why it shouldn't work from the drag&drop part (not tested though). But even if my drag&drop stuff is done, you would also need what Pieh talked about, in order to actually fill both lists
Pieh Wrote:In future we want to be able to fill containers with items outside of their dedicate window


So, some progress has been made Wink
  • The dragHint position isn't off completely anymore (there is still a small offset of a few pixels, but better than before)
  • When the skinner didn't specify a dragHint, direct reordering will now be used (A few minor issues exist, but I'm confident that those are fixed until tonight)
  • Previously the Control where the dragging started requested exclusive mouse control. That way it was not possible for the user to e.g. hover the button that opens the left side menu. Now skinners could decide to hide drag areas in those kind of menus. Downside: If the user drags the listitem from the 2nd screenshot i posted on top of the favourites button, he will most like drag over the scrollbar, which will issue some scrolling. In this case that's most likely unwanted. However, there might be other cases where the user explicitly wants to hover the scrollbar to scroll the list... so I'm not sure if this behavior should be kept or not, will wait for some input regarding this.
    Also: There are probably a lot of other Controls that listen to drag events, will probably have to look at each one of those and perhaps prevent their normal drag behavior if the user is currently dragging a fileitem!
  • Also some work has been done in order to let the skinner design the dragHint... unfortunately without success, the thing will just not show up Sad will have to investigate a little further how guilibs black magic works...

Didn't push any of this, because I'm still working on the issues regarding the 2nd point and code right now looks really ugly... will clean things up after I resolved the issues and i hope I'm ready to push this tonight Wink
Reply
#6
Regarding your first question, I'd make the reorderability a property of the CFileItemList, which is then set on the container once you BIND the items. You'll need to make sure you reset it at the appropriate points.
Always read the XBMC online-manual, FAQ and search the forum before posting.
Do not e-mail XBMC-Team members directly asking for support. Read/follow the forum rules.
For troubleshooting and bug reporting please make sure you read this first.


Image
Reply
#7
Status report Wink

In-List dragging, and dragging of list items onto generic CGUIControls, where the skinner set a <ondrop>action</ondrop> is working now. Also, the <ondrop> functions get executed properly.

The in-list-dragging, without a drag hint set, works without any issues.

@Pieh: The <dropable> <dragable> stuff is gone now Wink Whether a file item can be dropped onto another list will be decided by xbmc. also if a list is reorderable will be set by xbmc core. If a ListItem can be dropped on to any other control will be determined by the condition of the ondrop definition. That should simplify things for skinners

I've exposed a few more things via the info manager. Skinners can now change the Drag Handle based on what element is currently hovered. (In my example skin I adde a little plus icon when hovering the Favourites button).

Also, started to work on Drag&Drop between lists and that is making good progress Wink

Now the bad news: i worked a bit further on the drag hint and I just can't get it to work. (at least it's showing up now, but at the wrong position).
I tried two approaches.
  • Using SetOrigin():
    Code:
    void CGUIListDragHandler::Render()
    {
    ...
        g_graphicsContext.SetOrigin(m_dragHintPosition.x, m_dragHintPosition.y);
        m_dragHint->DoRender();
       g_graphicsContext.RestoreOrigin();
    }
    I did the same with DoProcess, but that didn't do it, the DragHint was drawn in the top left corner of the screen
  • Using
    Code:
    m_dragHint->SetPosition()
    ... and that is were things get strange.
    If the skinner uses a <control type="label"> as a drag hint, it gets drawn in the top left corner of the screen...
    If he uses a <control type="image">, then SetPosition() seems to have the desired effect, BUT the image gets drawn a few (100 perhabs) pixels below a DrawQuad() that gets the exact same position. hence the position is wrong too. Any idea where that offset comes from?
    If the user uses a <control type="group"> with one image inside, nothing shows up... Everytime the controls had posx/posy explicitly set to 0.
So, to anyone with some guilib knowledge: What is the best method to set the position of a CGUIControl* programmatically (independent of the actual control type)?
Or perhaps someone wants to take a look at: https://github.com/Fice/xbmc/blob/in_lis...andler.cpp
The functions in question are ShowDragHint() (called mostly when we got a DragMove Event) and the Process() and Render() functions (called from the same named functions in the GUIBaseContainer class during drag&drop).


NOTE: i wanted to focus on the guilib stuff first, so CGUIWindow* is still responsible of determining if a list is reorderable, a fileitem is dropable (from another list), and adding a new item. Will do that Refactoring once everything in the guilib is working
Reply
#8
Next Status Report Wink

Made a short showcase video of what is already working

Everything is a bit slow and stutters a bit, but that is due to the screen capturing

Did a big Refactor. I created an IGUIDropPolicy interface that is responsible for deciding what capabilities a CFileItemList has regarding Drag&Drop. This policy needs to be set by a Directory during loading. That way, CGUIWindow* is no longer responsible for anything Drag&Drop relating.
One exception though: I didn't feel comfortable to set a folder like C:/whatever to be dropable per default, but on the other hand it makes sense in the FileBrowser... so for now, the FileBrowser overrides the drag policy by hand.

Reordering is now also supported for containers others than list (wrapcontainer, fixedliscontainer etc...)
Didn't have time to test if it also works when dragging sth. onto one of those lists.

Implemented some special behavior for buttons that have a <ondrop> action set. if the user hovers such a button for 2 seconds, the onclick action will be executed.

And lot's of bugfixes Wink

BTW: since so much has changed and it is no longer just in-list-dragging, the new development branch is here: https://github.com/Fice/xbmc/tree/dragndrop
Reply
#9
Great work !!! I will definitely be using this all the time!
Reply
#10
You don't happen to have a touch device and could give my dragndrop branch a test?

Would be nice to know if it actually works with touch Wink
Reply
#11
Hello Fice,

i am very interested in helping on your drag & drop work. Whats the status about it? Are you planning to continue your work? Did you tried to merge your changes into the current XBMC code?

Greetings from Germany,
Bene
Reply

Logout Mark Read Team Forum Stats Members Help
extended Drag&Drop functionality0