diff --git a/Import/GacUI.cpp b/Import/GacUI.cpp index 13024247..d3570d06 100644 --- a/Import/GacUI.cpp +++ b/Import/GacUI.cpp @@ -3763,9 +3763,13 @@ GuiControlHost SetNativeWindow(nullptr); } - void GuiControlHost::UpdateClientSizeAfterRendering(Size clientSize) + void GuiControlHost::UpdateClientSizeAfterRendering(Size preferredSize, Size clientSize) { - SetClientSize(clientSize); + auto size = GetClientSize(); + if (size != clientSize) + { + SetClientSize(clientSize); + } } GuiControlHost::GuiControlHost(theme::ThemeName themeName) @@ -4465,11 +4469,11 @@ GuiWindow GuiPopup ***********************************************************************/ - void GuiPopup::UpdateClientSizeAfterRendering(Size clientSize) + void GuiPopup::UpdateClientSizeAfterRendering(Size preferredSize, Size clientSize) { if (popupType == -1) { - GuiWindow::UpdateClientSizeAfterRendering(clientSize); + GuiWindow::UpdateClientSizeAfterRendering(preferredSize, clientSize); } else { @@ -4480,7 +4484,10 @@ GuiPopup auto offsetY = currentWindowSize.y - currentClientSize.y; auto nativeClientSize = window->Convert(clientSize); auto position = CalculatePopupPosition(NativeSize(nativeClientSize.x + offsetX, nativeClientSize.y + offsetY), popupType, popupInfo); - SetBounds(position, clientSize); + if (position != GetLocation() || clientSize != GetClientSize()) + { + SetBounds(position, clientSize); + } } } @@ -4612,7 +4619,8 @@ GuiPopup void GuiPopup::ShowPopupInternal() { auto window = GetNativeWindow(); - UpdateClientSizeAfterRendering(window->Convert(window->GetClientSize())); + auto clientSize = window->Convert(window->GetClientSize()); + UpdateClientSizeAfterRendering(clientSize, clientSize); INativeWindow* controlWindow = nullptr; switch (popupType) @@ -10173,6 +10181,7 @@ GuiSelectableListControl shift = false; ctrl = false; } + if (shift) { if (!ctrl) @@ -20533,6 +20542,14 @@ GuiMenu Hide(); } + void GuiMenu::UpdateClientSizeAfterRendering(Size preferredSize, Size clientSize) + { + auto size = preferredSize; + if (size.x < preferredMenuClientSize.x) size.x = preferredMenuClientSize.x; + if (size.y < preferredMenuClientSize.y) size.x = preferredMenuClientSize.y; + GuiPopup::UpdateClientSizeAfterRendering(preferredSize, size); + } + void GuiMenu::OnWindowOpened(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments) { if(parentMenuService) @@ -20606,6 +20623,16 @@ GuiMenu hideOnDeactivateAltHost = value; } + Size GuiMenu::GetPreferredMenuClientSize() + { + return preferredMenuClientSize; + } + + void GuiMenu::SetPreferredMenuClientSize(Size value) + { + preferredMenuClientSize = value; + } + /*********************************************************************** GuiMenuBar ***********************************************************************/ @@ -20889,15 +20916,16 @@ GuiMenuButton void GuiMenuButton::SetSubMenu(GuiMenu* value, bool owned) { - if(subMenu) + if (subMenu) { DetachSubMenu(); subMenuDisposeFlag = nullptr; } - subMenu=value; - ownedSubMenu=owned; - if(subMenu) + subMenu = value; + ownedSubMenu = owned; + if (subMenu) { + subMenu->SetPreferredMenuClientSize(preferredMenuClientSize); subMenuDisposeFlag = subMenu->GetDisposedFlag(); subMenuWindowOpenedHandler = subMenu->WindowOpened.AttachMethod(this, &GuiMenuButton::OnSubMenuWindowOpened); subMenuWindowClosedHandler = subMenu->WindowClosed.AttachMethod(this, &GuiMenuButton::OnSubMenuWindowClosed); @@ -20955,7 +20983,11 @@ GuiMenuButton void GuiMenuButton::SetPreferredMenuClientSize(Size value) { - preferredMenuClientSize=value; + preferredMenuClientSize = value; + if (subMenu) + { + subMenu->SetPreferredMenuClientSize(preferredMenuClientSize); + } } bool GuiMenuButton::GetCascadeAction() @@ -32132,10 +32164,7 @@ GuiGraphicsHost auto preferred = windowComposition->GetPreferredBounds(); auto width = bounds.Width() > preferred.Width() ? bounds.Width() : preferred.Width(); auto height = bounds.Height() > preferred.Height() ? bounds.Height() : preferred.Height(); - if (width != bounds.Width() || height != bounds.Height()) - { - controlHost->UpdateClientSizeAfterRendering(Size(width, height)); - } + controlHost->UpdateClientSizeAfterRendering(preferred.GetSize(), Size(width, height)); } auto result = hostRecord.renderTarget->StopRendering(); hostRecord.nativeWindow->RedrawContent(); diff --git a/Import/GacUI.h b/Import/GacUI.h index 0297ebdc..0eb140c4 100644 --- a/Import/GacUI.h +++ b/Import/GacUI.h @@ -11237,7 +11237,7 @@ Control Host void Closed()override; void Destroying()override; - virtual void UpdateClientSizeAfterRendering(Size clientSize); + virtual void UpdateClientSizeAfterRendering(Size preferredSize, Size clientSize); public: /// Create a control with a specified default theme. /// The theme name for retriving a default control template. @@ -11557,7 +11557,7 @@ Window vint popupType = -1; PopupInfo popupInfo; - void UpdateClientSizeAfterRendering(Size clientSize)override; + void UpdateClientSizeAfterRendering(Size preferredSize, Size clientSize)override; void PopupOpened(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); void PopupClosed(compositions::GuiGraphicsComposition* sender, compositions::GuiEventArgs& arguments); void OnKeyDown(compositions::GuiGraphicsComposition* sender, compositions::GuiKeyEventArgs& arguments); @@ -15761,6 +15761,7 @@ Menu private: IGuiMenuService* parentMenuService = nullptr; bool hideOnDeactivateAltHost = true; + Size preferredMenuClientSize; IGuiMenuService* GetParentMenuService()override; Direction GetPreferredDirection()override; @@ -15768,6 +15769,7 @@ Menu bool IsSubMenuActivatedByMouseDown()override; void MenuItemExecuted()override; + void UpdateClientSizeAfterRendering(Size preferredSize, Size clientSize)override; protected: GuiControl* owner; @@ -15791,6 +15793,13 @@ Menu /// Set if this menu hide after pressing ESC key to exit to the upper level of ALT shortcuts. /// Set to true to make this menu hide after pressing ESC key to exit to the upper level of ALT shortcuts. void SetHideOnDeactivateAltHost(bool value); + + /// Get the preferred client size for the menu. + /// The preferred client size for the menu. + Size GetPreferredMenuClientSize(); + /// Set the preferred client size for the menu. + /// The preferred client size for the menu. + void SetPreferredMenuClientSize(Size value); }; /// Menu bar. diff --git a/TODO.md b/TODO.md index 2e437181..ad2ab92f 100644 --- a/TODO.md +++ b/TODO.md @@ -6,9 +6,6 @@ https://zhuanlan.zhihu.com/p/39369370 ### Bug -- [ ] Demo `control_toolstrip_menu_binding` - - add 10 items -> open menu -> delete some items -> open menu - - the menu is too large - [ ] `GlobalStringKey` need to remember the `GlobalStringKeyManager` object, and if the global object is changed, it means this key becomes a wild pointer, it should crash. - [ ] `let X = Y in (F(X.a.b.c))` reports `X does not exist in the current scope` in binding property value - while `F((let X = Y.a.b).c)` works