| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405 |
- #include "StdAfx.h"
- #include <math.h>
- namespace DuiLib {
- #define HSLMAX 255 /* H,L, and S vary over 0-HSLMAX */
- #define RGBMAX 255 /* R,G, and B vary over 0-RGBMAX */
- #define HSLUNDEFINED (HSLMAX*2/3)
- /*
- * Convert hue value to RGB
- */
- static float HueToRGB(float v1, float v2, float vH)
- {
- if (vH < 0.0f) vH += 1.0f;
- if (vH > 1.0f) vH -= 1.0f;
- if ((6.0f * vH) < 1.0f) return (v1 + (v2 - v1) * 6.0f * vH);
- if ((2.0f * vH) < 1.0f) return (v2);
- if ((3.0f * vH) < 2.0f) return (v1 + (v2 - v1) * ((2.0f / 3.0f) - vH) * 6.0f);
- return (v1);
- }
- /*
- * Convert color RGB to HSL
- * pHue HSL hue value [0 - 1]
- * pSat HSL saturation value [0 - 1]
- * pLue HSL luminance value [0 - 1]
- */
- static void RGBToHSL(DWORD clr, float *pHue, float *pSat, float *pLue)
- {
- float R = (float)(GetRValue(clr) / 255.0f); //RGB from 0 to 255
- float G = (float)(GetGValue(clr) / 255.0f);
- float B = (float)(GetBValue(clr) / 255.0f);
- float H = 0, S = 0, L = 0;
- float fMin = min(R, min(G, B)); //Min. value of RGB
- float fMax = max(R, max(G, B)); //Max. value of RGB
- float fDelta = fMax - fMin; //Delta RGB value
- L = (fMax + fMin) / 2.0f;
- if (fDelta == 0) //This is a gray, no chroma...
- {
- H = 0.0f; //HSL results from 0 to 1
- S = 0.0f;
- }
- else //Chromatic data...
- {
- float del_R, del_G, del_B;
- if (L < 0.5) S = fDelta / (fMax + fMin);
- else S = fDelta / (2.0f - fMax - fMin);
- del_R = (((fMax - R) / 6.0f) + (fDelta / 2.0f)) / fDelta;
- del_G = (((fMax - G) / 6.0f) + (fDelta / 2.0f)) / fDelta;
- del_B = (((fMax - B) / 6.0f) + (fDelta / 2.0f)) / fDelta;
- if (R == fMax) H = del_B - del_G;
- else if (G == fMax) H = (1.0f / 3.0f) + del_R - del_B;
- else if (B == fMax) H = (2.0f / 3.0f) + del_G - del_R;
- if (H < 0.0f) H += 1.0f;
- if (H > 1.0f) H -= 1.0f;
- }
- *pHue = H;
- *pSat = S;
- *pLue = L;
- }
- /*
- * Convert color HSL to RGB
- * H HSL hue value [0 - 1]
- * S HSL saturation value [0 - 1]
- * L HSL luminance value [0 - 1]
- */
- static DWORD HSLToRGB(float H, float S, float L)
- {
- BYTE R, G, B;
- float var_1, var_2;
- if (S == 0) //HSL from 0 to 1
- {
- R = G = B = (BYTE)(L * 255.0f); //RGB results from 0 to 255
- }
- else
- {
- if (L < 0.5) var_2 = L * (1.0f + S);
- else var_2 = (L + S) - (S * L);
- var_1 = 2.0f * L - var_2;
- R = (BYTE)(255.0f * HueToRGB(var_1, var_2, H + (1.0f / 3.0f)));
- G = (BYTE)(255.0f * HueToRGB(var_1, var_2, H));
- B = (BYTE)(255.0f * HueToRGB(var_1, var_2, H - (1.0f / 3.0f)));
- }
- return RGB(R, G, B);
- }
- /*
- * _HSLToRGB color HSL value to RGB
- * clr RGB color value
- * nHue HSL hue value [0 - 360]
- * nSat HSL saturation value [0 - 200]
- * nLue HSL luminance value [0 - 200]
- */
- #define _HSLToRGB(h,s,l) (0xFF << 24 | HSLToRGB((float)h / 360.0f,(float)s / 200.0f,l / 200.0f))
- ///////////////////////////////////////////////////////////////////////
- //
- //
- IMPLEMENT_DUICONTROL(CColorPaletteUI)
- CColorPaletteUI::CColorPaletteUI()
- : m_uButtonState(0)
- , m_bIsInBar(false)
- , m_bIsInPallet(false)
- , m_nCurH(180)
- , m_nCurS(200)
- , m_nCurB(100)
- , m_nPalletHeight(200)
- , m_nBarHeight(10)
- , m_pBits(NULL)
- {
- memset(&m_bmInfo, 0, sizeof(m_bmInfo));
-
- m_hMemBitmap=NULL;
- }
- CColorPaletteUI::~CColorPaletteUI()
- {
- if (m_pBits) free(m_pBits);
- if (m_hMemBitmap) {
- ::DeleteObject(m_hMemBitmap);
- }
- }
- DWORD CColorPaletteUI::GetSelectColor()
- {
- DWORD dwColor = _HSLToRGB(m_nCurH, m_nCurS, m_nCurB);
- return 0xFF << 24 | GetRValue(dwColor) << 16 | GetGValue(dwColor) << 8 | GetBValue(dwColor);
- }
- void CColorPaletteUI::SetSelectColor(DWORD dwColor)
- {
- float H = 0, S = 0, B = 0;
- COLORREF dwBkClr = RGB(GetBValue(dwColor),GetGValue(dwColor),GetRValue(dwColor));
- RGBToHSL(dwBkClr, &H, &S, &B);
- m_nCurH = (int)(H*360);
- m_nCurS = (int)(S*200);
- m_nCurB = (int)(B*200);
- UpdatePalletData();
- NeedUpdate();
- }
- LPCTSTR CColorPaletteUI::GetClass() const
- {
- return _T("ColorPaletteUI");
- }
- LPVOID CColorPaletteUI::GetInterface(LPCTSTR pstrName)
- {
- if (_tcscmp(pstrName, DUI_CTR_COLORPALETTE) == 0) return static_cast<CColorPaletteUI*>(this);
- return CControlUI::GetInterface(pstrName);
- }
- void CColorPaletteUI::SetPalletHeight(int nHeight)
- {
- m_nPalletHeight = nHeight;
- }
- int CColorPaletteUI::GetPalletHeight() const
- {
- return m_nPalletHeight;
- }
- void CColorPaletteUI::SetBarHeight(int nHeight)
- {
- if (nHeight>150) {
- nHeight = 150; //限制最大高度,由于当前设计,nheight超出190,程序会因越界访问崩溃
- }
- m_nBarHeight = nHeight;
- }
- int CColorPaletteUI::GetBarHeight() const
- {
- return m_nBarHeight;
- }
- void CColorPaletteUI::SetThumbImage(LPCTSTR pszImage)
- {
- if (m_strThumbImage != pszImage)
- {
- m_strThumbImage = pszImage;
- NeedUpdate();
- }
- }
- LPCTSTR CColorPaletteUI::GetThumbImage() const
- {
- return m_strThumbImage.GetData();
- }
- void CColorPaletteUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue)
- {
- if (_tcscmp(pstrName, _T("palletheight")) == 0) SetPalletHeight(_ttoi(pstrValue));
- else if (_tcscmp(pstrName, _T("barheight")) == 0) SetBarHeight(_ttoi(pstrValue));
- else if (_tcscmp(pstrName, _T("thumbimage")) == 0) SetThumbImage(pstrValue);
- else CControlUI::SetAttribute(pstrName, pstrValue);
- }
- void CColorPaletteUI::DoInit()
- {
- m_MemDc = CreateCompatibleDC(GetManager()->GetPaintDC());
- m_hMemBitmap = CreateCompatibleBitmap(GetManager()->GetPaintDC(), 400, 360);
- SelectObject(m_MemDc, m_hMemBitmap);
- ::GetObject(m_hMemBitmap, sizeof(m_bmInfo), &m_bmInfo);
- DWORD dwSize = m_bmInfo.bmHeight * m_bmInfo.bmWidthBytes;
- m_pBits = (BYTE *)malloc(dwSize);
- ::GetBitmapBits(m_hMemBitmap, dwSize, m_pBits);
- }
- void CColorPaletteUI::SetPos(RECT rc, bool bNeedInvalidate)
- {
- CControlUI::SetPos(rc, bNeedInvalidate);
- m_ptLastPalletMouse.x = m_nCurH * (m_rcItem.right - m_rcItem.left) / 360 + m_rcItem.left;
- m_ptLastPalletMouse.y = (200 - m_nCurB) * m_nPalletHeight / 200 + m_rcItem.top;
- UpdatePalletData();
- UpdateBarData();
- }
- void CColorPaletteUI::DoEvent(TEventUI& event)
- {
- CControlUI::DoEvent(event);
- if (event.Type == UIEVENT_BUTTONDOWN)
- {
- if (event.ptMouse.x >= m_rcItem.left && event.ptMouse.y >= m_rcItem.top &&
- event.ptMouse.x < m_rcItem.right && event.ptMouse.y < m_rcItem.top + m_nPalletHeight)
- {
- int x = (event.ptMouse.x - m_rcItem.left) * 360 / (m_rcItem.right - m_rcItem.left);
- int y = (event.ptMouse.y - m_rcItem.top) * 200 / m_nPalletHeight;
- x = min(max(x, 0), 360);
- y = min(max(y, 0), 200);
- m_ptLastPalletMouse = event.ptMouse;
- if (m_ptLastPalletMouse.x < m_rcItem.left) m_ptLastPalletMouse.x = m_rcItem.left;
- if (m_ptLastPalletMouse.x > m_rcItem.right) m_ptLastPalletMouse.x = m_rcItem.right;
- if (m_ptLastPalletMouse.y < m_rcItem.top) m_ptLastPalletMouse.y = m_rcItem.top;
- if (m_ptLastPalletMouse.y > m_rcItem.top + m_nPalletHeight) m_ptLastPalletMouse.y = m_rcItem.top + m_nPalletHeight;
- m_nCurH = x;
- m_nCurB = 200 - y;
- m_uButtonState |= UISTATE_PUSHED;
- m_bIsInPallet = true;
- m_bIsInBar = false;
- UpdateBarData();
- }
- if (event.ptMouse.x >= m_rcItem.left && event.ptMouse.y >= m_rcItem.bottom - m_nBarHeight &&
- event.ptMouse.x < m_rcItem.right && event.ptMouse.y < m_rcItem.bottom)
- {
- m_nCurS = (event.ptMouse.x - m_rcItem.left) * 200 / (m_rcItem.right - m_rcItem.left);
- m_uButtonState |= UISTATE_PUSHED;
- m_bIsInBar = true;
- m_bIsInPallet = false;
- UpdatePalletData();
- }
- Invalidate();
- return;
- }
- if (event.Type == UIEVENT_BUTTONUP)
- {
- DWORD color=0;
- if ((m_uButtonState | UISTATE_PUSHED) && (IsEnabled()))
- {
- color = GetSelectColor();
- m_pManager->SendNotify(this, DUI_MSGTYPE_COLORCHANGED, color, 0);
- }
- m_uButtonState &= ~UISTATE_PUSHED;
- m_bIsInPallet = false;
- m_bIsInBar = false;
- Invalidate();
- return;
- }
- if (event.Type == UIEVENT_MOUSEMOVE)
- {
- if (!(m_uButtonState &UISTATE_PUSHED))
- {
- m_bIsInBar = false;
- m_bIsInPallet = false;
- }
- if (m_bIsInPallet == true)
- {
- POINT pt = event.ptMouse;
- pt.x -= m_rcItem.left;
- pt.y -= m_rcItem.top;
- if (pt.x >= 0 && pt.y >= 0 && pt.x <= m_rcItem.right && pt.y <= m_rcItem.top + m_nPalletHeight)
- {
- int x = pt.x * 360 / (m_rcItem.right - m_rcItem.left);
- int y = pt.y * 200 / m_nPalletHeight;
- x = min(max(x, 0), 360);
- y = min(max(y, 0), 200);
- m_ptLastPalletMouse = event.ptMouse;
- if (m_ptLastPalletMouse.x < m_rcItem.left) m_ptLastPalletMouse.x = m_rcItem.left;
- if (m_ptLastPalletMouse.x > m_rcItem.right) m_ptLastPalletMouse.x = m_rcItem.right;
- if (m_ptLastPalletMouse.y < m_rcItem.top) m_ptLastPalletMouse.y = m_rcItem.top;
- if (m_ptLastPalletMouse.y >= m_rcItem.top + m_nPalletHeight) m_ptLastPalletMouse.y = m_rcItem.top + m_nPalletHeight;
- m_nCurH = x;
- m_nCurB = 200 - y;
- UpdateBarData();
- }
- }
- else if (m_bIsInBar == true)
- {
- m_nCurS = (event.ptMouse.x - m_rcItem.left) * 200 / (m_rcItem.right - m_rcItem.left);
- m_nCurS = min(max(m_nCurS, 0), 200);
- UpdatePalletData();
- }
- Invalidate();
- return;
- }
- }
- void CColorPaletteUI::PaintBkColor(HDC hDC)
- {
- PaintPallet(hDC);
- }
-
- void CColorPaletteUI::PaintPallet(HDC hDC)
- {
- int nSaveDC = ::SaveDC(hDC);
- ::SetStretchBltMode(hDC, HALFTONE);
- //拉伸模式将内存图画到控件上
- StretchBlt(hDC, m_rcItem.left, m_rcItem.top, m_rcItem.right - m_rcItem.left, m_nPalletHeight, m_MemDc, 0, 1, 360, 200, SRCCOPY);
- StretchBlt(hDC, m_rcItem.left, m_rcItem.bottom - m_nBarHeight, m_rcItem.right - m_rcItem.left, m_nBarHeight, m_MemDc, 0, 210, 200, m_nBarHeight, SRCCOPY);
- RECT rcCurSorPaint = { m_ptLastPalletMouse.x - 4, m_ptLastPalletMouse.y - 4, m_ptLastPalletMouse.x + 4, m_ptLastPalletMouse.y + 4 };
- CRenderEngine::DrawImageString(hDC, m_pManager, rcCurSorPaint, m_rcPaint, m_strThumbImage);
- rcCurSorPaint.left = m_rcItem.left + m_nCurS * (m_rcItem.right - m_rcItem.left) / 200 - 4;
- rcCurSorPaint.right = m_rcItem.left + m_nCurS * (m_rcItem.right - m_rcItem.left) / 200 + 4;
- rcCurSorPaint.top = m_rcItem.bottom - m_nBarHeight / 2 - 4;
- rcCurSorPaint.bottom = m_rcItem.bottom - m_nBarHeight / 2 + 4;
- CRenderEngine::DrawImageString(hDC, m_pManager, rcCurSorPaint, m_rcPaint, m_strThumbImage);
- ::RestoreDC(hDC, nSaveDC);
- }
- void CColorPaletteUI::UpdatePalletData()
- {
- int x, y;
- BYTE *pPiexl;
- DWORD dwColor;
- for (y = 0; y < 200; ++y) {
- for (x = 0; x < 360; ++x) {
- pPiexl = LPBYTE(m_pBits) + ((200 - y)*m_bmInfo.bmWidthBytes) + ((x*m_bmInfo.bmBitsPixel) / 8);
- dwColor = _HSLToRGB(x, m_nCurS, y);
- if(dwColor == 0xFF000000) dwColor = 0xFF000001;
- pPiexl[0] = GetBValue(dwColor);
- pPiexl[1] = GetGValue(dwColor);
- pPiexl[2] = GetRValue(dwColor);
- }
- }
- SetBitmapBits(m_hMemBitmap, m_bmInfo.bmWidthBytes * m_bmInfo.bmHeight, m_pBits);
- }
- void CColorPaletteUI::UpdateBarData()
- {
- int x, y;
- BYTE *pPiexl;
- DWORD dwColor;
- //这里画出Bar
- for (y = 0; y < m_nBarHeight; ++y) {
- for (x = 0; x < 200; ++x) {
- pPiexl = LPBYTE(m_pBits) + ((210 + y)*m_bmInfo.bmWidthBytes) + ((x*m_bmInfo.bmBitsPixel) / 8);
- dwColor = _HSLToRGB(m_nCurH, x, m_nCurB);
- if(dwColor == 0xFF000000) dwColor = 0xFF000001;
- pPiexl[0] = GetBValue(dwColor);
- pPiexl[1] = GetGValue(dwColor);
- pPiexl[2] = GetRValue(dwColor);
- }
- }
- SetBitmapBits(m_hMemBitmap, m_bmInfo.bmWidthBytes * m_bmInfo.bmHeight, m_pBits);
- }
- }
|