feat(tab menu): add selection/keyboard navigation

This commit is contained in:
parker
2025-07-17 03:47:04 +01:00
parent b99bcb73dc
commit fa8189b816
2 changed files with 100 additions and 7 deletions

View File

@@ -20,6 +20,7 @@
#include <QEvent> #include <QEvent>
#include <QPainterPath> #include <QPainterPath>
#include <QPushButton> #include <QPushButton>
#include <stdexcept>
#include <string> #include <string>
enzo::ui::TabMenu::TabMenu(QWidget *parent, Qt::WindowFlags f) enzo::ui::TabMenu::TabMenu(QWidget *parent, Qt::WindowFlags f)
@@ -53,6 +54,14 @@ enzo::ui::TabMenu::TabMenu(QWidget *parent, Qt::WindowFlags f)
border-radius: 8px; border-radius: 8px;
} }
QPushButton#TabMenuButton[selected="true"] {
background-color: #3d3d3d;
}
QPushButton#TabMenuButton[selected="false"] {
background-color: transparent;
}
QPushButton#TabMenuButton:hover { QPushButton#TabMenuButton:hover {
background-color: #3d3d3d; background-color: #3d3d3d;
color: white; color: white;
@@ -129,16 +138,28 @@ enzo::ui::TabMenu::TabMenu(QWidget *parent, Qt::WindowFlags f)
void enzo::ui::TabMenu::textChanged(const QString &text) void enzo::ui::TabMenu::textChanged(const QString &text)
{ {
for(auto button : buttons_) selectionIndex_ = 0;
bool selectionMade = false;
visibleButtons_.clear();
for(size_t i=0; i<buttons_.size(); ++i)
{ {
if(text=="") auto button = buttons_.at(i);
if(text=="" || button->getDisplayText().toLower().contains(text.toLower()))
{ {
button->setVisible(true); // make selection
continue; if(!selectionMade)
{
std::cout << "selecting: " << button->getDisplayText().toStdString() << "\n";
button->setSelected(true);
} }
if(button->getDisplayText().toLower().contains(text.toLower())) else
{ {
std::cout << "deselecting: " << button->getDisplayText().toStdString() << "\n";
button->setSelected(false);
}
visibleButtons_.push_back(button);
button->setVisible(true); button->setVisible(true);
selectionMade = true;
} }
else else
{ {
@@ -162,6 +183,7 @@ void enzo::ui::TabMenu::showOnMouse(float dx, float dy)
std::cout << "showing\n"; std::cout << "showing\n";
QPoint cursorPos = mapToParent(mapFromGlobal(QCursor::pos())); QPoint cursorPos = mapToParent(mapFromGlobal(QCursor::pos()));
searchBar_->clear(); searchBar_->clear();
textChanged("");
move(cursorPos + QPoint(dx, dy)); move(cursorPos + QPoint(dx, dy));
show(); show();
adjustSize(); adjustSize();
@@ -200,6 +222,23 @@ bool enzo::ui::TabMenu::event(QEvent *event)
focusOutEvent(static_cast<QFocusEvent*>(event)); focusOutEvent(static_cast<QFocusEvent*>(event));
return true; return true;
} }
else if(key==Qt::Key_Enter || key==Qt::Key_Return)
{
if(visibleButtons_.size()==0) return true;
if(selectionIndex_>=visibleButtons_.size()) selectionIndex_=visibleButtons_.size()-1;
auto button = visibleButtons_.at(selectionIndex_);
static_cast<Network*>(parentWidget())->createNode(op::OperatorTable::getOpConstructor(button->nodeName));
doHide();
return true;
}
else if(key==Qt::Key_Up)
{
moveSelection(SelectionDirection::DOWN);
}
else if(key==Qt::Key_Down)
{
moveSelection(SelectionDirection::UP);
}
// std::cout << "key pressed: " << static_cast<QKeyEvent*>(event)->text().toStdString() << "\n"; // std::cout << "key pressed: " << static_cast<QKeyEvent*>(event)->text().toStdString() << "\n";
} }
// else if(event->type() == QEvent::KeyRelease) // else if(event->type() == QEvent::KeyRelease)
@@ -213,9 +252,44 @@ bool enzo::ui::TabMenu::event(QEvent *event)
} }
void enzo::ui::TabMenu::moveSelection(SelectionDirection direction)
{
if(direction==SelectionDirection::UP)
{
if(selectionIndex_+1>=visibleButtons_.size())
{
return;
}
selectionIndex_++;
}
else if(direction==SelectionDirection::DOWN)
{
if(selectionIndex_<=0)
{
return;
}
selectionIndex_--;
std::cout << "selection index: " << selectionIndex_ << "\n";
}
for(size_t i=0; i<visibleButtons_.size(); ++i)
{
TabMenuButton* button = visibleButtons_.at(i);
if(i==selectionIndex_)
{
button->setSelected(true);
}
else
{
button->setSelected(false);
}
}
}
enzo::ui::TabMenuButton::TabMenuButton(const QString &text, QWidget *parent) enzo::ui::TabMenuButton::TabMenuButton(const QString &text, QWidget *parent)
: QPushButton(parent) : QPushButton(parent)
{ {
setSelected(false);
setObjectName("TabMenuButton"); setObjectName("TabMenuButton");
displayText_ = text; displayText_ = text;
@@ -239,6 +313,14 @@ enzo::ui::TabMenuButton::TabMenuButton(const QString &text, QWidget *parent)
} }
void enzo::ui::TabMenuButton::setSelected(bool selected)
{
setProperty("selected", selected);
style()->polish(this);
update();
}
// enzo::ui::TabMenuSearch::TabMenuSearch(QWidget *parent) // enzo::ui::TabMenuSearch::TabMenuSearch(QWidget *parent)
// : QLineEdit(parent) // : QLineEdit(parent)
// { // {

View File

@@ -19,6 +19,7 @@ public:
TabMenuButton(const QString &text, QWidget *parent = nullptr); TabMenuButton(const QString &text, QWidget *parent = nullptr);
std::string nodeName; std::string nodeName;
QString getDisplayText() {return displayText_;} QString getDisplayText() {return displayText_;}
void setSelected(bool selected);
private: private:
QHBoxLayout* mainLayout_; QHBoxLayout* mainLayout_;
QLabel* textLabel_; QLabel* textLabel_;
@@ -35,6 +36,12 @@ public:
void showOnMouse(float dx=0, float dy=0); void showOnMouse(float dx=0, float dy=0);
private: private:
enum class SelectionDirection
{
UP,
DOWN
};
QVBoxLayout* mainLayout_; QVBoxLayout* mainLayout_;
QLineEdit* searchBar_; QLineEdit* searchBar_;
QScrollArea* nodeScrollArea_; QScrollArea* nodeScrollArea_;
@@ -43,6 +50,10 @@ private:
void doHide(); void doHide();
void textChanged(const QString &text); void textChanged(const QString &text);
std::vector<TabMenuButton*> buttons_; std::vector<TabMenuButton*> buttons_;
std::vector<TabMenuButton*> visibleButtons_;
unsigned int selectionIndex_ = 0;
void moveSelection(SelectionDirection direction);
protected: protected:
void focusOutEvent(QFocusEvent *event) override; void focusOutEvent(QFocusEvent *event) override;
bool event(QEvent *event) override; bool event(QEvent *event) override;