diff --git a/Import/GacUI.Windows.cpp b/Import/GacUI.Windows.cpp index e4e29beb..fd0fb0df 100644 --- a/Import/GacUI.Windows.cpp +++ b/Import/GacUI.Windows.cpp @@ -3467,11 +3467,11 @@ WindowsDirect2DParagraph (Formatting) void SetWrapLine(bool value)override { - if(wrapLine!=value) + if (wrapLine != value) { - wrapLine=value; - textLayout->SetWordWrapping(value?DWRITE_WORD_WRAPPING_WRAP:DWRITE_WORD_WRAPPING_NO_WRAP); - formatDataAvailable=false; + wrapLine = value; + textLayout->SetWordWrapping(value ? DWRITE_WORD_WRAPPING_WRAP : DWRITE_WORD_WRAPPING_NO_WRAP); + formatDataAvailable = false; } } @@ -3656,11 +3656,13 @@ WindowsDirect2DParagraph (Formatting) return false; } - vint GetHeight()override + Size GetSize()override { DWRITE_TEXT_METRICS metrics; textLayout->GetMetrics(&metrics); - return (vint)ceil(metrics.height); + return Size( + (wrapLine ? 0 : (vint)ceil(metrics.widthIncludingTrailingWhitespace)), + (vint)ceil(metrics.height)); } /*********************************************************************** @@ -4070,7 +4072,7 @@ WindowsDirect2DParagraph (Caret) { PrepareFormatData(); if(!IsValidCaret(caret)) return Rect(); - if(paragraphText.Length()==0) return Rect(Point(0, 0), Size(0, GetHeight())); + if(paragraphText.Length()==0) return Rect(Point(0, 0), Size(0, GetSize().y)); vint frontLineIndex=-1; vint backLineIndex=-1; @@ -5442,6 +5444,78 @@ GuiPolygonElementRenderer } } +/*********************************************************************** +GuiDirect2DElementRenderer +***********************************************************************/ + + void GuiDirect2DElementRenderer::InitializeInternal() + { + } + + void GuiDirect2DElementRenderer::FinalizeInternal() + { + } + + void GuiDirect2DElementRenderer::RenderTargetChangedInternal(IWindowsDirect2DRenderTarget* oldRenderTarget, IWindowsDirect2DRenderTarget* newRenderTarget) + { + IDWriteFactory* fdw=GetWindowsDirect2DObjectProvider()->GetDirectWriteFactory(); + ID2D1Factory* fd2d=GetWindowsDirect2DObjectProvider()->GetDirect2DFactory(); + if(oldRenderTarget) + { + GuiDirect2DElementEventArgs arguments(element, oldRenderTarget->GetDirect2DRenderTarget(), fdw, fd2d, Rect()); + element->BeforeRenderTargetChanged.Execute(arguments); + } + if(newRenderTarget) + { + GuiDirect2DElementEventArgs arguments(element, newRenderTarget->GetDirect2DRenderTarget(), fdw, fd2d, Rect()); + element->AfterRenderTargetChanged.Execute(arguments); + } + } + + GuiDirect2DElementRenderer::GuiDirect2DElementRenderer() + { + } + + GuiDirect2DElementRenderer::~GuiDirect2DElementRenderer() + { + } + + void GuiDirect2DElementRenderer::Render(Rect bounds) + { + if(renderTarget) + { + IDWriteFactory* fdw=GetWindowsDirect2DObjectProvider()->GetDirectWriteFactory(); + ID2D1Factory* fd2d=GetWindowsDirect2DObjectProvider()->GetDirect2DFactory(); + renderTarget->PushClipper(bounds, element); + if(!renderTarget->IsClipperCoverWholeTarget()) + { + ID2D1RenderTarget* rt=renderTarget->GetDirect2DRenderTarget(); + GuiDirect2DElementEventArgs arguments(element, rt, fdw, fd2d, bounds); + element->Rendering.Execute(arguments); + } + renderTarget->PopClipper(element); + } + } + + void GuiDirect2DElementRenderer::OnElementStateChanged() + { + } + } + } +} + +/*********************************************************************** +.\DIRECT2D\RENDERERS\GUIGRAPHICSTEXTRENDERERSWINDOWSDIRECT2D.CPP +***********************************************************************/ + +namespace vl +{ + namespace presentation + { + namespace elements_windows_d2d + { + using namespace collections; + /*********************************************************************** GuiColorizedTextElementRenderer ***********************************************************************/ @@ -5689,63 +5763,6 @@ GuiColorizedTextElementRenderer } } } - -/*********************************************************************** -GuiDirect2DElementRenderer -***********************************************************************/ - - void GuiDirect2DElementRenderer::InitializeInternal() - { - } - - void GuiDirect2DElementRenderer::FinalizeInternal() - { - } - - void GuiDirect2DElementRenderer::RenderTargetChangedInternal(IWindowsDirect2DRenderTarget* oldRenderTarget, IWindowsDirect2DRenderTarget* newRenderTarget) - { - IDWriteFactory* fdw=GetWindowsDirect2DObjectProvider()->GetDirectWriteFactory(); - ID2D1Factory* fd2d=GetWindowsDirect2DObjectProvider()->GetDirect2DFactory(); - if(oldRenderTarget) - { - GuiDirect2DElementEventArgs arguments(element, oldRenderTarget->GetDirect2DRenderTarget(), fdw, fd2d, Rect()); - element->BeforeRenderTargetChanged.Execute(arguments); - } - if(newRenderTarget) - { - GuiDirect2DElementEventArgs arguments(element, newRenderTarget->GetDirect2DRenderTarget(), fdw, fd2d, Rect()); - element->AfterRenderTargetChanged.Execute(arguments); - } - } - - GuiDirect2DElementRenderer::GuiDirect2DElementRenderer() - { - } - - GuiDirect2DElementRenderer::~GuiDirect2DElementRenderer() - { - } - - void GuiDirect2DElementRenderer::Render(Rect bounds) - { - if(renderTarget) - { - IDWriteFactory* fdw=GetWindowsDirect2DObjectProvider()->GetDirectWriteFactory(); - ID2D1Factory* fd2d=GetWindowsDirect2DObjectProvider()->GetDirect2DFactory(); - renderTarget->PushClipper(bounds, element); - if(!renderTarget->IsClipperCoverWholeTarget()) - { - ID2D1RenderTarget* rt=renderTarget->GetDirect2DRenderTarget(); - GuiDirect2DElementEventArgs arguments(element, rt, fdw, fd2d, bounds); - element->Rendering.Execute(arguments); - } - renderTarget->PopClipper(element); - } - } - - void GuiDirect2DElementRenderer::OnElementStateChanged() - { - } } } } @@ -8812,11 +8829,18 @@ WindowsGDIParagraph bool GetWrapLine()override { - return true; + return paragraph->wrapLine; } void SetWrapLine(bool value)override { + CHECK_ERROR(value, L"vl::presentation::elements_windows_gdi::WindowsGDIParagraph::SetWrapLine(bool)#Non-wrapline not implemented."); + if (paragraph->wrapLine != value) + { + paragraph->wrapLine = value; + paragraph->BuildUniscribeData(renderTarget->GetDC()); + paragraph->Layout(paragraph->lastAvailableWidth, paragraph->paragraphAlignment); + } } vint GetMaxWidth()override @@ -8948,10 +8972,12 @@ WindowsGDIParagraph return false; } - vint GetHeight()override + Size GetSize()override { PrepareUniscribeData(); - return paragraph->bounds.Height(); + return Size( + (paragraph->wrapLine ? 0 : paragraph->bounds.Width()), + paragraph->bounds.Height()); } bool OpenCaret(vint _caret, Color _color, bool _frontSide)override @@ -9899,6 +9925,65 @@ GuiPolygonElementRenderer } } +/*********************************************************************** +GuiGDIElementRenderer +***********************************************************************/ + + void GuiGDIElementRenderer::InitializeInternal() + { + } + + void GuiGDIElementRenderer::FinalizeInternal() + { + } + + void GuiGDIElementRenderer::RenderTargetChangedInternal(IWindowsGDIRenderTarget* oldRenderTarget, IWindowsGDIRenderTarget* newRenderTarget) + { + } + + GuiGDIElementRenderer::GuiGDIElementRenderer() + { + } + + GuiGDIElementRenderer::~GuiGDIElementRenderer() + { + } + + void GuiGDIElementRenderer::Render(Rect bounds) + { + if(renderTarget) + { + renderTarget->PushClipper(bounds, element); + if(!renderTarget->IsClipperCoverWholeTarget()) + { + WinDC* dc=renderTarget->GetDC(); + GuiGDIElementEventArgs arguments(element, dc, bounds); + element->Rendering.Execute(arguments); + } + renderTarget->PopClipper(element); + } + } + + void GuiGDIElementRenderer::OnElementStateChanged() + { + } + } + } +} + +/*********************************************************************** +.\GDI\RENDERERS\GUIGRAPHICSTEXTRENDERERSWINDOWSGDI.CPP +***********************************************************************/ + +namespace vl +{ + namespace presentation + { + namespace elements_windows_gdi + { + using namespace windows; + using namespace collections; + /*********************************************************************** GuiColorizedTextElementRenderer ***********************************************************************/ @@ -10095,49 +10180,6 @@ GuiColorizedTextElementRenderer caretPen=resourceManager->CreateGdiPen(oldCaretColor); } } - -/*********************************************************************** -GuiGDIElementRenderer -***********************************************************************/ - - void GuiGDIElementRenderer::InitializeInternal() - { - } - - void GuiGDIElementRenderer::FinalizeInternal() - { - } - - void GuiGDIElementRenderer::RenderTargetChangedInternal(IWindowsGDIRenderTarget* oldRenderTarget, IWindowsGDIRenderTarget* newRenderTarget) - { - } - - GuiGDIElementRenderer::GuiGDIElementRenderer() - { - } - - GuiGDIElementRenderer::~GuiGDIElementRenderer() - { - } - - void GuiGDIElementRenderer::Render(Rect bounds) - { - if(renderTarget) - { - renderTarget->PushClipper(bounds, element); - if(!renderTarget->IsClipperCoverWholeTarget()) - { - WinDC* dc=renderTarget->GetDC(); - GuiGDIElementEventArgs arguments(element, dc, bounds); - element->Rendering.Execute(arguments); - } - renderTarget->PopClipper(element); - } - } - - void GuiGDIElementRenderer::OnElementStateChanged() - { - } } } } @@ -11483,7 +11525,8 @@ UniscribeParagraph ***********************************************************************/ UniscribeParagraph::UniscribeParagraph() - :lastAvailableWidth(-1) + :wrapLine(true) + ,lastAvailableWidth(-1) ,paragraphAlignment(Alignment::Left) ,built(false) { @@ -13262,31 +13305,17 @@ WindowsClipboardWriter void WindowsClipboardWriter::SetDocument(Ptr value) { - documentData = value; if (!textData) { - textData = documentData->GetText(true); + textData = value->GetTextForReading(WString::Unmanaged(L"\r\n\r\n")); } - if (!imageData && documentData->paragraphs.Count() == 1) + if (!imageData) { - Ptr container = documentData->paragraphs[0]; - while (container) - { - if (container->runs.Count() != 1) goto FAILED; - if (auto imageRun = container->runs[0].Cast()) - { - imageData = imageRun->image; - break; - } - else - { - container = container->runs[0].Cast(); - } - } - FAILED:; + imageData = GetImageFromSingleImageDocument(value); } + documentData = value; ModifyDocumentForClipboard(documentData); } diff --git a/Import/GacUI.Windows.h b/Import/GacUI.Windows.h index 74b7706e..6370e1bb 100644 --- a/Import/GacUI.Windows.h +++ b/Import/GacUI.Windows.h @@ -481,6 +481,54 @@ Renderers void OnElementStateChanged()override; }; + class GuiDirect2DElementRenderer : public GuiElementRendererBase + { + friend class GuiElementRendererBase; + + protected: + + void InitializeInternal(); + void FinalizeInternal(); + void RenderTargetChangedInternal(IWindowsDirect2DRenderTarget* oldRenderTarget, IWindowsDirect2DRenderTarget* newRenderTarget); + public: + GuiDirect2DElementRenderer(); + ~GuiDirect2DElementRenderer(); + + void Render(Rect bounds)override; + void OnElementStateChanged()override; + }; + } + } +} + +#endif + +/*********************************************************************** +.\DIRECT2D\RENDERERS\GUIGRAPHICSTEXTRENDERERSWINDOWSDIRECT2D.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI::Native Window::Direct2D Provider for Windows Implementation::Renderer + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_ELEMENTS_GUIGRAPHICSTEXTRENDERERSWINDOWSDIRECT2D +#define VCZH_PRESENTATION_ELEMENTS_GUIGRAPHICSTEXTRENDERERSWINDOWSDIRECT2D + + +namespace vl +{ + namespace presentation + { + namespace elements_windows_d2d + { + +/*********************************************************************** +Renderers +***********************************************************************/ + class GuiColorizedTextElementRenderer : public GuiElementRendererBase, protected GuiColorizedTextElement::ICallback { friend class GuiElementRendererBase; @@ -528,23 +576,6 @@ Renderers void Render(Rect bounds)override; void OnElementStateChanged()override; }; - - class GuiDirect2DElementRenderer : public GuiElementRendererBase - { - friend class GuiElementRendererBase; - - protected: - - void InitializeInternal(); - void FinalizeInternal(); - void RenderTargetChangedInternal(IWindowsDirect2DRenderTarget* oldRenderTarget, IWindowsDirect2DRenderTarget* newRenderTarget); - public: - GuiDirect2DElementRenderer(); - ~GuiDirect2DElementRenderer(); - - void Render(Rect bounds)override; - void OnElementStateChanged()override; - }; } } } @@ -1345,6 +1376,7 @@ UniscribeParagraph //***************************** Uniscribe Data List> lines; //***************************** Layout Data + bool wrapLine; vint lastAvailableWidth; Rect bounds; @@ -1710,6 +1742,54 @@ Renderers void OnElementStateChanged()override; }; + class GuiGDIElementRenderer : public GuiElementRendererBase + { + friend class GuiElementRendererBase; + + protected: + + void InitializeInternal(); + void FinalizeInternal(); + void RenderTargetChangedInternal(IWindowsGDIRenderTarget* oldRenderTarget, IWindowsGDIRenderTarget* newRenderTarget); + public: + GuiGDIElementRenderer(); + ~GuiGDIElementRenderer(); + + void Render(Rect bounds)override; + void OnElementStateChanged()override; + }; + } + } +} + +#endif + +/*********************************************************************** +.\GDI\RENDERERS\GUIGRAPHICSTEXTRENDERERSWINDOWSGDI.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI::Native Window::GDI Provider for Windows Implementation::Renderer + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_ELEMENTS_GUIGRAPHICSTEXTRENDERERSWINDOWSGDI +#define VCZH_PRESENTATION_ELEMENTS_GUIGRAPHICSTEXTRENDERERSWINDOWSGDI + + +namespace vl +{ + namespace presentation + { + namespace elements_windows_gdi + { + +/*********************************************************************** +Renderers +***********************************************************************/ + class GuiColorizedTextElementRenderer : public GuiElementRendererBase, protected GuiColorizedTextElement::ICallback { friend class GuiElementRendererBase; @@ -1751,23 +1831,6 @@ Renderers void Render(Rect bounds)override; void OnElementStateChanged()override; }; - - class GuiGDIElementRenderer : public GuiElementRendererBase - { - friend class GuiElementRendererBase; - - protected: - - void InitializeInternal(); - void FinalizeInternal(); - void RenderTargetChangedInternal(IWindowsGDIRenderTarget* oldRenderTarget, IWindowsGDIRenderTarget* newRenderTarget); - public: - GuiGDIElementRenderer(); - ~GuiGDIElementRenderer(); - - void Render(Rect bounds)override; - void OnElementStateChanged()override; - }; } } } diff --git a/Import/GacUI.cpp b/Import/GacUI.cpp index 73e6dc54..d2b90a5c 100644 --- a/Import/GacUI.cpp +++ b/Import/GacUI.cpp @@ -18022,6 +18022,75 @@ namespace vl using namespace elements; using namespace compositions; +/*********************************************************************** +GuiDocumentConfig +***********************************************************************/ + + GuiDocumentConfig GuiDocumentConfig::GetDocumentLabelDefaultConfig() + { + GuiDocumentConfig config; + config.autoExpand = true; + config.pasteAsPlainText = false; + config.wrapLine = true; + config.paragraphMode = GuiDocumentParagraphMode::Paragraph; + config.paragraphPadding = true; + config.doubleLineBreaksBetweenParagraph = true; + config.spaceForFlattenedLineBreak = false; + return config; + } + + GuiDocumentConfig GuiDocumentConfig::GetDocumentViewerDefaultConfig() + { + GuiDocumentConfig config; + config.autoExpand = false; + config.pasteAsPlainText = false; + config.wrapLine = true; + config.paragraphMode = GuiDocumentParagraphMode::Paragraph; + config.paragraphPadding = true; + config.doubleLineBreaksBetweenParagraph = true; + config.spaceForFlattenedLineBreak = false; + return config; + } + + GuiDocumentConfig GuiDocumentConfig::GetSinglelineTextBoxDefaultConfig() + { + GuiDocumentConfig config; + config.autoExpand = false; + config.pasteAsPlainText = true; + config.wrapLine = false; + config.paragraphMode = GuiDocumentParagraphMode::Singleline; + config.paragraphPadding = false; + config.doubleLineBreaksBetweenParagraph = false; + config.spaceForFlattenedLineBreak = false; + return config; + } + + GuiDocumentConfig GuiDocumentConfig::GetMultilineTextBoxDefaultConfig() + { + GuiDocumentConfig config; + config.autoExpand = false; + config.pasteAsPlainText = true; + config.wrapLine = false; + config.paragraphMode = GuiDocumentParagraphMode::Multiline; + config.paragraphPadding = false; + config.doubleLineBreaksBetweenParagraph = false; + config.spaceForFlattenedLineBreak = false; + return config; + } + + GuiDocumentConfig GuiDocumentConfig::OverrideConfig(const GuiDocumentConfig& toOverride, const GuiDocumentConfig& newConfig) + { + GuiDocumentConfig result = toOverride; + if (newConfig.autoExpand) result.autoExpand = newConfig.autoExpand; + if (newConfig.pasteAsPlainText) result.pasteAsPlainText = newConfig.pasteAsPlainText; + if (newConfig.wrapLine) result.wrapLine = newConfig.wrapLine; + if (newConfig.paragraphMode) result.paragraphMode = newConfig.paragraphMode; + if (newConfig.paragraphPadding) result.paragraphPadding = newConfig.paragraphPadding; + if (newConfig.doubleLineBreaksBetweenParagraph) result.doubleLineBreaksBetweenParagraph = newConfig.doubleLineBreaksBetweenParagraph; + if (newConfig.spaceForFlattenedLineBreak) result.spaceForFlattenedLineBreak = newConfig.spaceForFlattenedLineBreak; + return result; + } + /*********************************************************************** GuiDocumentItem ***********************************************************************/ @@ -18107,65 +18176,65 @@ GuiDocumentCommonInterface bool GuiDocumentCommonInterface::ProcessKey(VKEY code, bool shift, bool ctrl) { - if(IGuiShortcutKeyItem* item=internalShortcutKeyManager->TryGetShortcut(ctrl, shift, false, code)) + if (IGuiShortcutKeyItem* item = internalShortcutKeyManager->TryGetShortcut(ctrl, shift, false, code)) { GuiEventArgs arguments(documentControl->GetBoundsComposition()); item->Executed.Execute(arguments); return true; } - TextPos currentCaret=documentElement->GetCaretEnd(); - bool frontSide=documentElement->IsCaretEndPreferFrontSide(); - TextPos begin=documentElement->GetCaretBegin(); - TextPos end=documentElement->GetCaretEnd(); + TextPos currentCaret = documentElement->GetCaretEnd(); + bool frontSide = documentElement->IsCaretEndPreferFrontSide(); + TextPos begin = documentElement->GetCaretBegin(); + TextPos end = documentElement->GetCaretEnd(); - switch(code) + switch (code) { case VKEY::KEY_UP: { - TextPos newCaret=documentElement->CalculateCaret(currentCaret, IGuiGraphicsParagraph::CaretMoveUp, frontSide); + TextPos newCaret = documentElement->CalculateCaret(currentCaret, IGuiGraphicsParagraph::CaretMoveUp, frontSide); Move(newCaret, shift, frontSide); } break; case VKEY::KEY_DOWN: { - TextPos newCaret=documentElement->CalculateCaret(currentCaret, IGuiGraphicsParagraph::CaretMoveDown, frontSide); + TextPos newCaret = documentElement->CalculateCaret(currentCaret, IGuiGraphicsParagraph::CaretMoveDown, frontSide); Move(newCaret, shift, frontSide); } break; case VKEY::KEY_LEFT: { - TextPos newCaret=documentElement->CalculateCaret(currentCaret, IGuiGraphicsParagraph::CaretMoveLeft, frontSide); + TextPos newCaret = documentElement->CalculateCaret(currentCaret, IGuiGraphicsParagraph::CaretMoveLeft, frontSide); Move(newCaret, shift, frontSide); } break; case VKEY::KEY_RIGHT: { - TextPos newCaret=documentElement->CalculateCaret(currentCaret, IGuiGraphicsParagraph::CaretMoveRight, frontSide); + TextPos newCaret = documentElement->CalculateCaret(currentCaret, IGuiGraphicsParagraph::CaretMoveRight, frontSide); Move(newCaret, shift, frontSide); } break; case VKEY::KEY_HOME: { - TextPos newCaret=documentElement->CalculateCaret(currentCaret, IGuiGraphicsParagraph::CaretLineFirst, frontSide); - if(newCaret==currentCaret) + TextPos newCaret = documentElement->CalculateCaret(currentCaret, IGuiGraphicsParagraph::CaretLineFirst, frontSide); + if (newCaret == currentCaret) { - newCaret=documentElement->CalculateCaret(currentCaret, IGuiGraphicsParagraph::CaretFirst, frontSide); + newCaret = documentElement->CalculateCaret(currentCaret, IGuiGraphicsParagraph::CaretFirst, frontSide); } Move(newCaret, shift, frontSide); } break; case VKEY::KEY_END: { - TextPos newCaret=documentElement->CalculateCaret(currentCaret, IGuiGraphicsParagraph::CaretLineLast, frontSide); - if(newCaret==currentCaret) + TextPos newCaret = documentElement->CalculateCaret(currentCaret, IGuiGraphicsParagraph::CaretLineLast, frontSide); + if (newCaret == currentCaret) { - newCaret=documentElement->CalculateCaret(currentCaret, IGuiGraphicsParagraph::CaretLast, frontSide); + newCaret = documentElement->CalculateCaret(currentCaret, IGuiGraphicsParagraph::CaretLast, frontSide); } Move(newCaret, shift, frontSide); } - break; - case VKEY::KEY_PRIOR: + break; + case VKEY::KEY_PRIOR: { } break; @@ -18174,9 +18243,9 @@ GuiDocumentCommonInterface } break; case VKEY::KEY_BACK: - if(editMode==Editable) + if (editMode == GuiDocumentEditMode::Editable) { - if(begin==end) + if (begin == end) { ProcessKey(VKEY::KEY_LEFT, true, false); } @@ -18186,9 +18255,9 @@ GuiDocumentCommonInterface } break; case VKEY::KEY_DELETE: - if(editMode==Editable) + if (editMode == GuiDocumentEditMode::Editable) { - if(begin==end) + if (begin == end) { ProcessKey(VKEY::KEY_RIGHT, true, false); } @@ -18198,12 +18267,12 @@ GuiDocumentCommonInterface } break; case VKEY::KEY_RETURN: - if(editMode==Editable) + if (editMode == GuiDocumentEditMode::Editable) { - if(ctrl) + if (ctrl) { Array text(1); - text[0]=L"\r\n"; + text[0] = L"\r\n"; EditText(documentElement->GetCaretBegin(), documentElement->GetCaretEnd(), documentElement->IsCaretEndPreferFrontSide(), text); } else @@ -18231,6 +18300,8 @@ GuiDocumentCommonInterface documentElement = GuiDocumentElement::Create(); documentElement->SetCallback(this); + documentElement->SetParagraphPadding(config.paragraphPadding); + documentElement->SetWrapLine(config.wrapLine); documentComposition = new GuiBoundsComposition; documentComposition->SetOwnedElement(Ptr(documentElement)); @@ -18413,9 +18484,9 @@ GuiDocumentCommonInterface void GuiDocumentCommonInterface::OnCaretNotify(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments) { - if(documentControl->GetVisuallyEnabled()) + if (documentControl->GetVisuallyEnabled()) { - if(editMode!=ViewOnly) + if (editMode != GuiDocumentEditMode::ViewOnly) { documentElement->SetCaretVisible(!documentElement->GetCaretVisible()); } @@ -18424,9 +18495,9 @@ GuiDocumentCommonInterface void GuiDocumentCommonInterface::OnGotFocus(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments) { - if(documentControl->GetVisuallyEnabled()) + if (documentControl->GetVisuallyEnabled()) { - if(editMode!=ViewOnly) + if (editMode != GuiDocumentEditMode::ViewOnly) { documentElement->SetCaretVisible(true); UpdateCaretPoint(); @@ -18444,13 +18515,13 @@ GuiDocumentCommonInterface void GuiDocumentCommonInterface::OnKeyDown(compositions::GuiGraphicsComposition* sender, compositions::GuiKeyEventArgs& arguments) { - if(documentControl->GetVisuallyEnabled()) + if (documentControl->GetVisuallyEnabled()) { - if(editMode!=ViewOnly) + if (editMode != GuiDocumentEditMode::ViewOnly) { - if(ProcessKey(arguments.code, arguments.shift, arguments.ctrl)) + if (ProcessKey(arguments.code, arguments.shift, arguments.ctrl)) { - arguments.handled=true; + arguments.handled = true; } } } @@ -18460,7 +18531,7 @@ GuiDocumentCommonInterface { if (documentControl->GetVisuallyEnabled()) { - if (editMode == Editable && + if (editMode == GuiDocumentEditMode::Editable && arguments.code != (wchar_t)VKEY::KEY_ESCAPE && arguments.code != (wchar_t)VKEY::KEY_BACK && arguments.code != (wchar_t)VKEY::KEY_RETURN && @@ -18509,7 +18580,7 @@ GuiDocumentCommonInterface { switch(editMode) { - case ViewOnly: + case GuiDocumentEditMode::ViewOnly: { auto package = documentElement->GetHyperlinkFromPoint({ x, y }); bool handCursor = false; @@ -18546,8 +18617,8 @@ GuiDocumentCommonInterface } } break; - case Selectable: - case Editable: + case GuiDocumentEditMode::Selectable: + case GuiDocumentEditMode::Editable: if(dragging) { TextPos caret=documentElement->CalculateCaretFromPoint(Point(x, y)); @@ -18569,11 +18640,11 @@ GuiDocumentCommonInterface { switch(editMode) { - case ViewOnly: + case GuiDocumentEditMode::ViewOnly: SetActiveHyperlink(documentElement->GetHyperlinkFromPoint({ x, y })); break; - case Selectable: - case Editable: + case GuiDocumentEditMode::Selectable: + case GuiDocumentEditMode::Editable: { documentControl->SetFocused(); TextPos caret=documentElement->CalculateCaretFromPoint(Point(x, y)); @@ -18600,7 +18671,7 @@ GuiDocumentCommonInterface dragging=false; switch(editMode) { - case ViewOnly: + case GuiDocumentEditMode::ViewOnly: { auto package = documentElement->GetHyperlinkFromPoint({ x, y }); if(activeHyperlinks) @@ -18672,10 +18743,181 @@ GuiDocumentCommonInterface //================ basic - GuiDocumentCommonInterface::GuiDocumentCommonInterface() + WString GuiDocumentCommonInterface::UserInput_ConvertDocumentToText(Ptr model) + { + return model->GetTextForReading(WString::Unmanaged(config.doubleLineBreaksBetweenParagraph ? L"\r\n\r\n" : L"\r\n")); + } + + void GuiDocumentCommonInterface::UserInput_FormatText(const WString& text, collections::List& paragraphTexts) + { + stream::StringReader reader(text); + WString paragraph; + bool empty = true; + + if (config.doubleLineBreaksBetweenParagraph) + { + while (!reader.IsEnd()) + { + WString line = reader.ReadLine(); + if (empty) + { + paragraph += line; + empty = false; + } + else if (line != L"") + { + if (config.paragraphMode == GuiDocumentParagraphMode::Paragraph) + { + paragraph += L"\r\n" + line; + } + else if(config.spaceForFlattenedLineBreak) + { + paragraph += L" " + line; + } + else + { + paragraph += line; + } + } + else + { + paragraphTexts.Add(paragraph); + paragraph = L""; + empty = true; + } + } + } + else + { + while (!reader.IsEnd()) + { + WString line = reader.ReadLine(); + paragraphTexts.Add(line); + } + } + + if (!empty) + { + paragraphTexts.Add(paragraph); + } + + if (config.paragraphMode == GuiDocumentParagraphMode::Singleline) + { + auto line = stream::GenerateToStream([&](stream::StreamWriter& writer) + { + for(auto [paragraph, index] : indexed(paragraphTexts)) + { + if (index > 0 && config.spaceForFlattenedLineBreak) + { + writer.WriteChar(L' '); + } + writer.WriteString(paragraph); + } + }); + paragraphTexts.Clear(); + paragraphTexts.Add(line); + } + } + + void GuiDocumentCommonInterface::UserInput_FormatDocument(Ptr model) + { + if (!model) return; + if (config.pasteAsPlainText) + { + if (model->paragraphs.Count() > 0) + { + RunRangeMap runRanges; + vint lastParagraphIndex = model->paragraphs.Count() - 1; + document_editor::GetRunRange(model->paragraphs[lastParagraphIndex].Obj(), runRanges); + + TextPos begin(0, 0); + TextPos end(lastParagraphIndex, runRanges[model->paragraphs[lastParagraphIndex].Obj()].end); + model->ConvertToPlainText(begin, end); + + for (auto paragraph : model->paragraphs) + { + paragraph->alignment.Reset(); + } + } + + if (baselineDocument) + { + CopyFrom(model->styles, baselineDocument->styles); + } + else + { + model->styles.Clear(); + } + } + + if (model->paragraphs.Count() == 0) + { + return; + } + + if (config.paragraphMode != GuiDocumentParagraphMode::Paragraph) + { + List> containers; + for (auto paragraph : model->paragraphs) + { + containers.Add(paragraph); + } + + for (vint i = 0; i < containers.Count(); i++) + { + auto container = containers[i]; + for (auto run : container->runs) + { + if (auto subContainer = run.Cast()) + { + containers.Add(subContainer); + } + else if (auto textRun = run.Cast()) + { + textRun->text = stream::GenerateToStream([&](stream::StreamWriter& writer) + { + for (vint j = 0; j < textRun->text.Length(); j++) + { + if (textRun->text[j] == L'\n') + { + if (config.spaceForFlattenedLineBreak) + { + writer.WriteChar(L' '); + } + } + else if (textRun->text[j] != L'\r') + { + writer.WriteChar(textRun->text[j]); + } + } + }); + } + } + } + } + + if (config.paragraphMode == GuiDocumentParagraphMode::Singleline) + { + auto firstParagraph = model->paragraphs[0]; + for(auto paragraph:From(model->paragraphs).Skip(1)) + { + if (config.spaceForFlattenedLineBreak) + { + auto textRun = Ptr(new DocumentTextRun); + textRun->text = WString::Unmanaged(L" "); + firstParagraph->runs.Add(textRun); + } + CopyFrom(firstParagraph->runs, paragraph->runs, true); + } + model->paragraphs.Clear(); + model->paragraphs.Add(firstParagraph); + } + } + + GuiDocumentCommonInterface::GuiDocumentCommonInterface(const GuiDocumentConfig& _config) + : config(_config) { undoRedoProcessor = Ptr(new GuiDocumentUndoRedoProcessor); - internalShortcutKeyManager = Ptr(new GuiShortcutKeyManager); AddShortcutCommand(VKEY::KEY_Z, Func(this, &GuiDocumentCommonInterface::Undo)); AddShortcutCommand(VKEY::KEY_Y, Func(this, &GuiDocumentCommonInterface::Redo)); @@ -18696,6 +18938,8 @@ GuiDocumentCommonInterface void GuiDocumentCommonInterface::SetDocument(Ptr value) { + value = value ? value->CopyDocument() : nullptr; + UserInput_FormatDocument(value); SetActiveHyperlink(0); ClearUndoRedo(); NotifyModificationSaved(); @@ -18792,7 +19036,7 @@ GuiDocumentCommonInterface { documentElement->EditRun(begin, end, model, copy); paragraphCount=model->paragraphs.Count(); - lastParagraphLength=paragraphCount==0?0:model->paragraphs[paragraphCount-1]->GetText(false).Length(); + lastParagraphLength=paragraphCount==0?0:model->paragraphs[paragraphCount-1]->GetTextForCaret().Length(); }); } @@ -18960,26 +19204,26 @@ GuiDocumentCommonInterface return activeHyperlinks ? activeHyperlinks->hyperlinks[0]->reference : L""; } - GuiDocumentCommonInterface::EditMode GuiDocumentCommonInterface::GetEditMode() + GuiDocumentEditMode GuiDocumentCommonInterface::GetEditMode() { return editMode; } - void GuiDocumentCommonInterface::SetEditMode(EditMode value) + void GuiDocumentCommonInterface::SetEditMode(GuiDocumentEditMode value) { - if(activeHyperlinks) + if (activeHyperlinks) { SetActiveHyperlink(nullptr); } - editMode=value; - if(editMode==ViewOnly) + editMode = value; + if (editMode == GuiDocumentEditMode::ViewOnly) { UpdateCursor(nullptr); } else { - INativeCursor* cursor=GetCurrentController()->ResourceService()->GetSystemCursor(INativeCursor::IBeam); + INativeCursor* cursor = GetCurrentController()->ResourceService()->GetSystemCursor(INativeCursor::IBeam); UpdateCursor(cursor); } } @@ -18992,7 +19236,7 @@ GuiDocumentCommonInterface Ptr lastParagraph=documentElement->GetDocument()->paragraphs[lastIndex]; TextPos begin(0, 0); - TextPos end(lastIndex, lastParagraph->GetText(false).Length()); + TextPos end(lastIndex, lastParagraph->GetTextForCaret().Length()); SetCaret(begin, end); } @@ -19008,54 +19252,25 @@ GuiDocumentCommonInterface } Ptr model=documentElement->GetDocument()->CopyDocument(begin, end, false); - return model->GetText(true); + return UserInput_ConvertDocumentToText(model); } void GuiDocumentCommonInterface::SetSelectionText(const WString& value) { - List paragraphs; + List paragraphTexts; + UserInput_FormatText(value, paragraphTexts); + + TextPos begin = documentElement->GetCaretBegin(); + TextPos end = documentElement->GetCaretEnd(); + if (begin > end) { - stream::StringReader reader(value); - WString paragraph; - bool empty=true; - - while(!reader.IsEnd()) - { - WString line=reader.ReadLine(); - if(empty) - { - paragraph+=line; - empty=false; - } - else if(line!=L"") - { - paragraph+=L"\r\n"+line; - } - else - { - paragraphs.Add(paragraph); - paragraph=L""; - empty=true; - } - } - - if(!empty) - { - paragraphs.Add(paragraph); - } - } - - TextPos begin=documentElement->GetCaretBegin(); - TextPos end=documentElement->GetCaretEnd(); - if(begin>end) - { - TextPos temp=begin; - begin=end; - end=temp; + TextPos temp = begin; + begin = end; + end = temp; } Array text; - CopyFrom(text, paragraphs); + CopyFrom(text, paragraphTexts); EditText(begin, end, documentElement->IsCaretEndPreferFrontSide(), text); } @@ -19076,6 +19291,8 @@ GuiDocumentCommonInterface void GuiDocumentCommonInterface::SetSelectionModel(Ptr value) { + value = value ? value->CopyDocument() : nullptr; + UserInput_FormatDocument(value); TextPos begin=documentElement->GetCaretBegin(); TextPos end=documentElement->GetCaretEnd(); if(begin>end) @@ -19092,7 +19309,7 @@ GuiDocumentCommonInterface bool GuiDocumentCommonInterface::CanCut() { - return editMode==Editable && documentElement->GetCaretBegin()!=documentElement->GetCaretEnd(); + return editMode == GuiDocumentEditMode::Editable && documentElement->GetCaretBegin() != documentElement->GetCaretEnd(); } bool GuiDocumentCommonInterface::CanCopy() @@ -19102,10 +19319,17 @@ GuiDocumentCommonInterface bool GuiDocumentCommonInterface::CanPaste() { - if (editMode == Editable) + if (editMode == GuiDocumentEditMode::Editable) { auto reader = GetCurrentController()->ClipboardService()->ReadClipboard(); - return reader->ContainsText() || reader->ContainsDocument() || reader->ContainsImage(); + if (config.pasteAsPlainText) + { + return reader->ContainsText(); + } + else + { + return reader->ContainsText() || reader->ContainsDocument() || reader->ContainsImage(); + } } return false; } @@ -19115,7 +19339,11 @@ GuiDocumentCommonInterface if (!CanCut())return false; auto writer = GetCurrentController()->ClipboardService()->WriteClipboard(); auto model = GetSelectionModel(); - writer->SetDocument(model); + writer->SetText(UserInput_ConvertDocumentToText(model)); + if (!config.pasteAsPlainText) + { + writer->SetDocument(model); + } writer->Submit(); SetSelectionText(L""); return true; @@ -19126,7 +19354,11 @@ GuiDocumentCommonInterface if (!CanCopy()) return false; auto writer = GetCurrentController()->ClipboardService()->WriteClipboard(); auto model = GetSelectionModel(); - writer->SetDocument(model); + writer->SetText(UserInput_ConvertDocumentToText(model)); + if (!config.pasteAsPlainText) + { + writer->SetDocument(model); + } writer->Submit(); return true; } @@ -19135,7 +19367,7 @@ GuiDocumentCommonInterface { if (!CanPaste()) return false; auto reader = GetCurrentController()->ClipboardService()->ReadClipboard(); - if (reader->ContainsDocument()) + if (reader->ContainsDocument() && !config.pasteAsPlainText) { if (auto document = reader->GetDocument()) { @@ -19148,7 +19380,7 @@ GuiDocumentCommonInterface SetSelectionText(reader->GetText()); return true; } - if (reader->ContainsImage()) + if (reader->ContainsImage() && !config.pasteAsPlainText) { if (auto image = reader->GetImage()) { @@ -19164,12 +19396,12 @@ GuiDocumentCommonInterface bool GuiDocumentCommonInterface::CanUndo() { - return editMode==Editable && undoRedoProcessor->CanUndo(); + return editMode == GuiDocumentEditMode::Editable && undoRedoProcessor->CanUndo(); } bool GuiDocumentCommonInterface::CanRedo() { - return editMode==Editable && undoRedoProcessor->CanRedo(); + return editMode == GuiDocumentEditMode::Editable && undoRedoProcessor->CanRedo(); } void GuiDocumentCommonInterface::ClearUndoRedo() @@ -19246,31 +19478,57 @@ GuiDocumentViewer void GuiDocumentViewer::EnsureRectVisible(Rect bounds) { Rect viewBounds=GetViewBounds(); - vint offset=0; - if(bounds.y1viewBounds.y2) - { - offset=bounds.y2-viewBounds.y2; - } + vint offset = 0; + if (bounds.x1 < viewBounds.x1) + { + offset = bounds.x1 - viewBounds.x1; + } + else if (bounds.x2 > viewBounds.x2) + { + offset = bounds.x2 - viewBounds.x2; + } - if (auto scroll = GetVerticalScroll()) + if (auto scroll = GetHorizontalScroll()) + { + scroll->SetPosition(viewBounds.x1 + offset); + } + } { - scroll->SetPosition(viewBounds.y1 + offset); + vint offset = 0; + if (bounds.y1 < viewBounds.y1) + { + offset = bounds.y1 - viewBounds.y1; + } + else if (bounds.y2 > viewBounds.y2) + { + offset = bounds.y2 - viewBounds.y2; + } + + if (auto scroll = GetVerticalScroll()) + { + scroll->SetPosition(viewBounds.y1 + offset); + } } } - GuiDocumentViewer::GuiDocumentViewer(theme::ThemeName themeName) - :GuiScrollContainer(themeName) + GuiDocumentConfig GuiDocumentViewer::FixConfig(const GuiDocumentConfig& config) + { + auto result = config; + result.autoExpand = false; + return config; + } + + GuiDocumentViewer::GuiDocumentViewer(theme::ThemeName themeName, const GuiDocumentConfig& _config) + : GuiScrollContainer(themeName) + , GuiDocumentCommonInterface(FixConfig(GuiDocumentConfig::OverrideConfig(GuiDocumentConfig::GetDocumentViewerDefaultConfig(), _config))) { SetAcceptTabInput(true); SetFocusableComposition(boundsComposition); InstallDocumentViewer(this, containerComposition->GetParent(), containerComposition, boundsComposition, focusableComposition); - SetExtendToFullWidth(true); - SetHorizontalAlwaysVisible(false); + SetExtendToFullWidth(config.wrapLine); + SetHorizontalAlwaysVisible(!config.wrapLine); } GuiDocumentViewer::~GuiDocumentViewer() @@ -19279,7 +19537,7 @@ GuiDocumentViewer const WString& GuiDocumentViewer::GetText() { - text=documentElement->GetDocument()->GetText(true); + text = UserInput_ConvertDocumentToText(documentElement->GetDocument()); return text; } @@ -19314,12 +19572,107 @@ GuiDocumentLabel OnFontChanged(); } - GuiDocumentLabel::GuiDocumentLabel(theme::ThemeName themeName) - :GuiControl(themeName) + Point GuiDocumentLabel::GetDocumentViewPosition() + { + // when autoExpand is true, the document does not move in containerComposition + // when autoExpand is not false, the document does not move in documentContainer + return{ 0,0 }; + } + + void GuiDocumentLabel::EnsureRectVisible(Rect bounds) + { + if (!scrollingContainer) return; + vint documentWidth = documentContainer->GetCachedBounds().Width(); + vint scrollingWidth = scrollingContainer->GetCachedBounds().Width(); + if (documentWidth <= scrollingWidth) + { + documentContainer->SetExpectedBounds({}); + return; + } + + vint x1 = -documentContainer->GetCachedBounds().x1; + vint x2 = x1 + scrollingWidth; + vint offset = 0; + + if (bounds.x1 < x1) + { + offset = bounds.x1 - x1; + } + else if (bounds.x2 > x2) + { + offset = bounds.x2 - x2; + } + + auto expectedBounds = documentContainer->GetExpectedBounds(); + expectedBounds.x1 -= offset; + expectedBounds.x2 -= offset; + + if (expectedBounds.x1 > 0) + { + expectedBounds.x1 = 0; + } + else if (expectedBounds.x1 + documentWidth < scrollingWidth) + { + expectedBounds.x1 = scrollingWidth - documentWidth; + } + expectedBounds.x2 = expectedBounds.x1; + documentContainer->SetExpectedBounds(expectedBounds); + documentContainer->ForceCalculateSizeImmediately(); + } + + void GuiDocumentLabel::scrollingContainer_CachedBoundsChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments) + { + Rect bounds = scrollingContainer->GetCachedBounds(); + vint x1 = documentContainer->GetCachedBounds().x1; + vint offset = -x1 - bounds.x1; + bounds.x1 += offset; + bounds.x2 += offset; + EnsureRectVisible(bounds); + } + + void GuiDocumentLabel::documentContainer_CachedMinSizeChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments) + { + scrollingContainer->SetPreferredMinSize({ 0,documentContainer->GetCachedMinSize().y }); + } + + GuiDocumentConfig GuiDocumentLabel::FixConfig(const GuiDocumentConfig& config) + { + auto result = config; + if (!result.autoExpand.Value()) + { + if (result.wrapLine.Value() || result.paragraphMode.Value() != GuiDocumentParagraphMode::Singleline) + { + result.autoExpand = true; + } + } + return result; + } + + GuiDocumentLabel::GuiDocumentLabel(theme::ThemeName themeName, const GuiDocumentConfig& _config) + : GuiControl(themeName) + , GuiDocumentCommonInterface(FixConfig(GuiDocumentConfig::OverrideConfig(GuiDocumentConfig::GetDocumentLabelDefaultConfig(), _config))) { SetAcceptTabInput(true); SetFocusableComposition(boundsComposition); - InstallDocumentViewer(this, containerComposition, containerComposition, boundsComposition, focusableComposition); + + if (config.autoExpand) + { + InstallDocumentViewer(this, containerComposition, containerComposition, boundsComposition, focusableComposition); + } + else + { + scrollingContainer = new GuiBoundsComposition(); + scrollingContainer->SetAlignmentToParent(Margin(0, 0, 0, 0)); + containerComposition->AddChild(scrollingContainer); + + documentContainer = new GuiBoundsComposition(); + documentContainer->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren); + scrollingContainer->AddChild(documentContainer); + + scrollingContainer->CachedBoundsChanged.AttachMethod(this, &GuiDocumentLabel::scrollingContainer_CachedBoundsChanged); + documentContainer->CachedBoundsChanged.AttachMethod(this, &GuiDocumentLabel::documentContainer_CachedMinSizeChanged); + InstallDocumentViewer(this, containerComposition, documentContainer, boundsComposition, focusableComposition); + } } GuiDocumentLabel::~GuiDocumentLabel() @@ -19328,7 +19681,7 @@ GuiDocumentLabel const WString& GuiDocumentLabel::GetText() { - text=documentElement->GetDocument()->GetText(true); + text = UserInput_ConvertDocumentToText(documentElement->GetDocument()); return text; } @@ -32633,38 +32986,42 @@ GuiDocumentElement::GuiDocumentElementRenderer Ptr GuiDocumentElement::GuiDocumentElementRenderer::EnsureAndGetCache(vint paragraphIndex, bool createParagraph) { - if(paragraphIndex<0 || paragraphIndex>=paragraphCaches.Count()) return 0; - Ptr paragraph=element->document->paragraphs[paragraphIndex]; - Ptr cache=paragraphCaches[paragraphIndex]; - if(!cache) + if (paragraphIndex < 0 || paragraphIndex >= paragraphCaches.Count()) return 0; + Ptr paragraph = element->document->paragraphs[paragraphIndex]; + Ptr cache = paragraphCaches[paragraphIndex]; + if (!cache) { - cache=Ptr(new ParagraphCache); - cache->fullText=paragraph->GetText(false); - paragraphCaches[paragraphIndex]=cache; + cache = Ptr(new ParagraphCache); + cache->fullText = paragraph->GetTextForCaret(); + paragraphCaches[paragraphIndex] = cache; } - if(createParagraph) + if (createParagraph) { - if(!cache->graphicsParagraph) + if (!cache->graphicsParagraph) { - cache->graphicsParagraph=layoutProvider->CreateParagraph(cache->fullText, renderTarget, this); + cache->graphicsParagraph = layoutProvider->CreateParagraph(cache->fullText, renderTarget, this); cache->graphicsParagraph->SetParagraphAlignment(paragraph->alignment ? paragraph->alignment.Value() : Alignment::Left); + cache->graphicsParagraph->SetWrapLine(element->wrapLine); SetPropertiesVisitor::SetProperty(element->document.Obj(), this, cache, paragraph, cache->selectionBegin, cache->selectionEnd); } - if(cache->graphicsParagraph->GetMaxWidth()!=lastMaxWidth) + if (cache->graphicsParagraph->GetMaxWidth() != lastMaxWidth) { cache->graphicsParagraph->SetMaxWidth(lastMaxWidth); } - vint paragraphHeight=paragraphHeights[paragraphIndex]; - vint height=cache->graphicsParagraph->GetHeight(); - if(paragraphHeight!=height) + Size cachedSize = paragraphSizes[paragraphIndex]; + Size realSize = cache->graphicsParagraph->GetSize(); + if (cachedTotalSize.x < realSize.x) { - cachedTotalHeight+=height-paragraphHeight; - paragraphHeight=height; - paragraphHeights[paragraphIndex]=paragraphHeight; - minSize=Size(0, cachedTotalHeight); + cachedTotalSize.x = realSize.x; } + if (cachedSize.y != realSize.y) + { + cachedTotalSize.y += realSize.y - cachedSize.y; + } + paragraphSizes[paragraphIndex] = realSize; + minSize = cachedTotalSize; } return cache; @@ -32672,18 +33029,18 @@ GuiDocumentElement::GuiDocumentElementRenderer bool GuiDocumentElement::GuiDocumentElementRenderer::GetParagraphIndexFromPoint(Point point, vint& top, vint& index) { - vint y=0; + vint y = 0; // TODO: (enumerable) foreach - for(vint i=0;iGetLayoutProvider()) ,lastCaret(-1, -1) ,lastCaretFrontSide(false) @@ -32711,47 +33067,52 @@ GuiDocumentElement::GuiDocumentElementRenderer element->callback->OnStartRender(); } renderTarget->PushClipper(bounds, element); - if(!renderTarget->IsClipperCoverWholeTarget()) + if (!renderTarget->IsClipperCoverWholeTarget()) { - vint maxWidth=bounds.Width(); - Rect clipper=renderTarget->GetClipper(); - vint cx=bounds.Left(); - vint cy=bounds.Top(); - vint y1=clipper.Top()-bounds.Top(); - vint y2=y1+clipper.Height(); - vint y=0; + vint maxWidth = bounds.Width(); + Rect clipper = renderTarget->GetClipper(); + vint cx = bounds.Left(); + vint cy = bounds.Top(); + vint y1 = clipper.Top() - bounds.Top(); + vint y2 = y1 + clipper.Height(); + vint y = 0; - lastMaxWidth=maxWidth; + lastMaxWidth = maxWidth; // TODO: (enumerable) foreach - for(vint i=0;i element->document->paragraphs.Count()) { - vint paragraphHeight=paragraphHeights[i]; - if(y+paragraphHeight<=y1) + paragraphCount = element->document->paragraphs.Count(); + } + for (vint i = 0; i < paragraphCount; i++) + { + Size cachedSize = paragraphSizes[i]; + if (y + cachedSize.y <= y1) { - y+=paragraphHeight+paragraphDistance; + y += cachedSize.y + paragraphDistance; continue; } - else if(y>=y2) + else if (y >= y2) { break; } else { - Ptr paragraph=element->document->paragraphs[i]; - Ptr cache=paragraphCaches[i]; - bool created=cache && cache->graphicsParagraph; - cache=EnsureAndGetCache(i, true); - if(!created && i==lastCaret.row && element->caretVisible) + Ptr paragraph = element->document->paragraphs[i]; + Ptr cache = paragraphCaches[i]; + bool created = cache && cache->graphicsParagraph; + cache = EnsureAndGetCache(i, true); + if (!created && i == lastCaret.row && element->caretVisible) { cache->graphicsParagraph->OpenCaret(lastCaret.column, lastCaretColor, lastCaretFrontSide); } - paragraphHeight=cache->graphicsParagraph->GetHeight(); + cachedSize = cache->graphicsParagraph->GetSize(); renderingParagraph = i; renderingParagraphOffset = Point(cx - bounds.x1, cy + y - bounds.y1); - cache->graphicsParagraph->Render(Rect(Point(cx, cy+y), Size(maxWidth, paragraphHeight))); + cache->graphicsParagraph->Render(Rect(Point(cx, cy + y), Size(maxWidth, cachedSize.y))); renderingParagraph = -1; bool resized = false; @@ -32772,7 +33133,7 @@ GuiDocumentElement::GuiDocumentElementRenderer } } - y+=paragraphHeight+paragraphDistance; + y += cachedSize.y + paragraphDistance; } } renderTarget->PopClipper(element); @@ -32784,38 +33145,36 @@ GuiDocumentElement::GuiDocumentElementRenderer void GuiDocumentElement::GuiDocumentElementRenderer::OnElementStateChanged() { + cachedTotalSize = { 1,1 }; if (element->document && element->document->paragraphs.Count() > 0) { - vint defaultSize = GetCurrentController()->ResourceService()->GetDefaultFont().size; - paragraphDistance = defaultSize; - vint defaultHeight = defaultSize; + vint defaultHeight = GetCurrentController()->ResourceService()->GetDefaultFont().size; + paragraphDistance = element->paragraphPadding ? defaultHeight : 0; paragraphCaches.Resize(element->document->paragraphs.Count()); - paragraphHeights.Resize(element->document->paragraphs.Count()); + paragraphSizes.Resize(element->document->paragraphs.Count()); for (vint i = 0; i < paragraphCaches.Count(); i++) { paragraphCaches[i] = 0; } - for (vint i = 0; i < paragraphHeights.Count(); i++) + for (vint i = 0; i < paragraphSizes.Count(); i++) { - paragraphHeights[i] = defaultHeight; + paragraphSizes[i] = { 0,defaultHeight }; } - cachedTotalHeight = paragraphHeights.Count() * (defaultHeight + paragraphDistance); - if (paragraphHeights.Count()>0) + cachedTotalSize.y = paragraphSizes.Count() * (defaultHeight + paragraphDistance); + if (paragraphSizes.Count()>0) { - cachedTotalHeight -= paragraphDistance; + cachedTotalSize.y -= paragraphDistance; } - minSize = Size(0, cachedTotalHeight); } else { paragraphCaches.Resize(0); - paragraphHeights.Resize(0); - cachedTotalHeight = 0; - minSize = Size(0, 0); + paragraphSizes.Resize(0); } + minSize = cachedTotalSize; nameCallbackIdMap.Clear(); freeCallbackIds.Clear(); @@ -32834,24 +33193,24 @@ GuiDocumentElement::GuiDocumentElementRenderer CopyFrom(oldCaches, paragraphCaches); paragraphCaches.Resize(paragraphCount); - ParagraphHeightArray oldHeights; - CopyFrom(oldHeights, paragraphHeights); - paragraphHeights.Resize(paragraphCount); + ParagraphSizeArray oldSizes; + CopyFrom(oldSizes, paragraphSizes); + paragraphSizes.Resize(paragraphCount); vint defaultHeight = GetCurrentController()->ResourceService()->GetDefaultFont().size; - cachedTotalHeight = 0; + cachedTotalSize = { 1,1 }; for (vint i = 0; i < paragraphCount; i++) { if (i < index) { paragraphCaches[i] = oldCaches[i]; - paragraphHeights[i] = oldHeights[i]; + paragraphSizes[i] = oldSizes[i]; } else if (i < index + newCount) { paragraphCaches[i] = 0; - paragraphHeights[i] = defaultHeight; + paragraphSizes[i] = { 0,defaultHeight }; if (!updatedText && i < index + oldCount) { auto cache = oldCaches[i]; @@ -32860,19 +33219,25 @@ GuiDocumentElement::GuiDocumentElementRenderer cache->graphicsParagraph = 0; } paragraphCaches[i] = cache; - paragraphHeights[i] = oldHeights[i]; + paragraphSizes[i] = oldSizes[i]; } } else { paragraphCaches[i] = oldCaches[i - (newCount - oldCount)]; - paragraphHeights[i] = oldHeights[i - (newCount - oldCount)]; + paragraphSizes[i] = oldSizes[i - (newCount - oldCount)]; } - cachedTotalHeight += paragraphHeights[i] + paragraphDistance; + + auto cachedSize = paragraphSizes[i]; + if (cachedTotalSize.x < cachedSize.x) + { + cachedTotalSize.x = cachedSize.x; + } + cachedTotalSize.y += cachedSize.y + paragraphDistance; } if (paragraphCount > 0) { - cachedTotalHeight -= paragraphDistance; + cachedTotalSize.y -= paragraphDistance; } if (updatedText) @@ -32893,6 +33258,7 @@ GuiDocumentElement::GuiDocumentElementRenderer } } } + minSize = cachedTotalSize; } } @@ -32999,45 +33365,45 @@ GuiDocumentElement::GuiDocumentElementRenderer TextPos GuiDocumentElement::GuiDocumentElementRenderer::CalculateCaret(TextPos comparingCaret, IGuiGraphicsParagraph::CaretRelativePosition position, bool& preferFrontSide) { if (!renderTarget) return comparingCaret; - Ptr cache=EnsureAndGetCache(comparingCaret.row, true); - if(cache) + Ptr cache = EnsureAndGetCache(comparingCaret.row, true); + if (cache) { - switch(position) + switch (position) { case IGuiGraphicsParagraph::CaretFirst: { - preferFrontSide=false; - vint caret=cache->graphicsParagraph->GetCaret(0, IGuiGraphicsParagraph::CaretFirst, preferFrontSide); + preferFrontSide = false; + vint caret = cache->graphicsParagraph->GetCaret(0, IGuiGraphicsParagraph::CaretFirst, preferFrontSide); return TextPos(comparingCaret.row, caret); } case IGuiGraphicsParagraph::CaretLast: { - preferFrontSide=true; - vint caret=cache->graphicsParagraph->GetCaret(0, IGuiGraphicsParagraph::CaretLast, preferFrontSide); + preferFrontSide = true; + vint caret = cache->graphicsParagraph->GetCaret(0, IGuiGraphicsParagraph::CaretLast, preferFrontSide); return TextPos(comparingCaret.row, caret); } case IGuiGraphicsParagraph::CaretLineFirst: { - preferFrontSide=false; - vint caret=cache->graphicsParagraph->GetCaret(comparingCaret.column, IGuiGraphicsParagraph::CaretLineFirst, preferFrontSide); + preferFrontSide = false; + vint caret = cache->graphicsParagraph->GetCaret(comparingCaret.column, IGuiGraphicsParagraph::CaretLineFirst, preferFrontSide); return TextPos(comparingCaret.row, caret); } case IGuiGraphicsParagraph::CaretLineLast: { - preferFrontSide=true; - vint caret=cache->graphicsParagraph->GetCaret(comparingCaret.column, IGuiGraphicsParagraph::CaretLineLast, preferFrontSide); + preferFrontSide = true; + vint caret = cache->graphicsParagraph->GetCaret(comparingCaret.column, IGuiGraphicsParagraph::CaretLineLast, preferFrontSide); return TextPos(comparingCaret.row, caret); } case IGuiGraphicsParagraph::CaretMoveUp: { - vint caret=cache->graphicsParagraph->GetCaret(comparingCaret.column, IGuiGraphicsParagraph::CaretMoveUp, preferFrontSide); - if(caret==comparingCaret.column && comparingCaret.row>0) + vint caret = cache->graphicsParagraph->GetCaret(comparingCaret.column, IGuiGraphicsParagraph::CaretMoveUp, preferFrontSide); + if (caret == comparingCaret.column && comparingCaret.row > 0) { - Rect caretBounds=cache->graphicsParagraph->GetCaretBounds(comparingCaret.column, preferFrontSide); - Ptr anotherCache=EnsureAndGetCache(comparingCaret.row-1, true); - vint height=anotherCache->graphicsParagraph->GetHeight(); - caret=anotherCache->graphicsParagraph->GetCaretFromPoint(Point(caretBounds.x1, height)); - return TextPos(comparingCaret.row-1, caret); + Rect caretBounds = cache->graphicsParagraph->GetCaretBounds(comparingCaret.column, preferFrontSide); + Ptr anotherCache = EnsureAndGetCache(comparingCaret.row - 1, true); + vint height = anotherCache->graphicsParagraph->GetSize().y; + caret = anotherCache->graphicsParagraph->GetCaretFromPoint(Point(caretBounds.x1, height)); + return TextPos(comparingCaret.row - 1, caret); } else { @@ -33046,13 +33412,13 @@ GuiDocumentElement::GuiDocumentElementRenderer } case IGuiGraphicsParagraph::CaretMoveDown: { - vint caret=cache->graphicsParagraph->GetCaret(comparingCaret.column, IGuiGraphicsParagraph::CaretMoveDown, preferFrontSide); - if(caret==comparingCaret.column && comparingCaret.rowgraphicsParagraph->GetCaret(comparingCaret.column, IGuiGraphicsParagraph::CaretMoveDown, preferFrontSide); + if (caret == comparingCaret.column && comparingCaret.row < paragraphCaches.Count() - 1) { - Rect caretBounds=cache->graphicsParagraph->GetCaretBounds(comparingCaret.column, preferFrontSide); - Ptr anotherCache=EnsureAndGetCache(comparingCaret.row+1, true); - caret=anotherCache->graphicsParagraph->GetCaretFromPoint(Point(caretBounds.x1, 0)); - return TextPos(comparingCaret.row+1, caret); + Rect caretBounds = cache->graphicsParagraph->GetCaretBounds(comparingCaret.column, preferFrontSide); + Ptr anotherCache = EnsureAndGetCache(comparingCaret.row + 1, true); + caret = anotherCache->graphicsParagraph->GetCaretFromPoint(Point(caretBounds.x1, 0)); + return TextPos(comparingCaret.row + 1, caret); } else { @@ -33061,13 +33427,13 @@ GuiDocumentElement::GuiDocumentElementRenderer } case IGuiGraphicsParagraph::CaretMoveLeft: { - preferFrontSide=false; - vint caret=cache->graphicsParagraph->GetCaret(comparingCaret.column, IGuiGraphicsParagraph::CaretMoveLeft, preferFrontSide); - if(caret==comparingCaret.column && comparingCaret.row>0) + preferFrontSide = false; + vint caret = cache->graphicsParagraph->GetCaret(comparingCaret.column, IGuiGraphicsParagraph::CaretMoveLeft, preferFrontSide); + if (caret == comparingCaret.column && comparingCaret.row > 0) { - Ptr anotherCache=EnsureAndGetCache(comparingCaret.row-1, true); - caret=anotherCache->graphicsParagraph->GetCaret(0, IGuiGraphicsParagraph::CaretLast, preferFrontSide); - return TextPos(comparingCaret.row-1, caret); + Ptr anotherCache = EnsureAndGetCache(comparingCaret.row - 1, true); + caret = anotherCache->graphicsParagraph->GetCaret(0, IGuiGraphicsParagraph::CaretLast, preferFrontSide); + return TextPos(comparingCaret.row - 1, caret); } else { @@ -33076,13 +33442,13 @@ GuiDocumentElement::GuiDocumentElementRenderer } case IGuiGraphicsParagraph::CaretMoveRight: { - preferFrontSide=true; - vint caret=cache->graphicsParagraph->GetCaret(comparingCaret.column, IGuiGraphicsParagraph::CaretMoveRight, preferFrontSide); - if(caret==comparingCaret.column && comparingCaret.rowgraphicsParagraph->GetCaret(comparingCaret.column, IGuiGraphicsParagraph::CaretMoveRight, preferFrontSide); + if (caret == comparingCaret.column && comparingCaret.row < paragraphCaches.Count() - 1) { - Ptr anotherCache=EnsureAndGetCache(comparingCaret.row+1, true); - caret=anotherCache->graphicsParagraph->GetCaret(0, IGuiGraphicsParagraph::CaretFirst, preferFrontSide); - return TextPos(comparingCaret.row+1, caret); + Ptr anotherCache = EnsureAndGetCache(comparingCaret.row + 1, true); + caret = anotherCache->graphicsParagraph->GetCaret(0, IGuiGraphicsParagraph::CaretFirst, preferFrontSide); + return TextPos(comparingCaret.row + 1, caret); } else { @@ -33112,21 +33478,21 @@ GuiDocumentElement::GuiDocumentElementRenderer Rect GuiDocumentElement::GuiDocumentElementRenderer::GetCaretBounds(TextPos caret, bool frontSide) { if (!renderTarget) return Rect(); - Ptr cache=EnsureAndGetCache(caret.row, true); - if(cache) + Ptr cache = EnsureAndGetCache(caret.row, true); + if (cache) { - Rect bounds=cache->graphicsParagraph->GetCaretBounds(caret.column, frontSide); - if(bounds!=Rect()) + Rect bounds = cache->graphicsParagraph->GetCaretBounds(caret.column, frontSide); + if (bounds != Rect()) { - vint y=0; - for(vint i=0;i paragraph=paragraphs[i]; - paragraph->GetText(writer, skipNonTextContent); + paragraph->ConvertToText(writer, forCaret); if(i GetImageFromSingleImageDocument(Ptr model) + { + if (model->paragraphs.Count() != 1) return nullptr; + Ptr container = model->paragraphs[0]; + while (container) + { + if (container->runs.Count() != 1) return nullptr; + if (auto imageRun = container->runs[0].Cast()) + { + return imageRun->image; + } + else + { + container = container->runs[0].Cast(); + } + } + return nullptr; + } + Ptr LoadDocumentFromClipboardStream(stream::IStream& clipboardStream) { auto tempResource = Ptr(new GuiResource); @@ -48167,7 +48594,7 @@ Calculate range informations for each run object } /*********************************************************************** -.\RESOURCES\GUIDOCUMENTEDITOR_LOCALEHYPERLINK.CPP +.\RESOURCES\GUIDOCUMENTEDITOR_LOCATEHYPERLINK.CPP ***********************************************************************/ namespace vl @@ -48320,7 +48747,7 @@ Get the hyperlink run that contains the specified position } /*********************************************************************** -.\RESOURCES\GUIDOCUMENTEDITOR_LOCALESTYLE.CPP +.\RESOURCES\GUIDOCUMENTEDITOR_LOCATESTYLE.CPP ***********************************************************************/ namespace vl @@ -48587,6 +49014,28 @@ ClearStyleVisitor : Remove all styles that intersect with the specified range RemoveContainer(run); } }; + + class ConvertToPlainTextVisitor : public ClearStyleVisitor + { + public: + ConvertToPlainTextVisitor(RunRangeMap& _runRanges, vint _start, vint _end) + :ClearStyleVisitor(_runRanges, _start, _end) + { + } + + void Visit(DocumentHyperlinkRun* run)override + { + RemoveContainer(run); + } + + void Visit(DocumentImageRun* run)override + { + } + + void Visit(DocumentEmbeddedObjectRun* run)override + { + } + }; } using namespace document_operation_visitors; @@ -48609,6 +49058,12 @@ ClearStyleVisitor : Remove all styles that intersect with the specified range ClearStyleVisitor visitor(runRanges, start, end); run->Accept(&visitor); } + + void ConvertToPlainText(DocumentParagraphRun* run, RunRangeMap& runRanges, vint start, vint end) + { + ConvertToPlainTextVisitor visitor(runRanges, start, end); + run->Accept(&visitor); + } } } } @@ -49201,44 +49656,47 @@ DocumentModel::EditRangeOperations Ptr DocumentModel::CopyDocument(TextPos begin, TextPos end, bool deepCopy) { - // check caret range - RunRangeMap runRanges; - if(!CheckEditRange(begin, end, runRanges)) return nullptr; - - // get ranges - for(vint i=begin.row+1;i 0) { - newDocument->paragraphs.Add(CopyRunRecursively(paragraphs[begin.row].Obj(), runRanges, begin.column, end.column, deepCopy).Cast()); - } - else - { - for(vint i=begin.row;i<=end.row;i++) + // check caret range + RunRangeMap runRanges; + if (!CheckEditRange(begin, end, runRanges)) return nullptr; + + // get ranges + for (vint i = begin.row + 1; i < end.row; i++) { - Ptr paragraph=paragraphs[i]; - RunRange range=runRanges[paragraph.Obj()]; - if(i==begin.row) + GetRunRange(paragraphs[i].Obj(), runRanges); + } + + // copy paragraphs + if (begin.row == end.row) + { + newDocument->paragraphs.Add(CopyRunRecursively(paragraphs[begin.row].Obj(), runRanges, begin.column, end.column, deepCopy).Cast()); + } + else + { + for (vint i = begin.row; i <= end.row; i++) { - newDocument->paragraphs.Add(CopyRunRecursively(paragraph.Obj(), runRanges, begin.column, range.end, deepCopy).Cast()); - } - else if(i==end.row) - { - newDocument->paragraphs.Add(CopyRunRecursively(paragraph.Obj(), runRanges, range.start, end.column, deepCopy).Cast()); - } - else if(deepCopy) - { - newDocument->paragraphs.Add(CopyRunRecursively(paragraph.Obj(), runRanges, range.start, range.end, deepCopy).Cast()); - } - else - { - newDocument->paragraphs.Add(paragraph); + Ptr paragraph = paragraphs[i]; + RunRange range = runRanges[paragraph.Obj()]; + if (i == begin.row) + { + newDocument->paragraphs.Add(CopyRunRecursively(paragraph.Obj(), runRanges, begin.column, range.end, deepCopy).Cast()); + } + else if (i == end.row) + { + newDocument->paragraphs.Add(CopyRunRecursively(paragraph.Obj(), runRanges, range.start, end.column, deepCopy).Cast()); + } + else if (deepCopy) + { + newDocument->paragraphs.Add(CopyRunRecursively(paragraph.Obj(), runRanges, range.start, range.end, deepCopy).Cast()); + } + else + { + newDocument->paragraphs.Add(paragraph); + } } } } @@ -49270,7 +49728,7 @@ DocumentModel::EditRangeOperations newDocument->styles.Add(styleName, style); } - if(!styleNames.Contains(style->parentStyleName)) + if(!styleNames.Contains(style->parentStyleName) && style->parentStyleName != WString::Empty) { styleNames.Add(style->parentStyleName); } @@ -49282,14 +49740,21 @@ DocumentModel::EditRangeOperations Ptr DocumentModel::CopyDocument() { - // determine run ranges - RunRangeMap runRanges; - vint lastParagraphIndex = paragraphs.Count() - 1; - GetRunRange(paragraphs[lastParagraphIndex].Obj(), runRanges); - - TextPos begin(0, 0); - TextPos end(lastParagraphIndex, runRanges[paragraphs[lastParagraphIndex].Obj()].end); - return CopyDocument(begin, end, true); + if (paragraphs.Count() == 0) + { + return CopyDocument({ 0,0 }, { 0,0 }, true); + } + else + { + // determine run ranges + RunRangeMap runRanges; + vint lastParagraphIndex = paragraphs.Count() - 1; + GetRunRange(paragraphs[lastParagraphIndex].Obj(), runRanges); + + TextPos begin(0, 0); + TextPos end(lastParagraphIndex, runRanges[paragraphs[lastParagraphIndex].Obj()].end); + return CopyDocument(begin, end, true); + } } bool DocumentModel::CutParagraph(TextPos position) @@ -49715,7 +50180,19 @@ DocumentModel::ClearStyle } /*********************************************************************** -DocumentModel::ClearStyle +DocumentModel::ConvertToPlainText +***********************************************************************/ + + bool DocumentModel::ConvertToPlainText(TextPos begin, TextPos end) + { + return EditContainer(begin, end, [=](DocumentParagraphRun* paragraph, RunRangeMap& runRanges, vint start, vint end) + { + document_editor::ConvertToPlainText(paragraph, runRanges, start, end); + }); + } + +/*********************************************************************** +DocumentModel::Summarize ***********************************************************************/ Ptr DocumentModel::SummarizeStyle(TextPos begin, TextPos end) @@ -50460,6 +50937,7 @@ document_operation_visitors::SerializeRunVisitor if (tag) { writer.Element(tag); + last++; } else if (c == 0) { @@ -53644,7 +54122,13 @@ FakeClipboardWriter void SetDocument(Ptr value) override { - if (reader) reader->document = value; + if (reader) + { + if (!reader->text) reader->text = value->GetTextForReading(WString::Unmanaged(L"\r\n\r\n"));; + if (!reader->image) reader->image = GetImageFromSingleImageDocument(value); + reader->document = value; + ModifyDocumentForClipboard(reader->document); + } } void SetImage(Ptr value) override diff --git a/Import/GacUI.h b/Import/GacUI.h index 7d6282df..d88536d7 100644 --- a/Import/GacUI.h +++ b/Import/GacUI.h @@ -2058,9 +2058,9 @@ Layout Engine /// Returns true if this operation succeeded. virtual bool ResetInlineObject(vint start, vint length)=0; - /// Get the layouted height of the text. The result depends on rich styled text and the two important properties that can be set using and . - /// The layouted height. - virtual vint GetHeight()=0; + /// Get the layouted size of the text. The result depends on rich styled text and the two important properties that can be set using and . + /// The layouted size. + virtual Size GetSize()=0; /// Make the caret visible so that it will be rendered in the paragraph. /// Returns true if this operation succeeded. /// The caret. @@ -12037,8 +12037,10 @@ Rich Content Document (run) void Accept(IVisitor* visitor)override{visitor->Visit(this);} - WString GetText(bool skipNonTextContent); - void GetText(stream::TextWriter& writer, bool skipNonTextContent); + WString GetTextForCaret(); + WString GetTextForReading(); + WString ConvertToText(bool forCaret); + void ConvertToText(stream::TextWriter& writer, bool forCaret); }; /*********************************************************************** @@ -12117,8 +12119,10 @@ Rich Content Document (model) ResolvedStyle GetStyle(Ptr sp, const ResolvedStyle& context); ResolvedStyle GetStyle(const WString& styleName, const ResolvedStyle& context); - WString GetText(bool skipNonTextContent); - void GetText(stream::TextWriter& writer, bool skipNonTextContent); + WString GetTextForCaret(); + WString GetTextForReading(const WString& paragraphDelimiter); + WString ConvertToText(bool forCaret, const WString& paragraphDelimiter); + void ConvertToText(stream::TextWriter& writer, bool forCaret, const WString& paragraphDelimiter); bool CheckEditRange(TextPos begin, TextPos end, RunRangeMap& relatedRanges); Ptr CopyDocument(TextPos begin, TextPos end, bool deepCopy); @@ -12139,6 +12143,7 @@ Rich Content Document (model) bool RemoveStyleName(TextPos begin, TextPos end); bool RenameStyle(const WString& oldStyleName, const WString& newStyleName); bool ClearStyle(TextPos begin, TextPos end); + bool ConvertToPlainText(TextPos begin, TextPos end); Ptr SummarizeStyle(TextPos begin, TextPos end); Nullable SummarizeStyleName(TextPos begin, TextPos end); Nullable SummarizeParagraphAlignment(TextPos begin, TextPos end); @@ -12905,7 +12910,7 @@ Rich Content Document (element) }; typedef collections::Array> ParagraphCacheArray; - typedef collections::Array ParagraphHeightArray; + typedef collections::Array ParagraphSizeArray; private: @@ -12913,10 +12918,10 @@ Rich Content Document (element) protected: vint paragraphDistance; vint lastMaxWidth; - vint cachedTotalHeight; + Size cachedTotalSize; IGuiGraphicsLayoutProvider* layoutProvider; ParagraphCacheArray paragraphCaches; - ParagraphHeightArray paragraphHeights; + ParagraphSizeArray paragraphSizes; TextPos lastCaret; Color lastCaretColor; @@ -12953,6 +12958,8 @@ Rich Content Document (element) protected: Ptr document; ICallback* callback = nullptr; + bool paragraphPadding = true; + bool wrapLine = true; TextPos caretBegin; TextPos caretEnd; bool caretVisible; @@ -12976,6 +12983,19 @@ Rich Content Document (element) /// Set the document. When a document is set to this element, modifying the document without invoking will lead to undefined behavior. /// The document. void SetDocument(Ptr value); + /// Get whether paddings are inserted between paragraphs. + /// Returns true if paddings are inserted between paragraphs. + bool GetParagraphPadding(); + /// Set whether paddings are inserted between paragraphs + /// Set to true so that paddings are inserted between paragraphs. + void SetParagraphPadding(bool value); + /// Get line wrapping. + /// Return true if there is automatic line wrapping. + bool GetWrapLine(); + /// Set line wrapping. + /// Set to true so that there is automatic line wrapping. + void SetWrapLine(bool value); + /// /// Get the begin position of the selection area. /// @@ -16661,6 +16681,84 @@ namespace vl namespace controls { +/*********************************************************************** +GuiDocumentConfig +***********************************************************************/ + + /// Represents the edit mode. + enum class GuiDocumentEditMode + { + /// View the rich text only. + ViewOnly, + /// The rich text is selectable. + Selectable, + /// The rich text is editable. + Editable, + }; + + /// Represents the paragraph mode. + enum class GuiDocumentParagraphMode + { + /// Only one paragraph is allowed, only one line in a paragraph is allowed. + Singleline, + /// Only one line in a paragraph is allowed. + Multiline, + /// No constraint. + Paragraph, + }; + + /// Control of editing and rendering behavior. + struct GuiDocumentConfig + { + /// For GuiDocumentLabel only. When it is true, or when wrapLine is true, or when paragraphMode is not Singleline, the control automatically expands to display all content. + Nullable autoExpand; + /// When it is true, the defaut copy paste behavior ignores RTF format. + Nullable pasteAsPlainText; + /// When it is true, document automatically wraps if the width of the control is not enough. + Nullable wrapLine; + /// Control the paragraph and line behavior + Nullable paragraphMode; + /// Insert the space of a default font between paragraphs. + Nullable paragraphPadding; + /// When it is true: + /// double CrLf will be used between paragraphs, when the document converts to plain text. + /// only double CrLf will be recognized as paragraph breaks, when the document converts from plain text. + /// + Nullable doubleLineBreaksBetweenParagraph; + /// When it is true, when removing a line break from a document due to paragraphMode, insert a extra space. + Nullable spaceForFlattenedLineBreak; + + auto operator<=>(const GuiDocumentConfig&) const = default; + + static GuiDocumentConfig GetDocumentLabelDefaultConfig(); + static GuiDocumentConfig GetDocumentViewerDefaultConfig(); + static GuiDocumentConfig GetSinglelineTextBoxDefaultConfig(); + static GuiDocumentConfig GetMultilineTextBoxDefaultConfig(); + static GuiDocumentConfig OverrideConfig(const GuiDocumentConfig& toOverride, const GuiDocumentConfig& newConfig); + }; + + struct GuiDocumentConfigEvaluated + { + bool autoExpand; + bool pasteAsPlainText; + bool wrapLine; + GuiDocumentParagraphMode paragraphMode; + bool paragraphPadding; + bool doubleLineBreaksBetweenParagraph; + bool spaceForFlattenedLineBreak; + + GuiDocumentConfigEvaluated(const GuiDocumentConfig& config) + : autoExpand(config.autoExpand.Value()) + , pasteAsPlainText(config.pasteAsPlainText.Value()) + , wrapLine(config.wrapLine.Value()) + , paragraphMode(config.paragraphMode.Value()) + , paragraphPadding(config.paragraphPadding.Value()) + , doubleLineBreaksBetweenParagraph(config.doubleLineBreaksBetweenParagraph.Value()) + , spaceForFlattenedLineBreak(config.spaceForFlattenedLineBreak.Value()) + { + } + }; + /*********************************************************************** GuiDocumentCommonInterface ***********************************************************************/ @@ -16695,18 +16793,8 @@ GuiDocumentCommonInterface , public Description { typedef collections::Dictionary> DocumentItemMap; - public: - /// Represents the edit mode. - enum EditMode - { - /// View the rich text only. - ViewOnly, - /// The rich text is selectable. - Selectable, - /// The rich text is editable. - Editable, - }; protected: + GuiDocumentConfigEvaluated config; Ptr baselineDocument; DocumentItemMap documentItems; GuiControl* documentControl = nullptr; @@ -16721,7 +16809,7 @@ GuiDocumentCommonInterface Ptr activeHyperlinks; bool dragging = false; - EditMode editMode = EditMode::ViewOnly; + GuiDocumentEditMode editMode = GuiDocumentEditMode::ViewOnly; Ptr undoRedoProcessor; Ptr internalShortcutKeyManager; @@ -16771,8 +16859,15 @@ GuiDocumentCommonInterface void OnStartRender()override; void OnFinishRender()override; Size OnRenderEmbeddedObject(const WString& name, const Rect& location)override; + + protected: + + WString UserInput_ConvertDocumentToText(Ptr model); + void UserInput_FormatText(const WString& text, collections::List& paragraphTexts); + void UserInput_FormatDocument(Ptr model); + public: - GuiDocumentCommonInterface(); + GuiDocumentCommonInterface(const GuiDocumentConfig& _config); ~GuiDocumentCommonInterface(); /// Active hyperlink changed event. @@ -16931,10 +17026,10 @@ GuiDocumentCommonInterface WString GetActiveHyperlinkReference(); /// Get the edit mode of this control. /// The edit mode. - EditMode GetEditMode(); + GuiDocumentEditMode GetEditMode(); /// Set the edit mode of this control. /// The edit mode. - void SetEditMode(EditMode value); + void SetEditMode(GuiDocumentEditMode value); //================ selection operations @@ -17010,10 +17105,13 @@ GuiDocumentViewer void UpdateDisplayFont()override; Point GetDocumentViewPosition()override; void EnsureRectVisible(Rect bounds)override; + + static GuiDocumentConfig FixConfig(const GuiDocumentConfig& config); public: /// Create a control with a specified style provider. /// The theme name for retriving a default control template. - GuiDocumentViewer(theme::ThemeName themeName); + /// (Optional): configuration of document editing and rendering behavior. + GuiDocumentViewer(theme::ThemeName themeName, const GuiDocumentConfig& _config = {}); ~GuiDocumentViewer(); const WString& GetText()override; @@ -17029,12 +17127,21 @@ GuiDocumentViewer { GUI_SPECIFY_CONTROL_TEMPLATE_TYPE(DocumentLabelTemplate, GuiControl) protected: + compositions::GuiBoundsComposition* scrollingContainer = nullptr; + compositions::GuiBoundsComposition* documentContainer = nullptr; void UpdateDisplayFont()override; + Point GetDocumentViewPosition()override; + void EnsureRectVisible(Rect bounds)override; + void scrollingContainer_CachedBoundsChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); + void documentContainer_CachedMinSizeChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); + + static GuiDocumentConfig FixConfig(const GuiDocumentConfig& config); public: /// Create a control with a specified default theme. /// The theme name for retriving a default control template. - GuiDocumentLabel(theme::ThemeName themeName); + /// (Optional): configuration of document editing and rendering behavior. + GuiDocumentLabel(theme::ThemeName themeName, const GuiDocumentConfig& _config = {}); ~GuiDocumentLabel(); const WString& GetText()override; @@ -25016,6 +25123,7 @@ namespace vl namespace presentation { extern void ModifyDocumentForClipboard(Ptr model); + extern Ptr GetImageFromSingleImageDocument(Ptr model); extern Ptr LoadDocumentFromClipboardStream(stream::IStream& clipboardStream); extern void SaveDocumentToClipboardStream(Ptr model, stream::IStream& clipboardStream); @@ -25071,6 +25179,7 @@ namespace vl extern void RemoveHyperlink(DocumentParagraphRun* run, RunRangeMap& runRanges, vint start, vint end); extern void RemoveStyleName(DocumentParagraphRun* run, RunRangeMap& runRanges, vint start, vint end); extern void ClearStyle(DocumentParagraphRun* run, RunRangeMap& runRanges, vint start, vint end); + extern void ConvertToPlainText(DocumentParagraphRun* run, RunRangeMap& runRanges, vint start, vint end); extern Ptr SummarizeStyle(DocumentParagraphRun* run, RunRangeMap& runRanges, DocumentModel* model, vint start, vint end); extern Nullable SummarizeStyleName(DocumentParagraphRun* run, RunRangeMap& runRanges, DocumentModel* model, vint start, vint end); extern void AggregateStyle(Ptr& dst, Ptr src); diff --git a/Import/GacUICompiler.cpp b/Import/GacUICompiler.cpp index 12645083..64ad744c 100644 --- a/Import/GacUICompiler.cpp +++ b/Import/GacUICompiler.cpp @@ -8142,6 +8142,18 @@ GuiDocumentInstanceLoaderBase private: using TypeInfo = typename TBaseType::TypeInfo; + protected: + GlobalStringKey _Behavior; + + void AddAdditionalArguments(types::ResolvingResult& resolvingResult, const TypeInfo& typeInfo, GlobalStringKey variableName, IGuiInstanceLoader::ArgumentMap& arguments, GuiResourceError::List& errors, Ptr createControl)override + { + vint indexBehavior = arguments.Keys().IndexOf(_Behavior); + if (indexBehavior != -1) + { + createControl->arguments.Add(arguments.GetByIndex(indexBehavior)[0].expression); + } + } + public: using PropertyInfo = IGuiInstanceLoader::PropertyInfo; using ArgumentMap = IGuiInstanceLoader::ArgumentMap; @@ -8149,6 +8161,7 @@ GuiDocumentInstanceLoaderBase GuiDocumentInstanceLoaderBase(const WString& _typeName, theme::ThemeName themeName) :TBaseType(_typeName, themeName) { + _Behavior = GlobalStringKey::Get(L"Behavior"); } void GetPropertyNames(GuiResourcePrecompileContext& precompileContext, const TypeInfo& typeInfo, collections::List& propertyNames)override @@ -8163,6 +8176,12 @@ GuiDocumentInstanceLoaderBase { return GuiInstancePropertyInfo::CollectionWithParent(TypeInfoRetriver>::CreateTypeInfo()); } + else if(propertyInfo.propertyName == _Behavior && this->CanCreate(propertyInfo.typeInfo)) + { + auto info = GuiInstancePropertyInfo::Assign(TypeInfoRetriver::CreateTypeInfo()); + info->usage = GuiInstancePropertyInfo::ConstructorArgument; + return info; + } return TBaseType::GetPropertyType(precompileContext, propertyInfo); } @@ -8240,6 +8259,11 @@ Initialization manager->SetLoader(Ptr(new GuiDocumentItemInstanceLoader)); manager->SetLoader(Ptr(new GuiDocumentViewerInstanceLoader)); manager->SetLoader(Ptr(new GuiDocumentLabelInstanceLoader)); + manager->CreateVirtualType(GlobalStringKey::Get(description::TypeInfo::content.typeName), + Ptr(new GuiDocumentInstanceLoaderBase>( + L"presentation::controls::GuiDocumentTextBox", + theme::ThemeName::DocumentTextBox + ))); } } } @@ -8763,6 +8787,7 @@ GuiInstanceLoader_Document.cpp default: GuiControl*, GuiGraphicsComposition* GuiDocumentViewer, GuiDocumentLable default: Ptr + ctor: Behavior(GuiDocumentConfig) GuiInstanceLoader_List.cpp GuiComboBox ctor: ListControl(GuiListControl*) @@ -9118,7 +9143,6 @@ GuiPredefinedInstanceLoadersPlugin ADD_VIRTUAL_CONTROL (RadioButton, GuiSelectableButton, RadioButton ); ADD_VIRTUAL_CONTROL (HScroll, GuiScroll, HScroll ); ADD_VIRTUAL_CONTROL (VScroll, GuiScroll, VScroll ); - ADD_VIRTUAL_CONTROL (DocumentTextBox, GuiDocumentLabel, DocumentTextBox ); ADD_VIRTUAL_CONTROL_F (HTracker, GuiScroll, HTracker, InitializeTrackerProgressBar); ADD_VIRTUAL_CONTROL_F (VTracker, GuiScroll, VTracker, InitializeTrackerProgressBar); ADD_VIRTUAL_CONTROL_F (ProgressBar, GuiScroll, ProgressBar, InitializeTrackerProgressBar); @@ -11266,7 +11290,7 @@ GenerateRemoteProtocolHeaderFile auto type = stream::GenerateToStream([&](stream::TextWriter& writer) { GuiRpPrintTypeVisitor visitor(symbols, config, writer); - eventDecl->request->type->Accept(&visitor); + eventDecl->request->type->Accept(&visitor); }); if (!eventTypes.Contains(type)) { diff --git a/Import/GacUIReflection.cpp b/Import/GacUIReflection.cpp index 2b577744..172d0866 100644 --- a/Import/GacUIReflection.cpp +++ b/Import/GacUIReflection.cpp @@ -832,7 +832,9 @@ Type Declaration CLASS_MEMBER_FIELD(alignment) - CLASS_MEMBER_METHOD_OVERLOAD(GetText, {L"skipNonTextContent"}, WString(DocumentParagraphRun::*)(bool)) + CLASS_MEMBER_METHOD(GetTextForCaret, NO_PARAMETER) + CLASS_MEMBER_METHOD(GetTextForReading, NO_PARAMETER) + CLASS_MEMBER_METHOD_OVERLOAD(ConvertToText, {L"forCaret"}, WString(DocumentParagraphRun::*)(bool)) END_CLASS_MEMBER(DocumentParagraphRun) BEGIN_CLASS_MEMBER(DocumentStyle) @@ -849,7 +851,9 @@ Type Declaration CLASS_MEMBER_FIELD(paragraphs) CLASS_MEMBER_FIELD(styles) - CLASS_MEMBER_METHOD_OVERLOAD(GetText, {L"skipNonTextContent"}, WString(DocumentModel::*)(bool)) + CLASS_MEMBER_METHOD(GetTextForCaret, NO_PARAMETER) + CLASS_MEMBER_METHOD(GetTextForReading, { L"paragraphDelimiter" }) + CLASS_MEMBER_METHOD_OVERLOAD(ConvertToText, { L"forCaret" _ L"paragraphDelimiter"}, WString(DocumentModel::*)(bool, const WString&)) CLASS_MEMBER_STATIC_METHOD(LoadFromXml, {L"resource" _ L"xml" _ L"workingDirectory" _ L"errors"}) CLASS_MEMBER_METHOD_OVERLOAD(SaveToXml, NO_PARAMETER, Ptr(DocumentModel::*)()) END_CLASS_MEMBER(DocumentModel) @@ -2182,6 +2186,28 @@ Type Declaration (Extra) CLASS_MEMBER_PROPERTY_READONLY_FAST(Groups) END_CLASS_MEMBER(GroupedDataSource) + BEGIN_ENUM_ITEM(GuiDocumentEditMode) + ENUM_CLASS_ITEM(ViewOnly) + ENUM_CLASS_ITEM(Selectable) + ENUM_CLASS_ITEM(Editable) + END_ENUM_ITEM(GuiDocumentEditMode) + + BEGIN_ENUM_ITEM(GuiDocumentParagraphMode) + ENUM_CLASS_ITEM(Singleline) + ENUM_CLASS_ITEM(Multiline) + ENUM_CLASS_ITEM(Paragraph) + END_ENUM_ITEM(GuiDocumentParagraphMode) + + BEGIN_STRUCT_MEMBER(GuiDocumentConfig) + STRUCT_MEMBER(autoExpand) + STRUCT_MEMBER(pasteAsPlainText) + STRUCT_MEMBER(wrapLine) + STRUCT_MEMBER(paragraphMode) + STRUCT_MEMBER(paragraphPadding) + STRUCT_MEMBER(doubleLineBreaksBetweenParagraph) + STRUCT_MEMBER(spaceForFlattenedLineBreak) + END_STRUCT_MEMBER(GuiDocumentConfig) + BEGIN_CLASS_MEMBER(GuiDocumentItem) CLASS_MEMBER_CONSTRUCTOR(Ptr(const WString&), { L"name" }) @@ -2189,13 +2215,6 @@ Type Declaration (Extra) CLASS_MEMBER_PROPERTY_READONLY_FAST(Name) END_CLASS_MEMBER(GuiDocumentItem) - BEGIN_ENUM_ITEM(GuiDocumentCommonInterface::EditMode) - ENUM_ITEM_NAMESPACE(GuiDocumentCommonInterface) - ENUM_NAMESPACE_ITEM(ViewOnly) - ENUM_NAMESPACE_ITEM(Selectable) - ENUM_NAMESPACE_ITEM(Editable) - END_ENUM_ITEM(GuiDocumentCommonInterface::EditMode) - BEGIN_INTERFACE_MEMBER(IDataGridContext) CLASS_MEMBER_BASE(IDescriptable) @@ -2993,12 +3012,14 @@ Type Declaration (Class) CLASS_MEMBER_BASE(GuiScrollContainer) CLASS_MEMBER_BASE(GuiDocumentCommonInterface) CONTROL_CONSTRUCTOR_CONTROLT_TEMPLATE(GuiDocumentViewer) + CONTROL_CONSTRUCTOR_CONTROLT_TEMPLATE_2(GuiDocumentViewer, const GuiDocumentConfig&, config) END_CLASS_MEMBER(GuiDocumentViewer) BEGIN_CLASS_MEMBER(GuiDocumentLabel) CLASS_MEMBER_BASE(GuiControl) CLASS_MEMBER_BASE(GuiDocumentCommonInterface) CONTROL_CONSTRUCTOR_CONTROLT_TEMPLATE(GuiDocumentLabel) + CONTROL_CONSTRUCTOR_CONTROLT_TEMPLATE_2(GuiDocumentLabel, const GuiDocumentConfig&, config) END_CLASS_MEMBER(GuiDocumentLabel) BEGIN_CLASS_MEMBER(GuiTextBoxCommonInterface) @@ -3427,6 +3448,8 @@ Type Declaration (Class) ELEMENT_CONSTRUCTOR(GuiDocumentElement) CLASS_MEMBER_PROPERTY_FAST(Document) + CLASS_MEMBER_PROPERTY_FAST(ParagraphPadding) + CLASS_MEMBER_PROPERTY_FAST(WrapLine) CLASS_MEMBER_PROPERTY_READONLY_FAST(CaretBegin) CLASS_MEMBER_PROPERTY_READONLY_FAST(CaretEnd) CLASS_MEMBER_PROPERTY_FAST(CaretVisible) diff --git a/Import/GacUIReflection.h b/Import/GacUIReflection.h index f6b959df..c0e2af41 100644 --- a/Import/GacUIReflection.h +++ b/Import/GacUIReflection.h @@ -416,9 +416,11 @@ Type List (Controls) F(presentation::controls::GalleryPos)\ F(presentation::controls::list::GalleryGroup)\ F(presentation::controls::list::GroupedDataSource)\ + F(presentation::controls::GuiDocumentEditMode)\ + F(presentation::controls::GuiDocumentParagraphMode)\ + F(presentation::controls::GuiDocumentConfig)\ F(presentation::controls::GuiDocumentItem)\ F(presentation::controls::GuiDocumentCommonInterface)\ - F(presentation::controls::GuiDocumentCommonInterface::EditMode)\ F(presentation::controls::GuiTextBoxCommonInterface)\ F(presentation::controls::list::IDataGridContext)\ F(presentation::controls::list::IDataVisualizerFactory)\ diff --git a/Tools/Reflection32.bin b/Tools/Reflection32.bin index d4e73e5b..5a1202e3 100644 Binary files a/Tools/Reflection32.bin and b/Tools/Reflection32.bin differ diff --git a/Tools/Reflection64.bin b/Tools/Reflection64.bin index 6712148a..4f994a1b 100644 Binary files a/Tools/Reflection64.bin and b/Tools/Reflection64.bin differ diff --git a/Tutorial/GacUI_ControlTemplate/BlackSkin/UI/FullControlTest/DocumentEditorBase.xml b/Tutorial/GacUI_ControlTemplate/BlackSkin/UI/FullControlTest/DocumentEditorBase.xml index f1df7d54..c820c57f 100644 --- a/Tutorial/GacUI_ControlTemplate/BlackSkin/UI/FullControlTest/DocumentEditorBase.xml +++ b/Tutorial/GacUI_ControlTemplate/BlackSkin/UI/FullControlTest/DocumentEditorBase.xml @@ -7,11 +7,11 @@ prop EditModeCommand : ToolstripCommand* = null {const} @cpp:Private - func SetEditMode(editMode: DocumentCommonInterface::EditMode) : void + func SetEditMode(editMode: GuiDocumentEditMode) : void { var command = - editMode == DocumentCommonInterface::EditMode::ViewOnly ? commandViewOnly : - editMode == DocumentCommonInterface::EditMode::Selectable ? commandSelectable : + editMode == GuiDocumentEditMode::ViewOnly ? commandViewOnly : + editMode == GuiDocumentEditMode::Selectable ? commandSelectable : commandEditable; document.EditMode = editMode; @@ -49,7 +49,7 @@ @cpp:Private func HasEditableCursor() : bool { - return document.EditMode == DocumentCommonInterface::EditMode::Editable; + return document.EditMode == GuiDocumentEditMode::Editable; } @cpp:Private diff --git a/Tutorial/GacUI_ControlTemplate/BlackSkin/UI/FullControlTest/Source/DemoPartialClasses.cpp b/Tutorial/GacUI_ControlTemplate/BlackSkin/UI/FullControlTest/Source/DemoPartialClasses.cpp index 15f55533..7c9c5efe 100644 --- a/Tutorial/GacUI_ControlTemplate/BlackSkin/UI/FullControlTest/Source/DemoPartialClasses.cpp +++ b/Tutorial/GacUI_ControlTemplate/BlackSkin/UI/FullControlTest/Source/DemoPartialClasses.cpp @@ -2096,7 +2096,7 @@ Closures void __vwsnf192_Demo_demo_DocumentEditorBaseConstructor___vwsn_demo_DocumentEditorBase_Initialize_::operator()(::vl::presentation::compositions::GuiGraphicsComposition* sender, ::vl::presentation::compositions::GuiEventArgs* arguments) const { - ::vl::__vwsn::This(__vwsnthis_0->self)->SetEditMode(::vl::presentation::controls::GuiDocumentCommonInterface::EditMode::ViewOnly); + ::vl::__vwsn::This(__vwsnthis_0->self)->SetEditMode(::vl::presentation::controls::GuiDocumentEditMode::ViewOnly); } //------------------------------------------------------------------- @@ -2108,7 +2108,7 @@ Closures void __vwsnf193_Demo_demo_DocumentEditorBaseConstructor___vwsn_demo_DocumentEditorBase_Initialize_::operator()(::vl::presentation::compositions::GuiGraphicsComposition* sender, ::vl::presentation::compositions::GuiEventArgs* arguments) const { - ::vl::__vwsn::This(__vwsnthis_0->self)->SetEditMode(::vl::presentation::controls::GuiDocumentCommonInterface::EditMode::Selectable); + ::vl::__vwsn::This(__vwsnthis_0->self)->SetEditMode(::vl::presentation::controls::GuiDocumentEditMode::Selectable); } //------------------------------------------------------------------- @@ -2120,7 +2120,7 @@ Closures void __vwsnf194_Demo_demo_DocumentEditorBaseConstructor___vwsn_demo_DocumentEditorBase_Initialize_::operator()(::vl::presentation::compositions::GuiGraphicsComposition* sender, ::vl::presentation::compositions::GuiEventArgs* arguments) const { - ::vl::__vwsn::This(__vwsnthis_0->self)->SetEditMode(::vl::presentation::controls::GuiDocumentCommonInterface::EditMode::Editable); + ::vl::__vwsn::This(__vwsnthis_0->self)->SetEditMode(::vl::presentation::controls::GuiDocumentEditMode::Editable); } //------------------------------------------------------------------- @@ -17949,7 +17949,7 @@ Class (::demo::DocumentBoxSubTabPageConstructor) (this->__vwsn_precompile_2 = new ::vl::presentation::controls::GuiDocumentLabel(::vl::presentation::theme::ThemeName::DocumentTextBox)); } { - ::vl::__vwsn::This(this->__vwsn_precompile_2)->SetEditMode(::vl::presentation::controls::GuiDocumentCommonInterface::EditMode::Editable); + ::vl::__vwsn::This(this->__vwsn_precompile_2)->SetEditMode(::vl::presentation::controls::GuiDocumentEditMode::Editable); } { ::vl::__vwsn::This(this->__vwsn_precompile_2)->SetAlt(::vl::WString::Unmanaged(L"T")); @@ -17975,7 +17975,7 @@ Class (::demo::DocumentBoxSubTabPageConstructor) (this->__vwsn_precompile_5 = new ::vl::presentation::controls::GuiDocumentViewer(::vl::presentation::theme::ThemeName::DocumentViewer)); } { - ::vl::__vwsn::This(this->__vwsn_precompile_5)->SetEditMode(::vl::presentation::controls::GuiDocumentCommonInterface::EditMode::Editable); + ::vl::__vwsn::This(this->__vwsn_precompile_5)->SetEditMode(::vl::presentation::controls::GuiDocumentEditMode::Editable); } { ::vl::__vwsn::This(this->__vwsn_precompile_5)->SetAlt(::vl::WString::Unmanaged(L"V")); @@ -17998,7 +17998,7 @@ Class (::demo::DocumentBoxSubTabPageConstructor) (this->__vwsn_precompile_8 = new ::vl::presentation::controls::GuiDocumentLabel(::vl::presentation::theme::ThemeName::DocumentLabel)); } { - ::vl::__vwsn::This(this->__vwsn_precompile_8)->SetEditMode(::vl::presentation::controls::GuiDocumentCommonInterface::EditMode::Editable); + ::vl::__vwsn::This(this->__vwsn_precompile_8)->SetEditMode(::vl::presentation::controls::GuiDocumentEditMode::Editable); } { ::vl::__vwsn::This(this->__vwsn_precompile_8)->SetAlt(::vl::WString::Unmanaged(L"L")); @@ -18221,7 +18221,7 @@ Class (::demo::DocumentEditorBaseConstructor) ::vl::__vwsn::This(__vwsn_this_)->SetNamedObject(::vl::WString::Unmanaged(L"document"), ::vl::__vwsn::Box(this->document)); } { - ::vl::__vwsn::This(this->document)->SetEditMode(::vl::presentation::controls::GuiDocumentCommonInterface::EditMode::Editable); + ::vl::__vwsn::This(this->document)->SetEditMode(::vl::presentation::controls::GuiDocumentEditMode::Editable); } { ::vl::__vwsn::This(this->document)->SetAlt(::vl::WString::Unmanaged(L"D")); @@ -29585,7 +29585,7 @@ Class (::demo::ResponsiveViewControlConstructor) ::vl::__vwsn::This(__vwsn_this_)->SetNamedObject(::vl::WString::Unmanaged(L"documentBox"), ::vl::__vwsn::Box(this->documentBox)); } { - ::vl::__vwsn::This(this->documentBox)->SetEditMode(::vl::presentation::controls::GuiDocumentCommonInterface::EditMode::Editable); + ::vl::__vwsn::This(this->documentBox)->SetEditMode(::vl::presentation::controls::GuiDocumentEditMode::Editable); } { ::vl::__vwsn::This(this->documentBox)->SetText(::vl::WString::Unmanaged(L"Edit me!")); diff --git a/Tutorial/GacUI_ControlTemplate/BlackSkin/UI/FullControlTest/Source/DocumentEditorBase.cpp b/Tutorial/GacUI_ControlTemplate/BlackSkin/UI/FullControlTest/Source/DocumentEditorBase.cpp index db671ddf..8544278a 100644 --- a/Tutorial/GacUI_ControlTemplate/BlackSkin/UI/FullControlTest/Source/DocumentEditorBase.cpp +++ b/Tutorial/GacUI_ControlTemplate/BlackSkin/UI/FullControlTest/Source/DocumentEditorBase.cpp @@ -51,9 +51,9 @@ namespace demo } } - void DocumentEditorBase::SetEditMode(::vl::presentation::controls::GuiDocumentCommonInterface::EditMode editMode) + void DocumentEditorBase::SetEditMode(::vl::presentation::controls::GuiDocumentEditMode editMode) { - auto command = ((editMode == ::vl::presentation::controls::GuiDocumentCommonInterface::EditMode::ViewOnly) ? this->commandViewOnly : ((editMode == ::vl::presentation::controls::GuiDocumentCommonInterface::EditMode::Selectable) ? this->commandSelectable : this->commandEditable)); + auto command = ((editMode == ::vl::presentation::controls::GuiDocumentEditMode::ViewOnly) ? this->commandViewOnly : ((editMode == ::vl::presentation::controls::GuiDocumentEditMode::Selectable) ? this->commandSelectable : this->commandEditable)); ::vl::__vwsn::This(this->document)->SetEditMode(editMode); ::vl::__vwsn::This(this->commandViewOnly)->SetSelected((command == this->commandViewOnly)); ::vl::__vwsn::This(this->commandSelectable)->SetSelected((command == this->commandSelectable)); @@ -102,7 +102,7 @@ namespace demo bool DocumentEditorBase::HasEditableCursor() { - return (::vl::__vwsn::This(this->document)->GetEditMode() == ::vl::presentation::controls::GuiDocumentCommonInterface::EditMode::Editable); + return (::vl::__vwsn::This(this->document)->GetEditMode() == ::vl::presentation::controls::GuiDocumentEditMode::Editable); } bool DocumentEditorBase::HasEditableHyperlink(bool forEdit) @@ -214,7 +214,7 @@ namespace demo void DocumentEditorBase::__vwsn_instance_ctor_() { - this->SetEditMode(::vl::presentation::controls::GuiDocumentCommonInterface::EditMode::Editable); + this->SetEditMode(::vl::presentation::controls::GuiDocumentEditMode::Editable); } DocumentEditorBase::~DocumentEditorBase() diff --git a/Tutorial/GacUI_ControlTemplate/BlackSkin/UI/FullControlTest/Source/DocumentEditorBase.h b/Tutorial/GacUI_ControlTemplate/BlackSkin/UI/FullControlTest/Source/DocumentEditorBase.h index cc7fa29b..3a16ca11 100644 --- a/Tutorial/GacUI_ControlTemplate/BlackSkin/UI/FullControlTest/Source/DocumentEditorBase.h +++ b/Tutorial/GacUI_ControlTemplate/BlackSkin/UI/FullControlTest/Source/DocumentEditorBase.h @@ -125,7 +125,7 @@ namespace demo void SetEditModeCommand(::vl::presentation::controls::GuiToolstripCommand* __vwsn_value_); ::vl::Event EditModeCommandChanged; private: - void SetEditMode(::vl::presentation::controls::GuiDocumentCommonInterface::EditMode editMode); + void SetEditMode(::vl::presentation::controls::GuiDocumentEditMode editMode); protected: ::vl::presentation::controls::GuiToolstripCommand* SelectAlignmentCommand(); private: diff --git a/Tutorial/GacUI_ControlTemplate/UIRes/BlackSkin.bin b/Tutorial/GacUI_ControlTemplate/UIRes/BlackSkin.bin index 7548d75c..5f723eb4 100644 Binary files a/Tutorial/GacUI_ControlTemplate/UIRes/BlackSkin.bin and b/Tutorial/GacUI_ControlTemplate/UIRes/BlackSkin.bin differ diff --git a/Tutorial/GacUI_Controls/AddressBook/UI/Source/DemoPartialClasses.cpp b/Tutorial/GacUI_Controls/AddressBook/UI/Source/DemoPartialClasses.cpp index 334dfada..ecd99694 100644 --- a/Tutorial/GacUI_Controls/AddressBook/UI/Source/DemoPartialClasses.cpp +++ b/Tutorial/GacUI_Controls/AddressBook/UI/Source/DemoPartialClasses.cpp @@ -2251,7 +2251,7 @@ Class (::demo::NewContactWindowConstructor) ::vl::__vwsn::This(__vwsn_this_)->SetNamedObject(::vl::WString::Unmanaged(L"textBoxName"), ::vl::__vwsn::Box(this->textBoxName)); } { - ::vl::__vwsn::This(this->textBoxName)->SetEditMode(::vl::presentation::controls::GuiDocumentCommonInterface::EditMode::Editable); + ::vl::__vwsn::This(this->textBoxName)->SetEditMode(::vl::presentation::controls::GuiDocumentEditMode::Editable); } (this->__vwsn_precompile_4 = ::vl::__vwsn::This(this->textBoxName)->GetBoundsComposition()); { @@ -2291,7 +2291,7 @@ Class (::demo::NewContactWindowConstructor) ::vl::__vwsn::This(__vwsn_this_)->SetNamedObject(::vl::WString::Unmanaged(L"textBoxPhone"), ::vl::__vwsn::Box(this->textBoxPhone)); } { - ::vl::__vwsn::This(this->textBoxPhone)->SetEditMode(::vl::presentation::controls::GuiDocumentCommonInterface::EditMode::Editable); + ::vl::__vwsn::This(this->textBoxPhone)->SetEditMode(::vl::presentation::controls::GuiDocumentEditMode::Editable); } (this->__vwsn_precompile_8 = ::vl::__vwsn::This(this->textBoxPhone)->GetBoundsComposition()); { @@ -2331,7 +2331,7 @@ Class (::demo::NewContactWindowConstructor) ::vl::__vwsn::This(__vwsn_this_)->SetNamedObject(::vl::WString::Unmanaged(L"textBoxAddress"), ::vl::__vwsn::Box(this->textBoxAddress)); } { - ::vl::__vwsn::This(this->textBoxAddress)->SetEditMode(::vl::presentation::controls::GuiDocumentCommonInterface::EditMode::Editable); + ::vl::__vwsn::This(this->textBoxAddress)->SetEditMode(::vl::presentation::controls::GuiDocumentEditMode::Editable); } (this->__vwsn_precompile_12 = ::vl::__vwsn::This(this->textBoxAddress)->GetBoundsComposition()); { @@ -2591,7 +2591,7 @@ Class (::demo::NewFolderWindowConstructor) ::vl::__vwsn::This(__vwsn_this_)->SetNamedObject(::vl::WString::Unmanaged(L"textBoxName"), ::vl::__vwsn::Box(this->textBoxName)); } { - ::vl::__vwsn::This(this->textBoxName)->SetEditMode(::vl::presentation::controls::GuiDocumentCommonInterface::EditMode::Editable); + ::vl::__vwsn::This(this->textBoxName)->SetEditMode(::vl::presentation::controls::GuiDocumentEditMode::Editable); } (this->__vwsn_precompile_4 = ::vl::__vwsn::This(this->textBoxName)->GetBoundsComposition()); { diff --git a/Tutorial/GacUI_Controls/DocumentEditor/UI/Source/DocumentEditorBase.cpp b/Tutorial/GacUI_Controls/DocumentEditor/UI/Source/DocumentEditorBase.cpp index 1cdaf78a..4f763e3e 100644 --- a/Tutorial/GacUI_Controls/DocumentEditor/UI/Source/DocumentEditorBase.cpp +++ b/Tutorial/GacUI_Controls/DocumentEditor/UI/Source/DocumentEditorBase.cpp @@ -51,9 +51,9 @@ namespace demo } } - void DocumentEditorBase::SetEditMode(::vl::presentation::controls::GuiDocumentCommonInterface::EditMode editMode) + void DocumentEditorBase::SetEditMode(::vl::presentation::controls::GuiDocumentEditMode editMode) { - auto command = ((editMode == ::vl::presentation::controls::GuiDocumentCommonInterface::EditMode::ViewOnly) ? this->commandViewOnly : ((editMode == ::vl::presentation::controls::GuiDocumentCommonInterface::EditMode::Selectable) ? this->commandSelectable : this->commandEditable)); + auto command = ((editMode == ::vl::presentation::controls::GuiDocumentEditMode::ViewOnly) ? this->commandViewOnly : ((editMode == ::vl::presentation::controls::GuiDocumentEditMode::Selectable) ? this->commandSelectable : this->commandEditable)); ::vl::__vwsn::This(this->document)->SetEditMode(editMode); ::vl::__vwsn::This(this->commandViewOnly)->SetSelected((command == this->commandViewOnly)); ::vl::__vwsn::This(this->commandSelectable)->SetSelected((command == this->commandSelectable)); @@ -102,7 +102,7 @@ namespace demo bool DocumentEditorBase::HasEditableCursor() { - return (::vl::__vwsn::This(this->document)->GetEditMode() == ::vl::presentation::controls::GuiDocumentCommonInterface::EditMode::Editable); + return (::vl::__vwsn::This(this->document)->GetEditMode() == ::vl::presentation::controls::GuiDocumentEditMode::Editable); } bool DocumentEditorBase::HasEditableHyperlink(bool forEdit) @@ -235,7 +235,7 @@ namespace demo void DocumentEditorBase::__vwsn_instance_ctor_() { - this->SetEditMode(::vl::presentation::controls::GuiDocumentCommonInterface::EditMode::Editable); + this->SetEditMode(::vl::presentation::controls::GuiDocumentEditMode::Editable); } DocumentEditorBase::~DocumentEditorBase() diff --git a/Tutorial/GacUI_Controls/DocumentEditor/UI/Source/DocumentEditorBase.h b/Tutorial/GacUI_Controls/DocumentEditor/UI/Source/DocumentEditorBase.h index 0d27a04c..79564bdc 100644 --- a/Tutorial/GacUI_Controls/DocumentEditor/UI/Source/DocumentEditorBase.h +++ b/Tutorial/GacUI_Controls/DocumentEditor/UI/Source/DocumentEditorBase.h @@ -125,7 +125,7 @@ namespace demo void SetEditModeCommand(::vl::presentation::controls::GuiToolstripCommand* __vwsn_value_); ::vl::Event EditModeCommandChanged; private: - void SetEditMode(::vl::presentation::controls::GuiDocumentCommonInterface::EditMode editMode); + void SetEditMode(::vl::presentation::controls::GuiDocumentEditMode editMode); protected: ::vl::presentation::controls::GuiToolstripCommand* SelectAlignmentCommand(); private: diff --git a/Tutorial/GacUI_Controls/DocumentEditor/UI/Source/EditorBasePartialClasses.cpp b/Tutorial/GacUI_Controls/DocumentEditor/UI/Source/EditorBasePartialClasses.cpp index 167efb44..1e11aae5 100644 --- a/Tutorial/GacUI_Controls/DocumentEditor/UI/Source/EditorBasePartialClasses.cpp +++ b/Tutorial/GacUI_Controls/DocumentEditor/UI/Source/EditorBasePartialClasses.cpp @@ -726,7 +726,7 @@ Closures void __vwsnf47_EditorBase_demo_DocumentEditorBaseConstructor___vwsn_demo_DocumentEditorBase_Initialize_::operator()(::vl::presentation::compositions::GuiGraphicsComposition* sender, ::vl::presentation::compositions::GuiEventArgs* arguments) const { - ::vl::__vwsn::This(__vwsnthis_0->self)->SetEditMode(::vl::presentation::controls::GuiDocumentCommonInterface::EditMode::ViewOnly); + ::vl::__vwsn::This(__vwsnthis_0->self)->SetEditMode(::vl::presentation::controls::GuiDocumentEditMode::ViewOnly); } //------------------------------------------------------------------- @@ -738,7 +738,7 @@ Closures void __vwsnf48_EditorBase_demo_DocumentEditorBaseConstructor___vwsn_demo_DocumentEditorBase_Initialize_::operator()(::vl::presentation::compositions::GuiGraphicsComposition* sender, ::vl::presentation::compositions::GuiEventArgs* arguments) const { - ::vl::__vwsn::This(__vwsnthis_0->self)->SetEditMode(::vl::presentation::controls::GuiDocumentCommonInterface::EditMode::Selectable); + ::vl::__vwsn::This(__vwsnthis_0->self)->SetEditMode(::vl::presentation::controls::GuiDocumentEditMode::Selectable); } //------------------------------------------------------------------- @@ -750,7 +750,7 @@ Closures void __vwsnf49_EditorBase_demo_DocumentEditorBaseConstructor___vwsn_demo_DocumentEditorBase_Initialize_::operator()(::vl::presentation::compositions::GuiGraphicsComposition* sender, ::vl::presentation::compositions::GuiEventArgs* arguments) const { - ::vl::__vwsn::This(__vwsnthis_0->self)->SetEditMode(::vl::presentation::controls::GuiDocumentCommonInterface::EditMode::Editable); + ::vl::__vwsn::This(__vwsnthis_0->self)->SetEditMode(::vl::presentation::controls::GuiDocumentEditMode::Editable); } //------------------------------------------------------------------- @@ -3030,7 +3030,7 @@ namespace demo ::vl::__vwsn::This(this->document)->SetAlt(::vl::WString::Unmanaged(L"D")); } { - ::vl::__vwsn::This(this->document)->SetEditMode(::vl::presentation::controls::GuiDocumentCommonInterface::EditMode::Editable); + ::vl::__vwsn::This(this->document)->SetEditMode(::vl::presentation::controls::GuiDocumentEditMode::Editable); } (this->__vwsn_precompile_2 = ::vl::__vwsn::This(this->document)->GetBoundsComposition()); { diff --git a/Tutorial/GacUI_Controls/UIRes/TextEditor.bin b/Tutorial/GacUI_Controls/UIRes/TextEditor.bin index b6f11619..f0c35ced 100644 Binary files a/Tutorial/GacUI_Controls/UIRes/TextEditor.bin and b/Tutorial/GacUI_Controls/UIRes/TextEditor.bin differ diff --git a/Tutorial/GacUI_HelloWorlds/UIRes/Xml.bin.x64 b/Tutorial/GacUI_HelloWorlds/UIRes/Xml.bin.x64 index 7ff696b6..c4dddb0a 100644 Binary files a/Tutorial/GacUI_HelloWorlds/UIRes/Xml.bin.x64 and b/Tutorial/GacUI_HelloWorlds/UIRes/Xml.bin.x64 differ diff --git a/Tutorial/GacUI_HelloWorlds/UIRes/Xml.bin.x86 b/Tutorial/GacUI_HelloWorlds/UIRes/Xml.bin.x86 index 282dcfb1..fe2fc985 100644 Binary files a/Tutorial/GacUI_HelloWorlds/UIRes/Xml.bin.x86 and b/Tutorial/GacUI_HelloWorlds/UIRes/Xml.bin.x86 differ diff --git a/Tutorial/GacUI_Layout/Responsive1/UI/Source/DemoPartialClasses.cpp b/Tutorial/GacUI_Layout/Responsive1/UI/Source/DemoPartialClasses.cpp index 13a0bd06..91e72274 100644 --- a/Tutorial/GacUI_Layout/Responsive1/UI/Source/DemoPartialClasses.cpp +++ b/Tutorial/GacUI_Layout/Responsive1/UI/Source/DemoPartialClasses.cpp @@ -2090,7 +2090,7 @@ Class (::demo::ResponsiveViewControlConstructor) ::vl::__vwsn::This(__vwsn_this_)->SetNamedObject(::vl::WString::Unmanaged(L"documentBox"), ::vl::__vwsn::Box(this->documentBox)); } { - ::vl::__vwsn::This(this->documentBox)->SetEditMode(::vl::presentation::controls::GuiDocumentCommonInterface::EditMode::Editable); + ::vl::__vwsn::This(this->documentBox)->SetEditMode(::vl::presentation::controls::GuiDocumentEditMode::Editable); } { ::vl::__vwsn::This(this->documentBox)->SetText(::vl::WString::Unmanaged(L"Edit me!")); diff --git a/Tutorial/GacUI_Layout/RichTextEmbedding/UI/Source/DemoPartialClasses.cpp b/Tutorial/GacUI_Layout/RichTextEmbedding/UI/Source/DemoPartialClasses.cpp index dd4ce013..8488b73d 100644 --- a/Tutorial/GacUI_Layout/RichTextEmbedding/UI/Source/DemoPartialClasses.cpp +++ b/Tutorial/GacUI_Layout/RichTextEmbedding/UI/Source/DemoPartialClasses.cpp @@ -103,7 +103,7 @@ Class (::demo::MainWindowConstructor) ::vl::__vwsn::This(this->__vwsn_precompile_50)->SetAlignmentToParent([&](){ ::vl::presentation::Margin __vwsn_temp__; __vwsn_temp__.left = static_cast<::vl::vint>(5); __vwsn_temp__.top = static_cast<::vl::vint>(5); __vwsn_temp__.right = static_cast<::vl::vint>(5); __vwsn_temp__.bottom = static_cast<::vl::vint>(5); return __vwsn_temp__; }()); } { - ::vl::__vwsn::This(this->documentViewer)->SetEditMode(::vl::presentation::controls::GuiDocumentCommonInterface::EditMode::ViewOnly); + ::vl::__vwsn::This(this->documentViewer)->SetEditMode(::vl::presentation::controls::GuiDocumentEditMode::ViewOnly); } (this->__vwsn_precompile_1 = ::vl::Ptr<::vl::presentation::controls::GuiDocumentItem>(new ::vl::presentation::controls::GuiDocumentItem(::vl::WString::Unmanaged(L"Button")))); { diff --git a/Tutorial/GacUI_Layout/UIRes/RichTextEmbedding.bin b/Tutorial/GacUI_Layout/UIRes/RichTextEmbedding.bin index 7a6ce9fe..3a26cfa1 100644 Binary files a/Tutorial/GacUI_Layout/UIRes/RichTextEmbedding.bin and b/Tutorial/GacUI_Layout/UIRes/RichTextEmbedding.bin differ diff --git a/Tutorial/GacUI_Xml/UIRes/Binding_Uri.bin b/Tutorial/GacUI_Xml/UIRes/Binding_Uri.bin index 057cc162..787a16e6 100644 Binary files a/Tutorial/GacUI_Xml/UIRes/Binding_Uri.bin and b/Tutorial/GacUI_Xml/UIRes/Binding_Uri.bin differ