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/pdfwindow/PWL_Note.h" | |
8 | |
9 #include "core/fxge/include/fx_ge.h" | |
10 #include "fpdfsdk/pdfwindow/PWL_Button.h" | |
11 #include "fpdfsdk/pdfwindow/PWL_Caret.h" | |
12 #include "fpdfsdk/pdfwindow/PWL_Edit.h" | |
13 #include "fpdfsdk/pdfwindow/PWL_EditCtrl.h" | |
14 #include "fpdfsdk/pdfwindow/PWL_Label.h" | |
15 #include "fpdfsdk/pdfwindow/PWL_ListCtrl.h" | |
16 #include "fpdfsdk/pdfwindow/PWL_ScrollBar.h" | |
17 #include "fpdfsdk/pdfwindow/PWL_Utils.h" | |
18 #include "fpdfsdk/pdfwindow/PWL_Wnd.h" | |
19 | |
20 #define POPUP_ITEM_HEAD_BOTTOM 3.0f | |
21 #define POPUP_ITEM_BOTTOMWIDTH 1.0f | |
22 #define POPUP_ITEM_SIDEMARGIN 3.0f | |
23 #define POPUP_ITEM_SPACE 4.0f | |
24 #define POPUP_ITEM_TEXT_INDENT 2.0f | |
25 #define POPUP_ITEM_BORDERCOLOR \ | |
26 CPWL_Color(COLORTYPE_RGB, 80 / 255.0f, 80 / 255.0f, 80 / 255.0f) | |
27 | |
28 #define IsFloatZero(f) ((f) < 0.0001 && (f) > -0.0001) | |
29 #define IsFloatBigger(fa, fb) ((fa) > (fb) && !IsFloatZero((fa) - (fb))) | |
30 #define IsFloatSmaller(fa, fb) ((fa) < (fb) && !IsFloatZero((fa) - (fb))) | |
31 #define IsFloatEqual(fa, fb) IsFloatZero((fa) - (fb)) | |
32 | |
33 CPWL_Note_Options::CPWL_Note_Options() : m_pText(NULL) {} | |
34 | |
35 CPWL_Note_Options::~CPWL_Note_Options() {} | |
36 | |
37 void CPWL_Note_Options::SetTextColor(const CPWL_Color& color) { | |
38 CPWL_Wnd::SetTextColor(color); | |
39 | |
40 if (m_pText) | |
41 m_pText->SetTextColor(color); | |
42 } | |
43 | |
44 void CPWL_Note_Options::RePosChildWnd() { | |
45 if (IsValid()) { | |
46 CFX_FloatRect rcClient = GetClientRect(); | |
47 | |
48 if (rcClient.Width() > 15.0f) { | |
49 rcClient.right -= 15.0f; | |
50 m_pText->Move(rcClient, TRUE, FALSE); | |
51 m_pText->SetVisible(TRUE); | |
52 } else { | |
53 m_pText->Move(CFX_FloatRect(0, 0, 0, 0), TRUE, FALSE); | |
54 m_pText->SetVisible(FALSE); | |
55 } | |
56 } | |
57 } | |
58 | |
59 void CPWL_Note_Options::CreateChildWnd(const PWL_CREATEPARAM& cp) { | |
60 m_pText = new CPWL_Label; | |
61 PWL_CREATEPARAM tcp = cp; | |
62 tcp.pParentWnd = this; | |
63 tcp.dwFlags = PWS_CHILD | PWS_VISIBLE; | |
64 m_pText->Create(tcp); | |
65 } | |
66 | |
67 void CPWL_Note_Options::SetText(const CFX_WideString& sText) { | |
68 m_pText->SetText(sText.c_str()); | |
69 } | |
70 | |
71 void CPWL_Note_Options::DrawThisAppearance(CFX_RenderDevice* pDevice, | |
72 CFX_Matrix* pUser2Device) { | |
73 CPWL_Wnd::DrawThisAppearance(pDevice, pUser2Device); | |
74 | |
75 CFX_FloatRect rcClient = GetClientRect(); | |
76 rcClient.left = rcClient.right - 15.0f; | |
77 | |
78 CFX_FloatPoint ptCenter = | |
79 CFX_FloatPoint((rcClient.left + rcClient.right) * 0.5f, | |
80 (rcClient.top + rcClient.bottom) * 0.5f); | |
81 | |
82 CFX_FloatPoint pt1(ptCenter.x - 2.0f, ptCenter.y + 2.0f * 0.5f); | |
83 CFX_FloatPoint pt2(ptCenter.x + 2.0f, ptCenter.y + 2.0f * 0.5f); | |
84 CFX_FloatPoint pt3(ptCenter.x, ptCenter.y - 3.0f * 0.5f); | |
85 | |
86 CFX_PathData path; | |
87 | |
88 path.SetPointCount(4); | |
89 path.SetPoint(0, pt1.x, pt1.y, FXPT_MOVETO); | |
90 path.SetPoint(1, pt2.x, pt2.y, FXPT_LINETO); | |
91 path.SetPoint(2, pt3.x, pt3.y, FXPT_LINETO); | |
92 path.SetPoint(3, pt1.x, pt1.y, FXPT_LINETO); | |
93 | |
94 pDevice->DrawPath( | |
95 &path, pUser2Device, NULL, | |
96 CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()), 0, | |
97 FXFILL_ALTERNATE); | |
98 } | |
99 | |
100 CFX_FloatRect CPWL_Note_Options::GetContentRect() const { | |
101 CFX_FloatRect rcText = m_pText->GetContentRect(); | |
102 rcText.right += 15.0f; | |
103 return rcText; | |
104 } | |
105 | |
106 CPWL_Note_Edit::CPWL_Note_Edit() | |
107 : m_bEnableNotify(TRUE), | |
108 m_fOldItemHeight(0.0f), | |
109 m_bSizeChanged(FALSE), | |
110 m_fOldMin(0.0f), | |
111 m_fOldMax(0.0f) {} | |
112 | |
113 CPWL_Note_Edit::~CPWL_Note_Edit() {} | |
114 | |
115 void CPWL_Note_Edit::RePosChildWnd() { | |
116 m_bEnableNotify = FALSE; | |
117 CPWL_Edit::RePosChildWnd(); | |
118 m_bEnableNotify = TRUE; | |
119 | |
120 m_fOldItemHeight = GetContentRect().Height(); | |
121 } | |
122 | |
123 void CPWL_Note_Edit::SetText(const FX_WCHAR* csText) { | |
124 m_bEnableNotify = FALSE; | |
125 CPWL_Edit::SetText(csText); | |
126 m_bEnableNotify = TRUE; | |
127 m_fOldItemHeight = GetContentRect().Height(); | |
128 } | |
129 | |
130 void CPWL_Note_Edit::OnSetFocus() { | |
131 m_bEnableNotify = FALSE; | |
132 CPWL_Edit::OnSetFocus(); | |
133 m_bEnableNotify = TRUE; | |
134 | |
135 EnableSpellCheck(TRUE); | |
136 } | |
137 | |
138 void CPWL_Note_Edit::OnKillFocus() { | |
139 EnableSpellCheck(FALSE); | |
140 CPWL_Edit::OnKillFocus(); | |
141 } | |
142 | |
143 void CPWL_Note_Edit::OnNotify(CPWL_Wnd* pWnd, | |
144 uint32_t msg, | |
145 intptr_t wParam, | |
146 intptr_t lParam) { | |
147 if (m_bEnableNotify) { | |
148 if (wParam == SBT_VSCROLL) { | |
149 switch (msg) { | |
150 case PNM_SETSCROLLINFO: | |
151 if (PWL_SCROLL_INFO* pInfo = (PWL_SCROLL_INFO*)lParam) { | |
152 if (!IsFloatEqual(pInfo->fContentMax, m_fOldMax) || | |
153 !IsFloatEqual(pInfo->fContentMin, m_fOldMin)) { | |
154 m_bSizeChanged = TRUE; | |
155 if (CPWL_Wnd* pParent = GetParentWindow()) { | |
156 pParent->OnNotify(this, PNM_NOTEEDITCHANGED, 0, 0); | |
157 } | |
158 | |
159 m_fOldMax = pInfo->fContentMax; | |
160 m_fOldMin = pInfo->fContentMin; | |
161 return; | |
162 } | |
163 } | |
164 } | |
165 } | |
166 } | |
167 | |
168 CPWL_Edit::OnNotify(pWnd, msg, wParam, lParam); | |
169 | |
170 if (m_bEnableNotify) { | |
171 switch (msg) { | |
172 case PNM_SETCARETINFO: | |
173 if (PWL_CARET_INFO* pInfo = (PWL_CARET_INFO*)wParam) { | |
174 PWL_CARET_INFO newInfo = *pInfo; | |
175 newInfo.bVisible = TRUE; | |
176 newInfo.ptHead = ChildToParent(pInfo->ptHead); | |
177 newInfo.ptFoot = ChildToParent(pInfo->ptFoot); | |
178 | |
179 if (CPWL_Wnd* pParent = GetParentWindow()) { | |
180 pParent->OnNotify(this, PNM_SETCARETINFO, (intptr_t)&newInfo, 0); | |
181 } | |
182 } | |
183 break; | |
184 } | |
185 } | |
186 } | |
187 | |
188 FX_FLOAT CPWL_Note_Edit::GetItemHeight(FX_FLOAT fLimitWidth) { | |
189 if (fLimitWidth > 0) { | |
190 if (!m_bSizeChanged) | |
191 return m_fOldItemHeight; | |
192 | |
193 m_bSizeChanged = FALSE; | |
194 | |
195 EnableNotify(FALSE); | |
196 EnableRefresh(FALSE); | |
197 m_pEdit->EnableNotify(FALSE); | |
198 | |
199 Move(CFX_FloatRect(0, 0, fLimitWidth, 0), TRUE, FALSE); | |
200 FX_FLOAT fRet = GetContentRect().Height(); | |
201 | |
202 m_pEdit->EnableNotify(TRUE); | |
203 EnableNotify(TRUE); | |
204 EnableRefresh(TRUE); | |
205 | |
206 return fRet; | |
207 } | |
208 | |
209 return 0; | |
210 } | |
211 | |
212 FX_FLOAT CPWL_Note_Edit::GetItemLeftMargin() { | |
213 return POPUP_ITEM_TEXT_INDENT; | |
214 } | |
215 | |
216 FX_FLOAT CPWL_Note_Edit::GetItemRightMargin() { | |
217 return POPUP_ITEM_TEXT_INDENT; | |
218 } | |
219 | |
220 CPWL_Note_LBBox::CPWL_Note_LBBox() {} | |
221 | |
222 CPWL_Note_LBBox::~CPWL_Note_LBBox() {} | |
223 | |
224 void CPWL_Note_LBBox::DrawThisAppearance(CFX_RenderDevice* pDevice, | |
225 CFX_Matrix* pUser2Device) { | |
226 CFX_FloatRect rcClient = GetClientRect(); | |
227 | |
228 CFX_GraphStateData gsd; | |
229 gsd.m_LineWidth = 1.0f; | |
230 | |
231 CFX_PathData pathCross; | |
232 | |
233 pathCross.SetPointCount(4); | |
234 pathCross.SetPoint(0, rcClient.left, rcClient.top, FXPT_MOVETO); | |
235 pathCross.SetPoint(1, rcClient.right, rcClient.bottom, FXPT_LINETO); | |
236 pathCross.SetPoint(2, rcClient.left, | |
237 rcClient.bottom + rcClient.Height() * 0.5f, FXPT_MOVETO); | |
238 pathCross.SetPoint(3, rcClient.left + rcClient.Width() * 0.5f, | |
239 rcClient.bottom, FXPT_LINETO); | |
240 | |
241 pDevice->DrawPath( | |
242 &pathCross, pUser2Device, &gsd, 0, | |
243 CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()), | |
244 FXFILL_ALTERNATE); | |
245 } | |
246 | |
247 CPWL_Note_RBBox::CPWL_Note_RBBox() {} | |
248 | |
249 CPWL_Note_RBBox::~CPWL_Note_RBBox() {} | |
250 | |
251 void CPWL_Note_RBBox::DrawThisAppearance(CFX_RenderDevice* pDevice, | |
252 CFX_Matrix* pUser2Device) { | |
253 CFX_FloatRect rcClient = GetClientRect(); | |
254 | |
255 CFX_GraphStateData gsd; | |
256 gsd.m_LineWidth = 1.0f; | |
257 | |
258 CFX_PathData pathCross; | |
259 | |
260 pathCross.SetPointCount(4); | |
261 pathCross.SetPoint(0, rcClient.right, rcClient.top, FXPT_MOVETO); | |
262 pathCross.SetPoint(1, rcClient.left, rcClient.bottom, FXPT_LINETO); | |
263 pathCross.SetPoint(2, rcClient.right, | |
264 rcClient.bottom + rcClient.Height() * 0.5f, FXPT_MOVETO); | |
265 pathCross.SetPoint(3, rcClient.left + rcClient.Width() * 0.5f, | |
266 rcClient.bottom, FXPT_LINETO); | |
267 | |
268 pDevice->DrawPath( | |
269 &pathCross, pUser2Device, &gsd, 0, | |
270 CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()), | |
271 FXFILL_ALTERNATE); | |
272 } | |
273 | |
274 CPWL_Note_Icon::CPWL_Note_Icon() : m_nType(0) {} | |
275 | |
276 CPWL_Note_Icon::~CPWL_Note_Icon() {} | |
277 | |
278 void CPWL_Note_Icon::SetIconType(int32_t nType) { | |
279 m_nType = nType; | |
280 } | |
281 | |
282 void CPWL_Note_Icon::DrawThisAppearance(CFX_RenderDevice* pDevice, | |
283 CFX_Matrix* pUser2Device) { | |
284 CPWL_Utils::DrawIconAppStream(pDevice, pUser2Device, m_nType, GetClientRect(), | |
285 GetBackgroundColor(), PWL_DEFAULT_BLACKCOLOR, | |
286 GetTransparency()); | |
287 } | |
288 | |
289 CPWL_Note_CloseBox::CPWL_Note_CloseBox() : m_bMouseDown(FALSE) {} | |
290 | |
291 CPWL_Note_CloseBox::~CPWL_Note_CloseBox() {} | |
292 | |
293 void CPWL_Note_CloseBox::DrawThisAppearance(CFX_RenderDevice* pDevice, | |
294 CFX_Matrix* pUser2Device) { | |
295 CPWL_Button::DrawThisAppearance(pDevice, pUser2Device); | |
296 | |
297 CFX_FloatRect rcClient = GetClientRect(); | |
298 rcClient = CPWL_Utils::DeflateRect(rcClient, 2.0f); | |
299 | |
300 CFX_GraphStateData gsd; | |
301 gsd.m_LineWidth = 1.0f; | |
302 | |
303 CFX_PathData pathCross; | |
304 | |
305 if (m_bMouseDown) { | |
306 rcClient.left += 0.5f; | |
307 rcClient.right += 0.5f; | |
308 rcClient.top -= 0.5f; | |
309 rcClient.bottom -= 0.5f; | |
310 } | |
311 | |
312 pathCross.SetPointCount(4); | |
313 pathCross.SetPoint(0, rcClient.left, rcClient.bottom, FXPT_MOVETO); | |
314 pathCross.SetPoint(1, rcClient.right, rcClient.top, FXPT_LINETO); | |
315 pathCross.SetPoint(2, rcClient.left, rcClient.top, FXPT_MOVETO); | |
316 pathCross.SetPoint(3, rcClient.right, rcClient.bottom, FXPT_LINETO); | |
317 | |
318 pDevice->DrawPath( | |
319 &pathCross, pUser2Device, &gsd, 0, | |
320 CPWL_Utils::PWLColorToFXColor(GetTextColor(), GetTransparency()), | |
321 FXFILL_ALTERNATE); | |
322 } | |
323 | |
324 FX_BOOL CPWL_Note_CloseBox::OnLButtonDown(const CFX_FloatPoint& point, | |
325 uint32_t nFlag) { | |
326 SetBorderStyle(PBS_INSET); | |
327 InvalidateRect(NULL); | |
328 | |
329 m_bMouseDown = TRUE; | |
330 | |
331 return CPWL_Button::OnLButtonDown(point, nFlag); | |
332 } | |
333 | |
334 FX_BOOL CPWL_Note_CloseBox::OnLButtonUp(const CFX_FloatPoint& point, | |
335 uint32_t nFlag) { | |
336 m_bMouseDown = FALSE; | |
337 | |
338 SetBorderStyle(PBS_BEVELED); | |
339 InvalidateRect(NULL); | |
340 | |
341 return CPWL_Button::OnLButtonUp(point, nFlag); | |
342 } | |
343 | |
344 CPWL_Note_Contents::CPWL_Note_Contents() : m_pEdit(NULL) {} | |
345 | |
346 CPWL_Note_Contents::~CPWL_Note_Contents() {} | |
347 | |
348 CFX_ByteString CPWL_Note_Contents::GetClassName() const { | |
349 return "CPWL_Note_Contents"; | |
350 } | |
351 | |
352 void CPWL_Note_Contents::CreateChildWnd(const PWL_CREATEPARAM& cp) { | |
353 m_pEdit = new CPWL_Note_Edit; | |
354 PWL_CREATEPARAM ecp = cp; | |
355 ecp.pParentWnd = this; | |
356 ecp.dwFlags = PWS_VISIBLE | PWS_CHILD | PES_MULTILINE | PES_AUTORETURN | | |
357 PES_TEXTOVERFLOW | PES_UNDO | PES_SPELLCHECK; | |
358 | |
359 m_pEdit->EnableNotify(FALSE); | |
360 m_pEdit->Create(ecp); | |
361 m_pEdit->EnableNotify(TRUE); | |
362 } | |
363 | |
364 void CPWL_Note_Contents::SetText(const CFX_WideString& sText) { | |
365 if (m_pEdit) { | |
366 m_pEdit->EnableNotify(FALSE); | |
367 m_pEdit->SetText(sText.c_str()); | |
368 m_pEdit->EnableNotify(TRUE); | |
369 OnNotify(m_pEdit, PNM_NOTEEDITCHANGED, 0, 0); | |
370 } | |
371 } | |
372 | |
373 CFX_WideString CPWL_Note_Contents::GetText() const { | |
374 if (m_pEdit) | |
375 return m_pEdit->GetText(); | |
376 | |
377 return L""; | |
378 } | |
379 | |
380 int32_t CPWL_Note_Contents::CountSubItems() const { | |
381 return m_aChildren.GetSize() - 1; | |
382 } | |
383 | |
384 IPWL_NoteItem* CPWL_Note_Contents::GetSubItems(int32_t index) const { | |
385 int32_t nIndex = index + 1; | |
386 | |
387 if (nIndex > 0 && nIndex < m_aChildren.GetSize()) { | |
388 if (CPWL_Wnd* pChild = m_aChildren.GetAt(nIndex)) { | |
389 ASSERT(pChild->GetClassName() == "CPWL_NoteItem"); | |
390 CPWL_NoteItem* pItem = (CPWL_NoteItem*)pChild; | |
391 return pItem; | |
392 } | |
393 } | |
394 return NULL; | |
395 } | |
396 | |
397 IPWL_NoteItem* CPWL_Note_Contents::GetHitNoteItem(const CFX_FloatPoint& point) { | |
398 CFX_FloatPoint pt = ParentToChild(point); | |
399 | |
400 for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) { | |
401 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) { | |
402 if (pChild->GetClassName() == "CPWL_NoteItem") { | |
403 CPWL_NoteItem* pNoteItem = (CPWL_NoteItem*)pChild; | |
404 if (IPWL_NoteItem* pRet = pNoteItem->GetHitNoteItem(pt)) | |
405 return pRet; | |
406 } | |
407 } | |
408 } | |
409 return NULL; | |
410 } | |
411 | |
412 void CPWL_Note_Contents::OnNotify(CPWL_Wnd* pWnd, | |
413 uint32_t msg, | |
414 intptr_t wParam, | |
415 intptr_t lParam) { | |
416 switch (msg) { | |
417 case PNM_NOTEEDITCHANGED: { | |
418 int32_t nIndex = GetItemIndex(pWnd); | |
419 if (nIndex < 0) | |
420 nIndex = 0; | |
421 | |
422 m_pEdit->EnableNotify(FALSE); | |
423 ResetContent(nIndex); | |
424 m_pEdit->EnableNotify(TRUE); | |
425 | |
426 for (int32_t i = nIndex + 1, sz = m_aChildren.GetSize(); i < sz; i++) { | |
427 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) | |
428 pChild->OnNotify(this, PNM_NOTERESET, 0, 0); | |
429 } | |
430 | |
431 if (CPWL_Wnd* pParent = GetParentWindow()) { | |
432 pParent->OnNotify(this, PNM_NOTEEDITCHANGED, 0, 0); | |
433 } | |
434 } | |
435 return; | |
436 case PNM_SCROLLWINDOW: | |
437 SetScrollPos(CFX_FloatPoint(0.0f, *(FX_FLOAT*)lParam)); | |
438 ResetFace(); | |
439 InvalidateRect(NULL); | |
440 return; | |
441 case PNM_SETCARETINFO: | |
442 if (PWL_CARET_INFO* pInfo = (PWL_CARET_INFO*)wParam) { | |
443 PWL_CARET_INFO newInfo = *pInfo; | |
444 newInfo.bVisible = TRUE; | |
445 newInfo.ptHead = ChildToParent(pInfo->ptHead); | |
446 newInfo.ptFoot = ChildToParent(pInfo->ptFoot); | |
447 | |
448 if (CPWL_Wnd* pParent = GetParentWindow()) { | |
449 pParent->OnNotify(this, PNM_SETCARETINFO, (intptr_t)&newInfo, 0); | |
450 } | |
451 } | |
452 return; | |
453 case PNM_NOTERESET: { | |
454 m_pEdit->EnableNotify(FALSE); | |
455 ResetContent(0); | |
456 m_pEdit->EnableNotify(TRUE); | |
457 | |
458 for (int32_t i = 1, sz = m_aChildren.GetSize(); i < sz; i++) { | |
459 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) | |
460 pChild->OnNotify(this, PNM_NOTERESET, 0, 0); | |
461 } | |
462 | |
463 m_pEdit->EnableNotify(FALSE); | |
464 ResetContent(0); | |
465 m_pEdit->EnableNotify(TRUE); | |
466 } | |
467 return; | |
468 } | |
469 | |
470 CPWL_Wnd::OnNotify(pWnd, msg, wParam, lParam); | |
471 } | |
472 | |
473 FX_BOOL CPWL_Note_Contents::OnLButtonDown(const CFX_FloatPoint& point, | |
474 uint32_t nFlag) { | |
475 if (CPWL_Wnd::OnLButtonDown(point, nFlag)) | |
476 return TRUE; | |
477 | |
478 if (!m_pEdit->IsFocused()) { | |
479 m_pEdit->SetFocus(); | |
480 } | |
481 | |
482 return TRUE; | |
483 } | |
484 | |
485 void CPWL_Note_Contents::SetEditFocus(FX_BOOL bLast) { | |
486 if (!m_pEdit->IsFocused()) { | |
487 m_pEdit->SetFocus(); | |
488 m_pEdit->SetCaret(bLast ? m_pEdit->GetTotalWords() : 0); | |
489 } | |
490 } | |
491 | |
492 CPWL_Edit* CPWL_Note_Contents::GetEdit() const { | |
493 return m_pEdit; | |
494 } | |
495 | |
496 void CPWL_Note_Contents::EnableModify(FX_BOOL bEnabled) { | |
497 if (!bEnabled) | |
498 m_pEdit->AddFlag(PWS_READONLY); | |
499 else | |
500 m_pEdit->RemoveFlag(PWS_READONLY); | |
501 | |
502 for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) { | |
503 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) { | |
504 if (pChild->GetClassName() == "CPWL_NoteItem") { | |
505 CPWL_NoteItem* pNoteItem = (CPWL_NoteItem*)pChild; | |
506 pNoteItem->EnableModify(bEnabled); | |
507 } | |
508 } | |
509 } | |
510 } | |
511 | |
512 void CPWL_Note_Contents::EnableRead(FX_BOOL bEnabled) { | |
513 if (!bEnabled) | |
514 m_pEdit->AddFlag(PES_NOREAD); | |
515 else | |
516 m_pEdit->RemoveFlag(PES_NOREAD); | |
517 | |
518 for (int32_t i = 0, sz = m_aChildren.GetSize(); i < sz; i++) { | |
519 if (CPWL_Wnd* pChild = m_aChildren.GetAt(i)) { | |
520 if (pChild->GetClassName() == "CPWL_NoteItem") { | |
521 CPWL_NoteItem* pNoteItem = (CPWL_NoteItem*)pChild; | |
522 pNoteItem->EnableRead(bEnabled); | |
523 } | |
524 } | |
525 } | |
526 } | |
527 | |
528 CPWL_NoteItem::CPWL_NoteItem() | |
529 : m_pSubject(NULL), | |
530 m_pDateTime(NULL), | |
531 m_pContents(NULL), | |
532 m_pPrivateData(NULL), | |
533 m_sAuthor(L""), | |
534 m_fOldItemHeight(0.0f), | |
535 m_bSizeChanged(FALSE), | |
536 m_bAllowModify(TRUE) {} | |
537 | |
538 CPWL_NoteItem::~CPWL_NoteItem() {} | |
539 | |
540 CFX_ByteString CPWL_NoteItem::GetClassName() const { | |
541 return "CPWL_NoteItem"; | |
542 } | |
543 | |
544 void CPWL_NoteItem::CreateChildWnd(const PWL_CREATEPARAM& cp) { | |
545 CPWL_Color sTextColor; | |
546 | |
547 if (CPWL_Utils::IsBlackOrWhite(GetBackgroundColor())) | |
548 sTextColor = PWL_DEFAULT_WHITECOLOR; | |
549 else | |
550 sTextColor = PWL_DEFAULT_BLACKCOLOR; | |
551 | |
552 m_pSubject = new CPWL_Label; | |
553 PWL_CREATEPARAM scp = cp; | |
554 scp.pParentWnd = this; | |
555 scp.dwFlags = PWS_VISIBLE | PWS_CHILD | PES_LEFT | PES_TOP; | |
556 scp.sTextColor = sTextColor; | |
557 m_pSubject->Create(scp); | |
558 | |
559 m_pDateTime = new CPWL_Label; | |
560 PWL_CREATEPARAM dcp = cp; | |
561 dcp.pParentWnd = this; | |
562 dcp.dwFlags = PWS_VISIBLE | PWS_CHILD | PES_RIGHT | PES_TOP; | |
563 dcp.sTextColor = sTextColor; | |
564 m_pDateTime->Create(dcp); | |
565 | |
566 m_pContents = new CPWL_Note_Contents; | |
567 PWL_CREATEPARAM ccp = cp; | |
568 ccp.pParentWnd = this; | |
569 ccp.sBackgroundColor = | |
570 CPWL_Color(COLORTYPE_RGB, 240 / 255.0f, 240 / 255.0f, 240 / 255.0f); | |
571 ccp.dwFlags = PWS_VISIBLE | PWS_CHILD | PWS_BACKGROUND; | |
572 m_pContents->Create(ccp); | |
573 m_pContents->SetItemSpace(POPUP_ITEM_SPACE); | |
574 m_pContents->SetTopSpace(POPUP_ITEM_SPACE); | |
575 m_pContents->SetBottomSpace(POPUP_ITEM_SPACE); | |
576 } | |
577 | |
578 void CPWL_NoteItem::RePosChildWnd() { | |
579 if (IsValid()) { | |
580 CFX_FloatRect rcClient = GetClientRect(); | |
581 | |
582 CFX_FloatRect rcSubject = rcClient; | |
583 rcSubject.left += POPUP_ITEM_TEXT_INDENT; | |
584 rcSubject.top = rcClient.top; | |
585 rcSubject.right = | |
586 PWL_MIN(rcSubject.left + m_pSubject->GetContentRect().Width() + 1.0f, | |
587 rcClient.right); | |
588 rcSubject.bottom = rcSubject.top - m_pSubject->GetContentRect().Height(); | |
589 rcSubject.Normalize(); | |
590 m_pSubject->Move(rcSubject, TRUE, FALSE); | |
591 m_pSubject->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcSubject)); | |
592 | |
593 CFX_FloatRect rcDate = rcClient; | |
594 rcDate.right -= POPUP_ITEM_TEXT_INDENT; | |
595 rcDate.left = | |
596 PWL_MAX(rcDate.right - m_pDateTime->GetContentRect().Width() - 1.0f, | |
597 rcSubject.right); | |
598 rcDate.bottom = rcDate.top - m_pDateTime->GetContentRect().Height(); | |
599 rcDate.Normalize(); | |
600 m_pDateTime->Move(rcDate, TRUE, FALSE); | |
601 m_pDateTime->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcDate)); | |
602 | |
603 CFX_FloatRect rcContents = rcClient; | |
604 rcContents.left += 1.0f; | |
605 rcContents.right -= 1.0f; | |
606 rcContents.top = rcDate.bottom - POPUP_ITEM_HEAD_BOTTOM; | |
607 rcContents.bottom += POPUP_ITEM_BOTTOMWIDTH; | |
608 rcContents.Normalize(); | |
609 m_pContents->Move(rcContents, TRUE, FALSE); | |
610 m_pContents->SetVisible(CPWL_Utils::ContainsRect(rcClient, rcContents)); | |
611 } | |
612 | |
613 SetClipRect(CPWL_Utils::InflateRect(GetWindowRect(), 1.0f)); | |
614 } | |
615 | |
616 void CPWL_NoteItem::SetPrivateData(void* pData) { | |
617 m_pPrivateData = pData; | |
618 } | |
619 | |
620 void CPWL_NoteItem::SetBkColor(const CPWL_Color& color) { | |
621 CPWL_Color sBK = color; | |
622 SetBackgroundColor(sBK); | |
623 | |
624 CPWL_Color sTextColor; | |
625 | |
626 if (CPWL_Utils::IsBlackOrWhite(sBK)) | |
627 sTextColor = PWL_DEFAULT_WHITECOLOR; | |
628 else | |
629 sTextColor = PWL_DEFAULT_BLACKCOLOR; | |
630 | |
631 SetTextColor(sTextColor); | |
632 if (m_pSubject) | |
633 m_pSubject->SetTextColor(sTextColor); | |
634 if (m_pDateTime) | |
635 m_pDateTime->SetTextColor(sTextColor); | |
636 | |
637 InvalidateRect(nullptr); | |
638 } | |
639 | |
640 void CPWL_NoteItem::SetSubjectName(const CFX_WideString& sName) { | |
641 if (m_pSubject) | |
642 m_pSubject->SetText(sName.c_str()); | |
643 } | |
644 | |
645 void CPWL_NoteItem::SetDateTime(FX_SYSTEMTIME time) { | |
646 m_dtNote = time; | |
647 | |
648 CFX_WideString swTime; | |
649 swTime.Format(L"%04d-%02d-%02d %02d:%02d:%02d", time.wYear, time.wMonth, | |
650 time.wDay, time.wHour, time.wMinute, time.wSecond); | |
651 if (m_pDateTime) { | |
652 m_pDateTime->SetText(swTime.c_str()); | |
653 } | |
654 | |
655 RePosChildWnd(); | |
656 } | |
657 | |
658 void CPWL_NoteItem::SetContents(const CFX_WideString& sContents) { | |
659 if (m_pContents) { | |
660 m_pContents->SetText(sContents); | |
661 } | |
662 } | |
663 | |
664 CPWL_NoteItem* CPWL_NoteItem::GetParentNoteItem() const { | |
665 if (CPWL_Wnd* pParent = GetParentWindow()) { | |
666 if (CPWL_Wnd* pGrand = pParent->GetParentWindow()) { | |
667 ASSERT(pGrand->GetClassName() == "CPWL_NoteItem"); | |
668 return (CPWL_NoteItem*)pGrand; | |
669 } | |
670 } | |
671 | |
672 return NULL; | |
673 } | |
674 | |
675 IPWL_NoteItem* CPWL_NoteItem::GetParentItem() const { | |
676 return GetParentNoteItem(); | |
677 } | |
678 | |
679 CPWL_Edit* CPWL_NoteItem::GetEdit() const { | |
680 if (m_pContents) | |
681 return m_pContents->GetEdit(); | |
682 return NULL; | |
683 } | |
684 | |
685 void* CPWL_NoteItem::GetPrivateData() const { | |
686 return m_pPrivateData; | |
687 } | |
688 | |
689 CFX_WideString CPWL_NoteItem::GetAuthorName() const { | |
690 return m_sAuthor; | |
691 } | |
692 | |
693 CPWL_Color CPWL_NoteItem::GetBkColor() const { | |
694 return GetBackgroundColor(); | |
695 } | |
696 | |
697 CFX_WideString CPWL_NoteItem::GetContents() const { | |
698 if (m_pContents) | |
699 return m_pContents->GetText(); | |
700 | |
701 return L""; | |
702 } | |
703 | |
704 FX_SYSTEMTIME CPWL_NoteItem::GetDateTime() const { | |
705 return m_dtNote; | |
706 } | |
707 | |
708 CFX_WideString CPWL_NoteItem::GetSubjectName() const { | |
709 if (m_pSubject) | |
710 return m_pSubject->GetText(); | |
711 | |
712 return L""; | |
713 } | |
714 | |
715 int32_t CPWL_NoteItem::CountSubItems() const { | |
716 if (m_pContents) | |
717 return m_pContents->CountSubItems(); | |
718 | |
719 return 0; | |
720 } | |
721 | |
722 IPWL_NoteItem* CPWL_NoteItem::GetSubItems(int32_t index) const { | |
723 if (m_pContents) | |
724 return m_pContents->GetSubItems(index); | |
725 | |
726 return NULL; | |
727 } | |
728 | |
729 IPWL_NoteItem* CPWL_NoteItem::GetHitNoteItem(const CFX_FloatPoint& point) { | |
730 CFX_FloatPoint pt = ParentToChild(point); | |
731 | |
732 if (WndHitTest(pt)) { | |
733 if (m_pContents) { | |
734 if (IPWL_NoteItem* pNoteItem = m_pContents->GetHitNoteItem(pt)) | |
735 return pNoteItem; | |
736 } | |
737 | |
738 return this; | |
739 } | |
740 | |
741 return NULL; | |
742 } | |
743 | |
744 IPWL_NoteItem* CPWL_NoteItem::GetFocusedNoteItem() const { | |
745 if (const CPWL_Wnd* pWnd = GetFocused()) { | |
746 if (pWnd->GetClassName() == "CPWL_Edit") { | |
747 if (CPWL_Wnd* pParent = pWnd->GetParentWindow()) { | |
748 ASSERT(pParent->GetClassName() == "CPWL_Note_Contents"); | |
749 | |
750 if (CPWL_Wnd* pGrand = pParent->GetParentWindow()) { | |
751 ASSERT(pGrand->GetClassName() == "CPWL_NoteItem"); | |
752 return (CPWL_NoteItem*)pGrand; | |
753 } | |
754 } | |
755 } | |
756 } | |
757 | |
758 return NULL; | |
759 } | |
760 | |
761 FX_FLOAT CPWL_NoteItem::GetItemHeight(FX_FLOAT fLimitWidth) { | |
762 if (fLimitWidth > 0) { | |
763 if (!m_bSizeChanged) | |
764 return m_fOldItemHeight; | |
765 | |
766 m_bSizeChanged = FALSE; | |
767 | |
768 FX_FLOAT fRet = m_pDateTime->GetContentRect().Height(); | |
769 FX_FLOAT fBorderWidth = (FX_FLOAT)GetBorderWidth(); | |
770 if (fLimitWidth > fBorderWidth * 2) | |
771 fRet += m_pContents->GetContentsHeight(fLimitWidth - fBorderWidth * 2); | |
772 fRet += POPUP_ITEM_HEAD_BOTTOM + POPUP_ITEM_BOTTOMWIDTH + fBorderWidth * 2; | |
773 | |
774 return m_fOldItemHeight = fRet; | |
775 } | |
776 | |
777 return 0; | |
778 } | |
779 | |
780 FX_FLOAT CPWL_NoteItem::GetItemLeftMargin() { | |
781 return POPUP_ITEM_SIDEMARGIN; | |
782 } | |
783 | |
784 FX_FLOAT CPWL_NoteItem::GetItemRightMargin() { | |
785 return POPUP_ITEM_SIDEMARGIN; | |
786 } | |
787 | |
788 FX_BOOL CPWL_NoteItem::OnLButtonDown(const CFX_FloatPoint& point, | |
789 uint32_t nFlag) { | |
790 if (!m_pContents->WndHitTest(m_pContents->ParentToChild(point))) { | |
791 SetNoteFocus(FALSE); | |
792 } | |
793 | |
794 CPWL_Wnd::OnLButtonDown(point, nFlag); | |
795 | |
796 return TRUE; | |
797 } | |
798 | |
799 FX_BOOL CPWL_NoteItem::OnRButtonUp(const CFX_FloatPoint& point, | |
800 uint32_t nFlag) { | |
801 if (!m_pContents->WndHitTest(m_pContents->ParentToChild(point))) { | |
802 SetNoteFocus(FALSE); | |
803 PopupNoteItemMenu(point); | |
804 | |
805 return TRUE; | |
806 } | |
807 | |
808 return CPWL_Wnd::OnRButtonUp(point, nFlag); | |
809 } | |
810 | |
811 void CPWL_NoteItem::OnNotify(CPWL_Wnd* pWnd, | |
812 uint32_t msg, | |
813 intptr_t wParam, | |
814 intptr_t lParam) { | |
815 switch (msg) { | |
816 case PNM_NOTEEDITCHANGED: | |
817 m_bSizeChanged = TRUE; | |
818 | |
819 if (CPWL_Wnd* pParent = GetParentWindow()) { | |
820 pParent->OnNotify(this, PNM_NOTEEDITCHANGED, 0, 0); | |
821 } | |
822 return; | |
823 case PNM_SETCARETINFO: | |
824 if (PWL_CARET_INFO* pInfo = (PWL_CARET_INFO*)wParam) { | |
825 PWL_CARET_INFO newInfo = *pInfo; | |
826 newInfo.bVisible = TRUE; | |
827 newInfo.ptHead = ChildToParent(pInfo->ptHead); | |
828 newInfo.ptFoot = ChildToParent(pInfo->ptFoot); | |
829 | |
830 if (CPWL_Wnd* pParent = GetParentWindow()) { | |
831 pParent->OnNotify(this, PNM_SETCARETINFO, (intptr_t)&newInfo, 0); | |
832 } | |
833 } | |
834 return; | |
835 case PNM_NOTERESET: | |
836 m_bSizeChanged = TRUE; | |
837 m_pContents->OnNotify(this, PNM_NOTERESET, 0, 0); | |
838 | |
839 return; | |
840 } | |
841 | |
842 CPWL_Wnd::OnNotify(pWnd, msg, wParam, lParam); | |
843 } | |
844 | |
845 void CPWL_NoteItem::PopupNoteItemMenu(const CFX_FloatPoint& point) { | |
846 } | |
847 | |
848 void CPWL_NoteItem::SetNoteFocus(FX_BOOL bLast) { | |
849 m_pContents->SetEditFocus(bLast); | |
850 } | |
851 | |
852 void CPWL_NoteItem::EnableModify(FX_BOOL bEnabled) { | |
853 m_pContents->EnableModify(bEnabled); | |
854 m_bAllowModify = bEnabled; | |
855 } | |
856 | |
857 void CPWL_NoteItem::EnableRead(FX_BOOL bEnabled) { | |
858 m_pContents->EnableRead(bEnabled); | |
859 } | |
OLD | NEW |