UIColorPalette.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  1. #include "StdAfx.h"
  2. #include <math.h>
  3. namespace DuiLib {
  4. #define HSLMAX 255 /* H,L, and S vary over 0-HSLMAX */
  5. #define RGBMAX 255 /* R,G, and B vary over 0-RGBMAX */
  6. #define HSLUNDEFINED (HSLMAX*2/3)
  7. /*
  8. * Convert hue value to RGB
  9. */
  10. static float HueToRGB(float v1, float v2, float vH)
  11. {
  12. if (vH < 0.0f) vH += 1.0f;
  13. if (vH > 1.0f) vH -= 1.0f;
  14. if ((6.0f * vH) < 1.0f) return (v1 + (v2 - v1) * 6.0f * vH);
  15. if ((2.0f * vH) < 1.0f) return (v2);
  16. if ((3.0f * vH) < 2.0f) return (v1 + (v2 - v1) * ((2.0f / 3.0f) - vH) * 6.0f);
  17. return (v1);
  18. }
  19. /*
  20. * Convert color RGB to HSL
  21. * pHue HSL hue value [0 - 1]
  22. * pSat HSL saturation value [0 - 1]
  23. * pLue HSL luminance value [0 - 1]
  24. */
  25. static void RGBToHSL(DWORD clr, float *pHue, float *pSat, float *pLue)
  26. {
  27. float R = (float)(GetRValue(clr) / 255.0f); //RGB from 0 to 255
  28. float G = (float)(GetGValue(clr) / 255.0f);
  29. float B = (float)(GetBValue(clr) / 255.0f);
  30. float H = 0, S = 0, L = 0;
  31. float fMin = min(R, min(G, B)); //Min. value of RGB
  32. float fMax = max(R, max(G, B)); //Max. value of RGB
  33. float fDelta = fMax - fMin; //Delta RGB value
  34. L = (fMax + fMin) / 2.0f;
  35. if (fDelta == 0) //This is a gray, no chroma...
  36. {
  37. H = 0.0f; //HSL results from 0 to 1
  38. S = 0.0f;
  39. }
  40. else //Chromatic data...
  41. {
  42. float del_R, del_G, del_B;
  43. if (L < 0.5) S = fDelta / (fMax + fMin);
  44. else S = fDelta / (2.0f - fMax - fMin);
  45. del_R = (((fMax - R) / 6.0f) + (fDelta / 2.0f)) / fDelta;
  46. del_G = (((fMax - G) / 6.0f) + (fDelta / 2.0f)) / fDelta;
  47. del_B = (((fMax - B) / 6.0f) + (fDelta / 2.0f)) / fDelta;
  48. if (R == fMax) H = del_B - del_G;
  49. else if (G == fMax) H = (1.0f / 3.0f) + del_R - del_B;
  50. else if (B == fMax) H = (2.0f / 3.0f) + del_G - del_R;
  51. if (H < 0.0f) H += 1.0f;
  52. if (H > 1.0f) H -= 1.0f;
  53. }
  54. *pHue = H;
  55. *pSat = S;
  56. *pLue = L;
  57. }
  58. /*
  59. * Convert color HSL to RGB
  60. * H HSL hue value [0 - 1]
  61. * S HSL saturation value [0 - 1]
  62. * L HSL luminance value [0 - 1]
  63. */
  64. static DWORD HSLToRGB(float H, float S, float L)
  65. {
  66. BYTE R, G, B;
  67. float var_1, var_2;
  68. if (S == 0) //HSL from 0 to 1
  69. {
  70. R = G = B = (BYTE)(L * 255.0f); //RGB results from 0 to 255
  71. }
  72. else
  73. {
  74. if (L < 0.5) var_2 = L * (1.0f + S);
  75. else var_2 = (L + S) - (S * L);
  76. var_1 = 2.0f * L - var_2;
  77. R = (BYTE)(255.0f * HueToRGB(var_1, var_2, H + (1.0f / 3.0f)));
  78. G = (BYTE)(255.0f * HueToRGB(var_1, var_2, H));
  79. B = (BYTE)(255.0f * HueToRGB(var_1, var_2, H - (1.0f / 3.0f)));
  80. }
  81. return RGB(R, G, B);
  82. }
  83. /*
  84. * _HSLToRGB color HSL value to RGB
  85. * clr RGB color value
  86. * nHue HSL hue value [0 - 360]
  87. * nSat HSL saturation value [0 - 200]
  88. * nLue HSL luminance value [0 - 200]
  89. */
  90. #define _HSLToRGB(h,s,l) (0xFF << 24 | HSLToRGB((float)h / 360.0f,(float)s / 200.0f,l / 200.0f))
  91. ///////////////////////////////////////////////////////////////////////
  92. //
  93. //
  94. IMPLEMENT_DUICONTROL(CColorPaletteUI)
  95. CColorPaletteUI::CColorPaletteUI()
  96. : m_uButtonState(0)
  97. , m_bIsInBar(false)
  98. , m_bIsInPallet(false)
  99. , m_nCurH(180)
  100. , m_nCurS(200)
  101. , m_nCurB(100)
  102. , m_nPalletHeight(200)
  103. , m_nBarHeight(10)
  104. , m_pBits(NULL)
  105. {
  106. memset(&m_bmInfo, 0, sizeof(m_bmInfo));
  107. m_hMemBitmap=NULL;
  108. }
  109. CColorPaletteUI::~CColorPaletteUI()
  110. {
  111. if (m_pBits) free(m_pBits);
  112. if (m_hMemBitmap) {
  113. ::DeleteObject(m_hMemBitmap);
  114. }
  115. }
  116. DWORD CColorPaletteUI::GetSelectColor()
  117. {
  118. DWORD dwColor = _HSLToRGB(m_nCurH, m_nCurS, m_nCurB);
  119. return 0xFF << 24 | GetRValue(dwColor) << 16 | GetGValue(dwColor) << 8 | GetBValue(dwColor);
  120. }
  121. void CColorPaletteUI::SetSelectColor(DWORD dwColor)
  122. {
  123. float H = 0, S = 0, B = 0;
  124. COLORREF dwBkClr = RGB(GetBValue(dwColor),GetGValue(dwColor),GetRValue(dwColor));
  125. RGBToHSL(dwBkClr, &H, &S, &B);
  126. m_nCurH = (int)(H*360);
  127. m_nCurS = (int)(S*200);
  128. m_nCurB = (int)(B*200);
  129. UpdatePalletData();
  130. NeedUpdate();
  131. }
  132. LPCTSTR CColorPaletteUI::GetClass() const
  133. {
  134. return _T("ColorPaletteUI");
  135. }
  136. LPVOID CColorPaletteUI::GetInterface(LPCTSTR pstrName)
  137. {
  138. if (_tcscmp(pstrName, DUI_CTR_COLORPALETTE) == 0) return static_cast<CColorPaletteUI*>(this);
  139. return CControlUI::GetInterface(pstrName);
  140. }
  141. void CColorPaletteUI::SetPalletHeight(int nHeight)
  142. {
  143. m_nPalletHeight = nHeight;
  144. }
  145. int CColorPaletteUI::GetPalletHeight() const
  146. {
  147. return m_nPalletHeight;
  148. }
  149. void CColorPaletteUI::SetBarHeight(int nHeight)
  150. {
  151. if (nHeight>150) {
  152. nHeight = 150; //限制最大高度,由于当前设计,nheight超出190,程序会因越界访问崩溃
  153. }
  154. m_nBarHeight = nHeight;
  155. }
  156. int CColorPaletteUI::GetBarHeight() const
  157. {
  158. return m_nBarHeight;
  159. }
  160. void CColorPaletteUI::SetThumbImage(LPCTSTR pszImage)
  161. {
  162. if (m_strThumbImage != pszImage)
  163. {
  164. m_strThumbImage = pszImage;
  165. NeedUpdate();
  166. }
  167. }
  168. LPCTSTR CColorPaletteUI::GetThumbImage() const
  169. {
  170. return m_strThumbImage.GetData();
  171. }
  172. void CColorPaletteUI::SetAttribute(LPCTSTR pstrName, LPCTSTR pstrValue)
  173. {
  174. if (_tcscmp(pstrName, _T("palletheight")) == 0) SetPalletHeight(_ttoi(pstrValue));
  175. else if (_tcscmp(pstrName, _T("barheight")) == 0) SetBarHeight(_ttoi(pstrValue));
  176. else if (_tcscmp(pstrName, _T("thumbimage")) == 0) SetThumbImage(pstrValue);
  177. else CControlUI::SetAttribute(pstrName, pstrValue);
  178. }
  179. void CColorPaletteUI::DoInit()
  180. {
  181. m_MemDc = CreateCompatibleDC(GetManager()->GetPaintDC());
  182. m_hMemBitmap = CreateCompatibleBitmap(GetManager()->GetPaintDC(), 400, 360);
  183. SelectObject(m_MemDc, m_hMemBitmap);
  184. ::GetObject(m_hMemBitmap, sizeof(m_bmInfo), &m_bmInfo);
  185. DWORD dwSize = m_bmInfo.bmHeight * m_bmInfo.bmWidthBytes;
  186. m_pBits = (BYTE *)malloc(dwSize);
  187. ::GetBitmapBits(m_hMemBitmap, dwSize, m_pBits);
  188. }
  189. void CColorPaletteUI::SetPos(RECT rc, bool bNeedInvalidate)
  190. {
  191. CControlUI::SetPos(rc, bNeedInvalidate);
  192. m_ptLastPalletMouse.x = m_nCurH * (m_rcItem.right - m_rcItem.left) / 360 + m_rcItem.left;
  193. m_ptLastPalletMouse.y = (200 - m_nCurB) * m_nPalletHeight / 200 + m_rcItem.top;
  194. UpdatePalletData();
  195. UpdateBarData();
  196. }
  197. void CColorPaletteUI::DoEvent(TEventUI& event)
  198. {
  199. CControlUI::DoEvent(event);
  200. if (event.Type == UIEVENT_BUTTONDOWN)
  201. {
  202. if (event.ptMouse.x >= m_rcItem.left && event.ptMouse.y >= m_rcItem.top &&
  203. event.ptMouse.x < m_rcItem.right && event.ptMouse.y < m_rcItem.top + m_nPalletHeight)
  204. {
  205. int x = (event.ptMouse.x - m_rcItem.left) * 360 / (m_rcItem.right - m_rcItem.left);
  206. int y = (event.ptMouse.y - m_rcItem.top) * 200 / m_nPalletHeight;
  207. x = min(max(x, 0), 360);
  208. y = min(max(y, 0), 200);
  209. m_ptLastPalletMouse = event.ptMouse;
  210. if (m_ptLastPalletMouse.x < m_rcItem.left) m_ptLastPalletMouse.x = m_rcItem.left;
  211. if (m_ptLastPalletMouse.x > m_rcItem.right) m_ptLastPalletMouse.x = m_rcItem.right;
  212. if (m_ptLastPalletMouse.y < m_rcItem.top) m_ptLastPalletMouse.y = m_rcItem.top;
  213. if (m_ptLastPalletMouse.y > m_rcItem.top + m_nPalletHeight) m_ptLastPalletMouse.y = m_rcItem.top + m_nPalletHeight;
  214. m_nCurH = x;
  215. m_nCurB = 200 - y;
  216. m_uButtonState |= UISTATE_PUSHED;
  217. m_bIsInPallet = true;
  218. m_bIsInBar = false;
  219. UpdateBarData();
  220. }
  221. if (event.ptMouse.x >= m_rcItem.left && event.ptMouse.y >= m_rcItem.bottom - m_nBarHeight &&
  222. event.ptMouse.x < m_rcItem.right && event.ptMouse.y < m_rcItem.bottom)
  223. {
  224. m_nCurS = (event.ptMouse.x - m_rcItem.left) * 200 / (m_rcItem.right - m_rcItem.left);
  225. m_uButtonState |= UISTATE_PUSHED;
  226. m_bIsInBar = true;
  227. m_bIsInPallet = false;
  228. UpdatePalletData();
  229. }
  230. Invalidate();
  231. return;
  232. }
  233. if (event.Type == UIEVENT_BUTTONUP)
  234. {
  235. DWORD color=0;
  236. if ((m_uButtonState | UISTATE_PUSHED) && (IsEnabled()))
  237. {
  238. color = GetSelectColor();
  239. m_pManager->SendNotify(this, DUI_MSGTYPE_COLORCHANGED, color, 0);
  240. }
  241. m_uButtonState &= ~UISTATE_PUSHED;
  242. m_bIsInPallet = false;
  243. m_bIsInBar = false;
  244. Invalidate();
  245. return;
  246. }
  247. if (event.Type == UIEVENT_MOUSEMOVE)
  248. {
  249. if (!(m_uButtonState &UISTATE_PUSHED))
  250. {
  251. m_bIsInBar = false;
  252. m_bIsInPallet = false;
  253. }
  254. if (m_bIsInPallet == true)
  255. {
  256. POINT pt = event.ptMouse;
  257. pt.x -= m_rcItem.left;
  258. pt.y -= m_rcItem.top;
  259. if (pt.x >= 0 && pt.y >= 0 && pt.x <= m_rcItem.right && pt.y <= m_rcItem.top + m_nPalletHeight)
  260. {
  261. int x = pt.x * 360 / (m_rcItem.right - m_rcItem.left);
  262. int y = pt.y * 200 / m_nPalletHeight;
  263. x = min(max(x, 0), 360);
  264. y = min(max(y, 0), 200);
  265. m_ptLastPalletMouse = event.ptMouse;
  266. if (m_ptLastPalletMouse.x < m_rcItem.left) m_ptLastPalletMouse.x = m_rcItem.left;
  267. if (m_ptLastPalletMouse.x > m_rcItem.right) m_ptLastPalletMouse.x = m_rcItem.right;
  268. if (m_ptLastPalletMouse.y < m_rcItem.top) m_ptLastPalletMouse.y = m_rcItem.top;
  269. if (m_ptLastPalletMouse.y >= m_rcItem.top + m_nPalletHeight) m_ptLastPalletMouse.y = m_rcItem.top + m_nPalletHeight;
  270. m_nCurH = x;
  271. m_nCurB = 200 - y;
  272. UpdateBarData();
  273. }
  274. }
  275. else if (m_bIsInBar == true)
  276. {
  277. m_nCurS = (event.ptMouse.x - m_rcItem.left) * 200 / (m_rcItem.right - m_rcItem.left);
  278. m_nCurS = min(max(m_nCurS, 0), 200);
  279. UpdatePalletData();
  280. }
  281. Invalidate();
  282. return;
  283. }
  284. }
  285. void CColorPaletteUI::PaintBkColor(HDC hDC)
  286. {
  287. PaintPallet(hDC);
  288. }
  289. void CColorPaletteUI::PaintPallet(HDC hDC)
  290. {
  291. int nSaveDC = ::SaveDC(hDC);
  292. ::SetStretchBltMode(hDC, HALFTONE);
  293. //拉伸模式将内存图画到控件上
  294. StretchBlt(hDC, m_rcItem.left, m_rcItem.top, m_rcItem.right - m_rcItem.left, m_nPalletHeight, m_MemDc, 0, 1, 360, 200, SRCCOPY);
  295. 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);
  296. RECT rcCurSorPaint = { m_ptLastPalletMouse.x - 4, m_ptLastPalletMouse.y - 4, m_ptLastPalletMouse.x + 4, m_ptLastPalletMouse.y + 4 };
  297. CRenderEngine::DrawImageString(hDC, m_pManager, rcCurSorPaint, m_rcPaint, m_strThumbImage);
  298. rcCurSorPaint.left = m_rcItem.left + m_nCurS * (m_rcItem.right - m_rcItem.left) / 200 - 4;
  299. rcCurSorPaint.right = m_rcItem.left + m_nCurS * (m_rcItem.right - m_rcItem.left) / 200 + 4;
  300. rcCurSorPaint.top = m_rcItem.bottom - m_nBarHeight / 2 - 4;
  301. rcCurSorPaint.bottom = m_rcItem.bottom - m_nBarHeight / 2 + 4;
  302. CRenderEngine::DrawImageString(hDC, m_pManager, rcCurSorPaint, m_rcPaint, m_strThumbImage);
  303. ::RestoreDC(hDC, nSaveDC);
  304. }
  305. void CColorPaletteUI::UpdatePalletData()
  306. {
  307. int x, y;
  308. BYTE *pPiexl;
  309. DWORD dwColor;
  310. for (y = 0; y < 200; ++y) {
  311. for (x = 0; x < 360; ++x) {
  312. pPiexl = LPBYTE(m_pBits) + ((200 - y)*m_bmInfo.bmWidthBytes) + ((x*m_bmInfo.bmBitsPixel) / 8);
  313. dwColor = _HSLToRGB(x, m_nCurS, y);
  314. if(dwColor == 0xFF000000) dwColor = 0xFF000001;
  315. pPiexl[0] = GetBValue(dwColor);
  316. pPiexl[1] = GetGValue(dwColor);
  317. pPiexl[2] = GetRValue(dwColor);
  318. }
  319. }
  320. SetBitmapBits(m_hMemBitmap, m_bmInfo.bmWidthBytes * m_bmInfo.bmHeight, m_pBits);
  321. }
  322. void CColorPaletteUI::UpdateBarData()
  323. {
  324. int x, y;
  325. BYTE *pPiexl;
  326. DWORD dwColor;
  327. //这里画出Bar
  328. for (y = 0; y < m_nBarHeight; ++y) {
  329. for (x = 0; x < 200; ++x) {
  330. pPiexl = LPBYTE(m_pBits) + ((210 + y)*m_bmInfo.bmWidthBytes) + ((x*m_bmInfo.bmBitsPixel) / 8);
  331. dwColor = _HSLToRGB(m_nCurH, x, m_nCurB);
  332. if(dwColor == 0xFF000000) dwColor = 0xFF000001;
  333. pPiexl[0] = GetBValue(dwColor);
  334. pPiexl[1] = GetGValue(dwColor);
  335. pPiexl[2] = GetRValue(dwColor);
  336. }
  337. }
  338. SetBitmapBits(m_hMemBitmap, m_bmInfo.bmWidthBytes * m_bmInfo.bmHeight, m_pBits);
  339. }
  340. }