SymbolEdit.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955
  1. // AeroEdit.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "SymbolEdit.h"
  5. #include "cp_main.h"
  6. #include "QListCtrl.h"
  7. #include "Shared\TextConvert.h"
  8. // CSymbolEdit
  9. #define RANGE_START 3000
  10. #define CLEAR_LIST 3050
  11. #define LIST_MAX_COUNT 50
  12. IMPLEMENT_DYNAMIC(CSymbolEdit, CEdit)
  13. CSymbolEdit::CSymbolEdit() :
  14. m_hSymbolIcon(NULL),
  15. m_bInternalIcon(false),
  16. m_colorPromptText(RGB(127, 127, 127)),
  17. m_centerTextDiff(0)
  18. {
  19. m_fontPrompt.CreateFont(
  20. 16, // nHeight
  21. 0, // nWidth
  22. 0, // nEscapement
  23. 0, // nOrientation
  24. FW_NORMAL, // nWeight
  25. TRUE, // bItalic
  26. FALSE, // bUnderline
  27. 0, // cStrikeOut
  28. DEFAULT_CHARSET, // nCharSet
  29. OUT_DEFAULT_PRECIS, // nOutPrecision
  30. CLIP_DEFAULT_PRECIS, // nClipPrecision
  31. DEFAULT_QUALITY, // nQuality
  32. DEFAULT_PITCH | FF_SWISS, // nPitchAndFamily
  33. _T("Calibri"));
  34. m_mouseDownOnSearches = false;
  35. m_mouseHoveringOverSearches = false;
  36. m_mouseDownOnClose = false;
  37. m_mouseHoveringOverClose = false;
  38. m_windowDpi = NULL;
  39. //m_searchButton.LoadStdImageDPI(Search_16, Search_20, Search_24, Search_32, _T("PNG"));
  40. }
  41. CSymbolEdit::~CSymbolEdit()
  42. {
  43. DestroyIcon();
  44. }
  45. BEGIN_MESSAGE_MAP(CSymbolEdit, CEdit)
  46. ON_WM_PAINT()
  47. ON_MESSAGE(WM_SETFONT, OnSetFont)
  48. //ON_MESSAGE(WM_EXITMENULOOP, OnMenuExit)
  49. ON_WM_CTLCOLOR_REFLECT()
  50. ON_WM_SETFOCUS()
  51. ON_WM_KILLFOCUS()
  52. ON_WM_SETCURSOR()
  53. ON_WM_LBUTTONUP()
  54. ON_WM_LBUTTONDOWN()
  55. ON_WM_MOUSEMOVE()
  56. ON_COMMAND_RANGE(RANGE_START, (RANGE_START+ LIST_MAX_COUNT), OnSelectSearchString)
  57. ON_WM_EXITSIZEMOVE()
  58. //ON_WM_ERASEBKGND()
  59. ON_WM_NCCALCSIZE()
  60. ON_WM_NCPAINT()
  61. END_MESSAGE_MAP()
  62. BOOL CSymbolEdit::PreTranslateMessage(MSG* pMsg)
  63. {
  64. // TODO: Add your specialized code here and/or call the base class
  65. // Intercept Ctrl + Z (Undo), Ctrl + X (Cut), Ctrl + C (Copy), Ctrl + V (Paste) and Ctrl + A (Select All)
  66. // before CEdit base class gets a hold of them.
  67. if (pMsg->message == WM_KEYDOWN &&
  68. CONTROL_PRESSED)
  69. {
  70. switch (pMsg->wParam)
  71. {
  72. case 'Z':
  73. Undo();
  74. return TRUE;
  75. case 'X':
  76. Cut();
  77. return TRUE;
  78. case 'C':
  79. {
  80. int startChar;
  81. int endChar;
  82. this->GetSel(startChar, endChar);
  83. if (startChar == endChar)
  84. {
  85. CWnd *pWnd = GetParent();
  86. if (pWnd)
  87. {
  88. pWnd->SendMessage(NM_COPY_CLIP, pMsg->wParam, pMsg->lParam);
  89. }
  90. }
  91. else
  92. {
  93. Copy();
  94. }
  95. }
  96. return TRUE;
  97. case 'V':
  98. Paste();
  99. return TRUE;
  100. case 'A':
  101. SetSel(0, -1);
  102. return TRUE;
  103. }
  104. }
  105. switch (pMsg->message)
  106. {
  107. case WM_KEYDOWN:
  108. {
  109. if (pMsg->wParam == VK_RETURN)
  110. {
  111. CWnd *pWnd = GetParent();
  112. if (pWnd)
  113. {
  114. if (g_Opt.m_bFindAsYouType)
  115. {
  116. pWnd->SendMessage(NM_SEARCH_ENTER_PRESSED, 0, 0);
  117. }
  118. else
  119. {
  120. //Send a message to the parent to refill the lb from the search
  121. pWnd->PostMessage(CB_SEARCH, 0, 0);
  122. }
  123. AddToSearchHistory();
  124. }
  125. return TRUE;
  126. }
  127. else if (pMsg->wParam == VK_DOWN &&
  128. ((GetKeyState(VK_CONTROL) & 0x8000) || ((GetKeyState(VK_CONTROL) & 0x8000) && (GetKeyState(VK_SHIFT) & 0x8000))))
  129. {
  130. if (ShowSearchHistoryMenu())
  131. {
  132. return TRUE;
  133. }
  134. }
  135. else if (pMsg->wParam == VK_DOWN ||
  136. pMsg->wParam == VK_UP ||
  137. pMsg->wParam == VK_PRIOR ||
  138. pMsg->wParam == VK_NEXT)
  139. {
  140. CWnd *pWnd = GetParent();
  141. if (pWnd)
  142. {
  143. pWnd->SendMessage(CB_UPDOWN, pMsg->wParam, pMsg->lParam);
  144. return TRUE;
  145. }
  146. }
  147. else if (pMsg->wParam == VK_DELETE)
  148. {
  149. int startChar;
  150. int endChar;
  151. this->GetSel(startChar, endChar);
  152. CString cs;
  153. this->GetWindowText(cs);
  154. //if selection is at the end then forward this on to the parent to delete the selected clip
  155. if(startChar == cs.GetLength() &&
  156. endChar == cs.GetLength())
  157. {
  158. CWnd *pWnd = GetParent();
  159. if (pWnd)
  160. {
  161. pWnd->SendMessage(NM_DELETE, pMsg->wParam, pMsg->lParam);
  162. return TRUE;
  163. }
  164. }
  165. }
  166. break;
  167. }
  168. }
  169. return CEdit::PreTranslateMessage(pMsg);
  170. }
  171. CString CSymbolEdit::SavePastSearches()
  172. {
  173. TiXmlDocument doc;
  174. TiXmlElement* outer = new TiXmlElement("PastSearches");
  175. doc.LinkEndChild(outer);
  176. int count = (int)m_searches.GetCount();
  177. for (int i = 0; i < count; i++)
  178. {
  179. TiXmlElement* searchElement = new TiXmlElement("Search");
  180. CStringA t;
  181. CTextConvert::ConvertToUTF8(m_searches[i], t);
  182. searchElement->SetAttribute("text", t);
  183. outer->LinkEndChild(searchElement);
  184. }
  185. TiXmlPrinter printer;
  186. printer.SetLineBreak("");
  187. doc.Accept(&printer);
  188. CString cs = printer.CStr();
  189. return cs;
  190. }
  191. void CSymbolEdit::LoadPastSearches(CString values)
  192. {
  193. m_searches.RemoveAll();
  194. TiXmlDocument doc;
  195. CStringA xmlA;
  196. CTextConvert::ConvertToUTF8(values, xmlA);
  197. doc.Parse(xmlA);
  198. TiXmlElement *ItemHeader = doc.FirstChildElement("PastSearches");
  199. if (ItemHeader != NULL)
  200. {
  201. TiXmlElement *ItemElement = ItemHeader->FirstChildElement();
  202. while (ItemElement)
  203. {
  204. CString item = ItemElement->Attribute("text");
  205. m_searches.Add(item);
  206. ItemElement = ItemElement->NextSiblingElement();
  207. }
  208. }
  209. }
  210. void CSymbolEdit::AddToSearchHistory()
  211. {
  212. CString cs;
  213. this->GetWindowText(cs);
  214. if (cs != _T(""))
  215. {
  216. if (m_searches.GetCount() >= LIST_MAX_COUNT)
  217. {
  218. m_searches.RemoveAt(0);
  219. }
  220. bool existing = false;
  221. int count = (int)m_searches.GetCount();
  222. for (int i = 0; i < count; i++)
  223. {
  224. if (m_searches[i] == cs)
  225. {
  226. m_searches.RemoveAt(i);
  227. m_searches.Add(cs);
  228. existing = true;
  229. break;
  230. }
  231. }
  232. if (existing == false)
  233. {
  234. m_searches.Add(cs);
  235. }
  236. }
  237. }
  238. bool CSymbolEdit::ShowSearchHistoryMenu()
  239. {
  240. if (m_searches.GetCount() == 0)
  241. {
  242. return false;
  243. }
  244. CMenu cmPopUp;
  245. cmPopUp.CreatePopupMenu();
  246. int count = min((int)m_searches.GetCount(), LIST_MAX_COUNT);
  247. for (int i = count-1; i >= 0; i--)
  248. {
  249. CString text = m_searches[i];
  250. if (i == count - 1 &&
  251. m_lastSearchShortCut.Key > 0)
  252. {
  253. CString cmdShortcutText = CHotKey::GetHotKeyDisplayStatic(m_lastSearchShortCut.Key);
  254. if (m_lastSearchShortCut.Key2 != 0)
  255. {
  256. CString cmdShortcutText2 = CHotKey::GetHotKeyDisplayStatic(m_lastSearchShortCut.Key2);
  257. if (cmdShortcutText2.GetLength() > 0)
  258. {
  259. cmdShortcutText += _T(" - ");
  260. cmdShortcutText += cmdShortcutText2;
  261. }
  262. }
  263. text += "\t";
  264. text += cmdShortcutText;
  265. }
  266. cmPopUp.AppendMenuW(MF_STRING, (RANGE_START + i), text);
  267. }
  268. cmPopUp.AppendMenu(MF_SEPARATOR);
  269. cmPopUp.AppendMenuW(MF_STRING, CLEAR_LIST, _T("Clear List"));
  270. CRect windowRect;
  271. this->GetWindowRect(&windowRect);
  272. POINT pp;
  273. GetCursorPos(&pp);
  274. POINT x = this->GetCaretPos();
  275. ClientToScreen(&x);
  276. x.y += windowRect.Height();
  277. cmPopUp.TrackPopupMenu(TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON, x.x, x.y, this, NULL);
  278. Invalidate();
  279. return true;
  280. }
  281. void CSymbolEdit::DestroyIcon()
  282. {
  283. // if icon was loaded internally, destroy it
  284. if (m_bInternalIcon || m_hSymbolIcon != NULL)
  285. ::DestroyIcon(m_hSymbolIcon);
  286. }
  287. void CSymbolEdit::PreSubclassWindow()
  288. {
  289. RecalcLayout();
  290. }
  291. void CSymbolEdit::SetSymbolIcon(HICON hIcon, BOOL redraw)
  292. {
  293. DestroyIcon();
  294. m_hSymbolIcon = hIcon;
  295. // icon was not loaded internally
  296. m_bInternalIcon = false;
  297. RecalcLayout();
  298. if (redraw)
  299. Invalidate(TRUE);
  300. }
  301. void CSymbolEdit::SetSymbolIcon(UINT id, BOOL redraw)
  302. {
  303. DestroyIcon();
  304. m_hSymbolIcon = (HICON)::LoadImage(
  305. AfxGetResourceHandle(),
  306. MAKEINTRESOURCE(id),
  307. IMAGE_ICON,
  308. 16,
  309. 16,
  310. LR_DEFAULTCOLOR | LR_LOADTRANSPARENT);
  311. ASSERT(m_hSymbolIcon != NULL);
  312. // icon was loaded internally
  313. m_bInternalIcon = true;
  314. RecalcLayout();
  315. if (redraw)
  316. Invalidate(TRUE);
  317. }
  318. void CSymbolEdit::SetPromptText(CString text, BOOL redraw)
  319. {
  320. m_strPromptText = text;
  321. if (redraw)
  322. Invalidate(TRUE);
  323. }
  324. void CSymbolEdit::SetPromptText(LPCTSTR szText, BOOL redraw)
  325. {
  326. m_strPromptText = szText;
  327. if (redraw)
  328. Invalidate(TRUE);
  329. }
  330. void CSymbolEdit::SetPromptTextColor(COLORREF color, BOOL redraw)
  331. {
  332. m_colorPromptText = color;
  333. if (redraw)
  334. Invalidate(TRUE);
  335. }
  336. void CSymbolEdit::SetPromptFont(CFont& font, BOOL redraw)
  337. {
  338. LOGFONT lf;
  339. memset(&lf, 0, sizeof(LOGFONT));
  340. font.GetLogFont(&lf);
  341. SetPromptFont(&lf);
  342. if (redraw)
  343. Invalidate(TRUE);
  344. }
  345. void CSymbolEdit::SetPromptFont(const LOGFONT* lpLogFont, BOOL redraw)
  346. {
  347. m_fontPrompt.DeleteObject();
  348. m_fontPrompt.CreateFontIndirect(lpLogFont);
  349. if (redraw)
  350. Invalidate(TRUE);
  351. }
  352. void CSymbolEdit::RecalcLayout()
  353. {
  354. int width = GetSystemMetrics(SM_CXSMICON);
  355. if (m_hSymbolIcon)
  356. {
  357. DWORD dwMargins = GetMargins();
  358. SetMargins(LOWORD(dwMargins), width + 6);
  359. }
  360. else
  361. {
  362. if (m_windowDpi != NULL)
  363. {
  364. SetMargins(m_windowDpi->Scale(4), m_windowDpi->Scale(34));
  365. }
  366. }
  367. }
  368. // CSymbolEdit message handlers
  369. CString c;
  370. void CSymbolEdit::OnPaint()
  371. {
  372. CPaintDC dc(this);
  373. CRect rect;
  374. GetClientRect(&rect);
  375. DWORD margins = GetMargins();
  376. CRect textRect(rect);
  377. textRect.left += LOWORD(margins);
  378. textRect.right -= HIWORD(margins);
  379. // Clearing the background
  380. dc.FillSolidRect(rect, GetSysColor(COLOR_WINDOW));
  381. if (m_hSymbolIcon)
  382. {
  383. // Drawing the icon
  384. int width = GetSystemMetrics(SM_CXSMICON);
  385. int height = GetSystemMetrics(SM_CYSMICON);
  386. ::DrawIconEx(
  387. dc.m_hDC,
  388. rect.right - width - 1,
  389. 1,
  390. m_hSymbolIcon,
  391. width,
  392. height,
  393. 0,
  394. NULL,
  395. DI_NORMAL);
  396. rect.left += LOWORD(margins) + 1;
  397. rect.right -= (width + 7);
  398. }
  399. else
  400. {
  401. //rect.left += (LOWORD(dwMargins) + 1);
  402. //rect.right -= (HIWORD(dwMargins) + 1);
  403. }
  404. CString text;
  405. GetWindowText(text);
  406. CFont* oldFont = NULL;
  407. //rect.top += 1;
  408. if(this == GetFocus() || text.GetLength() > 0)
  409. {
  410. dc.FillSolidRect(rect, g_Opt.m_Theme.SearchTextBoxFocusBG());
  411. //CBrush borderBrush(g_Opt.m_Theme.SearchTextBoxFocusBorder());
  412. //dc.FrameRect(rect, &borderBrush);
  413. //rect.DeflateRect(1, 1, 1, 1);
  414. //textRect.DeflateRect(0, 1, 1, 1);
  415. oldFont = dc.SelectObject(GetFont());
  416. COLORREF oldColor = dc.GetTextColor();
  417. dc.SetTextColor(g_Opt.m_Theme.SearchTextBoxFocusText());
  418. dc.DrawText(text, textRect, DT_SINGLELINE | DT_INTERNAL | DT_EDITCONTROL | DT_NOPREFIX);
  419. dc.SelectObject(oldFont);
  420. dc.SetTextColor(oldColor);
  421. }
  422. else
  423. {
  424. dc.FillSolidRect(rect, g_Opt.m_Theme.MainWindowBG());
  425. }
  426. if (text.GetLength() == 0 && m_strPromptText.GetLength() > 0)
  427. {
  428. //if we aren't showing the close icon, then use the full space
  429. textRect.right += m_windowDpi->Scale(16);
  430. //textRect.right -= LOWORD(margins);
  431. oldFont = dc.SelectObject(&m_fontPrompt);
  432. COLORREF color = dc.GetTextColor();
  433. dc.SetTextColor(m_colorPromptText);
  434. dc.DrawText(m_strPromptText, textRect, DT_LEFT | DT_SINGLELINE | DT_EDITCONTROL | DT_VCENTER | DT_NOPREFIX);
  435. dc.SetTextColor(color);
  436. dc.SelectObject(oldFont);
  437. }
  438. int right = rect.right;
  439. if ((text.GetLength() > 0 || this == GetFocus()))
  440. {
  441. m_searchesButtonRect.SetRect(rect.right - m_windowDpi->Scale(18), 0, rect.right, rect.bottom);
  442. right = rect.right - m_windowDpi->Scale(18);
  443. m_searchesButton.Draw(&dc, *m_windowDpi, this, m_searchesButtonRect.left, 4, m_mouseHoveringOverSearches, m_mouseDownOnSearches);
  444. }
  445. else
  446. {
  447. m_searchesButtonRect.SetRect(0, 0, 0, 0);
  448. //m_searchButton.Draw(&dc, this, rect.right - 22, 4, false, false);
  449. }
  450. if (text.GetLength() > 0)
  451. {
  452. OutputDebugString(_T("showing close button\n"));
  453. m_closeButtonRect.SetRect(right - m_windowDpi->Scale(16), 0, right, rect.bottom);
  454. m_closeButton.Draw(&dc, *m_windowDpi, this, m_closeButtonRect.left, 4, m_mouseHoveringOverClose, m_mouseDownOnClose);
  455. }
  456. else
  457. {
  458. OutputDebugString(_T("not showing close button\n"));
  459. m_closeButtonRect.SetRect(0, 0, 0, 0);
  460. //m_searchButton.Draw(&dc, this, rect.right - 22, 4, false, false);
  461. }
  462. //OutputDebugString(_T("OnPaint"));
  463. if (text != c)
  464. {
  465. ::SetWindowPos(m_hWnd, NULL, 0, 0, 0, 0, SWP_DRAWFRAME | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
  466. }
  467. c = text;
  468. OutputDebugString(_T("OnPaint \r\n"));
  469. }
  470. void CSymbolEdit::OnSize(UINT nType, int cx, int cy)
  471. {
  472. CEdit::OnSize(nType, cx, cy);
  473. RecalcLayout();
  474. }
  475. LRESULT CSymbolEdit::OnSetFont(WPARAM wParam, LPARAM lParam)
  476. {
  477. DefWindowProc(WM_SETFONT, wParam, lParam);
  478. RecalcLayout();
  479. return 0;
  480. }
  481. HBRUSH CSymbolEdit::CtlColor(CDC* pDC, UINT n)
  482. {
  483. OutputDebugString(_T("CtlColor \r\n"));
  484. //if (m_rectNCTop.IsRectEmpty())
  485. {
  486. SetWindowPos(NULL, 0, 0, 0, 0, SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED);
  487. }
  488. if (::GetFocus() == m_hWnd)
  489. {
  490. pDC->SetTextColor(g_Opt.m_Theme.SearchTextBoxFocusText());
  491. pDC->SetBkColor(g_Opt.m_Theme.SearchTextBoxFocusBG());
  492. return CreateSolidBrush(g_Opt.m_Theme.SearchTextBoxFocusBG());
  493. }
  494. else
  495. {
  496. pDC->SetBkColor(g_Opt.m_Theme.MainWindowBG());
  497. return CreateSolidBrush(g_Opt.m_Theme.MainWindowBG());
  498. }
  499. }
  500. void CSymbolEdit::OnSetFocus(CWnd* pOldWnd)
  501. {
  502. OutputDebugString(_T("OnSetFocus \r\n"));
  503. CEdit::OnSetFocus(pOldWnd);
  504. Invalidate(TRUE);
  505. ::SetWindowPos(m_hWnd, NULL, 0, 0, 0, 0, SWP_DRAWFRAME | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
  506. CWnd *pWnd = GetParent();
  507. if (pWnd)
  508. {
  509. if (g_Opt.m_bFindAsYouType)
  510. {
  511. pWnd->SendMessage(NM_FOCUS_ON_SEARCH, 0, 0);
  512. }
  513. }
  514. }
  515. void CSymbolEdit::OnKillFocus(CWnd* pNewWnd)
  516. {
  517. OutputDebugString(_T("OnKillFocus \r\n"));
  518. AddToSearchHistory();
  519. // ::SetWindowPos(m_hWnd, NULL, 0, 0, 0, 0, SWP_DRAWFRAME | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
  520. Invalidate();
  521. CEdit::OnKillFocus(pNewWnd);
  522. }
  523. BOOL CSymbolEdit::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
  524. {
  525. CPoint pntCursor;
  526. GetCursorPos(&pntCursor);
  527. ScreenToClient(&pntCursor);
  528. if(m_closeButtonRect.PtInRect(pntCursor))
  529. {
  530. HCURSOR h = ::LoadCursor(NULL, IDC_ARROW);
  531. ::SetCursor(h);
  532. return TRUE;
  533. }
  534. if (m_searchesButtonRect.PtInRect(pntCursor))
  535. {
  536. HCURSOR h = ::LoadCursor(NULL, IDC_ARROW);
  537. ::SetCursor(h);
  538. return TRUE;
  539. }
  540. return CEdit::OnSetCursor(pWnd, nHitTest, message);
  541. }
  542. void CSymbolEdit::OnLButtonUp(UINT nFlags, CPoint point)
  543. {
  544. if (m_mouseDownOnClose)
  545. {
  546. ReleaseCapture();
  547. InvalidateRect(m_closeButtonRect);
  548. }
  549. if (m_mouseDownOnSearches)
  550. {
  551. ReleaseCapture();
  552. InvalidateRect(m_searchesButtonRect);
  553. }
  554. m_mouseDownOnClose = false;
  555. m_mouseDownOnSearches = false;
  556. if (m_closeButtonRect.PtInRect(point))
  557. {
  558. if ((GetWindowTextLength() > 0))
  559. {
  560. CWnd *pOwner = GetOwner();
  561. if (pOwner)
  562. {
  563. pOwner->SendMessage(NM_CANCEL_SEARCH, 0, 0);
  564. }
  565. }
  566. }
  567. if (m_searchesButtonRect.PtInRect(point))
  568. {
  569. this->ShowSearchHistoryMenu();
  570. }
  571. CEdit::OnLButtonUp(nFlags, point);
  572. }
  573. void CSymbolEdit::OnLButtonDown(UINT nFlags, CPoint point)
  574. {
  575. if (m_closeButtonRect.PtInRect(point))
  576. {
  577. m_mouseDownOnClose = true;
  578. SetCapture();
  579. InvalidateRect(m_closeButtonRect);
  580. }
  581. else
  582. {
  583. m_mouseDownOnClose = false;
  584. }
  585. if (m_searchesButtonRect.PtInRect(point))
  586. {
  587. m_mouseDownOnSearches = true;
  588. SetCapture();
  589. InvalidateRect(m_searchesButtonRect);
  590. }
  591. else
  592. {
  593. m_mouseDownOnSearches = false;
  594. }
  595. CEdit::OnLButtonDown(nFlags, point);
  596. }
  597. void CSymbolEdit::OnMouseMove(UINT nFlags, CPoint point)
  598. {
  599. if (m_closeButtonRect.PtInRect(point))
  600. {
  601. if (m_mouseHoveringOverClose == false)
  602. {
  603. m_mouseHoveringOverClose = true;
  604. InvalidateRect(m_closeButtonRect);
  605. }
  606. }
  607. else if(m_mouseHoveringOverClose)
  608. {
  609. m_mouseHoveringOverClose = false;
  610. InvalidateRect(m_closeButtonRect);
  611. }
  612. if (m_searchesButtonRect.PtInRect(point))
  613. {
  614. if (m_mouseHoveringOverSearches == false)
  615. {
  616. m_mouseHoveringOverSearches = true;
  617. InvalidateRect(m_searchesButtonRect);
  618. }
  619. }
  620. else if (m_mouseHoveringOverSearches)
  621. {
  622. m_mouseHoveringOverSearches = false;
  623. InvalidateRect(m_searchesButtonRect);
  624. }
  625. CEdit::OnMouseMove(nFlags, point);
  626. }
  627. void CSymbolEdit::OnSelectSearchString(UINT idIn)
  628. {
  629. int index = idIn - RANGE_START;
  630. if (idIn == CLEAR_LIST)
  631. {
  632. m_searches.RemoveAll();
  633. }
  634. else if (index >= 0 &&
  635. index < m_searches.GetCount())
  636. {
  637. CString cs = m_searches[index];
  638. this->SetWindowTextW(cs);
  639. this->SetFocus();
  640. this->SetSel(-1);
  641. this->Invalidate();
  642. m_searches.RemoveAt(index);
  643. m_searches.Add(cs);
  644. }
  645. }
  646. bool CSymbolEdit::ApplyLastSearch()
  647. {
  648. bool ret = false;
  649. if (m_searches.GetCount() > 0)
  650. {
  651. CString cs = m_searches[m_searches.GetCount()-1];
  652. this->SetWindowTextW(cs);
  653. this->SetFocus();
  654. this->SetSel(-1);
  655. this->Invalidate();
  656. ret = true;
  657. }
  658. return ret;
  659. }
  660. void CSymbolEdit::OnDpiChanged()
  661. {
  662. SetDpiInfo(m_windowDpi);
  663. }
  664. void CSymbolEdit::SetDpiInfo(CDPI *dpi)
  665. {
  666. m_windowDpi = dpi;
  667. m_closeButton.Reset();
  668. m_closeButton.LoadStdImageDPI(m_windowDpi->GetDPI(), search_close_16, Search_20, Search_24, Search_28, Search_32, _T("PNG"));
  669. m_searchesButton.Reset();
  670. m_searchesButton.LoadStdImageDPI(m_windowDpi->GetDPI(), down_16, down_20, down_24, down_28, down_32, _T("PNG"));
  671. RecalcLayout();
  672. }
  673. BOOL CSymbolEdit::OnEraseBkgnd(CDC* pDC)
  674. {
  675. // TODO: Add your message handler code here and/or call default
  676. //return CEdit::OnEraseBkgnd(pDC);
  677. return FALSE;
  678. }
  679. void CSymbolEdit::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp)
  680. {
  681. CString text;
  682. GetWindowText(text);
  683. if (text.GetLength() > 0 || this == GetFocus())
  684. {
  685. lpncsp->rgrc[0].left += 1;
  686. lpncsp->rgrc[0].top += 3;
  687. lpncsp->rgrc[0].right -= 1;
  688. lpncsp->rgrc[0].bottom -= 3;
  689. }
  690. CRect rectWnd, rectClient;
  691. ////calculate client area height needed for a font
  692. CFont *pFont = GetFont();
  693. CRect rectText;
  694. CDC *pDC = GetDC();
  695. CFont *pOld = pDC->SelectObject(pFont);
  696. pDC->DrawText("Ky", rectText, DT_CALCRECT | DT_LEFT);
  697. UINT uiVClientHeight = rectText.Height();
  698. pDC->SelectObject(pOld);
  699. ReleaseDC(pDC);
  700. ////calculate NC area to center text.
  701. //GetClientRect(rectClient);
  702. GetWindowRect(rectWnd);
  703. m_centerTextDiff = (rectWnd.Height() - uiVClientHeight) / 2;
  704. //ClientToScreen(rectClient);
  705. //UINT uiCenterOffset = (rectWnd.Height() - uiVClientHeight) / 2;
  706. //UINT uiCY = (rectWnd.Height() - rectClient.Height()) / 2;
  707. //UINT uiCX = (rectWnd.Width() - rectClient.Width()) / 2;
  708. //rectWnd.OffsetRect(-rectWnd.left, -rectWnd.top);
  709. //m_rectNCTop = rectWnd;
  710. //m_rectNCTop.DeflateRect(uiCX, uiCY, uiCX, uiCenterOffset + uiVClientHeight + uiCY);
  711. //m_rectNCBottom = rectWnd;
  712. //m_rectNCBottom.DeflateRect(uiCX, uiCenterOffset + uiVClientHeight + uiCY, uiCX, uiCY);
  713. //lpncsp->rgrc[0].top += uiCenterOffset;
  714. //lpncsp->rgrc[0].bottom -= uiCenterOffset;
  715. //lpncsp->rgrc[0].left += uiCX;
  716. //lpncsp->rgrc[0].right -= uiCY;
  717. //CEdit::OnNcCalcSize(bCalcValidRects, lpncsp);
  718. }
  719. void CSymbolEdit::OnNcPaint()
  720. {
  721. //Default();
  722. CString text;
  723. GetWindowText(text);
  724. CWindowDC dc(this);
  725. CRect r;
  726. this->GetWindowRect(r);
  727. this->ScreenToClient(r);
  728. CRect t(0, 0, r.Width(), m_centerTextDiff);
  729. CRect b(0, r.Height() - m_centerTextDiff, r.Width(), r.Height());
  730. if (this == GetFocus() || text.GetLength() > 0)
  731. {
  732. dc.FillSolidRect(t, g_Opt.m_Theme.SearchTextBoxFocusBG());
  733. dc.FillSolidRect(b, g_Opt.m_Theme.SearchTextBoxFocusBG());
  734. }
  735. else
  736. {
  737. dc.FillSolidRect(t, g_Opt.m_Theme.MainWindowBG());
  738. dc.FillSolidRect(b, g_Opt.m_Theme.MainWindowBG());
  739. }
  740. if ((text.GetLength() > 0 || this == GetFocus()) && m_windowDpi)
  741. {
  742. CWindowDC dc(this);
  743. CRect rcFrame;
  744. this->GetWindowRect(rcFrame);
  745. this->ScreenToClient(rcFrame);
  746. CRect rcBorder(0, 0, rcFrame.Width(), rcFrame.Height());
  747. int border = m_windowDpi->Scale(1);
  748. CBrush borderBrush(g_Opt.m_Theme.SearchTextBoxFocusBorder());
  749. for (int x = 0; x < border; x++)
  750. {
  751. dc.FrameRect(rcBorder, &borderBrush);
  752. rcBorder.DeflateRect(1, 1, 1, 1);
  753. }
  754. }
  755. OutputDebugString(_T("OnNCPaint \r\n"));
  756. }
  757. //
  758. //void CSymbolEdit::SetWindowTextEx(LPCTSTR str)
  759. //{
  760. // this->SetWindowText(str);
  761. // ::SetWindowPos(m_hWnd, NULL, 0, 0, 0, 0, SWP_DRAWFRAME | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);;
  762. // Invalidate();
  763. //}