Continue with wx->gtk portage.
Callbacks for mouse events are "almost" working in this commit.
This commit is contained in:
parent
b8876a7632
commit
f70b1af2f3
|
@ -1,8 +1,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 numpy as np
|
||||
from threading import Timer
|
||||
# from time import clock
|
||||
# import copy
|
||||
|
||||
|
@ -11,7 +11,8 @@ import wx.lib.wxcairo
|
|||
|
||||
import gi
|
||||
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
|
||||
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.drawing_area.add_events(Gdk.EventMask.SCROLL_MASK |
|
||||
Gdk.EventMask.POINTER_MOTION_MASK |
|
||||
Gdk.EventMask.BUTTON1_MOTION_MASK)
|
||||
#Gdk.EventMask.POINTER_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.drawing_area.connect("draw", self.__evt_draw_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("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.timer_id = None
|
||||
|
||||
def show_emitter(self, show=True, alpha=0.25):
|
||||
_opts = self.sprites_opts.copy()
|
||||
if show:
|
||||
|
@ -123,11 +130,11 @@ class ClusterViewer(Gtk.Window):
|
|||
"""
|
||||
Attach an Atoms object to the view.
|
||||
|
||||
This will translate the model to the center of mass, move the model
|
||||
center to the center of screen and adjust the scale to the largest
|
||||
This will translate the model to the center of mass, move the model
|
||||
center to the center of screen and adjust the scale to the largest
|
||||
dimension of the model
|
||||
|
||||
:param rescale: if True, the zoom is computed to view the atoms; if
|
||||
:param rescale: if True, the zoom is computed to view the atoms; if
|
||||
False, a fixed zoom value is used
|
||||
"""
|
||||
if atoms is None:
|
||||
|
@ -149,7 +156,7 @@ class ClusterViewer(Gtk.Window):
|
|||
self.atoms_center_of_mass = atoms.get_center_of_mass()
|
||||
# get the largest dimension
|
||||
p = atoms.get_positions()
|
||||
self.atoms_largest_dimension = np.max(np.amax(p, axis=0) -
|
||||
self.atoms_largest_dimension = np.max(np.amax(p, axis=0) -
|
||||
np.amin(p, axis=0))
|
||||
if self.atoms_largest_dimension == 0:
|
||||
self.atoms_largest_dimension = 1.0
|
||||
|
@ -203,8 +210,8 @@ class ClusterViewer(Gtk.Window):
|
|||
self.translation_matrix[-1, (0, 1)] = (x, y)
|
||||
self.update_projection_matrix()
|
||||
|
||||
def select_atoms(self, x, y, w=None, h=None, append=False,
|
||||
toggle=False):
|
||||
def select_atoms(self, x, y, w=None, h=None, append=False, toggle=False):
|
||||
print("Append=", append, "Toggle=", toggle)
|
||||
selection = np.array([])
|
||||
if w is None and h is None:
|
||||
# get the projections
|
||||
|
@ -237,10 +244,10 @@ class ClusterViewer(Gtk.Window):
|
|||
selection = p[:, -1].astype(int)
|
||||
|
||||
if toggle:
|
||||
#print(self.selection)
|
||||
print(self.selection)
|
||||
# whether atoms in the current selection were previously selected
|
||||
i = np.in1d(self.selection, selection)
|
||||
#print(i)
|
||||
print(i)
|
||||
self.selection = self.selection[np.invert(i)]
|
||||
|
||||
if append:
|
||||
|
@ -261,8 +268,9 @@ class ClusterViewer(Gtk.Window):
|
|||
self.update_drawing()
|
||||
|
||||
def __evt_size_cb(self, widget, data):
|
||||
#self.timer.Stop()
|
||||
#self.timer.Start(self.refresh_delay)
|
||||
#self.timer.cancel()
|
||||
#self.timer.start()
|
||||
self._postpone_drawing()
|
||||
size = self.get_size()
|
||||
self.back_buffer = cairo.ImageSurface(cairo.FORMAT_RGB24, *size)
|
||||
self.create_background_sprite(*size)
|
||||
|
@ -283,6 +291,53 @@ class ClusterViewer(Gtk.Window):
|
|||
if event.AltDown():
|
||||
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):
|
||||
if self.mode & self.MODE_SELECTION:
|
||||
self.mode ^= self.MODE_SELECTION
|
||||
|
@ -351,9 +406,12 @@ class ClusterViewer(Gtk.Window):
|
|||
self.update_drawing()
|
||||
|
||||
def __evt_motion_cb(self, widget, event):
|
||||
#self.timer.Stop()
|
||||
#self.timer.Start(self.refresh_delay)
|
||||
if True:#event.state & Gdk.ModifierType.BUTTON1_MASK:
|
||||
#self.timer.cancel()
|
||||
#self.timer.start()
|
||||
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 &
|
||||
Gdk.ModifierType.BUTTON1_MASK))
|
||||
mx, my = event.x, event.y
|
||||
|
@ -374,11 +432,11 @@ class ClusterViewer(Gtk.Window):
|
|||
self.translate_atoms(self.ox, self.oy)
|
||||
self.update_drawing()
|
||||
#elif event.RightIsDown():
|
||||
elif event.state & Gdk.ModifierType.BUTTON2_MASK:
|
||||
elif event.state & Gdk.ModifierType.BUTTON3_MASK:
|
||||
self.mode = self.MODE_ROTATION
|
||||
theta = 2. * (float(self.scale0) / self.scale)
|
||||
theta = max(1., theta)
|
||||
mx, my = event.GetPosition()
|
||||
mx, my = event.x, event.y
|
||||
dx, dy = (mx - self.mx, my - self.my)
|
||||
self.mx, self.my = (mx, my)
|
||||
|
||||
|
@ -433,8 +491,9 @@ class ClusterViewer(Gtk.Window):
|
|||
else:
|
||||
#rot = event.GetWheelRotation()
|
||||
rot = event.direction
|
||||
#self.timer.Stop()
|
||||
#self.timer.Start(self.refresh_delay)
|
||||
#self.timer.cancel()
|
||||
#self.timer.start()
|
||||
self._postpone_drawing()
|
||||
if rot == Gdk.ScrollDirection.UP:
|
||||
factor = self.scale * 1.1
|
||||
im_factor = 1 * 1.1
|
||||
|
@ -445,6 +504,29 @@ class ClusterViewer(Gtk.Window):
|
|||
self.scale_atoms(factor)
|
||||
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):
|
||||
# get size of screen
|
||||
w, h = self.get_size()
|
||||
|
@ -514,7 +596,7 @@ class ClusterViewer(Gtk.Window):
|
|||
return surface, overlay
|
||||
|
||||
for i, a in enumerate(atom_numbers):
|
||||
surface, overlay = create_surface(a,
|
||||
surface, overlay = create_surface(a,
|
||||
alpha=self.sprites_opts['alpha'],
|
||||
glow=self.sprites_opts['glow'])
|
||||
atom_surfaces[0, i] = surface
|
||||
|
@ -565,7 +647,7 @@ class ClusterViewer(Gtk.Window):
|
|||
self.atom_surfaces = atom_surfaces
|
||||
try:
|
||||
absorber_number = self.atoms[self.atoms.info['absorber']].number
|
||||
self.absorber_surface = create_surface(absorber_number, alpha=1,
|
||||
self.absorber_surface = create_surface(absorber_number, alpha=1,
|
||||
glow=True)
|
||||
except:
|
||||
self.atoms.info['absorber'] = -1
|
||||
|
@ -622,10 +704,10 @@ class ClusterViewer(Gtk.Window):
|
|||
@classmethod
|
||||
def create_v2p_matrix(cls, left, right, bottom, top, near, far):
|
||||
"""
|
||||
creates the matrix that transforms coordinates from view space (space
|
||||
creates the matrix that transforms coordinates from view space (space
|
||||
defined by the bounding box passed as argument) to projection space
|
||||
|
||||
this transformation is a scale and offset that maps [left; right],
|
||||
this transformation is a scale and offset that maps [left; right],
|
||||
[bottom; top], [near; far] to [-1;1], [-1;1], [0;1]
|
||||
"""
|
||||
v2p_matrix = np.eye(4) * -1
|
||||
|
@ -685,12 +767,12 @@ class ClusterViewer(Gtk.Window):
|
|||
scalebar_bb_width = 200
|
||||
scalebar_bb_height = 20
|
||||
ctx.set_source_rgba(0., 0., 0., 0.7)
|
||||
ctx.rectangle(x + w - scalebar_bb_width - 6, h - scalebar_bb_height - 6,
|
||||
ctx.rectangle(x + w - scalebar_bb_width - 6, h - scalebar_bb_height - 6,
|
||||
scalebar_bb_width, scalebar_bb_height)
|
||||
ctx.fill()
|
||||
|
||||
ctx.set_source_rgb(1, 1, 1)
|
||||
ctx.rectangle(x + w - scalebar_bb_width, h - scalebar_bb_height, 100,
|
||||
ctx.rectangle(x + w - scalebar_bb_width, h - scalebar_bb_height, 100,
|
||||
scalebar_bb_height - 12)
|
||||
ctx.fill()
|
||||
|
||||
|
@ -890,7 +972,7 @@ class ClusterViewer(Gtk.Window):
|
|||
v2 = projections[f[3], :3] - projections[f[0], :3]
|
||||
# cross multiply them to get the normal
|
||||
n = np.cross(v2, v1)
|
||||
# If the normal z coordinate is <0, the plane is not visible, so,
|
||||
# If the normal z coordinate is <0, the plane is not visible, so,
|
||||
# draw it first, otherwise draw it last
|
||||
if n[-1] > 0:
|
||||
ind.append(i)
|
||||
|
@ -997,6 +1079,7 @@ class ClusterViewer(Gtk.Window):
|
|||
allocation = self.drawing_area.get_allocation()
|
||||
self.drawing_area.queue_draw_area(allocation.x, allocation.y,
|
||||
allocation.width, allocation.height)
|
||||
return False
|
||||
|
||||
def swap_buffers(self):
|
||||
if self.back_buffer:
|
||||
|
@ -1007,7 +1090,7 @@ class ClusterViewer(Gtk.Window):
|
|||
bitmap = wx.lib.wxcairo.BitmapFromImageSurface(back_buffer)
|
||||
dc = wx.PaintDC(self)
|
||||
dc.DrawBitmap(bitmap, 0, 0)
|
||||
|
||||
|
||||
def __evt_draw_cb(self, da, ctx):
|
||||
if self.back_buffer:
|
||||
print("Draw called.", ctx)
|
||||
|
@ -1022,6 +1105,7 @@ if __name__ == "__main__":
|
|||
import wx
|
||||
|
||||
MgO = bulk('MgO', crystalstructure='rocksalt', a=4.21, cubic=True)
|
||||
MgO = MgO.repeat((10,10,10))
|
||||
#view(MgO)
|
||||
|
||||
#app = wx.App(False)
|
||||
|
|
Loading…
Reference in New Issue