public inbox for cygwin-apps@cygwin.com
 help / color / mirror / Atom feed
From: Jon Turney <jon.turney@dronecode.org.uk>
To: cygwin-apps@cygwin.com
Cc: Jon Turney <jon.turney@dronecode.org.uk>
Subject: [PATCH setup 05/13] Custom draw checkboxes in ListView control
Date: Sun, 05 Aug 2018 22:10:00 -0000	[thread overview]
Message-ID: <20180805220851.270212-6-jon.turney@dronecode.org.uk> (raw)
In-Reply-To: <20180805220851.270212-1-jon.turney@dronecode.org.uk>

Future work: What does this look like when a theme is in used? Does the row
size need to be slightly adjusted to ensure it accomodates checkbox height?

v2:
erase to background colour before drawing checkbox
---
 ListView.cc | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 ListView.h  |  7 ++++++
 choose.cc   | 16 +++++++-------
 3 files changed, 78 insertions(+), 8 deletions(-)

diff --git a/ListView.cc b/ListView.cc
index 97ee44c..e3f1e44 100644
--- a/ListView.cc
+++ b/ListView.cc
@@ -289,6 +289,69 @@ ListView::OnNotify (NMHDR *pNmHdr, LRESULT *pResult)
       return true;
     }
     break;
+
+  case NM_CUSTOMDRAW:
+    {
+      NMLVCUSTOMDRAW *pNmLvCustomDraw = (NMLVCUSTOMDRAW *)pNmHdr;
+
+      switch(pNmLvCustomDraw->nmcd.dwDrawStage)
+        {
+        case CDDS_PREPAINT:
+          *pResult = CDRF_NOTIFYITEMDRAW;
+          return true;
+        case CDDS_ITEMPREPAINT:
+          *pResult = CDRF_NOTIFYSUBITEMDRAW;
+          return true;
+        case CDDS_SUBITEM | CDDS_ITEMPREPAINT:
+          {
+            LRESULT result = CDRF_DODEFAULT;
+            int iCol = pNmLvCustomDraw->iSubItem;
+            int iRow = pNmLvCustomDraw->nmcd.dwItemSpec;
+
+            switch (headers[iCol].type)
+              {
+              default:
+              case ListView::ControlType::text:
+                result = CDRF_DODEFAULT;
+                break;
+
+              case ListView::ControlType::checkbox:
+                {
+                  // get the subitem text
+                  char buf[3];
+                  ListView_GetItemText(hWndListView, iRow, iCol, buf, _countof(buf));
+
+                  // map the subitem text to a checkbox state
+                  UINT state = DFCS_BUTTONCHECK | DFCS_FLAT;
+                  if (buf[0] == '\0')                           // empty
+                    {
+                      result = CDRF_DODEFAULT;
+                      break;
+                    }
+                  else if (buf[0] == 'y')                       // yes
+                    state |= DFCS_CHECKED;
+                  else if ((buf[0] == 'n') && (buf[1] == 'o'))  // no
+                    state |= 0;
+                  else                                          // n/a
+                    state |= DFCS_INACTIVE;
+
+                  // erase and draw a checkbox
+                  RECT r;
+                  ListView_GetSubItemRect(hWndListView, iRow, iCol, LVIR_BOUNDS, &r);
+                  HBRUSH hBrush = CreateSolidBrush(ListView_GetBkColor(hWndListView));
+                  FillRect(pNmLvCustomDraw->nmcd.hdc, &r, hBrush);
+                  DeleteObject(hBrush);
+                  DrawFrameControl(pNmLvCustomDraw->nmcd.hdc, &r, DFC_BUTTON, state);
+
+                  result = CDRF_SKIPDEFAULT;
+                }
+                break;
+              }
+            *pResult = result;
+            return true;
+          }
+        }
+    }
   }
 
   // We don't care.
diff --git a/ListView.h b/ListView.h
index d339011..3aabc3f 100644
--- a/ListView.h
+++ b/ListView.h
@@ -36,11 +36,18 @@ typedef std::vector<ListViewLine *> ListViewContents;
 class ListView
 {
  public:
+  enum class ControlType
+  {
+    text,
+    checkbox,
+  };
+
   class Header
   {
   public:
     const char *text;
     int fmt;
+    ControlType type;
     int width;
     int hdr_width;
   };
diff --git a/choose.cc b/choose.cc
index c86294a..c65a107 100644
--- a/choose.cc
+++ b/choose.cc
@@ -132,14 +132,14 @@ ChooserPage::~ChooserPage ()
 }
 
 static ListView::Header pkg_headers[] = {
-  {"Package",     LVCFMT_LEFT},
-  {"Current",     LVCFMT_LEFT},
-  {"New",         LVCFMT_LEFT},
-  {"Bin?",        LVCFMT_LEFT},
-  {"Src?",        LVCFMT_LEFT},
-  {"Categories",  LVCFMT_LEFT},
-  {"Size",        LVCFMT_RIGHT},
-  {"Description", LVCFMT_LEFT},
+  {"Package",     LVCFMT_LEFT,  ListView::ControlType::text},
+  {"Current",     LVCFMT_LEFT,  ListView::ControlType::text},
+  {"New",         LVCFMT_LEFT,  ListView::ControlType::text},
+  {"Bin?",        LVCFMT_LEFT,  ListView::ControlType::checkbox},
+  {"Src?",        LVCFMT_LEFT,  ListView::ControlType::checkbox},
+  {"Categories",  LVCFMT_LEFT,  ListView::ControlType::text},
+  {"Size",        LVCFMT_RIGHT, ListView::ControlType::text},
+  {"Description", LVCFMT_LEFT,  ListView::ControlType::text},
   {0}
 };
 
-- 
2.17.0

  parent reply	other threads:[~2018-08-05 22:10 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-08-05 22:09 [PATCH setup 00/13] ListView Package Chooser Jon Turney
2018-08-05 22:09 ` [PATCH setup 02/13] Add OnNotify virtual function to class Window for WM_NOTIFY notifications Jon Turney
2018-08-05 22:09 ` [PATCH setup 01/13] Change packagemeta::_actions to an enum Jon Turney
2018-08-05 22:09 ` [PATCH setup 03/13] Drop 'using namespace std;' from PickView.cc Jon Turney
2018-08-05 22:10 ` [PATCH setup 06/13] Add methods for listing possible actions on, and applying one to, a package Jon Turney
2018-08-05 22:10 ` [PATCH setup 07/13] Custom draw popup menus in ListView control Jon Turney
2018-08-05 22:10 ` Jon Turney [this message]
2018-08-05 22:10 ` [PATCH setup 04/13] Use a ListView common control rather than a hand-built grid Jon Turney
2018-08-05 22:10 ` [PATCH setup 09/13] Use an icon to represent expanded/collapsed state Jon Turney
2018-08-05 22:10 ` [PATCH setup 08/13] Show the count of packages in a category Jon Turney
2018-08-05 22:11 ` [PATCH setup 10/13] Use indents in category view Jon Turney
2018-08-05 22:12 ` [PATCH setup 12/13] Restore packagemeta::LDesc() Jon Turney
2018-08-05 22:12 ` [PATCH setup 11/13] Add LDesc() accessor method to SolvableVersion Jon Turney
2018-08-05 22:12 ` [PATCH setup 13/13] Add ldesc tooltips to sdesc column of listview Jon Turney
2018-08-06 14:15 ` [PATCH setup 00/13] ListView Package Chooser Ken Brown
2018-08-06 16:41   ` Achim Gratz
2018-08-06 16:47     ` Achim Gratz
2018-08-06 19:19   ` Ken Brown
2018-10-13 18:46     ` Jon Turney
2018-08-06 16:40 ` Achim Gratz

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180805220851.270212-6-jon.turney@dronecode.org.uk \
    --to=jon.turney@dronecode.org.uk \
    --cc=cygwin-apps@cygwin.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).