From e0eaa00b00b8b0049853d41fed010705f6cd0cdc Mon Sep 17 00:00:00 2001 From: xorloser Date: Sun, 20 Sep 2020 17:34:27 +1000 Subject: [PATCH 1/2] Added the under-the-hood code to support customisation of keys/mousewheel used to navigate the traces such as for multiple levels of moving and zooming. --- pv/views/trace/view.cpp | 137 ++++++++++++++++++++++- pv/views/trace/view.hpp | 210 +++++++++++++++++++++++++++++++++++- pv/views/trace/viewport.cpp | 14 +-- 3 files changed, 341 insertions(+), 20 deletions(-) diff --git a/pv/views/trace/view.cpp b/pv/views/trace/view.cpp index 47cb96b2..7947df8a 100644 --- a/pv/views/trace/view.cpp +++ b/pv/views/trace/view.cpp @@ -223,11 +223,6 @@ View::View(Session &session, bool is_main_view, QMainWindow *parent) : SLOT(on_zoom_out_shortcut_triggered()), nullptr, Qt::WidgetWithChildrenShortcut); zoom_out_shortcut_->setAutoRepeat(false); - zoom_in_shortcut_2_ = new QShortcut(QKeySequence(Qt::Key_Up), this, - SLOT(on_zoom_in_shortcut_triggered()), nullptr, Qt::WidgetWithChildrenShortcut); - zoom_out_shortcut_2_ = new QShortcut(QKeySequence(Qt::Key_Down), this, - SLOT(on_zoom_out_shortcut_triggered()), nullptr, Qt::WidgetWithChildrenShortcut); - home_shortcut_ = new QShortcut(QKeySequence(Qt::Key_Home), this, SLOT(on_scroll_to_start_shortcut_triggered()), nullptr, Qt::WidgetWithChildrenShortcut); home_shortcut_->setAutoRepeat(false); @@ -254,6 +249,52 @@ View::View(Session &session, bool is_main_view, QMainWindow *parent) : this, [=]{grabbed_widget_ = nullptr;}); cancel_grab_shortcut_->setAutoRepeat(false); + // Keyboard navigation + // This sets them all up as disabled initially. + NAV_KB_VAR_SETUP(up, Qt::Key_Up); + NAV_KB_VAR_SETUP(down, Qt::Key_Down); + NAV_KB_VAR_SETUP(left, Qt::Key_Left); + NAV_KB_VAR_SETUP(right, Qt::Key_Right); + NAV_KB_VAR_SETUP(pageup, Qt::Key_PageUp); + NAV_KB_VAR_SETUP(pagedown, Qt::Key_PageDown); + // Next we set the default types and amounts to start with when the user has not changed them yet + // vertical movement + NAV_KB_VAR_DEFAULT(up, NAV_TYPE_VERT, -0.125); // up arrow will move the traces up by 1/8 page + NAV_KB_VAR_DEFAULT(down, NAV_TYPE_VERT, 0.125); // down arrow will move the traces up by 1/8 page + // zoom + NAV_KB_VAR_DEFAULT(up_shift, NAV_TYPE_ZOOM, -1.0); // up arrow + shift will zoom in by 1x + NAV_KB_VAR_DEFAULT(down_shift, NAV_TYPE_ZOOM, 1.0); // down arrow + shift will zoom out by 1x + NAV_KB_VAR_DEFAULT(pageup_shift, NAV_TYPE_ZOOM, -2.0); // page up + shift will zoom in by 2x + NAV_KB_VAR_DEFAULT(pagedown_shift, NAV_TYPE_ZOOM, 2.0); // page down + shift will zoom out by 2x + // small horizontal movement + NAV_KB_VAR_DEFAULT(left, NAV_TYPE_HORI, -0.125); // left arrow will move the trace backwards by 1/8 page + NAV_KB_VAR_DEFAULT(right, NAV_TYPE_HORI, 0.125); // right arrow will move the trace forwards by 1/8 page + NAV_KB_VAR_DEFAULT(left_alt, NAV_TYPE_HORI, -0.25); // left arrow + alt will move the trace backwards by 1/4 page + NAV_KB_VAR_DEFAULT(right_alt, NAV_TYPE_HORI, 0.25); // right arrow + alt will move the trace forwards by 1/4 page + NAV_KB_VAR_DEFAULT(left_ctrl, NAV_TYPE_HORI, -0.5); // left arrow + ctrl will move the trace backwards by 1/2 page + NAV_KB_VAR_DEFAULT(right_ctrl, NAV_TYPE_HORI, 0.5); // right arrow + ctrl will move the trace forwards by 1/2 page + // big horizontal movement + NAV_KB_VAR_DEFAULT(pageup, NAV_TYPE_HORI, -1.0); // page up will move the trace backwards by 1 page + NAV_KB_VAR_DEFAULT(pagedown, NAV_TYPE_HORI, 1.0); // page down will move the trace forwards by 1 page + NAV_KB_VAR_DEFAULT(pageup_alt, NAV_TYPE_HORI, -2.0); // page up + alt will move the trace backwards by 2 pages + NAV_KB_VAR_DEFAULT(pagedown_alt, NAV_TYPE_HORI, 2.0); // page down + alt will move the trace forwards by 2 pages + NAV_KB_VAR_DEFAULT(pageup_ctrl, NAV_TYPE_HORI, -4.0); // page up + ctrl will move the trace backwards by 4 pages + NAV_KB_VAR_DEFAULT(pagedown_ctrl, NAV_TYPE_HORI, 4.0); // page down + ctrl will move the trace forwards by 4 pages + + // Mousewheel navigation + // This sets them all up as disabled initially. + NAV_MW_VAR_SETUP(hori); + NAV_MW_VAR_SETUP(vert); + // Next we set the default types and amounts to start with when the user has not changed them yet + NAV_MW_VAR_DEFAULT(hori_shift, NAV_TYPE_ZOOM, 0.25); // horizontal mousewheel + shift will zoom the traces by 1/4 x + NAV_MW_VAR_DEFAULT(vert_shift, NAV_TYPE_ZOOM, 0.25); // vertical mousewheel + shift will zoom the traces by 1/4 x + NAV_MW_VAR_DEFAULT(hori, NAV_TYPE_HORI, 0.25); // horizontal mousewheel will move the traces up by 1/4 page + NAV_MW_VAR_DEFAULT(vert, NAV_TYPE_HORI, 0.25); // vertical mousewheel will move the traces up by 1/4 page + NAV_MW_VAR_DEFAULT(hori_alt, NAV_TYPE_HORI, 0.5); // horizontal mousewheel + alt will move the traces up by 1/2 page + NAV_MW_VAR_DEFAULT(vert_alt, NAV_TYPE_HORI, 0.5); // vertical mousewheel + alt will move the traces up by 1/2 page + NAV_MW_VAR_DEFAULT(hori_ctrl, NAV_TYPE_HORI, 1.0); // horizontal mousewheel + ctrl will move the traces up by 1 page + NAV_MW_VAR_DEFAULT(vert_ctrl, NAV_TYPE_HORI, 1.0); // vertical mousewheel + ctrl will move the traces up by 14 page + // Trigger the initial event manually. The default device has signals // which were created before this object came into being signals_changed(); @@ -514,6 +555,16 @@ void View::save_settings(QSettings &settings) const signal->save_settings(settings); settings.endGroup(); } + + NAV_KB_SAVE(up); + NAV_KB_SAVE(down); + NAV_KB_SAVE(left); + NAV_KB_SAVE(right); + NAV_KB_SAVE(pageup); + NAV_KB_SAVE(pagedown); + + NAV_MW_SAVE(hori); + NAV_MW_SAVE(vert); } void View::restore_settings(QSettings &settings) @@ -551,6 +602,16 @@ void View::restore_settings(QSettings &settings) scroll_needs_defaults_ = false; } + NAV_KB_RESTORE(up); + NAV_KB_RESTORE(down); + NAV_KB_RESTORE(left); + NAV_KB_RESTORE(right); + NAV_KB_RESTORE(pageup); + NAV_KB_RESTORE(pagedown); + + NAV_MW_RESTORE(hori); + NAV_MW_RESTORE(vert); + restoring_state_ = true; // Update the ruler so that it uses the new scale @@ -1738,6 +1799,72 @@ void View::on_scroll_to_end_shortcut_triggered() set_h_offset(get_h_scrollbar_maximum()); } + +void View::nav_zoom(double numTimes) +{ + zoom(numTimes); +} + +void View::nav_zoom(double numTimes, int offset) +{ + zoom(numTimes, offset); +} + +void View::nav_move_hori(double numPages) +{ + double page_width = viewport_->width(); + double move_amount = numPages * page_width; + int curr_pos = scrollarea_->horizontalScrollBar()->sliderPosition(); + int new_pos = curr_pos + move_amount; + +// printf("nav_move_hori(): page_width=%g move_amount=%g curr_pos=%d new_pos=%d\n", +// page_width, move_amount, curr_pos, new_pos); + + set_h_offset(new_pos); +} + +// amount is double value representing numPages. +// 1.0 is a full page down +// -1.0 is a full page up +void View::nav_move_vert(double numPages) +{ + double page_height = viewport_->height(); + double move_amount = numPages * page_height; + int curr_pos = scrollarea_->verticalScrollBar()->sliderPosition(); + int new_pos = curr_pos + move_amount; + +// printf("nav_move_vert(): page_height=%g move_amount=%g curr_pos=%d new_pos=%d\n", +// page_height, move_amount, curr_pos, new_pos); + + set_v_offset(new_pos); +} + +NAV_KB_FUNC_DEFINE(up) +NAV_KB_FUNC_DEFINE(down) +NAV_KB_FUNC_DEFINE(left) +NAV_KB_FUNC_DEFINE(right) +NAV_KB_FUNC_DEFINE(pageup) +NAV_KB_FUNC_DEFINE(pagedown) + +NAV_MW_FUNC_DEFINE(hori) +NAV_MW_FUNC_DEFINE(vert) + +void View::on_mw_vert_all(QWheelEvent *event) +{ + if (event->modifiers() & Qt::AltModifier) on_mw_vert_alt(event); + else if (event->modifiers() & Qt::ControlModifier) on_mw_vert_ctrl(event); + else if (event->modifiers() & Qt::ShiftModifier) on_mw_vert_shift(event); + else on_mw_vert(event); +} + +void View::on_mw_hori_all(QWheelEvent *event) +{ + if (event->modifiers() & Qt::AltModifier) on_mw_hori_alt(event); + else if (event->modifiers() & Qt::ControlModifier) on_mw_hori_ctrl(event); + else if (event->modifiers() & Qt::ShiftModifier) on_mw_hori_shift(event); + else on_mw_hori(event); +} + void View::h_scroll_value_changed(int value) { if (updating_scroll_) diff --git a/pv/views/trace/view.hpp b/pv/views/trace/view.hpp index f8506cf4..2c6f1934 100644 --- a/pv/views/trace/view.hpp +++ b/pv/views/trace/view.hpp @@ -80,6 +80,183 @@ class CustomScrollArea : public QAbstractScrollArea bool viewportEvent(QEvent *event); }; +// This Navigation code handles customisation of keyboard and mousewheel controls +// for navigating the traces by moving them and zooming them. +// Code is done to support the custom controls as well as saving and restoring them +// from settings. Missing is code to set/get them from a GUI settings dialog. +// +// TODO: Add GUI support for getting and setting the navigation params. +// The GUI can call these provided functions to get set the values: +// View::nav_kb_up_alt_get() / View::nav_kb_up_alt_set() +// View::nav_mw_vert_get() / View::nav_mw_vert_set() +// etc +// +// Currently the customisations can only be changed by editing where the settings +// are stored which is platform specific: +// - Windows: stored in registry at "Computer\HKEY_CURRENT_USER\SOFTWARE\sigrok\PulseView\Session0\view0" +// - Linux: stored in a file at ~/.config/sigrok/pulseview.conf +// - Mac: stored in a file at ~/Library/Preferences/pulseview.plist + +// type of navigation to perform +#define NAV_TYPE_NONE 0 +#define NAV_TYPE_ZOOM 1 +#define NAV_TYPE_HORI 2 +#define NAV_TYPE_VERT 3 + +// navigation using keyboard +typedef struct { + int type; // NAV_TYPE_??? value + double amount; // amount to perform nav operation by + QShortcut* sc; +} NavKb_t; + +// navigation using mousewheel +typedef struct { + int type; // NAV_TYPE_??? value + double amount; // amount to perform nav operation by +} NavMw_t; + +// keyboard +#define NAV_KB_VAR_DECLARE(name) \ + NavKb_t name ## _nav_, name ## _alt_nav_, name ## _ctrl_nav_, name ## _shift_nav_ + +#define NAV_KB_VAR_SETUP(name, keys) \ + name ## _nav_.type = NAV_TYPE_NONE;\ + name ## _alt_nav_.type = NAV_TYPE_NONE;\ + name ## _ctrl_nav_.type = NAV_TYPE_NONE;\ + name ## _shift_nav_.type = NAV_TYPE_NONE;\ + name ## _nav_.amount = 0; \ + name ## _alt_nav_.amount = 0; \ + name ## _ctrl_nav_.amount = 0; \ + name ## _shift_nav_.amount = 0; \ + name ## _nav_.sc = new QShortcut(QKeySequence(keys), this, SLOT(on_kb_ ##name ()), nullptr, Qt::WidgetWithChildrenShortcut); \ + name ## _alt_nav_.sc = new QShortcut(QKeySequence(keys + Qt::ALT), this, SLOT(on_kb_ ##name## _alt()), nullptr, Qt::WidgetWithChildrenShortcut); \ + name ## _ctrl_nav_.sc = new QShortcut(QKeySequence(keys + Qt::CTRL), this, SLOT(on_kb_ ##name## _ctrl()), nullptr, Qt::WidgetWithChildrenShortcut); \ + name ## _shift_nav_.sc = new QShortcut(QKeySequence(keys + Qt::SHIFT), this, SLOT(on_kb_ ##name## _shift()), nullptr, Qt::WidgetWithChildrenShortcut) + +#define NAV_KB_VAR_DEFAULT(name, t, a) \ + name ## _nav_.type = t; \ + name ## _nav_.amount = a + +#define NAV_KB_FUNC_DECLARE1(name) \ + void on_kb_ ## name (); \ + void nav_kb_ ## name ## _set(int type, double amount); \ + void nav_kb_ ## name ## _get(int* type, double* amount) + +#define NAV_KB_FUNC_DECLARE(name) \ + NAV_KB_FUNC_DECLARE1(name); \ + NAV_KB_FUNC_DECLARE1(name ## _alt); \ + NAV_KB_FUNC_DECLARE1(name ## _ctrl); \ + NAV_KB_FUNC_DECLARE1(name ## _shift) + +#define NAV_KB_FUNC_DEFINE1(name) \ + void View::on_kb_ ## name () { \ + if ( name ## _nav_.type == NAV_TYPE_NONE )return; \ + else if (name ## _nav_.type == NAV_TYPE_ZOOM )nav_zoom(name ## _nav_.amount); \ + else if (name ## _nav_.type == NAV_TYPE_HORI )nav_move_hori(name ## _nav_.amount); \ + else if (name ## _nav_.type == NAV_TYPE_VERT )nav_move_vert(name ## _nav_.amount); \ + } \ + void View::nav_kb_ ## name ## _set(int type, double amount) { \ + name ## _nav_.type = type; \ + name ## _nav_.amount = amount; \ + } \ + void View::nav_kb_ ## name ## _get(int* type, double* amount) { \ + if(type) *type = name ## _nav_.type; \ + if(amount) *amount = name ## _nav_.amount; \ + } + +#define NAV_KB_FUNC_DEFINE(name) \ + NAV_KB_FUNC_DEFINE1(name) \ + NAV_KB_FUNC_DEFINE1(name ## _alt) \ + NAV_KB_FUNC_DEFINE1(name ## _ctrl) \ + NAV_KB_FUNC_DEFINE1(name ## _shift) + +// mousewheel +#define NAV_MW_VAR_DECLARE(name) \ + NavMw_t name ## _nav_, name ## _alt_nav_, name ## _ctrl_nav_, name ## _shift_nav_ + +#define NAV_MW_VAR_SETUP(name) \ + name ## _nav_.type = NAV_TYPE_NONE;\ + name ## _alt_nav_.type = NAV_TYPE_NONE;\ + name ## _ctrl_nav_.type = NAV_TYPE_NONE;\ + name ## _shift_nav_.type = NAV_TYPE_NONE;\ + name ## _nav_.amount = 0; \ + name ## _alt_nav_.amount = 0; \ + name ## _ctrl_nav_.amount = 0; \ + name ## _shift_nav_.amount = 0 + +#define NAV_MW_VAR_DEFAULT(name, t, a) \ + name ## _nav_.type = t; \ + name ## _nav_.amount = a + +#define NAV_MW_FUNC_DECLARE1(name) \ + void on_mw_ ## name (QWheelEvent *event); \ + void nav_mw_ ## name ## _set(int type, double amount); \ + void nav_mw_ ## name ## _get(int* type, double* amount) + +#define NAV_MW_FUNC_DECLARE(name) \ + NAV_MW_FUNC_DECLARE1(name); \ + NAV_MW_FUNC_DECLARE1(name ## _alt); \ + NAV_MW_FUNC_DECLARE1(name ## _ctrl); \ + NAV_MW_FUNC_DECLARE1(name ## _shift) + +#define NAV_MW_FUNC_DEFINE1(name) \ + void View::on_mw_ ## name (QWheelEvent *event) { \ + if ( name ## _nav_.type == NAV_TYPE_NONE )return; \ + else if (name ## _nav_.type == NAV_TYPE_ZOOM )nav_zoom( (-event->delta() * name ## _nav_.amount)/120.0, event->x()); \ + else if (name ## _nav_.type == NAV_TYPE_HORI )nav_move_hori((-event->delta() * name ## _nav_.amount)/120.0); \ + else if (name ## _nav_.type == NAV_TYPE_VERT )nav_move_vert((-event->delta() * name ## _nav_.amount)/120.0); \ + } \ + void View::nav_mw_ ## name ## _set(int type, double amount) { \ + name ## _nav_.type = type; \ + name ## _nav_.amount = amount; \ + } \ + void View::nav_mw_ ## name ## _get(int* type, double* amount) { \ + if(type) *type = name ## _nav_.type; \ + if(amount) *amount = name ## _nav_.amount; \ + } + +#define NAV_MW_FUNC_DEFINE(name) \ + NAV_MW_FUNC_DEFINE1(name) \ + NAV_MW_FUNC_DEFINE1(name ## _alt) \ + NAV_MW_FUNC_DEFINE1(name ## _ctrl) \ + NAV_MW_FUNC_DEFINE1(name ## _shift) + + +#define NAV_SAVE1(name) \ + settings.setValue("nav_" #name "_type", name ## _nav_.type); \ + settings.setValue("nav_" #name "_amount", name ## _nav_.amount) + +#define NAV_KB_SAVE(name) \ + NAV_SAVE1(name); \ + NAV_SAVE1(name ## _alt);\ + NAV_SAVE1(name ## _ctrl);\ + NAV_SAVE1(name ## _shift) + +#define NAV_MW_SAVE(name) \ + NAV_SAVE1(name); \ + NAV_SAVE1(name ## _alt);\ + NAV_SAVE1(name ## _ctrl);\ + NAV_SAVE1(name ## _shift) + + +#define NAV_RESTORE1(name) \ + if (settings.contains("nav_" #name "_type")) name ## _nav_.type = settings.value("nav_" #name "_type").toInt(); \ + if (settings.contains("nav_" #name "_amount")) name ## _nav_.amount = settings.value("nav_" #name "_amount").toDouble() + +#define NAV_KB_RESTORE(name) \ + NAV_RESTORE1(name); \ + NAV_RESTORE1(name ## _alt); \ + NAV_RESTORE1(name ## _ctrl);\ + NAV_RESTORE1(name ## _shift) + +#define NAV_MW_RESTORE(name) \ + NAV_RESTORE1(name); \ + NAV_RESTORE1(name ## _alt); \ + NAV_RESTORE1(name ## _ctrl);\ + NAV_RESTORE1(name ## _shift) + + class View : public ViewBase, public TraceTreeItemOwner, public GlobalSettingsInterface { Q_OBJECT @@ -429,6 +606,14 @@ public Q_SLOTS: void extents_changed(bool horz, bool vert); + void nav_zoom(double amount); + void nav_zoom(double amount, int offset); + void nav_move_hori(double amount); + void nav_move_vert(double amount); + + void on_mw_vert_all(QWheelEvent *event); + void on_mw_hori_all(QWheelEvent *event); + private Q_SLOTS: void on_signal_name_changed(); void on_splitter_moved(); @@ -446,6 +631,16 @@ private Q_SLOTS: void signals_changed(); void capture_state_updated(int state); + NAV_KB_FUNC_DECLARE(up); + NAV_KB_FUNC_DECLARE(down); + NAV_KB_FUNC_DECLARE(left); + NAV_KB_FUNC_DECLARE(right); + NAV_KB_FUNC_DECLARE(pageup); + NAV_KB_FUNC_DECLARE(pagedown); + + NAV_MW_FUNC_DECLARE(hori); + NAV_MW_FUNC_DECLARE(vert); + void on_new_segment(int new_segment_id); void on_segment_completed(int new_segment_id); void on_segment_changed(int segment); @@ -504,12 +699,21 @@ private Q_SLOTS: Header *header_; QSplitter *splitter_; - QShortcut *zoom_in_shortcut_, *zoom_in_shortcut_2_; - QShortcut *zoom_out_shortcut_, *zoom_out_shortcut_2_; + QShortcut *zoom_in_shortcut_, *zoom_out_shortcut_; QShortcut *home_shortcut_, *end_shortcut_; QShortcut *grab_ruler_left_shortcut_, *grab_ruler_right_shortcut_; QShortcut *cancel_grab_shortcut_; - + + // keyboard and mousewheel navigation + NAV_KB_VAR_DECLARE(up); + NAV_KB_VAR_DECLARE(down); + NAV_KB_VAR_DECLARE(left); + NAV_KB_VAR_DECLARE(right); + NAV_KB_VAR_DECLARE(pageup); + NAV_KB_VAR_DECLARE(pagedown); + NAV_MW_VAR_DECLARE(hori); + NAV_MW_VAR_DECLARE(vert); + mutable mutex signal_mutex_; vector< shared_ptr > signals_; diff --git a/pv/views/trace/viewport.cpp b/pv/views/trace/viewport.cpp index 0c73ec49..7753dc60 100644 --- a/pv/views/trace/viewport.cpp +++ b/pv/views/trace/viewport.cpp @@ -212,19 +212,9 @@ void Viewport::wheelEvent(QWheelEvent *event) assert(event); if (event->orientation() == Qt::Vertical) { - if (event->modifiers() & Qt::ControlModifier) { - // Vertical scrolling with the control key pressed - // is intrepretted as vertical scrolling - view_.set_v_offset(-view_.owner_visual_v_offset() - - (event->delta() * height()) / (8 * 120)); - } else { - // Vertical scrolling is interpreted as zooming in/out - view_.zoom(event->delta() / 120.0, event->x()); - } + view_.on_mw_vert_all(event); } else if (event->orientation() == Qt::Horizontal) { - // Horizontal scrolling is interpreted as moving left/right - view_.set_scale_offset(view_.scale(), - event->delta() * view_.scale() + view_.offset()); + view_.on_mw_hori_all(event); } } From 8ed7b72f25b750c142934c37f09c85813490a1b7 Mon Sep 17 00:00:00 2001 From: xorloser Date: Wed, 23 Sep 2020 17:58:00 +1000 Subject: [PATCH 2/2] Finished customised navigation by adding GUI support for setting the customisations --- icons/navigation.svg | 535 ++++++++++++++++++++++++++++++++++++++++ pulseview.qrc | 1 + pv/dialogs/settings.cpp | 89 +++++++ pv/dialogs/settings.hpp | 89 ++++++- pv/globalsettings.cpp | 75 +++++- pv/globalsettings.hpp | 40 +++ pv/views/trace/view.cpp | 89 +++---- pv/views/trace/view.hpp | 161 ++++++------ 8 files changed, 946 insertions(+), 133 deletions(-) create mode 100644 icons/navigation.svg diff --git a/icons/navigation.svg b/icons/navigation.svg new file mode 100644 index 00000000..cbafe7b3 --- /dev/null +++ b/icons/navigation.svg @@ -0,0 +1,535 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pulseview.qrc b/pulseview.qrc index ceda06df..069dd8eb 100644 --- a/pulseview.qrc +++ b/pulseview.qrc @@ -16,6 +16,7 @@ icons/media-playback-pause.png icons/media-playback-start.png icons/menu.svg + icons/navigation.svg icons/preferences-system.png icons/settings-general.png icons/settings-views.svg diff --git a/pv/dialogs/settings.cpp b/pv/dialogs/settings.cpp index efe854af..50eedece 100644 --- a/pv/dialogs/settings.cpp +++ b/pv/dialogs/settings.cpp @@ -144,6 +144,15 @@ void Settings::create_pages() viewButton->setTextAlignment(Qt::AlignVCenter); viewButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); + // Navigation page + pages->addWidget(get_navigation_settings_form(pages)); + + QListWidgetItem *navButton = new QListWidgetItem(page_list); + navButton->setIcon(QIcon(":/icons/navigation.svg")); + navButton->setText(tr("Navigation")); + navButton->setTextAlignment(Qt::AlignVCenter); + navButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); + #ifdef ENABLE_DECODE // Decoder page pages->addWidget(get_decoder_settings_form(pages)); @@ -384,6 +393,54 @@ QWidget *Settings::get_view_settings_form(QWidget *parent) const return form; } +QWidget *Settings::get_navigation_settings_form(QWidget *parent) +{ + GlobalSettings settings; + + QWidget *form = new QWidget(parent); + QVBoxLayout *form_layout = new QVBoxLayout(form); + + // Navigation control settings + QGroupBox *nav_group = new QGroupBox(tr("Trace Navigation Controls")); + form_layout->addWidget(nav_group); + + QGridLayout *nav_layout = new QGridLayout(); + nav_group->setLayout(nav_layout); + + int row = 0; + + // buttons for default settings + QPushButton *zoom_but = new QPushButton( tr("Reset to &Zoom as main controls") ); + connect(zoom_but, SIGNAL(clicked(bool)), this, SLOT(on_nav_resetZoomControls_clicked(bool))); + nav_layout->addWidget(zoom_but, row, 0); + QPushButton *move_but = new QPushButton( tr("Reset to &Move as main controls") ); + connect(move_but, SIGNAL(clicked(bool)), this, SLOT(on_nav_resetMoveControls_clicked(bool))); + nav_layout->addWidget(move_but, row, 1); + row++; + + // heading + QLabel *hdr1_label = new QLabel(tr("Control")); + hdr1_label->setAlignment(Qt::AlignLeft); + nav_layout->addWidget(hdr1_label, row, 0); + QLabel *hdr2_label = new QLabel(tr("Operation")); + hdr2_label->setAlignment(Qt::AlignLeft); + nav_layout->addWidget(hdr2_label, row, 1); + QLabel *hdr3_label = new QLabel(tr("NumPages or NumTimes")); + hdr3_label->setAlignment(Qt::AlignLeft); + nav_layout->addWidget(hdr3_label, row, 2); + row++; + // entries + NAV_SETTINGS_ROWS(UpDown, "Up / Down", row); row++; + NAV_SETTINGS_ROWS(LeftRight,"Left / Right", row); row++; + NAV_SETTINGS_ROWS(PageUpDown,"PageUp / PageDown", row); row++; + NAV_SETTINGS_ROWS(WheelHori,"Mouse Wheel Horizontal", row); row++; + NAV_SETTINGS_ROWS(WheelVert,"Mouse Wheel Vertical", row); row++; + + nav_load_gui_from_settings(); + + return form; +} + QWidget *Settings::get_decoder_settings_form(QWidget *parent) { #ifdef ENABLE_DECODE @@ -769,6 +826,38 @@ void Settings::on_view_defaultLogicHeight_changed(int value) settings.setValue(GlobalSettings::Key_View_DefaultLogicHeight, value); } +void Settings::on_nav_resetZoomControls_clicked(bool checked) +{ + printf("on_nav_resetZoomControls_clicked : %d\n", checked?1:0); + GlobalSettings settings; + settings.set_nav_zoom_defaults(true); + nav_load_gui_from_settings(); +} + +void Settings::on_nav_resetMoveControls_clicked(bool checked) +{ + printf("on_nav_resetMoveControls_clicked : %d\n", checked?1:0); + GlobalSettings settings; + settings.set_nav_move_defaults(true); + nav_load_gui_from_settings(); +} + +NAV_SETTINGS_FUNC_DEFINE(UpDown) +NAV_SETTINGS_FUNC_DEFINE(LeftRight) +NAV_SETTINGS_FUNC_DEFINE(PageUpDown) +NAV_SETTINGS_FUNC_DEFINE(WheelHori) +NAV_SETTINGS_FUNC_DEFINE(WheelVert) + +void Settings::nav_load_gui_from_settings() +{ + GlobalSettings settings; + NAV_SETTINGS_LOAD(UpDown); + NAV_SETTINGS_LOAD(LeftRight); + NAV_SETTINGS_LOAD(PageUpDown); + NAV_SETTINGS_LOAD(WheelHori); + NAV_SETTINGS_LOAD(WheelVert); +} + #ifdef ENABLE_DECODE void Settings::on_dec_initialStateConfigurable_changed(int state) { diff --git a/pv/dialogs/settings.hpp b/pv/dialogs/settings.hpp index 157fa6ba..764a8c99 100644 --- a/pv/dialogs/settings.hpp +++ b/pv/dialogs/settings.hpp @@ -27,6 +27,79 @@ #include #include #include +#include + +#define NAV_SETTINGS_FUNC_DECLARE1(name) \ + void on_nav_ ## name ## Type_changed(int type); \ + void on_nav_ ## name ## Amount_changed(const QString& astr) + +#define NAV_SETTINGS_FUNC_DECLARE(name) \ + NAV_SETTINGS_FUNC_DECLARE1(name); \ + NAV_SETTINGS_FUNC_DECLARE1(name ## Alt);\ + NAV_SETTINGS_FUNC_DECLARE1(name ## Ctrl);\ + NAV_SETTINGS_FUNC_DECLARE1(name ## Shift) + +#define NAV_SETTINGS_FUNC_DEFINE1(name) \ + void Settings::on_nav_ ## name ## Type_changed(int type){ \ + GlobalSettings settings; \ + settings.setValue(GlobalSettings::Key_Nav_ ## name ## Type, type); \ + } \ + void Settings::on_nav_ ## name ## Amount_changed(const QString& astr) { \ + GlobalSettings settings; \ + settings.setValue(GlobalSettings::Key_Nav_ ## name ## Amount, astr.toDouble()); \ + } + +#define NAV_SETTINGS_FUNC_DEFINE(name) \ + NAV_SETTINGS_FUNC_DEFINE1(name) \ + NAV_SETTINGS_FUNC_DEFINE1(name ## Alt) \ + NAV_SETTINGS_FUNC_DEFINE1(name ## Ctrl) \ + NAV_SETTINGS_FUNC_DEFINE1(name ## Shift) + +#define NAV_SETTINGS_ROW(name, text, row) \ + QLabel * name ## _label = new QLabel(tr(text));\ + name ## _label->setAlignment(Qt::AlignLeft); \ + nav_layout->addWidget(name ## _label, row, 0); \ + \ + name ## _type_cb_ = new QComboBox(); \ + name ## _type_cb_->addItem(tr("None"), NAV_TYPE_NONE); \ + name ## _type_cb_->addItem(tr("Zoom"), NAV_TYPE_ZOOM); \ + name ## _type_cb_->addItem(tr("Move Horizontally"), NAV_TYPE_HORI); \ + name ## _type_cb_->addItem(tr("Move Vertically"), NAV_TYPE_VERT); \ + name ## _type_cb_->setCurrentIndex( settings.value(GlobalSettings::Key_Nav_ ## name ## Type).toInt() ); \ + connect(name ## _type_cb_, SIGNAL(currentIndexChanged(int)), this, SLOT(on_nav_ ## name ## Type_changed(int))); \ + nav_layout->addWidget(name ## _type_cb_, row, 1); \ + \ + name ## _amount_edit_ = new QLineEdit(); \ + name ## _amount_edit_->setText( settings.value(GlobalSettings::Key_Nav_ ## name ## Amount).toString() ); \ + connect(name ## _amount_edit_, SIGNAL(textChanged(const QString&)), this, SLOT(on_nav_ ## name ## Amount_changed(const QString&))); \ + nav_layout->addWidget(name ## _amount_edit_, row, 2) +// name ## _amount_edit_->setValidator( new QDoubleValidator(name ## _amount_edit_) ); + +#define NAV_SETTINGS_ROWS(name, text, row) \ + NAV_SETTINGS_ROW(name, text, row*4 + 0); \ + NAV_SETTINGS_ROW(name ## Alt, text " + Alt", row*4 + 1); \ + NAV_SETTINGS_ROW(name ## Ctrl, text " + Ctrl", row*4 + 2); \ + NAV_SETTINGS_ROW(name ## Shift, text " + Shift", row*4 + 3) + +#define NAV_SETTINGS_VAR_DECLARE1(name) \ + QComboBox * name ## _type_cb_; \ + QLineEdit* name ## _amount_edit_ + +#define NAV_SETTINGS_VAR_DECLARE(name) \ + NAV_SETTINGS_VAR_DECLARE1(name); \ + NAV_SETTINGS_VAR_DECLARE1(name ## Alt); \ + NAV_SETTINGS_VAR_DECLARE1(name ## Ctrl); \ + NAV_SETTINGS_VAR_DECLARE1(name ## Shift) + +#define NAV_SETTINGS_LOAD1(name) \ + name ## _type_cb_->setCurrentIndex( settings.value(GlobalSettings::Key_Nav_ ## name ## Type).toInt() ); \ + name ## _amount_edit_->setText( settings.value(GlobalSettings::Key_Nav_ ## name ## Amount).toString() ) + +#define NAV_SETTINGS_LOAD(name) \ + NAV_SETTINGS_LOAD1(name); \ + NAV_SETTINGS_LOAD1(name ## Alt); \ + NAV_SETTINGS_LOAD1(name ## Ctrl); \ + NAV_SETTINGS_LOAD1(name ## Shift) namespace pv { @@ -49,6 +122,7 @@ class Settings : public QDialog QWidget *get_general_settings_form(QWidget *parent) const; QWidget *get_view_settings_form(QWidget *parent) const; + QWidget *get_navigation_settings_form(QWidget *parent); QWidget *get_decoder_settings_form(QWidget *parent); QWidget *get_about_page(QWidget *parent) const; QWidget *get_logging_page(QWidget *parent) const; @@ -77,7 +151,15 @@ private Q_SLOTS: void on_view_conversionThresholdDispMode_changed(int state); void on_view_defaultDivHeight_changed(int value); void on_view_defaultLogicHeight_changed(int value); -#ifdef ENABLE_DECODE + void on_nav_resetZoomControls_clicked(bool checked); + void on_nav_resetMoveControls_clicked(bool checked); + NAV_SETTINGS_FUNC_DECLARE(UpDown); + NAV_SETTINGS_FUNC_DECLARE(LeftRight); + NAV_SETTINGS_FUNC_DECLARE(PageUpDown); + NAV_SETTINGS_FUNC_DECLARE(WheelHori); + NAV_SETTINGS_FUNC_DECLARE(WheelVert); + void nav_load_gui_from_settings(); + #ifdef ENABLE_DECODE void on_dec_initialStateConfigurable_changed(int state); void on_dec_exportFormat_changed(const QString &text); void on_dec_alwaysshowallrows_changed(int state); @@ -91,6 +173,11 @@ private Q_SLOTS: DeviceManager &device_manager_; PageListWidget *page_list; QStackedWidget *pages; + NAV_SETTINGS_VAR_DECLARE(UpDown); + NAV_SETTINGS_VAR_DECLARE(LeftRight); + NAV_SETTINGS_VAR_DECLARE(PageUpDown); + NAV_SETTINGS_VAR_DECLARE(WheelHori); + NAV_SETTINGS_VAR_DECLARE(WheelVert); #ifdef ENABLE_DECODE QLineEdit *ann_export_format_; diff --git a/pv/globalsettings.cpp b/pv/globalsettings.cpp index ca649bef..34ad983b 100644 --- a/pv/globalsettings.cpp +++ b/pv/globalsettings.cpp @@ -70,6 +70,11 @@ const QString GlobalSettings::Key_View_CursorFillColor = "View_CursorFillColor"; const QString GlobalSettings::Key_View_CursorShowFrequency = "View_CursorShowFrequency"; const QString GlobalSettings::Key_View_CursorShowInterval = "View_CursorShowInterval"; const QString GlobalSettings::Key_View_CursorShowSamples = "View_CursorShowSamples"; +NAV_GSETTINGS_VAR_SETUP(UpDown); +NAV_GSETTINGS_VAR_SETUP(LeftRight); +NAV_GSETTINGS_VAR_SETUP(PageUpDown); +NAV_GSETTINGS_VAR_SETUP(WheelHori); +NAV_GSETTINGS_VAR_SETUP(WheelVert); const QString GlobalSettings::Key_Dec_InitialStateConfigurable = "Dec_InitialStateConfigurable"; const QString GlobalSettings::Key_Dec_ExportFormat = "Dec_ExportFormat"; const QString GlobalSettings::Key_Dec_AlwaysShowAllRows = "Dec_AlwaysShowAllRows"; @@ -98,6 +103,72 @@ void GlobalSettings::save_internal_defaults() default_palette_ = QApplication::palette(); } +// make controls zoom the traces when not using any key modifiers +// these controls are similar to the old controls used before customisation was introduced. +void GlobalSettings::set_nav_zoom_defaults(bool force) +{ + // zoom + NAV_GSETTINGS_VAR_DEFAULT(UpDown, NAV_TYPE_ZOOM, 0.25); // up/down arrow will zoom the traces by 1/4x + // small vertical movement + NAV_GSETTINGS_VAR_DEFAULT(UpDownCtrl, NAV_TYPE_VERT, 0.125); // up/down with any modifier will move traces vertically by 1/8 page + NAV_GSETTINGS_VAR_DEFAULT(UpDownAlt, NAV_TYPE_VERT, 0.125); + NAV_GSETTINGS_VAR_DEFAULT(UpDownShift, NAV_TYPE_VERT, 0.125); + // small horizontal movement + NAV_GSETTINGS_VAR_DEFAULT(LeftRight, NAV_TYPE_HORI, 0.125); // left/right arrow will move the trace by 1/8 page + NAV_GSETTINGS_VAR_DEFAULT(LeftRightShift, NAV_TYPE_HORI, 0.125); // left/right arrow + ctrl will move the trace by 1/8 page + NAV_GSETTINGS_VAR_DEFAULT(LeftRightCtrl, NAV_TYPE_HORI, 0.25); // left/right arrow + ctrl will move the trace by 1/4 page + NAV_GSETTINGS_VAR_DEFAULT(LeftRightAlt, NAV_TYPE_HORI, 0.5); // left/right arrow + alt will move the trace by 1/2 page + // big vertical movement + NAV_GSETTINGS_VAR_DEFAULT(PageUpDown, NAV_TYPE_VERT, 1.0); // page up/down will move traces vertically by 1 page + NAV_GSETTINGS_VAR_DEFAULT(PageUpDownShift, NAV_TYPE_VERT, 1.0); // page up/down + shift will move traces vertically by 1 page + NAV_GSETTINGS_VAR_DEFAULT(PageUpDownCtrl, NAV_TYPE_VERT, 2.0); // page up/down + ctrl will move traces vertically by 2 page + NAV_GSETTINGS_VAR_DEFAULT(PageUpDownAlt, NAV_TYPE_VERT, 4.0); // page up/down + alt will move traces vertically by 4 page + // vertical mosewheel can zoom and move horizontally and vertically + NAV_GSETTINGS_VAR_DEFAULT(WheelVert, NAV_TYPE_ZOOM, 0.25); // vertical mousewheel will zoom the traces by 1/4x + NAV_GSETTINGS_VAR_DEFAULT(WheelVertShift, NAV_TYPE_ZOOM, 0.25); // vertical mousewheel + shift will zoom the traces by 1/4x + NAV_GSETTINGS_VAR_DEFAULT(WheelVertCtrl, NAV_TYPE_VERT, 0.5); // vertical mousewheel + ctrl will move the traces by 1/2 page + NAV_GSETTINGS_VAR_DEFAULT(WheelVertAlt, NAV_TYPE_HORI, 1.0); // vertical mousewheel + alt will move the traces by 1 page + // horizontal mousewheel always moves horizontally + NAV_GSETTINGS_VAR_DEFAULT(WheelHori, NAV_TYPE_HORI, 0.25); // horizontal mousewheel will move the traces by 1/4 page + NAV_GSETTINGS_VAR_DEFAULT(WheelHoriShift, NAV_TYPE_HORI, 0.25); // horizontal mousewheel + shift will move the traces by 1/4 page + NAV_GSETTINGS_VAR_DEFAULT(WheelHoriCtrl, NAV_TYPE_HORI, 0.5); // horizontal mousewheel + ctrl will move the traces by 1/2 page + NAV_GSETTINGS_VAR_DEFAULT(WheelHoriAlt, NAV_TYPE_HORI, 1.0); // horizontal mousewheel + alt will move the traces by 1 page +} + +// make controls move the traces without key modifiers. +// slow speed move is default +// ctrl modifier does medium speed move +// alt modifier does fast speed move +// shift key always does zoom +void GlobalSettings::set_nav_move_defaults(bool force) +{ + // vertical movement + NAV_GSETTINGS_VAR_DEFAULT(UpDown, NAV_TYPE_VERT, 0.125); // up/down arrow will move the traces by 1/8 page + // zoom + NAV_GSETTINGS_VAR_DEFAULT(WheelHoriShift, NAV_TYPE_ZOOM, 0.25); // horizontal mousewheel + shift will zoom in/out by 1/4 x + NAV_GSETTINGS_VAR_DEFAULT(WheelVertShift, NAV_TYPE_ZOOM, 0.25); // vertical mousewheel + shift will zoom in/out by 1/4 x + NAV_GSETTINGS_VAR_DEFAULT(UpDownShift, NAV_TYPE_ZOOM, 1.0); // up/down arrow + shift will zoom in/out by 1x + NAV_GSETTINGS_VAR_DEFAULT(PageUpDownShift, NAV_TYPE_ZOOM, 2.0); // page up/down + shift will zoom in/out by 2x + // horizontal movement + NAV_GSETTINGS_VAR_DEFAULT(LeftRight, NAV_TYPE_HORI, 0.125); // left/right arrow will move the trace by 1/8 page + NAV_GSETTINGS_VAR_DEFAULT(LeftRightCtrl, NAV_TYPE_HORI, 0.25); // left/right arrow + ctrl will move the trace by 1/4 page + NAV_GSETTINGS_VAR_DEFAULT(LeftRightAlt, NAV_TYPE_HORI, 0.5); // left/right arrow + alt will move the trace by 1/2 page + NAV_GSETTINGS_VAR_DEFAULT(PageUpDown, NAV_TYPE_HORI, 1.0); // page up/down will move the trace by 1 page + NAV_GSETTINGS_VAR_DEFAULT(PageUpDownCtrl, NAV_TYPE_HORI, 2.0); // page up/down + ctrl will move the trace by 2 pages + NAV_GSETTINGS_VAR_DEFAULT(PageUpDownAlt, NAV_TYPE_HORI, 4.0); // page up/down + alt will move the trace by 4 pages + // horizontal movement with mousewheel + NAV_GSETTINGS_VAR_DEFAULT(WheelHori, NAV_TYPE_HORI, 0.25); // horizontal mousewheel will move the traces by 1/4 page + NAV_GSETTINGS_VAR_DEFAULT(WheelVert, NAV_TYPE_HORI, 0.25); // vertical mousewheel will move the traces by 1/4 page + NAV_GSETTINGS_VAR_DEFAULT(WheelHoriCtrl, NAV_TYPE_HORI, 0.5); // horizontal mousewheel + ctrl will move the traces by 1/2 page + NAV_GSETTINGS_VAR_DEFAULT(WheelVertCtrl, NAV_TYPE_HORI, 0.5); // vertical mousewheel + ctrl will move the traces by 1/2 page + NAV_GSETTINGS_VAR_DEFAULT(WheelHoriAlt, NAV_TYPE_HORI, 1.0); // horizontal mousewheel + alt will move the traces by 1 page + NAV_GSETTINGS_VAR_DEFAULT(WheelVertAlt, NAV_TYPE_HORI, 1.0); // vertical mousewheel + alt will move the traces by 1 page + // not used + NAV_GSETTINGS_VAR_DEFAULT(UpDownCtrl, NAV_TYPE_NONE, 0); + NAV_GSETTINGS_VAR_DEFAULT(UpDownAlt, NAV_TYPE_NONE, 0); + NAV_GSETTINGS_VAR_DEFAULT(LeftRightShift, NAV_TYPE_NONE, 0); +} + void GlobalSettings::set_defaults_where_needed() { if (!contains(Key_General_Language)) { @@ -154,7 +225,9 @@ void GlobalSettings::set_defaults_where_needed() if (!contains(Key_View_CursorShowFrequency)) setValue(Key_View_CursorShowFrequency, true); - + + set_nav_zoom_defaults(false); + // %c was used for the row name in the past so we need to transition such users if (!contains(Key_Dec_ExportFormat) || value(Key_Dec_ExportFormat).toString() == "%s %d: %c: %1") diff --git a/pv/globalsettings.hpp b/pv/globalsettings.hpp index e41c2ea9..151c300e 100644 --- a/pv/globalsettings.hpp +++ b/pv/globalsettings.hpp @@ -48,6 +48,39 @@ class GlobalSettingsInterface }; +// type of navigation to perform +#define NAV_TYPE_NONE 0 +#define NAV_TYPE_ZOOM 1 +#define NAV_TYPE_HORI 2 +#define NAV_TYPE_VERT 3 + +#define NAV_GSETTINGS_VAR_DECLARE(name) \ + static const QString Key_Nav_ ## name ## Type; \ + static const QString Key_Nav_ ## name ## Amount; \ + static const QString Key_Nav_ ## name ## AltType; \ + static const QString Key_Nav_ ## name ## AltAmount; \ + static const QString Key_Nav_ ## name ## CtrlType; \ + static const QString Key_Nav_ ## name ## CtrlAmount; \ + static const QString Key_Nav_ ## name ## ShiftType; \ + static const QString Key_Nav_ ## name ## ShiftAmount + +#define NAV_GSETTINGS_VAR_SETUP(name) \ + const QString GlobalSettings::Key_Nav_ ## name ## Type = "Nav_" #name "Type"; \ + const QString GlobalSettings::Key_Nav_ ## name ## Amount = "Nav_" #name "Amount"; \ + const QString GlobalSettings::Key_Nav_ ## name ## AltType = "Nav_" #name "AltType"; \ + const QString GlobalSettings::Key_Nav_ ## name ## AltAmount = "Nav_" #name "AltAmount"; \ + const QString GlobalSettings::Key_Nav_ ## name ## CtrlType = "Nav_" #name "CtrlType"; \ + const QString GlobalSettings::Key_Nav_ ## name ## CtrlAmount = "Nav_" #name "CtrlAmount"; \ + const QString GlobalSettings::Key_Nav_ ## name ## ShiftType = "Nav_" #name "ShiftType"; \ + const QString GlobalSettings::Key_Nav_ ## name ## ShiftAmount = "Nav_" #name "ShiftAmount" + +#define NAV_GSETTINGS_VAR_DEFAULT(name, type, amount) \ + if (!contains(Key_Nav_ ## name ## Type) || force) \ + setValue(Key_Nav_ ## name ## Type, type); \ + if (!contains(Key_Nav_ ## name ## Amount) || force) \ + setValue(Key_Nav_ ## name ## Amount, amount) + + class GlobalSettings : public QSettings { Q_OBJECT @@ -75,6 +108,11 @@ class GlobalSettings : public QSettings static const QString Key_View_CursorShowInterval; static const QString Key_View_CursorShowFrequency; static const QString Key_View_CursorShowSamples; + NAV_GSETTINGS_VAR_DECLARE(UpDown); + NAV_GSETTINGS_VAR_DECLARE(LeftRight); + NAV_GSETTINGS_VAR_DECLARE(PageUpDown); + NAV_GSETTINGS_VAR_DECLARE(WheelHori); + NAV_GSETTINGS_VAR_DECLARE(WheelVert); static const QString Key_Dec_InitialStateConfigurable; static const QString Key_Dec_ExportFormat; static const QString Key_Dec_AlwaysShowAllRows; @@ -92,6 +130,8 @@ class GlobalSettings : public QSettings void save_internal_defaults(); void set_defaults_where_needed(); + void set_nav_zoom_defaults(bool force); + void set_nav_move_defaults(bool force); void set_bright_theme_default_colors(); void set_dark_theme_default_colors(); diff --git a/pv/views/trace/view.cpp b/pv/views/trace/view.cpp index 7947df8a..dd519b8e 100644 --- a/pv/views/trace/view.cpp +++ b/pv/views/trace/view.cpp @@ -257,43 +257,17 @@ View::View(Session &session, bool is_main_view, QMainWindow *parent) : NAV_KB_VAR_SETUP(right, Qt::Key_Right); NAV_KB_VAR_SETUP(pageup, Qt::Key_PageUp); NAV_KB_VAR_SETUP(pagedown, Qt::Key_PageDown); - // Next we set the default types and amounts to start with when the user has not changed them yet - // vertical movement - NAV_KB_VAR_DEFAULT(up, NAV_TYPE_VERT, -0.125); // up arrow will move the traces up by 1/8 page - NAV_KB_VAR_DEFAULT(down, NAV_TYPE_VERT, 0.125); // down arrow will move the traces up by 1/8 page - // zoom - NAV_KB_VAR_DEFAULT(up_shift, NAV_TYPE_ZOOM, -1.0); // up arrow + shift will zoom in by 1x - NAV_KB_VAR_DEFAULT(down_shift, NAV_TYPE_ZOOM, 1.0); // down arrow + shift will zoom out by 1x - NAV_KB_VAR_DEFAULT(pageup_shift, NAV_TYPE_ZOOM, -2.0); // page up + shift will zoom in by 2x - NAV_KB_VAR_DEFAULT(pagedown_shift, NAV_TYPE_ZOOM, 2.0); // page down + shift will zoom out by 2x - // small horizontal movement - NAV_KB_VAR_DEFAULT(left, NAV_TYPE_HORI, -0.125); // left arrow will move the trace backwards by 1/8 page - NAV_KB_VAR_DEFAULT(right, NAV_TYPE_HORI, 0.125); // right arrow will move the trace forwards by 1/8 page - NAV_KB_VAR_DEFAULT(left_alt, NAV_TYPE_HORI, -0.25); // left arrow + alt will move the trace backwards by 1/4 page - NAV_KB_VAR_DEFAULT(right_alt, NAV_TYPE_HORI, 0.25); // right arrow + alt will move the trace forwards by 1/4 page - NAV_KB_VAR_DEFAULT(left_ctrl, NAV_TYPE_HORI, -0.5); // left arrow + ctrl will move the trace backwards by 1/2 page - NAV_KB_VAR_DEFAULT(right_ctrl, NAV_TYPE_HORI, 0.5); // right arrow + ctrl will move the trace forwards by 1/2 page - // big horizontal movement - NAV_KB_VAR_DEFAULT(pageup, NAV_TYPE_HORI, -1.0); // page up will move the trace backwards by 1 page - NAV_KB_VAR_DEFAULT(pagedown, NAV_TYPE_HORI, 1.0); // page down will move the trace forwards by 1 page - NAV_KB_VAR_DEFAULT(pageup_alt, NAV_TYPE_HORI, -2.0); // page up + alt will move the trace backwards by 2 pages - NAV_KB_VAR_DEFAULT(pagedown_alt, NAV_TYPE_HORI, 2.0); // page down + alt will move the trace forwards by 2 pages - NAV_KB_VAR_DEFAULT(pageup_ctrl, NAV_TYPE_HORI, -4.0); // page up + ctrl will move the trace backwards by 4 pages - NAV_KB_VAR_DEFAULT(pagedown_ctrl, NAV_TYPE_HORI, 4.0); // page down + ctrl will move the trace forwards by 4 pages - // Mousewheel navigation // This sets them all up as disabled initially. NAV_MW_VAR_SETUP(hori); NAV_MW_VAR_SETUP(vert); - // Next we set the default types and amounts to start with when the user has not changed them yet - NAV_MW_VAR_DEFAULT(hori_shift, NAV_TYPE_ZOOM, 0.25); // horizontal mousewheel + shift will zoom the traces by 1/4 x - NAV_MW_VAR_DEFAULT(vert_shift, NAV_TYPE_ZOOM, 0.25); // vertical mousewheel + shift will zoom the traces by 1/4 x - NAV_MW_VAR_DEFAULT(hori, NAV_TYPE_HORI, 0.25); // horizontal mousewheel will move the traces up by 1/4 page - NAV_MW_VAR_DEFAULT(vert, NAV_TYPE_HORI, 0.25); // vertical mousewheel will move the traces up by 1/4 page - NAV_MW_VAR_DEFAULT(hori_alt, NAV_TYPE_HORI, 0.5); // horizontal mousewheel + alt will move the traces up by 1/2 page - NAV_MW_VAR_DEFAULT(vert_alt, NAV_TYPE_HORI, 0.5); // vertical mousewheel + alt will move the traces up by 1/2 page - NAV_MW_VAR_DEFAULT(hori_ctrl, NAV_TYPE_HORI, 1.0); // horizontal mousewheel + ctrl will move the traces up by 1 page - NAV_MW_VAR_DEFAULT(vert_ctrl, NAV_TYPE_HORI, 1.0); // vertical mousewheel + ctrl will move the traces up by 14 page + + // Load settings for keyboard and mousewheel navigation + NAV_KB_SETTING_LOAD(UpDown, up, down); + NAV_KB_SETTING_LOAD(LeftRight, left, right); + NAV_KB_SETTING_LOAD(PageUpDown, pageup, pagedown); + NAV_MW_SETTING_LOAD(WheelHori, hori); + NAV_MW_SETTING_LOAD(WheelVert, vert); // Trigger the initial event manually. The default device has signals // which were created before this object came into being @@ -555,16 +529,6 @@ void View::save_settings(QSettings &settings) const signal->save_settings(settings); settings.endGroup(); } - - NAV_KB_SAVE(up); - NAV_KB_SAVE(down); - NAV_KB_SAVE(left); - NAV_KB_SAVE(right); - NAV_KB_SAVE(pageup); - NAV_KB_SAVE(pagedown); - - NAV_MW_SAVE(hori); - NAV_MW_SAVE(vert); } void View::restore_settings(QSettings &settings) @@ -602,16 +566,6 @@ void View::restore_settings(QSettings &settings) scroll_needs_defaults_ = false; } - NAV_KB_RESTORE(up); - NAV_KB_RESTORE(down); - NAV_KB_RESTORE(left); - NAV_KB_RESTORE(right); - NAV_KB_RESTORE(pageup); - NAV_KB_RESTORE(pagedown); - - NAV_MW_RESTORE(hori); - NAV_MW_RESTORE(vert); - restoring_state_ = true; // Update the ruler so that it uses the new scale @@ -1256,6 +1210,12 @@ void View::on_setting_changed(const QString &key, const QVariant &value) if (key == GlobalSettings::Key_View_SnapDistance) snap_distance_ = settings.value(GlobalSettings::Key_View_SnapDistance).toInt(); + + NAV_KB_SETTING_CHANGED(UpDown, up, down) + NAV_KB_SETTING_CHANGED(LeftRight, left, right) + NAV_KB_SETTING_CHANGED(PageUpDown, pageup, pagedown) + NAV_MW_SETTING_CHANGED(WheelHori, hori) + NAV_MW_SETTING_CHANGED(WheelVert, vert) } void View::trigger_event(int segment_id, util::Timestamp location) @@ -1802,12 +1762,31 @@ void View::on_scroll_to_end_shortcut_triggered() void View::nav_zoom(double numTimes) { - zoom(numTimes); + QPoint global_point = QCursor::pos(); + printf("nav_zoom() global_point(%d, %d) %d\n", global_point.x(), global_point.y(), global_point.isNull()?1:0); + if( global_point.isNull() ) + { + zoom(-numTimes); + return; + } + + QPoint widget_point = viewport_->mapFromGlobal(global_point); + printf("nav_zoom() widget_point(%d, %d) %d\n", widget_point.x(), widget_point.y(), widget_point.isNull()?1:0); + if( widget_point.isNull() || + widget_point.x() < 0 || widget_point.x() > viewport_->width() || + widget_point.y() < 0 || widget_point.y() > viewport_->height()) + { + zoom(-numTimes); + return; + } + + printf("zoom t mouse\n"); + zoom(-numTimes, widget_point.x()); } void View::nav_zoom(double numTimes, int offset) { - zoom(numTimes, offset); + zoom(-numTimes, offset); } void View::nav_move_hori(double numPages) diff --git a/pv/views/trace/view.hpp b/pv/views/trace/view.hpp index 2c6f1934..d3c02c0d 100644 --- a/pv/views/trace/view.hpp +++ b/pv/views/trace/view.hpp @@ -82,20 +82,31 @@ class CustomScrollArea : public QAbstractScrollArea // This Navigation code handles customisation of keyboard and mousewheel controls // for navigating the traces by moving them and zooming them. -// Code is done to support the custom controls as well as saving and restoring them -// from settings. Missing is code to set/get them from a GUI settings dialog. // -// TODO: Add GUI support for getting and setting the navigation params. -// The GUI can call these provided functions to get set the values: -// View::nav_kb_up_alt_get() / View::nav_kb_up_alt_set() -// View::nav_mw_vert_get() / View::nav_mw_vert_set() -// etc +// There are 5 sets of keys/mousewheels usable for customisation: +// up/down, left/right, pageup/pagedown, +// horizontal mousewheel and vertical mousewheel. +// There are 3 modifier keys that can be used with the above, as well as using +// no modifier. These are: +// none, alt, ctrl, shift. +// Together the main and modifiers provide 5 * 4 = 20 different navigation controls +// for customisation. // -// Currently the customisations can only be changed by editing where the settings -// are stored which is platform specific: -// - Windows: stored in registry at "Computer\HKEY_CURRENT_USER\SOFTWARE\sigrok\PulseView\Session0\view0" -// - Linux: stored in a file at ~/.config/sigrok/pulseview.conf -// - Mac: stored in a file at ~/Library/Preferences/pulseview.plist +// There are 4 types of navigation that the above can be assigned to do: +// none = no operation performed (same as disabling the operation) +// zoom = zoom in/out of the trace view +// hori = move the trace horizontally to see previous or next sample data +// vert = move the trace vertically to see channels above or below +// +// There is an "amount" variable of type "double" to be used with navigation. +// When moving traces horizontally or vertically the "amount" value is equal to +// the number of pages to move. So a value of 1.0 would move 1 page forward. +// A value of -0.5 would move half a page backwards. +// When zooming into traces the "amount" value is equal to the zoom multiplier. +// So a value of 1.0 will zoom out by 1x and a value of -2.0 will zoom in by 2x. +// +// A "Navigation" page has been added to the Settings to allow the user to +// customise the navigation controls to their liking. // type of navigation to perform #define NAV_TYPE_NONE 0 @@ -134,14 +145,8 @@ typedef struct { name ## _ctrl_nav_.sc = new QShortcut(QKeySequence(keys + Qt::CTRL), this, SLOT(on_kb_ ##name## _ctrl()), nullptr, Qt::WidgetWithChildrenShortcut); \ name ## _shift_nav_.sc = new QShortcut(QKeySequence(keys + Qt::SHIFT), this, SLOT(on_kb_ ##name## _shift()), nullptr, Qt::WidgetWithChildrenShortcut) -#define NAV_KB_VAR_DEFAULT(name, t, a) \ - name ## _nav_.type = t; \ - name ## _nav_.amount = a - #define NAV_KB_FUNC_DECLARE1(name) \ - void on_kb_ ## name (); \ - void nav_kb_ ## name ## _set(int type, double amount); \ - void nav_kb_ ## name ## _get(int* type, double* amount) + void on_kb_ ## name () #define NAV_KB_FUNC_DECLARE(name) \ NAV_KB_FUNC_DECLARE1(name); \ @@ -155,14 +160,6 @@ typedef struct { else if (name ## _nav_.type == NAV_TYPE_ZOOM )nav_zoom(name ## _nav_.amount); \ else if (name ## _nav_.type == NAV_TYPE_HORI )nav_move_hori(name ## _nav_.amount); \ else if (name ## _nav_.type == NAV_TYPE_VERT )nav_move_vert(name ## _nav_.amount); \ - } \ - void View::nav_kb_ ## name ## _set(int type, double amount) { \ - name ## _nav_.type = type; \ - name ## _nav_.amount = amount; \ - } \ - void View::nav_kb_ ## name ## _get(int* type, double* amount) { \ - if(type) *type = name ## _nav_.type; \ - if(amount) *amount = name ## _nav_.amount; \ } #define NAV_KB_FUNC_DEFINE(name) \ @@ -171,6 +168,38 @@ typedef struct { NAV_KB_FUNC_DEFINE1(name ## _ctrl) \ NAV_KB_FUNC_DEFINE1(name ## _shift) +#define NAV_KB_SETTING_CHANGED1(name, k1, k2) \ + if (key == GlobalSettings::Key_Nav_ ## name ## Type) { \ + k1 ## _nav_.type = settings.value(GlobalSettings::Key_Nav_ ## name ## Type).toInt(); \ + k2 ## _nav_.type = settings.value(GlobalSettings::Key_Nav_ ## name ## Type).toInt(); \ + } \ + if (key == GlobalSettings::Key_Nav_ ## name ## Amount) { \ + k1 ## _nav_.amount = -settings.value(GlobalSettings::Key_Nav_ ## name ## Amount).toDouble(); \ + k2 ## _nav_.amount = settings.value(GlobalSettings::Key_Nav_ ## name ## Amount).toDouble(); \ + } + +#define NAV_KB_SETTING_CHANGED(name, k1, k2) \ + NAV_KB_SETTING_CHANGED1(name, k1, k2) \ + NAV_KB_SETTING_CHANGED1(name ## Alt, k1 ## _alt, k2 ## _alt) \ + NAV_KB_SETTING_CHANGED1(name ## Ctrl, k1 ## _ctrl, k2 ## _ctrl) \ + NAV_KB_SETTING_CHANGED1(name ## Shift, k1 ## _shift, k2 ## _shift) + +#define NAV_KB_SETTING_LOAD1(name, k1, k2) \ + if (settings.contains(GlobalSettings::Key_Nav_ ## name ## Type)) { \ + k1 ## _nav_.type = settings.value(GlobalSettings::Key_Nav_ ## name ## Type).toInt(); \ + k2 ## _nav_.type = settings.value(GlobalSettings::Key_Nav_ ## name ## Type).toInt(); \ + } \ + if (settings.contains(GlobalSettings::Key_Nav_ ## name ## Amount)) { \ + k1 ## _nav_.amount = -settings.value(GlobalSettings::Key_Nav_ ## name ## Amount).toDouble(); \ + k2 ## _nav_.amount = settings.value(GlobalSettings::Key_Nav_ ## name ## Amount).toDouble(); \ + } + +#define NAV_KB_SETTING_LOAD(name, k1, k2) \ + NAV_KB_SETTING_LOAD1(name, k1, k2) \ + NAV_KB_SETTING_LOAD1(name ## Alt, k1 ## _alt, k2 ## _alt) \ + NAV_KB_SETTING_LOAD1(name ## Ctrl, k1 ## _ctrl, k2 ## _ctrl) \ + NAV_KB_SETTING_LOAD1(name ## Shift, k1 ## _shift, k2 ## _shift) + // mousewheel #define NAV_MW_VAR_DECLARE(name) \ NavMw_t name ## _nav_, name ## _alt_nav_, name ## _ctrl_nav_, name ## _shift_nav_ @@ -185,14 +214,8 @@ typedef struct { name ## _ctrl_nav_.amount = 0; \ name ## _shift_nav_.amount = 0 -#define NAV_MW_VAR_DEFAULT(name, t, a) \ - name ## _nav_.type = t; \ - name ## _nav_.amount = a - #define NAV_MW_FUNC_DECLARE1(name) \ - void on_mw_ ## name (QWheelEvent *event); \ - void nav_mw_ ## name ## _set(int type, double amount); \ - void nav_mw_ ## name ## _get(int* type, double* amount) + void on_mw_ ## name (QWheelEvent *event) #define NAV_MW_FUNC_DECLARE(name) \ NAV_MW_FUNC_DECLARE1(name); \ @@ -206,14 +229,6 @@ typedef struct { else if (name ## _nav_.type == NAV_TYPE_ZOOM )nav_zoom( (-event->delta() * name ## _nav_.amount)/120.0, event->x()); \ else if (name ## _nav_.type == NAV_TYPE_HORI )nav_move_hori((-event->delta() * name ## _nav_.amount)/120.0); \ else if (name ## _nav_.type == NAV_TYPE_VERT )nav_move_vert((-event->delta() * name ## _nav_.amount)/120.0); \ - } \ - void View::nav_mw_ ## name ## _set(int type, double amount) { \ - name ## _nav_.type = type; \ - name ## _nav_.amount = amount; \ - } \ - void View::nav_mw_ ## name ## _get(int* type, double* amount) { \ - if(type) *type = name ## _nav_.type; \ - if(amount) *amount = name ## _nav_.amount; \ } #define NAV_MW_FUNC_DEFINE(name) \ @@ -222,39 +237,33 @@ typedef struct { NAV_MW_FUNC_DEFINE1(name ## _ctrl) \ NAV_MW_FUNC_DEFINE1(name ## _shift) +#define NAV_MW_SETTING_CHANGED1(name, mw) \ + if (key == GlobalSettings::Key_Nav_ ## name ## Type) { \ + mw ## _nav_.type = settings.value(GlobalSettings::Key_Nav_ ## name ## Type).toInt(); \ + } \ + if (key == GlobalSettings::Key_Nav_ ## name ## Amount) { \ + mw ## _nav_.amount = settings.value(GlobalSettings::Key_Nav_ ## name ## Amount).toDouble(); \ + } + +#define NAV_MW_SETTING_CHANGED(name, mw) \ + NAV_MW_SETTING_CHANGED1(name, mw) \ + NAV_MW_SETTING_CHANGED1(name ## Alt, mw ## _alt) \ + NAV_MW_SETTING_CHANGED1(name ## Ctrl, mw ## _ctrl) \ + NAV_MW_SETTING_CHANGED1(name ## Shift, mw ## _shift) + +#define NAV_MW_SETTING_LOAD1(name, mw) \ + if (settings.contains(GlobalSettings::Key_Nav_ ## name ## Type)) { \ + mw ## _nav_.type = settings.value(GlobalSettings::Key_Nav_ ## name ## Type).toInt(); \ + } \ + if (settings.contains(GlobalSettings::Key_Nav_ ## name ## Amount)) { \ + mw ## _nav_.amount = settings.value(GlobalSettings::Key_Nav_ ## name ## Amount).toDouble(); \ + } -#define NAV_SAVE1(name) \ - settings.setValue("nav_" #name "_type", name ## _nav_.type); \ - settings.setValue("nav_" #name "_amount", name ## _nav_.amount) - -#define NAV_KB_SAVE(name) \ - NAV_SAVE1(name); \ - NAV_SAVE1(name ## _alt);\ - NAV_SAVE1(name ## _ctrl);\ - NAV_SAVE1(name ## _shift) - -#define NAV_MW_SAVE(name) \ - NAV_SAVE1(name); \ - NAV_SAVE1(name ## _alt);\ - NAV_SAVE1(name ## _ctrl);\ - NAV_SAVE1(name ## _shift) - - -#define NAV_RESTORE1(name) \ - if (settings.contains("nav_" #name "_type")) name ## _nav_.type = settings.value("nav_" #name "_type").toInt(); \ - if (settings.contains("nav_" #name "_amount")) name ## _nav_.amount = settings.value("nav_" #name "_amount").toDouble() - -#define NAV_KB_RESTORE(name) \ - NAV_RESTORE1(name); \ - NAV_RESTORE1(name ## _alt); \ - NAV_RESTORE1(name ## _ctrl);\ - NAV_RESTORE1(name ## _shift) - -#define NAV_MW_RESTORE(name) \ - NAV_RESTORE1(name); \ - NAV_RESTORE1(name ## _alt); \ - NAV_RESTORE1(name ## _ctrl);\ - NAV_RESTORE1(name ## _shift) +#define NAV_MW_SETTING_LOAD(name, mw) \ + NAV_MW_SETTING_LOAD1(name, mw) \ + NAV_MW_SETTING_LOAD1(name ## Alt, mw ## _alt) \ + NAV_MW_SETTING_LOAD1(name ## Ctrl, mw ## _ctrl) \ + NAV_MW_SETTING_LOAD1(name ## Shift, mw ## _shift) class View : public ViewBase, public TraceTreeItemOwner, public GlobalSettingsInterface @@ -631,13 +640,13 @@ private Q_SLOTS: void signals_changed(); void capture_state_updated(int state); + // keyboard and mousewheel navigation functions NAV_KB_FUNC_DECLARE(up); NAV_KB_FUNC_DECLARE(down); NAV_KB_FUNC_DECLARE(left); NAV_KB_FUNC_DECLARE(right); NAV_KB_FUNC_DECLARE(pageup); NAV_KB_FUNC_DECLARE(pagedown); - NAV_MW_FUNC_DECLARE(hori); NAV_MW_FUNC_DECLARE(vert); @@ -704,7 +713,7 @@ private Q_SLOTS: QShortcut *grab_ruler_left_shortcut_, *grab_ruler_right_shortcut_; QShortcut *cancel_grab_shortcut_; - // keyboard and mousewheel navigation + // keyboard and mousewheel navigation variables NAV_KB_VAR_DECLARE(up); NAV_KB_VAR_DECLARE(down); NAV_KB_VAR_DECLARE(left);