1 // Copyright 2001-2018 Crytek GmbH / Crytek Group. All rights reserved.
4 #include "ColorGradientCtrl.h"
6 #include "Dialogs/CustomColorDialog.h"
7 #include "WndGridHelper.h"
8 #include "Util/MFCUtil.h"
10 IMPLEMENT_DYNAMIC(CColorGradientCtrl
, CWnd
)
12 #define MIN_TIME_EPSILON 0.01f
14 //////////////////////////////////////////////////////////////////////////
15 CColorGradientCtrl::CColorGradientCtrl()
17 m_bAutoDelete
= false;
29 m_bLockFirstLastKey
= false;
34 m_bSelectedKeys
.reserve(0);
41 CColorGradientCtrl::~CColorGradientCtrl()
45 //////////////////////////////////////////////////////////////////////////
46 BEGIN_MESSAGE_MAP(CColorGradientCtrl
, CWnd
)
61 /////////////////////////////////////////////////////////////////////////////
62 // CColorGradientCtrl message handlers
64 /////////////////////////////////////////////////////////////////////////////
65 BOOL
CColorGradientCtrl::Create(DWORD dwStyle
, const CRect
& rc
, CWnd
* pParentWnd
, UINT nID
)
67 if (dwStyle
& CLRGRD_STYLE_AUTO_DELETE
)
69 LPCTSTR lpClassName
= AfxRegisterWndClass(CS_DBLCLKS
| CS_HREDRAW
| CS_VREDRAW
, AfxGetApp()->LoadStandardCursor(IDC_ARROW
), NULL
, NULL
);
70 return CreateEx(0, lpClassName
, "SplineCtrl", dwStyle
, rc
, pParentWnd
, nID
);
73 //////////////////////////////////////////////////////////////////////////
74 void CColorGradientCtrl::PostNcDestroy()
80 //////////////////////////////////////////////////////////////////////////
81 BOOL
CColorGradientCtrl::OnEraseBkgnd(CDC
* pDC
)
86 //////////////////////////////////////////////////////////////////////////
87 void CColorGradientCtrl::OnSize(UINT nType
, int cx
, int cy
)
89 __super::OnSize(nType
, cx
, cy
);
91 m_offscreenBitmap
.DeleteObject();
92 if (!m_offscreenBitmap
.GetSafeHandle())
95 m_offscreenBitmap
.CreateCompatibleBitmap(pDC
, cx
, cy
);
102 m_rcGradient
.bottom
-= 11;
103 //m_rcGradient.DeflateRect(4,4);
105 m_grid
.rect
= m_rcGradient
;
107 m_grid
.zoom
.x
= m_grid
.rect
.Width();
110 m_rcKeys
.top
= m_rcKeys
.bottom
- 10;
112 if (m_tooltip
.m_hWnd
)
114 m_tooltip
.DelTool(this, 1);
115 m_tooltip
.AddTool(this, "", m_rcGradient
, 1);
119 //////////////////////////////////////////////////////////////////////////
120 BOOL
CColorGradientCtrl::PreTranslateMessage(MSG
* pMsg
)
122 if (!m_tooltip
.m_hWnd
)
126 m_tooltip
.Create(this);
127 m_tooltip
.SetDelayTime(TTDT_AUTOPOP
, 500);
128 m_tooltip
.SetDelayTime(TTDT_INITIAL
, 0);
129 m_tooltip
.SetDelayTime(TTDT_RESHOW
, 0);
130 m_tooltip
.SetMaxTipWidth(600);
131 m_tooltip
.AddTool(this, "", rc
, 1);
132 m_tooltip
.Activate(FALSE
);
134 m_tooltip
.RelayEvent(pMsg
);
136 return __super::PreTranslateMessage(pMsg
);
139 //////////////////////////////////////////////////////////////////////////
140 void CColorGradientCtrl::SetZoom(float fZoom
)
142 m_grid
.zoom
.x
= fZoom
;
145 //////////////////////////////////////////////////////////////////////////
146 void CColorGradientCtrl::SetOrigin(float fOffset
)
148 m_grid
.origin
.x
= fOffset
;
151 //////////////////////////////////////////////////////////////////////////
152 CPoint
CColorGradientCtrl::KeyToPoint(int nKey
)
156 return TimeToPoint(m_pSpline
->GetKeyTime(nKey
));
161 //////////////////////////////////////////////////////////////////////////
162 CPoint
CColorGradientCtrl::TimeToPoint(float time
)
164 return CPoint(m_grid
.WorldToClient(Vec2(time
, 0)).x
, m_rcGradient
.Height() / 2);
167 point
.x
= (time
- m_fMinTime
) * (m_rcGradient
.Width() / (m_fMaxTime
- m_fMinTime
)) + m_rcGradient
.left
;
168 point
.y
= m_rcGradient
.Height() / 2;
172 //////////////////////////////////////////////////////////////////////////
173 COLORREF
CColorGradientCtrl::TimeToColor(float time
)
175 ISplineInterpolator::ValueType val
;
176 m_pSpline
->Interpolate(time
, val
);
177 COLORREF col
= ValueToColor(val
);
181 //////////////////////////////////////////////////////////////////////////
182 void CColorGradientCtrl::PointToTimeValue(CPoint point
, float& time
, ISplineInterpolator::ValueType
& val
)
184 time
= XOfsToTime(point
.x
);
185 ColorToValue(TimeToColor(time
), val
);
188 //////////////////////////////////////////////////////////////////////////
189 float CColorGradientCtrl::XOfsToTime(int x
)
191 return m_grid
.ClientToWorld(CPoint(x
, 0)).x
;
193 // m_fMinTime to m_fMaxTime time range.
194 float time
= m_fMinTime
+ (float)((m_fMaxTime
- m_fMinTime
) * (x
- m_rcGradient
.left
)) / m_rcGradient
.Width();
198 //////////////////////////////////////////////////////////////////////////
199 CPoint
CColorGradientCtrl::XOfsToPoint(int x
)
201 return TimeToPoint(XOfsToTime(x
));
204 //////////////////////////////////////////////////////////////////////////
205 COLORREF
CColorGradientCtrl::XOfsToColor(int x
)
207 return TimeToColor(XOfsToTime(x
));
210 //////////////////////////////////////////////////////////////////////////
211 void CColorGradientCtrl::OnPaint()
213 CPaintDC
PaintDC(this);
216 GetClientRect(&rcClient
);
219 m_bSelectedKeys
.resize(m_pSpline
->GetKeyCount());
221 if (!m_offscreenBitmap
.GetSafeHandle())
222 m_offscreenBitmap
.CreateCompatibleBitmap(&PaintDC
, rcClient
.Width(), rcClient
.Height());
224 CMemoryDC
dc(PaintDC
, &m_offscreenBitmap
);
226 if (!IsWindowEnabled())
230 rc
.IntersectRect(rc
, CRect(PaintDC
.m_ps
.rcPaint
));
232 keysBrush
.CreateSolidBrush(GetXtremeColor(COLOR_BTNFACE
));
233 dc
.FillRect(rc
, &keysBrush
);
237 //////////////////////////////////////////////////////////////////////////
238 // Fill keys backgound.
239 //////////////////////////////////////////////////////////////////////////
241 rcKeys
.IntersectRect(m_rcKeys
, CRect(PaintDC
.m_ps
.rcPaint
));
243 keysBrush
.CreateSolidBrush(GetXtremeColor(COLOR_BTNFACE
));
244 dc
.FillRect(rcKeys
, &keysBrush
);
245 //////////////////////////////////////////////////////////////////////////
247 //Draw Keys and Curve
256 //////////////////////////////////////////////////////////////////////////
257 void CColorGradientCtrl::DrawGradient(CDC
* pDC
)
259 int cx
= m_rcGradient
.Width();
260 int cy
= m_rcGradient
.Height();
263 // create and select a thick, white pen
265 pen
.CreatePen(PS_SOLID
, 1, RGB(128, 255, 128));
266 CPen
* pOldPen
= pDC
->SelectObject(&pen
);
269 pDC
->GetClipBox(rcClip
);
270 rcClip
.IntersectRect(rcClip
, m_rcGradient
);
272 for (int x
= rcClip
.left
; x
< rcClip
.right
; x
++)
274 COLORREF col
= XOfsToColor(x
);
276 pen
.CreatePen(PS_SOLID
, 1, col
);
277 pDC
->SelectObject(&pen
);
278 pDC
->MoveTo(CPoint(x
, m_rcGradient
.top
));
279 pDC
->LineTo(CPoint(x
, m_rcGradient
.bottom
));
282 // Put back the old objects
283 pDC
->SelectObject(pOldPen
);
286 //////////////////////////////////////////////////////////////////////////
287 void CColorGradientCtrl::DrawKeys(CDC
* pDC
)
292 // create and select a white pen
294 pen
.CreatePen(PS_SOLID
, 1, RGB(0, 0, 0));
295 CPen
* pOldPen
= pDC
->SelectObject(&pen
);
298 pDC
->GetClipBox(rcClip
);
300 m_bSelectedKeys
.resize(m_pSpline
->GetKeyCount());
302 for (int i
= 0; i
< m_pSpline
->GetKeyCount(); i
++)
304 float time
= m_pSpline
->GetKeyTime(i
);
305 CPoint pt
= TimeToPoint(time
);
307 if (pt
.x
< rcClip
.left
- 8 || pt
.x
> rcClip
.right
+ 8)
310 COLORREF clr
= TimeToColor(time
);
312 CBrush
* pOldBrush
= pDC
->SelectObject(&brush
);
314 // Find the midpoints of the top, right, left, and bottom
315 // of the client area. They will be the vertices of our polygon.
318 pts
[0].y
= m_rcKeys
.top
+ 1;
320 pts
[1].y
= m_rcKeys
.top
+ 8;
322 pts
[2].y
= m_rcKeys
.top
+ 8;
323 pDC
->Polygon(pts
, 3);
325 if (m_bSelectedKeys
[i
])
328 pen
.CreatePen(PS_SOLID
, 1, RGB(200, 0, 0));
329 CPen
* pOldPen
= pDC
->SelectObject(&pen
);
330 pDC
->Polygon(pts
, 3);
331 pDC
->SelectObject(pOldPen
);
334 pDC
->SelectObject(pOldBrush
);
338 timePen
.CreatePen(PS_SOLID
, 1, RGB(255, 0, 255));
339 if (!(GetStyle() & CLRGRD_STYLE_NO_TIME_MARKER
))
341 pDC
->SelectObject(&timePen
);
342 CPoint pt
= TimeToPoint(m_fTimeMarker
);
343 pDC
->MoveTo(pt
.x
, m_rcGradient
.top
+ 1);
344 pDC
->LineTo(pt
.x
, m_rcGradient
.bottom
- 1);
347 pDC
->SelectObject(pOldPen
);
350 void CColorGradientCtrl::UpdateTooltip()
352 if (m_nHitKeyIndex
>= 0)
354 float time
= m_pSpline
->GetKeyTime(m_nHitKeyIndex
);
355 ISplineInterpolator::ValueType val
;
356 m_pSpline
->GetKeyValue(m_nHitKeyIndex
, val
);
358 COLORREF col
= TimeToColor(time
);
359 int cont_s
= (m_pSpline
->GetKeyFlags(m_nHitKeyIndex
) >> SPLINE_KEY_TANGENT_IN_SHIFT
) & SPLINE_KEY_TANGENT_LINEAR
? 1 : 2;
360 int cont_d
= (m_pSpline
->GetKeyFlags(m_nHitKeyIndex
) >> SPLINE_KEY_TANGENT_OUT_SHIFT
) & SPLINE_KEY_TANGENT_LINEAR
? 1 : 2;
363 tipText
.Format("%.2f : %d,%d,%d [%d,%d]",
364 time
* m_fTooltipScaleX
, GetRValue(col
), GetGValue(col
), GetBValue(col
), cont_s
, cont_d
);
365 m_tooltip
.UpdateTipText(tipText
, this, 1);
366 m_tooltip
.Activate(TRUE
);
370 /////////////////////////////////////////////////////////////////////////////
371 //Mouse Message Handlers
372 //////////////////////////////////////////////////////////////////////////
373 void CColorGradientCtrl::OnLButtonDown(UINT nFlags
, CPoint point
)
375 CWnd::OnLButtonDown(nFlags
, point
);
388 SetActiveKey(m_nHitKeyIndex
);
394 // Cycle the spline slope of the nearest key.
395 int flags = m_pSpline->GetKeyFlags(m_nHitKeyIndex);
396 if (m_nHitKeyDist < 0)
398 flags ^= SPLINE_KEY_TANGENT_LINEAR << SPLINE_KEY_TANGENT_IN_SHIFT;
399 if (m_nHitKeyDist > 0)
400 // Toggle right side.
401 flags ^= SPLINE_KEY_TANGENT_LINEAR << SPLINE_KEY_TANGENT_OUT_SHIFT;
402 m_pSpline->SetKeyFlags(m_nHitKeyIndex, flags);
406 SendNotifyEvent( CLRGRDN_CHANGE );
407 if (m_updateCallback)
408 m_updateCallback(this);
420 //////////////////////////////////////////////////////////////////////////
421 void CColorGradientCtrl::OnRButtonDown(UINT nFlags
, CPoint point
)
423 CWnd::OnRButtonDown(nFlags
, point
);
426 nmh
.hwndFrom
= m_hWnd
;
427 nmh
.idFrom
= ::GetDlgCtrlID(m_hWnd
);
428 nmh
.code
= NM_RCLICK
;
430 GetOwner()->SendMessage(WM_NOTIFY
, (WPARAM
)GetDlgCtrlID(), (LPARAM
)&nmh
);
433 //////////////////////////////////////////////////////////////////////////
434 void CColorGradientCtrl::OnLButtonDblClk(UINT nFlags
, CPoint point
)
446 int iIndex
= InsertKey(point
);
447 SetActiveKey(iIndex
);
455 EditKey(m_nHitKeyIndex
);
460 CWnd::OnLButtonDblClk(nFlags
, point
);
463 //////////////////////////////////////////////////////////////////////////
464 void CColorGradientCtrl::OnMouseMove(UINT nFlags
, CPoint point
)
469 if (GetCapture() != this)
478 CWnd::OnMouseMove(nFlags
, point
);
481 //////////////////////////////////////////////////////////////////////////
482 void CColorGradientCtrl::OnLButtonUp(UINT nFlags
, CPoint point
)
490 CWnd::OnLButtonUp(nFlags
, point
);
493 //////////////////////////////////////////////////////////////////////////
494 void CColorGradientCtrl::OnRButtonUp(UINT nFlags
, CPoint point
)
498 CWnd::OnRButtonUp(nFlags
, point
);
501 /////////////////////////////////////////////////////////////////////////////
502 void CColorGradientCtrl::SetActiveKey(int nIndex
)
509 m_bSelectedKeys
[nIndex
] = true;
511 m_nActiveKey
= nIndex
;
515 /////////////////////////////////////////////////////////////////////////////
516 void CColorGradientCtrl::SetSpline(ISplineInterpolator
* pSpline
, BOOL bRedraw
)
518 if (pSpline
!= m_pSpline
)
520 //if (pSpline && pSpline->GetNumDimensions() != 3)
532 //////////////////////////////////////////////////////////////////////////
533 ISplineInterpolator
* CColorGradientCtrl::GetSpline()
538 /////////////////////////////////////////////////////////////////////////////
539 BOOL
CColorGradientCtrl::OnSetCursor(CWnd
* pWnd
, UINT nHitTest
, UINT message
)
544 GetCursorPos(&point
);
545 ScreenToClient(&point
);
547 switch (HitTest(point
))
552 hCursor
= AfxGetApp()->LoadCursor(IDC_ARRWHITE
);
559 hCursor
= AfxGetApp()->LoadCursor(IDC_ARRBLCK
);
567 if (m_tooltip
.m_hWnd
&& m_pSpline
)
569 if (m_nHitKeyIndex
>= 0)
573 else if (!m_bTracking
)
575 m_tooltip
.Activate(FALSE
);
580 return CWnd::OnSetCursor(pWnd
, nHitTest
, message
);
584 /////////////////////////////////////////////////////////////////////////////
585 void CColorGradientCtrl::OnKeyDown(UINT nChar
, UINT nRepCnt
, UINT nFlags
)
587 BOOL bProcessed
= false;
589 if (m_nActiveKey
!= -1 && m_pSpline
)
595 RemoveKey(m_nActiveKey
);
600 CUndo
undo("Move Spline Key");
601 CPoint point
= KeyToPoint(m_nActiveKey
);
603 SendNotifyEvent(CLRGRDN_BEFORE_CHANGE
);
609 CUndo
undo("Move Spline Key");
610 CPoint point
= KeyToPoint(m_nActiveKey
);
612 SendNotifyEvent(CLRGRDN_BEFORE_CHANGE
);
618 CUndo
undo("Move Spline Key");
619 CPoint point
= KeyToPoint(m_nActiveKey
);
621 SendNotifyEvent(CLRGRDN_BEFORE_CHANGE
);
627 CUndo
undo("Move Spline Key");
628 CPoint point
= KeyToPoint(m_nActiveKey
);
630 SendNotifyEvent(CLRGRDN_BEFORE_CHANGE
);
643 CWnd::OnKeyDown(nChar
, nRepCnt
, nFlags
);
646 //////////////////////////////////////////////////////////////////////////////
647 CColorGradientCtrl::EHitCode
CColorGradientCtrl::HitTest(CPoint point
)
652 ISplineInterpolator::ValueType val
;
654 PointToTimeValue(point
, time
, val
);
656 CPoint splinePt
= TimeToPoint(time
);
658 //bool bSplineHit = abs(splinePt.x-point.x) < 4 && abs(splinePt.y-point.y) < 4;
665 if (rc
.PtInRect(point
))
667 m_nHitKeyDist
= 0xFFFF;
668 m_hitCode
= HIT_SPLINE
;
670 for (int i
= 0; i
< m_pSpline
->GetKeyCount(); i
++)
672 CPoint splinePt
= TimeToPoint(m_pSpline
->GetKeyTime(i
));
673 if (abs(point
.x
- splinePt
.x
) < abs(m_nHitKeyDist
))
676 m_nHitKeyDist
= point
.x
- splinePt
.x
;
679 if (abs(m_nHitKeyDist
) < 4)
683 m_hitCode
= HIT_NOTHING
;
688 ///////////////////////////////////////////////////////////////////////////////
689 void CColorGradientCtrl::StartTracking()
694 GetIEditor()->GetIUndoManager()->Begin();
695 SendNotifyEvent(CLRGRDN_BEFORE_CHANGE
);
698 hCursor
= AfxGetApp()->LoadCursor(IDC_ARRBLCKCROSS
);
703 //////////////////////////////////////////////////////////////////////////
704 void CColorGradientCtrl::TrackKey(CPoint point
)
706 if (point
.x
< m_rcGradient
.left
|| point
.y
> m_rcGradient
.right
)
709 int nKey
= m_nHitKeyIndex
;
713 ISplineInterpolator::ValueType val
;
715 PointToTimeValue(point
, time
, val
);
717 // Clamp to min/max time.
718 if (time
< m_fMinTime
|| time
> m_fMaxTime
)
722 for (i
= 0; i
< m_pSpline
->GetKeyCount(); i
++)
724 // Switch to next key.
725 if (fabs(m_pSpline
->GetKeyTime(i
) - time
) < MIN_TIME_EPSILON
)
732 if (!m_bLockFirstLastKey
|| (nKey
!= 0 && nKey
!= m_pSpline
->GetKeyCount() - 1))
734 m_pSpline
->SetKeyTime(nKey
, time
);
738 SendNotifyEvent(CLRGRDN_CHANGE
);
739 if (m_updateCallback
)
740 m_updateCallback(this);
746 //////////////////////////////////////////////////////////////////////////
747 void CColorGradientCtrl::StopTracking()
752 GetIEditor()->GetIUndoManager()->Accept("Spline Move");
754 if (m_nHitKeyIndex
>= 0)
757 GetCursorPos(&point
);
758 ScreenToClient(&point
);
762 rc
.InflateRect(100, 100);
763 if (!rc
.PtInRect(point
))
765 RemoveKey(m_nHitKeyIndex
);
773 //////////////////////////////////////////////////////////////////////////
774 void CColorGradientCtrl::EditKey(int nKey
)
779 if (nKey
< 0 || nKey
>= m_pSpline
->GetKeyCount())
784 ISplineInterpolator::ValueType val
;
785 m_pSpline
->GetKeyValue(nKey
, val
);
787 SendNotifyEvent(CLRGRDN_BEFORE_CHANGE
);
789 CCustomColorDialog
dlg(ValueToColor(val
));
790 dlg
.SetColorChangeCallback(functor(*this, &CColorGradientCtrl::OnKeyColorChanged
));
791 if (dlg
.DoModal() == IDOK
)
793 CUndo
undo("Modify Gradient Color");
794 OnKeyColorChanged(dlg
.GetColor());
798 OnKeyColorChanged(ValueToColor(val
));
802 //////////////////////////////////////////////////////////////////////////
803 void CColorGradientCtrl::OnKeyColorChanged(COLORREF color
)
805 int nKey
= m_nActiveKey
;
808 if (nKey
< 0 || nKey
>= m_pSpline
->GetKeyCount())
811 ISplineInterpolator::ValueType val
;
812 ColorToValue(color
, val
);
813 m_pSpline
->SetKeyValue(nKey
, val
);
816 if (m_bLockFirstLastKey
)
819 m_pSpline
->SetKeyValue(m_pSpline
->GetKeyCount() - 1, val
);
820 else if (nKey
== m_pSpline
->GetKeyCount() - 1)
821 m_pSpline
->SetKeyValue(0, val
);
824 SendNotifyEvent(CLRGRDN_CHANGE
);
825 if (m_updateCallback
)
826 m_updateCallback(this);
828 GetIEditor()->UpdateViews(eRedrawViewports
);
831 //////////////////////////////////////////////////////////////////////////
832 void CColorGradientCtrl::RemoveKey(int nKey
)
836 if (m_bLockFirstLastKey
)
838 if (nKey
== 0 || nKey
== m_pSpline
->GetKeyCount() - 1)
842 CUndo
undo("Remove Spline Key");
844 SendNotifyEvent(CLRGRDN_BEFORE_CHANGE
);
849 m_pSpline
->RemoveKey(nKey
);
852 SendNotifyEvent(CLRGRDN_CHANGE
);
853 if (m_updateCallback
)
854 m_updateCallback(this);
859 //////////////////////////////////////////////////////////////////////////
860 int CColorGradientCtrl::InsertKey(CPoint point
)
862 CUndo
undo("Spline Insert Key");
864 ISplineInterpolator::ValueType val
;
867 PointToTimeValue(point
, time
, val
);
869 if (time
< m_fMinTime
|| time
> m_fMaxTime
)
873 for (i
= 0; i
< m_pSpline
->GetKeyCount(); i
++)
875 // Skip if any key already have time that is very close.
876 if (fabs(m_pSpline
->GetKeyTime(i
) - time
) < MIN_TIME_EPSILON
)
880 SendNotifyEvent(CLRGRDN_BEFORE_CHANGE
);
882 m_pSpline
->InsertKey(time
, val
);
883 m_pSpline
->Interpolate(time
, val
);
887 SendNotifyEvent(CLRGRDN_CHANGE
);
888 if (m_updateCallback
)
889 m_updateCallback(this);
891 for (i
= 0; i
< m_pSpline
->GetKeyCount(); i
++)
893 // Find key with added time.
894 if (m_pSpline
->GetKeyTime(i
) == time
)
901 //////////////////////////////////////////////////////////////////////////
902 void CColorGradientCtrl::ClearSelection()
906 m_bSelectedKeys
.resize(m_pSpline
->GetKeyCount());
907 for (int i
= 0; i
< (int)m_bSelectedKeys
.size(); i
++)
908 m_bSelectedKeys
[i
] = false;
911 //////////////////////////////////////////////////////////////////////////
912 void CColorGradientCtrl::SetTimeMarker(float fTime
)
918 CPoint pt
= TimeToPoint(m_fTimeMarker
);
919 CRect rc
= CRect(pt
.x
, m_rcGradient
.top
, pt
.x
, m_rcGradient
.bottom
);
921 rc
.InflateRect(1, 0);
925 CPoint pt
= TimeToPoint(fTime
);
926 CRect rc
= CRect(pt
.x
, m_rcGradient
.top
, pt
.x
, m_rcGradient
.bottom
);
928 rc
.InflateRect(1, 0);
931 m_fTimeMarker
= fTime
;
934 //////////////////////////////////////////////////////////////////////////
935 void CColorGradientCtrl::SendNotifyEvent(int nEvent
)
938 nmh
.hwndFrom
= m_hWnd
;
939 nmh
.idFrom
= ::GetDlgCtrlID(m_hWnd
);
942 GetOwner()->SendMessage(WM_NOTIFY
, (WPARAM
)GetDlgCtrlID(), (LPARAM
)&nmh
);
945 //////////////////////////////////////////////////////////////////////////
946 COLORREF
CColorGradientCtrl::ValueToColor(ISplineInterpolator::ValueType val
)
948 return CMFCUtils::ColorLinearToGamma(ColorF(val
[0], val
[1], val
[2]));
951 //////////////////////////////////////////////////////////////////////////
952 void CColorGradientCtrl::ColorToValue(COLORREF col
, ISplineInterpolator::ValueType
& val
)
954 ColorF colLin
= CMFCUtils::ColorGammaToLinear(col
);