Merge pull request #567 from manongjohn/ot_patches_20210126
OpenToonz changes thru 2/11/2021
This commit is contained in:
commit
5a5bfa8679
|
@ -3,13 +3,3 @@ brew update
|
|||
# Remove symlink to bin/2to3 in order for latest python to install
|
||||
rm -f '/usr/local/bin/2to3'
|
||||
brew install boost qt clang-format glew lz4 lzo libmypaint jpeg-turbo nasm yasm aom dav1d fontconfig freetype gnutls lame libass libbluray libsoxr libvorbis libvpx opencore-amr openh264 openjpeg opus rav1e sdl2 snappy speex tesseract theora webp xvid xz
|
||||
# delete older qt versions and make sure to have only the latest
|
||||
brew cleanup qt
|
||||
# temp workaround to brew installed glew cmake info overriding glew lib detection
|
||||
# which causes compiling issues later
|
||||
if [ -L /usr/local/lib/cmake/glew ]
|
||||
then
|
||||
echo "Symbolic link '/usr/local/lib/cmake/glew' detected. Removing to avoid glew lib detection issue!"
|
||||
ls -l /usr/local/lib/cmake/glew
|
||||
rm /usr/local/lib/cmake/glew
|
||||
fi
|
||||
|
|
|
@ -6,13 +6,3 @@ brew install clang-format
|
|||
# from Homebrew 1.6.0 the old formula for obtaining Qt5.9.2 becomes invalid.
|
||||
# so we start to use the latest version of Qt. (#1910)
|
||||
brew install qt
|
||||
# delete older qt versions and make sure to have only the latest
|
||||
brew cleanup qt
|
||||
# temp workaround to brew installed glew cmake info overriding glew lib detection
|
||||
# which causes compiling issues later
|
||||
if [ -L /usr/local/lib/cmake/glew ]
|
||||
then
|
||||
echo "Symbolic link '/usr/local/lib/cmake/glew' detected. Removing to avoid glew lib detection issue!"
|
||||
ls -l /usr/local/lib/cmake/glew
|
||||
rm /usr/local/lib/cmake/glew
|
||||
fi
|
||||
|
|
|
@ -1316,9 +1316,16 @@
|
|||
|
||||
<item>"STD_iwa_GlareFx" "Glare Iwa" </item>
|
||||
<item>"STD_iwa_GlareFx.renderMode" "Render Mode" </item>
|
||||
<item>"STD_iwa_GlareFx.irisMode" "Iris Shape" </item>
|
||||
<item>"STD_iwa_GlareFx.irisScale" "Iris Scale" </item>
|
||||
<item>"STD_iwa_GlareFx.irisGearEdgeCount" "Edges" </item>
|
||||
<item>"STD_iwa_GlareFx.irisRandomSeed" "Random Seed" </item>
|
||||
<item>"STD_iwa_GlareFx.irisSymmetry" "Symmetry" </item>
|
||||
<item>"STD_iwa_GlareFx.irisAppearance" "Appearance" </item>
|
||||
<item>"STD_iwa_GlareFx.intensity" "Intensity" </item>
|
||||
<item>"STD_iwa_GlareFx.size" "Filter Size" </item>
|
||||
<item>"STD_iwa_GlareFx.rotation" "Filter Rotation" </item>
|
||||
<item>"STD_iwa_GlareFx.aberration" "Chromatic Aberration" </item>
|
||||
<item>"STD_iwa_GlareFx.noise_factor" "Noise Factor" </item>
|
||||
<item>"STD_iwa_GlareFx.noise_size" "Noise Size" </item>
|
||||
<item>"STD_iwa_GlareFx.noise_octave" "Noise Octave" </item>
|
||||
|
|
|
@ -1496,9 +1496,6 @@ QStatusBar #StatusBarLabel {
|
|||
/* -----------------------------------------------------------------------------
|
||||
Style Editor
|
||||
----------------------------------------------------------------------------- */
|
||||
#StyleEditor #TabBarContainer {
|
||||
margin-left: -5px;
|
||||
}
|
||||
#StyleEditor #bottomWidget {
|
||||
border-top: 1 solid #111111;
|
||||
padding: 3 2 8 3;
|
||||
|
@ -2365,9 +2362,13 @@ SpreadsheetViewer {
|
|||
qproperty-KeyFrameColor: #995d1d;
|
||||
qproperty-KeyFrameBorderColor: #db9041;
|
||||
qproperty-SelectedKeyFrameColor: #a2835b;
|
||||
qproperty-IgnoredKeyFrameColor: #ac2a39;
|
||||
qproperty-SelectedIgnoredKeyFrameColor: #b25872;
|
||||
qproperty-InBetweenColor: #666250;
|
||||
qproperty-InBetweenBorderColor: #b0aa91;
|
||||
qproperty-SelectedInBetweenColor: #717970;
|
||||
qproperty-IgnoredInBetweenColor: #8a695e;
|
||||
qproperty-SelectedIgnoredInBetweenColor: #93807d;
|
||||
qproperty-SelectedEmptyColor: rgba(90, 100, 106, 0.5);
|
||||
qproperty-SelectedSceneRangeEmptyColor: rgba(90, 100, 106, 0.5);
|
||||
qproperty-TextColor: #e6e6e6;
|
||||
|
|
|
@ -1496,9 +1496,6 @@ QStatusBar #StatusBarLabel {
|
|||
/* -----------------------------------------------------------------------------
|
||||
Style Editor
|
||||
----------------------------------------------------------------------------- */
|
||||
#StyleEditor #TabBarContainer {
|
||||
margin-left: -5px;
|
||||
}
|
||||
#StyleEditor #bottomWidget {
|
||||
border-top: 1 solid #060606;
|
||||
padding: 3 2 8 3;
|
||||
|
@ -2365,9 +2362,13 @@ SpreadsheetViewer {
|
|||
qproperty-KeyFrameColor: #995d1d;
|
||||
qproperty-KeyFrameBorderColor: #db9041;
|
||||
qproperty-SelectedKeyFrameColor: #a2835b;
|
||||
qproperty-IgnoredKeyFrameColor: #ac2a39;
|
||||
qproperty-SelectedIgnoredKeyFrameColor: #b25872;
|
||||
qproperty-InBetweenColor: #666250;
|
||||
qproperty-InBetweenBorderColor: #b0aa91;
|
||||
qproperty-SelectedInBetweenColor: #717970;
|
||||
qproperty-IgnoredInBetweenColor: #8a695e;
|
||||
qproperty-SelectedIgnoredInBetweenColor: #93807d;
|
||||
qproperty-SelectedEmptyColor: rgba(83, 93, 100, 0.5);
|
||||
qproperty-SelectedSceneRangeEmptyColor: rgba(83, 93, 100, 0.5);
|
||||
qproperty-TextColor: #e6e6e6;
|
||||
|
|
|
@ -1496,9 +1496,6 @@ QStatusBar #StatusBarLabel {
|
|||
/* -----------------------------------------------------------------------------
|
||||
Style Editor
|
||||
----------------------------------------------------------------------------- */
|
||||
#StyleEditor #TabBarContainer {
|
||||
margin-left: -5px;
|
||||
}
|
||||
#StyleEditor #bottomWidget {
|
||||
border-top: 1 solid #a8a8a8;
|
||||
padding: 3 2 8 3;
|
||||
|
@ -2365,9 +2362,13 @@ SpreadsheetViewer {
|
|||
qproperty-KeyFrameColor: #edaa64;
|
||||
qproperty-KeyFrameBorderColor: #bb6a16;
|
||||
qproperty-SelectedKeyFrameColor: #c9a278;
|
||||
qproperty-IgnoredKeyFrameColor: #cb5765;
|
||||
qproperty-SelectedIgnoredKeyFrameColor: #eb96ad;
|
||||
qproperty-InBetweenColor: #e2dbcc;
|
||||
qproperty-InBetweenBorderColor: #ac9f82;
|
||||
qproperty-SelectedInBetweenColor: #c2c4c0;
|
||||
qproperty-IgnoredInBetweenColor: #c29c92;
|
||||
qproperty-SelectedIgnoredInBetweenColor: #ab9898;
|
||||
qproperty-SelectedEmptyColor: rgba(146, 153, 158, 0.5);
|
||||
qproperty-SelectedSceneRangeEmptyColor: rgba(146, 153, 158, 0.5);
|
||||
qproperty-TextColor: #000;
|
||||
|
|
|
@ -1496,9 +1496,6 @@ QStatusBar #StatusBarLabel {
|
|||
/* -----------------------------------------------------------------------------
|
||||
Style Editor
|
||||
----------------------------------------------------------------------------- */
|
||||
#StyleEditor #TabBarContainer {
|
||||
margin-left: -5px;
|
||||
}
|
||||
#StyleEditor #bottomWidget {
|
||||
border-top: 1 solid #2c2c2c;
|
||||
padding: 3 2 8 3;
|
||||
|
@ -2365,9 +2362,13 @@ SpreadsheetViewer {
|
|||
qproperty-KeyFrameColor: #995d1d;
|
||||
qproperty-KeyFrameBorderColor: #db9041;
|
||||
qproperty-SelectedKeyFrameColor: #a2835b;
|
||||
qproperty-IgnoredKeyFrameColor: #ac2a39;
|
||||
qproperty-SelectedIgnoredKeyFrameColor: #b25872;
|
||||
qproperty-InBetweenColor: #666250;
|
||||
qproperty-InBetweenBorderColor: #b0aa91;
|
||||
qproperty-SelectedInBetweenColor: #717970;
|
||||
qproperty-IgnoredInBetweenColor: #8a695e;
|
||||
qproperty-SelectedIgnoredInBetweenColor: #93807d;
|
||||
qproperty-SelectedEmptyColor: rgba(103, 113, 119, 0.5);
|
||||
qproperty-SelectedSceneRangeEmptyColor: rgba(103, 113, 119, 0.5);
|
||||
qproperty-TextColor: #e6e6e6;
|
||||
|
|
|
@ -556,9 +556,13 @@
|
|||
@function-KeyFrame-color: darken(desaturate(spin(@keyframe-total-color, 0.0000), 0.7570), 8.4314);
|
||||
@function-KeyFrameBorder-color: lighten(@function-KeyFrame-color, 20);
|
||||
@function-SelectedKeyFrame-color: mix(shade(@function-KeyFrame-color, -40), @cellHighlightTintColor, 60);
|
||||
@function-IgnoredKeyFrame-color: rgb(172,42,57);
|
||||
@function-SelectedIgnoredKeyFrame-color: mix(shade(@function-IgnoredKeyFrame-color, -40), @cellHighlightTintColor, 60);
|
||||
@function-Inbetween-color: darken(desaturate(spin(@keyframe-inbetween-color, 0.4423), 4.8071), 7.2549);
|
||||
@function-InbetweenBorder-color: lighten(@keyframe-inbetween-color, 20);
|
||||
@function-SelectedInbetween-color: mix(shade(@function-Inbetween-color, @cellHighlightLightness), @cellHighlightTintColor, @cellHighlightTintAmount);
|
||||
@function-IgnoredInbetween-color: rgb(138,105,94);
|
||||
@function-SelectedIgnoredInbetween-color: mix(shade(@function-IgnoredInbetween-color, @cellHighlightLightness), @cellHighlightTintColor, @cellHighlightTintAmount);
|
||||
|
||||
// Expression Field
|
||||
@function-ExpressionFieldBG-color: lighten(@bg, 61.9608);
|
||||
|
|
|
@ -3,9 +3,6 @@
|
|||
----------------------------------------------------------------------------- */
|
||||
|
||||
#StyleEditor {
|
||||
& #TabBarContainer {
|
||||
margin-left: -5px;
|
||||
}
|
||||
& #bottomWidget {
|
||||
border-top: 1 solid @accent;
|
||||
padding: 3 2 8 3;
|
||||
|
|
|
@ -280,9 +280,13 @@ SpreadsheetViewer {
|
|||
qproperty-KeyFrameColor: @function-KeyFrame-color;
|
||||
qproperty-KeyFrameBorderColor: @function-KeyFrameBorder-color;
|
||||
qproperty-SelectedKeyFrameColor: @function-SelectedKeyFrame-color;
|
||||
qproperty-IgnoredKeyFrameColor: @function-IgnoredKeyFrame-color;
|
||||
qproperty-SelectedIgnoredKeyFrameColor: @function-SelectedIgnoredKeyFrame-color;
|
||||
qproperty-InBetweenColor: @function-Inbetween-color;
|
||||
qproperty-InBetweenBorderColor: @function-InbetweenBorder-color;
|
||||
qproperty-SelectedInBetweenColor: @function-SelectedInbetween-color;
|
||||
qproperty-IgnoredInBetweenColor: @function-IgnoredInbetween-color;
|
||||
qproperty-SelectedIgnoredInBetweenColor: @function-SelectedIgnoredInbetween-color;
|
||||
qproperty-SelectedEmptyColor: @xsheet-SelectedEmptyCell-color; // paired
|
||||
qproperty-SelectedSceneRangeEmptyColor: @function-SelectedSceneRangeEmpty-color;
|
||||
qproperty-TextColor: @xsheet-text-color; // paired
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
// -----------------------------------------------------------------------------
|
||||
// This inherits from NEUTRAL theme, when updating NEUTRAL make sure to check
|
||||
// changes against LIGHT.
|
||||
//
|
||||
// NOTE: Compile Neutral.less before this.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Override
|
||||
|
@ -234,7 +236,10 @@
|
|||
@function-panel-bg-color: @schematic-viewer-bg-color;
|
||||
@function-panel-OtherCurves-color: rgb(218, 218, 218);
|
||||
@function-panel-Text-color: @text-color;
|
||||
|
||||
@function-panel-Sub-color: #fff;
|
||||
@function-panel-Selected-color: #ffe033;
|
||||
@function-IgnoredKeyFrame-color: rgb(203,87,101);
|
||||
@function-IgnoredInbetween-color: rgb(194,156,146);
|
||||
|
||||
@function-SelectedKeyFrame-color: mix(shade(@function-KeyFrame-color, @cellHighlightLightness), @cellHighlightTintColor, @cellHighlightTintAmount);
|
||||
|
|
|
@ -1496,9 +1496,6 @@ QStatusBar #StatusBarLabel {
|
|||
/* -----------------------------------------------------------------------------
|
||||
Style Editor
|
||||
----------------------------------------------------------------------------- */
|
||||
#StyleEditor #TabBarContainer {
|
||||
margin-left: -5px;
|
||||
}
|
||||
#StyleEditor #bottomWidget {
|
||||
border-top: 1 solid #5a5a5a;
|
||||
padding: 3 2 8 3;
|
||||
|
@ -2365,9 +2362,13 @@ SpreadsheetViewer {
|
|||
qproperty-KeyFrameColor: #c4833e;
|
||||
qproperty-KeyFrameBorderColor: #64421f;
|
||||
qproperty-SelectedKeyFrameColor: #deae7b;
|
||||
qproperty-IgnoredKeyFrameColor: #ac2a39;
|
||||
qproperty-SelectedIgnoredKeyFrameColor: #b25872;
|
||||
qproperty-InBetweenColor: #b4b09e;
|
||||
qproperty-InBetweenBorderColor: #6e6c64;
|
||||
qproperty-SelectedInBetweenColor: #c7c7bb;
|
||||
qproperty-IgnoredInBetweenColor: #8a695e;
|
||||
qproperty-SelectedIgnoredInBetweenColor: #93807d;
|
||||
qproperty-SelectedEmptyColor: rgba(155, 159, 162, 0.5);
|
||||
qproperty-SelectedSceneRangeEmptyColor: rgba(155, 159, 162, 0.5);
|
||||
qproperty-TextColor: #000;
|
||||
|
|
|
@ -1,9 +1,24 @@
|
|||
<fxlayout help_command="iexplore" help_file="BokehIwa.html">
|
||||
<page name="Glare Iwa">
|
||||
<control>renderMode</control>
|
||||
<control>irisMode</control>
|
||||
<vbox modeSensitive="irisMode" mode="1,2,3,4">
|
||||
<separator/>
|
||||
<control>irisScale</control>
|
||||
<control>irisSymmetry</control>
|
||||
<control>irisAppearance</control>
|
||||
</vbox>
|
||||
<vbox modeSensitive="irisMode" mode="4">
|
||||
<control>irisGearEdgeCount</control>
|
||||
<control>irisRandomSeed</control>
|
||||
</vbox>
|
||||
<vbox modeSensitive="irisMode" mode="1,2,3,4">
|
||||
<separator/>
|
||||
</vbox>
|
||||
<control>intensity</control>
|
||||
<control>size</control>
|
||||
<control>rotation</control>
|
||||
<control>aberration</control>
|
||||
<control>noise_factor</control>
|
||||
<control>noise_size</control>
|
||||
<control>noise_octave</control>
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<fxlayout help_file="MotionBlurIwa.html">
|
||||
<page name="Motion Blur Iwa">
|
||||
<vbox>
|
||||
<hbox>
|
||||
<control>motionObjectType</control>
|
||||
<vbox modeSensitive="motionObjectType" mode="1,2,4">
|
||||
<control>motionObjectIndex</control>
|
||||
</hbox>
|
||||
</vbox>
|
||||
<control>shutterStart</control>
|
||||
<control>startValue</control>
|
||||
<control>startCurve</control>
|
||||
|
|
62
stuff/studiopalette/Global Palettes/color_key.tpl
Normal file
62
stuff/studiopalette/Global Palettes/color_key.tpl
Normal file
|
@ -0,0 +1,62 @@
|
|||
<palette name="1611507682_28145">
|
||||
<version>
|
||||
71 0
|
||||
</version>
|
||||
<styles>
|
||||
<style>
|
||||
"|-1611507682_28145-0"color_0 3 255 255 255 0
|
||||
</style>
|
||||
<style>
|
||||
"|-1611507682_28145-1"color_1 3 0 0 0 255
|
||||
</style>
|
||||
<style>
|
||||
"|-1611507682_28145-2"color_2 3 255 255 255 255
|
||||
</style>
|
||||
<style>
|
||||
_1 "|-1611507682_28145-3"color_3 3 255 0 0 255
|
||||
</style>
|
||||
<style>
|
||||
_1 "|-1611507682_28145-4"color_4 3 0 255 0 255
|
||||
</style>
|
||||
<style>
|
||||
_1 "|-1611507682_28145-5"color_5 3 0 0 255 255
|
||||
</style>
|
||||
<style>
|
||||
"|-1611507682_28145-6"color_6 3 255 128 255 255
|
||||
</style>
|
||||
<style>
|
||||
"|-1611507682_28145-7"color_7 3 128 255 192 255
|
||||
</style>
|
||||
<style>
|
||||
"|-1611507682_28145-8"color_8 3 255 255 0 255
|
||||
</style>
|
||||
<style>
|
||||
"|-1611507682_28145-9"color_9 3 128 128 255 255
|
||||
</style>
|
||||
<style>
|
||||
"|-1611507682_28145-10"color_10 3 255 128 0 255
|
||||
</style>
|
||||
<style>
|
||||
"|-1611507682_28145-11"color_11 3 0 192 255 255
|
||||
</style>
|
||||
<style>
|
||||
"|-1611507682_28145-12"color_12 3 128 255 255 255
|
||||
</style>
|
||||
<style>
|
||||
"|-1611507682_28145-13"color_13 3 255 128 128 255
|
||||
</style>
|
||||
</styles>
|
||||
<stylepages>
|
||||
<page>
|
||||
<name>
|
||||
colors
|
||||
</name>
|
||||
<indices>
|
||||
0 1 2 3 4 5 6 7 8 9 10 11 12 13
|
||||
</indices>
|
||||
</page>
|
||||
</stylepages>
|
||||
<shortcuts>
|
||||
9 0 1 2 3 4 5 6 7 8
|
||||
</shortcuts>
|
||||
</palette>
|
|
@ -395,7 +395,11 @@ elseif(BUILD_ENV_APPLE)
|
|||
if(GLEW-NOTFOUND)
|
||||
pkg_check_modules(GLEW REQUIRED glew)
|
||||
endif()
|
||||
set(GLEW_LIB ${GLEW_LIBRARIES})
|
||||
if (TARGET GLEW::GLEW)
|
||||
set(GLEW_LIB GLEW::GLEW)
|
||||
else()
|
||||
set(GLEW_LIB ${GLEW_LIBRARIES})
|
||||
endif()
|
||||
|
||||
pkg_check_modules(LZ4_LIB REQUIRED liblz4)
|
||||
|
||||
|
|
|
@ -26,7 +26,8 @@ public:
|
|||
m_errorPos; //!< Position of the error in the expression's text
|
||||
|
||||
bool m_isValid, //!< Whether the expression is valid
|
||||
m_hasBeenParsed; //!< Whether the expression has already been parsed
|
||||
m_hasBeenParsed, //!< Whether the expression has already been parsed
|
||||
m_hasReference;
|
||||
|
||||
public:
|
||||
Imp()
|
||||
|
@ -35,7 +36,8 @@ public:
|
|||
, m_calculator(0)
|
||||
, m_errorPos(0, -1)
|
||||
, m_isValid(false)
|
||||
, m_hasBeenParsed(true) {}
|
||||
, m_hasBeenParsed(true)
|
||||
, m_hasReference(false) {}
|
||||
~Imp() { delete m_calculator; }
|
||||
};
|
||||
|
||||
|
@ -60,6 +62,7 @@ TExpression::TExpression(const TExpression &src) : m_imp(new Imp()) {
|
|||
m_imp->m_error = src.m_imp->m_error;
|
||||
m_imp->m_errorPos = src.m_imp->m_errorPos;
|
||||
m_imp->m_hasBeenParsed = false;
|
||||
m_imp->m_hasReference = src.m_imp->m_hasReference;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
@ -85,11 +88,12 @@ const TSyntax::Grammar *TExpression::getGrammar() const {
|
|||
//--------------------------------------------------------------------------
|
||||
|
||||
void TExpression::setText(std::string text) {
|
||||
if (m_imp->m_text != text) {
|
||||
if (m_imp->m_text != text || m_imp->m_hasReference) {
|
||||
m_imp->m_text = text;
|
||||
delete m_imp->m_calculator;
|
||||
m_imp->m_calculator = 0;
|
||||
m_imp->m_isValid = false;
|
||||
m_imp->m_hasReference = false;
|
||||
m_imp->m_hasBeenParsed = false;
|
||||
m_imp->m_error = "";
|
||||
m_imp->m_errorPos = std::make_pair(0, -1);
|
||||
|
@ -142,8 +146,9 @@ void TExpression::parse() {
|
|||
delete m_imp->m_calculator;
|
||||
m_imp->m_calculator = 0;
|
||||
|
||||
m_imp->m_errorPos = std::make_pair(0, -1);
|
||||
m_imp->m_error = std::string();
|
||||
m_imp->m_errorPos = std::make_pair(0, -1);
|
||||
m_imp->m_error = std::string();
|
||||
m_imp->m_hasReference = false;
|
||||
|
||||
if (!m_imp->m_grammar) {
|
||||
m_imp->m_error = "No grammar defined";
|
||||
|
@ -156,7 +161,8 @@ void TExpression::parse() {
|
|||
if (m_imp->m_calculator)
|
||||
m_imp->m_calculator->setOwnerParameter(m_imp->m_param);
|
||||
|
||||
m_imp->m_isValid = parser.isValid();
|
||||
m_imp->m_isValid = parser.isValid();
|
||||
m_imp->m_hasReference = parser.hasReference();
|
||||
|
||||
if (!m_imp->m_isValid) {
|
||||
m_imp->m_error = parser.getError();
|
||||
|
|
|
@ -66,13 +66,15 @@ public:
|
|||
std::vector<SyntaxToken> m_syntaxTokens;
|
||||
Grammar::Position m_position;
|
||||
// Pattern *m_lastPattern;
|
||||
bool m_hasReference;
|
||||
|
||||
Imp(const Grammar *grammar)
|
||||
: m_grammar(grammar)
|
||||
, m_errorString("")
|
||||
, m_isValid(false)
|
||||
, m_calculator(0)
|
||||
, m_position(Grammar::ExpressionStart) {}
|
||||
, m_position(Grammar::ExpressionStart)
|
||||
, m_hasReference(false) {}
|
||||
~Imp() {
|
||||
clearPointerContainer(m_nodeStack);
|
||||
delete m_calculator;
|
||||
|
@ -235,14 +237,24 @@ bool Parser::Imp::parseExpression(bool checkOnly) {
|
|||
Calculator *Parser::parse(std::string text) {
|
||||
m_imp->m_tokenizer.setBuffer(text);
|
||||
clearPointerContainer(m_imp->m_nodeStack);
|
||||
m_imp->m_errorString = "";
|
||||
m_imp->m_isValid = false;
|
||||
m_imp->m_calculator = new Calculator();
|
||||
bool ret = m_imp->parseExpression(false);
|
||||
m_imp->m_errorString = "";
|
||||
m_imp->m_isValid = false;
|
||||
m_imp->m_hasReference = false;
|
||||
m_imp->m_calculator = new Calculator();
|
||||
bool ret = m_imp->parseExpression(false);
|
||||
if (ret && !m_imp->m_nodeStack.empty()) {
|
||||
m_imp->m_calculator->setRootNode(m_imp->m_nodeStack.back());
|
||||
|
||||
for (auto node : m_imp->m_nodeStack) {
|
||||
if (node->hasReference()) {
|
||||
m_imp->m_hasReference = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_imp->m_nodeStack.pop_back();
|
||||
m_imp->m_isValid = true;
|
||||
|
||||
} else {
|
||||
delete m_imp->m_calculator;
|
||||
m_imp->m_calculator = 0;
|
||||
|
@ -306,6 +318,10 @@ bool Parser::isValid() const { return m_imp->m_isValid; }
|
|||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
bool Parser::hasReference() const { return m_imp->m_hasReference; }
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
std::string Parser::getText() const { return m_imp->m_tokenizer.getBuffer(); }
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
|
|
@ -37,9 +37,10 @@ public:
|
|||
}
|
||||
int getUndoCount() const { return (int)m_undos.size(); }
|
||||
void setLast() {
|
||||
for (UINT i = 1; i < m_undos.size(); i++)
|
||||
m_undos[i]->m_isLastInBlock = false;
|
||||
m_undos[0]->m_isLastInBlock = true;
|
||||
for (UINT i = 0; i < m_undos.size(); i++) {
|
||||
m_undos[i]->m_isLastInBlock = (i == 0);
|
||||
m_undos[i]->m_isLastInRedoBlock = (i == m_undos.size() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void undo() const override {
|
||||
|
@ -65,7 +66,8 @@ public:
|
|||
//}
|
||||
void onAdd() override {}
|
||||
void add(TUndo *undo) {
|
||||
undo->m_isLastInBlock = true;
|
||||
undo->m_isLastInBlock = true;
|
||||
undo->m_isLastInRedoBlock = true;
|
||||
m_undos.push_back(undo);
|
||||
}
|
||||
|
||||
|
@ -97,7 +99,7 @@ public:
|
|||
return m_undos.back()->getHistoryType();
|
||||
}
|
||||
};
|
||||
}
|
||||
} // namespace
|
||||
|
||||
typedef std::deque<TUndo *> UndoList;
|
||||
typedef UndoList::iterator UndoListIterator;
|
||||
|
@ -186,9 +188,8 @@ void TUndoManager::TUndoManagerImp::doAdd(TUndo *undo) {
|
|||
int i, memorySize = 0, count = m_undoList.size();
|
||||
for (i = 0; i < count; i++) memorySize += m_undoList[i]->getSize();
|
||||
|
||||
while (
|
||||
count > 100 ||
|
||||
(count != 0 && memorySize + undo->getSize() > m_undoMemorySize)) // 20MB
|
||||
while (count > 100 || (count != 0 && memorySize + undo->getSize() >
|
||||
m_undoMemorySize)) // 20MB
|
||||
{
|
||||
--count;
|
||||
TUndo *undo = m_undoList.front();
|
||||
|
@ -197,7 +198,8 @@ void TUndoManager::TUndoManagerImp::doAdd(TUndo *undo) {
|
|||
delete undo;
|
||||
}
|
||||
|
||||
undo->m_isLastInBlock = true;
|
||||
undo->m_isLastInBlock = true;
|
||||
undo->m_isLastInRedoBlock = true;
|
||||
m_undoList.push_back(undo);
|
||||
m_current = m_undoList.end();
|
||||
}
|
||||
|
|
|
@ -701,6 +701,9 @@ void TFx::setNewIdentifier() { m_imp->m_id = ++m_imp->m_nextId; }
|
|||
//--------------------------------------------------
|
||||
|
||||
void TFx::loadData(TIStream &is) {
|
||||
// default version of fx is 1
|
||||
setFxVersion(1);
|
||||
|
||||
std::string tagName;
|
||||
VersionNumber tnzVersion = is.getVersion();
|
||||
// Prevent to load "params" tag under "super" tag on saving macro fx.
|
||||
|
@ -818,6 +821,10 @@ void TFx::loadData(TIStream &is) {
|
|||
is >> groupName;
|
||||
groupNames.append(groupName);
|
||||
}
|
||||
} else if (tagName == "fxVersion") {
|
||||
int version = 1;
|
||||
is >> version;
|
||||
setFxVersion(version);
|
||||
} else {
|
||||
throw TException("Unknown tag!");
|
||||
}
|
||||
|
@ -907,6 +914,7 @@ void TFx::saveData(TOStream &os) {
|
|||
for (i = 0; i < groupNameStack.size(); i++) os << groupNameStack[i];
|
||||
os.closeChild();
|
||||
}
|
||||
if (getFxVersion() != 1) os.child("fxVersion") << getFxVersion();
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
|
@ -992,6 +1000,14 @@ TFx *TFx::getLinkedFx() const {
|
|||
return m_imp->m_next->m_fx;
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
void TFx::setFxVersion(int v) { m_imp->m_attributes.setFxVersion(v); }
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
int TFx::getFxVersion() const { return m_imp->m_attributes.getFxVersion(); }
|
||||
|
||||
//===================================================
|
||||
//
|
||||
// TFxTimeRegion
|
||||
|
|
|
@ -468,13 +468,11 @@ void TSystem::readDirectory_DirItems(QStringList &dst, const TFilePath &path) {
|
|||
|
||||
#ifdef _WIN32
|
||||
// equivalent to sorting with QDir::LocaleAware
|
||||
struct strCompare {
|
||||
bool operator()(const QString &s1, const QString &s2) const {
|
||||
return QString::localeAwareCompare(s1, s2) < 0;
|
||||
}
|
||||
auto const strCompare = [](const QString &s1, const QString &s2) {
|
||||
return QString::localeAwareCompare(s1, s2) < 0;
|
||||
};
|
||||
|
||||
std::set<QString, strCompare> entries;
|
||||
std::set<QString, decltype(strCompare)> entries(strCompare);
|
||||
|
||||
WIN32_FIND_DATA find_dir_data;
|
||||
QString dir_search_path = dir.absolutePath() + "\\*";
|
||||
|
|
|
@ -902,7 +902,7 @@ void TifWriter::open(FILE *file, const TImageInfo &info) {
|
|||
std::wstring compressionType =
|
||||
((TEnumProperty *)(m_properties->getProperty("Compression Type")))
|
||||
->getValue();
|
||||
if (compressionType == TNZ_INFO_COMPRESS_LZW)
|
||||
if (compressionType == TNZ_INFO_COMPRESS_LZW || compressionType == TNZ_INFO_COMPRESS_LZW_LEG)
|
||||
TIFFSetField(m_tiff, TIFFTAG_COMPRESSION, COMPRESSION_LZW);
|
||||
else if (compressionType == TNZ_INFO_COMPRESS_PACKBITS)
|
||||
TIFFSetField(m_tiff, TIFFTAG_COMPRESSION, COMPRESSION_PACKBITS);
|
||||
|
|
|
@ -14,7 +14,8 @@
|
|||
#define TNZ_INFO_COMPRESS_CCITTRLE L"CCITT modified Huffman Run-length encoding"
|
||||
#define TNZ_INFO_COMPRESS_CCITTFAX3 L"CCITT Group 3 fax encoding"
|
||||
#define TNZ_INFO_COMPRESS_CCITTFAX4 L"CCITT Group 4 fax encoding"
|
||||
#define TNZ_INFO_COMPRESS_LZW L"Lempel-Ziv & Welch encoding"
|
||||
#define TNZ_INFO_COMPRESS_LZW L"Lempel-Ziv and Welch encoding"
|
||||
#define TNZ_INFO_COMPRESS_LZW_LEG L"Lempel-Ziv & Welch encoding"
|
||||
#define TNZ_INFO_COMPRESS_PACKBITS L"Macintosh Run-length encoding"
|
||||
#define TNZ_INFO_COMPRESS_THUNDERSCAN L"ThunderScan Run-length encoding"
|
||||
#define TNZ_INFO_COMPRESS_RLE L"Run-length compression"
|
||||
|
|
|
@ -53,10 +53,6 @@ public:
|
|||
PlasticDeformer();
|
||||
~PlasticDeformer();
|
||||
|
||||
friend void swap(PlasticDeformer &a, PlasticDeformer &b) {
|
||||
std::swap(a.m_imp, b.m_imp);
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns whether the last compilation procedure succeeded, or it either failed
|
||||
or was never invoked after the last initialize() call.
|
||||
|
|
|
@ -503,6 +503,9 @@ public:
|
|||
// parameter is loaded. Do nothing by default.
|
||||
virtual void onObsoleteParamLoaded(const std::string ¶mName) {}
|
||||
|
||||
void setFxVersion(int);
|
||||
int getFxVersion() const;
|
||||
|
||||
public:
|
||||
// Id-related functions
|
||||
|
||||
|
|
|
@ -33,6 +33,8 @@ class DVAPI TFxAttributes {
|
|||
|
||||
/*-- MotionBlurなどのFxのために、オブジェクトの軌跡のデータを取得する --*/
|
||||
QList<TPointD> m_motionPoints;
|
||||
// to maintain backward compatibility in the fx
|
||||
int m_fxVersion;
|
||||
|
||||
public:
|
||||
TFxAttributes();
|
||||
|
@ -62,6 +64,8 @@ public:
|
|||
m_motionPoints = motionPoints;
|
||||
}
|
||||
QList<TPointD> getMotionPoints() { return m_motionPoints; }
|
||||
void setFxVersion(int version) { m_fxVersion = version; }
|
||||
int getFxVersion() const { return m_fxVersion; };
|
||||
|
||||
// Group management
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ class TUnit;
|
|||
namespace TSyntax {
|
||||
class Token;
|
||||
class Calculator;
|
||||
}
|
||||
} // namespace TSyntax
|
||||
|
||||
//==============================================
|
||||
|
||||
|
@ -63,6 +63,8 @@ public:
|
|||
|
||||
virtual void accept(CalculatorNodeVisitor &visitor) = 0;
|
||||
|
||||
virtual bool hasReference() const { return false; }
|
||||
|
||||
private:
|
||||
// Non-copyable
|
||||
CalculatorNode(const CalculatorNode &);
|
||||
|
|
|
@ -57,14 +57,15 @@ public:
|
|||
|
||||
/*-- (StylePickerTool内で)LineとAreaを切り替えてPickできる。mode: 0=Area,
|
||||
* 1=Line, 2=Line&Areas(default) --*/
|
||||
int pickStyleId(const TPointD &point, double radius2 = 1, int mode = 2) const;
|
||||
int pickStyleId(const TPointD &point, double radius, double scale2,
|
||||
int mode = 2) const;
|
||||
|
||||
/*--- Toonz Raster LevelのToneを拾う。 ---*/
|
||||
int pickTone(const TPointD &pos) const;
|
||||
|
||||
// per pli come sopra, ma ritorna il maincolor
|
||||
// per tzp e fullcolor ritorna il colore effettivo del pixel
|
||||
TPixel32 pickColor(const TPointD &point, double radius2 = 1) const;
|
||||
TPixel32 pickColor(const TPointD &point, double radius, double scale2) const;
|
||||
TPixel32 pickAverageColor(const TRectD &rect) const;
|
||||
|
||||
// ritorna il colore medio presente nell'area della finestra corrente openGL
|
||||
|
|
|
@ -466,8 +466,9 @@ return true if the method execution can have changed the current tool
|
|||
const TAffine &getMatrix() const { return m_matrix; }
|
||||
void setMatrix(const TAffine &matrix) { m_matrix = matrix; }
|
||||
|
||||
TAffine getCurrentColumnMatrix()
|
||||
TAffine getCurrentColumnMatrix(int frame = -1)
|
||||
const; //!< Returns the current column matrix transformation.
|
||||
//! if frame = -1 then it uses the current frame
|
||||
//! \sa TXsheet::getPlacement.
|
||||
|
||||
TAffine getCurrentColumnParentMatrix()
|
||||
|
@ -480,9 +481,10 @@ return true if the method execution can have changed the current tool
|
|||
Returns the matrix transformation of the stage object with column
|
||||
index equal to \p index
|
||||
and frame as the current frame.
|
||||
\sa TXsheet::getPlacement.
|
||||
if frame = -1 then it uses the current frame
|
||||
\sa TXsheet::getPlacement.
|
||||
*/
|
||||
TAffine getColumnMatrix(int index) const;
|
||||
TAffine getColumnMatrix(int index, int frame = -1) const;
|
||||
|
||||
/*!
|
||||
Updates the current matrix transformation with the actual column matrix
|
||||
|
|
57
toonz/sources/include/toonz/expressionreferencemonitor.h
Normal file
57
toonz/sources/include/toonz/expressionreferencemonitor.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
#pragma once
|
||||
|
||||
#ifndef EXPRESSIONREFERENCEMONITOR_H
|
||||
#define EXPRESSIONREFERENCEMONITOR_H
|
||||
|
||||
#undef DVAPI
|
||||
#undef DVVAR
|
||||
#ifdef TOONZLIB_EXPORTS
|
||||
#define DVAPI DV_EXPORT_API
|
||||
#define DVVAR DV_EXPORT_VAR
|
||||
#else
|
||||
#define DVAPI DV_IMPORT_API
|
||||
#define DVVAR DV_IMPORT_VAR
|
||||
#endif
|
||||
|
||||
#include <QMap>
|
||||
#include <QSet>
|
||||
#include <QString>
|
||||
|
||||
class TDoubleParam;
|
||||
|
||||
class DVAPI ExpressionReferenceMonitorInfo {
|
||||
// name of the parameter
|
||||
QString m_name = "";
|
||||
// true if the parameter is not monitored
|
||||
bool m_ignored = false;
|
||||
// column indices to which the parameter refers.
|
||||
// note that the columns refered by the "cell" syntax will be
|
||||
// registered in this container, but not in the paramRefMap.
|
||||
QSet<int> m_colRefMap;
|
||||
// parameters to which the parameter refers
|
||||
QSet<TDoubleParam*> m_paramRefMap;
|
||||
|
||||
public:
|
||||
QString& name() { return m_name; }
|
||||
bool& ignored() { return m_ignored; }
|
||||
QSet<int>& colRefMap() { return m_colRefMap; }
|
||||
QSet<TDoubleParam*>& paramRefMap() { return m_paramRefMap; }
|
||||
};
|
||||
|
||||
class DVAPI ExpressionReferenceMonitor {
|
||||
QMap<TDoubleParam*, ExpressionReferenceMonitorInfo> m_info;
|
||||
|
||||
public:
|
||||
ExpressionReferenceMonitor() {}
|
||||
QMap<TDoubleParam*, ExpressionReferenceMonitorInfo>& info() { return m_info; }
|
||||
|
||||
void clearAll() { m_info.clear(); }
|
||||
|
||||
ExpressionReferenceMonitor* clone() {
|
||||
ExpressionReferenceMonitor* ret = new ExpressionReferenceMonitor();
|
||||
ret->info() = m_info;
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
|
@ -397,6 +397,9 @@ public:
|
|||
// Animation tab
|
||||
int getKeyframeType() const { return getIntValue(keyframeType); }
|
||||
int getAnimationStep() const { return getIntValue(animationStep); }
|
||||
bool isModifyExpressionOnMovingReferencesEnabled() const {
|
||||
return getBoolValue(modifyExpressionOnMovingReferences);
|
||||
}
|
||||
|
||||
// Preview tab
|
||||
void getBlankValues(int &bCount, TPixel32 &bColor) const {
|
||||
|
|
|
@ -131,6 +131,7 @@ enum PreferencesItemId {
|
|||
// Animation
|
||||
keyframeType,
|
||||
animationStep,
|
||||
modifyExpressionOnMovingReferences,
|
||||
|
||||
//----------
|
||||
// Preview
|
||||
|
|
|
@ -302,14 +302,16 @@ class DVAPI Picker final : public Visitor {
|
|||
TPointD m_point;
|
||||
TAffine m_viewAff;
|
||||
double m_minDist2;
|
||||
int m_devPixRatio;
|
||||
|
||||
int m_currentColumnIndex = -1;
|
||||
|
||||
public:
|
||||
Picker(const TAffine &viewAff, const TPointD &p,
|
||||
const ImagePainter::VisualSettings &vs);
|
||||
const ImagePainter::VisualSettings &vs, int devPixRatio = 1);
|
||||
|
||||
void setDistance(double d);
|
||||
// minimum distance to pick thin vector strokes.
|
||||
void setMinimumDistance(double d);
|
||||
|
||||
void onImage(const Stage::Player &data) override;
|
||||
void onRasterImage(TRasterImage *ri, const Stage::Player &data) override{};
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
// TnzLib includes
|
||||
#include "toonz/txshcolumn.h"
|
||||
#include "toonz/txshlevel.h"
|
||||
#include "toonz/txsheetcolumnchange.h"
|
||||
|
||||
#include "cellposition.h"
|
||||
|
||||
|
@ -50,6 +51,8 @@ class TXshSoundColumn;
|
|||
class TXshNoteSet;
|
||||
class TFrameId;
|
||||
class Orientation;
|
||||
class TXsheetColumnChangeObserver;
|
||||
class ExpressionReferenceMonitor;
|
||||
|
||||
//=============================================================================
|
||||
|
||||
|
@ -159,6 +162,8 @@ private:
|
|||
int m_cameraColumnIndex;
|
||||
TXshColumn *m_cameraColumn;
|
||||
|
||||
TXsheetColumnChangeObserver *m_observer;
|
||||
|
||||
DECLARE_CLASS_CODE
|
||||
|
||||
public:
|
||||
|
@ -236,15 +241,15 @@ public:
|
|||
*/
|
||||
void removeCells(int row, int col, int rowCount = 1);
|
||||
|
||||
/*! If column identified by index \b \e col is not empty, is a \b TXshCellColumn and is not
|
||||
locked, clear \b \e rowCount cells starting from \b \e row and it recalls TXshCellColumn::clearCells().
|
||||
Clears cells and it shifts remaining cells. Xsheet's frame count is updated.
|
||||
\sa removeCells(), insertCells()
|
||||
*/ void
|
||||
clearCells(int row, int col, int rowCount = 1);
|
||||
/*! If column identified by index \b \e col is not empty, is a \b
|
||||
TXshCellColumn and is not locked, clear \b \e rowCount cells starting from
|
||||
\b \e row and it recalls TXshCellColumn::clearCells(). Clears cells and it
|
||||
shifts remaining cells. Xsheet's frame count is updated. \sa removeCells(),
|
||||
insertCells()
|
||||
*/ void clearCells(int row, int col, int rowCount = 1);
|
||||
/*! Clears xsheet. It sets to default values all xsheet elements contained in
|
||||
* struct \b TXsheetImp.
|
||||
*/
|
||||
*/
|
||||
void clearAll();
|
||||
/*! Returns cell range of column identified by index \b \e col and set \b \e
|
||||
r0 and \b \e r1 respectively to first and last not empty cell, it then
|
||||
|
@ -432,7 +437,7 @@ frame duplication.
|
|||
/*! Exposes level \b \e xl in xsheet starting from cell identified by \b \e
|
||||
row and \b \e col.
|
||||
Returns the number of the inserted cells.
|
||||
*/
|
||||
*/
|
||||
int exposeLevel(int row, int col, TXshLevel *xl, bool overwrite = false);
|
||||
|
||||
// cutomized exposseLevel used from LoadLevel command
|
||||
|
@ -461,7 +466,7 @@ frame duplication.
|
|||
*/
|
||||
void saveData(TOStream &os) override;
|
||||
/*! Inserts an empty column in \b \e index calling \b insertColumn().
|
||||
*/
|
||||
*/
|
||||
void insertColumn(int index,
|
||||
TXshColumn::ColumnType type = TXshColumn::eLevelType);
|
||||
/*! Insert \b \e column in column \b \e index. Insert column in the column
|
||||
|
@ -497,10 +502,10 @@ in TXsheetImp.
|
|||
calls
|
||||
\b TColumnSetT::getColumnCount().
|
||||
\sa getColumn() and getMaxFrame().
|
||||
*/
|
||||
*/
|
||||
int getColumnCount() const;
|
||||
/*! Returns first not empty column index in xsheet.
|
||||
*/
|
||||
*/
|
||||
int getFirstFreeColumnIndex() const;
|
||||
|
||||
TSoundTrack *makeSound(SoundProperties *properties, int col = -1);
|
||||
|
@ -570,6 +575,14 @@ in TXsheetImp.
|
|||
void setCameraColumnLocked(bool locked) { m_cameraColumn->lock(locked); }
|
||||
bool isCameraColumnLocked() { return m_cameraColumn->isLocked(); }
|
||||
|
||||
ExpressionReferenceMonitor *getExpRefMonitor() const;
|
||||
void setObserver(TXsheetColumnChangeObserver *observer);
|
||||
|
||||
void notify(const TXsheetColumnChange &change);
|
||||
void notifyFxAdded(const std::vector<TFx *> &fxs);
|
||||
void notifyStageObjectAdded(const TStageObjectId id);
|
||||
bool isReferenceManagementIgnored(TDoubleParam *);
|
||||
|
||||
protected:
|
||||
bool checkCircularReferences(TXsheet *childCandidate);
|
||||
|
||||
|
|
56
toonz/sources/include/toonz/txsheetcolumnchange.h
Normal file
56
toonz/sources/include/toonz/txsheetcolumnchange.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
#pragma once
|
||||
|
||||
#ifndef TXSHEETCOLUMNCHANGE_INCLUDED
|
||||
#define TXSHEETCOLUMNCHANGE_INCLUDED
|
||||
|
||||
// TnzCore includes
|
||||
#include "tcommon.h"
|
||||
// TnzLib includes
|
||||
#include "tstageobjectid.h"
|
||||
|
||||
#undef DVAPI
|
||||
#undef DVVAR
|
||||
#ifdef TOONZLIB_EXPORTS
|
||||
#define DVAPI DV_EXPORT_API
|
||||
#define DVVAR DV_EXPORT_VAR
|
||||
#else
|
||||
#define DVAPI DV_IMPORT_API
|
||||
#define DVVAR DV_IMPORT_VAR
|
||||
#endif
|
||||
|
||||
class TFx;
|
||||
class TDoubleParam;
|
||||
//===========================================================
|
||||
|
||||
//*****************************************************************************************
|
||||
// TXsheetColumnChange declaration
|
||||
//*****************************************************************************************
|
||||
|
||||
class DVAPI TXsheetColumnChange {
|
||||
public:
|
||||
enum OperationType { Insert, Remove, Move } m_type;
|
||||
|
||||
int m_index1, m_index2;
|
||||
|
||||
public:
|
||||
TXsheetColumnChange(OperationType type, int index1, int index2 = -1)
|
||||
: m_type(type), m_index1(index1), m_index2(index2) {}
|
||||
};
|
||||
|
||||
//*****************************************************************************************
|
||||
// TXsheetColumnChangeObserver definition
|
||||
//*****************************************************************************************
|
||||
|
||||
class DVAPI TXsheetColumnChangeObserver {
|
||||
public:
|
||||
virtual void onChange(const TXsheetColumnChange &) = 0;
|
||||
// Call when adding fxs in which expression references may be included.
|
||||
// This can be happen when undoing removing fxs operation.
|
||||
virtual void onFxAdded(const std::vector<TFx *> &) = 0;
|
||||
// Call when adding stage objects in which expression references may be
|
||||
// included. This can be happen when undoing removing objects operation.
|
||||
virtual void onStageObjectAdded(const TStageObjectId) = 0;
|
||||
virtual bool isIgnored(TDoubleParam *) = 0;
|
||||
};
|
||||
|
||||
#endif // TPARAMCHANGE_INCLUDED
|
|
@ -4,6 +4,7 @@
|
|||
#define XSHEETEXPR_INCLUDED
|
||||
|
||||
#include "tgrammar.h"
|
||||
#include <QSet>
|
||||
|
||||
#undef DVAPI
|
||||
#undef DVVAR
|
||||
|
@ -24,5 +25,7 @@ class TExpression;
|
|||
DVAPI TSyntax::Grammar *createXsheetGrammar(TXsheet *xsh);
|
||||
DVAPI bool dependsOn(TExpression &expr, TDoubleParam *possiblyDependentParam);
|
||||
DVAPI bool dependsOn(TDoubleParam *param, TDoubleParam *possiblyDependentParam);
|
||||
DVAPI void referenceParams(TExpression &expr, QSet<int> &columnIndices,
|
||||
QSet<TDoubleParam *> ¶ms);
|
||||
|
||||
#endif // XSHEETEXPR_INCLUDED
|
||||
|
|
|
@ -40,7 +40,7 @@ class DoubleLineEdit;
|
|||
class IntLineEdit;
|
||||
class MeasuredDoubleLineEdit;
|
||||
class CheckBox;
|
||||
}
|
||||
} // namespace DVGui
|
||||
|
||||
//---------------------------------------------------------------
|
||||
|
||||
|
@ -124,8 +124,8 @@ public:
|
|||
// camera => widget fields (i.e. initialize widget)
|
||||
void setFields(const TCamera *camera);
|
||||
|
||||
// widget fields => camera
|
||||
void getFields(TCamera *camera);
|
||||
// widget fields => camera return true if the value is actually changed
|
||||
bool getFields(TCamera *camera);
|
||||
|
||||
QSize sizeHint() const override { return minimumSize(); }
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ class TXsheet;
|
|||
class TParamContainer;
|
||||
class TFxHandle;
|
||||
class TObjectHandle;
|
||||
class TXsheetHandle;
|
||||
|
||||
class FunctionTreeView;
|
||||
class FunctionViewer;
|
||||
|
@ -70,7 +71,7 @@ class FunctionViewer;
|
|||
TnzExt library).
|
||||
*/
|
||||
|
||||
class FunctionTreeModel final : public TreeModel, public TParamObserver {
|
||||
class DVAPI FunctionTreeModel final : public TreeModel, public TParamObserver {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
@ -85,6 +86,7 @@ to
|
|||
|
||||
virtual bool isActive() const = 0;
|
||||
virtual bool isAnimated() const = 0;
|
||||
virtual bool isIgnored() const = 0;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
|
@ -104,6 +106,7 @@ to
|
|||
|
||||
bool isActive() const override;
|
||||
bool isAnimated() const override;
|
||||
bool isIgnored() const override;
|
||||
|
||||
virtual QString getShortName() const { return m_name; }
|
||||
virtual QString getLongName() const { return m_name; }
|
||||
|
@ -153,9 +156,9 @@ color, which
|
|||
//----------------------------------------------------------------------------------
|
||||
|
||||
//! The model item representing a channel (i.e. a real-valued function).
|
||||
class Channel final : public ParamWrapper,
|
||||
public Item,
|
||||
public TParamObserver {
|
||||
class DVAPI Channel final : public ParamWrapper,
|
||||
public Item,
|
||||
public TParamObserver {
|
||||
FunctionTreeModel *m_model; //!< (\p not \p owned) Reference to the model
|
||||
ChannelGroup
|
||||
*m_group; //!< (\p not \p owned) Reference to the enclosing group
|
||||
|
@ -189,6 +192,7 @@ color, which
|
|||
void setIsActive(bool active);
|
||||
|
||||
bool isAnimated() const override;
|
||||
bool isIgnored() const override;
|
||||
|
||||
bool isCurrent() const;
|
||||
void setIsCurrent(bool current);
|
||||
|
@ -313,7 +317,7 @@ public:
|
|||
|
||||
//=============================================================================
|
||||
|
||||
class FxChannelGroup final : public FunctionTreeModel::ChannelGroup {
|
||||
class DVAPI FxChannelGroup final : public FunctionTreeModel::ChannelGroup{
|
||||
public:
|
||||
TFx *m_fx;
|
||||
|
||||
|
@ -337,7 +341,8 @@ public:
|
|||
|
||||
//=============================================================================
|
||||
|
||||
class StageObjectChannelGroup final : public FunctionTreeModel::ChannelGroup {
|
||||
class DVAPI StageObjectChannelGroup final
|
||||
: public FunctionTreeModel::ChannelGroup {
|
||||
public:
|
||||
TStageObject *m_stageObject; //!< (not owned) Referenced stage object
|
||||
FunctionTreeModel::ChannelGroup
|
||||
|
@ -381,6 +386,8 @@ class FunctionTreeView final : public TreeView {
|
|||
QColor m_textColor; // text color (black)
|
||||
Q_PROPERTY(QColor TextColor READ getTextColor WRITE setTextColor)
|
||||
|
||||
TXsheetHandle *m_xshHandle;
|
||||
|
||||
public:
|
||||
FunctionTreeView(FunctionViewer *parent);
|
||||
|
||||
|
@ -392,6 +399,9 @@ public:
|
|||
QColor getTextColor() const { return m_textColor; }
|
||||
FunctionViewer *getViewer() { return m_viewer; }
|
||||
|
||||
void setXsheetHandle(TXsheetHandle *xshHandle) { m_xshHandle = xshHandle; }
|
||||
TXsheetHandle *getXsheetHandle() { return m_xshHandle; }
|
||||
|
||||
protected:
|
||||
void onClick(TreeModel::Item *item, const QPoint &itemPos,
|
||||
QMouseEvent *e) override;
|
||||
|
|
|
@ -121,6 +121,7 @@ public:
|
|||
bool columnsOrGraphHasFocus();
|
||||
void setSceneHandle(TSceneHandle *sceneHandle);
|
||||
TSceneHandle *getSceneHandle() const { return m_sceneHandle; }
|
||||
TXsheetHandle *getXsheetHandle() const { return m_xshHandle; }
|
||||
|
||||
// SaveLoadQSettings
|
||||
virtual void save(QSettings &settings) const override;
|
||||
|
|
|
@ -155,6 +155,7 @@ private:
|
|||
signals:
|
||||
void doCollapse(const QList<TFxP> &);
|
||||
void doExplodeChild(const QList<TFxP> &);
|
||||
void doDelete();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -54,6 +54,8 @@ class QToolButton;
|
|||
class QAction;
|
||||
class QTouchEvent;
|
||||
class QGestureEvent;
|
||||
class FxSelection;
|
||||
class StageObjectSelection;
|
||||
|
||||
//====================================================
|
||||
namespace {
|
||||
|
@ -566,6 +568,9 @@ signals:
|
|||
void doExplodeChild(QList<TStageObjectId>);
|
||||
void editObject();
|
||||
|
||||
void doDeleteFxs(const FxSelection *);
|
||||
void doDeleteStageObjects(const StageObjectSelection *);
|
||||
|
||||
protected slots:
|
||||
|
||||
void onSceneChanged();
|
||||
|
@ -577,6 +582,9 @@ protected slots:
|
|||
void zoomModeEnabled();
|
||||
void handModeEnabled();
|
||||
|
||||
void deleteFxs();
|
||||
void deleteStageObjects();
|
||||
|
||||
private:
|
||||
SchematicSceneViewer *m_viewer;
|
||||
StageSchematicScene *m_stageScene;
|
||||
|
|
|
@ -253,10 +253,14 @@ class DVAPI SpreadsheetViewer : public QDialog {
|
|||
QColor m_keyFrameColor; // (219,139,54)
|
||||
QColor m_keyFrameBorderColor; // (82,51,20)
|
||||
QColor m_selectedKeyFrameColor; // (237,197,155)
|
||||
QColor m_ignoredKeyFrameColor;
|
||||
QColor m_selectedIgnoredKeyFrameColor;
|
||||
// key frame inbetween
|
||||
QColor m_inBetweenColor; // (194,194,176)
|
||||
QColor m_inBetweenBorderColor; // (72,72,65)
|
||||
QColor m_selectedInBetweenColor; // (225,225,216)
|
||||
QColor m_ignoredInBetweenColor;
|
||||
QColor m_selectedIgnoredInBetweenColor;
|
||||
// empty cell
|
||||
QColor m_selectedEmptyColor; // (190,190,190)
|
||||
// empty cell in the scene range
|
||||
|
@ -266,12 +270,22 @@ class DVAPI SpreadsheetViewer : public QDialog {
|
|||
setKeyFrameBorderColor)
|
||||
Q_PROPERTY(QColor SelectedKeyFrameColor READ getSelectedKeyFrameColor WRITE
|
||||
setSelectedKeyFrameColor)
|
||||
Q_PROPERTY(QColor IgnoredKeyFrameColor READ getIgnoredKeyFrameColor WRITE
|
||||
setIgnoredKeyFrameColor)
|
||||
Q_PROPERTY(
|
||||
QColor SelectedIgnoredKeyFrameColor READ getSelectedIgnoredKeyFrameColor
|
||||
WRITE setSelectedIgnoredKeyFrameColor)
|
||||
Q_PROPERTY(
|
||||
QColor InBetweenColor READ getInBetweenColor WRITE setInBetweenColor)
|
||||
Q_PROPERTY(QColor InBetweenBorderColor READ getInBetweenBorderColor WRITE
|
||||
setInBetweenBorderColor)
|
||||
Q_PROPERTY(QColor SelectedInBetweenColor READ getSelectedInBetweenColor WRITE
|
||||
setSelectedInBetweenColor)
|
||||
Q_PROPERTY(QColor IgnoredInBetweenColor READ getIgnoredInBetweenColor WRITE
|
||||
setIgnoredInBetweenColor)
|
||||
Q_PROPERTY(
|
||||
QColor SelectedIgnoredInBetweenColor READ getSelectedIgnoredInBetweenColor
|
||||
WRITE setSelectedIgnoredInBetweenColor)
|
||||
Q_PROPERTY(QColor SelectedEmptyColor READ getSelectedEmptyColor WRITE
|
||||
setSelectedEmptyColor)
|
||||
Q_PROPERTY(
|
||||
|
@ -352,6 +366,18 @@ public:
|
|||
m_selectedKeyFrameColor = color;
|
||||
}
|
||||
QColor getSelectedKeyFrameColor() const { return m_selectedKeyFrameColor; }
|
||||
|
||||
void setIgnoredKeyFrameColor(const QColor &color) {
|
||||
m_ignoredKeyFrameColor = color;
|
||||
}
|
||||
QColor getIgnoredKeyFrameColor() const { return m_ignoredKeyFrameColor; }
|
||||
void setSelectedIgnoredKeyFrameColor(const QColor &color) {
|
||||
m_selectedIgnoredKeyFrameColor = color;
|
||||
}
|
||||
QColor getSelectedIgnoredKeyFrameColor() const {
|
||||
return m_selectedIgnoredKeyFrameColor;
|
||||
}
|
||||
|
||||
void setInBetweenColor(const QColor &color) { m_inBetweenColor = color; }
|
||||
QColor getInBetweenColor() const { return m_inBetweenColor; }
|
||||
void setInBetweenBorderColor(const QColor &color) {
|
||||
|
@ -362,6 +388,18 @@ public:
|
|||
m_selectedInBetweenColor = color;
|
||||
}
|
||||
QColor getSelectedInBetweenColor() const { return m_selectedInBetweenColor; }
|
||||
|
||||
void setIgnoredInBetweenColor(const QColor &color) {
|
||||
m_ignoredInBetweenColor = color;
|
||||
}
|
||||
QColor getIgnoredInBetweenColor() const { return m_ignoredInBetweenColor; }
|
||||
void setSelectedIgnoredInBetweenColor(const QColor &color) {
|
||||
m_selectedIgnoredInBetweenColor = color;
|
||||
}
|
||||
QColor getSelectedIgnoredInBetweenColor() const {
|
||||
return m_selectedIgnoredInBetweenColor;
|
||||
}
|
||||
|
||||
void setSelectedEmptyColor(const QColor &color) {
|
||||
m_selectedEmptyColor = color;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
// Qt includes
|
||||
#include <QList>
|
||||
#include <QMap>
|
||||
|
||||
#undef DVAPI
|
||||
#undef DVVAR
|
||||
|
@ -128,6 +129,12 @@ public:
|
|||
std::vector<TStageObjectId> restoreObjects(
|
||||
std::set<int> &columnIndices, std::list<int> &restoredSplinIds,
|
||||
TXsheet *xsheet, int fxFlags, const TPointD &pos = TConst::nowhere) const;
|
||||
|
||||
std::vector<TStageObjectId> restoreObjects(
|
||||
std::set<int> &columnIndices, std::list<int> &restoredSplinIds,
|
||||
TXsheet *xsheet, int fxFlags,
|
||||
QMap<TStageObjectId, TStageObjectId> &idTable,
|
||||
QMap<TFx *, TFx *> &fxTable, const TPointD &pos = TConst::nowhere) const;
|
||||
};
|
||||
|
||||
#endif // STAGEOBJECT_DATA_H
|
||||
|
|
|
@ -137,6 +137,8 @@ public:
|
|||
|
||||
SchematicViewer *getSchematicViewer() { return m_viewer; }
|
||||
|
||||
StageObjectSelection *getStageSelection() const { return m_selection; }
|
||||
|
||||
private:
|
||||
StageSchematicNode *addStageSchematicNode(TStageObject *pegbar);
|
||||
StageSchematicGroupNode *addStageGroupNode(QList<TStageObject *> objs);
|
||||
|
|
|
@ -40,6 +40,9 @@ public:
|
|||
//! return true if the last parsed string was correct
|
||||
bool isValid() const;
|
||||
|
||||
//! return true if the last parsed string was correct
|
||||
bool hasReference() const;
|
||||
|
||||
//! return the last parsed string
|
||||
std::string getText() const;
|
||||
|
||||
|
|
|
@ -28,7 +28,10 @@
|
|||
|
||||
class DVAPI TUndo {
|
||||
public:
|
||||
// To be called in the last of the block when undo
|
||||
bool m_isLastInBlock;
|
||||
// To be called in the last of the block when redo
|
||||
bool m_isLastInRedoBlock;
|
||||
|
||||
public:
|
||||
TUndo() {}
|
||||
|
|
|
@ -12,11 +12,15 @@
|
|||
#include "iwa_xyz.h"
|
||||
#include "iwa_simplexnoise.h"
|
||||
|
||||
#include <random>
|
||||
|
||||
#include <QPair>
|
||||
#include <QVector>
|
||||
#include <QReadWriteLock>
|
||||
#include <QMutexLocker>
|
||||
#include <QMap>
|
||||
#include <QImage>
|
||||
#include <QPainter>
|
||||
|
||||
namespace {
|
||||
// FFT coordinate -> Normal corrdinate
|
||||
|
@ -38,25 +42,55 @@ inline int getCoord(int i, int j, int lx, int ly) {
|
|||
|
||||
Iwa_GlareFx::Iwa_GlareFx()
|
||||
: m_renderMode(new TIntEnumParam(RendeMode_FilterPreview, "Filter Preview"))
|
||||
, m_irisMode(new TIntEnumParam(Iris_InputImage, "Input Image"))
|
||||
, m_irisScale(0.2)
|
||||
, m_irisGearEdgeCount(10)
|
||||
, m_irisRandomSeed(0)
|
||||
, m_irisSymmetry(1.0)
|
||||
, m_irisAppearance(new TIntEnumParam())
|
||||
, m_intensity(0.0)
|
||||
, m_size(100.0)
|
||||
, m_rotation(0.0)
|
||||
, m_aberration(1.0)
|
||||
, m_noise_factor(0.0)
|
||||
, m_noise_size(0.5)
|
||||
, m_noise_octave(new TIntEnumParam(1, "1"))
|
||||
, m_noise_evolution(0.0)
|
||||
, m_noise_offset(TPointD(0, 0)) {
|
||||
// Version 1 : lights had been constantly summed in all wavelength
|
||||
// Version 2 : intensities are weighted proportional to 1/(rambda^2)
|
||||
setFxVersion(2);
|
||||
|
||||
// Bind the common parameters
|
||||
addInputPort("Source", m_source);
|
||||
addInputPort("Iris", m_iris);
|
||||
|
||||
bindParam(this, "renderMode", m_renderMode);
|
||||
m_renderMode->addItem(RendeMode_Render, "Render");
|
||||
m_renderMode->addItem(RenderMode_Iris, "Iris");
|
||||
|
||||
bindParam(this, "irisMode", m_irisMode);
|
||||
m_irisMode->addItem(Iris_Square, "4 Streaks");
|
||||
m_irisMode->addItem(Iris_Hexagon, "6 Streaks");
|
||||
m_irisMode->addItem(Iris_Octagon, "8 Streaks");
|
||||
m_irisMode->addItem(Iris_GearShape, "Multiple Streaks");
|
||||
|
||||
bindParam(this, "irisScale", m_irisScale);
|
||||
bindParam(this, "irisGearEdgeCount", m_irisGearEdgeCount);
|
||||
bindParam(this, "irisRandomSeed", m_irisRandomSeed);
|
||||
bindParam(this, "irisSymmetry", m_irisSymmetry);
|
||||
bindParam(this, "irisAppearance", m_irisAppearance);
|
||||
m_irisAppearance->addItem(Appearance_ThinLine, "Thin Line");
|
||||
m_irisAppearance->addItem(Appearance_MediumLine, "Medium Line");
|
||||
m_irisAppearance->addItem(Appearance_ThickLine, "Thick Line");
|
||||
m_irisAppearance->addItem(Appearance_Fill, "Filled");
|
||||
m_irisAppearance->setValue(Appearance_MediumLine);
|
||||
|
||||
bindParam(this, "intensity", m_intensity, false);
|
||||
bindParam(this, "size", m_size, false);
|
||||
m_size->setMeasureName("fxLength");
|
||||
bindParam(this, "rotation", m_rotation, false);
|
||||
bindParam(this, "aberration", m_aberration, false);
|
||||
|
||||
bindParam(this, "noise_factor", m_noise_factor, false);
|
||||
bindParam(this, "noise_size", m_noise_size, false);
|
||||
|
@ -69,9 +103,15 @@ Iwa_GlareFx::Iwa_GlareFx()
|
|||
m_noise_offset->getX()->setMeasureName("fxLength");
|
||||
m_noise_offset->getY()->setMeasureName("fxLength");
|
||||
|
||||
m_irisScale->setValueRange(0.1, 0.8);
|
||||
m_irisGearEdgeCount->setValueRange(3, 50);
|
||||
m_irisSymmetry->setValueRange(0.1, 1.0);
|
||||
m_irisRandomSeed->setValueRange(0, (std::numeric_limits<int>::max)());
|
||||
|
||||
m_intensity->setValueRange(-5.0, 5.0);
|
||||
m_size->setValueRange(10.0, 500.0);
|
||||
m_size->setValueRange(10.0, 1500.0);
|
||||
m_rotation->setValueRange(-1800, 1800);
|
||||
m_aberration->setValueRange(-2.0, 2.0);
|
||||
m_noise_factor->setValueRange(0.0, 1.0);
|
||||
m_noise_size->setValueRange(0.01, 3.0);
|
||||
}
|
||||
|
@ -91,12 +131,149 @@ double Iwa_GlareFx::getSizePixelAmount(const double val, const TAffine affine) {
|
|||
/*--- return the length of the vector ---*/
|
||||
return sqrt(vect.x * vect.x + vect.y * vect.y);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
|
||||
void Iwa_GlareFx::drawPresetIris(TRaster32P irisRas, double irisSize,
|
||||
const double frame) {
|
||||
QImage img(irisRas->getLx(), irisRas->getLy(),
|
||||
QImage::Format_ARGB32_Premultiplied);
|
||||
img.fill(Qt::black);
|
||||
QPainter painter(&img);
|
||||
painter.setRenderHint(QPainter::Antialiasing, true);
|
||||
painter.translate(
|
||||
QPointF((float)irisRas->getLx() / 2.0, (float)irisRas->getLy() / 2.0));
|
||||
painter.scale(irisSize, irisSize);
|
||||
// shrink a bit
|
||||
painter.scale(0.9, 0.9);
|
||||
|
||||
QPen pen(Qt::white);
|
||||
double lineWidthRatio;
|
||||
int appearance = m_irisAppearance->getValue();
|
||||
if (appearance == Appearance_Fill) {
|
||||
painter.setPen(Qt::NoPen);
|
||||
painter.setBrush(Qt::white);
|
||||
} else {
|
||||
assert(appearance >= 0 && appearance <= 2);
|
||||
pen.setCapStyle(Qt::RoundCap);
|
||||
pen.setJoinStyle(Qt::MiterJoin);
|
||||
double ratio[3] = {0.05, 0.1, 0.2};
|
||||
lineWidthRatio = ratio[appearance];
|
||||
pen.setWidthF(lineWidthRatio);
|
||||
painter.setPen(pen);
|
||||
painter.setBrush(Qt::NoBrush);
|
||||
}
|
||||
|
||||
double symmetry = m_irisSymmetry->getValue(frame);
|
||||
|
||||
switch (m_irisMode->getValue()) {
|
||||
case Iris_Square:
|
||||
painter.scale(1.0, symmetry);
|
||||
painter.drawRect(QRectF(-1.0, -1.0, 2.0, 2.0));
|
||||
break;
|
||||
case Iris_Hexagon: {
|
||||
QPointF p(1.0 - 0.5 * symmetry, symmetry * std::sqrt(3) * 0.5);
|
||||
const QPointF points[6] = {-p, QPointF(-1.0, 0.0), QPointF(-p.x(), p.y()),
|
||||
p, QPointF(1.0, 0.0), QPointF(p.x(), -p.y())};
|
||||
if (appearance != Appearance_Fill) {
|
||||
if (symmetry < 1.0) {
|
||||
painter.drawPolyline(points, 3);
|
||||
painter.drawPolyline(&points[3], 3);
|
||||
}
|
||||
pen.setWidthF(lineWidthRatio * symmetry);
|
||||
painter.setPen(pen);
|
||||
}
|
||||
painter.drawPolygon(points, 6);
|
||||
if (appearance != Appearance_Fill && symmetry < 1.0) {
|
||||
pen.setColor(Qt::black);
|
||||
painter.setPen(pen);
|
||||
painter.setBrush(Qt::NoBrush);
|
||||
painter.drawRect(
|
||||
QRectF(-1.2, -p.y() - symmetry, 2.4, (p.y() + symmetry) * 2.0));
|
||||
}
|
||||
} break;
|
||||
case Iris_Octagon: {
|
||||
double u = (2 + std::sqrt(2) * (1 - symmetry)) / (2 * std::sqrt(2) + 2);
|
||||
double v = (2 + std::sqrt(2) * (1 + symmetry)) / (2 * std::sqrt(2) + 2);
|
||||
const QPointF points[8] = {QPointF(u, v), QPointF(v, u), QPointF(v, -u),
|
||||
QPointF(u, -v), QPointF(-u, -v), QPointF(-v, -u),
|
||||
QPointF(-v, u), QPointF(-u, v)};
|
||||
if (appearance != Appearance_Fill) {
|
||||
if (symmetry < 1.0) {
|
||||
painter.drawLine(points[0], points[1]);
|
||||
painter.drawLine(points[2], points[3]);
|
||||
painter.drawLine(points[4], points[5]);
|
||||
painter.drawLine(points[6], points[7]);
|
||||
}
|
||||
pen.setWidthF(lineWidthRatio * symmetry);
|
||||
painter.setPen(pen);
|
||||
}
|
||||
painter.drawPolygon(points, 8);
|
||||
if (appearance != Appearance_Fill && symmetry < 1.0) {
|
||||
pen.setColor(Qt::black);
|
||||
painter.setPen(pen);
|
||||
painter.setBrush(Qt::NoBrush);
|
||||
painter.drawRect(QRectF(-v - symmetry, -v - symmetry,
|
||||
(v + symmetry) * 2.0, (v + symmetry) * 2.0));
|
||||
}
|
||||
} break;
|
||||
case Iris_GearShape: {
|
||||
int edgeCount = (int)std::round(m_irisGearEdgeCount->getValue(frame));
|
||||
QPointF* points = new QPointF[edgeCount * 2];
|
||||
QList<double> thickness;
|
||||
double angleUnit = M_PI / (double)edgeCount;
|
||||
std::mt19937_64 mt;
|
||||
mt.seed(m_irisRandomSeed->getValue());
|
||||
std::uniform_real_distribution<> random_plusminus1(-1.0, 1.0);
|
||||
std::uniform_real_distribution<> random_thickness(symmetry * lineWidthRatio,
|
||||
lineWidthRatio);
|
||||
for (int e = 0; e < edgeCount; e++) {
|
||||
double baseAngle = angleUnit * e * 2.0;
|
||||
double theta =
|
||||
baseAngle + random_plusminus1(mt) * angleUnit * (1.0 - symmetry);
|
||||
points[e * 2] = QPointF(std::cos(theta), std::sin(theta));
|
||||
thickness.append(random_thickness(mt));
|
||||
baseAngle += angleUnit;
|
||||
theta = baseAngle + random_plusminus1(mt) * angleUnit * (1.0 - symmetry);
|
||||
points[e * 2 + 1] = QPointF(0.5 * std::cos(theta), 0.5 * std::sin(theta));
|
||||
thickness.append(random_thickness(mt));
|
||||
}
|
||||
|
||||
if (appearance != Appearance_Fill) {
|
||||
for (int v = 0; v < edgeCount * 2; v++) {
|
||||
int next_v = (v == edgeCount * 2 - 1) ? 0 : v + 1;
|
||||
pen.setWidthF(thickness.at(v));
|
||||
painter.setPen(pen);
|
||||
painter.drawLine(points[v], points[next_v]);
|
||||
}
|
||||
} else {
|
||||
painter.drawPolygon(points, edgeCount * 2);
|
||||
}
|
||||
delete[] points;
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
for (int j = 0; j < img.height(); j++) {
|
||||
TPixel32* pix = irisRas->pixels(j);
|
||||
QRgb* img_p = (QRgb*)img.scanLine(img.height() - j - 1);
|
||||
for (int i = 0; i < img.width(); i++, img_p++, pix++) {
|
||||
pix->r = (unsigned char)(qRed(*img_p));
|
||||
pix->g = (unsigned char)(qGreen(*img_p));
|
||||
pix->b = (unsigned char)(qBlue(*img_p));
|
||||
pix->m = (unsigned char)(qAlpha(*img_p));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------
|
||||
|
||||
void Iwa_GlareFx::doCompute(TTile& tile, double frame,
|
||||
const TRenderSettings& settings) {
|
||||
int irisMode = m_irisMode->getValue();
|
||||
// If the iris is not connected, then do nothing
|
||||
if (!m_iris.isConnected()) {
|
||||
if (irisMode == Iris_InputImage && !m_iris.isConnected()) {
|
||||
tile.getRaster()->clear();
|
||||
return;
|
||||
}
|
||||
|
@ -110,16 +287,35 @@ void Iwa_GlareFx::doCompute(TTile& tile, double frame,
|
|||
|
||||
// Get the original size of Iris image
|
||||
TRectD irisBBox;
|
||||
m_iris->getBBox(frame, irisBBox, settings);
|
||||
// Compute the iris tile.
|
||||
TTile irisTile;
|
||||
m_iris->allocateAndCompute(
|
||||
irisTile, irisBBox.getP00(),
|
||||
TDimension(static_cast<int>(irisBBox.getLx() + 0.5),
|
||||
static_cast<int>(irisBBox.getLy() + 0.5)),
|
||||
tile.getRaster(), frame, settings);
|
||||
|
||||
TRasterP irisRas;
|
||||
double size = getSizePixelAmount(m_size->getValue(frame), settings.m_affine);
|
||||
if (irisMode == Iris_InputImage) {
|
||||
m_iris->getBBox(frame, irisBBox, settings);
|
||||
// Compute the iris tile.
|
||||
m_iris->allocateAndCompute(
|
||||
irisTile, irisBBox.getP00(),
|
||||
TDimension(static_cast<int>(irisBBox.getLx() + 0.5),
|
||||
static_cast<int>(irisBBox.getLy() + 0.5)),
|
||||
tile.getRaster(), frame, settings);
|
||||
irisRas = irisTile.getRaster();
|
||||
} else {
|
||||
// obtain iris bbox based on the glare pattern size
|
||||
double irisSize = size * m_irisScale->getValue(frame);
|
||||
irisBBox = TRectD(-irisSize, -irisSize, irisSize, irisSize);
|
||||
int dimIrisRas = int(std::ceil(irisSize) * 2.0);
|
||||
irisRas = TRaster32P(dimIrisRas, dimIrisRas);
|
||||
drawPresetIris(irisRas, irisSize, frame);
|
||||
}
|
||||
|
||||
if (renderMode == RenderMode_Iris) {
|
||||
TTranslation aff(
|
||||
(double)(tile.getRaster()->getLx() - irisRas->getLx()) * 0.5,
|
||||
(double)(tile.getRaster()->getLy() - irisRas->getLy()) * 0.5);
|
||||
TRop::quickPut(tile.getRaster(), irisRas, aff);
|
||||
return;
|
||||
}
|
||||
|
||||
int dimIris = int(std::ceil(size) * 2.0);
|
||||
dimIris = kiss_fft_next_fast_size(dimIris);
|
||||
while ((tile.getRaster()->getSize().lx - dimIris) % 2 != 0)
|
||||
|
@ -140,7 +336,8 @@ void Iwa_GlareFx::doCompute(TTile& tile, double frame,
|
|||
kissfft_comp_iris_before_ras->lock();
|
||||
kissfft_comp_iris_before =
|
||||
(kiss_fft_cpx*)kissfft_comp_iris_before_ras->getRawData();
|
||||
convertIris(kissfft_comp_iris_before, dimIris, irisBBox, irisTile);
|
||||
|
||||
convertIris(kissfft_comp_iris_before, dimIris, irisBBox, irisRas);
|
||||
|
||||
// Create the FFT plan for the iris image.
|
||||
kiss_fftnd_cfg iris_kissfft_plan;
|
||||
|
@ -349,10 +546,20 @@ void Iwa_GlareFx::powerSpectrum2GlarePattern(
|
|||
glare_xyz_ras->clear();
|
||||
|
||||
double irisRadius = double(dimIris / 2);
|
||||
double aberration = m_aberration->getValue(frame);
|
||||
|
||||
// old version had summed each wavelength constantly.
|
||||
// it was not physically-collect but keep it in order to maintain backward
|
||||
// compatibility.
|
||||
bool isOldVersion = getFxVersion() < 2;
|
||||
|
||||
// accumurate xyz values for each optical wavelength
|
||||
for (int ram = 0; ram < 34; ram++) {
|
||||
double rambda = 0.38 + 0.01 * (double)ram;
|
||||
double scale = 0.55 / rambda;
|
||||
// double scale = 0.55 / rambda;
|
||||
double scale = std::pow(0.55 / rambda, aberration);
|
||||
double intensity_scale =
|
||||
(isOldVersion) ? 1.0 : std::pow(0.55 / rambda, 2.0 * aberration);
|
||||
scale *= irisResizeFactor;
|
||||
for (int j = 0; j < dimIris; j++) {
|
||||
double j_scaled = (double(j) - irisRadius) * scale + irisRadius;
|
||||
|
@ -369,7 +576,8 @@ void Iwa_GlareFx::powerSpectrum2GlarePattern(
|
|||
else if (i_scaled > double(dimIris - 1))
|
||||
break;
|
||||
|
||||
double gl = lerpGlarePtn(i_scaled, j_scaled, glarePattern_p);
|
||||
double gl =
|
||||
lerpGlarePtn(i_scaled, j_scaled, glarePattern_p) * intensity_scale;
|
||||
g_xyz_p->x += gl * cie_d65[ram] * xyz[ram * 3 + 0];
|
||||
g_xyz_p->y += gl * cie_d65[ram] * xyz[ram * 3 + 1];
|
||||
g_xyz_p->z += gl * cie_d65[ram] * xyz[ram * 3 + 2];
|
||||
|
@ -634,7 +842,7 @@ bool Iwa_GlareFx::canHandle(const TRenderSettings& info, double frame) {
|
|||
// Enlarge the iris to the output size.
|
||||
void Iwa_GlareFx::convertIris(kiss_fft_cpx* kissfft_comp_iris_before,
|
||||
const int& dimIris, const TRectD& irisBBox,
|
||||
const TTile& irisTile) {
|
||||
const TRasterP irisRaster) {
|
||||
// the original size of iris image
|
||||
double2 irisOrgSize = {irisBBox.getLx(), irisBBox.getLy()};
|
||||
|
||||
|
@ -655,10 +863,10 @@ void Iwa_GlareFx::convertIris(kiss_fft_cpx* kissfft_comp_iris_before,
|
|||
if (dimIris % 2 == 1) affOffset += TPointD(0.5, 0.5);
|
||||
|
||||
aff = TTranslation(resizedIris->getCenterD() + affOffset);
|
||||
aff *= TTranslation(-(irisTile.getRaster()->getCenterD() + affOffset));
|
||||
aff *= TTranslation(-(irisRaster->getCenterD() + affOffset));
|
||||
|
||||
// resample the iris
|
||||
TRop::resample(resizedIris, irisTile.getRaster(), aff);
|
||||
TRop::resample(resizedIris, irisRaster, aff);
|
||||
|
||||
// accumulated value
|
||||
float irisValAmount = 0.0;
|
||||
|
|
|
@ -35,12 +35,21 @@ class Iwa_GlareFx : public TStandardRasterFx {
|
|||
protected:
|
||||
TRasterFxPort m_source;
|
||||
TRasterFxPort m_iris;
|
||||
// rendering mode (filter preview / render)
|
||||
// rendering mode (filter preview / render / iris)
|
||||
TIntEnumParamP m_renderMode;
|
||||
TIntEnumParamP m_irisMode;
|
||||
|
||||
TDoubleParamP m_irisScale;
|
||||
TDoubleParamP m_irisGearEdgeCount;
|
||||
TIntParamP m_irisRandomSeed;
|
||||
TDoubleParamP m_irisSymmetry;
|
||||
TIntEnumParamP m_irisAppearance;
|
||||
|
||||
TDoubleParamP m_intensity;
|
||||
TDoubleParamP m_size;
|
||||
|
||||
TDoubleParamP m_rotation;
|
||||
TDoubleParamP m_aberration;
|
||||
|
||||
TDoubleParamP m_noise_factor;
|
||||
TDoubleParamP m_noise_size;
|
||||
|
@ -48,15 +57,32 @@ protected:
|
|||
TDoubleParamP m_noise_evolution;
|
||||
TPointParamP m_noise_offset;
|
||||
|
||||
enum { RendeMode_FilterPreview = 0, RendeMode_Render };
|
||||
enum { RendeMode_FilterPreview = 0, RendeMode_Render, RenderMode_Iris };
|
||||
|
||||
enum {
|
||||
Iris_InputImage = 0,
|
||||
Iris_Square,
|
||||
Iris_Hexagon,
|
||||
Iris_Octagon,
|
||||
Iris_GearShape
|
||||
};
|
||||
|
||||
enum {
|
||||
Appearance_ThinLine,
|
||||
Appearance_MediumLine,
|
||||
Appearance_ThickLine,
|
||||
Appearance_Fill,
|
||||
};
|
||||
|
||||
double getSizePixelAmount(const double val, const TAffine affine);
|
||||
|
||||
void drawPresetIris(TRaster32P irisRas, double irisSize, const double frame);
|
||||
|
||||
// Resize / flip the iris image according to the size ratio.
|
||||
// Normalize the brightness of the iris image.
|
||||
// Enlarge the iris to the output size.
|
||||
void convertIris(kiss_fft_cpx *kissfft_comp_iris_before, const int &dimIris,
|
||||
const TRectD &irisBBox, const TTile &irisTile);
|
||||
const TRectD &irisBBox, const TRasterP irisRaster);
|
||||
|
||||
void powerSpectrum2GlarePattern(const double frame, const TAffine affine,
|
||||
kiss_fft_cpx *spectrum, double3 *glare,
|
||||
|
|
|
@ -32,7 +32,7 @@ public:
|
|||
, m_shutterEnd(0.05)
|
||||
, m_traceResolution(4)
|
||||
, m_motionObjectType(new TIntEnumParam(OBJTYPE_OWN, "Own Motion"))
|
||||
, m_motionObjectIndex(0) {
|
||||
, m_motionObjectIndex(1) {
|
||||
m_shutterStart->setValueRange(0.0, 1.0);
|
||||
m_shutterEnd->setValueRange(0.0, 1.0);
|
||||
m_traceResolution->setValueRange(1, 20);
|
||||
|
|
|
@ -13,7 +13,8 @@ TFxAttributes::TFxAttributes()
|
|||
, m_isOpened(false)
|
||||
, m_speed()
|
||||
, m_groupSelector(-1)
|
||||
, m_passiveCacheDataIdx(-1) {}
|
||||
, m_passiveCacheDataIdx(-1)
|
||||
, m_fxVersion(1) {}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -576,8 +576,7 @@ void ControlPointEditorTool::leftButtonDown(const TPointD &pos,
|
|||
if (m_autoSelectDrawing.getValue()) {
|
||||
// Non sono in nessun gadget
|
||||
std::vector<int> columnIndexes;
|
||||
getViewer()->posToColumnIndexes(e.m_pos, columnIndexes,
|
||||
getPixelSize() * 5, false);
|
||||
getViewer()->posToColumnIndexes(e.m_pos, columnIndexes, 5.0, false);
|
||||
getNearestStrokeColumnIndexes(columnIndexes, pos);
|
||||
if (!columnIndexes.empty()) {
|
||||
int currentColumnIndex = app->getCurrentColumn()->getColumnIndex();
|
||||
|
|
|
@ -1059,8 +1059,7 @@ void EditTool::onEditAllLeftButtonDown(TPointD &pos, const TMouseEvent &e) {
|
|||
|
||||
if (selectedDevice < 0 && m_autoSelect.getValue() != L"None") {
|
||||
pos = getMatrix() * pos;
|
||||
int columnIndex =
|
||||
getViewer()->posToColumnIndex(e.m_pos, 5 * getPixelSize(), false);
|
||||
int columnIndex = getViewer()->posToColumnIndex(e.m_pos, 5.0, false);
|
||||
if (columnIndex >= 0) {
|
||||
TStageObjectId id = TStageObjectId::ColumnId(columnIndex);
|
||||
int currentColumnIndex = getColumnIndex();
|
||||
|
|
|
@ -1812,6 +1812,8 @@ void AreaFillTool::onEnter() {
|
|||
// getApplication()->editImage();
|
||||
}
|
||||
|
||||
bool descending(int i, int j) { return (i > j); }
|
||||
|
||||
} // namespace
|
||||
|
||||
//=============================================================================
|
||||
|
@ -2457,14 +2459,30 @@ void FillTool::draw() {
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int FillTool::pick(const TImageP &image, const TPointD &pos) {
|
||||
int FillTool::pick(const TImageP &image, const TPointD &pos, const int frame) {
|
||||
TToonzImageP ti = image;
|
||||
TVectorImageP vi = image;
|
||||
if (!ti && !vi) return 0;
|
||||
|
||||
StylePicker picker(image);
|
||||
double pixelSize2 = getPixelSize() * getPixelSize();
|
||||
return picker.pickStyleId(pos, pixelSize2);
|
||||
double scale2 = 1.0;
|
||||
if (vi) {
|
||||
TAffine aff = getViewer()->getViewMatrix() * getCurrentColumnMatrix(frame);
|
||||
scale2 = aff.det();
|
||||
}
|
||||
TPointD pickPos = pos;
|
||||
// in case that the column is animated in scene-editing mode
|
||||
if (frame > 0) {
|
||||
TPointD dpiScale = getViewer()->getDpiScale();
|
||||
pickPos.x *= dpiScale.x;
|
||||
pickPos.y *= dpiScale.y;
|
||||
TPointD worldPos = getCurrentColumnMatrix() * pickPos;
|
||||
pickPos = getCurrentColumnMatrix(frame).inv() * worldPos;
|
||||
pickPos.x /= dpiScale.x;
|
||||
pickPos.y /= dpiScale.y;
|
||||
}
|
||||
// thin stroke can be picked with 10 pixel range
|
||||
return picker.pickStyleId(pickPos, 10.0, scale2);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -2481,32 +2499,53 @@ int FillTool::pickOnionColor(const TPointD &pos) {
|
|||
if (!sl) return 0;
|
||||
|
||||
std::vector<int> rows;
|
||||
osMask.getAll(sl->guessIndex(fid), rows);
|
||||
// level editing case
|
||||
if (app->getCurrentFrame()->isEditingLevel()) {
|
||||
osMask.getAll(sl->guessIndex(fid), rows);
|
||||
int i, j;
|
||||
for (i = 0; i < (int)rows.size(); i++)
|
||||
if (sl->index2fid(rows[i]) > fid) break;
|
||||
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < (int)rows.size(); i++)
|
||||
if (sl->index2fid(rows[i]) > fid) break;
|
||||
|
||||
int onionStyleId = 0;
|
||||
for (j = i - 1; j >= 0; j--) {
|
||||
TFrameId onionFid = sl->index2fid(rows[j]);
|
||||
if (onionFid != fid &&
|
||||
((onionStyleId =
|
||||
pick(m_level->getFrame(onionFid, ImageManager::none, 1), pos)) >
|
||||
0)) // subsabling must be 1, otherwise onionfill does not work
|
||||
break;
|
||||
}
|
||||
if (onionStyleId == 0)
|
||||
for (j = i; j < (int)rows.size(); j++) {
|
||||
int onionStyleId = 0;
|
||||
for (j = i - 1; j >= 0; j--) {
|
||||
TFrameId onionFid = sl->index2fid(rows[j]);
|
||||
if (onionFid != fid &&
|
||||
((onionStyleId =
|
||||
pick(m_level->getFrame(onionFid, ImageManager::none, 1), pos)) >
|
||||
0)) // subsabling must be 1, otherwise onionfill does not work
|
||||
0)) // subsampling must be 1, otherwise onionfill does not work
|
||||
break;
|
||||
}
|
||||
return onionStyleId;
|
||||
if (onionStyleId == 0)
|
||||
for (j = i; j < (int)rows.size(); j++) {
|
||||
TFrameId onionFid = sl->index2fid(rows[j]);
|
||||
if (onionFid != fid &&
|
||||
((onionStyleId = pick(
|
||||
m_level->getFrame(onionFid, ImageManager::none, 1), pos)) >
|
||||
0)) // subsampling must be 1, otherwise onionfill does not work
|
||||
break;
|
||||
}
|
||||
return onionStyleId;
|
||||
} else { // scene editing case
|
||||
TXsheet *xsh = app->getCurrentXsheet()->getXsheet();
|
||||
int colId = app->getCurrentColumn()->getColumnIndex();
|
||||
int row = app->getCurrentFrame()->getFrame();
|
||||
osMask.getAll(row, rows);
|
||||
std::vector<int>::iterator it = rows.begin();
|
||||
while (it != rows.end() && *it < row) it++;
|
||||
std::sort(rows.begin(), it, descending);
|
||||
int onionStyleId = 0;
|
||||
for (int i = 0; i < (int)rows.size(); i++) {
|
||||
if (rows[i] == row) continue;
|
||||
TXshCell cell = xsh->getCell(rows[i], colId);
|
||||
TXshLevel *xl = cell.m_level.getPointer();
|
||||
if (!xl || xl->getSimpleLevel() != sl) continue;
|
||||
TFrameId onionFid = cell.getFrameId();
|
||||
onionStyleId = pick(m_level->getFrame(onionFid, ImageManager::none, 1),
|
||||
pos, rows[i]);
|
||||
if (onionStyleId > 0) break;
|
||||
}
|
||||
return onionStyleId;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
@ -76,7 +76,7 @@ public:
|
|||
void onActivate();
|
||||
void onEnter();
|
||||
};
|
||||
}
|
||||
} // namespace
|
||||
class FillTool final : public QObject, public TTool {
|
||||
// Q_DECLARE_TR_FUNCTIONS(FillTool)
|
||||
Q_OBJECT
|
||||
|
@ -135,7 +135,8 @@ public:
|
|||
void onImageChanged() override;
|
||||
void draw() override;
|
||||
|
||||
int pick(const TImageP &image, const TPointD &pos);
|
||||
// if frame = -1 it uses current frame
|
||||
int pick(const TImageP &image, const TPointD &pos, const int frame = -1);
|
||||
int pickOnionColor(const TPointD &pos);
|
||||
|
||||
void onEnter() override;
|
||||
|
|
|
@ -450,8 +450,7 @@ void ShiftTraceTool::leftButtonDown(const TPointD &pos, const TMouseEvent &e) {
|
|||
m_gadget = RotateGadget;
|
||||
}
|
||||
|
||||
int row = getViewer()->posToRow(e.m_pos, getPixelSize() * getPixelSize(),
|
||||
false, true);
|
||||
int row = getViewer()->posToRow(e.m_pos, 5.0, false, true);
|
||||
if (row >= 0) {
|
||||
int index = -1;
|
||||
TApplication *app = TTool::getApplication();
|
||||
|
|
|
@ -180,7 +180,7 @@ DragPositionTool::DragPositionTool(SkeletonTool *tool)
|
|||
|
||||
void DragPositionTool::leftButtonDown(const TPointD &pos, const TMouseEvent &) {
|
||||
start();
|
||||
m_firstPos = pos;
|
||||
m_firstPos = pos;
|
||||
m_firstDrag = true;
|
||||
}
|
||||
|
||||
|
@ -190,9 +190,9 @@ void DragPositionTool::leftButtonDrag(const TPointD &pos,
|
|||
const TMouseEvent &e) {
|
||||
TPointD delta = pos - m_firstPos;
|
||||
if (m_firstDrag && (delta.x > 2.0 || delta.y > 2.0)) {
|
||||
m_firstPos = pos;
|
||||
delta = TPointD(0.0, 0.0);
|
||||
m_firstDrag = false;
|
||||
m_firstPos = pos;
|
||||
delta = TPointD(0.0, 0.0);
|
||||
m_firstDrag = false;
|
||||
}
|
||||
if (e.isShiftPressed()) {
|
||||
if (fabs(delta.x) > fabs(delta.y))
|
||||
|
@ -300,10 +300,10 @@ void ParentChangeTool::leftButtonDown(const TPointD &pos,
|
|||
// registro alcune informazioni relative a colId:
|
||||
// placement, bbox, centro, hooks, name, ecc.
|
||||
Element element;
|
||||
element.m_columnIndex = col;
|
||||
TImageP img = cell.getImage(false);
|
||||
element.m_columnIndex = col;
|
||||
TImageP img = cell.getImage(false);
|
||||
if (img) element.m_bbox = img->getBBox();
|
||||
element.m_aff = xsh->getPlacement(colId, currentFrame);
|
||||
element.m_aff = xsh->getPlacement(colId, currentFrame);
|
||||
Peer peer;
|
||||
peer.m_columnIndex = col;
|
||||
peer.m_handle = 0;
|
||||
|
@ -352,7 +352,7 @@ void ParentChangeTool::leftButtonDrag(const TPointD &pos,
|
|||
if (m_snapped) return;
|
||||
getTool()->setParentProbe(getTool()->getCurrentColumnParentMatrix() * pos);
|
||||
|
||||
m_index = m_viewer->posToColumnIndex(e.m_pos, m_pixelSize * 5, false);
|
||||
m_index = m_viewer->posToColumnIndex(e.m_pos, 5.0, false);
|
||||
|
||||
m_lastPos = m_viewer->winToWorld(e.m_pos);
|
||||
|
||||
|
@ -425,16 +425,13 @@ void ParentChangeTool::draw() { getTool()->drawHooks(); }
|
|||
//
|
||||
//------------------------------------------------------------
|
||||
|
||||
|
||||
// This needs some clarification.
|
||||
namespace {
|
||||
class Graph {
|
||||
|
||||
// local variables defined below are:
|
||||
// Nodes m_nodes;
|
||||
// std::map<int, int> m_leaves;
|
||||
|
||||
|
||||
public:
|
||||
typedef std::set<int> Links;
|
||||
typedef Links::const_iterator LinkIter;
|
||||
|
@ -455,7 +452,7 @@ public:
|
|||
|
||||
// check if a node is found in m_nodes
|
||||
bool isNode(int id) const { return m_nodes.count(id) > 0; }
|
||||
|
||||
|
||||
int getNodeCount() const { return (int)m_nodes.size(); }
|
||||
|
||||
void link(int a, int b) {
|
||||
|
@ -468,7 +465,7 @@ public:
|
|||
NodeIter it = m_nodes.find(a);
|
||||
return it == m_nodes.end() ? false : it->second.count(b);
|
||||
}
|
||||
|
||||
|
||||
const Links &getLinks(int id) const {
|
||||
static const Links empty;
|
||||
NodeIter it = m_nodes.find(id);
|
||||
|
@ -501,7 +498,7 @@ public:
|
|||
LeaveIter it = m_leaves.find(id);
|
||||
return it == m_leaves.end() ? 0 : it->second;
|
||||
}
|
||||
|
||||
|
||||
void setLeaveType(int id, int type) { m_leaves[id] = type; }
|
||||
|
||||
|
||||
|
@ -509,7 +506,7 @@ public:
|
|||
void remove(int id) {
|
||||
NodeIter it = m_nodes.find(id);
|
||||
if (it != m_nodes.end()) {
|
||||
// iterate over the links
|
||||
// iterate over the links
|
||||
for (LinkIter j = it->second.begin(); j != it->second.end(); ++j)
|
||||
m_nodes[*j].erase(id);
|
||||
m_nodes.erase(it->first);
|
||||
|
@ -536,15 +533,15 @@ bool hasPinned(const Skeleton::Bone *bone, const Skeleton::Bone *prevBone) {
|
|||
|
||||
if (bone->getParent() && bone->getParent() != prevBone &&
|
||||
hasPinned(bone->getParent(), bone)) {
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < bone->getChildCount(); i++) {
|
||||
if (bone->getChild(i) != prevBone) {
|
||||
if (hasPinned(bone->getChild(i), bone)) {
|
||||
return true;
|
||||
}
|
||||
if (bone->getChild(i) != prevBone) {
|
||||
if (hasPinned(bone->getChild(i), bone)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -556,9 +553,9 @@ bool hasPinned(const Skeleton::Bone *bone, const Skeleton::Bone *prevBone) {
|
|||
bool addToActiveChain(Graph &tree, const Skeleton::Bone *bone,
|
||||
const Skeleton::Bone *prevBone) {
|
||||
if (!bone) return false;
|
||||
|
||||
|
||||
// The handle is what you grabbed
|
||||
bool isHandle = prevBone == 0;
|
||||
bool isHandle = prevBone == 0;
|
||||
|
||||
bool isChild = prevBone != 0 && prevBone == bone->getParent();
|
||||
bool isParent = prevBone != 0 && prevBone->getParent() == bone;
|
||||
|
@ -571,19 +568,19 @@ bool addToActiveChain(Graph &tree, const Skeleton::Bone *bone,
|
|||
|
||||
// Go up the chain from what you grabbed and add bones
|
||||
if (!isChild && isFree) {
|
||||
if (bone->getParent()) {
|
||||
propagate |= addToActiveChain(tree, bone->getParent(), bone);
|
||||
}
|
||||
if (bone->getParent()) {
|
||||
propagate |= addToActiveChain(tree, bone->getParent(), bone);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<int> children;
|
||||
// Once you reach the top parent, add the other children
|
||||
if (isHandle || isFree) {
|
||||
for (int i = 0; i < bone->getChildCount(); i++) {
|
||||
if (bone->getChild(i) != prevBone) {
|
||||
propagate |= addToActiveChain(tree, bone->getChild(i), bone);
|
||||
}
|
||||
for (int i = 0; i < bone->getChildCount(); i++) {
|
||||
if (bone->getChild(i) != prevBone) {
|
||||
propagate |= addToActiveChain(tree, bone->getChild(i), bone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool insert = false;
|
||||
|
@ -856,8 +853,9 @@ void IKTool::initEngine(const TPointD &pos) {
|
|||
Skeleton::Bone *next = m_skeleton->getBoneByColumnIndex(*it++);
|
||||
for (; it != links.end(); ++it)
|
||||
stack.push_back(std::make_pair(*it, prev));
|
||||
if (links.size() > 1 || (prev && next && (prev->getParent() == bone &&
|
||||
next->getParent() == bone))) {
|
||||
if (links.size() > 1 ||
|
||||
(prev && next &&
|
||||
(prev->getParent() == bone && next->getParent() == bone))) {
|
||||
bone = next;
|
||||
} else {
|
||||
m_joints.push_back(Joint(bone, prev, sign));
|
||||
|
@ -918,11 +916,12 @@ void IKTool::computeIHateIK() {
|
|||
int n = (int)objs.size();
|
||||
int frame = TTool::getApplication()->getCurrentFrame()->getFrame();
|
||||
m_foot = m_firstFoot = 0;
|
||||
m_frameOnNewPin = false;
|
||||
m_frameOnNewPin = false;
|
||||
|
||||
// this just finds the first pin
|
||||
int i;
|
||||
for (i = 0; i < n && !objs[i]->getPinnedRangeSet()->isPinned(frame); i++) {}
|
||||
for (i = 0; i < n && !objs[i]->getPinnedRangeSet()->isPinned(frame); i++) {
|
||||
}
|
||||
if (i == n) return;
|
||||
|
||||
// this makes m_foot to be the current pin
|
||||
|
@ -940,7 +939,8 @@ void IKTool::computeIHateIK() {
|
|||
// the frame is the start of a new pinned frame, find the previous pin
|
||||
for (;;) {
|
||||
for (i = 0; i < n && !objs[i]->getPinnedRangeSet()->isPinned(firstFrame);
|
||||
i++) {}
|
||||
i++) {
|
||||
}
|
||||
|
||||
if (i == n) break;
|
||||
m_firstFoot = objs[i];
|
||||
|
|
|
@ -383,8 +383,7 @@ void SkeletonTool::leftButtonDown(const TPointD &ppos, const TMouseEvent &e) {
|
|||
if (m_device < 0) {
|
||||
// No gadget clicked. Select the column
|
||||
std::vector<int> columnIndexes;
|
||||
getViewer()->posToColumnIndexes(e.m_pos, columnIndexes, getPixelSize() * getPixelSize(),
|
||||
false);
|
||||
getViewer()->posToColumnIndexes(e.m_pos, columnIndexes, 5.0, false);
|
||||
if (!columnIndexes.empty()) {
|
||||
int columnIndex;
|
||||
columnIndex = columnIndexes.back();
|
||||
|
@ -1056,8 +1055,7 @@ void SkeletonTool::drawHooks() {
|
|||
// otherColumn = "picked" column not connected
|
||||
TPointD parentProbePos = getViewer()->worldToPos(m_parentProbe);
|
||||
std::vector<int> indexes;
|
||||
getViewer()->posToColumnIndexes(parentProbePos, indexes,
|
||||
getPixelSize() * 10, false);
|
||||
getViewer()->posToColumnIndexes(parentProbePos, indexes, 10.0, false);
|
||||
for (int i = (int)indexes.size() - 1; i >= 0; i--) {
|
||||
if (connectedColumns.count(indexes[i]) == 0) {
|
||||
otherColumn = indexes[i];
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "toonz/dpiscale.h"
|
||||
#include "tpixelutils.h"
|
||||
#include "tregion.h"
|
||||
#include "toonzqt/gutil.h"
|
||||
|
||||
#include <QRect>
|
||||
|
||||
|
@ -44,7 +45,7 @@ TPoint StylePicker::getRasterPoint(const TPointD &p) const {
|
|||
//---------------------------------------------------------
|
||||
/*-- (StylePickerTool内で)LineとAreaを切り替えてPickできる。mode: 0=Area,
|
||||
* 1=Line, 2=Line&Areas(default) --*/
|
||||
int StylePicker::pickStyleId(const TPointD &pos, double radius2,
|
||||
int StylePicker::pickStyleId(const TPointD &pos, double radius, double scale2,
|
||||
int mode) const {
|
||||
int styleId = 0;
|
||||
if (TToonzImageP ti = m_image) {
|
||||
|
@ -78,11 +79,6 @@ int StylePicker::pickStyleId(const TPointD &pos, double radius2,
|
|||
// prima cerca lo stile della regione piu' vicina
|
||||
TRegion *r = vi->getRegion(pos);
|
||||
if (r) styleId = r->getStyle();
|
||||
// poi cerca quello della stroke, ma se prima aveva trovato una regione,
|
||||
// richiede che
|
||||
// il click sia proprio sopra la stroke, altrimenti cerca la stroke piu'
|
||||
// vicina (max circa 10 pixel)
|
||||
const double maxDist2 = (styleId == 0) ? 100.0 * radius2 : 0;
|
||||
bool strokeFound;
|
||||
double dist2, w, thick;
|
||||
UINT index;
|
||||
|
@ -90,9 +86,16 @@ int StylePicker::pickStyleId(const TPointD &pos, double radius2,
|
|||
// la thickness, cioe' la min distance dalla outline e non dalla centerLine
|
||||
strokeFound = vi->getNearestStroke(pos, w, index, dist2);
|
||||
if (strokeFound) {
|
||||
int devPixRatio = getDevPixRatio();
|
||||
dist2 *= scale2;
|
||||
TStroke *stroke = vi->getStroke(index);
|
||||
thick = stroke->getThickPoint(w).thick;
|
||||
if (dist2 - thick * thick < maxDist2) {
|
||||
double len2 = thick * thick * scale2;
|
||||
const double minDist2 =
|
||||
(styleId == 0) ? radius * radius * (double)(devPixRatio * devPixRatio)
|
||||
: 0;
|
||||
double checkDist = std::max(minDist2, len2);
|
||||
if (dist2 < checkDist) {
|
||||
assert(stroke);
|
||||
styleId = stroke->getStyle();
|
||||
}
|
||||
|
@ -118,7 +121,8 @@ int StylePicker::pickTone(const TPointD &pos) const {
|
|||
|
||||
//---------------------------------------------------------
|
||||
|
||||
TPixel32 StylePicker::pickColor(const TPointD &pos, double radius2) const {
|
||||
TPixel32 StylePicker::pickColor(const TPointD &pos, double radius,
|
||||
double scale2) const {
|
||||
TToonzImageP ti = m_image;
|
||||
TRasterImageP ri = m_image;
|
||||
TVectorImageP vi = m_image;
|
||||
|
@ -141,14 +145,14 @@ TPixel32 StylePicker::pickColor(const TPointD &pos, double radius2) const {
|
|||
} else if (vi) {
|
||||
const TPalette *palette = m_palette.getPointer();
|
||||
if (!palette) return TPixel32::Transparent;
|
||||
int styleId = pickStyleId(pos, radius2);
|
||||
int styleId = pickStyleId(pos, radius, scale2);
|
||||
if (0 <= styleId && styleId < palette->getStyleCount())
|
||||
return palette->getStyle(styleId)->getAverageColor();
|
||||
} else if (ti) {
|
||||
const TPalette *palette = m_palette.getPointer();
|
||||
if (!palette) return TPixel32::Transparent;
|
||||
int paintId = pickStyleId(pos, radius2, 0);
|
||||
int inkId = pickStyleId(pos, radius2, 1);
|
||||
int paintId = pickStyleId(pos, radius, scale2, 0);
|
||||
int inkId = pickStyleId(pos, radius, scale2, 1);
|
||||
int tone = pickTone(pos);
|
||||
TPixel32 ink, paint;
|
||||
if (0 <= inkId && inkId < palette->getStyleCount())
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
// TnzQt includes
|
||||
#include "toonzqt/tselectionhandle.h"
|
||||
#include "toonzqt/styleselection.h"
|
||||
#include "toonzqt/gutil.h"
|
||||
|
||||
// TnzLib includes
|
||||
#include "toonz/txshsimplelevel.h"
|
||||
|
@ -86,13 +87,13 @@ void StylePickerTool::pick(const TPointD &pos, const TMouseEvent &e,
|
|||
---*/
|
||||
if (Preferences::instance()->isMultiLayerStylePickerEnabled() &&
|
||||
getApplication()->getCurrentFrame()->isEditingScene()) {
|
||||
int superPickedColumnId = getViewer()->posToColumnIndex(
|
||||
e.m_pos, getPixelSize() * getPixelSize(), false);
|
||||
double pickRange = 10.0;
|
||||
int superPickedColumnId =
|
||||
getViewer()->posToColumnIndex(e.m_pos, pickRange, false);
|
||||
|
||||
if (superPickedColumnId >= 0 /*-- 何かColumnに当たった場合 --*/
|
||||
&&
|
||||
getApplication()->getCurrentColumn()->getColumnIndex() !=
|
||||
superPickedColumnId) /*-- かつ、Current Columnでない場合 --*/
|
||||
&& getApplication()->getCurrentColumn()->getColumnIndex() !=
|
||||
superPickedColumnId) /*-- かつ、Current Columnでない場合 --*/
|
||||
{
|
||||
/*-- そのColumnからPickを試みる --*/
|
||||
int currentFrame = getApplication()->getCurrentFrame()->getFrame();
|
||||
|
@ -112,13 +113,16 @@ void StylePickerTool::pick(const TPointD &pos, const TMouseEvent &e,
|
|||
tmpMousePosition.x /= tmpDpiScale.x;
|
||||
tmpMousePosition.y /= tmpDpiScale.y;
|
||||
|
||||
TAffine aff =
|
||||
getViewer()->getViewMatrix() * getColumnMatrix(superPickedColumnId);
|
||||
double scale2 = aff.det();
|
||||
StylePicker superPicker(pickedImage);
|
||||
int picked_subsampling =
|
||||
picked_level->getImageSubsampling(pickedCell.getFrameId());
|
||||
int superPicked_StyleId = superPicker.pickStyleId(
|
||||
TScale(1.0 / picked_subsampling) * tmpMousePosition +
|
||||
TPointD(-0.5, -0.5),
|
||||
getPixelSize() * getPixelSize(), modeValue);
|
||||
pickRange, scale2, modeValue);
|
||||
/*-- 何かStyleが拾えて、Transparentでない場合 --*/
|
||||
if (superPicked_StyleId > 0) {
|
||||
/*-- Levelの移動 --*/
|
||||
|
@ -152,25 +156,26 @@ void StylePickerTool::pick(const TPointD &pos, const TMouseEvent &e,
|
|||
/*-- 画面外をpickしても拾えないようにする --*/
|
||||
if (!m_viewer->getGeometry().contains(pos)) return;
|
||||
|
||||
TAffine aff = getViewer()->getViewMatrix() * getCurrentColumnMatrix();
|
||||
double scale2 = aff.det();
|
||||
int subsampling = level->getImageSubsampling(getCurrentFid());
|
||||
StylePicker picker(image);
|
||||
int styleId =
|
||||
picker.pickStyleId(TScale(1.0 / subsampling) * pos + TPointD(-0.5, -0.5),
|
||||
getPixelSize() * getPixelSize(), modeValue);
|
||||
10.0, scale2, modeValue);
|
||||
|
||||
if (styleId < 0) return;
|
||||
|
||||
if (modeValue == 1) // LINES
|
||||
{
|
||||
/*-- pickLineモードのとき、取得Styleが0の場合はカレントStyleを変えない。
|
||||
* --*/
|
||||
* --*/
|
||||
if (styleId == 0) return;
|
||||
/*--
|
||||
* pickLineモードのとき、PurePaintの部分をクリックしてもカレントStyleを変えない
|
||||
* --*/
|
||||
if (ti &&
|
||||
picker.pickTone(TScale(1.0 / subsampling) * pos +
|
||||
TPointD(-0.5, -0.5)) == 255)
|
||||
* pickLineモードのとき、PurePaintの部分をクリックしてもカレントStyleを変えない
|
||||
* --*/
|
||||
if (ti && picker.pickTone(TScale(1.0 / subsampling) * pos +
|
||||
TPointD(-0.5, -0.5)) == 255)
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -207,13 +212,13 @@ void StylePickerTool::mouseMove(const TPointD &pos, const TMouseEvent &e) {
|
|||
return;
|
||||
}
|
||||
|
||||
TAffine aff = getViewer()->getViewMatrix() * getCurrentColumnMatrix();
|
||||
double scale2 = aff.det();
|
||||
int subsampling = level->getImageSubsampling(getCurrentFid());
|
||||
StylePicker picker(image);
|
||||
TPointD pickPos(TScale(1.0 / subsampling) * pos + TPointD(-0.5, -0.5));
|
||||
int inkStyleId =
|
||||
picker.pickStyleId(pickPos, getPixelSize() * getPixelSize(), 1);
|
||||
int paintStyleId =
|
||||
picker.pickStyleId(pickPos, getPixelSize() * getPixelSize(), 0);
|
||||
int inkStyleId = picker.pickStyleId(pickPos, 10.0, scale2, 1);
|
||||
int paintStyleId = picker.pickStyleId(pickPos, 10.0, scale2, 0);
|
||||
int tone = picker.pickTone(pickPos);
|
||||
controller->notifyStylePassivePicked(inkStyleId, paintStyleId, tone);
|
||||
}
|
||||
|
|
|
@ -721,8 +721,9 @@ TFrameId TTool::getCurrentFid() const {
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
TAffine TTool::getCurrentColumnMatrix() const {
|
||||
return getColumnMatrix(m_application->getCurrentColumn()->getColumnIndex());
|
||||
TAffine TTool::getCurrentColumnMatrix(int frame) const {
|
||||
return getColumnMatrix(m_application->getCurrentColumn()->getColumnIndex(),
|
||||
frame);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -759,12 +760,12 @@ TAffine TTool::getCurrentObjectParentMatrix() const {
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
TAffine TTool::getColumnMatrix(int columnIndex) const {
|
||||
TAffine TTool::getColumnMatrix(int columnIndex, int frame) const {
|
||||
if (!m_application) return TAffine();
|
||||
|
||||
TFrameHandle *fh = m_application->getCurrentFrame();
|
||||
if (fh->isEditingLevel()) return TAffine();
|
||||
int frame = fh->getFrame();
|
||||
if (frame < 0) frame = fh->getFrame();
|
||||
TXsheet *xsh = m_application->getCurrentXsheet()->getXsheet();
|
||||
TStageObjectId columnObjId =
|
||||
(columnIndex >= 0)
|
||||
|
|
|
@ -120,6 +120,7 @@ set(MOC_HEADERS
|
|||
xshrowviewer.h
|
||||
quicktoolbar.h
|
||||
xdtsimportpopup.h
|
||||
expressionreferencemanager.h
|
||||
motionpathpanel.h
|
||||
graphwidget.h
|
||||
../stopmotion/stopmotion.h
|
||||
|
@ -345,6 +346,7 @@ set(SOURCES
|
|||
separatecolorspopup.cpp
|
||||
xdtsio.cpp
|
||||
xdtsimportpopup.cpp
|
||||
expressionreferencemanager.cpp
|
||||
# Tracker file
|
||||
dummyprocessor.cpp
|
||||
metnum.cpp
|
||||
|
|
|
@ -224,11 +224,12 @@ void CameraSettingsPopup::updateWindowTitle() {
|
|||
void CameraSettingsPopup::onChanged() {
|
||||
TCamera *camera = getCamera();
|
||||
if (!camera) return;
|
||||
m_cameraSettingsWidget->getFields(camera);
|
||||
TApp::instance()->getCurrentScene()->notifySceneChanged();
|
||||
TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
|
||||
if (m_cameraSettingsWidget->getFields(camera)) {
|
||||
TApp::instance()->getCurrentScene()->notifySceneChanged();
|
||||
TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
|
||||
|
||||
emit changed();
|
||||
emit changed();
|
||||
}
|
||||
}
|
||||
|
||||
void CameraSettingsPopup::onNameChanged() {
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "menubarcommandids.h"
|
||||
#include "columnselection.h"
|
||||
#include "tapp.h"
|
||||
#include "expressionreferencemanager.h"
|
||||
|
||||
// TnzQt includes
|
||||
#include "toonzqt/tselectionhandle.h"
|
||||
|
@ -37,6 +38,7 @@
|
|||
#include "toonz/tstageobjectspline.h"
|
||||
#include "toonz/fxcommand.h"
|
||||
#include "toonz/preferences.h"
|
||||
#include "toonz/tstageobjectid.h"
|
||||
|
||||
// TnzBase includes
|
||||
#include "tfx.h"
|
||||
|
@ -51,6 +53,7 @@
|
|||
// Qt includes
|
||||
#include <QApplication>
|
||||
#include <QClipboard>
|
||||
#include <QSet>
|
||||
|
||||
#include <memory>
|
||||
|
||||
|
@ -773,8 +776,9 @@ static void copyColumns_internal(const std::set<int> &indices) {
|
|||
|
||||
TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet();
|
||||
|
||||
data->storeColumns(indices, xsh, StageObjectsData::eDoClone |
|
||||
StageObjectsData::eResetFxDagPositions);
|
||||
data->storeColumns(
|
||||
indices, xsh,
|
||||
StageObjectsData::eDoClone | StageObjectsData::eResetFxDagPositions);
|
||||
data->storeColumnFxs(
|
||||
indices, xsh,
|
||||
StageObjectsData::eDoClone | StageObjectsData::eResetFxDagPositions);
|
||||
|
@ -962,8 +966,8 @@ void ColumnCmd::resequence(int index) {
|
|||
assert(!cell.isEmpty());
|
||||
TXshChildLevel *xl = cell.m_level->getChildLevel();
|
||||
assert(xl);
|
||||
TXsheet *childXsh = xl->getXsheet();
|
||||
int frameCount = childXsh->getFrameCount();
|
||||
TXsheet *childXsh = xl->getXsheet();
|
||||
int frameCount = childXsh->getFrameCount();
|
||||
if (frameCount < 1) frameCount = 1;
|
||||
|
||||
TUndoManager::manager()->add(new ResequenceUndo(index, frameCount));
|
||||
|
@ -1001,7 +1005,7 @@ public:
|
|||
void redo() const override {
|
||||
TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet();
|
||||
xsh->insertColumn(m_columnIndex);
|
||||
int frameCount = m_childLevel->getXsheet()->getFrameCount();
|
||||
int frameCount = m_childLevel->getXsheet()->getFrameCount();
|
||||
if (frameCount < 1) frameCount = 1;
|
||||
for (int r = 0; r < frameCount; r++)
|
||||
xsh->setCell(r, m_columnIndex,
|
||||
|
@ -1196,6 +1200,160 @@ void ColumnCmd::clearCells(int index) {
|
|||
TApp::instance()->getCurrentScene()->setDirtyFlag(true);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// checkExpressionReferences
|
||||
//=============================================================================
|
||||
// - If onlyColumns is true, it means that only columns with specified indices
|
||||
// will be removed.
|
||||
// - If onlyColumns is false, it means that the relevant pegbars will be removed
|
||||
// as well (when collapsing collumns).
|
||||
// - Note that relevant Fxs will be removed / collapsed regardless of
|
||||
// onlyColumns.
|
||||
// - When checkInvert is true, check references both side from the main xsheet
|
||||
// and the child xsheet when collapsing columns.
|
||||
|
||||
bool ColumnCmd::checkExpressionReferences(const std::set<int> &indices,
|
||||
bool onlyColumns, bool checkInvert) {
|
||||
if (!Preferences::instance()->isModifyExpressionOnMovingReferencesEnabled())
|
||||
return true;
|
||||
|
||||
TApp *app = TApp::instance();
|
||||
TXsheet *xsh = app->getCurrentXsheet()->getXsheet();
|
||||
|
||||
// check if fxs will be deleted
|
||||
QSet<int> colIdsToBeDeleted;
|
||||
QSet<TFx *> fxsToBeDeleted;
|
||||
// store column fxs to be deleted
|
||||
std::set<TFx *> leaves;
|
||||
for (auto index : indices) {
|
||||
if (index < 0) continue;
|
||||
TXshColumn *column = xsh->getColumn(index);
|
||||
if (!column) continue;
|
||||
colIdsToBeDeleted.insert(index);
|
||||
TFx *fx = column->getFx();
|
||||
if (fx) {
|
||||
leaves.insert(fx);
|
||||
TZeraryColumnFx *zcfx = dynamic_cast<TZeraryColumnFx *>(fx);
|
||||
if (zcfx) fxsToBeDeleted.insert(zcfx->getZeraryFx());
|
||||
}
|
||||
}
|
||||
|
||||
// store relevant fxs which will be deleted along with the columns
|
||||
TFxSet *fxSet = xsh->getFxDag()->getInternalFxs();
|
||||
for (int i = 0; i < fxSet->getFxCount(); i++) {
|
||||
TFx *fx = fxSet->getFx(i);
|
||||
if (canRemoveFx(leaves, fx)) fxsToBeDeleted.insert(fx);
|
||||
}
|
||||
|
||||
// store object ids which will be duplicated in the child xsheet on collapse
|
||||
QList<TStageObjectId> objIdsToBeDuplicated;
|
||||
if (checkInvert && !onlyColumns) {
|
||||
for (auto index : indices) {
|
||||
TStageObjectId id =
|
||||
xsh->getStageObjectParent(TStageObjectId::ColumnId(index));
|
||||
// store pegbars/cameras connected to the columns
|
||||
while (id.isPegbar() || id.isCamera()) {
|
||||
if (!objIdsToBeDuplicated.contains(id)) objIdsToBeDuplicated.append(id);
|
||||
id = xsh->getStageObjectParent(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ExpressionReferenceManager::instance()->checkReferenceDeletion(
|
||||
colIdsToBeDeleted, fxsToBeDeleted, objIdsToBeDuplicated, checkInvert);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool ColumnCmd::checkExpressionReferences(const std::set<int> &indices,
|
||||
const std::set<TFx *> &fxs,
|
||||
bool onlyColumns, bool checkInvert) {
|
||||
if (!Preferences::instance()->isModifyExpressionOnMovingReferencesEnabled())
|
||||
return true;
|
||||
|
||||
TApp *app = TApp::instance();
|
||||
TXsheet *xsh = app->getCurrentXsheet()->getXsheet();
|
||||
|
||||
// check if fxs will be deleted
|
||||
QSet<int> colIdsToBeDeleted;
|
||||
QSet<TFx *> fxsToBeDeleted;
|
||||
for (auto index : indices) {
|
||||
if (index < 0) continue;
|
||||
TXshColumn *column = xsh->getColumn(index);
|
||||
if (!column) continue;
|
||||
colIdsToBeDeleted.insert(index);
|
||||
TFx *fx = column->getFx();
|
||||
if (fx) {
|
||||
TZeraryColumnFx *zcfx = dynamic_cast<TZeraryColumnFx *>(fx);
|
||||
if (zcfx) fxsToBeDeleted.insert(zcfx->getZeraryFx());
|
||||
}
|
||||
}
|
||||
|
||||
TFxSet *fxSet = xsh->getFxDag()->getInternalFxs();
|
||||
for (auto fx : fxs) fxsToBeDeleted.insert(fx);
|
||||
|
||||
// store object ids which will be duplicated in the child xsheet on collapse
|
||||
QList<TStageObjectId> objIdsToBeDuplicated;
|
||||
if (checkInvert && !onlyColumns) {
|
||||
for (auto index : indices) {
|
||||
TStageObjectId id =
|
||||
xsh->getStageObjectParent(TStageObjectId::ColumnId(index));
|
||||
// store pegbars/cameras connected to the columns
|
||||
while (id.isPegbar() || id.isCamera()) {
|
||||
if (!objIdsToBeDuplicated.contains(id)) objIdsToBeDuplicated.append(id);
|
||||
id = xsh->getStageObjectParent(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ExpressionReferenceManager::instance()->checkReferenceDeletion(
|
||||
colIdsToBeDeleted, fxsToBeDeleted, objIdsToBeDuplicated, checkInvert);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool ColumnCmd::checkExpressionReferences(
|
||||
const QList<TStageObjectId> &objects) {
|
||||
if (!Preferences::instance()->isModifyExpressionOnMovingReferencesEnabled())
|
||||
return true;
|
||||
|
||||
TApp *app = TApp::instance();
|
||||
TXsheet *xsh = app->getCurrentXsheet()->getXsheet();
|
||||
|
||||
QSet<int> colIdsToBeDeleted;
|
||||
QSet<TFx *> fxsToBeDeleted;
|
||||
QList<TStageObjectId> objIdsToBeDuplicated;
|
||||
|
||||
// store column fxs to be deleted
|
||||
std::set<TFx *> leaves;
|
||||
for (auto objId : objects) {
|
||||
if (objId.isColumn()) {
|
||||
int index = objId.getIndex();
|
||||
if (index < 0) continue;
|
||||
TXshColumn *column = xsh->getColumn(index);
|
||||
if (!column) continue;
|
||||
colIdsToBeDeleted.insert(index);
|
||||
TFx *fx = column->getFx();
|
||||
if (fx) {
|
||||
leaves.insert(fx);
|
||||
TZeraryColumnFx *zcfx = dynamic_cast<TZeraryColumnFx *>(fx);
|
||||
if (zcfx) fxsToBeDeleted.insert(zcfx->getZeraryFx());
|
||||
}
|
||||
} else
|
||||
objIdsToBeDuplicated.append(objId);
|
||||
}
|
||||
|
||||
// store relevant fxs which will be deleted along with the columns
|
||||
TFxSet *fxSet = xsh->getFxDag()->getInternalFxs();
|
||||
for (int i = 0; i < fxSet->getFxCount(); i++) {
|
||||
TFx *fx = fxSet->getFx(i);
|
||||
if (canRemoveFx(leaves, fx)) fxsToBeDeleted.insert(fx);
|
||||
}
|
||||
|
||||
return ExpressionReferenceManager::instance()->checkReferenceDeletion(
|
||||
colIdsToBeDeleted, fxsToBeDeleted, objIdsToBeDuplicated, true);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
namespace {
|
||||
|
@ -1294,7 +1452,7 @@ public:
|
|||
else
|
||||
column->setCamstandVisible(!column->isCamstandVisible());
|
||||
if (column->getSoundColumn()) sound_changed = true;
|
||||
viewer_changed = true;
|
||||
viewer_changed = true;
|
||||
}
|
||||
/*TAB
|
||||
if(cmd & (CMD_ENABLE_PREVIEW|CMD_DISABLE_PREVIEW|CMD_TOGGLE_PREVIEW))
|
||||
|
|
|
@ -4,8 +4,12 @@
|
|||
#define COLUMN_COMMAND_INCLUDED
|
||||
|
||||
#include <set>
|
||||
#include <QList>
|
||||
|
||||
#include "toonz/tstageobjectid.h"
|
||||
|
||||
class StageObjectsData;
|
||||
class TFx;
|
||||
|
||||
namespace ColumnCmd {
|
||||
|
||||
|
@ -35,6 +39,21 @@ void clearCells(int index);
|
|||
//! Adds an undo object for converting layer to vector.
|
||||
void addConvertToVectorUndo(std::set<int> &newColumnIndices);
|
||||
|
||||
} // namespace
|
||||
// "checkInvert" flag is ON when collapsing columns.
|
||||
// expression references need to be checked in both way,
|
||||
// the columns to be collapsed and other columns to be kept in the parent
|
||||
// xsheet.
|
||||
|
||||
bool checkExpressionReferences(const std::set<int> &indices,
|
||||
bool onlyColumns = true,
|
||||
bool checkInvert = false);
|
||||
bool checkExpressionReferences(const std::set<int> &indices,
|
||||
const std::set<TFx *> &fxs,
|
||||
bool onlyColumns = true,
|
||||
bool checkInvert = false);
|
||||
// checkInvert is always true for collapsing in stage schematic
|
||||
bool checkExpressionReferences(const QList<TStageObjectId> &objects);
|
||||
|
||||
} // namespace ColumnCmd
|
||||
|
||||
#endif
|
||||
|
|
|
@ -95,6 +95,8 @@ void TColumnSelection::pasteColumns() {
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
void TColumnSelection::deleteColumns() {
|
||||
if (!ColumnCmd::checkExpressionReferences(m_indices)) return;
|
||||
|
||||
ColumnCmd::deleteColumns(m_indices, false, false);
|
||||
}
|
||||
|
||||
|
|
1016
toonz/sources/toonz/expressionreferencemanager.cpp
Normal file
1016
toonz/sources/toonz/expressionreferencemanager.cpp
Normal file
File diff suppressed because it is too large
Load diff
89
toonz/sources/toonz/expressionreferencemanager.h
Normal file
89
toonz/sources/toonz/expressionreferencemanager.h
Normal file
|
@ -0,0 +1,89 @@
|
|||
#pragma once
|
||||
|
||||
#ifndef EXPRESSIONREFERENCEMANAGER_H
|
||||
#define EXPRESSIONREFERENCEMANAGER_H
|
||||
|
||||
#include "tparamchange.h"
|
||||
#include "toonzqt/treemodel.h"
|
||||
#include "toonzqt/functiontreeviewer.h"
|
||||
#include "toonz/txsheetcolumnchange.h"
|
||||
#include "toonz/tstageobjectid.h"
|
||||
#include "toonz/expressionreferencemonitor.h"
|
||||
#include <QObject>
|
||||
#include <QMap>
|
||||
#include <QSet>
|
||||
#include <QList>
|
||||
|
||||
class TDoubleParam;
|
||||
class TFx;
|
||||
|
||||
class ExpressionReferenceManager : public QObject,
|
||||
public TXsheetColumnChangeObserver,
|
||||
public TParamObserver { // singleton
|
||||
Q_OBJECT
|
||||
|
||||
FunctionTreeModel* m_model;
|
||||
// block to run onChange() due to keyframe change caused by itself
|
||||
bool m_blockParamChange;
|
||||
|
||||
ExpressionReferenceMonitor* currentMonitor();
|
||||
|
||||
QMap<TDoubleParam*, ExpressionReferenceMonitorInfo>& info(
|
||||
TXsheet* xsh = nullptr);
|
||||
|
||||
ExpressionReferenceMonitorInfo& touchInfo(TDoubleParam* param,
|
||||
TXsheet* xsh = nullptr);
|
||||
|
||||
ExpressionReferenceManager();
|
||||
|
||||
void checkRef(TreeModel::Item* item, TXsheet* xsh = nullptr);
|
||||
FunctionTreeModel::Channel* findChannel(TDoubleParam* param,
|
||||
TreeModel::Item* item);
|
||||
|
||||
void gatherParams(TreeModel::Item* item, QList<TDoubleParam*>&);
|
||||
bool refreshParamsRef(TDoubleParam* curve, TXsheet* xsh = nullptr);
|
||||
|
||||
void replaceExpressionTexts(
|
||||
TDoubleParam* curve, const std::map<std::string, std::string> replaceMap,
|
||||
TXsheet* xsh = nullptr);
|
||||
|
||||
bool doCheckReferenceDeletion(
|
||||
const QSet<int>& columnIdsToBeDeleted, const QSet<TFx*>& fxsToBeDeleted,
|
||||
const QList<TStageObjectId>& objectIdsToBeDeleted,
|
||||
const QList<TStageObjectId>& objIdsToBeDuplicated,
|
||||
bool checkInvert = false);
|
||||
|
||||
public:
|
||||
static ExpressionReferenceManager* instance();
|
||||
void onChange(const TXsheetColumnChange&) override;
|
||||
void onFxAdded(const std::vector<TFx*>&) override;
|
||||
void onStageObjectAdded(const TStageObjectId) override;
|
||||
bool isIgnored(TDoubleParam*) override;
|
||||
|
||||
void onChange(const TParamChange&) override;
|
||||
|
||||
void init();
|
||||
|
||||
bool checkReferenceDeletion(const QSet<int>& columnIdsToBeDeleted,
|
||||
const QSet<TFx*>& fxsToBeDeleted,
|
||||
const QList<TStageObjectId>& objIdsToBeDuplicated,
|
||||
bool checkInvert);
|
||||
bool checkReferenceDeletion(
|
||||
const QList<TStageObjectId>& objectIdsToBeDeleted);
|
||||
bool checkExplode(TXsheet* childXsh, int index, bool removeColumn,
|
||||
bool columnsOnly);
|
||||
|
||||
void transferReference(TXsheet* fromXsh, TXsheet* toXsh,
|
||||
const QMap<TStageObjectId, TStageObjectId>& idTable,
|
||||
const QMap<TFx*, TFx*>& fxTable);
|
||||
|
||||
bool askIfParamIsIgnoredOnSave(bool saveSubXsheet);
|
||||
|
||||
protected slots:
|
||||
void onSceneSwitched();
|
||||
void onXsheetSwitched();
|
||||
void onXsheetChanged();
|
||||
void onPreferenceChanged(const QString& prefName);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -239,10 +239,15 @@ void TFilmstripSelection::copyFrames() {
|
|||
void TFilmstripSelection::cutFrames() {
|
||||
TXshSimpleLevel *sl = TApp::instance()->getCurrentLevel()->getSimpleLevel();
|
||||
if (sl) {
|
||||
int firstSelectedIndex = sl->fid2index(*m_selectedFrames.begin());
|
||||
assert(firstSelectedIndex >= 0);
|
||||
FilmstripCmd::cut(sl, m_selectedFrames);
|
||||
selectNone();
|
||||
TApp::instance()->getCurrentFrame()->setFid(sl->getFirstFid());
|
||||
select(sl->getFirstFid());
|
||||
TFrameId fId = (firstSelectedIndex == 0)
|
||||
? sl->getFirstFid()
|
||||
: sl->getFrameId(firstSelectedIndex - 1);
|
||||
TApp::instance()->getCurrentFrame()->setFid(fId);
|
||||
select(fId);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -954,9 +954,11 @@ void ImageViewer::pickColor(QMouseEvent *event, bool putValueToStyleEditor) {
|
|||
TPointD(0.5 * imgRect.getLx() + pos.x, 0.5 * imgRect.getLy() + pos.y);
|
||||
|
||||
TPixel32 pix;
|
||||
if (m_lutCalibrator && m_lutCalibrator->isValid())
|
||||
pix = picker.pickColor(pos + TPointD(-0.5, -0.5));
|
||||
else
|
||||
if (m_lutCalibrator && m_lutCalibrator->isValid()) {
|
||||
// for specifiying pixel range on picking vector
|
||||
double scale2 = getViewAff().det();
|
||||
pix = picker.pickColor(pos + TPointD(-0.5, -0.5), 10.0, scale2);
|
||||
} else
|
||||
pix = picker.pickColor(area);
|
||||
|
||||
if (!img->raster() || imgRect.contains(imagePos)) {
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "versioncontrol.h"
|
||||
#include "cachefxcommand.h"
|
||||
#include "xdtsio.h"
|
||||
#include "expressionreferencemanager.h"
|
||||
|
||||
// TnzTools includes
|
||||
#include "tools/toolhandle.h"
|
||||
|
@ -1370,6 +1371,13 @@ bool IoCmd::saveScene(const TFilePath &path, int flags) {
|
|||
.arg(toQString(scenePath.getParentDir())));
|
||||
return false;
|
||||
}
|
||||
|
||||
// notify user if the scene will be saved including any "broken" expression
|
||||
// reference
|
||||
if (!ExpressionReferenceManager::instance()->askIfParamIsIgnoredOnSave(
|
||||
saveSubxsheet))
|
||||
return false;
|
||||
|
||||
if (!overwrite && TFileStatus(scenePath).doesExist()) {
|
||||
QString question;
|
||||
question = QObject::tr(
|
||||
|
@ -3025,7 +3033,7 @@ public:
|
|||
|
||||
if (sl && sl->getPath().getType() == "pli")
|
||||
sl->save(palettePath, TFilePath(), true);
|
||||
else if (sl->getType() & FULLCOLOR_TYPE)
|
||||
else if (sl && sl->getType() & FULLCOLOR_TYPE)
|
||||
FullColorPalette::instance()->savePalette(scene);
|
||||
else
|
||||
StudioPalette::instance()->save(palettePath, palette);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "previewfxmanager.h"
|
||||
#include "cleanupsettingspopup.h"
|
||||
#include "filebrowsermodel.h"
|
||||
#include "expressionreferencemanager.h"
|
||||
|
||||
// TnzTools includes
|
||||
#include "tools/tool.h"
|
||||
|
@ -467,11 +468,7 @@ int main(int argc, char *argv[]) {
|
|||
fmt.setStencil(true);
|
||||
QGLFormat::setDefaultFormat(fmt);
|
||||
|
||||
// seems this function should be called at all systems
|
||||
// perhaps in some GLUT-implementations initalization is mere formality
|
||||
#if defined(LINUX) || defined(_WIN32)
|
||||
glutInit(&argc, argv);
|
||||
#endif
|
||||
|
||||
splash.showMessage(offsetStr + "Initializing environment...",
|
||||
Qt::AlignRight | Qt::AlignBottom, Qt::black);
|
||||
|
@ -710,6 +707,8 @@ int main(int argc, char *argv[]) {
|
|||
QSettings settings(toQString(fp), QSettings::IniFormat);
|
||||
w.restoreGeometry(settings.value("MainWindowGeometry").toByteArray());
|
||||
|
||||
ExpressionReferenceManager::instance()->init();
|
||||
|
||||
#ifndef MACOSX
|
||||
// Workaround for the maximized window case: Qt delivers two resize events,
|
||||
// one in the normal geometry, before
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -7,9 +7,12 @@
|
|||
|
||||
#include "toonz/sceneproperties.h"
|
||||
|
||||
#include <QLabel>
|
||||
// forward declaration
|
||||
class ToonzScene;
|
||||
class QComboBox;
|
||||
class QScrollArea;
|
||||
class QListWidgetItem;
|
||||
|
||||
namespace DVGui {
|
||||
class FileField;
|
||||
|
@ -17,7 +20,7 @@ class LineEdit;
|
|||
class IntLineEdit;
|
||||
class CheckBox;
|
||||
class DoubleLineEdit;
|
||||
}
|
||||
} // namespace DVGui
|
||||
|
||||
class CameraSettingsPopup;
|
||||
|
||||
|
@ -25,6 +28,24 @@ class CameraSettingsPopup;
|
|||
// OutputSettingsPopup
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class AnimatedLabel : public QLabel {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QColor color READ color WRITE setColor)
|
||||
public:
|
||||
AnimatedLabel(const QString &text, QWidget *parent = 0)
|
||||
: QLabel(text, parent) {
|
||||
setObjectName("OutputSettingsLabel");
|
||||
}
|
||||
void setColor(QColor color) {
|
||||
setStyleSheet(QString("background-color: rgba(%1,%2,%3,%4);")
|
||||
.arg(color.red())
|
||||
.arg(color.green())
|
||||
.arg(color.blue())
|
||||
.arg(color.alpha()));
|
||||
}
|
||||
QColor color() { return Qt::black; }
|
||||
};
|
||||
|
||||
class OutputSettingsPopup : public DVGui::Dialog {
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -49,8 +70,6 @@ class OutputSettingsPopup : public DVGui::Dialog {
|
|||
|
||||
DVGui::DoubleLineEdit *m_frameRateFld;
|
||||
QPushButton *m_fileFormatButton;
|
||||
QPushButton *m_renderButton;
|
||||
QPushButton *m_saveAndRenderButton;
|
||||
CameraSettingsPopup *m_cameraSettings;
|
||||
QComboBox *m_presetCombo;
|
||||
|
||||
|
@ -58,12 +77,24 @@ class OutputSettingsPopup : public DVGui::Dialog {
|
|||
DVGui::CheckBox *m_addBoard;
|
||||
QPushButton *m_boardSettingsBtn;
|
||||
|
||||
QScrollArea *m_scrollArea;
|
||||
QLabel *m_generalLabel, *m_cameraLabel, *m_advancedLabel, *m_moreLabel;
|
||||
QFrame *m_generalBox, *m_cameraBox, *m_advancedBox, *m_moreBox;
|
||||
QPushButton *m_showCameraSettingsButton, *m_showAdvancedSettingsButton,
|
||||
*m_showMoreSettingsButton;
|
||||
|
||||
bool m_isPreviewSettings;
|
||||
bool m_hideAlreadyCalled = false;
|
||||
|
||||
void updatePresetComboItems();
|
||||
void translateResampleOptions();
|
||||
|
||||
QFrame *createPanel(bool isPreview);
|
||||
QFrame *createGeneralSettingsBox(bool isPreview);
|
||||
QFrame *createCameraSettingsBox(bool isPreview);
|
||||
QFrame *createAdvancedSettingsBox(bool isPreview);
|
||||
QFrame *createMoreSettingsBox();
|
||||
|
||||
public:
|
||||
OutputSettingsPopup(bool isPreview = false);
|
||||
|
||||
|
@ -108,6 +139,8 @@ protected slots:
|
|||
// clapperboard
|
||||
void onAddBoardChecked(int state);
|
||||
void onBoardSettingsBtnClicked();
|
||||
|
||||
void onCategoryActivated(QListWidgetItem *);
|
||||
};
|
||||
|
||||
class PreviewSettingsPopup final : public OutputSettingsPopup {
|
||||
|
|
|
@ -552,6 +552,13 @@ void PreferencesPopup::onShowQuickToolbarClicked() {
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void PreferencesPopup::onModifyExpressionOnMovingReferencesChanged() {
|
||||
TApp::instance()->getCurrentScene()->notifyPreferenceChanged(
|
||||
"modifyExpressionOnMovingReferences");
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void PreferencesPopup::onBlankCountChanged() {
|
||||
TApp::instance()->getCurrentScene()->notifyPreferenceChanged("BlankCount");
|
||||
}
|
||||
|
@ -1104,6 +1111,9 @@ QString PreferencesPopup::getUIString(PreferencesItemId id) {
|
|||
// Animation
|
||||
{keyframeType, tr("Default Interpolation:")},
|
||||
{animationStep, tr("Animation Step:")},
|
||||
{modifyExpressionOnMovingReferences,
|
||||
tr("[Experimental Feature] ") +
|
||||
tr("Automatically Modify Expression On Moving Referenced Objects")},
|
||||
|
||||
// Preview
|
||||
{blanksCount, tr("Blank Frames:")},
|
||||
|
@ -1767,9 +1777,15 @@ QWidget* PreferencesPopup::createAnimationPage() {
|
|||
|
||||
insertUI(keyframeType, lay, getComboItemList(keyframeType));
|
||||
insertUI(animationStep, lay);
|
||||
insertUI(modifyExpressionOnMovingReferences, lay);
|
||||
|
||||
lay->setRowStretch(lay->rowCount(), 1);
|
||||
widget->setLayout(lay);
|
||||
|
||||
m_onEditedFuncMap.insert(
|
||||
modifyExpressionOnMovingReferences,
|
||||
&PreferencesPopup::onModifyExpressionOnMovingReferencesChanged);
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
||||
|
|
|
@ -146,6 +146,8 @@ private:
|
|||
// Xsheet
|
||||
void onShowKeyframesOnCellAreaChanged();
|
||||
void onShowQuickToolbarClicked();
|
||||
// Animation
|
||||
void onModifyExpressionOnMovingReferencesChanged();
|
||||
// Preview
|
||||
void onBlankCountChanged();
|
||||
void onBlankColorChanged();
|
||||
|
|
|
@ -3117,8 +3117,9 @@ void SceneViewer::posToColumnIndexes(const TPointD &p,
|
|||
OnionSkinMask osm = app->getCurrentOnionSkin()->getOnionSkinMask();
|
||||
|
||||
TPointD pos = TPointD(p.x - width() / 2, p.y - height() / 2);
|
||||
Stage::Picker picker(getViewMatrix(), pos, m_visualSettings);
|
||||
picker.setDistance(distance);
|
||||
Stage::Picker picker(getViewMatrix(), pos, m_visualSettings,
|
||||
getDevPixRatio());
|
||||
picker.setMinimumDistance(distance);
|
||||
|
||||
TXshSimpleLevel::m_rasterizePli = 0;
|
||||
|
||||
|
@ -3156,8 +3157,9 @@ int SceneViewer::posToRow(const TPointD &p, double distance,
|
|||
OnionSkinMask osm = app->getCurrentOnionSkin()->getOnionSkinMask();
|
||||
|
||||
TPointD pos = TPointD(p.x - width() / 2, p.y - height() / 2);
|
||||
Stage::Picker picker(getViewMatrix(), pos, m_visualSettings);
|
||||
picker.setDistance(distance);
|
||||
Stage::Picker picker(getViewMatrix(), pos, m_visualSettings,
|
||||
getDevPixRatio());
|
||||
picker.setMinimumDistance(distance);
|
||||
|
||||
if (app->getCurrentFrame()->isEditingLevel()) {
|
||||
Stage::visit(picker, app->getCurrentLevel()->getLevel(),
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "toonz/tstageobjecttree.h"
|
||||
#include "toonz/tstageobjectspline.h"
|
||||
#include "toonz/tcamera.h"
|
||||
#include "toonz/expressionreferencemonitor.h"
|
||||
|
||||
// TnzQt includes
|
||||
#include "toonzqt/menubarcommand.h"
|
||||
|
@ -47,6 +48,7 @@
|
|||
#include "tapp.h"
|
||||
#include "columnselection.h"
|
||||
#include "cellselection.h"
|
||||
#include "expressionreferencemanager.h"
|
||||
|
||||
#include "subscenecommand.h"
|
||||
|
||||
|
@ -625,12 +627,10 @@ std::set<int> explodeStageObjects(
|
|||
const GroupData &fxGroupData, QList<TStageObject *> &pegObjects,
|
||||
QMap<TFx *, QPair<TFx *, int>> &fxs,
|
||||
QMap<TStageObjectSpline *, TStageObjectSpline *> &splines,
|
||||
bool onlyColumn) {
|
||||
QMap<TStageObjectId, TStageObjectId> &ids, bool onlyColumn) {
|
||||
/*- SubXsheet, 親Xsheet両方のツリーを取得 -*/
|
||||
TStageObjectTree *innerTree = subXsh->getStageObjectTree();
|
||||
TStageObjectTree *outerTree = xsh->getStageObjectTree();
|
||||
// inner id->outer id
|
||||
QMap<TStageObjectId, TStageObjectId> ids;
|
||||
// innerSpline->outerSpline
|
||||
int groupId = -1; // outerTree->getNewGroupId();
|
||||
/*- Pegbarも持ち出す場合 -*/
|
||||
|
@ -927,20 +927,58 @@ void explodeFxs(TXsheet *xsh, TXsheet *subXsh, const GroupData &fxGroupData,
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template <typename ParamCont>
|
||||
void setGrammerToParams(const ParamCont *cont,
|
||||
const TSyntax::Grammar *grammer) {
|
||||
for (int p = 0; p != cont->getParamCount(); ++p) {
|
||||
TParam ¶m = *cont->getParam(p);
|
||||
if (TDoubleParam *dp = dynamic_cast<TDoubleParam *>(¶m))
|
||||
dp->setGrammar(grammer);
|
||||
else if (TParamSet *paramSet = dynamic_cast<TParamSet *>(¶m))
|
||||
setGrammerToParams(paramSet, grammer);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
std::set<int> explode(TXsheet *xsh, TXsheet *subXsh, int index,
|
||||
const TStageObjectId &parentId,
|
||||
const GroupData &objGroupData, const TPointD &stageSubPos,
|
||||
const GroupData &fxGroupData, const TPointD &fxSubPos,
|
||||
QList<TStageObject *> &pegObjects,
|
||||
QMap<TStageObjectSpline *, TStageObjectSpline *> &splines,
|
||||
const std::vector<TFxPort *> &outPorts, bool onlyColumn,
|
||||
bool linkToXsheet) {
|
||||
const TStageObjectId &parentId, const GroupData &objGroupData,
|
||||
const TPointD &stageSubPos, const GroupData &fxGroupData,
|
||||
const TPointD &fxSubPos, QList<TStageObject *> &pegObjects,
|
||||
QMap<TStageObjectSpline *, TStageObjectSpline *> &splines,
|
||||
const std::vector<TFxPort *> &outPorts, bool onlyColumn,
|
||||
bool linkToXsheet) {
|
||||
// innerFx->outerFxs
|
||||
QMap<TFx *, QPair<TFx *, int>> fxs;
|
||||
// inner id->outer id
|
||||
QMap<TStageObjectId, TStageObjectId> objIds;
|
||||
std::set<int> indexes = explodeStageObjects(
|
||||
xsh, subXsh, index, parentId, objGroupData, stageSubPos, fxGroupData,
|
||||
pegObjects, fxs, splines, onlyColumn);
|
||||
pegObjects, fxs, splines, objIds, onlyColumn);
|
||||
explodeFxs(xsh, subXsh, fxGroupData, fxs, fxSubPos, outPorts, linkToXsheet);
|
||||
|
||||
assert(TApp::instance()->getCurrentXsheet()->getXsheet() == xsh);
|
||||
|
||||
// reset grammers for all parameters brought out to the parent xsheet
|
||||
TSyntax::Grammar *grammer = xsh->getStageObjectTree()->getGrammar();
|
||||
for (auto id : objIds.values()) {
|
||||
TStageObject *obj = xsh->getStageObject(id);
|
||||
for (int c = 0; c != TStageObject::T_ChannelCount; ++c)
|
||||
obj->getParam((TStageObject::Channel)c)->setGrammar(grammer);
|
||||
if (const PlasticSkeletonDeformationP &sd =
|
||||
obj->getPlasticSkeletonDeformation())
|
||||
sd->setGrammar(grammer);
|
||||
}
|
||||
|
||||
QMap<TFx *, TFx *> fxMap;
|
||||
for (auto it = fxs.constBegin(); it != fxs.constEnd(); ++it) {
|
||||
setGrammerToParams(it.value().first->getParams(), grammer);
|
||||
fxMap.insert(it.key(), it.value().first);
|
||||
}
|
||||
|
||||
ExpressionReferenceManager::instance()->transferReference(subXsh, xsh, objIds,
|
||||
fxMap);
|
||||
|
||||
return indexes;
|
||||
}
|
||||
|
||||
|
@ -1160,9 +1198,9 @@ bool hasPegbarsToBringInsideChildXsheet(TXsheet *xsh,
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void bringPegbarsInsideChildXsheet(TXsheet *xsh, TXsheet *childXsh,
|
||||
std::set<int> indices,
|
||||
std::set<int> newIndices) {
|
||||
void bringPegbarsInsideChildXsheet(
|
||||
TXsheet *xsh, TXsheet *childXsh, std::set<int> indices,
|
||||
std::set<int> newIndices, QMap<TStageObjectId, TStageObjectId> &idTable) {
|
||||
// columns in the child xsheet are all connected to the table for now.
|
||||
// so we need to take parental connection information from the parent xsheet.
|
||||
|
||||
|
@ -1201,6 +1239,9 @@ void bringPegbarsInsideChildXsheet(TXsheet *xsh, TXsheet *childXsh,
|
|||
for (int c = 0; c != TStageObject::T_ChannelCount; ++c)
|
||||
childXsh->getStageObjectTree()->setGrammar(
|
||||
obj->getParam((TStageObject::Channel)c));
|
||||
|
||||
// register pegbars to the table
|
||||
idTable.insert(id, id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1249,11 +1290,15 @@ void collapseColumns(std::set<int> indices, bool columnsOnly) {
|
|||
TApp *app = TApp::instance();
|
||||
TXsheet *xsh = app->getCurrentXsheet()->getXsheet();
|
||||
|
||||
std::set<int> oldIndices = indices;
|
||||
|
||||
StageObjectsData *data = new StageObjectsData();
|
||||
// store xsheet data to be collapsed
|
||||
data->storeColumns(indices, xsh, StageObjectsData::eDoClone);
|
||||
data->storeColumnFxs(indices, xsh, StageObjectsData::eDoClone);
|
||||
|
||||
ExpressionReferenceMonitor *monitor = xsh->getExpRefMonitor()->clone();
|
||||
|
||||
ToonzScene *scene = app->getCurrentScene()->getScene();
|
||||
TXshLevel *xl = scene->createNewLevel(CHILD_XSHLEVEL);
|
||||
assert(xl);
|
||||
|
@ -1265,12 +1310,18 @@ void collapseColumns(std::set<int> indices, bool columnsOnly) {
|
|||
|
||||
std::set<int> newIndices;
|
||||
std::list<int> restoredSplineIds;
|
||||
QMap<TStageObjectId, TStageObjectId> idTable;
|
||||
QMap<TFx *, TFx *> fxTable;
|
||||
// restore data into sub xsheet
|
||||
data->restoreObjects(newIndices, restoredSplineIds, childXsh, 0);
|
||||
data->restoreObjects(newIndices, restoredSplineIds, childXsh, 0, idTable,
|
||||
fxTable);
|
||||
|
||||
// bring pegbars into sub xsheet
|
||||
if (!columnsOnly)
|
||||
bringPegbarsInsideChildXsheet(xsh, childXsh, indices, newIndices);
|
||||
bringPegbarsInsideChildXsheet(xsh, childXsh, indices, newIndices, idTable);
|
||||
|
||||
ExpressionReferenceManager::instance()->transferReference(xsh, childXsh,
|
||||
idTable, fxTable);
|
||||
|
||||
childXsh->updateFrameCount();
|
||||
|
||||
|
@ -1339,8 +1390,9 @@ void collapseColumns(std::set<int> indices,
|
|||
const QList<TStageObjectId> &objIds) {
|
||||
if (indices.empty()) return;
|
||||
|
||||
TApp *app = TApp::instance();
|
||||
TXsheet *xsh = app->getCurrentXsheet()->getXsheet();
|
||||
TApp *app = TApp::instance();
|
||||
TXsheet *xsh = app->getCurrentXsheet()->getXsheet();
|
||||
std::set<int> oldIndices = indices;
|
||||
|
||||
int index = *indices.begin();
|
||||
|
||||
|
@ -1356,13 +1408,7 @@ void collapseColumns(std::set<int> indices,
|
|||
StageObjectsData::eDoClone);
|
||||
data->storeColumnFxs(indices, xsh, StageObjectsData::eDoClone);
|
||||
|
||||
app->getCurrentXsheet()->blockSignals(true);
|
||||
app->getCurrentObject()->blockSignals(true);
|
||||
ColumnCmd::deleteColumns(indices, false, true);
|
||||
app->getCurrentXsheet()->blockSignals(false);
|
||||
app->getCurrentObject()->blockSignals(false);
|
||||
|
||||
xsh->insertColumn(index);
|
||||
ExpressionReferenceMonitor *monitor = xsh->getExpRefMonitor()->clone();
|
||||
|
||||
ToonzScene *scene = app->getCurrentScene()->getScene();
|
||||
TXshLevel *xl = scene->createNewLevel(CHILD_XSHLEVEL);
|
||||
|
@ -1375,9 +1421,23 @@ void collapseColumns(std::set<int> indices,
|
|||
|
||||
std::set<int> newIndices;
|
||||
std::list<int> restoredSplineIds;
|
||||
data->restoreObjects(newIndices, restoredSplineIds, childXsh, 0);
|
||||
QMap<TStageObjectId, TStageObjectId> idTable;
|
||||
QMap<TFx *, TFx *> fxTable;
|
||||
data->restoreObjects(newIndices, restoredSplineIds, childXsh, 0, idTable,
|
||||
fxTable);
|
||||
childXsh->updateFrameCount();
|
||||
|
||||
ExpressionReferenceManager::instance()->transferReference(xsh, childXsh,
|
||||
idTable, fxTable);
|
||||
|
||||
app->getCurrentXsheet()->blockSignals(true);
|
||||
app->getCurrentObject()->blockSignals(true);
|
||||
ColumnCmd::deleteColumns(indices, false, true);
|
||||
app->getCurrentXsheet()->blockSignals(false);
|
||||
app->getCurrentObject()->blockSignals(false);
|
||||
|
||||
xsh->insertColumn(index);
|
||||
|
||||
int r, rowCount = childXsh->getFrameCount();
|
||||
for (r = 0; r < rowCount; r++)
|
||||
xsh->setCell(r, index, TXshCell(xl, TFrameId(r + 1)));
|
||||
|
@ -1405,12 +1465,15 @@ void collapseColumns(std::set<int> indices, const std::set<TFx *> &fxs,
|
|||
TApp *app = TApp::instance();
|
||||
TXsheet *xsh = app->getCurrentXsheet()->getXsheet();
|
||||
|
||||
std::set<int> oldIndices = indices;
|
||||
//++++++++++++++++++++++++++++++
|
||||
|
||||
StageObjectsData *data = new StageObjectsData();
|
||||
data->storeColumns(indices, xsh, StageObjectsData::eDoClone);
|
||||
data->storeFxs(fxs, xsh, StageObjectsData::eDoClone);
|
||||
|
||||
ExpressionReferenceMonitor *monitor = xsh->getExpRefMonitor()->clone();
|
||||
|
||||
ToonzScene *scene = app->getCurrentScene()->getScene();
|
||||
TXshLevel *xl = scene->createNewLevel(CHILD_XSHLEVEL);
|
||||
assert(xl);
|
||||
|
@ -1420,10 +1483,16 @@ void collapseColumns(std::set<int> indices, const std::set<TFx *> &fxs,
|
|||
|
||||
std::set<int> newIndices;
|
||||
std::list<int> restoredSplineIds;
|
||||
data->restoreObjects(newIndices, restoredSplineIds, childXsh, 0);
|
||||
QMap<TStageObjectId, TStageObjectId> idTable;
|
||||
QMap<TFx *, TFx *> fxTable;
|
||||
data->restoreObjects(newIndices, restoredSplineIds, childXsh, 0, idTable,
|
||||
fxTable);
|
||||
|
||||
if (!columnsOnly)
|
||||
bringPegbarsInsideChildXsheet(xsh, childXsh, indices, newIndices);
|
||||
bringPegbarsInsideChildXsheet(xsh, childXsh, indices, newIndices, idTable);
|
||||
|
||||
ExpressionReferenceManager::instance()->transferReference(xsh, childXsh,
|
||||
idTable, fxTable);
|
||||
|
||||
childXsh->updateFrameCount();
|
||||
|
||||
|
@ -2224,6 +2293,7 @@ void SubsceneCmd::collapse(std::set<int> &indices) {
|
|||
if (ret == 0) return;
|
||||
onlyColumns = (ret == 2);
|
||||
}
|
||||
if (!ColumnCmd::checkExpressionReferences(indices, onlyColumns, true)) return;
|
||||
|
||||
std::set<int> oldIndices = indices;
|
||||
int index = *indices.begin();
|
||||
|
@ -2272,6 +2342,8 @@ void SubsceneCmd::collapse(const QList<TStageObjectId> &objects) {
|
|||
std::set<int> indices;
|
||||
getColumnIndexes(objects, indices);
|
||||
|
||||
if (!ColumnCmd::checkExpressionReferences(objects)) return;
|
||||
|
||||
std::set<int> oldIndices = indices;
|
||||
int index = *indices.begin();
|
||||
|
||||
|
@ -2320,6 +2392,7 @@ void SubsceneCmd::collapse(const QList<TFxP> &fxs) {
|
|||
TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet();
|
||||
bool onlyColumns = true;
|
||||
if (hasPegbarsToBringInsideChildXsheet(xsh, indices)) {
|
||||
// User must decide if pegbars must be collapsed too
|
||||
QString question(QObject::tr("Collapsing columns: what you want to do?"));
|
||||
QList<QString> list;
|
||||
list.append(QObject::tr(
|
||||
|
@ -2332,6 +2405,10 @@ void SubsceneCmd::collapse(const QList<TFxP> &fxs) {
|
|||
onlyColumns = (ret == 2);
|
||||
}
|
||||
|
||||
if (!ColumnCmd::checkExpressionReferences(indices, internalFx, onlyColumns,
|
||||
true))
|
||||
return;
|
||||
|
||||
std::set<int> oldIndices = indices;
|
||||
int index = *indices.begin();
|
||||
|
||||
|
@ -2385,6 +2462,15 @@ void SubsceneCmd::explode(int index) {
|
|||
TXshChildLevel *childLevel = cell.getChildLevel();
|
||||
if (!childLevel) return;
|
||||
|
||||
// Cannot remove the column if it contains frames of a TXshSimpleLevel.
|
||||
int from, to;
|
||||
|
||||
// removeColumn is true if the column contains only one subXsheetLevel (i.e.
|
||||
// the column will be removed) removeColumn is false if there is another level
|
||||
// in the same column (i.e. the column will remain)
|
||||
bool removeColumn =
|
||||
mustRemoveColumn(from, to, childLevel, xsh, index, frameIndex);
|
||||
|
||||
/*- Pegbarを親Sheetに持って出るか?の質問ダイアログ -*/
|
||||
QString question(QObject::tr("Exploding Sub-Scene: what you want to do?"));
|
||||
QList<QString> list;
|
||||
|
@ -2394,6 +2480,11 @@ void SubsceneCmd::explode(int index) {
|
|||
QObject::tr("Bring columns in the main scene without parenting."));
|
||||
int ret = DVGui::RadioButtonMsgBox(DVGui::WARNING, question, list);
|
||||
if (ret == 0) return;
|
||||
|
||||
if (!ExpressionReferenceManager::instance()->checkExplode(
|
||||
childLevel->getXsheet(), index, removeColumn, ret == 2))
|
||||
return;
|
||||
|
||||
// Collect column stage object informations
|
||||
TStageObjectId colId = TStageObjectId::ColumnId(index);
|
||||
TStageObjectId parentId = xsh->getStageObjectParent(colId);
|
||||
|
@ -2450,14 +2541,6 @@ void SubsceneCmd::explode(int index) {
|
|||
|
||||
std::vector<TFxPort *> outPorts;
|
||||
|
||||
// Cannot remove the column if it contains frames of a TXshSimpleLevel.
|
||||
int from, to;
|
||||
/*--
|
||||
このカラムがsubXsheetLevelしか入っていない場合は、カラムを消去できるのでremoveColumnはtrue
|
||||
何か別のLevelが入っていた場合は、カラムを消去しないので、removeColumnはfalse
|
||||
--*/
|
||||
bool removeColumn =
|
||||
mustRemoveColumn(from, to, childLevel, xsh, index, frameIndex);
|
||||
QList<TStageObject *> pegObjects;
|
||||
QMap<TStageObjectSpline *, TStageObjectSpline *> splines;
|
||||
|
||||
|
@ -2519,7 +2602,7 @@ void SubsceneCmd::explode(int index) {
|
|||
objGroupNames);
|
||||
TUndoManager::manager()->add(undo);
|
||||
} else {
|
||||
// keep outPorts empty since the exploded node will be re-cocnected to the
|
||||
// keep outPorts empty since the exploded node will be re-connected to the
|
||||
// xsheet node
|
||||
|
||||
// Collect information for undo
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "historypane.h"
|
||||
#include "cleanupsettingspane.h"
|
||||
#include "vectorguideddrawingpane.h"
|
||||
#include "expressionreferencemanager.h"
|
||||
#include "stopmotioncontroller.h"
|
||||
#include "motionpathpanel.h"
|
||||
|
||||
|
@ -35,6 +36,7 @@
|
|||
#include "menubarcommandids.h"
|
||||
#include "tapp.h"
|
||||
#include "mainwindow.h"
|
||||
#include "columncommand.h"
|
||||
|
||||
// TnzTools includes
|
||||
#include "tools/tooloptions.h"
|
||||
|
@ -52,6 +54,8 @@
|
|||
#include "toonzqt/tmessageviewer.h"
|
||||
#include "toonzqt/scriptconsole.h"
|
||||
#include "toonzqt/fxsettings.h"
|
||||
#include "toonzqt/fxselection.h"
|
||||
#include "stageobjectselection.h"
|
||||
|
||||
// TnzLib includes
|
||||
#include "toonz/palettecontroller.h"
|
||||
|
@ -72,6 +76,8 @@
|
|||
#include "toonz/preferences.h"
|
||||
#include "tw/stringtable.h"
|
||||
#include "toonz/toonzfolders.h"
|
||||
#include "toonz/fxcommand.h"
|
||||
#include "toonz/tstageobjectcmd.h"
|
||||
|
||||
// TnzBase includes
|
||||
#include "trasterfx.h"
|
||||
|
@ -223,6 +229,39 @@ int SchematicScenePanel::getViewType() {
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SchematicScenePanel::onDeleteFxs(const FxSelection *selection) {
|
||||
if (selection->isEmpty()) return;
|
||||
std::set<int> colIndices;
|
||||
std::set<TFx *> fxs;
|
||||
for (auto index : selection->getColumnIndexes()) colIndices.insert(index);
|
||||
for (auto fx : selection->getFxs()) fxs.insert(fx.getPointer());
|
||||
|
||||
if (!ColumnCmd::checkExpressionReferences(colIndices, fxs)) return;
|
||||
|
||||
TApp *app = TApp::instance();
|
||||
TFxCommand::deleteSelection(selection->getFxs().toStdList(),
|
||||
selection->getLinks().toStdList(),
|
||||
selection->getColumnIndexes().toStdList(),
|
||||
app->getCurrentXsheet(), app->getCurrentFx());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SchematicScenePanel::onDeleteStageObjects(
|
||||
const StageObjectSelection *selection) {
|
||||
if (!ExpressionReferenceManager::instance()->checkReferenceDeletion(
|
||||
selection->getObjects()))
|
||||
return;
|
||||
|
||||
TApp *app = TApp::instance();
|
||||
TStageObjectCmd::deleteSelection(
|
||||
selection->getObjects().toVector().toStdVector(),
|
||||
selection->getLinks().toStdList(), selection->getSplines().toStdList(),
|
||||
app->getCurrentXsheet(), app->getCurrentObject(), app->getCurrentFx());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void SchematicScenePanel::showEvent(QShowEvent *e) {
|
||||
if (m_schematicViewer->isStageSchematicViewed())
|
||||
setWindowTitle(QObject::tr("Stage Schematic"));
|
||||
|
@ -238,8 +277,13 @@ void SchematicScenePanel::showEvent(QShowEvent *e) {
|
|||
SLOT(onCollapse(QList<TStageObjectId>)));
|
||||
connect(m_schematicViewer, SIGNAL(doExplodeChild(const QList<TFxP> &)), this,
|
||||
SLOT(onExplodeChild(const QList<TFxP> &)));
|
||||
connect(m_schematicViewer, SIGNAL(doDeleteFxs(const FxSelection *)), this,
|
||||
SLOT(onDeleteFxs(const FxSelection *)));
|
||||
connect(m_schematicViewer, SIGNAL(doExplodeChild(QList<TStageObjectId>)),
|
||||
this, SLOT(onExplodeChild(QList<TStageObjectId>)));
|
||||
connect(m_schematicViewer,
|
||||
SIGNAL(doDeleteStageObjects(const StageObjectSelection *)), this,
|
||||
SLOT(onDeleteStageObjects(const StageObjectSelection *)));
|
||||
connect(m_schematicViewer, SIGNAL(editObject()), this, SLOT(onEditObject()));
|
||||
connect(app->getCurrentLevel(), SIGNAL(xshLevelChanged()), m_schematicViewer,
|
||||
SLOT(updateScenes()));
|
||||
|
|
|
@ -30,6 +30,8 @@ class ComboViewerPanel;
|
|||
class SceneViewerPanel;
|
||||
class FxSettings;
|
||||
class VectorGuidedDrawingPane;
|
||||
class FxSelection;
|
||||
class StageObjectSelection;
|
||||
|
||||
//=========================================================
|
||||
// PaletteViewerPanel
|
||||
|
@ -187,6 +189,8 @@ protected slots:
|
|||
void onExplodeChild(const QList<TFxP> &);
|
||||
void onExplodeChild(QList<TStageObjectId>);
|
||||
void onEditObject();
|
||||
void onDeleteFxs(const FxSelection *);
|
||||
void onDeleteStageObjects(const StageObjectSelection *);
|
||||
};
|
||||
|
||||
//=========================================================
|
||||
|
|
|
@ -1051,7 +1051,10 @@ static void removeEmptyColumns() {
|
|||
if (!column || column->isEmpty()) indices.insert(i);
|
||||
}
|
||||
|
||||
if (indices.size()) ColumnCmd::deleteColumns(indices, false, false);
|
||||
if (indices.empty()) return;
|
||||
if (!ColumnCmd::checkExpressionReferences(indices)) return;
|
||||
|
||||
ColumnCmd::deleteColumns(indices, false, false);
|
||||
|
||||
app->getCurrentXsheet()->notifyXsheetChanged();
|
||||
}
|
||||
|
|
|
@ -160,6 +160,8 @@ set(HEADERS
|
|||
../include/toonz/vectorizerparameters.h
|
||||
../include/toutputproperties.h
|
||||
../include/toonz/preferencesitemids.h
|
||||
../include/toonz/txsheetcolumnchange.h
|
||||
../include/toonz/expressionreferencemonitor.h
|
||||
)
|
||||
|
||||
set(SOURCES
|
||||
|
|
|
@ -1947,7 +1947,7 @@ void DeleteLinksUndo::redo() const {
|
|||
outputFx->getInputPort(index)->setFx(0);
|
||||
}
|
||||
|
||||
m_xshHandle->notifyXsheetChanged();
|
||||
if (m_isLastInRedoBlock) m_xshHandle->notifyXsheetChanged();
|
||||
}
|
||||
|
||||
//------------------------------------------------------
|
||||
|
@ -2012,7 +2012,7 @@ void DeleteLinksUndo::undo() const {
|
|||
}
|
||||
}
|
||||
|
||||
m_xshHandle->notifyXsheetChanged();
|
||||
if (m_isLastInBlock) m_xshHandle->notifyXsheetChanged();
|
||||
}
|
||||
|
||||
//------------------------------------------------------
|
||||
|
@ -2051,6 +2051,7 @@ static void deleteLinks(const std::list<TFxCommand::Link> &links,
|
|||
TXsheetHandle *xshHandle) {
|
||||
std::unique_ptr<FxCommandUndo> undo(new DeleteLinksUndo(links, xshHandle));
|
||||
if (undo->isConsistent()) {
|
||||
undo->m_isLastInRedoBlock = false;
|
||||
undo->redo();
|
||||
TUndoManager::manager()->add(undo.release());
|
||||
}
|
||||
|
@ -2245,7 +2246,8 @@ void DeleteFxOrColumnUndo::redo() const {
|
|||
// Perform operation
|
||||
FxCommandUndo::removeFxOrColumn(xsh, m_fx.getPointer(), m_colIdx);
|
||||
|
||||
m_xshHandle->notifyXsheetChanged(); // Add the rest...
|
||||
if (m_isLastInRedoBlock)
|
||||
m_xshHandle->notifyXsheetChanged(); // Add the rest...
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
|
@ -2296,7 +2298,7 @@ void DeleteFxOrColumnUndo::undo() const {
|
|||
|
||||
// Re-establish fx links
|
||||
DeleteLinksUndo::undo();
|
||||
} else // Already covered by DeleteLinksUndo::undo()
|
||||
} else if (m_isLastInBlock) // Already covered by DeleteLinksUndo::undo()
|
||||
m_xshHandle->notifyXsheetChanged(); // in the other branch
|
||||
}
|
||||
|
||||
|
@ -2327,6 +2329,9 @@ static void deleteFxs(const std::list<TFxP> &fxs, TXsheetHandle *xshHandle,
|
|||
std::unique_ptr<FxCommandUndo> undo(
|
||||
new DeleteFxOrColumnUndo(*ft, xshHandle, fxHandle));
|
||||
if (undo->isConsistent()) {
|
||||
// prevent emiting xsheetChanged signal for every undos which will cause
|
||||
// multiple triggers of preview rendering
|
||||
undo->m_isLastInRedoBlock = false;
|
||||
undo->redo();
|
||||
TUndoManager::manager()->add(undo.release());
|
||||
}
|
||||
|
@ -2377,6 +2382,9 @@ static void deleteColumns(const std::list<int> &columns,
|
|||
std::unique_ptr<FxCommandUndo> undo(
|
||||
new DeleteFxOrColumnUndo(cols[c]->getIndex(), xshHandle, fxHandle));
|
||||
if (undo->isConsistent()) {
|
||||
// prevent emiting xsheetChanged signal for every undos which will cause
|
||||
// multiple triggers of preview rendering
|
||||
undo->m_isLastInRedoBlock = false;
|
||||
undo->redo();
|
||||
undoManager->add(undo.release());
|
||||
}
|
||||
|
@ -2395,8 +2403,7 @@ void TFxCommand::deleteSelection(const std::list<TFxP> &fxs,
|
|||
TXsheetHandle *xshHandle,
|
||||
TFxHandle *fxHandle) {
|
||||
// Prepare selected fxs - column fxs would be done twice if the corresponding
|
||||
// columns have
|
||||
// been supplied for deletion too
|
||||
// columns have been supplied for deletion too
|
||||
::FilterColumnFxs filterColumnFxs;
|
||||
|
||||
std::list<TFxP> filteredFxs(fxs);
|
||||
|
@ -2407,11 +2414,13 @@ void TFxCommand::deleteSelection(const std::list<TFxP> &fxs,
|
|||
// Perform deletions
|
||||
TUndoManager::manager()->beginBlock();
|
||||
|
||||
deleteColumns(columns, xshHandle, fxHandle);
|
||||
deleteFxs(filteredFxs, xshHandle, fxHandle);
|
||||
deleteLinks(links, xshHandle);
|
||||
if (!columns.empty()) deleteColumns(columns, xshHandle, fxHandle);
|
||||
if (!filteredFxs.empty()) deleteFxs(filteredFxs, xshHandle, fxHandle);
|
||||
if (!links.empty()) deleteLinks(links, xshHandle);
|
||||
|
||||
TUndoManager::manager()->endBlock();
|
||||
// emit xsheetChanged once here
|
||||
xshHandle->notifyXsheetChanged();
|
||||
}
|
||||
|
||||
//**********************************************************************
|
||||
|
|
|
@ -532,6 +532,8 @@ void Preferences::definePreferenceItems() {
|
|||
// Animation
|
||||
define(keyframeType, "keyframeType", QMetaType::Int, 2); // Linear
|
||||
define(animationStep, "animationStep", QMetaType::Int, 1, 1, 500);
|
||||
define(modifyExpressionOnMovingReferences,
|
||||
"modifyExpressionOnMovingReferences", QMetaType::Bool, false);
|
||||
|
||||
// Preview
|
||||
define(blanksCount, "blanksCount", QMetaType::Int, 0, 0, 1000);
|
||||
|
|
|
@ -215,16 +215,20 @@ void onPlasticDeformedImage(TStageObject *playerObj,
|
|||
//**********************************************************************************************
|
||||
|
||||
Picker::Picker(const TAffine &viewAff, const TPointD &point,
|
||||
const ImagePainter::VisualSettings &vs)
|
||||
const ImagePainter::VisualSettings &vs, int devPixRatio)
|
||||
: Visitor(vs)
|
||||
, m_viewAff(viewAff)
|
||||
, m_point(point)
|
||||
, m_columnIndexes()
|
||||
, m_minDist2(1.0e10) {}
|
||||
, m_minDist2(25.0)
|
||||
, m_devPixRatio(devPixRatio) {}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void Picker::setDistance(double d) { m_minDist2 = d * d; }
|
||||
void Picker::setMinimumDistance(double d) {
|
||||
m_minDist2 = (double)(m_devPixRatio * m_devPixRatio) * d * d;
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
@ -251,21 +255,12 @@ void Picker::onImage(const Stage::Player &player) {
|
|||
if (styleId != 0)
|
||||
picked = true;
|
||||
else if (vi->getNearestStroke(point, w, strokeIndex, dist2)) {
|
||||
// based on TTool::Viewer::doPickGuideStroke
|
||||
|
||||
// m_minDist2 seems to be the pixel size to the power 4, so take the
|
||||
// square root of the square root.
|
||||
// Use abs() just in case m_minDist2 is negative, to avoid math errors.
|
||||
double pixelSize = sqrt(sqrt(abs(m_minDist2)));
|
||||
double maxDist = 5 * pixelSize;
|
||||
double maxDist2 = maxDist * maxDist;
|
||||
double checkDist = maxDist2 * 4;
|
||||
dist2 *= aff.det();
|
||||
|
||||
TStroke *stroke = vi->getStroke(strokeIndex);
|
||||
TThickPoint thickPoint = stroke->getThickPoint(w);
|
||||
double thickness = thickPoint.thick;
|
||||
double len = thickness * pixelSize * sqrt(m_viewAff.det());
|
||||
checkDist = std::max(checkDist, (len * len));
|
||||
double len2 = thickPoint.thick * thickPoint.thick * aff.det();
|
||||
double checkDist = std::max(m_minDist2, len2);
|
||||
if (dist2 < checkDist) picked = true;
|
||||
}
|
||||
} else if (TRasterImageP ri = img) {
|
||||
|
|
|
@ -406,7 +406,7 @@ public:
|
|||
TXsheet *xsh = xshHandle->getXsheet();
|
||||
TStageObject *obj = xsh->getStageObject(id);
|
||||
assert(obj);
|
||||
m_params = obj->getParams();
|
||||
m_params = obj->getParams();
|
||||
if (id.isColumn()) m_column = xsh->getColumn(id.getIndex());
|
||||
}
|
||||
|
||||
|
@ -432,6 +432,7 @@ public:
|
|||
linkedObj->setParent(m_objId);
|
||||
}
|
||||
m_xshHandle->notifyXsheetChanged();
|
||||
xsh->notifyStageObjectAdded(m_objId);
|
||||
}
|
||||
|
||||
void redo() const override {
|
||||
|
@ -518,6 +519,7 @@ public:
|
|||
terminalFxs->removeFx(m_notTerminalColumns[i]);
|
||||
|
||||
m_xshHandle->notifyXsheetChanged();
|
||||
xsh->notifyFxAdded(m_deletedFx);
|
||||
}
|
||||
|
||||
void redo() const override {
|
||||
|
@ -1192,9 +1194,8 @@ public:
|
|||
m_xshHandle->notifyXsheetChanged();
|
||||
}
|
||||
int getSize() const override {
|
||||
return sizeof(*this) +
|
||||
sizeof(TDoubleKeyframe) *
|
||||
(m_xKeyframes.size() + m_yKeyframes.size());
|
||||
return sizeof(*this) + sizeof(TDoubleKeyframe) *
|
||||
(m_xKeyframes.size() + m_yKeyframes.size());
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1456,7 +1457,7 @@ TStageObjectSpline *TStageObjectCmd::addNewSpline(TXsheetHandle *xshHandle,
|
|||
|
||||
TStageObjectId objId = objHandle->getObjectId();
|
||||
if (objId == TStageObjectId::NoneId) {
|
||||
int col = colHandle->getColumnIndex();
|
||||
int col = colHandle->getColumnIndex();
|
||||
if (col >= 0) objId = TStageObjectId::ColumnId(col);
|
||||
}
|
||||
if (objId != TStageObjectId::NoneId) {
|
||||
|
@ -1602,7 +1603,7 @@ void TStageObjectCmd::renameGroup(const QList<TStageObject *> objs,
|
|||
int i;
|
||||
for (i = 0; i < objs.size(); i++) {
|
||||
if (i == 0) oldName = objs[i]->getGroupName(fromEditor);
|
||||
int position = objs[i]->removeGroupName(fromEditor);
|
||||
int position = objs[i]->removeGroupName(fromEditor);
|
||||
objs[i]->setGroupName(name, position);
|
||||
positions.push_back(position);
|
||||
}
|
||||
|
|
|
@ -32,10 +32,14 @@
|
|||
#include "toonz/textureutils.h"
|
||||
#include "xshhandlemanager.h"
|
||||
#include "orientation.h"
|
||||
#include "toonz/expressionreferencemonitor.h"
|
||||
|
||||
#include "toonz/txsheet.h"
|
||||
#include "toonz/preferences.h"
|
||||
|
||||
// STD includes
|
||||
#include <set>
|
||||
|
||||
using namespace std;
|
||||
|
||||
DEFINE_CLASS_CODE(TXsheet, 18)
|
||||
|
@ -98,6 +102,8 @@ struct TXsheet::TXsheetImp {
|
|||
XshHandleManager *m_handleManager;
|
||||
ToonzScene *m_scene;
|
||||
|
||||
ExpressionReferenceMonitor *m_expRefMonitor;
|
||||
|
||||
public:
|
||||
TXsheetImp();
|
||||
~TXsheetImp();
|
||||
|
@ -150,7 +156,8 @@ TXsheet::TXsheetImp::TXsheetImp()
|
|||
, m_soloColumn(-1)
|
||||
, m_viewColumn(-1)
|
||||
, m_mixedSound(0)
|
||||
, m_scene(0) {
|
||||
, m_scene(0)
|
||||
, m_expRefMonitor(new ExpressionReferenceMonitor()) {
|
||||
initColumnFans();
|
||||
}
|
||||
|
||||
|
@ -189,7 +196,8 @@ TXsheet::TXsheet()
|
|||
, m_player(0)
|
||||
, m_imp(new TXsheet::TXsheetImp)
|
||||
, m_notes(new TXshNoteSet())
|
||||
, m_cameraColumnIndex(0) {
|
||||
, m_cameraColumnIndex(0)
|
||||
, m_observer(nullptr) {
|
||||
// extern TSyntax::Grammar *createXsheetGrammar(TXsheet*);
|
||||
m_soundProperties = new TXsheet::SoundProperties();
|
||||
m_imp->m_handleManager = new XshHandleManager(this);
|
||||
|
@ -1326,6 +1334,8 @@ void TXsheet::insertColumn(int col, TXshColumn *column) {
|
|||
columnFan.rollRightFoldedState(col,
|
||||
m_imp->m_columnSet.getColumnCount() - col);
|
||||
}
|
||||
|
||||
notify(TXsheetColumnChange(TXsheetColumnChange::Insert, col));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -1349,6 +1359,8 @@ void TXsheet::removeColumn(int col) {
|
|||
columnFan.rollLeftFoldedState(col,
|
||||
m_imp->m_columnSet.getColumnCount() - col);
|
||||
}
|
||||
|
||||
notify(TXsheetColumnChange(TXsheetColumnChange::Remove, col));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -1388,6 +1400,8 @@ void TXsheet::moveColumn(int srcIndex, int dstIndex) {
|
|||
columnFan.rollRightFoldedState(c0, c1 - c0 + 1);
|
||||
for (int c = c1 - 1; c >= c0; --c) m_imp->m_pegTree->swapColumns(c, c + 1);
|
||||
}
|
||||
|
||||
notify(TXsheetColumnChange(TXsheetColumnChange::Move, srcIndex, dstIndex));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -1792,3 +1806,29 @@ void TXsheet::autoInputCellNumbers(int increment, int interval, int step,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
||||
void TXsheet::setObserver(TXsheetColumnChangeObserver *observer) {
|
||||
m_observer = observer;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
||||
void TXsheet::notify(const TXsheetColumnChange &change) {
|
||||
if (m_observer) m_observer->onChange(change);
|
||||
}
|
||||
void TXsheet::notifyFxAdded(const std::vector<TFx *> &fxs) {
|
||||
if (m_observer) m_observer->onFxAdded(fxs);
|
||||
}
|
||||
void TXsheet::notifyStageObjectAdded(const TStageObjectId id) {
|
||||
if (m_observer) m_observer->onStageObjectAdded(id);
|
||||
}
|
||||
bool TXsheet::isReferenceManagementIgnored(TDoubleParam *param) {
|
||||
if (m_observer) return m_observer->isIgnored(param);
|
||||
return false;
|
||||
}
|
||||
ExpressionReferenceMonitor *TXsheet::getExpRefMonitor() const {
|
||||
return m_imp->m_expRefMonitor;
|
||||
}
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#include "texpression.h"
|
||||
#include "tparser.h"
|
||||
#include "tfx.h"
|
||||
#include "tzeraryfx.h"
|
||||
#include "tcolumnset.h"
|
||||
|
||||
#include "tw/stringtable.h"
|
||||
#include "tunit.h"
|
||||
|
@ -20,6 +22,9 @@
|
|||
#include "toonz/tstageobjectid.h"
|
||||
#include "toonz/tstageobject.h"
|
||||
#include "toonz/fxdag.h"
|
||||
#include "toonz/tstageobjecttree.h"
|
||||
#include "toonz/tcolumnfxset.h"
|
||||
#include "toonz/tcolumnfx.h"
|
||||
|
||||
// Boost includes
|
||||
#include "boost/noncopyable.hpp"
|
||||
|
@ -56,18 +61,51 @@ public:
|
|||
bool found() const { return m_found; }
|
||||
};
|
||||
|
||||
//===================================================================
|
||||
/*
|
||||
class ColumnReferenceFinder final : public TSyntax::CalculatorNodeVisitor {
|
||||
QSet<int> m_indices;
|
||||
|
||||
public:
|
||||
ColumnReferenceFinder() {}
|
||||
|
||||
void registerColumnIndex(int columnIndex) { m_indices.insert(columnIndex); }
|
||||
|
||||
QSet<int> indices() const { return m_indices; }
|
||||
};
|
||||
*/
|
||||
//===================================================================
|
||||
|
||||
class ParamReferenceFinder final : public TSyntax::CalculatorNodeVisitor {
|
||||
QSet<TDoubleParam *> m_refParams;
|
||||
QSet<int> m_columnIndices;
|
||||
|
||||
public:
|
||||
ParamReferenceFinder() {}
|
||||
|
||||
void registerRefParam(TDoubleParam *param) { m_refParams.insert(param); }
|
||||
void registerColumnIndex(int columnIndex) {
|
||||
m_columnIndices.insert(columnIndex);
|
||||
}
|
||||
|
||||
QSet<int> columnIndices() const { return m_columnIndices; }
|
||||
QSet<TDoubleParam *> refParams() const { return m_refParams; }
|
||||
};
|
||||
|
||||
//===================================================================
|
||||
//
|
||||
// Calculator Nodes
|
||||
//
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
class ParamCalculatorNode final : public CalculatorNode,
|
||||
public TParamObserver,
|
||||
public boost::noncopyable {
|
||||
TDoubleParamP m_param;
|
||||
class ParamCalculatorNode : public CalculatorNode,
|
||||
public TParamObserver,
|
||||
public boost::noncopyable {
|
||||
std::unique_ptr<CalculatorNode> m_frame;
|
||||
|
||||
protected:
|
||||
TDoubleParamP m_param;
|
||||
|
||||
public:
|
||||
ParamCalculatorNode(Calculator *calculator, const TDoubleParamP ¶m,
|
||||
std::unique_ptr<CalculatorNode> frame)
|
||||
|
@ -88,10 +126,18 @@ public:
|
|||
}
|
||||
|
||||
void accept(TSyntax::CalculatorNodeVisitor &visitor) override {
|
||||
ParamReferenceFinder *prf = dynamic_cast<ParamReferenceFinder *>(&visitor);
|
||||
if (prf) {
|
||||
prf->registerRefParam(m_param.getPointer());
|
||||
return;
|
||||
}
|
||||
|
||||
ParamDependencyFinder *pdf =
|
||||
dynamic_cast<ParamDependencyFinder *>(&visitor);
|
||||
pdf->check(m_param.getPointer());
|
||||
m_param->accept(visitor);
|
||||
if (pdf) {
|
||||
pdf->check(m_param.getPointer());
|
||||
if (!pdf->found()) m_param->accept(visitor);
|
||||
}
|
||||
}
|
||||
|
||||
void onChange(const TParamChange ¶mChange) override {
|
||||
|
@ -113,6 +159,36 @@ public:
|
|||
(*ot)->onChange(propagatedChange);
|
||||
}
|
||||
}
|
||||
|
||||
bool hasReference() const override { return true; }
|
||||
};
|
||||
|
||||
// ParamCalculatorNode subclass to monitor referenced columns
|
||||
class ColumnParamCalculatorNode final : public ParamCalculatorNode {
|
||||
int m_columnIndex;
|
||||
|
||||
public:
|
||||
ColumnParamCalculatorNode(Calculator *calculator, const TDoubleParamP ¶m,
|
||||
std::unique_ptr<CalculatorNode> frame,
|
||||
int columnIndex)
|
||||
: ParamCalculatorNode(calculator, param, std::move(frame))
|
||||
, m_columnIndex(columnIndex) {}
|
||||
|
||||
void accept(TSyntax::CalculatorNodeVisitor &visitor) override {
|
||||
ParamReferenceFinder *prf = dynamic_cast<ParamReferenceFinder *>(&visitor);
|
||||
if (prf) {
|
||||
prf->registerRefParam(m_param.getPointer());
|
||||
prf->registerColumnIndex(m_columnIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
ParamDependencyFinder *pdf =
|
||||
dynamic_cast<ParamDependencyFinder *>(&visitor);
|
||||
if (pdf) {
|
||||
pdf->check(m_param.getPointer());
|
||||
if (!pdf->found()) m_param->accept(visitor);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
|
@ -145,7 +221,12 @@ public:
|
|||
return d;
|
||||
}
|
||||
|
||||
void accept(TSyntax::CalculatorNodeVisitor &) override {}
|
||||
void accept(TSyntax::CalculatorNodeVisitor &visitor) override {
|
||||
ParamReferenceFinder *prf = dynamic_cast<ParamReferenceFinder *>(&visitor);
|
||||
if (prf) prf->registerColumnIndex(m_columnIndex);
|
||||
}
|
||||
|
||||
bool hasReference() const override { return true; }
|
||||
};
|
||||
|
||||
//===================================================================
|
||||
|
@ -191,6 +272,15 @@ public:
|
|||
return TStageObjectId::NoneId;
|
||||
}
|
||||
|
||||
TStageObjectId matchExistingObjectName(const Token &token) const {
|
||||
TStageObjectId objId = matchObjectName(token);
|
||||
if (objId != TStageObjectId::NoneId &&
|
||||
m_xsh->getStageObjectTree()->getStageObject(objId, false))
|
||||
return objId;
|
||||
else
|
||||
return TStageObjectId::NoneId;
|
||||
}
|
||||
|
||||
TStageObject::Channel matchChannelName(const Token &token) const {
|
||||
std::string s = toLower(token.getText());
|
||||
if (s == "ns" || s == "y")
|
||||
|
@ -227,7 +317,7 @@ public:
|
|||
const Token &token) const override {
|
||||
int i = (int)previousTokens.size();
|
||||
if (i == 0)
|
||||
return matchObjectName(token) != TStageObjectId::NoneId;
|
||||
return matchExistingObjectName(token) != TStageObjectId::NoneId;
|
||||
else if ((i == 1 && token.getText() == ".") ||
|
||||
(i == 3 && token.getText() == "(") ||
|
||||
(i == 5 && token.getText() == ")"))
|
||||
|
@ -237,7 +327,7 @@ public:
|
|||
return true;
|
||||
else
|
||||
return token.getText() == "cell" &&
|
||||
matchObjectName(previousTokens[0]).isColumn();
|
||||
matchExistingObjectName(previousTokens[0]).isColumn();
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
@ -276,12 +366,20 @@ public:
|
|||
stack.push_back(new XsheetDrawingCalculatorNode(calc, m_xsh, columnIndex,
|
||||
std::move(frameNode)));
|
||||
} else {
|
||||
TStageObject *object = m_xsh->getStageObject(objectId);
|
||||
// do not create object if it does not exist
|
||||
TStageObject *object =
|
||||
m_xsh->getStageObjectTree()->getStageObject(objectId, false);
|
||||
if (!object) return;
|
||||
TStageObject::Channel channelName = matchChannelName(tokens[2]);
|
||||
TDoubleParam *channel = object->getParam(channelName);
|
||||
if (channel)
|
||||
stack.push_back(
|
||||
new ParamCalculatorNode(calc, channel, std::move(frameNode)));
|
||||
if (channel) {
|
||||
if (objectId.isColumn())
|
||||
stack.push_back(new ColumnParamCalculatorNode(
|
||||
calc, channel, std::move(frameNode), objectId.getIndex()));
|
||||
else
|
||||
stack.push_back(
|
||||
new ParamCalculatorNode(calc, channel, std::move(frameNode)));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -295,7 +393,20 @@ public:
|
|||
FxReferencePattern(TXsheet *xsh) : m_xsh(xsh) {}
|
||||
|
||||
TFx *getFx(const Token &token) const {
|
||||
return m_xsh->getFxDag()->getFxById(::to_wstring(toLower(token.getText())));
|
||||
TFx *fx =
|
||||
m_xsh->getFxDag()->getFxById(::to_wstring(toLower(token.getText())));
|
||||
// removed fx cannot be referenced
|
||||
if (!fx)
|
||||
return nullptr;
|
||||
else if (fx->isZerary()) {
|
||||
TZeraryFx *zFx = dynamic_cast<TZeraryFx *>(fx);
|
||||
// For now we cannot use zFx->getColumnFx()->getColumnIndex() < 0 to check
|
||||
// existence of the column. See a comment in tcolumnset.h for details.
|
||||
if (!zFx || !zFx->getColumnFx()->getXshColumn()->inColumnsSet())
|
||||
return nullptr;
|
||||
} else if (!m_xsh->getFxDag()->getInternalFxs()->containsFx(fx))
|
||||
return nullptr;
|
||||
return fx;
|
||||
}
|
||||
TParam *getParam(const TFx *fx, const Token &token) const {
|
||||
int i;
|
||||
|
@ -607,3 +718,11 @@ bool dependsOn(TDoubleParam *param, TDoubleParam *possiblyDependentParam) {
|
|||
param->accept(pdf);
|
||||
return pdf.found();
|
||||
}
|
||||
|
||||
void referenceParams(TExpression &expr, QSet<int> &columnIndices,
|
||||
QSet<TDoubleParam *> ¶ms) {
|
||||
ParamReferenceFinder prf;
|
||||
expr.accept(prf);
|
||||
columnIndices = prf.columnIndices();
|
||||
params = prf.refParams();
|
||||
}
|
||||
|
|
82
toonz/sources/toonzqt/Resources/paramignored_off.svg
Normal file
82
toonz/sources/toonzqt/Resources/paramignored_off.svg
Normal file
|
@ -0,0 +1,82 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 21.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="svg2"
|
||||
inkscape:version="0.92.1 r15371"
|
||||
sodipodi:docname="paramignored_off.svg"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 21 17"
|
||||
style="enable-background:new 0 0 21 17;"
|
||||
xml:space="preserve"><metadata
|
||||
id="metadata13"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs11"><linearGradient
|
||||
id="linearGradient4558"
|
||||
osb:paint="solid"><stop
|
||||
style="stop-color:#4b4b4b;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop4556" /></linearGradient></defs><style
|
||||
type="text/css"
|
||||
id="style2">
|
||||
.st0{fill:none;}
|
||||
.st1{fill:none;stroke:#6F6C50;stroke-width:2;stroke-linecap:square;stroke-miterlimit:1.5;}
|
||||
.st2{fill:#FFF082;}
|
||||
.st3{stroke:#000000;stroke-width:0.5;stroke-linejoin:round;stroke-miterlimit:1.4142;}
|
||||
</style><sodipodi:namedview
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
id="namedview15"
|
||||
inkscape:current-layer="svg2"
|
||||
inkscape:cx="26.553329"
|
||||
inkscape:cy="7.6715202"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-height="851"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:window-width="1440"
|
||||
inkscape:window-x="126"
|
||||
inkscape:window-y="54"
|
||||
inkscape:zoom="11.313709"
|
||||
objecttolerance="10"
|
||||
pagecolor="#ffffff"
|
||||
showgrid="true"><inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid4490" /></sodipodi:namedview><rect
|
||||
id="rect5"
|
||||
y="0"
|
||||
class="st0"
|
||||
width="21"
|
||||
height="17" /><path
|
||||
style="opacity:1;vector-effect:none;fill:#faafb5;fill-opacity:1;stroke-width:0.02723992;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 16.178576,13 c -0.08036,0.139006 -0.230014,0.225165 -0.390893,0.225165 H 5.2121385 c -0.1604971,0 -0.310371,-0.08616 -0.3903208,-0.225574 -0.080742,-0.139196 -0.081149,-0.311761 -3.808e-4,-0.450766 L 10.109304,3.3896748 c 0.08017,-0.139005 0.229796,-0.2253832 0.390893,-0.2253832 0.160716,0 0.310154,0.086374 0.390511,0.225602 l 5.287868,9.1587684 c 0.08036,0.139168 0.08036,0.312142 0,0.451338 z"
|
||||
id="path6-3"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
id="path4"
|
||||
style="fill:#606060;stroke-width:0.02539061;fill-opacity:1"
|
||||
d="m 10.50018,10.762063 c -0.426156,0 -0.7721536,0.345642 -0.7721536,0.771798 0,0.426334 0.3459976,0.772001 0.7721536,0.772001 0.426156,0 0.771799,-0.345667 0.771799,-0.772001 2.5e-5,-0.426156 -0.345617,-0.771798 -0.771799,-0.771798 z"
|
||||
class="st0"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
id="path6"
|
||||
style="fill:#606060;stroke-width:0.02539061;font-variant-east_asian:normal;opacity:1;vector-effect:none;fill-opacity:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="M 16.824727,12.031745 11.636715,3.0457546 C 11.403045,2.6409267 10.96752,2.3894835 10.499799,2.3894835 c -0.467365,0 -0.9024835,0.2514686 -1.1361533,0.6562711 L 4.1752523,12.031364 c -0.2336698,0.404803 -0.2336698,0.90774 0,1.312543 C 4.4089475,13.748709 4.8444472,14 5.3118122,14 H 15.688193 c 0.467339,0 0.902864,-0.251291 1.136534,-0.656093 0.233695,-0.404803 0.233695,-0.90774 0,-1.312162 z m -1.031671,0.642027 c -0.0749,0.129569 -0.214398,0.209879 -0.364355,0.209879 H 5.5711265 c -0.1496015,0 -0.2893006,-0.08031 -0.3638221,-0.21026 -0.075258,-0.129746 -0.075639,-0.290595 -3.555e-4,-0.420163 L 10.135825,3.7158889 C 10.21055,3.5863207 10.35002,3.505807 10.50018,3.505807 c 0.149805,0 0.289098,0.080514 0.364,0.2102851 l 4.928876,8.5369829 c 0.0749,0.129721 0.0749,0.290951 0,0.420697 z"
|
||||
class="st0"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
id="path8"
|
||||
style="fill:#606060;stroke-width:0.02539061;fill-opacity:1"
|
||||
d="m 10.50018,5.5723742 c -0.426156,0 -0.7721536,0.3456423 -0.7721536,0.7720015 l 0.2965626,3.4908788 c 0,0.2626915 0.212722,0.4754135 0.475591,0.4754135 0.262488,0 0.475592,-0.212722 0.475592,-0.4754135 L 11.271979,6.3443757 C 11.272004,5.9179912 10.926362,5.5723742 10.50018,5.5723742 Z"
|
||||
class="st0"
|
||||
inkscape:connector-curvature="0" /></svg>
|
After Width: | Height: | Size: 4.8 KiB |
82
toonz/sources/toonzqt/Resources/paramignored_on.svg
Normal file
82
toonz/sources/toonzqt/Resources/paramignored_on.svg
Normal file
|
@ -0,0 +1,82 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 21.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
|
||||
<svg
|
||||
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
id="svg2"
|
||||
inkscape:version="0.92.1 r15371"
|
||||
sodipodi:docname="paramignored_on.svg"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 21 17"
|
||||
style="enable-background:new 0 0 21 17;"
|
||||
xml:space="preserve"><metadata
|
||||
id="metadata13"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs11"><linearGradient
|
||||
id="linearGradient4558"
|
||||
osb:paint="solid"><stop
|
||||
style="stop-color:#4b4b4b;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop4556" /></linearGradient></defs><style
|
||||
type="text/css"
|
||||
id="style2">
|
||||
.st0{fill:none;}
|
||||
.st1{fill:none;stroke:#6F6C50;stroke-width:2;stroke-linecap:square;stroke-miterlimit:1.5;}
|
||||
.st2{fill:#FFF082;}
|
||||
.st3{stroke:#000000;stroke-width:0.5;stroke-linejoin:round;stroke-miterlimit:1.4142;}
|
||||
</style><sodipodi:namedview
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
id="namedview15"
|
||||
inkscape:current-layer="svg2"
|
||||
inkscape:cx="26.553329"
|
||||
inkscape:cy="7.6715202"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-height="851"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:window-width="1440"
|
||||
inkscape:window-x="126"
|
||||
inkscape:window-y="54"
|
||||
inkscape:zoom="11.313709"
|
||||
objecttolerance="10"
|
||||
pagecolor="#ffffff"
|
||||
showgrid="true"><inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid4490" /></sodipodi:namedview><rect
|
||||
id="rect5"
|
||||
y="0"
|
||||
class="st0"
|
||||
width="21"
|
||||
height="17" /><path
|
||||
style="opacity:1;vector-effect:none;fill:#fc5b68;fill-opacity:1;stroke-width:0.02723992;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 16.178576,13 c -0.08036,0.139006 -0.230014,0.225165 -0.390893,0.225165 H 5.2121385 c -0.1604971,0 -0.310371,-0.08616 -0.3903208,-0.225574 -0.080742,-0.139196 -0.081149,-0.311761 -3.808e-4,-0.450766 L 10.109304,3.3896748 c 0.08017,-0.139005 0.229796,-0.2253832 0.390893,-0.2253832 0.160716,0 0.310154,0.086374 0.390511,0.225602 l 5.287868,9.1587684 c 0.08036,0.139168 0.08036,0.312142 0,0.451338 z"
|
||||
id="path6-3"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
id="path4"
|
||||
style="fill:#000000;stroke-width:0.02539061;fill-opacity:1"
|
||||
d="m 10.50018,10.762063 c -0.426156,0 -0.7721536,0.345642 -0.7721536,0.771798 0,0.426334 0.3459976,0.772001 0.7721536,0.772001 0.426156,0 0.771799,-0.345667 0.771799,-0.772001 2.5e-5,-0.426156 -0.345617,-0.771798 -0.771799,-0.771798 z"
|
||||
class="st0"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
id="path6"
|
||||
style="fill:#89363f;stroke-width:0.02539061;font-variant-east_asian:normal;opacity:1;vector-effect:none;fill-opacity:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="M 16.824727,12.031745 11.636715,3.0457546 C 11.403045,2.6409267 10.96752,2.3894835 10.499799,2.3894835 c -0.467365,0 -0.9024835,0.2514686 -1.1361533,0.6562711 L 4.1752523,12.031364 c -0.2336698,0.404803 -0.2336698,0.90774 0,1.312543 C 4.4089475,13.748709 4.8444472,14 5.3118122,14 H 15.688193 c 0.467339,0 0.902864,-0.251291 1.136534,-0.656093 0.233695,-0.404803 0.233695,-0.90774 0,-1.312162 z m -1.031671,0.642027 c -0.0749,0.129569 -0.214398,0.209879 -0.364355,0.209879 H 5.5711265 c -0.1496015,0 -0.2893006,-0.08031 -0.3638221,-0.21026 -0.075258,-0.129746 -0.075639,-0.290595 -3.555e-4,-0.420163 L 10.135825,3.7158889 C 10.21055,3.5863207 10.35002,3.505807 10.50018,3.505807 c 0.149805,0 0.289098,0.080514 0.364,0.2102851 l 4.928876,8.5369829 c 0.0749,0.129721 0.0749,0.290951 0,0.420697 z"
|
||||
class="st0"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
id="path8"
|
||||
style="fill:#000000;stroke-width:0.02539061;fill-opacity:1"
|
||||
d="m 10.50018,5.5723742 c -0.426156,0 -0.7721536,0.3456423 -0.7721536,0.7720015 l 0.2965626,3.4908788 c 0,0.2626915 0.212722,0.4754135 0.475591,0.4754135 0.262488,0 0.475592,-0.212722 0.475592,-0.4754135 L 11.271979,6.3443757 C 11.272004,5.9179912 10.926362,5.5723742 10.50018,5.5723742 Z"
|
||||
class="st0"
|
||||
inkscape:connector-curvature="0" /></svg>
|
After Width: | Height: | Size: 4.8 KiB |
|
@ -591,9 +591,14 @@ void CameraSettingsWidget::setFields(const TCamera *camera) {
|
|||
updatePresetListOm();
|
||||
}
|
||||
|
||||
void CameraSettingsWidget::getFields(TCamera *camera) {
|
||||
bool CameraSettingsWidget::getFields(TCamera *camera) {
|
||||
TDimensionD old_sz = camera->getSize();
|
||||
TDimension old_res = camera->getRes();
|
||||
|
||||
if (old_sz == getSize() && old_res == getRes()) return false;
|
||||
camera->setSize(getSize());
|
||||
camera->setRes(getRes());
|
||||
return true;
|
||||
}
|
||||
|
||||
TDimensionD CameraSettingsWidget::getSize() const {
|
||||
|
@ -954,8 +959,8 @@ double CameraSettingsWidget::aspectRatioStringToValue(const QString &s) {
|
|||
}
|
||||
int i = s.indexOf("/");
|
||||
if (i <= 0 || i + 1 >= s.length()) return s.toDouble();
|
||||
int num = s.left(i).toInt();
|
||||
int den = s.mid(i + 1).toInt();
|
||||
int num = s.left(i).toInt();
|
||||
int den = s.mid(i + 1).toInt();
|
||||
if (den <= 0) den = 1;
|
||||
return (double)num / (double)den;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#include "toonz/preferences.h"
|
||||
#include "toonz/toonzfolders.h"
|
||||
#include "toonz/tstageobject.h"
|
||||
#include "toonz/txsheethandle.h"
|
||||
#include "toonz/txsheet.h"
|
||||
|
||||
// TnzBase includes
|
||||
#include "tunit.h"
|
||||
|
@ -360,6 +362,14 @@ void FunctionSheetColumnHeadViewer::paintEvent(QPaintEvent *e) {
|
|||
Qt::TextWrapAnywhere | Qt::AlignLeft | Qt::AlignVCenter,
|
||||
text);
|
||||
|
||||
// warning of losing expression reference
|
||||
TXsheet *xsh = m_sheet->getViewer()->getXsheetHandle()->getXsheet();
|
||||
if (xsh->isReferenceManagementIgnored(channel->getParam())) {
|
||||
static QIcon paramIgnoredIcon(":Resources/paramignored_on.svg");
|
||||
painter.drawPixmap(QPoint(x0 + 30, y1 + 20),
|
||||
paramIgnoredIcon.pixmap(21, 17));
|
||||
}
|
||||
|
||||
// group name
|
||||
if (firstGroupColumn) {
|
||||
int tmpwidth = (lastGroupColumn) ? width : width * 2;
|
||||
|
@ -389,13 +399,23 @@ void FunctionSheetColumnHeadViewer::mouseMoveEvent(QMouseEvent *e) {
|
|||
Qt::DropAction dropAction = drag->exec();
|
||||
return;
|
||||
}
|
||||
|
||||
// get the column under the cursor
|
||||
int col = getViewer()->xyToPosition(e->pos()).layer();
|
||||
FunctionTreeModel::Channel *channel = m_sheet->getChannel(col);
|
||||
if (!channel) {
|
||||
setToolTip(QString(""));
|
||||
} else
|
||||
setToolTip(channel->getExprRefName());
|
||||
} else {
|
||||
QString tooltip = channel->getExprRefName();
|
||||
TXsheet *xsh = m_sheet->getViewer()->getXsheetHandle()->getXsheet();
|
||||
if (xsh->isReferenceManagementIgnored(channel->getParam()))
|
||||
tooltip +=
|
||||
"\n" + tr("Some key(s) in this parameter loses original reference in "
|
||||
"expression.\nManually changing any keyframe will clear "
|
||||
"the warning.");
|
||||
|
||||
setToolTip(tooltip);
|
||||
}
|
||||
|
||||
// modify selected channel by left dragging
|
||||
if (m_clickedColumn >= 0 && channel && e->buttons() & Qt::LeftButton) {
|
||||
|
@ -616,16 +636,25 @@ void FunctionSheetCellViewer::drawCells(QPainter &painter, int r0, int c0,
|
|||
QColor KeyFrameColor = getViewer()->getKeyFrameColor();
|
||||
QColor KeyFrameBorderColor = getViewer()->getKeyFrameBorderColor();
|
||||
QColor SelectedKeyFrameColor = getViewer()->getSelectedKeyFrameColor();
|
||||
QColor IgnoredKeyFrameColor = getViewer()->getIgnoredKeyFrameColor();
|
||||
QColor SelectedIgnoredKeyFrameColor =
|
||||
getViewer()->getSelectedIgnoredKeyFrameColor();
|
||||
// inbetween
|
||||
QColor InBetweenColor = getViewer()->getInBetweenColor();
|
||||
QColor InBetweenBorderColor = getViewer()->getInBetweenBorderColor();
|
||||
QColor SelectedInBetweenColor = getViewer()->getSelectedInBetweenColor();
|
||||
QColor IgnoredInBetweenColor = getViewer()->getIgnoredInBetweenColor();
|
||||
QColor SelectedIgnoredInBetweenColor =
|
||||
getViewer()->getSelectedIgnoredInBetweenColor();
|
||||
|
||||
// empty cells
|
||||
QColor SelectedEmptyColor = getViewer()->getSelectedEmptyColor();
|
||||
// empty cells in scene frame range
|
||||
QColor SelectedSceneRangeEmptyColor =
|
||||
getViewer()->getSelectedSceneRangeEmptyColor();
|
||||
|
||||
TXsheet *xsh = m_sheet->getViewer()->getXsheetHandle()->getXsheet();
|
||||
|
||||
// top and bottom pos
|
||||
int y0 = getViewer()->rowToY(r0);
|
||||
int y1 = getViewer()->rowToY(r1 + 1) - 1;
|
||||
|
@ -656,6 +685,8 @@ void FunctionSheetCellViewer::drawCells(QPainter &painter, int r0, int c0,
|
|||
bool isParamCycled = curve->isCycleEnabled();
|
||||
int rowCount = getViewer()->getRowCount();
|
||||
|
||||
bool isRefMngIgnored = xsh->isReferenceManagementIgnored(curve);
|
||||
|
||||
// draw each cell
|
||||
for (int row = r0; row <= r1; row++) {
|
||||
int ya = m_sheet->rowToY(row);
|
||||
|
@ -676,10 +707,18 @@ void FunctionSheetCellViewer::drawCells(QPainter &painter, int r0, int c0,
|
|||
/*--- キーフレーム間の範囲だけ色をつける ---*/
|
||||
if (kr0 <= row && row <= kr1) {
|
||||
if (curve->isKeyframe(row)) {
|
||||
cellColor = (isSelected) ? SelectedKeyFrameColor : KeyFrameColor;
|
||||
cellColor =
|
||||
(isRefMngIgnored)
|
||||
? ((isSelected) ? SelectedIgnoredKeyFrameColor
|
||||
: IgnoredKeyFrameColor)
|
||||
: ((isSelected) ? SelectedKeyFrameColor : KeyFrameColor);
|
||||
borderColor = KeyFrameBorderColor;
|
||||
} else {
|
||||
cellColor = (isSelected) ? SelectedInBetweenColor : InBetweenColor;
|
||||
cellColor =
|
||||
(isRefMngIgnored)
|
||||
? ((isSelected) ? SelectedIgnoredInBetweenColor
|
||||
: IgnoredInBetweenColor)
|
||||
: ((isSelected) ? SelectedInBetweenColor : InBetweenColor);
|
||||
borderColor = InBetweenBorderColor;
|
||||
|
||||
// when the inbetween values are hidden, change the cell colors to
|
||||
|
|
|
@ -132,29 +132,45 @@ bool FunctionTreeModel::ChannelGroup::isAnimated() const {
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool FunctionTreeModel::ChannelGroup::isIgnored() const {
|
||||
// Same for the ignored ones, show warning icon if any of its children is.
|
||||
int c, childCount = getChildCount();
|
||||
for (c = 0; c != childCount; ++c)
|
||||
if (static_cast<Item *>(getChild(c))->isIgnored()) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
QVariant FunctionTreeModel::ChannelGroup::data(int role) const {
|
||||
if (role == Qt::DisplayRole)
|
||||
return getLongName();
|
||||
else if (role == Qt::DecorationRole) {
|
||||
bool animated = isAnimated();
|
||||
bool active = isActive();
|
||||
bool ignored = (animated) ? isIgnored() : false;
|
||||
|
||||
if (active) {
|
||||
static QIcon folderAnimOpen(createQIcon("folder_anim_on", true));
|
||||
static QIcon folderAnimClose(createQIcon("folder_anim", true));
|
||||
static QIcon folderOpen(createQIcon("folder_on", true));
|
||||
static QIcon folderClose(createQIcon("folder", true));
|
||||
static QIcon ignoredOn(":Resources/paramignored_on.svg");
|
||||
|
||||
return animated ? isOpen() ? folderAnimOpen : folderAnimClose
|
||||
: isOpen() ? folderOpen : folderClose;
|
||||
return animated ? (isOpen() ? folderAnimOpen
|
||||
: (ignored ? ignoredOn : folderAnimClose))
|
||||
: (isOpen() ? folderOpen : folderClose);
|
||||
} else {
|
||||
static QIcon folderAnimOpen(createQIcon("folder_anim_inactive_on", true));
|
||||
static QIcon folderAnimClose(createQIcon("folder_anim_inactive", true));
|
||||
static QIcon folderOpen(createQIcon("folder_inactive_on", true));
|
||||
static QIcon folderClose(createQIcon("folder_inactive", true));
|
||||
static QIcon ignoredOff(":Resources/paramignored_off.svg");
|
||||
|
||||
return animated ? isOpen() ? folderAnimOpen : folderAnimClose
|
||||
: isOpen() ? folderOpen : folderClose;
|
||||
return animated ? (isOpen() ? folderAnimOpen
|
||||
: (ignored ? ignoredOff : folderAnimClose))
|
||||
: (isOpen() ? folderOpen : folderClose);
|
||||
}
|
||||
} else
|
||||
return Item::data(role);
|
||||
|
@ -352,22 +368,27 @@ QVariant FxChannelGroup::data(int role) const {
|
|||
isOneChildActive = true;
|
||||
break;
|
||||
}
|
||||
bool ignored = (isAnimated) ? isIgnored() : false;
|
||||
if (isOneChildActive) {
|
||||
static QIcon folderAnimOpen(createQIcon("folder_anim_on", true));
|
||||
static QIcon folderAnimClose(createQIcon("folder_anim", true));
|
||||
static QIcon folderOpen(createQIcon("folder_on", true));
|
||||
static QIcon folderClose(createQIcon("folder", true));
|
||||
static QIcon ignoredOn(":Resources/paramignored_on.svg");
|
||||
|
||||
return isAnimated ? isOpen() ? folderAnimOpen : folderAnimClose
|
||||
: isOpen() ? folderOpen : folderClose;
|
||||
return isAnimated ? (isOpen() ? folderAnimOpen
|
||||
: (ignored ? ignoredOn : folderAnimClose))
|
||||
: (isOpen() ? folderOpen : folderClose);
|
||||
} else {
|
||||
static QIcon folderAnimOpen(createQIcon("folder_anim_inactive_on", true));
|
||||
static QIcon folderAnimClose(createQIcon("folder_anim_inactive", true));
|
||||
static QIcon folderOpen(createQIcon("folder_inactive_on", true));
|
||||
static QIcon folderClose(createQIcon("folder_inactive", true));
|
||||
static QIcon ignoredOff(":Resources/paramignored_off.svg");
|
||||
|
||||
return isAnimated ? isOpen() ? folderAnimOpen : folderAnimClose
|
||||
: isOpen() ? folderOpen : folderClose;
|
||||
return isAnimated ? (isOpen() ? folderAnimOpen
|
||||
: (ignored ? ignoredOff : folderAnimClose))
|
||||
: (isOpen() ? folderOpen : folderClose);
|
||||
}
|
||||
} else if (role == Qt::DisplayRole) {
|
||||
std::wstring name = m_fx->getName();
|
||||
|
@ -561,8 +582,24 @@ bool FunctionTreeModel::Channel::isAnimated() const {
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool FunctionTreeModel::Channel::isIgnored() const {
|
||||
if (!isAnimated()) return false;
|
||||
TDoubleParam *dp = dynamic_cast<TDoubleParam *>(m_param.getPointer());
|
||||
if (!dp) return false;
|
||||
FunctionTreeView *view = dynamic_cast<FunctionTreeView *>(m_model->m_view);
|
||||
if (!view) return false;
|
||||
return view->getXsheetHandle()->getXsheet()->isReferenceManagementIgnored(dp);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
QVariant FunctionTreeModel::Channel::data(int role) const {
|
||||
if (role == Qt::DecorationRole) {
|
||||
static QIcon paramIgnoredOn(":Resources/paramignored_on.svg");
|
||||
static QIcon paramIgnoredOff(":Resources/paramignored_off.svg");
|
||||
|
||||
if (isIgnored()) return isActive() ? paramIgnoredOn : paramIgnoredOff;
|
||||
|
||||
QPixmap pixmap(10, 10);
|
||||
QColor color;
|
||||
QString name = getShortName();
|
||||
|
@ -620,6 +657,20 @@ QVariant FunctionTreeModel::Channel::data(int role) const {
|
|||
#endif
|
||||
return (isCurrent()) ? view->getViewer()->getCurrentTextColor()
|
||||
: view->getTextColor();
|
||||
} else if (role == Qt::ToolTipRole) {
|
||||
if (m_param->hasKeyframes()) {
|
||||
TDoubleParam *dp = dynamic_cast<TDoubleParam *>(m_param.getPointer());
|
||||
FunctionTreeView *view =
|
||||
dynamic_cast<FunctionTreeView *>(m_model->m_view);
|
||||
if (dp && view &&
|
||||
view->getXsheetHandle()->getXsheet()->isReferenceManagementIgnored(
|
||||
dp))
|
||||
return tr(
|
||||
"Some key(s) in this parameter loses original reference in "
|
||||
"expression.\nManually changing any keyframe will clear the "
|
||||
"warning.");
|
||||
}
|
||||
return TreeModel::Item::data(role);
|
||||
} else
|
||||
return TreeModel::Item::data(role);
|
||||
}
|
||||
|
@ -638,7 +689,7 @@ QString FunctionTreeModel::Channel::getShortName() const {
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
QString FunctionTreeModel::Channel::getLongName() const {
|
||||
QString name = getShortName();
|
||||
QString name = getShortName();
|
||||
if (getChannelGroup()) name = getChannelGroup()->getLongName() + " " + name;
|
||||
return name;
|
||||
}
|
||||
|
@ -1117,7 +1168,7 @@ void FunctionTreeModel::addChannels(TFx *fx, ChannelGroup *groupItem,
|
|||
|
||||
std::wstring fxId = L"";
|
||||
TMacroFx *macro = dynamic_cast<TMacroFx *>(fxItem->getFx());
|
||||
if (macro) fxId = fx->getFxId();
|
||||
if (macro) fxId = fx->getFxId();
|
||||
|
||||
const std::string ¶mNamePref = fx->getFxType() + ".";
|
||||
|
||||
|
@ -1263,7 +1314,7 @@ void FunctionTreeModel::resetAll() {
|
|||
|
||||
void FunctionTreeModel::setCurrentFx(TFx *fx) {
|
||||
TZeraryColumnFx *zcfx = dynamic_cast<TZeraryColumnFx *>(fx);
|
||||
if (zcfx) fx = zcfx->getZeraryFx();
|
||||
if (zcfx) fx = zcfx->getZeraryFx();
|
||||
if (fx != m_currentFx) {
|
||||
if (fx) fx->addRef();
|
||||
if (m_currentFx) m_currentFx->release();
|
||||
|
|
|
@ -171,11 +171,11 @@ FunctionViewer::FunctionViewer(QWidget *parent, Qt::WFlags flags)
|
|||
bool ret = true;
|
||||
ret = ret && connect(m_toolbar, SIGNAL(numericalColumnToggled()), this,
|
||||
SLOT(toggleMode()));
|
||||
ret = ret && connect(ftModel, SIGNAL(activeChannelsChanged()),
|
||||
ret = ret && connect(ftModel, SIGNAL(activeChannelsChanged()),
|
||||
m_functionGraph, SLOT(update()));
|
||||
ret = ret && connect(ftModel, SIGNAL(activeChannelsChanged()),
|
||||
ret = ret && connect(ftModel, SIGNAL(activeChannelsChanged()),
|
||||
m_numericalColumns, SLOT(updateAll()));
|
||||
ret = ret && connect(ftModel, SIGNAL(curveChanged(bool)), m_treeView,
|
||||
ret = ret && connect(ftModel, SIGNAL(curveChanged(bool)), m_treeView,
|
||||
SLOT(update()));
|
||||
ret = ret && connect(ftModel, SIGNAL(curveChanged(bool)), m_functionGraph,
|
||||
SLOT(update()));
|
||||
|
@ -388,6 +388,7 @@ void FunctionViewer::setXsheetHandle(TXsheetHandle *xshHandle) {
|
|||
|
||||
m_xshHandle = xshHandle;
|
||||
m_segmentViewer->setXsheetHandle(xshHandle);
|
||||
m_treeView->setXsheetHandle(xshHandle);
|
||||
|
||||
if (m_xshHandle && isVisible()) {
|
||||
TXsheet *xsh = m_xshHandle->getXsheet();
|
||||
|
@ -610,7 +611,7 @@ void FunctionViewer::onStageObjectChanged(bool isDragging) {
|
|||
void FunctionViewer::onFxSwitched() {
|
||||
TFx *fx = m_fxHandle->getFx();
|
||||
TZeraryColumnFx *zfx = dynamic_cast<TZeraryColumnFx *>(fx);
|
||||
if (zfx) fx = zfx->getZeraryFx();
|
||||
if (zfx) fx = zfx->getZeraryFx();
|
||||
static_cast<FunctionTreeModel *>(m_treeView->model())->setCurrentFx(fx);
|
||||
m_treeView->updateAll();
|
||||
m_functionGraph->update();
|
||||
|
|
|
@ -35,7 +35,7 @@ bool canGroup(TFx *fx) {
|
|||
TOutputFx *ofx = dynamic_cast<TOutputFx *>(fx);
|
||||
return (!xfx && !ofx);
|
||||
}
|
||||
}
|
||||
} // namespace
|
||||
|
||||
//=========================================================
|
||||
//
|
||||
|
@ -156,10 +156,11 @@ bool FxSelection::isSelected(SchematicLink *link) {
|
|||
//---------------------------------------------------------
|
||||
|
||||
void FxSelection::deleteSelection() {
|
||||
std::list<TFxP, std::allocator<TFxP>> fxList = m_selectedFxs.toStdList();
|
||||
TFxCommand::deleteSelection(fxList, m_selectedLinks.toStdList(),
|
||||
m_selectedColIndexes.toStdList(), m_xshHandle,
|
||||
m_fxHandle);
|
||||
emit doDelete();
|
||||
// std::list<TFxP, std::allocator<TFxP>> fxList = m_selectedFxs.toStdList();
|
||||
// TFxCommand::deleteSelection(fxList, m_selectedLinks.toStdList(),
|
||||
// m_selectedColIndexes.toStdList(), m_xshHandle,
|
||||
// m_fxHandle);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
@ -524,8 +525,8 @@ bool FxSelection::isConnected() {
|
|||
TColumnFx *cfx = dynamic_cast<TColumnFx *>(selectedFx);
|
||||
if (!cfx && !internalFxs->containsFx(selectedFx)) return false;
|
||||
TZeraryColumnFx *zfx = dynamic_cast<TZeraryColumnFx *>(selectedFx);
|
||||
if (zfx) selectedFx = zfx->getZeraryFx();
|
||||
connected = connected && visitedFxs.contains(selectedFx);
|
||||
if (zfx) selectedFx = zfx->getZeraryFx();
|
||||
connected = connected && visitedFxs.contains(selectedFx);
|
||||
}
|
||||
return connected;
|
||||
}
|
||||
|
@ -535,14 +536,14 @@ bool FxSelection::isConnected() {
|
|||
void FxSelection::visitFx(TFx *fx, QList<TFx *> &visitedFxs) {
|
||||
if (visitedFxs.contains(fx)) return;
|
||||
TZeraryColumnFx *zfx = dynamic_cast<TZeraryColumnFx *>(fx);
|
||||
if (zfx) fx = zfx->getZeraryFx();
|
||||
if (zfx) fx = zfx->getZeraryFx();
|
||||
if (!canGroup(fx)) return;
|
||||
visitedFxs.append(fx);
|
||||
int i;
|
||||
for (i = 0; i < fx->getInputPortCount(); i++) {
|
||||
TFx *inputFx = fx->getInputPort(i)->getFx();
|
||||
TZeraryColumnFx *onputZFx = dynamic_cast<TZeraryColumnFx *>(inputFx);
|
||||
if (onputZFx) inputFx = onputZFx->getZeraryFx();
|
||||
if (onputZFx) inputFx = onputZFx->getZeraryFx();
|
||||
if (!inputFx) continue;
|
||||
bool canBeGrouped = !inputFx->getAttributes()->isGrouped() ||
|
||||
(inputFx->getAttributes()->getEditingGroupId() ==
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
#include "toonzqt/gutil.h"
|
||||
#include "toonzqt/imageutils.h"
|
||||
#include "toonzqt/dvscrollwidget.h"
|
||||
#include "toonzqt/fxselection.h"
|
||||
#include "stageobjectselection.h"
|
||||
|
||||
// TnzLib includes
|
||||
#include "toonz/txsheethandle.h"
|
||||
|
@ -397,12 +399,12 @@ void SchematicSceneViewer::wheelEvent(QWheelEvent *me) {
|
|||
|
||||
default: // Qt::MouseEventSynthesizedByQt,
|
||||
// Qt::MouseEventSynthesizedByApplication
|
||||
{
|
||||
std::cout << "not supported event: Qt::MouseEventSynthesizedByQt, "
|
||||
"Qt::MouseEventSynthesizedByApplication"
|
||||
<< std::endl;
|
||||
break;
|
||||
}
|
||||
{
|
||||
std::cout << "not supported event: Qt::MouseEventSynthesizedByQt, "
|
||||
"Qt::MouseEventSynthesizedByApplication"
|
||||
<< std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
} // end switch
|
||||
|
||||
|
@ -435,8 +437,9 @@ void SchematicSceneViewer::zoomQt(bool zoomin, bool resetView) {
|
|||
#endif
|
||||
if ((scale2 < 100000 || !zoomin) && (scale2 > 0.001 * 0.05 || zoomin)) {
|
||||
double oldZoomScale = sqrt(scale2);
|
||||
double zoomScale = resetView ? 1 : ImageUtils::getQuantizedZoomFactor(
|
||||
oldZoomScale, zoomin);
|
||||
double zoomScale =
|
||||
resetView ? 1
|
||||
: ImageUtils::getQuantizedZoomFactor(oldZoomScale, zoomin);
|
||||
QMatrix scale =
|
||||
QMatrix().scale(zoomScale / oldZoomScale, zoomScale / oldZoomScale);
|
||||
|
||||
|
@ -701,10 +704,9 @@ bool SchematicSceneViewer::event(QEvent *e) {
|
|||
}
|
||||
*/
|
||||
|
||||
if (e->type() == QEvent::Gesture &&
|
||||
CommandManager::instance()
|
||||
->getAction(MI_TouchGestureControl)
|
||||
->isChecked()) {
|
||||
if (e->type() == QEvent::Gesture && CommandManager::instance()
|
||||
->getAction(MI_TouchGestureControl)
|
||||
->isChecked()) {
|
||||
gestureEvent(static_cast<QGestureEvent *>(e));
|
||||
return true;
|
||||
}
|
||||
|
@ -793,6 +795,11 @@ SchematicViewer::SchematicViewer(QWidget *parent)
|
|||
connect(m_stageScene, SIGNAL(editObject()), this, SIGNAL(editObject()));
|
||||
connect(m_fxScene, SIGNAL(editObject()), this, SIGNAL(editObject()));
|
||||
|
||||
connect(m_fxScene->getFxSelection(), SIGNAL(doDelete()), this,
|
||||
SLOT(deleteFxs()));
|
||||
connect(m_stageScene->getStageSelection(), SIGNAL(doDelete()), this,
|
||||
SLOT(deleteStageObjects()));
|
||||
|
||||
m_viewer->setScene(m_stageScene);
|
||||
m_fxToolbar->hide();
|
||||
|
||||
|
@ -942,10 +949,10 @@ void SchematicViewer::createActions() {
|
|||
|
||||
QIcon nodeSizeIcon =
|
||||
createQIcon(m_maximizedNode ? "minimizenodes" : "maximizenodes");
|
||||
m_nodeSize =
|
||||
new QAction(nodeSizeIcon, m_maximizedNode ? tr("&Minimize Nodes")
|
||||
: tr("&Maximize Nodes"),
|
||||
m_commonToolbar);
|
||||
m_nodeSize = new QAction(
|
||||
nodeSizeIcon,
|
||||
m_maximizedNode ? tr("&Minimize Nodes") : tr("&Maximize Nodes"),
|
||||
m_commonToolbar);
|
||||
connect(m_nodeSize, SIGNAL(triggered()), this, SLOT(changeNodeSize()));
|
||||
|
||||
QIcon selectModeIcon = createQIcon("selection_schematic");
|
||||
|
@ -1219,3 +1226,15 @@ void SchematicViewer::zoomModeEnabled() { setCursorMode(CursorMode::Zoom); }
|
|||
//------------------------------------------------------------------
|
||||
|
||||
void SchematicViewer::handModeEnabled() { setCursorMode(CursorMode::Hand); }
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
||||
void SchematicViewer::deleteFxs() {
|
||||
emit doDeleteFxs(m_fxScene->getFxSelection());
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
||||
void SchematicViewer::deleteStageObjects() {
|
||||
emit doDeleteStageObjects(m_stageScene->getStageSelection());
|
||||
}
|
||||
|
|
|
@ -918,12 +918,25 @@ void StageObjectsData::storeSplines(const std::list<int> &splineIds,
|
|||
std::vector<TStageObjectId> StageObjectsData::restoreObjects(
|
||||
std::set<int> &columnIndices, std::list<int> &restoredSpline, TXsheet *xsh,
|
||||
int fxFlags, const TPointD &pos) const {
|
||||
QMap<TStageObjectId, TStageObjectId> idTable;
|
||||
QMap<TFx *, TFx *> fxTable;
|
||||
return restoreObjects(columnIndices, restoredSpline, xsh, fxFlags, idTable,
|
||||
fxTable, pos);
|
||||
}
|
||||
|
||||
// idTable : Trace stored/restored id pairings
|
||||
// fxTable : Same for fxs
|
||||
|
||||
std::vector<TStageObjectId> StageObjectsData::restoreObjects(
|
||||
std::set<int> &columnIndices, std::list<int> &restoredSpline, TXsheet *xsh,
|
||||
int fxFlags, QMap<TStageObjectId, TStageObjectId> &idTable,
|
||||
QMap<TFx *, TFx *> &fxTable, const TPointD &pos) const {
|
||||
bool doClone = (fxFlags & eDoClone);
|
||||
bool resetFxDagPositions = (fxFlags & eResetFxDagPositions);
|
||||
|
||||
QMap<TStageObjectId, TStageObjectId>
|
||||
idTable; // Trace stored/restored id pairings
|
||||
std::map<TFx *, TFx *> fxTable; // Same for fxs here
|
||||
// QMap<TStageObjectId, TStageObjectId>
|
||||
// idTable; // Trace stored/restored id pairings
|
||||
// std::map<TFx *, TFx *> fxTable; // Same for fxs here
|
||||
std::vector<TStageObjectId> restoredIds;
|
||||
|
||||
std::set<int>::iterator idxt = columnIndices.begin();
|
||||
|
@ -1104,7 +1117,7 @@ std::vector<TStageObjectId> StageObjectsData::restoreObjects(
|
|||
}
|
||||
|
||||
// Update the link, like in functions above
|
||||
if (!fxTable.empty() && doClone) updateFxLinks(fxTable);
|
||||
if (!fxTable.empty() && doClone) updateFxLinks(fxTable.toStdMap());
|
||||
|
||||
// Paste any associated spline (not stored im m_splines)
|
||||
std::map<TStageObjectSpline *, TStageObjectSpline *> splines;
|
||||
|
@ -1194,9 +1207,9 @@ std::vector<TStageObjectId> StageObjectsData::restoreObjects(
|
|||
obj->getPlasticSkeletonDeformation())
|
||||
sd->setGrammar(grammer);
|
||||
}
|
||||
std::map<TFx *, TFx *>::const_iterator it;
|
||||
for (it = fxTable.begin(); it != fxTable.end(); ++it) {
|
||||
setGrammerToParams(it->second->getParams(), grammer);
|
||||
QMap<TFx *, TFx *>::const_iterator it;
|
||||
for (it = fxTable.constBegin(); it != fxTable.constEnd(); ++it) {
|
||||
setGrammerToParams(it.value()->getParams(), grammer);
|
||||
}
|
||||
|
||||
return restoredIds;
|
||||
|
|
|
@ -108,7 +108,7 @@ public:
|
|||
}
|
||||
int getHistoryType() override { return HistoryType::Schematic; }
|
||||
};
|
||||
}
|
||||
} // namespace
|
||||
|
||||
//======================================================================
|
||||
//
|
||||
|
@ -153,9 +153,10 @@ void StageObjectSelection::enableCommands() {
|
|||
//-------------------------------------------------------
|
||||
|
||||
void StageObjectSelection::deleteSelection() {
|
||||
TStageObjectCmd::deleteSelection(
|
||||
m_selectedObjects.toVector().toStdVector(), m_selectedLinks.toStdList(),
|
||||
m_selectedSplines.toStdList(), m_xshHandle, m_objHandle, m_fxHandle);
|
||||
emit doDelete();
|
||||
// TStageObjectCmd::deleteSelection(
|
||||
// m_selectedObjects.toVector().toStdVector(), m_selectedLinks.toStdList(),
|
||||
// m_selectedSplines.toStdList(), m_xshHandle, m_objHandle, m_fxHandle);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------
|
||||
|
|
|
@ -76,6 +76,7 @@ public:
|
|||
const QList<QPair<TStageObjectId, TStageObjectId>> &getLinks() const {
|
||||
return m_selectedLinks;
|
||||
}
|
||||
const QList<int> &getSplines() const { return m_selectedSplines; }
|
||||
|
||||
void setXsheetHandle(TXsheetHandle *xshHandle) { m_xshHandle = xshHandle; }
|
||||
void setObjectHandle(TObjectHandle *objHandle) { m_objHandle = objHandle; }
|
||||
|
@ -96,6 +97,7 @@ private:
|
|||
signals:
|
||||
void doCollapse(QList<TStageObjectId>);
|
||||
void doExplodeChild(QList<TStageObjectId>);
|
||||
void doDelete();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
<file>Resources/param_on.svg</file>
|
||||
<file>Resources/paramanim_off.svg</file>
|
||||
<file>Resources/paramanim_on.svg</file>
|
||||
<file>Resources/paramignored_off.svg</file>
|
||||
<file>Resources/paramignored_on.svg</file>
|
||||
<file>Resources/resizeColumnNode.svg</file>
|
||||
<file>Resources/schematic_spin_arrows.svg</file>
|
||||
<file>Resources/schematic_spline_aim_rhomb.svg</file>
|
||||
|
|
|
@ -171,7 +171,7 @@ TreeModel::~TreeModel() { delete m_rootItem; }
|
|||
//------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void TreeModel::setExpandedItem(const QModelIndex &index, bool expanded) {
|
||||
m_view->setExpanded(index, expanded);
|
||||
if (m_view) m_view->setExpanded(index, expanded);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
|
@ -320,7 +320,7 @@ void TreeModel::setRootItem_NoFree(Item *rootItem) {
|
|||
//---------------------------------------------------------------------------------------------------------------
|
||||
|
||||
void TreeModel::setRowHidden(int row, const QModelIndex &parent, bool hide) {
|
||||
m_view->setRowHidden(row, parent, hide);
|
||||
if (m_view) m_view->setRowHidden(row, parent, hide);
|
||||
}
|
||||
|
||||
//====================================================================================================
|
||||
|
|
Loading…
Reference in a new issue