[PATCH] setup: Always draw chooser icons using system colors

Igor Peshansky pechtcha@cs.nyu.edu
Tue May 23 13:17:00 GMT 2006


Hi,

As promised in <http://cygwin.com/ml/cygwin/2006-05/msg00612.html>, here's
a patch that makes setup always draw the chooser icons using the system
foreground and background colors (just like it does for text).  I've also
taken the opportunity to do a slight bit of code clean-up.  There's still
a little glitch left -- when doing a lot of fast scrolling back and forth,
the icons sometimes switch from the system foreground color to the
inverted system background color.  I think I know why this is happening
(i.e., the FillRgn() gets ignored for some reason), but this needs further
debugging.  As this is a corner case, I wouldn't worry too much about it.
As always, the ChangeLog is below -- opinions welcome.
	Igor

ChangeLog:
==============================================================================
2006-05-23  Igor Peshansky  <pechtcha@cs.nyu.edu>

	* PickPackageLine.h (PickPackageLine::DrawIcon): Move to PickView.
	* PickView.h (PickView::DrawIcon): Move from PickPackageLine.
	* PickCategoryLine.cc (PickCategoryLine::paint): Use
	PickView::DrawIcon() instead of BitBlt().
	* PickPackageLine.cc (PickPackageLine::DrawIcon): Move to PickView.
	(PickPackageLine::paint): Use PickView::DrawIcon().
	* PickView.cc (PickView::~PickView): Delete GDI objects.
	(PickView::DrawIcon): New function.  Use system default colors to
	draw bitmaps.
	(PickView::paint): Set background color instead of using transparent
	mode.

-- 
				http://cs.nyu.edu/~pechtcha/
      |\      _,,,---,,_	    pechtcha@cs.nyu.edu | igor@watson.ibm.com
ZZZzz /,`.-'`'    -.  ;-;;,_		Igor Peshansky, Ph.D. (name changed!)
     |,4-  ) )-,_. ,\ (  `'-'		old name: Igor Pechtchanski
    '---''(_/--'  `-'\_) fL	a.k.a JaguaR-R-R-r-r-r-.-.-.  Meow!

"Las! je suis sot... -Mais non, tu ne l'es pas, puisque tu t'en rends compte."
"But no -- you are no fool; you call yourself a fool, there's proof enough in
that!" -- Rostand, "Cyrano de Bergerac"
-------------- next part --------------
Index: PickCategoryLine.cc
===================================================================
RCS file: /cvs/cygwin-apps/setup/PickCategoryLine.cc,v
retrieving revision 2.9
diff -u -p -r2.9 PickCategoryLine.cc
--- PickCategoryLine.cc	9 Sep 2005 19:08:02 -0000	2.9
+++ PickCategoryLine.cc	23 May 2006 13:10:27 -0000
@@ -38,9 +38,7 @@ PickCategoryLine::paint (HDC hdc, HRGN h
       int by = r + (theView.tm.tmHeight / 2) - 5;
 
       // draw the '+' or '-' box
-      SelectObject (theView.bitmap_dc, 
-                      (collapsed ? theView.bm_treeplus : theView.bm_treeminus));
-      BitBlt (hdc, x2, by, 11, 11, theView.bitmap_dc, 0, 0, SRCAND);
+      theView.DrawIcon (hdc, x2, by, (collapsed ? theView.bm_treeplus : theView.bm_treeminus));
 
       // draw the category name
       TextOut (hdc, x2 + 11 + ICON_MARGIN, r, cat.first.c_str(), cat.first.size());
@@ -52,9 +50,8 @@ PickCategoryLine::paint (HDC hdc, HRGN h
 	}
       
       // draw the 'spin' glyph
-      SelectObject (theView.bitmap_dc, theView.bm_spin);
       spin_x = x2 + 11 + ICON_MARGIN + labellength + ICON_MARGIN;
-      BitBlt (hdc, spin_x, by, 11, 11, theView.bitmap_dc, 0, 0, SRCAND);
+      theView.DrawIcon (hdc, spin_x, by, theView.bm_spin);
       
       // draw the caption ('Default', 'Install', etc)
       TextOut (hdc, spin_x + SPIN_WIDTH + ICON_MARGIN, r, 
Index: PickPackageLine.cc
===================================================================
RCS file: /cvs/cygwin-apps/setup/PickPackageLine.cc,v
retrieving revision 2.20
diff -u -p -r2.20 PickPackageLine.cc
--- PickPackageLine.cc	16 Apr 2006 23:07:44 -0000	2.20
+++ PickPackageLine.cc	23 May 2006 13:10:27 -0000
@@ -19,13 +19,6 @@
 #include "package_version.h"
 
 void
-PickPackageLine::DrawIcon (HDC hdc, int x, int y, HANDLE hIcon)
-{
-  SelectObject (theView.bitmap_dc, hIcon);
-  BitBlt (hdc, x, y, 11, 11, theView.bitmap_dc, 0, 0, SRCAND);
-}
-
-void
 PickPackageLine::paint (HDC hdc, HRGN unused, int x, int y, int col_num, int show_cat)
 {
   int rb = y + theView.tm.tmHeight;
@@ -40,21 +33,21 @@ PickPackageLine::paint (HDC hdc, HRGN un
   else if (col_num == theView.new_col)
     {
       // TextOut (hdc, x + HMARGIN/2 + NEW_COL_SIZE_SLOP, y, s.c_str(), s.size());
-      // DrawIcon (hdc, x + HMARGIN/2 + ICON_MARGIN/2 + RTARROW_WIDTH, by, theView.bm_spin);
+      // theView.DrawIcon (hdc, x + HMARGIN/2 + ICON_MARGIN/2 + RTARROW_WIDTH, by, theView.bm_spin);
       TextOut (hdc, x + HMARGIN/2 + ICON_MARGIN/2 + SPIN_WIDTH , y,
             pkg.action_caption ().c_str(), pkg.action_caption ().size());
-      DrawIcon (hdc, x + HMARGIN/2, by, theView.bm_spin);
+      theView.DrawIcon (hdc, x + HMARGIN/2, by, theView.bm_spin);
     }
   else if (col_num == theView.bintick_col)
     {
       if (/* uninstall or skip */ !pkg.desired ||
           /* current version */ pkg.desired == pkg.installed ||
           /* no source */ !pkg.desired.accessible())
-        DrawIcon (hdc, x + HMARGIN/2, by, theView.bm_checkna);
+        theView.DrawIcon (hdc, x + HMARGIN/2, by, theView.bm_checkna);
       else if (pkg.desired.picked())
-        DrawIcon (hdc, x + HMARGIN/2, by, theView.bm_checkyes);
+        theView.DrawIcon (hdc, x + HMARGIN/2, by, theView.bm_checkyes);
       else
-        DrawIcon (hdc, x + HMARGIN/2, by, theView.bm_checkno);
+        theView.DrawIcon (hdc, x + HMARGIN/2, by, theView.bm_checkno);
     }
   else if (col_num == theView.srctick_col)
     {
@@ -73,11 +66,11 @@ PickPackageLine::paint (HDC hdc, HRGN un
 #endif
           /* when no source mirror available */
           !pkg.desired.sourcePackage().accessible())
-        DrawIcon (hdc, x + HMARGIN/2, by, theView.bm_checkna);
+        theView.DrawIcon (hdc, x + HMARGIN/2, by, theView.bm_checkna);
       else if (pkg.desired.sourcePackage().picked())
-        DrawIcon (hdc, x + HMARGIN/2, by, theView.bm_checkyes);
+        theView.DrawIcon (hdc, x + HMARGIN/2, by, theView.bm_checkyes);
       else
-        DrawIcon (hdc, x + HMARGIN/2, by, theView.bm_checkno);
+        theView.DrawIcon (hdc, x + HMARGIN/2, by, theView.bm_checkno);
     }
   else if (col_num == theView.cat_col)
     {
Index: PickPackageLine.h
===================================================================
RCS file: /cvs/cygwin-apps/setup/PickPackageLine.h,v
retrieving revision 2.6
diff -u -p -r2.6 PickPackageLine.h
--- PickPackageLine.h	21 May 2005 23:04:02 -0000	2.6
+++ PickPackageLine.h	23 May 2006 13:10:27 -0000
@@ -26,7 +26,6 @@ public:
   PickPackageLine (PickView &aView, packagemeta & apkg):PickLine (apkg.key), pkg (apkg), theView (aView)
   {
   };
-  void DrawIcon (HDC hdc, int x, int y, HANDLE hIcon);
   virtual void paint (HDC hdc, HRGN unused, int x, int y, int col_num, int show_cat);
   virtual int click (int const myrow, int const ClickedRow, int const x);
   virtual int itemcount () const
Index: PickView.cc
===================================================================
RCS file: /cvs/cygwin-apps/setup/PickView.cc,v
retrieving revision 2.30
diff -u -p -r2.30 PickView.cc
--- PickView.cc	17 Apr 2006 15:40:11 -0000	2.30
+++ PickView.cc	23 May 2006 13:10:27 -0000
@@ -575,6 +575,13 @@ PickView::init(views _mode)
 
 PickView::~PickView()
 {
+  DeleteDC(bitmap_dc);
+  DeleteObject(bm_spin);
+  DeleteObject(bm_checkyes);
+  DeleteObject(bm_checkno);
+  DeleteObject(bm_checkna);
+  DeleteObject(bm_treeplus);
+  DeleteObject(bm_treeminus);
 }
 
 bool PickView::registerWindowClass ()
@@ -798,6 +805,38 @@ PickView::WindowProc (UINT message, WPAR
   return DefWindowProc (GetHWND(), message, wParam, lParam);
 }
 
+////
+// Turn black into foreground color and white into background color by
+//   1) Filling a square with ~(FG^BG)
+//   2) Blitting the bitmap on it with NOTSRCERASE (white->black; black->FG^BG)
+//   3) Blitting the result on BG with SRCINVERT (white->BG; black->FG)
+void
+PickView::DrawIcon (HDC hdc, int x, int y, HANDLE hIcon)
+{
+  SelectObject (bitmap_dc, hIcon);
+  HDC dc_tmp = CreateCompatibleDC (hdc);
+  HBITMAP bm_tmp = CreateCompatibleBitmap (hdc, 11, 11);
+  HANDLE sv_tmp = SelectObject (dc_tmp, bm_tmp);
+  COLORREF clr = ~GetSysColor (COLOR_WINDOW) ^ GetSysColor (COLOR_WINDOWTEXT);
+  clr = RGB (GetRValue (clr), GetGValue (clr), GetBValue (clr)); // reconvert
+  // TODO: Figure out how to create this brush only once
+  HBRUSH bg_fg_brush = CreateSolidBrush (clr);
+  // FIXME: Sometimes (after fast scrolling?) the color gets reset
+  FillRgn (dc_tmp, CreateRectRgn (0, 0, 11, 11), bg_fg_brush);
+  BitBlt (dc_tmp, 0, 0, 11, 11, bitmap_dc, 0, 0, NOTSRCERASE);
+  BitBlt (hdc, x, y, 11, 11, dc_tmp, 0, 0, SRCINVERT);
+  DeleteObject (bg_fg_brush);
+///////////// On WinNT-based systems, we could've done the below instead
+///////////// See http://support.microsoft.com/default.aspx?scid=kb;en-us;79212
+//      SelectObject (hdc, GetSysColorBrush (COLOR_WINDOWTEXT));
+//      HBITMAP bm_tmp = CreateBitmap (11, 11, 1, 1, NULL);
+//      HANDLE sv_tmp = SelectObject (dc_tmp, bm_tmp);
+//      BitBlt (dc_tmp, 0, 0, 11, 11, bitmap_dc, 0, 0, SRCCOPY);
+//      MaskBlt (hdc, x2, by, 11, 11, bitmap_dc, 0, 0, bm_tmp, 0, 0, MAKEROP4 (SRCAND, PATCOPY));
+  DeleteObject (SelectObject (dc_tmp, sv_tmp));
+  DeleteDC (dc_tmp);
+}
+
 void
 PickView::paint (HWND hwnd)
 {
@@ -821,7 +860,7 @@ PickView::paint (HWND hwnd)
  
   SelectObject (hdc, sysfont);
   SetTextColor (hdc, GetSysColor (COLOR_WINDOWTEXT));
-  SetBkMode (hdc, TRANSPARENT);
+  SetBkColor (hdc, GetSysColor (COLOR_WINDOW));
   FillRgn (hdc, hUpdRgn, GetSysColorBrush(COLOR_WINDOW));
 
   RECT cr;
Index: PickView.h
===================================================================
RCS file: /cvs/cygwin-apps/setup/PickView.h,v
retrieving revision 2.16
diff -u -p -r2.16 PickView.h
--- PickView.h	17 Apr 2006 15:40:11 -0000	2.16
+++ PickView.h	23 May 2006 13:10:27 -0000
@@ -45,6 +45,7 @@ public:
   void defaultTrust (trusts trust);
   void cycleViewMode ();
   void setViewMode (views mode);
+  void DrawIcon (HDC hdc, int x, int y, HANDLE hIcon);
   void paint (HWND hwnd);
   LRESULT CALLBACK list_click (HWND hwnd, BOOL dblclk, int x, int y, UINT hitCode);
   LRESULT CALLBACK list_hscroll (HWND hwnd, HWND hctl, UINT code, int pos);


More information about the Cygwin-apps mailing list