SymbolEdit.cpp 21 KB

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