// This is a part of the GWC Library
// Copyright (C) 2001-2002 Aircom software
// All rights reserved.
//
// This source code can be used, distributed or modified
// free of charge only if this header copyright is not removed.
// In other cases, contact us at:
// web: http://www.aircom.org
// email: info@aircom.org
//
#include "stdafx.h"
#include "GWCGradientColorWnd.h"
#include "GWCColorComponentEditCtrl.h"
#include "GWCColorComponentSet.h"
#include "GWCColorFunc.h"
#include "memdc.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define WINDOW_WIDTH 262 // 262 = 256 colors + 3 pixels each side for the 3D border
//==================================================================
// Description:
// Constructs a new GWCGradientColorWnd instance.
//
// Parameters:
// pComp - A pointer to the component control that owns this window.
//==================================================================
GWCGradientColorWnd::GWCGradientColorWnd(GWCColorComponentEditCtrl* pComp) : m_comp(pComp)
{
}
//========================================================================
// Description:
// Creates the handle of this popup window.
//
// Parameters:
// dwStyle - The window style to apply to this window. Should be WS_POPUP.
// pParentWnd - A pointer to the parent window.
// nID - The child ID of this window.
//
// Returns:
// TRUE if successfull, FALSE otherwise.
//========================================================================
BOOL GWCGradientColorWnd::Create(DWORD dwStyle, CWnd* pParentWnd, UINT nID)
{
return CWnd::CreateEx(0,AfxRegisterWndClass(CS_CLASSDC), NULL, dwStyle, CRect(0,0,WINDOW_WIDTH,20), pParentWnd, nID);
}
BEGIN_MESSAGE_MAP(GWCGradientColorWnd, CWnd)
//{{AFX_MSG_MAP(GWCGradientColorWnd)
ON_WM_ERASEBKGND()
ON_WM_PAINT()
ON_WM_NCPAINT()
ON_WM_NCCALCSIZE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
//===============================================================
// Description:
// Called before OnPaint to erase the background of this control.
//
// Parameters:
// pDC - A pointer to the device context used for drawing.
//
// Returns:
// TRUE so that the parent won't paint the background.
//===============================================================
BOOL GWCGradientColorWnd::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
}
//===============================================
// Description:
// Called by the framework to paint this control.
//===============================================
void GWCGradientColorWnd::OnPaint()
{
// Create a memory DC for a non flickering draw
CPaintDC paintDC(this);
CMemDC dc(&paintDC);
// Draw the gradient bar
CRect rect;
GetClientRect(&rect);
COLORREF color = m_comp->GetOwnerSet()->GetColor();
int type = m_comp->GetType();
if (type == GWCColorComponentEditCtrl::RED)
{
for(int i=0;i<256;i++)
{
CPen pen(PS_SOLID,1,RGB(i,GetGValue(color),GetBValue(color)));
CPen* oldPen = dc.SelectObject(&pen);
dc.MoveTo(i,0);
dc.LineTo(i,14);
dc.SelectObject(oldPen);
}
}
else if (type == GWCColorComponentEditCtrl::GREEN)
{
for(int i=0;i<256;i++)
{
CPen pen(PS_SOLID,1,RGB(GetRValue(color),i,GetBValue(color)));
CPen* oldPen = dc.SelectObject(&pen);
dc.MoveTo(i,0);
dc.LineTo(i,14);
dc.SelectObject(oldPen);
}
}
else if (type == GWCColorComponentEditCtrl::BLUE)
{
for(int i=0;i<256;i++)
{
CPen pen(PS_SOLID,1,RGB(GetRValue(color),GetGValue(color),i));
CPen* oldPen = dc.SelectObject(&pen);
dc.MoveTo(i,0);
dc.LineTo(i,14);
dc.SelectObject(oldPen);
}
}
else if (type == GWCColorComponentEditCtrl::HUE)
{
BYTE hue,sat,light;
m_comp->GetOwnerSet()->GetColor(&hue,&sat,&light);
for(int i=0;i<256;i++)
{
CPen pen(PS_SOLID,1,GWCColorFunc::HSLtoRGB((double)i/255.0,(double)sat/255.,(double)light/255.));
CPen* oldPen = dc.SelectObject(&pen);
dc.MoveTo(i,0);
dc.LineTo(i,14);
dc.SelectObject(oldPen);
}
}
else if (type == GWCColorComponentEditCtrl::SAT)
{
BYTE hue,sat,light;
m_comp->GetOwnerSet()->GetColor(&hue,&sat,&light);
for(int i=0;i<256;i++)
{
CPen pen(PS_SOLID,1,GWCColorFunc::HSLtoRGB((double)hue/255.,(double)i/255.0,(double)light/255.));
CPen* oldPen = dc.SelectObject(&pen);
dc.MoveTo(i,0);
dc.LineTo(i,14);
dc.SelectObject(oldPen);
}
}
else if (type == GWCColorComponentEditCtrl::LIGHT)
{
BYTE hue,sat,light;
m_comp->GetOwnerSet()->GetColor(&hue,&sat,&light);
for(int i=0;i<256;i++)
{
CPen pen(PS_SOLID,1,GWCColorFunc::HSLtoRGB((double)hue/255.,(double)sat/255.,(double)i/255.0));
CPen* oldPen = dc.SelectObject(&pen);
dc.MoveTo(i,0);
dc.LineTo(i,14);
dc.SelectObject(oldPen);
}
}
// Draw a mark for the current value
BYTE hue,sat,light;
m_comp->GetOwnerSet()->GetColor(&hue,&sat,&light);
double dHue = (double)hue/255. + 0.5;
if (dHue > 1.0) dHue -= 1.0;
COLORREF markColor = GWCColorFunc::HSLtoRGB(dHue,1.0,0.5);
CPen pen(PS_SOLID,1,markColor);
CPen* oldPen = dc.SelectObject(&pen);
BYTE value = m_comp->GetValue();
dc.MoveTo(value,0);
dc.LineTo(value,14);
dc.MoveTo(value-1,0);
dc.LineTo(value-1,14);
dc.MoveTo(value+1,0);
dc.LineTo(value+1,14);
dc.SelectObject(oldPen);
}
//===========================================================
// Description:
// Called by the framework to draw the border of this window.
//===========================================================
void GWCGradientColorWnd::OnNcPaint()
{
// Draw a 3D border
CWindowDC dc(this);
CRect rect;
GetWindowRect(&rect);
int w = rect.Width();
int h = rect.Height();
CPen lightPen(PS_SOLID,1,::GetSysColor(COLOR_BTNFACE));
CPen darkPen(PS_SOLID,1,::GetSysColor(COLOR_BTNSHADOW));
CPen* oldPen = dc.SelectObject(&lightPen);
dc.MoveTo(0, h-2);
dc.LineTo(0, 0);
dc.LineTo(w, 0);
dc.MoveTo(2, h-3);
dc.LineTo(2, 2);
dc.LineTo(w-3, 2);
dc.LineTo(w-3, h-3);
dc.LineTo(2, h-3);
dc.SelectStockObject(WHITE_PEN);
dc.MoveTo(1, h-2);
dc.LineTo(1, 1);
dc.LineTo(w-1, 1);
dc.SelectStockObject(BLACK_PEN);
dc.MoveTo(0, h-1);
dc.LineTo(w-1, h-1);
dc.LineTo(w-1, -1);
dc.SelectObject(&darkPen);
dc.MoveTo(1, h-2);
dc.LineTo(w-2, h-2);
dc.LineTo(w-2, 0);
dc.SelectObject(oldPen);
}
//========================================================================
// Description:
// Called bu the framework to calculates the rectangle of the client area.
//
// Parameters:
// bCalcValidRects - Not used.
// lpncsp - Contains the rectangle of the client area.
//========================================================================
void GWCGradientColorWnd::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp)
{
// 3 pixels are removed from each side for the 3D effect
lpncsp->rgrc[0].left += 3;
lpncsp->rgrc[0].top += 3;
lpncsp->rgrc[0].right -= 3;
lpncsp->rgrc[0].bottom -= 3;
CWnd::OnNcCalcSize(bCalcValidRects, lpncsp);
}
//=====================================================================================
// Description:
// Shows the popup window
//
// Parameters:
// point - x contains the x position of the mouse, y contains the top side of the popup
// window.
//=====================================================================================
void GWCGradientColorWnd::Show(CPoint point)
{
int value = m_comp->GetValue();
// Get the screen rectangle
CRect rect;
::SystemParametersInfo(SPI_GETWORKAREA,0,&rect,0);
// Check if the bar is not beyond the right side of the screen
int posx = point.x-value-3;
if (posx + WINDOW_WIDTH > rect.right)
{
int deltax = point.x - posx;
posx = rect.right - WINDOW_WIDTH;
CPoint mousePos;
::GetCursorPos(&mousePos);
::SetCursorPos(posx+deltax,mousePos.y);
}
// Check if the bar is not beyond the left side of the screen
else if (posx < 0)
{
int deltax = point.x - posx;
posx = 0;
CPoint mousePos;
::GetCursorPos(&mousePos);
::SetCursorPos(posx+deltax,mousePos.y);
}
SetWindowPos(NULL,posx,point.y,0,0,SWP_NOSIZE|SWP_NOZORDER|SWP_SHOWWINDOW|SWP_NOACTIVATE);
}