Skip to content

Commit

Permalink
fix: DSettingsDialog的setGroupVisible方法对树形结构的导航栏失效
Browse files Browse the repository at this point in the history
1.修改Content控件,树形结构的遍历及设置visible方法,
对QFormLayout布局时,即使控件隐藏也会占部分空间,后改成QVBoxLayout,
在滚动条滚动时,只有显示的title才参与计算.
2.修改Navigation控件,设置setGroupVisible时对所有子树项进行设置.
3.添加测试代码.

Log: 
Change-Id: I68f03260b9bd62b14cb6cd0de3a6d382a74dbdcd
  • Loading branch information
18202781743 committed Jun 25, 2021
1 parent f838e3b commit 475d96c
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 37 deletions.
22 changes: 22 additions & 0 deletions examples/dwidget-examples/collections/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <QHBoxLayout>
#include <QTextCodec>
#include <QDebug>
#include <QComboBox>

#include <DStandardItem>
#include <DTitlebar>
Expand Down Expand Up @@ -259,6 +260,27 @@ void MainWindow::menuItemInvoked(QAction *action)

return nullptr;
});

// 测试DSettingsDialog::setGroupVisible接口
auto hLayout = dsd.layout();
auto test = new QWidget;
auto layout = new QHBoxLayout(test);
auto testBtn = new QPushButton();
testBtn->setText("test setGroupVisible");
auto combobox = new QComboBox();
combobox->addItem("base");
combobox->addItem("base.custom-widgets");
combobox->addItem("base.theme");
combobox->addItem("shortcuts");
combobox->addItem("advance");
layout->addWidget(combobox);
layout->addWidget(testBtn);
hLayout->addWidget(test);
connect(testBtn, &QPushButton::clicked, [&dsd, combobox](){
auto key = combobox->currentText();
dsd.setGroupVisible(key, !dsd.groupIsVisible(key));
});

dsd.updateSettings(settings);
dsd.exec();
return;
Expand Down
73 changes: 39 additions & 34 deletions src/widgets/private/settings/content.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class ContentPrivate

QScrollArea *contentArea = nullptr;
QWidget *contentFrame = nullptr;
QFormLayout *contentLayout = nullptr;
QVBoxLayout *contentLayout = nullptr;

QMap<QString, QWidget *> titles = {};
QList<QWidget *> sortTitles = {};
Expand Down Expand Up @@ -94,10 +94,8 @@ Content::Content(QWidget *parent)
d->contentFrame = new QWidget(this);
d->contentFrame->setObjectName("SettingsContent");
d->contentFrame->setAccessibleName("ContentSettingsFrame");
d->contentLayout = new QFormLayout(d->contentFrame);
d->contentLayout->setRowWrapPolicy(QFormLayout::DontWrapRows);
d->contentLayout->setLabelAlignment(Qt::AlignLeft);
d->contentLayout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow);
d->contentLayout = new QVBoxLayout(d->contentFrame);
d->contentLayout->setAlignment(Qt::AlignLeft);
d->contentLayout->setContentsMargins(0, 0, 10, 0);
layout->addWidget(d->contentArea);

Expand All @@ -106,16 +104,27 @@ Content::Content(QWidget *parent)
connect(d->contentArea->verticalScrollBar(), &QScrollBar::valueChanged,
this, [ = ](int value) {
Q_D(Content);

// 当前显示的Title才参与滚动条的计算
QList<QWidget *> visableSortTitles;
for (auto idx = 0; idx < d->sortTitles.length(); ++idx) {
auto title = d->sortTitles[idx];
if (title->isVisible())
visableSortTitles.push_back(title);
}
if (visableSortTitles.empty())
return;

auto currentTitle = visableSortTitles.first();
auto viewHeight = d->contentArea->height();
auto currentTitle = d->sortTitles.first();

QList<QWidget *> visableTitleList;

for (auto idx = 0; idx < d->sortTitles.length(); ++idx) {
auto title = d->sortTitles[idx];
for (auto idx = 0; idx < visableSortTitles.length(); ++idx) {
auto title = visableSortTitles[idx];
if (title->y() <= value) {
if (idx < d->sortTitles.length() - 1) {
auto nextTitle = d->sortTitles[idx + 1];
if (idx < visableSortTitles.length() - 1) {
auto nextTitle = visableSortTitles[idx + 1];
if (nextTitle->y() >= value) {
visableTitleList.push_back(title);
}
Expand All @@ -126,18 +135,18 @@ Content::Content(QWidget *parent)
}

if (!visableTitleList.isEmpty()) {
auto lastTitle = d->sortTitles.last();
auto lastTitle = visableSortTitles.last();
if (value + viewHeight - 180 >= lastTitle->y()) {
currentTitle = visableTitleList.last();
} else {
currentTitle = visableTitleList.first();
}
}

if (value >= d->sortTitles.last()->y())
currentTitle = d->sortTitles.last();
if (value <= d->sortTitles.first()->y())
currentTitle = d->sortTitles.first();
if (value >= visableSortTitles.last()->y())
currentTitle = visableSortTitles.last();
if (value <= visableSortTitles.first()->y())
currentTitle = visableSortTitles.first();

if (currentTitle) {
Q_EMIT scrollToGroup(currentTitle->property("key").toString());
Expand Down Expand Up @@ -169,23 +178,17 @@ void Content::setGroupVisible(const QString &key, bool visible)
{
Q_D(Content);

if (!d->titles.contains(key))
return;

auto title = d->titles.value(key);
title->setVisible(visible);

QSet<QString> keys = {key}; // 需要改变visible的key集合
for (QObject *obj : d->contentFrame->children()) {
if (obj->property("_d_dtk_group_key").toString() == key) {
if (ContentTitle *title = qobject_cast<ContentTitle *>(obj)) {
const QString &key = title->property("key").toString();
auto parentKey = obj->property("_d_dtk_group_key").toString();
auto currKey = obj->property("key").toString();

if (d->titles.contains(key)) {
setGroupVisible(key, visible);
continue;
}
}
// 若父组或者当前组为需要改变visible,则加入到keys集合中
if (parentKey == key || currKey == key) {
keys << currKey;
}

if (keys.contains(currKey)) {
if (QWidget *w = qobject_cast<QWidget *>(obj)) {
if (!visible || w->parentWidget()) // 无父控件时禁止其显示
w->setVisible(visible);
Expand Down Expand Up @@ -235,7 +238,7 @@ void Content::updateSettings(const QByteArray &translateContext, QPointer<DTK_CO
widTile->setAccessibleName(QString("ContentWidTileFor").append(groupKey));
QHBoxLayout *hLayTile = new QHBoxLayout(widTile);
hLayTile->addWidget(title);
d->contentLayout->setWidget(d->contentLayout->rowCount(), QFormLayout::SpanningRole, widTile);
d->contentLayout->addWidget(widTile);

d->sortTitles.push_back(widTile);
d->titles.insert(groupKey, widTile);
Expand Down Expand Up @@ -264,18 +267,20 @@ void Content::updateSettings(const QByteArray &translateContext, QPointer<DTK_CO
hLay->setContentsMargins(10, 0, 0, 0);
hLay->addWidget(title);

d->contentLayout->setWidget(d->contentLayout->rowCount(), QFormLayout::LabelRole, wid);
d->contentLayout->addWidget(wid);

d->sortTitles.push_back(wid);
d->titles.insert(subgroup->key(), wid);
}

QVBoxLayout *bgGpLayout = new QVBoxLayout;
DBackgroundGroup *bgGroup = new DBackgroundGroup(bgGpLayout);
bgGroup->setProperty("key", subgroup->key());
bgGroup->setProperty("_d_dtk_group_key", current_groupKey);
bgGroup->setItemSpacing(1);
bgGroup->setItemMargins(QMargins(0, 0, 0, 0));
bgGroup->setBackgroundRole(QPalette::Window);
d->contentLayout->addRow(bgGroup);
d->contentLayout->addWidget(bgGroup);

for (auto option : subgroup->childOptions()) {
if (option->isHidden()) {
Expand Down Expand Up @@ -322,7 +327,7 @@ void Content::updateSettings(const QByteArray &translateContext, QPointer<DTK_CO
}
}
QSpacerItem *spaceItem = new QSpacerItem(0, 20,QSizePolicy::Minimum,QSizePolicy::Expanding);
d->contentLayout->setItem(d->contentLayout->rowCount(), QFormLayout::LabelRole, spaceItem);
d->contentLayout->addItem(spaceItem);
}

QWidget *box = new QWidget();
Expand All @@ -337,7 +342,7 @@ void Content::updateSettings(const QByteArray &translateContext, QPointer<DTK_CO
box->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
box->setAccessibleName("ContentBottomWidget");

d->contentLayout->setWidget(d->contentLayout->rowCount(), QFormLayout::SpanningRole, box);
d->contentLayout->addWidget(box);

connect(resetBt, &QPushButton::released,
this, [ = ]() {
Expand Down
23 changes: 20 additions & 3 deletions src/widgets/private/settings/navigation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,25 @@ class NavigationPrivate
return QModelIndex();
}

// 返回所有符合条件的key集合, e.g: key: abc, 可返回{abc.dc, abc}, 过滤掉{abcd}
QList<QModelIndex> indexesOfGroup(const QString &key) const
{
static const QChar SplitChar = '.'; // group之间的key以'.'分割连接组成实际的key值
QList<QModelIndex> res;
for (int i = 0; i < navbarModel->rowCount(); ++i) {
auto index = navbarModel->index(i, 0);
const auto& navKey = index.data(NavigationDelegate::NavKeyRole).toString();
if (navKey.startsWith(key)) {
const auto& remainderKey = navKey.mid(key.size());
if (remainderKey.isEmpty() || remainderKey.at(0) == SplitChar) {
res.append(index);
}
}
}

return res;
}

DListView *navbar = nullptr;
QStandardItemModel *navbarModel = nullptr;

Expand Down Expand Up @@ -114,9 +133,7 @@ void Navigation::setGroupVisible(const QString &key, bool visible)
{
Q_D(Navigation);

const QModelIndex &index = d->indexOfGroup(key);

if (index.isValid()) {
for (const auto& index : d->indexesOfGroup(key)) {
d->navbar->setRowHidden(index.row(), !visible);
}
}
Expand Down

0 comments on commit 475d96c

Please sign in to comment.