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