Cleaned up toolbar code, lots of work still to be done.
Does not work.
This commit is contained in:
parent
0ed180d6ab
commit
a6571d8c6b
790
system/plots.py
790
system/plots.py
|
@ -20,7 +20,7 @@ import networkx
|
||||||
import scipy
|
import scipy
|
||||||
|
|
||||||
# global active mode. Used by toolbars to communicate correct mode
|
# global active mode. Used by toolbars to communicate correct mode
|
||||||
active_mode = 'DEFAULT'
|
active_mode = 'default'
|
||||||
|
|
||||||
class ObjectTable:
|
class ObjectTable:
|
||||||
"""A 2D table of elements."""
|
"""A 2D table of elements."""
|
||||||
|
@ -245,28 +245,51 @@ class MainView (gtk.Notebook):
|
||||||
self.emit('view-changed', vf)
|
self.emit('view-changed', vf)
|
||||||
|
|
||||||
|
|
||||||
class Plot (gtk.Frame):
|
class View (gtk.Frame):
|
||||||
|
"""The base class of everything that is shown in the center view of fluents.
|
||||||
|
|
||||||
|
Most views should rather subclass Plot, which automatically handles freezing and
|
||||||
|
toolbars, and sets up matplotlib Figure and Canvas objects.
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, title):
|
def __init__(self, title):
|
||||||
gtk.Frame.__init__(self)
|
gtk.Frame.__init__(self)
|
||||||
self.title = title
|
self.title = title
|
||||||
|
self.set_shadow_type(gtk.SHADOW_NONE)
|
||||||
|
|
||||||
|
def get_toolbar(self):
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
class EmptyView (View):
|
||||||
|
"""EmptyView is shown in ViewFrames that are unused."""
|
||||||
|
def __init__(self):
|
||||||
|
View.__init__(self, 'Empty view')
|
||||||
|
label = gtk.Label('No view')
|
||||||
|
ebox = gtk.EventBox()
|
||||||
|
ebox.add(label)
|
||||||
|
self.add(ebox)
|
||||||
|
label.show()
|
||||||
|
ebox.show()
|
||||||
|
self.show()
|
||||||
|
|
||||||
|
|
||||||
|
class Plot (View):
|
||||||
|
def __init__(self, title):
|
||||||
|
View.__init__(self, title)
|
||||||
|
|
||||||
self.selection_listener = None
|
self.selection_listener = None
|
||||||
self.fig = Figure()
|
self.fig = Figure()
|
||||||
self.canvas = FigureCanvas(self.fig)
|
self.canvas = FigureCanvas(self.fig)
|
||||||
self.set_shadow_type(gtk.SHADOW_NONE)
|
|
||||||
self._background = None
|
self._background = None
|
||||||
self._sel_sensitive = True
|
self._frozen = False
|
||||||
|
self._toolbar = PlotToolbar(self)
|
||||||
self.canvas.add_events(gtk.gdk.ENTER_NOTIFY_MASK)
|
self.canvas.add_events(gtk.gdk.ENTER_NOTIFY_MASK)
|
||||||
self.current_dim = None
|
self.current_dim = None
|
||||||
|
|
||||||
def set_selection_sensitive(self,event):
|
def set_frozen(self, frozen):
|
||||||
if event:
|
"""A frozen plot will not be updated when the current selection is changed."""
|
||||||
if event.get_active():
|
self._frozen = frozen
|
||||||
logger.log('debug','Selection freezed')
|
|
||||||
self._sel_sensitive = False
|
|
||||||
else:
|
|
||||||
logger.log('debug','Selections active')
|
|
||||||
self._sel_sensitive = True
|
|
||||||
|
|
||||||
|
|
||||||
def get_title(self):
|
def get_title(self):
|
||||||
return self.title
|
return self.title
|
||||||
|
@ -280,9 +303,12 @@ class Plot (gtk.Frame):
|
||||||
3.) the selections dim_name is the plot's dimension.
|
3.) the selections dim_name is the plot's dimension.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if not self._sel_sensitive or not self.get_property('visible') or self.current_dim!=dim_name:
|
if not self._sel_sensitive \
|
||||||
|
or not self.get_property('visible') \
|
||||||
|
or self.current_dim != dim_name:
|
||||||
print "Ignored a selection changed call in plot: %s" %self.get_title()
|
print "Ignored a selection changed call in plot: %s" %self.get_title()
|
||||||
return
|
return
|
||||||
|
|
||||||
print "Setting current selection in: %s " %self.get_title()
|
print "Setting current selection in: %s " %self.get_title()
|
||||||
self.set_current_selection(selection)
|
self.set_current_selection(selection)
|
||||||
|
|
||||||
|
@ -295,20 +321,6 @@ class Plot (gtk.Frame):
|
||||||
"""
|
"""
|
||||||
self.selection_listener = listener
|
self.selection_listener = listener
|
||||||
|
|
||||||
def get_toolbar(self):
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
class EmptyView (Plot):
|
|
||||||
def __init__(self):
|
|
||||||
Plot.__init__(self, 'Empty view')
|
|
||||||
label = gtk.Label('No view')
|
|
||||||
ebox = gtk.EventBox()
|
|
||||||
ebox.add(label)
|
|
||||||
self.add(ebox)
|
|
||||||
label.show()
|
|
||||||
ebox.show()
|
|
||||||
self.show()
|
|
||||||
|
|
||||||
class LineViewPlot(Plot):
|
class LineViewPlot(Plot):
|
||||||
"""Line view of current selection, no interaction
|
"""Line view of current selection, no interaction
|
||||||
|
@ -369,8 +381,7 @@ class LineViewPlot(Plot):
|
||||||
self.canvas.show()
|
self.canvas.show()
|
||||||
|
|
||||||
#FIXME: Lineview plot cannot do selections -> disable in toolbar
|
#FIXME: Lineview plot cannot do selections -> disable in toolbar
|
||||||
self._toolbar = PlotToolbar(self.canvas,self)
|
self._toolbar = PlotToolbar(self)
|
||||||
self._toolbar.chk.connect ('toggled' , self.set_selection_sensitive)
|
|
||||||
self.canvas.mpl_connect('resize_event', self.clear_background)
|
self.canvas.mpl_connect('resize_event', self.clear_background)
|
||||||
|
|
||||||
|
|
||||||
|
@ -436,12 +447,6 @@ has no color and size options."""
|
||||||
self.add(self.canvas)
|
self.add(self.canvas)
|
||||||
self.canvas.show()
|
self.canvas.show()
|
||||||
|
|
||||||
# add toolbar
|
|
||||||
self._toolbar = PlotToolbar(self.canvas, self)
|
|
||||||
self._toolbar.chk.connect ('toggled', self.set_selection_sensitive)
|
|
||||||
self._toolbar.set_property('show-arrow', False)
|
|
||||||
self._toolbar.set_select_callback(self.rectangle_select_callback)
|
|
||||||
|
|
||||||
def get_toolbar(self):
|
def get_toolbar(self):
|
||||||
return self._toolbar
|
return self._toolbar
|
||||||
|
|
||||||
|
@ -516,11 +521,6 @@ class ScatterPlot(Plot):
|
||||||
self.add(self.canvas)
|
self.add(self.canvas)
|
||||||
self.canvas.show()
|
self.canvas.show()
|
||||||
|
|
||||||
# create toolbar
|
|
||||||
self._toolbar = PlotToolbar(self.canvas, self)
|
|
||||||
self._toolbar.chk.connect ('toggled' , self.set_selection_sensitive)
|
|
||||||
self._toolbar.set_select_callback(self.rectangle_select_callback)
|
|
||||||
|
|
||||||
def get_toolbar(self):
|
def get_toolbar(self):
|
||||||
return self._toolbar
|
return self._toolbar
|
||||||
|
|
||||||
|
@ -620,11 +620,6 @@ class NetworkPlot(Plot):
|
||||||
# Initial draw
|
# Initial draw
|
||||||
networkx.draw_networkx(self.graph, ax=self.ax, **kw)
|
networkx.draw_networkx(self.graph, ax=self.ax, **kw)
|
||||||
|
|
||||||
# Setup toolbar
|
|
||||||
self._toolbar = PlotToolbar(self.canvas, self)
|
|
||||||
self._toolbar.chk.connect ('toggled' , self.set_selection_sensitive)
|
|
||||||
self._toolbar.set_select_callback(self.rectangle_select_callback)
|
|
||||||
|
|
||||||
def get_toolbar(self):
|
def get_toolbar(self):
|
||||||
return self._toolbar
|
return self._toolbar
|
||||||
|
|
||||||
|
@ -682,304 +677,477 @@ class NetworkPlot(Plot):
|
||||||
self.canvas.draw()
|
self.canvas.draw()
|
||||||
|
|
||||||
|
|
||||||
class PlotToolbar(NavigationToolbar2,gtk.Toolbar):
|
class PlotMode:
|
||||||
# list of toolitems to add to the toolbar, format is:
|
"""A PlotMode object corresponds to a mouse mode in a plot.
|
||||||
# text, tooltip_text, image_file, callback(str)
|
|
||||||
toolitems = (
|
|
||||||
('Home', 'Reset original view', 'home.png', 'home'),
|
|
||||||
#('Back', 'Back to previous view','back.png', 'back'),
|
|
||||||
#('Forward', 'Forward to next view','forward.png', 'forward'),
|
|
||||||
#('Subplots', 'Configure subplots','subplots.png', 'configure_subplots'),
|
|
||||||
('Save', 'Save the figure','filesave.png', 'save_figure'),
|
|
||||||
)
|
|
||||||
|
|
||||||
radiobuttons = (
|
When a mode is selected in the toolbar, the PlotMode corresponding
|
||||||
('DEFAULT', 'Default mode', 'cursor.png', 'default'),
|
to the toolbar button is activated by calling setup(ax) for the axis
|
||||||
('PAN', 'Pan axes with left mouse, zoom with right', 'move.png', 'pan'),
|
system ax.
|
||||||
('ZOOM', 'Zoom to rectangle','zoom_to_rect.png', 'zoom'),
|
"""
|
||||||
('SELECT', 'Select within rectangle', 'select.png', 'select'),
|
def __init__(self, name, tooltip, image_file):
|
||||||
)
|
self.name = name
|
||||||
|
self.tooltip = tooltip
|
||||||
|
self.image_file = image_file
|
||||||
|
|
||||||
def __init__(self, canvas, plot):
|
def get_icon(self):
|
||||||
self.win = None
|
"""Returns the icon for the PlotMode"""
|
||||||
self.plot = plot
|
fname = os.path.join(fluents.ICONDIR, self.image_file)
|
||||||
gtk.Toolbar.__init__(self)
|
|
||||||
NavigationToolbar2.__init__(self, canvas)
|
|
||||||
self._idleId = 0
|
|
||||||
self._select_callback = None
|
|
||||||
canvas.connect('enter-notify-event', self.on_enter_notify)
|
|
||||||
|
|
||||||
def _init_toolbar(self):
|
|
||||||
self.set_style(gtk.TOOLBAR_ICONS)
|
|
||||||
self.tooltips = gtk.Tooltips()
|
|
||||||
self._states = {}
|
|
||||||
self._selector = None
|
|
||||||
self.set_property('show-arrow', False)
|
|
||||||
basedir = fluents.ICONDIR
|
|
||||||
|
|
||||||
# setup base buttons
|
|
||||||
for text, tooltip_text, image_file, callback in self.toolitems:
|
|
||||||
if text is None:
|
|
||||||
self.insert(gtk.SeparatorToolItem(), -1 )
|
|
||||||
continue
|
|
||||||
fname = os.path.join(basedir, image_file)
|
|
||||||
image = gtk.Image()
|
image = gtk.Image()
|
||||||
image.set_from_file(fname)
|
image.set_from_file(fname)
|
||||||
tbutton = gtk.ToolButton(image, text)
|
return image
|
||||||
self.insert(tbutton, -1)
|
|
||||||
tbutton.connect('clicked', getattr(self, callback))
|
|
||||||
tbutton.set_tooltip(self.tooltips, tooltip_text, 'Private')
|
|
||||||
|
|
||||||
self.insert(gtk.SeparatorToolItem(), -1)
|
def activate(self, canvas):
|
||||||
|
pass
|
||||||
|
|
||||||
# mode/state buttons
|
def deactivate(self):
|
||||||
rbutton = None
|
pass
|
||||||
for text,tooltip_text,image_file,callback in self.radiobuttons:
|
|
||||||
if text is None:
|
|
||||||
self.insert(gtk.SeparatorToolItem(), -1 )
|
|
||||||
continue
|
|
||||||
fname = os.path.join(basedir, image_file)
|
|
||||||
image = gtk.Image()
|
|
||||||
image.set_from_file(fname)
|
|
||||||
rbutton = gtk.RadioToolButton(rbutton)
|
|
||||||
rbutton.set_icon_widget(image)
|
|
||||||
rbutton.connect('toggled', getattr(self, callback))
|
|
||||||
rbutton.set_tooltip(self.tooltips, tooltip_text, 'Private')
|
|
||||||
self._states[text] = rbutton
|
|
||||||
self.insert(rbutton, -1)
|
|
||||||
|
|
||||||
self.insert(gtk.SeparatorToolItem(), -1)
|
|
||||||
|
|
||||||
toolitem = gtk.ToolItem()
|
|
||||||
self.insert(toolitem, -1)
|
|
||||||
self.message = gtk.Label()
|
|
||||||
toolitem.add(self.message)
|
|
||||||
|
|
||||||
self.tb_freeze = gtk.ToolItem()
|
|
||||||
self.chk = gtk.CheckButton ()
|
|
||||||
self.chk.set_label ('Freeze')
|
|
||||||
self.tb_freeze.add (self.chk)
|
|
||||||
self.tb_freeze.set_tooltip(self.tooltips, 'Freeze current selection')
|
|
||||||
self.insert(self.tb_freeze,-1)
|
|
||||||
|
|
||||||
toolitem = gtk.SeparatorToolItem()
|
|
||||||
self.insert(toolitem, -1)
|
|
||||||
|
|
||||||
self.show_all()
|
|
||||||
|
|
||||||
self.fileselect = FileChooserDialog(title='Save the figure', parent=self.win,)
|
|
||||||
|
|
||||||
|
|
||||||
def on_enter_notify(self, widget, event):
|
class DefaultPlotMode (PlotMode):
|
||||||
if self._active != active_mode:
|
def __init__(self):
|
||||||
self.set_mode(active_mode)
|
PlotMode.__init__(self, 'default', 'Default mode', 'cursor.png')
|
||||||
self.set_mode(active_mode)
|
|
||||||
|
|
||||||
def set_mode(self, active):
|
|
||||||
print "Set mode called in toolbar from: %s" %self.plot.get_title()
|
|
||||||
# if state is unkown or not set, set to default
|
|
||||||
if active == None or active not in self._states.keys():
|
|
||||||
active = 'DEFAULT'
|
|
||||||
|
|
||||||
# remove current Selector:
|
class PanPlotMode (PlotMode):
|
||||||
if self._selector != None:
|
def __init__(self):
|
||||||
# problem is ... i have mutliple selectors still connected
|
PlotMode.__init__(self, 'pan',
|
||||||
# trying to remove old selectors connections
|
'Pan axes with left mouse, zoom with right',
|
||||||
#
|
'move.png')
|
||||||
# blah
|
self._button_press = None
|
||||||
# Her Einar ...
|
self._button_release = None
|
||||||
#
|
|
||||||
self.canvas.mpl_disconnect(self._selector.onmove)
|
|
||||||
self.canvas.mpl_disconnect(self._selector.press)
|
|
||||||
self.canvas.mpl_disconnect(self._selector.release)
|
|
||||||
self.canvas.mpl_disconnect(self._selector.update_background)
|
|
||||||
print "Removing selector in: %s" %self.plot.get_title()
|
|
||||||
self._selector = None
|
|
||||||
|
|
||||||
# remove current button bindings
|
def activate(self, canvas):
|
||||||
if self._idPress != None:
|
self._button_press = self.canvas.mpl_connect(
|
||||||
self._idPress = self.canvas.mpl_disconnect(self._idPress)
|
'button_press_event', self._on_button_press)
|
||||||
self.mode = ''
|
self._button_relese = self.canvas.mpl_connect(
|
||||||
|
'button_release_event', self._on_button_release)
|
||||||
if self._idRelease != None:
|
|
||||||
self._idRelease = self.canvas.mpl_disconnect(self._idRelease)
|
|
||||||
self.mode = ''
|
|
||||||
|
|
||||||
for state, button in self._states.items():
|
|
||||||
if state != active:
|
|
||||||
continue
|
|
||||||
|
|
||||||
if state == 'SELECT':
|
|
||||||
for ax in self.canvas.figure.get_axes():
|
|
||||||
props = dict(facecolor='blue', edgecolor = 'black',
|
|
||||||
alpha=0.3, fill=True)
|
|
||||||
print "creating a selector"
|
|
||||||
self._selector = RectangleSelector(ax, self.on_select,
|
|
||||||
drawtype='box', useblit=True,
|
|
||||||
rectprops=props)
|
|
||||||
self.mode = 'Select rectangle mode'
|
|
||||||
|
|
||||||
elif state == 'PAN':
|
|
||||||
self._idPress = self.canvas.mpl_connect(
|
|
||||||
'button_press_event', self.press_pan)
|
|
||||||
self._idRelease = self.canvas.mpl_connect(
|
|
||||||
'button_release_event', self.release_pan)
|
|
||||||
self.mode = 'pan/zoom mode'
|
self.mode = 'pan/zoom mode'
|
||||||
|
|
||||||
elif state == 'ZOOM':
|
def deactivate(self):
|
||||||
self._idPress = self.canvas.mpl_connect('button_press_event', self.press_zoom)
|
if self._button_press:
|
||||||
self._idRelease = self.canvas.mpl_connect('button_release_event', self.release_zoom)
|
self.canvas.mpl_disconnect(self._button_press)
|
||||||
self.mode = 'Zoom to rect mode'
|
|
||||||
|
|
||||||
elif state == 'DEFAULT':
|
if self._button_release:
|
||||||
pass
|
self.canvas.mpl_disconnect(self._button_release)
|
||||||
|
|
||||||
|
|
||||||
|
class ZoomPlotMode (PlotMode):
|
||||||
|
def __init__(self):
|
||||||
|
PlotMode.__init__(self, 'zoom',
|
||||||
|
'Zoom to rectangle','zoom_to_rect.png')
|
||||||
|
|
||||||
|
def activate(self, canvas):
|
||||||
|
self._button_press = self.canvas.mpl_connect(
|
||||||
|
'button_press_event', self._on_button_press)
|
||||||
|
self._button_relese = self.canvas.mpl_connect(
|
||||||
|
'button_release_event', self._on_button_release)
|
||||||
|
self.mode = 'pan/zoom mode'
|
||||||
|
|
||||||
|
def deactivate(self):
|
||||||
|
if self._button_press:
|
||||||
|
self.canvas.mpl_disconnect(self._button_press)
|
||||||
|
|
||||||
|
if self._button_release:
|
||||||
|
self.canvas.mpl_disconnect(self._button_release)
|
||||||
|
|
||||||
|
|
||||||
|
class SelectPlotMode (PlotMode):
|
||||||
|
def __init__(self):
|
||||||
|
PlotMode.__init__(self, 'select',
|
||||||
|
'Select within rectangle', 'select.png')
|
||||||
|
self._selectors = []
|
||||||
|
|
||||||
|
|
||||||
|
def activate(self, canvas):
|
||||||
|
for ax in canvas.figure.get_axes():
|
||||||
|
props = dict(facecolor='blue', edgecolor = 'black',
|
||||||
|
alpha=0.3, fill=True)
|
||||||
|
|
||||||
|
rs = RectangleSelector(ax, self.on_select, drawtype='box',
|
||||||
|
useblit=True, rectprops = props)
|
||||||
|
self._selectors.append(rs)
|
||||||
|
|
||||||
|
def deactivate(self):
|
||||||
|
for sel in self.selectors:
|
||||||
|
self.canvas.mpl_disconnect(sel.onmove)
|
||||||
|
self.canvas.mpl_disconnect(sel.press)
|
||||||
|
self.canvas.mpl_disconnect(sel.release)
|
||||||
|
self.canvas.mpl_disconnect(sel.update_background)
|
||||||
|
|
||||||
|
|
||||||
|
class PlotToolbar(gtk.Toolbar):
|
||||||
|
|
||||||
|
def __init__(self, plot):
|
||||||
|
gtk.Toolbar.__init__(self)
|
||||||
|
self.plot = plot
|
||||||
|
self.canvas = plot.canvas
|
||||||
|
self._current_mode = None
|
||||||
|
self.tooltips = gtk.Tooltips()
|
||||||
|
|
||||||
|
## Maps toolbar buttons to PlotMode objects.
|
||||||
|
self._mode_buttons = {}
|
||||||
|
|
||||||
|
self.set_property('show-arrow', False)
|
||||||
|
|
||||||
|
#canvas.connect('enter-notify-event', self.on_enter_notify)
|
||||||
|
self.show()
|
||||||
|
self.add_mode(DefaultPlotMode())
|
||||||
|
self.add_mode(PanPlotMode())
|
||||||
|
self.add_mode(ZoomPlotMode())
|
||||||
|
self.add_mode(SelectPlotMode())
|
||||||
|
self.show_all()
|
||||||
|
|
||||||
|
def add_mode(self, mode):
|
||||||
|
"""Adds a new mode to the toolbar."""
|
||||||
|
|
||||||
|
if len(self._mode_buttons) > 0:
|
||||||
|
other = self._mode_buttons.keys()[0]
|
||||||
else:
|
else:
|
||||||
pass
|
other = None
|
||||||
|
|
||||||
if not button.get_active():
|
btn = gtk.RadioToolButton(other)
|
||||||
button.set_active(True)
|
btn.set_icon_widget(mode.get_icon())
|
||||||
|
btn.set_tooltip(self.tooltips, mode.tooltip, 'Private')
|
||||||
|
btn.connect('toggled', self._on_mode_toggle)
|
||||||
|
|
||||||
for a in self.canvas.figure.get_axes():
|
self._mode_buttons[btn] = mode
|
||||||
a.set_navigate_mode(self._active)
|
self.insert(btn, -1)
|
||||||
|
|
||||||
self.set_message(self.mode)
|
if self._current_mode == None:
|
||||||
|
self._current_mode = mode
|
||||||
self._active = active
|
|
||||||
# update global active_mode (for all toolbar)
|
|
||||||
globals()['active_mode'] = active
|
|
||||||
|
|
||||||
def get_mode(self):
|
def get_mode(self):
|
||||||
if self._active == None:
|
"""Returns the active mode name."""
|
||||||
return 'DEFAULT'
|
if self._current_mode:
|
||||||
return self._active
|
return self._current_mode.name
|
||||||
|
return None
|
||||||
|
|
||||||
def default(self, button):
|
def get_mode_by_name(self, mode_name):
|
||||||
"""Activates default mode"""
|
"""Returns the mode with the given name or None."""
|
||||||
if not button.get_active():
|
for m in self._mode_buttons.values():
|
||||||
return
|
if m.name == mode_name:
|
||||||
self.set_mode('DEFAULT')
|
return m
|
||||||
|
return None
|
||||||
|
|
||||||
def select(self, button):
|
def get_button(self, mode_name):
|
||||||
"""Activate select mode"""
|
"""Returns the button that corresponds to a mode name."""
|
||||||
if not button.get_active():
|
for b, m in self._mode_buttons.items():
|
||||||
return
|
if m == mode_name:
|
||||||
self.set_mode('SELECT')
|
return b
|
||||||
|
return None
|
||||||
|
|
||||||
def on_select(self,eclick, erelease):
|
def set_mode(self, mode_name):
|
||||||
'eclick and erelease are matplotlib events at press and release'
|
"""Sets a mode by name. Returns the mode or None"""
|
||||||
if self._select_callback:
|
if mode_name == self._current_mode.name:
|
||||||
print "Onselect called"
|
return None
|
||||||
self._select_callback(eclick.xdata, eclick.ydata, erelease.xdata, erelease.ydata)
|
|
||||||
|
|
||||||
def pan(self, button):
|
if self._current_mode:
|
||||||
"""Activate the pan/zoom tool. pan with left button, zoom with right"""
|
self._current_mode.deactivate()
|
||||||
if not button.get_active():
|
|
||||||
return
|
|
||||||
self.set_mode('PAN')
|
|
||||||
|
|
||||||
def zoom(self, button):
|
new_mode = self.get_mode_by_name(mode_name)
|
||||||
"""Activate zoom to rect mode"""
|
if new_mode:
|
||||||
if not button.get_active():
|
new_mode.activate(self.canvas)
|
||||||
return
|
self._current_mode = self.get_mode_by_name(mode_name)
|
||||||
self.set_mode('ZOOM')
|
|
||||||
|
|
||||||
def mouse_move(self, event):
|
|
||||||
"""Extend NavigationToolbar2.mouse_move to provide selection support."""
|
|
||||||
# Only update the rubberband for selection mode when mouse is
|
|
||||||
# within the plotting area.
|
|
||||||
|
|
||||||
#if event.inaxes and self._active=='SELECT':
|
|
||||||
# if self._lastCursor != cursors.SELECT_REGION:
|
|
||||||
# self.set_cursor(cursors.SELECT_REGION)
|
|
||||||
# self._lastCursor = cursors.SELECT_REGION
|
|
||||||
# if self._xypress is not None:
|
|
||||||
# x, y = event.x, event.y
|
|
||||||
# lastx, lasty, a, ind, lim, trans= self._xypress
|
|
||||||
# self.draw_rubberband(event, x, y, lastx, lasty)
|
|
||||||
|
|
||||||
NavigationToolbar2.mouse_move(self, event)
|
|
||||||
|
|
||||||
def set_select_callback(self, listener):
|
|
||||||
"""Allow plots to register a callback for selection events.
|
|
||||||
|
|
||||||
The callback will be called as listener(x1, y1, x2, y2). All
|
|
||||||
coordinates are in the plot coordinate system, not pixels or
|
|
||||||
widget coordinates.
|
|
||||||
"""
|
|
||||||
self._select_callback = listener
|
|
||||||
|
|
||||||
def set_cursor(self, cursor):
|
|
||||||
self.canvas.window.set_cursor(cursord[cursor])
|
|
||||||
|
|
||||||
def dynamic_update(self):
|
|
||||||
# legacy method; new method is canvas.draw_idle
|
|
||||||
self.canvas.draw_idle()
|
|
||||||
|
|
||||||
def draw_rubberband(self, event, x0, y0, x1, y1):
|
|
||||||
'adapted from http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/189744'
|
|
||||||
drawable = self.canvas.window
|
|
||||||
if drawable is None:
|
|
||||||
return
|
|
||||||
|
|
||||||
gc = drawable.new_gc()
|
|
||||||
|
|
||||||
height = self.canvas.figure.bbox.height()
|
|
||||||
y1 = height - y1
|
|
||||||
y0 = height - y0
|
|
||||||
|
|
||||||
w = abs(x1 - x0)
|
|
||||||
h = abs(y1 - y0)
|
|
||||||
rect = [int(val)for val in min(x0,x1), min(y0, y1), w, h]
|
|
||||||
try: lastrect, imageBack = self._imageBack
|
|
||||||
except AttributeError:
|
|
||||||
#snap image back
|
|
||||||
if event.inaxes is None:
|
|
||||||
return
|
|
||||||
|
|
||||||
ax = event.inaxes
|
|
||||||
l,b,w,h = [int(val) for val in ax.bbox.get_bounds()]
|
|
||||||
b = int(height)-(b+h)
|
|
||||||
axrect = l,b,w,h
|
|
||||||
self._imageBack = axrect, drawable.get_image(*axrect)
|
|
||||||
drawable.draw_rectangle(gc, False, *rect)
|
|
||||||
self._idleId = 0
|
|
||||||
else:
|
else:
|
||||||
def idle_draw(*args):
|
logger.log('warning', 'No such mode: %s' % mode_name)
|
||||||
drawable.draw_image(gc, imageBack, 0, 0, *lastrect)
|
|
||||||
drawable.draw_rectangle(gc, False, *rect)
|
|
||||||
self._idleId = 0
|
|
||||||
return False
|
|
||||||
if self._idleId == 0:
|
|
||||||
self._idleId = gobject.idle_add(idle_draw)
|
|
||||||
|
|
||||||
def save_figure(self, button):
|
return self._current_mode
|
||||||
fname = self.fileselect.get_filename_from_user()
|
|
||||||
if fname:
|
|
||||||
self.canvas.print_figure(fname)
|
|
||||||
|
|
||||||
def configure_subplots(self, button):
|
def _on_mode_toggle(self, button):
|
||||||
toolfig = Figure(figsize=(6,3))
|
if button.get_active():
|
||||||
canvas = self._get_canvas(toolfig)
|
self.set_mode(self._mode_buttons[button].name)
|
||||||
toolfig.subplots_adjust(top=0.9)
|
|
||||||
tool = SubplotTool(self.canvas.figure, toolfig)
|
|
||||||
|
|
||||||
w = int (toolfig.bbox.width())
|
# def show(self):
|
||||||
h = int (toolfig.bbox.height())
|
# for b in self._mode_buttons.keys():
|
||||||
|
# b.show()
|
||||||
|
# gtk.Toolbar.show(self)
|
||||||
|
|
||||||
|
# class PlotToolbar(NavigationToolbar2,gtk.Toolbar):
|
||||||
|
# # list of toolitems to add to the toolbar, format is:
|
||||||
|
# # text, tooltip_text, image_file, callback(str)
|
||||||
|
# toolitems = (
|
||||||
|
# ('Home', 'Reset original view', 'home.png', 'home'),
|
||||||
|
# #('Back', 'Back to previous view','back.png', 'back'),
|
||||||
|
# #('Forward', 'Forward to next view','forward.png', 'forward'),
|
||||||
|
# #('Subplots', 'Configure subplots','subplots.png', 'configure_subplots'),
|
||||||
|
# ('Save', 'Save the figure','filesave.png', 'save_figure'),
|
||||||
|
# )
|
||||||
|
|
||||||
|
# def __init__(self, canvas, plot):
|
||||||
|
# self.win = None
|
||||||
|
# self.plot = plot
|
||||||
|
# gtk.Toolbar.__init__(self)
|
||||||
|
# NavigationToolbar2.__init__(self, canvas)
|
||||||
|
# self._idleId = 0
|
||||||
|
# self._select_callback = None
|
||||||
|
# canvas.connect('enter-notify-event', self.on_enter_notify)
|
||||||
|
|
||||||
|
# def _init_toolbar(self):
|
||||||
|
# self.set_style(gtk.TOOLBAR_ICONS)
|
||||||
|
# self.tooltips = gtk.Tooltips()
|
||||||
|
# self._modes = {}
|
||||||
|
# self._selector = None
|
||||||
|
# self.set_property('show-arrow', False)
|
||||||
|
# basedir = fluents.ICONDIR
|
||||||
|
|
||||||
|
# # setup base buttons
|
||||||
|
# for text, tooltip_text, image_file, callback in self.toolitems:
|
||||||
|
# if text is None:
|
||||||
|
# self.insert(gtk.SeparatorToolItem(), -1 )
|
||||||
|
# continue
|
||||||
|
# fname = os.path.join(basedir, image_file)
|
||||||
|
# image = gtk.Image()
|
||||||
|
# image.set_from_file(fname)
|
||||||
|
# tbutton = gtk.ToolButton(image, text)
|
||||||
|
# self.insert(tbutton, -1)
|
||||||
|
# tbutton.connect('clicked', getattr(self, callback))
|
||||||
|
# tbutton.set_tooltip(self.tooltips, tooltip_text, 'Private')
|
||||||
|
|
||||||
|
# self.insert(gtk.SeparatorToolItem(), -1)
|
||||||
|
|
||||||
|
# # mode/state buttons
|
||||||
|
# rbutton = None
|
||||||
|
# for text,tooltip_text,image_file,callback in self.radiobuttons:
|
||||||
|
# if text is None:
|
||||||
|
# self.insert(gtk.SeparatorToolItem(), -1 )
|
||||||
|
# continue
|
||||||
|
# fname = os.path.join(basedir, image_file)
|
||||||
|
# image = gtk.Image()
|
||||||
|
# image.set_from_file(fname)
|
||||||
|
# rbutton = gtk.RadioToolButton(rbutton)
|
||||||
|
# rbutton.set_icon_widget(image)
|
||||||
|
# rbutton.connect('toggled', getattr(self, callback))
|
||||||
|
# rbutton.set_tooltip(self.tooltips, tooltip_text, 'Private')
|
||||||
|
# self._modes[text] = rbutton
|
||||||
|
# a self.insert(rbutton, -1)
|
||||||
|
|
||||||
|
# self.insert(gtk.SeparatorToolItem(), -1)
|
||||||
|
|
||||||
|
# toolitem = gtk.ToolItem()
|
||||||
|
# self.insert(toolitem, -1)
|
||||||
|
# self.message = gtk.Label()
|
||||||
|
# toolitem.add(self.message)
|
||||||
|
|
||||||
|
# self.tb_freeze = gtk.ToolItem()
|
||||||
|
# self.chk = gtk.CheckButton ()
|
||||||
|
# self.chk.set_label ('Freeze')
|
||||||
|
# self.tb_freeze.add (self.chk)
|
||||||
|
# self.tb_freeze.set_tooltip(self.tooltips, 'Freeze current selection')
|
||||||
|
# self.insert(self.tb_freeze,-1)
|
||||||
|
|
||||||
|
# toolitem = gtk.SeparatorToolItem()
|
||||||
|
# self.insert(toolitem, -1)
|
||||||
|
|
||||||
|
# self.show_all()
|
||||||
|
|
||||||
|
# self.fileselect = FileChooserDialog(title='Save the figure', parent=self.win,)
|
||||||
|
|
||||||
|
|
||||||
window = gtk.Window()
|
# def on_enter_notify(self, widget, event):
|
||||||
window.set_title("Subplot Configuration Tool")
|
# if self._active != active_mode:
|
||||||
window.set_default_size(w, h)
|
# self.set_mode(active_mode)
|
||||||
vbox = gtk.VBox()
|
# self.set_mode(active_mode)
|
||||||
window.add(vbox)
|
|
||||||
vbox.show()
|
|
||||||
|
|
||||||
canvas.show()
|
# def set_mode(self, mode):
|
||||||
vbox.pack_start(canvas, True, True)
|
# ## Do nothing if this mode is already active
|
||||||
window.show()
|
# if self.mode == mode:
|
||||||
|
# print "set_mode: already in mode '%s': returning" % mode
|
||||||
|
# return mode
|
||||||
|
|
||||||
def _get_canvas(self, fig):
|
# ## Remove current Selector if set.
|
||||||
return FigureCanvas(fig)
|
# if self._selector != None:
|
||||||
|
# self.canvas.mpl_disconnect(self._selector.onmove)
|
||||||
|
# self.canvas.mpl_disconnect(self._selector.press)
|
||||||
|
# self.canvas.mpl_disconnect(self._selector.release)
|
||||||
|
# self.canvas.mpl_disconnect(self._selector.update_background)
|
||||||
|
# print "set_mode: Removing selector in: %s" %self.plot.get_title()
|
||||||
|
# self._selector = None
|
||||||
|
|
||||||
|
# ## Remove current mouse button bindings
|
||||||
|
# if self._idPress != None:
|
||||||
|
# self._idPress = self.canvas.mpl_disconnect(self._idPress)
|
||||||
|
# self.mode = ''
|
||||||
|
|
||||||
|
# if self._idRelease != None:
|
||||||
|
# self._idRelease = self.canvas.mpl_disconnect(self._idRelease)
|
||||||
|
# self.mode = ''
|
||||||
|
|
||||||
|
# ## Set state, and do state initialization
|
||||||
|
# self.mode = mode
|
||||||
|
|
||||||
|
|
||||||
|
# def set_mode(self, active):
|
||||||
|
# print "Set mode called in toolbar from: %s" %self.plot.get_title()
|
||||||
|
# # if state is unkown or not set, set to default
|
||||||
|
# if active == None or active not in self._modes.keys():
|
||||||
|
# active = 'DEFAULT'
|
||||||
|
|
||||||
|
# # remove current Selector:
|
||||||
|
# if self._selector != None:
|
||||||
|
# # problem is ... i have mutliple selectors still connected
|
||||||
|
# # trying to remove old selectors connections
|
||||||
|
# #
|
||||||
|
# # blah
|
||||||
|
# # Her Einar ...
|
||||||
|
# #
|
||||||
|
# self.canvas.mpl_disconnect(self._selector.onmove)
|
||||||
|
# self.canvas.mpl_disconnect(self._selector.press)
|
||||||
|
# self.canvas.mpl_disconnect(self._selector.release)
|
||||||
|
# self.canvas.mpl_disconnect(self._selector.update_background)
|
||||||
|
# print "Removing selector in: %s" %self.plot.get_title()
|
||||||
|
# self._selector = None
|
||||||
|
|
||||||
|
# # remove current button bindings
|
||||||
|
# if self._idPress != None:
|
||||||
|
# self._idPress = self.canvas.mpl_disconnect(self._idPress)
|
||||||
|
# self.mode = ''
|
||||||
|
|
||||||
|
# if self._idRelease != None:
|
||||||
|
# self._idRelease = self.canvas.mpl_disconnect(self._idRelease)
|
||||||
|
# self.mode = ''
|
||||||
|
|
||||||
|
# self._modes[active]
|
||||||
|
|
||||||
|
# for state, button in self._modes.items():
|
||||||
|
# if state != active:
|
||||||
|
# continue
|
||||||
|
|
||||||
|
# if state == 'SELECT':
|
||||||
|
# for ax in self.canvas.figure.get_axes():
|
||||||
|
# props = dict(facecolor='blue', edgecolor = 'black',
|
||||||
|
# alpha=0.3, fill=True)
|
||||||
|
# print "creating a selector"
|
||||||
|
# self._selector = RectangleSelector(ax, self.on_select,
|
||||||
|
# drawtype='box', useblit=True,
|
||||||
|
# rectprops=props)
|
||||||
|
# self.mode = 'Select rectangle mode'
|
||||||
|
|
||||||
|
# elif state == 'PAN':
|
||||||
|
# self._idPress = self.canvas.mpl_connect(
|
||||||
|
# 'button_press_event', self.press_pan)
|
||||||
|
# self._idRelease = self.canvas.mpl_connect(
|
||||||
|
# 'button_release_event', self.release_pan)
|
||||||
|
# self.mode = 'pan/zoom mode'
|
||||||
|
|
||||||
|
# elif state == 'ZOOM':
|
||||||
|
# self._idPress = self.canvas.mpl_connect('button_press_event', self.press_zoom)
|
||||||
|
# self._idRelease = self.canvas.mpl_connect('button_release_event', self.release_zoom)
|
||||||
|
# self.mode = 'Zoom to rect mode'
|
||||||
|
|
||||||
|
# elif state == 'DEFAULT':
|
||||||
|
# pass
|
||||||
|
# else:
|
||||||
|
# pass
|
||||||
|
|
||||||
|
# if not button.get_active():
|
||||||
|
# button.set_active(True)
|
||||||
|
|
||||||
|
# for a in self.canvas.figure.get_axes():
|
||||||
|
# a.set_navigate_mode(self._active)
|
||||||
|
|
||||||
|
# self.set_message(self.mode)
|
||||||
|
|
||||||
|
# self._active = active
|
||||||
|
# # update global active_mode (for all toolbar)
|
||||||
|
# globals()['active_mode'] = active
|
||||||
|
|
||||||
|
# def get_mode(self):
|
||||||
|
# if self._active == None:
|
||||||
|
# return 'DEFAULT'
|
||||||
|
# return self._active
|
||||||
|
|
||||||
|
# def default(self, button):
|
||||||
|
# """Activates default mode"""
|
||||||
|
# if not button.get_active():
|
||||||
|
# return
|
||||||
|
# self.set_mode('DEFAULT')
|
||||||
|
|
||||||
|
# def select(self, button):
|
||||||
|
# """Activate select mode"""
|
||||||
|
# if not button.get_active():
|
||||||
|
# return
|
||||||
|
# self.set_mode('SELECT')
|
||||||
|
|
||||||
|
# def on_select(self, eclick, erelease, selector):
|
||||||
|
# 'eclick and erelease are matplotlib events at press and release'
|
||||||
|
# if self._select_callback:
|
||||||
|
# print "Onselect called:"
|
||||||
|
# print " %s" % selector
|
||||||
|
# self._select_callback(eclick.xdata, eclick.ydata, erelease.xdata, erelease.ydata)
|
||||||
|
|
||||||
|
# def pan(self, button):
|
||||||
|
# """Activate the pan/zoom tool. pan with left button, zoom with right"""
|
||||||
|
# if not button.get_active():
|
||||||
|
# return
|
||||||
|
# self.set_mode('PAN')
|
||||||
|
|
||||||
|
# def zoom(self, button):
|
||||||
|
# """Activate zoom to rect mode"""
|
||||||
|
# if not button.get_active():
|
||||||
|
# return
|
||||||
|
# self.set_mode('ZOOM')
|
||||||
|
|
||||||
|
# def mouse_move(self, event):
|
||||||
|
# """Extend NavigationToolbar2.mouse_move to provide selection support."""
|
||||||
|
# # Only update the rubberband for selection mode when mouse is
|
||||||
|
# # within the plotting area.
|
||||||
|
|
||||||
|
# #if event.inaxes and self._active=='SELECT':
|
||||||
|
# # if self._lastCursor != cursors.SELECT_REGION:
|
||||||
|
# # self.set_cursor(cursors.SELECT_REGION)
|
||||||
|
# # self._lastCursor = cursors.SELECT_REGION
|
||||||
|
# # if self._xypress is not None:
|
||||||
|
# # x, y = event.x, event.y
|
||||||
|
# # lastx, lasty, a, ind, lim, trans= self._xypress
|
||||||
|
# # self.draw_rubberband(event, x, y, lastx, lasty)
|
||||||
|
|
||||||
|
# NavigationToolbar2.mouse_move(self, event)
|
||||||
|
|
||||||
|
# def set_select_callback(self, listener):
|
||||||
|
# """Allow plots to register a callback for selection events.
|
||||||
|
|
||||||
|
# The callback will be called as listener(x1, y1, x2, y2). All
|
||||||
|
# coordinates are in the plot coordinate system, not pixels or
|
||||||
|
# widget coordinates.
|
||||||
|
# """
|
||||||
|
# self._select_callback = listener
|
||||||
|
|
||||||
|
# def set_cursor(self, cursor):
|
||||||
|
# self.canvas.window.set_cursor(cursord[cursor])
|
||||||
|
|
||||||
|
# def dynamic_update(self):
|
||||||
|
# # legacy method; new method is canvas.draw_idle
|
||||||
|
# self.canvas.draw_idle()
|
||||||
|
|
||||||
|
|
||||||
|
# def save_figure(self, button):
|
||||||
|
# fname = self.fileselect.get_filename_from_user()
|
||||||
|
# if fname:
|
||||||
|
# self.canvas.print_figure(fname)
|
||||||
|
|
||||||
|
# def configure_subplots(self, button):
|
||||||
|
# toolfig = Figure(figsize=(6,3))
|
||||||
|
# canvas = self._get_canvas(toolfig)
|
||||||
|
# toolfig.subplots_adjust(top=0.9)
|
||||||
|
# tool = SubplotTool(self.canvas.figure, toolfig)
|
||||||
|
|
||||||
|
# w = int (toolfig.bbox.width())
|
||||||
|
# h = int (toolfig.bbox.height())
|
||||||
|
|
||||||
|
|
||||||
|
# window = gtk.Window()
|
||||||
|
# window.set_title("Subplot Configuration Tool")
|
||||||
|
# window.set_default_size(w, h)
|
||||||
|
# vbox = gtk.VBox()
|
||||||
|
# window.add(vbox)
|
||||||
|
# vbox.show()
|
||||||
|
|
||||||
|
# canvas.show()
|
||||||
|
# vbox.pack_start(canvas, True, True)
|
||||||
|
# window.show()
|
||||||
|
|
||||||
|
# def _get_canvas(self, fig):
|
||||||
|
# return FigureCanvas(fig)
|
||||||
|
|
||||||
|
|
||||||
# Create a view-changed signal that should be emitted every time
|
# Create a view-changed signal that should be emitted every time
|
||||||
|
|
Reference in New Issue