Coherence/src/core/widgets/drag_area_widget.py

164 lines
6.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Python imports
# Lib imports
import gi
gi.require_version('Gtk', '3.0')
gi.require_version('Gdk', '3.0')
gi.require_version('GtkSource', '4')
from gi.repository import Gtk
from gi.repository import Gdk
from gi.repository import GtkSource
from gi.repository import Gio
# Application imports
from .template.dynamic_widget_template import DynamicWidget
class DragArea(Gtk.Fixed):
def __init__(self):
super(DragArea, self).__init__()
self._children_content = []
self._setup_styling()
self._setup_signals()
self._set_up_dnd()
self._subscribe_to_events()
self._load_widgets()
def _setup_styling(self):
self.set_size_request(1800, 1800)
def _setup_signals(self):
self.connect("drag-data-received", self._on_drag_data_received)
...
def _subscribe_to_events(self):
...
def _load_widgets(self):
...
def _set_up_dnd(self):
# https://python-gtk-3-tutorial.readthedocs.io/en/latest/drag_and_drop.html
# https://www.openshot.org/blog/2008/09/12/drag-drop-with-gtk-and-python/
# Gtk.DestDefaults.MOTION - This checks if the drag matches this widget's list of possible targets and actions, then calls the drag_status() as appropriate.
# Gtk.DestDefaults.HIGHLIGHT - This draws a highlight on this widget as long as a drag is over this widget
# Gtk.DestDefaults.DROP - When a drop occurs, if the drag matches this widget's list of possible targets and actions call drag_get_data() on behalf of the widget. Whether or not the drop is successful, call drag_finish(). If the action was a move and the drag was successful, then TRUE will be passed for the delete parameter to drag_finish().
# Gtk.DestDefaults.ALL - If set, specifies that all default actions should be taken
flags = Gtk.DestDefaults.ALL
# The target is a list of tuples containing target information that is human-understandable descriptions of the data type.
# If TargetFlags set to 0, it means there are no constraints.
# Gtk.TargetFlags.SAME_APP (1) - The target will only be selected for drags within a single application.
# Gtk.TargetFlags.SAME_WIDGET (2) - The target will only be selected for drags within a single widget.
# Gtk.TargetFlags.OTHER_APP (4) - The target will not be selected for drags within a single application
# Gtk.TargetFlags.OTHER_WIDGET (8) - The target will not be selected for drags withing a single widget.
# A random id for the target types. Note: Can be used in code to determin action flow
PLAIN_TEXT_TARGET_TYPE = 70
URI_TARGET_TYPE = 80
text_target = Gtk.TargetEntry.new('text/plain', Gtk.TargetFlags(0), PLAIN_TEXT_TARGET_TYPE)
uri_target = Gtk.TargetEntry.new('text/uri-list', Gtk.TargetFlags(0), URI_TARGET_TYPE)
targets = [ uri_target, text_target ]
# The actions argument is a bitmask of or a combination of one or more of the following values
# Gdk.DragAction.COPY - data provided by the source will be copied to the destination widget.
# Gdk.DragAction.MOVE - data provided by the source will be moved to the destination widget.
# Gdk.DragAction.LINK - the destination widget will create a link to the provided data, rather than copy its contents.
# Gdk.DragAction.PRIVATE - the destination widget is free to do anything with the copy of the data provided.
# Gdk.DragAction.ASK - allows the destination widget to ask the user which action should be performed.
action = Gdk.DragAction.COPY
# Set the app to allow drops from any type of file. Supposedly works but doesn't for me.
# self.drawArea.drag_dest_set(7, [], 2)
self.drag_dest_set(flags, targets, action)
def _on_drag_data_received(self, widget, drag_context, _x, _y, data, info, time):
if info == 70:
self._load_dnd_text(data, _x, _y)
return
if info == 80:
self._load_dnd_files(data, _x, _y)
return
def _load_dnd_text(self, data, _x, _y):
event_system.emit("set_widget_type", "TextAreaWidget")
dynamic_widget = self.add_or_select_widget(x = _x, y = _y)
body = dynamic_widget.get_body()
body.buffer.set_text(data.get_text())
dynamic_widget.save()
def _load_dnd_files(self, data, _x, _y):
uris = data.get_uris()
if len(uris) == 0:
uris = data.get_text().split("\n")
for uri in uris:
event_system.emit("set_widget_type", "FileWidget")
dynamic_widget = self.add_or_select_widget(x = _x, y = _y)
dynamic_widget.get_body().set_file_path(uri)
dynamic_widget.save()
_y += 85
def _move_callback(self, widget = None, x = None, y = None):
self.move(widget.get_parent(), x, y)
def wrap_widget_in_trap(self, widget):
eve_trap_box = Gtk.EventBox()
eve_trap_box.connect("button-release-event", self._release_event)
eve_trap_box.add(widget)
eve_trap_box.show()
return eve_trap_box
def _release_event(self, widget = None, eve = None):
return True
def _handle_add(self, widget, x, y):
widget_wrapped = self.wrap_widget_in_trap(widget)
self._children_content.append(widget)
self.put(widget_wrapped, x, y)
def add_fixed_base_widgets(self, name = None, date = None, update_header_callback = None):
entry = Gtk.Entry(text = name)
wrapped_entry = self.wrap_widget_in_trap( entry )
date_label = Gtk.Label(label = date)
wrapped_date = self.wrap_widget_in_trap( date_label )
ctx = entry.get_style_context()
ctx.add_class("drag-area-title")
entry.connect("changed", update_header_callback)
entry.set_width_chars(25)
entry.set_max_length(25)
self.put(wrapped_entry, 30, 30)
self.put(wrapped_date, 30, 65)
def add_or_select_widget(self, widget = None, eve = None, x = None, y = None):
if eve:
x = eve.x
y = eve.y
dynamic_widget = DynamicWidget(self._move_callback, None, x, y)
self._handle_add(dynamic_widget, x, y)
dynamic_widget.save()
return dynamic_widget
def load_path_to_widget(self, path):
dynamic_widget = DynamicWidget(self._move_callback, path)
x = dynamic_widget.get_header()._current_x
y = dynamic_widget.get_header()._current_y
self._handle_add(dynamic_widget, x, y)