OLD | NEW |
| (Empty) |
1 // Copyright 2014 PDFium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | |
6 | |
7 #include "fpdfsdk/include/pdfwindow/PWL_Note.h" | |
8 | |
9 #include "fpdfsdk/include/pdfwindow/PWL_Button.h" | |
10 #include "fpdfsdk/include/pdfwindow/PWL_Caret.h" | |
11 #include "fpdfsdk/include/pdfwindow/PWL_Edit.h" | |
12 #include "fpdfsdk/include/pdfwindow/PWL_EditCtrl.h" | |
13 #include "fpdfsdk/include/pdfwindow/PWL_Label.h" | |
14 #include "fpdfsdk/include/pdfwindow/PWL_ListCtrl.h" | |
15 #include "fpdfsdk/include/pdfwindow/PWL_ScrollBar.h" | |
16 #include "fpdfsdk/include/pdfwindow/PWL_Utils.h" | |
17 #include "fpdfsdk/include/pdfwindow/PWL_Wnd.h" | |
18 | |
19 #define POPUP_ITEM_HEAD_BOTTOM 3.0f | |
20 #define POPUP_ITEM_BOTTOMWIDTH 1.0f | |
21 #define POPUP_ITEM_SIDEMARGIN 3.0f | |
22 #define POPUP_ITEM_SPACE 4.0f | |
23 #define POPUP_ITEM_TEXT_INDENT 2.0f | |
24 #define POPUP_ITEM_BORDERCOLOR \ | |
25 CPWL_Color(COLORTYPE_RGB, 80 / 255.0f, 80 / 255.0f, 80 / 255.0f) | |
26 | |
27 #define IsFloatZero(f) ((f) < 0.0001 && (f) > -0.0001) | |
28 #define IsFloatBigger(fa, fb) ((fa) > (fb) && !IsFloatZero((fa) - (fb))) | |
29 #define IsFloatSmaller(fa, fb) ((fa) < (fb) && !IsFloatZero((fa) - (fb))) | |
30 #define IsFloatEqual(fa, fb) IsFloatZero((fa) - (fb)) | |
31 | |
32 CPWL_Note_Options::CPWL_Note_Options() : m_pText(NULL) {} | |
33 | |
34 CPWL_Note_Options::~CPWL_Note_Options() {} | |
35 | |
36 void CPWL_Note_Options::SetTextColor(const CPWL_Color& color) { | |
37 CPWL_Wnd::SetTextColor(color); | |
38 | |
39 if (m_pText) | |
40 m_pText->SetTextColor(color); | |
41 } | |
42 | |
43 void CPWL_Note_Options::RePosChildWnd() { | |
44 if (IsValid()) { | |
45 CFX_FloatRect rcClient = GetClientRect(); | |
46 | |
47 if (rcClient.Width() > 15.0f) { | |
48 rcClient.right -= 15.0f; | |
49 m_pText->Move(rcClient, TRUE, FALSE); | |
50 m_pText->SetVisible(TRUE); | |
51 } else { | |
52 m_pText->Move(CFX_FloatRect(0, 0, 0, 0), TRUE, FALSE); | |
53 m_pText->SetVisible(FALSE); | |
54 } | |
55 } | |
56 } | |
57 | |
58 void CPWL_Note_Options::CreateChildWnd(const PWL_CREATEPARAM& cp) { | |
59 m_pText = new CPWL_Label; | |
60 PWL_CREATEPARAM tcp = cp; | |
61 tcp.pParentWnd = this; | |
62 tcp.dwFlags = PWS_CHILD | PWS_VISIBLE; | |
63 m_pText->Create(tcp); | |
64 } | |
65 | |
66 void CPWL_Note_Options::SetText(const CFX_WideString& sText) { | |
67 m_pText->SetText(sText.c_str()); | |
68 } | |
69 | |
70 void CPWL_Note_Options::DrawThisAppearance(CFX_RenderDevice* pDevice, | |
71 CFX_Matrix* pUser2Device) { | |
72 CPWL_Wnd::DrawThisAppearance(pDevice, pUser2Device); | |
73 | |
74 CFX_FloatRect rcClient = GetClientRect(); | |
75 rcClient.left = rcClient.right - 15.0f; | |
76 | |
77 CFX_FloatPoint ptCenter = | |
78 CFX_FloatPoint((rcClient.left + rcClient.right) * 0.5f, | |
79 (rcClient.top + rcClient.bottom) * 0.5f); | |
80 | |
81 CFX_FloatPoint pt1(ptCenter.x - 2.0f, ptCenter.y + 2.0f * 0.5f); | |
82 CFX_FloatPoint pt2(ptCenter.x + 2.0f, ptCenter.y + 2.0f * 0.5f); | |
83 CFX_FloatPoint pt3(ptCenter.x, ptCenter.y - 3.0f * 0.5f); | |
84 | |
85 CFX_PathData path; | |
86 | |
87 path.SetPointCount(4); | |
88 path.SetPoint(0, pt1.x, pt1.y, FXPT_MOVETO); | |
89 path.SetPoint(1, pt2.x, pt2.y, FXPT_LINETO); | |
90 path.SetPoint(2, pt3.x, pt3.y, FXPT_LINETO); | |
91 path.SetPoint(3, pt1.x, pt1.y, FXPT_LINETO); | |
92 | |
93 pDevice->DrawPath( | |
94 &path, pUser2Device, NULL, | |
95 CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()), 0, | |
96 FXFILL_ALTERNATE); | |
97 } | |
98 | |
99 CFX_FloatRect CPWL_Note_Options::GetContentRect() const { | |
100 CFX_FloatRect rcText = m_pText->GetContentRect(); | |
101 rcText.right += 15.0f; | |
102 return rcText; | |
103 } | |
104 | |
105 CPWL_Note_Edit::CPWL_Note_Edit() | |
106 : m_bEnableNotify(TRUE), | |
107 m_fOldItemHeight(0.0f), | |
108 m_bSizeChanged(FALSE), | |
109 m_fOldMin(0.0f), | |
110 m_fOldMax(0.0f) {} | |
111 | |
112 CPWL_Note_Edit::~CPWL_Note_Edit() {} | |
113 | |
114 void CPWL_Note_Edit::RePosChildWnd() { | |
115 m_bEnableNotify = FALSE; | |
116 CPWL_Edit::RePosChildWnd(); | |
117 m_bEnableNotify = TRUE; | |
118 | |
119 m_fOldItemHeight = GetContentRect().Height(); | |
120 } | |
121 | |
122 void CPWL_Note_Edit::SetText(const FX_WCHAR* csText) { | |
123 m_bEnableNotify = FALSE; | |
124 CPWL_Edit::SetText(csText); | |
125 m_bEnableNotify = TRUE; | |
126 m_fOldItemHeight = GetContentRect().Height(); | |
127 } | |
128 | |
129 void CPWL_Note_Edit::OnSetFocus() { | |
130 m_bEnableNotify = FALSE; | |
131 CPWL_Edit::OnSetFocus(); | |
132 m_bEnableNotify = TRUE; | |
133 | |
134 EnableSpellCheck(TRUE); | |
135 } | |
136 | |
137 void CPWL_Note_Edit::OnKillFocus() { | |
138 EnableSpellCheck(FALSE); | |
139 | |
140 if (CPWL_Wnd* pParent = GetParentWindow()) { | |
141 if (CPWL_Wnd* pGrand = pParent->GetParentWindow()) { | |
142 ASSERT(pGrand->GetClassName() == "CPWL_NoteItem"); | |
143 | |
144 CPWL_NoteItem* pNoteItem = (CPWL_NoteItem*)pGrand; | |
145 | |
146 pNoteItem->OnContentsValidate(); | |
147 } | |
148 } | |
149 | |
150 CPWL_Edit::OnKillFocus(); | |
151 } | |
152 | |
153 void CPWL_Note_Edit::OnNotify(CPWL_Wnd* pWnd, | |
154 FX_DWORD msg, | |
155 intptr_t wParam, | |
156 intptr_t lParam) { | |
157 if (m_bEnableNotify) { | |
158 if (wParam == SBT_VSCROLL) { | |
159 switch (msg) { | |
160 case PNM_SETSCROLLINFO: | |
161 if (PWL_SCROLL_INFO* pInfo = (PWL_SCROLL_INFO*)lParam) { | |
162 if (!IsFloatEqual(pInfo->fContentMax, m_fOldMax) || | |
163 !IsFloatEqual(pInfo->fContentMin, m_fOldMin)) { | |
164 m_bSizeChanged = TRUE; | |
165 if (CPWL_Wnd* pParent = GetParentWindow()) { | |
166 pParent->OnNotify(this, PNM_NOTEEDITCHANGED, 0, 0); | |
167 } | |
168 | |
169 m_fOldMax = pInfo->fContentMax; | |
170 m_fOldMin = pInfo->fContentMin; | |
171 return; | |
172 } | |
173 } | |
174 } | |
175 } | |
176 } | |
177 | |
178 CPWL_Edit::OnNotify(pWnd, msg, wParam, lParam); | |
179 | |
180 if (m_bEnableNotify) { | |
181 switch (msg) { | |
182 case PNM_SETCARETINFO: | |
183 if (PWL_CARET_INFO* pInfo = (PWL_CARET_INFO*)wParam) { | |
184 PWL_CARET_INFO newInfo = *pInfo; | |
185 newInfo.bVisible = TRUE; | |
186 newInfo.ptHead = ChildToParent(pInfo->ptHead); | |
187 newInfo.ptFoot = ChildToParent(pInfo->ptFoot); | |
188 | |
189 if (CPWL_Wnd* pParent = GetParentWindow()) { | |
190 pParent->OnNotify(this, PNM_SETCARETINFO, (intptr_t)&newInfo, 0); | |
191 } | |
192 } | |
193 break; | |
194 } | |
195 } | |
196 } | |
197 | |
198 FX_FLOAT CPWL_Note_Edit::GetItemHeight(FX_FLOAT fLimitWidth) { | |
199 if (fLimitWidth > 0) { | |
200 if (!m_bSizeChanged) | |
201 return m_fOldItemHeight; | |
202 | |
203 m_bSizeChanged = FALSE; | |
204 | |
205 EnableNotify(FALSE); | |
206 EnableRefresh(FALSE); | |
207 m_pEdit->EnableNotify(FALSE); | |
208 | |
209 Move(CFX_FloatRect(0, 0, fLimitWidth, 0), TRUE, FALSE); | |
210 FX_FLOAT fRet = GetContentRect().Height(); | |
211 | |
212 m_pEdit->EnableNotify(TRUE); | |
213 EnableNotify(TRUE); | |
214 EnableRefresh(TRUE); | |
215 | |
216 return fRet; | |
217 } | |
218 | |
219 return 0; | |
220 } | |
221 | |
222 FX_FLOAT CPWL_Note_Edit::GetItemLeftMargin() { | |
223 return POPUP_ITEM_TEXT_INDENT; | |
224 } | |
225 | |
226 FX_FLOAT CPWL_Note_Edit::GetItemRightMargin() { | |
227 return POPUP_ITEM_TEXT_INDENT; | |
228 } | |
229 | |
230 CPWL_Note_LBBox::CPWL_Note_LBBox() {} | |
231 | |
232 CPWL_Note_LBBox::~CPWL_Note_LBBox() {} | |
233 | |
234 void CPWL_Note_LBBox::DrawThisAppearance(CFX_RenderDevice* pDevice, | |
235 CFX_Matrix* pUser2Device) { | |
236 CFX_FloatRect rcClient = GetClientRect(); | |
237 | |
238 CFX_GraphStateData gsd; | |
239 gsd.m_LineWidth = 1.0f; | |
240 | |
241 CFX_PathData pathCross; | |
242 | |
243 pathCross.SetPointCount(4); | |
244 pathCross.SetPoint(0, rcClient.left, rcClient.top, FXPT_MOVETO); | |
245 pathCross.SetPoint(1, rcClient.right, rcClient.bottom, FXPT_LINETO); | |
246 pathCross.SetPoint(2, rcClient.left, | |
247 rcClient.bottom + rcClient.Height() * 0.5f, FXPT_MOVETO); | |
248 pathCross.SetPoint(3, rcClient.left + rcClient.Width() * 0.5f, | |
249 rcClient.bottom, FXPT_LINETO); | |
250 | |
251 pDevice->DrawPath( | |
252 &pathCross, pUser2Device, &gsd, 0, | |
253 CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()), | |
254 FXFILL_ALTERNATE); | |
255 } | |
256 | |
257 CPWL_Note_RBBox::CPWL_Note_RBBox() {} | |
258 | |
259 CPWL_Note_RBBox::~CPWL_Note_RBBox() {} | |
260 | |
261 void CPWL_Note_RBBox::DrawThisAppearance(CFX_RenderDevice* pDevice, | |
262 CFX_Matrix* pUser2Device) { | |
263 CFX_FloatRect rcClient = GetClientRect(); | |
264 | |
265 CFX_GraphStateData gsd; | |
266 gsd.m_LineWidth = 1.0f; | |
267 | |
268 CFX_PathData pathCross; | |
269 | |
270 pathCross.SetPointCount(4); | |
271 pathCross.SetPoint(0, rcClient.right, rcClient.top, FXPT_MOVETO); | |
272 pathCross.SetPoint(1, rcClient.left, rcClient.bottom, FXPT_LINETO); | |
273 pathCross.SetPoint(2, rcClient.right, | |
274 rcClient.bottom + rcClient.Height() * 0.5f, FXPT_MOVETO); | |
275 pathCross.SetPoint(3, rcClient.left + rcClient.Width() * 0.5f, | |
276 rcClient.bottom, FXPT_LINETO); | |
277 | |
278 pDevice->DrawPath( | |
279 &pathCross, pUser2Device, &gsd, 0, | |
280 CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()), | |
281 FXFILL_ALTERNATE); | |
282 } | |
283 | |
284 CPWL_Note_Icon::CPWL_Note_Icon() : m_nType(0) {} | |
285 | |
286 CPWL_Note_Icon::~CPWL_Note_Icon() {} | |
287 | |
288 void CPWL_Note_Icon::SetIconType(int32_t nType) { | |
289 m_nType = nType; | |
290 } | |
291 | |
292 void CPWL_Note_Icon::DrawThisAppearance(CFX_RenderDevice* pDevice, | |
293 CFX_Matrix* pUser2Device) { | |
294 CPWL_Utils::DrawIconAppStream(pDevice, pUser2Device, m_nType, GetClientRect(), | |
295 GetBackgroundColor(), PWL_DEFAULT_BLACKCOLOR, | |
296 GetTransparency()); | |
297 } | |
298 | |
299 CPWL_Note_CloseBox::CPWL_Note_CloseBox() : m_bMouseDown(FALSE) {} | |
300 | |
301 CPWL_Note_CloseBox::~CPWL_Note_CloseBox() {} | |
302 | |
303 void CPWL_Note_CloseBox::DrawThisAppearance(CFX_RenderDevice* pDevice, | |
304 CFX_Matrix* pUser2Device) { | |
305 CPWL_Button::DrawThisAppearance(pDevice, pUser2Device); | |
306 | |
307 CFX_FloatRect rcClient = GetClientRect(); | |
308 rcClient = CPWL_Utils::DeflateRect(rcClient, 2.0f); | |
309 | |
310 CFX_GraphStateData gsd; | |
311 gsd.m_LineWidth = 1.0f; | |
312 | |
313 CFX_PathData pathCross; | |
314 | |
315 if (m_bMouseDown) { | |
316 rcClient.left += 0.5f; | |
317 rcClient.right += 0.5f; | |
318 rcClient.top -= 0.5f; | |
319 rcClient.bottom -= 0.5f; | |
320 } | |
321 | |
322 pathCross.SetPointCount(4); | |
323 pathCross.SetPoint(0, rcClient.left, rcClient.bottom, FXPT_MOVETO); | |
324 pathCross.SetPoint(1, rcClient.right, rcClient.top, FXPT_LINETO); | |
325 pathCross.SetPoint(2, rcClient.left, rcClient.top, FXPT_MOVETO); | |
326 pathCross.SetPoint(3, rcClient.right, rcClient.bottom, FXPT_LINETO); | |
327 | |
328 pDevice->DrawPath( | |
329 &pathCross, pUser2Device, &gsd, 0, | |
330 CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()), | |
331 FXFILL_ALTERNATE); | |
332 } | |
333 | |
334 FX_BOOL CPWL_Note_CloseBox::OnLButtonDown(const CFX_FloatPoint& point, | |
335 FX_DWORD nFlag) { | |
336 SetBorderStyle(PBS_INSET); | |
337 InvalidateRect(NULL); | |
338 | |
339 m_bMouseDown = TRUE; | |
340 | |
341 return CPWL_Button::OnLButtonDown(point, nFlag); | |
342 } | |
343 | |
344 FX_BOOL CPWL_Note_CloseBox::OnLButtonUp(const CFX_FloatPoint& point, | |
345 FX_DWORD nFlag) { | |
346 m_bMouseDown = FALSE; | |
347 | |
348 SetBorderStyle(PBS_BEVELED); | |
349 InvalidateRect(NULL); | |
350 | |
351 return CPWL_Button::OnLButtonUp(point, nFlag); | |
352 } | |
353 | |
354 CPWL_Note_Contents::CPWL_Note_Contents() : m_pEdit(NULL) {} | |
355 | |
356 CPWL_Note_Contents::~CPWL_Note_Contents() {} | |
357 | |
358 CFX_ByteString CPWL_Note_Contents::GetClassName() const { | |
359 return "CPWL_Note_Contents"; | |
360 } | |
361 | |
362 void CPWL_Note_Contents::CreateChildWnd(const PWL_CREATEPARAM& cp) { | |
363 m_pEdit = new CPWL_Note_Edit; | |
364 PWL_CREATEPARAM ecp = cp; | |
365 ecp.pParentWnd = this; | |
366 ecp.dwFlags = PWS_VISIBLE | PWS_CHILD | PES_MULTILINE | PES_AUTORETURN | | |
367 PES_TEXTOVERFLOW | PES_UNDO | PES_SPELLCHECK; | |
368 | |
369 m_pEdit->EnableNotify(FALSE); | |
370 m_pEdit->Create(ecp); | |
371 m_pEdit->EnableNotify(TRUE); | |
372 } | |
373 | |
374 void CPWL_Note_Contents::SetText(const CFX_WideString& sText) { | |
375 if (m_pEdit) { | |
376 m_pEdit->EnableNotify(FALSE); | |
377 m_pEdit->SetText(sText.c_str()); | |
378 m_pEdit->EnableNotify(TRUE); | |
379 OnNotify(m_pEdit, PNM_NOTEEDITCHANGED, 0, 0); | |
380 } | |
381 } | |
382 | |
383 CFX_WideString CPWL_Note_Contents::GetText() const { | |
384 if (m_pEdit) | |
385 return m_pEdit->GetText(); | |
386 | |
387 return L""; | |
388 } | |
389 | |
390 CPWL_NoteItem* CPWL_Note_Contents::CreateSubItem() { | |
391 CPWL_NoteItem* pNoteItem = new CPWL_NoteItem; | |
392 PWL_CREATEPARAM icp = GetCreationParam(); | |
393 icp.pParentWnd = this; | |
394 icp.dwFlags = PWS_CHILD | PWS_VISIBLE | PWS_BACKGROUND; | |
395 pNoteItem->Create(icp); | |
396 | |
397 pNoteItem->OnCreateNoteItem(); | |
398 | |
399 pNoteItem->ResetSubjectName(m_aChildren.GetSize() - 1); | |
400 | |
401 FX_SYSTEMTIME st; | |
402 if (IFX_SystemHandler* pSH = GetSystemHandler()) | |
403 st = pSH->GetLocalTime(); | |
404 pNoteItem->SetDateTime(st); | |
405 | |
406 pNoteItem->SetContents(L""); | |
407 | |
408 OnNotify(pNoteItem, PNM_NOTEEDITCHANGED, 0, 0); | |
409 | |
410 return pNoteItem; | |
411 } | |
412 | |
413 int32_t CPWL_Note_Contents::CountSubItems() const { | |
414 return m_aChildren.GetSize() - 1; | |
415 } | |
416 | |
417 IPWL_NoteItem* CPWL_Note_Contents::GetSubItems(int32_t index) const { | |
418 int32_t nIndex = index + 1; | |
419 | |
420 if (nIndex > 0 && nIndex < m_aChildren.GetSize()) { | |
421 if (CPWL_Wnd* pChild = m_aChildren.GetAt(nIndex)) { | |
422 ASSERT(pChild->GetClassName() == "CPWL_NoteItem"); | |
423 CPWL_NoteItem* pItem = (CPWL_NoteItem*)pChild; | |
424 return pItem; | |
425 } | |
426 } | |
427 return NULL; | |
428 } | |
429 | |
430 void CPWL_Note_Contents::DeleteSubItem(IPWL_NoteItem* pNoteItem) { | |
431 int32_t nIndex = GetItemIndex((CPWL_NoteItem*)pNoteItem); | |
432 | |
433 if (nIndex > 0) { | |
434 if (CPWL_NoteItem* pPWLNoteItem = (CPWL_NoteItem*)pNoteItem) { | |
435 pPWLNoteItem->KillFocus(); | |
436 pPWLNoteItem->Destroy(); | |
437 delete pPWLNoteItem; | |
438 } | |
439 | |
440 for (int32_t i = nIndex, sz = m_aChildren.GetSize(); i < sz; i++) { | |
441 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) { | |
442 ASSERT(pChild->GetClassName() == "CPWL_NoteItem"); | |
443 CPWL_NoteItem* pItem = (CPWL_NoteItem*)pChild; | |
444 pItem->ResetSubjectName(i); | |
445 } | |
446 } | |
447 | |
448 OnNotify(this, PNM_NOTEEDITCHANGED, 0, 0); | |
449 } | |
450 } | |
451 | |
452 IPWL_NoteItem* CPWL_Note_Contents::GetHitNoteItem(const CFX_FloatPoint& point) { | |
453 CFX_FloatPoint pt = ParentToChild(point); | |
454 | |
455 for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) { | |
456 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) { | |
457 if (pChild->GetClassName() == "CPWL_NoteItem") { | |
458 CPWL_NoteItem* pNoteItem = (CPWL_NoteItem*)pChild; | |
459 if (IPWL_NoteItem* pRet = pNoteItem->GetHitNoteItem(pt)) | |
460 return pRet; | |
461 } | |
462 } | |
463 } | |
464 return NULL; | |
465 } | |
466 | |
467 void CPWL_Note_Contents::OnNotify(CPWL_Wnd* pWnd, | |
468 FX_DWORD msg, | |
469 intptr_t wParam, | |
470 intptr_t lParam) { | |
471 switch (msg) { | |
472 case PNM_NOTEEDITCHANGED: { | |
473 int32_t nIndex = GetItemIndex(pWnd); | |
474 if (nIndex < 0) | |
475 nIndex = 0; | |
476 | |
477 m_pEdit->EnableNotify(FALSE); | |
478 ResetContent(nIndex); | |
479 m_pEdit->EnableNotify(TRUE); | |
480 | |
481 for (int32_t i = nIndex + 1, sz = m_aChildren.GetSize(); i < sz; i++) { | |
482 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) | |
483 pChild->OnNotify(this, PNM_NOTERESET, 0, 0); | |
484 } | |
485 | |
486 if (CPWL_Wnd* pParent = GetParentWindow()) { | |
487 pParent->OnNotify(this, PNM_NOTEEDITCHANGED, 0, 0); | |
488 } | |
489 } | |
490 return; | |
491 case PNM_SCROLLWINDOW: | |
492 SetScrollPos(CFX_FloatPoint(0.0f, *(FX_FLOAT*)lParam)); | |
493 ResetFace(); | |
494 InvalidateRect(NULL); | |
495 return; | |
496 case PNM_SETCARETINFO: | |
497 if (PWL_CARET_INFO* pInfo = (PWL_CARET_INFO*)wParam) { | |
498 PWL_CARET_INFO newInfo = *pInfo; | |
499 newInfo.bVisible = TRUE; | |
500 newInfo.ptHead = ChildToParent(pInfo->ptHead); | |
501 newInfo.ptFoot = ChildToParent(pInfo->ptFoot); | |
502 | |
503 if (CPWL_Wnd* pParent = GetParentWindow()) { | |
504 pParent->OnNotify(this, PNM_SETCARETINFO, (intptr_t)&newInfo, 0); | |
505 } | |
506 } | |
507 return; | |
508 case PNM_NOTERESET: { | |
509 m_pEdit->EnableNotify(FALSE); | |
510 ResetContent(0); | |
511 m_pEdit->EnableNotify(TRUE); | |
512 | |
513 for (int32_t i = 1, sz = m_aChildren.GetSize(); i < sz; i++) { | |
514 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) | |
515 pChild->OnNotify(this, PNM_NOTERESET, 0, 0); | |
516 } | |
517 | |
518 m_pEdit->EnableNotify(FALSE); | |
519 ResetContent(0); | |
520 m_pEdit->EnableNotify(TRUE); | |
521 } | |
522 return; | |
523 } | |
524 | |
525 CPWL_Wnd::OnNotify(pWnd, msg, wParam, lParam); | |
526 } | |
527 | |
528 FX_BOOL CPWL_Note_Contents::OnLButtonDown(const CFX_FloatPoint& point, | |
529 FX_DWORD nFlag) { | |
530 if (CPWL_Wnd::OnLButtonDown(point, nFlag)) | |
531 return TRUE; | |
532 | |
533 if (!m_pEdit->IsFocused()) { | |
534 m_pEdit->SetFocus(); | |
535 } | |
536 | |
537 return TRUE; | |
538 } | |
539 | |
540 void CPWL_Note_Contents::SetEditFocus(FX_BOOL bLast) { | |
541 if (!m_pEdit->IsFocused()) { | |
542 m_pEdit->SetFocus(); | |
543 m_pEdit->SetCaret(bLast ? m_pEdit->GetTotalWords() : 0); | |
544 } | |
545 } | |
546 | |
547 CPWL_Edit* CPWL_Note_Contents::GetEdit() const { | |
548 return m_pEdit; | |
549 } | |
550 | |
551 void CPWL_Note_Contents::EnableModify(FX_BOOL bEnabled) { | |
552 if (!bEnabled) | |
553 m_pEdit->AddFlag(PWS_READONLY); | |
554 else | |
555 m_pEdit->RemoveFlag(PWS_READONLY); | |
556 | |
557 for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) { | |
558 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) { | |
559 if (pChild->GetClassName() == "CPWL_NoteItem") { | |
560 CPWL_NoteItem* pNoteItem = (CPWL_NoteItem*)pChild; | |
561 pNoteItem->EnableModify(bEnabled); | |
562 } | |
563 } | |
564 } | |
565 } | |
566 | |
567 void CPWL_Note_Contents::EnableRead(FX_BOOL bEnabled) { | |
568 if (!bEnabled) | |
569 m_pEdit->AddFlag(PES_NOREAD); | |
570 else | |
571 m_pEdit->RemoveFlag(PES_NOREAD); | |
572 | |
573 for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) { | |
574 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) { | |
575 if (pChild->GetClassName() == "CPWL_NoteItem") { | |
576 CPWL_NoteItem* pNoteItem = (CPWL_NoteItem*)pChild; | |
577 pNoteItem->EnableRead(bEnabled); | |
578 } | |
579 } | |
580 } | |
581 } | |
582 | |
583 CPWL_NoteItem::CPWL_NoteItem() | |
584 : m_pSubject(NULL), | |
585 m_pDateTime(NULL), | |
586 m_pContents(NULL), | |
587 m_pPrivateData(NULL), | |
588 m_sAuthor(L""), | |
589 m_fOldItemHeight(0.0f), | |
590 m_bSizeChanged(FALSE), | |
591 m_bAllowModify(TRUE) {} | |
592 | |
593 CPWL_NoteItem::~CPWL_NoteItem() {} | |
594 | |
595 CFX_ByteString CPWL_NoteItem::GetClassName() const { | |
596 return "CPWL_NoteItem"; | |
597 } | |
598 | |
599 void CPWL_NoteItem::CreateChildWnd(const PWL_CREATEPARAM& cp) { | |
600 CPWL_Color sTextColor; | |
601 | |
602 if (CPWL_Utils::IsBlackOrWhite(GetBackgroundColor())) | |
603 sTextColor = PWL_DEFAULT_WHITECOLOR; | |
604 else | |
605 sTextColor = PWL_DEFAULT_BLACKCOLOR; | |
606 | |
607 m_pSubject = new CPWL_Label; | |
608 PWL_CREATEPARAM scp = cp; | |
609 scp.pParentWnd = this; | |
610 scp.dwFlags = PWS_VISIBLE | PWS_CHILD | PES_LEFT | PES_TOP; | |
611 scp.sTextColor = sTextColor; | |
612 m_pSubject->Create(scp); | |
613 | |
614 m_pDateTime = new CPWL_Label; | |
615 PWL_CREATEPARAM dcp = cp; | |
616 dcp.pParentWnd = this; | |
617 dcp.dwFlags = PWS_VISIBLE | PWS_CHILD | PES_RIGHT | PES_TOP; | |
618 dcp.sTextColor = sTextColor; | |
619 m_pDateTime->Create(dcp); | |
620 | |
621 m_pContents = new CPWL_Note_Contents; | |
622 PWL_CREATEPARAM ccp = cp; | |
623 ccp.pParentWnd = this; | |
624 ccp.sBackgroundColor = | |
625 CPWL_Color(COLORTYPE_RGB, 240 / 255.0f, 240 / 255.0f, 240 / 255.0f); | |
626 ccp.dwFlags = PWS_VISIBLE | PWS_CHILD | PWS_BACKGROUND; | |
627 m_pContents->Create(ccp); | |
628 m_pContents->SetItemSpace(POPUP_ITEM_SPACE); | |
629 m_pContents->SetTopSpace(POPUP_ITEM_SPACE); | |
630 m_pContents->SetBottomSpace(POPUP_ITEM_SPACE); | |
631 } | |
632 | |
633 void CPWL_NoteItem::RePosChildWnd() { | |
634 if (IsValid()) { | |
635 CFX_FloatRect rcClient = GetClientRect(); | |
636 | |
637 CFX_FloatRect rcSubject = rcClient; | |
638 rcSubject.left += POPUP_ITEM_TEXT_INDENT; | |
639 rcSubject.top = rcClient.top; | |
640 rcSubject.right = | |
641 PWL_MIN(rcSubject.left + m_pSubject->GetContentRect().Width() + 1.0f, | |
642 rcClient.right); | |
643 rcSubject.bottom = rcSubject.top - m_pSubject->GetContentRect().Height(); | |
644 rcSubject.Normalize(); | |
645 m_pSubject->Move(rcSubject, TRUE, FALSE); | |
646 m_pSubject->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcSubject)); | |
647 | |
648 CFX_FloatRect rcDate = rcClient; | |
649 rcDate.right -= POPUP_ITEM_TEXT_INDENT; | |
650 rcDate.left = | |
651 PWL_MAX(rcDate.right - m_pDateTime->GetContentRect().Width() - 1.0f, | |
652 rcSubject.right); | |
653 rcDate.bottom = rcDate.top - m_pDateTime->GetContentRect().Height(); | |
654 rcDate.Normalize(); | |
655 m_pDateTime->Move(rcDate, TRUE, FALSE); | |
656 m_pDateTime->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcDate)); | |
657 | |
658 CFX_FloatRect rcContents = rcClient; | |
659 rcContents.left += 1.0f; | |
660 rcContents.right -= 1.0f; | |
661 rcContents.top = rcDate.bottom - POPUP_ITEM_HEAD_BOTTOM; | |
662 rcContents.bottom += POPUP_ITEM_BOTTOMWIDTH; | |
663 rcContents.Normalize(); | |
664 m_pContents->Move(rcContents, TRUE, FALSE); | |
665 m_pContents->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcContents)); | |
666 } | |
667 | |
668 SetClipRect(CPWL_Utils::InflateRect(GetWindowRect(), 1.0f)); | |
669 } | |
670 | |
671 void CPWL_NoteItem::SetPrivateData(void* pData) { | |
672 m_pPrivateData = pData; | |
673 } | |
674 | |
675 void CPWL_NoteItem::SetBkColor(const CPWL_Color& color) { | |
676 CPWL_Color sBK = color; | |
677 SetBackgroundColor(sBK); | |
678 | |
679 CPWL_Color sTextColor; | |
680 | |
681 if (CPWL_Utils::IsBlackOrWhite(sBK)) | |
682 sTextColor = PWL_DEFAULT_WHITECOLOR; | |
683 else | |
684 sTextColor = PWL_DEFAULT_BLACKCOLOR; | |
685 | |
686 SetTextColor(sTextColor); | |
687 if (m_pSubject) | |
688 m_pSubject->SetTextColor(sTextColor); | |
689 if (m_pDateTime) | |
690 m_pDateTime->SetTextColor(sTextColor); | |
691 | |
692 InvalidateRect(nullptr); | |
693 | |
694 if (IPWL_NoteNotify* pNotify = GetNoteNotify()) { | |
695 pNotify->OnSetBkColor(this); | |
696 } | |
697 } | |
698 | |
699 void CPWL_NoteItem::SetSubjectName(const CFX_WideString& sName) { | |
700 if (m_pSubject) { | |
701 m_pSubject->SetText(sName.c_str()); | |
702 } | |
703 | |
704 if (IPWL_NoteNotify* pNotify = GetNoteNotify()) { | |
705 pNotify->OnSetSubjectName(this); | |
706 } | |
707 } | |
708 | |
709 void CPWL_NoteItem::SetAuthorName(const CFX_WideString& sName) { | |
710 m_sAuthor = sName; | |
711 ResetSubjectName(-1); | |
712 | |
713 if (IPWL_NoteNotify* pNotify = GetNoteNotify()) { | |
714 pNotify->OnSetAuthorName(this); | |
715 } | |
716 } | |
717 | |
718 void CPWL_NoteItem::ResetSubjectName(int32_t nItemIndex) { | |
719 if (nItemIndex < 0) { | |
720 if (CPWL_Wnd* pParent = GetParentWindow()) { | |
721 ASSERT(pParent->GetClassName() == "CPWL_Note_Contents"); | |
722 | |
723 CPWL_Note_Contents* pContents = (CPWL_Note_Contents*)pParent; | |
724 nItemIndex = pContents->GetItemIndex(this); | |
725 } | |
726 } | |
727 | |
728 const CPWL_Note* pNote = GetNote(); | |
729 CFX_WideString sSubject; | |
730 sSubject.Format(pNote->GetReplyString().c_str(), nItemIndex); | |
731 | |
732 if (!m_sAuthor.IsEmpty()) { | |
733 sSubject += L" - "; | |
734 sSubject += m_sAuthor; | |
735 } | |
736 SetSubjectName(sSubject); | |
737 RePosChildWnd(); | |
738 } | |
739 | |
740 void CPWL_NoteItem::SetDateTime(FX_SYSTEMTIME time) { | |
741 m_dtNote = time; | |
742 | |
743 CFX_WideString swTime; | |
744 swTime.Format(L"%04d-%02d-%02d %02d:%02d:%02d", time.wYear, time.wMonth, | |
745 time.wDay, time.wHour, time.wMinute, time.wSecond); | |
746 if (m_pDateTime) { | |
747 m_pDateTime->SetText(swTime.c_str()); | |
748 } | |
749 | |
750 RePosChildWnd(); | |
751 | |
752 if (IPWL_NoteNotify* pNotify = GetNoteNotify()) { | |
753 pNotify->OnSetDateTime(this); | |
754 } | |
755 } | |
756 | |
757 void CPWL_NoteItem::SetContents(const CFX_WideString& sContents) { | |
758 if (m_pContents) { | |
759 m_pContents->SetText(sContents); | |
760 } | |
761 | |
762 if (IPWL_NoteNotify* pNotify = GetNoteNotify()) { | |
763 pNotify->OnSetContents(this); | |
764 } | |
765 } | |
766 | |
767 CPWL_NoteItem* CPWL_NoteItem::GetParentNoteItem() const { | |
768 if (CPWL_Wnd* pParent = GetParentWindow()) { | |
769 if (CPWL_Wnd* pGrand = pParent->GetParentWindow()) { | |
770 ASSERT(pGrand->GetClassName() == "CPWL_NoteItem"); | |
771 return (CPWL_NoteItem*)pGrand; | |
772 } | |
773 } | |
774 | |
775 return NULL; | |
776 } | |
777 | |
778 IPWL_NoteItem* CPWL_NoteItem::GetParentItem() const { | |
779 return GetParentNoteItem(); | |
780 } | |
781 | |
782 CPWL_Edit* CPWL_NoteItem::GetEdit() const { | |
783 if (m_pContents) | |
784 return m_pContents->GetEdit(); | |
785 return NULL; | |
786 } | |
787 | |
788 void* CPWL_NoteItem::GetPrivateData() const { | |
789 return m_pPrivateData; | |
790 } | |
791 | |
792 CFX_WideString CPWL_NoteItem::GetAuthorName() const { | |
793 return m_sAuthor; | |
794 } | |
795 | |
796 CPWL_Color CPWL_NoteItem::GetBkColor() const { | |
797 return GetBackgroundColor(); | |
798 } | |
799 | |
800 CFX_WideString CPWL_NoteItem::GetContents() const { | |
801 if (m_pContents) | |
802 return m_pContents->GetText(); | |
803 | |
804 return L""; | |
805 } | |
806 | |
807 FX_SYSTEMTIME CPWL_NoteItem::GetDateTime() const { | |
808 return m_dtNote; | |
809 } | |
810 | |
811 CFX_WideString CPWL_NoteItem::GetSubjectName() const { | |
812 if (m_pSubject) | |
813 return m_pSubject->GetText(); | |
814 | |
815 return L""; | |
816 } | |
817 | |
818 CPWL_NoteItem* CPWL_NoteItem::CreateNoteItem() { | |
819 if (m_pContents) | |
820 return m_pContents->CreateSubItem(); | |
821 | |
822 return NULL; | |
823 } | |
824 | |
825 IPWL_NoteItem* CPWL_NoteItem::CreateSubItem() { | |
826 return CreateNoteItem(); | |
827 } | |
828 | |
829 int32_t CPWL_NoteItem::CountSubItems() const { | |
830 if (m_pContents) | |
831 return m_pContents->CountSubItems(); | |
832 | |
833 return 0; | |
834 } | |
835 | |
836 IPWL_NoteItem* CPWL_NoteItem::GetSubItems(int32_t index) const { | |
837 if (m_pContents) | |
838 return m_pContents->GetSubItems(index); | |
839 | |
840 return NULL; | |
841 } | |
842 | |
843 void CPWL_NoteItem::DeleteSubItem(IPWL_NoteItem* pNoteItem) { | |
844 KillFocus(); | |
845 | |
846 if (IPWL_NoteNotify* pNotify = GetNoteNotify()) { | |
847 pNotify->OnItemDelete(pNoteItem); | |
848 } | |
849 | |
850 if (m_pContents) | |
851 m_pContents->DeleteSubItem(pNoteItem); | |
852 } | |
853 | |
854 IPWL_NoteItem* CPWL_NoteItem::GetHitNoteItem(const CFX_FloatPoint& point) { | |
855 CFX_FloatPoint pt = ParentToChild(point); | |
856 | |
857 if (WndHitTest(pt)) { | |
858 if (m_pContents) { | |
859 if (IPWL_NoteItem* pNoteItem = m_pContents->GetHitNoteItem(pt)) | |
860 return pNoteItem; | |
861 } | |
862 | |
863 return this; | |
864 } | |
865 | |
866 return NULL; | |
867 } | |
868 | |
869 IPWL_NoteItem* CPWL_NoteItem::GetFocusedNoteItem() const { | |
870 if (const CPWL_Wnd* pWnd = GetFocused()) { | |
871 if (pWnd->GetClassName() == "CPWL_Edit") { | |
872 if (CPWL_Wnd* pParent = pWnd->GetParentWindow()) { | |
873 ASSERT(pParent->GetClassName() == "CPWL_Note_Contents"); | |
874 | |
875 if (CPWL_Wnd* pGrand = pParent->GetParentWindow()) { | |
876 ASSERT(pGrand->GetClassName() == "CPWL_NoteItem"); | |
877 return (CPWL_NoteItem*)pGrand; | |
878 } | |
879 } | |
880 } | |
881 } | |
882 | |
883 return NULL; | |
884 } | |
885 | |
886 FX_FLOAT CPWL_NoteItem::GetItemHeight(FX_FLOAT fLimitWidth) { | |
887 if (fLimitWidth > 0) { | |
888 if (!m_bSizeChanged) | |
889 return m_fOldItemHeight; | |
890 | |
891 m_bSizeChanged = FALSE; | |
892 | |
893 FX_FLOAT fRet = m_pDateTime->GetContentRect().Height(); | |
894 FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth(); | |
895 if (fLimitWidth > fBorderWidth * 2) | |
896 fRet += m_pContents->GetContentsHeight(fLimitWidth - fBorderWidth * 2); | |
897 fRet += POPUP_ITEM_HEAD_BOTTOM + POPUP_ITEM_BOTTOMWIDTH + fBorderWidth * 2; | |
898 | |
899 return m_fOldItemHeight = fRet; | |
900 } | |
901 | |
902 return 0; | |
903 } | |
904 | |
905 FX_FLOAT CPWL_NoteItem::GetItemLeftMargin() { | |
906 return POPUP_ITEM_SIDEMARGIN; | |
907 } | |
908 | |
909 FX_FLOAT CPWL_NoteItem::GetItemRightMargin() { | |
910 return POPUP_ITEM_SIDEMARGIN; | |
911 } | |
912 | |
913 FX_BOOL CPWL_NoteItem::OnLButtonDown(const CFX_FloatPoint& point, | |
914 FX_DWORD nFlag) { | |
915 if (!m_pContents->WndHitTest(m_pContents->ParentToChild(point))) { | |
916 SetNoteFocus(FALSE); | |
917 } | |
918 | |
919 CPWL_Wnd::OnLButtonDown(point, nFlag); | |
920 | |
921 return TRUE; | |
922 } | |
923 | |
924 FX_BOOL CPWL_NoteItem::OnRButtonUp(const CFX_FloatPoint& point, | |
925 FX_DWORD nFlag) { | |
926 if (!m_pContents->WndHitTest(m_pContents->ParentToChild(point))) { | |
927 SetNoteFocus(FALSE); | |
928 PopupNoteItemMenu(point); | |
929 | |
930 return TRUE; | |
931 } | |
932 | |
933 return CPWL_Wnd::OnRButtonUp(point, nFlag); | |
934 } | |
935 | |
936 void CPWL_NoteItem::OnNotify(CPWL_Wnd* pWnd, | |
937 FX_DWORD msg, | |
938 intptr_t wParam, | |
939 intptr_t lParam) { | |
940 switch (msg) { | |
941 case PNM_NOTEEDITCHANGED: | |
942 m_bSizeChanged = TRUE; | |
943 | |
944 if (CPWL_Wnd* pParent = GetParentWindow()) { | |
945 pParent->OnNotify(this, PNM_NOTEEDITCHANGED, 0, 0); | |
946 } | |
947 return; | |
948 case PNM_SETCARETINFO: | |
949 if (PWL_CARET_INFO* pInfo = (PWL_CARET_INFO*)wParam) { | |
950 PWL_CARET_INFO newInfo = *pInfo; | |
951 newInfo.bVisible = TRUE; | |
952 newInfo.ptHead = ChildToParent(pInfo->ptHead); | |
953 newInfo.ptFoot = ChildToParent(pInfo->ptFoot); | |
954 | |
955 if (CPWL_Wnd* pParent = GetParentWindow()) { | |
956 pParent->OnNotify(this, PNM_SETCARETINFO, (intptr_t)&newInfo, 0); | |
957 } | |
958 } | |
959 return; | |
960 case PNM_NOTERESET: | |
961 m_bSizeChanged = TRUE; | |
962 m_pContents->OnNotify(this, PNM_NOTERESET, 0, 0); | |
963 | |
964 return; | |
965 } | |
966 | |
967 CPWL_Wnd::OnNotify(pWnd, msg, wParam, lParam); | |
968 } | |
969 | |
970 void CPWL_NoteItem::PopupNoteItemMenu(const CFX_FloatPoint& point) { | |
971 if (IPWL_NoteNotify* pNotify = GetNoteNotify()) { | |
972 int32_t x, y; | |
973 PWLtoWnd(point, x, y); | |
974 if (IFX_SystemHandler* pSH = GetSystemHandler()) | |
975 pSH->ClientToScreen(GetAttachedHWnd(), x, y); | |
976 pNotify->OnPopupMenu(this, x, y); | |
977 } | |
978 } | |
979 | |
980 const CPWL_Note* CPWL_NoteItem::GetNote() const { | |
981 if (const CPWL_Wnd* pRoot = GetRootWnd()) { | |
982 ASSERT(pRoot->GetClassName() == "CPWL_NoteItem"); | |
983 CPWL_NoteItem* pNoteItem = (CPWL_NoteItem*)pRoot; | |
984 if (pNoteItem->IsTopItem()) { | |
985 return (CPWL_Note*)pNoteItem; | |
986 } | |
987 } | |
988 | |
989 return NULL; | |
990 } | |
991 | |
992 IPWL_NoteNotify* CPWL_NoteItem::GetNoteNotify() const { | |
993 if (const CPWL_Note* pNote = GetNote()) | |
994 return pNote->GetNoteNotify(); | |
995 | |
996 return NULL; | |
997 } | |
998 | |
999 void CPWL_NoteItem::OnCreateNoteItem() { | |
1000 if (IPWL_NoteNotify* pNotify = GetNoteNotify()) { | |
1001 pNotify->OnItemCreate(this); | |
1002 } | |
1003 } | |
1004 | |
1005 void CPWL_NoteItem::OnContentsValidate() { | |
1006 if (IPWL_NoteNotify* pNotify = GetNoteNotify()) { | |
1007 pNotify->OnSetContents(this); | |
1008 } | |
1009 } | |
1010 | |
1011 void CPWL_NoteItem::SetNoteFocus(FX_BOOL bLast) { | |
1012 m_pContents->SetEditFocus(bLast); | |
1013 } | |
1014 | |
1015 void CPWL_NoteItem::EnableModify(FX_BOOL bEnabled) { | |
1016 m_pContents->EnableModify(bEnabled); | |
1017 m_bAllowModify = bEnabled; | |
1018 } | |
1019 | |
1020 void CPWL_NoteItem::EnableRead(FX_BOOL bEnabled) { | |
1021 m_pContents->EnableRead(bEnabled); | |
1022 } | |
1023 | |
1024 CPWL_Note::CPWL_Note(IPopup_Note* pPopupNote, | |
1025 IPWL_NoteNotify* pNoteNotify, | |
1026 IPWL_NoteHandler* pNoteHandler) | |
1027 : m_pAuthor(NULL), | |
1028 m_pIcon(NULL), | |
1029 m_pCloseBox(NULL), | |
1030 m_pLBBox(NULL), | |
1031 m_pRBBox(NULL), | |
1032 m_pContentsBar(NULL), | |
1033 m_pOptions(NULL), | |
1034 m_pNoteNotify(pNoteNotify), | |
1035 m_bResizing(FALSE), | |
1036 m_bEnableNotify(TRUE) {} | |
1037 | |
1038 CPWL_Note::~CPWL_Note() {} | |
1039 | |
1040 IPWL_NoteItem* CPWL_Note::Reply() { | |
1041 return CreateNoteItem(); | |
1042 } | |
1043 | |
1044 void CPWL_Note::EnableNotify(FX_BOOL bEnabled) { | |
1045 m_bEnableNotify = bEnabled; | |
1046 } | |
1047 | |
1048 void CPWL_Note::RePosChildWnd() { | |
1049 RePosNoteChildren(); | |
1050 m_pContents->OnNotify(this, PNM_NOTERESET, 0, 0); | |
1051 ResetScrollBar(); | |
1052 m_pContents->OnNotify(this, PNM_NOTERESET, 0, 0); | |
1053 OnNotify(this, PNM_NOTEEDITCHANGED, 0, 0); | |
1054 if (const CPWL_Wnd* pWnd = GetFocused()) { | |
1055 if (pWnd->GetClassName() == "CPWL_Edit") { | |
1056 CPWL_Edit* pEdit = (CPWL_Edit*)pWnd; | |
1057 pEdit->SetCaret(pEdit->GetCaret()); | |
1058 } | |
1059 } | |
1060 } | |
1061 | |
1062 FX_BOOL CPWL_Note::ResetScrollBar() { | |
1063 FX_BOOL bScrollChanged = FALSE; | |
1064 | |
1065 if (ScrollBarShouldVisible()) { | |
1066 if (!m_pContentsBar->IsVisible()) { | |
1067 m_pContentsBar->SetVisible(TRUE); | |
1068 if (m_pContentsBar->IsVisible()) { | |
1069 m_pContentsBar->InvalidateRect(NULL); | |
1070 bScrollChanged = TRUE; | |
1071 } | |
1072 } | |
1073 } else { | |
1074 if (m_pContentsBar->IsVisible()) { | |
1075 m_pContentsBar->SetVisible(FALSE); | |
1076 m_pContentsBar->InvalidateRect(NULL); | |
1077 | |
1078 bScrollChanged = TRUE; | |
1079 } | |
1080 } | |
1081 | |
1082 if (bScrollChanged) { | |
1083 CFX_FloatRect rcNote = GetClientRect(); | |
1084 CFX_FloatRect rcContents = m_pContents->GetWindowRect(); | |
1085 rcContents.right = rcNote.right - 3.0f; | |
1086 if (m_pContentsBar->IsVisible()) | |
1087 rcContents.right -= PWL_SCROLLBAR_WIDTH; | |
1088 m_pContents->Move(rcContents, TRUE, TRUE); | |
1089 m_pContents->SetScrollPos(CFX_FloatPoint(0.0f, 0.0f)); | |
1090 m_pContents->InvalidateRect(NULL); | |
1091 } | |
1092 | |
1093 return bScrollChanged; | |
1094 } | |
1095 | |
1096 FX_BOOL CPWL_Note::ScrollBarShouldVisible() { | |
1097 CFX_FloatRect rcContentsFact = m_pContents->GetScrollArea(); | |
1098 CFX_FloatRect rcContentsClient = m_pContents->GetClientRect(); | |
1099 | |
1100 return rcContentsFact.Height() > rcContentsClient.Height(); | |
1101 } | |
1102 | |
1103 void CPWL_Note::SetOptionsText(const CFX_WideString& sText) { | |
1104 if (m_pOptions) | |
1105 m_pOptions->SetText(sText); | |
1106 | |
1107 RePosNoteChildren(); | |
1108 } | |
1109 | |
1110 void CPWL_Note::RePosNoteChildren() { | |
1111 if (m_bResizing) | |
1112 return; | |
1113 | |
1114 m_bResizing = TRUE; | |
1115 | |
1116 if (IsValid()) { | |
1117 CFX_FloatRect rcClient = GetClientRect(); | |
1118 | |
1119 CFX_FloatRect rcIcon = rcClient; | |
1120 rcIcon.top -= 2.0f; | |
1121 rcIcon.right = rcIcon.left + 14.0f; | |
1122 rcIcon.bottom = rcIcon.top - 14.0f; | |
1123 rcIcon.Normalize(); | |
1124 m_pIcon->Move(rcIcon, TRUE, FALSE); | |
1125 m_pIcon->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcIcon)); | |
1126 | |
1127 CFX_FloatRect rcCloseBox = rcClient; | |
1128 rcCloseBox.right -= 1.0f; | |
1129 rcCloseBox.top -= 1.0f; | |
1130 rcCloseBox.left = rcCloseBox.right - 14.0f; | |
1131 rcCloseBox.bottom = rcCloseBox.top - 14.0f; | |
1132 rcCloseBox.Normalize(); | |
1133 m_pCloseBox->Move(rcCloseBox, TRUE, FALSE); | |
1134 m_pCloseBox->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcCloseBox)); | |
1135 | |
1136 CFX_FloatRect rcDate = rcClient; | |
1137 rcDate.right = rcCloseBox.left - POPUP_ITEM_TEXT_INDENT; | |
1138 rcDate.left = | |
1139 PWL_MAX(rcDate.right - m_pDateTime->GetContentRect().Width() - 1.0f, | |
1140 rcIcon.right + 1.0f); | |
1141 rcDate.top = rcClient.top - 2.0f; | |
1142 rcDate.bottom = rcDate.top - m_pDateTime->GetContentRect().Height(); | |
1143 rcDate.Normalize(); | |
1144 m_pDateTime->Move(rcDate, TRUE, FALSE); | |
1145 m_pDateTime->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcDate)); | |
1146 | |
1147 CFX_FloatRect rcSubject = rcClient; | |
1148 rcSubject.top = rcClient.top - 2.0f; | |
1149 rcSubject.left = rcIcon.right + POPUP_ITEM_TEXT_INDENT; | |
1150 rcSubject.right = | |
1151 PWL_MIN(rcSubject.left + m_pSubject->GetContentRect().Width() + 1.0f, | |
1152 rcDate.left - 1.0f); | |
1153 rcSubject.bottom = rcSubject.top - m_pSubject->GetContentRect().Height(); | |
1154 rcSubject.Normalize(); | |
1155 m_pSubject->Move(rcSubject, TRUE, FALSE); | |
1156 m_pSubject->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcSubject)); | |
1157 | |
1158 CFX_FloatRect rcOptions = rcClient; | |
1159 rcOptions.left = | |
1160 PWL_MAX(rcOptions.right - m_pOptions->GetContentRect().Width(), | |
1161 rcIcon.right + 1.0f); | |
1162 rcOptions.top = rcSubject.bottom - 4.0f; | |
1163 rcOptions.bottom = rcOptions.top - m_pOptions->GetContentRect().Height(); | |
1164 rcOptions.Normalize(); | |
1165 m_pOptions->Move(rcOptions, TRUE, FALSE); | |
1166 m_pOptions->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcOptions)); | |
1167 | |
1168 CFX_FloatRect rcAuthor = rcClient; | |
1169 rcAuthor.top = rcSubject.bottom - 4.0f; | |
1170 rcAuthor.left = rcSubject.left; | |
1171 rcAuthor.right = | |
1172 PWL_MIN(rcSubject.left + m_pAuthor->GetContentRect().Width() + 1.0f, | |
1173 rcOptions.left - 1.0f); | |
1174 rcAuthor.bottom = rcAuthor.top - m_pAuthor->GetContentRect().Height(); | |
1175 rcAuthor.Normalize(); | |
1176 m_pAuthor->Move(rcAuthor, TRUE, FALSE); | |
1177 m_pAuthor->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcAuthor)); | |
1178 | |
1179 CFX_FloatRect rcLBBox = rcClient; | |
1180 rcLBBox.top = rcLBBox.bottom + 7.0f; | |
1181 rcLBBox.right = rcLBBox.left + 7.0f; | |
1182 rcLBBox.Normalize(); | |
1183 m_pLBBox->Move(rcLBBox, TRUE, FALSE); | |
1184 m_pLBBox->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcLBBox)); | |
1185 | |
1186 CFX_FloatRect rcRBBox = rcClient; | |
1187 rcRBBox.top = rcRBBox.bottom + 7.0f; | |
1188 rcRBBox.left = rcRBBox.right - 7.0f; | |
1189 rcRBBox.Normalize(); | |
1190 m_pRBBox->Move(rcRBBox, TRUE, FALSE); | |
1191 m_pRBBox->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcRBBox)); | |
1192 | |
1193 CFX_FloatRect rcContents = rcClient; | |
1194 rcContents.top = rcAuthor.bottom - POPUP_ITEM_HEAD_BOTTOM; | |
1195 rcContents.left += 3.0f; | |
1196 rcContents.right -= 3.0f; | |
1197 if (m_pContentsBar->IsVisible()) | |
1198 rcContents.right -= PWL_SCROLLBAR_WIDTH; | |
1199 rcContents.bottom += 14.0f; | |
1200 rcContents.Normalize(); | |
1201 m_pContents->Move(rcContents, FALSE, FALSE); | |
1202 m_pContents->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcContents)); | |
1203 | |
1204 CFX_FloatRect rcContentsBar = rcContents; | |
1205 rcContentsBar.right = rcClient.right - 3.0f; | |
1206 rcContentsBar.left = rcContentsBar.right - PWL_SCROLLBAR_WIDTH; | |
1207 rcContentsBar.Normalize(); | |
1208 m_pContentsBar->Move(rcContentsBar, TRUE, FALSE); | |
1209 } | |
1210 | |
1211 m_bResizing = FALSE; | |
1212 } | |
1213 | |
1214 void CPWL_Note::CreateChildWnd(const PWL_CREATEPARAM& cp) { | |
1215 CPWL_NoteItem::CreateChildWnd(cp); | |
1216 | |
1217 CPWL_Color sTextColor; | |
1218 | |
1219 if (CPWL_Utils::IsBlackOrWhite(GetBackgroundColor())) | |
1220 sTextColor = PWL_DEFAULT_WHITECOLOR; | |
1221 else | |
1222 sTextColor = PWL_DEFAULT_BLACKCOLOR; | |
1223 | |
1224 m_pAuthor = new CPWL_Label; | |
1225 PWL_CREATEPARAM acp = cp; | |
1226 acp.pParentWnd = this; | |
1227 acp.dwFlags = PWS_VISIBLE | PWS_CHILD | PES_LEFT | PES_TOP; | |
1228 acp.sTextColor = sTextColor; | |
1229 m_pAuthor->Create(acp); | |
1230 | |
1231 m_pCloseBox = new CPWL_Note_CloseBox; | |
1232 PWL_CREATEPARAM ccp = cp; | |
1233 ccp.pParentWnd = this; | |
1234 ccp.dwBorderWidth = 2; | |
1235 ccp.nBorderStyle = PBS_BEVELED; | |
1236 ccp.dwFlags = PWS_VISIBLE | PWS_CHILD | PWS_BORDER; | |
1237 ccp.sTextColor = sTextColor; | |
1238 m_pCloseBox->Create(ccp); | |
1239 | |
1240 m_pIcon = new CPWL_Note_Icon; | |
1241 PWL_CREATEPARAM icp = cp; | |
1242 icp.pParentWnd = this; | |
1243 icp.dwFlags = PWS_VISIBLE | PWS_CHILD; | |
1244 m_pIcon->Create(icp); | |
1245 | |
1246 m_pOptions = new CPWL_Note_Options; | |
1247 PWL_CREATEPARAM ocp = cp; | |
1248 ocp.pParentWnd = this; | |
1249 ocp.dwFlags = PWS_CHILD | PWS_VISIBLE; | |
1250 ocp.sTextColor = sTextColor; | |
1251 m_pOptions->Create(ocp); | |
1252 | |
1253 m_pLBBox = new CPWL_Note_LBBox; | |
1254 PWL_CREATEPARAM lcp = cp; | |
1255 lcp.pParentWnd = this; | |
1256 lcp.dwFlags = PWS_VISIBLE | PWS_CHILD; | |
1257 lcp.eCursorType = FXCT_NESW; | |
1258 lcp.sTextColor = sTextColor; | |
1259 m_pLBBox->Create(lcp); | |
1260 | |
1261 m_pRBBox = new CPWL_Note_RBBox; | |
1262 PWL_CREATEPARAM rcp = cp; | |
1263 rcp.pParentWnd = this; | |
1264 rcp.dwFlags = PWS_VISIBLE | PWS_CHILD; | |
1265 rcp.eCursorType = FXCT_NWSE; | |
1266 rcp.sTextColor = sTextColor; | |
1267 m_pRBBox->Create(rcp); | |
1268 | |
1269 m_pContentsBar = new CPWL_ScrollBar(SBT_VSCROLL); | |
1270 PWL_CREATEPARAM scp = cp; | |
1271 scp.pParentWnd = this; | |
1272 scp.sBackgroundColor = | |
1273 CPWL_Color(COLORTYPE_RGB, 240 / 255.0f, 240 / 255.0f, 240 / 255.0f); | |
1274 scp.dwFlags = PWS_CHILD | PWS_VISIBLE | PWS_BACKGROUND; | |
1275 m_pContentsBar->Create(scp); | |
1276 m_pContentsBar->SetNotifyForever(TRUE); | |
1277 } | |
1278 | |
1279 void CPWL_Note::SetSubjectName(const CFX_WideString& sName) { | |
1280 CPWL_NoteItem::SetSubjectName(sName); | |
1281 RePosChildWnd(); | |
1282 } | |
1283 | |
1284 void CPWL_Note::SetAuthorName(const CFX_WideString& sName) { | |
1285 if (m_pAuthor) { | |
1286 m_pAuthor->SetText(sName.c_str()); | |
1287 RePosChildWnd(); | |
1288 } | |
1289 | |
1290 if (IPWL_NoteNotify* pNotify = GetNoteNotify()) { | |
1291 pNotify->OnSetAuthorName(this); | |
1292 } | |
1293 } | |
1294 | |
1295 CFX_WideString CPWL_Note::GetAuthorName() const { | |
1296 if (m_pAuthor) | |
1297 return m_pAuthor->GetText(); | |
1298 | |
1299 return L""; | |
1300 } | |
1301 | |
1302 FX_BOOL CPWL_Note::OnMouseWheel(short zDelta, | |
1303 const CFX_FloatPoint& point, | |
1304 FX_DWORD nFlag) { | |
1305 CFX_FloatPoint ptScroll = m_pContents->GetScrollPos(); | |
1306 CFX_FloatRect rcScroll = m_pContents->GetScrollArea(); | |
1307 CFX_FloatRect rcContents = m_pContents->GetClientRect(); | |
1308 | |
1309 if (rcScroll.top - rcScroll.bottom > rcContents.Height()) { | |
1310 CFX_FloatPoint ptNew = ptScroll; | |
1311 | |
1312 if (zDelta > 0) | |
1313 ptNew.y += 30; | |
1314 else | |
1315 ptNew.y -= 30; | |
1316 | |
1317 if (ptNew.y > rcScroll.top) | |
1318 ptNew.y = rcScroll.top; | |
1319 if (ptNew.y < rcScroll.bottom + rcContents.Height()) | |
1320 ptNew.y = rcScroll.bottom + rcContents.Height(); | |
1321 if (ptNew.y < rcScroll.bottom) | |
1322 ptNew.y = rcScroll.bottom; | |
1323 | |
1324 if (ptNew.y != ptScroll.y) { | |
1325 m_pContents->OnNotify(this, PNM_NOTERESET, 0, 0); | |
1326 m_pContents->OnNotify(this, PNM_SCROLLWINDOW, SBT_VSCROLL, | |
1327 (intptr_t)&ptNew.y); | |
1328 m_pContentsBar->OnNotify(this, PNM_SETSCROLLPOS, SBT_VSCROLL, | |
1329 (intptr_t)&ptNew.y); | |
1330 | |
1331 return TRUE; | |
1332 } | |
1333 } | |
1334 | |
1335 return FALSE; | |
1336 } | |
1337 | |
1338 void CPWL_Note::OnNotify(CPWL_Wnd* pWnd, | |
1339 FX_DWORD msg, | |
1340 intptr_t wParam, | |
1341 intptr_t lParam) { | |
1342 switch (msg) { | |
1343 case PNM_NOTEEDITCHANGED: { | |
1344 CFX_FloatRect rcScroll = m_pContents->GetScrollArea(); | |
1345 | |
1346 PWL_SCROLL_INFO sInfo; | |
1347 sInfo.fContentMin = rcScroll.bottom; | |
1348 sInfo.fContentMax = rcScroll.top; | |
1349 sInfo.fPlateWidth = m_pContents->GetClientRect().Height(); | |
1350 sInfo.fSmallStep = 13.0f; | |
1351 sInfo.fBigStep = sInfo.fPlateWidth; | |
1352 | |
1353 if (FXSYS_memcmp(&m_OldScrollInfo, &sInfo, sizeof(PWL_SCROLL_INFO)) != | |
1354 0) { | |
1355 FX_BOOL bScrollChanged = FALSE; | |
1356 | |
1357 if (lParam < 3) { | |
1358 bScrollChanged = ResetScrollBar(); | |
1359 if (bScrollChanged) { | |
1360 lParam++; | |
1361 m_pContents->OnNotify(this, PNM_NOTERESET, 0, 0); | |
1362 OnNotify(this, PNM_NOTEEDITCHANGED, 0, lParam); | |
1363 } | |
1364 } | |
1365 | |
1366 if (!bScrollChanged) { | |
1367 if (m_pContentsBar->IsVisible()) { | |
1368 m_pContentsBar->OnNotify(pWnd, PNM_SETSCROLLINFO, SBT_VSCROLL, | |
1369 (intptr_t)&sInfo); | |
1370 m_OldScrollInfo = sInfo; | |
1371 | |
1372 CFX_FloatPoint ptScroll = m_pContents->GetScrollPos(); | |
1373 CFX_FloatPoint ptOld = ptScroll; | |
1374 | |
1375 if (ptScroll.y > sInfo.fContentMax) | |
1376 ptScroll.y = sInfo.fContentMax; | |
1377 if (ptScroll.y < sInfo.fContentMin + sInfo.fPlateWidth) | |
1378 ptScroll.y = sInfo.fContentMin + sInfo.fPlateWidth; | |
1379 if (ptScroll.y < sInfo.fContentMin) | |
1380 ptScroll.y = sInfo.fContentMin; | |
1381 | |
1382 if (ptOld.y != ptScroll.y) { | |
1383 m_pContentsBar->OnNotify(this, PNM_SETSCROLLPOS, SBT_VSCROLL, | |
1384 (intptr_t)&ptScroll.y); | |
1385 m_pContentsBar->InvalidateRect(NULL); | |
1386 m_pContents->OnNotify(this, PNM_SCROLLWINDOW, SBT_VSCROLL, | |
1387 (intptr_t)&ptScroll.y); | |
1388 } | |
1389 } | |
1390 } | |
1391 } | |
1392 } | |
1393 | |
1394 m_pContents->InvalidateRect(NULL); | |
1395 | |
1396 return; | |
1397 case PNM_SCROLLWINDOW: | |
1398 if (m_pContents) | |
1399 m_pContents->OnNotify(pWnd, msg, wParam, lParam); | |
1400 return; | |
1401 case PNM_SETSCROLLPOS: | |
1402 if (m_pContentsBar) | |
1403 m_pContentsBar->OnNotify(pWnd, PNM_SETSCROLLPOS, wParam, lParam); | |
1404 return; | |
1405 } | |
1406 | |
1407 if (msg == PNM_SETCARETINFO && IsValid()) { | |
1408 if (PWL_CARET_INFO* pInfo = (PWL_CARET_INFO*)wParam) { | |
1409 if (m_pContents) { | |
1410 CFX_FloatRect rcClient = m_pContents->GetClientRect(); | |
1411 if (pInfo->ptHead.y > rcClient.top) { | |
1412 CFX_FloatPoint pt = m_pContents->OutToIn(pInfo->ptHead); | |
1413 m_pContents->OnNotify(this, PNM_SCROLLWINDOW, SBT_VSCROLL, | |
1414 (intptr_t)&pt.y); | |
1415 | |
1416 CFX_FloatPoint ptScroll = m_pContents->GetScrollPos(); | |
1417 m_pContentsBar->OnNotify(this, PNM_SETSCROLLPOS, SBT_VSCROLL, | |
1418 (intptr_t)&ptScroll.y); | |
1419 | |
1420 return; | |
1421 } | |
1422 | |
1423 if (pInfo->ptFoot.y < rcClient.bottom) { | |
1424 CFX_FloatPoint pt = m_pContents->OutToIn(pInfo->ptFoot); | |
1425 pt.y += rcClient.Height(); | |
1426 m_pContents->OnNotify(this, PNM_SCROLLWINDOW, SBT_VSCROLL, | |
1427 (intptr_t)&pt.y); | |
1428 | |
1429 CFX_FloatPoint ptScroll = m_pContents->GetScrollPos(); | |
1430 m_pContentsBar->OnNotify(this, PNM_SETSCROLLPOS, SBT_VSCROLL, | |
1431 (intptr_t)&ptScroll.y); | |
1432 | |
1433 return; | |
1434 } | |
1435 } | |
1436 } | |
1437 } | |
1438 | |
1439 CPWL_NoteItem::OnNotify(pWnd, msg, wParam, lParam); | |
1440 } | |
1441 | |
1442 void CPWL_Note::SetBkColor(const CPWL_Color& color) { | |
1443 CPWL_NoteItem::SetBkColor(color); | |
1444 | |
1445 CPWL_Color sBK = color; | |
1446 CPWL_Color sTextColor; | |
1447 if (CPWL_Utils::IsBlackOrWhite(sBK)) | |
1448 sTextColor = PWL_DEFAULT_WHITECOLOR; | |
1449 else | |
1450 sTextColor = PWL_DEFAULT_BLACKCOLOR; | |
1451 | |
1452 if (m_pCloseBox) | |
1453 m_pCloseBox->SetTextColor(sTextColor); | |
1454 if (m_pAuthor) | |
1455 m_pAuthor->SetTextColor(sTextColor); | |
1456 if (m_pOptions) | |
1457 m_pOptions->SetTextColor(sTextColor); | |
1458 if (m_pLBBox) | |
1459 m_pLBBox->SetTextColor(sTextColor); | |
1460 if (m_pRBBox) | |
1461 m_pRBBox->SetTextColor(sTextColor); | |
1462 } | |
1463 | |
1464 FX_BOOL CPWL_Note::OnLButtonDown(const CFX_FloatPoint& point, FX_DWORD nFlag) { | |
1465 if (m_pOptions->WndHitTest(m_pOptions->ParentToChild(point))) { | |
1466 if (IPWL_NoteNotify* pNotify = GetNoteNotify()) { | |
1467 int32_t x, y; | |
1468 PWLtoWnd(point, x, y); | |
1469 if (IFX_SystemHandler* pSH = GetSystemHandler()) | |
1470 pSH->ClientToScreen(GetAttachedHWnd(), x, y); | |
1471 KillFocus(); | |
1472 pNotify->OnPopupMenu(x, y); | |
1473 | |
1474 return TRUE; | |
1475 } | |
1476 } | |
1477 | |
1478 return CPWL_Wnd::OnLButtonDown(point, nFlag); | |
1479 } | |
1480 | |
1481 FX_BOOL CPWL_Note::OnRButtonUp(const CFX_FloatPoint& point, FX_DWORD nFlag) { | |
1482 return CPWL_Wnd::OnRButtonUp(point, nFlag); | |
1483 } | |
1484 | |
1485 const CPWL_Note* CPWL_Note::GetNote() const { | |
1486 return this; | |
1487 } | |
1488 | |
1489 IPWL_NoteNotify* CPWL_Note::GetNoteNotify() const { | |
1490 return m_bEnableNotify ? m_pNoteNotify : nullptr; | |
1491 } | |
1492 | |
1493 void CPWL_Note::SetIconType(int32_t nType) { | |
1494 if (m_pIcon) | |
1495 m_pIcon->SetIconType(nType); | |
1496 } | |
1497 | |
1498 void CPWL_Note::EnableModify(FX_BOOL bEnabled) { | |
1499 m_pContents->EnableModify(bEnabled); | |
1500 } | |
1501 | |
1502 void CPWL_Note::EnableRead(FX_BOOL bEnabled) { | |
1503 m_pContents->EnableRead(bEnabled); | |
1504 } | |
1505 | |
1506 CFX_WideString CPWL_Note::GetReplyString() const { | |
1507 return m_sReplyString; | |
1508 } | |
1509 | |
1510 void CPWL_Note::SetReplyString(const CFX_WideString& str) { | |
1511 m_sReplyString = str; | |
1512 } | |
OLD | NEW |