Added keyboard shortcuts for move up, move down and delete.
This fixes issue #1430.
This commit is contained in:
parent
bdf2bba1bb
commit
d235b8faa6
4 changed files with 222 additions and 3 deletions
|
@ -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 */
|
||||
|
||||
|
@ -107,6 +121,10 @@ LiveModeWindow :: LiveModeWindow (Ptr<GLiveSupport>::Ref gLiveSupport,
|
|||
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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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,6 +406,30 @@ 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
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue