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 05/13] Custom draw checkboxes in ListView control


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


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