80 lines
2.8 KiB
Python
80 lines
2.8 KiB
Python
import os, gi
|
|
|
|
gi.require_version('Gdk', '3.0')
|
|
|
|
from gi.repository import Gdk
|
|
from gi.repository import GObject
|
|
|
|
|
|
class Dragging:
|
|
def __init__(self):
|
|
# higher values make movement more performant
|
|
# lower values make movement smoother
|
|
self.SENSITIVITY = 1
|
|
self.desktop = None
|
|
self.EvMask = Gdk.EventMask.BUTTON_PRESS_MASK | Gdk.EventMask.BUTTON1_MOTION_MASK
|
|
self.offsetx = 0
|
|
self.offsety = 0
|
|
self.px = 0
|
|
self.py = 0
|
|
self.maxx = 0
|
|
self.maxy = 0
|
|
|
|
def connectEvents(self, desktop, widget):
|
|
self.desktop = desktop
|
|
widget.set_events(self.EvMask)
|
|
widget.connect("button_press_event", self.press_event)
|
|
widget.connect("motion_notify_event", self.draggingEvent)
|
|
widget.show()
|
|
|
|
def press_event(self, w, event):
|
|
if event.button == 1:
|
|
p = w.get_parent()
|
|
# offset == distance of parent widget from edge of screen ...
|
|
self.offsetx, self.offsety = p.get_window().get_position()
|
|
# plus distance from pointer to edge of widget
|
|
self.offsetx += event.x
|
|
self.offsety += event.y
|
|
# self.maxx, self.maxy both relative to the parent
|
|
# note that we're rounding down now so that these max values don't get
|
|
# rounded upward later and push the widget off the edge of its parent.
|
|
self.maxx = self.RoundDownToMultiple(p.get_allocation().width - w.get_allocation().width, self.SENSITIVITY)
|
|
self.maxy = self.RoundDownToMultiple(p.get_allocation().height - w.get_allocation().height, self.SENSITIVITY)
|
|
|
|
|
|
def draggingEvent(self, widget, event):
|
|
# x_root,x_root relative to screen
|
|
# x,y relative to parent (fixed widget)
|
|
# self.px,self.py stores previous values of x,y
|
|
|
|
# get starting values for x,y
|
|
x = event.x_root - self.offsetx
|
|
y = event.y_root - self.offsety
|
|
# make sure the potential coordinates x,y:
|
|
# 1) will not push any part of the widget outside of its parent container
|
|
# 2) is a multiple of self.SENSITIVITY
|
|
x = self.RoundToNearestMultiple(self.Max(self.Min(x, self.maxx), 0), self.SENSITIVITY)
|
|
y = self.RoundToNearestMultiple(self.Max(self.Min(y, self.maxy), 0), self.SENSITIVITY)
|
|
if x != self.px or y != self.py:
|
|
self.px = x
|
|
self.py = y
|
|
self.desktop.move(widget, x, y)
|
|
|
|
def Min(self, a, b):
|
|
if b < a:
|
|
return b
|
|
return a
|
|
|
|
def Max(self, a, b):
|
|
if b > a:
|
|
return b
|
|
return a
|
|
|
|
def RoundDownToMultiple(self, i, m):
|
|
return i/m*m
|
|
|
|
def RoundToNearestMultiple(self, i, m):
|
|
if i % m > m / 2:
|
|
return (i/m+1)*m
|
|
return i/m*m
|