diff --git a/Import/GacUI.cpp b/Import/GacUI.cpp index 31e92216..4017a8f9 100644 --- a/Import/GacUI.cpp +++ b/Import/GacUI.cpp @@ -8890,6 +8890,11 @@ namespace vl GuiListControl::ItemCallback ***********************************************************************/ + void GuiListControl::ItemCallback::OnStyleBoundsChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments) + { + listControl->CalculateView(); + } + GuiListControl::ItemCallback::ItemCallback(GuiListControl* _listControl) :listControl(_listControl) { @@ -8902,13 +8907,16 @@ GuiListControl::ItemCallback void GuiListControl::ItemCallback::ClearCache() { - for(vint i=0;iitemStyleProvider->DestroyItemStyle(cachedStyles[i]); } - for(vint i=0;iitemStyleProvider->DestroyItemStyle(installedStyles[i]); + auto style = installedStyles.Keys()[i]; + auto handler = installedStyles.Values()[i]; + style->GetBoundsComposition()->BoundsChanged.Detach(handler); + listControl->itemStyleProvider->DestroyItemStyle(style); } cachedStyles.Clear(); installedStyles.Clear(); @@ -8925,25 +8933,26 @@ GuiListControl::ItemCallback GuiListControl::IItemStyleController* GuiListControl::ItemCallback::RequestItem(vint itemIndex) { - vint id=listControl->itemStyleProvider->GetItemStyleId(itemIndex); - IItemStyleController* style=0; - for(vint i=0;iitemStyleProvider->GetItemStyleId(itemIndex); + IItemStyleController* style = 0; + for (vint i = 0; i < cachedStyles.Count(); i++) { - IItemStyleController* cachedStyle=cachedStyles[i]; - if(cachedStyle->GetItemStyleId()==id) + IItemStyleController* cachedStyle = cachedStyles[i]; + if (cachedStyle->GetItemStyleId() == id) { - style=cachedStyle; + style = cachedStyle; cachedStyles.RemoveAt(i); break; } } - if(!style) + if (!style) { - style=listControl->itemStyleProvider->CreateItemStyle(id); + style = listControl->itemStyleProvider->CreateItemStyle(id); } listControl->itemStyleProvider->Install(style, itemIndex); style->OnInstalled(); - installedStyles.Add(style); + auto handler = style->GetBoundsComposition()->BoundsChanged.AttachMethod(this, &ItemCallback::OnStyleBoundsChanged); + installedStyles.Add(style, handler); listControl->GetContainerComposition()->AddChild(style->GetBoundsComposition()); listControl->OnStyleInstalled(itemIndex, style); return style; @@ -8951,14 +8960,16 @@ GuiListControl::ItemCallback void GuiListControl::ItemCallback::ReleaseItem(IItemStyleController* style) { - vint index=installedStyles.IndexOf(style); - if(index!=-1) + vint index = installedStyles.Keys().IndexOf(style); + if (index != -1) { listControl->OnStyleUninstalled(style); listControl->GetContainerComposition()->RemoveChild(style->GetBoundsComposition()); - installedStyles.RemoveAt(index); + auto handler = installedStyles.Values()[index]; + style->GetBoundsComposition()->BoundsChanged.Detach(handler); + installedStyles.Remove(style); style->OnUninstalled(); - if(style->IsCacheable()) + if (style->IsCacheable()) { cachedStyles.Add(style); } @@ -8972,32 +8983,32 @@ GuiListControl::ItemCallback void GuiListControl::ItemCallback::SetViewLocation(Point value) { Rect virtualRect(value, listControl->GetViewSize()); - Rect realRect=listControl->axis->VirtualRectToRealRect(listControl->fullSize, virtualRect); + Rect realRect = listControl->axis->VirtualRectToRealRect(listControl->fullSize, virtualRect); listControl->GetHorizontalScroll()->SetPosition(realRect.Left()); listControl->GetVerticalScroll()->SetPosition(realRect.Top()); } Size GuiListControl::ItemCallback::GetStylePreferredSize(IItemStyleController* style) { - Size size=style->GetBoundsComposition()->GetPreferredBounds().GetSize(); + Size size = style->GetBoundsComposition()->GetPreferredBounds().GetSize(); return listControl->axis->RealSizeToVirtualSize(size); } void GuiListControl::ItemCallback::SetStyleAlignmentToParent(IItemStyleController* style, Margin margin) { - Margin newMargin=listControl->axis->VirtualMarginToRealMargin(margin); + Margin newMargin = listControl->axis->VirtualMarginToRealMargin(margin); style->GetBoundsComposition()->SetAlignmentToParent(newMargin); } Rect GuiListControl::ItemCallback::GetStyleBounds(IItemStyleController* style) { - Rect bounds=style->GetBoundsComposition()->GetBounds(); + Rect bounds = style->GetBoundsComposition()->GetBounds(); return listControl->axis->RealRectToVirtualRect(listControl->GetViewSize(), bounds); } void GuiListControl::ItemCallback::SetStyleBounds(IItemStyleController* style, Rect bounds) { - Rect newBounds=listControl->axis->VirtualRectToRealRect(listControl->GetViewSize(), bounds); + Rect newBounds = listControl->axis->VirtualRectToRealRect(listControl->GetViewSize(), bounds); return style->GetBoundsComposition()->SetBounds(newBounds); } @@ -9908,34 +9919,39 @@ FixedHeightItemArranger void FixedHeightItemArranger::OnViewChangedInternal(Rect oldBounds, Rect newBounds) { - if(callback) + if (callback) { - if(!suppressOnViewChanged) + if (!suppressOnViewChanged) { - vint oldVisibleCount=visibleStyles.Count(); - vint newRowHeight=rowHeight; - vint newStartIndex=(newBounds.Top()-GetYOffset())/rowHeight; - if(newStartIndex<0) newStartIndex=0; + vint oldVisibleCount = visibleStyles.Count(); + vint newRowHeight = rowHeight; + vint newStartIndex = (newBounds.Top() - GetYOffset()) / rowHeight; + if (newStartIndex < 0) newStartIndex = 0; - vint endIndex=startIndex+visibleStyles.Count()-1; - vint newEndIndex=(newBounds.Bottom()-1)/newRowHeight; - vint itemCount=itemProvider->Count(); + vint endIndex = startIndex + visibleStyles.Count() - 1; + vint newEndIndex = (newBounds.Bottom() - 1) / newRowHeight; + vint itemCount = itemProvider->Count(); - for(vint i=newStartIndex;i<=newEndIndex && iRequestItem(i); + style = callback->RequestItem(i); visibleStyles.Add(style); - vint styleHeight=callback->GetStylePreferredSize(style).y; - if(newRowHeightGetStylePreferredSize(style).y; + if (newRowHeight < styleHeight) { - newRowHeight=styleHeight; + newRowHeight = styleHeight; newEndIndex = newStartIndex + (newBounds.Height() - 1) / newRowHeight + 1; if (newEndIndex < i) { @@ -9945,28 +9961,28 @@ FixedHeightItemArranger } } - for(vint i=0;iReleaseItem(style); } } visibleStyles.RemoveRange(0, oldVisibleCount); - if(rowHeight!=newRowHeight) + if (rowHeight != newRowHeight) { - vint offset=oldBounds.Top()-rowHeight*startIndex; - rowHeight=newRowHeight; - suppressOnViewChanged=true; + vint offset = oldBounds.Top() - rowHeight*startIndex; + rowHeight = newRowHeight; + suppressOnViewChanged = true; callback->OnTotalSizeChanged(); - callback->SetViewLocation(Point(0, rowHeight*newStartIndex+offset)); - suppressOnViewChanged=false; + callback->SetViewLocation(Point(0, rowHeight*newStartIndex + offset)); + suppressOnViewChanged = false; InvalidateAdoptedSize(); } - startIndex=newStartIndex; + startIndex = newStartIndex; RearrangeItemBounds(); } } @@ -10128,85 +10144,89 @@ FixedSizeMultiColumnItemArranger void FixedSizeMultiColumnItemArranger::OnViewChangedInternal(Rect oldBounds, Rect newBounds) { - if(callback) + if (callback) { - if(!suppressOnViewChanged) + if (!suppressOnViewChanged) { - vint oldVisibleCount=visibleStyles.Count(); - Size newItemSize=itemSize; - vint endIndex=startIndex+visibleStyles.Count()-1; + vint oldVisibleCount = visibleStyles.Count(); + Size newItemSize = itemSize; + vint endIndex = startIndex + visibleStyles.Count() - 1; - vint newStartIndex=0; - vint newEndIndex=0; - vint itemCount=itemProvider->Count(); + vint newStartIndex = 0; + vint newEndIndex = 0; + vint itemCount = itemProvider->Count(); CalculateRange(newItemSize, newBounds, itemCount, newStartIndex, newEndIndex); - if(newItemSize==Size(1, 1) && newStartIndexpreviousEndIndex) + else if (ipreviousEndIndex) { - GuiListControl::IItemStyleController* style=callback->RequestItem(i); + style = callback->RequestItem(i); - if(iGetStylePreferredSize(style); - if(newItemSize.xGetStylePreferredSize(style); + if (newItemSize.x < styleSize.x) newItemSize.x = styleSize.x; + if (newItemSize.y < styleSize.y) newItemSize.y = styleSize.y; } } - vint updatedStartIndex=0; - vint updatedEndIndex=0; + vint updatedStartIndex = 0; + vint updatedEndIndex = 0; CalculateRange(newItemSize, newBounds, itemCount, updatedStartIndex, updatedEndIndex); - bool again=updatedStartIndexnewEndIndex; - previousStartIndex=newStartIndex; - previousEndIndex=newEndIndex; - if(updatedStartIndexnewEndIndex) newEndIndex=updatedEndIndex; - if(!again) break; + bool again = updatedStartIndexnewEndIndex; + previousStartIndex = newStartIndex; + previousEndIndex = newEndIndex; + if (updatedStartIndex < newStartIndex) newStartIndex = updatedStartIndex; + if (updatedEndIndex > newEndIndex) newEndIndex = updatedEndIndex; + if (!again) break; } - for(vint i=0;iReleaseItem(style); } } visibleStyles.RemoveRange(0, oldVisibleCount); - if(itemSize!=newItemSize) + if (itemSize != newItemSize) { - itemSize=newItemSize; - suppressOnViewChanged=true; + itemSize = newItemSize; + suppressOnViewChanged = true; callback->OnTotalSizeChanged(); - suppressOnViewChanged=false; + suppressOnViewChanged = false; InvalidateAdoptedSize(); } - startIndex=newStartIndex; + startIndex = newStartIndex; RearrangeItemBounds(); } } @@ -10352,8 +10372,6 @@ FixedHeightMultiColumnItemArranger currentWidth=0; } GuiListControl::IItemStyleController* style=visibleStyles[i]; - vint itemWidth=callback->GetStylePreferredSize(style).x; - if(currentWidthSetStyleBounds(style, Rect(Point(totalWidth, itemHeight*column), Size(0, 0))); } } @@ -10389,99 +10407,103 @@ FixedHeightMultiColumnItemArranger void FixedHeightMultiColumnItemArranger::OnViewChangedInternal(Rect oldBounds, Rect newBounds) { - if(callback) + if (callback) { - if(!suppressOnViewChanged) + if (!suppressOnViewChanged) { - vint oldVisibleCount=visibleStyles.Count(); - vint endIndex=startIndex+oldVisibleCount-1; + vint oldVisibleCount = visibleStyles.Count(); + vint endIndex = startIndex + oldVisibleCount - 1; - vint newItemHeight=itemHeight; - vint itemCount=itemProvider->Count(); + vint newItemHeight = itemHeight; + vint itemCount = itemProvider->Count(); - vint previousStartIndex=-1; - vint previousEndIndex=-1; - vint newStartIndex=-1; - vint newEndIndex=-1; + vint previousStartIndex = -1; + vint previousEndIndex = -1; + vint newStartIndex = -1; + vint newEndIndex = -1; - while(true) + while (true) { - vint newRows=0; - vint newStartColumn=0; - vint currentWidth=0; - vint totalWidth=0; + vint newRows = 0; + vint newStartColumn = 0; + vint currentWidth = 0; + vint totalWidth = 0; CalculateRange(newItemHeight, newBounds, newRows, newStartColumn); - newStartIndex=newRows*newStartColumn; - vint currentItemHeight=newItemHeight; + newStartIndex = newRows*newStartColumn; + vint currentItemHeight = newItemHeight; - for(vint i=newStartIndex;i=newBounds.Width()) + totalWidth += currentWidth; + currentWidth = 0; + if (totalWidth >= newBounds.Width()) { break; } } - newEndIndex=i; + newEndIndex = i; - if(startIndex<=i && i<=endIndex) + GuiListControl::IItemStyleController* style = nullptr; + if (startIndex <= i && i <= endIndex) { - GuiListControl::IItemStyleController* style=visibleStyles[i-startIndex]; + style = visibleStyles[i - startIndex]; visibleStyles.Add(style); } - else if(ipreviousEndIndex) + else if (ipreviousEndIndex) { - GuiListControl::IItemStyleController* style=callback->RequestItem(i); + style = callback->RequestItem(i); - if(iGetStylePreferredSize(style); - if(currentWidthGetStylePreferredSize(style); + if (currentWidth < styleSize.x) currentWidth = styleSize.x; + if (newItemHeight < styleSize.y) newItemHeight = styleSize.y; + if (currentItemHeight != newItemHeight) break; } } - if(previousStartIndex==-1 || previousStartIndexnewEndIndex) previousEndIndex=newEndIndex; - if(currentItemHeight==newItemHeight) + if (previousStartIndex == -1 || previousStartIndex < newStartIndex) previousStartIndex = newStartIndex; + if (previousEndIndex == -1 || previousEndIndex > newEndIndex) previousEndIndex = newEndIndex; + if (currentItemHeight == newItemHeight) { break; } } - newStartIndex=previousStartIndex; - newEndIndex=previousEndIndex; + newStartIndex = previousStartIndex; + newEndIndex = previousEndIndex; - for(vint i=0;iReleaseItem(style); } } visibleStyles.RemoveRange(0, oldVisibleCount); - if(itemHeight!=newItemHeight) + if (itemHeight != newItemHeight) { - itemHeight=newItemHeight; - suppressOnViewChanged=true; + itemHeight = newItemHeight; + suppressOnViewChanged = true; callback->OnTotalSizeChanged(); - suppressOnViewChanged=false; + suppressOnViewChanged = false; InvalidateAdoptedSize(); } - startIndex=newStartIndex; + startIndex = newStartIndex; RearrangeItemBounds(); } } @@ -33743,12 +33765,12 @@ GuiGraphicsComposition { associatedControl->OnRenderTargetChanged(renderTarget); } - OnRenderContextChanged(); for (vint i = 0; i < children.Count(); i++) { children[i]->UpdateRelatedHostRecord(record); } + OnRenderContextChanged(); } void GuiGraphicsComposition::SetAssociatedControl(controls::GuiControl* control) @@ -35754,6 +35776,7 @@ GuiTableComposition { previousContentMinSize = tableContentMinSize; UpdateCellBoundsInternal(); + InvokeOnCompositionStateChanged(); } } @@ -35938,8 +35961,8 @@ GuiTableComposition if (previousBounds != result || cellMinSizeModified) { - previousBounds = result; UpdateCellBounds(); + UpdatePreviousBounds(result); } return result; } @@ -38495,6 +38518,13 @@ GuiGraphicsHost } } + void GuiGraphicsHost::RefreshRelatedHostRecord(INativeWindow* nativeWindow) + { + hostRecord.nativeWindow = nativeWindow; + hostRecord.renderTarget = nativeWindow ? GetGuiGraphicsResourceManager()->GetRenderTarget(nativeWindow) : nullptr; + windowComposition->UpdateRelatedHostRecord(&hostRecord); + } + void GuiGraphicsHost::DisconnectCompositionInternal(GuiGraphicsComposition* composition) { for(vint i=0;iChildren().Count();i++) @@ -38737,7 +38767,7 @@ GuiGraphicsHost { previousClientSize = size; minSize = windowComposition->GetPreferredBounds().GetSize(); - Render(true); + needRender = true; } } @@ -39041,8 +39071,8 @@ GuiGraphicsHost { hostRecord.host = this; windowComposition=new GuiWindowComposition; - windowComposition->UpdateRelatedHostRecord(&hostRecord); windowComposition->SetMinSizeLimitation(GuiGraphicsComposition::LimitToElementAndChildren); + RefreshRelatedHostRecord(nullptr); } GuiGraphicsHost::~GuiGraphicsHost() @@ -39069,18 +39099,18 @@ GuiGraphicsHost GetCurrentController()->CallbackService()->UninstallListener(this); hostRecord.nativeWindow->UninstallListener(this); } - hostRecord.nativeWindow = _nativeWindow; - hostRecord.renderTarget = _nativeWindow ? GetGuiGraphicsResourceManager()->GetRenderTarget(_nativeWindow) : nullptr; - windowComposition->UpdateRelatedHostRecord(&hostRecord); - if (hostRecord.nativeWindow) + + if (_nativeWindow) { - hostRecord.nativeWindow->InstallListener(this); + _nativeWindow->InstallListener(this); GetCurrentController()->CallbackService()->InstallListener(this); - previousClientSize = hostRecord.nativeWindow->GetClientSize(); + previousClientSize = _nativeWindow->GetClientSize(); minSize = windowComposition->GetPreferredBounds().GetSize(); - hostRecord.nativeWindow->SetCaretPoint(caretPoint); + _nativeWindow->SetCaretPoint(caretPoint); needRender = true; } + + RefreshRelatedHostRecord(_nativeWindow); } } @@ -39102,16 +39132,27 @@ GuiGraphicsHost supressPaint = true; hostRecord.renderTarget->StartRendering(); windowComposition->Render(Size()); - bool success = hostRecord.renderTarget->StopRendering(); + auto result = hostRecord.renderTarget->StopRendering(); hostRecord.nativeWindow->RedrawContent(); supressPaint = false; - if (!success) + switch (result) { - windowComposition->UpdateRelatedHostRecord(nullptr); - GetGuiGraphicsResourceManager()->RecreateRenderTarget(hostRecord.nativeWindow); - windowComposition->UpdateRelatedHostRecord(&hostRecord); - needRender = true; + case RenderTargetFailure::ResizeWhileRendering: + { + GetGuiGraphicsResourceManager()->ResizeRenderTarget(hostRecord.nativeWindow); + needRender = true; + } + break; + case RenderTargetFailure::LostDevice: + { + windowComposition->UpdateRelatedHostRecord(nullptr); + GetGuiGraphicsResourceManager()->RecreateRenderTarget(hostRecord.nativeWindow); + RefreshRelatedHostRecord(hostRecord.nativeWindow); + needRender = true; + } + break; + default:; } } } diff --git a/Import/GacUI.h b/Import/GacUI.h index c95b0f07..060bf021 100644 --- a/Import/GacUI.h +++ b/Import/GacUI.h @@ -813,6 +813,13 @@ Basic Construction virtual IGuiGraphicsRenderer* Create()=0; }; + enum RenderTargetFailure + { + None, + ResizeWhileRendering, + LostDevice, + }; + /// /// This is the interface for graphics renderer targets. /// @@ -827,7 +834,7 @@ Basic Construction /// Notify the target to stop rendering. /// /// Returns false to recreate render target. - virtual bool StopRendering()=0; + virtual RenderTargetFailure StopRendering()=0; /// /// Apply a clipper to the render target. /// The result clipper is combined by all clippers in the clipper stack maintained by the render target. @@ -2981,6 +2988,11 @@ Resource Manager /// 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. @@ -6888,7 +6900,6 @@ Table Compositions collections::Array rowSizes; collections::Array columnSizes; - Rect previousBounds; Size previousContentMinSize; Size tableContentMinSize; @@ -8019,6 +8030,7 @@ Host vint FilterTitles(); void ClearAltHost(); void CloseAltHost(); + void RefreshRelatedHostRecord(INativeWindow* nativeWindow); void DisconnectCompositionInternal(GuiGraphicsComposition* composition); void MouseCapture(const NativeWindowMouseInfo& info); @@ -10806,13 +10818,15 @@ List Control class ItemCallback : public IItemProviderCallback, public IItemArrangerCallback { - typedef collections::List StyleList; + typedef collections::List StyleList; + typedef collections::Dictionary> InstalledStyleMap; protected: GuiListControl* listControl; IItemProvider* itemProvider; StyleList cachedStyles; - StyleList installedStyles; + InstalledStyleMap installedStyles; + void OnStyleBoundsChanged(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); public: ItemCallback(GuiListControl* _listControl); ~ItemCallback(); diff --git a/Import/GacUICompiler.cpp b/Import/GacUICompiler.cpp index cb191e27..d3b12dd9 100644 --- a/Import/GacUICompiler.cpp +++ b/Import/GacUICompiler.cpp @@ -2915,21 +2915,29 @@ GuiInstanceContext errors.Add(GuiResourceError({ {resource},element->codeRange.start }, L"ref.Parameter requires the following attributes existing at the same time: Name, Class.")); } } - else if (element->name.value == L"ref.Members") - { - if (element->subNodes.Count() == 1) - { - if (auto cdata = element->subNodes[0].Cast()) - { - context->memberScript = cdata->content.value; - context->memberPosition = { {resource},cdata->codeRange.start }; - context->memberPosition.column += 9; // codeRange.start }, L"Script should be contained in a CDATA section.")); - MEMBERSCRIPT_SUCCESS:; - } + +#define COLLECT_SCRIPT(NAME, SCRIPT, POSITION)\ + (element->name.value == L"ref." #NAME)\ + {\ + if (element->subNodes.Count() == 1)\ + {\ + if (auto cdata = element->subNodes[0].Cast())\ + {\ + context->SCRIPT = cdata->content.value;\ + context->POSITION = { {resource},cdata->codeRange.start };\ + context->POSITION.column += 9; /* codeRange.start }, L"Script should be contained in a CDATA section."));\ + NAME##_SCRIPT_SUCCESS:;\ + }\ + + else if COLLECT_SCRIPT(Members, memberScript, memberPosition) + else if COLLECT_SCRIPT(Ctor, ctorScript, ctorPosition) + else if COLLECT_SCRIPT(Dtor, dtorScript, dtorPosition) + +#undef COLLECT_SCRIPT else if (!context->instance) { context->instance = LoadCtor(resource, element, errors); @@ -3002,16 +3010,22 @@ GuiInstanceContext xmlParameter->attributes.Add(attClass); } - if (memberScript != L"") - { - auto xmlMembers = MakePtr(); - xmlMembers->name.value = L"ref.Members"; - xmlInstance->subNodes.Add(xmlMembers); +#define SERIALIZE_SCRIPT(NAME, SCRIPT)\ + if (SCRIPT != L"")\ + {\ + auto xmlScript = MakePtr();\ + xmlScript->name.value = L"ref." #NAME;\ + xmlInstance->subNodes.Add(xmlScript);\ + auto text = MakePtr();\ + text->content.value = SCRIPT;\ + xmlScript->subNodes.Add(text);\ + }\ - auto text = MakePtr(); - text->content.value = memberScript; - xmlMembers->subNodes.Add(text); - } + SERIALIZE_SCRIPT(Members, memberScript) + SERIALIZE_SCRIPT(Ctpr, ctorScript) + SERIALIZE_SCRIPT(Dtor, dtorScript) + +#undef SERIALIZE_SCRIPT if (stylePaths.Count() > 0) { @@ -7271,6 +7285,10 @@ Workflow_GenerateInstanceClass return nullptr; } + /////////////////////////////////////////////////////////////// + // Instance Class + /////////////////////////////////////////////////////////////// + auto module = Workflow_CreateModuleWithUsings(context); auto instanceClass = Workflow_InstallClass(context->className, module); { @@ -7291,6 +7309,11 @@ Workflow_GenerateInstanceClass instanceClass->attributes.Add(att); } } + + /////////////////////////////////////////////////////////////// + // Inherit from Constructor Class + /////////////////////////////////////////////////////////////// + if (!beforePrecompile) { auto baseType = MakePtr(); @@ -7310,6 +7333,10 @@ Workflow_GenerateInstanceClass } } + /////////////////////////////////////////////////////////////// + // Helpers + /////////////////////////////////////////////////////////////// + auto parseClassMembers = [&](const WString& code, const WString& name, List>& memberDecls, GuiResourceTextPos position) { WString wrappedCode = L"module parse_members; class Class {\r\n" + code + L"\r\n}"; @@ -7340,6 +7367,10 @@ Workflow_GenerateInstanceClass return block; }; + /////////////////////////////////////////////////////////////// + // ref.Members + /////////////////////////////////////////////////////////////// + if (context->memberScript != L"") { List> memberDecls; @@ -7360,6 +7391,10 @@ Workflow_GenerateInstanceClass CopyFrom(instanceClass->declarations, memberDecls, true); } + /////////////////////////////////////////////////////////////// + // Constructor Declaration + /////////////////////////////////////////////////////////////// + auto ctor = MakePtr(); ctor->constructorType = WfConstructorType::RawPtr; auto ctorBlock = (beforePrecompile ? notImplemented() : MakePtr()); @@ -7393,6 +7428,10 @@ Workflow_GenerateInstanceClass } } + /////////////////////////////////////////////////////////////// + // ref.Parameter (Variable, Getter, CtorArgument) + /////////////////////////////////////////////////////////////// + FOREACH(Ptr, param, context->parameters) { if (auto type = Workflow_ParseType(precompileContext, { resolvingResult.resource }, param->className.ToString() + L"^", param->classPosition, errors)) @@ -7476,13 +7515,22 @@ Workflow_GenerateInstanceClass } } + /////////////////////////////////////////////////////////////// + // Event Handlers + /////////////////////////////////////////////////////////////// + if (needEventHandler) { WorkflowEventNamesVisitor visitor(precompileContext, resolvingResult, instanceClass, errors); context->instance->Accept(&visitor); } + addDecl(ctor); + /////////////////////////////////////////////////////////////// + // Calling Constructor Class + /////////////////////////////////////////////////////////////// + if (!beforePrecompile) { { @@ -7574,13 +7622,97 @@ Workflow_GenerateInstanceClass } } + /////////////////////////////////////////////////////////////// + // ref.Ctor + /////////////////////////////////////////////////////////////// + + if (context->ctorScript != L"") { - auto dtor = MakePtr(); - addDecl(dtor); + if (auto stat = Workflow_ParseStatement(precompileContext, { resolvingResult.resource }, context->ctorScript, context->ctorPosition, errors)) + { + if (!beforePrecompile) + { + if (!stat.Cast()) + { + auto block = MakePtr(); + block->statements.Add(stat); + stat = block; + } - auto block = MakePtr(); - dtor->statement = block; + auto decl = MakePtr(); + decl->anonymity = WfFunctionAnonymity::Named; + decl->name.value = L""; + decl->returnType = GetTypeFromTypeInfo(TypeInfoRetriver::CreateTypeInfo().Obj()); + decl->statement = stat; + addDecl(decl); + { + auto refCtor = MakePtr(); + refCtor->name.value = L""; + + auto callExpr = MakePtr(); + callExpr->function = refCtor; + + auto exprStat = MakePtr(); + exprStat->expression = callExpr; + ctorBlock->statements.Add(exprStat); + } + } + } + } + + /////////////////////////////////////////////////////////////// + // Destructor + /////////////////////////////////////////////////////////////// + + auto dtor = MakePtr(); + auto dtorBlock = MakePtr(); + dtor->statement = dtorBlock; + + /////////////////////////////////////////////////////////////// + // ref.Dtor + /////////////////////////////////////////////////////////////// + + if (context->dtorScript != L"") + { + if (auto stat = Workflow_ParseStatement(precompileContext, { resolvingResult.resource }, context->dtorScript, context->dtorPosition, errors)) + { + if (!beforePrecompile) + { + if (!stat.Cast()) + { + auto block = MakePtr(); + block->statements.Add(stat); + stat = block; + } + + auto decl = MakePtr(); + decl->anonymity = WfFunctionAnonymity::Named; + decl->name.value = L""; + decl->returnType = GetTypeFromTypeInfo(TypeInfoRetriver::CreateTypeInfo().Obj()); + decl->statement = stat; + addDecl(decl); + + { + auto refDtor = MakePtr(); + refDtor->name.value = L""; + + auto callExpr = MakePtr(); + callExpr->function = refDtor; + + auto exprStat = MakePtr(); + exprStat->expression = callExpr; + dtorBlock->statements.Add(exprStat); + } + } + } + } + + /////////////////////////////////////////////////////////////// + // Clear Binding Subscriptions + /////////////////////////////////////////////////////////////// + + { auto ref = MakePtr(); ref->name.value = L"ClearSubscriptions"; @@ -7589,9 +7721,11 @@ Workflow_GenerateInstanceClass auto stat = MakePtr(); stat->expression = call; - block->statements.Add(stat); + dtorBlock->statements.Add(stat); } + addDecl(dtor); + return module; } diff --git a/Import/GacUICompiler.h b/Import/GacUICompiler.h index 68d70646..21b84298 100644 --- a/Import/GacUICompiler.h +++ b/Import/GacUICompiler.h @@ -362,11 +362,15 @@ Instance Context ParameterList parameters; WString memberScript; + WString ctorScript; + WString dtorScript; GuiResourceTextPos tagPosition; GuiResourceTextPos classPosition; GuiResourceTextPos stylePosition; GuiResourceTextPos memberPosition; + GuiResourceTextPos ctorPosition; + GuiResourceTextPos dtorPosition; bool appliedStyles = false; StyleContextList styles; diff --git a/Import/GacUIWindows.cpp b/Import/GacUIWindows.cpp index 62116b42..9570fd56 100644 --- a/Import/GacUIWindows.cpp +++ b/Import/GacUIWindows.cpp @@ -1627,6 +1627,13 @@ Windows Platform Native Controller void EnableCrossKernelCrashing() { + /* + "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options" + DWORD DisableUserModeCallbackFilter = 1 + + "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\TestCppCodegen.exe" + DWORD DisableUserModeCallbackFilter = 1 + */ typedef BOOL (WINAPI *tGetPolicy)(LPDWORD lpFlags); typedef BOOL (WINAPI *tSetPolicy)(DWORD dwFlags); const DWORD EXCEPTION_SWALLOWING = 0x1; @@ -1660,6 +1667,8 @@ namespace vl { namespace presentation { + using namespace elements; + namespace windows { using namespace vl::collections; @@ -1673,6 +1682,8 @@ WindowListener protected: ID2D1Factory* d2dFactory; INativeWindow* window; + bool rendering = false; + bool movedWhileRendering = false; virtual void RebuildCanvas(Size size) = 0; public: @@ -1683,10 +1694,39 @@ WindowListener } void Moved() + { + if (rendering) + { + movedWhileRendering = true; + } + else + { + ResizeRenderTarget(); + } + } + + void ResizeRenderTarget() { RebuildCanvas(window->GetClientSize()); } + void StartRendering() + { + rendering = true; + } + + void StopRendering() + { + rendering = false; + } + + bool RetrieveAndResetMovedWhileRendering() + { + bool result = movedWhileRendering; + movedWhileRendering = false; + return result; + } + virtual ID2D1RenderTarget* GetDirect2DRenderTarget() = 0; virtual void RecreateRenderTarget() = 0; virtual bool PresentRenderTarget() = 0; @@ -2067,40 +2107,6 @@ ControllerListener Direct2DWindowsNativeControllerListener* direct2DListener=0; - Direct2DWindowsNativeWindowListener* GetNativeWindowListener(INativeWindow* window) - { - vint index = direct2DListener->nativeWindowListeners.Keys().IndexOf(window); - return index == -1 - ? 0 - : direct2DListener->nativeWindowListeners.Values().Get(index).Obj(); - } - - ID2D1RenderTarget* GetNativeWindowDirect2DRenderTarget(INativeWindow* window) - { - if (auto listener = GetNativeWindowListener(window)) - { - return listener->GetDirect2DRenderTarget(); - } - return 0; - } - - void RecreateNativeWindowDirect2DRenderTarget(INativeWindow* window) - { - if (auto listener = GetNativeWindowListener(window)) - { - return listener->RecreateRenderTarget(); - } - } - - bool PresentNativeWindowDirect2DRenderTarget(INativeWindow* window) - { - if (auto listener = GetNativeWindowListener(window)) - { - return listener->PresentRenderTarget(); - } - return true; - } - ID2D1Factory* GetDirect2DFactory() { return direct2DListener->d2dFactory.Obj(); @@ -2125,48 +2131,107 @@ OS Supporting class WinDirect2DApplicationDirect2DObjectProvider : public IWindowsDirect2DObjectProvider { + protected: + + windows::Direct2DWindowsNativeWindowListener* GetNativeWindowListener(INativeWindow* window) + { + vint index = windows::direct2DListener->nativeWindowListeners.Keys().IndexOf(window); + return index == -1 + ? nullptr + : windows::direct2DListener->nativeWindowListeners.Values().Get(index).Obj(); + } + public: - void RecreateRenderTarget(INativeWindow* window) + void RecreateRenderTarget(INativeWindow* window)override { - vl::presentation::windows::RecreateNativeWindowDirect2DRenderTarget(window); + if (auto listener = GetNativeWindowListener(window)) + { + return listener->RecreateRenderTarget(); + } } - bool PresentRenderTarget(INativeWindow* window) + void ResizeRenderTarget(INativeWindow* window)override { - return vl::presentation::windows::PresentNativeWindowDirect2DRenderTarget(window); + if (auto listener = GetNativeWindowListener(window)) + { + return listener->ResizeRenderTarget(); + } } - ID2D1RenderTarget* GetNativeWindowDirect2DRenderTarget(INativeWindow* window) + ID2D1RenderTarget* GetNativeWindowDirect2DRenderTarget(INativeWindow* window)override { - return vl::presentation::windows::GetNativeWindowDirect2DRenderTarget(window); + if (auto listener = GetNativeWindowListener(window)) + { + return listener->GetDirect2DRenderTarget(); + } + return nullptr; } - ID2D1Factory* GetDirect2DFactory() + void StartRendering(INativeWindow* window)override + { + if (auto listener = GetNativeWindowListener(window)) + { + listener->StartRendering(); + if (auto renderTarget = listener->GetDirect2DRenderTarget()) + { + renderTarget->BeginDraw(); + renderTarget->Clear(D2D1::ColorF(D2D1::ColorF::Black)); + } + } + } + + RenderTargetFailure StopRenderingAndPresent(INativeWindow* window)override + { + if (auto listener = GetNativeWindowListener(window)) + { + listener->StopRendering(); + bool moved = listener->RetrieveAndResetMovedWhileRendering(); + + if (auto renderTarget = listener->GetDirect2DRenderTarget()) + { + HRESULT hr = renderTarget->EndDraw(); + if (hr == S_OK) + { + if (moved) + { + return RenderTargetFailure::ResizeWhileRendering; + } + else if (listener->PresentRenderTarget()) + { + return RenderTargetFailure::None; + } + } + } + } + return RenderTargetFailure::LostDevice; + } + + ID2D1Factory* GetDirect2DFactory()override { return vl::presentation::windows::GetDirect2DFactory(); } - IDWriteFactory* GetDirectWriteFactory() + IDWriteFactory* GetDirectWriteFactory()override { return vl::presentation::windows::GetDirectWriteFactory(); } - IWindowsDirect2DRenderTarget* GetBindedRenderTarget(INativeWindow* window) + IWindowsDirect2DRenderTarget* GetBindedRenderTarget(INativeWindow* window)override { return dynamic_cast(vl::presentation::windows::GetWindowsForm(window)->GetGraphicsHandler()); } - void SetBindedRenderTarget(INativeWindow* window, IWindowsDirect2DRenderTarget* renderTarget) + void SetBindedRenderTarget(INativeWindow* window, IWindowsDirect2DRenderTarget* renderTarget)override { vl::presentation::windows::GetWindowsForm(window)->SetGraphicsHandler(renderTarget); } - IWICImagingFactory* GetWICImagingFactory() + IWICImagingFactory* GetWICImagingFactory()override { return vl::presentation::windows::GetWICImagingFactory(); } - IWICBitmap* GetWICBitmap(INativeImageFrame* frame) + IWICBitmap* GetWICBitmap(INativeImageFrame* frame)override { return vl::presentation::windows::GetWICBitmap(frame); } @@ -9778,10 +9843,10 @@ WindowsGDIRenderTarget dc=GetWindowsGDIObjectProvider()->GetNativeWindowDC(window); } - bool StopRendering()override + RenderTargetFailure StopRendering()override { dc = 0; - return true; + return RenderTargetFailure::None; } void PushClipper(Rect clipper)override @@ -10053,6 +10118,10 @@ WindowsGDIResourceManager { } + void ResizeRenderTarget(INativeWindow* window)override + { + } + IGuiGraphicsLayoutProvider* GetLayoutProvider()override { return layoutProvider.Obj(); @@ -13051,9 +13120,9 @@ WindowsDirect2DRenderTarget typedef SortedList> ImageCacheList; protected: INativeWindow* window; - ID2D1RenderTarget* d2dRenderTarget; + ID2D1RenderTarget* d2dRenderTarget = nullptr; List clippers; - vint clipperCoverWholeTargetCounter; + vint clipperCoverWholeTargetCounter = 0; CachedSolidBrushAllocator solidBrushes; CachedLinearBrushAllocator linearBrushes; @@ -13089,8 +13158,6 @@ WindowsDirect2DRenderTarget public: WindowsDirect2DRenderTarget(INativeWindow* _window) :window(_window) - ,d2dRenderTarget(0) - ,clipperCoverWholeTargetCounter(0) { solidBrushes.SetRenderTarget(this); linearBrushes.SetRenderTarget(this); @@ -13173,20 +13240,17 @@ WindowsDirect2DRenderTarget void StartRendering()override { d2dRenderTarget = GetWindowsDirect2DObjectProvider()->GetNativeWindowDirect2DRenderTarget(window); - d2dRenderTarget->BeginDraw(); - d2dRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::Black)); + CHECK_ERROR(d2dRenderTarget, L"vl::presentation::elements_windows_d2d::WindowsDirect2DRenderTarget::StartRendering()#Invalid render target."); + + GetWindowsDirect2DObjectProvider()->StartRendering(window); } - bool StopRendering()override + RenderTargetFailure StopRendering()override { - auto result = d2dRenderTarget->EndDraw(); - bool deviceAvailable = false; - if (result == S_OK) - { - deviceAvailable = GetWindowsDirect2DObjectProvider()->PresentRenderTarget(window); - } - d2dRenderTarget = 0; - return deviceAvailable; + CHECK_ERROR(d2dRenderTarget, L"vl::presentation::elements_windows_d2d::WindowsDirect2DRenderTarget::StartRendering()#Invalid render target."); + auto result = GetWindowsDirect2DObjectProvider()->StopRenderingAndPresent(window); + d2dRenderTarget = nullptr; + return result; } void PushClipper(Rect clipper)override @@ -13301,6 +13365,11 @@ WindowsGDIResourceManager NativeWindowCreated(window); } + void ResizeRenderTarget(INativeWindow* window) + { + GetWindowsDirect2DObjectProvider()->ResizeRenderTarget(window); + } + IGuiGraphicsLayoutProvider* GetLayoutProvider()override { return layoutProvider.Obj(); diff --git a/Import/GacUIWindows.h b/Import/GacUIWindows.h index 9f706a79..a8e4882d 100644 --- a/Import/GacUIWindows.h +++ b/Import/GacUIWindows.h @@ -650,9 +650,6 @@ namespace vl { namespace windows { - extern ID2D1RenderTarget* GetNativeWindowDirect2DRenderTarget(INativeWindow* window); - extern void RecreateNativeWindowDirect2DRenderTarget(INativeWindow* window); - extern bool PresentNativeWindowDirect2DRenderTarget(INativeWindow* window); extern ID2D1Factory* GetDirect2DFactory(); extern IDWriteFactory* GetDirectWriteFactory(); extern ID3D11Device* GetD3D11Device(); @@ -1935,15 +1932,18 @@ OS Supporting class IWindowsDirect2DObjectProvider : public Interface { public: - virtual void RecreateRenderTarget(INativeWindow* window)=0; - virtual bool PresentRenderTarget(INativeWindow* window)=0; - virtual ID2D1RenderTarget* GetNativeWindowDirect2DRenderTarget(INativeWindow* window)=0; - virtual ID2D1Factory* GetDirect2DFactory()=0; - virtual IDWriteFactory* GetDirectWriteFactory()=0; - virtual IWindowsDirect2DRenderTarget* GetBindedRenderTarget(INativeWindow* window)=0; - virtual void SetBindedRenderTarget(INativeWindow* window, IWindowsDirect2DRenderTarget* renderTarget)=0; - virtual IWICImagingFactory* GetWICImagingFactory()=0; - virtual IWICBitmap* GetWICBitmap(INativeImageFrame* frame)=0; + virtual void RecreateRenderTarget(INativeWindow* window) = 0; + virtual void ResizeRenderTarget(INativeWindow* window) = 0; + virtual ID2D1RenderTarget* GetNativeWindowDirect2DRenderTarget(INativeWindow* window) = 0; + virtual void StartRendering(INativeWindow* window) = 0; + virtual elements::RenderTargetFailure StopRenderingAndPresent(INativeWindow* window) = 0; + + virtual ID2D1Factory* GetDirect2DFactory() = 0; + virtual IDWriteFactory* GetDirectWriteFactory() = 0; + virtual IWindowsDirect2DRenderTarget* GetBindedRenderTarget(INativeWindow* window) = 0; + virtual void SetBindedRenderTarget(INativeWindow* window, IWindowsDirect2DRenderTarget* renderTarget) = 0; + virtual IWICImagingFactory* GetWICImagingFactory() = 0; + virtual IWICBitmap* GetWICBitmap(INativeImageFrame* frame) = 0; }; extern IWindowsDirect2DObjectProvider* GetWindowsDirect2DObjectProvider(); diff --git a/Tools/GacGen.exe b/Tools/GacGen.exe index c4b746b9..9ff0d556 100644 Binary files a/Tools/GacGen.exe and b/Tools/GacGen.exe differ diff --git a/Tutorial/GacUI_HelloWorlds/UIRes/Xml.bin b/Tutorial/GacUI_HelloWorlds/UIRes/Xml.bin index 7b394581..03590a61 100644 Binary files a/Tutorial/GacUI_HelloWorlds/UIRes/Xml.bin and b/Tutorial/GacUI_HelloWorlds/UIRes/Xml.bin differ