[gnome-music/wip/jfelder/gtk4-v3: 200/200] songwidget: Restore drag and drop
- From: Jean Felder <jfelder src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-music/wip/jfelder/gtk4-v3: 200/200] songwidget: Restore drag and drop
- Date: Fri, 11 Feb 2022 15:44:53 +0000 (UTC)
commit fa15dc8043b849e645864a2ff39e2e50a1f64429
Author: Jean Felder <jfelder src gnome org>
Date: Fri Feb 11 15:09:42 2022 +0100
songwidget: Restore drag and drop
data/ui/SongWidget.ui | 37 ++++++++------
gnomemusic/widgets/songwidget.py | 103 +++++++++++++++++++--------------------
2 files changed, 73 insertions(+), 67 deletions(-)
---
diff --git a/data/ui/SongWidget.ui b/data/ui/SongWidget.ui
index 8c4b273b2..367849c83 100644
--- a/data/ui/SongWidget.ui
+++ b/data/ui/SongWidget.ui
@@ -1,29 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.20.0 -->
<interface>
- <requires lib="gtk+" version="3.10"/>
+ <requires lib="gtk" version="4.0"/>
<template class="SongWidget" parent="GtkListBoxRow">
<property name="focusable">False</property>
<property name="selectable">False</property>
- <!-- <signal name="drag_data_received" handler="_on_drag_data_received"/> -->
<child>
<object class="GtkBox" id="box1">
<property name="focusable">False</property>
<property name="spacing">6</property>
<child>
- <object class="GtkBox" id="_dnd_eventbox">
+ <object class="GtkImage" id="_dnd_icon">
<property name="visible">False</property>
- <!-- <signal name="drag-begin" handler="_on_drag_begin"/> -->
- <!-- <signal name="drag-end" handler="_on_drag_end"/> -->
- <!-- <signal name="drag_data_get" handler="_on_drag_data_get"/> -->
- <child>
- <object class="GtkImage">
- <property name="icon-name">list-drag-handle-symbolic</property>
- <style>
- <class name="drag-handle"/>
- </style>
- </object>
- </child>
+ <property name="icon-name">list-drag-handle-symbolic</property>
+ <style>
+ <class name="drag-handle"/>
+ </style>
</object>
</child>
<child>
@@ -191,6 +182,22 @@
<signal name="released" handler="_on_click" swapped="no"/>
</object>
</child>
+ <child>
+ <object class="GtkDragSource" id="_drag_source">
+ <property name="actions">move</property>
+ <property name="propagation-phase">none</property>
+ <signal name="prepare" handler="_on_drag_prepare" swapped="no"/>
+ <signal name="drag-begin" handler="_on_drag_begin" swapped="no"/>
+ </object>
+ </child>
+ <child>
+ <object class="GtkDropTarget">
+ <property name="actions">move</property>
+ <property name="formats">SongWidget</property>
+ <property name="preload">True</property>
+ <signal name="drop" handler="_on_drop" swapped="no"/>
+ </object>
+ </child>
<style>
<class name="songwidget"/>
</style>
diff --git a/gnomemusic/widgets/songwidget.py b/gnomemusic/widgets/songwidget.py
index c39b8b6aa..ff3dbf3f4 100644
--- a/gnomemusic/widgets/songwidget.py
+++ b/gnomemusic/widgets/songwidget.py
@@ -22,6 +22,8 @@
# code, but you are not obligated to do so. If you do not wish to do so,
# delete this exception statement from your version.
+from __future__ import annotations
+
from enum import IntEnum
from typing import Optional
@@ -60,7 +62,8 @@ class SongWidget(Gtk.ListBoxRow):
_album_duration_box = Gtk.Template.Child()
_artist_box = Gtk.Template.Child()
_artist_label = Gtk.Template.Child()
- # _dnd_eventbox = Gtk.Template.Child()
+ _dnd_icon = Gtk.Template.Child()
+ _drag_source = Gtk.Template.Child()
_menu_button = Gtk.Template.Child()
_select_button = Gtk.Template.Child()
_number_label = Gtk.Template.Child()
@@ -142,57 +145,53 @@ class SongWidget(Gtk.ListBoxRow):
if not self.props.coresong.props.is_tracker:
self._star_stack.props.visible_child_name = "empty"
- # if can_dnd is True:
- # self._dnd_eventbox.props.visible = True
- # self._drag_widget = None
- # entries = [
- # Gtk.TargetEntry.new(
- # "GTK_EVENT_BOX", Gtk.TargetFlags.SAME_APP, 0)
- # ]
- # self._dnd_eventbox.drag_source_set(
- # Gdk.ModifierType.BUTTON1_MASK, entries,
- # Gdk.DragAction.MOVE)
- # self.drag_dest_set(
- # Gtk.DestDefaults.ALL, entries, Gdk.DragAction.MOVE)
-
- # @Gtk.Template.Callback()
- # def _on_drag_begin(self, klass, context):
- # gdk_window = self.get_window()
- # _, x, y, _ = gdk_window.get_device_position(context.get_device())
- # allocation = self.get_allocation()
-
- # self._drag_widget = Gtk.ListBox()
- # self._drag_widget.set_size_request(allocation.width, allocation.height)
-
- # drag_row = SongWidget(self.props.coresong)
- # drag_row.props.show_song_number = self.props.show_song_number
-
- # self._drag_widget.add(drag_row)
- # self._drag_widget.drag_highlight_row(drag_row)
- # self._drag_widget.props.visible = True
- # Gtk.drag_set_icon_widget(
- # context, self._drag_widget, x - allocation.x, y - allocation.y)
-
- # @Gtk.Template.Callback()
- # def _on_drag_end(self, klass, context):
- # self._drag_widget = None
-
- # @Gtk.Template.Callback()
- # def _on_drag_data_get(self, klass, context, selection_data, info, time_):
- # row_position = self.get_index()
- # selection_data.set(
- # Gdk.Atom.intern("row_position", False), 0,
- # bytes(str(row_position), encoding="UTF8"))
-
- # @Gtk.Template.Callback()
- # def _on_drag_data_received(
- # self, klass, context, x, y, selection_data, info, time_):
- # source_position = int(str(selection_data.get_data(), "UTF-8"))
- # target_position = self.get_index()
- # if source_position == target_position:
- # return
-
- # self.emit("widget-moved", source_position)
+ self._drag_x = 0.
+ self._drag_y = 0.
+ self._drag_widget: Optional[Gtk.ListBox] = None
+ if can_dnd:
+ capture_phase = Gtk.PropagationPhase.CAPTURE
+ self._drag_source.props.propagation_phase = capture_phase
+ self._dnd_icon.props.visible = True
+
+ @Gtk.Template.Callback()
+ def _on_drag_prepare(
+ self, drag_source: Gtk.DragSource, x: float,
+ y: float) -> Gdk.ContentProvider:
+ self._drag_x = x
+ self._drag_y = y
+ return Gdk.ContentProvider.new_for_value(self)
+
+ @Gtk.Template.Callback()
+ def _on_drag_begin(
+ self, drag_source: Gtk.DragSource, drag: Gdk.Drag) -> None:
+ allocation = self.get_allocation()
+ self._drag_widget = Gtk.ListBox()
+ self._drag_widget.set_size_request(allocation.width, allocation.height)
+
+ drag_row = SongWidget(self.props.coresong, False, True)
+ drag_row.props.show_song_number = self.props.show_song_number
+ self._drag_widget.append(drag_row)
+ self._drag_widget.drag_highlight_row(drag_row)
+
+ drag_icon = Gtk.DragIcon.get_for_drag(drag)
+ drag_icon.props.child = self._drag_widget
+ drag.set_hotspot(self._drag_x, self._drag_y)
+
+ @Gtk.Template.Callback()
+ def _on_drop(
+ self, target: Gtk.DropTarget,
+ source_widget: SongWidget, x: float, y: float) -> bool:
+ self._drag_widget = None
+ self._drag_x = 0.
+ self._drag_y = 0.
+
+ source_position = source_widget.get_index()
+ target_position = self.get_index()
+ if source_position == target_position:
+ return False
+
+ self.emit("widget-moved", source_position)
+ return True
@Gtk.Template.Callback()
def _on_click(
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]