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