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 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 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 } 40 IFWL_Edit::IFWL_Edit() {} 41 FWL_ERR IFWL_Edit::SetText(const CFX_WideString& wsText) { 42 return static_cast<CFWL_EditImp*>(GetImpl())->SetText(wsText); 43 } 44 int32_t IFWL_Edit::GetTextLength() const { 45 return static_cast<CFWL_EditImp*>(GetImpl())->GetTextLength(); 46 } 47 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 } 52 FWL_ERR IFWL_Edit::ClearText() { 53 return static_cast<CFWL_EditImp*>(GetImpl())->ClearText(); 54 } 55 int32_t IFWL_Edit::GetCaretPos() const { 56 return static_cast<CFWL_EditImp*>(GetImpl())->GetCaretPos(); 57 } 58 int32_t IFWL_Edit::SetCaretPos(int32_t nIndex, FX_BOOL bBefore) { 59 return static_cast<CFWL_EditImp*>(GetImpl())->SetCaretPos(nIndex, bBefore); 60 } 61 FWL_ERR IFWL_Edit::AddSelRange(int32_t nStart, int32_t nCount) { 62 return static_cast<CFWL_EditImp*>(GetImpl())->AddSelRange(nStart, nCount); 63 } 64 int32_t IFWL_Edit::CountSelRanges() { 65 return static_cast<CFWL_EditImp*>(GetImpl())->CountSelRanges(); 66 } 67 int32_t IFWL_Edit::GetSelRange(int32_t nIndex, int32_t& nStart) { 68 return static_cast<CFWL_EditImp*>(GetImpl())->GetSelRange(nIndex, nStart); 69 } 70 FWL_ERR IFWL_Edit::ClearSelections() { 71 return static_cast<CFWL_EditImp*>(GetImpl())->ClearSelections(); 72 } 73 int32_t IFWL_Edit::GetLimit() { 74 return static_cast<CFWL_EditImp*>(GetImpl())->GetLimit(); 75 } 76 FWL_ERR IFWL_Edit::SetLimit(int32_t nLimit) { 77 return static_cast<CFWL_EditImp*>(GetImpl())->SetLimit(nLimit); 78 } 79 FWL_ERR IFWL_Edit::SetAliasChar(FX_WCHAR wAlias) { 80 return static_cast<CFWL_EditImp*>(GetImpl())->SetAliasChar(wAlias); 81 } 82 FWL_ERR IFWL_Edit::SetFormatString(const CFX_WideString& wsFormat) { 83 return static_cast<CFWL_EditImp*>(GetImpl())->SetFormatString(wsFormat); 84 } 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 } 90 FWL_ERR IFWL_Edit::DeleteSelections() { 91 return static_cast<CFWL_EditImp*>(GetImpl())->DeleteSelections(); 92 } 93 FWL_ERR IFWL_Edit::DeleteRange(int32_t nStart, int32_t nCount) { 94 return static_cast<CFWL_EditImp*>(GetImpl())->DeleteRange(nStart, nCount); 95 } 96 FWL_ERR IFWL_Edit::ReplaceSelections(const CFX_WideStringC& wsReplace) { 97 return static_cast<CFWL_EditImp*>(GetImpl())->ReplaceSelections(wsReplace); 98 } 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 } 105 FWL_ERR IFWL_Edit::DoClipboard(int32_t iCmd) { 106 return static_cast<CFWL_EditImp*>(GetImpl())->DoClipboard(iCmd); 107 } 108 FX_BOOL IFWL_Edit::Copy(CFX_WideString& wsCopy) { 109 return static_cast<CFWL_EditImp*>(GetImpl())->Copy(wsCopy); 110 } 111 FX_BOOL IFWL_Edit::Cut(CFX_WideString& wsCut) { 112 return static_cast<CFWL_EditImp*>(GetImpl())->Cut(wsCut); 113 } 114 FX_BOOL IFWL_Edit::Paste(const CFX_WideString& wsPaste) { 115 return static_cast<CFWL_EditImp*>(GetImpl())->Paste(wsPaste); 116 } 117 FX_BOOL IFWL_Edit::Delete() { 118 return static_cast<CFWL_EditImp*>(GetImpl())->Delete(); 119 } 120 FX_BOOL IFWL_Edit::Redo(const CFX_ByteStringC& bsRecord) { 121 return static_cast<CFWL_EditImp*>(GetImpl())->Redo(bsRecord); 122 } 123 FX_BOOL IFWL_Edit::Undo(const CFX_ByteStringC& bsRecord) { 124 return static_cast<CFWL_EditImp*>(GetImpl())->Undo(bsRecord); 125 } 126 FX_BOOL IFWL_Edit::Undo() { 127 return static_cast<CFWL_EditImp*>(GetImpl())->Undo(); 128 } 129 FX_BOOL IFWL_Edit::Redo() { 130 return static_cast<CFWL_EditImp*>(GetImpl())->Redo(); 131 } 132 FX_BOOL IFWL_Edit::CanUndo() { 133 return static_cast<CFWL_EditImp*>(GetImpl())->CanUndo(); 134 } 135 FX_BOOL IFWL_Edit::CanRedo() { 136 return static_cast<CFWL_EditImp*>(GetImpl())->CanRedo(); 137 } 138 FWL_ERR IFWL_Edit::SetTabWidth(FX_FLOAT fTabWidth, FX_BOOL bEquidistant) { 139 return static_cast<CFWL_EditImp*>(GetImpl()) 140 ->SetTabWidth(fTabWidth, bEquidistant); 141 } 142 FWL_ERR IFWL_Edit::SetOuter(IFWL_Widget* pOuter) { 143 return static_cast<CFWL_EditImp*>(GetImpl())->SetOuter(pOuter); 144 } 145 FWL_ERR IFWL_Edit::SetNumberRange(int32_t iMin, int32_t iMax) { 146 return static_cast<CFWL_EditImp*>(GetImpl())->SetNumberRange(iMin, iMax); 147 } 148 FWL_ERR IFWL_Edit::SetBackColor(FX_DWORD dwColor) { 149 return static_cast<CFWL_EditImp*>(GetImpl())->SetBackgroundColor(dwColor); 150 } 151 FWL_ERR IFWL_Edit::SetFont(const CFX_WideString& wsFont, FX_FLOAT fSize) { 152 return static_cast<CFWL_EditImp*>(GetImpl())->SetFont(wsFont, fSize); 153 } 154 void IFWL_Edit::SetScrollOffset(FX_FLOAT fScrollOffset) { 155 return static_cast<CFWL_EditImp*>(GetImpl())->SetScrollOffset(fScrollOffset); 156 } 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 } 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 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 } 192 CFWL_EditImp::~CFWL_EditImp() { 193 if (m_pEdtEngine) { 194 m_pEdtEngine->Release(); 195 m_pEdtEngine = NULL; 196 } 197 ClearRecord(); 198 } 199 FWL_ERR CFWL_EditImp::GetClassName(CFX_WideString& wsClass) const { 200 wsClass = FWL_CLASS_Edit; 201 return FWL_ERR_Succeeded; 202 } 203 FX_DWORD CFWL_EditImp::GetClassID() const { 204 return FWL_CLASSHASH_Edit; 205 } 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 } 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 } 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 } 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 } 273 FWL_ERR CFWL_EditImp::SetWidgetRect(const CFX_RectF& rect) { 274 return CFWL_WidgetImp::SetWidgetRect(rect); 275 } 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 } 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) 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 } 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 } 356 int32_t CFWL_EditImp::GetWordAtPoint(CFX_PointF pointf, int32_t& nCount) { 357 return 0; 358 } 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 } 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 } 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 } 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 } 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 } 520 FWL_ERR CFWL_EditImp::SetText(const CFX_WideString& wsText) { 521 m_pEdtEngine->SetText(wsText); 522 return FWL_ERR_Succeeded; 523 } 524 int32_t CFWL_EditImp::GetTextLength() const { 525 if (!m_pEdtEngine) 526 return -1; 527 return m_pEdtEngine->GetTextLength(); 528 } 529 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 } 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 } 543 int32_t CFWL_EditImp::GetCaretPos() const { 544 if (!m_pEdtEngine) 545 return -1; 546 return m_pEdtEngine->GetCaretPos(); 547 } 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 } 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 } 559 int32_t CFWL_EditImp::CountSelRanges() { 560 if (!m_pEdtEngine) 561 return 0; 562 return m_pEdtEngine->CountSelRanges(); 563 return FWL_ERR_Succeeded; 564 } 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 } 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 } 576 int32_t CFWL_EditImp::GetLimit() { 577 return m_nLimit; 578 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 791 FX_BOOL CFWL_EditImp::CanUndo() { 792 return m_iCurRecord >= 0; 793 } 794 FX_BOOL CFWL_EditImp::CanRedo() { 795 return m_iCurRecord < m_RecordArr.GetSize() - 1; 796 } 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 } 806 FWL_ERR CFWL_EditImp::SetOuter(IFWL_Widget* pOuter) { 807 m_pOuter = pOuter; 808 return FWL_ERR_Succeeded; 809 } 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 } 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 } 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 } 909 void CFWL_EditImp::On_SelChanged(IFDE_TxtEdtEngine* pEdit) { 910 CFX_RectF rtTemp; 911 GetClientRect(rtTemp); 912 Repaint(&rtTemp); 913 } 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 } 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 } 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 } 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 } 953 FX_BOOL CFWL_EditImp::On_ValidateBlock(IFDE_TxtEdtEngine* pEdit, 954 int32_t nBlockIndex) { 955 return TRUE; 956 } 957 FX_BOOL CFWL_EditImp::On_GetBlockFormatText(IFDE_TxtEdtEngine* pEdit, 958 int32_t nBlockIndex, 959 CFX_WideString& wsBlockText) { 960 return FALSE; 961 } 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 } 976 FWL_ERR CFWL_EditImp::SetBackgroundColor(FX_DWORD color) { 977 m_backColor = color; 978 m_updateBackColor = TRUE; 979 return FWL_ERR_Succeeded; 980 } 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 } 986 void CFWL_EditImp::SetScrollOffset(FX_FLOAT fScrollOffset) { 987 m_fScrollOffsetY = fScrollOffset; 988 } 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 } 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 } 1125 void CFWL_EditImp::UpdateEditEngine() { 1126 UpdateEditParams(); 1127 UpdateEditLayout(); 1128 if (m_nLimit > -1) { 1129 m_pEdtEngine->SetLimit(m_nLimit); 1130 } 1131 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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); 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 } 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 } 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 } 1751 void CFWL_EditImp::ClearRecord() { 1752 m_iCurRecord = -1; 1753 m_RecordArr.RemoveAll(); 1754 } 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 } 1766 CFWL_EditImpDelegate::CFWL_EditImpDelegate(CFWL_EditImp* pOwner) 1767 : m_pOwner(pOwner) {} 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 } 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 } 1848 FWL_ERR CFWL_EditImpDelegate::OnDrawWidget(CFX_Graphics* pGraphics, 1849 const CFX_Matrix* pMatrix) { 1850 return m_pOwner->DrawWidget(pGraphics, pMatrix); 1851 } 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 } 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 } 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 } 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 } 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 } 1942 void CFWL_EditImpDelegate::OnLButtonUp(CFWL_MsgMouse* pMsg) { 1943 DoCursor(pMsg); 1944 m_pOwner->m_bLButtonDown = FALSE; 1945 m_pOwner->SetGrab(FALSE); 1946 } 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 } 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 } 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 } 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 } 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 } 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