diff --git a/src/qtquick/views/TabBar_qtquick.cpp b/src/qtquick/views/TabBar_qtquick.cpp index cb4b97ed..51fb3a81 100644 --- a/src/qtquick/views/TabBar_qtquick.cpp +++ b/src/qtquick/views/TabBar_qtquick.cpp @@ -40,33 +40,6 @@ void TabBar_qtquick::init() }); } -QHash TabBar_qtquick::qmlTabs() const -{ - if (!m_tabBarQmlItem) { - qWarning() << Q_FUNC_INFO << "No visual tab bar item yet" << this; - return {}; - } - - /// Returns the list of QtQuickControls tabs in our tab bar - QHash tabs; - - if (QQuickItem *internalListView = listView()) { - const auto childItems = internalListView->childItems(); - if (!childItems.isEmpty()) { - for (QQuickItem *item : childItems.first()->childItems()) { - bool ok = false; - const int index = item->property("tabIndex").toInt(&ok); - if (ok) - tabs.insert(index, item); - } - } - } else { - qWarning() << Q_FUNC_INFO << "Couldn't find the internal ListView"; - } - - return tabs; -} - int TabBar_qtquick::tabAt(QPoint localPt) const { // QtQuick's TabBar doesn't provide any API for this. @@ -79,14 +52,13 @@ int TabBar_qtquick::tabAt(QPoint localPt) const const QPointF globalPos = m_tabBarQmlItem->mapToGlobal(localPt); - const QHash tabs = qmlTabs(); - for (auto it = tabs.keyValueBegin(); it != tabs.keyValueEnd(); ++it) { - QQuickItem *tab = it->second; - if (tab->contains(tab->mapFromGlobal(globalPos))) { - const int index = it->first; - return index; - } - } + QVariant index; + const bool res = QMetaObject::invokeMethod(m_tabBarQmlItem, "getTabIndexAtPosition", + Q_RETURN_ARG(QVariant, index), + Q_ARG(QVariant, globalPos)); + + if (res) + return index.toInt(); return -1; } @@ -154,27 +126,6 @@ QQuickItem *TabBar_qtquick::tabAt(int index) const return nullptr; } -QQuickItem *TabBar_qtquick::listView() const -{ - // Returns the internal ListView of the TabBar - if (!m_tabBarQmlItem) { - qWarning() << Q_FUNC_INFO << "No visual tab bar item yet"; - return nullptr; - } - - const QList children = m_tabBarQmlItem->childItems(); - if (children.size() != 1) { - return nullptr; - } - - for (QQuickItem *child : children.constFirst()->childItems()) { - if (qstrcmp(child->metaObject()->className(), "QQuickListView") == 0) - return child; - } - - return nullptr; -} - void TabBar_qtquick::moveTabTo(int from, int to) { Q_UNUSED(from); diff --git a/src/qtquick/views/TabBar_qtquick.h b/src/qtquick/views/TabBar_qtquick.h index 08879fa0..8208fb3a 100644 --- a/src/qtquick/views/TabBar_qtquick.h +++ b/src/qtquick/views/TabBar_qtquick.h @@ -72,9 +72,7 @@ protected: void init() override; private: - QHash qmlTabs() const; QQuickItem *tabAt(int index) const; - QQuickItem *listView() const; QPointer m_tabBarQmlItem; KDBindings::ScopedConnection m_tabBarAutoHideChanged; }; diff --git a/src/qtquick/views/qml/TabBar.qml b/src/qtquick/views/qml/TabBar.qml index 8992039b..c68fd702 100644 --- a/src/qtquick/views/qml/TabBar.qml +++ b/src/qtquick/views/qml/TabBar.qml @@ -16,23 +16,62 @@ import QtQuick.Controls 2.9 TabBarBase { id: root + // Helper, only applies if you're using the TabBar from QQControls. + // Returns the internal ListView function getInternalListView() { for(var i = 0; i < tabBar.children.length; ++i) { if (tabBar.children[i].toString().startsWith("QQuickListView")) return tabBar.children[i]; } + console.warn("Couldn't find the internal ListView"); return null; } function getTabAtIndex(index) { var listView = getInternalListView(); + var content = listView.children[0]; + + var curr = 0; + for (var i = 0; i < content.children.length; ++i) { + var candidate = content.children[i]; + if (typeof candidate.tabIndex == "undefined") { + // All tabs need to have "tabIndex" property. + continue; + } + + if (curr == index) + return candidate; + + curr++; + } + if (index < listView.children.length) return listView.children[0].children[index]; return null; } + function getTabIndexAtPosition(globalPoint) { + var listView = getInternalListView(); + var content = listView.children[0]; + + for (var i = 0; i < content.children.length; ++i) { + var candidate = content.children[i]; + if (typeof candidate.tabIndex == "undefined") { + // All tabs need to have "tabIndex" property. + continue; + } + + var localPt = candidate.mapFromGlobal(globalPoint.x, globalPoint.y); + if (candidate.contains(localPt)) { + return i; + } + } + + return -1; + } + implicitHeight: tabBar.implicitHeight onCurrentTabIndexChanged: { diff --git a/src/qtquick/views/qml/TabBarBase.qml b/src/qtquick/views/qml/TabBarBase.qml index 29938648..7dd47698 100644 --- a/src/qtquick/views/qml/TabBarBase.qml +++ b/src/qtquick/views/qml/TabBarBase.qml @@ -67,4 +67,12 @@ Item { function getTabAtIndex(index) { console.warn("Override this function in the actual derived tab bar!"); } + + /// Returns the index of the tab that's at localPoint + /// Returns -1 if no tab there. + /// This is called by C++ and needs to be implemented in the derived class. + /// See TabBar.qml for an example. + function getTabIndexAtPosition(localPoint) { + console.warn("Override this function in the actual derived tab bar!"); + } }