diff --git a/doc/how_to_build_linux.md b/doc/how_to_build_linux.md index 6bfa621..6212a2c 100644 --- a/doc/how_to_build_linux.md +++ b/doc/how_to_build_linux.md @@ -1,42 +1,43 @@ -# Setting up the development environment for GNU/Linux and Unix +# Setting up the development environment for GNU/Linux ## Required software -You will need to install some dependencies before you can build. Depending on your distribution you will be able to install the packages directly with the command lines below or will have to manually install: +Building OpenToonz from source requires the following dependencies: - Git -- GCC -- CMake - - confirmed to work with 3.4.1. -- Qt5 - - http://download.qt.io/official_releases/qt/5.5/5.5.1/ -- Boost - - http://www.boost.org/users/history/version_1_55_0.html +- GCC or Clang +- CMake (3.4.1 or newer). +- Qt5 (5.5 or newer) +- Boost (1.55 or newer) - SDL2 +- LibPNG +- SuperLU +- Lzo2 +- FreeType -### Installing required packages on Debian / Ubuntu +### Installing Dependencies on Debian / Ubuntu ``` -$ sudo apt-get install build-essential git cmake pkg-config libboost-all-dev qt5-default qtbase5-dev libqt5svg5-dev qtscript5-dev qttools5-dev-tools libqt5opengl5-dev qtmultimedia5-dev libsuperlu-dev liblz4-dev libusb-1.0-0-dev liblzo2-dev libpng-dev libjpeg-dev libglew-dev freeglut3-dev libsdl2-dev libfreetype6-dev +$ sudo apt-get install build-essential git cmake pkg-config libboost-all-dev qt5-default qtbase5-dev libqt5svg5-dev qtscript5-dev qttools5-dev qttools5-dev-tools libqt5opengl5-dev qtmultimedia5-dev libsuperlu-dev liblz4-dev libusb-1.0-0-dev liblzo2-dev libpng-dev libjpeg-dev libglew-dev freeglut3-dev libsdl2-dev libfreetype6-dev ``` Notes: -* It's possible we also need libgsl2 (or maybe libopenbias-dev) +* It's possible we also need `libgsl2` (or maybe `libopenblas-dev`) -### Installing required packages on RedHat / Mageia +### Installing Dependencies on RedHat / CentOS TODO ``` $ rpm ... ``` -### Installing required packages on Fedora +### Installing Dependencies on Fedora (it may include some useless packages) ``` -dnf install gcc gcc-c++ automake git cmake boost boost-devel SuperLU SuperLU-devel lz4-devel libusb-devel lzo-devel libjpeg-turbo-devel GLEW libGLEW freeglut-devel freeglut SDL2 SDL2-devel freetype-devel libpng-devel qt5-base qt5-qtbase-devel qt5-qtsvg qt5-qtsvg-devel qt5-qtscript qt5-qtscript-devel qt5-qttools qt5-qttools-devel blas blas-devel +$ dnf install gcc gcc-c++ automake git cmake boost boost-devel SuperLU SuperLU-devel lz4-devel lzma libusb-devel lzo-devel libjpeg-turbo-devel libGLEW glew-devel freeglut-devel freeglut SDL2 SDL2-devel freetype-devel libpng-devel qt5-qtbase-devel qt5-qtsvg qt5-qtsvg-devel qt5-qtscript qt5-qtscript-devel qt5-qttools qt5-qttools-devel qt5-qtmultimedia-devel blas blas-devel ``` -### Installing required packages on ArchLinux +### Installing Dependencies on ArchLinux ``` $ sudo pacman -S base-devel git cmake boost boost-libs qt5-base qt5-svg qt5-script qt5-tools qt5-multimedia lz4 libusb lzo libjpeg-turbo glew freeglut sdl2 freetype2 @@ -48,38 +49,40 @@ $ yaourt -S superlu ``` Notes: -* ArchLinux had BLAS splitted in blas and cblas +* ArchLinux has `blas` split into `blas` and `cblas`. -### Installing required packages on openSUSE +### Installing Dependencies on openSUSE ``` -zypper in boost-devel cmake freeglut-devel freetype2-devel gcc-c++ glew-devel libQt5OpenGL-devel libSDL2-devel libjpeg-devel liblz4-devel libpng16-compat-devel libqt5-linguist-devel libqt5-qtbase-devel libqt5-qtmultimedia-devel libqt5-qtscript-devel libqt5-qtsvg-devel libtiff-devel libusb-devel lzo-devel openblas-devel pkgconfig sed superlu-devel zlib-devel +$ zypper in boost-devel cmake freeglut-devel freetype2-devel gcc-c++ glew-devel libQt5OpenGL-devel libSDL2-devel libjpeg-devel liblz4-devel libpng16-compat-devel libqt5-linguist-devel libqt5-qtbase-devel libqt5-qtmultimedia-devel libqt5-qtscript-devel libqt5-qtsvg-devel libtiff-devel libusb-devel lzo-devel openblas-devel pkgconfig sed superlu-devel zlib-devel ``` ## Build instructions -### cloning the git tree +### Cloning the GIT Tree ``` $ git clone https://github.com/opentoonz/opentoonz ``` -### Copying the stuff directory +### Copying the 'stuff' Directory TODO: some parts should really be installed in $prefix/ instead... and some other in various cache or user-local places. cf. https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html Until then we just follow the Win32/OSX layout. -It is supposedly optional but some files are actually required to run the executable properly. +The `~/.config/OpenToonz/` directory contains your settings, work and other files. -The .config/OpenToonz/ directory in your home folder will contain your settings, work and other files. We need to create it from the command-line: +Initialize this path with the folling commands: ``` $ mkdir -p $HOME/.config/OpenToonz $ cp -r opentoonz/stuff $HOME/.config/OpenToonz/ ``` -### Creating a default ini file for stuff folders +*Currently this is required to run OpenToonz.* + +### Creating SystemVar.ini TODO: fix the code to discover it automatically @@ -98,20 +101,21 @@ TOONZROOT="$HOME/.config/OpenToonz/stuff" TOONZSTUDIOPALETTE="$HOME/.config/OpenToonz/stuff/projects/studiopalette" EOF ``` -Note the generated file must not actually contain "$HOME", this shell command repaces it with /home/youraccount in the generated file. +Note the generated file must not actually contain `$HOME`, this expands to an absolute path in the generated file. -### Building the tiff library from thirdparty +### Building LibTIFF TODO: make sure we can use the system libtiff instead and remove this section. Features from the modified libtiff and needed currently, so this isn't a simple switch. ``` $ cd opentoonz/thirdparty/tiff-4.0.3 -$ CFLAGS="-fPIC" ./configure && make +$ ./configure --with-pic --disable-jbig +$ make $ cd - ``` -### Compiling the actual application +### Building OpenToonz ``` $ cd ../../toonz @@ -123,18 +127,18 @@ $ make The build takes a lot of time, be patient. -### Debugging the build +### Troubleshooting Build Errors If something doesn't compile or link, please run `make` this way to help spot the problem: ``` -LANG=C make VERBOSE=1 +$ LANG=C make VERBOSE=1 ``` -#### Debug build +#### Debug Build If you need to debug the application, you should be able to use `cmake -DCMAKE_BUILD_TYPE=Debug`. -### Running the application +### Running OpenToonz You can now run the application: @@ -143,7 +147,7 @@ $ cd bin $ LD_LIBRARY_PATH=./lib/opentoonz:$LD_LIBRARY_PATH ./bin/OpenToonz_1.0 ``` -### Performing a system installation +### Performing a System Installation The steps above show how to run OpenToonz from the build directory, however you may wish to install OpenToonz onto your system. @@ -158,3 +162,15 @@ Then you can launch OpenToonz by running `/opt/opentoonz/bin/opentoonz`. You can change the installation path by modifying the `CMAKE_INSTALL_PREFIX` CMake variable. +---- + +# Linux Package Definitions + +It may be helpful to use existing packages as a reference when creating a package for your own distribution. + +- ArchLinux (AUR): + https://aur.archlinux.org/packages/opentoonz-git/ + +- App-Image (Portable): + https://github.com/morevnaproject/morevna-builds + diff --git a/stuff/config/qss/gray_048/gray_048.less b/stuff/config/qss/gray_048/gray_048.less index 0590e85..84eee18 100644 --- a/stuff/config/qss/gray_048/gray_048.less +++ b/stuff/config/qss/gray_048/gray_048.less @@ -1,4 +1,4 @@ - +// out: gray_048.qss /* LESS Definitions */ /*Image URL*/ @@ -748,7 +748,7 @@ DvDirTreeView { /*---------------------------------------------------------------------------*/ #CleanupSettingsFrame, #LoadLevelFrame, -#SolidLineFrame{ +#SolidLineFrame { border: 1px solid @m_baseTxtColor; } @@ -821,30 +821,29 @@ ParamsPage { } } /* Customize QScrollBar vertical*/ -#XsheetScrollBar { - .baseBG(light, 10%); +QScrollBar { border: 1px solid black; &:vertical { - width: 18px; - .set_margin( 0px, 20px ); + width: 16px; + .set_margin( 0px, 16px ); } &:horizontal { - height: 18px; - .set_margin( 20px, 0px ); + height: 16px; + .set_margin( 16px, 0px ); } &::handle { - border-width: 4; + border-width: 3; image-position: center center; &:vertical { - border-image: url("@{image_url}/sb_g_vhandle.png")4; + border-image: url("@{image_url}/sb_g_vhandle.png")3; image: url("@{image_url}/sb_g_vline.png"); min-height: 40px; } &:horizontal { - border-image: url("@{image_url}/sb_g_hhandle.png")4; + border-image: url("@{image_url}/sb_g_hhandle.png")3; image: url("@{image_url}/sb_g_hline.png"); min-width: 40px; } @@ -854,7 +853,7 @@ ParamsPage { subcontrol-origin: margin; &:vertical { image: url("@{image_url}/sb_g_downarrow.png"); - height: 20px; + height: 16px; subcontrol-position: bottom; &:pressed { image: url("@{image_url}/sb_g_downarrow_pressed.png"); @@ -862,7 +861,7 @@ ParamsPage { } &:horizontal { image: url("@{image_url}/sb_g_rarrow.png"); - width: 20px; + width: 16px; subcontrol-position: right; &:pressed{ image: url("@{image_url}/sb_g_rarrow_pressed.png"); @@ -874,7 +873,7 @@ ParamsPage { subcontrol-origin: margin; &:vertical { image: url("@{image_url}/sb_g_uparrow.png"); - height: 20px; + height: 16px; subcontrol-position: top; &:pressed { image: url("@{image_url}/sb_g_uparrow_pressed.png"); @@ -882,7 +881,7 @@ ParamsPage { } &:horizontal { image: url("@{image_url}/sb_g_larrow.png"); - width: 20px; + width: 16px; subcontrol-position: left; &:pressed{ image: url("@{image_url}/sb_g_larrow_pressed.png"); @@ -890,8 +889,8 @@ ParamsPage { } } - &::add-page { - background: none; + &::add-page, &::sub-page { + .baseBG(light, 10%); } } @@ -1365,4 +1364,15 @@ QDialog #dialogButtonFrame { #LargeSizedText { font-size: 17px; +} + +#GearButton { + qproperty-icon: url("@{image_url}/gear.png"); +} + +#StartupLabel { + padding: 3px; + &:hover { + .baseBG(light, 10%); + } } \ No newline at end of file diff --git a/stuff/config/qss/gray_048/gray_048.qss b/stuff/config/qss/gray_048/gray_048.qss index 6936166..b1a2239 100644 --- a/stuff/config/qss/gray_048/gray_048.qss +++ b/stuff/config/qss/gray_048/gray_048.qss @@ -841,79 +841,79 @@ ParamsPage { background-color: #000080; } /* Customize QScrollBar vertical*/ -#XsheetScrollBar { - background-color: #4a4a4a; +QScrollBar { border: 1px solid black; /* buttons */ } -#XsheetScrollBar:vertical { - width: 18px; +QScrollBar:vertical { + width: 16px; margin-left: 0px; margin-right: 0px; - margin-top: 20px; - margin-bottom: 20px; + margin-top: 16px; + margin-bottom: 16px; } -#XsheetScrollBar:horizontal { - height: 18px; - margin-left: 20px; - margin-right: 20px; +QScrollBar:horizontal { + height: 16px; + margin-left: 16px; + margin-right: 16px; margin-top: 0px; margin-bottom: 0px; } -#XsheetScrollBar::handle { - border-width: 4; +QScrollBar::handle { + border-width: 3; image-position: center center; } -#XsheetScrollBar::handle:vertical { - border-image: url("../gray_072/imgs/sb_g_vhandle.png") 4; +QScrollBar::handle:vertical { + border-image: url("../gray_072/imgs/sb_g_vhandle.png") 3; image: url("../gray_072/imgs/sb_g_vline.png"); min-height: 40px; } -#XsheetScrollBar::handle:horizontal { - border-image: url("../gray_072/imgs/sb_g_hhandle.png") 4; +QScrollBar::handle:horizontal { + border-image: url("../gray_072/imgs/sb_g_hhandle.png") 3; image: url("../gray_072/imgs/sb_g_hline.png"); min-width: 40px; } -#XsheetScrollBar::add-line { +QScrollBar::add-line { subcontrol-origin: margin; } -#XsheetScrollBar::add-line:vertical { +QScrollBar::add-line:vertical { image: url("../gray_072/imgs/sb_g_downarrow.png"); - height: 20px; + height: 16px; subcontrol-position: bottom; } -#XsheetScrollBar::add-line:vertical:pressed { +QScrollBar::add-line:vertical:pressed { image: url("../gray_072/imgs/sb_g_downarrow_pressed.png"); } -#XsheetScrollBar::add-line:horizontal { +QScrollBar::add-line:horizontal { image: url("../gray_072/imgs/sb_g_rarrow.png"); - width: 20px; + width: 16px; subcontrol-position: right; } -#XsheetScrollBar::add-line:horizontal:pressed { +QScrollBar::add-line:horizontal:pressed { image: url("../gray_072/imgs/sb_g_rarrow_pressed.png"); } -#XsheetScrollBar::sub-line { +QScrollBar::sub-line { subcontrol-origin: margin; } -#XsheetScrollBar::sub-line:vertical { +QScrollBar::sub-line:vertical { image: url("../gray_072/imgs/sb_g_uparrow.png"); - height: 20px; + height: 16px; subcontrol-position: top; } -#XsheetScrollBar::sub-line:vertical:pressed { +QScrollBar::sub-line:vertical:pressed { image: url("../gray_072/imgs/sb_g_uparrow_pressed.png"); } -#XsheetScrollBar::sub-line:horizontal { +QScrollBar::sub-line:horizontal { image: url("../gray_072/imgs/sb_g_larrow.png"); - width: 20px; + width: 16px; subcontrol-position: left; } -#XsheetScrollBar::sub-line:horizontal:pressed { +QScrollBar::sub-line:horizontal:pressed { image: url("../gray_072/imgs/sb_g_larrow_pressed.png"); } -#XsheetScrollBar::add-page { - background: none; +QScrollBar::add-page, +QScrollBar::sub-page { + background-color: #4a4a4a; } #noteTextEdit { color: black; @@ -1369,5 +1369,14 @@ QDialog #dialogButtonFrame { #LargeSizedText { font-size: 17px; } +#GearButton { + qproperty-icon: url("../gray_072/imgs/gear.png"); +} +#StartupLabel { + padding: 3px; +} +#StartupLabel:hover { + background-color: #4a4a4a; +} //# sourceMappingURL=gray_048.qss.map \ No newline at end of file diff --git a/stuff/config/qss/gray_048/gray_048_mac.qss b/stuff/config/qss/gray_048/gray_048_mac.qss index 7c6a503..23babcd 100644 --- a/stuff/config/qss/gray_048/gray_048_mac.qss +++ b/stuff/config/qss/gray_048/gray_048_mac.qss @@ -841,79 +841,79 @@ ParamsPage { background-color: #000080; } /* Customize QScrollBar vertical*/ -#XsheetScrollBar { - background-color: #4a4a4a; +QScrollBar { border: 1px solid black; /* buttons */ } -#XsheetScrollBar:vertical { - width: 18px; +QScrollBar:vertical { + width: 16px; margin-left: 0px; margin-right: 0px; - margin-top: 20px; - margin-bottom: 20px; + margin-top: 16px; + margin-bottom: 16px; } -#XsheetScrollBar:horizontal { - height: 18px; - margin-left: 20px; - margin-right: 20px; +QScrollBar:horizontal { + height: 16px; + margin-left: 16px; + margin-right: 16px; margin-top: 0px; margin-bottom: 0px; } -#XsheetScrollBar::handle { - border-width: 4; +QScrollBar::handle { + border-width: 3; image-position: center center; } -#XsheetScrollBar::handle:vertical { - border-image: url("../gray_072/imgs/sb_g_vhandle.png") 4; +QScrollBar::handle:vertical { + border-image: url("../gray_072/imgs/sb_g_vhandle.png") 3; image: url("../gray_072/imgs/sb_g_vline.png"); min-height: 40px; } -#XsheetScrollBar::handle:horizontal { - border-image: url("../gray_072/imgs/sb_g_hhandle.png") 4; +QScrollBar::handle:horizontal { + border-image: url("../gray_072/imgs/sb_g_hhandle.png") 3; image: url("../gray_072/imgs/sb_g_hline.png"); min-width: 40px; } -#XsheetScrollBar::add-line { +QScrollBar::add-line { subcontrol-origin: margin; } -#XsheetScrollBar::add-line:vertical { +QScrollBar::add-line:vertical { image: url("../gray_072/imgs/sb_g_downarrow.png"); - height: 20px; + height: 16px; subcontrol-position: bottom; } -#XsheetScrollBar::add-line:vertical:pressed { +QScrollBar::add-line:vertical:pressed { image: url("../gray_072/imgs/sb_g_downarrow_pressed.png"); } -#XsheetScrollBar::add-line:horizontal { +QScrollBar::add-line:horizontal { image: url("../gray_072/imgs/sb_g_rarrow.png"); - width: 20px; + width: 16px; subcontrol-position: right; } -#XsheetScrollBar::add-line:horizontal:pressed { +QScrollBar::add-line:horizontal:pressed { image: url("../gray_072/imgs/sb_g_rarrow_pressed.png"); } -#XsheetScrollBar::sub-line { +QScrollBar::sub-line { subcontrol-origin: margin; } -#XsheetScrollBar::sub-line:vertical { +QScrollBar::sub-line:vertical { image: url("../gray_072/imgs/sb_g_uparrow.png"); - height: 20px; + height: 16px; subcontrol-position: top; } -#XsheetScrollBar::sub-line:vertical:pressed { +QScrollBar::sub-line:vertical:pressed { image: url("../gray_072/imgs/sb_g_uparrow_pressed.png"); } -#XsheetScrollBar::sub-line:horizontal { +QScrollBar::sub-line:horizontal { image: url("../gray_072/imgs/sb_g_larrow.png"); - width: 20px; + width: 16px; subcontrol-position: left; } -#XsheetScrollBar::sub-line:horizontal:pressed { +QScrollBar::sub-line:horizontal:pressed { image: url("../gray_072/imgs/sb_g_larrow_pressed.png"); } -#XsheetScrollBar::add-page { - background: none; +QScrollBar::add-page, +QScrollBar::sub-page { + background-color: #4a4a4a; } #noteTextEdit { color: black; @@ -1369,5 +1369,14 @@ QDialog #dialogButtonFrame { #LargeSizedText { font-size: 17px; } +#GearButton { + qproperty-icon: url("../gray_072/imgs/gear.png"); +} +#StartupLabel { + padding: 3px; +} +#StartupLabel:hover { + background-color: #4a4a4a; +} //# sourceMappingURL=gray_048_mac.qss.map \ No newline at end of file diff --git a/stuff/config/qss/gray_072/gray_072.less b/stuff/config/qss/gray_072/gray_072.less index c918bcf..7cb9432 100644 --- a/stuff/config/qss/gray_072/gray_072.less +++ b/stuff/config/qss/gray_072/gray_072.less @@ -747,7 +747,7 @@ DvDirTreeView { /*---------------------------------------------------------------------------*/ #CleanupSettingsFrame, #LoadLevelFrame, -#SolidLineFrame{ +#SolidLineFrame { border: 1px solid @m_baseTxtColor; } @@ -821,30 +821,29 @@ ParamsPage { } } /* Customize QScrollBar vertical*/ -#XsheetScrollBar { - .baseBG(light, 10%); +QScrollBar { border: 1px solid black; &:vertical { - width: 18px; - .set_margin( 0px, 20px ); + width: 16px; + .set_margin( 0px, 16px ); } &:horizontal { - height: 18px; - .set_margin( 20px, 0px ); + height: 16px; + .set_margin( 16px, 0px ); } &::handle { - border-width: 4; + border-width: 3; image-position: center center; &:vertical { - border-image: url("@{image_url}/sb_g_vhandle.png")4; + border-image: url("@{image_url}/sb_g_vhandle.png")3; image: url("@{image_url}/sb_g_vline.png"); min-height: 40px; } &:horizontal { - border-image: url("@{image_url}/sb_g_hhandle.png")4; + border-image: url("@{image_url}/sb_g_hhandle.png")3; image: url("@{image_url}/sb_g_hline.png"); min-width: 40px; } @@ -854,7 +853,7 @@ ParamsPage { subcontrol-origin: margin; &:vertical { image: url("@{image_url}/sb_g_downarrow.png"); - height: 20px; + height: 16px; subcontrol-position: bottom; &:pressed { image: url("@{image_url}/sb_g_downarrow_pressed.png"); @@ -862,7 +861,7 @@ ParamsPage { } &:horizontal { image: url("@{image_url}/sb_g_rarrow.png"); - width: 20px; + width: 16px; subcontrol-position: right; &:pressed{ image: url("@{image_url}/sb_g_rarrow_pressed.png"); @@ -874,7 +873,7 @@ ParamsPage { subcontrol-origin: margin; &:vertical { image: url("@{image_url}/sb_g_uparrow.png"); - height: 20px; + height: 16px; subcontrol-position: top; &:pressed { image: url("@{image_url}/sb_g_uparrow_pressed.png"); @@ -882,7 +881,7 @@ ParamsPage { } &:horizontal { image: url("@{image_url}/sb_g_larrow.png"); - width: 20px; + width: 16px; subcontrol-position: left; &:pressed{ image: url("@{image_url}/sb_g_larrow_pressed.png"); @@ -890,8 +889,8 @@ ParamsPage { } } - &::add-page { - background: none; + &::add-page, &::sub-page { + .baseBG(light, 10%); } } @@ -1365,4 +1364,15 @@ QDialog #dialogButtonFrame { #LargeSizedText { font-size: 17px; +} + +#GearButton { + qproperty-icon: url("@{image_url}/gear.png"); +} + +#StartupLabel { + padding: 3px; + &:hover { + .baseBG(light, 10%); + } } \ No newline at end of file diff --git a/stuff/config/qss/gray_072/gray_072.qss b/stuff/config/qss/gray_072/gray_072.qss index 69c5a4d..84bb341 100644 --- a/stuff/config/qss/gray_072/gray_072.qss +++ b/stuff/config/qss/gray_072/gray_072.qss @@ -841,79 +841,79 @@ ParamsPage { background-color: #000080; } /* Customize QScrollBar vertical*/ -#XsheetScrollBar { - background-color: #626262; +QScrollBar { border: 1px solid black; /* buttons */ } -#XsheetScrollBar:vertical { - width: 18px; +QScrollBar:vertical { + width: 16px; margin-left: 0px; margin-right: 0px; - margin-top: 20px; - margin-bottom: 20px; + margin-top: 16px; + margin-bottom: 16px; } -#XsheetScrollBar:horizontal { - height: 18px; - margin-left: 20px; - margin-right: 20px; +QScrollBar:horizontal { + height: 16px; + margin-left: 16px; + margin-right: 16px; margin-top: 0px; margin-bottom: 0px; } -#XsheetScrollBar::handle { - border-width: 4; +QScrollBar::handle { + border-width: 3; image-position: center center; } -#XsheetScrollBar::handle:vertical { - border-image: url("imgs/sb_g_vhandle.png") 4; +QScrollBar::handle:vertical { + border-image: url("imgs/sb_g_vhandle.png") 3; image: url("imgs/sb_g_vline.png"); min-height: 40px; } -#XsheetScrollBar::handle:horizontal { - border-image: url("imgs/sb_g_hhandle.png") 4; +QScrollBar::handle:horizontal { + border-image: url("imgs/sb_g_hhandle.png") 3; image: url("imgs/sb_g_hline.png"); min-width: 40px; } -#XsheetScrollBar::add-line { +QScrollBar::add-line { subcontrol-origin: margin; } -#XsheetScrollBar::add-line:vertical { +QScrollBar::add-line:vertical { image: url("imgs/sb_g_downarrow.png"); - height: 20px; + height: 16px; subcontrol-position: bottom; } -#XsheetScrollBar::add-line:vertical:pressed { +QScrollBar::add-line:vertical:pressed { image: url("imgs/sb_g_downarrow_pressed.png"); } -#XsheetScrollBar::add-line:horizontal { +QScrollBar::add-line:horizontal { image: url("imgs/sb_g_rarrow.png"); - width: 20px; + width: 16px; subcontrol-position: right; } -#XsheetScrollBar::add-line:horizontal:pressed { +QScrollBar::add-line:horizontal:pressed { image: url("imgs/sb_g_rarrow_pressed.png"); } -#XsheetScrollBar::sub-line { +QScrollBar::sub-line { subcontrol-origin: margin; } -#XsheetScrollBar::sub-line:vertical { +QScrollBar::sub-line:vertical { image: url("imgs/sb_g_uparrow.png"); - height: 20px; + height: 16px; subcontrol-position: top; } -#XsheetScrollBar::sub-line:vertical:pressed { +QScrollBar::sub-line:vertical:pressed { image: url("imgs/sb_g_uparrow_pressed.png"); } -#XsheetScrollBar::sub-line:horizontal { +QScrollBar::sub-line:horizontal { image: url("imgs/sb_g_larrow.png"); - width: 20px; + width: 16px; subcontrol-position: left; } -#XsheetScrollBar::sub-line:horizontal:pressed { +QScrollBar::sub-line:horizontal:pressed { image: url("imgs/sb_g_larrow_pressed.png"); } -#XsheetScrollBar::add-page { - background: none; +QScrollBar::add-page, +QScrollBar::sub-page { + background-color: #626262; } #noteTextEdit { color: black; @@ -1369,5 +1369,14 @@ QDialog #dialogButtonFrame { #LargeSizedText { font-size: 17px; } +#GearButton { + qproperty-icon: url("imgs/gear.png"); +} +#StartupLabel { + padding: 3px; +} +#StartupLabel:hover { + background-color: #626262; +} //# sourceMappingURL=gray_072.qss.map \ No newline at end of file diff --git a/stuff/config/qss/gray_072/gray_072_mac.qss b/stuff/config/qss/gray_072/gray_072_mac.qss index 182e253..ec73907 100644 --- a/stuff/config/qss/gray_072/gray_072_mac.qss +++ b/stuff/config/qss/gray_072/gray_072_mac.qss @@ -841,79 +841,79 @@ ParamsPage { background-color: #000080; } /* Customize QScrollBar vertical*/ -#XsheetScrollBar { - background-color: #626262; +QScrollBar { border: 1px solid black; /* buttons */ } -#XsheetScrollBar:vertical { - width: 18px; +QScrollBar:vertical { + width: 16px; margin-left: 0px; margin-right: 0px; - margin-top: 20px; - margin-bottom: 20px; + margin-top: 16px; + margin-bottom: 16px; } -#XsheetScrollBar:horizontal { - height: 18px; - margin-left: 20px; - margin-right: 20px; +QScrollBar:horizontal { + height: 16px; + margin-left: 16px; + margin-right: 16px; margin-top: 0px; margin-bottom: 0px; } -#XsheetScrollBar::handle { - border-width: 4; +QScrollBar::handle { + border-width: 3; image-position: center center; } -#XsheetScrollBar::handle:vertical { - border-image: url("imgs/sb_g_vhandle.png") 4; +QScrollBar::handle:vertical { + border-image: url("imgs/sb_g_vhandle.png") 3; image: url("imgs/sb_g_vline.png"); min-height: 40px; } -#XsheetScrollBar::handle:horizontal { - border-image: url("imgs/sb_g_hhandle.png") 4; +QScrollBar::handle:horizontal { + border-image: url("imgs/sb_g_hhandle.png") 3; image: url("imgs/sb_g_hline.png"); min-width: 40px; } -#XsheetScrollBar::add-line { +QScrollBar::add-line { subcontrol-origin: margin; } -#XsheetScrollBar::add-line:vertical { +QScrollBar::add-line:vertical { image: url("imgs/sb_g_downarrow.png"); - height: 20px; + height: 16px; subcontrol-position: bottom; } -#XsheetScrollBar::add-line:vertical:pressed { +QScrollBar::add-line:vertical:pressed { image: url("imgs/sb_g_downarrow_pressed.png"); } -#XsheetScrollBar::add-line:horizontal { +QScrollBar::add-line:horizontal { image: url("imgs/sb_g_rarrow.png"); - width: 20px; + width: 16px; subcontrol-position: right; } -#XsheetScrollBar::add-line:horizontal:pressed { +QScrollBar::add-line:horizontal:pressed { image: url("imgs/sb_g_rarrow_pressed.png"); } -#XsheetScrollBar::sub-line { +QScrollBar::sub-line { subcontrol-origin: margin; } -#XsheetScrollBar::sub-line:vertical { +QScrollBar::sub-line:vertical { image: url("imgs/sb_g_uparrow.png"); - height: 20px; + height: 16px; subcontrol-position: top; } -#XsheetScrollBar::sub-line:vertical:pressed { +QScrollBar::sub-line:vertical:pressed { image: url("imgs/sb_g_uparrow_pressed.png"); } -#XsheetScrollBar::sub-line:horizontal { +QScrollBar::sub-line:horizontal { image: url("imgs/sb_g_larrow.png"); - width: 20px; + width: 16px; subcontrol-position: left; } -#XsheetScrollBar::sub-line:horizontal:pressed { +QScrollBar::sub-line:horizontal:pressed { image: url("imgs/sb_g_larrow_pressed.png"); } -#XsheetScrollBar::add-page { - background: none; +QScrollBar::add-page, +QScrollBar::sub-page { + background-color: #626262; } #noteTextEdit { color: black; @@ -1369,5 +1369,14 @@ QDialog #dialogButtonFrame { #LargeSizedText { font-size: 17px; } +#GearButton { + qproperty-icon: url("imgs/gear.png"); +} +#StartupLabel { + padding: 3px; +} +#StartupLabel:hover { + background-color: #626262; +} //# sourceMappingURL=gray_072_mac.qss.map \ No newline at end of file diff --git a/stuff/config/qss/gray_072/imgs/gear.png b/stuff/config/qss/gray_072/imgs/gear.png new file mode 100644 index 0000000..7e07631 Binary files /dev/null and b/stuff/config/qss/gray_072/imgs/gear.png differ diff --git a/stuff/config/qss/gray_072/imgs/sb_g_downarrow.png b/stuff/config/qss/gray_072/imgs/sb_g_downarrow.png index cb7c0de..406effb 100644 Binary files a/stuff/config/qss/gray_072/imgs/sb_g_downarrow.png and b/stuff/config/qss/gray_072/imgs/sb_g_downarrow.png differ diff --git a/stuff/config/qss/gray_072/imgs/sb_g_downarrow_pressed.png b/stuff/config/qss/gray_072/imgs/sb_g_downarrow_pressed.png index 04fe449..70df3a6 100644 Binary files a/stuff/config/qss/gray_072/imgs/sb_g_downarrow_pressed.png and b/stuff/config/qss/gray_072/imgs/sb_g_downarrow_pressed.png differ diff --git a/stuff/config/qss/gray_072/imgs/sb_g_larrow.png b/stuff/config/qss/gray_072/imgs/sb_g_larrow.png index 686f566..01d4162 100644 Binary files a/stuff/config/qss/gray_072/imgs/sb_g_larrow.png and b/stuff/config/qss/gray_072/imgs/sb_g_larrow.png differ diff --git a/stuff/config/qss/gray_072/imgs/sb_g_larrow_pressed.png b/stuff/config/qss/gray_072/imgs/sb_g_larrow_pressed.png index 1450404..0f83f2a 100644 Binary files a/stuff/config/qss/gray_072/imgs/sb_g_larrow_pressed.png and b/stuff/config/qss/gray_072/imgs/sb_g_larrow_pressed.png differ diff --git a/stuff/config/qss/gray_072/imgs/sb_g_ls_downarrow.png b/stuff/config/qss/gray_072/imgs/sb_g_ls_downarrow.png deleted file mode 100644 index 406effb..0000000 Binary files a/stuff/config/qss/gray_072/imgs/sb_g_ls_downarrow.png and /dev/null differ diff --git a/stuff/config/qss/gray_072/imgs/sb_g_ls_downarrow_pressed.png b/stuff/config/qss/gray_072/imgs/sb_g_ls_downarrow_pressed.png deleted file mode 100644 index 70df3a6..0000000 Binary files a/stuff/config/qss/gray_072/imgs/sb_g_ls_downarrow_pressed.png and /dev/null differ diff --git a/stuff/config/qss/gray_072/imgs/sb_g_ls_uparrow.png b/stuff/config/qss/gray_072/imgs/sb_g_ls_uparrow.png deleted file mode 100644 index 5979c72..0000000 Binary files a/stuff/config/qss/gray_072/imgs/sb_g_ls_uparrow.png and /dev/null differ diff --git a/stuff/config/qss/gray_072/imgs/sb_g_ls_uparrow_pressed.png b/stuff/config/qss/gray_072/imgs/sb_g_ls_uparrow_pressed.png deleted file mode 100644 index eb84176..0000000 Binary files a/stuff/config/qss/gray_072/imgs/sb_g_ls_uparrow_pressed.png and /dev/null differ diff --git a/stuff/config/qss/gray_072/imgs/sb_g_rarrow.png b/stuff/config/qss/gray_072/imgs/sb_g_rarrow.png index 29f6518..4c997fc 100644 Binary files a/stuff/config/qss/gray_072/imgs/sb_g_rarrow.png and b/stuff/config/qss/gray_072/imgs/sb_g_rarrow.png differ diff --git a/stuff/config/qss/gray_072/imgs/sb_g_rarrow_pressed.png b/stuff/config/qss/gray_072/imgs/sb_g_rarrow_pressed.png index 2fa0aef..579f8f9 100644 Binary files a/stuff/config/qss/gray_072/imgs/sb_g_rarrow_pressed.png and b/stuff/config/qss/gray_072/imgs/sb_g_rarrow_pressed.png differ diff --git a/stuff/config/qss/gray_072/imgs/sb_g_uparrow.png b/stuff/config/qss/gray_072/imgs/sb_g_uparrow.png index 16c8136..5979c72 100644 Binary files a/stuff/config/qss/gray_072/imgs/sb_g_uparrow.png and b/stuff/config/qss/gray_072/imgs/sb_g_uparrow.png differ diff --git a/stuff/config/qss/gray_072/imgs/sb_g_uparrow_pressed.png b/stuff/config/qss/gray_072/imgs/sb_g_uparrow_pressed.png index 95224d9..eb84176 100644 Binary files a/stuff/config/qss/gray_072/imgs/sb_g_uparrow_pressed.png and b/stuff/config/qss/gray_072/imgs/sb_g_uparrow_pressed.png differ diff --git a/stuff/config/qss/gray_128/gray_128.less b/stuff/config/qss/gray_128/gray_128.less index 2c13e25..31fa3db 100644 --- a/stuff/config/qss/gray_128/gray_128.less +++ b/stuff/config/qss/gray_128/gray_128.less @@ -1,3 +1,4 @@ +// out: gray_128.qss /* LESS Definitions */ /*Image URL*/ @@ -595,7 +596,7 @@ DvDirTreeView { /*---------------------------------------------------------------------------*/ #CleanupSettingsFrame, #LoadLevelFrame, -#SolidLineFrame{ +#SolidLineFrame { border: 1px solid rgb(20,20,20); } @@ -661,30 +662,29 @@ ParamsPage { } } /* Customize QScrollBar vertical*/ -#XsheetScrollBar { - background-color: rgb(160,160,160); +QScrollBar { border: 1px solid black; &:vertical { - width: 18px; - .set_margin( 0px, 20px ); + width: 16px; + .set_margin( 0px, 16px ); } &:horizontal { - height: 18px; - .set_margin( 20px, 0px ); + height: 16px; + .set_margin( 16px, 0px ); } &::handle { - border-width: 4; + border-width: 3; image-position: center center; &:vertical { - border-image: url("@{image_url}/sb_g_vhandle.png")4; + border-image: url("@{image_url}/sb_g_vhandle.png")3; image: url("@{image_url}/sb_g_vline.png"); min-height: 40px; } &:horizontal { - border-image: url("@{image_url}/sb_g_hhandle.png")4; + border-image: url("@{image_url}/sb_g_hhandle.png")3; image: url("@{image_url}/sb_g_hline.png"); min-width: 40px; } @@ -694,7 +694,7 @@ ParamsPage { subcontrol-origin: margin; &:vertical { image: url("@{image_url}/sb_g_downarrow.png"); - height: 20px; + height: 16px; subcontrol-position: bottom; &:pressed { image: url("@{image_url}/sb_g_downarrow_pressed.png"); @@ -702,7 +702,7 @@ ParamsPage { } &:horizontal { image: url("@{image_url}/sb_g_rarrow.png"); - width: 20px; + width: 16px; subcontrol-position: right; &:pressed{ image: url("@{image_url}/sb_g_rarrow_pressed.png"); @@ -714,7 +714,7 @@ ParamsPage { subcontrol-origin: margin; &:vertical { image: url("@{image_url}/sb_g_uparrow.png"); - height: 20px; + height: 16px; subcontrol-position: top; &:pressed { image: url("@{image_url}/sb_g_uparrow_pressed.png"); @@ -722,7 +722,7 @@ ParamsPage { } &:horizontal { image: url("@{image_url}/sb_g_larrow.png"); - width: 20px; + width: 16px; subcontrol-position: left; &:pressed{ image: url("@{image_url}/sb_g_larrow_pressed.png"); @@ -730,8 +730,8 @@ ParamsPage { } } - &::add-page { - background: none; + &::add-page, &::sub-page { + background-color: rgb(160,160,160); } } @@ -1190,4 +1190,15 @@ QDialog #dialogButtonFrame { #LargeSizedText { font-size: 17px; +} + +#GearButton { + qproperty-icon: url("@{image_url}/gear.png"); +} + +#StartupLabel { + padding: 3px; + &:hover { + .baseBG(light, 10%); + } } \ No newline at end of file diff --git a/stuff/config/qss/gray_128/gray_128.qss b/stuff/config/qss/gray_128/gray_128.qss index 1f3a66e..c8f42cd 100644 --- a/stuff/config/qss/gray_128/gray_128.qss +++ b/stuff/config/qss/gray_128/gray_128.qss @@ -591,79 +591,79 @@ ParamsPage { background-color: #000080; } /* Customize QScrollBar vertical*/ -#XsheetScrollBar { - background-color: #a0a0a0; +QScrollBar { border: 1px solid black; /* buttons */ } -#XsheetScrollBar:vertical { - width: 18px; +QScrollBar:vertical { + width: 16px; margin-left: 0px; margin-right: 0px; - margin-top: 20px; - margin-bottom: 20px; + margin-top: 16px; + margin-bottom: 16px; } -#XsheetScrollBar:horizontal { - height: 18px; - margin-left: 20px; - margin-right: 20px; +QScrollBar:horizontal { + height: 16px; + margin-left: 16px; + margin-right: 16px; margin-top: 0px; margin-bottom: 0px; } -#XsheetScrollBar::handle { - border-width: 4; +QScrollBar::handle { + border-width: 3; image-position: center center; } -#XsheetScrollBar::handle:vertical { - border-image: url("imgs/sb_g_vhandle.png") 4; +QScrollBar::handle:vertical { + border-image: url("imgs/sb_g_vhandle.png") 3; image: url("imgs/sb_g_vline.png"); min-height: 40px; } -#XsheetScrollBar::handle:horizontal { - border-image: url("imgs/sb_g_hhandle.png") 4; +QScrollBar::handle:horizontal { + border-image: url("imgs/sb_g_hhandle.png") 3; image: url("imgs/sb_g_hline.png"); min-width: 40px; } -#XsheetScrollBar::add-line { +QScrollBar::add-line { subcontrol-origin: margin; } -#XsheetScrollBar::add-line:vertical { +QScrollBar::add-line:vertical { image: url("imgs/sb_g_downarrow.png"); - height: 20px; + height: 16px; subcontrol-position: bottom; } -#XsheetScrollBar::add-line:vertical:pressed { +QScrollBar::add-line:vertical:pressed { image: url("imgs/sb_g_downarrow_pressed.png"); } -#XsheetScrollBar::add-line:horizontal { +QScrollBar::add-line:horizontal { image: url("imgs/sb_g_rarrow.png"); - width: 20px; + width: 16px; subcontrol-position: right; } -#XsheetScrollBar::add-line:horizontal:pressed { +QScrollBar::add-line:horizontal:pressed { image: url("imgs/sb_g_rarrow_pressed.png"); } -#XsheetScrollBar::sub-line { +QScrollBar::sub-line { subcontrol-origin: margin; } -#XsheetScrollBar::sub-line:vertical { +QScrollBar::sub-line:vertical { image: url("imgs/sb_g_uparrow.png"); - height: 20px; + height: 16px; subcontrol-position: top; } -#XsheetScrollBar::sub-line:vertical:pressed { +QScrollBar::sub-line:vertical:pressed { image: url("imgs/sb_g_uparrow_pressed.png"); } -#XsheetScrollBar::sub-line:horizontal { +QScrollBar::sub-line:horizontal { image: url("imgs/sb_g_larrow.png"); - width: 20px; + width: 16px; subcontrol-position: left; } -#XsheetScrollBar::sub-line:horizontal:pressed { +QScrollBar::sub-line:horizontal:pressed { image: url("imgs/sb_g_larrow_pressed.png"); } -#XsheetScrollBar::add-page { - background: none; +QScrollBar::add-page, +QScrollBar::sub-page { + background-color: #a0a0a0; } XsheetViewer { qproperty-TextColor: black; @@ -1108,5 +1108,14 @@ QDialog #dialogButtonFrame { #LargeSizedText { font-size: 17px; } +#GearButton { + qproperty-icon: url("imgs/gear.png"); +} +#StartupLabel { + padding: 3px; +} +#StartupLabel:hover { + background-color: #9a9a9a; +} //# sourceMappingURL=gray_128.qss.map \ No newline at end of file diff --git a/stuff/config/qss/gray_128/gray_128_mac.qss b/stuff/config/qss/gray_128/gray_128_mac.qss index f66c40d..8f53904 100644 --- a/stuff/config/qss/gray_128/gray_128_mac.qss +++ b/stuff/config/qss/gray_128/gray_128_mac.qss @@ -591,79 +591,79 @@ ParamsPage { background-color: #000080; } /* Customize QScrollBar vertical*/ -#XsheetScrollBar { - background-color: #a0a0a0; +QScrollBar { border: 1px solid black; /* buttons */ } -#XsheetScrollBar:vertical { - width: 18px; +QScrollBar:vertical { + width: 16px; margin-left: 0px; margin-right: 0px; - margin-top: 20px; - margin-bottom: 20px; + margin-top: 16px; + margin-bottom: 16px; } -#XsheetScrollBar:horizontal { - height: 18px; - margin-left: 20px; - margin-right: 20px; +QScrollBar:horizontal { + height: 16px; + margin-left: 16px; + margin-right: 16px; margin-top: 0px; margin-bottom: 0px; } -#XsheetScrollBar::handle { - border-width: 4; +QScrollBar::handle { + border-width: 3; image-position: center center; } -#XsheetScrollBar::handle:vertical { - border-image: url("imgs/sb_g_vhandle.png") 4; +QScrollBar::handle:vertical { + border-image: url("imgs/sb_g_vhandle.png") 3; image: url("imgs/sb_g_vline.png"); min-height: 40px; } -#XsheetScrollBar::handle:horizontal { - border-image: url("imgs/sb_g_hhandle.png") 4; +QScrollBar::handle:horizontal { + border-image: url("imgs/sb_g_hhandle.png") 3; image: url("imgs/sb_g_hline.png"); min-width: 40px; } -#XsheetScrollBar::add-line { +QScrollBar::add-line { subcontrol-origin: margin; } -#XsheetScrollBar::add-line:vertical { +QScrollBar::add-line:vertical { image: url("imgs/sb_g_downarrow.png"); - height: 20px; + height: 16px; subcontrol-position: bottom; } -#XsheetScrollBar::add-line:vertical:pressed { +QScrollBar::add-line:vertical:pressed { image: url("imgs/sb_g_downarrow_pressed.png"); } -#XsheetScrollBar::add-line:horizontal { +QScrollBar::add-line:horizontal { image: url("imgs/sb_g_rarrow.png"); - width: 20px; + width: 16px; subcontrol-position: right; } -#XsheetScrollBar::add-line:horizontal:pressed { +QScrollBar::add-line:horizontal:pressed { image: url("imgs/sb_g_rarrow_pressed.png"); } -#XsheetScrollBar::sub-line { +QScrollBar::sub-line { subcontrol-origin: margin; } -#XsheetScrollBar::sub-line:vertical { +QScrollBar::sub-line:vertical { image: url("imgs/sb_g_uparrow.png"); - height: 20px; + height: 16px; subcontrol-position: top; } -#XsheetScrollBar::sub-line:vertical:pressed { +QScrollBar::sub-line:vertical:pressed { image: url("imgs/sb_g_uparrow_pressed.png"); } -#XsheetScrollBar::sub-line:horizontal { +QScrollBar::sub-line:horizontal { image: url("imgs/sb_g_larrow.png"); - width: 20px; + width: 16px; subcontrol-position: left; } -#XsheetScrollBar::sub-line:horizontal:pressed { +QScrollBar::sub-line:horizontal:pressed { image: url("imgs/sb_g_larrow_pressed.png"); } -#XsheetScrollBar::add-page { - background: none; +QScrollBar::add-page, +QScrollBar::sub-page { + background-color: #a0a0a0; } XsheetViewer { qproperty-TextColor: black; @@ -1108,5 +1108,14 @@ QDialog #dialogButtonFrame { #LargeSizedText { font-size: 17px; } +#GearButton { + qproperty-icon: url("imgs/gear.png"); +} +#StartupLabel { + padding: 3px; +} +#StartupLabel:hover { + background-color: #9a9a9a; +} //# sourceMappingURL=gray_128_mac.qss.map \ No newline at end of file diff --git a/stuff/config/qss/gray_128/imgs/gear.png b/stuff/config/qss/gray_128/imgs/gear.png new file mode 100644 index 0000000..36477dd Binary files /dev/null and b/stuff/config/qss/gray_128/imgs/gear.png differ diff --git a/stuff/config/qss/gray_128/imgs/sb_g_downarrow.png b/stuff/config/qss/gray_128/imgs/sb_g_downarrow.png index f5e678c..4747674 100644 Binary files a/stuff/config/qss/gray_128/imgs/sb_g_downarrow.png and b/stuff/config/qss/gray_128/imgs/sb_g_downarrow.png differ diff --git a/stuff/config/qss/gray_128/imgs/sb_g_downarrow_pressed.png b/stuff/config/qss/gray_128/imgs/sb_g_downarrow_pressed.png index ca150f6..0e10442 100644 Binary files a/stuff/config/qss/gray_128/imgs/sb_g_downarrow_pressed.png and b/stuff/config/qss/gray_128/imgs/sb_g_downarrow_pressed.png differ diff --git a/stuff/config/qss/gray_128/imgs/sb_g_larrow.png b/stuff/config/qss/gray_128/imgs/sb_g_larrow.png index db68d6d..44e406e 100644 Binary files a/stuff/config/qss/gray_128/imgs/sb_g_larrow.png and b/stuff/config/qss/gray_128/imgs/sb_g_larrow.png differ diff --git a/stuff/config/qss/gray_128/imgs/sb_g_larrow_pressed.png b/stuff/config/qss/gray_128/imgs/sb_g_larrow_pressed.png index 23acd01..c3b6701 100644 Binary files a/stuff/config/qss/gray_128/imgs/sb_g_larrow_pressed.png and b/stuff/config/qss/gray_128/imgs/sb_g_larrow_pressed.png differ diff --git a/stuff/config/qss/gray_128/imgs/sb_g_rarrow.png b/stuff/config/qss/gray_128/imgs/sb_g_rarrow.png index 17c8865..92b1e59 100644 Binary files a/stuff/config/qss/gray_128/imgs/sb_g_rarrow.png and b/stuff/config/qss/gray_128/imgs/sb_g_rarrow.png differ diff --git a/stuff/config/qss/gray_128/imgs/sb_g_rarrow_pressed.png b/stuff/config/qss/gray_128/imgs/sb_g_rarrow_pressed.png index 873e91b..cc9c423 100644 Binary files a/stuff/config/qss/gray_128/imgs/sb_g_rarrow_pressed.png and b/stuff/config/qss/gray_128/imgs/sb_g_rarrow_pressed.png differ diff --git a/stuff/config/qss/gray_128/imgs/sb_g_uparrow.png b/stuff/config/qss/gray_128/imgs/sb_g_uparrow.png index 3fd43db..e0c71f9 100644 Binary files a/stuff/config/qss/gray_128/imgs/sb_g_uparrow.png and b/stuff/config/qss/gray_128/imgs/sb_g_uparrow.png differ diff --git a/stuff/config/qss/gray_128/imgs/sb_g_uparrow_pressed.png b/stuff/config/qss/gray_128/imgs/sb_g_uparrow_pressed.png index 37b4e73..74d514b 100644 Binary files a/stuff/config/qss/gray_128/imgs/sb_g_uparrow_pressed.png and b/stuff/config/qss/gray_128/imgs/sb_g_uparrow_pressed.png differ diff --git a/stuff/profiles/layouts/rooms/Default/menubar_template.xml b/stuff/profiles/layouts/rooms/Default/menubar_template.xml index 5df924e..92a3b14 100644 --- a/stuff/profiles/layouts/rooms/Default/menubar_template.xml +++ b/stuff/profiles/layouts/rooms/Default/menubar_template.xml @@ -2,9 +2,9 @@ MI_NewScene MI_LoadScene + MI_SaveAll MI_SaveScene MI_SaveSceneAs - MI_SaveAll MI_OpenRecentScene MI_RevertScene @@ -13,6 +13,7 @@ MI_NewLevel MI_LoadLevel + MI_SaveAllLevels MI_SaveLevel MI_SaveLevelAs MI_ExportLevel @@ -33,6 +34,7 @@ MI_OutputSettings MI_Render + MI_FastRender MI_PrintXsheet MI_Print @@ -233,6 +235,7 @@ MI_ResetRoomLayout + MI_StartupPopup MI_About \ No newline at end of file diff --git a/stuff/profiles/layouts/rooms/StudioGhibli/menubar_template.xml b/stuff/profiles/layouts/rooms/StudioGhibli/menubar_template.xml index eee1faf..b78b58c 100644 --- a/stuff/profiles/layouts/rooms/StudioGhibli/menubar_template.xml +++ b/stuff/profiles/layouts/rooms/StudioGhibli/menubar_template.xml @@ -13,6 +13,7 @@ MI_NewLevel MI_LoadLevel + MI_SaveAllLevels MI_SaveLevel MI_SaveLevelAs MI_ExportLevel diff --git a/stuff/profiles/layouts/shortcuts/defopentoonz.ini b/stuff/profiles/layouts/shortcuts/defopentoonz.ini new file mode 100644 index 0000000..27ec312 --- /dev/null +++ b/stuff/profiles/layouts/shortcuts/defopentoonz.ini @@ -0,0 +1,366 @@ +[shortcuts] +MI_Clear=Del +MI_OnionSkin=/ +A_DecreaseBrushHardness= +A_DecreaseMaxBrushThickness=U +A_DecreaseMinBrushThickness=H +A_FxSchematicToggle= +A_IncreaseBrushHardness= +A_IncreaseMaxBrushThickness=I +A_IncreaseMinBrushThickness=J +A_ToolOption_AutoGroup= +A_ToolOption_AutoSelect%3AColumn= +A_ToolOption_AutoSelect%3ANone= +A_ToolOption_AutoSelect%3APegbar= +A_ToolOption_AutoSelectDrawing= +A_ToolOption_Autofill= +A_ToolOption_BreakSharpAngles= +A_ToolOption_BrushPreset= +A_ToolOption_EditToolActiveAxis= +A_ToolOption_EditToolActiveAxis%3ACenter= +A_ToolOption_EditToolActiveAxis%3APosition= +A_ToolOption_EditToolActiveAxis%3ARotation= +A_ToolOption_EditToolActiveAxis%3AScale= +A_ToolOption_EditToolActiveAxis%3AShear= +A_ToolOption_FrameRange=F6 +A_ToolOption_GeometricEdge= +A_ToolOption_GeometricShape= +A_ToolOption_GlobalKey= +A_ToolOption_IK= +A_ToolOption_Invert= +A_ToolOption_JoinVectors= +A_ToolOption_Manual= +A_ToolOption_Meshify= +A_ToolOption_Mode= +A_ToolOption_Mode%3AAreas= +A_ToolOption_Mode%3ALines= +A_ToolOption_Mode%3ALines%20%26%20Areas= +A_ToolOption_OnionSkin= +A_ToolOption_Orientation= +A_ToolOption_PencilMode= +A_ToolOption_PickScreen= +A_ToolOption_PreserveThickness= +A_ToolOption_PressureSensitivity=Shift+P +A_ToolOption_SegmentInk=F8 +A_ToolOption_Selective=F7 +A_ToolOption_ShowOnlyActiveSkeleton= +A_ToolOption_SkeletonMode%3AAnimate= +A_ToolOption_SkeletonMode%3ABuild%20Skeleton= +A_ToolOption_SkeletonMode%3AInverse%20Kinematics= +A_ToolOption_Smooth= +A_ToolOption_Snap= +A_ToolOption_Type= +A_ToolOption_Type%3AFreehand= +A_ToolOption_Type%3ANormal= +A_ToolOption_Type%3APolyline= +A_ToolOption_Type%3ARectangular=F5 +A_ToolOption_TypeFont= +A_ToolOption_TypeSize= +A_ToolOption_TypeStyle= +MI_ACheck= +MI_About= +MI_ActivateAllColumns= +MI_ActivateSelectedColumns= +MI_ActivateThisColumnOnly= +MI_AddFrames= +MI_AddToBatchCleanupList= +MI_AddToBatchRenderList= +MI_AdjustLevels= +MI_AdjustThickness= +MI_Antialias= +MI_ApplyMatchLines= +MI_AutoFillToggle=Shift+A +MI_Autocenter= +MI_Autorenumber= +MI_BCheck= +MI_Binarize= +MI_BlendColors= +MI_BlueChannel= +MI_BlueChannelGreyscale= +MI_BrightnessAndContrast= +MI_BringForward=] +MI_BringToFront=Ctrl+] +MI_CameraSettings= +MI_CameraStage= +MI_CameraTest= +MI_CanvasSize= +MI_Cleanup= +MI_CleanupPreview= +MI_CleanupSettings= +MI_ClearRecentImage= +MI_ClearRecentLevel= +MI_ClearRecentScene= +MI_CloneChild= +MI_CloneLevel= +MI_ClonePreview= +MI_CloseChild= +MI_Collapse= +MI_CollectAssets= +MI_CompareToSnapshot= +MI_ConvertFileWithInput= +MI_ConvertFiles= +MI_ConvertToVectors= +MI_Copy=Ctrl+C +MI_Cut=Ctrl+X +MI_DeactivateAllColumns= +MI_DeactivateSelectedColumns= +MI_DeactivateUpperColumns= +MI_DecreaseStep=";" +MI_DefineScanner= +MI_DeleteInk= +MI_DeleteMatchLines= +MI_DisableAllColumns= +MI_DisableSelectedColumns= +MI_DockingCheck= +MI_DrawingSubBackward=Q +MI_DrawingSubForward=W +MI_DrawingSubGroupBackward=Alt+Q +MI_DrawingSubGroupForward=Alt+W +MI_Dup= +MI_Duplicate=D +MI_DuplicateFile= +MI_Each2= +MI_Each3= +MI_Each4= +MI_EditLevel= +MI_EditShift= +MI_EnableAllColumns= +MI_EnableSelectedColumns= +MI_EnableThisColumnOnly= +MI_EnterGroup= +MI_EraseUnusedStyles= +MI_ExitGroup= +MI_ExplodeChild= +MI_ExportLevel= +MI_ExportScenes= +MI_ExposeResource= +MI_FieldGuide=Shift+G +MI_FileInfo= +MI_FillAreas= +MI_FillLines= +MI_FirstFrame="Alt+," +MI_FoldColumns= +MI_FrezzePreview= +MI_FullScreenWindow=Ctrl+` +MI_FxParamEditor=Ctrl+K +MI_GCheck= +MI_GetColorFromStudioPalette= +MI_GreenChannel= +MI_GreenChannelGreyscale= +MI_Group=Ctrl+G +MI_Histogram= +MI_ICheck= +MI_IOnly= +MI_ImportMagpieFile= +MI_ImportScenes= +MI_IncreaseStep="'" +MI_Increment= +MI_Ink1Check= +MI_Insert=Ins +MI_InsertFx=Ctrl+F +MI_InsertGlobalKeyframe= +MI_InsertSceneFrame= +MI_InvertKeyframeSelection= +MI_InvertSelection= +MI_LastFrame=Alt+. +MI_LevelSettings= +MI_LinesFade= +MI_Link= +MI_LoadColorModel= +MI_LoadFolder= +MI_LoadLevel= +MI_LoadScene=Ctrl+L +MI_LoadSubSceneFile= +MI_LockAllColumns=Ctrl+Alt+Shift+L +MI_LockSelectedColumns=Ctrl+Shift+L +MI_LockThisColumnOnly=Shift+L +MI_Loop=L +MI_MatteChannel= +MI_MaximizePanel=` +MI_MergeCmapped= +MI_MergeColumns= +MI_MergeFrames= +MI_NewLevel=Alt+N +MI_NewOutputFx= +MI_NewProject= +MI_NewScene=Ctrl+N +MI_NextDrawing=. +MI_NextFrame=Shift+. +MI_NextStep= +MI_NoShift= +MI_OpacityCheck=Alt+1 +MI_OpenBatchServers= +MI_OpenChild= +MI_OpenCleanupSettings= +MI_OpenColorModel= +MI_OpenComboViewer= +MI_OpenFileBrowser= +MI_OpenFileBrowser2= +MI_OpenFileViewer= +MI_OpenFilmStrip= +MI_OpenFunctionEditor= +MI_OpenHistoryPanel=Ctrl+H +MI_OpenLevelView= +MI_OpenPalette= +MI_OpenPltGizmo= +MI_OpenRecentLevel= +MI_OpenRecentScene= +MI_OpenSchematic= +MI_OpenScriptConsole= +MI_OpenStudioPalette= +MI_OpenStyleControl= +MI_OpenTMessage= +MI_OpenTasks= +MI_OpenToolOptionBar= +MI_OpenToolbar= +MI_OpenXshView= +MI_OutputSettings=Ctrl+O +MI_OverwritePalette= +MI_PCheck= +MI_Paste=Ctrl+V +MI_PasteColors= +MI_PasteInto= +MI_PasteNames= +MI_PasteValues= +MI_Pause= +MI_PencilTest= +MI_PickStyleAreas= +MI_PickStyleLines= +MI_Play=P +MI_Preferences=Ctrl+U +MI_PrevDrawing="," +MI_PrevFrame="Shift+," +MI_PrevStep= +MI_Preview=Ctrl+R +MI_PreviewFx= +MI_PreviewSettings= +MI_Print=Ctrl+P +MI_PrintXsheet= +MI_ProjectSettings= +MI_Quit=Ctrl+Q +MI_Random= +MI_RasterizePli= +MI_RedChannel= +MI_RedChannelGreyscale= +MI_Redo=Ctrl+Y +MI_Reframe1= +MI_Reframe2= +MI_Reframe3= +MI_Reframe4= +MI_RefreshTree= +MI_RegenerateFramePr= +MI_RegeneratePreview= +MI_ReloadStyle= +MI_RemoveEndpoints= +MI_RemoveGlobalKeyframe= +MI_RemoveLevel= +MI_RemoveSceneFrame= +MI_RemoveUnused= +MI_Render=Ctrl+Shift+R +MI_Renumber= +MI_ReplaceLevel= +MI_ReplaceParentDirectory= +MI_Resequence= +MI_ResetInterpolation= +MI_ResetRoomLayout= +MI_ResetScanCropbox= +MI_ResetShift= +MI_ResetStep= +MI_Reverse= +MI_RevertScene= +MI_RevertToCleanedUp= +MI_RevertToLastSaved= +MI_Rolldown= +MI_Rollup= +MI_RunScript= +MI_SafeArea= +MI_SaveAll=Ctrl+S +MI_SaveDefaultSettings= +MI_SaveLevel= +MI_SaveLevelAs= +MI_SavePaletteAs= +MI_SavePreset= +MI_SavePreviewedFrames= +MI_SaveScene=Ctrl+Shift+S +MI_SaveSceneAs= +MI_SaveSubxsheetAs= +MI_Scan= +MI_ScanSettings= +MI_SceneSettings= +MI_SelectAll=Ctrl+A +MI_SelectAllKeyframes= +MI_SelectAllKeyframesNotAfter= +MI_SelectAllKeyframesNotBefore= +MI_SelectColumnKeyframes= +MI_SelectFollowingKeysInColumn= +MI_SelectFollowingKeysInRow= +MI_SelectPreviousKeysInColumn= +MI_SelectPreviousKeysInRow= +MI_SelectRowKeyframes= +MI_SendBack=Ctrl+[ +MI_SendBackward=[ +MI_SetAcceleration= +MI_SetConstantSpeed= +MI_SetDeceleration= +MI_SetKeyframes=Z +MI_SetScanCropbox= +MI_ShiftTrace= +MI_ShortcutPopup= +MI_ShowFolderContents= +MI_Step2= +MI_Step3= +MI_Step4= +MI_SwapEnabledColumns= +MI_Swing= +MI_TCheck= +MI_TimeStretch= +MI_ToggleColumnLocks= +MI_ToggleColumnsActivation= +MI_ToggleEditInPlace= +MI_Tracking= +MI_Undo=Ctrl+Z +MI_Ungroup=Ctrl+Shift+G +MI_UnlockAllColumns=Ctrl+Alt+Shift+U +MI_UnlockSelectedColumns=Ctrl+Shift+U +MI_ViewBBox= +MI_ViewCamera= +MI_ViewColorcard= +MI_ViewFile= +MI_ViewGuide= +MI_ViewRuler= +MI_ViewTable= +MI_ZeroThick=Shift+/ +T_ActualPixelSize=N +T_Bender= +T_Brush=B +T_ControlPointEditor=C +T_Cutter= +T_Edit=E +T_Eraser=A +T_Fill=F +T_Finger= +T_Geometric=G +T_Hand=Space +T_Hook=O +T_Iron= +T_Magnet= +T_PaintBrush= +T_Pinch=M +T_Plastic=X +T_Pump= +T_RGBPicker=R +T_Rotate=Ctrl+Space +T_Ruler= +T_Selection=S +T_ShowHideFullScreen=Alt+F +T_Skeleton=V +T_StylePicker=K +T_Tape=T +T_Tracker= +T_Type=Y +T_Zoom=Shift+Space +T_ZoomFit=Alt+9 +T_ZoomReset=Alt+0 +T_Zoomin=+ +T_Zoomout=- +MI_LoadRecentImage= diff --git a/stuff/profiles/layouts/shortcuts/otadobe.ini b/stuff/profiles/layouts/shortcuts/otadobe.ini new file mode 100644 index 0000000..7a1b172 --- /dev/null +++ b/stuff/profiles/layouts/shortcuts/otadobe.ini @@ -0,0 +1,366 @@ +[shortcuts] +MI_LoadRecentImage= +A_ToolOption_FrameRange= +A_ToolOption_SegmentInk= +A_ToolOption_Selective= +A_ToolOption_Type%3ARectangular= +MI_BringForward=Ctrl+Up +MI_BringToFront=Ctrl+Shift+Up +MI_Clear=Delete +MI_Copy=Ctrl+C +MI_Cut=Ctrl+X +MI_DrawingSubBackward=[ +MI_DrawingSubForward=] +MI_DrawingSubGroupBackward=Ctrl+[ +MI_DrawingSubGroupForward=Ctrl+] +MI_Duplicate= +MI_FullScreenWindow=Ctrl+F +MI_FxParamEditor= +MI_Group=Ctrl+G +MI_Insert=Ins +MI_InsertFx= +MI_LoadScene=Ctrl+O +MI_MaximizePanel= +MI_NewScene=Ctrl+N +MI_NextDrawing=G +MI_NextFrame=. +MI_OpacityCheck= +MI_Paste=Ctrl+V +MI_PrevDrawing=F +MI_PrevFrame="," +MI_Preview=Alt+P +MI_Quit=Ctrl+Q +MI_Redo=Ctrl+Y +MI_SaveScene=Ctrl+Shift+S +MI_SaveSceneAs=Ctrl+Alt+Shift+S +MI_SelectAll=Shift+A +MI_SendBack=Ctrl+Shift+Down +MI_SendBackward=Ctrl+Down +MI_Undo=Ctrl+Z +MI_ZeroThick=D +T_ActualPixelSize= +T_Brush=Alt+B +T_ControlPointEditor=Alt+A +T_Edit=Alt+Q +T_Eraser=Alt+E +T_Fill=Alt+K +T_Geometric=Atl+R +T_Hand= +T_Pinch= +T_Rotate= +T_Selection=Alt+V +T_StylePicker=Alt+I +T_Tape=Alt+C +T_Type= +T_Zoom=Alt+Z +T_ZoomReset=Shift+Z +T_Zoomin=Ctrl+= +T_Zoomout=Ctrl+- +A_DecreaseBrushHardness= +A_DecreaseMaxBrushThickness= +A_DecreaseMinBrushThickness= +A_FxSchematicToggle= +A_IncreaseBrushHardness= +A_IncreaseMaxBrushThickness= +A_IncreaseMinBrushThickness= +A_ToolOption_AutoGroup= +A_ToolOption_AutoSelect%3AColumn= +A_ToolOption_AutoSelect%3ANone= +A_ToolOption_AutoSelect%3APegbar= +A_ToolOption_AutoSelectDrawing= +A_ToolOption_Autofill= +A_ToolOption_BreakSharpAngles= +A_ToolOption_BrushPreset= +A_ToolOption_EditToolActiveAxis= +A_ToolOption_EditToolActiveAxis%3ACenter= +A_ToolOption_EditToolActiveAxis%3APosition= +A_ToolOption_EditToolActiveAxis%3ARotation= +A_ToolOption_EditToolActiveAxis%3AScale= +A_ToolOption_EditToolActiveAxis%3AShear= +A_ToolOption_GeometricEdge= +A_ToolOption_GeometricShape= +A_ToolOption_GlobalKey= +A_ToolOption_IK=Alt+8 +A_ToolOption_Invert= +A_ToolOption_JoinVectors= +A_ToolOption_Manual= +A_ToolOption_Meshify= +A_ToolOption_Mode= +A_ToolOption_Mode%3AAreas= +A_ToolOption_Mode%3ALines= +A_ToolOption_Mode%3ALines%20%26%20Areas= +A_ToolOption_OnionSkin= +A_ToolOption_Orientation= +A_ToolOption_PencilMode= +A_ToolOption_PickScreen= +A_ToolOption_PreserveThickness= +A_ToolOption_PressureSensitivity= +A_ToolOption_ShowOnlyActiveSkeleton= +A_ToolOption_SkeletonMode%3AAnimate= +A_ToolOption_SkeletonMode%3ABuild%20Skeleton= +A_ToolOption_SkeletonMode%3AInverse%20Kinematics= +A_ToolOption_Smooth= +A_ToolOption_Snap= +A_ToolOption_Type= +A_ToolOption_Type%3AFreehand= +A_ToolOption_Type%3ANormal= +A_ToolOption_Type%3APolyline= +A_ToolOption_TypeFont= +A_ToolOption_TypeSize= +A_ToolOption_TypeStyle= +MI_ACheck= +MI_About= +MI_ActivateAllColumns= +MI_ActivateSelectedColumns= +MI_ActivateThisColumnOnly= +MI_AddFrames=Ctrl+H +MI_AddToBatchCleanupList= +MI_AddToBatchRenderList= +MI_AdjustLevels= +MI_AdjustThickness= +MI_Antialias= +MI_ApplyMatchLines= +MI_AutoFillToggle= +MI_Autocenter= +MI_Autorenumber= +MI_BCheck= +MI_Binarize= +MI_BlendColors= +MI_BlueChannel= +MI_BlueChannelGreyscale= +MI_BrightnessAndContrast= +MI_CameraSettings= +MI_CameraStage= +MI_CameraTest= +MI_CanvasSize= +MI_Cleanup= +MI_CleanupPreview= +MI_CleanupSettings= +MI_ClearRecentImage= +MI_ClearRecentLevel= +MI_ClearRecentScene= +MI_CloneChild= +MI_CloneLevel= +MI_ClonePreview= +MI_CloseChild= +MI_Collapse= +MI_CollectAssets= +MI_CompareToSnapshot= +MI_ConvertFileWithInput= +MI_ConvertFiles= +MI_ConvertToVectors= +MI_DeactivateAllColumns= +MI_DeactivateSelectedColumns=Alt+H +MI_DeactivateUpperColumns= +MI_DecreaseStep= +MI_DefineScanner= +MI_DeleteInk= +MI_DeleteMatchLines= +MI_DisableAllColumns= +MI_DisableSelectedColumns= +MI_DockingCheck= +MI_Dup= +MI_DuplicateFile= +MI_Each2= +MI_Each3= +MI_Each4= +MI_EditLevel= +MI_EditShift= +MI_EnableAllColumns=Alt+Shift+H +MI_EnableSelectedColumns= +MI_EnableThisColumnOnly= +MI_EnterGroup=Ctrl+Return +MI_EraseUnusedStyles= +MI_ExitGroup=Backspace +MI_ExplodeChild=Ctrl+B +MI_ExportLevel= +MI_ExportScenes= +MI_ExposeResource= +MI_FieldGuide="Ctrl+'" +MI_FileInfo= +MI_FillAreas= +MI_FillLines= +MI_FirstFrame=Home +MI_FoldColumns= +MI_FrezzePreview= +MI_GCheck= +MI_GetColorFromStudioPalette= +MI_GreenChannel= +MI_GreenChannelGreyscale= +MI_Histogram= +MI_ICheck= +MI_IOnly= +MI_ImportMagpieFile= +MI_ImportScenes= +MI_IncreaseStep="+" +MI_Increment= +MI_Ink1Check= +MI_InsertGlobalKeyframe= +MI_InsertSceneFrame= +MI_InvertKeyframeSelection= +MI_InvertSelection= +MI_LastFrame=End +MI_LevelSettings= +MI_LinesFade= +MI_Link= +MI_LoadColorModel= +MI_LoadFolder= +MI_LoadLevel= +MI_LoadSubSceneFile= +MI_LockAllColumns= +MI_LockSelectedColumns= +MI_LockThisColumnOnly= +MI_Loop= +MI_MatteChannel= +MI_MergeCmapped= +MI_MergeColumns= +MI_MergeFrames= +MI_NewLevel= +MI_NewOutputFx= +MI_NewProject= +MI_NextStep= +MI_NoShift= +MI_OnionSkin=Ctrl+Alt+O +MI_OpenBatchServers= +MI_OpenChild= +MI_OpenCleanupSettings= +MI_OpenColorModel= +MI_OpenComboViewer= +MI_OpenFileBrowser= +MI_OpenFileBrowser2= +MI_OpenFileViewer= +MI_OpenFilmStrip= +MI_OpenFunctionEditor=Alt+F +MI_OpenHistoryPanel= +MI_OpenLevelView= +MI_OpenPalette= +MI_OpenPltGizmo= +MI_OpenRecentScene= +MI_OpenSchematic= +MI_OpenScriptConsole= +MI_OpenStudioPalette= +MI_OpenStyleControl= +MI_OpenTMessage= +MI_OpenTasks= +MI_OpenToolOptionBar= +MI_OpenToolbar= +MI_OpenXshView= +MI_OutputSettings= +MI_OverwritePalette= +MI_PCheck= +MI_PasteColors= +MI_PasteInto= +MI_PasteNames= +MI_PasteValues= +MI_Pause= +MI_PencilTest= +MI_PickStyleAreas= +MI_PickStyleLines= +MI_Play=Return +MI_Preferences=Ctrl+U +MI_PrevStep= +MI_PreviewFx= +MI_PreviewSettings= +MI_Print= +MI_PrintXsheet= +MI_ProjectSettings= +MI_Random= +MI_RasterizePli= +MI_RedChannel= +MI_RedChannelGreyscale= +MI_Reframe1= +MI_Reframe2= +MI_Reframe3= +MI_Reframe4= +MI_RefreshTree= +MI_RegenerateFramePr= +MI_RegeneratePreview= +MI_ReloadStyle= +MI_RemoveEndpoints= +MI_RemoveGlobalKeyframe= +MI_RemoveLevel= +MI_RemoveSceneFrame= +MI_RemoveUnused= +MI_Render=Ctrl+Alt+Shift+S +MI_Renumber= +MI_ReplaceLevel= +MI_ReplaceParentDirectory= +MI_Resequence= +MI_ResetInterpolation= +MI_ResetRoomLayout= +MI_ResetScanCropbox= +MI_ResetShift= +MI_ResetStep= +MI_Reverse= +MI_RevertScene= +MI_RevertToCleanedUp= +MI_RevertToLastSaved= +MI_Rolldown= +MI_Rollup= +MI_RunScript= +MI_SafeArea= +MI_SaveAll=Ctrl+S +MI_SaveDefaultSettings= +MI_SaveLevel= +MI_SaveLevelAs= +MI_SavePaletteAs= +MI_SavePreset= +MI_SavePreviewedFrames= +MI_SaveSubxsheetAs= +MI_Scan= +MI_ScanSettings= +MI_SceneSettings=Ctrl+F3 +MI_SelectAllKeyframes= +MI_SelectAllKeyframesNotAfter= +MI_SelectAllKeyframesNotBefore= +MI_SelectColumnKeyframes= +MI_SelectFollowingKeysInColumn= +MI_SelectFollowingKeysInRow= +MI_SelectPreviousKeysInColumn= +MI_SelectPreviousKeysInRow= +MI_SelectRowKeyframes= +MI_SetAcceleration= +MI_SetConstantSpeed= +MI_SetDeceleration= +MI_SetKeyframes=Ctrl+F6 +MI_SetScanCropbox= +MI_ShiftTrace= +MI_ShortcutPopup= +MI_ShowFolderContents= +MI_Step2= +MI_Step3= +MI_Step4= +MI_SwapEnabledColumns= +MI_Swing= +MI_TCheck= +MI_TimeStretch= +MI_ToggleColumnLocks= +MI_ToggleColumnsActivation= +MI_ToggleEditInPlace= +MI_Tracking= +MI_Ungroup=Ctrl+Shift+G +MI_UnlockAllColumns=Ctrl+Alt+Shift+L +MI_UnlockSelectedColumns=Ctrl+Shift+K +MI_ViewBBox= +MI_ViewCamera= +MI_ViewColorcard= +MI_ViewFile= +MI_ViewGuide= +MI_ViewRuler=Ctrl+Alt+Shift+R +MI_ViewTable= +T_Bender= +T_Cutter=Alt+T +T_Finger= +T_Hook= +T_Iron= +T_Magnet= +T_PaintBrush= +T_Plastic= +T_Pump= +T_RGBPicker= +T_Ruler= +T_ShowHideFullScreen=F4 +T_Skeleton= +T_Tracker= +T_ZoomFit= +MI_OpenRecentLevel= diff --git a/stuff/profiles/layouts/shortcuts/otharmony.ini b/stuff/profiles/layouts/shortcuts/otharmony.ini new file mode 100644 index 0000000..3675e6d --- /dev/null +++ b/stuff/profiles/layouts/shortcuts/otharmony.ini @@ -0,0 +1,366 @@ +[shortcuts] +MI_LoadRecentImage= +A_ToolOption_FrameRange= +A_ToolOption_SegmentInk= +A_ToolOption_Selective= +A_ToolOption_Type%3ARectangular= +MI_BringForward=Ctrl+PgUp +MI_BringToFront=Ctrl+Shift+PgUp +MI_Clear=Delete +MI_Copy=Ctrl+C +MI_Cut=Ctrl+X +MI_DrawingSubBackward=[ +MI_DrawingSubForward=] +MI_DrawingSubGroupBackward=Ctrl+[ +MI_DrawingSubGroupForward=Ctrl+] +MI_Duplicate= +MI_FullScreenWindow=Ctrl+F +MI_FxParamEditor= +MI_Group=Ctrl+G +MI_Insert=Ins +MI_InsertFx= +MI_LoadScene=Ctrl+O +MI_MaximizePanel=` +MI_NewScene=Ctrl+N +MI_NextDrawing=G +MI_NextFrame=. +MI_OpacityCheck= +MI_Paste=Ctrl+V +MI_PrevDrawing=F +MI_PrevFrame="," +MI_Preview= +MI_Quit=Ctrl+Q +MI_Redo=Ctrl+Shift+Z +MI_SaveScene=Ctrl+Shift+S +MI_SaveSceneAs=Ctrl+Shift+Alt+S +MI_SelectAll=Ctrl+A +MI_SendBack=Ctrl+PgDown +MI_SendBackward=Ctrl+Shift+PgDown +MI_Undo=Ctrl+Z +MI_ZeroThick= +T_ActualPixelSize= +T_Brush=Alt+B +T_ControlPointEditor=Alt+Q +T_Edit=Shift+T +T_Eraser=Alt+E +T_Fill=Alt+I +T_Geometric=Alt+7 +T_Hand= +T_Pinch= +T_Rotate= +T_Selection=Alt+S +T_StylePicker=Alt+D +T_Tape=Alt+C +T_Type=Alt+9 +T_Zoom=Alt+Z +T_ZoomReset= +T_Zoomin=Alt+2 +T_Zoomout=Alt+1 +A_DecreaseBrushHardness= +A_DecreaseMaxBrushThickness= +A_DecreaseMinBrushThickness= +A_FxSchematicToggle= +A_IncreaseBrushHardness= +A_IncreaseMaxBrushThickness= +A_IncreaseMinBrushThickness= +A_ToolOption_AutoGroup= +A_ToolOption_AutoSelect%3AColumn= +A_ToolOption_AutoSelect%3ANone= +A_ToolOption_AutoSelect%3APegbar= +A_ToolOption_AutoSelectDrawing= +A_ToolOption_Autofill= +A_ToolOption_BreakSharpAngles= +A_ToolOption_BrushPreset= +A_ToolOption_EditToolActiveAxis= +A_ToolOption_EditToolActiveAxis%3ACenter= +A_ToolOption_EditToolActiveAxis%3APosition=Alt+2 +A_ToolOption_EditToolActiveAxis%3ARotation=Alt+3 +A_ToolOption_EditToolActiveAxis%3AScale=Alt+4 +A_ToolOption_EditToolActiveAxis%3AShear=Alt+5 +A_ToolOption_GeometricEdge= +A_ToolOption_GeometricShape= +A_ToolOption_GlobalKey= +A_ToolOption_IK= +A_ToolOption_Invert= +A_ToolOption_JoinVectors= +A_ToolOption_Manual= +A_ToolOption_Meshify= +A_ToolOption_Mode= +A_ToolOption_Mode%3AAreas= +A_ToolOption_Mode%3ALines= +A_ToolOption_Mode%3ALines%20%26%20Areas= +A_ToolOption_OnionSkin= +A_ToolOption_Orientation= +A_ToolOption_PencilMode= +A_ToolOption_PickScreen= +A_ToolOption_PreserveThickness= +A_ToolOption_PressureSensitivity= +A_ToolOption_ShowOnlyActiveSkeleton= +A_ToolOption_SkeletonMode%3AAnimate= +A_ToolOption_SkeletonMode%3ABuild%20Skeleton= +A_ToolOption_SkeletonMode%3AInverse%20Kinematics= +A_ToolOption_Smooth= +A_ToolOption_Snap= +A_ToolOption_Type= +A_ToolOption_Type%3AFreehand= +A_ToolOption_Type%3ANormal= +A_ToolOption_Type%3APolyline= +A_ToolOption_TypeFont= +A_ToolOption_TypeSize= +A_ToolOption_TypeStyle= +MI_ACheck= +MI_About= +MI_ActivateAllColumns= +MI_ActivateSelectedColumns= +MI_ActivateThisColumnOnly= +MI_AddFrames= +MI_AddToBatchCleanupList= +MI_AddToBatchRenderList= +MI_AdjustLevels= +MI_AdjustThickness= +MI_Antialias= +MI_ApplyMatchLines= +MI_AutoFillToggle= +MI_Autocenter= +MI_Autorenumber= +MI_BCheck= +MI_Binarize= +MI_BlendColors= +MI_BlueChannel= +MI_BlueChannelGreyscale= +MI_BrightnessAndContrast= +MI_CameraSettings= +MI_CameraStage= +MI_CameraTest= +MI_CanvasSize= +MI_Cleanup= +MI_CleanupPreview= +MI_CleanupSettings= +MI_ClearRecentImage= +MI_ClearRecentLevel= +MI_ClearRecentScene= +MI_CloneChild= +MI_CloneLevel= +MI_ClonePreview= +MI_CloseChild= +MI_Collapse=Alt+0 +MI_CollectAssets= +MI_CompareToSnapshot= +MI_ConvertFileWithInput= +MI_ConvertFiles= +MI_ConvertToVectors= +MI_DeactivateAllColumns= +MI_DeactivateSelectedColumns= +MI_DeactivateUpperColumns= +MI_DecreaseStep=- +MI_DefineScanner= +MI_DeleteInk= +MI_DeleteMatchLines= +MI_DisableAllColumns= +MI_DisableSelectedColumns=Alt+H +MI_DockingCheck= +MI_Dup= +MI_DuplicateFile= +MI_Each2= +MI_Each3= +MI_Each4= +MI_EditLevel= +MI_EditShift= +MI_EnableAllColumns=Alt+Shift+H +MI_EnableSelectedColumns= +MI_EnableThisColumnOnly= +MI_EnterGroup=Ctrl+Return +MI_EraseUnusedStyles= +MI_ExitGroup=Backspace +MI_ExplodeChild=Ctrl+B +MI_ExportLevel= +MI_ExportScenes= +MI_ExposeResource= +MI_FieldGuide="Ctrl+'" +MI_FileInfo= +MI_FillAreas= +MI_FillLines= +MI_FirstFrame="Shift+<" +MI_FoldColumns= +MI_FrezzePreview= +MI_GCheck= +MI_GetColorFromStudioPalette= +MI_GreenChannel= +MI_GreenChannelGreyscale= +MI_Histogram= +MI_ICheck= +MI_IOnly= +MI_ImportMagpieFile= +MI_ImportScenes= +MI_IncreaseStep="+" +MI_Increment= +MI_Ink1Check= +MI_InsertGlobalKeyframe= +MI_InsertSceneFrame= +MI_InvertKeyframeSelection= +MI_InvertSelection= +MI_LastFrame="Shift+>" +MI_LevelSettings= +MI_LinesFade= +MI_Link= +MI_LoadColorModel= +MI_LoadFolder= +MI_LoadLevel= +MI_LoadSubSceneFile= +MI_LockAllColumns=Ctrl+Shift+L +MI_LockSelectedColumns=Ctrl+Alt+L +MI_LockThisColumnOnly= +MI_Loop= +MI_MatteChannel= +MI_MergeCmapped= +MI_MergeColumns= +MI_MergeFrames= +MI_NewLevel= +MI_NewOutputFx= +MI_NewProject= +MI_NextStep= +MI_NoShift= +MI_OnionSkin=Alt+O +MI_OpenBatchServers= +MI_OpenChild= +MI_OpenCleanupSettings= +MI_OpenColorModel= +MI_OpenComboViewer= +MI_OpenFileBrowser= +MI_OpenFileBrowser2= +MI_OpenFileViewer= +MI_OpenFilmStrip= +MI_OpenFunctionEditor=Alt+F +MI_OpenHistoryPanel= +MI_OpenLevelView= +MI_OpenPalette= +MI_OpenPltGizmo= +MI_OpenRecentScene= +MI_OpenSchematic= +MI_OpenScriptConsole= +MI_OpenStudioPalette= +MI_OpenStyleControl= +MI_OpenTMessage= +MI_OpenTasks= +MI_OpenToolOptionBar= +MI_OpenToolbar= +MI_OpenXshView= +MI_OutputSettings= +MI_OverwritePalette= +MI_PCheck= +MI_PasteColors= +MI_PasteInto= +MI_PasteNames= +MI_PasteValues= +MI_Pause= +MI_PencilTest= +MI_PickStyleAreas= +MI_PickStyleLines= +MI_Play=Ctrl+Return +MI_Preferences=Ctrl+U +MI_PrevStep= +MI_PreviewFx= +MI_PreviewSettings= +MI_Print= +MI_PrintXsheet= +MI_ProjectSettings= +MI_Random= +MI_RasterizePli= +MI_RedChannel= +MI_RedChannelGreyscale= +MI_Reframe1= +MI_Reframe2= +MI_Reframe3= +MI_Reframe4= +MI_RefreshTree= +MI_RegenerateFramePr= +MI_RegeneratePreview= +MI_ReloadStyle= +MI_RemoveEndpoints= +MI_RemoveGlobalKeyframe= +MI_RemoveLevel= +MI_RemoveSceneFrame= +MI_RemoveUnused= +MI_Render= +MI_Renumber= +MI_ReplaceLevel= +MI_ReplaceParentDirectory= +MI_Resequence= +MI_ResetInterpolation= +MI_ResetRoomLayout= +MI_ResetScanCropbox= +MI_ResetShift= +MI_ResetStep= +MI_Reverse= +MI_RevertScene= +MI_RevertToCleanedUp= +MI_RevertToLastSaved= +MI_Rolldown= +MI_Rollup= +MI_RunScript= +MI_SafeArea= +MI_SaveAll=Ctrl+S +MI_SaveDefaultSettings= +MI_SaveLevel= +MI_SaveLevelAs= +MI_SavePaletteAs= +MI_SavePreset= +MI_SavePreviewedFrames= +MI_SaveSubxsheetAs= +MI_Scan=Ctrl+Shift+S +MI_ScanSettings= +MI_SceneSettings= +MI_SelectAllKeyframes= +MI_SelectAllKeyframesNotAfter= +MI_SelectAllKeyframesNotBefore= +MI_SelectColumnKeyframes= +MI_SelectFollowingKeysInColumn= +MI_SelectFollowingKeysInRow= +MI_SelectPreviousKeysInColumn= +MI_SelectPreviousKeysInRow= +MI_SelectRowKeyframes= +MI_SetAcceleration= +MI_SetConstantSpeed= +MI_SetDeceleration= +MI_SetKeyframes=F6 +MI_SetScanCropbox= +MI_ShiftTrace= +MI_ShortcutPopup= +MI_ShowFolderContents= +MI_Step2= +MI_Step3= +MI_Step4= +MI_SwapEnabledColumns= +MI_Swing= +MI_TCheck= +MI_TimeStretch= +MI_ToggleColumnLocks= +MI_ToggleColumnsActivation= +MI_ToggleEditInPlace= +MI_Tracking= +MI_Ungroup=Ctrl+Shift+G +MI_UnlockAllColumns=Ctrl+Alt+Shift+K +MI_UnlockSelectedColumns=Ctrl+Shift+K +MI_ViewBBox= +MI_ViewCamera= +MI_ViewColorcard= +MI_ViewFile= +MI_ViewGuide="Ctrl+'" +MI_ViewRuler= +MI_ViewTable= +T_Bender= +T_Cutter=Alt+T +T_Finger= +T_Hook= +T_Iron= +T_Magnet= +T_PaintBrush= +T_Plastic= +T_Pump= +T_RGBPicker= +T_Ruler= +T_ShowHideFullScreen= +T_Skeleton= +T_Tracker= +T_ZoomFit= +MI_OpenRecentLevel= diff --git a/stuff/profiles/layouts/shortcuts/otretas.ini b/stuff/profiles/layouts/shortcuts/otretas.ini new file mode 100644 index 0000000..7a1b172 --- /dev/null +++ b/stuff/profiles/layouts/shortcuts/otretas.ini @@ -0,0 +1,366 @@ +[shortcuts] +MI_LoadRecentImage= +A_ToolOption_FrameRange= +A_ToolOption_SegmentInk= +A_ToolOption_Selective= +A_ToolOption_Type%3ARectangular= +MI_BringForward=Ctrl+Up +MI_BringToFront=Ctrl+Shift+Up +MI_Clear=Delete +MI_Copy=Ctrl+C +MI_Cut=Ctrl+X +MI_DrawingSubBackward=[ +MI_DrawingSubForward=] +MI_DrawingSubGroupBackward=Ctrl+[ +MI_DrawingSubGroupForward=Ctrl+] +MI_Duplicate= +MI_FullScreenWindow=Ctrl+F +MI_FxParamEditor= +MI_Group=Ctrl+G +MI_Insert=Ins +MI_InsertFx= +MI_LoadScene=Ctrl+O +MI_MaximizePanel= +MI_NewScene=Ctrl+N +MI_NextDrawing=G +MI_NextFrame=. +MI_OpacityCheck= +MI_Paste=Ctrl+V +MI_PrevDrawing=F +MI_PrevFrame="," +MI_Preview=Alt+P +MI_Quit=Ctrl+Q +MI_Redo=Ctrl+Y +MI_SaveScene=Ctrl+Shift+S +MI_SaveSceneAs=Ctrl+Alt+Shift+S +MI_SelectAll=Shift+A +MI_SendBack=Ctrl+Shift+Down +MI_SendBackward=Ctrl+Down +MI_Undo=Ctrl+Z +MI_ZeroThick=D +T_ActualPixelSize= +T_Brush=Alt+B +T_ControlPointEditor=Alt+A +T_Edit=Alt+Q +T_Eraser=Alt+E +T_Fill=Alt+K +T_Geometric=Atl+R +T_Hand= +T_Pinch= +T_Rotate= +T_Selection=Alt+V +T_StylePicker=Alt+I +T_Tape=Alt+C +T_Type= +T_Zoom=Alt+Z +T_ZoomReset=Shift+Z +T_Zoomin=Ctrl+= +T_Zoomout=Ctrl+- +A_DecreaseBrushHardness= +A_DecreaseMaxBrushThickness= +A_DecreaseMinBrushThickness= +A_FxSchematicToggle= +A_IncreaseBrushHardness= +A_IncreaseMaxBrushThickness= +A_IncreaseMinBrushThickness= +A_ToolOption_AutoGroup= +A_ToolOption_AutoSelect%3AColumn= +A_ToolOption_AutoSelect%3ANone= +A_ToolOption_AutoSelect%3APegbar= +A_ToolOption_AutoSelectDrawing= +A_ToolOption_Autofill= +A_ToolOption_BreakSharpAngles= +A_ToolOption_BrushPreset= +A_ToolOption_EditToolActiveAxis= +A_ToolOption_EditToolActiveAxis%3ACenter= +A_ToolOption_EditToolActiveAxis%3APosition= +A_ToolOption_EditToolActiveAxis%3ARotation= +A_ToolOption_EditToolActiveAxis%3AScale= +A_ToolOption_EditToolActiveAxis%3AShear= +A_ToolOption_GeometricEdge= +A_ToolOption_GeometricShape= +A_ToolOption_GlobalKey= +A_ToolOption_IK=Alt+8 +A_ToolOption_Invert= +A_ToolOption_JoinVectors= +A_ToolOption_Manual= +A_ToolOption_Meshify= +A_ToolOption_Mode= +A_ToolOption_Mode%3AAreas= +A_ToolOption_Mode%3ALines= +A_ToolOption_Mode%3ALines%20%26%20Areas= +A_ToolOption_OnionSkin= +A_ToolOption_Orientation= +A_ToolOption_PencilMode= +A_ToolOption_PickScreen= +A_ToolOption_PreserveThickness= +A_ToolOption_PressureSensitivity= +A_ToolOption_ShowOnlyActiveSkeleton= +A_ToolOption_SkeletonMode%3AAnimate= +A_ToolOption_SkeletonMode%3ABuild%20Skeleton= +A_ToolOption_SkeletonMode%3AInverse%20Kinematics= +A_ToolOption_Smooth= +A_ToolOption_Snap= +A_ToolOption_Type= +A_ToolOption_Type%3AFreehand= +A_ToolOption_Type%3ANormal= +A_ToolOption_Type%3APolyline= +A_ToolOption_TypeFont= +A_ToolOption_TypeSize= +A_ToolOption_TypeStyle= +MI_ACheck= +MI_About= +MI_ActivateAllColumns= +MI_ActivateSelectedColumns= +MI_ActivateThisColumnOnly= +MI_AddFrames=Ctrl+H +MI_AddToBatchCleanupList= +MI_AddToBatchRenderList= +MI_AdjustLevels= +MI_AdjustThickness= +MI_Antialias= +MI_ApplyMatchLines= +MI_AutoFillToggle= +MI_Autocenter= +MI_Autorenumber= +MI_BCheck= +MI_Binarize= +MI_BlendColors= +MI_BlueChannel= +MI_BlueChannelGreyscale= +MI_BrightnessAndContrast= +MI_CameraSettings= +MI_CameraStage= +MI_CameraTest= +MI_CanvasSize= +MI_Cleanup= +MI_CleanupPreview= +MI_CleanupSettings= +MI_ClearRecentImage= +MI_ClearRecentLevel= +MI_ClearRecentScene= +MI_CloneChild= +MI_CloneLevel= +MI_ClonePreview= +MI_CloseChild= +MI_Collapse= +MI_CollectAssets= +MI_CompareToSnapshot= +MI_ConvertFileWithInput= +MI_ConvertFiles= +MI_ConvertToVectors= +MI_DeactivateAllColumns= +MI_DeactivateSelectedColumns=Alt+H +MI_DeactivateUpperColumns= +MI_DecreaseStep= +MI_DefineScanner= +MI_DeleteInk= +MI_DeleteMatchLines= +MI_DisableAllColumns= +MI_DisableSelectedColumns= +MI_DockingCheck= +MI_Dup= +MI_DuplicateFile= +MI_Each2= +MI_Each3= +MI_Each4= +MI_EditLevel= +MI_EditShift= +MI_EnableAllColumns=Alt+Shift+H +MI_EnableSelectedColumns= +MI_EnableThisColumnOnly= +MI_EnterGroup=Ctrl+Return +MI_EraseUnusedStyles= +MI_ExitGroup=Backspace +MI_ExplodeChild=Ctrl+B +MI_ExportLevel= +MI_ExportScenes= +MI_ExposeResource= +MI_FieldGuide="Ctrl+'" +MI_FileInfo= +MI_FillAreas= +MI_FillLines= +MI_FirstFrame=Home +MI_FoldColumns= +MI_FrezzePreview= +MI_GCheck= +MI_GetColorFromStudioPalette= +MI_GreenChannel= +MI_GreenChannelGreyscale= +MI_Histogram= +MI_ICheck= +MI_IOnly= +MI_ImportMagpieFile= +MI_ImportScenes= +MI_IncreaseStep="+" +MI_Increment= +MI_Ink1Check= +MI_InsertGlobalKeyframe= +MI_InsertSceneFrame= +MI_InvertKeyframeSelection= +MI_InvertSelection= +MI_LastFrame=End +MI_LevelSettings= +MI_LinesFade= +MI_Link= +MI_LoadColorModel= +MI_LoadFolder= +MI_LoadLevel= +MI_LoadSubSceneFile= +MI_LockAllColumns= +MI_LockSelectedColumns= +MI_LockThisColumnOnly= +MI_Loop= +MI_MatteChannel= +MI_MergeCmapped= +MI_MergeColumns= +MI_MergeFrames= +MI_NewLevel= +MI_NewOutputFx= +MI_NewProject= +MI_NextStep= +MI_NoShift= +MI_OnionSkin=Ctrl+Alt+O +MI_OpenBatchServers= +MI_OpenChild= +MI_OpenCleanupSettings= +MI_OpenColorModel= +MI_OpenComboViewer= +MI_OpenFileBrowser= +MI_OpenFileBrowser2= +MI_OpenFileViewer= +MI_OpenFilmStrip= +MI_OpenFunctionEditor=Alt+F +MI_OpenHistoryPanel= +MI_OpenLevelView= +MI_OpenPalette= +MI_OpenPltGizmo= +MI_OpenRecentScene= +MI_OpenSchematic= +MI_OpenScriptConsole= +MI_OpenStudioPalette= +MI_OpenStyleControl= +MI_OpenTMessage= +MI_OpenTasks= +MI_OpenToolOptionBar= +MI_OpenToolbar= +MI_OpenXshView= +MI_OutputSettings= +MI_OverwritePalette= +MI_PCheck= +MI_PasteColors= +MI_PasteInto= +MI_PasteNames= +MI_PasteValues= +MI_Pause= +MI_PencilTest= +MI_PickStyleAreas= +MI_PickStyleLines= +MI_Play=Return +MI_Preferences=Ctrl+U +MI_PrevStep= +MI_PreviewFx= +MI_PreviewSettings= +MI_Print= +MI_PrintXsheet= +MI_ProjectSettings= +MI_Random= +MI_RasterizePli= +MI_RedChannel= +MI_RedChannelGreyscale= +MI_Reframe1= +MI_Reframe2= +MI_Reframe3= +MI_Reframe4= +MI_RefreshTree= +MI_RegenerateFramePr= +MI_RegeneratePreview= +MI_ReloadStyle= +MI_RemoveEndpoints= +MI_RemoveGlobalKeyframe= +MI_RemoveLevel= +MI_RemoveSceneFrame= +MI_RemoveUnused= +MI_Render=Ctrl+Alt+Shift+S +MI_Renumber= +MI_ReplaceLevel= +MI_ReplaceParentDirectory= +MI_Resequence= +MI_ResetInterpolation= +MI_ResetRoomLayout= +MI_ResetScanCropbox= +MI_ResetShift= +MI_ResetStep= +MI_Reverse= +MI_RevertScene= +MI_RevertToCleanedUp= +MI_RevertToLastSaved= +MI_Rolldown= +MI_Rollup= +MI_RunScript= +MI_SafeArea= +MI_SaveAll=Ctrl+S +MI_SaveDefaultSettings= +MI_SaveLevel= +MI_SaveLevelAs= +MI_SavePaletteAs= +MI_SavePreset= +MI_SavePreviewedFrames= +MI_SaveSubxsheetAs= +MI_Scan= +MI_ScanSettings= +MI_SceneSettings=Ctrl+F3 +MI_SelectAllKeyframes= +MI_SelectAllKeyframesNotAfter= +MI_SelectAllKeyframesNotBefore= +MI_SelectColumnKeyframes= +MI_SelectFollowingKeysInColumn= +MI_SelectFollowingKeysInRow= +MI_SelectPreviousKeysInColumn= +MI_SelectPreviousKeysInRow= +MI_SelectRowKeyframes= +MI_SetAcceleration= +MI_SetConstantSpeed= +MI_SetDeceleration= +MI_SetKeyframes=Ctrl+F6 +MI_SetScanCropbox= +MI_ShiftTrace= +MI_ShortcutPopup= +MI_ShowFolderContents= +MI_Step2= +MI_Step3= +MI_Step4= +MI_SwapEnabledColumns= +MI_Swing= +MI_TCheck= +MI_TimeStretch= +MI_ToggleColumnLocks= +MI_ToggleColumnsActivation= +MI_ToggleEditInPlace= +MI_Tracking= +MI_Ungroup=Ctrl+Shift+G +MI_UnlockAllColumns=Ctrl+Alt+Shift+L +MI_UnlockSelectedColumns=Ctrl+Shift+K +MI_ViewBBox= +MI_ViewCamera= +MI_ViewColorcard= +MI_ViewFile= +MI_ViewGuide= +MI_ViewRuler=Ctrl+Alt+Shift+R +MI_ViewTable= +T_Bender= +T_Cutter=Alt+T +T_Finger= +T_Hook= +T_Iron= +T_Magnet= +T_PaintBrush= +T_Plastic= +T_Pump= +T_RGBPicker= +T_Ruler= +T_ShowHideFullScreen=F4 +T_Skeleton= +T_Tracker= +T_ZoomFit= +MI_OpenRecentLevel= diff --git a/thirdparty/libpng-1.6.21/lib/libpng16_2015.lib b/thirdparty/libpng-1.6.21/lib/libpng16_2015.lib index ca4827f..1e7bbcf 100644 --- a/thirdparty/libpng-1.6.21/lib/libpng16_2015.lib +++ b/thirdparty/libpng-1.6.21/lib/libpng16_2015.lib @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1d6be973caafd36b6dcf9b8fcb2d030ad2e0c3c523527fad7bbf7da9f9ba5b6e -size 56118 +oid sha256:e005a1c28ab5a1f8ed57793a79c883f0b44cd5d2b25152544e3dca5fbdd616bc +size 374568 diff --git a/thirdparty/libpng-1.6.21/lib/libpng16_2015d.lib b/thirdparty/libpng-1.6.21/lib/libpng16_2015d.lib index a94d492..1859771 100644 --- a/thirdparty/libpng-1.6.21/lib/libpng16_2015d.lib +++ b/thirdparty/libpng-1.6.21/lib/libpng16_2015d.lib @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:be7784d0f86cf87b9dd965a32707e1a999b059d57fbeddb4066a033200e0fbc9 -size 56118 +oid sha256:f61acffbae2925d60a61bd11b6d5b09502843c89c8b3f20b89f240e050a1e916 +size 858596 diff --git a/thirdparty/tiff-4.0.3/libtiff/Makefile.am b/thirdparty/tiff-4.0.3/libtiff/Makefile.am index 82fa31d..0a47dab 100644 --- a/thirdparty/tiff-4.0.3/libtiff/Makefile.am +++ b/thirdparty/tiff-4.0.3/libtiff/Makefile.am @@ -74,6 +74,7 @@ libtiff_la_SOURCES = \ tif_fax3sm.c \ tif_flush.c \ tif_getimage.c \ + tif_getimage_64.c \ tif_jbig.c \ tif_jpeg.c \ tif_jpeg_12.c \ diff --git a/toonz/sources/CMakeLists.txt b/toonz/sources/CMakeLists.txt index af8ea55..b06a20d 100644 --- a/toonz/sources/CMakeLists.txt +++ b/toonz/sources/CMakeLists.txt @@ -92,7 +92,7 @@ elseif(UNIX) else() set(PLATFORM 32) endif() - if (CMAKE_SYSTEM_NAME MATCHES "Linux") + if(CMAKE_SYSTEM_NAME MATCHES "Linux") add_definitions(-DLINUX) else() message(WARNING "Support for generic Unix (Not Apple or Linux) isn't yet working!") diff --git a/toonz/sources/common/tsystem/tfilepath.cpp b/toonz/sources/common/tsystem/tfilepath.cpp index 215a042..d16a1a3 100644 --- a/toonz/sources/common/tsystem/tfilepath.cpp +++ b/toonz/sources/common/tsystem/tfilepath.cpp @@ -480,6 +480,7 @@ bool TFilePath::isRoot() const { // ritorna ""(niente tipo, niente punto), "." (file con tipo) o ".." (file con // tipo e frame) std::string TFilePath::getDots() const { + if (isFfmpegType()) return "."; int i = getLastSlash(m_path); std::wstring str = m_path.substr(i + 1); // potrei anche avere a.b.c.d dove d e' l'estensione @@ -561,7 +562,7 @@ std::string TFilePath::getLevelName() const { std::wstring TFilePath::getLevelNameW() const { int i = getLastSlash(m_path); // cerco l'ultimo slash std::wstring str = m_path.substr(i + 1); // str e' m_path senza directory - + if (isFfmpegType()) return str; int j = str.rfind(L"."); // str[j..] = ".type" if (j == (int)std::wstring::npos) return str; // no frame; no type i = str.substr(0, j).rfind(L'.'); @@ -597,6 +598,7 @@ TFilePath TFilePath::getParentDir() const // noSlash! //----------------------------------------------------------------------------- bool TFilePath::isLevelName() const { + if (isFfmpegType()) return false; try { return getFrame() == TFrameId(TFrameId::EMPTY_FRAME); } @@ -638,6 +640,15 @@ TFrameId TFilePath::getFrame() const { //----------------------------------------------------------------------------- +bool TFilePath::isFfmpegType() const { + QString type = QString::fromStdString(getType()).toLower(); + if (type == "gif" || type == "mp4" || type == "webm") + return true; + else + return false; +} + +//----------------------------------------------------------------------------- TFilePath TFilePath::withType(const std::string &type) const { assert(type.length() < 2 || type.substr(0, 2) != ".."); int i = getLastSlash(m_path); // cerco l'ultimo slash diff --git a/toonz/sources/common/tvrender/tcolorstyles.cpp b/toonz/sources/common/tvrender/tcolorstyles.cpp index 3b18ce5..a67f8f1 100644 --- a/toonz/sources/common/tvrender/tcolorstyles.cpp +++ b/toonz/sources/common/tvrender/tcolorstyles.cpp @@ -50,7 +50,8 @@ TColorStyle::TColorStyle() , m_enabled(true) , m_icon(0) , m_validIcon(false) - , m_isEditedFromOriginal(false) {} + , m_isEditedFromOriginal(false) + , m_pickedPosition() {} //------------------------------------------------------------------- @@ -66,7 +67,8 @@ TColorStyle::TColorStyle(const TColorStyle &other) , m_flags(other.m_flags) , m_enabled(other.m_enabled) , m_validIcon(false) - , m_isEditedFromOriginal(other.m_isEditedFromOriginal) {} + , m_isEditedFromOriginal(other.m_isEditedFromOriginal) + , m_pickedPosition(other.m_pickedPosition) {} //------------------------------------------------------------------- @@ -79,6 +81,7 @@ TColorStyle &TColorStyle::operator=(const TColorStyle &other) { m_enabled = other.m_enabled; m_validIcon = false; m_isEditedFromOriginal = other.m_isEditedFromOriginal; + m_pickedPosition = other.m_pickedPosition; return *this; } @@ -100,6 +103,7 @@ bool TColorStyle::operator==(const TColorStyle &cs) const { if (m_originalName != cs.getOriginalName()) return false; if (m_globalName != cs.getGlobalName()) return false; if (m_isEditedFromOriginal != cs.getIsEditedFlag()) return false; + if (m_pickedPosition != cs.getPickedPosition()) return false; for (int p = 0; p < colorParamCount; ++p) if (getColorParamValue(p) != cs.getColorParamValue(p)) return false; diff --git a/toonz/sources/common/tvrender/tpalette.cpp b/toonz/sources/common/tvrender/tpalette.cpp index e301908..ad236ef 100644 --- a/toonz/sources/common/tvrender/tpalette.cpp +++ b/toonz/sources/common/tvrender/tpalette.cpp @@ -15,6 +15,7 @@ #include "tpalette.h" #include +#include PERSIST_IDENTIFIER(TPalette, "palette") @@ -30,6 +31,21 @@ namespace { const int maxStyleIndex = 32765; +const std::string pointToString(const TPoint &point) { + return std::to_string(point.x) + "," + std::to_string(point.y); +} + +// splitting string with ',' +const TPoint stringToPoint(const std::string &string) { + std::string buffer; + std::stringstream ss(string); + std::getline(ss, buffer, ','); // getting the first part of string + int x = std::stoi(buffer); + std::getline(ss, buffer); // getting the second part of string + int y = std::stoi(buffer); + return TPoint(x, y); +} + } // namespace //=================================================================== @@ -168,7 +184,8 @@ TPalette::TPalette() , m_dirtyFlag(false) , m_mutex(QMutex::Recursive) , m_isLocked(false) - , m_askOverwriteFlag(false) { + , m_askOverwriteFlag(false) + , m_shortcutScopeIndex(0) { QString tempName(QObject::tr("colors")); std::wstring pageName = tempName.toStdWString(); Page *page = addPage(pageName); @@ -563,10 +580,17 @@ void TPalette::saveData(TOStream &os) { os.openChild("styles"); { for (int i = 0; i < getStyleCount(); ++i) { - os.openChild("style"); + TColorStyleP style = m_styles[i].second; + if (style->getPickedPosition() == TPoint()) + os.openChild("style"); + else { + std::map attr; + attr["pickedpos"] = pointToString(style->getPickedPosition()); + os.openChild("style", attr); + } { StyleWriter w(os, i); - m_styles[i].second->save(w); + style->save(w); } os.closeChild(); } @@ -680,6 +704,10 @@ void TPalette::loadData(TIStream &is) { StyleReader r(is, version); TColorStyle *cs = TColorStyle::load(r); + std::string pickedPosStr; + if (is.getTagParam("pickedpos", pickedPosStr)) + cs->setPickedPosition(stringToPoint(pickedPosStr)); + addStyle(cs); } @@ -851,9 +879,10 @@ void TPalette::assign(const TPalette *src, bool isFromStudioPalette) { j->second = j->second->clone(); m_styleAnimationTable[cit->first] = cit->second; } - m_globalName = src->getGlobalName(); - m_shortcuts = src->m_shortcuts; - m_currentFrame = src->m_currentFrame; + m_globalName = src->getGlobalName(); + m_shortcuts = src->m_shortcuts; + m_currentFrame = src->m_currentFrame; + m_shortcutScopeIndex = src->m_shortcutScopeIndex; // setDirtyFlag(true); } @@ -1053,22 +1082,26 @@ void TPalette::clearKeyframe(int styleId, int frame) { //------------------------------------------------------------------- int TPalette::getShortcutValue(int key) const { - assert('0' <= key && key <= '9'); - std::map::const_iterator it; - it = m_shortcuts.find(key); - if (it == m_shortcuts.end()) return -1; - int styleId = it->second; - return 0 <= styleId && styleId < getStyleCount() ? styleId : -1; + assert(Qt::Key_0 <= key && key <= Qt::Key_9); + + int shortcutIndex = (key == Qt::Key_0) ? 9 : key - Qt::Key_1; + int indexInPage = m_shortcutScopeIndex * 10 + shortcutIndex; + // shortcut is available only in the first page + return getPage(0)->getStyleId(indexInPage); } //------------------------------------------------------------------- int TPalette::getStyleShortcut(int styleId) const { assert(0 <= styleId && styleId < getStyleCount()); - std::map::const_iterator it; - for (it = m_shortcuts.begin(); it != m_shortcuts.end(); ++it) - if (it->second == styleId) return it->first; - return -1; + + Page *page = getStylePage(styleId); + // shortcut is available only in the first page + if (!page || page->getIndex() != 0) return -1; + int indexInPage = page->search(styleId); + int shortcutIndex = indexInPage - m_shortcutScopeIndex * 10; + if (shortcutIndex < 0 || shortcutIndex > 9) return -1; + return (shortcutIndex == 9) ? Qt::Key_0 : Qt::Key_1 + shortcutIndex; } //------------------------------------------------------------------- @@ -1088,3 +1121,31 @@ void TPalette::setShortcutValue(int key, int styleId) { m_shortcuts[key] = styleId; } } + +//------------------------------------------------------------------- +// Returns true if there is at least one style with picked pos value +//------------------------------------------------------------------- + +bool TPalette::hasPickedPosStyle() { + for (int i = 0; i < getStyleCount(); ++i) { + TColorStyleP style = m_styles[i].second; + if (style->getPickedPosition() != TPoint()) return true; + } + return false; +} + +//------------------------------------------------------------------- + +void TPalette::nextShortcutScope(bool invert) { + if (invert) { + if (m_shortcutScopeIndex > 0) + m_shortcutScopeIndex -= 1; + else + m_shortcutScopeIndex = getPage(0)->getStyleCount() / 10; + } else { + if ((m_shortcutScopeIndex + 1) * 10 < getPage(0)->getStyleCount()) + m_shortcutScopeIndex += 1; + else + m_shortcutScopeIndex = 0; + } +} diff --git a/toonz/sources/image/ffmpeg/tiio_ffmpeg.cpp b/toonz/sources/image/ffmpeg/tiio_ffmpeg.cpp index 3f35abe..9dd86a1 100644 --- a/toonz/sources/image/ffmpeg/tiio_ffmpeg.cpp +++ b/toonz/sources/image/ffmpeg/tiio_ffmpeg.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include "toonz/preferences.h" #include "toonz/toonzfolders.h" @@ -98,8 +99,9 @@ void Ffmpeg::setFrameRate(double fps) { m_frameRate = fps; } void Ffmpeg::setPath(TFilePath path) { m_path = path; } void Ffmpeg::createIntermediateImage(const TImageP &img, int frameIndex) { + m_frameCount++; QString tempPath = m_path.getQString() + "tempOut" + - QString::number(frameIndex) + "." + m_intermediateFormat; + QString::number(m_frameCount) + "." + m_intermediateFormat; std::string saveStatus = ""; TRasterImageP tempImage(img); TRasterImage *image = (TRasterImage *)tempImage->cloneImage(); @@ -127,7 +129,7 @@ void Ffmpeg::createIntermediateImage(const TImageP &img, int frameIndex) { qi->save(tempPath, format, -1); free(buffer); m_cleanUpList.push_back(tempPath); - m_frameCount++; + delete qi; delete image; } @@ -217,9 +219,9 @@ void Ffmpeg::saveSoundTrack(TSoundTrack *st) { bool Ffmpeg::checkFilesExist() { QString ffmpegCachePath = getFfmpegCache().getQString(); QString tempPath = ffmpegCachePath + "//" + - QString::fromStdString(m_path.getName()) + - QString::fromStdString(m_path.getType()) + "In0001." + - m_intermediateFormat; + m_path.getQString().remove(QRegExp(QString::fromUtf8( + "[-`~!@#$%^&*()_�+=|:;<>��,.?/{}\'\"\\[\\]\\\\]"))) + + "In0001." + m_intermediateFormat; if (TSystem::doesExistFileOrLevel(TFilePath(tempPath))) { return true; } else @@ -229,8 +231,9 @@ bool Ffmpeg::checkFilesExist() { ffmpegFileInfo Ffmpeg::getInfo() { QString ffmpegCachePath = getFfmpegCache().getQString(); QString tempPath = ffmpegCachePath + "//" + - QString::fromStdString(m_path.getName()) + - QString::fromStdString(m_path.getType()) + ".txt"; + m_path.getQString().remove(QRegExp(QString::fromUtf8( + "[-`~!@#$%^&*()_�+=|:;<>��,.?/{}\'\"\\[\\]\\\\]"))) + + ".txt"; if (QFile::exists(tempPath)) { QFile infoText(tempPath); infoText.open(QIODevice::ReadOnly); @@ -264,8 +267,8 @@ ffmpegFileInfo Ffmpeg::getInfo() { TRasterImageP Ffmpeg::getImage(int frameIndex) { QString ffmpegCachePath = getFfmpegCache().getQString(); QString tempPath = ffmpegCachePath + "//" + - QString::fromStdString(m_path.getName()) + - QString::fromStdString(m_path.getType()); + m_path.getQString().remove(QRegExp(QString::fromUtf8( + "[-`~!@#$%^&*()_�+=|:;<>��,.?/{}\'\"\\[\\]\\\\]"))); std::string tmpPath = tempPath.toStdString(); // QString tempPath= m_path.getQString(); QString number = QString("%1").arg(frameIndex, 4, 10, QChar('0')); @@ -356,8 +359,8 @@ int Ffmpeg::getFrameCount() { void Ffmpeg::getFramesFromMovie(int frame) { QString ffmpegCachePath = getFfmpegCache().getQString(); QString tempPath = ffmpegCachePath + "//" + - QString::fromStdString(m_path.getName()) + - QString::fromStdString(m_path.getType()); + m_path.getQString().remove(QRegExp(QString::fromUtf8( + "[-`~!@#$%^&*()_�+=|:;<>��,.?/{}\'\"\\[\\]\\\\]"))); std::string tmpPath = tempPath.toStdString(); QString tempName = "In%04d." + m_intermediateFormat; tempName = tempPath + tempName; @@ -399,6 +402,26 @@ void Ffmpeg::getFramesFromMovie(int frame) { } } +int Ffmpeg::getGifFrameCount() { + int frame = 1; + QString ffmpegCachePath = getFfmpegCache().getQString(); + QString tempPath = ffmpegCachePath + "//" + + QString::fromStdString(m_path.getName()) + + QString::fromStdString(m_path.getType()); + std::string tmpPath = tempPath.toStdString(); + QString tempName = "In%04d." + m_intermediateFormat; + tempName = tempPath + tempName; + QString tempStart; + tempStart = "In0001." + m_intermediateFormat; + tempStart = tempPath + tempStart; + while (TSystem::doesExistFileOrLevel(TFilePath(tempStart))) { + frame++; + QString number = QString("%1").arg(frame, 4, 10, QChar('0')); + tempStart = tempPath + "In" + number + "." + m_intermediateFormat; + } + return frame - 1; +} + void Ffmpeg::addToCleanUp(QString path) { if (TSystem::doesExistFileOrLevel(TFilePath(path))) { m_cleanUpList.push_back(path); diff --git a/toonz/sources/image/ffmpeg/tiio_ffmpeg.h b/toonz/sources/image/ffmpeg/tiio_ffmpeg.h index 4b3fe4f..853110a 100644 --- a/toonz/sources/image/ffmpeg/tiio_ffmpeg.h +++ b/toonz/sources/image/ffmpeg/tiio_ffmpeg.h @@ -41,6 +41,7 @@ public: TFilePath getFfmpegCache(); ffmpegFileInfo getInfo(); void disablePrecompute(); + int getGifFrameCount(); private: QString m_intermediateFormat, m_ffmpegPath, m_audioPath, m_audioFormat; diff --git a/toonz/sources/image/ffmpeg/tiio_gif.cpp b/toonz/sources/image/ffmpeg/tiio_gif.cpp index 089461d..0676b91 100644 --- a/toonz/sources/image/ffmpeg/tiio_gif.cpp +++ b/toonz/sources/image/ffmpeg/tiio_gif.cpp @@ -3,6 +3,7 @@ #include "tiio_gif.h" #include "trasterimage.h" #include "timageinfo.h" +#include "toonz/stage.h" #include //=========================================================== @@ -151,8 +152,9 @@ class TImageReaderGif final : public TImageReader { public: int m_frameIndex; - TImageReaderGif(const TFilePath &path, int index, TLevelReaderGif *lra) - : TImageReader(path), m_lra(lra), m_frameIndex(index) { + TImageReaderGif(const TFilePath &path, int index, TLevelReaderGif *lra, + TImageInfo *info) + : TImageReader(path), m_lra(lra), m_frameIndex(index), m_info(info) { m_lra->addRef(); } ~TImageReaderGif() { m_lra->release(); } @@ -160,9 +162,11 @@ public: TImageP load() override { return m_lra->load(m_frameIndex); } TDimension getSize() const { return m_lra->getSize(); } TRect getBBox() const { return TRect(); } + const TImageInfo *getImageInfo() const override { return m_info; } private: TLevelReaderGif *m_lra; + TImageInfo *m_info; // not implemented TImageReaderGif(const TImageReaderGif &); @@ -190,7 +194,7 @@ TLevelReaderGif::TLevelReaderGif(const TFilePath &path) m_ly = m_size.ly; ffmpegReader->getFramesFromMovie(); - + m_frameCount = ffmpegReader->getGifFrameCount(); // set values m_info = new TImageInfo(); m_info->m_frameRate = fps; @@ -198,6 +202,8 @@ TLevelReaderGif::TLevelReaderGif(const TFilePath &path) m_info->m_ly = m_ly; m_info->m_bitsPerSample = 8; m_info->m_samplePerPixel = 4; + m_info->m_dpix = Stage::standardDpi; + m_info->m_dpiy = Stage::standardDpi; } //----------------------------------------------------------- @@ -220,9 +226,8 @@ TImageReaderP TLevelReaderGif::getFrameReader(TFrameId fid) { // if (IOError != 0) // throw TImageException(m_path, buildAVIExceptionString(IOError)); if (fid.getLetter() != 0) return TImageReaderP(0); - int index = fid.getNumber(); - - TImageReaderGif *irm = new TImageReaderGif(m_path, index, this); + int index = fid.getNumber(); + TImageReaderGif *irm = new TImageReaderGif(m_path, index, this, m_info); return TImageReaderP(irm); } diff --git a/toonz/sources/image/ffmpeg/tiio_mp4.cpp b/toonz/sources/image/ffmpeg/tiio_mp4.cpp index fb7d9a1..1e83e1a 100644 --- a/toonz/sources/image/ffmpeg/tiio_mp4.cpp +++ b/toonz/sources/image/ffmpeg/tiio_mp4.cpp @@ -4,6 +4,7 @@ #include "trasterimage.h" #include "timageinfo.h" #include "tsound.h" +#include "toonz/stage.h" #include //=========================================================== @@ -38,11 +39,16 @@ private: TLevelWriterMp4::TLevelWriterMp4(const TFilePath &path, TPropertyGroup *winfo) : TLevelWriter(path, winfo) { if (!m_properties) m_properties = new Tiio::Mp4WriterProperties(); - std::string scale = m_properties->getProperty("Scale")->getValueAsString(); - m_scale = QString::fromStdString(scale).toInt(); - std::string quality = - m_properties->getProperty("Quality")->getValueAsString(); - m_vidQuality = QString::fromStdString(quality).toInt(); + if (m_properties->getPropertyCount() == 0) { + m_scale = 100; + m_vidQuality = 100; + } else { + std::string scale = m_properties->getProperty("Scale")->getValueAsString(); + m_scale = QString::fromStdString(scale).toInt(); + std::string quality = + m_properties->getProperty("Quality")->getValueAsString(); + m_vidQuality = QString::fromStdString(quality).toInt(); + } ffmpegWriter = new Ffmpeg(); ffmpegWriter->setPath(m_path); if (TSystem::doesExistFileOrLevel(m_path)) TSystem::deleteFile(m_path); @@ -129,8 +135,9 @@ class TImageReaderMp4 final : public TImageReader { public: int m_frameIndex; - TImageReaderMp4(const TFilePath &path, int index, TLevelReaderMp4 *lra) - : TImageReader(path), m_lra(lra), m_frameIndex(index) { + TImageReaderMp4(const TFilePath &path, int index, TLevelReaderMp4 *lra, + TImageInfo *info) + : TImageReader(path), m_lra(lra), m_frameIndex(index), m_info(info) { m_lra->addRef(); } ~TImageReaderMp4() { m_lra->release(); } @@ -138,9 +145,11 @@ public: TImageP load() override { return m_lra->load(m_frameIndex); } TDimension getSize() const { return m_lra->getSize(); } TRect getBBox() const { return TRect(); } + const TImageInfo *getImageInfo() const override { return m_info; } private: TLevelReaderMp4 *m_lra; + TImageInfo *m_info; // not implemented TImageReaderMp4(const TImageReaderMp4 &); @@ -173,6 +182,8 @@ TLevelReaderMp4::TLevelReaderMp4(const TFilePath &path) : TLevelReader(path) { m_info->m_ly = m_ly; m_info->m_bitsPerSample = 8; m_info->m_samplePerPixel = 4; + m_info->m_dpix = Stage::standardDpi; + m_info->m_dpiy = Stage::standardDpi; } //----------------------------------------------------------- @@ -197,7 +208,7 @@ TImageReaderP TLevelReaderMp4::getFrameReader(TFrameId fid) { if (fid.getLetter() != 0) return TImageReaderP(0); int index = fid.getNumber(); - TImageReaderMp4 *irm = new TImageReaderMp4(m_path, index, this); + TImageReaderMp4 *irm = new TImageReaderMp4(m_path, index, this, m_info); return TImageReaderP(irm); } diff --git a/toonz/sources/image/ffmpeg/tiio_webm.cpp b/toonz/sources/image/ffmpeg/tiio_webm.cpp index 0d9e2b2..d780061 100644 --- a/toonz/sources/image/ffmpeg/tiio_webm.cpp +++ b/toonz/sources/image/ffmpeg/tiio_webm.cpp @@ -4,6 +4,7 @@ #include "trasterimage.h" #include "tsound.h" #include "timageinfo.h" +#include "toonz/stage.h" #include //=========================================================== @@ -133,8 +134,9 @@ class TImageReaderWebm final : public TImageReader { public: int m_frameIndex; - TImageReaderWebm(const TFilePath &path, int index, TLevelReaderWebm *lra) - : TImageReader(path), m_lra(lra), m_frameIndex(index) { + TImageReaderWebm(const TFilePath &path, int index, TLevelReaderWebm *lra, + TImageInfo *info) + : TImageReader(path), m_lra(lra), m_frameIndex(index), m_info(info) { m_lra->addRef(); } ~TImageReaderWebm() { m_lra->release(); } @@ -142,9 +144,11 @@ public: TImageP load() override { return m_lra->load(m_frameIndex); } TDimension getSize() const { return m_lra->getSize(); } TRect getBBox() const { return TRect(); } + const TImageInfo *getImageInfo() const override { return m_info; } private: TLevelReaderWebm *m_lra; + TImageInfo *m_info; // not implemented TImageReaderWebm(const TImageReaderWebm &); @@ -177,6 +181,8 @@ TLevelReaderWebm::TLevelReaderWebm(const TFilePath &path) : TLevelReader(path) { m_info->m_ly = m_ly; m_info->m_bitsPerSample = 8; m_info->m_samplePerPixel = 4; + m_info->m_dpix = Stage::standardDpi; + m_info->m_dpiy = Stage::standardDpi; } //----------------------------------------------------------- @@ -201,7 +207,7 @@ TImageReaderP TLevelReaderWebm::getFrameReader(TFrameId fid) { if (fid.getLetter() != 0) return TImageReaderP(0); int index = fid.getNumber(); - TImageReaderWebm *irm = new TImageReaderWebm(m_path, index, this); + TImageReaderWebm *irm = new TImageReaderWebm(m_path, index, this, m_info); return TImageReaderP(irm); } diff --git a/toonz/sources/include/tcolorstyles.h b/toonz/sources/include/tcolorstyles.h index 1b999e7..2aecdad 100644 --- a/toonz/sources/include/tcolorstyles.h +++ b/toonz/sources/include/tcolorstyles.h @@ -118,6 +118,9 @@ private: // This flag will be set when the //! style is edited from the original one. + TPoint m_pickedPosition; // picked position from color model by using style + // picker tool with "organize palette" option. + protected: TRaster32P m_icon; //!< Icon shown on TPalette viewers. bool m_validIcon; //!< Icon's validity status. @@ -212,6 +215,9 @@ The \a global name contains information about palette id. m_flags = flags; } //!< Returns color attributes. + void setPickedPosition(const TPoint &pos) { m_pickedPosition = pos; } + TPoint getPickedPosition() const { return m_pickedPosition; } + // Color-related functions /*! \detail diff --git a/toonz/sources/include/tfilepath.h b/toonz/sources/include/tfilepath.h index ee04a45..0d58b5a 100644 --- a/toonz/sources/include/tfilepath.h +++ b/toonz/sources/include/tfilepath.h @@ -177,7 +177,7 @@ If the path is ":" a slash will be added*/ TFilePath getParentDir() const; // noSlash!; TFrameId getFrame() const; - + bool isFfmpegType() const; bool isLevelName() const; //{return getFrame() == TFrameId(TFrameId::EMPTY_FRAME);}; bool isAbsolute() const; diff --git a/toonz/sources/include/tools/cursors.h b/toonz/sources/include/tools/cursors.h index a912ffa..16eec82 100644 --- a/toonz/sources/include/tools/cursors.h +++ b/toonz/sources/include/tools/cursors.h @@ -66,6 +66,8 @@ enum { PickerCursorWhite, PickerCursorWhiteLine, PickerCursorWhiteArea, + PickerCursorOrganize, + PickerCursorWhiteOrganize, PickerRGB, PickerRGBWhite, diff --git a/toonz/sources/include/tools/tooloptions.h b/toonz/sources/include/tools/tooloptions.h index b06a86d..abded96 100644 --- a/toonz/sources/include/tools/tooloptions.h +++ b/toonz/sources/include/tools/tooloptions.h @@ -647,7 +647,9 @@ public slots: void onToolChanged(); void onStageObjectChange(); - // signals: +signals: + // used in ComboViewer to handle Tab focus + void newPanelCreated(); // void toolOptionChange(); }; diff --git a/toonz/sources/include/toonz/Naa2TlvConverter.h b/toonz/sources/include/toonz/Naa2TlvConverter.h index efe5765..e15fd38 100644 --- a/toonz/sources/include/toonz/Naa2TlvConverter.h +++ b/toonz/sources/include/toonz/Naa2TlvConverter.h @@ -146,7 +146,8 @@ public: return -1; } - TToonzImageP makeTlv(bool transparentSyntheticInks); + TToonzImageP makeTlv(bool transparentSyntheticInks, + bool removeUnusedStyles = false); TVectorImageP vectorize(const TToonzImageP &ti); TVectorImageP vectorize(const TRaster32P &ras); diff --git a/toonz/sources/include/toonz/palettecmd.h b/toonz/sources/include/toonz/palettecmd.h index bca5440..ada5ee4 100644 --- a/toonz/sources/include/toonz/palettecmd.h +++ b/toonz/sources/include/toonz/palettecmd.h @@ -88,6 +88,17 @@ DVAPI void renamePalettePage(TPaletteHandle *paletteHandle, int pageIndex, DVAPI void renamePaletteStyle(TPaletteHandle *paletteHandle, const std::wstring &newName); +/* called in ColorModelViewer::pick() - move selected style to the first page */ +DVAPI void organizePaletteStyle(TPaletteHandle *paletteHandle, int styleId, + const TPoint &point); + +/* +called in ColorModelViewer::repickFromColorModel(). +Pick color from the img for all styles with "picked position" value. +*/ +DVAPI void pickColorByUsingPickedPosition(TPaletteHandle *paletteHandle, + TImageP img); + } // namespace #endif diff --git a/toonz/sources/include/toonz/preferences.h b/toonz/sources/include/toonz/preferences.h index 7b8c6e4..4e3e30d 100644 --- a/toonz/sources/include/toonz/preferences.h +++ b/toonz/sources/include/toonz/preferences.h @@ -99,6 +99,14 @@ public: void setAutosavePeriod(int minutes); int getAutosavePeriod() const { return m_autosavePeriod; } // minutes + void enableAutosaveScene(bool on); + bool isAutosaveSceneEnabled() const { return m_autosaveSceneEnabled; } + + void enableAutosaveOtherFiles(bool on); + bool isAutosaveOtherFilesEnabled() const { + return m_autosaveOtherFilesEnabled; + } + void enableLevelsBackup(bool enabled); bool isLevelsBackupEnabled() const { return m_levelsBackupEnabled; } @@ -110,6 +118,9 @@ public: return m_replaceAfterSaveLevelAs; } + void enableStartupPopup(bool on); + bool isStartupPopupEnabled() { return m_startupPopupEnabled; } + void setProjectRoot(int index); int getProjectRoot() { return m_projectRoot; } @@ -296,6 +307,11 @@ public: return m_multiLayerStylePickerEnabled; } + void enableUseNumpadForSwitchingStyles(bool on); + bool isUseNumpadForSwitchingStylesEnabled() const { + return m_useNumpadForSwitchingStyles; + } + // Xsheet tab void setXsheetStep(int step); //!< Sets the step used for the next/prev @@ -395,7 +411,8 @@ public: bool getPrecompute() { return m_precompute; } void setFfmpegTimeout(int seconds); int getFfmpegTimeout() { return m_ffmpegTimeout; } - + void setFastRenderPath(std::string path); + QString getFastRenderPath() const { return m_fastRenderPath; } // Uncategorized - internals void setAskForOverrideRender(bool on); @@ -407,6 +424,9 @@ public: int getTextureSize() const { return m_textureSize; } bool useDrawPixel() { return m_textureSize == 0; } + void setShortcutPreset(std::string preset); + QString getShortcutPreset() { return m_shortcutPreset; } + int getShmMax() const { return m_shmmax; } //! \sa The \p sysctl unix command. @@ -434,7 +454,9 @@ private: std::vector m_levelFormats; QString m_units, m_cameraUnits, m_scanLevelType, m_currentRoomChoice, - m_oldUnits, m_oldCameraUnits, m_ffmpegPath, m_customProjectRoot; + m_oldUnits, m_oldCameraUnits, m_ffmpegPath, m_shortcutPreset, + m_customProjectRoot; + QString m_fastRenderPath; double m_defLevelWidth, m_defLevelHeight, m_defLevelDpi; @@ -457,11 +479,13 @@ private: m_generatedMovieViewEnabled, m_xsheetAutopanEnabled, m_ignoreAlphaonColumn1Enabled, m_previewAlwaysOpenNewFlipEnabled, m_rewindAfterPlaybackEnabled, m_fitToFlipbookEnabled, m_autosaveEnabled, + m_autosaveSceneEnabled, m_autosaveOtherFilesEnabled, m_defaultViewerEnabled, m_pixelsOnly; bool m_rasterOptimizedMemory, m_saveUnpaintedInCleanup, m_askForOverrideRender, m_automaticSVNFolderRefreshEnabled, m_SVNEnabled, m_levelsBackupEnabled, m_minimizeSaveboxAfterEditing, - m_sceneNumberingEnabled, m_animationSheetEnabled, m_inksOnly; + m_sceneNumberingEnabled, m_animationSheetEnabled, m_inksOnly, + m_startupPopupEnabled; bool m_fillOnlySavebox, m_show0ThickLines, m_regionAntialias; bool m_onionSkinDuringPlayback; TPixel32 m_viewerBGColor, m_previewBGColor, m_chessboardColor1, @@ -499,6 +523,8 @@ private: std::string m_layerNameEncoding = "SJIS"; // Fixed to SJIS for now. You can // add interface if you wanna // change encoding. + // whether to use numpad and tab key shortcut for selecting styles + bool m_useNumpadForSwitchingStyles; private: Preferences(); diff --git a/toonz/sources/include/toonz/tproject.h b/toonz/sources/include/toonz/tproject.h index 399f5f6..0898213 100644 --- a/toonz/sources/include/toonz/tproject.h +++ b/toonz/sources/include/toonz/tproject.h @@ -57,7 +57,7 @@ public: bool isConstantFolder(int index) const; TFilePath getFolder(int index) const; - TFilePath getFolder(std::string name) const; + TFilePath getFolder(std::string name, bool absolute = false) const; TFilePath getScenesPath() const; diff --git a/toonz/sources/include/toonz/tscenehandle.h b/toonz/sources/include/toonz/tscenehandle.h index bc8ded5..75ad8cf 100644 --- a/toonz/sources/include/toonz/tscenehandle.h +++ b/toonz/sources/include/toonz/tscenehandle.h @@ -52,7 +52,9 @@ public: } void notifyNameSceneChange() { emit nameSceneChanged(); } - void notifyPreferenceChanged() { emit preferenceChanged(); } + void notifyPreferenceChanged(const QString &prefName) { + emit preferenceChanged(prefName); + } void notifyPixelUnitSelected(bool on) { emit pixelUnitSelected(on); } @@ -76,7 +78,7 @@ signals: void castChanged(); void castFolderAdded(const TFilePath &path); void nameSceneChanged(); - void preferenceChanged(); + void preferenceChanged(const QString &prefName); void pixelUnitSelected(bool on); }; diff --git a/toonz/sources/include/toonzqt/camerasettingswidget.h b/toonz/sources/include/toonzqt/camerasettingswidget.h index 18fc23b..1b2a995 100644 --- a/toonz/sources/include/toonzqt/camerasettingswidget.h +++ b/toonz/sources/include/toonzqt/camerasettingswidget.h @@ -71,6 +71,7 @@ protected: //--------------------------------------------------------------- class DVAPI CameraSettingsWidget final : public QFrame { + friend class StartupPopup; Q_OBJECT bool m_forCleanup; diff --git a/toonz/sources/include/toonzqt/dvdialog.h b/toonz/sources/include/toonzqt/dvdialog.h index b61e366..6184bf5 100644 --- a/toonz/sources/include/toonzqt/dvdialog.h +++ b/toonz/sources/include/toonzqt/dvdialog.h @@ -58,10 +58,11 @@ void DVAPI MsgBoxInPopup(MsgType type, const QString &text); // ATTENZIONE: Valore di ritorno // 0 = l'utente ha chiuso la finestra (dovrebbe corrispondere ad un cancel o ad -// un NO) -// 1 = primo bottone da sx premuto -// 2 = secondo bottone da sx premuto -// 3 = terzo bottone da sx premuto +// un NO) - closed window +// 1 = primo bottone da sx premuto - first button selected +// 2 = secondo bottone da sx premuto - second button +// 3 = terzo bottone da sx premuto - third button +// 4 = fourth button int DVAPI MsgBox(MsgType type, const QString &text, const std::vector &buttons, @@ -77,6 +78,12 @@ int DVAPI MsgBox(const QString &text, const QString &button1, const QString &button2, const QString &button3, int defaultButtonIndex = 0, QWidget *parent = 0); +// QUESTION: four botton user defined +int DVAPI MsgBox(const QString &text, const QString &button1, + const QString &button2, const QString &button3, + const QString &button4, int defaultButtonIndex = 0, + QWidget *parent = 0); + Dialog DVAPI *createMsgBox(MsgType type, const QString &text, const QStringList &buttons, int defaultButtonIndex, QWidget *parent = 0); @@ -229,6 +236,8 @@ public: void addButtonBarWidget(QWidget *widget); void addButtonBarWidget(QWidget *first, QWidget *second); void addButtonBarWidget(QWidget *first, QWidget *second, QWidget *third); + void addButtonBarWidget(QWidget *first, QWidget *second, QWidget *third, + QWidget *fourth); void hideEvent(QHideEvent *event) override; diff --git a/toonz/sources/include/toonzqt/filefield.h b/toonz/sources/include/toonzqt/filefield.h index f5a65f8..944f2d1 100644 --- a/toonz/sources/include/toonzqt/filefield.h +++ b/toonz/sources/include/toonzqt/filefield.h @@ -53,6 +53,8 @@ class DVAPI FileField : public QWidget { QStringList m_filters; QFileDialog::FileMode m_fileMode; QString m_windowTitle; + QString m_descriptionText; // if the initial text is not path, set the string + // here and prevent browsing protected: // used in the child class for CleanupSettings QPushButton *m_fileBrowseButton; @@ -73,7 +75,7 @@ public: static BrowserPopupController *m_browserPopupController; FileField(QWidget *parent = 0, QString path = QString(), - bool readOnly = false); + bool readOnly = false, bool doNotBrowseInitialPath = false); ~FileField() {} /*! Set what the user may select in the file dialog: diff --git a/toonz/sources/include/toonzqt/flipconsole.h b/toonz/sources/include/toonzqt/flipconsole.h index f7d54e6..93e493f 100644 --- a/toonz/sources/include/toonzqt/flipconsole.h +++ b/toonz/sources/include/toonzqt/flipconsole.h @@ -214,7 +214,8 @@ public: eFilledRaster = 0x4000000, // Used only in LineTest eDefineLoadBox = 0x8000000, eUseLoadBox = 0x10000000, - eEnd = 0x20000000 + eLocator = 0x20000000, + eEnd = 0x40000000 }; static const UINT cFullConsole = eEnd - 1; @@ -249,6 +250,7 @@ public: void enableButton(UINT button, bool enable, bool doShowHide = true); void showCurrentFrame(); int getCurrentFrame() const { return m_currentFrame; } + int getCurrentFps() const { return m_fps; } void setChecked(UINT button, bool state); bool isChecked(UINT button) const; void setCurrentFrame(int frame, bool forceResetting = false); diff --git a/toonz/sources/include/toonzqt/imageutils.h b/toonz/sources/include/toonzqt/imageutils.h index 357706d..6c73ebe 100644 --- a/toonz/sources/include/toonzqt/imageutils.h +++ b/toonz/sources/include/toonzqt/imageutils.h @@ -111,8 +111,10 @@ void DVAPI convertNaa2Tlv( FrameTaskNotifier *frameNotifier, //!< Observer class for frame success notifications. TPalette *palette = - 0); //!< Special conversion function from an antialiased level to tlv. - //! \sa Function ImageUtils::convert(). + 0, //!< Special conversion function from an antialiased level to tlv. + //! \sa Function ImageUtils::convert(). + bool removeUnusedStyles = + false); //! Remove unused styles from input palette. double DVAPI getQuantizedZoomFactor(double zf, bool forward); diff --git a/toonz/sources/include/toonzqt/menubarcommand.h b/toonz/sources/include/toonzqt/menubarcommand.h index 869b1be..b1b677b 100644 --- a/toonz/sources/include/toonzqt/menubarcommand.h +++ b/toonz/sources/include/toonzqt/menubarcommand.h @@ -145,7 +145,8 @@ public: std::string getShortcutFromId(CommandId id); int getKeyFromShortcut(const std::string &shortcut); int getKeyFromId(CommandId id); - void setShortcut(QAction *action, std::string shortcutString); + void setShortcut(QAction *action, std::string shortcutString, + bool keepDefault = true); QAction *getAction(CommandId id, bool createIfNeeded = false); diff --git a/toonz/sources/include/toonzqt/paletteviewergui.h b/toonz/sources/include/toonzqt/paletteviewergui.h index 390722c..e853458 100644 --- a/toonz/sources/include/toonzqt/paletteviewergui.h +++ b/toonz/sources/include/toonzqt/paletteviewergui.h @@ -199,11 +199,7 @@ protected: void zoomInChip(); void zoomOutChip(); -protected slots: - - void toggleLink(); - void eraseToggleLink(); - void removeLink(); + bool hasShortcut(int indexInPage); private: DVGui::LineEdit *m_renameTextField; diff --git a/toonz/sources/include/toonzqt/selectioncommandids.h b/toonz/sources/include/toonzqt/selectioncommandids.h index 0dd6b73..99ebe5e 100644 --- a/toonz/sources/include/toonzqt/selectioncommandids.h +++ b/toonz/sources/include/toonzqt/selectioncommandids.h @@ -12,6 +12,8 @@ #define MI_PasteColors "MI_PasteColors" #define MI_PasteNames "MI_PasteNames" #define MI_GetColorFromStudioPalette "MI_GetColorFromStudioPalette" +#define MI_ToggleLinkToStudioPalette "MI_ToggleLinkToStudioPalette" +#define MI_RemoveReferenceToStudioPalette "MI_RemoveReferenceToStudioPalette" #define MI_Clear "MI_Clear" #define MI_SelectAll "MI_SelectAll" #define MI_InvertSelection "MI_InvertSelection" diff --git a/toonz/sources/include/toonzqt/styleselection.h b/toonz/sources/include/toonzqt/styleselection.h index fb78637..6e5099e 100644 --- a/toonz/sources/include/toonzqt/styleselection.h +++ b/toonz/sources/include/toonzqt/styleselection.h @@ -95,9 +95,11 @@ public: void toggleKeyframe(int frame); // remove link from the studio palette (if linked) - bool removeLink(); + void removeLink(); // get back the style from the studio palette (if linked) void getBackOriginalStyle(); + // return true if there is at least one linked style in the selection + bool hasLinkedStyle(); }; #endif // STYLESELECTION_INCLUDED diff --git a/toonz/sources/include/tpalette.h b/toonz/sources/include/tpalette.h index bf16794..e883e6d 100644 --- a/toonz/sources/include/tpalette.h +++ b/toonz/sources/include/tpalette.h @@ -211,6 +211,9 @@ private: //! The confirmation dialog will not be opened unless the palette is edited //! again, //! even if the palette's dirtyflag is true. + + int m_shortcutScopeIndex; + public: TPalette(); ~TPalette(); @@ -417,6 +420,11 @@ between RGBA color components. m_isLocked = lock; } + bool hasPickedPosStyle(); // Returns true if there is at least one style with + // picked pos value + + void nextShortcutScope(bool invert); + public: // Deprecated functions diff --git a/toonz/sources/tnztools/CMakeLists.txt b/toonz/sources/tnztools/CMakeLists.txt index b3d5525..c597e31 100644 --- a/toonz/sources/tnztools/CMakeLists.txt +++ b/toonz/sources/tnztools/CMakeLists.txt @@ -11,6 +11,7 @@ set(MOC_HEADERS ../include/tools/screenpicker.h rgbpickertool.h rulertool.h + stylepickertool.h ) set(HEADERS ${MOC_HEADERS} diff --git a/toonz/sources/tnztools/Resources/picker_style_organize.png b/toonz/sources/tnztools/Resources/picker_style_organize.png new file mode 100644 index 0000000..c502b37 Binary files /dev/null and b/toonz/sources/tnztools/Resources/picker_style_organize.png differ diff --git a/toonz/sources/tnztools/Resources/picker_style_white_organize.png b/toonz/sources/tnztools/Resources/picker_style_white_organize.png new file mode 100644 index 0000000..b905466 Binary files /dev/null and b/toonz/sources/tnztools/Resources/picker_style_white_organize.png differ diff --git a/toonz/sources/tnztools/brushtool.cpp b/toonz/sources/tnztools/brushtool.cpp index 3272da2..1585aa8 100644 --- a/toonz/sources/tnztools/brushtool.cpp +++ b/toonz/sources/tnztools/brushtool.cpp @@ -45,7 +45,7 @@ using namespace ToolUtils; TEnv::DoubleVar VectorBrushMinSize("InknpaintVectorBrushMinSize", 1); TEnv::DoubleVar VectorBrushMaxSize("InknpaintVectorBrushMaxSize", 5); -TEnv::IntVar VectorCapStyle("InknpaintVectorCapStyle", 0); +TEnv::IntVar VectorCapStyle("InknpaintVectorCapStyle", 1); TEnv::IntVar VectorJoinStyle("InknpaintVectorJoinStyle", 0); TEnv::IntVar VectorMiterValue("InknpaintVectorMiterValue", 4); TEnv::DoubleVar RasterBrushMinSize("InknpaintRasterBrushMinSize", 1); diff --git a/toonz/sources/tnztools/cursormanager.cpp b/toonz/sources/tnztools/cursormanager.cpp index 126610f..323ba47 100644 --- a/toonz/sources/tnztools/cursormanager.cpp +++ b/toonz/sources/tnztools/cursormanager.cpp @@ -73,6 +73,9 @@ const struct { {ToolCursor::PickerCursorWhiteLine, "picker_style_white_line", 7, 22}, {ToolCursor::PickerCursorWhiteArea, "picker_style_white_area", 7, 22}, {ToolCursor::PickerCursorWhite, "picker_style_white", 7, 22}, + {ToolCursor::PickerCursorOrganize, "picker_style_organize", 7, 22}, + {ToolCursor::PickerCursorWhiteOrganize, "picker_style_white_organize", 7, + 22}, {ToolCursor::PickerRGB, "picker_rgb", 7, 22}, {ToolCursor::PickerRGBWhite, "picker_rgb_white", 7, 22}, {ToolCursor::FillCursorF, "fill_f", 6, 23}, diff --git a/toonz/sources/tnztools/stylepickertool.cpp b/toonz/sources/tnztools/stylepickertool.cpp index e73625c..4c21641 100644 --- a/toonz/sources/tnztools/stylepickertool.cpp +++ b/toonz/sources/tnztools/stylepickertool.cpp @@ -1,238 +1,307 @@ +#include "stylepickertool.h" - +// TnzTools includes #include "tools/tool.h" #include "tools/cursors.h" #include "tools/stylepicker.h" -#include "toonz/txshsimplelevel.h" -#include "toonz/txshlevelhandle.h" +#include "tools/toolhandle.h" -#include "drawutil.h" -#include "tvectorimage.h" -#include "ttoonzimage.h" -#include "tundo.h" +// TnzQt includes +#include "toonzqt/tselectionhandle.h" +#include "toonzqt/styleselection.h" +// TnzLib includes +#include "toonz/txshsimplelevel.h" +#include "toonz/txshlevelhandle.h" #include "toonz/tpalettehandle.h" - #include "toonz/stage2.h" -#include "tproperty.h" -#include "toonzqt/tselectionhandle.h" -#include "toonzqt/styleselection.h" -#include "tools/toolhandle.h" #include "toonz/tframehandle.h" #include "toonz/txsheethandle.h" #include "toonz/preferences.h" #include "toonz/tcolumnhandle.h" #include "toonz/dpiscale.h" #include "toonz/palettecontroller.h" +#include "toonz/txshleveltypes.h" +#include "toonz/txshpalettelevel.h" + +// TnzCore includes +#include "drawutil.h" +#include "tvectorimage.h" +#include "ttoonzimage.h" +#include "tundo.h" +#include "tmsgcore.h" #define LINES L"Lines" #define AREAS L"Areas" #define ALL L"Lines & Areas" -namespace { - //======================================================================== // Pick Style Tool //------------------------------------------------------------------------ -class StylePickerTool final : public TTool { - int m_oldStyleId, m_currentStyleId; - - TEnumProperty m_colorType; - TPropertyGroup m_prop; - - TBoolProperty m_passivePick; +StylePickerTool::StylePickerTool() + : TTool("T_StylePicker") + , m_currentStyleId(0) + , m_colorType("Mode:") + , m_passivePick("Passive Pick", false) + , m_organizePalette("Organize Palette", false) + , m_paletteToBeOrganized(NULL) { + m_prop.bind(m_colorType); + m_colorType.addValue(AREAS); + m_colorType.addValue(LINES); + m_colorType.addValue(ALL); + m_colorType.setId("Mode"); + bind(TTool::CommonLevels); + + m_prop.bind(m_passivePick); + m_passivePick.setId("PassivePick"); + + m_prop.bind(m_organizePalette); + m_organizePalette.setId("OrganizePalette"); +} -public: - TPropertyGroup *getProperties(int targetType) override { return &m_prop; } +void StylePickerTool::leftButtonDown(const TPointD &pos, const TMouseEvent &e) { + m_oldStyleId = m_currentStyleId = + getApplication()->getCurrentLevelStyleIndex(); + pick(pos, e); +} - StylePickerTool() - : TTool("T_StylePicker") - , m_currentStyleId(0) - , m_colorType("Mode:") - , m_passivePick("Passive Pick", false) { - m_prop.bind(m_colorType); - m_colorType.addValue(AREAS); - m_colorType.addValue(LINES); - m_colorType.addValue(ALL); - m_colorType.setId("Mode"); - bind(TTool::CommonLevels); +void StylePickerTool::leftButtonDrag(const TPointD &pos, const TMouseEvent &e) { + pick(pos, e); +} - m_prop.bind(m_passivePick); - m_passivePick.setId("PassivePick"); +void StylePickerTool::pick(const TPointD &pos, const TMouseEvent &e) { + // Area = 0, Line = 1, All = 2 + int modeValue = m_colorType.getIndex(); + + //------------------------------------ + // MultiLayerStylePicker + /*--- + PickしたStyleId = 0、かつ + Preference で MultiLayerStylePickerが有効、かつ + Scene編集モード、かつ + 下のカラムから拾った色がTransparentでない場合、 + → カレントLevelを移動する。 + ---*/ + if (Preferences::instance()->isMultiLayerStylePickerEnabled() && + getApplication()->getCurrentFrame()->isEditingScene()) { + int superPickedColumnId = getViewer()->posToColumnIndex( + e.m_pos, getPixelSize() * getPixelSize(), false); + + if (superPickedColumnId >= 0 /*-- 何かColumnに当たった場合 --*/ + && + getApplication()->getCurrentColumn()->getColumnIndex() != + superPickedColumnId) /*-- かつ、Current Columnでない場合 --*/ + { + /*-- そのColumnからPickを試みる --*/ + int currentFrame = getApplication()->getCurrentFrame()->getFrame(); + TXshCell pickedCell = + getApplication()->getCurrentXsheet()->getXsheet()->getCell( + currentFrame, superPickedColumnId); + TImageP pickedImage = pickedCell.getImage(false).getPointer(); + TToonzImageP picked_ti = pickedImage; + TVectorImageP picked_vi = pickedImage; + TXshSimpleLevel *picked_level = pickedCell.getSimpleLevel(); + if ((picked_ti || picked_vi) && picked_level) { + TPointD tmpMousePosition = getColumnMatrix(superPickedColumnId).inv() * + getViewer()->winToWorld(e.m_pos); + + TPointD tmpDpiScale = getCurrentDpiScale(picked_level, getCurrentFid()); + + tmpMousePosition.x /= tmpDpiScale.x; + tmpMousePosition.y /= tmpDpiScale.y; + + StylePicker superPicker(pickedImage); + int picked_subsampling = + picked_level->getImageSubsampling(pickedCell.getFrameId()); + int superPicked_StyleId = superPicker.pickStyleId( + TScale(1.0 / picked_subsampling) * tmpMousePosition + + TPointD(-0.5, -0.5), + getPixelSize() * getPixelSize(), modeValue); + /*-- 何かStyleが拾えて、Transparentでない場合 --*/ + if (superPicked_StyleId > 0) { + /*-- Levelの移動 --*/ + getApplication()->getCurrentLevel()->setLevel(picked_level); + /*-- Columnの移動 --*/ + getApplication()->getCurrentColumn()->setColumnIndex( + superPickedColumnId); + /*-- 選択の解除 --*/ + if (getApplication()->getCurrentSelection()->getSelection()) + getApplication() + ->getCurrentSelection() + ->getSelection() + ->selectNone(); + /*-- StyleIdの移動 --*/ + getApplication()->setCurrentLevelStyleIndex(superPicked_StyleId); + return; + } + } + } + } + /*-- MultiLayerStylePicker ここまで --*/ + //------------------------------------ + TImageP image = getImage(false); + TToonzImageP ti = image; + TVectorImageP vi = image; + TXshSimpleLevel *level = + getApplication()->getCurrentLevel()->getSimpleLevel(); + if ((!ti && !vi) || !level) return; + + /*-- 画面外をpickしても拾えないようにする --*/ + if (!m_viewer->getGeometry().contains(pos)) return; + + int subsampling = level->getImageSubsampling(getCurrentFid()); + StylePicker picker(image); + int styleId = + picker.pickStyleId(TScale(1.0 / subsampling) * pos + TPointD(-0.5, -0.5), + getPixelSize() * getPixelSize(), modeValue); + + if (styleId < 0) return; + + if (modeValue == 1) // LINES + { + /*-- pickLineモードのとき、取得Styleが0の場合はカレントStyleを変えない。 + * --*/ + if (styleId == 0) return; + /*-- + * pickLineモードのとき、PurePaintの部分をクリックしてもカレントStyleを変えない + * --*/ + if (ti && + picker.pickTone(TScale(1.0 / subsampling) * pos + + TPointD(-0.5, -0.5)) == 255) + return; } - ToolType getToolType() const override { return TTool::LevelReadTool; } + /*--- Styleを選択している場合は選択を解除する ---*/ + TSelection *selection = + TTool::getApplication()->getCurrentSelection()->getSelection(); + if (selection) { + TStyleSelection *styleSelection = + dynamic_cast(selection); + if (styleSelection) styleSelection->selectNone(); + } - void draw() override {} + getApplication()->setCurrentLevelStyleIndex(styleId); +} - void leftButtonDown(const TPointD &pos, const TMouseEvent &e) override { - m_oldStyleId = m_currentStyleId = - getApplication()->getCurrentLevelStyleIndex(); - pick(pos, e); - } - void leftButtonDrag(const TPointD &pos, const TMouseEvent &e) override { - pick(pos, e); +void StylePickerTool::mouseMove(const TPointD &pos, const TMouseEvent &e) { + if (!m_passivePick.getValue()) return; + /*--- PassiveにStyleを拾う機能 ---*/ + PaletteController *controller = + TTool::getApplication()->getPaletteController(); + + TImageP image = getImage(false); + TToonzImageP ti = image; + TVectorImageP vi = image; + TXshSimpleLevel *level = + getApplication()->getCurrentLevel()->getSimpleLevel(); + if ((!ti && !vi) || !level || !m_viewer->getGeometry().contains(pos)) { + controller->notifyStylePassivePicked(-1, -1, -1); + return; } - void pick(const TPointD &pos, const TMouseEvent &e) { - // Area = 0, Line = 1, All = 2 - int modeValue = m_colorType.getIndex(); - - //------------------------------------ - // MultiLayerStylePicker - /*--- - PickしたStyleId = 0、かつ - Preference で MultiLayerStylePickerが有効、かつ - Scene編集モード、かつ - 下のカラムから拾った色がTransparentでない場合、 - → カレントLevelを移動する。 - ---*/ - if (Preferences::instance()->isMultiLayerStylePickerEnabled() && - getApplication()->getCurrentFrame()->isEditingScene()) { - int superPickedColumnId = getViewer()->posToColumnIndex( - e.m_pos, getPixelSize() * getPixelSize(), false); - - if (superPickedColumnId >= 0 /*-- 何かColumnに当たった場合 --*/ - && - getApplication()->getCurrentColumn()->getColumnIndex() != - superPickedColumnId) /*-- かつ、Current Columnでない場合 --*/ - { - /*-- そのColumnからPickを試みる --*/ - int currentFrame = getApplication()->getCurrentFrame()->getFrame(); - TXshCell pickedCell = - getApplication()->getCurrentXsheet()->getXsheet()->getCell( - currentFrame, superPickedColumnId); - TImageP pickedImage = pickedCell.getImage(false).getPointer(); - TToonzImageP picked_ti = pickedImage; - TVectorImageP picked_vi = pickedImage; - TXshSimpleLevel *picked_level = pickedCell.getSimpleLevel(); - if ((picked_ti || picked_vi) && picked_level) { - TPointD tmpMousePosition = - getColumnMatrix(superPickedColumnId).inv() * - getViewer()->winToWorld(e.m_pos); - - TPointD tmpDpiScale = - getCurrentDpiScale(picked_level, getCurrentFid()); - - tmpMousePosition.x /= tmpDpiScale.x; - tmpMousePosition.y /= tmpDpiScale.y; - - StylePicker superPicker(pickedImage); - int picked_subsampling = - picked_level->getImageSubsampling(pickedCell.getFrameId()); - int superPicked_StyleId = superPicker.pickStyleId( - TScale(1.0 / picked_subsampling) * tmpMousePosition + - TPointD(-0.5, -0.5), - getPixelSize() * getPixelSize(), modeValue); - /*-- 何かStyleが拾えて、Transparentでない場合 --*/ - if (superPicked_StyleId > 0) { - /*-- Levelの移動 --*/ - getApplication()->getCurrentLevel()->setLevel(picked_level); - /*-- Columnの移動 --*/ - getApplication()->getCurrentColumn()->setColumnIndex( - superPickedColumnId); - /*-- 選択の解除 --*/ - if (getApplication()->getCurrentSelection()->getSelection()) - getApplication() - ->getCurrentSelection() - ->getSelection() - ->selectNone(); - /*-- StyleIdの移動 --*/ - getApplication()->setCurrentLevelStyleIndex(superPicked_StyleId); - return; - } - } - } - } - /*-- MultiLayerStylePicker ここまで --*/ - //------------------------------------ - TImageP image = getImage(false); - TToonzImageP ti = image; - TVectorImageP vi = image; - TXshSimpleLevel *level = - getApplication()->getCurrentLevel()->getSimpleLevel(); - if ((!ti && !vi) || !level) return; - - /*-- 画面外をpickしても拾えないようにする --*/ - if (!m_viewer->getGeometry().contains(pos)) return; - - int subsampling = level->getImageSubsampling(getCurrentFid()); - StylePicker picker(image); - int styleId = picker.pickStyleId( - TScale(1.0 / subsampling) * pos + TPointD(-0.5, -0.5), - getPixelSize() * getPixelSize(), modeValue); - - if (styleId < 0) return; - - if (modeValue == 1) // LINES - { - /*-- pickLineモードのとき、取得Styleが0の場合はカレントStyleを変えない。 - * --*/ - if (styleId == 0) return; - /*-- - * pickLineモードのとき、PurePaintの部分をクリックしてもカレントStyleを変えない - * --*/ - if (ti && - picker.pickTone(TScale(1.0 / subsampling) * pos + - TPointD(-0.5, -0.5)) == 255) - return; - } - - /*--- Styleを選択している場合は選択を解除する ---*/ - TSelection *selection = - TTool::getApplication()->getCurrentSelection()->getSelection(); - if (selection) { - TStyleSelection *styleSelection = - dynamic_cast(selection); - if (styleSelection) styleSelection->selectNone(); - } + int subsampling = level->getImageSubsampling(getCurrentFid()); + StylePicker picker(image); + TPointD pickPos(TScale(1.0 / subsampling) * pos + TPointD(-0.5, -0.5)); + int inkStyleId = + picker.pickStyleId(pickPos, getPixelSize() * getPixelSize(), 1); + int paintStyleId = + picker.pickStyleId(pickPos, getPixelSize() * getPixelSize(), 0); + int tone = picker.pickTone(pickPos); + controller->notifyStylePassivePicked(inkStyleId, paintStyleId, tone); +} - getApplication()->setCurrentLevelStyleIndex(styleId); - } +int StylePickerTool::getCursorId() const { + bool isBlackBG = ToonzCheck::instance()->getChecks() & ToonzCheck::eBlackBg; + + /* in case the "organize palette" option is active */ + if (m_organizePalette.getValue()) + return (isBlackBG) ? ToolCursor::PickerCursorWhiteOrganize + : ToolCursor::PickerCursorOrganize; + + if (m_colorType.getValue() == LINES) + return (isBlackBG) ? ToolCursor::PickerCursorWhiteLine + : ToolCursor::PickerCursorLine; + else if (m_colorType.getValue() == AREAS) + return (isBlackBG) ? ToolCursor::PickerCursorWhiteArea + : ToolCursor::PickerCursorArea; + else // line&areas + return (isBlackBG) ? ToolCursor::PickerCursorWhite + : ToolCursor::PickerCursor; +} - void mouseMove(const TPointD &pos, const TMouseEvent &e) override { - if (!m_passivePick.getValue()) return; - /*--- PassiveにStyleを拾う機能 ---*/ - PaletteController *controller = - TTool::getApplication()->getPaletteController(); - - TImageP image = getImage(false); - TToonzImageP ti = image; - TVectorImageP vi = image; - TXshSimpleLevel *level = - getApplication()->getCurrentLevel()->getSimpleLevel(); - if ((!ti && !vi) || !level || !m_viewer->getGeometry().contains(pos)) { - controller->notifyStylePassivePicked(-1, -1, -1); - return; +bool StylePickerTool::onPropertyChanged(std::string propertyName) { + if (propertyName == m_organizePalette.getName()) { + if (m_organizePalette.getValue()) { + if (!startOrganizePalette()) { + m_organizePalette.setValue(false); + getApplication()->getCurrentTool()->notifyToolChanged(); + return false; + } + } else { + std::cout << "End Organize Palette" << std::endl; + m_paletteToBeOrganized = NULL; } + } + return true; +} - int subsampling = level->getImageSubsampling(getCurrentFid()); - StylePicker picker(image); - TPointD pickPos(TScale(1.0 / subsampling) * pos + TPointD(-0.5, -0.5)); - int inkStyleId = - picker.pickStyleId(pickPos, getPixelSize() * getPixelSize(), 1); - int paintStyleId = - picker.pickStyleId(pickPos, getPixelSize() * getPixelSize(), 0); - int tone = picker.pickTone(pickPos); - controller->notifyStylePassivePicked(inkStyleId, paintStyleId, tone); +bool StylePickerTool::startOrganizePalette() { + /* Check if the organizing operation is available */ + TXshLevel *level = getApplication()->getCurrentLevel()->getLevel(); + if (!level) { + DVGui::error(tr("No current level.")); + return false; + } + if (level->getType() != PLI_XSHLEVEL && level->getType() != TZP_XSHLEVEL && + level->getType() != PLT_XSHLEVEL) { + DVGui::error(tr("Current level has no available palette.")); + return false; + } + /* palette should have more than one page to organize */ + TPalette *pal = NULL; + if (level->getType() == PLT_XSHLEVEL) + pal = level->getPaletteLevel()->getPalette(); + else + pal = level->getSimpleLevel()->getPalette(); + if (!pal || pal->getPageCount() < 2) { + DVGui::error( + tr("Palette must have more than one palette to be organized.")); + return false; } - void onActivate() override {} + m_paletteToBeOrganized = pal; - int getCursorId() const override { - bool isBlackBG = ToonzCheck::instance()->getChecks() & ToonzCheck::eBlackBg; + std::cout << "Start Organize Palette" << std::endl; - if (m_colorType.getValue() == LINES) - return (isBlackBG) ? ToolCursor::PickerCursorWhiteLine - : ToolCursor::PickerCursorLine; - else if (m_colorType.getValue() == AREAS) - return (isBlackBG) ? ToolCursor::PickerCursorWhiteArea - : ToolCursor::PickerCursorArea; - else // line&areas - return (isBlackBG) ? ToolCursor::PickerCursorWhite - : ToolCursor::PickerCursor; - } + return true; +} -} stylePickerTool; +/* + If the working palette is changed, then deactivate the "organize palette" + toggle. +*/ +void StylePickerTool::onImageChanged() { + std::cout << "StylePickerTool::onImageChanged" << std::endl; + if (!m_organizePalette.getValue() || !m_paletteToBeOrganized) return; + + TXshLevel *level = getApplication()->getCurrentLevel()->getLevel(); + if (!level) { + m_organizePalette.setValue(false); + getApplication()->getCurrentTool()->notifyToolChanged(); + return; + } + TPalette *pal = NULL; + if (level->getType() == PLT_XSHLEVEL) + pal = level->getPaletteLevel()->getPalette(); + else if (level->getSimpleLevel()) { + pal = level->getSimpleLevel()->getPalette(); + } + if (!pal || pal != m_paletteToBeOrganized) { + m_organizePalette.setValue(false); + getApplication()->getCurrentTool()->notifyToolChanged(); + return; + } } + +StylePickerTool stylePickerTool; diff --git a/toonz/sources/tnztools/stylepickertool.h b/toonz/sources/tnztools/stylepickertool.h new file mode 100644 index 0000000..2a6982a --- /dev/null +++ b/toonz/sources/tnztools/stylepickertool.h @@ -0,0 +1,54 @@ +#pragma once + +#ifndef STYLEPICKERTOOL_H +#define STYLEPICKERTOOL_H + +#include "tools/tool.h" +#include "tproperty.h" +#include + +class StylePickerTool final : public TTool, public QObject { + int m_oldStyleId, m_currentStyleId; + + TEnumProperty m_colorType; + TPropertyGroup m_prop; + TBoolProperty m_passivePick; + + TBoolProperty m_organizePalette; + TPalette *m_paletteToBeOrganized; + + bool startOrganizePalette(); + +public: + TPropertyGroup *getProperties(int targetType) override { return &m_prop; } + + StylePickerTool(); + + ToolType getToolType() const override { return TTool::LevelReadTool; } + + void draw() override {} + + void leftButtonDown(const TPointD &pos, const TMouseEvent &e) override; + + void leftButtonDrag(const TPointD &pos, const TMouseEvent &e) override; + + void pick(const TPointD &pos, const TMouseEvent &e); + + void mouseMove(const TPointD &pos, const TMouseEvent &e) override; + + int getCursorId() const override; + + bool onPropertyChanged(std::string propertyName); + + bool isOrganizePaletteActive() { return m_organizePalette.getValue(); } + + /* + This function is called when either frame/column/level/scene is switched or + either scene/level/object is changed (see tapp.cpp). + If the working palette is changed, then deactivate the "organize palette" + toggle. + */ + void onImageChanged() override; +}; + +#endif \ No newline at end of file diff --git a/toonz/sources/tnztools/tnztools.qrc b/toonz/sources/tnztools/tnztools.qrc index 98087dc..1b5b91b 100644 --- a/toonz/sources/tnztools/tnztools.qrc +++ b/toonz/sources/tnztools/tnztools.qrc @@ -50,6 +50,8 @@ Resources/picker_style_white_line.png Resources/picker_style_white_area.png Resources/picker_style_white.png + Resources/picker_style_organize.png + Resources/picker_style_white_organize.png Resources/picker_rgb.png Resources/picker_rgb_white.png Resources/fill_f.png diff --git a/toonz/sources/tnztools/tooloptions.cpp b/toonz/sources/tnztools/tooloptions.cpp index f19ee3b..399b876 100644 --- a/toonz/sources/tnztools/tooloptions.cpp +++ b/toonz/sources/tnztools/tooloptions.cpp @@ -2182,6 +2182,17 @@ StylePickerToolOptionsBox::StylePickerToolOptionsBox( m_layout->addWidget(m_currentStyleLabel, 0); m_layout->addStretch(1); + // retrieve the "organize palette" checkbox from the layout and insert + // into rightmost of the tool option bar + ToolOptionCheckbox *organizePaletteCB = + dynamic_cast(m_controls.value("Organize Palette")); + m_layout->removeWidget(organizePaletteCB); + m_layout->addWidget(new ToolOptionsBarSeparator(this), 0); + m_layout->addWidget(organizePaletteCB); + organizePaletteCB->setToolTip( + tr("With this option being activated, the picked style will be\nmoved to " + "the end of the first page of the palette.")); + if (m_realTimePickMode) { connect(m_realTimePickMode, SIGNAL(toggled(bool)), m_currentStyleLabel, SLOT(setVisible(bool))); @@ -2340,6 +2351,7 @@ un po' di codice... */ m_panels[tool] = panel; layout()->addWidget(panel); + emit newPanelCreated(); } else { // il panel c'e' gia'. panel = it->second; diff --git a/toonz/sources/toonz/CMakeLists.txt b/toonz/sources/toonz/CMakeLists.txt index 0215c13..c6849a1 100644 --- a/toonz/sources/toonz/CMakeLists.txt +++ b/toonz/sources/toonz/CMakeLists.txt @@ -100,6 +100,7 @@ set(MOC_HEADERS selectionutils.h shifttracetool.h shortcutpopup.h + startuppopup.h subcameramanager.h subscenecommand.h svncleanupdialog.h @@ -140,6 +141,8 @@ set(MOC_HEADERS historypane.h cleanupsettingspane.h penciltestpopup.h + locatorpopup.h + styleshortcutswitchablepanel.h # Tracker file dummyprocessor.h metnum.h @@ -232,6 +235,7 @@ set(SOURCES scriptconsolepanel.cpp shifttracetool.cpp shortcutpopup.cpp + startuppopup.cpp subcameramanager.cpp timestretchpopup.cpp trackerpopup.cpp @@ -298,6 +302,8 @@ set(SOURCES historypane.cpp cleanupsettingspane.cpp penciltestpopup.cpp + locatorpopup.cpp + styleshortcutswitchablepanel.cpp # Tracker file dummyprocessor.cpp metnum.cpp @@ -378,7 +384,7 @@ if(WIN32) target_link_libraries(OpenToonz_${VERSION} Qt5::WinMain Qt5::Core Qt5::Gui Qt5::Network Qt5::OpenGL Qt5::Svg Qt5::Xml Qt5::Script Qt5::Widgets Qt5::PrintSupport Qt5::Multimedia - ${GL_LIB} ${GLUT_LIB} + ${GL_LIB} ${GLUT_LIB} strmiids tnzcore tnzbase toonzlib colorfx tnzext image sound toonzqt tnztools tnzstdfx tfarm ) elseif(APPLE) @@ -430,10 +436,10 @@ if(APPLE) get_target_property(loc OpenToonz_${VERSION} MACOSX_BUNDLE_NAME) message(" ==> App Bundle: " ${loc}) message(" ==> Mach-o: " ${bin}) - foreach (lib ${EXTRA_LIBS}) + foreach(lib ${EXTRA_LIBS}) message(" copy:" ${lib} "==>" ${CMAKE_CURRENT_BINARY_DIR}/OpenToonz_${VERSION}.app/Contents/MacOS/) add_custom_command(TARGET OpenToonz_${VERSION} POST_BUILD COMMAND cp ${lib} ${CMAKE_CURRENT_BINARY_DIR}/OpenToonz_${VERSION}.app/Contents/MacOS/) - endforeach () + endforeach() add_custom_command(TARGET OpenToonz_${VERSION} POST_BUILD COMMAND diff --git a/toonz/sources/toonz/Resources/locator.png b/toonz/sources/toonz/Resources/locator.png new file mode 100644 index 0000000..439df63 Binary files /dev/null and b/toonz/sources/toonz/Resources/locator.png differ diff --git a/toonz/sources/toonz/Resources/locator_click.png b/toonz/sources/toonz/Resources/locator_click.png new file mode 100644 index 0000000..8045221 Binary files /dev/null and b/toonz/sources/toonz/Resources/locator_click.png differ diff --git a/toonz/sources/toonz/Resources/locator_over.png b/toonz/sources/toonz/Resources/locator_over.png new file mode 100644 index 0000000..8045221 Binary files /dev/null and b/toonz/sources/toonz/Resources/locator_over.png differ diff --git a/toonz/sources/toonz/Resources/startup.png b/toonz/sources/toonz/Resources/startup.png new file mode 100644 index 0000000..10757e0 Binary files /dev/null and b/toonz/sources/toonz/Resources/startup.png differ diff --git a/toonz/sources/toonz/cellselectioncommand.cpp b/toonz/sources/toonz/cellselectioncommand.cpp index a670e73..fa3c108 100644 --- a/toonz/sources/toonz/cellselectioncommand.cpp +++ b/toonz/sources/toonz/cellselectioncommand.cpp @@ -1292,6 +1292,7 @@ TXshSimpleLevel *CloneLevelUndo::cloneLevel( assert(palette); dstSl->setPalette(palette->clone()); + dstSl->getPalette()->setDirtyFlag(true); } // The level clone shell was created. Now, clone the associated frames found @@ -1306,6 +1307,8 @@ TXshSimpleLevel *CloneLevelUndo::cloneLevel( dstSl->setFrame(*ft, img->cloneImage()); } + dstSl->setDirtyFlag(true); + return dstSl; } diff --git a/toonz/sources/toonz/cleanupsettingspane.cpp b/toonz/sources/toonz/cleanupsettingspane.cpp index d7e5579..30756ba 100644 --- a/toonz/sources/toonz/cleanupsettingspane.cpp +++ b/toonz/sources/toonz/cleanupsettingspane.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include "cleanupsettingspane.h" @@ -80,6 +81,10 @@ void CleanupSaveInField::browseDirectory() { CleanupSettingsPane::CleanupSettingsPane(QWidget *parent) : QFrame(parent), m_attached(false) { + // Autocenter + m_autocenterBox = new QGroupBox(tr("Autocenter"), this); + m_pegHolesOm = new QComboBox(this); + m_fieldGuideOm = new QComboBox(this); // Rotate&Flip QFrame *rotFlipFrame = new QFrame(this); m_rotateOm = new QComboBox(this); @@ -103,6 +108,19 @@ CleanupSettingsPane::CleanupSettingsPane(QWidget *parent) QPushButton *loadBtn = new QPushButton(tr("Load")); QPushButton *resetBtn = new QPushButton(tr("Reset")); + // Autocenter + m_autocenterBox->setCheckable(true); + QStringList pegbarHoles; + pegbarHoles << "Bottom" + << "Top" + << "Left" + << "Right"; + m_pegHolesOm->addItems(pegbarHoles); + std::vector fdgNames; + CleanupParameters::getFdgNames(fdgNames); + for (int i = 0; i < (int)fdgNames.size(); i++) + m_fieldGuideOm->addItem(QString(fdgNames[i].c_str())); + // Rotate&Flip rotFlipFrame->setObjectName("CleanupSettingsFrame"); QStringList rotate; @@ -137,6 +155,23 @@ CleanupSettingsPane::CleanupSettingsPane(QWidget *parent) mainLay->setSpacing(2); mainLay->setMargin(5); { + // Autocenter + QGridLayout *autocenterLay = new QGridLayout(); + autocenterLay->setMargin(5); + autocenterLay->setSpacing(3); + { + autocenterLay->addWidget(new QLabel(tr("Pegbar Holes")), 0, 0, + Qt::AlignRight | Qt::AlignVCenter); + autocenterLay->addWidget(m_pegHolesOm, 0, 1); + autocenterLay->addWidget(new QLabel(tr("Field Guide")), 1, 0, + Qt::AlignRight | Qt::AlignVCenter); + autocenterLay->addWidget(m_fieldGuideOm, 1, 1); + } + autocenterLay->setColumnStretch(0, 0); + autocenterLay->setColumnStretch(1, 1); + m_autocenterBox->setLayout(autocenterLay); + mainLay->addWidget(m_autocenterBox, 0); + // Rotate&Flip QGridLayout *rotFlipLay = new QGridLayout(); rotFlipLay->setMargin(5); @@ -226,7 +261,14 @@ CleanupSettingsPane::CleanupSettingsPane(QWidget *parent) //-----signal-slot connections bool ret = true; - ret = ret && connect(m_rotateOm, SIGNAL(activated(int)), + ret = ret && connect(m_autocenterBox, SIGNAL(toggled(bool)), + SLOT(onGenericSettingsChange())); + ret = ret && connect(m_pegHolesOm, SIGNAL(activated(int)), + SLOT(onGenericSettingsChange())); + ret = ret && connect(m_fieldGuideOm, SIGNAL(activated(int)), + SLOT(onGenericSettingsChange())); + + ret = ret && connect(m_rotateOm, SIGNAL(activated(int)), SLOT(onGenericSettingsChange())); ret = ret && connect(m_flipX, SIGNAL(stateChanged(int)), SLOT(onGenericSettingsChange())); @@ -336,6 +378,15 @@ void CleanupSettingsPane::updateGui(bool needsPostProcess) { void CleanupSettingsPane::updateGui(CleanupParameters *params, CleanupParameters *oldParams) { + m_autocenterBox->setChecked(params->m_autocenterType == + CleanupTypes::AUTOCENTER_FDG); + m_pegHolesOm->setCurrentIndex(params->m_pegSide - 1); + + QString fieldName = QString::fromStdString(params->getFdgName()); + int index = (fieldName.isEmpty()) ? 0 : m_fieldGuideOm->findText(fieldName); + assert(index != -1); + m_fieldGuideOm->setCurrentIndex(index); + m_rotateOm->setCurrentIndex(params->m_rotate / 90); m_flipX->setChecked(params->m_flipx); m_flipY->setChecked(params->m_flipy); @@ -462,6 +513,13 @@ void CleanupSettingsPane::onGenericSettingsChange() { CleanupSettingsModel *model = CleanupSettingsModel::instance(); CleanupParameters *params = model->getCurrentParameters(); + params->m_autocenterType = m_autocenterBox->isChecked() + ? CleanupTypes::AUTOCENTER_FDG + : CleanupTypes::AUTOCENTER_NONE; + params->m_pegSide = + (CleanupTypes::PEGS_SIDE)(m_pegHolesOm->currentIndex() + 1); + params->setFdgByName(m_fieldGuideOm->currentText().toStdString()); + params->m_rotate = m_rotateOm->currentIndex() * 90; params->m_flipx = m_flipX->isChecked(); params->m_flipy = m_flipY->isChecked(); diff --git a/toonz/sources/toonz/cleanupsettingspane.h b/toonz/sources/toonz/cleanupsettingspane.h index b0069d8..75da278 100644 --- a/toonz/sources/toonz/cleanupsettingspane.h +++ b/toonz/sources/toonz/cleanupsettingspane.h @@ -18,6 +18,7 @@ class QComboBox; class QLabel; class QCheckBox; class CleanupPaletteViewer; +class QGroupBox; namespace DVGui { @@ -47,6 +48,9 @@ public: CleanupCameraSettingsWidget *m_cameraWidget; private: + //----Autocenter + QGroupBox *m_autocenterBox; + QComboBox *m_pegHolesOm, *m_fieldGuideOm; //----Rotate & Flip QComboBox *m_rotateOm; QCheckBox *m_flipX; diff --git a/toonz/sources/toonz/colormodelviewer.cpp b/toonz/sources/toonz/colormodelviewer.cpp index 2e063b5..e4b0085 100644 --- a/toonz/sources/toonz/colormodelviewer.cpp +++ b/toonz/sources/toonz/colormodelviewer.cpp @@ -14,6 +14,7 @@ #include "tools/toolcommandids.h" #include "tools/tool.h" #include "tools/toolhandle.h" +#include "../tnztools/stylepickertool.h" // TnzQt includes #include "toonzqt/menubarcommand.h" @@ -84,7 +85,7 @@ ColorModelViewer::ColorModelViewer(QWidget *parent) FlipConsole::eCompare | FlipConsole::eCustomize | FlipConsole::eSave | FlipConsole::eFilledRaster | FlipConsole::eDefineLoadBox | FlipConsole::eUseLoadBox | - FlipConsole::eDefineSubCamera)), + FlipConsole::eDefineSubCamera | FlipConsole::eLocator)), eDontKeepFilesOpened, true) , m_mode(0) , m_currentRefImgPath(TFilePath()) { @@ -222,11 +223,28 @@ void ColorModelViewer::contextMenuEvent(QContextMenuEvent *event) { connect(loadCurrentFrame, SIGNAL(triggered()), SLOT(loadCurrentFrame())); menu.addAction(loadCurrentFrame); + if (!m_imageViewer->getImage()) { + menu.exec(event->globalPos()); + return; + } + QAction *removeColorModel = new QAction(QString(tr("Remove Color Model")), this); connect(removeColorModel, SIGNAL(triggered()), SLOT(removeColorModel())); menu.addAction(removeColorModel); + /* If there is at least one style with "picked pos" parameter, then enable + * repick command */ + TRasterImageP ri = m_imageViewer->getImage(); + if (ri && currentPalette->hasPickedPosStyle()) { + menu.addSeparator(); + QAction *repickFromColorModelAct = new QAction( + QString(tr("Update Colors by Using Picked Positions")), this); + connect(repickFromColorModelAct, SIGNAL(triggered()), + SLOT(repickFromColorModel())); + menu.addAction(repickFromColorModelAct); + } + menu.addSeparator(); QString shortcut = QString::fromStdString( @@ -306,6 +324,19 @@ void ColorModelViewer::pick(const QPoint &p) { if (styleSelection) styleSelection->selectNone(); } + /* + if the Style Picker tool is current and "organize palette" is activated, + then move the picked style to the first page of the palette. + */ + TTool *tool = TApp::instance()->getCurrentTool()->getTool(); + if (tool->getName() == "T_StylePicker") { + StylePickerTool *spTool = dynamic_cast(tool); + if (spTool && spTool->isOrganizePaletteActive()) { + TPoint point = picker.getRasterPoint(pos); + PaletteCmd::organizePaletteStyle(ph, styleIndex, point); + } + } + ph->setStyleIndex(styleIndex); } @@ -356,8 +387,16 @@ void ColorModelViewer::showEvent(QShowEvent *e) { //----------------------------------------------------------------------------- /*- ツールのTypeに合わせてPickのタイプも変え、カーソルも切り替える -*/ void ColorModelViewer::changePickType() { - TPropertyGroup *propGroup = - TApp::instance()->getCurrentTool()->getTool()->getProperties(0); + TTool *tool = TApp::instance()->getCurrentTool()->getTool(); + if (tool->getName() == T_StylePicker) { + StylePickerTool *stylePickerTool = dynamic_cast(tool); + if (stylePickerTool->isOrganizePaletteActive()) { + setToolCursor(m_imageViewer, ToolCursor::PickerCursorOrganize); + return; + } + } + + TPropertyGroup *propGroup = tool->getProperties(0); /*- Propertyの無いツールの場合 -*/ if (!propGroup) { m_mode = 2; @@ -573,6 +612,17 @@ void ColorModelViewer::onRefImageNotFound() { "level.")); } +//----------------------------------------------------------------------------- + +void ColorModelViewer::repickFromColorModel() { + TImageP img = m_imageViewer->getImage(); + if (!img) return; + TPaletteHandle *ph = + TApp::instance()->getPaletteController()->getCurrentLevelPalette(); + + PaletteCmd::pickColorByUsingPickedPosition(ph, img); +} + //============================================================================= OpenFloatingPanel openColorModelCommand(MI_OpenColorModel, "ColorModel", diff --git a/toonz/sources/toonz/colormodelviewer.h b/toonz/sources/toonz/colormodelviewer.h index e068080..833a62d 100644 --- a/toonz/sources/toonz/colormodelviewer.h +++ b/toonz/sources/toonz/colormodelviewer.h @@ -48,6 +48,7 @@ protected: * UseCurrentFrameのLevelに移動してきたときに、改めてCurrentFrameを格納しなおす * -*/ void reloadCurrentFrame(); + protected slots: void showCurrentImage(); @@ -62,6 +63,8 @@ protected slots: * -*/ void changePickType(); + void repickFromColorModel(); + signals: void refImageNotFound(); }; diff --git a/toonz/sources/toonz/comboviewerpane.cpp b/toonz/sources/toonz/comboviewerpane.cpp index 6a10ad9..c592005 100644 --- a/toonz/sources/toonz/comboviewerpane.cpp +++ b/toonz/sources/toonz/comboviewerpane.cpp @@ -86,7 +86,7 @@ ComboViewerPanel::ComboViewerPanel(QWidget *parent, Qt::WindowFlags flags) #else ComboViewerPanel::ComboViewerPanel(QWidget *parent, Qt::WFlags flags) #endif - : TPanel(parent) { + : StyleShortcutSwitchablePanel(parent) { TApp *app = TApp::instance(); QFrame *hbox = new QFrame(this); @@ -103,6 +103,7 @@ ComboViewerPanel::ComboViewerPanel(QWidget *parent, Qt::WFlags flags) ImageUtils::FullScreenWidget *fsWidget = new ImageUtils::FullScreenWidget(this); fsWidget->setWidget(m_sceneViewer = new SceneViewer(fsWidget)); + m_sceneViewer->setIsStyleShortcutSwitchable(); #if defined(Q_OS_WIN) && (QT_VERSION >= 0x050500) && (QT_VERSION < 0x050600) // Workaround for QTBUG-48288 @@ -189,6 +190,9 @@ ComboViewerPanel::ComboViewerPanel(QWidget *parent, Qt::WFlags flags) SLOT(update())); ret = ret && connect(app->getCurrentScene(), SIGNAL(sceneSwitched()), this, SLOT(onSceneSwitched())); + ret = ret && connect(m_toolOptions, SIGNAL(newPanelCreated()), this, + SLOT(updateTabFocus())); + assert(ret); // note: initializeTitleBar() refers to m_sceneViewer @@ -336,7 +340,8 @@ ComboViewerPanel::~ComboViewerPanel() { //----------------------------------------------------------------------------- -void ComboViewerPanel::showEvent(QShowEvent *) { +void ComboViewerPanel::showEvent(QShowEvent *event) { + StyleShortcutSwitchablePanel::showEvent(event); TApp *app = TApp::instance(); TFrameHandle *frameHandle = app->getCurrentFrame(); TSceneHandle *sceneHandle = app->getCurrentScene(); @@ -388,9 +393,6 @@ void ComboViewerPanel::showEvent(QShowEvent *) { ret = ret && connect(app->getCurrentTool(), SIGNAL(toolSwitched()), m_sceneViewer, SLOT(onToolSwitched())); - ret = ret && connect(sceneHandle, SIGNAL(preferenceChanged()), m_flipConsole, - SLOT(onPreferenceChanged())); - m_flipConsole->onPreferenceChanged(); assert(ret); @@ -403,7 +405,8 @@ void ComboViewerPanel::showEvent(QShowEvent *) { //----------------------------------------------------------------------------- -void ComboViewerPanel::hideEvent(QHideEvent *) { +void ComboViewerPanel::hideEvent(QHideEvent *event) { + StyleShortcutSwitchablePanel::hideEvent(event); TApp *app = TApp::instance(); disconnect(app->getCurrentScene()); disconnect(app->getCurrentLevel()); @@ -781,3 +784,12 @@ bool ComboViewerPanel::isFrameAlreadyCached(int frame) { } //----------------------------------------------------------------------------- + +void ComboViewerPanel::onPreferenceChanged(const QString &prefName) { + // if no name specified (on showEvent), then process all updates + if (prefName == "BlankCount" || prefName == "BlankColor" || + prefName.isEmpty()) + m_flipConsole->onPreferenceChanged(); + + StyleShortcutSwitchablePanel::onPreferenceChanged(prefName); +} diff --git a/toonz/sources/toonz/comboviewerpane.h b/toonz/sources/toonz/comboviewerpane.h index 8f935ca..d7f2ea0 100644 --- a/toonz/sources/toonz/comboviewerpane.h +++ b/toonz/sources/toonz/comboviewerpane.h @@ -3,7 +3,7 @@ #ifndef COMBOVIEWER_PANE_INCLUDED #define COMBOVIEWER_PANE_INCLUDED -#include "pane.h" +#include "styleshortcutswitchablepanel.h" #include "sceneviewer.h" #include "toonzqt/intfield.h" #include "toonzqt/keyframenavigator.h" @@ -37,7 +37,8 @@ enum CV_Parts { }; //----------------------------------------------------------------------------- -class ComboViewerPanel final : public TPanel, public FlipConsoleOwner { +class ComboViewerPanel final : public StyleShortcutSwitchablePanel, + public FlipConsoleOwner { Q_OBJECT SceneViewer *m_sceneViewer; @@ -118,6 +119,8 @@ protected slots: void onSceneSwitched(); void enableFullPreview(bool enabled); void enableSubCameraPreview(bool enabled); + + void onPreferenceChanged(const QString &prefName) override; }; #endif diff --git a/toonz/sources/toonz/convertpopup.cpp b/toonz/sources/toonz/convertpopup.cpp index 97ac0e6..7ed582e 100644 --- a/toonz/sources/toonz/convertpopup.cpp +++ b/toonz/sources/toonz/convertpopup.cpp @@ -55,6 +55,8 @@ TEnv::IntVar ConvertPopupRemoveDot("ConvertPopupRemoveDot", 1); TEnv::IntVar ConvertPopupSaveToNopaint("ConvertPopupSaveToNopaint", 1); TEnv::IntVar ConvertPopupAppendDefaultPalette( "ConvertPopupAppendDefaultPalette", 0); +TEnv::IntVar ConvertPopupRemoveUnusedStyles("ConvertPopupRemoveUnusedStyles", + 0); //============================================================================= // convertPopup @@ -200,7 +202,8 @@ void ConvertPopup::Converter::convertLevel( // no AA source (retas) TPaletteP palette = popup->readUserProvidedPalette(); ImageUtils::convertNaa2Tlv(sourceFileFullPath, dstFileFullPath, from, to, - m_parent->m_notifier, palette.getPointer()); + m_parent->m_notifier, palette.getPointer(), + m_parent->m_removeUnusedStyles->isChecked()); } else { convertLevelWithConvert2Tlv(sourceFileFullPath); } @@ -441,6 +444,7 @@ ConvertPopup::ConvertPopup(bool specifyInput) m_removeDotBeforeFrameNumber->setChecked(ConvertPopupRemoveDot != 0); m_saveBackupToNopaint->setChecked(ConvertPopupSaveToNopaint != 0); m_appendDefaultPalette->setChecked(ConvertPopupAppendDefaultPalette != 0); + m_removeUnusedStyles->setChecked(ConvertPopupRemoveUnusedStyles != 0); //--- signal-slot connections qRegisterMetaType("TFilePath"); @@ -470,6 +474,9 @@ ConvertPopup::ConvertPopup(bool specifyInput) ret = ret && connect(m_convertFileFld, SIGNAL(pathChanged()), this, SLOT(onFileInChanged())); + // update unable/enable of checkboxes + onTlvModeSelected(m_tlvMode->currentText()); + assert(ret); } @@ -522,7 +529,7 @@ QFrame *ConvertPopup::createTlvSettings() { m_tlvMode = new QComboBox(); m_unpaintedFolderLabel = new QLabel(tr("Unpainted File Folder:")); m_unpaintedFolder = - new DVGui::FileField(0, QString(tr("Same as Painted")), true); + new DVGui::FileField(0, QString(tr("Same as Painted")), true, true); m_suffixLabel = new QLabel(tr(" Unpainted File Suffix:")); m_unpaintedSuffix = new DVGui::LineEdit("_np"); m_applyAutoclose = new QCheckBox(tr("Apply Autoclose")); @@ -531,8 +538,12 @@ QFrame *ConvertPopup::createTlvSettings() { m_appendDefaultPalette = new QCheckBox(tr("Append Default Palette")); m_antialias = new QComboBox(); m_antialiasIntensity = new DVGui::IntLineEdit(0, 50, 0, 100); - m_palettePath = new DVGui::FileField(0, QString(CreateNewPalette), true); - m_tolerance = new DVGui::IntLineEdit(0, 0, 0, 255); + m_palettePath = + new DVGui::FileField(0, QString(CreateNewPalette), true, true); + m_tolerance = new DVGui::IntLineEdit(0, 0, 0, 255); + + m_removeUnusedStyles = + new QCheckBox(tr("Remove Unused Styles from Input Palette")); m_unpaintedFolder->setFileMode(QFileDialog::DirectoryOnly); m_unpaintedSuffix->setMaximumWidth(40); @@ -585,8 +596,9 @@ QFrame *ConvertPopup::createTlvSettings() { Qt::AlignRight | Qt::AlignVCenter); gridLay->addWidget(m_tolerance, 4, 3); - gridLay->addWidget(m_appendDefaultPalette, 5, 1, 1, 3); - gridLay->addWidget(m_saveBackupToNopaint, 6, 1, 1, 3); + gridLay->addWidget(m_removeUnusedStyles, 5, 1, 1, 3); + gridLay->addWidget(m_appendDefaultPalette, 6, 1, 1, 3); + gridLay->addWidget(m_saveBackupToNopaint, 7, 1, 1, 3); } gridLay->setColumnStretch(0, 0); gridLay->setColumnStretch(1, 1); @@ -597,6 +609,9 @@ QFrame *ConvertPopup::createTlvSettings() { bool ret = true; ret = ret && connect(m_antialias, SIGNAL(currentIndexChanged(int)), this, SLOT(onAntialiasSelected(int))); + ret = ret && connect(m_palettePath, SIGNAL(pathChanged()), this, + SLOT(onPalettePathChanged())); + assert(ret); frame->setVisible(false); @@ -652,8 +667,13 @@ void ConvertPopup::onTlvModeSelected(const QString &tlvMode) { m_suffixLabel->setEnabled(usesTwoImages); m_unpaintedSuffix->setEnabled(usesTwoImages); m_antialias->setEnabled(TlvMode_PaintedFromNonAA != tlvMode); - m_palettePath->setEnabled(TlvMode_PaintedFromNonAA != tlvMode); + // m_palettePath->setEnabled(TlvMode_PaintedFromNonAA != tlvMode); m_tolerance->setEnabled(TlvMode_PaintedFromNonAA != tlvMode); + m_appendDefaultPalette->setEnabled(TlvMode_PaintedFromNonAA != tlvMode); + + m_removeUnusedStyles->setEnabled(TlvMode_PaintedFromNonAA == tlvMode && + m_palettePath->getPath() != + CreateNewPalette); m_saveBackupToNopaint->setEnabled(TlvMode_Unpainted == tlvMode); } @@ -1057,6 +1077,7 @@ void ConvertPopup::apply() { ConvertPopupSaveToNopaint = m_saveBackupToNopaint->isChecked() ? 1 : 0; ConvertPopupAppendDefaultPalette = m_appendDefaultPalette->isChecked() ? 1 : 0; + ConvertPopupRemoveUnusedStyles = m_removeUnusedStyles->isChecked() ? 1 : 0; // parameters are ok: close the dialog first close(); @@ -1174,6 +1195,14 @@ void ConvertPopup::onFormatChanged(const QString &ext) { //------------------------------------------------------------------- +void ConvertPopup::onPalettePathChanged() { + m_removeUnusedStyles->setEnabled( + m_tlvMode->currentText() == TlvMode_PaintedFromNonAA && + m_palettePath->getPath() != CreateNewPalette); +} + +//------------------------------------------------------------------- + bool ConvertPopup::isSaveTlvBackupToNopaintActive() { return m_fileFormat->currentText() == TlvExtension /*-- tlvが選択されている --*/ diff --git a/toonz/sources/toonz/convertpopup.h b/toonz/sources/toonz/convertpopup.h index cc4ff5a..b779a07 100644 --- a/toonz/sources/toonz/convertpopup.h +++ b/toonz/sources/toonz/convertpopup.h @@ -87,6 +87,7 @@ public slots: void onLevelConverted(const TFilePath &fullPath); void onFormatChanged(const QString &); + void onPalettePathChanged(); protected: Convert2Tlv *makeTlvConverter(const TFilePath &sourceFilePath); @@ -104,7 +105,7 @@ private: DVGui::ColorField *m_bgColorField; QFrame *m_tlvFrame; QCheckBox *m_applyAutoclose, *m_removeDotBeforeFrameNumber, - *m_saveBackupToNopaint, *m_appendDefaultPalette; + *m_saveBackupToNopaint, *m_appendDefaultPalette, *m_removeUnusedStyles; DVGui::CheckBox *m_skip; QComboBox *m_antialias, *m_tlvMode, *m_fileFormat; QLabel *m_bgColorLabel, *m_suffixLabel, *m_unpaintedFolderLabel, diff --git a/toonz/sources/toonz/filebrowser.cpp b/toonz/sources/toonz/filebrowser.cpp index f4f06e8..73f7f9a 100644 --- a/toonz/sources/toonz/filebrowser.cpp +++ b/toonz/sources/toonz/filebrowser.cpp @@ -148,7 +148,8 @@ QMutex levelFileMutex; inline bool isMultipleFrameType(std::string type) { return (type == "tlv" || type == "tzl" || type == "pli" || type == "mov" || - type == "avi" || type == "3gp"); + type == "avi" || type == "3gp" || type == "gif" || type == "mp4" || + type == "webm"); } //============================================================================= diff --git a/toonz/sources/toonz/filebrowserpopup.cpp b/toonz/sources/toonz/filebrowserpopup.cpp index 8bbda39..6ab99c7 100644 --- a/toonz/sources/toonz/filebrowserpopup.cpp +++ b/toonz/sources/toonz/filebrowserpopup.cpp @@ -485,17 +485,15 @@ bool LoadScenePopup::execute() { void LoadScenePopup::initFolder() { setInitialFolderByCurrentRoom(); } void LoadScenePopup::setInitialFolderByCurrentRoom() { - QString roomName = TApp::instance()->getCurrentRoomName(); + QString roomName = TApp::instance()->getCurrentRoomName(); + TProjectP project = TProjectManager::instance()->getCurrentProject(); TFilePath scenePath; if (roomName == "Cleanup" || roomName == "InknPaint") - scenePath = TProjectManager::instance()->getCurrentProject()->getFolder( - TProject::Drawings); + scenePath = project->getFolder(TProject::Drawings, true); else if (roomName == "PltEdit") - scenePath = TProjectManager::instance()->getCurrentProject()->getFolder( - TProject::Palettes); + scenePath = project->getFolder(TProject::Palettes, true); else - scenePath = TProjectManager::instance()->getCurrentProject()->getFolder( - TProject::Scenes); + scenePath = project->getFolder(TProject::Scenes, true); setFolder(scenePath); } diff --git a/toonz/sources/toonz/flipbook.h b/toonz/sources/toonz/flipbook.h index a116f3c..b9e13ee 100644 --- a/toonz/sources/toonz/flipbook.h +++ b/toonz/sources/toonz/flipbook.h @@ -179,7 +179,8 @@ public: FlipBook(QWidget *parent = 0, QString viewerTitle = QString(), UINT flipConsoleButtonMask = FlipConsole::cFullConsole & (~(FlipConsole::eFilledRaster | - FlipConsole::eDefineSubCamera)), + FlipConsole::eDefineSubCamera | + FlipConsole::eLocator)), UCHAR flags = 0, bool isColorModel = false); ~FlipBook(); void setLevel(const TFilePath &path, TPalette *palette = 0, int from = -1, diff --git a/toonz/sources/toonz/iocommand.cpp b/toonz/sources/toonz/iocommand.cpp index 00b9df1..2cb728d 100644 --- a/toonz/sources/toonz/iocommand.cpp +++ b/toonz/sources/toonz/iocommand.cpp @@ -1176,17 +1176,21 @@ bool IoCmd::saveSceneIfNeeded(QString msg) { QString question; question = QObject::tr( "%1: the current scene has been modified.\n" - "Do you want to save your changes?") + "What would you like to do?") .arg(msg); - int ret = DVGui::MsgBox(question, QObject::tr("Save"), - QObject::tr("Discard"), QObject::tr("Cancel"), 0); - if (ret == 0 || ret == 3) { + int ret = DVGui::MsgBox( + question, QObject::tr("Save All"), QObject::tr("Save Scene Only"), + QObject::tr("Discard Changes"), QObject::tr("Cancel"), 0); + if (ret == 0 || ret == 4) { // cancel (or closed message box window) return false; } else if (ret == 1) { + // save all + if (!IoCmd::saveAll()) return false; + } else if (ret == 2) { // save if (!IoCmd::saveScene()) return false; - } else if (ret == 2) { + } else if (ret == 3) { } isLevelOrSceneIsDirty = true; @@ -1203,21 +1207,25 @@ bool IoCmd::saveSceneIfNeeded(QString msg) { if (!dirtyResources.empty()) { QString question; - question = - msg + ":" + QObject::tr(" Following file(s) are modified.\n\n"); + question = msg + ":" + + QObject::tr(" The following file(s) have been modified.\n\n"); for (int i = 0; i < dirtyResources.size(); i++) { question += " " + dirtyResources[i] + "\n"; } - question += - QObject::tr("\nAre you sure to ") + msg + QObject::tr(" anyway ?"); + question += QObject::tr("\nWhat would you like to do? "); int ret = - DVGui::MsgBox(question, QObject::tr("OK"), QObject::tr("Cancel"), 0); - if (ret == 0 || ret == 2) { + DVGui::MsgBox(question, QObject::tr("Save Changes"), + msg + QObject::tr(" Anyway"), QObject::tr("Cancel"), 0); + if (ret == 0 || ret == 3) { // cancel (or closed message box window) return false; } else if (ret == 1) { - // ok + // save non scene files + IoCmd::saveNonSceneFiles(); + return false; + } else if (ret == 2) { + // quit } isLevelOrSceneIsDirty = true; @@ -1604,7 +1612,7 @@ bool IoCmd::saveLevel(TXshSimpleLevel *sl) { } //=========================================================================== -// IoCmd::saveSound(soundPath, soundColumn, overwrite) +// IoCmd::saveAll() //--------------------------------------------------------------------------- bool IoCmd::saveAll() { @@ -1627,6 +1635,26 @@ bool IoCmd::saveAll() { } //=========================================================================== +// IoCmd::saveNonSceneFiles() +//--------------------------------------------------------------------------- + +void IoCmd::saveNonSceneFiles() { + // try to save non scene files + + TApp *app = TApp::instance(); + ToonzScene *scene = app->getCurrentScene()->getScene(); + bool untitled = scene->isUntitled(); + SceneResources resources(scene, 0); + resources.save(scene->getScenePath()); + if (untitled) scene->setUntitled(); + resources.updatePaths(); + + // for update title bar + app->getCurrentLevel()->notifyLevelTitleChange(); + app->getCurrentPalette()->notifyPaletteTitleChanged(); +} + +//=========================================================================== // IoCmd::saveSound(soundPath, soundColumn, overwrite) //--------------------------------------------------------------------------- @@ -2738,3 +2766,12 @@ public: SaveAllCommandHandler() : MenuItemHandler(MI_SaveAll) {} void execute() override { IoCmd::saveAll(); } } saveAllCommandHandler; + +//============================================================================= +// Save all levels +//----------------------------------------------------------------------------- +class SaveAllLevelsCommandHandler : public MenuItemHandler { +public: + SaveAllLevelsCommandHandler() : MenuItemHandler(MI_SaveAllLevels) {} + void execute() { IoCmd::saveNonSceneFiles(); } +} saveAllLevelsCommandHandler; diff --git a/toonz/sources/toonz/iocommand.h b/toonz/sources/toonz/iocommand.h index 17f6fdb..2415e85 100644 --- a/toonz/sources/toonz/iocommand.h +++ b/toonz/sources/toonz/iocommand.h @@ -197,6 +197,8 @@ bool saveLevel(TXshSimpleLevel *sl); bool saveAll(); +void saveNonSceneFiles(); + bool saveSound(const TFilePath &fp, TXshSoundLevel *sc, bool overwrite); bool saveSound(TXshSoundLevel *sc); diff --git a/toonz/sources/toonz/locatorpopup.cpp b/toonz/sources/toonz/locatorpopup.cpp new file mode 100644 index 0000000..434ca52 --- /dev/null +++ b/toonz/sources/toonz/locatorpopup.cpp @@ -0,0 +1,117 @@ +#include "locatorpopup.h" + +// TnzLib includes +#include "toonz/txshlevelhandle.h" +#include "toonz/tframehandle.h" +#include "toonz/preferences.h" +#include "toonz/stage2.h" + +// Tnz6 includes +#include "tapp.h" +#include "sceneviewer.h" + +#include + +LocatorPopup::LocatorPopup(QWidget *parent) + : QDialog(parent), m_initialZoom(true) { + m_viewer = new SceneViewer(NULL); + m_viewer->setParent(parent); + m_viewer->setIsLocator(); + + //---- layout + QVBoxLayout *mainLayout = new QVBoxLayout(); + mainLayout->setMargin(0); + mainLayout->addWidget(m_viewer, 1); + setLayout(mainLayout); + + bool ret = true; + // When zoom changed, change window title. + ret = connect(m_viewer, SIGNAL(onZoomChanged()), SLOT(changeWindowTitle())); + ret = ret && + connect(m_viewer, SIGNAL(previewToggled()), SLOT(changeWindowTitle())); + assert(ret); + + resize(400, 400); +} + +//----------------------------------------------------------------------------- + +void LocatorPopup::onChangeViewAff(const TPointD &pos) { + TAffine curAff = m_viewer->getSceneMatrix(); + TAffine newAff(curAff.a11, 0, -pos.x * curAff.a11, 0, curAff.a22, + -pos.y * curAff.a22); + m_viewer->setViewMatrix(newAff, 0); + m_viewer->setViewMatrix(newAff, 1); + m_viewer->update(); +} + +//----------------------------------------------------------------------------- + +void LocatorPopup::showEvent(QShowEvent *) { + // zoom the locator for the first time + if (m_initialZoom) { + for (int z = 0; z < 4; z++) m_viewer->zoomQt(true, false); + m_initialZoom = false; + } + + TApp *app = TApp::instance(); + TFrameHandle *frameHandle = app->getCurrentFrame(); + TXshLevelHandle *levelHandle = app->getCurrentLevel(); + + bool ret = true; + ret = ret && connect(frameHandle, SIGNAL(frameSwitched()), this, + SLOT(changeWindowTitle())); + ret = ret && connect(levelHandle, SIGNAL(xshLevelSwitched(TXshLevel *)), this, + SLOT(changeWindowTitle())); + assert(ret); + + changeWindowTitle(); +} + +//----------------------------------------------------------------------------- + +void LocatorPopup::hideEvent(QHideEvent *) { + TApp *app = TApp::instance(); + disconnect(app->getCurrentLevel()); + disconnect(app->getCurrentFrame()); +} + +//----------------------------------------------------------------------------- + +void LocatorPopup::changeWindowTitle() { + TApp *app = TApp::instance(); + // put the titlebar texts in this string + QString name = tr("Locator"); + + bool showZoomFactor = false; + + // if the frame type is "scene editing" + if (app->getCurrentFrame()->isEditingScene()) { + if (m_viewer->isPreviewEnabled()) showZoomFactor = true; + + // If the current level exists and some option is set in the preference, + // set the zoom value to the current level's dpi + else if (Preferences::instance() + ->isActualPixelViewOnSceneEditingModeEnabled() && + app->getCurrentLevel()->getSimpleLevel() && + !CleanupPreviewCheck::instance() + ->isEnabled() // cleanup preview must be OFF + && + !CameraTestCheck::instance() + ->isEnabled()) // camera test mode must be OFF neither + showZoomFactor = true; + } + // if the frame type is "level editing" + else { + TXshLevel *level = app->getCurrentLevel()->getLevel(); + if (level) showZoomFactor = true; + } + + if (showZoomFactor) { + name = name + " Zoom : " + + QString::number((int)(100.0 * sqrt(m_viewer->getViewMatrix().det()) * + m_viewer->getDpiFactor())) + + "%"; + } + setWindowTitle(name); +} \ No newline at end of file diff --git a/toonz/sources/toonz/locatorpopup.h b/toonz/sources/toonz/locatorpopup.h new file mode 100644 index 0000000..2dc3448 --- /dev/null +++ b/toonz/sources/toonz/locatorpopup.h @@ -0,0 +1,34 @@ +#pragma once + +#ifndef LOCATORPOPUP_H +#define LOCATORPOPUP_H + +#include "tgeometry.h" +#include + +class SceneViewer; + +//============================================================================= +// LoactorPopup +//----------------------------------------------------------------------------- + +class LocatorPopup : public QDialog { + Q_OBJECT + SceneViewer* m_viewer; + bool m_initialZoom; + +public: + LocatorPopup(QWidget* parent = 0); + SceneViewer* viewer() { return m_viewer; } + + void onChangeViewAff(const TPointD& curPos); + +protected: + void showEvent(QShowEvent*); + void hideEvent(QHideEvent*); + +protected slots: + void changeWindowTitle(); +}; + +#endif \ No newline at end of file diff --git a/toonz/sources/toonz/magpiefileimportpopup.cpp b/toonz/sources/toonz/magpiefileimportpopup.cpp index 5134d72..72a90ab 100644 --- a/toonz/sources/toonz/magpiefileimportpopup.cpp +++ b/toonz/sources/toonz/magpiefileimportpopup.cpp @@ -124,7 +124,7 @@ MagpieFileImportPopup::MagpieFileImportPopup() FlipConsole::eRed | FlipConsole::eGreen | FlipConsole::eBlue | FlipConsole::eMatte | FlipConsole::eDefineSubCamera | FlipConsole::eDefineLoadBox | FlipConsole::eUseLoadBox | - FlipConsole::eFilledRaster)); + FlipConsole::eFilledRaster | FlipConsole::eLocator)); m_flipbook = new FlipBook(this, tr("Import Magpie File"), buttonMask); m_flipbook->setFixedHeight(250); frameLayout->addWidget(m_flipbook); diff --git a/toonz/sources/toonz/mainwindow.cpp b/toonz/sources/toonz/mainwindow.cpp index e0acfec..1a070a6 100644 --- a/toonz/sources/toonz/mainwindow.cpp +++ b/toonz/sources/toonz/mainwindow.cpp @@ -12,6 +12,7 @@ #include "iocommand.h" #include "tapp.h" #include "comboviewerpane.h" +#include "startuppopup.h" // TnzTools includes #include "tools/toolcommandids.h" @@ -1275,6 +1276,12 @@ void MainWindow::onMenuCheckboxChanged() { void MainWindow::showEvent(QShowEvent *event) { getCurrentRoom()->layout()->setEnabled(true); // See main function in // main.cpp + if (Preferences::instance()->isStartupPopupEnabled() && + !m_startupPopupShown) { + StartupPopup *startupPopup = new StartupPopup(); + startupPopup->show(); + m_startupPopupShown = true; + } } extern const char *applicationName; extern const char *applicationVersion; @@ -1558,9 +1565,9 @@ QAction *MainWindow::createToolAction(const char *id, const char *iconName, void MainWindow::defineActions() { createMenuFileAction(MI_NewScene, tr("&New Scene"), "Ctrl+N"); createMenuFileAction(MI_LoadScene, tr("&Load Scene..."), "Ctrl+L"); - createMenuFileAction(MI_SaveScene, tr("&Save Scene"), "Ctrl+S"); - createMenuFileAction(MI_SaveSceneAs, tr("&Save Scene As..."), "Ctrl+Shift+S"); - createMenuFileAction(MI_SaveAll, tr("&Save All"), ""); + createMenuFileAction(MI_SaveScene, tr("&Save Scene"), "Ctrl+Shift+S"); + createMenuFileAction(MI_SaveSceneAs, tr("&Save Scene As..."), ""); + createMenuFileAction(MI_SaveAll, tr("&Save All"), "Ctrl+S"); createMenuFileAction(MI_RevertScene, tr("&Revert Scene"), ""); QAction *act = CommandManager::instance()->getAction(MI_RevertScene); @@ -1576,9 +1583,10 @@ void MainWindow::defineActions() { ""); createMenuFileAction(MI_ClearRecentLevel, tr("&Clear Recent level File List"), ""); - createMenuFileAction(MI_NewLevel, tr("&New Level..."), ""); + createMenuFileAction(MI_NewLevel, tr("&New Level..."), "Alt+N"); createMenuFileAction(MI_LoadLevel, tr("&Load Level..."), ""); createMenuFileAction(MI_SaveLevel, tr("&Save Level"), ""); + createMenuFileAction(MI_SaveAllLevels, tr("&Save All Levels"), ""); createMenuFileAction(MI_SaveLevelAs, tr("&Save Level As..."), ""); createMenuFileAction(MI_ExportLevel, tr("&Export Level..."), ""); createMenuFileAction(MI_ConvertFileWithInput, tr("&Convert File..."), ""); @@ -1590,9 +1598,10 @@ void MainWindow::defineActions() { createMenuFileAction(MI_ProjectSettings, tr("&Project Settings..."), ""); createMenuFileAction(MI_SaveDefaultSettings, tr("&Save Default Settings"), ""); - createMenuFileAction(MI_OutputSettings, tr("&Output Settings..."), ""); + createMenuFileAction(MI_OutputSettings, tr("&Output Settings..."), "Ctrl+O"); createMenuFileAction(MI_PreviewSettings, tr("&Preview Settings..."), ""); - createMenuFileAction(MI_Render, tr("&Render"), ""); + createMenuFileAction(MI_Render, tr("&Render"), "Ctrl+Shift+R"); + createMenuFileAction(MI_FastRender, tr("&Fast Render to MP4"), "Alt+R"); createMenuFileAction(MI_Preview, tr("&Preview"), "Ctrl+R"); createRightClickMenuAction(MI_SavePreviewedFrames, tr("&Save Previewed Frames"), ""); @@ -1607,13 +1616,13 @@ void MainWindow::defineActions() { MI_FreezePreview, tr("Freeze Preview"), tr("Unfreeze Preview")); // createAction(MI_SavePreview, "&Save Preview", ""); createRightClickMenuAction(MI_SavePreset, tr("&Save As Preset"), ""); - createMenuFileAction(MI_Preferences, tr("&Preferences..."), ""); + createMenuFileAction(MI_Preferences, tr("&Preferences..."), "Ctrl+U"); createMenuFileAction(MI_ShortcutPopup, tr("&Configure Shortcuts..."), ""); createMenuFileAction(MI_PrintXsheet, tr("&Print Xsheet"), ""); createMenuFileAction("MI_RunScript", tr("Run Script..."), ""); createMenuFileAction("MI_OpenScriptConsole", tr("Open Script Console..."), ""); - createMenuFileAction(MI_Print, tr("&Print Current Frame..."), ""); + createMenuFileAction(MI_Print, tr("&Print Current Frame..."), "Ctrl+P"); createMenuFileAction(MI_Quit, tr("&Quit"), "Ctrl+Q"); #ifndef NDEBUG createMenuFileAction("MI_ReloadStyle", tr("Reload qss"), ""); @@ -1639,10 +1648,14 @@ void MainWindow::defineActions() { createRightClickMenuAction(MI_PasteNames, tr("Paste Name"), ""); createRightClickMenuAction(MI_GetColorFromStudioPalette, tr("Get Color from Studio Palette"), ""); + createRightClickMenuAction(MI_ToggleLinkToStudioPalette, + tr("Toggle Link to Studio Palette"), ""); + createRightClickMenuAction(MI_RemoveReferenceToStudioPalette, + tr("Remove Reference to Studio Palette"), ""); createMenuEditAction(MI_Clear, tr("&Delete"), "Delete"); createMenuEditAction(MI_Insert, tr("&Insert"), "Ins"); createMenuEditAction(MI_Group, tr("&Group"), "Ctrl+G"); - createMenuEditAction(MI_Ungroup, tr("&Ungroup"), ""); + createMenuEditAction(MI_Ungroup, tr("&Ungroup"), "Ctrl+Shift+G"); createMenuEditAction(MI_BringToFront, tr("&Bring to Front"), "Ctrl+]"); createMenuEditAction(MI_BringForward, tr("&Bring Forward"), "]"); createMenuEditAction(MI_SendBack, tr("&Send Back"), "Ctrl+["); @@ -1677,7 +1690,7 @@ void MainWindow::defineActions() { MenuScanCleanupCommandType); CameraTestCheck::instance()->setToggle(toggle); - createToggle(MI_OpacityCheck, tr("&Opacity Check"), "1", false, + createToggle(MI_OpacityCheck, tr("&Opacity Check"), "Alt+1", false, MenuScanCleanupCommandType); createMenuScanCleanupAction(MI_Cleanup, tr("&Cleanup"), ""); @@ -1747,8 +1760,8 @@ void MainWindow::defineActions() { createMenuCellsAction(MI_Increment, tr("&Autoexpose"), ""); createMenuCellsAction(MI_Dup, tr("&Repeat..."), ""); createMenuCellsAction(MI_ResetStep, tr("&Reset Step"), ""); - createMenuCellsAction(MI_IncreaseStep, tr("&Increase Step"), ""); - createMenuCellsAction(MI_DecreaseStep, tr("&Decrease Step"), ""); + createMenuCellsAction(MI_IncreaseStep, tr("&Increase Step"), "'"); + createMenuCellsAction(MI_DecreaseStep, tr("&Decrease Step"), ";"); createMenuCellsAction(MI_Step2, tr("&Step 2"), ""); createMenuCellsAction(MI_Step3, tr("&Step 3"), ""); createMenuCellsAction(MI_Step4, tr("&Step 4"), ""); @@ -1762,26 +1775,26 @@ void MainWindow::defineActions() { createMenuCellsAction(MI_Autorenumber, tr("&Autorenumber"), ""); createMenuCellsAction(MI_CloneLevel, tr("&Clone"), ""); createMenuCellsAction(MI_DrawingSubForward, - tr("Drawing Substitution Forward"), "."); + tr("Drawing Substitution Forward"), "W"); createMenuCellsAction(MI_DrawingSubBackward, - tr("Drawing Substitution Backward"), ","); + tr("Drawing Substitution Backward"), "Q"); createMenuCellsAction(MI_DrawingSubGroupForward, - tr("Similar Drawing Substitution Forward"), "Ctrl+."); + tr("Similar Drawing Substitution Forward"), "Alt+W"); createMenuCellsAction(MI_DrawingSubGroupBackward, - tr("Similar Drawing Substitution Backward"), "Ctrl+,"); + tr("Similar Drawing Substitution Backward"), "Alt+Q"); createMenuCellsAction(MI_Reframe1, tr("1's"), ""); createMenuCellsAction(MI_Reframe2, tr("2's"), ""); createMenuCellsAction(MI_Reframe3, tr("3's"), ""); createMenuCellsAction(MI_Reframe4, tr("4's"), ""); - createRightClickMenuAction(MI_SetKeyframes, tr("&Set Key"), ""); + createRightClickMenuAction(MI_SetKeyframes, tr("&Set Key"), "Z"); createToggle(MI_ViewCamera, tr("&Camera Box"), "", ViewCameraToggleAction ? 1 : 0, MenuViewCommandType); createToggle(MI_ViewTable, tr("&Table"), "", ViewTableToggleAction ? 1 : 0, MenuViewCommandType); - createToggle(MI_FieldGuide, tr("&Field Guide"), "", + createToggle(MI_FieldGuide, tr("&Field Guide"), "Shift+G", FieldGuideToggleAction ? 1 : 0, MenuViewCommandType); createToggle(MI_ViewBBox, tr("&Raster Bounding Box"), "", ViewBBoxToggleAction ? 1 : 0, MenuViewCommandType); @@ -1840,18 +1853,16 @@ void MainWindow::defineActions() { createToggle(MI_Link, tr("Link Flipbooks"), "", LinkToggleAction ? 1 : 0, MenuViewCommandType); - createPlaybackAction(MI_Play, tr("Play"), ""); - createPlaybackAction(MI_Loop, tr("Loop"), ""); + createPlaybackAction(MI_Play, tr("Play"), "P"); + createPlaybackAction(MI_Loop, tr("Loop"), "L"); createPlaybackAction(MI_Pause, tr("Pause"), ""); - createPlaybackAction(MI_FirstFrame, tr("First Frame"), ""); - createPlaybackAction(MI_LastFrame, tr("Last Frame"), ""); - createPlaybackAction(MI_PrevFrame, tr("Previous Frame"), "Shift+A"); - createPlaybackAction(MI_NextFrame, tr("Next Frame"), "Shift+S"); - - createAction(MI_NextDrawing, tr("Next Drawing"), "Shift+X", - PlaybackCommandType); - createAction(MI_PrevDrawing, tr("Prev Drawing"), "Shift+Z", - PlaybackCommandType); + createPlaybackAction(MI_FirstFrame, tr("First Frame"), "Alt+,"); + createPlaybackAction(MI_LastFrame, tr("Last Frame"), "Alt+."); + createPlaybackAction(MI_PrevFrame, tr("Previous Frame"), "Shift+,"); + createPlaybackAction(MI_NextFrame, tr("Next Frame"), "Shift+."); + + createAction(MI_NextDrawing, tr("Next Drawing"), ".", PlaybackCommandType); + createAction(MI_PrevDrawing, tr("Prev Drawing"), ",", PlaybackCommandType); createAction(MI_NextStep, tr("Next Step"), "", PlaybackCommandType); createAction(MI_PrevStep, tr("Prev Step"), "", PlaybackCommandType); @@ -1866,7 +1877,7 @@ void MainWindow::defineActions() { createViewerAction(MI_CompareToSnapshot, tr("Compare to Snapshot"), ""); createFillAction(MI_AutoFillToggle, - tr("Toggle Autofill on Current Palette Color"), ""); + tr("Toggle Autofill on Current Palette Color"), "Shift+A"); toggle = createToggle(MI_DockingCheck, tr("&Lock Room Panes"), "", @@ -1908,7 +1919,7 @@ void MainWindow::defineActions() { // createAction(MI_Export, "Export", "Ctrl+E"); createMenuWindowsAction(MI_OpenComboViewer, tr("&ComboViewer"), ""); - createMenuWindowsAction(MI_OpenHistoryPanel, tr("&History"), ""); + createMenuWindowsAction(MI_OpenHistoryPanel, tr("&History"), "Ctrl+H"); createMenuWindowsAction(MI_ResetRoomLayout, tr("&Reset to Default Rooms"), ""); @@ -1917,10 +1928,10 @@ void MainWindow::defineActions() { tr("Toggle Main Window's Full Screen Mode"), "Ctrl+`"); createMenuWindowsAction(MI_About, tr("&About OpenToonz..."), ""); - + createMenuWindowsAction(MI_StartupPopup, tr("&Startup Popup..."), "Alt+S"); createRightClickMenuAction(MI_BlendColors, tr("&Blend colors"), ""); - createToggle(MI_OnionSkin, tr("Onion Skin Toggle"), "//", false, + createToggle(MI_OnionSkin, tr("Onion Skin Toggle"), "/", false, RightClickMenuCommandType); createToggle(MI_ZeroThick, tr("Zero Thick Lines"), "Shift+/", false, RightClickMenuCommandType); @@ -1991,12 +2002,16 @@ void MainWindow::defineActions() { createRightClickMenuAction(MI_DisableAllColumns, tr("OFF All"), ""); createRightClickMenuAction(MI_DisableSelectedColumns, tr("OFF Selected"), ""); createRightClickMenuAction(MI_SwapEnabledColumns, tr("Swap ON/OFF"), ""); - createRightClickMenuAction(MI_LockThisColumnOnly, tr("Lock This Only"), ""); - createRightClickMenuAction(MI_LockSelectedColumns, tr("Lock Selected"), ""); - createRightClickMenuAction(MI_LockAllColumns, tr("Lock All"), ""); + createRightClickMenuAction(MI_LockThisColumnOnly, tr("Lock This Only"), + "Shift+L"); + createRightClickMenuAction(MI_LockSelectedColumns, tr("Lock Selected"), + "Ctrl+Shift+L"); + createRightClickMenuAction(MI_LockAllColumns, tr("Lock All"), + "Ctrl+Alt+Shift+L"); createRightClickMenuAction(MI_UnlockSelectedColumns, tr("Unlock Selected"), - ""); - createRightClickMenuAction(MI_UnlockAllColumns, tr("Unlock All"), ""); + "Ctrl+Shift+U"); + createRightClickMenuAction(MI_UnlockAllColumns, tr("Unlock All"), + "Ctrl+Alt+Shift+U"); createRightClickMenuAction(MI_ToggleColumnLocks, tr("Swap Lock/Unlock"), ""); /*-- カレントカラムの右側のカラムを全て非表示にするコマンド --*/ createRightClickMenuAction(MI_DeactivateUpperColumns, @@ -2012,31 +2027,32 @@ void MainWindow::defineActions() { createToolAction(T_Eraser, "eraser", tr("Eraser Tool"), "A"); createToolAction(T_Tape, "tape", tr("Tape Tool"), "T"); createToolAction(T_StylePicker, "stylepicker", tr("Style Picker Tool"), "K"); - createToolAction(T_RGBPicker, "RGBpicker", tr("RGB Picker Tool"), ""); + createToolAction(T_RGBPicker, "RGBpicker", tr("RGB Picker Tool"), "R"); createToolAction(T_ControlPointEditor, "controlpointeditor", tr("Control Point Editor Tool"), "C"); - createToolAction(T_Pinch, "pinch", tr("Pinch Tool"), "P"); + createToolAction(T_Pinch, "pinch", tr("Pinch Tool"), "M"); createToolAction(T_Pump, "pump", tr("Pump Tool"), ""); createToolAction(T_Magnet, "magnet", tr("Magnet Tool"), ""); createToolAction(T_Bender, "bender", tr("Bender Tool"), ""); createToolAction(T_Iron, "iron", tr("Iron Tool"), ""); createToolAction(T_Cutter, "cutter", tr("Cutter Tool"), ""); - createToolAction(T_Skeleton, "skeleton", tr("Skeleton Tool"), ""); + createToolAction(T_Skeleton, "skeleton", tr("Skeleton Tool"), "V"); createToolAction(T_Tracker, "tracker", tr("Tracker Tool"), ""); - createToolAction(T_Hook, "hook", tr("Hook Tool"), ""); + createToolAction(T_Hook, "hook", tr("Hook Tool"), "O"); createToolAction(T_Zoom, "zoom", tr("Zoom Tool"), "Shift+Space"); createToolAction(T_Rotate, "rotate", tr("Rotate Tool"), "Ctrl+Space"); createToolAction(T_Hand, "hand", tr("Hand Tool"), "Space"); - createToolAction(T_Plastic, "plastic", tr("Plastic Tool"), ""); + createToolAction(T_Plastic, "plastic", tr("Plastic Tool"), "X"); createToolAction(T_Ruler, "ruler", tr("Ruler Tool"), ""); createToolAction(T_Finger, "finger", tr("Finger Tool"), ""); createViewerAction(V_ZoomIn, tr("Zoom In"), "+"); createViewerAction(V_ZoomOut, tr("Zoom Out"), "-"); - createViewerAction(V_ZoomReset, tr("Reset View"), "0"); - createViewerAction(V_ZoomFit, tr("Fit to Window"), ""); + createViewerAction(V_ZoomReset, tr("Reset View"), "Alt+0"); + createViewerAction(V_ZoomFit, tr("Fit to Window"), "Alt+9"); createViewerAction(V_ActualPixelSize, tr("Actual Pixel Size"), "N"); - createViewerAction(V_ShowHideFullScreen, tr("Show//Hide Full Screen"), ""); + createViewerAction(V_ShowHideFullScreen, tr("Show//Hide Full Screen"), + "Alt+F"); CommandManager::instance()->setToggleTexts(V_ShowHideFullScreen, tr("Full Screen Mode"), tr("Exit Full Screen Mode")); @@ -2046,13 +2062,13 @@ void MainWindow::defineActions() { createToolOptionsAction("A_ToolOption_GlobalKey", tr("Global Key"), ""); createToolOptionsAction("A_IncreaseMaxBrushThickness", - tr("Brush size - Increase max"), ""); + tr("Brush size - Increase max"), "I"); createToolOptionsAction("A_DecreaseMaxBrushThickness", - tr("Brush size - Decrease max"), ""); + tr("Brush size - Decrease max"), "U"); createToolOptionsAction("A_IncreaseMinBrushThickness", - tr("Brush size - Increase min"), ""); + tr("Brush size - Increase min"), "J"); createToolOptionsAction("A_DecreaseMinBrushThickness", - tr("Brush size - Decrease min"), ""); + tr("Brush size - Decrease min"), "H"); createToolOptionsAction("A_IncreaseBrushHardness", tr("Brush hardness - Increase"), ""); createToolOptionsAction("A_DecreaseBrushHardness", @@ -2071,7 +2087,7 @@ void MainWindow::defineActions() { createToolOptionsAction("A_ToolOption_PreserveThickness", tr("Preserve Thickness"), ""); createToolOptionsAction("A_ToolOption_PressureSensitivity", - tr("Pressure Sensitivity"), ""); + tr("Pressure Sensitivity"), "Shift+P"); createToolOptionsAction("A_ToolOption_SegmentInk", tr("Segment Ink"), "F8"); createToolOptionsAction("A_ToolOption_Selective", tr("Selective"), "F7"); createToolOptionsAction("A_ToolOption_Smooth", tr("Smooth"), ""); diff --git a/toonz/sources/toonz/mainwindow.h b/toonz/sources/toonz/mainwindow.h index 8efc118..4eb088a 100644 --- a/toonz/sources/toonz/mainwindow.h +++ b/toonz/sources/toonz/mainwindow.h @@ -67,6 +67,7 @@ class MainWindow final : public QMainWindow { Q_OBJECT bool m_saveSettingsOnQuit; + bool m_startupPopupShown = false; int m_oldRoomIndex; QString m_currentRoomsChoice; UpdateChecker *m_updateChecker; @@ -212,6 +213,7 @@ signals: }; class RecentFiles { + friend class StartupPopup; QList m_recentScenes; QList m_recentLevels; QList m_recentFlipbookImages; diff --git a/toonz/sources/toonz/menubar.cpp b/toonz/sources/toonz/menubar.cpp index 512c136..97b4398 100644 --- a/toonz/sources/toonz/menubar.cpp +++ b/toonz/sources/toonz/menubar.cpp @@ -1077,6 +1077,7 @@ QMenuBar *StackedMenuBar::createFullMenuBar() { fileMenu->addSeparator(); addMenuItem(fileMenu, MI_NewLevel); addMenuItem(fileMenu, MI_LoadLevel); + addMenuItem(fileMenu, MI_SaveAllLevels); addMenuItem(fileMenu, MI_SaveLevel); addMenuItem(fileMenu, MI_SaveLevelAs); addMenuItem(fileMenu, MI_ExportLevel); @@ -1098,6 +1099,7 @@ QMenuBar *StackedMenuBar::createFullMenuBar() { fileMenu->addSeparator(); addMenuItem(fileMenu, MI_OutputSettings); addMenuItem(fileMenu, MI_Render); + addMenuItem(fileMenu, MI_FastRender); // addMenuItem(fileMenu, MI_SavePreviewedFrames); fileMenu->addSeparator(); addMenuItem(fileMenu, MI_PrintXsheet); @@ -1343,6 +1345,7 @@ QMenuBar *StackedMenuBar::createFullMenuBar() { //---Help Menu QMenu *helpMenu = addMenu(tr("Help"), fullMenuBar); + addMenuItem(helpMenu, MI_StartupPopup); addMenuItem(helpMenu, MI_About); return fullMenuBar; diff --git a/toonz/sources/toonz/menubarcommandids.h b/toonz/sources/toonz/menubarcommandids.h index ac9a5bf..0b7f96b 100644 --- a/toonz/sources/toonz/menubarcommandids.h +++ b/toonz/sources/toonz/menubarcommandids.h @@ -16,6 +16,7 @@ #define MI_SaveScene "MI_SaveScene" #define MI_SaveSceneAs "MI_SaveSceneAs" #define MI_SaveAll "MI_SaveAll" +#define MI_SaveAllLevels "MI_SaveAllLevels" #define MI_RevertScene "MI_RevertScene" #define MI_LoadSubSceneFile "MI_LoadSubSceneFile" @@ -40,6 +41,7 @@ #define MI_OutputSettings "MI_OutputSettings" #define MI_PreviewSettings "MI_PreviewSettings" #define MI_Render "MI_Render" +#define MI_FastRender "MI_FastRender" #define MI_Preview "MI_Preview" #define MI_RegeneratePreview "MI_RegeneratePreview" #define MI_RegenerateFramePr "MI_RegenerateFramePr" @@ -310,5 +312,6 @@ #define MI_PreviewFx "MI_PreviewFx" #define MI_About "MI_About" +#define MI_StartupPopup "MI_StartupPopup" #define MI_PencilTest "MI_PencilTest" #endif diff --git a/toonz/sources/toonz/penciltestpopup.cpp b/toonz/sources/toonz/penciltestpopup.cpp index 2a74e88..02fb1b2 100644 --- a/toonz/sources/toonz/penciltestpopup.cpp +++ b/toonz/sources/toonz/penciltestpopup.cpp @@ -65,6 +65,11 @@ #include #include #include +#include + +#ifdef _WIN32 +#include +#endif using namespace DVGui; @@ -305,6 +310,90 @@ int letterToNum(QChar appendix) { return 0; } +#ifdef _WIN32 +void openCaptureFilterSettings(const QWidget* parent, + const QString& cameraName) { + HRESULT hr; + + ICreateDevEnum* createDevEnum = NULL; + IEnumMoniker* enumMoniker = NULL; + IMoniker* moniker = NULL; + + IBaseFilter* deviceFilter; + + ISpecifyPropertyPages* specifyPropertyPages; + CAUUID cauuid; + // set parent's window handle in order to make the dialog modal + HWND ghwndApp = (HWND)(parent->winId()); + + // initialize COM + CoInitialize(NULL); + + // get device list + CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, + IID_ICreateDevEnum, (PVOID*)&createDevEnum); + + // create EnumMoniker + createDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, + &enumMoniker, 0); + if (enumMoniker == NULL) { + // if no connected devices found + return; + } + + // reset EnumMoniker + enumMoniker->Reset(); + + // find target camera + ULONG fetched = 0; + bool isCameraFound = false; + while (hr = enumMoniker->Next(1, &moniker, &fetched), hr == S_OK) { + // get friendly name (= device name) of the camera + IPropertyBag* pPropertyBag; + moniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pPropertyBag); + VARIANT var; + var.vt = VT_BSTR; + VariantInit(&var); + + pPropertyBag->Read(L"FriendlyName", &var, 0); + + QString deviceName = QString::fromWCharArray(var.bstrVal); + + VariantClear(&var); + + if (deviceName == cameraName) { + // bind monkier to the filter + moniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&deviceFilter); + + // release moniker etc. + moniker->Release(); + enumMoniker->Release(); + createDevEnum->Release(); + + isCameraFound = true; + break; + } + } + + // if no matching camera found + if (!isCameraFound) return; + + // open capture filter popup + hr = deviceFilter->QueryInterface(IID_ISpecifyPropertyPages, + (void**)&specifyPropertyPages); + if (hr == S_OK) { + hr = specifyPropertyPages->GetPages(&cauuid); + + hr = OleCreatePropertyFrame(ghwndApp, 30, 30, NULL, 1, + (IUnknown**)&deviceFilter, cauuid.cElems, + (GUID*)cauuid.pElems, 0, 0, NULL); + + CoTaskMemFree(cauuid.pElems); + specifyPropertyPages->Release(); + } +} +#endif + } // namespace //============================================================================= @@ -547,6 +636,12 @@ PencilTestPopup::PencilTestPopup() m_captureButton = new QPushButton(tr("Capture\n[Return key]"), this); QPushButton* closeButton = new QPushButton(tr("Close"), this); + +#ifdef _WIN32 + m_captureFilterSettingsBtn = new QPushButton(this); +#else + m_captureFilterSettingsBtn = 0; +#endif //---- m_resolutionCombo->setMaximumWidth(fontMetrics().width("0000 x 0000") + 25); @@ -598,6 +693,14 @@ PencilTestPopup::PencilTestPopup() m_captureButton->setIcon(style.standardIcon(QStyle::SP_DialogOkButton)); m_captureButton->setIconSize(QSize(30, 30)); + if (m_captureFilterSettingsBtn) { + m_captureFilterSettingsBtn->setObjectName("GearButton"); + m_captureFilterSettingsBtn->setFixedSize(23, 23); + m_captureFilterSettingsBtn->setIconSize(QSize(15, 15)); + m_captureFilterSettingsBtn->setToolTip( + tr("Video Capture Filter Settings...")); + } + //---- layout ---- QHBoxLayout* mainLay = new QHBoxLayout(); mainLay->setMargin(0); @@ -617,6 +720,12 @@ PencilTestPopup::PencilTestPopup() camLay->addSpacing(10); camLay->addWidget(new QLabel(tr("Resolution:"), this), 0); camLay->addWidget(m_resolutionCombo, 1); + + if (m_captureFilterSettingsBtn) { + camLay->addSpacing(10); + camLay->addWidget(m_captureFilterSettingsBtn); + } + camLay->addStretch(0); } leftLay->addLayout(camLay, 0); @@ -788,6 +897,9 @@ PencilTestPopup::PencilTestPopup() ret = ret && connect(closeButton, SIGNAL(clicked()), this, SLOT(reject())); ret = ret && connect(m_captureButton, SIGNAL(clicked(bool)), this, SLOT(onCaptureButtonClicked(bool))); + if (m_captureFilterSettingsBtn) + ret = ret && connect(m_captureFilterSettingsBtn, SIGNAL(pressed()), this, + SLOT(onCaptureFilterSettingsBtnPressed())); assert(ret); refreshCameraList(); @@ -1403,4 +1515,20 @@ bool PencilTestPopup::importImage(QImage& image) { //----------------------------------------------------------------------------- +void PencilTestPopup::onCaptureFilterSettingsBtnPressed() { + if (!m_currentCamera || m_deviceName.isNull()) return; + + QList cameras = QCameraInfo::availableCameras(); + for (int c = 0; c < cameras.size(); c++) { + if (cameras.at(c).deviceName() == m_deviceName) { +#ifdef _WIN32 + openCaptureFilterSettings(this, cameras.at(c).description()); +#endif + return; + } + } +} + +//----------------------------------------------------------------------------- + OpenPopupCommandHandler openPencilTestPopup(MI_PencilTest); \ No newline at end of file diff --git a/toonz/sources/toonz/penciltestpopup.h b/toonz/sources/toonz/penciltestpopup.h index 94b1172..0ff31f4 100644 --- a/toonz/sources/toonz/penciltestpopup.h +++ b/toonz/sources/toonz/penciltestpopup.h @@ -21,6 +21,7 @@ class QVideoFrame; class QTimer; class QIntValidator; class QRegExpValidator; +class QPushButton; namespace DVGui { class FileField; @@ -147,6 +148,9 @@ class PencilTestPopup : public DVGui::Dialog { QImage m_whiteBGImg; + // used only for Windows + QPushButton* m_captureFilterSettingsBtn; + int m_timerId; QString m_cacheImagePath; bool m_captureWhiteBGCue; @@ -183,6 +187,7 @@ protected slots: void onCountDown(); void onCaptureButtonClicked(bool); + void onCaptureFilterSettingsBtnPressed(); }; #endif \ No newline at end of file diff --git a/toonz/sources/toonz/preferencespopup.cpp b/toonz/sources/toonz/preferencespopup.cpp index 09064aa..2b518ae 100644 --- a/toonz/sources/toonz/preferencespopup.cpp +++ b/toonz/sources/toonz/preferencespopup.cpp @@ -359,7 +359,7 @@ void PreferencesPopup::onChunkSizeChanged() { void PreferencesPopup::onBlankCountChanged() { if (m_blanksCount && m_blankColor) m_pref->setBlankValues(m_blanksCount->getValue(), m_blankColor->getColor()); - TApp::instance()->getCurrentScene()->notifyPreferenceChanged(); + TApp::instance()->getCurrentScene()->notifyPreferenceChanged("BlankCount"); } //----------------------------------------------------------------------------- @@ -378,7 +378,7 @@ void PreferencesPopup::onBlankColorChanged(const TPixel32 &, bool isDragging) { if (m_blanksCount && m_blankColor) m_pref->setBlankValues(m_blanksCount->getValue(), m_blankColor->getColor()); - TApp::instance()->getCurrentScene()->notifyPreferenceChanged(); + TApp::instance()->getCurrentScene()->notifyPreferenceChanged("BlankColor"); } //----------------------------------------------------------------------------- @@ -554,9 +554,37 @@ void PreferencesPopup::onDefaultViewerChanged(int index) { //----------------------------------------------------------------------------- -void PreferencesPopup::onAutoSaveChanged(int index) { - m_minuteFld->setEnabled(index == Qt::Checked); - m_pref->enableAutosave(index == Qt::Checked); +void PreferencesPopup::onAutoSaveChanged(bool on) { + m_pref->enableAutosave(on); + if (on && !m_autoSaveSceneCB->isChecked() && + !m_autoSaveOtherFilesCB->isChecked()) { + m_autoSaveSceneCB->setChecked(true); + m_autoSaveOtherFilesCB->setChecked(true); + } +} + +//----------------------------------------------------------------------------- + +void PreferencesPopup::onAutoSaveSceneChanged(int index) { + m_pref->enableAutosaveScene(index == Qt::Checked); + if (!m_autoSaveOtherFilesCB->isChecked() && index == Qt::Unchecked) { + m_autoSaveGroup->setChecked(false); + } +} + +//----------------------------------------------------------------------------- + +void PreferencesPopup::onAutoSaveOtherFilesChanged(int index) { + m_pref->enableAutosaveOtherFiles(index == Qt::Checked); + if (!m_autoSaveSceneCB->isChecked() && index == Qt::Unchecked) { + m_autoSaveGroup->setChecked(false); + } +} + +//----------------------------------------------------------------------------- + +void PreferencesPopup::onStartupPopupChanged(int index) { + m_pref->enableStartupPopup(index == Qt::Checked); } //----------------------------------------------------------------------------- @@ -895,10 +923,58 @@ void PreferencesPopup::onFfmpegPathChanged() { //----------------------------------------------------------------------------- +void PreferencesPopup::onFastRenderPathChanged() { + QString text = m_fastRenderPathFileField->getPath(); + m_pref->setFastRenderPath(text.toStdString()); +} + +//----------------------------------------------------------------------------- + void PreferencesPopup::onFfmpegTimeoutChanged() { m_pref->setFfmpegTimeout(m_ffmpegTimeout->getValue()); } +//----------------------------------------------------------------------------- + +void PreferencesPopup::onUseNumpadForSwitchingStylesClicked(bool checked) { + if (checked) { + // check if there are any commands with numpadkey shortcuts + CommandManager *cm = CommandManager::instance(); + QList actionsList; + for (int key = Qt::Key_0; key <= Qt::Key_9; key++) { + std::string str = QKeySequence(key).toString().toStdString(); + QAction *action = cm->getActionFromShortcut(str); + if (action) actionsList.append(action); + } + QAction *tabAction = cm->getActionFromShortcut("Tab"); + if (tabAction) actionsList.append(tabAction); + tabAction = cm->getActionFromShortcut("Shift+Tab"); + if (tabAction) actionsList.append(tabAction); + // if there are actions using numpad shortcuts, notify to release them. + if (!actionsList.isEmpty()) { + QString msgStr = + tr("Numpad keys are assigned to the following commands.\nIs it OK to " + "release these shortcuts?"); + for (int a = 0; a < actionsList.size(); a++) { + msgStr += "\n" + actionsList.at(a)->iconText() + " (" + + actionsList.at(a)->shortcut().toString() + ")"; + } + int ret = DVGui::MsgBox(msgStr, tr("OK"), tr("Cancel"), 1); + if (ret == 2 || ret == 0) { // canceled + m_useNumpadForSwitchingStyles->setChecked(false); + return; + } else { // accepted, then release shortcuts + for (int a = 0; a < actionsList.size(); a++) + cm->setShortcut(actionsList[a], ""); + } + } + } + m_pref->enableUseNumpadForSwitchingStyles(checked); + // emit signal to update Palette and Viewer + TApp::instance()->getCurrentScene()->notifyPreferenceChanged( + "NumpadForSwitchingStyles"); +} + //********************************************************************************** // PrefencesPopup's constructor //********************************************************************************** @@ -926,8 +1002,14 @@ PreferencesPopup::PreferencesPopup() new CheckBox(tr("Use Default Viewer for Movie Formats"), this); CheckBox *minimizeRasterMemoryCB = new CheckBox(tr("Minimize Raster Memory Fragmentation *"), this); - CheckBox *autoSaveCB = new CheckBox(tr("Save Automatically Every Minutes")); - m_minuteFld = new DVGui::IntLineEdit(this, 15, 1, 60); + m_autoSaveGroup = new QGroupBox(tr("Save Automatically"), this); + m_autoSaveGroup->setCheckable(true); + m_autoSaveSceneCB = new CheckBox(tr("Automatically Save the Scene File")); + m_autoSaveOtherFilesCB = + new CheckBox(tr("Automatically Save Non-Scene Files")); + CheckBox *startupPopupCB = + new CheckBox(tr("Show Startup Window when OpenToonz Starts")); + m_minuteFld = new DVGui::IntLineEdit(this, 15, 1, 60); CheckBox *replaceAfterSaveLevelAsCB = new CheckBox(tr("Replace Toonz Level after SaveLevelAs command"), this); @@ -1043,7 +1125,9 @@ PreferencesPopup::PreferencesPopup() //--- Import/Export ------------------------------ categoryList->addItem(tr("Import/Export")); m_ffmpegPathFileFld = new DVGui::FileField(this, QString("")); - m_ffmpegTimeout = new DVGui::IntLineEdit(this, 30, 1); + m_fastRenderPathFileField = + new DVGui::FileField(this, QString("desktop"), false, true); + m_ffmpegTimeout = new DVGui::IntLineEdit(this, 30, 1); //--- Drawing ------------------------------ categoryList->addItem(tr("Drawing")); @@ -1063,6 +1147,8 @@ PreferencesPopup::PreferencesPopup() new CheckBox(tr("Use the TLV Savebox to Limit Filling Operations"), this); CheckBox *minimizeSaveboxAfterEditingCB = new CheckBox(tr("Minimize Savebox after Editing"), this); + m_useNumpadForSwitchingStyles = + new CheckBox(tr("Use Numpad and Tab keys for Switching Styles"), this); //--- Xsheet ------------------------------ categoryList->addItem(tr("Xsheet")); @@ -1137,9 +1223,11 @@ PreferencesPopup::PreferencesPopup() //--- General ------------------------------ useDefaultViewerCB->setChecked(m_pref->isDefaultViewerEnabled()); minimizeRasterMemoryCB->setChecked(m_pref->isRasterOptimizedMemory()); - autoSaveCB->setChecked(m_pref->isAutosaveEnabled()); + m_autoSaveGroup->setChecked(m_pref->isAutosaveEnabled()); + m_autoSaveSceneCB->setChecked(m_pref->isAutosaveSceneEnabled()); + m_autoSaveOtherFilesCB->setChecked(m_pref->isAutosaveOtherFilesEnabled()); m_minuteFld->setValue(m_pref->getAutosavePeriod()); - m_minuteFld->setEnabled(m_pref->isAutosaveEnabled()); + startupPopupCB->setChecked(m_pref->isStartupPopupEnabled()); replaceAfterSaveLevelAsCB->setChecked( m_pref->isReplaceAfterSaveLevelAsEnabled()); @@ -1263,6 +1351,8 @@ PreferencesPopup::PreferencesPopup() //--- Import/Export ------------------------------ QString path = m_pref->getFfmpegPath(); m_ffmpegPathFileFld->setPath(path); + path = m_pref->getFastRenderPath(); + m_fastRenderPathFileField->setPath(path); m_ffmpegTimeout->setValue(m_pref->getFfmpegTimeout()); //--- Drawing ------------------------------ @@ -1271,6 +1361,8 @@ PreferencesPopup::PreferencesPopup() minimizeSaveboxAfterEditingCB->setChecked( m_pref->isMinimizeSaveboxAfterEditing()); useSaveboxToLimitFillingOpCB->setChecked(m_pref->getFillOnlySavebox()); + m_useNumpadForSwitchingStyles->setChecked( + m_pref->isUseNumpadForSwitchingStylesEnabled()); QStringList scanLevelTypes; scanLevelTypes << "tif" @@ -1384,16 +1476,29 @@ PreferencesPopup::PreferencesPopup() Qt::AlignLeft | Qt::AlignVCenter); generalFrameLay->addWidget(minimizeRasterMemoryCB, 0, Qt::AlignLeft | Qt::AlignVCenter); - QHBoxLayout *saveAutoLay = new QHBoxLayout(); - saveAutoLay->setMargin(0); - saveAutoLay->setSpacing(15); + + QVBoxLayout *autoSaveOptionsLay = new QVBoxLayout(); + autoSaveOptionsLay->setMargin(10); { - saveAutoLay->addWidget(autoSaveCB, 0); - saveAutoLay->addWidget(m_minuteFld, 0); - saveAutoLay->addStretch(1); - } - generalFrameLay->addLayout(saveAutoLay, 0); + QHBoxLayout *saveAutoLay = new QHBoxLayout(); + saveAutoLay->setMargin(0); + saveAutoLay->setSpacing(5); + { + saveAutoLay->addWidget(new QLabel(tr("Interval(Minutes): "), this)); + saveAutoLay->addWidget(m_minuteFld, 0); + saveAutoLay->addStretch(1); + } + autoSaveOptionsLay->addLayout(saveAutoLay, 0); + autoSaveOptionsLay->addWidget(m_autoSaveSceneCB, 0, + Qt::AlignLeft | Qt::AlignVCenter); + autoSaveOptionsLay->addWidget(m_autoSaveOtherFilesCB, 0, + Qt::AlignLeft | Qt::AlignVCenter); + } + m_autoSaveGroup->setLayout(autoSaveOptionsLay); + generalFrameLay->addWidget(m_autoSaveGroup); + generalFrameLay->addWidget(startupPopupCB, 0, + Qt::AlignLeft | Qt::AlignVCenter); // Unit, CameraUnit QGridLayout *unitLay = new QGridLayout(); unitLay->setMargin(0); @@ -1661,6 +1766,14 @@ PreferencesPopup::PreferencesPopup() ioGridLay->addWidget(new QLabel(tr("FFmpeg Timeout:")), 4, 0, Qt::AlignRight); ioGridLay->addWidget(m_ffmpegTimeout, 4, 1, 1, 3); + ioGridLay->addWidget(new QLabel(" "), 5, 0); + ioGridLay->addWidget( + new QLabel(tr("Please indicate where you would like " + "exports from Fast Render(MP4) to go.")), + 6, 0, 1, 4); + ioGridLay->addWidget(new QLabel(tr("Fast Render Path: ")), 7, 0, + Qt::AlignRight); + ioGridLay->addWidget(m_fastRenderPathFileField, 7, 1, 1, 3); } ioLay->addLayout(ioGridLay); ioLay->addStretch(1); @@ -1711,6 +1824,9 @@ PreferencesPopup::PreferencesPopup() Qt::AlignLeft | Qt::AlignVCenter); drawingFrameLay->addWidget(multiLayerStylePickerCB, 0, Qt::AlignLeft | Qt::AlignVCenter); + drawingFrameLay->addWidget(m_useNumpadForSwitchingStyles, 0, + Qt::AlignLeft | Qt::AlignVCenter); + drawingFrameLay->addStretch(1); } drawingBox->setLayout(drawingFrameLay); @@ -1903,10 +2019,16 @@ PreferencesPopup::PreferencesPopup() SLOT(onDefaultViewerChanged(int))); ret = ret && connect(minimizeRasterMemoryCB, SIGNAL(stateChanged(int)), this, SLOT(onRasterOptimizedMemoryChanged(int))); - ret = ret && connect(autoSaveCB, SIGNAL(stateChanged(int)), - SLOT(onAutoSaveChanged(int))); + ret = ret && connect(m_autoSaveGroup, SIGNAL(toggled(bool)), + SLOT(onAutoSaveChanged(bool))); + ret = ret && connect(m_autoSaveSceneCB, SIGNAL(stateChanged(int)), + SLOT(onAutoSaveSceneChanged(int))); + ret = ret && connect(m_autoSaveOtherFilesCB, SIGNAL(stateChanged(int)), + SLOT(onAutoSaveOtherFilesChanged(int))); ret = ret && connect(m_minuteFld, SIGNAL(editingFinished()), SLOT(onMinuteChanged())); + ret = ret && connect(startupPopupCB, SIGNAL(stateChanged(int)), + SLOT(onStartupPopupChanged(int))); ret = ret && connect(m_cellsDragBehaviour, SIGNAL(currentIndexChanged(int)), SLOT(onDragCellsBehaviourChanged(int))); ret = ret && connect(m_undoMemorySize, SIGNAL(editingFinished()), @@ -2025,6 +2147,8 @@ PreferencesPopup::PreferencesPopup() //--- Import/Export ---------------------- ret = ret && connect(m_ffmpegPathFileFld, SIGNAL(pathChanged()), this, SLOT(onFfmpegPathChanged())); + ret = ret && connect(m_fastRenderPathFileField, SIGNAL(pathChanged()), this, + SLOT(onFastRenderPathChanged())); ret = ret && connect(m_ffmpegTimeout, SIGNAL(editingFinished()), this, SLOT(onFfmpegTimeoutChanged())); @@ -2050,6 +2174,8 @@ PreferencesPopup::PreferencesPopup() SLOT(onDefLevelParameterChanged())); ret = ret && connect(m_defLevelDpi, SIGNAL(valueChanged()), SLOT(onDefLevelParameterChanged())); + ret = ret && connect(m_useNumpadForSwitchingStyles, SIGNAL(clicked(bool)), + SLOT(onUseNumpadForSwitchingStylesClicked(bool))); //--- Xsheet ---------------------- ret = ret && connect(xsheetAutopanDuringPlaybackCB, SIGNAL(stateChanged(int)), diff --git a/toonz/sources/toonz/preferencespopup.h b/toonz/sources/toonz/preferencespopup.h index 74290c8..ddc1be1 100644 --- a/toonz/sources/toonz/preferencespopup.h +++ b/toonz/sources/toonz/preferencespopup.h @@ -24,6 +24,7 @@ class QLineEdit; class QPushButton; class QLabel; +class QGroupBox; //============================================================== @@ -70,11 +71,14 @@ private: DVGui::CheckBox *m_inksOnly, *m_enableVersionControl, *m_levelsBackup, *m_onionSkinVisibility, *m_pixelsOnlyCB, *m_projectRootDocuments, *m_projectRootDesktop, *m_projectRootCustom, *m_projectRootStuff, - *m_onionSkinDuringPlayback; + *m_onionSkinDuringPlayback, *m_autoSaveSceneCB, *m_autoSaveOtherFilesCB, + *m_useNumpadForSwitchingStyles; DVGui::FileField *m_customProjectRootFileField; - DVGui::FileField *m_ffmpegPathFileFld; + DVGui::FileField *m_ffmpegPathFileFld, *m_fastRenderPathFileField; + + QGroupBox *m_autoSaveGroup; private: // QWidget* create(const QString& lbl, bool def, const char* slot); @@ -104,7 +108,10 @@ private slots: void onRasterOptimizedMemoryChanged(int index); void onSaveUnpaintedInCleanupChanged(int index); void onMinimizeSaveboxAfterEditing(int index); - void onAutoSaveChanged(int index); + void onAutoSaveChanged(bool on); + void onAutoSaveSceneChanged(int index); + void onAutoSaveOtherFilesChanged(int index); + void onStartupPopupChanged(int index); void onDefaultViewerChanged(int index); void onBlankCountChanged(); void onBlankColorChanged(const TPixel32 &, bool isDragging); @@ -161,6 +168,8 @@ private slots: void onShowKeyframesOnCellAreaChanged(int); void onFfmpegPathChanged(); void onFfmpegTimeoutChanged(); + void onFastRenderPathChanged(); + void onUseNumpadForSwitchingStylesClicked(bool); }; //********************************************************************************** diff --git a/toonz/sources/toonz/rendercommand.cpp b/toonz/sources/toonz/rendercommand.cpp index adaf9f8..5af6af1 100644 --- a/toonz/sources/toonz/rendercommand.cpp +++ b/toonz/sources/toonz/rendercommand.cpp @@ -214,6 +214,7 @@ public: , m_timeStretchFactor(1) , m_multimediaRender(0) { setCommandHandler("MI_Render", this, &RenderCommand::onRender); + setCommandHandler("MI_FastRender", this, &RenderCommand::onFastRender); setCommandHandler("MI_Preview", this, &RenderCommand::onPreview); } @@ -222,6 +223,7 @@ public: void rasterRender(bool isPreview); void multimediaRender(); void onRender(); + void onFastRender(); void onPreview(); static void resetBgColor(); void doRender(bool isPreview); @@ -788,6 +790,38 @@ void RenderCommand::multimediaRender() { void RenderCommand::onRender() { doRender(false); } +void RenderCommand::onFastRender() { + TOutputProperties *prop = TApp::instance() + ->getCurrentScene() + ->getScene() + ->getProperties() + ->getOutputProperties(); + QString sceneName = QString::fromStdWString( + TApp::instance()->getCurrentScene()->getScene()->getSceneName()); + QString location = Preferences::instance()->getFastRenderPath(); + if (location == "desktop" || location == "Desktop") { + location = + QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); + } + TFilePath path = TFilePath(location) + TFilePath(sceneName + ".mp4"); + TFilePath currPath = prop->getPath(); + + QStringList formats; + TImageWriter::getSupportedFormats(formats, true); + TLevelWriter::getSupportedFormats(formats, true); + Tiio::Writer::getSupportedFormats(formats, true); + if (!formats.contains("mp4")) { + QString msg = QObject::tr( + "FFmpeg not found, please set the location in the Preferences and " + "restart."); + DVGui::warning(msg); + return; + } + prop->setPath(path); + doRender(false); + prop->setPath(currPath); +} + void RenderCommand::onPreview() { doRender(true); } //--------------------------------------------------------- diff --git a/toonz/sources/toonz/sceneviewer.cpp b/toonz/sources/toonz/sceneviewer.cpp index d039b34..1b521a2 100644 --- a/toonz/sources/toonz/sceneviewer.cpp +++ b/toonz/sources/toonz/sceneviewer.cpp @@ -10,6 +10,7 @@ #include "viewerdraw.h" #include "menubarcommandids.h" #include "ruler.h" +#include "locatorpopup.h" // TnzTools includes #include "tools/cursors.h" @@ -501,9 +502,9 @@ SceneViewer::SceneViewer(ImageUtils::FullScreenWidget *parent) , m_sideRasterPos() , m_topRasterPos() , m_toolDisableReason("") - , m_editPreviewSubCamera(false) { - assert(parent); - + , m_editPreviewSubCamera(false) + , m_locator(NULL) + , m_isLocator(false) { m_visualSettings.m_sceneProperties = TApp::instance()->getCurrentScene()->getScene()->getProperties(); // Enables multiple key input. @@ -880,6 +881,9 @@ void SceneViewer::hideEvent(QHideEvent *) { ToolHandle *toolHandle = app->getCurrentTool(); if (toolHandle) toolHandle->disconnect(this); + + // hide locator + if (m_locator && m_locator->isVisible()) m_locator->hide(); } //----------------------------------------------------------------------------- @@ -967,7 +971,7 @@ void SceneViewer::drawBuildVars() { } TTool *tool = app->getCurrentTool()->getTool(); - if (tool) tool->setViewer(this); + if (tool && !m_isLocator) tool->setViewer(this); } //----------------------------------------------------------------------------- @@ -1100,7 +1104,7 @@ void SceneViewer::drawCameraStand() { // Show white background when level editing mode. TTool *tool = TApp::instance()->getCurrentTool()->getTool(); if (m_drawEditingLevel && tool && tool->isEnabled()) { - tool->setViewer(this); + if (!m_isLocator) tool->setViewer(this); glPushMatrix(); if (m_referenceMode == CAMERA3D_REFERENCE) { mult3DMatrix(); @@ -1358,6 +1362,13 @@ void SceneViewer::drawOverlay() { // use // another glContext if (tool->getName() == "T_RGBPicker") tool->onImageChanged(); + + // draw cross at the center of the locator window + if (m_isLocator) { + glColor3d(1.0, 0.0, 0.0); + tglDrawSegment(TPointD(-4, 0), TPointD(5, 0)); + tglDrawSegment(TPointD(0, -4), TPointD(0, 5)); + } } } diff --git a/toonz/sources/toonz/sceneviewer.h b/toonz/sources/toonz/sceneviewer.h index 68ed8de..10276dc 100644 --- a/toonz/sources/toonz/sceneviewer.h +++ b/toonz/sources/toonz/sceneviewer.h @@ -33,6 +33,7 @@ class Ruler; class QMenu; class SceneViewer; +class LocatorPopup; namespace ImageUtils { class FullScreenWidget; @@ -135,6 +136,10 @@ class SceneViewer final : public QGLWidget, TOP_3D, } m_current3DDevice; + LocatorPopup *m_locator; + bool m_isLocator; + bool m_isStyleShortcutSwitchable; + // iwsw commented out temporarily // Ghibli3DLutUtil * m_ghibli3DLutUtil; public: @@ -230,6 +235,9 @@ public: void setFocus(Qt::FocusReason reason) { QWidget::setFocus(reason); }; + void setIsLocator() { m_isLocator = true; } + void setIsStyleShortcutSwitchable() { m_isStyleShortcutSwitchable = true; } + public: // SceneViewer's gadget public functions TPointD winToWorld(const QPoint &pos) const; diff --git a/toonz/sources/toonz/sceneviewerevents.cpp b/toonz/sources/toonz/sceneviewerevents.cpp index 17f3f3d..7a7a924 100644 --- a/toonz/sources/toonz/sceneviewerevents.cpp +++ b/toonz/sources/toonz/sceneviewerevents.cpp @@ -14,6 +14,11 @@ #include "onionskinmaskgui.h" #include "ruler.h" #include "comboviewerpane.h" +#include "locatorpopup.h" + +// TnzQt includes +#include "toonzqt/tselectionhandle.h" +#include "toonzqt/styleselection.h" // TnzTools includes #include "tools/cursors.h" @@ -180,6 +185,14 @@ void SceneViewer::onButtonPressed(FlipConsole::EGadget button) { m_editPreviewSubCamera = !m_editPreviewSubCamera; update(); break; + + // open locator. Create one for the first time + case FlipConsole::eLocator: + if (!m_locator) m_locator = new LocatorPopup(this); + m_locator->show(); + m_locator->raise(); + m_locator->activateWindow(); + break; } } @@ -347,7 +360,12 @@ void SceneViewer::mouseMoveEvent(QMouseEvent *event) { TMouseEvent toonzEvent; initToonzEvent(toonzEvent, event, height(), m_pressure, m_tabletEvent, false); - TPointD pos = tool->getMatrix().inv() * winToWorld(curPos); + TPointD worldPos = winToWorld(curPos); + TPointD pos = tool->getMatrix().inv() * worldPos; + + if (m_locator) { + m_locator->onChangeViewAff(worldPos); + } TObjectHandle *objHandle = TApp::instance()->getCurrentObject(); if (tool->getToolType() & TTool::LevelTool && !objHandle->isSpline()) { @@ -375,6 +393,7 @@ void SceneViewer::mouseMoveEvent(QMouseEvent *event) { // panning panQt(curPos - m_pos); m_pos = curPos; + return; } } @@ -753,6 +772,19 @@ void SceneViewer::keyPressEvent(QKeyEvent *event) { tool->setViewer(this); + // If this object is child of Viewer or ComboViewer + // (m_isStyleShortcutSelective = true), + // then consider about shortcut for the current style selection. + if (m_isStyleShortcutSwitchable && + Preferences::instance()->isUseNumpadForSwitchingStylesEnabled() && + (!isTextToolActive) && (event->modifiers() == Qt::NoModifier || + event->modifiers() == Qt::KeypadModifier) && + ((Qt::Key_0 <= key && key <= Qt::Key_9) || key == Qt::Key_Tab || + key == Qt::Key_Backtab)) { + event->ignore(); + return; + } + if (key == Qt::Key_Shift) modifiers |= Qt::SHIFT; else if (key == Qt::Key_Control) @@ -973,6 +1005,7 @@ void SceneViewer::contextMenuEvent(QContextMenuEvent *e) { #endif if (m_freezedStatus != NO_FREEZED) return; + if (m_isLocator) return; TPoint winPos(e->pos().x(), height() - e->pos().y()); std::vector columnIndices; diff --git a/toonz/sources/toonz/shortcutpopup.cpp b/toonz/sources/toonz/shortcutpopup.cpp index 911a11f..b51b020 100644 --- a/toonz/sources/toonz/shortcutpopup.cpp +++ b/toonz/sources/toonz/shortcutpopup.cpp @@ -5,11 +5,19 @@ // Tnz6 includes #include "menubarcommandids.h" #include "tapp.h" +#include "tenv.h" +#include "tsystem.h" +#include "toonz/preferences.h" +#include "toonz/toonzfolders.h" // TnzQt includes +#include "toonzqt/gutil.h" #include "toonzqt/menubarcommand.h" #include "toonzqt/dvdialog.h" +// TnzLib includes +#include "toonz/preferences.h" + // Qt includes #include #include @@ -24,6 +32,9 @@ #include #include #include +#include +#include +#include // STD includes #include @@ -128,6 +139,14 @@ void ShortcutViewer::keyPressEvent(QKeyEvent *event) { modifiers = 0; } + // If "Use Numpad and Tab keys for Switching Styles" option is activated, + // then prevent to assign such keys + if (Preferences::instance()->isUseNumpadForSwitchingStylesEnabled() && + modifiers == 0 && (key >= Qt::Key_0 && key <= Qt::Key_9)) { + event->ignore(); + return; + } + if (m_action) { CommandManager *cm = CommandManager::instance(); QKeySequence keySequence(key + modifiers); @@ -155,7 +174,7 @@ void ShortcutViewer::keyPressEvent(QKeyEvent *event) { void ShortcutViewer::removeShortcut() { if (m_action) { - CommandManager::instance()->setShortcut(m_action, ""); + CommandManager::instance()->setShortcut(m_action, "", false); emit shortcutChanged(); update(); } @@ -339,14 +358,32 @@ void ShortcutTree::onShortcutChanged() { ShortcutPopup::ShortcutPopup() : Dialog(TApp::instance()->getMainWindow(), false, false, "Shortcut") { setWindowTitle(tr("Configure Shortcuts")); + m_presetChoiceCB = new QComboBox(this); + buildPresets(); + m_presetChoiceCB->setCurrentIndex(0); m_list = new ShortcutTree(this); m_list->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); m_list->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); m_list->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); - m_sViewer = new ShortcutViewer(this); - m_removeBtn = new QPushButton(tr("Remove"), this); + m_sViewer = new ShortcutViewer(this); + m_removeBtn = new QPushButton(tr("Remove"), this); + m_loadShortcutsPopup = NULL; + m_saveShortcutsPopup = NULL; + m_dialog = NULL; + m_exportButton = new QPushButton(tr("Export Current Shortcuts"), this); + m_exportButton->setToolTip(tr("Export Current Shortcuts")); + m_deletePresetButton = new QPushButton("Delete", this); + m_deletePresetButton->setToolTip(tr("Delete Current Preset")); + m_deletePresetButton->setIcon(QIcon(":Resources/delete_on.png")); + m_savePresetButton = new QPushButton("Save As", this); + m_savePresetButton->setToolTip(tr("Save Current Shortcuts as New Preset")); + m_savePresetButton->setIcon(QIcon(":Resources/saveas_on.png")); + m_loadPresetButton = new QPushButton(tr("Apply")); + m_loadPresetButton->setToolTip(tr("Use selected preset as shortcuts")); + m_loadPresetButton->setIcon(QIcon(":Resources/green.png")); + m_clearAllShortcutsButton = new QPushButton(tr("Clear All Shortcuts")); QLabel *noSearchResultLabel = new QLabel(tr("Couldn't find any matching command."), this); noSearchResultLabel->setHidden(true); @@ -383,6 +420,28 @@ ShortcutPopup::ShortcutPopup() bottomLayout->addWidget(m_removeBtn, 0); } m_topLayout->addLayout(bottomLayout, 0); + m_topLayout->addSpacing(10); + QHBoxLayout *presetLay = new QHBoxLayout(); + presetLay->setMargin(0); + presetLay->setSpacing(5); + { + presetLay->addWidget(new QLabel("Preset:", this), 0); + presetLay->addWidget(m_presetChoiceCB, 1); + presetLay->addWidget(m_loadPresetButton, 0); + presetLay->addWidget(m_savePresetButton, 0); + presetLay->addWidget(m_deletePresetButton, 0); + } + m_topLayout->addLayout(presetLay, 0); + m_topLayout->addSpacing(10); + QHBoxLayout *exportLay = new QHBoxLayout(); + exportLay->setMargin(0); + exportLay->setSpacing(5); + { + exportLay->addWidget(m_exportButton, 0); + exportLay->addWidget(m_clearAllShortcutsButton, 0); + } + m_topLayout->addLayout(exportLay, 0); + // m_topLayout->addWidget(m_exportButton, 0); } connect(m_list, SIGNAL(actionSelected(QAction *)), m_sViewer, @@ -397,6 +456,14 @@ ShortcutPopup::ShortcutPopup() SLOT(setHidden(bool))); connect(searchEdit, SIGNAL(textChanged(const QString &)), this, SLOT(onSearchTextChanged(const QString &))); + connect(m_presetChoiceCB, SIGNAL(currentIndexChanged(int)), + SLOT(onPresetChanged(int))); + connect(m_exportButton, SIGNAL(clicked()), SLOT(onExportButton())); + connect(m_deletePresetButton, SIGNAL(clicked()), SLOT(onDeletePreset())); + connect(m_savePresetButton, SIGNAL(clicked()), SLOT(onSavePreset())); + connect(m_loadPresetButton, SIGNAL(clicked()), SLOT(onLoadPreset())); + connect(m_clearAllShortcutsButton, SIGNAL(clicked()), + SLOT(clearAllShortcuts())); } //----------------------------------------------------------------------------- @@ -415,4 +482,324 @@ void ShortcutPopup::onSearchTextChanged(const QString &text) { //----------------------------------------------------------------------------- +void ShortcutPopup::onPresetChanged(int index) { + if (m_presetChoiceCB->currentText() == "Load from file...") { + importPreset(); + } +} + +//----------------------------------------------------------------------------- + +void ShortcutPopup::clearAllShortcuts(bool warning) { + if (warning) { + QString question(tr("This will erase ALL shortcuts. Continue?")); + int ret = + DVGui::MsgBox(question, QObject::tr("OK"), QObject::tr("Cancel"), 0); + if (ret == 0 || ret == 2) { + // cancel (or closed message box window) + return; + } + showDialog("Clearing All Shortcuts"); + } + for (int commandType = UndefinedCommandType; commandType <= MenuCommandType; + commandType++) { + std::vector actions; + CommandManager::instance()->getActions((CommandType)commandType, actions); + for (QAction *action : actions) { + qApp->processEvents(); + m_sViewer->setAction(action); + m_sViewer->removeShortcut(); + } + } + setCurrentPresetPref("DELETED"); + // if warning is true, this was called directly- need to hide the dialog after + if (warning) m_dialog->hide(); +} + +//----------------------------------------------------------------------------- + +void ShortcutPopup::setPresetShortcuts(TFilePath fp) { + QSettings preset(toQString(fp), QSettings::IniFormat); + preset.beginGroup("shortcuts"); + QStringList allIds = preset.allKeys(); + QAction *action; + for (QString id : allIds) { + QByteArray ba = id.toLatin1(); + const char *charId = ba.data(); + action = CommandManager::instance()->getAction((CommandId)charId); + CommandManager::instance()->setShortcut( + action, preset.value(id).toString().toStdString(), false); + } + preset.endGroup(); + emit m_sViewer->shortcutChanged(); + m_dialog->hide(); + buildPresets(); + setCurrentPresetPref(QString::fromStdString(fp.getName())); +} + +//----------------------------------------------------------------------------- + +bool ShortcutPopup::showConfirmDialog() { + QString question(tr("This will overwrite all current shortcuts. Continue?")); + int ret = + DVGui::MsgBox(question, QObject::tr("OK"), QObject::tr("Cancel"), 0); + if (ret == 0 || ret == 2) { + // cancel (or closed message box window) + return false; + } else + return true; +} + +//----------------------------------------------------------------------------- + +bool ShortcutPopup::showOverwriteDialog(QString name) { + QString question(tr("A file named ") + name + + tr(" already exists. Do you want to replace it?")); + int ret = DVGui::MsgBox(question, QObject::tr("Yes"), QObject::tr("No"), 0); + if (ret == 0 || ret == 2) { + // cancel (or closed message box window) + return false; + } else + return true; +} + +//----------------------------------------------------------------------------- + +void ShortcutPopup::showDialog(QString text) { + if (m_dialog == NULL) { + m_dialogLabel = new QLabel("", this); + m_dialog = new DVGui::Dialog(this, false, false); + m_dialog->setWindowTitle(tr("OpenToonz - Setting Shortcuts")); + m_dialog->setModal(false); + + m_dialog->setTopMargin(10); + m_dialog->setTopSpacing(10); + m_dialog->setLabelWidth(500); + m_dialog->beginVLayout(); + m_dialog->addWidget(m_dialogLabel, false); + m_dialog->endVLayout(); + } + m_dialogLabel->setText(text); + m_dialog->show(); +} + +//----------------------------------------------------------------------------- + +void ShortcutPopup::onExportButton(TFilePath fp) { + if (fp == TFilePath()) { + m_saveShortcutsPopup = new GenericSaveFilePopup("Save Current Shortcuts"); + m_saveShortcutsPopup->addFilterType("ini"); + fp = m_saveShortcutsPopup->getPath(); + if (fp == TFilePath()) return; + } + showDialog("Saving Shortcuts"); + QString shortcutString = "[shortcuts]\n"; + for (int commandType = UndefinedCommandType; commandType <= MenuCommandType; + commandType++) { + std::vector actions; + CommandManager::instance()->getActions((CommandType)commandType, actions); + for (QAction *action : actions) { + qApp->processEvents(); + std::string id = CommandManager::instance()->getIdFromAction(action); + std::string shortcut = + CommandManager::instance()->getShortcutFromAction(action); + if (shortcut != "") { + shortcutString = shortcutString + QString::fromStdString(id) + "=" + + QString::fromStdString(shortcut) + "\n"; + } + } + } + QFile file(fp.getQString()); + file.open(QIODevice::WriteOnly | QIODevice::Text); + QTextStream out(&file); + out << shortcutString; + file.close(); + m_dialog->hide(); +} + +//----------------------------------------------------------------------------- + +void ShortcutPopup::onDeletePreset() { + // change this to 4 once RETAS shortcuts are updated + if (m_presetChoiceCB->currentIndex() <= 3) { + DVGui::MsgBox(DVGui::CRITICAL, tr("Included presets cannot be deleted.")); + return; + } + + QString question(tr("Are you sure you want to delete the preset: ") + + m_presetChoiceCB->currentText() + tr("?")); + int ret = DVGui::MsgBox(question, QObject::tr("Yes"), QObject::tr("No"), 0); + if (ret == 0 || ret == 2) { + // cancel (or closed message box window) + return; + } + TFilePath presetDir = + ToonzFolder::getMyModuleDir() + TFilePath("shortcutpresets"); + QString presetName = m_presetChoiceCB->currentText(); + if (TSystem::doesExistFileOrLevel(presetDir + + TFilePath(presetName + ".ini"))) { + TSystem::deleteFile(presetDir + TFilePath(presetName + ".ini")); + buildPresets(); + m_presetChoiceCB->setCurrentIndex(0); + } + if (Preferences::instance()->getShortcutPreset() == presetName) + setCurrentPresetPref("DELETED"); + getCurrentPresetPref(); +} + +//----------------------------------------------------------------------------- + +void ShortcutPopup::importPreset() { + m_loadShortcutsPopup = new GenericLoadFilePopup("Load Shortcuts File"); + m_loadShortcutsPopup->addFilterType("ini"); + TFilePath shortcutPath = m_loadShortcutsPopup->getPath(); + if (shortcutPath == TFilePath()) { + m_presetChoiceCB->setCurrentIndex(0); + return; + } + if (!showConfirmDialog()) return; + + TFilePath presetDir = + ToonzFolder::getMyModuleDir() + TFilePath("shortcutpresets"); + if (!TSystem::doesExistFileOrLevel(presetDir)) { + TSystem::mkDir(presetDir); + } + QString name = shortcutPath.withoutParentDir().getQString(); + std::string strName = name.toStdString(); + if (TSystem::doesExistFileOrLevel(presetDir + TFilePath(name))) { + if (!showOverwriteDialog(name)) return; + } + showDialog("Importing Shortcuts"); + TSystem::copyFile(presetDir + TFilePath(name), shortcutPath, true); + clearAllShortcuts(false); + setPresetShortcuts(presetDir + TFilePath(name)); + return; +} + +//----------------------------------------------------------------------------- + +void ShortcutPopup::onLoadPreset() { + QString preset = m_presetChoiceCB->currentText(); + TFilePath presetDir = + ToonzFolder::getMyModuleDir() + TFilePath("shortcutpresets"); + TFilePath defaultPresetDir = + ToonzFolder::getProfileFolder() + TFilePath("layouts/shortcuts"); + if (preset == "") return; + if (preset == "Load from file...") { + importPreset(); + return; + } + + if (!showConfirmDialog()) return; + showDialog("Setting Shortcuts"); + if (preset == "OpenToonz") { + clearAllShortcuts(false); + TFilePath fp = defaultPresetDir + TFilePath("defopentoonz.ini"); + setPresetShortcuts(fp); + return; + } else if (preset == "Toon Boom Harmony") { + clearAllShortcuts(false); + TFilePath fp = defaultPresetDir + TFilePath("otharmony.ini"); + setPresetShortcuts(fp); + return; + } else if (preset == "Adobe Animate(Flash)") { + clearAllShortcuts(false); + TFilePath fp = defaultPresetDir + TFilePath("otadobe.ini"); + setPresetShortcuts(fp); + return; + } else if (preset == "RETAS PaintMan") { + clearAllShortcuts(false); + TFilePath fp = defaultPresetDir + TFilePath("otretas.ini"); + setPresetShortcuts(fp); + return; + } else if (TSystem::doesExistFileOrLevel(presetDir + + TFilePath(preset + ".ini"))) { + clearAllShortcuts(false); + TFilePath fp = presetDir + TFilePath(preset + ".ini"); + setPresetShortcuts(fp); + return; + } + m_dialog->hide(); +} + +//----------------------------------------------------------------------------- + +QStringList ShortcutPopup::buildPresets() { + QStringList presets; + presets << "" + << "OpenToonz" + //<< "RETAS PaintMan" + << "Toon Boom Harmony" + << "Adobe Animate(Flash)"; + TFilePath presetDir = + ToonzFolder::getMyModuleDir() + TFilePath("shortcutpresets"); + if (TSystem::doesExistFileOrLevel(presetDir)) { + TFilePathSet fps = TSystem::readDirectory(presetDir, true, true, false); + QStringList customPresets; + for (TFilePath fp : fps) { + if (fp.getType() == "ini") { + customPresets << QString::fromStdString(fp.getName()); + std::string name = fp.getName(); + } + } + customPresets.sort(); + presets = presets + customPresets; + } + presets << tr("Load from file..."); + m_presetChoiceCB->clear(); + m_presetChoiceCB->addItems(presets); + return presets; +} + +//----------------------------------------------------------------------------- + +void ShortcutPopup::onSavePreset() { + QString presetName = DVGui::getText("Enter Preset Name", "Preset Name:", ""); + if (presetName == "") return; + TFilePath presetDir = + ToonzFolder::getMyModuleDir() + TFilePath("shortcutpresets"); + if (!TSystem::doesExistFileOrLevel(presetDir)) { + TSystem::mkDir(presetDir); + } + TFilePath fp; + fp = presetDir + TFilePath(presetName + ".ini"); + if (TSystem::doesExistFileOrLevel(fp)) { + if (!showOverwriteDialog(QString::fromStdString(fp.getName()))) return; + } + onExportButton(fp); + + buildPresets(); + setCurrentPresetPref(presetName); +} + +//----------------------------------------------------------------------------- + +void ShortcutPopup::showEvent(QShowEvent *se) { getCurrentPresetPref(); } + +//----------------------------------------------------------------------------- + +void ShortcutPopup::setCurrentPresetPref(QString name) { + Preferences::instance()->setShortcutPreset(name.toStdString()); + getCurrentPresetPref(); +} + +//----------------------------------------------------------------------------- + +void ShortcutPopup::getCurrentPresetPref() { + QString name = Preferences::instance()->getShortcutPreset(); + if (name == "DELETED") + m_presetChoiceCB->setCurrentText(""); + else if (name == "defopentoonz") + m_presetChoiceCB->setCurrentText("OpenToonz"); + else if (name == "otharmony") + m_presetChoiceCB->setCurrentText("Toon Boom Harmony"); + else if (name == "otadobe") + m_presetChoiceCB->setCurrentText("Adobe Animate(Flash)"); + else if (name == "otretas") + m_presetChoiceCB->setCurrentText("RETAS PaintMan"); + + else + m_presetChoiceCB->setCurrentText(name); +} + OpenPopupCommandHandler openShortcutPopup(MI_ShortcutPopup); diff --git a/toonz/sources/toonz/shortcutpopup.h b/toonz/sources/toonz/shortcutpopup.h index 2044ac6..142d04f 100644 --- a/toonz/sources/toonz/shortcutpopup.h +++ b/toonz/sources/toonz/shortcutpopup.h @@ -5,7 +5,8 @@ #include #include - +#include +#include "filebrowserpopup.h" #include "toonzqt/dvdialog.h" // forward declaration @@ -92,13 +93,40 @@ class ShortcutPopup final : public DVGui::Dialog { QPushButton *m_removeBtn; ShortcutViewer *m_sViewer; ShortcutTree *m_list; + QComboBox *m_presetChoiceCB; + DVGui::Dialog *m_dialog; + GenericLoadFilePopup *m_loadShortcutsPopup; + GenericSaveFilePopup *m_saveShortcutsPopup; + QPushButton *m_exportButton; + QPushButton *m_deletePresetButton; + QPushButton *m_savePresetButton; + QPushButton *m_loadPresetButton; + QPushButton *m_clearAllShortcutsButton; + QLabel *m_dialogLabel; public: ShortcutPopup(); ~ShortcutPopup(); +private: + void setPresetShortcuts(TFilePath fp); + void showDialog(QString text); + bool showConfirmDialog(); + bool showOverwriteDialog(QString name); + void importPreset(); + QStringList buildPresets(); + void showEvent(QShowEvent *se) override; + void setCurrentPresetPref(QString preset); + void getCurrentPresetPref(); + protected slots: + void clearAllShortcuts(bool warning = true); void onSearchTextChanged(const QString &text); + void onPresetChanged(int index); + void onExportButton(TFilePath fp = TFilePath()); + void onDeletePreset(); + void onSavePreset(); + void onLoadPreset(); }; #endif // SHORTCUTPOPUP_H diff --git a/toonz/sources/toonz/startuppopup.cpp b/toonz/sources/toonz/startuppopup.cpp new file mode 100644 index 0000000..bf8c375 --- /dev/null +++ b/toonz/sources/toonz/startuppopup.cpp @@ -0,0 +1,917 @@ + + +#include "startuppopup.h" + +// Tnz6 includes +#include "mainwindow.h" +#include "tapp.h" +#include "iocommand.h" +#include "toutputproperties.h" +#include "toonzqt/flipconsole.h" +#include "menubarcommandids.h" +#include "tenv.h" +#include "toonz/stage.h" + +// TnzQt includes +#include "toonzqt/menubarcommand.h" +#include "toonzqt/gutil.h" +#include "toonzqt/doublefield.h" + +// TnzLib includes +#include "toonz/toonzscene.h" +#include "toonz/txsheet.h" +#include "toonz/levelproperties.h" +#include "toonz/sceneproperties.h" +#include "toonz/tcamera.h" +#include "toonz/tscenehandle.h" +#include "toonz/txsheethandle.h" +#include "toonz/preferences.h" +#include "toonz/tproject.h" + +// TnzCore includes +#include "tsystem.h" +#include "filebrowsermodel.h" + +// Qt includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace DVGui; + +namespace { + +// the first value in the preset list +const QString custom = QObject::tr(""); + +QString removeZeros(QString srcStr) { + if (!srcStr.contains('.')) return srcStr; + + for (int i = srcStr.length() - 1; i >= 0; i--) { + if (srcStr.at(i) == '0') + srcStr.chop(1); + else if (srcStr.at(i) == '.') { + srcStr.chop(1); + break; + } else + break; + } + return srcStr; +} +} // namespace + +//============================================================================= +/*! \class StartupPopup + \brief The StartupPopup class provides a modal dialog to + bring up recent files or create a new scene. + + Inherits \b Dialog. +*/ +//----------------------------------------------------------------------------- + +StartupPopup::StartupPopup() + : Dialog(TApp::instance()->getMainWindow(), true, true, "StartupPopup") { + setWindowTitle(tr("OpenToonz Startup")); + + m_projectBox = new QGroupBox(tr("Choose Project"), this); + m_sceneBox = new QGroupBox(tr("Create a New Scene"), this); + m_recentBox = new QGroupBox(tr("Open Scene"), this); + m_projectBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_nameFld = new LineEdit(this); + m_pathFld = new FileField(this); + m_sceneNameLabel = new QLabel(tr("Scene Name:")); + m_widthLabel = new QLabel(tr("Width:"), this); + m_widthFld = new MeasuredDoubleLineEdit(this); + m_heightLabel = new QLabel(tr("Height:"), this); + m_heightFld = new MeasuredDoubleLineEdit(this); + m_dpiLabel = new QLabel(tr("DPI:"), this); + m_dpiFld = new DoubleLineEdit(this, 120); + m_resXLabel = new QLabel(tr("X"), this); + m_resXFld = new DoubleLineEdit(this); + m_resYFld = new DoubleLineEdit(this); + m_resTextLabel = new QLabel(tr("Resolution:"), this); + m_fpsLabel = new QLabel(tr("Frame Rate:"), this); + m_fpsFld = new DoubleLineEdit(this, 24.0); + m_cameraSettingsWidget = new CameraSettingsWidget(false); + m_presetCombo = new QComboBox(this); + m_unitsCB = new QComboBox(this); + m_addPresetBtn = new QPushButton(tr("Add"), this); + m_removePresetBtn = new QPushButton(tr("Remove"), this); + m_showAtStartCB = new QCheckBox(tr("Show this at startup"), this); + QPushButton *createButton = new QPushButton(tr("Create Scene"), this); + QPushButton *newProjectButton = new QPushButton(tr("New Project..."), this); + QPushButton *loadOtherSceneButton = + new QPushButton(tr("Open Another Scene..."), this); + m_projectsCB = new QComboBox(this); + QStringList type; + type << tr("pixel") << tr("cm") << tr("mm") << tr("inch") << tr("field"); + m_unitsCB->addItems(type); + + // Exclude all character which cannot fit in a filepath (Win). + // Dots are also prohibited since they are internally managed by Toonz. + QRegExp rx("[^\\\\/:?*.\"<>|]+"); + m_nameFld->setValidator(new QRegExpValidator(rx, this)); + + m_widthFld->setMeasure("camera.lx"); + m_heightFld->setMeasure("camera.ly"); + + m_widthFld->setRange(0.1, (std::numeric_limits::max)()); + m_heightFld->setRange(0.1, (std::numeric_limits::max)()); + m_fpsFld->setRange(1.0, (std::numeric_limits::max)()); + m_dpiFld->setRange(1.0, (std::numeric_limits::max)()); + m_resXFld->setRange(0.1, (std::numeric_limits::max)()); + m_resYFld->setRange(0.1, (std::numeric_limits::max)()); + m_showAtStartCB->setChecked(Preferences::instance()->isStartupPopupEnabled()); + m_showAtStartCB->setStyleSheet("QCheckBox{ background-color: none; }"); + m_addPresetBtn->setStyleSheet( + "QPushButton { padding-left: 4px; padding-right: 4px;}"); + m_removePresetBtn->setStyleSheet( + "QPushButton { padding-left: 4px; padding-right: 4px;}"); + QLabel *label = new QLabel(); + label->setPixmap(QPixmap(":Resources/startup.png")); + m_projectBox->setObjectName("SolidLineFrame"); + m_sceneBox->setObjectName("SolidLineFrame"); + m_recentBox->setObjectName("SolidLineFrame"); + m_projectBox->setContentsMargins(10, 10, 10, 10); + m_sceneBox->setContentsMargins(10, 10, 10, 10); + m_recentBox->setContentsMargins(10, 10, 10, 10); + m_recentBox->setFixedWidth(200); + m_sceneBox->setMinimumWidth(480); + m_projectBox->setMinimumWidth(480); + m_buttonFrame->setFixedHeight(30); + //--- layout + m_topLayout->setMargin(0); + m_topLayout->setSpacing(0); + { + QGridLayout *guiLay = new QGridLayout(); + QHBoxLayout *projectLay = new QHBoxLayout(); + QGridLayout *newSceneLay = new QGridLayout(); + m_recentSceneLay = new QVBoxLayout(); + guiLay->setMargin(10); + guiLay->setVerticalSpacing(10); + guiLay->setHorizontalSpacing(10); + + guiLay->addWidget(label, 0, 0, 1, 2, Qt::AlignLeft); + + projectLay->setSpacing(8); + projectLay->setMargin(8); + { + projectLay->addWidget(m_projectsCB, 1); + projectLay->addWidget(newProjectButton, 0); + } + m_projectBox->setLayout(projectLay); + guiLay->addWidget(m_projectBox, 1, 0, 1, 1, Qt::AlignCenter); + + newSceneLay->setMargin(8); + newSceneLay->setVerticalSpacing(8); + newSceneLay->setHorizontalSpacing(8); + { + // Scene Name + newSceneLay->addWidget(m_sceneNameLabel, 0, 0, + Qt::AlignRight | Qt::AlignVCenter); + newSceneLay->addWidget(m_nameFld, 0, 1, 1, 3); + + // Save In + newSceneLay->addWidget(new QLabel(tr("Save In:")), 1, 0, + Qt::AlignRight | Qt::AlignVCenter); + newSceneLay->addWidget(m_pathFld, 1, 1, 1, 3); + newSceneLay->addWidget(new QLabel(tr("Camera Size:")), 2, 0, + Qt::AlignRight | Qt::AlignVCenter); + QHBoxLayout *resListLay = new QHBoxLayout(); + resListLay->setSpacing(3); + resListLay->setMargin(1); + { + resListLay->addWidget(m_presetCombo, 1); + resListLay->addWidget(m_addPresetBtn, 0); + resListLay->addWidget(m_removePresetBtn, 0); + } + newSceneLay->addLayout(resListLay, 2, 1, 1, 3, Qt::AlignLeft); + + // Width - Height + newSceneLay->addWidget(m_widthLabel, 3, 0, + Qt::AlignRight | Qt::AlignVCenter); + newSceneLay->addWidget(m_widthFld, 3, 1); + newSceneLay->addWidget(m_heightLabel, 3, 2, + Qt::AlignRight | Qt::AlignVCenter); + newSceneLay->addWidget(m_heightFld, 3, 3); + + newSceneLay->addWidget(m_resTextLabel, 4, 0, 1, 1, Qt::AlignRight); + newSceneLay->addWidget(m_resXFld, 4, 1); + newSceneLay->addWidget(m_resXLabel, 4, 2, 1, 1, Qt::AlignCenter); + newSceneLay->addWidget(m_resYFld, 4, 3); + newSceneLay->addWidget(new QLabel(tr("Units:")), 5, 0, + Qt::AlignRight | Qt::AlignVCenter); + newSceneLay->addWidget(m_unitsCB, 5, 1, 1, 1); + newSceneLay->addWidget(m_dpiLabel, 5, 2, + Qt::AlignRight | Qt::AlignVCenter); + newSceneLay->addWidget(m_dpiFld, 5, 3, 1, 1); + newSceneLay->addWidget(m_fpsLabel, 6, 0, + Qt::AlignRight | Qt::AlignVCenter); + newSceneLay->addWidget(m_fpsFld, 6, 1, 1, 1); + newSceneLay->addWidget(createButton, 7, 1, 1, 3, Qt::AlignLeft); + } + m_sceneBox->setLayout(newSceneLay); + guiLay->addWidget(m_sceneBox, 2, 0, 4, 1, Qt::AlignLeft); + + m_recentSceneLay->setMargin(5); + m_recentSceneLay->setSpacing(2); + { + // Recent Scene List + m_recentBox->setLayout(m_recentSceneLay); + guiLay->addWidget(m_recentBox, 1, 1, 4, 1, Qt::AlignTop); + guiLay->addWidget(loadOtherSceneButton, 5, 1, 1, 1, Qt::AlignRight); + } + m_topLayout->addLayout(guiLay, 0); + } + + m_buttonLayout->setMargin(0); + m_buttonLayout->setSpacing(10); + { m_buttonLayout->addWidget(m_showAtStartCB, Qt::AlignLeft); } + + TApp *app = TApp::instance(); + TSceneHandle *sceneHandle = app->getCurrentScene(); + + //---- signal-slot connections + bool ret = true; + ret = ret && connect(sceneHandle, SIGNAL(sceneChanged()), this, + SLOT(onSceneChanged())); + ret = ret && connect(sceneHandle, SIGNAL(sceneSwitched()), this, + SLOT(onSceneChanged())); + ret = ret && connect(newProjectButton, SIGNAL(clicked()), this, + SLOT(onNewProjectButtonPressed())); + ret = ret && connect(loadOtherSceneButton, SIGNAL(clicked()), this, + SLOT(onLoadSceneButtonPressed())); + ret = ret && connect(m_projectsCB, SIGNAL(currentIndexChanged(int)), + SLOT(onProjectChanged(int))); + ret = ret && + connect(createButton, SIGNAL(clicked()), this, SLOT(onCreateButton())); + ret = ret && connect(m_showAtStartCB, SIGNAL(stateChanged(int)), this, + SLOT(onShowAtStartChanged(int))); + ret = ret && connect(m_widthFld, SIGNAL(valueChanged()), this, + SLOT(updateResolution())); + ret = ret && connect(m_heightFld, SIGNAL(valueChanged()), this, + SLOT(updateResolution())); + ret = ret && + connect(m_resXFld, SIGNAL(valueChanged()), this, SLOT(updateSize())); + ret = ret && + connect(m_resYFld, SIGNAL(valueChanged()), this, SLOT(updateSize())); + ret = ret && connect(m_dpiFld, SIGNAL(editingFinished()), this, + SLOT(onDpiChanged())); + ret = ret && connect(m_presetCombo, SIGNAL(activated(const QString &)), + SLOT(onPresetSelected(const QString &))); + ret = ret && connect(m_addPresetBtn, SIGNAL(clicked()), SLOT(addPreset())); + ret = ret && connect(m_unitsCB, SIGNAL(currentIndexChanged(int)), + SLOT(onCameraUnitChanged(int))); + ret = ret && + connect(m_removePresetBtn, SIGNAL(clicked()), SLOT(removePreset())); + ret = ret && connect(m_nameFld, SIGNAL(returnPressedNow()), createButton, + SLOT(animateClick())); + assert(ret); +} + +//----------------------------------------------------------------------------- + +void StartupPopup::showEvent(QShowEvent *) { + loadPresetList(); + updateProjectCB(); + m_nameFld->setFocus(); + m_pathFld->setPath(TApp::instance() + ->getCurrentScene() + ->getScene() + ->getProject() + ->getScenesPath() + .getQString()); + TDimensionD cameraSize = TApp::instance() + ->getCurrentScene() + ->getScene() + ->getCurrentCamera() + ->getSize(); + TDimension cameraRes = TApp::instance() + ->getCurrentScene() + ->getScene() + ->getCurrentCamera() + ->getRes(); + double fps = TApp::instance() + ->getCurrentScene() + ->getScene() + ->getProperties() + ->getOutputProperties() + ->getFrameRate(); + m_widthFld->setValue(cameraSize.lx); + m_heightFld->setValue(cameraSize.ly); + if (Preferences::instance()->getCameraUnits() == "pixel") { + m_widthFld->setDecimals(0); + m_heightFld->setDecimals(0); + m_resTextLabel->hide(); + m_resXFld->hide(); + m_resYFld->hide(); + m_resXLabel->hide(); + m_dpiFld->hide(); + m_dpiLabel->hide(); + } else { + m_widthFld->setDecimals(4); + m_heightFld->setDecimals(4); + m_resXFld->show(); + m_resYFld->show(); + m_resXLabel->show(); + m_resTextLabel->show(); + m_dpiFld->show(); + m_dpiLabel->show(); + } + + m_fpsFld->setValue(fps); + m_unitsCB->setCurrentText(Preferences::instance()->getCameraUnits()); + m_dpi = cameraRes.lx / cameraSize.lx; + m_xRes = cameraRes.lx; + m_yRes = cameraRes.ly; + m_resXFld->setValue(m_xRes); + m_resYFld->setValue(m_yRes); + m_resXFld->setDecimals(0); + m_resYFld->setDecimals(0); + m_dpiFld->setValue(m_dpi); + + int boxWidth = m_sceneBox->width(); + int boxHeight = m_sceneBox->height(); + m_sceneBox->setFixedWidth(boxWidth); + m_projectBox->setFixedWidth(boxWidth); + m_recentBox->setMinimumHeight(boxHeight); + + // update recent scenes + // clear items if they exist first + + if (m_recentSceneLay->count() > 0) { + QLayoutItem *child; + while (m_recentSceneLay->count() != 0) { + child = m_recentSceneLay->takeAt(0); + delete child; + } + } + + m_sceneNames = RecentFiles::instance()->getFilesNameList(RecentFiles::Scene); + m_recentNamesLabels = QVector(m_sceneNames.count()); + + if (m_sceneNames.count() <= 0) { + m_recentSceneLay->addWidget(new QLabel(tr("No Recent Scenes"), this), 1, + Qt::AlignTop); + } else { + int i = 0; + for (QString name : m_sceneNames) { + if (i > 9) break; // box can hold 10 scenes + QString justName = QString::fromStdString(TFilePath(name).getName()); + m_recentNamesLabels[i] = new StartupLabel(justName, this, i); + m_recentNamesLabels[i]->setToolTip( + name.remove(0, name.indexOf(" ") + 1)); // remove "#. " prefix + m_recentSceneLay->addWidget(m_recentNamesLabels[i], i, Qt::AlignTop); + i++; + } + m_recentSceneLay->addStretch(100); + } + + bool ret = true; + for (int i = 0; i < m_recentNamesLabels.count() && i < 7; i++) { + ret = ret && connect(m_recentNamesLabels[i], SIGNAL(wasClicked(int)), this, + SLOT(onRecentSceneClicked(int))); + } + assert(ret); + // center window + this->move(QApplication::desktop()->screen()->rect().center() - + this->rect().center()); +} + +//----------------------------------------------------------------------------- + +void StartupPopup::onCreateButton() { + if (m_nameFld->text().trimmed() == "") { + DVGui::warning(tr("The name cannot be empty.")); + m_nameFld->setFocus(); + return; + } + if (!TSystem::doesExistFileOrLevel(TFilePath(m_pathFld->getPath()))) { + DVGui::warning(tr("The chosen file path is not valid.")); + m_pathFld->setFocus(); + return; + } + + if (m_widthFld->getValue() < 1) { + DVGui::warning(tr("The width must be 1 or more.")); + m_widthFld->setFocus(); + return; + } + if (m_heightFld->getValue() < 1) { + DVGui::warning(tr("The height must be 1 or more.")); + m_heightFld->setFocus(); + return; + } + if (m_fpsFld->getValue() < 1) { + DVGui::warning(tr("The frame rate must be 1 or more.")); + m_fpsFld->setFocus(); + return; + } + if (TSystem::doesExistFileOrLevel( + TFilePath(m_pathFld->getPath()) + + TFilePath(m_nameFld->text().trimmed().toStdWString() + L".tnz"))) { + QString question; + question = QObject::tr( + "The file name already exists." + "\nDo you want to overwrite it?"); + int ret = DVGui::MsgBox(question, QObject::tr("Yes"), QObject::tr("No"), 0); + if (ret == 0 || ret == 2) { + // no (or closed message box window) + return; + ; + } + } + CommandManager::instance()->execute(MI_NewScene); + TApp::instance()->getCurrentScene()->getScene()->setScenePath( + TFilePath(m_pathFld->getPath()) + + TFilePath(m_nameFld->text().trimmed().toStdWString())); + TDimensionD size = + TDimensionD(m_widthFld->getValue(), m_heightFld->getValue()); + TDimension res = TDimension(m_xRes, m_yRes); + double fps = m_fpsFld->getValue(); + TApp::instance() + ->getCurrentScene() + ->getScene() + ->getProperties() + ->getOutputProperties() + ->setFrameRate(fps); + TApp::instance()->getCurrentScene()->getScene()->getCurrentCamera()->setSize( + size); + TApp::instance()->getCurrentScene()->getScene()->getCurrentCamera()->setRes( + res); + // this one is debatable - should the scene be saved right away? + // IoCmd::saveScene(); + // this makes sure the scene viewers update to the right fps + TApp::instance()->getCurrentScene()->notifySceneSwitched(); + + hide(); +} + +//----------------------------------------------------------------------------- + +void StartupPopup::updateProjectCB() { + m_updating = true; + m_projectPaths.clear(); + m_projectsCB->clear(); + + TFilePath sandboxFp = TProjectManager::instance()->getSandboxProjectFolder() + + "sandbox_otprj.xml"; + m_projectPaths.push_back(sandboxFp); + m_projectsCB->addItem("sandbox"); + + std::vector prjRoots; + TProjectManager::instance()->getProjectRoots(prjRoots); + for (int i = 0; i < prjRoots.size(); i++) { + TFilePathSet fps; + TSystem::readDirectory_Dir_ReadExe(fps, prjRoots[i]); + + TFilePathSet::iterator it; + for (it = fps.begin(); it != fps.end(); ++it) { + TFilePath fp(*it); + if (TProjectManager::instance()->isProject(fp)) { + m_projectPaths.push_back( + TProjectManager::instance()->projectFolderToProjectPath(fp)); + m_projectsCB->addItem(QString::fromStdString(fp.getName())); + } + } + } + int i; + for (i = 0; i < m_projectPaths.size(); i++) { + if (TProjectManager::instance()->getCurrentProjectPath() == + m_projectPaths[i]) { + m_projectsCB->setCurrentIndex(i); + break; + } + } + m_pathFld->setPath(TApp::instance() + ->getCurrentScene() + ->getScene() + ->getProject() + ->getScenesPath() + .getQString()); + m_updating = false; +} + +//----------------------------------------------------------------------------- + +void StartupPopup::onProjectChanged(int index) { + if (m_updating) return; + TFilePath projectFp = m_projectPaths[index]; + + TProjectManager::instance()->setCurrentProjectPath(projectFp); + + IoCmd::newScene(); + m_pathFld->setPath(TApp::instance() + ->getCurrentScene() + ->getScene() + ->getProject() + ->getScenesPath() + .getQString()); + m_fpsFld->setValue(TApp::instance() + ->getCurrentScene() + ->getScene() + ->getProperties() + ->getOutputProperties() + ->getFrameRate()); + TDimension res = TApp::instance() + ->getCurrentScene() + ->getScene() + ->getCurrentCamera() + ->getRes(); + m_xRes = res.lx; + m_yRes = res.ly; + m_resXFld->setValue(m_xRes); + m_resYFld->setValue(m_yRes); + TDimensionD size = TApp::instance() + ->getCurrentScene() + ->getScene() + ->getCurrentCamera() + ->getSize(); + m_widthFld->setValue(size.lx); + m_heightFld->setValue(size.ly); + m_dpi = m_xRes / size.lx; + m_dpiFld->setValue(m_dpi); +} + +//----------------------------------------------------------------------------- + +void StartupPopup::loadPresetList() { + m_presetCombo->clear(); + m_presetCombo->addItem("..."); + m_presetListFile = ToonzFolder::getReslistPath(false).getQString(); + QFile file(m_presetListFile); + if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { + QTextStream in(&file); + while (!in.atEnd()) { + QString line = in.readLine().trimmed(); + if (line != "") m_presetCombo->addItem(line); + } + } + m_presetCombo->setCurrentIndex(0); +} + +//----------------------------------------------------------------------------- + +void StartupPopup::savePresetList() { + QFile file(m_presetListFile); + if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) return; + QTextStream out(&file); + int n = m_presetCombo->count(); + for (int i = 1; i < n; i++) out << m_presetCombo->itemText(i) << "\n"; +} + +//----------------------------------------------------------------------------- + +void StartupPopup::addPreset() { + int xRes = (int)(m_widthFld->getValue() * m_dpi); + int yRes = (int)(m_heightFld->getValue() * m_dpi); + double lx = m_widthFld->getValue(); + double ly = m_heightFld->getValue(); + double ar = m_widthFld->getValue() / m_heightFld->getValue(); + + QString presetString; + presetString = QString::number(xRes) + "x" + QString::number(yRes) + ", " + + removeZeros(QString::number(lx)) + "x" + + removeZeros(QString::number(ly)) + ", " + + aspectRatioValueToString(ar); + + bool ok; + QString qs; + while (1) { + qs = DVGui::getText(tr("Preset name"), + tr("Enter the name for %1").arg(presetString), "", &ok); + + if (!ok) return; + + if (qs.indexOf(",") != -1) + QMessageBox::warning(this, tr("Error : Preset Name is Invalid"), + tr("The preset name must not use ','(comma).")); + else + break; + } + + int oldn = m_presetCombo->count(); + m_presetCombo->addItem(qs + "," + presetString); + int newn = m_presetCombo->count(); + m_presetCombo->blockSignals(true); + m_presetCombo->setCurrentIndex(m_presetCombo->count() - 1); + m_presetCombo->blockSignals(false); + + savePresetList(); +} + +//----------------------------------------------------------------------------- + +void StartupPopup::removePreset() { + int index = m_presetCombo->currentIndex(); + if (index <= 0) return; + + // confirmation dialog + int ret = DVGui::MsgBox(QObject::tr("Deleting \"%1\".\nAre you sure?") + .arg(m_presetCombo->currentText()), + QObject::tr("Delete"), QObject::tr("Cancel")); + if (ret == 0 || ret == 2) return; + + m_presetCombo->removeItem(index); + m_presetCombo->setCurrentIndex(0); + savePresetList(); +} + +//----------------------------------------------------------------------------- + +void StartupPopup::onPresetSelected(const QString &str) { + if (str == custom || str.isEmpty()) return; + QString name, arStr; + int xres = 0, yres = 0; + double fx = -1.0, fy = -1.0; + QString xoffset = "", yoffset = ""; + double ar; + + if (parsePresetString(str, name, xres, yres, fx, fy, xoffset, yoffset, ar, + false)) { + m_xRes = xres; + m_yRes = yres; + // The current solution is to preserve the DPI so that scenes are less + // likely to become incompatible with pixels only mode in the future + // Commented below is the default behavior of the camera settings widget + // m_widthFld->setValue(m_heightFld->getValue() * ar); + // m_dpiFld->setValue(m_xRes / m_widthFld->getValue()); + + // here is the system that preserves dpi + m_widthFld->setValue((double)xres / (double)m_dpi); + m_heightFld->setValue((double)yres / (double)m_dpi); + if (Preferences::instance()->getPixelsOnly()) { + m_widthFld->setValue((double)xres / Stage::standardDpi); + m_heightFld->setValue((double)yres / Stage::standardDpi); + m_dpiFld->setValue(Stage::standardDpi); + } + m_resXFld->setValue(m_xRes); + m_resYFld->setValue(m_yRes); + } else { + QMessageBox::warning( + this, tr("Bad camera preset"), + tr("'%1' doesn't seem to be a well formed camera preset. \n" + "Possibly the preset file has been corrupted") + .arg(str)); + } +} + +//-------------------------------------------------------------------------- + +bool StartupPopup::parsePresetString(const QString &str, QString &name, + int &xres, int &yres, double &fx, + double &fy, QString &xoffset, + QString &yoffset, double &ar, + bool forCleanup) { + /* + parsing preset string with QString::split(). + !NOTE! fx/fy (camera size in inch) and xoffset/yoffset (camera offset used in + cleanup camera) are optional, + in order to keep compatibility with default (Harlequin's) reslist.txt + */ + + QStringList tokens = str.split(",", QString::SkipEmptyParts); + + if (!(tokens.count() == 3 || + (!forCleanup && tokens.count() == 4) || /*- with "fx x fy" token -*/ + (forCleanup && + tokens.count() == + 6))) /*- with "fx x fy", xoffset and yoffset tokens -*/ + return false; + /*- name -*/ + name = tokens[0]; + + /*- xres, yres (like: 1024x768) -*/ + QStringList values = tokens[1].split("x"); + if (values.count() != 2) return false; + bool ok; + xres = values[0].toInt(&ok); + if (!ok) return false; + yres = values[1].toInt(&ok); + if (!ok) return false; + + if (tokens.count() >= 4) { + /*- fx, fy -*/ + values = tokens[2].split("x"); + if (values.count() != 2) return false; + fx = values[0].toDouble(&ok); + if (!ok) return false; + fy = values[1].toDouble(&ok); + if (!ok) return false; + + /*- xoffset, yoffset -*/ + if (forCleanup) { + xoffset = tokens[3]; + yoffset = tokens[4]; + /*- remove single space -*/ + if (xoffset.startsWith(' ')) xoffset.remove(0, 1); + if (yoffset.startsWith(' ')) yoffset.remove(0, 1); + } + } + + /*- AR -*/ + ar = aspectRatioStringToValue(tokens.last()); + + return true; +} + +//----------------------------------------------------------------------------- + +double StartupPopup::aspectRatioStringToValue(const QString &s) { + if (s == "") { + return 1; + } + int i = s.indexOf("/"); + if (i <= 0 || i + 1 >= s.length()) return s.toDouble(); + int num = s.left(i).toInt(); + int den = s.mid(i + 1).toInt(); + if (den <= 0) den = 1; + return (double)num / (double)den; +} + +//----------------------------------------------------------------------------- + +// A/R : value => string (e.g. '4/3' or '1.23') +QString StartupPopup::aspectRatioValueToString(double value, int width, + int height) { + double v = value; + + if (width != 0 && height != 0) { + if (areAlmostEqual(value, (double)width / (double)height, 1e-3)) + return QString("%1/%2").arg(width).arg(height); + } + + double iv = tround(v); + if (fabs(iv - v) > 0.01) { + for (int d = 2; d < 20; d++) { + int n = tround(v * d); + if (fabs(n - v * d) <= 0.01) + return QString::number(n) + "/" + QString::number(d); + } + return QString::number(value, 'f', 5); + } else { + return QString::number((int)iv); + } +} + +//----------------------------------------------------------------------------- + +void StartupPopup::onNewProjectButtonPressed() { + CommandManager::instance()->execute(MI_NewProject); +} + +//----------------------------------------------------------------------------- + +void StartupPopup::onSceneChanged() { + // close the box if a recent scene has been selected + if (!TApp::instance()->getCurrentScene()->getScene()->isUntitled()) { + hide(); + } else { + updateProjectCB(); + } +} + +//----------------------------------------------------------------------------- + +void StartupPopup::onDpiChanged() { + if (Preferences::instance()->getPixelsOnly()) { + m_dpi = Stage::standardDpi; + m_dpiFld->setValue(Stage::standardDpi); + updateResolution(); + } else { + m_dpi = m_dpiFld->getValue(); + updateResolution(); + } +} + +//----------------------------------------------------------------------------- + +void StartupPopup::onLoadSceneButtonPressed() { + CommandManager::instance()->execute(MI_LoadScene); +} + +//----------------------------------------------------------------------------- + +void StartupPopup::onRecentSceneClicked(int index) { + if (index < 0) return; + QString path = + RecentFiles::instance()->getFilePath(index, RecentFiles::Scene); + IoCmd::loadScene(TFilePath(path.toStdWString()), false); + RecentFiles::instance()->moveFilePath(index, 0, RecentFiles::Scene); + RecentFiles::instance()->refreshRecentFilesMenu(RecentFiles::Scene); + hide(); +} + +//----------------------------------------------------------------------------- + +void StartupPopup::onCameraUnitChanged(int index) { + Preferences *pref = Preferences::instance(); + QStringList type; + type << tr("pixel") << tr("cm") << tr("mm") << tr("inch") << tr("field"); + + double width = m_widthFld->getValue(); + double height = m_heightFld->getValue(); + if (index != 0) { + pref->setPixelsOnly(false); + pref->setCameraUnits(type[index].toStdString()); + m_widthFld->setDecimals(4); + m_heightFld->setDecimals(4); + m_resTextLabel->show(); + m_resXFld->show(); + m_resYFld->show(); + m_resXLabel->show(); + m_dpiFld->show(); + m_dpiLabel->show(); + m_widthFld->setMeasure("camera.lx"); + m_heightFld->setMeasure("camera.ly"); + m_widthFld->setValue(width); + m_heightFld->setValue(height); + } else { + pref->setPixelsOnly(true); + pref->setUnits("pixel"); + pref->setCameraUnits("pixel"); + m_widthFld->setDecimals(0); + m_heightFld->setDecimals(0); + m_resTextLabel->hide(); + m_resXFld->hide(); + m_resYFld->hide(); + m_resXLabel->hide(); + m_dpiFld->hide(); + m_dpiLabel->hide(); + m_dpiFld->setValue(Stage::standardDpi); + m_widthFld->setMeasure("camera.lx"); + m_heightFld->setMeasure("camera.ly"); + m_widthFld->setValue(m_xRes / Stage::standardDpi); + m_heightFld->setValue(m_yRes / Stage::standardDpi); + } +} + +//----------------------------------------------------------------------------- + +void StartupPopup::onShowAtStartChanged(int index) { + Preferences::instance()->enableStartupPopup(index); +} + +//----------------------------------------------------------------------------- + +void StartupPopup::updateResolution() { + if (Preferences::instance()->getPixelsOnly()) { + if (m_dpiFld->getValue() != Stage::standardDpi) { + m_dpiFld->setValue(Stage::standardDpi); + } + m_xRes = m_widthFld->getValue() * Stage::standardDpi; + m_yRes = m_heightFld->getValue() * Stage::standardDpi; + m_resXFld->setValue(m_xRes); + m_resYFld->setValue(m_yRes); + } else { + m_xRes = m_widthFld->getValue() * m_dpi; + m_yRes = m_heightFld->getValue() * m_dpi; + m_resXFld->setValue(m_xRes); + m_resYFld->setValue(m_yRes); + } + m_presetCombo->setCurrentIndex(0); +} + +//----------------------------------------------------------------------------- + +void StartupPopup::updateSize() { + m_xRes = m_resXFld->getValue(); + m_yRes = m_resYFld->getValue(); + if (Preferences::instance()->getPixelsOnly()) { + if (m_dpiFld->getValue() != Stage::standardDpi) { + m_dpiFld->setValue(Stage::standardDpi); + } + m_widthFld->setValue((double)m_xRes / Stage::standardDpi); + m_heightFld->setValue((double)m_yRes / Stage::standardDpi); + } else { + m_widthFld->setValue((double)m_xRes / m_dpi); + m_heightFld->setValue((double)m_yRes / m_dpi); + } + m_presetCombo->setCurrentIndex(0); +} + +//----------------------------------------------------------------------------- + +StartupLabel::StartupLabel(const QString &text, QWidget *parent, int index) + : QLabel(parent), m_index(index) { + setText(text); + setObjectName("StartupLabel"); +} + +StartupLabel::~StartupLabel() {} + +void StartupLabel::mousePressEvent(QMouseEvent *event) { + m_text = text(); + std::string strText = m_text.toStdString(); + emit wasClicked(m_index); +} + +OpenPopupCommandHandler openStartupPopup(MI_StartupPopup); diff --git a/toonz/sources/toonz/startuppopup.h b/toonz/sources/toonz/startuppopup.h new file mode 100644 index 0000000..cd1e33d --- /dev/null +++ b/toonz/sources/toonz/startuppopup.h @@ -0,0 +1,109 @@ +#pragma once + +#ifndef STARTUPPOPUP_H +#define STARTUPPOPUP_H + +#include "toonzqt/dvdialog.h" +#include "toonzqt/doublefield.h" +#include "toonzqt/intfield.h" +#include "toonzqt/filefield.h" +#include "toonzqt/camerasettingswidget.h" +#include +#include +#include +#include + +// forward declaration +class QLabel; +class QComboBox; +class StartupLabel; + +//============================================================================= +// LevelCreatePopup +//----------------------------------------------------------------------------- + +class StartupPopup final : public DVGui::Dialog { + Q_OBJECT + + DVGui::LineEdit *m_nameFld; + DVGui::FileField *m_pathFld; + QLabel *m_widthLabel; + QLabel *m_heightLabel; + QLabel *m_fpsLabel; + QLabel *m_resXLabel; + QLabel *m_resTextLabel; + QLabel *m_dpiLabel; + QLabel *m_sceneNameLabel; + DVGui::DoubleLineEdit *m_dpiFld; + DVGui::MeasuredDoubleLineEdit *m_widthFld; + DVGui::MeasuredDoubleLineEdit *m_heightFld; + DVGui::DoubleLineEdit *m_fpsFld; + DVGui::DoubleLineEdit *m_resXFld; + DVGui::DoubleLineEdit *m_resYFld; + QList m_sceneNames; + QList m_projectPaths; + QCheckBox *m_showAtStartCB; + QComboBox *m_projectsCB; + QComboBox *m_unitsCB; + QPushButton *m_loadOtherSceneButton; + QPushButton *m_newProjectButton; + QComboBox *m_presetCombo; + QPushButton *m_addPresetBtn, *m_removePresetBtn; + CameraSettingsWidget *m_cameraSettingsWidget; + double m_dpi; + int m_xRes, m_yRes; + bool m_updating = false; + QString m_presetListFile; + QGroupBox *m_projectBox; + QGroupBox *m_sceneBox; + QGroupBox *m_recentBox; + QVBoxLayout *m_recentSceneLay; + QVector m_recentNamesLabels; + +public: + StartupPopup(); + +protected: + void showEvent(QShowEvent *) override; + void loadPresetList(); + void savePresetList(); + QString aspectRatioValueToString(double value, int width = 0, int height = 0); + double aspectRatioStringToValue(const QString &s); + bool parsePresetString(const QString &str, QString &name, int &xres, + int &yres, double &fx, double &fy, QString &xoffset, + QString &yoffset, double &ar, bool forCleanup = false); + +public slots: + void onRecentSceneClicked(int index); + void onCreateButton(); + void onShowAtStartChanged(int index); + void updateProjectCB(); + void onProjectChanged(int index); + void onNewProjectButtonPressed(); + void onLoadSceneButtonPressed(); + void onSceneChanged(); + void updateResolution(); + void updateSize(); + void onDpiChanged(); + void addPreset(); + void removePreset(); + void onPresetSelected(const QString &str); + void onCameraUnitChanged(int index); +}; + +class StartupLabel : public QLabel { + Q_OBJECT +public: + explicit StartupLabel(const QString &text = "", QWidget *parent = 0, + int index = -1); + ~StartupLabel(); + QString m_text; + int m_index; +signals: + void wasClicked(int index); + +protected: + void mousePressEvent(QMouseEvent *event); +}; + +#endif // STARTUPPOPUP_H diff --git a/toonz/sources/toonz/styleshortcutswitchablepanel.cpp b/toonz/sources/toonz/styleshortcutswitchablepanel.cpp new file mode 100644 index 0000000..d680521 --- /dev/null +++ b/toonz/sources/toonz/styleshortcutswitchablepanel.cpp @@ -0,0 +1,112 @@ +#include "styleshortcutswitchablepanel.h" + +// TnzLib includes +#include "toonz/tscenehandle.h" +#include "toonz/preferences.h" +#include "toonz/palettecontroller.h" +#include "toonz/tpalettehandle.h" + +// TnzTools includes +#include "tools/toolhandle.h" +#include "tools/toolcommandids.h" + +// TnzQt includes +#include "toonzqt/tselectionhandle.h" +#include "toonzqt/styleselection.h" + +// Tnz6 includes +#include "tapp.h" + +#include + +//----------------------------------------------------------------------------- + +void StyleShortcutSwitchablePanel::keyPressEvent(QKeyEvent *event) { + if (!Preferences::instance()->isUseNumpadForSwitchingStylesEnabled()) return; + TTool *tool = TApp::instance()->getCurrentTool()->getTool(); + if (!tool) return; + if (tool->getName() == T_Type && tool->isActive()) return; + if (event->modifiers() != Qt::NoModifier && + event->modifiers() != Qt::KeypadModifier) + return; + int key = event->key(); + if (Qt::Key_0 <= key && key <= Qt::Key_9) { + TPaletteHandle *ph = + TApp::instance()->getPaletteController()->getCurrentLevelPalette(); + + TPalette *palette = ph->getPalette(); + if (palette) { + int styleId = palette->getShortcutValue(key); + if (styleId >= 0) { + ph->setStyleIndex(styleId); + TStyleSelection *selection = dynamic_cast( + TApp::instance()->getCurrentSelection()->getSelection()); + if (selection) selection->selectNone(); + } + } + event->accept(); + } else if (key == Qt::Key_Tab || key == Qt::Key_Backtab) { + TPaletteHandle *ph = + TApp::instance()->getPaletteController()->getCurrentLevelPalette(); + + TPalette *palette = ph->getPalette(); + if (palette) { + palette->nextShortcutScope(key == Qt::Key_Backtab); + ph->notifyPaletteChanged(); + } + event->accept(); + } +} + +//----------------------------------------------------------------------------- + +void StyleShortcutSwitchablePanel::showEvent(QShowEvent *event) { + TPanel::showEvent(event); + bool ret = connect(TApp::instance()->getCurrentScene(), + SIGNAL(preferenceChanged(const QString &)), this, + SLOT(onPreferenceChanged(const QString &))); + onPreferenceChanged(""); + assert(ret); +} + +//----------------------------------------------------------------------------- + +void StyleShortcutSwitchablePanel::hideEvent(QHideEvent *event) { + TPanel::hideEvent(event); + disconnect(TApp::instance()->getCurrentScene(), + SIGNAL(preferenceChanged(const QString &)), this, + SLOT(onPreferenceChanged(const QString &))); +} + +//----------------------------------------------------------------------------- + +void StyleShortcutSwitchablePanel::onPreferenceChanged( + const QString &prefName) { + if (prefName == "NumpadForSwitchingStyles" || prefName.isEmpty()) + updateTabFocus(); +} + +//----------------------------------------------------------------------------- + +void StyleShortcutSwitchablePanel::updateTabFocus() { + QList widgets = findChildren(); + if (Preferences::instance()->isUseNumpadForSwitchingStylesEnabled()) { + // disable tab focus + foreach (QWidget *widget, widgets) { + Qt::FocusPolicy policy = widget->focusPolicy(); + if (policy == Qt::TabFocus || policy == Qt::StrongFocus || + policy == Qt::WheelFocus) { + m_childrenFocusPolicies[widget] = policy; + widget->setFocusPolicy((policy == Qt::TabFocus) ? Qt::NoFocus + : Qt::ClickFocus); + } + } + } else { + // revert tab focus + QHashIterator i(m_childrenFocusPolicies); + while (i.hasNext()) { + i.next(); + i.key()->setFocusPolicy(i.value()); + } + } +} \ No newline at end of file diff --git a/toonz/sources/toonz/styleshortcutswitchablepanel.h b/toonz/sources/toonz/styleshortcutswitchablepanel.h new file mode 100644 index 0000000..ce68933 --- /dev/null +++ b/toonz/sources/toonz/styleshortcutswitchablepanel.h @@ -0,0 +1,39 @@ +#pragma once + +#ifndef STYLE_SHORTCUT_SWITCHABLE_PANEL_H +#define STYLE_SHORTCUT_SWITCHABLE_PANEL_H + +#include "pane.h" + +//============================================================================= +// StyleShortcutSwitchablePanel +//----------------------------------------------------------------------------- +// StyleShortcutSwitchablePanel class is subclass of TPanel and +// inherited by panels which can select the current style by 0-9 +// number keys if the Preferences option +// "Use Numpad and Tab keys for Switching Styles" is active. +// Currently inherited by ComboViewer, Viewer and Palette +//----------------------------------------------------------------------------- + +class StyleShortcutSwitchablePanel : public TPanel { + Q_OBJECT + + QHash m_childrenFocusPolicies; + +public: + StyleShortcutSwitchablePanel( + QWidget *parent = 0, Qt::WindowFlags flags = 0, + TDockWidget::Orientation orientation = TDockWidget::vertical) + : TPanel(parent, flags, orientation) {} + +protected: + void keyPressEvent(QKeyEvent *event) override; + void showEvent(QShowEvent *) override; + void hideEvent(QHideEvent *) override; + +protected slots: + virtual void onPreferenceChanged(const QString &prefName); + void updateTabFocus(); +}; + +#endif \ No newline at end of file diff --git a/toonz/sources/toonz/tapp.cpp b/toonz/sources/toonz/tapp.cpp index a6ef8b2..698fe26 100644 --- a/toonz/sources/toonz/tapp.cpp +++ b/toonz/sources/toonz/tapp.cpp @@ -673,16 +673,25 @@ void TApp::autosave() { } else m_autosaveSuspended = false; - if (scene->isUntitled()) { + if (scene->isUntitled() && + Preferences::instance()->isAutosaveSceneEnabled()) { DVGui::warning( - tr("It is not possible to save automatically an untitled scene.")); + tr("It is not possible to automatically save an untitled scene.")); return; } DVGui::ProgressDialog pb( "Autosaving scene..." + toQString(scene->getScenePath()), 0, 0, 1); pb.show(); - IoCmd::saveScene(); + Preferences *pref = Preferences::instance(); + if (pref->isAutosaveSceneEnabled() && pref->isAutosaveOtherFilesEnabled()) { + IoCmd::saveAll(); + } else if (pref->isAutosaveSceneEnabled()) { + IoCmd::saveScene(); + } else if (pref->isAutosaveOtherFilesEnabled()) { + IoCmd::saveNonSceneFiles(); + } + pb.setValue(1); } @@ -705,7 +714,7 @@ void TApp::onStartAutoSave() { //----------------------------------------------------------------------------- void TApp::onStopAutoSave() { - assert(!Preferences::instance()->isAutosaveEnabled()); + // assert(!Preferences::instance()->isAutosaveEnabled()); m_autosaveTimer->stop(); } diff --git a/toonz/sources/toonz/toonz.qrc b/toonz/sources/toonz/toonz.qrc index 75aa7a1..3ad3f78 100644 --- a/toonz/sources/toonz/toonz.qrc +++ b/toonz/sources/toonz/toonz.qrc @@ -264,6 +264,7 @@ Resources/standard.png Resources/standard_on.png Resources/standard_over.png + Resources/startup.png Resources/start_off.png Resources/start_on.png Resources/stop_off.png @@ -442,5 +443,8 @@ Resources/finger_rollover.svg Resources/ruler.svg Resources/ruler_rollover.svg + Resources/locator.png + Resources/locator_click.png + Resources/locator_over.png diff --git a/toonz/sources/toonz/tpanels.cpp b/toonz/sources/toonz/tpanels.cpp index 74fee6a..8ed5795 100644 --- a/toonz/sources/toonz/tpanels.cpp +++ b/toonz/sources/toonz/tpanels.cpp @@ -402,7 +402,8 @@ public: // PaletteViewer //----------------------------------------------------------------------------- -PaletteViewerPanel::PaletteViewerPanel(QWidget *parent) : TPanel(parent) { +PaletteViewerPanel::PaletteViewerPanel(QWidget *parent) + : StyleShortcutSwitchablePanel(parent) { m_paletteHandle = new TPaletteHandle(); connect(m_paletteHandle, SIGNAL(colorStyleSwitched()), SLOT(onColorStyleSwitched())); diff --git a/toonz/sources/toonz/tpanels.h b/toonz/sources/toonz/tpanels.h index ed6cbf8..d6501d8 100644 --- a/toonz/sources/toonz/tpanels.h +++ b/toonz/sources/toonz/tpanels.h @@ -4,6 +4,7 @@ #define TPANELS_INCLUDED #include "pane.h" +#include "styleshortcutswitchablepanel.h" #include "tpalette.h" #include "trenderer.h" @@ -27,7 +28,7 @@ class ToolOptions; // PaletteViewerPanel //--------------------------------------------------------- -class PaletteViewerPanel final : public TPanel { +class PaletteViewerPanel final : public StyleShortcutSwitchablePanel { Q_OBJECT TPaletteHandle *m_paletteHandle; diff --git a/toonz/sources/toonz/viewerpane.cpp b/toonz/sources/toonz/viewerpane.cpp index 819a466..6fc4ef7 100644 --- a/toonz/sources/toonz/viewerpane.cpp +++ b/toonz/sources/toonz/viewerpane.cpp @@ -77,7 +77,7 @@ SceneViewerPanel::SceneViewerPanel(QWidget *parent, Qt::WindowFlags flags) #else SceneViewerPanel::SceneViewerPanel(QWidget *parent, Qt::WFlags flags) #endif - : TPanel(parent) { + : StyleShortcutSwitchablePanel(parent) { QFrame *hbox = new QFrame(this); hbox->setFrameStyle(QFrame::StyledPanel); hbox->setObjectName("ViewerPanel"); @@ -94,6 +94,7 @@ SceneViewerPanel::SceneViewerPanel(QWidget *parent, Qt::WFlags flags) new ImageUtils::FullScreenWidget(viewer); fsWidget->setWidget(m_sceneViewer = new SceneViewer(fsWidget)); + m_sceneViewer->setIsStyleShortcutSwitchable(); bool ret = true; ret = ret && connect(m_sceneViewer, SIGNAL(onZoomChanged()), @@ -120,7 +121,7 @@ SceneViewerPanel::SceneViewerPanel(QWidget *parent, Qt::WFlags flags) int buttons = FlipConsole::cFullConsole; - buttons &= (~FlipConsole::eSound); + // buttons &= (~FlipConsole::eSound); buttons &= (~FlipConsole::eFilledRaster); buttons &= (~FlipConsole::eDefineLoadBox); buttons &= (~FlipConsole::eUseLoadBox); @@ -150,6 +151,10 @@ SceneViewerPanel::SceneViewerPanel(QWidget *parent, Qt::WFlags flags) connect(m_flipConsole, SIGNAL(buttonPressed(FlipConsole::EGadget)), m_sceneViewer, SLOT(onButtonPressed(FlipConsole::EGadget))); + ret = + ret && connect(m_flipConsole, SIGNAL(buttonPressed(FlipConsole::EGadget)), + this, SLOT(onButtonPressed(FlipConsole::EGadget))); + ret = ret && connect(m_sceneViewer, SIGNAL(previewStatusChanged()), this, SLOT(update())); @@ -157,7 +162,8 @@ SceneViewerPanel::SceneViewerPanel(QWidget *parent, Qt::WFlags flags) SLOT(onSceneSwitched())); assert(ret); - + m_flipConsole->setChecked(FlipConsole::eSound, true); + m_playSound = m_flipConsole->isChecked(FlipConsole::eSound); m_flipConsole->setFrameRate(app->getCurrentScene() ->getScene() ->getProperties() @@ -220,7 +226,8 @@ SceneViewerPanel::~SceneViewerPanel() {} //----------------------------------------------------------------------------- -void SceneViewerPanel::showEvent(QShowEvent *) { +void SceneViewerPanel::showEvent(QShowEvent *event) { + StyleShortcutSwitchablePanel::showEvent(event); TApp *app = TApp::instance(); TFrameHandle *frameHandle = app->getCurrentFrame(); TSceneHandle *sceneHandle = app->getCurrentScene(); @@ -259,10 +266,6 @@ void SceneViewerPanel::showEvent(QShowEvent *) { ret = ret && connect(app->getCurrentTool(), SIGNAL(toolSwitched()), m_sceneViewer, SLOT(onToolSwitched())); - ret = ret && connect(sceneHandle, SIGNAL(preferenceChanged()), m_flipConsole, - SLOT(onPreferenceChanged())); - m_flipConsole->onPreferenceChanged(); - assert(ret); // Aggiorno FPS al valore definito nel viewer corrente. @@ -272,7 +275,8 @@ void SceneViewerPanel::showEvent(QShowEvent *) { //----------------------------------------------------------------------------- -void SceneViewerPanel::hideEvent(QHideEvent *) { +void SceneViewerPanel::hideEvent(QHideEvent *event) { + StyleShortcutSwitchablePanel::hideEvent(event); TApp *app = TApp::instance(); TFrameHandle *frameHandle = app->getCurrentFrame(); TSceneHandle *sceneHandle = app->getCurrentScene(); @@ -305,9 +309,6 @@ void SceneViewerPanel::hideEvent(QHideEvent *) { disconnect(app->getCurrentTool(), SIGNAL(toolSwitched()), m_sceneViewer, SLOT(onToolSwitched())); - disconnect(sceneHandle, SIGNAL(preferenceChanged()), m_flipConsole, - SLOT(onPreferenceChanged())); - m_flipConsole->setActive(false); } @@ -326,25 +327,49 @@ void SceneViewerPanel::initializeTitleBar(TPanelTitleBar *titleBar) { TPanelTitleBarButtonSet *viewModeButtonSet; m_referenceModeBs = viewModeButtonSet = new TPanelTitleBarButtonSet(); - int x = -188; + int x = -232; int iconWidth = 17; TPanelTitleBarButton *button; - button = new TPanelTitleBarButton(titleBar, ":Resources/freeze.png", - ":Resources/freeze_over.png", - ":Resources/freeze_on.png"); - button->setToolTip(tr("Freeze")); - titleBar->add(QPoint(x, 2), button); - ret = ret && connect(button, SIGNAL(toggled(bool)), m_sceneViewer, - SLOT(freeze(bool))); - ret = ret && connect(m_sceneViewer, SIGNAL(freezeStateChanged(bool)), button, - SLOT(setPressed(bool))); + // buttons for show / hide toggle for the field guide and the safe area + TPanelTitleBarButtonForSafeArea *safeAreaButton = + new TPanelTitleBarButtonForSafeArea(titleBar, ":Resources/safearea.png", + ":Resources/safearea_over.png", + ":Resources/safearea_on.png"); + safeAreaButton->setToolTip(tr("Safe Area (Right Click to Select)")); + titleBar->add(QPoint(x, 1), safeAreaButton); + ret = ret && connect(safeAreaButton, SIGNAL(toggled(bool)), + CommandManager::instance()->getAction(MI_SafeArea), + SLOT(trigger())); + ret = ret && connect(CommandManager::instance()->getAction(MI_SafeArea), + SIGNAL(triggered(bool)), safeAreaButton, + SLOT(setPressed(bool))); + // initialize state + safeAreaButton->setPressed( + CommandManager::instance()->getAction(MI_SafeArea)->isChecked()); + + button = new TPanelTitleBarButton(titleBar, ":Resources/fieldguide.png", + ":Resources/fieldguide_over.png", + ":Resources/fieldguide_on.png"); + button->setToolTip(tr("Field Guide")); + x += 5 + iconWidth; + titleBar->add(QPoint(x, 1), button); + ret = ret && connect(button, SIGNAL(toggled(bool)), + CommandManager::instance()->getAction(MI_FieldGuide), + SLOT(trigger())); + ret = ret && connect(CommandManager::instance()->getAction(MI_FieldGuide), + SIGNAL(triggered(bool)), button, SLOT(setPressed(bool))); + // initialize state + button->setPressed( + CommandManager::instance()->getAction(MI_FieldGuide)->isChecked()); + + // view mode toggles button = new TPanelTitleBarButton(titleBar, ":Resources/standard.png", ":Resources/standard_over.png", ":Resources/standard_on.png"); button->setToolTip(tr("Camera Stand View")); - x += 18 + iconWidth; - titleBar->add(QPoint(x, 2), button); + x += 10 + iconWidth; + titleBar->add(QPoint(x, 1), button); button->setButtonSet(viewModeButtonSet, SceneViewer::NORMAL_REFERENCE); button->setPressed(true); @@ -352,25 +377,37 @@ void SceneViewerPanel::initializeTitleBar(TPanelTitleBar *titleBar) { ":Resources/3D_over.png", ":Resources/3D_on.png"); button->setToolTip(tr("3D View")); - x += 5 + iconWidth; - titleBar->add(QPoint(x, 2), button); + x += 19; // width of standard.png = 18pixels + titleBar->add(QPoint(x, 1), button); button->setButtonSet(viewModeButtonSet, SceneViewer::CAMERA3D_REFERENCE); button = new TPanelTitleBarButton(titleBar, ":Resources/view_camera.png", ":Resources/view_camera_over.png", ":Resources/view_camera_on.png"); button->setToolTip(tr("Camera View")); - x += 5 + iconWidth; - titleBar->add(QPoint(x, 2), button); + x += 18; // width of 3D.png = 18pixels + titleBar->add(QPoint(x, 1), button); button->setButtonSet(viewModeButtonSet, SceneViewer::CAMERA_REFERENCE); ret = ret && connect(viewModeButtonSet, SIGNAL(selected(int)), m_sceneViewer, SLOT(setReferenceMode(int))); + // freeze button + button = new TPanelTitleBarButton(titleBar, ":Resources/freeze.png", + ":Resources/freeze_over.png", + ":Resources/freeze_on.png"); + x += 10 + 19; // width of viewcamera.png = 18pixels + + button->setToolTip(tr("Freeze")); // RC1 + titleBar->add(QPoint(x, 1), button); + ret = ret && connect(button, SIGNAL(toggled(bool)), m_sceneViewer, + SLOT(freeze(bool))); + + // preview toggles m_previewButton = new TPanelTitleBarButton( titleBar, ":Resources/viewpreview.png", ":Resources/viewpreview_over.png", ":Resources/viewpreview_on.png"); - x += 18 + iconWidth; - titleBar->add(QPoint(x, 2), m_previewButton); + x += 5 + iconWidth; + titleBar->add(QPoint(x, 1), m_previewButton); m_previewButton->setToolTip(tr("Preview")); ret = ret && connect(m_previewButton, SIGNAL(toggled(bool)), SLOT(enableFullPreview(bool))); @@ -379,8 +416,9 @@ void SceneViewerPanel::initializeTitleBar(TPanelTitleBar *titleBar) { new TPanelTitleBarButton(titleBar, ":Resources/subcamera_preview.png", ":Resources/subcamera_preview_over.png", ":Resources/subcamera_preview_on.png"); - x += 5 + iconWidth; - titleBar->add(QPoint(x, 2), m_subcameraPreviewButton); + x += 28; // width of viewpreview.png =28pixels + + titleBar->add(QPoint(x, 1), m_subcameraPreviewButton); m_subcameraPreviewButton->setToolTip(tr("Sub-camera Preview")); ret = ret && connect(m_subcameraPreviewButton, SIGNAL(toggled(bool)), SLOT(enableSubCameraPreview(bool))); @@ -437,6 +475,12 @@ void SceneViewerPanel::onXshLevelSwitched(TXshLevel *) { changeWindowTitle(); } //----------------------------------------------------------------------------- void SceneViewerPanel::onPlayingStatusChanged(bool playing) { + if (playing) { + m_playing = true; + } else { + m_playing = false; + m_first = true; + } if (Preferences::instance()->getOnionSkinDuringPlayback()) return; OnionSkinMask osm = TApp::instance()->getCurrentOnionSkin()->getOnionSkinMask(); @@ -541,7 +585,6 @@ void SceneViewerPanel::onSceneChanged() { updateFrameRange(); updateFrameMarkers(); changeWindowTitle(); - TApp *app = TApp::instance(); ToonzScene *scene = app->getCurrentScene()->getScene(); assert(scene); @@ -551,6 +594,7 @@ void SceneViewerPanel::onSceneChanged() { int frameIndex = TApp::instance()->getCurrentFrame()->getFrameIndex(); if (m_keyFrameButton->getCurrentFrame() != frameIndex) m_keyFrameButton->setCurrentFrame(frameIndex); + hasSoundtrack(); } //----------------------------------------------------------------------------- @@ -578,6 +622,14 @@ void SceneViewerPanel::onFrameSwitched() { m_flipConsole->setCurrentFrame(frameIndex + 1); if (m_keyFrameButton->getCurrentFrame() != frameIndex) m_keyFrameButton->setCurrentFrame(frameIndex); + + if (m_playing && m_playSound) { + if (m_first == true && hasSoundtrack()) { + playAudioFrame(frameIndex); + } else if (m_hasSoundtrack) { + playAudioFrame(frameIndex); + } + } } //----------------------------------------------------------------------------- @@ -601,3 +653,64 @@ void SceneViewerPanel::onFrameTypeChanged() { updateFrameRange(); updateFrameMarkers(); } + +//----------------------------------------------------------------------------- + +void SceneViewerPanel::onPreferenceChanged(const QString &prefName) { + // if no name specified (on StyleShortcutSelectivePanel::showEvent), + // then process all updates + if (prefName == "BlankCount" || prefName == "BlankColor" || + prefName.isEmpty()) + m_flipConsole->onPreferenceChanged(); + + StyleShortcutSwitchablePanel::onPreferenceChanged(prefName); +} + +//----------------------------------------------------------------------------- + +void SceneViewerPanel::playAudioFrame(int frame) { + if (m_first) { + m_first = false; + m_fps = TApp::instance() + ->getCurrentScene() + ->getScene() + ->getProperties() + ->getOutputProperties() + ->getFrameRate(); + m_samplesPerFrame = m_sound->getSampleRate() / abs(m_fps); + } + if (!m_sound) return; + m_viewerFps = m_flipConsole->getCurrentFps(); + double s0 = frame * m_samplesPerFrame, s1 = s0 + m_samplesPerFrame; + + // make the sound stop if the viewerfps is higher so the next sound can play + // on time. + if (m_fps < m_viewerFps) + TApp::instance()->getCurrentXsheet()->getXsheet()->stopScrub(); + TApp::instance()->getCurrentXsheet()->getXsheet()->play(m_sound, s0, s1, + false); +} + +bool SceneViewerPanel::hasSoundtrack() { + if (m_sound != NULL) { + m_sound = NULL; + m_hasSoundtrack = false; + m_first = true; + } + TXsheetHandle *xsheetHandle = TApp::instance()->getCurrentXsheet(); + TXsheet::SoundProperties *prop = new TXsheet::SoundProperties(); + m_sound = xsheetHandle->getXsheet()->makeSound(prop); + if (m_sound == NULL) { + m_hasSoundtrack = false; + return false; + } else { + m_hasSoundtrack = true; + return true; + } +} + +void SceneViewerPanel::onButtonPressed(FlipConsole::EGadget button) { + if (button == FlipConsole::eSound) { + m_playSound = !m_playSound; + } +} diff --git a/toonz/sources/toonz/viewerpane.h b/toonz/sources/toonz/viewerpane.h index d308604..48e5c11 100644 --- a/toonz/sources/toonz/viewerpane.h +++ b/toonz/sources/toonz/viewerpane.h @@ -3,7 +3,7 @@ #ifndef VIEWER_PANE_INCLUDED #define VIEWER_PANE_INCLUDED -#include "pane.h" +#include "styleshortcutswitchablepanel.h" #include "sceneviewer.h" #include "toonzqt/intfield.h" #include "toonzqt/keyframenavigator.h" @@ -25,7 +25,8 @@ class Ruler; class FlipConsole; class TXshLevel; -class SceneViewerPanel final : public TPanel, public FlipConsoleOwner { +class SceneViewerPanel final : public StyleShortcutSwitchablePanel, + public FlipConsoleOwner { Q_OBJECT friend class SceneViewer; @@ -37,6 +38,14 @@ class SceneViewerPanel final : public TPanel, public FlipConsoleOwner { TPanelTitleBarButton *m_previewButton; TPanelTitleBarButton *m_subcameraPreviewButton; bool m_onionSkinActive = false; + bool m_playSound = true; + bool m_hasSoundtrack = false; + bool m_playing = false; + double m_fps; + int m_viewerFps; + double m_samplesPerFrame; + bool m_first = true; + TSoundTrack *m_sound = NULL; public: #if QT_VERSION >= 0x050500 @@ -58,6 +67,8 @@ protected: void createPlayToolBar(); void addColorMaskButton(QWidget *parent, const char *iconSVGName, int id); void enableFlipConsoleForCamerastand(bool on); + void playAudioFrame(int frame); + bool hasSoundtrack(); public slots: @@ -66,6 +77,7 @@ public slots: void onXshLevelSwitched(TXshLevel *); void updateFrameRange(); void updateFrameMarkers(); + void onButtonPressed(FlipConsole::EGadget button); protected slots: @@ -75,6 +87,7 @@ protected slots: void onPlayingStatusChanged(bool playing); void enableFullPreview(bool enabled); void enableSubCameraPreview(bool enabled); + void onPreferenceChanged(const QString &prefName) override; }; #endif diff --git a/toonz/sources/toonz/xsheetviewer.cpp b/toonz/sources/toonz/xsheetviewer.cpp index 6c243fd..6e45023 100644 --- a/toonz/sources/toonz/xsheetviewer.cpp +++ b/toonz/sources/toonz/xsheetviewer.cpp @@ -184,8 +184,8 @@ XsheetViewer::XsheetViewer(QWidget *parent, Qt::WFlags flags) m_cellScrollArea->setWidget(m_cellArea); m_cellScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); m_cellScrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); - m_cellScrollArea->horizontalScrollBar()->setObjectName("XsheetScrollBar"); - m_cellScrollArea->verticalScrollBar()->setObjectName("XsheetScrollBar"); + // m_cellScrollArea->horizontalScrollBar()->setObjectName("XsheetScrollBar"); + // m_cellScrollArea->verticalScrollBar()->setObjectName("XsheetScrollBar"); m_columnArea = new XsheetGUI::ColumnArea(this); m_columnScrollArea = new XsheetScrollArea(this); @@ -694,13 +694,13 @@ void XsheetViewer::paintEvent(QPaintEvent*) //----------------------------------------------------------------------------- void XsheetViewer::resizeEvent(QResizeEvent *event) { - int w = width(); - int h = height(); - + int w = width(); + int h = height(); + int scrollBarWidth = 16; m_noteScrollArea->setGeometry(3, 1, m_x0 - 4, m_y0 - 3); m_cellScrollArea->setGeometry(m_x0, m_y0, w - m_x0, h - m_y0); - m_columnScrollArea->setGeometry(m_x0, 1, w - m_x0 - 20, m_y0 - 3); - m_rowScrollArea->setGeometry(1, m_y0, m_x0 - 1, h - m_y0 - 20); + m_columnScrollArea->setGeometry(m_x0, 1, w - m_x0 - scrollBarWidth, m_y0 - 3); + m_rowScrollArea->setGeometry(1, m_y0, m_x0 - 1, h - m_y0 - scrollBarWidth); //(Nuovo Layout Manager) Reintrodotto per il refresh automatico refreshContentSize( diff --git a/toonz/sources/toonzlib/Naa2TlvConverter.cpp b/toonz/sources/toonzlib/Naa2TlvConverter.cpp index f740f7b..d0a5e6e 100644 --- a/toonz/sources/toonzlib/Naa2TlvConverter.cpp +++ b/toonz/sources/toonzlib/Naa2TlvConverter.cpp @@ -1005,7 +1005,8 @@ int Naa2TlvConverter::measureThickness(int x0, int y0) { //----------------------------------------------------------------------------- -TToonzImageP Naa2TlvConverter::makeTlv(bool transparentSyntheticInks) { +TToonzImageP Naa2TlvConverter::makeTlv(bool transparentSyntheticInks, + bool removeUnusedStyles) { if (!m_valid || m_colors.empty() || m_regions.empty() || !m_regionRas) return TToonzImageP(); int lx = m_regionRas->getLx(); @@ -1025,8 +1026,9 @@ TToonzImageP Naa2TlvConverter::makeTlv(bool transparentSyntheticInks) { if (cs->getMainColor() != color) cs = 0; } if (cs == 0) { - styleId = palette->getPage(0)->addStyle(color); - cs = palette->getStyle(styleId); + styleId = palette->addStyle(color); + palette->getPage(0)->addStyle(styleId); + cs = palette->getStyle(styleId); } styleIds.append(styleId); } @@ -1035,6 +1037,21 @@ TToonzImageP Naa2TlvConverter::makeTlv(bool transparentSyntheticInks) { // int synteticInkStyleId = palette->getPage(0)->addStyle(TPixel32(0,0,0,0)); // styleIds.append(synteticInkStyleId); + // Remove unused styles from input palette + if (removeUnusedStyles) { + for (int p = palette->getPageCount() - 1; p >= 0; p--) { + TPalette::Page *page = palette->getPage(p); + for (int s = page->getStyleCount() - 1; s >= 0; s--) { + int styleId = page->getStyleId(s); + if (styleId == -1) continue; + // check if the style is used or not + if (!styleIds.contains(styleId)) page->removeStyle(s); + } + // erase empty page + if (page->getStyleCount() == 0) palette->erasePage(p); + } + } + for (int y = 0; y < ly; y++) { unsigned short *workScanLine = m_regionRas->pixels(y); TPixelCM32 *outScanLine = ras->pixels(y); diff --git a/toonz/sources/toonzlib/convert2tlv.cpp b/toonz/sources/toonzlib/convert2tlv.cpp index 8e9c529..2fbed64 100644 --- a/toonz/sources/toonzlib/convert2tlv.cpp +++ b/toonz/sources/toonzlib/convert2tlv.cpp @@ -566,6 +566,18 @@ TPalette *Convert2Tlv::buildPalette() { page->addStyle(stylesToBeAddedToPage.at(s)); } + /* + If the palette path is empty, an initial palette with four colors are set in + the palette here. + ( see Convert2Tlv::init() ) So here I make the latter three styles in the + initial palette to set + "AutoPaint" options. + */ + if (m_palettePath.isEmpty()) { + assert(m_palette->getStyleCount() >= 5); + for (int id = 2; id <= 4; id++) m_palette->getStyle(id)->setFlags(1); + } + if (!m_appendDefaultPalette) return m_palette; /*-- Adding styles in the default palette to the result palette, starts here @@ -810,11 +822,17 @@ bool Convert2Tlv::init(std::string &errorMessage) { m_it = m_level1->begin(); - /*- 既定のパレットを作る。黒、赤、青、緑の順 -*/ - m_colorMap[TPixel::Black] = ++m_lastIndex; - m_colorMap[TPixel::Red] = ++m_lastIndex; - m_colorMap[TPixel::Blue] = ++m_lastIndex; - m_colorMap[TPixel::Green] = ++m_lastIndex; + /*- + If the palette is empty, make an initial palette with black, red, blue and + green styles. + For the latter three styles the "autopaint" option should be set. + -*/ + if (m_lastIndex == 0) { + m_colorMap[TPixel::Black] = ++m_lastIndex; + m_colorMap[TPixel::Red] = ++m_lastIndex; + m_colorMap[TPixel::Blue] = ++m_lastIndex; + m_colorMap[TPixel::Green] = ++m_lastIndex; + } return true; } diff --git a/toonz/sources/toonzlib/movierenderer.cpp b/toonz/sources/toonzlib/movierenderer.cpp index 924ce5b..e9f4ed4 100644 --- a/toonz/sources/toonzlib/movierenderer.cpp +++ b/toonz/sources/toonzlib/movierenderer.cpp @@ -209,7 +209,6 @@ void MovieRenderer::Imp::prepareForStart() { if (TSystem::doesExistFileOrLevel(fp)) { bool remove = false; - // In case the raster specifics are different from those of a currently // existing movie, erase it try { @@ -217,7 +216,8 @@ void MovieRenderer::Imp::prepareForStart() { lr->loadInfo(); const TImageInfo *info = lr->getImageInfo(); - if (!info || info->m_lx != imageSize.lx || info->m_ly != imageSize.ly) + if (!info || info->m_lx != imageSize.lx || + info->m_ly != imageSize.ly || fp.isFfmpegType()) TSystem::removeFileOrLevel(fp); // nothrow } catch (...) { // Same if the level could not be read/opened diff --git a/toonz/sources/toonzlib/outputproperties.cpp b/toonz/sources/toonzlib/outputproperties.cpp index 3951752..0ea61b2 100644 --- a/toonz/sources/toonzlib/outputproperties.cpp +++ b/toonz/sources/toonzlib/outputproperties.cpp @@ -97,7 +97,7 @@ TOutputProperties &TOutputProperties::operator=(const TOutputProperties &src) { std::map::const_iterator sft, sfEnd = src.m_formatProperties.end(); - for (sft = src.m_formatProperties.end(); sft != sfEnd; ++sft) + for (sft = src.m_formatProperties.begin(); sft != sfEnd; ++sft) m_formatProperties[sft->first] = sft->second->clone(); return *this; diff --git a/toonz/sources/toonzlib/palettecmd.cpp b/toonz/sources/toonzlib/palettecmd.cpp index 5e16930..c23f12e 100644 --- a/toonz/sources/toonzlib/palettecmd.cpp +++ b/toonz/sources/toonzlib/palettecmd.cpp @@ -33,6 +33,7 @@ #include "tstroke.h" #include "tregion.h" #include "tlevel_io.h" +#include "tpixelutils.h" #include "historytypes.h" @@ -45,6 +46,8 @@ #include #include +#include + //=================================================================== void findPaletteLevels(set &levels, int &rowIndex, @@ -1168,3 +1171,177 @@ void PaletteCmd::renamePaletteStyle(TPaletteHandle *paletteHandle, paletteHandle->notifyColorStyleChanged(false); TUndoManager::manager()->add(undo); } + +//============================================================================= +// organizePaletteStyle +// called in ColorModelViewer::pick() - move selected style to the first page +//----------------------------------------------------------------------------- +namespace { + +class setStylePickedPositionUndo final : public TUndo { + TPaletteHandle *m_paletteHandle; // Used in undo and redo to notify change + int m_styleId; + TPaletteP m_palette; + TPoint m_newPos; + TPoint m_oldPos; + +public: + setStylePickedPositionUndo(TPaletteHandle *paletteHandle, int styleId, + const TPoint &newPos) + : m_paletteHandle(paletteHandle), m_styleId(styleId), m_newPos(newPos) { + m_palette = paletteHandle->getPalette(); + assert(m_palette); + TColorStyle *style = m_palette->getStyle(m_styleId); + assert(style); + m_oldPos = style->getPickedPosition(); + } + void undo() const override { + TColorStyle *style = m_palette->getStyle(m_styleId); + assert(style); + style->setPickedPosition(m_oldPos); + m_paletteHandle->notifyColorStyleChanged(false); + } + void redo() const override { + TColorStyle *style = m_palette->getStyle(m_styleId); + assert(style); + style->setPickedPosition(m_newPos); + m_paletteHandle->notifyColorStyleChanged(false); + } + int getSize() const override { return sizeof *this; } + QString getHistoryString() override { + return QObject::tr("Set Picked Position of Style#%1 in Palette%2 : %3,%4") + .arg(QString::number(m_styleId)) + .arg(QString::fromStdWString(m_palette->getPaletteName())) + .arg(QString::number(m_newPos.x)) + .arg(QString::number(m_newPos.y)); + } + int getHistoryType() override { return HistoryType::Palette; } +}; +} + +void PaletteCmd::organizePaletteStyle(TPaletteHandle *paletteHandle, + int styleId, const TPoint &point) { + if (!paletteHandle) return; + TPalette *palette = paletteHandle->getPalette(); + if (!palette) return; + // if the style is already in the first page, then do nothing + TPalette::Page *page = palette->getStylePage(styleId); + if (!page || page->getIndex() == 0) return; + + int indexInPage = page->search(styleId); + + TUndoManager::manager()->beginBlock(); + + // call arrangeStyles() to move style to the first page + arrangeStyles(paletteHandle, 0, palette->getPage(0)->getStyleCount(), + page->getIndex(), {indexInPage}); + // then set the picked position + setStylePickedPositionUndo *undo = + new setStylePickedPositionUndo(paletteHandle, styleId, point); + undo->redo(); + TUndoManager::manager()->add(undo); + + TUndoManager::manager()->endBlock(); +} + +//============================================================================= +// called in ColorModelViewer::repickFromColorModel(). +// Pick color from the img for all styles with "picked position" value. +//----------------------------------------------------------------------------- +namespace { + +class pickColorByUsingPickedPositionUndo final : public TUndo { + TPaletteHandle *m_paletteHandle; // Used in undo and redo to notify change + TPaletteP m_palette; + QHash> m_styleList; + +public: + pickColorByUsingPickedPositionUndo( + TPaletteHandle *paletteHandle, + QHash> styleList) + : m_paletteHandle(paletteHandle), m_styleList(styleList) { + m_palette = paletteHandle->getPalette(); + assert(m_palette); + } + void undo() const override { + QHash>::const_iterator i = + m_styleList.constBegin(); + while (i != m_styleList.constEnd()) { + TColorStyle *style = m_palette->getStyle(i.key()); + assert(style); + style->setMainColor(i.value().first); + ++i; + } + m_paletteHandle->notifyColorStyleChanged(false); + } + void redo() const override { + QHash>::const_iterator i = + m_styleList.constBegin(); + while (i != m_styleList.constEnd()) { + TColorStyle *style = m_palette->getStyle(i.key()); + assert(style); + style->setMainColor(i.value().second); + ++i; + } + m_paletteHandle->notifyColorStyleChanged(false); + } + int getSize() const override { return sizeof *this; } + QString getHistoryString() override { + return QObject::tr("Update Colors by Using Picked Positions in Palette %1") + .arg(QString::fromStdWString(m_palette->getPaletteName())); + } + int getHistoryType() override { return HistoryType::Palette; } +}; + +TPixel32 pickColor(TRasterImageP ri, const TPoint &rasterPoint) { + TRasterP raster; + raster = ri->getRaster(); + + if (!TRect(raster->getSize()).contains(rasterPoint)) + return TPixel32::Transparent; + + TRaster32P raster32 = raster; + if (raster32) return raster32->pixels(rasterPoint.y)[rasterPoint.x]; + + TRasterGR8P rasterGR8 = raster; + if (rasterGR8) + return toPixel32(rasterGR8->pixels(rasterPoint.y)[rasterPoint.x]); + + return TPixel32::Transparent; +} +} + +void PaletteCmd::pickColorByUsingPickedPosition(TPaletteHandle *paletteHandle, + TImageP img) { + TRasterImageP ri = img; + if (!ri) return; + + TPalette *currentPalette = paletteHandle->getPalette(); + if (!currentPalette) return; + + TDimension imgSize = ri->getRaster()->getSize(); + QHash> styleList; + + // For all styles (starting from #1 as #0 is reserved for the transparent) + for (int sId = 1; sId < currentPalette->getStyleCount(); sId++) { + TColorStyle *style = currentPalette->getStyle(sId); + TPoint pp = style->getPickedPosition(); + // If style has a valid picked position + if (pp != TPoint() && pp.x >= 0 && pp.x < imgSize.lx && pp.y >= 0 && + pp.y < imgSize.ly && style->hasMainColor()) { + TPixel32 beforeColor = style->getMainColor(); + TPixel32 afterColor = pickColor(ri, pp); + style->setMainColor(afterColor); + //... store the style in the list for undo + styleList.insert(sId, QPair(beforeColor, afterColor)); + } + } + + // if some style has been changed, then register undo and notify changes + if (!styleList.isEmpty()) { + pickColorByUsingPickedPositionUndo *undo = + new pickColorByUsingPickedPositionUndo(paletteHandle, styleList); + TUndoManager::manager()->add(undo); + paletteHandle->notifyColorStyleChanged(false, true); // set dirty flag here + } +} \ No newline at end of file diff --git a/toonz/sources/toonzlib/preferences.cpp b/toonz/sources/toonzlib/preferences.cpp index e7da85d..3d63618 100644 --- a/toonz/sources/toonzlib/preferences.cpp +++ b/toonz/sources/toonzlib/preferences.cpp @@ -23,6 +23,7 @@ // Qt includes #include #include +#include // boost includes #include @@ -255,6 +256,9 @@ Preferences::Preferences() , m_fitToFlipbookEnabled(false) , m_previewAlwaysOpenNewFlipEnabled(false) , m_autosaveEnabled(false) + , m_autosaveSceneEnabled(true) + , m_autosaveOtherFilesEnabled(true) + , m_startupPopupEnabled(true) , m_defaultViewerEnabled(false) , m_saveUnpaintedInCleanup(true) , m_askForOverrideRender(true) @@ -290,7 +294,10 @@ Preferences::Preferences() , m_projectRoot(0x08) , m_customProjectRoot("") , m_precompute(true) - , m_ffmpegTimeout(30) { + , m_fastRenderPath("desktop") + , m_ffmpegTimeout(30) + , m_shortcutPreset("defopentoonz") + , m_useNumpadForSwitchingStyles(true) { TCamera camera; m_defLevelType = PLI_XSHLEVEL; m_defLevelWidth = camera.getSize().lx; @@ -324,6 +331,10 @@ Preferences::Preferences() getValue(*m_settings, "sceneNumberingEnabled", m_sceneNumberingEnabled); getValue(*m_settings, "animationSheetEnabled", m_animationSheetEnabled); getValue(*m_settings, "autosaveEnabled", m_autosaveEnabled); + getValue(*m_settings, "autosaveSceneEnabled", m_autosaveSceneEnabled); + getValue(*m_settings, "autosaveOtherFilesEnabled", + m_autosaveOtherFilesEnabled); + getValue(*m_settings, "startupPopupEnabled", m_startupPopupEnabled); getValue(*m_settings, "defaultViewerEnabled", m_defaultViewerEnabled); getValue(*m_settings, "rasterOptimizedMemory", m_rasterOptimizedMemory); getValue(*m_settings, "saveUnpaintedInCleanup", m_saveUnpaintedInCleanup); @@ -551,7 +562,15 @@ Preferences::Preferences() QString ffmpegPath = m_settings->value("ffmpegPath").toString(); if (ffmpegPath != "") m_ffmpegPath = ffmpegPath; setFfmpegPath(m_ffmpegPath.toStdString()); + QString fastRenderPath = m_settings->value("fastRenderPath").toString(); + if (fastRenderPath != "") m_fastRenderPath = fastRenderPath; + setFastRenderPath(m_fastRenderPath.toStdString()); getValue(*m_settings, "ffmpegTimeout", m_ffmpegTimeout); + QString shortcutPreset = m_settings->value("shortcutPreset").toString(); + if (shortcutPreset != "") m_shortcutPreset = shortcutPreset; + setShortcutPreset(m_shortcutPreset.toStdString()); + getValue(*m_settings, "useNumpadForSwitchingStyles", + m_useNumpadForSwitchingStyles); } //----------------------------------------------------------------- @@ -644,6 +663,27 @@ void Preferences::enableAutosave(bool on) { //----------------------------------------------------------------- +void Preferences::enableAutosaveScene(bool on) { + m_autosaveSceneEnabled = on; + m_settings->setValue("autosaveSceneEnabled", on ? "1" : "0"); +} + +//----------------------------------------------------------------- + +void Preferences::enableAutosaveOtherFiles(bool on) { + m_autosaveOtherFilesEnabled = on; + m_settings->setValue("autosaveOtherFilesEnabled", on ? "1" : "0"); +} + +//----------------------------------------------------------------- + +void Preferences::enableStartupPopup(bool on) { + m_startupPopupEnabled = on; + m_settings->setValue("startupPopupEnabled", on ? "1" : "0"); +} + +//----------------------------------------------------------------- + void Preferences::setAskForOverrideRender(bool on) { m_autosaveEnabled = on; m_settings->setValue("askForOverrideRender", on ? "1" : "0"); @@ -1223,6 +1263,21 @@ void Preferences::setFfmpegPath(std::string path) { //----------------------------------------------------------------- +void Preferences::setFastRenderPath(std::string path) { + m_fastRenderPath = QString::fromStdString(path); + std::string strPath = m_ffmpegPath.toStdString(); + m_settings->setValue("fastRenderPath", m_fastRenderPath); +} + +//----------------------------------------------------------------- + +void Preferences::setShortcutPreset(std::string preset) { + m_shortcutPreset = QString::fromStdString(preset); + m_settings->setValue("shortcutPreset", m_shortcutPreset); +} + +//----------------------------------------------------------------- + void Preferences::setPrecompute(bool enabled) { m_precompute = enabled; } //----------------------------------------------------------------- @@ -1281,3 +1336,10 @@ int Preferences::matchLevelFormat(const TFilePath &fp) const { return (lft != m_levelFormats.end()) ? lft - m_levelFormats.begin() : -1; } + +//----------------------------------------------------------------- + +void Preferences::enableUseNumpadForSwitchingStyles(bool on) { + m_useNumpadForSwitchingStyles = on; + m_settings->setValue("useNumpadForSwitchingStyles", on ? "1" : "0"); +} \ No newline at end of file diff --git a/toonz/sources/toonzlib/sceneproperties.cpp b/toonz/sources/toonzlib/sceneproperties.cpp index 154bfd5..76b6e25 100644 --- a/toonz/sources/toonzlib/sceneproperties.cpp +++ b/toonz/sources/toonzlib/sceneproperties.cpp @@ -80,8 +80,6 @@ void TSceneProperties::assign(const TSceneProperties *sprop) { for (int i = 0; i < (int)m_cameras.size(); i++) m_cameras[i] = new TCamera(*m_cameras[i]); } - *m_outputProp = *sprop->m_outputProp; - *m_previewProp = *sprop->m_previewProp; m_bgColor = sprop->m_bgColor; m_markerDistance = sprop->m_markerDistance; m_markerOffset = sprop->m_markerOffset; diff --git a/toonz/sources/toonzlib/stagevisitor.cpp b/toonz/sources/toonzlib/stagevisitor.cpp index f3746ab..dc256db 100644 --- a/toonz/sources/toonzlib/stagevisitor.cpp +++ b/toonz/sources/toonzlib/stagevisitor.cpp @@ -602,6 +602,9 @@ void RasterPainter::flushRasterImages() { glDisable(GL_DITHER); glDisable(GL_LOGIC_OP); +/* disable, since these features are never enabled, and cause OpenGL to assert + * on systems that don't support them: see #591 */ +#if 0 #ifdef GL_EXT_convolution glDisable(GL_CONVOLUTION_1D_EXT); glDisable(GL_CONVOLUTION_2D_EXT); @@ -612,6 +615,7 @@ void RasterPainter::flushRasterImages() { glDisable(GL_HISTOGRAM_EXT); glDisable(GL_MINMAX_EXT); #endif +#endif #ifdef GL_EXT_texture3D glDisable(GL_TEXTURE_3D_EXT); diff --git a/toonz/sources/toonzlib/studiopalettecmd.cpp b/toonz/sources/toonzlib/studiopalettecmd.cpp index 8cf07e9..c8023ec 100644 --- a/toonz/sources/toonzlib/studiopalettecmd.cpp +++ b/toonz/sources/toonzlib/studiopalettecmd.cpp @@ -501,7 +501,11 @@ void StudioPaletteCmd::loadIntoCurrentPalette(TPaletteHandle *paletteHandle, // keep the color model path unchanged TFilePath oldRefImagePath = current->getRefImgPath(); + std::wstring oldGlobalName = current->getGlobalName(); current->assign(palette, true); + // keep global name unchanged + current->setGlobalName(oldGlobalName); + current->setDirtyFlag(true); current->setRefImgPath(oldRefImagePath); diff --git a/toonz/sources/toonzlib/tproject.cpp b/toonz/sources/toonzlib/tproject.cpp index ec9ef5a..0a6b82e 100644 --- a/toonz/sources/toonzlib/tproject.cpp +++ b/toonz/sources/toonzlib/tproject.cpp @@ -298,13 +298,15 @@ void TProject::setFolder(string name) { setFolder(name, TFilePath(name)); } //------------------------------------------------------------------- /*! Returns the path of the folder named with \b name.\n Returns TFilePath() if there isn't a folder named with \b name. - \note The returned path could be a relative path. + \note The returned path could be a relative path if \b absolute is + false. */ -TFilePath TProject::getFolder(string name) const { +TFilePath TProject::getFolder(string name, bool absolute) const { std::map::const_iterator it; it = m_folders.find(name); if (it != m_folders.end()) - return it->second; + return (absolute) ? makeAbsolute(getProjectFolder(), it->second) + : it->second; else return TFilePath(); } diff --git a/toonz/sources/toonzqt/dvdialog.cpp b/toonz/sources/toonzqt/dvdialog.cpp index 281586e..59cfbd8 100644 --- a/toonz/sources/toonzqt/dvdialog.cpp +++ b/toonz/sources/toonzqt/dvdialog.cpp @@ -729,6 +729,23 @@ void Dialog::addButtonBarWidget(QWidget *first, QWidget *second, } } +//----------------------------------------------------------------------------- +/*! Add four widget to the button part of dialog. +*/ +void Dialog::addButtonBarWidget(QWidget *first, QWidget *second, QWidget *third, + QWidget *fourth) { + first->setMinimumSize(65, 25); + second->setMinimumSize(65, 25); + third->setMinimumSize(65, 25); + assert(m_hasButton); + if (m_hasButton) { + m_buttonLayout->addWidget(first); + m_buttonLayout->addWidget(second); + m_buttonLayout->addWidget(third); + m_buttonLayout->addWidget(fourth); + } +} + //============================================================================= RadioButtonDialog::RadioButtonDialog(const QString &labelText, @@ -1060,6 +1077,65 @@ int DVGui::MsgBox(const QString &text, const QString &button1Text, //----------------------------------------------------------------------------- +int DVGui::MsgBox(const QString &text, const QString &button1Text, + const QString &button2Text, const QString &button3Text, + const QString &button4Text, int defaultButtonIndex, + QWidget *parent) { + Dialog dialog(parent, true); + dialog.setWindowFlags(dialog.windowFlags() | Qt::WindowStaysOnTopHint); + dialog.setAlignment(Qt::AlignLeft); + QString msgBoxTitle = getMsgBoxTitle(QUESTION); + dialog.setWindowTitle(msgBoxTitle); + + QLabel *mainTextLabel = new QLabel(text, &dialog); + QPixmap iconPixmap = getMsgBoxPixmap(QUESTION); + if (!iconPixmap.isNull()) { + QLabel *iconLabel = new QLabel(&dialog); + iconLabel->setPixmap(iconPixmap); + + QHBoxLayout *mainLayout = new QHBoxLayout; + mainLayout->addWidget(iconLabel); + mainLayout->addSpacing(16); + mainLayout->addWidget(mainTextLabel); + dialog.addLayout(mainLayout); + } else + dialog.addWidget(mainTextLabel); + + // ButtonGroup: is used only to retrieve the clicked button + QButtonGroup *buttonGroup = new QButtonGroup(&dialog); + + QPushButton *button1 = new QPushButton(button1Text, &dialog); + button1->setDefault(false); + if (defaultButtonIndex == 0) button1->setDefault(true); + dialog.addButtonBarWidget(button1); + buttonGroup->addButton(button1, 1); + + QPushButton *button2 = new QPushButton(button2Text, &dialog); + button2->setDefault(false); + if (defaultButtonIndex == 1) button2->setDefault(true); + dialog.addButtonBarWidget(button2); + buttonGroup->addButton(button2, 2); + + QPushButton *button3 = new QPushButton(button3Text, &dialog); + button3->setDefault(false); + if (defaultButtonIndex == 2) button3->setDefault(true); + dialog.addButtonBarWidget(button3); + buttonGroup->addButton(button3, 3); + + QPushButton *button4 = new QPushButton(button4Text, &dialog); + button4->setDefault(false); + if (defaultButtonIndex == 3) button4->setDefault(true); + dialog.addButtonBarWidget(button4); + buttonGroup->addButton(button4, 4); + + QObject::connect(buttonGroup, SIGNAL(buttonPressed(int)), &dialog, + SLOT(done(int))); + dialog.raise(); + return dialog.exec(); +} + +//----------------------------------------------------------------------------- + int DVGui::MsgBox(const QString &text, const QString &button1, const QString &button2, int defaultButtonIndex, QWidget *parent) { diff --git a/toonz/sources/toonzqt/filefield.cpp b/toonz/sources/toonzqt/filefield.cpp index 3a32da2..1832f08 100644 --- a/toonz/sources/toonzqt/filefield.cpp +++ b/toonz/sources/toonzqt/filefield.cpp @@ -18,7 +18,8 @@ FileField::BrowserPopupController *FileField::m_browserPopupController = 0; // FileField //----------------------------------------------------------------------------- -FileField::FileField(QWidget *parent, QString path, bool readOnly) +FileField::FileField(QWidget *parent, QString path, bool readOnly, + bool doNotBrowseInitialPath) : QWidget(parent) , m_filters(QStringList()) , m_fileMode(QFileDialog::DirectoryOnly) @@ -33,6 +34,9 @@ FileField::FileField(QWidget *parent, QString path, bool readOnly) m_fileBrowseButton->setMinimumSize(20, WidgetHeight); m_fileBrowseButton->setObjectName("PushButton_NoPadding"); + // if the initial text is not path, set the string here and prevent browsing + if (doNotBrowseInitialPath) m_descriptionText = path; + QHBoxLayout *mainLayout = new QHBoxLayout(); mainLayout->setMargin(0); mainLayout->setSpacing(1); @@ -90,7 +94,7 @@ void FileField::browseDirectory() { if (!m_browserPopupController) return; m_browserPopupController->openPopup( m_filters, (m_fileMode == QFileDialog::DirectoryOnly), - m_lastSelectedPath); + (m_lastSelectedPath == m_descriptionText) ? "" : m_lastSelectedPath); if (m_browserPopupController->isExecute()) directory = m_browserPopupController->getPath(); diff --git a/toonz/sources/toonzqt/flipconsole.cpp b/toonz/sources/toonzqt/flipconsole.cpp index 706bb6e..1caa5ac 100644 --- a/toonz/sources/toonzqt/flipconsole.cpp +++ b/toonz/sources/toonzqt/flipconsole.cpp @@ -1234,16 +1234,19 @@ void FlipConsole::createPlayToolBar(bool withCustomWidget) { if (m_gadgetsMask & eRed || m_gadgetsMask & eGRed) m_colorFilterSep = m_playToolBar->addSeparator(); - // Sound & Histogram - if (m_gadgetsMask & eSound || m_gadgetsMask & eHisto) { + // Sound & Histogram & Locator + if (m_gadgetsMask & eSound || m_gadgetsMask & eHisto || + m_gadgetsMask & eLocator) { if (m_gadgetsMask & eSound) { createButton(eSound, "sound", tr("&Soundtrack "), true); m_soundSep = m_playToolBar->addSeparator(); } - if (m_gadgetsMask & eHisto) { + if (m_gadgetsMask & eHisto) createButton(eHisto, "histograms", tr("&Histogram"), false); + if (m_gadgetsMask & eLocator) + createButton(eLocator, "locator", tr("&Locator"), false); + if (m_gadgetsMask & eHisto || m_gadgetsMask & eLocator) m_histoSep = m_playToolBar->addSeparator(); - } } if (m_gadgetsMask & eFilledRaster) { @@ -1572,6 +1575,7 @@ void FlipConsole::doButtonPressed(UINT button) { case eHisto: case eSaveImg: case eSave: + case eLocator: // nothing to do return; diff --git a/toonz/sources/toonzqt/functiontreeviewer.cpp b/toonz/sources/toonzqt/functiontreeviewer.cpp index bcfcd2c..58be7a8 100644 --- a/toonz/sources/toonzqt/functiontreeviewer.cpp +++ b/toonz/sources/toonzqt/functiontreeviewer.cpp @@ -1184,11 +1184,14 @@ void FunctionTreeModel::onChange(const TParamChange &tpc) { struct Func final : public TFunctorInvoker::BaseFunctor { FunctionTreeModel *m_obj; - const TParamChange *m_tpc; + // Use a copy of 'TParamChange' since callers declare + // and free this value on the stack, + // so we can't ensure its valid later on when the notifier executes. + const TParamChange m_tpc; Func(FunctionTreeModel *obj, const TParamChange *tpc) - : m_obj(obj), m_tpc(tpc) {} - void operator()() override { m_obj->onParamChange(m_tpc->m_dragging); } + : m_obj(obj), m_tpc(*tpc) {} + void operator()() override { m_obj->onParamChange(m_tpc.m_dragging); } }; QMetaObject::invokeMethod(TFunctorInvoker::instance(), "invoke", diff --git a/toonz/sources/toonzqt/imageutils.cpp b/toonz/sources/toonzqt/imageutils.cpp index 24fcf11..06b67b6 100644 --- a/toonz/sources/toonzqt/imageutils.cpp +++ b/toonz/sources/toonzqt/imageutils.cpp @@ -632,7 +632,8 @@ void convert(const TFilePath &source, const TFilePath &dest, void convertNaa2Tlv(const TFilePath &source, const TFilePath &dest, const TFrameId &from, const TFrameId &to, - FrameTaskNotifier *frameNotifier, TPalette *palette) { + FrameTaskNotifier *frameNotifier, TPalette *palette, + bool removeUnusedStyles) { std::string dstExt = dest.getType(), srcExt = source.getType(); // Load source level structure @@ -671,8 +672,8 @@ void convertNaa2Tlv(const TFilePath &source, const TFilePath &dest, converter.process(raster); - if (TToonzImageP dstImg = - converter.makeTlv(false)) // Opaque synthetic inks + if (TToonzImageP dstImg = converter.makeTlv( + false, removeUnusedStyles)) // Opaque synthetic inks { if (converter.getPalette() == 0) converter.setPalette(dstImg->getPalette()); diff --git a/toonz/sources/toonzqt/menubarcommand.cpp b/toonz/sources/toonzqt/menubarcommand.cpp index 5e9612f..723cfda 100644 --- a/toonz/sources/toonzqt/menubarcommand.cpp +++ b/toonz/sources/toonzqt/menubarcommand.cpp @@ -279,7 +279,8 @@ int CommandManager::getKeyFromId(const char *id) { //--------------------------------------------------------- -void CommandManager::setShortcut(QAction *action, std::string shortcutString) { +void CommandManager::setShortcut(QAction *action, std::string shortcutString, + bool keepDefault) { QString shortcut = QString::fromStdString(shortcutString); std::string oldShortcutString = action->shortcut().toString().toStdString(); @@ -296,7 +297,7 @@ void CommandManager::setShortcut(QAction *action, std::string shortcutString) { if (node->m_type == ZoomCommandType && ks.count() > 1) { DVGui::warning( - QObject::tr("It is not possible to assing a shortcut with modifiers to " + QObject::tr("It is not possible to assign a shortcut with modifiers to " "the visualization commands.")); return; } @@ -328,7 +329,9 @@ void CommandManager::setShortcut(QAction *action, std::string shortcutString) { settings.beginGroup("shortcuts"); settings.setValue(QString::fromStdString(node->m_id), QString::fromStdString(shortcutString)); - if (oldActionId != "") settings.remove(oldActionId); + if (keepDefault) { + if (oldActionId != "") settings.remove(oldActionId); + } settings.endGroup(); } diff --git a/toonz/sources/toonzqt/paletteviewer.cpp b/toonz/sources/toonzqt/paletteviewer.cpp index faace8b..b7a59ea 100644 --- a/toonz/sources/toonzqt/paletteviewer.cpp +++ b/toonz/sources/toonzqt/paletteviewer.cpp @@ -911,10 +911,7 @@ void PaletteViewer::saveStudioPalette() { if (ret == 2 || ret == 0) return; sp->setPalette(fp, getPalette(), false); - question = "Do you want to update all linked styles in current scene ?"; - ret = DVGui::MsgBox(question, tr("Update"), tr("Don't Update"), 0); - if (ret == 1) - StudioPaletteCmd::updateAllLinkedStyles(m_paletteHandle, m_xsheetHandle); + StudioPaletteCmd::updateAllLinkedStyles(m_paletteHandle, m_xsheetHandle); palette->setDirtyFlag(false); } diff --git a/toonz/sources/toonzqt/paletteviewergui.cpp b/toonz/sources/toonzqt/paletteviewergui.cpp index b22622c..4cabe0d 100644 --- a/toonz/sources/toonzqt/paletteviewergui.cpp +++ b/toonz/sources/toonzqt/paletteviewergui.cpp @@ -454,6 +454,10 @@ void PageViewer::drawColorName(QPainter &p, QRect &nameRect, TColorStyle *style, name += " " + toQString(g.first) + ":" + QString::number(g.second); if (style->getFlags() != 0) name += "(autopaint)"; + TPoint pickedPos = style->getPickedPosition(); + if (pickedPos != TPoint()) + name += QString(" (%1,%2)").arg(pickedPos.x).arg(pickedPos.y); + p.drawText(nameRect.adjusted(6, 4, -6, -4), name); QColor borderCol(getTextColor()); @@ -587,6 +591,18 @@ void PageViewer::paintEvent(QPaintEvent *e) { QRect nameRect = getColorNameRect(i); drawColorName(p, nameRect, style, styleIndex); + // if numpad shortcut is activated, draw shortcut scope + if (Preferences::instance()->isUseNumpadForSwitchingStylesEnabled() && + m_viewType == LEVEL_PALETTE && + palette->getStyleShortcut(styleIndex) >= 0) { + p.setPen(QPen(QColor(0, 0, 0, 128), 2)); + p.drawLine(nameRect.topLeft() + QPoint(2, 1), + nameRect.bottomLeft() + QPoint(2, 0)); + p.setPen(QPen(QColor(255, 255, 255, 128), 2)); + p.drawLine(nameRect.topLeft() + QPoint(4, 1), + nameRect.bottomLeft() + QPoint(4, 0)); + } + // selezione if (m_styleSelection->isSelected(m_page->getIndex(), i)) { p.setPen(Qt::white); @@ -622,10 +638,37 @@ void PageViewer::paintEvent(QPaintEvent *e) { TColorStyle *style = m_page->getStyle(i); int styleIndex = m_page->getStyleId(i); + // if numpad shortcut is activated, draw shortcut scope + if (Preferences::instance()->isUseNumpadForSwitchingStylesEnabled() && + m_viewType == LEVEL_PALETTE && + palette->getStyleShortcut(styleIndex) >= 0) { + QRect itemRect = getItemRect(i); + // paint dark + p.setPen(Qt::NoPen); + p.setBrush(QColor(0, 0, 0, 64)); + p.drawRect(itemRect); + // check the neighbours and draw light lines + p.setPen(QPen(QColor(255, 255, 255, 128), 2)); + // top + if (!hasShortcut(i - m_chipPerRow)) + p.drawLine(itemRect.topLeft(), itemRect.topRight() - QPoint(1, 0)); + // left + if (i % m_chipPerRow == 0 || !hasShortcut(i - 1)) + p.drawLine(itemRect.topLeft() + QPoint(0, 1), itemRect.bottomLeft()); + // bottom + if (!hasShortcut(i + m_chipPerRow)) + p.drawLine(itemRect.bottomLeft() + QPoint(1, 0), + itemRect.bottomRight()); + // right + if ((i + 1) % m_chipPerRow == 0 || !hasShortcut(i + 1)) + p.drawLine(itemRect.topRight(), + itemRect.bottomRight() - QPoint(0, 1)); + } + // draw white frame if the style is selected or current if (m_styleSelection->isSelected(m_page->getIndex(), i) || currentStyleIndex == styleIndex) { - QRect itemRect = getItemRect(i).adjusted(-1, -2, 1, 2); + QRect itemRect = getItemRect(i).adjusted(0, -1, 0, 1); p.setPen(Qt::NoPen); p.setBrush(Qt::white); p.drawRoundRect(itemRect, 7, 25); @@ -772,10 +815,39 @@ void PageViewer::paintEvent(QPaintEvent *e) { p.drawText(indexRect, Qt::AlignCenter, QString().setNum(styleIndex)); // draw "Autopaint for lines" indicator + int offset = 0; if (style->getFlags() != 0) { QRect aflRect(chipRect.bottomLeft() + QPoint(0, -14), QSize(12, 15)); p.drawRect(aflRect); p.drawText(aflRect, Qt::AlignCenter, "A"); + offset += 12; + } + + // draw "Picked Position" indicator (not show on small chip mode) + if (style->getPickedPosition() != TPoint() && m_viewMode != SmallChips) { + QRect ppRect(chipRect.bottomLeft() + QPoint(offset, -14), + QSize(12, 15)); + p.drawRect(ppRect); + QPoint markPos = ppRect.center() + QPoint(1, 0); + p.drawEllipse(markPos, 3, 3); + p.drawLine(markPos - QPoint(5, 0), markPos + QPoint(5, 0)); + p.drawLine(markPos - QPoint(0, 5), markPos + QPoint(0, 5)); + } + + // if numpad shortcut is activated, draw shortcut number on top + if (Preferences::instance()->isUseNumpadForSwitchingStylesEnabled() && + m_viewType == LEVEL_PALETTE && + palette->getStyleShortcut(styleIndex) >= 0 && + m_viewMode != SmallChips) { + int key = palette->getStyleShortcut(styleIndex); + int shortcut = key - Qt::Key_0; + QRect ssRect(chipRect.center().x() - 8, chipRect.top() - 11, 16, 20); + p.setBrush(Qt::gray); + p.drawChord(ssRect, 0, -180 * 16); + tmpFont.setPointSize(6); + p.setFont(tmpFont); + p.drawText(ssRect.adjusted(0, 10, 0, 0), Qt::AlignCenter, + QString().setNum(shortcut)); } // revert font set @@ -1023,27 +1095,21 @@ void PageViewer::contextMenuEvent(QContextMenuEvent *event) { // remove links from studio palette if (m_viewType == LEVEL_PALETTE && m_styleSelection && - !m_styleSelection->isEmpty() && !isLocked) { + !m_styleSelection->isEmpty() && !isLocked && + m_styleSelection->hasLinkedStyle()) { menu.addSeparator(); - QAction *removeLinkAct = menu.addAction(tr("Remove Links")); - connect(removeLinkAct, SIGNAL(triggered()), this, SLOT(removeLink())); + QAction *toggleStyleLink = cmd->getAction("MI_ToggleLinkToStudioPalette"); + menu.addAction(toggleStyleLink); + QAction *removeStyleLink = + cmd->getAction("MI_RemoveReferenceToStudioPalette"); + menu.addAction(removeStyleLink); + QAction *getBackOriginalAct = + cmd->getAction("MI_GetColorFromStudioPalette"); + menu.addAction(getBackOriginalAct); } if (((indexPage == 0 && index > 0) || (indexPage > 0 && index >= 0)) && index < getChipCount() && !isLocked) { - // iwsw commented out temporarly - /* - wstring globalName = m_page->getStyle(index)->getGlobalName(); - if (m_viewType != STUDIO_PALETTE && - globalName != L"" && - (globalName[0] == L'-' || globalName[0] == L'+')) - { - createMenuAction(menu, "MI_ToggleLinkToStudioPalette", tr("Toggle - Link to Studio Palette"), "toggleLink()"); - createMenuAction(menu, "MI_RemoveReferenceToStudioPalette", - tr("Remove Reference to Studio Palette"), "eraseToggleLink()"); - } - */ if (pasteValueAct) pasteValueAct->setEnabled(true); if (pasteColorsAct) pasteColorsAct->setEnabled(true); @@ -1061,29 +1127,20 @@ void PageViewer::contextMenuEvent(QContextMenuEvent *event) { clearAct->setEnabled(false); } - // get color from the original studio palette - if (m_viewType == LEVEL_PALETTE && m_styleSelection && - !m_styleSelection->isEmpty() && !isLocked) { + if (m_page) { menu.addSeparator(); - QAction *getBackOriginalAct = - cmd->getAction("MI_GetColorFromStudioPalette"); - menu.addAction(getBackOriginalAct); + QAction *newStyle = menu.addAction(tr("New Style")); + connect(newStyle, SIGNAL(triggered()), SLOT(addNewColor())); + QAction *newPage = menu.addAction(tr("New Page")); + connect(newPage, SIGNAL(triggered()), SLOT(addNewPage())); } - // iwsw commented out temporarly /* - if (m_viewType != STUDIO_PALETTE) - { - menu.addSeparator(); + if (m_viewType != STUDIO_PALETTE) { menu.addAction(cmd->getAction(MI_EraseUnusedStyles)); } */ - if (m_page) { - QAction *newStyle = menu.addAction(tr("New Style")); - connect(newStyle, SIGNAL(triggered()), SLOT(addNewColor())); - QAction *newPage = menu.addAction(tr("New Page")); - connect(newPage, SIGNAL(triggered()), SLOT(addNewPage())); - } + menu.exec(event->globalPos()); } @@ -1371,22 +1428,12 @@ void PageViewer::onStyleRenamed() { } //----------------------------------------------------------------------------- -/*! Recall \b TStyleSelection::toggleLink() to current page style selection. -*/ -void PageViewer::toggleLink() { - if (!m_page || !m_styleSelection || m_styleSelection->isEmpty()) return; - m_styleSelection->toggleLink(); - update(); - emit changeWindowTitleSignal(); -} -//----------------------------------------------------------------------------- -/*! Recall \b TStyleSelection::eraseToggleLink() to current page style - * selection. -*/ -void PageViewer::eraseToggleLink() { - if (!m_page || !m_styleSelection || m_styleSelection->isEmpty()) return; - m_styleSelection->eraseToggleLink(); +bool PageViewer::hasShortcut(int indexInPage) { + if (!m_page) return false; + if (indexInPage < 0 || indexInPage >= m_page->getStyleCount()) return false; + int styleIndex = m_page->getStyleId(indexInPage); + return (m_page->getPalette()->getStyleShortcut(styleIndex) >= 0); } //============================================================================= @@ -1652,13 +1699,6 @@ void PageViewer::updateCommandLocks() { cmd->getAction("MI_BlendColors")->setEnabled(!isLocked); cmd->getAction("MI_PasteNames")->setEnabled(!isLocked); cmd->getAction("MI_GetColorFromStudioPalette")->setEnabled(!isLocked); -} - -//----------------------------------------------------------------------------- -/*! remove link and revert to the normal style -*/ -void PageViewer::removeLink() { - if (!m_page || !m_styleSelection || m_styleSelection->isEmpty()) return; - - if (m_styleSelection->removeLink()) emit changeWindowTitleSignal(); + cmd->getAction("MI_ToggleLinkToStudioPalette")->setEnabled(!isLocked); + cmd->getAction("MI_RemoveReferenceToStudioPalette")->setEnabled(!isLocked); } diff --git a/toonz/sources/toonzqt/spreadsheetviewer.cpp b/toonz/sources/toonzqt/spreadsheetviewer.cpp index 353a0b5..8c375e9 100644 --- a/toonz/sources/toonzqt/spreadsheetviewer.cpp +++ b/toonz/sources/toonzqt/spreadsheetviewer.cpp @@ -413,8 +413,8 @@ SpreadsheetViewer::SpreadsheetViewer(QWidget *parent) m_cellScrollArea->setObjectName("ScrollArea"); m_cellScrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); m_cellScrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); - m_cellScrollArea->horizontalScrollBar()->setObjectName("XsheetScrollBar"); - m_cellScrollArea->verticalScrollBar()->setObjectName("XsheetScrollBar"); + // m_cellScrollArea->horizontalScrollBar()->setObjectName("XsheetScrollBar"); + // m_cellScrollArea->verticalScrollBar()->setObjectName("XsheetScrollBar"); m_cellScrollArea->setFocusPolicy(Qt::NoFocus); m_columnScrollArea->setSizePolicy( @@ -435,14 +435,15 @@ SpreadsheetViewer::SpreadsheetViewer(QWidget *parent) layout->addWidget(m_rowScrollArea, 1, 0); layout->addWidget(m_cellScrollArea, 1, 1, 2, 2); + int scrollBarWidth = 16; // upper-right QWidget *w = new QWidget(this); - w->setFixedSize(QSize(20, m_rowHeight * 3 + 60 - 63)); + w->setFixedSize(QSize(scrollBarWidth, m_rowHeight * 3 + 60 - 63)); layout->addWidget(w, 0, 2); // lower-left w = new QWidget(this); - w->setFixedSize(QSize(30, 20)); + w->setFixedSize(QSize(30, scrollBarWidth)); layout->addWidget(w, 2, 0); layout->setColumnStretch(0, 0); diff --git a/toonz/sources/toonzqt/studiopaletteviewer.cpp b/toonz/sources/toonzqt/studiopaletteviewer.cpp index 052335e..1ba4e37 100644 --- a/toonz/sources/toonzqt/studiopaletteviewer.cpp +++ b/toonz/sources/toonzqt/studiopaletteviewer.cpp @@ -497,6 +497,7 @@ void StudioPaletteTreeViewer::onCurrentItemChanged(QTreeWidgetItem *current, m_currentPalette = StudioPalette::instance()->getPalette(newPath, false); m_studioPaletteHandle->setPalette(m_currentPalette.getPointer()); m_studioPaletteHandle->notifyPaletteSwitched(); + StudioPaletteCmd::updateAllLinkedStyles(m_levelPaletteHandle, m_xsheetHandle); } //----------------------------------------------------------------------------- @@ -1049,6 +1050,8 @@ void StudioPaletteTreeViewer::dropEvent(QDropEvent *event) { resetDropItem(); + if (newPath.isEmpty()) return; + const QMimeData *mimeData = event->mimeData(); const PaletteData *paletteData = dynamic_cast(mimeData); if (paletteData) { diff --git a/toonz/sources/toonzqt/styleeditor.cpp b/toonz/sources/toonzqt/styleeditor.cpp index 107db3e..361b879 100644 --- a/toonz/sources/toonzqt/styleeditor.cpp +++ b/toonz/sources/toonzqt/styleeditor.cpp @@ -3060,9 +3060,13 @@ void StyleEditor::onStyleSwitched() { QString::fromStdWString(L" Palette : " + palette->getPaletteName()); // style name - statusText += QString::fromStdWString(L" | Style#"); + statusText += QString::fromStdWString(L" | #"); statusText += QString::number(styleIndex); statusText += QString::fromStdWString(L" : " + m_editedStyle->getName()); + TPoint pickedPos = m_editedStyle->getPickedPosition(); + if (pickedPos != TPoint()) + statusText += + QString(" (Picked from %1,%2)").arg(pickedPos.x).arg(pickedPos.y); m_statusLabel->setText(statusText); } else diff --git a/toonz/sources/toonzqt/styleselection.cpp b/toonz/sources/toonzqt/styleselection.cpp index 024ace0..99f9bb9 100644 --- a/toonz/sources/toonzqt/styleselection.cpp +++ b/toonz/sources/toonzqt/styleselection.cpp @@ -505,9 +505,14 @@ void TStyleSelection::enableCommands() { enableCommand(this, MI_PasteNames, &TStyleSelection::pasteStylesName); // available only for level palette - if (m_paletteHandle->getPalette()->getGlobalName() == L"") + if (m_paletteHandle->getPalette()->getGlobalName() == L"") { enableCommand(this, MI_GetColorFromStudioPalette, &TStyleSelection::getBackOriginalStyle); + enableCommand(this, MI_ToggleLinkToStudioPalette, + &TStyleSelection::toggleLink); + enableCommand(this, MI_RemoveReferenceToStudioPalette, + &TStyleSelection::removeLink); + } } enableCommand(this, MI_Clear, &TStyleSelection::deleteStyles); enableCommand(this, MI_EraseUnusedStyles, &TStyleSelection::eraseUnsedStyle); @@ -1408,14 +1413,15 @@ public: void TStyleSelection::toggleLink() { TPalette *palette = getPalette(); if (!palette || m_pageIndex < 0) return; + if (isEmpty() || palette->isLocked()) return; int n = m_styleIndicesInPage.size(); if (n <= 0) return; std::vector> oldColorStylesLinked; std::vector> newColorStylesLinked; - bool somethingHasBeenLinked = false; - + bool somethingHasBeenLinked = false; + bool somethingChanged = false; bool currentStyleIsInSelection = false; TPalette::Page *page = palette->getPage(m_pageIndex); @@ -1435,6 +1441,7 @@ void TStyleSelection::toggleLink() { name[0] = name[0] == L'-' ? L'+' : L'-'; cs->setGlobalName(name); if (name[0] == L'+') somethingHasBeenLinked = true; + somethingChanged = true; } undo->setColorStyle(index, oldCs, name); @@ -1442,6 +1449,13 @@ void TStyleSelection::toggleLink() { palette->getPage(m_pageIndex)->search(m_paletteHandle->getStyleIndex())) currentStyleIsInSelection = true; } + + // if nothing changed, do not set dirty flag, nor register undo + if (!somethingChanged) { + delete undo; + return; + } + if (somethingHasBeenLinked) StudioPalette::instance()->updateLinkedColors(palette); @@ -1460,6 +1474,7 @@ void TStyleSelection::toggleLink() { void TStyleSelection::eraseToggleLink() { TPalette *palette = getPalette(); if (!palette || m_pageIndex < 0) return; + if (isEmpty() || palette->isLocked()) return; int n = m_styleIndicesInPage.size(); if (n <= 0) return; @@ -1575,7 +1590,7 @@ public: int getSize() const override { return sizeof(*this); } QString getHistoryString() override { - return QObject::tr("Remove Link in Palette : %1") + return QObject::tr("Remove Reference in Palette : %1") .arg(QString::fromStdWString(m_palette->getPaletteName())); } int getHistoryType() override { return HistoryType::Palette; } @@ -1585,11 +1600,11 @@ public: /*! remove link from studio palette. Delete the global and the orginal names. * return true if something changed */ -bool TStyleSelection::removeLink() { +void TStyleSelection::removeLink() { TPalette *palette = getPalette(); - if (!palette || m_pageIndex < 0) return false; + if (!palette || m_pageIndex < 0) return; int n = m_styleIndicesInPage.size(); - if (n <= 0) return false; + if (n <= 0) return; TPalette::Page *page = palette->getPage(m_pageIndex); assert(page); @@ -1614,12 +1629,10 @@ bool TStyleSelection::removeLink() { } if (somethingChanged) { - palette->setDirtyFlag(true); + m_paletteHandle->notifyColorStyleChanged(false); TUndoManager::manager()->add(undo); } else delete undo; - - return somethingChanged; } //============================================================================= @@ -1781,3 +1794,26 @@ void TStyleSelection::getBackOriginalStyle() { } else delete undo; } + +//----------------------------------------------------------------------------- +/*! return true if there is at least one linked style in the selection +*/ + +bool TStyleSelection::hasLinkedStyle() { + TPalette *palette = getPalette(); + if (!palette || m_pageIndex < 0 || isEmpty()) return false; + if (m_styleIndicesInPage.size() <= 0) return false; + + TPalette::Page *page = palette->getPage(m_pageIndex); + assert(page); + + // for each selected style + for (std::set::iterator it = m_styleIndicesInPage.begin(); + it != m_styleIndicesInPage.end(); ++it) { + TColorStyle *cs = page->getStyle(*it); + std::wstring gname = cs->getGlobalName(); + // if the style has link, return true + if (gname != L"" && (gname[0] == L'-' || gname[0] == L'+')) return true; + } + return false; +}