Continue with wx->gtk portage.

Callbacks for mouse events are "almost" working
in this commit.
This commit is contained in:
Sylvain Tricot 2021-01-25 13:59:03 +01:00
parent b8876a7632
commit f70b1af2f3
1 changed files with 114 additions and 30 deletions

View File

@ -1,8 +1,8 @@
# -*- encoding: utf-8 -*- # -*- encoding: utf-8 -*-
# vim: set fdm=indent ts=2 sw=2 sts=2 et tw=80 cc=+1 mouse=a nu : #
# import wx # import wx
import numpy as np import numpy as np
from threading import Timer
# from time import clock # from time import clock
# import copy # import copy
@ -11,7 +11,8 @@ import wx.lib.wxcairo
import gi import gi
gi.require_version("Gtk", "3.0") gi.require_version("Gtk", "3.0")
from gi.repository import GLib, Gio, Gtk, Gdk from gi.repository import GLib, Gio, Gtk, Gdk, GObject
GObject.threads_init()
# import ase # import ase
from ase.data import covalent_radii from ase.data import covalent_radii
@ -101,16 +102,22 @@ class ClusterViewer(Gtk.Window):
#self.Bind(wx.EVT_TIMER, self.__evt_timer_cb, self.timer) #self.Bind(wx.EVT_TIMER, self.__evt_timer_cb, self.timer)
self.drawing_area.add_events(Gdk.EventMask.SCROLL_MASK | self.drawing_area.add_events(Gdk.EventMask.SCROLL_MASK |
Gdk.EventMask.POINTER_MOTION_MASK | #Gdk.EventMask.POINTER_MOTION_MASK |
Gdk.EventMask.BUTTON1_MOTION_MASK) Gdk.EventMask.BUTTON_PRESS_MASK |
Gdk.EventMask.BUTTON_RELEASE_MASK |
Gdk.EventMask.BUTTON1_MOTION_MASK |
Gdk.EventMask.BUTTON3_MOTION_MASK)
self.connect("size-allocate", self.__evt_size_cb) self.connect("size-allocate", self.__evt_size_cb)
self.drawing_area.connect("draw", self.__evt_draw_cb) self.drawing_area.connect("draw", self.__evt_draw_cb)
self.drawing_area.connect("scroll-event", self.__evt_mousewheel_cb) self.drawing_area.connect("scroll-event", self.__evt_mousewheel_cb)
self.drawing_area.connect("motion-notify-event", self.__evt_motion_cb) self.drawing_area.connect("motion-notify-event", self.__evt_motion_cb)
#self.drawing_area.connect("button-press-event", self.__evt_press_cb) self.drawing_area.connect("button-press-event", self.__evt_press_cb)
self.drawing_area.connect("button-release-event", self.__evt_release_cb)
#self.drawing_area.connect("button-release-event", self.__evt_release_cb) #self.drawing_area.connect("button-release-event", self.__evt_release_cb)
self.timer_id = None
def show_emitter(self, show=True, alpha=0.25): def show_emitter(self, show=True, alpha=0.25):
_opts = self.sprites_opts.copy() _opts = self.sprites_opts.copy()
if show: if show:
@ -203,8 +210,8 @@ class ClusterViewer(Gtk.Window):
self.translation_matrix[-1, (0, 1)] = (x, y) self.translation_matrix[-1, (0, 1)] = (x, y)
self.update_projection_matrix() self.update_projection_matrix()
def select_atoms(self, x, y, w=None, h=None, append=False, def select_atoms(self, x, y, w=None, h=None, append=False, toggle=False):
toggle=False): print("Append=", append, "Toggle=", toggle)
selection = np.array([]) selection = np.array([])
if w is None and h is None: if w is None and h is None:
# get the projections # get the projections
@ -237,10 +244,10 @@ class ClusterViewer(Gtk.Window):
selection = p[:, -1].astype(int) selection = p[:, -1].astype(int)
if toggle: if toggle:
#print(self.selection) print(self.selection)
# whether atoms in the current selection were previously selected # whether atoms in the current selection were previously selected
i = np.in1d(self.selection, selection) i = np.in1d(self.selection, selection)
#print(i) print(i)
self.selection = self.selection[np.invert(i)] self.selection = self.selection[np.invert(i)]
if append: if append:
@ -261,8 +268,9 @@ class ClusterViewer(Gtk.Window):
self.update_drawing() self.update_drawing()
def __evt_size_cb(self, widget, data): def __evt_size_cb(self, widget, data):
#self.timer.Stop() #self.timer.cancel()
#self.timer.Start(self.refresh_delay) #self.timer.start()
self._postpone_drawing()
size = self.get_size() size = self.get_size()
self.back_buffer = cairo.ImageSurface(cairo.FORMAT_RGB24, *size) self.back_buffer = cairo.ImageSurface(cairo.FORMAT_RGB24, *size)
self.create_background_sprite(*size) self.create_background_sprite(*size)
@ -283,6 +291,53 @@ class ClusterViewer(Gtk.Window):
if event.AltDown(): if event.AltDown():
self.mode |= self.MODE_SELECTION_TOGGLE self.mode |= self.MODE_SELECTION_TOGGLE
def __evt_press_cb(self, widget, event):
if event.button == 1:
print("press_cb", event.state)
self.mx = event.x
self.my = event.y
self.capture_screen()
if event.state & Gdk.ModifierType.CONTROL_MASK:
self.mode |= self.MODE_SELECTION
if event.state & Gdk.ModifierType.SHIFT_MASK:
self.mode |= self.MODE_SELECTION_APPEND
if event.state & Gdk.ModifierType.MOD1_MASK:
self.mode |= self.MODE_SELECTION_TOGGLE
def __evt_release_cb(self, widget, event):
if event.button not in (1,3):
return
if self.mode & self.MODE_SELECTION:
self.mode ^= self.MODE_SELECTION
# search for atoms in the selection box
x, y = event.x, event.y
w = h = None
if self.mode & self.MODE_SELECTION_BOX:
self.mode ^= self.MODE_SELECTION_BOX
x, y, w, h = self.selection_box
append = False
if self.mode & self.MODE_SELECTION_APPEND:
self.mode ^= self.MODE_SELECTION_APPEND
append = True
toggle = False
if self.mode & self.MODE_SELECTION_TOGGLE:
self.mode ^= self.MODE_SELECTION_TOGGLE
toggle = True
self.select_atoms(x, y, w, h, append=append, toggle=toggle)
if self.mode == self.MODE_TRANSLATION:
self.mode ^= self.MODE_TRANSLATION
if self.mode & self.MODE_ROTATION:
self.mode ^= self.MODE_ROTATION
self.update_drawing(light=False)
def __evt_left_up_cb(self, event): def __evt_left_up_cb(self, event):
if self.mode & self.MODE_SELECTION: if self.mode & self.MODE_SELECTION:
self.mode ^= self.MODE_SELECTION self.mode ^= self.MODE_SELECTION
@ -351,9 +406,12 @@ class ClusterViewer(Gtk.Window):
self.update_drawing() self.update_drawing()
def __evt_motion_cb(self, widget, event): def __evt_motion_cb(self, widget, event):
#self.timer.Stop() #self.timer.cancel()
#self.timer.Start(self.refresh_delay) #self.timer.start()
if True:#event.state & Gdk.ModifierType.BUTTON1_MASK: self._postpone_drawing()
self._update_flag = True
GLib.timeout_add(self.refresh_delay, self.update_drawing, False)
if event.state & Gdk.ModifierType.BUTTON1_MASK:
print("motion cb...", bool(event.state & print("motion cb...", bool(event.state &
Gdk.ModifierType.BUTTON1_MASK)) Gdk.ModifierType.BUTTON1_MASK))
mx, my = event.x, event.y mx, my = event.x, event.y
@ -374,11 +432,11 @@ class ClusterViewer(Gtk.Window):
self.translate_atoms(self.ox, self.oy) self.translate_atoms(self.ox, self.oy)
self.update_drawing() self.update_drawing()
#elif event.RightIsDown(): #elif event.RightIsDown():
elif event.state & Gdk.ModifierType.BUTTON2_MASK: elif event.state & Gdk.ModifierType.BUTTON3_MASK:
self.mode = self.MODE_ROTATION self.mode = self.MODE_ROTATION
theta = 2. * (float(self.scale0) / self.scale) theta = 2. * (float(self.scale0) / self.scale)
theta = max(1., theta) theta = max(1., theta)
mx, my = event.GetPosition() mx, my = event.x, event.y
dx, dy = (mx - self.mx, my - self.my) dx, dy = (mx - self.mx, my - self.my)
self.mx, self.my = (mx, my) self.mx, self.my = (mx, my)
@ -433,8 +491,9 @@ class ClusterViewer(Gtk.Window):
else: else:
#rot = event.GetWheelRotation() #rot = event.GetWheelRotation()
rot = event.direction rot = event.direction
#self.timer.Stop() #self.timer.cancel()
#self.timer.Start(self.refresh_delay) #self.timer.start()
self._postpone_drawing()
if rot == Gdk.ScrollDirection.UP: if rot == Gdk.ScrollDirection.UP:
factor = self.scale * 1.1 factor = self.scale * 1.1
im_factor = 1 * 1.1 im_factor = 1 * 1.1
@ -445,6 +504,29 @@ class ClusterViewer(Gtk.Window):
self.scale_atoms(factor) self.scale_atoms(factor)
self.update_drawing() self.update_drawing()
def target_fn(self):
print("Timer function!!")
return True
def _postpone_drawing(self):
if self.timer_id:
GLib.source_remove(self.timer_id)
self.timer_id = GLib.timeout_add(self.refresh_delay,
self.update_drawing, False)
def __postpone_drawing(self):
return
try:
self.timer.cancel()
except:
#self.timer = Timer(self.refresh_delay, self.update_drawing,
# kwargs={'light_mode': False})
self.timer = Timer(self.refresh_delay, self.target_fn)
self.timer.start()
print("Timer created")
def capture_screen(self): def capture_screen(self):
# get size of screen # get size of screen
w, h = self.get_size() w, h = self.get_size()
@ -997,6 +1079,7 @@ class ClusterViewer(Gtk.Window):
allocation = self.drawing_area.get_allocation() allocation = self.drawing_area.get_allocation()
self.drawing_area.queue_draw_area(allocation.x, allocation.y, self.drawing_area.queue_draw_area(allocation.x, allocation.y,
allocation.width, allocation.height) allocation.width, allocation.height)
return False
def swap_buffers(self): def swap_buffers(self):
if self.back_buffer: if self.back_buffer:
@ -1022,6 +1105,7 @@ if __name__ == "__main__":
import wx import wx
MgO = bulk('MgO', crystalstructure='rocksalt', a=4.21, cubic=True) MgO = bulk('MgO', crystalstructure='rocksalt', a=4.21, cubic=True)
MgO = MgO.repeat((10,10,10))
#view(MgO) #view(MgO)
#app = wx.App(False) #app = wx.App(False)