This commit is contained in:
Zihan Chen
2018-07-01 14:27:25 -07:00
parent 3576e35647
commit bb7767db8f
47 changed files with 553 additions and 124 deletions
+257 -15
View File
@@ -11032,10 +11032,10 @@ namespace vl
currentTheme = nullptr;
}
bool RegisterTheme(const WString& name, Ptr<ThemeTemplates> theme)
bool RegisterTheme(Ptr<ThemeTemplates> theme)
{
CHECK_ERROR(currentTheme != nullptr, L"vl::presentation::theme::RegisterTheme(const WString&, Ptr<ThemeTemplates>)#Theme has already been initialized");
return currentTheme->RegisterTheme(name, theme);
return currentTheme->RegisterTheme(theme->Name, theme);
}
Ptr<ThemeTemplates> UnregisterTheme(const WString& name)
@@ -17122,6 +17122,19 @@ GuiComboBoxListControl
SelectedIndexChanged.Execute(GetNotifyEventArguments());
}
void GuiComboBoxListControl::OnAttached(GuiListControl::IItemProvider* provider)
{
}
void GuiComboBoxListControl::OnItemModified(vint start, vint count, vint newCount)
{
vint index = GetSelectedIndex();
if (start <= index && index < start + count)
{
DisplaySelectedContent(index);
}
}
GuiComboBoxListControl::GuiComboBoxListControl(theme::ThemeName themeName, GuiSelectableListControl* _containedListControl)
:GuiComboBoxBase(themeName)
, containedListControl(_containedListControl)
@@ -17131,6 +17144,7 @@ GuiComboBoxListControl
ContextChanged.AttachMethod(this, &GuiComboBoxListControl::OnContextChanged);
VisuallyEnabledChanged.AttachMethod(this, &GuiComboBoxListControl::OnVisuallyEnabledChanged);
containedListControl->GetItemProvider()->AttachCallback(this);
containedListControl->SetMultiSelect(false);
containedListControl->AdoptedSizeInvalidated.AttachMethod(this, &GuiComboBoxListControl::OnListControlAdoptedSizeInvalidated);
containedListControl->SelectionChanged.AttachMethod(this, &GuiComboBoxListControl::OnListControlSelectionChanged);
@@ -17147,6 +17161,7 @@ GuiComboBoxListControl
GuiComboBoxListControl::~GuiComboBoxListControl()
{
containedListControl->GetItemProvider()->DetachCallback(this);
containedListControl->GetBoundsComposition()->BoundsChanged.Detach(boundsChangedHandler);
boundsChangedHandler = nullptr;
}
@@ -33921,10 +33936,83 @@ GuiResourceFolder
}
}
/***********************************************************************
GuiResourceMetadata
***********************************************************************/
void GuiResourceMetadata::LoadFromXml(Ptr<parsing::xml::XmlDocument> xml, GuiResourceLocation location, GuiResourceError::List& errors)
{
auto attrName = XmlGetAttribute(xml->rootElement, L"Name");
auto attrVersion = XmlGetAttribute(xml->rootElement, L"Version");
if (!attrName || !attrVersion)
{
errors.Add(GuiResourceError(location, L"[INTERNAL-ERROR] Resource metadata lacks of Name or Version attribute."));
return;
}
name = attrName->value.value;
version = attrVersion->value.value;
dependencies.Clear();
if (auto xmlDeps = XmlGetElement(xml->rootElement, L"Dependencies"))
{
FOREACH(Ptr<XmlElement>, xmlDep, XmlGetElements(xmlDeps, L"Resource"))
{
auto attrDep = XmlGetAttribute(xmlDep, L"Name");
if (!attrDep)
{
errors.Add(GuiResourceError(location, L"[INTERNAL-ERROR] Resource dependency lacks of Name attribute."));
}
dependencies.Add(attrDep->value.value);
}
}
}
Ptr<parsing::xml::XmlDocument> GuiResourceMetadata::SaveToXml()
{
auto root = MakePtr<XmlElement>();
root->name.value = L"ResourceMetadata";
{
auto attr = MakePtr<XmlAttribute>();
attr->name.value = L"Name";
attr->value.value = name;
root->attributes.Add(attr);
}
{
auto attr = MakePtr<XmlAttribute>();
attr->name.value = L"Version";
attr->value.value = version;
root->attributes.Add(attr);
}
{
auto xmlDeps = MakePtr<XmlElement>();
xmlDeps->name.value = L"Dependencies";
root->subNodes.Add(xmlDeps);
FOREACH(WString, dep, dependencies)
{
auto xmlDep = MakePtr<XmlElement>();
xmlDep->name.value = L"Resource";
xmlDeps->subNodes.Add(xmlDep);
{
auto attr = MakePtr<XmlAttribute>();
attr->name.value = L"Name";
attr->value.value = dep;
xmlDep->attributes.Add(attr);
}
}
}
auto doc = MakePtr<XmlDocument>();
doc->rootElement = root;
return doc;
}
/***********************************************************************
GuiResource
***********************************************************************/
const wchar_t* GuiResource::CurrentVersionString = L"1.0";
void GuiResource::ProcessDelayLoading(Ptr<GuiResource> resource, DelayLoadingList& delayLoadings, GuiResourceError::List& errors)
{
FOREACH(DelayLoading, delay, delayLoadings)
@@ -33961,12 +34049,19 @@ GuiResource
GuiResource::GuiResource()
{
metadata = MakePtr<GuiResourceMetadata>();
metadata->version = CurrentVersionString;
}
GuiResource::~GuiResource()
{
}
Ptr<GuiResourceMetadata> GuiResource::GetMetadata()
{
return metadata;
}
WString GuiResource::GetWorkingDirectory()
{
return workingDirectory;
@@ -34021,6 +34116,23 @@ GuiResource
{
stream::internal::ContextFreeReader reader(stream);
auto resource = MakePtr<GuiResource>();
{
WString metadata;
reader << metadata;
auto parser = GetParserManager()->GetParser<XmlDocument>(L"XML");
auto xmlMetadata = parser->Parse({ resource }, metadata, errors);
if (!xmlMetadata) return nullptr;
resource->metadata->LoadFromXml(xmlMetadata, { resource }, errors);
if (errors.Count() != 0) return nullptr;
if (resource->metadata->version != CurrentVersionString)
{
errors.Add(GuiResourceError({ resource }, L"Only resource binary of version \"" + WString(CurrentVersionString) + L"\" is accepted. Please recompile the resource before loading it."));
return nullptr;
}
}
List<WString> typeNames;
reader << typeNames;
@@ -34043,7 +34155,19 @@ GuiResource
void GuiResource::SavePrecompiledBinary(stream::IStream& stream)
{
stream::internal::ContextFreeWriter writer(stream);
{
auto xmlMetadata = metadata->SaveToXml();
stream::MemoryStream memoryStream;
{
stream::StreamWriter writer(memoryStream);
XmlPrint(xmlMetadata, writer);
}
memoryStream.SeekFromBegin(0);
{
stream::StreamReader reader(memoryStream);
writer << reader.ReadToEnd();
}
}
List<WString> typeNames;
CollectTypeNames(typeNames);
writer << typeNames;
@@ -34936,6 +35060,7 @@ namespace vl
{
using namespace collections;
using namespace stream;
using namespace parsing::xml;
using namespace reflection::description;
using namespace controls;
@@ -35004,9 +35129,30 @@ IGuiInstanceResourceManager
protected:
typedef Dictionary<WString, Ptr<GuiResource>> ResourceMap;
List<Ptr<GuiResource>> anonymousResources;
ResourceMap resources;
ResourceMap instanceResources;
class PendingResource : public Object
{
public:
Ptr<GuiResourceMetadata> metadata;
GuiResourceUsage usage;
MemoryStream memoryStream;
SortedList<WString> dependencies;
Ptr<GuiResource> LoadResource()
{
memoryStream.SeekFromBegin(0);
List<GuiResourceError> errors;
auto resource = GuiResource::LoadPrecompiledBinary(memoryStream, errors);
CHECK_ERROR(errors.Count() == 0, L"PendingResource::LoadResource()#Failed to load the resource.");
return resource;
}
};
Group<WString, Ptr<PendingResource>> depToPendings;
SortedList<Ptr<PendingResource>> pendingResources;
public:
GUI_PLUGIN_NAME(GacUI_Res_Resource)
@@ -35026,18 +35172,50 @@ IGuiInstanceResourceManager
resourceManager = nullptr;
}
bool SetResource(const WString& name, Ptr<GuiResource> resource, GuiResourceUsage usage)override
bool SetResource(Ptr<GuiResource> resource, GuiResourceUsage usage)override
{
vint index = resources.Keys().IndexOf(name);
if (index != -1) return false;
resource->Initialize(usage);
resources.Add(name, resource);
auto record = resource->GetValueByPath(L"Precompiled/ClassNameRecord").Cast<GuiResourceClassNameRecord>();
FOREACH(WString, className, record->classNames)
auto metadata = resource->GetMetadata();
if (metadata->name == L"")
{
instanceResources.Add(className, resource);
if (anonymousResources.Contains(resource.Obj())) return false;
resource->Initialize(usage);
anonymousResources.Add(resource);
}
else
{
CHECK_ERROR(!resources.Keys().Contains(metadata->name), L"GuiResourceManager::SetResource(Ptr<GuiResource>, GuiResourceUsage)#A resource with the same name has been loaded.");
resource->Initialize(usage);
resources.Add(metadata->name, resource);
}
if (auto record = resource->GetValueByPath(L"Precompiled/ClassNameRecord").Cast<GuiResourceClassNameRecord>())
{
FOREACH(WString, className, record->classNames)
{
instanceResources.Add(className, resource);
}
}
if (metadata->name != L"")
{
vint index = depToPendings.Keys().IndexOf(metadata->name);
if (index != -1)
{
List<Ptr<PendingResource>> prs;
CopyFrom(prs, depToPendings.GetByIndex(index));
depToPendings.Remove(metadata->name);
FOREACH(Ptr<PendingResource>, pr, prs)
{
pr->dependencies.Remove(metadata->name);
if (pr->dependencies.Count() == 0)
{
pendingResources.Remove(pr.Obj());
SetResource(pr->LoadResource(), pr->usage);
}
}
}
}
return true;
}
@@ -35054,6 +35232,70 @@ IGuiInstanceResourceManager
if (index == -1) return nullptr;
return instanceResources.Values()[index];
}
void UnloadResource(const WString& name)
{
vint index = resources.Keys().IndexOf(name);
if (index != -1)
{
auto resource = resources.Values()[index];
resources.Remove(name);
if (auto record = resource->GetValueByPath(L"Precompiled/ClassNameRecord").Cast<GuiResourceClassNameRecord>())
{
FOREACH(WString, className, record->classNames)
{
instanceResources.Remove(className);
}
}
}
}
void LoadResourceOrPending(stream::IStream& stream, GuiResourceUsage usage = GuiResourceUsage::DataOnly)override
{
auto pr = MakePtr<PendingResource>();
pr->usage = usage;
CopyStream(stream, pr->memoryStream);
pr->metadata = MakePtr<GuiResourceMetadata>();
{
pr->memoryStream.SeekFromBegin(0);
stream::internal::ContextFreeReader reader(pr->memoryStream);
WString metadata;
reader << metadata;
List<GuiResourceError> errors;
auto parser = GetParserManager()->GetParser<XmlDocument>(L"XML");
auto xmlMetadata = parser->Parse({}, metadata, errors);
CHECK_ERROR(xmlMetadata, L"GuiResourceManager::LoadResourceOrPending(stream::IStream&, GuiResourceUsage)#This resource does not contain a valid metadata.");
pr->metadata->LoadFromXml(xmlMetadata, {}, errors);
CHECK_ERROR(errors.Count() == 0, L"GuiResourceManager::LoadResourceOrPending(stream::IStream&, GuiResourceUsage)#This resource does not contain a valid metadata.");
}
CHECK_ERROR(
pr->metadata->name != L"" || pr->dependencies.Count() == 0,
L"GuiResourceManager::LoadResourceOrPending(stream::IStream&, GuiResourceUsage)#The name of this resource cannot be empty because it has dependencies."
);
CopyFrom(pr->dependencies, From(pr->metadata->dependencies).Except(resources.Keys()));
if (pr->dependencies.Count() == 0)
{
SetResource(pr->LoadResource(), pr->usage);
}
else
{
pendingResources.Add(pr);
FOREACH(WString, dep, pr->dependencies)
{
depToPendings.Add(dep, pr);
}
}
}
void GetPendingResourceNames(collections::List<WString>& names)override
{
CopyFrom(names, From(pendingResources).Select([](Ptr<PendingResource> pr) {return pr->metadata->name; }));
}
};
GUI_REGISTER_PLUGIN(GuiResourceManager)
}
@@ -35377,7 +35619,7 @@ namespace vl
paragraph->Accept(&visitor);
}
{
vint32_t count = visitor.imageRuns.Count();
vint32_t count = (vint32_t)visitor.imageRuns.Count();
stream.Write(&count, sizeof(count));
FOREACH(Ptr<DocumentImageRun>, imageRun, visitor.imageRuns)
{
@@ -35780,7 +36022,7 @@ namespace vl
ResolvedStyle style = styles[styles.Count() - 1];
writer.WriteString(L"{\\f" + itow(GetFont(style.style.fontFamily)));
writer.WriteString(L"{\\fs" + itow((vint)(style.style.size * 1.5)));
writer.WriteString(L"\\fs" + itow((vint)(style.style.size * 1.5)));
writer.WriteString(L"\\cf" + itow(GetColor(style.color)));
writer.WriteString(L"\\cb" + itow(GetColor(style.backgroundColor)));
writer.WriteString(L"\\chshdng" + itow(GetColor(style.backgroundColor)));
+39 -6
View File
@@ -4214,19 +4214,38 @@ Resource
DataOnly,
InstanceClass,
};
/// <summary>Resource metadata.</summary>
class GuiResourceMetadata : public Object
{
public:
WString name;
WString version;
collections::List<WString> dependencies;
void LoadFromXml(Ptr<parsing::xml::XmlDocument> xml, GuiResourceLocation location, GuiResourceError::List& errors);
Ptr<parsing::xml::XmlDocument> SaveToXml();
};
/// <summary>Resource. A resource is a root resource folder that does not have a name.</summary>
class GuiResource : public GuiResourceFolder, public Description<GuiResource>
{
protected:
WString workingDirectory;
Ptr<GuiResourceMetadata> metadata;
static void ProcessDelayLoading(Ptr<GuiResource> resource, DelayLoadingList& delayLoadings, GuiResourceError::List& errors);
public:
static const wchar_t* CurrentVersionString;
/// <summary>Create a resource.</summary>
GuiResource();
~GuiResource();
/// <summary>Get the metadata of the resource.</summary>
/// <returns>The metadata.</returns>
Ptr<GuiResourceMetadata> GetMetadata();
/// <summary>Get the directory where the resource is load.</summary>
/// <returns>The directory.</returns>
WString GetWorkingDirectory();
@@ -9283,13 +9302,15 @@ namespace vl
{
friend class Theme;
protected:
ThemeTemplates* previous = nullptr;
ThemeTemplates* next = nullptr;
ThemeTemplates* previous = nullptr;
ThemeTemplates* next = nullptr;
controls::GuiControlHost* GetControlHostForInstance()override;
controls::GuiControlHost* GetControlHostForInstance()override;
public:
~ThemeTemplates();
WString Name;
#define GUI_DEFINE_ITEM_PROPERTY(TEMPLATE, CONTROL) TemplateProperty<templates::Gui##TEMPLATE> CONTROL;
GUI_CONTROL_TEMPLATE_TYPES(GUI_DEFINE_ITEM_PROPERTY)
#undef GUI_DEFINE_ITEM_PROPERTY
@@ -9304,7 +9325,7 @@ namespace vl
/// <returns>Returns true if this operation succeeded.</returns>
/// <param name="name">The name of the theme.</param>
/// <param name="theme">The control template collection object.</param>
extern bool RegisterTheme(const WString& name, Ptr<ThemeTemplates> theme);
extern bool RegisterTheme(Ptr<ThemeTemplates> theme);
/// <summary>Unregister a control template collection object.</summary>
/// <returns>The registered object. Returns null if it does not exist.</returns>
/// <param name="name">The name of the theme.</param>
@@ -15753,7 +15774,10 @@ ComboBox with GuiListControl
***********************************************************************/
/// <summary>Combo box list control. This control is a combo box with a list control in its popup.</summary>
class GuiComboBoxListControl : public GuiComboBoxBase, public Description<GuiComboBoxListControl>
class GuiComboBoxListControl
: public GuiComboBoxBase
, private GuiListControl::IItemProviderCallback
, public Description<GuiComboBoxListControl>
{
public:
using ItemStyleProperty = TemplateProperty<templates::GuiTemplate>;
@@ -15779,6 +15803,12 @@ ComboBox with GuiListControl
void OnListControlAdoptedSizeInvalidated(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments);
void OnListControlBoundsChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments);
void OnListControlSelectionChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments);
private:
// ===================== GuiListControl::IItemProviderCallback =====================
void OnAttached(GuiListControl::IItemProvider* provider)override;
void OnItemModified(vint start, vint count, vint newCount)override;
public:
/// <summary>Create a control with a specified default theme and a list control that will be put in the popup control to show all items.</summary>
/// <param name="themeName">The theme name for retriving a default control template.</param>
@@ -18919,9 +18949,12 @@ IGuiResourceManager
class IGuiResourceManager : public IDescriptable, public Description<IGuiResourceManager>
{
public:
virtual bool SetResource(const WString& name, Ptr<GuiResource> resource, GuiResourceUsage usage = GuiResourceUsage::DataOnly) = 0;
virtual bool SetResource(Ptr<GuiResource> resource, GuiResourceUsage usage = GuiResourceUsage::DataOnly) = 0;
virtual Ptr<GuiResource> GetResource(const WString& name) = 0;
virtual Ptr<GuiResource> GetResourceFromClassName(const WString& classFullName) = 0;
virtual void UnloadResource(const WString& name) = 0;
virtual void LoadResourceOrPending(stream::IStream& stream, GuiResourceUsage usage = GuiResourceUsage::DataOnly) = 0;
virtual void GetPendingResourceNames(collections::List<WString>& names) = 0;
};
extern IGuiResourceManager* GetResourceManager();
+240 -94
View File
File diff suppressed because it is too large Load Diff
+4 -2
View File
@@ -624,8 +624,9 @@ namespace vl
extern bool WriteBinaryResource(
Ptr<GuiResource> resource,
bool compress,
bool workflow,
const filesystem::FilePath& filePath);
bool includeAssemblyInResource,
Nullable<filesystem::FilePath> resourceOutput,
Nullable<filesystem::FilePath> assemblyOutput);
extern bool WriteEmbeddedResource(Ptr<GuiResource> resource,
Ptr<workflow::cppcodegen::WfCppInput> cppInput,
@@ -1119,6 +1120,7 @@ WorkflowCompiler (Compile)
}
};
extern IGuiInstanceLoader::TypeInfo Workflow_AdjustPropertySearchType(types::ResolvingResult& resolvingResult, IGuiInstanceLoader::TypeInfo resolvedTypeInfo, GlobalStringKey prop);
extern bool Workflow_GetPropertyTypes(WString& errorPrefix, types::ResolvingResult& resolvingResult, IGuiInstanceLoader* loader, IGuiInstanceLoader::TypeInfo resolvedTypeInfo, GlobalStringKey prop, Ptr<GuiAttSetterRepr::SetterValue> setter, collections::List<types::PropertyResolving>& possibleInfos, GuiResourceError::List& errors);
extern Ptr<reflection::description::ITypeInfo> Workflow_GetSuggestedParameterType(reflection::description::ITypeDescriptor* typeDescriptor);
extern IGuiInstanceLoader::TypeInfo Workflow_CollectReferences(GuiResourcePrecompileContext& precompileContext, types::ResolvingResult& resolvingResult, GuiResourceError::List& errors);
+1
View File
@@ -1414,6 +1414,7 @@ Type Declaration (Extra)
CLASS_MEMBER_BASE(GuiInstanceRootObject)
CLASS_MEMBER_CONSTRUCTOR(Ptr<ThemeTemplates>(), NO_PARAMETER)
CLASS_MEMBER_FIELD(Name)
#define GUI_DEFINE_ITEM_PROPERTY(TEMPLATE, CONTROL) CLASS_MEMBER_FIELD(CONTROL)
GUI_CONTROL_TEMPLATE_TYPES(GUI_DEFINE_ITEM_PROPERTY)
#undef GUI_DEFINE_ITEM_PROPERTY
File diff suppressed because one or more lines are too long
+4 -1
View File
@@ -28683,7 +28683,10 @@ ValidateStructure(Expression)
void Visit(WfVirtualCfeExpression* node)override
{
ValidateExpressionStructure(manager, context, node->expandedExpression);
if (node->expandedExpression)
{
ValidateExpressionStructure(manager, context, node->expandedExpression);
}
}
void Visit(WfVirtualCseExpression* node)override
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.