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