New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
wxGTK: Expose GtkTreeView drop position #2240
base: master
Are you sure you want to change the base?
Conversation
Within a wxDataViewCtrl drag-and-drop the underlying GtkTreeView in wxGTK provides visual hints whether the drop is before/on/after the destination row, but this information is not exposed to the end developer. This proof-of-concept adds this functionality. The main change is connecting to the drag-data-get and drag-data-received signals which as far as I know were introduced in GTK3, and are able to provide more information then GtkTreeDragSourceIface and GtkTreeDragDestIface.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, this would be definitely useful to have, but I think this should reuse the existing m_proposedDropIndex
rather than adding another pair of accessors because it looks like the same thing to me, isn't it?
I.e. ideally we'd change wxGTK code so that the existing MyFrame::OnDrop()
handler in samples/dataview/dataview.cpp
would show the correct index when something is being dropped.
Could you please try to update the code to work like this? TIA!
src/gtk/dataview.cpp
Outdated
@@ -4630,6 +4634,30 @@ gtk_dataview_motion_notify_callback( GtkWidget *WXUNUSED(widget), | |||
return FALSE; | |||
} | |||
|
|||
static void evtDragDataGet(GtkWidget *widget, GdkDragContext *WXUNUSED(context), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor, but it would be nice to use the usual convention for the GTK callbacks names, i.e. wx_gtk_dataview_drag_data_get_callback
for this one.
Looks like |
Maybe I'm just misunderstanding what is this supposed to be used for, but how exactly is this different from the proposed drop index? I.e. how would you use this index other than for determining where to insert the new data? |
Consider the four cases in composite screenshot: GTK reports them as:
How would these four map to Maybe I should get to sleep now.. |
If the index of "Microcontrollers" is |
I think the idea behind labelling them Maybe |
Only build of generic |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, but unfortunately this still can't be applied because I don't think this provides a usable API for wx users (I also still have questions about the implementation, but this is secondary).
I.e. IMO the goal here should be to make the dataview sample work, i.e. determine the correct drop location, under all platforms. Right now this isn't the case because it doesn't work in wxGTK and this PR doesn't really help with it, as it just adds a different API which doesn't work in the other ports, while we really need something working in all of them.
include/wx/dnd.h
Outdated
// Flags for wxDataViewEvent::GetDragFlags() with wxEVT_DATAVIEW_DROP | ||
// Note: 0x05 & 0x06 are valid combinations! | ||
enum wxDropFlags |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Naming-wise it's not great to use wxDropFlags
as return value of GetDragFlags()
, "drag" and "drop" are different verbs. It looks like GetDragFlags()
is actually not used at all right now, which is, I guess, why you've decided to reuse it, but I'd still rather add GetDropFlags()
if we want to return these flags.
But more importantly, I'd still like to somehow reuse GetProposedDropIndex()
for this because otherwise you simply can't write portable code working correctly. I.e. you can either use the proposed drop index and it would work in the generic and Cocoa versions (i.e. under MSW and Mac) or use the drop flags and then it would work with wxGTK, but there is no way to make it work with both which is clearly not ideal.
Even if we can't represent all the possibilities using the proposed drop index, we should at least at least fill it when we can. I.e. it would be fine to provide some extra information in wxGTK which is not available under the other platforms, but we need to have at least some functionality common to all implementations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My intention is to at least add the new flags to the generic dataview, but this looks like it will take a while to figure out and unfortunately other things have been making calls on my time. Might be able to do some trickery with GTK's map_expanded_rows
in order to implement GetProposedDropIndex
with relatively few lines of code, but not sure how closely it will emulate how generic does things.
Probably should tag this as WIP
for the time being.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there is an inevitable API break here.
In cases where the item is dropped between two rows, wxGTK will select the lower row as what ends up returned by event.GetItem() whereas wxMSW (i.e. generic) will select the parent of the rows. Which one should be adopted as the universal convention?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there is an inevitable API break here.
This is not necessarily catastrophic (although best avoided, of course), the only "hard" requirement is to have at least a useful subset of the API actually working the same on all platforms, but I don't even think we need to break the API here.
In cases where the item is dropped between two rows, wxGTK will select the lower row as what ends up returned by event.GetItem() whereas wxMSW (i.e. generic) will select the parent of the rows. Which one should be adopted as the universal convention?
The latter behaviour seems more useful to me and this is also how the native macOS version behaves, so I'd strongly prefer to keep it like this and make wxGTK behave in the same way. Would it be possible to do it like this please? TIA!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll see what i can put together.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did some quick testing with samples/dataview
which looks like it was made for wxGeneric's reporting convention.
This is a reimplementation of how wxMSW cross-compiled on Linux using MinGW-w64 and run using Wine behaved so it is possible the behaviour is incorrect. Tested with a simple 3-deep tree that might have missed edge cases. What gets set for wxEVT_DATAVIEW_ITEM_DROP_POSSIBLE is not the same for wxMSW and wxGTK due to data not being available at the associated callback :( GTK2 vs. GTK3 vs. GTK4 also needs testing.
Some tidyup and testing still required. Need to change names to follow wxWidget coding standards. In wxGeneric event.GetDataBuffer() appears to be broken.
Within a wxDataViewCtrl drag-and-drop the underlying GtkTreeView
in wxGTK provides visual hints whether the drop is before/on/after
the destination row, but this information is not exposed to the
end developer. This proof-of-concept adds this functionality.
The main change is connecting to the drag-data-get and
drag-data-received signals which as far as I know were introduced
in GTK3, and are able to provide more information then
GtkTreeDragSourceIface and GtkTreeDragDestIface.