From 3daa6a51fef52737779896f9c3dbf26dcce6013a Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Fri, 30 Jul 2010 08:09:40 -0400 Subject: [PATCH] Cleaned up playlist panel's curve selection --- hooke/ui/gui/__init__.py | 4 + hooke/ui/gui/panel/playlist.py | 194 +++++++++++++++++++-------------- 2 files changed, 119 insertions(+), 79 deletions(-) diff --git a/hooke/ui/gui/__init__.py b/hooke/ui/gui/__init__.py index d250dbd..f677171 100644 --- a/hooke/ui/gui/__init__.py +++ b/hooke/ui/gui/__init__.py @@ -122,6 +122,7 @@ class HookeFrame (wx.Frame): '_delete_playlist':self._on_delete_playlist, 'delete_curve':self._on_user_delete_curve, '_delete_curve':self._on_delete_curve, + '_set_selected_curve':self._on_set_selected_curve, }, config=self.gui.config, parent=self, @@ -698,6 +699,9 @@ class HookeFrame (wx.Frame): def _on_delete_curve(self, _class, method, playlist, curve): os.remove(curve.path) + def _on_set_selected_curve(self, _class, method, playlist, curve): + print 'selected', playlist.name, curve.name + # Navbar interface diff --git a/hooke/ui/gui/panel/playlist.py b/hooke/ui/gui/panel/playlist.py index 53eb998..37782c3 100644 --- a/hooke/ui/gui/panel/playlist.py +++ b/hooke/ui/gui/panel/playlist.py @@ -46,9 +46,7 @@ class Tree (wx.TreeCtrl): 'root': self.AddRoot(text='Playlists', image=self.image['root']) } self.Bind(wx.EVT_RIGHT_DOWN, self._on_context_menu) - self.Bind(wx.EVT_TREE_SEL_CHANGED, self._on_curve_select) - self.Bind(wx.EVT_LEFT_DOWN, self._on_left_down) - self.Bind(wx.EVT_LEFT_DCLICK, self._on_left_doubleclick) + self.Bind(wx.EVT_TREE_SEL_CHANGED, self._on_select) self.config = config self._callbacks = callbacks @@ -93,34 +91,8 @@ class Tree (wx.TreeCtrl): return c_id raise KeyError(_id) - def _on_curve_select(self, event): - """Act on playlist/curve selection. - Currently just a hook for a potential callback. - """ - _id = self.GetSelection() - name = self._name_for_id[self._canonical_id(_id)] - if self._is_curve(name): - playlist = self._playlists[name[0]] - curve = playlist.current() - in_callback(self, playlist, curve) - - def _on_left_down(self, event): - """Select the clicked-on curve/playlist. - """ # TODO: dup with _on_curve_select? - hit_id, hit_flags = self.HitTest(event.GetPosition()) - if (hit_flags & wx.TREE_HITTEST_ONITEM) != 0: - name = self._name_for_id[self._canonical_id(hit_id)] - if self._is_curve(name): - self.set_selected_curve(name[0], name[1]) - else: - self.set_selected_playlist(name) - event.Skip() - - def _on_left_doubleclick(self, event): - pass - #playlist.index = index - #event.Skip() + # Context menu def _on_context_menu(self, event): """Launch a popup :class:`Menu` with per-playlist/curve activities. @@ -132,23 +104,22 @@ class Tree (wx.TreeCtrl): self.PopupMenu(menu, event.GetPosition()) menu.Destroy() - def _on_delete(self, event): - """Handler for :class:`Menu`'s `Delete` button. - - Determines the clicked item and calls the appropriate - `.delete_*()` method on it. - """ - #if hasattr(self, '_hit_id'): # called via ._c['menu'] - _id = self._hit_id - 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]) - else: - self.delete_playlist(name) + # Add + # add_* called directly by HookeFrame + # _add_* called on every addition def add_playlist(self, playlist): """Add a :class:`hooke.playlist.Playlist` to the tree. + + Calls :meth:`_add_playlist` and triggers a callback. + """ + self._add_playlist(playlist) + in_callback(self, playlist) + + def _add_playlist(self, playlist): + """Add a class:`hooke.playlist.Playlist` to the tree. + + No callback triggered. """ if playlist.name not in self._playlists: pass @@ -161,21 +132,22 @@ class Tree (wx.TreeCtrl): image=self.image['playlist']) self._id_for_name[playlist.name] = p_id self._name_for_id[p_id] = playlist.name - - # temporarily disable any add_curve callbacks - acc = self._callbacks.get('add_curve', None) - self._callbacks['add_curve'] = None - for curve in playlist: - self.add_curve(playlist.name, curve) - - # restore the add_curve callback - self._callbacks['add_curve'] = acc - - in_callback(self, playlist) + self._add_curve(playlist.name, curve) def add_curve(self, playlist_name, curve): """Add a :class:`hooke.curve.Curve` to a curently loaded playlist. + + Calls :meth:`_add_curve` and triggers a callback. + """ + self._add_curve(playlist_name, curve) + playlist = self._playlists[playlist_name] + in_callback(self, playlist, curve) + + def _add_curve(self, playlist_name, curve): + """Add a class:`hooke.curve.Curve` to the tree. + + No callback triggered. """ p = self._playlists[playlist_name] if curve not in p: @@ -186,7 +158,37 @@ class Tree (wx.TreeCtrl): image=self.image['curve']) self._id_for_name[(p.name, curve.name)] = c_id self._name_for_id[c_id] = (p.name, curve.name) - in_callback(self, p, curve) + + @callback + def generate_new_playlist(self): + pass # TODO + + def _GetUniquePlaylistName(self, name): # TODO + playlist_name = name + count = 1 + while playlist_name in self.playlists: + playlist_name = ''.join([name, str(count)]) + count += 1 + return playlist_name + + # Delete + # delete_* called by _on_delete handler (user click) or HookeFrame + # _delete_* called on every deletion + + def _on_delete(self, event): + """Handler for :class:`Menu`'s `Delete` button. + + Determines the clicked item and calls the appropriate + `.delete_*()` method on it. + """ + #if hasattr(self, '_hit_id'): # called via ._c['menu'] + _id = self._hit_id + 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]) + else: + self.delete_playlist(name) def delete_playlist(self, name): """Delete a :class:`hooke.playlist.Playlist` by name. @@ -242,6 +244,8 @@ class Tree (wx.TreeCtrl): del(self._name_for_id[_id]) in_callback(self, playlist, curve) + # Get selection + def get_selected_playlist(self): """Return the selected :class:`hooke.playlist.Playlist`. """ @@ -259,44 +263,76 @@ class Tree (wx.TreeCtrl): if self._is_curve(name): p_name,c_name = name playlist = self._playlists[p_name] - index = [i for i,c in enumerate(playlist) if c.name == c_name] - playlist.jump(index) + c = playlist.current() + assert c.name == c_name, '%s != %s' % (c.name, c_name) else: playlist = self._playlists[name] return playlist.current() + # Set selection + # set_* called by HookeFrame, includes tree display updates + # _set_* called on every selection (including _on_select) + # + # Selection is a bit tricky, because playlists are never selected + # directly. Selecting a playlist is equivalent to selecting its + # current curve. + + def _on_select(self, event): + """Select the clicked-on curve/playlist. + """ + _id = self.GetSelection() + name = self._name_for_id[self._canonical_id(_id)] + if self._is_curve(name): + p_name,c_name = name + self._set_selected_curve(p_name, c_name) + else: + self._set_selected_playlist(name) + def set_selected_playlist(self, name): """Set the selected :class:`hooke.playlist.Playlist` by name. + + Just a wrapper around :meth:`_set_selected_playlist`. + """ + # Selection would be overridden by _set_select_playlist + #self.SelectItem(self._id_for_name[name]) + self.Expand(self._id_for_name[name]) + self._set_selected_playlist(name) + + def _set_selected_playlist(self, name): + """Selects the playlist's current :class:`hooke.curve.Curve`. + + Updates the tree to display, which calls + :meth:`_set_selected_curvet` via :meth:`_on_select`. """ playlist = self._playlists[name] curve = playlist.current() - self.set_selected_curve(playlist.name, curve.name) - + self.SelectItem(self._id_for_name[(name, curve.name)]) + # triggers _set_selected_curve + def set_selected_curve(self, playlist_name, name): """Set the selected :class:`hooke.curve.Curve` by name. + + Updates the tree display, which calls + :meth:`_set_selected_curvet` via :meth:`_on_select`. """ - playlist = self._playlists[playlist.name] - for i,curve in enumerate(playlist): - if curve.name == name: + self.Expand(self._id_for_name[playlist_name]) + self.SelectItem(self._id_for_name[(playlist_name, name)]) + # triggers _set_selected_curve + + def _set_selected_curve(self, playlist_name, name): + """Make the curve the playlist's current curve. + """ + playlist = self._playlists[playlist_name] + curve = None + for i,c in enumerate(playlist): + if c.name == name: + curve = c playlist.jump(i) break + if curve == None: + raise ValueError(name) curve = playlist.current() - _id = self._id_for_name[(playlist.name, curve.name)] - self.Expand(self._id_for_name[playlist.name]) - self.SelectItem(_id) - in_callback(self, playlist, curve) # TODO: dup callback with _on_curve_select - - @callback - def generate_new_playlist(self): - pass - - def _GetUniquePlaylistName(self, name): - playlist_name = name - count = 1 - while playlist_name in self.playlists: - playlist_name = ''.join([name, str(count)]) - count += 1 - return playlist_name + in_callback(self, playlist, curve) class Playlist (Panel, wx.Panel): -- 2.26.2