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