Menu Bar keyboard navigation improvements.

This commit is contained in:
Martín Lucas Golini
2024-04-14 16:44:16 -03:00
parent 16f4bea13e
commit 6461402e30
7 changed files with 100 additions and 17 deletions

View File

@@ -756,6 +756,7 @@ MenuBar::Button {
min-height: 18dp;
}
MenuBar::Button:selected,
MenuBar::Button:hover {
background-color: var(--primary);
}

View File

@@ -50,6 +50,12 @@ class EE_API UIMenuBar : public UIWidget {
void setCurrentMenu( UIPopUpMenu* currentMenu );
void showMenu( const Uint32& index );
void showNextMenu();
void showPrevMenu();
protected:
UIMenuBar();
@@ -60,6 +66,8 @@ class EE_API UIMenuBar : public UIWidget {
MenuBarList mButtons;
UIPopUpMenu* mWaitingUp;
Uint32 getMenuIndex( UIPopUpMenu* menu );
void refreshButtons();
virtual Uint32 onMessage( const NodeMessage* Msg );

View File

@@ -3,6 +3,7 @@
#include <eepp/ui/css/propertydefinition.hpp>
#include <eepp/ui/uiiconthememanager.hpp>
#include <eepp/ui/uimenu.hpp>
#include <eepp/ui/uimenubar.hpp>
#include <eepp/ui/uipopupmenu.hpp>
#include <eepp/ui/uiscenenode.hpp>
#include <eepp/ui/uithememanager.hpp>
@@ -444,7 +445,8 @@ void UIMenu::trySelect( UIWidget* node, bool up ) {
if ( up ) {
if ( index > 0 ) {
for ( Int32 i = (Int32)index - 1; i >= 0; i-- ) {
if ( !mItems[i]->isType( UI_TYPE_MENU_SEPARATOR ) ) {
if ( !mItems[i]->isType( UI_TYPE_MENU_SEPARATOR ) &&
mItems[i]->isVisible() ) {
setItemSelected( mItems[i] );
return;
}
@@ -453,7 +455,8 @@ void UIMenu::trySelect( UIWidget* node, bool up ) {
setItemSelected( mItems[mItems.size()] );
} else {
for ( Uint32 i = index + 1; i < mItems.size(); i++ ) {
if ( !mItems[i]->isType( UI_TYPE_MENU_SEPARATOR ) ) {
if ( !mItems[i]->isType( UI_TYPE_MENU_SEPARATOR ) &&
mItems[i]->isVisible() ) {
setItemSelected( mItems[i] );
return;
}
@@ -515,8 +518,18 @@ Uint32 UIMenu::onKeyDown( const KeyEvent& event ) {
case KEY_RIGHT:
if ( nullptr != mItemSelected && mItemSelected->isType( UI_TYPE_MENUSUBMENU ) )
mItemSelected->asType<UIMenuSubMenu>()->showSubMenu();
else if ( getOwnerNode() && getOwnerNode()->getParent() &&
getOwnerNode()->getParent()->isType( UI_TYPE_MENUBAR ) )
getOwnerNode()->getParent()->asType<UIMenuBar>()->showNextMenu();
break;
case KEY_LEFT:
if ( getOwnerNode() && getOwnerNode()->getParent() &&
getOwnerNode()->getParent()->isType( UI_TYPE_MENUBAR ) )
getOwnerNode()->getParent()->asType<UIMenuBar>()->showPrevMenu();
else if ( getOwnerNode() && getOwnerNode()->getParent() &&
getOwnerNode()->getParent()->isType( UI_TYPE_MENU ) )
hide();
break;
case KEY_ESCAPE:
hide();
break;

View File

@@ -23,6 +23,16 @@ UIMenuBar::UIMenuBar() :
applyDefaultTheme();
}
Uint32 UIMenuBar::getMenuIndex( UIPopUpMenu* menu ) {
Uint32 index = 0;
for ( const auto& [_, tmenu] : mButtons ) {
if ( tmenu == menu )
return index;
index++;
}
return eeINDEX_NOT_FOUND;
}
UIPopUpMenu* UIMenuBar::getCurrentMenu() const {
return mCurrentMenu;
}
@@ -32,6 +42,48 @@ void UIMenuBar::setCurrentMenu( UIPopUpMenu* currentMenu ) {
mWaitingUp = nullptr;
}
void UIMenuBar::showMenu( const Uint32& index ) {
eeASSERT( index < mButtons.size() );
auto but = mButtons[index];
auto tbut = but.first;
auto tpop = but.second;
Vector2f pos( tbut->getPosition().x, tbut->getPosition().y + tbut->getSize().getHeight() );
tpop->setPosition( pos );
if ( !tpop->isVisible() ) {
mCurrentMenu = tpop;
tbut->select();
tpop->setParent( getWindowContainer() );
tpop->show();
mWaitingUp = tpop;
} else if ( mCurrentMenu != tpop || mWaitingUp == nullptr ) {
mCurrentMenu = nullptr;
tbut->unselect();
tpop->hide();
}
}
void UIMenuBar::showNextMenu() {
if ( mCurrentMenu ) {
auto index = getMenuIndex( mCurrentMenu );
if ( index != eeINDEX_NOT_FOUND )
showMenu( index + 1 < mButtons.size() ? index + 1 : 0 );
} else if ( !mButtons.empty() ) {
showMenu( 0 );
}
}
void UIMenuBar::showPrevMenu() {
if ( mCurrentMenu ) {
auto index = getMenuIndex( mCurrentMenu );
if ( index != eeINDEX_NOT_FOUND )
showMenu( static_cast<int>( index ) - 1 >= 0 ? index - 1 : mButtons.size() - 1 );
} else if ( !mButtons.empty() ) {
showMenu( 0 );
}
}
UIMenuBar::~UIMenuBar() {
destroyMenues();
}

View File

@@ -432,7 +432,7 @@ Anchor.error:hover {
R"html(
<vbox id="" lw="mp" lh="mp">
<MenuBar id="main_menubar" visible="false" nomenu="true">
<MenuBar id="main_menubar" visible="false">
<Menu id="menubar_file" text="@string(file, File)" nomenu="true" />
<Menu id="menubar_edit" text="@string(edit, Edit)" nomenu="true" />
<Menu id="menubar_view" text="@string(view, View)" nomenu="true" />

View File

@@ -1,6 +1,6 @@
#include "pluginmanager.hpp"
#include "../filesystemlistener.hpp"
#include "plugin.hpp"
#include "pluginmanager.hpp"
#include <eepp/system/filesystem.hpp>
#include <eepp/ui/uicheckbox.hpp>
#include <eepp/ui/uitableview.hpp>
@@ -494,6 +494,11 @@ UIWindow* UIPluginManager::New( UISceneNode* sceneNode, PluginManager* manager,
plugin->removeReadyCallback( cb.second );
}
} );
win->on( Event::KeyDown, [win]( const Event* event ) {
const KeyEvent* kevent = event->asKeyEvent();
if ( kevent->getKeyCode() == EE::Window::KEY_ESCAPE )
win->close();
} );
win->center();
return win;
}

View File

@@ -1439,11 +1439,6 @@ UIMenu* SettingsMenu::createViewMenu() {
UIPopUpMenu* SettingsMenu::createToolsMenu() {
mToolsMenu = UIPopUpMenu::New();
mToolsMenu->add( i18n( "plugin_manager", "Plugin Manager" ), findIcon( "extensions" ) )
->setId( "plugin-manager-open" );
mToolsMenu->addSeparator();
mToolsMenu
->add( i18n( "locate_ellipsis", "Locate..." ), findIcon( "search" ),
getKeybind( "open-locatebar" ) )
@@ -1475,6 +1470,11 @@ UIPopUpMenu* SettingsMenu::createToolsMenu() {
mToolsMenu->addSeparator();
mToolsMenu->add( i18n( "plugin_manager", "Plugin Manager" ), findIcon( "extensions" ) )
->setId( "plugin-manager-open" );
mToolsMenu->addSeparator();
mToolsMenu
->add( i18n( "check_languages_health", "Check Languages Health" ),
findIcon( "hearth-pulse" ), getKeybind( "check-languages-health" ) )
@@ -1603,15 +1603,19 @@ UIMenu* SettingsMenu::createLanguagesMenu() {
}
void SettingsMenu::toggleSettingsMenu() {
if ( ( !mSettingsMenu->isVisible() || mSettingsMenu->isHiding() ) &&
mSettingsMenu->getInactiveTime().getElapsedTime().asMilliseconds() > 1 ) {
Vector2f pos( mSettingsButton->getPixelsPosition() );
mSettingsButton->nodeToWorldTranslation( pos );
UIMenu::findBestMenuPos( pos, mSettingsMenu );
mSettingsMenu->setPixelsPosition( pos );
mSettingsMenu->show();
if ( mApp->getConfig().ui.showMenuBar ) {
mMenuBar->showMenu( 0 );
} else {
mSettingsMenu->hide();
if ( ( !mSettingsMenu->isVisible() || mSettingsMenu->isHiding() ) &&
mSettingsMenu->getInactiveTime().getElapsedTime().asMilliseconds() > 1 ) {
Vector2f pos( mSettingsButton->getPixelsPosition() );
mSettingsButton->nodeToWorldTranslation( pos );
UIMenu::findBestMenuPos( pos, mSettingsMenu );
mSettingsMenu->setPixelsPosition( pos );
mSettingsMenu->show();
} else {
mSettingsMenu->hide();
}
}
}