| |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| using namespace DVGui; |
| |
| |
| |
| |
| |
| ToolOptionControl::ToolOptionControl(TTool *tool, std::string propertyName, ToolHandle *toolHandle) |
| : m_tool(tool), m_propertyName(propertyName), m_toolHandle(toolHandle) |
| { |
| } |
| |
| |
| |
| void ToolOptionControl::notifyTool() |
| { |
| m_tool->onPropertyChanged(m_propertyName); |
| } |
| |
| |
| |
| |
| bool ToolOptionControl::isInVisibleViewer(QWidget *widget) |
| { |
| if (!widget) |
| return false; |
| |
| if (widget->isVisible()) |
| return true; |
| |
| ToolOptionsBox *parentTOB = dynamic_cast<ToolOptionsBox *>(widget->parentWidget()); |
| if (!parentTOB) |
| return false; |
| |
| ToolOptions *grandParentTO = dynamic_cast<ToolOptions *>(parentTOB->parentWidget()); |
| if (!grandParentTO) |
| return false; |
| |
| |
| QFrame *greatGrandParentFrame = dynamic_cast<QFrame *>(grandParentTO->parentWidget()); |
| if (!greatGrandParentFrame) |
| return false; |
| |
| return greatGrandParentFrame->isVisible(); |
| } |
| |
| |
| |
| |
| |
| ToolOptionCheckbox::ToolOptionCheckbox(TTool *tool, TBoolProperty *property, ToolHandle *toolHandle, |
| QWidget *parent) |
| : CheckBox(parent), ToolOptionControl(tool, property->getName(), toolHandle), m_property(property) |
| { |
| setText(property->getQStringName()); |
| m_property->addListener(this); |
| updateStatus(); |
| |
| if (toolHandle) |
| connect(this, SIGNAL(clicked(bool)), toolHandle, SIGNAL(toolChanged())); |
| } |
| |
| |
| |
| void ToolOptionCheckbox::updateStatus() |
| { |
| bool check = m_property->getValue(); |
| if (isChecked() == check) |
| return; |
| |
| setCheckState(check ? Qt::Checked : Qt::Unchecked); |
| } |
| |
| |
| |
| void ToolOptionCheckbox::nextCheckState() |
| { |
| QAbstractButton::nextCheckState(); |
| m_property->setValue(checkState() == Qt::Checked); |
| notifyTool(); |
| } |
| |
| |
| |
| void ToolOptionCheckbox::doClick() |
| { |
| if (m_toolHandle && m_toolHandle->getTool() != m_tool) |
| return; |
| |
| if (!isInVisibleViewer(this)) |
| return; |
| click(); |
| } |
| |
| |
| |
| ToolOptionSlider::ToolOptionSlider(TTool *tool, TDoubleProperty *property, ToolHandle *toolHandle) |
| : DoubleField(), ToolOptionControl(tool, property->getName(), toolHandle), m_property(property) |
| { |
| m_property->addListener(this); |
| TDoubleProperty::Range range = property->getRange(); |
| setRange(range.first, range.second); |
| updateStatus(); |
| connect(this, SIGNAL(valueChanged(bool)), SLOT(onValueChanged(bool))); |
| |
| if (toolHandle) |
| connect(this, SIGNAL(valueEditedByHand()), toolHandle, SIGNAL(toolChanged())); |
| } |
| |
| |
| |
| void ToolOptionSlider::updateStatus() |
| { |
| double v = m_property->getValue(); |
| if (getValue() == v) |
| return; |
| |
| setValue(v); |
| } |
| |
| |
| |
| void ToolOptionSlider::onValueChanged(bool isDragging) |
| { |
| m_property->setValue(getValue()); |
| notifyTool(); |
| } |
| |
| |
| |
| void ToolOptionSlider::increase() |
| { |
| if (m_toolHandle && m_toolHandle->getTool() != m_tool) |
| return; |
| |
| if (!isInVisibleViewer(this)) |
| return; |
| |
| double value = getValue(); |
| double minValue, maxValue; |
| getRange(minValue, maxValue); |
| |
| value += 1; |
| if (value > maxValue) |
| value = maxValue; |
| |
| setValue(value); |
| m_property->setValue(getValue()); |
| notifyTool(); |
| |
| repaint(); |
| } |
| |
| |
| |
| void ToolOptionSlider::decrease() |
| { |
| if (m_toolHandle && m_toolHandle->getTool() != m_tool) |
| return; |
| |
| if (!isInVisibleViewer(this)) |
| return; |
| |
| double value = getValue(); |
| double minValue, maxValue; |
| getRange(minValue, maxValue); |
| |
| value -= 1; |
| if (value < minValue) |
| value = minValue; |
| |
| setValue(value); |
| m_property->setValue(getValue()); |
| notifyTool(); |
| |
| repaint(); |
| } |
| |
| |
| |
| ToolOptionPairSlider::ToolOptionPairSlider(TTool *tool, TDoublePairProperty *property, |
| const QString &leftName, const QString &rightName, |
| ToolHandle *toolHandle) |
| : DoublePairField(0, property->isMaxRangeLimited()), ToolOptionControl(tool, property->getName(), toolHandle), m_property(property) |
| { |
| setLeftText(leftName); |
| setRightText(rightName); |
| m_property->addListener(this); |
| TDoublePairProperty::Value value = property->getValue(); |
| TDoublePairProperty::Range range = property->getRange(); |
| setRange(range.first, range.second); |
| updateStatus(); |
| connect(this, SIGNAL(valuesChanged(bool)), SLOT(onValuesChanged(bool))); |
| } |
| |
| |
| |
| void ToolOptionPairSlider::updateStatus() |
| { |
| TDoublePairProperty::Value value = m_property->getValue(); |
| setValues(value); |
| } |
| |
| |
| |
| void ToolOptionPairSlider::onValuesChanged(bool isDragging) |
| { |
| m_property->setValue(getValues()); |
| notifyTool(); |
| |
| if (m_toolHandle) |
| m_toolHandle->notifyToolChanged(); |
| } |
| |
| |
| |
| void ToolOptionPairSlider::increaseMaxValue() |
| { |
| if (m_toolHandle && m_toolHandle->getTool() != m_tool) |
| return; |
| |
| if (!isInVisibleViewer(this)) |
| return; |
| |
| std::pair<double, double> values = getValues(); |
| double minValue, maxValue; |
| getRange(minValue, maxValue); |
| values.second += 1; |
| if (values.second > maxValue) |
| values.second = maxValue; |
| setValues(values); |
| m_property->setValue(getValues()); |
| notifyTool(); |
| |
| repaint(); |
| } |
| |
| |
| |
| void ToolOptionPairSlider::decreaseMaxValue() |
| { |
| if (m_toolHandle && m_toolHandle->getTool() != m_tool) |
| return; |
| |
| if (!isInVisibleViewer(this)) |
| return; |
| |
| std::pair<double, double> values = getValues(); |
| values.second -= 1; |
| if (values.second < values.first) |
| values.second = values.first; |
| setValues(values); |
| m_property->setValue(getValues()); |
| notifyTool(); |
| |
| repaint(); |
| } |
| |
| |
| |
| void ToolOptionPairSlider::increaseMinValue() |
| { |
| if (m_toolHandle && m_toolHandle->getTool() != m_tool) |
| return; |
| |
| if (!isInVisibleViewer(this)) |
| return; |
| |
| std::pair<double, double> values = getValues(); |
| values.first += 1; |
| if (values.first > values.second) |
| values.first = values.second; |
| setValues(values); |
| m_property->setValue(getValues()); |
| notifyTool(); |
| |
| repaint(); |
| } |
| |
| |
| |
| void ToolOptionPairSlider::decreaseMinValue() |
| { |
| if (m_toolHandle && m_toolHandle->getTool() != m_tool) |
| return; |
| |
| if (!isInVisibleViewer(this)) |
| return; |
| |
| std::pair<double, double> values = getValues(); |
| double minValue, maxValue; |
| getRange(minValue, maxValue); |
| values.first -= 1; |
| if (values.first < minValue) |
| values.first = minValue; |
| setValues(values); |
| m_property->setValue(getValues()); |
| notifyTool(); |
| |
| repaint(); |
| } |
| |
| |
| |
| ToolOptionIntPairSlider::ToolOptionIntPairSlider(TTool *tool, TIntPairProperty *property, |
| const QString &leftName, const QString &rightName, |
| ToolHandle *toolHandle) |
| : IntPairField(0, property->isMaxRangeLimited()), ToolOptionControl(tool, property->getName(), toolHandle), m_property(property) |
| { |
| setLeftText(leftName); |
| setRightText(rightName); |
| m_property->addListener(this); |
| TIntPairProperty::Value value = property->getValue(); |
| TIntPairProperty::Range range = property->getRange(); |
| setRange(range.first, range.second); |
| updateStatus(); |
| connect(this, SIGNAL(valuesChanged(bool)), SLOT(onValuesChanged(bool))); |
| } |
| |
| |
| |
| void ToolOptionIntPairSlider::updateStatus() |
| { |
| TIntPairProperty::Value value = m_property->getValue(); |
| setValues(value); |
| } |
| |
| |
| |
| void ToolOptionIntPairSlider::onValuesChanged(bool isDragging) |
| { |
| m_property->setValue(getValues()); |
| notifyTool(); |
| |
| if (m_toolHandle) |
| m_toolHandle->notifyToolChanged(); |
| } |
| |
| |
| |
| void ToolOptionIntPairSlider::increaseMaxValue() |
| { |
| if (m_toolHandle && m_toolHandle->getTool() != m_tool) |
| return; |
| |
| if (!isInVisibleViewer(this)) |
| return; |
| |
| std::pair<int, int> values = getValues(); |
| int minValue, maxValue; |
| getRange(minValue, maxValue); |
| values.second += 1; |
| |
| |
| if (values.second == 3 && m_tool->isPencilModeActive()) |
| values.second += 1; |
| |
| if (values.second > maxValue) |
| values.second = maxValue; |
| setValues(values); |
| m_property->setValue(getValues()); |
| notifyTool(); |
| |
| repaint(); |
| } |
| |
| |
| |
| void ToolOptionIntPairSlider::decreaseMaxValue() |
| { |
| if (m_toolHandle && m_toolHandle->getTool() != m_tool) |
| return; |
| |
| if (!isInVisibleViewer(this)) |
| return; |
| |
| std::pair<int, int> values = getValues(); |
| values.second -= 1; |
| |
| |
| if (values.second == 3 && m_tool->isPencilModeActive()) |
| values.second -= 1; |
| |
| if (values.second < values.first) |
| values.second = values.first; |
| setValues(values); |
| m_property->setValue(getValues()); |
| notifyTool(); |
| |
| repaint(); |
| } |
| |
| |
| |
| void ToolOptionIntPairSlider::increaseMinValue() |
| { |
| if (m_toolHandle && m_toolHandle->getTool() != m_tool) |
| return; |
| |
| if (!isInVisibleViewer(this)) |
| return; |
| |
| std::pair<int, int> values = getValues(); |
| values.first += 1; |
| if (values.first > values.second) |
| values.first = values.second; |
| setValues(values); |
| m_property->setValue(getValues()); |
| notifyTool(); |
| |
| repaint(); |
| } |
| |
| |
| |
| void ToolOptionIntPairSlider::decreaseMinValue() |
| { |
| if (m_toolHandle && m_toolHandle->getTool() != m_tool) |
| return; |
| |
| if (!isInVisibleViewer(this)) |
| return; |
| |
| std::pair<int, int> values = getValues(); |
| int minValue, maxValue; |
| getRange(minValue, maxValue); |
| values.first -= 1; |
| if (values.first < minValue) |
| values.first = minValue; |
| setValues(values); |
| m_property->setValue(getValues()); |
| notifyTool(); |
| |
| repaint(); |
| } |
| |
| |
| |
| ToolOptionIntSlider::ToolOptionIntSlider(TTool *tool, TIntProperty *property, |
| ToolHandle *toolHandle) |
| : IntField(0, property->isMaxRangeLimited()), ToolOptionControl(tool, property->getName(), toolHandle), m_property(property) |
| { |
| m_property->addListener(this); |
| TIntProperty::Range range = property->getRange(); |
| setRange(range.first, range.second); |
| updateStatus(); |
| connect(this, SIGNAL(valueChanged(bool)), SLOT(onValueChanged(bool))); |
| |
| if (toolHandle) |
| connect(this, SIGNAL(valueEditedByHand()), toolHandle, SIGNAL(toolChanged())); |
| } |
| |
| |
| |
| void ToolOptionIntSlider::updateStatus() |
| { |
| int v = m_property->getValue(); |
| if (getValue() == v) |
| return; |
| |
| setValue(v); |
| } |
| |
| |
| |
| void ToolOptionIntSlider::increase() |
| { |
| if (m_toolHandle && m_toolHandle->getTool() != m_tool) |
| return; |
| |
| if (!isInVisibleViewer(this)) |
| return; |
| |
| int value = getValue(); |
| int minValue, maxValue; |
| getRange(minValue, maxValue); |
| value += 1; |
| |
| if (value == 3 && m_tool->isPencilModeActive()) |
| value += 1; |
| |
| if (value > maxValue) |
| value = maxValue; |
| |
| setValue(value); |
| m_property->setValue(getValue()); |
| notifyTool(); |
| |
| repaint(); |
| } |
| |
| |
| |
| void ToolOptionIntSlider::decrease() |
| { |
| if (m_toolHandle && m_toolHandle->getTool() != m_tool) |
| return; |
| |
| if (!isInVisibleViewer(this)) |
| return; |
| |
| int value = getValue(); |
| int minValue, maxValue; |
| getRange(minValue, maxValue); |
| value -= 1; |
| |
| |
| if (value == 3 && m_tool->isPencilModeActive()) |
| value -= 1; |
| |
| if (value < minValue) |
| value = minValue; |
| |
| setValue(value); |
| m_property->setValue(getValue()); |
| notifyTool(); |
| |
| repaint(); |
| } |
| |
| |
| |
| void ToolOptionIntSlider::onValueChanged(bool isDragging) |
| { |
| m_property->setValue(getValue()); |
| notifyTool(); |
| } |
| |
| |
| |
| ToolOptionCombo::ToolOptionCombo(TTool *tool, TEnumProperty *property, ToolHandle *toolHandle) |
| : QComboBox(), ToolOptionControl(tool, property->getName(), toolHandle), m_property(property) |
| { |
| setMinimumWidth(65); |
| m_property->addListener(this); |
| loadEntries(); |
| setSizeAdjustPolicy(QComboBox::AdjustToContents); |
| connect(this, SIGNAL(activated(int)), this, SLOT(onActivated(int))); |
| |
| if (toolHandle) |
| connect(this, SIGNAL(activated(int)), toolHandle, SIGNAL(toolChanged())); |
| } |
| |
| |
| |
| void ToolOptionCombo::loadEntries() |
| { |
| TEnumProperty::Range range = m_property->getRange(); |
| TEnumProperty::Range::iterator it; |
| |
| clear(); |
| for (it = range.begin(); it != range.end(); ++it) |
| addItem(QString::fromStdWString(*it)); |
| |
| updateStatus(); |
| } |
| |
| |
| |
| void ToolOptionCombo::updateStatus() |
| { |
| QString value = QString::fromStdWString(m_property->getValue()); |
| int index = findText(value); |
| if (index >= 0 && index != currentIndex()) |
| setCurrentIndex(index); |
| } |
| |
| |
| |
| void ToolOptionCombo::onActivated(int index) |
| { |
| const TEnumProperty::Range &range = m_property->getRange(); |
| if (index < 0 || index >= (int)range.size()) |
| return; |
| |
| std::wstring item = range[index]; |
| m_property->setValue(item); |
| notifyTool(); |
| } |
| |
| |
| |
| void ToolOptionCombo::doShowPopup() |
| { |
| if (isVisible()) |
| showPopup(); |
| } |
| |
| |
| |
| void ToolOptionCombo::doOnActivated(int index) |
| { |
| if (m_toolHandle && m_toolHandle->getTool() != m_tool) |
| return; |
| |
| if (!isInVisibleViewer(this)) |
| return; |
| |
| |
| if (itemText(0) != "Normal") { |
| onActivated(index); |
| setCurrentIndex(index); |
| |
| m_toolHandle->notifyToolChanged(); |
| return; |
| } |
| |
| |
| if (currentIndex() == index) { |
| |
| onActivated(0); |
| setCurrentIndex(0); |
| } else { |
| onActivated(index); |
| setCurrentIndex(index); |
| } |
| |
| |
| m_toolHandle->notifyToolCursorTypeChanged(); |
| } |
| |
| |
| |
| ToolOptionPopupButton::ToolOptionPopupButton(TTool *tool, TEnumProperty *property) |
| : PopupButton(), ToolOptionControl(tool, property->getName()), m_property(property) |
| { |
| setObjectName(QString::fromStdString(property->getName())); |
| setFixedHeight(20); |
| m_property->addListener(this); |
| |
| TEnumProperty::Range range = property->getRange(); |
| TEnumProperty::Range::iterator it; |
| for (it = range.begin(); it != range.end(); ++it) |
| addItem(createQIconPNG(QString::fromStdWString(*it).toUtf8())); |
| |
| setCurrentIndex(0); |
| updateStatus(); |
| connect(this, SIGNAL(activated(int)), this, SLOT(onActivated(int))); |
| } |
| |
| |
| |
| void ToolOptionPopupButton::updateStatus() |
| { |
| int index = m_property->getIndex(); |
| if (index >= 0 && index != currentIndex()) |
| setCurrentIndex(index); |
| } |
| |
| |
| |
| void ToolOptionPopupButton::onActivated(int index) |
| { |
| const TEnumProperty::Range &range = m_property->getRange(); |
| if (index < 0 || index >= (int)range.size()) |
| return; |
| |
| std::wstring item = range[index]; |
| m_property->setValue(item); |
| notifyTool(); |
| } |
| |
| |
| |
| void ToolOptionPopupButton::doShowPopup() |
| { |
| if (isVisible()) |
| showMenu(); |
| } |
| |
| |
| |
| void ToolOptionPopupButton::doSetCurrentIndex(int index) |
| { |
| if (isVisible()) |
| setCurrentIndex(index); |
| } |
| |
| |
| |
| void ToolOptionPopupButton::doOnActivated(int index) |
| { |
| if (isVisible()) |
| onActivated(index); |
| } |
| |
| |
| |
| ToolOptionTextField::ToolOptionTextField(TTool *tool, TStringProperty *property) |
| : LineEdit(), ToolOptionControl(tool, property->getName()), m_property(property) |
| { |
| setFixedSize(100, 23); |
| m_property->addListener(this); |
| |
| updateStatus(); |
| connect(this, SIGNAL(editingFinished()), SLOT(onValueChanged())); |
| } |
| |
| |
| |
| void ToolOptionTextField::updateStatus() |
| { |
| QString newText = QString::fromStdWString(m_property->getValue()); |
| if (newText == text()) |
| return; |
| |
| setText(newText); |
| } |
| |
| |
| |
| void ToolOptionTextField::onValueChanged() |
| { |
| m_property->setValue(text().toStdWString()); |
| notifyTool(); |
| |
| if (m_toolHandle) |
| m_toolHandle->notifyToolChanged(); |
| } |
| |
| |
| |
| StyleIndexFieldAndChip::StyleIndexFieldAndChip(TTool *tool, TStyleIndexProperty *property, TPaletteHandle *pltHandle, |
| ToolHandle *toolHandle) |
| : StyleIndexLineEdit(), ToolOptionControl(tool, property->getName(), toolHandle), m_property(property), m_pltHandle(pltHandle) |
| { |
| m_property->addListener(this); |
| |
| updateStatus(); |
| connect(this, SIGNAL(textChanged(const QString &)), SLOT(onValueChanged(const QString &))); |
| |
| setPaletteHandle(pltHandle); |
| connect(pltHandle, SIGNAL(colorStyleSwitched()), SLOT(updateColor())); |
| connect(pltHandle, SIGNAL(colorStyleChanged()), SLOT(updateColor())); |
| } |
| |
| |
| |
| void StyleIndexFieldAndChip::updateStatus() |
| { |
| QString newText = QString::fromStdWString(m_property->getValue()); |
| if (newText == text()) |
| return; |
| |
| setText(newText); |
| } |
| |
| |
| |
| void StyleIndexFieldAndChip::onValueChanged(const QString &changedText) |
| { |
| QString style; |
| |
| if (!QString("current").contains(changedText)) { |
| int index = changedText.toInt(); |
| TPalette *plt = m_pltHandle->getPalette(); |
| int indexCount = plt->getStyleCount(); |
| if (index > indexCount) |
| style = QString::number(indexCount - 1); |
| else |
| style = text(); |
| } |
| m_property->setValue(style.toStdWString()); |
| repaint(); |
| |
| if (m_toolHandle) |
| m_toolHandle->notifyToolChanged(); |
| } |
| |
| |
| |
| void StyleIndexFieldAndChip::updateColor() |
| { |
| repaint(); |
| } |
| |
| |
| |
| ToolOptionParamRelayField::ToolOptionParamRelayField( |
| TTool *tool, TDoubleParamRelayProperty *property, int decimals) |
| : MeasuredDoubleLineEdit(), ToolOptionControl(tool, property->getName()), m_param(), m_measure(), m_property(property), m_globalKey(), m_globalGroup() |
| { |
| setFixedSize(70, 20); |
| m_property->addListener(this); |
| |
| setDecimals(decimals); |
| updateStatus(); |
| connect(this, SIGNAL(valueChanged()), SLOT(onValueChanged())); |
| } |
| |
| |
| |
| void ToolOptionParamRelayField::setGlobalKey(TBoolProperty *globalKey, TPropertyGroup *globalGroup) |
| { |
| m_globalKey = globalKey, m_globalGroup = globalGroup; |
| } |
| |
| |
| |
| void ToolOptionParamRelayField::updateStatus() |
| { |
| TDoubleParamP param(m_property->getParam()); |
| if (param != m_param) { |
| |
| m_param = param.getPointer(); |
| |
| if (param) { |
| m_measure = param->getMeasure(); |
| setMeasure(m_measure ? m_measure->getName() : ""); |
| |
| setValue(m_property->getValue()); |
| } |
| } |
| |
| if (!param) { |
| setEnabled(false); |
| m_measure = 0; |
| setText(""); |
| |
| return; |
| } |
| |
| setEnabled(true); |
| |
| TMeasure *measure = param->getMeasure(); |
| if (measure != m_measure) { |
| |
| m_measure = measure; |
| setMeasure(measure ? measure->getName() : ""); |
| } |
| |
| double v = m_property->getValue(); |
| if (getValue() == v) |
| return; |
| |
| |
| setValue(v); |
| } |
| |
| |
| |
| void ToolOptionParamRelayField::onValueChanged() |
| { |
| struct locals { |
| static inline void setKeyframe(TDoubleParamRelayProperty *prop) |
| { |
| if (!prop) |
| return; |
| |
| TDoubleParam *param = prop->getParam().getPointer(); |
| if (!param) |
| return; |
| |
| double frame = prop->frame(); |
| if (!param->isKeyframe(frame)) { |
| KeyframeSetter setter(param, -1, true); |
| setter.createKeyframe(frame); |
| } |
| } |
| |
| |
| |
| struct SetValueUndo : public TUndo { |
| TDoubleParamP m_param; |
| double m_oldVal, m_newVal; |
| double m_frame; |
| |
| public: |
| SetValueUndo(const TDoubleParamP ¶m, double oldVal, double newVal, double frame) |
| : m_param(param), m_oldVal(oldVal), m_newVal(newVal), m_frame(frame) {} |
| |
| int getSize() const { return sizeof(SetValueUndo) + sizeof(TDoubleParam); } |
| void undo() const { m_param->setValue(m_frame, m_oldVal); } |
| void redo() const { m_param->setValue(m_frame, m_newVal); } |
| }; |
| }; |
| |
| |
| |
| |
| |
| double oldVal = m_property->getValue(), newVal = getValue(), frame = m_property->frame(); |
| |
| TDoubleParamP param = m_property->getParam(); |
| if (!param) |
| return; |
| |
| TUndoManager *manager = TUndoManager::manager(); |
| manager->beginBlock(); |
| |
| if (m_globalKey && m_globalGroup && m_globalKey->getValue()) { |
| |
| int p, pCount = m_globalGroup->getPropertyCount(); |
| for (p = 0; p != pCount; ++p) { |
| TProperty *prop = m_globalGroup->getProperty(p); |
| if (TDoubleParamRelayProperty *relProp = dynamic_cast<TDoubleParamRelayProperty *>(prop)) |
| locals::setKeyframe(relProp); |
| } |
| } else { |
| |
| locals::setKeyframe(m_property); |
| } |
| |
| |
| m_property->setValue(newVal); |
| notifyTool(); |
| |
| manager->add(new locals::SetValueUndo(param, oldVal, newVal, frame)); |
| manager->endBlock(); |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| using namespace DVGui; |
| |
| MeasuredValueField::MeasuredValueField(QWidget *parent, QString name) |
| : LineEdit(name, parent), m_isGlobalKeyframe(false), m_modified(false), m_errorHighlighting(false), m_precision(2) |
| { |
| setObjectName("MeasuredValueField"); |
| |
| m_value = new TMeasuredValue("length"); |
| setText(QString::fromStdWString(m_value->toWideString(m_precision))); |
| connect(this, SIGNAL(textChanged(const QString &)), this, SLOT(onTextChanged(const QString &))); |
| connect(this, SIGNAL(editingFinished()), SLOT(commit())); |
| connect(&m_errorHighlightingTimer, SIGNAL(timeout()), this, SLOT(errorHighlightingTick())); |
| } |
| |
| |
| |
| MeasuredValueField::~MeasuredValueField() |
| { |
| delete m_value; |
| } |
| |
| |
| |
| void MeasuredValueField::setMeasure(std::string name) |
| { |
| |
| int oldPrec = -1; |
| |
| delete m_value; |
| m_value = new TMeasuredValue(name != "" ? name : "dummy"); |
| |
| setText(QString::fromStdWString(m_value->toWideString(m_precision))); |
| } |
| |
| |
| |
| void MeasuredValueField::commit() |
| { |
| if (!m_modified && !isReturnPressed()) |
| return; |
| int err = 1; |
| bool isSet = m_value->setValue(text().toStdWString(), &err); |
| m_modified = false; |
| if (err != 0) { |
| setText(QString::fromStdWString(m_value->toWideString(m_precision))); |
| m_errorHighlighting = 1; |
| if (!m_errorHighlightingTimer.isActive()) |
| m_errorHighlightingTimer.start(40); |
| } else { |
| if (m_errorHighlightingTimer.isActive()) |
| m_errorHighlightingTimer.stop(); |
| m_errorHighlighting = 0; |
| setStyleSheet(""); |
| } |
| |
| if (!isSet && !isReturnPressed()) |
| return; |
| |
| setText(QString::fromStdWString(m_value->toWideString(m_precision))); |
| m_modified = false; |
| emit measuredValueChanged(m_value); |
| } |
| |
| |
| |
| void MeasuredValueField::onTextChanged(const QString &) |
| { |
| m_modified = true; |
| } |
| |
| |
| |
| void MeasuredValueField::setValue(double v) |
| { |
| if (getValue() == v) |
| return; |
| m_value->setValue(TMeasuredValue::MainUnit, v); |
| setText(QString::fromStdWString(m_value->toWideString(m_precision))); |
| } |
| |
| |
| |
| double MeasuredValueField::getValue() const |
| { |
| return m_value->getValue(TMeasuredValue::MainUnit); |
| } |
| |
| |
| |
| void MeasuredValueField::errorHighlightingTick() |
| { |
| if (m_errorHighlighting < 0.01) { |
| if (m_errorHighlightingTimer.isActive()) |
| m_errorHighlightingTimer.stop(); |
| m_errorHighlighting = 0; |
| setStyleSheet(""); |
| } else { |
| int v = 255 - (int)(m_errorHighlighting * 255); |
| m_errorHighlighting = m_errorHighlighting * 0.8; |
| int c = 255 << 16 | v << 8 | v; |
| setStyleSheet(QString("#MeasuredValueField {background-color:#%1}").arg(c, 6, 16, QLatin1Char('0'))); |
| } |
| } |
| |
| |
| |
| void MeasuredValueField::setPrecision(int precision) |
| { |
| m_precision = precision; |
| setText(QString::fromStdWString(m_value->toWideString(m_precision))); |
| } |
| |
| |
| |
| PegbarChannelField::PegbarChannelField(TTool *tool, enum TStageObject::Channel actionId, QString name, |
| TFrameHandle *frameHandle, TObjectHandle *objHandle, TXsheetHandle *xshHandle, |
| QWidget *parent) |
| : MeasuredValueField(parent, name), ToolOptionControl(tool, ""), m_actionId(actionId), m_frameHandle(frameHandle), m_objHandle(objHandle), m_xshHandle(xshHandle), m_scaleType(eNone) |
| { |
| bool ret = connect(this, SIGNAL(measuredValueChanged(TMeasuredValue *)), |
| SLOT(onChange(TMeasuredValue *))); |
| assert(ret); |
| |
| switch (actionId) { |
| case TStageObject::T_X: |
| setMeasure("length.x"); |
| break; |
| case TStageObject::T_Y: |
| setMeasure("length.y"); |
| break; |
| case TStageObject::T_Z: |
| setMeasure("zdepth"); |
| break; |
| case TStageObject::T_Path: |
| setMeasure("percentage2"); |
| break; |
| case TStageObject::T_ShearX: |
| case TStageObject::T_ShearY: |
| setMeasure("shear"); |
| break; |
| case TStageObject::T_Angle: |
| setMeasure("angle"); |
| break; |
| case TStageObject::T_ScaleX: |
| case TStageObject::T_ScaleY: |
| case TStageObject::T_Scale: |
| setMeasure("scale"); |
| break; |
| default: |
| setMeasure("dummy"); |
| break; |
| } |
| updateStatus(); |
| } |
| |
| |
| |
| void PegbarChannelField::onChange(TMeasuredValue *fld) |
| { |
| if (!m_tool->isEnabled()) |
| return; |
| TUndoManager::manager()->beginBlock(); |
| TStageObjectValues before; |
| before.setFrameHandle(m_frameHandle); |
| before.setObjectHandle(m_objHandle); |
| before.setXsheetHandle(m_xshHandle); |
| before.add(m_actionId); |
| bool modifyConnectedActionId = false; |
| if (m_scaleType != eNone) { |
| modifyConnectedActionId = true; |
| if (m_actionId == TStageObject::T_ScaleX) |
| before.add(TStageObject::T_ScaleY); |
| else if (m_actionId == TStageObject::T_ScaleY) |
| before.add(TStageObject::T_ScaleX); |
| else |
| modifyConnectedActionId = false; |
| } |
| if (m_isGlobalKeyframe) { |
| before.add(TStageObject::T_Angle); |
| before.add(TStageObject::T_X); |
| before.add(TStageObject::T_Y); |
| before.add(TStageObject::T_Z); |
| before.add(TStageObject::T_SO); |
| before.add(TStageObject::T_ScaleX); |
| before.add(TStageObject::T_ScaleY); |
| before.add(TStageObject::T_Scale); |
| before.add(TStageObject::T_Path); |
| before.add(TStageObject::T_ShearX); |
| before.add(TStageObject::T_ShearY); |
| } |
| before.updateValues(); |
| TStageObjectValues after; |
| after = before; |
| double v = fld->getValue(TMeasuredValue::MainUnit); |
| if (modifyConnectedActionId) { |
| double oldv1 = after.getValue(0); |
| double oldv2 = after.getValue(1); |
| double newV; |
| if (m_scaleType == eAR) |
| newV = (v / oldv1) * oldv2; |
| else |
| newV = (v == 0) ? 10000 : (1 / v) * (oldv1 * oldv2); |
| after.setValues(v, newV); |
| } else |
| after.setValue(v); |
| after.applyValues(); |
| |
| TTool::Viewer *viewer = m_tool->getViewer(); |
| if (viewer) |
| m_tool->invalidate(); |
| setCursorPosition(0); |
| |
| UndoStageObjectMove *undo = new UndoStageObjectMove(before, after); |
| undo->setObjectHandle(m_objHandle); |
| TUndoManager::manager()->add(undo); |
| TUndoManager::manager()->endBlock(); |
| m_objHandle->notifyObjectIdChanged(false); |
| } |
| |
| |
| |
| void PegbarChannelField::updateStatus() |
| { |
| TXsheet *xsh = m_tool->getXsheet(); |
| int frame = m_tool->getFrame(); |
| TStageObjectId objId = m_tool->getObjectId(); |
| if (m_actionId == TStageObject::T_Z) |
| setMeasure(objId.isCamera() ? "zdepth.cam" : "zdepth"); |
| |
| double v = xsh->getStageObject(objId)->getParam(m_actionId, frame); |
| |
| if (getValue() == v) |
| return; |
| setValue(v); |
| setCursorPosition(0); |
| } |
| |
| |
| |
| void PegbarChannelField::onScaleTypeChanged(int type) |
| { |
| m_scaleType = (ScaleType)type; |
| } |
| |
| |
| |
| PegbarCenterField::PegbarCenterField(TTool *tool, int index, QString name, TObjectHandle *objHandle, TXsheetHandle *xshHandle, |
| QWidget *parent) |
| : MeasuredValueField(parent, name), ToolOptionControl(tool, ""), m_index(index), m_objHandle(objHandle), m_xshHandle(xshHandle) |
| { |
| TStageObjectId objId = m_tool->getObjectId(); |
| setMeasure(m_index == 0 ? "length.x" : "length.y"); |
| connect(this, SIGNAL(measuredValueChanged(TMeasuredValue *)), SLOT(onChange(TMeasuredValue *))); |
| updateStatus(); |
| } |
| |
| |
| |
| void PegbarCenterField::onChange(TMeasuredValue *fld) |
| { |
| if (!m_tool->isEnabled()) |
| return; |
| TXsheet *xsh = m_tool->getXsheet(); |
| int frame = m_tool->getFrame(); |
| TStageObjectId objId = m_tool->getObjectId(); |
| |
| TStageObject *obj = xsh->getStageObject(objId); |
| |
| double v = fld->getValue(TMeasuredValue::MainUnit); |
| TPointD center = obj->getCenter(frame); |
| TPointD oldCenter = center; |
| if (m_index == 0) |
| center.x = v; |
| else |
| center.y = v; |
| obj->setCenter(frame, center); |
| m_tool->invalidate(); |
| |
| UndoStageObjectCenterMove *undo = new UndoStageObjectCenterMove(objId, frame, oldCenter, center); |
| undo->setObjectHandle(m_objHandle); |
| undo->setXsheetHandle(m_xshHandle); |
| TUndoManager::manager()->add(undo); |
| |
| m_objHandle->notifyObjectIdChanged(false); |
| } |
| |
| |
| |
| void PegbarCenterField::updateStatus() |
| { |
| TXsheet *xsh = m_tool->getXsheet(); |
| int frame = m_tool->getFrame(); |
| TStageObjectId objId = m_tool->getObjectId(); |
| TStageObject *obj = xsh->getStageObject(objId); |
| TPointD center = obj->getCenter(frame); |
| |
| double v = m_index == 0 ? center.x : center.y; |
| if (getValue() == v) |
| return; |
| setValue(v); |
| } |
| |
| |
| |
| NoScaleField::NoScaleField(TTool *tool, QString name) |
| : MeasuredValueField(0, name), ToolOptionControl(tool, "") |
| { |
| TStageObjectId objId = m_tool->getObjectId(); |
| setMeasure("zdepth"); |
| connect(this, SIGNAL(measuredValueChanged(TMeasuredValue *)), |
| SLOT(onChange(TMeasuredValue *))); |
| updateStatus(); |
| } |
| |
| |
| |
| void NoScaleField::onChange(TMeasuredValue *fld) |
| { |
| if (!m_tool->isEnabled()) |
| return; |
| TXsheet *xsh = m_tool->getXsheet(); |
| int frame = m_tool->getFrame(); |
| TStageObjectId objId = m_tool->getObjectId(); |
| TStageObject *obj = xsh->getStageObject(objId); |
| |
| if (m_isGlobalKeyframe) |
| xsh->getStageObject(objId)->setKeyframeWithoutUndo(frame); |
| |
| double v = fld->getValue(TMeasuredValue::MainUnit); |
| obj->setNoScaleZ(v); |
| m_tool->invalidate(); |
| } |
| |
| |
| |
| void NoScaleField::updateStatus() |
| { |
| TXsheet *xsh = m_tool->getXsheet(); |
| int frame = m_tool->getFrame(); |
| TStageObjectId objId = m_tool->getObjectId(); |
| TStageObject *obj = xsh->getStageObject(objId); |
| |
| double v = obj->getNoScaleZ(); |
| if (getValue() == v) |
| return; |
| setValue(v); |
| } |
| |
| |
| |
| PropertyMenuButton::PropertyMenuButton(QWidget *parent, TTool *tool, |
| QList<TBoolProperty *> properties, |
| QIcon icon, QString tooltip) |
| : QToolButton(parent), ToolOptionControl(tool, ""), m_properties(properties) |
| { |
| setPopupMode(QToolButton::InstantPopup); |
| setIcon(icon); |
| setToolTip(tooltip); |
| |
| QMenu *menu = new QMenu(tooltip, this); |
| if (!tooltip.isEmpty()) |
| tooltip = tooltip + " "; |
| |
| QActionGroup *actiongroup = new QActionGroup(this); |
| actiongroup->setExclusive(false); |
| int i; |
| for (i = 0; i < m_properties.count(); i++) { |
| TBoolProperty *prop = m_properties.at(i); |
| QString propertyName = prop->getQStringName(); |
| |
| if (propertyName.contains(tooltip)) |
| propertyName.remove(tooltip); |
| QAction *action = menu->addAction(propertyName); |
| action->setCheckable(true); |
| action->setChecked(prop->getValue()); |
| action->setData(QVariant(i)); |
| actiongroup->addAction(action); |
| } |
| bool ret = connect(actiongroup, SIGNAL(triggered(QAction *)), SLOT(onActionTriggered(QAction *))); |
| assert(ret); |
| |
| setMenu(menu); |
| } |
| |
| |
| |
| void PropertyMenuButton::updateStatus() |
| { |
| QMenu *m = menu(); |
| assert(m); |
| QList<QAction *> actionList = m->actions(); |
| assert(actionList.count() == m_properties.count()); |
| |
| int i; |
| for (i = 0; i < m_properties.count(); i++) { |
| TBoolProperty *prop = m_properties.at(i); |
| QAction *action = actionList.at(i); |
| bool isPropertyLocked = prop->getValue(); |
| if (action->isChecked() != isPropertyLocked) |
| action->setChecked(isPropertyLocked); |
| } |
| } |
| |
| |
| |
| void PropertyMenuButton::onActionTriggered(QAction *action) |
| { |
| int currentPropertyIndex = action->data().toInt(); |
| TBoolProperty *prop = m_properties.at(currentPropertyIndex); |
| bool isChecked = action->isChecked(); |
| if (isChecked == prop->getValue()) |
| return; |
| prop->setValue(isChecked); |
| notifyTool(); |
| |
| emit onPropertyChanged(QString(prop->getName().c_str())); |
| } |
| |
| |
| |
| |
| SelectionScaleField::SelectionScaleField(SelectionTool *tool, int id, QString name) |
| : MeasuredValueField(0, name), m_tool(tool), m_id(id) |
| { |
| bool ret = connect(this, SIGNAL(measuredValueChanged(TMeasuredValue *)), SLOT(onChange(TMeasuredValue *))); |
| assert(ret); |
| setMeasure("scale"); |
| updateStatus(); |
| } |
| |
| |
| |
| bool SelectionScaleField::applyChange() |
| { |
| if (!m_tool || (m_tool->isSelectionEmpty() && !m_tool->isLevelType())) |
| return false; |
| DragSelectionTool::DragTool *scaleTool = createNewScaleTool(m_tool, 0); |
| double p = getValue(); |
| if (p == 0) |
| p = 0.00001; |
| DragSelectionTool::FourPoints points = m_tool->getBBox(); |
| TPointD center = m_tool->getCenter(); |
| TPointD p0M = points.getPoint(7); |
| TPointD p1M = points.getPoint(5); |
| TPointD pM1 = points.getPoint(6); |
| TPointD pM0 = points.getPoint(4); |
| int pointIndex; |
| TPointD sign(1, 1); |
| TPointD scaleFactor = m_tool->m_deformValues.m_scaleValue; |
| TPointD newPos; |
| if (m_id == 0) { |
| if (p1M == p0M) |
| return false; |
| pointIndex = 7; |
| TPointD v = normalize(p1M - p0M); |
| double currentD = tdistance(p1M, p0M); |
| double startD = currentD / scaleFactor.x; |
| double d = (currentD - startD * p) * tdistance(center, p0M) / currentD; |
| newPos = TPointD(p0M.x + d * v.x, p0M.y + d * v.y); |
| scaleFactor.x = p; |
| } else if (m_id == 1) { |
| if (pM1 == pM0) |
| return false; |
| pointIndex = 4; |
| TPointD v = normalize(pM1 - pM0); |
| double currentD = tdistance(pM1, pM0); |
| double startD = currentD / scaleFactor.y; |
| double d = (currentD - startD * p) * tdistance(center, pM0) / currentD; |
| newPos = TPointD(pM0.x + d * v.x, pM0.y + d * v.y); |
| scaleFactor.y = p; |
| } |
| |
| m_tool->m_deformValues.m_scaleValue = scaleFactor; |
| scaleTool->transform(pointIndex, newPos); |
| |
| if (!m_tool->isLevelType()) |
| scaleTool->addTransformUndo(); |
| setCursorPosition(0); |
| return true; |
| } |
| |
| |
| |
| void SelectionScaleField::onChange(TMeasuredValue *fld) |
| { |
| if (!m_tool->isEnabled()) |
| return; |
| if (!applyChange()) |
| return; |
| emit valueChange(); |
| } |
| |
| |
| |
| void SelectionScaleField::updateStatus() |
| { |
| if (!m_tool || (m_tool->isSelectionEmpty() && !m_tool->isLevelType())) { |
| setValue(0); |
| setDisabled(true); |
| return; |
| } |
| setDisabled(false); |
| if (m_id == 0) |
| setValue(m_tool->m_deformValues.m_scaleValue.x); |
| else |
| setValue(m_tool->m_deformValues.m_scaleValue.y); |
| setCursorPosition(0); |
| } |
| |
| |
| |
| SelectionRotationField::SelectionRotationField(SelectionTool *tool, QString name) |
| : MeasuredValueField(0, name), m_tool(tool) |
| { |
| bool ret = connect(this, SIGNAL(measuredValueChanged(TMeasuredValue *)), SLOT(onChange(TMeasuredValue *))); |
| assert(ret); |
| setMeasure("angle"); |
| updateStatus(); |
| } |
| |
| |
| |
| void SelectionRotationField::onChange(TMeasuredValue *fld) |
| { |
| if (!m_tool || !m_tool->isEnabled() || (m_tool->isSelectionEmpty() && !m_tool->isLevelType())) |
| return; |
| |
| DragSelectionTool::DragTool *rotationTool = createNewRotationTool(m_tool); |
| |
| DragSelectionTool::DeformValues &deformValues = m_tool->m_deformValues; |
| double p = getValue(); |
| |
| TAffine aff = TRotation(m_tool->getCenter(), p - deformValues.m_rotationAngle); |
| |
| deformValues.m_rotationAngle = p; |
| rotationTool->transform(aff, p - deformValues.m_rotationAngle); |
| |
| if (!m_tool->isLevelType()) |
| rotationTool->addTransformUndo(); |
| |
| setCursorPosition(0); |
| } |
| |
| |
| |
| void SelectionRotationField::updateStatus() |
| { |
| if (!m_tool || (m_tool->isSelectionEmpty() && !m_tool->isLevelType())) { |
| setValue(0); |
| setDisabled(true); |
| return; |
| } |
| setDisabled(false); |
| setValue(m_tool->m_deformValues.m_rotationAngle); |
| setCursorPosition(0); |
| } |
| |
| |
| |
| |
| SelectionMoveField::SelectionMoveField(SelectionTool *tool, int id, QString name) |
| : MeasuredValueField(0, name), m_tool(tool), m_id(id) |
| { |
| bool ret = connect(this, SIGNAL(measuredValueChanged(TMeasuredValue *)), SLOT(onChange(TMeasuredValue *))); |
| assert(ret); |
| if (m_id == 0) |
| setMeasure("length.x"); |
| else |
| setMeasure("length.y"); |
| updateStatus(); |
| } |
| |
| |
| |
| void SelectionMoveField::onChange(TMeasuredValue *fld) |
| { |
| if (!m_tool || !m_tool->isEnabled() || (m_tool->isSelectionEmpty() && !m_tool->isLevelType())) |
| return; |
| |
| DragSelectionTool::DragTool *moveTool = createNewMoveSelectionTool(m_tool); |
| |
| double p = getValue() * Stage::inch; |
| TPointD delta = (m_id == 0) ? TPointD(p, 1) : TPointD(1, p), |
| oldMove = Stage::inch * m_tool->m_deformValues.m_moveValue, |
| oldDelta = (m_id == 0) ? TPointD(oldMove.x, 1) : TPointD(1, oldMove.y), |
| newMove = (m_id == 0) ? TPointD(delta.x, oldMove.y) : TPointD(oldMove.x, delta.y); |
| |
| TAffine aff = TTranslation(-oldDelta) * TTranslation(delta); |
| |
| m_tool->m_deformValues.m_moveValue = 1 / Stage::inch * newMove; |
| moveTool->transform(aff); |
| |
| if (!m_tool->isLevelType()) |
| moveTool->addTransformUndo(); |
| |
| setCursorPosition(0); |
| } |
| |
| |
| |
| void SelectionMoveField::updateStatus() |
| { |
| if (!m_tool || (m_tool->isSelectionEmpty() && !m_tool->isLevelType())) { |
| setValue(0); |
| setDisabled(true); |
| return; |
| } |
| setDisabled(false); |
| |
| if (m_id == 0) |
| setValue(m_tool->m_deformValues.m_moveValue.x); |
| else |
| setValue(m_tool->m_deformValues.m_moveValue.y); |
| |
| setCursorPosition(0); |
| } |
| |
| |
| |
| ThickChangeField::ThickChangeField(SelectionTool *tool, QString name) |
| : MeasuredValueField(0, name), m_tool(tool) |
| { |
| bool ret = connect(this, SIGNAL(measuredValueChanged(TMeasuredValue *)), SLOT(onChange(TMeasuredValue *))); |
| assert(ret); |
| setMeasure(""); |
| updateStatus(); |
| } |
| |
| |
| |
| void ThickChangeField::onChange(TMeasuredValue *fld) |
| { |
| if (!m_tool || (m_tool->isSelectionEmpty() && !m_tool->isLevelType())) |
| return; |
| |
| DragSelectionTool::VectorChangeThicknessTool *changeThickTool = new DragSelectionTool::VectorChangeThicknessTool((VectorSelectionTool *)m_tool); |
| |
| TVectorImageP vi = (TVectorImageP)m_tool->getImage(true); |
| |
| double p = 0.5 * getValue(); |
| double newThickness = p - m_tool->m_deformValues.m_maxSelectionThickness; |
| |
| changeThickTool->setThicknessChange(newThickness); |
| changeThickTool->changeImageThickness(*vi, newThickness); |
| |
| |
| |
| |
| changeThickTool->addUndo(); |
| m_tool->computeBBox(); |
| m_tool->invalidate(); |
| m_tool->notifyImageChanged(m_tool->getCurrentFid()); |
| } |
| |
| |
| |
| void ThickChangeField::updateStatus() |
| { |
| if (!m_tool || m_tool->m_deformValues.m_isSelectionModified || (m_tool->isSelectionEmpty() && !m_tool->isLevelType())) { |
| setValue(0); |
| setDisabled(true); |
| return; |
| } |
| |
| setDisabled(false); |
| setValue(2 * m_tool->m_deformValues.m_maxSelectionThickness); |
| setCursorPosition(0); |
| } |
| |