Skip to content

Commit a55a20c

Browse files
committed
use drag_source_set instead of manual activation
1 parent da460ab commit a55a20c

File tree

2 files changed

+55
-89
lines changed

2 files changed

+55
-89
lines changed

GraphView/drag_n_drop.py

Lines changed: 38 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -20,24 +20,34 @@ class DragAndDrop():
2020
Add Drag-n-Drop feature to GraphView addon.
2121
"""
2222

23-
def __init__(self, widget, dbstate):
24-
self.ready = False # True - when drag can be started
25-
self.do_drag = False # True - when drag is started
26-
23+
def __init__(self, canvas, dbstate):
2724
self.drag_person = None
2825
self.drag_family = None
2926

3027
self.dbstate = dbstate
31-
self.widget = widget
32-
self.widget.connect("drag_data_get", self.drag_data_get)
33-
self.widget.connect("drag_begin", self.begin)
34-
self.widget.connect("drag_end", self.stop)
28+
self.canvas = canvas
29+
self.canvas.connect("drag_data_get", self.drag_data_get)
30+
self.canvas.connect("drag_begin", self.begin)
31+
self.canvas.connect("drag_end", self.stop)
32+
33+
self.enable_dnd(True)
34+
35+
def enable_dnd(self, state):
36+
"""
37+
Enable or disable drag-n-drop for canvas widget.
38+
"""
39+
if state:
40+
self.canvas.drag_source_set(
41+
Gdk.ModifierType.BUTTON1_MASK,
42+
[],
43+
Gdk.DragAction.COPY)
44+
else:
45+
self.canvas.drag_source_unset()
3546

3647
def begin(self, widget, context):
3748
"""
3849
Called when drag is start.
3950
"""
40-
self.do_drag = True
4151
tgs = [x.name() for x in context.list_targets()]
4252
# set icon depending on person or family drag
4353
if DdTargets.PERSON_LINK.drag_type in tgs:
@@ -49,29 +59,36 @@ def stop(self, *args):
4959
"""
5060
Called when drag is end.
5161
"""
52-
self.ready = False
53-
self.do_drag = False
5462
self.drag_person = None
5563
self.drag_family = None
5664

57-
def is_ready(self):
65+
def set_target(self, node_class, handle):
5866
"""
59-
Check if we ready to drag.
60-
"""
61-
return self.ready and (not self.do_drag)
62-
63-
def set_ready(self, node_class, handle):
64-
"""
65-
Set ready to drag state.
67+
Set targets for drag-n-drop.
6668
"""
6769
self.stop()
70+
tglist = Gtk.TargetList.new([])
6871
if node_class == 'node':
6972
self.drag_person = self.dbstate.db.get_person_from_handle(handle)
73+
tglist.add(DdTargets.PERSON_LINK.atom_drag_type,
74+
DdTargets.PERSON_LINK.target_flags,
75+
DdTargets.PERSON_LINK.app_id,
76+
)
77+
# allow drag to a text document, info on drag_get will be 0
78+
tglist.add_text_targets(0)
7079
elif node_class == 'familynode':
7180
self.drag_family = self.dbstate.db.get_family_from_handle(handle)
81+
tglist.add(DdTargets.FAMILY_LINK.atom_drag_type,
82+
DdTargets.FAMILY_LINK.target_flags,
83+
DdTargets.FAMILY_LINK.app_id,
84+
)
85+
# allow drag to a text document, info on drag_get will be 1
86+
tglist.add_text_targets(1)
7287

73-
if self.drag_person or self.drag_family:
74-
self.ready = True
88+
if tglist:
89+
self.canvas.drag_source_set_target_list(tglist)
90+
else:
91+
self.enable_dnd(False)
7592

7693
def drag_data_get(self, widget, context, sel_data, info, time):
7794
"""
@@ -109,33 +126,3 @@ def drag_data_get(self, widget, context, sel_data, info, time):
109126
mother = '...'
110127
sel_data.set_text(
111128
_('Family of %s and %s') % (father, mother), -1)
112-
113-
def start_drag(self, pos_x, pos_y, event):
114-
"""
115-
Activate drag.
116-
"""
117-
# setup targets
118-
tglist = Gtk.TargetList.new([])
119-
if self.drag_person is not None:
120-
tglist.add(DdTargets.PERSON_LINK.atom_drag_type,
121-
DdTargets.PERSON_LINK.target_flags,
122-
DdTargets.PERSON_LINK.app_id,
123-
)
124-
# allow drag to a text document, info on drag_get will be 0
125-
tglist.add_text_targets(0)
126-
if self.drag_family is not None:
127-
tglist.add(DdTargets.FAMILY_LINK.atom_drag_type,
128-
DdTargets.FAMILY_LINK.target_flags,
129-
DdTargets.FAMILY_LINK.app_id,
130-
)
131-
# allow drag to a text document, info on drag_get will be 1
132-
tglist.add_text_targets(1)
133-
134-
# start drag
135-
self.widget.drag_begin_with_coordinates(
136-
tglist,
137-
Gdk.DragAction.COPY,
138-
1, # left mouse button = 1
139-
event,
140-
pos_x, pos_y)
141-
return True

GraphView/graphview.py

Lines changed: 17 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1154,7 +1154,8 @@ def __init__(self, view, dbstate, uistate):
11541154
self.bold_size = self.norm_size = 0 # font sizes to send to dot
11551155

11561156
# setup drag and drop
1157-
self.dnd = DragAndDrop(self.get_widget(), self.dbstate)
1157+
self.dnd = DragAndDrop(self.canvas, self.dbstate)
1158+
self.canvas.connect("drag-begin", self.del_click_events)
11581159

11591160
def add_popover(self, widget, container):
11601161
"""
@@ -1474,8 +1475,6 @@ def populate(self, active_person):
14741475
if self.uistate.window.get_window().is_visible():
14751476
process_pending_events()
14761477

1477-
self.dnd.stop()
1478-
14791478
self.clear()
14801479
self.active_person_handle = active_person
14811480

@@ -1606,7 +1605,8 @@ def button_press(self, item, _target, event):
16061605
return False
16071606

16081607
button = event.get_button()[1]
1609-
if button == 1 or button == 2:
1608+
if button in (1, 2):
1609+
self.dnd.enable_dnd(False)
16101610
window = self.canvas.get_parent().get_window()
16111611
window.set_cursor(Gdk.Cursor.new(Gdk.CursorType.FLEUR))
16121612
self._last_x = event.x_root
@@ -1626,14 +1626,14 @@ def button_release(self, item, target, event):
16261626
"""
16271627
Exit from scroll mode when button release.
16281628
"""
1629-
self.dnd.stop()
16301629
button = event.get_button()[1]
16311630
if((button == 1 or button == 2) and
16321631
event.type == getattr(Gdk.EventType, "BUTTON_RELEASE")):
16331632

16341633
self.motion_notify_event(item, target, event)
16351634
self.canvas.get_parent().get_window().set_cursor(None)
16361635
self._in_move = False
1636+
self.dnd.enable_dnd(True)
16371637
return True
16381638
return False
16391639

@@ -1655,29 +1655,6 @@ def motion_notify_event(self, _item, _target, event):
16551655
(event.y_root - self._last_y) * scale_coef)
16561656
self.vadjustment.set_value(new_y)
16571657
return True
1658-
1659-
if not (event.type == Gdk.EventType.MOTION_NOTIFY):
1660-
return False
1661-
1662-
if self.dnd.is_ready():
1663-
# start drag when cursor moved more then 5
1664-
# to separate it from simple click
1665-
if ((abs(self._last_x - event.x_root) > 5)
1666-
or (abs(self._last_y - event.y_root) > 5)):
1667-
self.uistate.set_busy_cursor(False)
1668-
# Remove all single click events
1669-
for click_item in self.click_events:
1670-
if not click_item.is_destroyed():
1671-
GLib.source_remove(click_item.get_id())
1672-
self.click_events.clear()
1673-
1674-
# translate to drag_widget coords
1675-
scale_coef = self.canvas.get_scale()
1676-
x = self._last_x * scale_coef - self.hadjustment.get_value()
1677-
y = self._last_y * scale_coef - self.vadjustment.get_value()
1678-
1679-
self.dnd.start_drag(x, y, event)
1680-
16811658
return False
16821659

16831660
def set_zoom(self, value):
@@ -1688,6 +1665,15 @@ def set_zoom(self, value):
16881665
self.view._config.set('interface.graphview-scale', value)
16891666
self.canvas.set_scale(value / self.transform_scale)
16901667

1668+
def del_click_events(self, *args):
1669+
"""
1670+
Remove all single click events.
1671+
"""
1672+
for click_item in self.click_events:
1673+
if not click_item.is_destroyed():
1674+
GLib.source_remove(click_item.get_id())
1675+
self.click_events.clear()
1676+
16911677
def select_node(self, item, target, event):
16921678
"""
16931679
Perform actions when a node is clicked.
@@ -1704,11 +1690,7 @@ def select_node(self, item, target, event):
17041690

17051691
# perform double click on node by left mouse button
17061692
if event.type == getattr(Gdk.EventType, "DOUBLE_BUTTON_PRESS"):
1707-
# Remove all single click events
1708-
for click_item in self.click_events:
1709-
if not click_item.is_destroyed():
1710-
GLib.source_remove(click_item.get_id())
1711-
self.click_events.clear()
1693+
self.del_click_events()
17121694
if button == 1 and node_class == 'node':
17131695
GLib.idle_add(self.actions.edit_person, None, handle)
17141696
return True
@@ -1719,11 +1701,8 @@ def select_node(self, item, target, event):
17191701
if event.type != getattr(Gdk.EventType, "BUTTON_PRESS"):
17201702
return False
17211703

1722-
if button == 1 and node_class: # left mouse
1723-
# set drag mode, it will be applied on motion event
1724-
self.dnd.set_ready(node_class, handle)
1725-
self._last_x = event.x_root
1726-
self._last_y = event.y_root
1704+
if button == 1 and node_class in ('node', 'familynode'):
1705+
self.dnd.set_target(node_class, handle)
17271706

17281707
if button == 1 and node_class == 'node': # left mouse
17291708
if handle == self.active_person_handle:

0 commit comments

Comments
 (0)