qtquick: Don't assume in the C++ that the tab bar has a list view
Getting the tab index by QPoint is now done in QML, so it can be overridden by the user.
This commit is contained in:
@@ -40,33 +40,6 @@ void TabBar_qtquick::init()
|
||||
});
|
||||
}
|
||||
|
||||
QHash<int, QQuickItem *> 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<int, QQuickItem *> 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<int, QQuickItem *> 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<QQuickItem *> 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);
|
||||
|
||||
@@ -72,9 +72,7 @@ protected:
|
||||
void init() override;
|
||||
|
||||
private:
|
||||
QHash<int, QQuickItem *> qmlTabs() const;
|
||||
QQuickItem *tabAt(int index) const;
|
||||
QQuickItem *listView() const;
|
||||
QPointer<QQuickItem> m_tabBarQmlItem;
|
||||
KDBindings::ScopedConnection m_tabBarAutoHideChanged;
|
||||
};
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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!");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user