This is the mail archive of the cygwin-apps mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH setup 4/4] Add double-click for a 'default action' to ListView


Add support for a double-click in the ListView to invoke a 'default
action'.

Because we receive both NM_CLICK and then NM_DBCLK, reduce the area of a
pop-up column which is sensitive to a click to the drop-down button
(which opens a focus-stealing pop-up menu), so the rest of the area can
receive a click (which does nothing) or a double-click (which does the
default action).

For a package, this default action is to toggle between the currently
installed version (or uninstalled, if not installed), and the highest
non-test version.

There is no keyboard acceleration for this action currently.

Signed-off-by: Jon Turney <jon.turney@dronecode.org.uk>
---
 ListView.cc         | 38 +++++++++++++++++++++++++++++++++++++-
 ListView.h          |  1 +
 PickCategoryLine.cc |  6 ++++++
 PickCategoryLine.h  |  1 +
 PickPackageLine.cc  | 11 +++++++++++
 PickPackageLine.h   |  1 +
 package_meta.cc     | 21 +++++++++++++++++++++
 package_meta.h      |  1 +
 8 files changed, 79 insertions(+), 1 deletion(-)

diff --git a/ListView.cc b/ListView.cc
index d58780b..a6dc56d 100644
--- a/ListView.cc
+++ b/ListView.cc
@@ -345,9 +345,19 @@ ListView::OnNotify (NMHDR *pNmHdr, LRESULT *pResult)
       if (headers[iCol].type == ListView::ControlType::popup)
         {
           POINT p;
-          // position pop-up menu at the location of the click
           GetCursorPos(&p);
 
+          RECT r;
+          ListView_GetSubItemRect(hWndListView, iRow, iCol, LVIR_BOUNDS, &r);
+          POINT cp = p;
+          ::ScreenToClient(hWndListView, &cp);
+
+          // if the click isn't over the pop-up button, do nothing yet (but this
+          // might be followed by a NM_DBLCLK)
+          if (cp.x < r.right - GetSystemMetrics(SM_CXVSCROLL))
+            return true;
+
+          // position pop-up menu at the location of the click
           update = popup_menu(iRow, iCol, p);
         }
       else
@@ -366,6 +376,32 @@ ListView::OnNotify (NMHDR *pNmHdr, LRESULT *pResult)
     }
     break;
 
+  case NM_DBLCLK:
+    {
+      NMITEMACTIVATE *pNmItemAct = (NMITEMACTIVATE *) pNmHdr;
+#if DEBUG
+      Log (LOG_BABBLE) << "NM_DBLCLICK: pnmitem->iItem " << pNmItemAct->iItem << " pNmItemAct->iSubItem " << pNmItemAct->iSubItem << endLog;
+#endif
+      int iRow = pNmItemAct->iItem;
+      int iCol = pNmItemAct->iSubItem;
+      if (iRow < 0)
+        return false;
+
+      int update = 0;
+
+      // Inform the item of the double-click
+      update = (*contents)[iRow]->do_default_action(iCol );
+
+      // Update items, if needed
+      if (update > 0)
+        {
+          ListView_RedrawItems(hWndListView, iRow, iRow + update -1);
+        }
+
+      return true;
+    }
+    break;
+
   case NM_CUSTOMDRAW:
     {
       NMLVCUSTOMDRAW *pNmLvCustomDraw = (NMLVCUSTOMDRAW *)pNmHdr;
diff --git a/ListView.h b/ListView.h
index 97b138a..519b61a 100644
--- a/ListView.h
+++ b/ListView.h
@@ -37,6 +37,7 @@ class ListViewLine
   virtual int get_indent() const = 0;
   virtual ActionList *get_actions(int col) const = 0;
   virtual int do_action(int col, int id) = 0;
+  virtual int do_default_action(int col) = 0;
   virtual bool map_key_to_action(WORD vkey, int *col_num, int *action_id) const = 0;
 };
 
diff --git a/PickCategoryLine.cc b/PickCategoryLine.cc
index c088cd4..7aa1f28 100644
--- a/PickCategoryLine.cc
+++ b/PickCategoryLine.cc
@@ -56,6 +56,12 @@ PickCategoryLine::do_action(int col_num, int action_id)
   return 1;
 }
 
+int
+PickCategoryLine::do_default_action(int col_num)
+{
+  return 0;
+}
+
 ActionList *
 PickCategoryLine::get_actions(int col) const
 {
diff --git a/PickCategoryLine.h b/PickCategoryLine.h
index 9486904..35b90e6 100644
--- a/PickCategoryLine.h
+++ b/PickCategoryLine.h
@@ -40,6 +40,7 @@ public:
   int get_indent() const;
   ActionList *get_actions(int col) const;
   int do_action(int col, int action_id);
+  int do_default_action(int col);
   bool map_key_to_action(WORD vkey, int *col_num, int *action_id) const;
 
 private:
diff --git a/PickPackageLine.cc b/PickPackageLine.cc
index 1f884be..685d632 100644
--- a/PickPackageLine.cc
+++ b/PickPackageLine.cc
@@ -144,6 +144,17 @@ PickPackageLine::do_action(int col_num, int action_id)
   return 0;
 }
 
+int
+PickPackageLine::do_default_action(int col_num)
+{
+  if (col_num == new_col)
+    {
+      pkg.toggle_action();
+      return 1;
+    }
+  return 0;
+}
+
 ActionList *
 PickPackageLine::get_actions(int col_num) const
 {
diff --git a/PickPackageLine.h b/PickPackageLine.h
index a35f399..3877a4b 100644
--- a/PickPackageLine.h
+++ b/PickPackageLine.h
@@ -36,6 +36,7 @@ public:
   int get_indent() const;
   ActionList *get_actions(int col_num) const;
   int do_action(int col, int action_id);
+  int do_default_action(int col);
   bool map_key_to_action(WORD vkey, int *col_num, int *action_id) const;
 private:
   packagemeta & pkg;
diff --git a/package_meta.cc b/package_meta.cc
index cbb7388..3509f05 100644
--- a/package_meta.cc
+++ b/package_meta.cc
@@ -465,6 +465,27 @@ packagemeta::select_action (int id, trusts const deftrust)
     user_picked = true;
 }
 
+// toggle between the currently installed version (or uninstalled, if not
+// installed), and the naively preferred version (the highest non-test version)
+void
+packagemeta::toggle_action ()
+{
+  if (desired != installed)
+    {
+      set_action(Default_action, installed);
+    }
+  else
+    {
+      packageversion naively_preferred;
+      std::set<packageversion>::iterator i = versions.begin ();
+      for (i = versions.begin (); i != versions.end (); ++i)
+        if (!packagedb::solver.is_test_package(*i))
+          naively_preferred = *i;
+
+      set_action(Install_action, naively_preferred);
+    }
+}
+
 ActionList *
 packagemeta::list_actions(trusts const trust)
 {
diff --git a/package_meta.h b/package_meta.h
index 0eff8d0..c9bfe7c 100644
--- a/package_meta.h
+++ b/package_meta.h
@@ -63,6 +63,7 @@ public:
   void set_action (_actions, packageversion const & default_version);
   ActionList *list_actions(trusts const trust);
   void select_action (int id, trusts const deftrust);
+  void toggle_action ();
 
   void set_message (const std::string& message_id, const std::string& message_string)
   {
-- 
2.17.0


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]