Merge pull request #634 from manongjohn/ot_patches_20210328

OpenToonz patches thru 3/28
This commit is contained in:
manongjohn 2021-04-01 17:07:39 -04:00 committed by GitHub
commit 489ea06570
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
40 changed files with 1379 additions and 539 deletions

View file

@ -0,0 +1,716 @@
<dvpreset fxId="STD_particlesFx" ver="1.0">
<params>
<source_ctrl>
0 0
</source_ctrl>
<bright_thres>
25 25
</bright_thres>
<multi_source>
0 0
</multi_source>
<center>
<x>
<default>
444.444
</default>
</x>
<y>
<default>
0
</default>
</y>
</center>
<length>
<default>
4.44444
</default>
</length>
<height>
<default>
480
</default>
</height>
<birth_rate>
<default>
1
</default>
</birth_rate>
<lifetime>
<min>
<default>
900
</default>
</min>
<max>
<default>
900
</default>
</max>
</lifetime>
<lifetime_ctrl>
0 0
</lifetime_ctrl>
<column_lifetime>
0 0
</column_lifetime>
<starting_frame>
1 1
</starting_frame>
<random_seed>
1 1
</random_seed>
<gravity>
<default>
0
</default>
</gravity>
<gravity_angle>
<default>
0
</default>
</gravity_angle>
<gravity_ctrl>
0 0
</gravity_ctrl>
<friction>
<default>
0
</default>
</friction>
<friction_ctrl>
0 0
</friction_ctrl>
<wind>
<default>
0
</default>
</wind>
<wind_angle>
<default>
0
</default>
</wind_angle>
<swing_mode>
1
</swing_mode>
<scattering_x>
<min>
<default>
0
</default>
</min>
<max>
<default>
0
</default>
</max>
</scattering_x>
<scattering_y>
<min>
<default>
0.444444
</default>
</min>
<max>
<default>
11.1111
</default>
</max>
</scattering_y>
<scattering_x_ctrl>
0 0
</scattering_x_ctrl>
<scattering_y_ctrl>
0 0
</scattering_y_ctrl>
<swing>
<min>
<default>
15
</default>
</min>
<max>
<default>
45
</default>
</max>
</swing>
<speed>
<min>
<default>
20
</default>
</min>
<max>
<default>
26.6667
</default>
</max>
</speed>
<speed_ctrl>
0 0
</speed_ctrl>
<speed_angle>
<min>
<default>
-105
</default>
</min>
<max>
<default>
-60
</default>
</max>
</speed_angle>
<speeda_ctrl>
0 0
</speeda_ctrl>
<speeda_use_gradient>
0 0
</speeda_use_gradient>
<speed_size>
0 1
</speed_size>
<top_layer>
3
</top_layer>
<mass>
<min>
<default>
1
</default>
</min>
<max>
<default>
1
</default>
</max>
</mass>
<scale>
<min>
<default>
30
</default>
</min>
<max>
<default>
75
</default>
</max>
</scale>
<scale_ctrl>
0 0
</scale_ctrl>
<scale_ctrl_all>
0 0
</scale_ctrl_all>
<rot>
<min>
<default>
0
</default>
</min>
<max>
<default>
0
</default>
</max>
</rot>
<rot_ctrl>
0 0
</rot_ctrl>
<trail>
<min>
<default>
0
</default>
</min>
<max>
<default>
0
</default>
</max>
</trail>
<trail_step>
<default>
0
</default>
</trail_step>
<spin_swing_mode>
0
</spin_swing_mode>
<spin_speed>
<default>
0
</default>
</spin_speed>
<spin_random>
<min>
<default>
0
</default>
</min>
<max>
<default>
0
</default>
</max>
</spin_random>
<spin_swing>
<min>
<default>
0
</default>
</min>
<max>
<default>
0
</default>
</max>
</spin_swing>
<path_aim>
0 0
</path_aim>
<opacity>
<min>
<default>
0
</default>
</min>
<max>
<default>
100
</default>
</max>
</opacity>
<opacity_ctrl>
0 0
</opacity_ctrl>
<trail_opacity>
<min>
<default>
0
</default>
</min>
<max>
<default>
100
</default>
</max>
</trail_opacity>
<scale_step>
<min>
<default>
-2
</default>
</min>
<max>
<default>
3
</default>
</max>
</scale_step>
<scale_step_ctrl>
0 0
</scale_step_ctrl>
<fade_in>
<default>
0
</default>
</fade_in>
<fade_out>
<default>
0
</default>
</fade_out>
<animation>
3
</animation>
<step>
1 1
</step>
<birth_color>
<spectrum>
<s_value>
<default>
0
</default>
<keyframes>
<S>
0 0 1 0
</S>
</keyframes>
</s_value>
<col_value>
<red>
<default>
1
</default>
<keyframes>
<S>
0 1 1 0
</S>
</keyframes>
</red>
<green>
<default>
0
</default>
<keyframes>
<S>
0 0 1 0
</S>
</keyframes>
</green>
<blue>
<default>
0
</default>
<keyframes>
<S>
0 0 1 0
</S>
</keyframes>
</blue>
<matte>
<default>
1
</default>
<keyframes>
<S>
0 1 1 0
</S>
</keyframes>
</matte>
</col_value>
<s_value>
<default>
1
</default>
<keyframes>
<S>
0 1 1 0
</S>
</keyframes>
</s_value>
<col_value>
<red>
<default>
1
</default>
<keyframes>
<S>
0 1 1 0
</S>
</keyframes>
</red>
<green>
<default>
0
</default>
<keyframes>
<S>
0 0 1 0
</S>
</keyframes>
</green>
<blue>
<default>
0
</default>
<keyframes>
<S>
0 0 1 0
</S>
</keyframes>
</blue>
<matte>
<default>
1
</default>
<keyframes>
<S>
0 1 1 0
</S>
</keyframes>
</matte>
</col_value>
</spectrum>
</birth_color>
<birth_color_ctrl>
0 0
</birth_color_ctrl>
<birth_color_spread>
<default>
0
</default>
</birth_color_spread>
<birth_color_fade>
<default>
0
</default>
</birth_color_fade>
<fadein_color>
<spectrum>
<s_value>
<default>
0
</default>
<keyframes>
<S>
0 0 1 0
</S>
</keyframes>
</s_value>
<col_value>
<red>
<default>
0
</default>
<keyframes>
<S>
0 0 1 0
</S>
</keyframes>
</red>
<green>
<default>
1
</default>
<keyframes>
<S>
0 1 1 0
</S>
</keyframes>
</green>
<blue>
<default>
0
</default>
<keyframes>
<S>
0 0 1 0
</S>
</keyframes>
</blue>
<matte>
<default>
1
</default>
<keyframes>
<S>
0 1 1 0
</S>
</keyframes>
</matte>
</col_value>
<s_value>
<default>
1
</default>
<keyframes>
<S>
0 1 1 0
</S>
</keyframes>
</s_value>
<col_value>
<red>
<default>
0
</default>
<keyframes>
<S>
0 0 1 0
</S>
</keyframes>
</red>
<green>
<default>
1
</default>
<keyframes>
<S>
0 1 1 0
</S>
</keyframes>
</green>
<blue>
<default>
0
</default>
<keyframes>
<S>
0 0 1 0
</S>
</keyframes>
</blue>
<matte>
<default>
1
</default>
<keyframes>
<S>
0 1 1 0
</S>
</keyframes>
</matte>
</col_value>
</spectrum>
</fadein_color>
<fadein_color_ctrl>
0 0
</fadein_color_ctrl>
<fadein_color_spread>
<default>
0
</default>
</fadein_color_spread>
<fadein_color_range>
<default>
0
</default>
</fadein_color_range>
<fadein_color_fade>
<default>
0
</default>
</fadein_color_fade>
<fadeout_color>
<spectrum>
<s_value>
<default>
0
</default>
<keyframes>
<S>
0 0 1 0
</S>
</keyframes>
</s_value>
<col_value>
<red>
<default>
0
</default>
<keyframes>
<S>
0 0 1 0
</S>
</keyframes>
</red>
<green>
<default>
0
</default>
<keyframes>
<S>
0 0 1 0
</S>
</keyframes>
</green>
<blue>
<default>
1
</default>
<keyframes>
<S>
0 1 1 0
</S>
</keyframes>
</blue>
<matte>
<default>
1
</default>
<keyframes>
<S>
0 1 1 0
</S>
</keyframes>
</matte>
</col_value>
<s_value>
<default>
1
</default>
<keyframes>
<S>
0 1 1 0
</S>
</keyframes>
</s_value>
<col_value>
<red>
<default>
0
</default>
<keyframes>
<S>
0 0 1 0
</S>
</keyframes>
</red>
<green>
<default>
0
</default>
<keyframes>
<S>
0 0 1 0
</S>
</keyframes>
</green>
<blue>
<default>
1
</default>
<keyframes>
<S>
0 1 1 0
</S>
</keyframes>
</blue>
<matte>
<default>
1
</default>
<keyframes>
<S>
0 1 1 0
</S>
</keyframes>
</matte>
</col_value>
</spectrum>
</fadeout_color>
<fadeout_color_ctrl>
0 0
</fadeout_color_ctrl>
<fadeout_color_spread>
<default>
0
</default>
</fadeout_color_spread>
<fadeout_color_range>
<default>
0
</default>
</fadeout_color_range>
<fadeout_color_fade>
<default>
0
</default>
</fadeout_color_fade>
<source_gradation>
0 0
</source_gradation>
<pick_color_for_every_frame>
0 0
</pick_color_for_every_frame>
<perspective_distribution>
0 1
</perspective_distribution>
</params>
</dvpreset>

View file

@ -145,7 +145,7 @@ if(BUILD_ENV_MSVC)
return() return()
endif() endif()
set(QT_LIB_PATH ${QT_PATH}) set(QT_LIB_PATH ${QT_PATH})
set(CMAKE_PREFIX_PATH "${QT_PATH}/lib/cmake/") set(CMAKE_PREFIX_PATH "${CMAKE_PREFIX_PATH};${QT_PATH}/lib/cmake/")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4251") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4251")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4251") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4251")
add_definitions( add_definitions(
@ -159,12 +159,12 @@ elseif(BUILD_ENV_APPLE)
endif() endif()
message("PLATFORM:" ${PLATFORM}) message("PLATFORM:" ${PLATFORM})
if(PLATFORM EQUAL 64) if(PLATFORM EQUAL 64)
set(QT_PATH "~/Qt5.9.2/5.9.2/clang_64/lib" CACHE PATH "Qt installation directory") set(QT_PATH "~/Qt5.9.2/5.9.2/clang_${PLATFORM}/lib" CACHE PATH "Qt installation directory")
# set(QT_PATH "/usr/local/Cellar/qt/5.15.0/lib" CACHE PATH "Qt installation directory")
set(QT_LIB_PATH "${QT_PATH}/") set(QT_LIB_PATH "${QT_PATH}/")
set(CMAKE_PREFIX_PATH "${QT_LIB_PATH}cmake/") set(CMAKE_PREFIX_PATH "${CMAKE_PREFIX_PATH};${QT_LIB_PATH}cmake/")
foreach(path ${CMAKE_PREFIX_PATH})
message("CMAKE_PREFIX_PATH:" ${CMAKE_PREFIX_PATH}) message("CMAKE_PREFIX_PATH: " ${path})
endforeach(path)
add_definitions( add_definitions(
-DMACOSX -DMACOSX
-Di386 -Di386

View file

@ -66,7 +66,7 @@ double tglGetPixelSize2() {
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glGetDoublev(GL_MODELVIEW_MATRIX, mat); glGetDoublev(GL_MODELVIEW_MATRIX, mat);
double det = fabs(mat[0] * mat[5] - mat[1] * mat[4]); double det = fabs(mat[0] * mat[5] - mat[1] * mat[4]);
if (det < TConsts::epsilon) det = TConsts::epsilon; if (det < TConsts::epsilon) det = TConsts::epsilon;
return 1.0 / det; return 1.0 / det;
} }
@ -431,7 +431,7 @@ void tglDraw(const TRectD &rect, const std::vector<TRaster32P> &textures,
unsigned int level = 1; unsigned int level = 1;
while (pixelSize2 * level * level <= 1.0) level <<= 1; while (pixelSize2 * level * level <= 1.0) level <<= 1;
unsigned int texturesCount = (int)textures.size(); unsigned int texturesCount = (int)textures.size();
if (level > texturesCount) level = texturesCount; if (level > texturesCount) level = texturesCount;
level = texturesCount - level; level = texturesCount - level;
@ -467,8 +467,8 @@ void tglDraw(const TRectD &rect, const TRaster32P &tex, bool blending) {
texture = TRaster32P(texWidth, texHeight); texture = TRaster32P(texWidth, texHeight);
texture->fill(TPixel32(0, 0, 0, 0)); texture->fill(TPixel32(0, 0, 0, 0));
texture->copy(tex); texture->copy(tex);
lwTex = (texLx) / (double)(texWidth); lwTex = (texLx) / (double)(texWidth);
lhTex = (texLy) / (double)(texHeight); lhTex = (texLy) / (double)(texHeight);
if (lwTex > 1.0) lwTex = 1.0; if (lwTex > 1.0) lwTex = 1.0;
if (lhTex > 1.0) lhTex = 1.0; if (lhTex > 1.0) lhTex = 1.0;
} else } else
@ -587,10 +587,10 @@ void tglBuildMipmaps(std::vector<TRaster32P> &rasters,
ly >>= 1; ly >>= 1;
if (lx < 1) lx = 1; if (lx < 1) lx = 1;
if (ly < 1) ly = 1; if (ly < 1) ly = 1;
rasters[i] = TRaster32P(lx, ly); rasters[i] = TRaster32P(lx, ly);
sx = (double)lx / (double)ras2Lx; sx = (double)lx / (double)ras2Lx;
sy = (double)ly / (double)ras2Ly; sy = (double)ly / (double)ras2Ly;
rasters[i] = TRaster32P(lx, ly); rasters[i] = TRaster32P(lx, ly);
#ifndef SCALE_BY_GLU #ifndef SCALE_BY_GLU
TRop::resample(rasters[i], ras2, TScale(sx, sy), resampleFilter); TRop::resample(rasters[i], ras2, TScale(sx, sy), resampleFilter);
#else #else

View file

@ -204,7 +204,8 @@ public:
png_set_palette_to_rgb(m_png_ptr); png_set_palette_to_rgb(m_png_ptr);
// treat the image as RGBA from now on // treat the image as RGBA from now on
m_info.m_samplePerPixel = 4; // there are 4 channels per pixel (R, G, B, and A) m_info.m_samplePerPixel =
4; // there are 4 channels per pixel (R, G, B, and A)
// if there is no alpha channel, then fill it with "255" (full opacity) // if there is no alpha channel, then fill it with "255" (full opacity)
png_set_filler(m_png_ptr, 0xFF, PNG_FILLER_AFTER); png_set_filler(m_png_ptr, 0xFF, PNG_FILLER_AFTER);
@ -349,7 +350,8 @@ public:
void writeRow(char *buffer) { void writeRow(char *buffer) {
if (m_color_type == PNG_COLOR_TYPE_RGB_ALPHA || if (m_color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
m_color_type == PNG_COLOR_TYPE_GRAY_ALPHA || m_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
m_color_type == PNG_COLOR_TYPE_PALETTE) { // PNG_COLOR_TYPE_PALETTE is expanded to RGBA m_color_type == PNG_COLOR_TYPE_PALETTE) { // PNG_COLOR_TYPE_PALETTE is
// expanded to RGBA
if (m_bit_depth == 16) { if (m_bit_depth == 16) {
TPixel32 *pix = (TPixel32 *)buffer; TPixel32 *pix = (TPixel32 *)buffer;
int i = -2; int i = -2;
@ -377,6 +379,9 @@ public:
#else #else
#error "unknown channel order" #error "unknown channel order"
#endif #endif
// premultiply here
premult(pix[j]);
} }
} else { } else {
TPixel32 *pix = (TPixel32 *)buffer; TPixel32 *pix = (TPixel32 *)buffer;
@ -388,23 +393,25 @@ public:
pix[j].g = m_rowBuffer[i++]; pix[j].g = m_rowBuffer[i++];
pix[j].b = m_rowBuffer[i++]; pix[j].b = m_rowBuffer[i++];
#elif defined(TNZ_MACHINE_CHANNEL_ORDER_RGBM) #elif defined(TNZ_MACHINE_CHANNEL_ORDER_RGBM)
pix[j].r = m_rowBuffer[i++]; pix[j].r = m_rowBuffer[i++];
pix[j].g = m_rowBuffer[i++]; pix[j].g = m_rowBuffer[i++];
pix[j].b = m_rowBuffer[i++]; pix[j].b = m_rowBuffer[i++];
pix[j].m = m_rowBuffer[i++]; pix[j].m = m_rowBuffer[i++];
#elif defined(TNZ_MACHINE_CHANNEL_ORDER_BGRM) #elif defined(TNZ_MACHINE_CHANNEL_ORDER_BGRM)
pix[j].b = m_rowBuffer[i++]; pix[j].b = m_rowBuffer[i++];
pix[j].g = m_rowBuffer[i++]; pix[j].g = m_rowBuffer[i++];
pix[j].r = m_rowBuffer[i++]; pix[j].r = m_rowBuffer[i++];
pix[j].m = m_rowBuffer[i++]; pix[j].m = m_rowBuffer[i++];
#elif defined(TNZ_MACHINE_CHANNEL_ORDER_MBGR) #elif defined(TNZ_MACHINE_CHANNEL_ORDER_MBGR)
pix[j].m = m_rowBuffer[i++]; pix[j].m = m_rowBuffer[i++];
pix[j].b = m_rowBuffer[i++]; pix[j].b = m_rowBuffer[i++];
pix[j].g = m_rowBuffer[i++]; pix[j].g = m_rowBuffer[i++];
pix[j].r = m_rowBuffer[i++]; pix[j].r = m_rowBuffer[i++];
#else #else
#error "unknown channel order" #error "unknown channel order"
#endif #endif
// premultiply here
premult(pix[j]);
} }
} }
} else // qui gestisce RGB senza alpha. } else // qui gestisce RGB senza alpha.
@ -439,9 +446,9 @@ public:
pix[j].b = m_rowBuffer[i++]; pix[j].b = m_rowBuffer[i++];
#elif defined(TNZ_MACHINE_CHANNEL_ORDER_MBGR) || \ #elif defined(TNZ_MACHINE_CHANNEL_ORDER_MBGR) || \
defined(TNZ_MACHINE_CHANNEL_ORDER_BGRM) defined(TNZ_MACHINE_CHANNEL_ORDER_BGRM)
pix[j].b = m_rowBuffer[i++]; pix[j].b = m_rowBuffer[i++];
pix[j].g = m_rowBuffer[i++]; pix[j].g = m_rowBuffer[i++];
pix[j].r = m_rowBuffer[i++]; pix[j].r = m_rowBuffer[i++];
#else #else
#error "unknown channel order" #error "unknown channel order"
#endif #endif
@ -454,7 +461,8 @@ public:
void writeRow(short *buffer) { void writeRow(short *buffer) {
if (m_color_type == PNG_COLOR_TYPE_RGB_ALPHA || if (m_color_type == PNG_COLOR_TYPE_RGB_ALPHA ||
m_color_type == PNG_COLOR_TYPE_GRAY_ALPHA || m_color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
m_color_type == PNG_COLOR_TYPE_PALETTE) { // PNG_COLOR_TYPE_PALETTE is expanded to RGBA m_color_type == PNG_COLOR_TYPE_PALETTE) { // PNG_COLOR_TYPE_PALETTE is
// expanded to RGBA
TPixel64 *pix = (TPixel64 *)buffer; TPixel64 *pix = (TPixel64 *)buffer;
int i = -2; // 0; int i = -2; // 0;
for (int j = 0; j < m_info.m_lx; j++) { for (int j = 0; j < m_info.m_lx; j++) {
@ -474,6 +482,9 @@ public:
#error "unknown channel order" #error "unknown channel order"
#endif #endif
// pix[j].m = 255; // pix[j].m = 255;
// premultiply here
premult(pix[j]);
} }
} else // qui gestisce RGB senza alpha. } else // qui gestisce RGB senza alpha.
{ // grayscale e' gestito come RGB perche' si usa png_set_gray_to_rgb { // grayscale e' gestito come RGB perche' si usa png_set_gray_to_rgb
@ -849,7 +860,7 @@ void PngWriter::open(FILE *file, const TImageInfo &info) {
png_set_PLTE(m_png_ptr, m_info_ptr, palette, m_colormap->size()); png_set_PLTE(m_png_ptr, m_info_ptr, palette, m_colormap->size());
} }
// png_set_dither(m_png_ptr, palette, 256, 256, 0, 1); // png_set_dither(m_png_ptr, palette, 256, 256, 0, 1);
#if defined(TNZ_MACHINE_CHANNEL_ORDER_MBGR) #if defined(TNZ_MACHINE_CHANNEL_ORDER_MBGR)
png_set_bgr(m_png_ptr); png_set_bgr(m_png_ptr);
@ -862,7 +873,6 @@ void PngWriter::open(FILE *file, const TImageInfo &info) {
#error "unknownchannel order" #error "unknownchannel order"
#endif #endif
png_write_info(m_png_ptr, m_info_ptr);
png_set_pHYs(m_png_ptr, m_info_ptr, x_pixels_per_meter, y_pixels_per_meter, png_set_pHYs(m_png_ptr, m_info_ptr, x_pixels_per_meter, y_pixels_per_meter,
1); 1);
@ -873,6 +883,8 @@ void PngWriter::open(FILE *file, const TImageInfo &info) {
bgcolor.index = 0; bgcolor.index = 0;
png_set_tRNS(m_png_ptr, m_info_ptr, alpha, 1, &bgcolor); png_set_tRNS(m_png_ptr, m_info_ptr, alpha, 1, &bgcolor);
} }
png_write_info(m_png_ptr, m_info_ptr);
} }
//--------------------------------------------------------- //---------------------------------------------------------
@ -945,10 +957,10 @@ void PngWriter::writeLine(char *buffer) {
tmp[k++] = depremult_pix.g; tmp[k++] = depremult_pix.g;
tmp[k++] = depremult_pix.r; tmp[k++] = depremult_pix.r;
#elif defined(TNZ_MACHINE_CHANNEL_ORDER_BGRM) #elif defined(TNZ_MACHINE_CHANNEL_ORDER_BGRM)
tmp[k++] = depremult_pix.b; tmp[k++] = depremult_pix.b;
tmp[k++] = depremult_pix.g; tmp[k++] = depremult_pix.g;
tmp[k++] = depremult_pix.r; tmp[k++] = depremult_pix.r;
tmp[k++] = depremult_pix.m; tmp[k++] = depremult_pix.m;
#else #else
#error "unknown channel order" #error "unknown channel order"
#endif #endif
@ -961,7 +973,7 @@ void PngWriter::writeLine(char *buffer) {
int k = 0; int k = 0;
for (int j = 0; j < m_info.m_lx; j++) { for (int j = 0; j < m_info.m_lx; j++) {
// tmp = (pix->r&0xe0)|((pix->g&0xe0)>>3) | ((pix->b&0xc0)>>6); // tmp = (pix->r&0xe0)|((pix->g&0xe0)>>3) | ((pix->b&0xc0)>>6);
#if defined(TNZ_MACHINE_CHANNEL_ORDER_MRGB) || \ #if defined(TNZ_MACHINE_CHANNEL_ORDER_MRGB) || \
defined(TNZ_MACHINE_CHANNEL_ORDER_RGBM) defined(TNZ_MACHINE_CHANNEL_ORDER_RGBM)

View file

@ -112,9 +112,9 @@ public:
/*! \return The \a coded path to be used for import. */ /*! \return The \a coded path to be used for import. */
TFilePath getImportedLevelPath(const TFilePath path) TFilePath getImportedLevelPath(
const; //!< Builds the path to be used during a level import const TFilePath path) const; //!< Builds the path to be used during a
//!< operation. //!< level import operation.
/*! \details If convertion is required, a new level file will be created /*! \details If convertion is required, a new level file will be created
and \p levelPath will be substituted with its new path. and \p levelPath will be substituted with its new path.
@ -267,9 +267,11 @@ private:
TLevelSet *m_levelSet; TLevelSet *m_levelSet;
TProject *m_project; TProject *m_project;
TContentHistory *m_contentHistory; TContentHistory *m_contentHistory;
bool m_isUntitled; //!< Whether the scene is untitled. bool m_isUntitled; //!< Whether the scene is untitled.
//! \sa The setUntitled() member function. //! \sa The setUntitled() member function.
VersionNumber m_versionNumber; VersionNumber m_versionNumber; // last saved scene file version. Note that
// currently it is not match with OT version.
// TODO: Revise VersionNumber with OT version
private: private:
// noncopyable // noncopyable

View file

@ -108,15 +108,14 @@ int DVAPI getDevPixRatio();
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
QPixmap DVAPI setOpacity(QPixmap pixmap, const qreal &opacity = 0.8); QPixmap DVAPI compositePixmap(QPixmap pixmap, const qreal &opacity = 0.8,
const QSize &size = QSize(),
const int leftAdj = 0, const int topAdj = 0,
QColor bgColor = Qt::transparent);
QPixmap DVAPI recolorPixmap( QPixmap DVAPI recolorPixmap(
QPixmap pixmap, QColor color = Preferences::instance()->getIconTheme() QPixmap pixmap, QColor color = Preferences::instance()->getIconTheme()
? Qt::black ? Qt::black
: Qt::white); : Qt::white);
QPixmap DVAPI compositePixmap(QPixmap pixmap, qreal opacity,
int canvasWidth = 20, int canvasHeight = 20,
int iconWidth = 16, int iconHeight = 16,
int offset = 0);
QIcon DVAPI createQIcon(const char *iconSVGName, bool useFullOpacity = false); QIcon DVAPI createQIcon(const char *iconSVGName, bool useFullOpacity = false);
QIcon DVAPI createQIconPNG(const char *iconPNGName); QIcon DVAPI createQIconPNG(const char *iconPNGName);
QIcon DVAPI createQIconOnOffPNG(const char *iconPNGName, bool withOver = true); QIcon DVAPI createQIconOnOffPNG(const char *iconPNGName, bool withOver = true);

View file

@ -30,6 +30,9 @@
#include "toutputproperties.h" #include "toutputproperties.h"
#include "toonz/imagestyles.h" #include "toonz/imagestyles.h"
#include "tproperty.h" #include "tproperty.h"
#include "toonz/levelset.h"
#include "toonz/txshsimplelevel.h"
#include "toonz/levelproperties.h"
// TnzSound includes // TnzSound includes
#include "tnzsound.h" #include "tnzsound.h"
@ -226,6 +229,35 @@ void tcomposerRunOutOfContMemHandler(unsigned long size) {
TImageCache::instance()->clear(true); TImageCache::instance()->clear(true);
exit(2); exit(2);
} }
// Check if the scene saved with the previous version AND the premultiply option
// is set to PNG level setting
void UnsetPremultiplyOptionsInPngLevels(ToonzScene *scene) {
if (scene->getVersionNumber() <
VersionNumber(71, 1)) { // V1.4 = 71.0 , V1.5 = 71.1
QStringList modifiedPNGLevelNames;
std::vector<TXshLevel *> levels;
scene->getLevelSet()->listLevels(levels);
for (auto level : levels) {
if (!level || !level->getSimpleLevel()) continue;
TFilePath path = level->getPath();
if (path.isEmpty() || path.getType() != "png") continue;
if (level->getSimpleLevel()->getProperties()->doPremultiply()) {
level->getSimpleLevel()->getProperties()->setDoPremultiply(false);
modifiedPNGLevelNames.append(QString::fromStdWString(level->getName()));
}
}
if (!modifiedPNGLevelNames.isEmpty()) {
std::string msg =
"The Premultiply options in the following levels are disabled, since "
"PNG files are premultiplied on loading in the current version:" +
modifiedPNGLevelNames.join(", ").toStdString();
cout << msg << endl;
m_userLog->info(msg);
}
}
}
} // namespace } // namespace
//============================================================================================== //==============================================================================================
@ -406,7 +438,7 @@ static std::pair<int, int> generateMovie(ToonzScene *scene, const TFilePath &fp,
r0 = r0 - 1; r0 = r0 - 1;
r1 = r1 - 1; r1 = r1 - 1;
if (r0 < 0) r0 = 0; if (r0 < 0) r0 = 0;
if (r1 < 0 || r1 >= scene->getFrameCount()) r1 = scene->getFrameCount() - 1; if (r1 < 0 || r1 >= scene->getFrameCount()) r1 = scene->getFrameCount() - 1;
string msg; string msg;
assert(r1 >= r0); assert(r1 >= r0);
@ -725,7 +757,7 @@ int main(int argc, char *argv[]) {
TVectorBrushStyle::setRootDir(libraryFolder); TVectorBrushStyle::setRootDir(libraryFolder);
TPalette::setRootDir(libraryFolder); TPalette::setRootDir(libraryFolder);
TImageStyle::setLibraryDir(libraryFolder); TImageStyle::setLibraryDir(libraryFolder);
TFilePath cacheRoot = ToonzFolder::getCacheRootFolder(); TFilePath cacheRoot = ToonzFolder::getCacheRootFolder();
if (cacheRoot.isEmpty()) cacheRoot = TEnv::getStuffDir() + "cache"; if (cacheRoot.isEmpty()) cacheRoot = TEnv::getStuffDir() + "cache";
TImageCache::instance()->setRootDir(cacheRoot); TImageCache::instance()->setRootDir(cacheRoot);
// #endif // #endif
@ -820,6 +852,10 @@ int main(int argc, char *argv[]) {
// return false; // return false;
} }
// Check if the scene saved with the previous version AND the premultiply
// option is set to PNG level setting
UnsetPremultiplyOptionsInPngLevels(scene);
msg = "scene loaded"; msg = "scene loaded";
cout << "scene loaded" << endl; cout << "scene loaded" << endl;
m_userLog->info(msg); m_userLog->info(msg);
@ -992,8 +1028,8 @@ int main(int argc, char *argv[]) {
DVGui::info(QString::fromStdString(msg)); DVGui::info(QString::fromStdString(msg));
TImageCache::instance()->clear(true); TImageCache::instance()->clear(true);
} catch (TException &e) { } catch (TException &e) {
msg = "Untrapped exception: " + ::to_string(e.getMessage()), cout << msg msg = "Untrapped exception: " + ::to_string(e.getMessage()),
<< endl; cout << msg << endl;
m_userLog->error(msg); m_userLog->error(msg);
TImageCache::instance()->clear(true); TImageCache::instance()->clear(true);
} catch (...) { } catch (...) {

View file

@ -326,7 +326,7 @@ void tglDraw(const TMeshImage &meshImage, const DrawableTextureData &texData,
GL_HINT_BIT); // Preserve original status bits GL_HINT_BIT); // Preserve original status bits
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_LINE_SMOOTH); glEnable(GL_LINE_SMOOTH);
glLineWidth(1.0f); glLineWidth(1.0f);

View file

@ -565,7 +565,7 @@ void FingerTool::pick(const TPointD &pos) {
int styleId = int styleId =
picker.pickStyleId(TScale(1.0 / subsampling) * pos + TPointD(-0.5, -0.5), picker.pickStyleId(TScale(1.0 / subsampling) * pos + TPointD(-0.5, -0.5),
getPixelSize() * getPixelSize(), modeValue); getPixelSize() * getPixelSize(), 1.0, modeValue);
if (styleId < 0) return; if (styleId < 0) return;

View file

@ -19,6 +19,7 @@
#include "toonz/txsheethandle.h" #include "toonz/txsheethandle.h"
#include "toonz/txshlevelhandle.h" #include "toonz/txshlevelhandle.h"
#include "toonz/tobjecthandle.h" #include "toonz/tobjecthandle.h"
#include "toonz/tframehandle.h"
#include "toonz/ttileset.h" #include "toonz/ttileset.h"
#include "toonz/ttilesaver.h" #include "toonz/ttilesaver.h"
#include "toonz/strokegenerator.h" #include "toonz/strokegenerator.h"
@ -291,7 +292,13 @@ bool FullColorBrushTool::askWrite(const TRect &rect) {
bool FullColorBrushTool::preLeftButtonDown() { bool FullColorBrushTool::preLeftButtonDown() {
touchImage(); touchImage();
if (m_isFrameCreated) setWorkAndBackupImages(); if (m_isFrameCreated) {
setWorkAndBackupImages();
// When the xsheet frame is selected, whole viewer will be updated from
// SceneViewer::onXsheetChanged() on adding a new frame.
// We need to take care of a case when the level frame is selected.
if (m_application->getCurrentFrame()->isEditingLevel()) invalidate();
}
return true; return true;
} }
@ -308,7 +315,7 @@ void FullColorBrushTool::leftButtonDown(const TPointD &pos,
if (!viewer) return; if (!viewer) return;
TRasterImageP ri = (TRasterImageP)getImage(true); TRasterImageP ri = (TRasterImageP)getImage(true);
if (!ri) ri = (TRasterImageP)touchImage(); if (!ri) ri = (TRasterImageP)touchImage();
if (!ri) return; if (!ri) return;

View file

@ -567,6 +567,7 @@ public:
bool getSmooth() { return m_param->m_smooth.getValue(); } bool getSmooth() { return m_param->m_smooth.getValue(); }
virtual TStroke *makeStroke() const = 0; virtual TStroke *makeStroke() const = 0;
virtual bool canTouchImageOnPreLeftClick() { return true; }
}; };
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -739,6 +740,9 @@ public:
void onImageChanged() override; void onImageChanged() override;
void setVertexes(const std::vector<TPointD> &vertex) { m_vertex = vertex; }; void setVertexes(const std::vector<TPointD> &vertex) { m_vertex = vertex; };
void setSpeedMoved(bool speedMoved) { m_speedMoved = speedMoved; }; void setSpeedMoved(bool speedMoved) { m_speedMoved = speedMoved; };
// Only execute touchImage when clicking the first point of the polyline
bool canTouchImageOnPreLeftClick() override { return m_vertex.empty(); }
}; };
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -849,6 +853,7 @@ public:
TStroke *makeStroke() const override; TStroke *makeStroke() const override;
void draw() override; void draw() override;
void leftButtonDown(const TPointD &pos, const TMouseEvent &e) override;
void leftButtonUp(const TPointD &pos, const TMouseEvent &) override; void leftButtonUp(const TPointD &pos, const TMouseEvent &) override;
void mouseMove(const TPointD &pos, const TMouseEvent &e) override; void mouseMove(const TPointD &pos, const TMouseEvent &e) override;
void leftButtonDoubleClick(const TPointD &, const TMouseEvent &e) override; void leftButtonDoubleClick(const TPointD &, const TMouseEvent &e) override;
@ -879,6 +884,9 @@ public:
void decreaseUndo() { --m_undoCount; } void decreaseUndo() { --m_undoCount; }
void increaseUndo() { ++m_undoCount; } void increaseUndo() { ++m_undoCount; }
// Only execute touchImage when clicking the first point of the multi arc
bool canTouchImageOnPreLeftClick() override { return m_clickNumber == 0; }
}; };
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -1032,19 +1040,27 @@ public:
} }
} }
bool preLeftButtonDown() override {
if (getViewer() && getViewer()->getGuidedStrokePickerMode()) return false;
if (getApplication()->getCurrentObject()->isSpline()) return true;
// in the halfway through the drawing of Polyline / MultiArc primitive, OT
// should not call touchImage or the m_frameCreated / m_levelCreated flags
// will be reset.
if (m_primitive && !m_primitive->canTouchImageOnPreLeftClick()) return true;
// NEEDS to be done even if(m_active), due
// to the HORRIBLE m_frameCreated / m_levelCreated
// mechanism. touchImage() is the ONLY function
// resetting them to false... >_<
m_active = !!touchImage();
return true;
}
void leftButtonDown(const TPointD &p, const TMouseEvent &e) override { void leftButtonDown(const TPointD &p, const TMouseEvent &e) override {
if (getViewer() && getViewer()->getGuidedStrokePickerMode()) { if (getViewer() && getViewer()->getGuidedStrokePickerMode()) {
getViewer()->doPickGuideStroke(p); getViewer()->doPickGuideStroke(p);
return; return;
} }
/* m_active = getApplication()->getCurrentObject()->isSpline() ||
(bool) getImage(true);*/
if (!getApplication()->getCurrentObject()->isSpline())
m_active = touchImage(); // NEEDS to be done even if(m_active), due
if (!m_active) // to the HORRIBLE m_frameCreated / m_levelCreated
return; // mechanism. touchImage() is the ONLY function
// resetting them to false... >_<
if (m_primitive) m_primitive->leftButtonDown(p, e); if (m_primitive) m_primitive->leftButtonDown(p, e);
invalidate(); invalidate();
} }
@ -2397,6 +2413,17 @@ TStroke *MultiArcPrimitive::makeStroke() const {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void MultiArcPrimitive::leftButtonDown(const TPointD &pos,
const TMouseEvent &e) {
if (m_clickNumber == 0) {
TPointD newPos = calculateSnap(pos, e);
newPos = checkGuideSnapping(pos, e);
m_startPoint = newPos;
}
}
//-----------------------------------------------------------------------------
void MultiArcPrimitive::leftButtonUp(const TPointD &pos, const TMouseEvent &) { void MultiArcPrimitive::leftButtonUp(const TPointD &pos, const TMouseEvent &) {
TTool::Application *app = TTool::getApplication(); TTool::Application *app = TTool::getApplication();
if (!app) return; if (!app) return;

View file

@ -1973,9 +1973,8 @@ void PlasticTool::drawOnionSkinSkeletons_animate(double pixelSize) {
PlasticSkeleton skel; PlasticSkeleton skel;
m_sd->storeDeformedSkeleton(m_sd->skeletonId(sdFrame), sdFrame, skel); m_sd->storeDeformedSkeleton(m_sd->skeletonId(sdFrame), sdFrame, skel);
UCHAR alpha = UCHAR alpha = 255 - 255.0 * OnionSkinMask::getOnionSkinFade(
255 - abs(osRows[r] - currentRow));
255.0 * OnionSkinMask::getOnionSkinFade(abs(osRows[r] - currentRow));
drawSkeleton(skel, pixelSize, alpha); drawSkeleton(skel, pixelSize, alpha);
} }
} }
@ -2114,6 +2113,7 @@ void PlasticTool::draw() {
glPushAttrib(GL_LINE_BIT | GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT); glPushAttrib(GL_LINE_BIT | GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT);
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_LINE_SMOOTH); glEnable(GL_LINE_SMOOTH);
switch (m_mode.getIndex()) { switch (m_mode.getIndex()) {

View file

@ -358,6 +358,7 @@ public:
void setCursorIndexFromPoint(TPointD point); void setCursorIndexFromPoint(TPointD point);
void mouseMove(const TPointD &pos, const TMouseEvent &) override; void mouseMove(const TPointD &pos, const TMouseEvent &) override;
bool preLeftButtonDown() override;
void leftButtonDown(const TPointD &pos, const TMouseEvent &) override; void leftButtonDown(const TPointD &pos, const TMouseEvent &) override;
void rightButtonDown(const TPointD &pos, const TMouseEvent &) override; void rightButtonDown(const TPointD &pos, const TMouseEvent &) override;
bool keyDown(QKeyEvent *event) override; bool keyDown(QKeyEvent *event) override;
@ -1201,6 +1202,15 @@ void TypeTool::mouseMove(const TPointD &pos, const TMouseEvent &) {
//--------------------------------------------------------- //---------------------------------------------------------
bool TypeTool::preLeftButtonDown() {
if (getViewer() && getViewer()->getGuidedStrokePickerMode()) return false;
if (m_validFonts && !m_active) touchImage();
return true;
}
//---------------------------------------------------------
void TypeTool::leftButtonDown(const TPointD &pos, const TMouseEvent &) { void TypeTool::leftButtonDown(const TPointD &pos, const TMouseEvent &) {
TSelection::setCurrent(0); TSelection::setCurrent(0);
@ -1211,11 +1221,7 @@ void TypeTool::leftButtonDown(const TPointD &pos, const TMouseEvent &) {
if (!m_validFonts) return; if (!m_validFonts) return;
TImageP img; TImageP img = getImage(true);
if (!m_active)
img = touchImage();
else
img = getImage(true);
TVectorImageP vi = img; TVectorImageP vi = img;
TToonzImageP ti = img; TToonzImageP ti = img;
@ -1608,7 +1614,7 @@ bool TypeTool::keyDown(QKeyEvent *event) {
invalidate(); invalidate();
break; break;
/////////////////// end cursors /////////////////// end cursors
case Qt::Key_Escape: case Qt::Key_Escape:
resetInputMethod(); resetInputMethod();

View file

@ -175,11 +175,11 @@ AudioRecordingPopup::AudioRecordingPopup()
m_probe->setSource(m_audioRecorder); m_probe->setSource(m_audioRecorder);
QAudioEncoderSettings audioSettings; QAudioEncoderSettings audioSettings;
audioSettings.setCodec("audio/PCM"); audioSettings.setCodec("audio/PCM");
#ifdef MACOSX // setting the sample rate to some value (like 44100)
audioSettings.setSampleRate(-1); // may cause divide-by-zero crash in QAudioDeviceInfo::nearestFormat()
#else // so here we set the value to -1, as the documentation says;
audioSettings.setSampleRate(44100); // "A value of -1 indicates the encoder should make an optimal choice"
#endif audioSettings.setSampleRate(-1);
audioSettings.setChannelCount(1); audioSettings.setChannelCount(1);
audioSettings.setBitRate(16); audioSettings.setBitRate(16);
audioSettings.setEncodingMode(QMultimedia::ConstantBitRateEncoding); audioSettings.setEncodingMode(QMultimedia::ConstantBitRateEncoding);

View file

@ -14,6 +14,7 @@
#include "tapp.h" #include "tapp.h"
#include "xsheetviewer.h" #include "xsheetviewer.h"
#include "levelcommand.h" #include "levelcommand.h"
#include "columncommand.h"
// TnzTools includes // TnzTools includes
#include "tools/toolutils.h" #include "tools/toolutils.h"
@ -120,8 +121,13 @@ void deleteCellsWithoutUndo(int &r0, int &c0, int &r1, int &c1) {
TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet(); TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet();
int c; int c;
for (c = c0; c <= c1; c++) { for (c = c0; c <= c1; c++) {
if (xsh->isColumnEmpty(c)) continue;
xsh->clearCells(r0, c, r1 - r0 + 1); xsh->clearCells(r0, c, r1 - r0 + 1);
TXshColumn *column = xsh->getColumn(c); // when the column becomes empty after deletion,
// ColumnCmd::DeleteColumn() will take care of column related operations
// like disconnecting from fx nodes etc.
/*
TXshColumn* column = xsh->getColumn(c);
if (column && column->isEmpty()) { if (column && column->isEmpty()) {
column->resetColumnProperties(); column->resetColumnProperties();
TFx *fx = column->getFx(); TFx *fx = column->getFx();
@ -135,8 +141,8 @@ void deleteCellsWithoutUndo(int &r0, int &c0, int &r1, int &c1) {
xsh->getStageObjectTree()->removeStageObject( xsh->getStageObjectTree()->removeStageObject(
TStageObjectId::ColumnId(c)); TStageObjectId::ColumnId(c));
} }
*/
} }
TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
} catch (...) { } catch (...) {
DVGui::error(QObject::tr("It is not possible to delete the selection.")); DVGui::error(QObject::tr("It is not possible to delete the selection."));
} }
@ -149,25 +155,52 @@ void cutCellsWithoutUndo(int &r0, int &c0, int &r1, int &c1) {
int c; int c;
for (c = c0; c <= c1; c++) { for (c = c0; c <= c1; c++) {
xsh->removeCells(r0, c, r1 - r0 + 1); xsh->removeCells(r0, c, r1 - r0 + 1);
TXshColumn *column = xsh->getColumn(c); // when the column becomes empty after deletion,
// ColumnCmd::DeleteColumn() will take care of column related operations
// like disconnecting from fx nodes etc.
/*
TXshColumn* column = xsh->getColumn(c);
if (column && column->isEmpty()) { if (column && column->isEmpty()) {
column->resetColumnProperties(); column->resetColumnProperties();
TFx *fx = column->getFx(); TFx* fx = column->getFx();
if (!fx) continue; if (!fx) continue;
int i; int i;
for (i = fx->getOutputConnectionCount() - 1; i >= 0; i--) { for (i = fx->getOutputConnectionCount() - 1; i >= 0; i--) {
TFxPort *port = fx->getOutputConnection(i); TFxPort* port = fx->getOutputConnection(i);
port->setFx(0); port->setFx(0);
} }
xsh->getStageObjectTree()->removeStageObject(TStageObjectId::ColumnId(c)); xsh->getStageObjectTree()->removeStageObject(TStageObjectId::ColumnId(c));
} }
*/
} }
// Se la selezione corrente e' TCellSelection svuoto la selezione. // Se la selezione corrente e' TCellSelection svuoto la selezione.
TCellSelection *cellSelection = dynamic_cast<TCellSelection *>( TCellSelection *cellSelection = dynamic_cast<TCellSelection *>(
TApp::instance()->getCurrentSelection()->getSelection()); TApp::instance()->getCurrentSelection()->getSelection());
if (cellSelection) cellSelection->selectNone(); if (cellSelection) cellSelection->selectNone();
TApp::instance()->getCurrentXsheet()->notifyXsheetChanged(); }
//-----------------------------------------------------------------------------
// check if the operation may remove expression reference as column becomes
// empty and deleted after the operation. return true to continue the operation.
bool checkColumnRemoval(const int r0, const int c0, const int r1, const int c1,
std::set<int> &removedColIds) {
TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet();
// std::set<int> colIndicesToBeRemoved;
for (int c = c0; c <= c1; c++) {
TXshColumnP column = xsh->getColumn(c);
if (!column || column->isEmpty() || column->isLocked()) continue;
int tmp_r0, tmp_r1;
xsh->getCellRange(c, tmp_r0, tmp_r1);
if (r0 <= tmp_r0 && r1 >= tmp_r1) removedColIds.insert(c);
}
if (removedColIds.empty() ||
!Preferences::instance()->isModifyExpressionOnMovingReferencesEnabled())
return true;
std::set<TFx *> dummy_fxs;
return ColumnCmd::checkExpressionReferences(removedColIds, dummy_fxs, true);
} }
//============================================================================= //=============================================================================
@ -239,15 +272,15 @@ public:
//============================================================================= //=============================================================================
// DeleteCellsUndo // DeleteCellsUndo
// Recovering the column information (such as reconnecting nodes) when
// undoing deletion of entire column will be done by DeleteColumnsUndo which
// will be called in the same undo block. So here we only need to recover the
// cell arrangement.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
class DeleteCellsUndo final : public TUndo { class DeleteCellsUndo final : public TUndo {
TCellSelection *m_selection; TCellSelection *m_selection;
QMimeData *m_data; QMimeData *m_data;
QMap<int, QList<TFxPort *>> m_outputConnections;
QMap<int, TXshColumn *> m_columns;
QMap<TStageObjectId, QList<TStageObjectId>> m_columnObjChildren;
QMap<TStageObjectId, TStageObjectId> m_columnObjParents;
public: public:
DeleteCellsUndo(TCellSelection *selection, QMimeData *data) : m_data(data) { DeleteCellsUndo(TCellSelection *selection, QMimeData *data) : m_data(data) {
@ -256,115 +289,26 @@ public:
if (c0 < 0) c0 = 0; // Ignore camera column if (c0 < 0) c0 = 0; // Ignore camera column
m_selection = new TCellSelection(); m_selection = new TCellSelection();
m_selection->selectCells(r0, c0, r1, c1); m_selection->selectCells(r0, c0, r1, c1);
TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet();
int i;
for (i = c0; i <= c1; i++) {
TXshColumn *col = xsh->getColumn(i);
if (!col || col->isEmpty()) continue;
int colr0, colr1;
col->getRange(colr0, colr1);
if (r0 <= colr0 && r1 >= colr1 && !col->getLevelColumn()) {
// la colonna verra' rimossa dall'xsheet
m_columns[i] = col;
col->addRef();
}
// Store TStageObject children in case column is emptied and we need to
// restore it
int pegbarsCount = xsh->getStageObjectTree()->getStageObjectCount();
TStageObjectId id = TStageObjectId::ColumnId(i);
TStageObject *pegbar = xsh->getStageObject(id);
for (int k = 0; k < pegbarsCount; ++k) {
TStageObject *other = xsh->getStageObjectTree()->getStageObject(k);
if (other == pegbar) continue;
if (other->getParent() == id) {
// other->setParent(pegbar->getParent());
m_columnObjChildren[id].append(other->getId());
}
}
// Store TStageObject parent in case column is emptied and we need to
// restore it
m_columnObjParents[id] = pegbar->getParent();
TFx *fx = col->getFx();
if (!fx) continue;
int j;
QList<TFxPort *> fxPorts;
for (j = 0; j < fx->getOutputConnectionCount(); j++)
fxPorts.append(fx->getOutputConnection(j));
if (fxPorts.isEmpty()) continue;
m_outputConnections[i] = fxPorts;
}
} }
~DeleteCellsUndo() { ~DeleteCellsUndo() { delete m_selection; }
delete m_selection;
QMap<int, TXshColumn *>::iterator it;
for (it = m_columns.begin(); it != m_columns.end(); it++)
it.value()->release();
}
void undo() const override { void undo() const override {
TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet(); TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet();
// devo rimettere le colonne che ho rimosso dall'xsheet
QMap<int, TXshColumn *>::const_iterator colIt;
for (colIt = m_columns.begin(); colIt != m_columns.end(); colIt++) {
int index = colIt.key();
TXshColumn *column = colIt.value();
xsh->removeColumn(index);
xsh->insertColumn(index, column);
}
int r0, c0, r1, c1; int r0, c0, r1, c1;
m_selection->getSelectedCells(r0, c0, r1, c1); m_selection->getSelectedCells(r0, c0, r1, c1);
QMap<int, QList<TFxPort *>>::const_iterator it;
for (it = m_outputConnections.begin(); it != m_outputConnections.end();
it++) {
TXshColumn *col = xsh->getColumn(it.key());
QList<TFxPort *> fxPorts = it.value();
int i;
for (i = 0; i < fxPorts.size(); i++) fxPorts[i]->setFx(col->getFx());
}
// Restore TStageObject parent
QMap<TStageObjectId, TStageObjectId>::const_iterator it2;
for (it2 = m_columnObjParents.begin(); it2 != m_columnObjParents.end();
it2++) { // Parents
TStageObject *obj = xsh->getStageObject(it2.key());
if (obj) {
obj->setParent(it2.value());
}
}
// Restore TStageObject children
QMap<TStageObjectId, QList<TStageObjectId>>::const_iterator it3;
for (it3 = m_columnObjChildren.begin(); it3 != m_columnObjChildren.end();
it3++) { // Children
QList<TStageObjectId> children = it3.value();
int i;
for (i = 0; i < children.size(); i++) {
TStageObject *child = xsh->getStageObject(children[i]);
if (child) {
child->setParent(it3.key());
}
}
}
const TCellData *cellData = dynamic_cast<const TCellData *>(m_data); const TCellData *cellData = dynamic_cast<const TCellData *>(m_data);
pasteCellsWithoutUndo(cellData, r0, c0, r1, c1, false, false); pasteCellsWithoutUndo(cellData, r0, c0, r1, c1, false, false);
TApp::instance()->getCurrentXsheet()->notifyXsheetChanged(); TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
TApp::instance()->getCurrentObject()->notifyObjectIdSwitched();
} }
void redo() const override { void redo() const override {
int r0, c0, r1, c1; int r0, c0, r1, c1;
m_selection->getSelectedCells(r0, c0, r1, c1); m_selection->getSelectedCells(r0, c0, r1, c1);
deleteCellsWithoutUndo(r0, c0, r1, c1); deleteCellsWithoutUndo(r0, c0, r1, c1);
TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
} }
int getSize() const override { return sizeof(*this); } int getSize() const override { return sizeof(*this); }
@ -375,14 +319,14 @@ public:
//============================================================================= //=============================================================================
// CutCellsUndo // CutCellsUndo
// Just like DeleteCellsUndo, recovering the column information (such as
// reconnecting nodes) when undoing deletion of entire column will be done
// by DeleteColumnsUndo which will be called in the same undo block.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
class CutCellsUndo final : public TUndo { class CutCellsUndo final : public TUndo {
TCellSelection *m_selection; TCellSelection *m_selection;
TCellData *m_data; TCellData *m_data;
QMap<int, QList<TFxPort *>> m_outputConnections;
QMap<TStageObjectId, QList<TStageObjectId>> m_columnObjChildren;
QMap<TStageObjectId, TStageObjectId> m_columnObjParents;
public: public:
CutCellsUndo(TCellSelection *selection) : m_data() { CutCellsUndo(TCellSelection *selection) : m_data() {
@ -391,41 +335,6 @@ public:
if (c0 < 0) c0 = 0; // Ignore camera column if (c0 < 0) c0 = 0; // Ignore camera column
m_selection = new TCellSelection(); m_selection = new TCellSelection();
m_selection->selectCells(r0, c0, r1, c1); m_selection->selectCells(r0, c0, r1, c1);
TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet();
int i;
for (i = c0; i <= c1; i++) {
TXshColumn *col = xsh->getColumn(i);
if (!col || col->isEmpty()) continue;
// Store TStageObject children in case column is emptied and we need to
// restore it
int pegbarsCount = xsh->getStageObjectTree()->getStageObjectCount();
TStageObjectId id = TStageObjectId::ColumnId(i);
TStageObject *pegbar = xsh->getStageObject(id);
for (int k = 0; k < pegbarsCount; ++k) {
TStageObject *other = xsh->getStageObjectTree()->getStageObject(k);
if (other == pegbar) continue;
if (other->getParent() == id) {
// other->setParent(pegbar->getParent());
m_columnObjChildren[id].append(other->getId());
}
}
// Store TStageObject parent in case column is emptied and we need to
// restore it
m_columnObjParents[id] = pegbar->getParent();
TFx *fx = col->getFx();
if (!fx) continue;
int j;
QList<TFxPort *> fxPorts;
for (j = 0; j < fx->getOutputConnectionCount(); j++)
fxPorts.append(fx->getOutputConnection(j));
if (fxPorts.isEmpty()) continue;
m_outputConnections[i] = fxPorts;
}
} }
void setCurrentData(int r0, int c0, int r1, int c1) { void setCurrentData(int r0, int c0, int r1, int c1) {
@ -443,43 +352,8 @@ public:
int r0, c0, r1, c1; int r0, c0, r1, c1;
m_selection->getSelectedCells(r0, c0, r1, c1); m_selection->getSelectedCells(r0, c0, r1, c1);
TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet();
QMap<int, QList<TFxPort *>>::const_iterator it;
for (it = m_outputConnections.begin(); it != m_outputConnections.end();
it++) {
TXshColumn *col = xsh->getColumn(it.key());
QList<TFxPort *> fxPorts = it.value();
int i;
for (i = 0; i < fxPorts.size(); i++) fxPorts[i]->setFx(col->getFx());
}
// Restore TStageObject parent
QMap<TStageObjectId, TStageObjectId>::const_iterator it2;
for (it2 = m_columnObjParents.begin(); it2 != m_columnObjParents.end();
it2++) { // Parents
TStageObject *obj = xsh->getStageObject(it2.key());
if (obj) {
obj->setParent(it2.value());
}
}
// Restore TStageObject children
QMap<TStageObjectId, QList<TStageObjectId>>::const_iterator it3;
for (it3 = m_columnObjChildren.begin(); it3 != m_columnObjChildren.end();
it3++) { // Children
QList<TStageObjectId> children = it3.value();
int i;
for (i = 0; i < children.size(); i++) {
TStageObject *child = xsh->getStageObject(children[i]);
if (child) {
child->setParent(it3.key());
}
}
}
pasteCellsWithoutUndo(m_data, r0, c0, r1, c1, true); pasteCellsWithoutUndo(m_data, r0, c0, r1, c1, true);
TApp::instance()->getCurrentXsheet()->notifyXsheetChanged(); TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
TApp::instance()->getCurrentObject()->notifyObjectIdSwitched();
} }
void redo() const override { void redo() const override {
@ -491,6 +365,7 @@ public:
cutCellsWithoutUndo(r0, c0, r1, c1); cutCellsWithoutUndo(r0, c0, r1, c1);
clipboard->setMimeData(currentData, QClipboard::Clipboard); clipboard->setMimeData(currentData, QClipboard::Clipboard);
TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
} }
int getSize() const override { return sizeof(*this); } int getSize() const override { return sizeof(*this); }
@ -779,6 +654,8 @@ bool pasteRasterImageInCellWithoutUndo(int row, int col,
app->getCurrentLevel()->setLevel(sl); app->getCurrentLevel()->setLevel(sl);
app->getCurrentLevel()->notifyLevelChange(); app->getCurrentLevel()->notifyLevelChange();
sl->save(); sl->save();
// after saving you need to obtain the image again
img = sl->getFrame(fid, true);
} else { } else {
img = sl->createEmptyFrame(); img = sl->createEmptyFrame();
assert(img); assert(img);
@ -788,6 +665,8 @@ bool pasteRasterImageInCellWithoutUndo(int row, int col,
sl->setFrame(fid, img); sl->setFrame(fid, img);
} }
xsh->setCell(row, col, TXshCell(sl, fid)); xsh->setCell(row, col, TXshCell(sl, fid));
// to let the undo to know which frame is edited
TTool::m_cellsData.push_back({row, row, TTool::CellOps::BlankToNew});
} else { } else {
sl = cell.getSimpleLevel(); sl = cell.getSimpleLevel();
fid = cell.getFrameId(); fid = cell.getFrameId();
@ -1785,6 +1664,8 @@ static void pasteRasterImageInCell(int row, int col,
bool newLevel = false) { bool newLevel = false) {
TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet(); TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet();
// to let the undo to know which frame is edited
TTool::m_cellsData.clear();
bool createdFrame = false; bool createdFrame = false;
bool isLevelCreated = false; bool isLevelCreated = false;
TPaletteP oldPalette = 0; TPaletteP oldPalette = 0;
@ -2599,12 +2480,36 @@ void TCellSelection::deleteCells() {
TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet(); TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet();
// if all the selected cells are already empty, then do nothing // if all the selected cells are already empty, then do nothing
if (xsh->isRectEmpty(CellPosition(r0, c0), CellPosition(r1, c1))) return; if (xsh->isRectEmpty(CellPosition(r0, c0), CellPosition(r1, c1))) return;
std::set<int> removedColIds;
// check if the operation may remove expression reference as column becomes
// empty and deleted after the operation.
if (!checkColumnRemoval(r0, c0, r1, c1, removedColIds)) return;
TCellData *data = new TCellData(); TCellData *data = new TCellData();
data->setCells(xsh, r0, c0, r1, c1); data->setCells(xsh, r0, c0, r1, c1);
// clear empty column
if (!removedColIds.empty()) {
TUndoManager::manager()->beginBlock();
// remove, then insert empty column
for (auto colId : removedColIds) {
ColumnCmd::deleteColumn(colId, true);
ColumnCmd::insertEmptyColumn(colId);
}
}
DeleteCellsUndo *undo = DeleteCellsUndo *undo =
new DeleteCellsUndo(new TCellSelection(m_range), data); new DeleteCellsUndo(new TCellSelection(m_range), data);
deleteCellsWithoutUndo(r0, c0, r1, c1); deleteCellsWithoutUndo(r0, c0, r1, c1);
TUndoManager::manager()->add(undo);
if (!removedColIds.empty()) {
TUndoManager::manager()->endBlock();
}
// emit selectionChanged() signal so that the rename field will update // emit selectionChanged() signal so that the rename field will update
// accordingly // accordingly
if (Preferences::instance()->isUseArrowKeyToShiftCellSelectionEnabled()) if (Preferences::instance()->isUseArrowKeyToShiftCellSelectionEnabled())
@ -2612,8 +2517,8 @@ void TCellSelection::deleteCells() {
else else
selectNone(); selectNone();
TUndoManager::manager()->add(undo);
TApp::instance()->getCurrentScene()->setDirtyFlag(true); TApp::instance()->getCurrentScene()->setDirtyFlag(true);
TApp::instance()->getCurrentXsheet()->notifyXsheetChanged();
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -2631,11 +2536,32 @@ void TCellSelection::cutCells(bool withoutCopy) {
getSelectedCells(r0, c0, r1, c1); getSelectedCells(r0, c0, r1, c1);
if (c0 < 0) c0 = 0; // Ignore camera column if (c0 < 0) c0 = 0; // Ignore camera column
std::set<int> removedColIds;
// check if the operation may remove expression reference as column becomes
// empty and deleted after the operation.
if (!checkColumnRemoval(r0, c0, r1, c1, removedColIds)) return;
undo->setCurrentData(r0, c0, r1, c1); undo->setCurrentData(r0, c0, r1, c1);
if (!withoutCopy) copyCellsWithoutUndo(r0, c0, r1, c1); if (!withoutCopy) copyCellsWithoutUndo(r0, c0, r1, c1);
// clear empty column
if (!removedColIds.empty()) {
TUndoManager::manager()->beginBlock();
// remove, then insert empty column
for (auto colId : removedColIds) {
ColumnCmd::deleteColumn(colId, true);
ColumnCmd::insertEmptyColumn(colId);
}
}
cutCellsWithoutUndo(r0, c0, r1, c1); cutCellsWithoutUndo(r0, c0, r1, c1);
TUndoManager::manager()->add(undo); TUndoManager::manager()->add(undo);
if (!removedColIds.empty()) {
TUndoManager::manager()->endBlock();
}
// cutCellsWithoutUndo will clear the selection, so select cells again // cutCellsWithoutUndo will clear the selection, so select cells again
if (Preferences::instance()->isUseArrowKeyToShiftCellSelectionEnabled()) { if (Preferences::instance()->isUseArrowKeyToShiftCellSelectionEnabled()) {
selectCells(r0, c0, r1, c1); selectCells(r0, c0, r1, c1);

View file

@ -310,6 +310,9 @@ CleanupPopup::CleanupPopup()
m_imgViewBox->setChecked(false); m_imgViewBox->setChecked(false);
m_imageViewer->setVisible(false); m_imageViewer->setVisible(false);
m_imageViewer->resize(406, 306); m_imageViewer->resize(406, 306);
ImagePainter::VisualSettings settings;
settings.m_bg = 0x80000; // set to white regardless of the flipbook bg
m_imageViewer->setVisual(settings);
//---layout //---layout
QVBoxLayout *mainLayout = new QVBoxLayout(); QVBoxLayout *mainLayout = new QVBoxLayout();
@ -563,7 +566,8 @@ bool CleanupPopup::analyzeCleanupList() {
} }
// Prompt user for file conflict resolution // Prompt user for file conflict resolution
clt.m_resolution = Resolution(m_overwriteDialog->execute(&clt.m_outputPath)); clt.m_resolution =
Resolution(m_overwriteDialog->execute(&clt.m_outputPath));
switch (clt.m_resolution) { switch (clt.m_resolution) {
case CANCEL: case CANCEL:
return false; return false;
@ -1253,7 +1257,9 @@ void CleanupPopup::cleanupFrame() {
// Update the level data about the cleanupped frame // Update the level data about the cleanupped frame
sl->setFrameStatus(fid, sl->setFrameStatus(fid,
sl->getFrameStatus(fid) | TXshSimpleLevel::Cleanupped); sl->getFrameStatus(fid) | TXshSimpleLevel::Cleanupped);
sl->setFrame(fid, TImageP()); // Invalidate the old image data
// sl->setFrame(fid, TImageP()); // Invalidate the old image data
sl->setFrame(fid, ti); // replace with the new image data
// Output the cleanupped image to disk // Output the cleanupped image to disk
try { try {

View file

@ -303,11 +303,13 @@ void ColorModelViewer::pick(const QPoint &p) {
TPointD(viewP.x() - m_imageViewer->width() / 2, TPointD(viewP.x() - m_imageViewer->width() / 2,
-viewP.y() + m_imageViewer->height() / 2); -viewP.y() + m_imageViewer->height() / 2);
double scale2 = m_imageViewer->getViewAff().det();
/*--- /*---
Toolに合わせてPickモードを変更 Toolに合わせてPickモードを変更
0=Area, 1=Line, 2=Line&Areas(default) 0=Area, 1=Line, 2=Line&Areas(default)
---*/ ---*/
int styleIndex = picker.pickStyleId(pos + TPointD(-0.5, -0.5), 1, m_mode); int styleIndex =
picker.pickStyleId(pos + TPointD(-0.5, -0.5), 1, scale2, m_mode);
if (styleIndex < 0) return; if (styleIndex < 0) return;

View file

@ -539,10 +539,13 @@ class DeleteColumnsUndo final : public TUndo {
QMap<TStageObjectId, TStageObjectId> m_columnObjParents; QMap<TStageObjectId, TStageObjectId> m_columnObjParents;
mutable std::unique_ptr<StageObjectsData> m_data; mutable std::unique_ptr<StageObjectsData> m_data;
bool m_onlyColumns;
public: public:
DeleteColumnsUndo(const std::set<int> &indices) DeleteColumnsUndo(const std::set<int> &indices, bool onlyColumns)
: m_indices(indices), m_data(new StageObjectsData) { : m_indices(indices)
, m_data(new StageObjectsData)
, m_onlyColumns(onlyColumns) {
TApp *app = TApp::instance(); TApp *app = TApp::instance();
TXsheet *xsh = app->getCurrentXsheet()->getXsheet(); TXsheet *xsh = app->getCurrentXsheet()->getXsheet();
@ -597,7 +600,7 @@ public:
m_data->storeColumnFxs(m_indices, xsh, 0); m_data->storeColumnFxs(m_indices, xsh, 0);
std::set<int> indices = m_indices; std::set<int> indices = m_indices;
deleteColumnsWithoutUndo(&indices); deleteColumnsWithoutUndo(&indices, m_onlyColumns);
} }
void undo() const override { void undo() const override {
@ -816,8 +819,8 @@ void ColumnCmd::deleteColumns(std::set<int> &indices, bool onlyColumns,
indices.erase(-1); // Ignore camera column indices.erase(-1); // Ignore camera column
if (indices.empty()) return; if (indices.empty()) return;
if (!withoutUndo && !onlyColumns) if (!withoutUndo)
TUndoManager::manager()->add(new DeleteColumnsUndo(indices)); TUndoManager::manager()->add(new DeleteColumnsUndo(indices, onlyColumns));
deleteColumnsWithoutUndo(&indices, onlyColumns); deleteColumnsWithoutUndo(&indices, onlyColumns);
TApp::instance()->getCurrentScene()->setDirtyFlag(true); TApp::instance()->getCurrentScene()->setDirtyFlag(true);
@ -827,10 +830,10 @@ void ColumnCmd::deleteColumns(std::set<int> &indices, bool onlyColumns,
// deleteColumn // deleteColumn
//============================================================================= //=============================================================================
void ColumnCmd::deleteColumn(int index) { void ColumnCmd::deleteColumn(int index, bool onlyColumns) {
std::set<int> ii; std::set<int> ii;
ii.insert(index); ii.insert(index);
ColumnCmd::deleteColumns(ii, false, false); ColumnCmd::deleteColumns(ii, onlyColumns, false);
} }
//============================================================================= //=============================================================================
@ -845,7 +848,7 @@ static void cutColumnsWithoutUndo(std::set<int> *indices) {
void ColumnCmd::cutColumns(std::set<int> &indices) { void ColumnCmd::cutColumns(std::set<int> &indices) {
if (indices.empty()) return; if (indices.empty()) return;
TUndoManager::manager()->add(new DeleteColumnsUndo(indices)); TUndoManager::manager()->add(new DeleteColumnsUndo(indices, false));
cutColumnsWithoutUndo(&indices); cutColumnsWithoutUndo(&indices);
TApp::instance()->getCurrentScene()->setDirtyFlag(true); TApp::instance()->getCurrentScene()->setDirtyFlag(true);

View file

@ -24,7 +24,7 @@ void cutColumns(std::set<int> &indices);
//! deleted //! deleted
void deleteColumns(std::set<int> &indices, bool onlyColumns, bool withoutUndo); void deleteColumns(std::set<int> &indices, bool onlyColumns, bool withoutUndo);
//! helper function: deletes a single column, with undo //! helper function: deletes a single column, with undo
void deleteColumn(int index); void deleteColumn(int index, bool onlyColumns = false);
//! if data==0 then uses clipboard //! if data==0 then uses clipboard
void pasteColumns(std::set<int> &indices, const StageObjectsData *data = 0); void pasteColumns(std::set<int> &indices, const StageObjectsData *data = 0);
//! helper function: copies srcIndex column and pastes it before dstIndex. Does //! helper function: copies srcIndex column and pastes it before dstIndex. Does

View file

@ -412,8 +412,11 @@ std::map<TFrameId, QString> clearFramesWithoutUndo(
"-" + QString::number(it->getNumber()); "-" + QString::number(it->getNumber());
TImageCache::instance()->add(id, sl->getFrame(frameId, false)); TImageCache::instance()->add(id, sl->getFrame(frameId, false));
clearedFrames[frameId] = id; clearedFrames[frameId] = id;
// empty frame must be created BEFORE erasing frame or it may initialize
// palette.
TImageP emptyFrame = sl->createEmptyFrame();
sl->eraseFrame(frameId); sl->eraseFrame(frameId);
sl->setFrame(*it, sl->createEmptyFrame()); sl->setFrame(*it, emptyFrame);
} }
invalidateIcons(sl.getPointer(), frames); invalidateIcons(sl.getPointer(), frames);
TApp::instance()->getCurrentLevel()->notifyLevelChange(); TApp::instance()->getCurrentLevel()->notifyLevelChange();

View file

@ -1345,6 +1345,8 @@ void ImageViewer::onContextAboutToBeDestroyed() {
makeCurrent(); makeCurrent();
m_lutCalibrator->cleanup(); m_lutCalibrator->cleanup();
doneCurrent(); doneCurrent();
disconnect(context(), SIGNAL(aboutToBeDestroyed()), this,
SLOT(onContextAboutToBeDestroyed()));
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -1352,6 +1354,9 @@ void ImageViewer::onContextAboutToBeDestroyed() {
void ImageViewer::onPreferenceChanged(const QString& prefName) { void ImageViewer::onPreferenceChanged(const QString& prefName) {
if (prefName == "ColorCalibration") { if (prefName == "ColorCalibration") {
if (Preferences::instance()->isColorCalibrationEnabled()) { if (Preferences::instance()->isColorCalibrationEnabled()) {
// if the window is so shriked that the gl widget is empty,
// showEvent can be called before creating the context.
if (!context()) return;
makeCurrent(); makeCurrent();
if (!m_lutCalibrator) if (!m_lutCalibrator)
m_lutCalibrator = new LutCalibrator(); m_lutCalibrator = new LutCalibrator();

View file

@ -671,6 +671,16 @@ void ChildLevelResourceImporter::process(TXshSimpleLevel *sl) {
sl->load(); sl->load();
} catch (...) { } catch (...) {
} }
// Check if the scene saved with the previous version AND the premultiply
// option is set to PNG level setting
if (m_childScene->getVersionNumber() <
VersionNumber(71, 1)) { // V1.4 = 71.0 , V1.5 = 71.1
if (!path.isEmpty() && path.getType() == "png" &&
sl->getProperties()->doPremultiply())
sl->getProperties()->setDoPremultiply(false);
}
sl->release(); sl->release();
} }
@ -1994,6 +2004,31 @@ bool IoCmd::loadScene(const TFilePath &path, bool updateRecentFile,
} }
} }
// Check if the scene saved with the previous version AND the premultiply
// option is set to PNG level setting
if (scene->getVersionNumber() <
VersionNumber(71, 1)) { // V1.4 = 71.0 , V1.5 = 71.1
QStringList modifiedPNGLevelNames;
std::vector<TXshLevel *> levels;
scene->getLevelSet()->listLevels(levels);
for (auto level : levels) {
if (!level || !level->getSimpleLevel()) continue;
TFilePath path = level->getPath();
if (path.isEmpty() || path.getType() != "png") continue;
if (level->getSimpleLevel()->getProperties()->doPremultiply()) {
level->getSimpleLevel()->getProperties()->setDoPremultiply(false);
modifiedPNGLevelNames.append(QString::fromStdWString(level->getName()));
}
}
if (!modifiedPNGLevelNames.isEmpty()) {
DVGui::info(QObject::tr("The Premultiply options in the following levels "
"are disabled, since PNG files are premultiplied "
"on loading in the current version: %1")
.arg(modifiedPNGLevelNames.join(", ")));
app->getCurrentScene()->setDirtyFlag(true);
}
}
printf("%s:%s loadScene() completed :\n", __FILE__, __FUNCTION__); printf("%s:%s loadScene() completed :\n", __FILE__, __FUNCTION__);
return true; return true;
} }

View file

@ -55,6 +55,9 @@
#include <QPushButton> #include <QPushButton>
#include <QLabel> #include <QLabel>
#include <QMessageBox> #include <QMessageBox>
#ifdef _WIN32
#include <QtPlatformHeaders/QWindowsWindowFunctions>
#endif
TEnv::IntVar ViewCameraToggleAction("ViewCameraToggleAction", 1); TEnv::IntVar ViewCameraToggleAction("ViewCameraToggleAction", 1);
TEnv::IntVar ViewTableToggleAction("ViewTableToggleAction", 0); TEnv::IntVar ViewTableToggleAction("ViewTableToggleAction", 0);
@ -1264,9 +1267,16 @@ void MainWindow::maximizePanel() {
void MainWindow::fullScreenWindow() { void MainWindow::fullScreenWindow() {
if (isFullScreen()) if (isFullScreen())
setWindowState(Qt::WindowMaximized); showNormal();
else else {
setWindowState(Qt::WindowFullScreen); #if defined(_WIN32)
// http://doc.qt.io/qt-5/windows-issues.html#fullscreen-opengl-based-windows
this->winId();
QWindowsWindowFunctions::setHasBorderInFullScreen(this->windowHandle(),
true);
#endif
this->showFullScreen();
}
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View file

@ -263,34 +263,23 @@ void TPanelTitleBarButton::setPressed(bool pressed) {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void TPanelTitleBarButton::paintEvent(QPaintEvent *event) { void TPanelTitleBarButton::paintEvent(QPaintEvent *event) {
// Set unique pressed colors if filename contains the following words:
QColor bgColor = getPressedColor();
if (m_standardPixmapName.contains("freeze", Qt::CaseInsensitive))
bgColor = getFreezeColor();
if (m_standardPixmapName.contains("preview", Qt::CaseInsensitive))
bgColor = getPreviewColor();
QPixmap panePixmap = recolorPixmap(svgToPixmap(m_standardPixmapName));
QPixmap panePixmapOff = compositePixmap(panePixmap, 0.8);
QPixmap panePixmapOver =
compositePixmap(panePixmap, 1, QSize(), 0, 0, getOverColor());
QPixmap panePixmapOn = compositePixmap(panePixmap, 1, QSize(), 0, 0, bgColor);
QPainter painter(this); QPainter painter(this);
// Create color states for the button
QPixmap normalPixmap(m_standardPixmap.size());
QPixmap onPixmap(m_standardPixmap.size());
QPixmap overPixmap(m_standardPixmap.size());
normalPixmap.fill(Qt::transparent);
onPixmap.fill(QColor(getPressedColor()));
overPixmap.fill(QColor(getOverColor()));
// Set unique 'pressed' colors if filename contains...
if (m_standardPixmapName.contains("freeze", Qt::CaseInsensitive)) {
onPixmap.fill(QColor(getFreezeColor()));
}
if (m_standardPixmapName.contains("preview", Qt::CaseInsensitive)) {
onPixmap.fill(QColor(getPreviewColor()));
}
// Compose the state colors
painter.drawPixmap( painter.drawPixmap(
0, 0, m_pressed ? onPixmap : m_rollover ? overPixmap : normalPixmap); 0, 0,
m_pressed ? panePixmapOn : m_rollover ? panePixmapOver : panePixmapOff);
// Icon
QPixmap panePixmap = recolorPixmap(m_standardPixmap);
QPixmap paneOffPixmap = setOpacity(panePixmap, 0.8);
painter.drawPixmap(
0, 0, m_pressed ? panePixmap : m_rollover ? panePixmap : paneOffPixmap);
painter.end(); painter.end();
} }

View file

@ -1209,6 +1209,9 @@ void SceneViewer::onStopMotionLiveViewStopped() {
void SceneViewer::onPreferenceChanged(const QString &prefName) { void SceneViewer::onPreferenceChanged(const QString &prefName) {
if (prefName == "ColorCalibration") { if (prefName == "ColorCalibration") {
if (Preferences::instance()->isColorCalibrationEnabled()) { if (Preferences::instance()->isColorCalibrationEnabled()) {
// if the window is so shriked that the gl widget is empty,
// showEvent can be called before creating the context.
if (!context()) return;
makeCurrent(); makeCurrent();
if (!m_lutCalibrator) if (!m_lutCalibrator)
m_lutCalibrator = new LutCalibrator(); m_lutCalibrator = new LutCalibrator();
@ -3555,6 +3558,8 @@ void SceneViewer::onContextAboutToBeDestroyed() {
makeCurrent(); makeCurrent();
m_lutCalibrator->cleanup(); m_lutCalibrator->cleanup();
doneCurrent(); doneCurrent();
disconnect(context(), SIGNAL(aboutToBeDestroyed()), this,
SLOT(onContextAboutToBeDestroyed()));
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View file

@ -16,6 +16,8 @@
#include "comboviewerpane.h" #include "comboviewerpane.h"
#include "locatorpopup.h" #include "locatorpopup.h"
#include "cellselection.h" #include "cellselection.h"
#include "styleshortcutswitchablepanel.h"
#include "stopmotion.h" #include "stopmotion.h"
#include "tstopwatch.h" #include "tstopwatch.h"
@ -1634,6 +1636,15 @@ void SceneViewer::keyPressEvent(QKeyEvent *event) {
event->modifiers() == Qt::KeypadModifier) && event->modifiers() == Qt::KeypadModifier) &&
((Qt::Key_0 <= key && key <= Qt::Key_9) || key == Qt::Key_Tab || ((Qt::Key_0 <= key && key <= Qt::Key_9) || key == Qt::Key_Tab ||
key == Qt::Key_Backtab)) { key == Qt::Key_Backtab)) {
// When the viewer is in full screen mode, directly call the style
// shortcut function since the viewer is retrieved from the parent
// panel.
if (parentWidget() &&
parentWidget()->windowState() & Qt::WindowFullScreen) {
StyleShortcutSwitchablePanel::onKeyPress(event);
return true;
}
event->ignore(); event->ignore();
return true; return true;
} }

View file

@ -21,7 +21,7 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void StyleShortcutSwitchablePanel::keyPressEvent(QKeyEvent *event) { void StyleShortcutSwitchablePanel::onKeyPress(QKeyEvent *event) {
if (!Preferences::instance()->isUseNumpadForSwitchingStylesEnabled()) return; if (!Preferences::instance()->isUseNumpadForSwitchingStylesEnabled()) return;
TTool *tool = TApp::instance()->getCurrentTool()->getTool(); TTool *tool = TApp::instance()->getCurrentTool()->getTool();
if (!tool) return; if (!tool) return;
@ -57,6 +57,11 @@ void StyleShortcutSwitchablePanel::keyPressEvent(QKeyEvent *event) {
event->accept(); event->accept();
} }
} }
//-----------------------------------------------------------------------------
void StyleShortcutSwitchablePanel::keyPressEvent(QKeyEvent *event) {
StyleShortcutSwitchablePanel::onKeyPress(event);
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View file

@ -26,6 +26,8 @@ public:
TDockWidget::Orientation orientation = TDockWidget::vertical) TDockWidget::Orientation orientation = TDockWidget::vertical)
: TPanel(parent, flags, orientation) {} : TPanel(parent, flags, orientation) {}
static void onKeyPress(QKeyEvent *event);
protected: protected:
void keyPressEvent(QKeyEvent *event) override; void keyPressEvent(QKeyEvent *event) override;
void showEvent(QShowEvent *) override; void showEvent(QShowEvent *) override;

View file

@ -463,6 +463,8 @@ bool XdtsIo::loadXdtsScene(ToonzScene *scene, const TFilePath &scenePath) {
// obtain level names // obtain level names
QStringList levelNames = xdtsData.getLevelNames(); QStringList levelNames = xdtsData.getLevelNames();
// in case multiple columns have the same name
levelNames.removeDuplicates();
scene->clear(); scene->clear();

View file

@ -474,15 +474,12 @@ NoteArea::NoteArea(XsheetViewer *parent, Qt::WFlags flags)
m_layerHeaderPanel = new LayerHeaderPanel(m_viewer, this); m_layerHeaderPanel = new LayerHeaderPanel(m_viewer, this);
//----- //-----
//
// m_flipOrientationButton->setObjectName("flipOrientationButton"); // m_flipOrientationButton->setObjectName("flipOrientationButton");
// m_flipOrientationButton->setFocusPolicy(Qt::FocusPolicy::NoFocus); // m_flipOrientationButton->setFocusPolicy(Qt::FocusPolicy::NoFocus);
// m_flipOrientationButton->setFixedSize(QSize(70, 23)); // m_flipOrientationButton->setFixedSize(QSize(70, 23));
// m_flipOrientationButton->setIconSize(QSize(40, 20)); // m_flipOrientationButton->setIconSize(QSize(20, 20));
// QIcon flipOrientationIcon; // m_flipOrientationButton->setIcon(createQIcon("toggle_xsheet_orientation"));
// flipOrientationIcon.addFile(QString(":Resources/xsheet2timeline.svg"),
// QSize(), QIcon::Normal);
// m_flipOrientationButton->setIcon(flipOrientationIcon);
// m_flipOrientationButton->setToolTip(tr("Toggle Xsheet/Timeline")); // m_flipOrientationButton->setToolTip(tr("Toggle Xsheet/Timeline"));
m_newLevelButton->setObjectName("ToolbarToolButton"); m_newLevelButton->setObjectName("ToolbarToolButton");
@ -646,12 +643,8 @@ void NoteArea::updateButtons() {
void NoteArea::onXsheetOrientationChanged(const Orientation *newOrientation) { void NoteArea::onXsheetOrientationChanged(const Orientation *newOrientation) {
// m_flipOrientationButton->setText(newOrientation->caption()); // m_flipOrientationButton->setText(newOrientation->caption());
// QIcon flipOrientationIcon; // m_flipOrientationButton->setIcon(createQIcon("toggle_xsheet_orientation"));
// QString iconFile = newOrientation->isVerticalTimeline() // m_flipOrientationButton->setIconSize(QSize(20, 20));
// ? QString(":Resources/xsheet2timeline.svg")
// : QString(":Resources/timeline2xsheet.svg");
// flipOrientationIcon.addFile(iconFile, QSize(), QIcon::Normal);
// m_flipOrientationButton->setIcon(flipOrientationIcon);
removeLayout(); removeLayout();
createLayout(); createLayout();

View file

@ -109,9 +109,10 @@ void getDefaultLevelFormats(LevelFormatVector &lfv) {
lfv[1].m_options.m_premultiply = true; lfv[1].m_options.m_premultiply = true;
// for all PNG files, set premultiply by default // for all PNG files, set premultiply by default
lfv[2].m_name = Preferences::tr("PNG"); // UPDATE : from V1.5, PNG images are premultiplied on loading
lfv[2].m_pathFormat = QRegExp("..*\\.png", Qt::CaseInsensitive); // lfv[2].m_name = Preferences::tr("PNG");
lfv[2].m_options.m_premultiply = true; // lfv[2].m_pathFormat = QRegExp("..*\\.png",
// Qt::CaseInsensitive); lfv[2].m_options.m_premultiply = true;
} }
} }
@ -193,6 +194,32 @@ void getValue(QSettings &settings,
getValue(settings, lfv[lf]); getValue(settings, lfv[lf]);
} }
settings.endArray(); settings.endArray();
// from OT V1.5, PNG images are premultiplied on loading.
// Leaving the premultiply option will cause unwanted double operation.
// So, check the loaded options and modify it "silently".
bool changed = false;
LevelFormatVector::iterator it = lfv.begin();
while (it != lfv.end()) {
if ((*it).m_name == Preferences::tr("PNG") &&
(*it).m_pathFormat == QRegExp("..*\\.png", Qt::CaseInsensitive) &&
(*it).m_options.m_premultiply == true) {
LevelOptions defaultValue;
defaultValue.m_premultiply = true;
// if other parameters are the same as deafault, just erase the item
if ((*it).m_options == defaultValue) it = lfv.erase(it);
// if there are some adjustments by user, then disable only premultiply
// option
else {
(*it).m_options.m_premultiply = false;
++it;
}
changed = true;
} else
++it;
}
// overwrite the setting
if (changed) _setValue(settings, lfv);
} }
} // namespace } // namespace

View file

@ -1405,6 +1405,7 @@ void onMeshImage(TMeshImage *mi, const Stage::Player &player,
// Prepare OpenGL // Prepare OpenGL
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_LINE_SMOOTH); glEnable(GL_LINE_SMOOTH);
// Push mesh coordinates // Push mesh coordinates
@ -1581,6 +1582,7 @@ void onPlasticDeformedImage(TStageObject *playerObj,
// Set up OpenGL stuff // Set up OpenGL stuff
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_LINE_SMOOTH); glEnable(GL_LINE_SMOOTH);
// Push mesh coordinates // Push mesh coordinates

View file

@ -591,7 +591,7 @@ void StudioPaletteCmd::mergeIntoCurrentPalette(TPaletteHandle *paletteHandle,
TUndoManager::manager()->add( TUndoManager::manager()->add(
new PaletteAssignUndo(current, old, current->clone(), paletteHandle)); new PaletteAssignUndo(current, old, current->clone(), paletteHandle));
palette->setDirtyFlag(true); current->setDirtyFlag(true);
paletteHandle->notifyPaletteChanged(); paletteHandle->notifyPaletteChanged();
} }

View file

@ -60,8 +60,11 @@ TOfflineGL *currentOfflineGL = 0;
// Utility functions // Utility functions
//============================================================================= //=============================================================================
namespace { namespace {
// tentatively update the scene file version from 71.0 to 71.1 in order to
const VersionNumber l_currentVersion(71, 0); // manage PNG level settings
const VersionNumber l_currentVersion(71, 1);
// TODO: Revise VersionNumber with OT version (converting 71.0 -> 14.0 , 71.1
// -> 15.0)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -345,12 +348,9 @@ bool ToonzScene::isUntitled() const {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void ToonzScene::load(const TFilePath &path, bool withProgressDialog) { void ToonzScene::load(const TFilePath &path, bool withProgressDialog) {
loadNoResources(path); // This loads a version number .. loadNoResources(path);
loadResources(withProgressDialog); // .. this uses the version number .. loadResources(withProgressDialog);
}
setVersionNumber(
VersionNumber()); // .. but scene instances in memory do not retain
} // a version number beyond resource loading
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -456,7 +456,9 @@ void ToonzScene::loadTnzFile(const TFilePath &fp) {
while (is.matchTag(tagName)) { while (is.matchTag(tagName)) {
if (tagName == "generator") { if (tagName == "generator") {
std::string program = is.getString(); std::string program = is.getString();
reading22 = program.find("2.2") != std::string::npos; // TODO: This obsolete condition should be removed before releasing OT
// v2.2 !
reading22 = program.find("2.2") != std::string::npos;
} else if (tagName == "properties") } else if (tagName == "properties")
m_properties->loadData(is, false); m_properties->loadData(is, false);
else if (tagName == "palette") // per compatibilita' beta1 else if (tagName == "palette") // per compatibilita' beta1
@ -685,6 +687,8 @@ void ToonzScene::save(const TFilePath &fp, TXsheet *subxsh) {
} else { } else {
if (wasUntitled) deleteUntitledScene(oldScenePath.getParentDir()); if (wasUntitled) deleteUntitledScene(oldScenePath.getParentDir());
} }
// update the last saved version
setVersionNumber(l_currentVersion);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View file

@ -840,10 +840,15 @@ void TXshSimpleLevel::eraseFrame(const TFrameId &fid) {
getHookSet()->eraseFrame(fid); getHookSet()->eraseFrame(fid);
ImageManager *im = ImageManager::instance(); ImageManager *im = ImageManager::instance();
TImageCache *ic = TImageCache::instance();
{ {
im->unbind(getImageId(fid, Normal)); im->unbind(getImageId(fid, Normal));
im->unbind(getImageId(fid, Scanned)); im->unbind(getImageId(fid, Scanned));
im->unbind(getImageId(fid, CleanupPreview)); im->unbind(getImageId(fid, CleanupPreview));
// remove icon cache as well
ic->remove(getIconId(fid, Normal));
ic->remove(getIconId(fid, Scanned));
ic->remove(getIconId(fid, CleanupPreview));
if (m_type == PLI_XSHLEVEL) im->unbind(rasterized(getImageId(fid))); if (m_type == PLI_XSHLEVEL) im->unbind(rasterized(getImageId(fid)));
@ -858,13 +863,17 @@ void TXshSimpleLevel::eraseFrame(const TFrameId &fid) {
void TXshSimpleLevel::clearFrames() { void TXshSimpleLevel::clearFrames() {
ImageManager *im = ImageManager::instance(); ImageManager *im = ImageManager::instance();
TImageCache *ic = TImageCache::instance();
// Unbind frames // Unbind frames
FramesSet::iterator ft, fEnd = m_frames.end(); FramesSet::iterator ft, fEnd = m_frames.end();
for (ft = m_frames.begin(); ft != fEnd; ++ft) { for (ft = m_frames.begin(); ft != fEnd; ++ft) {
im->unbind(getImageId(*ft, Scanned)); im->unbind(getImageId(*ft, Scanned));
im->unbind(getImageId(*ft, Cleanupped)); im->unbind(getImageId(*ft, Cleanupped));
im->unbind(getImageId(*ft, CleanupPreview)); im->unbind(getImageId(*ft, CleanupPreview));
// remove icon cache as well
ic->remove(getIconId(*ft, Normal));
ic->remove(getIconId(*ft, Scanned));
ic->remove(getIconId(*ft, CleanupPreview));
if (m_type == PLI_XSHLEVEL) im->unbind(rasterized(getImageId(*ft))); if (m_type == PLI_XSHLEVEL) im->unbind(rasterized(getImageId(*ft)));

View file

@ -490,7 +490,7 @@ void FxSchematicScene::updateEditedGroups(
const QMap<int, QList<SchematicNode *>> &editedGroup) { const QMap<int, QList<SchematicNode *>> &editedGroup) {
QMap<int, QList<SchematicNode *>>::const_iterator it; QMap<int, QList<SchematicNode *>>::const_iterator it;
for (it = editedGroup.begin(); it != editedGroup.end(); it++) { for (it = editedGroup.begin(); it != editedGroup.end(); it++) {
int zValue = 2; int zValue = 2;
QMap<int, QList<SchematicNode *>>::const_iterator it2 = editedGroup.begin(); QMap<int, QList<SchematicNode *>>::const_iterator it2 = editedGroup.begin();
while (it2 != editedGroup.end()) { while (it2 != editedGroup.end()) {
FxSchematicNode *placedFxNode = FxSchematicNode *placedFxNode =
@ -626,7 +626,7 @@ void FxSchematicScene::updatePosition(FxSchematicNode *node,
//------------------------------------------------------------------ //------------------------------------------------------------------
/*! create node depends on the fx type /*! create node depends on the fx type
*/ */
FxSchematicNode *FxSchematicScene::createFxSchematicNode(TFx *fx) { FxSchematicNode *FxSchematicScene::createFxSchematicNode(TFx *fx) {
if (TLevelColumnFx *lcFx = dynamic_cast<TLevelColumnFx *>(fx)) if (TLevelColumnFx *lcFx = dynamic_cast<TLevelColumnFx *>(fx))
return new FxSchematicColumnNode(this, lcFx); return new FxSchematicColumnNode(this, lcFx);
@ -644,7 +644,7 @@ FxSchematicNode *FxSchematicScene::createFxSchematicNode(TFx *fx) {
//------------------------------------------------------------------ //------------------------------------------------------------------
/*! place nodes of which positions are not specified manually /*! place nodes of which positions are not specified manually
*/ */
void FxSchematicScene::placeNode(FxSchematicNode *node) { void FxSchematicScene::placeNode(FxSchematicNode *node) {
if (!node) return; if (!node) return;
int step = m_gridDimension == eLarge ? 100 : 50; int step = m_gridDimension == eLarge ? 100 : 50;
@ -872,7 +872,7 @@ void FxSchematicScene::updateLink() {
} }
TZeraryColumnFx *zfx = dynamic_cast<TZeraryColumnFx *>(fx); TZeraryColumnFx *zfx = dynamic_cast<TZeraryColumnFx *>(fx);
if (zfx) fx = zfx->getZeraryFx(); if (zfx) fx = zfx->getZeraryFx();
if (fx) { if (fx) {
int j; int j;
for (j = 0; j < fx->getInputPortCount(); j++) { for (j = 0; j < fx->getInputPortCount(); j++) {
@ -1026,7 +1026,7 @@ QPointF FxSchematicScene::nearestPoint(const QPointF &point) {
if (item) return rect.bottomRight(); if (item) return rect.bottomRight();
item = itemAt(rect.topLeft()); item = itemAt(rect.topLeft());
if (item) return rect.topLeft(); if (item) return rect.topLeft();
item = itemAt(rect.topRight()); item = itemAt(rect.topRight());
#endif #endif
if (item) return rect.topRight(); if (item) return rect.topRight();
return QPointF(); return QPointF();
@ -1471,8 +1471,8 @@ void FxSchematicScene::setEnableCache(bool toggle) {
for (int i = 0; i < selectedFxs.size(); i++) { for (int i = 0; i < selectedFxs.size(); i++) {
TFx *fx = selectedFxs[i].getPointer(); TFx *fx = selectedFxs[i].getPointer();
TZeraryColumnFx *zcfx = dynamic_cast<TZeraryColumnFx *>(fx); TZeraryColumnFx *zcfx = dynamic_cast<TZeraryColumnFx *>(fx);
if (zcfx) fx = zcfx->getZeraryFx(); if (zcfx) fx = zcfx->getZeraryFx();
TFxAttributes *attr = fx->getAttributes(); TFxAttributes *attr = fx->getAttributes();
if (!attr->isGrouped() || attr->isGroupEditing()) { if (!attr->isGrouped() || attr->isGroupEditing()) {
if (toggle) { if (toggle) {
TPassiveCacheManager::instance()->enableCache(fx); TPassiveCacheManager::instance()->enableCache(fx);
@ -1490,9 +1490,9 @@ void FxSchematicScene::setEnableCache(bool toggle) {
TPassiveCacheManager::instance()->enableCache(fx); TPassiveCacheManager::instance()->enableCache(fx);
} else { } else {
TPassiveCacheManager::instance()->disableCache(fx); TPassiveCacheManager::instance()->disableCache(fx);
} }
} }
} }
group->update(); group->update();
} }
} }
@ -1589,7 +1589,7 @@ void FxSchematicScene::mousePressEvent(QGraphicsSceneMouseEvent *me) {
#if QT_VERSION >= 0x050000 #if QT_VERSION >= 0x050000
QGraphicsItem *item = itemAt(me->scenePos(), QTransform()); QGraphicsItem *item = itemAt(me->scenePos(), QTransform());
#else #else
QGraphicsItem *item = itemAt(me->scenePos()); QGraphicsItem *item = itemAt(me->scenePos());
#endif #endif
FxSchematicPort *port = dynamic_cast<FxSchematicPort *>(item); FxSchematicPort *port = dynamic_cast<FxSchematicPort *>(item);
FxSchematicLink *link = dynamic_cast<FxSchematicLink *>(item); FxSchematicLink *link = dynamic_cast<FxSchematicLink *>(item);
@ -1646,7 +1646,7 @@ void FxSchematicScene::mouseMoveEvent(QGraphicsSceneMouseEvent *me) {
SchematicLink *link = SchematicLink *link =
dynamic_cast<SchematicLink *>(itemAt(m_lastPos, QTransform())); dynamic_cast<SchematicLink *>(itemAt(m_lastPos, QTransform()));
#else #else
SchematicLink *link = dynamic_cast<SchematicLink *>(itemAt(m_lastPos)); SchematicLink *link = dynamic_cast<SchematicLink *>(itemAt(m_lastPos));
#endif #endif
if (link && (link->getEndPort() && link->getStartPort())) { if (link && (link->getEndPort() && link->getStartPort())) {
TFxCommand::Link fxLink = m_selection->getBoundingFxs(link); TFxCommand::Link fxLink = m_selection->getBoundingFxs(link);
@ -1710,8 +1710,8 @@ void FxSchematicScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *me) {
if (port == outputNode->getInputPort(i)) break; if (port == outputNode->getInputPort(i)) break;
TFxCommand::Link fxLink; TFxCommand::Link fxLink;
fxLink.m_outputFx = outputNode->getFx(); fxLink.m_outputFx = outputNode->getFx();
fxLink.m_inputFx = inputNode->getFx(); fxLink.m_inputFx = inputNode->getFx();
if (!outputNode->isA(eXSheetFx)) fxLink.m_index = i; if (!outputNode->isA(eXSheetFx)) fxLink.m_index = i;
TFxCommand::connectFxs(fxLink, m_selection->getFxs().toStdList(), TFxCommand::connectFxs(fxLink, m_selection->getFxs().toStdList(),
@ -1880,7 +1880,7 @@ void FxSchematicScene::simulateDisconnectSelection(bool disconnect) {
if (selectedFxs.isEmpty()) return; if (selectedFxs.isEmpty()) return;
QMap<TFx *, bool> visitedFxs; QMap<TFx *, bool> visitedFxs;
int i; int i;
for (i = 0; i < selectedFxs.size(); i++) for (i = 0; i < selectedFxs.size(); i++)
visitedFxs[selectedFxs[i].getPointer()] = false; visitedFxs[selectedFxs[i].getPointer()] = false;
TFx *inputFx = 0, *outputFx = 0; TFx *inputFx = 0, *outputFx = 0;
@ -1935,61 +1935,62 @@ void FxSchematicScene::simulateDisconnectSelection(bool disconnect) {
void FxSchematicScene::simulateInsertSelection(SchematicLink *link, void FxSchematicScene::simulateInsertSelection(SchematicLink *link,
bool connect) { bool connect) {
if (!link || !connect) { // first, remove all connected links
m_connectionLinks.showBridgeLinks(); m_connectionLinks.showBridgeLinks();
m_connectionLinks.hideInputLinks(); m_connectionLinks.hideInputLinks();
m_connectionLinks.hideOutputLinks(); m_connectionLinks.hideOutputLinks();
m_connectionLinks.removeBridgeLinks(); m_connectionLinks.removeBridgeLinks();
m_connectionLinks.removeInputLinks(true); m_connectionLinks.removeInputLinks(true);
m_connectionLinks.removeOutputLinks(true); m_connectionLinks.removeOutputLinks(true);
} else { if (!link || !connect) return;
if (m_disconnectionLinks.isABridgeLink(link) || m_selection->isEmpty())
return;
m_connectionLinks.addBridgeLink(link); if (m_disconnectionLinks.isABridgeLink(link) || m_selection->isEmpty())
m_connectionLinks.hideBridgeLinks(); return;
SchematicPort *inputPort = 0, *outputPort = 0; m_connectionLinks.addBridgeLink(link);
if (link) { m_connectionLinks.hideBridgeLinks();
if (link->getStartPort()->getType() == eFxInputPort) {
inputPort = link->getStartPort(); SchematicPort *inputPort = 0, *outputPort = 0;
outputPort = link->getEndPort(); if (link) {
} else { if (link->getStartPort()->getType() == eFxInputPort) {
inputPort = link->getEndPort(); inputPort = link->getStartPort();
outputPort = link->getStartPort(); outputPort = link->getEndPort();
} } else {
inputPort = link->getEndPort();
outputPort = link->getStartPort();
} }
QMap<TFx *, bool> visitedFxs;
QList<TFxP> selectedFxs = m_selection->getFxs();
if (selectedFxs.isEmpty()) return;
int i;
for (i = 0; i < selectedFxs.size(); i++)
visitedFxs[selectedFxs[i].getPointer()] = false;
TFx *inputFx = 0, *outputFx = 0;
findBoundariesFxs(inputFx, outputFx, visitedFxs);
FxSchematicNode *inputNode = m_table[inputFx];
FxSchematicNode *outputNode = m_table[outputFx];
assert(inputNode && outputNode);
if (inputNode->getInputPortCount() > 0) {
SchematicPort *inputNodePort = inputNode->getInputPort(0);
if (inputNodePort && outputPort)
m_connectionLinks.addInputLink(inputNodePort->makeLink(outputPort));
}
SchematicPort *outputNodePort = outputNode->getOutputPort();
if (outputNodePort && inputPort)
m_connectionLinks.addOutputLink(inputPort->makeLink(outputNodePort));
m_connectionLinks.showInputLinks();
m_connectionLinks.showOutputLinks();
} }
QMap<TFx *, bool> visitedFxs;
QList<TFxP> selectedFxs = m_selection->getFxs();
if (selectedFxs.isEmpty()) return;
int i;
for (i = 0; i < selectedFxs.size(); i++)
visitedFxs[selectedFxs[i].getPointer()] = false;
TFx *inputFx = 0, *outputFx = 0;
findBoundariesFxs(inputFx, outputFx, visitedFxs);
FxSchematicNode *inputNode = m_table[inputFx];
FxSchematicNode *outputNode = m_table[outputFx];
assert(inputNode && outputNode);
if (inputNode->getInputPortCount() > 0) {
SchematicPort *inputNodePort = inputNode->getInputPort(0);
if (inputNodePort && outputPort)
m_connectionLinks.addInputLink(inputNodePort->makeLink(outputPort));
}
SchematicPort *outputNodePort = outputNode->getOutputPort();
if (outputNodePort && inputPort)
m_connectionLinks.addOutputLink(inputPort->makeLink(outputNodePort));
m_connectionLinks.showInputLinks();
m_connectionLinks.showOutputLinks();
} }
//------------------------------------------------------------ //------------------------------------------------------------
/*! in order to select nods after pasting the copied fx nodes from FxSelection /*! in order to select nods after pasting the copied fx nodes from FxSelection
*/ */
void FxSchematicScene::selectNodes(QList<TFxP> &fxs) { void FxSchematicScene::selectNodes(QList<TFxP> &fxs) {
clearSelection(); clearSelection();
for (int i = 0; i < (int)fxs.size(); i++) { for (int i = 0; i < (int)fxs.size(); i++) {
@ -2021,7 +2022,7 @@ void FxSchematicScene::updateNestedGroupEditors(FxSchematicNode *node,
#if QT_VERSION >= 0x050000 #if QT_VERSION >= 0x050000
rect = rect.united(app); rect = rect.united(app);
#else #else
rect = rect.unite(app); rect = rect.unite(app);
#endif #endif
} }
} }
@ -2035,7 +2036,7 @@ void FxSchematicScene::updateNestedGroupEditors(FxSchematicNode *node,
#if QT_VERSION >= 0x050000 #if QT_VERSION >= 0x050000
rect = rect.united(app); rect = rect.united(app);
#else #else
rect = rect.unite(app); rect = rect.unite(app);
#endif #endif
} }
} }
@ -2046,7 +2047,7 @@ void FxSchematicScene::updateNestedGroupEditors(FxSchematicNode *node,
rect = rect =
rect.united(m_groupEditorTable[groupIdStack[i]]->sceneBoundingRect()); rect.united(m_groupEditorTable[groupIdStack[i]]->sceneBoundingRect());
#else #else
rect = rect.unite(m_groupEditorTable[groupIdStack[i]]->sceneBoundingRect()); rect = rect.unite(m_groupEditorTable[groupIdStack[i]]->sceneBoundingRect());
#endif #endif
QRectF app = m_groupEditorTable[groupIdStack[i]]->boundingSceneRect(); QRectF app = m_groupEditorTable[groupIdStack[i]]->boundingSceneRect();
if (m_groupEditorTable[groupIdStack[i]]->scenePos() != app.topLeft()) if (m_groupEditorTable[groupIdStack[i]]->scenePos() != app.topLeft())
@ -2059,7 +2060,7 @@ void FxSchematicScene::updateNestedGroupEditors(FxSchematicNode *node,
#if QT_VERSION >= 0x050000 #if QT_VERSION >= 0x050000
rect = rect.united(app); rect = rect.united(app);
#else #else
rect = rect.unite(app); rect = rect.unite(app);
#endif #endif
app = editor->boundingSceneRect(); app = editor->boundingSceneRect();
if (editor->scenePos() != app.topLeft()) editor->setPos(app.topLeft()); if (editor->scenePos() != app.topLeft()) editor->setPos(app.topLeft());

View file

@ -222,26 +222,27 @@ QString getIconThemePath(const QString &fileSVGPath) {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
QPixmap setOpacity(QPixmap pixmap, const qreal &opacity) { QPixmap compositePixmap(QPixmap pixmap, const qreal &opacity, const QSize &size,
const int leftAdj, const int topAdj, QColor bgColor) {
static int devPixRatio = getDevPixRatio(); static int devPixRatio = getDevPixRatio();
const QSize pixmapSize(pixmap.width() * devPixRatio,
pixmap.height() * devPixRatio);
QPixmap opacityPixmap(pixmapSize); // Sets size of destination pixmap for source to be drawn onto, if size is
opacityPixmap.setDevicePixelRatio(devPixRatio); // empty use source pixmap size, else use custom size.
opacityPixmap.fill(Qt::transparent); QPixmap destination(size.isEmpty() ? pixmap.size() : size * devPixRatio);
destination.setDevicePixelRatio(devPixRatio);
destination.fill(bgColor);
if (!pixmap.isNull()) { if (!pixmap.isNull()) {
QPainter p(&opacityPixmap); QPainter p(&destination);
QPixmap normalPixmap = pixmap.scaled(pixmapSize, Qt::KeepAspectRatio); pixmap = pixmap.scaled(pixmap.size(), Qt::KeepAspectRatio);
normalPixmap.setDevicePixelRatio(devPixRatio); pixmap.setDevicePixelRatio(devPixRatio);
p.setBackgroundMode(Qt::TransparentMode); p.setBackgroundMode(Qt::TransparentMode);
p.setBackground(QBrush(Qt::transparent)); p.setBackground(QBrush(Qt::transparent));
p.eraseRect(normalPixmap.rect()); p.eraseRect(pixmap.rect());
p.setOpacity(opacity); p.setOpacity(opacity);
p.drawPixmap(0, 0, normalPixmap); p.drawPixmap(leftAdj, topAdj, pixmap);
} }
return opacityPixmap; return destination;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -266,138 +267,126 @@ QPixmap recolorPixmap(QPixmap pixmap, QColor color) {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
QPixmap compositePixmap(QPixmap pixmap, qreal opacity, int canvasWidth,
int canvasHeight, int iconWidth, int iconHeight,
int offset) {
/* Creates a composite pixmap from two pixmaps. The canvas controls the final
* size, whereas pixmap is the image to be composited ontop. You can control
* the position of pixmap by setting an offset (top-left), default is 0. */
static int devPixRatio = getDevPixRatio();
QPixmap canvas(canvasWidth, canvasHeight);
canvas.fill(Qt::transparent); // set this to a color to debug
QPixmap combined(canvasWidth, canvasHeight);
combined.fill(Qt::transparent);
if (!pixmap.isNull()) {
QPainter painter;
painter.begin(&combined);
QRect canvasRect(0, 0, canvasWidth, canvasHeight);
painter.drawPixmap(canvasRect, canvas);
painter.setOpacity(opacity);
QRect iconRect(offset, offset, iconWidth, iconHeight);
painter.drawPixmap(iconRect, pixmap);
painter.end();
}
return combined;
}
//-----------------------------------------------------------------------------
QIcon createQIcon(const char *iconSVGName, bool useFullOpacity) { QIcon createQIcon(const char *iconSVGName, bool useFullOpacity) {
static int devPixRatio = getDevPixRatio(); static int devPixRatio = getDevPixRatio();
// get icon size
QIcon themeIcon = QIcon::fromTheme(iconSVGName); QIcon themeIcon = QIcon::fromTheme(iconSVGName);
// Get icon dimensions
QSize iconSize(0, 0); QSize iconSize(0, 0);
for (QList<QSize> sizes = themeIcon.availableSizes(); !sizes.isEmpty(); for (QList<QSize> sizes = themeIcon.availableSizes(); !sizes.isEmpty();
sizes.removeFirst()) sizes.removeFirst())
if (sizes.first().width() > iconSize.width()) iconSize = sizes.first(); if (sizes.first().width() > iconSize.width())
iconSize = sizes.first() * devPixRatio;
// Control lightness of the icons
const qreal activeOpacity = 1;
const qreal baseOpacity = useFullOpacity ? 1 : 0.8;
const qreal disabledOpacity = 0.15;
// Psuedo state name strings
QString overStr = QString(iconSVGName) + "_over";
QString onStr = QString(iconSVGName) + "_on";
//----------
// Base pixmap
QPixmap themeIconPixmap(recolorPixmap(themeIcon.pixmap(iconSize)));
if (!themeIconPixmap.isNull()) { // suppress message
themeIconPixmap.setDevicePixelRatio(devPixRatio);
themeIconPixmap = themeIconPixmap.scaled(iconSize, Qt::KeepAspectRatio,
Qt::SmoothTransformation);
}
// Over pixmap
QPixmap overPixmap(recolorPixmap(QIcon::fromTheme(overStr).pixmap(iconSize)));
if (!overPixmap.isNull()) { // suppress message
overPixmap.setDevicePixelRatio(devPixRatio);
overPixmap = overPixmap.scaled(iconSize, Qt::KeepAspectRatio,
Qt::SmoothTransformation);
}
// On pixmap
QPixmap onPixmap(recolorPixmap(QIcon::fromTheme(onStr).pixmap(iconSize)));
if (!onPixmap.isNull()) { // suppress message
onPixmap.setDevicePixelRatio(devPixRatio);
onPixmap = onPixmap.scaled(iconSize, Qt::KeepAspectRatio,
Qt::SmoothTransformation);
}
//----------
QString overStr = QString(iconSVGName) + "_over";
QString onStr = QString(iconSVGName) + "_on";
QPixmap themeIconPixmap = recolorPixmap(themeIcon.pixmap(iconSize));
QPixmap overPixmap =
recolorPixmap(QIcon::fromTheme(overStr).pixmap(iconSize));
QPixmap onPixmap = recolorPixmap(QIcon::fromTheme(onStr).pixmap(iconSize));
QIcon icon; QIcon icon;
// build icon // Base icon
for (int devPixRatio = 1; devPixRatio <= 2; devPixRatio++) { icon.addPixmap(compositePixmap(themeIconPixmap, baseOpacity), QIcon::Normal,
int iconW = themeIconPixmap.width(); QIcon::Off);
int iconH = themeIconPixmap.height(); icon.addPixmap(compositePixmap(themeIconPixmap, disabledOpacity),
int canvasW = iconW; QIcon::Disabled, QIcon::Off);
int canvasH = iconH;
int offset = 0;
const qreal normalOpacity = useFullOpacity ? 1 : 0.8;
const qreal disabledOpacity = 0.15;
const qreal onOpacity = 1;
// off // Over icon
icon.addPixmap(compositePixmap(themeIconPixmap, normalOpacity, canvasW, icon.addPixmap(!overPixmap.isNull()
canvasH, iconW, iconH), ? compositePixmap(overPixmap, activeOpacity)
QIcon::Normal, QIcon::Off); : compositePixmap(themeIconPixmap, activeOpacity),
icon.addPixmap(compositePixmap(themeIconPixmap, disabledOpacity, canvasW, QIcon::Active);
canvasH, iconW, iconH),
QIcon::Disabled);
// over // On icon
if (!onPixmap.isNull()) {
icon.addPixmap(compositePixmap(onPixmap, activeOpacity), QIcon::Normal,
QIcon::On);
icon.addPixmap(compositePixmap(onPixmap, disabledOpacity), QIcon::Disabled,
QIcon::On);
} else {
icon.addPixmap(compositePixmap(themeIconPixmap, activeOpacity),
QIcon::Normal, QIcon::On);
icon.addPixmap(compositePixmap(themeIconPixmap, disabledOpacity),
QIcon::Disabled, QIcon::On);
}
//----------
// For icons intended for menus that are 16x16 in dimensions, to repurpose
// them for use in toolbars that are set for 20x20 we want to draw them onto a
// 20x20 pixmap so they don't get resized in the GUI, they will be loaded into
// the icon along with the original 16x16 pixmap.
if (themeIconPixmap.size() == QSize(16 * devPixRatio, 16 * devPixRatio)) {
const QSize drawOnSize(20, 20);
const int x = (drawOnSize.width() - 16) / 2; // left adjust
const int y = (drawOnSize.height() - 16) / 2; // top adjust
// Base icon
icon.addPixmap( icon.addPixmap(
compositePixmap(!overPixmap.isNull() ? overPixmap : themeIconPixmap, compositePixmap(themeIconPixmap, baseOpacity, drawOnSize, x, y),
onOpacity, canvasW, canvasH, iconW, iconH), QIcon::Normal, QIcon::Off);
icon.addPixmap(
compositePixmap(themeIconPixmap, disabledOpacity, drawOnSize, x, y),
QIcon::Disabled, QIcon::Off);
// Over icon
icon.addPixmap(
!overPixmap.isNull()
? compositePixmap(overPixmap, activeOpacity, drawOnSize, x, y)
: compositePixmap(themeIconPixmap, activeOpacity, drawOnSize, x, y),
QIcon::Active); QIcon::Active);
// on // On icon
if (!onPixmap.isNull()) { if (!onPixmap.isNull()) {
icon.addPixmap( icon.addPixmap(compositePixmap(onPixmap, activeOpacity, drawOnSize, x, y),
compositePixmap(onPixmap, onOpacity, canvasW, canvasH, iconW, iconH),
QIcon::Normal, QIcon::On);
icon.addPixmap(compositePixmap(onPixmap, normalOpacity, canvasW, canvasH,
iconW, iconH),
QIcon::Disabled, QIcon::On);
} else {
icon.addPixmap(compositePixmap(themeIconPixmap, onOpacity, canvasW,
canvasH, iconW, iconH),
QIcon::Normal, QIcon::On); QIcon::Normal, QIcon::On);
icon.addPixmap(compositePixmap(themeIconPixmap, disabledOpacity, canvasW,
canvasH, iconW, iconH),
QIcon::Disabled, QIcon::On);
}
/* If size is 16x16 (suitable for menu) we composite it onto a separate
* 20x20 pixmap so that it is compatible with toolbars, otherwise it will be
* scaled up and blur. You need to add icons to all QIcon modes otherwise it
* will use the original size, which is undesirable. This is equal to having
* two sets loaded into the icon (16x16 and 20x20) and is dynamically used
* depending on iconSize for toolbars.
*/
if (iconSize == (QSize(16, 16))) {
canvasW = 20 * devPixRatio;
canvasH = 20 * devPixRatio;
offset = 2 * devPixRatio;
// off
icon.addPixmap(compositePixmap(themeIconPixmap, normalOpacity, canvasW,
canvasH, iconW, iconH, offset),
QIcon::Normal, QIcon::Off);
icon.addPixmap(compositePixmap(themeIconPixmap, disabledOpacity, canvasW,
canvasH, iconW, iconH, offset),
QIcon::Disabled);
// over
icon.addPixmap( icon.addPixmap(
compositePixmap(!overPixmap.isNull() ? overPixmap : themeIconPixmap, compositePixmap(onPixmap, disabledOpacity, drawOnSize, x, y),
onOpacity, canvasW, canvasH, iconW, iconH, offset), QIcon::Disabled, QIcon::On);
QIcon::Active); } else {
icon.addPixmap(
// on compositePixmap(themeIconPixmap, activeOpacity, drawOnSize, x, y),
if (!onPixmap.isNull()) { QIcon::Normal, QIcon::On);
icon.addPixmap(compositePixmap(onPixmap, onOpacity, canvasW, canvasH, icon.addPixmap(
iconW, iconH, offset), compositePixmap(themeIconPixmap, disabledOpacity, drawOnSize, x, y),
QIcon::Normal, QIcon::On); QIcon::Disabled, QIcon::On);
icon.addPixmap(compositePixmap(onPixmap, disabledOpacity, canvasW,
canvasH, iconW, iconH, offset),
QIcon::Disabled, QIcon::On);
} else {
icon.addPixmap(compositePixmap(themeIconPixmap, onOpacity, canvasW,
canvasH, iconW, iconH, offset),
QIcon::Normal, QIcon::On);
icon.addPixmap(compositePixmap(themeIconPixmap, disabledOpacity,
canvasW, canvasH, iconW, iconH, offset),
QIcon::Disabled, QIcon::On);
}
} }
} }
return icon; return icon;
} }
@ -439,9 +428,9 @@ QIcon createQIconOnOffPNG(const char *iconPNGName, bool withOver) {
QIcon createTemporaryIconFromName(const char *commandName) { QIcon createTemporaryIconFromName(const char *commandName) {
const int visibleIconSize = 20; const int visibleIconSize = 20;
const int menubarIconSize = 16; const int menubarIconSize = 16;
const qreal normalOpacity = 0.8; const qreal activeOpacity = 1;
const qreal baseOpacity = 0.8;
const qreal disabledOpacity = 0.15; const qreal disabledOpacity = 0.15;
const qreal onOpacity = 1;
QString name(commandName); QString name(commandName);
QList<QChar> iconChar; QList<QChar> iconChar;
@ -495,22 +484,23 @@ QIcon createTemporaryIconFromName(const char *commandName) {
painter.end(); painter.end();
// For menu only
icon.addPixmap(transparentPm, QIcon::Normal, QIcon::Off); icon.addPixmap(transparentPm, QIcon::Normal, QIcon::Off);
icon.addPixmap(transparentPm, QIcon::Active); icon.addPixmap(transparentPm, QIcon::Active);
icon.addPixmap(transparentPm, QIcon::Normal, QIcon::On); icon.addPixmap(transparentPm, QIcon::Normal, QIcon::On);
icon.addPixmap(transparentPm, QIcon::Disabled); icon.addPixmap(transparentPm, QIcon::Disabled, QIcon::Off);
icon.addPixmap(compositePixmap(pixmap, normalOpacity, pxSize, pxSize, icon.addPixmap(transparentPm, QIcon::Disabled, QIcon::On);
pixmap.width(), pixmap.height()),
QIcon::Normal, QIcon::Off); // For toolbars
icon.addPixmap(compositePixmap(pixmap, onOpacity, pxSize, pxSize, icon.addPixmap(compositePixmap(pixmap, baseOpacity), QIcon::Normal,
pixmap.width(), pixmap.height()), QIcon::Off);
QIcon::Normal, QIcon::On); icon.addPixmap(compositePixmap(pixmap, disabledOpacity), QIcon::Disabled,
icon.addPixmap(compositePixmap(pixmap, onOpacity, pxSize, pxSize, QIcon::Off);
pixmap.width(), pixmap.height()), icon.addPixmap(compositePixmap(pixmap, activeOpacity), QIcon::Active);
QIcon::Active); icon.addPixmap(compositePixmap(pixmap, activeOpacity), QIcon::Normal,
icon.addPixmap(compositePixmap(pixmap, disabledOpacity, pxSize, pxSize, QIcon::On);
pixmap.width(), pixmap.height()), icon.addPixmap(compositePixmap(pixmap, disabledOpacity), QIcon::Disabled,
QIcon::Disabled); QIcon::On);
} }
return icon; return icon;
} }

View file

@ -928,9 +928,8 @@ bool FullScreenWidget::toggleFullScreen(
// Define some constants for setting and clearing window flags. // Define some constants for setting and clearing window flags.
const Qt::WindowFlags kwfFullScreenWidgetFlags = const Qt::WindowFlags kwfFullScreenWidgetFlags =
Qt::Window | // <-- Make the widget become a window. Qt::Window | // <-- Make the widget become a window.
Qt::WindowStaysOnTopHint | // <-- Ensure the window stays on top. Qt::FramelessWindowHint; // <-- Full screen windows have no border.
Qt::FramelessWindowHint; // <-- Full screen windows have no border.
const Qt::WindowFlags kwfFullScreenWidgetExcludedFlagsMask = const Qt::WindowFlags kwfFullScreenWidgetExcludedFlagsMask =
(Qt::WindowFlags)~Qt::WindowTitleHint; // <-- Full screen windows have no (Qt::WindowFlags)~Qt::WindowTitleHint; // <-- Full screen windows have no
@ -1032,8 +1031,7 @@ bool FullScreenWidget::toggleFullScreen(
// effect. // effect.
this->show(); this->show();
#else #else
this->setWindowFlags(this->windowFlags() | Qt::Window | this->setWindowFlags(this->windowFlags() | Qt::Window);
Qt::WindowStaysOnTopHint);
this->window()->windowHandle()->setScreen(ptrScreenThisWindowIsOn); this->window()->windowHandle()->setScreen(ptrScreenThisWindowIsOn);
// http://doc.qt.io/qt-5/windows-issues.html#fullscreen-opengl-based-windows // http://doc.qt.io/qt-5/windows-issues.html#fullscreen-opengl-based-windows

View file

@ -989,6 +989,8 @@ void HexagonalColorWheel::onContextAboutToBeDestroyed() {
makeCurrent(); makeCurrent();
m_lutCalibrator->cleanup(); m_lutCalibrator->cleanup();
doneCurrent(); doneCurrent();
disconnect(context(), SIGNAL(aboutToBeDestroyed()), this,
SLOT(onContextAboutToBeDestroyed()));
} }
//***************************************************************************** //*****************************************************************************

View file

@ -185,6 +185,10 @@ void TreeModel::endRefresh() {
int i; int i;
QList<Item *>::iterator it; QList<Item *>::iterator it;
// comment out as no subclass of TreeModel reimplement removeRows() for now
// and it causes assertion failure on calling beginRemoveRows() when deleting
// the last column in the xsheet
/*
for (i = m_itemsToDelete.size() - 1; i >= 0; i--) { for (i = m_itemsToDelete.size() - 1; i >= 0; i--) {
int row = m_itemsToDelete[i]->getRow(); int row = m_itemsToDelete[i]->getRow();
Item *parentItem = m_itemsToDelete[i]->getParent(); Item *parentItem = m_itemsToDelete[i]->getParent();
@ -192,10 +196,11 @@ void TreeModel::endRefresh() {
parentItem ? parentItem->createIndex() : QModelIndex(); parentItem ? parentItem->createIndex() : QModelIndex();
beginRemoveRows(parentIndex, row, row); beginRemoveRows(parentIndex, row, row);
removeRow(row, parentIndex); // NOTE: This is currently doing NOTHING? (see removeRows(row, 1, parentIndex); // NOTE: This is currently doing NOTHING?
(see
// Qt's manual) // Qt's manual)
endRemoveRows(); endRemoveRows();
} }*/
qDeleteAll(m_itemsToDelete); qDeleteAll(m_itemsToDelete);
m_itemsToDelete.clear(); m_itemsToDelete.clear();