diff --git a/Import/GacUI.cpp b/Import/GacUI.cpp index b2099226..79839695 100644 --- a/Import/GacUI.cpp +++ b/Import/GacUI.cpp @@ -14951,7 +14951,7 @@ namespace vl return themeTemplates; } - TemplateProperty CreateStyle(ThemeName themeName)override + TemplateProperty CreateStyle(ThemeName themeName)override { switch (themeName) { @@ -17350,7 +17350,7 @@ GuiMultilineTextBox void GuiMultilineTextBox::AfterControlTemplateInstalled_(bool initialize) { auto ct = GetControlTemplateObject(true); - Array colors(1); + Array colors(1); colors[0] = ct->GetTextColor(); textElement->SetColors(colors); textElement->SetCaretColor(ct->GetCaretColor()); @@ -17378,7 +17378,7 @@ GuiMultilineTextBox Size GuiMultilineTextBox::QueryFullSize() { - text::TextLines& lines = textElement->GetLines(); + TextLines& lines = textElement->GetLines(); return Size(lines.GetMaxWidth() + TextMargin * 2, lines.GetMaxHeight() + TextMargin * 2); } @@ -17536,7 +17536,7 @@ GuiSinglelineTextBox void GuiSinglelineTextBox::AfterControlTemplateInstalled_(bool initialize) { auto ct = GetControlTemplateObject(true); - Array colors(1); + Array colors(1); colors[0] = ct->GetTextColor(); textElement->SetColors(colors); textElement->SetCaretColor(ct->GetCaretColor()); @@ -33695,14 +33695,14 @@ namespace vl } } - Ptr LoadDocumentFromClipboardStream(stream::IStream& stream) + Ptr LoadDocumentFromClipboardStream(stream::IStream& clipboardStream) { auto tempResource = MakePtr(); auto tempResourceItem = MakePtr(); tempResource->AddItem(L"Document", tempResourceItem); auto tempResolver = MakePtr(tempResource, L""); - internal::ContextFreeReader reader(stream); + internal::ContextFreeReader reader(clipboardStream); { WString title; vint32_t version = 0; @@ -33741,7 +33741,7 @@ namespace vl return document; } - void SaveDocumentToClipboardStream(Ptr model, stream::IStream& stream) + void SaveDocumentToClipboardStream(Ptr model, stream::IStream& clipboardStream) { CollectImageRunsVisitor visitor; FOREACH(Ptr, paragraph, model->paragraphs) @@ -33749,7 +33749,7 @@ namespace vl paragraph->Accept(&visitor); } - internal::ContextFreeWriter writer(stream); + internal::ContextFreeWriter writer(clipboardStream); { WString title = L"WCF_Document"; vint32_t version = 1; @@ -33781,7 +33781,7 @@ namespace vl imageRun->image->SaveToStream(memoryStream, format); } - writer << (IStream&)memoryStream; + writer << (stream::IStream&)memoryStream; } } } @@ -34058,7 +34058,7 @@ namespace vl ; } - void SaveDocumentToHtmlClipboardStream(Ptr model, stream::IStream& stream) + void SaveDocumentToHtmlClipboardStream(Ptr model, stream::IStream& clipboardStream) { AString header, content, footer; SaveDocumentToHtmlUtf8(model, header, content, footer); @@ -34079,12 +34079,12 @@ namespace vl memcpy(strstr(clipboardHeader, "EndFragment:") - offsetStartString.Length() - 2, offsetStartString.Buffer(), offsetStartString.Length()); memcpy(clipboardHeader + sizeof(clipboardHeader) - 1 - offsetEndString.Length() - 2, offsetEndString.Buffer(), offsetEndString.Length()); - stream.Write(clipboardHeader, sizeof(clipboardHeader) - 1); - if (header.Length() > 0) stream.Write((void*)header.Buffer(), header.Length()); - stream.Write(commentStart, sizeof(commentStart) - 1); - if (content.Length() > 0) stream.Write((void*)content.Buffer(), content.Length()); - stream.Write(commentEnd, sizeof(commentEnd) - 1); - if (footer.Length() > 0) stream.Write((void*)footer.Buffer(), footer.Length()); + clipboardStream.Write(clipboardHeader, sizeof(clipboardHeader) - 1); + if (header.Length() > 0) clipboardStream.Write((void*)header.Buffer(), header.Length()); + clipboardStream.Write(commentStart, sizeof(commentStart) - 1); + if (content.Length() > 0) clipboardStream.Write((void*)content.Buffer(), content.Length()); + clipboardStream.Write(commentEnd, sizeof(commentEnd) - 1); + if (footer.Length() > 0) clipboardStream.Write((void*)footer.Buffer(), footer.Length()); } #undef HTML_LINE @@ -34321,11 +34321,11 @@ namespace vl rtf = (const char*)rtfStream.GetInternalBuffer(); } - void SaveDocumentToRtfStream(Ptr model, stream::IStream& stream) + void SaveDocumentToRtfStream(Ptr model, stream::IStream& rtfStream) { AString rtf; SaveDocumentToRtf(model, rtf); - stream.Write((void*)rtf.Buffer(), rtf.Length()); + rtfStream.Write((void*)rtf.Buffer(), rtf.Length()); } } } @@ -38252,7 +38252,7 @@ namespace vl } } - void HexToBinary(stream::IStream& stream, const WString& hexText) + void HexToBinary(stream::IStream& binaryStream, const WString& hexText) { const wchar_t* buffer = hexText.Buffer(); vint count = hexText.Length() / 2; @@ -38260,17 +38260,17 @@ namespace vl { vuint8_t byte = (vuint8_t)(HexToInt(buffer[0]) * 16 + HexToInt(buffer[1])); buffer += 2; - stream.Write(&byte, 1); + binaryStream.Write(&byte, 1); } } - WString BinaryToHex(stream::IStream& stream) + WString BinaryToHex(stream::IStream& binaryStream) { stream::MemoryStream memoryStream; { stream::StreamWriter writer(memoryStream); vuint8_t byte; - while (stream.Read(&byte, 1) == 1) + while (binaryStream.Read(&byte, 1) == 1) { writer.WriteChar(L"0123456789ABCDEF"[byte / 16]); writer.WriteChar(L"0123456789ABCDEF"[byte % 16]); @@ -39552,14 +39552,14 @@ GuiResource return doc; } - Ptr GuiResource::LoadPrecompiledBinary(stream::IStream& stream, GuiResourceError::List& errors) + Ptr GuiResource::LoadPrecompiledBinary(stream::IStream& binaryStream, GuiResourceError::List& errors) { - stream::internal::ContextFreeReader reader(stream); + stream::internal::ContextFreeReader reader(binaryStream); auto resource = MakePtr(); { WString metadata; reader << metadata; - + auto parser = GetParserManager()->GetParser(L"XML"); auto xmlMetadata = parser->Parse({ resource }, metadata, errors); if (!xmlMetadata) return nullptr; @@ -39576,25 +39576,25 @@ GuiResource List typeNames; reader << typeNames; - + DelayLoadingList delayLoadings; resource->LoadResourceFolderFromBinary(delayLoadings, reader, typeNames, errors); - + ProcessDelayLoading(resource, delayLoadings, errors); return resource; } - Ptr GuiResource::LoadPrecompiledBinary(stream::IStream& stream) + Ptr GuiResource::LoadPrecompiledBinary(stream::IStream& binaryStream) { GuiResourceError::List errors; - auto resource = LoadPrecompiledBinary(stream, errors); + auto resource = LoadPrecompiledBinary(binaryStream, errors); CHECK_ERROR(errors.Count() == 0, L"GuiResource::LoadPrecompiledBinary(IStream&)#There are errors."); return resource; } - void GuiResource::SavePrecompiledBinary(stream::IStream& stream) + void GuiResource::SavePrecompiledBinary(stream::IStream& binaryStream) { - stream::internal::ContextFreeWriter writer(stream); + stream::internal::ContextFreeWriter writer(binaryStream); { auto xmlMetadata = metadata->SaveToXml(); WString xml = GenerateToStream([&](StreamWriter& writer) @@ -40070,18 +40070,18 @@ Class Name Record (ClassNameRecord) return this; } - void SerializePrecompiled(Ptr resource, Ptr content, stream::IStream& stream)override + void SerializePrecompiled(Ptr resource, Ptr content, stream::IStream& binaryStream)override { if (auto obj = content.Cast()) { - internal::ContextFreeWriter writer(stream); + internal::ContextFreeWriter writer(binaryStream); writer << obj->classNames; } } - Ptr ResolveResourcePrecompiled(Ptr resource, stream::IStream& stream, GuiResourceError::List& errors)override + Ptr ResolveResourcePrecompiled(Ptr resource, stream::IStream& binaryStream, GuiResourceError::List& errors)override { - internal::ContextFreeReader reader(stream); + internal::ContextFreeReader reader(binaryStream); auto obj = MakePtr(); reader << obj->classNames; @@ -40234,11 +40234,11 @@ IGuiInstanceResourceManager } } - void LoadResourceOrPending(stream::IStream& stream, GuiResourceError::List& errors, GuiResourceUsage usage)override + void LoadResourceOrPending(stream::IStream& resourceStream, GuiResourceError::List& errors, GuiResourceUsage usage)override { auto pr = MakePtr(); pr->usage = usage; - CopyStream(stream, pr->memoryStream); + CopyStream(resourceStream, pr->memoryStream); pr->metadata = MakePtr(); { @@ -40275,10 +40275,10 @@ IGuiInstanceResourceManager } } - void LoadResourceOrPending(stream::IStream& stream, GuiResourceUsage usage)override + void LoadResourceOrPending(stream::IStream& resourceStream, GuiResourceUsage usage)override { GuiResourceError::List errors; - LoadResourceOrPending(stream, errors, usage); + LoadResourceOrPending(resourceStream, errors, usage); CHECK_ERROR(errors.Count() == 0, L"GuiResourceManager::LoadResourceOrPending(stream::IStream&, GuiResourceUsage)#Error happened."); } @@ -40348,10 +40348,10 @@ Image Type Resolver (Image) return nullptr; } - void SerializePrecompiled(Ptr resource, Ptr content, stream::IStream& stream)override + void SerializePrecompiled(Ptr resource, Ptr content, stream::IStream& binaryStream)override { auto obj = content.Cast(); - stream::internal::ContextFreeWriter writer(stream); + stream::internal::ContextFreeWriter writer(binaryStream); FileStream fileStream(resource->GetFileAbsolutePath(), FileStream::ReadOnly); writer << (stream::IStream&)fileStream; } @@ -40376,9 +40376,9 @@ Image Type Resolver (Image) } } - Ptr ResolveResourcePrecompiled(Ptr resource, stream::IStream& stream, GuiResourceError::List& errors)override + Ptr ResolveResourcePrecompiled(Ptr resource, stream::IStream& binaryStream, GuiResourceError::List& errors)override { - stream::internal::ContextFreeReader reader(stream); + stream::internal::ContextFreeReader reader(binaryStream); MemoryStream memoryStream; reader << (stream::IStream&)memoryStream; @@ -40447,10 +40447,10 @@ Text Type Resolver (Text) return 0; } - void SerializePrecompiled(Ptr resource, Ptr content, stream::IStream& stream)override + void SerializePrecompiled(Ptr resource, Ptr content, stream::IStream& binaryStream)override { auto obj = content.Cast(); - stream::internal::ContextFreeWriter writer(stream); + stream::internal::ContextFreeWriter writer(binaryStream); WString text = obj->GetText(); writer << text; } @@ -40474,9 +40474,9 @@ Text Type Resolver (Text) } } - Ptr ResolveResourcePrecompiled(Ptr resource, stream::IStream& stream, GuiResourceError::List& errors)override + Ptr ResolveResourcePrecompiled(Ptr resource, stream::IStream& binaryStream, GuiResourceError::List& errors)override { - stream::internal::ContextFreeReader reader(stream); + stream::internal::ContextFreeReader reader(binaryStream); WString text; reader << text; return new GuiTextData(text); @@ -40531,14 +40531,14 @@ Xml Type Resolver (Xml) return nullptr; } - void SerializePrecompiled(Ptr resource, Ptr content, stream::IStream& stream)override + void SerializePrecompiled(Ptr resource, Ptr content, stream::IStream& binaryStream)override { auto obj = content.Cast(); WString text = GenerateToStream([&](StreamWriter& writer) { XmlPrint(obj, writer); }); - stream::internal::ContextFreeWriter writer(stream); + stream::internal::ContextFreeWriter writer(binaryStream); writer << text; } @@ -40571,11 +40571,11 @@ Xml Type Resolver (Xml) return nullptr; } - Ptr ResolveResourcePrecompiled(Ptr resource, stream::IStream& stream, GuiResourceError::List& errors)override + Ptr ResolveResourcePrecompiled(Ptr resource, stream::IStream& binaryStream, GuiResourceError::List& errors)override { if (auto parser = GetParserManager()->GetParser(L"XML")) { - stream::internal::ContextFreeReader reader(stream); + stream::internal::ContextFreeReader reader(binaryStream); WString text; reader << text; diff --git a/Import/GacUI.h b/Import/GacUI.h index d67a155d..ce2620f8 100644 --- a/Import/GacUI.h +++ b/Import/GacUI.h @@ -1341,6 +1341,253 @@ Basic Construction #endif +/*********************************************************************** +.\GRAPHICSELEMENT\GUIGRAPHICSDOCUMENTINTERFACES.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI::Element System and Infrastructure Interfaces + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_ELEMENTS_GUIGRAPHICSDOCUMENTINTERFACES +#define VCZH_PRESENTATION_ELEMENTS_GUIGRAPHICSDOCUMENTINTERFACES + + +namespace vl +{ + namespace presentation + { + namespace elements + { + +/*********************************************************************** +Layout Engine +***********************************************************************/ + + class IGuiGraphicsParagraph; + class IGuiGraphicsLayoutProvider; + + /// Represents a paragraph of a layouted rich text content. + class IGuiGraphicsParagraph : public IDescriptable, public Description + { + public: + static const vint NullInteractionId = -1; + + /// Text style. Items in this enumeration type can be combined. + enum TextStyle + { + /// Bold. + Bold=1, + /// Italic. + Italic=2, + /// Underline. + Underline=4, + /// Strikeline. + Strikeline=8, + }; + + /// Inline object break condition. + enum BreakCondition + { + /// Stay together with the previous run if possible. + StickToPreviousRun, + /// Stay together with the next run if possible. + StickToNextRun, + /// Treat as a single run. + Alone, + }; + + /// Caret relative position. + enum CaretRelativePosition + { + /// The first caret position. + CaretFirst, + /// The last caret position. + CaretLast, + /// The first caret position of the current line. + CaretLineFirst, + /// The last caret position of the current line. + CaretLineLast, + /// The relative left caret position. + CaretMoveLeft, + /// The relative right caret position. + CaretMoveRight, + /// The relative up caret position. + CaretMoveUp, + /// The relative down caret position. + CaretMoveDown, + }; + + /// Inline object properties. + struct InlineObjectProperties + { + /// The size of the inline object. + Size size; + /// The baseline of the inline object.If the baseline is at the bottom, then set the baseline to -1. + vint baseline = -1; + /// The break condition of the inline object. + BreakCondition breakCondition; + /// The background image, nullable. + Ptr backgroundImage; + /// The id for callback. If the value is -1, then no callback will be received . + vint callbackId = -1; + + InlineObjectProperties() + :baseline(-1) + { + } + }; + + /// Get the object that created this paragraph. + /// The layout provider object. + virtual IGuiGraphicsLayoutProvider* GetProvider()=0; + /// Get the associated to this paragraph. + /// The associated render target. + virtual IGuiGraphicsRenderTarget* GetRenderTarget()=0; + /// Get if line auto-wrapping is enabled for this paragraph. + /// Return true if line auto-wrapping is enabled for this paragraph. + virtual bool GetWrapLine()=0; + /// Set if line auto-wrapping is enabled for this paragraph. + /// True if line auto-wrapping is enabled for this paragraph. + virtual void SetWrapLine(bool value)=0; + /// Get the max width for this paragraph. If there is no max width limitation, it returns -1. + /// The max width for this paragraph. + virtual vint GetMaxWidth()=0; + /// Set the max width for this paragraph. If the max width is set to -1, the max width limitation will be removed. + /// The max width. + virtual void SetMaxWidth(vint value)=0; + /// Get the horizontal alignment for this paragraph. + /// The alignment. + virtual Alignment GetParagraphAlignment()=0; + /// Set the horizontal alignment for this paragraph. + /// The alignment. + virtual void SetParagraphAlignment(Alignment value)=0; + + /// Replace the font within the specified range. + /// The position of the first character of the specified range. + /// The length of the specified range by character. + /// The font. + /// Returns true if this operation succeeded. + virtual bool SetFont(vint start, vint length, const WString& value)=0; + /// Replace the size within the specified range. + /// The position of the first character of the specified range. + /// The length of the specified range by character. + /// The size. + /// Returns true if this operation succeeded. + virtual bool SetSize(vint start, vint length, vint value)=0; + /// Replace the text style within the specified range. + /// The position of the first character of the specified range. + /// The length of the specified range by character. + /// The text style. + /// Returns true if this operation succeeded. + virtual bool SetStyle(vint start, vint length, TextStyle value)=0; + /// Replace the color within the specified range. + /// The position of the first character of the specified range. + /// The length of the specified range by character. + /// The color. + /// Returns true if this operation succeeded. + virtual bool SetColor(vint start, vint length, Color value)=0; + /// Replace the background color within the specified range. + /// The position of the first character of the specified range. + /// The length of the specified range by character. + /// The background color. + /// Returns true if this operation succeeded. + virtual bool SetBackgroundColor(vint start, vint length, Color value)=0; + /// Bind an to a range of text. + /// The position of the first character of the specified range. + /// The length of the specified range by character. + /// The properties for the inline object. + /// Returns true if this operation succeeded. + virtual bool SetInlineObject(vint start, vint length, const InlineObjectProperties& properties)=0; + /// Unbind all inline objects to a range of text. + /// The position of the first character of the specified range. + /// The length of the specified range by character. + /// 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; + /// Make the caret visible so that it will be rendered in the paragraph. + /// Returns true if this operation succeeded. + /// The caret. + /// The color of the caret. + /// Set to true to display the caret for the character before it. + virtual bool OpenCaret(vint caret, Color color, bool frontSide)=0; + /// Make the caret invisible. + /// Returns true if this operation succeeded. + virtual bool CloseCaret()=0; + /// Render the graphics element using a specified bounds. + /// Bounds to decide the size and position of the binded graphics element. + virtual void Render(Rect bounds)=0; + + /// Get a new caret from the old caret with a relative position. + /// The new caret. Returns -1 if failed. + /// The caret to compare. If the position is CaretFirst or CaretLast, this argument is ignored. + /// The relative position. + /// Only for CaretMoveUp and CaretMoveDown. Set to true to make the caret prefer to get closer to the character before it. After this function is called, this argument stored the suggested side for displaying the new caret. + virtual vint GetCaret(vint comparingCaret, CaretRelativePosition position, bool& preferFrontSide)=0; + /// Get the bounds of the caret. + /// The bounds whose width is 0. Returns an empty Rect value if failed. + /// The caret. + /// Set to true to get the bounds of the front side, otherwise the back side. If only one side is valid, this argument is ignored. + virtual Rect GetCaretBounds(vint caret, bool frontSide)=0; + /// Get the caret from a specified position. + /// The caret. Returns -1 if failed. + /// The point. + virtual vint GetCaretFromPoint(Point point)=0; + /// Get the inline object from a specified position. + /// The inline object. Returns null if failed. + /// The point. + /// Get the start position of this element. + /// Get the length of this element. + virtual Nullable GetInlineObjectFromPoint(Point point, vint& start, vint& length)=0; + /// Get the nearest caret from a text position. + /// The caret. Returns -1 if failed. If the text position is a caret, then the result will be the text position itself without considering the frontSide argument. + /// The caret to compare. If the position is CaretFirst or CaretLast, this argument is ignored. + /// Set to true to search in front of the text position, otherwise the opposite position. + virtual vint GetNearestCaretFromTextPos(vint textPos, bool frontSide)=0; + /// Test is the caret valid. + /// Returns true if the caret is valid. + /// The caret to test. + virtual bool IsValidCaret(vint caret)=0; + /// Test is the text position valid. + /// Returns true if the text position is valid. + /// The text position to test. + virtual bool IsValidTextPos(vint textPos)=0; + }; + + /// Paragraph callback + class IGuiGraphicsParagraphCallback : public IDescriptable, public Description + { + public: + /// Called when an inline object with a valid callback id is being rendered. + /// Returns the new size of the rendered inline object. + /// The callback id of the inline object + /// The location of the inline object, relative to the left-top corner of this paragraph. + virtual Size OnRenderInlineObject(vint callbackId, Rect location) = 0; + }; + + /// Renderer awared rich text document layout engine provider interface. + class IGuiGraphicsLayoutProvider : public IDescriptable, public Description + { + public: + /// Create a paragraph with internal renderer device dependent objects initialized. + /// The text used to fill the paragraph. + /// The render target that the created paragraph will render to. + /// A callback to receive necessary information when the paragraph is being rendered. + /// The created paragraph object. + virtual Ptr CreateParagraph(const WString& text, IGuiGraphicsRenderTarget* renderTarget, IGuiGraphicsParagraphCallback* callback)=0; + }; + } + } +} + +#endif + /*********************************************************************** .\NATIVEWINDOW\GUINATIVEWINDOW.H ***********************************************************************/ @@ -1403,12 +1650,14 @@ System Object /// Returns true if the screen is a primary screen. virtual bool IsPrimary()=0; /// - /// Get the scaling for the screen's horizontal edge. For example, in Windows when you have a 96 DPI, this function returns 1.0. + /// Get the scaling for the screen's horizontal edge. /// + /// The scaling. For example, in Windows when you have a 96 DPI, this function returns 1.0. virtual double GetScalingX() = 0; /// - /// Get the scaling for the screen's vertical edge. For example, in Windows when you have a 96 DPI, this function returns 1.0. + /// Get the scaling for the screen's vertical edge. /// + /// The scaling. For example, in Windows when you have a 96 DPI, this function returns 1.0. virtual double GetScalingY() = 0; }; @@ -1424,53 +1673,56 @@ System Object enum SystemCursorType { /// - /// [T:vl.presentation.INativeCursor.SystemCursorType]Small waiting cursor. + /// Small waiting cursor. /// SmallWaiting, /// - /// [T:vl.presentation.INativeCursor.SystemCursorType]large waiting cursor. + /// large waiting cursor. /// LargeWaiting, /// - /// [T:vl.presentation.INativeCursor.SystemCursorType]Arrow cursor. + /// Arrow cursor. /// Arrow, /// - /// [T:vl.presentation.INativeCursor.SystemCursorType]Cross cursor. + /// Cross cursor. /// Cross, /// - /// [T:vl.presentation.INativeCursor.SystemCursorType]Hand cursor. + /// Hand cursor. /// Hand, /// - /// [T:vl.presentation.INativeCursor.SystemCursorType]Help cursor. + /// Help cursor. /// Help, /// - /// [T:vl.presentation.INativeCursor.SystemCursorType]I beam cursor. + /// I beam cursor. /// IBeam, /// - /// [T:vl.presentation.INativeCursor.SystemCursorType]Sizing in all direction cursor. + /// Sizing in all direction cursor. /// SizeAll, /// - /// [T:vl.presentation.INativeCursor.SystemCursorType]Sizing NE-SW cursor. + /// Sizing NE-SW cursor. /// SizeNESW, /// - /// [T:vl.presentation.INativeCursor.SystemCursorType]Sizing N-S cursor. + /// Sizing N-S cursor. /// SizeNS, /// - /// [T:vl.presentation.INativeCursor.SystemCursorType]Sizing NW-SE cursor. + /// Sizing NW-SE cursor. /// SizeNWSE, /// - /// [T:vl.presentation.INativeCursor.SystemCursorType]Sizing W-E cursor. + /// Sizing W-E cursor. /// SizeWE, + /// + /// Number of available cursors, this is not an available cursor by itself. + /// LastSystemCursor=SizeWE, }; @@ -1564,35 +1816,35 @@ Image Object enum FormatType { /// - /// [T:vl.presentation.INativeImage.FormatType]Bitmap format. + /// Bitmap format. /// Bmp, /// - /// [T:vl.presentation.INativeImage.FormatType]GIF format. + /// GIF format. /// Gif, /// - /// [T:vl.presentation.INativeImage.FormatType]Icon format. + /// Icon format. /// Icon, /// - /// [T:vl.presentation.INativeImage.FormatType]JPEG format. + /// JPEG format. /// Jpeg, /// - /// [T:vl.presentation.INativeImage.FormatType]PNG format. + /// PNG format. /// Png, /// - /// [T:vl.presentation.INativeImage.FormatType]TIFF format. + /// TIFF format. /// Tiff, /// - /// [T:vl.presentation.INativeImage.FormatType]WMP format. + /// WMP format. /// Wmp, /// - /// [T:vl.presentation.INativeImage.FormatType]Unknown format. + /// Unknown format. /// Unknown, }; @@ -1621,9 +1873,9 @@ Image Object /// /// Save the image to a stream. /// - /// The stream. + /// The stream. /// The format of the image. - virtual void SaveToStream(stream::IStream& stream, FormatType formatType = FormatType::Unknown) = 0; + virtual void SaveToStream(stream::IStream& imageStream, FormatType formatType = FormatType::Unknown) = 0; }; /// @@ -1651,8 +1903,8 @@ Image Object /// Create an image from stream. /// /// The created image. - /// The stream. - virtual Ptr CreateImageFromStream(stream::IStream& stream)=0; + /// The stream. + virtual Ptr CreateImageFromStream(stream::IStream& imageStream)=0; }; /*********************************************************************** @@ -3987,6 +4239,1619 @@ namespace vl #endif +/*********************************************************************** +.\GRAPHICSCOMPOSITION\GUIGRAPHICSFLOWCOMPOSITION.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI::Composition System + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_COMPOSITION_GUIGRAPHICSFLOWCOMPOSITION +#define VCZH_PRESENTATION_COMPOSITION_GUIGRAPHICSFLOWCOMPOSITION + + +namespace vl +{ + namespace presentation + { + namespace compositions + { +/*********************************************************************** +Flow Compositions +***********************************************************************/ + + /// + /// Alignment for a row in a flow layout + /// + enum class FlowAlignment + { + /// Align to the left. + Left, + /// Align to the center. + Center, + /// Extend to the entire row. + Extend, + }; + + /// + /// Represents a flow composition. + /// + class GuiFlowComposition : public GuiBoundsComposition, public Description + { + friend class GuiFlowItemComposition; + + typedef collections::List ItemCompositionList; + protected: + Margin extraMargin; + vint rowPadding = 0; + vint columnPadding = 0; + FlowAlignment alignment = FlowAlignment::Left; + Ptr axis; + + ItemCompositionList flowItems; + collections::Array flowItemBounds; + Rect bounds; + vint minHeight = 0; + bool needUpdate = false; + + void UpdateFlowItemBounds(bool forceUpdate); + void OnBoundsChanged(GuiGraphicsComposition* sender, GuiEventArgs& arguments); + void OnChildInserted(GuiGraphicsComposition* child)override; + void OnChildRemoved(GuiGraphicsComposition* child)override; + public: + GuiFlowComposition(); + ~GuiFlowComposition(); + + /// Get all flow items inside the flow composition. + /// All flow items inside the flow composition. + const ItemCompositionList& GetFlowItems(); + /// Insert a flow item at a specified position. + /// Returns true if this operation succeeded. + /// The position. + /// The flow item to insert. + bool InsertFlowItem(vint index, GuiFlowItemComposition* item); + + /// Get the extra margin inside the flow composition. + /// The extra margin inside the flow composition. + Margin GetExtraMargin(); + /// Set the extra margin inside the flow composition. + /// The extra margin inside the flow composition. + void SetExtraMargin(Margin value); + + /// Get the distance between rows. + /// The distance between rows. + vint GetRowPadding(); + /// Set the distance between rows. + /// The distance between rows. + void SetRowPadding(vint value); + + /// Get the distance between columns. + /// The distance between columns. + vint GetColumnPadding(); + /// Set the distance between columns. + /// The distance between columns. + void SetColumnPadding(vint value); + + /// Get the axis of the layout. + /// The axis. + Ptr GetAxis(); + /// Set the axis of the layout. + /// The axis. + void SetAxis(Ptr value); + + /// Get the alignment for rows. + /// The alignment. + FlowAlignment GetAlignment(); + /// Set the alignment for rows. + /// The alignment. + void SetAlignment(FlowAlignment value); + + void ForceCalculateSizeImmediately()override; + Size GetMinPreferredClientSize()override; + Rect GetBounds()override; + }; + + /// + /// Represnets a base line configuration for a flow item. + /// + struct GuiFlowOption + { + /// Base line calculation algorithm + enum BaselineType + { + /// By percentage of the height from the top. + Percentage, + /// By a distance from the top. + FromTop, + /// By a distance from the bottom. + FromBottom, + }; + + /// The base line calculation algorithm. + BaselineType baseline = FromBottom; + /// The percentage value. + double percentage = 0.0; + /// The distance value. + vint distance = 0; + }; + + /// + /// Represents a flow item composition of a . + /// + class GuiFlowItemComposition : public GuiGraphicsSite, public Description + { + friend class GuiFlowComposition; + protected: + GuiFlowComposition* flowParent; + Rect bounds; + Margin extraMargin; + GuiFlowOption option; + + void OnParentChanged(GuiGraphicsComposition* oldParent, GuiGraphicsComposition* newParent)override; + Size GetMinSize(); + public: + GuiFlowItemComposition(); + ~GuiFlowItemComposition(); + + bool IsSizeAffectParent()override; + Rect GetBounds()override; + void SetBounds(Rect value); + + /// Get the extra margin for this flow item. An extra margin is used to enlarge the bounds of the flow item, but only the non-extra part will be used for deciding the flow item layout. + /// The extra margin for this flow item. + Margin GetExtraMargin(); + /// Set the extra margin for this flow item. An extra margin is used to enlarge the bounds of the flow item, but only the non-extra part will be used for deciding the flow item layout. + /// The extra margin for this flow item. + void SetExtraMargin(Margin value); + + /// Get the base line option for this flow item. + /// The base line option. + GuiFlowOption GetFlowOption(); + /// Set the base line option for this flow item. + /// The base line option. + void SetFlowOption(GuiFlowOption value); + }; + } + } +} + +#endif + + +/*********************************************************************** +.\GRAPHICSCOMPOSITION\GUIGRAPHICSRESPONSIVECOMPOSITION.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI::Composition System + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_COMPOSITION_GUIGRAPHICSRESPONSIVECOMPOSITION +#define VCZH_PRESENTATION_COMPOSITION_GUIGRAPHICSRESPONSIVECOMPOSITION + + +namespace vl +{ + namespace presentation + { + namespace compositions + { + +/*********************************************************************** +GuiResponsiveCompositionBase +***********************************************************************/ + + enum class ResponsiveDirection + { + Horizontal = 1, + Vertical = 2, + Both = 3, + }; + + /// Base class for responsive layout compositions. + class GuiResponsiveCompositionBase abstract : public GuiBoundsComposition, public Description + { + protected: + GuiResponsiveCompositionBase* responsiveParent = nullptr; + ResponsiveDirection direction = ResponsiveDirection::Both; + + void OnParentLineChanged()override; + virtual void OnResponsiveChildInserted(GuiResponsiveCompositionBase* child); + virtual void OnResponsiveChildRemoved(GuiResponsiveCompositionBase* child); + virtual void OnResponsiveChildLevelUpdated(); + + public: + GuiResponsiveCompositionBase(); + ~GuiResponsiveCompositionBase(); + + /// LevelCount changed event. + GuiNotifyEvent LevelCountChanged; + /// CurrentLevel chagned event. + GuiNotifyEvent CurrentLevelChanged; + + /// Get the level count. A level count represents how many views this composition carries. + /// The level count. + virtual vint GetLevelCount() = 0; + /// Get the current level. Zero is the view with the smallest size. + /// The current level. + virtual vint GetCurrentLevel() = 0; + /// Switch to a smaller view. + /// Returns true if this operation succeeded. + virtual bool LevelDown() = 0; + /// Switch to a larger view. + /// Returns true if this operation succeeded. + virtual bool LevelUp() = 0; + + /// Get all supported directions. If all directions of a child [T:vl.presentation.compositions.GuiResponsiveCompositionBase] are not supported, its view will not be changed when the parent composition changes its view . + /// All supported directions. + ResponsiveDirection GetDirection(); + /// Set all supported directions. + /// All supported directions. + void SetDirection(ResponsiveDirection value); + }; + +/*********************************************************************** +GuiResponsiveViewComposition +***********************************************************************/ + + class GuiResponsiveSharedCollection : public collections::ObservableListBase + { + protected: + GuiResponsiveViewComposition* view = nullptr; + + void BeforeInsert(vint index, controls::GuiControl* const& value)override; + void AfterInsert(vint index, controls::GuiControl* const& value)override; + void BeforeRemove(vint index, controls::GuiControl* const& value)override; + void AfterRemove(vint index, vint count)override; + + public: + GuiResponsiveSharedCollection(GuiResponsiveViewComposition* _view); + ~GuiResponsiveSharedCollection(); + }; + + class GuiResponsiveViewCollection : public collections::ObservableListBase + { + protected: + GuiResponsiveViewComposition* view = nullptr; + + void BeforeInsert(vint index, GuiResponsiveCompositionBase* const& value)override; + void AfterInsert(vint index, GuiResponsiveCompositionBase* const& value)override; + void BeforeRemove(vint index, GuiResponsiveCompositionBase* const& value)override; + void AfterRemove(vint index, vint count)override; + + public: + GuiResponsiveViewCollection(GuiResponsiveViewComposition* _view); + ~GuiResponsiveViewCollection(); + }; + + /// Represents a composition, which will pick up a shared control and install inside it, when it is displayed by a [T:vl.presentation.compositions.GuiResponsiveViewComposition] + class GuiResponsiveSharedComposition : public GuiBoundsComposition, public Description + { + protected: + GuiResponsiveViewComposition* view = nullptr; + controls::GuiControl* shared = nullptr; + + void SetSharedControl(); + void OnParentLineChanged()override; + + public: + GuiResponsiveSharedComposition(); + ~GuiResponsiveSharedComposition(); + + /// Get the selected shared control. + /// The selected shared control. + controls::GuiControl* GetShared(); + /// Set the selected shared control, which should be stored in [M:vl.presentation.compositions.GuiResponsiveViewComposition.GetSharedControls]. + /// The selected shared control. + void SetShared(controls::GuiControl* value); + }; + + /// A responsive layout composition defined by views of different sizes. + class GuiResponsiveViewComposition : public GuiResponsiveCompositionBase, public Description + { + friend class GuiResponsiveSharedCollection; + friend class GuiResponsiveViewCollection; + friend class GuiResponsiveSharedComposition; + using ControlSet = collections::SortedList; + protected: + vint levelCount = 1; + vint currentLevel = 0; + bool skipUpdatingLevels = false; + GuiResponsiveCompositionBase* currentView = nullptr; + + ControlSet usedSharedControls; + GuiResponsiveSharedCollection sharedControls; + GuiResponsiveViewCollection views; + bool destructing = false; + + bool CalculateLevelCount(); + bool CalculateCurrentLevel(); + void OnResponsiveChildLevelUpdated()override; + + public: + GuiResponsiveViewComposition(); + ~GuiResponsiveViewComposition(); + + /// Before switch view event. This event happens between hiding the previous view and showing the next view. The itemIndex field can be used to access [M:vl.presentation.compositions.GuiResponsiveViewComposition.GetViews], it is not the level number. + GuiItemNotifyEvent BeforeSwitchingView; + + vint GetLevelCount()override; + vint GetCurrentLevel()override; + bool LevelDown()override; + bool LevelUp()override; + + /// Get the current displaying view. + /// The current displaying view. + GuiResponsiveCompositionBase* GetCurrentView(); + + /// Get all shared controls. A shared control can jump between different views if it is contained in a [T:vl.presentation.compositions.GuiResponsiveSharedComposition]. This helps to keep control states during switching views. + /// All shared controls. + collections::ObservableListBase& GetSharedControls(); + + /// Get all individual views to switch. + /// All individual views to switch. + collections::ObservableListBase& GetViews(); + }; + +/*********************************************************************** +Others +***********************************************************************/ + + /// A responsive layout composition which stop parent responsive composition to search its children. + class GuiResponsiveFixedComposition : public GuiResponsiveCompositionBase, public Description + { + protected: + void OnResponsiveChildLevelUpdated()override; + + public: + GuiResponsiveFixedComposition(); + ~GuiResponsiveFixedComposition(); + + vint GetLevelCount()override; + vint GetCurrentLevel()override; + bool LevelDown()override; + bool LevelUp()override; + }; + + /// A responsive layout composition which change its size by changing children's views one by one in one direction. + class GuiResponsiveStackComposition : public GuiResponsiveCompositionBase, public Description + { + using ResponsiveChildList = collections::List; + protected: + vint levelCount = 1; + vint currentLevel = 0; + ResponsiveChildList responsiveChildren; + + bool CalculateLevelCount(); + bool CalculateCurrentLevel(); + void OnResponsiveChildInserted(GuiResponsiveCompositionBase* child)override; + void OnResponsiveChildRemoved(GuiResponsiveCompositionBase* child)override; + void OnResponsiveChildLevelUpdated()override; + bool ChangeLevel(bool levelDown); + + public: + GuiResponsiveStackComposition(); + ~GuiResponsiveStackComposition(); + + vint GetLevelCount()override; + vint GetCurrentLevel()override; + bool LevelDown()override; + bool LevelUp()override; + }; + + /// A responsive layout composition which change its size by changing children's views at the same time. + class GuiResponsiveGroupComposition : public GuiResponsiveCompositionBase, public Description + { + using ResponsiveChildList = collections::List; + protected: + vint levelCount = 1; + vint currentLevel = 0; + ResponsiveChildList responsiveChildren; + + bool CalculateLevelCount(); + bool CalculateCurrentLevel(); + void OnResponsiveChildInserted(GuiResponsiveCompositionBase* child)override; + void OnResponsiveChildRemoved(GuiResponsiveCompositionBase* child)override; + void OnResponsiveChildLevelUpdated()override; + + public: + GuiResponsiveGroupComposition(); + ~GuiResponsiveGroupComposition(); + + vint GetLevelCount()override; + vint GetCurrentLevel()override; + bool LevelDown()override; + bool LevelUp()override; + }; + +/*********************************************************************** +GuiResponsiveContainerComposition +***********************************************************************/ + + /// A composition which will automatically tell its target responsive composition to switch between views according to its size. + class GuiResponsiveContainerComposition : public GuiBoundsComposition, public Description + { + protected: + GuiResponsiveCompositionBase* responsiveTarget = nullptr; + Size upperLevelSize; + + void AdjustLevel(); + void OnBoundsChanged(GuiGraphicsComposition* sender, GuiEventArgs& arguments); + + public: + GuiResponsiveContainerComposition(); + ~GuiResponsiveContainerComposition(); + + /// Get the responsive composition to control. + /// The responsive composition to control. + GuiResponsiveCompositionBase* GetResponsiveTarget(); + /// Get the responsive composition to control. + /// The responsive composition to control. + void SetResponsiveTarget(GuiResponsiveCompositionBase* value); + }; + } + } +} + +#endif + + +/*********************************************************************** +.\GRAPHICSCOMPOSITION\GUIGRAPHICSSHAREDSIZECOMPOSITION.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI::Composition System + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_COMPOSITION_GUIGRAPHICSSHAREDSIZECOMPOSITION +#define VCZH_PRESENTATION_COMPOSITION_GUIGRAPHICSSHAREDSIZECOMPOSITION + + +namespace vl +{ + namespace presentation + { + namespace compositions + { + /// A shared size composition that shares the same size with all other that has a same group name. + class GuiSharedSizeItemComposition : public GuiBoundsComposition, public Description + { + protected: + GuiSharedSizeRootComposition* parentRoot = nullptr; + WString group; + bool sharedWidth = false; + bool sharedHeight = false; + + void Update(); + void OnParentLineChanged()override; + public: + GuiSharedSizeItemComposition(); + ~GuiSharedSizeItemComposition(); + + /// Get the group name of this item. + /// The group name. + const WString& GetGroup(); + /// Set the group name of this item. + /// The group name. + void SetGroup(const WString& value); + /// Test is the width of this item is shared. + /// Returns true if the width of this item is shared. + bool GetSharedWidth(); + /// Enable or disable sharing the width of this item. + /// Set to true to share the width of this item. + void SetSharedWidth(bool value); + /// Test is the height of this item is shared. + /// Returns true if the height of this item is shared. + bool GetSharedHeight(); + /// Enable or disable sharing the height of this item. + /// Set to true to share the height of this item. + void SetSharedHeight(bool value); + }; + + /// A root composition that takes care of all direct or indirect to enable size sharing. + class GuiSharedSizeRootComposition :public GuiBoundsComposition, public Description + { + friend class GuiSharedSizeItemComposition; + protected: + collections::Dictionary itemWidths; + collections::Dictionary itemHeights; + collections::List childItems; + + void AddSizeComponent(collections::Dictionary& sizes, const WString& group, vint sizeComponent); + void CollectSizes(collections::Dictionary& widths, collections::Dictionary& heights); + void AlignSizes(collections::Dictionary& widths, collections::Dictionary& heights); + public: + GuiSharedSizeRootComposition(); + ~GuiSharedSizeRootComposition(); + + void ForceCalculateSizeImmediately()override; + Rect GetBounds()override; + }; + } + } +} + +#endif + +/*********************************************************************** +.\GRAPHICSCOMPOSITION\GUIGRAPHICSSPECIALIZEDCOMPOSITION.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI::Composition System + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_COMPOSITION_GUIGRAPHICSSPECIALIZEDCOMPOSITION +#define VCZH_PRESENTATION_COMPOSITION_GUIGRAPHICSSPECIALIZEDCOMPOSITION + + +namespace vl +{ + namespace presentation + { + namespace compositions + { + +/*********************************************************************** +Specialized Compositions +***********************************************************************/ + + /// + /// Represents a composition that is aligned to one border of the parent composition. + /// + class GuiSideAlignedComposition : public GuiGraphicsSite, public Description + { + public: + /// The border to align. + enum Direction + { + /// The left border. + Left, + /// The top border. + Top, + /// The right border. + Right, + /// The bottom border. + Bottom, + }; + protected: + Direction direction; + vint maxLength; + double maxRatio; + public: + GuiSideAlignedComposition(); + ~GuiSideAlignedComposition(); + + /// Get the border to align. + /// The border to align. + Direction GetDirection(); + /// Set the border to align. + /// The border to align. + void SetDirection(Direction value); + /// Get the maximum length of this composition. + /// The maximum length of this composition. + vint GetMaxLength(); + /// Set the maximum length of this composition. + /// The maximum length of this composition. + void SetMaxLength(vint value); + /// Get the maximum ratio to limit the size according to the size of the parent. + /// The maximum ratio to limit the size according to the size of the parent. + double GetMaxRatio(); + /// Set the maximum ratio to limit the size according to the size of the parent. + /// The maximum ratio to limit the size according to the size of the parent. + void SetMaxRatio(double value); + + bool IsSizeAffectParent()override; + Rect GetBounds()override; + }; + + /// + /// Represents a composition that its location and size are decided by the client area of the parent composition by setting ratios. + /// + class GuiPartialViewComposition : public GuiGraphicsSite, public Description + { + protected: + double wRatio; + double wPageSize; + double hRatio; + double hPageSize; + + public: + GuiPartialViewComposition(); + ~GuiPartialViewComposition(); + + /// Get the width ratio to decided the horizontal location. Value in [0, 1-pageSize]. + /// The width ratio to decided the horizontal location. + double GetWidthRatio(); + /// Get the page size to decide the horizontal size. Value in [0, 1]. + /// The page size to decide the horizontal size. + double GetWidthPageSize(); + /// Get the height ratio to decided the vertical location. Value in [0, 1-pageSize]. + /// The height ratio to decided the vertical location. + double GetHeightRatio(); + /// Get the page size to decide the vertical size. Value in [0, 1]. + /// The page size to decide the vertical size. + double GetHeightPageSize(); + /// Set the width ratio to decided the horizontal location. Value in [0, 1-pageSize]. + /// The width ratio to decided the horizontal location. + void SetWidthRatio(double value); + /// Set the page size to decide the horizontal size. Value in [0, 1]. + /// The page size to decide the horizontal size. + void SetWidthPageSize(double value); + /// Set the height ratio to decided the vertical location. Value in [0, 1-pageSize]. + /// The height ratio to decided the vertical location. + void SetHeightRatio(double value); + /// Set the page size to decide the vertical size. Value in [0, 1]. + /// The page size to decide the vertical size. + void SetHeightPageSize(double value); + + bool IsSizeAffectParent()override; + Rect GetBounds()override; + }; + } + } +} + +#endif + +/*********************************************************************** +.\GRAPHICSCOMPOSITION\GUIGRAPHICSSTACKCOMPOSITION.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI::Composition System + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_COMPOSITION_GUIGRAPHICSSTACKCOMPOSITION +#define VCZH_PRESENTATION_COMPOSITION_GUIGRAPHICSSTACKCOMPOSITION + + +namespace vl +{ + namespace presentation + { + namespace compositions + { + +/*********************************************************************** +Stack Compositions +***********************************************************************/ + + /// + /// Represents a stack composition. + /// + class GuiStackComposition : public GuiBoundsComposition, public Description + { + friend class GuiStackItemComposition; + + typedef collections::List ItemCompositionList; + public: + /// Stack item layout direction. + enum Direction + { + /// Stack items is layouted from left to right. + Horizontal, + /// Stack items is layouted from top to bottom. + Vertical, + /// Stack items is layouted from right to left. + ReversedHorizontal, + /// Stack items is layouted from bottom to top. + ReversedVertical, + }; + protected: + Direction direction = Horizontal; + ItemCompositionList stackItems; + GuiStackItemComposition* ensuringVisibleStackItem = nullptr; + + vint padding = 0; + vint adjustment = 0; + Margin extraMargin; + + collections::Array stackItemBounds; + Size stackItemTotalSize; + Rect previousBounds; + + void UpdateStackItemBounds(); + void EnsureStackItemVisible(); + void OnBoundsChanged(GuiGraphicsComposition* sender, GuiEventArgs& arguments); + void OnChildInserted(GuiGraphicsComposition* child)override; + void OnChildRemoved(GuiGraphicsComposition* child)override; + public: + GuiStackComposition(); + ~GuiStackComposition(); + + /// Get all stack items inside the stack composition. + /// All stack items inside the stack composition. + const ItemCompositionList& GetStackItems(); + /// Insert a stack item at a specified position. + /// Returns true if this operation succeeded. + /// The position. + /// The statck item to insert. + bool InsertStackItem(vint index, GuiStackItemComposition* item); + + /// Get the stack item layout direction. + /// The stack item layout direction. + Direction GetDirection(); + /// Set the stack item layout direction. + /// The stack item layout direction. + void SetDirection(Direction value); + /// Get the stack item padding. + /// The stack item padding. + vint GetPadding(); + /// Set the stack item padding. + /// The stack item padding. + void SetPadding(vint value); + + void ForceCalculateSizeImmediately()override; + Size GetMinPreferredClientSize()override; + Rect GetBounds()override; + + /// Get the extra margin inside the stack composition. + /// The extra margin inside the stack composition. + Margin GetExtraMargin(); + /// Set the extra margin inside the stack composition. + /// The extra margin inside the stack composition. + void SetExtraMargin(Margin value); + /// Test is any stack item clipped in the stack direction. + /// Returns true if any stack item is clipped. + bool IsStackItemClipped(); + /// Make an item visible as complete as possible. + /// Returns true if this operation succeeded. + /// The index of the item. + bool EnsureVisible(vint index); + }; + + /// + /// Represents a stack item composition of a . + /// + class GuiStackItemComposition : public GuiGraphicsSite, public Description + { + friend class GuiStackComposition; + protected: + GuiStackComposition* stackParent; + Rect bounds; + Margin extraMargin; + + void OnParentChanged(GuiGraphicsComposition* oldParent, GuiGraphicsComposition* newParent)override; + Size GetMinSize(); + public: + GuiStackItemComposition(); + ~GuiStackItemComposition(); + + bool IsSizeAffectParent()override; + Rect GetBounds()override; + /// Set the expected bounds of a stack item. In most of the cases only the size of the bounds is used. + /// The expected bounds of a stack item. + void SetBounds(Rect value); + + /// Get the extra margin for this stack item. An extra margin is used to enlarge the bounds of the stack item, but only the non-extra part will be used for deciding the stack item layout. + /// The extra margin for this stack item. + Margin GetExtraMargin(); + /// Set the extra margin for this stack item. An extra margin is used to enlarge the bounds of the stack item, but only the non-extra part will be used for deciding the stack item layout. + /// The extra margin for this stack item. + void SetExtraMargin(Margin value); + }; + } + } +} + +#endif + +/*********************************************************************** +.\GRAPHICSCOMPOSITION\GUIGRAPHICSREPEATCOMPOSITION.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI::Composition System + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_COMPOSITION_GUIGRAPHICSREPEATCOMPOSITION +#define VCZH_PRESENTATION_COMPOSITION_GUIGRAPHICSREPEATCOMPOSITION + + +namespace vl +{ + namespace presentation + { + namespace compositions + { + /// A base class for all bindable repeat compositions. + class GuiRepeatCompositionBase : public Object, public Description + { + using ItemStyleProperty = TemplateProperty; + using IValueEnumerable = reflection::description::IValueEnumerable; + using IValueList = reflection::description::IValueList; + protected: + ItemStyleProperty itemTemplate; + Ptr itemSource; + Ptr itemChangedHandler; + + virtual vint GetRepeatCompositionCount() = 0; + virtual GuiGraphicsComposition* GetRepeatComposition(vint index) = 0; + virtual GuiGraphicsComposition* InsertRepeatComposition(vint index) = 0; + virtual GuiGraphicsComposition* RemoveRepeatComposition(vint index) = 0; + + void OnItemChanged(vint index, vint oldCount, vint newCount); + void RemoveItem(vint index); + void InstallItem(vint index); + void ClearItems(); + void InstallItems(); + public: + GuiRepeatCompositionBase(); + ~GuiRepeatCompositionBase(); + + /// An event called after a new item is inserted. + GuiItemNotifyEvent ItemInserted; + /// An event called before a new item is removed. + GuiItemNotifyEvent ItemRemoved; + + /// Get the item style provider. + /// The item style provider. + ItemStyleProperty GetItemTemplate(); + /// Set the item style provider + /// The new item style provider + void SetItemTemplate(ItemStyleProperty value); + + /// Get the item source. + /// The item source. + Ptr GetItemSource(); + /// Set the item source. + /// The item source. Null is acceptable if you want to clear all data. + void SetItemSource(Ptr value); + }; + + /// Bindable stack composition. + class GuiRepeatStackComposition : public GuiStackComposition, public GuiRepeatCompositionBase, public Description + { + protected: + vint GetRepeatCompositionCount()override; + GuiGraphicsComposition* GetRepeatComposition(vint index)override; + GuiGraphicsComposition* InsertRepeatComposition(vint index)override; + GuiGraphicsComposition* RemoveRepeatComposition(vint index)override; + public: + }; + + /// Bindable flow composition. + class GuiRepeatFlowComposition : public GuiFlowComposition, public GuiRepeatCompositionBase, public Description + { + protected: + vint GetRepeatCompositionCount()override; + GuiGraphicsComposition* GetRepeatComposition(vint index)override; + GuiGraphicsComposition* InsertRepeatComposition(vint index)override; + GuiGraphicsComposition* RemoveRepeatComposition(vint index)override; + public: + }; + } + } +} + +#endif + +/*********************************************************************** +.\GRAPHICSCOMPOSITION\GUIGRAPHICSTABLECOMPOSITION.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI::Composition System + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_COMPOSITION_GUIGRAPHICSTABLECOMPOSITION +#define VCZH_PRESENTATION_COMPOSITION_GUIGRAPHICSTABLECOMPOSITION + + +namespace vl +{ + namespace presentation + { + namespace compositions + { + +/*********************************************************************** +Table Compositions +***********************************************************************/ + + /// + /// Represnets a sizing configuration for a row or a column. + /// + struct GuiCellOption + { + /// Sizing algorithm + enum ComposeType + { + /// Set the size to an absolute value. + Absolute, + /// Set the size to a percentage number of the whole table. + Percentage, + /// Set the size to the minimum size of the cell element. + MinSize, + }; + + /// Sizing algorithm + ComposeType composeType; + /// The absolute size when is ::Absolute. + vint absolute; + /// The percentage number when is ::Percentage. + double percentage; + + GuiCellOption() + :composeType(Absolute) + ,absolute(20) + ,percentage(0) + { + } + + bool operator==(const GuiCellOption& value){return false;} + bool operator!=(const GuiCellOption& value){return true;} + + /// Creates an absolute sizing option + /// The created option. + /// The absolute size. + static GuiCellOption AbsoluteOption(vint value) + { + GuiCellOption option; + option.composeType=Absolute; + option.absolute=value; + return option; + } + + /// Creates an percantage sizing option + /// The created option. + /// The percentage number. + static GuiCellOption PercentageOption(double value) + { + GuiCellOption option; + option.composeType=Percentage; + option.percentage=value; + return option; + } + + /// Creates an minimum sizing option + /// The created option. + static GuiCellOption MinSizeOption() + { + GuiCellOption option; + option.composeType=MinSize; + return option; + } + }; + + /// + /// Represents a table composition. + /// + class GuiTableComposition : public GuiBoundsComposition, public Description + { + friend class GuiCellComposition; + friend class GuiTableSplitterCompositionBase; + friend class GuiRowSplitterComposition; + friend class GuiColumnSplitterComposition; + protected: + vint rows; + vint columns; + vint cellPadding; + bool borderVisible; + vint rowExtending; + vint columnExtending; + collections::Array rowOptions; + collections::Array columnOptions; + collections::Array cellCompositions; + + collections::Array cellBounds; + collections::Array rowOffsets; + collections::Array columnOffsets; + collections::Array rowSizes; + collections::Array columnSizes; + + Size tableContentMinSize; + + vint GetSiteIndex(vint _rows, vint _columns, vint _row, vint _column); + void SetSitedCell(vint _row, vint _column, GuiCellComposition* cell); + + void UpdateCellBoundsInternal( + collections::Array& dimSizes, + vint& dimSize, + vint& dimSizeWithPercentage, + collections::Array& dimOptions, + vint GuiTableComposition::* dim1, + vint GuiTableComposition::* dim2, + vint (*getSize)(Size), + vint (*getLocation)(GuiCellComposition*), + vint (*getSpan)(GuiCellComposition*), + vint (*getRow)(vint, vint), + vint (*getCol)(vint, vint), + vint maxPass + ); + void UpdateCellBoundsPercentages( + collections::Array& dimSizes, + vint dimSize, + vint maxDimSize, + collections::Array& dimOptions + ); + vint UpdateCellBoundsOffsets( + collections::Array& offsets, + collections::Array& sizes, + vint max + ); + + void OnRenderContextChanged()override; + public: + GuiTableComposition(); + ~GuiTableComposition(); + + /// Event that will be raised with row numbers, column numbers or options are changed. + compositions::GuiNotifyEvent ConfigChanged; + + /// Get the number of rows. + /// The number of rows. + vint GetRows(); + /// Get the number of columns. + /// The number of columns. + vint GetColumns(); + /// Change the number of rows and columns. + /// Returns true if this operation succeeded. + /// The number of rows. + /// The number of columns. + bool SetRowsAndColumns(vint _rows, vint _columns); + /// Get the cell composition that covers the specified cell location. + /// The cell composition that covers the specified cell location. + /// The number of rows. + /// The number of columns. + GuiCellComposition* GetSitedCell(vint _row, vint _column); + + /// Get the sizing option of the specified row. + /// The sizing option of the specified row. + /// The specified row number. + GuiCellOption GetRowOption(vint _row); + /// Set the sizing option of the specified row. + /// The specified row number. + /// The sizing option of the specified row. + void SetRowOption(vint _row, GuiCellOption option); + /// Get the sizing option of the specified column. + /// The sizing option of the specified column. + /// The specified column number. + GuiCellOption GetColumnOption(vint _column); + /// Set the sizing option of the specified column. + /// The specified column number. + /// The sizing option of the specified column. + void SetColumnOption(vint _column, GuiCellOption option); + + /// Get the cell padding. A cell padding is the distance between a table client area and a cell, or between two cells. + /// The cell padding. + vint GetCellPadding(); + /// Set the cell padding. A cell padding is the distance between a table client area and a cell, or between two cells. + /// The cell padding. + void SetCellPadding(vint value); + /// Get the border visibility. + /// Returns true means the border thickness equals to the cell padding, otherwise zero. + bool GetBorderVisible(); + /// Set the border visibility. + /// Set to true to let the border thickness equal to the cell padding, otherwise zero. + void SetBorderVisible(bool value); + /// Get the cell area in the space of the table's parent composition's client area. + /// The cell area. + Rect GetCellArea(); + /// Update the sizing of the table and cells after all rows' and columns' sizing options are prepared. + void UpdateCellBounds(); + + void ForceCalculateSizeImmediately()override; + Size GetMinPreferredClientSize()override; + Rect GetBounds()override; + }; + + /// + /// Represents a cell composition of a . + /// + class GuiCellComposition : public GuiGraphicsSite, public Description + { + friend class GuiTableComposition; + protected: + vint row; + vint rowSpan; + vint column; + vint columnSpan; + GuiTableComposition* tableParent; + Size lastPreferredSize; + + void ClearSitedCells(GuiTableComposition* table); + void SetSitedCells(GuiTableComposition* table); + void ResetSiteInternal(); + bool SetSiteInternal(vint _row, vint _column, vint _rowSpan, vint _columnSpan); + void OnParentChanged(GuiGraphicsComposition* oldParent, GuiGraphicsComposition* newParent)override; + void OnTableRowsAndColumnsChanged(); + public: + GuiCellComposition(); + ~GuiCellComposition(); + + /// Get the owner table composition. + /// The owner table composition. + GuiTableComposition* GetTableParent(); + + /// Get the row number for this cell composition. + /// The row number for this cell composition. + vint GetRow(); + /// Get the total numbers of acrossed rows for this cell composition. + /// The total numbers of acrossed rows for this cell composition. + vint GetRowSpan(); + /// Get the column number for this cell composition. + /// The column number for this cell composition. + vint GetColumn(); + /// Get the total numbers of acrossed columns for this cell composition. + /// The total numbers of acrossed columns for this cell composition. + vint GetColumnSpan(); + /// Set the position for this cell composition in the table. + /// Returns true if this operation succeeded. + /// The row number for this cell composition. + /// The column number for this cell composition. + /// The total numbers of acrossed rows for this cell composition. + /// The total numbers of acrossed columns for this cell composition. + bool SetSite(vint _row, vint _column, vint _rowSpan, vint _columnSpan); + + Rect GetBounds()override; + }; + + class GuiTableSplitterCompositionBase : public GuiGraphicsSite, public Description + { + protected: + GuiTableComposition* tableParent; + + bool dragging; + Point draggingPoint; + + void OnParentChanged(GuiGraphicsComposition* oldParent, GuiGraphicsComposition* newParent)override; + void OnLeftButtonDown(GuiGraphicsComposition* sender, GuiMouseEventArgs& arguments); + void OnLeftButtonUp(GuiGraphicsComposition* sender, GuiMouseEventArgs& arguments); + + void OnMouseMoveHelper( + vint cellsBefore, + vint GuiTableComposition::* cells, + collections::Array& cellSizes, + vint offset, + GuiCellOption(GuiTableComposition::*getOption)(vint), + void(GuiTableComposition::*setOption)(vint, GuiCellOption) + ); + + Rect GetBoundsHelper( + vint cellsBefore, + vint GuiTableComposition::* cells, + vint(Rect::* dimSize)()const, + collections::Array& cellOffsets, + vint Rect::* dimU1, + vint Rect::* dimU2, + vint Rect::* dimV1, + vint Rect::* dimV2 + ); + public: + GuiTableSplitterCompositionBase(); + ~GuiTableSplitterCompositionBase(); + + /// Get the owner table composition. + /// The owner table composition. + GuiTableComposition* GetTableParent(); + }; + + /// + /// Represents a row splitter composition of a . + /// + class GuiRowSplitterComposition : public GuiTableSplitterCompositionBase, public Description + { + protected: + vint rowsToTheTop; + + void OnMouseMove(GuiGraphicsComposition* sender, GuiMouseEventArgs& arguments); + public: + GuiRowSplitterComposition(); + ~GuiRowSplitterComposition(); + + /// Get the number of rows that above the splitter. + /// The number of rows that above the splitter. + vint GetRowsToTheTop(); + /// Set the number of rows that above the splitter. + /// The number of rows that above the splitter + void SetRowsToTheTop(vint value); + + Rect GetBounds()override; + }; + + /// + /// Represents a column splitter composition of a . + /// + class GuiColumnSplitterComposition : public GuiTableSplitterCompositionBase, public Description + { + protected: + vint columnsToTheLeft; + + void OnMouseMove(GuiGraphicsComposition* sender, GuiMouseEventArgs& arguments); + public: + GuiColumnSplitterComposition(); + ~GuiColumnSplitterComposition(); + + /// Get the number of columns that before the splitter. + /// The number of columns that before the splitter. + vint GetColumnsToTheLeft(); + /// Set the number of columns that before the splitter. + /// The number of columns that before the splitter + void SetColumnsToTheLeft(vint value); + + Rect GetBounds()override; + }; + } + } +} + +#endif + +/*********************************************************************** +.\GRAPHICSCOMPOSITION\INCLUDEALL.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI::Composition System + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_COMPOSITION_INCLUDEALL +#define VCZH_PRESENTATION_COMPOSITION_INCLUDEALL + + +#endif + +/*********************************************************************** +.\GRAPHICSELEMENT\GUIGRAPHICSRESOURCEMANAGER.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI::Element System and Infrastructure Interfaces + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_ELEMENTS_GUIGRAPHICSRESOURCEMANAGER +#define VCZH_PRESENTATION_ELEMENTS_GUIGRAPHICSRESOURCEMANAGER + + +namespace vl +{ + namespace presentation + { + namespace elements + { + +/*********************************************************************** +Resource Manager +***********************************************************************/ + + /// + /// This is a class for managing grpahics element factories and graphics renderer factories + /// + class GuiGraphicsResourceManager : public Object + { + typedef collections::Dictionary> elementFactoryMap; + typedef collections::Dictionary> rendererFactoryMap; + protected: + elementFactoryMap elementFactories; + rendererFactoryMap rendererFactories; + public: + /// + /// Create a graphics resource manager without any predefined factories + /// + GuiGraphicsResourceManager(); + ~GuiGraphicsResourceManager(); + + /// + /// Register a using the element type from . + /// + /// The instance of the graphics element factory to register. + /// Returns true if this operation succeeded. + virtual bool RegisterElementFactory(IGuiGraphicsElementFactory* factory); + /// + /// Register a and bind it to a registered . + /// + /// The element type to represent a graphics element factory. + /// The instance of the graphics renderer factory to register. + /// Returns true if this operation succeeded. + virtual bool RegisterRendererFactory(const WString& elementTypeName, IGuiGraphicsRendererFactory* factory); + /// + /// Get the instance of a registered that is binded to a specified element type. + /// + /// Returns the element factory. + /// The element type to get a corresponding graphics element factory. + virtual IGuiGraphicsElementFactory* GetElementFactory(const WString& elementTypeName); + /// + /// Get the instance of a registered that is binded to a specified element type. + /// + /// Returns the renderer factory. + /// The element type to get a corresponding graphics renderer factory. + virtual IGuiGraphicsRendererFactory* GetRendererFactory(const WString& elementTypeName); + /// + /// Get the instance of a that is binded to an . + /// + /// The specified window. + /// Returns the render target. + virtual IGuiGraphicsRenderTarget* GetRenderTarget(INativeWindow* window)=0; + /// + /// Recreate the render target for the specified window. + /// + /// The specified window. + virtual void RecreateRenderTarget(INativeWindow* window) = 0; + /// + /// Resize the render target to fit the current window size. + /// + /// The specified window. + virtual void ResizeRenderTarget(INativeWindow* window) = 0; + /// + /// Get the renderer awared rich text document layout engine provider object. + /// + /// Returns the layout provider. + virtual IGuiGraphicsLayoutProvider* GetLayoutProvider()=0; + }; + + /// + /// Get the current . + /// + /// Returns the current resource manager. + extern GuiGraphicsResourceManager* GetGuiGraphicsResourceManager(); + /// + /// Set the current . + /// + /// The resource manager to set. + extern void SetGuiGraphicsResourceManager(GuiGraphicsResourceManager* resourceManager); + /// + /// Helper function to register a with a and bind them together. + /// + /// Returns true if this operation succeeded. + /// The element factory to register. + /// The renderer factory to register. + extern bool RegisterFactories(IGuiGraphicsElementFactory* elementFactory, IGuiGraphicsRendererFactory* rendererFactory); + +/*********************************************************************** +Helpers +***********************************************************************/ + + template + class GuiElementBase : public Object, public IGuiGraphicsElement, public Description + { + public: + class Factory : public Object, public IGuiGraphicsElementFactory + { + public: + WString GetElementTypeName() + { + return TElement::GetElementTypeName(); + } + IGuiGraphicsElement* Create() + { + auto element = new TElement; + element->factory = this; + IGuiGraphicsRendererFactory* rendererFactory = GetGuiGraphicsResourceManager()->GetRendererFactory(GetElementTypeName()); + if (rendererFactory) + { + element->renderer = rendererFactory->Create(); + element->renderer->Initialize(element); + } + return element; + } + }; + protected: + IGuiGraphicsElementFactory* factory = nullptr; + Ptr renderer; + compositions::GuiGraphicsComposition* ownerComposition = nullptr; + + void SetOwnerComposition(compositions::GuiGraphicsComposition* composition)override + { + ownerComposition = composition; + } + + void InvokeOnCompositionStateChanged() + { + if (ownerComposition) + { + compositions::InvokeOnCompositionStateChanged(ownerComposition); + } + } + + void InvokeOnElementStateChanged() + { + if (renderer) + { + renderer->OnElementStateChanged(); + } + InvokeOnCompositionStateChanged(); + } + public: + static TElement* Create() + { + auto factory = GetGuiGraphicsResourceManager()->GetElementFactory(TElement::GetElementTypeName()); + CHECK_ERROR(factory != nullptr, L"This element is not supported by the selected renderer."); + return dynamic_cast(factory->Create()); + } + + ~GuiElementBase() + { + if (renderer) + { + renderer->Finalize(); + } + } + + IGuiGraphicsElementFactory* GetFactory()override + { + return factory; + } + + IGuiGraphicsRenderer* GetRenderer()override + { + return renderer.Obj(); + } + + compositions::GuiGraphicsComposition* GetOwnerComposition()override + { + return ownerComposition; + } + }; + +#define DEFINE_GUI_GRAPHICS_ELEMENT(TELEMENT, ELEMENT_TYPE_NAME)\ + friend class GuiElementBase;\ + public:\ + static WString GetElementTypeName()\ + {\ + return ELEMENT_TYPE_NAME;\ + }\ + +#define DEFINE_GUI_GRAPHICS_RENDERER(TELEMENT, TRENDERER, TTARGET)\ + public:\ + class Factory : public Object, public IGuiGraphicsRendererFactory\ + {\ + public:\ + IGuiGraphicsRenderer* Create()\ + {\ + TRENDERER* renderer=new TRENDERER;\ + renderer->factory=this;\ + renderer->element=0;\ + renderer->renderTarget=0;\ + return renderer;\ + }\ + };\ + protected:\ + IGuiGraphicsRendererFactory* factory;\ + TELEMENT* element;\ + TTARGET* renderTarget;\ + Size minSize;\ + public:\ + static void Register()\ + {\ + RegisterFactories(new TELEMENT::Factory, new TRENDERER::Factory);\ + }\ + IGuiGraphicsRendererFactory* GetFactory()override\ + {\ + return factory;\ + }\ + void Initialize(IGuiGraphicsElement* _element)override\ + {\ + element=dynamic_cast(_element);\ + InitializeInternal();\ + }\ + void Finalize()override\ + {\ + FinalizeInternal();\ + }\ + void SetRenderTarget(IGuiGraphicsRenderTarget* _renderTarget)override\ + {\ + TTARGET* oldRenderTarget=renderTarget;\ + renderTarget=dynamic_cast(_renderTarget);\ + RenderTargetChangedInternal(oldRenderTarget, renderTarget);\ + }\ + Size GetMinSize()override\ + {\ + return minSize;\ + }\ + +#define DEFINE_CACHED_RESOURCE_ALLOCATOR(TKEY, TVALUE)\ + public:\ + static const vint DeadPackageMax=32;\ + struct Package\ + {\ + TVALUE resource;\ + vint counter;\ + bool operator==(const Package& package)const{return false;}\ + bool operator!=(const Package& package)const{return true;}\ + };\ + struct DeadPackage\ + {\ + TKEY key;\ + TVALUE value;\ + bool operator==(const DeadPackage& package)const{return false;}\ + bool operator!=(const DeadPackage& package)const{return true;}\ + };\ + Dictionary aliveResources;\ + List deadResources;\ + public:\ + TVALUE Create(const TKEY& key)\ + {\ + vint index=aliveResources.Keys().IndexOf(key);\ + if(index!=-1)\ + {\ + Package package=aliveResources.Values().Get(index);\ + package.counter++;\ + aliveResources.Set(key, package);\ + return package.resource;\ + }\ + TVALUE resource;\ + for(vint i=0;iShortcut key item. + class IGuiShortcutKeyItem : public virtual IDescriptable, public Description + { + public: + /// Shortcut key executed event. + GuiNotifyEvent Executed; + + /// Get the associated object. + /// The associated shortcut key manager. + virtual IGuiShortcutKeyManager* GetManager()=0; + /// Get the name represents the shortcut key combination for this item. + /// The name represents the shortcut key combination for this item. + virtual WString GetName()=0; + }; + + /// Shortcut key manager item. + class IGuiShortcutKeyManager : public virtual IDescriptable, public Description + { + public: + /// Get the number of shortcut key items that already attached to the manager. + /// T number of shortcut key items that already attached to the manager. + virtual vint GetItemCount()=0; + /// Get the associated with the index. + /// The shortcut key item. + /// The index. + virtual IGuiShortcutKeyItem* GetItem(vint index)=0; + /// Execute shortcut key items using a key event info. + /// Returns true if at least one shortcut key item is executed. + /// The key event info. + virtual bool Execute(const NativeWindowKeyInfo& info)=0; + }; + +/*********************************************************************** +Shortcut Key Manager Helpers +***********************************************************************/ + + class GuiShortcutKeyManager; + + class GuiShortcutKeyItem : public Object, public IGuiShortcutKeyItem + { + protected: + GuiShortcutKeyManager* shortcutKeyManager; + bool ctrl; + bool shift; + bool alt; + VKEY key; + + void AttachManager(GuiShortcutKeyManager* manager); + void DetachManager(GuiShortcutKeyManager* manager); + public: + GuiShortcutKeyItem(GuiShortcutKeyManager* _shortcutKeyManager, bool _ctrl, bool _shift, bool _alt, VKEY _key); + ~GuiShortcutKeyItem(); + + IGuiShortcutKeyManager* GetManager()override; + WString GetName()override; + bool CanActivate(const NativeWindowKeyInfo& info); + bool CanActivate(bool _ctrl, bool _shift, bool _alt, VKEY _key); + }; + + /// A default implementation for . + class GuiShortcutKeyManager : public Object, public IGuiShortcutKeyManager, public Description + { + typedef collections::List> ShortcutKeyItemList; + protected: + ShortcutKeyItemList shortcutKeyItems; + + public: + /// Create the shortcut key manager. + GuiShortcutKeyManager(); + ~GuiShortcutKeyManager(); + + vint GetItemCount()override; + IGuiShortcutKeyItem* GetItem(vint index)override; + bool Execute(const NativeWindowKeyInfo& info)override; + + /// Create a shortcut key item using a key combination. If the item for the key combination exists, this function returns the item that is created before. + /// The created shortcut key item. + /// Set to true if the CTRL key is required. + /// Set to true if the SHIFT key is required. + /// Set to true if the ALT key is required. + /// The non-control key. + IGuiShortcutKeyItem* CreateShortcut(bool ctrl, bool shift, bool alt, VKEY key); + /// Destroy a shortcut key item using a key combination + /// Returns true if the manager destroyed a existing shortcut key item. + /// Set to true if the CTRL key is required. + /// Set to true if the SHIFT key is required. + /// Set to true if the ALT key is required. + /// The non-control key. + bool DestroyShortcut(bool ctrl, bool shift, bool alt, VKEY key); + /// Get a shortcut key item using a key combination. If the item for the key combination does not exist, this function returns null. + /// The shortcut key item. + /// Set to true if the CTRL key is required. + /// Set to true if the SHIFT key is required. + /// Set to true if the ALT key is required. + /// The non-control key. + IGuiShortcutKeyItem* TryGetShortcut(bool ctrl, bool shift, bool alt, VKEY key); + }; + } + } +} + +#endif + /*********************************************************************** .\GRAPHICSHOST\GUIGRAPHICSHOST_TAB.H ***********************************************************************/ @@ -4188,6 +6184,207 @@ Tab-Combined Shortcut Key Interfaces Helpers #endif +/*********************************************************************** +.\GRAPHICSHOST\GUIGRAPHICSHOST.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI::Graphics Composition Host + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_HOST_GUIGRAPHICSHOST +#define VCZH_PRESENTATION_HOST_GUIGRAPHICSHOST + + +namespace vl +{ + namespace presentation + { + namespace controls + { + class GuiWindow; + } + + namespace compositions + { + +/*********************************************************************** +Animation +***********************************************************************/ + + /// + /// Represents a timer callback object. + /// + class IGuiGraphicsTimerCallback : public virtual IDescriptable, public Description + { + public: + /// Called periodically. + /// Returns false to indicate that this callback need to be removed. + virtual bool Play() = 0; + }; + + /// + /// Timer callback manager. + /// + class GuiGraphicsTimerManager : public Object, public Description + { + typedef collections::List> CallbackList; + protected: + CallbackList callbacks; + + public: + GuiGraphicsTimerManager(); + ~GuiGraphicsTimerManager(); + + /// Add a new callback. + /// The new callback to add. + void AddCallback(Ptr callback); + /// Called periodically. + void Play(); + }; + +/*********************************************************************** +Host +***********************************************************************/ + + /// + /// GuiGraphicsHost hosts an in an . The composition will fill the whole window. + /// + class GuiGraphicsHost : public Object, private INativeWindowListener, private INativeControllerListener, public Description + { + typedef collections::List CompositionList; + typedef GuiGraphicsComposition::GraphicsHostRecord HostRecord; + typedef collections::Pair ProcKey; + typedef collections::List> ProcList; + typedef collections::Dictionary> ProcMap; + public: + static const vuint64_t CaretInterval = 500; + + protected: + HostRecord hostRecord; + bool supressPaint = false; + bool needRender = true; + ProcList afterRenderProcs; + ProcMap afterRenderKeyedProcs; + + GuiAltActionManager* altActionManager = nullptr; + GuiTabActionManager* tabActionManager = nullptr; + IGuiShortcutKeyManager* shortcutKeyManager = nullptr; + + controls::GuiControlHost* controlHost = nullptr; + GuiWindowComposition* windowComposition = nullptr; + GuiGraphicsComposition* focusedComposition = nullptr; + NativeSize previousClientSize; + Size minSize; + Point caretPoint; + vuint64_t lastCaretTime = 0; + + GuiGraphicsTimerManager timerManager; + GuiGraphicsComposition* mouseCaptureComposition = nullptr; + CompositionList mouseEnterCompositions; + void RefreshRelatedHostRecord(INativeWindow* nativeWindow); + + void DisconnectCompositionInternal(GuiGraphicsComposition* composition); + void MouseCapture(const NativeWindowMouseInfo& info); + void MouseUncapture(const NativeWindowMouseInfo& info); + void OnCharInput(const NativeWindowCharInfo& info, GuiGraphicsComposition* composition, GuiCharEvent GuiGraphicsEventReceiver::* eventReceiverEvent); + void OnKeyInput(const NativeWindowKeyInfo& info, GuiGraphicsComposition* composition, GuiKeyEvent GuiGraphicsEventReceiver::* eventReceiverEvent); + void RaiseMouseEvent(GuiMouseEventArgs& arguments, GuiGraphicsComposition* composition, GuiMouseEvent GuiGraphicsEventReceiver::* eventReceiverEvent); + void OnMouseInput(const NativeWindowMouseInfo& info, GuiMouseEvent GuiGraphicsEventReceiver::* eventReceiverEvent); + void RecreateRenderTarget(); + + private: + INativeWindowListener::HitTestResult HitTest(NativePoint location)override; + void Moving(NativeRect& bounds, bool fixSizeOnly)override; + void Moved()override; + void DpiChanged()override; + void Paint()override; + + void LeftButtonDown(const NativeWindowMouseInfo& info)override; + void LeftButtonUp(const NativeWindowMouseInfo& info)override; + void LeftButtonDoubleClick(const NativeWindowMouseInfo& info)override; + void RightButtonDown(const NativeWindowMouseInfo& info)override; + void RightButtonUp(const NativeWindowMouseInfo& info)override; + void RightButtonDoubleClick(const NativeWindowMouseInfo& info)override; + void MiddleButtonDown(const NativeWindowMouseInfo& info)override; + void MiddleButtonUp(const NativeWindowMouseInfo& info)override; + void MiddleButtonDoubleClick(const NativeWindowMouseInfo& info)override; + void HorizontalWheel(const NativeWindowMouseInfo& info)override; + void VerticalWheel(const NativeWindowMouseInfo& info)override; + void MouseMoving(const NativeWindowMouseInfo& info)override; + void MouseEntered()override; + void MouseLeaved()override; + + void KeyDown(const NativeWindowKeyInfo& info)override; + void KeyUp(const NativeWindowKeyInfo& info)override; + void SysKeyDown(const NativeWindowKeyInfo& info)override; + void SysKeyUp(const NativeWindowKeyInfo& info)override; + void Char(const NativeWindowCharInfo& info)override; + + void GlobalTimer()override; + public: + GuiGraphicsHost(controls::GuiControlHost* _controlHost, GuiGraphicsComposition* boundsComposition); + ~GuiGraphicsHost(); + + /// Get the associated window. + /// The associated window. + INativeWindow* GetNativeWindow(); + /// Associate a window. A will fill and appear in the window. + /// The window to associated. + void SetNativeWindow(INativeWindow* _nativeWindow); + /// Get the main . If a window is associated, everything that put into the main composition will be shown in the window. + /// The main compositoin. + GuiGraphicsComposition* GetMainComposition(); + /// Render the main composition and all content to the associated window. + /// Set to true to force updating layout and then render. + void Render(bool forceUpdate); + /// Request a rendering + void RequestRender(); + /// Invoke a specified function after rendering. + /// The specified function. + /// A key to cancel a previous binded key if not null. + void InvokeAfterRendering(const Func& proc, ProcKey key = { nullptr,-1 }); + + /// Invalidte the internal tab order control list. Next time when TAB is pressed it will be rebuilt. + void InvalidateTabOrderCache(); + /// Get the attached with this graphics host. + /// The shortcut key manager. + IGuiShortcutKeyManager* GetShortcutKeyManager(); + /// Attach or detach the associated with this graphics host. When this graphics host is disposing, the associated shortcut key manager will be deleted if exists. + /// The shortcut key manager. Set to null to detach the previous shortcut key manager from this graphics host. + void SetShortcutKeyManager(IGuiShortcutKeyManager* value); + + /// Set the focus composition. A focused composition will receive keyboard messages. + /// Returns true if this operation succeeded. + /// The composition to set focus. This composition should be or in the main composition. + bool SetFocus(GuiGraphicsComposition* composition); + /// Get the focus composition. A focused composition will receive keyboard messages. + /// The focus composition. + GuiGraphicsComposition* GetFocusedComposition(); + /// Get the caret point. A caret point is the position to place the edit box of the activated input method editor. + /// The caret point. + Point GetCaretPoint(); + /// Set the caret point. A caret point is the position to place the edit box of the activated input method editor. + /// The caret point. + /// The point space. If this argument is null, the "value" argument will use the point space of the client area in the main composition. + void SetCaretPoint(Point value, GuiGraphicsComposition* referenceComposition=0); + + /// Get the timer manager. + /// The timer manager. + GuiGraphicsTimerManager* GetTimerManager(); + /// Notify that a composition is going to disconnect from this graphics host. Generally this happens when a composition's parent line changes. + /// The composition to disconnect + void DisconnectComposition(GuiGraphicsComposition* composition); + }; + } + } +} + +#endif + /*********************************************************************** .\RESOURCES\GUIRESOURCE.H ***********************************************************************/ @@ -4240,8 +6437,8 @@ Helper Functions /// The extracted path. extern bool IsResourceUrl(const WString& text, WString& protocol, WString& path); - extern void HexToBinary(stream::IStream& stream, const WString& hexText); - extern WString BinaryToHex(stream::IStream& stream); + extern void HexToBinary(stream::IStream& binaryStream, const WString& hexText); + extern WString BinaryToHex(stream::IStream& binaryStream); /*********************************************************************** Global String Key @@ -4625,18 +6822,18 @@ Resource /// Load a precompiled resource from a stream. /// The loaded resource. - /// The stream. + /// The stream. /// All collected errors during loading a resource. - static Ptr LoadPrecompiledBinary(stream::IStream& stream, GuiResourceError::List& errors); + static Ptr LoadPrecompiledBinary(stream::IStream& binaryStream, GuiResourceError::List& errors); /// Load a precompiled resource from a stream. This function will hit an assert if there are errors. /// The loaded resource. - /// The stream. - static Ptr LoadPrecompiledBinary(stream::IStream& stream); + /// The stream. + static Ptr LoadPrecompiledBinary(stream::IStream& binaryStream); /// Save the precompiled resource to a stream. - /// The stream. - void SavePrecompiledBinary(stream::IStream& stream); + /// The stream. + void SavePrecompiledBinary(stream::IStream& binaryStream); /// Precompile this resource to improve performance. /// The resource folder contains all precompiled result. The folder will be added to the resource if there is no error. @@ -4902,15 +7099,15 @@ Resource Type Resolver /// Serialize a precompiled resource to a stream. /// The resource item containing the resource. /// The content to serialize. - /// The stream. - virtual void SerializePrecompiled(Ptr resource, Ptr content, stream::IStream& stream) = 0; + /// The stream. + virtual void SerializePrecompiled(Ptr resource, Ptr content, stream::IStream& binaryStream) = 0; /// Load a precompiled resource from a stream. /// The resource. /// The resource item containing the resource. - /// The stream. + /// The stream. /// All collected errors during loading a resource. - virtual Ptr ResolveResourcePrecompiled(Ptr resource, stream::IStream& stream, GuiResourceError::List& errors) = 0; + virtual Ptr ResolveResourcePrecompiled(Ptr resource, stream::IStream& binaryStream, GuiResourceError::List& errors) = 0; }; /// Represents a symbol type for loading a resource with a preload type. @@ -5693,586 +7890,6 @@ Rich Content Document (model) #endif -/*********************************************************************** -.\GRAPHICSELEMENT\GUIGRAPHICSDOCUMENTINTERFACES.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI::Element System and Infrastructure Interfaces - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_ELEMENTS_GUIGRAPHICSDOCUMENTINTERFACES -#define VCZH_PRESENTATION_ELEMENTS_GUIGRAPHICSDOCUMENTINTERFACES - - -namespace vl -{ - namespace presentation - { - namespace elements - { - -/*********************************************************************** -Layout Engine -***********************************************************************/ - - class IGuiGraphicsParagraph; - class IGuiGraphicsLayoutProvider; - - /// Represents a paragraph of a layouted rich text content. - class IGuiGraphicsParagraph : public IDescriptable, public Description - { - public: - static const vint NullInteractionId = -1; - - /// Text style. Items in this enumeration type can be combined. - enum TextStyle - { - /// Bold. - Bold=1, - /// Italic. - Italic=2, - /// Underline. - Underline=4, - /// Strikeline. - Strikeline=8, - }; - - /// Inline object break condition. - enum BreakCondition - { - /// Stay together with the previous run if possible. - StickToPreviousRun, - /// Stay together with the next run if possible. - StickToNextRun, - /// Treat as a single run. - Alone, - }; - - /// Caret relative position. - enum CaretRelativePosition - { - /// The first caret position. - CaretFirst, - /// The last caret position. - CaretLast, - /// The first caret position of the current line. - CaretLineFirst, - /// The last caret position of the current line. - CaretLineLast, - /// The relative left caret position. - CaretMoveLeft, - /// The relative right caret position. - CaretMoveRight, - /// The relative up caret position. - CaretMoveUp, - /// The relative down caret position. - CaretMoveDown, - }; - - /// Inline object properties. - struct InlineObjectProperties - { - /// The size of the inline object. - Size size; - /// The baseline of the inline object.If the baseline is at the bottom, then set the baseline to -1. - vint baseline = -1; - /// The break condition of the inline object. - BreakCondition breakCondition; - /// The background image, nullable. - Ptr backgroundImage; - /// The id for callback. If the value is -1, then no callback will be received . - vint callbackId = -1; - - InlineObjectProperties() - :baseline(-1) - { - } - }; - - /// Get the object that created this paragraph. - /// The layout provider object. - virtual IGuiGraphicsLayoutProvider* GetProvider()=0; - /// Get the associated to this paragraph. - /// The associated render target. - virtual IGuiGraphicsRenderTarget* GetRenderTarget()=0; - /// Get if line auto-wrapping is enabled for this paragraph. - /// Return true if line auto-wrapping is enabled for this paragraph. - virtual bool GetWrapLine()=0; - /// Set if line auto-wrapping is enabled for this paragraph. - /// True if line auto-wrapping is enabled for this paragraph. - virtual void SetWrapLine(bool value)=0; - /// Get the max width for this paragraph. If there is no max width limitation, it returns -1. - /// The max width for this paragraph. - virtual vint GetMaxWidth()=0; - /// Set the max width for this paragraph. If the max width is set to -1, the max width limitation will be removed. - /// The max width. - virtual void SetMaxWidth(vint value)=0; - /// Get the horizontal alignment for this paragraph. - /// The alignment. - virtual Alignment GetParagraphAlignment()=0; - /// Set the horizontal alignment for this paragraph. - /// The alignment. - virtual void SetParagraphAlignment(Alignment value)=0; - - /// Replace the font within the specified range. - /// The position of the first character of the specified range. - /// The length of the specified range by character. - /// The font. - /// Returns true if this operation succeeded. - virtual bool SetFont(vint start, vint length, const WString& value)=0; - /// Replace the size within the specified range. - /// The position of the first character of the specified range. - /// The length of the specified range by character. - /// The size. - /// Returns true if this operation succeeded. - virtual bool SetSize(vint start, vint length, vint value)=0; - /// Replace the text style within the specified range. - /// The position of the first character of the specified range. - /// The length of the specified range by character. - /// The text style. - /// Returns true if this operation succeeded. - virtual bool SetStyle(vint start, vint length, TextStyle value)=0; - /// Replace the color within the specified range. - /// The position of the first character of the specified range. - /// The length of the specified range by character. - /// The color. - /// Returns true if this operation succeeded. - virtual bool SetColor(vint start, vint length, Color value)=0; - /// Replace the background color within the specified range. - /// The position of the first character of the specified range. - /// The length of the specified range by character. - /// The background color. - /// Returns true if this operation succeeded. - virtual bool SetBackgroundColor(vint start, vint length, Color value)=0; - /// Bind an to a range of text. - /// The position of the first character of the specified range. - /// The length of the specified range by character. - /// The properties for the inline object. - /// Returns true if this operation succeeded. - virtual bool SetInlineObject(vint start, vint length, const InlineObjectProperties& properties)=0; - /// Unbind all inline objects to a range of text. - /// The position of the first character of the specified range. - /// The length of the specified range by character. - /// 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; - /// Make the caret visible so that it will be rendered in the paragraph. - /// Returns true if this operation succeeded. - /// The caret. - /// The color of the caret. - /// Set to true to display the caret for the character before it. - virtual bool OpenCaret(vint caret, Color color, bool frontSide)=0; - /// Make the caret invisible. - /// Returns true if this operation succeeded. - virtual bool CloseCaret()=0; - /// Render the graphics element using a specified bounds. - /// Bounds to decide the size and position of the binded graphics element. - virtual void Render(Rect bounds)=0; - - /// Get a new caret from the old caret with a relative position. - /// The new caret. Returns -1 if failed. - /// The caret to compare. If the position is CaretFirst or CaretLast, this argument is ignored. - /// The relative position. - /// Only for CaretMoveUp and CaretMoveDown. Set to true to make the caret prefer to get closer to the character before it. After this function is called, this argument stored the suggested side for displaying the new caret. - virtual vint GetCaret(vint comparingCaret, CaretRelativePosition position, bool& preferFrontSide)=0; - /// Get the bounds of the caret. - /// The bounds whose width is 0. Returns an empty Rect value if failed. - /// The caret. - /// Set to true to get the bounds of the front side, otherwise the back side. If only one side is valid, this argument is ignored. - virtual Rect GetCaretBounds(vint caret, bool frontSide)=0; - /// Get the caret from a specified position. - /// The caret. Returns -1 if failed. - /// The point. - virtual vint GetCaretFromPoint(Point point)=0; - /// Get the inline object from a specified position. - /// The inline object. Returns null if failed. - /// The point. - /// Get the start position of this element. - /// Get the length of this element. - virtual Nullable GetInlineObjectFromPoint(Point point, vint& start, vint& length)=0; - /// Get the nearest caret from a text position. - /// The caret. Returns -1 if failed. If the text position is a caret, then the result will be the text position itself without considering the frontSide argument. - /// The caret to compare. If the position is CaretFirst or CaretLast, this argument is ignored. - /// Set to true to search in front of the text position, otherwise the opposite position. - virtual vint GetNearestCaretFromTextPos(vint textPos, bool frontSide)=0; - /// Test is the caret valid. - /// Returns true if the caret is valid. - /// The caret to test. - virtual bool IsValidCaret(vint caret)=0; - /// Test is the text position valid. - /// Returns true if the text position is valid. - /// The text position to test. - virtual bool IsValidTextPos(vint textPos)=0; - }; - - /// Paragraph callback - class IGuiGraphicsParagraphCallback : public IDescriptable, public Description - { - public: - /// Called when an inline object with a valid callback id is being rendered. - /// Returns the new size of the rendered inline object. - /// The callback id of the inline object - /// The location of the inline object, relative to the left-top corner of this paragraph. - virtual Size OnRenderInlineObject(vint callbackId, Rect location) = 0; - }; - - /// Renderer awared rich text document layout engine provider interface. - class IGuiGraphicsLayoutProvider : public IDescriptable, public Description - { - public: - /// Create a paragraph with internal renderer device dependent objects initialized. - /// The text used to fill the paragraph. - /// The render target that the created paragraph will render to. - /// A callback to receive necessary information when the paragraph is being rendered. - /// The created paragraph object. - virtual Ptr CreateParagraph(const WString& text, IGuiGraphicsRenderTarget* renderTarget, IGuiGraphicsParagraphCallback* callback)=0; - }; - } - } -} - -#endif - -/*********************************************************************** -.\GRAPHICSELEMENT\GUIGRAPHICSRESOURCEMANAGER.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI::Element System and Infrastructure Interfaces - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_ELEMENTS_GUIGRAPHICSRESOURCEMANAGER -#define VCZH_PRESENTATION_ELEMENTS_GUIGRAPHICSRESOURCEMANAGER - - -namespace vl -{ - namespace presentation - { - namespace elements - { - -/*********************************************************************** -Resource Manager -***********************************************************************/ - - /// - /// This is a class for managing grpahics element factories and graphics renderer factories - /// - class GuiGraphicsResourceManager : public Object - { - typedef collections::Dictionary> elementFactoryMap; - typedef collections::Dictionary> rendererFactoryMap; - protected: - elementFactoryMap elementFactories; - rendererFactoryMap rendererFactories; - public: - /// - /// Create a graphics resource manager without any predefined factories - /// - GuiGraphicsResourceManager(); - ~GuiGraphicsResourceManager(); - - /// - /// Register a using the element type from . - /// - /// The instance of the graphics element factory to register. - /// Returns true if this operation succeeded. - virtual bool RegisterElementFactory(IGuiGraphicsElementFactory* factory); - /// - /// Register a and bind it to a registered . - /// - /// The element type to represent a graphics element factory. - /// The instance of the graphics renderer factory to register. - /// Returns true if this operation succeeded. - virtual bool RegisterRendererFactory(const WString& elementTypeName, IGuiGraphicsRendererFactory* factory); - /// - /// Get the instance of a registered that is binded to a specified element type. - /// - /// Returns the element factory. - /// The element type to get a corresponding graphics element factory. - virtual IGuiGraphicsElementFactory* GetElementFactory(const WString& elementTypeName); - /// - /// Get the instance of a registered that is binded to a specified element type. - /// - /// Returns the renderer factory. - /// The element type to get a corresponding graphics renderer factory. - virtual IGuiGraphicsRendererFactory* GetRendererFactory(const WString& elementTypeName); - /// - /// Get the instance of a that is binded to an . - /// - /// The specified window. - /// Returns the render target. - virtual IGuiGraphicsRenderTarget* GetRenderTarget(INativeWindow* window)=0; - /// - /// Recreate the render target for the specified window. - /// - /// The specified window. - virtual void RecreateRenderTarget(INativeWindow* window) = 0; - /// - /// Resize the render target to fit the current window size. - /// - /// The specified window. - virtual void ResizeRenderTarget(INativeWindow* window) = 0; - /// - /// Get the renderer awared rich text document layout engine provider object. - /// - /// Returns the layout provider. - virtual IGuiGraphicsLayoutProvider* GetLayoutProvider()=0; - }; - - /// - /// Get the current . - /// - /// Returns the current resource manager. - extern GuiGraphicsResourceManager* GetGuiGraphicsResourceManager(); - /// - /// Set the current . - /// - /// The resource manager to set. - extern void SetGuiGraphicsResourceManager(GuiGraphicsResourceManager* resourceManager); - /// - /// Helper function to register a with a and bind them together. - /// - /// Returns true if this operation succeeded. - /// The element factory to register. - /// The renderer factory to register. - extern bool RegisterFactories(IGuiGraphicsElementFactory* elementFactory, IGuiGraphicsRendererFactory* rendererFactory); - -/*********************************************************************** -Helpers -***********************************************************************/ - - template - class GuiElementBase : public Object, public IGuiGraphicsElement, public Description - { - public: - class Factory : public Object, public IGuiGraphicsElementFactory - { - public: - WString GetElementTypeName() - { - return TElement::GetElementTypeName(); - } - IGuiGraphicsElement* Create() - { - auto element = new TElement; - element->factory = this; - IGuiGraphicsRendererFactory* rendererFactory = GetGuiGraphicsResourceManager()->GetRendererFactory(GetElementTypeName()); - if (rendererFactory) - { - element->renderer = rendererFactory->Create(); - element->renderer->Initialize(element); - } - return element; - } - }; - protected: - IGuiGraphicsElementFactory* factory = nullptr; - Ptr renderer; - compositions::GuiGraphicsComposition* ownerComposition = nullptr; - - void SetOwnerComposition(compositions::GuiGraphicsComposition* composition)override - { - ownerComposition = composition; - } - - void InvokeOnCompositionStateChanged() - { - if (ownerComposition) - { - compositions::InvokeOnCompositionStateChanged(ownerComposition); - } - } - - void InvokeOnElementStateChanged() - { - if (renderer) - { - renderer->OnElementStateChanged(); - } - InvokeOnCompositionStateChanged(); - } - public: - static TElement* Create() - { - auto factory = GetGuiGraphicsResourceManager()->GetElementFactory(TElement::GetElementTypeName()); - CHECK_ERROR(factory != nullptr, L"This element is not supported by the selected renderer."); - return dynamic_cast(factory->Create()); - } - - ~GuiElementBase() - { - if (renderer) - { - renderer->Finalize(); - } - } - - IGuiGraphicsElementFactory* GetFactory()override - { - return factory; - } - - IGuiGraphicsRenderer* GetRenderer()override - { - return renderer.Obj(); - } - - compositions::GuiGraphicsComposition* GetOwnerComposition()override - { - return ownerComposition; - } - }; - -#define DEFINE_GUI_GRAPHICS_ELEMENT(TELEMENT, ELEMENT_TYPE_NAME)\ - friend class GuiElementBase;\ - public:\ - static WString GetElementTypeName()\ - {\ - return ELEMENT_TYPE_NAME;\ - }\ - -#define DEFINE_GUI_GRAPHICS_RENDERER(TELEMENT, TRENDERER, TTARGET)\ - public:\ - class Factory : public Object, public IGuiGraphicsRendererFactory\ - {\ - public:\ - IGuiGraphicsRenderer* Create()\ - {\ - TRENDERER* renderer=new TRENDERER;\ - renderer->factory=this;\ - renderer->element=0;\ - renderer->renderTarget=0;\ - return renderer;\ - }\ - };\ - protected:\ - IGuiGraphicsRendererFactory* factory;\ - TELEMENT* element;\ - TTARGET* renderTarget;\ - Size minSize;\ - public:\ - static void Register()\ - {\ - RegisterFactories(new TELEMENT::Factory, new TRENDERER::Factory);\ - }\ - IGuiGraphicsRendererFactory* GetFactory()override\ - {\ - return factory;\ - }\ - void Initialize(IGuiGraphicsElement* _element)override\ - {\ - element=dynamic_cast(_element);\ - InitializeInternal();\ - }\ - void Finalize()override\ - {\ - FinalizeInternal();\ - }\ - void SetRenderTarget(IGuiGraphicsRenderTarget* _renderTarget)override\ - {\ - TTARGET* oldRenderTarget=renderTarget;\ - renderTarget=dynamic_cast(_renderTarget);\ - RenderTargetChangedInternal(oldRenderTarget, renderTarget);\ - }\ - Size GetMinSize()override\ - {\ - return minSize;\ - }\ - -#define DEFINE_CACHED_RESOURCE_ALLOCATOR(TKEY, TVALUE)\ - public:\ - static const vint DeadPackageMax=32;\ - struct Package\ - {\ - TVALUE resource;\ - vint counter;\ - bool operator==(const Package& package)const{return false;}\ - bool operator!=(const Package& package)const{return true;}\ - };\ - struct DeadPackage\ - {\ - TKEY key;\ - TVALUE value;\ - bool operator==(const DeadPackage& package)const{return false;}\ - bool operator!=(const DeadPackage& package)const{return true;}\ - };\ - Dictionary aliveResources;\ - List deadResources;\ - public:\ - TVALUE Create(const TKEY& key)\ - {\ - vint index=aliveResources.Keys().IndexOf(key);\ - if(index!=-1)\ - {\ - Package package=aliveResources.Values().Get(index);\ - package.counter++;\ - aliveResources.Set(key, package);\ - return package.resource;\ - }\ - TVALUE resource;\ - for(vint i=0;iA control with 3 phases state transffering when mouse click happens. + class GuiButton : public GuiControl, public Description + { + GUI_SPECIFY_CONTROL_TEMPLATE_TYPE(ButtonTemplate, GuiControl) + protected: + bool clickOnMouseUp = true; + bool autoFocus = true; + bool keyPressing = false; + bool mousePressing = false; + bool mouseHoving = false; + ButtonState controlState = ButtonState::Normal; + + void OnParentLineChanged()override; + void OnActiveAlt()override; + bool IsTabAvailable()override; + void UpdateControlState(); + void CheckAndClick(compositions::GuiEventArgs& arguments); + void OnLeftButtonDown(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments); + void OnLeftButtonUp(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments); + void OnMouseEnter(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); + void OnMouseLeave(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); + void OnKeyDown(compositions::GuiGraphicsComposition* sender, compositions::GuiKeyEventArgs& arguments); + void OnKeyUp(compositions::GuiGraphicsComposition* sender, compositions::GuiKeyEventArgs& arguments); + void OnLostFocus(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); + public: + /// Create a control with a specified default theme. + /// The theme name for retriving a default control template. + GuiButton(theme::ThemeName themeName); + ~GuiButton(); + + /// Mouse click event. + compositions::GuiNotifyEvent Clicked; + + /// Test is the event raised when left mouse button up. + /// Returns true if this event is raised when left mouse button up + bool GetClickOnMouseUp(); + /// Set is the event raised when left mouse button up or not. + /// Set to true to make this event raised when left mouse button up + void SetClickOnMouseUp(bool value); + + /// Test if the button gets focus when it is clicked. + /// Returns true if the button gets focus when it is clicked + bool GetAutoFocus(); + /// Set if the button gets focus when it is clicked. + /// Set to true to make this button get focus when it is clicked. + void SetAutoFocus(bool value); + }; + + /// A with a selection state. + class GuiSelectableButton : public GuiButton, public Description + { + GUI_SPECIFY_CONTROL_TEMPLATE_TYPE(SelectableButtonTemplate, GuiButton) + public: + /// Selection group controller. Control the selection state of all attached button. + class GroupController : public GuiComponent, public Description + { + protected: + collections::List buttons; + public: + GroupController(); + ~GroupController(); + + /// Called when the group controller is attached to a . use [M:vl.presentation.controls.GuiSelectableButton.SetGroupController] to attach or detach a group controller to or from a selectable button. + /// The button to attach. + virtual void Attach(GuiSelectableButton* button); + /// Called when the group controller is deteched to a . use [M:vl.presentation.controls.GuiSelectableButton.SetGroupController] to attach or detach a group controller to or from a selectable button. + /// The button to detach. + virtual void Detach(GuiSelectableButton* button); + /// Called when the selection state of any changed. + /// The button that changed the selection state. + virtual void OnSelectedChanged(GuiSelectableButton* button) = 0; + }; + + /// A mutex group controller, usually for radio buttons. + class MutexGroupController : public GroupController, public Description + { + protected: + bool suppress; + public: + MutexGroupController(); + ~MutexGroupController(); + + void OnSelectedChanged(GuiSelectableButton* button)override; + }; + + protected: + GroupController* groupController = nullptr; + bool autoSelection = true; + bool isSelected = false; + + void OnClicked(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); + public: + /// Create a control with a specified default theme. + /// The theme name for retriving a default control template. + GuiSelectableButton(theme::ThemeName themeName); + ~GuiSelectableButton(); + + /// Group controller changed event. + compositions::GuiNotifyEvent GroupControllerChanged; + /// Auto selection changed event. + compositions::GuiNotifyEvent AutoSelectionChanged; + /// Selected changed event. + compositions::GuiNotifyEvent SelectedChanged; + + /// Get the attached group controller. + /// The attached group controller. + virtual GroupController* GetGroupController(); + /// Set the attached group controller. + /// The attached group controller. + virtual void SetGroupController(GroupController* value); + + /// Get the auto selection state. True if the button is automatically selected or unselected when the button is clicked. + /// The auto selection state. + virtual bool GetAutoSelection(); + /// Set the auto selection state. True if the button is automatically selected or unselected when the button is clicked. + /// The auto selection state. + virtual void SetAutoSelection(bool value); + + /// Get the selected state. + /// The selected state. + virtual bool GetSelected(); + /// Set the selected state. + /// The selected state. + virtual void SetSelected(bool value); + }; + } + } +} + +#endif + + +/*********************************************************************** +.\CONTROLS\GUIDIALOGS.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI::Control System + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_CONTROLS_GUIDIALOGS +#define VCZH_PRESENTATION_CONTROLS_GUIDIALOGS + + +namespace vl +{ + namespace presentation + { + namespace controls + { + class GuiWindow; + +/*********************************************************************** +Dialogs +***********************************************************************/ + + /// Base class for dialogs. + class GuiDialogBase abstract : public GuiComponent, public Description + { + protected: + GuiInstanceRootObject* rootObject = nullptr; + + GuiWindow* GetHostWindow(); + public: + GuiDialogBase(); + ~GuiDialogBase(); + + void Attach(GuiInstanceRootObject* _rootObject); + void Detach(GuiInstanceRootObject* _rootObject); + }; + + /// Message dialog. + class GuiMessageDialog : public GuiDialogBase, public Description + { + protected: + INativeDialogService::MessageBoxButtonsInput input = INativeDialogService::DisplayOK; + INativeDialogService::MessageBoxDefaultButton defaultButton = INativeDialogService::DefaultFirst; + INativeDialogService::MessageBoxIcons icon = INativeDialogService::IconNone; + INativeDialogService::MessageBoxModalOptions modalOption = INativeDialogService::ModalWindow; + WString text; + WString title; + + public: + /// Create a message dialog. + GuiMessageDialog(); + ~GuiMessageDialog(); + + /// Get the button combination that appear on the dialog. + /// The button combination. + INativeDialogService::MessageBoxButtonsInput GetInput(); + /// Set the button combination that appear on the dialog. + /// The button combination. + void SetInput(INativeDialogService::MessageBoxButtonsInput value); + + /// Get the default button for the selected button combination. + /// The default button. + INativeDialogService::MessageBoxDefaultButton GetDefaultButton(); + /// Set the default button for the selected button combination. + /// The default button. + void SetDefaultButton(INativeDialogService::MessageBoxDefaultButton value); + + /// Get the icon that appears on the dialog. + /// The icon. + INativeDialogService::MessageBoxIcons GetIcon(); + /// Set the icon that appears on the dialog. + /// The icon. + void SetIcon(INativeDialogService::MessageBoxIcons value); + + /// Get the way that how this dialog disable windows of the current process. + /// The way that how this dialog disable windows of the current process. + INativeDialogService::MessageBoxModalOptions GetModalOption(); + /// Set the way that how this dialog disable windows of the current process. + /// The way that how this dialog disable windows of the current process. + void SetModalOption(INativeDialogService::MessageBoxModalOptions value); + + /// Get the text for the dialog. + /// The text. + const WString& GetText(); + /// Set the text for the dialog. + /// The text. + void SetText(const WString& value); + + /// Get the title for the dialog. + /// The title. + const WString& GetTitle(); + /// Set the title for the dialog. If the title is empty, the dialog will use the title of the window that host this dialog. + /// The title. + void SetTitle(const WString& value); + + /// Show the dialog. + /// Returns the clicked button. + INativeDialogService::MessageBoxButtonsOutput ShowDialog(); + }; + + /// Color dialog. + class GuiColorDialog : public GuiDialogBase, public Description + { + protected: + bool enabledCustomColor = true; + bool openedCustomColor = false; + Color selectedColor; + bool showSelection = true; + collections::List customColors; + + public: + /// Create a color dialog. + GuiColorDialog(); + ~GuiColorDialog(); + + /// Selected color changed event. + compositions::GuiNotifyEvent SelectedColorChanged; + + /// Get if the custom color panel is enabled for the dialog. + /// Returns true if the color panel is enabled for the dialog. + bool GetEnabledCustomColor(); + /// Set if custom color panel is enabled for the dialog. + /// Set to true to enable the custom color panel for the dialog. + void SetEnabledCustomColor(bool value); + + /// Get if the custom color panel is opened by default when it is enabled. + /// Returns true if the custom color panel is opened by default. + bool GetOpenedCustomColor(); + /// Set if the custom color panel is opened by default when it is enabled. + /// Set to true to open custom color panel by default if it is enabled. + void SetOpenedCustomColor(bool value); + + /// Get the selected color. + /// The selected color. + Color GetSelectedColor(); + /// Set the selected color. + /// The selected color. + void SetSelectedColor(Color value); + + /// Get the list to access 16 selected custom colors on the palette. Colors in the list is guaranteed to have exactly 16 items after the dialog is closed. + /// The list to access custom colors on the palette. + collections::List& GetCustomColors(); + + /// Show the dialog. + /// Returns true if the "OK" button is clicked. + bool ShowDialog(); + }; + + /// Font dialog. + class GuiFontDialog : public GuiDialogBase, public Description + { + protected: + FontProperties selectedFont; + Color selectedColor; + bool showSelection = true; + bool showEffect = true; + bool forceFontExist = true; + + public: + /// Create a font dialog. + GuiFontDialog(); + ~GuiFontDialog(); + + /// Selected font changed event. + compositions::GuiNotifyEvent SelectedFontChanged; + /// Selected color changed event. + compositions::GuiNotifyEvent SelectedColorChanged; + + /// Get the selected font. + /// The selected font. + const FontProperties& GetSelectedFont(); + /// Set the selected font. + /// The selected font. + void SetSelectedFont(const FontProperties& value); + + /// Get the selected color. + /// The selected color. + Color GetSelectedColor(); + /// Set the selected color. + /// The selected color. + void SetSelectedColor(Color value); + + /// Get if the selected font is already selected on the dialog when it is opened. + /// Returns true if the selected font is already selected on the dialog when it is opened. + bool GetShowSelection(); + /// Set if the selected font is already selected on the dialog when it is opened. + /// Set to true to select the selected font when the dialog is opened. + void SetShowSelection(bool value); + + /// Get if the font preview is enabled. + /// Returns true if the font preview is enabled. + bool GetShowEffect(); + /// Set if the font preview is enabled. + /// Set to true to enable the font preview. + void SetShowEffect(bool value); + + /// Get if the dialog only accepts an existing font. + /// Returns true if the dialog only accepts an existing font. + bool GetForceFontExist(); + /// Set if the dialog only accepts an existing font. + /// Set to true to let the dialog only accept an existing font. + void SetForceFontExist(bool value); + + /// Show the dialog. + /// Returns true if the "OK" button is clicked. + bool ShowDialog(); + }; + + /// Base class for file dialogs. + class GuiFileDialogBase abstract : public GuiDialogBase, public Description + { + protected: + WString filter = L"All Files (*.*)|*.*"; + vint filterIndex = 0; + bool enabledPreview = false; + WString title; + WString fileName; + WString directory; + WString defaultExtension; + INativeDialogService::FileDialogOptions options; + + public: + GuiFileDialogBase(); + ~GuiFileDialogBase(); + + /// File name changed event. + compositions::GuiNotifyEvent FileNameChanged; + /// Filter index changed event. + compositions::GuiNotifyEvent FilterIndexChanged; + + /// Get the filter. + /// The filter. + const WString& GetFilter(); + /// Set the filter. The filter is formed by pairs of filter name and wildcard concatenated by "|", like "Text Files (*.txt)|*.txt|All Files (*.*)|*.*". + /// The filter. + void SetFilter(const WString& value); + + /// Get the filter index. + /// The filter index. + vint GetFilterIndex(); + /// Set the filter index. + /// The filter index. + void SetFilterIndex(vint value); + + /// Get if the file preview is enabled. + /// Returns true if the file preview is enabled. + bool GetEnabledPreview(); + /// Set if the file preview is enabled. + /// Set to true to enable the file preview. + void SetEnabledPreview(bool value); + + /// Get the title. + /// The title. + WString GetTitle(); + /// Set the title. + /// The title. + void SetTitle(const WString& value); + + /// Get the selected file name. + /// The selected file name. + WString GetFileName(); + /// Set the selected file name. + /// The selected file name. + void SetFileName(const WString& value); + + /// Get the default folder. + /// The default folder. + WString GetDirectory(); + /// Set the default folder. + /// The default folder. + void SetDirectory(const WString& value); + + /// Get the default file extension. + /// The default file extension. + WString GetDefaultExtension(); + /// Set the default file extension like "txt". If the user does not specify a file extension, the default file extension will be appended using "." after the file name. + /// The default file extension. + void SetDefaultExtension(const WString& value); + + /// Get the dialog options. + /// The dialog options. + INativeDialogService::FileDialogOptions GetOptions(); + /// Set the dialog options. + /// The dialog options. + void SetOptions(INativeDialogService::FileDialogOptions value); + }; + + /// Open file dialog. + class GuiOpenFileDialog : public GuiFileDialogBase, public Description + { + protected: + collections::List fileNames; + + public: + /// Create a open file dialog. + GuiOpenFileDialog(); + ~GuiOpenFileDialog(); + + /// Get the list to access multiple selected file names. + /// The list to access multiple selected file names. + collections::List& GetFileNames(); + + /// Show the dialog. + /// Returns true if the "Open" button is clicked. + bool ShowDialog(); + }; + + /// Save file dialog. + class GuiSaveFileDialog : public GuiFileDialogBase, public Description + { + public: + /// Create a save file dialog. + GuiSaveFileDialog(); + ~GuiSaveFileDialog(); + + /// Show the dialog. + /// Returns true if the "Save" button is clicked. + bool ShowDialog(); + }; + } + } +} + +#endif + + +/*********************************************************************** +.\CONTROLS\GUILABELCONTROLS.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI::Control System + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_CONTROLS_GUILABELCONTROLS +#define VCZH_PRESENTATION_CONTROLS_GUILABELCONTROLS + + +namespace vl +{ + namespace presentation + { + namespace controls + { + +/*********************************************************************** +Label +***********************************************************************/ + + /// A control to display a text. + class GuiLabel : public GuiControl, public Description + { + GUI_SPECIFY_CONTROL_TEMPLATE_TYPE(LabelTemplate, GuiControl) + protected: + Color textColor; + bool textColorConsisted = true; + + public: + /// Create a control with a specified default theme. + /// The theme name for retriving a default control template. + GuiLabel(theme::ThemeName themeName); + ~GuiLabel(); + + /// Get the text color. + /// The text color. + Color GetTextColor(); + /// Set the text color. + /// The text color. + void SetTextColor(Color value); + }; + } + } +} + +#endif + + +/*********************************************************************** +.\CONTROLS\GUISCROLLCONTROLS.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI::Control System + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_CONTROLS_GUISCROLLCONTROLS +#define VCZH_PRESENTATION_CONTROLS_GUISCROLLCONTROLS + + +namespace vl +{ + namespace presentation + { + + namespace controls + { + +/*********************************************************************** +Scrolls +***********************************************************************/ + + /// A scroll control, which represents a one dimension sub range of a whole range. + class GuiScroll : public GuiControl, public Description + { + GUI_SPECIFY_CONTROL_TEMPLATE_TYPE(ScrollTemplate, GuiControl) + protected: + class CommandExecutor : public Object, public IScrollCommandExecutor + { + protected: + GuiScroll* scroll; + public: + CommandExecutor(GuiScroll* _scroll); + ~CommandExecutor(); + + void SmallDecrease()override; + void SmallIncrease()override; + void BigDecrease()override; + void BigIncrease()override; + + void SetTotalSize(vint value)override; + void SetPageSize(vint value)override; + void SetPosition(vint value)override; + }; + + Ptr commandExecutor; + vint totalSize = 100; + vint pageSize = 10; + vint position = 0; + vint smallMove = 1; + vint bigMove = 10; + bool autoFocus = true; + + void OnActiveAlt()override; + bool IsTabAvailable()override; + void OnKeyDown(compositions::GuiGraphicsComposition* sender, compositions::GuiKeyEventArgs& arguments); + void OnMouseDown(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments); + public: + /// Create a control with a specified default theme. + /// The theme name for retriving a default control template. + GuiScroll(theme::ThemeName themeName); + ~GuiScroll(); + + /// Total size changed event. + compositions::GuiNotifyEvent TotalSizeChanged; + /// Page size changed event. + compositions::GuiNotifyEvent PageSizeChanged; + /// Position changed event. + compositions::GuiNotifyEvent PositionChanged; + /// Small move changed event. + compositions::GuiNotifyEvent SmallMoveChanged; + /// Big move changed event. + compositions::GuiNotifyEvent BigMoveChanged; + + /// Get the total size. + /// The total size. + virtual vint GetTotalSize(); + /// Set the total size. + /// The total size. + virtual void SetTotalSize(vint value); + /// Get the page size. + /// The page size. + virtual vint GetPageSize(); + /// Set the page size. + /// The page size. + virtual void SetPageSize(vint value); + /// Get the position. + /// The position. + virtual vint GetPosition(); + /// Set the position. + /// The position. + virtual void SetPosition(vint value); + /// Get the small move. + /// The small move. + virtual vint GetSmallMove(); + /// Set the small move. + /// The small move. + virtual void SetSmallMove(vint value); + /// Get the big move. + /// The big move. + virtual vint GetBigMove(); + /// Set the big move. + /// The big move. + virtual void SetBigMove(vint value); + + /// Get the minimum possible position. + /// The minimum possible position. + vint GetMinPosition(); + /// Get the maximum possible position. + /// The maximum possible position. + vint GetMaxPosition(); + + /// Test if the scroll gets focus when it is clicked. + /// Returns true if the scroll gets focus when it is clicked + bool GetAutoFocus(); + /// Set if the scroll gets focus when it is clicked. + /// Set to true to make this scroll get focus when it is clicked. + void SetAutoFocus(bool value); + }; + } + } +} + +#endif + + +/*********************************************************************** +.\CONTROLS\GUICONTAINERCONTROLS.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI::Control System + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_CONTROLS_GUICONTAINERCONTROLS +#define VCZH_PRESENTATION_CONTROLS_GUICONTAINERCONTROLS + + +namespace vl +{ + namespace presentation + { + namespace controls + { +/*********************************************************************** +Tab Control +***********************************************************************/ + + class GuiTabPageList; + class GuiTab; + + /// Represnets a tab page control. + class GuiTabPage : public GuiCustomControl, public AggregatableDescription + { + friend class GuiTabPageList; + protected: + GuiTab* tab = nullptr; + + bool IsAltAvailable()override; + public: + /// Create a tab page control with a specified style controller. + /// The theme name for retriving a default control template. + GuiTabPage(theme::ThemeName themeName); + ~GuiTabPage(); + + GuiTab* GetOwnerTab(); + }; + + class GuiTabPageList : public collections::ObservableList + { + protected: + GuiTab* tab; + + bool QueryInsert(vint index, GuiTabPage* const& value)override; + void AfterInsert(vint index, GuiTabPage* const& value)override; + void BeforeRemove(vint index, GuiTabPage* const& value)override; + public: + GuiTabPageList(GuiTab* _tab); + ~GuiTabPageList(); + }; + + /// Represents a container with multiple named tabs. + class GuiTab : public GuiControl, public Description + { + GUI_SPECIFY_CONTROL_TEMPLATE_TYPE(TabTemplate, GuiControl) + friend class GuiTabPageList; + protected: + class CommandExecutor : public Object, public ITabCommandExecutor + { + protected: + GuiTab* tab; + + public: + CommandExecutor(GuiTab* _tab); + ~CommandExecutor(); + + void ShowTab(vint index, bool setFocus)override; + }; + + Ptr commandExecutor; + GuiTabPageList tabPages; + GuiTabPage* selectedPage = nullptr; + + void OnKeyDown(compositions::GuiGraphicsComposition* sender, compositions::GuiKeyEventArgs& arguments); + public: + /// Create a control with a specified default theme. + /// The theme name for retriving a default control template. + GuiTab(theme::ThemeName themeName); + ~GuiTab(); + + /// Selected page changed event. + compositions::GuiNotifyEvent SelectedPageChanged; + + /// Get all pages. + /// All pages. + collections::ObservableList& GetPages(); + + /// Get the selected page. + /// The selected page. + GuiTabPage* GetSelectedPage(); + /// Set the selected page. + /// Returns true if this operation succeeded. + /// The selected page. + bool SetSelectedPage(GuiTabPage* value); + }; + +/*********************************************************************** +Scroll View +***********************************************************************/ + + /// A control with a vertical scroll bar and a horizontal scroll bar to perform partial viewing. + class GuiScrollView : public GuiControl, public Description + { + GUI_SPECIFY_CONTROL_TEMPLATE_TYPE(ScrollViewTemplate, GuiControl) + + using IEventHandler = compositions::IGuiGraphicsEventHandler; + protected: + bool supressScrolling = false; + Ptr hScrollHandler; + Ptr vScrollHandler; + Ptr hWheelHandler; + Ptr vWheelHandler; + Ptr containerBoundsChangedHandler; + bool horizontalAlwaysVisible = true; + bool verticalAlwaysVisible = true; + + void UpdateDisplayFont()override; + + void OnContainerBoundsChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); + void OnHorizontalScroll(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); + void OnVerticalScroll(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); + void OnHorizontalWheel(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments); + void OnVerticalWheel(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments); + void CallUpdateView(); + bool AdjustView(Size fullSize); + + /// Calculate the full size of the content. + /// The full size of the content. + virtual Size QueryFullSize()=0; + /// Update the visible content using a view bounds. The view bounds is in the space from (0,0) to full size. + /// The view bounds. + virtual void UpdateView(Rect viewBounds)=0; + /// Calculate the small move of the scroll bar. + /// The small move of the scroll bar. + virtual vint GetSmallMove(); + /// Calculate the big move of the scroll bar. + /// The big move of the scroll bar. + virtual Size GetBigMove(); + + public: + /// Create a control with a specified style provider. + /// The theme name for retriving a default control template. + GuiScrollView(theme::ThemeName themeName); + ~GuiScrollView(); + + /// Force to update contents and scroll bars. + void CalculateView(); + /// Get the view size. + /// The view size. + Size GetViewSize(); + /// Get the view bounds. + /// The view bounds. + Rect GetViewBounds(); + + /// Get the position of the left-top corner of the view bounds. + /// The view position. + Point GetViewPosition(); + /// Set the position of the left-top corner of the view bounds. + /// The position. + void SetViewPosition(Point value); + + /// Get the horizontal scroll control. + /// The horizontal scroll control. + GuiScroll* GetHorizontalScroll(); + /// Get the vertical scroll control. + /// The vertical scroll control. + GuiScroll* GetVerticalScroll(); + /// Test is the horizontal scroll bar always visible even the content doesn't exceed the view bounds. + /// Returns true if the horizontal scroll bar always visible even the content doesn't exceed the view bounds + bool GetHorizontalAlwaysVisible(); + /// Set is the horizontal scroll bar always visible even the content doesn't exceed the view bounds. + /// Set to true if the horizontal scroll bar always visible even the content doesn't exceed the view bounds + void SetHorizontalAlwaysVisible(bool value); + /// Test is the vertical scroll bar always visible even the content doesn't exceed the view bounds. + /// Returns true if the vertical scroll bar always visible even the content doesn't exceed the view bounds + bool GetVerticalAlwaysVisible(); + /// Set is the vertical scroll bar always visible even the content doesn't exceed the view bounds. + /// Set to true if the vertical scroll bar always visible even the content doesn't exceed the view bounds + void SetVerticalAlwaysVisible(bool value); + }; + + /// A control container with a vertical scroll bar and a horizontal scroll bar to perform partial viewing. When controls are added, removed, moved or resized, the scroll bars will adjust automatically. + class GuiScrollContainer : public GuiScrollView, public Description + { + protected: + bool extendToFullWidth = false; + bool extendToFullHeight = false; + + Size QueryFullSize()override; + void UpdateView(Rect viewBounds)override; + public: + /// Create a control with a specified style provider. + /// The theme name for retriving a default control template. + GuiScrollContainer(theme::ThemeName themeName); + ~GuiScrollContainer(); + + /// Test does the content container always extend its width to fill the scroll container. + /// Return true if the content container always extend its width to fill the scroll container. + bool GetExtendToFullWidth(); + /// Set does the content container always extend its width to fill the scroll container. + /// Set to true if the content container always extend its width to fill the scroll container. + void SetExtendToFullWidth(bool value); + + /// Test does the content container always extend its height to fill the scroll container. + /// Return true if the content container always extend its height to fill the scroll container. + bool GetExtendToFullHeight(); + /// Set does the content container always extend its height to fill the scroll container. + /// Set to true if the content container always extend its height to fill the scroll container. + void SetExtendToFullHeight(bool value); + }; + } + } +} + +#endif + + /*********************************************************************** .\CONTROLS\GUIWINDOWCONTROLS.H ***********************************************************************/ @@ -9380,1772 +11895,18 @@ extern void GuiApplicationMain(); #endif /*********************************************************************** -.\CONTROLS\TEMPLATES\GUICOMMONTEMPLATES.H +.\CONTROLS\INCLUDEFORWARD.H ***********************************************************************/ /*********************************************************************** Vczh Library++ 3.0 Developer: Zihan Chen(vczh) -GacUI::Template System +GacUI::Application Framework Interfaces: ***********************************************************************/ -#ifndef VCZH_PRESENTATION_CONTROLS_TEMPLATES_GUICOMMONTEMPLATES -#define VCZH_PRESENTATION_CONTROLS_TEMPLATES_GUICOMMONTEMPLATES - - -namespace vl -{ - namespace presentation - { - namespace templates - { - -/*********************************************************************** -GuiCommonDatePickerLook -***********************************************************************/ - - class GuiCommonDatePickerLook : public GuiTemplate, public Description - { - protected: - static const vint DaysOfWeek = 7; - static const vint DayRows = 6; - static const vint DayRowStart = 2; - static const vint YearFirst = 1900; - static const vint YearLast = 2099; - - Color backgroundColor; - Color primaryTextColor; - Color secondaryTextColor; - DateTime currentDate; - Locale dateLocale; - FontProperties font; - - TemplateProperty dateButtonTemplate; - TemplateProperty dateTextListTemplate; - TemplateProperty dateComboBoxTemplate; - - controls::IDatePickerCommandExecutor* commands = nullptr; - bool preventComboEvent = false; - bool preventButtonEvent = false; - - controls::GuiComboBoxListControl* comboYear; - controls::GuiTextList* listYears; - controls::GuiComboBoxListControl* comboMonth; - controls::GuiTextList* listMonths; - collections::Array labelDaysOfWeek; - collections::Array buttonDays; - collections::Array labelDays; - collections::Array dateDays; - - void SetDay(const DateTime& day, vint& index, vint monthOffset); - void DisplayMonth(vint year, vint month); - void SelectDay(vint day); - - void comboYearMonth_SelectedIndexChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); - void buttonDay_SelectedChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); - - public: - GuiCommonDatePickerLook(Color _backgroundColor, Color _primaryTextColor, Color _secondaryTextColor); - ~GuiCommonDatePickerLook(); - - compositions::GuiNotifyEvent DateChanged; - - controls::IDatePickerCommandExecutor* GetCommands(); - void SetCommands(controls::IDatePickerCommandExecutor* value); - TemplateProperty GetDateButtonTemplate(); - void SetDateButtonTemplate(const TemplateProperty& value); - TemplateProperty GetDateTextListTemplate(); - void SetDateTextListTemplate(const TemplateProperty& value); - TemplateProperty GetDateComboBoxTemplate(); - void SetDateComboBoxTemplate(const TemplateProperty& value); - - const Locale& GetDateLocale(); - void SetDateLocale(const Locale& value); - const DateTime& GetDate(); - void SetDate(const DateTime& value); - const FontProperties& GetFont(); - void SetFont(const FontProperties& value); - }; - -/*********************************************************************** -GuiCommonScrollViewLook -***********************************************************************/ - - class GuiCommonScrollViewLook : public GuiTemplate, public Description - { - protected: - controls::GuiScroll* horizontalScroll = nullptr; - controls::GuiScroll* verticalScroll = nullptr; - compositions::GuiTableComposition* tableComposition = nullptr; - compositions::GuiCellComposition* containerCellComposition = nullptr; - compositions::GuiBoundsComposition* containerComposition = nullptr; - - vint defaultScrollSize = 12; - TemplateProperty hScrollTemplate; - TemplateProperty vScrollTemplate; - - void UpdateTable(); - void hScroll_OnVisibleChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); - void vScroll_OnVisibleChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); - public: - GuiCommonScrollViewLook(vint _defaultScrollSize); - ~GuiCommonScrollViewLook(); - - controls::GuiScroll* GetHScroll(); - controls::GuiScroll* GetVScroll(); - compositions::GuiGraphicsComposition* GetContainerComposition(); - - TemplateProperty GetHScrollTemplate(); - void SetHScrollTemplate(const TemplateProperty& value); - TemplateProperty GetVScrollTemplate(); - void SetVScrollTemplate(const TemplateProperty& value); - }; - -/*********************************************************************** -GuiCommonScrollBehavior -***********************************************************************/ - - class GuiCommonScrollBehavior : public controls::GuiComponent, public Description - { - protected: - bool dragging = false; - Point location = { 0,0 }; - GuiScrollTemplate* scrollTemplate = nullptr; - - void SetScroll(vint totalPixels, vint newOffset); - void AttachHandle(compositions::GuiGraphicsComposition* handle); - public: - GuiCommonScrollBehavior(); - ~GuiCommonScrollBehavior(); - - void AttachScrollTemplate(GuiScrollTemplate* value); - void AttachDecreaseButton(controls::GuiButton* button); - void AttachIncreaseButton(controls::GuiButton* button); - void AttachHorizontalScrollHandle(compositions::GuiPartialViewComposition* partialView); - void AttachVerticalScrollHandle(compositions::GuiPartialViewComposition* partialView); - void AttachHorizontalTrackerHandle(compositions::GuiPartialViewComposition* partialView); - void AttachVerticalTrackerHandle(compositions::GuiPartialViewComposition* partialView); - - vint GetHorizontalTrackerHandlerPosition(compositions::GuiBoundsComposition* handle, vint totalSize, vint pageSize, vint position); - vint GetVerticalTrackerHandlerPosition(compositions::GuiBoundsComposition* handle, vint totalSize, vint pageSize, vint position); - }; - } - } -} - -#endif - -/*********************************************************************** -.\CONTROLS\TEMPLATES\GUITHEMESTYLEFACTORY.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI::Control Styles::Common Style Helpers - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_CONTROLS_GUITHEMESTYLEFACTORY -#define VCZH_PRESENTATION_CONTROLS_GUITHEMESTYLEFACTORY - - -namespace vl -{ - namespace presentation - { - namespace theme - { -#define GUI_CONTROL_TEMPLATE_TYPES(F) \ - F(WindowTemplate, Window) \ - F(ControlTemplate, CustomControl) \ - F(WindowTemplate, Tooltip) \ - F(LabelTemplate, Label) \ - F(LabelTemplate, ShortcutKey) \ - F(ScrollViewTemplate, ScrollView) \ - F(ControlTemplate, GroupBox) \ - F(TabTemplate, Tab) \ - F(ComboBoxTemplate, ComboBox) \ - F(MultilineTextBoxTemplate, MultilineTextBox) \ - F(SinglelineTextBoxTemplate, SinglelineTextBox) \ - F(DocumentViewerTemplate, DocumentViewer) \ - F(DocumentLabelTemplate, DocumentLabel) \ - F(DocumentLabelTemplate, DocumentTextBox) \ - F(ListViewTemplate, ListView) \ - F(TreeViewTemplate, TreeView) \ - F(TextListTemplate, TextList) \ - F(SelectableButtonTemplate, ListItemBackground) \ - F(SelectableButtonTemplate, TreeItemExpander) \ - F(SelectableButtonTemplate, CheckTextListItem) \ - F(SelectableButtonTemplate, RadioTextListItem) \ - F(MenuTemplate, Menu) \ - F(ControlTemplate, MenuBar) \ - F(ControlTemplate, MenuSplitter) \ - F(ToolstripButtonTemplate, MenuBarButton) \ - F(ToolstripButtonTemplate, MenuItemButton) \ - F(ControlTemplate, ToolstripToolBar) \ - F(ToolstripButtonTemplate, ToolstripButton) \ - F(ToolstripButtonTemplate, ToolstripDropdownButton) \ - F(ToolstripButtonTemplate, ToolstripSplitButton) \ - F(ControlTemplate, ToolstripSplitter) \ - F(RibbonTabTemplate, RibbonTab) \ - F(RibbonGroupTemplate, RibbonGroup) \ - F(RibbonIconLabelTemplate, RibbonIconLabel) \ - F(RibbonIconLabelTemplate, RibbonSmallIconLabel) \ - F(RibbonButtonsTemplate, RibbonButtons) \ - F(RibbonToolstripsTemplate, RibbonToolstrips) \ - F(RibbonGalleryTemplate, RibbonGallery) \ - F(RibbonToolstripMenuTemplate, RibbonToolstripMenu) \ - F(RibbonGalleryListTemplate, RibbonGalleryList) \ - F(TextListTemplate, RibbonGalleryItemList) \ - F(ToolstripButtonTemplate, RibbonSmallButton) \ - F(ToolstripButtonTemplate, RibbonSmallDropdownButton) \ - F(ToolstripButtonTemplate, RibbonSmallSplitButton) \ - F(ToolstripButtonTemplate, RibbonLargeButton) \ - F(ToolstripButtonTemplate, RibbonLargeDropdownButton) \ - F(ToolstripButtonTemplate, RibbonLargeSplitButton) \ - F(ControlTemplate, RibbonSplitter) \ - F(ControlTemplate, RibbonToolstripHeader) \ - F(ButtonTemplate, Button) \ - F(SelectableButtonTemplate, CheckBox) \ - F(SelectableButtonTemplate, RadioButton) \ - F(DatePickerTemplate, DatePicker) \ - F(DateComboBoxTemplate, DateComboBox) \ - F(ScrollTemplate, HScroll) \ - F(ScrollTemplate, VScroll) \ - F(ScrollTemplate, HTracker) \ - F(ScrollTemplate, VTracker) \ - F(ScrollTemplate, ProgressBar) \ - - enum class ThemeName - { - Unknown, -#define GUI_DEFINE_THEME_NAME(TEMPLATE, CONTROL) CONTROL, - GUI_CONTROL_TEMPLATE_TYPES(GUI_DEFINE_THEME_NAME) -#undef GUI_DEFINE_THEME_NAME - }; - - /// Theme interface. A theme creates appropriate style controllers or style providers for default controls. Call [M:vl.presentation.theme.GetCurrentTheme] to access this interface. - class ITheme : public virtual IDescriptable, public Description - { - public: - virtual TemplateProperty CreateStyle(ThemeName themeName) = 0; - }; - - class Theme; - - /// Partial control template collections. [F:vl.presentation.theme.GetCurrentTheme] will returns an object, which walks through multiple registered [T:vl.presentation.theme.ThemeTemplates] to create a correct template object for a control. - class ThemeTemplates : public controls::GuiInstanceRootObject, public AggregatableDescription - { - friend class Theme; - protected: - ThemeTemplates* previous = nullptr; - ThemeTemplates* next = nullptr; - - controls::GuiControlHost* GetControlHostForInstance()override; - public: - ~ThemeTemplates(); - - WString Name; - -#define GUI_DEFINE_ITEM_PROPERTY(TEMPLATE, CONTROL) TemplateProperty CONTROL; - GUI_CONTROL_TEMPLATE_TYPES(GUI_DEFINE_ITEM_PROPERTY) -#undef GUI_DEFINE_ITEM_PROPERTY - }; - - /// Get the current theme style factory object. Call or to change the default theme. - /// The current theme style factory object. - extern ITheme* GetCurrentTheme(); - extern void InitializeTheme(); - extern void FinalizeTheme(); - /// Register a control template collection object. - /// Returns true if this operation succeeded. - /// The control template collection object. - extern bool RegisterTheme(Ptr theme); - /// Unregister a control template collection object. - /// The registered object. Returns null if it does not exist. - /// The name of the theme. - extern Ptr UnregisterTheme(const WString& name); - } - } -} - -#endif - -/*********************************************************************** -.\RESOURCES\GUIRESOURCEMANAGER.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI Reflection: Instance Loader - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_REFLECTION_GUIRESOURCEMANAGER -#define VCZH_PRESENTATION_REFLECTION_GUIRESOURCEMANAGER - - -namespace vl -{ - namespace presentation - { - -/*********************************************************************** -IGuiResourceManager -***********************************************************************/ - - class GuiResourceClassNameRecord : public Object, public Description - { - public: - collections::List classNames; - collections::Dictionary> classResources; - }; - - class IGuiResourceManager : public IDescriptable, public Description - { - public: - virtual void SetResource(Ptr resource, GuiResourceError::List& errors, GuiResourceUsage usage = GuiResourceUsage::DataOnly) = 0; - virtual Ptr GetResource(const WString& name) = 0; - virtual Ptr GetResourceFromClassName(const WString& classFullName) = 0; - virtual void UnloadResource(const WString& name) = 0; - virtual void LoadResourceOrPending(stream::IStream& stream, GuiResourceError::List& errors, GuiResourceUsage usage = GuiResourceUsage::DataOnly) = 0; - virtual void LoadResourceOrPending(stream::IStream& stream, GuiResourceUsage usage = GuiResourceUsage::DataOnly) = 0; - virtual void GetPendingResourceNames(collections::List& names) = 0; - }; - - extern IGuiResourceManager* GetResourceManager(); - } -} - -#endif - -/*********************************************************************** -.\GRAPHICSCOMPOSITION\GUIGRAPHICSTABLECOMPOSITION.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI::Composition System - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_COMPOSITION_GUIGRAPHICSTABLECOMPOSITION -#define VCZH_PRESENTATION_COMPOSITION_GUIGRAPHICSTABLECOMPOSITION - - -namespace vl -{ - namespace presentation - { - namespace compositions - { - -/*********************************************************************** -Table Compositions -***********************************************************************/ - - /// - /// Represnets a sizing configuration for a row or a column. - /// - struct GuiCellOption - { - /// Sizing algorithm - enum ComposeType - { - /// Set the size to an absolute value. - Absolute, - /// Set the size to a percentage number of the whole table. - Percentage, - /// Set the size to the minimum size of the cell element. - MinSize, - }; - - /// Sizing algorithm - ComposeType composeType; - /// The absolute size when is ::Absolute. - vint absolute; - /// The percentage number when is ::Percentage. - double percentage; - - GuiCellOption() - :composeType(Absolute) - ,absolute(20) - ,percentage(0) - { - } - - bool operator==(const GuiCellOption& value){return false;} - bool operator!=(const GuiCellOption& value){return true;} - - /// Creates an absolute sizing option - /// The created option. - /// The absolute size. - static GuiCellOption AbsoluteOption(vint value) - { - GuiCellOption option; - option.composeType=Absolute; - option.absolute=value; - return option; - } - - /// Creates an percantage sizing option - /// The created option. - /// The percentage number. - static GuiCellOption PercentageOption(double value) - { - GuiCellOption option; - option.composeType=Percentage; - option.percentage=value; - return option; - } - - /// Creates an minimum sizing option - /// The created option. - static GuiCellOption MinSizeOption() - { - GuiCellOption option; - option.composeType=MinSize; - return option; - } - }; - - /// - /// Represents a table composition. - /// - class GuiTableComposition : public GuiBoundsComposition, public Description - { - friend class GuiCellComposition; - friend class GuiTableSplitterCompositionBase; - friend class GuiRowSplitterComposition; - friend class GuiColumnSplitterComposition; - protected: - vint rows; - vint columns; - vint cellPadding; - bool borderVisible; - vint rowExtending; - vint columnExtending; - collections::Array rowOptions; - collections::Array columnOptions; - collections::Array cellCompositions; - - collections::Array cellBounds; - collections::Array rowOffsets; - collections::Array columnOffsets; - collections::Array rowSizes; - collections::Array columnSizes; - - Size tableContentMinSize; - - vint GetSiteIndex(vint _rows, vint _columns, vint _row, vint _column); - void SetSitedCell(vint _row, vint _column, GuiCellComposition* cell); - - void UpdateCellBoundsInternal( - collections::Array& dimSizes, - vint& dimSize, - vint& dimSizeWithPercentage, - collections::Array& dimOptions, - vint GuiTableComposition::* dim1, - vint GuiTableComposition::* dim2, - vint (*getSize)(Size), - vint (*getLocation)(GuiCellComposition*), - vint (*getSpan)(GuiCellComposition*), - vint (*getRow)(vint, vint), - vint (*getCol)(vint, vint), - vint maxPass - ); - void UpdateCellBoundsPercentages( - collections::Array& dimSizes, - vint dimSize, - vint maxDimSize, - collections::Array& dimOptions - ); - vint UpdateCellBoundsOffsets( - collections::Array& offsets, - collections::Array& sizes, - vint max - ); - - void OnRenderContextChanged()override; - public: - GuiTableComposition(); - ~GuiTableComposition(); - - /// Event that will be raised with row numbers, column numbers or options are changed. - compositions::GuiNotifyEvent ConfigChanged; - - /// Get the number of rows. - /// The number of rows. - vint GetRows(); - /// Get the number of columns. - /// The number of columns. - vint GetColumns(); - /// Change the number of rows and columns. - /// Returns true if this operation succeeded. - /// The number of rows. - /// The number of columns. - bool SetRowsAndColumns(vint _rows, vint _columns); - /// Get the cell composition that covers the specified cell location. - /// The cell composition that covers the specified cell location. - /// The number of rows. - /// The number of columns. - GuiCellComposition* GetSitedCell(vint _row, vint _column); - - /// Get the sizing option of the specified row. - /// The sizing option of the specified row. - /// The specified row number. - GuiCellOption GetRowOption(vint _row); - /// Set the sizing option of the specified row. - /// The specified row number. - /// The sizing option of the specified row. - void SetRowOption(vint _row, GuiCellOption option); - /// Get the sizing option of the specified column. - /// The sizing option of the specified column. - /// The specified column number. - GuiCellOption GetColumnOption(vint _column); - /// Set the sizing option of the specified column. - /// The specified column number. - /// The sizing option of the specified column. - void SetColumnOption(vint _column, GuiCellOption option); - - /// Get the cell padding. A cell padding is the distance between a table client area and a cell, or between two cells. - /// The cell padding. - vint GetCellPadding(); - /// Set the cell padding. A cell padding is the distance between a table client area and a cell, or between two cells. - /// The cell padding. - void SetCellPadding(vint value); - /// Get the border visibility. - /// Returns true means the border thickness equals to the cell padding, otherwise zero. - bool GetBorderVisible(); - /// Set the border visibility. - /// Set to true to let the border thickness equal to the cell padding, otherwise zero. - void SetBorderVisible(bool value); - /// Get the cell area in the space of the table's parent composition's client area. - /// The cell area. - Rect GetCellArea(); - /// Update the sizing of the table and cells after all rows' and columns' sizing options are prepared. - void UpdateCellBounds(); - - void ForceCalculateSizeImmediately()override; - Size GetMinPreferredClientSize()override; - Rect GetBounds()override; - }; - - /// - /// Represents a cell composition of a . - /// - class GuiCellComposition : public GuiGraphicsSite, public Description - { - friend class GuiTableComposition; - protected: - vint row; - vint rowSpan; - vint column; - vint columnSpan; - GuiTableComposition* tableParent; - Size lastPreferredSize; - - void ClearSitedCells(GuiTableComposition* table); - void SetSitedCells(GuiTableComposition* table); - void ResetSiteInternal(); - bool SetSiteInternal(vint _row, vint _column, vint _rowSpan, vint _columnSpan); - void OnParentChanged(GuiGraphicsComposition* oldParent, GuiGraphicsComposition* newParent)override; - void OnTableRowsAndColumnsChanged(); - public: - GuiCellComposition(); - ~GuiCellComposition(); - - /// Get the owner table composition. - /// The owner table composition. - GuiTableComposition* GetTableParent(); - - /// Get the row number for this cell composition. - /// The row number for this cell composition. - vint GetRow(); - /// Get the total numbers of acrossed rows for this cell composition. - /// The total numbers of acrossed rows for this cell composition. - vint GetRowSpan(); - /// Get the column number for this cell composition. - /// The column number for this cell composition. - vint GetColumn(); - /// Get the total numbers of acrossed columns for this cell composition. - /// The total numbers of acrossed columns for this cell composition. - vint GetColumnSpan(); - /// Set the position for this cell composition in the table. - /// Returns true if this operation succeeded. - /// The row number for this cell composition. - /// The column number for this cell composition. - /// The total numbers of acrossed rows for this cell composition. - /// The total numbers of acrossed columns for this cell composition. - bool SetSite(vint _row, vint _column, vint _rowSpan, vint _columnSpan); - - Rect GetBounds()override; - }; - - class GuiTableSplitterCompositionBase : public GuiGraphicsSite, public Description - { - protected: - GuiTableComposition* tableParent; - - bool dragging; - Point draggingPoint; - - void OnParentChanged(GuiGraphicsComposition* oldParent, GuiGraphicsComposition* newParent)override; - void OnLeftButtonDown(GuiGraphicsComposition* sender, GuiMouseEventArgs& arguments); - void OnLeftButtonUp(GuiGraphicsComposition* sender, GuiMouseEventArgs& arguments); - - void OnMouseMoveHelper( - vint cellsBefore, - vint GuiTableComposition::* cells, - collections::Array& cellSizes, - vint offset, - GuiCellOption(GuiTableComposition::*getOption)(vint), - void(GuiTableComposition::*setOption)(vint, GuiCellOption) - ); - - Rect GetBoundsHelper( - vint cellsBefore, - vint GuiTableComposition::* cells, - vint(Rect::* dimSize)()const, - collections::Array& cellOffsets, - vint Rect::* dimU1, - vint Rect::* dimU2, - vint Rect::* dimV1, - vint Rect::* dimV2 - ); - public: - GuiTableSplitterCompositionBase(); - ~GuiTableSplitterCompositionBase(); - - /// Get the owner table composition. - /// The owner table composition. - GuiTableComposition* GetTableParent(); - }; - - /// - /// Represents a row splitter composition of a . - /// - class GuiRowSplitterComposition : public GuiTableSplitterCompositionBase, public Description - { - protected: - vint rowsToTheTop; - - void OnMouseMove(GuiGraphicsComposition* sender, GuiMouseEventArgs& arguments); - public: - GuiRowSplitterComposition(); - ~GuiRowSplitterComposition(); - - /// Get the number of rows that above the splitter. - /// The number of rows that above the splitter. - vint GetRowsToTheTop(); - /// Set the number of rows that above the splitter. - /// The number of rows that above the splitter - void SetRowsToTheTop(vint value); - - Rect GetBounds()override; - }; - - /// - /// Represents a column splitter composition of a . - /// - class GuiColumnSplitterComposition : public GuiTableSplitterCompositionBase, public Description - { - protected: - vint columnsToTheLeft; - - void OnMouseMove(GuiGraphicsComposition* sender, GuiMouseEventArgs& arguments); - public: - GuiColumnSplitterComposition(); - ~GuiColumnSplitterComposition(); - - /// Get the number of columns that before the splitter. - /// The number of columns that before the splitter. - vint GetColumnsToTheLeft(); - /// Set the number of columns that before the splitter. - /// The number of columns that before the splitter - void SetColumnsToTheLeft(vint value); - - Rect GetBounds()override; - }; - } - } -} - -#endif - -/*********************************************************************** -.\GRAPHICSCOMPOSITION\GUIGRAPHICSSTACKCOMPOSITION.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI::Composition System - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_COMPOSITION_GUIGRAPHICSSTACKCOMPOSITION -#define VCZH_PRESENTATION_COMPOSITION_GUIGRAPHICSSTACKCOMPOSITION - - -namespace vl -{ - namespace presentation - { - namespace compositions - { - -/*********************************************************************** -Stack Compositions -***********************************************************************/ - - /// - /// Represents a stack composition. - /// - class GuiStackComposition : public GuiBoundsComposition, public Description - { - friend class GuiStackItemComposition; - - typedef collections::List ItemCompositionList; - public: - /// Stack item layout direction. - enum Direction - { - /// Stack items is layouted from left to right. - Horizontal, - /// Stack items is layouted from top to bottom. - Vertical, - /// Stack items is layouted from right to left. - ReversedHorizontal, - /// Stack items is layouted from bottom to top. - ReversedVertical, - }; - protected: - Direction direction = Horizontal; - ItemCompositionList stackItems; - GuiStackItemComposition* ensuringVisibleStackItem = nullptr; - - vint padding = 0; - vint adjustment = 0; - Margin extraMargin; - - collections::Array stackItemBounds; - Size stackItemTotalSize; - Rect previousBounds; - - void UpdateStackItemBounds(); - void EnsureStackItemVisible(); - void OnBoundsChanged(GuiGraphicsComposition* sender, GuiEventArgs& arguments); - void OnChildInserted(GuiGraphicsComposition* child)override; - void OnChildRemoved(GuiGraphicsComposition* child)override; - public: - GuiStackComposition(); - ~GuiStackComposition(); - - /// Get all stack items inside the stack composition. - /// All stack items inside the stack composition. - const ItemCompositionList& GetStackItems(); - /// Insert a stack item at a specified position. - /// Returns true if this operation succeeded. - /// The position. - /// The statck item to insert. - bool InsertStackItem(vint index, GuiStackItemComposition* item); - - /// Get the stack item layout direction. - /// The stack item layout direction. - Direction GetDirection(); - /// Set the stack item layout direction. - /// The stack item layout direction. - void SetDirection(Direction value); - /// Get the stack item padding. - /// The stack item padding. - vint GetPadding(); - /// Set the stack item padding. - /// The stack item padding. - void SetPadding(vint value); - - void ForceCalculateSizeImmediately()override; - Size GetMinPreferredClientSize()override; - Rect GetBounds()override; - - /// Get the extra margin inside the stack composition. - /// The extra margin inside the stack composition. - Margin GetExtraMargin(); - /// Set the extra margin inside the stack composition. - /// The extra margin inside the stack composition. - void SetExtraMargin(Margin value); - /// Test is any stack item clipped in the stack direction. - /// Returns true if any stack item is clipped. - bool IsStackItemClipped(); - /// Make an item visible as complete as possible. - /// Returns true if this operation succeeded. - /// The index of the item. - bool EnsureVisible(vint index); - }; - - /// - /// Represents a stack item composition of a . - /// - class GuiStackItemComposition : public GuiGraphicsSite, public Description - { - friend class GuiStackComposition; - protected: - GuiStackComposition* stackParent; - Rect bounds; - Margin extraMargin; - - void OnParentChanged(GuiGraphicsComposition* oldParent, GuiGraphicsComposition* newParent)override; - Size GetMinSize(); - public: - GuiStackItemComposition(); - ~GuiStackItemComposition(); - - bool IsSizeAffectParent()override; - Rect GetBounds()override; - /// Set the expected bounds of a stack item. In most of the cases only the size of the bounds is used. - /// The expected bounds of a stack item. - void SetBounds(Rect value); - - /// Get the extra margin for this stack item. An extra margin is used to enlarge the bounds of the stack item, but only the non-extra part will be used for deciding the stack item layout. - /// The extra margin for this stack item. - Margin GetExtraMargin(); - /// Set the extra margin for this stack item. An extra margin is used to enlarge the bounds of the stack item, but only the non-extra part will be used for deciding the stack item layout. - /// The extra margin for this stack item. - void SetExtraMargin(Margin value); - }; - } - } -} - -#endif - -/*********************************************************************** -.\GRAPHICSCOMPOSITION\GUIGRAPHICSFLOWCOMPOSITION.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI::Composition System - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_COMPOSITION_GUIGRAPHICSFLOWCOMPOSITION -#define VCZH_PRESENTATION_COMPOSITION_GUIGRAPHICSFLOWCOMPOSITION - - -namespace vl -{ - namespace presentation - { - namespace compositions - { -/*********************************************************************** -Flow Compositions -***********************************************************************/ - - /// - /// Alignment for a row in a flow layout - /// - enum class FlowAlignment - { - /// Align to the left. - Left, - /// Align to the center. - Center, - /// Extend to the entire row. - Extend, - }; - - /// - /// Represents a flow composition. - /// - class GuiFlowComposition : public GuiBoundsComposition, public Description - { - friend class GuiFlowItemComposition; - - typedef collections::List ItemCompositionList; - protected: - Margin extraMargin; - vint rowPadding = 0; - vint columnPadding = 0; - FlowAlignment alignment = FlowAlignment::Left; - Ptr axis; - - ItemCompositionList flowItems; - collections::Array flowItemBounds; - Rect bounds; - vint minHeight = 0; - bool needUpdate = false; - - void UpdateFlowItemBounds(bool forceUpdate); - void OnBoundsChanged(GuiGraphicsComposition* sender, GuiEventArgs& arguments); - void OnChildInserted(GuiGraphicsComposition* child)override; - void OnChildRemoved(GuiGraphicsComposition* child)override; - public: - GuiFlowComposition(); - ~GuiFlowComposition(); - - /// Get all flow items inside the flow composition. - /// All flow items inside the flow composition. - const ItemCompositionList& GetFlowItems(); - /// Insert a flow item at a specified position. - /// Returns true if this operation succeeded. - /// The position. - /// The flow item to insert. - bool InsertFlowItem(vint index, GuiFlowItemComposition* item); - - /// Get the extra margin inside the flow composition. - /// The extra margin inside the flow composition. - Margin GetExtraMargin(); - /// Set the extra margin inside the flow composition. - /// The extra margin inside the flow composition. - void SetExtraMargin(Margin value); - - /// Get the distance between rows. - /// The distance between rows. - vint GetRowPadding(); - /// Set the distance between rows. - /// The distance between rows. - void SetRowPadding(vint value); - - /// Get the distance between columns. - /// The distance between columns. - vint GetColumnPadding(); - /// Set the distance between columns. - /// The distance between columns. - void SetColumnPadding(vint value); - - /// Get the axis of the layout. - /// The axis. - Ptr GetAxis(); - /// Set the axis of the layout. - /// The axis. - void SetAxis(Ptr value); - - /// Get the alignment for rows. - /// The alignment. - FlowAlignment GetAlignment(); - /// Set the alignment for rows. - /// The alignment. - void SetAlignment(FlowAlignment value); - - void ForceCalculateSizeImmediately()override; - Size GetMinPreferredClientSize()override; - Rect GetBounds()override; - }; - - /// - /// Represnets a base line configuration for a flow item. - /// - struct GuiFlowOption - { - /// Base line calculation algorithm - enum BaselineType - { - /// By percentage of the height from the top. - Percentage, - /// By a distance from the top. - FromTop, - /// By a distance from the bottom. - FromBottom, - }; - - /// The base line calculation algorithm. - BaselineType baseline = FromBottom; - /// The percentage value. - double percentage = 0.0; - /// The distance value. - vint distance = 0; - }; - - /// - /// Represents a flow item composition of a . - /// - class GuiFlowItemComposition : public GuiGraphicsSite, public Description - { - friend class GuiFlowComposition; - protected: - GuiFlowComposition* flowParent; - Rect bounds; - Margin extraMargin; - GuiFlowOption option; - - void OnParentChanged(GuiGraphicsComposition* oldParent, GuiGraphicsComposition* newParent)override; - Size GetMinSize(); - public: - GuiFlowItemComposition(); - ~GuiFlowItemComposition(); - - bool IsSizeAffectParent()override; - Rect GetBounds()override; - void SetBounds(Rect value); - - /// Get the extra margin for this flow item. An extra margin is used to enlarge the bounds of the flow item, but only the non-extra part will be used for deciding the flow item layout. - /// The extra margin for this flow item. - Margin GetExtraMargin(); - /// Set the extra margin for this flow item. An extra margin is used to enlarge the bounds of the flow item, but only the non-extra part will be used for deciding the flow item layout. - /// The extra margin for this flow item. - void SetExtraMargin(Margin value); - - /// Get the base line option for this flow item. - /// The base line option. - GuiFlowOption GetFlowOption(); - /// Set the base line option for this flow item. - /// The base line option. - void SetFlowOption(GuiFlowOption value); - }; - } - } -} - -#endif - - -/*********************************************************************** -.\GRAPHICSCOMPOSITION\GUIGRAPHICSSPECIALIZEDCOMPOSITION.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI::Composition System - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_COMPOSITION_GUIGRAPHICSSPECIALIZEDCOMPOSITION -#define VCZH_PRESENTATION_COMPOSITION_GUIGRAPHICSSPECIALIZEDCOMPOSITION - - -namespace vl -{ - namespace presentation - { - namespace compositions - { - -/*********************************************************************** -Specialized Compositions -***********************************************************************/ - - /// - /// Represents a composition that is aligned to one border of the parent composition. - /// - class GuiSideAlignedComposition : public GuiGraphicsSite, public Description - { - public: - /// The border to align. - enum Direction - { - /// The left border. - Left, - /// The top border. - Top, - /// The right border. - Right, - /// The bottom border. - Bottom, - }; - protected: - Direction direction; - vint maxLength; - double maxRatio; - public: - GuiSideAlignedComposition(); - ~GuiSideAlignedComposition(); - - /// Get the border to align. - /// The border to align. - Direction GetDirection(); - /// Set the border to align. - /// The border to align. - void SetDirection(Direction value); - /// Get the maximum length of this composition. - /// The maximum length of this composition. - vint GetMaxLength(); - /// Set the maximum length of this composition. - /// The maximum length of this composition. - void SetMaxLength(vint value); - /// Get the maximum ratio to limit the size according to the size of the parent. - /// The maximum ratio to limit the size according to the size of the parent. - double GetMaxRatio(); - /// Set the maximum ratio to limit the size according to the size of the parent. - /// The maximum ratio to limit the size according to the size of the parent. - void SetMaxRatio(double value); - - bool IsSizeAffectParent()override; - Rect GetBounds()override; - }; - - /// - /// Represents a composition that its location and size are decided by the client area of the parent composition by setting ratios. - /// - class GuiPartialViewComposition : public GuiGraphicsSite, public Description - { - protected: - double wRatio; - double wPageSize; - double hRatio; - double hPageSize; - - public: - GuiPartialViewComposition(); - ~GuiPartialViewComposition(); - - /// Get the width ratio to decided the horizontal location. Value in [0, 1-pageSize]. - /// The width ratio to decided the horizontal location. - double GetWidthRatio(); - /// Get the page size to decide the horizontal size. Value in [0, 1]. - /// The page size to decide the horizontal size. - double GetWidthPageSize(); - /// Get the height ratio to decided the vertical location. Value in [0, 1-pageSize]. - /// The height ratio to decided the vertical location. - double GetHeightRatio(); - /// Get the page size to decide the vertical size. Value in [0, 1]. - /// The page size to decide the vertical size. - double GetHeightPageSize(); - /// Set the width ratio to decided the horizontal location. Value in [0, 1-pageSize]. - /// The width ratio to decided the horizontal location. - void SetWidthRatio(double value); - /// Set the page size to decide the horizontal size. Value in [0, 1]. - /// The page size to decide the horizontal size. - void SetWidthPageSize(double value); - /// Set the height ratio to decided the vertical location. Value in [0, 1-pageSize]. - /// The height ratio to decided the vertical location. - void SetHeightRatio(double value); - /// Set the page size to decide the vertical size. Value in [0, 1]. - /// The page size to decide the vertical size. - void SetHeightPageSize(double value); - - bool IsSizeAffectParent()override; - Rect GetBounds()override; - }; - } - } -} - -#endif - -/*********************************************************************** -.\GRAPHICSCOMPOSITION\GUIGRAPHICSRESPONSIVECOMPOSITION.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI::Composition System - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_COMPOSITION_GUIGRAPHICSRESPONSIVECOMPOSITION -#define VCZH_PRESENTATION_COMPOSITION_GUIGRAPHICSRESPONSIVECOMPOSITION - - -namespace vl -{ - namespace presentation - { - namespace compositions - { - -/*********************************************************************** -GuiResponsiveCompositionBase -***********************************************************************/ - - enum class ResponsiveDirection - { - Horizontal = 1, - Vertical = 2, - Both = 3, - }; - - /// Base class for responsive layout compositions. - class GuiResponsiveCompositionBase abstract : public GuiBoundsComposition, public Description - { - protected: - GuiResponsiveCompositionBase* responsiveParent = nullptr; - ResponsiveDirection direction = ResponsiveDirection::Both; - - void OnParentLineChanged()override; - virtual void OnResponsiveChildInserted(GuiResponsiveCompositionBase* child); - virtual void OnResponsiveChildRemoved(GuiResponsiveCompositionBase* child); - virtual void OnResponsiveChildLevelUpdated(); - - public: - GuiResponsiveCompositionBase(); - ~GuiResponsiveCompositionBase(); - - /// LevelCount changed event. - GuiNotifyEvent LevelCountChanged; - /// CurrentLevel chagned event. - GuiNotifyEvent CurrentLevelChanged; - - /// Get the level count. A level count represents how many views this composition carries. - /// The level count. - virtual vint GetLevelCount() = 0; - /// Get the current level. Zero is the view with the smallest size. - /// The current level. - virtual vint GetCurrentLevel() = 0; - /// Switch to a smaller view. - /// Returns true if this operation succeeded. - virtual bool LevelDown() = 0; - /// Switch to a larger view. - /// Returns true if this operation succeeded. - virtual bool LevelUp() = 0; - - /// Get all supported directions. If all directions of a child [T:vl.presentation.compositions.GuiResponsiveCompositionBase] are not supported, its view will not be changed when the parent composition changes its view . - /// All supported directions. - ResponsiveDirection GetDirection(); - /// Set all supported directions. - /// All supported directions. - void SetDirection(ResponsiveDirection value); - }; - -/*********************************************************************** -GuiResponsiveViewComposition -***********************************************************************/ - - class GuiResponsiveSharedCollection : public collections::ObservableListBase - { - protected: - GuiResponsiveViewComposition* view = nullptr; - - void BeforeInsert(vint index, controls::GuiControl* const& value)override; - void AfterInsert(vint index, controls::GuiControl* const& value)override; - void BeforeRemove(vint index, controls::GuiControl* const& value)override; - void AfterRemove(vint index, vint count)override; - - public: - GuiResponsiveSharedCollection(GuiResponsiveViewComposition* _view); - ~GuiResponsiveSharedCollection(); - }; - - class GuiResponsiveViewCollection : public collections::ObservableListBase - { - protected: - GuiResponsiveViewComposition* view = nullptr; - - void BeforeInsert(vint index, GuiResponsiveCompositionBase* const& value)override; - void AfterInsert(vint index, GuiResponsiveCompositionBase* const& value)override; - void BeforeRemove(vint index, GuiResponsiveCompositionBase* const& value)override; - void AfterRemove(vint index, vint count)override; - - public: - GuiResponsiveViewCollection(GuiResponsiveViewComposition* _view); - ~GuiResponsiveViewCollection(); - }; - - /// Represents a composition, which will pick up a shared control and install inside it, when it is displayed by a [T:vl.presentation.compositions.GuiResponsiveViewComposition] - class GuiResponsiveSharedComposition : public GuiBoundsComposition, public Description - { - protected: - GuiResponsiveViewComposition* view = nullptr; - controls::GuiControl* shared = nullptr; - - void SetSharedControl(); - void OnParentLineChanged()override; - - public: - GuiResponsiveSharedComposition(); - ~GuiResponsiveSharedComposition(); - - /// Get the selected shared control. - /// The selected shared control. - controls::GuiControl* GetShared(); - /// Set the selected shared control, which should be stored in [M:vl.presentation.compositions.GuiResponsiveViewComposition.GetSharedControls]. - /// The selected shared control. - void SetShared(controls::GuiControl* value); - }; - - /// A responsive layout composition defined by views of different sizes. - class GuiResponsiveViewComposition : public GuiResponsiveCompositionBase, public Description - { - friend class GuiResponsiveSharedCollection; - friend class GuiResponsiveViewCollection; - friend class GuiResponsiveSharedComposition; - using ControlSet = collections::SortedList; - protected: - vint levelCount = 1; - vint currentLevel = 0; - bool skipUpdatingLevels = false; - GuiResponsiveCompositionBase* currentView = nullptr; - - ControlSet usedSharedControls; - GuiResponsiveSharedCollection sharedControls; - GuiResponsiveViewCollection views; - bool destructing = false; - - bool CalculateLevelCount(); - bool CalculateCurrentLevel(); - void OnResponsiveChildLevelUpdated()override; - - public: - GuiResponsiveViewComposition(); - ~GuiResponsiveViewComposition(); - - /// Before switch view event. This event happens between hiding the previous view and showing the next view. The itemIndex field can be used to access [M:vl.presentation.compositions.GuiResponsiveViewComposition.GetViews], it is not the level number. - GuiItemNotifyEvent BeforeSwitchingView; - - vint GetLevelCount()override; - vint GetCurrentLevel()override; - bool LevelDown()override; - bool LevelUp()override; - - /// Get the current displaying view. - /// The current displaying view. - GuiResponsiveCompositionBase* GetCurrentView(); - - /// Get all shared controls. A shared control can jump between different views if it is contained in a [T:vl.presentation.compositions.GuiResponsiveSharedComposition]. This helps to keep control states during switching views. - /// All shared controls. - collections::ObservableListBase& GetSharedControls(); - - /// Get all individual views to switch. - /// All individual views to switch. - collections::ObservableListBase& GetViews(); - }; - -/*********************************************************************** -Others -***********************************************************************/ - - /// A responsive layout composition which stop parent responsive composition to search its children. - class GuiResponsiveFixedComposition : public GuiResponsiveCompositionBase, public Description - { - protected: - void OnResponsiveChildLevelUpdated()override; - - public: - GuiResponsiveFixedComposition(); - ~GuiResponsiveFixedComposition(); - - vint GetLevelCount()override; - vint GetCurrentLevel()override; - bool LevelDown()override; - bool LevelUp()override; - }; - - /// A responsive layout composition which change its size by changing children's views one by one in one direction. - class GuiResponsiveStackComposition : public GuiResponsiveCompositionBase, public Description - { - using ResponsiveChildList = collections::List; - protected: - vint levelCount = 1; - vint currentLevel = 0; - ResponsiveChildList responsiveChildren; - - bool CalculateLevelCount(); - bool CalculateCurrentLevel(); - void OnResponsiveChildInserted(GuiResponsiveCompositionBase* child)override; - void OnResponsiveChildRemoved(GuiResponsiveCompositionBase* child)override; - void OnResponsiveChildLevelUpdated()override; - bool ChangeLevel(bool levelDown); - - public: - GuiResponsiveStackComposition(); - ~GuiResponsiveStackComposition(); - - vint GetLevelCount()override; - vint GetCurrentLevel()override; - bool LevelDown()override; - bool LevelUp()override; - }; - - /// A responsive layout composition which change its size by changing children's views at the same time. - class GuiResponsiveGroupComposition : public GuiResponsiveCompositionBase, public Description - { - using ResponsiveChildList = collections::List; - protected: - vint levelCount = 1; - vint currentLevel = 0; - ResponsiveChildList responsiveChildren; - - bool CalculateLevelCount(); - bool CalculateCurrentLevel(); - void OnResponsiveChildInserted(GuiResponsiveCompositionBase* child)override; - void OnResponsiveChildRemoved(GuiResponsiveCompositionBase* child)override; - void OnResponsiveChildLevelUpdated()override; - - public: - GuiResponsiveGroupComposition(); - ~GuiResponsiveGroupComposition(); - - vint GetLevelCount()override; - vint GetCurrentLevel()override; - bool LevelDown()override; - bool LevelUp()override; - }; - -/*********************************************************************** -GuiResponsiveContainerComposition -***********************************************************************/ - - /// A composition which will automatically tell its target responsive composition to switch between views according to its size. - class GuiResponsiveContainerComposition : public GuiBoundsComposition, public Description - { - protected: - GuiResponsiveCompositionBase* responsiveTarget = nullptr; - Size upperLevelSize; - - void AdjustLevel(); - void OnBoundsChanged(GuiGraphicsComposition* sender, GuiEventArgs& arguments); - - public: - GuiResponsiveContainerComposition(); - ~GuiResponsiveContainerComposition(); - - /// Get the responsive composition to control. - /// The responsive composition to control. - GuiResponsiveCompositionBase* GetResponsiveTarget(); - /// Get the responsive composition to control. - /// The responsive composition to control. - void SetResponsiveTarget(GuiResponsiveCompositionBase* value); - }; - } - } -} - -#endif - - -/*********************************************************************** -.\GRAPHICSCOMPOSITION\GUIGRAPHICSSHAREDSIZECOMPOSITION.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI::Composition System - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_COMPOSITION_GUIGRAPHICSSHAREDSIZECOMPOSITION -#define VCZH_PRESENTATION_COMPOSITION_GUIGRAPHICSSHAREDSIZECOMPOSITION - - -namespace vl -{ - namespace presentation - { - namespace compositions - { - /// A shared size composition that shares the same size with all other that has a same group name. - class GuiSharedSizeItemComposition : public GuiBoundsComposition, public Description - { - protected: - GuiSharedSizeRootComposition* parentRoot = nullptr; - WString group; - bool sharedWidth = false; - bool sharedHeight = false; - - void Update(); - void OnParentLineChanged()override; - public: - GuiSharedSizeItemComposition(); - ~GuiSharedSizeItemComposition(); - - /// Get the group name of this item. - /// The group name. - const WString& GetGroup(); - /// Set the group name of this item. - /// The group name. - void SetGroup(const WString& value); - /// Test is the width of this item is shared. - /// Returns true if the width of this item is shared. - bool GetSharedWidth(); - /// Enable or disable sharing the width of this item. - /// Set to true to share the width of this item. - void SetSharedWidth(bool value); - /// Test is the height of this item is shared. - /// Returns true if the height of this item is shared. - bool GetSharedHeight(); - /// Enable or disable sharing the height of this item. - /// Set to true to share the height of this item. - void SetSharedHeight(bool value); - }; - - /// A root composition that takes care of all direct or indirect to enable size sharing. - class GuiSharedSizeRootComposition :public GuiBoundsComposition, public Description - { - friend class GuiSharedSizeItemComposition; - protected: - collections::Dictionary itemWidths; - collections::Dictionary itemHeights; - collections::List childItems; - - void AddSizeComponent(collections::Dictionary& sizes, const WString& group, vint sizeComponent); - void CollectSizes(collections::Dictionary& widths, collections::Dictionary& heights); - void AlignSizes(collections::Dictionary& widths, collections::Dictionary& heights); - public: - GuiSharedSizeRootComposition(); - ~GuiSharedSizeRootComposition(); - - void ForceCalculateSizeImmediately()override; - Rect GetBounds()override; - }; - } - } -} - -#endif - -/*********************************************************************** -.\GRAPHICSCOMPOSITION\GUIGRAPHICSREPEATCOMPOSITION.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI::Composition System - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_COMPOSITION_GUIGRAPHICSREPEATCOMPOSITION -#define VCZH_PRESENTATION_COMPOSITION_GUIGRAPHICSREPEATCOMPOSITION - - -namespace vl -{ - namespace presentation - { - namespace compositions - { - /// A base class for all bindable repeat compositions. - class GuiRepeatCompositionBase : public Object, public Description - { - using ItemStyleProperty = TemplateProperty; - using IValueEnumerable = reflection::description::IValueEnumerable; - using IValueList = reflection::description::IValueList; - protected: - ItemStyleProperty itemTemplate; - Ptr itemSource; - Ptr itemChangedHandler; - - virtual vint GetRepeatCompositionCount() = 0; - virtual GuiGraphicsComposition* GetRepeatComposition(vint index) = 0; - virtual GuiGraphicsComposition* InsertRepeatComposition(vint index) = 0; - virtual GuiGraphicsComposition* RemoveRepeatComposition(vint index) = 0; - - void OnItemChanged(vint index, vint oldCount, vint newCount); - void RemoveItem(vint index); - void InstallItem(vint index); - void ClearItems(); - void InstallItems(); - public: - GuiRepeatCompositionBase(); - ~GuiRepeatCompositionBase(); - - /// An event called after a new item is inserted. - GuiItemNotifyEvent ItemInserted; - /// An event called before a new item is removed. - GuiItemNotifyEvent ItemRemoved; - - /// Get the item style provider. - /// The item style provider. - ItemStyleProperty GetItemTemplate(); - /// Set the item style provider - /// The new item style provider - void SetItemTemplate(ItemStyleProperty value); - - /// Get the item source. - /// The item source. - Ptr GetItemSource(); - /// Set the item source. - /// The item source. Null is acceptable if you want to clear all data. - void SetItemSource(Ptr value); - }; - - /// Bindable stack composition. - class GuiRepeatStackComposition : public GuiStackComposition, public GuiRepeatCompositionBase, public Description - { - protected: - vint GetRepeatCompositionCount()override; - GuiGraphicsComposition* GetRepeatComposition(vint index)override; - GuiGraphicsComposition* InsertRepeatComposition(vint index)override; - GuiGraphicsComposition* RemoveRepeatComposition(vint index)override; - public: - }; - - /// Bindable flow composition. - class GuiRepeatFlowComposition : public GuiFlowComposition, public GuiRepeatCompositionBase, public Description - { - protected: - vint GetRepeatCompositionCount()override; - GuiGraphicsComposition* GetRepeatComposition(vint index)override; - GuiGraphicsComposition* InsertRepeatComposition(vint index)override; - GuiGraphicsComposition* RemoveRepeatComposition(vint index)override; - public: - }; - } - } -} - -#endif - -/*********************************************************************** -.\GRAPHICSCOMPOSITION\INCLUDEALL.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI::Composition System - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_COMPOSITION_INCLUDEALL -#define VCZH_PRESENTATION_COMPOSITION_INCLUDEALL - - -#endif - -/*********************************************************************** -.\GRAPHICSHOST\GUIGRAPHICSHOST_SHORTCUTKEY.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI::Graphics Composition Host - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_HOST_GUIGRAPHICSHOST_SHORTCUTKEY -#define VCZH_PRESENTATION_HOST_GUIGRAPHICSHOST_SHORTCUTKEY - - -namespace vl -{ - namespace presentation - { - namespace compositions - { - -/*********************************************************************** -Shortcut Key Manager -***********************************************************************/ - - class IGuiShortcutKeyManager; - - /// Shortcut key item. - class IGuiShortcutKeyItem : public virtual IDescriptable, public Description - { - public: - /// Shortcut key executed event. - GuiNotifyEvent Executed; - - /// Get the associated object. - /// The associated shortcut key manager. - virtual IGuiShortcutKeyManager* GetManager()=0; - /// Get the name represents the shortcut key combination for this item. - /// The name represents the shortcut key combination for this item. - virtual WString GetName()=0; - }; - - /// Shortcut key manager item. - class IGuiShortcutKeyManager : public virtual IDescriptable, public Description - { - public: - /// Get the number of shortcut key items that already attached to the manager. - /// T number of shortcut key items that already attached to the manager. - virtual vint GetItemCount()=0; - /// Get the associated with the index. - /// The shortcut key item. - /// The index. - virtual IGuiShortcutKeyItem* GetItem(vint index)=0; - /// Execute shortcut key items using a key event info. - /// Returns true if at least one shortcut key item is executed. - /// The key event info. - virtual bool Execute(const NativeWindowKeyInfo& info)=0; - }; - -/*********************************************************************** -Shortcut Key Manager Helpers -***********************************************************************/ - - class GuiShortcutKeyManager; - - class GuiShortcutKeyItem : public Object, public IGuiShortcutKeyItem - { - protected: - GuiShortcutKeyManager* shortcutKeyManager; - bool ctrl; - bool shift; - bool alt; - VKEY key; - - void AttachManager(GuiShortcutKeyManager* manager); - void DetachManager(GuiShortcutKeyManager* manager); - public: - GuiShortcutKeyItem(GuiShortcutKeyManager* _shortcutKeyManager, bool _ctrl, bool _shift, bool _alt, VKEY _key); - ~GuiShortcutKeyItem(); - - IGuiShortcutKeyManager* GetManager()override; - WString GetName()override; - bool CanActivate(const NativeWindowKeyInfo& info); - bool CanActivate(bool _ctrl, bool _shift, bool _alt, VKEY _key); - }; - - /// A default implementation for . - class GuiShortcutKeyManager : public Object, public IGuiShortcutKeyManager, public Description - { - typedef collections::List> ShortcutKeyItemList; - protected: - ShortcutKeyItemList shortcutKeyItems; - - public: - /// Create the shortcut key manager. - GuiShortcutKeyManager(); - ~GuiShortcutKeyManager(); - - vint GetItemCount()override; - IGuiShortcutKeyItem* GetItem(vint index)override; - bool Execute(const NativeWindowKeyInfo& info)override; - - /// Create a shortcut key item using a key combination. If the item for the key combination exists, this function returns the item that is created before. - /// The created shortcut key item. - /// Set to true if the CTRL key is required. - /// Set to true if the SHIFT key is required. - /// Set to true if the ALT key is required. - /// The non-control key. - IGuiShortcutKeyItem* CreateShortcut(bool ctrl, bool shift, bool alt, VKEY key); - /// Destroy a shortcut key item using a key combination - /// Returns true if the manager destroyed a existing shortcut key item. - /// Set to true if the CTRL key is required. - /// Set to true if the SHIFT key is required. - /// Set to true if the ALT key is required. - /// The non-control key. - bool DestroyShortcut(bool ctrl, bool shift, bool alt, VKEY key); - /// Get a shortcut key item using a key combination. If the item for the key combination does not exist, this function returns null. - /// The shortcut key item. - /// Set to true if the CTRL key is required. - /// Set to true if the SHIFT key is required. - /// Set to true if the ALT key is required. - /// The non-control key. - IGuiShortcutKeyItem* TryGetShortcut(bool ctrl, bool shift, bool alt, VKEY key); - }; - } - } -} - -#endif - -/*********************************************************************** -.\GRAPHICSHOST\GUIGRAPHICSHOST.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI::Graphics Composition Host - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_HOST_GUIGRAPHICSHOST -#define VCZH_PRESENTATION_HOST_GUIGRAPHICSHOST +#ifndef VCZH_PRESENTATION_CONTROLS_INCLUDEFORWARD +#define VCZH_PRESENTATION_CONTROLS_INCLUDEFORWARD namespace vl @@ -11154,1084 +11915,69 @@ namespace vl { namespace controls { - class GuiWindow; - } - - namespace compositions - { - -/*********************************************************************** -Animation -***********************************************************************/ - - /// - /// Represents a timer callback object. - /// - class IGuiGraphicsTimerCallback : public virtual IDescriptable, public Description - { - public: - /// Called periodically. - /// Returns false to indicate that this callback need to be removed. - virtual bool Play() = 0; - }; - - /// - /// Timer callback manager. - /// - class GuiGraphicsTimerManager : public Object, public Description - { - typedef collections::List> CallbackList; - protected: - CallbackList callbacks; - - public: - GuiGraphicsTimerManager(); - ~GuiGraphicsTimerManager(); - - /// Add a new callback. - /// The new callback to add. - void AddCallback(Ptr callback); - /// Called periodically. - void Play(); - }; - -/*********************************************************************** -Host -***********************************************************************/ - - /// - /// GuiGraphicsHost hosts an in an . The composition will fill the whole window. - /// - class GuiGraphicsHost : public Object, private INativeWindowListener, private INativeControllerListener, public Description - { - typedef collections::List CompositionList; - typedef GuiGraphicsComposition::GraphicsHostRecord HostRecord; - typedef collections::Pair ProcKey; - typedef collections::List> ProcList; - typedef collections::Dictionary> ProcMap; - public: - static const vuint64_t CaretInterval = 500; - - protected: - HostRecord hostRecord; - bool supressPaint = false; - bool needRender = true; - ProcList afterRenderProcs; - ProcMap afterRenderKeyedProcs; - - GuiAltActionManager* altActionManager = nullptr; - GuiTabActionManager* tabActionManager = nullptr; - IGuiShortcutKeyManager* shortcutKeyManager = nullptr; - - controls::GuiControlHost* controlHost = nullptr; - GuiWindowComposition* windowComposition = nullptr; - GuiGraphicsComposition* focusedComposition = nullptr; - NativeSize previousClientSize; - Size minSize; - Point caretPoint; - vuint64_t lastCaretTime = 0; - - GuiGraphicsTimerManager timerManager; - GuiGraphicsComposition* mouseCaptureComposition = nullptr; - CompositionList mouseEnterCompositions; - void RefreshRelatedHostRecord(INativeWindow* nativeWindow); - - void DisconnectCompositionInternal(GuiGraphicsComposition* composition); - void MouseCapture(const NativeWindowMouseInfo& info); - void MouseUncapture(const NativeWindowMouseInfo& info); - void OnCharInput(const NativeWindowCharInfo& info, GuiGraphicsComposition* composition, GuiCharEvent GuiGraphicsEventReceiver::* eventReceiverEvent); - void OnKeyInput(const NativeWindowKeyInfo& info, GuiGraphicsComposition* composition, GuiKeyEvent GuiGraphicsEventReceiver::* eventReceiverEvent); - void RaiseMouseEvent(GuiMouseEventArgs& arguments, GuiGraphicsComposition* composition, GuiMouseEvent GuiGraphicsEventReceiver::* eventReceiverEvent); - void OnMouseInput(const NativeWindowMouseInfo& info, GuiMouseEvent GuiGraphicsEventReceiver::* eventReceiverEvent); - void RecreateRenderTarget(); - - private: - INativeWindowListener::HitTestResult HitTest(NativePoint location)override; - void Moving(NativeRect& bounds, bool fixSizeOnly)override; - void Moved()override; - void DpiChanged()override; - void Paint()override; - - void LeftButtonDown(const NativeWindowMouseInfo& info)override; - void LeftButtonUp(const NativeWindowMouseInfo& info)override; - void LeftButtonDoubleClick(const NativeWindowMouseInfo& info)override; - void RightButtonDown(const NativeWindowMouseInfo& info)override; - void RightButtonUp(const NativeWindowMouseInfo& info)override; - void RightButtonDoubleClick(const NativeWindowMouseInfo& info)override; - void MiddleButtonDown(const NativeWindowMouseInfo& info)override; - void MiddleButtonUp(const NativeWindowMouseInfo& info)override; - void MiddleButtonDoubleClick(const NativeWindowMouseInfo& info)override; - void HorizontalWheel(const NativeWindowMouseInfo& info)override; - void VerticalWheel(const NativeWindowMouseInfo& info)override; - void MouseMoving(const NativeWindowMouseInfo& info)override; - void MouseEntered()override; - void MouseLeaved()override; - - void KeyDown(const NativeWindowKeyInfo& info)override; - void KeyUp(const NativeWindowKeyInfo& info)override; - void SysKeyDown(const NativeWindowKeyInfo& info)override; - void SysKeyUp(const NativeWindowKeyInfo& info)override; - void Char(const NativeWindowCharInfo& info)override; - - void GlobalTimer()override; - public: - GuiGraphicsHost(controls::GuiControlHost* _controlHost, GuiGraphicsComposition* boundsComposition); - ~GuiGraphicsHost(); - - /// Get the associated window. - /// The associated window. - INativeWindow* GetNativeWindow(); - /// Associate a window. A will fill and appear in the window. - /// The window to associated. - void SetNativeWindow(INativeWindow* _nativeWindow); - /// Get the main . If a window is associated, everything that put into the main composition will be shown in the window. - /// The main compositoin. - GuiGraphicsComposition* GetMainComposition(); - /// Render the main composition and all content to the associated window. - /// Set to true to force updating layout and then render. - void Render(bool forceUpdate); - /// Request a rendering - void RequestRender(); - /// Invoke a specified function after rendering. - /// The specified function. - /// A key to cancel a previous binded key if not null. - void InvokeAfterRendering(const Func& proc, ProcKey key = { nullptr,-1 }); - - /// Invalidte the internal tab order control list. Next time when TAB is pressed it will be rebuilt. - void InvalidateTabOrderCache(); - /// Get the attached with this graphics host. - /// The shortcut key manager. - IGuiShortcutKeyManager* GetShortcutKeyManager(); - /// Attach or detach the associated with this graphics host. When this graphics host is disposing, the associated shortcut key manager will be deleted if exists. - /// The shortcut key manager. Set to null to detach the previous shortcut key manager from this graphics host. - void SetShortcutKeyManager(IGuiShortcutKeyManager* value); - - /// Set the focus composition. A focused composition will receive keyboard messages. - /// Returns true if this operation succeeded. - /// The composition to set focus. This composition should be or in the main composition. - bool SetFocus(GuiGraphicsComposition* composition); - /// Get the focus composition. A focused composition will receive keyboard messages. - /// The focus composition. - GuiGraphicsComposition* GetFocusedComposition(); - /// Get the caret point. A caret point is the position to place the edit box of the activated input method editor. - /// The caret point. - Point GetCaretPoint(); - /// Set the caret point. A caret point is the position to place the edit box of the activated input method editor. - /// The caret point. - /// The point space. If this argument is null, the "value" argument will use the point space of the client area in the main composition. - void SetCaretPoint(Point value, GuiGraphicsComposition* referenceComposition=0); - - /// Get the timer manager. - /// The timer manager. - GuiGraphicsTimerManager* GetTimerManager(); - /// Notify that a composition is going to disconnect from this graphics host. Generally this happens when a composition's parent line changes. - /// The composition to disconnect - void DisconnectComposition(GuiGraphicsComposition* composition); - }; - } - } -} - -#endif - -/*********************************************************************** -.\CONTROLS\GUILABELCONTROLS.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI::Control System - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_CONTROLS_GUILABELCONTROLS -#define VCZH_PRESENTATION_CONTROLS_GUILABELCONTROLS - - -namespace vl -{ - namespace presentation - { - namespace controls - { - -/*********************************************************************** -Label -***********************************************************************/ - - /// A control to display a text. - class GuiLabel : public GuiControl, public Description - { - GUI_SPECIFY_CONTROL_TEMPLATE_TYPE(LabelTemplate, GuiControl) - protected: - Color textColor; - bool textColorConsisted = true; - - public: - /// Create a control with a specified default theme. - /// The theme name for retriving a default control template. - GuiLabel(theme::ThemeName themeName); - ~GuiLabel(); - - /// Get the text color. - /// The text color. - Color GetTextColor(); - /// Set the text color. - /// The text color. - void SetTextColor(Color value); - }; - } - } -} - -#endif - - -/*********************************************************************** -.\CONTROLS\GUIBUTTONCONTROLS.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI::Control System - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_CONTROLS_GUIBUTTONCONTROLS -#define VCZH_PRESENTATION_CONTROLS_GUIBUTTONCONTROLS - - -namespace vl -{ - namespace presentation - { - namespace controls - { - -/*********************************************************************** -Buttons -***********************************************************************/ - - /// A control with 3 phases state transffering when mouse click happens. - class GuiButton : public GuiControl, public Description - { - GUI_SPECIFY_CONTROL_TEMPLATE_TYPE(ButtonTemplate, GuiControl) - protected: - bool clickOnMouseUp = true; - bool autoFocus = true; - bool keyPressing = false; - bool mousePressing = false; - bool mouseHoving = false; - ButtonState controlState = ButtonState::Normal; - - void OnParentLineChanged()override; - void OnActiveAlt()override; - bool IsTabAvailable()override; - void UpdateControlState(); - void CheckAndClick(compositions::GuiEventArgs& arguments); - void OnLeftButtonDown(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments); - void OnLeftButtonUp(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments); - void OnMouseEnter(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); - void OnMouseLeave(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); - void OnKeyDown(compositions::GuiGraphicsComposition* sender, compositions::GuiKeyEventArgs& arguments); - void OnKeyUp(compositions::GuiGraphicsComposition* sender, compositions::GuiKeyEventArgs& arguments); - void OnLostFocus(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); - public: - /// Create a control with a specified default theme. - /// The theme name for retriving a default control template. - GuiButton(theme::ThemeName themeName); - ~GuiButton(); - - /// Mouse click event. - compositions::GuiNotifyEvent Clicked; - - /// Test is the event raised when left mouse button up. - /// Returns true if this event is raised when left mouse button up - bool GetClickOnMouseUp(); - /// Set is the event raised when left mouse button up or not. - /// Set to true to make this event raised when left mouse button up - void SetClickOnMouseUp(bool value); - - /// Test if the button gets focus when it is clicked. - /// Returns true if the button gets focus when it is clicked - bool GetAutoFocus(); - /// Set if the button gets focus when it is clicked. - /// Set to true to make this button get focus when it is clicked. - void SetAutoFocus(bool value); - }; - - /// A with a selection state. - class GuiSelectableButton : public GuiButton, public Description - { - GUI_SPECIFY_CONTROL_TEMPLATE_TYPE(SelectableButtonTemplate, GuiButton) - public: - /// Selection group controller. Control the selection state of all attached button. - class GroupController : public GuiComponent, public Description - { - protected: - collections::List buttons; - public: - GroupController(); - ~GroupController(); - - /// Called when the group controller is attached to a . use [M:vl.presentation.controls.GuiSelectableButton.SetGroupController] to attach or detach a group controller to or from a selectable button. - /// The button to attach. - virtual void Attach(GuiSelectableButton* button); - /// Called when the group controller is deteched to a . use [M:vl.presentation.controls.GuiSelectableButton.SetGroupController] to attach or detach a group controller to or from a selectable button. - /// The button to detach. - virtual void Detach(GuiSelectableButton* button); - /// Called when the selection state of any changed. - /// The button that changed the selection state. - virtual void OnSelectedChanged(GuiSelectableButton* button) = 0; - }; - - /// A mutex group controller, usually for radio buttons. - class MutexGroupController : public GroupController, public Description - { - protected: - bool suppress; - public: - MutexGroupController(); - ~MutexGroupController(); - - void OnSelectedChanged(GuiSelectableButton* button)override; - }; - - protected: - GroupController* groupController = nullptr; - bool autoSelection = true; - bool isSelected = false; - - void OnClicked(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); - public: - /// Create a control with a specified default theme. - /// The theme name for retriving a default control template. - GuiSelectableButton(theme::ThemeName themeName); - ~GuiSelectableButton(); - - /// Group controller changed event. - compositions::GuiNotifyEvent GroupControllerChanged; - /// Auto selection changed event. - compositions::GuiNotifyEvent AutoSelectionChanged; - /// Selected changed event. - compositions::GuiNotifyEvent SelectedChanged; - - /// Get the attached group controller. - /// The attached group controller. - virtual GroupController* GetGroupController(); - /// Set the attached group controller. - /// The attached group controller. - virtual void SetGroupController(GroupController* value); - - /// Get the auto selection state. True if the button is automatically selected or unselected when the button is clicked. - /// The auto selection state. - virtual bool GetAutoSelection(); - /// Set the auto selection state. True if the button is automatically selected or unselected when the button is clicked. - /// The auto selection state. - virtual void SetAutoSelection(bool value); - - /// Get the selected state. - /// The selected state. - virtual bool GetSelected(); - /// Set the selected state. - /// The selected state. - virtual void SetSelected(bool value); - }; - } - } -} - -#endif - - -/*********************************************************************** -.\CONTROLS\GUISCROLLCONTROLS.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI::Control System - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_CONTROLS_GUISCROLLCONTROLS -#define VCZH_PRESENTATION_CONTROLS_GUISCROLLCONTROLS - - -namespace vl -{ - namespace presentation - { - - namespace controls - { - -/*********************************************************************** -Scrolls -***********************************************************************/ - - /// A scroll control, which represents a one dimension sub range of a whole range. - class GuiScroll : public GuiControl, public Description - { - GUI_SPECIFY_CONTROL_TEMPLATE_TYPE(ScrollTemplate, GuiControl) - protected: - class CommandExecutor : public Object, public IScrollCommandExecutor - { - protected: - GuiScroll* scroll; - public: - CommandExecutor(GuiScroll* _scroll); - ~CommandExecutor(); - - void SmallDecrease()override; - void SmallIncrease()override; - void BigDecrease()override; - void BigIncrease()override; - - void SetTotalSize(vint value)override; - void SetPageSize(vint value)override; - void SetPosition(vint value)override; - }; - - Ptr commandExecutor; - vint totalSize = 100; - vint pageSize = 10; - vint position = 0; - vint smallMove = 1; - vint bigMove = 10; - bool autoFocus = true; - - void OnActiveAlt()override; - bool IsTabAvailable()override; - void OnKeyDown(compositions::GuiGraphicsComposition* sender, compositions::GuiKeyEventArgs& arguments); - void OnMouseDown(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments); - public: - /// Create a control with a specified default theme. - /// The theme name for retriving a default control template. - GuiScroll(theme::ThemeName themeName); - ~GuiScroll(); - - /// Total size changed event. - compositions::GuiNotifyEvent TotalSizeChanged; - /// Page size changed event. - compositions::GuiNotifyEvent PageSizeChanged; - /// Position changed event. - compositions::GuiNotifyEvent PositionChanged; - /// Small move changed event. - compositions::GuiNotifyEvent SmallMoveChanged; - /// Big move changed event. - compositions::GuiNotifyEvent BigMoveChanged; - - /// Get the total size. - /// The total size. - virtual vint GetTotalSize(); - /// Set the total size. - /// The total size. - virtual void SetTotalSize(vint value); - /// Get the page size. - /// The page size. - virtual vint GetPageSize(); - /// Set the page size. - /// The page size. - virtual void SetPageSize(vint value); - /// Get the position. - /// The position. - virtual vint GetPosition(); - /// Set the position. - /// The position. - virtual void SetPosition(vint value); - /// Get the small move. - /// The small move. - virtual vint GetSmallMove(); - /// Set the small move. - /// The small move. - virtual void SetSmallMove(vint value); - /// Get the big move. - /// The big move. - virtual vint GetBigMove(); - /// Set the big move. - /// The big move. - virtual void SetBigMove(vint value); - - /// Get the minimum possible position. - /// The minimum possible position. - vint GetMinPosition(); - /// Get the maximum possible position. - /// The maximum possible position. - vint GetMaxPosition(); - - /// Test if the scroll gets focus when it is clicked. - /// Returns true if the scroll gets focus when it is clicked - bool GetAutoFocus(); - /// Set if the scroll gets focus when it is clicked. - /// Set to true to make this scroll get focus when it is clicked. - void SetAutoFocus(bool value); - }; - } - } -} - -#endif - - -/*********************************************************************** -.\CONTROLS\GUICONTAINERCONTROLS.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI::Control System - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_CONTROLS_GUICONTAINERCONTROLS -#define VCZH_PRESENTATION_CONTROLS_GUICONTAINERCONTROLS - - -namespace vl -{ - namespace presentation - { - namespace controls - { -/*********************************************************************** -Tab Control -***********************************************************************/ - - class GuiTabPageList; + class GuiControl; + class GuiCustomControl; + class GuiLabel; + class GuiButton; + class GuiSelectableButton; + class GuiScroll; + class GuiTabPage; class GuiTab; - - /// Represnets a tab page control. - class GuiTabPage : public GuiCustomControl, public AggregatableDescription - { - friend class GuiTabPageList; - protected: - GuiTab* tab = nullptr; - - bool IsAltAvailable()override; - public: - /// Create a tab page control with a specified style controller. - /// The theme name for retriving a default control template. - GuiTabPage(theme::ThemeName themeName); - ~GuiTabPage(); - - GuiTab* GetOwnerTab(); - }; - - class GuiTabPageList : public collections::ObservableList - { - protected: - GuiTab* tab; - - bool QueryInsert(vint index, GuiTabPage* const& value)override; - void AfterInsert(vint index, GuiTabPage* const& value)override; - void BeforeRemove(vint index, GuiTabPage* const& value)override; - public: - GuiTabPageList(GuiTab* _tab); - ~GuiTabPageList(); - }; - - /// Represents a container with multiple named tabs. - class GuiTab : public GuiControl, public Description - { - GUI_SPECIFY_CONTROL_TEMPLATE_TYPE(TabTemplate, GuiControl) - friend class GuiTabPageList; - protected: - class CommandExecutor : public Object, public ITabCommandExecutor - { - protected: - GuiTab* tab; - - public: - CommandExecutor(GuiTab* _tab); - ~CommandExecutor(); - - void ShowTab(vint index, bool setFocus)override; - }; - - Ptr commandExecutor; - GuiTabPageList tabPages; - GuiTabPage* selectedPage = nullptr; - - void OnKeyDown(compositions::GuiGraphicsComposition* sender, compositions::GuiKeyEventArgs& arguments); - public: - /// Create a control with a specified default theme. - /// The theme name for retriving a default control template. - GuiTab(theme::ThemeName themeName); - ~GuiTab(); - - /// Selected page changed event. - compositions::GuiNotifyEvent SelectedPageChanged; - - /// Get all pages. - /// All pages. - collections::ObservableList& GetPages(); - - /// Get the selected page. - /// The selected page. - GuiTabPage* GetSelectedPage(); - /// Set the selected page. - /// Returns true if this operation succeeded. - /// The selected page. - bool SetSelectedPage(GuiTabPage* value); - }; - -/*********************************************************************** -Scroll View -***********************************************************************/ - - /// A control with a vertical scroll bar and a horizontal scroll bar to perform partial viewing. - class GuiScrollView : public GuiControl, public Description - { - GUI_SPECIFY_CONTROL_TEMPLATE_TYPE(ScrollViewTemplate, GuiControl) - - using IEventHandler = compositions::IGuiGraphicsEventHandler; - protected: - bool supressScrolling = false; - Ptr hScrollHandler; - Ptr vScrollHandler; - Ptr hWheelHandler; - Ptr vWheelHandler; - Ptr containerBoundsChangedHandler; - bool horizontalAlwaysVisible = true; - bool verticalAlwaysVisible = true; - - void UpdateDisplayFont()override; - - void OnContainerBoundsChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); - void OnHorizontalScroll(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); - void OnVerticalScroll(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); - void OnHorizontalWheel(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments); - void OnVerticalWheel(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments); - void CallUpdateView(); - bool AdjustView(Size fullSize); - - /// Calculate the full size of the content. - /// The full size of the content. - virtual Size QueryFullSize()=0; - /// Update the visible content using a view bounds. The view bounds is in the space from (0,0) to full size. - /// The view bounds. - virtual void UpdateView(Rect viewBounds)=0; - /// Calculate the small move of the scroll bar. - /// The small move of the scroll bar. - virtual vint GetSmallMove(); - /// Calculate the big move of the scroll bar. - /// The big move of the scroll bar. - virtual Size GetBigMove(); - - public: - /// Create a control with a specified style provider. - /// The theme name for retriving a default control template. - GuiScrollView(theme::ThemeName themeName); - ~GuiScrollView(); - - /// Force to update contents and scroll bars. - void CalculateView(); - /// Get the view size. - /// The view size. - Size GetViewSize(); - /// Get the view bounds. - /// The view bounds. - Rect GetViewBounds(); - - /// Get the position of the left-top corner of the view bounds. - /// The view position. - Point GetViewPosition(); - /// Set the position of the left-top corner of the view bounds. - /// The position. - void SetViewPosition(Point value); - - /// Get the horizontal scroll control. - /// The horizontal scroll control. - GuiScroll* GetHorizontalScroll(); - /// Get the vertical scroll control. - /// The vertical scroll control. - GuiScroll* GetVerticalScroll(); - /// Test is the horizontal scroll bar always visible even the content doesn't exceed the view bounds. - /// Returns true if the horizontal scroll bar always visible even the content doesn't exceed the view bounds - bool GetHorizontalAlwaysVisible(); - /// Set is the horizontal scroll bar always visible even the content doesn't exceed the view bounds. - /// Set to true if the horizontal scroll bar always visible even the content doesn't exceed the view bounds - void SetHorizontalAlwaysVisible(bool value); - /// Test is the vertical scroll bar always visible even the content doesn't exceed the view bounds. - /// Returns true if the vertical scroll bar always visible even the content doesn't exceed the view bounds - bool GetVerticalAlwaysVisible(); - /// Set is the vertical scroll bar always visible even the content doesn't exceed the view bounds. - /// Set to true if the vertical scroll bar always visible even the content doesn't exceed the view bounds - void SetVerticalAlwaysVisible(bool value); - }; - - /// A control container with a vertical scroll bar and a horizontal scroll bar to perform partial viewing. When controls are added, removed, moved or resized, the scroll bars will adjust automatically. - class GuiScrollContainer : public GuiScrollView, public Description - { - protected: - bool extendToFullWidth = false; - bool extendToFullHeight = false; - - Size QueryFullSize()override; - void UpdateView(Rect viewBounds)override; - public: - /// Create a control with a specified style provider. - /// The theme name for retriving a default control template. - GuiScrollContainer(theme::ThemeName themeName); - ~GuiScrollContainer(); - - /// Test does the content container always extend its width to fill the scroll container. - /// Return true if the content container always extend its width to fill the scroll container. - bool GetExtendToFullWidth(); - /// Set does the content container always extend its width to fill the scroll container. - /// Set to true if the content container always extend its width to fill the scroll container. - void SetExtendToFullWidth(bool value); - - /// Test does the content container always extend its height to fill the scroll container. - /// Return true if the content container always extend its height to fill the scroll container. - bool GetExtendToFullHeight(); - /// Set does the content container always extend its height to fill the scroll container. - /// Set to true if the content container always extend its height to fill the scroll container. - void SetExtendToFullHeight(bool value); - }; - } - } -} - -#endif - - -/*********************************************************************** -.\CONTROLS\GUIDIALOGS.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI::Control System - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_CONTROLS_GUIDIALOGS -#define VCZH_PRESENTATION_CONTROLS_GUIDIALOGS - - -namespace vl -{ - namespace presentation - { - namespace controls - { + class GuiScrollView; + class GuiScrollContainer; + class GuiControlHost; class GuiWindow; - -/*********************************************************************** -Dialogs -***********************************************************************/ - - /// Base class for dialogs. - class GuiDialogBase abstract : public GuiComponent, public Description - { - protected: - GuiInstanceRootObject* rootObject = nullptr; - - GuiWindow* GetHostWindow(); - public: - GuiDialogBase(); - ~GuiDialogBase(); - - void Attach(GuiInstanceRootObject* _rootObject); - void Detach(GuiInstanceRootObject* _rootObject); - }; - - /// Message dialog. - class GuiMessageDialog : public GuiDialogBase, public Description - { - protected: - INativeDialogService::MessageBoxButtonsInput input = INativeDialogService::DisplayOK; - INativeDialogService::MessageBoxDefaultButton defaultButton = INativeDialogService::DefaultFirst; - INativeDialogService::MessageBoxIcons icon = INativeDialogService::IconNone; - INativeDialogService::MessageBoxModalOptions modalOption = INativeDialogService::ModalWindow; - WString text; - WString title; - - public: - /// Create a message dialog. - GuiMessageDialog(); - ~GuiMessageDialog(); - - /// Get the button combination that appear on the dialog. - /// The button combination. - INativeDialogService::MessageBoxButtonsInput GetInput(); - /// Set the button combination that appear on the dialog. - /// The button combination. - void SetInput(INativeDialogService::MessageBoxButtonsInput value); - - /// Get the default button for the selected button combination. - /// The default button. - INativeDialogService::MessageBoxDefaultButton GetDefaultButton(); - /// Set the default button for the selected button combination. - /// The default button. - void SetDefaultButton(INativeDialogService::MessageBoxDefaultButton value); - - /// Get the icon that appears on the dialog. - /// The icon. - INativeDialogService::MessageBoxIcons GetIcon(); - /// Set the icon that appears on the dialog. - /// The icon. - void SetIcon(INativeDialogService::MessageBoxIcons value); - - /// Get the way that how this dialog disable windows of the current process. - /// The way that how this dialog disable windows of the current process. - INativeDialogService::MessageBoxModalOptions GetModalOption(); - /// Set the way that how this dialog disable windows of the current process. - /// The way that how this dialog disable windows of the current process. - void SetModalOption(INativeDialogService::MessageBoxModalOptions value); - - /// Get the text for the dialog. - /// The text. - const WString& GetText(); - /// Set the text for the dialog. - /// The text. - void SetText(const WString& value); - - /// Get the title for the dialog. - /// The title. - const WString& GetTitle(); - /// Set the title for the dialog. If the title is empty, the dialog will use the title of the window that host this dialog. - /// The title. - void SetTitle(const WString& value); - - /// Show the dialog. - /// Returns the clicked button. - INativeDialogService::MessageBoxButtonsOutput ShowDialog(); - }; - - /// Color dialog. - class GuiColorDialog : public GuiDialogBase, public Description - { - protected: - bool enabledCustomColor = true; - bool openedCustomColor = false; - Color selectedColor; - bool showSelection = true; - collections::List customColors; - - public: - /// Create a color dialog. - GuiColorDialog(); - ~GuiColorDialog(); - - /// Selected color changed event. - compositions::GuiNotifyEvent SelectedColorChanged; - - /// Get if the custom color panel is enabled for the dialog. - /// Returns true if the color panel is enabled for the dialog. - bool GetEnabledCustomColor(); - /// Set if custom color panel is enabled for the dialog. - /// Set to true to enable the custom color panel for the dialog. - void SetEnabledCustomColor(bool value); - - /// Get if the custom color panel is opened by default when it is enabled. - /// Returns true if the custom color panel is opened by default. - bool GetOpenedCustomColor(); - /// Set if the custom color panel is opened by default when it is enabled. - /// Set to true to open custom color panel by default if it is enabled. - void SetOpenedCustomColor(bool value); - - /// Get the selected color. - /// The selected color. - Color GetSelectedColor(); - /// Set the selected color. - /// The selected color. - void SetSelectedColor(Color value); - - /// Get the list to access 16 selected custom colors on the palette. Colors in the list is guaranteed to have exactly 16 items after the dialog is closed. - /// The list to access custom colors on the palette. - collections::List& GetCustomColors(); - - /// Show the dialog. - /// Returns true if the "OK" button is clicked. - bool ShowDialog(); - }; - - /// Font dialog. - class GuiFontDialog : public GuiDialogBase, public Description - { - protected: - FontProperties selectedFont; - Color selectedColor; - bool showSelection = true; - bool showEffect = true; - bool forceFontExist = true; - - public: - /// Create a font dialog. - GuiFontDialog(); - ~GuiFontDialog(); - - /// Selected font changed event. - compositions::GuiNotifyEvent SelectedFontChanged; - /// Selected color changed event. - compositions::GuiNotifyEvent SelectedColorChanged; - - /// Get the selected font. - /// The selected font. - const FontProperties& GetSelectedFont(); - /// Set the selected font. - /// The selected font. - void SetSelectedFont(const FontProperties& value); - - /// Get the selected color. - /// The selected color. - Color GetSelectedColor(); - /// Set the selected color. - /// The selected color. - void SetSelectedColor(Color value); - - /// Get if the selected font is already selected on the dialog when it is opened. - /// Returns true if the selected font is already selected on the dialog when it is opened. - bool GetShowSelection(); - /// Set if the selected font is already selected on the dialog when it is opened. - /// Set to true to select the selected font when the dialog is opened. - void SetShowSelection(bool value); - - /// Get if the font preview is enabled. - /// Returns true if the font preview is enabled. - bool GetShowEffect(); - /// Set if the font preview is enabled. - /// Set to true to enable the font preview. - void SetShowEffect(bool value); - - /// Get if the dialog only accepts an existing font. - /// Returns true if the dialog only accepts an existing font. - bool GetForceFontExist(); - /// Set if the dialog only accepts an existing font. - /// Set to true to let the dialog only accept an existing font. - void SetForceFontExist(bool value); - - /// Show the dialog. - /// Returns true if the "OK" button is clicked. - bool ShowDialog(); - }; - - /// Base class for file dialogs. - class GuiFileDialogBase abstract : public GuiDialogBase, public Description - { - protected: - WString filter = L"All Files (*.*)|*.*"; - vint filterIndex = 0; - bool enabledPreview = false; - WString title; - WString fileName; - WString directory; - WString defaultExtension; - INativeDialogService::FileDialogOptions options; - - public: - GuiFileDialogBase(); - ~GuiFileDialogBase(); - - /// File name changed event. - compositions::GuiNotifyEvent FileNameChanged; - /// Filter index changed event. - compositions::GuiNotifyEvent FilterIndexChanged; - - /// Get the filter. - /// The filter. - const WString& GetFilter(); - /// Set the filter. The filter is formed by pairs of filter name and wildcard concatenated by "|", like "Text Files (*.txt)|*.txt|All Files (*.*)|*.*". - /// The filter. - void SetFilter(const WString& value); - - /// Get the filter index. - /// The filter index. - vint GetFilterIndex(); - /// Set the filter index. - /// The filter index. - void SetFilterIndex(vint value); - - /// Get if the file preview is enabled. - /// Returns true if the file preview is enabled. - bool GetEnabledPreview(); - /// Set if the file preview is enabled. - /// Set to true to enable the file preview. - void SetEnabledPreview(bool value); - - /// Get the title. - /// The title. - WString GetTitle(); - /// Set the title. - /// The title. - void SetTitle(const WString& value); - - /// Get the selected file name. - /// The selected file name. - WString GetFileName(); - /// Set the selected file name. - /// The selected file name. - void SetFileName(const WString& value); - - /// Get the default folder. - /// The default folder. - WString GetDirectory(); - /// Set the default folder. - /// The default folder. - void SetDirectory(const WString& value); - - /// Get the default file extension. - /// The default file extension. - WString GetDefaultExtension(); - /// Set the default file extension like "txt". If the user does not specify a file extension, the default file extension will be appended using "." after the file name. - /// The default file extension. - void SetDefaultExtension(const WString& value); - - /// Get the dialog options. - /// The dialog options. - INativeDialogService::FileDialogOptions GetOptions(); - /// Set the dialog options. - /// The dialog options. - void SetOptions(INativeDialogService::FileDialogOptions value); - }; - - /// Open file dialog. - class GuiOpenFileDialog : public GuiFileDialogBase, public Description - { - protected: - collections::List fileNames; - - public: - /// Create a open file dialog. - GuiOpenFileDialog(); - ~GuiOpenFileDialog(); - - /// Get the list to access multiple selected file names. - /// The list to access multiple selected file names. - collections::List& GetFileNames(); - - /// Show the dialog. - /// Returns true if the "Open" button is clicked. - bool ShowDialog(); - }; - - /// Save file dialog. - class GuiSaveFileDialog : public GuiFileDialogBase, public Description - { - public: - /// Create a save file dialog. - GuiSaveFileDialog(); - ~GuiSaveFileDialog(); - - /// Show the dialog. - /// Returns true if the "Save" button is clicked. - bool ShowDialog(); - }; + class GuiPopup; + class GuiTooltip; + class GuiListControl; + class GuiSelectableListControl; + class GuiVirtualTextList; + class GuiTextList; + class GuiListViewColumnHeader; + class GuiListViewBase; + class GuiVirtualListView; + class GuiListView; + class GuiMenu; + class GuiMenuBar; + class GuiMenuButton; + class GuiVirtualTreeListControl; + class GuiVirtualTreeView; + class GuiTreeView; + class GuiComboBoxBase; + class GuiComboBoxListControl; + class GuiToolstripMenu; + class GuiToolstripMenuBar; + class GuiToolstripToolBar; + class GuiToolstripButton; + class GuiToolstripNestedContainer; + class GuiToolstripGroupContainer; + class GuiToolstripGroup; + class GuiRibbonTab; + class GuiRibbonTabPage; + class GuiRibbonGroup; + class GuiRibbonIconLabel; + class GuiRibbonButtons; + class GuiRibbonToolstrips; + class GuiRibbonGallery; + class GuiRibbonToolstripMenu; + class GuiBindableRibbonGalleryList; + class GuiDocumentViewer; + class GuiDocumentLabel; + class GuiMultilineTextBox; + class GuiSinglelineTextBox; + class GuiVirtualDataGrid; + class GuiDatePicker; + class GuiDateComboBox; + class GuiBindableTextList; + class GuiBindableListView; + class GuiBindableTreeView; + class GuiBindableDataGrid; } } } #endif - /*********************************************************************** .\CONTROLS\LISTCONTROLPACKAGE\GUILISTCONTROLS.H ***********************************************************************/ @@ -12732,6 +12478,208 @@ Predefined ItemProvider #endif +/*********************************************************************** +.\CONTROLS\LISTCONTROLPACKAGE\GUILISTCONTROLITEMARRANGERS.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI::Control System + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_CONTROLS_GUILISTCONTROLITEMARRANGERS +#define VCZH_PRESENTATION_CONTROLS_GUILISTCONTROLITEMARRANGERS + + +namespace vl +{ + namespace presentation + { + namespace controls + { + +/*********************************************************************** +Predefined ItemArranger +***********************************************************************/ + + namespace list + { + + /// Ranged item arranger. This arranger implements most of the common functionality for those arrangers that display a continuing subset of item at a time. + class RangedItemArrangerBase : public Object, virtual public GuiListControl::IItemArranger, public Description + { + protected: + using ItemStyleRecord = collections::Pair; + typedef collections::List StyleList; + + GuiListControl* listControl = nullptr; + GuiListControl::IItemArrangerCallback* callback = nullptr; + GuiListControl::IItemProvider* itemProvider = nullptr; + + bool suppressOnViewChanged = false; + Rect viewBounds; + vint startIndex = 0; + StyleList visibleStyles; + + protected: + + void InvalidateAdoptedSize(); + vint CalculateAdoptedSize(vint expectedSize, vint count, vint itemSize); + ItemStyleRecord CreateStyle(vint index); + void DeleteStyle(ItemStyleRecord style); + compositions::GuiBoundsComposition* GetStyleBounds(ItemStyleRecord style); + void ClearStyles(); + void OnViewChangedInternal(Rect oldBounds, Rect newBounds); + virtual void RearrangeItemBounds(); + + virtual void BeginPlaceItem(bool forMoving, Rect newBounds, vint& newStartIndex) = 0; + virtual void PlaceItem(bool forMoving, bool newCreatedStyle, vint index, ItemStyleRecord style, Rect viewBounds, Rect& bounds, Margin& alignmentToParent) = 0; + virtual bool IsItemOutOfViewBounds(vint index, ItemStyleRecord style, Rect bounds, Rect viewBounds) = 0; + virtual bool EndPlaceItem(bool forMoving, Rect newBounds, vint newStartIndex) = 0; + virtual void InvalidateItemSizeCache() = 0; + virtual Size OnCalculateTotalSize() = 0; + public: + /// Create the arranger. + RangedItemArrangerBase(); + ~RangedItemArrangerBase(); + + void OnAttached(GuiListControl::IItemProvider* provider)override; + void OnItemModified(vint start, vint count, vint newCount)override; + void AttachListControl(GuiListControl* value)override; + void DetachListControl()override; + GuiListControl::IItemArrangerCallback* GetCallback()override; + void SetCallback(GuiListControl::IItemArrangerCallback* value)override; + Size GetTotalSize()override; + GuiListControl::ItemStyle* GetVisibleStyle(vint itemIndex)override; + vint GetVisibleIndex(GuiListControl::ItemStyle* style)override; + void ReloadVisibleStyles()override; + void OnViewChanged(Rect bounds)override; + }; + /// Free height item arranger. This arranger will cache heights of all items. + class FreeHeightItemArranger : public RangedItemArrangerBase, public Description + { + private: + bool pim_heightUpdated = false; + + protected: + collections::Array heights; + collections::Array offsets; + vint availableOffsetCount = 0; + + void EnsureOffsetForItem(vint itemIndex); + + void BeginPlaceItem(bool forMoving, Rect newBounds, vint& newStartIndex)override; + void PlaceItem(bool forMoving, bool newCreatedStyle, vint index, ItemStyleRecord style, Rect viewBounds, Rect& bounds, Margin& alignmentToParent)override; + bool IsItemOutOfViewBounds(vint index, ItemStyleRecord style, Rect bounds, Rect viewBounds)override; + bool EndPlaceItem(bool forMoving, Rect newBounds, vint newStartIndex)override; + void InvalidateItemSizeCache()override; + Size OnCalculateTotalSize()override; + public: + /// Create the arranger. + FreeHeightItemArranger(); + ~FreeHeightItemArranger(); + + void OnAttached(GuiListControl::IItemProvider* provider)override; + void OnItemModified(vint start, vint count, vint newCount)override; + vint FindItem(vint itemIndex, compositions::KeyDirection key)override; + GuiListControl::EnsureItemVisibleResult EnsureItemVisible(vint itemIndex)override; + Size GetAdoptedSize(Size expectedSize)override; + }; + + /// Fixed height item arranger. This arranger lists all item with the same height value. This value is the maximum height of all minimum heights of displayed items. + class FixedHeightItemArranger : public RangedItemArrangerBase, public Description + { + private: + vint pi_width = 0; + vint pim_rowHeight = 0; + + protected: + vint rowHeight = 1; + + virtual vint GetWidth(); + virtual vint GetYOffset(); + + void BeginPlaceItem(bool forMoving, Rect newBounds, vint& newStartIndex)override; + void PlaceItem(bool forMoving, bool newCreatedStyle, vint index, ItemStyleRecord style, Rect viewBounds, Rect& bounds, Margin& alignmentToParent)override; + bool IsItemOutOfViewBounds(vint index, ItemStyleRecord style, Rect bounds, Rect viewBounds)override; + bool EndPlaceItem(bool forMoving, Rect newBounds, vint newStartIndex)override; + void InvalidateItemSizeCache()override; + Size OnCalculateTotalSize()override; + public: + /// Create the arranger. + FixedHeightItemArranger(); + ~FixedHeightItemArranger(); + + vint FindItem(vint itemIndex, compositions::KeyDirection key)override; + GuiListControl::EnsureItemVisibleResult EnsureItemVisible(vint itemIndex)override; + Size GetAdoptedSize(Size expectedSize)override; + }; + + /// Fixed size multiple columns item arranger. This arranger adjust all items in multiple lines with the same size. The width is the maximum width of all minimum widths of displayed items. The same to height. + class FixedSizeMultiColumnItemArranger : public RangedItemArrangerBase, public Description + { + private: + Size pim_itemSize; + + protected: + Size itemSize{ 1,1 }; + + void CalculateRange(Size itemSize, Rect bounds, vint count, vint& start, vint& end); + + void BeginPlaceItem(bool forMoving, Rect newBounds, vint& newStartIndex)override; + void PlaceItem(bool forMoving, bool newCreatedStyle, vint index, ItemStyleRecord style, Rect viewBounds, Rect& bounds, Margin& alignmentToParent)override; + bool IsItemOutOfViewBounds(vint index, ItemStyleRecord style, Rect bounds, Rect viewBounds)override; + bool EndPlaceItem(bool forMoving, Rect newBounds, vint newStartIndex)override; + void InvalidateItemSizeCache()override; + Size OnCalculateTotalSize()override; + public: + /// Create the arranger. + FixedSizeMultiColumnItemArranger(); + ~FixedSizeMultiColumnItemArranger(); + + vint FindItem(vint itemIndex, compositions::KeyDirection key)override; + GuiListControl::EnsureItemVisibleResult EnsureItemVisible(vint itemIndex)override; + Size GetAdoptedSize(Size expectedSize)override; + }; + + /// Fixed size multiple columns item arranger. This arranger adjust all items in multiple columns with the same height. The height is the maximum width of all minimum height of displayed items. Each item will displayed using its minimum width. + class FixedHeightMultiColumnItemArranger : public RangedItemArrangerBase, public Description + { + private: + vint pi_currentWidth = 0; + vint pi_totalWidth = 0; + vint pim_itemHeight = 0; + + protected: + vint itemHeight; + + void CalculateRange(vint itemHeight, Rect bounds, vint& rows, vint& startColumn); + + void BeginPlaceItem(bool forMoving, Rect newBounds, vint& newStartIndex)override; + void PlaceItem(bool forMoving, bool newCreatedStyle, vint index, ItemStyleRecord style, Rect viewBounds, Rect& bounds, Margin& alignmentToParent)override; + bool IsItemOutOfViewBounds(vint index, ItemStyleRecord style, Rect bounds, Rect viewBounds)override; + bool EndPlaceItem(bool forMoving, Rect newBounds, vint newStartIndex)override; + void InvalidateItemSizeCache()override; + Size OnCalculateTotalSize()override; + public: + /// Create the arranger. + FixedHeightMultiColumnItemArranger(); + ~FixedHeightMultiColumnItemArranger(); + + vint FindItem(vint itemIndex, compositions::KeyDirection key)override; + GuiListControl::EnsureItemVisibleResult EnsureItemVisible(vint itemIndex)override; + Size GetAdoptedSize(Size expectedSize)override; + }; + } + } + } +} + +#endif + + /*********************************************************************** .\CONTROLS\LISTCONTROLPACKAGE\GUITEXTLISTCONTROLS.H ***********************************************************************/ @@ -13041,7 +12989,6 @@ NodeItemProvider /// The instance of a specified sub node. /// The index of the sub node. virtual Ptr GetChild(vint index)=0; - /// Increase the reference counter. }; /// Represents a root node provider. @@ -13492,6 +13439,2253 @@ DefaultTreeItemTemplate #endif +/*********************************************************************** +.\CONTROLS\TEMPLATES\GUICOMMONTEMPLATES.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI::Template System + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_CONTROLS_TEMPLATES_GUICOMMONTEMPLATES +#define VCZH_PRESENTATION_CONTROLS_TEMPLATES_GUICOMMONTEMPLATES + + +namespace vl +{ + namespace presentation + { + namespace templates + { + +/*********************************************************************** +GuiCommonDatePickerLook +***********************************************************************/ + + class GuiCommonDatePickerLook : public GuiTemplate, public Description + { + protected: + static const vint DaysOfWeek = 7; + static const vint DayRows = 6; + static const vint DayRowStart = 2; + static const vint YearFirst = 1900; + static const vint YearLast = 2099; + + Color backgroundColor; + Color primaryTextColor; + Color secondaryTextColor; + DateTime currentDate; + Locale dateLocale; + FontProperties font; + + TemplateProperty dateButtonTemplate; + TemplateProperty dateTextListTemplate; + TemplateProperty dateComboBoxTemplate; + + controls::IDatePickerCommandExecutor* commands = nullptr; + bool preventComboEvent = false; + bool preventButtonEvent = false; + + controls::GuiComboBoxListControl* comboYear; + controls::GuiTextList* listYears; + controls::GuiComboBoxListControl* comboMonth; + controls::GuiTextList* listMonths; + collections::Array labelDaysOfWeek; + collections::Array buttonDays; + collections::Array labelDays; + collections::Array dateDays; + + void SetDay(const DateTime& day, vint& index, vint monthOffset); + void DisplayMonth(vint year, vint month); + void SelectDay(vint day); + + void comboYearMonth_SelectedIndexChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); + void buttonDay_SelectedChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); + + public: + GuiCommonDatePickerLook(Color _backgroundColor, Color _primaryTextColor, Color _secondaryTextColor); + ~GuiCommonDatePickerLook(); + + compositions::GuiNotifyEvent DateChanged; + + controls::IDatePickerCommandExecutor* GetCommands(); + void SetCommands(controls::IDatePickerCommandExecutor* value); + TemplateProperty GetDateButtonTemplate(); + void SetDateButtonTemplate(const TemplateProperty& value); + TemplateProperty GetDateTextListTemplate(); + void SetDateTextListTemplate(const TemplateProperty& value); + TemplateProperty GetDateComboBoxTemplate(); + void SetDateComboBoxTemplate(const TemplateProperty& value); + + const Locale& GetDateLocale(); + void SetDateLocale(const Locale& value); + const DateTime& GetDate(); + void SetDate(const DateTime& value); + const FontProperties& GetFont(); + void SetFont(const FontProperties& value); + }; + +/*********************************************************************** +GuiCommonScrollViewLook +***********************************************************************/ + + class GuiCommonScrollViewLook : public GuiTemplate, public Description + { + protected: + controls::GuiScroll* horizontalScroll = nullptr; + controls::GuiScroll* verticalScroll = nullptr; + compositions::GuiTableComposition* tableComposition = nullptr; + compositions::GuiCellComposition* containerCellComposition = nullptr; + compositions::GuiBoundsComposition* containerComposition = nullptr; + + vint defaultScrollSize = 12; + TemplateProperty hScrollTemplate; + TemplateProperty vScrollTemplate; + + void UpdateTable(); + void hScroll_OnVisibleChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); + void vScroll_OnVisibleChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); + public: + GuiCommonScrollViewLook(vint _defaultScrollSize); + ~GuiCommonScrollViewLook(); + + controls::GuiScroll* GetHScroll(); + controls::GuiScroll* GetVScroll(); + compositions::GuiGraphicsComposition* GetContainerComposition(); + + TemplateProperty GetHScrollTemplate(); + void SetHScrollTemplate(const TemplateProperty& value); + TemplateProperty GetVScrollTemplate(); + void SetVScrollTemplate(const TemplateProperty& value); + }; + +/*********************************************************************** +GuiCommonScrollBehavior +***********************************************************************/ + + class GuiCommonScrollBehavior : public controls::GuiComponent, public Description + { + protected: + bool dragging = false; + Point location = { 0,0 }; + GuiScrollTemplate* scrollTemplate = nullptr; + + void SetScroll(vint totalPixels, vint newOffset); + void AttachHandle(compositions::GuiGraphicsComposition* handle); + public: + GuiCommonScrollBehavior(); + ~GuiCommonScrollBehavior(); + + void AttachScrollTemplate(GuiScrollTemplate* value); + void AttachDecreaseButton(controls::GuiButton* button); + void AttachIncreaseButton(controls::GuiButton* button); + void AttachHorizontalScrollHandle(compositions::GuiPartialViewComposition* partialView); + void AttachVerticalScrollHandle(compositions::GuiPartialViewComposition* partialView); + void AttachHorizontalTrackerHandle(compositions::GuiPartialViewComposition* partialView); + void AttachVerticalTrackerHandle(compositions::GuiPartialViewComposition* partialView); + + vint GetHorizontalTrackerHandlerPosition(compositions::GuiBoundsComposition* handle, vint totalSize, vint pageSize, vint position); + vint GetVerticalTrackerHandlerPosition(compositions::GuiBoundsComposition* handle, vint totalSize, vint pageSize, vint position); + }; + } + } +} + +#endif + +/*********************************************************************** +.\CONTROLS\TEMPLATES\GUITHEMESTYLEFACTORY.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI::Control Styles::Common Style Helpers + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_CONTROLS_GUITHEMESTYLEFACTORY +#define VCZH_PRESENTATION_CONTROLS_GUITHEMESTYLEFACTORY + + +namespace vl +{ + namespace presentation + { + namespace theme + { +#define GUI_CONTROL_TEMPLATE_TYPES(F) \ + F(WindowTemplate, Window) \ + F(ControlTemplate, CustomControl) \ + F(WindowTemplate, Tooltip) \ + F(LabelTemplate, Label) \ + F(LabelTemplate, ShortcutKey) \ + F(ScrollViewTemplate, ScrollView) \ + F(ControlTemplate, GroupBox) \ + F(TabTemplate, Tab) \ + F(ComboBoxTemplate, ComboBox) \ + F(MultilineTextBoxTemplate, MultilineTextBox) \ + F(SinglelineTextBoxTemplate, SinglelineTextBox) \ + F(DocumentViewerTemplate, DocumentViewer) \ + F(DocumentLabelTemplate, DocumentLabel) \ + F(DocumentLabelTemplate, DocumentTextBox) \ + F(ListViewTemplate, ListView) \ + F(TreeViewTemplate, TreeView) \ + F(TextListTemplate, TextList) \ + F(SelectableButtonTemplate, ListItemBackground) \ + F(SelectableButtonTemplate, TreeItemExpander) \ + F(SelectableButtonTemplate, CheckTextListItem) \ + F(SelectableButtonTemplate, RadioTextListItem) \ + F(MenuTemplate, Menu) \ + F(ControlTemplate, MenuBar) \ + F(ControlTemplate, MenuSplitter) \ + F(ToolstripButtonTemplate, MenuBarButton) \ + F(ToolstripButtonTemplate, MenuItemButton) \ + F(ControlTemplate, ToolstripToolBar) \ + F(ToolstripButtonTemplate, ToolstripButton) \ + F(ToolstripButtonTemplate, ToolstripDropdownButton) \ + F(ToolstripButtonTemplate, ToolstripSplitButton) \ + F(ControlTemplate, ToolstripSplitter) \ + F(RibbonTabTemplate, RibbonTab) \ + F(RibbonGroupTemplate, RibbonGroup) \ + F(RibbonIconLabelTemplate, RibbonIconLabel) \ + F(RibbonIconLabelTemplate, RibbonSmallIconLabel) \ + F(RibbonButtonsTemplate, RibbonButtons) \ + F(RibbonToolstripsTemplate, RibbonToolstrips) \ + F(RibbonGalleryTemplate, RibbonGallery) \ + F(RibbonToolstripMenuTemplate, RibbonToolstripMenu) \ + F(RibbonGalleryListTemplate, RibbonGalleryList) \ + F(TextListTemplate, RibbonGalleryItemList) \ + F(ToolstripButtonTemplate, RibbonSmallButton) \ + F(ToolstripButtonTemplate, RibbonSmallDropdownButton) \ + F(ToolstripButtonTemplate, RibbonSmallSplitButton) \ + F(ToolstripButtonTemplate, RibbonLargeButton) \ + F(ToolstripButtonTemplate, RibbonLargeDropdownButton) \ + F(ToolstripButtonTemplate, RibbonLargeSplitButton) \ + F(ControlTemplate, RibbonSplitter) \ + F(ControlTemplate, RibbonToolstripHeader) \ + F(ButtonTemplate, Button) \ + F(SelectableButtonTemplate, CheckBox) \ + F(SelectableButtonTemplate, RadioButton) \ + F(DatePickerTemplate, DatePicker) \ + F(DateComboBoxTemplate, DateComboBox) \ + F(ScrollTemplate, HScroll) \ + F(ScrollTemplate, VScroll) \ + F(ScrollTemplate, HTracker) \ + F(ScrollTemplate, VTracker) \ + F(ScrollTemplate, ProgressBar) \ + + enum class ThemeName + { + Unknown, +#define GUI_DEFINE_THEME_NAME(TEMPLATE, CONTROL) CONTROL, + GUI_CONTROL_TEMPLATE_TYPES(GUI_DEFINE_THEME_NAME) +#undef GUI_DEFINE_THEME_NAME + }; + + /// Theme interface. A theme creates appropriate style controllers or style providers for default controls. Call [M:vl.presentation.theme.GetCurrentTheme] to access this interface. + class ITheme : public virtual IDescriptable, public Description + { + public: + virtual TemplateProperty CreateStyle(ThemeName themeName) = 0; + }; + + class Theme; + + /// Partial control template collections. [F:vl.presentation.theme.GetCurrentTheme] will returns an object, which walks through multiple registered [T:vl.presentation.theme.ThemeTemplates] to create a correct template object for a control. + class ThemeTemplates : public controls::GuiInstanceRootObject, public AggregatableDescription + { + friend class Theme; + protected: + ThemeTemplates* previous = nullptr; + ThemeTemplates* next = nullptr; + + controls::GuiControlHost* GetControlHostForInstance()override; + public: + ~ThemeTemplates(); + + WString Name; + +#define GUI_DEFINE_ITEM_PROPERTY(TEMPLATE, CONTROL) TemplateProperty CONTROL; + GUI_CONTROL_TEMPLATE_TYPES(GUI_DEFINE_ITEM_PROPERTY) +#undef GUI_DEFINE_ITEM_PROPERTY + }; + + /// Get the current theme style factory object. Call or to change the default theme. + /// The current theme style factory object. + extern ITheme* GetCurrentTheme(); + extern void InitializeTheme(); + extern void FinalizeTheme(); + /// Register a control template collection object. + /// Returns true if this operation succeeded. + /// The control template collection object. + extern bool RegisterTheme(Ptr theme); + /// Unregister a control template collection object. + /// The registered object. Returns null if it does not exist. + /// The name of the theme. + extern Ptr UnregisterTheme(const WString& name); + } + } +} + +#endif + +/*********************************************************************** +.\CONTROLS\TEXTEDITORPACKAGE\EDITORCALLBACK\GUITEXTGENERALOPERATIONS.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI::Control System + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_CONTROLS_GUITEXTGENERALOPERATIONS +#define VCZH_PRESENTATION_CONTROLS_GUITEXTGENERALOPERATIONS + + +namespace vl +{ + namespace presentation + { + namespace controls + { + +/*********************************************************************** +Common Operations +***********************************************************************/ + + /// An text edit callback for text box controls. + class ICommonTextEditCallback : public virtual IDescriptable, public Description + { + public: + /// Callback data for text editing preview. + struct TextEditPreviewStruct + { + /// The start position of the selection before replacing. This field can be modified. + TextPos originalStart; + /// The end position of the selection before replacing. This field can be modified. + TextPos originalEnd; + /// The text of the selection before replacing. + WString originalText; + /// The text of the selection after replacing. This field can be modified. + WString inputText; + /// The base edit version. + vuint editVersion = 0; + /// True if this modification is raised by the keyboard. + bool keyInput = false; + }; + + /// Callback data for text editing. + struct TextEditNotifyStruct + { + /// The start position of the selection before replacing. + TextPos originalStart; + /// The end position of the selection before replacing. + TextPos originalEnd; + /// The text of the selection before replacing. + WString originalText; + /// The start position of the selection after replacing. + TextPos inputStart; + /// The end position of the selection after replacing. + TextPos inputEnd; + /// The text of the selection after replacing. + WString inputText; + /// The created edit version. + vuint editVersion = 0; + /// True if this modification is raised by the keyboard. + bool keyInput = false; + }; + + /// Callback data for text caret changing. + struct TextCaretChangedStruct + { + /// The start position of the selection before caret changing. + TextPos oldBegin; + /// The end position of the selection before caret changing. + TextPos oldEnd; + /// The start position of the selection after caret changing. + TextPos newBegin; + /// The end position of the selection after caret changing. + TextPos newEnd; + /// The current edit version. + vuint editVersion = 0; + }; + + /// Called when the callback is attached to a text box control. + /// The element that used in the text box control. + /// The lock that pretect the element. + /// The owner composition of this element. + /// The current edit version. + virtual void Attach(elements::GuiColorizedTextElement* element, SpinLock& elementModifyLock, compositions::GuiGraphicsComposition* ownerComposition, vuint editVersion)=0; + /// Called when the callback is detached from a text box control. + virtual void Detach()=0; + /// Called before the text is edited. + /// The data for this callback. + virtual void TextEditPreview(TextEditPreviewStruct& arguments)=0; + /// Called after the text is edited and before the caret is changed. + /// The data for this callback. + virtual void TextEditNotify(const TextEditNotifyStruct& arguments)=0; + /// Called after the caret is changed. + /// The data for this callback. + virtual void TextCaretChanged(const TextCaretChangedStruct& arguments)=0; + /// Called after the text is edited and after the caret is changed. + /// The current edit version. + virtual void TextEditFinished(vuint editVersion)=0; + }; + } + } +} + +#endif + +/*********************************************************************** +.\CONTROLS\TEXTEDITORPACKAGE\EDITORCALLBACK\GUITEXTAUTOCOMPLETE.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI::Control System + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_CONTROLS_GUITEXTAUTOCOMPLETE +#define VCZH_PRESENTATION_CONTROLS_GUITEXTAUTOCOMPLETE + + +namespace vl +{ + namespace presentation + { + namespace controls + { + +/*********************************************************************** +GuiTextBoxAutoCompleteBase +***********************************************************************/ + + /// The base class of text box auto complete controller. + class GuiTextBoxAutoCompleteBase : public Object, public virtual ICommonTextEditCallback + { + public: + /// Represents an auto complete candidate item. + struct AutoCompleteItem + { + /// Tag object for any purpose, e.g., data binding. + description::Value tag; + /// Display text for the item. + WString text; + }; + + /// Auto complete control provider. + class IAutoCompleteControlProvider : public virtual Interface + { + public: + /// Get the auto complete control that will be installed in a popup to show candidate items. + /// The auto complete control. + virtual GuiControl* GetAutoCompleteControl() = 0; + + /// Get the list control storing candidate items. + /// The list control. It should be inside the auto complete control, or the auto complete control itself. + virtual GuiSelectableListControl* GetListControl() = 0; + + /// Store candidate items in the list control. + /// Candidate items. + virtual void SetSortedContent(const collections::List& items) = 0; + + /// Get the numbers of all stored candidate items. + /// The number of all stored candidate items. + virtual vint GetItemCount() = 0; + + /// Get the text of a specified item. + /// The index of the item. + /// The text of the item. + virtual WString GetItemText(vint index) = 0; + }; + + class TextListControlProvider : public Object, public virtual IAutoCompleteControlProvider + { + protected: + GuiTextList* autoCompleteList; + + public: + TextListControlProvider(TemplateProperty controlTemplate = {}); + ~TextListControlProvider(); + + GuiControl* GetAutoCompleteControl()override; + GuiSelectableListControl* GetListControl()override; + void SetSortedContent(const collections::List& items)override; + vint GetItemCount()override; + WString GetItemText(vint index)override; + }; + + protected: + elements::GuiColorizedTextElement* element; + SpinLock* elementModifyLock; + compositions::GuiGraphicsComposition* ownerComposition; + GuiPopup* autoCompletePopup; + Ptr autoCompleteControlProvider; + TextPos autoCompleteStartPosition; + + bool IsPrefix(const WString& prefix, const WString& candidate); + public: + /// Create an auto complete. + /// A auto complete control provider. Set to null to use a default one. + GuiTextBoxAutoCompleteBase(Ptr _autoCompleteControlProvider = nullptr); + ~GuiTextBoxAutoCompleteBase(); + + void Attach(elements::GuiColorizedTextElement* _element, SpinLock& _elementModifyLock, compositions::GuiGraphicsComposition* _ownerComposition, vuint editVersion)override; + void Detach()override; + void TextEditPreview(TextEditPreviewStruct& arguments)override; + void TextEditNotify(const TextEditNotifyStruct& arguments)override; + void TextCaretChanged(const TextCaretChangedStruct& arguments)override; + void TextEditFinished(vuint editVersion)override; + + /// Get the list state. + /// Returns true if the list is visible. + bool IsListOpening(); + /// Notify the list to be visible. + /// The text position to show the list. + void OpenList(TextPos startPosition); + /// Notify the list to be invisible. + void CloseList(); + /// Set the content of the list. + /// The content of the list. + void SetListContent(const collections::List& items); + /// Get the last start position when the list is opened. + /// The start position. + TextPos GetListStartPosition(); + /// Select the previous item. + /// Returns true if this operation succeeded. + bool SelectPreviousListItem(); + /// Select the next item. + /// Returns true if this operation succeeded. + bool SelectNextListItem(); + /// Apply the selected item into the text box. + /// Returns true if this operation succeeded. + bool ApplySelectedListItem(); + /// Get the selected item. + /// The text of the selected item. Returns empty if there is no selected item. + WString GetSelectedListItem(); + /// Highlight a candidate item in the list. + /// The text to match an item. + void HighlightList(const WString& editingText); + }; + } + } +} + +#endif + +/*********************************************************************** +.\CONTROLS\TEXTEDITORPACKAGE\EDITORCALLBACK\GUITEXTCOLORIZER.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI::Control System + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_CONTROLS_GUITEXTCOLORIZER +#define VCZH_PRESENTATION_CONTROLS_GUITEXTCOLORIZER + + +namespace vl +{ + namespace presentation + { + namespace controls + { + +/*********************************************************************** +GuiTextBoxColorizerBase +***********************************************************************/ + + /// The base class of text box colorizer. + class GuiTextBoxColorizerBase : public Object, public virtual ICommonTextEditCallback + { + public: + typedef collections::Array ColorArray; + protected: + elements::GuiColorizedTextElement* element; + SpinLock* elementModifyLock; + volatile vint colorizedLineCount; + volatile bool isColorizerRunning; + volatile bool isFinalizing; + SpinLock colorizerRunningEvent; + + static void ColorizerThreadProc(void* argument); + + void StartColorizer(); + void StopColorizer(bool forever); + void StopColorizerForever(); + public: + /// Create a colorrizer. + GuiTextBoxColorizerBase(); + ~GuiTextBoxColorizerBase(); + + void Attach(elements::GuiColorizedTextElement* _element, SpinLock& _elementModifyLock, compositions::GuiGraphicsComposition* _ownerComposition, vuint editVersion)override; + void Detach()override; + void TextEditPreview(TextEditPreviewStruct& arguments)override; + void TextEditNotify(const TextEditNotifyStruct& arguments)override; + void TextCaretChanged(const TextCaretChangedStruct& arguments)override; + void TextEditFinished(vuint editVersion)override; + void RestartColorizer(); + + /// Get the lexical analyzer start state for the first line. + /// The lexical analyzer start state for the first line. + virtual vint GetLexerStartState()=0; + /// Get the context sensitive start state for the first line. + /// The context sensitive start state for the first line. + virtual vint GetContextStartState()=0; + /// Colorizer one line with a start state. + /// Line index. + /// Text buffer. + /// Color index buffer. The index should be in [0 .. [M:vl.presentation.controls.GuiTextBoxColorizerBase.GetColors]()-1]. + /// The length of the buffer. + /// The lexical analyzer state for this line. After executing this function, the new value of this argument indicates the new state. + /// The context sensitive state for this line. After executing this function, the new value of this argument indicates the new state. + virtual void ColorizeLineWithCRLF(vint lineIndex, const wchar_t* text, vuint32_t* colors, vint length, vint& lexerState, vint& contextState)=0; + /// Get the supported colors ordered by their indices. + /// The supported colors ordered by their indices. + virtual const ColorArray& GetColors()=0; + }; + +/*********************************************************************** +GuiTextBoxRegexColorizer +***********************************************************************/ + + /// Regex based colorizer. + class GuiTextBoxRegexColorizer : public GuiTextBoxColorizerBase + { + protected: + Ptr lexer; + Ptr colorizer; + void* colorizerArgument[1] { nullptr }; + ColorArray colors; + + elements::text::ColorEntry defaultColor; + collections::List tokenRegexes; + collections::List tokenColors; + collections::List extraTokenColors; + + static void ColorizerProc(void* argument, vint start, vint length, vint token); + public: + /// Create the colorizer. + GuiTextBoxRegexColorizer(); + ~GuiTextBoxRegexColorizer(); + + /// Get the default color. + /// The default color. + elements::text::ColorEntry GetDefaultColor(); + /// Get all regular expressions for tokens. + /// All regular expressions for tokens. + collections::List& GetTokenRegexes(); + /// Get all colors for tokens. + /// All colors for tokens. + collections::List& GetTokenColors(); + /// Get all colors for extra tokens. + /// All colors for extra tokens. + collections::List& GetExtraTokenColors(); + /// Get the first token index for the first extra token. + /// The first token index for the first extra token. Returns -1 if this operation failed. + vint GetExtraTokenIndexStart(); + + /// Set the default color. Call [M:vl.presentation.controls.GuiTextBoxRegexColorizer.Setup] after finishing all configuration. + /// Returns the token index of this token. Returns -1 if this operation failed. + /// The default color. + bool SetDefaultColor(elements::text::ColorEntry value); + /// Add a token type. Call [M:vl.presentation.controls.GuiTextBoxRegexColorizer.Setup] after finishing all configuration. + /// Returns the token index of this token. Returns -1 if this operation failed. + /// The regular expression for this token type. + /// The color for this token type. + vint AddToken(const WString& regex, elements::text::ColorEntry color); + /// Add an extra token type. Call [M:vl.presentation.controls.GuiTextBoxRegexColorizer.Setup] after finishing all configuration. + /// Returns the extra token index of this token. The token index for this token is regex-token-count + extra-token-index Returns -1 if this operation failed. + /// The color for this token type. + vint AddExtraToken(elements::text::ColorEntry color); + /// Clear all token color settings. + void ClearTokens(); + /// Setup the colorizer. After that, the colorizer cannot be changed. + void Setup(); + /// Callback function to set context sensitive state and change token accordingly. + /// Line index. + /// Text buffer. + /// The start position of the token. + /// The length of the token. + /// The token type. After executing this function, the new value of this argument indicates the new token type. + /// The context sensitive state. After executing this function, the new value of this argument indicates the new state. + virtual void ColorizeTokenContextSensitive(vint lineIndex, const wchar_t* text, vint start, vint length, vint& token, vint& contextState); + + vint GetLexerStartState()override; + vint GetContextStartState()override; + void ColorizeLineWithCRLF(vint lineIndex, const wchar_t* text, vuint32_t* colors, vint length, vint& lexerState, vint& contextState)override; + const ColorArray& GetColors()override; + }; + } + } +} + +#endif + +/*********************************************************************** +.\CONTROLS\TEXTEDITORPACKAGE\EDITORCALLBACK\GUITEXTUNDOREDO.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI::Control System + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_CONTROLS_GUITEXTUNDOREDO +#define VCZH_PRESENTATION_CONTROLS_GUITEXTUNDOREDO + + +namespace vl +{ + namespace presentation + { + namespace controls + { + class GuiTextBoxCommonInterface; + +/*********************************************************************** +Undo Redo +***********************************************************************/ + + class GuiGeneralUndoRedoProcessor : public Object + { + protected: + class IEditStep : public Interface + { + public: + virtual void Undo()=0; + virtual void Redo()=0; + }; + friend class collections::ArrayBase>; + + protected: + collections::List> steps; + vint firstFutureStep; + vint savedStep; + bool performingUndoRedo; + + void PushStep(Ptr step); + public: + GuiGeneralUndoRedoProcessor(); + ~GuiGeneralUndoRedoProcessor(); + + Event UndoRedoChanged; + Event ModifiedChanged; + + bool CanUndo(); + bool CanRedo(); + void ClearUndoRedo(); + bool GetModified(); + void NotifyModificationSaved(); + bool Undo(); + bool Redo(); + }; + +/*********************************************************************** +Undo Redo (Text) +***********************************************************************/ + + class GuiTextBoxUndoRedoProcessor : public GuiGeneralUndoRedoProcessor, public ICommonTextEditCallback + { + protected: + class EditStep : public Object, public IEditStep + { + public: + GuiTextBoxUndoRedoProcessor* processor; + TextEditNotifyStruct arguments; + + void Undo(); + void Redo(); + }; + + compositions::GuiGraphicsComposition* ownerComposition; + public: + GuiTextBoxUndoRedoProcessor(); + ~GuiTextBoxUndoRedoProcessor(); + + void Attach(elements::GuiColorizedTextElement* element, SpinLock& elementModifyLock, compositions::GuiGraphicsComposition* _ownerComposition, vuint editVersion)override; + void Detach()override; + void TextEditPreview(TextEditPreviewStruct& arguments)override; + void TextEditNotify(const TextEditNotifyStruct& arguments)override; + void TextCaretChanged(const TextCaretChangedStruct& arguments)override; + void TextEditFinished(vuint editVersion)override; + }; + +/*********************************************************************** +Undo Redo (Document) +***********************************************************************/ + + class GuiDocumentUndoRedoProcessor : public GuiGeneralUndoRedoProcessor + { + public: + struct ReplaceModelStruct + { + TextPos originalStart; + TextPos originalEnd; + Ptr originalModel; + TextPos inputStart; + TextPos inputEnd; + Ptr inputModel; + + ReplaceModelStruct() + { + } + }; + + struct RenameStyleStruct + { + WString oldStyleName; + WString newStyleName; + + RenameStyleStruct() + { + } + }; + + struct SetAlignmentStruct + { + vint start; + vint end; + collections::Array> originalAlignments; + collections::Array> inputAlignments; + }; + + protected: + elements::GuiDocumentElement* element; + compositions::GuiGraphicsComposition* ownerComposition; + + class ReplaceModelStep : public Object, public IEditStep + { + public: + GuiDocumentUndoRedoProcessor* processor; + ReplaceModelStruct arguments; + + void Undo(); + void Redo(); + }; + + class RenameStyleStep : public Object, public IEditStep + { + public: + GuiDocumentUndoRedoProcessor* processor; + RenameStyleStruct arguments; + + void Undo(); + void Redo(); + }; + + class SetAlignmentStep : public Object, public IEditStep + { + public: + GuiDocumentUndoRedoProcessor* processor; + Ptr arguments; + + void Undo(); + void Redo(); + }; + public: + + GuiDocumentUndoRedoProcessor(); + ~GuiDocumentUndoRedoProcessor(); + + void Setup(elements::GuiDocumentElement* _element, compositions::GuiGraphicsComposition* _ownerComposition); + void OnReplaceModel(const ReplaceModelStruct& arguments); + void OnRenameStyle(const RenameStyleStruct& arguments); + void OnSetAlignment(Ptr arguments); + }; + } + } +} + +#endif + +/*********************************************************************** +.\CONTROLS\TEXTEDITORPACKAGE\GUIDOCUMENTVIEWER.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI::Control System + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_CONTROLS_GUIDOCUMENTVIEWER +#define VCZH_PRESENTATION_CONTROLS_GUIDOCUMENTVIEWER + + +namespace vl +{ + namespace presentation + { + namespace compositions + { + class GuiShortcutKeyManager; + } + + namespace controls + { + +/*********************************************************************** +GuiDocumentCommonInterface +***********************************************************************/ + + class GuiDocumentCommonInterface; + + /// Embedded object in a document. + class GuiDocumentItem : public Object, public Description + { + friend class GuiDocumentCommonInterface; + protected: + bool visible = false; + WString name; + compositions::GuiBoundsComposition* container; + bool owned = false; + public: + GuiDocumentItem(const WString& _name); + ~GuiDocumentItem(); + + /// Get the container for all embedded controls and compositions in this item. + /// The container. + compositions::GuiGraphicsComposition* GetContainer(); + + /// Get the name of the document item. + /// The name. + WString GetName(); + }; + + /// Document displayer control common interface for displaying . + class GuiDocumentCommonInterface abstract + : protected virtual elements::GuiDocumentElement::ICallback + , 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: + Ptr baselineDocument; + DocumentItemMap documentItems; + GuiControl* documentControl = nullptr; + elements::GuiDocumentElement* documentElement = nullptr; + compositions::GuiBoundsComposition* documentComposition = nullptr; + Ptr activeHyperlinks; + bool dragging = false; + EditMode editMode = EditMode::ViewOnly; + + Ptr undoRedoProcessor; + Ptr internalShortcutKeyManager; + + protected: + void InvokeUndoRedoChanged(); + void InvokeModifiedChanged(); + void UpdateCaretPoint(); + void Move(TextPos caret, bool shift, bool frontSide); + bool ProcessKey(VKEY code, bool shift, bool ctrl); + void InstallDocumentViewer(GuiControl* _sender, compositions::GuiGraphicsComposition* _container, compositions::GuiGraphicsComposition* eventComposition, compositions::GuiGraphicsComposition* focusableComposition); + void SetActiveHyperlink(Ptr package); + void ActivateActiveHyperlink(bool activate); + void AddShortcutCommand(VKEY key, const Func& eventHandler); + void EditTextInternal(TextPos begin, TextPos end, const Func& editor); + void EditStyleInternal(TextPos begin, TextPos end, const Func& editor); + + void MergeBaselineAndDefaultFont(Ptr document); + void OnFontChanged(); + void OnCaretNotify(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); + void OnGotFocus(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); + void OnLostFocus(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); + void OnKeyDown(compositions::GuiGraphicsComposition* sender, compositions::GuiKeyEventArgs& arguments); + void OnCharInput(compositions::GuiGraphicsComposition* sender, compositions::GuiCharEventArgs& arguments); + void OnMouseMove(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments); + void OnMouseDown(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments); + void OnMouseUp(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments); + void OnMouseLeave(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); + + virtual Point GetDocumentViewPosition(); + virtual void EnsureRectVisible(Rect bounds); + + //================ callback + + void OnStartRender()override; + void OnFinishRender()override; + Size OnRenderEmbeddedObject(const WString& name, const Rect& location)override; + public: + GuiDocumentCommonInterface(); + ~GuiDocumentCommonInterface(); + + /// Active hyperlink changed event. + compositions::GuiNotifyEvent ActiveHyperlinkChanged; + /// Active hyperlink executed event. + compositions::GuiNotifyEvent ActiveHyperlinkExecuted; + + /// Selection changed event. + compositions::GuiNotifyEvent SelectionChanged; + /// Undo redo status changed event. + compositions::GuiNotifyEvent UndoRedoChanged; + /// Modified status changed event. + compositions::GuiNotifyEvent ModifiedChanged; + + /// Get the document. + /// The document. + Ptr GetDocument(); + /// 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); + + //================ document items + + /// Add a document item. The name of the document item will display in the position of the <object> element with the same name in the document. + /// The document item. + /// Returns true if this operation succeeded. + bool AddDocumentItem(Ptr value); + + /// Remove a document item. + /// The document item. + /// Returns true if this operation succeeded. + bool RemoveDocumentItem(Ptr value); + + /// Get all document items. + /// All document items. + const DocumentItemMap& GetDocumentItems(); + + //================ caret operations + + /// + /// Get the begin position of the selection area. + /// + /// The begin position of the selection area. + TextPos GetCaretBegin(); + /// + /// Get the end position of the selection area. + /// + /// The end position of the selection area. + TextPos GetCaretEnd(); + /// + /// Set the end position of the selection area. + /// + /// The begin position of the selection area. + /// The end position of the selection area. + void SetCaret(TextPos begin, TextPos end); + /// Calculate a caret using a specified point. + /// The calculated caret. + /// The specified point. + TextPos CalculateCaretFromPoint(Point point); + /// Get the bounds of a caret. + /// The bounds. + /// The caret. + /// Set to true to get the bounds for the character before it. + Rect GetCaretBounds(TextPos caret, bool frontSide); + + //================ editing operations + + /// Notify that some paragraphs are updated. + /// The start paragraph index. + /// The number of paragraphs to be updated. + /// The number of updated paragraphs. + /// Set to true to notify that the text is updated. + void NotifyParagraphUpdated(vint index, vint oldCount, vint newCount, bool updatedText); + /// Edit run in a specified range. + /// The begin position of the range. + /// The end position of the range. + /// The new run. + /// Set to true to copy the model before editing. Otherwise, objects inside the model will be used directly + void EditRun(TextPos begin, TextPos end, Ptr model, bool copy); + /// Edit text in a specified range. + /// The begin position of the range. + /// The end position of the range. + /// Set to true to use the text style in front of the specified range. + /// The new text. + void EditText(TextPos begin, TextPos end, bool frontSide, const collections::Array& text); + /// Edit style in a specified range. + /// The begin position of the range. + /// The end position of the range. + /// The new style. + void EditStyle(TextPos begin, TextPos end, Ptr style); + /// Edit image in a specified range. + /// The begin position of the range. + /// The end position of the range. + /// The new image. + void EditImage(TextPos begin, TextPos end, Ptr image); + /// Set hyperlink in a specified range. + /// The index of the paragraph to edit. + /// The begin position of the range. + /// The end position of the range. + /// The reference of the hyperlink. + /// The normal style name of the hyperlink. + /// The active style name of the hyperlink. + void EditHyperlink(vint paragraphIndex, vint begin, vint end, const WString& reference, const WString& normalStyleName=DocumentModel::NormalLinkStyleName, const WString& activeStyleName=DocumentModel::ActiveLinkStyleName); + /// Remove hyperlink in a specified range. + /// The index of the paragraph to edit. + /// The begin position of the range. + /// The end position of the range. + void RemoveHyperlink(vint paragraphIndex, vint begin, vint end); + /// Edit style name in a specified range. + /// The begin position of the range. + /// The end position of the range. + /// The new style name. + void EditStyleName(TextPos begin, TextPos end, const WString& styleName); + /// Remove style name in a specified range. + /// The begin position of the range. + /// The end position of the range. + void RemoveStyleName(TextPos begin, TextPos end); + /// Rename a style. + /// The name of the style. + /// The new name. + void RenameStyle(const WString& oldStyleName, const WString& newStyleName); + /// Clear all styles in a specified range. + /// The begin position of the range. + /// The end position of the range. + void ClearStyle(TextPos begin, TextPos end); + /// Summarize the text style in a specified range. + /// The text style summary. + /// The begin position of the range. + /// The end position of the range. + Ptr SummarizeStyle(TextPos begin, TextPos end); + /// Summarize the style name in a specified range. + /// The style name summary. + /// The begin position of the range. + /// The end position of the range. + Nullable SummarizeStyleName(TextPos begin, TextPos end); + /// Set the alignment of paragraphs in a specified range. + /// The begin position of the range. + /// The end position of the range. + /// The alignment for each paragraph. + void SetParagraphAlignments(TextPos begin, TextPos end, const collections::Array>& alignments); + /// Set the alignment of paragraphs in a specified range. + /// The begin position of the range. + /// The end position of the range. + /// The alignment for each paragraph. + void SetParagraphAlignment(TextPos begin, TextPos end, Nullable alignment); + /// Summarize the text alignment in a specified range. + /// The text alignment summary. + /// The begin position of the range. + /// The end position of the range. + Nullable SummarizeParagraphAlignment(TextPos begin, TextPos end); + + //================ editing control + + /// Get the href attribute of the active hyperlink. + /// The href attribute of the active hyperlink. + WString GetActiveHyperlinkReference(); + /// Get the edit mode of this control. + /// The edit mode. + EditMode GetEditMode(); + /// Set the edit mode of this control. + /// The edit mode. + void SetEditMode(EditMode value); + + //================ selection operations + + /// Select all text. + void SelectAll(); + /// Get the selected text. + /// The selected text. + WString GetSelectionText(); + /// Set the selected text. + /// The selected text. + void SetSelectionText(const WString& value); + /// Get the selected model. + /// The selected model. + Ptr GetSelectionModel(); + /// Set the selected model. + /// The selected model. + void SetSelectionModel(Ptr value); + + //================ clipboard operations + + /// Test can the selection be cut. + /// Returns true if the selection can be cut. + bool CanCut(); + /// Test can the selection be copied. + /// Returns true if the selection can be cut. + bool CanCopy(); + /// Test can the content in the clipboard be pasted. + /// Returns true if the content in the clipboard can be pasted. + bool CanPaste(); + /// Cut the selection text. + /// Returns true if this operation succeeded. + bool Cut(); + /// Copy the selection text. + /// Returns true if this operation succeeded. + bool Copy(); + /// Paste the content from the clipboard and replace the selected text. + /// Returns true if this operation succeeded. + bool Paste(); + + //================ undo redo control + + /// Test can undo. + /// Returns true if this action can be performed. + bool CanUndo(); + /// Test can redo. + /// Returns true if this action can be performed. + bool CanRedo(); + /// Clear all undo and redo information. + void ClearUndoRedo(); + /// Test is the text box modified. + /// Returns true if the text box is modified. + bool GetModified(); + /// Notify the text box that the current status is considered saved. + void NotifyModificationSaved(); + /// Perform the undo action. + /// Returns true if this operation succeeded. + bool Undo(); + /// Perform the redo action. + /// Returns true if this operation succeeded. + bool Redo(); + }; + +/*********************************************************************** +GuiDocumentViewer +***********************************************************************/ + + /// Scrollable document viewer for displaying . + class GuiDocumentViewer : public GuiScrollContainer, public GuiDocumentCommonInterface, public Description + { + GUI_SPECIFY_CONTROL_TEMPLATE_TYPE(DocumentViewerTemplate, GuiScrollContainer) + protected: + + void UpdateDisplayFont()override; + Point GetDocumentViewPosition()override; + void EnsureRectVisible(Rect bounds)override; + public: + /// Create a control with a specified style provider. + /// The theme name for retriving a default control template. + GuiDocumentViewer(theme::ThemeName themeName); + ~GuiDocumentViewer(); + + const WString& GetText()override; + void SetText(const WString& value)override; + }; + +/*********************************************************************** +GuiDocumentViewer +***********************************************************************/ + + /// Static document viewer for displaying . + class GuiDocumentLabel : public GuiControl, public GuiDocumentCommonInterface, public Description + { + GUI_SPECIFY_CONTROL_TEMPLATE_TYPE(DocumentLabelTemplate, GuiControl) + protected: + + void UpdateDisplayFont()override; + public: + /// Create a control with a specified default theme. + /// The theme name for retriving a default control template. + GuiDocumentLabel(theme::ThemeName themeName); + ~GuiDocumentLabel(); + + const WString& GetText()override; + void SetText(const WString& value)override; + }; + } + } +} + +#endif + + +/*********************************************************************** +.\CONTROLS\TEXTEDITORPACKAGE\GUITEXTCOMMONINTERFACE.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI::Control System + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_CONTROLS_GUITEXTCOMMONINTERFACE +#define VCZH_PRESENTATION_CONTROLS_GUITEXTCOMMONINTERFACE + + +namespace vl +{ + namespace presentation + { + namespace compositions + { + class GuiShortcutKeyManager; + } + + namespace controls + { + +/*********************************************************************** +Common Interface +***********************************************************************/ + + /// Common interface for text box controls. + class GuiTextBoxCommonInterface abstract : public Description + { + typedef collections::Array ColorArray; + protected: + class ICallback : public virtual IDescriptable, public Description + { + public: + virtual TextPos GetLeftWord(TextPos pos)=0; + virtual TextPos GetRightWord(TextPos pos)=0; + virtual void GetWord(TextPos pos, TextPos& begin, TextPos& end)=0; + virtual vint GetPageRows()=0; + virtual bool BeforeModify(TextPos start, TextPos end, const WString& originalText, WString& inputText)=0; + virtual void AfterModify(TextPos originalStart, TextPos originalEnd, const WString& originalText, TextPos inputStart, TextPos inputEnd, const WString& inputText)=0; + virtual void ScrollToView(Point point)=0; + virtual vint GetTextMargin()=0; + }; + + class DefaultCallback : public Object, public ICallback, public Description + { + protected: + elements::GuiColorizedTextElement* textElement; + compositions::GuiGraphicsComposition* textComposition; + bool readonly; + public: + DefaultCallback(elements::GuiColorizedTextElement* _textElement, compositions::GuiGraphicsComposition* _textComposition); + ~DefaultCallback(); + + TextPos GetLeftWord(TextPos pos)override; + TextPos GetRightWord(TextPos pos)override; + void GetWord(TextPos pos, TextPos& begin, TextPos& end)override; + vint GetPageRows()override; + bool BeforeModify(TextPos start, TextPos end, const WString& originalText, WString& inputText)override; + }; + private: + elements::GuiColorizedTextElement* textElement; + compositions::GuiGraphicsComposition* textComposition; + vuint editVersion; + GuiControl* textControl; + ICallback* callback; + bool dragging; + bool readonly; + Ptr colorizer; + Ptr autoComplete; + Ptr undoRedoProcessor; + + bool filledDefaultColors = false; + ColorArray defaultColors; + + SpinLock elementModifyLock; + collections::List> textEditCallbacks; + Ptr internalShortcutKeyManager; + bool preventEnterDueToAutoComplete; + + void InvokeUndoRedoChanged(); + void InvokeModifiedChanged(); + void UpdateCaretPoint(); + void Move(TextPos pos, bool shift); + void Modify(TextPos start, TextPos end, const WString& input, bool asKeyInput); + bool ProcessKey(VKEY code, bool shift, bool ctrl); + + void OnGotFocus(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); + void OnLostFocus(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); + void OnCaretNotify(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); + + void OnLeftButtonDown(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments); + void OnLeftButtonUp(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments); + void OnMouseMove(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments); + void OnKeyDown(compositions::GuiGraphicsComposition* sender, compositions::GuiKeyEventArgs& arguments); + void OnCharInput(compositions::GuiGraphicsComposition* sender, compositions::GuiCharEventArgs& arguments); + + protected: + + void Install(elements::GuiColorizedTextElement* _textElement, compositions::GuiGraphicsComposition* _textComposition, GuiControl* _textControl, compositions::GuiGraphicsComposition* eventComposition, compositions::GuiGraphicsComposition* focusableComposition); + ICallback* GetCallback(); + void SetCallback(ICallback* value); + bool AttachTextEditCallback(Ptr value); + bool DetachTextEditCallback(Ptr value); + void AddShortcutCommand(VKEY key, const Func& eventHandler); + elements::GuiColorizedTextElement* GetTextElement(); + void UnsafeSetText(const WString& value); + + public: + GuiTextBoxCommonInterface(); + ~GuiTextBoxCommonInterface(); + + /// Selection changed event. + compositions::GuiNotifyEvent SelectionChanged; + /// Undo redo status changed event. + compositions::GuiNotifyEvent UndoRedoChanged; + /// Modified status changed event. + compositions::GuiNotifyEvent ModifiedChanged; + + //================ clipboard operations + + /// Test can the selection be cut. + /// Returns true if the selection can be cut. + bool CanCut(); + /// Test can the selection be copied. + /// Returns true if the selection can be cut. + bool CanCopy(); + /// Test can the content in the clipboard be pasted. + /// Returns true if the content in the clipboard can be pasted. + bool CanPaste(); + /// Cut the selection text. + /// Returns true if this operation succeeded. + bool Cut(); + /// Copy the selection text. + /// Returns true if this operation succeeded. + bool Copy(); + /// Paste the content from the clipboard and replace the selected text. + /// Returns true if this operation succeeded. + bool Paste(); + + //================ editing control + + /// Get the readonly mode. + /// Returns true if the text box is readonly. + bool GetReadonly(); + /// Set the readonly mode. + /// Set to true to make the texg box readonly. + void SetReadonly(bool value); + + //================ text operations + + /// Select all text. + void SelectAll(); + /// Select (highlight) a part of text. + /// The begin position. + /// The end position. This is also the caret position. + void Select(TextPos begin, TextPos end); + /// Get the selected text. + /// The selected text. + WString GetSelectionText(); + /// Set the selected text. + /// The selected text. + void SetSelectionText(const WString& value); + /// Set the selected text and let to text box treat this changing as input by the keyboard. + /// The selected text. + void SetSelectionTextAsKeyInput(const WString& value); + + /// Get the text from a specified row number. + /// The text from a specified row number. + /// The specified row number. + WString GetRowText(vint row); + /// Get the number of rows. + /// The number of rows. + vint GetRowCount(); + /// Get the text from a specified range. + /// The text from a specified range. + /// The specified start position. + /// The specified end position. + WString GetFragmentText(TextPos start, TextPos end); + + /// Get the begin text position of the selection. + /// The begin text position of the selection. + TextPos GetCaretBegin(); + /// Get the end text position of the selection. + /// The end text position of the selection. + TextPos GetCaretEnd(); + /// Get the left-top text position of the selection. + /// The left-top text position of the selection. + TextPos GetCaretSmall(); + /// Get the right-bottom text position of the selection. + /// The right-bottom text position of the selection. + TextPos GetCaretLarge(); + + //================ position query + + /// Get the width of a row. + /// The width of a row in pixel. + /// The specified row number + vint GetRowWidth(vint row); + /// Get the height of a row. + /// The height of a row in pixel. + vint GetRowHeight(); + /// Get the maximum width of all rows. + /// The maximum width of all rows. + vint GetMaxWidth(); + /// Get the total height of all rows. + /// The total height of all rows. + vint GetMaxHeight(); + /// Get the nearest position of a character from a specified display position. + /// Get the nearest position of a character. + /// The specified display position. + TextPos GetTextPosFromPoint(Point point); + /// Get the display position of a character from a specified text position. + /// Get the display position of a character. + /// The specified text position. + Point GetPointFromTextPos(TextPos pos); + /// Get the display bounds of a character from a specified text position. + /// Get the display bounds of a character. + /// The specified text position. + Rect GetRectFromTextPos(TextPos pos); + /// Get the nearest text position from a specified display position. + /// Get the nearest text position. + /// The specified display position. + TextPos GetNearestTextPos(Point point); + + //================ colorizing + + /// Get the current colorizer. + /// The current colorizer. + Ptr GetColorizer(); + /// Set the current colorizer. + /// The current colorizer. + void SetColorizer(Ptr value); + + //================ auto complete + + /// Get the current auto complete controller. + /// The current auto complete controller. + Ptr GetAutoComplete(); + /// Set the current auto complete controller. + /// The current auto complete controller. + void SetAutoComplete(Ptr value); + + //================ undo redo control + + /// Get the current edit version. When the control is modified, the edit version increased. Calling will not reset the edit version. + /// The current edit version. + vuint GetEditVersion(); + /// Test can undo. + /// Returns true if this action can be performed. + bool CanUndo(); + /// Test can redo. + /// Returns true if this action can be performed. + bool CanRedo(); + /// Clear all undo and redo information. + void ClearUndoRedo(); + /// Test is the text box modified. + /// Returns true if the text box is modified. + bool GetModified(); + /// Notify the text box that the current status is considered saved. + void NotifyModificationSaved(); + /// Perform the undo action. + /// Returns true if this operation succeeded. + bool Undo(); + /// Perform the redo action. + /// Returns true if this operation succeeded. + bool Redo(); + }; + } + } +} + +#endif + +/*********************************************************************** +.\CONTROLS\TEXTEDITORPACKAGE\GUITEXTCONTROLS.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI::Control System + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_CONTROLS_GUITEXTCONTROLS +#define VCZH_PRESENTATION_CONTROLS_GUITEXTCONTROLS + + +namespace vl +{ + namespace presentation + { + namespace controls + { + +/*********************************************************************** +MultilineTextBox +***********************************************************************/ + + /// Multiline text box control. + class GuiMultilineTextBox : public GuiScrollView, public GuiTextBoxCommonInterface, public Description + { + GUI_SPECIFY_CONTROL_TEMPLATE_TYPE(MultilineTextBoxTemplate, GuiScrollView) + public: + static const vint TextMargin=3; + + class CommandExecutor : public Object, public ITextBoxCommandExecutor + { + protected: + GuiMultilineTextBox* textBox; + + public: + CommandExecutor(GuiMultilineTextBox* _textBox); + ~CommandExecutor(); + + void UnsafeSetText(const WString& value)override; + }; + + protected: + class TextElementOperatorCallback : public GuiTextBoxCommonInterface::DefaultCallback, public Description + { + protected: + GuiMultilineTextBox* textControl; + public: + TextElementOperatorCallback(GuiMultilineTextBox* _textControl); + + void AfterModify(TextPos originalStart, TextPos originalEnd, const WString& originalText, TextPos inputStart, TextPos inputEnd, const WString& inputText)override; + void ScrollToView(Point point)override; + vint GetTextMargin()override; + }; + + protected: + Ptr callback; + Ptr commandExecutor; + elements::GuiColorizedTextElement* textElement = nullptr; + compositions::GuiBoundsComposition* textComposition = nullptr; + + void UpdateVisuallyEnabled()override; + void UpdateDisplayFont()override; + void OnRenderTargetChanged(elements::IGuiGraphicsRenderTarget* renderTarget)override; + Size QueryFullSize()override; + void UpdateView(Rect viewBounds)override; + void CalculateViewAndSetScroll(); + void OnBoundsMouseButtonDown(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments); + public: + /// Create a control with a specified style provider. + /// The theme name for retriving a default control template. + GuiMultilineTextBox(theme::ThemeName themeName); + ~GuiMultilineTextBox(); + + const WString& GetText()override; + void SetText(const WString& value)override; + }; + +/*********************************************************************** +SinglelineTextBox +***********************************************************************/ + + /// Single text box control. + class GuiSinglelineTextBox : public GuiControl, public GuiTextBoxCommonInterface, public Description + { + GUI_SPECIFY_CONTROL_TEMPLATE_TYPE(SinglelineTextBoxTemplate, GuiControl) + public: + static const vint TextMargin=2; + + protected: + class TextElementOperatorCallback : public GuiTextBoxCommonInterface::DefaultCallback, public Description + { + public: + TextElementOperatorCallback(GuiSinglelineTextBox* _textControl); + + bool BeforeModify(TextPos start, TextPos end, const WString& originalText, WString& inputText)override; + void AfterModify(TextPos originalStart, TextPos originalEnd, const WString& originalText, TextPos inputStart, TextPos inputEnd, const WString& inputText)override; + void ScrollToView(Point point)override; + vint GetTextMargin()override; + }; + + protected: + Ptr callback; + elements::GuiColorizedTextElement* textElement = nullptr; + compositions::GuiTableComposition* textCompositionTable = nullptr; + compositions::GuiCellComposition* textComposition = nullptr; + + void UpdateVisuallyEnabled()override; + void UpdateDisplayFont()override; + void RearrangeTextElement(); + void OnRenderTargetChanged(elements::IGuiGraphicsRenderTarget* renderTarget)override; + void OnBoundsMouseButtonDown(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments); + public: + /// Create a control with a specified style provider. + /// The theme name for retriving a default control template. + GuiSinglelineTextBox(theme::ThemeName themeName); + ~GuiSinglelineTextBox(); + + const WString& GetText()override; + void SetText(const WString& value)override; + + /// + /// Get the password mode displaying character. + /// + /// The password mode displaying character. Returns L'\0' means the password mode is not activated. + wchar_t GetPasswordChar(); + /// + /// Set the password mode displaying character. + /// + /// The password mode displaying character. Set to L'\0' to deactivate the password mode. + void SetPasswordChar(wchar_t value); + }; + } + } +} + +#endif + +/*********************************************************************** +.\CONTROLS\TEXTEDITORPACKAGE\LANGUAGESERVICE\GUILANGUAGEOPERATIONS.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI::Control System + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_CONTROLS_GUILANGUAGEOPERATIONS +#define VCZH_PRESENTATION_CONTROLS_GUILANGUAGEOPERATIONS + + +namespace vl +{ + namespace presentation + { + namespace controls + { + +/*********************************************************************** +ParsingInput +***********************************************************************/ + + class RepeatingParsingExecutor; + + /// A data structure storing the parsing input for text box control. + struct RepeatingParsingInput + { + /// The text box edit version of the code. + vuint editVersion = 0; + /// The code. + WString code; + }; + +/*********************************************************************** +ParsingOutput +***********************************************************************/ + + /// A data structure storing the parsing result for text box control. + struct RepeatingParsingOutput + { + /// The parsed syntax tree. + Ptr node; + /// The text box edit version of the code. + vuint editVersion = 0; + /// The code. + WString code; + /// The cache created from [T:vl.presentation.controls.RepeatingParsingExecutor.IParsingAnalyzer]. + Ptr cache; + }; + +/*********************************************************************** +PartialParsingOutput +***********************************************************************/ + + /// A data structure storing the parsing result for partial updating when a text box control is modified. + struct RepeatingPartialParsingOutput + { + /// The input data. + RepeatingParsingOutput input; + /// The rule name that can parse the code of the selected context. + WString rule; + /// Range of the original context in the input. + parsing::ParsingTextRange originalRange; + /// The original context in the syntax tree. + Ptr originalNode; + /// The modified context in the syntax tree. + Ptr modifiedNode; + /// The modified code of the selected context. + WString modifiedCode; + }; + +/*********************************************************************** +PartialParsingOutput +***********************************************************************/ + + /// A data structure storing the information for a candidate item. + struct ParsingCandidateItem + { + /// Semantic id. + vint semanticId = -1; + /// Display name. + WString name; + /// Tag object for any purpose, e.g., data binding. + description::Value tag; + }; + +/*********************************************************************** +ParsingContext +***********************************************************************/ + + /// A data structure storing the context of a token. + struct ParsingTokenContext + { + /// Token syntax tree for the selected token. + parsing::ParsingTreeToken* foundToken = nullptr; + /// The object syntax tree parent of the token. + parsing::ParsingTreeObject* tokenParent = nullptr; + /// Type of the parent. + WString type; + /// Field of the parent that contains the token. + WString field; + /// All acceptable semantic ids. + Ptr> acceptableSemanticIds; + + static bool RetriveContext(ParsingTokenContext& output, parsing::ParsingTreeNode* foundNode, RepeatingParsingExecutor* executor); + static bool RetriveContext(ParsingTokenContext& output, parsing::ParsingTextPos pos, parsing::ParsingTreeObject* rootNode, RepeatingParsingExecutor* executor); + static bool RetriveContext(ParsingTokenContext& output, parsing::ParsingTextRange range, parsing::ParsingTreeObject* rootNode, RepeatingParsingExecutor* executor); + }; + +/*********************************************************************** +RepeatingParsingExecutor +***********************************************************************/ + + /// Repeating parsing executor. + class RepeatingParsingExecutor : public RepeatingTaskExecutor, public Description + { + public: + /// Callback. + class ICallback : public virtual Interface + { + public: + /// Callback when a parsing task is finished. + /// the result of the parsing. + virtual void OnParsingFinishedAsync(const RepeatingParsingOutput& output)=0; + /// Callback when requires enabling or disabling automatically repeating calling to the SubmitTask function. + /// Set to true to require an automatically repeating calling to the SubmitTask function + virtual void RequireAutoSubmitTask(bool enabled)=0; + }; + + /// Parsing analyzer. + class IParsingAnalyzer : public virtual Interface + { + private: + parsing::ParsingTreeNode* ToParent(parsing::ParsingTreeNode* node, const RepeatingPartialParsingOutput* output); + parsing::ParsingTreeObject* ToChild(parsing::ParsingTreeObject* node, const RepeatingPartialParsingOutput* output); + Ptr ToChild(Ptr node, const RepeatingPartialParsingOutput* output); + + protected: + /// Get a syntax tree node's parent when the whole tree is in a partial modified state. You should use this function instead of ParsingTreeNode::GetParent when implementing this interface. + /// Returns the parent node. + /// The node. + /// The partial parsing output, which describes how the whole tree is partial modified. + parsing::ParsingTreeNode* GetParent(parsing::ParsingTreeNode* node, const RepeatingPartialParsingOutput* output); + /// Get a syntax tree node's member when the whole tree is in a partial modified state. You should use this function instead of ParsingTreeObject::GetMember when implementing this interface. + /// Returns the member node. + /// The node. + /// The name of the member. + /// The partial parsing output, which describes how the whole tree is partial modified. + Ptr GetMember(parsing::ParsingTreeObject* node, const WString& name, const RepeatingPartialParsingOutput* output); + /// Get a syntax tree node's item when the whole tree is in a partial modified state. You should use this function instead of ParsingTreeArray::GetItem when implementing this interface. + /// Returns the item node. + /// The node. + /// The index of the item. + /// The partial parsing output, which describes how the whole tree is partial modified. + Ptr GetItem(parsing::ParsingTreeArray* node, vint index, const RepeatingPartialParsingOutput* output); + + public: + /// Called when a is created. + /// The releated . + virtual void Attach(RepeatingParsingExecutor* executor) = 0; + + /// Called when a is destroyed. + /// The releated . + virtual void Detach(RepeatingParsingExecutor* executor) = 0; + + /// Called when a new parsing result is produced. A parsing analyzer can create a cache to be attached to the output containing anything necessary. This function does not run in UI thread. + /// The new parsing result. + /// The created cache object, which can be null. + virtual Ptr CreateCacheAsync(const RepeatingParsingOutput& output) = 0; + + /// Called when an semantic id for a token is needed. If an semantic id is returned, a context sensitive color can be assigned to this token. This functio does not run in UI thread, but it will only be called (for several times) after the cache object is initialized. + /// The token context. + /// The current parsing result. + /// The semantic id. + virtual vint GetSemanticIdForTokenAsync(const ParsingTokenContext& tokenContext, const RepeatingParsingOutput& output) = 0; + + /// Called when multiple auto complete candidate items for a token is needed. If nothing is written into the "candidateItems" parameter and the grammar also doesn't provide static candidate items, nothing will popup. This functio does not run in UI thread, but it will only be called (for several times) after the cache object is initialized. + /// The token context. + /// The partial parsing result. It contains the current parsing result, and an incremental parsing result. If the calculation of candidate items are is very context sensitive, then you should be very careful when traversing the syntax tree, by carefully looking at the "originalNode" and the "modifiedNode" in the "partialOutput" parameter. + /// The candidate items. + virtual void GetCandidateItemsAsync(const ParsingTokenContext& tokenContext, const RepeatingPartialParsingOutput& partialOutput, collections::List& candidateItems) = 0; + + /// Create a tag object for a candidate item without a tag object. An candidate item without a tag maybe created by calling or any token marked by a @Candidate attribute in the grammar. + /// The candidate item. + /// The tag object. In most of the case this object is used for data binding or any other purpose when you want to customize the auto complete control. Returns null if the specified [T.vl.presentation.controls.GuiTextBoxAutoCompleteBase.IAutoCompleteControlProvider] can handle null tag correctly. + virtual description::Value CreateTagForCandidateItem(ParsingCandidateItem& item) = 0; + }; + + /// A base class for implementing a callback. + class CallbackBase : public virtual ICallback, public virtual ICommonTextEditCallback + { + private: + bool callbackAutoPushing; + elements::GuiColorizedTextElement* callbackElement; + SpinLock* callbackElementModifyLock; + + protected: + Ptr parsingExecutor; + + public: + CallbackBase(Ptr _parsingExecutor); + ~CallbackBase(); + + void RequireAutoSubmitTask(bool enabled)override; + void Attach(elements::GuiColorizedTextElement* _element, SpinLock& _elementModifyLock, compositions::GuiGraphicsComposition* _ownerComposition, vuint editVersion)override; + void Detach()override; + void TextEditPreview(TextEditPreviewStruct& arguments)override; + void TextEditNotify(const TextEditNotifyStruct& arguments)override; + void TextCaretChanged(const TextCaretChangedStruct& arguments)override; + void TextEditFinished(vuint editVersion)override; + }; + + struct TokenMetaData + { + vint tableTokenIndex; + vint lexerTokenIndex; + vint defaultColorIndex; + bool hasContextColor; + bool hasAutoComplete; + bool isCandidate; + WString unescapedRegexText; + }; + + struct FieldMetaData + { + vint colorIndex; + Ptr> semantics; + }; + private: + Ptr grammarParser; + WString grammarRule; + Ptr analyzer; + collections::List callbacks; + collections::List activatedCallbacks; + ICallback* autoPushingCallback; + + typedef collections::Pair FieldDesc; + collections::Dictionary tokenIndexMap; + collections::SortedList semanticIndexMap; + collections::Dictionary tokenMetaDatas; + collections::Dictionary fieldMetaDatas; + + protected: + + void Execute(const RepeatingParsingInput& input)override; + void PrepareMetaData(); + + /// Called when semantic analyzing is needed. It is encouraged to set the "cache" fields in "context" argument. If there is an binded to the , this function can be automatically done. + /// The parsing result. + virtual void OnContextFinishedAsync(RepeatingParsingOutput& context); + public: + /// Initialize the parsing executor. + /// Parser generated from a grammar. + /// The rule name to parse a complete code. + /// The parsing analyzer to create semantic metadatas, it can be null. + RepeatingParsingExecutor(Ptr _grammarParser, const WString& _grammarRule, Ptr _analyzer = 0); + ~RepeatingParsingExecutor(); + + /// Get the internal parser that parse the text. + /// The internal parser. + Ptr GetParser(); + /// Detach callback. + /// Returns true if this operation succeeded. + /// The callback. + bool AttachCallback(ICallback* value); + /// Detach callback. + /// Returns true if this operation succeeded. + /// The callback. + bool DetachCallback(ICallback* value); + /// Activate a callback. Activating a callback means that the callback owner has an ability to watch a text box modification, e.g., an attached that is also an . The may require one of the activated callback to push code for parsing automatically via a call to . + /// Returns true if this operation succeeded. + /// The callback. + bool ActivateCallback(ICallback* value); + /// Deactivate a callback. See for deatils. + /// Returns true if this operation succeeded. + /// The callback. + bool DeactivateCallback(ICallback* value); + /// Get the parsing analyzer. + /// The parsing analyzer. + Ptr GetAnalyzer(); + + vint GetTokenIndex(const WString& tokenName); + vint GetSemanticId(const WString& name); + WString GetSemanticName(vint id); + const TokenMetaData& GetTokenMetaData(vint regexTokenIndex); + const FieldMetaData& GetFieldMetaData(const WString& type, const WString& field); + + Ptr GetAttribute(vint index, const WString& name, vint argumentCount); + Ptr GetColorAttribute(vint index); + Ptr GetContextColorAttribute(vint index); + Ptr GetSemanticAttribute(vint index); + Ptr GetCandidateAttribute(vint index); + Ptr GetAutoCompleteAttribute(vint index); + + /* + @Color(ColorName) + field: color of the token field when the token type is marked with @ContextColor + token: color of the token + @ContextColor() + token: the color of the token may be changed if the token field is marked with @Color or @Semantic + @Semantic(Type1, Type2, ...) + field: After resolved symbols for this field, only types of symbols that specified in the arguments are acceptable. + @Candidate() + token: when the token can be available after the editing caret, than it will be in the auto complete list. + @AutoComplete() + token: when the token is editing, an auto complete list will appear if possible + */ + }; + } + } +} + +#endif + +/*********************************************************************** +.\CONTROLS\TEXTEDITORPACKAGE\LANGUAGESERVICE\GUILANGUAGEAUTOCOMPLETE.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI::Control System + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_CONTROLS_GUILANGUAGEAUTOCOMPLETE +#define VCZH_PRESENTATION_CONTROLS_GUILANGUAGEAUTOCOMPLETE + +namespace vl +{ + namespace presentation + { + namespace controls + { + +/*********************************************************************** +GuiGrammarAutoComplete +***********************************************************************/ + + /// Grammar based auto complete controller. + class GuiGrammarAutoComplete + : public GuiTextBoxAutoCompleteBase + , protected RepeatingParsingExecutor::CallbackBase + , private RepeatingTaskExecutor + { + public: + + /// The auto complete list data. + struct AutoCompleteData : ParsingTokenContext + { + /// Available candidate tokens (in lexer token index). + collections::List candidates; + /// Available candidate tokens (in lexer token index) that marked with @AutoCompleteCandidate(). + collections::List shownCandidates; + /// Candidate items. + collections::List candidateItems; + /// The start position of the editing token in global coordination. + TextPos startPosition; + }; + + /// The analysed data from an input code. + struct AutoCompleteContext : RepeatingPartialParsingOutput + { + /// The edit version of modified code. + vuint modifiedEditVersion = 0; + /// The analysed auto complete list data. + Ptr autoComplete; + }; + private: + Ptr grammarParser; + collections::SortedList leftRecursiveRules; + bool editing; + + SpinLock editTraceLock; + collections::List editTrace; + + SpinLock contextLock; + AutoCompleteContext context; + + void Attach(elements::GuiColorizedTextElement* _element, SpinLock& _elementModifyLock, compositions::GuiGraphicsComposition* _ownerComposition, vuint editVersion)override; + void Detach()override; + void TextEditPreview(TextEditPreviewStruct& arguments)override; + void TextEditNotify(const TextEditNotifyStruct& arguments)override; + void TextCaretChanged(const TextCaretChangedStruct& arguments)override; + void TextEditFinished(vuint editVersion)override; + void OnParsingFinishedAsync(const RepeatingParsingOutput& output)override; + void CollectLeftRecursiveRules(); + + vint UnsafeGetEditTraceIndex(vuint editVersion); + TextPos ChooseCorrectTextPos(TextPos pos, const regex::RegexTokens& tokens); + void ExecuteRefresh(AutoCompleteContext& newContext); + + bool NormalizeTextPos(AutoCompleteContext& newContext, elements::text::TextLines& lines, TextPos& pos); + void ExecuteEdit(AutoCompleteContext& newContext); + + void DeleteFutures(collections::List& futures); + regex::RegexToken* TraverseTransitions( + parsing::tabling::ParsingState& state, + parsing::tabling::ParsingTransitionCollector& transitionCollector, + TextPos stopPosition, + collections::List& nonRecoveryFutures, + collections::List& recoveryFutures + ); + regex::RegexToken* SearchValidInputToken( + parsing::tabling::ParsingState& state, + parsing::tabling::ParsingTransitionCollector& transitionCollector, + TextPos stopPosition, + AutoCompleteContext& newContext, + collections::SortedList& tableTokenIndices + ); + + TextPos GlobalTextPosToModifiedTextPos(AutoCompleteContext& newContext, TextPos pos); + TextPos ModifiedTextPosToGlobalTextPos(AutoCompleteContext& newContext, TextPos pos); + void ExecuteCalculateList(AutoCompleteContext& newContext); + + void Execute(const RepeatingParsingOutput& input)override; + void PostList(const AutoCompleteContext& newContext, bool byGlobalCorrection); + void Initialize(); + protected: + + /// Called when the context of the code is selected. It is encouraged to set the "candidateItems" field in "context.autoComplete" during the call. If there is an binded to the , this function can be automatically done. + /// The selected context. + virtual void OnContextFinishedAsync(AutoCompleteContext& context); + + /// Call this function in the derived class's destructor when it overrided . + void EnsureAutoCompleteFinished(); + public: + /// Create the auto complete controller with a created parsing executor. + /// The parsing executor. + GuiGrammarAutoComplete(Ptr _parsingExecutor); + /// Create the auto complete controller with a specified grammar and start rule to create a . + /// Parser generated from a grammar. + /// + GuiGrammarAutoComplete(Ptr _grammarParser, const WString& _grammarRule); + ~GuiGrammarAutoComplete(); + + /// Get the internal parsing executor. + /// The parsing executor. + Ptr GetParsingExecutor(); + }; + } + } +} + +#endif + +/*********************************************************************** +.\CONTROLS\TEXTEDITORPACKAGE\LANGUAGESERVICE\GUILANGUAGECOLORIZER.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI::Control System + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_CONTROLS_GUILANGUAGECOLORIZER +#define VCZH_PRESENTATION_CONTROLS_GUILANGUAGECOLORIZER + + +namespace vl +{ + namespace presentation + { + namespace controls + { + +/*********************************************************************** +GuiGrammarColorizer +***********************************************************************/ + + /// Grammar based colorizer. + class GuiGrammarColorizer : public GuiTextBoxRegexColorizer, protected RepeatingParsingExecutor::CallbackBase + { + typedef collections::Pair FieldDesc; + typedef collections::Dictionary FieldContextColors; + typedef collections::Dictionary FieldSemanticColors; + typedef elements::text::ColorEntry ColorEntry; + public: + /// Context for doing semantic colorizing. + struct SemanticColorizeContext : ParsingTokenContext + { + /// Output semantic id that comes from one the argument in the @Semantic attribute. + vint semanticId; + }; + private: + collections::Dictionary colorSettings; + collections::Dictionary semanticColorMap; + + SpinLock contextLock; + RepeatingParsingOutput context; + + void OnParsingFinishedAsync(const RepeatingParsingOutput& output)override; + protected: + /// Called when the node is parsed successfully before restarting colorizing. + /// The result of the parsing. + virtual void OnContextFinishedAsync(const RepeatingParsingOutput& context); + + void Attach(elements::GuiColorizedTextElement* _element, SpinLock& _elementModifyLock, compositions::GuiGraphicsComposition* _ownerComposition, vuint editVersion)override; + void Detach()override; + void TextEditPreview(TextEditPreviewStruct& arguments)override; + void TextEditNotify(const TextEditNotifyStruct& arguments)override; + void TextCaretChanged(const TextCaretChangedStruct& arguments)override; + void TextEditFinished(vuint editVersion)override; + + /// Called when a @SemanticColor attribute in a grammar is activated during colorizing to determine a color for the token. If there is an binded to the , this function can be automatically done. + /// Context for doing semantic colorizing. + /// The corressponding result from the . + virtual void OnSemanticColorize(SemanticColorizeContext& context, const RepeatingParsingOutput& input); + + /// Call this function in the derived class's destructor when it overrided . + void EnsureColorizerFinished(); + public: + /// Create the colorizer with a created parsing executor. + /// The parsing executor. + GuiGrammarColorizer(Ptr _parsingExecutor); + /// Create the colorizer with a specified grammar and start rule to create a . + /// Parser generated from a grammar. + /// + GuiGrammarColorizer(Ptr _grammarParser, const WString& _grammarRule); + ~GuiGrammarColorizer(); + + /// Reset all color settings. + void BeginSetColors(); + /// Get all color names. + /// All color names. + const collections::SortedList& GetColorNames(); + /// Get the color for a token theme name (@Color or @ContextColor("theme-name") in the grammar). + /// The color. + /// The token theme name. + ColorEntry GetColor(const WString& name); + /// Set a color for a token theme name (@Color or @ContextColor("theme-name") in the grammar). + /// The token theme name. + /// The color. + void SetColor(const WString& name, const ColorEntry& entry); + /// Set a color for a token theme name (@Color or @ContextColor("theme-name") in the grammar). + /// The token theme name. + /// The color. + void SetColor(const WString& name, const Color& color); + /// Submit all color settings. + void EndSetColors(); + void ColorizeTokenContextSensitive(vint lineIndex, const wchar_t* text, vint start, vint length, vint& token, vint& contextState)override; + + /// Get the internal parsing executor. + /// The parsing executor. + Ptr GetParsingExecutor(); + }; + } + } +} + +#endif + /*********************************************************************** .\CONTROLS\TOOLSTRIPPACKAGE\GUIMENUCONTROLS.H ***********************************************************************/ @@ -14028,208 +16222,6 @@ DateComboBox #endif -/*********************************************************************** -.\CONTROLS\LISTCONTROLPACKAGE\GUILISTCONTROLITEMARRANGERS.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI::Control System - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_CONTROLS_GUILISTCONTROLITEMARRANGERS -#define VCZH_PRESENTATION_CONTROLS_GUILISTCONTROLITEMARRANGERS - - -namespace vl -{ - namespace presentation - { - namespace controls - { - -/*********************************************************************** -Predefined ItemArranger -***********************************************************************/ - - namespace list - { - - /// Ranged item arranger. This arranger implements most of the common functionality for those arrangers that display a continuing subset of item at a time. - class RangedItemArrangerBase : public Object, virtual public GuiListControl::IItemArranger, public Description - { - protected: - using ItemStyleRecord = collections::Pair; - typedef collections::List StyleList; - - GuiListControl* listControl = nullptr; - GuiListControl::IItemArrangerCallback* callback = nullptr; - GuiListControl::IItemProvider* itemProvider = nullptr; - - bool suppressOnViewChanged = false; - Rect viewBounds; - vint startIndex = 0; - StyleList visibleStyles; - - protected: - - void InvalidateAdoptedSize(); - vint CalculateAdoptedSize(vint expectedSize, vint count, vint itemSize); - ItemStyleRecord CreateStyle(vint index); - void DeleteStyle(ItemStyleRecord style); - compositions::GuiBoundsComposition* GetStyleBounds(ItemStyleRecord style); - void ClearStyles(); - void OnViewChangedInternal(Rect oldBounds, Rect newBounds); - virtual void RearrangeItemBounds(); - - virtual void BeginPlaceItem(bool forMoving, Rect newBounds, vint& newStartIndex) = 0; - virtual void PlaceItem(bool forMoving, bool newCreatedStyle, vint index, ItemStyleRecord style, Rect viewBounds, Rect& bounds, Margin& alignmentToParent) = 0; - virtual bool IsItemOutOfViewBounds(vint index, ItemStyleRecord style, Rect bounds, Rect viewBounds) = 0; - virtual bool EndPlaceItem(bool forMoving, Rect newBounds, vint newStartIndex) = 0; - virtual void InvalidateItemSizeCache() = 0; - virtual Size OnCalculateTotalSize() = 0; - public: - /// Create the arranger. - RangedItemArrangerBase(); - ~RangedItemArrangerBase(); - - void OnAttached(GuiListControl::IItemProvider* provider)override; - void OnItemModified(vint start, vint count, vint newCount)override; - void AttachListControl(GuiListControl* value)override; - void DetachListControl()override; - GuiListControl::IItemArrangerCallback* GetCallback()override; - void SetCallback(GuiListControl::IItemArrangerCallback* value)override; - Size GetTotalSize()override; - GuiListControl::ItemStyle* GetVisibleStyle(vint itemIndex)override; - vint GetVisibleIndex(GuiListControl::ItemStyle* style)override; - void ReloadVisibleStyles()override; - void OnViewChanged(Rect bounds)override; - }; - /// Free height item arranger. This arranger will cache heights of all items. - class FreeHeightItemArranger : public RangedItemArrangerBase, public Description - { - private: - bool pim_heightUpdated = false; - - protected: - collections::Array heights; - collections::Array offsets; - vint availableOffsetCount = 0; - - void EnsureOffsetForItem(vint itemIndex); - - void BeginPlaceItem(bool forMoving, Rect newBounds, vint& newStartIndex)override; - void PlaceItem(bool forMoving, bool newCreatedStyle, vint index, ItemStyleRecord style, Rect viewBounds, Rect& bounds, Margin& alignmentToParent)override; - bool IsItemOutOfViewBounds(vint index, ItemStyleRecord style, Rect bounds, Rect viewBounds)override; - bool EndPlaceItem(bool forMoving, Rect newBounds, vint newStartIndex)override; - void InvalidateItemSizeCache()override; - Size OnCalculateTotalSize()override; - public: - /// Create the arranger. - FreeHeightItemArranger(); - ~FreeHeightItemArranger(); - - void OnAttached(GuiListControl::IItemProvider* provider)override; - void OnItemModified(vint start, vint count, vint newCount)override; - vint FindItem(vint itemIndex, compositions::KeyDirection key)override; - GuiListControl::EnsureItemVisibleResult EnsureItemVisible(vint itemIndex)override; - Size GetAdoptedSize(Size expectedSize)override; - }; - - /// Fixed height item arranger. This arranger lists all item with the same height value. This value is the maximum height of all minimum heights of displayed items. - class FixedHeightItemArranger : public RangedItemArrangerBase, public Description - { - private: - vint pi_width = 0; - vint pim_rowHeight = 0; - - protected: - vint rowHeight = 1; - - virtual vint GetWidth(); - virtual vint GetYOffset(); - - void BeginPlaceItem(bool forMoving, Rect newBounds, vint& newStartIndex)override; - void PlaceItem(bool forMoving, bool newCreatedStyle, vint index, ItemStyleRecord style, Rect viewBounds, Rect& bounds, Margin& alignmentToParent)override; - bool IsItemOutOfViewBounds(vint index, ItemStyleRecord style, Rect bounds, Rect viewBounds)override; - bool EndPlaceItem(bool forMoving, Rect newBounds, vint newStartIndex)override; - void InvalidateItemSizeCache()override; - Size OnCalculateTotalSize()override; - public: - /// Create the arranger. - FixedHeightItemArranger(); - ~FixedHeightItemArranger(); - - vint FindItem(vint itemIndex, compositions::KeyDirection key)override; - GuiListControl::EnsureItemVisibleResult EnsureItemVisible(vint itemIndex)override; - Size GetAdoptedSize(Size expectedSize)override; - }; - - /// Fixed size multiple columns item arranger. This arranger adjust all items in multiple lines with the same size. The width is the maximum width of all minimum widths of displayed items. The same to height. - class FixedSizeMultiColumnItemArranger : public RangedItemArrangerBase, public Description - { - private: - Size pim_itemSize; - - protected: - Size itemSize{ 1,1 }; - - void CalculateRange(Size itemSize, Rect bounds, vint count, vint& start, vint& end); - - void BeginPlaceItem(bool forMoving, Rect newBounds, vint& newStartIndex)override; - void PlaceItem(bool forMoving, bool newCreatedStyle, vint index, ItemStyleRecord style, Rect viewBounds, Rect& bounds, Margin& alignmentToParent)override; - bool IsItemOutOfViewBounds(vint index, ItemStyleRecord style, Rect bounds, Rect viewBounds)override; - bool EndPlaceItem(bool forMoving, Rect newBounds, vint newStartIndex)override; - void InvalidateItemSizeCache()override; - Size OnCalculateTotalSize()override; - public: - /// Create the arranger. - FixedSizeMultiColumnItemArranger(); - ~FixedSizeMultiColumnItemArranger(); - - vint FindItem(vint itemIndex, compositions::KeyDirection key)override; - GuiListControl::EnsureItemVisibleResult EnsureItemVisible(vint itemIndex)override; - Size GetAdoptedSize(Size expectedSize)override; - }; - - /// Fixed size multiple columns item arranger. This arranger adjust all items in multiple columns with the same height. The height is the maximum width of all minimum height of displayed items. Each item will displayed using its minimum width. - class FixedHeightMultiColumnItemArranger : public RangedItemArrangerBase, public Description - { - private: - vint pi_currentWidth = 0; - vint pi_totalWidth = 0; - vint pim_itemHeight = 0; - - protected: - vint itemHeight; - - void CalculateRange(vint itemHeight, Rect bounds, vint& rows, vint& startColumn); - - void BeginPlaceItem(bool forMoving, Rect newBounds, vint& newStartIndex)override; - void PlaceItem(bool forMoving, bool newCreatedStyle, vint index, ItemStyleRecord style, Rect viewBounds, Rect& bounds, Margin& alignmentToParent)override; - bool IsItemOutOfViewBounds(vint index, ItemStyleRecord style, Rect bounds, Rect viewBounds)override; - bool EndPlaceItem(bool forMoving, Rect newBounds, vint newStartIndex)override; - void InvalidateItemSizeCache()override; - Size OnCalculateTotalSize()override; - public: - /// Create the arranger. - FixedHeightMultiColumnItemArranger(); - ~FixedHeightMultiColumnItemArranger(); - - vint FindItem(vint itemIndex, compositions::KeyDirection key)override; - GuiListControl::EnsureItemVisibleResult EnsureItemVisible(vint itemIndex)override; - Size GetAdoptedSize(Size expectedSize)override; - }; - } - } - } -} - -#endif - - /*********************************************************************** .\CONTROLS\LISTCONTROLPACKAGE\GUILISTVIEWCONTROLS.H ***********************************************************************/ @@ -16264,7 +18256,7 @@ GuiBindableDataGrid /*********************************************************************** -.\CONTROLS\TEXTEDITORPACKAGE\EDITORCALLBACK\GUITEXTGENERALOPERATIONS.H +.\CONTROLS\TOOLSTRIPPACKAGE\GUIRIBBONIMPL.H ***********************************************************************/ /*********************************************************************** Vczh Library++ 3.0 @@ -16274,8 +18266,8 @@ GacUI::Control System Interfaces: ***********************************************************************/ -#ifndef VCZH_PRESENTATION_CONTROLS_GUITEXTGENERALOPERATIONS -#define VCZH_PRESENTATION_CONTROLS_GUITEXTGENERALOPERATIONS +#ifndef VCZH_PRESENTATION_CONTROLS_GUIRIBBONIMPL +#define VCZH_PRESENTATION_CONTROLS_GUIRIBBONIMPL namespace vl @@ -16284,1463 +18276,81 @@ namespace vl { namespace controls { - -/*********************************************************************** -Common Operations -***********************************************************************/ - - /// An text edit callback for text box controls. - class ICommonTextEditCallback : public virtual IDescriptable, public Description - { - public: - /// Callback data for text editing preview. - struct TextEditPreviewStruct - { - /// The start position of the selection before replacing. This field can be modified. - TextPos originalStart; - /// The end position of the selection before replacing. This field can be modified. - TextPos originalEnd; - /// The text of the selection before replacing. - WString originalText; - /// The text of the selection after replacing. This field can be modified. - WString inputText; - /// The base edit version. - vuint editVersion = 0; - /// True if this modification is raised by the keyboard. - bool keyInput = false; - }; - - /// Callback data for text editing. - struct TextEditNotifyStruct - { - /// The start position of the selection before replacing. - TextPos originalStart; - /// The end position of the selection before replacing. - TextPos originalEnd; - /// The text of the selection before replacing. - WString originalText; - /// The start position of the selection after replacing. - TextPos inputStart; - /// The end position of the selection after replacing. - TextPos inputEnd; - /// The text of the selection after replacing. - WString inputText; - /// The created edit version. - vuint editVersion = 0; - /// True if this modification is raised by the keyboard. - bool keyInput = false; - }; - - /// Callback data for text caret changing. - struct TextCaretChangedStruct - { - /// The start position of the selection before caret changing. - TextPos oldBegin; - /// The end position of the selection before caret changing. - TextPos oldEnd; - /// The start position of the selection after caret changing. - TextPos newBegin; - /// The end position of the selection after caret changing. - TextPos newEnd; - /// The current edit version. - vuint editVersion = 0; - }; - - /// Called when the callback is attached to a text box control. - /// The element that used in the text box control. - /// The lock that pretect the element. - /// The owner composition of this element. - /// The current edit version. - virtual void Attach(elements::GuiColorizedTextElement* element, SpinLock& elementModifyLock, compositions::GuiGraphicsComposition* ownerComposition, vuint editVersion)=0; - /// Called when the callback is detached from a text box control. - virtual void Detach()=0; - /// Called before the text is edited. - /// The data for this callback. - virtual void TextEditPreview(TextEditPreviewStruct& arguments)=0; - /// Called after the text is edited and before the caret is changed. - /// The data for this callback. - virtual void TextEditNotify(const TextEditNotifyStruct& arguments)=0; - /// Called after the caret is changed. - /// The data for this callback. - virtual void TextCaretChanged(const TextCaretChangedStruct& arguments)=0; - /// Called after the text is edited and after the caret is changed. - /// The current edit version. - virtual void TextEditFinished(vuint editVersion)=0; - }; - } - } -} - -#endif - -/*********************************************************************** -.\CONTROLS\TEXTEDITORPACKAGE\EDITORCALLBACK\GUITEXTCOLORIZER.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI::Control System - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_CONTROLS_GUITEXTCOLORIZER -#define VCZH_PRESENTATION_CONTROLS_GUITEXTCOLORIZER - - -namespace vl -{ - namespace presentation - { - namespace controls - { - -/*********************************************************************** -GuiTextBoxColorizerBase -***********************************************************************/ - - /// The base class of text box colorizer. - class GuiTextBoxColorizerBase : public Object, public virtual ICommonTextEditCallback - { - public: - typedef collections::Array ColorArray; - protected: - elements::GuiColorizedTextElement* element; - SpinLock* elementModifyLock; - volatile vint colorizedLineCount; - volatile bool isColorizerRunning; - volatile bool isFinalizing; - SpinLock colorizerRunningEvent; - - static void ColorizerThreadProc(void* argument); - - void StartColorizer(); - void StopColorizer(bool forever); - void StopColorizerForever(); - public: - /// Create a colorrizer. - GuiTextBoxColorizerBase(); - ~GuiTextBoxColorizerBase(); - - void Attach(elements::GuiColorizedTextElement* _element, SpinLock& _elementModifyLock, compositions::GuiGraphicsComposition* _ownerComposition, vuint editVersion)override; - void Detach()override; - void TextEditPreview(TextEditPreviewStruct& arguments)override; - void TextEditNotify(const TextEditNotifyStruct& arguments)override; - void TextCaretChanged(const TextCaretChangedStruct& arguments)override; - void TextEditFinished(vuint editVersion)override; - void RestartColorizer(); - - /// Get the lexical analyzer start state for the first line. - /// The lexical analyzer start state for the first line. - virtual vint GetLexerStartState()=0; - /// Get the context sensitive start state for the first line. - /// The context sensitive start state for the first line. - virtual vint GetContextStartState()=0; - /// Colorizer one line with a start state. - /// Line index. - /// Text buffer. - /// Color index buffer. The index should be in [0 .. [M:vl.presentation.controls.GuiTextBoxColorizerBase.GetColors]()-1]. - /// The length of the buffer. - /// The lexical analyzer state for this line. After executing this function, the new value of this argument indicates the new state. - /// The context sensitive state for this line. After executing this function, the new value of this argument indicates the new state. - virtual void ColorizeLineWithCRLF(vint lineIndex, const wchar_t* text, vuint32_t* colors, vint length, vint& lexerState, vint& contextState)=0; - /// Get the supported colors ordered by their indices. - /// The supported colors ordered by their indices. - virtual const ColorArray& GetColors()=0; - }; - -/*********************************************************************** -GuiTextBoxRegexColorizer -***********************************************************************/ - - /// Regex based colorizer. - class GuiTextBoxRegexColorizer : public GuiTextBoxColorizerBase - { - protected: - Ptr lexer; - Ptr colorizer; - void* colorizerArgument[1] { nullptr }; - ColorArray colors; - - elements::text::ColorEntry defaultColor; - collections::List tokenRegexes; - collections::List tokenColors; - collections::List extraTokenColors; - - static void ColorizerProc(void* argument, vint start, vint length, vint token); - public: - /// Create the colorizer. - GuiTextBoxRegexColorizer(); - ~GuiTextBoxRegexColorizer(); - - /// Get the default color. - /// The default color. - elements::text::ColorEntry GetDefaultColor(); - /// Get all regular expressions for tokens. - /// All regular expressions for tokens. - collections::List& GetTokenRegexes(); - /// Get all colors for tokens. - /// All colors for tokens. - collections::List& GetTokenColors(); - /// Get all colors for extra tokens. - /// All colors for extra tokens. - collections::List& GetExtraTokenColors(); - /// Get the first token index for the first extra token. - /// The first token index for the first extra token. Returns -1 if this operation failed. - vint GetExtraTokenIndexStart(); - - /// Set the default color. Call [M:vl.presentation.controls.GuiTextBoxRegexColorizer.Setup] after finishing all configuration. - /// Returns the token index of this token. Returns -1 if this operation failed. - /// The default color. - bool SetDefaultColor(elements::text::ColorEntry value); - /// Add a token type. Call [M:vl.presentation.controls.GuiTextBoxRegexColorizer.Setup] after finishing all configuration. - /// Returns the token index of this token. Returns -1 if this operation failed. - /// The regular expression for this token type. - /// The color for this token type. - vint AddToken(const WString& regex, elements::text::ColorEntry color); - /// Add an extra token type. Call [M:vl.presentation.controls.GuiTextBoxRegexColorizer.Setup] after finishing all configuration. - /// Returns the extra token index of this token. The token index for this token is regex-token-count + extra-token-index Returns -1 if this operation failed. - /// The color for this token type. - vint AddExtraToken(elements::text::ColorEntry color); - /// Clear all token color settings. - void ClearTokens(); - /// Setup the colorizer. After that, the colorizer cannot be changed. - void Setup(); - /// Callback function to set context sensitive state and change token accordingly. - /// Line index. - /// Text buffer. - /// The start position of the token. - /// The length of the token. - /// The token type. After executing this function, the new value of this argument indicates the new token type. - /// The context sensitive state. After executing this function, the new value of this argument indicates the new state. - virtual void ColorizeTokenContextSensitive(vint lineIndex, const wchar_t* text, vint start, vint length, vint& token, vint& contextState); - - vint GetLexerStartState()override; - vint GetContextStartState()override; - void ColorizeLineWithCRLF(vint lineIndex, const wchar_t* text, vuint32_t* colors, vint length, vint& lexerState, vint& contextState)override; - const ColorArray& GetColors()override; - }; - } - } -} - -#endif - -/*********************************************************************** -.\CONTROLS\TEXTEDITORPACKAGE\EDITORCALLBACK\GUITEXTUNDOREDO.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI::Control System - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_CONTROLS_GUITEXTUNDOREDO -#define VCZH_PRESENTATION_CONTROLS_GUITEXTUNDOREDO - - -namespace vl -{ - namespace presentation - { - namespace controls - { - class GuiTextBoxCommonInterface; - -/*********************************************************************** -Undo Redo -***********************************************************************/ - - class GuiGeneralUndoRedoProcessor : public Object - { - protected: - class IEditStep : public Interface - { - public: - virtual void Undo()=0; - virtual void Redo()=0; - }; - friend class collections::ArrayBase>; - - protected: - collections::List> steps; - vint firstFutureStep; - vint savedStep; - bool performingUndoRedo; - - void PushStep(Ptr step); - public: - GuiGeneralUndoRedoProcessor(); - ~GuiGeneralUndoRedoProcessor(); - - Event UndoRedoChanged; - Event ModifiedChanged; - - bool CanUndo(); - bool CanRedo(); - void ClearUndoRedo(); - bool GetModified(); - void NotifyModificationSaved(); - bool Undo(); - bool Redo(); - }; - -/*********************************************************************** -Undo Redo (Text) -***********************************************************************/ - - class GuiTextBoxUndoRedoProcessor : public GuiGeneralUndoRedoProcessor, public ICommonTextEditCallback - { - protected: - class EditStep : public Object, public IEditStep - { - public: - GuiTextBoxUndoRedoProcessor* processor; - TextEditNotifyStruct arguments; - - void Undo(); - void Redo(); - }; - - compositions::GuiGraphicsComposition* ownerComposition; - public: - GuiTextBoxUndoRedoProcessor(); - ~GuiTextBoxUndoRedoProcessor(); - - void Attach(elements::GuiColorizedTextElement* element, SpinLock& elementModifyLock, compositions::GuiGraphicsComposition* _ownerComposition, vuint editVersion)override; - void Detach()override; - void TextEditPreview(TextEditPreviewStruct& arguments)override; - void TextEditNotify(const TextEditNotifyStruct& arguments)override; - void TextCaretChanged(const TextCaretChangedStruct& arguments)override; - void TextEditFinished(vuint editVersion)override; - }; - -/*********************************************************************** -Undo Redo (Document) -***********************************************************************/ - - class GuiDocumentUndoRedoProcessor : public GuiGeneralUndoRedoProcessor - { - public: - struct ReplaceModelStruct - { - TextPos originalStart; - TextPos originalEnd; - Ptr originalModel; - TextPos inputStart; - TextPos inputEnd; - Ptr inputModel; - - ReplaceModelStruct() - { - } - }; - - struct RenameStyleStruct - { - WString oldStyleName; - WString newStyleName; - - RenameStyleStruct() - { - } - }; - - struct SetAlignmentStruct - { - vint start; - vint end; - collections::Array> originalAlignments; - collections::Array> inputAlignments; - }; - - protected: - elements::GuiDocumentElement* element; - compositions::GuiGraphicsComposition* ownerComposition; - - class ReplaceModelStep : public Object, public IEditStep - { - public: - GuiDocumentUndoRedoProcessor* processor; - ReplaceModelStruct arguments; - - void Undo(); - void Redo(); - }; - - class RenameStyleStep : public Object, public IEditStep - { - public: - GuiDocumentUndoRedoProcessor* processor; - RenameStyleStruct arguments; - - void Undo(); - void Redo(); - }; - - class SetAlignmentStep : public Object, public IEditStep - { - public: - GuiDocumentUndoRedoProcessor* processor; - Ptr arguments; - - void Undo(); - void Redo(); - }; - public: - - GuiDocumentUndoRedoProcessor(); - ~GuiDocumentUndoRedoProcessor(); - - void Setup(elements::GuiDocumentElement* _element, compositions::GuiGraphicsComposition* _ownerComposition); - void OnReplaceModel(const ReplaceModelStruct& arguments); - void OnRenameStyle(const RenameStyleStruct& arguments); - void OnSetAlignment(Ptr arguments); - }; - } - } -} - -#endif - -/*********************************************************************** -.\CONTROLS\TEXTEDITORPACKAGE\GUIDOCUMENTVIEWER.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI::Control System - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_CONTROLS_GUIDOCUMENTVIEWER -#define VCZH_PRESENTATION_CONTROLS_GUIDOCUMENTVIEWER - - -namespace vl -{ - namespace presentation - { - namespace compositions - { - class GuiShortcutKeyManager; - } - - namespace controls - { - -/*********************************************************************** -GuiDocumentCommonInterface -***********************************************************************/ - - class GuiDocumentCommonInterface; - - /// Embedded object in a document. - class GuiDocumentItem : public Object, public Description - { - friend class GuiDocumentCommonInterface; - protected: - bool visible = false; - WString name; - compositions::GuiBoundsComposition* container; - bool owned = false; - public: - GuiDocumentItem(const WString& _name); - ~GuiDocumentItem(); - - /// Get the container for all embedded controls and compositions in this item. - /// The container. - compositions::GuiGraphicsComposition* GetContainer(); - - /// Get the name of the document item. - /// The name. - WString GetName(); - }; - - /// Document displayer control common interface for displaying . - class GuiDocumentCommonInterface abstract - : protected virtual elements::GuiDocumentElement::ICallback - , 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: - Ptr baselineDocument; - DocumentItemMap documentItems; - GuiControl* documentControl = nullptr; - elements::GuiDocumentElement* documentElement = nullptr; - compositions::GuiBoundsComposition* documentComposition = nullptr; - Ptr activeHyperlinks; - bool dragging = false; - EditMode editMode = EditMode::ViewOnly; - - Ptr undoRedoProcessor; - Ptr internalShortcutKeyManager; - - protected: - void InvokeUndoRedoChanged(); - void InvokeModifiedChanged(); - void UpdateCaretPoint(); - void Move(TextPos caret, bool shift, bool frontSide); - bool ProcessKey(VKEY code, bool shift, bool ctrl); - void InstallDocumentViewer(GuiControl* _sender, compositions::GuiGraphicsComposition* _container, compositions::GuiGraphicsComposition* eventComposition, compositions::GuiGraphicsComposition* focusableComposition); - void SetActiveHyperlink(Ptr package); - void ActivateActiveHyperlink(bool activate); - void AddShortcutCommand(VKEY key, const Func& eventHandler); - void EditTextInternal(TextPos begin, TextPos end, const Func& editor); - void EditStyleInternal(TextPos begin, TextPos end, const Func& editor); - - void MergeBaselineAndDefaultFont(Ptr document); - void OnFontChanged(); - void OnCaretNotify(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); - void OnGotFocus(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); - void OnLostFocus(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); - void OnKeyDown(compositions::GuiGraphicsComposition* sender, compositions::GuiKeyEventArgs& arguments); - void OnCharInput(compositions::GuiGraphicsComposition* sender, compositions::GuiCharEventArgs& arguments); - void OnMouseMove(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments); - void OnMouseDown(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments); - void OnMouseUp(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments); - void OnMouseLeave(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); - - virtual Point GetDocumentViewPosition(); - virtual void EnsureRectVisible(Rect bounds); - - //================ callback - - void OnStartRender()override; - void OnFinishRender()override; - Size OnRenderEmbeddedObject(const WString& name, const Rect& location)override; - public: - GuiDocumentCommonInterface(); - ~GuiDocumentCommonInterface(); - - /// Active hyperlink changed event. - compositions::GuiNotifyEvent ActiveHyperlinkChanged; - /// Active hyperlink executed event. - compositions::GuiNotifyEvent ActiveHyperlinkExecuted; - - /// Selection changed event. - compositions::GuiNotifyEvent SelectionChanged; - /// Undo redo status changed event. - compositions::GuiNotifyEvent UndoRedoChanged; - /// Modified status changed event. - compositions::GuiNotifyEvent ModifiedChanged; - - /// Get the document. - /// The document. - Ptr GetDocument(); - /// 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); - - //================ document items - - /// Add a document item. The name of the document item will display in the position of the <object> element with the same name in the document. - /// The document item. - /// Returns true if this operation succeeded. - bool AddDocumentItem(Ptr value); - - /// Remove a document item. - /// The document item. - /// Returns true if this operation succeeded. - bool RemoveDocumentItem(Ptr value); - - /// Get all document items. - /// All document items. - const DocumentItemMap& GetDocumentItems(); - - //================ caret operations - - /// - /// Get the begin position of the selection area. - /// - /// The begin position of the selection area. - TextPos GetCaretBegin(); - /// - /// Get the end position of the selection area. - /// - /// The end position of the selection area. - TextPos GetCaretEnd(); - /// - /// Set the end position of the selection area. - /// - /// The begin position of the selection area. - /// The end position of the selection area. - void SetCaret(TextPos begin, TextPos end); - /// Calculate a caret using a specified point. - /// The calculated caret. - /// The specified point. - TextPos CalculateCaretFromPoint(Point point); - /// Get the bounds of a caret. - /// The bounds. - /// The caret. - /// Set to true to get the bounds for the character before it. - Rect GetCaretBounds(TextPos caret, bool frontSide); - - //================ editing operations - - /// Notify that some paragraphs are updated. - /// The start paragraph index. - /// The number of paragraphs to be updated. - /// The number of updated paragraphs. - /// Set to true to notify that the text is updated. - void NotifyParagraphUpdated(vint index, vint oldCount, vint newCount, bool updatedText); - /// Edit run in a specified range. - /// The begin position of the range. - /// The end position of the range. - /// The new run. - /// Set to true to copy the model before editing. Otherwise, objects inside the model will be used directly - void EditRun(TextPos begin, TextPos end, Ptr model, bool copy); - /// Edit text in a specified range. - /// The begin position of the range. - /// The end position of the range. - /// Set to true to use the text style in front of the specified range. - /// The new text. - void EditText(TextPos begin, TextPos end, bool frontSide, const collections::Array& text); - /// Edit style in a specified range. - /// The begin position of the range. - /// The end position of the range. - /// The new style. - void EditStyle(TextPos begin, TextPos end, Ptr style); - /// Edit image in a specified range. - /// The begin position of the range. - /// The end position of the range. - /// The new image. - void EditImage(TextPos begin, TextPos end, Ptr image); - /// Set hyperlink in a specified range. - /// The index of the paragraph to edit. - /// The begin position of the range. - /// The end position of the range. - /// The reference of the hyperlink. - /// The normal style name of the hyperlink. - /// The active style name of the hyperlink. - void EditHyperlink(vint paragraphIndex, vint begin, vint end, const WString& reference, const WString& normalStyleName=DocumentModel::NormalLinkStyleName, const WString& activeStyleName=DocumentModel::ActiveLinkStyleName); - /// Remove hyperlink in a specified range. - /// The index of the paragraph to edit. - /// The begin position of the range. - /// The end position of the range. - void RemoveHyperlink(vint paragraphIndex, vint begin, vint end); - /// Edit style name in a specified range. - /// The begin position of the range. - /// The end position of the range. - /// The new style name. - void EditStyleName(TextPos begin, TextPos end, const WString& styleName); - /// Remove style name in a specified range. - /// The begin position of the range. - /// The end position of the range. - void RemoveStyleName(TextPos begin, TextPos end); - /// Rename a style. - /// The name of the style. - /// The new name. - void RenameStyle(const WString& oldStyleName, const WString& newStyleName); - /// Clear all styles in a specified range. - /// The begin position of the range. - /// The end position of the range. - void ClearStyle(TextPos begin, TextPos end); - /// Summarize the text style in a specified range. - /// The text style summary. - /// The begin position of the range. - /// The end position of the range. - Ptr SummarizeStyle(TextPos begin, TextPos end); - /// Summarize the style name in a specified range. - /// The style name summary. - /// The begin position of the range. - /// The end position of the range. - Nullable SummarizeStyleName(TextPos begin, TextPos end); - /// Set the alignment of paragraphs in a specified range. - /// The begin position of the range. - /// The end position of the range. - /// The alignment for each paragraph. - void SetParagraphAlignments(TextPos begin, TextPos end, const collections::Array>& alignments); - /// Set the alignment of paragraphs in a specified range. - /// The begin position of the range. - /// The end position of the range. - /// The alignment for each paragraph. - void SetParagraphAlignment(TextPos begin, TextPos end, Nullable alignment); - /// Summarize the text alignment in a specified range. - /// The text alignment summary. - /// The begin position of the range. - /// The end position of the range. - Nullable SummarizeParagraphAlignment(TextPos begin, TextPos end); - - //================ editing control - - /// Get the href attribute of the active hyperlink. - /// The href attribute of the active hyperlink. - WString GetActiveHyperlinkReference(); - /// Get the edit mode of this control. - /// The edit mode. - EditMode GetEditMode(); - /// Set the edit mode of this control. - /// The edit mode. - void SetEditMode(EditMode value); - - //================ selection operations - - /// Select all text. - void SelectAll(); - /// Get the selected text. - /// The selected text. - WString GetSelectionText(); - /// Set the selected text. - /// The selected text. - void SetSelectionText(const WString& value); - /// Get the selected model. - /// The selected model. - Ptr GetSelectionModel(); - /// Set the selected model. - /// The selected model. - void SetSelectionModel(Ptr value); - - //================ clipboard operations - - /// Test can the selection be cut. - /// Returns true if the selection can be cut. - bool CanCut(); - /// Test can the selection be copied. - /// Returns true if the selection can be cut. - bool CanCopy(); - /// Test can the content in the clipboard be pasted. - /// Returns true if the content in the clipboard can be pasted. - bool CanPaste(); - /// Cut the selection text. - /// Returns true if this operation succeeded. - bool Cut(); - /// Copy the selection text. - /// Returns true if this operation succeeded. - bool Copy(); - /// Paste the content from the clipboard and replace the selected text. - /// Returns true if this operation succeeded. - bool Paste(); - - //================ undo redo control - - /// Test can undo. - /// Returns true if this action can be performed. - bool CanUndo(); - /// Test can redo. - /// Returns true if this action can be performed. - bool CanRedo(); - /// Clear all undo and redo information. - void ClearUndoRedo(); - /// Test is the text box modified. - /// Returns true if the text box is modified. - bool GetModified(); - /// Notify the text box that the current status is considered saved. - void NotifyModificationSaved(); - /// Perform the undo action. - /// Returns true if this operation succeeded. - bool Undo(); - /// Perform the redo action. - /// Returns true if this operation succeeded. - bool Redo(); - }; - -/*********************************************************************** -GuiDocumentViewer -***********************************************************************/ - - /// Scrollable document viewer for displaying . - class GuiDocumentViewer : public GuiScrollContainer, public GuiDocumentCommonInterface, public Description - { - GUI_SPECIFY_CONTROL_TEMPLATE_TYPE(DocumentViewerTemplate, GuiScrollContainer) - protected: - - void UpdateDisplayFont()override; - Point GetDocumentViewPosition()override; - void EnsureRectVisible(Rect bounds)override; - public: - /// Create a control with a specified style provider. - /// The theme name for retriving a default control template. - GuiDocumentViewer(theme::ThemeName themeName); - ~GuiDocumentViewer(); - - const WString& GetText()override; - void SetText(const WString& value)override; - }; - -/*********************************************************************** -GuiDocumentViewer -***********************************************************************/ - - /// Static document viewer for displaying . - class GuiDocumentLabel : public GuiControl, public GuiDocumentCommonInterface, public Description - { - GUI_SPECIFY_CONTROL_TEMPLATE_TYPE(DocumentLabelTemplate, GuiControl) - protected: - - void UpdateDisplayFont()override; - public: - /// Create a control with a specified default theme. - /// The theme name for retriving a default control template. - GuiDocumentLabel(theme::ThemeName themeName); - ~GuiDocumentLabel(); - - const WString& GetText()override; - void SetText(const WString& value)override; - }; - } - } -} - -#endif - - -/*********************************************************************** -.\CONTROLS\INCLUDEFORWARD.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI::Application Framework - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_CONTROLS_INCLUDEFORWARD -#define VCZH_PRESENTATION_CONTROLS_INCLUDEFORWARD - - -namespace vl -{ - namespace presentation - { - namespace controls - { - class GuiControl; - class GuiCustomControl; - class GuiLabel; - class GuiButton; - class GuiSelectableButton; - class GuiScroll; - class GuiTabPage; - class GuiTab; - class GuiScrollView; - class GuiScrollContainer; - class GuiControlHost; - class GuiWindow; - class GuiPopup; - class GuiTooltip; - class GuiListControl; - class GuiSelectableListControl; - class GuiVirtualTextList; - class GuiTextList; - class GuiListViewColumnHeader; - class GuiListViewBase; - class GuiVirtualListView; - class GuiListView; - class GuiMenu; - class GuiMenuBar; - class GuiMenuButton; - class GuiVirtualTreeListControl; - class GuiVirtualTreeView; - class GuiTreeView; - class GuiComboBoxBase; - class GuiComboBoxListControl; - class GuiToolstripMenu; - class GuiToolstripMenuBar; - class GuiToolstripToolBar; - class GuiToolstripButton; - class GuiToolstripNestedContainer; - class GuiToolstripGroupContainer; - class GuiToolstripGroup; - class GuiRibbonTab; - class GuiRibbonTabPage; - class GuiRibbonGroup; - class GuiRibbonIconLabel; - class GuiRibbonButtons; - class GuiRibbonToolstrips; - class GuiRibbonGallery; - class GuiRibbonToolstripMenu; class GuiBindableRibbonGalleryList; - class GuiDocumentViewer; - class GuiDocumentLabel; - class GuiMultilineTextBox; - class GuiSinglelineTextBox; - class GuiVirtualDataGrid; - class GuiDatePicker; - class GuiDateComboBox; - class GuiBindableTextList; - class GuiBindableListView; - class GuiBindableTreeView; - class GuiBindableDataGrid; + +/*********************************************************************** +GalleryItemArranger +***********************************************************************/ + + namespace ribbon_impl + { + class GalleryItemArranger : public list::RangedItemArrangerBase, public Description + { + private: + vint pim_itemWidth = 0; + bool blockScrollUpdate = true; + + protected: + GuiBindableRibbonGalleryList* owner; + vint itemWidth = 1; + vint firstIndex = 0; + + void BeginPlaceItem(bool forMoving, Rect newBounds, vint& newStartIndex)override; + void PlaceItem(bool forMoving, bool newCreatedStyle, vint index, ItemStyleRecord style, Rect viewBounds, Rect& bounds, Margin& alignmentToParent)override; + bool IsItemOutOfViewBounds(vint index, ItemStyleRecord style, Rect bounds, Rect viewBounds)override; + bool EndPlaceItem(bool forMoving, Rect newBounds, vint newStartIndex)override; + void InvalidateItemSizeCache()override; + Size OnCalculateTotalSize()override; + public: + GalleryItemArranger(GuiBindableRibbonGalleryList* _owner); + ~GalleryItemArranger(); + + vint FindItem(vint itemIndex, compositions::KeyDirection key)override; + GuiListControl::EnsureItemVisibleResult EnsureItemVisible(vint itemIndex)override; + Size GetAdoptedSize(Size expectedSize)override; + + void ScrollUp(); + void ScrollDown(); + void UnblockScrollUpdate(); + }; + + class GalleryResponsiveLayout : public compositions::GuiResponsiveCompositionBase, public Description + { + protected: + vint minCount = 0; + vint maxCount = 0; + Size sizeOffset; + vint itemCount = 0; + vint itemWidth = 1; + + void UpdateMinSize(); + public: + GalleryResponsiveLayout(); + ~GalleryResponsiveLayout(); + + vint GetMinCount(); + vint GetMaxCount(); + vint GetItemWidth(); + Size GetSizeOffset(); + vint GetVisibleItemCount(); + + void SetMinCount(vint value); + void SetMaxCount(vint value); + void SetItemWidth(vint value); + void SetSizeOffset(Size value); + + vint GetLevelCount()override; + vint GetCurrentLevel()override; + bool LevelDown()override; + bool LevelUp()override; + }; + } } } } #endif -/*********************************************************************** -.\CONTROLS\TEXTEDITORPACKAGE\EDITORCALLBACK\GUITEXTAUTOCOMPLETE.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI::Control System - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_CONTROLS_GUITEXTAUTOCOMPLETE -#define VCZH_PRESENTATION_CONTROLS_GUITEXTAUTOCOMPLETE - - -namespace vl -{ - namespace presentation - { - namespace controls - { - -/*********************************************************************** -GuiTextBoxAutoCompleteBase -***********************************************************************/ - - /// The base class of text box auto complete controller. - class GuiTextBoxAutoCompleteBase : public Object, public virtual ICommonTextEditCallback - { - public: - /// Represents an auto complete candidate item. - struct AutoCompleteItem - { - /// Tag object for any purpose, e.g., data binding. - description::Value tag; - /// Display text for the item. - WString text; - }; - - /// Auto complete control provider. - class IAutoCompleteControlProvider : public virtual Interface - { - public: - /// Get the auto complete control that will be installed in a popup to show candidate items. - /// The auto complete control. - virtual GuiControl* GetAutoCompleteControl() = 0; - - /// Get the list control storing candidate items. - /// The list control. It should be inside the auto complete control, or the auto complete control itself. - virtual GuiSelectableListControl* GetListControl() = 0; - - /// Store candidate items in the list control. - /// Candidate items. - virtual void SetSortedContent(const collections::List& items) = 0; - - /// Get the numbers of all stored candidate items. - /// The number of all stored candidate items. - virtual vint GetItemCount() = 0; - - /// Get the text of a specified item. - /// The index of the item. - /// The text of the item. - virtual WString GetItemText(vint index) = 0; - }; - - class TextListControlProvider : public Object, public virtual IAutoCompleteControlProvider - { - protected: - GuiTextList* autoCompleteList; - - public: - TextListControlProvider(TemplateProperty controlTemplate = {}); - ~TextListControlProvider(); - - GuiControl* GetAutoCompleteControl()override; - GuiSelectableListControl* GetListControl()override; - void SetSortedContent(const collections::List& items)override; - vint GetItemCount()override; - WString GetItemText(vint index)override; - }; - - protected: - elements::GuiColorizedTextElement* element; - SpinLock* elementModifyLock; - compositions::GuiGraphicsComposition* ownerComposition; - GuiPopup* autoCompletePopup; - Ptr autoCompleteControlProvider; - TextPos autoCompleteStartPosition; - - bool IsPrefix(const WString& prefix, const WString& candidate); - public: - /// Create an auto complete. - /// A auto complete control provider. Set to null to use a default one. - GuiTextBoxAutoCompleteBase(Ptr _autoCompleteControlProvider = nullptr); - ~GuiTextBoxAutoCompleteBase(); - - void Attach(elements::GuiColorizedTextElement* _element, SpinLock& _elementModifyLock, compositions::GuiGraphicsComposition* _ownerComposition, vuint editVersion)override; - void Detach()override; - void TextEditPreview(TextEditPreviewStruct& arguments)override; - void TextEditNotify(const TextEditNotifyStruct& arguments)override; - void TextCaretChanged(const TextCaretChangedStruct& arguments)override; - void TextEditFinished(vuint editVersion)override; - - /// Get the list state. - /// Returns true if the list is visible. - bool IsListOpening(); - /// Notify the list to be visible. - /// The text position to show the list. - void OpenList(TextPos startPosition); - /// Notify the list to be invisible. - void CloseList(); - /// Set the content of the list. - /// The content of the list. - void SetListContent(const collections::List& items); - /// Get the last start position when the list is opened. - /// The start position. - TextPos GetListStartPosition(); - /// Select the previous item. - /// Returns true if this operation succeeded. - bool SelectPreviousListItem(); - /// Select the next item. - /// Returns true if this operation succeeded. - bool SelectNextListItem(); - /// Apply the selected item into the text box. - /// Returns true if this operation succeeded. - bool ApplySelectedListItem(); - /// Get the selected item. - /// The text of the selected item. Returns empty if there is no selected item. - WString GetSelectedListItem(); - /// Highlight a candidate item in the list. - /// The text to match an item. - void HighlightList(const WString& editingText); - }; - } - } -} - -#endif - -/*********************************************************************** -.\CONTROLS\TEXTEDITORPACKAGE\GUITEXTCOMMONINTERFACE.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI::Control System - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_CONTROLS_GUITEXTCOMMONINTERFACE -#define VCZH_PRESENTATION_CONTROLS_GUITEXTCOMMONINTERFACE - - -namespace vl -{ - namespace presentation - { - namespace compositions - { - class GuiShortcutKeyManager; - } - - namespace controls - { - -/*********************************************************************** -Common Interface -***********************************************************************/ - - /// Common interface for text box controls. - class GuiTextBoxCommonInterface abstract : public Description - { - typedef collections::Array ColorArray; - protected: - class ICallback : public virtual IDescriptable, public Description - { - public: - virtual TextPos GetLeftWord(TextPos pos)=0; - virtual TextPos GetRightWord(TextPos pos)=0; - virtual void GetWord(TextPos pos, TextPos& begin, TextPos& end)=0; - virtual vint GetPageRows()=0; - virtual bool BeforeModify(TextPos start, TextPos end, const WString& originalText, WString& inputText)=0; - virtual void AfterModify(TextPos originalStart, TextPos originalEnd, const WString& originalText, TextPos inputStart, TextPos inputEnd, const WString& inputText)=0; - virtual void ScrollToView(Point point)=0; - virtual vint GetTextMargin()=0; - }; - - class DefaultCallback : public Object, public ICallback, public Description - { - protected: - elements::GuiColorizedTextElement* textElement; - compositions::GuiGraphicsComposition* textComposition; - bool readonly; - public: - DefaultCallback(elements::GuiColorizedTextElement* _textElement, compositions::GuiGraphicsComposition* _textComposition); - ~DefaultCallback(); - - TextPos GetLeftWord(TextPos pos)override; - TextPos GetRightWord(TextPos pos)override; - void GetWord(TextPos pos, TextPos& begin, TextPos& end)override; - vint GetPageRows()override; - bool BeforeModify(TextPos start, TextPos end, const WString& originalText, WString& inputText)override; - }; - private: - elements::GuiColorizedTextElement* textElement; - compositions::GuiGraphicsComposition* textComposition; - vuint editVersion; - GuiControl* textControl; - ICallback* callback; - bool dragging; - bool readonly; - Ptr colorizer; - Ptr autoComplete; - Ptr undoRedoProcessor; - - bool filledDefaultColors = false; - ColorArray defaultColors; - - SpinLock elementModifyLock; - collections::List> textEditCallbacks; - Ptr internalShortcutKeyManager; - bool preventEnterDueToAutoComplete; - - void InvokeUndoRedoChanged(); - void InvokeModifiedChanged(); - void UpdateCaretPoint(); - void Move(TextPos pos, bool shift); - void Modify(TextPos start, TextPos end, const WString& input, bool asKeyInput); - bool ProcessKey(VKEY code, bool shift, bool ctrl); - - void OnGotFocus(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); - void OnLostFocus(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); - void OnCaretNotify(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); - - void OnLeftButtonDown(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments); - void OnLeftButtonUp(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments); - void OnMouseMove(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments); - void OnKeyDown(compositions::GuiGraphicsComposition* sender, compositions::GuiKeyEventArgs& arguments); - void OnCharInput(compositions::GuiGraphicsComposition* sender, compositions::GuiCharEventArgs& arguments); - - protected: - - void Install(elements::GuiColorizedTextElement* _textElement, compositions::GuiGraphicsComposition* _textComposition, GuiControl* _textControl, compositions::GuiGraphicsComposition* eventComposition, compositions::GuiGraphicsComposition* focusableComposition); - ICallback* GetCallback(); - void SetCallback(ICallback* value); - bool AttachTextEditCallback(Ptr value); - bool DetachTextEditCallback(Ptr value); - void AddShortcutCommand(VKEY key, const Func& eventHandler); - elements::GuiColorizedTextElement* GetTextElement(); - void UnsafeSetText(const WString& value); - - public: - GuiTextBoxCommonInterface(); - ~GuiTextBoxCommonInterface(); - - /// Selection changed event. - compositions::GuiNotifyEvent SelectionChanged; - /// Undo redo status changed event. - compositions::GuiNotifyEvent UndoRedoChanged; - /// Modified status changed event. - compositions::GuiNotifyEvent ModifiedChanged; - - //================ clipboard operations - - /// Test can the selection be cut. - /// Returns true if the selection can be cut. - bool CanCut(); - /// Test can the selection be copied. - /// Returns true if the selection can be cut. - bool CanCopy(); - /// Test can the content in the clipboard be pasted. - /// Returns true if the content in the clipboard can be pasted. - bool CanPaste(); - /// Cut the selection text. - /// Returns true if this operation succeeded. - bool Cut(); - /// Copy the selection text. - /// Returns true if this operation succeeded. - bool Copy(); - /// Paste the content from the clipboard and replace the selected text. - /// Returns true if this operation succeeded. - bool Paste(); - - //================ editing control - - /// Get the readonly mode. - /// Returns true if the text box is readonly. - bool GetReadonly(); - /// Set the readonly mode. - /// Set to true to make the texg box readonly. - void SetReadonly(bool value); - - //================ text operations - - /// Select all text. - void SelectAll(); - /// Select (highlight) a part of text. - /// The begin position. - /// The end position. This is also the caret position. - void Select(TextPos begin, TextPos end); - /// Get the selected text. - /// The selected text. - WString GetSelectionText(); - /// Set the selected text. - /// The selected text. - void SetSelectionText(const WString& value); - /// Set the selected text and let to text box treat this changing as input by the keyboard. - /// The selected text. - void SetSelectionTextAsKeyInput(const WString& value); - - /// Get the text from a specified row number. - /// The text from a specified row number. - /// The specified row number. - WString GetRowText(vint row); - /// Get the number of rows. - /// The number of rows. - vint GetRowCount(); - /// Get the text from a specified range. - /// The text from a specified range. - /// The specified start position. - /// The specified end position. - WString GetFragmentText(TextPos start, TextPos end); - - /// Get the begin text position of the selection. - /// The begin text position of the selection. - TextPos GetCaretBegin(); - /// Get the end text position of the selection. - /// The end text position of the selection. - TextPos GetCaretEnd(); - /// Get the left-top text position of the selection. - /// The left-top text position of the selection. - TextPos GetCaretSmall(); - /// Get the right-bottom text position of the selection. - /// The right-bottom text position of the selection. - TextPos GetCaretLarge(); - - //================ position query - - /// Get the width of a row. - /// The width of a row in pixel. - /// The specified row number - vint GetRowWidth(vint row); - /// Get the height of a row. - /// The height of a row in pixel. - vint GetRowHeight(); - /// Get the maximum width of all rows. - /// The maximum width of all rows. - vint GetMaxWidth(); - /// Get the total height of all rows. - /// The total height of all rows. - vint GetMaxHeight(); - /// Get the nearest position of a character from a specified display position. - /// Get the nearest position of a character. - /// The specified display position. - TextPos GetTextPosFromPoint(Point point); - /// Get the display position of a character from a specified text position. - /// Get the display position of a character. - /// The specified text position. - Point GetPointFromTextPos(TextPos pos); - /// Get the display bounds of a character from a specified text position. - /// Get the display bounds of a character. - /// The specified text position. - Rect GetRectFromTextPos(TextPos pos); - /// Get the nearest text position from a specified display position. - /// Get the nearest text position. - /// The specified display position. - TextPos GetNearestTextPos(Point point); - - //================ colorizing - - /// Get the current colorizer. - /// The current colorizer. - Ptr GetColorizer(); - /// Set the current colorizer. - /// The current colorizer. - void SetColorizer(Ptr value); - - //================ auto complete - - /// Get the current auto complete controller. - /// The current auto complete controller. - Ptr GetAutoComplete(); - /// Set the current auto complete controller. - /// The current auto complete controller. - void SetAutoComplete(Ptr value); - - //================ undo redo control - - /// Get the current edit version. When the control is modified, the edit version increased. Calling will not reset the edit version. - /// The current edit version. - vuint GetEditVersion(); - /// Test can undo. - /// Returns true if this action can be performed. - bool CanUndo(); - /// Test can redo. - /// Returns true if this action can be performed. - bool CanRedo(); - /// Clear all undo and redo information. - void ClearUndoRedo(); - /// Test is the text box modified. - /// Returns true if the text box is modified. - bool GetModified(); - /// Notify the text box that the current status is considered saved. - void NotifyModificationSaved(); - /// Perform the undo action. - /// Returns true if this operation succeeded. - bool Undo(); - /// Perform the redo action. - /// Returns true if this operation succeeded. - bool Redo(); - }; - } - } -} - -#endif - -/*********************************************************************** -.\CONTROLS\TEXTEDITORPACKAGE\GUITEXTCONTROLS.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI::Control System - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_CONTROLS_GUITEXTCONTROLS -#define VCZH_PRESENTATION_CONTROLS_GUITEXTCONTROLS - - -namespace vl -{ - namespace presentation - { - namespace controls - { - -/*********************************************************************** -MultilineTextBox -***********************************************************************/ - - /// Multiline text box control. - class GuiMultilineTextBox : public GuiScrollView, public GuiTextBoxCommonInterface, public Description - { - GUI_SPECIFY_CONTROL_TEMPLATE_TYPE(MultilineTextBoxTemplate, GuiScrollView) - public: - static const vint TextMargin=3; - - class CommandExecutor : public Object, public ITextBoxCommandExecutor - { - protected: - GuiMultilineTextBox* textBox; - - public: - CommandExecutor(GuiMultilineTextBox* _textBox); - ~CommandExecutor(); - - void UnsafeSetText(const WString& value)override; - }; - - protected: - class TextElementOperatorCallback : public GuiTextBoxCommonInterface::DefaultCallback, public Description - { - protected: - GuiMultilineTextBox* textControl; - public: - TextElementOperatorCallback(GuiMultilineTextBox* _textControl); - - void AfterModify(TextPos originalStart, TextPos originalEnd, const WString& originalText, TextPos inputStart, TextPos inputEnd, const WString& inputText)override; - void ScrollToView(Point point)override; - vint GetTextMargin()override; - }; - - protected: - Ptr callback; - Ptr commandExecutor; - elements::GuiColorizedTextElement* textElement = nullptr; - compositions::GuiBoundsComposition* textComposition = nullptr; - - void UpdateVisuallyEnabled()override; - void UpdateDisplayFont()override; - void OnRenderTargetChanged(elements::IGuiGraphicsRenderTarget* renderTarget)override; - Size QueryFullSize()override; - void UpdateView(Rect viewBounds)override; - void CalculateViewAndSetScroll(); - void OnBoundsMouseButtonDown(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments); - public: - /// Create a control with a specified style provider. - /// The theme name for retriving a default control template. - GuiMultilineTextBox(theme::ThemeName themeName); - ~GuiMultilineTextBox(); - - const WString& GetText()override; - void SetText(const WString& value)override; - }; - -/*********************************************************************** -SinglelineTextBox -***********************************************************************/ - - /// Single text box control. - class GuiSinglelineTextBox : public GuiControl, public GuiTextBoxCommonInterface, public Description - { - GUI_SPECIFY_CONTROL_TEMPLATE_TYPE(SinglelineTextBoxTemplate, GuiControl) - public: - static const vint TextMargin=2; - - protected: - class TextElementOperatorCallback : public GuiTextBoxCommonInterface::DefaultCallback, public Description - { - public: - TextElementOperatorCallback(GuiSinglelineTextBox* _textControl); - - bool BeforeModify(TextPos start, TextPos end, const WString& originalText, WString& inputText)override; - void AfterModify(TextPos originalStart, TextPos originalEnd, const WString& originalText, TextPos inputStart, TextPos inputEnd, const WString& inputText)override; - void ScrollToView(Point point)override; - vint GetTextMargin()override; - }; - - protected: - Ptr callback; - elements::GuiColorizedTextElement* textElement = nullptr; - compositions::GuiTableComposition* textCompositionTable = nullptr; - compositions::GuiCellComposition* textComposition = nullptr; - - void UpdateVisuallyEnabled()override; - void UpdateDisplayFont()override; - void RearrangeTextElement(); - void OnRenderTargetChanged(elements::IGuiGraphicsRenderTarget* renderTarget)override; - void OnBoundsMouseButtonDown(compositions::GuiGraphicsComposition* sender, compositions::GuiMouseEventArgs& arguments); - public: - /// Create a control with a specified style provider. - /// The theme name for retriving a default control template. - GuiSinglelineTextBox(theme::ThemeName themeName); - ~GuiSinglelineTextBox(); - - const WString& GetText()override; - void SetText(const WString& value)override; - - /// - /// Get the password mode displaying character. - /// - /// The password mode displaying character. Returns L'\0' means the password mode is not activated. - wchar_t GetPasswordChar(); - /// - /// Set the password mode displaying character. - /// - /// The password mode displaying character. Set to L'\0' to deactivate the password mode. - void SetPasswordChar(wchar_t value); - }; - } - } -} - -#endif /*********************************************************************** .\CONTROLS\TOOLSTRIPPACKAGE\GUITOOLSTRIPCOMMAND.H @@ -18841,75 +19451,83 @@ Interfaces: #endif /*********************************************************************** -.\GACUIREFLECTIONHELPER.H +.\RESOURCES\GUIDOCUMENTCLIPBOARD.H ***********************************************************************/ /*********************************************************************** Vczh Library++ 3.0 Developer: Zihan Chen(vczh) -GacUI Reflection Helper +GacUI::Resource +Interfaces: ***********************************************************************/ -#ifndef VCZH_PRESENTATION_GACUIREFLECTIONHELPER -#define VCZH_PRESENTATION_GACUIREFLECTIONHELPER +#ifndef VCZH_PRESENTATION_RESOURCES_GUIDOCUMENTCLIPBOARD +#define VCZH_PRESENTATION_RESOURCES_GUIDOCUMENTCLIPBOARD namespace vl { - namespace reflection + namespace presentation { - namespace description + extern void ModifyDocumentForClipboard(Ptr model); + extern Ptr LoadDocumentFromClipboardStream(stream::IStream& clipboardStream); + extern void SaveDocumentToClipboardStream(Ptr model, stream::IStream& clipboardStream); + + extern void SaveDocumentToRtf(Ptr model, AString& rtf); + extern void SaveDocumentToRtfStream(Ptr model, stream::IStream& rtfStream); + + extern void SaveDocumentToHtmlUtf8(Ptr model, AString& header, AString& content, AString& footer); + extern void SaveDocumentToHtmlClipboardStream(Ptr model, stream::IStream& clipboardStream); + } +} + +#endif + +/*********************************************************************** +.\RESOURCES\GUIDOCUMENTEDITOR.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI::Resource + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_RESOURCES_GUIDOCUMENTEDITOR +#define VCZH_PRESENTATION_RESOURCES_GUIDOCUMENTEDITOR + + +namespace vl +{ + namespace presentation + { + typedef DocumentModel::RunRange RunRange; + typedef DocumentModel::RunRangeMap RunRangeMap; + + namespace document_editor { - -/*********************************************************************** -Serialization -***********************************************************************/ - - template<> - struct TypedValueSerializerProvider - { - static presentation::Color GetDefaultValue(); - static bool Serialize(const presentation::Color& input, WString& output); - static bool Deserialize(const WString& input, presentation::Color& output); - static IBoxedValue::CompareResult Compare(const presentation::Color& a, const presentation::Color& b); - }; - - template<> - struct TypedValueSerializerProvider - { - static presentation::DocumentFontSize GetDefaultValue(); - static bool Serialize(const presentation::DocumentFontSize& input, WString& output); - static bool Deserialize(const WString& input, presentation::DocumentFontSize& output); - static IBoxedValue::CompareResult Compare(const presentation::DocumentFontSize& a, const presentation::DocumentFontSize& b); - }; - - template<> - struct TypedValueSerializerProvider - { - static presentation::GlobalStringKey GetDefaultValue(); - static bool Serialize(const presentation::GlobalStringKey& input, WString& output); - static bool Deserialize(const WString& input, presentation::GlobalStringKey& output); - static IBoxedValue::CompareResult Compare(const presentation::GlobalStringKey& a, const presentation::GlobalStringKey& b); - }; - -/*********************************************************************** -External Functions -***********************************************************************/ - - extern Ptr INativeImage_Constructor(const WString& path); - extern presentation::INativeCursor* INativeCursor_Constructor1(); - extern presentation::INativeCursor* INativeCursor_Constructor2(presentation::INativeCursor::SystemCursorType type); - - template - Ptr Element_Constructor() - { - return T::Create(); - } - extern presentation::elements::text::TextLines* GuiColorizedTextElement_GetLines(presentation::elements::GuiColorizedTextElement* thisObject); - - extern void GuiTableComposition_SetRows(presentation::compositions::GuiTableComposition* thisObject, vint value); - extern void GuiTableComposition_SetColumns(presentation::compositions::GuiTableComposition* thisObject, vint value); - extern void IGuiAltActionHost_CollectAltActions(presentation::compositions::IGuiAltActionHost* host, collections::List& actions); + extern void GetRunRange(DocumentParagraphRun* run, RunRangeMap& runRanges); + extern void LocateStyle(DocumentParagraphRun* run, RunRangeMap& runRanges, vint position, bool frontSide, collections::List& locatedRuns); + extern Ptr LocateHyperlink(DocumentParagraphRun* run, RunRangeMap& runRanges, vint row, vint start, vint end); + extern Ptr CopyStyle(Ptr style); + extern Ptr CopyRun(DocumentRun* run); + extern Ptr CopyStyledText(collections::List& styleRuns, const WString& text); + extern Ptr CopyRunRecursively(DocumentParagraphRun* run, RunRangeMap& runRanges, vint start, vint end, bool deepCopy); + extern void CollectStyleName(DocumentParagraphRun* run, collections::List& styleNames); + extern void ReplaceStyleName(DocumentParagraphRun* run, const WString& oldStyleName, const WString& newStyleName); + extern void RemoveRun(DocumentParagraphRun* run, RunRangeMap& runRanges, vint start, vint end); + extern void CutRun(DocumentParagraphRun* run, RunRangeMap& runRanges, vint position, Ptr& leftRun, Ptr& rightRun); + extern void ClearUnnecessaryRun(DocumentParagraphRun* run, DocumentModel* model); + extern void AddStyle(DocumentParagraphRun* run, RunRangeMap& runRanges, vint start, vint end, Ptr style); + extern void AddHyperlink(DocumentParagraphRun* run, RunRangeMap& runRanges, vint start, vint end, const WString& reference, const WString& normalStyleName, const WString& activeStyleName); + extern void AddStyleName(DocumentParagraphRun* run, RunRangeMap& runRanges, vint start, vint end, const WString& styleName); + 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 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); } } } @@ -19083,317 +19701,124 @@ Parser Manager #endif /*********************************************************************** -.\CONTROLS\TEXTEDITORPACKAGE\LANGUAGESERVICE\GUILANGUAGEOPERATIONS.H +.\RESOURCES\GUIRESOURCEMANAGER.H ***********************************************************************/ /*********************************************************************** Vczh Library++ 3.0 Developer: Zihan Chen(vczh) -GacUI::Control System +GacUI Reflection: Instance Loader Interfaces: ***********************************************************************/ -#ifndef VCZH_PRESENTATION_CONTROLS_GUILANGUAGEOPERATIONS -#define VCZH_PRESENTATION_CONTROLS_GUILANGUAGEOPERATIONS +#ifndef VCZH_PRESENTATION_REFLECTION_GUIRESOURCEMANAGER +#define VCZH_PRESENTATION_REFLECTION_GUIRESOURCEMANAGER namespace vl { namespace presentation { - namespace controls + +/*********************************************************************** +IGuiResourceManager +***********************************************************************/ + + class GuiResourceClassNameRecord : public Object, public Description + { + public: + collections::List classNames; + collections::Dictionary> classResources; + }; + + class IGuiResourceManager : public IDescriptable, public Description + { + public: + virtual void SetResource(Ptr resource, GuiResourceError::List& errors, GuiResourceUsage usage = GuiResourceUsage::DataOnly) = 0; + virtual Ptr GetResource(const WString& name) = 0; + virtual Ptr GetResourceFromClassName(const WString& classFullName) = 0; + virtual void UnloadResource(const WString& name) = 0; + virtual void LoadResourceOrPending(stream::IStream& resourceStream, GuiResourceError::List& errors, GuiResourceUsage usage = GuiResourceUsage::DataOnly) = 0; + virtual void LoadResourceOrPending(stream::IStream& resourceStream, GuiResourceUsage usage = GuiResourceUsage::DataOnly) = 0; + virtual void GetPendingResourceNames(collections::List& names) = 0; + }; + + extern IGuiResourceManager* GetResourceManager(); + } +} + +#endif + +/*********************************************************************** +.\GACUIREFLECTIONHELPER.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI Reflection Helper + +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_GACUIREFLECTIONHELPER +#define VCZH_PRESENTATION_GACUIREFLECTIONHELPER + + +namespace vl +{ + namespace reflection + { + namespace description { /*********************************************************************** -ParsingInput +Serialization ***********************************************************************/ - class RepeatingParsingExecutor; - - /// A data structure storing the parsing input for text box control. - struct RepeatingParsingInput + template<> + struct TypedValueSerializerProvider { - /// The text box edit version of the code. - vuint editVersion = 0; - /// The code. - WString code; + static presentation::Color GetDefaultValue(); + static bool Serialize(const presentation::Color& input, WString& output); + static bool Deserialize(const WString& input, presentation::Color& output); + static IBoxedValue::CompareResult Compare(const presentation::Color& a, const presentation::Color& b); + }; + + template<> + struct TypedValueSerializerProvider + { + static presentation::DocumentFontSize GetDefaultValue(); + static bool Serialize(const presentation::DocumentFontSize& input, WString& output); + static bool Deserialize(const WString& input, presentation::DocumentFontSize& output); + static IBoxedValue::CompareResult Compare(const presentation::DocumentFontSize& a, const presentation::DocumentFontSize& b); + }; + + template<> + struct TypedValueSerializerProvider + { + static presentation::GlobalStringKey GetDefaultValue(); + static bool Serialize(const presentation::GlobalStringKey& input, WString& output); + static bool Deserialize(const WString& input, presentation::GlobalStringKey& output); + static IBoxedValue::CompareResult Compare(const presentation::GlobalStringKey& a, const presentation::GlobalStringKey& b); }; /*********************************************************************** -ParsingOutput +External Functions ***********************************************************************/ - /// A data structure storing the parsing result for text box control. - struct RepeatingParsingOutput + extern Ptr INativeImage_Constructor(const WString& path); + extern presentation::INativeCursor* INativeCursor_Constructor1(); + extern presentation::INativeCursor* INativeCursor_Constructor2(presentation::INativeCursor::SystemCursorType type); + + template + Ptr Element_Constructor() { - /// The parsed syntax tree. - Ptr node; - /// The text box edit version of the code. - vuint editVersion = 0; - /// The code. - WString code; - /// The cache created from [T:vl.presentation.controls.RepeatingParsingExecutor.IParsingAnalyzer]. - Ptr cache; - }; + return T::Create(); + } + extern presentation::elements::text::TextLines* GuiColorizedTextElement_GetLines(presentation::elements::GuiColorizedTextElement* thisObject); -/*********************************************************************** -PartialParsingOutput -***********************************************************************/ - - /// A data structure storing the parsing result for partial updating when a text box control is modified. - struct RepeatingPartialParsingOutput - { - /// The input data. - RepeatingParsingOutput input; - /// The rule name that can parse the code of the selected context. - WString rule; - /// Range of the original context in the input. - parsing::ParsingTextRange originalRange; - /// The original context in the syntax tree. - Ptr originalNode; - /// The modified context in the syntax tree. - Ptr modifiedNode; - /// The modified code of the selected context. - WString modifiedCode; - }; - -/*********************************************************************** -PartialParsingOutput -***********************************************************************/ - - /// A data structure storing the information for a candidate item. - struct ParsingCandidateItem - { - /// Semantic id. - vint semanticId = -1; - /// Display name. - WString name; - /// Tag object for any purpose, e.g., data binding. - description::Value tag; - }; - -/*********************************************************************** -ParsingContext -***********************************************************************/ - - /// A data structure storing the context of a token. - struct ParsingTokenContext - { - /// Token syntax tree for the selected token. - parsing::ParsingTreeToken* foundToken = nullptr; - /// The object syntax tree parent of the token. - parsing::ParsingTreeObject* tokenParent = nullptr; - /// Type of the parent. - WString type; - /// Field of the parent that contains the token. - WString field; - /// All acceptable semantic ids. - Ptr> acceptableSemanticIds; - - static bool RetriveContext(ParsingTokenContext& output, parsing::ParsingTreeNode* foundNode, RepeatingParsingExecutor* executor); - static bool RetriveContext(ParsingTokenContext& output, parsing::ParsingTextPos pos, parsing::ParsingTreeObject* rootNode, RepeatingParsingExecutor* executor); - static bool RetriveContext(ParsingTokenContext& output, parsing::ParsingTextRange range, parsing::ParsingTreeObject* rootNode, RepeatingParsingExecutor* executor); - }; - -/*********************************************************************** -RepeatingParsingExecutor -***********************************************************************/ - - /// Repeating parsing executor. - class RepeatingParsingExecutor : public RepeatingTaskExecutor, public Description - { - public: - /// Callback. - class ICallback : public virtual Interface - { - public: - /// Callback when a parsing task is finished. - /// the result of the parsing. - virtual void OnParsingFinishedAsync(const RepeatingParsingOutput& output)=0; - /// Callback when requires enabling or disabling automatically repeating calling to the SubmitTask function. - /// Set to true to require an automatically repeating calling to the SubmitTask function - virtual void RequireAutoSubmitTask(bool enabled)=0; - }; - - /// Parsing analyzer. - class IParsingAnalyzer : public virtual Interface - { - private: - parsing::ParsingTreeNode* ToParent(parsing::ParsingTreeNode* node, const RepeatingPartialParsingOutput* output); - parsing::ParsingTreeObject* ToChild(parsing::ParsingTreeObject* node, const RepeatingPartialParsingOutput* output); - Ptr ToChild(Ptr node, const RepeatingPartialParsingOutput* output); - - protected: - /// Get a syntax tree node's parent when the whole tree is in a partial modified state. You should use this function instead of ParsingTreeNode::GetParent when implementing this interface. - /// Returns the parent node. - /// The node. - /// The partial parsing output, which describes how the whole tree is partial modified. - parsing::ParsingTreeNode* GetParent(parsing::ParsingTreeNode* node, const RepeatingPartialParsingOutput* output); - /// Get a syntax tree node's member when the whole tree is in a partial modified state. You should use this function instead of ParsingTreeObject::GetMember when implementing this interface. - /// Returns the member node. - /// The node. - /// The name of the member. - /// The partial parsing output, which describes how the whole tree is partial modified. - Ptr GetMember(parsing::ParsingTreeObject* node, const WString& name, const RepeatingPartialParsingOutput* output); - /// Get a syntax tree node's item when the whole tree is in a partial modified state. You should use this function instead of ParsingTreeArray::GetItem when implementing this interface. - /// Returns the item node. - /// The node. - /// The index of the item. - /// The partial parsing output, which describes how the whole tree is partial modified. - Ptr GetItem(parsing::ParsingTreeArray* node, vint index, const RepeatingPartialParsingOutput* output); - - public: - /// Called when a is created. - /// The releated . - virtual void Attach(RepeatingParsingExecutor* executor) = 0; - - /// Called when a is destroyed. - /// The releated . - virtual void Detach(RepeatingParsingExecutor* executor) = 0; - - /// Called when a new parsing result is produced. A parsing analyzer can create a cache to be attached to the output containing anything necessary. This function does not run in UI thread. - /// The new parsing result. - /// The created cache object, which can be null. - virtual Ptr CreateCacheAsync(const RepeatingParsingOutput& output) = 0; - - /// Called when an semantic id for a token is needed. If an semantic id is returned, a context sensitive color can be assigned to this token. This functio does not run in UI thread, but it will only be called (for several times) after the cache object is initialized. - /// The token context. - /// The current parsing result. - /// The semantic id. - virtual vint GetSemanticIdForTokenAsync(const ParsingTokenContext& tokenContext, const RepeatingParsingOutput& output) = 0; - - /// Called when multiple auto complete candidate items for a token is needed. If nothing is written into the "candidateItems" parameter and the grammar also doesn't provide static candidate items, nothing will popup. This functio does not run in UI thread, but it will only be called (for several times) after the cache object is initialized. - /// The token context. - /// The partial parsing result. It contains the current parsing result, and an incremental parsing result. If the calculation of candidate items are is very context sensitive, then you should be very careful when traversing the syntax tree, by carefully looking at the "originalNode" and the "modifiedNode" in the "partialOutput" parameter. - /// The candidate items. - virtual void GetCandidateItemsAsync(const ParsingTokenContext& tokenContext, const RepeatingPartialParsingOutput& partialOutput, collections::List& candidateItems) = 0; - - /// Create a tag object for a candidate item without a tag object. An candidate item without a tag maybe created by calling or any token marked by a @Candidate attribute in the grammar. - /// The candidate item. - /// The tag object. In most of the case this object is used for data binding or any other purpose when you want to customize the auto complete control. Returns null if the specified [T.vl.presentation.controls.GuiTextBoxAutoCompleteBase.IAutoCompleteControlProvider] can handle null tag correctly. - virtual description::Value CreateTagForCandidateItem(ParsingCandidateItem& item) = 0; - }; - - /// A base class for implementing a callback. - class CallbackBase : public virtual ICallback, public virtual ICommonTextEditCallback - { - private: - bool callbackAutoPushing; - elements::GuiColorizedTextElement* callbackElement; - SpinLock* callbackElementModifyLock; - - protected: - Ptr parsingExecutor; - - public: - CallbackBase(Ptr _parsingExecutor); - ~CallbackBase(); - - void RequireAutoSubmitTask(bool enabled)override; - void Attach(elements::GuiColorizedTextElement* _element, SpinLock& _elementModifyLock, compositions::GuiGraphicsComposition* _ownerComposition, vuint editVersion)override; - void Detach()override; - void TextEditPreview(TextEditPreviewStruct& arguments)override; - void TextEditNotify(const TextEditNotifyStruct& arguments)override; - void TextCaretChanged(const TextCaretChangedStruct& arguments)override; - void TextEditFinished(vuint editVersion)override; - }; - - struct TokenMetaData - { - vint tableTokenIndex; - vint lexerTokenIndex; - vint defaultColorIndex; - bool hasContextColor; - bool hasAutoComplete; - bool isCandidate; - WString unescapedRegexText; - }; - - struct FieldMetaData - { - vint colorIndex; - Ptr> semantics; - }; - private: - Ptr grammarParser; - WString grammarRule; - Ptr analyzer; - collections::List callbacks; - collections::List activatedCallbacks; - ICallback* autoPushingCallback; - - typedef collections::Pair FieldDesc; - collections::Dictionary tokenIndexMap; - collections::SortedList semanticIndexMap; - collections::Dictionary tokenMetaDatas; - collections::Dictionary fieldMetaDatas; - - protected: - - void Execute(const RepeatingParsingInput& input)override; - void PrepareMetaData(); - - /// Called when semantic analyzing is needed. It is encouraged to set the "cache" fields in "context" argument. If there is an binded to the , this function can be automatically done. - /// The parsing result. - virtual void OnContextFinishedAsync(RepeatingParsingOutput& context); - public: - /// Initialize the parsing executor. - /// Parser generated from a grammar. - /// The rule name to parse a complete code. - /// The parsing analyzer to create semantic metadatas, it can be null. - RepeatingParsingExecutor(Ptr _grammarParser, const WString& _grammarRule, Ptr _analyzer = 0); - ~RepeatingParsingExecutor(); - - /// Get the internal parser that parse the text. - /// The internal parser. - Ptr GetParser(); - /// Detach callback. - /// Returns true if this operation succeeded. - /// The callback. - bool AttachCallback(ICallback* value); - /// Detach callback. - /// Returns true if this operation succeeded. - /// The callback. - bool DetachCallback(ICallback* value); - /// Activate a callback. Activating a callback means that the callback owner has an ability to watch a text box modification, e.g., an attached that is also an . The may require one of the activated callback to push code for parsing automatically via a call to . - /// Returns true if this operation succeeded. - /// The callback. - bool ActivateCallback(ICallback* value); - /// Deactivate a callback. See for deatils. - /// Returns true if this operation succeeded. - /// The callback. - bool DeactivateCallback(ICallback* value); - /// Get the parsing analyzer. - /// The parsing analyzer. - Ptr GetAnalyzer(); - - vint GetTokenIndex(const WString& tokenName); - vint GetSemanticId(const WString& name); - WString GetSemanticName(vint id); - const TokenMetaData& GetTokenMetaData(vint regexTokenIndex); - const FieldMetaData& GetFieldMetaData(const WString& type, const WString& field); - - Ptr GetAttribute(vint index, const WString& name, vint argumentCount); - Ptr GetColorAttribute(vint index); - Ptr GetContextColorAttribute(vint index); - Ptr GetSemanticAttribute(vint index); - Ptr GetCandidateAttribute(vint index); - Ptr GetAutoCompleteAttribute(vint index); - - /* - @Color(ColorName) - field: color of the token field when the token type is marked with @ContextColor - token: color of the token - @ContextColor() - token: the color of the token may be changed if the token field is marked with @Color or @Semantic - @Semantic(Type1, Type2, ...) - field: After resolved symbols for this field, only types of symbols that specified in the arguments are acceptable. - @Candidate() - token: when the token can be available after the editing caret, than it will be in the auto complete list. - @AutoComplete() - token: when the token is editing, an auto complete list will appear if possible - */ - }; + extern void GuiTableComposition_SetRows(presentation::compositions::GuiTableComposition* thisObject, vint value); + extern void GuiTableComposition_SetColumns(presentation::compositions::GuiTableComposition* thisObject, vint value); + extern void IGuiAltActionHost_CollectAltActions(presentation::compositions::IGuiAltActionHost* host, collections::List& actions); } } } @@ -19448,424 +19873,3 @@ extern int SetupWindowsDirect2DRenderer(); extern int SetupOSXCoreGraphicsRenderer(); #endif - -/*********************************************************************** -.\CONTROLS\TEXTEDITORPACKAGE\LANGUAGESERVICE\GUILANGUAGEAUTOCOMPLETE.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI::Control System - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_CONTROLS_GUILANGUAGEAUTOCOMPLETE -#define VCZH_PRESENTATION_CONTROLS_GUILANGUAGEAUTOCOMPLETE - -namespace vl -{ - namespace presentation - { - namespace controls - { - -/*********************************************************************** -GuiGrammarAutoComplete -***********************************************************************/ - - /// Grammar based auto complete controller. - class GuiGrammarAutoComplete - : public GuiTextBoxAutoCompleteBase - , protected RepeatingParsingExecutor::CallbackBase - , private RepeatingTaskExecutor - { - public: - - /// The auto complete list data. - struct AutoCompleteData : ParsingTokenContext - { - /// Available candidate tokens (in lexer token index). - collections::List candidates; - /// Available candidate tokens (in lexer token index) that marked with @AutoCompleteCandidate(). - collections::List shownCandidates; - /// Candidate items. - collections::List candidateItems; - /// The start position of the editing token in global coordination. - TextPos startPosition; - }; - - /// The analysed data from an input code. - struct AutoCompleteContext : RepeatingPartialParsingOutput - { - /// The edit version of modified code. - vuint modifiedEditVersion = 0; - /// The analysed auto complete list data. - Ptr autoComplete; - }; - private: - Ptr grammarParser; - collections::SortedList leftRecursiveRules; - bool editing; - - SpinLock editTraceLock; - collections::List editTrace; - - SpinLock contextLock; - AutoCompleteContext context; - - void Attach(elements::GuiColorizedTextElement* _element, SpinLock& _elementModifyLock, compositions::GuiGraphicsComposition* _ownerComposition, vuint editVersion)override; - void Detach()override; - void TextEditPreview(TextEditPreviewStruct& arguments)override; - void TextEditNotify(const TextEditNotifyStruct& arguments)override; - void TextCaretChanged(const TextCaretChangedStruct& arguments)override; - void TextEditFinished(vuint editVersion)override; - void OnParsingFinishedAsync(const RepeatingParsingOutput& output)override; - void CollectLeftRecursiveRules(); - - vint UnsafeGetEditTraceIndex(vuint editVersion); - TextPos ChooseCorrectTextPos(TextPos pos, const regex::RegexTokens& tokens); - void ExecuteRefresh(AutoCompleteContext& newContext); - - bool NormalizeTextPos(AutoCompleteContext& newContext, elements::text::TextLines& lines, TextPos& pos); - void ExecuteEdit(AutoCompleteContext& newContext); - - void DeleteFutures(collections::List& futures); - regex::RegexToken* TraverseTransitions( - parsing::tabling::ParsingState& state, - parsing::tabling::ParsingTransitionCollector& transitionCollector, - TextPos stopPosition, - collections::List& nonRecoveryFutures, - collections::List& recoveryFutures - ); - regex::RegexToken* SearchValidInputToken( - parsing::tabling::ParsingState& state, - parsing::tabling::ParsingTransitionCollector& transitionCollector, - TextPos stopPosition, - AutoCompleteContext& newContext, - collections::SortedList& tableTokenIndices - ); - - TextPos GlobalTextPosToModifiedTextPos(AutoCompleteContext& newContext, TextPos pos); - TextPos ModifiedTextPosToGlobalTextPos(AutoCompleteContext& newContext, TextPos pos); - void ExecuteCalculateList(AutoCompleteContext& newContext); - - void Execute(const RepeatingParsingOutput& input)override; - void PostList(const AutoCompleteContext& newContext, bool byGlobalCorrection); - void Initialize(); - protected: - - /// Called when the context of the code is selected. It is encouraged to set the "candidateItems" field in "context.autoComplete" during the call. If there is an binded to the , this function can be automatically done. - /// The selected context. - virtual void OnContextFinishedAsync(AutoCompleteContext& context); - - /// Call this function in the derived class's destructor when it overrided . - void EnsureAutoCompleteFinished(); - public: - /// Create the auto complete controller with a created parsing executor. - /// The parsing executor. - GuiGrammarAutoComplete(Ptr _parsingExecutor); - /// Create the auto complete controller with a specified grammar and start rule to create a . - /// Parser generated from a grammar. - /// - GuiGrammarAutoComplete(Ptr _grammarParser, const WString& _grammarRule); - ~GuiGrammarAutoComplete(); - - /// Get the internal parsing executor. - /// The parsing executor. - Ptr GetParsingExecutor(); - }; - } - } -} - -#endif - -/*********************************************************************** -.\CONTROLS\TEXTEDITORPACKAGE\LANGUAGESERVICE\GUILANGUAGECOLORIZER.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI::Control System - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_CONTROLS_GUILANGUAGECOLORIZER -#define VCZH_PRESENTATION_CONTROLS_GUILANGUAGECOLORIZER - - -namespace vl -{ - namespace presentation - { - namespace controls - { - -/*********************************************************************** -GuiGrammarColorizer -***********************************************************************/ - - /// Grammar based colorizer. - class GuiGrammarColorizer : public GuiTextBoxRegexColorizer, protected RepeatingParsingExecutor::CallbackBase - { - typedef collections::Pair FieldDesc; - typedef collections::Dictionary FieldContextColors; - typedef collections::Dictionary FieldSemanticColors; - typedef elements::text::ColorEntry ColorEntry; - public: - /// Context for doing semantic colorizing. - struct SemanticColorizeContext : ParsingTokenContext - { - /// Output semantic id that comes from one the argument in the @Semantic attribute. - vint semanticId; - }; - private: - collections::Dictionary colorSettings; - collections::Dictionary semanticColorMap; - - SpinLock contextLock; - RepeatingParsingOutput context; - - void OnParsingFinishedAsync(const RepeatingParsingOutput& output)override; - protected: - /// Called when the node is parsed successfully before restarting colorizing. - /// The result of the parsing. - virtual void OnContextFinishedAsync(const RepeatingParsingOutput& context); - - void Attach(elements::GuiColorizedTextElement* _element, SpinLock& _elementModifyLock, compositions::GuiGraphicsComposition* _ownerComposition, vuint editVersion)override; - void Detach()override; - void TextEditPreview(TextEditPreviewStruct& arguments)override; - void TextEditNotify(const TextEditNotifyStruct& arguments)override; - void TextCaretChanged(const TextCaretChangedStruct& arguments)override; - void TextEditFinished(vuint editVersion)override; - - /// Called when a @SemanticColor attribute in a grammar is activated during colorizing to determine a color for the token. If there is an binded to the , this function can be automatically done. - /// Context for doing semantic colorizing. - /// The corressponding result from the . - virtual void OnSemanticColorize(SemanticColorizeContext& context, const RepeatingParsingOutput& input); - - /// Call this function in the derived class's destructor when it overrided . - void EnsureColorizerFinished(); - public: - /// Create the colorizer with a created parsing executor. - /// The parsing executor. - GuiGrammarColorizer(Ptr _parsingExecutor); - /// Create the colorizer with a specified grammar and start rule to create a . - /// Parser generated from a grammar. - /// - GuiGrammarColorizer(Ptr _grammarParser, const WString& _grammarRule); - ~GuiGrammarColorizer(); - - /// Reset all color settings. - void BeginSetColors(); - /// Get all color names. - /// All color names. - const collections::SortedList& GetColorNames(); - /// Get the color for a token theme name (@Color or @ContextColor("theme-name") in the grammar). - /// The color. - /// The token theme name. - ColorEntry GetColor(const WString& name); - /// Set a color for a token theme name (@Color or @ContextColor("theme-name") in the grammar). - /// The token theme name. - /// The color. - void SetColor(const WString& name, const ColorEntry& entry); - /// Set a color for a token theme name (@Color or @ContextColor("theme-name") in the grammar). - /// The token theme name. - /// The color. - void SetColor(const WString& name, const Color& color); - /// Submit all color settings. - void EndSetColors(); - void ColorizeTokenContextSensitive(vint lineIndex, const wchar_t* text, vint start, vint length, vint& token, vint& contextState)override; - - /// Get the internal parsing executor. - /// The parsing executor. - Ptr GetParsingExecutor(); - }; - } - } -} - -#endif - -/*********************************************************************** -.\CONTROLS\TOOLSTRIPPACKAGE\GUIRIBBONIMPL.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI::Control System - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_CONTROLS_GUIRIBBONIMPL -#define VCZH_PRESENTATION_CONTROLS_GUIRIBBONIMPL - - -namespace vl -{ - namespace presentation - { - namespace controls - { - class GuiBindableRibbonGalleryList; - -/*********************************************************************** -GalleryItemArranger -***********************************************************************/ - - namespace ribbon_impl - { - class GalleryItemArranger : public list::RangedItemArrangerBase, public Description - { - private: - vint pim_itemWidth = 0; - bool blockScrollUpdate = true; - - protected: - GuiBindableRibbonGalleryList* owner; - vint itemWidth = 1; - vint firstIndex = 0; - - void BeginPlaceItem(bool forMoving, Rect newBounds, vint& newStartIndex)override; - void PlaceItem(bool forMoving, bool newCreatedStyle, vint index, ItemStyleRecord style, Rect viewBounds, Rect& bounds, Margin& alignmentToParent)override; - bool IsItemOutOfViewBounds(vint index, ItemStyleRecord style, Rect bounds, Rect viewBounds)override; - bool EndPlaceItem(bool forMoving, Rect newBounds, vint newStartIndex)override; - void InvalidateItemSizeCache()override; - Size OnCalculateTotalSize()override; - public: - GalleryItemArranger(GuiBindableRibbonGalleryList* _owner); - ~GalleryItemArranger(); - - vint FindItem(vint itemIndex, compositions::KeyDirection key)override; - GuiListControl::EnsureItemVisibleResult EnsureItemVisible(vint itemIndex)override; - Size GetAdoptedSize(Size expectedSize)override; - - void ScrollUp(); - void ScrollDown(); - void UnblockScrollUpdate(); - }; - - class GalleryResponsiveLayout : public compositions::GuiResponsiveCompositionBase, public Description - { - protected: - vint minCount = 0; - vint maxCount = 0; - Size sizeOffset; - vint itemCount = 0; - vint itemWidth = 1; - - void UpdateMinSize(); - public: - GalleryResponsiveLayout(); - ~GalleryResponsiveLayout(); - - vint GetMinCount(); - vint GetMaxCount(); - vint GetItemWidth(); - Size GetSizeOffset(); - vint GetVisibleItemCount(); - - void SetMinCount(vint value); - void SetMaxCount(vint value); - void SetItemWidth(vint value); - void SetSizeOffset(Size value); - - vint GetLevelCount()override; - vint GetCurrentLevel()override; - bool LevelDown()override; - bool LevelUp()override; - }; - } - } - } -} - -#endif - - -/*********************************************************************** -.\RESOURCES\GUIDOCUMENTCLIPBOARD.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI::Resource - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_RESOURCES_GUIDOCUMENTCLIPBOARD -#define VCZH_PRESENTATION_RESOURCES_GUIDOCUMENTCLIPBOARD - - -namespace vl -{ - namespace presentation - { - extern void ModifyDocumentForClipboard(Ptr model); - extern Ptr LoadDocumentFromClipboardStream(stream::IStream& stream); - extern void SaveDocumentToClipboardStream(Ptr model, stream::IStream& stream); - - extern void SaveDocumentToRtf(Ptr model, AString& rtf); - extern void SaveDocumentToRtfStream(Ptr model, stream::IStream& stream); - - extern void SaveDocumentToHtmlUtf8(Ptr model, AString& header, AString& content, AString& footer); - extern void SaveDocumentToHtmlClipboardStream(Ptr model, stream::IStream& stream); - } -} - -#endif - -/*********************************************************************** -.\RESOURCES\GUIDOCUMENTEDITOR.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI::Resource - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_RESOURCES_GUIDOCUMENTEDITOR -#define VCZH_PRESENTATION_RESOURCES_GUIDOCUMENTEDITOR - - -namespace vl -{ - namespace presentation - { - typedef DocumentModel::RunRange RunRange; - typedef DocumentModel::RunRangeMap RunRangeMap; - - namespace document_editor - { - extern void GetRunRange(DocumentParagraphRun* run, RunRangeMap& runRanges); - extern void LocateStyle(DocumentParagraphRun* run, RunRangeMap& runRanges, vint position, bool frontSide, collections::List& locatedRuns); - extern Ptr LocateHyperlink(DocumentParagraphRun* run, RunRangeMap& runRanges, vint row, vint start, vint end); - extern Ptr CopyStyle(Ptr style); - extern Ptr CopyRun(DocumentRun* run); - extern Ptr CopyStyledText(collections::List& styleRuns, const WString& text); - extern Ptr CopyRunRecursively(DocumentParagraphRun* run, RunRangeMap& runRanges, vint start, vint end, bool deepCopy); - extern void CollectStyleName(DocumentParagraphRun* run, collections::List& styleNames); - extern void ReplaceStyleName(DocumentParagraphRun* run, const WString& oldStyleName, const WString& newStyleName); - extern void RemoveRun(DocumentParagraphRun* run, RunRangeMap& runRanges, vint start, vint end); - extern void CutRun(DocumentParagraphRun* run, RunRangeMap& runRanges, vint position, Ptr& leftRun, Ptr& rightRun); - extern void ClearUnnecessaryRun(DocumentParagraphRun* run, DocumentModel* model); - extern void AddStyle(DocumentParagraphRun* run, RunRangeMap& runRanges, vint start, vint end, Ptr style); - extern void AddHyperlink(DocumentParagraphRun* run, RunRangeMap& runRanges, vint start, vint end, const WString& reference, const WString& normalStyleName, const WString& activeStyleName); - extern void AddStyleName(DocumentParagraphRun* run, RunRangeMap& runRanges, vint start, vint end, const WString& styleName); - 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 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); - } - } -} - -#endif diff --git a/Import/GacUICompiler.h b/Import/GacUICompiler.h index d8f8e51c..cd1a01e0 100644 --- a/Import/GacUICompiler.h +++ b/Import/GacUICompiler.h @@ -13,6 +13,314 @@ DEVELOPER: Zihan Chen(vczh) #include "VlppRegex.h" #include "VlppWorkflowRuntime.h" +/*********************************************************************** +.\GUICPPGEN.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI Reflection: Instance Loader + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_REFLECTION_GUICPPGEN +#define VCZH_PRESENTATION_REFLECTION_GUICPPGEN + + +namespace vl +{ + namespace presentation + { + extern bool WriteErrors( + collections::List& errors, + const filesystem::FilePath& errorPath + ); + + extern Ptr PrecompileResource( + Ptr resource, + IGuiResourcePrecompileCallback* callback, + collections::List& errors); + + extern Ptr WriteWorkflowScript( + Ptr precompiledFolder, + const WString& assemblyResourcePath, + const filesystem::FilePath& workflowPath); + + extern Ptr WriteCppCodesToFile( + Ptr resource, + Ptr compiled, + Ptr cppInput, + const filesystem::FilePath& cppFolder, + collections::List& errors); + + extern bool WriteBinaryResource( + Ptr resource, + bool compress, + bool includeAssemblyInResource, + Nullable resourceOutput, + Nullable assemblyOutput); + + extern bool WriteEmbeddedResource(Ptr resource, + Ptr cppInput, + Ptr cppOutput, + bool compress, + const filesystem::FilePath& filePath); + } +} + +#endif + + +/*********************************************************************** +.\GUIINSTANCEANIMATION.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI Reflection: Shared Script + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_REFLECTION_GUIINSTANCEANIMATION +#define VCZH_PRESENTATION_REFLECTION_GUIINSTANCEANIMATION + + +namespace vl +{ + namespace presentation + { + class GuiInstanceAnimation : public Object, public Description + { + public: + }; + + class GuiInstanceGradientAnimation : public GuiInstanceAnimation, public Description + { + public: + struct Target + { + WString name; + WString interpolation; + + GuiResourceTextPos namePosition; + GuiResourceTextPos interpolationPosition; + }; + + using EnumerateMemberAccessor = const Func(Ptr)>&; + using EnumerateMemberCallback = const Func&; + + WString className; + WString typeName; + WString interpolation; + collections::List targets; + + GuiResourceTextPos tagPosition; + GuiResourceTextPos classPosition; + GuiResourceTextPos typePosition; + GuiResourceTextPos interpolationPosition; + + static Ptr LoadFromXml(Ptr resource, Ptr xml, GuiResourceError::List& errors); + Ptr SaveToXml(); + + bool IsSupportedPrimitiveType(description::ITypeDescriptor* td); + vint ValidateStructMembers(GuiResourceTextPos namePosition, description::ITypeDescriptor* td, const WString& prefix, GuiResourceError::List& errors); + vint ValidatePropertyType(GuiResourceTextPos namePosition, description::ITypeInfo* typeInfo, const WString& prefix, GuiResourceError::List& errors, bool rootValue = false); + + void EnumerateMembers(EnumerateMemberCallback callback, EnumerateMemberAccessor accessor, description::IPropertyInfo* propInfo, description::IPropertyInfo* originPropInfo); + void EnumerateMembers(EnumerateMemberCallback callback, EnumerateMemberAccessor accessor, description::ITypeDescriptor* td, description::IPropertyInfo* originPropInfo); + void EnumerateProperties(EnumerateMemberCallback callback, description::ITypeDescriptor* td); + Ptr InitStruct(description::IPropertyInfo* propInfo, const WString& prefix, collections::SortedList& varNames); + Ptr Compile(GuiResourcePrecompileContext& precompileContext, const WString& moduleName, bool generateImpl, GuiResourceError::List& errors); + }; + } +} + +#endif + +/*********************************************************************** +.\GUIINSTANCEHELPERTYPES.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI Reflection: Instance Helper Types + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_REFLECTION_GUIINSTANCEHELPERTYPES +#define VCZH_PRESENTATION_REFLECTION_GUIINSTANCEHELPERTYPES + + +#if defined(__APPLE__) || defined(__APPLE_CC__) + +using namespace vl; +using namespace vl::presentation; +using namespace vl::presentation::elements; +using namespace vl::presentation::compositions; +using namespace vl::presentation::controls; +using namespace vl::presentation::templates; +using namespace vl::presentation::theme; + +#endif + +namespace vl +{ + namespace presentation + { + +/*********************************************************************** +Helper Types +***********************************************************************/ + + namespace helper_types + { + struct SiteValue + { + vint row = 0; + vint column = 0; + vint rowSpan = 1; + vint columnSpan = 1; + }; + } + } + +#ifndef VCZH_DEBUG_NO_REFLECTION + + namespace reflection + { + namespace description + { + +/*********************************************************************** +Type List +***********************************************************************/ + +#define GUIREFLECTIONHELPERTYPES_TYPELIST(F)\ + F(presentation::helper_types::SiteValue)\ + + GUIREFLECTIONHELPERTYPES_TYPELIST(DECL_TYPE_INFO) + } + } + +#endif +} + +#endif + +/*********************************************************************** +.\GUIINSTANCELOCALIZEDSTRINGS.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI Reflection: Shared Script + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_REFLECTION_GUIINSTANCELOCALIZEDSTRINGS +#define VCZH_PRESENTATION_REFLECTION_GUIINSTANCELOCALIZEDSTRINGS + + +namespace vl +{ + namespace presentation + { + class GuiInstanceLocalizedStrings : public Object, public Description + { + public: + struct StringItem + { + public: + WString name; + WString text; + GuiResourceTextPos textPosition; + }; + + struct Strings + { + using StringItemMap = collections::Dictionary>; + + collections::List locales; + StringItemMap items; + GuiResourceTextPos tagPosition; + + WString GetLocalesName(); + }; + + WString className; + WString defaultLocale; + collections::List> strings; + GuiResourceTextPos tagPosition; + + using ParameterPair = collections::Pair, WString>; + using ParameterList = collections::List; + using PositionList = collections::List; + using TextList = collections::List; + + struct TextDesc + { + ParameterList parameters; + PositionList positions; + TextList texts; + }; + + using TextDescMap = collections::Dictionary, WString>, Ptr>; + + static Ptr LoadFromXml(Ptr resource, Ptr xml, GuiResourceError::List& errors); + Ptr SaveToXml(); + + Ptr GetDefaultStrings(); + WString GetInterfaceTypeName(bool hasNamespace); + + Ptr ParseLocalizedText(const WString& text, GuiResourceTextPos pos, GuiResourceError::List& errors); + void Validate(TextDescMap& textDescs, GuiResourcePrecompileContext& precompileContext, GuiResourceError::List& errors); + Ptr GenerateFunction(Ptr textDesc, const WString& functionName, workflow::WfClassMemberKind classMemberKind); + Ptr GenerateStrings(TextDescMap& textDescs, Ptr ls); + Ptr Compile(GuiResourcePrecompileContext& precompileContext, const WString& moduleName, GuiResourceError::List& errors); + }; + } +} + +#endif + +/*********************************************************************** +.\GUIINSTANCESHAREDSCRIPT.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI Reflection: Shared Script + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_REFLECTION_GUIINSTANCESHAREDSCRIPT +#define VCZH_PRESENTATION_REFLECTION_GUIINSTANCESHAREDSCRIPT + + +namespace vl +{ + namespace presentation + { + class GuiInstanceSharedScript :public Object, public Description + { + public: + WString language; + WString code; + GuiResourceTextPos codePosition; + + static Ptr LoadFromXml(Ptr resource, Ptr xml, GuiResourceError::List& errors); + Ptr SaveToXml(); + }; + } +} + +#endif + /*********************************************************************** .\INSTANCEQUERY\GUIINSTANCEQUERY_AST.H ***********************************************************************/ @@ -453,77 +761,6 @@ Instance Style Context #endif -/*********************************************************************** -.\GUIINSTANCEHELPERTYPES.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI Reflection: Instance Helper Types - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_REFLECTION_GUIINSTANCEHELPERTYPES -#define VCZH_PRESENTATION_REFLECTION_GUIINSTANCEHELPERTYPES - - -#if defined(__APPLE__) || defined(__APPLE_CC__) - -using namespace vl; -using namespace vl::presentation; -using namespace vl::presentation::elements; -using namespace vl::presentation::compositions; -using namespace vl::presentation::controls; -using namespace vl::presentation::templates; -using namespace vl::presentation::theme; - -#endif - -namespace vl -{ - namespace presentation - { - -/*********************************************************************** -Helper Types -***********************************************************************/ - - namespace helper_types - { - struct SiteValue - { - vint row = 0; - vint column = 0; - vint rowSpan = 1; - vint columnSpan = 1; - }; - } - } - -#ifndef VCZH_DEBUG_NO_REFLECTION - - namespace reflection - { - namespace description - { - -/*********************************************************************** -Type List -***********************************************************************/ - -#define GUIREFLECTIONHELPERTYPES_TYPELIST(F)\ - F(presentation::helper_types::SiteValue)\ - - GUIREFLECTIONHELPERTYPES_TYPELIST(DECL_TYPE_INFO) - } - } - -#endif -} - -#endif - /*********************************************************************** .\GUIINSTANCELOADER.H ***********************************************************************/ @@ -740,6 +977,34 @@ Helper Functions #endif +/*********************************************************************** +.\INSTANCEQUERY\GUIINSTANCEQUERY.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI Reflection: Instance Query + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_REFLECTION_INSTANCEQUERY_GUIINSTANCEQUERY +#define VCZH_PRESENTATION_REFLECTION_INSTANCEQUERY_GUIINSTANCEQUERY + + +namespace vl +{ + namespace presentation + { + extern void ExecuteQuery(Ptr query, Ptr context, collections::List>& input, collections::List>& output); + extern void ExecuteQuery(Ptr query, Ptr context, collections::List>& output); + extern void ApplyStyle(Ptr style, Ptr ctor); + extern void GuiIqPrint(Ptr query, stream::StreamWriter& writer); + } +} + +#endif + /*********************************************************************** .\WORKFLOWCODEGEN\GUIINSTANCELOADER_WORKFLOWCODEGEN.H ***********************************************************************/ @@ -920,271 +1185,6 @@ WorkflowCompiler (ScriptPosition) #endif -/*********************************************************************** -.\GUICPPGEN.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI Reflection: Instance Loader - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_REFLECTION_GUICPPGEN -#define VCZH_PRESENTATION_REFLECTION_GUICPPGEN - - -namespace vl -{ - namespace presentation - { - extern bool WriteErrors( - collections::List& errors, - const filesystem::FilePath& errorPath - ); - - extern Ptr PrecompileResource( - Ptr resource, - IGuiResourcePrecompileCallback* callback, - collections::List& errors); - - extern Ptr WriteWorkflowScript( - Ptr precompiledFolder, - const WString& assemblyResourcePath, - const filesystem::FilePath& workflowPath); - - extern Ptr WriteCppCodesToFile( - Ptr resource, - Ptr compiled, - Ptr cppInput, - const filesystem::FilePath& cppFolder, - collections::List& errors); - - extern bool WriteBinaryResource( - Ptr resource, - bool compress, - bool includeAssemblyInResource, - Nullable resourceOutput, - Nullable assemblyOutput); - - extern bool WriteEmbeddedResource(Ptr resource, - Ptr cppInput, - Ptr cppOutput, - bool compress, - const filesystem::FilePath& filePath); - } -} - -#endif - - -/*********************************************************************** -.\GUIINSTANCEANIMATION.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI Reflection: Shared Script - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_REFLECTION_GUIINSTANCEANIMATION -#define VCZH_PRESENTATION_REFLECTION_GUIINSTANCEANIMATION - - -namespace vl -{ - namespace presentation - { - class GuiInstanceAnimation : public Object, public Description - { - public: - }; - - class GuiInstanceGradientAnimation : public GuiInstanceAnimation, public Description - { - public: - struct Target - { - WString name; - WString interpolation; - - GuiResourceTextPos namePosition; - GuiResourceTextPos interpolationPosition; - }; - - using EnumerateMemberAccessor = const Func(Ptr)>&; - using EnumerateMemberCallback = const Func&; - - WString className; - WString typeName; - WString interpolation; - collections::List targets; - - GuiResourceTextPos tagPosition; - GuiResourceTextPos classPosition; - GuiResourceTextPos typePosition; - GuiResourceTextPos interpolationPosition; - - static Ptr LoadFromXml(Ptr resource, Ptr xml, GuiResourceError::List& errors); - Ptr SaveToXml(); - - bool IsSupportedPrimitiveType(description::ITypeDescriptor* td); - vint ValidateStructMembers(GuiResourceTextPos namePosition, description::ITypeDescriptor* td, const WString& prefix, GuiResourceError::List& errors); - vint ValidatePropertyType(GuiResourceTextPos namePosition, description::ITypeInfo* typeInfo, const WString& prefix, GuiResourceError::List& errors, bool rootValue = false); - - void EnumerateMembers(EnumerateMemberCallback callback, EnumerateMemberAccessor accessor, description::IPropertyInfo* propInfo, description::IPropertyInfo* originPropInfo); - void EnumerateMembers(EnumerateMemberCallback callback, EnumerateMemberAccessor accessor, description::ITypeDescriptor* td, description::IPropertyInfo* originPropInfo); - void EnumerateProperties(EnumerateMemberCallback callback, description::ITypeDescriptor* td); - Ptr InitStruct(description::IPropertyInfo* propInfo, const WString& prefix, collections::SortedList& varNames); - Ptr Compile(GuiResourcePrecompileContext& precompileContext, const WString& moduleName, bool generateImpl, GuiResourceError::List& errors); - }; - } -} - -#endif - -/*********************************************************************** -.\INSTANCEQUERY\GUIINSTANCEQUERY.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI Reflection: Instance Query - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_REFLECTION_INSTANCEQUERY_GUIINSTANCEQUERY -#define VCZH_PRESENTATION_REFLECTION_INSTANCEQUERY_GUIINSTANCEQUERY - - -namespace vl -{ - namespace presentation - { - extern void ExecuteQuery(Ptr query, Ptr context, collections::List>& input, collections::List>& output); - extern void ExecuteQuery(Ptr query, Ptr context, collections::List>& output); - extern void ApplyStyle(Ptr style, Ptr ctor); - extern void GuiIqPrint(Ptr query, stream::StreamWriter& writer); - } -} - -#endif - -/*********************************************************************** -.\GUIINSTANCESHAREDSCRIPT.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI Reflection: Shared Script - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_REFLECTION_GUIINSTANCESHAREDSCRIPT -#define VCZH_PRESENTATION_REFLECTION_GUIINSTANCESHAREDSCRIPT - - -namespace vl -{ - namespace presentation - { - class GuiInstanceSharedScript :public Object, public Description - { - public: - WString language; - WString code; - GuiResourceTextPos codePosition; - - static Ptr LoadFromXml(Ptr resource, Ptr xml, GuiResourceError::List& errors); - Ptr SaveToXml(); - }; - } -} - -#endif - -/*********************************************************************** -.\GUIINSTANCELOCALIZEDSTRINGS.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI Reflection: Shared Script - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_REFLECTION_GUIINSTANCELOCALIZEDSTRINGS -#define VCZH_PRESENTATION_REFLECTION_GUIINSTANCELOCALIZEDSTRINGS - - -namespace vl -{ - namespace presentation - { - class GuiInstanceLocalizedStrings : public Object, public Description - { - public: - struct StringItem - { - public: - WString name; - WString text; - GuiResourceTextPos textPosition; - }; - - struct Strings - { - using StringItemMap = collections::Dictionary>; - - collections::List locales; - StringItemMap items; - GuiResourceTextPos tagPosition; - - WString GetLocalesName(); - }; - - WString className; - WString defaultLocale; - collections::List> strings; - GuiResourceTextPos tagPosition; - - using ParameterPair = collections::Pair, WString>; - using ParameterList = collections::List; - using PositionList = collections::List; - using TextList = collections::List; - - struct TextDesc - { - ParameterList parameters; - PositionList positions; - TextList texts; - }; - - using TextDescMap = collections::Dictionary, WString>, Ptr>; - - static Ptr LoadFromXml(Ptr resource, Ptr xml, GuiResourceError::List& errors); - Ptr SaveToXml(); - - Ptr GetDefaultStrings(); - WString GetInterfaceTypeName(bool hasNamespace); - - Ptr ParseLocalizedText(const WString& text, GuiResourceTextPos pos, GuiResourceError::List& errors); - void Validate(TextDescMap& textDescs, GuiResourcePrecompileContext& precompileContext, GuiResourceError::List& errors); - Ptr GenerateFunction(Ptr textDesc, const WString& functionName, workflow::WfClassMemberKind classMemberKind); - Ptr GenerateStrings(TextDescMap& textDescs, Ptr ls); - Ptr Compile(GuiResourcePrecompileContext& precompileContext, const WString& moduleName, GuiResourceError::List& errors); - }; - } -} - -#endif - /*********************************************************************** .\INSTANCELOADERS\GUIINSTANCELOADER_TEMPLATECONTROL.H ***********************************************************************/ diff --git a/Import/GacUIReflection.cpp b/Import/GacUIReflection.cpp index 5833ab26..62d9a54d 100644 --- a/Import/GacUIReflection.cpp +++ b/Import/GacUIReflection.cpp @@ -116,37 +116,37 @@ Compiled Workflow Type Resolver (Workflow) return this; } - void SerializePrecompiled(Ptr resource, Ptr content, stream::IStream& stream)override + void SerializePrecompiled(Ptr resource, Ptr content, stream::IStream& resourceStream)override { if (auto obj = content.Cast()) { - internal::ContextFreeWriter writer(stream); + internal::ContextFreeWriter writer(resourceStream); vint type = (vint)obj->type; writer << type; if (obj->type == GuiInstanceCompiledWorkflow::InstanceClass) { - MemoryStream memoryStream; + stream::MemoryStream memoryStream; obj->assembly->Serialize(memoryStream); - writer << (IStream&)memoryStream; + writer << (stream::IStream&)memoryStream; } } } - Ptr ResolveResourcePrecompiled(Ptr resource, stream::IStream& stream, GuiResourceError::List& errors)override + Ptr ResolveResourcePrecompiled(Ptr resource, stream::IStream& resourceStream, GuiResourceError::List& errors)override { - internal::ContextFreeReader reader(stream); + internal::ContextFreeReader reader(resourceStream); vint type; reader << type; - + auto obj = MakePtr(); obj->type = (GuiInstanceCompiledWorkflow::AssemblyType)type; if (obj->type == GuiInstanceCompiledWorkflow::InstanceClass) { - auto memoryStream = MakePtr(); - reader << (IStream&)*memoryStream.Obj(); + auto memoryStream = MakePtr(); + reader << (stream::IStream&)*memoryStream.Obj(); obj->binaryToLoad = memoryStream; } return obj; diff --git a/Import/GacUIWindows.cpp b/Import/GacUIWindows.cpp index d0228eb5..97ec9f75 100644 --- a/Import/GacUIWindows.cpp +++ b/Import/GacUIWindows.cpp @@ -13767,7 +13767,7 @@ WindowsImageFrame return frameBitmap.Obj(); } - void WindowsImageFrame::SaveBitmapToStream(stream::IStream& stream) + void WindowsImageFrame::SaveBitmapToStream(stream::IStream& imageStream) { UINT width = 0; UINT height = 0; @@ -13781,7 +13781,7 @@ WindowsImageFrame rect.Height = (INT)height; frameBitmap->CopyPixels(&rect, (UINT)bitmap->GetLineBytes(), (UINT)(bitmap->GetLineBytes()*height), (BYTE*)bitmap->GetScanLines()[0]); - bitmap->SaveToStream(stream, false); + bitmap->SaveToStream(imageStream, false); } /*********************************************************************** @@ -13944,7 +13944,7 @@ WindowsImage } } - void MoveIStreamToStream(IStream* pIStream, stream::IStream& stream) + void MoveIStreamToStream(IStream* pIStream, stream::IStream& outputStream) { LARGE_INTEGER dlibMove; dlibMove.QuadPart = 0; @@ -13957,7 +13957,7 @@ WindowsImage hr = pIStream->Read(&buffer[0], count, &read); if (read > 0) { - stream.Write(&buffer[0], (vint)read); + outputStream.Write(&buffer[0], (vint)read); } if (read != count) { @@ -13966,7 +13966,7 @@ WindowsImage } } - void WindowsImage::SaveToStream(stream::IStream& stream, FormatType formatType) + void WindowsImage::SaveToStream(stream::IStream& imageStream, FormatType formatType) { auto factory = GetWICImagingFactory(); GUID formatGUID; @@ -14084,7 +14084,7 @@ WindowsImage hr = bitmapEncoder->Commit(); bitmapEncoder->Release(); - MoveIStreamToStream(pIStream, stream); + MoveIStreamToStream(pIStream, imageStream); pIStream->Release(); } FAILED:; @@ -14125,7 +14125,7 @@ WindowsBitmapImage return index==0?frame.Obj():0; } - void WindowsBitmapImage::SaveToStream(stream::IStream& stream, FormatType formatType) + void WindowsBitmapImage::SaveToStream(stream::IStream& imageStream, FormatType formatType) { auto factory = GetWICImagingFactory(); if (formatType == INativeImage::Unknown) @@ -14169,7 +14169,7 @@ WindowsBitmapImage hr = bitmapEncoder->Commit(); bitmapEncoder->Release(); - MoveIStreamToStream(pIStream, stream); + MoveIStreamToStream(pIStream, imageStream); pIStream->Release(); } FAILED:; @@ -14239,15 +14239,15 @@ WindowsImageService return result; } - Ptr WindowsImageService::CreateImageFromStream(stream::IStream& stream) + Ptr WindowsImageService::CreateImageFromStream(stream::IStream& imageStream) { stream::MemoryStream memoryStream; char buffer[65536]; - while(true) + while (true) { - vint length=stream.Read(buffer, sizeof(buffer)); + vint length = imageStream.Read(buffer, sizeof(buffer)); memoryStream.Write(buffer, length); - if(length!=sizeof(buffer)) + if (length != sizeof(buffer)) { break; } diff --git a/Import/GacUIWindows.h b/Import/GacUIWindows.h index d6233d16..2a568233 100644 --- a/Import/GacUIWindows.h +++ b/Import/GacUIWindows.h @@ -10,6 +10,38 @@ DEVELOPER: Zihan Chen(vczh) #include "Vlpp.h" #include "VlppRegex.h" +/*********************************************************************** +.\GRAPHICSELEMENT\WINDOWSDIRECT2D\GUIGRAPHICSLAYOUTPROVIDERWINDOWSDIRECT2D.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI::Native Window::Direct2D Provider for Windows Implementation::Renderer + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_ELEMENTS_GUIGRAPHICSLAYOUTPROVIDERWINDOWSDIRECT2D +#define VCZH_PRESENTATION_ELEMENTS_GUIGRAPHICSLAYOUTPROVIDERWINDOWSDIRECT2D + + +namespace vl +{ + namespace presentation + { + namespace elements_windows_d2d + { + class WindowsDirect2DLayoutProvider : public Object, public elements::IGuiGraphicsLayoutProvider + { + public: + Ptr CreateParagraph(const WString& text, elements::IGuiGraphicsRenderTarget* renderTarget, elements::IGuiGraphicsParagraphCallback* callback)override; + }; + } + } +} + +#endif + /*********************************************************************** .\GRAPHICSELEMENT\WINDOWSDIRECT2D\GUIGRAPHICSWINDOWSDIRECT2D.H ***********************************************************************/ @@ -160,38 +192,6 @@ extern void RendererMainDirect2D(); #endif -/*********************************************************************** -.\GRAPHICSELEMENT\WINDOWSDIRECT2D\GUIGRAPHICSLAYOUTPROVIDERWINDOWSDIRECT2D.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI::Native Window::Direct2D Provider for Windows Implementation::Renderer - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_ELEMENTS_GUIGRAPHICSLAYOUTPROVIDERWINDOWSDIRECT2D -#define VCZH_PRESENTATION_ELEMENTS_GUIGRAPHICSLAYOUTPROVIDERWINDOWSDIRECT2D - - -namespace vl -{ - namespace presentation - { - namespace elements_windows_d2d - { - class WindowsDirect2DLayoutProvider : public Object, public elements::IGuiGraphicsLayoutProvider - { - public: - Ptr CreateParagraph(const WString& text, elements::IGuiGraphicsRenderTarget* renderTarget, elements::IGuiGraphicsParagraphCallback* callback)override; - }; - } - } -} - -#endif - /*********************************************************************** .\GRAPHICSELEMENT\WINDOWSDIRECT2D\GUIGRAPHICSRENDERERSWINDOWSDIRECT2D.H ***********************************************************************/ @@ -675,6 +675,7 @@ Images class WinControlDC; class WinProxyDC; class WinImageDC; + class WinMetaFile; class WinMetaFileBuilder : public Object { @@ -1051,7 +1052,7 @@ Raw API Rendering Element public: /// The element that raised this event. GuiGDIElement* element; - /// The device context to draw. The HDC handle can be retrived using dc->GetHandle(), but it is recommended that using the WinDC class directly. + /// The device context to draw. The HDC handle can be retrived using dc->GetHandle(), but it is recommended that using the WinDC class directly. windows::WinDC* dc; /// The range for rendering. Rect bounds; @@ -1746,6 +1747,255 @@ UniscribeParagraph #endif +/*********************************************************************** +.\NATIVEWINDOW\WINDOWS\SERVICESIMPL\WINDOWSASYNCSERVICE.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI::Native Window::Windows Implementation + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_WINDOWS_SERVICESIMPL_WINDOWSASYNCSERVICE +#define VCZH_PRESENTATION_WINDOWS_SERVICESIMPL_WINDOWSASYNCSERVICE + + +namespace vl +{ + namespace presentation + { + namespace windows + { + class WindowsAsyncService : public INativeAsyncService + { + protected: + struct TaskItem + { + Semaphore* semaphore; + Func proc; + + TaskItem(); + TaskItem(Semaphore* _semaphore, const Func& _proc); + ~TaskItem(); + }; + + class DelayItem : public Object, public INativeDelay + { + public: + DelayItem(WindowsAsyncService* _service, const Func& _proc, bool _executeInMainThread, vint milliseconds); + ~DelayItem(); + + WindowsAsyncService* service; + Func proc; + ExecuteStatus status; + DateTime executeTime; + bool executeInMainThread; + + ExecuteStatus GetStatus()override; + bool Delay(vint milliseconds)override; + bool Cancel()override; + }; + protected: + vint mainThreadId; + SpinLock taskListLock; + collections::List taskItems; + collections::List> delayItems; + public: + WindowsAsyncService(); + ~WindowsAsyncService(); + + void ExecuteAsyncTasks(); + bool IsInMainThread(INativeWindow* window)override; + void InvokeAsync(const Func& proc)override; + void InvokeInMainThread(INativeWindow* window, const Func& proc)override; + bool InvokeInMainThreadAndWait(INativeWindow* window, const Func& proc, vint milliseconds)override; + Ptr DelayExecute(const Func& proc, vint milliseconds)override; + Ptr DelayExecuteInMainThread(const Func& proc, vint milliseconds)override; + }; + } + } +} + +#endif + +/*********************************************************************** +.\NATIVEWINDOW\WINDOWS\SERVICESIMPL\WINDOWSCALLBACKSERVICE.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI::Native Window::Windows Implementation + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_WINDOWS_SERVICESIMPL_WINDOWSCALLBACKSERVICE +#define VCZH_PRESENTATION_WINDOWS_SERVICESIMPL_WINDOWSCALLBACKSERVICE + + +namespace vl +{ + namespace presentation + { + namespace windows + { + class WindowsCallbackService : public Object, public INativeCallbackService + { + protected: + collections::List listeners; + + public: + WindowsCallbackService(); + + bool InstallListener(INativeControllerListener* listener)override; + bool UninstallListener(INativeControllerListener* listener)override; + + void InvokeMouseHook(WPARAM message, NativePoint location); + void InvokeGlobalTimer(); + void InvokeClipboardUpdated(); + void InvokeNativeWindowCreated(INativeWindow* window); + void InvokeNativeWindowDestroyed(INativeWindow* window); + }; + } + } +} + +#endif + +/*********************************************************************** +.\NATIVEWINDOW\WINDOWS\SERVICESIMPL\WINDOWSCLIPBOARDSERVICE.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI::Native Window::Windows Implementation + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_WINDOWS_SERVICESIMPL_WINDOWSCLIPBOARDSERVICE +#define VCZH_PRESENTATION_WINDOWS_SERVICESIMPL_WINDOWSCLIPBOARDSERVICE + + +namespace vl +{ + namespace presentation + { + namespace windows + { + class WindowsClipboardService; + + class WindowsClipboardReader : public Object, public INativeClipboardReader + { + friend class WindowsClipboardService; + protected: + WindowsClipboardService* service; + bool ContainsFormat(UINT format); + + public: + WindowsClipboardReader(WindowsClipboardService* _service); + ~WindowsClipboardReader(); + + bool ContainsText()override; + WString GetText()override; + + bool ContainsDocument()override; + Ptr GetDocument()override; + + bool ContainsImage()override; + Ptr GetImage()override; + + void CloseClipboard(); + }; + + class WindowsClipboardWriter : public Object, public INativeClipboardWriter + { + friend class WindowsClipboardService; + protected: + WindowsClipboardService* service; + Nullable textData; + Ptr documentData; + Ptr imageData; + + void SetClipboardData(UINT format, stream::MemoryStream& memoryStream); + public: + WindowsClipboardWriter(WindowsClipboardService* _service); + ~WindowsClipboardWriter(); + + void SetText(const WString& value)override; + void SetDocument(Ptr value)override; + void SetImage(Ptr value)override; + bool Submit()override; + }; + + class WindowsClipboardService : public Object, public INativeClipboardService + { + friend class WindowsClipboardReader; + friend class WindowsClipboardWriter; + protected: + HWND ownerHandle; + UINT WCF_Document; + UINT WCF_RTF; + UINT WCF_HTML; + WindowsClipboardReader* reader = nullptr; + + public: + WindowsClipboardService(); + + Ptr ReadClipboard()override; + Ptr WriteClipboard()override; + + void SetOwnerHandle(HWND handle); + }; + } + } +} + +#endif + +/*********************************************************************** +.\NATIVEWINDOW\WINDOWS\SERVICESIMPL\WINDOWSDIALOGSERVICE.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI::Native Window::Windows Implementation + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_WINDOWS_SERVICESIMPL_WINDOWSDIALOGSERVICE +#define VCZH_PRESENTATION_WINDOWS_SERVICESIMPL_WINDOWSDIALOGSERVICE + + +namespace vl +{ + namespace presentation + { + namespace windows + { + class WindowsDialogService : public INativeDialogService + { + typedef HWND (*HandleRetriver)(INativeWindow*); + protected: + HandleRetriver handleRetriver; + + public: + WindowsDialogService(HandleRetriver _handleRetriver); + + MessageBoxButtonsOutput ShowMessageBox(INativeWindow* window, const WString& text, const WString& title, MessageBoxButtonsInput buttons, MessageBoxDefaultButton defaultButton, MessageBoxIcons icon, MessageBoxModalOptions modal)override; + bool ShowColorDialog(INativeWindow* window, Color& selection, bool selected, ColorDialogCustomColorOptions customColorOptions, Color* customColors)override; + bool ShowFontDialog(INativeWindow* window, FontProperties& selectionFont, Color& selectionColor, bool selected, bool showEffect, bool forceFontExist)override; + bool ShowFileDialog(INativeWindow* window, collections::List& selectionFileNames, vint& selectionFilterIndex, FileDialogTypes dialogType, const WString& title, const WString& initialFileName, const WString& initialDirectory, const WString& defaultExtension, const WString& filter, FileDialogOptions options)override; + }; + } + } +} + +#endif + /*********************************************************************** .\NATIVEWINDOW\WINDOWS\SERVICESIMPL\WINDOWSIMAGESERVICE.H ***********************************************************************/ @@ -1786,7 +2036,7 @@ namespace vl Ptr GetCache(void* key)override; Ptr RemoveCache(void* key)override; IWICBitmap* GetFrameBitmap(); - void SaveBitmapToStream(stream::IStream& stream); + void SaveBitmapToStream(stream::IStream& imageStream); }; class WindowsImage : public Object, public INativeImage @@ -1803,7 +2053,7 @@ namespace vl FormatType GetFormat()override; vint GetFrameCount()override; INativeImageFrame* GetFrame(vint index)override; - void SaveToStream(stream::IStream& stream, FormatType formatType)override; + void SaveToStream(stream::IStream& imageStream, FormatType formatType)override; }; class WindowsBitmapImage : public Object, public INativeImage @@ -1820,7 +2070,7 @@ namespace vl FormatType GetFormat()override; vint GetFrameCount()override; INativeImageFrame* GetFrame(vint index)override; - void SaveToStream(stream::IStream& stream, FormatType formatType)override; + void SaveToStream(stream::IStream& imageStream, FormatType formatType)override; }; class WindowsImageService : public Object, public INativeImageService @@ -1833,7 +2083,7 @@ namespace vl Ptr CreateImageFromFile(const WString& path); Ptr CreateImageFromMemory(void* buffer, vint length); - Ptr CreateImageFromStream(stream::IStream& stream); + Ptr CreateImageFromStream(stream::IStream& imageStream); Ptr CreateImageFromHBITMAP(HBITMAP handle); Ptr CreateImageFromHICON(HICON handle); IWICImagingFactory* GetImagingFactory(); @@ -1936,6 +2186,94 @@ extern int WinMainDirect2D(HINSTANCE hInstance, void(*RendererMain)()); #endif +/*********************************************************************** +.\NATIVEWINDOW\WINDOWS\GDI\WINGDIAPPLICATION.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI::Native Window::GDI Provider for Windows Implementation + +Interfaces: +***********************************************************************/ +#ifndef VCZH_PRESENTATION_WINDOWS_GDI_WINGDIAPPLICATION +#define VCZH_PRESENTATION_WINDOWS_GDI_WINGDIAPPLICATION + + +namespace vl +{ + namespace presentation + { + namespace windows + { + extern WinDC* GetNativeWindowDC(INativeWindow* window); + extern HDC GetNativeWindowHDC(INativeWindow* window); + } + } +} + +extern int WinMainGDI(HINSTANCE hInstance, void(*RendererMain)()); + +#endif + +/*********************************************************************** +.\NATIVEWINDOW\WINDOWS\SERVICESIMPL\WINDOWSINPUTSERVICE.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +GacUI::Native Window::Windows Implementation + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_PRESENTATION_WINDOWS_SERVICESIMPL_WINDOWSINPUTSERVICE +#define VCZH_PRESENTATION_WINDOWS_SERVICESIMPL_WINDOWSINPUTSERVICE + + +namespace vl +{ + namespace presentation + { + namespace windows + { + class WindowsInputService : public Object, public INativeInputService + { + protected: + HWND ownerHandle; + HHOOK mouseHook; + bool isTimerEnabled; + HOOKPROC mouseProc; + + collections::Array keyNames; + collections::Dictionary keys; + + WString GetKeyNameInternal(VKEY code); + void InitializeKeyNames(); + public: + WindowsInputService(HOOKPROC _mouseProc); + + void SetOwnerHandle(HWND handle); + void StartHookMouse()override; + void StopHookMouse()override; + bool IsHookingMouse()override; + void StartTimer()override; + void StopTimer()override; + bool IsTimerEnabled()override; + bool IsKeyPressing(VKEY code)override; + bool IsKeyToggled(VKEY code)override; + WString GetKeyName(VKEY code)override; + VKEY GetKey(const WString& name)override; + }; + + extern bool WinIsKeyPressing(VKEY code); + extern bool WinIsKeyToggled(VKEY code); + } + } +} + +#endif + /*********************************************************************** .\NATIVEWINDOW\WINDOWS\SERVICESIMPL\WINDOWSRESOURCESERVICE.H ***********************************************************************/ @@ -1991,170 +2329,6 @@ namespace vl #endif -/*********************************************************************** -.\NATIVEWINDOW\WINDOWS\SERVICESIMPL\WINDOWSCLIPBOARDSERVICE.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI::Native Window::Windows Implementation - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_WINDOWS_SERVICESIMPL_WINDOWSCLIPBOARDSERVICE -#define VCZH_PRESENTATION_WINDOWS_SERVICESIMPL_WINDOWSCLIPBOARDSERVICE - - -namespace vl -{ - namespace presentation - { - namespace windows - { - class WindowsClipboardService; - - class WindowsClipboardReader : public Object, public INativeClipboardReader - { - friend class WindowsClipboardService; - protected: - WindowsClipboardService* service; - bool ContainsFormat(UINT format); - - public: - WindowsClipboardReader(WindowsClipboardService* _service); - ~WindowsClipboardReader(); - - bool ContainsText()override; - WString GetText()override; - - bool ContainsDocument()override; - Ptr GetDocument()override; - - bool ContainsImage()override; - Ptr GetImage()override; - - void CloseClipboard(); - }; - - class WindowsClipboardWriter : public Object, public INativeClipboardWriter - { - friend class WindowsClipboardService; - protected: - WindowsClipboardService* service; - Nullable textData; - Ptr documentData; - Ptr imageData; - - void SetClipboardData(UINT format, stream::MemoryStream& memoryStream); - public: - WindowsClipboardWriter(WindowsClipboardService* _service); - ~WindowsClipboardWriter(); - - void SetText(const WString& value)override; - void SetDocument(Ptr value)override; - void SetImage(Ptr value)override; - bool Submit()override; - }; - - class WindowsClipboardService : public Object, public INativeClipboardService - { - friend class WindowsClipboardReader; - friend class WindowsClipboardWriter; - protected: - HWND ownerHandle; - UINT WCF_Document; - UINT WCF_RTF; - UINT WCF_HTML; - WindowsClipboardReader* reader = nullptr; - - public: - WindowsClipboardService(); - - Ptr ReadClipboard()override; - Ptr WriteClipboard()override; - - void SetOwnerHandle(HWND handle); - }; - } - } -} - -#endif - -/*********************************************************************** -.\NATIVEWINDOW\WINDOWS\SERVICESIMPL\WINDOWSASYNCSERVICE.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI::Native Window::Windows Implementation - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_WINDOWS_SERVICESIMPL_WINDOWSASYNCSERVICE -#define VCZH_PRESENTATION_WINDOWS_SERVICESIMPL_WINDOWSASYNCSERVICE - - -namespace vl -{ - namespace presentation - { - namespace windows - { - class WindowsAsyncService : public INativeAsyncService - { - protected: - struct TaskItem - { - Semaphore* semaphore; - Func proc; - - TaskItem(); - TaskItem(Semaphore* _semaphore, const Func& _proc); - ~TaskItem(); - }; - - class DelayItem : public Object, public INativeDelay - { - public: - DelayItem(WindowsAsyncService* _service, const Func& _proc, bool _executeInMainThread, vint milliseconds); - ~DelayItem(); - - WindowsAsyncService* service; - Func proc; - ExecuteStatus status; - DateTime executeTime; - bool executeInMainThread; - - ExecuteStatus GetStatus()override; - bool Delay(vint milliseconds)override; - bool Cancel()override; - }; - protected: - vint mainThreadId; - SpinLock taskListLock; - collections::List taskItems; - collections::List> delayItems; - public: - WindowsAsyncService(); - ~WindowsAsyncService(); - - void ExecuteAsyncTasks(); - bool IsInMainThread(INativeWindow* window)override; - void InvokeAsync(const Func& proc)override; - void InvokeInMainThread(INativeWindow* window, const Func& proc)override; - bool InvokeInMainThreadAndWait(INativeWindow* window, const Func& proc, vint milliseconds)override; - Ptr DelayExecute(const Func& proc, vint milliseconds)override; - Ptr DelayExecuteInMainThread(const Func& proc, vint milliseconds)override; - }; - } - } -} - -#endif - /*********************************************************************** .\NATIVEWINDOW\WINDOWS\SERVICESIMPL\WINDOWSSCREENSERVICE.H ***********************************************************************/ @@ -2221,176 +2395,3 @@ namespace vl } #endif - -/*********************************************************************** -.\NATIVEWINDOW\WINDOWS\SERVICESIMPL\WINDOWSCALLBACKSERVICE.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI::Native Window::Windows Implementation - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_WINDOWS_SERVICESIMPL_WINDOWSCALLBACKSERVICE -#define VCZH_PRESENTATION_WINDOWS_SERVICESIMPL_WINDOWSCALLBACKSERVICE - - -namespace vl -{ - namespace presentation - { - namespace windows - { - class WindowsCallbackService : public Object, public INativeCallbackService - { - protected: - collections::List listeners; - - public: - WindowsCallbackService(); - - bool InstallListener(INativeControllerListener* listener)override; - bool UninstallListener(INativeControllerListener* listener)override; - - void InvokeMouseHook(WPARAM message, NativePoint location); - void InvokeGlobalTimer(); - void InvokeClipboardUpdated(); - void InvokeNativeWindowCreated(INativeWindow* window); - void InvokeNativeWindowDestroyed(INativeWindow* window); - }; - } - } -} - -#endif - -/*********************************************************************** -.\NATIVEWINDOW\WINDOWS\SERVICESIMPL\WINDOWSINPUTSERVICE.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI::Native Window::Windows Implementation - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_WINDOWS_SERVICESIMPL_WINDOWSINPUTSERVICE -#define VCZH_PRESENTATION_WINDOWS_SERVICESIMPL_WINDOWSINPUTSERVICE - - -namespace vl -{ - namespace presentation - { - namespace windows - { - class WindowsInputService : public Object, public INativeInputService - { - protected: - HWND ownerHandle; - HHOOK mouseHook; - bool isTimerEnabled; - HOOKPROC mouseProc; - - collections::Array keyNames; - collections::Dictionary keys; - - WString GetKeyNameInternal(VKEY code); - void InitializeKeyNames(); - public: - WindowsInputService(HOOKPROC _mouseProc); - - void SetOwnerHandle(HWND handle); - void StartHookMouse()override; - void StopHookMouse()override; - bool IsHookingMouse()override; - void StartTimer()override; - void StopTimer()override; - bool IsTimerEnabled()override; - bool IsKeyPressing(VKEY code)override; - bool IsKeyToggled(VKEY code)override; - WString GetKeyName(VKEY code)override; - VKEY GetKey(const WString& name)override; - }; - - extern bool WinIsKeyPressing(VKEY code); - extern bool WinIsKeyToggled(VKEY code); - } - } -} - -#endif - -/*********************************************************************** -.\NATIVEWINDOW\WINDOWS\SERVICESIMPL\WINDOWSDIALOGSERVICE.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI::Native Window::Windows Implementation - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_PRESENTATION_WINDOWS_SERVICESIMPL_WINDOWSDIALOGSERVICE -#define VCZH_PRESENTATION_WINDOWS_SERVICESIMPL_WINDOWSDIALOGSERVICE - - -namespace vl -{ - namespace presentation - { - namespace windows - { - class WindowsDialogService : public INativeDialogService - { - typedef HWND (*HandleRetriver)(INativeWindow*); - protected: - HandleRetriver handleRetriver; - - public: - WindowsDialogService(HandleRetriver _handleRetriver); - - MessageBoxButtonsOutput ShowMessageBox(INativeWindow* window, const WString& text, const WString& title, MessageBoxButtonsInput buttons, MessageBoxDefaultButton defaultButton, MessageBoxIcons icon, MessageBoxModalOptions modal)override; - bool ShowColorDialog(INativeWindow* window, Color& selection, bool selected, ColorDialogCustomColorOptions customColorOptions, Color* customColors)override; - bool ShowFontDialog(INativeWindow* window, FontProperties& selectionFont, Color& selectionColor, bool selected, bool showEffect, bool forceFontExist)override; - bool ShowFileDialog(INativeWindow* window, collections::List& selectionFileNames, vint& selectionFilterIndex, FileDialogTypes dialogType, const WString& title, const WString& initialFileName, const WString& initialDirectory, const WString& defaultExtension, const WString& filter, FileDialogOptions options)override; - }; - } - } -} - -#endif - -/*********************************************************************** -.\NATIVEWINDOW\WINDOWS\GDI\WINGDIAPPLICATION.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -GacUI::Native Window::GDI Provider for Windows Implementation - -Interfaces: -***********************************************************************/ -#ifndef VCZH_PRESENTATION_WINDOWS_GDI_WINGDIAPPLICATION -#define VCZH_PRESENTATION_WINDOWS_GDI_WINGDIAPPLICATION - - -namespace vl -{ - namespace presentation - { - namespace windows - { - extern WinDC* GetNativeWindowDC(INativeWindow* window); - extern HDC GetNativeWindowHDC(INativeWindow* window); - } - } -} - -extern int WinMainGDI(HINSTANCE hInstance, void(*RendererMain)()); - -#endif diff --git a/Import/Vlpp.cpp b/Import/Vlpp.cpp index fe92a47a..4ac72070 100644 --- a/Import/Vlpp.cpp +++ b/Import/Vlpp.cpp @@ -7,6 +7,11 @@ DEVELOPER: Zihan Chen(vczh) /*********************************************************************** .\BASIC.CPP ***********************************************************************/ +/*********************************************************************** +Author: Zihan Chen (vczh) +Licensed under https://github.com/vczh-libraries/License +***********************************************************************/ + #include #if defined VCZH_MSVC #include @@ -109,6 +114,8 @@ DateTime dt.minute = timeinfo->tm_min; dt.second = timeinfo->tm_sec; dt.milliseconds = milliseconds; + + // in Linux and macOS, filetime will be mktime(t) * 1000 + gettimeofday().tv_usec / 1000 dt.filetime = (vuint64_t)timer * 1000 + milliseconds; dt.totalMilliseconds = (vuint64_t)timer * 1000 + milliseconds; return dt; @@ -274,6 +281,11 @@ Interface /*********************************************************************** .\CONSOLE.CPP ***********************************************************************/ +/*********************************************************************** +Author: Zihan Chen (vczh) +Licensed under https://github.com/vczh-libraries/License +***********************************************************************/ + #if defined VCZH_MSVC #elif defined VCZH_GCC #include @@ -394,6 +406,11 @@ Console /*********************************************************************** .\EXCEPTION.CPP ***********************************************************************/ +/*********************************************************************** +Author: Zihan Chen (vczh) +Licensed under https://github.com/vczh-libraries/License +***********************************************************************/ + namespace vl { @@ -457,6 +474,11 @@ ParsingException /*********************************************************************** .\GLOBALSTORAGE.CPP ***********************************************************************/ +/*********************************************************************** +Author: Zihan Chen (vczh) +Licensed under https://github.com/vczh-libraries/License +***********************************************************************/ + namespace vl { @@ -483,7 +505,6 @@ GlobalStorage ***********************************************************************/ GlobalStorage::GlobalStorage(const wchar_t* key) - :cleared(false) { InitializeGlobalStorage(); GetGlobalStorageManager().storages->Add(key, this); @@ -514,21 +535,21 @@ Helper Functions void InitializeGlobalStorage() { - if(!GetGlobalStorageManager().storages) + if (!GetGlobalStorageManager().storages) { - GetGlobalStorageManager().storages=new Dictionary; + GetGlobalStorageManager().storages = new Dictionary; } } void FinalizeGlobalStorage() { - if(GetGlobalStorageManager().storages) + if (GetGlobalStorageManager().storages) { - for(vint i=0;iCount();i++) + for (vint i = 0; i < GetGlobalStorageManager().storages->Count(); i++) { GetGlobalStorageManager().storages->Values().Get(i)->ClearResource(); } - GetGlobalStorageManager().storages=0; + GetGlobalStorageManager().storages = nullptr; } } } @@ -537,6 +558,11 @@ Helper Functions /*********************************************************************** .\STRING.CPP ***********************************************************************/ +/*********************************************************************** +Author: Zihan Chen (vczh) +Licensed under https://github.com/vczh-libraries/License +***********************************************************************/ + #if defined VCZH_MSVC #elif defined VCZH_GCC #include @@ -1082,6 +1108,11 @@ namespace vl /*********************************************************************** .\COLLECTIONS\PARTIALORDERING.CPP ***********************************************************************/ +/*********************************************************************** +Author: Zihan Chen (vczh) +Licensed under https://github.com/vczh-libraries/License +***********************************************************************/ + namespace vl { @@ -1189,6 +1220,11 @@ PartialOrderingProcessor /*********************************************************************** .\UNITTEST\UNITTEST.CPP ***********************************************************************/ +/*********************************************************************** +Author: Zihan Chen (vczh) +Licensed under https://github.com/vczh-libraries/License +***********************************************************************/ + #ifdef VCZH_MSVC #endif @@ -1219,7 +1255,7 @@ UnitTest Category, Case, }; - + struct UnitTestContext { UnitTestContext* parent = nullptr; diff --git a/Import/Vlpp.h b/Import/Vlpp.h index ade8edd5..7c3e31a7 100644 --- a/Import/Vlpp.h +++ b/Import/Vlpp.h @@ -7,19 +7,8 @@ DEVELOPER: Zihan Chen(vczh) .\BASIC.H ***********************************************************************/ /*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -Framework::Basic - -Classes: - NotCopyable : Object inherits from this type cannot be copied - Error : Error, unlike exception, is not encouraged to catch - Object : Base class of all classes - -Macros: - CHECK_ERROR(CONDITION,DESCRIPTION) : Assert, throws an Error if failed - CHECK_FAIL(DESCRIPTION) : Force an assert failure - SCOPE_VARIABLE(TYPE,VARIABLE,VALUE){ ... } : Scoped variable +Author: Zihan Chen (vczh) +Licensed under https://github.com/vczh-libraries/License ***********************************************************************/ #ifndef VCZH_BASIC @@ -117,18 +106,18 @@ namespace vl #endif #ifdef VCZH_64 - /// Signed interface whose size is equal to sizeof(void*). + /// Signed interface whose size equals to sizeof(void*). typedef vint64_t vint; - /// Signed interface whose size is equal to sizeof(void*). + /// Signed interface whose size equals to sizeof(void*). typedef vint64_t vsint; - /// Unsigned interface whose size is equal to sizeof(void*). + /// Unsigned interface whose size equals to sizeof(void*). typedef vuint64_t vuint; #else - /// Signed interface whose size is equal to sizeof(void*). + /// Signed interface whose size equals to sizeof(void*). typedef vint32_t vint; - /// Signed interface whose size is equal to sizeof(void*). + /// Signed interface whose size equals to sizeof(void*). typedef vint32_t vsint; - /// Unsigned interface whose size is equal to sizeof(void*). + /// Unsigned interface whose size equals to sizeof(void*). typedef vuint32_t vuint; #endif /// Signed interger representing position. @@ -172,6 +161,7 @@ namespace vl Basic Types ***********************************************************************/ + /// Base type for all classes to stop generating default copy constructors. class NotCopyable { private: @@ -181,7 +171,7 @@ namespace vl NotCopyable(); }; - /// Base type of all errors. An error is an exception that you are not allowed to catch. Raising it means there is a fatal error in the code. + /// Base type of all errors. An error is an exception that is not recommended to catch. Raising it means there is a mistake in the code. class Error { private: @@ -307,210 +297,202 @@ namespace vl Basic Types ***********************************************************************/ - /// Base type of all classes. + /// + /// Base type of all classes. + /// This type has a virtual destructor, making all derived classes destructors virtual. + /// In this way an object is allowed to be deleted using a pointer of a qualified base type pointing to this object. + /// class Object { public: virtual ~Object(); }; - /// Type for storing a value to wherever requiring a [T:vl.Ptr`1] to [T:vl.Object]. - /// Type of the value. + /// Store data of a value type in a reference type object. It is useful when the data is required to be stored in a pointer to [T:vl.Object]. + /// boxed = MakePtr>(100); + /// vint unboxed = boxed.Cast>().UnBox(); + /// Console::WriteLine(itow(unboxed)); + /// } + /// ]]> + /// Value type to use. template class ObjectBox : public Object { private: T object; public: - /// Box a value. - /// The value to box. + /// Create a boxed reference object from data of a value type. + /// The data to box. ObjectBox(const T& _object) :object(_object) { } - /// Box a movable value. - /// The value to box. + /// Create a boxed reference object by moving data of a value type. + /// The data to move and box. ObjectBox(T&& _object) :object(MoveValue(_object)) { } - /// Copy a box. - /// The box. - ObjectBox(const ObjectBox& value) - :object(value.object) - { - } + /// Copy a boxed reference object. + /// The reference object to copy. + ObjectBox(const ObjectBox& value) = default; - /// Move a box. - /// The box. - ObjectBox(ObjectBox&& value) - :object(MoveValue(value.object)) - { - } + /// Move a boxed reference object. + /// The reference object to move. + ObjectBox(ObjectBox&& value) = default; - /// Box a value. - /// The boxed value. - /// The value to box. + /// Replace the boxed data of a value type. + /// The reference object itself. + /// The data to replace the original data. ObjectBox& operator=(const T& _object) { object = _object; return *this; } - /// Copy a box. - /// The boxed value. - /// The box. - ObjectBox& operator=(const ObjectBox& value) - { - object = value.object; - return *this; - } + /// Replace the boxed data from another reference object. + /// The reference object itself. + /// The reference object to copy. + ObjectBox& operator=(const ObjectBox& value) = default; - /// Move a box. - /// The boxed value. - /// The box. - ObjectBox& operator=(ObjectBox&& value) - { - object = MoveValue(value.object); - return *this; - } + /// Replace the boxed data by moving from another reference object. + /// The reference object itself. + /// The reference object to move. + ObjectBox& operator=(ObjectBox&& value) = default; - /// Unbox the value. - /// The original value. + /// Get the boxed data of a value type. + /// The unboxed data of a value type. const T& Unbox() { return object; } }; - /// Type for optionally storing a value. - /// Type of the value. + /// Type for representing nullable data. + /// Type of the data, typically it is a value type, or [T:vl.Ptr`1] could be used here. template class Nullable { private: - T* object; + T* object = nullptr; public: /// Create a null value. - Nullable() - :object(0) - { - } + Nullable() = default; - /// Create a non-null value. - /// The value to copy. + /// Create a non-null value by copying data. + /// The data to copy. Nullable(const T& value) :object(new T(value)) { } - /// Create a non-null value. - /// The value to move. + /// Create a non-null value by moving data. + /// The data to move. Nullable(T&& value) :object(new T(MoveValue(value))) { } - /// Copy a nullable value. + /// Create a nullable value by copying from another nullable value. /// The nullable value to copy. Nullable(const Nullable& nullable) - :object(nullable.object ? new T(*nullable.object) : 0) + :object(nullable.object ? new T(*nullable.object) : nullptr) { } - /// Move a nullable value. + /// Create a nullable value by moving from another nullable value. /// The nullable value to move. Nullable(Nullable&& nullable) :object(nullable.object) { - nullable.object = 0; + nullable.object = nullptr; } ~Nullable() { - if (object) - { - delete object; - object = 0; - } + if (object) delete object; } - /// Create a non-null value. - /// The created nullable value. - /// The value to copy. + /// Replace the data inside this nullable value by copying from data. + /// The nullable value itself. + /// The data to copy. Nullable& operator=(const T& value) { - if (object) - { - delete object; - object = 0; - } + if (object) delete object; object = new T(value); return *this; } - /// Copy a nullable value. - /// The created nullable value. + /// Replace the data inside this nullable value by copying from another nullable value. + /// The nullable value itself. /// The nullable value to copy. Nullable& operator=(const Nullable& nullable) { if (this != &nullable) { - if (object) - { - delete object; - object = 0; - } + if (object) delete object; if (nullable.object) { object = new T(*nullable.object); } + else + { + object = nullptr; + } } return *this; } - /// Move a nullable value. - /// The created nullable value. + /// Replace the data inside this nullable value by moving from another nullable value. + /// The nullable value itself. /// The nullable value to move. Nullable& operator=(Nullable&& nullable) { if (this != &nullable) { - if (object) - { - delete object; - object = 0; - } + if (object) delete object; object = nullable.object; - nullable.object = 0; + nullable.object = nullptr; } return *this; } + /// Comparing two nullable values. + /// Returns true when these nullable values are all null, or the data inside them equals. + /// The first nullable value to compare. + /// The second nullable value to compare. static bool Equals(const Nullable& a, const Nullable& b) { - return - a.object - ? b.object - ? *a.object == *b.object - : false - : b.object - ? false - : true; + if (!a.object && !b.object) return true; + if (a.object && b.object) return *a.object == *b.object; + return false; } + /// Comparing two nullable values. + /// + /// Returns a positive value when the first value is greater than the second value. + /// Returns a negative value when the first value is lesser than the second value. + /// Returns zero when the two values equal. + /// When one is null and another one is not, the non-null one is greater. + /// + /// The first nullable value to compare. + /// The second nullable value to compare. static vint Compare(const Nullable& a, const Nullable& b) { - return - a.object - ? b.object - ? (*a.object == *b.object ? 0 : *a.object < *b.object ? -1 : 1) - : 1 - : b.object - ? -1 - : 0; + if (a.object && b.object) + { + if (*a.object > *b.object) return 1; + if (*a.object < *b.object) return -1; + return 0; + } + if (a.object) return 1; + if (b.object) return -1; + return 0; } bool operator==(const Nullable& nullable)const @@ -543,17 +525,18 @@ namespace vl return Compare(*this, nullable) >= 0; } - /// Convert the nullable value to a bool value. - /// Returns true if it is not null. + /// Test if this nullable value is non-null. + /// Returns true if it is non-null. operator bool()const { - return object != 0; + return object != nullptr; } - /// Unbox the value. This operation will cause an access violation of it is null. - /// The original value. + /// Return the data inside this nullable value + /// The data inside this nullable value. It crashes when it is null. const T& Value()const { + if (!object) throw Error(L"Nullable::Value()#Cannot unbox from null."); return *object; } }; @@ -569,18 +552,18 @@ namespace vl Type Traits ***********************************************************************/ - /// Get the index type of a value for containers. - /// Type of the value. + /// Type for specify and create a representative value for comparing another value of a specific type for containers. + /// The element type for containers. template struct KeyType { public: - /// The index type of a value for containers. + /// The type of the representative value. typedef T Type; - /// Convert a value to its index type. - /// The corresponding index value. - /// The value. + /// Convert a value in a container to its representative value. + /// The representative value. + /// The value in a container. static const T& GetKeyValue(const T& value) { return value; @@ -623,18 +606,39 @@ namespace vl /// A type representing the combination of date and time. struct DateTime { + /// The year. vint year; + /// The month, from 1 to 12. vint month; - vint dayOfWeek; + /// The day, from 1 to 31. vint day; + /// The hour, from 0 to 23. vint hour; + /// The minute, from 0 to 59. vint minute; + /// The second, from 0 to 60. vint second; + /// The milliseconds, from 0 to 999. vint milliseconds; + /// + /// The calculated total milliseconds. It is OS dependent because the start time is different. + /// It is from 0 to 6, representing Sunday to Saturday. + /// + vint dayOfWeek; + + /// + /// The calculated total milliseconds. It is OS dependent because the start time is different. + /// You should not rely on the fact about how this value is created. + /// The only invariant thing is that, when an date time is earlier than another, the totalMilliseconds is lesser. + /// vuint64_t totalMilliseconds; - // in gcc, this will be mktime(t) * 1000 + gettimeofday().tv_usec / 1000 + /// + /// The calculated file time for the date and time. It is OS dependent. + /// You should not rely on the fact about how this value is created. + /// The only invariant thing is that, when an date time is earlier than another, the filetime is lesser. + /// vuint64_t filetime; /// Get the current local time. @@ -656,9 +660,12 @@ namespace vl /// The millisecond. static DateTime FromDateTime(vint _year, vint _month, vint _day, vint _hour = 0, vint _minute = 0, vint _second = 0, vint _milliseconds = 0); + /// Create a date time value from a file time. + /// The created date time value. + /// The file time. static DateTime FromFileTime(vuint64_t filetime); - /// Create an empty date time value. + /// Create an empty date time value that is not meaningful. DateTime(); /// Convert the UTC time to the local time. @@ -798,706 +805,12 @@ namespace vl #endif -/*********************************************************************** -.\STRING.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -Data Structure::String - -Classes: - AString : Mbcs using the code page of the current locale - WString : UTF-16 (for Windows), or UTF-32 (for Linux and macOS) -***********************************************************************/ - -#ifndef VCZH_STRING -#define VCZH_STRING - -#include - -namespace vl -{ - /// A type representing a string. - /// Type of a character. - template - class ObjectString : public Object - { - private: - static const T zero; - - mutable T* buffer; - mutable volatile vint* counter; - mutable vint start; - mutable vint length; - mutable vint realLength; - - static vint CalculateLength(const T* buffer) - { - vint result=0; - while(*buffer++)result++; - return result; - } - - static vint Compare(const T* bufA, const ObjectString& strB) - { - const T* bufB=strB.buffer+strB.start; - const T* bufAOld=bufA; - vint length=strB.length; - while(length-- && *bufA) - { - vint diff=*bufA++-*bufB++; - if(diff!=0) - { - return diff; - } - }; - return CalculateLength(bufAOld)-strB.length; - } - - public: - - static vint Compare(const ObjectString& strA, const ObjectString& strB) - { - const T* bufA=strA.buffer+strA.start; - const T* bufB=strB.buffer+strB.start; - vint length=strA.length& string, vint _start, vint _length) - { - if(_length<=0) - { - buffer=(T*)&zero; - counter=0; - start=0; - length=0; - realLength=0; - } - else - { - buffer=string.buffer; - counter=string.counter; - start=string.start+_start; - length=_length; - realLength=string.realLength; - Inc(); - } - } - - ObjectString(const ObjectString& dest, const ObjectString& source, vint index, vint count) - { - if(index==0 && count==dest.length && source.length==0) - { - buffer=(T*)&zero; - counter=0; - start=0; - length=0; - realLength=0; - } - else - { - counter=new vint(1); - start=0; - length=dest.length-count+source.length; - realLength=length; - buffer=new T[length+1]; - memcpy(buffer, dest.buffer+dest.start, sizeof(T)*index); - memcpy(buffer+index, source.buffer+source.start, sizeof(T)*source.length); - memcpy(buffer+index+source.length, (dest.buffer+dest.start+index+count), sizeof(T)*(dest.length-index-count)); - buffer[length]=0; - } - } - public: - static ObjectString Empty; - - /// Create an empty string. - ObjectString() - { - buffer=(T*)&zero; - counter=0; - start=0; - length=0; - realLength=0; - } - - /// Create a string continaing one character. - /// The character. - ObjectString(const T& _char) - { - counter=new vint(1); - start=0; - length=1; - buffer=new T[2]; - buffer[0]=_char; - buffer[1]=0; - realLength=length; - } - - /// Copy a string. - /// Memory to copy. It does not have to contain the zero terminator. - /// Size of the content in characters. - ObjectString(const T* _buffer, vint _length) - { - if(_length<=0) - { - buffer=(T*)&zero; - counter=0; - start=0; - length=0; - realLength=0; - } - else - { - buffer=new T[_length+1]; - memcpy(buffer, _buffer, _length*sizeof(T)); - buffer[_length]=0; - counter=new vint(1); - start=0; - length=_length; - realLength=_length; - } - } - - /// Copy a string. - /// Memory to copy. It should have to contain the zero terminator. - /// Set to true to copy the memory. Set to false to use the memory directly. - ObjectString(const T* _buffer, bool copy = true) - { - CHECK_ERROR(_buffer!=0, L"ObjectString::ObjectString(const T*, bool)#Cannot construct a string from nullptr."); - if(copy) - { - counter=new vint(1); - start=0; - length=CalculateLength(_buffer); - buffer=new T[length+1]; - memcpy(buffer, _buffer, sizeof(T)*(length+1)); - realLength=length; - } - else - { - buffer=(T*)_buffer; - counter=0; - start=0; - length=CalculateLength(_buffer); - realLength=length; - } - } - - /// Copy a string. - /// The string to copy. - ObjectString(const ObjectString& string) - { - buffer=string.buffer; - counter=string.counter; - start=string.start; - length=string.length; - realLength=string.realLength; - Inc(); - } - - /// Move a string. - /// The string to move. - ObjectString(ObjectString&& string) - { - buffer=string.buffer; - counter=string.counter; - start=string.start; - length=string.length; - realLength=string.realLength; - - string.buffer=(T*)&zero; - string.counter=0; - string.start=0; - string.length=0; - string.realLength=0; - } - - ~ObjectString() - { - Dec(); - } - - /// Get the zero-terminated buffer in the string. Copying parts of a string does not necessarily create a new buffer, so in some situation the string will not actually points to a zero-terminated buffer. In this case, this function will copy the content to a new buffer with a zero terminator and return. - /// Returns the buffer. - const T* Buffer()const - { - if(start+length!=realLength) - { - T* newBuffer=new T[length+1]; - memcpy(newBuffer, buffer+start, sizeof(T)*length); - newBuffer[length]=0; - Dec(); - buffer=newBuffer; - counter=new vint(1); - start=0; - realLength=length; - } - return buffer+start; - } - - ObjectString& operator=(const ObjectString& string) - { - if(this!=&string) - { - Dec(); - buffer=string.buffer; - counter=string.counter; - start=string.start; - length=string.length; - realLength=string.realLength; - Inc(); - } - return *this; - } - - ObjectString& operator=(ObjectString&& string) - { - if(this!=&string) - { - Dec(); - buffer=string.buffer; - counter=string.counter; - start=string.start; - length=string.length; - realLength=string.realLength; - - string.buffer=(T*)&zero; - string.counter=0; - string.start=0; - string.length=0; - string.realLength=0; - } - return *this; - } - - ObjectString& operator+=(const ObjectString& string) - { - return *this=*this+string; - } - - ObjectString operator+(const ObjectString& string)const - { - return ObjectString(*this, string, length, 0); - } - - bool operator==(const ObjectString& string)const - { - return Compare(*this, string)==0; - } - - bool operator!=(const ObjectString& string)const - { - return Compare(*this, string)!=0; - } - - bool operator>(const ObjectString& string)const - { - return Compare(*this, string)>0; - } - - bool operator>=(const ObjectString& string)const - { - return Compare(*this, string)>=0; - } - - bool operator<(const ObjectString& string)const - { - return Compare(*this, string)<0; - } - - bool operator<=(const ObjectString& string)const - { - return Compare(*this, string)<=0; - } - - bool operator==(const T* buffer)const - { - return Compare(buffer, *this)==0; - } - - bool operator!=(const T* buffer)const - { - return Compare(buffer, *this)!=0; - } - - bool operator>(const T* buffer)const - { - return Compare(buffer, *this)<0; - } - - bool operator>=(const T* buffer)const - { - return Compare(buffer, *this)<=0; - } - - bool operator<(const T* buffer)const - { - return Compare(buffer, *this)>0; - } - - bool operator<=(const T* buffer)const - { - return Compare(buffer, *this)>=0; - } - - T operator[](vint index)const - { - CHECK_ERROR(index>=0 && index:operator[](vint)#Argument index not in range."); - return buffer[start+index]; - } - - /// Get the size of the string in characters. - /// The size. - vint Length()const - { - return length; - } - - /// Find a character. - /// The position of the character. Returns -1 if it doesn not exist. - /// The character to find. - vint IndexOf(T c)const - { - const T* reading=buffer+start; - for(vint i=0;iCopy the beginning of the string. - /// The copied string. - /// Size of characters to copy. - ObjectString Left(vint count)const - { - CHECK_ERROR(count>=0 && count<=length, L"ObjectString::Left(vint)#Argument count not in range."); - return ObjectString(*this, 0, count); - } - - /// Copy the ending of the string. - /// The copied string. - /// Size of characters to copy. - ObjectString Right(vint count)const - { - CHECK_ERROR(count>=0 && count<=length, L"ObjectString::Right(vint)#Argument count not in range."); - return ObjectString(*this, length-count, count); - } - - /// Copy the middle of the string. - /// The copied string. - /// Position of characters to copy. - /// Size of characters to copy. - ObjectString Sub(vint index, vint count)const - { - CHECK_ERROR(index>=0 && index<=length, L"ObjectString::Sub(vint, vint)#Argument index not in range."); - CHECK_ERROR(index+count>=0 && index+count<=length, L"ObjectString::Sub(vint, vint)#Argument count not in range."); - return ObjectString(*this, index, count); - } - - /// Copy the beginning and the end of the string. - /// The copied string. - /// Position of characters NOT to copy. - /// Size of characters NOT to copy. - ObjectString Remove(vint index, vint count)const - { - CHECK_ERROR(index>=0 && index::Remove(vint, vint)#Argument index not in range."); - CHECK_ERROR(index+count>=0 && index+count<=length, L"ObjectString::Remove(vint, vint)#Argument count not in range."); - return ObjectString(*this, ObjectString(), index, count); - } - - /// Make a new string by inserting a string in this string. - /// The copied string. - /// Position of characters to insert. - /// The string to be inserted in this string. - ObjectString Insert(vint index, const ObjectString& string)const - { - CHECK_ERROR(index>=0 && index<=length, L"ObjectString::Insert(vint)#Argument count not in range."); - return ObjectString(*this, string, index, 0); - } - - friend bool operator<(const T* left, const ObjectString& right) - { - return Compare(left, right)<0; - } - - friend bool operator<=(const T* left, const ObjectString& right) - { - return Compare(left, right)<=0; - } - - friend bool operator>(const T* left, const ObjectString& right) - { - return Compare(left, right)>0; - } - - friend bool operator>=(const T* left, const ObjectString& right) - { - return Compare(left, right)>=0; - } - - friend bool operator==(const T* left, const ObjectString& right) - { - return Compare(left, right)==0; - } - - friend bool operator!=(const T* left, const ObjectString& right) - { - return Compare(left, right)!=0; - } - - friend ObjectString operator+(const T* left, const ObjectString& right) - { - return ObjectString(left, false)+right; - } - }; - - template - ObjectString ObjectString::Empty=ObjectString(); - template - const T ObjectString::zero=0; - - /// Ansi string. - typedef ObjectString AString; - /// Unicode string. - typedef ObjectString WString; - - /// Convert a string to an signed integer. - /// The converted number. If the convert failed, the result is undefined. - /// The string to convert. - /// Returns true if this operation succeeded. - extern vint atoi_test(const AString& string, bool& success); - /// Convert a string to an signed integer. - /// The converted number. If the convert failed, the result is undefined. - /// The string to convert. - /// Returns true if this operation succeeded. - extern vint wtoi_test(const WString& string, bool& success); - /// Convert a string to an signed 64-bits integer. - /// The converted number. If the convert failed, the result is undefined. - /// The string to convert. - /// Returns true if this operation succeeded. - extern vint64_t atoi64_test(const AString& string, bool& success); - /// Convert a string to an signed 64-bits integer. - /// The converted number. If the convert failed, the result is undefined. - /// The string to convert. - /// Returns true if this operation succeeded. - extern vint64_t wtoi64_test(const WString& string, bool& success); - /// Convert a string to an unsigned integer. - /// The converted number. If the convert failed, the result is undefined. - /// The string to convert. - /// Returns true if this operation succeeded. - extern vuint atou_test(const AString& string, bool& success); - /// Convert a string to an unsigned integer. - /// The converted number. If the convert failed, the result is undefined. - /// The string to convert. - /// Returns true if this operation succeeded. - extern vuint wtou_test(const WString& string, bool& success); - /// Convert a string to a 64-bits unsigned integer. - /// The converted number. If the convert failed, the result is undefined. - /// The string to convert. - /// Returns true if this operation succeeded. - extern vuint64_t atou64_test(const AString& string, bool& success); - /// Convert a string to a 64-bits unsigned integer. - /// The converted number. If the convert failed, the result is undefined. - /// The string to convert. - /// Returns true if this operation succeeded. - extern vuint64_t wtou64_test(const WString& string, bool& success); - /// Convert a string to 64-bits floating point number. - /// The converted number. If the convert failed, the result is undefined. - /// The string to convert. - /// Returns true if this operation succeeded. - extern double atof_test(const AString& string, bool& success); - /// Convert a string to 64-bits floating point number. - /// The converted number. If the convert failed, the result is undefined. - /// The string to convert. - /// Returns true if this operation succeeded. - extern double wtof_test(const WString& string, bool& success); - - /// Convert a string to an signed integer. - /// The converted number. If the convert failed, the result is undefined. - /// The string to convert. - extern vint atoi(const AString& string); - /// Convert a string to an signed integer. - /// The converted number. If the convert failed, the result is undefined. - /// The string to convert. - extern vint wtoi(const WString& string); - /// Convert a string to an signed 64-bits integer. - /// The converted number. If the convert failed, the result is undefined. - /// The string to convert. - extern vint64_t atoi64(const AString& string); - /// Convert a string to an signed 64-bits integer. - /// The converted number. If the convert failed, the result is undefined. - /// The string to convert. - extern vint64_t wtoi64(const WString& string); - /// Convert a string to an unsigned integer. - /// The converted number. If the convert failed, the result is undefined. - /// The string to convert. - extern vuint atou(const AString& string); - /// Convert a string to an unsigned integer. - /// The converted number. If the convert failed, the result is undefined. - /// The string to convert. - extern vuint wtou(const WString& string); - /// Convert a string to a 64-bits unsigned integer. - /// The converted number. If the convert failed, the result is undefined. - /// The string to convert. - extern vuint64_t atou64(const AString& string); - /// Convert a string to a 64-bits unsigned integer. - /// The converted number. If the convert failed, the result is undefined. - /// The string to convert. - extern vuint64_t wtou64(const WString& string); - /// Convert a string to a 64-bits floating point number. - /// The converted number. If the convert failed, the result is undefined. - /// The string to convert. - extern double atof(const AString& string); - /// Convert a string to a 64-bits floating point number. - /// The converted number. If the convert failed, the result is undefined. - /// The string to convert. - extern double wtof(const WString& string); - - /// Convert a signed interger to a string. - /// The converted string. - /// The number to convert. - extern AString itoa(vint number); - /// Convert a signed interger to a string. - /// The converted string. - /// The number to convert. - extern WString itow(vint number); - /// Convert a 64-bits signed interger to a string. - /// The converted string. - /// The number to convert. - extern AString i64toa(vint64_t number); - /// Convert a 64-bits signed interger to a string. - /// The converted string. - /// The number to convert. - extern WString i64tow(vint64_t number); - /// Convert an unsigned interger to a string. - /// The converted string. - /// The number to convert. - extern AString utoa(vuint number); - /// Convert an unsigned interger to a string. - /// The converted string. - /// The number to convert. - extern WString utow(vuint number); - /// Convert a 64-bits unsigned interger to a string. - /// The converted string. - /// The number to convert. - extern AString u64toa(vuint64_t number); - /// Convert a 64-bits unsigned interger to a string. - /// The converted string. - /// The number to convert. - extern WString u64tow(vuint64_t number); - /// Convert a 64-bits floating pointer number to a string. - /// The converted string. - /// The number to convert. - extern AString ftoa(double number); - /// Convert a 64-bits floating pointer number to a string. - /// The converted string. - /// The number to convert. - extern WString ftow(double number); - - extern vint _wtoa(const wchar_t* w, char* a, vint chars); - /// Convert an Unicode string to an Ansi string. - /// The converted string. - /// The string to convert. - extern AString wtoa(const WString& string); - extern vint _atow(const char* a, wchar_t* w, vint chars); - /// Convert an Ansi string to an Unicode string. - /// The converted string. - /// The string to convert. - extern WString atow(const AString& string); - /// Convert all letters to lower case letters. - /// The converted string. - /// The string to convert. - extern AString alower(const AString& string); - /// Convert all letters to lower case letters. - /// The converted string. - /// The string to convert. - extern WString wlower(const WString& string); - /// Convert all letters to upper case letters. - /// The converted string. - /// The string to convert. - extern AString aupper(const AString& string); - /// Convert all letters to upper case letters. - /// The converted string. - /// The string to convert. - extern WString wupper(const WString& string); - -#if defined VCZH_GCC - extern void _itoa_s(vint32_t value, char* buffer, size_t size, vint radix); - extern void _itow_s(vint32_t value, wchar_t* buffer, size_t size, vint radix); - extern void _i64toa_s(vint64_t value, char* buffer, size_t size, vint radix); - extern void _i64tow_s(vint64_t value, wchar_t* buffer, size_t size, vint radix); - extern void _uitoa_s(vuint32_t value, char* buffer, size_t size, vint radix); - extern void _uitow_s(vuint32_t value, wchar_t* buffer, size_t size, vint radix); - extern void _ui64toa_s(vuint64_t value, char* buffer, size_t size, vint radix); - extern void _ui64tow_s(vuint64_t value, wchar_t* buffer, size_t size, vint radix); - extern void _gcvt_s(char* buffer, size_t size, double value, vint numberOfDigits); - extern void _strlwr_s(char* buffer, size_t size); - extern void _strupr_s(char* buffer, size_t size); - extern void _wcslwr_s(wchar_t* buffer, size_t size); - extern void _wcsupr_s(wchar_t* buffer, size_t size); - extern void wcscpy_s(wchar_t* buffer, size_t size, const wchar_t* text); -#endif - - enum class LoremIpsumCasing - { - AllWordsLowerCase, - FirstWordUpperCase, - AllWordsUpperCase, - }; - - extern WString LoremIpsum(vint bestLength, LoremIpsumCasing casing); - extern WString LoremIpsumTitle(vint bestLength); - extern WString LoremIpsumSentence(vint bestLength); - extern WString LoremIpsumParagraph(vint bestLength); -} - -#endif - - /*********************************************************************** .\POINTER.H ***********************************************************************/ /*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -Data Structure::Smart Pointer - -Classes: - Ptr : Shared Pointer +Author: Zihan Chen (vczh) +Licensed under https://github.com/vczh-libraries/License ***********************************************************************/ #ifndef VCZH_POINTER @@ -1511,13 +824,23 @@ namespace vl ReferenceCounterOperator ***********************************************************************/ - /// The strategy to get the pointer to the reference counter from an object. If you get the same pointer multiple times from the same object by calling [M:vl.ReferenceCounterOperator`2.CreateCounter], than it is safe to convert a object pointer to a [T:vl.Ptr`1]. Currently for reflectable C++ types which inherit from [T:vl.reflection.DescriptableObject] it is yet. For others it is no. - /// The type of the object. - /// [T:vl.Ptr`1] will always use [T:vl.YesType] as the second type parameter. This parameter is useful when you want to do partial specialization in the SFINAE way. + /// + /// The strategy class to create and delete the reference counter of an object. + /// For any object inherits from [T:vl.reflection.DescriptableObject], the reference counter is stored inside the object. + /// For any other object, the reference counter is allocated separately. + /// You can create your own strategy by adding a new partial specialization to this class. + /// + /// + /// The type of the object. + /// + /// + /// [T:vl.Ptr`1] will always use [T:vl.YesType] as the second type parameter. + /// This parameter is useful when you want to do partial specialization in the SFINAE way. + /// template struct ReferenceCounterOperator { - /// Create a pointer to the reference counter from an object. + /// Create the reference counter of an object. /// The pointer to the reference counter. /// The object. static __forceinline volatile vint* CreateCounter(T* reference) @@ -1525,7 +848,7 @@ ReferenceCounterOperator return new vint(0); } - /// Destroy a pointer to the reference counter from an object. + /// Delete the reference counter from an object. /// The pointer to the reference counter. /// The object. static __forceinline void DeleteReference(volatile vint* counter, void* reference) @@ -1539,7 +862,17 @@ ReferenceCounterOperator Ptr ***********************************************************************/ - /// A smart pointer. It is always safe to convert a pointer to an object to a smart pointer once. If you do it multiple times, it may be wrong due to different implementation of [T:vl.ReferenceCounterOperator`2]. In case of wrong, disposing the smart pointer will cause an access violation. + /// + /// A shared pointer. + /// It maintains a reference counter to the object. + /// When no [T:vl.Ptr`1] is referencing the object, the object will be deleted automatically. + /// + /// + /// It is safe to convert the same pointer to an object to a shared pointer once. + /// If you do it multiple times, it depends on [T:vl.ReferenceCounterOperator`2]. + /// For built-in strategies, only pointer to [T:vl.reflection.DescriptableObject] or its derived classes can be safely converted to a shared pointer for multiple times. + /// For any other object, it will crash on the destructor of [T:vl.Ptr`1]. + /// /// The type of the object. template class Ptr @@ -1601,11 +934,9 @@ Ptr public: /// Create a null pointer. - Ptr() - { - } + Ptr() = default; - /// Convert a pointer to an object to a smart pointer. + /// Convert a pointer to an object to a shared pointer. /// The pointer to the object. Ptr(T* pointer) { @@ -1619,8 +950,8 @@ Ptr } } - /// Copy a smart pointer. - /// The smart pointer to copy. + /// Copy a shared pointer. + /// The shared pointer to copy. Ptr(const Ptr& pointer) :counter(pointer.counter) , reference(pointer.reference) @@ -1630,8 +961,8 @@ Ptr Inc(); } - /// Move a smart pointer. - /// The smart pointer to Move. + /// Move a shared pointer. + /// The shared pointer to Move. Ptr(Ptr&& pointer) :counter(pointer.counter) , reference(pointer.reference) @@ -1641,9 +972,9 @@ Ptr pointer.SetEmptyNoIncDec(); } - /// Cast a smart pointer. + /// Cast a shared pointer implicitly by copying another shared pointer. /// The type of the object before casting. - /// The smart pointer to cast. + /// The shared pointer to cast. template::YesNoType>::Type> Ptr(const Ptr& pointer) { @@ -1657,9 +988,9 @@ Ptr } } - /// Cast a smart pointer. + /// Cast a shared pointer implicitly by moving another shared pointer. /// The type of the object before casting. - /// The smart pointer to cast. + /// The shared pointer to cast. template::YesNoType>::Type> Ptr(Ptr&& pointer) { @@ -1678,8 +1009,11 @@ Ptr Dec(); } - /// Detach the contained object from this smart pointer. - /// The detached object. Returns null if this smart pointer is empty. + /// + /// Detach the contained object from this shared pointer. + /// When no [T:vl.Ptr`1] is referencing to the object because of a call to Detach, the object will not be deleted. + /// + /// The detached object. Returns null if this shared pointer is empty. T* Detach() { auto detached = reference; @@ -1687,9 +1021,9 @@ Ptr return detached; } - /// Cast a smart pointer. + /// Cast a shared pointer explicitly. /// The type of the object after casting. - /// The casted smart pointer. Returns null if failed. + /// The casted shared pointer. Returns null for empty shared pointer or a failed cast. template Ptr Cast()const { @@ -1697,9 +1031,9 @@ Ptr return Ptr((converted ? counter : 0), converted, originalReference, originalDestructor); } - /// Convert a pointer to an object to a smart pointer. - /// The converted smart pointer. - /// The pointer to the object. + /// Replace the object inside this shared pointer. + /// The shared pointer itself. + /// The pointer to the new object. Ptr& operator=(T* pointer) { Dec(); @@ -1718,9 +1052,9 @@ Ptr return *this; } - /// Copy a smart pointer. - /// The copied smart pointer. - /// The smart pointer to copy. + /// Replace by copying another shared pointer. + /// The shared pointer itself. + /// The shared pointer to copy. Ptr& operator=(const Ptr& pointer) { if (this != &pointer) @@ -1735,9 +1069,9 @@ Ptr return *this; } - /// Move a smart pointer. - /// The moved smart pointer. - /// The smart pointer to Move. + /// Replace by moving another shared pointer. + /// The shared pointer itself. + /// The shared pointer to copy. Ptr& operator=(Ptr&& pointer) { if (this != &pointer) @@ -1812,22 +1146,22 @@ Ptr return reference <= pointer.reference; } - /// Test if it is a null pointer. - /// Returns true if it is not null. + /// Test if it is an empty shared pointer. + /// Returns true if it is non-null. operator bool()const { return reference != 0; } - /// Get the pointer to the object. - /// The pointer to the object. + /// Get the pointer to the contained object. + /// The pointer to the contained object. Returns null for an empty shared pointer. T* Obj()const { return reference; } - /// Get the pointer to the object. - /// The pointer to the object. + /// Get the pointer to the contained object. + /// The pointer to the contained object. Returns null for an empty shared pointer. T* operator->()const { return reference; @@ -2090,26 +1424,18 @@ Traits .\FUNCTION.H ***********************************************************************/ /*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -Framework::Function - -Classes: - Func : Functor - -Functions: - Curry :: (A->B) -> A -> B : Currying - Combine :: (A->B) -> (A->C) -> (B->C->D) -> (A->D) : Combine multiple functors using an operator +Author: Zihan Chen (vczh) +Licensed under https://github.com/vczh-libraries/License ***********************************************************************/ + #ifndef VCZH_FUNCTION #define VCZH_FUNCTION +#include namespace vl { template - class Func - { - }; + class Func; /*********************************************************************** vl::function_lambda::LambdaRetriveType @@ -2265,7 +1591,7 @@ vl::Func }; } - /// A type representing a function reference. + /// A type for functors. /// The return type. /// Types of parameters. template @@ -2295,45 +1621,37 @@ vl::Func typedef R FunctionType(TArgs...); typedef R ResultType; - /// Create a null function reference. - Func() - { - } + /// Create a null functor. + Func() = default; - /// Copy a function reference. - /// The function reference to copy. - Func(const Func& function) - :invoker(function.invoker) - { - } + /// Copy a functor. + /// The functor to copy. + Func(const Func& function) = default; - /// Move a function reference. - /// The function reference to move. - Func(Func&& function) - :invoker(MoveValue(function.invoker)) - { - } + /// Move a functor. + /// The functor to move. + Func(Func&& function) = default; - /// Create a reference using a function pointer. + /// Create a functor from a function pointer. /// The function pointer. Func(R(*function)(TArgs...)) { invoker = new internal_invokers::StaticInvoker(function); } - /// Create a reference using a method. - /// Type of the class that has the method. - /// The object that has the method. - /// The function pointer. + /// Create a functor from a method. + /// Type of the class that this method belongs to. + /// The object that this method belongs to. + /// The method pointer. template Func(C* sender, R(C::*function)(TArgs...)) { invoker = new internal_invokers::MemberInvoker(sender, function); } - /// Create a reference using a function object. - /// Type of the function object. - /// The function object. It could be a lambda expression. + /// Create a functor from another compatible functor. + /// Type of the functor to copy. + /// The functor to copy. It could be a lambda expression, or any types that has operator() members. template()(ValueOf()...)), R>::YesNoType>::Type> Func(C&& function) { @@ -2344,7 +1662,7 @@ vl::Func } /// Invoke the function. - /// Returns the function result. + /// Returns the function result. It crashes when the functor is null. /// Arguments to invoke the function. R operator()(TArgs ...args)const { @@ -2373,8 +1691,8 @@ vl::Func return invoker != function.invoker; } - /// Test is the reference a null reference. - /// Returns true if it is not a null reference. + /// Test is the functor is non-null. + /// Returns true if the functor is non-null. operator bool()const { return invoker; @@ -2387,19 +1705,19 @@ LAMBDA namespace function_lambda { - /// Create a function reference to a function object or a lambda expression, with all type information autotimatically inferred. You can use the macro called "LAMBDA" to refer to this function. - /// Type of the function object or the lambda expression. - /// The function reference. - /// The function object or the lambda expression. + /// Create a functor in [T:vl.Func`1] from another functor, with all type arguments autotimatically inferred. The "LAMBDA" macro is recommended for the same purpose for writing compact code. + /// Type of the functor to copy. + /// A copied functor in [T:vl.Func`1]. + /// The functor to copy. template typename LambdaRetriveType::Type Lambda(T functionObject) { return functionObject; } - /// Create a function reference to a function pointer, with all type information autotimatically inferred. You can use the macro called "FUNCTION" to refer to this function. + /// Create a functor in [T:vl.Func`1] from a function pointer, with all type arguments autotimatically inferred. The "FUNCTION" macro is recommended for the same purpose for writing compact code. /// Type of the function pointer. - /// The function reference. + /// A copied functor in [T:vl.Func`1]. /// The function pointer. template typename FunctionObjectRetriveType::Type ConvertToFunction(T functionObject) @@ -2476,9 +1794,14 @@ vl::function_binding::Binding }; } - /// Currize a function. Currizing means to create a new function whose argument is the first argument of the original function. Calling this function will return another function reference whose arguments is all remain arguments of the original function. Calling the returned function will call the original function. - /// Type of the function. - /// The currized function. + /// + /// Currize a function pointer. + /// Currizing means to create a new functor whose argument is the first argument of the original function. + /// Calling this functor will return another functor whose arguments are all remaining arguments of the original function. + /// Calling the returned function will call the original function. + /// + /// Type of the function pointer. + /// The currized functor. /// The function pointer to currize. template Func::CurriedType>(typename function_binding::Binding::FirstParameterType)> @@ -2486,94 +1809,1463 @@ vl::function_binding::Binding { return typename function_binding::Binding::Currier(function); } - - /// Currize a function. Currizing means to create a new function whose argument is the first argument of the original function. Calling this function will return another function reference whose arguments is all remain arguments of the original function. Calling the returned function will call the original function. - /// Type of the function. - /// The currized function. - /// The function reference to currize. + + /// + /// Currize a functor in [T:vl.Func`1]. + /// Currizing means to create a new functor whose argument is the first argument of the original function. + /// Calling this functor will return another functor whose arguments are all remaining arguments of the original function. + /// Calling the returned function will call the original function. + /// + /// Type of the functor. + /// The currized functor. + /// The functor to currize. template Func::CurriedType>(typename function_binding::Binding::FirstParameterType)> Curry(const Func& function) { return typename function_binding::Binding::Currier(function); } +} +#endif /*********************************************************************** -vl::function_combining::Combining +.\LAZY.H +***********************************************************************/ +/*********************************************************************** +Author: Zihan Chen (vczh) +Licensed under https://github.com/vczh-libraries/License ***********************************************************************/ - - namespace function_combining - { - template - class Combining - { - }; - - template - class Combining : public Object - { - protected: - Func function1; - Func function2; - Func converter; - public: - typedef R1 FirstFunctionType(TArgs...); - typedef R2 SecondFunctionType(TArgs...); - typedef R ConverterFunctionType(R1, R2); - typedef R FinalFunctionType(TArgs...); - Combining(const Func& _function1, const Func& _function2, const Func& _converter) - :function1(_function1) - ,function2(_function2) - ,converter(_converter) - { - } +#ifndef VCZH_LAZY +#define VCZH_LAZY - R operator()(TArgs&& ...args)const - { - return converter(function1(ForwardValue(args)...), function2(ForwardValue(args)...)); - } - }; - } - /// Combine two functions with a converter function. The two functions to combine should have the same argument types. The converter function will use the return values of the two function to calculate the final value. - /// Type of the first function. - /// Type of the second function. - /// Type of the converter function. - /// A new function whose argument list are the same of the two functions to provide. Calling this function will call function1, function2 and converter in order to calculate the final value. - /// The converter function. - /// The first function. - /// The second function. - template - Func::FinalFunctionType> - Combine(Func converter, Func function1, Func function2) - { - return function_combining::Combining(function1, function2, converter); - } - - /// Use the converter function to create a combiner, who will receive two function and use to create a combined function. This function assumes the result types of the two provided function in the future are the same, and the converter function will not change the result type. - /// Type of the two functions to combine. - /// The combiner. - /// The converter function. +namespace vl +{ + /// A type representing a lazy evaluation. + /// The type of the evaluation result. template - Func(Func,Func)> Combiner(const Func::ResultType(typename Func::ResultType,typename Func::ResultType)>& converter) + class Lazy : public Object { - typedef typename Func::ResultType R; - return Curry(Func,Func,Func)>(Combine)(converter); + protected: + class Internal + { + public: + Func evaluator; + T value; + bool evaluated; + }; + + Ptr internalValue; + public: + /// Create an empty evaluation. + Lazy() = default; + + /// Create an evaluation using a function, which produces the evaluation result. + /// The function. + Lazy(const Func& evaluator) + { + internalValue=new Internal; + internalValue->evaluated=false; + internalValue->evaluator=evaluator; + } + + /// Create an evaluation with the immediate result. + /// The result.0 + Lazy(const T& value) + { + internalValue=new Internal; + internalValue->evaluated=true; + internalValue->value=value; + } + + /// Create an evaluation by copying another one. + /// The evaluation to copy. + Lazy(const Lazy& lazy) = default; + + /// Create an evaluation by moving another one. + /// The evaluation to move. + Lazy(Lazy&& lazy) = default; + + Lazy& operator=(const Func& evaluator) + { + internalValue=new Internal; + internalValue->evaluated=false; + internalValue->evaluator=evaluator; + return *this; + } + + Lazy& operator=(const T& value) + { + internalValue=new Internal; + internalValue->evaluated=true; + internalValue->value=value; + return *this; + } + + Lazy& operator=(const Lazy& lazy) + { + internalValue=lazy.internalValue; + return *this; + } + + /// Get the evaluation result. If the evaluation has not been performed, it will run the evaluation function and cache the result. + /// The evaluation result. + const T& Value()const + { + if(!internalValue->evaluated) + { + internalValue->evaluated=true; + internalValue->value=internalValue->evaluator(); + internalValue->evaluator=Func(); + } + return internalValue->value; + } + + /// Test if it has already been evaluated or not. + /// Returns true if it has already been evaluated. + bool IsEvaluated()const + { + return internalValue->evaluated; + } + + /// Test if it is an empty evaluation or not. + /// Returns true if it is not empty. + operator bool()const + { + return internalValue; + } + }; +} + +#endif + + +/*********************************************************************** +.\STRING.H +***********************************************************************/ +/*********************************************************************** +Author: Zihan Chen (vczh) +Licensed under https://github.com/vczh-libraries/License +***********************************************************************/ + +#ifndef VCZH_STRING +#define VCZH_STRING + + +namespace vl +{ + /// + /// Immutable string. and is recommended instead. + /// Locale awared operations are in [T:vl.Locale], typically by using the "INVLOC" macro. + /// + /// Type of code points. + template + class ObjectString : public Object + { + private: + static const T zero; + + mutable T* buffer; + mutable volatile vint* counter; + mutable vint start; + mutable vint length; + mutable vint realLength; + + static vint CalculateLength(const T* buffer) + { + vint result=0; + while(*buffer++)result++; + return result; + } + + static vint Compare(const T* bufA, const ObjectString& strB) + { + const T* bufB=strB.buffer+strB.start; + const T* bufAOld=bufA; + vint length=strB.length; + while(length-- && *bufA) + { + vint diff=*bufA++-*bufB++; + if(diff!=0) + { + return diff; + } + }; + return CalculateLength(bufAOld)-strB.length; + } + + public: + + static vint Compare(const ObjectString& strA, const ObjectString& strB) + { + const T* bufA=strA.buffer+strA.start; + const T* bufB=strB.buffer+strB.start; + vint length=strA.length& string, vint _start, vint _length) + { + if(_length<=0) + { + buffer=(T*)&zero; + counter=0; + start=0; + length=0; + realLength=0; + } + else + { + buffer=string.buffer; + counter=string.counter; + start=string.start+_start; + length=_length; + realLength=string.realLength; + Inc(); + } + } + + ObjectString(const ObjectString& dest, const ObjectString& source, vint index, vint count) + { + if(index==0 && count==dest.length && source.length==0) + { + buffer=(T*)&zero; + counter=0; + start=0; + length=0; + realLength=0; + } + else + { + counter=new vint(1); + start=0; + length=dest.length-count+source.length; + realLength=length; + buffer=new T[length+1]; + memcpy(buffer, dest.buffer+dest.start, sizeof(T)*index); + memcpy(buffer+index, source.buffer+source.start, sizeof(T)*source.length); + memcpy(buffer+index+source.length, (dest.buffer+dest.start+index+count), sizeof(T)*(dest.length-index-count)); + buffer[length]=0; + } + } + public: + static ObjectString Empty; + + /// Create an empty string. + ObjectString() + { + buffer=(T*)&zero; + counter=0; + start=0; + length=0; + realLength=0; + } + + /// Create a string continaing one code point. + /// The code point. + ObjectString(const T& _char) + { + counter=new vint(1); + start=0; + length=1; + buffer=new T[2]; + buffer[0]=_char; + buffer[1]=0; + realLength=length; + } + + /// Copy a string. + /// Memory to copy. It is not required to be zero terminated. + /// Size of the content in code points. + ObjectString(const T* _buffer, vint _length) + { + if(_length<=0) + { + buffer=(T*)&zero; + counter=0; + start=0; + length=0; + realLength=0; + } + else + { + buffer=new T[_length+1]; + memcpy(buffer, _buffer, _length*sizeof(T)); + buffer[_length]=0; + counter=new vint(1); + start=0; + length=_length; + realLength=_length; + } + } + + /// Copy a string. + /// Memory to copy. It must be zero terminated. + /// Set to true to copy the memory. Set to false to use the memory directly. + ObjectString(const T* _buffer, bool copy = true) + { + CHECK_ERROR(_buffer!=0, L"ObjectString::ObjectString(const T*, bool)#Cannot construct a string from nullptr."); + if(copy) + { + counter=new vint(1); + start=0; + length=CalculateLength(_buffer); + buffer=new T[length+1]; + memcpy(buffer, _buffer, sizeof(T)*(length+1)); + realLength=length; + } + else + { + buffer=(T*)_buffer; + counter=0; + start=0; + length=CalculateLength(_buffer); + realLength=length; + } + } + + /// Copy a string. + /// The string to copy. + ObjectString(const ObjectString& string) + { + buffer=string.buffer; + counter=string.counter; + start=string.start; + length=string.length; + realLength=string.realLength; + Inc(); + } + + /// Move a string. + /// The string to move. + ObjectString(ObjectString&& string) + { + buffer=string.buffer; + counter=string.counter; + start=string.start; + length=string.length; + realLength=string.realLength; + + string.buffer=(T*)&zero; + string.counter=0; + string.start=0; + string.length=0; + string.realLength=0; + } + + ~ObjectString() + { + Dec(); + } + + /// + /// Get the zero terminated buffer in the string. + /// Copying parts of a string does not necessarily create a new buffer, + /// so in some situation the string will not actually points to a zero terminated buffer. + /// In this case, this function will copy the content to a new buffer with a zero terminator and return. + /// + /// The zero terminated buffer. + const T* Buffer()const + { + if(start+length!=realLength) + { + T* newBuffer=new T[length+1]; + memcpy(newBuffer, buffer+start, sizeof(T)*length); + newBuffer[length]=0; + Dec(); + buffer=newBuffer; + counter=new vint(1); + start=0; + realLength=length; + } + return buffer+start; + } + + /// Replace the string by copying another string. + /// The string itself. + /// The string to copy. + ObjectString& operator=(const ObjectString& string) + { + if(this!=&string) + { + Dec(); + buffer=string.buffer; + counter=string.counter; + start=string.start; + length=string.length; + realLength=string.realLength; + Inc(); + } + return *this; + } + + /// Replace the string by moving another string. + /// The string itself. + /// The string to move. + ObjectString& operator=(ObjectString&& string) + { + if(this!=&string) + { + Dec(); + buffer=string.buffer; + counter=string.counter; + start=string.start; + length=string.length; + realLength=string.realLength; + + string.buffer=(T*)&zero; + string.counter=0; + string.start=0; + string.length=0; + string.realLength=0; + } + return *this; + } + + /// Replace the string by appending another string. + /// The string itself. + /// The string to append. + ObjectString& operator+=(const ObjectString& string) + { + return *this=*this+string; + } + + /// Create a new string by concatenating two strings. + /// The new string. + /// The string to append. + ObjectString operator+(const ObjectString& string)const + { + return ObjectString(*this, string, length, 0); + } + + bool operator==(const ObjectString& string)const + { + return Compare(*this, string)==0; + } + + bool operator!=(const ObjectString& string)const + { + return Compare(*this, string)!=0; + } + + bool operator>(const ObjectString& string)const + { + return Compare(*this, string)>0; + } + + bool operator>=(const ObjectString& string)const + { + return Compare(*this, string)>=0; + } + + bool operator<(const ObjectString& string)const + { + return Compare(*this, string)<0; + } + + bool operator<=(const ObjectString& string)const + { + return Compare(*this, string)<=0; + } + + bool operator==(const T* buffer)const + { + return Compare(buffer, *this)==0; + } + + bool operator!=(const T* buffer)const + { + return Compare(buffer, *this)!=0; + } + + bool operator>(const T* buffer)const + { + return Compare(buffer, *this)<0; + } + + bool operator>=(const T* buffer)const + { + return Compare(buffer, *this)<=0; + } + + bool operator<(const T* buffer)const + { + return Compare(buffer, *this)>0; + } + + bool operator<=(const T* buffer)const + { + return Compare(buffer, *this)>=0; + } + + /// Get a code point in the specified position. + /// Returns the code point. It will crash when the specified position is out of range. + /// + T operator[](vint index)const + { + CHECK_ERROR(index>=0 && index:operator[](vint)#Argument index not in range."); + return buffer[start+index]; + } + + /// Get the size of the string in code points. + /// The size, not including the zero terminator. + vint Length()const + { + return length; + } + + /// Find a code point. + /// The position of the code point. Returns -1 if it does not exist. + /// The code point to find. + vint IndexOf(T c)const + { + const T* reading=buffer+start; + for(vint i=0;iGet the prefix of the string. + /// The prefix. It will crash when the specified size is out of range. + /// Size of the prefix. + /// + ObjectString Left(vint count)const + { + CHECK_ERROR(count>=0 && count<=length, L"ObjectString::Left(vint)#Argument count not in range."); + return ObjectString(*this, 0, count); + } + + /// Get the postfix of the string. + /// The postfix. It will crash when the specified size is out of range. + /// Size of the prefix. + /// + ObjectString Right(vint count)const + { + CHECK_ERROR(count>=0 && count<=length, L"ObjectString::Right(vint)#Argument count not in range."); + return ObjectString(*this, length-count, count); + } + + /// Get a sub string. + /// The sub string. It will crash when the specified position or size is out of range. + /// The position of the first code point of the sub string. + /// The size of the sub string. + /// + ObjectString Sub(vint index, vint count)const + { + CHECK_ERROR(index>=0 && index<=length, L"ObjectString::Sub(vint, vint)#Argument index not in range."); + CHECK_ERROR(index+count>=0 && index+count<=length, L"ObjectString::Sub(vint, vint)#Argument count not in range."); + return ObjectString(*this, index, count); + } + + /// Get a string by removing a sub string. + /// The string without the sub string. It will crash when the specified position or size is out of range. + /// The position of the first code point of the sub string. + /// The size of the sub string. + /// + ObjectString Remove(vint index, vint count)const + { + CHECK_ERROR(index>=0 && index::Remove(vint, vint)#Argument index not in range."); + CHECK_ERROR(index+count>=0 && index+count<=length, L"ObjectString::Remove(vint, vint)#Argument count not in range."); + return ObjectString(*this, ObjectString(), index, count); + } + + /// Get a string by inserting another string. + /// The string with another string inserted. It will crash when the specified position is out of range. + /// The position to insert. + /// The string to insert. + /// + ObjectString Insert(vint index, const ObjectString& string)const + { + CHECK_ERROR(index>=0 && index<=length, L"ObjectString::Insert(vint)#Argument count not in range."); + return ObjectString(*this, string, index, 0); + } + + friend bool operator<(const T* left, const ObjectString& right) + { + return Compare(left, right)<0; + } + + friend bool operator<=(const T* left, const ObjectString& right) + { + return Compare(left, right)<=0; + } + + friend bool operator>(const T* left, const ObjectString& right) + { + return Compare(left, right)>0; + } + + friend bool operator>=(const T* left, const ObjectString& right) + { + return Compare(left, right)>=0; + } + + friend bool operator==(const T* left, const ObjectString& right) + { + return Compare(left, right)==0; + } + + friend bool operator!=(const T* left, const ObjectString& right) + { + return Compare(left, right)!=0; + } + + friend ObjectString operator+(const T* left, const ObjectString& right) + { + return ObjectString(left, false)+right; + } + }; + + template + ObjectString ObjectString::Empty=ObjectString(); + template + const T ObjectString::zero=0; + + /// Ansi string in local code page. + typedef ObjectString AString; + /// + /// Unicode string, UTF-16 on Windows, UTF-32 on Linux and macOS. + /// + typedef ObjectString WString; + + /// Convert a string to a signed integer. + /// The converted number. If the conversion failed, the result is undefined. + /// The string to convert. + /// Returns true if this operation succeeded. + extern vint atoi_test(const AString& string, bool& success); + /// Convert a string to a signed integer. + /// The converted number. If the conversion failed, the result is undefined. + /// The string to convert. + /// Returns true if this operation succeeded. + extern vint wtoi_test(const WString& string, bool& success); + /// Convert a string to a signed 64-bits integer. + /// The converted number. If the conversion failed, the result is undefined. + /// The string to convert. + /// Returns true if this operation succeeded. + extern vint64_t atoi64_test(const AString& string, bool& success); + /// Convert a string to a signed 64-bits integer. + /// The converted number. If the conversion failed, the result is undefined. + /// The string to convert. + /// Returns true if this operation succeeded. + extern vint64_t wtoi64_test(const WString& string, bool& success); + /// Convert a string to an unsigned integer. + /// The converted number. If the conversion failed, the result is undefined. + /// The string to convert. + /// Returns true if this operation succeeded. + extern vuint atou_test(const AString& string, bool& success); + /// Convert a string to an unsigned integer. + /// The converted number. If the conversion failed, the result is undefined. + /// The string to convert. + /// Returns true if this operation succeeded. + extern vuint wtou_test(const WString& string, bool& success); + /// Convert a string to an unsigned 64-bits integer. + /// The converted number. If the conversion failed, the result is undefined. + /// The string to convert. + /// Returns true if this operation succeeded. + extern vuint64_t atou64_test(const AString& string, bool& success); + /// Convert a string to an unsigned 64-bits integer. + /// The converted number. If the conversion failed, the result is undefined. + /// The string to convert. + /// Returns true if this operation succeeded. + extern vuint64_t wtou64_test(const WString& string, bool& success); + /// Convert a string to a 64-bits floating point number. + /// The converted number. If the conversion failed, the result is undefined. + /// The string to convert. + /// Returns true if this operation succeeded. + extern double atof_test(const AString& string, bool& success); + /// Convert a string to a 64-bits floating point number. + /// The converted number. If the conversion failed, the result is undefined. + /// The string to convert. + /// Returns true if this operation succeeded. + extern double wtof_test(const WString& string, bool& success); + + /// Convert a string to a signed integer. + /// The converted number. If the conversion failed, the result is undefined. + /// The string to convert. + /// If you need to know whether the conversion is succeeded or not, please use instead. + extern vint atoi(const AString& string); + /// Convert a string to a signed integer. + /// The converted number. If the conversion failed, the result is undefined. + /// The string to convert. + /// If you need to know whether the conversion is succeeded or not, please use instead. + extern vint wtoi(const WString& string); + /// Convert a string to a signed 64-bits integer. + /// The converted number. If the conversion failed, the result is undefined. + /// The string to convert. + /// If you need to know whether the conversion is succeeded or not, please use instead. + extern vint64_t atoi64(const AString& string); + /// Convert a string to a signed 64-bits integer. + /// The converted number. If the conversion failed, the result is undefined. + /// The string to convert. + /// If you need to know whether the conversion is succeeded or not, please use instead. + extern vint64_t wtoi64(const WString& string); + /// Convert a string to an usigned integer. + /// The converted number. If the conversion failed, the result is undefined. + /// The string to convert. + /// If you need to know whether the conversion is succeeded or not, please use instead. + extern vuint atou(const AString& string); + /// Convert a string to an usigned integer. + /// The converted number. If the conversion failed, the result is undefined. + /// The string to convert. + /// If you need to know whether the conversion is succeeded or not, please use instead. + extern vuint wtou(const WString& string); + /// Convert a string to an usigned 64-bits integer. + /// The converted number. If the conversion failed, the result is undefined. + /// The string to convert. + /// If you need to know whether the conversion is succeeded or not, please use instead. + extern vuint64_t atou64(const AString& string); + /// Convert a string to an usigned 64-bits integer. + /// The converted number. If the conversion failed, the result is undefined. + /// The string to convert. + /// If you need to know whether the conversion is succeeded or not, please use instead. + extern vuint64_t wtou64(const WString& string); + /// Convert a string to a 64-bits floating point number. + /// The converted number. If the conversion failed, the result is undefined. + /// The string to convert. + /// If you need to know whether the conversion is succeeded or not, please use instead. + extern double atof(const AString& string); + /// Convert a string to a 64-bits floating point number. + /// The converted number. If the conversion failed, the result is undefined. + /// The string to convert. + /// If you need to know whether the conversion is succeeded or not, please use instead. + extern double wtof(const WString& string); + + /// Convert a signed interger to a string. + /// The converted string. + /// The number to convert. + extern AString itoa(vint number); + /// Convert a signed interger to a string. + /// The converted string. + /// The number to convert. + extern WString itow(vint number); + /// Convert a signed 64-bits interger to a string. + /// The converted string. + /// The number to convert. + extern AString i64toa(vint64_t number); + /// Convert a signed 64-bits interger to a string. + /// The converted string. + /// The number to convert. + extern WString i64tow(vint64_t number); + /// Convert an unsigned interger to a string. + /// The converted string. + /// The number to convert. + extern AString utoa(vuint number); + /// Convert an unsigned interger to a string. + /// The converted string. + /// The number to convert. + extern WString utow(vuint number); + /// Convert an unsigned 64-bits interger to a string. + /// The converted string. + /// The number to convert. + extern AString u64toa(vuint64_t number); + /// Convert an unsigned 64-bits interger to a string. + /// The converted string. + /// The number to convert. + extern WString u64tow(vuint64_t number); + /// Convert a 64-bits floating pointer number to a string. + /// The converted string. + /// The number to convert. + extern AString ftoa(double number); + /// Convert a 64-bits floating pointer number to a string. + /// The converted string. + /// The number to convert. + extern WString ftow(double number); + + extern vint _wtoa(const wchar_t* w, char* a, vint chars); + /// Convert a Unicode string to an Ansi string. + /// The converted string. + /// The string to convert. + extern AString wtoa(const WString& string); + extern vint _atow(const char* a, wchar_t* w, vint chars); + /// Convert an Ansi string to an Unicode string. + /// The converted string. + /// The string to convert. + extern WString atow(const AString& string); + /// Convert all letters to lower case letters. + /// The converted string. + /// The string to convert. + extern AString alower(const AString& string); + /// Convert all letters to lower case letters. + /// The converted string. + /// The string to convert. + extern WString wlower(const WString& string); + /// Convert all letters to upper case letters. + /// The converted string. + /// The string to convert. + extern AString aupper(const AString& string); + /// Convert all letters to upper case letters. + /// The converted string. + /// The string to convert. + extern WString wupper(const WString& string); + +#if defined VCZH_GCC + extern void _itoa_s(vint32_t value, char* buffer, size_t size, vint radix); + extern void _itow_s(vint32_t value, wchar_t* buffer, size_t size, vint radix); + extern void _i64toa_s(vint64_t value, char* buffer, size_t size, vint radix); + extern void _i64tow_s(vint64_t value, wchar_t* buffer, size_t size, vint radix); + extern void _uitoa_s(vuint32_t value, char* buffer, size_t size, vint radix); + extern void _uitow_s(vuint32_t value, wchar_t* buffer, size_t size, vint radix); + extern void _ui64toa_s(vuint64_t value, char* buffer, size_t size, vint radix); + extern void _ui64tow_s(vuint64_t value, wchar_t* buffer, size_t size, vint radix); + extern void _gcvt_s(char* buffer, size_t size, double value, vint numberOfDigits); + extern void _strlwr_s(char* buffer, size_t size); + extern void _strupr_s(char* buffer, size_t size); + extern void _wcslwr_s(wchar_t* buffer, size_t size); + extern void _wcsupr_s(wchar_t* buffer, size_t size); + extern void wcscpy_s(wchar_t* buffer, size_t size, const wchar_t* text); +#endif + + /// Style of the random text. + enum class LoremIpsumCasing + { + /// First letters of all words are lower cased. + AllWordsLowerCase, + /// first letters of first words of all sentences are upper cased. + FirstWordUpperCase, + /// First letters of all words are upper cased. + AllWordsUpperCase, + }; + + /// Get some random text. + /// The generated random text. It may not exactly in the expected size. + /// The expected size. + /// The expected casing. + extern WString LoremIpsum(vint bestLength, LoremIpsumCasing casing); + /// Get some random text for a title, first letters of all words are upper cased. + /// The generated random text. It may not be exactly in the expected size. + /// The expected size. + extern WString LoremIpsumTitle(vint bestLength); + /// Get some random sentences. The first letter of the first word is uppder cased. + /// The generated random text with a period character ".". It may not be exactly in the expected size. + /// The expected size. + extern WString LoremIpsumSentence(vint bestLength); + /// Get some random paragraphs. First letters of first words of all sentences are upper cased. + /// The generated random text with multiple sentences ending with period characters ".". It may not be exactly in the expected size. + /// The expected size. + extern WString LoremIpsumParagraph(vint bestLength); +} + +#endif + + +/*********************************************************************** +.\CONSOLE.H +***********************************************************************/ +/*********************************************************************** +Author: Zihan Chen (vczh) +Licensed under https://github.com/vczh-libraries/License +***********************************************************************/ + +#ifndef VCZH_CONSOLE +#define VCZH_CONSOLE + + +namespace vl +{ + namespace console + { + /// Basic I/O for command-line applications. + class Console abstract + { + public: + /// Write a string to the command-line window. + /// Content to write. + /// Size of the content in wchar_t, not including the zero terminator. + static void Write(const wchar_t* string, vint length); + + /// Write a string to the command-line window. + /// Content to write, must be zero terminated. + static void Write(const wchar_t* string); + + /// Write a string to the command-line window. + /// Content to write. + static void Write(const WString& string); + + /// Write to the command-line window, following CR/LF characters. + /// Content to write. + static void WriteLine(const WString& string); + + /// Read a string from the command-line window. + /// The whole line read from the command-line window. + static WString Read(); + + static void SetColor(bool red, bool green, bool blue, bool light); + static void SetTitle(const WString& string); + }; } } + +#endif + +/*********************************************************************** +.\EXCEPTION.H +***********************************************************************/ +/*********************************************************************** +Author: Zihan Chen (vczh) +Licensed under https://github.com/vczh-libraries/License +***********************************************************************/ + +#ifndef VCZH_EXCEPTION +#define VCZH_EXCEPTION + + +namespace vl +{ + /// Base type of all exceptions. + class Exception : public Object + { + protected: + WString message; + + public: + Exception(const WString& _message=WString::Empty); + + const WString& Message()const; + }; + + class ArgumentException : public Exception + { + protected: + WString function; + WString name; + + public: + ArgumentException(const WString& _message=WString::Empty, const WString& _function=WString::Empty, const WString& _name=WString::Empty); + + const WString& GetFunction()const; + const WString& GetName()const; + }; + + class ParsingException : public Exception + { + protected: + vint position; + WString expression; + + public: + ParsingException(const WString& _message, const WString& _expression, vint _position); + + const WString& GetExpression()const; + vint GetPosition()const; + }; +} + +#endif + +/*********************************************************************** +.\GLOBALSTORAGE.H +***********************************************************************/ +/*********************************************************************** +Author: Zihan Chen (vczh) +Licensed under https://github.com/vczh-libraries/License +***********************************************************************/ + +#ifndef VCZH_GLOBALSTORAGE +#define VCZH_GLOBALSTORAGE + + +namespace vl +{ + /// + /// Base type of all global storages. + /// A global storage stores multiple values using a name. + /// The "BEGIN_GLOBAL_STOREGE_CLASS" macro is recommended to create a global storage. + /// + /// + /// All values are shared like global variables, but they are created at the first time when they need to be accessed. + /// is recommended after you don't need any global storages any more, it frees memory. + /// + /// data; + /// INITIALIZE_GLOBAL_STORAGE_CLASS + /// data = new vint(100); + /// FINALIZE_GLOBAL_STORAGE_CLASS + /// data = nullptr; + /// END_GLOBAL_STORAGE_CLASS(MyStorage) + /// + /// int main() + /// { + /// // GetMyStorage is generated by defining MyStorage + /// Console::WriteLine(itow(*GetMyStorage().data.Obj())); + /// FinalizeGlobalStorage(); + /// } + /// ]]> + class GlobalStorage : public Object, private NotCopyable + { + private: + bool cleared = false; + public: + GlobalStorage(const wchar_t* key); + ~GlobalStorage(); + + bool Cleared(); + virtual void ClearResource() = 0; + }; + + extern GlobalStorage* GetGlobalStorage(const wchar_t* key); + extern GlobalStorage* GetGlobalStorage(const WString& key); + + extern void InitializeGlobalStorage(); + /// Free all memories used by global storages. + extern void FinalizeGlobalStorage(); +} + +#define BEGIN_GLOBAL_STORAGE_CLASS(NAME) \ + class NAME : public vl::GlobalStorage \ + { \ + public: \ + NAME() \ + :vl::GlobalStorage(L ## #NAME) \ + { \ + InitializeClearResource(); \ + } \ + ~NAME() \ + { \ + if(!Cleared())ClearResource(); \ + } \ + +#define INITIALIZE_GLOBAL_STORAGE_CLASS \ + void InitializeClearResource() \ + { \ + +#define FINALIZE_GLOBAL_STORAGE_CLASS \ + } \ + void ClearResource() \ + { \ + +#define END_GLOBAL_STORAGE_CLASS(NAME) \ + } \ + }; \ + NAME& Get##NAME() \ + { \ + static NAME __global_storage_##NAME; \ + return __global_storage_##NAME; \ + } \ + +#define EXTERN_GLOBAL_STORAGE_CLASS(NAME)\ + class NAME;\ + extern NAME& Get##NAME();\ + +#endif + + +/*********************************************************************** +.\TUPLE.H +***********************************************************************/ +/*********************************************************************** +Author: Zihan Chen (vczh) +Licensed under https://github.com/vczh-libraries/License + +This file is generated by: Vczh Functional Macro +***********************************************************************/ +#ifndef VCZH_TUPLE +#define VCZH_TUPLE + + +namespace vl +{ + class TupleNullItem + { + }; + template + class Tuple + { + }; + +/*********************************************************************** +vl::Tuple +***********************************************************************/ + template + class Tuple : public Object + { + public: + T0 f0; + + Tuple() + { + } + + Tuple(T0 p0) + :f0(p0) + { + } + + static int Compare(const Tuple& a, const Tuple& b) + { + if (a.f0 < b.f0) return -1; else if (a.f0 > b.f0) return 1; + return 0; + } + + bool operator==(const Tuple& value)const{ return Compare(*this, value) == 0; } + bool operator!=(const Tuple& value)const{ return Compare(*this, value) != 0; } + bool operator< (const Tuple& value)const{ return Compare(*this, value) < 0; } + bool operator<=(const Tuple& value)const{ return Compare(*this, value) <= 0; } + bool operator> (const Tuple& value)const{ return Compare(*this, value) > 0; } + bool operator>=(const Tuple& value)const{ return Compare(*this, value) >= 0; } + }; + +/*********************************************************************** +vl::Tuple +***********************************************************************/ + template + class Tuple : public Object + { + public: + T0 f0;T1 f1; + + Tuple() + { + } + + Tuple(T0 p0,T1 p1) + :f0(p0),f1(p1) + { + } + + static int Compare(const Tuple& a, const Tuple& b) + { + if (a.f0 < b.f0) return -1; else if (a.f0 > b.f0) return 1;if (a.f1 < b.f1) return -1; else if (a.f1 > b.f1) return 1; + return 0; + } + + bool operator==(const Tuple& value)const{ return Compare(*this, value) == 0; } + bool operator!=(const Tuple& value)const{ return Compare(*this, value) != 0; } + bool operator< (const Tuple& value)const{ return Compare(*this, value) < 0; } + bool operator<=(const Tuple& value)const{ return Compare(*this, value) <= 0; } + bool operator> (const Tuple& value)const{ return Compare(*this, value) > 0; } + bool operator>=(const Tuple& value)const{ return Compare(*this, value) >= 0; } + }; + +/*********************************************************************** +vl::Tuple +***********************************************************************/ + template + class Tuple : public Object + { + public: + T0 f0;T1 f1;T2 f2; + + Tuple() + { + } + + Tuple(T0 p0,T1 p1,T2 p2) + :f0(p0),f1(p1),f2(p2) + { + } + + static int Compare(const Tuple& a, const Tuple& b) + { + if (a.f0 < b.f0) return -1; else if (a.f0 > b.f0) return 1;if (a.f1 < b.f1) return -1; else if (a.f1 > b.f1) return 1;if (a.f2 < b.f2) return -1; else if (a.f2 > b.f2) return 1; + return 0; + } + + bool operator==(const Tuple& value)const{ return Compare(*this, value) == 0; } + bool operator!=(const Tuple& value)const{ return Compare(*this, value) != 0; } + bool operator< (const Tuple& value)const{ return Compare(*this, value) < 0; } + bool operator<=(const Tuple& value)const{ return Compare(*this, value) <= 0; } + bool operator> (const Tuple& value)const{ return Compare(*this, value) > 0; } + bool operator>=(const Tuple& value)const{ return Compare(*this, value) >= 0; } + }; + +/*********************************************************************** +vl::Tuple +***********************************************************************/ + template + class Tuple : public Object + { + public: + T0 f0;T1 f1;T2 f2;T3 f3; + + Tuple() + { + } + + Tuple(T0 p0,T1 p1,T2 p2,T3 p3) + :f0(p0),f1(p1),f2(p2),f3(p3) + { + } + + static int Compare(const Tuple& a, const Tuple& b) + { + if (a.f0 < b.f0) return -1; else if (a.f0 > b.f0) return 1;if (a.f1 < b.f1) return -1; else if (a.f1 > b.f1) return 1;if (a.f2 < b.f2) return -1; else if (a.f2 > b.f2) return 1;if (a.f3 < b.f3) return -1; else if (a.f3 > b.f3) return 1; + return 0; + } + + bool operator==(const Tuple& value)const{ return Compare(*this, value) == 0; } + bool operator!=(const Tuple& value)const{ return Compare(*this, value) != 0; } + bool operator< (const Tuple& value)const{ return Compare(*this, value) < 0; } + bool operator<=(const Tuple& value)const{ return Compare(*this, value) <= 0; } + bool operator> (const Tuple& value)const{ return Compare(*this, value) > 0; } + bool operator>=(const Tuple& value)const{ return Compare(*this, value) >= 0; } + }; + +/*********************************************************************** +vl::Tuple +***********************************************************************/ + template + class Tuple : public Object + { + public: + T0 f0;T1 f1;T2 f2;T3 f3;T4 f4; + + Tuple() + { + } + + Tuple(T0 p0,T1 p1,T2 p2,T3 p3,T4 p4) + :f0(p0),f1(p1),f2(p2),f3(p3),f4(p4) + { + } + + static int Compare(const Tuple& a, const Tuple& b) + { + if (a.f0 < b.f0) return -1; else if (a.f0 > b.f0) return 1;if (a.f1 < b.f1) return -1; else if (a.f1 > b.f1) return 1;if (a.f2 < b.f2) return -1; else if (a.f2 > b.f2) return 1;if (a.f3 < b.f3) return -1; else if (a.f3 > b.f3) return 1;if (a.f4 < b.f4) return -1; else if (a.f4 > b.f4) return 1; + return 0; + } + + bool operator==(const Tuple& value)const{ return Compare(*this, value) == 0; } + bool operator!=(const Tuple& value)const{ return Compare(*this, value) != 0; } + bool operator< (const Tuple& value)const{ return Compare(*this, value) < 0; } + bool operator<=(const Tuple& value)const{ return Compare(*this, value) <= 0; } + bool operator> (const Tuple& value)const{ return Compare(*this, value) > 0; } + bool operator>=(const Tuple& value)const{ return Compare(*this, value) >= 0; } + }; + +/*********************************************************************** +vl::Tuple +***********************************************************************/ + template + class Tuple : public Object + { + public: + T0 f0;T1 f1;T2 f2;T3 f3;T4 f4;T5 f5; + + Tuple() + { + } + + Tuple(T0 p0,T1 p1,T2 p2,T3 p3,T4 p4,T5 p5) + :f0(p0),f1(p1),f2(p2),f3(p3),f4(p4),f5(p5) + { + } + + static int Compare(const Tuple& a, const Tuple& b) + { + if (a.f0 < b.f0) return -1; else if (a.f0 > b.f0) return 1;if (a.f1 < b.f1) return -1; else if (a.f1 > b.f1) return 1;if (a.f2 < b.f2) return -1; else if (a.f2 > b.f2) return 1;if (a.f3 < b.f3) return -1; else if (a.f3 > b.f3) return 1;if (a.f4 < b.f4) return -1; else if (a.f4 > b.f4) return 1;if (a.f5 < b.f5) return -1; else if (a.f5 > b.f5) return 1; + return 0; + } + + bool operator==(const Tuple& value)const{ return Compare(*this, value) == 0; } + bool operator!=(const Tuple& value)const{ return Compare(*this, value) != 0; } + bool operator< (const Tuple& value)const{ return Compare(*this, value) < 0; } + bool operator<=(const Tuple& value)const{ return Compare(*this, value) <= 0; } + bool operator> (const Tuple& value)const{ return Compare(*this, value) > 0; } + bool operator>=(const Tuple& value)const{ return Compare(*this, value) >= 0; } + }; + +/*********************************************************************** +vl::Tuple +***********************************************************************/ + template + class Tuple : public Object + { + public: + T0 f0;T1 f1;T2 f2;T3 f3;T4 f4;T5 f5;T6 f6; + + Tuple() + { + } + + Tuple(T0 p0,T1 p1,T2 p2,T3 p3,T4 p4,T5 p5,T6 p6) + :f0(p0),f1(p1),f2(p2),f3(p3),f4(p4),f5(p5),f6(p6) + { + } + + static int Compare(const Tuple& a, const Tuple& b) + { + if (a.f0 < b.f0) return -1; else if (a.f0 > b.f0) return 1;if (a.f1 < b.f1) return -1; else if (a.f1 > b.f1) return 1;if (a.f2 < b.f2) return -1; else if (a.f2 > b.f2) return 1;if (a.f3 < b.f3) return -1; else if (a.f3 > b.f3) return 1;if (a.f4 < b.f4) return -1; else if (a.f4 > b.f4) return 1;if (a.f5 < b.f5) return -1; else if (a.f5 > b.f5) return 1;if (a.f6 < b.f6) return -1; else if (a.f6 > b.f6) return 1; + return 0; + } + + bool operator==(const Tuple& value)const{ return Compare(*this, value) == 0; } + bool operator!=(const Tuple& value)const{ return Compare(*this, value) != 0; } + bool operator< (const Tuple& value)const{ return Compare(*this, value) < 0; } + bool operator<=(const Tuple& value)const{ return Compare(*this, value) <= 0; } + bool operator> (const Tuple& value)const{ return Compare(*this, value) > 0; } + bool operator>=(const Tuple& value)const{ return Compare(*this, value) >= 0; } + }; + +/*********************************************************************** +vl::Tuple +***********************************************************************/ + template + class Tuple : public Object + { + public: + T0 f0;T1 f1;T2 f2;T3 f3;T4 f4;T5 f5;T6 f6;T7 f7; + + Tuple() + { + } + + Tuple(T0 p0,T1 p1,T2 p2,T3 p3,T4 p4,T5 p5,T6 p6,T7 p7) + :f0(p0),f1(p1),f2(p2),f3(p3),f4(p4),f5(p5),f6(p6),f7(p7) + { + } + + static int Compare(const Tuple& a, const Tuple& b) + { + if (a.f0 < b.f0) return -1; else if (a.f0 > b.f0) return 1;if (a.f1 < b.f1) return -1; else if (a.f1 > b.f1) return 1;if (a.f2 < b.f2) return -1; else if (a.f2 > b.f2) return 1;if (a.f3 < b.f3) return -1; else if (a.f3 > b.f3) return 1;if (a.f4 < b.f4) return -1; else if (a.f4 > b.f4) return 1;if (a.f5 < b.f5) return -1; else if (a.f5 > b.f5) return 1;if (a.f6 < b.f6) return -1; else if (a.f6 > b.f6) return 1;if (a.f7 < b.f7) return -1; else if (a.f7 > b.f7) return 1; + return 0; + } + + bool operator==(const Tuple& value)const{ return Compare(*this, value) == 0; } + bool operator!=(const Tuple& value)const{ return Compare(*this, value) != 0; } + bool operator< (const Tuple& value)const{ return Compare(*this, value) < 0; } + bool operator<=(const Tuple& value)const{ return Compare(*this, value) <= 0; } + bool operator> (const Tuple& value)const{ return Compare(*this, value) > 0; } + bool operator>=(const Tuple& value)const{ return Compare(*this, value) >= 0; } + }; + +/*********************************************************************** +vl::Tuple +***********************************************************************/ + template + class Tuple : public Object + { + public: + T0 f0;T1 f1;T2 f2;T3 f3;T4 f4;T5 f5;T6 f6;T7 f7;T8 f8; + + Tuple() + { + } + + Tuple(T0 p0,T1 p1,T2 p2,T3 p3,T4 p4,T5 p5,T6 p6,T7 p7,T8 p8) + :f0(p0),f1(p1),f2(p2),f3(p3),f4(p4),f5(p5),f6(p6),f7(p7),f8(p8) + { + } + + static int Compare(const Tuple& a, const Tuple& b) + { + if (a.f0 < b.f0) return -1; else if (a.f0 > b.f0) return 1;if (a.f1 < b.f1) return -1; else if (a.f1 > b.f1) return 1;if (a.f2 < b.f2) return -1; else if (a.f2 > b.f2) return 1;if (a.f3 < b.f3) return -1; else if (a.f3 > b.f3) return 1;if (a.f4 < b.f4) return -1; else if (a.f4 > b.f4) return 1;if (a.f5 < b.f5) return -1; else if (a.f5 > b.f5) return 1;if (a.f6 < b.f6) return -1; else if (a.f6 > b.f6) return 1;if (a.f7 < b.f7) return -1; else if (a.f7 > b.f7) return 1;if (a.f8 < b.f8) return -1; else if (a.f8 > b.f8) return 1; + return 0; + } + + bool operator==(const Tuple& value)const{ return Compare(*this, value) == 0; } + bool operator!=(const Tuple& value)const{ return Compare(*this, value) != 0; } + bool operator< (const Tuple& value)const{ return Compare(*this, value) < 0; } + bool operator<=(const Tuple& value)const{ return Compare(*this, value) <= 0; } + bool operator> (const Tuple& value)const{ return Compare(*this, value) > 0; } + bool operator>=(const Tuple& value)const{ return Compare(*this, value) >= 0; } + }; + +/*********************************************************************** +vl::Tuple +***********************************************************************/ + template + class Tuple : public Object + { + public: + T0 f0;T1 f1;T2 f2;T3 f3;T4 f4;T5 f5;T6 f6;T7 f7;T8 f8;T9 f9; + + Tuple() + { + } + + Tuple(T0 p0,T1 p1,T2 p2,T3 p3,T4 p4,T5 p5,T6 p6,T7 p7,T8 p8,T9 p9) + :f0(p0),f1(p1),f2(p2),f3(p3),f4(p4),f5(p5),f6(p6),f7(p7),f8(p8),f9(p9) + { + } + + static int Compare(const Tuple& a, const Tuple& b) + { + if (a.f0 < b.f0) return -1; else if (a.f0 > b.f0) return 1;if (a.f1 < b.f1) return -1; else if (a.f1 > b.f1) return 1;if (a.f2 < b.f2) return -1; else if (a.f2 > b.f2) return 1;if (a.f3 < b.f3) return -1; else if (a.f3 > b.f3) return 1;if (a.f4 < b.f4) return -1; else if (a.f4 > b.f4) return 1;if (a.f5 < b.f5) return -1; else if (a.f5 > b.f5) return 1;if (a.f6 < b.f6) return -1; else if (a.f6 > b.f6) return 1;if (a.f7 < b.f7) return -1; else if (a.f7 > b.f7) return 1;if (a.f8 < b.f8) return -1; else if (a.f8 > b.f8) return 1;if (a.f9 < b.f9) return -1; else if (a.f9 > b.f9) return 1; + return 0; + } + + bool operator==(const Tuple& value)const{ return Compare(*this, value) == 0; } + bool operator!=(const Tuple& value)const{ return Compare(*this, value) != 0; } + bool operator< (const Tuple& value)const{ return Compare(*this, value) < 0; } + bool operator<=(const Tuple& value)const{ return Compare(*this, value) <= 0; } + bool operator> (const Tuple& value)const{ return Compare(*this, value) > 0; } + bool operator>=(const Tuple& value)const{ return Compare(*this, value) >= 0; } + }; + +} #endif /*********************************************************************** .\COLLECTIONS\PAIR.H ***********************************************************************/ /*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -Data Structure::Pair - -Classes: - Pair : Pair +Author: Zihan Chen (vczh) +Licensed under https://github.com/vczh-libraries/License ***********************************************************************/ #ifndef VCZH_COLLECTIONS_PAIR @@ -2681,13 +3373,8 @@ namespace vl .\COLLECTIONS\INTERFACES.H ***********************************************************************/ /*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -Data Structure::Interfaces - -Interfaces: - IEnumerator : Enumerator interface - IEnumerable : Enumerable object interface +Author: Zihan Chen (vczh) +Licensed under https://github.com/vczh-libraries/License ***********************************************************************/ #ifndef VCZH_COLLECTIONS_INTERFACES @@ -2703,8 +3390,8 @@ namespace vl Interfaces ***********************************************************************/ - /// Enumerator. - /// Type of the elements in the enumerator. + /// An enumerator interface for receiving values without going back. + /// Type of the values returned from the enumerator. template class IEnumerator : public virtual Interface { @@ -2714,30 +3401,79 @@ Interfaces /// Copy the enumerator with the current state. /// The copied enumerator. virtual IEnumerator* Clone()const=0; - /// Get the reference to the current element in the enumerator. - /// The reference to the current element. + /// Get the reference to the current value in the enumerator. + /// The reference to the current value. + /// + /// After calling , need to be called to make the first value available. + /// Return value of will be changed after each time is called. + /// If returns false, the behavior of is undefined. + /// virtual const T& Current()const=0; - /// Get the position of the current element in the enumerator. - /// The position of the current element. + /// Get the position of the current value in the enumerator. + /// The position of the current value. + /// + /// After calling , need to be called to make the first value available. + /// Index will be increased after each time is called with true returned. + /// virtual vint Index()const=0; - /// Step forward. - /// Returns false if the enumerator reaches the end. + /// Prepare for the next value. + /// Returns false if there is no more value. virtual bool Next()=0; /// Reset the enumerator. virtual void Reset()=0; - + /// Test if all values of this enumerator have been evaluated. + /// Returns true if all values have been evaluated. + /// An evaluated enumerator typically means, there will be no more calculation happens in regardless if all values have been read or not. virtual bool Evaluated()const{return false;} }; - /// Enumerable. - /// Type of the elements in the enumerator. + /// + /// An enumerable interface representing all types that provide multiple values in order. + /// range-based for-loop is not supported on enumerable yet, current we have "FOREACH" and "FOREACH_INDEXER" for iterating values. + /// functions work for all enumerable implementation. + /// provides high-level operations for enumerables, you can create a lazy list by calling on any enumerables. + /// + /// xs; + /// for (vint i = 0; i < 10; i++) + /// xs.Add(i); + /// List ys; + /// + /// // replace values in ys using xs, it could also be appending instead of replacing, which is controlled by the third argument + /// CopyFrom(ys, xs); + /// + /// // print ys + /// FOREACH(vint, y, ys) + /// Console::Write(itow(y) + L" "); + /// Console::WriteLine(L""); + /// + /// // print ys, added by the position + /// FOREACH_INDEXER(vint, y, i, ys) + /// Console::Write(itow(y + i) + L" "); + /// Console::WriteLine(L""); + /// + /// // print all odd numbers in ys + /// FOREACH(vint, y, From(ys).Where([](int a){return a % 2 == 1;})) + /// Console::Write(itow(y) + L" "); + /// Console::WriteLine(L""); + /// } + /// ]]> + /// Type of the values in the enumerable. template class IEnumerable : public virtual Interface { public: typedef T ElementType; - /// Create an enumerator. [M:vl.collections.IEnumerator`1.Next] should be called to get the first element. + /// + /// Create an enumerator. [M:vl.collections.IEnumerator`1.Next] should be called before reading the first value. + /// + /// + /// In most of the cases, you do not need to call this function. + /// "FOREACH", "FOREACH_INDEXER", and do all the jobs for you. + /// /// The enumerator. virtual IEnumerator* CreateEnumerator()const=0; }; @@ -2794,16 +3530,8 @@ Random Access .\COLLECTIONS\LIST.H ***********************************************************************/ /*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -Data Structure::List - -Classes: - ListStore : Array copy helper functions - ListBase : Base class for array - Array : Array - List : List - SortedList : List with item order maintained +Author: Zihan Chen (vczh) +Licensed under https://github.com/vczh-libraries/License ***********************************************************************/ #ifndef VCZH_COLLECTIONS_LIST @@ -2985,31 +3713,36 @@ ArrayBase index = _index; } - IEnumerator* Clone()const + IEnumerator* Clone()const override { return new Enumerator(container, index); } - const T& Current()const + const T& Current()const override { return container->Get(index); } - vint Index()const + vint Index()const override { return index; } - bool Next() + bool Next() override { index++; return index >= 0 && index < container->Count(); } - void Reset() + void Reset() override { index = -1; } + + bool Evaluated()const override + { + return true; + } }; void* buffer = nullptr; @@ -3047,7 +3780,7 @@ ArrayBase } /// Get the reference to the specified element. - /// The reference to the specified element. + /// The reference to the specified element. It will crash when the index is out of range. /// The index of the element. const T& Get(vint index)const { @@ -3056,7 +3789,7 @@ ArrayBase } /// Get the reference to the specified element. - /// The reference to the specified element. + /// The reference to the specified element. It will crash when the index is out of range. /// The index of the element. const T& operator[](vint index)const { @@ -3069,27 +3802,34 @@ ArrayBase Array ***********************************************************************/ - /// Array. + /// Array: linear container with fixed size in runtime. All elements are contiguous in memory. /// Type of elements. - /// Type of the key type of elements. + /// Type of the key type of elements. It is recommended to use the default value. template::Type> class Array : public ArrayBase { public: /// Create an array. /// The size of the array. + /// + /// The default value is zero. can be called to determine the size later. + /// It will crash when the size is a negative number. + /// Array(vint size = 0) { + CHECK_ERROR(size >= 0, L"Array::Array(vint)#Size should not be negative."); this->buffer = this->AllocateBuffer(size); this->InitializeItemsByDefault(this->buffer, size); this->count = size; } - /// Create an array. - /// Pointer to an array to copy. - /// The size of the array. + /// Create an array with elements provided. + /// Pointer to values to copy. + /// The number of values to copy. + /// It will crash when the size is a negative number. Array(const T* _buffer, vint size) { + CHECK_ERROR(size >= 0, L"Array::Array(const T*, vint)#Size should not be negative."); this->buffer = this->AllocateBuffer(size); this->InitializeItemsByCopy(this->buffer, (void*)_buffer, size); this->count = size; @@ -3101,17 +3841,17 @@ Array this->DeallocateBuffer(this->buffer); } - /// Test does the array contain an item or not. - /// Returns true if the array contains the specified item. - /// The item to test. + /// Test does the array contain a value or not. + /// Returns true if the array contains the specified value. + /// The value to test. bool Contains(const K& item)const { return IndexOf(item) != -1; } - /// Get the position of an item in this array. - /// Returns the position. Returns -1 if not exists - /// The item to find. + /// Get the position of a value in this array. + /// Returns the position of first element that equals to the specified value. Returns -1 if failed to find. + /// The value to find. vint IndexOf(const K& item)const { for (vint i = 0; i < this->count; i++) @@ -3124,29 +3864,34 @@ Array return -1; } - /// Replace an item. - /// The position of the item. - /// The new item to put into the array. - void Set(vint index, const T& item) + /// Replace an element in the specified position. + /// Returns true if this operation succeeded. It will crash when the index is out of range + /// The position of the element to replace. + /// The new value to replace. + bool Set(vint index, const T& item) { CHECK_ERROR(index >= 0 && index < this->count, L"Array::Set(vint)#Argument index not in range."); this->ItemOf(index) = item; + return true; } - /// Get the reference to the specified element. - /// The reference to the specified element. - /// The index of the element. using ArrayBase::operator[]; + + /// Get the reference to the specified element. + /// The reference to the specified element. It will crash when the index is out of range. + /// The index of the element. T& operator[](vint index) { CHECK_ERROR(index >= 0 && index < this->count, L"Array::operator[](vint)#Argument index not in range."); return this->ItemOf(index); } - /// Change the size of the array. + /// Change the size of the array. This function can be called multiple times to change the size. /// The new size of the array. + /// It will crash when the size is a negative number. void Resize(vint size) { + CHECK_ERROR(size >= 0, L"Array::Resize(vint)#Size should not be negative."); void* newBuffer = this->AllocateBuffer(size); if (size < this->count) { @@ -3169,9 +3914,9 @@ Array ListBase ***********************************************************************/ - /// Base type for a list container. + /// Base type for all list containers. /// Type of elements. - /// Type of the key type of elements. + /// Type of the key type of elements. It is recommended to use the default value. template::Type> class ListBase abstract : public ArrayBase { @@ -3255,14 +4000,17 @@ ListBase } /// Set a preference of using memory. - /// Set to true (by default) to let the container efficiently reduce memory usage when necessary. + /// + /// Set to true (by default) to let the container actively reduce memories when there is too much room for unused elements. + /// This could happen after removing a lot of elements. + /// void SetLessMemoryMode(bool mode) { this->lessMemoryMode = mode; } - /// Remove an element. - /// Returns true if the element is removed. + /// Remove an element at a specified position. + /// Returns true if the element is removed. It will crash when the index is out of range. /// The index of the element to remove. bool RemoveAt(vint index) { @@ -3274,8 +4022,8 @@ ListBase return true; } - /// Remove elements. - /// Returns true if the element is removed. + /// Remove contiguous elements at a specified psition. + /// Returns true if elements are removed. It will crash when the index or the size is out of range. /// The index of the first element to remove. /// The number of elements to remove. bool RemoveRange(vint index, vint _count) @@ -3314,29 +4062,27 @@ ListBase List ***********************************************************************/ - /// List. + /// List: linear container with dynamic size in runtime for unordered values. All elements are contiguous in memory. /// Type of elements. - /// Type of the key type of elements. + /// Type of the key type of elements. It is recommended to use the default value. template::Type> class List : public ListBase { public: - /// Create a list. - List() - { - } + /// Create an empty list. + List() = default; - /// Test does the list contain an item or not. - /// Returns true if the list contains the specified item. - /// The item to test. + /// Test does the list contain a value or not. + /// Returns true if the list contains the specified value. + /// The value to test. bool Contains(const K& item)const { return IndexOf(item) != -1; } - /// Get the position of an item in this list. - /// Returns the position. Returns -1 if not exists - /// The item to find. + /// Get the position of a value in this list. + /// Returns the position of first element that equals to the specified value. Returns -1 if failed to find. + /// The value to find. vint IndexOf(const K& item)const { for (vint i = 0; i < this->count; i++) @@ -3349,18 +4095,18 @@ List return -1; } - /// Add an item at the end of the list. + /// Append a value at the end of the list. /// The index of the added item. - /// The item to add. + /// The value to add. vint Add(const T& item) { return Insert(this->count, item); } - /// Add an item at the specified position. - /// The index of the added item. - /// The position of the item to add. - /// The item to add. + /// Insert a value at the specified position. + /// The index of the added item. It will crash if the index is out of range + /// The position to insert the value. + /// The value to add. vint Insert(vint index, const T& item) { CHECK_ERROR(index >= 0 && index <= this->count, L"List::Insert(vint, const T&)#Argument index not in range."); @@ -3377,8 +4123,8 @@ List return index; } - /// Remove an item. - /// Returns true if the item is removed. + /// Remove an element from the list. If multiple elements equal to the specified value, only the first one will be removed + /// Returns true if the element is removed. /// The item to remove. bool Remove(const K& item) { @@ -3394,10 +4140,10 @@ List } } - /// Replace an item. - /// Returns true if this operation succeeded. - /// The position of the item. - /// The new item to put into the array. + /// Replace an element in the specified position. + /// Returns true if this operation succeeded. It will crash when the index is out of range + /// The position of the element to replace. + /// The new value to replace. bool Set(vint index, const T& item) { CHECK_ERROR(index >= 0 && index < this->count, L"List::Set(vint)#Argument index not in range."); @@ -3405,10 +4151,11 @@ List return true; } - /// Get the reference to the specified element. - /// The reference to the specified element. - /// The index of the element. using ListBase::operator[]; + + /// Get the reference to the specified element. + /// The reference to the specified element. It will crash when the index is out of range. + /// The index of the element. T& operator[](vint index) { CHECK_ERROR(index >= 0 && index < this->count, L"List::operator[](vint)#Argument index not in range."); @@ -3420,19 +4167,24 @@ List SortedList ***********************************************************************/ - /// List that keeps everything in order. + /// SortedList: linear container with dynamic size in runtime for ordered values. All elements are kept in order, and are contiguous in memory. /// Type of elements. - /// Type of the key type of elements. + /// Type of the key type of elements. It is recommended to use the default value. template::Type> class SortedList : public ListBase { protected: - /// Get the position of an item in this list. - /// Type of the item to find. - /// Returns the position. Returns -1 if not exists - /// The item to find. - /// Returns the last index. + /// Get the position of an element in this list by performing binary search. + /// Type of the element to find. + /// Returns the position. Returns -1 if it does not exist. + /// The element to find. + /// + /// If the element exist, this argument returns one of the element that equals to the specified value. + /// If the element doesn not exist, + /// this argument returns either the greatest element that less than the specified value, + /// or the lest element that greater than the specified value. + /// template vint IndexOfInternal(const Key& item, vint& index)const { @@ -3473,31 +4225,29 @@ SortedList return index; } public: - /// Create a list. - SortedList() - { - } + /// Create an empty list. + SortedList() = default; - /// Test does the list contain an item or not. - /// Returns true if the list contains the specified item. - /// The item to test. + /// Test does the list contain a value or not. + /// Returns true if the list contains the specified value. + /// The value to test. bool Contains(const K& item)const { return IndexOf(item) != -1; } - /// Get the position of an item in this list. - /// Returns the position. Returns -1 if not exists - /// The item to find. + /// Get the position of a value in this list. + /// Returns the position of first element that equals to the specified value. Returns -1 if failed to find. + /// The value to find. vint IndexOf(const K& item)const { vint outputIndex = -1; return IndexOfInternal(item, outputIndex); } - /// Add an item at a correct position to keep everying in order. + /// Add a value at the correct position, all elements will be kept in order. /// The index of the added item. - /// The item to add. + /// The value to add. vint Add(const T& item) { if (ArrayBase::count == 0) @@ -3517,8 +4267,8 @@ SortedList } } - /// Remove an item. - /// Returns true if the item is removed. + /// Remove an element from the list. If multiple elements equal to the specified value, only the first one will be removed + /// Returns true if the element is removed. /// The item to remove. bool Remove(const K& item) { @@ -3598,7 +4348,7 @@ Special Containers { if (!root) { - return 0; + return nullptr; } vint fragmentIndex = (index >> (2 * (Index - 1))) % 4; TreeNode* fragmentRoot = root->nodes[fragmentIndex]; @@ -3639,17 +4389,11 @@ Special Containers public: typedef PushOnlyAllocator Allocator; protected: - bom_helper::TreeNode* root; + bom_helper::TreeNode* root = nullptr; public: - ByteObjectMap() - :root(0) - { - } - - ~ByteObjectMap() - { - } + ByteObjectMap() = default; + ~ByteObjectMap() = default; T* Get(vuint8_t index) { @@ -3699,14 +4443,671 @@ Random Access #endif +/*********************************************************************** +.\COLLECTIONS\DICTIONARY.H +***********************************************************************/ +/*********************************************************************** +Author: Zihan Chen (vczh) +Licensed under https://github.com/vczh-libraries/License +***********************************************************************/ + +#ifndef VCZH_COLLECTIONS_DICTIONARY +#define VCZH_COLLECTIONS_DICTIONARY + + +namespace vl +{ + namespace collections + { + /// Dictionary: one to one map container. + /// Type of keys. + /// Type of values. + /// Type of the key type of keys. It is recommended to use the default value. + /// Type of the key type of values. It is recommended to use the default value. + template< + typename KT, + typename VT, + typename KK=typename KeyType::Type, + typename VK=typename KeyType::Type + > + class Dictionary : public Object, public virtual IEnumerable> + { + public: + typedef SortedList KeyContainer; + typedef List ValueContainer; + protected: + class Enumerator : public Object, public virtual IEnumerator> + { + private: + const Dictionary* container; + vint index; + Pair current; + + void UpdateCurrent() + { + if(indexCount()) + { + current.key=container->Keys().Get(index); + current.value=container->Values().Get(index); + } + } + public: + Enumerator(const Dictionary* _container, vint _index=-1) + { + container=_container; + index=_index; + } + + IEnumerator>* Clone()const override + { + return new Enumerator(container, index); + } + + const Pair& Current()const override + { + return current; + } + + vint Index()const override + { + return index; + } + + bool Next() override + { + index++; + UpdateCurrent(); + return index>=0 && indexCount(); + } + + void Reset() override + { + index=-1; + UpdateCurrent(); + } + + bool Evaluated()const override + { + return true; + } + }; + + KeyContainer keys; + ValueContainer values; + public: + /// Create an empty dictionary. + Dictionary() = default; + + IEnumerator>* CreateEnumerator()const + { + return new Enumerator(this); + } + + /// Set a preference of using memory. + /// + /// Set to true (by default) to let the container actively reduce memories when there is too much room for unused elements. + /// This could happen after removing a lot of elements. + /// + void SetLessMemoryMode(bool mode) + { + keys.SetLessMemoryMode(mode); + values.SetLessMemoryMode(mode); + } + + /// Get all keys. + /// All keys. + const KeyContainer& Keys()const + { + return keys; + } + + /// Get all values. + /// All values. + const ValueContainer& Values()const + { + return values; + } + + /// Get the number of keys. + /// The number of keys. It is also the number of values. + vint Count()const + { + return keys.Count(); + } + + /// Get the reference to the value associated to a specified key. + /// The reference to the value. It will crash if the key does not exist. + /// The key to find. + const VT& Get(const KK& key)const + { + return values.Get(keys.IndexOf(key)); + } + + /// Get the reference to the value associated to a specified key. + /// The reference to the value. It will crash if the key does not exist. + /// The key to find. + const VT& operator[](const KK& key)const + { + return values.Get(keys.IndexOf(key)); + } + + /// Replace the value associated to a specified key. + /// Returns true if the value is replaced. + /// The key to find. If the key does not exist, it will be added to the dictionary. + /// The associated value to replace. + bool Set(const KT& key, const VT& value) + { + vint index=keys.IndexOf(KeyType::GetKeyValue(key)); + if(index==-1) + { + index=keys.Add(key); + values.Insert(index, value); + } + else + { + values[index]=value; + } + return true; + } + + /// Add a key with an associated value. + /// Returns true if the pair is added. If will crash if the key exists. + /// The pair of key and value. + bool Add(const Pair& value) + { + return Add(value.key, value.value); + } + + /// Add a key with an associated value. + /// Returns true if the pair is added. If will crash if the key exists. + /// The key to add. + /// The value to add. + bool Add(const KT& key, const VT& value) + { + CHECK_ERROR(!keys.Contains(KeyType::GetKeyValue(key)), L"Dictionary::Add(const KT&, const VT&)#Key already exists."); + vint index=keys.Add(key); + values.Insert(index, value); + return true; + } + + /// Remove a key with the associated value. + /// Returns true if the key and the value is removed. + /// The key to find. + bool Remove(const KK& key) + { + vint index=keys.IndexOf(key); + if(index!=-1) + { + keys.RemoveAt(index); + values.RemoveAt(index); + return true; + } + else + { + return false; + } + } + + /// Remove all elements. + /// Returns true if all elements are removed. + bool Clear() + { + keys.Clear(); + values.Clear(); + return true; + } + }; + + /// Group: one to many map container. + /// Type of keys. + /// Type of values. + /// Type of the key type of keys. It is recommended to use the default value. + /// Type of the key type of values. It is recommended to use the default value. + template< + typename KT, + typename VT, + typename KK=typename KeyType::Type, + typename VK=typename KeyType::Type + > + class Group : public Object, public virtual IEnumerable> + { + public: + typedef SortedList KeyContainer; + typedef List ValueContainer; + protected: + class Enumerator : public Object, public virtual IEnumerator> + { + private: + const Group* container; + vint keyIndex; + vint valueIndex; + Pair current; + + void UpdateCurrent() + { + if(keyIndexCount()) + { + const ValueContainer& values=container->GetByIndex(keyIndex); + if(valueIndexKeys().Get(keyIndex); + current.value=values.Get(valueIndex); + } + } + } + public: + Enumerator(const Group* _container, vint _keyIndex=-1, vint _valueIndex=-1) + { + container=_container; + keyIndex=_keyIndex; + valueIndex=_valueIndex; + } + + IEnumerator>* Clone()const override + { + return new Enumerator(container, keyIndex, valueIndex); + } + + const Pair& Current()const override + { + return current; + } + + vint Index()const override + { + if(0<=keyIndex && keyIndexCount()) + { + vint index=0; + for(vint i=0;iGetByIndex(i).Count(); + } + return index+valueIndex; + } + else + { + return -1; + } + } + + bool Next() override + { + if(keyIndex==-1) + { + keyIndex=0; + } + while(keyIndexCount()) + { + valueIndex++; + const ValueContainer& values=container->GetByIndex(keyIndex); + if(valueIndex values; + public: + /// Create an empty group. + Group() = default; + + ~Group() + { + Clear(); + } + + IEnumerator>* CreateEnumerator()const + { + return new Enumerator(this); + } + + /// Get all keys. + /// All keys. + const KeyContainer& Keys()const + { + return keys; + } + + /// Get the number of keys. + /// The number of keys. + vint Count()const + { + return keys.Count(); + } + + /// Get all values associated to a specified key. + /// All associated values. It will crash if the key does not exist. + /// The key to find. + const ValueContainer& Get(const KK& key)const + { + return *values.Get(keys.IndexOf(key)); + } + + /// Get all values associated to a key at a specified index in . + /// All associaged values. It will crash if the index is out of range. + /// The position of the key. + const ValueContainer& GetByIndex(vint index)const + { + return *values.Get(index); + } + + /// Get all values associated to a specified key. + /// All associated values. It will crash if the key does not exist. + /// The key to find. + const ValueContainer& operator[](const KK& key)const + { + return *values.Get(keys.IndexOf(key)); + } + + /// Test if there is any value associated to a specified key or not. + /// Returns true there is at least one value associated to this key. + /// The key to find. + bool Contains(const KK& key)const + { + return keys.Contains(key); + } + + /// Test if a value is associated to a specified key or not. + /// Returns true if the specified value is associated to the specified key. + /// The key to find. + /// The value to find. + bool Contains(const KK& key, const VK& value)const + { + vint index=keys.IndexOf(key); + if(index!=-1) + { + return values.Get(index)->Contains(value); + } + else + { + return false; + } + } + + /// + /// Add a key with an associated value. + /// If the key already exists, the value will be associated to the key with other values. + /// If this value has already been associated to the key, it will still be duplicated. + /// + /// Returns true if the pair is added. + /// The pair of key and value to add. + bool Add(const Pair& value) + { + return Add(value.key, value.value); + } + + /// + /// Add a key with an associated value. + /// If the key already exists, the value will be associated to the key with other values. + /// If this value has already been associated to the key, it will still be duplicated. + /// + /// Returns true if the key and the value are added. + /// The key to add. + /// The value to add. + bool Add(const KT& key, const VT& value) + { + ValueContainer* target=0; + vint index=keys.IndexOf(KeyType::GetKeyValue(key)); + if(index==-1) + { + target=new ValueContainer; + values.Insert(keys.Add(key), target); + } + else + { + target=values[index]; + } + target->Add(value); + return true; + } + + /// Remove a key with all associated values. + /// Returns true if the key and all associated values are removed. + /// The key to find. + bool Remove(const KK& key) + { + vint index=keys.IndexOf(key); + if(index!=-1) + { + keys.RemoveAt(index); + List* target=values[index]; + values.RemoveAt(index); + delete target; + return true; + } + else + { + return false; + } + } + + /// Remove a value associated to a specified key. + /// + /// Returns true if the value is removed. + /// If this value is associated to the key for jultiple times, only the first one will be removed. + /// If this value is associated to the key for jultiple times, only the first one will be removed. + /// + /// The key to find. + /// The value to remove. + bool Remove(const KK& key, const VK& value) + { + vint index=keys.IndexOf(key); + if(index!=-1) + { + List* target=values[index]; + target->Remove(value); + if(target->Count()==0) + { + keys.RemoveAt(index); + values.RemoveAt(index); + delete target; + } + return true; + } + else + { + return false; + } + } + + /// Remove everything. + /// Returns true if all keys and values are removed. + bool Clear() + { + for(vint i=0;iPerform inner join on two groups. + /// The type of keys in two groups. + /// The type of values in the first group. + /// The type of values in the second group. + /// The type of the first callback. + /// The type of the second callback. + /// The type of the third callback. + /// The first group. + /// The second group. + /// + /// Callback that is called when a value in the first group is discarded. + /// This happens for values associated to a key in the first group, that no value is assocated to the same key in the second group. + /// The first argument is the key, the second argument is the discarded value in the first group. + /// + /// + /// Callback that is called when a value in the second group is discarded. + /// This happens for values associated to a key in the second group, that no value is assocated to the same key in the first group. + /// The first argument is the key, the second argument is the discarded value in the first group. + /// + /// + /// Callback that is called when a match of values in both groups are found. + /// This happens for any key that, values are associated to this key in both group. + /// If multiple values are associated to this key in both group, cartesian product applies on values. + /// The first argument is the key, the second argument is the associated value in the first group, the third argument is the associated value in the second group. + /// + /// + /// This function does not change data in provided groups. + /// + /// as, bs; + /// as.Add(1 ,L"A"); as.Add(1 ,L"B"); as.Add(2 ,L"C"); as.Add(2 ,L"D"); + /// bs.Add(1 ,L"X"); bs.Add(1 ,L"Y"); as.Add(3 ,L"Z"); as.Add(3 ,L"W"); + /// GroupInnerJoin( + /// as, + /// bs, + /// [](vint key, const WString& value) { Console::WriteLine(L"Discarded in as: " + itow(key) + L", " + value); }, + /// [](vint key, const WString& value) { Console::WriteLine(L"Discarded in bs: " + itow(key) + L", " + value); }, + /// [](vint key, const WString& value1, const WString& value 2) { Console::WriteLine(L"Accepted: " + itow(key) + L", " + value1 + L", " + value2); } + /// ); + /// } + /// ]]> + template< + typename TKey, + typename TValueFirst, + typename TValueSecond, + typename TDiscardFirst, // TKey * [TValueFirst] -> void + typename TDiscardSecond, // TKey * [TValueSecond] -> void + typename TAccept // TKey * [TValueFirst] * [TValueSecond] -> void + > + void GroupInnerJoin( + const Group& first, + const Group& second, + const TDiscardFirst& discardFirst, + const TDiscardSecond& discardSecond, + const TAccept& accept + ) + { + vint firstIndex = 0; + vint secondIndex = 0; + vint firstCount = first.Keys().Count(); + vint secondCount = second.Keys().Count(); + while (true) + { + if (firstIndex < firstCount) + { + auto firstKey = first.Keys()[firstIndex]; + const List& firstValues = first.GetByIndex(firstIndex); + + if (secondIndex < secondCount) + { + auto secondKey = second.Keys()[secondIndex]; + const List& secondValues = second.GetByIndex(secondIndex); + + if (firstKey < secondKey) + { + discardFirst(firstKey, firstValues); + firstIndex++; + } + else if (firstKey > secondKey) + { + discardSecond(secondKey, secondValues); + secondIndex++; + } + else + { + accept(firstKey, firstValues, secondValues); + firstIndex++; + secondIndex++; + } + } + else + { + discardFirst(firstKey, firstValues); + firstIndex++; + } + } + else + { + if (secondIndex < secondCount) + { + auto secondKey = second.Keys()[secondIndex]; + const List& secondValues = second.GetByIndex(secondIndex); + + discardSecond(secondKey, secondValues); + secondIndex++; + } + else + { + break; + } + } + } + } + +/*********************************************************************** +Random Access +***********************************************************************/ + namespace randomaccess_internal + { + template + struct RandomAccessable> + { + static const bool CanRead = true; + static const bool CanResize = false; + }; + + template + struct RandomAccess> + { + static vint GetCount(const Dictionary& t) + { + return t.Count(); + } + + static Pair GetValue(const Dictionary& t, vint index) + { + return Pair(t.Keys().Get(index), t.Values().Get(index)); + } + + static void AppendValue(Dictionary& t, const Pair& value) + { + t.Set(value.key, value.value); + } + }; + } + } +} + +#endif + /*********************************************************************** .\COLLECTIONS\OPERATIONCOPYFROM.H ***********************************************************************/ /*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -Data Structure::Operations - +Author: Zihan Chen (vczh) +Licensed under https://github.com/vczh-libraries/License ***********************************************************************/ #ifndef VCZH_COLLECTIONS_OPERATIONCOPYFROM @@ -3840,42 +5241,42 @@ Copy Functions for Containers } /// Copy containers. - /// Type of the destination container. + /// Type of the target container. /// Type of the source container. - /// The destination container. + /// The target container. /// The source container. - /// Set to false to delete everything in the destination container before copying. + /// Set to true to perform appending instead of replacing. template - void CopyFrom(Ds& ds, const Ss& ss, bool append=false) + void CopyFrom(Ds& ds, const Ss& ss, bool append = false) { copyfrom_internal::CopyFromAlgorithm::CanResize, randomaccess_internal::RandomAccessable::CanRead>::Perform(ds, ss, append); } /// Copy containers. - /// Type of the destination container. - /// Type of the elements in the source container. - /// The destination container. - /// Pointer to the source array. - /// The number of elements to copy. - /// Set to false to delete everything in the destination container before copying. + /// Type of the target container. + /// Type of values in the source container. + /// The target container. + /// Pointer to source values. + /// The number of values to copy. + /// Set to true to perform appending instead of replacing. template - void CopyFrom(Ds& ds, const S* buffer, vint count, bool append=false) + void CopyFrom(Ds& ds, const S* buffer, vint count, bool append = false) { - copyfrom_internal::Slice slice={buffer, count}; + copyfrom_internal::Slice slice = { buffer, count }; CopyFrom(ds, slice, append); } - + /// Copy containers. - /// Type of the destination container. - /// Type of the elements in the source container. - /// The destination container. - /// Pointer to the first element in the source array. - /// Pointer to the element after the last element in the source array. - /// Set to false to delete everything in the destination container before copying. + /// Type of the target container. + /// Type of values in the source container. + /// The target container. + /// Pointer to the first source value. + /// Pointer to the value after the last source value. + /// Set to true to perform appending instead of replacing. template - void CopyFrom(Ds& ds, const S* begin, const S* end, bool append=false) + void CopyFrom(Ds& ds, const S* begin, const S* end, bool append = false) { - copyfrom_internal::Slice slice={begin, end-begin}; + copyfrom_internal::Slice slice = { begin, end - begin }; CopyFrom(ds, slice, append); } } @@ -3887,10 +5288,8 @@ Copy Functions for Containers .\COLLECTIONS\OPERATIONENUMERABLE.H ***********************************************************************/ /*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -Data Structure::Operations - +Author: Zihan Chen (vczh) +Licensed under https://github.com/vczh-libraries/License ***********************************************************************/ #ifndef VCZH_COLLECTIONS_OPERATIONENUMERABLE @@ -4067,26 +5466,43 @@ ContainerEnumerator CompareEnumerable ***********************************************************************/ + /// Compare two enumerables. + /// Type of elements in the first enumerable. + /// Type of elements in the second enumerable. + /// + /// Returns a positive value when the first enumerable is greater than the second enumerable. + /// Returns a negative value when the first enumerable is lesser than the second enumerable. + /// Returns zero when the two enumerables equal. + /// + /// The first enumerable to compare. + /// The second enumerable to compare. + /// + /// The comparison result is similar to comparing two strings. + /// When an enumerable contains no value but another one does, the empty one is lesser. + /// When an enumerable is the prefix of another one, the prefix is lesser. + /// When two enumerable contain the same values in the same order, they equals. + /// In other cases, the results represents the comparison result of the first pair of inequal values in enumerables. + /// template vint CompareEnumerable(const IEnumerable& a, const IEnumerable& b) { - Ptr> ator=a.CreateEnumerator(); - Ptr> btor=b.CreateEnumerator(); - while(true) + Ptr> ator = a.CreateEnumerator(); + Ptr> btor = b.CreateEnumerator(); + while (true) { - bool a=ator->Next(); - bool b=btor->Next(); - if(a&&!b) return 1; - if(!a&&b) return -1; - if(!a&&!b) break; + bool a = ator->Next(); + bool b = btor->Next(); + if (a && !b) return 1; + if (!a&&b) return -1; + if (!a && !b) break; - const T& ac=ator->Current(); - const U& bc=btor->Current(); - if(acCurrent(); + const U& bc = btor->Current(); + if (ac < bc) { return -1; } - else if(ac>bc) + else if (ac > bc) { return 1; } @@ -4117,177 +5533,12 @@ CompareEnumerable #endif -/*********************************************************************** -.\COLLECTIONS\OPERATIONSELECT.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -Data Structure::Operations - -***********************************************************************/ - -#ifndef VCZH_COLLECTIONS_OPERATIONSELECT -#define VCZH_COLLECTIONS_OPERATIONSELECT - - -namespace vl -{ - namespace collections - { - -/*********************************************************************** -Select -***********************************************************************/ - - template - class SelectEnumerator : public virtual IEnumerator - { - protected: - IEnumerator* enumerator; - Func selector; - K current; - public: - SelectEnumerator(IEnumerator* _enumerator, const Func& _selector, K _current=K()) - :enumerator(_enumerator) - ,selector(_selector) - ,current(_current) - { - } - - ~SelectEnumerator() - { - delete enumerator; - } - - IEnumerator* Clone()const override - { - return new SelectEnumerator(enumerator->Clone(), selector, current); - } - - const K& Current()const override - { - return current; - } - - vint Index()const override - { - return enumerator->Index(); - } - - bool Next()override - { - if(enumerator->Next()) - { - current=selector(enumerator->Current()); - return true; - } - else - { - return false; - } - } - - void Reset()override - { - enumerator->Reset(); - } - }; - } -} - -#endif - -/*********************************************************************** -.\COLLECTIONS\OPERATIONWHERE.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -Data Structure::Operations - -***********************************************************************/ - -#ifndef VCZH_COLLECTIONS_OPERATIONWHERE -#define VCZH_COLLECTIONS_OPERATIONWHERE - - -namespace vl -{ - namespace collections - { -/*********************************************************************** -Where -***********************************************************************/ - - template - class WhereEnumerator : public virtual IEnumerator - { - protected: - IEnumerator* enumerator; - Func selector; - vint index; - - public: - WhereEnumerator(IEnumerator* _enumerator, const Func& _selector, vint _index=-1) - :enumerator(_enumerator) - ,selector(_selector) - ,index(_index) - { - } - - ~WhereEnumerator() - { - delete enumerator; - } - - IEnumerator* Clone()const override - { - return new WhereEnumerator(enumerator->Clone(), selector, index); - } - - const T& Current()const override - { - return enumerator->Current(); - } - - vint Index()const override - { - return index; - } - - bool Next()override - { - while(enumerator->Next()) - { - if(selector(enumerator->Current())) - { - index++; - return true; - } - } - return false; - } - - void Reset()override - { - enumerator->Reset(); - index=-1; - } - }; - } -} - -#endif - /*********************************************************************** .\COLLECTIONS\OPERATIONCONCAT.H ***********************************************************************/ /*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -Data Structure::Operations - +Author: Zihan Chen (vczh) +Licensed under https://github.com/vczh-libraries/License ***********************************************************************/ #ifndef VCZH_COLLECTIONS_OPERATIONCONCAT @@ -4387,14 +5638,266 @@ Concat #endif +/*********************************************************************** +.\COLLECTIONS\OPERATIONFOREACH.H +***********************************************************************/ +/*********************************************************************** +Author: Zihan Chen (vczh) +Licensed under https://github.com/vczh-libraries/License +***********************************************************************/ + +#ifndef VCZH_COLLECTIONS_FOREACH +#define VCZH_COLLECTIONS_FOREACH + +namespace vl +{ + namespace collections + { + +/*********************************************************************** +ForEachIterator +***********************************************************************/ + + template + class ForEachIterator : public Object + { + public: + virtual bool Next(T& variable)const=0; + + operator bool()const + { + return true; + } + }; + +/*********************************************************************** +ForEachIterator for IEnumerable +***********************************************************************/ + + template + class EnumerableForEachIterator : public ForEachIterator + { + protected: + Ptr> enumerator; + public: + EnumerableForEachIterator(const IEnumerable& enumerable) + :enumerator(enumerable.CreateEnumerator()) + { + } + + EnumerableForEachIterator(const EnumerableForEachIterator& enumerableIterator) + :enumerator(enumerableIterator.enumerator) + { + } + + bool Next(T& variable)const + { + if(enumerator->Next()) + { + variable=enumerator->Current(); + return true; + } + else + { + return false; + } + } + }; + + template + EnumerableForEachIterator CreateForEachIterator(const IEnumerable& enumerable) + { + return enumerable; + } + +/*********************************************************************** +FOREACH and FOREACH_INDEXER +***********************************************************************/ + +#define FOREACH(TYPE, VARIABLE, COLLECTION)\ + SCOPE_VARIABLE(const ::vl::collections::ForEachIterator&, __foreach_iterator__, ::vl::collections::CreateForEachIterator(COLLECTION))\ + for(TYPE VARIABLE;__foreach_iterator__.Next(VARIABLE);) + +#define FOREACH_INDEXER(TYPE, VARIABLE, INDEXER, COLLECTION)\ + SCOPE_VARIABLE(const ::vl::collections::ForEachIterator&, __foreach_iterator__, ::vl::collections::CreateForEachIterator(COLLECTION))\ + SCOPE_VARIABLE(vint, INDEXER, 0)\ + for(TYPE VARIABLE;__foreach_iterator__.Next(VARIABLE);INDEXER++) + } +} + +#endif + +/*********************************************************************** +.\COLLECTIONS\OPERATIONPAIR.H +***********************************************************************/ +/*********************************************************************** +Author: Zihan Chen (vczh) +Licensed under https://github.com/vczh-libraries/License +***********************************************************************/ + +#ifndef VCZH_COLLECTIONS_OPERATIONPAIR +#define VCZH_COLLECTIONS_OPERATIONPAIR + + +namespace vl +{ + namespace collections + { + +/*********************************************************************** +Pairwise +***********************************************************************/ + + template + class PairwiseEnumerator : public virtual IEnumerator> + { + protected: + IEnumerator* enumerator1; + IEnumerator* enumerator2; + Pair current; + public: + PairwiseEnumerator(IEnumerator* _enumerator1, IEnumerator* _enumerator2, Pair _current=Pair()) + :enumerator1(_enumerator1) + ,enumerator2(_enumerator2) + ,current(_current) + { + } + + ~PairwiseEnumerator() + { + delete enumerator1; + delete enumerator2; + } + + IEnumerator>* Clone()const override + { + return new PairwiseEnumerator(enumerator1->Clone(), enumerator2->Clone(), current); + } + + const Pair& Current()const override + { + return current; + } + + vint Index()const override + { + return enumerator1->Index(); + } + + bool Next()override + { + if(enumerator1->Next() && enumerator2->Next()) + { + current=Pair(enumerator1->Current(), enumerator2->Current()); + return true; + } + else + { + return false; + } + } + + void Reset()override + { + enumerator1->Reset(); + enumerator2->Reset(); + } + + bool Evaluated()const override + { + return enumerator1->Evaluated() && enumerator2->Evaluated(); + } + }; + } +} + +#endif + +/*********************************************************************** +.\COLLECTIONS\OPERATIONSELECT.H +***********************************************************************/ +/*********************************************************************** +Author: Zihan Chen (vczh) +Licensed under https://github.com/vczh-libraries/License +***********************************************************************/ + +#ifndef VCZH_COLLECTIONS_OPERATIONSELECT +#define VCZH_COLLECTIONS_OPERATIONSELECT + + +namespace vl +{ + namespace collections + { + +/*********************************************************************** +Select +***********************************************************************/ + + template + class SelectEnumerator : public virtual IEnumerator + { + protected: + IEnumerator* enumerator; + Func selector; + K current; + public: + SelectEnumerator(IEnumerator* _enumerator, const Func& _selector, K _current=K()) + :enumerator(_enumerator) + ,selector(_selector) + ,current(_current) + { + } + + ~SelectEnumerator() + { + delete enumerator; + } + + IEnumerator* Clone()const override + { + return new SelectEnumerator(enumerator->Clone(), selector, current); + } + + const K& Current()const override + { + return current; + } + + vint Index()const override + { + return enumerator->Index(); + } + + bool Next()override + { + if(enumerator->Next()) + { + current=selector(enumerator->Current()); + return true; + } + else + { + return false; + } + } + + void Reset()override + { + enumerator->Reset(); + } + }; + } +} + +#endif + /*********************************************************************** .\COLLECTIONS\OPERATIONSEQUENCE.H ***********************************************************************/ /*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -Data Structure::Operations - +Author: Zihan Chen (vczh) +Licensed under https://github.com/vczh-libraries/License ***********************************************************************/ #ifndef VCZH_COLLECTIONS_OPERATIONSEQUENCE @@ -4829,10 +6332,8 @@ FromIterator .\COLLECTIONS\OPERATIONSET.H ***********************************************************************/ /*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -Data Structure::Operations - +Author: Zihan Chen (vczh) +Licensed under https://github.com/vczh-libraries/License ***********************************************************************/ #ifndef VCZH_COLLECTIONS_OPERATIONSET @@ -4915,102 +6416,12 @@ Intersect/Except #endif -/*********************************************************************** -.\COLLECTIONS\OPERATIONPAIR.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -Data Structure::Operations - -***********************************************************************/ - -#ifndef VCZH_COLLECTIONS_OPERATIONPAIR -#define VCZH_COLLECTIONS_OPERATIONPAIR - - -namespace vl -{ - namespace collections - { - -/*********************************************************************** -Pairwise -***********************************************************************/ - - template - class PairwiseEnumerator : public virtual IEnumerator> - { - protected: - IEnumerator* enumerator1; - IEnumerator* enumerator2; - Pair current; - public: - PairwiseEnumerator(IEnumerator* _enumerator1, IEnumerator* _enumerator2, Pair _current=Pair()) - :enumerator1(_enumerator1) - ,enumerator2(_enumerator2) - ,current(_current) - { - } - - ~PairwiseEnumerator() - { - delete enumerator1; - delete enumerator2; - } - - IEnumerator>* Clone()const override - { - return new PairwiseEnumerator(enumerator1->Clone(), enumerator2->Clone(), current); - } - - const Pair& Current()const override - { - return current; - } - - vint Index()const override - { - return enumerator1->Index(); - } - - bool Next()override - { - if(enumerator1->Next() && enumerator2->Next()) - { - current=Pair(enumerator1->Current(), enumerator2->Current()); - return true; - } - else - { - return false; - } - } - - void Reset()override - { - enumerator1->Reset(); - enumerator2->Reset(); - } - - bool Evaluated()const override - { - return enumerator1->Evaluated() && enumerator2->Evaluated(); - } - }; - } -} - -#endif - /*********************************************************************** .\COLLECTIONS\OPERATIONSTRING.H ***********************************************************************/ /*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -Data Structure::Operations - +Author: Zihan Chen (vczh) +Licensed under https://github.com/vczh-libraries/License ***********************************************************************/ #ifndef VCZH_COLLECTIONS_OPERATIONSTRING @@ -5021,26 +6432,38 @@ namespace vl { namespace collections { + /// Copy containers. + /// Type of the target container. + /// Type of code points in the source string. + /// The target container. + /// The source string. + /// Set to true to perform appending instead of replacing. template - void CopyFrom(Ds& ds, const ObjectString& ss, bool append=false) + void CopyFrom(Ds& ds, const ObjectString& ss, bool append = false) { - const S* buffer=ss.Buffer(); - vint count=ss.Length(); + const S* buffer = ss.Buffer(); + vint count = ss.Length(); CopyFrom(ds, buffer, count, append); } + /// Copy containers. + /// Type of code points in the target string. + /// Type of the source container. + /// The target string. + /// The source container. + /// Set to true to perform appending instead of replacing. template - void CopyFrom(ObjectString& ds, const Ss& ss, bool append=false) + void CopyFrom(ObjectString& ds, const Ss& ss, bool append = false) { Array da(ds.Buffer(), ds.Length()); CopyFrom(da, ss, append); - if(da.Count()==0) + if (da.Count() == 0) { - ds=ObjectString(); + ds = ObjectString(); } else { - ds=ObjectString(&da[0], da.Count()); + ds = ObjectString(&da[0], da.Count()); } } } @@ -5049,21 +6472,142 @@ namespace vl #endif /*********************************************************************** -.\COLLECTIONS\OPERATIONFOREACH.H +.\COLLECTIONS\OPERATIONWHERE.H ***********************************************************************/ /*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -Data Structure::Operations - -In order to let a container support FOREACH and FOREACH_INDEXER�� - Implement a global function overloading: IteratorType vl::collections::CreateForEachIterator(const CollectionType& collection); - CollectionType is the container type - IteratorType should inherit from ForEachIterator +Author: Zihan Chen (vczh) +Licensed under https://github.com/vczh-libraries/License ***********************************************************************/ -#ifndef VCZH_COLLECTIONS_FOREACH -#define VCZH_COLLECTIONS_FOREACH +#ifndef VCZH_COLLECTIONS_OPERATIONWHERE +#define VCZH_COLLECTIONS_OPERATIONWHERE + + +namespace vl +{ + namespace collections + { +/*********************************************************************** +Where +***********************************************************************/ + + template + class WhereEnumerator : public virtual IEnumerator + { + protected: + IEnumerator* enumerator; + Func selector; + vint index; + + public: + WhereEnumerator(IEnumerator* _enumerator, const Func& _selector, vint _index=-1) + :enumerator(_enumerator) + ,selector(_selector) + ,index(_index) + { + } + + ~WhereEnumerator() + { + delete enumerator; + } + + IEnumerator* Clone()const override + { + return new WhereEnumerator(enumerator->Clone(), selector, index); + } + + const T& Current()const override + { + return enumerator->Current(); + } + + vint Index()const override + { + return index; + } + + bool Next()override + { + while(enumerator->Next()) + { + if(selector(enumerator->Current())) + { + index++; + return true; + } + } + return false; + } + + void Reset()override + { + enumerator->Reset(); + index=-1; + } + }; + } +} + +#endif + +/*********************************************************************** +.\COLLECTIONS\OPERATION.H +***********************************************************************/ +/*********************************************************************** +Author: Zihan Chen (vczh) +Licensed under https://github.com/vczh-libraries/License + +Functions: + CopyFrom(TargetContainer, SourceContainer) + [T] .Select(T->K) => [K] + [T] .Where(T->bool) => [T] + [Ptr] .Cast() => [Ptr] + [Ptr] .FindType() => [Ptr] + [T] .OrderBy(T->T->int) => [T] + + [T] .Aggregate(T->T->T) => T + [T] .Aggregate(T->T->T, T) => T + [T] .All(T->bool) => bool + [T] .Any(T->bool) => bool + [T] .Max() => T + [T] .Min() => T + [T] .First() => T + [T] .FirstOrDefault(T) => T + [T] .Last() => T + [T] .LastOrDefault(T) => T + [T] .Count() => vint + [T] .IsEmpty() => bool + + [T] .Concat([T]) => [T] (evaluated) + [T] .Take(vint) => [T] (evaluated) + [T] .Skip(vint) => [T] (evaluated) + [T] .Repeat(vint) => [T] (evaluated) + [T] .Distinct() => [T] + [T] .Reverse() => [T] (evaluated) + + [T] .Pairwise([K]) => [(T,K)] (evaluated) + [T] .Intersect([T]) => [T] + [T] .Except([T]) => [T] + [T] .Union([T]) => [T] + + [T] .Evaluate() => [T] + [T] .SelectMany(T->[K]) => [K] + [T] .GroupBy(T->K) => [(K, [T])] + + (evaluated) means the lazy list is evaluated when all sources are evaluated + + From(begin, end) => [T] + From(array) => [T] + Range(start, count) => [vint] + + FOREACH(X, a, XList) + FOREACH_INDEXER(X, a, index, XList) +***********************************************************************/ + +#ifndef VCZH_COLLECTIONS_OPERATION +#define VCZH_COLLECTIONS_OPERATION + namespace vl { @@ -5071,875 +6615,899 @@ namespace vl { /*********************************************************************** -ForEachIterator +Quick Sort ***********************************************************************/ - template - class ForEachIterator : public Object + /// Quick sort. + /// Type of elements. + /// Type of the comparer. + /// Pointer to element array to sort. + /// The number of elements to sort. + /// + /// The comparar for two elements. + /// Both arguments are elements to compare. + /// Returns a positive number when the first argument is greater. + /// Returns a negative number when the second argument is greater. + /// Returns zero when two arguments equal. + /// + template + void SortLambda(T* items, vint length, F orderer) { - public: - virtual bool Next(T& variable)const=0; + if (length == 0) return; + vint pivot = 0; + vint left = 0; + vint right = 0; + bool flag = false; - operator bool()const + while (left + right + 1 != length) { - return true; - } - }; + vint& mine = (flag ? left : right); + vint& theirs = (flag ? right : left); + vint candidate = (flag ? left : length - right - 1); + vint factor = (flag ? -1 : 1); -/*********************************************************************** -ForEachIterator for IEnumerable -***********************************************************************/ - - template - class EnumerableForEachIterator : public ForEachIterator - { - protected: - Ptr> enumerator; - public: - EnumerableForEachIterator(const IEnumerable& enumerable) - :enumerator(enumerable.CreateEnumerator()) - { - } - - EnumerableForEachIterator(const EnumerableForEachIterator& enumerableIterator) - :enumerator(enumerableIterator.enumerator) - { - } - - bool Next(T& variable)const - { - if(enumerator->Next()) + if (orderer(items[pivot], items[candidate])*factor <= 0) { - variable=enumerator->Current(); - return true; + mine++; } else { - return false; + theirs++; + T temp = items[pivot]; + items[pivot] = items[candidate]; + items[candidate] = temp; + pivot = candidate; + flag = !flag; } } + + SortLambda(items, left, orderer); + SortLambda(items + left + 1, right, orderer); + } + + /// Quick sort. + /// Type of elements. + /// Pointer to element array to sort. + /// The number of elements to sort. + /// + /// The comparar for two elements. + /// Both arguments are elements to compare. + /// Returns a positive number when the first argument is greater. + /// Returns a negative number when the second argument is greater. + /// Returns zero when two arguments equal. + /// + template + void Sort(T* items, vint length, const Func& orderer) + { + SortLambda>(items, length, orderer); + } + +/*********************************************************************** +LazyList +***********************************************************************/ + + /// A lazy evaluated container with rich operations. is useful to create lazy list from arrays or containers. + /// The type of elements. + /// + /// A lazy list is usually created directly from a container source, or from a calculation on a source. + /// Typically the lazy list cannot be used after the source is deleted. + /// If this lazy list needs to be used after the source is deleted, + /// you are recommended to use [F:vl.collections.LazyList`1.Evaluate], with forceCopy set to true. + /// In this way you get a lazy list with all values copied, they do not rely on other objects. + /// + template + class LazyList : public Object, public IEnumerable + { + protected: + Ptr> enumeratorPrototype; + + IEnumerator* xs()const + { + return enumeratorPrototype->Clone(); + } + public: + /// Create a lazy list from an enumerator. This enumerator will be deleted when this lazy list is deleted. + /// The enumerator. + LazyList(IEnumerator* enumerator) + :enumeratorPrototype(enumerator) + { + } + + /// Create a lazy list from an enumerator. + /// The enumerator. + LazyList(Ptr> enumerator) + :enumeratorPrototype(enumerator) + { + } + + /// Create a lazy list from an enumerable. + /// The enumerable. + LazyList(const IEnumerable& enumerable) + :enumeratorPrototype(enumerable.CreateEnumerator()) + { + } + + /// Create a lazy list from another lazy list. + /// The lazy list. + LazyList(const LazyList& lazyList) + :enumeratorPrototype(lazyList.enumeratorPrototype) + { + } + + /// Create a lazy list from a container. It is very useful to a container as an intermediate result and then put in a lazy list. + /// Type of the container. + /// The container. + template + LazyList(Ptr container) + :enumeratorPrototype(new ContainerEnumerator(container)) + { + } + + /// Create an empty lazy list. + LazyList() + :enumeratorPrototype(EmptyEnumerable().CreateEnumerator()) + { + } + + LazyList& operator=(const LazyList& lazyList) + { + enumeratorPrototype=lazyList.enumeratorPrototype; + return *this; + } + + IEnumerator* CreateEnumerator()const + { + return enumeratorPrototype->Clone(); + } + + //------------------------------------------------------- + + /// Create a new lazy list with all elements transformed. + /// Type of the transformer. + /// The created lazy list. + /// The transformer. + /// + template + LazyList Select(F f)const + { + return new SelectEnumerator(xs(), f); + } + + /// Create a new lazy list with all elements filtered. + /// Type of the filter. + /// The created lazy list. + /// The filter. + /// + template + LazyList Where(F f)const + { + return new WhereEnumerator(xs(), f); + } + + /// Create a new lazy list with all elements casted to a new type. + /// The new type. + /// The created lazy list. + /// + /// The lazy list being casted contains elements of type [T:vl.Ptr`1]. + /// [F:vl.Ptr`1.Cast`1] is called on each elements. + /// If some elements fail to cast, they become empty shared pointers. + /// + template + LazyList> Cast()const + { + Func(T)> f=[](T t)->Ptr{return t.template Cast();}; + return new SelectEnumerator>(xs(), f); + } + + /// Create a new lazy list with only elements that successfully casted to a new type. + /// The new type. + /// The created lazy list. + /// + /// The lazy list being casted contains elements of type [T:vl.Ptr`1]. + /// [F:vl.Ptr`1.Cast`1] is called on each elements. + /// If some elements fail to cast, they are eliminated from the result. + /// + template + LazyList> FindType()const + { + return Cast().Where([](Ptr t){return t;}); + } + + /// Create a new lazy list with all elements sorted. + /// Type of the comparer. + /// The created lazy list. + /// + /// The comparar for two elements. + /// Both arguments are elements to compare. + /// Returns a positive number when the first argument is greater. + /// Returns a negative number when the second argument is greater. + /// Returns zero when two arguments equal. + /// + /// + template + LazyList OrderBy(F f)const + { + Ptr> sorted=new List; + CopyFrom(*sorted.Obj(), *this); + if(sorted->Count()>0) + { + SortLambda(&sorted->operator[](0), sorted->Count(), f); + } + return new ContainerEnumerator>(sorted); + } + + //------------------------------------------------------- + + /// Aggregate a lazy list. It will crash if the lazy list is empty. + /// Type of the aggregator. + /// The aggregated value. + /// + /// The aggregator. + /// The first argument is the aggregated value of any prefix. + /// The second argument is the element right after a prefix. + /// Returns the aggregated value of the new prefix. + /// For the first call, the first argument is the first element in the lazy list. + /// + /// + template + T Aggregate(F f)const + { + Ptr> enumerator=CreateEnumerator(); + if(!enumerator->Next()) + { + throw Error(L"LazyList::Aggregate(F)#Aggregate failed to calculate from an empty container."); + } + T result=enumerator->Current(); + while(enumerator->Next()) + { + result=f(result, enumerator->Current()); + } + return result; + } + + /// Aggregate a lazy list. + /// Type of the initial value. + /// Type of the aggregator. + /// The aggregated value. + /// The aggregated value defined for the empty prefix. + /// + /// The aggregator. + /// The first argument is the aggregated value of any prefix. + /// The second argument is the element right after a prefix. + /// Returns the aggregated value of the new prefix. + /// + /// + template + I Aggregate(I init, F f)const + { + FOREACH(T, t, *this) + { + init=f(init, t); + } + return init; + } + + /// Test if all elements in the lazy list satisfy a filter. + /// Type of the filter. + /// Returns true if all elements satisfy the filter. + /// The filter. + /// + template + bool All(F f)const + { + return Select(f).Aggregate(true, [](bool a, bool b){return a&&b;}); + } + + /// Test if any elements in the lazy list satisfy a filter. + /// Type of the filter. + /// Returns true if there is at least one element satisfies the filter. + /// The filter. + /// + template + bool Any(F f)const + { + return Select(f).Aggregate(false, [](bool a, bool b){return a||b;}); + } + + /// Get the maximum value in the lazy list. It will crash if the lazy list is empty. + /// The maximum value. + /// + T Max()const + { + return Aggregate([](T a, T b){return a>b?a:b;}); + } + + /// Get the minimum value in the lazy list. It will crash if the lazy list is empty. + /// The minimum value. + /// + T Min()const + { + return Aggregate([](T a, T b){return aGet the first value in the lazy list. It will crash if the lazy list is empty. + /// The first value. + T First()const + { + Ptr> enumerator=CreateEnumerator(); + if(!enumerator->Next()) + { + throw Error(L"LazyList::First(F)#First failed to calculate from an empty container."); + } + return enumerator->Current(); + } + + /// Get the first value in the lazy list. + /// The first value. If the lazy list is empty, the argument is returned. + /// The argument to return if the lazy list is empty. + T First(T defaultValue)const + { + Ptr> enumerator=CreateEnumerator(); + if(!enumerator->Next()) + { + return defaultValue; + } + return enumerator->Current(); + } + + /// Get the last value in the lazy list. It will crash if the lazy list is empty. + /// The last value. + T Last()const + { + Ptr> enumerator=CreateEnumerator(); + if(!enumerator->Next()) + { + throw Error(L"LazyList::Last(F)#Last failed to calculate from an empty container."); + } + else + { + T value=enumerator->Current(); + while(enumerator->Next()) + { + value=enumerator->Current(); + } + return value; + } + } + + /// Get the last value in the lazy list. + /// The last value. If the lazy list is empty, the argument is returned. + /// The argument to return if the lazy list is empty. + T Last(T defaultValue)const + { + Ptr> enumerator=CreateEnumerator(); + while(enumerator->Next()) + { + defaultValue=enumerator->Current(); + } + return defaultValue; + } + + /// Get the number of elements in the lazy list. + /// The number of elements. + vint Count()const + { + vint result=0; + Ptr> enumerator=CreateEnumerator(); + while(enumerator->Next()) + { + result++; + } + return result; + } + + /// Test if the lazy list is empty. + /// Returns true if the lazy list is empty. + bool IsEmpty()const + { + Ptr> enumerator=CreateEnumerator(); + return !enumerator->Next(); + } + + //------------------------------------------------------- + + /// Create a new lazy list containing elements of the two container in order. + /// The created lazy list. + /// Elements to be appended. + /// + LazyList Concat(const IEnumerable& remains)const + { + return new ConcatEnumerator(xs(), remains.CreateEnumerator()); + } + + /// Create a new lazy list with a prefix of the lazy list. + /// The created lazy list. + /// The size of the prefix. + /// + LazyList Take(vint count)const + { + return new TakeEnumerator(xs(), count); + } + + /// Create a new lazy list with a postfix of the lazy list. + /// The created lazy list. + /// The number of elements to skip. + /// + LazyList Skip(vint count)const + { + return new SkipEnumerator(xs(), count); + } + + /// Create a new lazy list with several copies of the lazy list in order. + /// The created lazy list. + /// The numbers of copies. + /// + LazyList Repeat(vint count)const + { + return new RepeatEnumerator(xs(), count); + } + + /// Create a new lazy list with duplicated elements removed in this lazy list. + /// The created lazy list. + /// + LazyList Distinct()const + { + return new DistinctEnumerator(xs()); + } + + /// Create a new lazy list with all elements in this lazy list in a reverse order. + /// The created lazy list. + /// + LazyList Reverse()const + { + return new ReverseEnumerator(*this); + } + + //------------------------------------------------------- + + /// Create a new lazy list of pairs from elements from two containers. + /// Type of all elements in the second container. + /// + /// The created lazy list, which contains pairs of elements from two containers at the same position. + /// If the two container have different sizes, the created lazy list has the size of the shorter one. + /// + /// The second container. + /// p){ return p.key + p.value; }); + /// FOREACH(vint, z, zs) Console::Write(itow(z) + L" "); + /// } + /// ]]> + template + LazyList> Pairwise(const IEnumerable& remains)const + { + return new PairwiseEnumerator(xs(), remains.CreateEnumerator()); + } + + /// Create a new lazy list with elements from the lazy list, which also appear in the second container. + /// The created lazy list. Elements in the create lazy list is in the same order as in this lazy list. + /// The second container. + /// + LazyList Intersect(const IEnumerable& remains)const + { + return LazyList(new IntersectExceptEnumerator(xs(), remains)).Distinct(); + } + + /// Create a new lazy list with elements from the lazy list, which do not appear in the second container. + /// The created lazy list. Elements in the create lazy list is in the same order as in this lazy list. + /// The second container. + /// + LazyList Except(const IEnumerable& remains)const + { + return LazyList(new IntersectExceptEnumerator(xs(), remains)).Distinct(); + } + + /// Create a new lazy list with elements in two containers. Duplicated elements will be removed. + /// The created lazy list. + /// The second container. + /// + LazyList Union(const IEnumerable& remains)const + { + return Concat(remains).Distinct(); + } + + //------------------------------------------------------- + + /// Get an evaluated copy of this lazy list. + /// + /// The created lazy list. + /// If this lazy list has been evaluated before, it returns a reference to this lazy list. + /// If this lazy list has not been evaluated before, it go through this lazy list and copy all values. + /// + /// Set to true to force copying values, regardless of whether this lazy list is evaluated or not. + /// + /// "Evaluated" means reading from this lazy list cause no extra calculation. + /// In most of the cases, the created lazy list relies on its source. + /// For example, a lazy list can be created from a reference to a , or from an array on stack. + /// If this list or array is deleted, then iterating the created lazy list will crash. + /// By calling the Evaluate function with forceCopy set to true, a new lazy list is created, with all values cached in it. + /// Its connection to the source list or array is removed, and can then be passed to everywhere. + /// + LazyList Evaluate(bool forceCopy = false)const + { + if (!forceCopy && enumeratorPrototype->Evaluated()) + { + return *this; + } + else + { + Ptr> xs = new List; + CopyFrom(*xs.Obj(), *this); + return xs; + } + } + + /// Create a new lazy list, whose elements are from transformed elements in this lazy list. + /// Type of the transformer. + /// The created lazy list. + /// + /// The transformer. + /// The first argument is any element in this lazy list. + /// Returns the transformed lazy list from this argument. + /// + /// + template + FUNCTION_RESULT_TYPE(F) SelectMany(F f)const + { + typedef FUNCTION_RESULT_TYPE(F) LazyListU; + typedef typename LazyListU::ElementType U; + return Select(f).Aggregate(LazyList(), [](const LazyList& a, const IEnumerable& b)->LazyList{return a.Concat(b);}); + } + + /// Create a new lazy list, with elements from this lazy list grouped by a key function. + /// Type of the key function. + /// The created lazy list. + /// + /// The key function. + /// The first argument is any element in this lazy list. + /// Returns a key calculated from this argument. + /// Elements that have the same key will be grouped together. + /// + /// >; + /// FOREACH(TY, y, ys) + /// { + /// Console::Write(itow(y.key) + L":"); + /// FOREACH(vint, z, y.value) Console::Write(L" " + itow(z)); + /// Console::WriteLine(L""); + /// } + /// } + /// ]]> + template + LazyList>> GroupBy(F f)const + { + typedef FUNCTION_RESULT_TYPE(F) K; + return Select(f) + .Distinct() + .Select([=](K k) + { + return Pair>( + k, + Where([=](T t){return k==f(t);}) + ); + }); + } }; + /// Create a lazy list with a series of increasing number. + /// Type of elements. + /// A lazy list of increasing numbers. + /// The first number. + /// Total amount of increasing numbers. template - EnumerableForEachIterator CreateForEachIterator(const IEnumerable& enumerable) + LazyList Range(T start, T count) + { + return new RangeEnumerator(start, count); + } + + /// Create a lazy list from an enumerable. + /// Type of elements. + /// The created lazy list. + /// The enumerable. + template + LazyList From(const IEnumerable& enumerable) { return enumerable; } -/*********************************************************************** -FOREACH and FOREACH_INDEXER -***********************************************************************/ - -#define FOREACH(TYPE, VARIABLE, COLLECTION)\ - SCOPE_VARIABLE(const ::vl::collections::ForEachIterator&, __foreach_iterator__, ::vl::collections::CreateForEachIterator(COLLECTION))\ - for(TYPE VARIABLE;__foreach_iterator__.Next(VARIABLE);) - -#define FOREACH_INDEXER(TYPE, VARIABLE, INDEXER, COLLECTION)\ - SCOPE_VARIABLE(const ::vl::collections::ForEachIterator&, __foreach_iterator__, ::vl::collections::CreateForEachIterator(COLLECTION))\ - SCOPE_VARIABLE(vint, INDEXER, 0)\ - for(TYPE VARIABLE;__foreach_iterator__.Next(VARIABLE);INDEXER++) - } -} - -#endif - -/*********************************************************************** -.\COLLECTIONS\DICTIONARY.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -Data Structure::Dictionary - -Classes: - Dictionary : One to one mapping - Group : One to many mapping -***********************************************************************/ - -#ifndef VCZH_COLLECTIONS_DICTIONARY -#define VCZH_COLLECTIONS_DICTIONARY - - -namespace vl -{ - namespace collections - { - /// Dictionary. - /// Type of keys. - /// Type of values. - /// Type of the key type of keys. - /// Type of the key type of values. - template< - typename KT, - typename VT, - typename KK=typename KeyType::Type, - typename VK=typename KeyType::Type - > - class Dictionary : public Object, public virtual IEnumerable> + /// Create a lazy list from another lazy list. + /// Type of elements. + /// The created lazy list. + /// The lazy list to copy. + template + LazyList From(const LazyList& enumerable) { - public: - typedef SortedList KeyContainer; - typedef List ValueContainer; - protected: - class Enumerator : public Object, public virtual IEnumerator> - { - private: - const Dictionary* container; - vint index; - Pair current; - - void UpdateCurrent() - { - if(indexCount()) - { - current.key=container->Keys().Get(index); - current.value=container->Values().Get(index); - } - } - public: - Enumerator(const Dictionary* _container, vint _index=-1) - { - container=_container; - index=_index; - } - - IEnumerator>* Clone()const - { - return new Enumerator(container, index); - } - - const Pair& Current()const - { - return current; - } - - vint Index()const - { - return index; - } - - bool Next() - { - index++; - UpdateCurrent(); - return index>=0 && indexCount(); - } - - void Reset() - { - index=-1; - UpdateCurrent(); - } - }; - - KeyContainer keys; - ValueContainer values; - public: - /// Create a dictionary. - Dictionary() - { - } - - IEnumerator>* CreateEnumerator()const - { - return new Enumerator(this); - } - - /// Set a preference of using memory. - /// Set to true (by default) to let the container efficiently reduce memory usage when necessary. - void SetLessMemoryMode(bool mode) - { - keys.SetLessMemoryMode(mode); - values.SetLessMemoryMode(mode); - } - - /// Get all keys. - /// All keys. - const KeyContainer& Keys()const - { - return keys; - } - - /// Get all values. - /// All values. - const ValueContainer& Values()const - { - return values; - } - - /// Get the number of keys. - /// The number of keys. - vint Count()const - { - return keys.Count(); - } - - /// Get the reference to the value associated with a key. - /// The reference to the value. - /// The key to find. - const VT& Get(const KK& key)const - { - return values.Get(keys.IndexOf(key)); - } - - /// Get the reference to the value associated with a key. - /// The reference to the value. - /// The key to find. - const VT& operator[](const KK& key)const - { - return values.Get(keys.IndexOf(key)); - } - - /// Replace the value associated with a key. - /// Returns true if the value is replaced. - /// The key to find. - /// The key to replace. - bool Set(const KT& key, const VT& value) - { - vint index=keys.IndexOf(KeyType::GetKeyValue(key)); - if(index==-1) - { - index=keys.Add(key); - values.Insert(index, value); - } - else - { - values[index]=value; - } - return true; - } - - /// Add a key with an associated value. Exception will raise if the key already exists. - /// Returns true if the pair is added. - /// The pair of key and value. - bool Add(const Pair& value) - { - return Add(value.key, value.value); - } - - /// Add a key with an associated value. Exception will raise if the key already exists. - /// Returns true if the pair is added. - /// The key. - /// The value. - bool Add(const KT& key, const VT& value) - { - CHECK_ERROR(!keys.Contains(KeyType::GetKeyValue(key)), L"Dictionary::Add(const KT&, const VT&)#Key already exists."); - vint index=keys.Add(key); - values.Insert(index, value); - return true; - } - - /// Remove a key with the associated value. - /// Returns true if the key and the value is removed. - /// The key. - bool Remove(const KK& key) - { - vint index=keys.IndexOf(key); - if(index!=-1) - { - keys.RemoveAt(index); - values.RemoveAt(index); - return true; - } - else - { - return false; - } - } - - /// Remove everything. - /// Returns true if all keys and values are removed. - bool Clear() - { - keys.Clear(); - values.Clear(); - return true; - } - }; - - /// Group, which is similar to an dictionary, but a group can associate multiple values with a key. - /// Type of keys. - /// Type of values. - /// Type of the key type of keys. - /// Type of the key type of values. - template< - typename KT, - typename VT, - typename KK=typename KeyType::Type, - typename VK=typename KeyType::Type - > - class Group : public Object, public virtual IEnumerable> - { - public: - typedef SortedList KeyContainer; - typedef List ValueContainer; - protected: - class Enumerator : public Object, public virtual IEnumerator> - { - private: - const Group* container; - vint keyIndex; - vint valueIndex; - Pair current; - - void UpdateCurrent() - { - if(keyIndexCount()) - { - const ValueContainer& values=container->GetByIndex(keyIndex); - if(valueIndexKeys().Get(keyIndex); - current.value=values.Get(valueIndex); - } - } - } - public: - Enumerator(const Group* _container, vint _keyIndex=-1, vint _valueIndex=-1) - { - container=_container; - keyIndex=_keyIndex; - valueIndex=_valueIndex; - } - - IEnumerator>* Clone()const - { - return new Enumerator(container, keyIndex, valueIndex); - } - - const Pair& Current()const - { - return current; - } - - vint Index()const - { - if(0<=keyIndex && keyIndexCount()) - { - vint index=0; - for(vint i=0;iGetByIndex(i).Count(); - } - return index+valueIndex; - } - else - { - return -1; - } - } - - bool Next() - { - if(keyIndex==-1) - { - keyIndex=0; - } - while(keyIndexCount()) - { - valueIndex++; - const ValueContainer& values=container->GetByIndex(keyIndex); - if(valueIndex values; - public: - Group() - { - } - - ~Group() - { - Clear(); - } - - IEnumerator>* CreateEnumerator()const - { - return new Enumerator(this); - } - - /// Get all keys. - /// All keys. - const KeyContainer& Keys()const - { - return keys; - } - - /// Get the number of keys. - /// The number of keys. - vint Count()const - { - return keys.Count(); - } - - /// Get all values associated with a key. - /// All values. - /// The key to find. - const ValueContainer& Get(const KK& key)const - { - return *values.Get(keys.IndexOf(key)); - } - - /// Get all values associated with a key. - /// All values. - /// The position of a the key. - const ValueContainer& GetByIndex(vint index)const - { - return *values.Get(index); - } - - /// Get all values associated with a key. - /// All values. - /// The key to find. - const ValueContainer& operator[](const KK& key)const - { - return *values.Get(keys.IndexOf(key)); - } - - /// Test if a key exists in the group or not. - /// Returns true if the key exists. - /// The key to find. - bool Contains(const KK& key)const - { - return keys.Contains(key); - } - - /// Test if a key exists with an associated value in the group or not. - /// Returns true if the key exists with an associated value. - /// The key to find. - /// The value to find. - bool Contains(const KK& key, const VK& value)const - { - vint index=keys.IndexOf(key); - if(index!=-1) - { - return values.Get(index)->Contains(value); - } - else - { - return false; - } - } - - /// Add a key with an associated value. If the key already exists, the value will be associated with the key with other values. - /// Returns true if the pair is added. - /// The pair of key and value. - bool Add(const Pair& value) - { - return Add(value.key, value.value); - } - - /// Add a key with an associated value. If the key already exists, the value will be associated with the key with other values. - /// Returns true if the pair is added. - /// The key. - /// The value. - bool Add(const KT& key, const VT& value) - { - ValueContainer* target=0; - vint index=keys.IndexOf(KeyType::GetKeyValue(key)); - if(index==-1) - { - target=new ValueContainer; - values.Insert(keys.Add(key), target); - } - else - { - target=values[index]; - } - target->Add(value); - return true; - } - - /// Remove a key with all associated values. - /// Returns true if the key and all associated values are removed. - /// The key. - bool Remove(const KK& key) - { - vint index=keys.IndexOf(key); - if(index!=-1) - { - keys.RemoveAt(index); - List* target=values[index]; - values.RemoveAt(index); - delete target; - return true; - } - else - { - return false; - } - } - - /// Remove a key with the associated values. - /// Returns true if the key and the associated values are removed. If there are multiple values associated with the key, only the value will be removed. - /// The key. - /// The value. - bool Remove(const KK& key, const VK& value) - { - vint index=keys.IndexOf(key); - if(index!=-1) - { - List* target=values[index]; - target->Remove(value); - if(target->Count()==0) - { - keys.RemoveAt(index); - values.RemoveAt(index); - delete target; - } - return true; - } - else - { - return false; - } - } - - /// Remove everything. - /// Returns true if all keys and values are removed. - bool Clear() - { - for(vint i=0;i void - typename TDiscardSecond, // TKey * [TValueSecond] -> void - typename TAccept // TKey * [TValueFirst] * [TValueSecond] -> void - > - void GroupInnerJoin( - const Group& first, - const Group& second, - const TDiscardFirst& discardFirst, - const TDiscardSecond& discardSecond, - const TAccept& accept - ) - { - vint firstIndex = 0; - vint secondIndex = 0; - vint firstCount = first.Keys().Count(); - vint secondCount = second.Keys().Count(); - while (true) - { - if (firstIndex < firstCount) - { - auto firstKey = first.Keys()[firstIndex]; - const List& firstValues = first.GetByIndex(firstIndex); - - if (secondIndex < secondCount) - { - auto secondKey = second.Keys()[secondIndex]; - const List& secondValues = second.GetByIndex(secondIndex); - - if (firstKey < secondKey) - { - discardFirst(firstKey, firstValues); - firstIndex++; - } - else if (firstKey > secondKey) - { - discardSecond(secondKey, secondValues); - secondIndex++; - } - else - { - accept(firstKey, firstValues, secondValues); - firstIndex++; - secondIndex++; - } - } - else - { - discardFirst(firstKey, firstValues); - firstIndex++; - } - } - else - { - if (secondIndex < secondCount) - { - auto secondKey = second.Keys()[secondIndex]; - const List& secondValues = second.GetByIndex(secondIndex); - - discardSecond(secondKey, secondValues); - secondIndex++; - } - else - { - break; - } - } - } + return enumerable; } -/*********************************************************************** -Random Access -***********************************************************************/ - namespace randomaccess_internal + /// Create a lazy list from an array. + /// Type of elements. + /// The created lazy list. + /// Pointer to the first element in the array. + /// Pointer to the element after the last element in the array. + template + LazyList From(const T* begin, const T* end) { - template - struct RandomAccessable> - { - static const bool CanRead = true; - static const bool CanResize = false; - }; - - template - struct RandomAccess> - { - static vint GetCount(const Dictionary& t) - { - return t.Count(); - } + return FromPointer(begin, end); + } - static Pair GetValue(const Dictionary& t, vint index) - { - return Pair(t.Keys().Get(index), t.Values().Get(index)); - } + /// Create a lazy list from an array. + /// Type of elements. + /// Size of the array. + /// The created lazy list. + /// The array. + template + LazyList From(T (&items)[size]) + { + return FromArray(items); + } - static void AppendValue(Dictionary& t, const Pair& value) - { - t.Set(value.key, value.value); - } - }; + /// Create a lazy list from an array. + /// Type of elements. + /// Size of the array. + /// The created lazy list. + /// The array. + template + LazyList From(const T (&items)[size]) + { + return FromArray(items); } } } #endif + /*********************************************************************** -.\EXCEPTION.H +.\EVENT.H ***********************************************************************/ /*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -Framework::Exception - -Classes: - Exception : Exception +Author: Zihan Chen (vczh) +Licensed under https://github.com/vczh-libraries/License ***********************************************************************/ - -#ifndef VCZH_EXCEPTION -#define VCZH_EXCEPTION +#ifndef VCZH_EVENT +#define VCZH_EVENT namespace vl { - /// Base type of all exceptions. - class Exception : public Object + template + class Event; + + class EventHandler : public Object { - protected: - WString message; - public: - Exception(const WString& _message=WString::Empty); - - const WString& Message()const; + virtual bool IsAttached() = 0; }; - class ArgumentException : public Exception + /// An event for being subscribed using multiple callbacks. A callback is any functor that returns void. + /// Types of callback parameters. + template + class Event : public Object, private NotCopyable { protected: - WString function; - WString name; - - public: - ArgumentException(const WString& _message=WString::Empty, const WString& _function=WString::Empty, const WString& _name=WString::Empty); - - const WString& GetFunction()const; - const WString& GetName()const; - }; - - class ParsingException : public Exception - { - protected: - vint position; - WString expression; - - public: - ParsingException(const WString& _message, const WString& _expression, vint _position); - - const WString& GetExpression()const; - vint GetPosition()const; - }; -} - -#endif - -/*********************************************************************** -.\CONSOLE.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -UI::Console - -***********************************************************************/ - -#ifndef VCZH_CONSOLE -#define VCZH_CONSOLE - - -namespace vl -{ - namespace console - { - /// A Static class for command line window operations. - class Console abstract + class EventHandlerImpl : public EventHandler { public: - /// Write to the command line window. - /// Content to write. - /// Size of the content in wchar_t. The zero terminator is not included. - static void Write(const wchar_t* string, vint length); + bool attached; + Func function; - /// Write to the command line window. - /// Content to write. - static void Write(const wchar_t* string); - - /// Write to the command line window. - /// Content to write. - static void Write(const WString& string); - - /// Write to the command line window with a CRLF. - /// Content to write. - static void WriteLine(const WString& string); - - /// Read from the command line window. - /// The whole line read from the command line window. - static WString Read(); - - static void SetColor(bool red, bool green, bool blue, bool light); - static void SetTitle(const WString& string); + EventHandlerImpl(const Func& _function) + :attached(true) + , function(_function) + { + } + + bool IsAttached()override + { + return attached; + } }; - } -} - -#endif - -/*********************************************************************** -.\GLOBALSTORAGE.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -Framework::Global Storage - -Classes: - GlobalStorage : Global storage accessable by name, each storage will be initialized on the first access, and all storages will be released by FinalizeGlobalStorage - -***********************************************************************/ - -#ifndef VCZH_GLOBALSTORAGE -#define VCZH_GLOBALSTORAGE - - -namespace vl -{ - /// ) - /// - /// INITIALIZE_GLOBAL_STORAGE_CLASS - /// - /// FINALIZE_GLOBAL_STORAGE_CLASS - /// - /// END_GLOBAL_STORAGE_CLASS - /// Then you have a global storage. You can only use this global storage in the current cpp file. [M:vl.InitializeGlobalStorage] should be called before using any global storage. [M:vl.FinalizeGlobalStorage] is encouraged to call if you think you will not use any global storages anymore. It will reduce noices when you want to detect memory leaks. - /// If the key of the global variable is called Key, and the variable you want to access is called Variable, then you can use GetKey()->Variable to access that variable. The GetKey function is created in the macro calls before. - /// ]]> - class GlobalStorage : public Object, private NotCopyable - { - private: - bool cleared; + + collections::SortedList> handlers; public: - GlobalStorage(const wchar_t* key); - ~GlobalStorage(); - - bool Cleared(); - virtual void ClearResource()=0; + /// Add a callback to the event. + /// The event handler representing the callback. + /// The callback. + Ptr Add(const Func& function) + { + Ptr handler = new EventHandlerImpl(function); + handlers.Add(handler); + return handler; + } + + /// Add a callback to the event. + /// The event handler representing the callback. + /// The callback. + Ptr Add(void(*function)(TArgs...)) + { + return Add(Func(function)); + } + + /// Add a method callback to the event. + /// Type of the class that the callback belongs to. + /// The event handler representing the callback. + /// The object that the callback belongs to. + /// The method callback. + template + Ptr Add(C* sender, void(C::*function)(TArgs...)) + { + return Add(Func(sender, function)); + } + + /// Remove a callback by an event handler returns from . + /// Returns true if this operation succeeded. + /// The event handler representing the callback. + bool Remove(Ptr handler) + { + auto impl = handler.Cast(); + if (!impl) return false; + vint index = handlers.IndexOf(impl.Obj()); + if (index == -1) return false; + impl->attached = false; + handlers.RemoveAt(index); + return true; + } + + /// Invoke all callbacks in the event. + /// Arguments to invoke all callbacks. + void operator()(TArgs ...args)const + { + for(vint i = 0; i < handlers.Count(); i++) + { + handlers[i]->function(args...); + } + } }; - - extern GlobalStorage* GetGlobalStorage(const wchar_t* key); - extern GlobalStorage* GetGlobalStorage(const WString& key); - - /// Initialize the global storage. - extern void InitializeGlobalStorage(); - /// Finalize the global storage. - extern void FinalizeGlobalStorage(); } - -#define BEGIN_GLOBAL_STORAGE_CLASS(NAME)\ - class NAME : public vl::GlobalStorage\ - {\ - public:\ - NAME()\ - :vl::GlobalStorage(L ## #NAME)\ - {\ - InitializeClearResource();\ - }\ - ~NAME()\ - {\ - if(!Cleared())ClearResource();\ - }\ - -#define INITIALIZE_GLOBAL_STORAGE_CLASS\ - void InitializeClearResource()\ - {\ - -#define FINALIZE_GLOBAL_STORAGE_CLASS\ - }\ - void ClearResource()\ - {\ - -#define END_GLOBAL_STORAGE_CLASS(NAME)\ - }\ - };\ - NAME& Get##NAME()\ - {\ - static NAME __global_storage_##NAME;\ - return __global_storage_##NAME;\ - }\ - -#define EXTERN_GLOBAL_STORAGE_CLASS(NAME)\ - class NAME;\ - extern NAME& Get##NAME();\ - #endif @@ -5947,10 +7515,8 @@ namespace vl .\COLLECTIONS\PARTIALORDERING.H ***********************************************************************/ /*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -Data Structure::Partial Ordering - +Author: Zihan Chen (vczh) +Licensed under https://github.com/vczh-libraries/License ***********************************************************************/ #ifndef VCZH_COLLECTIONS_PARTIALORDERING @@ -5991,7 +7557,7 @@ Partial Ordering /// Partial ordering item sorter. /// This class sorts items in a partial order using the given dependency information. /// Node stored in this class using the index of items. - /// If a depends on b, then a.ins->Contains(b) && b.outs->Contains(a). + /// If a depends on b, then a.ins->Contains(b) && b.outs->Contains(a). /// The sorting result is a list of strong connected components in order. /// If a depends on b, then the component containing a appears after the component containing b. /// Node could represent a sub class if InitWithSubClass is called. @@ -6183,10 +7749,8 @@ Partial Ordering .\UNITTEST\UNITTEST.H ***********************************************************************/ /*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -UI::Console - +Author: Zihan Chen (vczh) +Licensed under https://github.com/vczh-libraries/License ***********************************************************************/ #ifndef VCZH_UNITTEST @@ -6199,30 +7763,85 @@ namespace vl { using UnitTestFileProc = void(*)(); - /// + /// + ///

Unit test framework.

+ ///

+ /// Test cases could be defined in multiple cpp files. In each cpp file, there can be one TEST_FILE call. + /// + ///

+ ///

+ /// Both TEST_CATEGORY could be used inside TEST_FILE, or nested inside another TEST_CATEGORY. + /// TEST_CASE could be used inside TEST_FILE or TEST_CATEGORY. + ///

+ ///

+ /// TEST_ASSERT is used to verify a boolean expression. + /// It could only be used in TEST_CASE. + /// TEST_ASSERT could not be used in TEST_FILE or TEST_CATEGORY. + ///

+ ///

+ /// When the test program is started in debug mode (Windows only), or by command line options "/D", + /// A TEST_ASSERT failure will trigger a break point, it could be catched by any debugger. + ///

+ ///

+ /// When the test program is started in release mode, or by command line options "/R", or without command line options, + /// A TEST_ASSERT failure will report an error and skip rest of the current TEST_CASE, the execution will continue. + ///

+ ///

+ /// TEST_ERROR execute one statement, it fails when no [T:vl.Error] is thrown. + ///

+ ///

+ /// TEST_EXCEPTION execute one statement, it fails when the specified exception type is not thrown. + /// Another callback will be called when the exception is thrown, given a chance to check data in the exception. + ///

+ ///

+ /// TEST_CASE_ASSERT is an abbreviation of TEST_CASE + TEST_ASSERT. + /// It is very common that are multiple independent assertions. + ///

+ ///

+ /// TEST_CASE_ASSERT is a test case, it can be used in TEST_CATEGORY or TEST_FILE. + /// In release mode, by failing this assertion, the execution does not stop. + ///

+ ///

+ /// TEST_CATEGORY is very useful when multiple assertions do not have dependencies. + /// During the execution of the test program, TEST_FILE, TEST_CATEGORY, TEST_CASE and failed TEST_ASSERT will be rendered with indentation and different colors. + ///

+ ///

+ /// is needed in the main function to execute test cases. + /// TEST_PRINT could be used during test cases to print debug information to a command-line application. + ///

+ ///
+ /// class UnitTest { public: @@ -6237,12 +7856,12 @@ namespace vl Case, }; - /// Print a message with specified color. - /// The content. - /// The kind of the content. static void PrintMessage(const WString& string, MessageKind kind); /// Run all test cases. + /// The return value for the main function. If any assertion fails, it is non-zero. + /// Accept the first argument of the main function. + /// Accept the second argument of the main function. #ifdef VCZH_MSVC static int RunAndDisposeTests(int argc, wchar_t* argv[]); #else @@ -6322,1142 +7941,3 @@ namespace vl #endif - -/*********************************************************************** -.\EVENT.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -Framework::Event - -Classes: - Event : Event object, which is a functor with no return value, executing multiple functors stored inside -***********************************************************************/ -#ifndef VCZH_EVENT -#define VCZH_EVENT - - -namespace vl -{ - template - class Event - { - }; - - class EventHandler : public Object - { - public: - virtual bool IsAttached() = 0; - }; - - /// Event. - /// Types of callback parameters. - template - class Event : public Object, private NotCopyable - { - protected: - class EventHandlerImpl : public EventHandler - { - public: - bool attached; - Func function; - - EventHandlerImpl(const Func& _function) - :attached(true) - , function(_function) - { - } - - bool IsAttached()override - { - return attached; - } - }; - - collections::SortedList> handlers; - public: - /// Add a callback to the event. - /// The event handler representing the callback. - /// The callback. - Ptr Add(const Func& function) - { - Ptr handler = new EventHandlerImpl(function); - handlers.Add(handler); - return handler; - } - - /// Add a callback to the event. - /// The event handler representing the callback. - /// The callback. - Ptr Add(void(*function)(TArgs...)) - { - return Add(Func(function)); - } - - /// Add a method callback to the event. - /// Type of the class that has the method callback. - /// The event handler representing the callback. - /// The object that has the method callback. - /// The method callback. - template - Ptr Add(C* sender, void(C::*function)(TArgs...)) - { - return Add(Func(sender, function)); - } - - /// Remove a callback. - /// Returns true if this operation succeeded. - /// The event handler representing the callback. - bool Remove(Ptr handler) - { - Ptr impl = handler.Cast(); - if (!impl) return false; - vint index = handlers.IndexOf(impl.Obj()); - if (index == -1) return false; - impl->attached = false; - handlers.RemoveAt(index); - return true; - } - - /// Invoke all callbacks in the event. - /// Arguments to invoke all callbacks. - void operator()(TArgs ...args)const - { - for(vint i = 0; i < handlers.Count(); i++) - { - handlers[i]->function(args...); - } - } - }; -} -#endif - - -/*********************************************************************** -.\LAZY.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -Framework::Lazy Evaluation - -Classes: - Lazy : Object with lazy evaluation - -***********************************************************************/ - -#ifndef VCZH_LAZY -#define VCZH_LAZY - - -namespace vl -{ - /// A type representing a lazy evaluation. - /// The type of the evaluation result. - template - class Lazy : public Object - { - protected: - class Internal - { - public: - Func evaluator; - T value; - bool evaluated; - }; - - Ptr internalValue; - public: - /// Create an empty evaluation. - Lazy() - { - } - - /// Create an evaluation using a function. - /// The function. - Lazy(const Func& evaluator) - { - internalValue=new Internal; - internalValue->evaluated=false; - internalValue->evaluator=evaluator; - } - - /// Create an evaluation using the result directly. - /// The result that you have already known.0 - Lazy(const T& value) - { - internalValue=new Internal; - internalValue->evaluated=true; - internalValue->value=value; - } - - /// Copy an evaluation. - /// The evaluation to copy. - Lazy(const Lazy& lazy) - :internalValue(lazy.internalValue) - { - } - - Lazy& operator=(const Func& evaluator) - { - internalValue=new Internal; - internalValue->evaluated=false; - internalValue->evaluator=evaluator; - return *this; - } - - Lazy& operator=(const T& value) - { - internalValue=new Internal; - internalValue->evaluated=true; - internalValue->value=value; - return *this; - } - - Lazy& operator=(const Lazy& lazy) - { - internalValue=lazy.internalValue; - return *this; - } - - /// Get the evaluation result. If it has not been calculated yet, it will run the evaluation and cache the result. You will not need to calculate for the second time. - /// The evaluation result. - const T& Value()const - { - if(!internalValue->evaluated) - { - internalValue->evaluated=true; - internalValue->value=internalValue->evaluator(); - internalValue->evaluator=Func(); - } - return internalValue->value; - } - - /// Test if it has already been evaluated or not. - /// Returns true if it has already been evaluated. - const bool IsEvaluated()const - { - return internalValue->evaluated; - } - - /// Test if it is an empty evaluation or not. - /// Returns true if it is not empty. - const bool IsAvailable()const - { - return internalValue; - } - }; -} - -#endif - - -/*********************************************************************** -.\TUPLE.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -Framework::Tuple - -This file is generated by: Vczh Functional Macro -***********************************************************************/ -#ifndef VCZH_TUPLE -#define VCZH_TUPLE - - -namespace vl -{ - class TupleNullItem - { - }; - template - class Tuple - { - }; - -/*********************************************************************** -vl::Tuple -***********************************************************************/ - template - class Tuple : public Object - { - public: - T0 f0; - - Tuple() - { - } - - Tuple(T0 p0) - :f0(p0) - { - } - - static int Compare(const Tuple& a, const Tuple& b) - { - if (a.f0 < b.f0) return -1; else if (a.f0 > b.f0) return 1; - return 0; - } - - bool operator==(const Tuple& value)const{ return Compare(*this, value) == 0; } - bool operator!=(const Tuple& value)const{ return Compare(*this, value) != 0; } - bool operator< (const Tuple& value)const{ return Compare(*this, value) < 0; } - bool operator<=(const Tuple& value)const{ return Compare(*this, value) <= 0; } - bool operator> (const Tuple& value)const{ return Compare(*this, value) > 0; } - bool operator>=(const Tuple& value)const{ return Compare(*this, value) >= 0; } - }; - -/*********************************************************************** -vl::Tuple -***********************************************************************/ - template - class Tuple : public Object - { - public: - T0 f0;T1 f1; - - Tuple() - { - } - - Tuple(T0 p0,T1 p1) - :f0(p0),f1(p1) - { - } - - static int Compare(const Tuple& a, const Tuple& b) - { - if (a.f0 < b.f0) return -1; else if (a.f0 > b.f0) return 1;if (a.f1 < b.f1) return -1; else if (a.f1 > b.f1) return 1; - return 0; - } - - bool operator==(const Tuple& value)const{ return Compare(*this, value) == 0; } - bool operator!=(const Tuple& value)const{ return Compare(*this, value) != 0; } - bool operator< (const Tuple& value)const{ return Compare(*this, value) < 0; } - bool operator<=(const Tuple& value)const{ return Compare(*this, value) <= 0; } - bool operator> (const Tuple& value)const{ return Compare(*this, value) > 0; } - bool operator>=(const Tuple& value)const{ return Compare(*this, value) >= 0; } - }; - -/*********************************************************************** -vl::Tuple -***********************************************************************/ - template - class Tuple : public Object - { - public: - T0 f0;T1 f1;T2 f2; - - Tuple() - { - } - - Tuple(T0 p0,T1 p1,T2 p2) - :f0(p0),f1(p1),f2(p2) - { - } - - static int Compare(const Tuple& a, const Tuple& b) - { - if (a.f0 < b.f0) return -1; else if (a.f0 > b.f0) return 1;if (a.f1 < b.f1) return -1; else if (a.f1 > b.f1) return 1;if (a.f2 < b.f2) return -1; else if (a.f2 > b.f2) return 1; - return 0; - } - - bool operator==(const Tuple& value)const{ return Compare(*this, value) == 0; } - bool operator!=(const Tuple& value)const{ return Compare(*this, value) != 0; } - bool operator< (const Tuple& value)const{ return Compare(*this, value) < 0; } - bool operator<=(const Tuple& value)const{ return Compare(*this, value) <= 0; } - bool operator> (const Tuple& value)const{ return Compare(*this, value) > 0; } - bool operator>=(const Tuple& value)const{ return Compare(*this, value) >= 0; } - }; - -/*********************************************************************** -vl::Tuple -***********************************************************************/ - template - class Tuple : public Object - { - public: - T0 f0;T1 f1;T2 f2;T3 f3; - - Tuple() - { - } - - Tuple(T0 p0,T1 p1,T2 p2,T3 p3) - :f0(p0),f1(p1),f2(p2),f3(p3) - { - } - - static int Compare(const Tuple& a, const Tuple& b) - { - if (a.f0 < b.f0) return -1; else if (a.f0 > b.f0) return 1;if (a.f1 < b.f1) return -1; else if (a.f1 > b.f1) return 1;if (a.f2 < b.f2) return -1; else if (a.f2 > b.f2) return 1;if (a.f3 < b.f3) return -1; else if (a.f3 > b.f3) return 1; - return 0; - } - - bool operator==(const Tuple& value)const{ return Compare(*this, value) == 0; } - bool operator!=(const Tuple& value)const{ return Compare(*this, value) != 0; } - bool operator< (const Tuple& value)const{ return Compare(*this, value) < 0; } - bool operator<=(const Tuple& value)const{ return Compare(*this, value) <= 0; } - bool operator> (const Tuple& value)const{ return Compare(*this, value) > 0; } - bool operator>=(const Tuple& value)const{ return Compare(*this, value) >= 0; } - }; - -/*********************************************************************** -vl::Tuple -***********************************************************************/ - template - class Tuple : public Object - { - public: - T0 f0;T1 f1;T2 f2;T3 f3;T4 f4; - - Tuple() - { - } - - Tuple(T0 p0,T1 p1,T2 p2,T3 p3,T4 p4) - :f0(p0),f1(p1),f2(p2),f3(p3),f4(p4) - { - } - - static int Compare(const Tuple& a, const Tuple& b) - { - if (a.f0 < b.f0) return -1; else if (a.f0 > b.f0) return 1;if (a.f1 < b.f1) return -1; else if (a.f1 > b.f1) return 1;if (a.f2 < b.f2) return -1; else if (a.f2 > b.f2) return 1;if (a.f3 < b.f3) return -1; else if (a.f3 > b.f3) return 1;if (a.f4 < b.f4) return -1; else if (a.f4 > b.f4) return 1; - return 0; - } - - bool operator==(const Tuple& value)const{ return Compare(*this, value) == 0; } - bool operator!=(const Tuple& value)const{ return Compare(*this, value) != 0; } - bool operator< (const Tuple& value)const{ return Compare(*this, value) < 0; } - bool operator<=(const Tuple& value)const{ return Compare(*this, value) <= 0; } - bool operator> (const Tuple& value)const{ return Compare(*this, value) > 0; } - bool operator>=(const Tuple& value)const{ return Compare(*this, value) >= 0; } - }; - -/*********************************************************************** -vl::Tuple -***********************************************************************/ - template - class Tuple : public Object - { - public: - T0 f0;T1 f1;T2 f2;T3 f3;T4 f4;T5 f5; - - Tuple() - { - } - - Tuple(T0 p0,T1 p1,T2 p2,T3 p3,T4 p4,T5 p5) - :f0(p0),f1(p1),f2(p2),f3(p3),f4(p4),f5(p5) - { - } - - static int Compare(const Tuple& a, const Tuple& b) - { - if (a.f0 < b.f0) return -1; else if (a.f0 > b.f0) return 1;if (a.f1 < b.f1) return -1; else if (a.f1 > b.f1) return 1;if (a.f2 < b.f2) return -1; else if (a.f2 > b.f2) return 1;if (a.f3 < b.f3) return -1; else if (a.f3 > b.f3) return 1;if (a.f4 < b.f4) return -1; else if (a.f4 > b.f4) return 1;if (a.f5 < b.f5) return -1; else if (a.f5 > b.f5) return 1; - return 0; - } - - bool operator==(const Tuple& value)const{ return Compare(*this, value) == 0; } - bool operator!=(const Tuple& value)const{ return Compare(*this, value) != 0; } - bool operator< (const Tuple& value)const{ return Compare(*this, value) < 0; } - bool operator<=(const Tuple& value)const{ return Compare(*this, value) <= 0; } - bool operator> (const Tuple& value)const{ return Compare(*this, value) > 0; } - bool operator>=(const Tuple& value)const{ return Compare(*this, value) >= 0; } - }; - -/*********************************************************************** -vl::Tuple -***********************************************************************/ - template - class Tuple : public Object - { - public: - T0 f0;T1 f1;T2 f2;T3 f3;T4 f4;T5 f5;T6 f6; - - Tuple() - { - } - - Tuple(T0 p0,T1 p1,T2 p2,T3 p3,T4 p4,T5 p5,T6 p6) - :f0(p0),f1(p1),f2(p2),f3(p3),f4(p4),f5(p5),f6(p6) - { - } - - static int Compare(const Tuple& a, const Tuple& b) - { - if (a.f0 < b.f0) return -1; else if (a.f0 > b.f0) return 1;if (a.f1 < b.f1) return -1; else if (a.f1 > b.f1) return 1;if (a.f2 < b.f2) return -1; else if (a.f2 > b.f2) return 1;if (a.f3 < b.f3) return -1; else if (a.f3 > b.f3) return 1;if (a.f4 < b.f4) return -1; else if (a.f4 > b.f4) return 1;if (a.f5 < b.f5) return -1; else if (a.f5 > b.f5) return 1;if (a.f6 < b.f6) return -1; else if (a.f6 > b.f6) return 1; - return 0; - } - - bool operator==(const Tuple& value)const{ return Compare(*this, value) == 0; } - bool operator!=(const Tuple& value)const{ return Compare(*this, value) != 0; } - bool operator< (const Tuple& value)const{ return Compare(*this, value) < 0; } - bool operator<=(const Tuple& value)const{ return Compare(*this, value) <= 0; } - bool operator> (const Tuple& value)const{ return Compare(*this, value) > 0; } - bool operator>=(const Tuple& value)const{ return Compare(*this, value) >= 0; } - }; - -/*********************************************************************** -vl::Tuple -***********************************************************************/ - template - class Tuple : public Object - { - public: - T0 f0;T1 f1;T2 f2;T3 f3;T4 f4;T5 f5;T6 f6;T7 f7; - - Tuple() - { - } - - Tuple(T0 p0,T1 p1,T2 p2,T3 p3,T4 p4,T5 p5,T6 p6,T7 p7) - :f0(p0),f1(p1),f2(p2),f3(p3),f4(p4),f5(p5),f6(p6),f7(p7) - { - } - - static int Compare(const Tuple& a, const Tuple& b) - { - if (a.f0 < b.f0) return -1; else if (a.f0 > b.f0) return 1;if (a.f1 < b.f1) return -1; else if (a.f1 > b.f1) return 1;if (a.f2 < b.f2) return -1; else if (a.f2 > b.f2) return 1;if (a.f3 < b.f3) return -1; else if (a.f3 > b.f3) return 1;if (a.f4 < b.f4) return -1; else if (a.f4 > b.f4) return 1;if (a.f5 < b.f5) return -1; else if (a.f5 > b.f5) return 1;if (a.f6 < b.f6) return -1; else if (a.f6 > b.f6) return 1;if (a.f7 < b.f7) return -1; else if (a.f7 > b.f7) return 1; - return 0; - } - - bool operator==(const Tuple& value)const{ return Compare(*this, value) == 0; } - bool operator!=(const Tuple& value)const{ return Compare(*this, value) != 0; } - bool operator< (const Tuple& value)const{ return Compare(*this, value) < 0; } - bool operator<=(const Tuple& value)const{ return Compare(*this, value) <= 0; } - bool operator> (const Tuple& value)const{ return Compare(*this, value) > 0; } - bool operator>=(const Tuple& value)const{ return Compare(*this, value) >= 0; } - }; - -/*********************************************************************** -vl::Tuple -***********************************************************************/ - template - class Tuple : public Object - { - public: - T0 f0;T1 f1;T2 f2;T3 f3;T4 f4;T5 f5;T6 f6;T7 f7;T8 f8; - - Tuple() - { - } - - Tuple(T0 p0,T1 p1,T2 p2,T3 p3,T4 p4,T5 p5,T6 p6,T7 p7,T8 p8) - :f0(p0),f1(p1),f2(p2),f3(p3),f4(p4),f5(p5),f6(p6),f7(p7),f8(p8) - { - } - - static int Compare(const Tuple& a, const Tuple& b) - { - if (a.f0 < b.f0) return -1; else if (a.f0 > b.f0) return 1;if (a.f1 < b.f1) return -1; else if (a.f1 > b.f1) return 1;if (a.f2 < b.f2) return -1; else if (a.f2 > b.f2) return 1;if (a.f3 < b.f3) return -1; else if (a.f3 > b.f3) return 1;if (a.f4 < b.f4) return -1; else if (a.f4 > b.f4) return 1;if (a.f5 < b.f5) return -1; else if (a.f5 > b.f5) return 1;if (a.f6 < b.f6) return -1; else if (a.f6 > b.f6) return 1;if (a.f7 < b.f7) return -1; else if (a.f7 > b.f7) return 1;if (a.f8 < b.f8) return -1; else if (a.f8 > b.f8) return 1; - return 0; - } - - bool operator==(const Tuple& value)const{ return Compare(*this, value) == 0; } - bool operator!=(const Tuple& value)const{ return Compare(*this, value) != 0; } - bool operator< (const Tuple& value)const{ return Compare(*this, value) < 0; } - bool operator<=(const Tuple& value)const{ return Compare(*this, value) <= 0; } - bool operator> (const Tuple& value)const{ return Compare(*this, value) > 0; } - bool operator>=(const Tuple& value)const{ return Compare(*this, value) >= 0; } - }; - -/*********************************************************************** -vl::Tuple -***********************************************************************/ - template - class Tuple : public Object - { - public: - T0 f0;T1 f1;T2 f2;T3 f3;T4 f4;T5 f5;T6 f6;T7 f7;T8 f8;T9 f9; - - Tuple() - { - } - - Tuple(T0 p0,T1 p1,T2 p2,T3 p3,T4 p4,T5 p5,T6 p6,T7 p7,T8 p8,T9 p9) - :f0(p0),f1(p1),f2(p2),f3(p3),f4(p4),f5(p5),f6(p6),f7(p7),f8(p8),f9(p9) - { - } - - static int Compare(const Tuple& a, const Tuple& b) - { - if (a.f0 < b.f0) return -1; else if (a.f0 > b.f0) return 1;if (a.f1 < b.f1) return -1; else if (a.f1 > b.f1) return 1;if (a.f2 < b.f2) return -1; else if (a.f2 > b.f2) return 1;if (a.f3 < b.f3) return -1; else if (a.f3 > b.f3) return 1;if (a.f4 < b.f4) return -1; else if (a.f4 > b.f4) return 1;if (a.f5 < b.f5) return -1; else if (a.f5 > b.f5) return 1;if (a.f6 < b.f6) return -1; else if (a.f6 > b.f6) return 1;if (a.f7 < b.f7) return -1; else if (a.f7 > b.f7) return 1;if (a.f8 < b.f8) return -1; else if (a.f8 > b.f8) return 1;if (a.f9 < b.f9) return -1; else if (a.f9 > b.f9) return 1; - return 0; - } - - bool operator==(const Tuple& value)const{ return Compare(*this, value) == 0; } - bool operator!=(const Tuple& value)const{ return Compare(*this, value) != 0; } - bool operator< (const Tuple& value)const{ return Compare(*this, value) < 0; } - bool operator<=(const Tuple& value)const{ return Compare(*this, value) <= 0; } - bool operator> (const Tuple& value)const{ return Compare(*this, value) > 0; } - bool operator>=(const Tuple& value)const{ return Compare(*this, value) >= 0; } - }; - -} -#endif - -/*********************************************************************** -.\COLLECTIONS\OPERATION.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -Data Structure::Operations - -Functions: - CopyFrom(TargetContainer, SourceContainer) - [T] .Select(T->K) => [K] - [T] .SelectMany(T->[K]) => [K] - [T] .Where(T->bool) => [T] - [Ptr].Cast() => [Ptr] - [Ptr].FindType() => [Ptr] - [T] .OrderBy(T->T->int) => [T] - - [T] .Aggregate(T->T->T) => T - [T] .Aggregate(T->T->T, T) => T - [T] .All(T->bool) => bool - [T] .Any(T->bool) => bool - [T] .Max() => T - [T] .Min() => T - [T] .First() => T - [T] .FirstOrDefault(T) => T - [T] .Last() => T - [T] .LastOrDefault(T) => T - [T] .Count() => vint - [T] .IsEmpty() => bool - - [T] .Concat([T]) => [T] - [T] .Repeat(vint) => [T] - [T] .Take(vint) => [T] - [T] .Skip(vint) => [T] - [T] .Distinct() => [T] - [T] .Reverse() => [T] - - [T] .Pairwise([K]) => [(T,K)] - [T] .Intersect([T]) => [T] - [T] .Union([T]) => [T] - [T] .Except([T]) => [T] - - [T] .Evaluate() => [T] - [T] .GroupBy(T->K) => [(K, [T])] - - From(begin, end) => [T] - From(array) => [T] - Range(start, count) => [vint] - - FOREACH(X, a, XList) - FOREACH_INDEXER(X, a, index, XList) -***********************************************************************/ - -#ifndef VCZH_COLLECTIONS_OPERATION -#define VCZH_COLLECTIONS_OPERATION - - -namespace vl -{ - namespace collections - { - -/*********************************************************************** -OrderBy Quick Sort -***********************************************************************/ - - template - void SortLambda(T* items, vint length, F orderer) - { - if(length==0) return; - vint pivot=0; - vint left=0; - vint right=0; - bool flag=false; - - while(left+right+1!=length) - { - vint& mine=(flag?left:right); - vint& theirs=(flag?right:left); - vint candidate=(flag?left:length-right-1); - vint factor=(flag?-1:1); - - if(orderer(items[pivot], items[candidate])*factor<=0) - { - mine++; - } - else - { - theirs++; - T temp=items[pivot]; - items[pivot]=items[candidate]; - items[candidate]=temp; - pivot=candidate; - flag=!flag; - } - } - - SortLambda(items, left, orderer); - SortLambda(items+left+1, right, orderer); - } - - template - void Sort(T* items, vint length, const Func& orderer) - { - SortLambda>(items, length, orderer); - } - -/*********************************************************************** -LazyList -***********************************************************************/ - - /// A lazy evaluated readonly container. - /// The type of elements. - template - class LazyList : public Object, public IEnumerable - { - protected: - Ptr> enumeratorPrototype; - - template - static U Element(const IEnumerable&); - - IEnumerator* xs()const - { - return enumeratorPrototype->Clone(); - } - public: - /// Create a lazy list with an enumerator. - /// The enumerator. - LazyList(IEnumerator* enumerator) - :enumeratorPrototype(enumerator) - { - } - - /// Create a lazy list with an enumerator. - /// The enumerator. - LazyList(Ptr> enumerator) - :enumeratorPrototype(enumerator) - { - } - - /// Create a lazy list with an enumerable. - /// The enumerator. - LazyList(const IEnumerable& enumerable) - :enumeratorPrototype(enumerable.CreateEnumerator()) - { - } - - /// Create a lazy list with an lazy list. - /// The lazy list. - LazyList(const LazyList& lazyList) - :enumeratorPrototype(lazyList.enumeratorPrototype) - { - } - - /// Create a lazy list with a container. - /// Type of the container. - /// The container. - template - LazyList(Ptr container) - :enumeratorPrototype(new ContainerEnumerator(container)) - { - } - - /// Create an empty lazy list. - LazyList() - :enumeratorPrototype(EmptyEnumerable().CreateEnumerator()) - { - } - - LazyList& operator=(const LazyList& lazyList) - { - enumeratorPrototype=lazyList.enumeratorPrototype; - return *this; - } - - IEnumerator* CreateEnumerator()const - { - return enumeratorPrototype->Clone(); - } - - //------------------------------------------------------- - - /// Create a new lazy list with all elements transformed. - /// Type of the lambda expression. - /// The created lazy list. - /// The lambda expression as a transformation function. - template - LazyList Select(F f)const - { - return new SelectEnumerator(xs(), f); - } - - /// Create a new lazy list with all elements that satisfy with a condition. - /// Type of the lambda expression. - /// The created lazy list. - /// The lambda expression as a filter. - template - LazyList Where(F f)const - { - return new WhereEnumerator(xs(), f); - } - - /// Create a new lazy list with all elements casted to a new type. - /// The new type. - /// The created lazy list. - template - LazyList> Cast()const - { - Func(T)> f=[](T t)->Ptr{return t.template Cast();}; - return new SelectEnumerator>(xs(), f); - } - - /// Create a new lazy list with only elements that successfully casted to a new type. - /// The new type. - /// The created lazy list. - template - LazyList> FindType()const - { - return Cast().Where([](Ptr t){return t;}); - } - - /// Create a new lazy list with all elements sorted. - /// Type of the lambda expression. - /// The created lazy list. - /// The lambda expression as a comparing function. - template - LazyList OrderBy(F f)const - { - Ptr> sorted=new List; - CopyFrom(*sorted.Obj(), *this); - if(sorted->Count()>0) - { - SortLambda(&sorted->operator[](0), sorted->Count(), f); - } - return new ContainerEnumerator>(sorted); - } - - //------------------------------------------------------- - - /// Aggregate a lazy list. An exception will raise if the lazy list is empty. - /// Type of the lambda expression. - /// The aggregated value. - /// The lambda expression as an aggregator. - template - T Aggregate(F f)const - { - Ptr> enumerator=CreateEnumerator(); - if(!enumerator->Next()) - { - throw Error(L"LazyList::Aggregate(F)#Aggregate failed to calculate from an empty container."); - } - T result=enumerator->Current(); - while(enumerator->Next()) - { - result=f(result, enumerator->Current()); - } - return result; - } - - /// Aggregate a lazy list. - /// Type of the initial value. - /// Type of the lambda expression. - /// The aggregated value. - /// The initial value that is virtually added before the lazy list. - /// The lambda expression as an aggregator. - template - I Aggregate(I init, F f)const - { - FOREACH(T, t, *this) - { - init=f(init, t); - } - return init; - } - - /// Test does all elements in the lazy list satisfy with a condition. - /// Type of the lambda expression. - /// Returns true if all elements satisfy with a condition. - /// The lambda expression as a filter. - template - bool All(F f)const - { - return Select(f).Aggregate(true, [](bool a, bool b){return a&&b;}); - } - - /// Test does any elements in the lazy list satisfy with a condition. - /// Type of the lambda expression. - /// Returns true if at least one element satisfies with a condition. - /// The lambda expression as a filter. - template - bool Any(F f)const - { - return Select(f).Aggregate(false, [](bool a, bool b){return a||b;}); - } - - /// Get the maximum value in the lazy list. An exception will raise if the lazy list is empty. - /// The maximum value. - T Max()const - { - return Aggregate([](T a, T b){return a>b?a:b;}); - } - - /// Get the minimum value in the lazy list. An exception will raise if the lazy list is empty. - /// The minimum value. - T Min()const - { - return Aggregate([](T a, T b){return aGet the first value in the lazy list. An exception will raise if the lazy list is empty. - /// The first value. - T First()const - { - Ptr> enumerator=CreateEnumerator(); - if(!enumerator->Next()) - { - throw Error(L"LazyList::First(F)#First failed to calculate from an empty container."); - } - return enumerator->Current(); - } - - /// Get the first value in the lazy list. - /// The first value. - /// Returns this argument if the lazy list is empty. - T First(T defaultValue)const - { - Ptr> enumerator=CreateEnumerator(); - if(!enumerator->Next()) - { - return defaultValue; - } - return enumerator->Current(); - } - - /// Get the last value in the lazy list. An exception will raise if the lazy list is empty. - /// The last value. - T Last()const - { - Ptr> enumerator=CreateEnumerator(); - if(!enumerator->Next()) - { - throw Error(L"LazyList::Last(F)#Last failed to calculate from an empty container."); - } - else - { - T value=enumerator->Current(); - while(enumerator->Next()) - { - value=enumerator->Current(); - } - return value; - } - } - - /// Get the last value in the lazy list. - /// The last value. - /// Returns this argument if the lazy list is empty. - T Last(T defaultValue)const - { - Ptr> enumerator=CreateEnumerator(); - while(enumerator->Next()) - { - defaultValue=enumerator->Current(); - } - return defaultValue; - } - - /// Get the number of elements in the lazy list. - /// The number of elements. - vint Count()const - { - vint result=0; - Ptr> enumerator=CreateEnumerator(); - while(enumerator->Next()) - { - result++; - } - return result; - } - - /// Test is the lazy list empty. - /// Returns true if the lazy list is empty. - bool IsEmpty()const - { - Ptr> enumerator=CreateEnumerator(); - return !enumerator->Next(); - } - - //------------------------------------------------------- - - /// Create a new lazy list containing elements of the two container one after another. - /// The created lazy list. - /// Elements that put after this lazy list. - LazyList Concat(const IEnumerable& remains)const - { - return new ConcatEnumerator(xs(), remains.CreateEnumerator()); - } - - /// Create a new lazy list with some prefix elements. - /// The created lazy list. - /// The size of the prefix. - LazyList Take(vint count)const - { - return new TakeEnumerator(xs(), count); - } - - /// Create a new lazy list without some prefix elements. - /// The created lazy list. - /// The size of the prefix. - LazyList Skip(vint count)const - { - return new SkipEnumerator(xs(), count); - } - - /// Create a new lazy list with several copies of this lazy list one after another. - /// The created lazy list. - /// The numbers of copies. - LazyList Repeat(vint count)const - { - return new RepeatEnumerator(xs(), count); - } - - /// Create a new lazy list with all elements in this lazy list. If some elements appear several times, only one will be kept. - /// The created lazy list. - LazyList Distinct()const - { - return new DistinctEnumerator(xs()); - } - - /// Create a new lazy list with all elements in this lazy list in a reverse order. - /// The created lazy list. - LazyList Reverse()const - { - return new ReverseEnumerator(*this); - } - - //------------------------------------------------------- - - /// Create a new lazy list of pairs from elements from two containers. - /// Type of all elements in the second container. - /// The created lazy list. - /// The second container. - template - LazyList> Pairwise(const IEnumerable& remains)const - { - return new PairwiseEnumerator(xs(), remains.CreateEnumerator()); - } - - /// Create a new lazy list with only elements that appear in both containers. - /// The created lazy list. - /// The second container. - LazyList Intersect(const IEnumerable& remains)const - { - return LazyList(new IntersectExceptEnumerator(xs(), remains)).Distinct(); - } - - /// Create a new lazy list with only elements that appear in this lazy list but not in another container. - /// The created lazy list. - /// The second container. - LazyList Except(const IEnumerable& remains)const - { - return LazyList(new IntersectExceptEnumerator(xs(), remains)).Distinct(); - } - - /// Create a new lazy list with elements in two containers. If some elements appear several times, only one will be kept. - /// The created lazy list. - /// The second container. - LazyList Union(const IEnumerable& remains)const - { - return Concat(remains).Distinct(); - } - - //------------------------------------------------------- - - LazyList Evaluate()const - { - if(enumeratorPrototype->Evaluated()) - { - return *this; - } - else - { - Ptr> xs=new List; - CopyFrom(*xs.Obj(), *this); - return xs; - } - } - - /// Create a new lazy list, whose elements are from transformed elements in this lazy list. - /// Type of the lambda expression. - /// The created lazy list. - /// The lambda expression as a transformation function to transform one element to multiple elements. - template - FUNCTION_RESULT_TYPE(F) SelectMany(F f)const - { - typedef FUNCTION_RESULT_TYPE(F) LazyListU; - typedef typename LazyListU::ElementType U; - return Select(f).Aggregate(LazyList(), [](const LazyList& a, const IEnumerable& b)->LazyList{return a.Concat(b);}); - } - - /// Create a new lazy list, whose elements are groupd by from elements in this lazy list. - /// Type of the lambda expression. - /// The created lazy list. - /// The lambda expression as a key retriver to calcuate a key from an element. - template - LazyList>> GroupBy(F f)const - { - typedef FUNCTION_RESULT_TYPE(F) K; - return Select(f) - .Distinct() - .Select([=](K k) - { - return Pair>( - k, - Where([=](T t){return k==f(t);}) - ); - }); - } - }; - - template - LazyList Range(T start, T count) - { - return new RangeEnumerator(start, count); - } - - template - LazyList From(const IEnumerable& enumerable) - { - return enumerable; - } - - template - LazyList From(const LazyList& enumerable) - { - return enumerable; - } - - template - LazyList From(const T* begin, const T* end) - { - return FromPointer(begin, end); - } - - template - LazyList From(T (&items)[size]) - { - return FromArray(items); - } - - template - LazyList From(const T (&items)[size]) - { - return FromArray(items); - } - } -} - -#endif - diff --git a/Import/VlppOS.h b/Import/VlppOS.h index 7c7457f8..a8c40fb9 100644 --- a/Import/VlppOS.h +++ b/Import/VlppOS.h @@ -4,6 +4,1027 @@ DEVELOPER: Zihan Chen(vczh) ***********************************************************************/ #include "Vlpp.h" +/*********************************************************************** +.\HTTPUTILITY.H +***********************************************************************/ +#ifndef VCZH_HTTPUTILITY +#define VCZH_HTTPUTILITY + + +#ifdef VCZH_MSVC + +namespace vl +{ + +/*********************************************************************** +HTTP Utility +***********************************************************************/ + + /// A type representing an http requiest. + class HttpRequest + { + typedef collections::Array BodyBuffer; + typedef collections::List StringList; + typedef collections::Dictionary HeaderMap; + public: + /// Name of the server, like "gaclib.net". + WString server; + /// Port of the server, like 80. + vint port; + /// Query of the request, like "/GettingStart.html". + WString query; + /// Set to true if the request uses SSL. + bool secure; + /// User name to authorize. Set to empty if you don't want to provide it. + WString username; + /// Password to authorize. Set to empty if you don't want to provide it. + WString password; + /// HTTP method, like "GET", "POST", "PUT", "DELETE", etc. + WString method; + /// Cookie. Set to empty if you don't want to provide it. + WString cookie; + /// Request body. This is a binary array using an array container to char. + BodyBuffer body; + /// Content type, like "text/xml". + WString contentType; + /// Accept type list, elements of it like "text/xml". + StringList acceptTypes; + /// A dictionary to contain extra headers. + HeaderMap extraHeaders; + + /// Create an empty request. + HttpRequest(); + + /// Set , , and fields for you using an URL. + /// Returns true if this operation succeeded. + /// The URL. + bool SetHost(const WString& inputQuery); + + /// Fill the body with a text using UTF-8 encoding. + /// The text to fill. + void SetBodyUtf8(const WString& bodyString); + }; + + /// A type representing an http response. + class HttpResponse + { + typedef collections::Array BodyBuffer; + public: + /// Status code, like 200. + vint statusCode; + /// Response body. This is a binary array using an array container to char. + BodyBuffer body; + /// Returned cookie from the server. + WString cookie; + + HttpResponse(); + + /// If you believe the server returns a text in UTF-8, use it to decode the body. + /// The response body as text. + WString GetBodyUtf8(); + }; + + /// Send an http request and receive a response. + /// Returns true if this operation succeeded. Even the server returns 404 will be treated as success, because you get the response. + /// The request. + /// The response. + extern bool HttpQuery(const HttpRequest& request, HttpResponse& response); + + /// Encode a text as part of the url. This function can be used to create arguments in an URL. + /// The encoded text. + /// The text to encode. + extern WString UrlEncodeQuery(const WString& query); +} + +#endif + +#endif + + +/*********************************************************************** +.\LOCALE.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +Framework::Locale + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_LOCALE +#define VCZH_LOCALE + + +namespace vl +{ + /// Locale awared operations. Macro "INVLOC" is a shortcut to get a invariant locale. + class Locale : public Object + { + protected: + WString localeName; + + public: + Locale(const WString& _localeName=WString::Empty); + ~Locale(); + + bool operator==(const Locale& value)const { return localeName==value.localeName; } + bool operator!=(const Locale& value)const { return localeName!=value.localeName; } + bool operator<(const Locale& value)const { return localeName(const Locale& value)const { return localeName>value.localeName; } + bool operator>=(const Locale& value)const { return localeName>=value.localeName; } + + /// Get the invariant locale. + /// The invariant locale. + static Locale Invariant(); + /// Get the system default locale. This locale controls the code page that used by the the system to interpret ANSI string buffers. + /// The system default locale. + static Locale SystemDefault(); + /// Get the user default locale. This locale reflect the user's setting. + /// The user default locale. + static Locale UserDefault(); + /// Get all supported locales. + /// All supported locales. + static void Enumerate(collections::List& locales); + + /// Get the name of the locale. + /// The name of the locale. + const WString& GetName()const; + + /// Get all short date formats for the locale. + /// The formats. + void GetShortDateFormats(collections::List& formats)const; + /// Get all long date formats for the locale. + /// The formats. + void GetLongDateFormats(collections::List& formats)const; + /// Get all Year-Month date formats for the locale. + /// The formats. + void GetYearMonthDateFormats(collections::List& formats)const; + /// Get all long time formats for the locale. + /// The formats. + void GetLongTimeFormats(collections::List& formats)const; + /// Get all short time formats for the locale. + /// The formats. + void GetShortTimeFormats(collections::List& formats)const; + + /// Convert a date to a formatted string. + /// The formatted string. + /// The format to use. + /// The date to convert. + WString FormatDate(const WString& format, DateTime date)const; + /// Convert a time to a formatted string. + /// The formatted string. + /// The format to use. + /// The time to convert. + WString FormatTime(const WString& format, DateTime time)const; + + /// Convert a number to a formatted string. + /// The formatted string. + /// The number to convert. + WString FormatNumber(const WString& number)const; + /// Convert a currency (money) to a formatted string. + /// The formatted string. + /// The currency to convert. + WString FormatCurrency(const WString& currency)const; + + /// Get the short display string of a day of week. + /// The display string. + /// Day of week, begins from 0 as Sunday. + WString GetShortDayOfWeekName(vint dayOfWeek)const; + /// Get the long display string of a day of week. + /// The display string. + /// Day of week, begins from 0 as Sunday. + WString GetLongDayOfWeekName(vint dayOfWeek)const; + /// Get the short display string of a month. + /// The display string. + /// Month, begins from 1 as January. + WString GetShortMonthName(vint month)const; + /// Get the long display string of a month. + /// The display string. + /// Month, begins from 1 as January. + WString GetLongMonthName(vint month)const; + +#ifdef VCZH_MSVC + /// Convert characters to the full width. + /// The converted string. + /// The string to convert. + WString ToFullWidth(const WString& str)const; + /// Convert characters to the half width. + /// The converted string. + /// The string to convert. + WString ToHalfWidth(const WString& str)const; + /// Convert characters to the Hiragana. + /// The converted string. + /// The string to convert. + WString ToHiragana(const WString& str)const; + /// Convert characters to the Katagana. + /// The converted string. + /// The string to convert. + WString ToKatagana(const WString& str)const; +#endif + + /// Convert characters to the lower case using the file system rule. + /// The converted string. + /// The string to convert. + WString ToLower(const WString& str)const; + /// Convert characters to the upper case using the file system rule. + /// The converted string. + /// The string to convert. + WString ToUpper(const WString& str)const; + /// Convert characters to the lower case using the linguistic rule. + /// The converted string. + /// The string to convert. + WString ToLinguisticLower(const WString& str)const; + /// Convert characters to the upper case using the linguistic rule. + /// The converted string. + /// The string to convert. + WString ToLinguisticUpper(const WString& str)const; + +#ifdef VCZH_MSVC + /// Convert characters to Simplified Chinese. + /// The converted string. + /// The string to convert. + WString ToSimplifiedChinese(const WString& str)const; + /// Convert characters to the Traditional Chinese. + /// The converted string. + /// The string to convert. + WString ToTraditionalChinese(const WString& str)const; + /// Convert characters to the tile case, in which the first letter of each major word is capitalized. + /// The converted string. + /// The string to convert. + WString ToTileCase(const WString& str)const; +#endif + + /// Mergable flags controlling how to normalize a string. + enum Normalization + { + /// Do nothing. + None=0, + /// Ignore case using the file system rule. + IgnoreCase=1, +#ifdef VCZH_MSVC + /// Ignore case using the linguistic rule. + IgnoreCaseLinguistic=2, + /// Ignore the difference between between hiragana and katakana characters. + IgnoreKanaType=4, + /// Ignore nonspacing characters. + IgnoreNonSpace=8, + /// Ignore symbols and punctuation. + IgnoreSymbol=16, + /// Ignore the difference between half-width and full-width characters. + IgnoreWidth=32, + /// Treat digits as numbers during sorting. + DigitsAsNumbers=64, + /// Treat punctuation the same as symbols. + StringSoft=128, +#endif + }; + + /// Compare two strings. + /// Returns 0 if two strings are equal. Returns a positive number if the first string is larger. Returns a negative number if the second string is larger. When sorting strings, larger strings are put after then smaller strings. + /// The first string to compare. + /// The second string to compare. + /// Flags controlling how to normalize a string. + vint Compare(const WString& s1, const WString& s2, Normalization normalization)const; + /// Compare two strings to test binary equivalence. + /// Returns 0 if two strings are equal. Returns a positive number if the first string is larger. Returns a negative number if the second string is larger. When sorting strings, larger strings are put after then smaller strings. + /// The first string to compare. + /// The second string to compare. + vint CompareOrdinal(const WString& s1, const WString& s2)const; + /// Compare two strings to test binary equivalence, ignoring case. + /// Returns 0 if two strings are equal. Returns a positive number if the first string is larger. Returns a negative number if the second string is larger. When sorting strings, larger strings are put after then smaller strings. + /// The first string to compare. + /// The second string to compare. + vint CompareOrdinalIgnoreCase(const WString& s1, const WString& s2)const; + /// Find the first position that the sub string appears in a text. + /// Returns a pair of numbers, the first number indicating the position in the text, the second number indicating the size of the equivalence sub string in the text. For some normalization, the found sub string may be binary different to the string you want to find. + /// The text to find the sub string. + /// The sub string to match. + /// Flags controlling how to normalize a string. + collections::Pair FindFirst(const WString& text, const WString& find, Normalization normalization)const; + /// Find the last position that the sub string appears in a text. + /// Returns a pair of numbers, the first number indicating the position in the text, the second number indicating the size of the equivalence sub string in the text. For some normalization, the found sub string may be binary different to the string you want to find. + /// The text to find the sub string. + /// The sub string to match. + /// Flags controlling how to normalize a string. + collections::Pair FindLast(const WString& text, const WString& find, Normalization normalization)const; + /// Test is the prefix of the text equivalence to the provided sub string. + /// Returns true if the prefix of the text equivalence to the provided sub string. + /// The text to test the prefix. + /// The sub string to match. + /// Flags controlling how to normalize a string. + bool StartsWith(const WString& text, const WString& find, Normalization normalization)const; + /// Test is the postfix of the text equivalence to the provided sub string. + /// Returns true if the postfix of the text equivalence to the provided sub string. + /// The text to test the postfix. + /// The sub string to match. + /// Flags controlling how to normalize a string. + bool EndsWith(const WString& text, const WString& find, Normalization normalization)const; + }; + +#define INVLOC vl::Locale::Invariant() +} + +#endif + +/*********************************************************************** +.\THREADING.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +Framework::Threading + +Classes: + Thread : Thread + CriticalSection + Mutex + Semaphore + EventObject +***********************************************************************/ + +#ifndef VCZH_THREADING +#define VCZH_THREADING + + +namespace vl +{ + +/*********************************************************************** +Kernel Mode Objects +***********************************************************************/ + + namespace threading_internal + { + struct WaitableData; + struct ThreadData; + struct MutexData; + struct SemaphoreData; + struct EventData; + struct CriticalSectionData; + struct ReaderWriterLockData; + struct ConditionVariableData; + } + + /// Base type of all synchronization objects. + class WaitableObject : public Object, public NotCopyable + { +#if defined VCZH_MSVC + private: + threading_internal::WaitableData* waitableData; + protected: + + WaitableObject(); + void SetData(threading_internal::WaitableData* data); + public: + /// Test if the object has already been created. Some of the synchronization objects should initialize itself after the constructor. This function is only available in Windows. + /// Returns true if the object has already been created. + bool IsCreated(); + /// Wait for this object to signal. + /// Returns true if the object is signaled. Returns false if this operation failed. + bool Wait(); + /// Wait for this object to signal for a period of time. This function is only available in Windows. + /// Returns true if the object is signaled. Returns false if this operation failed, including time out. + /// Time in milliseconds. + bool WaitForTime(vint ms); + + /// Wait for multiple objects. This function is only available in Windows. + /// Returns true if all objects are signaled. Returns false if this operation failed. + /// A pointer to an array to pointers. + /// The number of objects in the array. + static bool WaitAll(WaitableObject** objects, vint count); + /// Wait for multiple objects for a period of time. This function is only available in Windows. + /// Returns true if all objects are signaled. Returns false if this operation failed, including time out. + /// A pointer to an array to pointers. + /// The number of objects in the array. + /// Time in milliseconds. + static bool WaitAllForTime(WaitableObject** objects, vint count, vint ms); + /// Wait for one of the objects. This function is only available in Windows. + /// Returns the index of the first signaled or abandoned object, according to the "abandoned" parameter. Returns -1 if this operation failed. + /// A pointer to an array to pointers. + /// The number of objects in the array. + /// Returns true if the waiting is canceled by an abandoned object. An abandoned object is caused by it's owner thread existing without releasing it. + static vint WaitAny(WaitableObject** objects, vint count, bool* abandoned); + /// Wait for one of the objects for a period of time. This function is only available in Windows. + /// Returns the index of the first signaled or abandoned object, according to the "abandoned" parameter. Returns -1 if this operation failed, including time out. + /// A pointer to an array to pointers. + /// The number of objects in the array. + /// Time in milliseconds. + /// Returns true if the waiting is canceled by an abandoned object. An abandoned object is caused by it's owner thread existing without releasing it. + static vint WaitAnyForTime(WaitableObject** objects, vint count, vint ms, bool* abandoned); +#elif defined VCZH_GCC + virtual bool Wait() = 0; +#endif + }; + + /// Representing a thread. [M:vl.Thread.CreateAndStart] is the suggested way to create threads. + class Thread : public WaitableObject + { + friend void InternalThreadProc(Thread* thread); + public: + /// Thread state. + enum ThreadState + { + /// The thread has not started. + NotStarted, + /// The thread is running. + Running, + /// The thread has been stopped. + Stopped + }; + + typedef void(*ThreadProcedure)(Thread*, void*); + protected: + threading_internal::ThreadData* internalData; + volatile ThreadState threadState; + + virtual void Run()=0; + + Thread(); + public: + ~Thread(); + + /// Create a thread using a function pointer. + /// Returns the created thread. + /// The function pointer. + /// The argument to call the function pointer. + /// Set to true (by default) to make the thread delete itself after the job is done. If you set this argument to true, you are not suggested to touch the returned thread pointer in any way. + static Thread* CreateAndStart(ThreadProcedure procedure, void* argument=0, bool deleteAfterStopped=true); + /// Create a thread using a function object or a lambda expression. + /// Returns the created thread. + /// The function object or the lambda expression. + /// Set to true (by default) to make the thread delete itself after the job is done. If you set this argument to true, you are not suggested to touch the returned thread pointer in any way. + static Thread* CreateAndStart(const Func& procedure, bool deleteAfterStopped=true); + /// Pause the caller thread for a period of time. + /// Time in milliseconds. + static void Sleep(vint ms); + /// Get the number of logical processors. + /// The number of logical processor. + static vint GetCPUCount(); + /// Get the current thread id. + /// The current thread id. + static vint GetCurrentThreadId(); + + /// Start the thread. + /// Returns true if this operation succeeded. + bool Start(); +#if defined VCZH_GCC + bool Wait(); +#endif + /// Stop the thread. + /// Returns true if this operation succeeded. + bool Stop(); + /// Get the state of the thread. + /// The state of the thread. + ThreadState GetState(); +#ifdef VCZH_MSVC + void SetCPU(vint index); +#endif + }; + + /// Mutex. + class Mutex : public WaitableObject + { + private: + threading_internal::MutexData* internalData; + public: + Mutex(); + ~Mutex(); + + /// Create a mutex. + /// Returns true if this operation succeeded. + /// Set to true to own the created mutex. + /// Name of the mutex. If it is not empty, than it is a global named mutex. This argument is ignored in Linux. + bool Create(bool owned=false, const WString& name=L""); + /// Open an existing global named mutex. + /// Returns true if this operation succeeded. + /// Set to true make the mutex visible to all all child processes. This argument is only used in Windows. + /// Name of the mutex. This argument is ignored in Linux. + bool Open(bool inheritable, const WString& name); + + /// + /// Release the mutex. + /// In the implementation for Linux, calling Release() more than once between two Wait(), or calling Wait() more than once between two Release(), will results in an undefined behavior. + /// + /// Returns true if this operation succeeded. + bool Release(); +#ifdef VCZH_GCC + bool Wait(); +#endif + }; + + /// Semaphore. + class Semaphore : public WaitableObject + { + private: + threading_internal::SemaphoreData* internalData; + public: + Semaphore(); + ~Semaphore(); + + /// Create a semaphore. + /// Returns true if this operation succeeded. + /// Define the counter of the semaphore. + /// Define the maximum value of the counter of the semaphore. This argument is only used in Windows. + /// Name of the semaphore. If it is not empty, than it is a global named semaphore. This argument is ignored in Linux. + bool Create(vint initialCount, vint maxCount, const WString& name=L""); + /// Open an existing global named semaphore. + /// Returns true if this operation succeeded. + /// Set to true make the semaphore visible to all all child processes. This argument is only used in Windows. + /// Name of the semaphore. This argument is ignored in Linux. + bool Open(bool inheritable, const WString& name); + + /// Release the semaphore once. + /// Returns true if this operation succeeded. + bool Release(); + /// Release the semaphore multiple times. + /// Returns true if this operation succeeded. + /// The amout to release. + vint Release(vint count); +#ifdef VCZH_GCC + bool Wait(); +#endif + }; + + /// Event. + class EventObject : public WaitableObject + { + private: + threading_internal::EventData* internalData; + public: + EventObject(); + ~EventObject(); + + /// Create an auto unsignal event. Auto unsignal means, when one thread waits for the event and succeeded, the event will become unsignaled immediately. + /// Returns true if this operation succeeded. + /// Set to true make the event signaled at the beginning. + /// Name of the event. If it is not empty, than it is a global named mutex. This argument is only used in Windows. + bool CreateAutoUnsignal(bool signaled, const WString& name=L""); + /// Create a manual unsignal event. + /// Returns true if this operation succeeded. + /// Set to true make the event signaled at the beginning. + /// Name of the event. If it is not empty, than it is a global named mutex. This argument is only used in Windows. + bool CreateManualUnsignal(bool signaled, const WString& name=L""); + /// Open an existing global named event. + /// Returns true if this operation succeeded. + /// Set to true make the event visible to all all child processes. This argument is only used in Windows. + /// Name of the event. This argument is only used in Windows. + bool Open(bool inheritable, const WString& name); + + /// Signal the event. + /// Returns true if this operation succeeded. + bool Signal(); + /// Unsignal the event. + /// Returns true if this operation succeeded. + bool Unsignal(); +#ifdef VCZH_GCC + bool Wait(); +#endif + }; + +/*********************************************************************** +Thread Pool +***********************************************************************/ + + /// A light-weight thread pool. + class ThreadPoolLite : public Object + { + private: + ThreadPoolLite(); + ~ThreadPoolLite(); + public: + /// Queue a function pointer. + /// Returns true if this operation succeeded. + /// The function pointer. + /// The argument to call the function pointer. + static bool Queue(void(*proc)(void*), void* argument); + /// Queue a function object. + /// Returns true if this operation succeeded. + /// The function object. + static bool Queue(const Func& proc); + + /// Queue a lambda expression. + /// The type of the lambda expression. + /// The lambda expression. + template + static void QueueLambda(const T& proc) + { + Queue(Func(proc)); + } + +#ifdef VCZH_GCC + static bool Stop(bool discardPendingTasks); +#endif + }; + +/*********************************************************************** +Kernel Mode Objects in Process +***********************************************************************/ + + /// + /// } + /// ]]> + class CriticalSection : public Object, public NotCopyable + { + private: + friend class ConditionVariable; + threading_internal::CriticalSectionData* internalData; + public: + /// Create a critical section. + CriticalSection(); + ~CriticalSection(); + + /// Try enter a critical section. This function will return immediately. + /// Returns true if the current thread owned the critical section. + bool TryEnter(); + /// Enter a critical section. + void Enter(); + /// Leave a critical section. + void Leave(); + + public: + class Scope : public Object, public NotCopyable + { + private: + CriticalSection* criticalSection; + public: + Scope(CriticalSection& _criticalSection); + ~Scope(); + }; + }; + + /// + /// } + /// or + /// WRITER_LOCK(yourLock) + /// { + /// + /// } + /// ]]> + class ReaderWriterLock : public Object, public NotCopyable + { + private: + friend class ConditionVariable; + threading_internal::ReaderWriterLockData* internalData; + public: + /// Create a reader writer lock. + ReaderWriterLock(); + ~ReaderWriterLock(); + + /// Try acquire a reader lock. This function will return immediately. + /// Returns true if the current thread acquired the reader lock. + bool TryEnterReader(); + /// Acquire a reader lock. + void EnterReader(); + /// Release a reader lock. + void LeaveReader(); + /// Try acquire a writer lock. This function will return immediately. + /// Returns true if the current thread acquired the writer lock. + bool TryEnterWriter(); + /// Acquire a writer lock. + void EnterWriter(); + /// Release a writer lock. + void LeaveWriter(); + public: + class ReaderScope : public Object, public NotCopyable + { + private: + ReaderWriterLock* lock; + public: + ReaderScope(ReaderWriterLock& _lock); + ~ReaderScope(); + }; + + class WriterScope : public Object, public NotCopyable + { + private: + ReaderWriterLock* lock; + public: + WriterScope(ReaderWriterLock& _lock); + ~WriterScope(); + }; + }; + + /// Conditional variable. + class ConditionVariable : public Object, public NotCopyable + { + private: + threading_internal::ConditionVariableData* internalData; + public: + /// Create a conditional variable. + ConditionVariable(); + ~ConditionVariable(); + + /// Bind a conditional variable with a owned critical section and release it. When the function returns, the condition variable is activated, and the current thread owned the critical section again. + /// Returns true if this operation succeeded. + /// The critical section. + bool SleepWith(CriticalSection& cs); +#ifdef VCZH_MSVC + /// Bind a conditional variable with a owned critical section and release it for a period of time. When the function returns, the condition variable is activated or it is time out, and the current thread owned the critical section again. This function is only available in Windows. + /// Returns true if this operation succeeded. + /// The critical section. + /// Time in milliseconds. + bool SleepWithForTime(CriticalSection& cs, vint ms); + /// Bind a conditional variable with a owned reader lock and release it. When the function returns, the condition variable is activated, and the current thread owned the reader lock again. This function is only available in Windows. + /// Returns true if this operation succeeded. + /// The reader lock. + bool SleepWithReader(ReaderWriterLock& lock); + /// Bind a conditional variable with a owned reader lock and release it for a period of time. When the function returns, the condition variable is activated or it is time out, and the current thread owned the reader lock again. This function is only available in Windows. + /// Returns true if this operation succeeded. + /// The reader lock. + /// Time in milliseconds. + bool SleepWithReaderForTime(ReaderWriterLock& lock, vint ms); + /// Bind a conditional variable with a owned writer lock and release it. When the function returns, the condition variable is activated, and the current thread owned the writer lock again. This function is only available in Windows. + /// Returns true if this operation succeeded. + /// The writer lock. + bool SleepWithWriter(ReaderWriterLock& lock); + /// Bind a conditional variable with a owned writer lock and release it for a period of time. When the function returns, the condition variable is activated or it is time out, and the current thread owned the writer lock again. This function is only available in Windows. + /// Returns true if this operation succeeded. + /// The writer lock. + /// Time in milliseconds. + bool SleepWithWriterForTime(ReaderWriterLock& lock, vint ms); +#endif + /// Wake one thread that pending on this condition variable. + void WakeOnePending(); + /// Wake all thread that pending on this condition variable. + void WakeAllPendings(); + }; + +/*********************************************************************** +User Mode Objects +***********************************************************************/ + + typedef long LockedInt; + + /// + /// } + /// ]]> + class SpinLock : public Object, public NotCopyable + { + protected: + volatile LockedInt token; + public: + /// Create a spin lock. + SpinLock(); + ~SpinLock(); + + /// Try enter a spin lock. This function will return immediately. + /// Returns true if the current thread owned the spin lock. + bool TryEnter(); + /// Enter a spin lock. + void Enter(); + /// Leave a spin lock. + void Leave(); + + public: + class Scope : public Object, public NotCopyable + { + private: + SpinLock* spinLock; + public: + Scope(SpinLock& _spinLock); + ~Scope(); + }; + }; + +#define SPIN_LOCK(LOCK) SCOPE_VARIABLE(const SpinLock::Scope&, scope, LOCK) +#define CS_LOCK(LOCK) SCOPE_VARIABLE(const CriticalSection::Scope&, scope, LOCK) +#define READER_LOCK(LOCK) SCOPE_VARIABLE(const ReaderWriterLock::ReaderScope&, scope, LOCK) +#define WRITER_LOCK(LOCK) SCOPE_VARIABLE(const ReaderWriterLock::WriterScope&, scope, LOCK) + +/*********************************************************************** +Thread Local Storage + +ThreadLocalStorage and ThreadVariable are designed to be used as global value types only. +Dynamically create instances of them are undefined behavior. +***********************************************************************/ + + /// Thread local storage operations. + class ThreadLocalStorage : public Object, private NotCopyable + { + typedef void(*Destructor)(void*); + protected: + vuint64_t key; + Destructor destructor; + volatile bool disposed = false; + + static void PushStorage(ThreadLocalStorage* storage); + public: + ThreadLocalStorage(Destructor _destructor); + ~ThreadLocalStorage(); + + void* Get(); + void Set(void* data); + void Clear(); + void Dispose(); + + /// Fix all storage creation. + static void FixStorages(); + /// Clear all storages for the current thread. For threads that are created using [T:vl.Thread], this function will be automatically called when before the thread exit. + static void ClearStorages(); + /// Clear all storages for the current thread (should be the main thread) and clear all records. This function can only be called by the main thread when all other threads are exited. It will reduce noices when you want to detect memory leaks. + static void DisposeStorages(); + }; + + /// Thread local variable. This type can only be used to define global variables. Different threads can store different values to and obtain differnt values from a thread local variable. + /// Type of the storage. + template + class ThreadVariable : public Object, private NotCopyable + { + protected: + ThreadLocalStorage storage; + + static void Destructor(void* data) + { + if (data) + { + delete (T*)data; + } + } + public: + /// Create a thread local variable. + ThreadVariable() + :storage(&Destructor) + { + } + + ~ThreadVariable() + { + } + + /// Test if the storage has data. + /// Returns true if the storage has data. + bool HasData() + { + return storage.Get() != nullptr; + } + + /// Remove the data from this storage. + void Clear() + { + storage.Clear(); + } + + /// Get the stored data. + /// The stored ata. + T& Get() + { + return *(T*)storage.Get(); + } + + /// Set data to this storage. + /// The data to set. + void Set(const T& value) + { + storage.Clear(); + storage.Set(new T(value)); + } + }; + + template + class ThreadVariable : public Object, private NotCopyable + { + protected: + ThreadLocalStorage storage; + + public: + ThreadVariable() + :storage(nullptr) + { + } + + ~ThreadVariable() + { + } + + bool HasData() + { + return storage.Get() != nullptr; + } + + void Clear() + { + storage.Set(nullptr); + } + + T* Get() + { + return (T*)storage.Get(); + } + + void Set(T* value) + { + storage.Set((void*)value); + } + }; + +/*********************************************************************** +RepeatingTaskExecutor +***********************************************************************/ + + /// Queued task executor. It is different from a thread pool by: 1) Task execution is single threaded, 2) If you queue a task, it will override the the unexecuted queued task. + /// The type of the argument to run a task. + template + class RepeatingTaskExecutor : public Object + { + private: + SpinLock inputLock; + T inputData; + volatile bool inputDataAvailable; + SpinLock executingEvent; + volatile bool executing; + + void ExecutingProcInternal() + { + while(true) + { + bool currentInputDataAvailable; + T currentInputData; + SPIN_LOCK(inputLock) + { + currentInputData=inputData; + inputData=T(); + currentInputDataAvailable=inputDataAvailable; + inputDataAvailable=false; + if(!currentInputDataAvailable) + { + executing=false; + goto FINISH_EXECUTING; + } + } + Execute(currentInputData); + } + FINISH_EXECUTING: + executingEvent.Leave(); + } + + static void ExecutingProc(void* argument) + { + ((RepeatingTaskExecutor*)argument)->ExecutingProcInternal(); + } + + protected: + /// This function is called when it is ready to execute a task. Task execution is single threaded. All task code should be put inside the function. + /// The argument to run a task. + virtual void Execute(const T& input)=0; + + public: + /// Create a task executor. + RepeatingTaskExecutor() + :inputDataAvailable(false) + ,executing(false) + { + } + + ~RepeatingTaskExecutor() + { + EnsureTaskFinished(); + } + + /// Wait for all tasks to finish. + void EnsureTaskFinished() + { + executingEvent.Enter(); + executingEvent.Leave(); + } + + /// Queue a task. If there is a queued task that has not been executied yet, those tasks will be canceled. Only one task can be queued at the same moment. + /// The argument to run a task. + void SubmitTask(const T& input) + { + SPIN_LOCK(inputLock) + { + inputData=input; + inputDataAvailable=true; + } + if(!executing) + { + executing=true; + executingEvent.Enter(); + ThreadPoolLite::Queue(&ExecutingProc, this); + } + } + }; +} +#endif + + /*********************************************************************** .\STREAM\INTERFACES.H ***********************************************************************/ @@ -124,6 +1145,329 @@ namespace vl #endif +/*********************************************************************** +.\STREAM\BROADCASTSTREAM.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +Stream::BroadcastStream + +Interfaces: + BroadcastStream : Stream that copy the written data to multiple streams +***********************************************************************/ + +#ifndef VCZH_STREAM_BROADCASTSTREAM +#define VCZH_STREAM_BROADCASTSTREAM + + +namespace vl +{ + namespace stream + { + /// A writable stream that copy written content to multiple target streams. + class BroadcastStream : public Object, public virtual IStream + { + typedef collections::List StreamList; + protected: + bool closed; + pos_t position; + StreamList streams; + public: + /// Create a strema. + BroadcastStream(); + ~BroadcastStream(); + + /// Get the list of target streams. You can add streams to this list, or remove streams from this list. + /// The list of target streams. + StreamList& Targets(); + bool CanRead()const; + bool CanWrite()const; + bool CanSeek()const; + bool CanPeek()const; + bool IsLimited()const; + bool IsAvailable()const; + void Close(); + pos_t Position()const; + pos_t Size()const; + void Seek(pos_t _size); + void SeekFromBegin(pos_t _size); + void SeekFromEnd(pos_t _size); + vint Read(void* _buffer, vint _size); + vint Write(void* _buffer, vint _size); + vint Peek(void* _buffer, vint _size); + }; + } +} + +#endif + +/*********************************************************************** +.\STREAM\CACHESTREAM.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +Stream::CacheStream + +Interfaces: + CacheStream : Stream that provide a cache for reading and writing +***********************************************************************/ + +#ifndef VCZH_STREAM_CACHESTREAM +#define VCZH_STREAM_CACHESTREAM + + +namespace vl +{ + namespace stream + { + /// + /// A cache stream. Features (readable, writable, seekable, peekable) are enabled according to the target stream. + /// When you read from the cache strema, it will read a specified size of content from the target stream first and cache, reducing the numbers of operations on the target stream. + /// When you write to the cache strema, it will save them to a buffer, and write to the target stream until the buffer reaches a specified size, reducing the numbers of operations on the target stream. + /// + class CacheStream : public Object, public virtual IStream + { + protected: + IStream* target; + vint block; + pos_t start; + pos_t position; + + char* buffer; + vint dirtyStart; + vint dirtyLength; + vint availableLength; + pos_t operatedSize; + + void Flush(); + void Load(pos_t _position); + vint InternalRead(void* _buffer, vint _size); + vint InternalWrite(void* _buffer, vint _size); + public: + /// Create a cache stream using a target stream. + /// The target stream. + /// Size of the cache. + CacheStream(IStream& _target, vint _block=65536); + ~CacheStream(); + + bool CanRead()const; + bool CanWrite()const; + bool CanSeek()const; + bool CanPeek()const; + bool IsLimited()const; + bool IsAvailable()const; + void Close(); + pos_t Position()const; + pos_t Size()const; + void Seek(pos_t _size); + void SeekFromBegin(pos_t _size); + void SeekFromEnd(pos_t _size); + vint Read(void* _buffer, vint _size); + vint Write(void* _buffer, vint _size); + vint Peek(void* _buffer, vint _size); + }; + } +} + +#endif + +/*********************************************************************** +.\STREAM\COMPRESSIONSTREAM.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +Stream::CharFormat + +Classes: +***********************************************************************/ + +#ifndef VCZH_STREAM_COMPRESSIONSTREAM +#define VCZH_STREAM_COMPRESSIONSTREAM + + +namespace vl +{ + namespace stream + { + +/*********************************************************************** +Compression +***********************************************************************/ + + namespace lzw + { + static const vint BufferSize = 1024; + static const vint MaxDictionarySize = 1 << 24; + + struct Code + { + typedef collections::PushOnlyAllocator CodeAllocator; + typedef collections::ByteObjectMap::Allocator MapAllocator; + + vuint8_t byte = 0; + vint code = -1; + Code* parent = 0; + vint size = 0; + collections::ByteObjectMap children; + }; + } + + class LzwBase : public Object + { + protected: + lzw::Code::CodeAllocator codeAllocator; + lzw::Code::MapAllocator mapAllocator; + lzw::Code* root; + vint eofIndex = -1; + vint nextIndex = 0; + vint indexBits = 1; + + void UpdateIndexBits(); + lzw::Code* CreateCode(lzw::Code* parent, vuint8_t byte); + + LzwBase(); + LzwBase(bool (&existingBytes)[256]); + ~LzwBase(); + }; + + /// An encoder to compress using Lzw algorithm. + class LzwEncoder : public LzwBase, public IEncoder + { + protected: + IStream* stream = 0; + + vuint8_t buffer[lzw::BufferSize]; + vint bufferUsedBits = 0; + lzw::Code* prefix; + + void Flush(); + void WriteNumber(vint number, vint bitSize); + public: + /// Create an encoder. + LzwEncoder(); + /// Create an encoder and tell it which byte will never appear in the data before compression. + /// An array to tell the encoder which byte will never appear in the data before compression. + LzwEncoder(bool (&existingBytes)[256]); + ~LzwEncoder(); + + void Setup(IStream* _stream)override; + void Close()override; + vint Write(void* _buffer, vint _size)override; + }; + + /// An decoder to decompress using Lzw algorithm. + class LzwDecoder :public LzwBase, public IDecoder + { + protected: + IStream* stream = 0; + collections::List dictionary; + lzw::Code* lastCode = 0; + + vuint8_t inputBuffer[lzw::BufferSize]; + vint inputBufferSize = 0; + vint inputBufferUsedBits = 0; + + collections::Array outputBuffer; + vint outputBufferSize = 0; + vint outputBufferUsedBytes = 0; + + bool ReadNumber(vint& number, vint bitSize); + void PrepareOutputBuffer(vint size); + void ExpandCodeToOutputBuffer(lzw::Code* code); + public: + /// Create an decoder. + LzwDecoder(); + /// Create an decoder and tell it which byte will never appear in the data before compression. + /// An array to tell the encoder which byte will never appear in the data before compression. + LzwDecoder(bool (&existingBytes)[256]); + ~LzwDecoder(); + + void Setup(IStream* _stream)override; + void Close()override; + vint Read(void* _buffer, vint _size)override; + }; + +/*********************************************************************** +Helper Functions +***********************************************************************/ + + extern vint CopyStream(stream::IStream& inputStream, stream::IStream& outputStream); + extern void CompressStream(stream::IStream& inputStream, stream::IStream& outputStream); + extern void DecompressStream(stream::IStream& inputStream, stream::IStream& outputStream); + } +} + +#endif + +/*********************************************************************** +.\STREAM\FILESTREAM.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +Stream::FileStream + +Interfaces: + FileStream : File stream +***********************************************************************/ + +#ifndef VCZH_STREAM_FILESTREAM +#define VCZH_STREAM_FILESTREAM + +#include + +namespace vl +{ + namespace stream + { + /// A file stream. It is readable when you use [F:vl.stream.FileStream.AccessRight.ReadOnly] or [F:vl.stream.FileStream.AccessRight.ReadWrite] to create the stream. It is writable when you use [F:vl.stream.FileStream.AccessRight.WriteOnly] or [F:vl.stream.FileStream.AccessRight.ReadWrite] to create the stream. + class FileStream : public Object, public virtual IStream + { + public: + /// Access to the file. + enum AccessRight + { + /// The file is opened to read. + ReadOnly, + /// The file is opened to write. + WriteOnly, + /// The file is opened to both read and write. + ReadWrite + }; + protected: + AccessRight accessRight; + FILE* file; + public: + /// Create a stream. + /// File to operate. + /// Operations want to perform on the file. + FileStream(const WString& fileName, AccessRight _accessRight); + ~FileStream(); + + bool CanRead()const; + bool CanWrite()const; + bool CanSeek()const; + bool CanPeek()const; + bool IsLimited()const; + bool IsAvailable()const; + void Close(); + pos_t Position()const; + pos_t Size()const; + void Seek(pos_t _size); + void SeekFromBegin(pos_t _size); + void SeekFromEnd(pos_t _size); + vint Read(void* _buffer, vint _size); + vint Write(void* _buffer, vint _size); + vint Peek(void* _buffer, vint _size); + }; + } +} + +#endif + /*********************************************************************** .\STREAM\MEMORYSTREAM.H ***********************************************************************/ @@ -183,6 +1527,231 @@ namespace vl #endif +/*********************************************************************** +.\STREAM\ACCESSOR.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +Stream::Accessor + +Classes: + TextReader : Text reader base class + TextWriter : Text writer base class + StringReader : Text reader from a string + StreamReader : Text reader from a stream + StreamWriter : Text writer to a stream + EncoderStream : Stream that takes an encoder to translate another stream + DecoderStream : Stream that takes a decoder to translate another stream +***********************************************************************/ + +#ifndef VCZH_STREAM_ACCESSOR +#define VCZH_STREAM_ACCESSOR + + +namespace vl +{ + namespace stream + { + +/*********************************************************************** +Text Related +***********************************************************************/ + + /// Text reader. All line breaks are normalized to CRLF regardless the format in the source. + class TextReader : public Object, private NotCopyable + { + public: + /// Test does the reader reach the end or not. + /// Returns true if the reader reaches the end. + virtual bool IsEnd()=0; + /// Read a single character. + /// The character. + virtual wchar_t ReadChar()=0; + /// Read a string of a specified size. + /// The string. + /// Expected length of the string to read. + virtual WString ReadString(vint length); + /// Read a string until a line breaks is reached. + /// The string. It does not contain the line break. + virtual WString ReadLine(); + /// Read everying remain. + /// The string. + virtual WString ReadToEnd(); + }; + + /// Text writer. + class TextWriter : public Object, private NotCopyable + { + public: + /// Write a single character. + /// The character to write. + virtual void WriteChar(wchar_t c)=0; + /// Write a string. + /// Buffer to the string to write. + /// Size of the string in characters not including the zero terminator. + virtual void WriteString(const wchar_t* string, vint charCount); + /// Write a string. + /// Buffer to the zero terminated string to write. + virtual void WriteString(const wchar_t* string); + /// Write a string. + /// The string to write. + virtual void WriteString(const WString& string); + /// Write a string with a CRLF. + /// Buffer to the string to write. + /// Size of the string in characters not including the zero terminator. + virtual void WriteLine(const wchar_t* string, vint charCount); + /// Write a string with a CRLF. + /// Buffer to the zero terminated string to write. + virtual void WriteLine(const wchar_t* string); + /// Write a string with a CRLF. + /// The string to write. + virtual void WriteLine(const WString& string); + + virtual void WriteMonospacedEnglishTable(collections::Array& tableByRow, vint rows, vint columns); + }; + + /// Text reader from a string. + class StringReader : public TextReader + { + protected: + WString string; + vint current; + bool lastCallIsReadLine; + + void PrepareIfLastCallIsReadLine(); + public: + /// Create a text reader. + /// The string to read. + StringReader(const WString& _string); + + bool IsEnd(); + wchar_t ReadChar(); + WString ReadString(vint length); + WString ReadLine(); + WString ReadToEnd(); + }; + + /// Text reader from a stream. + class StreamReader : public TextReader + { + protected: + IStream* stream; + public: + /// Create a text reader. + /// The stream to read. + StreamReader(IStream& _stream); + + bool IsEnd(); + wchar_t ReadChar(); + }; + + /// Text writer to a stream. + class StreamWriter : public TextWriter + { + protected: + IStream* stream; + public: + /// Create a text writer. + /// The stream to write. + StreamWriter(IStream& _stream); + using TextWriter::WriteString; + + void WriteChar(wchar_t c); + void WriteString(const wchar_t* string, vint charCount); + }; + +/*********************************************************************** +Encoding Related +***********************************************************************/ + + /// Encoder stream, a writable stream using an [T:vl.stream.IEncoder] to transform content. + class EncoderStream : public virtual IStream + { + protected: + IStream* stream; + IEncoder* encoder; + pos_t position; + + public: + /// Create a stream. + /// The target stream to write. + /// The encoder to transform content. + EncoderStream(IStream& _stream, IEncoder& _encoder); + ~EncoderStream(); + + bool CanRead()const; + bool CanWrite()const; + bool CanSeek()const; + bool CanPeek()const; + bool IsLimited()const; + bool IsAvailable()const; + void Close(); + pos_t Position()const; + pos_t Size()const; + void Seek(pos_t _size); + void SeekFromBegin(pos_t _size); + void SeekFromEnd(pos_t _size); + vint Read(void* _buffer, vint _size); + vint Write(void* _buffer, vint _size); + vint Peek(void* _buffer, vint _size); + }; + + /// Decoder stream, a readable stream using an [T:vl.stream.IDecoder] to transform content. + class DecoderStream : public virtual IStream + { + protected: + IStream* stream; + IDecoder* decoder; + pos_t position; + + public: + /// Create a stream. + /// The target stream to read. + /// The decoder to transform content. + DecoderStream(IStream& _stream, IDecoder& _decoder); + ~DecoderStream(); + + bool CanRead()const; + bool CanWrite()const; + bool CanSeek()const; + bool CanPeek()const; + bool IsLimited()const; + bool IsAvailable()const; + void Close(); + pos_t Position()const; + pos_t Size()const; + void Seek(pos_t _size); + void SeekFromBegin(pos_t _size); + void SeekFromEnd(pos_t _size); + vint Read(void* _buffer, vint _size); + vint Write(void* _buffer, vint _size); + vint Peek(void* _buffer, vint _size); + }; + +/*********************************************************************** +Helper Functions +***********************************************************************/ + + template + WString GenerateToStream(const TCallback& callback, vint block = 65536) + { + MemoryStream stream(block); + { + StreamWriter writer(stream); + callback(writer); + } + stream.SeekFromBegin(0); + { + StreamReader reader(stream); + return reader.ReadToEnd(); + } + } + } +} + +#endif + /*********************************************************************** .\STREAM\MEMORYWRAPPERSTREAM.H ***********************************************************************/ @@ -1144,1575 +2713,6 @@ namespace vl #endif -/*********************************************************************** -.\LOCALE.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -Framework::Locale - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_LOCALE -#define VCZH_LOCALE - - -namespace vl -{ - /// Locale awared operations. Macro "INVLOC" is a shortcut to get a invariant locale. - class Locale : public Object - { - protected: - WString localeName; - - public: - Locale(const WString& _localeName=WString::Empty); - ~Locale(); - - bool operator==(const Locale& value)const { return localeName==value.localeName; } - bool operator!=(const Locale& value)const { return localeName!=value.localeName; } - bool operator<(const Locale& value)const { return localeName(const Locale& value)const { return localeName>value.localeName; } - bool operator>=(const Locale& value)const { return localeName>=value.localeName; } - - /// Get the invariant locale. - /// The invariant locale. - static Locale Invariant(); - /// Get the system default locale. This locale controls the code page that used by the the system to interpret ANSI string buffers. - /// The system default locale. - static Locale SystemDefault(); - /// Get the user default locale. This locale reflect the user's setting. - /// The user default locale. - static Locale UserDefault(); - /// Get all supported locales. - /// All supported locales. - static void Enumerate(collections::List& locales); - - /// Get the name of the locale. - /// The name of the locale. - const WString& GetName()const; - - /// Get all short date formats for the locale. - /// The formats. - void GetShortDateFormats(collections::List& formats)const; - /// Get all long date formats for the locale. - /// The formats. - void GetLongDateFormats(collections::List& formats)const; - /// Get all Year-Month date formats for the locale. - /// The formats. - void GetYearMonthDateFormats(collections::List& formats)const; - /// Get all long time formats for the locale. - /// The formats. - void GetLongTimeFormats(collections::List& formats)const; - /// Get all short time formats for the locale. - /// The formats. - void GetShortTimeFormats(collections::List& formats)const; - - /// Convert a date to a formatted string. - /// The formatted string. - /// The format to use. - /// The date to convert. - WString FormatDate(const WString& format, DateTime date)const; - /// Convert a time to a formatted string. - /// The formatted string. - /// The format to use. - /// The time to convert. - WString FormatTime(const WString& format, DateTime time)const; - - /// Convert a number to a formatted string. - /// The formatted string. - /// The number to convert. - WString FormatNumber(const WString& number)const; - /// Convert a currency (money) to a formatted string. - /// The formatted string. - /// The currency to convert. - WString FormatCurrency(const WString& currency)const; - - /// Get the short display string of a day of week. - /// The display string. - /// Day of week, begins from 0 as Sunday. - WString GetShortDayOfWeekName(vint dayOfWeek)const; - /// Get the long display string of a day of week. - /// The display string. - /// Day of week, begins from 0 as Sunday. - WString GetLongDayOfWeekName(vint dayOfWeek)const; - /// Get the short display string of a month. - /// The display string. - /// Month, begins from 1 as January. - WString GetShortMonthName(vint month)const; - /// Get the long display string of a month. - /// The display string. - /// Month, begins from 1 as January. - WString GetLongMonthName(vint month)const; - -#ifdef VCZH_MSVC - /// Convert characters to the full width. - /// The converted string. - /// The string to convert. - WString ToFullWidth(const WString& str)const; - /// Convert characters to the half width. - /// The converted string. - /// The string to convert. - WString ToHalfWidth(const WString& str)const; - /// Convert characters to the Hiragana. - /// The converted string. - /// The string to convert. - WString ToHiragana(const WString& str)const; - /// Convert characters to the Katagana. - /// The converted string. - /// The string to convert. - WString ToKatagana(const WString& str)const; -#endif - - /// Convert characters to the lower case using the file system rule. - /// The converted string. - /// The string to convert. - WString ToLower(const WString& str)const; - /// Convert characters to the upper case using the file system rule. - /// The converted string. - /// The string to convert. - WString ToUpper(const WString& str)const; - /// Convert characters to the lower case using the linguistic rule. - /// The converted string. - /// The string to convert. - WString ToLinguisticLower(const WString& str)const; - /// Convert characters to the upper case using the linguistic rule. - /// The converted string. - /// The string to convert. - WString ToLinguisticUpper(const WString& str)const; - -#ifdef VCZH_MSVC - /// Convert characters to Simplified Chinese. - /// The converted string. - /// The string to convert. - WString ToSimplifiedChinese(const WString& str)const; - /// Convert characters to the Traditional Chinese. - /// The converted string. - /// The string to convert. - WString ToTraditionalChinese(const WString& str)const; - /// Convert characters to the tile case, in which the first letter of each major word is capitalized. - /// The converted string. - /// The string to convert. - WString ToTileCase(const WString& str)const; -#endif - - /// Mergable flags controlling how to normalize a string. - enum Normalization - { - /// Do nothing. - None=0, - /// Ignore case using the file system rule. - IgnoreCase=1, -#ifdef VCZH_MSVC - /// Ignore case using the linguistic rule. - IgnoreCaseLinguistic=2, - /// Ignore the difference between between hiragana and katakana characters. - IgnoreKanaType=4, - /// Ignore nonspacing characters. - IgnoreNonSpace=8, - /// Ignore symbols and punctuation. - IgnoreSymbol=16, - /// Ignore the difference between half-width and full-width characters. - IgnoreWidth=32, - /// Treat digits as numbers during sorting. - DigitsAsNumbers=64, - /// Treat punctuation the same as symbols. - StringSoft=128, -#endif - }; - - /// Compare two strings. - /// Returns 0 if two strings are equal. Returns a positive number if the first string is larger. Returns a negative number if the second string is larger. When sorting strings, larger strings are put after then smaller strings. - /// The first string to compare. - /// The second string to compare. - /// Flags controlling how to normalize a string. - vint Compare(const WString& s1, const WString& s2, Normalization normalization)const; - /// Compare two strings to test binary equivalence. - /// Returns 0 if two strings are equal. Returns a positive number if the first string is larger. Returns a negative number if the second string is larger. When sorting strings, larger strings are put after then smaller strings. - /// The first string to compare. - /// The second string to compare. - vint CompareOrdinal(const WString& s1, const WString& s2)const; - /// Compare two strings to test binary equivalence, ignoring case. - /// Returns 0 if two strings are equal. Returns a positive number if the first string is larger. Returns a negative number if the second string is larger. When sorting strings, larger strings are put after then smaller strings. - /// The first string to compare. - /// The second string to compare. - vint CompareOrdinalIgnoreCase(const WString& s1, const WString& s2)const; - /// Find the first position that the sub string appears in a text. - /// Returns a pair of numbers, the first number indicating the position in the text, the second number indicating the size of the equivalence sub string in the text. For some normalization, the found sub string may be binary different to the string you want to find. - /// The text to find the sub string. - /// The sub string to match. - /// Flags controlling how to normalize a string. - collections::Pair FindFirst(const WString& text, const WString& find, Normalization normalization)const; - /// Find the last position that the sub string appears in a text. - /// Returns a pair of numbers, the first number indicating the position in the text, the second number indicating the size of the equivalence sub string in the text. For some normalization, the found sub string may be binary different to the string you want to find. - /// The text to find the sub string. - /// The sub string to match. - /// Flags controlling how to normalize a string. - collections::Pair FindLast(const WString& text, const WString& find, Normalization normalization)const; - /// Test is the prefix of the text equivalence to the provided sub string. - /// Returns true if the prefix of the text equivalence to the provided sub string. - /// The text to test the prefix. - /// The sub string to match. - /// Flags controlling how to normalize a string. - bool StartsWith(const WString& text, const WString& find, Normalization normalization)const; - /// Test is the postfix of the text equivalence to the provided sub string. - /// Returns true if the postfix of the text equivalence to the provided sub string. - /// The text to test the postfix. - /// The sub string to match. - /// Flags controlling how to normalize a string. - bool EndsWith(const WString& text, const WString& find, Normalization normalization)const; - }; - -#define INVLOC vl::Locale::Invariant() -} - -#endif - -/*********************************************************************** -.\STREAM\FILESTREAM.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -Stream::FileStream - -Interfaces: - FileStream : File stream -***********************************************************************/ - -#ifndef VCZH_STREAM_FILESTREAM -#define VCZH_STREAM_FILESTREAM - -#include - -namespace vl -{ - namespace stream - { - /// A file stream. It is readable when you use [F:vl.stream.FileStream.AccessRight.ReadOnly] or [F:vl.stream.FileStream.AccessRight.ReadWrite] to create the stream. It is writable when you use [F:vl.stream.FileStream.AccessRight.WriteOnly] or [F:vl.stream.FileStream.AccessRight.ReadWrite] to create the stream. - class FileStream : public Object, public virtual IStream - { - public: - /// Access to the file. - enum AccessRight - { - /// The file is opened to read. - ReadOnly, - /// The file is opened to write. - WriteOnly, - /// The file is opened to both read and write. - ReadWrite - }; - protected: - AccessRight accessRight; - FILE* file; - public: - /// Create a stream. - /// File to operate. - /// Operations want to perform on the file. - FileStream(const WString& fileName, AccessRight _accessRight); - ~FileStream(); - - bool CanRead()const; - bool CanWrite()const; - bool CanSeek()const; - bool CanPeek()const; - bool IsLimited()const; - bool IsAvailable()const; - void Close(); - pos_t Position()const; - pos_t Size()const; - void Seek(pos_t _size); - void SeekFromBegin(pos_t _size); - void SeekFromEnd(pos_t _size); - vint Read(void* _buffer, vint _size); - vint Write(void* _buffer, vint _size); - vint Peek(void* _buffer, vint _size); - }; - } -} - -#endif - -/*********************************************************************** -.\STREAM\ACCESSOR.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -Stream::Accessor - -Classes: - TextReader : Text reader base class - TextWriter : Text writer base class - StringReader : Text reader from a string - StreamReader : Text reader from a stream - StreamWriter : Text writer to a stream - EncoderStream : Stream that takes an encoder to translate another stream - DecoderStream : Stream that takes a decoder to translate another stream -***********************************************************************/ - -#ifndef VCZH_STREAM_ACCESSOR -#define VCZH_STREAM_ACCESSOR - - -namespace vl -{ - namespace stream - { - -/*********************************************************************** -Text Related -***********************************************************************/ - - /// Text reader. All line breaks are normalized to CRLF regardless the format in the source. - class TextReader : public Object, private NotCopyable - { - public: - /// Test does the reader reach the end or not. - /// Returns true if the reader reaches the end. - virtual bool IsEnd()=0; - /// Read a single character. - /// The character. - virtual wchar_t ReadChar()=0; - /// Read a string of a specified size. - /// The string. - /// Expected length of the string to read. - virtual WString ReadString(vint length); - /// Read a string until a line breaks is reached. - /// The string. It does not contain the line break. - virtual WString ReadLine(); - /// Read everying remain. - /// The string. - virtual WString ReadToEnd(); - }; - - /// Text writer. - class TextWriter : public Object, private NotCopyable - { - public: - /// Write a single character. - /// The character to write. - virtual void WriteChar(wchar_t c)=0; - /// Write a string. - /// Buffer to the string to write. - /// Size of the string in characters not including the zero terminator. - virtual void WriteString(const wchar_t* string, vint charCount); - /// Write a string. - /// Buffer to the zero terminated string to write. - virtual void WriteString(const wchar_t* string); - /// Write a string. - /// The string to write. - virtual void WriteString(const WString& string); - /// Write a string with a CRLF. - /// Buffer to the string to write. - /// Size of the string in characters not including the zero terminator. - virtual void WriteLine(const wchar_t* string, vint charCount); - /// Write a string with a CRLF. - /// Buffer to the zero terminated string to write. - virtual void WriteLine(const wchar_t* string); - /// Write a string with a CRLF. - /// The string to write. - virtual void WriteLine(const WString& string); - - virtual void WriteMonospacedEnglishTable(collections::Array& tableByRow, vint rows, vint columns); - }; - - /// Text reader from a string. - class StringReader : public TextReader - { - protected: - WString string; - vint current; - bool lastCallIsReadLine; - - void PrepareIfLastCallIsReadLine(); - public: - /// Create a text reader. - /// The string to read. - StringReader(const WString& _string); - - bool IsEnd(); - wchar_t ReadChar(); - WString ReadString(vint length); - WString ReadLine(); - WString ReadToEnd(); - }; - - /// Text reader from a stream. - class StreamReader : public TextReader - { - protected: - IStream* stream; - public: - /// Create a text reader. - /// The stream to read. - StreamReader(IStream& _stream); - - bool IsEnd(); - wchar_t ReadChar(); - }; - - /// Text writer to a stream. - class StreamWriter : public TextWriter - { - protected: - IStream* stream; - public: - /// Create a text writer. - /// The stream to write. - StreamWriter(IStream& _stream); - using TextWriter::WriteString; - - void WriteChar(wchar_t c); - void WriteString(const wchar_t* string, vint charCount); - }; - -/*********************************************************************** -Encoding Related -***********************************************************************/ - - /// Encoder stream, a writable stream using an [T:vl.stream.IEncoder] to transform content. - class EncoderStream : public virtual IStream - { - protected: - IStream* stream; - IEncoder* encoder; - pos_t position; - - public: - /// Create a stream. - /// The target stream to write. - /// The encoder to transform content. - EncoderStream(IStream& _stream, IEncoder& _encoder); - ~EncoderStream(); - - bool CanRead()const; - bool CanWrite()const; - bool CanSeek()const; - bool CanPeek()const; - bool IsLimited()const; - bool IsAvailable()const; - void Close(); - pos_t Position()const; - pos_t Size()const; - void Seek(pos_t _size); - void SeekFromBegin(pos_t _size); - void SeekFromEnd(pos_t _size); - vint Read(void* _buffer, vint _size); - vint Write(void* _buffer, vint _size); - vint Peek(void* _buffer, vint _size); - }; - - /// Decoder stream, a readable stream using an [T:vl.stream.IDecoder] to transform content. - class DecoderStream : public virtual IStream - { - protected: - IStream* stream; - IDecoder* decoder; - pos_t position; - - public: - /// Create a stream. - /// The target stream to read. - /// The decoder to transform content. - DecoderStream(IStream& _stream, IDecoder& _decoder); - ~DecoderStream(); - - bool CanRead()const; - bool CanWrite()const; - bool CanSeek()const; - bool CanPeek()const; - bool IsLimited()const; - bool IsAvailable()const; - void Close(); - pos_t Position()const; - pos_t Size()const; - void Seek(pos_t _size); - void SeekFromBegin(pos_t _size); - void SeekFromEnd(pos_t _size); - vint Read(void* _buffer, vint _size); - vint Write(void* _buffer, vint _size); - vint Peek(void* _buffer, vint _size); - }; - -/*********************************************************************** -Helper Functions -***********************************************************************/ - - template - WString GenerateToStream(const TCallback& callback, vint block = 65536) - { - MemoryStream stream(block); - { - StreamWriter writer(stream); - callback(writer); - } - stream.SeekFromBegin(0); - { - StreamReader reader(stream); - return reader.ReadToEnd(); - } - } - } -} - -#endif - -/*********************************************************************** -.\HTTPUTILITY.H -***********************************************************************/ -#ifndef VCZH_HTTPUTILITY -#define VCZH_HTTPUTILITY - - -#ifdef VCZH_MSVC - -namespace vl -{ - -/*********************************************************************** -HTTP Utility -***********************************************************************/ - - /// A type representing an http requiest. - class HttpRequest - { - typedef collections::Array BodyBuffer; - typedef collections::List StringList; - typedef collections::Dictionary HeaderMap; - public: - /// Name of the server, like "gaclib.net". - WString server; - /// Port of the server, like 80. - vint port; - /// Query of the request, like "/GettingStart.html". - WString query; - /// Set to true if the request uses SSL. - bool secure; - /// User name to authorize. Set to empty if you don't want to provide it. - WString username; - /// Password to authorize. Set to empty if you don't want to provide it. - WString password; - /// HTTP method, like "GET", "POST", "PUT", "DELETE", etc. - WString method; - /// Cookie. Set to empty if you don't want to provide it. - WString cookie; - /// Request body. This is a binary array using an array container to char. - BodyBuffer body; - /// Content type, like "text/xml". - WString contentType; - /// Accept type list, elements of it like "text/xml". - StringList acceptTypes; - /// A dictionary to contain extra headers. - HeaderMap extraHeaders; - - /// Create an empty request. - HttpRequest(); - - /// Set , , and fields for you using an URL. - /// Returns true if this operation succeeded. - /// The URL. - bool SetHost(const WString& inputQuery); - - /// Fill the body with a text using UTF-8 encoding. - /// The text to fill. - void SetBodyUtf8(const WString& bodyString); - }; - - /// A type representing an http response. - class HttpResponse - { - typedef collections::Array BodyBuffer; - public: - /// Status code, like 200. - vint statusCode; - /// Response body. This is a binary array using an array container to char. - BodyBuffer body; - /// Returned cookie from the server. - WString cookie; - - HttpResponse(); - - /// If you believe the server returns a text in UTF-8, use it to decode the body. - /// The response body as text. - WString GetBodyUtf8(); - }; - - /// Send an http request and receive a response. - /// Returns true if this operation succeeded. Even the server returns 404 will be treated as success, because you get the response. - /// The request. - /// The response. - extern bool HttpQuery(const HttpRequest& request, HttpResponse& response); - - /// Encode a text as part of the url. This function can be used to create arguments in an URL. - /// The encoded text. - /// The text to encode. - extern WString UrlEncodeQuery(const WString& query); -} - -#endif - -#endif - - -/*********************************************************************** -.\THREADING.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -Framework::Threading - -Classes: - Thread : Thread - CriticalSection - Mutex - Semaphore - EventObject -***********************************************************************/ - -#ifndef VCZH_THREADING -#define VCZH_THREADING - - -namespace vl -{ - -/*********************************************************************** -Kernel Mode Objects -***********************************************************************/ - - namespace threading_internal - { - struct WaitableData; - struct ThreadData; - struct MutexData; - struct SemaphoreData; - struct EventData; - struct CriticalSectionData; - struct ReaderWriterLockData; - struct ConditionVariableData; - } - - /// Base type of all synchronization objects. - class WaitableObject : public Object, public NotCopyable - { -#if defined VCZH_MSVC - private: - threading_internal::WaitableData* waitableData; - protected: - - WaitableObject(); - void SetData(threading_internal::WaitableData* data); - public: - /// Test if the object has already been created. Some of the synchronization objects should initialize itself after the constructor. This function is only available in Windows. - /// Returns true if the object has already been created. - bool IsCreated(); - /// Wait for this object to signal. - /// Returns true if the object is signaled. Returns false if this operation failed. - bool Wait(); - /// Wait for this object to signal for a period of time. This function is only available in Windows. - /// Returns true if the object is signaled. Returns false if this operation failed, including time out. - /// Time in milliseconds. - bool WaitForTime(vint ms); - - /// Wait for multiple objects. This function is only available in Windows. - /// Returns true if all objects are signaled. Returns false if this operation failed. - /// A pointer to an array to pointers. - /// The number of objects in the array. - static bool WaitAll(WaitableObject** objects, vint count); - /// Wait for multiple objects for a period of time. This function is only available in Windows. - /// Returns true if all objects are signaled. Returns false if this operation failed, including time out. - /// A pointer to an array to pointers. - /// The number of objects in the array. - /// Time in milliseconds. - static bool WaitAllForTime(WaitableObject** objects, vint count, vint ms); - /// Wait for one of the objects. This function is only available in Windows. - /// Returns the index of the first signaled or abandoned object, according to the "abandoned" parameter. Returns -1 if this operation failed. - /// A pointer to an array to pointers. - /// The number of objects in the array. - /// Returns true if the waiting is canceled by an abandoned object. An abandoned object is caused by it's owner thread existing without releasing it. - static vint WaitAny(WaitableObject** objects, vint count, bool* abandoned); - /// Wait for one of the objects for a period of time. This function is only available in Windows. - /// Returns the index of the first signaled or abandoned object, according to the "abandoned" parameter. Returns -1 if this operation failed, including time out. - /// A pointer to an array to pointers. - /// The number of objects in the array. - /// Time in milliseconds. - /// Returns true if the waiting is canceled by an abandoned object. An abandoned object is caused by it's owner thread existing without releasing it. - static vint WaitAnyForTime(WaitableObject** objects, vint count, vint ms, bool* abandoned); -#elif defined VCZH_GCC - virtual bool Wait() = 0; -#endif - }; - - /// Representing a thread. [M:vl.Thread.CreateAndStart] is the suggested way to create threads. - class Thread : public WaitableObject - { - friend void InternalThreadProc(Thread* thread); - public: - /// Thread state. - enum ThreadState - { - /// The thread has not started. - NotStarted, - /// The thread is running. - Running, - /// The thread has been stopped. - Stopped - }; - - typedef void(*ThreadProcedure)(Thread*, void*); - protected: - threading_internal::ThreadData* internalData; - volatile ThreadState threadState; - - virtual void Run()=0; - - Thread(); - public: - ~Thread(); - - /// Create a thread using a function pointer. - /// Returns the created thread. - /// The function pointer. - /// The argument to call the function pointer. - /// Set to true (by default) to make the thread delete itself after the job is done. If you set this argument to true, you are not suggested to touch the returned thread pointer in any way. - static Thread* CreateAndStart(ThreadProcedure procedure, void* argument=0, bool deleteAfterStopped=true); - /// Create a thread using a function object or a lambda expression. - /// Returns the created thread. - /// The function object or the lambda expression. - /// Set to true (by default) to make the thread delete itself after the job is done. If you set this argument to true, you are not suggested to touch the returned thread pointer in any way. - static Thread* CreateAndStart(const Func& procedure, bool deleteAfterStopped=true); - /// Pause the caller thread for a period of time. - /// Time in milliseconds. - static void Sleep(vint ms); - /// Get the number of logical processors. - /// The number of logical processor. - static vint GetCPUCount(); - /// Get the current thread id. - /// The current thread id. - static vint GetCurrentThreadId(); - - /// Start the thread. - /// Returns true if this operation succeeded. - bool Start(); -#if defined VCZH_GCC - bool Wait(); -#endif - /// Stop the thread. - /// Returns true if this operation succeeded. - bool Stop(); - /// Get the state of the thread. - /// The state of the thread. - ThreadState GetState(); -#ifdef VCZH_MSVC - void SetCPU(vint index); -#endif - }; - - /// Mutex. - class Mutex : public WaitableObject - { - private: - threading_internal::MutexData* internalData; - public: - Mutex(); - ~Mutex(); - - /// Create a mutex. - /// Returns true if this operation succeeded. - /// Set to true to own the created mutex. - /// Name of the mutex. If it is not empty, than it is a global named mutex. This argument is ignored in Linux. - bool Create(bool owned=false, const WString& name=L""); - /// Open an existing global named mutex. - /// Returns true if this operation succeeded. - /// Set to true make the mutex visible to all all child processes. This argument is only used in Windows. - /// Name of the mutex. This argument is ignored in Linux. - bool Open(bool inheritable, const WString& name); - - /// - /// Release the mutex. - /// In the implementation for Linux, calling Release() more than once between two Wait(), or calling Wait() more than once between two Release(), will results in an undefined behavior. - /// - /// Returns true if this operation succeeded. - bool Release(); -#ifdef VCZH_GCC - bool Wait(); -#endif - }; - - /// Semaphore. - class Semaphore : public WaitableObject - { - private: - threading_internal::SemaphoreData* internalData; - public: - Semaphore(); - ~Semaphore(); - - /// Create a semaphore. - /// Returns true if this operation succeeded. - /// Define the counter of the semaphore. - /// Define the maximum value of the counter of the semaphore. This argument is only used in Windows. - /// Name of the semaphore. If it is not empty, than it is a global named semaphore. This argument is ignored in Linux. - bool Create(vint initialCount, vint maxCount, const WString& name=L""); - /// Open an existing global named semaphore. - /// Returns true if this operation succeeded. - /// Set to true make the semaphore visible to all all child processes. This argument is only used in Windows. - /// Name of the semaphore. This argument is ignored in Linux. - bool Open(bool inheritable, const WString& name); - - /// Release the semaphore once. - /// Returns true if this operation succeeded. - bool Release(); - /// Release the semaphore multiple times. - /// Returns true if this operation succeeded. - /// The amout to release. - vint Release(vint count); -#ifdef VCZH_GCC - bool Wait(); -#endif - }; - - /// Event. - class EventObject : public WaitableObject - { - private: - threading_internal::EventData* internalData; - public: - EventObject(); - ~EventObject(); - - /// Create an auto unsignal event. Auto unsignal means, when one thread waits for the event and succeeded, the event will become unsignaled immediately. - /// Returns true if this operation succeeded. - /// Set to true make the event signaled at the beginning. - /// Name of the event. If it is not empty, than it is a global named mutex. This argument is only used in Windows. - bool CreateAutoUnsignal(bool signaled, const WString& name=L""); - /// Create a manual unsignal event. - /// Returns true if this operation succeeded. - /// Set to true make the event signaled at the beginning. - /// Name of the event. If it is not empty, than it is a global named mutex. This argument is only used in Windows. - bool CreateManualUnsignal(bool signaled, const WString& name=L""); - /// Open an existing global named event. - /// Returns true if this operation succeeded. - /// Set to true make the event visible to all all child processes. This argument is only used in Windows. - /// Name of the event. This argument is only used in Windows. - bool Open(bool inheritable, const WString& name); - - /// Signal the event. - /// Returns true if this operation succeeded. - bool Signal(); - /// Unsignal the event. - /// Returns true if this operation succeeded. - bool Unsignal(); -#ifdef VCZH_GCC - bool Wait(); -#endif - }; - -/*********************************************************************** -Thread Pool -***********************************************************************/ - - /// A light-weight thread pool. - class ThreadPoolLite : public Object - { - private: - ThreadPoolLite(); - ~ThreadPoolLite(); - public: - /// Queue a function pointer. - /// Returns true if this operation succeeded. - /// The function pointer. - /// The argument to call the function pointer. - static bool Queue(void(*proc)(void*), void* argument); - /// Queue a function object. - /// Returns true if this operation succeeded. - /// The function object. - static bool Queue(const Func& proc); - - /// Queue a lambda expression. - /// The type of the lambda expression. - /// The lambda expression. - template - static void QueueLambda(const T& proc) - { - Queue(Func(proc)); - } - -#ifdef VCZH_GCC - static bool Stop(bool discardPendingTasks); -#endif - }; - -/*********************************************************************** -Kernel Mode Objects in Process -***********************************************************************/ - - /// - /// } - /// ]]> - class CriticalSection : public Object, public NotCopyable - { - private: - friend class ConditionVariable; - threading_internal::CriticalSectionData* internalData; - public: - /// Create a critical section. - CriticalSection(); - ~CriticalSection(); - - /// Try enter a critical section. This function will return immediately. - /// Returns true if the current thread owned the critical section. - bool TryEnter(); - /// Enter a critical section. - void Enter(); - /// Leave a critical section. - void Leave(); - - public: - class Scope : public Object, public NotCopyable - { - private: - CriticalSection* criticalSection; - public: - Scope(CriticalSection& _criticalSection); - ~Scope(); - }; - }; - - /// - /// } - /// or - /// WRITER_LOCK(yourLock) - /// { - /// - /// } - /// ]]> - class ReaderWriterLock : public Object, public NotCopyable - { - private: - friend class ConditionVariable; - threading_internal::ReaderWriterLockData* internalData; - public: - /// Create a reader writer lock. - ReaderWriterLock(); - ~ReaderWriterLock(); - - /// Try acquire a reader lock. This function will return immediately. - /// Returns true if the current thread acquired the reader lock. - bool TryEnterReader(); - /// Acquire a reader lock. - void EnterReader(); - /// Release a reader lock. - void LeaveReader(); - /// Try acquire a writer lock. This function will return immediately. - /// Returns true if the current thread acquired the writer lock. - bool TryEnterWriter(); - /// Acquire a writer lock. - void EnterWriter(); - /// Release a writer lock. - void LeaveWriter(); - public: - class ReaderScope : public Object, public NotCopyable - { - private: - ReaderWriterLock* lock; - public: - ReaderScope(ReaderWriterLock& _lock); - ~ReaderScope(); - }; - - class WriterScope : public Object, public NotCopyable - { - private: - ReaderWriterLock* lock; - public: - WriterScope(ReaderWriterLock& _lock); - ~WriterScope(); - }; - }; - - /// Conditional variable. - class ConditionVariable : public Object, public NotCopyable - { - private: - threading_internal::ConditionVariableData* internalData; - public: - /// Create a conditional variable. - ConditionVariable(); - ~ConditionVariable(); - - /// Bind a conditional variable with a owned critical section and release it. When the function returns, the condition variable is activated, and the current thread owned the critical section again. - /// Returns true if this operation succeeded. - /// The critical section. - bool SleepWith(CriticalSection& cs); -#ifdef VCZH_MSVC - /// Bind a conditional variable with a owned critical section and release it for a period of time. When the function returns, the condition variable is activated or it is time out, and the current thread owned the critical section again. This function is only available in Windows. - /// Returns true if this operation succeeded. - /// The critical section. - /// Time in milliseconds. - bool SleepWithForTime(CriticalSection& cs, vint ms); - /// Bind a conditional variable with a owned reader lock and release it. When the function returns, the condition variable is activated, and the current thread owned the reader lock again. This function is only available in Windows. - /// Returns true if this operation succeeded. - /// The reader lock. - bool SleepWithReader(ReaderWriterLock& lock); - /// Bind a conditional variable with a owned reader lock and release it for a period of time. When the function returns, the condition variable is activated or it is time out, and the current thread owned the reader lock again. This function is only available in Windows. - /// Returns true if this operation succeeded. - /// The reader lock. - /// Time in milliseconds. - bool SleepWithReaderForTime(ReaderWriterLock& lock, vint ms); - /// Bind a conditional variable with a owned writer lock and release it. When the function returns, the condition variable is activated, and the current thread owned the writer lock again. This function is only available in Windows. - /// Returns true if this operation succeeded. - /// The writer lock. - bool SleepWithWriter(ReaderWriterLock& lock); - /// Bind a conditional variable with a owned writer lock and release it for a period of time. When the function returns, the condition variable is activated or it is time out, and the current thread owned the writer lock again. This function is only available in Windows. - /// Returns true if this operation succeeded. - /// The writer lock. - /// Time in milliseconds. - bool SleepWithWriterForTime(ReaderWriterLock& lock, vint ms); -#endif - /// Wake one thread that pending on this condition variable. - void WakeOnePending(); - /// Wake all thread that pending on this condition variable. - void WakeAllPendings(); - }; - -/*********************************************************************** -User Mode Objects -***********************************************************************/ - - typedef long LockedInt; - - /// - /// } - /// ]]> - class SpinLock : public Object, public NotCopyable - { - protected: - volatile LockedInt token; - public: - /// Create a spin lock. - SpinLock(); - ~SpinLock(); - - /// Try enter a spin lock. This function will return immediately. - /// Returns true if the current thread owned the spin lock. - bool TryEnter(); - /// Enter a spin lock. - void Enter(); - /// Leave a spin lock. - void Leave(); - - public: - class Scope : public Object, public NotCopyable - { - private: - SpinLock* spinLock; - public: - Scope(SpinLock& _spinLock); - ~Scope(); - }; - }; - -#define SPIN_LOCK(LOCK) SCOPE_VARIABLE(const SpinLock::Scope&, scope, LOCK) -#define CS_LOCK(LOCK) SCOPE_VARIABLE(const CriticalSection::Scope&, scope, LOCK) -#define READER_LOCK(LOCK) SCOPE_VARIABLE(const ReaderWriterLock::ReaderScope&, scope, LOCK) -#define WRITER_LOCK(LOCK) SCOPE_VARIABLE(const ReaderWriterLock::WriterScope&, scope, LOCK) - -/*********************************************************************** -Thread Local Storage - -ThreadLocalStorage and ThreadVariable are designed to be used as global value types only. -Dynamically create instances of them are undefined behavior. -***********************************************************************/ - - /// Thread local storage operations. - class ThreadLocalStorage : public Object, private NotCopyable - { - typedef void(*Destructor)(void*); - protected: - vuint64_t key; - Destructor destructor; - volatile bool disposed = false; - - static void PushStorage(ThreadLocalStorage* storage); - public: - ThreadLocalStorage(Destructor _destructor); - ~ThreadLocalStorage(); - - void* Get(); - void Set(void* data); - void Clear(); - void Dispose(); - - /// Fix all storage creation. - static void FixStorages(); - /// Clear all storages for the current thread. For threads that are created using [T:vl.Thread], this function will be automatically called when before the thread exit. - static void ClearStorages(); - /// Clear all storages for the current thread (should be the main thread) and clear all records. This function can only be called by the main thread when all other threads are exited. It will reduce noices when you want to detect memory leaks. - static void DisposeStorages(); - }; - - /// Thread local variable. This type can only be used to define global variables. Different threads can store different values to and obtain differnt values from a thread local variable. - /// Type of the storage. - template - class ThreadVariable : public Object, private NotCopyable - { - protected: - ThreadLocalStorage storage; - - static void Destructor(void* data) - { - if (data) - { - delete (T*)data; - } - } - public: - /// Create a thread local variable. - ThreadVariable() - :storage(&Destructor) - { - } - - ~ThreadVariable() - { - } - - /// Test if the storage has data. - /// Returns true if the storage has data. - bool HasData() - { - return storage.Get() != nullptr; - } - - /// Remove the data from this storage. - void Clear() - { - storage.Clear(); - } - - /// Get the stored data. - /// The stored ata. - T& Get() - { - return *(T*)storage.Get(); - } - - /// Set data to this storage. - /// The data to set. - void Set(const T& value) - { - storage.Clear(); - storage.Set(new T(value)); - } - }; - - template - class ThreadVariable : public Object, private NotCopyable - { - protected: - ThreadLocalStorage storage; - - public: - ThreadVariable() - :storage(nullptr) - { - } - - ~ThreadVariable() - { - } - - bool HasData() - { - return storage.Get() != nullptr; - } - - void Clear() - { - storage.Set(nullptr); - } - - T* Get() - { - return (T*)storage.Get(); - } - - void Set(T* value) - { - storage.Set((void*)value); - } - }; - -/*********************************************************************** -RepeatingTaskExecutor -***********************************************************************/ - - /// Queued task executor. It is different from a thread pool by: 1) Task execution is single threaded, 2) If you queue a task, it will override the the unexecuted queued task. - /// The type of the argument to run a task. - template - class RepeatingTaskExecutor : public Object - { - private: - SpinLock inputLock; - T inputData; - volatile bool inputDataAvailable; - SpinLock executingEvent; - volatile bool executing; - - void ExecutingProcInternal() - { - while(true) - { - bool currentInputDataAvailable; - T currentInputData; - SPIN_LOCK(inputLock) - { - currentInputData=inputData; - inputData=T(); - currentInputDataAvailable=inputDataAvailable; - inputDataAvailable=false; - if(!currentInputDataAvailable) - { - executing=false; - goto FINISH_EXECUTING; - } - } - Execute(currentInputData); - } - FINISH_EXECUTING: - executingEvent.Leave(); - } - - static void ExecutingProc(void* argument) - { - ((RepeatingTaskExecutor*)argument)->ExecutingProcInternal(); - } - - protected: - /// This function is called when it is ready to execute a task. Task execution is single threaded. All task code should be put inside the function. - /// The argument to run a task. - virtual void Execute(const T& input)=0; - - public: - /// Create a task executor. - RepeatingTaskExecutor() - :inputDataAvailable(false) - ,executing(false) - { - } - - ~RepeatingTaskExecutor() - { - EnsureTaskFinished(); - } - - /// Wait for all tasks to finish. - void EnsureTaskFinished() - { - executingEvent.Enter(); - executingEvent.Leave(); - } - - /// Queue a task. If there is a queued task that has not been executied yet, those tasks will be canceled. Only one task can be queued at the same moment. - /// The argument to run a task. - void SubmitTask(const T& input) - { - SPIN_LOCK(inputLock) - { - inputData=input; - inputDataAvailable=true; - } - if(!executing) - { - executing=true; - executingEvent.Enter(); - ThreadPoolLite::Queue(&ExecutingProc, this); - } - } - }; -} -#endif - - -/*********************************************************************** -.\STREAM\BROADCASTSTREAM.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -Stream::BroadcastStream - -Interfaces: - BroadcastStream : Stream that copy the written data to multiple streams -***********************************************************************/ - -#ifndef VCZH_STREAM_BROADCASTSTREAM -#define VCZH_STREAM_BROADCASTSTREAM - - -namespace vl -{ - namespace stream - { - /// A writable stream that copy written content to multiple target streams. - class BroadcastStream : public Object, public virtual IStream - { - typedef collections::List StreamList; - protected: - bool closed; - pos_t position; - StreamList streams; - public: - /// Create a strema. - BroadcastStream(); - ~BroadcastStream(); - - /// Get the list of target streams. You can add streams to this list, or remove streams from this list. - /// The list of target streams. - StreamList& Targets(); - bool CanRead()const; - bool CanWrite()const; - bool CanSeek()const; - bool CanPeek()const; - bool IsLimited()const; - bool IsAvailable()const; - void Close(); - pos_t Position()const; - pos_t Size()const; - void Seek(pos_t _size); - void SeekFromBegin(pos_t _size); - void SeekFromEnd(pos_t _size); - vint Read(void* _buffer, vint _size); - vint Write(void* _buffer, vint _size); - vint Peek(void* _buffer, vint _size); - }; - } -} - -#endif - -/*********************************************************************** -.\STREAM\CACHESTREAM.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -Stream::CacheStream - -Interfaces: - CacheStream : Stream that provide a cache for reading and writing -***********************************************************************/ - -#ifndef VCZH_STREAM_CACHESTREAM -#define VCZH_STREAM_CACHESTREAM - - -namespace vl -{ - namespace stream - { - /// - /// A cache stream. Features (readable, writable, seekable, peekable) are enabled according to the target stream. - /// When you read from the cache strema, it will read a specified size of content from the target stream first and cache, reducing the numbers of operations on the target stream. - /// When you write to the cache strema, it will save them to a buffer, and write to the target stream until the buffer reaches a specified size, reducing the numbers of operations on the target stream. - /// - class CacheStream : public Object, public virtual IStream - { - protected: - IStream* target; - vint block; - pos_t start; - pos_t position; - - char* buffer; - vint dirtyStart; - vint dirtyLength; - vint availableLength; - pos_t operatedSize; - - void Flush(); - void Load(pos_t _position); - vint InternalRead(void* _buffer, vint _size); - vint InternalWrite(void* _buffer, vint _size); - public: - /// Create a cache stream using a target stream. - /// The target stream. - /// Size of the cache. - CacheStream(IStream& _target, vint _block=65536); - ~CacheStream(); - - bool CanRead()const; - bool CanWrite()const; - bool CanSeek()const; - bool CanPeek()const; - bool IsLimited()const; - bool IsAvailable()const; - void Close(); - pos_t Position()const; - pos_t Size()const; - void Seek(pos_t _size); - void SeekFromBegin(pos_t _size); - void SeekFromEnd(pos_t _size); - vint Read(void* _buffer, vint _size); - vint Write(void* _buffer, vint _size); - vint Peek(void* _buffer, vint _size); - }; - } -} - -#endif - -/*********************************************************************** -.\STREAM\COMPRESSIONSTREAM.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -Stream::CharFormat - -Classes: -***********************************************************************/ - -#ifndef VCZH_STREAM_COMPRESSIONSTREAM -#define VCZH_STREAM_COMPRESSIONSTREAM - - -namespace vl -{ - namespace stream - { - -/*********************************************************************** -Compression -***********************************************************************/ - - namespace lzw - { - static const vint BufferSize = 1024; - static const vint MaxDictionarySize = 1 << 24; - - struct Code - { - typedef collections::PushOnlyAllocator CodeAllocator; - typedef collections::ByteObjectMap::Allocator MapAllocator; - - vuint8_t byte = 0; - vint code = -1; - Code* parent = 0; - vint size = 0; - collections::ByteObjectMap children; - }; - } - - class LzwBase : public Object - { - protected: - lzw::Code::CodeAllocator codeAllocator; - lzw::Code::MapAllocator mapAllocator; - lzw::Code* root; - vint eofIndex = -1; - vint nextIndex = 0; - vint indexBits = 1; - - void UpdateIndexBits(); - lzw::Code* CreateCode(lzw::Code* parent, vuint8_t byte); - - LzwBase(); - LzwBase(bool (&existingBytes)[256]); - ~LzwBase(); - }; - - /// An encoder to compress using Lzw algorithm. - class LzwEncoder : public LzwBase, public IEncoder - { - protected: - IStream* stream = 0; - - vuint8_t buffer[lzw::BufferSize]; - vint bufferUsedBits = 0; - lzw::Code* prefix; - - void Flush(); - void WriteNumber(vint number, vint bitSize); - public: - /// Create an encoder. - LzwEncoder(); - /// Create an encoder and tell it which byte will never appear in the data before compression. - /// An array to tell the encoder which byte will never appear in the data before compression. - LzwEncoder(bool (&existingBytes)[256]); - ~LzwEncoder(); - - void Setup(IStream* _stream)override; - void Close()override; - vint Write(void* _buffer, vint _size)override; - }; - - /// An decoder to decompress using Lzw algorithm. - class LzwDecoder :public LzwBase, public IDecoder - { - protected: - IStream* stream = 0; - collections::List dictionary; - lzw::Code* lastCode = 0; - - vuint8_t inputBuffer[lzw::BufferSize]; - vint inputBufferSize = 0; - vint inputBufferUsedBits = 0; - - collections::Array outputBuffer; - vint outputBufferSize = 0; - vint outputBufferUsedBytes = 0; - - bool ReadNumber(vint& number, vint bitSize); - void PrepareOutputBuffer(vint size); - void ExpandCodeToOutputBuffer(lzw::Code* code); - public: - /// Create an decoder. - LzwDecoder(); - /// Create an decoder and tell it which byte will never appear in the data before compression. - /// An array to tell the encoder which byte will never appear in the data before compression. - LzwDecoder(bool (&existingBytes)[256]); - ~LzwDecoder(); - - void Setup(IStream* _stream)override; - void Close()override; - vint Read(void* _buffer, vint _size)override; - }; - -/*********************************************************************** -Helper Functions -***********************************************************************/ - - extern vint CopyStream(stream::IStream& inputStream, stream::IStream& outputStream); - extern void CompressStream(stream::IStream& inputStream, stream::IStream& outputStream); - extern void DecompressStream(stream::IStream& inputStream, stream::IStream& outputStream); - } -} - -#endif - /*********************************************************************** .\STREAM\RECORDERSTREAM.H ***********************************************************************/ diff --git a/Import/VlppParser.h b/Import/VlppParser.h index 8dec099f..4c15a249 100644 --- a/Import/VlppParser.h +++ b/Import/VlppParser.h @@ -582,923 +582,6 @@ Logging #endif -/*********************************************************************** -.\PARSINGTABLE.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -Parsing::Table - -Classes: -***********************************************************************/ - -#ifndef VCZH_PARSING_PARSINGTABLE -#define VCZH_PARSING_PARSINGTABLE - - -namespace vl -{ - namespace parsing - { - namespace tabling - { - -/*********************************************************************** -Parsing Table -***********************************************************************/ - - /// " // (multiple) e.g. "../Import/Vlpp.h" - /// classPrefix: // (single) A prefix that will be add before all generated types and function. e.g. Xml - /// guard: // (single) The C++ header guard pattern macro name. e.g. VCZH_PARSING_XML_PARSINGXML_PARSER - /// namespace: // (single) Namespaces separated by "." to contain the generated code. e.g. vl.parsing.xml - /// reflection: // (single) Namespaces separated by "." to contain the name of reflectable types. In most of the cases this should be the same as namespace. e.g. vl.parsing.xml - /// parser:() // (multiple) Pair a function name to a rule name. ParserGen.exe will generate a function called "" to parse the input using rule named "". e.g. ParseDocument(XDocument) - /// ambiguity:(enabled|disabled) // (single) Set to "enabled" indicating that the grammar is by design to have ambiguity. - /// serialization:(enabled|disabled) // (single) Set to "enabled" to serialize the parsing table as binary in the generated C++ code, so that when the "LoadTable" function is called to load the table, it can deserialize from the binary data directly, instead of parsing the grammar again. But the grammar text will always be contained in the generated C++ code regardless of the value of "serialization", it can always be retrived using the "GetParserTextBuffer" function. - /// grammar: // (single) Configuration ends here. All content after "grammar:" will be treated as the grammar to define the input. - /// - /// Here is the brief description of the grammar. - /// The grammar is formed by 3 parts: types, token definitions and rule definitions. There is only one character escaping in strings: "", which means the " character. - /// - /// 1) Types: - /// You can write attributes like @AttributeName("argument1", "argument2", ...) in the middle of types. But attributes don't affect the parsing. All attribute definitions will be stored in the generated parsing table, and who uses the table defines how attributes work. Multiple attributes are separated by ",". - /// - /// a) Enum: - /// enum EnumName - /// { - /// Item1 , - /// Item2 , - /// ... // cannot skip the last "," - /// } - /// - /// b) Class: - /// class Name [ambiguous(AmbiguousType)] [: ParentType] - /// { - /// Type name [(UnescapingFunction)] ; - /// } - /// - /// UnescapingFunction is a callback, which will be called when the contained type is fully constructed. The generated C++ code will define forward declarations of all unescaping functions in the cpp file. You should implement them in other places, or you will get linking errors. - /// - /// If the grammar enables ambiguity, then the parsing result may contain ambiguous results for the same part of the input. For example, in C++: - /// A*B; - /// has two meaning (if we only consider context-free parsing): multiplication expression and pointer variable definition. - /// So if the grammar doesn't enable ambiguity, ParserGen.exe will refuce to generate C++ codes because the grammar is wrong. - /// If the grammar enables ambiguity, than the syntax tree should be defined like this: - /// - /// class Statement ambiguous(AmbiguousStatement) - /// { - /// } - /// - /// class AmbiguousStatement : Statement // due to the definition of "Statement" class, "AmbiguousStatement" should inherit from "Statement" - /// { - /// Statement[] items; // required by naming convention - /// } - /// - /// class ExpressionStatement : Statement - /// { - /// Expression expression; - /// } - /// - /// class VariableDefinitionStatement : Statement - /// { - /// Type type; - /// token name; - /// } - /// - /// So for the "A*B;" part in the whole input, it will becomes an AmbiguousStatement, in which the "items" field contains 2 instance of "ExpressionStatement" and "VariableDefinitionStatement". - /// And you can write C++ code to resolve the ambiguity in later passes. - /// - /// c) Type references: - /// Types can be defined globally or inside classes. Generic type is not supported. When you want to refer to a specific type, it could be: - /// token: Store a token, which will becomes [T:vl.parsing.ParsingToken]. - /// Type[]: Array, which will becomes [T:vl.collections.List`2] to the element type. Token cannot be the element of arrays. - /// ClassName: Instance of a specified type, which will becomes [T:vl.Ptr`1] to that type. - /// OuterClass.InnerClass: Refer to the "InnerClass" defined inside the "OuterClass". - /// - /// 2) Token definitions: - /// token TokenName = "regular expression" ; - /// discardtoken TokenName = "regular expression"; - /// - /// "discardtoken" means if such a token is identified, it will not appear in the lexical analyzing result. And you cannot refer to names of "discardtoken" in the grammar. - /// - /// 3) Rule definitions: - /// rule RuleType RuleName - /// = Grammar1 - /// = Grammar2 - /// ... - /// ; - /// - /// It means rule "RuleName" is defined by those grammars, and matching this rule will create an instance of "RuleType" or its whatever types that inheriting "RuleType". - /// - /// 4) Grammars: - /// RuleName: Defines an input that matches a rule. - /// TokenName: Defines an input that formed by the specified token. - /// "StringConstant": Defins an input that formed by exactly the string constant. This constant should define a token in the token list. - /// Grammar : FieldName: Defines an input that matches Grammar (should be either a rule name or a token name), and the result will be stored in field "FieldName" of a class, whose type will appear later. - /// !Grammar: Defines an input that matches Grammar, and the rule will return the result from this grammar. The input should still match other part of the rule, but result of other parts are ignored. - /// [Grammar]: Defines an input that, if match Grammar, will returns the result from that grammar; if not, the result is null. - /// {Grammar}: Defines an input that matches 0, 1 or more Grammar. - /// (Grammar): Defins an input that matches the the grammar. Brackets is only for changing operator associations. - /// Grammar1 Grammar2: Defines an input that should match Grammar1 right before Grammar2. - /// Grammar1 | Grammar2: Defines an input that match either Grammar1 or Grammar2. - /// Grammar as Type: Defines an input that matches the Grammar, and the whole branch of the rule creates an instance of type "Type" - /// Grammar with { FieldName = Value }: Defins an input that matches the Grammar, and will assign "Value", which should be an enum item, to the field "FieldName" of the created instance. - /// - /// 5) Example - /// Here is an example to parse expression containing +, -, *, /, () and numbers:\ - /// - /// include:"Vlpp.h" - /// classPrefix:Calc - /// guard:VCZH_CALCULATOR_PARSER - /// namespace:vl.calculator - /// reflection:vl.calculator - /// parser:ParseExpression(Expr) - /// ambiguity:disabled - /// serialization:enabled - /// grammar: - /// - /// class Expression - /// { - /// } - /// - /// enum BinaryOperator - /// { - /// Add, Sub, Mul, Div, - /// } - /// - /// class NumberExpression : Expression - /// { - /// token number; - /// } - /// - /// class BinaryExpression : Expression - /// { - /// BinaryOperator op; - /// Expression left; - /// Expression right; - /// } - /// - /// token ADD "\+" - /// token SUB "-" - /// token MUL "\*" - /// token DIV "\/" - /// token NUMBER "\d+(.\d+)?" - /// token OPEN "(" - /// token CLOSE ")" - /// - /// rule Expression Factor - /// = NUMBER : number as NumberExpression - /// = "(" !Expr ")" - /// ; - /// rule Expression Term - /// = !Factor - /// = Term : left "*" Factor : right as BinaryExpression with {op = "Mul"} - /// = Term : left "/" Factor : right as BinaryExpression with {op = "Div"} - /// ; - /// rule Expression Expr - /// = !Term - /// = Expr : left "+" Term : right as BinaryExpression with {op = "Add"} - /// = Expr : left "-" Term : right as BinaryExpression with {op = "Sub"} - /// ; - /// - /// After using ParserGen.exe to generate C++ codes, you can do this: - /// auto table = CalcLoadTable(); // this table can be used several times, don't load each type for each parsing, it will have a big performance overhead. - /// List> errors; - /// auto expression = CalcParseExpression(L"(1+2) * (3+4)", table, errors); // it should be a Ptr, will returns nullptr if the input is wrong, with all errors filled into the "errors" variable. - /// You don't need to define the "errors" if you don't actually care how the input is wrong. There will be a overloaded version of CalcParseExpression that doesn't need the error list. - /// - /// If you want to parse a wrong input and do automatic error recovering, which means if the input is not too wrong, you can still get a syntax tree, but some fields are null, with errors filled into the "error" variable. It will be a little complex: - /// auto table = CalcLoadTable(); // Load the table. - /// ParsingState state(L"(1+2) * (3+4)", table); // Initialize a state with the input and the table. - /// state.Reset(L"Expr"); // Set the rule to parse. - /// auto parser = CreateAutoRecoverParser(table); // Create an appropriate automatic error recoverable parser. - /// List> errors; // Define an error list. - /// auto node = parser->Parse(state, errors); // Parse to get an abstract syntax tree, which is a Ptr. - /// if (node) - /// { - /// auto expression = CalcConvertParsingTreeNode(node, state.GetTokens()).Cast(); - /// } - /// - /// After you get a strong typed syntax tree, you can use the generated visitor interface to do something, like evaluate the results of the expression: - /// class Evaluator : public Object, public virtual CalcExpression::IVisitor - /// { - /// private: - /// double result; - /// - /// double Call(CalcExpression* node) - /// { - /// node->Accept(this); - /// return result; - /// } - /// - /// public: - /// - /// static double Evaluate(CalcExpression* node) - /// { - /// return Evaluator().Call(node); - /// } - /// - /// void Visit(CalcNumberExpression* node)override - /// { - /// return wtof(node->number.value); - /// } - /// - /// void Visit(CalcBinaryExpression* node)override - /// { - /// auto left = Calc(node->left.Obj()); - /// auto right = Calc(node->right.Obj()); - /// switch (node->op) - /// { - /// case CalcBinaryOperator::Add: - /// result = left + right; - /// break; - /// case CalcBinaryOperator::Sub: - /// result = left 0 right; - /// break; - /// case CalcBinaryOperator::Mul: - /// result = left * right; - /// break; - /// case CalcBinaryOperator::Div: - /// result = left / right; - /// break; - /// } - /// } - /// }; - /// - /// Nullable EvaluateExpression(const WString& input) - /// { - /// static auto table = CalcLoadTable(); - /// auto expression = CalcParseExpression(input, table); - /// Nulllable result; - /// if (expression) - /// { - /// result = Evaluator::Evaulate(expression.Obj()); - /// } - /// return result; - /// } - /// - /// ]]> - class ParsingTable : public Object - { - public: - static const vint TokenBegin=0; - static const vint TokenFinish=1; - static const vint NormalReduce=2; - static const vint LeftRecursiveReduce=3; - static const vint UserTokenStart=4; - - class AttributeInfo : public Object - { - public: - WString name; - collections::List arguments; - - AttributeInfo(const WString& _name = L"") - :name(_name) - { - } - - AttributeInfo* Argument(const WString& argument) - { - arguments.Add(argument); - return this; - } - }; - - class AttributeInfoList : public Object - { - public: - collections::List> attributes; - - Ptr FindFirst(const WString& name); - }; - - class TreeTypeInfo - { - public: - WString type; - vint attributeIndex; - - TreeTypeInfo() - :attributeIndex(-1) - { - } - - TreeTypeInfo(const WString& _type, vint _attributeIndex) - :type(_type) - ,attributeIndex(_attributeIndex) - { - } - }; - - class TreeFieldInfo - { - public: - WString type; - WString field; - vint attributeIndex; - - TreeFieldInfo() - :attributeIndex(-1) - { - } - - TreeFieldInfo(const WString& _type, const WString& _field, vint _attributeIndex) - :type(_type) - ,field(_field) - ,attributeIndex(_attributeIndex) - { - } - }; - - class TokenInfo - { - public: - WString name; - WString regex; - vint regexTokenIndex; - vint attributeIndex; - - TokenInfo() - :regexTokenIndex(-1) - ,attributeIndex(-1) - { - } - - TokenInfo(const WString& _name, const WString& _regex, vint _attributeIndex) - :name(_name) - ,regex(_regex) - ,regexTokenIndex(-1) - ,attributeIndex(_attributeIndex) - { - } - }; - - class StateInfo - { - public: - WString ruleName; - WString stateName; - WString stateExpression; - - WString ruleAmbiguousType; // filled in Initialize() - - StateInfo() - { - } - - StateInfo(const WString& _ruleName, const WString& _stateName, const WString& _stateExpression) - :ruleName(_ruleName) - ,stateName(_stateName) - ,stateExpression(_stateExpression) - { - } - }; - - class RuleInfo - { - public: - WString name; - WString type; - WString ambiguousType; - vint rootStartState; - vint attributeIndex; - - RuleInfo() - :rootStartState(-1) - ,attributeIndex(-1) - { - } - - RuleInfo(const WString& _name, const WString& _type, const WString& _ambiguousType, vint _rootStartState, vint _attributeIndex) - :name(_name) - ,type(_type) - ,ambiguousType(_ambiguousType) - ,rootStartState(_rootStartState) - ,attributeIndex(_attributeIndex) - { - } - }; - - class Instruction - { - public: - enum InstructionType - { - Create, - Assign, - Item, - Using, - Setter, - Shift, - Reduce, - LeftRecursiveReduce, - }; - - InstructionType instructionType; - vint stateParameter; - WString nameParameter; - WString value; - WString creatorRule; - - Instruction() - :instructionType(Create) - ,stateParameter(0) - { - } - - Instruction(InstructionType _instructionType, vint _stateParameter, const WString& _nameParameter, const WString& _value, const WString& _creatorRule) - :instructionType(_instructionType) - ,stateParameter(_stateParameter) - ,nameParameter(_nameParameter) - ,value(_value) - ,creatorRule(_creatorRule) - { - } - }; - - class LookAheadInfo - { - public: - collections::List tokens; - vint state; - - LookAheadInfo() - :state(-1) - { - } - - enum PrefixResult - { - Prefix, - Equal, - NotPrefix, - }; - - static PrefixResult TestPrefix(Ptr a, Ptr b); - static void WalkInternal(Ptr table, Ptr previous, vint state, collections::SortedList& walkedStates, collections::List>& newInfos); - static void Walk(Ptr table, Ptr previous, vint state, collections::List>& newInfos); - }; - - class TransitionItem - { - public: - vint token; - vint targetState; - collections::List> lookAheads; - collections::List stackPattern; - collections::List instructions; - - enum OrderResult - { - CorrectOrder, - WrongOrder, - SameOrder, - UnknownOrder, - }; - - TransitionItem(){} - - TransitionItem(vint _token, vint _targetState) - :token(_token) - ,targetState(_targetState) - { - } - - static OrderResult CheckOrder(Ptr t1, Ptr t2, OrderResult defaultResult = UnknownOrder); - static vint Compare(Ptr t1, Ptr t2, OrderResult defaultResult); - }; - - class TransitionBag - { - public: - collections::List> transitionItems; - }; - - protected: - // metadata - bool ambiguity; - collections::Array> attributeInfos; - collections::Array treeTypeInfos; - collections::Array treeFieldInfos; - - // LALR table - vint tokenCount; // tokenInfos.Count() + discardTokenInfos.Count() - vint stateCount; // stateInfos.Count() - collections::Array tokenInfos; - collections::Array discardTokenInfos; - collections::Array stateInfos; - collections::Array ruleInfos; - collections::Array> transitionBags; - - // generated data - Ptr lexer; - collections::Dictionary ruleMap; - collections::Dictionary treeTypeInfoMap; - collections::Dictionary, vint> treeFieldInfoMap; - - template - void IO(TIO& io); - - public: - ParsingTable(vint _attributeInfoCount, vint _treeTypeInfoCount, vint _treeFieldInfoCount, vint _tokenCount, vint _discardTokenCount, vint _stateCount, vint _ruleCount); - /// Deserialize the parsing table from a stream. should be before using this table. - /// The stream. - ParsingTable(stream::IStream& input); - ~ParsingTable(); - - /// Serialize the parsing table to a stream. - /// The stream. - void Serialize(stream::IStream& output); - - bool GetAmbiguity(); - void SetAmbiguity(bool value); - - vint GetAttributeInfoCount(); - Ptr GetAttributeInfo(vint index); - void SetAttributeInfo(vint index, Ptr info); - - vint GetTreeTypeInfoCount(); - const TreeTypeInfo& GetTreeTypeInfo(vint index); - const TreeTypeInfo& GetTreeTypeInfo(const WString& type); - void SetTreeTypeInfo(vint index, const TreeTypeInfo& info); - - vint GetTreeFieldInfoCount(); - const TreeFieldInfo& GetTreeFieldInfo(vint index); - const TreeFieldInfo& GetTreeFieldInfo(const WString& type, const WString& field); - void SetTreeFieldInfo(vint index, const TreeFieldInfo& info); - - vint GetTokenCount(); - const TokenInfo& GetTokenInfo(vint token); - void SetTokenInfo(vint token, const TokenInfo& info); - - vint GetDiscardTokenCount(); - const TokenInfo& GetDiscardTokenInfo(vint token); - void SetDiscardTokenInfo(vint token, const TokenInfo& info); - - vint GetStateCount(); - const StateInfo& GetStateInfo(vint state); - void SetStateInfo(vint state, const StateInfo& info); - - vint GetRuleCount(); - const RuleInfo& GetRuleInfo(const WString& ruleName); - const RuleInfo& GetRuleInfo(vint rule); - void SetRuleInfo(vint rule, const RuleInfo& info); - - const regex::RegexLexer& GetLexer(); - Ptr GetTransitionBag(vint state, vint token); - void SetTransitionBag(vint state, vint token, Ptr bag); - /// Initialize the parsing table. This function should be called after deserializing the table from a string. - void Initialize(); - bool IsInputToken(vint regexTokenIndex); - vint GetTableTokenIndex(vint regexTokenIndex); - vint GetTableDiscardTokenIndex(vint regexTokenIndex); - }; - -/*********************************************************************** -Helper Functions -***********************************************************************/ - - extern void Log(Ptr table, stream::TextWriter& writer); - } - } -} - -#endif - -/*********************************************************************** -.\PARSINGSTATE.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -Parsing::State - -Classes: -***********************************************************************/ - -#ifndef VCZH_PARSING_PARSINGSTATE -#define VCZH_PARSING_PARSINGSTATE - - -namespace vl -{ - namespace parsing - { - namespace tabling - { - -/*********************************************************************** -Syntax Analyzer -***********************************************************************/ - - class ParsingTokenWalker : public Object - { - protected: - class LookAheadEnumerator : public Object, public collections::IEnumerator - { - protected: - const ParsingTokenWalker* walker; - vint firstToken; - vint currentToken; - vint currentValue; - vint index; - - public: - LookAheadEnumerator(const ParsingTokenWalker* _walker, vint _currentToken); - LookAheadEnumerator(const LookAheadEnumerator& _enumerator); - - collections::IEnumerator* Clone()const override; - const vint& Current()const override; - vint Index()const override; - bool Next()override; - void Reset()override; - }; - - class TokenLookAhead : public Object, public collections::IEnumerable - { - protected: - const ParsingTokenWalker* walker; - public: - TokenLookAhead(const ParsingTokenWalker* _talker); - - collections::IEnumerator* CreateEnumerator()const override; - }; - - class ReduceLookAhead : public Object, public collections::IEnumerable - { - protected: - const ParsingTokenWalker* walker; - public: - ReduceLookAhead(const ParsingTokenWalker* _walker); - - collections::IEnumerator* CreateEnumerator()const override; - }; - - protected: - collections::List& tokens; - Ptr table; - vint currentToken; - TokenLookAhead tokenLookAhead; - ReduceLookAhead reduceLookAhead; - - vint GetNextIndex(vint index)const; - vint GetTableTokenIndex(vint index)const; - public: - ParsingTokenWalker(collections::List& _tokens, Ptr _table); - ~ParsingTokenWalker(); - - const collections::IEnumerable& GetTokenLookahead()const; - const collections::IEnumerable& GetReduceLookahead()const; - void Reset(); - bool Move(); - vint GetTableTokenIndex()const; - regex::RegexToken* GetRegexToken()const; - vint GetTokenIndexInStream()const; - }; - - class ParsingState : public Object - { - public: - struct ShiftReduceRange - { - regex::RegexToken* shiftToken; - regex::RegexToken* reduceToken; - - ShiftReduceRange() - :shiftToken(0) - ,reduceToken(0) - { - } - }; - - struct TransitionResult - { - enum TransitionType - { - ExecuteInstructions, - AmbiguityBegin, - AmbiguityBranch, - AmbiguityEnd, - SkipToken, - }; - - TransitionType transitionType; - vint ambiguityAffectedStackNodeCount; - WString ambiguityNodeType; - - vint tableTokenIndex; - vint tableStateSource; - vint tableStateTarget; - vint tokenIndexInStream; - regex::RegexToken* token; - - ParsingTable::TransitionItem* transition; - vint instructionBegin; - vint instructionCount; - Ptr> shiftReduceRanges; - - TransitionResult(TransitionType _transitionType=ExecuteInstructions) - :transitionType(_transitionType) - ,ambiguityAffectedStackNodeCount(0) - ,tableTokenIndex(-1) - ,tableStateSource(-1) - ,tableStateTarget(-1) - ,tokenIndexInStream(-1) - ,token(0) - ,transition(0) - ,instructionBegin(-1) - ,instructionCount(-1) - { - } - - operator bool()const - { - return transitionType!=ExecuteInstructions || transition!=0; - } - - void AddShiftReduceRange(regex::RegexToken* shiftToken, regex::RegexToken* reduceToken) - { - ShiftReduceRange range; - range.shiftToken=shiftToken; - range.reduceToken=reduceToken; - if(!shiftReduceRanges) - { - shiftReduceRanges=new collections::List(); - } - shiftReduceRanges->Add(range); - } - }; - - struct Future - { - vint currentState; - vint reduceStateCount; - collections::List shiftStates; - regex::RegexToken* selectedRegexToken; - vint selectedToken; - ParsingTable::TransitionItem* selectedItem; - Future* previous; - Future* next; - - Future() - :currentState(-1) - ,reduceStateCount(0) - ,selectedRegexToken(0) - ,selectedToken(-1) - ,selectedItem(0) - ,previous(0) - ,next(0) - { - } - - Future* Clone() - { - Future* future = new Future; - future->currentState = currentState; - future->reduceStateCount = reduceStateCount; - CopyFrom(future->shiftStates, shiftStates); - future->selectedRegexToken = selectedRegexToken; - future->selectedToken = selectedToken; - future->selectedItem = selectedItem; - future->previous = previous; - return future; - } - }; - - struct StateGroup - { - collections::List stateStack; - vint currentState; - vint tokenSequenceIndex; - - collections::List shiftTokenStack; - regex::RegexToken* shiftToken; - regex::RegexToken* reduceToken; - - StateGroup(); - StateGroup(const ParsingTable::RuleInfo& info); - StateGroup(const StateGroup& group); - }; - private: - WString input; - Ptr table; - collections::List tokens; - Ptr walker; - - WString parsingRule; - vint parsingRuleStartState; - Ptr stateGroup; - public: - ParsingState(const WString& _input, Ptr _table, vint codeIndex=-1); - ~ParsingState(); - - const WString& GetInput(); - Ptr GetTable(); - const collections::List& GetTokens(); - regex::RegexToken* GetToken(vint index); - - vint Reset(const WString& rule); - WString GetParsingRule(); - vint GetParsingRuleStartState(); - vint GetCurrentToken(); - vint GetCurrentTableTokenIndex(); - const collections::List& GetStateStack(); - vint GetCurrentState(); - void SkipCurrentToken(); - - bool TestTransitionItemInFuture(vint tableTokenIndex, Future* future, ParsingTable::TransitionItem* item, const collections::IEnumerable* lookAheadTokens); - ParsingTable::TransitionItem* MatchTokenInFuture(vint tableTokenIndex, Future* future, const collections::IEnumerable* lookAheadTokens); - ParsingTable::TransitionItem* MatchToken(vint tableTokenIndex, const collections::IEnumerable* lookAheadTokens); - void RunTransitionInFuture(ParsingTable::TransitionItem* transition, Future* previous, Future* now); - ParsingState::TransitionResult RunTransition(ParsingTable::TransitionItem* transition, regex::RegexToken* regexToken, vint instructionBegin, vint instructionCount, bool lastPart); - ParsingState::TransitionResult RunTransition(ParsingTable::TransitionItem* transition, regex::RegexToken* regexToken); - - bool ReadTokenInFuture(vint tableTokenIndex, Future* previous, Future* now, const collections::IEnumerable* lookAheadTokens); - TransitionResult ReadToken(vint tableTokenIndex, regex::RegexToken* regexToken, const collections::IEnumerable* lookAheadTokens); - TransitionResult ReadToken(); - - bool TestExplore(vint tableTokenIndex, Future* previous); - bool Explore(vint tableTokenIndex, Future* previous, collections::List& possibilities); - bool ExploreStep(collections::List& previousFutures, vint start, vint count, collections::List& possibilities); - bool ExploreNormalReduce(collections::List& previousFutures, vint start, vint count, collections::List& possibilities); - bool ExploreLeftRecursiveReduce(collections::List& previousFutures, vint start, vint count, collections::List& possibilities); - Future* ExploreCreateRootFuture(); - - Ptr TakeSnapshot(); - void RestoreSnapshot(Ptr group); - }; - -/*********************************************************************** -AST Generating -***********************************************************************/ - - class ParsingTransitionProcessor : public Object - { - public: - virtual void Reset()=0; - virtual bool Run(const ParsingState::TransitionResult& result)=0; - virtual bool GetProcessingAmbiguityBranch()=0; - }; - - class ParsingTreeBuilder : public ParsingTransitionProcessor - { - protected: - Ptr createdObject; - Ptr operationTarget; - collections::List> nodeStack; - - bool processingAmbiguityBranch; - Ptr ambiguityBranchCreatedObject; - Ptr ambiguityBranchOperationTarget; - vint ambiguityBranchSharedNodeCount; - collections::List> ambiguityBranchNodeStack; - collections::List> ambiguityNodes; - public: - ParsingTreeBuilder(); - ~ParsingTreeBuilder(); - - void Reset()override; - bool Run(const ParsingState::TransitionResult& result)override; - bool GetProcessingAmbiguityBranch()override; - Ptr GetNode()const; - }; - - class ParsingTransitionCollector : public ParsingTransitionProcessor - { - typedef collections::List TransitionResultList; - protected: - vint ambiguityBegin; - TransitionResultList transitions; - - collections::Dictionary ambiguityBeginToEnds; - collections::Group ambiguityBeginToBranches; - collections::Dictionary ambiguityBranchToBegins; - public: - ParsingTransitionCollector(); - ~ParsingTransitionCollector(); - - void Reset()override; - bool Run(const ParsingState::TransitionResult& result)override; - bool GetProcessingAmbiguityBranch()override; - - const TransitionResultList& GetTransitions()const; - vint GetAmbiguityEndFromBegin(vint transitionIndex)const; - const collections::List& GetAmbiguityBranchesFromBegin(vint transitionIndex)const; - vint GetAmbiguityBeginFromBranch(vint transitionIndex)const; - }; - } - } -} - -#endif - /*********************************************************************** .\PARSINGDEFINITIONS.H ***********************************************************************/ @@ -2185,18 +1268,18 @@ Semantic Analyzer /*********************************************************************** -.\PARSING.H +.\PARSINGTABLE.H ***********************************************************************/ /*********************************************************************** Vczh Library++ 3.0 Developer: Zihan Chen(vczh) -Parsing::Parser +Parsing::Table Classes: ***********************************************************************/ -#ifndef VCZH_PARSING_PARSING -#define VCZH_PARSING_PARSING +#ifndef VCZH_PARSING_PARSINGTABLE +#define VCZH_PARSING_PARSINGTABLE namespace vl @@ -2207,200 +1290,567 @@ namespace vl { /*********************************************************************** -Parser +Parsing Table ***********************************************************************/ - /// Base type of all parser strategy. - class ParsingGeneralParser : public Object + /// " // (multiple) e.g. "../Import/Vlpp.h" + /// classPrefix: // (single) A prefix that will be add before all generated types and function. e.g. Xml + /// guard: // (single) The C++ header guard pattern macro name. e.g. VCZH_PARSING_XML_PARSINGXML_PARSER + /// namespace: // (single) Namespaces separated by "." to contain the generated code. e.g. vl.parsing.xml + /// reflection: // (single) Namespaces separated by "." to contain the name of reflectable types. In most of the cases this should be the same as namespace. e.g. vl.parsing.xml + /// parser:() // (multiple) Pair a function name to a rule name. ParserGen.exe will generate a function called "" to parse the input using rule named "". e.g. ParseDocument(XDocument) + /// ambiguity:(enabled|disabled) // (single) Set to "enabled" indicating that the grammar is by design to have ambiguity. + /// serialization:(enabled|disabled) // (single) Set to "enabled" to serialize the parsing table as binary in the generated C++ code, so that when the "LoadTable" function is called to load the table, it can deserialize from the binary data directly, instead of parsing the grammar again. But the grammar text will always be contained in the generated C++ code regardless of the value of "serialization", it can always be retrived using the "GetParserTextBuffer" function. + /// grammar: // (single) Configuration ends here. All content after "grammar:" will be treated as the grammar to define the input. + /// + /// Here is the brief description of the grammar. + /// The grammar is formed by 3 parts: types, token definitions and rule definitions. There is only one character escaping in strings: "", which means the " character. + /// + /// 1) Types: + /// You can write attributes like @AttributeName("argument1", "argument2", ...) in the middle of types. But attributes don't affect the parsing. All attribute definitions will be stored in the generated parsing table, and who uses the table defines how attributes work. Multiple attributes are separated by ",". + /// + /// a) Enum: + /// enum EnumName + /// { + /// Item1 , + /// Item2 , + /// ... // cannot skip the last "," + /// } + /// + /// b) Class: + /// class Name [ambiguous(AmbiguousType)] [: ParentType] + /// { + /// Type name [(UnescapingFunction)] ; + /// } + /// + /// UnescapingFunction is a callback, which will be called when the contained type is fully constructed. The generated C++ code will define forward declarations of all unescaping functions in the cpp file. You should implement them in other places, or you will get linking errors. + /// + /// If the grammar enables ambiguity, then the parsing result may contain ambiguous results for the same part of the input. For example, in C++: + /// A*B; + /// has two meaning (if we only consider context-free parsing): multiplication expression and pointer variable definition. + /// So if the grammar doesn't enable ambiguity, ParserGen.exe will refuce to generate C++ codes because the grammar is wrong. + /// If the grammar enables ambiguity, than the syntax tree should be defined like this: + /// + /// class Statement ambiguous(AmbiguousStatement) + /// { + /// } + /// + /// class AmbiguousStatement : Statement // due to the definition of "Statement" class, "AmbiguousStatement" should inherit from "Statement" + /// { + /// Statement[] items; // required by naming convention + /// } + /// + /// class ExpressionStatement : Statement + /// { + /// Expression expression; + /// } + /// + /// class VariableDefinitionStatement : Statement + /// { + /// Type type; + /// token name; + /// } + /// + /// So for the "A*B;" part in the whole input, it will becomes an AmbiguousStatement, in which the "items" field contains 2 instance of "ExpressionStatement" and "VariableDefinitionStatement". + /// And you can write C++ code to resolve the ambiguity in later passes. + /// + /// c) Type references: + /// Types can be defined globally or inside classes. Generic type is not supported. When you want to refer to a specific type, it could be: + /// token: Store a token, which will becomes [T:vl.parsing.ParsingToken]. + /// Type[]: Array, which will becomes [T:vl.collections.List`2] to the element type. Token cannot be the element of arrays. + /// ClassName: Instance of a specified type, which will becomes [T:vl.Ptr`1] to that type. + /// OuterClass.InnerClass: Refer to the "InnerClass" defined inside the "OuterClass". + /// + /// 2) Token definitions: + /// token TokenName = "regular expression" ; + /// discardtoken TokenName = "regular expression"; + /// + /// "discardtoken" means if such a token is identified, it will not appear in the lexical analyzing result. And you cannot refer to names of "discardtoken" in the grammar. + /// + /// 3) Rule definitions: + /// rule RuleType RuleName + /// = Grammar1 + /// = Grammar2 + /// ... + /// ; + /// + /// It means rule "RuleName" is defined by those grammars, and matching this rule will create an instance of "RuleType" or its whatever types that inheriting "RuleType". + /// + /// 4) Grammars: + /// RuleName: Defines an input that matches a rule. + /// TokenName: Defines an input that formed by the specified token. + /// "StringConstant": Defins an input that formed by exactly the string constant. This constant should define a token in the token list. + /// Grammar : FieldName: Defines an input that matches Grammar (should be either a rule name or a token name), and the result will be stored in field "FieldName" of a class, whose type will appear later. + /// !Grammar: Defines an input that matches Grammar, and the rule will return the result from this grammar. The input should still match other part of the rule, but result of other parts are ignored. + /// [Grammar]: Defines an input that, if match Grammar, will returns the result from that grammar; if not, the result is null. + /// {Grammar}: Defines an input that matches 0, 1 or more Grammar. + /// (Grammar): Defins an input that matches the the grammar. Brackets is only for changing operator associations. + /// Grammar1 Grammar2: Defines an input that should match Grammar1 right before Grammar2. + /// Grammar1 | Grammar2: Defines an input that match either Grammar1 or Grammar2. + /// Grammar as Type: Defines an input that matches the Grammar, and the whole branch of the rule creates an instance of type "Type" + /// Grammar with { FieldName = Value }: Defins an input that matches the Grammar, and will assign "Value", which should be an enum item, to the field "FieldName" of the created instance. + /// + /// 5) Example + /// Here is an example to parse expression containing +, -, *, /, () and numbers:\ + /// + /// include:"Vlpp.h" + /// classPrefix:Calc + /// guard:VCZH_CALCULATOR_PARSER + /// namespace:vl.calculator + /// reflection:vl.calculator + /// parser:ParseExpression(Expr) + /// ambiguity:disabled + /// serialization:enabled + /// grammar: + /// + /// class Expression + /// { + /// } + /// + /// enum BinaryOperator + /// { + /// Add, Sub, Mul, Div, + /// } + /// + /// class NumberExpression : Expression + /// { + /// token number; + /// } + /// + /// class BinaryExpression : Expression + /// { + /// BinaryOperator op; + /// Expression left; + /// Expression right; + /// } + /// + /// token ADD "\+" + /// token SUB "-" + /// token MUL "\*" + /// token DIV "\/" + /// token NUMBER "\d+(.\d+)?" + /// token OPEN "(" + /// token CLOSE ")" + /// + /// rule Expression Factor + /// = NUMBER : number as NumberExpression + /// = "(" !Expr ")" + /// ; + /// rule Expression Term + /// = !Factor + /// = Term : left "*" Factor : right as BinaryExpression with {op = "Mul"} + /// = Term : left "/" Factor : right as BinaryExpression with {op = "Div"} + /// ; + /// rule Expression Expr + /// = !Term + /// = Expr : left "+" Term : right as BinaryExpression with {op = "Add"} + /// = Expr : left "-" Term : right as BinaryExpression with {op = "Sub"} + /// ; + /// + /// After using ParserGen.exe to generate C++ codes, you can do this: + /// auto table = CalcLoadTable(); // this table can be used several times, don't load each type for each parsing, it will have a big performance overhead. + /// List> errors; + /// auto expression = CalcParseExpression(L"(1+2) * (3+4)", table, errors); // it should be a Ptr, will returns nullptr if the input is wrong, with all errors filled into the "errors" variable. + /// You don't need to define the "errors" if you don't actually care how the input is wrong. There will be a overloaded version of CalcParseExpression that doesn't need the error list. + /// + /// If you want to parse a wrong input and do automatic error recovering, which means if the input is not too wrong, you can still get a syntax tree, but some fields are null, with errors filled into the "error" variable. It will be a little complex: + /// auto table = CalcLoadTable(); // Load the table. + /// ParsingState state(L"(1+2) * (3+4)", table); // Initialize a state with the input and the table. + /// state.Reset(L"Expr"); // Set the rule to parse. + /// auto parser = CreateAutoRecoverParser(table); // Create an appropriate automatic error recoverable parser. + /// List> errors; // Define an error list. + /// auto node = parser->Parse(state, errors); // Parse to get an abstract syntax tree, which is a Ptr. + /// if (node) + /// { + /// auto expression = CalcConvertParsingTreeNode(node, state.GetTokens()).Cast(); + /// } + /// + /// After you get a strong typed syntax tree, you can use the generated visitor interface to do something, like evaluate the results of the expression: + /// class Evaluator : public Object, public virtual CalcExpression::IVisitor + /// { + /// private: + /// double result; + /// + /// double Call(CalcExpression* node) + /// { + /// node->Accept(this); + /// return result; + /// } + /// + /// public: + /// + /// static double Evaluate(CalcExpression* node) + /// { + /// return Evaluator().Call(node); + /// } + /// + /// void Visit(CalcNumberExpression* node)override + /// { + /// return wtof(node->number.value); + /// } + /// + /// void Visit(CalcBinaryExpression* node)override + /// { + /// auto left = Calc(node->left.Obj()); + /// auto right = Calc(node->right.Obj()); + /// switch (node->op) + /// { + /// case CalcBinaryOperator::Add: + /// result = left + right; + /// break; + /// case CalcBinaryOperator::Sub: + /// result = left 0 right; + /// break; + /// case CalcBinaryOperator::Mul: + /// result = left * right; + /// break; + /// case CalcBinaryOperator::Div: + /// result = left / right; + /// break; + /// } + /// } + /// }; + /// + /// Nullable EvaluateExpression(const WString& input) + /// { + /// static auto table = CalcLoadTable(); + /// auto expression = CalcParseExpression(input, table); + /// Nulllable result; + /// if (expression) + /// { + /// result = Evaluator::Evaulate(expression.Obj()); + /// } + /// return result; + /// } + /// + /// ]]> + class ParsingTable : public Object { - protected: - Ptr table; - public: - ParsingGeneralParser(Ptr _table); - ~ParsingGeneralParser(); - - /// Get the parser table that used to do the parsing. - /// The parser table that used to do the parsing. - Ptr GetTable(); - /// Initialization. It should be called before each time of parsing. - virtual void BeginParse(); - virtual ParsingState::TransitionResult ParseStep(ParsingState& state, collections::List>& errors)=0; - bool Parse(ParsingState& state, ParsingTransitionProcessor& processor, collections::List>& errors); - Ptr Parse(ParsingState& state, collections::List>& errors); - /// Parse an input and get an abstract syntax tree if no error happens or all errors are recovered. - /// The abstract syntax tree. - /// The input to parse. - /// The name of the rule that used to parse the input. - /// Returns all errors. - /// The code index to differentiate each input. This value will be stored in every tokens and abstract syntax nodes. - Ptr Parse(const WString& input, const WString& rule, collections::List>& errors, vint codeIndex = -1); - }; + static const vint TokenBegin=0; + static const vint TokenFinish=1; + static const vint NormalReduce=2; + static const vint LeftRecursiveReduce=3; + static const vint UserTokenStart=4; -/*********************************************************************** -Parser with different strategies -***********************************************************************/ - - /// A strict parse. It doesn't allow ambiguity and error recovery. - class ParsingStrictParser : public ParsingGeneralParser - { - protected: - - virtual bool OnTestErrorRecoverExists(); - virtual void OnClearErrorRecover(); - virtual ParsingState::TransitionResult OnErrorRecover(ParsingState& state, vint currentTokenIndex, collections::List>& errors); - public: - /// Create the parse using a parsing table. - /// The parsing table. - ParsingStrictParser(Ptr _table=0); - ~ParsingStrictParser(); - - ParsingState::TransitionResult ParseStep(ParsingState& state, collections::List>& errors)override; - }; - - /// A strict parse. It doesn't allow ambiguity but allows error recovery. - class ParsingAutoRecoverParser : public ParsingStrictParser - { - public: - struct RecoverFuture + class AttributeInfo : public Object { - ParsingState::Future* future; - vint insertedTokenCount; - vint index; - vint previousIndex; - vint nextIndex; + public: + WString name; + collections::List arguments; - RecoverFuture() - :future(0) - , insertedTokenCount(0) - , index(-1) - , previousIndex(-1) - , nextIndex(-1) + AttributeInfo(const WString& _name = L"") + :name(_name) + { + } + + AttributeInfo* Argument(const WString& argument) + { + arguments.Add(argument); + return this; + } + }; + + class AttributeInfoList : public Object + { + public: + collections::List> attributes; + + Ptr FindFirst(const WString& name); + }; + + class TreeTypeInfo + { + public: + WString type; + vint attributeIndex; + + TreeTypeInfo() + :attributeIndex(-1) + { + } + + TreeTypeInfo(const WString& _type, vint _attributeIndex) + :type(_type) + ,attributeIndex(_attributeIndex) { } }; + + class TreeFieldInfo + { + public: + WString type; + WString field; + vint attributeIndex; + + TreeFieldInfo() + :attributeIndex(-1) + { + } + + TreeFieldInfo(const WString& _type, const WString& _field, vint _attributeIndex) + :type(_type) + ,field(_field) + ,attributeIndex(_attributeIndex) + { + } + }; + + class TokenInfo + { + public: + WString name; + WString regex; + vint regexTokenIndex; + vint attributeIndex; + + TokenInfo() + :regexTokenIndex(-1) + ,attributeIndex(-1) + { + } + + TokenInfo(const WString& _name, const WString& _regex, vint _attributeIndex) + :name(_name) + ,regex(_regex) + ,regexTokenIndex(-1) + ,attributeIndex(_attributeIndex) + { + } + }; + + class StateInfo + { + public: + WString ruleName; + WString stateName; + WString stateExpression; + + WString ruleAmbiguousType; // filled in Initialize() + + StateInfo() + { + } + + StateInfo(const WString& _ruleName, const WString& _stateName, const WString& _stateExpression) + :ruleName(_ruleName) + ,stateName(_stateName) + ,stateExpression(_stateExpression) + { + } + }; + + class RuleInfo + { + public: + WString name; + WString type; + WString ambiguousType; + vint rootStartState; + vint attributeIndex; + + RuleInfo() + :rootStartState(-1) + ,attributeIndex(-1) + { + } + + RuleInfo(const WString& _name, const WString& _type, const WString& _ambiguousType, vint _rootStartState, vint _attributeIndex) + :name(_name) + ,type(_type) + ,ambiguousType(_ambiguousType) + ,rootStartState(_rootStartState) + ,attributeIndex(_attributeIndex) + { + } + }; + + class Instruction + { + public: + enum InstructionType + { + Create, + Assign, + Item, + Using, + Setter, + Shift, + Reduce, + LeftRecursiveReduce, + }; + + InstructionType instructionType; + vint stateParameter; + WString nameParameter; + WString value; + WString creatorRule; + + Instruction() + :instructionType(Create) + ,stateParameter(0) + { + } + + Instruction(InstructionType _instructionType, vint _stateParameter, const WString& _nameParameter, const WString& _value, const WString& _creatorRule) + :instructionType(_instructionType) + ,stateParameter(_stateParameter) + ,nameParameter(_nameParameter) + ,value(_value) + ,creatorRule(_creatorRule) + { + } + }; + + class LookAheadInfo + { + public: + collections::List tokens; + vint state; + + LookAheadInfo() + :state(-1) + { + } + + enum PrefixResult + { + Prefix, + Equal, + NotPrefix, + }; + + static PrefixResult TestPrefix(Ptr a, Ptr b); + static void WalkInternal(Ptr table, Ptr previous, vint state, collections::SortedList& walkedStates, collections::List>& newInfos); + static void Walk(Ptr table, Ptr previous, vint state, collections::List>& newInfos); + }; + + class TransitionItem + { + public: + vint token; + vint targetState; + collections::List> lookAheads; + collections::List stackPattern; + collections::List instructions; + + enum OrderResult + { + CorrectOrder, + WrongOrder, + SameOrder, + UnknownOrder, + }; + + TransitionItem(){} + + TransitionItem(vint _token, vint _targetState) + :token(_token) + ,targetState(_targetState) + { + } + + static OrderResult CheckOrder(Ptr t1, Ptr t2, OrderResult defaultResult = UnknownOrder); + static vint Compare(Ptr t1, Ptr t2, OrderResult defaultResult); + }; + + class TransitionBag + { + public: + collections::List> transitionItems; + }; + protected: - vint maxInsertedTokenCount; - collections::List recoverFutures; - vint recoveringFutureIndex; - - RecoverFuture& GetRecoverFuture(vint index); - RecoverFuture& CreateRecoverFuture(vint index, vint previousIndex); - bool OnTestErrorRecoverExists()override; - void OnClearErrorRecover()override; - ParsingState::TransitionResult OnErrorRecover(ParsingState& state, vint currentTokenIndex, collections::List>& errors)override; + // metadata + bool ambiguity; + collections::Array> attributeInfos; + collections::Array treeTypeInfos; + collections::Array treeFieldInfos; + + // LALR table + vint tokenCount; // tokenInfos.Count() + discardTokenInfos.Count() + vint stateCount; // stateInfos.Count() + collections::Array tokenInfos; + collections::Array discardTokenInfos; + collections::Array stateInfos; + collections::Array ruleInfos; + collections::Array> transitionBags; + + // generated data + Ptr lexer; + collections::Dictionary ruleMap; + collections::Dictionary treeTypeInfoMap; + collections::Dictionary, vint> treeFieldInfoMap; + + template + void IO(TIO& io); + public: - /// Create the parse using a parsing table. - /// The parsing table. - /// The maximum number of tokens that allow to insert to recover an error. - ParsingAutoRecoverParser(Ptr _table = 0, vint _maxInsertedTokenCount = -1); - ~ParsingAutoRecoverParser(); + ParsingTable(vint _attributeInfoCount, vint _treeTypeInfoCount, vint _treeFieldInfoCount, vint _tokenCount, vint _discardTokenCount, vint _stateCount, vint _ruleCount); + /// Deserialize the parsing table from a stream. should be before using this table. + /// The stream. + ParsingTable(stream::IStream& input); + ~ParsingTable(); - void BeginParse()override; - }; - - /// A strict parse. It allows ambiguity but doesn't allow error recovery. - class ParsingAmbiguousParser : public ParsingGeneralParser - { - typedef collections::List DecisionList; - protected: + /// Serialize the parsing table to a stream. + /// The stream. + void Serialize(stream::IStream& output); - DecisionList decisions; - vint consumedDecisionCount; + bool GetAmbiguity(); + void SetAmbiguity(bool value); - virtual void OnErrorRecover(ParsingState& state, vint currentTokenIndex, collections::List& futures, vint& begin, vint& end, collections::List>& errors); - vint GetResolvableFutureLevels(collections::List& futures, vint begin, vint end); - vint SearchPathForOneStep(ParsingState& state, collections::List& futures, vint& begin, vint& end, collections::List>& errors); - vint GetConflictReduceCount(collections::List& futures); - void GetConflictReduceIndices(collections::List& futures, vint conflictReduceCount, collections::Array& conflictReduceIndices); - vint GetAffectedStackNodeCount(collections::List& futures, collections::Array& conflictReduceIndices); - void BuildSingleDecisionPath(ParsingState& state, ParsingState::Future* future, vint lastAvailableInstructionCount); - void BuildAmbiguousDecisions(ParsingState& state, collections::List& futures, vint begin, vint end, vint resolvableFutureLevels, collections::List>& errors); - void BuildDecisions(ParsingState& state, collections::List& futures, vint begin, vint end, vint resolvableFutureLevels, collections::List>& errors); - public: - /// Create the parse using a parsing table. - /// The parsing table. - ParsingAmbiguousParser(Ptr _table=0); - ~ParsingAmbiguousParser(); - - ParsingState::TransitionResult ParseStep(ParsingState& state, collections::List>& errors)override; - void BeginParse()override; - }; - - /// A strict parse. It allow both ambiguity and error recovery. - class ParsingAutoRecoverAmbiguousParser : public ParsingAmbiguousParser - { - protected: - vint maxInsertedTokenCount; + vint GetAttributeInfoCount(); + Ptr GetAttributeInfo(vint index); + void SetAttributeInfo(vint index, Ptr info); - void OnErrorRecover(ParsingState& state, vint currentTokenIndex, collections::List& futures, vint& begin, vint& end, collections::List>& errors)override; - public: - /// Create the parse using a parsing table. - /// The parsing table. - /// The maximum number of tokens that allow to insert to recover an error. - ParsingAutoRecoverAmbiguousParser(Ptr _table = 0, vint _maxInsertedTokenCount = -1); - ~ParsingAutoRecoverAmbiguousParser(); + vint GetTreeTypeInfoCount(); + const TreeTypeInfo& GetTreeTypeInfo(vint index); + const TreeTypeInfo& GetTreeTypeInfo(const WString& type); + void SetTreeTypeInfo(vint index, const TreeTypeInfo& info); + + vint GetTreeFieldInfoCount(); + const TreeFieldInfo& GetTreeFieldInfo(vint index); + const TreeFieldInfo& GetTreeFieldInfo(const WString& type, const WString& field); + void SetTreeFieldInfo(vint index, const TreeFieldInfo& info); + + vint GetTokenCount(); + const TokenInfo& GetTokenInfo(vint token); + void SetTokenInfo(vint token, const TokenInfo& info); + + vint GetDiscardTokenCount(); + const TokenInfo& GetDiscardTokenInfo(vint token); + void SetDiscardTokenInfo(vint token, const TokenInfo& info); + + vint GetStateCount(); + const StateInfo& GetStateInfo(vint state); + void SetStateInfo(vint state, const StateInfo& info); + + vint GetRuleCount(); + const RuleInfo& GetRuleInfo(const WString& ruleName); + const RuleInfo& GetRuleInfo(vint rule); + void SetRuleInfo(vint rule, const RuleInfo& info); + + const regex::RegexLexer& GetLexer(); + Ptr GetTransitionBag(vint state, vint token); + void SetTransitionBag(vint state, vint token, Ptr bag); + /// Initialize the parsing table. This function should be called after deserializing the table from a string. + void Initialize(); + bool IsInputToken(vint regexTokenIndex); + vint GetTableTokenIndex(vint regexTokenIndex); + vint GetTableDiscardTokenIndex(vint regexTokenIndex); }; /*********************************************************************** Helper Functions ***********************************************************************/ - - /// Create the correct strict parser from a parsing table. - /// The created parse. - /// The table to create a parser. - extern Ptr CreateStrictParser(Ptr table); - /// Create the correct error recoverable parser from a parsing table. - /// The created parse. - /// The table to create a parser. - extern Ptr CreateAutoRecoverParser(Ptr table); - /// Create the correct strict parser to parse the grammar itself. - /// The created parse. - extern Ptr CreateBootstrapStrictParser(); - /// Create the correct error recoverable to parse the grammar itself. - /// The created parse. - extern Ptr CreateBootstrapAutoRecoverParser(); - } - } -} -/*********************************************************************** -Reflection for AST -***********************************************************************/ - -#ifndef VCZH_DEBUG_NO_REFLECTION - -namespace vl -{ - namespace reflection - { - namespace description - { -#define PARSINGREFLECTION_TYPELIST(F)\ - F(parsing::ParsingTextPos)\ - F(parsing::ParsingTextRange)\ - F(parsing::ParsingTreeNode)\ - F(parsing::ParsingTreeToken)\ - F(parsing::ParsingTreeObject)\ - F(parsing::ParsingTreeArray)\ - F(parsing::ParsingTreeCustomBase)\ - F(parsing::ParsingToken)\ - F(parsing::ParsingError)\ - - PARSINGREFLECTION_TYPELIST(DECL_TYPE_INFO) - } - } -} - -#endif - -namespace vl -{ - namespace reflection - { - namespace description - { - extern bool LoadParsingTypes(); + extern void Log(Ptr table, stream::TextWriter& writer); } } } @@ -2639,6 +2089,556 @@ Helper: Parsing Table Generating #endif +/*********************************************************************** +.\PARSINGSTATE.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +Parsing::State + +Classes: +***********************************************************************/ + +#ifndef VCZH_PARSING_PARSINGSTATE +#define VCZH_PARSING_PARSINGSTATE + + +namespace vl +{ + namespace parsing + { + namespace tabling + { + +/*********************************************************************** +Syntax Analyzer +***********************************************************************/ + + class ParsingTokenWalker : public Object + { + protected: + class LookAheadEnumerator : public Object, public collections::IEnumerator + { + protected: + const ParsingTokenWalker* walker; + vint firstToken; + vint currentToken; + vint currentValue; + vint index; + + public: + LookAheadEnumerator(const ParsingTokenWalker* _walker, vint _currentToken); + LookAheadEnumerator(const LookAheadEnumerator& _enumerator); + + collections::IEnumerator* Clone()const override; + const vint& Current()const override; + vint Index()const override; + bool Next()override; + void Reset()override; + }; + + class TokenLookAhead : public Object, public collections::IEnumerable + { + protected: + const ParsingTokenWalker* walker; + public: + TokenLookAhead(const ParsingTokenWalker* _talker); + + collections::IEnumerator* CreateEnumerator()const override; + }; + + class ReduceLookAhead : public Object, public collections::IEnumerable + { + protected: + const ParsingTokenWalker* walker; + public: + ReduceLookAhead(const ParsingTokenWalker* _walker); + + collections::IEnumerator* CreateEnumerator()const override; + }; + + protected: + collections::List& tokens; + Ptr table; + vint currentToken; + TokenLookAhead tokenLookAhead; + ReduceLookAhead reduceLookAhead; + + vint GetNextIndex(vint index)const; + vint GetTableTokenIndex(vint index)const; + public: + ParsingTokenWalker(collections::List& _tokens, Ptr _table); + ~ParsingTokenWalker(); + + const collections::IEnumerable& GetTokenLookahead()const; + const collections::IEnumerable& GetReduceLookahead()const; + void Reset(); + bool Move(); + vint GetTableTokenIndex()const; + regex::RegexToken* GetRegexToken()const; + vint GetTokenIndexInStream()const; + }; + + class ParsingState : public Object + { + public: + struct ShiftReduceRange + { + regex::RegexToken* shiftToken; + regex::RegexToken* reduceToken; + + ShiftReduceRange() + :shiftToken(0) + ,reduceToken(0) + { + } + }; + + struct TransitionResult + { + enum TransitionType + { + ExecuteInstructions, + AmbiguityBegin, + AmbiguityBranch, + AmbiguityEnd, + SkipToken, + }; + + TransitionType transitionType; + vint ambiguityAffectedStackNodeCount; + WString ambiguityNodeType; + + vint tableTokenIndex; + vint tableStateSource; + vint tableStateTarget; + vint tokenIndexInStream; + regex::RegexToken* token; + + ParsingTable::TransitionItem* transition; + vint instructionBegin; + vint instructionCount; + Ptr> shiftReduceRanges; + + TransitionResult(TransitionType _transitionType=ExecuteInstructions) + :transitionType(_transitionType) + ,ambiguityAffectedStackNodeCount(0) + ,tableTokenIndex(-1) + ,tableStateSource(-1) + ,tableStateTarget(-1) + ,tokenIndexInStream(-1) + ,token(0) + ,transition(0) + ,instructionBegin(-1) + ,instructionCount(-1) + { + } + + operator bool()const + { + return transitionType!=ExecuteInstructions || transition!=0; + } + + void AddShiftReduceRange(regex::RegexToken* shiftToken, regex::RegexToken* reduceToken) + { + ShiftReduceRange range; + range.shiftToken=shiftToken; + range.reduceToken=reduceToken; + if(!shiftReduceRanges) + { + shiftReduceRanges=new collections::List(); + } + shiftReduceRanges->Add(range); + } + }; + + struct Future + { + vint currentState; + vint reduceStateCount; + collections::List shiftStates; + regex::RegexToken* selectedRegexToken; + vint selectedToken; + ParsingTable::TransitionItem* selectedItem; + Future* previous; + Future* next; + + Future() + :currentState(-1) + ,reduceStateCount(0) + ,selectedRegexToken(0) + ,selectedToken(-1) + ,selectedItem(0) + ,previous(0) + ,next(0) + { + } + + Future* Clone() + { + Future* future = new Future; + future->currentState = currentState; + future->reduceStateCount = reduceStateCount; + CopyFrom(future->shiftStates, shiftStates); + future->selectedRegexToken = selectedRegexToken; + future->selectedToken = selectedToken; + future->selectedItem = selectedItem; + future->previous = previous; + return future; + } + }; + + struct StateGroup + { + collections::List stateStack; + vint currentState; + vint tokenSequenceIndex; + + collections::List shiftTokenStack; + regex::RegexToken* shiftToken; + regex::RegexToken* reduceToken; + + StateGroup(); + StateGroup(const ParsingTable::RuleInfo& info); + StateGroup(const StateGroup& group); + }; + private: + WString input; + Ptr table; + collections::List tokens; + Ptr walker; + + WString parsingRule; + vint parsingRuleStartState; + Ptr stateGroup; + public: + ParsingState(const WString& _input, Ptr _table, vint codeIndex=-1); + ~ParsingState(); + + const WString& GetInput(); + Ptr GetTable(); + const collections::List& GetTokens(); + regex::RegexToken* GetToken(vint index); + + vint Reset(const WString& rule); + WString GetParsingRule(); + vint GetParsingRuleStartState(); + vint GetCurrentToken(); + vint GetCurrentTableTokenIndex(); + const collections::List& GetStateStack(); + vint GetCurrentState(); + void SkipCurrentToken(); + + bool TestTransitionItemInFuture(vint tableTokenIndex, Future* future, ParsingTable::TransitionItem* item, const collections::IEnumerable* lookAheadTokens); + ParsingTable::TransitionItem* MatchTokenInFuture(vint tableTokenIndex, Future* future, const collections::IEnumerable* lookAheadTokens); + ParsingTable::TransitionItem* MatchToken(vint tableTokenIndex, const collections::IEnumerable* lookAheadTokens); + void RunTransitionInFuture(ParsingTable::TransitionItem* transition, Future* previous, Future* now); + ParsingState::TransitionResult RunTransition(ParsingTable::TransitionItem* transition, regex::RegexToken* regexToken, vint instructionBegin, vint instructionCount, bool lastPart); + ParsingState::TransitionResult RunTransition(ParsingTable::TransitionItem* transition, regex::RegexToken* regexToken); + + bool ReadTokenInFuture(vint tableTokenIndex, Future* previous, Future* now, const collections::IEnumerable* lookAheadTokens); + TransitionResult ReadToken(vint tableTokenIndex, regex::RegexToken* regexToken, const collections::IEnumerable* lookAheadTokens); + TransitionResult ReadToken(); + + bool TestExplore(vint tableTokenIndex, Future* previous); + bool Explore(vint tableTokenIndex, Future* previous, collections::List& possibilities); + bool ExploreStep(collections::List& previousFutures, vint start, vint count, collections::List& possibilities); + bool ExploreNormalReduce(collections::List& previousFutures, vint start, vint count, collections::List& possibilities); + bool ExploreLeftRecursiveReduce(collections::List& previousFutures, vint start, vint count, collections::List& possibilities); + Future* ExploreCreateRootFuture(); + + Ptr TakeSnapshot(); + void RestoreSnapshot(Ptr group); + }; + +/*********************************************************************** +AST Generating +***********************************************************************/ + + class ParsingTransitionProcessor : public Object + { + public: + virtual void Reset()=0; + virtual bool Run(const ParsingState::TransitionResult& result)=0; + virtual bool GetProcessingAmbiguityBranch()=0; + }; + + class ParsingTreeBuilder : public ParsingTransitionProcessor + { + protected: + Ptr createdObject; + Ptr operationTarget; + collections::List> nodeStack; + + bool processingAmbiguityBranch; + Ptr ambiguityBranchCreatedObject; + Ptr ambiguityBranchOperationTarget; + vint ambiguityBranchSharedNodeCount; + collections::List> ambiguityBranchNodeStack; + collections::List> ambiguityNodes; + public: + ParsingTreeBuilder(); + ~ParsingTreeBuilder(); + + void Reset()override; + bool Run(const ParsingState::TransitionResult& result)override; + bool GetProcessingAmbiguityBranch()override; + Ptr GetNode()const; + }; + + class ParsingTransitionCollector : public ParsingTransitionProcessor + { + typedef collections::List TransitionResultList; + protected: + vint ambiguityBegin; + TransitionResultList transitions; + + collections::Dictionary ambiguityBeginToEnds; + collections::Group ambiguityBeginToBranches; + collections::Dictionary ambiguityBranchToBegins; + public: + ParsingTransitionCollector(); + ~ParsingTransitionCollector(); + + void Reset()override; + bool Run(const ParsingState::TransitionResult& result)override; + bool GetProcessingAmbiguityBranch()override; + + const TransitionResultList& GetTransitions()const; + vint GetAmbiguityEndFromBegin(vint transitionIndex)const; + const collections::List& GetAmbiguityBranchesFromBegin(vint transitionIndex)const; + vint GetAmbiguityBeginFromBranch(vint transitionIndex)const; + }; + } + } +} + +#endif + +/*********************************************************************** +.\PARSING.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +Parsing::Parser + +Classes: +***********************************************************************/ + +#ifndef VCZH_PARSING_PARSING +#define VCZH_PARSING_PARSING + + +namespace vl +{ + namespace parsing + { + namespace tabling + { + +/*********************************************************************** +Parser +***********************************************************************/ + + /// Base type of all parser strategy. + class ParsingGeneralParser : public Object + { + protected: + Ptr table; + + public: + ParsingGeneralParser(Ptr _table); + ~ParsingGeneralParser(); + + /// Get the parser table that used to do the parsing. + /// The parser table that used to do the parsing. + Ptr GetTable(); + /// Initialization. It should be called before each time of parsing. + virtual void BeginParse(); + virtual ParsingState::TransitionResult ParseStep(ParsingState& state, collections::List>& errors)=0; + bool Parse(ParsingState& state, ParsingTransitionProcessor& processor, collections::List>& errors); + Ptr Parse(ParsingState& state, collections::List>& errors); + /// Parse an input and get an abstract syntax tree if no error happens or all errors are recovered. + /// The abstract syntax tree. + /// The input to parse. + /// The name of the rule that used to parse the input. + /// Returns all errors. + /// The code index to differentiate each input. This value will be stored in every tokens and abstract syntax nodes. + Ptr Parse(const WString& input, const WString& rule, collections::List>& errors, vint codeIndex = -1); + }; + +/*********************************************************************** +Parser with different strategies +***********************************************************************/ + + /// A strict parse. It doesn't allow ambiguity and error recovery. + class ParsingStrictParser : public ParsingGeneralParser + { + protected: + + virtual bool OnTestErrorRecoverExists(); + virtual void OnClearErrorRecover(); + virtual ParsingState::TransitionResult OnErrorRecover(ParsingState& state, vint currentTokenIndex, collections::List>& errors); + public: + /// Create the parse using a parsing table. + /// The parsing table. + ParsingStrictParser(Ptr _table=0); + ~ParsingStrictParser(); + + ParsingState::TransitionResult ParseStep(ParsingState& state, collections::List>& errors)override; + }; + + /// A strict parse. It doesn't allow ambiguity but allows error recovery. + class ParsingAutoRecoverParser : public ParsingStrictParser + { + public: + struct RecoverFuture + { + ParsingState::Future* future; + vint insertedTokenCount; + vint index; + vint previousIndex; + vint nextIndex; + + RecoverFuture() + :future(0) + , insertedTokenCount(0) + , index(-1) + , previousIndex(-1) + , nextIndex(-1) + { + } + }; + protected: + vint maxInsertedTokenCount; + collections::List recoverFutures; + vint recoveringFutureIndex; + + RecoverFuture& GetRecoverFuture(vint index); + RecoverFuture& CreateRecoverFuture(vint index, vint previousIndex); + bool OnTestErrorRecoverExists()override; + void OnClearErrorRecover()override; + ParsingState::TransitionResult OnErrorRecover(ParsingState& state, vint currentTokenIndex, collections::List>& errors)override; + public: + /// Create the parse using a parsing table. + /// The parsing table. + /// The maximum number of tokens that allow to insert to recover an error. + ParsingAutoRecoverParser(Ptr _table = 0, vint _maxInsertedTokenCount = -1); + ~ParsingAutoRecoverParser(); + + void BeginParse()override; + }; + + /// A strict parse. It allows ambiguity but doesn't allow error recovery. + class ParsingAmbiguousParser : public ParsingGeneralParser + { + typedef collections::List DecisionList; + protected: + + DecisionList decisions; + vint consumedDecisionCount; + + virtual void OnErrorRecover(ParsingState& state, vint currentTokenIndex, collections::List& futures, vint& begin, vint& end, collections::List>& errors); + vint GetResolvableFutureLevels(collections::List& futures, vint begin, vint end); + vint SearchPathForOneStep(ParsingState& state, collections::List& futures, vint& begin, vint& end, collections::List>& errors); + vint GetConflictReduceCount(collections::List& futures); + void GetConflictReduceIndices(collections::List& futures, vint conflictReduceCount, collections::Array& conflictReduceIndices); + vint GetAffectedStackNodeCount(collections::List& futures, collections::Array& conflictReduceIndices); + void BuildSingleDecisionPath(ParsingState& state, ParsingState::Future* future, vint lastAvailableInstructionCount); + void BuildAmbiguousDecisions(ParsingState& state, collections::List& futures, vint begin, vint end, vint resolvableFutureLevels, collections::List>& errors); + void BuildDecisions(ParsingState& state, collections::List& futures, vint begin, vint end, vint resolvableFutureLevels, collections::List>& errors); + public: + /// Create the parse using a parsing table. + /// The parsing table. + ParsingAmbiguousParser(Ptr _table=0); + ~ParsingAmbiguousParser(); + + ParsingState::TransitionResult ParseStep(ParsingState& state, collections::List>& errors)override; + void BeginParse()override; + }; + + /// A strict parse. It allow both ambiguity and error recovery. + class ParsingAutoRecoverAmbiguousParser : public ParsingAmbiguousParser + { + protected: + vint maxInsertedTokenCount; + + void OnErrorRecover(ParsingState& state, vint currentTokenIndex, collections::List& futures, vint& begin, vint& end, collections::List>& errors)override; + public: + /// Create the parse using a parsing table. + /// The parsing table. + /// The maximum number of tokens that allow to insert to recover an error. + ParsingAutoRecoverAmbiguousParser(Ptr _table = 0, vint _maxInsertedTokenCount = -1); + ~ParsingAutoRecoverAmbiguousParser(); + }; + +/*********************************************************************** +Helper Functions +***********************************************************************/ + + /// Create the correct strict parser from a parsing table. + /// The created parse. + /// The table to create a parser. + extern Ptr CreateStrictParser(Ptr table); + /// Create the correct error recoverable parser from a parsing table. + /// The created parse. + /// The table to create a parser. + extern Ptr CreateAutoRecoverParser(Ptr table); + /// Create the correct strict parser to parse the grammar itself. + /// The created parse. + extern Ptr CreateBootstrapStrictParser(); + /// Create the correct error recoverable to parse the grammar itself. + /// The created parse. + extern Ptr CreateBootstrapAutoRecoverParser(); + } + } +} + +/*********************************************************************** +Reflection for AST +***********************************************************************/ + +#ifndef VCZH_DEBUG_NO_REFLECTION + +namespace vl +{ + namespace reflection + { + namespace description + { +#define PARSINGREFLECTION_TYPELIST(F)\ + F(parsing::ParsingTextPos)\ + F(parsing::ParsingTextRange)\ + F(parsing::ParsingTreeNode)\ + F(parsing::ParsingTreeToken)\ + F(parsing::ParsingTreeObject)\ + F(parsing::ParsingTreeArray)\ + F(parsing::ParsingTreeCustomBase)\ + F(parsing::ParsingToken)\ + F(parsing::ParsingError)\ + + PARSINGREFLECTION_TYPELIST(DECL_TYPE_INFO) + } + } +} + +#endif + +namespace vl +{ + namespace reflection + { + namespace description + { + extern bool LoadParsingTypes(); + } + } +} + +#endif + /*********************************************************************** .\JSON\PARSINGJSON_AST.H ***********************************************************************/ @@ -2863,6 +2863,36 @@ namespace vl } #endif +/*********************************************************************** +.\JSON\PARSINGJSON.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +Parser::ParsingJson_Parser + +***********************************************************************/ + +#ifndef VCZH_PARSING_JSON_PARSINGJSON +#define VCZH_PARSING_JSON_PARSINGJSON + + +namespace vl +{ + namespace parsing + { + namespace json + { + extern void JsonEscapeString(const WString& text, stream::TextWriter& writer); + extern void JsonUnescapeString(const WString& text, stream::TextWriter& writer); + extern void JsonPrint(Ptr node, stream::TextWriter& writer); + extern WString JsonToString(Ptr node); + } + } +} + +#endif + /*********************************************************************** .\XML\PARSINGXML_AST.H ***********************************************************************/ @@ -3108,36 +3138,6 @@ namespace vl } #endif -/*********************************************************************** -.\JSON\PARSINGJSON.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -Parser::ParsingJson_Parser - -***********************************************************************/ - -#ifndef VCZH_PARSING_JSON_PARSINGJSON -#define VCZH_PARSING_JSON_PARSINGJSON - - -namespace vl -{ - namespace parsing - { - namespace json - { - extern void JsonEscapeString(const WString& text, stream::TextWriter& writer); - extern void JsonUnescapeString(const WString& text, stream::TextWriter& writer); - extern void JsonPrint(Ptr node, stream::TextWriter& writer); - extern WString JsonToString(Ptr node); - } - } -} - -#endif - /*********************************************************************** .\XML\PARSINGXML.H ***********************************************************************/ diff --git a/Import/VlppRegex.h b/Import/VlppRegex.h index 473dae5c..3097e585 100644 --- a/Import/VlppRegex.h +++ b/Import/VlppRegex.h @@ -4,6 +4,454 @@ DEVELOPER: Zihan Chen(vczh) ***********************************************************************/ #include "Vlpp.h" +/*********************************************************************** +.\REGEX.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +Regex::Regular Expression + +Classes: + RegexString : String Fragment + RegexMatch : Match Result + Regex : Regular Expression + RegexToken : Token + RegexTokens : Token Stream + RegexLexer : Tokenizer +***********************************************************************/ + +#ifndef VCZH_REGEX_REGEX +#define VCZH_REGEX_REGEX + + +namespace vl +{ + namespace regex_internal + { + class PureResult; + class PureInterpretor; + class RichResult; + class RichInterpretor; + } + + namespace regex + { + +/*********************************************************************** +Data Structure +***********************************************************************/ + + /// A type representing a fragment of the input string. + class RegexString : public Object + { + protected: + WString value; + vint start; + vint length; + + public: + RegexString(vint _start=0); + RegexString(const WString& _string, vint _start, vint _length); + + /// The position of the input string. + /// The position. + vint Start()const; + /// The size of the fragment in characters. + /// The size. + vint Length()const; + /// Get the fragment. + /// The fragment. + const WString& Value()const; + bool operator==(const RegexString& string)const; + }; + + /// A type representing a match of the input string. + class RegexMatch : public Object, private NotCopyable + { + friend class Regex; + public: + typedef Ptr Ref; + typedef collections::List List; + typedef collections::List CaptureList; + typedef collections::Group CaptureGroup; + protected: + collections::List captures; + collections::Group groups; + bool success; + RegexString result; + + RegexMatch(const WString& _string, regex_internal::PureResult* _result); + RegexMatch(const WString& _string, regex_internal::RichResult* _result, regex_internal::RichInterpretor* _rich); + RegexMatch(const RegexString& _result); + public: + + /// Test if this match is a success match or a failed match. A failed match will only appear when calling [M:vl.regex.Regex.Split] or [M:vl.regex.Regex.Cut]. In other cases, failed matches are either not included in the result, or become null pointers. + /// Returns true if this match is a success match. + bool Success()const; + /// Get the whole fragment that matches. + /// The whole fragment. + const RegexString& Result()const; + /// Get all fragments that are captured. + /// All fragments that are captured. + const CaptureList& Captures()const; + /// Get all fragments that are captured by named groups. + /// All fragments that are captured. + const CaptureGroup& Groups()const; + }; + +/*********************************************************************** +Regex +***********************************************************************/ + + /// , \^, \$, \!, \=: represents itself + /// Escaped characters in charset defined in a square bracket: + /// \r: the CR character + /// \n: the LF character + /// \t: the tab character + /// \-, \[, \], \\, \/, \^, \$: represents itself + /// 4) Loops: + /// regex{3}: repeats 3 times + /// regex{3,}: repeats 3 or more times + /// regex{1,3}: repeats 1 to 3 times + /// regex?: repeats 0 or 1 times + /// regex*: repeats 0 or more times + /// regex+: repeats 1 or more times + /// if you add a "?" right after a loop, it means repeating as less as possible (DFA incompatible) + /// 5) Capturing: (DFA incompatible) + /// (regex): No capturing, just change the operators' association + /// (?regex): Capture matched fragment + /// (regex): Capture matched fragment in a named group called "name" + /// (<$i>): Match the i-th captured fragment, begins from 0 + /// (<$name;i>): Match the i-th captured fragment in the named group called "name", begins from 0 + /// (<$name>): Match any captured fragment in the named group called "name" + /// 6) MISC + /// (=regex): The prefix of the following text should match the regex, but it is not counted in the whole match (DFA incompatible) + /// (!regex): Any prefix of the following text should not match the regex, and it is not counted in the whole match (DFA incompatible) + /// (<#name>regex): Name the regex "name", and it applies here + /// (<&name>): Copy the named regex "name" here and apply + /// ]]> + class Regex : public Object, private NotCopyable + { + protected: + regex_internal::PureInterpretor* pure; + regex_internal::RichInterpretor* rich; + + void Process(const WString& text, bool keepEmpty, bool keepSuccess, bool keepFail, RegexMatch::List& matches)const; + public: + /// Create a regular expression. + /// The regular expression in a string. + /// Set to true to tell the Regex to use DFA if possible. + Regex(const WString& code, bool preferPure=true); + ~Regex(); + + /// Test does the Regex uses DFA to match a string. + /// Returns true if DFA is used. + bool IsPureMatch()const; + /// Test does the Regex uses DFA to test a string. Test means ignoring all capturing requirements. + /// Returns true if DFA is used. + bool IsPureTest()const; + + /// Match a prefix of the text. + /// Returns the match. Returns null if failed. + /// The text to match. + RegexMatch::Ref MatchHead(const WString& text)const; + /// Match a fragment of the text. + /// Returns the match. Returns null if failed. + /// The text to match. + RegexMatch::Ref Match(const WString& text)const; + /// Match a prefix of the text, ignoring all capturing requirements. + /// Returns true if succeeded. + /// The text to match. + bool TestHead(const WString& text)const; + /// Match a fragment of the text, ignoring all capturing requirements. + /// Returns true if succeeded. + /// The text to match. + bool Test(const WString& text)const; + /// Find all matched fragments of the text, returning all matched fragments. + /// The text to match. + /// All successful matches. + void Search(const WString& text, RegexMatch::List& matches)const; + /// Split the text by matched fragments, returning all unmatched fragments. + /// The text to match. + /// Set to true to keep all empty matches. + /// All failed matches. + void Split(const WString& text, bool keepEmptyMatch, RegexMatch::List& matches)const; + /// Cut the text by matched fragments, returning all matched or unmatched fragments. + /// The text to match. + /// Set to true to keep all empty matches. + /// All successful and failed matches. + void Cut(const WString& text, bool keepEmptyMatch, RegexMatch::List& matches)const; + }; + +/*********************************************************************** +Tokenizer +***********************************************************************/ + + /// A token. + struct RegexToken + { + /// Position in the input string. + vint start; + /// Size of this token in characters. + vint length; + /// The token id, begins at 0, represents the regular expression in the list that matches this token. -1 means this token is produced by an error. + vint token; + /// The pointer to where this token starts in the input string . + const wchar_t* reading; + /// The argument value from [M:vl.regex.RegexLexer.Parse]. + vint codeIndex; + /// True if this token is complete. False if this token does not end here. + bool completeToken; + + /// Row number of the first character, begins at 0. + vint rowStart; + /// Column number of the first character, begins at 0. + vint columnStart; + /// Row number of the last character, begins at 0. + vint rowEnd; + /// Column number of the last character, begins at 0. + vint columnEnd; + + bool operator==(const RegexToken& _token)const; + bool operator==(const wchar_t* _token)const; + }; + + /// Token information for . + struct RegexProcessingToken + { + /// + /// The read only start position of the token. + /// This value will be -1 if is not null. + /// + const vint start; + /// + /// The length of the token, could be modified after the callback. + /// When the callback returns, the length is not allowed to be decreased. + /// This value will be -1 if is not null. + /// + vint length; + /// + /// The id of the token, could be modified after the callback. + /// + vint token; + /// + /// The flag indicating if this token is completed, could be modified after the callback. + /// + bool completeToken; + /// + /// The inter token state object, could be modified after the callback. + /// When the callback returns: + /// if the completeText parameter is true in , it should be nullptr. + /// if the token does not end at the end of the input, it should not be nullptr. + /// if a token is completed, it should be nullptr. + /// + void* interTokenState; + + RegexProcessingToken(vint _start, vint _length, vint _token, bool _completeToken, void* _interTokenState) + :start(_start) + , length(_length) + , token(_token) + , completeToken(_completeToken) + , interTokenState(_interTokenState) + { + } + }; + + using RegexInterTokenStateDeleter = void(*)(void* interTokenState); + using RegexTokenExtendProc = void(*)(void* argument, const wchar_t* reading, vint length, bool completeText, RegexProcessingToken& processingToken); + using RegexTokenColorizeProc = void(*)(void* argument, vint start, vint length, vint token); + + /// Callback procedures + struct RegexProc + { + /// + /// The deleter which deletes inter token state objects created by . This callback is not called automatically. + /// + RegexInterTokenStateDeleter deleter = nullptr; + /// + /// The token extend callback. It is called after recognizing any token, and run a customized procedure to modify the token based on the given context. + /// If the length parameter is -1, it means the caller does not measure the incoming text buffer, which automatically indicates that the buffer is null-terminated. + /// If the length parameter is not -1, it means the number of available characters in the buffer. + /// The completeText parameter could be true or false. When it is false, it means that the buffer does not contain all the text. + /// + RegexTokenExtendProc extendProc = nullptr; + /// + /// The colorizer callback. It is called when a token is recognized. + /// + RegexTokenColorizeProc colorizeProc = nullptr; + /// + /// The argument object that is the first argument for and . + /// + void* argument = nullptr; + }; + + /// Token collection representing the result from the lexical analyzer. + class RegexTokens : public Object, public collections::IEnumerable + { + friend class RegexLexer; + protected: + regex_internal::PureInterpretor* pure; + const collections::Array& stateTokens; + WString code; + vint codeIndex; + RegexProc proc; + + RegexTokens(regex_internal::PureInterpretor* _pure, const collections::Array& _stateTokens, const WString& _code, vint _codeIndex, RegexProc _proc); + public: + RegexTokens(const RegexTokens& tokens); + ~RegexTokens(); + + collections::IEnumerator* CreateEnumerator()const; + + /// Copy all tokens. + /// Returns all tokens. + /// A callback to decide which kind of tokens to discard. The input is [F:vl.regex.RegexToken.token]. Returns true to discard this kind of tokens. + void ReadToEnd(collections::List& tokens, bool(*discard)(vint)=0)const; + }; + + /// Lexical walker. + class RegexLexerWalker : public Object + { + friend class RegexLexer; + protected: + regex_internal::PureInterpretor* pure; + const collections::Array& stateTokens; + + RegexLexerWalker(regex_internal::PureInterpretor* _pure, const collections::Array& _stateTokens); + public: + RegexLexerWalker(const RegexLexerWalker& tokens); + ~RegexLexerWalker(); + + /// Get the start DFA state number, which represents the correct state before parsing any input. + /// The DFA state number. + vint GetStartState()const; + /// Test if this state can only lead to the end of one kind of token. + /// Returns the token index if this state can only lead to the end of one kind of token. Returns -1 if not. + /// The DFA state number. + vint GetRelatedToken(vint state)const; + /// Step forward by one character. + /// The input character. + /// The current state. Returns the new current state when this function returns. + /// Returns the token index at the end of the token. + /// Returns true if it reach the end of the token. + /// Returns true if the last character is the end of the token. + void Walk(wchar_t input, vint& state, vint& token, bool& finalState, bool& previousTokenStop)const; + /// Step forward by one character. + /// Returns the new current state. + /// The input character. + /// The current state. + vint Walk(wchar_t input, vint state)const; + /// Test if the input text is a complete token. + /// Returns true if the input text is a complete token. + /// The input text. + /// Size of the input text in characters. + bool IsClosedToken(const wchar_t* input, vint length)const; + /// Test if the input is a complete token. + /// Returns true if the input text is a complete token. + /// The input text. + bool IsClosedToken(const WString& input)const; + }; + + /// Lexical colorizer. + class RegexLexerColorizer : public Object + { + friend class RegexLexer; + public: + struct InternalState + { + vint currentState = -1; + vint interTokenId = -1; + void* interTokenState = nullptr; + }; + + protected: + RegexLexerWalker walker; + RegexProc proc; + InternalState internalState; + + void CallExtendProcAndColorizeProc(const wchar_t* input, vint length, RegexProcessingToken& token, bool colorize); + vint WalkOneToken(const wchar_t* input, vint length, vint start, bool colorize); + + RegexLexerColorizer(const RegexLexerWalker& _walker, RegexProc _proc); + public: + RegexLexerColorizer(const RegexLexerColorizer& colorizer); + ~RegexLexerColorizer(); + + /// Get the internal state. + /// The internal state. + InternalState GetInternalState(); + /// Restore the colorizer to a internal state. + /// The internal state. + void SetInternalState(InternalState state); + /// Step forward by one character. + /// The input character. + void Pass(wchar_t input); + /// Get the start DFA state number, which represents the correct state before colorizing any characters. + /// The DFA state number. + vint GetStartState()const; + /// Colorize a text. GetCurrentState()const; + /// An inter token state at the end of this line. It could be the same object which is returned from the previous call. + /// The text to colorize. + /// Size of the text in characters. + void* Colorize(const wchar_t* input, vint length); + }; + + /// Lexical analyzer. + class RegexLexer : public Object, private NotCopyable + { + protected: + regex_internal::PureInterpretor* pure = nullptr; + collections::Array ids; + collections::Array stateTokens; + RegexProc proc; + + public: + /// Create a lexical analyzer by a set of regular expressions. [F:vl.regex.RegexToken.token] will be the index of the matched regular expression. + /// The regular expressions. + /// Callback procedures. + RegexLexer(const collections::IEnumerable& tokens, RegexProc _proc); + ~RegexLexer(); + + /// Tokenize a input text. + /// The result. + /// The text to tokenize. + /// Extra information that will store in [F:vl.regex.RegexToken.codeIndex]. + RegexTokens Parse(const WString& code, vint codeIndex=-1)const; + /// Create a equivalence walker from this lexical analyzer. + /// The walker. + RegexLexerWalker Walk()const; + /// Create a equivalence colorizer from this lexical analyzer. + /// The colorizer. + RegexLexerColorizer Colorize()const; + }; + } +} + +#endif + /*********************************************************************** .\REGEXDATA.H ***********************************************************************/ @@ -548,454 +996,6 @@ Helper Functions #endif -/*********************************************************************** -.\REGEX.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -Regex::Regular Expression - -Classes: - RegexString : String Fragment - RegexMatch : Match Result - Regex : Regular Expression - RegexToken : Token - RegexTokens : Token Stream - RegexLexer : Tokenizer -***********************************************************************/ - -#ifndef VCZH_REGEX_REGEX -#define VCZH_REGEX_REGEX - - -namespace vl -{ - namespace regex_internal - { - class PureResult; - class PureInterpretor; - class RichResult; - class RichInterpretor; - } - - namespace regex - { - -/*********************************************************************** -Data Structure -***********************************************************************/ - - /// A type representing a fragment of the input string. - class RegexString : public Object - { - protected: - WString value; - vint start; - vint length; - - public: - RegexString(vint _start=0); - RegexString(const WString& _string, vint _start, vint _length); - - /// The position of the input string. - /// The position. - vint Start()const; - /// The size of the fragment in characters. - /// The size. - vint Length()const; - /// Get the fragment. - /// The fragment. - const WString& Value()const; - bool operator==(const RegexString& string)const; - }; - - /// A type representing a match of the input string. - class RegexMatch : public Object, private NotCopyable - { - friend class Regex; - public: - typedef Ptr Ref; - typedef collections::List List; - typedef collections::List CaptureList; - typedef collections::Group CaptureGroup; - protected: - collections::List captures; - collections::Group groups; - bool success; - RegexString result; - - RegexMatch(const WString& _string, regex_internal::PureResult* _result); - RegexMatch(const WString& _string, regex_internal::RichResult* _result, regex_internal::RichInterpretor* _rich); - RegexMatch(const RegexString& _result); - public: - - /// Test if this match is a success match or a failed match. A failed match will only appear when calling [M:vl.regex.Regex.Split] or [M:vl.regex.Regex.Cut]. In other cases, failed matches are either not included in the result, or become null pointers. - /// Returns true if this match is a success match. - bool Success()const; - /// Get the whole fragment that matches. - /// The whole fragment. - const RegexString& Result()const; - /// Get all fragments that are captured. - /// All fragments that are captured. - const CaptureList& Captures()const; - /// Get all fragments that are captured by named groups. - /// All fragments that are captured. - const CaptureGroup& Groups()const; - }; - -/*********************************************************************** -Regex -***********************************************************************/ - - /// , \^, \$, \!, \=: represents itself - /// Escaped characters in charset defined in a square bracket: - /// \r: the CR character - /// \n: the LF character - /// \t: the tab character - /// \-, \[, \], \\, \/, \^, \$: represents itself - /// 4) Loops: - /// regex{3}: repeats 3 times - /// regex{3,}: repeats 3 or more times - /// regex{1,3}: repeats 1 to 3 times - /// regex?: repeats 0 or 1 times - /// regex*: repeats 0 or more times - /// regex+: repeats 1 or more times - /// if you add a "?" right after a loop, it means repeating as less as possible (DFA incompatible) - /// 5) Capturing: (DFA incompatible) - /// (regex): No capturing, just change the operators' association - /// (?regex): Capture matched fragment - /// (regex): Capture matched fragment in a named group called "name" - /// (<$i>): Match the i-th captured fragment, begins from 0 - /// (<$name;i>): Match the i-th captured fragment in the named group called "name", begins from 0 - /// (<$name>): Match any captured fragment in the named group called "name" - /// 6) MISC - /// (=regex): The prefix of the following text should match the regex, but it is not counted in the whole match (DFA incompatible) - /// (!regex): Any prefix of the following text should not match the regex, and it is not counted in the whole match (DFA incompatible) - /// (<#name>regex): Name the regex "name", and it applies here - /// (<&name>): Copy the named regex "name" here and apply - /// ]]> - class Regex : public Object, private NotCopyable - { - protected: - regex_internal::PureInterpretor* pure; - regex_internal::RichInterpretor* rich; - - void Process(const WString& text, bool keepEmpty, bool keepSuccess, bool keepFail, RegexMatch::List& matches)const; - public: - /// Create a regular expression. - /// The regular expression in a string. - /// Set to true to tell the Regex to use DFA if possible. - Regex(const WString& code, bool preferPure=true); - ~Regex(); - - /// Test does the Regex uses DFA to match a string. - /// Returns true if DFA is used. - bool IsPureMatch()const; - /// Test does the Regex uses DFA to test a string. Test means ignoring all capturing requirements. - /// Returns true if DFA is used. - bool IsPureTest()const; - - /// Match a prefix of the text. - /// Returns the match. Returns null if failed. - /// The text to match. - RegexMatch::Ref MatchHead(const WString& text)const; - /// Match a fragment of the text. - /// Returns the match. Returns null if failed. - /// The text to match. - RegexMatch::Ref Match(const WString& text)const; - /// Match a prefix of the text, ignoring all capturing requirements. - /// Returns true if succeeded. - /// The text to match. - bool TestHead(const WString& text)const; - /// Match a fragment of the text, ignoring all capturing requirements. - /// Returns true if succeeded. - /// The text to match. - bool Test(const WString& text)const; - /// Find all matched fragments of the text, returning all matched fragments. - /// The text to match. - /// All successful matches. - void Search(const WString& text, RegexMatch::List& matches)const; - /// Split the text by matched fragments, returning all unmatched fragments. - /// The text to match. - /// Set to true to keep all empty matches. - /// All failed matches. - void Split(const WString& text, bool keepEmptyMatch, RegexMatch::List& matches)const; - /// Cut the text by matched fragments, returning all matched or unmatched fragments. - /// The text to match. - /// Set to true to keep all empty matches. - /// All successful and failed matches. - void Cut(const WString& text, bool keepEmptyMatch, RegexMatch::List& matches)const; - }; - -/*********************************************************************** -Tokenizer -***********************************************************************/ - - /// A token. - struct RegexToken - { - /// Position in the input string. - vint start; - /// Size of this token in characters. - vint length; - /// The token id, begins at 0, represents the regular expression in the list that matches this token. -1 means this token is produced by an error. - vint token; - /// The pointer to where this token starts in the input string . - const wchar_t* reading; - /// The argument value from [M:vl.regex.RegexLexer.Parse]. - vint codeIndex; - /// True if this token is complete. False if this token does not end here. - bool completeToken; - - /// Row number of the first character, begins at 0. - vint rowStart; - /// Column number of the first character, begins at 0. - vint columnStart; - /// Row number of the last character, begins at 0. - vint rowEnd; - /// Column number of the last character, begins at 0. - vint columnEnd; - - bool operator==(const RegexToken& _token)const; - bool operator==(const wchar_t* _token)const; - }; - - /// Token information for . - struct RegexProcessingToken - { - /// - /// The read only start position of the token. - /// This value will be -1 if is not null. - /// - const vint start; - /// - /// The length of the token, could be modified after the callback. - /// When the callback returns, the length is not allowed to be decreased. - /// This value will be -1 if is not null. - /// - vint length; - /// - /// The id of the token, could be modified after the callback. - /// - vint token; - /// - /// The flag indicating if this token is completed, could be modified after the callback. - /// - bool completeToken; - /// - /// The inter token state object, could be modified after the callback. - /// When the callback returns: - /// if the completeText parameter is true in , it should be nullptr. - /// if the token does not end at the end of the input, it should not be nullptr. - /// if a token is completed, it should be nullptr. - /// - void* interTokenState; - - RegexProcessingToken(vint _start, vint _length, vint _token, bool _completeToken, void* _interTokenState) - :start(_start) - , length(_length) - , token(_token) - , completeToken(_completeToken) - , interTokenState(_interTokenState) - { - } - }; - - using RegexInterTokenStateDeleter = void(*)(void* interTokenState); - using RegexTokenExtendProc = void(*)(void* argument, const wchar_t* reading, vint length, bool completeText, RegexProcessingToken& processingToken); - using RegexTokenColorizeProc = void(*)(void* argument, vint start, vint length, vint token); - - /// Callback procedures - struct RegexProc - { - /// - /// The deleter which deletes inter token state objects created by . This callback is not called automatically. - /// - RegexInterTokenStateDeleter deleter = nullptr; - /// - /// The token extend callback. It is called after recognizing any token, and run a customized procedure to modify the token based on the given context. - /// If the length parameter is -1, it means the caller does not measure the incoming text buffer, which automatically indicates that the buffer is null-terminated. - /// If the length parameter is not -1, it means the number of available characters in the buffer. - /// The completeText parameter could be true or false. When it is false, it means that the buffer does not contain all the text. - /// - RegexTokenExtendProc extendProc = nullptr; - /// - /// The colorizer callback. It is called when a token is recognized. - /// - RegexTokenColorizeProc colorizeProc = nullptr; - /// - /// The argument object that is the first argument for and . - /// - void* argument = nullptr; - }; - - /// Token collection representing the result from the lexical analyzer. - class RegexTokens : public Object, public collections::IEnumerable - { - friend class RegexLexer; - protected: - regex_internal::PureInterpretor* pure; - const collections::Array& stateTokens; - WString code; - vint codeIndex; - RegexProc proc; - - RegexTokens(regex_internal::PureInterpretor* _pure, const collections::Array& _stateTokens, const WString& _code, vint _codeIndex, RegexProc _proc); - public: - RegexTokens(const RegexTokens& tokens); - ~RegexTokens(); - - collections::IEnumerator* CreateEnumerator()const; - - /// Copy all tokens. - /// Returns all tokens. - /// A callback to decide which kind of tokens to discard. The input is [F:vl.regex.RegexToken.token]. Returns true to discard this kind of tokens. - void ReadToEnd(collections::List& tokens, bool(*discard)(vint)=0)const; - }; - - /// Lexical walker. - class RegexLexerWalker : public Object - { - friend class RegexLexer; - protected: - regex_internal::PureInterpretor* pure; - const collections::Array& stateTokens; - - RegexLexerWalker(regex_internal::PureInterpretor* _pure, const collections::Array& _stateTokens); - public: - RegexLexerWalker(const RegexLexerWalker& tokens); - ~RegexLexerWalker(); - - /// Get the start DFA state number, which represents the correct state before parsing any input. - /// The DFA state number. - vint GetStartState()const; - /// Test if this state can only lead to the end of one kind of token. - /// Returns the token index if this state can only lead to the end of one kind of token. Returns -1 if not. - /// The DFA state number. - vint GetRelatedToken(vint state)const; - /// Step forward by one character. - /// The input character. - /// The current state. Returns the new current state when this function returns. - /// Returns the token index at the end of the token. - /// Returns true if it reach the end of the token. - /// Returns true if the last character is the end of the token. - void Walk(wchar_t input, vint& state, vint& token, bool& finalState, bool& previousTokenStop)const; - /// Step forward by one character. - /// Returns the new current state. - /// The input character. - /// The current state. - vint Walk(wchar_t input, vint state)const; - /// Test if the input text is a complete token. - /// Returns true if the input text is a complete token. - /// The input text. - /// Size of the input text in characters. - bool IsClosedToken(const wchar_t* input, vint length)const; - /// Test if the input is a complete token. - /// Returns true if the input text is a complete token. - /// The input text. - bool IsClosedToken(const WString& input)const; - }; - - /// Lexical colorizer. - class RegexLexerColorizer : public Object - { - friend class RegexLexer; - public: - struct InternalState - { - vint currentState = -1; - vint interTokenId = -1; - void* interTokenState = nullptr; - }; - - protected: - RegexLexerWalker walker; - RegexProc proc; - InternalState internalState; - - void CallExtendProcAndColorizeProc(const wchar_t* input, vint length, RegexProcessingToken& token, bool colorize); - vint WalkOneToken(const wchar_t* input, vint length, vint start, bool colorize); - - RegexLexerColorizer(const RegexLexerWalker& _walker, RegexProc _proc); - public: - RegexLexerColorizer(const RegexLexerColorizer& colorizer); - ~RegexLexerColorizer(); - - /// Get the internal state. - /// The internal state. - InternalState GetInternalState(); - /// Restore the colorizer to a internal state. - /// The internal state. - void SetInternalState(InternalState state); - /// Step forward by one character. - /// The input character. - void Pass(wchar_t input); - /// Get the start DFA state number, which represents the correct state before colorizing any characters. - /// The DFA state number. - vint GetStartState()const; - /// Colorize a text. GetCurrentState()const; - /// An inter token state at the end of this line. It could be the same object which is returned from the previous call. - /// The text to colorize. - /// Size of the text in characters. - void* Colorize(const wchar_t* input, vint length); - }; - - /// Lexical analyzer. - class RegexLexer : public Object, private NotCopyable - { - protected: - regex_internal::PureInterpretor* pure = nullptr; - collections::Array ids; - collections::Array stateTokens; - RegexProc proc; - - public: - /// Create a lexical analyzer by a set of regular expressions. [F:vl.regex.RegexToken.token] will be the index of the matched regular expression. - /// The regular expressions. - /// Callback procedures. - RegexLexer(const collections::IEnumerable& tokens, RegexProc _proc); - ~RegexLexer(); - - /// Tokenize a input text. - /// The result. - /// The text to tokenize. - /// Extra information that will store in [F:vl.regex.RegexToken.codeIndex]. - RegexTokens Parse(const WString& code, vint codeIndex=-1)const; - /// Create a equivalence walker from this lexical analyzer. - /// The walker. - RegexLexerWalker Walk()const; - /// Create a equivalence colorizer from this lexical analyzer. - /// The colorizer. - RegexLexerColorizer Colorize()const; - }; - } -} - -#endif - /*********************************************************************** .\REGEXPURE.H ***********************************************************************/ diff --git a/Import/VlppWorkflowCompiler.cpp b/Import/VlppWorkflowCompiler.cpp index 10cbe536..fb714244 100644 --- a/Import/VlppWorkflowCompiler.cpp +++ b/Import/VlppWorkflowCompiler.cpp @@ -765,11 +765,11 @@ WfLexicalScopeManager stateMachineInfos.Clear(); } -#define CALLBACK(EXPR) if (callback) callback->EXPR +#define EXECUTE_CALLBACK(EXPR) if (callback) callback->EXPR void WfLexicalScopeManager::Rebuild(bool keepTypeDescriptorNames, IWfCompilerCallback* callback) { - CALLBACK(OnLoadEnvironment()); + EXECUTE_CALLBACK(OnLoadEnvironment()); Clear(keepTypeDescriptorNames, false); if (!globalName) { @@ -777,7 +777,7 @@ WfLexicalScopeManager BuildGlobalNameFromTypeDescriptors(this); } - CALLBACK(OnInitialize(this)); + EXECUTE_CALLBACK(OnInitialize(this)); vint errorCount = errors.Count(); #define EXIT_IF_ERRORS_EXIST\ @@ -813,14 +813,14 @@ WfLexicalScopeManager EXIT_IF_ERRORS_EXIST; FOREACH(Ptr, module, modules) { - CALLBACK(OnValidateModule(module)); + EXECUTE_CALLBACK(OnValidateModule(module)); ValidateModuleSemantic(this, module); } #undef EXIT_IF_ERRORS_EXIST } -#undef CALLBACK +#undef EXECUTE_CALLBACK bool WfLexicalScopeManager::ResolveMember(ITypeDescriptor* typeDescriptor, const WString& name, bool preferStatic, collections::SortedList& searchedTypes, collections::List& results) { @@ -24282,11 +24282,11 @@ GetInstructionTypeArgument GenerateAssembly ***********************************************************************/ -#define CALLBACK(EXPR) if (callback) callback->EXPR +#define EXECUTE_CALLBACK(EXPR) if (callback) callback->EXPR Ptr GenerateAssembly(analyzer::WfLexicalScopeManager* manager, IWfCompilerCallback* callback) { - CALLBACK(OnGenerateMetadata()); + EXECUTE_CALLBACK(OnGenerateMetadata()); auto assembly = MakePtr(); assembly->insBeforeCodegen = new WfInstructionDebugInfo; assembly->insAfterCodegen = new WfInstructionDebugInfo; @@ -24381,19 +24381,19 @@ GenerateAssembly FOREACH(Ptr, module, manager->GetModules()) { - CALLBACK(OnGenerateCode(module)); + EXECUTE_CALLBACK(OnGenerateCode(module)); FOREACH(Ptr, decl, module->declarations) { GenerateDeclarationInstructions(context, decl); } } - CALLBACK(OnGenerateDebugInfo()); + EXECUTE_CALLBACK(OnGenerateDebugInfo()); assembly->Initialize(); return assembly; } -#undef CALLBACK +#undef EXECUTE_CALLBACK #undef FILL_LABEL_TO_CURRENT #undef FILL_LABEL_TO_INS #undef INSTRUCTION diff --git a/Import/VlppWorkflowCompiler.h b/Import/VlppWorkflowCompiler.h index a11b1366..14cc7df2 100644 --- a/Import/VlppWorkflowCompiler.h +++ b/Import/VlppWorkflowCompiler.h @@ -2355,62 +2355,6 @@ namespace vl } #endif -/*********************************************************************** -.\EXPRESSION\WFEXPRESSION_PARSER.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -Parser::WfExpression.parser.txt - -This file is generated by: Vczh Parser Generator -***********************************************************************/ - -#ifndef VCZH_WORKFLOW_EXPRESSION_WFEXPRESSIONPARSER_PARSER -#define VCZH_WORKFLOW_EXPRESSION_WFEXPRESSIONPARSER_PARSER - - -namespace vl -{ - namespace workflow - { - extern vl::WString WfGetParserTextBuffer(); - extern vl::Ptr WfConvertParsingTreeNode(vl::Ptr node, const vl::collections::List& tokens); - extern vl::Ptr WfLoadTable(); - - extern vl::Ptr WfParseCoProviderStatementAsParsingTreeNode(const vl::WString& input, vl::Ptr table, vl::collections::List>& errors, vl::vint codeIndex = -1); - extern vl::Ptr WfParseCoProviderStatementAsParsingTreeNode(const vl::WString& input, vl::Ptr table, vl::vint codeIndex = -1); - extern vl::Ptr WfParseCoProviderStatement(const vl::WString& input, vl::Ptr table, vl::collections::List>& errors, vl::vint codeIndex = -1); - extern vl::Ptr WfParseCoProviderStatement(const vl::WString& input, vl::Ptr table, vl::vint codeIndex = -1); - - extern vl::Ptr WfParseDeclarationAsParsingTreeNode(const vl::WString& input, vl::Ptr table, vl::collections::List>& errors, vl::vint codeIndex = -1); - extern vl::Ptr WfParseDeclarationAsParsingTreeNode(const vl::WString& input, vl::Ptr table, vl::vint codeIndex = -1); - extern vl::Ptr WfParseDeclaration(const vl::WString& input, vl::Ptr table, vl::collections::List>& errors, vl::vint codeIndex = -1); - extern vl::Ptr WfParseDeclaration(const vl::WString& input, vl::Ptr table, vl::vint codeIndex = -1); - - extern vl::Ptr WfParseExpressionAsParsingTreeNode(const vl::WString& input, vl::Ptr table, vl::collections::List>& errors, vl::vint codeIndex = -1); - extern vl::Ptr WfParseExpressionAsParsingTreeNode(const vl::WString& input, vl::Ptr table, vl::vint codeIndex = -1); - extern vl::Ptr WfParseExpression(const vl::WString& input, vl::Ptr table, vl::collections::List>& errors, vl::vint codeIndex = -1); - extern vl::Ptr WfParseExpression(const vl::WString& input, vl::Ptr table, vl::vint codeIndex = -1); - - extern vl::Ptr WfParseModuleAsParsingTreeNode(const vl::WString& input, vl::Ptr table, vl::collections::List>& errors, vl::vint codeIndex = -1); - extern vl::Ptr WfParseModuleAsParsingTreeNode(const vl::WString& input, vl::Ptr table, vl::vint codeIndex = -1); - extern vl::Ptr WfParseModule(const vl::WString& input, vl::Ptr table, vl::collections::List>& errors, vl::vint codeIndex = -1); - extern vl::Ptr WfParseModule(const vl::WString& input, vl::Ptr table, vl::vint codeIndex = -1); - - extern vl::Ptr WfParseStatementAsParsingTreeNode(const vl::WString& input, vl::Ptr table, vl::collections::List>& errors, vl::vint codeIndex = -1); - extern vl::Ptr WfParseStatementAsParsingTreeNode(const vl::WString& input, vl::Ptr table, vl::vint codeIndex = -1); - extern vl::Ptr WfParseStatement(const vl::WString& input, vl::Ptr table, vl::collections::List>& errors, vl::vint codeIndex = -1); - extern vl::Ptr WfParseStatement(const vl::WString& input, vl::Ptr table, vl::vint codeIndex = -1); - - extern vl::Ptr WfParseTypeAsParsingTreeNode(const vl::WString& input, vl::Ptr table, vl::collections::List>& errors, vl::vint codeIndex = -1); - extern vl::Ptr WfParseTypeAsParsingTreeNode(const vl::WString& input, vl::Ptr table, vl::vint codeIndex = -1); - extern vl::Ptr WfParseType(const vl::WString& input, vl::Ptr table, vl::collections::List>& errors, vl::vint codeIndex = -1); - extern vl::Ptr WfParseType(const vl::WString& input, vl::Ptr table, vl::vint codeIndex = -1); - } -} -#endif - /*********************************************************************** .\EXPRESSION\WFEXPRESSION_COPY.H ***********************************************************************/ @@ -2913,6 +2857,273 @@ namespace vl } #endif +/*********************************************************************** +.\EXPRESSION\WFEXPRESSION_EMPTY.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +Parser::WfExpression.parser.txt + +This file is generated by: Vczh Parser Generator +***********************************************************************/ + +#ifndef VCZH_WORKFLOW_EXPRESSION_WFEXPRESSIONPARSER_EMPTY +#define VCZH_WORKFLOW_EXPRESSION_WFEXPRESSIONPARSER_EMPTY + + +namespace vl +{ + namespace workflow + { + namespace empty_visitor + { + class TypeVisitor : public Object, public WfType::IVisitor + { + public: + + // Visitor Members ----------------------------------- + void Visit(WfPredefinedType* node)override; + void Visit(WfTopQualifiedType* node)override; + void Visit(WfReferenceType* node)override; + void Visit(WfRawPointerType* node)override; + void Visit(WfSharedPointerType* node)override; + void Visit(WfNullableType* node)override; + void Visit(WfEnumerableType* node)override; + void Visit(WfMapType* node)override; + void Visit(WfObservableListType* node)override; + void Visit(WfFunctionType* node)override; + void Visit(WfChildType* node)override; + }; + + class ExpressionVisitor : public Object, public WfExpression::IVisitor + { + public: + + // Dispatch (virtual) -------------------------------- + virtual void Dispatch(WfVirtualCfeExpression* node) = 0; + virtual void Dispatch(WfVirtualCseExpression* node) = 0; + + // Visitor Members ----------------------------------- + void Visit(WfThisExpression* node)override; + void Visit(WfTopQualifiedExpression* node)override; + void Visit(WfReferenceExpression* node)override; + void Visit(WfOrderedNameExpression* node)override; + void Visit(WfOrderedLambdaExpression* node)override; + void Visit(WfMemberExpression* node)override; + void Visit(WfChildExpression* node)override; + void Visit(WfLiteralExpression* node)override; + void Visit(WfFloatingExpression* node)override; + void Visit(WfIntegerExpression* node)override; + void Visit(WfStringExpression* node)override; + void Visit(WfUnaryExpression* node)override; + void Visit(WfBinaryExpression* node)override; + void Visit(WfLetExpression* node)override; + void Visit(WfIfExpression* node)override; + void Visit(WfRangeExpression* node)override; + void Visit(WfSetTestingExpression* node)override; + void Visit(WfConstructorExpression* node)override; + void Visit(WfInferExpression* node)override; + void Visit(WfTypeCastingExpression* node)override; + void Visit(WfTypeTestingExpression* node)override; + void Visit(WfTypeOfTypeExpression* node)override; + void Visit(WfTypeOfExpressionExpression* node)override; + void Visit(WfAttachEventExpression* node)override; + void Visit(WfDetachEventExpression* node)override; + void Visit(WfObserveExpression* node)override; + void Visit(WfCallExpression* node)override; + void Visit(WfFunctionExpression* node)override; + void Visit(WfNewClassExpression* node)override; + void Visit(WfNewInterfaceExpression* node)override; + void Visit(WfVirtualCfeExpression* node)override; + void Visit(WfVirtualCseExpression* node)override; + }; + + class StatementVisitor : public Object, public WfStatement::IVisitor + { + public: + + // Dispatch (virtual) -------------------------------- + virtual void Dispatch(WfVirtualCseStatement* node) = 0; + virtual void Dispatch(WfCoroutineStatement* node) = 0; + virtual void Dispatch(WfStateMachineStatement* node) = 0; + + // Visitor Members ----------------------------------- + void Visit(WfBreakStatement* node)override; + void Visit(WfContinueStatement* node)override; + void Visit(WfReturnStatement* node)override; + void Visit(WfDeleteStatement* node)override; + void Visit(WfRaiseExceptionStatement* node)override; + void Visit(WfIfStatement* node)override; + void Visit(WfWhileStatement* node)override; + void Visit(WfTryStatement* node)override; + void Visit(WfBlockStatement* node)override; + void Visit(WfGotoStatement* node)override; + void Visit(WfVariableStatement* node)override; + void Visit(WfExpressionStatement* node)override; + void Visit(WfVirtualCseStatement* node)override; + void Visit(WfCoroutineStatement* node)override; + void Visit(WfStateMachineStatement* node)override; + }; + + class DeclarationVisitor : public Object, public WfDeclaration::IVisitor + { + public: + + // Dispatch (virtual) -------------------------------- + virtual void Dispatch(WfVirtualCfeDeclaration* node) = 0; + virtual void Dispatch(WfVirtualCseDeclaration* node) = 0; + + // Visitor Members ----------------------------------- + void Visit(WfNamespaceDeclaration* node)override; + void Visit(WfFunctionDeclaration* node)override; + void Visit(WfVariableDeclaration* node)override; + void Visit(WfEventDeclaration* node)override; + void Visit(WfPropertyDeclaration* node)override; + void Visit(WfConstructorDeclaration* node)override; + void Visit(WfDestructorDeclaration* node)override; + void Visit(WfClassDeclaration* node)override; + void Visit(WfEnumDeclaration* node)override; + void Visit(WfStructDeclaration* node)override; + void Visit(WfVirtualCfeDeclaration* node)override; + void Visit(WfVirtualCseDeclaration* node)override; + }; + + class VirtualCfeDeclarationVisitor : public Object, public WfVirtualCfeDeclaration::IVisitor + { + public: + + // Visitor Members ----------------------------------- + void Visit(WfAutoPropertyDeclaration* node)override; + void Visit(WfCastResultInterfaceDeclaration* node)override; + }; + + class VirtualCseDeclarationVisitor : public Object, public WfVirtualCseDeclaration::IVisitor + { + public: + + // Visitor Members ----------------------------------- + void Visit(WfStateMachineDeclaration* node)override; + }; + + class VirtualCseStatementVisitor : public Object, public WfVirtualCseStatement::IVisitor + { + public: + + // Visitor Members ----------------------------------- + void Visit(WfForEachStatement* node)override; + void Visit(WfSwitchStatement* node)override; + void Visit(WfCoProviderStatement* node)override; + }; + + class CoroutineStatementVisitor : public Object, public WfCoroutineStatement::IVisitor + { + public: + + // Visitor Members ----------------------------------- + void Visit(WfCoPauseStatement* node)override; + void Visit(WfCoOperatorStatement* node)override; + }; + + class StateMachineStatementVisitor : public Object, public WfStateMachineStatement::IVisitor + { + public: + + // Visitor Members ----------------------------------- + void Visit(WfStateSwitchStatement* node)override; + void Visit(WfStateInvokeStatement* node)override; + }; + + class VirtualCfeExpressionVisitor : public Object, public WfVirtualCfeExpression::IVisitor + { + public: + + // Visitor Members ----------------------------------- + void Visit(WfFormatExpression* node)override; + }; + + class VirtualCseExpressionVisitor : public Object, public WfVirtualCseExpression::IVisitor + { + public: + + // Visitor Members ----------------------------------- + void Visit(WfBindExpression* node)override; + void Visit(WfNewCoroutineExpression* node)override; + void Visit(WfMixinCastExpression* node)override; + void Visit(WfExpectedTypeCastExpression* node)override; + void Visit(WfCoOperatorExpression* node)override; + }; + + class ModuleUsingFragmentVisitor : public Object, public WfModuleUsingFragment::IVisitor + { + public: + + // Visitor Members ----------------------------------- + void Visit(WfModuleUsingNameFragment* node)override; + void Visit(WfModuleUsingWildCardFragment* node)override; + }; + + } + } +} +#endif + +/*********************************************************************** +.\EXPRESSION\WFEXPRESSION_PARSER.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +Parser::WfExpression.parser.txt + +This file is generated by: Vczh Parser Generator +***********************************************************************/ + +#ifndef VCZH_WORKFLOW_EXPRESSION_WFEXPRESSIONPARSER_PARSER +#define VCZH_WORKFLOW_EXPRESSION_WFEXPRESSIONPARSER_PARSER + + +namespace vl +{ + namespace workflow + { + extern vl::WString WfGetParserTextBuffer(); + extern vl::Ptr WfConvertParsingTreeNode(vl::Ptr node, const vl::collections::List& tokens); + extern vl::Ptr WfLoadTable(); + + extern vl::Ptr WfParseCoProviderStatementAsParsingTreeNode(const vl::WString& input, vl::Ptr table, vl::collections::List>& errors, vl::vint codeIndex = -1); + extern vl::Ptr WfParseCoProviderStatementAsParsingTreeNode(const vl::WString& input, vl::Ptr table, vl::vint codeIndex = -1); + extern vl::Ptr WfParseCoProviderStatement(const vl::WString& input, vl::Ptr table, vl::collections::List>& errors, vl::vint codeIndex = -1); + extern vl::Ptr WfParseCoProviderStatement(const vl::WString& input, vl::Ptr table, vl::vint codeIndex = -1); + + extern vl::Ptr WfParseDeclarationAsParsingTreeNode(const vl::WString& input, vl::Ptr table, vl::collections::List>& errors, vl::vint codeIndex = -1); + extern vl::Ptr WfParseDeclarationAsParsingTreeNode(const vl::WString& input, vl::Ptr table, vl::vint codeIndex = -1); + extern vl::Ptr WfParseDeclaration(const vl::WString& input, vl::Ptr table, vl::collections::List>& errors, vl::vint codeIndex = -1); + extern vl::Ptr WfParseDeclaration(const vl::WString& input, vl::Ptr table, vl::vint codeIndex = -1); + + extern vl::Ptr WfParseExpressionAsParsingTreeNode(const vl::WString& input, vl::Ptr table, vl::collections::List>& errors, vl::vint codeIndex = -1); + extern vl::Ptr WfParseExpressionAsParsingTreeNode(const vl::WString& input, vl::Ptr table, vl::vint codeIndex = -1); + extern vl::Ptr WfParseExpression(const vl::WString& input, vl::Ptr table, vl::collections::List>& errors, vl::vint codeIndex = -1); + extern vl::Ptr WfParseExpression(const vl::WString& input, vl::Ptr table, vl::vint codeIndex = -1); + + extern vl::Ptr WfParseModuleAsParsingTreeNode(const vl::WString& input, vl::Ptr table, vl::collections::List>& errors, vl::vint codeIndex = -1); + extern vl::Ptr WfParseModuleAsParsingTreeNode(const vl::WString& input, vl::Ptr table, vl::vint codeIndex = -1); + extern vl::Ptr WfParseModule(const vl::WString& input, vl::Ptr table, vl::collections::List>& errors, vl::vint codeIndex = -1); + extern vl::Ptr WfParseModule(const vl::WString& input, vl::Ptr table, vl::vint codeIndex = -1); + + extern vl::Ptr WfParseStatementAsParsingTreeNode(const vl::WString& input, vl::Ptr table, vl::collections::List>& errors, vl::vint codeIndex = -1); + extern vl::Ptr WfParseStatementAsParsingTreeNode(const vl::WString& input, vl::Ptr table, vl::vint codeIndex = -1); + extern vl::Ptr WfParseStatement(const vl::WString& input, vl::Ptr table, vl::collections::List>& errors, vl::vint codeIndex = -1); + extern vl::Ptr WfParseStatement(const vl::WString& input, vl::Ptr table, vl::vint codeIndex = -1); + + extern vl::Ptr WfParseTypeAsParsingTreeNode(const vl::WString& input, vl::Ptr table, vl::collections::List>& errors, vl::vint codeIndex = -1); + extern vl::Ptr WfParseTypeAsParsingTreeNode(const vl::WString& input, vl::Ptr table, vl::vint codeIndex = -1); + extern vl::Ptr WfParseType(const vl::WString& input, vl::Ptr table, vl::collections::List>& errors, vl::vint codeIndex = -1); + extern vl::Ptr WfParseType(const vl::WString& input, vl::Ptr table, vl::vint codeIndex = -1); + } +} +#endif + /*********************************************************************** .\EXPRESSION\WFEXPRESSION_TRAVERSE.H ***********************************************************************/ @@ -3435,217 +3646,6 @@ namespace vl } #endif -/*********************************************************************** -.\EXPRESSION\WFEXPRESSION_EMPTY.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -Parser::WfExpression.parser.txt - -This file is generated by: Vczh Parser Generator -***********************************************************************/ - -#ifndef VCZH_WORKFLOW_EXPRESSION_WFEXPRESSIONPARSER_EMPTY -#define VCZH_WORKFLOW_EXPRESSION_WFEXPRESSIONPARSER_EMPTY - - -namespace vl -{ - namespace workflow - { - namespace empty_visitor - { - class TypeVisitor : public Object, public WfType::IVisitor - { - public: - - // Visitor Members ----------------------------------- - void Visit(WfPredefinedType* node)override; - void Visit(WfTopQualifiedType* node)override; - void Visit(WfReferenceType* node)override; - void Visit(WfRawPointerType* node)override; - void Visit(WfSharedPointerType* node)override; - void Visit(WfNullableType* node)override; - void Visit(WfEnumerableType* node)override; - void Visit(WfMapType* node)override; - void Visit(WfObservableListType* node)override; - void Visit(WfFunctionType* node)override; - void Visit(WfChildType* node)override; - }; - - class ExpressionVisitor : public Object, public WfExpression::IVisitor - { - public: - - // Dispatch (virtual) -------------------------------- - virtual void Dispatch(WfVirtualCfeExpression* node) = 0; - virtual void Dispatch(WfVirtualCseExpression* node) = 0; - - // Visitor Members ----------------------------------- - void Visit(WfThisExpression* node)override; - void Visit(WfTopQualifiedExpression* node)override; - void Visit(WfReferenceExpression* node)override; - void Visit(WfOrderedNameExpression* node)override; - void Visit(WfOrderedLambdaExpression* node)override; - void Visit(WfMemberExpression* node)override; - void Visit(WfChildExpression* node)override; - void Visit(WfLiteralExpression* node)override; - void Visit(WfFloatingExpression* node)override; - void Visit(WfIntegerExpression* node)override; - void Visit(WfStringExpression* node)override; - void Visit(WfUnaryExpression* node)override; - void Visit(WfBinaryExpression* node)override; - void Visit(WfLetExpression* node)override; - void Visit(WfIfExpression* node)override; - void Visit(WfRangeExpression* node)override; - void Visit(WfSetTestingExpression* node)override; - void Visit(WfConstructorExpression* node)override; - void Visit(WfInferExpression* node)override; - void Visit(WfTypeCastingExpression* node)override; - void Visit(WfTypeTestingExpression* node)override; - void Visit(WfTypeOfTypeExpression* node)override; - void Visit(WfTypeOfExpressionExpression* node)override; - void Visit(WfAttachEventExpression* node)override; - void Visit(WfDetachEventExpression* node)override; - void Visit(WfObserveExpression* node)override; - void Visit(WfCallExpression* node)override; - void Visit(WfFunctionExpression* node)override; - void Visit(WfNewClassExpression* node)override; - void Visit(WfNewInterfaceExpression* node)override; - void Visit(WfVirtualCfeExpression* node)override; - void Visit(WfVirtualCseExpression* node)override; - }; - - class StatementVisitor : public Object, public WfStatement::IVisitor - { - public: - - // Dispatch (virtual) -------------------------------- - virtual void Dispatch(WfVirtualCseStatement* node) = 0; - virtual void Dispatch(WfCoroutineStatement* node) = 0; - virtual void Dispatch(WfStateMachineStatement* node) = 0; - - // Visitor Members ----------------------------------- - void Visit(WfBreakStatement* node)override; - void Visit(WfContinueStatement* node)override; - void Visit(WfReturnStatement* node)override; - void Visit(WfDeleteStatement* node)override; - void Visit(WfRaiseExceptionStatement* node)override; - void Visit(WfIfStatement* node)override; - void Visit(WfWhileStatement* node)override; - void Visit(WfTryStatement* node)override; - void Visit(WfBlockStatement* node)override; - void Visit(WfGotoStatement* node)override; - void Visit(WfVariableStatement* node)override; - void Visit(WfExpressionStatement* node)override; - void Visit(WfVirtualCseStatement* node)override; - void Visit(WfCoroutineStatement* node)override; - void Visit(WfStateMachineStatement* node)override; - }; - - class DeclarationVisitor : public Object, public WfDeclaration::IVisitor - { - public: - - // Dispatch (virtual) -------------------------------- - virtual void Dispatch(WfVirtualCfeDeclaration* node) = 0; - virtual void Dispatch(WfVirtualCseDeclaration* node) = 0; - - // Visitor Members ----------------------------------- - void Visit(WfNamespaceDeclaration* node)override; - void Visit(WfFunctionDeclaration* node)override; - void Visit(WfVariableDeclaration* node)override; - void Visit(WfEventDeclaration* node)override; - void Visit(WfPropertyDeclaration* node)override; - void Visit(WfConstructorDeclaration* node)override; - void Visit(WfDestructorDeclaration* node)override; - void Visit(WfClassDeclaration* node)override; - void Visit(WfEnumDeclaration* node)override; - void Visit(WfStructDeclaration* node)override; - void Visit(WfVirtualCfeDeclaration* node)override; - void Visit(WfVirtualCseDeclaration* node)override; - }; - - class VirtualCfeDeclarationVisitor : public Object, public WfVirtualCfeDeclaration::IVisitor - { - public: - - // Visitor Members ----------------------------------- - void Visit(WfAutoPropertyDeclaration* node)override; - void Visit(WfCastResultInterfaceDeclaration* node)override; - }; - - class VirtualCseDeclarationVisitor : public Object, public WfVirtualCseDeclaration::IVisitor - { - public: - - // Visitor Members ----------------------------------- - void Visit(WfStateMachineDeclaration* node)override; - }; - - class VirtualCseStatementVisitor : public Object, public WfVirtualCseStatement::IVisitor - { - public: - - // Visitor Members ----------------------------------- - void Visit(WfForEachStatement* node)override; - void Visit(WfSwitchStatement* node)override; - void Visit(WfCoProviderStatement* node)override; - }; - - class CoroutineStatementVisitor : public Object, public WfCoroutineStatement::IVisitor - { - public: - - // Visitor Members ----------------------------------- - void Visit(WfCoPauseStatement* node)override; - void Visit(WfCoOperatorStatement* node)override; - }; - - class StateMachineStatementVisitor : public Object, public WfStateMachineStatement::IVisitor - { - public: - - // Visitor Members ----------------------------------- - void Visit(WfStateSwitchStatement* node)override; - void Visit(WfStateInvokeStatement* node)override; - }; - - class VirtualCfeExpressionVisitor : public Object, public WfVirtualCfeExpression::IVisitor - { - public: - - // Visitor Members ----------------------------------- - void Visit(WfFormatExpression* node)override; - }; - - class VirtualCseExpressionVisitor : public Object, public WfVirtualCseExpression::IVisitor - { - public: - - // Visitor Members ----------------------------------- - void Visit(WfBindExpression* node)override; - void Visit(WfNewCoroutineExpression* node)override; - void Visit(WfMixinCastExpression* node)override; - void Visit(WfExpectedTypeCastExpression* node)override; - void Visit(WfCoOperatorExpression* node)override; - }; - - class ModuleUsingFragmentVisitor : public Object, public WfModuleUsingFragment::IVisitor - { - public: - - // Visitor Members ----------------------------------- - void Visit(WfModuleUsingNameFragment* node)override; - void Visit(WfModuleUsingWildCardFragment* node)override; - }; - - } - } -} -#endif - /*********************************************************************** .\EXPRESSION\WFEXPRESSION.H ***********************************************************************/ diff --git a/Import/VlppWorkflowLibrary.h b/Import/VlppWorkflowLibrary.h index 28c7b07a..7545f913 100644 --- a/Import/VlppWorkflowLibrary.h +++ b/Import/VlppWorkflowLibrary.h @@ -7,6 +7,362 @@ DEVELOPER: Zihan Chen(vczh) #include "Vlpp.h" #include "VlppRegex.h" +/*********************************************************************** +.\WFLIBRARYCPPHELPER.H +***********************************************************************/ +/*********************************************************************** +Vczh Library++ 3.0 +Developer: Zihan Chen(vczh) +Framework::Reflection + +Interfaces: +***********************************************************************/ + +#ifndef VCZH_WORKFLOW_LIBRARY_CPPLIBRARY +#define VCZH_WORKFLOW_LIBRARY_CPPLIBRARY + + +namespace vl +{ + namespace __vwsn + { + template + struct RunOnExit + { + T* function; + + RunOnExit(T* _function) + :function(_function) + { + } + + ~RunOnExit() + { + function->operator()(); + } + }; + + template + T* This(T* thisValue) + { + CHECK_ERROR(thisValue != nullptr, L"The this pointer cannot be null."); + return thisValue; + } + + template + T* Ensure(T* pointer) + { + CHECK_ERROR(pointer != nullptr, L"The pointer cannot be null."); + return pointer; + } + + template + Ptr& Ensure(Ptr& pointer) + { + CHECK_ERROR(pointer != nullptr, L"The pointer cannot be null."); + return pointer; + } + + template + Ptr Ensure(Ptr&& pointer) + { + CHECK_ERROR(pointer != nullptr, L"The pointer cannot be null."); + return MoveValue(pointer); + } + + template + Nullable Ensure(Nullable&& nullable) + { + CHECK_ERROR(nullable, L"The pointer cannot be null."); + return MoveValue(nullable); + } + + template + Nullable& Ensure(Nullable& nullable) + { + CHECK_ERROR(nullable, L"The pointer cannot be null."); + return nullable; + } + + template + WString ToString(const T& value) + { + using Type = typename RemoveCVR::Type; + WString str; + CHECK_ERROR(reflection::description::TypedValueSerializerProvider::Serialize(value, str), L"Failed to serialize."); + return str; + } + + template + T Parse(const WString& str) + { + using Type = typename RemoveCVR::Type; + T value; + CHECK_ERROR(reflection::description::TypedValueSerializerProvider::Deserialize(str, value), L"Failed to serialize."); + return value; + } + + template + struct NullableCastHelper + { + static Nullable Cast(Nullable nullable) + { + return Nullable(static_cast(nullable.Value())); + } + }; + + template + struct NullableCastHelper + { + static Nullable Cast(Nullable nullable) + { + return Nullable(ToString(nullable.Value())); + } + }; + + template + struct NullableCastHelper + { + static Nullable Cast(Nullable nullable) + { + return Nullable(Parse(nullable.Value())); + } + }; + + template + Nullable NullableCast(Nullable nullable) + { + if (!nullable) return Nullable(); + return NullableCastHelper::Cast(nullable); + } + + template + TTo* RawPtrCast(TFrom* pointer) + { + if (!pointer) return nullptr; + return pointer->template SafeAggregationCast(); + } + + template + Ptr SharedPtrCast(TFrom* pointer) + { + if (!pointer) return nullptr; + return pointer->template SafeAggregationCast(); + } + + template + reflection::description::Value Box(const T& value) + { + using Type = typename RemoveCVR::Type; + return reflection::description::BoxParameter(const_cast(value)); + } + + template + T Unbox(const reflection::description::Value& value) + { + using Type = typename RemoveCVR::Type; + T result; + reflection::description::UnboxParameter(value, result); + return result; + } + + template + struct UnboxWeakHelper + { + }; + + template + struct UnboxWeakHelper + { + static T* Unbox(const reflection::description::Value& value) + { + if (value.IsNull()) return nullptr; + return value.GetRawPtr()->SafeAggregationCast(); + } + }; + + template + struct UnboxWeakHelper> + { + static Ptr Unbox(const reflection::description::Value& value) + { + if (value.IsNull()) return nullptr; + return value.GetRawPtr()->SafeAggregationCast(); + } + }; + + template + struct UnboxWeakHelper> + { + static Nullable Unbox(const reflection::description::Value& value) + { + if (value.IsNull()) return Nullable(); + auto boxed = value.GetBoxedValue().Cast>(); + if (!boxed) return Nullable(); + return Nullable(boxed->value); + } + }; + + template + T UnboxWeak(const reflection::description::Value& value) + { + using Type = typename RemoveCVR::Type; + return UnboxWeakHelper::Unbox(value); + } + + template + collections::LazyList Range(T begin, T end) + { + return collections::Range(begin, end - begin); + } + + template + bool InSet(const T& value, const collections::LazyList& collection) + { + return collection.Any([&](const T& element) {return element == value; }); + } + + template + bool InSet(const T& value, Ptr collection) + { + return InSet(value, reflection::description::GetLazyList(collection)); + } + + template + Ptr UnboxCollection(const U& value) + { + auto boxedValue = reflection::description::BoxParameter(const_cast(value)); + Ptr result; + reflection::description::UnboxParameter>(boxedValue, result); + return result; + } + + template + Ptr UnboxCollection(const collections::LazyList& value) + { + auto boxedValue = reflection::description::BoxParameter>(const_cast&>(value)); + Ptr result; + reflection::description::UnboxParameter>(boxedValue, result); + return result; + } + + struct CreateList + { + using IValueList = reflection::description::IValueList; + + Ptr list; + + CreateList(); + CreateList(Ptr _list); + + template + CreateList Add(const T& value) + { + list->Add(Box(value)); + return{ list }; + } + }; + + struct CreateObservableList + { + using IValueObservableList = reflection::description::IValueObservableList; + + Ptr list; + + CreateObservableList(); + CreateObservableList(Ptr _list); + + template + CreateObservableList Add(const T& value) + { + list->Add(Box(value)); + return{ list }; + } + }; + + struct CreateDictionary + { + using IValueDictionary = reflection::description::IValueDictionary; + + Ptr dictionary; + + CreateDictionary(); + CreateDictionary(Ptr _dictionary); + + template + CreateDictionary Add(const K& key, const V& value) + { + dictionary->Set(Box(key), Box(value)); + return{ dictionary }; + } + }; + + template + struct EventHelper + { + }; + + template + Ptr EventAttach(T& e, typename EventHelper::Handler handler) + { + return EventHelper::Attach(e, handler); + } + + template + bool EventDetach(T& e, Ptr handler) + { + return EventHelper::Detach(e, handler); + } + + template + decltype(auto) EventInvoke(T& e) + { + return EventHelper::Invoke(e); + } + + template + struct EventHelper> + { + using Handler = const Func&; + + class EventHandlerImpl : public Object, public reflection::description::IEventHandler + { + public: + Ptr handler; + + EventHandlerImpl(Ptr _handler) + :handler(_handler) + { + } + + bool IsAttached()override + { + return handler->IsAttached(); + } + }; + + static Ptr Attach(Event& e, Handler handler) + { + return MakePtr(e.Add(handler)); + } + + static bool Detach(Event& e, Ptr handler) + { + auto impl = handler.Cast(); + if (!impl) return false; + return e.Remove(impl->handler); + } + + static Event& Invoke(Event& e) + { + return e; + } + }; + } +} + +#endif + /*********************************************************************** .\WFLIBRARYPREDEFINED.H ***********************************************************************/ @@ -418,359 +774,3 @@ LoadPredefinedTypes #endif - -/*********************************************************************** -.\WFLIBRARYCPPHELPER.H -***********************************************************************/ -/*********************************************************************** -Vczh Library++ 3.0 -Developer: Zihan Chen(vczh) -Framework::Reflection - -Interfaces: -***********************************************************************/ - -#ifndef VCZH_WORKFLOW_LIBRARY_CPPLIBRARY -#define VCZH_WORKFLOW_LIBRARY_CPPLIBRARY - - -namespace vl -{ - namespace __vwsn - { - template - struct RunOnExit - { - T* function; - - RunOnExit(T* _function) - :function(_function) - { - } - - ~RunOnExit() - { - function->operator()(); - } - }; - - template - T* This(T* thisValue) - { - CHECK_ERROR(thisValue != nullptr, L"The this pointer cannot be null."); - return thisValue; - } - - template - T* Ensure(T* pointer) - { - CHECK_ERROR(pointer != nullptr, L"The pointer cannot be null."); - return pointer; - } - - template - Ptr& Ensure(Ptr& pointer) - { - CHECK_ERROR(pointer != nullptr, L"The pointer cannot be null."); - return pointer; - } - - template - Ptr Ensure(Ptr&& pointer) - { - CHECK_ERROR(pointer != nullptr, L"The pointer cannot be null."); - return MoveValue(pointer); - } - - template - Nullable Ensure(Nullable&& nullable) - { - CHECK_ERROR(nullable, L"The pointer cannot be null."); - return MoveValue(nullable); - } - - template - Nullable& Ensure(Nullable& nullable) - { - CHECK_ERROR(nullable, L"The pointer cannot be null."); - return nullable; - } - - template - WString ToString(const T& value) - { - using Type = typename RemoveCVR::Type; - WString str; - CHECK_ERROR(reflection::description::TypedValueSerializerProvider::Serialize(value, str), L"Failed to serialize."); - return str; - } - - template - T Parse(const WString& str) - { - using Type = typename RemoveCVR::Type; - T value; - CHECK_ERROR(reflection::description::TypedValueSerializerProvider::Deserialize(str, value), L"Failed to serialize."); - return value; - } - - template - struct NullableCastHelper - { - static Nullable Cast(Nullable nullable) - { - return Nullable(static_cast(nullable.Value())); - } - }; - - template - struct NullableCastHelper - { - static Nullable Cast(Nullable nullable) - { - return Nullable(ToString(nullable.Value())); - } - }; - - template - struct NullableCastHelper - { - static Nullable Cast(Nullable nullable) - { - return Nullable(Parse(nullable.Value())); - } - }; - - template - Nullable NullableCast(Nullable nullable) - { - if (!nullable) return Nullable(); - return NullableCastHelper::Cast(nullable); - } - - template - TTo* RawPtrCast(TFrom* pointer) - { - if (!pointer) return nullptr; - return pointer->template SafeAggregationCast(); - } - - template - Ptr SharedPtrCast(TFrom* pointer) - { - if (!pointer) return nullptr; - return pointer->template SafeAggregationCast(); - } - - template - reflection::description::Value Box(const T& value) - { - using Type = typename RemoveCVR::Type; - return reflection::description::BoxParameter(const_cast(value)); - } - - template - T Unbox(const reflection::description::Value& value) - { - using Type = typename RemoveCVR::Type; - T result; - reflection::description::UnboxParameter(value, result); - return result; - } - - template - struct UnboxWeakHelper - { - }; - - template - struct UnboxWeakHelper - { - static T* Unbox(const reflection::description::Value& value) - { - if (value.IsNull()) return nullptr; - return value.GetRawPtr()->SafeAggregationCast(); - } - }; - - template - struct UnboxWeakHelper> - { - static Ptr Unbox(const reflection::description::Value& value) - { - if (value.IsNull()) return nullptr; - return value.GetRawPtr()->SafeAggregationCast(); - } - }; - - template - struct UnboxWeakHelper> - { - static Nullable Unbox(const reflection::description::Value& value) - { - if (value.IsNull()) return Nullable(); - auto boxed = value.GetBoxedValue().Cast>(); - if (!boxed) return Nullable(); - return Nullable(boxed->value); - } - }; - - template - T UnboxWeak(const reflection::description::Value& value) - { - using Type = typename RemoveCVR::Type; - return UnboxWeakHelper::Unbox(value); - } - - template - collections::LazyList Range(T begin, T end) - { - return collections::Range(begin, end - begin); - } - - template - bool InSet(const T& value, const collections::LazyList& collection) - { - return collection.Any([&](const T& element) {return element == value; }); - } - - template - bool InSet(const T& value, Ptr collection) - { - return InSet(value, reflection::description::GetLazyList(collection)); - } - - template - Ptr UnboxCollection(const U& value) - { - auto boxedValue = reflection::description::BoxParameter(const_cast(value)); - Ptr result; - reflection::description::UnboxParameter>(boxedValue, result); - return result; - } - - template - Ptr UnboxCollection(const collections::LazyList& value) - { - auto boxedValue = reflection::description::BoxParameter>(const_cast&>(value)); - Ptr result; - reflection::description::UnboxParameter>(boxedValue, result); - return result; - } - - struct CreateList - { - using IValueList = reflection::description::IValueList; - - Ptr list; - - CreateList(); - CreateList(Ptr _list); - - template - CreateList Add(const T& value) - { - list->Add(Box(value)); - return{ list }; - } - }; - - struct CreateObservableList - { - using IValueObservableList = reflection::description::IValueObservableList; - - Ptr list; - - CreateObservableList(); - CreateObservableList(Ptr _list); - - template - CreateObservableList Add(const T& value) - { - list->Add(Box(value)); - return{ list }; - } - }; - - struct CreateDictionary - { - using IValueDictionary = reflection::description::IValueDictionary; - - Ptr dictionary; - - CreateDictionary(); - CreateDictionary(Ptr _dictionary); - - template - CreateDictionary Add(const K& key, const V& value) - { - dictionary->Set(Box(key), Box(value)); - return{ dictionary }; - } - }; - - template - struct EventHelper - { - }; - - template - Ptr EventAttach(T& e, typename EventHelper::Handler handler) - { - return EventHelper::Attach(e, handler); - } - - template - bool EventDetach(T& e, Ptr handler) - { - return EventHelper::Detach(e, handler); - } - - template - decltype(auto) EventInvoke(T& e) - { - return EventHelper::Invoke(e); - } - - template - struct EventHelper> - { - using Handler = const Func&; - - class EventHandlerImpl : public Object, public reflection::description::IEventHandler - { - public: - Ptr handler; - - EventHandlerImpl(Ptr _handler) - :handler(_handler) - { - } - - bool IsAttached()override - { - return handler->IsAttached(); - } - }; - - static Ptr Attach(Event& e, Handler handler) - { - return MakePtr(e.Add(handler)); - } - - static bool Detach(Event& e, Ptr handler) - { - auto impl = handler.Cast(); - if (!impl) return false; - return e.Remove(impl->handler); - } - - static Event& Invoke(Event& e) - { - return e; - } - }; - } -} - -#endif diff --git a/Tools/CppMerge.exe b/Tools/CppMerge.exe index c4713320..546234df 100644 Binary files a/Tools/CppMerge.exe and b/Tools/CppMerge.exe differ diff --git a/Tools/GacGen32.exe b/Tools/GacGen32.exe index a210e6d1..c064797e 100644 Binary files a/Tools/GacGen32.exe and b/Tools/GacGen32.exe differ diff --git a/Tools/GacGen64.exe b/Tools/GacGen64.exe index 2c0a99a8..1b031d07 100644 Binary files a/Tools/GacGen64.exe and b/Tools/GacGen64.exe differ diff --git a/Tutorial/GacUI_HelloWorlds/UIRes/Xml.bin.x64 b/Tutorial/GacUI_HelloWorlds/UIRes/Xml.bin.x64 index 4cfb1276..609e4289 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 1943de7f..f1acc50b 100644 Binary files a/Tutorial/GacUI_HelloWorlds/UIRes/Xml.bin.x86 and b/Tutorial/GacUI_HelloWorlds/UIRes/Xml.bin.x86 differ