diff --git a/bin/assets/colorschemes/colorschemes.conf b/bin/assets/colorschemes/colorschemes.conf index e9b1c253c..45d79f4fc 100644 --- a/bin/assets/colorschemes/colorschemes.conf +++ b/bin/assets/colorschemes/colorschemes.conf @@ -24,14 +24,14 @@ operator = #93DDFA function = #93DDFA [eepp] -background = #2e2e32 +background = #282a36 text = #e1e1e6 caret = #93DDFA -selection = #48484f -line_highlight = #343438 +selection = #4c5163 +line_highlight = #2d303d line_number = #525259 line_number2 = #83838f -line_number_background = #2e2e32 +line_number_background = #282a36 whitespace = #54575b line_break_column = #54575b99 matching_bracket = #FFFFFF33 @@ -39,14 +39,14 @@ matching_selection = #FFFFFF33 normal = #cfcfcf symbol = #cfcfcf -comment = #cd8b00 -keyword = #8a98ff,bold -keyword2 = #8abdff,bold -number = #f0ad6d -literal = #808000,bold +comment = #94b633 +keyword = #66bfff,shadow +keyword2 = #8abdff,shadow +number = #ffd24a +literal = #f1fa8c,shadow string = #ffcd8b -operator = #cfbfad -function = #76c0d0,bold +operator = #f051bb +function = #6ae0f9,shadow [fall] background = #343233 diff --git a/bin/assets/ui/breeze.css b/bin/assets/ui/breeze.css index 870cffb65..b60721ffe 100644 --- a/bin/assets/ui/breeze.css +++ b/bin/assets/ui/breeze.css @@ -615,10 +615,10 @@ Menu::RadioButton { background-color: transparent; } -Menu::Item:hover, -Menu::CheckBox:hover, -Menu::SubMenu:hover, -Menu::RadioButton:hover { +Menu::Item:selected, +Menu::CheckBox:selected, +Menu::SubMenu:selected, +Menu::RadioButton:selected { background-color: var(--primary); } diff --git a/include/eepp/scene/event.hpp b/include/eepp/scene/event.hpp index ddbc41fe4..b739f2435 100644 --- a/include/eepp/scene/event.hpp +++ b/include/eepp/scene/event.hpp @@ -37,7 +37,6 @@ class EE_API Event { OnValueChange, OnWidgetFocusLoss, OnItemClicked, - OnHideByClick, OnItemKeyDown, OnItemKeyUp, OnItemSelected, diff --git a/include/eepp/scene/eventdispatcher.hpp b/include/eepp/scene/eventdispatcher.hpp index 9842d6768..18ad5afc7 100644 --- a/include/eepp/scene/eventdispatcher.hpp +++ b/include/eepp/scene/eventdispatcher.hpp @@ -68,6 +68,8 @@ class EE_API EventDispatcher { const Uint32& getDoubleClickTrigger() const; + const Uint32& getReleaseTrigger() const; + void setNodeDragging( Node* dragging ); bool isNodeDragging() const; diff --git a/include/eepp/ui/uimenu.hpp b/include/eepp/ui/uimenu.hpp index ca39680cb..158f7ff04 100644 --- a/include/eepp/ui/uimenu.hpp +++ b/include/eepp/ui/uimenu.hpp @@ -46,6 +46,8 @@ class EE_API UIMenu : public UIWidget { Uint32 getCount() const; + UIWidget* getItemSelected() const; + void remove( const Uint32& index ); void remove( UIWidget* widget ); @@ -72,12 +74,14 @@ class EE_API UIMenu : public UIWidget { UINode* getOwnerNode() const; /** The owner node is the node who triggers the visibility of the menu */ - void setOwnerNode( UINode* ownerNode ); + void setOwnerNode( UIWidget* ownerNode ); void setIconMinimumSize( const Sizei& minIconSize ); const Sizei& getIconMinimumSize() const; + void backpropagateHide(); + protected: friend class UIMenuItem; friend class UIMenuCheckBox; @@ -90,11 +94,11 @@ class EE_API UIMenu : public UIWidget { Int32 mBiggestIcon; UIWidget* mItemSelected; Uint32 mItemSelectedIndex; - bool mClickHide; bool mResizing; - Uint32 mLastTickMove; - UINode* mOwnerNode; + UIWidget* mOwnerNode; Sizei mIconMinSize; + UIMenu* mCurrentSubMenu{nullptr}; + Clock mInactiveTime; virtual void onSizeChange(); @@ -136,6 +140,16 @@ class EE_API UIMenu : public UIWidget { void nextSel(); void trySelect( UIWidget* node, bool up ); + + void safeHide(); + + virtual void onVisibilityChange(); + + virtual void scheduledUpdate( const Time& time ); + + bool isChildOfMeOrSubMenu( Node* node ); + + void unselectSelected(); }; }} // namespace EE::UI diff --git a/include/eepp/ui/uimenubar.hpp b/include/eepp/ui/uimenubar.hpp index da312bb22..1c29d8d15 100644 --- a/include/eepp/ui/uimenubar.hpp +++ b/include/eepp/ui/uimenubar.hpp @@ -20,15 +20,15 @@ class EE_API UIMenuBar : public UIWidget { virtual bool isType( const Uint32& type ) const; - void addMenuButton( const String& ButtonText, UIPopUpMenu* Menu ); + void addMenuButton( const String& buttonText, UIPopUpMenu* Menu ); - void removeMenuButton( const String& ButtonText ); + void removeMenuButton( const String& buttonText ); - virtual void setTheme( UITheme* Theme ); + virtual void setTheme( UITheme* theme ); - UISelectButton* getButton( const String& ButtonText ); + UISelectButton* getButton( const String& buttonText ); - UIPopUpMenu* getPopUpMenu( const String& ButtonText ); + UIPopUpMenu* getPopUpMenu( const String& buttonText ); Uint32 getMenuHeight() const; @@ -54,16 +54,10 @@ class EE_API UIMenuBar : public UIWidget { virtual void onPaddingChange(); - virtual void onWidgetFocusLoss(); - UIPopUpMenu* getMenuFromButton( UISelectButton* Button ); bool isPopUpMenuChild( Node* node ); - void onMenuFocusLoss( const Event* Event ); - - void onHideByClick( const Event* Event ); - void unselectButtons(); void destroyMenues(); diff --git a/include/eepp/ui/uimenuitem.hpp b/include/eepp/ui/uimenuitem.hpp index 41530e11e..bc6ce82fe 100644 --- a/include/eepp/ui/uimenuitem.hpp +++ b/include/eepp/ui/uimenuitem.hpp @@ -30,7 +30,11 @@ class EE_API UIMenuItem : public UIPushButton { virtual void onSizeChange(); - virtual Uint32 onMouseOver( const Vector2i& position, const Uint32& flags ); + virtual Uint32 onMouseOver( const Vector2i& pos, const Uint32& flags ); + + virtual Uint32 onMouseLeave( const Vector2i& pos, const Uint32& flags ); + + virtual Uint32 onMouseClick( const Vector2i& pos, const Uint32& flags ); virtual UIWidget* getExtraInnerWidget(); diff --git a/include/eepp/ui/uimenusubmenu.hpp b/include/eepp/ui/uimenusubmenu.hpp index 6988aecc5..ab5722c78 100644 --- a/include/eepp/ui/uimenusubmenu.hpp +++ b/include/eepp/ui/uimenusubmenu.hpp @@ -29,8 +29,6 @@ class EE_API UIMenuSubMenu : public UIMenuItem { void showSubMenu(); - virtual bool inheritsFrom( const Uint32 getType ); - const Time& getMouseOverTimeShowMenu() const; void setMouseOverTimeShowMenu( const Time& maxTime ); @@ -39,13 +37,13 @@ class EE_API UIMenuSubMenu : public UIMenuItem { UIMenu* mSubMenu; UIWidget* mArrow; Time mMaxTime; - Uint32 mCbId; - Uint32 mCbId2; Action* mCurWait; - virtual Uint32 onMouseOver( const Vector2i& position, const Uint32& flags ); + virtual Uint32 onMouseOver( const Vector2i& pos, const Uint32& flags ); - virtual Uint32 onMouseLeave( const Vector2i& position, const Uint32& flags ); + virtual Uint32 onMouseLeave( const Vector2i& pos, const Uint32& flags ); + + virtual Uint32 onMouseClick( const Vector2i& pos, const Uint32& flags ); virtual void onStateChange(); diff --git a/include/eepp/ui/uipopupmenu.hpp b/include/eepp/ui/uipopupmenu.hpp index 27bcb1ccd..8171ddb41 100644 --- a/include/eepp/ui/uipopupmenu.hpp +++ b/include/eepp/ui/uipopupmenu.hpp @@ -23,14 +23,10 @@ class EE_API UIPopUpMenu : public UIMenu { virtual bool hide(); + bool isHiding() const; + protected: - virtual void onWidgetFocusLoss(); - - virtual Uint32 onMessage( const NodeMessage* Msg ); - -#ifdef EE_PLATFORM_TOUCH - Clock mTE; -#endif + Action* mHidingAction{nullptr}; }; }} // namespace EE::UI diff --git a/src/eepp/scene/eventdispatcher.cpp b/src/eepp/scene/eventdispatcher.cpp index ea056e0c4..45cc650d2 100644 --- a/src/eepp/scene/eventdispatcher.cpp +++ b/src/eepp/scene/eventdispatcher.cpp @@ -263,6 +263,10 @@ const Uint32& EventDispatcher::getDoubleClickTrigger() const { return mInput->getDoubleClickTrigger(); } +const Uint32& EventDispatcher::getReleaseTrigger() const { + return mInput->getReleaseTrigger(); +} + void EventDispatcher::setNodeDragging( Node* dragging ) { mNodeDragging = dragging; } diff --git a/src/eepp/ui/uimenu.cpp b/src/eepp/ui/uimenu.cpp index 299df138e..c4fcd9bdb 100644 --- a/src/eepp/ui/uimenu.cpp +++ b/src/eepp/ui/uimenu.cpp @@ -19,12 +19,10 @@ UIMenu::UIMenu() : mMaxWidth( 0 ), mNextPosY( 0 ), mBiggestIcon( 0 ), - mItemSelected( NULL ), + mItemSelected( nullptr ), mItemSelectedIndex( eeINDEX_NOT_FOUND ), - mClickHide( false ), mResizing( false ), - mLastTickMove( 0 ), - mOwnerNode( NULL ) { + mOwnerNode( nullptr ) { mFlags |= UI_AUTO_SIZE; onSizeChange(); @@ -44,16 +42,13 @@ bool UIMenu::isType( const Uint32& type ) const { void UIMenu::setTheme( UITheme* theme ) { UIWidget::setTheme( theme ); - setThemeSkin( theme, "menu" ); onThemeLoaded(); } void UIMenu::onThemeLoaded() { UIWidget::onThemeLoaded(); - autoPadding(); - onSizeChange(); } @@ -102,10 +97,8 @@ UIMenuRadioButton* UIMenu::createMenuRadioButton( const String& text, const bool widget->setParent( this ); widget->setIconMinimumSize( mIconMinSize ); widget->setText( text ); - if ( active ) widget->setActive( active ); - return widget; } @@ -135,55 +128,42 @@ UIMenuSubMenu* UIMenu::addSubMenu( const String& text, Drawable* icon, UIMenu* s bool UIMenu::widgetCheckSize( UIWidget* widget, const bool& resize ) { if ( widget->isType( UI_TYPE_MENUITEM ) ) { UIMenuItem* tItem = widget->asType(); - - if ( NULL != tItem->getIcon() && tItem->getIcon()->getLayoutMargin().Left + - tItem->getIcon()->getLayoutMargin().Right + - tItem->getIcon()->getSize().getWidth() > - (Int32)mBiggestIcon ) { + if ( nullptr != tItem->getIcon() && tItem->getIcon()->getLayoutMargin().Left + + tItem->getIcon()->getLayoutMargin().Right + + tItem->getIcon()->getSize().getWidth() > + (Int32)mBiggestIcon ) { mBiggestIcon = tItem->getIcon()->getLayoutMargin().Left + tItem->getIcon()->getLayoutMargin().Right + tItem->getIcon()->getSize().getWidth(); } - if ( mFlags & UI_AUTO_SIZE ) { if ( widget->getPixelsSize().getWidth() > (Int32)mMaxWidth ) { mMaxWidth = widget->getPixelsSize().getWidth(); - if ( resize ) { widgetsResize(); - return true; } } } } - return false; } UIWidget* UIMenu::add( UIWidget* widget ) { if ( this != widget->getParent() ) widget->setParent( this ); - widgetCheckSize( widget ); - setWidgetSize( widget ); - widget->setPixelsPosition( mRealPadding.Left, mRealPadding.Top + mNextPosY ); - mNextPosY += widget->getPixelsSize().getHeight(); - mItems.push_back( widget ); - widget->addEventListener( Event::OnSizeChange, [&]( const Event* ) { if ( !mResizing ) { widgetsSetPos(); widgetsResize(); } } ); - resizeMe(); - return widget; } @@ -199,20 +179,15 @@ UIMenuSeparator* UIMenu::addSeparator() { separator->setPixelsPosition( mRealPadding.Left, mRealPadding.Top + mNextPosY ); separator->setPixelsSize( mSize.getWidth() - mRealPadding.Left - mRealPadding.Right, PixelDensity::dpToPxI( separator->getSkinSize().getHeight() ) ); - mNextPosY += separator->getPixelsSize().getHeight(); - mItems.push_back( separator ); - resizeMe(); - separator->addEventListener( Event::OnSizeChange, [&]( const Event* ) { if ( !mResizing ) { widgetsSetPos(); widgetsResize(); } } ); - return separator; } @@ -225,13 +200,11 @@ UIWidget* UIMenu::getItem( const String& text ) { for ( Uint32 i = 0; i < mItems.size(); i++ ) { if ( mItems[i]->isType( UI_TYPE_MENUITEM ) ) { UIMenuItem* tMenuItem = mItems[i]->asType(); - if ( tMenuItem->getText() == text ) return tMenuItem; } } - - return NULL; + return nullptr; } Uint32 UIMenu::getItemIndex( UIWidget* item ) { @@ -239,7 +212,6 @@ Uint32 UIMenu::getItemIndex( UIWidget* item ) { if ( mItems[i] == item ) return i; } - return eeINDEX_NOT_FOUND; } @@ -247,13 +219,14 @@ Uint32 UIMenu::getCount() const { return mItems.size(); } +UIWidget* UIMenu::getItemSelected() const { + return mItemSelected; +} + void UIMenu::remove( const Uint32& index ) { eeASSERT( index < mItems.size() ); - mItems[index]->close(); - mItems.erase( mItems.begin() + index ); - widgetsSetPos(); widgetsResize(); } @@ -271,11 +244,9 @@ void UIMenu::removeAll() { for ( Uint32 i = 0; i < mItems.size(); i++ ) { mItems[i]->close(); } - mItems.clear(); mNextPosY = 0; mMaxWidth = 0; - resizeMe(); } @@ -285,52 +256,55 @@ void UIMenu::insert( const String& text, Drawable* icon, const Uint32& index ) { void UIMenu::insert( UIWidget* widget, const Uint32& index ) { mItems.insert( mItems.begin() + index, widget ); - childAddAt( widget, index ); - widgetsSetPos(); widgetsResize(); } bool UIMenu::isSubMenu( Node* node ) { for ( Uint32 i = 0; i < mItems.size(); i++ ) { - if ( NULL != mItems[i] && mItems[i]->isType( UI_TYPE_MENUSUBMENU ) ) { - UIMenuSubMenu* tMenu = mItems[i]->asType(); - - if ( tMenu->getSubMenu() == node ) + if ( nullptr != mItems[i] ) { + if ( mItems[i] == node || ( mItems[i]->isType( UI_TYPE_MENUSUBMENU ) && + mItems[i]->asType()->getSubMenu() == node ) ) return true; } } - + if ( mOwnerNode && mOwnerNode->isType( UI_TYPE_MENUSUBMENU ) ) { + if ( mOwnerNode->getParent() == node || + mOwnerNode->getParent()->asType()->isSubMenu( node ) ) + return true; + } return false; } -Uint32 UIMenu::onMessage( const NodeMessage* Msg ) { - switch ( Msg->getMsg() ) { - case NodeMessage::MouseUp: { - if ( Msg->getSender()->getParent() == this && ( Msg->getFlags() & EE_BUTTONS_LRM ) ) { - Event ItemEvent( Msg->getSender(), Event::OnItemClicked ); - sendEvent( &ItemEvent ); +Uint32 UIMenu::onMessage( const NodeMessage* msg ) { + switch ( msg->getMsg() ) { + case NodeMessage::MouseOver: { + if ( mOwnerNode && mOwnerNode->isType( UI_TYPE_MENUSUBMENU ) ) { + mOwnerNode->getParent()->asType()->setItemSelected( mOwnerNode ); } - - return 1; + break; } - case NodeMessage::FocusLoss: { - if ( NULL != getEventDispatcher() ) { - Node* focusNode = getEventDispatcher()->getFocusNode(); - - if ( this != focusNode && !isParentOf( focusNode ) && !isSubMenu( focusNode ) && - mOwnerNode != focusNode ) { - mClickHide = true; - - onWidgetFocusLoss(); - } - + case NodeMessage::MouseUp: { + if ( msg->getSender()->getParent() == this && ( msg->getFlags() & EE_BUTTONS_LRM ) ) { + Event itemEvent( msg->getSender(), Event::OnItemClicked ); + sendEvent( &itemEvent ); return 1; } + break; + } + case NodeMessage::FocusLoss: { + if ( nullptr != getEventDispatcher() ) { + Node* focusNode = getEventDispatcher()->getFocusNode(); + if ( this != focusNode && !isParentOf( focusNode ) && !isSubMenu( focusNode ) && + mOwnerNode != focusNode ) { + backpropagateHide(); + return 1; + } + } + break; } } - return 0; } @@ -368,7 +342,6 @@ void UIMenu::widgetsSetPos() { if ( mFlags & UI_AUTO_SIZE ) { mMaxWidth = 0; - for ( i = 0; i < mItems.size(); i++ ) { widgetCheckSize( mItems[i], false ); } @@ -376,9 +349,7 @@ void UIMenu::widgetsSetPos() { for ( i = 0; i < mItems.size(); i++ ) { UIWidget* widget = mItems[i]; - widget->setPixelsPosition( mRealPadding.Left, mRealPadding.Top + mNextPosY ); - mNextPosY += widget->getPixelsSize().getHeight(); } @@ -403,33 +374,43 @@ bool UIMenu::show() { bool UIMenu::hide() { setEnabled( false ); setVisible( false ); - - if ( NULL != mItemSelected ) - mItemSelected->popState( UIState::StateSelected ); - - mItemSelected = NULL; - mItemSelectedIndex = eeINDEX_NOT_FOUND; - + safeHide(); return true; } -void UIMenu::setItemSelected( UIWidget* Item ) { - if ( NULL != mItemSelected ) { - if ( mItemSelected->isType( UI_TYPE_MENUSUBMENU ) ) { - UIMenuSubMenu* tMenu = mItemSelected->asType(); - - if ( NULL != tMenu->getSubMenu() ) - tMenu->getSubMenu()->hide(); - } - - mItemSelected->popState( UIState::StateSelected ); +void UIMenu::safeHide() { + if ( mOwnerNode && mOwnerNode->isType( UI_TYPE_MENUSUBMENU ) ) { + UIMenu* menu = mOwnerNode->getParent()->asType(); + if ( menu->mCurrentSubMenu == this ) + menu->mCurrentSubMenu = nullptr; + if ( mOwnerNode == menu->getItemSelected() ) + menu->unselectSelected(); + menu->setFocus(); } + if ( nullptr == mOwnerNode || !mOwnerNode->isType( UI_TYPE_MENUSUBMENU ) ) { + eePRINTL( "sup" ); + } + unselectSelected(); + if ( mCurrentSubMenu ) { + mCurrentSubMenu->hide(); + mCurrentSubMenu = nullptr; + } +} - if ( NULL != Item ) - Item->pushState( UIState::StateSelected ); +void UIMenu::unselectSelected() { + if ( nullptr != mItemSelected ) + mItemSelected->popState( UIState::StateSelected ); + mItemSelected = nullptr; + mItemSelectedIndex = eeINDEX_NOT_FOUND; +} - if ( mItemSelected != Item ) { - mItemSelected = Item; +void UIMenu::setItemSelected( UIWidget* item ) { + if ( nullptr != mItemSelected ) + mItemSelected->popState( UIState::StateSelected ); + if ( nullptr != item ) + item->pushState( UIState::StateSelected ); + if ( mItemSelected != item ) { + mItemSelected = item; mItemSelectedIndex = getItemIndex( mItemSelected ); } } @@ -439,28 +420,25 @@ void UIMenu::trySelect( UIWidget* node, bool up ) { if ( !node->isType( UI_TYPE_MENU_SEPARATOR ) ) { setItemSelected( node ); } else { - Uint32 Index = getItemIndex( node ); - - if ( Index != eeINDEX_NOT_FOUND ) { + Uint32 index = getItemIndex( node ); + if ( index != eeINDEX_NOT_FOUND ) { if ( up ) { - if ( Index > 0 ) { - for ( Int32 i = (Int32)Index - 1; i >= 0; i-- ) { + if ( index > 0 ) { + for ( Int32 i = (Int32)index - 1; i >= 0; i-- ) { if ( !mItems[i]->isType( UI_TYPE_MENU_SEPARATOR ) ) { setItemSelected( mItems[i] ); return; } } } - setItemSelected( mItems[mItems.size()] ); } else { - for ( Uint32 i = Index + 1; i < mItems.size(); i++ ) { + for ( Uint32 i = index + 1; i < mItems.size(); i++ ) { if ( !mItems[i]->isType( UI_TYPE_MENU_SEPARATOR ) ) { setItemSelected( mItems[i] ); return; } } - setItemSelected( mItems[0] ); } } @@ -468,6 +446,13 @@ void UIMenu::trySelect( UIWidget* node, bool up ) { } } +void UIMenu::backpropagateHide() { + hide(); + if ( mOwnerNode && mOwnerNode->getParent()->isType( UI_TYPE_MENU ) ) { + mOwnerNode->getParent()->asType()->backpropagateHide(); + } +} + void UIMenu::nextSel() { if ( mItems.size() ) { if ( mItemSelectedIndex != eeINDEX_NOT_FOUND ) { @@ -496,79 +481,57 @@ void UIMenu::prevSel() { } } -Uint32 UIMenu::onKeyDown( const KeyEvent& Event ) { - if ( Sys::getTicks() - mLastTickMove > 50 ) { - switch ( Event.getKeyCode() ) { - case KEY_DOWN: - mLastTickMove = Sys::getTicks(); - nextSel(); - - break; - case KEY_UP: - mLastTickMove = Sys::getTicks(); - prevSel(); - - break; - case KEY_RIGHT: - if ( NULL != mItemSelected && ( mItemSelected->isType( UI_TYPE_MENUSUBMENU ) ) ) { - UIMenuSubMenu* tMenu = mItemSelected->asType(); - - tMenu->showSubMenu(); - } - - break; - case KEY_LEFT: - hide(); - - break; - case KEY_ESCAPE: - hide(); - - break; - case KEY_RETURN: - if ( NULL != mItemSelected && NULL != getEventDispatcher() ) { - mItemSelected->sendMouseEvent( - Event::MouseClick, getEventDispatcher()->getMousePos(), EE_BUTTONS_ALL ); - - NodeMessage Msg( mItemSelected, NodeMessage::MouseUp, EE_BUTTONS_ALL ); - mItemSelected->messagePost( &Msg ); - } - - break; - default: - break; - } +Uint32 UIMenu::onKeyDown( const KeyEvent& event ) { + switch ( event.getKeyCode() ) { + case KEY_DOWN: + nextSel(); + break; + case KEY_UP: + prevSel(); + break; + case KEY_RIGHT: + if ( nullptr != mItemSelected && mItemSelected->isType( UI_TYPE_MENUSUBMENU ) ) + mItemSelected->asType()->showSubMenu(); + break; + case KEY_LEFT: + case KEY_ESCAPE: + hide(); + break; + case KEY_KP_ENTER: + case KEY_RETURN: + if ( nullptr != mItemSelected && nullptr != getEventDispatcher() ) { + mItemSelected->sendMouseEvent( + Event::MouseClick, getEventDispatcher()->getMousePos(), EE_BUTTON_LMASK ); + NodeMessage msg( mItemSelected, NodeMessage::MouseUp, EE_BUTTON_LMASK ); + mItemSelected->messagePost( &msg ); + } + break; + default: + break; } - - return UIWidget::onKeyDown( Event ); + return UIWidget::onKeyDown( event ); } static Drawable* getIconDrawable( const std::string& name, UIIconThemeManager* iconThemeManager ) { - Drawable* iconDrawable = NULL; - - if ( NULL != iconThemeManager ) + Drawable* iconDrawable = nullptr; + if ( nullptr != iconThemeManager ) iconDrawable = iconThemeManager->findIcon( name ); - - if ( NULL == iconDrawable ) + if ( nullptr == iconDrawable ) iconDrawable = DrawableSearcher::searchByName( name ); - return iconDrawable; } void UIMenu::loadFromXmlNode( const pugi::xml_node& node ) { beginAttributesTransaction(); - UIWidget::loadFromXmlNode( node ); for ( pugi::xml_node item = node.first_child(); item; item = item.next_sibling() ) { std::string name( item.name() ); String::toLowerInPlace( name ); - if ( name == "menuitem" || name == "item" ) { std::string text( item.attribute( "text" ).as_string() ); std::string icon( item.attribute( "icon" ).as_string() ); - - if ( NULL != mSceneNode && mSceneNode->isUISceneNode() ) + if ( nullptr != mSceneNode && mSceneNode->isUISceneNode() ) add( static_cast( mSceneNode )->getTranslatorString( text ), getIconDrawable( icon, getUISceneNode()->getUIIconThemeManager() ) ); } else if ( name == "menuseparator" || name == "separator" ) { @@ -576,34 +539,34 @@ void UIMenu::loadFromXmlNode( const pugi::xml_node& node ) { } else if ( name == "menucheckbox" || name == "checkbox" ) { std::string text( item.attribute( "text" ).as_string() ); bool active( item.attribute( "active" ).as_bool() ); - - if ( NULL != mSceneNode && mSceneNode->isUISceneNode() ) + if ( nullptr != mSceneNode && mSceneNode->isUISceneNode() ) addCheckBox( static_cast( mSceneNode )->getTranslatorString( text ), active ); + } else if ( name == "menuradiobutton" || name == "radiobutton" ) { + std::string text( item.attribute( "text" ).as_string() ); + bool active( item.attribute( "active" ).as_bool() ); + if ( nullptr != mSceneNode && mSceneNode->isUISceneNode() ) + addRadioButton( + static_cast( mSceneNode )->getTranslatorString( text ), active ); } else if ( name == "menusubmenu" || name == "submenu" ) { std::string text( item.attribute( "text" ).as_string() ); std::string icon( item.attribute( "icon" ).as_string() ); - UIPopUpMenu* subMenu = UIPopUpMenu::New(); - - if ( NULL != getDrawInvalidator() ) + if ( nullptr != getDrawInvalidator() ) subMenu->setParent( getDrawInvalidator() ); - subMenu->loadFromXmlNode( item ); - - if ( NULL != mSceneNode && mSceneNode->isUISceneNode() ) + if ( nullptr != mSceneNode && mSceneNode->isUISceneNode() ) addSubMenu( static_cast( mSceneNode )->getTranslatorString( text ), getIconDrawable( icon, getUISceneNode()->getUIIconThemeManager() ), subMenu ); } } - endAttributesTransaction(); } std::string UIMenu::getPropertyString( const PropertyDefinition* propertyDef, const Uint32& propertyIndex ) { - if ( NULL == propertyDef ) + if ( nullptr == propertyDef ) return ""; switch ( propertyDef->getPropertyId() ) { @@ -634,22 +597,17 @@ UINode* UIMenu::getOwnerNode() const { return mOwnerNode; } -void UIMenu::setOwnerNode( UINode* ownerNode ) { +void UIMenu::setOwnerNode( UIWidget* ownerNode ) { mOwnerNode = ownerNode; } void UIMenu::setIconMinimumSize( const Sizei& minIconSize ) { mIconMinSize = minIconSize; mBiggestIcon = eemax( mBiggestIcon, mIconMinSize.getWidth() ); - for ( Uint32 i = 0; i < mItems.size(); i++ ) { - if ( mItems[i]->isType( UI_TYPE_MENUITEM ) ) { - UIMenuItem* menuItem = static_cast( mItems[i] ); - - menuItem->setIconMinimumSize( mIconMinSize ); - } + if ( mItems[i]->isType( UI_TYPE_MENUITEM ) ) + mItems[i]->asType()->setIconMinimumSize( mIconMinSize ); } - widgetsSetPos(); widgetsResize(); } @@ -658,74 +616,101 @@ const Sizei& UIMenu::getIconMinimumSize() const { return mIconMinSize; } -void UIMenu::fixMenuPos( Vector2f& Pos, UIMenu* menu, UIMenu* Parent, UIMenuSubMenu* subMenu ) { +void UIMenu::onVisibilityChange() { + UIWidget::onVisibilityChange(); + if ( mOwnerNode && mOwnerNode->isType( UI_TYPE_MENUSUBMENU ) ) { + if ( mVisible ) { + mInactiveTime.restart(); + subscribeScheduledUpdate(); + } else { + unsubscribeScheduledUpdate(); + } + } +} + +void UIMenu::scheduledUpdate( const Time& ) { + if ( !mVisible ) + return; + Node* node = getEventDispatcher()->getMouseOverNode(); + if ( node && ( isChildOfMeOrSubMenu( node ) || getItemSelected() ) ) + mInactiveTime.restart(); + if ( mInactiveTime.getElapsedTime() > Seconds( 1 ) ) + hide(); +} + +bool UIMenu::isChildOfMeOrSubMenu( Node* node ) { + return isParentOf( node ) || mOwnerNode == node || + ( mCurrentSubMenu && mCurrentSubMenu->isChildOfMeOrSubMenu( node ) ); +} + +void UIMenu::fixMenuPos( Vector2f& pos, UIMenu* menu, UIMenu* parent, UIMenuSubMenu* subMenu ) { SceneNode* sceneNode = menu->getSceneNode(); - if ( NULL == sceneNode ) + if ( nullptr == sceneNode ) return; Rectf qScreen( 0.f, 0.f, sceneNode->getPixelsSize().getWidth(), sceneNode->getPixelsSize().getHeight() ); - Rectf qPos( Pos.x, Pos.y, Pos.x + menu->getPixelsSize().getWidth(), - Pos.y + menu->getPixelsSize().getHeight() ); + Rectf qPos( pos.x, pos.y, pos.x + menu->getPixelsSize().getWidth(), + pos.y + menu->getPixelsSize().getHeight() ); - if ( NULL != Parent && NULL != subMenu ) { + if ( nullptr != parent && nullptr != subMenu ) { Vector2f sPos = subMenu->getPixelsPosition(); subMenu->nodeToWorldTranslation( sPos ); - Vector2f pPos = Parent->getPixelsPosition(); - Parent->nodeToWorldTranslation( pPos ); + Vector2f pPos = parent->getPixelsPosition(); + parent->nodeToWorldTranslation( pPos ); - Rectf qParent( pPos.x, pPos.y, pPos.x + Parent->getPixelsSize().getWidth(), - pPos.y + Parent->getPixelsSize().getHeight() ); + Rectf qParent( pPos.x, pPos.y, pPos.x + parent->getPixelsSize().getWidth(), + pPos.y + parent->getPixelsSize().getHeight() ); - Pos.x = qParent.Right; - Pos.y = sPos.y; - qPos.Left = Pos.x; + pos.x = qParent.Right; + pos.y = sPos.y; + qPos.Left = pos.x; qPos.Right = qPos.Left + menu->getPixelsSize().getWidth(); - qPos.Top = Pos.y; + qPos.Top = pos.y; qPos.Bottom = qPos.Top + menu->getPixelsSize().getHeight(); - Vector2f oriPos( Pos ); + Vector2f oriPos( pos ); if ( !qScreen.contains( qPos ) ) { - Pos.y = + pos.y = sPos.y + subMenu->getPixelsSize().getHeight() - menu->getPixelsSize().getHeight(); - qPos.Top = Pos.y; + qPos.Top = pos.y; qPos.Bottom = qPos.Top + menu->getPixelsSize().getHeight(); if ( !qScreen.contains( qPos ) ) { - Pos.x = qParent.Left - menu->getPixelsSize().getWidth(); - Pos.y = sPos.y; - qPos.Left = Pos.x; + pos.x = qParent.Left - menu->getPixelsSize().getWidth(); + pos.y = sPos.y; + qPos.Left = pos.x; qPos.Right = qPos.Left + menu->getPixelsSize().getWidth(); - qPos.Top = Pos.y; + qPos.Top = pos.y; qPos.Bottom = qPos.Top + menu->getPixelsSize().getHeight(); if ( !qScreen.contains( qPos ) ) { - Pos.y = sPos.y + subMenu->getPixelsSize().getHeight() - + pos.y = sPos.y + subMenu->getPixelsSize().getHeight() - menu->getPixelsSize().getHeight(); - qPos.Top = Pos.y; + qPos.Top = pos.y; qPos.Bottom = qPos.Top + menu->getPixelsSize().getHeight(); if ( !qScreen.contains( qPos ) ) { - Pos = oriPos; + pos = oriPos; } } } } } else { if ( !qScreen.contains( qPos ) ) { - Pos.y -= menu->getPixelsSize().getHeight(); + pos.y -= menu->getPixelsSize().getHeight(); qPos.Top -= menu->getPixelsSize().getHeight(); qPos.Bottom -= menu->getPixelsSize().getHeight(); if ( !qScreen.contains( qPos ) ) { - Pos.x -= menu->getPixelsSize().getWidth(); + pos.x -= menu->getPixelsSize().getWidth(); qPos.Left -= menu->getPixelsSize().getWidth(); qPos.Right -= menu->getPixelsSize().getWidth(); if ( !qScreen.contains( qPos ) ) { - Pos.y += menu->getPixelsSize().getHeight(); + pos.y += menu->getPixelsSize().getHeight(); qPos.Top += menu->getPixelsSize().getHeight(); qPos.Bottom += menu->getPixelsSize().getHeight(); } diff --git a/src/eepp/ui/uimenubar.cpp b/src/eepp/ui/uimenubar.cpp index a8e5b495d..97a5f3424 100644 --- a/src/eepp/ui/uimenubar.cpp +++ b/src/eepp/ui/uimenubar.cpp @@ -13,7 +13,7 @@ UIMenuBar* UIMenuBar::New() { } UIMenuBar::UIMenuBar() : - UIWidget( "menubar" ), mMenuHeight( 0 ), mCurrentMenu( NULL ), mWaitingUp( NULL ) { + UIWidget( "menubar" ), mMenuHeight( 0 ), mCurrentMenu( nullptr ), mWaitingUp( nullptr ) { if ( !( mFlags & UI_ANCHOR_RIGHT ) ) mFlags |= UI_ANCHOR_RIGHT; @@ -46,77 +46,88 @@ bool UIMenuBar::isType( const Uint32& type ) const { return UIMenuBar::getType() == type ? true : UIWidget::isType( type ); } -void UIMenuBar::addMenuButton( const String& ButtonText, UIPopUpMenu* Menu ) { - eeASSERT( NULL != Menu ); +void UIMenuBar::addMenuButton( const String& buttonText, UIPopUpMenu* menu ) { + eeASSERT( nullptr != menu ); - UISelectButton* Button = UISelectButton::NewWithTag( "menubar::button" ); - Button->setParent( this ); - Button->setText( ButtonText ); - Button->setVisible( true ); - Button->setEnabled( true ); - Button->addEventListener( Event::OnSizeChange, [&]( const Event* ) { refreshButtons(); } ); + UISelectButton* button = UISelectButton::NewWithTag( "menubar::button" ); + button->setParent( this ); + button->setText( buttonText ); + button->setVisible( true ); + button->setEnabled( true ); + button->addEventListener( Event::OnSizeChange, [&]( const Event* ) { refreshButtons(); } ); + button->addEventListener( Event::OnFocus, [&, button]( const Event* ) { + if ( getEventDispatcher()->getReleaseTrigger() & EE_BUTTON_LMASK ) { + getMenuFromButton( button )->setFocus(); + } + } ); - Menu->setVisible( false ); - Menu->setEnabled( false ); - Menu->setOwnerNode( Button ); + menu->setVisible( false ); + menu->setEnabled( false ); + menu->setOwnerNode( button ); // This will force to change the parent when shown, and force the CSS style reload. - Menu->setParent( this ); - Menu->addEventListener( Event::OnWidgetFocusLoss, - cb::Make1( this, &UIMenuBar::onMenuFocusLoss ) ); - Menu->addEventListener( Event::OnHideByClick, cb::Make1( this, &UIMenuBar::onHideByClick ) ); + menu->setParent( this ); + menu->addEventListener( Event::OnVisibleChange, [&, button]( const Event* event ) { + if ( event->getNode()->isVisible() ) { + button->select(); + mCurrentMenu = event->getNode()->asType(); + } else if ( button->isSelected() ) { + button->unselect(); + } + } ); + menu->addEventListener( Event::OnItemClicked, [&] ( const Event* ) { + mWaitingUp = nullptr; + mCurrentMenu = nullptr; + } ); - mButtons.push_back( std::make_pair( Button, Menu ) ); + mButtons.push_back( std::make_pair( button, menu ) ); - if ( NULL != mTheme ) - Button->setThemeSkin( mTheme, "menubarbutton" ); + if ( nullptr != mTheme ) + button->setThemeSkin( mTheme, "menubarbutton" ); refreshButtons(); } -void UIMenuBar::setTheme( UITheme* Theme ) { - UIWidget::setTheme( Theme ); +void UIMenuBar::setTheme( UITheme* theme ) { + UIWidget::setTheme( theme ); - setThemeSkin( Theme, "menubar" ); + setThemeSkin( theme, "menubar" ); for ( MenuBarList::iterator it = mButtons.begin(); it != mButtons.end(); ++it ) { - it->first->setThemeSkin( Theme, "menubarbutton" ); + it->first->setThemeSkin( theme, "menubarbutton" ); } autoHeight(); onThemeLoaded(); } -void UIMenuBar::removeMenuButton( const String& ButtonText ) { +void UIMenuBar::removeMenuButton( const String& buttonText ) { for ( MenuBarList::iterator it = mButtons.begin(); it != mButtons.end(); ++it ) { - if ( it->first->getText() == ButtonText ) { + if ( it->first->getText() == buttonText ) { it->first->close(); it->second->close(); - mButtons.erase( it ); - refreshButtons(); - break; } } } -UISelectButton* UIMenuBar::getButton( const String& ButtonText ) { +UISelectButton* UIMenuBar::getButton( const String& buttonText ) { for ( MenuBarList::iterator it = mButtons.begin(); it != mButtons.end(); ++it ) { - if ( it->first->getText() == ButtonText ) { + if ( it->first->getText() == buttonText ) { return it->first; } } - return NULL; + return nullptr; } -UIPopUpMenu* UIMenuBar::getPopUpMenu( const String& ButtonText ) { +UIPopUpMenu* UIMenuBar::getPopUpMenu( const String& buttonText ) { for ( MenuBarList::iterator it = mButtons.begin(); it != mButtons.end(); ++it ) { - if ( it->first->getText() == ButtonText ) { + if ( it->first->getText() == buttonText ) { return it->second; } } - return NULL; + return nullptr; } Uint32 UIMenuBar::getMenuHeight() const { @@ -182,7 +193,7 @@ bool UIMenuBar::applyProperty( const StyleSheetProperty& attribute ) { Uint32 UIMenuBar::onMessage( const NodeMessage* msg ) { switch ( msg->getMsg() ) { case NodeMessage::MouseUp: - mWaitingUp = NULL; + mWaitingUp = nullptr; case NodeMessage::MouseDown: case NodeMessage::MouseOver: { if ( msg->getSender()->isType( UI_TYPE_SELECTBUTTON ) ) { @@ -194,7 +205,7 @@ Uint32 UIMenuBar::onMessage( const NodeMessage* msg ) { tpop->setPosition( pos ); if ( msg->getMsg() == NodeMessage::MouseOver ) { - if ( NULL != mCurrentMenu && mCurrentMenu != tpop ) { + if ( nullptr != mCurrentMenu && mCurrentMenu != tpop ) { mCurrentMenu = tpop; tbut->select(); tpop->setParent( getWindowContainer() ); @@ -209,8 +220,8 @@ Uint32 UIMenuBar::onMessage( const NodeMessage* msg ) { tpop->setParent( getWindowContainer() ); tpop->show(); mWaitingUp = tpop; - } else if ( mCurrentMenu != tpop || mWaitingUp == NULL ) { - mCurrentMenu = NULL; + } else if ( mCurrentMenu != tpop || mWaitingUp == nullptr ) { + mCurrentMenu = nullptr; tbut->unselect(); tpop->hide(); } @@ -223,19 +234,18 @@ Uint32 UIMenuBar::onMessage( const NodeMessage* msg ) { break; } case NodeMessage::Selected: { - for ( MenuBarList::iterator it = mButtons.begin(); it != mButtons.end(); ++it ) { - if ( it->first != msg->getSender() ) { - it->first->unselect(); - it->second->hide(); + for ( auto& it : mButtons ) { + if ( it.first != msg->getSender() ) { + it.first->unselect(); + it.second->hide(); } } return 1; } case NodeMessage::FocusLoss: { - mWaitingUp = NULL; - if ( NULL != getEventDispatcher() ) { + mWaitingUp = nullptr; + if ( nullptr != getEventDispatcher() ) { Node* focusNode = getEventDispatcher()->getFocusNode(); - if ( !isParentOf( focusNode ) && !isPopUpMenuChild( focusNode ) ) { onWidgetFocusLoss(); } @@ -269,7 +279,7 @@ UIPopUpMenu* UIMenuBar::getMenuFromButton( UISelectButton* Button ) { } } - return NULL; + return nullptr; } bool UIMenuBar::isPopUpMenuChild( Node* node ) { @@ -281,42 +291,16 @@ bool UIMenuBar::isPopUpMenuChild( Node* node ) { return false; } -void UIMenuBar::onMenuFocusLoss( const Event* ) { - Node* focusNode = getEventDispatcher()->getFocusNode(); - if ( !isParentOf( focusNode ) && !isPopUpMenuChild( focusNode ) ) { - onWidgetFocusLoss(); - } -} - -void UIMenuBar::onHideByClick( const Event* ) { - onWidgetFocusLoss(); -} - -void UIMenuBar::onWidgetFocusLoss() { - UIWidget::onWidgetFocusLoss(); - - if ( NULL != mCurrentMenu ) { - mCurrentMenu->hide(); - - mCurrentMenu = NULL; - } - - unselectButtons(); -} - void UIMenuBar::autoHeight() { - if ( 0 == mMenuHeight && NULL != getSkin() ) { + if ( 0 == mMenuHeight && nullptr != getSkin() ) { mMenuHeight = getSkinSize().getHeight(); - setSize( getParent()->getSize().getWidth(), mMenuHeight ); - updateAnchorsDistances(); } } void UIMenuBar::loadFromXmlNode( const pugi::xml_node& node ) { beginAttributesTransaction(); - UIWidget::loadFromXmlNode( node ); for ( pugi::xml_node item = node.first_child(); item; item = item.next_sibling() ) { @@ -325,15 +309,14 @@ void UIMenuBar::loadFromXmlNode( const pugi::xml_node& node ) { if ( "menu" == name ) { std::string text( item.attribute( "text" ).as_string() ); - UIPopUpMenu* subMenu = UIPopUpMenu::New(); - if ( NULL != getDrawInvalidator() ) + if ( nullptr != getDrawInvalidator() ) subMenu->setParent( getDrawInvalidator() ); subMenu->loadFromXmlNode( item ); - if ( NULL != mSceneNode && mSceneNode->isUISceneNode() ) + if ( nullptr != mSceneNode && mSceneNode->isUISceneNode() ) addMenuButton( static_cast( mSceneNode )->getTranslatorString( text ), subMenu ); } diff --git a/src/eepp/ui/uimenuitem.cpp b/src/eepp/ui/uimenuitem.cpp index c1e5a5465..0113b0a1e 100644 --- a/src/eepp/ui/uimenuitem.cpp +++ b/src/eepp/ui/uimenuitem.cpp @@ -52,12 +52,25 @@ void UIMenuItem::onSizeChange() { } } -Uint32 UIMenuItem::onMouseOver( const Vector2i& Pos, const Uint32& Flags ) { - UIPushButton::onMouseOver( Pos, Flags ); +Uint32 UIMenuItem::onMouseOver( const Vector2i& pos, const Uint32& flags ) { + UIPushButton::onMouseOver( pos, flags ); getParent()->asType()->setItemSelected( this ); return 1; } +Uint32 UIMenuItem::onMouseLeave( const Vector2i& pos, const Uint32& flags ) { + UIPushButton::onMouseLeave( pos, flags ); + if ( getParent()->asType()->getItemSelected() == this ) + getParent()->asType()->unselectSelected(); + return 1; +} + +Uint32 UIMenuItem::onMouseClick( const Vector2i&, const Uint32& flags ) { + if ( flags & EE_BUTTON_LMASK ) + getParent()->asType()->backpropagateHide(); + return 1; +} + UIWidget* UIMenuItem::getExtraInnerWidget() { return mShortcutView; } diff --git a/src/eepp/ui/uimenusubmenu.cpp b/src/eepp/ui/uimenusubmenu.cpp index 5a230a214..2bc32c62e 100644 --- a/src/eepp/ui/uimenusubmenu.cpp +++ b/src/eepp/ui/uimenusubmenu.cpp @@ -10,12 +10,10 @@ UIMenuSubMenu* UIMenuSubMenu::New() { UIMenuSubMenu::UIMenuSubMenu() : UIMenuItem( "menu::submenu" ), - mSubMenu( NULL ), - mArrow( NULL ), + mSubMenu( nullptr ), + mArrow( nullptr ), mMaxTime( Milliseconds( 200.f ) ), - mCbId( 0 ), - mCbId2( 0 ), - mCurWait( NULL ) { + mCurWait( nullptr ) { mArrow = UIWidget::NewWithTag( getElementTag() + "::arrow" ); mArrow->setParent( this ); mArrow->setFlags( UI_AUTO_SIZE ); @@ -47,7 +45,6 @@ void UIMenuSubMenu::setTheme( UITheme* Theme ) { } onStateChange(); - onThemeLoaded(); } @@ -60,7 +57,6 @@ void UIMenuSubMenu::onSizeChange() { void UIMenuSubMenu::onAlphaChange() { UIMenuItem::onAlphaChange(); - mArrow->setAlpha( mAlpha ); } @@ -70,26 +66,15 @@ UIWidget* UIMenuSubMenu::getExtraInnerWidget() { void UIMenuSubMenu::onStateChange() { UIMenuItem::onStateChange(); - onSizeChange(); } -void UIMenuSubMenu::setSubMenu( UIMenu* SubMenu ) { - if ( NULL != mSubMenu && mSubMenu != SubMenu ) { - mSubMenu->removeEventListener( mCbId ); - mSubMenu->removeEventListener( mCbId2 ); - mSubMenu->setOwnerNode( NULL ); - } - - mSubMenu = SubMenu; - - if ( NULL != mSubMenu ) { - mCbId = mSubMenu->addEventListener( Event::OnEnabledChange, - cb::Make1( this, &UIMenuSubMenu::onSubMenuFocusLoss ) ); - mCbId2 = mSubMenu->addEventListener( Event::OnHideByClick, - cb::Make1( this, &UIMenuSubMenu::onHideByClick ) ); +void UIMenuSubMenu::setSubMenu( UIMenu* subMenu ) { + if ( nullptr != mSubMenu && mSubMenu != subMenu ) + mSubMenu->setOwnerNode( nullptr ); + mSubMenu = subMenu; + if ( nullptr != mSubMenu ) mSubMenu->setOwnerNode( this ); - } } UIMenu* UIMenuSubMenu::getSubMenu() const { @@ -97,86 +82,58 @@ UIMenu* UIMenuSubMenu::getSubMenu() const { } void UIMenuSubMenu::showSubMenu() { - mSubMenu->setParent( getParent()->getParent() ); - - Vector2f Pos = getPixelsPosition(); - nodeToWorldTranslation( Pos ); - Pos.x += mSize.getWidth() + getParent()->asType()->getPadding().Right; - - UIMenu::fixMenuPos( Pos, mSubMenu, getParent()->asType(), this ); - - mSubMenu->getParent()->worldToNode( Pos ); - mSubMenu->setPosition( Pos ); - + UIMenu* menu = getParent()->asType(); + mSubMenu->setParent( menu->getParent() ); + Vector2f pos = getPixelsPosition(); + nodeToWorldTranslation( pos ); + pos.x += mSize.getWidth() + menu->getPadding().Right; + UIMenu::fixMenuPos( pos, mSubMenu, menu, this ); + mSubMenu->getParent()->worldToNode( pos ); + mSubMenu->setPosition( pos ); if ( !mSubMenu->isVisible() ) { + if ( menu->mCurrentSubMenu != nullptr ) { + if ( menu->mCurrentSubMenu != mSubMenu ) { + menu->mCurrentSubMenu->hide(); + } + } mSubMenu->show(); + menu->mCurrentSubMenu = mSubMenu; } } -Uint32 UIMenuSubMenu::onMouseOver( const Vector2i& position, const Uint32& flags ) { - Action* openMenu = Actions::Runnable::New( - [&] { - if ( isMouseOver() ) - showSubMenu(); - mCurWait = NULL; - }, - mMaxTime ); - - runAction( openMenu ); - return UIMenuItem::onMouseOver( position, flags ); +Uint32 UIMenuSubMenu::onMouseOver( const Vector2i& pos, const Uint32& flags ) { + if ( nullptr == mCurWait ) { + mCurWait = Actions::Runnable::New( + [&] { + if ( isMouseOver() ) + showSubMenu(); + mCurWait = nullptr; + }, + mMaxTime ); + runAction( mCurWait ); + } + return UIMenuItem::onMouseOver( pos, flags ); } -Uint32 UIMenuSubMenu::onMouseLeave( const Vector2i& Pos, const Uint32& Flags ) { - UIMenuItem::onMouseLeave( Pos, Flags ); - if ( NULL != mCurWait ) { +Uint32 UIMenuSubMenu::onMouseLeave( const Vector2i& pos, const Uint32& flags ) { + UIMenuItem::onMouseLeave( pos, flags ); + if ( nullptr != mCurWait ) { removeAction( mCurWait ); - mCurWait = NULL; + mCurWait = nullptr; } - return UIMenuItem::onMouseLeave( Pos, Flags ); + return UIMenuItem::onMouseLeave( pos, flags ); +} + +Uint32 UIMenuSubMenu::onMouseClick( const Vector2i&, const Uint32& flags ) { + if ( (flags & EE_BUTTON_LMASK) && !mSubMenu->isVisible() ) + showSubMenu(); + return 1; } UINode* UIMenuSubMenu::getArrow() const { return mArrow; } -void UIMenuSubMenu::onSubMenuFocusLoss( const Event* ) { - Node* focusNode = NULL; - - if ( NULL != getEventDispatcher() ) { - focusNode = getEventDispatcher()->getFocusNode(); - - if ( getParent() != focusNode && !getParent()->isParentOf( focusNode ) ) { - getParent()->setFocus(); - } - } - - if ( mSubMenu->mClickHide ) { - UIMenu* parentMenu = getParent()->asType(); - - if ( !parentMenu->isSubMenu( focusNode ) && focusNode != this ) { - parentMenu->sendCommonEvent( Event::OnHideByClick ); - parentMenu->hide(); - } - - mSubMenu->mClickHide = false; - } -} - -void UIMenuSubMenu::onHideByClick( const Event* ) { - UIMenu* tMenu = getParent()->asType(); - - tMenu->mClickHide = true; - tMenu->sendCommonEvent( Event::OnHideByClick ); - tMenu->hide(); -} - -bool UIMenuSubMenu::inheritsFrom( const Uint32 Type ) { - if ( Type == UI_TYPE_MENUITEM ) - return true; - - return false; -} - const Time& UIMenuSubMenu::getMouseOverTimeShowMenu() const { return mMaxTime; } diff --git a/src/eepp/ui/uipopupmenu.cpp b/src/eepp/ui/uipopupmenu.cpp index 7831a64fb..a84db5026 100644 --- a/src/eepp/ui/uipopupmenu.cpp +++ b/src/eepp/ui/uipopupmenu.cpp @@ -35,26 +35,22 @@ void UIPopUpMenu::setTheme( UITheme* Theme ) { bool UIPopUpMenu::show() { if ( !isVisible() || 0.f == mAlpha ) { -#ifdef EE_PLATFORM_TOUCH - mTE.restart(); -#endif - setEnabled( true ); setVisible( true ); - toFront(); - if ( NULL != getUISceneNode() && getUISceneNode()->getUIThemeManager()->getDefaultEffectsEnabled() ) { + if ( mHidingAction ) { + removeAction( mHidingAction ); + mHidingAction = nullptr; + } runAction( Actions::Sequence::New( Actions::Fade::New( 255.f == mAlpha ? 0.f : mAlpha, 255.f, getUISceneNode()->getUIThemeManager()->getWidgetsFadeOutTime() ), Actions::Spawn::New( Actions::Enable::New(), Actions::Visible::New( true ) ) ) ); } - setFocus(); - return true; } @@ -62,58 +58,27 @@ bool UIPopUpMenu::show() { } bool UIPopUpMenu::hide() { - if ( isVisible() ) { - if ( NULL != mItemSelected ) - mItemSelected->popState( UIState::StateSelected ); - - mItemSelected = NULL; - mItemSelectedIndex = eeINDEX_NOT_FOUND; - + if ( isVisible() && !mHidingAction ) { if ( NULL != getUISceneNode() && getUISceneNode()->getUIThemeManager()->getDefaultEffectsEnabled() ) { - runAction( Actions::Sequence::New( + mHidingAction = Actions::Sequence::New( Actions::FadeOut::New( getUISceneNode()->getUIThemeManager()->getWidgetsFadeOutTime() ), - Actions::Spawn::New( Actions::Disable::New(), Actions::Visible::New( false ) ) ) ); + Actions::Spawn::New( Actions::Disable::New(), Actions::Visible::New( false ), + Actions::Runnable::New( [&] { mHidingAction = nullptr; } ) ) ); + runAction( mHidingAction ); } else { setEnabled( false ); setVisible( false ); } - + safeHide(); return true; } - return false; } -void UIPopUpMenu::onWidgetFocusLoss() { - hide(); - - UIMenu::onWidgetFocusLoss(); -} - -Uint32 UIPopUpMenu::onMessage( const NodeMessage* Msg ) { - switch ( Msg->getMsg() ) { - case NodeMessage::MouseUp: { -#ifdef EE_PLATFORM_TOUCH - if ( mTE.getElapsed().asMilliseconds() > 250.f ) { -#endif - if ( !Msg->getSender()->isType( UI_TYPE_MENUSUBMENU ) && - ( Msg->getFlags() & EE_BUTTONS_LRM ) ) { - sendCommonEvent( Event::OnHideByClick ); - - if ( isVisible() && NULL != mSceneNode ) - mSceneNode->setFocus(); - - hide(); - } -#ifdef EE_PLATFORM_TOUCH - } -#endif - } - } - - return UIMenu::onMessage( Msg ); +bool UIPopUpMenu::isHiding() const { + return mHidingAction != nullptr; } }} // namespace EE::UI diff --git a/src/tools/codeeditor/codeeditor.cpp b/src/tools/codeeditor/codeeditor.cpp index 8855ddba3..b806b02a6 100644 --- a/src/tools/codeeditor/codeeditor.cpp +++ b/src/tools/codeeditor/codeeditor.cpp @@ -820,6 +820,7 @@ void App::showFindView() { } else if ( !findInput->getText().empty() ) { findInput->getDocument().selectAll(); } + mCurEditor->getDocument().setActiveClient( mCurEditor ); } void App::closeApp() { @@ -917,6 +918,8 @@ void App::createSettingsMenu() { mSettingsMenu->show(); } ); mSettingsMenu->addEventListener( Event::OnItemClicked, [&]( const Event* event ) { + if ( !event->getNode()->isType( UI_TYPE_MENUITEM ) ) + return; const String& name = event->getNode()->asType()->getText(); if ( name == "New" ) { runCommand( "create-new" );