reapack

Package manager for REAPER
Log | Files | Refs | Submodules | README | LICENSE

commit 249836a81756aa2ca9bbf7a47aece1cb9b7e2607
parent 0855c9f2d8a357e59e158246de85bb70f9eaccad
Author: cfillion <cfillion@users.noreply.github.com>
Date:   Mon, 20 Jun 2016 18:35:33 -0400

listview: send context menu event through the list control

side effect: right click is correctly handled on the column header on OS X

Diffstat:
Msrc/browser.cpp | 14++++++--------
Msrc/browser.hpp | 2+-
Msrc/control.hpp | 3++-
Msrc/dialog.cpp | 16+++++++++++++++-
Msrc/listview.cpp | 14++++++++++++++
Msrc/listview.hpp | 6++++++
Msrc/manager.cpp | 15++++++---------
Msrc/manager.hpp | 2+-
8 files changed, 51 insertions(+), 21 deletions(-)

diff --git a/src/browser.cpp b/src/browser.cpp @@ -61,6 +61,8 @@ Browser::Browser(ReaPack *reapack) void Browser::onInit() { + namespace arg = std::placeholders; + m_applyBtn = getControl(IDAPPLY); m_filterHandle = getControl(IDC_FILTER); m_view = getControl(IDC_TABS); @@ -90,6 +92,7 @@ void Browser::onInit() m_list->onActivate([=] { history(m_list->itemUnderMouse()); }); m_list->onSelect([=] { setEnabled(m_list->hasSelection(), m_actionsBtn); }); + m_list->onContextMenu(bind(&Browser::fillContextMenu, this, arg::_1)); m_list->sortByColumn(1); const auto config = m_reapack->config()->browser(); @@ -232,18 +235,13 @@ void Browser::onTimer(const int id) checkFilter(); } -void Browser::onContextMenu(HWND target, const int x, const int y) +bool Browser::fillContextMenu(Menu &menu) { - if(target != m_list->handle()) - return; - - SetFocus(m_list->handle()); - m_currentIndex = m_list->itemUnderMouse(); - Menu menu; fillMenu(menu); - menu.show(x, y, handle()); + + return true; } void Browser::fillMenu(Menu &menu) diff --git a/src/browser.hpp b/src/browser.hpp @@ -48,7 +48,6 @@ public: protected: void onInit() override; void onCommand(int, int) override; - void onContextMenu(HWND, int x, int y) override; void onTimer(int) override; bool onKeyDown(int, int) override; void onClose() override; @@ -100,6 +99,7 @@ private: Entry makeEntry(const Package *, const Registry::Entry &) const; + bool fillContextMenu(Menu &); void populate(); void transferActions(); bool match(const Entry &) const; diff --git a/src/control.hpp b/src/control.hpp @@ -43,7 +43,8 @@ public: protected: friend Dialog; - virtual void onNotify(LPNMHDR, LPARAM) = 0; + virtual void onNotify(LPNMHDR, LPARAM) {} + virtual void onContextMenu(HWND, int, int) {} private: HWND m_handle; diff --git a/src/dialog.cpp b/src/dialog.cpp @@ -330,8 +330,22 @@ void Dialog::onNotify(LPNMHDR info, LPARAM lParam) it->second->onNotify(info, lParam); } -void Dialog::onContextMenu(HWND, int, int) +void Dialog::onContextMenu(HWND, int x, int y) { + for(const auto &pair : m_controls) { + Control *ctrl = pair.second; + + RECT rect; + GetWindowRect(ctrl->handle(), &rect); + +#ifndef _WIN32 + // special treatment for SWELL + swap(rect.top, rect.bottom); +#endif + + if(y >= rect.top && y <= rect.bottom && x >= rect.left && x <= rect.right) + return ctrl->onContextMenu(m_handle, x, y); + } } bool Dialog::onKeyDown(int, int) diff --git a/src/listview.cpp b/src/listview.cpp @@ -17,6 +17,8 @@ #include "listview.hpp" +#include "menu.hpp" + #include <boost/algorithm/string.hpp> #include <sstream> @@ -259,6 +261,18 @@ void ListView::onNotify(LPNMHDR info, LPARAM lParam) }; } +void ListView::onContextMenu(HWND dialog, int x, int y) +{ + SetFocus(handle()); + + Menu menu; + + if(!m_onContextMenu(menu)) + return; + + menu.show(x, y, dialog); +} + void ListView::handleDoubleClick() { const int index = itemUnderMouse(); diff --git a/src/listview.hpp b/src/listview.hpp @@ -25,6 +25,8 @@ #include "encoding.hpp" +class Menu; + class ListView : public Control { public: enum SortOrder { AscendingOrder, DescendingOrder }; @@ -34,6 +36,7 @@ public: typedef std::vector<auto_string> Row; typedef boost::signals2::signal<void ()> VoidSignal; + typedef boost::signals2::signal<bool (Menu &)> MenuSignal; ListView(const Columns &, HWND handle); @@ -66,9 +69,11 @@ public: void onSelect(const VoidSignal::slot_type &slot) { m_onSelect.connect(slot); } void onActivate(const VoidSignal::slot_type &slot) { m_onActivate.connect(slot); } + void onContextMenu(const MenuSignal::slot_type &slot) { m_onContextMenu.connect(slot); } protected: void onNotify(LPNMHDR, LPARAM) override; + void onContextMenu(HWND, int, int) override; private: static int adjustWidth(int); @@ -88,6 +93,7 @@ private: VoidSignal m_onSelect; VoidSignal m_onActivate; + MenuSignal m_onContextMenu; }; #endif diff --git a/src/manager.cpp b/src/manager.cpp @@ -42,6 +42,8 @@ Manager::Manager(ReaPack *reapack) void Manager::onInit() { + namespace arg = std::placeholders; + m_apply = getControl(IDAPPLY); disable(m_apply); @@ -52,6 +54,7 @@ void Manager::onInit() }); m_list->onActivate([=] { about(m_list->currentIndex()); }); + m_list->onContextMenu(bind(&Manager::fillContextMenu, this, arg::_1)); refresh(); @@ -134,21 +137,15 @@ void Manager::onCommand(const int id, int) } } -void Manager::onContextMenu(HWND target, const int x, const int y) +bool Manager::fillContextMenu(Menu &menu) { - if(target != m_list->handle()) - return; - const int index = m_list->itemUnderMouse(); const Remote &remote = getRemote(index); - Menu menu; - if(!remote) { menu.addAction(AUTO_STR("&Select all"), ACTION_SELECT); menu.addAction(AUTO_STR("&Unselect all"), ACTION_UNSELECT); - menu.show(x, y, handle()); - return; + return true; } const UINT enableAction = @@ -194,7 +191,7 @@ void Manager::onContextMenu(HWND target, const int x, const int y) if(allProtected) menu.disable(uninstallAction); - menu.show(x, y, handle()); + return true; } bool Manager::onKeyDown(const int key, const int mods) diff --git a/src/manager.hpp b/src/manager.hpp @@ -41,13 +41,13 @@ public: protected: void onInit() override; void onCommand(int, int) override; - void onContextMenu(HWND, int x, int y) override; bool onKeyDown(int, int) override; private: ListView::Row makeRow(const Remote &) const; Remote getRemote(int index) const; + bool fillContextMenu(Menu &); void setRemoteEnabled(bool); bool isRemoteEnabled(const Remote &) const; void uninstall();