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:
@@ -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});
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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"));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -78,6 +78,8 @@ public:
|
||||
PIVariant value() const override { return widget->isChecked(); }
|
||||
|
||||
private:
|
||||
void applyAttributes(const PIVariantMap & a) override;
|
||||
|
||||
QCheckBox * widget;
|
||||
};
|
||||
|
||||
|
||||
@@ -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.) {
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user