SpinSlider and ScrollSpinBox read-only support

PIVariantEdit - support for read-only for all types
PIValueTreeEdit - drop Parent grouping, default now Groups, full grouping control, global read-only support, fix new label error
This commit is contained in:
2023-04-28 19:51:22 +03:00
parent e7ef97dc6a
commit 46fd68a0fd
13 changed files with 102 additions and 27 deletions

View File

@@ -97,9 +97,7 @@ PIValueTree PIValueTreeEdit::value() const {
void PIValueTreeEdit::setGrouping(Grouping g) {
applyValues();
cur_grouping = real_grouping = g;
if (parent_tree && g == Parent) real_grouping = parent_tree->real_grouping;
if (real_grouping == Parent) real_grouping = Indent;
cur_grouping = g;
for (auto * a: widget_params->menu_grouping.actions()) {
if (a->data().toInt() == g) {
a->setChecked(true);
@@ -117,6 +115,13 @@ void PIValueTreeEdit::setFullEditMode(bool yes) {
}
void PIValueTreeEdit::setReadOnly(bool yes) {
applyValues();
m_read_only = yes;
build();
}
void PIValueTreeEdit::rollback() {
current = source;
build();
@@ -195,7 +200,7 @@ void PIValueTreeEdit::build() {
int index = 0;
for (const auto & i: current.children()) {
auto * ve = new PIVariantEdit();
ve->setAttributes(current.attributes());
ve->setAttributes(attributesWithRO(current.attributes()));
ve->setValue(i.value(), array_type);
grid->add(PIValueTree({PIString::fromNumber(index), PIVariant()}), PIString::fromNumber(index + 1), ve, i.comment());
++index;
@@ -467,10 +472,11 @@ PIValueTreeEdit * PIValueTreeEdit::addTreeEdit(const PIValueTree & vt) {
rp << vt.name();
ve->root_path = rp;
ve->parent_tree = this;
ve->setGrouping((Grouping)vt.attribute(Attribute::grouping, Parent).toEnum().selectedValue());
ve->m_read_only = m_read_only;
ve->setGrouping((Grouping)vt.attribute(Attribute::grouping, PIVariantEditorBase::createGrouping()).toEnum().selectedValue());
ve->setFullEditMode(is_full_edit);
ve->setValue(vt);
switch (real_grouping) {
switch (cur_grouping) {
case Indent: grid->add(vt, vt.name(), ve, vt.comment(), true); break;
case Groups: {
auto * gb = new GroupBox(ve);
@@ -523,7 +529,7 @@ void PIValueTreeEdit::applyArrayAttributes() {
uint array_type = PIVariant::typeIDFromName(current.attribute(Attribute::arrayType).toString());
for (int i = 0; i < array_edits.size_s(); ++i) {
auto * w = array_edits[i];
w->setAttributes(current.attributes());
w->setAttributes(attributesWithRO(current.attributes()));
w->setValue(i < current.children().size_s() ? current.children()[i].value() : PIVariant(), array_type);
}
}
@@ -540,7 +546,7 @@ QLabel * PIValueTreeEdit::newLabel(const PIValueTree & vt) {
void PIValueTreeEdit::applyVariantEdit(PIVariantEdit * ve, const PIValueTree & vt) {
ve->setAttributes(vt.attributes());
ve->setAttributes(attributesWithRO(vt.attributes()));
ve->setValue(vt.value());
ve->setFullEditMode(is_full_edit);
}
@@ -562,7 +568,7 @@ void PIValueTreeEdit::resizeArray() {
array_edits.resize(grid->rowCount());
for (int i = grid->rowCount(); i < value; ++i) {
auto * ve = new PIVariantEdit();
ve->setAttributes(current.attributes());
ve->setAttributes(attributesWithRO(current.attributes()));
ve->setValue(PIVariant::fromType(array_type), array_type);
grid->add(PIValueTree(), PIString::fromNumber(i + 1), ve, "");
array_edits << ve;
@@ -570,6 +576,13 @@ void PIValueTreeEdit::resizeArray() {
}
PIVariantMap PIValueTreeEdit::attributesWithRO(const PIVariantMap & attr) {
PIVariantMap ret = attr;
if (m_read_only) ret[PIValueTree::Attribute::readOnly] = true;
return ret;
}
void PIValueTreeEdit::newRequest(NewType type) {
PIString nn;
if (rootTreeEdit()->allowed_names && (type == NewType::Value)) {
@@ -605,7 +618,14 @@ void PIValueTreeEdit::newRequest(NewType type) {
}
current.addChild(vt);
switch (type) {
case NewType::Value: addValueEdit(vt); break;
case NewType::Value:
if (vt.attribute(Attribute::isLabel, false).toBool()) {
auto * l = newLabel(vt);
grid->add(vt, l);
} else {
addValueEdit(vt);
}
break;
case NewType::Group: addTreeEdit(vt); break;
case NewType::Array: addTreeEdit(vt)->resizeArray(); break;
}
@@ -626,7 +646,7 @@ PIValueTreeEdit::GridWidgets::GridWidgets(PIValueTreeEdit * p) {
auto common_actions =
{newSeparator(), wp->actionCut, wp->actionCopy, wp->actionPasteBefore, wp->actionPasteAfter, newSeparator(), wp->actionRemove};
menu_group.addActions({wp->actionRename, wp->actionReorder, wp->menu_grouping.menuAction()});
menu_conf.addActions({wp->actionRename, wp->actionChange, wp->actionReorder});
menu_conf.addActions({wp->actionRename, wp->actionChange, wp->actionReorder, wp->menu_grouping.menuAction()});
menu_group.addActions(common_actions);
menu_conf.addActions(common_actions);
menu_new.addActions({wp->actionValue, wp->actionGroup, wp->actionArray, newSeparator(), wp->actionPaste});

View File

@@ -49,8 +49,7 @@ public:
enum Grouping {
Indent,
Groups,
Tabs,
Parent = 0xFF
Tabs
};
void setValue(const PIValueTree & v);
@@ -60,6 +59,8 @@ public:
void setGrouping(Grouping g);
bool isFullEditMode() const { return is_full_edit; }
void setFullEditMode(bool yes);
bool isReadOnly() const { return m_read_only; }
void setReadOnly(bool yes);
void setAllowedNamesFunction(std::function<PIStringList()> f) { allowed_names = f; }
void setValueForNameFunction(std::function<PIVariant(PIString)> f) { value_by_name = f; }
@@ -97,6 +98,7 @@ private:
void applyVariantEdit(PIVariantEdit * ve, const PIValueTree & vt);
void createTabWidget();
void resizeArray();
PIVariantMap attributesWithRO(const PIVariantMap & attr);
class GridWidgets: public QWidget {
public:
@@ -146,9 +148,9 @@ private:
QTabWidget * tab_widget = nullptr;
Ui::PIValueTreeEditArray * ui_array;
GridWidgets * grid = nullptr;
Grouping cur_grouping = Parent, real_grouping = Indent;
Grouping cur_grouping = Groups;
mutable PIValueTree source, current;
bool is_full_edit = false;
bool is_full_edit = false, m_read_only = false;
std::function<PIStringList()> allowed_names;
std::function<PIVariant(PIString)> value_by_name;
};

View File

@@ -24,7 +24,7 @@ PIValueTreeEditParameters::PIValueTreeEditParameters(QWidget * parent): QDialog(
auto * a = ag->addAction(me.key(i));
a->setCheckable(true);
a->setData(me.value(i));
if (me.value(i) == PIValueTreeEdit::Indent) a->setChecked(true);
if (me.value(i) == PIValueTreeEdit::Groups) a->setChecked(true);
}
menu_grouping.addActions(ag->actions());
menu_grouping.menuAction()->setText(tr("Grouping"));

View File

@@ -43,8 +43,8 @@ PIVariantMap PIVariantEditorBase::editorDefaultAttributes(uint type_id) {
PIVariantTypes::Enum PIVariantEditorBase::createGrouping() {
PIVariantTypes::Enum ret;
ret << PIVariantTypes::Enumerator(PIValueTreeEdit::Indent, "indent") << PIVariantTypes::Enumerator(PIValueTreeEdit::Groups, "groups")
<< PIVariantTypes::Enumerator(PIValueTreeEdit::Tabs, "tabs") << PIVariantTypes::Enumerator(PIValueTreeEdit::Parent, "parent");
ret.selectValue(PIValueTreeEdit::Parent);
<< PIVariantTypes::Enumerator(PIValueTreeEdit::Tabs, "tabs");
ret.selectValue(PIValueTreeEdit::Groups);
return ret;
}

View File

@@ -196,6 +196,7 @@ void PIVariantEditors::NumberBase::retranslate() {
void PIVariantEditors::NumberBase::applyAttributes(const PIVariantMap & a) {
bool ro = a.value(Attribute::readOnly, false).toBool();
Type new_type = static_cast<Type>(a.value(Attribute::widgetType).toEnum().selectedValue());
if (new_type == tInvalid) new_type = tSpinBox;
if (type != new_type) {
@@ -226,6 +227,7 @@ void PIVariantEditors::NumberBase::applyAttributes(const PIVariantMap & a) {
case tSpinBox: {
auto * w = qobject_cast<QDoubleSpinBox *>(widget);
if (!w) return;
w->setReadOnly(ro);
w->setPrefix(PIVariantEditorBase::vtTr(prefix));
w->setSuffix(PIVariantEditorBase::vtTr(suffix));
w->setRange(min, max);
@@ -235,6 +237,7 @@ void PIVariantEditors::NumberBase::applyAttributes(const PIVariantMap & a) {
case tSlider: {
auto * w = qobject_cast<QSlider *>(widget);
if (!w) return;
w->setEnabled(!ro);
w->setTickInterval(piRoundd(piMaxd(1., (max - min) / 100.)));
w->setRange(min, max);
w->setSingleStep(step);
@@ -242,6 +245,7 @@ void PIVariantEditors::NumberBase::applyAttributes(const PIVariantMap & a) {
case tSpinSlider: {
auto * w = qobject_cast<SpinSlider *>(widget);
if (!w) return;
w->setReadOnly(ro);
w->setPrefix(PIVariantEditorBase::vtTr(prefix));
w->setSuffix(PIVariantEditorBase::vtTr(suffix));
w->setMinimum(min);
@@ -252,6 +256,7 @@ void PIVariantEditors::NumberBase::applyAttributes(const PIVariantMap & a) {
case tEvalSpinBox: {
auto * w = qobject_cast<EvalSpinBox *>(widget);
if (!w) return;
w->setReadOnly(ro);
w->setSingleStep(step);
w->setPrecision(dec);
w->setExpression(PI2QString(a.value(Attribute::expression).toString()));
@@ -259,6 +264,7 @@ void PIVariantEditors::NumberBase::applyAttributes(const PIVariantMap & a) {
case tScrollSpinBox: {
auto * w = qobject_cast<ScrollSpinBox *>(widget);
if (!w) return;
w->setReadOnly(ro);
w->setMinimum(min);
w->setMaximum(max);
} break;
@@ -267,6 +273,13 @@ void PIVariantEditors::NumberBase::applyAttributes(const PIVariantMap & a) {
}
// PIVariantEditors::Bool
void PIVariantEditors::Bool::applyAttributes(const PIVariantMap & a) {
widget->setEnabled(!a.value(Attribute::readOnly, !widget->isEnabled()).toBool());
}
// PIVariantEditors::Int

View File

@@ -78,6 +78,8 @@ public:
PIVariant value() const override { return widget->isChecked(); }
private:
void applyAttributes(const PIVariantMap & a) override;
QCheckBox * widget;
};

View File

@@ -54,6 +54,12 @@ double ScrollSpinBox::value() const {
}
void ScrollSpinBox::setReadOnly(bool r) {
m_read_only = r;
ui->spin->setReadOnly(r);
}
void ScrollSpinBox::changeEvent(QEvent * e) {
QWidget::changeEvent(e);
switch (e->type()) {
@@ -84,7 +90,7 @@ bool ScrollSpinBox::eventFilter(QObject * o, QEvent * e) {
void ScrollSpinBox::mousePress(QMouseEvent * e) {
if (canceled || !isEnabled()) return;
if (canceled || !isEnabled() || m_read_only) return;
if (e->button() == Qt::RightButton) {
canceled = true;
ui->spin->setExpression(last_text);
@@ -99,13 +105,13 @@ void ScrollSpinBox::mousePress(QMouseEvent * e) {
void ScrollSpinBox::mouseRelease(QMouseEvent * e) {
if (!isEnabled()) return;
if (!isEnabled() || m_read_only) return;
if (e->buttons() == Qt::NoButton) canceled = false;
}
void ScrollSpinBox::mouseMove(QMouseEvent * e) {
if (canceled || !isEnabled()) return;
if (canceled || !isEnabled() || m_read_only) return;
if (e->buttons().testFlag(Qt::LeftButton)) {
double dv = (down_pos.y() - e->pos().y()) * scroll_scale;
if (dv != 0.) {

View File

@@ -49,6 +49,9 @@ public:
int minimum() const { return m_minimum; }
int maximum() const { return m_maximum; }
void setReadOnly(bool r);
bool isReadOnly() const { return m_read_only; }
protected:
void changeEvent(QEvent * e);
void resizeEvent(QResizeEvent * e);
@@ -62,7 +65,7 @@ protected:
QString last_text;
double last_value, scroll_scale, sensivity_;
double m_minimum, m_maximum;
bool canceled;
bool canceled, m_read_only = false;
public slots:
void setSensivity(double s) { sensivity_ = s; }

View File

@@ -50,6 +50,13 @@ bool SpinSlider::adaptiveStep() const {
}
void SpinSlider::setReadOnly(bool r) {
m_read_only = r;
spin->setReadOnly(r);
slider->setEnabled(!r);
}
void SpinSlider::setAdaptiveStep(bool on) {
#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0))
if (on)

View File

@@ -77,6 +77,9 @@ public:
bool invertedAppearance() const { return slider->invertedAppearance(); }
bool squareScale() const { return square; }
void setReadOnly(bool r);
bool isReadOnly() const { return m_read_only; }
void setSingleStep(double step) {
spin->setSingleStep(step);
slider->setPageStep(qRound(step * delim));
@@ -134,7 +137,7 @@ private:
double min_, max_, val_, delim, page;
int dec_, ticks_;
bool adjusting, square;
bool adjusting, square, m_read_only = false;
QSlider * slider;
QDoubleSpinBox * spin;
QBoxLayout * layout;

View File

@@ -23,11 +23,10 @@ MainWindow::MainWindow(QWidget * parent): EMainWindow(parent), Ui::MainWindow()
auto mo = PIValueTreeEdit::staticMetaObject;
auto me = mo.enumerator(mo.indexOfEnumerator("Grouping"));
for (int i = 0; i < me.keyCount(); ++i) {
if (me.value(i) == PIValueTreeEdit::Parent) continue;
auto * a = ag->addAction(me.key(i));
a->setCheckable(true);
a->setData(me.value(i));
if (me.value(i) == PIValueTreeEdit::Indent) a->setChecked(true);
if (me.value(i) == PIValueTreeEdit::Groups) a->setChecked(true);
}
menuView->addActions(ag->actions());
widget->setFullEditMode(actionFull_edit_mode->isChecked());
@@ -100,3 +99,8 @@ QString MainWindow::loadFilter() {
void MainWindow::on_actionFull_edit_mode_toggled(bool on) {
widget->setFullEditMode(on);
}
void MainWindow::on_actionRead_only_toggled(bool on) {
widget->setReadOnly(on);
}

View File

@@ -26,6 +26,7 @@ protected:
private slots:
void on_actionFull_edit_mode_toggled(bool on);
void on_actionRead_only_toggled(bool on);
};
#endif // MAINWINDOW_H

View File

@@ -56,6 +56,12 @@
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
@@ -102,6 +108,7 @@
<string>View</string>
</property>
<addaction name="actionFull_edit_mode"/>
<addaction name="actionRead_only"/>
<addaction name="separator"/>
</widget>
<addaction name="menuFile"/>
@@ -145,7 +152,7 @@
</action>
<action name="actionNew">
<property name="icon">
<iconset resource="../../libs/qglview/qglview.qrc">
<iconset resource="../../libs/widgets/qad_widgets.qrc">
<normaloff>:/icons/document-new.png</normaloff>:/icons/document-new.png</iconset>
</property>
<property name="text">
@@ -175,6 +182,14 @@
<string>Full edit mode</string>
</property>
</action>
<action name="actionRead_only">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Read only</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
@@ -188,7 +203,6 @@
<resources>
<include location="../../../cd/utils/pult/cdpult.qrc"/>
<include location="../../libs/blockview/qad_blockview.qrc"/>
<include location="../../libs/qglview/qglview.qrc"/>
<include location="../../libs/widgets/qad_widgets.qrc"/>
</resources>
<connections>