Added keyboard shortcuts for move up, move down and delete.

This fixes issue #1430.
This commit is contained in:
fgerlits 2005-09-28 12:52:03 +00:00
parent bdf2bba1bb
commit d235b8faa6
4 changed files with 222 additions and 3 deletions

View file

@ -53,6 +53,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 */
@ -106,6 +120,10 @@ LiveModeWindow :: LiveModeWindow (Ptr<GLiveSupport>::Ref gLiveSupport,
&LiveModeWindow::onEntryClicked));
treeView->signal_row_activated().connect(sigc::mem_fun(*this,
&LiveModeWindow::onDoubleClick));
// register the signal handler for keyboard key presses
treeView->signal_key_press_event().connect(sigc::mem_fun(*this,
&LiveModeWindow::onKeyPressed));
// Add the TreeView, inside a ScrolledWindow, with the button underneath:
scrolledWindow.add(*treeView);
@ -284,7 +302,7 @@ LiveModeWindow :: onOutputPlay(void) throw ()
* Event handler for an entry being clicked in the list.
*----------------------------------------------------------------------------*/
void
LiveModeWindow :: onEntryClicked (GdkEventButton * event) throw ()
LiveModeWindow :: onEntryClicked(GdkEventButton * event) throw ()
{
if (event->type == GDK_BUTTON_PRESS && event->button == 3) {
Glib::RefPtr<Gtk::TreeView::Selection> refSelection =
@ -323,3 +341,39 @@ LiveModeWindow :: onDoubleClick(const Gtk::TreeModel::Path & path,
onOutputPlay();
}
/*------------------------------------------------------------------------------
* Event handler for a key pressed.
*----------------------------------------------------------------------------*/
bool
LiveModeWindow :: onKeyPressed(GdkEventKey * event) throw ()
{
if (event->type == GDK_KEY_PRESS) {
Glib::RefPtr<Gtk::TreeView::Selection> refSelection =
treeView->get_selection();
Gtk::TreeModel::iterator iter = refSelection->get_selected();
if (iter) {
if ((event->keyval == GDK_Up
|| event->keyval == GDK_KP_Up)
&& (event->state & MODIFIERS_CHECKED) == GDK_MOD1_MASK) {
treeView->onUpMenuOption();
return true;
} else if ((event->keyval == GDK_Down
|| event->keyval == GDK_KP_Down)
&& (event->state & MODIFIERS_CHECKED) == GDK_MOD1_MASK) {
treeView->onDownMenuOption();
return true;
} else if (event->keyval == GDK_Delete
|| event->keyval == GDK_KP_Delete) {
treeView->onRemoveMenuOption();
return true;
}
}
}
return false;
}

View file

@ -164,7 +164,7 @@ class LiveModeWindow : public WhiteWindow, public LocalizedObject
* @param event the button event recieved
*/
void
onEntryClicked(GdkEventButton * event) throw ();
onEntryClicked(GdkEventButton * event) throw ();
/**
* Signal handler for the user double-clicking, or pressing Enter
@ -177,6 +177,28 @@ class LiveModeWindow : public WhiteWindow, public LocalizedObject
const Gtk::TreeViewColumn * column)
throw ();
/**
* Signal handler for a key pressed at one of the entries.
* The keys handled are:
* <ul>
* <li>Alt-Up : move item up</li>
* <li>Alt-Down : move item down</li>
* <li>Delete : remove item</li>
* </ul>
*
* Technical note: the symbolic key names are found in
* <code>/usr/include/gtk-2.0/gdk/gdkkeysyms.h</code>,
* and the symbolic modifier names are found in
* <code>/usr/include/gtk-2.0/gdk/gdktypes.h</code>.
*
* 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 ();
/**
* Signal handler for the "rows reordered" event.
*/

View file

@ -53,6 +53,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 */
@ -122,6 +136,10 @@ ScratchpadWindow :: ScratchpadWindow (Ptr<GLiveSupport>::Ref gLiveSupport,
treeView->signal_row_activated().connect(sigc::mem_fun(*this,
&ScratchpadWindow::onDoubleClick));
// register the signal handler for keyboard key presses
treeView->signal_key_press_event().connect(sigc::mem_fun(*this,
&ScratchpadWindow::onKeyPressed));
// Add the TreeView, inside a ScrolledWindow, with the button underneath:
scrolledWindow.add(*treeView);
@ -388,13 +406,37 @@ ScratchpadWindow :: onEntryClicked (GdkEventButton * event) throw ()
}
/*------------------------------------------------------------------------------
* Select the row which contains the playable specified.
*----------------------------------------------------------------------------*/
void
ScratchpadWindow :: selectRow(Ptr<Playable>::Ref playable) throw ()
{
Gtk::TreeModel::const_iterator iter;
for (iter = treeModel->children().begin();
iter != treeModel->children().end(); ++iter) {
Gtk::TreeRow row = *iter;
Ptr<Playable>::Ref currentPlayable = row[modelColumns.playableColumn];
if (*playable->getId() == *currentPlayable->getId()) {
Glib::RefPtr<Gtk::TreeView::Selection>
selection = treeView->get_selection();
selection->select(iter);
return;
}
}
}
/*------------------------------------------------------------------------------
* Event handler for the Up menu item selected from the entry context menu
*----------------------------------------------------------------------------*/
void
ScratchpadWindow :: onUpItem(void) throw ()
{
Ptr<Playable>::Ref playable = currentRow[modelColumns.playableColumn];
Ptr<Playable>::Ref playable = currentRow[modelColumns.playableColumn];
Ptr<GLiveSupport::PlayableList>::Ref scratchpadContents;
GLiveSupport::PlayableList::iterator it;
@ -421,6 +463,8 @@ ScratchpadWindow :: onUpItem(void) throw ()
it++;
}
selectRow(playable);
}
@ -460,6 +504,8 @@ ScratchpadWindow :: onDownItem(void) throw ()
it++;
}
selectRow(playable);
}
@ -590,3 +636,58 @@ ScratchpadWindow :: onDoubleClick(const Gtk::TreeModel::Path & path,
}
}
/*------------------------------------------------------------------------------
* Event handler for a key pressed.
*----------------------------------------------------------------------------*/
bool
ScratchpadWindow :: 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) {
if (isSelectionSingle()) {
onUpItem();
return true;
}
} else if ((event->keyval == GDK_Down
|| event->keyval == GDK_KP_Down)
&& (event->state & MODIFIERS_CHECKED) == GDK_MOD1_MASK) {
if (isSelectionSingle()) {
onDownItem();
return true;
}
} else if (event->keyval == GDK_Delete
|| event->keyval == GDK_KP_Delete) {
onRemoveItemButtonClicked();
return true;
}
}
return false;
}
/*------------------------------------------------------------------------------
* Check whether exactly one row is selected.
*----------------------------------------------------------------------------*/
bool
ScratchpadWindow :: isSelectionSingle(void) throw ()
{
Glib::RefPtr<Gtk::TreeView::Selection>
selection = treeView->get_selection();
std::vector<Gtk::TreePath>
selectedRows = selection->get_selected_rows();
if (selectedRows.size() == 1) {
Gtk::TreeIter iter = treeModel->get_iter(selectedRows.at(0));
currentRow = *iter;
return true;
} else {
return false;
}
}

View file

@ -79,6 +79,26 @@ class ScratchpadWindow : public WhiteWindow,
public LocalizedObject
{
private:
/**
* Check whether exactly one row is selected, and if so, set
* the currentRow variable to point to it.
*
* This is an auxilliary function used by onKeyPressed().
*
* @return true if a single row is selected, false if not.
*/
bool
isSelectionSingle(void) throw ();
/**
* Select the (first) row which contains the playable specified.
* If no such row is found, then it does nothing.
*
* @param playable the playable to be selected.
*/
void
selectRow(Ptr<Playable>::Ref playable) throw ();
protected:
@ -234,6 +254,28 @@ class ScratchpadWindow : public WhiteWindow,
const Gtk::TreeViewColumn * column)
throw ();
/**
* Signal handler for a key pressed at one of the entries.
* The keys handled are:
* <ul>
* <li>Alt-Up : move item up</li>
* <li>Alt-Down : move item down</li>
* <li>Delete : remove item</li>
* </ul>
*
* Technical note: the symbolic key names are found in
* <code>/usr/include/gtk-2.0/gdk/gdkkeysyms.h</code>,
* and the symbolic modifier names are found in
* <code>/usr/include/gtk-2.0/gdk/gdktypes.h</code>.
*
* 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 ();
/**
* Signal handler for the "up" menu item selected from
* the entry context menu.