WIP DnD, added texta area update limiters

This commit is contained in:
itdominator 2023-04-13 22:45:46 -05:00
parent ff7a492e35
commit 9730e3a75e
5 changed files with 106 additions and 8 deletions

View File

@ -8,6 +8,7 @@ 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
@ -22,6 +23,7 @@ class DragArea(Gtk.Fixed):
self._setup_styling()
self._setup_signals()
self._set_up_dnd()
self._subscribe_to_events()
self._load_widgets()
@ -30,6 +32,7 @@ class DragArea(Gtk.Fixed):
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):
@ -38,6 +41,70 @@ class DragArea(Gtk.Fixed):
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:
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()
return
if info == 80:
uris = data.get_uris()
if len(uris) == 0:
uris = data.get_text().split("\n")
for uri in uris:
gfile = None
try:
gfile = Gio.File.new_for_uri(uri)
except Exception as e:
gfile = Gio.File.new_for_path(uri)
# event_system.emit('create_view', (None, None, gfile,))
return
def _move_callback(self, widget = None, x = None, y = None):
self.move(widget.get_parent(), x, y)
@ -74,11 +141,18 @@ class DragArea(Gtk.Fixed):
self.put(wrapped_entry, 30, 30)
self.put(wrapped_date, 30, 65)
def add_or_select_widget(self, widget = None, eve = None):
dynamic_widget = DynamicWidget(self._move_callback, None, eve.x, eve.y)
self._handle_add(dynamic_widget, eve.x, eve.y)
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

View File

@ -52,7 +52,6 @@ class Page(Gtk.ScrolledWindow):
def _load_widgets(self):
self._drag_area = DragArea()
eve_box = Gtk.EventBox()
eve_box.connect("button-release-event", self._release_event)
eve_box.add(self._drag_area)

View File

@ -36,6 +36,7 @@ class Pages(Gtk.Notebook):
def _setup_signals(self):
label = self._tab_widget.get_children()[0]
self.connect("switch-page", self._switch_page_update)
self.connect("map", self._map_update)
label.connect("button-release-event", self._change_section_name)
def _load_widgets(self):
@ -85,6 +86,15 @@ class Pages(Gtk.Notebook):
path = page.get_manifest_pth().replace("MANIFEST", "")
settings.set_active_page(path)
def _map_update(self, widget = None):
path = self.get_section_pth()
settings.set_active_section(path)
page = self.get_nth_page( self.get_current_page() )
path = page.get_manifest_pth()
settings.set_active_page(path)
def _change_section_name(self, widget = None, eve = None):
if eve.button == 3: # NOTE: If right click
label = widget.get_children()[0] # NOTE: Pull from event box

View File

@ -1,4 +1,5 @@
# Python imports
import hashlib
# Lib imports
import gi
@ -16,6 +17,7 @@ class TextAreaWidget(WidgetSaveLoadController, GtkSource.View):
super(TextAreaWidget, self).__init__()
self.buffer = self.get_buffer()
self._buffer_hash = None
self._setup_styling()
self._setup_signals()
@ -39,7 +41,15 @@ class TextAreaWidget(WidgetSaveLoadController, GtkSource.View):
...
def _key_released(self, widget = None, eve = None):
self.get_parent().save_needed = True
if eve.type == 9:
_hash = self.get_hash( self.get_buffer_text() )
if _hash == self._buffer_hash:
return
if (eve.keyval >= 32 or eve.keyval <= 126) or (eve.keyval in [65288, 65289, 65293]):
self.get_parent().save_needed = True
self._buffer_hash = _hash
def get_buffer_text(self):
start, end = self.buffer.get_start_iter(), self.buffer.get_end_iter()
@ -58,7 +68,14 @@ class TextAreaWidget(WidgetSaveLoadController, GtkSource.View):
self.load_saveable_data()
def load_saveable_data(self):
self.buffer.set_text(self.save_collection["data"])
text = self.save_collection["data"]
self._buffer_hash = self.get_hash(text)
self.buffer.set_text(text)
def get_hash(self, text):
sha = hashlib.sha1(text.encode("utf-8"))
return sha.hexdigest()
def new(self):
widget = TextAreaWidget()

View File

@ -1,8 +1,6 @@
# Python imports
# Lib imports
import gi
from gi.repository import GLib
# Application imports