From 014d2b767cbd2e346238ad8769fcbbe6fd30c88d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Thu, 1 Jan 2026 14:17:10 -0300 Subject: [PATCH] Improve UIMenu positioning (allow to take into account the trigger button to position). --- include/eepp/ui/uimenu.hpp | 2 +- src/eepp/ui/uimenu.cpp | 45 +++++++++++++++++-- .../ecode/plugins/aiassistant/chatui.cpp | 4 +- 3 files changed, 45 insertions(+), 6 deletions(-) diff --git a/include/eepp/ui/uimenu.hpp b/include/eepp/ui/uimenu.hpp index 121c6382e..bc889b523 100644 --- a/include/eepp/ui/uimenu.hpp +++ b/include/eepp/ui/uimenu.hpp @@ -16,7 +16,7 @@ class EE_API UIMenu : public UIWidget { static UIMenu* New(); static void findBestMenuPos( Vector2f& position, UIWidget* menu, UIMenu* parent = NULL, - UIMenuSubMenu* subMenu = NULL ); + UIMenuSubMenu* subMenu = NULL, Node* trigger = NULL ); UIMenu(); diff --git a/src/eepp/ui/uimenu.cpp b/src/eepp/ui/uimenu.cpp index 5ea269f22..469197ff0 100644 --- a/src/eepp/ui/uimenu.cpp +++ b/src/eepp/ui/uimenu.cpp @@ -693,8 +693,8 @@ bool UIMenu::isChildOrSubMenu( Node* node ) { ( mCurrentSubMenu && mCurrentSubMenu->isChildOrSubMenu( node ) ); } -void UIMenu::findBestMenuPos( Vector2f& pos, UIWidget* menu, UIMenu* parent, - UIMenuSubMenu* subMenu ) { +void UIMenu::findBestMenuPos( Vector2f& pos, UIWidget* menu, UIMenu* parent, UIMenuSubMenu* subMenu, + Node* trigger ) { SceneNode* sceneNode = menu->getSceneNode(); if ( nullptr == sceneNode ) @@ -706,7 +706,46 @@ void UIMenu::findBestMenuPos( Vector2f& pos, UIWidget* menu, UIMenu* parent, Rectf qPos( pos.x, pos.y, pos.x + menu->getPixelsSize().getWidth(), pos.y + menu->getPixelsSize().getHeight() ); - if ( nullptr != parent && nullptr != subMenu ) { + if ( nullptr != trigger ) { + Rectf qTrigger = trigger->getScreenRect(); + // Try to position below the trigger + pos.y = qTrigger.Bottom; + qPos.Top = pos.y; + qPos.Bottom = qPos.Top + menu->getPixelsSize().getHeight(); + + if ( !qScreen.contains( qPos ) ) { + // Try to position above the trigger + pos.y = qTrigger.Top - menu->getPixelsSize().getHeight(); + qPos.Top = pos.y; + qPos.Bottom = qPos.Top + menu->getPixelsSize().getHeight(); + + if ( !qScreen.contains( qPos ) ) { + // Try to position to the right of the trigger + pos.x = qTrigger.Right; + pos.y = qTrigger.Top; + qPos.Left = pos.x; + qPos.Right = qPos.Left + menu->getPixelsSize().getWidth(); + qPos.Top = pos.y; + qPos.Bottom = qPos.Top + menu->getPixelsSize().getHeight(); + + if ( !qScreen.contains( qPos ) ) { + // Try to position to the left of the trigger + pos.x = qTrigger.Left - menu->getPixelsSize().getWidth(); + qPos.Left = pos.x; + qPos.Right = qPos.Left + menu->getPixelsSize().getWidth(); + + if ( !qScreen.contains( qPos ) ) { + // Reset to original position if no better position found + pos = oriPos; + qPos.Left = pos.x; + qPos.Right = qPos.Left + menu->getPixelsSize().getWidth(); + qPos.Top = pos.y; + qPos.Bottom = qPos.Top + menu->getPixelsSize().getHeight(); + } + } + } + } + } else if ( nullptr != parent && nullptr != subMenu ) { Rectf qPrevMenu; bool clipMenu = parent->getOwnerNode() && parent->getOwnerNode()->getParent() && parent->getOwnerNode()->getParent()->isType( UI_TYPE_MENU ); diff --git a/src/tools/ecode/plugins/aiassistant/chatui.cpp b/src/tools/ecode/plugins/aiassistant/chatui.cpp index 638824b70..6f16c8959 100644 --- a/src/tools/ecode/plugins/aiassistant/chatui.cpp +++ b/src/tools/ecode/plugins/aiassistant/chatui.cpp @@ -449,7 +449,7 @@ LLMChatUI::LLMChatUI( PluginManager* manager ) : menu->runOnMainThread( [this, menu] { auto pos( mChatAttach->getScreenPos() ); - UIMenu::findBestMenuPos( pos, menu ); + UIMenu::findBestMenuPos( pos, menu, nullptr, nullptr, mChatAttach ); menu->showAtScreenPosition( pos ); } ); } ); @@ -516,7 +516,7 @@ LLMChatUI::LLMChatUI( PluginManager* manager ) : menu->runOnMainThread( [this, menu] { auto pos( mChatMore->getScreenPos() ); - UIMenu::findBestMenuPos( pos, menu ); + UIMenu::findBestMenuPos( pos, menu, nullptr, nullptr, mChatMore ); menu->showAtScreenPosition( pos ); } ); } );