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 "xfa/src/fwl/basewidget/fwl_editimp.h" | |
8 | |
9 #include <algorithm> | |
10 #include <vector> | |
11 | |
12 #include "xfa/include/fwl/basewidget/fwl_caret.h" | |
13 #include "xfa/include/fwl/basewidget/fwl_datetimepicker.h" | |
14 #include "xfa/include/fwl/core/fwl_theme.h" | |
15 #include "xfa/src/fde/fde_render.h" | |
16 #include "xfa/src/fde/fde_renderdevice.h" | |
17 #include "xfa/src/fee/ifde_txtedtpage.h" | |
18 #include "xfa/src/fwl/basewidget/fwl_caretimp.h" | |
19 #include "xfa/src/fwl/basewidget/fwl_comboboximp.h" | |
20 #include "xfa/src/fwl/basewidget/fwl_scrollbarimp.h" | |
21 #include "xfa/src/fwl/core/fwl_appimp.h" | |
22 #include "xfa/src/fwl/core/fwl_noteimp.h" | |
23 #include "xfa/src/fwl/core/fwl_targetimp.h" | |
24 #include "xfa/src/fwl/core/fwl_threadimp.h" | |
25 #include "xfa/src/fwl/core/fwl_widgetimp.h" | |
26 #include "xfa/src/fwl/core/fwl_widgetmgrimp.h" | |
27 | |
28 // static | |
29 IFWL_Edit* IFWL_Edit::Create(const CFWL_WidgetImpProperties& properties, | |
30 IFWL_Widget* pOuter) { | |
31 IFWL_Edit* pEdit = new IFWL_Edit; | |
32 CFWL_EditImp* pEditImpl = new CFWL_EditImp(properties, pOuter); | |
33 pEdit->SetImpl(pEditImpl); | |
34 pEditImpl->SetInterface(pEdit); | |
35 return pEdit; | |
36 } | |
37 // static | |
38 IFWL_Edit* IFWL_Edit::CreateComboEdit( | |
39 const CFWL_WidgetImpProperties& properties, | |
40 IFWL_Widget* pOuter) { | |
41 IFWL_Edit* pEdit = new IFWL_Edit; | |
42 CFWL_EditImp* pComboEditImpl = new CFWL_ComboEditImp(properties, pOuter); | |
43 pEdit->SetImpl(pComboEditImpl); | |
44 pComboEditImpl->SetInterface(pEdit); | |
45 return pEdit; | |
46 } | |
47 IFWL_Edit::IFWL_Edit() {} | |
48 FWL_ERR IFWL_Edit::SetText(const CFX_WideString& wsText) { | |
49 return static_cast<CFWL_EditImp*>(GetImpl())->SetText(wsText); | |
50 } | |
51 int32_t IFWL_Edit::GetTextLength() const { | |
52 return static_cast<CFWL_EditImp*>(GetImpl())->GetTextLength(); | |
53 } | |
54 FWL_ERR IFWL_Edit::GetText(CFX_WideString& wsText, | |
55 int32_t nStart, | |
56 int32_t nCount) const { | |
57 return static_cast<CFWL_EditImp*>(GetImpl())->GetText(wsText, nStart, nCount); | |
58 } | |
59 FWL_ERR IFWL_Edit::ClearText() { | |
60 return static_cast<CFWL_EditImp*>(GetImpl())->ClearText(); | |
61 } | |
62 int32_t IFWL_Edit::GetCaretPos() const { | |
63 return static_cast<CFWL_EditImp*>(GetImpl())->GetCaretPos(); | |
64 } | |
65 int32_t IFWL_Edit::SetCaretPos(int32_t nIndex, FX_BOOL bBefore) { | |
66 return static_cast<CFWL_EditImp*>(GetImpl())->SetCaretPos(nIndex, bBefore); | |
67 } | |
68 FWL_ERR IFWL_Edit::AddSelRange(int32_t nStart, int32_t nCount) { | |
69 return static_cast<CFWL_EditImp*>(GetImpl())->AddSelRange(nStart, nCount); | |
70 } | |
71 int32_t IFWL_Edit::CountSelRanges() { | |
72 return static_cast<CFWL_EditImp*>(GetImpl())->CountSelRanges(); | |
73 } | |
74 int32_t IFWL_Edit::GetSelRange(int32_t nIndex, int32_t& nStart) { | |
75 return static_cast<CFWL_EditImp*>(GetImpl())->GetSelRange(nIndex, nStart); | |
76 } | |
77 FWL_ERR IFWL_Edit::ClearSelections() { | |
78 return static_cast<CFWL_EditImp*>(GetImpl())->ClearSelections(); | |
79 } | |
80 int32_t IFWL_Edit::GetLimit() { | |
81 return static_cast<CFWL_EditImp*>(GetImpl())->GetLimit(); | |
82 } | |
83 FWL_ERR IFWL_Edit::SetLimit(int32_t nLimit) { | |
84 return static_cast<CFWL_EditImp*>(GetImpl())->SetLimit(nLimit); | |
85 } | |
86 FWL_ERR IFWL_Edit::SetAliasChar(FX_WCHAR wAlias) { | |
87 return static_cast<CFWL_EditImp*>(GetImpl())->SetAliasChar(wAlias); | |
88 } | |
89 FWL_ERR IFWL_Edit::Insert(int32_t nStart, | |
90 const FX_WCHAR* lpText, | |
91 int32_t nLen) { | |
92 return static_cast<CFWL_EditImp*>(GetImpl())->Insert(nStart, lpText, nLen); | |
93 } | |
94 FWL_ERR IFWL_Edit::DeleteSelections() { | |
95 return static_cast<CFWL_EditImp*>(GetImpl())->DeleteSelections(); | |
96 } | |
97 FWL_ERR IFWL_Edit::DeleteRange(int32_t nStart, int32_t nCount) { | |
98 return static_cast<CFWL_EditImp*>(GetImpl())->DeleteRange(nStart, nCount); | |
99 } | |
100 FWL_ERR IFWL_Edit::ReplaceSelections(const CFX_WideStringC& wsReplace) { | |
101 return static_cast<CFWL_EditImp*>(GetImpl())->ReplaceSelections(wsReplace); | |
102 } | |
103 FWL_ERR IFWL_Edit::Replace(int32_t nStart, | |
104 int32_t nLen, | |
105 const CFX_WideStringC& wsReplace) { | |
106 return static_cast<CFWL_EditImp*>(GetImpl()) | |
107 ->Replace(nStart, nLen, wsReplace); | |
108 } | |
109 FWL_ERR IFWL_Edit::DoClipboard(int32_t iCmd) { | |
110 return static_cast<CFWL_EditImp*>(GetImpl())->DoClipboard(iCmd); | |
111 } | |
112 FX_BOOL IFWL_Edit::Copy(CFX_WideString& wsCopy) { | |
113 return static_cast<CFWL_EditImp*>(GetImpl())->Copy(wsCopy); | |
114 } | |
115 FX_BOOL IFWL_Edit::Cut(CFX_WideString& wsCut) { | |
116 return static_cast<CFWL_EditImp*>(GetImpl())->Cut(wsCut); | |
117 } | |
118 FX_BOOL IFWL_Edit::Paste(const CFX_WideString& wsPaste) { | |
119 return static_cast<CFWL_EditImp*>(GetImpl())->Paste(wsPaste); | |
120 } | |
121 FX_BOOL IFWL_Edit::Delete() { | |
122 return static_cast<CFWL_EditImp*>(GetImpl())->Delete(); | |
123 } | |
124 FX_BOOL IFWL_Edit::Redo(const CFX_ByteStringC& bsRecord) { | |
125 return static_cast<CFWL_EditImp*>(GetImpl())->Redo(bsRecord); | |
126 } | |
127 FX_BOOL IFWL_Edit::Undo(const CFX_ByteStringC& bsRecord) { | |
128 return static_cast<CFWL_EditImp*>(GetImpl())->Undo(bsRecord); | |
129 } | |
130 FX_BOOL IFWL_Edit::Undo() { | |
131 return static_cast<CFWL_EditImp*>(GetImpl())->Undo(); | |
132 } | |
133 FX_BOOL IFWL_Edit::Redo() { | |
134 return static_cast<CFWL_EditImp*>(GetImpl())->Redo(); | |
135 } | |
136 FX_BOOL IFWL_Edit::CanUndo() { | |
137 return static_cast<CFWL_EditImp*>(GetImpl())->CanUndo(); | |
138 } | |
139 FX_BOOL IFWL_Edit::CanRedo() { | |
140 return static_cast<CFWL_EditImp*>(GetImpl())->CanRedo(); | |
141 } | |
142 FWL_ERR IFWL_Edit::SetTabWidth(FX_FLOAT fTabWidth, FX_BOOL bEquidistant) { | |
143 return static_cast<CFWL_EditImp*>(GetImpl()) | |
144 ->SetTabWidth(fTabWidth, bEquidistant); | |
145 } | |
146 FWL_ERR IFWL_Edit::SetOuter(IFWL_Widget* pOuter) { | |
147 return static_cast<CFWL_EditImp*>(GetImpl())->SetOuter(pOuter); | |
148 } | |
149 FWL_ERR IFWL_Edit::SetNumberRange(int32_t iMin, int32_t iMax) { | |
150 return static_cast<CFWL_EditImp*>(GetImpl())->SetNumberRange(iMin, iMax); | |
151 } | |
152 FWL_ERR IFWL_Edit::SetBackColor(FX_DWORD dwColor) { | |
153 return static_cast<CFWL_EditImp*>(GetImpl())->SetBackgroundColor(dwColor); | |
154 } | |
155 FWL_ERR IFWL_Edit::SetFont(const CFX_WideString& wsFont, FX_FLOAT fSize) { | |
156 return static_cast<CFWL_EditImp*>(GetImpl())->SetFont(wsFont, fSize); | |
157 } | |
158 void IFWL_Edit::SetScrollOffset(FX_FLOAT fScrollOffset) { | |
159 return static_cast<CFWL_EditImp*>(GetImpl())->SetScrollOffset(fScrollOffset); | |
160 } | |
161 FX_BOOL IFWL_Edit::GetSuggestWords(CFX_PointF pointf, | |
162 std::vector<CFX_ByteString>& sSuggest) { | |
163 return static_cast<CFWL_EditImp*>(GetImpl()) | |
164 ->GetSuggestWords(pointf, sSuggest); | |
165 } | |
166 FX_BOOL IFWL_Edit::ReplaceSpellCheckWord(CFX_PointF pointf, | |
167 const CFX_ByteStringC& bsReplace) { | |
168 return static_cast<CFWL_EditImp*>(GetImpl()) | |
169 ->ReplaceSpellCheckWord(pointf, bsReplace); | |
170 } | |
171 #define FWL_EDIT_Margin 3 | |
172 CFWL_EditImp::CFWL_EditImp(const CFWL_WidgetImpProperties& properties, | |
173 IFWL_Widget* pOuter) | |
174 : CFWL_WidgetImp(properties, pOuter), | |
175 m_fVAlignOffset(0.0f), | |
176 m_fScrollOffsetX(0.0f), | |
177 m_fScrollOffsetY(0.0f), | |
178 m_pEdtEngine(NULL), | |
179 m_bLButtonDown(FALSE), | |
180 m_nSelStart(0), | |
181 m_nLimit(-1), | |
182 m_fSpaceAbove(0), | |
183 m_fSpaceBelow(0), | |
184 m_fFontSize(0), | |
185 m_bSetRange(FALSE), | |
186 m_iMin(-1), | |
187 m_iMax(0xFFFFFFF), | |
188 m_backColor(0), | |
189 m_updateBackColor(FALSE), | |
190 m_iCurRecord(-1), | |
191 m_iMaxRecord(128) { | |
192 m_rtClient.Reset(); | |
193 m_rtEngine.Reset(); | |
194 m_rtStatic.Reset(); | |
195 } | |
196 CFWL_EditImp::~CFWL_EditImp() { | |
197 if (m_pEdtEngine) { | |
198 m_pEdtEngine->Release(); | |
199 m_pEdtEngine = NULL; | |
200 } | |
201 ClearRecord(); | |
202 } | |
203 FWL_ERR CFWL_EditImp::GetClassName(CFX_WideString& wsClass) const { | |
204 wsClass = FWL_CLASS_Edit; | |
205 return FWL_ERR_Succeeded; | |
206 } | |
207 FX_DWORD CFWL_EditImp::GetClassID() const { | |
208 return FWL_CLASSHASH_Edit; | |
209 } | |
210 FWL_ERR CFWL_EditImp::Initialize() { | |
211 if (CFWL_WidgetImp::Initialize() != FWL_ERR_Succeeded) | |
212 return FWL_ERR_Indefinite; | |
213 if (!m_pDelegate) { | |
214 m_pDelegate = new CFWL_EditImpDelegate(this); | |
215 } | |
216 InitCaret(); | |
217 if (!m_pEdtEngine) { | |
218 InitEngine(); | |
219 } | |
220 return FWL_ERR_Succeeded; | |
221 } | |
222 FWL_ERR CFWL_EditImp::Finalize() { | |
223 if (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) { | |
224 ShowCaret(FALSE); | |
225 } | |
226 if (m_pHorzScrollBar) { | |
227 m_pHorzScrollBar->Finalize(); | |
228 } | |
229 if (m_pVertScrollBar) { | |
230 m_pVertScrollBar->Finalize(); | |
231 } | |
232 delete m_pDelegate; | |
233 m_pDelegate = nullptr; | |
234 return CFWL_WidgetImp::Finalize(); | |
235 } | |
236 FWL_ERR CFWL_EditImp::GetWidgetRect(CFX_RectF& rect, FX_BOOL bAutoSize) { | |
237 if (bAutoSize) { | |
238 rect.Set(0, 0, 0, 0); | |
239 if (m_pEdtEngine) { | |
240 int32_t iTextLen = m_pEdtEngine->GetTextLength(); | |
241 if (iTextLen > 0) { | |
242 CFX_WideString wsText; | |
243 m_pEdtEngine->GetText(wsText, 0); | |
244 CFX_SizeF sz = CalcTextSize( | |
245 wsText, m_pProperties->m_pThemeProvider, | |
246 m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine); | |
247 rect.Set(0, 0, sz.x, sz.y); | |
248 } | |
249 } | |
250 CFWL_WidgetImp::GetWidgetRect(rect, TRUE); | |
251 } else { | |
252 rect = m_pProperties->m_rtWidget; | |
253 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) { | |
254 if (IsShowScrollBar(TRUE)) { | |
255 FX_FLOAT* pfWidth = static_cast<FX_FLOAT*>( | |
256 GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth)); | |
257 rect.width += *pfWidth; | |
258 rect.width += FWL_EDIT_Margin; | |
259 } | |
260 if (IsShowScrollBar(FALSE)) { | |
261 FX_FLOAT* pfWidth = static_cast<FX_FLOAT*>( | |
262 GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth)); | |
263 rect.height += *pfWidth; | |
264 rect.height += FWL_EDIT_Margin; | |
265 } | |
266 } | |
267 } | |
268 return FWL_ERR_Succeeded; | |
269 } | |
270 FWL_ERR CFWL_EditImp::SetStates(FX_DWORD dwStates, FX_BOOL bSet) { | |
271 if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Invisible) || | |
272 (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) { | |
273 ShowCaret(FALSE); | |
274 } | |
275 return CFWL_WidgetImp::SetStates(dwStates, bSet); | |
276 } | |
277 FWL_ERR CFWL_EditImp::SetWidgetRect(const CFX_RectF& rect) { | |
278 return CFWL_WidgetImp::SetWidgetRect(rect); | |
279 } | |
280 FWL_ERR CFWL_EditImp::Update() { | |
281 if (IsLocked()) { | |
282 return FWL_ERR_Indefinite; | |
283 } | |
284 if (!m_pProperties->m_pThemeProvider) { | |
285 m_pProperties->m_pThemeProvider = GetAvailableTheme(); | |
286 } | |
287 Layout(); | |
288 if (m_rtClient.IsEmpty()) { | |
289 return FWL_ERR_Indefinite; | |
290 } | |
291 UpdateEditEngine(); | |
292 UpdateVAlignment(); | |
293 UpdateScroll(); | |
294 InitCaret(); | |
295 return FWL_ERR_Succeeded; | |
296 } | |
297 FX_DWORD CFWL_EditImp::HitTest(FX_FLOAT fx, FX_FLOAT fy) { | |
298 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) { | |
299 if (IsShowScrollBar(TRUE)) { | |
300 CFX_RectF rect; | |
301 m_pVertScrollBar->GetWidgetRect(rect); | |
302 if (rect.Contains(fx, fy)) { | |
303 return FWL_WGTHITTEST_VScrollBar; | |
304 } | |
305 } | |
306 if (IsShowScrollBar(FALSE)) { | |
307 CFX_RectF rect; | |
308 m_pHorzScrollBar->GetWidgetRect(rect); | |
309 if (rect.Contains(fx, fy)) { | |
310 return FWL_WGTHITTEST_HScrollBar; | |
311 } | |
312 } | |
313 } | |
314 if (m_rtClient.Contains(fx, fy)) { | |
315 return FWL_WGTHITTEST_Edit; | |
316 } | |
317 return FWL_WGTHITTEST_Unknown; | |
318 } | |
319 #define FX_EDIT_ISLATINWORD(u) \ | |
320 (u == 0x2D || (u <= 0x005A && u >= 0x0041) || \ | |
321 (u <= 0x007A && u >= 0x0061) || (u <= 0x02AF && u >= 0x00C0) || \ | |
322 u == 0x0027) | |
323 static void AddSquigglyPath(CFX_Path& PathData, | |
324 FX_FLOAT fStartX, | |
325 FX_FLOAT fEndX, | |
326 FX_FLOAT fY, | |
327 FX_FLOAT fStep) { | |
328 PathData.MoveTo(fStartX, fY); | |
329 FX_FLOAT fx; | |
330 int32_t i; | |
331 for (i = 1, fx = fStartX + fStep; fx < fEndX; fx += fStep, i++) { | |
332 PathData.LineTo(fx, fY + (i & 1) * fStep); | |
333 } | |
334 } | |
335 void CFWL_EditImp::AddSpellCheckObj(CFX_Path& PathData, | |
336 int32_t nStart, | |
337 int32_t nCount, | |
338 FX_FLOAT fOffSetX, | |
339 FX_FLOAT fOffSetY) { | |
340 FX_FLOAT fStartX = 0.0f; | |
341 FX_FLOAT fEndX = 0.0f; | |
342 FX_FLOAT fY = 0.0f; | |
343 FX_FLOAT fStep = 0.0f; | |
344 IFDE_TxtEdtPage* pPage = m_pEdtEngine->GetPage(0); | |
345 CFX_RectFArray rectArray; | |
346 CFX_RectF rectText; | |
347 const FDE_TXTEDTPARAMS* txtEdtParams = m_pEdtEngine->GetEditParams(); | |
348 FX_FLOAT fAsent = (FX_FLOAT)txtEdtParams->pFont->GetAscent() * | |
349 txtEdtParams->fFontSize / 1000; | |
350 pPage->CalcRangeRectArray(nStart, nCount, rectArray); | |
351 for (int i = 0; i < rectArray.GetSize(); i++) { | |
352 rectText = rectArray.GetAt(i); | |
353 fY = rectText.top + fAsent + fOffSetY; | |
354 fStep = txtEdtParams->fFontSize / 16.0f; | |
355 fStartX = rectText.left + fOffSetX; | |
356 fEndX = fStartX + rectText.Width(); | |
357 AddSquigglyPath(PathData, fStartX, fEndX, fY, fStep); | |
358 } | |
359 } | |
360 int32_t CFWL_EditImp::GetWordAtPoint(CFX_PointF pointf, int32_t& nCount) { | |
361 return 0; | |
362 } | |
363 FX_BOOL CFWL_EditImp::GetSuggestWords(CFX_PointF pointf, | |
364 std::vector<CFX_ByteString>& sSuggest) { | |
365 int32_t nWordCount = 0; | |
366 int32_t nWordStart = GetWordAtPoint(pointf, nWordCount); | |
367 if (nWordCount < 1) { | |
368 return FALSE; | |
369 } | |
370 CFX_WideString wsSpell; | |
371 GetText(wsSpell, nWordStart, nWordCount); | |
372 CFX_ByteString sLatinWord; | |
373 for (int i = 0; i < nWordCount; i++) { | |
374 if (!FX_EDIT_ISLATINWORD(wsSpell[i])) { | |
375 break; | |
376 } | |
377 sLatinWord += (FX_CHAR)wsSpell[i]; | |
378 } | |
379 if (sLatinWord.IsEmpty()) { | |
380 return FALSE; | |
381 } | |
382 CFWL_EvtEdtCheckWord checkWordEvent; | |
383 checkWordEvent.m_pSrcTarget = m_pInterface; | |
384 checkWordEvent.bsWord = sLatinWord; | |
385 checkWordEvent.bCheckWord = TRUE; | |
386 DispatchEvent(&checkWordEvent); | |
387 if (checkWordEvent.bCheckWord) { | |
388 return FALSE; | |
389 } | |
390 CFWL_EvtEdtGetSuggestWords suggestWordsEvent; | |
391 suggestWordsEvent.m_pSrcTarget = m_pInterface; | |
392 suggestWordsEvent.bsWord = sLatinWord; | |
393 suggestWordsEvent.bsArraySuggestWords = sSuggest; | |
394 suggestWordsEvent.bSuggestWords = FALSE; | |
395 DispatchEvent(&checkWordEvent); | |
396 return suggestWordsEvent.bSuggestWords; | |
397 } | |
398 FX_BOOL CFWL_EditImp::ReplaceSpellCheckWord(CFX_PointF pointf, | |
399 const CFX_ByteStringC& bsReplace) { | |
400 int32_t nWordCount = 0; | |
401 int32_t nWordStart = GetWordAtPoint(pointf, nWordCount); | |
402 if (nWordCount < 1) { | |
403 return FALSE; | |
404 } | |
405 CFX_WideString wsSpell; | |
406 GetText(wsSpell, nWordStart, nWordCount); | |
407 for (int i = 0; i < nWordCount; i++) { | |
408 if (!FX_EDIT_ISLATINWORD(wsSpell[i])) { | |
409 nWordCount = i; | |
410 break; | |
411 } | |
412 } | |
413 int32_t nDestLen = bsReplace.GetLength(); | |
414 CFX_WideString wsDest; | |
415 FX_WCHAR* pBuffer = wsDest.GetBuffer(nDestLen); | |
416 for (int32_t i = 0; i < nDestLen; i++) { | |
417 pBuffer[i] = bsReplace[i]; | |
418 } | |
419 wsDest.ReleaseBuffer(nDestLen); | |
420 Replace(nWordStart, nWordCount, wsDest); | |
421 return TRUE; | |
422 } | |
423 void CFWL_EditImp::DrawSpellCheck(CFX_Graphics* pGraphics, | |
424 const CFX_Matrix* pMatrix) { | |
425 pGraphics->SaveGraphState(); | |
426 if (pMatrix) { | |
427 pGraphics->ConcatMatrix(const_cast<CFX_Matrix*>(pMatrix)); | |
428 } | |
429 FX_ARGB cr = 0xFFFF0000; | |
430 CFX_Color crLine(cr); | |
431 CFWL_EvtEdtCheckWord checkWordEvent; | |
432 checkWordEvent.m_pSrcTarget = m_pInterface; | |
433 CFX_ByteString sLatinWord; | |
434 CFX_Path pathSpell; | |
435 pathSpell.Create(); | |
436 int32_t nStart = 0; | |
437 FX_FLOAT fOffSetX = m_rtEngine.left - m_fScrollOffsetX; | |
438 FX_FLOAT fOffSetY = m_rtEngine.top - m_fScrollOffsetY + m_fVAlignOffset; | |
439 CFX_WideString wsSpell; | |
440 GetText(wsSpell); | |
441 int32_t nContentLen = wsSpell.GetLength(); | |
442 for (int i = 0; i < nContentLen; i++) { | |
443 if (FX_EDIT_ISLATINWORD(wsSpell[i])) { | |
444 if (sLatinWord.IsEmpty()) { | |
445 nStart = i; | |
446 } | |
447 sLatinWord += (FX_CHAR)wsSpell[i]; | |
448 } else { | |
449 checkWordEvent.bsWord = sLatinWord; | |
450 checkWordEvent.bCheckWord = TRUE; | |
451 DispatchEvent(&checkWordEvent); | |
452 if (!sLatinWord.IsEmpty() && !checkWordEvent.bCheckWord) { | |
453 AddSpellCheckObj(pathSpell, nStart, sLatinWord.GetLength(), fOffSetX, | |
454 fOffSetY); | |
455 } | |
456 sLatinWord.Empty(); | |
457 } | |
458 } | |
459 checkWordEvent.bsWord = sLatinWord; | |
460 checkWordEvent.bCheckWord = TRUE; | |
461 DispatchEvent(&checkWordEvent); | |
462 if (!sLatinWord.IsEmpty() && !checkWordEvent.bCheckWord) { | |
463 AddSpellCheckObj(pathSpell, nStart, sLatinWord.GetLength(), fOffSetX, | |
464 fOffSetY); | |
465 } | |
466 if (!pathSpell.IsEmpty()) { | |
467 CFX_RectF rtClip = m_rtEngine; | |
468 CFX_Matrix mt; | |
469 mt.Set(1, 0, 0, 1, fOffSetX, fOffSetY); | |
470 if (pMatrix) { | |
471 pMatrix->TransformRect(rtClip); | |
472 mt.Concat(*pMatrix); | |
473 } | |
474 pGraphics->SetClipRect(rtClip); | |
475 pGraphics->SetStrokeColor(&crLine); | |
476 pGraphics->SetLineWidth(0); | |
477 pGraphics->StrokePath(&pathSpell, NULL); | |
478 } | |
479 pGraphics->RestoreGraphState(); | |
480 } | |
481 FWL_ERR CFWL_EditImp::DrawWidget(CFX_Graphics* pGraphics, | |
482 const CFX_Matrix* pMatrix) { | |
483 if (!pGraphics) | |
484 return FWL_ERR_Indefinite; | |
485 if (!m_pProperties->m_pThemeProvider) | |
486 return FWL_ERR_Indefinite; | |
487 if (m_rtClient.IsEmpty()) { | |
488 return FWL_ERR_Indefinite; | |
489 } | |
490 IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider; | |
491 if (!m_pWidgetMgr->IsFormDisabled()) { | |
492 DrawTextBk(pGraphics, pTheme, pMatrix); | |
493 } | |
494 if (m_pEdtEngine) { | |
495 DrawContent(pGraphics, pTheme, pMatrix); | |
496 } | |
497 if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) && | |
498 !(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly)) { | |
499 DrawSpellCheck(pGraphics, pMatrix); | |
500 } | |
501 if (HasBorder()) { | |
502 DrawBorder(pGraphics, FWL_PART_EDT_Border, pTheme, pMatrix); | |
503 } | |
504 if (HasEdge()) { | |
505 DrawEdge(pGraphics, FWL_PART_EDT_Edge, pTheme, pMatrix); | |
506 } | |
507 return FWL_ERR_Succeeded; | |
508 } | |
509 FWL_ERR CFWL_EditImp::SetThemeProvider(IFWL_ThemeProvider* pThemeProvider) { | |
510 if (!pThemeProvider) | |
511 return FWL_ERR_Indefinite; | |
512 if (m_pHorzScrollBar) { | |
513 m_pHorzScrollBar->SetThemeProvider(pThemeProvider); | |
514 } | |
515 if (m_pVertScrollBar) { | |
516 m_pVertScrollBar->SetThemeProvider(pThemeProvider); | |
517 } | |
518 if (m_pCaret) { | |
519 m_pCaret->SetThemeProvider(pThemeProvider); | |
520 } | |
521 m_pProperties->m_pThemeProvider = pThemeProvider; | |
522 return FWL_ERR_Succeeded; | |
523 } | |
524 FWL_ERR CFWL_EditImp::SetText(const CFX_WideString& wsText) { | |
525 m_pEdtEngine->SetText(wsText); | |
526 return FWL_ERR_Succeeded; | |
527 } | |
528 int32_t CFWL_EditImp::GetTextLength() const { | |
529 if (!m_pEdtEngine) | |
530 return -1; | |
531 return m_pEdtEngine->GetTextLength(); | |
532 } | |
533 FWL_ERR CFWL_EditImp::GetText(CFX_WideString& wsText, | |
534 int32_t nStart, | |
535 int32_t nCount) const { | |
536 if (!m_pEdtEngine) | |
537 return FWL_ERR_Succeeded; | |
538 m_pEdtEngine->GetText(wsText, nStart, nCount); | |
539 return FWL_ERR_Succeeded; | |
540 } | |
541 FWL_ERR CFWL_EditImp::ClearText() { | |
542 if (!m_pEdtEngine) | |
543 return FWL_ERR_Succeeded; | |
544 m_pEdtEngine->ClearText(); | |
545 return FWL_ERR_Succeeded; | |
546 } | |
547 int32_t CFWL_EditImp::GetCaretPos() const { | |
548 if (!m_pEdtEngine) | |
549 return -1; | |
550 return m_pEdtEngine->GetCaretPos(); | |
551 } | |
552 int32_t CFWL_EditImp::SetCaretPos(int32_t nIndex, FX_BOOL bBefore) { | |
553 if (!m_pEdtEngine) | |
554 return -1; | |
555 return m_pEdtEngine->SetCaretPos(nIndex, bBefore); | |
556 } | |
557 FWL_ERR CFWL_EditImp::AddSelRange(int32_t nStart, int32_t nCount) { | |
558 if (!m_pEdtEngine) | |
559 return FWL_ERR_Succeeded; | |
560 m_pEdtEngine->AddSelRange(nStart, nCount); | |
561 return FWL_ERR_Succeeded; | |
562 } | |
563 int32_t CFWL_EditImp::CountSelRanges() { | |
564 if (!m_pEdtEngine) | |
565 return 0; | |
566 return m_pEdtEngine->CountSelRanges(); | |
567 return FWL_ERR_Succeeded; | |
568 } | |
569 int32_t CFWL_EditImp::GetSelRange(int32_t nIndex, int32_t& nStart) { | |
570 if (!m_pEdtEngine) | |
571 return -1; | |
572 return m_pEdtEngine->GetSelRange(nIndex, nStart); | |
573 } | |
574 FWL_ERR CFWL_EditImp::ClearSelections() { | |
575 if (!m_pEdtEngine) | |
576 return FWL_ERR_Succeeded; | |
577 m_pEdtEngine->ClearSelection(); | |
578 return FWL_ERR_Succeeded; | |
579 } | |
580 int32_t CFWL_EditImp::GetLimit() { | |
581 return m_nLimit; | |
582 } | |
583 FWL_ERR CFWL_EditImp::SetLimit(int32_t nLimit) { | |
584 m_nLimit = nLimit; | |
585 if (!m_pEdtEngine) | |
586 return FWL_ERR_Succeeded; | |
587 m_pEdtEngine->SetLimit(nLimit); | |
588 return FWL_ERR_Succeeded; | |
589 } | |
590 FWL_ERR CFWL_EditImp::SetAliasChar(FX_WCHAR wAlias) { | |
591 if (!m_pEdtEngine) | |
592 return FWL_ERR_Indefinite; | |
593 m_pEdtEngine->SetAliasChar(wAlias); | |
594 return FWL_ERR_Succeeded; | |
595 } | |
596 FWL_ERR CFWL_EditImp::Insert(int32_t nStart, | |
597 const FX_WCHAR* lpText, | |
598 int32_t nLen) { | |
599 if (!m_pEdtEngine) | |
600 return FWL_ERR_Succeeded; | |
601 if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly) || | |
602 (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) { | |
603 return FWL_ERR_Indefinite; | |
604 } | |
605 m_pEdtEngine->Insert(nStart, lpText, nLen); | |
606 return FWL_ERR_Succeeded; | |
607 } | |
608 FWL_ERR CFWL_EditImp::DeleteSelections() { | |
609 if (!m_pEdtEngine) | |
610 return FWL_ERR_Succeeded; | |
611 int32_t iCount = m_pEdtEngine->CountSelRanges(); | |
612 if (iCount > 0) { | |
613 m_pEdtEngine->Delete(-1); | |
614 } | |
615 return FWL_ERR_Succeeded; | |
616 } | |
617 FWL_ERR CFWL_EditImp::DeleteRange(int32_t nStart, int32_t nCount) { | |
618 if (!m_pEdtEngine) | |
619 return FWL_ERR_Succeeded; | |
620 m_pEdtEngine->DeleteRange(nStart, nCount); | |
621 return FWL_ERR_Succeeded; | |
622 } | |
623 FWL_ERR CFWL_EditImp::ReplaceSelections(const CFX_WideStringC& wsReplace) { | |
624 if (!m_pEdtEngine) | |
625 return FWL_ERR_Succeeded; | |
626 int32_t iCount = m_pEdtEngine->CountSelRanges(); | |
627 for (int i = 0; i < iCount; i++) { | |
628 int32_t nStart; | |
629 int32_t nCount = m_pEdtEngine->GetSelRange(i, nStart); | |
630 m_pEdtEngine->Replace(nStart, nCount, wsReplace); | |
631 } | |
632 return FWL_ERR_Succeeded; | |
633 } | |
634 FWL_ERR CFWL_EditImp::Replace(int32_t nStart, | |
635 int32_t nLen, | |
636 const CFX_WideStringC& wsReplace) { | |
637 if (!m_pEdtEngine) | |
638 return FWL_ERR_Succeeded; | |
639 m_pEdtEngine->Replace(nStart, nLen, wsReplace); | |
640 return FWL_ERR_Succeeded; | |
641 } | |
642 FWL_ERR CFWL_EditImp::DoClipboard(int32_t iCmd) { | |
643 if (!m_pEdtEngine) | |
644 return FWL_ERR_Succeeded; | |
645 if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly) || | |
646 (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) { | |
647 return FWL_ERR_Succeeded; | |
648 } | |
649 return FWL_ERR_Indefinite; | |
650 } | |
651 FX_BOOL CFWL_EditImp::Copy(CFX_WideString& wsCopy) { | |
652 if (!m_pEdtEngine) | |
653 return FALSE; | |
654 int32_t nCount = m_pEdtEngine->CountSelRanges(); | |
655 if (nCount == 0) { | |
656 return FALSE; | |
657 } | |
658 wsCopy.Empty(); | |
659 CFX_WideString wsTemp; | |
660 int32_t nStart, nLength; | |
661 for (int32_t i = 0; i < nCount; i++) { | |
662 nLength = m_pEdtEngine->GetSelRange(i, nStart); | |
663 m_pEdtEngine->GetText(wsTemp, nStart, nLength); | |
664 wsCopy += wsTemp; | |
665 wsTemp.Empty(); | |
666 } | |
667 return TRUE; | |
668 } | |
669 FX_BOOL CFWL_EditImp::Cut(CFX_WideString& wsCut) { | |
670 if (!m_pEdtEngine) | |
671 return FALSE; | |
672 int32_t nCount = m_pEdtEngine->CountSelRanges(); | |
673 if (nCount == 0) { | |
674 return FALSE; | |
675 } | |
676 wsCut.Empty(); | |
677 CFX_WideString wsTemp; | |
678 int32_t nStart, nLength; | |
679 for (int32_t i = 0; i < nCount; i++) { | |
680 nLength = m_pEdtEngine->GetSelRange(i, nStart); | |
681 m_pEdtEngine->GetText(wsTemp, nStart, nLength); | |
682 wsCut += wsTemp; | |
683 wsTemp.Empty(); | |
684 } | |
685 m_pEdtEngine->Delete(0); | |
686 return TRUE; | |
687 } | |
688 FX_BOOL CFWL_EditImp::Paste(const CFX_WideString& wsPaste) { | |
689 if (!m_pEdtEngine) | |
690 return FALSE; | |
691 int32_t nCaret = m_pEdtEngine->GetCaretPos(); | |
692 int32_t iError = | |
693 m_pEdtEngine->Insert(nCaret, wsPaste.c_str(), wsPaste.GetLength()); | |
694 if (iError < 0) { | |
695 ProcessInsertError(iError); | |
696 return FALSE; | |
697 } | |
698 return TRUE; | |
699 } | |
700 FX_BOOL CFWL_EditImp::Delete() { | |
701 if (!m_pEdtEngine) | |
702 return FALSE; | |
703 int32_t nCount = m_pEdtEngine->CountSelRanges(); | |
704 if (nCount < 1) { | |
705 return FALSE; | |
706 } | |
707 m_pEdtEngine->Delete(0); | |
708 return TRUE; | |
709 } | |
710 FX_BOOL CFWL_EditImp::Redo(const CFX_ByteStringC& bsRecord) { | |
711 if (!m_pEdtEngine) | |
712 return FALSE; | |
713 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_NoRedoUndo) { | |
714 return TRUE; | |
715 } | |
716 return m_pEdtEngine->Redo(bsRecord); | |
717 } | |
718 FX_BOOL CFWL_EditImp::Undo(const CFX_ByteStringC& bsRecord) { | |
719 if (!m_pEdtEngine) | |
720 return FALSE; | |
721 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_NoRedoUndo) { | |
722 return TRUE; | |
723 } | |
724 return m_pEdtEngine->Undo(bsRecord); | |
725 } | |
726 FX_BOOL CFWL_EditImp::Undo() { | |
727 if (!CanUndo()) { | |
728 return FALSE; | |
729 } | |
730 CFX_ByteString bsRecord = m_RecordArr[m_iCurRecord--]; | |
731 return Undo(bsRecord); | |
732 } | |
733 FX_BOOL CFWL_EditImp::Redo() { | |
734 if (!CanRedo()) { | |
735 return FALSE; | |
736 } | |
737 CFX_ByteString bsRecord = m_RecordArr[++m_iCurRecord]; | |
738 return Redo(bsRecord); | |
739 } | |
740 FX_BOOL CFWL_EditImp::CanUndo() { | |
741 return m_iCurRecord >= 0; | |
742 } | |
743 FX_BOOL CFWL_EditImp::CanRedo() { | |
744 return m_iCurRecord < m_RecordArr.GetSize() - 1; | |
745 } | |
746 FWL_ERR CFWL_EditImp::SetTabWidth(FX_FLOAT fTabWidth, FX_BOOL bEquidistant) { | |
747 if (!m_pEdtEngine) | |
748 return FWL_ERR_Succeeded; | |
749 FDE_LPTXTEDTPARAMS pParams = | |
750 (FDE_LPTXTEDTPARAMS)m_pEdtEngine->GetEditParams(); | |
751 pParams->fTabWidth = fTabWidth; | |
752 pParams->bTabEquidistant = bEquidistant; | |
753 return FWL_ERR_Succeeded; | |
754 } | |
755 FWL_ERR CFWL_EditImp::SetOuter(IFWL_Widget* pOuter) { | |
756 m_pOuter = pOuter; | |
757 return FWL_ERR_Succeeded; | |
758 } | |
759 FWL_ERR CFWL_EditImp::SetNumberRange(int32_t iMin, int32_t iMax) { | |
760 m_iMin = iMin; | |
761 m_iMax = iMax; | |
762 m_bSetRange = TRUE; | |
763 return FWL_ERR_Succeeded; | |
764 } | |
765 void CFWL_EditImp::On_CaretChanged(IFDE_TxtEdtEngine* pEdit, | |
766 int32_t nPage, | |
767 FX_BOOL bVisible) { | |
768 if (m_rtEngine.IsEmpty()) { | |
769 return; | |
770 } | |
771 if ((m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) { | |
772 return; | |
773 } | |
774 FX_BOOL bRepaintContent = UpdateOffset(); | |
775 UpdateCaret(); | |
776 CFX_RectF rtInvalid; | |
777 rtInvalid.Set(0, 0, 0, 0); | |
778 FX_BOOL bRepaintScroll = FALSE; | |
779 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine) { | |
780 IFWL_ScrollBar* pScroll = UpdateScroll(); | |
781 if (pScroll) { | |
782 pScroll->GetWidgetRect(rtInvalid); | |
783 bRepaintScroll = TRUE; | |
784 } | |
785 } | |
786 if (bRepaintContent || bRepaintScroll) { | |
787 if (bRepaintContent) { | |
788 rtInvalid.Union(m_rtEngine); | |
789 } | |
790 Repaint(&rtInvalid); | |
791 } | |
792 } | |
793 void CFWL_EditImp::On_TextChanged(IFDE_TxtEdtEngine* pEdit, | |
794 FDE_TXTEDT_TEXTCHANGE_INFO& ChangeInfo) { | |
795 FX_DWORD dwStyleEx = m_pProperties->m_dwStyleExes; | |
796 if (dwStyleEx & FWL_STYLEEXT_EDT_VAlignMask) { | |
797 UpdateVAlignment(); | |
798 } | |
799 IFDE_TxtEdtPage* page = m_pEdtEngine->GetPage(0); | |
800 FX_FLOAT fContentWidth = page->GetContentsBox().width; | |
801 FX_FLOAT fContentHeight = page->GetContentsBox().height; | |
802 CFX_RectF rtTemp; | |
803 GetClientRect(rtTemp); | |
804 FX_BOOL bHSelfAdaption = | |
805 m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HSelfAdaption; | |
806 FX_BOOL bVSelfAdaption = | |
807 m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VSelfAdaption; | |
808 FX_BOOL bNeedUpdate = FALSE; | |
809 if (bHSelfAdaption || bVSelfAdaption) { | |
810 CFWL_EvtEdtPreSelfAdaption evt; | |
811 evt.m_pSrcTarget = m_pInterface; | |
812 evt.bHSelfAdaption = TRUE; | |
813 evt.bVSelfAdaption = TRUE; | |
814 FX_FLOAT fWidth; | |
815 FX_FLOAT fHight; | |
816 fWidth = bHSelfAdaption ? fContentWidth : m_pProperties->m_rtWidget.width; | |
817 fHight = bVSelfAdaption ? fContentHeight : m_pProperties->m_rtWidget.height; | |
818 evt.rtAfterChange.Set(0, 0, fWidth, fHight); | |
819 DispatchEvent(&evt); | |
820 if (!evt.bHSelfAdaption) { | |
821 ModifyStylesEx( | |
822 0, FWL_STYLEEXT_EDT_HSelfAdaption | FWL_STYLEEXT_EDT_AutoHScroll); | |
823 } | |
824 if (!evt.bVSelfAdaption) { | |
825 ModifyStylesEx( | |
826 0, FWL_STYLEEXT_EDT_VSelfAdaption | FWL_STYLEEXT_EDT_AutoVScroll); | |
827 } | |
828 bNeedUpdate = (bHSelfAdaption && !evt.bHSelfAdaption) || | |
829 (bVSelfAdaption && !evt.bVSelfAdaption); | |
830 } | |
831 FX_FLOAT fContentWidth1 = fContentWidth; | |
832 FX_FLOAT fContentHeight1 = fContentHeight; | |
833 if (bNeedUpdate) { | |
834 UpdateEditParams(); | |
835 UpdateEditLayout(); | |
836 IFDE_TxtEdtPage* page1 = m_pEdtEngine->GetPage(0); | |
837 fContentWidth1 = page1->GetContentsBox().width; | |
838 fContentHeight1 = page1->GetContentsBox().height; | |
839 } | |
840 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HSelfAdaption) { | |
841 rtTemp.width = std::max(m_pProperties->m_rtWidget.width, fContentWidth1); | |
842 m_pProperties->m_rtWidget.width = fContentWidth1; | |
843 } | |
844 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VSelfAdaption) { | |
845 rtTemp.height = std::max(m_pProperties->m_rtWidget.height, fContentHeight1); | |
846 m_pProperties->m_rtWidget.height = fContentHeight1; | |
847 } | |
848 CFWL_EvtEdtTextChanged event; | |
849 event.m_pSrcTarget = m_pInterface; | |
850 event.nChangeType = ChangeInfo.nChangeType; | |
851 event.wsInsert = ChangeInfo.wsInsert; | |
852 event.wsDelete = ChangeInfo.wsDelete; | |
853 event.wsPrevText = ChangeInfo.wsPrevText; | |
854 DispatchEvent(&event); | |
855 LayoutScrollBar(); | |
856 Repaint(&rtTemp); | |
857 } | |
858 void CFWL_EditImp::On_SelChanged(IFDE_TxtEdtEngine* pEdit) { | |
859 CFX_RectF rtTemp; | |
860 GetClientRect(rtTemp); | |
861 Repaint(&rtTemp); | |
862 } | |
863 FX_BOOL CFWL_EditImp::On_PageLoad(IFDE_TxtEdtEngine* pEdit, | |
864 int32_t nPageIndex, | |
865 int32_t nPurpose) { | |
866 IFDE_TxtEdtEngine* pEdtEngine = m_pEdtEngine; | |
867 IFDE_TxtEdtPage* pPage = pEdtEngine->GetPage(nPageIndex); | |
868 if (!pPage) | |
869 return FALSE; | |
870 pPage->LoadPage(nullptr, nullptr); | |
871 return TRUE; | |
872 } | |
873 FX_BOOL CFWL_EditImp::On_PageUnload(IFDE_TxtEdtEngine* pEdit, | |
874 int32_t nPageIndex, | |
875 int32_t nPurpose) { | |
876 IFDE_TxtEdtEngine* pEdtEngine = m_pEdtEngine; | |
877 IFDE_TxtEdtPage* pPage = pEdtEngine->GetPage(nPageIndex); | |
878 if (!pPage) | |
879 return FALSE; | |
880 pPage->UnloadPage(nullptr); | |
881 return TRUE; | |
882 } | |
883 | |
884 void CFWL_EditImp::On_AddDoRecord(IFDE_TxtEdtEngine* pEdit, | |
885 const CFX_ByteStringC& bsDoRecord) { | |
886 AddDoRecord(bsDoRecord); | |
887 } | |
888 | |
889 FX_BOOL CFWL_EditImp::On_ValidateField(IFDE_TxtEdtEngine* pEdit, | |
890 int32_t nBlockIndex, | |
891 int32_t nFieldIndex, | |
892 const CFX_WideString& wsFieldText, | |
893 int32_t nCharIndex) { | |
894 return TRUE; | |
895 } | |
896 FX_BOOL CFWL_EditImp::On_ValidateBlock(IFDE_TxtEdtEngine* pEdit, | |
897 int32_t nBlockIndex) { | |
898 return TRUE; | |
899 } | |
900 FX_BOOL CFWL_EditImp::On_GetBlockFormatText(IFDE_TxtEdtEngine* pEdit, | |
901 int32_t nBlockIndex, | |
902 CFX_WideString& wsBlockText) { | |
903 return FALSE; | |
904 } | |
905 FX_BOOL CFWL_EditImp::On_Validate(IFDE_TxtEdtEngine* pEdit, | |
906 CFX_WideString& wsText) { | |
907 IFWL_Widget* pDst = GetOuter(); | |
908 if (!pDst) { | |
909 pDst = m_pInterface; | |
910 } | |
911 CFWL_EvtEdtValidate event; | |
912 event.pDstWidget = pDst; | |
913 event.m_pSrcTarget = m_pInterface; | |
914 event.wsInsert = wsText; | |
915 event.bValidate = TRUE; | |
916 DispatchEvent(&event); | |
917 return event.bValidate; | |
918 } | |
919 FWL_ERR CFWL_EditImp::SetBackgroundColor(FX_DWORD color) { | |
920 m_backColor = color; | |
921 m_updateBackColor = TRUE; | |
922 return FWL_ERR_Succeeded; | |
923 } | |
924 FWL_ERR CFWL_EditImp::SetFont(const CFX_WideString& wsFont, FX_FLOAT fSize) { | |
925 m_wsFont = wsFont; | |
926 m_fFontSize = fSize; | |
927 return FWL_ERR_Succeeded; | |
928 } | |
929 void CFWL_EditImp::SetScrollOffset(FX_FLOAT fScrollOffset) { | |
930 m_fScrollOffsetY = fScrollOffset; | |
931 } | |
932 void CFWL_EditImp::DrawTextBk(CFX_Graphics* pGraphics, | |
933 IFWL_ThemeProvider* pTheme, | |
934 const CFX_Matrix* pMatrix) { | |
935 CFWL_ThemeBackground param; | |
936 param.m_pWidget = m_pInterface; | |
937 param.m_iPart = FWL_PART_EDT_Background; | |
938 param.m_dwData = FWL_PARTDATA_EDT_Background; | |
939 param.m_dwStates = m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly | |
940 ? FWL_PARTSTATE_EDT_ReadOnly | |
941 : FWL_PARTSTATE_EDT_Normal; | |
942 FX_DWORD dwStates = (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled); | |
943 if (dwStates) { | |
944 param.m_dwStates = FWL_PARTSTATE_EDT_Disable; | |
945 } | |
946 param.m_pGraphics = pGraphics; | |
947 param.m_matrix = *pMatrix; | |
948 param.m_rtPart = m_rtClient; | |
949 pTheme->DrawBackground(¶m); | |
950 if (!IsShowScrollBar(TRUE) || !IsShowScrollBar(FALSE)) { | |
951 return; | |
952 } | |
953 CFX_RectF rtScorll; | |
954 m_pHorzScrollBar->GetWidgetRect(rtScorll); | |
955 CFX_RectF rtStatic; | |
956 rtStatic.Set(m_rtClient.right() - rtScorll.height, | |
957 m_rtClient.bottom() - rtScorll.height, rtScorll.height, | |
958 rtScorll.height); | |
959 param.m_dwData = FWL_PARTDATA_EDT_StaticBackground; | |
960 param.m_rtPart = rtStatic; | |
961 pTheme->DrawBackground(¶m); | |
962 } | |
963 void CFWL_EditImp::DrawContent(CFX_Graphics* pGraphics, | |
964 IFWL_ThemeProvider* pTheme, | |
965 const CFX_Matrix* pMatrix) { | |
966 if (!m_pEdtEngine) | |
967 return; | |
968 IFDE_TxtEdtPage* pPage = m_pEdtEngine->GetPage(0); | |
969 if (!pPage) | |
970 return; | |
971 pGraphics->SaveGraphState(); | |
972 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_CombText) { | |
973 pGraphics->SaveGraphState(); | |
974 } | |
975 CFX_RectF rtClip = m_rtEngine; | |
976 FX_FLOAT fOffSetX = m_rtEngine.left - m_fScrollOffsetX; | |
977 FX_FLOAT fOffSetY = m_rtEngine.top - m_fScrollOffsetY + m_fVAlignOffset; | |
978 CFX_Matrix mt; | |
979 mt.Set(1, 0, 0, 1, fOffSetX, fOffSetY); | |
980 if (pMatrix) { | |
981 pMatrix->TransformRect(rtClip); | |
982 mt.Concat(*pMatrix); | |
983 } | |
984 FX_BOOL bShowSel = | |
985 (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_NoHideSel) || | |
986 (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused); | |
987 if (bShowSel) { | |
988 IFWL_Widget* pForm = | |
989 m_pWidgetMgr->GetWidget(m_pInterface, FWL_WGTRELATION_SystemForm); | |
990 if (pForm) { | |
991 bShowSel = (pForm->GetStates() & FWL_WGTSTATE_Deactivated) != | |
992 FWL_WGTSTATE_Deactivated; | |
993 } | |
994 } | |
995 int32_t nSelCount = m_pEdtEngine->CountSelRanges(); | |
996 if (bShowSel && nSelCount > 0) { | |
997 int32_t nPageCharStart = pPage->GetCharStart(); | |
998 int32_t nPageCharCount = pPage->GetCharCount(); | |
999 int32_t nPageCharEnd = nPageCharStart + nPageCharCount - 1; | |
1000 int32_t nCharCount; | |
1001 int32_t nCharStart; | |
1002 CFX_RectFArray rectArr; | |
1003 int32_t i = 0; | |
1004 for (i = 0; i < nSelCount; i++) { | |
1005 nCharCount = m_pEdtEngine->GetSelRange(i, nCharStart); | |
1006 int32_t nCharEnd = nCharStart + nCharCount - 1; | |
1007 if (nCharEnd < nPageCharStart || nCharStart > nPageCharEnd) { | |
1008 continue; | |
1009 } | |
1010 int32_t nBgn = std::max(nCharStart, nPageCharStart); | |
1011 int32_t nEnd = std::min(nCharEnd, nPageCharEnd); | |
1012 pPage->CalcRangeRectArray(nBgn - nPageCharStart, nEnd - nBgn + 1, | |
1013 rectArr); | |
1014 } | |
1015 int32_t nCount = rectArr.GetSize(); | |
1016 CFX_Path path; | |
1017 path.Create(); | |
1018 for (i = 0; i < nCount; i++) { | |
1019 rectArr[i].left += fOffSetX; | |
1020 rectArr[i].top += fOffSetY; | |
1021 path.AddRectangle(rectArr[i].left, rectArr[i].top, rectArr[i].width, | |
1022 rectArr[i].height); | |
1023 } | |
1024 pGraphics->SetClipRect(rtClip); | |
1025 CFWL_ThemeBackground param; | |
1026 param.m_pGraphics = pGraphics; | |
1027 param.m_matrix = *pMatrix; | |
1028 param.m_pWidget = m_pInterface; | |
1029 param.m_iPart = FWL_PART_EDT_Background; | |
1030 param.m_pPath = &path; | |
1031 pTheme->DrawBackground(¶m); | |
1032 } | |
1033 CFX_RenderDevice* pRenderDev = pGraphics->GetRenderDevice(); | |
1034 if (!pRenderDev) | |
1035 return; | |
1036 IFDE_RenderDevice* pRenderDevice = IFDE_RenderDevice::Create(pRenderDev); | |
1037 if (!pRenderDevice) | |
1038 return; | |
1039 IFDE_RenderContext* pRenderContext = IFDE_RenderContext::Create(); | |
1040 if (!pRenderContext) | |
1041 return; | |
1042 pRenderDevice->SetClipRect(rtClip); | |
1043 pRenderContext->StartRender(pRenderDevice, pPage, mt); | |
1044 pRenderContext->DoRender(NULL); | |
1045 pRenderContext->Release(); | |
1046 pRenderDevice->Release(); | |
1047 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_CombText) { | |
1048 pGraphics->RestoreGraphState(); | |
1049 CFX_Path path; | |
1050 path.Create(); | |
1051 int32_t iLimit = m_nLimit > 0 ? m_nLimit : 1; | |
1052 FX_FLOAT fStep = m_rtEngine.width / iLimit; | |
1053 FX_FLOAT fLeft = m_rtEngine.left + 1; | |
1054 for (int32_t i = 1; i < iLimit; i++) { | |
1055 fLeft += fStep; | |
1056 path.AddLine(fLeft, m_rtClient.top, fLeft, m_rtClient.bottom()); | |
1057 } | |
1058 CFWL_ThemeBackground param; | |
1059 param.m_pGraphics = pGraphics; | |
1060 param.m_matrix = *pMatrix; | |
1061 param.m_pWidget = m_pInterface; | |
1062 param.m_iPart = FWL_PART_EDT_CombTextLine; | |
1063 param.m_pPath = &path; | |
1064 pTheme->DrawBackground(¶m); | |
1065 } | |
1066 pGraphics->RestoreGraphState(); | |
1067 } | |
1068 void CFWL_EditImp::UpdateEditEngine() { | |
1069 UpdateEditParams(); | |
1070 UpdateEditLayout(); | |
1071 if (m_nLimit > -1) { | |
1072 m_pEdtEngine->SetLimit(m_nLimit); | |
1073 } | |
1074 } | |
1075 void CFWL_EditImp::UpdateEditParams() { | |
1076 FDE_TXTEDTPARAMS params; | |
1077 params.nHorzScale = 100; | |
1078 params.fPlateWidth = m_rtEngine.width; | |
1079 params.fPlateHeight = m_rtEngine.height; | |
1080 if (m_pProperties->m_dwStyles & FWL_WGTSTYLE_RTLLayout) { | |
1081 params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_RTL; | |
1082 } | |
1083 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VerticalLayout) { | |
1084 params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_DocVertical; | |
1085 } | |
1086 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VerticalChars) { | |
1087 params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_CharVertial; | |
1088 } | |
1089 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReverseLine) { | |
1090 params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_LineReserve; | |
1091 } | |
1092 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ArabicShapes) { | |
1093 params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_ArabicShapes; | |
1094 } | |
1095 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ExpandTab) { | |
1096 params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_ExpandTab; | |
1097 } | |
1098 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_CombText) { | |
1099 params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_CombText; | |
1100 } | |
1101 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_LastLineHeight) { | |
1102 params.dwLayoutStyles |= FDE_TEXTEDITLAYOUT_LastLineHeight; | |
1103 } | |
1104 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_Validate) { | |
1105 params.dwMode |= FDE_TEXTEDITMODE_Validate; | |
1106 } | |
1107 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_Password) { | |
1108 params.dwMode |= FDE_TEXTEDITMODE_Password; | |
1109 } | |
1110 switch (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HAlignMask) { | |
1111 case FWL_STYLEEXT_EDT_HNear: { | |
1112 params.dwAlignment |= FDE_TEXTEDITALIGN_Left; | |
1113 break; | |
1114 } | |
1115 case FWL_STYLEEXT_EDT_HCenter: { | |
1116 params.dwAlignment |= FDE_TEXTEDITALIGN_Center; | |
1117 break; | |
1118 } | |
1119 case FWL_STYLEEXT_EDT_HFar: { | |
1120 params.dwAlignment |= FDE_TEXTEDITALIGN_Right; | |
1121 break; | |
1122 } | |
1123 default: {} | |
1124 } | |
1125 switch (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HAlignModeMask) { | |
1126 case FWL_STYLEEXT_EDT_Justified: { | |
1127 params.dwAlignment |= FDE_TEXTEDITALIGN_Justified; | |
1128 break; | |
1129 } | |
1130 case FWL_STYLEEXT_EDT_Distributed: { | |
1131 params.dwAlignment |= FDE_TEXTEDITALIGN_Distributed; | |
1132 break; | |
1133 } | |
1134 default: { params.dwAlignment |= FDE_TEXTEDITALIGN_Normal; } | |
1135 } | |
1136 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine) { | |
1137 params.dwMode |= FDE_TEXTEDITMODE_MultiLines; | |
1138 if ((m_pProperties->m_dwStyles & FWL_WGTSTYLE_HScroll) == 0 && | |
1139 (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_AutoHScroll) == 0) { | |
1140 params.dwMode |= | |
1141 FDE_TEXTEDITMODE_AutoLineWrap | FDE_TEXTEDITMODE_LimitArea_Horz; | |
1142 } | |
1143 if ((m_pProperties->m_dwStyles & FWL_WGTSTYLE_VScroll) == 0 && | |
1144 (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_AutoVScroll) == 0) { | |
1145 params.dwMode |= FDE_TEXTEDITMODE_LimitArea_Vert; | |
1146 } else { | |
1147 params.fPlateHeight = 0x00FFFFFF; | |
1148 } | |
1149 } else { | |
1150 if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_AutoHScroll) == 0) { | |
1151 params.dwMode |= FDE_TEXTEDITMODE_LimitArea_Horz; | |
1152 } | |
1153 } | |
1154 if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly) || | |
1155 (m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) { | |
1156 params.dwMode |= FDE_TEXTEDITMODE_ReadOnly; | |
1157 } | |
1158 FX_FLOAT* pFontSize = | |
1159 static_cast<FX_FLOAT*>(GetThemeCapacity(FWL_WGTCAPACITY_FontSize)); | |
1160 if (!pFontSize) | |
1161 return; | |
1162 m_fFontSize = *pFontSize; | |
1163 FX_DWORD* pFontColor = | |
1164 static_cast<FX_DWORD*>(GetThemeCapacity(FWL_WGTCAPACITY_TextColor)); | |
1165 if (!pFontColor) | |
1166 return; | |
1167 params.dwFontColor = *pFontColor; | |
1168 FX_FLOAT* pLineHeight = | |
1169 static_cast<FX_FLOAT*>(GetThemeCapacity(FWL_WGTCAPACITY_LineHeight)); | |
1170 if (!pLineHeight) | |
1171 return; | |
1172 params.fLineSpace = *pLineHeight; | |
1173 IFX_Font* pFont = | |
1174 static_cast<IFX_Font*>(GetThemeCapacity(FWL_WGTCAPACITY_Font)); | |
1175 if (!pFont) | |
1176 return; | |
1177 params.pFont = pFont; | |
1178 params.fFontSize = m_fFontSize; | |
1179 params.nLineCount = (int32_t)(params.fPlateHeight / params.fLineSpace); | |
1180 if (params.nLineCount <= 0) { | |
1181 params.nLineCount = 1; | |
1182 } | |
1183 params.fTabWidth = params.fFontSize * 1; | |
1184 params.bTabEquidistant = TRUE; | |
1185 params.wLineBreakChar = L'\n'; | |
1186 params.nCharRotation = 0; | |
1187 params.pEventSink = this; | |
1188 m_pEdtEngine->SetEditParams(params); | |
1189 } | |
1190 | |
1191 void CFWL_EditImp::UpdateEditLayout() { | |
1192 if (m_pEdtEngine->GetTextLength() <= 0) | |
1193 m_pEdtEngine->SetTextByStream(nullptr); | |
1194 | |
1195 IFDE_TxtEdtPage* pPage = m_pEdtEngine->GetPage(0); | |
1196 if (pPage) | |
1197 pPage->UnloadPage(nullptr); | |
1198 | |
1199 m_pEdtEngine->StartLayout(); | |
1200 m_pEdtEngine->DoLayout(nullptr); | |
1201 m_pEdtEngine->EndLayout(); | |
1202 pPage = m_pEdtEngine->GetPage(0); | |
1203 if (pPage) | |
1204 pPage->LoadPage(nullptr, nullptr); | |
1205 } | |
1206 | |
1207 FX_BOOL CFWL_EditImp::UpdateOffset() { | |
1208 CFX_RectF rtCaret; | |
1209 m_pEdtEngine->GetCaretRect(rtCaret); | |
1210 FX_FLOAT fOffSetX = m_rtEngine.left - m_fScrollOffsetX; | |
1211 FX_FLOAT fOffSetY = m_rtEngine.top - m_fScrollOffsetY + m_fVAlignOffset; | |
1212 rtCaret.Offset(fOffSetX, fOffSetY); | |
1213 const CFX_RectF& rtEidt = m_rtEngine; | |
1214 if (rtEidt.Contains(rtCaret)) { | |
1215 IFDE_TxtEdtPage* pPage = m_pEdtEngine->GetPage(0); | |
1216 if (!pPage) | |
1217 return FALSE; | |
1218 CFX_RectF rtFDE = pPage->GetContentsBox(); | |
1219 rtFDE.Offset(fOffSetX, fOffSetY); | |
1220 if (rtFDE.right() < rtEidt.right() && m_fScrollOffsetX > 0) { | |
1221 m_fScrollOffsetX += rtFDE.right() - rtEidt.right(); | |
1222 if (m_fScrollOffsetX < 0) { | |
1223 m_fScrollOffsetX = 0; | |
1224 } | |
1225 } | |
1226 if (rtFDE.bottom() < rtEidt.bottom() && m_fScrollOffsetY > 0) { | |
1227 m_fScrollOffsetY += rtFDE.bottom() - rtEidt.bottom(); | |
1228 if (m_fScrollOffsetY < 0) { | |
1229 m_fScrollOffsetY = 0; | |
1230 } | |
1231 } | |
1232 return FALSE; | |
1233 } else { | |
1234 FX_FLOAT offsetX = 0.0; | |
1235 FX_FLOAT offsetY = 0.0; | |
1236 if (rtCaret.left < rtEidt.left) { | |
1237 offsetX = rtCaret.left - rtEidt.left; | |
1238 } | |
1239 if (rtCaret.right() > rtEidt.right()) { | |
1240 offsetX = rtCaret.right() - rtEidt.right(); | |
1241 } | |
1242 if (rtCaret.top < rtEidt.top) { | |
1243 offsetY = rtCaret.top - rtEidt.top; | |
1244 } | |
1245 if (rtCaret.bottom() > rtEidt.bottom()) { | |
1246 offsetY = rtCaret.bottom() - rtEidt.bottom(); | |
1247 } | |
1248 if (!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HSelfAdaption)) { | |
1249 m_fScrollOffsetX += offsetX; | |
1250 } | |
1251 if (!(m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VSelfAdaption)) { | |
1252 m_fScrollOffsetY += offsetY; | |
1253 } | |
1254 if (m_fFontSize > m_rtEngine.height) { | |
1255 m_fScrollOffsetY = 0; | |
1256 } | |
1257 return TRUE; | |
1258 } | |
1259 } | |
1260 FX_BOOL CFWL_EditImp::UpdateOffset(IFWL_ScrollBar* pScrollBar, | |
1261 FX_FLOAT fPosChanged) { | |
1262 if (pScrollBar == m_pHorzScrollBar.get()) { | |
1263 m_fScrollOffsetX += fPosChanged; | |
1264 } else { | |
1265 m_fScrollOffsetY += fPosChanged; | |
1266 } | |
1267 return TRUE; | |
1268 } | |
1269 void CFWL_EditImp::UpdateVAlignment() { | |
1270 IFDE_TxtEdtPage* pPage = m_pEdtEngine->GetPage(0); | |
1271 if (!pPage) | |
1272 return; | |
1273 const CFX_RectF& rtFDE = pPage->GetContentsBox(); | |
1274 FX_FLOAT fOffsetY = 0.0f; | |
1275 FX_FLOAT fSpaceAbove = 0.0f; | |
1276 FX_FLOAT fSpaceBelow = 0.0f; | |
1277 CFX_SizeF* pSpace = static_cast<CFX_SizeF*>( | |
1278 GetThemeCapacity(FWL_WGTCAPACITY_SpaceAboveBelow)); | |
1279 if (pSpace) { | |
1280 fSpaceAbove = pSpace->x; | |
1281 fSpaceBelow = pSpace->y; | |
1282 } | |
1283 if (fSpaceAbove < 0.1f) { | |
1284 fSpaceAbove = 0; | |
1285 } | |
1286 if (fSpaceBelow < 0.1f) { | |
1287 fSpaceBelow = 0; | |
1288 } | |
1289 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VCenter) { | |
1290 fOffsetY = (m_rtEngine.height - rtFDE.height) / 2; | |
1291 if (fOffsetY < (fSpaceAbove + fSpaceBelow) / 2 && | |
1292 fSpaceAbove < fSpaceBelow) { | |
1293 return; | |
1294 } | |
1295 fOffsetY += (fSpaceAbove - fSpaceBelow) / 2; | |
1296 } else if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VFar) { | |
1297 fOffsetY = (m_rtEngine.height - rtFDE.height); | |
1298 fOffsetY -= fSpaceBelow; | |
1299 } else { | |
1300 fOffsetY += fSpaceAbove; | |
1301 } | |
1302 m_fVAlignOffset = fOffsetY; | |
1303 if (m_fVAlignOffset < 0) { | |
1304 m_fVAlignOffset = 0; | |
1305 } | |
1306 } | |
1307 void CFWL_EditImp::UpdateCaret() { | |
1308 CFX_RectF rtFDE; | |
1309 m_pEdtEngine->GetCaretRect(rtFDE); | |
1310 rtFDE.Offset(m_rtEngine.left - m_fScrollOffsetX, | |
1311 m_rtEngine.top - m_fScrollOffsetY + m_fVAlignOffset); | |
1312 CFX_RectF rtCaret; | |
1313 rtCaret.Set(rtFDE.left, rtFDE.top, rtFDE.width, rtFDE.height); | |
1314 CFX_RectF temp = rtCaret; | |
1315 CFX_RectF rtClient; | |
1316 GetClientRect(rtClient); | |
1317 rtCaret.Intersect(rtClient); | |
1318 if (rtCaret.left > rtClient.right()) { | |
1319 FX_FLOAT right = rtCaret.right(); | |
1320 rtCaret.left = rtClient.right() - 1; | |
1321 rtCaret.width = right - rtCaret.left; | |
1322 } | |
1323 FX_BOOL bIntersect = !rtCaret.IsEmpty(); | |
1324 FX_BOOL bShow = TRUE; | |
1325 FX_BOOL bShowWhole = FALSE; | |
1326 if (!(m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) || !bIntersect) { | |
1327 bShow = FALSE; | |
1328 } | |
1329 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_HSelfAdaption && | |
1330 temp.right() > m_rtEngine.right()) { | |
1331 bShowWhole = TRUE; | |
1332 } | |
1333 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_VSelfAdaption && | |
1334 temp.bottom() > m_rtEngine.bottom()) { | |
1335 bShowWhole = TRUE; | |
1336 } else { | |
1337 bShow = (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused && bIntersect); | |
1338 } | |
1339 if (bShowWhole) { | |
1340 rtCaret = temp; | |
1341 } | |
1342 ShowCaret(bShow, &rtCaret); | |
1343 } | |
1344 IFWL_ScrollBar* CFWL_EditImp::UpdateScroll() { | |
1345 FX_BOOL bShowHorz = | |
1346 m_pHorzScrollBar && | |
1347 ((m_pHorzScrollBar->GetStates() & FWL_WGTSTATE_Invisible) == 0); | |
1348 FX_BOOL bShowVert = | |
1349 m_pVertScrollBar && | |
1350 ((m_pVertScrollBar->GetStates() & FWL_WGTSTATE_Invisible) == 0); | |
1351 if (!bShowHorz && !bShowVert) { | |
1352 return NULL; | |
1353 } | |
1354 IFDE_TxtEdtPage* pPage = m_pEdtEngine->GetPage(0); | |
1355 if (!pPage) | |
1356 return NULL; | |
1357 const CFX_RectF& rtFDE = pPage->GetContentsBox(); | |
1358 IFWL_ScrollBar* pRepaint = NULL; | |
1359 if (bShowHorz) { | |
1360 CFX_RectF rtScroll; | |
1361 m_pHorzScrollBar->GetWidgetRect(rtScroll); | |
1362 if (rtScroll.width < rtFDE.width) { | |
1363 m_pHorzScrollBar->LockUpdate(); | |
1364 FX_FLOAT fRange = rtFDE.width - rtScroll.width; | |
1365 m_pHorzScrollBar->SetRange(0.0f, fRange); | |
1366 FX_FLOAT fPos = m_fScrollOffsetX; | |
1367 if (fPos < 0.0f) { | |
1368 fPos = 0.0f; | |
1369 } | |
1370 if (fPos > fRange) { | |
1371 fPos = fRange; | |
1372 } | |
1373 m_pHorzScrollBar->SetPos(fPos); | |
1374 m_pHorzScrollBar->SetTrackPos(fPos); | |
1375 m_pHorzScrollBar->SetPageSize(rtScroll.width); | |
1376 m_pHorzScrollBar->SetStepSize(rtScroll.width / 10); | |
1377 m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Disabled, FALSE); | |
1378 m_pHorzScrollBar->UnlockUpdate(); | |
1379 m_pHorzScrollBar->Update(); | |
1380 pRepaint = m_pHorzScrollBar.get(); | |
1381 } else if ((m_pHorzScrollBar->GetStates() & FWL_WGTSTATE_Disabled) == 0) { | |
1382 m_pHorzScrollBar->LockUpdate(); | |
1383 m_pHorzScrollBar->SetRange(0, -1); | |
1384 m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Disabled, TRUE); | |
1385 m_pHorzScrollBar->UnlockUpdate(); | |
1386 m_pHorzScrollBar->Update(); | |
1387 pRepaint = m_pHorzScrollBar.get(); | |
1388 } | |
1389 } | |
1390 if (bShowVert) { | |
1391 CFX_RectF rtScroll; | |
1392 m_pVertScrollBar->GetWidgetRect(rtScroll); | |
1393 if (rtScroll.height < rtFDE.height) { | |
1394 m_pVertScrollBar->LockUpdate(); | |
1395 FX_FLOAT fStep = m_pEdtEngine->GetEditParams()->fLineSpace; | |
1396 FX_FLOAT fRange = rtFDE.height - m_rtEngine.height; | |
1397 if (fRange < fStep) { | |
1398 fRange = fStep; | |
1399 } | |
1400 m_pVertScrollBar->SetRange(0.0f, fRange); | |
1401 FX_FLOAT fPos = m_fScrollOffsetY; | |
1402 if (fPos < 0.0f) { | |
1403 fPos = 0.0f; | |
1404 } | |
1405 if (fPos > fRange) { | |
1406 fPos = fRange; | |
1407 } | |
1408 m_pVertScrollBar->SetPos(fPos); | |
1409 m_pVertScrollBar->SetTrackPos(fPos); | |
1410 m_pVertScrollBar->SetPageSize(rtScroll.height); | |
1411 m_pVertScrollBar->SetStepSize(fStep); | |
1412 m_pVertScrollBar->SetStates(FWL_WGTSTATE_Disabled, FALSE); | |
1413 m_pVertScrollBar->UnlockUpdate(); | |
1414 m_pVertScrollBar->Update(); | |
1415 pRepaint = m_pVertScrollBar.get(); | |
1416 } else if ((m_pVertScrollBar->GetStates() & FWL_WGTSTATE_Disabled) == 0) { | |
1417 m_pVertScrollBar->LockUpdate(); | |
1418 m_pVertScrollBar->SetRange(0, -1); | |
1419 m_pVertScrollBar->SetStates(FWL_WGTSTATE_Disabled, TRUE); | |
1420 m_pVertScrollBar->UnlockUpdate(); | |
1421 m_pVertScrollBar->Update(); | |
1422 pRepaint = m_pVertScrollBar.get(); | |
1423 } | |
1424 } | |
1425 return pRepaint; | |
1426 } | |
1427 FX_BOOL CFWL_EditImp::IsShowScrollBar(FX_BOOL bVert) { | |
1428 FX_BOOL bShow = | |
1429 (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ShowScrollbarFocus) | |
1430 ? (m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == | |
1431 FWL_WGTSTATE_Focused | |
1432 : TRUE; | |
1433 if (bVert) { | |
1434 return bShow && (m_pProperties->m_dwStyles & FWL_WGTSTYLE_VScroll) && | |
1435 (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine) && | |
1436 IsContentHeightOverflow(); | |
1437 } | |
1438 return bShow && (m_pProperties->m_dwStyles & FWL_WGTSTYLE_HScroll) && | |
1439 (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_MultiLine); | |
1440 } | |
1441 FX_BOOL CFWL_EditImp::IsContentHeightOverflow() { | |
1442 if (!m_pEdtEngine) | |
1443 return FALSE; | |
1444 IFDE_TxtEdtPage* pPage = m_pEdtEngine->GetPage(0); | |
1445 if (!pPage) | |
1446 return FALSE; | |
1447 return pPage->GetContentsBox().height > m_rtEngine.height + 1.0f; | |
1448 } | |
1449 int32_t CFWL_EditImp::AddDoRecord(const CFX_ByteStringC& bsDoRecord) { | |
1450 int32_t nCount = m_RecordArr.GetSize(); | |
1451 if (m_iCurRecord == nCount - 1) { | |
1452 if (nCount == m_iMaxRecord) { | |
1453 m_RecordArr.RemoveAt(0); | |
1454 m_iCurRecord--; | |
1455 } | |
1456 } else { | |
1457 for (int32_t i = nCount - 1; i > m_iCurRecord; i--) { | |
1458 m_RecordArr.RemoveAt(i); | |
1459 } | |
1460 } | |
1461 m_RecordArr.Add(bsDoRecord); | |
1462 return m_iCurRecord = m_RecordArr.GetSize() - 1; | |
1463 } | |
1464 void CFWL_EditImp::Layout() { | |
1465 GetClientRect(m_rtClient); | |
1466 m_rtEngine = m_rtClient; | |
1467 FX_FLOAT* pfWidth = | |
1468 static_cast<FX_FLOAT*>(GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth)); | |
1469 if (!pfWidth) | |
1470 return; | |
1471 FX_FLOAT fWidth = *pfWidth; | |
1472 if (!m_pOuter) { | |
1473 CFX_RectF* pUIMargin = | |
1474 static_cast<CFX_RectF*>(GetThemeCapacity(FWL_WGTCAPACITY_UIMargin)); | |
1475 if (pUIMargin) { | |
1476 m_rtEngine.Deflate(pUIMargin->left, pUIMargin->top, pUIMargin->width, | |
1477 pUIMargin->height); | |
1478 } | |
1479 } else if (m_pOuter->GetClassID() == FWL_CLASSHASH_DateTimePicker) { | |
1480 CFWL_ThemePart part; | |
1481 part.m_pWidget = m_pOuter; | |
1482 CFX_RectF* pUIMargin = | |
1483 static_cast<CFX_RectF*>(m_pOuter->GetThemeProvider()->GetCapacity( | |
1484 &part, FWL_WGTCAPACITY_UIMargin)); | |
1485 if (pUIMargin) { | |
1486 m_rtEngine.Deflate(pUIMargin->left, pUIMargin->top, pUIMargin->width, | |
1487 pUIMargin->height); | |
1488 } | |
1489 } | |
1490 FX_BOOL bShowVertScrollbar = IsShowScrollBar(TRUE); | |
1491 FX_BOOL bShowHorzScrollbar = IsShowScrollBar(FALSE); | |
1492 if (bShowVertScrollbar) { | |
1493 InitScrollBar(); | |
1494 CFX_RectF rtVertScr; | |
1495 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) { | |
1496 rtVertScr.Set(m_rtClient.right() + FWL_EDIT_Margin, m_rtClient.top, | |
1497 fWidth, m_rtClient.height); | |
1498 } else { | |
1499 rtVertScr.Set(m_rtClient.right() - fWidth, m_rtClient.top, fWidth, | |
1500 m_rtClient.height); | |
1501 if (bShowHorzScrollbar) { | |
1502 rtVertScr.height -= fWidth; | |
1503 } | |
1504 m_rtEngine.width -= fWidth; | |
1505 } | |
1506 m_pVertScrollBar->SetWidgetRect(rtVertScr); | |
1507 m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible, FALSE); | |
1508 m_pVertScrollBar->Update(); | |
1509 } else if (m_pVertScrollBar) { | |
1510 m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible, TRUE); | |
1511 } | |
1512 if (bShowHorzScrollbar) { | |
1513 InitScrollBar(FALSE); | |
1514 CFX_RectF rtHoriScr; | |
1515 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) { | |
1516 rtHoriScr.Set(m_rtClient.left, m_rtClient.bottom() + FWL_EDIT_Margin, | |
1517 m_rtClient.width, fWidth); | |
1518 } else { | |
1519 rtHoriScr.Set(m_rtClient.left, m_rtClient.bottom() - fWidth, | |
1520 m_rtClient.width, fWidth); | |
1521 if (bShowVertScrollbar) { | |
1522 rtHoriScr.width -= fWidth; | |
1523 } | |
1524 m_rtEngine.height -= fWidth; | |
1525 } | |
1526 m_pHorzScrollBar->SetWidgetRect(rtHoriScr); | |
1527 m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible, FALSE); | |
1528 m_pHorzScrollBar->Update(); | |
1529 } else if (m_pHorzScrollBar) { | |
1530 m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible, TRUE); | |
1531 } | |
1532 } | |
1533 void CFWL_EditImp::LayoutScrollBar() { | |
1534 if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ShowScrollbarFocus) == | |
1535 0) { | |
1536 return; | |
1537 } | |
1538 FX_FLOAT* pfWidth = NULL; | |
1539 FX_BOOL bShowVertScrollbar = IsShowScrollBar(TRUE); | |
1540 FX_BOOL bShowHorzScrollbar = IsShowScrollBar(FALSE); | |
1541 if (bShowVertScrollbar) { | |
1542 if (!m_pVertScrollBar) { | |
1543 pfWidth = static_cast<FX_FLOAT*>( | |
1544 GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth)); | |
1545 FX_FLOAT fWidth = pfWidth ? *pfWidth : 0; | |
1546 InitScrollBar(); | |
1547 CFX_RectF rtVertScr; | |
1548 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) { | |
1549 rtVertScr.Set(m_rtClient.right() + FWL_EDIT_Margin, m_rtClient.top, | |
1550 fWidth, m_rtClient.height); | |
1551 } else { | |
1552 rtVertScr.Set(m_rtClient.right() - fWidth, m_rtClient.top, fWidth, | |
1553 m_rtClient.height); | |
1554 if (bShowHorzScrollbar) { | |
1555 rtVertScr.height -= fWidth; | |
1556 } | |
1557 } | |
1558 m_pVertScrollBar->SetWidgetRect(rtVertScr); | |
1559 m_pVertScrollBar->Update(); | |
1560 } | |
1561 m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible, FALSE); | |
1562 } else if (m_pVertScrollBar) { | |
1563 m_pVertScrollBar->SetStates(FWL_WGTSTATE_Invisible, TRUE); | |
1564 } | |
1565 if (bShowHorzScrollbar) { | |
1566 if (!m_pHorzScrollBar) { | |
1567 if (!pfWidth) { | |
1568 pfWidth = static_cast<FX_FLOAT*>( | |
1569 GetThemeCapacity(FWL_WGTCAPACITY_ScrollBarWidth)); | |
1570 } | |
1571 FX_FLOAT fWidth = pfWidth ? *pfWidth : 0; | |
1572 InitScrollBar(FALSE); | |
1573 CFX_RectF rtHoriScr; | |
1574 if (m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_OuterScrollbar) { | |
1575 rtHoriScr.Set(m_rtClient.left, m_rtClient.bottom() + FWL_EDIT_Margin, | |
1576 m_rtClient.width, fWidth); | |
1577 } else { | |
1578 rtHoriScr.Set(m_rtClient.left, m_rtClient.bottom() - fWidth, | |
1579 m_rtClient.width, fWidth); | |
1580 if (bShowVertScrollbar) { | |
1581 rtHoriScr.width -= (fWidth); | |
1582 } | |
1583 } | |
1584 m_pHorzScrollBar->SetWidgetRect(rtHoriScr); | |
1585 m_pHorzScrollBar->Update(); | |
1586 } | |
1587 m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible, FALSE); | |
1588 } else if (m_pHorzScrollBar) { | |
1589 m_pHorzScrollBar->SetStates(FWL_WGTSTATE_Invisible, TRUE); | |
1590 } | |
1591 if (bShowVertScrollbar || bShowHorzScrollbar) { | |
1592 UpdateScroll(); | |
1593 } | |
1594 } | |
1595 void CFWL_EditImp::DeviceToEngine(CFX_PointF& pt) { | |
1596 pt.x += -m_rtEngine.left + m_fScrollOffsetX; | |
1597 pt.y += -m_rtEngine.top - m_fVAlignOffset + m_fScrollOffsetY; | |
1598 } | |
1599 void CFWL_EditImp::InitScrollBar(FX_BOOL bVert) { | |
1600 if ((bVert && m_pVertScrollBar) || (!bVert && m_pHorzScrollBar)) { | |
1601 return; | |
1602 } | |
1603 CFWL_WidgetImpProperties prop; | |
1604 prop.m_dwStyleExes = bVert ? FWL_STYLEEXT_SCB_Vert : FWL_STYLEEXT_SCB_Horz; | |
1605 prop.m_dwStates = FWL_WGTSTATE_Disabled | FWL_WGTSTATE_Invisible; | |
1606 prop.m_pParent = m_pInterface; | |
1607 prop.m_pThemeProvider = m_pProperties->m_pThemeProvider; | |
1608 IFWL_ScrollBar* pScrollBar = IFWL_ScrollBar::Create(prop, m_pInterface); | |
1609 pScrollBar->Initialize(); | |
1610 (bVert ? &m_pVertScrollBar : &m_pHorzScrollBar)->reset(pScrollBar); | |
1611 } | |
1612 void CFWL_EditImp::InitEngine() { | |
1613 if (m_pEdtEngine) { | |
1614 return; | |
1615 } | |
1616 m_pEdtEngine = IFDE_TxtEdtEngine::Create(); | |
1617 } | |
1618 extern FX_BOOL FWL_ShowCaret(IFWL_Widget* pWidget, | |
1619 FX_BOOL bVisible, | |
1620 const CFX_RectF* pRtAnchor); | |
1621 void CFWL_EditImp::ShowCaret(FX_BOOL bVisible, CFX_RectF* pRect) { | |
1622 if (m_pCaret) { | |
1623 m_pCaret->ShowCaret(bVisible); | |
1624 if (bVisible && !pRect->IsEmpty()) { | |
1625 m_pCaret->SetWidgetRect(*pRect); | |
1626 } | |
1627 Repaint(&m_rtEngine); | |
1628 } else { | |
1629 IFWL_Widget* pOuter = m_pInterface; | |
1630 if (bVisible) { | |
1631 pRect->Offset(m_pProperties->m_rtWidget.left, | |
1632 m_pProperties->m_rtWidget.top); | |
1633 } | |
1634 while (pOuter->GetOuter()) { | |
1635 pOuter = pOuter->GetOuter(); | |
1636 if (bVisible) { | |
1637 CFX_RectF rtOuter; | |
1638 pOuter->GetWidgetRect(rtOuter); | |
1639 pRect->Offset(rtOuter.left, rtOuter.top); | |
1640 } | |
1641 } | |
1642 FWL_ShowCaret(pOuter, bVisible, pRect); | |
1643 } | |
1644 } | |
1645 FX_BOOL CFWL_EditImp::ValidateNumberChar(FX_WCHAR cNum) { | |
1646 if (!m_pEdtEngine) { | |
1647 return FALSE; | |
1648 } | |
1649 if (!m_bSetRange) { | |
1650 return TRUE; | |
1651 } | |
1652 CFX_WideString wsOld, wsText; | |
1653 m_pEdtEngine->GetText(wsText, 0); | |
1654 if (wsText.IsEmpty()) { | |
1655 if (cNum == L'0') { | |
1656 return FALSE; | |
1657 } | |
1658 return TRUE; | |
1659 } | |
1660 int32_t caretPos = m_pEdtEngine->GetCaretPos(); | |
1661 int32_t iSel = CountSelRanges(); | |
1662 if (iSel == 0) { | |
1663 if (cNum == L'0' && caretPos == 0) { | |
1664 return FALSE; | |
1665 } | |
1666 int32_t nLen = wsText.GetLength(); | |
1667 CFX_WideString l = wsText.Mid(0, caretPos); | |
1668 CFX_WideString r = wsText.Mid(caretPos, nLen - caretPos); | |
1669 CFX_WideString wsNew = l + cNum + r; | |
1670 if (wsNew.GetInteger() <= m_iMax) { | |
1671 return TRUE; | |
1672 } | |
1673 } else { | |
1674 if (wsText.GetInteger() <= m_iMax) { | |
1675 return TRUE; | |
1676 } | |
1677 } | |
1678 return FALSE; | |
1679 } | |
1680 void CFWL_EditImp::InitCaret() { | |
1681 if (!m_pCaret) { | |
1682 if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_InnerCaret)) { | |
1683 CFWL_WidgetImpProperties prop; | |
1684 m_pCaret.reset(IFWL_Caret::Create(prop, m_pInterface)); | |
1685 m_pCaret->Initialize(); | |
1686 m_pCaret->SetParent(m_pInterface); | |
1687 m_pCaret->SetStates(m_pProperties->m_dwStates); | |
1688 } | |
1689 } else if ((m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_InnerCaret) == | |
1690 0) { | |
1691 m_pCaret.reset(); | |
1692 } | |
1693 } | |
1694 void CFWL_EditImp::ClearRecord() { | |
1695 m_iCurRecord = -1; | |
1696 m_RecordArr.RemoveAll(); | |
1697 } | |
1698 void CFWL_EditImp::ProcessInsertError(int32_t iError) { | |
1699 switch (iError) { | |
1700 case -2: { | |
1701 CFWL_EvtEdtTextFull textFullEvent; | |
1702 textFullEvent.m_pSrcTarget = m_pInterface; | |
1703 DispatchEvent(&textFullEvent); | |
1704 break; | |
1705 } | |
1706 default: {} | |
1707 } | |
1708 } | |
1709 CFWL_EditImpDelegate::CFWL_EditImpDelegate(CFWL_EditImp* pOwner) | |
1710 : m_pOwner(pOwner) {} | |
1711 int32_t CFWL_EditImpDelegate::OnProcessMessage(CFWL_Message* pMessage) { | |
1712 if (!pMessage) | |
1713 return 0; | |
1714 FX_DWORD dwMsgCode = pMessage->GetClassID(); | |
1715 int32_t iRet = 1; | |
1716 switch (dwMsgCode) { | |
1717 case FWL_MSGHASH_Activate: { | |
1718 DoActivate(static_cast<CFWL_MsgActivate*>(pMessage)); | |
1719 break; | |
1720 } | |
1721 case FWL_MSGHASH_Deactivate: { | |
1722 DoDeactivate(static_cast<CFWL_MsgDeactivate*>(pMessage)); | |
1723 break; | |
1724 } | |
1725 case FWL_MSGHASH_SetFocus: | |
1726 case FWL_MSGHASH_KillFocus: { | |
1727 OnFocusChanged(pMessage, dwMsgCode == FWL_MSGHASH_SetFocus); | |
1728 break; | |
1729 } | |
1730 case FWL_MSGHASH_Mouse: { | |
1731 CFWL_MsgMouse* pMsg = static_cast<CFWL_MsgMouse*>(pMessage); | |
1732 FX_DWORD dwCmd = pMsg->m_dwCmd; | |
1733 switch (dwCmd) { | |
1734 case FWL_MSGMOUSECMD_LButtonDown: { | |
1735 OnLButtonDown(pMsg); | |
1736 break; | |
1737 } | |
1738 case FWL_MSGMOUSECMD_LButtonUp: { | |
1739 OnLButtonUp(pMsg); | |
1740 break; | |
1741 } | |
1742 case FWL_MSGMOUSECMD_LButtonDblClk: { | |
1743 OnButtonDblClk(pMsg); | |
1744 break; | |
1745 } | |
1746 case FWL_MSGMOUSECMD_MouseMove: { | |
1747 OnMouseMove(pMsg); | |
1748 break; | |
1749 } | |
1750 case FWL_MSGMOUSECMD_RButtonDown: { | |
1751 DoButtonDown(pMsg); | |
1752 break; | |
1753 } | |
1754 default: {} | |
1755 } | |
1756 break; | |
1757 } | |
1758 case FWL_MSGHASH_Key: { | |
1759 CFWL_MsgKey* pKey = static_cast<CFWL_MsgKey*>(pMessage); | |
1760 FX_DWORD dwCmd = pKey->m_dwCmd; | |
1761 if (dwCmd == FWL_MSGKEYCMD_KeyDown) { | |
1762 OnKeyDown(pKey); | |
1763 } else if (dwCmd == FWL_MSGKEYCMD_Char) { | |
1764 OnChar(pKey); | |
1765 } | |
1766 break; | |
1767 } | |
1768 default: { iRet = 0; } | |
1769 } | |
1770 CFWL_WidgetImpDelegate::OnProcessMessage(pMessage); | |
1771 return iRet; | |
1772 } | |
1773 FWL_ERR CFWL_EditImpDelegate::OnProcessEvent(CFWL_Event* pEvent) { | |
1774 if (!pEvent) | |
1775 return FWL_ERR_Indefinite; | |
1776 FX_DWORD dwHashCode = pEvent->GetClassID(); | |
1777 if (dwHashCode != FWL_EVTHASH_Scroll) { | |
1778 return FWL_ERR_Succeeded; | |
1779 } | |
1780 IFWL_Widget* pSrcTarget = pEvent->m_pSrcTarget; | |
1781 if ((pSrcTarget == m_pOwner->m_pVertScrollBar.get() && | |
1782 m_pOwner->m_pVertScrollBar) || | |
1783 (pSrcTarget == m_pOwner->m_pHorzScrollBar.get() && | |
1784 m_pOwner->m_pHorzScrollBar)) { | |
1785 CFWL_EvtScroll* pScrollEvent = static_cast<CFWL_EvtScroll*>(pEvent); | |
1786 OnScroll(static_cast<IFWL_ScrollBar*>(pSrcTarget), | |
1787 pScrollEvent->m_iScrollCode, pScrollEvent->m_fPos); | |
1788 } | |
1789 return FWL_ERR_Succeeded; | |
1790 } | |
1791 FWL_ERR CFWL_EditImpDelegate::OnDrawWidget(CFX_Graphics* pGraphics, | |
1792 const CFX_Matrix* pMatrix) { | |
1793 return m_pOwner->DrawWidget(pGraphics, pMatrix); | |
1794 } | |
1795 void CFWL_EditImpDelegate::DoActivate(CFWL_MsgActivate* pMsg) { | |
1796 m_pOwner->m_pProperties->m_dwStates |= ~FWL_WGTSTATE_Deactivated; | |
1797 m_pOwner->Repaint(&m_pOwner->m_rtClient); | |
1798 } | |
1799 void CFWL_EditImpDelegate::DoDeactivate(CFWL_MsgDeactivate* pMsg) { | |
1800 m_pOwner->m_pProperties->m_dwStates &= FWL_WGTSTATE_Deactivated; | |
1801 m_pOwner->Repaint(&m_pOwner->m_rtClient); | |
1802 } | |
1803 void CFWL_EditImpDelegate::DoButtonDown(CFWL_MsgMouse* pMsg) { | |
1804 if ((m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) == 0) { | |
1805 m_pOwner->SetFocus(TRUE); | |
1806 } | |
1807 if (!m_pOwner->m_pEdtEngine) { | |
1808 m_pOwner->UpdateEditEngine(); | |
1809 } | |
1810 IFDE_TxtEdtPage* pPage = m_pOwner->m_pEdtEngine->GetPage(0); | |
1811 if (!pPage) | |
1812 return; | |
1813 CFX_PointF pt(pMsg->m_fx, pMsg->m_fy); | |
1814 m_pOwner->DeviceToEngine(pt); | |
1815 FX_BOOL bBefore = TRUE; | |
1816 int32_t nIndex = pPage->GetCharIndex(pt, bBefore); | |
1817 if (nIndex < 0) { | |
1818 nIndex = 0; | |
1819 } | |
1820 m_pOwner->m_pEdtEngine->SetCaretPos(nIndex, bBefore); | |
1821 } | |
1822 void CFWL_EditImpDelegate::OnFocusChanged(CFWL_Message* pMsg, FX_BOOL bSet) { | |
1823 FX_DWORD dwStyleEx = m_pOwner->GetStylesEx(); | |
1824 FX_BOOL bRepaint = dwStyleEx & FWL_STYLEEXT_EDT_InnerCaret; | |
1825 if (bSet) { | |
1826 m_pOwner->m_pProperties->m_dwStates |= FWL_WGTSTATE_Focused; | |
1827 if (!m_pOwner->m_pEdtEngine) { | |
1828 m_pOwner->UpdateEditEngine(); | |
1829 } | |
1830 m_pOwner->UpdateVAlignment(); | |
1831 m_pOwner->UpdateOffset(); | |
1832 m_pOwner->UpdateCaret(); | |
1833 } else if (m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Focused) { | |
1834 m_pOwner->m_pProperties->m_dwStates &= ~FWL_WGTSTATE_Focused; | |
1835 m_pOwner->ShowCaret(FALSE); | |
1836 if (m_pOwner->m_pEdtEngine && | |
1837 (dwStyleEx & FWL_STYLEEXT_EDT_NoHideSel) == 0) { | |
1838 int32_t nSel = m_pOwner->CountSelRanges(); | |
1839 if (nSel > 0) { | |
1840 m_pOwner->ClearSelections(); | |
1841 bRepaint = TRUE; | |
1842 } | |
1843 m_pOwner->SetCaretPos(0); | |
1844 m_pOwner->UpdateOffset(); | |
1845 } | |
1846 m_pOwner->ClearRecord(); | |
1847 } | |
1848 m_pOwner->LayoutScrollBar(); | |
1849 if (bRepaint) { | |
1850 CFX_RectF rtInvalidate; | |
1851 rtInvalidate.Set(0, 0, m_pOwner->m_pProperties->m_rtWidget.width, | |
1852 m_pOwner->m_pProperties->m_rtWidget.height); | |
1853 m_pOwner->Repaint(&rtInvalidate); | |
1854 } | |
1855 } | |
1856 void CFWL_EditImpDelegate::OnLButtonDown(CFWL_MsgMouse* pMsg) { | |
1857 DoCursor(pMsg); | |
1858 if (m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled) { | |
1859 return; | |
1860 } | |
1861 m_pOwner->m_bLButtonDown = TRUE; | |
1862 m_pOwner->SetGrab(TRUE); | |
1863 DoButtonDown(pMsg); | |
1864 int32_t nIndex = m_pOwner->m_pEdtEngine->GetCaretPos(); | |
1865 FX_BOOL bRepaint = FALSE; | |
1866 int32_t iCount = m_pOwner->m_pEdtEngine->CountSelRanges(); | |
1867 if (iCount > 0) { | |
1868 m_pOwner->m_pEdtEngine->ClearSelection(); | |
1869 bRepaint = TRUE; | |
1870 } | |
1871 FX_BOOL bShift = pMsg->m_dwFlags & FWL_KEYFLAG_Shift; | |
1872 if (bShift && m_pOwner->m_nSelStart != nIndex) { | |
1873 int32_t iStart = std::min(m_pOwner->m_nSelStart, nIndex); | |
1874 int32_t iEnd = std::max(m_pOwner->m_nSelStart, nIndex); | |
1875 m_pOwner->m_pEdtEngine->AddSelRange(iStart, iEnd - iStart); | |
1876 bRepaint = TRUE; | |
1877 } else { | |
1878 m_pOwner->m_nSelStart = nIndex; | |
1879 } | |
1880 if (bRepaint) { | |
1881 m_pOwner->Repaint(&m_pOwner->m_rtEngine); | |
1882 } | |
1883 } | |
1884 void CFWL_EditImpDelegate::OnLButtonUp(CFWL_MsgMouse* pMsg) { | |
1885 DoCursor(pMsg); | |
1886 m_pOwner->m_bLButtonDown = FALSE; | |
1887 m_pOwner->SetGrab(FALSE); | |
1888 } | |
1889 void CFWL_EditImpDelegate::OnButtonDblClk(CFWL_MsgMouse* pMsg) { | |
1890 if (!m_pOwner->m_pEdtEngine) | |
1891 return; | |
1892 DoCursor(pMsg); | |
1893 IFDE_TxtEdtPage* pPage = m_pOwner->m_pEdtEngine->GetPage(0); | |
1894 if (!pPage) | |
1895 return; | |
1896 CFX_PointF pt(pMsg->m_fx, pMsg->m_fy); | |
1897 m_pOwner->DeviceToEngine(pt); | |
1898 int32_t nCount = 0; | |
1899 int32_t nIndex = pPage->SelectWord(pt, nCount); | |
1900 if (nIndex < 0) { | |
1901 return; | |
1902 } | |
1903 m_pOwner->m_pEdtEngine->AddSelRange(nIndex, nCount); | |
1904 m_pOwner->m_pEdtEngine->SetCaretPos(nIndex + nCount - 1, FALSE); | |
1905 m_pOwner->Repaint(&m_pOwner->m_rtEngine); | |
1906 } | |
1907 void CFWL_EditImpDelegate::OnMouseMove(CFWL_MsgMouse* pMsg) { | |
1908 if (!m_pOwner->m_pEdtEngine) | |
1909 return; | |
1910 DoCursor(pMsg); | |
1911 if (m_pOwner->m_nSelStart == -1 || !m_pOwner->m_bLButtonDown) { | |
1912 return; | |
1913 } | |
1914 IFDE_TxtEdtPage* pPage = m_pOwner->m_pEdtEngine->GetPage(0); | |
1915 if (!pPage) | |
1916 return; | |
1917 CFX_PointF pt(pMsg->m_fx, pMsg->m_fy); | |
1918 m_pOwner->DeviceToEngine(pt); | |
1919 FX_BOOL bBefore = TRUE; | |
1920 int32_t nIndex = pPage->GetCharIndex(pt, bBefore); | |
1921 m_pOwner->m_pEdtEngine->SetCaretPos(nIndex, bBefore); | |
1922 nIndex = m_pOwner->m_pEdtEngine->GetCaretPos(); | |
1923 m_pOwner->m_pEdtEngine->ClearSelection(); | |
1924 if (nIndex != m_pOwner->m_nSelStart) { | |
1925 int32_t nLen = m_pOwner->m_pEdtEngine->GetTextLength(); | |
1926 if (m_pOwner->m_nSelStart >= nLen) { | |
1927 m_pOwner->m_nSelStart = nLen; | |
1928 } | |
1929 m_pOwner->m_pEdtEngine->AddSelRange( | |
1930 std::min(m_pOwner->m_nSelStart, nIndex), | |
1931 FXSYS_abs(nIndex - m_pOwner->m_nSelStart)); | |
1932 } | |
1933 } | |
1934 void CFWL_EditImpDelegate::OnKeyDown(CFWL_MsgKey* pMsg) { | |
1935 if (!m_pOwner->m_pEdtEngine) | |
1936 return; | |
1937 FDE_TXTEDTMOVECARET MoveCaret = MC_MoveNone; | |
1938 FX_BOOL bShift = pMsg->m_dwFlags & FWL_KEYFLAG_Shift; | |
1939 FX_BOOL bCtrl = pMsg->m_dwFlags & FWL_KEYFLAG_Ctrl; | |
1940 FX_DWORD dwKeyCode = pMsg->m_dwKeyCode; | |
1941 switch (dwKeyCode) { | |
1942 case FWL_VKEY_Left: { | |
1943 MoveCaret = MC_Left; | |
1944 break; | |
1945 } | |
1946 case FWL_VKEY_Right: { | |
1947 MoveCaret = MC_Right; | |
1948 break; | |
1949 } | |
1950 case FWL_VKEY_Up: { | |
1951 MoveCaret = MC_Up; | |
1952 break; | |
1953 } | |
1954 case FWL_VKEY_Down: { | |
1955 MoveCaret = MC_Down; | |
1956 break; | |
1957 } | |
1958 case FWL_VKEY_Home: { | |
1959 if (bCtrl) { | |
1960 MoveCaret = MC_Home; | |
1961 } else { | |
1962 MoveCaret = MC_LineStart; | |
1963 } | |
1964 break; | |
1965 } | |
1966 case FWL_VKEY_End: { | |
1967 if (bCtrl) { | |
1968 MoveCaret = MC_End; | |
1969 } else { | |
1970 MoveCaret = MC_LineEnd; | |
1971 } | |
1972 break; | |
1973 } | |
1974 case FWL_VKEY_Insert: { | |
1975 break; | |
1976 } | |
1977 case FWL_VKEY_Delete: { | |
1978 if ((m_pOwner->m_pProperties->m_dwStyleExes & | |
1979 FWL_STYLEEXT_EDT_ReadOnly) || | |
1980 (m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) { | |
1981 break; | |
1982 } | |
1983 int32_t nCaret = m_pOwner->m_pEdtEngine->GetCaretPos(); | |
1984 #if (_FX_OS_ == _FX_MACOSX_) | |
1985 m_pOwner->m_pEdtEngine->Delete(nCaret, TRUE); | |
1986 #else | |
1987 m_pOwner->m_pEdtEngine->Delete(nCaret); | |
1988 #endif | |
1989 break; | |
1990 } | |
1991 case FWL_VKEY_F2: { | |
1992 break; | |
1993 } | |
1994 case FWL_VKEY_Tab: { | |
1995 m_pOwner->DispatchKeyEvent(pMsg); | |
1996 break; | |
1997 } | |
1998 default: { | |
1999 #if (_FX_OS_ == _FX_MACOSX_) | |
2000 if (pMsg->m_dwFlags & FWL_KEYFLAG_Command) { | |
2001 #else | |
2002 if (pMsg->m_dwFlags & FWL_KEYFLAG_Ctrl) { | |
2003 #endif | |
2004 if (dwKeyCode == 0x43 || dwKeyCode == 0x63) { | |
2005 m_pOwner->DoClipboard(1); | |
2006 return; | |
2007 } | |
2008 if (dwKeyCode == 0x58 || dwKeyCode == 0x78) { | |
2009 m_pOwner->DoClipboard(2); | |
2010 return; | |
2011 } | |
2012 if (dwKeyCode == 0x56 || dwKeyCode == 0x76) { | |
2013 m_pOwner->DoClipboard(3); | |
2014 return; | |
2015 } | |
2016 } | |
2017 } | |
2018 } | |
2019 if (MoveCaret != MC_MoveNone) { | |
2020 m_pOwner->m_pEdtEngine->MoveCaretPos(MoveCaret, bShift, bCtrl); | |
2021 } | |
2022 } | |
2023 void CFWL_EditImpDelegate::OnChar(CFWL_MsgKey* pMsg) { | |
2024 if ((m_pOwner->m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_ReadOnly) || | |
2025 (m_pOwner->m_pProperties->m_dwStates & FWL_WGTSTATE_Disabled)) { | |
2026 return; | |
2027 } | |
2028 if (!m_pOwner->m_pEdtEngine) | |
2029 return; | |
2030 int32_t iError = 0; | |
2031 FX_WCHAR c = (FX_WCHAR)pMsg->m_dwKeyCode; | |
2032 int32_t nCaret = m_pOwner->m_pEdtEngine->GetCaretPos(); | |
2033 switch (c) { | |
2034 case FWL_VKEY_Back: { | |
2035 m_pOwner->m_pEdtEngine->Delete(nCaret, TRUE); | |
2036 break; | |
2037 } | |
2038 case 0x0A: { | |
2039 break; | |
2040 } | |
2041 case FWL_VKEY_Escape: { | |
2042 break; | |
2043 } | |
2044 case FWL_VKEY_Tab: { | |
2045 iError = m_pOwner->m_pEdtEngine->Insert(nCaret, L"\t", 1); | |
2046 break; | |
2047 } | |
2048 case FWL_VKEY_Return: { | |
2049 if (m_pOwner->m_pProperties->m_dwStyleExes & | |
2050 FWL_STYLEEXT_EDT_WantReturn) { | |
2051 iError = m_pOwner->m_pEdtEngine->Insert(nCaret, L"\n", 1); | |
2052 } | |
2053 break; | |
2054 } | |
2055 default: { | |
2056 if (!m_pOwner->m_pWidgetMgr->IsFormDisabled()) { | |
2057 if (m_pOwner->m_pProperties->m_dwStyleExes & FWL_STYLEEXT_EDT_Number) { | |
2058 if (((pMsg->m_dwKeyCode < FWL_VKEY_0) && | |
2059 (pMsg->m_dwKeyCode != 0x2E && pMsg->m_dwKeyCode != 0x2D)) || | |
2060 pMsg->m_dwKeyCode > FWL_VKEY_9) { | |
2061 break; | |
2062 } | |
2063 if (!m_pOwner->ValidateNumberChar(c)) { | |
2064 break; | |
2065 } | |
2066 } | |
2067 } | |
2068 #if (_FX_OS_ == _FX_MACOSX_) | |
2069 if (pMsg->m_dwFlags & FWL_KEYFLAG_Command) | |
2070 #else | |
2071 if (pMsg->m_dwFlags & FWL_KEYFLAG_Ctrl) | |
2072 #endif | |
2073 { | |
2074 break; | |
2075 } | |
2076 iError = m_pOwner->m_pEdtEngine->Insert(nCaret, &c, 1); | |
2077 break; | |
2078 } | |
2079 } | |
2080 if (iError < 0) { | |
2081 m_pOwner->ProcessInsertError(iError); | |
2082 } | |
2083 } | |
2084 FX_BOOL CFWL_EditImpDelegate::OnScroll(IFWL_ScrollBar* pScrollBar, | |
2085 FX_DWORD dwCode, | |
2086 FX_FLOAT fPos) { | |
2087 CFX_SizeF fs; | |
2088 pScrollBar->GetRange(fs.x, fs.y); | |
2089 FX_FLOAT iCurPos = pScrollBar->GetPos(); | |
2090 FX_FLOAT fStep = pScrollBar->GetStepSize(); | |
2091 switch (dwCode) { | |
2092 case FWL_SCBCODE_Min: { | |
2093 fPos = fs.x; | |
2094 break; | |
2095 } | |
2096 case FWL_SCBCODE_Max: { | |
2097 fPos = fs.y; | |
2098 break; | |
2099 } | |
2100 case FWL_SCBCODE_StepBackward: { | |
2101 fPos -= fStep; | |
2102 if (fPos < fs.x + fStep / 2) { | |
2103 fPos = fs.x; | |
2104 } | |
2105 break; | |
2106 } | |
2107 case FWL_SCBCODE_StepForward: { | |
2108 fPos += fStep; | |
2109 if (fPos > fs.y - fStep / 2) { | |
2110 fPos = fs.y; | |
2111 } | |
2112 break; | |
2113 } | |
2114 case FWL_SCBCODE_PageBackward: { | |
2115 fPos -= pScrollBar->GetPageSize(); | |
2116 if (fPos < fs.x) { | |
2117 fPos = fs.x; | |
2118 } | |
2119 break; | |
2120 } | |
2121 case FWL_SCBCODE_PageForward: { | |
2122 fPos += pScrollBar->GetPageSize(); | |
2123 if (fPos > fs.y) { | |
2124 fPos = fs.y; | |
2125 } | |
2126 break; | |
2127 } | |
2128 case FWL_SCBCODE_Pos: | |
2129 case FWL_SCBCODE_TrackPos: { | |
2130 break; | |
2131 } | |
2132 case FWL_SCBCODE_EndScroll: { | |
2133 return FALSE; | |
2134 } | |
2135 default: {} | |
2136 } | |
2137 if (iCurPos != fPos) { | |
2138 pScrollBar->SetPos(fPos); | |
2139 pScrollBar->SetTrackPos(fPos); | |
2140 m_pOwner->UpdateOffset(pScrollBar, fPos - iCurPos); | |
2141 if (m_pOwner->m_pEdtEngine) { | |
2142 m_pOwner->UpdateCaret(); | |
2143 } | |
2144 CFX_RectF rect; | |
2145 m_pOwner->GetWidgetRect(rect); | |
2146 CFX_RectF rtInvalidate; | |
2147 rtInvalidate.Set(0, 0, rect.width + 2, rect.height + 2); | |
2148 m_pOwner->Repaint(&rtInvalidate); | |
2149 } | |
2150 return TRUE; | |
2151 } | |
2152 void CFWL_EditImpDelegate::DoCursor(CFWL_MsgMouse* pMsg) {} | |
OLD | NEW |