OptionTreeColorPopUp.cpp
Upload User: kairuinn
Upload Date: 2009-02-07
Package Size: 2922k
Code Size: 32k
Category:

Graph program

Development Platform:

Visual C++

  1. // COptionTree
  2. //
  3. // License
  4. // -------
  5. // This code is provided "as is" with no expressed or implied warranty.
  6. // 
  7. // You may use this code in a commercial product with or without acknowledgement.
  8. // However you may not sell this code or any modification of this code, this includes 
  9. // commercial libraries and anything else for profit.
  10. //
  11. // I would appreciate a notification of any bugs or bug fixes to help the control grow.
  12. //
  13. // History:
  14. // --------
  15. // See License.txt for full history information.
  16. //
  17. //
  18. // Copyright (c) 1999-2002 
  19. // ComputerSmarts.net 
  20. // mattrmiller@computersmarts.net
  21. #include "stdafx.h"
  22. #include <math.h>
  23. #include "OptionTreeColorPopUp.h"
  24. // Added Headers
  25. #include "OptionTree.h"
  26. #ifdef _DEBUG
  27. #define new DEBUG_NEW
  28. #undef THIS_FILE
  29. static char THIS_FILE[] = __FILE__;
  30. #endif
  31. OT_COLOR_ITEM COptionTreeColorPopUp::m_crColors[] = 
  32. {
  33.     { RGB(0x00, 0x00, 0x00),    _T("Black")             },
  34.     { RGB(0xA5, 0x2A, 0x00),    _T("Brown")             },
  35.     { RGB(0x00, 0x40, 0x40),    _T("Dark Olive Green")  },
  36.     { RGB(0x00, 0x55, 0x00),    _T("Dark Green")        },
  37.     { RGB(0x00, 0x00, 0x5E),    _T("Dark Teal")         },
  38.     { RGB(0x00, 0x00, 0x8B),    _T("Dark Blue")         },
  39.     { RGB(0x4B, 0x00, 0x82),    _T("Indigo")            },
  40.     { RGB(0x28, 0x28, 0x28),    _T("Gray-80%") },
  41.     { RGB(0x8B, 0x00, 0x00),    _T("Dark Red")          },
  42.     { RGB(0xFF, 0x68, 0x20),    _T("Orange")            },
  43.     { RGB(0x8B, 0x8B, 0x00),    _T("Dark Yellow")       },
  44.     { RGB(0x00, 0x93, 0x00),    _T("Green")             },
  45.     { RGB(0x38, 0x8E, 0x8E),    _T("Teal")              },
  46.     { RGB(0x00, 0x00, 0xFF),    _T("Blue")              },
  47.     { RGB(0x7B, 0x7B, 0xC0),    _T("Blue-Gray")         },
  48.     { RGB(0x66, 0x66, 0x66),    _T("Gray-50%") },
  49.     { RGB(0xFF, 0x00, 0x00),    _T("Red")               },
  50.     { RGB(0xFF, 0xAD, 0x5B),    _T("Light Orange")      },
  51.     { RGB(0x32, 0xCD, 0x32),    _T("Lime")              }, 
  52.     { RGB(0x3C, 0xB3, 0x71),    _T("Sea Green")         },
  53.     { RGB(0x7F, 0xFF, 0xD4),    _T("Aqua")              },
  54.     { RGB(0x7D, 0x9E, 0xC0),    _T("Light Blue")        },
  55.     { RGB(0x80, 0x00, 0x80),    _T("Violet")            },
  56.     { RGB(0x7F, 0x7F, 0x7F),    _T("Gray-40%") },
  57.     { RGB(0xFF, 0xC0, 0xCB),    _T("Pink")              },
  58.     { RGB(0xFF, 0xD7, 0x00),    _T("Gold")              },
  59.     { RGB(0xFF, 0xFF, 0x00),    _T("Yellow")            },    
  60.     { RGB(0x00, 0xFF, 0x00),    _T("Bright Green")      },
  61.     { RGB(0x40, 0xE0, 0xD0),    _T("Turquoise")         },
  62.     { RGB(0xC0, 0xFF, 0xFF),    _T("Skyblue")           },
  63.     { RGB(0x48, 0x00, 0x48),    _T("Plum")              },
  64.     { RGB(0xC0, 0xC0, 0xC0),    _T("Gray-25%") },
  65.     { RGB(0xFF, 0xE4, 0xE1),    _T("Rose")              },
  66.     { RGB(0xD2, 0xB4, 0x8C),    _T("Tan")               },
  67.     { RGB(0xFF, 0xFF, 0xE0),    _T("Light Yellow")      },
  68.     { RGB(0x98, 0xFB, 0x98),    _T("Pale Green ")       },
  69.     { RGB(0xAF, 0xEE, 0xEE),    _T("Pale Turquoise")    },
  70.     { RGB(0x68, 0x83, 0x8B),    _T("Pale Blue")         },
  71.     { RGB(0xE6, 0xE6, 0xFA),    _T("Lavender")          },
  72.     { RGB(0xFF, 0xFF, 0xFF),    _T("White")             }
  73. };
  74. /////////////////////////////////////////////////////////////////////////////
  75. // COptionTreeColorPopUp
  76. COptionTreeColorPopUp::COptionTreeColorPopUp()
  77. {
  78.     // Initialize
  79. Initialize();
  80. }
  81. COptionTreeColorPopUp::COptionTreeColorPopUp(CPoint pPoint, COLORREF crColor, COLORREF crDefault, CWnd* pParentWnd, LPCTSTR szDefaultText, LPCTSTR szCustomText)
  82. {
  83.     // Initialize
  84. Initialize();
  85. // Set variables
  86.     m_crColor = m_crInitialColor = crColor;
  87. m_crDefault = crDefault;
  88.     m_wndParent = pParentWnd;
  89.     m_strDefaultText = (szDefaultText)? szDefaultText : _T("");
  90.     m_strCustomText  = (szCustomText)?  szCustomText  : _T("");
  91.     // Create
  92. COptionTreeColorPopUp::Create(pPoint, m_crColor, pParentWnd, szDefaultText, szCustomText);
  93. }
  94. void COptionTreeColorPopUp::Initialize()
  95. {
  96. // Declare variables
  97. NONCLIENTMETRICS ncm;
  98. LOGPALETTE* pLogPalette;
  99.     struct 
  100. {
  101.         LOGPALETTE    LogPalette;
  102.         PALETTEENTRY  PalEntry[OT_COLOR_MAXCOLORS];
  103.     } pal;
  104.     // Get number of colors
  105. m_nNumColors = sizeof(m_crColors)/sizeof(OT_COLOR_ITEM);
  106.     ASSERT(m_nNumColors <= OT_COLOR_MAXCOLORS);
  107.     if (m_nNumColors > OT_COLOR_MAXCOLORS)
  108. {
  109.         m_nNumColors = OT_COLOR_MAXCOLORS;
  110. }
  111. // Set variables
  112.     m_nNumColumns = 0;
  113.     m_nNumRows = 0;
  114.     m_nBoxSize = 18;
  115.     //m_nMargin = ::GetSystemMetrics(SM_CXEDGE);
  116. m_nMargin = 2;
  117.     m_nCurrentSel = OT_COLOR_INVALIDCOLOR;
  118.     m_nChosenColorSel = OT_COLOR_INVALIDCOLOR;
  119.     m_wndParent = NULL;
  120.     m_crColor = m_crInitialColor = RGB(0, 0, 0);
  121.     m_bChildWindowVisible = FALSE;
  122.     // Make sure the color square is at least 5 x 5;
  123.     if (m_nBoxSize - 2 * m_nMargin - 2 < 5) 
  124. {
  125. m_nBoxSize = 5 + 2 * m_nMargin + 2;
  126. }
  127.     // Create the font
  128.     ncm.cbSize = sizeof(NONCLIENTMETRICS);
  129.     VERIFY(SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0));
  130.     m_fFont.CreateFontIndirect(&(ncm.lfMessageFont));
  131.     // Create the palette
  132.     pLogPalette = (LOGPALETTE*) &pal;
  133.     pLogPalette->palVersion = 0x300;
  134.     pLogPalette->palNumEntries = (WORD) m_nNumColors; 
  135.     for (int i = 0; i < m_nNumColors; i++)
  136.     {
  137.         pLogPalette->palPalEntry[i].peRed   = GetRValue(m_crColors[i].crColor);
  138.         pLogPalette->palPalEntry[i].peGreen = GetGValue(m_crColors[i].crColor);
  139.         pLogPalette->palPalEntry[i].peBlue  = GetBValue(m_crColors[i].crColor);
  140.         pLogPalette->palPalEntry[i].peFlags = 0;
  141.     }
  142.     m_plPalette.CreatePalette(pLogPalette);
  143. }
  144. COptionTreeColorPopUp::~COptionTreeColorPopUp()
  145. {
  146.     // Delete variables
  147. if (m_fFont.GetSafeHandle() != NULL)
  148. {
  149. m_fFont.DeleteObject();
  150. }
  151. if (m_plPalette.GetSafeHandle() != NULL)
  152. {
  153. m_plPalette.DeleteObject();
  154. }
  155. }
  156. BOOL COptionTreeColorPopUp::Create(CPoint pPoint, COLORREF crColor, CWnd* pParentWnd, LPCTSTR szDefaultText, LPCTSTR szCustomText)
  157. {
  158.     // Declare variables
  159. CString strClassName;
  160. // Verify window
  161. ASSERT(pParentWnd && ::IsWindow(pParentWnd->GetSafeHwnd()));
  162.   
  163.     // Se variables
  164. m_wndParent = pParentWnd;
  165.     m_crColor = m_crInitialColor = crColor;
  166.     // Get the class name and create the window
  167.     strClassName = AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW, 0, (HBRUSH) (COLOR_BTNFACE+1), 0);
  168. // Create window
  169.     if (!CWnd::CreateEx(0, strClassName, _T(""), WS_POPUP | WS_VISIBLE, pPoint.x, pPoint.y, 100, 100, pParentWnd->GetSafeHwnd(), 0, NULL))
  170. {
  171.         return FALSE;
  172. }
  173. // Show window
  174. ShowWindow(SW_SHOWNA);
  175.     // Store the Custom text
  176.     if (szCustomText != NULL) 
  177. {
  178.         m_strCustomText = szCustomText;
  179. }
  180.     // Store the Default Area text
  181.     if (szDefaultText != NULL) 
  182. {
  183.         m_strDefaultText = szDefaultText;
  184. }
  185.         
  186.     // Set the window size
  187.     SetWindowSize();
  188.     // Create the tooltips
  189.     CreateToolTips();
  190.     // Find which cell (if any) corresponds to the initial color
  191.     FindCellFromColor(crColor);
  192.     // Capture all mouse events for the life of this window
  193.     SetCapture();
  194.     return TRUE;
  195. }
  196. BEGIN_MESSAGE_MAP(COptionTreeColorPopUp, CWnd)
  197.     //{{AFX_MSG_MAP(COptionTreeColorPopUp)
  198.     ON_WM_NCDESTROY()
  199.     ON_WM_LBUTTONUP()
  200.     ON_WM_PAINT()
  201.     ON_WM_MOUSEMOVE()
  202.     ON_WM_KEYDOWN()
  203.     ON_WM_QUERYNEWPALETTE()
  204.     ON_WM_PALETTECHANGED()
  205. ON_WM_KILLFOCUS()
  206. ON_WM_ACTIVATEAPP()
  207. //}}AFX_MSG_MAP
  208. END_MESSAGE_MAP()
  209. /////////////////////////////////////////////////////////////////////////////
  210. // COptionTreeColorPopUp message handlers
  211. // For tooltips
  212. BOOL COptionTreeColorPopUp::PreTranslateMessage(MSG* pMsg) 
  213. {
  214. // Relay tooltip
  215. if (IsWindow(m_ttToolTip.GetSafeHwnd()))
  216. {
  217. m_ttToolTip.RelayEvent(pMsg);
  218. }
  219.     // Sometimes if the picker loses focus it is never destroyed
  220.     if (GetCapture()->GetSafeHwnd() != m_hWnd)
  221. {
  222.         SetCapture(); 
  223. }
  224.     return CWnd::PreTranslateMessage(pMsg);
  225. }
  226. void COptionTreeColorPopUp::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
  227. {
  228. // Declare variable
  229. int nRow, nCol;
  230.     
  231. // Get row
  232. nRow = GetRow(m_nCurrentSel);
  233. // Get column
  234. nCol = GetColumn(m_nCurrentSel);
  235.     // Down
  236. if (nChar == VK_DOWN) 
  237.     {
  238.         if (nRow == OT_COLOR_DEFAULTBOXVALUE) 
  239. {
  240.             nRow = nCol = 0; 
  241. }
  242.         else if (nRow == OT_COLOR_CUSTOMBOXVALUE)
  243.         {
  244.             if (m_strDefaultText.GetLength())
  245. {
  246.                 nRow = nCol = OT_COLOR_DEFAULTBOXVALUE;
  247. }
  248.             else
  249. {
  250.                 nRow = nCol = 0;
  251. }
  252.         }
  253.         else
  254.         {
  255.             nRow++;
  256.             if (GetIndex(nRow, nCol) < 0)
  257.             {
  258.                 if (m_strCustomText.GetLength())
  259. {
  260.                     nRow = nCol = OT_COLOR_CUSTOMBOXVALUE;
  261. }
  262.                 else if (m_strDefaultText.GetLength())
  263. {
  264.                     nRow = nCol = OT_COLOR_DEFAULTBOXVALUE;
  265. }
  266.                 else
  267. {
  268.                     nRow = nCol = 0;
  269. }
  270.             }
  271.         }
  272.         ChangeSelection(GetIndex(nRow, nCol));
  273.     }
  274. // Up
  275.     if (nChar == VK_UP) 
  276.     {
  277.         if (nRow == OT_COLOR_DEFAULTBOXVALUE)
  278.         {
  279.             if (m_strCustomText.GetLength())
  280. {
  281.                 nRow = nCol = OT_COLOR_CUSTOMBOXVALUE;
  282. }
  283.             else
  284.                 nRow = GetRow(m_nNumColors-1); 
  285.                 nCol = GetColumn(m_nNumColors-1); 
  286.             }
  287.         }
  288.         else if (nRow == OT_COLOR_CUSTOMBOXVALUE)
  289.         { 
  290.             nRow = GetRow(m_nNumColors-1); 
  291.             nCol = GetColumn(m_nNumColors-1); 
  292.         }
  293.         else if (nRow > 0) 
  294. {
  295. nRow--;
  296. }
  297.         else
  298.         {
  299.             if (m_strDefaultText.GetLength())
  300. {
  301.                 nRow = nCol = OT_COLOR_DEFAULTBOXVALUE;
  302. }
  303.             else if (m_strCustomText.GetLength())
  304. {
  305.                 nRow = nCol = OT_COLOR_CUSTOMBOXVALUE;
  306. }
  307.             else
  308.             { 
  309.                 nRow = GetRow(m_nNumColors-1); 
  310.                 nCol = GetColumn(m_nNumColors-1); 
  311.             }
  312.         }
  313.         ChangeSelection(GetIndex(nRow, nCol));
  314.     }
  315. // Right
  316.     if (nChar == VK_RIGHT) 
  317.     {
  318.         if (nRow == OT_COLOR_DEFAULTBOXVALUE) 
  319. {
  320.             nRow = nCol = 0; 
  321. }
  322.         else if (nRow == OT_COLOR_CUSTOMBOXVALUE)
  323.         {
  324.             if (m_strDefaultText.GetLength())
  325. {
  326.                 nRow = nCol = OT_COLOR_DEFAULTBOXVALUE;
  327. }
  328.             else
  329. {
  330.                 nRow = nCol = 0;
  331. }
  332.         }
  333.         else if (nCol < m_nNumColumns - 1) 
  334. {
  335.             nCol++;
  336. }
  337.         else 
  338.         { 
  339.             nCol = 0; nRow++;
  340.         }
  341.         if (GetIndex(nRow,nCol) == OT_COLOR_INVALIDCOLOR)
  342.         {
  343.             if (m_strCustomText.GetLength())
  344. {
  345.                 nRow = nCol = OT_COLOR_CUSTOMBOXVALUE;
  346. }
  347.             else if (m_strDefaultText.GetLength())
  348. {
  349.                 nRow = nCol = OT_COLOR_DEFAULTBOXVALUE;
  350. }
  351.             else
  352. {
  353.                 nRow = nCol = 0;
  354. }
  355.         }
  356.         ChangeSelection(GetIndex(nRow, nCol));
  357.     }
  358. // Left
  359.     if (nChar == VK_LEFT) 
  360.     {
  361.         if (nRow == OT_COLOR_DEFAULTBOXVALUE)
  362.         {
  363.             if (m_strCustomText.GetLength())
  364. {
  365.                 nRow = nCol = OT_COLOR_CUSTOMBOXVALUE;
  366. }
  367.             else
  368.                 nRow = GetRow(m_nNumColors-1); 
  369.                 nCol = GetColumn(m_nNumColors-1); 
  370.             }
  371.         }
  372.         else if (nRow == OT_COLOR_CUSTOMBOXVALUE)
  373.         { 
  374.             nRow = GetRow(m_nNumColors-1); 
  375.             nCol = GetColumn(m_nNumColors-1); 
  376.         }
  377.         else if (nCol > 0) 
  378. {
  379. nCol--;
  380. }
  381.         else
  382.         {
  383.             if (nRow > 0) 
  384. nRow--; 
  385. nCol = m_nNumColumns - 1; 
  386. }
  387.             else 
  388.             {
  389.                 if (m_strDefaultText.GetLength())
  390. {
  391.                     nRow = nCol = OT_COLOR_DEFAULTBOXVALUE;
  392. }
  393.                 else if (m_strCustomText.GetLength())
  394. {
  395.                     nRow = nCol = OT_COLOR_CUSTOMBOXVALUE;
  396. }
  397.                 else
  398.                 { 
  399.                     nRow = GetRow(m_nNumColors - 1); 
  400.                     nCol = GetColumn(m_nNumColors - 1); 
  401.                 }
  402.             }
  403.         }
  404.         ChangeSelection(GetIndex(nRow, nCol));
  405.     }
  406. // Escape
  407.     if (nChar == VK_ESCAPE) 
  408.     {
  409.         m_crColor = m_crInitialColor;
  410.         EndSelection(OT_COLOR_SELENDCANCEL);
  411.         return;
  412.     }
  413. // Return or space
  414.     if (nChar == VK_RETURN || nChar == VK_SPACE)
  415.     {
  416.         EndSelection(OT_COLOR_SELENDOK);
  417.         return;
  418.     }
  419.     CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
  420. }
  421. // auto-deletion
  422. void COptionTreeColorPopUp::OnNcDestroy() 
  423. {
  424.     CWnd::OnNcDestroy();
  425.     delete this;
  426. }
  427. void COptionTreeColorPopUp::OnPaint() 
  428. {
  429.     // Declare variables
  430. CPaintDC dc(this);
  431. CRect rcClient;
  432. // Get client rect
  433. GetClientRect(rcClient);
  434.     // Draw the Default Area text
  435.     if (m_strDefaultText.GetLength())
  436. {
  437.         DrawCell(&dc, OT_COLOR_DEFAULTBOXVALUE);
  438. }
  439.  
  440.     // Draw color cells
  441.     for (int i = 0; i < m_nNumColors; i++)
  442. {
  443.         DrawCell(&dc, i);
  444. }
  445.     
  446.     // Draw custom text
  447.     if (m_strCustomText.GetLength())
  448. {
  449.         DrawCell(&dc, OT_COLOR_CUSTOMBOXVALUE);
  450. }
  451.     // Draw raised window edge (ex-window style WS_EX_WINDOWEDGE is sposed to do this, but for some reason isn't
  452.     dc.DrawEdge(rcClient, EDGE_RAISED, BF_RECT);
  453. }
  454. void COptionTreeColorPopUp::OnMouseMove(UINT nFlags, CPoint point) 
  455. {
  456. // Declare variables
  457.     int nNewSelection = OT_COLOR_INVALIDCOLOR;
  458.     // Translate points to be relative raised window edge
  459.     point.x -= m_nMargin;
  460.     point.y -= m_nMargin;
  461.     // First check we aren't in text box
  462.     if (m_strCustomText.GetLength() && m_rcCustomTextRect.PtInRect(point))
  463. {
  464.         nNewSelection = OT_COLOR_CUSTOMBOXVALUE;
  465. }
  466.     else if (m_strDefaultText.GetLength() && m_rcDefaultTextRect.PtInRect(point))
  467. {
  468.         nNewSelection = OT_COLOR_DEFAULTBOXVALUE;
  469. }
  470.     else
  471.     {
  472.         // -- Take into account text box
  473.         if (m_strDefaultText.GetLength()) 
  474. {
  475.             point.y -= m_rcDefaultTextRect.Height();  
  476. }
  477.         // -- Get the row and column
  478.         nNewSelection = GetIndex(point.y / m_nBoxSize, point.x / m_nBoxSize);
  479.         // -- In range? If not, default and exit
  480.         if (nNewSelection < 0 || nNewSelection >= m_nNumColors)
  481.         {
  482.             CWnd::OnMouseMove(nFlags, point);
  483.             return;
  484.         }
  485.     }
  486.     // OK - we have the row and column of the current selection (may be OT_COLOR_CUSTOMBOXVALUE)
  487.     // Has the row/col selection changed? If yes, then redraw old and new cells.
  488.     if (nNewSelection != m_nCurrentSel)
  489. {
  490.         ChangeSelection(nNewSelection);
  491. }
  492.     CWnd::OnMouseMove(nFlags, point);
  493. }
  494. void COptionTreeColorPopUp::OnLButtonUp(UINT nFlags, CPoint point) 
  495. {
  496. // Declare variables
  497. DWORD dwPos;
  498.     // Get osition
  499. dwPos = GetMessagePos();
  500.     point = CPoint(LOWORD(dwPos), HIWORD(dwPos));
  501.     if (m_rcWindowRect.PtInRect(point))
  502. {
  503.         EndSelection(OT_COLOR_SELENDOK);
  504. }
  505.     else
  506. {
  507.         EndSelection(OT_COLOR_SELENDCANCEL);
  508. }
  509. // Handle left click
  510. if (::IsWindow(GetSafeHwnd()))
  511. {
  512. CWnd::OnLButtonUp(nFlags, point);
  513. }
  514. }
  515. int COptionTreeColorPopUp::GetIndex(int nRow, int nCol) const
  516. // Get index
  517.     if ((nRow == OT_COLOR_CUSTOMBOXVALUE || nCol == OT_COLOR_CUSTOMBOXVALUE) && m_strCustomText.GetLength())
  518. {
  519.         return OT_COLOR_CUSTOMBOXVALUE;
  520. }
  521.     else if ((nRow == OT_COLOR_DEFAULTBOXVALUE || nCol == OT_COLOR_DEFAULTBOXVALUE) && m_strDefaultText.GetLength())
  522. {
  523.         return OT_COLOR_DEFAULTBOXVALUE;
  524. }
  525.     else if (nRow < 0 || nCol < 0 || nRow >= m_nNumRows || nCol >= m_nNumColumns)
  526. {
  527.         return OT_COLOR_INVALIDCOLOR;
  528. }
  529.     else
  530.     {
  531.         if (nRow * m_nNumColumns + nCol >= m_nNumColors)
  532. {
  533.             return OT_COLOR_INVALIDCOLOR;
  534. }
  535.         else
  536. {
  537.             return nRow * m_nNumColumns + nCol;
  538. }
  539.     }
  540. }
  541. int COptionTreeColorPopUp::GetRow(int nIndex) const               
  542. // Get row
  543.     if (nIndex == OT_COLOR_CUSTOMBOXVALUE && m_strCustomText.GetLength())
  544. {
  545.         return OT_COLOR_CUSTOMBOXVALUE;
  546. }
  547.     else if (nIndex == OT_COLOR_DEFAULTBOXVALUE && m_strDefaultText.GetLength())
  548. {
  549.         return OT_COLOR_DEFAULTBOXVALUE;
  550. }
  551.     else if (nIndex < 0 || nIndex >= m_nNumColors)
  552. {
  553.         return OT_COLOR_INVALIDCOLOR;
  554. }
  555.     else
  556. {
  557.         return nIndex / m_nNumColumns; 
  558. }
  559. }
  560. int COptionTreeColorPopUp::GetColumn(int nIndex) const            
  561. // Get column
  562.     if (nIndex == OT_COLOR_CUSTOMBOXVALUE && m_strCustomText.GetLength())
  563. {
  564.         return OT_COLOR_CUSTOMBOXVALUE;
  565. }
  566.     else if (nIndex == OT_COLOR_DEFAULTBOXVALUE && m_strDefaultText.GetLength())
  567. {
  568.         return OT_COLOR_DEFAULTBOXVALUE;
  569. }
  570.     else if (nIndex < 0 || nIndex >= m_nNumColors)
  571. {
  572.         return OT_COLOR_INVALIDCOLOR;
  573. }
  574.     else
  575. {
  576.         return nIndex % m_nNumColumns; 
  577. }
  578. }
  579. void COptionTreeColorPopUp::FindCellFromColor(COLORREF crColor)
  580. {
  581. // Find cell
  582.     if (crColor == m_crDefault && m_strDefaultText.GetLength())
  583.     {
  584.         m_nChosenColorSel = OT_COLOR_DEFAULTBOXVALUE;
  585.         return;
  586.     }
  587.     for (int i = 0; i < m_nNumColors; i++)
  588.     {
  589.         if (GetColor(i) == crColor)
  590.         {
  591.             m_nChosenColorSel = i;
  592.             return;
  593.         }
  594.     }
  595.     if (m_strCustomText.GetLength())
  596. {
  597.         m_nChosenColorSel = OT_COLOR_CUSTOMBOXVALUE;
  598. }
  599.     else
  600. {
  601.         m_nChosenColorSel = OT_COLOR_INVALIDCOLOR;
  602. }
  603. }
  604. BOOL COptionTreeColorPopUp::GetCellRect(int nIndex, const LPRECT& rect)
  605. {
  606. // Get cell rect
  607.     if (nIndex == OT_COLOR_CUSTOMBOXVALUE)
  608.     {
  609.         ::SetRect(rect, m_rcCustomTextRect.left,  m_rcCustomTextRect.top, m_rcCustomTextRect.right, m_rcCustomTextRect.bottom);
  610. return TRUE;
  611.     }
  612.     else if (nIndex == OT_COLOR_DEFAULTBOXVALUE)
  613.     {
  614.         ::SetRect(rect, m_rcDefaultTextRect.left,  m_rcDefaultTextRect.top, m_rcDefaultTextRect.right, m_rcDefaultTextRect.bottom);
  615.         return TRUE;
  616.     }
  617.     if (nIndex < 0 || nIndex >= m_nNumColors)
  618. {
  619.         return FALSE;
  620. }
  621.     rect->left = GetColumn(nIndex) * m_nBoxSize + m_nMargin;
  622.     rect->top  = GetRow(nIndex) * m_nBoxSize + m_nMargin;
  623.     // Move everything down if we are displaying a default text area
  624.     if (m_strDefaultText.GetLength()) 
  625. {
  626.         rect->top += (m_nMargin + m_rcDefaultTextRect.Height());
  627. }
  628.     rect->right = rect->left + m_nBoxSize;
  629.     rect->bottom = rect->top + m_nBoxSize;
  630.     return TRUE;
  631. }
  632. void COptionTreeColorPopUp::SetWindowSize()
  633. {
  634.     // Declare variables
  635. CSize TextSize;
  636.     // If we are showing a custom or default text area, get the font and text size.
  637.     if (m_strCustomText.GetLength() || m_strDefaultText.GetLength())
  638.     {
  639.         CClientDC dc(this);
  640.         CFont* pOldFont = (CFont*) dc.SelectObject(&m_fFont);
  641.         // -- Get the size of the custom text (if there IS custom text)
  642.         TextSize = CSize(0,0);
  643.         if (m_strCustomText.GetLength())
  644.             TextSize = dc.GetTextExtent(m_strCustomText);
  645.         // -- Get the size of the default text (if there IS default text)
  646.         if (m_strDefaultText.GetLength())
  647.         {
  648.             CSize DefaultSize = dc.GetTextExtent(m_strDefaultText);
  649.             if (DefaultSize.cx > TextSize.cx) TextSize.cx = DefaultSize.cx;
  650.             if (DefaultSize.cy > TextSize.cy) TextSize.cy = DefaultSize.cy;
  651.         }
  652.         dc.SelectObject(pOldFont);
  653.         TextSize += CSize(2*m_nMargin,2*m_nMargin);
  654.         // -- Add even more space to draw the horizontal line
  655.         TextSize.cy += 2*m_nMargin + 2;
  656.     }
  657.     // Get the number of columns and rows
  658.     m_nNumColumns = 8;
  659.     m_nNumRows = m_nNumColors / m_nNumColumns;
  660.     if (m_nNumColors % m_nNumColumns) 
  661. {
  662. m_nNumRows++;
  663. }
  664.     // Get the current window position, and set the new size
  665.     CRect rect;
  666.     GetWindowRect(rect);
  667.     m_rcWindowRect.SetRect(rect.left, rect.top, rect.left + m_nNumColumns*m_nBoxSize + 2*m_nMargin, rect.top  + m_nNumRows*m_nBoxSize + 2*m_nMargin);
  668.     // If custom text, then expand window if necessary, and set text width as
  669.     // window width
  670.     if (m_strDefaultText.GetLength()) 
  671.     {
  672.         if (TextSize.cx > m_rcWindowRect.Width())
  673. {
  674.             m_rcWindowRect.right = m_rcWindowRect.left + TextSize.cx;
  675. }
  676.         TextSize.cx = m_rcWindowRect.Width()-2*m_nMargin;
  677.         // -- Work out the text area
  678.         m_rcDefaultTextRect.SetRect(m_nMargin, m_nMargin, m_nMargin+TextSize.cx, 2*m_nMargin+TextSize.cy);
  679.         m_rcWindowRect.bottom += m_rcDefaultTextRect.Height() + 2*m_nMargin;
  680.     }
  681.     // If custom text, then expand window if necessary, and set text width as
  682.     // window width
  683.     if (m_strCustomText.GetLength()) 
  684.     {
  685.         if (TextSize.cx > m_rcWindowRect.Width())
  686. {
  687.             m_rcWindowRect.right = m_rcWindowRect.left + TextSize.cx;
  688. }
  689.         TextSize.cx = m_rcWindowRect.Width()-2*m_nMargin;
  690.         // -- Work out the text area
  691.         m_rcCustomTextRect.SetRect(m_nMargin, m_rcWindowRect.Height(), m_nMargin+TextSize.cx, m_rcWindowRect.Height()+m_nMargin+TextSize.cy);
  692. m_rcWindowRect.bottom += m_rcCustomTextRect.Height() + 2*m_nMargin;
  693.    }
  694.     // Need to check it'll fit on screen: Too far right?
  695.     CSize ScreenSize(::GetSystemMetrics(SM_CXSCREEN), ::GetSystemMetrics(SM_CYSCREEN));
  696.     if (m_rcWindowRect.right > ScreenSize.cx)
  697. {
  698.         m_rcWindowRect.OffsetRect(-(m_rcWindowRect.right - ScreenSize.cx), 0);
  699. }
  700.     // Too far left?
  701.     if (m_rcWindowRect.left < 0)
  702. {
  703.         m_rcWindowRect.OffsetRect( -m_rcWindowRect.left, 0);
  704. }
  705.     // Bottom falling out of screen?
  706.     if (m_rcWindowRect.bottom > ScreenSize.cy)
  707.     {
  708.         CRect rcParentRect;
  709.         m_wndParent->GetWindowRect(rcParentRect);
  710.         m_rcWindowRect.OffsetRect(0, -(rcParentRect.Height() + m_rcWindowRect.Height()));
  711.     }
  712.     // Set the window size and position
  713.     MoveWindow(m_rcWindowRect, TRUE);
  714. }
  715. void COptionTreeColorPopUp::CreateToolTips()
  716. {
  717.     // Create the tool tip
  718.     if (!m_ttToolTip.Create(this)) 
  719. {
  720. return;
  721. }
  722.     // Add a tool for each cell
  723.     for (int i = 0; i < m_nNumColors; i++)
  724.     {
  725.         CRect rect;
  726.         if (!GetCellRect(i, rect)) 
  727. {
  728. continue;
  729. }
  730. m_ttToolTip.AddTool(this, GetColorName(i), rect, 1);
  731.     }
  732. // Create inactive
  733. m_ttToolTip.Activate(TRUE);
  734. }
  735. void COptionTreeColorPopUp::ChangeSelection(int nIndex)
  736. {
  737.     CClientDC dc(this);
  738.     if (nIndex > m_nNumColors)
  739. {
  740.         nIndex = OT_COLOR_CUSTOMBOXVALUE; 
  741. }
  742.     if ((m_nCurrentSel >= 0 && m_nCurrentSel < m_nNumColors) || m_nCurrentSel == OT_COLOR_CUSTOMBOXVALUE || m_nCurrentSel == OT_COLOR_DEFAULTBOXVALUE)
  743.     {
  744.         // -- Set Current selection as invalid and redraw old selection (this way
  745.         // the old selection will be drawn unselected)
  746.         int OldSel = m_nCurrentSel;
  747.         m_nCurrentSel = OT_COLOR_INVALIDCOLOR;
  748.         DrawCell(&dc, OldSel);
  749.     }
  750.     // Set the current selection as row/col and draw (it will be drawn selected)
  751.     m_nCurrentSel = nIndex;
  752.     DrawCell(&dc, m_nCurrentSel);
  753.     // Store the current color
  754.     if (m_nCurrentSel == OT_COLOR_CUSTOMBOXVALUE)
  755. {
  756.         m_wndParent->SendMessage(OT_COLOR_SELCHANGE, (WPARAM) m_crInitialColor, 0);
  757. }
  758.     else if (m_nCurrentSel == OT_COLOR_DEFAULTBOXVALUE)
  759.     {
  760.         m_crColor = m_crDefault;
  761.         m_wndParent->SendMessage(OT_COLOR_SELCHANGE, (WPARAM) m_crDefault, 0);
  762.     }
  763.     else
  764.     {
  765.         m_crColor = GetColor(m_nCurrentSel);
  766.         m_wndParent->SendMessage(OT_COLOR_SELCHANGE, (WPARAM) m_crColor, 0);
  767.     }
  768. }
  769. void COptionTreeColorPopUp::EndSelection(int nMessage)
  770. {
  771. // Release capture
  772.     ReleaseCapture();
  773.     // If custom text selected, perform a custom color selection
  774.     if (nMessage != OT_COLOR_SELENDCANCEL && m_nCurrentSel == OT_COLOR_CUSTOMBOXVALUE)
  775.     {
  776.         m_bChildWindowVisible = TRUE;
  777.         CColorDialog dlg(m_crInitialColor, CC_FULLOPEN | CC_ANYCOLOR, this);
  778.         if (dlg.DoModal() == IDOK)
  779. {
  780.             m_crColor = dlg.GetColor();
  781. }
  782.         else
  783. {
  784.             nMessage = OT_COLOR_SELENDCANCEL;
  785. }
  786.         m_bChildWindowVisible = FALSE;
  787.     } 
  788. // Get initial color
  789.     if (nMessage == OT_COLOR_SELENDCANCEL)
  790. {
  791.         m_crColor = m_crInitialColor;
  792. }
  793. // Send message
  794.     m_wndParent->SendMessage(nMessage, (WPARAM) m_crColor, 0);
  795.     
  796.     // Kill focus
  797.     if (!m_bChildWindowVisible)
  798. {
  799.         DestroyWindow();
  800. }
  801. }
  802. void COptionTreeColorPopUp::DrawCell(CDC* pDC, int nIndex)
  803. {
  804.     // For the Custom Text area
  805.     if (m_strCustomText.GetLength() && nIndex == OT_COLOR_CUSTOMBOXVALUE)
  806.     {
  807.         // -- The extent of the actual text button
  808.         CRect rcTextButton = m_rcCustomTextRect;
  809.         rcTextButton.top += 2 * m_nMargin;
  810.         // -- Fill background
  811.         pDC->FillSolidRect(rcTextButton, ::GetSysColor(COLOR_3DFACE));
  812.         // -- Draw horizontal line
  813.         pDC->FillSolidRect(m_rcCustomTextRect.left + 2 * m_nMargin, m_rcCustomTextRect.top, m_rcCustomTextRect.Width()-4*m_nMargin, 1, ::GetSysColor(COLOR_3DSHADOW));
  814.         pDC->FillSolidRect(m_rcCustomTextRect.left + 2 * m_nMargin, m_rcCustomTextRect.top + 1, m_rcCustomTextRect.Width()-4*m_nMargin, 1, ::GetSysColor(COLOR_3DHILIGHT));
  815.         rcTextButton.DeflateRect(1,1);
  816.         // -- Fill background
  817.         if (m_nChosenColorSel == nIndex && m_nCurrentSel != nIndex)
  818. {
  819.             pDC->FillSolidRect(rcTextButton, ::GetSysColor(COLOR_3DLIGHT));
  820. }
  821.         else
  822. {
  823.             pDC->FillSolidRect(rcTextButton, ::GetSysColor(COLOR_3DFACE));
  824. }
  825.         // -- Draw button
  826.         if (m_nCurrentSel == nIndex) 
  827. {
  828.             pDC->DrawEdge(rcTextButton, BDR_RAISEDINNER, BF_RECT);
  829. }
  830.         // -- Draw custom text
  831.         CFont *pOldFont = (CFont*) pDC->SelectObject(&m_fFont);
  832.         int nOldBack = pDC->SetBkMode(TRANSPARENT);
  833.         pDC->DrawText(m_strCustomText, rcTextButton, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  834. // -- Restore
  835.         pDC->SelectObject(pOldFont);
  836. pDC->SetBkMode(nOldBack);
  837.         return;
  838.     }        
  839.     // For the Default Text area
  840.     if (m_strDefaultText.GetLength() && nIndex == OT_COLOR_DEFAULTBOXVALUE)
  841.     {
  842.         // -- Fill background
  843.         pDC->FillSolidRect(m_rcDefaultTextRect, ::GetSysColor(COLOR_3DFACE));
  844.         // -- The extent of the actual text button
  845.         CRect rcTextButton = m_rcDefaultTextRect;
  846.         rcTextButton.DeflateRect(1,1);
  847.         // -- Fill background
  848.         if (m_nChosenColorSel == nIndex && m_nCurrentSel != nIndex)
  849. {
  850. for (long i = rcTextButton.top; i < rcTextButton.bottom; i++)
  851. {
  852. _DrawSelectRect(pDC->GetSafeHdc(), rcTextButton.left, i, rcTextButton.Width());
  853. }
  854. }
  855.         else
  856. {
  857.             pDC->FillSolidRect(rcTextButton, ::GetSysColor(COLOR_3DFACE));
  858. }
  859.         // -- Draw thin line around text
  860.         CRect rcLineRect = rcTextButton;
  861.         CPen pen(PS_SOLID, 1, ::GetSysColor(COLOR_3DSHADOW));
  862.         CPen* pOldPen = pDC->SelectObject(&pen);
  863. // -- Calculate the rectangle
  864. rcLineRect.left += 3;
  865. rcLineRect.right -= 3;
  866. rcLineRect.top += 2;
  867. rcLineRect.bottom -= 3;
  868. // -- Restore
  869.         pDC->SelectStockObject(NULL_BRUSH);
  870.         pDC->Rectangle(rcLineRect);
  871.         pDC->SelectObject(pOldPen);
  872. if (pen.GetSafeHandle() != NULL)
  873. {
  874. pen.DeleteObject();
  875. }
  876.         // -- Draw button
  877.         if (m_nCurrentSel == nIndex) 
  878. {
  879.             pDC->DrawEdge(rcTextButton, BDR_RAISEDINNER, BF_RECT);
  880. }
  881.         else if (m_nChosenColorSel == nIndex)
  882. {
  883.             pDC->DrawEdge(rcTextButton, BDR_SUNKENOUTER, BF_RECT);
  884. }
  885.         // -- Draw custom text
  886.         CFont *pOldFont = (CFont*) pDC->SelectObject(&m_fFont);
  887.         int nOldBack = pDC->SetBkMode(TRANSPARENT);
  888.         pDC->DrawText(m_strDefaultText, rcTextButton, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
  889. // -- Restore
  890.         pDC->SelectObject(pOldFont);
  891. pDC->SetBkMode(nOldBack);
  892. // -- Select and realize the palette
  893. CPalette* pOldPalette = NULL;
  894. if (pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE)
  895. {
  896. pOldPalette = pDC->SelectPalette(&m_plPalette, FALSE);
  897. pDC->RealizePalette();
  898. }
  899. // -- Draw sample cell of default color
  900. CRect rcSample;
  901. rcSample.left = rcLineRect.left;
  902. rcSample.right = rcSample.left + m_nBoxSize;
  903. rcSample.top = rcLineRect.top;
  904. rcSample.bottom = rcLineRect.top + m_nBoxSize;
  905. rcSample.DeflateRect(m_nMargin + 1, m_nMargin + 1);
  906. // -- Create objects
  907. CBrush brush(PALETTERGB(GetRValue(m_crDefault), GetGValue(m_crDefault), GetBValue(m_crDefault)));
  908. CPen penSample;
  909. penSample.CreatePen(PS_SOLID, 1, ::GetSysColor(COLOR_3DSHADOW));
  910. CBrush* pOldBrush = (CBrush*) pDC->SelectObject(&brush);
  911. CPen* pOldSamplePen = (CPen*) pDC->SelectObject(&penSample);
  912. // Draw the cell color
  913. pDC->Rectangle(rcSample);
  914. // Restore
  915. pDC->SelectObject(pOldBrush);
  916. pDC->SelectObject(pOldSamplePen);
  917. if (brush.GetSafeHandle() != NULL)
  918. {
  919. brush.DeleteObject();
  920. }
  921. if (penSample.GetSafeHandle() != NULL)
  922. {
  923. penSample.DeleteObject();
  924. }
  925. if (pOldPalette && pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE)
  926. {
  927. pDC->SelectPalette(pOldPalette, FALSE);
  928. }
  929.         return;
  930.     }        
  931. // Declare variables
  932.     CRect rcCell;
  933.     if (!GetCellRect(nIndex, rcCell)) 
  934. {
  935. return;
  936. }
  937.     // -- Select and realize the palette
  938.     CPalette* pOldPalette = NULL;
  939.     if (pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE)
  940.     {
  941.         pOldPalette = pDC->SelectPalette(&m_plPalette, FALSE);
  942.         pDC->RealizePalette();
  943.     }
  944.     // -- Fill background
  945.     if (m_nChosenColorSel == nIndex && m_nCurrentSel != nIndex)
  946. {
  947. for (long i = rcCell.top; i < rcCell.bottom; i++)
  948. {
  949. _DrawSelectRect(pDC->GetSafeHdc(), rcCell.left, i, rcCell.Width());
  950. }
  951. }
  952.     else
  953. {
  954.         pDC->FillSolidRect(rcCell, ::GetSysColor(COLOR_3DFACE));
  955. }
  956.     // Draw button
  957.     if (m_nCurrentSel == nIndex) 
  958. {
  959.         pDC->DrawEdge(rcCell, BDR_RAISEDINNER, BF_RECT);
  960. }
  961.     else if (m_nChosenColorSel == nIndex)
  962. {
  963.         pDC->DrawEdge(rcCell, BDR_SUNKENOUTER, BF_RECT);
  964. }
  965. // Create objects
  966.     CBrush brush(PALETTERGB(GetRValue(GetColor(nIndex)), GetGValue(GetColor(nIndex)), GetBValue(GetColor(nIndex))));
  967. CPen pen;
  968.     pen.CreatePen(PS_SOLID, 1, ::GetSysColor(COLOR_3DSHADOW));
  969.     CBrush* pOldBrush = (CBrush*) pDC->SelectObject(&brush);
  970.     CPen* pOldPen = (CPen*) pDC->SelectObject(&pen);
  971.     // Draw the cell color
  972.     rcCell.DeflateRect(m_nMargin + 1, m_nMargin + 1);
  973.     pDC->Rectangle(rcCell);
  974.     // Restore
  975.     pDC->SelectObject(pOldBrush);
  976.     pDC->SelectObject(pOldPen);
  977. if (brush.GetSafeHandle() != NULL)
  978. {
  979. brush.DeleteObject();
  980. }
  981. if (pen.GetSafeHandle() != NULL)
  982. {
  983. pen.DeleteObject();
  984. }
  985.     if (pOldPalette && pDC->GetDeviceCaps(RASTERCAPS) & RC_PALETTE)
  986. {
  987.         pDC->SelectPalette(pOldPalette, FALSE);
  988. }
  989. }
  990. BOOL COptionTreeColorPopUp::OnQueryNewPalette() 
  991. {
  992.     // Force redraw
  993. Invalidate();  
  994. // Update window
  995. UpdateWindow();
  996.     return CWnd::OnQueryNewPalette();
  997. }
  998. void COptionTreeColorPopUp::OnPaletteChanged(CWnd* pFocusWnd) 
  999. {
  1000.     if (pFocusWnd->GetSafeHwnd() != GetSafeHwnd())
  1001. {
  1002. // -- Force redraw
  1003.         Invalidate();
  1004. // -- Update window
  1005. UpdateWindow();
  1006. }
  1007. CWnd::OnPaletteChanged(pFocusWnd);
  1008. }
  1009. void COptionTreeColorPopUp::OnKillFocus(CWnd* pNewWnd) 
  1010. {
  1011. // Release capture
  1012.     ReleaseCapture();
  1013.     
  1014. CWnd::OnKillFocus(pNewWnd);
  1015. }
  1016. void COptionTreeColorPopUp::OnActivateApp(BOOL bActive, DWORD hTask) 
  1017. {
  1018. // If Deactivating App, cancel this selection
  1019. if (!bActive)
  1020. {
  1021.  EndSelection(OT_COLOR_SELENDCANCEL);
  1022. }
  1023. CWnd::OnActivateApp(bActive, hTask);
  1024. }