tahoma2d/toonz/sources/tnztools/tooloptionscontrols.cpp

1534 lines
51 KiB
C++
Raw Normal View History

2016-03-19 06:57:51 +13:00
// TnzCore includes
#include "tpalette.h"
#include "tcolorstyles.h"
#include "tundo.h"
// TnzBase includes
#include "tproperty.h"
// TnzLib includes
#include "toonz/palettecontroller.h"
#include "toonz/tpalettehandle.h"
#include "toonz/tobjecthandle.h"
#include "toonz/stage2.h"
#include "toonz/doubleparamcmd.h"
#include "toonz/preferences.h"
2016-03-19 06:57:51 +13:00
// TnzQt includes
#include "toonzqt/gutil.h"
// TnzTools includes
#include "tools/tool.h"
#include "rasterselectiontool.h"
#include "vectorselectiontool.h"
// to enable the increase/decrease shortcuts while hiding the tool option
#include "tools/toolhandle.h"
// to enable shortcuts only when the viewer is focused
#include "tools/tooloptions.h"
// Qt includes
#include <QPainter>
#include <QVBoxLayout>
#include <QMouseEvent>
#include <QAction>
#include <QLabel>
#include <QMainWindow>
#include <QButtonGroup>
#include <QMenu>
#include <QListView>
2016-03-19 06:57:51 +13:00
#include "tooloptionscontrols.h"
using namespace DVGui;
//***********************************************************************************
// ToolOptionControl implementation
//***********************************************************************************
2016-06-15 18:43:10 +12:00
ToolOptionControl::ToolOptionControl(TTool *tool, std::string propertyName,
ToolHandle *toolHandle)
: m_tool(tool), m_propertyName(propertyName), m_toolHandle(toolHandle) {}
2016-03-19 06:57:51 +13:00
//-----------------------------------------------------------------------------
void ToolOptionControl::notifyTool(bool addToUndo) {
std::string tempPropertyName = m_propertyName;
if (addToUndo && m_propertyName == "Maximum Gap")
tempPropertyName = tempPropertyName + "withUndo";
m_tool->onPropertyChanged(tempPropertyName);
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
/*! return true if the control is belonging to the visible combo viewer. very
* dirty implementation.
2018-05-07 14:09:06 +12:00
*/
2016-06-15 18:43:10 +12:00
bool ToolOptionControl::isInVisibleViewer(QWidget *widget) {
if (!widget) return false;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
if (widget->isVisible()) return true;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
ToolOptionsBox *parentTOB =
dynamic_cast<ToolOptionsBox *>(widget->parentWidget());
if (!parentTOB) return false;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
ToolOptions *grandParentTO =
dynamic_cast<ToolOptions *>(parentTOB->parentWidget());
if (!grandParentTO) return false;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
// There must be a QFrame between a ComboViewerPanel and a ToolOptions
QFrame *greatGrandParentFrame =
dynamic_cast<QFrame *>(grandParentTO->parentWidget());
if (!greatGrandParentFrame) return false;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
return greatGrandParentFrame->isVisible();
2016-03-19 06:57:51 +13:00
}
//***********************************************************************************
// ToolOptionControl derivative implementations
//***********************************************************************************
2016-06-15 18:43:10 +12:00
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();
// synchronize the state with the same widgets in other tool option bars
if (toolHandle)
connect(this, SIGNAL(clicked(bool)), toolHandle, SIGNAL(toolChanged()));
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void ToolOptionCheckbox::updateStatus() {
bool check = m_property->getValue();
2016-03-19 06:57:51 +13:00
2017-10-26 20:55:46 +13:00
if (isChecked() == check) return;
2016-03-19 06:57:51 +13:00
2017-10-26 20:55:46 +13:00
setCheckState(check ? Qt::Checked : Qt::Unchecked);
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2017-11-08 17:21:55 +13:00
void ToolOptionCheckbox::nextCheckState() {
QAbstractButton::nextCheckState();
m_property->setValue(checkState() == Qt::Checked);
notifyTool();
}
2016-03-19 06:57:51 +13:00
//=============================================================================
2016-06-15 18:43:10 +12:00
ToolOptionSlider::ToolOptionSlider(TTool *tool, TDoubleProperty *property,
ToolHandle *toolHandle)
: DoubleField()
, ToolOptionControl(tool, property->getName(), toolHandle)
, m_property(property) {
setLinearSlider(property->isLinearSlider());
2016-06-15 18:43:10 +12:00
m_property->addListener(this);
TDoubleProperty::Range range = property->getRange();
setRange(range.first, range.second);
// calculate maximum text length which includes length for decimals (for now
// it's fixed to 2) and period
int textMaxLength = std::max(QString::number((int)range.first).length(),
QString::number((int)range.second).length()) +
m_lineEdit->getDecimals() + 1;
QString txt;
// set the maximum width of the widget according to the text length (with 5
// pixels margin)
txt.fill('0', textMaxLength);
int widgetWidth = fontMetrics().width(txt) + 5;
m_lineEdit->parentWidget()->setMaximumWidth(widgetWidth);
// set the maximum width of the slider to 250 pixels
setMaximumWidth(250 + widgetWidth);
2020-05-12 18:27:39 +12:00
setMinimumWidth(50 + widgetWidth);
2016-06-15 18:43:10 +12:00
updateStatus();
connect(this, SIGNAL(valueChanged(bool)), SLOT(onValueChanged(bool)));
// synchronize the state with the same widgets in other tool option bars
if (toolHandle)
connect(this, SIGNAL(valueEditedByHand()), toolHandle,
SIGNAL(toolChanged()));
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void ToolOptionSlider::updateStatus() {
double v = m_property->getValue();
if (getValue() == v) return;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
setValue(v);
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void ToolOptionSlider::onValueChanged(bool isDragging) {
m_property->setValue(getValue());
notifyTool(!isDragging);
2016-03-19 06:57:51 +13:00
}
//=============================================================================
2016-06-15 18:43:10 +12:00
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) {
setLinearSlider(property->isLinearSlider());
2016-06-15 18:43:10 +12:00
m_property->addListener(this);
TDoublePairProperty::Value value = property->getValue();
TDoublePairProperty::Range range = property->getRange();
setRange(range.first, range.second);
// calculate maximum text length which includes length for decimals (for now
// it's fixed to 2) and period
int textMaxLength = std::max(QString::number((int)range.first).length(),
QString::number((int)range.second).length()) +
m_leftLineEdit->getDecimals() + 1;
QString txt;
// set the maximum width of the widget according to the text length (with 5
// pixels margin)
txt.fill('0', textMaxLength);
int widgetWidth = fontMetrics().width(txt) + 5;
m_leftLineEdit->setFixedWidth(widgetWidth);
m_rightLineEdit->setFixedWidth(widgetWidth);
m_leftMargin = widgetWidth + 12;
m_rightMargin = widgetWidth + 12;
// set the maximum width of the slider to 300 pixels
setMaximumWidth(300 + m_leftMargin + m_rightMargin);
2020-05-12 18:27:39 +12:00
setMinimumWidth(120 + m_leftMargin + m_rightMargin);
setLeftText(leftName);
setRightText(rightName);
2016-06-15 18:43:10 +12:00
updateStatus();
connect(this, SIGNAL(valuesChanged(bool)), SLOT(onValuesChanged(bool)));
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void ToolOptionPairSlider::updateStatus() {
TDoublePairProperty::Value value = m_property->getValue();
setValues(value);
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void ToolOptionPairSlider::onValuesChanged(bool isDragging) {
m_property->setValue(getValues());
notifyTool();
// synchronize the state with the same widgets in other tool option bars
if (m_toolHandle) m_toolHandle->notifyToolChanged();
2016-03-19 06:57:51 +13:00
}
//=============================================================================
2016-06-15 18:43:10 +12:00
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) {
setLinearSlider(property->isLinearSlider());
2016-06-15 18:43:10 +12:00
setLeftText(leftName);
setRightText(rightName);
m_property->addListener(this);
TIntPairProperty::Value value = property->getValue();
TIntPairProperty::Range range = property->getRange();
setRange(range.first, range.second);
setMaximumWidth(300);
2020-05-12 18:27:39 +12:00
setMinimumWidth(200);
2016-06-15 18:43:10 +12:00
updateStatus();
connect(this, SIGNAL(valuesChanged(bool)), SLOT(onValuesChanged(bool)));
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void ToolOptionIntPairSlider::updateStatus() {
TIntPairProperty::Value value = m_property->getValue();
setValues(value);
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void ToolOptionIntPairSlider::onValuesChanged(bool isDragging) {
m_property->setValue(getValues());
notifyTool();
// synchronize the state with the same widgets in other tool option bars
if (m_toolHandle) m_toolHandle->notifyToolChanged();
2016-03-19 06:57:51 +13:00
}
//=============================================================================
ToolOptionIntSlider::ToolOptionIntSlider(TTool *tool, TIntProperty *property,
2016-06-15 18:43:10 +12:00
ToolHandle *toolHandle)
: IntField(0, property->isMaxRangeLimited())
, ToolOptionControl(tool, property->getName(), toolHandle)
, m_property(property) {
setLinearSlider(property->isLinearSlider());
2016-06-15 18:43:10 +12:00
m_property->addListener(this);
TIntProperty::Range range = property->getRange();
setRange(range.first, range.second);
setMaximumWidth(300);
2020-05-12 18:27:39 +12:00
setMinimumWidth(50);
2016-06-15 18:43:10 +12:00
updateStatus();
connect(this, SIGNAL(valueChanged(bool)), SLOT(onValueChanged(bool)));
// synchronize the state with the same widgets in other tool option bars
if (toolHandle)
connect(this, SIGNAL(valueEditedByHand()), toolHandle,
SIGNAL(toolChanged()));
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void ToolOptionIntSlider::updateStatus() {
int v = m_property->getValue();
if (getValue() == v) return;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
setValue(v);
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void ToolOptionIntSlider::onValueChanged(bool isDragging) {
m_property->setValue(getValue());
notifyTool();
2016-03-19 06:57:51 +13:00
}
//=============================================================================
2016-06-15 18:43:10 +12:00
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)));
// synchronize the state with the same widgets in other tool option bars
if (toolHandle) {
2016-06-15 18:43:10 +12:00
connect(this, SIGNAL(activated(int)), toolHandle, SIGNAL(toolChanged()));
}
}
//-----------------------------------------------------------------------------
void ToolOptionCombo::reloadComboBoxList(std::string id) {
if (id == "" || m_property->getName() != id) return;
loadEntries();
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void ToolOptionCombo::loadEntries() {
const TEnumProperty::Range &range = m_property->getRange();
const TEnumProperty::Items &items = m_property->getItems();
2016-03-19 06:57:51 +13:00
const int count = m_property->getCount();
int maxWidth = 0;
2016-06-15 18:43:10 +12:00
clear();
bool hasIcon = false;
for (int i = 0; i < count; ++i) {
QString itemStr = QString::fromStdWString(range[i]);
if (items[i].iconName.isEmpty())
addItem(items[i].UIName, itemStr);
else {
addItem(createQIcon(items[i].iconName.toUtf8()), items[i].UIName,
itemStr);
if (!hasIcon) {
hasIcon = true;
UI update and Icons from Konero (#126) * add multi arc mockup * implement mutli arc * add join and smooth option * reset multiarc and arc when deactivated * create self loop if the last point is the same as the first * make join option in multiarc consistent with tape tool * fix a bug where thickness don't affect mutliarc in vector level * remove join option in geometric tool * stop mutliarc after closing shape * double click can also end multi arc * fix a bug where multiArc will produce buggy stroke * fix a bug where geometric tools is not deactivated * add multiArc shortcut * rewrite multiArc * revert changes to tvectorimage * add undo data for multiArc * Paste as Copy Command for XSheet * Remove unneeded code * Bug fix * prevent guide lines from jumping around in MultiArc * make stroke color consistent in MultiArc * remove color in MultiArc's undo data * make color consistent in MultiArc with previous version * Fix single image raster levels * fix compilation error * fix a bug where multiArc might generate bugged stroke * Remove ICONV dep (#3304) * fix crash on saving studio palette * Move to Paste Special Menu * Don't Set Fixed Width if Docking a Floating Panel * Update how_to_build_win.md New draft of pr for requested changes to windows build instructions. * fix geometric tool multiarc smooth option * fix level saving failure * fix wrong warning after saving palette * fix a bug where moving a control point while holding alt has unintended result * fix travis-install (#3389) * Fix assert debug crash in flipconsole.cpp Fix crash when using the viewer controls in the console (debug) * Redraw Audio Waveform Fills the waveform rather than outlines it. * Update .gitignore * fix undo data when drawing arc and mutliarc * fix overwriting raster drawing palette (#3387) * mode sensitive fx settings * Create New Style Command Button (#3394) * Create New Style Command Button This PR creates a new button in the pallette editor that creates a new style. Button is large and easy access for a faster and easier workflow. Original code developed by Turtletooth for Tahoma. Given permission to develop within Openoonz. Co-Authored-By: Jeremy Bullock <turtletooth@users.noreply.github.com> * Update paletteviewergui.cpp Made changes to the PR per request by Shun. * Fixed a space within the code that wasn't suppose to be there. Co-authored-by: Jeremy Bullock <turtletooth@users.noreply.github.com> * tahoma license (#3396) * new style button optional * fix loading pegbars (removing updateKeyframes) * periodic random expression * add fx in linear color space this commit is based on source for the ComposeAdd plugin fx by DWANGO Co., Ltd. in dwango_opentoonz_plugins and opentoonz_plugin_utility repositories. * fractal noise iwa fx * skip unnecessary icon invalidation * fix frame range fill with tablet * stop function editor to open by dbl clicking key * Expanding the radius of the rotation handle. This just changes when the cursor transforms into the rotation tool. (cherry picked from commit 7722ae989bbdc6aa5cb48df7a4c08bae1fe6ea39) * fix vector img patern stroke style * Update Stylesheets - Support the new icon sizes - XSheet and Timeline significantly redesigned - Lots of margin fixes and refactoring - Remove deprecated icons, as some icons are moved into binary - New Light theme * New Icons - Redesigns almost every icon as symbolic - Adds icons for most commands * Add Option for Icon Themes - Adds option for icon themes - Removes useless label from Preferences category list * Update Icon Functions - Adds themePath() boolean - Adds function for recoloring black pixels in pixmaps to any color - Rebuilds createQIcon to use fromTheme() and recolorPixmap() - Removes createQIconOnOff as it seemed to be a rarely used duplicate of createQIcon - Removes a grey horizontal line drawn above the console play bar in the viewer * Set Default Icon Theme and Paths - Sets search paths for icons for use with QIcon::fromTheme() - Sets default start icon theme on first install - Sets flag for displaying icons in menus, so we can selectively hide them * Set Icons for Commands - Sets icons for the commands - Hides icons being displayed in menus as most icons are 20x20, they will look blurry when shrunk to 16x16 - Selectively allows icons to display for Tools in menus * Change Icon Sizes, General Fixes and Stylesheet Additions - Change icon sizes to new size - Remove margin around FX Editor window - Remove white line under color sliders in Style Editor - Make keyframe icons uniform and color stylable in the stylesheets - Removes deprecated stylesheet strings - Redesign GUI for palette list view - Make tree list header sort row stylable - Remove black lines from scrollbars in New Project window - Remove margin around combobox in Level Strip - Alter how some lines are drawn in the Timeline to fix some alpha issues - Make conditional fixed onion skin and normal onion skin dots contrast more against a light background area to make sure they have good visibility - Make text always viewable in the FPS field in console bar - Increase size of radio buttons in Cleanup Settings - Increase size of switches in motion path nodes - Remove unessesary "Layer" label in Timeline and other rects - Various colors made stylable in the stylesheets; palette numpad and selection frame, cleanup settings border, scene cast folder path, schematic lines, ruler, xsheet lines, keyframes, cell input box and more - Moves some external stylesheet icons into binary * Make TPanelTitleBar Icon States Stylable - Makes icon states for TPanelTitleBar buttons stylable in stylesheets * Travis Fixes * Swap Startup Popup Logos They were in the wrong folders * Revert "Swap Startup Popup Logos" This reverts commit 815908a9f3e725f48507dab8a2270bdfa045649d. * Fix Startup Popup Logo It wasn't switching * Feedback Changes - Change render visualization to clapboard - Fix text contrast on levels in XSheet * Make Cell Selection More Clear * Darken Light Theme and Tint Empty Cell Selection * Fix missing icons * Fix memo button * Bring back colors * Hide Motion Tab * Fix Play Range Area (Light) Make play range area more visible * Vector Column Color Co-authored-by: pojienie <pojienie@gmail.com> Co-authored-by: rim <11380091+rozhuk-im@users.noreply.github.com> Co-authored-by: shun-iwasawa <shun.iwasawa@ghibli.jp> Co-authored-by: Rodney <rodney.baker@gmail.com> Co-authored-by: DoctorRyan <65507211+DoctorRyan@users.noreply.github.com> Co-authored-by: shun-iwasawa <shun-iwasawa@users.noreply.github.com> Co-authored-by: Kite <konero@users.noreply.github.com> Co-authored-by: Jeremy Bullock <turtletooth@users.noreply.github.com> Co-authored-by: DoctorRyan <doctorryan1969.gmail.com>
2020-09-01 06:51:22 +12:00
setIconSize(QSize(18, 18));
// add margin between items if they are with icons
setView(new QListView());
UI update and Icons from Konero (#126) * add multi arc mockup * implement mutli arc * add join and smooth option * reset multiarc and arc when deactivated * create self loop if the last point is the same as the first * make join option in multiarc consistent with tape tool * fix a bug where thickness don't affect mutliarc in vector level * remove join option in geometric tool * stop mutliarc after closing shape * double click can also end multi arc * fix a bug where multiArc will produce buggy stroke * fix a bug where geometric tools is not deactivated * add multiArc shortcut * rewrite multiArc * revert changes to tvectorimage * add undo data for multiArc * Paste as Copy Command for XSheet * Remove unneeded code * Bug fix * prevent guide lines from jumping around in MultiArc * make stroke color consistent in MultiArc * remove color in MultiArc's undo data * make color consistent in MultiArc with previous version * Fix single image raster levels * fix compilation error * fix a bug where multiArc might generate bugged stroke * Remove ICONV dep (#3304) * fix crash on saving studio palette * Move to Paste Special Menu * Don't Set Fixed Width if Docking a Floating Panel * Update how_to_build_win.md New draft of pr for requested changes to windows build instructions. * fix geometric tool multiarc smooth option * fix level saving failure * fix wrong warning after saving palette * fix a bug where moving a control point while holding alt has unintended result * fix travis-install (#3389) * Fix assert debug crash in flipconsole.cpp Fix crash when using the viewer controls in the console (debug) * Redraw Audio Waveform Fills the waveform rather than outlines it. * Update .gitignore * fix undo data when drawing arc and mutliarc * fix overwriting raster drawing palette (#3387) * mode sensitive fx settings * Create New Style Command Button (#3394) * Create New Style Command Button This PR creates a new button in the pallette editor that creates a new style. Button is large and easy access for a faster and easier workflow. Original code developed by Turtletooth for Tahoma. Given permission to develop within Openoonz. Co-Authored-By: Jeremy Bullock <turtletooth@users.noreply.github.com> * Update paletteviewergui.cpp Made changes to the PR per request by Shun. * Fixed a space within the code that wasn't suppose to be there. Co-authored-by: Jeremy Bullock <turtletooth@users.noreply.github.com> * tahoma license (#3396) * new style button optional * fix loading pegbars (removing updateKeyframes) * periodic random expression * add fx in linear color space this commit is based on source for the ComposeAdd plugin fx by DWANGO Co., Ltd. in dwango_opentoonz_plugins and opentoonz_plugin_utility repositories. * fractal noise iwa fx * skip unnecessary icon invalidation * fix frame range fill with tablet * stop function editor to open by dbl clicking key * Expanding the radius of the rotation handle. This just changes when the cursor transforms into the rotation tool. (cherry picked from commit 7722ae989bbdc6aa5cb48df7a4c08bae1fe6ea39) * fix vector img patern stroke style * Update Stylesheets - Support the new icon sizes - XSheet and Timeline significantly redesigned - Lots of margin fixes and refactoring - Remove deprecated icons, as some icons are moved into binary - New Light theme * New Icons - Redesigns almost every icon as symbolic - Adds icons for most commands * Add Option for Icon Themes - Adds option for icon themes - Removes useless label from Preferences category list * Update Icon Functions - Adds themePath() boolean - Adds function for recoloring black pixels in pixmaps to any color - Rebuilds createQIcon to use fromTheme() and recolorPixmap() - Removes createQIconOnOff as it seemed to be a rarely used duplicate of createQIcon - Removes a grey horizontal line drawn above the console play bar in the viewer * Set Default Icon Theme and Paths - Sets search paths for icons for use with QIcon::fromTheme() - Sets default start icon theme on first install - Sets flag for displaying icons in menus, so we can selectively hide them * Set Icons for Commands - Sets icons for the commands - Hides icons being displayed in menus as most icons are 20x20, they will look blurry when shrunk to 16x16 - Selectively allows icons to display for Tools in menus * Change Icon Sizes, General Fixes and Stylesheet Additions - Change icon sizes to new size - Remove margin around FX Editor window - Remove white line under color sliders in Style Editor - Make keyframe icons uniform and color stylable in the stylesheets - Removes deprecated stylesheet strings - Redesign GUI for palette list view - Make tree list header sort row stylable - Remove black lines from scrollbars in New Project window - Remove margin around combobox in Level Strip - Alter how some lines are drawn in the Timeline to fix some alpha issues - Make conditional fixed onion skin and normal onion skin dots contrast more against a light background area to make sure they have good visibility - Make text always viewable in the FPS field in console bar - Increase size of radio buttons in Cleanup Settings - Increase size of switches in motion path nodes - Remove unessesary "Layer" label in Timeline and other rects - Various colors made stylable in the stylesheets; palette numpad and selection frame, cleanup settings border, scene cast folder path, schematic lines, ruler, xsheet lines, keyframes, cell input box and more - Moves some external stylesheet icons into binary * Make TPanelTitleBar Icon States Stylable - Makes icon states for TPanelTitleBar buttons stylable in stylesheets * Travis Fixes * Swap Startup Popup Logos They were in the wrong folders * Revert "Swap Startup Popup Logos" This reverts commit 815908a9f3e725f48507dab8a2270bdfa045649d. * Fix Startup Popup Logo It wasn't switching * Feedback Changes - Change render visualization to clapboard - Fix text contrast on levels in XSheet * Make Cell Selection More Clear * Darken Light Theme and Tint Empty Cell Selection * Fix missing icons * Fix memo button * Bring back colors * Hide Motion Tab * Fix Play Range Area (Light) Make play range area more visible * Vector Column Color Co-authored-by: pojienie <pojienie@gmail.com> Co-authored-by: rim <11380091+rozhuk-im@users.noreply.github.com> Co-authored-by: shun-iwasawa <shun.iwasawa@ghibli.jp> Co-authored-by: Rodney <rodney.baker@gmail.com> Co-authored-by: DoctorRyan <65507211+DoctorRyan@users.noreply.github.com> Co-authored-by: shun-iwasawa <shun-iwasawa@users.noreply.github.com> Co-authored-by: Kite <konero@users.noreply.github.com> Co-authored-by: Jeremy Bullock <turtletooth@users.noreply.github.com> Co-authored-by: DoctorRyan <doctorryan1969.gmail.com>
2020-09-01 06:51:22 +12:00
view()->setIconSize(QSize(18, 18));
setStyleSheet(
"QComboBox QAbstractItemView::item{ \
margin: 5 0 0 0;\
}");
}
}
2021-04-22 19:44:18 +12:00
int tmpWidth = fontMetrics().width(items[i].UIName);
if (tmpWidth > maxWidth) maxWidth = tmpWidth;
}
// set the maximum width according to the longest item with 25 pixels for
// arrow button and margin
setMaximumWidth(maxWidth + 25 + (hasIcon ? 23 : 0));
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
updateStatus();
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void ToolOptionCombo::updateStatus() {
QString value = QString::fromStdWString(m_property->getValue());
int index = findData(value);
2016-06-15 18:43:10 +12:00
if (index >= 0 && index != currentIndex()) setCurrentIndex(index);
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void ToolOptionCombo::onActivated(int index) {
const TEnumProperty::Range &range = m_property->getRange();
if (index < 0 || index >= (int)range.size()) return;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
std::wstring item = range[index];
m_property->setValue(item);
notifyTool();
2016-03-19 06:57:51 +13:00
}
//=============================================================================
ToolOptionFontCombo::ToolOptionFontCombo(TTool *tool, TEnumProperty *property,
ToolHandle *toolHandle)
: QFontComboBox()
, ToolOptionControl(tool, property->getName(), toolHandle)
, m_property(property) {
setMaximumWidth(250);
m_property->addListener(this);
setSizeAdjustPolicy(QFontComboBox::AdjustToContents);
connect(this, SIGNAL(activated(int)), this, SLOT(onActivated(int)));
// synchronize the state with the same widgets in other tool option bars
if (toolHandle)
connect(this, SIGNAL(activated(int)), toolHandle, SIGNAL(toolChanged()));
updateStatus();
}
//-----------------------------------------------------------------------------
void ToolOptionFontCombo::updateStatus() {
QString value = QString::fromStdWString(m_property->getValue());
int index = findText(value);
if (index >= 0 && index != currentIndex()) setCurrentIndex(index);
}
//-----------------------------------------------------------------------------
void ToolOptionFontCombo::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();
}
//=============================================================================
2016-06-15 18:43:10 +12:00
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);
2016-03-19 06:57:51 +13:00
const TEnumProperty::Items &items = m_property->getItems();
const int count = m_property->getCount();
for (int i = 0; i < count; ++i) {
QAction *action = addItem(createQIcon(items[i].iconName.toUtf8()));
2017-06-26 14:43:02 +12:00
// make the tooltip text
action->setToolTip(items[i].UIName);
2017-06-26 14:43:02 +12:00
}
2016-06-15 18:43:10 +12:00
setCurrentIndex(0);
updateStatus();
connect(this, SIGNAL(activated(int)), this, SLOT(onActivated(int)));
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void ToolOptionPopupButton::updateStatus() {
int index = m_property->getIndex();
if (index >= 0 && index != currentIndex()) setCurrentIndex(index);
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void ToolOptionPopupButton::onActivated(int index) {
const TEnumProperty::Range &range = m_property->getRange();
if (index < 0 || index >= (int)range.size()) return;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
std::wstring item = range[index];
m_property->setValue(item);
notifyTool();
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void ToolOptionPopupButton::doSetCurrentIndex(int index) {
if (isVisible()) setCurrentIndex(index);
2016-03-19 06:57:51 +13:00
}
//=============================================================================
ToolOptionTextField::ToolOptionTextField(TTool *tool, TStringProperty *property)
2016-06-15 18:43:10 +12:00
: LineEdit()
, ToolOptionControl(tool, property->getName())
, m_property(property) {
setFixedSize(100, 23);
m_property->addListener(this);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
updateStatus();
connect(this, SIGNAL(editingFinished()), SLOT(onValueChanged()));
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void ToolOptionTextField::updateStatus() {
QString newText = QString::fromStdWString(m_property->getValue());
if (newText == text()) return;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
setText(newText);
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void ToolOptionTextField::onValueChanged() {
m_property->setValue(text().toStdWString());
notifyTool();
// synchronize the state with the same widgets in other tool option bars
if (m_toolHandle) m_toolHandle->notifyToolChanged();
2016-03-19 06:57:51 +13:00
}
//=============================================================================
2016-06-15 18:43:10 +12:00
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);
m_property->setStyleIndex(-1);
2016-06-15 18:43:10 +12:00
updateStatus();
connect(this, SIGNAL(textChanged(const QString &)),
SLOT(onValueChanged(const QString &)));
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
setPaletteHandle(pltHandle);
connect(pltHandle, SIGNAL(colorStyleSwitched()), SLOT(updateColor()));
2017-11-07 20:24:20 +13:00
connect(pltHandle, SIGNAL(colorStyleChanged(bool)), SLOT(updateColor()));
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void StyleIndexFieldAndChip::updateStatus() {
QString newText = QString::fromStdWString(m_property->getValue());
if (newText == text()) return;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
setText(newText);
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void StyleIndexFieldAndChip::onValueChanged(const QString &changedText) {
QString style;
2016-03-19 06:57:51 +13:00
// Aware of both "current" and translated string
if (!QString("current").contains(changedText) &&
!StyleIndexLineEdit::tr("current").contains(changedText)) {
2018-11-05 18:37:12 +13:00
int index = changedText.toInt();
TPalette *plt = m_pltHandle->getPalette();
if (plt && index > plt->getStyleCount())
style = QString::number(plt->getStyleCount() - 1);
2016-06-15 18:43:10 +12:00
else
style = text();
2018-11-05 18:37:12 +13:00
m_property->setValue(style.toStdWString());
m_property->setStyleIndex(std::min(index, plt->getStyleCount() - 1));
} else {
2018-11-05 18:37:12 +13:00
m_property->setValue(changedText.toStdWString());
m_property->setStyleIndex(-1);
}
2018-11-05 18:37:12 +13:00
2016-06-15 18:43:10 +12:00
repaint();
// synchronize the state with the same widgets in other tool option bars
if (m_toolHandle) m_toolHandle->notifyToolChanged();
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void StyleIndexFieldAndChip::updateColor() { repaint(); }
2016-03-19 06:57:51 +13:00
//=============================================================================
ToolOptionParamRelayField::ToolOptionParamRelayField(
2016-06-15 18:43:10 +12:00
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);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
setDecimals(decimals);
updateStatus();
connect(this, SIGNAL(valueChanged()), SLOT(onValueChanged()));
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void ToolOptionParamRelayField::setGlobalKey(TBoolProperty *globalKey,
TPropertyGroup *globalGroup) {
m_globalKey = globalKey, m_globalGroup = globalGroup;
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void ToolOptionParamRelayField::updateStatus() {
TDoubleParamP param(m_property->getParam());
if (param != m_param) {
// Initialize param referencing
m_param = param.getPointer();
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
if (param) {
m_measure = param->getMeasure();
setMeasure(m_measure ? m_measure->getName() : "");
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
setValue(m_property->getValue());
}
}
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
if (!param) {
setEnabled(false);
m_measure = 0;
setText("");
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
return;
}
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
setEnabled(true);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
TMeasure *measure = param->getMeasure();
if (measure != m_measure) {
// Update measure if needed
m_measure = measure;
setMeasure(measure ? measure->getName() : "");
}
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
double v = m_property->getValue();
if (getValue() == v) return;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
// Update value if needed
setValue(v);
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void ToolOptionParamRelayField::onValueChanged() {
struct locals {
static inline void setKeyframe(TDoubleParamRelayProperty *prop) {
if (!prop) return;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
TDoubleParam *param = prop->getParam().getPointer();
if (!param) return;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
double frame = prop->frame();
if (!param->isKeyframe(frame)) {
KeyframeSetter setter(param, -1, true);
setter.createKeyframe(frame);
}
}
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
//-----------------------------------------------------------------------------
2016-03-19 06:57:51 +13:00
struct SetValueUndo final : public TUndo {
2016-06-15 18:43:10 +12:00
TDoubleParamP m_param; //!< The referenced param
double m_oldVal, m_newVal; //!< Values before and after the set action...
double m_frame; //!< ... at this frame
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
public:
SetValueUndo(const TDoubleParamP &param, double oldVal, double newVal,
double frame)
: m_param(param)
, m_oldVal(oldVal)
, m_newVal(newVal)
, m_frame(frame) {}
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
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); }
};
};
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
//-----------------------------------------------------------------------------
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
// NOTE: Values are extracted upon entry, since setting a keyframe reverts the
// lineEdit
// field value back to the original value (due to feedback from the param
// itself)...
double oldVal = m_property->getValue(), newVal = getValue(),
frame = m_property->frame();
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
TDoubleParamP param = m_property->getParam();
if (!param) return;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
TUndoManager *manager = TUndoManager::manager();
manager->beginBlock();
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
if (m_globalKey && m_globalGroup && m_globalKey->getValue()) {
// Set a keyframe for each of the TDoubleParam relayed in the globalGroup
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 {
// Set a keyframe just for our param
locals::setKeyframe(m_property);
}
// Assign the edited value to the relayed param
m_property->setValue(newVal);
notifyTool();
manager->add(new locals::SetValueUndo(param, oldVal, newVal, frame));
manager->endBlock();
2016-03-19 06:57:51 +13:00
}
//=============================================================================
//
// Widget specifici di ArrowTool (derivati da ToolOptionControl)
//
// SPOSTA in un file a parte!
using namespace DVGui;
MeasuredValueField::MeasuredValueField(QWidget *parent, QString name)
2016-06-15 18:43:10 +12:00
: LineEdit(name, parent)
, m_isGlobalKeyframe(false)
, m_modified(false)
, m_errorHighlighting(false)
, m_precision(2) {
setObjectName("MeasuredValueField");
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
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()));
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
MeasuredValueField::~MeasuredValueField() { delete m_value; }
2016-03-19 06:57:51 +13:00
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void MeasuredValueField::setMeasure(std::string name) {
// for reproducing the precision
int oldPrec = -1;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
delete m_value;
m_value = new TMeasuredValue(name != "" ? name : "dummy");
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
setText(QString::fromStdWString(m_value->toWideString(m_precision)));
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void MeasuredValueField::commit() {
if (!m_modified && !isReturnPressed()) return;
// commit is called when the field comes out of focus.
// mouse drag will call this - return if coming from mouse drag.
// else undo is set twice
if (m_mouseEdit) {
m_mouseEdit = false;
return;
}
2016-06-15 18:43:10 +12:00
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("");
}
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
if (!isSet && !isReturnPressed()) return;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
setText(QString::fromStdWString(m_value->toWideString(m_precision)));
m_modified = false;
emit measuredValueChanged(m_value);
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void MeasuredValueField::onTextChanged(const QString &) { m_modified = true; }
2016-03-19 06:57:51 +13:00
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void MeasuredValueField::setValue(double v) {
if (getValue() == v) return;
m_value->setValue(TMeasuredValue::MainUnit, v);
setText(QString::fromStdWString(m_value->toWideString(m_precision)));
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
double MeasuredValueField::getValue() const {
return m_value->getValue(TMeasuredValue::MainUnit);
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
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')));
}
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void MeasuredValueField::setPrecision(int precision) {
m_precision = precision;
setText(QString::fromStdWString(m_value->toWideString(m_precision)));
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
void MeasuredValueField::mousePressEvent(QMouseEvent *e) {
if (!isEnabled()) return;
if ((e->buttons() == Qt::MiddleButton) || m_labelClicked) {
m_xMouse = e->x();
m_mouseEdit = true;
m_originalValue = m_value->getValue(TMeasuredValue::CurrentUnit);
2017-11-25 01:13:52 +13:00
} else {
QLineEdit::mousePressEvent(e);
2017-11-25 01:13:52 +13:00
if (!m_isTyping) { // only the first click will select all
selectAll();
m_isTyping = true;
}
}
}
//-----------------------------------------------------------------------------
void MeasuredValueField::mouseMoveEvent(QMouseEvent *e) {
if (!isEnabled()) return;
if ((e->buttons() == Qt::MiddleButton) || m_labelClicked) {
m_value->modifyValue((e->x() - m_xMouse) / 2);
setText(QString::fromStdWString(m_value->toWideString(m_precision)));
m_xMouse = e->x();
// measuredValueChanged to update the UI, but don't add to undo
emit measuredValueChanged(m_value, false);
} else
QLineEdit::mouseMoveEvent(e);
}
//-----------------------------------------------------------------------------
void MeasuredValueField::mouseReleaseEvent(QMouseEvent *e) {
if (!isEnabled()) return;
// m_mouseEdit will be set false in commit
if (m_mouseEdit) {
// This seems redundant, but this is necessary for undo to work
double valueToRestore = m_value->getValue(TMeasuredValue::CurrentUnit);
m_value->setValue(TMeasuredValue::CurrentUnit, m_originalValue);
setText(QString::fromStdWString(m_value->toWideString(m_precision)));
emit measuredValueChanged(m_value, false);
// add this to undo
m_value->setValue(TMeasuredValue::CurrentUnit, valueToRestore);
setText(QString::fromStdWString(m_value->toWideString(m_precision)));
emit measuredValueChanged(m_value, true);
clearFocus();
2017-11-25 01:13:52 +13:00
} else
QLineEdit::mouseReleaseEvent(e);
}
2017-11-25 01:13:52 +13:00
//-----------------------------------------------------------------------------
void MeasuredValueField::focusOutEvent(QFocusEvent *e) {
DVGui::LineEdit::focusOutEvent(e);
m_isTyping = false;
}
//-----------------------------------------------------------------------------
void MeasuredValueField::receiveMousePress(QMouseEvent *e) {
m_labelClicked = true;
mousePressEvent(e);
}
void MeasuredValueField::receiveMouseMove(QMouseEvent *e) { mouseMoveEvent(e); }
void MeasuredValueField::receiveMouseRelease(QMouseEvent *e) {
mouseReleaseEvent(e);
m_labelClicked = false;
}
2016-03-19 06:57:51 +13:00
//=============================================================================
namespace {
// calculate maximum field size (once) with 10 pixels margin
int getMaximumWidthForEditToolField(QWidget *widget) {
static int fieldMaxWidth = widget->fontMetrics().width("-0000.00 field") + 10;
return fieldMaxWidth;
}
} // namespace
2016-06-15 18:43:10 +12:00
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 *, bool)),
SLOT(onChange(TMeasuredValue *, bool)));
2016-06-15 18:43:10 +12:00
assert(ret);
// NOTA: per le unita' di misura controlla anche tpegbar.cpp
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;
}
setMaximumWidth(getMaximumWidthForEditToolField(this));
2016-06-15 18:43:10 +12:00
updateStatus();
}
//-----------------------------------------------------------------------------
void PegbarChannelField::onChange(TMeasuredValue *fld, bool addToUndo) {
2016-06-15 18:43:10 +12:00
if (!m_tool->isEnabled()) return;
// the camera will crash with a value of 0
if (m_tool->getObjectId().isCamera()) {
if (fld->getMeasure()->getName() == "scale" &&
fld->getValue(TMeasuredValue::MainUnit) == 0) {
fld->setValue(TMeasuredValue::MainUnit, 0.0001);
}
}
2016-06-15 18:43:10 +12:00
bool modifyConnectedActionId = false;
if (addToUndo) TUndoManager::manager()->beginBlock();
// m_firstMouseDrag is set to true only if addToUndo is false
// and only for the first drag
// This should always fire if addToUndo is true
if (!m_firstMouseDrag) {
2017-12-05 19:45:51 +13:00
m_before = TStageObjectValues();
m_before.setFrameHandle(m_frameHandle);
m_before.setObjectHandle(m_objHandle);
m_before.setXsheetHandle(m_xshHandle);
m_before.add(m_actionId);
if (m_scaleType != eNone) {
modifyConnectedActionId = true;
if (m_actionId == TStageObject::T_ScaleX)
m_before.add(TStageObject::T_ScaleY);
else if (m_actionId == TStageObject::T_ScaleY)
m_before.add(TStageObject::T_ScaleX);
else
modifyConnectedActionId = false;
}
if (m_isGlobalKeyframe) {
m_before.add(TStageObject::T_Angle);
m_before.add(TStageObject::T_X);
m_before.add(TStageObject::T_Y);
m_before.add(TStageObject::T_Z);
m_before.add(TStageObject::T_SO);
m_before.add(TStageObject::T_ScaleX);
m_before.add(TStageObject::T_ScaleY);
m_before.add(TStageObject::T_Scale);
m_before.add(TStageObject::T_Path);
m_before.add(TStageObject::T_ShearX);
m_before.add(TStageObject::T_ShearY);
}
m_before.updateValues();
2016-06-15 18:43:10 +12:00
}
TStageObjectValues after;
after = m_before;
2016-06-15 18:43:10 +12:00
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);
if (addToUndo) {
UndoStageObjectMove *undo = new UndoStageObjectMove(m_before, after);
undo->setObjectHandle(m_objHandle);
TUndoManager::manager()->add(undo);
TUndoManager::manager()->endBlock();
m_firstMouseDrag = false;
}
if (!addToUndo && !m_firstMouseDrag) m_firstMouseDrag = true;
2016-06-15 18:43:10 +12:00
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;
2016-03-19 06:57:51 +13:00
}
//=============================================================================
2016-06-15 18:43:10 +12:00
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 *, bool)),
SLOT(onChange(TMeasuredValue *, bool)));
2016-06-15 18:43:10 +12:00
updateStatus();
setMaximumWidth(getMaximumWidthForEditToolField(this));
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
void PegbarCenterField::onChange(TMeasuredValue *fld, bool addToUndo) {
2016-06-15 18:43:10 +12:00
if (!m_tool->isEnabled()) return;
TXsheet *xsh = m_tool->getXsheet();
int frame = m_tool->getFrame();
TStageObjectId objId = m_tool->getObjectId();
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
TStageObject *obj = xsh->getStageObject(objId);
2016-03-19 06:57:51 +13:00
2021-04-22 19:44:18 +12:00
double v = fld->getValue(TMeasuredValue::MainUnit);
TPointD center = obj->getCenter(frame);
if (!m_firstMouseDrag) m_oldCenter = center;
2016-06-15 18:43:10 +12:00
if (m_index == 0)
center.x = v;
else
center.y = v;
obj->setCenter(frame, center);
m_tool->invalidate();
2016-03-19 06:57:51 +13:00
if (addToUndo) {
UndoStageObjectCenterMove *undo =
new UndoStageObjectCenterMove(objId, frame, m_oldCenter, center);
undo->setObjectHandle(m_objHandle);
undo->setXsheetHandle(m_xshHandle);
TUndoManager::manager()->add(undo);
m_firstMouseDrag = false;
}
if (!addToUndo && !m_firstMouseDrag) m_firstMouseDrag = true;
2016-06-15 18:43:10 +12:00
m_objHandle->notifyObjectIdChanged(false);
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
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);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
double v = m_index == 0 ? center.x : center.y;
if (getValue() == v) return;
setValue(v);
2016-03-19 06:57:51 +13:00
}
//=============================================================================
NoScaleField::NoScaleField(TTool *tool, QString name)
2016-06-15 18:43:10 +12:00
: MeasuredValueField(0, name), ToolOptionControl(tool, "") {
TStageObjectId objId = m_tool->getObjectId();
setMeasure("zdepth");
connect(this, SIGNAL(measuredValueChanged(TMeasuredValue *, bool)),
SLOT(onChange(TMeasuredValue *, bool)));
2016-06-15 18:43:10 +12:00
updateStatus();
setMaximumWidth(getMaximumWidthForEditToolField(this));
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
void NoScaleField::onChange(TMeasuredValue *fld, bool addToUndo) {
// addToUndo isn't needed here as the field denominator
// doesn't have an undo
2016-06-15 18:43:10 +12:00
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);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
if (m_isGlobalKeyframe)
xsh->getStageObject(objId)->setKeyframeWithoutUndo(frame);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
double v = fld->getValue(TMeasuredValue::MainUnit);
obj->setNoScaleZ(v);
m_tool->invalidate();
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void NoScaleField::updateStatus() {
TXsheet *xsh = m_tool->getXsheet();
int frame = m_tool->getFrame();
TStageObjectId objId = m_tool->getObjectId();
TStageObject *obj = xsh->getStageObject(objId);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
double v = obj->getNoScaleZ();
if (getValue() == v) return;
setValue(v);
2016-03-19 06:57:51 +13:00
}
//=============================================================================
PropertyMenuButton::PropertyMenuButton(QWidget *parent, TTool *tool,
2016-06-15 18:43:10 +12:00
QList<TBoolProperty *> properties,
QIcon icon, QString tooltip)
: QToolButton(parent)
, ToolOptionControl(tool, "")
, m_properties(properties) {
setPopupMode(QToolButton::InstantPopup);
setIcon(icon);
setToolTip(tooltip);
2021-04-22 19:44:18 +12:00
QMenu *menu = new QMenu(tooltip, this);
2016-06-15 18:43:10 +12:00
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();
// Se il tooltip essagnato e' contenuto nel nome della proprieta' lo levo
// dalla stringa dell'azione
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()));
2016-03-19 06:57:51 +13:00
}
//=============================================================================
namespace {
// calculate maximum field size (once) with 10 pixels margin
int getMaximumWidthForSelectionToolField(QWidget *widget) {
static int fieldMaxWidth = widget->fontMetrics().width("-000.00 %") + 10;
return fieldMaxWidth;
}
} // namespace
2016-06-15 18:43:10 +12:00
// id == 0 Scale X
// id == 0 Scale Y
SelectionScaleField::SelectionScaleField(SelectionTool *tool, int id,
QString name)
: MeasuredValueField(0, name), m_tool(tool), m_id(id) {
bool ret = connect(this, SIGNAL(measuredValueChanged(TMeasuredValue *, bool)),
SLOT(onChange(TMeasuredValue *, bool)));
2016-06-15 18:43:10 +12:00
assert(ret);
setMeasure("scale");
updateStatus();
setMaximumWidth(getMaximumWidthForSelectionToolField(this));
2016-06-15 18:43:10 +12:00
}
//-----------------------------------------------------------------------------
bool SelectionScaleField::applyChange(bool addToUndo) {
2016-06-15 18:43:10 +12:00
if (!m_tool || (m_tool->isSelectionEmpty() && !m_tool->isLevelType()))
return false;
using namespace DragSelectionTool;
DragTool *scaleTool = createNewScaleTool(m_tool, ScaleType::GLOBAL);
2020-05-12 18:27:39 +12:00
double p = getValue();
2021-04-22 19:44:18 +12:00
if (p == 0) p = 0.00001;
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);
2016-06-15 18:43:10 +12:00
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; // Instruction order is relevant
scaleTool->transform(pointIndex,
newPos); // This line invokes GUI update using the
// value set above
if (!m_tool->isLevelType() && addToUndo) scaleTool->addTransformUndo();
2016-06-15 18:43:10 +12:00
setCursorPosition(0);
return true;
}
//-----------------------------------------------------------------------------
void SelectionScaleField::onChange(TMeasuredValue *fld, bool addToUndo) {
2016-06-15 18:43:10 +12:00
if (!m_tool->isEnabled()) return;
if (!applyChange(addToUndo)) return;
emit valueChange(addToUndo);
2016-06-15 18:43:10 +12:00
}
//-----------------------------------------------------------------------------
void SelectionScaleField::updateStatus() {
if (!m_tool || !m_tool->isSelectionEditable() ||
(m_tool->isSelectionEmpty() && !m_tool->isLevelType())) {
2016-06-15 18:43:10 +12:00
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);
2016-03-19 06:57:51 +13:00
}
//=============================================================================
2016-06-15 18:43:10 +12:00
SelectionRotationField::SelectionRotationField(SelectionTool *tool,
QString name)
: MeasuredValueField(0, name), m_tool(tool) {
bool ret = connect(this, SIGNAL(measuredValueChanged(TMeasuredValue *, bool)),
SLOT(onChange(TMeasuredValue *, bool)));
2016-06-15 18:43:10 +12:00
assert(ret);
setMeasure("angle");
updateStatus();
setMaximumWidth(getMaximumWidthForSelectionToolField(this));
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
void SelectionRotationField::onChange(TMeasuredValue *fld, bool addToUndo) {
2016-06-15 18:43:10 +12:00
if (!m_tool || !m_tool->isEnabled() ||
(m_tool->isSelectionEmpty() && !m_tool->isLevelType()))
return;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
DragSelectionTool::DragTool *rotationTool = createNewRotationTool(m_tool);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
DragSelectionTool::DeformValues &deformValues = m_tool->m_deformValues;
double p = getValue();
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
TAffine aff =
TRotation(m_tool->getCenter(), p - deformValues.m_rotationAngle);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
deformValues.m_rotationAngle = p; // Instruction order is relevant here
rotationTool->transform(aff, p - deformValues.m_rotationAngle); //
2016-03-19 06:57:51 +13:00
if (!m_tool->isLevelType() && addToUndo) rotationTool->addTransformUndo();
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
setCursorPosition(0);
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void SelectionRotationField::updateStatus() {
if (!m_tool || !m_tool->isSelectionEditable() ||
(m_tool->isSelectionEmpty() && !m_tool->isLevelType())) {
2016-06-15 18:43:10 +12:00
setValue(0);
setDisabled(true);
return;
}
setDisabled(false);
setValue(m_tool->m_deformValues.m_rotationAngle);
setCursorPosition(0);
2016-03-19 06:57:51 +13:00
}
//=============================================================================
2016-06-15 18:43:10 +12:00
// id == 0 Move X
// id == 0 Move Y
SelectionMoveField::SelectionMoveField(SelectionTool *tool, int id,
QString name)
: MeasuredValueField(0, name), m_tool(tool), m_id(id) {
bool ret = connect(this, SIGNAL(measuredValueChanged(TMeasuredValue *, bool)),
SLOT(onChange(TMeasuredValue *, bool)));
2016-06-15 18:43:10 +12:00
assert(ret);
if (m_id == 0)
setMeasure("length.x");
else
setMeasure("length.y");
updateStatus();
// for translation value field, use size for the Edit Tool as it needs more
// estate
setMaximumWidth(getMaximumWidthForEditToolField(this));
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
void SelectionMoveField::onChange(TMeasuredValue *fld, bool addToUndo) {
2016-06-15 18:43:10 +12:00
if (!m_tool || !m_tool->isEnabled() ||
(m_tool->isSelectionEmpty() && !m_tool->isLevelType()))
return;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
DragSelectionTool::DragTool *moveTool = createNewMoveSelectionTool(m_tool);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
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);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
TAffine aff = TTranslation(-oldDelta) * TTranslation(delta);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
m_tool->m_deformValues.m_moveValue =
1 / Stage::inch * newMove; // Instruction order relevant here
moveTool->transform(aff); //
2016-03-19 06:57:51 +13:00
if (!m_tool->isLevelType() && addToUndo) moveTool->addTransformUndo();
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
setCursorPosition(0);
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void SelectionMoveField::updateStatus() {
if (!m_tool || !m_tool->isSelectionEditable() ||
(m_tool->isSelectionEmpty() && !m_tool->isLevelType())) {
2016-06-15 18:43:10 +12:00
setValue(0);
setDisabled(true);
return;
}
setDisabled(false);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
if (m_id == 0)
setValue(m_tool->m_deformValues.m_moveValue.x);
else
setValue(m_tool->m_deformValues.m_moveValue.y);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
setCursorPosition(0);
2016-03-19 06:57:51 +13:00
}
//=============================================================================
ThickChangeField::ThickChangeField(SelectionTool *tool, QString name)
2016-06-15 18:43:10 +12:00
: MeasuredValueField(0, name), m_tool(tool) {
bool ret = connect(this, SIGNAL(measuredValueChanged(TMeasuredValue *, bool)),
SLOT(onChange(TMeasuredValue *, bool)));
2016-06-15 18:43:10 +12:00
assert(ret);
setMeasure("");
updateStatus();
setMaximumWidth(getMaximumWidthForSelectionToolField(this));
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
void ThickChangeField::onChange(TMeasuredValue *fld, bool addToUndo) {
2016-06-15 18:43:10 +12:00
if (!m_tool || (m_tool->isSelectionEmpty() && !m_tool->isLevelType())) return;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
DragSelectionTool::VectorChangeThicknessTool *changeThickTool =
new DragSelectionTool::VectorChangeThicknessTool(
(VectorSelectionTool *)m_tool);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
TVectorImageP vi = (TVectorImageP)m_tool->getImage(true);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
double p = 0.5 * getValue();
double newThickness = p - m_tool->m_deformValues.m_maxSelectionThickness;
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
changeThickTool->setThicknessChange(newThickness);
changeThickTool->changeImageThickness(*vi, newThickness);
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
// DragSelectionTool::DeformValues deformValues = m_tool->m_deformValues;
// // Like when I found it - it's a noop.
// deformValues.m_maxSelectionThickness = p;
// // Seems that the actual update is performed inside
// the above change..() instruction... >_<
if (addToUndo) {
changeThickTool->addUndo();
}
2016-06-15 18:43:10 +12:00
m_tool->computeBBox();
m_tool->invalidate();
m_tool->notifyImageChanged(m_tool->getCurrentFid());
2016-03-19 06:57:51 +13:00
}
//-----------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void ThickChangeField::updateStatus() {
if (!m_tool || !m_tool->isSelectionEditable() ||
m_tool->m_deformValues.m_isSelectionModified ||
2016-06-15 18:43:10 +12:00
(m_tool->isSelectionEmpty() && !m_tool->isLevelType())) {
setValue(0);
setDisabled(true);
return;
}
2016-03-19 06:57:51 +13:00
2016-06-15 18:43:10 +12:00
setDisabled(false);
setValue(2 * m_tool->m_deformValues.m_maxSelectionThickness);
setCursorPosition(0);
2016-03-19 06:57:51 +13:00
}
//=============================================================================
ClickableLabel::ClickableLabel(const QString &text, QWidget *parent,
Qt::WindowFlags f)
: QLabel(text, parent, f) {}
//-----------------------------------------------------------------------------
ClickableLabel::~ClickableLabel() {}
//-----------------------------------------------------------------------------
void ClickableLabel::mousePressEvent(QMouseEvent *event) {
emit onMousePress(event);
}
//-----------------------------------------------------------------------------
void ClickableLabel::mouseMoveEvent(QMouseEvent *event) {
emit onMouseMove(event);
}
//-----------------------------------------------------------------------------
void ClickableLabel::mouseReleaseEvent(QMouseEvent *event) {
emit onMouseRelease(event);
}