# defaultFilter=self.gui.config['folders-filter-index']), 'left'),
(panel.PANELS['playlist'](
callbacks={
- 'delete_playlist':self._on_user_delete_playlist,
- '_delete_playlist':self._on_delete_playlist,
- 'delete_curve':self._on_user_delete_curve,
- '_delete_curve':self._on_delete_curve,
+ '_delete_playlist':self._delete_playlist,
+ '_delete_curve':self._delete_curve,
'_on_set_selected_playlist':self._on_set_selected_playlist,
'_on_set_selected_curve':self._on_set_selected_curve,
},
callbacks={
'next': self._next_curve,
'previous': self._previous_curve,
+ 'delete': self._delete_curve,
},
- parent=self,
- style=wx.TB_FLAT | wx.TB_NODIVIDER)
+ parent=self)
self._c['manager'].AddPane(
self._c['navigation bar'],
aui.AuiPaneInfo().Name('Navigation').Caption('Navigation'
self.Bind(wx.EVT_SIZE, self._on_size)
self.Bind(wx.EVT_CLOSE, self._on_close)
self.Bind(aui.EVT_AUI_PANE_CLOSE, self._on_pane_close)
+ self.Bind(wx.EVT_CHAR_HOOK, self._on_key)
return # TODO: cleanup
treeCtrl = self._c['folders'].GetTreeCtrl()
def _on_close(self, *args):
self.log.info('closing GUI framework')
+
# apply changes
self._set_config('main height', self.GetSize().GetHeight())
self._set_config('main left', self.GetPosition()[0])
def _on_erase_background(self, event):
event.Skip()
+ def _on_key(self, event):
+ code = event.GetKeyCode()
+ if code == wx.WXK_RIGHT:
+ self._next_curve()
+ elif code == wx.WXK_LEFT:
+ self._previous_curve()
+ elif code == wx.WXK_DELETE or code == wx.WXK_BACK:
+ self._delete_curve()
+ else:
+ event.Skip()
# Panel utility functions
self.execute_command(
command=self._command_by_name('get playlist'))
+ def _postprocess_delete_curve(self, command, args={}, results=[]):
+ """No-op. Only call 'delete curve' via `self._delete_curve()`.
+ """
+ pass
+
def _update_curve(self, command, args={}, results=[]):
"""Update the curve, since the available columns may have changed.
"""
# Playlist panel interface
- def _on_user_delete_playlist(self, _class, method, playlist):
- pass
-
- def _on_delete_playlist(self, _class, method, playlist):
- if hasattr(playlist, 'path') and playlist.path != None:
- os.remove(playlist.path)
-
- def _on_user_delete_curve(self, _class, method, playlist, curve):
- pass
-
- def _on_delete_curve(self, _class, method, playlist, curve):
- index = playlist.index(curve)
- results = self.execute_command(
- command=self._command_by_name('remove curve from playlist'),
- args={'index': index})
- #os.remove(curve.path)
+ def _delete_playlist(self, _class, method, playlist):
+ #if hasattr(playlist, 'path') and playlist.path != None:
+ # os.remove(playlist.path)
+ # TODO: remove playlist from underlying hooke instance and call ._c['playlist'].delete_playlist()
+ # possibly rename this method to _postprocess_delete_playlist...
pass
def _on_set_selected_playlist(self, _class, method, playlist):
self.execute_command(
command=self._command_by_name('get curve'))
+ def _delete_curve(self, *args, **kwargs):
+ cmd_kwargs = {}
+ playlist = kwargs.get('playlist', None)
+ curve = kwargs.get('curve', None)
+ if playlist is not None and curve is not None:
+ cmd_kwargs['index'] = playlist.index(curve)
+ results = self.execute_command(
+ command=self._command_by_name('remove curve from playlist'),
+ args=cmd_kwargs)
+ if isinstance(results[-1], Success):
+ results = self.execute_command(
+ command=self._command_by_name('get playlist'))
# Panel display handling
short_help_string='Next curve',
long_help_string='',
client_data=None),
+ 'delete': self.AddTool(
+ tool_id=wx.ID_DELETE,
+ label='Delete',
+ bitmap=wx.ArtProvider_GetBitmap(
+ wx.ART_DELETE, wx.ART_OTHER, bitmap_size),
+ disabled_bitmap=wx.NullBitmap,
+ kind=wx.ITEM_NORMAL,
+ short_help_string='Remove curve from playlist',
+ long_help_string='',
+ client_data=None),
}
self.Realize()
self._callbacks = callbacks
self.Bind(wx.EVT_TOOL, self._on_next, self._c['next'])
self.Bind(wx.EVT_TOOL, self._on_previous, self._c['previous'])
+ self.Bind(wx.EVT_TOOL, self._on_delete, self._c['delete'])
def _on_next(self, event):
self.next()
def _on_previous(self, event):
self.previous()
+ def _on_delete(self, event):
+ self.delete()
+
@callback
def next(self):
pass
def previous(self):
pass
-
-
+ @callback
+ def delete(self):
+ pass
del(self._hit_id)
name = self._name_for_id[_id]
if self._is_curve(name):
- self.delete_curve(playlist_name=name[0], name=name[1])
+ self._delete_curve(playlist_name=name[0], name=name[1])
else:
- self.delete_playlist(name)
+ self._delete_playlist(name)
- def delete_playlist(self, name):
+ def _delete_playlist(self, name):
"""Delete a :class:`hooke.playlist.Playlist` by name.
- Called by the :meth:`_on_delete` handler.
-
- Removes the playlist and its curves from the tree, then calls
- :meth:`_delete_playlist`.
+ Called by the :meth:`_on_delete` handler. Calls the
+ approptiate interface callback.
"""
_id = self._id_for_name[name]
- self.Delete(_id)
playlist = self._playlists[name]
- self._delete_playlist(playlist)
in_callback(self, playlist)
- def _delete_playlist(self, playlist):
- """Adjust name/id caches for the playlist and its curves.
+ def delete_playlist(self, playlist):
+ """Respond to playlist deletion.
Called on *every* playlist deletion.
"""
self._playlists.pop(playlist.name)
_id = self._id_for_name.pop(playlist.name)
+ self.Delete(_id)
del(self._name_for_id[_id])
for curve in playlist:
self._delete_curve(playlist, curve)
- in_callback(self, playlist)
- def delete_curve(self, playlist_name, name):
+ def _delete_curve(self, playlist_name, name):
"""Delete a :class:`hooke.curve.Curve` by name.
- Called by the :meth:`_on_delete` handler.
-
- Removes the curve from the tree, then calls
- :meth:`_delete_curve`.
+ Called by the :meth:`_on_delete` handler. Calls the
+ approptiate interface callback.
"""
_id = self._id_for_name[(playlist_name, name)]
- self.Delete(_id)
playlist = self._playlists[playlist_name]
curve = None
for i,c in enumerate(playlist):
break
if curve is None:
raise ValueError(name)
- self._delete_curve(playlist=playlist, curve=curve)
in_callback(self, playlist, curve)
- def _delete_curve(self, playlist, curve):
- """Adjust name/id caches.
+ def delete_curve(self, playlist_name, name):
+ """Respond to curve deletions.
- Called on _every_ curve deletion.
+ Called on *every* curve deletion.
"""
- _id = self._id_for_name.pop((playlist.name, curve.name))
+ _id = self._id_for_name.pop((playlist_name, name))
+ self.Delete(_id)
del(self._name_for_id[_id])
- in_callback(self, playlist=playlist, curve=curve)
# Get selection
"""Absorb changed `.index()`, etc.
"""
self._playlists[playlist.name] = playlist
- cnames = []
+ cnames = set()
for curve in playlist:
if (playlist.name, curve.name) not in self._id_for_name:
self._add_curve(playlist.name, curve)
- cnames.append(curve.name)
- dc = self._callbacks['delete_curve']
- _dc = self._callbacks['_delete_curve']
- self._callbacks['delete_curve'] = None
- self._callbacks['_delete_curve'] = None
+ cnames.add(curve.name)
for name in self._id_for_name.keys():
if not self._is_curve(name):
continue
if pname != playlist.name:
continue
if cname not in cnames:
- self.delete_curve(playlist.name, cname)
- self._callbacks['delete_curve'] = dc
- self._callbacks['_delete_curve'] = _dc
+ self.delete_curve(playlist_name=pname, name=cname)
def is_playlist_loaded(self, playlist):
"""Return `True` if `playlist` is loaded, `False` otherwise.
-layout2|name=Folders;caption=Folders;state=33818620;dir=4;layer=0;row=0;pos=0;prop=100000;bestw=196;besth=246;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1;notebookid=-1;transparent=255|name=Playlists;caption=Playlists;state=33818620;dir=4;layer=0;row=0;pos=1;prop=100000;bestw=160;besth=250;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1;notebookid=-1;transparent=255|name=Plots;caption=;state=256;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=430;besth=200;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1;notebookid=-1;transparent=255|name=Commands;caption=Settings and commands;state=33818620;dir=2;layer=0;row=0;pos=0;prop=100000;bestw=160;besth=273;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1;notebookid=-1;transparent=255|name=Properties;caption=Properties;state=33818620;dir=2;layer=0;row=0;pos=1;prop=100000;bestw=60;besth=58;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1;notebookid=-1;transparent=255|name=Assistant;caption=Assistant;state=33818620;dir=2;layer=0;row=0;pos=2;prop=100000;bestw=133;besth=90;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1;notebookid=-1;transparent=255|name=Output;caption=Output;state=33818620;dir=3;layer=0;row=0;pos=0;prop=100000;bestw=133;besth=90;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1;notebookid=-1;transparent=255|name=Results;caption=Results;state=33818620;dir=3;layer=0;row=0;pos=1;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1;notebookid=-1;transparent=255|name=toolbar;caption=Toolbar;state=33827568;dir=1;layer=1;row=1;pos=0;prop=100000;bestw=100;besth=23;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1;notebookid=-1;transparent=255|name=toolbarNavigation;caption=Navigation;state=33827568;dir=1;layer=1;row=1;pos=111;prop=100000;bestw=46;besth=23;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1;notebookid=-1;transparent=255|dock_size(4,0,0)=198|dock_size(5,0,0)=325|dock_size(2,0,0)=162|dock_size(3,0,0)=111|dock_size(1,1,1)=25|
+layout2|name=Folders;caption=Folders;state=33818620;dir=4;layer=0;row=0;pos=0;prop=100000;bestw=196;besth=246;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1;notebookid=-1;transparent=255|name=Playlists;caption=Playlists;state=33818620;dir=4;layer=0;row=0;pos=1;prop=100000;bestw=160;besth=250;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1;notebookid=-1;transparent=255|name=Plots;caption=;state=256;dir=5;layer=0;row=0;pos=0;prop=100000;bestw=430;besth=200;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1;notebookid=-1;transparent=255|name=Commands;caption=Settings and commands;state=33818620;dir=2;layer=0;row=0;pos=0;prop=100000;bestw=160;besth=273;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1;notebookid=-1;transparent=255|name=Properties;caption=Properties;state=33818620;dir=2;layer=0;row=0;pos=1;prop=100000;bestw=60;besth=58;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1;notebookid=-1;transparent=255|name=Assistant;caption=Assistant;state=33818620;dir=2;layer=0;row=0;pos=2;prop=100000;bestw=133;besth=90;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1;notebookid=-1;transparent=255|name=Output;caption=Output;state=33818620;dir=3;layer=0;row=0;pos=0;prop=100000;bestw=133;besth=90;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1;notebookid=-1;transparent=255|name=Results;caption=Results;state=33818620;dir=3;layer=0;row=0;pos=1;prop=100000;bestw=20;besth=20;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1;notebookid=-1;transparent=255|name=toolbar;caption=Toolbar;state=33827568;dir=1;layer=1;row=1;pos=0;prop=100000;bestw=300;besth=23;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1;notebookid=-1;transparent=255|name=toolbarNavigation;caption=Navigation;state=33827568;dir=1;layer=1;row=1;pos=111;prop=100000;bestw=46;besth=23;minw=-1;minh=-1;maxw=-1;maxh=-1;floatx=-1;floaty=-1;floatw=-1;floath=-1;notebookid=-1;transparent=255|dock_size(4,0,0)=198|dock_size(5,0,0)=325|dock_size(2,0,0)=162|dock_size(3,0,0)=111|dock_size(1,1,1)=25|