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