]> icculus.org git repositories - icculus/iodoom3.git/blob - neo/tools/comafx/DialogColorPicker.cpp
Various Mac OS X tweaks to get this to build. Probably breaking things.
[icculus/iodoom3.git] / neo / tools / comafx / DialogColorPicker.cpp
1 /*
2 ===========================================================================
3
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company. 
6
7 This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).  
8
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code.  If not, see <http://www.gnu.org/licenses/>.
21
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code.  If not, please request a copy in writing from id Software at the address below.
23
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25
26 ===========================================================================
27 */
28
29 #include "../../idlib/precompiled.h"
30 #pragma hdrstop
31
32 #include "../../sys/win32/rc/Radiant_resource.h"
33 #include "DialogColorPicker.h"
34
35 #ifdef ID_DEBUG_MEMORY
36 #undef new
37 #undef DEBUG_NEW
38 #define DEBUG_NEW new
39 #endif
40
41 // Old color picker
42
43 class CMyColorDialog : public CColorDialog 
44 {
45   DECLARE_DYNCREATE(CMyColorDialog);
46      // Construction
47 public:
48      CMyColorDialog( COLORREF clrInit = 0, DWORD dwFlags = 0, CWnd *pParentWnd = NULL );
49      virtual int DoModal();
50
51 protected:
52      enum { NCUSTCOLORS = 16 };
53      static COLORREF    c_CustColors[NCUSTCOLORS];
54      static COLORREF    c_LastCustColors[NCUSTCOLORS];
55      static bool                c_NeedToInitCustColors;
56      static void                InitCustColors();
57      static void                SaveCustColors();
58
59          // Dialog Data
60      //{{AFX_DATA(CMyColorDialog)
61      //}}AFX_DATA
62
63 protected:
64      // ClassWizard generate virtual function overrides
65      //{{AFX_VIRTUAL(CMyColorDialog)
66      virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
67      //}}AFX_VIRTUAL
68
69          // Generated message map functions
70      //{{AFX_MSG(CMyColorDialog)
71      //}}AFX_MSG
72      DECLARE_MESSAGE_MAP()
73 };
74
75 IMPLEMENT_DYNCREATE( CMyColorDialog, CColorDialog )
76
77 bool CMyColorDialog::c_NeedToInitCustColors = true;
78 COLORREF CMyColorDialog::c_CustColors[];
79 COLORREF CMyColorDialog::c_LastCustColors[];
80
81 #define SECTION _T("Custom Colors")
82
83 void CMyColorDialog::InitCustColors() {
84         for ( int i = 0; i < NCUSTCOLORS; i++) {
85                 CString entry;
86                 entry.Format( "tool_color%d", i);
87                 idCVar *cvar = cvarSystem->Find( entry );
88                 if ( cvar ) {
89                         c_LastCustColors[i] = c_CustColors[i] = cvar->GetInteger();
90                 } else {
91                         c_LastCustColors[i] = c_CustColors[i] = RGB( 255, 255, 255 );
92                 }
93         }
94         c_NeedToInitCustColors= false;
95 }
96
97 void CMyColorDialog::SaveCustColors() {
98         for (int i = 0; i < NCUSTCOLORS; i++) {
99                 if ( c_LastCustColors[i] != c_CustColors[i] ) {
100                         CString entry;
101                         entry.Format( "tool_color%d", i );
102                         if ( c_CustColors[i] == RGB( 255, 255, 255 ) ) {
103                                 cvarSystem->SetCVarString( entry, "" );
104                         } else {
105                                 cvarSystem->SetCVarString( entry, va( "%d", c_CustColors[i] ), CVAR_TOOL );
106                         }
107                         c_LastCustColors[i] = c_CustColors[i];
108                 }
109         }
110 }
111
112 CMyColorDialog::CMyColorDialog( COLORREF clrInit, DWORD dwFlags, 
113                 CWnd* pParentWnd) : CColorDialog(clrInit,dwFlags,pParentWnd)
114 {
115      //{{AFX_DATA_INIT(CMyColorDialog)
116      //}}AFX_DATA_INIT
117      if (c_NeedToInitCustColors) {
118           InitCustColors();
119      }
120      m_cc.lpCustColors = c_CustColors;
121 }
122
123 int CMyColorDialog::DoModal() {
124      int code = CColorDialog::DoModal();
125      SaveCustColors();
126      return code;
127 }
128
129 void CMyColorDialog::DoDataExchange(CDataExchange* pDX) {
130      // overridden (calls this base class)
131      CColorDialog::DoDataExchange(pDX);
132      //{{AFX_DATA_MAP(CMyColorDialog)
133      //}}AFX_DATA_MAP
134 }
135
136 BEGIN_MESSAGE_MAP(CMyColorDialog, CColorDialog)
137 //{{AFX_MSG_MAP(CMyColorDialog)
138 //}}AFX_MSG_MAP
139 END_MESSAGE_MAP()
140
141 COLORREF DoOldColor(COLORREF cr) {
142         CMyColorDialog dlg(cr, CC_FULLOPEN | CC_RGBINIT | CC_ANYCOLOR);
143         if (dlg.DoModal() == IDOK) {
144                 return dlg.GetColor();
145         }
146         return cr;
147 }
148
149 // New color picker
150
151 // Original ColorPicker/DIB source by Rajiv Ramachandran <rrajivram@hotmail.com>
152 // included with Permission from the author
153
154 #define RADUIS  100
155
156 #define IN_NOTHING              0
157 #define IN_CIRCLE               1
158 #define IN_BRIGHT               2
159 #define IN_OVERBRIGHT   3
160
161 int Distance(CPoint pt1,CPoint pt2);
162
163
164 double Slope( CPoint pt1,CPoint pt2 ) {
165         double x,y;
166
167         y = pt2.y - pt1.y;
168         x = pt2.x - pt1.x;
169         if( x ) {
170                 return y/x;
171         } else {
172                 return BAD_SLOPE;
173         }
174 }
175
176 CPoint Intersection(LineDesc l1,LineDesc l2)
177 {
178         CPoint pt;
179         double x,y;
180
181         if(l1.slope == l2.slope)
182         {
183                 // Parallel lines, no intersection
184                 return CPoint(0,0);
185         }
186         else
187         if(l1.slope == BAD_SLOPE )
188         {
189                 // First Line is vertical, eqn is x=0
190                 // Put x = 0 in second line eqn to get y;
191                 x = l1.x;
192                 y = l2.slope * x + l2.c;
193         }
194         else
195         if(l2.slope == BAD_SLOPE)
196         {
197                 // second line is vertical Equation of line is x=0;
198                 // Put x = 0 in first line eqn to get y;
199                 x = l2.x;
200                 y = l1.slope * l2.x + l1.c;
201         }
202         else
203         {
204                 y = ((l1.c * l2.slope) - (l2.c * l1.slope))/(l2.slope - l1.slope);
205                 x = (y - l1.c)/l1.slope;
206         }
207
208         return CPoint((int)x,(int)y);
209 }
210
211 double FindC(LineDesc& l)
212 {
213         double c;
214
215         if(l.slope == BAD_SLOPE)
216         {
217                 c = l.y;
218         }
219         else
220         {
221                 c = l.y - l.slope * l.x;
222         }
223         return c;
224 }
225
226 CPoint PointOnLine(CPoint pt1,CPoint pt2,int len,int maxlen )
227 {
228         double x,y,m,a,c,C,A;
229         double a2,c2,m2,B;      
230         CPoint opt = pt1;
231         CPoint pt;
232
233         pt1.y *= -1;
234         pt2.y *= -1;
235
236         a = (double)len;
237
238         if(pt2.x != pt1.x)
239         {
240                 m = (double)(pt2.y - pt1.y)/(pt2.x - pt1.x);
241                 m2 = m*m;
242                 a2 = a*a;
243                 c = (double)pt1.y - m * (double)pt1.x;
244                 c2 = c*c;
245
246
247                 A = 1.0;
248                 
249                 x = pt1.x;
250
251                 B = 2.0 * pt1.x;
252
253                 x *= x;
254                 C = x - a2/(m2 + 1);
255                 
256                 x = (B + idMath::Sqrt(B*B - (4.0*A*C)))/(2.0*A);
257                 y = m*x + c;
258                 pt = CPoint((int)x,(int)y);
259                 if(Distance(pt,pt1) > maxlen || Distance(pt,pt2) > maxlen)
260                 {
261                         x = (B - idMath::Sqrt(B*B - (4.0*A*C)))/(2.0 * A);
262                         y = m*x + c;
263                         pt = CPoint((int)x,(int)y);
264                 }
265         }
266         else
267         {
268                 a2 = a*a;
269                 y = idMath::Sqrt(a2);
270                 x = 0;
271                 pt = CPoint((int)x,(int)y);
272                 pt += pt1;
273                 if(Distance(pt,pt1) > maxlen || Distance(pt,pt2) > maxlen)
274                 {
275                         y = -1.0 *y;
276                         pt = CPoint((int)x,(int)y);
277                         pt+=pt1;
278                 }
279         }
280         pt.y *= -1;
281         return pt;
282 }
283
284
285 int Distance(CPoint pt1,CPoint pt2)
286 {
287         double a;
288         int x,y;
289
290         y = (pt1.y - pt2.y);
291         y *= y;
292
293         x = (pt1.x - pt2.x);
294         x *= x;
295         
296         a = (double)x + (double)y ;
297         a = idMath::Sqrt(a);
298         return (int)a;
299 }
300
301 double AngleFromPoint(CPoint pt,CPoint center)
302 {
303         double x,y;
304
305         y = -1 * (pt.y - center.y);
306         x = pt.x - center.x;
307         if(x == 0 && y == 0)
308         {
309                 return 0.0;
310         }
311         else
312         {
313                 return atan2(y,x);
314         }
315 }
316
317 CPoint PtFromAngle(double angle,double sat,CPoint center)
318 {
319         angle = DEG2RAD(angle);
320         sat = TOSCALE(sat);
321
322         double x,y;
323
324         x = sat * cos(angle);
325         y = sat * sin(angle);
326
327         CPoint pt;
328
329         pt = CPoint((int)x,(int)y);
330         pt.y *= -1;
331         pt += center;
332         return pt;
333 }
334
335 RGBType HSVType::toRGB()
336 {
337         RGBType rgb;
338
339         if(!h  && !s)
340         {
341                 rgb.r = rgb.g = rgb.b = v;
342         }
343
344         double min,max,delta,hue;
345         
346         max = v;
347         delta = (max * s)/255.0;
348         min = max - delta;
349
350         hue = h;
351         if(h > 300 || h <= 60)
352         {
353                 rgb.r = (int)max;
354                 if(h > 300)
355                 {
356                         rgb.g = (int)min;
357                         hue = (hue - 360.0)/60.0;
358                         rgb.b = (int)((hue * delta - min) * -1);
359                 }
360                 else
361                 {
362                         rgb.b = (int)min;
363                         hue = hue / 60.0;
364                         rgb.g = (int)(hue * delta + min);
365                 }
366         }
367         else if(h > 60 && h < 180)
368         {
369                 rgb.g = (int)max;
370                 if(h < 120)
371                 {
372                         rgb.b = (int)min;
373                         hue = (hue/60.0 - 2.0 ) * delta;
374                         rgb.r = (int)(min - hue);
375                 }
376                 else
377                 {
378                         rgb.r = (int)min;
379                         hue = (hue/60 - 2.0) * delta;
380                         rgb.b = (int)(min + hue);
381                 }
382         }
383         else
384         {
385                 rgb.b = (int)max;
386                 if(h < 240)
387                 {
388                         rgb.r = (int)min;
389                         hue = (hue/60.0 - 4.0 ) * delta;
390                         rgb.g = (int)(min - hue);
391                 }
392                 else
393                 {
394                         rgb.g = (int)min;
395                         hue = (hue/60 - 4.0) * delta;
396                         rgb.r = (int)(min + hue);
397                 }
398         }
399         return rgb;
400 }
401
402
403 HSVType RGBType::toHSV()
404 {
405         HSVType hsv;
406
407         double min,max,delta,temp;
408
409         min = __min(r,__min(g,b));      
410         max = __max(r,__max(g,b));
411         delta = max - min;
412         
413         hsv.v = (int)max;
414         if(!delta)
415         {
416                 hsv.h = hsv.s = 0;
417         }
418         else
419         {
420                 temp = delta/max;
421                 hsv.s = (int)(temp*255);
422
423                 if(r == (int)max)
424                 {
425                         temp = (double)(g-b)/delta;
426                 }
427                 else
428                 if(g == (int)max)
429                 {
430                         temp = 2.0 + ((double)(b-r)/delta);
431                 }
432                 else
433                 {
434                         temp = 4.0 + ((double)(r-g)/delta);
435                 }
436                 temp *= 60;
437                 if(temp < 0)
438                 {
439                         temp+=360;
440                 }
441                 if(temp == 360)
442                 {
443                         temp = 0;
444                 }
445                 hsv.h = (int)temp;
446         }
447         return hsv;
448
449 }
450 /////////////////////////////////////////////////////////////////////////////
451 // CDialogColorPicker dialog
452
453
454 CDialogColorPicker::CDialogColorPicker( COLORREF c, CWnd* pParent /*=NULL*/)
455         : CDialog(CDialogColorPicker::IDD, pParent)
456 {
457         //{{AFX_DATA_INIT(CDialogColorPicker)
458         m_overBright = 0.0f;
459         //}}AFX_DATA_INIT
460
461         Vertex = CPoint(102,108);
462         Top = CPoint(102,9);
463         Left = CPoint(23,147);
464         Right = CPoint(181,147);
465
466         color.r = GetRValue(c);
467         color.g = GetGValue(c);
468         color.b = GetBValue(c);
469
470         m_OldColor = color;
471         hsvColor = color.toHSV();
472         m_bInMouse = FALSE;
473         m_bInitOver = FALSE;
474         m_bInDrawAll = FALSE;
475         overBright = 1.0f;
476         UpdateParent = NULL;
477 }
478
479 CDialogColorPicker::~CDialogColorPicker()
480 {
481         if(m_RgbBitmap.GetSafeHandle())
482         {
483                 m_RgbBitmap.DeleteObject();
484         }
485         if(m_HsbBitmap.GetSafeHandle())
486         {
487                 m_HsbBitmap.DeleteObject();
488         }
489 }
490
491
492 BEGIN_MESSAGE_MAP(CDialogColorPicker, CDialog)
493         //{{AFX_MSG_MAP(CDialogColorPicker)
494         ON_WM_LBUTTONDOWN()
495         ON_WM_LBUTTONUP()
496         ON_WM_MOUSEMOVE()
497         ON_WM_SYSCOLORCHANGE()
498         ON_WM_PAINT()
499         ON_EN_CHANGE(IDC_EDIT_BLUE, OnChangeEditBlue)
500         ON_EN_CHANGE(IDC_EDIT_GREEN, OnChangeEditGreen)
501         ON_EN_CHANGE(IDC_EDIT_HUE, OnChangeEditHue)
502         ON_EN_CHANGE(IDC_EDIT_RED, OnChangeEditRed)
503         ON_EN_CHANGE(IDC_EDIT_SAT, OnChangeEditSat)
504         ON_EN_CHANGE(IDC_EDIT_VAL, OnChangeEditVal)
505         ON_EN_CHANGE(IDC_EDIT_OVERBRIGHT, OnChangeEditOverbright)
506         ON_BN_CLICKED(IDC_BTN_OLDCOLOR, OnBtnColor)
507         ON_WM_TIMER()
508         //}}AFX_MSG_MAP
509 END_MESSAGE_MAP()
510
511 /////////////////////////////////////////////////////////////////////////////
512 // CDialogColorPicker message handlers
513
514 void CDialogColorPicker::OnLButtonDown(UINT nFlags, CPoint point) {
515         if(hsbRect.PtInRect(point)) {
516                 m_bInMouse = FALSE;
517                 if(InCircle(point)) {
518                         m_nMouseIn = IN_CIRCLE;
519                 } else if (InBright(point)) {
520                         m_nMouseIn = IN_BRIGHT;
521                 } else if (InOverBright(point)) {
522                         m_nMouseIn = IN_OVERBRIGHT;
523                 } else {
524                         m_nMouseIn = IN_NOTHING;
525                 }
526
527                 if(m_nMouseIn) {
528                         SetCapture();
529                         TrackPoint(point);
530                 }
531         }
532         else if (rgbRect.PtInRect(point)) {
533                 m_nMouseIn = IN_NOTHING;
534                 if(rects[RED].PtInRect(point)) {
535                         SetCapture();
536                         m_bInMouse = TRUE;
537                         nIndex = RED;
538                 } else if (rects[GREEN].PtInRect(point)) {
539                         SetCapture();
540                         m_bInMouse = TRUE;
541                         nIndex = GREEN;
542                 } else if (rects[BLUE].PtInRect(point)) {
543                         SetCapture();
544                         m_bInMouse = TRUE;
545                         nIndex = BLUE;
546                 }
547         }
548         
549         CDialog::OnLButtonDown(nFlags, point);
550 }
551
552 void CDialogColorPicker::OnLButtonUp(UINT nFlags, CPoint point) 
553 {
554         if(GetCapture() == this)
555         {
556                 ReleaseCapture();
557                 m_bInMouse = FALSE;
558         }
559         CDialog::OnLButtonUp(nFlags, point);
560 }
561
562 void CDialogColorPicker::OnMouseMove(UINT nFlags, CPoint point) 
563 {
564         if(GetCapture() == this && m_nMouseIn)
565         {
566                 TrackPoint(point);
567         }
568         else if(GetCapture() == this && m_bInMouse)
569         {
570                 double val;
571                 BOOL bChange = FALSE;
572
573                 if(nIndex == RED)
574                 {
575                         if(point.y > Vertex.y)
576                         {
577                                 point.y = Vertex.y;
578                         }
579                         point.x = Vertex.x;
580                         val = Distance(point,Vertex);
581                         if(val > RedLen)
582                         {
583                                 val = RedLen;
584                         }
585                         CClientDC dc(this);
586                         DrawLines(&dc);
587                         val = (val/RedLen)*255;
588                         color.r = (int)val;
589                         CPoint pt;
590                         pt = PointOnLine(Vertex,Top,(color.r*RedLen)/255,RedLen);
591                         rects[RED] = CRect(pt.x - RECT_WIDTH ,pt.y-RECT_WIDTH ,pt.x+RECT_WIDTH ,pt.y+RECT_WIDTH );
592                         CalcCuboid();
593                         DrawLines(&dc);
594                         bChange = TRUE;
595                 }
596                 else if(nIndex == GREEN)
597                 {
598                         if(point.x > Vertex.x)
599                         {
600                                 point.x = Vertex.x;
601                         }
602                         point.y = rects[GREEN].top + RECT_WIDTH;
603                         val = Distance(point,Vertex);
604                         if(val > GreenLen)
605                         {
606                                 val = GreenLen;
607                         }
608                         CClientDC dc(this);
609                         DrawLines(&dc);
610                         val = (val/GreenLen)*255;
611                         color.g = (int)val;
612                         CPoint pt;
613                         pt = PointOnLine(Vertex,Left,(color.g*GreenLen)/255,GreenLen);
614                         rects[GREEN] = CRect(pt.x - RECT_WIDTH ,pt.y-RECT_WIDTH ,pt.x+RECT_WIDTH ,pt.y+RECT_WIDTH );
615                         CalcCuboid();
616                         DrawLines(&dc);
617                         bChange = TRUE;
618                 }
619                 else if(nIndex == BLUE)
620                 {
621                         if(point.x < Vertex.x)
622                         {
623                                 point.x = Vertex.x;
624                         }
625                         point.y = rects[BLUE].top + RECT_WIDTH;
626                         val = Distance(point,Vertex);
627                         if(val > BlueLen)
628                         {
629                                 val = BlueLen;
630                         }
631                         CClientDC dc(this);
632                         DrawLines(&dc);
633                         val = (val/BlueLen)*255;
634                         color.b = (int)val;
635                         CPoint pt;
636                         pt = PointOnLine(Vertex,Right,(color.b*GreenLen)/255,BlueLen);
637                         rects[BLUE] = CRect(pt.x - RECT_WIDTH ,pt.y-RECT_WIDTH ,pt.x+RECT_WIDTH ,pt.y+RECT_WIDTH );
638                         CalcCuboid();
639                         DrawLines(&dc);
640                         bChange = TRUE;
641                 }
642                 if(bChange)
643                 {
644                         hsvColor = color.toHSV();
645                         SetEditVals();
646                         CClientDC dc(this);
647                         DrawMarkers(&dc);
648                         CalcRects();
649                         SetDIBPalette();
650
651                         InvalidateRect(&brightRect,FALSE);
652                         DrawHSB(&dc);
653                 }
654         }
655         CDialog::OnMouseMove(nFlags, point);
656 }
657
658 void CDialogColorPicker::OnPaint() 
659 {
660         CPaintDC dc(this); // device context for painting
661
662         DrawHSB(&dc);
663         DrawRGB(&dc);
664 }
665
666 BOOL CDialogColorPicker::OnInitDialog() 
667 {
668         CDialog::OnInitDialog();
669         
670         GetDlgItem(IDC_STATIC_RGB_RECT)->GetWindowRect(&rgbRect);
671         GetDlgItem(IDC_STATIC_HSB_RECT)->GetWindowRect(&hsbRect);
672         ScreenToClient(&rgbRect);
673         ScreenToClient(&hsbRect);
674
675         GetDlgItem(IDC_STATIC_NEWCOLOR)->GetWindowRect(&NewColorRect);
676         ScreenToClient(&NewColorRect);
677
678         
679         CWindowDC dc(NULL);
680         CSize bmSize;
681
682         //      Set Up HSB
683         
684         memDC.CreateCompatibleDC(&dc);
685
686         LoadMappedBitmap(m_HsbBitmap,IDB_BITMAP_HSB,bmSize);
687         hsbWidth = bmSize.cx;
688         hsbHeight = bmSize.cy;
689
690         hsbRect.InflateRect(-5,-5);
691         hsbRect.top += 20;
692         hsbRect.left += 10;
693
694         m_Centre = CPoint(RADIUS,RADIUS);
695         m_Centre += CPoint(hsbRect.left,hsbRect.top);
696
697         brightRect = CRect(hsbRect.left+hsbWidth+20,hsbRect.top,hsbRect.left+hsbWidth+20+20,hsbRect.top + hsbHeight);
698         overBrightRect = brightRect;
699         overBrightRect.OffsetRect(brightRect.Width() + 5, 0);
700
701         CreateBrightDIB();
702         CalcRects();
703         SetDIBPalette();
704
705
706         //      Set Up RGB
707
708         LoadMappedBitmap(m_RgbBitmap,IDB_BITMAP_RGB,bmSize);
709         rgbWidth = bmSize.cx;
710         rgbHeight = bmSize.cy;
711
712         rgbRect.InflateRect(-5,-5);
713         rgbRect.top+=10;
714         rgbRect.left-=3;
715
716         CPoint pt = CPoint(rgbRect.left,rgbRect.top);
717
718         Top += pt;
719         Left += pt;
720         Right += pt;
721         Vertex += pt;
722         // TODO: Add your specialized code here and/or call the base class
723
724         RedLen = Distance(Vertex,Top);
725         GreenLen = Distance(Vertex,Left);
726         BlueLen = Distance(Vertex,Right);
727
728         CalcSlopes();
729         CalcCuboid();
730
731         SetSpinVals();
732         SetEditVals();
733
734         m_bInitOver = TRUE;
735
736         SetTimer(0, 50, NULL);
737
738         return TRUE;  // return TRUE unless you set the focus to a control
739                       // EXCEPTION: OCX Property Pages should return FALSE
740 }
741
742 void CDialogColorPicker::DrawMarkers(CDC *pDC)
743 {
744         if(m_CurrentRect.Width())
745         {
746                 CPen *oldPen;
747                 CBrush *oldBrush;
748                 int oldMode;
749                 CRect cr = m_CurrentRect;
750
751                 oldPen = (CPen *)pDC->SelectStockObject(WHITE_PEN);
752                 oldBrush = (CBrush *)pDC->SelectStockObject(NULL_BRUSH);
753
754                 oldMode = pDC->SetROP2(R2_XORPEN);
755
756                 pDC->Rectangle(&cr);
757                 CPen pen;
758                 pen.CreatePen(PS_SOLID,2,RGB(255,255,255));
759                 pDC->SelectObject(&pen);
760                 pDC->Rectangle(&brightMark);
761
762                 pDC->SelectObject(oldPen);
763                 pDC->SelectObject(oldBrush);
764                 pDC->SetROP2(oldMode);
765                 pen.DeleteObject();
766         }
767 }
768
769 BOOL CDialogColorPicker::InCircle(CPoint pt)
770 {
771         return Distance(pt,m_Centre) <= RADIUS;
772 }
773
774 BOOL CDialogColorPicker::InBright(CPoint pt)
775 {
776         return brightRect.PtInRect(pt);
777 }
778
779 BOOL CDialogColorPicker::InOverBright(CPoint pt)
780 {
781         return overBrightRect.PtInRect(pt);
782 }
783
784 void CDialogColorPicker::TrackPoint(CPoint pt)
785 {
786         if(m_nMouseIn == IN_CIRCLE)
787         {
788                 CClientDC dc(this);
789
790                 DrawMarkers(&dc);
791                 
792                 hsvColor.h = (int)RAD2DEG(AngleFromPoint(pt,m_Centre));
793                 if(hsvColor.h < 0)
794                 {
795                         hsvColor.h += 360;
796                 }
797                 hsvColor.s = (int)SCALETOMAX(Distance(pt,m_Centre));
798                 if(hsvColor.s > 255) hsvColor.s = 255;
799
800                 SetDIBPalette();
801                 CalcRects();
802
803
804                 InvalidateRect(&brightRect,FALSE);
805
806                 DrawMarkers(&dc);
807
808                 color = hsvColor.toRGB();
809                 SetEditVals();
810                 DrawLines(&dc);
811                 CalcCuboid();
812                 DrawRGB(&dc);
813
814         }
815         else if(m_nMouseIn == IN_BRIGHT)
816         {
817                 double d;
818                 d = brightRect.bottom - pt.y;
819                 d *= 255;
820                 d /= brightRect.Height();
821                 if(d < 0 ) d = 0;
822                 if(d > 255) d = 255;
823                 CClientDC dc(this);
824                 DrawMarkers(&dc);
825                 hsvColor.v = (int)d;
826                 CalcRects();
827                 DrawMarkers(&dc);
828
829                 color = hsvColor.toRGB();
830                 SetEditVals();
831                 DrawLines(&dc);
832                 CalcCuboid();
833                 DrawRGB(&dc);
834         }
835 }
836
837 void CDialogColorPicker::CreateBrightDIB()
838 {
839         CDIB& d = m_BrightDIB;
840
841         d.Create(brightRect.Width(),brightRect.Height(),8);
842         for(int i=0; i < d.Height(); i++)
843         {
844                 memset(d.GetLinePtr(i),i,d.Width());
845         }
846 }
847
848 void CDialogColorPicker::SetDIBPalette()
849 {
850         BYTE palette[768],*p;
851         HSVType h = hsvColor;
852         double d;
853
854         d = 255.0/brightRect.Height();
855         p = palette;
856         for(int i=brightRect.Height()-1; i >= 0 ;i--,p+=3)
857         {
858                 h.v = (int)((double)i * d);
859                 RGBType rgb = h.toRGB();
860                 p[0] = rgb.r;
861                 p[1] = rgb.g;
862                 p[2] = rgb.b;
863         }
864         m_BrightDIB.SetPalette(palette);
865 }
866
867 void CDialogColorPicker::CalcRects()
868 {
869         CPoint pt;
870
871         pt = PtFromAngle(hsvColor.h,hsvColor.s,m_Centre);
872         m_CurrentRect = CRect(pt.x - RECT_WIDTH,pt.y - RECT_WIDTH,pt.x+RECT_WIDTH,pt.y + RECT_WIDTH);   
873         
874         int y;
875
876         y = (int)(((double)hsvColor.v/255)*brightRect.Height());        
877         y = brightRect.bottom - y;
878         brightMark = CRect(brightRect.left - 2, y - 4, brightRect.right+2,y+4);
879 }
880
881
882 void CDialogColorPicker::DrawHSB(CDC *pDC)
883 {
884         if(m_HsbBitmap.GetSafeHandle())
885         {
886         CBitmap *pOldBitmap ;
887                 pOldBitmap  = (CBitmap *)memDC.SelectObject(&m_HsbBitmap);
888                 pDC->BitBlt(hsbRect.left,hsbRect.top,hsbWidth,hsbHeight,&memDC,0,0,SRCCOPY);
889                 m_BrightDIB.BitBlt(pDC->m_hDC,brightRect.left,brightRect.top,brightRect.Width(),brightRect.Height(),0,0);
890                 DrawMarkers(pDC);
891                 memDC.SelectObject(pOldBitmap);
892         }
893 }
894
895 void CDialogColorPicker::DrawRGB(CDC *pDC)
896 {
897         if(m_RgbBitmap.GetSafeHandle())
898         {
899         CBitmap *pOldBitmap ;
900                 pOldBitmap  = (CBitmap *)memDC.SelectObject(&m_RgbBitmap);
901                 pDC->BitBlt(rgbRect.left,rgbRect.top,rgbWidth,rgbHeight,&memDC,0,0,SRCCOPY);
902                 DrawLines(pDC);
903                 memDC.SelectObject(pOldBitmap);
904         }
905 }
906
907 void CDialogColorPicker::DrawLines(CDC *pDC)
908 {
909         CPoint pt[3];
910
911         pt[0] = PointOnLine(Vertex,Top,(color.r*RedLen)/255,RedLen);
912         pt[1] = PointOnLine(Vertex,Left,(color.g*GreenLen)/255,GreenLen);
913         pt[2] = PointOnLine(Vertex,Right,(color.b*BlueLen)/255,BlueLen);
914
915         COLORREF col = RGB(255,255,255);
916         CRect cr;
917
918         for(int i = 0; i < 3; i++ ) {
919                 cr = CRect(pt[i].x - RECT_WIDTH ,pt[i].y-RECT_WIDTH ,pt[i].x+RECT_WIDTH ,pt[i].y+RECT_WIDTH );
920                 rects[i] = cr;
921                 DrawXorRect(pDC,cr);
922         }
923
924         CPen *oldPen;
925         int oldMode;
926
927         oldPen = (CPen *)pDC->SelectStockObject(WHITE_PEN);
928         oldMode = pDC->SetROP2(R2_XORPEN);
929
930         /*
931         Draw the following lines :
932                 
933                 1 -2 
934                 2 -3
935                 3 - 4
936                 4- 5
937                 5 -2
938                 5 - 6
939                 6-7
940                 7-4
941         */
942         pDC->MoveTo(m_Cuboid[1]);
943         pDC->LineTo(m_Cuboid[2]);
944         pDC->LineTo(m_Cuboid[3]);
945         pDC->LineTo(m_Cuboid[4]);
946         pDC->LineTo(m_Cuboid[5]);
947         pDC->LineTo(m_Cuboid[2]);
948
949         pDC->MoveTo(m_Cuboid[5]);
950         pDC->LineTo(m_Cuboid[6]);
951         pDC->LineTo(m_Cuboid[7]);
952         pDC->LineTo(m_Cuboid[4]);
953         
954         pDC->MoveTo(m_Cuboid[1]);
955         pDC->LineTo(m_Cuboid[6]);
956
957         pDC->SelectObject(oldPen);
958         pDC->SetROP2(oldMode);
959
960         DrawFilledColor(pDC,NewColorRect,color.color());
961 }
962
963 void CDialogColorPicker::DrawXorRect(CDC *pDC,CRect& cr)
964 {
965         CPen pen,*oldPen;
966         CBrush *oldBrush;
967         int oldMode;
968
969         pen.CreatePen(PS_SOLID,1,RGB(255,255,255));
970         oldPen = (CPen *)pDC->SelectObject(&pen);
971         oldBrush = (CBrush *)pDC->SelectStockObject(NULL_BRUSH);
972         oldMode =pDC->SetROP2(R2_XORPEN);
973         pDC->Rectangle(&cr);
974         pDC->SetROP2(oldMode);
975         pDC->SelectObject(oldPen);
976         pDC->SelectObject(oldBrush);
977         pen.DeleteObject();
978
979 }
980
981 void CDialogColorPicker::CalcSlopes()
982 {
983         lines[RED].slope = Slope(Top,Vertex);
984         lines[GREEN].slope = Slope(Left,Vertex);
985         lines[BLUE].slope = Slope(Right,Vertex);
986
987         int i;
988
989         for( i = 0; i < 3; i++ ) {
990                 lines[i].x = Vertex.x;
991                 lines[i].y = Vertex.y;
992                 lines[i].c = FindC(lines[i]);
993         }
994 }
995
996 /*
997
998   Cuboid points
999    0 = vertex
1000    1 = Red Axis
1001    2 = Red Green Intersection
1002    3 = Green Axis
1003    4 = Blue Green Intersection
1004    5 = Blue Green Red Intersection
1005    6 = Red Blue Intersection
1006    7 = Blue Axis
1007
1008   Draw the following lines :
1009         
1010         1 -2 
1011         2 -3
1012         3 - 4
1013         4- 5
1014         5 -2
1015         5 - 6
1016         6-7
1017         7-4
1018 */
1019
1020 void CDialogColorPicker::CalcCuboid()
1021 {
1022         double rLen,gLen,bLen;
1023
1024         rLen = (double)(color.r*RedLen)/255;
1025         gLen = (double)(color.g*GreenLen)/255;
1026         bLen = (double)(color.b*BlueLen)/255;
1027
1028         LineDesc l[12];
1029
1030         m_Cuboid[0] = Vertex;
1031         m_Cuboid[1] = PointOnLine(Vertex,Top,(int)rLen,RedLen);
1032         m_Cuboid[3] = PointOnLine(Vertex,Left,(int)gLen,GreenLen);
1033         m_Cuboid[7] = PointOnLine(Vertex,Right,(int)bLen,BlueLen);
1034
1035         l[0] = lines[RED];
1036         l[1] = lines[GREEN];
1037         l[2] = lines[BLUE];
1038
1039         l[3].slope = lines[GREEN].slope;
1040         l[3].x = m_Cuboid[1].x;
1041         l[3].y = m_Cuboid[1].y;
1042         l[3].c = FindC(l[3]);
1043         
1044         l[4].slope = lines[RED].slope;
1045         l[4].x = m_Cuboid[3].x;
1046         l[4].y = m_Cuboid[3].y;
1047         l[4].c = FindC(l[4]);
1048
1049         l[5].slope = lines[BLUE].slope;
1050         l[5].x = m_Cuboid[3].x;
1051         l[5].y = m_Cuboid[3].y;
1052         l[5].c = FindC(l[5]);
1053         
1054         l[6].slope = lines[GREEN].slope;
1055         l[6].x = m_Cuboid[7].x;
1056         l[6].y = m_Cuboid[7].y;
1057         l[6].c = FindC(l[6]);
1058
1059         l[10].slope = lines[BLUE].slope;
1060         l[10].x = m_Cuboid[1].x;
1061         l[10].y = m_Cuboid[1].y;
1062         l[10].c = FindC(l[10]);
1063         
1064         l[11].slope = lines[RED].slope;
1065         l[11].x = m_Cuboid[7].x;
1066         l[11].y = m_Cuboid[7].y;
1067         l[11].c = FindC(l[11]);
1068
1069         m_Cuboid[2] = Intersection(l[3],l[4]);
1070         m_Cuboid[4] = Intersection(l[5],l[6]);
1071         m_Cuboid[6] = Intersection(l[10],l[11]);
1072
1073         l[7].slope = lines[RED].slope;
1074         l[7].x = m_Cuboid[4].x;
1075         l[7].y = m_Cuboid[4].y;
1076         l[7].c = FindC(l[7]);
1077         
1078         l[8].slope = lines[BLUE].slope;
1079         l[8].x = m_Cuboid[2].x;
1080         l[8].y = m_Cuboid[2].y;
1081         l[8].c = FindC(l[8]);
1082
1083         m_Cuboid[5] = Intersection(l[7],l[8]);
1084                 
1085 }
1086
1087 void CDialogColorPicker::SetSpinVals()
1088 {
1089         ((CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_RED))->SetRange(0,255);
1090         ((CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_GREEN))->SetRange(0,255);
1091         ((CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_BLUE))->SetRange(0,255);
1092
1093         ((CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_HUE))->SetRange(0,360);
1094         ((CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_SAT))->SetRange(0,255);
1095         ((CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_VAL))->SetRange(0,255);
1096
1097         ((CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_OVERBRIGHT))->SetRange(0,1023);
1098
1099 }
1100
1101 void CDialogColorPicker::SetEditVals()
1102 {
1103         ((CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_RED))->SetPos(color.r);
1104         ((CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_GREEN))->SetPos(color.g);
1105         ((CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_BLUE))->SetPos(color.b);
1106
1107         ((CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_HUE))->SetPos(hsvColor.h);
1108         ((CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_SAT))->SetPos(hsvColor.s);
1109         ((CSpinButtonCtrl *)GetDlgItem(IDC_SPIN_VAL))->SetPos(hsvColor.v);
1110
1111 }
1112
1113 void CDialogColorPicker::OnChangeEditBlue() 
1114 {
1115         int b;
1116
1117         b = GetDlgItemInt(IDC_EDIT_BLUE);
1118         if( b != color.b && m_bInitOver)
1119         {
1120                 color.b = b;
1121                 if(color.b < 0) color.b = 0;
1122                 if(color.b > 255) color.b = 255;
1123                 hsvColor = color.toHSV();
1124                 DrawAll();
1125         }
1126 }
1127
1128 void CDialogColorPicker::OnChangeEditGreen() 
1129 {
1130         int g;
1131         
1132         g = GetDlgItemInt(IDC_EDIT_GREEN);
1133         if(g != color.g && m_bInitOver)
1134         {
1135                 color.g = g;
1136                 if(color.g < 0) color.g = 0;
1137                 if(color.g > 255) color.g = 255;
1138                 hsvColor = color.toHSV();
1139                 DrawAll();
1140         }
1141 }
1142
1143 void CDialogColorPicker::OnChangeEditRed() 
1144 {
1145         int r;
1146
1147         r = GetDlgItemInt(IDC_EDIT_RED);
1148         if(r != color.r && m_bInitOver)
1149         {
1150                 color.r = r;
1151                 if(color.r < 0) color.r = 0;
1152                 if(color.r > 255) color.r = 255;
1153                 hsvColor = color.toHSV();
1154                 DrawAll();
1155         }
1156 }
1157
1158 void CDialogColorPicker::OnChangeEditHue() 
1159 {
1160         int h;
1161
1162         h = GetDlgItemInt(IDC_EDIT_HUE);
1163         if(h != hsvColor.h && m_bInitOver)
1164         {
1165                 hsvColor.h = h;
1166                 if(hsvColor.h < 0) hsvColor.h = 0;
1167                 if(hsvColor.h > 359) hsvColor.h = 359;
1168                 color = hsvColor.toRGB();
1169                 DrawAll();
1170         }
1171 }
1172
1173 void CDialogColorPicker::OnChangeEditSat() 
1174 {
1175         int s;
1176
1177         s = GetDlgItemInt(IDC_EDIT_SAT);
1178         if(s != hsvColor.s && m_bInitOver)
1179         {
1180                 hsvColor.s = s;
1181                 if(hsvColor.s < 0) hsvColor.s = 0;
1182                 if(hsvColor.s > 255) hsvColor.s = 255;
1183                 color = hsvColor.toRGB();
1184                 DrawAll();
1185         }
1186 }
1187
1188 void CDialogColorPicker::OnChangeEditVal() 
1189 {
1190         int v;
1191
1192         v = GetDlgItemInt(IDC_EDIT_VAL);
1193         if(v != hsvColor.v && m_bInitOver)
1194         {
1195                 hsvColor.v = v;
1196                 if(hsvColor.v < 0) hsvColor.v = 0;
1197                 if(hsvColor.v > 255) hsvColor.v = 255;
1198                 color = hsvColor.toRGB();
1199                 DrawAll();
1200         }
1201 }
1202
1203 void CDialogColorPicker::OnChangeEditOverbright() {
1204         CString str;
1205         GetDlgItemText(IDC_EDIT_OVERBRIGHT, str);
1206         if(m_bInitOver) {
1207                 overBright = atof(str);
1208         }
1209 }
1210
1211 void CDialogColorPicker::DrawAll()
1212 {
1213         if(m_bInitOver && !m_bInDrawAll)
1214         {
1215                 CClientDC dc(this);
1216
1217                 DrawMarkers(&dc);
1218                 DrawLines(&dc);
1219                 m_bInDrawAll = TRUE;
1220                 CalcCuboid();
1221                 CalcRects();
1222                 SetDIBPalette();
1223                 DrawRGB(&dc);
1224                 DrawHSB(&dc);
1225                 SetEditVals();
1226                 m_bInDrawAll = FALSE;
1227         }
1228 }
1229
1230 void CDialogColorPicker::DrawFilledColor(CDC *pDC,CRect cr,COLORREF c)
1231 {
1232         pDC->FillSolidRect(&cr,c);
1233         pDC->Draw3dRect(&cr,RGB(0,0,0),RGB(0,0,0));
1234         cr.InflateRect(-1,-1);
1235         pDC->Draw3dRect(&cr,RGB(192,192,192),RGB(128,128,128));
1236 }
1237
1238 void CDialogColorPicker::LoadMappedBitmap(CBitmap& bitmap,UINT nIdResource,CSize& size)
1239 {
1240         CBitmap *pOldBitmap;
1241         
1242         if(bitmap.GetSafeHandle()) bitmap.DeleteObject();
1243         
1244         if(bitmap.LoadBitmap(nIdResource))
1245         {
1246
1247                 int width,height;
1248                 BITMAP bmInfo;
1249
1250                 ::GetObject(bitmap.m_hObject,sizeof(bmInfo),&bmInfo);   
1251                 width = bmInfo.bmWidth;
1252                 height = bmInfo.bmHeight;
1253
1254                 COLORREF colorWindow = ::GetSysColor(COLOR_3DFACE);
1255                 COLORREF sourceColor = RGB(192,192,192);
1256
1257                 pOldBitmap = (CBitmap *)memDC.SelectObject(&bitmap);
1258         
1259                 int i,j;
1260                 
1261                 for(i=0; i < height; i++)
1262                 {
1263                         for(j=0; j < width; j++)
1264                         {
1265                                 if(memDC.GetPixel(j,i) == sourceColor)
1266                                 {
1267                                         memDC.SetPixel(j,i,colorWindow);
1268                                 }
1269                         }
1270                 }
1271
1272                 memDC.SelectObject(&pOldBitmap);
1273                 size = CSize(width,height);
1274         }
1275 }
1276
1277 void CDialogColorPicker::OnSysColorChange()
1278 {
1279         CSize size;
1280         LoadMappedBitmap(m_HsbBitmap,IDB_BITMAP_HSB,size);
1281         LoadMappedBitmap(m_RgbBitmap,IDB_BITMAP_RGB,size);
1282 }
1283
1284 void CDialogColorPicker::OnTimer(UINT nIDEvent)  {
1285         if ( UpdateParent ) {
1286                 UpdateParent( color.r, color.g, color.b, 1.0f );
1287         }
1288 }
1289
1290 void CDialogColorPicker::OnBtnColor() {
1291         COLORREF cr = DoOldColor(GetColor());
1292         color.r = GetRValue(cr);
1293         color.g = GetGValue(cr);
1294         color.b = GetBValue(cr);
1295         hsvColor = color.toHSV();
1296         DrawAll();
1297 }
1298
1299 bool DoNewColor( int* i1, int* i2, int* i3, float *overBright, void (*Update)( float, float, float, float ) ) {
1300         COLORREF cr = (*i1) + ((*i2) <<8) + ((*i3) <<16);
1301         CDialogColorPicker dlg( cr );
1302         //CMyColorDialog dlg(cr, CC_FULLOPEN | CC_RGBINIT | CC_ANYCOLOR);
1303
1304         dlg.UpdateParent = Update;
1305
1306         if ( dlg.DoModal() == IDOK ) {
1307                 *i1 = (dlg.GetColor() & 255);
1308                 *i2 = ((dlg.GetColor() >> 8) & 255);
1309                 *i3 = ((dlg.GetColor() >> 16) & 255);
1310                 *overBright = dlg.GetOverBright();
1311                 return true;
1312         }
1313         return false;
1314 }