From 797a2d8312c0ae50bf6238dae1e9cc7d1532fc0a Mon Sep 17 00:00:00 2001 From: fgerlits Date: Fri, 30 Sep 2005 19:41:59 +0000 Subject: [PATCH] added keyboard shortcuts to the playlist editor window --- .../src/SimplePlaylistManagementWindow.cxx | 106 ++++++++++++++++-- .../src/SimplePlaylistManagementWindow.h | 40 +++++++ 2 files changed, 138 insertions(+), 8 deletions(-) diff --git a/livesupport/products/gLiveSupport/src/SimplePlaylistManagementWindow.cxx b/livesupport/products/gLiveSupport/src/SimplePlaylistManagementWindow.cxx index 9ed1777ca..a6d22ca65 100644 --- a/livesupport/products/gLiveSupport/src/SimplePlaylistManagementWindow.cxx +++ b/livesupport/products/gLiveSupport/src/SimplePlaylistManagementWindow.cxx @@ -52,6 +52,20 @@ using namespace LiveSupport::GLiveSupport; /* ================================================ local constants & macros */ +/* + * The modifier keys we check against in onKeyPressed(). + * The following modifiers are omitted, hence ignored: + * GDK_LOCK_MASK (caps lock), + * GDK_MOD2_MASK (don't know what; always on on my computer), + * GDK_MOD3_MASK (don't know what; always off on my computer), + * GDK_BUTTONX_MASK (mouse buttons, X = 1..5). + */ +static const guint MODIFIERS_CHECKED = GDK_SHIFT_MASK + | GDK_CONTROL_MASK + | GDK_MOD1_MASK // Alt + | GDK_MOD4_MASK // Windows key + | GDK_MOD5_MASK; // Alt-gr + /* =============================================== local function prototypes */ @@ -132,6 +146,8 @@ SimplePlaylistManagementWindow :: SimplePlaylistManagementWindow ( *this, &SimplePlaylistManagementWindow::onEntryClicked )); entriesView->signalCellEdited().connect(sigc::mem_fun( *this, &SimplePlaylistManagementWindow::onFadeInfoEdited )); + entriesView->signal_key_press_event().connect(sigc::mem_fun( + *this, &SimplePlaylistManagementWindow::onKeyPressed)); // create the right-click entry context menu rightClickMenu = Gtk::manage(new Gtk::Menu()); @@ -608,11 +624,14 @@ void SimplePlaylistManagementWindow :: onUpItem(void) throw() { if (currentItem && currentItem != entriesModel->children().begin()) { + int rowNumber = (*currentItem) + [modelColumns.rowNumberColumn]; Gtk::TreeIter previousItem = currentItem; --previousItem; swapPlaylistElements(previousItem, currentItem); isPlaylistModified = true; showContents(); + selectRow(--rowNumber); } } @@ -624,12 +643,15 @@ void SimplePlaylistManagementWindow :: onDownItem(void) throw() { if (currentItem) { - Gtk::TreeIter nextItem = currentItem; + Gtk::TreeIter nextItem = currentItem; ++nextItem; if (nextItem) { + int rowNumber = (*currentItem) + [modelColumns.rowNumberColumn]; swapPlaylistElements(currentItem, nextItem); isPlaylistModified = true; showContents(); + selectRow(++rowNumber); } } } @@ -719,14 +741,82 @@ SimplePlaylistManagementWindow :: swapPlaylistElements( void SimplePlaylistManagementWindow :: onRemoveItem(void) throw() { - Ptr::Ref playlist = gLiveSupport->getEditedPlaylist(); - Ptr::Ref playlistElement - = (*currentItem)[modelColumns.playlistElementColumn]; + if (currentItem) { + Ptr::Ref + playlist = gLiveSupport->getEditedPlaylist(); + Ptr::Ref + playlistElement = (*currentItem) + [modelColumns.playlistElementColumn]; - playlist->removePlaylistElement(playlistElement->getId()); - playlist->eliminateGaps(); + playlist->removePlaylistElement(playlistElement->getId()); + playlist->eliminateGaps(); - isPlaylistModified = true; - showContents(); + isPlaylistModified = true; + showContents(); + } +} + + +/*------------------------------------------------------------------------------ + * Event handler for a key pressed. + *----------------------------------------------------------------------------*/ +bool +SimplePlaylistManagementWindow :: onKeyPressed(GdkEventKey * event) + throw () +{ + if (event->type == GDK_KEY_PRESS) { + if ((event->keyval == GDK_Up + || event->keyval == GDK_KP_Up) + && (event->state & MODIFIERS_CHECKED) == GDK_MOD1_MASK) { + findCurrentItem(); + onUpItem(); + return true; + + } else if ((event->keyval == GDK_Down + || event->keyval == GDK_KP_Down) + && (event->state & MODIFIERS_CHECKED) == GDK_MOD1_MASK) { + findCurrentItem(); + onDownItem(); + return true; + + } else if (event->keyval == GDK_Delete + || event->keyval == GDK_KP_Delete) { + findCurrentItem(); + onRemoveItem(); + return true; + } + } + + return false; +} + + +/*------------------------------------------------------------------------------ + * Find (an iterator pointing to) the currently selected row. + *----------------------------------------------------------------------------*/ +void +SimplePlaylistManagementWindow :: findCurrentItem(void) throw () +{ + Glib::RefPtr selection + = entriesView->get_selection(); + currentItem = selection->get_selected(); +} + + +/*------------------------------------------------------------------------------ + * Select (highlight) the nth row. + *----------------------------------------------------------------------------*/ +void +SimplePlaylistManagementWindow :: selectRow(int rowNumber) throw () +{ + Gtk::TreeModel::iterator iter = entriesModel->children().begin(); + for (; rowNumber > 0; --rowNumber) { + ++iter; + } + if (iter) { + Glib::RefPtr selection + = entriesView->get_selection(); + selection->select(iter); + } } diff --git a/livesupport/products/gLiveSupport/src/SimplePlaylistManagementWindow.h b/livesupport/products/gLiveSupport/src/SimplePlaylistManagementWindow.h index 51b25a2a5..b092ee653 100644 --- a/livesupport/products/gLiveSupport/src/SimplePlaylistManagementWindow.h +++ b/livesupport/products/gLiveSupport/src/SimplePlaylistManagementWindow.h @@ -152,6 +152,46 @@ class SimplePlaylistManagementWindow : public WhiteWindow, void onEntryClicked(GdkEventButton * event) throw (); + /** + * Signal handler for a key pressed at one of the entries. + * The keys handled are: + *
    + *
  • Alt-Up : move item up
  • + *
  • Alt-Down : move item down
  • + *
  • Delete : remove item
  • + *
+ * + * Technical note: the symbolic key names are found in + * /usr/include/gtk-2.0/gdk/gdkkeysyms.h, + * and the symbolic modifier names are found in + * /usr/include/gtk-2.0/gdk/gdktypes.h. + * + * TODO: make keys customizable from a config file? + * + * @param event the button event recieved + * @return true if the key press was fully handled, false if not + */ + bool + onKeyPressed(GdkEventKey * event) throw (); + + /** + * Find (an iterator pointing to) the currently selected row. + * + * This is an auxilliary function used by onKeyPressed(). + */ + void + findCurrentItem(void) throw (); + + /** + * Select (highlight) the nth row. + * + * This is an auxilliary function used by onUpItem() and onDownItem(). + * + * @param rowNumber the number of the row to be selected. + */ + void + selectRow(int rowNumber) throw (); + /** * Signal handler for the save button clicked. */