blob: 6975f5078749fc5035cad262f625360dc03af971 [file] [log] [blame]
Dan Sinclair1770c022016-03-14 14:14:16 -04001// 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/fwl/basewidget/fwl_editimp.h"
8
9#include <algorithm>
10#include <vector>
11
12#include "xfa/fde/fde_render.h"
13#include "xfa/fde/fde_renderdevice.h"
14#include "xfa/fee/ifde_txtedtpage.h"
15#include "xfa/fwl/basewidget/fwl_caretimp.h"
16#include "xfa/fwl/basewidget/fwl_comboboximp.h"
17#include "xfa/fwl/basewidget/fwl_scrollbarimp.h"
18#include "xfa/fwl/core/fwl_appimp.h"
19#include "xfa/fwl/core/fwl_noteimp.h"
20#include "xfa/fwl/core/fwl_targetimp.h"
21#include "xfa/fwl/core/fwl_threadimp.h"
22#include "xfa/fwl/core/fwl_widgetimp.h"
23#include "xfa/fwl/core/fwl_widgetmgrimp.h"
24#include "xfa/include/fwl/basewidget/fwl_caret.h"
25#include "xfa/include/fwl/basewidget/fwl_datetimepicker.h"
26#include "xfa/include/fwl/core/fwl_theme.h"
27
28// static
29IFWL_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
38IFWL_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}
47IFWL_Edit::IFWL_Edit() {}
48FWL_ERR IFWL_Edit::SetText(const CFX_WideString& wsText) {
49 return static_cast<CFWL_EditImp*>(GetImpl())->SetText(wsText);
50}
51int32_t IFWL_Edit::GetTextLength() const {
52 return static_cast<CFWL_EditImp*>(GetImpl())->GetTextLength();
53}
54FWL_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}
59FWL_ERR IFWL_Edit::ClearText() {
60 return static_cast<CFWL_EditImp*>(GetImpl())->ClearText();
61}
62int32_t IFWL_Edit::GetCaretPos() const {
63 return static_cast<CFWL_EditImp*>(GetImpl())->GetCaretPos();
64}
65int32_t IFWL_Edit::SetCaretPos(int32_t nIndex, FX_BOOL bBefore) {
66 return static_cast<CFWL_EditImp*>(GetImpl())->SetCaretPos(nIndex, bBefore);
67}
68FWL_ERR IFWL_Edit::AddSelRange(int32_t nStart, int32_t nCount) {
69 return static_cast<CFWL_EditImp*>(GetImpl())->AddSelRange(nStart, nCount);
70}
71int32_t IFWL_Edit::CountSelRanges() {
72 return static_cast<CFWL_EditImp*>(GetImpl())->CountSelRanges();
73}
74int32_t IFWL_Edit::GetSelRange(int32_t nIndex, int32_t& nStart) {
75 return static_cast<CFWL_EditImp*>(GetImpl())->GetSelRange(nIndex, nStart);
76}
77FWL_ERR IFWL_Edit::ClearSelections() {
78 return static_cast<CFWL_EditImp*>(GetImpl())->ClearSelections();
79}
80int32_t IFWL_Edit::GetLimit() {
81 return static_cast<CFWL_EditImp*>(GetImpl())->GetLimit();
82}
83FWL_ERR IFWL_Edit::SetLimit(int32_t nLimit) {
84 return static_cast<CFWL_EditImp*>(GetImpl())->SetLimit(nLimit);
85}
86FWL_ERR IFWL_Edit::SetAliasChar(FX_WCHAR wAlias) {
87 return static_cast<CFWL_EditImp*>(GetImpl())->SetAliasChar(wAlias);
88}
89FWL_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}
94FWL_ERR IFWL_Edit::DeleteSelections() {
95 return static_cast<CFWL_EditImp*>(GetImpl())->DeleteSelections();
96}
97FWL_ERR IFWL_Edit::DeleteRange(int32_t nStart, int32_t nCount) {
98 return static_cast<CFWL_EditImp*>(GetImpl())->DeleteRange(nStart, nCount);
99}
100FWL_ERR IFWL_Edit::ReplaceSelections(const CFX_WideStringC& wsReplace) {
101 return static_cast<CFWL_EditImp*>(GetImpl())->ReplaceSelections(wsReplace);
102}
103FWL_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}
109FWL_ERR IFWL_Edit::DoClipboard(int32_t iCmd) {
110 return static_cast<CFWL_EditImp*>(GetImpl())->DoClipboard(iCmd);
111}
112FX_BOOL IFWL_Edit::Copy(CFX_WideString& wsCopy) {
113 return static_cast<CFWL_EditImp*>(GetImpl())->Copy(wsCopy);
114}
115FX_BOOL IFWL_Edit::Cut(CFX_WideString& wsCut) {
116 return static_cast<CFWL_EditImp*>(GetImpl())->Cut(wsCut);
117}
118FX_BOOL IFWL_Edit::Paste(const CFX_WideString& wsPaste) {
119 return static_cast<CFWL_EditImp*>(GetImpl())->Paste(wsPaste);
120}
121FX_BOOL IFWL_Edit::Delete() {
122 return static_cast<CFWL_EditImp*>(GetImpl())->Delete();
123}
124FX_BOOL IFWL_Edit::Redo(const CFX_ByteStringC& bsRecord) {
125 return static_cast<CFWL_EditImp*>(GetImpl())->Redo(bsRecord);
126}
127FX_BOOL IFWL_Edit::Undo(const CFX_ByteStringC& bsRecord) {
128 return static_cast<CFWL_EditImp*>(GetImpl())->Undo(bsRecord);
129}
130FX_BOOL IFWL_Edit::Undo() {
131 return static_cast<CFWL_EditImp*>(GetImpl())->Undo();
132}
133FX_BOOL IFWL_Edit::Redo() {
134 return static_cast<CFWL_EditImp*>(GetImpl())->Redo();
135}
136FX_BOOL IFWL_Edit::CanUndo() {
137 return static_cast<CFWL_EditImp*>(GetImpl())->CanUndo();
138}
139FX_BOOL IFWL_Edit::CanRedo() {
140 return static_cast<CFWL_EditImp*>(GetImpl())->CanRedo();
141}
142FWL_ERR IFWL_Edit::SetTabWidth(FX_FLOAT fTabWidth, FX_BOOL bEquidistant) {
143 return static_cast<CFWL_EditImp*>(GetImpl())
144 ->SetTabWidth(fTabWidth, bEquidistant);
145}
146FWL_ERR IFWL_Edit::SetOuter(IFWL_Widget* pOuter) {
147 return static_cast<CFWL_EditImp*>(GetImpl())->SetOuter(pOuter);
148}
149FWL_ERR IFWL_Edit::SetNumberRange(int32_t iMin, int32_t iMax) {
150 return static_cast<CFWL_EditImp*>(GetImpl())->SetNumberRange(iMin, iMax);
151}
152FWL_ERR IFWL_Edit::SetBackColor(FX_DWORD dwColor) {
153 return static_cast<CFWL_EditImp*>(GetImpl())->SetBackgroundColor(dwColor);
154}
155FWL_ERR IFWL_Edit::SetFont(const CFX_WideString& wsFont, FX_FLOAT fSize) {
156 return static_cast<CFWL_EditImp*>(GetImpl())->SetFont(wsFont, fSize);
157}
158void IFWL_Edit::SetScrollOffset(FX_FLOAT fScrollOffset) {
159 return static_cast<CFWL_EditImp*>(GetImpl())->SetScrollOffset(fScrollOffset);
160}
161FX_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}
166FX_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
172CFWL_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}
196CFWL_EditImp::~CFWL_EditImp() {
197 if (m_pEdtEngine) {
198 m_pEdtEngine->Release();
199 m_pEdtEngine = NULL;
200 }
201 ClearRecord();
202}
203FWL_ERR CFWL_EditImp::GetClassName(CFX_WideString& wsClass) const {
204 wsClass = FWL_CLASS_Edit;
205 return FWL_ERR_Succeeded;
206}
207FX_DWORD CFWL_EditImp::GetClassID() const {
208 return FWL_CLASSHASH_Edit;
209}
210FWL_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}
222FWL_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}
236FWL_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}
270FWL_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}
277FWL_ERR CFWL_EditImp::SetWidgetRect(const CFX_RectF& rect) {
278 return CFWL_WidgetImp::SetWidgetRect(rect);
279}
280FWL_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}
297FX_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)
323static 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}
335void 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}
360int32_t CFWL_EditImp::GetWordAtPoint(CFX_PointF pointf, int32_t& nCount) {
361 return 0;
362}
363FX_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}
398FX_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}
423void 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}
481FWL_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}
509FWL_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}
524FWL_ERR CFWL_EditImp::SetText(const CFX_WideString& wsText) {
525 m_pEdtEngine->SetText(wsText);
526 return FWL_ERR_Succeeded;
527}
528int32_t CFWL_EditImp::GetTextLength() const {
529 if (!m_pEdtEngine)
530 return -1;
531 return m_pEdtEngine->GetTextLength();
532}
533FWL_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}
541FWL_ERR CFWL_EditImp::ClearText() {
542 if (!m_pEdtEngine)
543 return FWL_ERR_Succeeded;
544 m_pEdtEngine->ClearText();
545 return FWL_ERR_Succeeded;
546}
547int32_t CFWL_EditImp::GetCaretPos() const {
548 if (!m_pEdtEngine)
549 return -1;
550 return m_pEdtEngine->GetCaretPos();
551}
552int32_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}
557FWL_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}
563int32_t CFWL_EditImp::CountSelRanges() {
564 if (!m_pEdtEngine)
565 return 0;
566 return m_pEdtEngine->CountSelRanges();
567 return FWL_ERR_Succeeded;
568}
569int32_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}
574FWL_ERR CFWL_EditImp::ClearSelections() {
575 if (!m_pEdtEngine)
576 return FWL_ERR_Succeeded;
577 m_pEdtEngine->ClearSelection();
578 return FWL_ERR_Succeeded;
579}
580int32_t CFWL_EditImp::GetLimit() {
581 return m_nLimit;
582}
583FWL_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}
590FWL_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}
596FWL_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}
608FWL_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}
617FWL_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}
623FWL_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}
634FWL_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}
642FWL_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}
651FX_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}
669FX_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}
688FX_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}
700FX_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}
710FX_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}
718FX_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}
726FX_BOOL CFWL_EditImp::Undo() {
727 if (!CanUndo()) {
728 return FALSE;
729 }
730 CFX_ByteString bsRecord = m_RecordArr[m_iCurRecord--];
731 return Undo(bsRecord);
732}
733FX_BOOL CFWL_EditImp::Redo() {
734 if (!CanRedo()) {
735 return FALSE;
736 }
737 CFX_ByteString bsRecord = m_RecordArr[++m_iCurRecord];
738 return Redo(bsRecord);
739}
740FX_BOOL CFWL_EditImp::CanUndo() {
741 return m_iCurRecord >= 0;
742}
743FX_BOOL CFWL_EditImp::CanRedo() {
744 return m_iCurRecord < m_RecordArr.GetSize() - 1;
745}
746FWL_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}
755FWL_ERR CFWL_EditImp::SetOuter(IFWL_Widget* pOuter) {
756 m_pOuter = pOuter;
757 return FWL_ERR_Succeeded;
758}
759FWL_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}
765void 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}
793void 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}
858void CFWL_EditImp::On_SelChanged(IFDE_TxtEdtEngine* pEdit) {
859 CFX_RectF rtTemp;
860 GetClientRect(rtTemp);
861 Repaint(&rtTemp);
862}
863FX_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}
873FX_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
884void CFWL_EditImp::On_AddDoRecord(IFDE_TxtEdtEngine* pEdit,
885 const CFX_ByteStringC& bsDoRecord) {
886 AddDoRecord(bsDoRecord);
887}
888
889FX_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}
896FX_BOOL CFWL_EditImp::On_ValidateBlock(IFDE_TxtEdtEngine* pEdit,
897 int32_t nBlockIndex) {
898 return TRUE;
899}
900FX_BOOL CFWL_EditImp::On_GetBlockFormatText(IFDE_TxtEdtEngine* pEdit,
901 int32_t nBlockIndex,
902 CFX_WideString& wsBlockText) {
903 return FALSE;
904}
905FX_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}
919FWL_ERR CFWL_EditImp::SetBackgroundColor(FX_DWORD color) {
920 m_backColor = color;
921 m_updateBackColor = TRUE;
922 return FWL_ERR_Succeeded;
923}
924FWL_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}
929void CFWL_EditImp::SetScrollOffset(FX_FLOAT fScrollOffset) {
930 m_fScrollOffsetY = fScrollOffset;
931}
932void 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(&param);
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(&param);
962}
963void 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(&param);
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(&param);
1065 }
1066 pGraphics->RestoreGraphState();
1067}
1068void CFWL_EditImp::UpdateEditEngine() {
1069 UpdateEditParams();
1070 UpdateEditLayout();
1071 if (m_nLimit > -1) {
1072 m_pEdtEngine->SetLimit(m_nLimit);
1073 }
1074}
1075void 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
1191void 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
1207FX_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}
1260FX_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}
1269void 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}
1307void 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}
1344IFWL_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}
1427FX_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}
1441FX_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}
1449int32_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}
1464void 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}
1533void 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}
1595void 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}
1599void 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}
1612void CFWL_EditImp::InitEngine() {
1613 if (m_pEdtEngine) {
1614 return;
1615 }
1616 m_pEdtEngine = IFDE_TxtEdtEngine::Create();
1617}
1618extern FX_BOOL FWL_ShowCaret(IFWL_Widget* pWidget,
1619 FX_BOOL bVisible,
1620 const CFX_RectF* pRtAnchor);
1621void 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}
1645FX_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}
1680void 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}
1694void CFWL_EditImp::ClearRecord() {
1695 m_iCurRecord = -1;
1696 m_RecordArr.RemoveAll();
1697}
1698void 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}
1709CFWL_EditImpDelegate::CFWL_EditImpDelegate(CFWL_EditImp* pOwner)
1710 : m_pOwner(pOwner) {}
1711int32_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}
1773FWL_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}
1791FWL_ERR CFWL_EditImpDelegate::OnDrawWidget(CFX_Graphics* pGraphics,
1792 const CFX_Matrix* pMatrix) {
1793 return m_pOwner->DrawWidget(pGraphics, pMatrix);
1794}
1795void 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}
1799void 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}
1803void 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}
1822void 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}
1856void 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}
1884void CFWL_EditImpDelegate::OnLButtonUp(CFWL_MsgMouse* pMsg) {
1885 DoCursor(pMsg);
1886 m_pOwner->m_bLButtonDown = FALSE;
1887 m_pOwner->SetGrab(FALSE);
1888}
1889void 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}
1907void 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}
1934void 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}
2023void 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}
2084FX_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}
2152void CFWL_EditImpDelegate::DoCursor(CFWL_MsgMouse* pMsg) {}