Fix style set management conflicts

This commit is contained in:
manongjohn 2021-10-07 12:07:57 -04:00
commit 49addb202a
39 changed files with 898 additions and 282 deletions

View file

@ -4,7 +4,7 @@ on: [push, pull_request]
jobs:
Windows:
runs-on: windows-2019
runs-on: windows-2016
steps:
- uses: actions/checkout@v2
with:

View file

@ -2,4 +2,6 @@
brew update
# Remove symlink to bin/2to3 in order for latest python to install
rm -f '/usr/local/bin/2to3'
# Remove synlink to nghttp2 in order fpr latest curl to install
brew unlink nghttp2
brew install boost qt@5 clang-format glew lz4 lzo libmypaint jpeg-turbo nasm yasm dav1d fontconfig freetype gnutls lame libass libbluray libsoxr libvorbis libvpx opencore-amr openh264 openjpeg opus rav1e sdl2 snappy speex tesseract theora webp xvid xz

View file

@ -10,16 +10,16 @@ IF NOT EXIST build mkdir build
cd build
REM Setup for local builds
set MSVCVERSION="Visual Studio 16 2019"
set MSVCVERSION="Visual Studio 15 2017"
set BOOST_ROOT=C:\boost\boost_1_74_0
set OPENCV_DIR=C:\opencv\451\build
set QT_PATH=C:\Qt\5.15.2\msvc2019_64
set QT_PATH=C:\Qt\5.9.7\msvc2017_64
REM These are effective when running from Actions
IF EXIST C:\local\boost_1_74_0 set BOOST_ROOT=C:\local\boost_1_74_0
IF EXIST C:\tools\opencv set OPENCV_DIR=C:\tools\opencv\build
IF EXIST D:\a\tahoma2d\tahoma2d\thirdparty\qt\5.15\msvc2019_64 (
set QT_PATH=D:\a\tahoma2d\tahoma2d\thirdparty\qt\5.15\msvc2019_64
IF EXIST D:\a\tahoma2d\tahoma2d\thirdparty\qt\5.9\msvc2017_64 (
set QT_PATH=D:\a\tahoma2d\tahoma2d\thirdparty\qt\5.9\msvc2017_64
)
set WITH_CANON=N

View file

@ -62,10 +62,10 @@ IF EXIST ..\..\thirdparty\apps\rhubarb (
echo ">>> Configuring Tahoma2D.exe for deployment"
REM Setup for local builds
set QT_PATH=C:\Qt\5.15.2\msvc2019_64
set QT_PATH=C:\Qt\5.9.7\msvc2017_64
REM These are effective when running from Actions/Appveyor
IF EXIST D:\a\tahoma2d\tahoma2d\thirdparty\qt\5.15\msvc2019_64 set QT_PATH=D:\a\tahoma2d\tahoma2d\thirdparty\qt\5.15\msvc2019_64
IF EXIST D:\a\tahoma2d\tahoma2d\thirdparty\qt\5.9\msvc2017_64 set QT_PATH=D:\a\tahoma2d\tahoma2d\thirdparty\qt\5.9\msvc2017_64
%QT_PATH%\bin\windeployqt.exe Tahoma2D\Tahoma2D.exe

View file

@ -1,9 +1,9 @@
choco install opencv --version=4.5.1
choco install boost-msvc-14.2
choco install boost-msvc-14.1
REM Install Qt 5.15
curl -fsSL -o Qt5.15.2_msvc2019_64.zip https://github.com/tahoma2d/qt5/releases/download/v5.15.2/Qt5.15.2_msvc2019_64.zip
7z x Qt5.15.2_msvc2019_64.zip
rename Qt5.15.2_msvc2019_64 5.15
REM Install Qt 5.9
curl -fsSL -o Qt5.9.7_msvc2017_64.zip https://github.com/tahoma2d/qt5/releases/download/v5.9.7/Qt5.9.7_msvc2017_64.zip
7z x Qt5.9.7_msvc2017_64.zip
rename Qt5.9.7_msvc2017_64 5.9
mkdir thirdparty\qt
move 5.15 thirdparty\qt
move 5.9 thirdparty\qt

View file

@ -22,7 +22,7 @@ Building Tahoma2D from source requires the following dependencies:
$ sudo apt-get install build-essential git cmake freeglut3-dev libboost-all-dev libegl1-mesa-dev libfreetype6-dev libgles2-mesa-dev libglew-dev libglib2.0-dev libjpeg-dev libjpeg-turbo8-dev libjson-c-dev liblz4-dev liblzma-dev liblzo2-dev libpng-dev libsuperlu-dev pkg-config qt5-default qtbase5-dev libqt5svg5-dev qtscript5-dev qttools5-dev qttools5-dev-tools libqt5opengl5-dev qtmultimedia5-dev qtwayland5 libqt5multimedia5-plugins
```
Find a PPA respository for Qt 5.9 or later and install the following:
Find a PPA repository for Qt 5.9 or later and install the following:
```
$ sudo apt-get install -y qt59multimedia qt59script qt59serialport qt59svg qt59tools
```

View file

@ -1,134 +1,197 @@
# Building on Windows
# Build Tahoma2D on Windows
This software can be built using Visual Studio 2015 or above and Qt 5.9 (later Qt versions still not working correctly.)
Throughout these instructions `$tahoma2d` represents the full path to your local Git repository for Tahoma2D.
## Required Software
### Visual Studio Express 2015 or higher for Windows Desktop
- https://www.visualstudio.com/vs/older-downloads/
- Make sure the target platform is "for Windows Desktop", not "for Windows".
- [ ] Install Visual Studio Express 2015 or higher for Windows Desktop, https://www.visualstudio.com/vs/older-downloads/
- Community and Professional versions of Visual Studio for Windows Desktop also work.
- During the installation, make sure to select all the Visual C++ packages.
- [ ] Make sure the target platform is "for Windows Desktop", not "for Windows".
- [ ] During the installation, make sure to select all the Visual C++ packages.
### Qt - cross-platform GUI framework.
- [ ] Install via **one** of the following methods.
- (option 1) Install Qt 5.9.9 from here: https://www.qt.io/download-open-source/. Click the `Download the Qt Online Installer` button at the bottom of the page. It should recommend the Windows installer, if not, select it. The installer is a small file and any additional needed files are downloaded during the install.
- [ ] Run the the downloaded file.
- [ ] On the filter tick the Archive checkbox to see older verions in the list. In the list choose version `Qt 5.9.9`.
- (option 2) Install using the [Qt 5.9.9 Offline Installer](http://download.qt.io/official_releases/qt/5.9/5.9.9/qt-opensource-windows-x86-5.9.9.exe). It is a large installer file which can be run offline.
From the site: *"We recommend you use the Qt Online Installer for first time installations and the Qt Maintenance Tool for changes to a current install."*
The Maintenance Tool for Qt is in the Qt installation folder, `C:\Qt\MaintenanceTool.exe`,
### CMake
- https://cmake.org/download/
- This will be used to create the `MSVC 2015` project file.
This will be used to create the `MSVC` project file.
- [ ] If CMake was installed with Qt, no additional installation is required.
### Qt
- https://www.qt.io/download-open-source/
- Qt is a cross-platform GUI framework.
- Install Qt 5.9 (64-bit version, tested up to 5.9.9) with the [Qt Online Installer for Windows](http://download.qt.io/official_releases/online_installers/qt-unified-windows-x86-online.exe).
The typical location of CMake installed with Qt is: `C:\Qt\Tools\CMake_64\bin\cmake-gui.exe`
- [ ] If CMake was not installed then get it here and install it: https://cmake.org/download/
### boost
- Boost 1.55.0 or later is required (tested up to 1.61.0).
- http://www.boost.org/users/history/version_1_61_0.html
- Download boost_1_73_0.zip from the above link. Extract all contents to the - '$tahoma2d/thirdparty/boost' directory.
- Install the following patch (Make the changes listed in the patch file), if you use Boost 1.55.0 with Visual Studio 2013.
- https://svn.boost.org/trac/boost/attachment/ticket/9369/vc12_fix_has_member_function_callable_with.patch
Boost 1.55.0 or later is required (tested up to 1.75.0).
- [ ] Download boost_1_75_0.zip from http://www.boost.org/users/history/version_1_75_0.html
- [ ] Extract all contents to the - '$tahoma2d\thirdparty\boost' directory. The result will be something like this: `$tahoma2d\thirdparty\boost\boost_1_75_0`
## Acquiring the Source Code
- Note: You can also perform these next commands with Github for Desktop client.
- Clone the base repository.
- Throughout the explanation `$tahoma2d` will represent the root for the base repository.
### OpenCV
- [ ] Install OpenCV. (https://opencv.org/) (v4.4.0 and later).
### lib and dll
OpenCV version 4.4.0 is the version distributed with Tahoma2D 1.1.
## Acquire the Source Code
You can use GitHub Desktop https://desktop.github.com/ or Git command line.
- [ ] Fork the base repository to your own GitHub account.
- [ ] Clone the base repository to your local environment.
- Visual Studio cannot properly recognize source code which is UTF-8 without BOM (Byte Order Mark). Furthermore, since the endline character is represented with only the LF character, one line comments in Japanese will often cause the following line to also be treated as a comment by `Microsoft Visual Studio`. In order to prevent this, please change the following setting in git so that it will preserve the proper endline characters:
- [ ] From a command line navigate to `$tahoma2d` and execute: `git config core.safecrlf true`
### Download the 'lib' and 'dll' files stored with Large File Storage (LFS)
- If you used the GitHub Desktop UI to clone to your local environment the lib and dll files will already be downloaded and you can skip this section.
- Perform these steps if you are using the Git command line to acquire the code.
- `lib` and `dll` files are tracked by [Git Large File Storage](https://git-lfs.github.com/).
- Note: git-lfs is also installed with Github Desktop.
- Visual Studio cannot recognize UTF-8 without BOM source code properly. Furthermore, since the endline character is represented with only the LF character, one line comments in Japanese will often cause the following line to be treated as a comment by `MSVS` as well.
- In order to prevent this, please change the following setting in git so that it will preserve the proper endline characters:
- `git config core.safecrlf true`
- Execute `git lfs pull` after `git clone` by using the lfs client.
- [ ] Ensure git-lfs is installed in your local Git environment. The command `git lfs` should return Git LFS information.
- Installation instructions for git-lfs: https://docs.github.com/en/github/managing-large-files/installing-git-large-file-storage
- From Git command line execute:
- [ ] `git clone`
- [ ] `git lfs pull`
### Using CMake to Create a Visual Studio Project
- Launch CMake
- In `Where is the source code`, navigate to `$tahoma2d/toonz/sources`
- In `Where to build the binaries`, navigate to `$tahoma2d/toonz/build`
- Or to wherever you usually build to.
- If the build directory is in the git repository, be sure to add the directory to .gitignore
### Use CMake to Create a Visual Studio Project
- [ ] Launch CMake GUI. You can find it in this Qt subfolder: `C:\Qt\Tools\CMake_64\bin\cmake-gui.exe`, or wherever you installed it.
- [ ] In `Where is the source code`, navigate to `$tahoma2d/toonz/sources`
- [ ] In `Where to build the binaries`, navigate to `$tahoma2d/toonz/build` or to wherever you usually build to.
- [ ] If the build directory is in the git repository, be sure to add the directory to .gitignore.
- If the build directory is different from the one above, be sure to change to the specified directory where appropriate below.
-Click on Configure and select the version of Visual Studio you are using.
-If Qt was installed to a directory other than the default, and the error Specify QT_PATH properly appears, navigate to the `QT_DIR` install folder and specify the path to `msvc2015_64`. Rerun Configure.
-If red lines appear in the bottom box, you can safely ignore them.
-Click Generate
-Should the CMakeLists.txt file change, such as during automatic build cleanup, there is no need to rerun CMake.
- [ ] Click on Configure, a pop-up should appear the first time this is done.
- If no pop-up appears then a cached version from a prior run of CMake was found at the locations you selected above.
- [ ] Clear the cache using: File -> Delete Cache.
- [ ] Click on Configure, the pop-up should now appear.
- In the pop-up that appears:
- [ ] Select the version of Visual Studio you are using.
- [ ] Select the x64 Target Environment.
- If Qt was installed to a directory other than the default, and the error `Specify QT_PATH properly` appears:
- Click on the value for `QT_PATH` in the top half of the CMake window.
- [ ] navigate to the `QT_DIR` install folder and down to the subfolder that most closely matches your version of Visual Studio, for example: `C:\Qt\5.9.9\msvc2017_64` for Visual Studio 2017.
- [ ] Rerun Configure.
- If OpenCV was installed to a directory other than the default and a message about `set "OpenCV_DIR"` appears:
- Click on the value for `OpenCV_DIR` in the top half of the CMake window.
- [ ] navigate to the OpenCV install folder and down to the level of the `build` folder. Example: `C:\opencv_4.4.0\build`.
- [ ] Rerun Configure.
- If red warning lines appear in the bottom box, you can safely ignore them.
- [ ] Click Generate.
- Should the CMakeLists.txt file change, such as during automatic build cleanup in Visual Studio, there is no need to rerun CMake.
## Setting Up Libraries
## Set Up Libraries
Rename the following files:
- `$tahoma2d/thirdparty/LibJPEG/jpeg-9/jconfig.vc` to `$tahoma2d/thirdparty/LibJPEG/jpeg-9/jconfig.h`
- `$tahoma2d/thirdparty/tiff-4.0.3/libtiff/tif_config.vc.h` to `$tahoma2d/thirdparty/tiff-4.0.3/libtiff/tif_config.h`
- `$tahoma2d/thirdparty/tiff-4.0.3/libtiff/tiffconf.vc.h to $tahoma2d/thirdparty/tiff-4.0.3/libtiff/tiffconf.h`
- `$tahoma2d/thirdparty/libpng-1.6.21/scripts/pnglibconf.h.prebuilt to $tahoma2d/thirdparty/libpng-1.6.21/pnglibconf.h`
- Note that the destination is a different folder for the last file.
- [ ] `$tahoma2d/thirdparty/LibJPEG/jpeg-9/jconfig.vc` to
- `$tahoma2d/thirdparty/LibJPEG/jpeg-9/jconfig.h`
- [ ] `$tahoma2d/thirdparty/tiff-4.0.3/libtiff/tif_config.vc.h` to
- `$tahoma2d/thirdparty/tiff-4.0.3/libtiff/tif_config.h`
- [ ] `$tahoma2d/thirdparty/tiff-4.0.3/libtiff/tiffconf.vc.h` to
- `$tahoma2d/thirdparty/tiff-4.0.3/libtiff/tiffconf.h`
- [ ] `$tahoma2d/thirdparty/libpng-1.6.21/scripts/pnglibconf.h.prebuilt` to
- `$tahoma2d/thirdparty/libpng-1.6.21/pnglibconf.h`
- Note that the destination folder is different for this file.
## Building
- Open `$tahoma2d/toonz/build/Tahoma2D.sln` and change to `Debug` or `Release` in the top bar.
- Compile the build.
- The output will be in the corresponding folder in `$tahoma2d/toonz/build/`
## Build
- [ ] Start Visual Studio and open the solution `$tahoma2d/toonz/build/Tahoma2D.sln`.
- [ ] Change to `Debug`, `RelWithDebInfo`, or `Release` in the top bar.
- [ ] Build the solution.
- [ ] Find the output in the folder `$tahoma2d/toonz/build/`
## Building with extended stop motion support for webcams and Canon DSLR cameras.
You will need three additional libraries.
- [OpenCV](https://opencv.org/) (v4.1.0 and later)
- [libjpeg-turbo](https://www.libjpeg-turbo.org/)
- The Canon SDK. This requires applying for the Canon developer program and downloading the SDK.
## Build with extended stop motion support for webcams and Canon DSLR cameras.
You will need two additional libraries.
- [ ] Get [libjpeg-turbo](https://www.libjpeg-turbo.org/)
- [ ] Get the Canon SDK. This requires applying for the Canon developer program and downloading the SDK.
Copy the following folders into the `$tahoma2d/thirdparty` folder.
- Copy the Header and library folders from the Canon SDK to `$tahoma2d/thirdparty/canon`
- [ ] Copy the Header and library folders from the Canon SDK to `$tahoma2d/thirdparty/canon`
- Make sure that the library is the one from the EDSDK_64 folder.
- Copy the lib and include folders from libjpeg-turbo64 into `$tahoma2d/thirdparty/libjpeg-turbo64`.
Check the checkbox in CMake to build with stop motion support.
On configuring with CMake or in the environmental variables, specify `OpenCV_DIR` to the `build` folder in the install folder of OpenCV (like `C:/opencv/build`).
- [ ] Copy the lib and include folders from libjpeg-turbo64 into `$tahoma2d/thirdparty/libjpeg-turbo64`.
- [ ] Check the checkbox in CMake to build with stop motion support.
To run the program with stop motion support, you will need to copy the .dll files from opencv2, libjpeg-turbo and the Canon SDK into the folder where your project is built.
## Running the Program
### Setting Up the Program's Path
1. Copy the entire contents of $tahoma2d/toonz/build/Release to an appropriate folder.
## Quick Setup and Run in Debug Mode - suitable for most people
- Use this method if you are interested in analyzing Tahoma2D rather than just creating a running copy.
- [ ] Start with a local working Tahoma2D installation. The latest release version is available here: https://tahoma2d.org/
- [ ] Copy all files and subfolders from the working Tahoma2D folder, except `tahomastuff` and `ffmpeg`.
- Paste to the build folder where the compiler generates output.
- `$tahoma2d/toonz/build/Debug` or `$tahoma2d/toonz/build/RelWithDebug` are typical build folders and the name is based on the `Solution Configuration` choice you make in Visual Studio during build.
- If the `Debug` or `RelWithDebug` subfolder does not already exist then create that folder manually or skip this step and come back to it after doing at least one build to create one of those folders. The Tahoma2d dlls and exe in the folder will be replaced when the next build is run.
- [ ] Copy the `tahomastuff` folder to `$tahoma2d/toonz/build/toonz` to get this result: `$tahoma2d/toonz/build/toonz/tahomastuff`.
- [ ] Start Visual Studio and load the solution.
- [ ] In Visual Studio set the `Solution Configuration` to `Debug` or `RelWithDebInfo` using the drop-down at the top of the screen.
- [ ] In the Solution Explorer window, right click on the `Tahoma2D` project.
- [ ] In the pop-up context menu that appears, choose `Set as StartUp Project`.
- This is a one time step. The `Tahoma2D` project will now show in bold indicating it is the startup project for the solution.
- [ ] Build the solution.
- [ ] Click the `Local Windows Debugger` to start Tahoma2D in debug mode.
- Set breakpoints, checkpoints, view the output window, do step-through debugging.
- To stop the debugging session exit Tahoma2D from its menu or stop the debugger in Visual Studio.
2. Open a Command Prompt and navigate to `QT_DIR/msvc2015_64/bin`. Run the Qt program `windeployqt.exe` with the path for `Tahoma2D.exe` as an argument. (Another way to do this is navigate to the exe that was created in your Release folder and drag and drop the Tahoma2D.exe on top of the windeployqt.exe This will automatically generate the QT files and folders you will need.)
- The necessary Qt library files should be in the same folder as `Tahoma2D.exe`
- These include:
- `Qt5Core.dll`
- `Qt5Gui.dll`
- `Qt5Network.dll`
- `Qt5OpenGL.dll`
- `Qt5PrintSupport.dll`
- `Qt5Script.dll`
- `Qt5Svg.dll`
- `Qt5Widgets.dll`
- `Qt5Multimedia.dll`
- These files should be in the corresponding folders in the same folder `Tahoma2D.exe`
- `/bearer/qgenericbearer.dll`
- `/bearer/qnativewifibearer.dll`
- `/iconengines/qsvgicon.dll`
- `/imageformats/qdds.dll`
- `/imageformats/qgif.dll`
- `/imageformats/qicns.dll`
- `/imageformats/qico.dll`
- `/imageformats/qjpeg.dll`
- `/imageformats/qsvg.dll`
- `/imageformats/qtga.dll`
- `/imageformats/qtiff.dll`
- `/imageformats/qwbmp.dll`
- `/imageformats/qwebp.dll`
- `/platforms/qwindows.dll`
## Run the Program - More Steps, Individual File Copying - more awareness over which files are used
1. - [ ] Copy the entire contents of $tahoma2d/toonz/build/Release to an appropriate folder.
2. - [ ] Do **one** of:
- (option 1) Open a Command Prompt and navigate to `QT_DIR/msvc2015_64/bin`. Run the Qt program `windeployqt.exe` with the path for `Tahoma2D.exe` as an argument.
3. Copy the following files to the same folder as `Tahoma2D.exe`
- `$tahoma2d/thirdparty/freeglut/bin/x64/freeglut.dll`
- `$tahoma2d/thirdparty/glew/glew-1.9.0/bin/64bit/glew32.dll`
- (option 2) Another way to do this is to open two windows in Windows Explorer. In the first window navigate to the folder containing `windeployqt.exe`. In a second window navigate to the Release folder contining the Tahoma2D.exe you built. Drag and drop Tahoma2D.exe onto `windeployqt.exe` in the other window.
- This will automatically generate the QT files and folders you will need.
### Creating the stuff Folder
1. Create a `tahomastuff` folder inside the folder where `Tahoma2D.exe` is located.
1. Copy the files from `$tahoma2d/stuff` to the new folder.
3. Confirm the result.
- These necessary Qt library files should be in the same folder as `Tahoma2D.exe`
- [ ] `Qt5Core.dll`
- [ ] `Qt5Gui.dll`
- [ ] `Qt5Multimedia.dll`
- [ ] `Qt5Network.dll`
- [ ] `Qt5OpenGL.dll`
- [ ] `Qt5PrintSupport.dll`
- [ ] `Qt5Script.dll`
- [ ] `Qt5SerialPort.dll`
- [ ] `Qt5Svg.dll`
- [ ] `Qt5Widgets.dll`
- [ ] `Qt5Xml.dll`
- and these files should be in corresponding sub-folders
- [ ] `/bearer/qgenericbearer.dll`
- [ ] `/iconengines/qsvgicon.dll`
- [ ] `/imageformats/qgif.dll`
- [ ] `/imageformats/qicns.dll`
- [ ] `/imageformats/qico.dll`
- [ ] `/imageformats/qjpeg.dll`
- [ ] `/imageformats/qsvg.dll`
- [ ] `/imageformats/qtga.dll`
- [ ] `/imageformats/qtiff.dll`
- [ ] `/imageformats/qwbmp.dll`
- [ ] `/imageformats/qwebp.dll`
- [ ] `/platforms/qwindows.dll`
### Running
4. Copy the following files to the same folder as `Tahoma2D.exe`
- [ ] `$tahoma2d/thirdparty/freeglut/bin/x64/freeglut.dll`
- [ ] `$tahoma2d/thirdparty/glew/glew-1.9.0/bin/64bit/glew32.dll`
- [ ] `$tahoma2d/thirdparty/libjpeg-turbo64/dist/turbojpeg.dll`
- [ ] `$tahoma2d/thirdparty/libmypaint/dist/64/libjson-c-2.dll`
- [ ] `$tahoma2d/thirdparty/libmypaint/dist/64/libmypaint-1-4-0.dll`
- [ ] `$OpenCV_DIR/build/x64/vc15/bin/opencv_world440.dll` Use the same OpenCV that was used to build the solution.
5. Copy the following files from a downloaded release copy of Tahoma2D to the same folder as `Tahoma2D.exe`. The latest release version is available here: https://tahoma2d.org/.
- [ ] `concrt140.dll`
- [ ] `EDSDK.dll`
- [ ] `EdsImage.dll`
- [ ] `ffmpeg.exe`
- [ ] `ffprobe.exe`
- [ ] `libiconv-2.dll`
- [ ] `libintl-8.dll`
- [ ] `msvcp140.dll`
- [ ] `vcruntime140.dll`
- [ ] `vcruntime140_1.dll`
### Create the stuff Folder
- [ ] Create an empty `tahomastuff` folder inside the folder where `Tahoma2D.exe` is located.
- [ ] Copy the files from `$tahoma2d/stuff` to the new folder.
### Run
`Tahoma2D.exe` can now be run. Congratulations!
## Debugging
1. In the Solution Explorer, select the Tahoma2D project within the Tahoma2D solution.
2. In the Project menu, choose Set as StartUp Project.
## Creating Translation Files
## Create Translation Files
Qt translation files are generated first from the source code to .ts files, then from .ts files to a .qm file. These files can be created in Visual Studio if the `translation_` project and `Build translation_??? only` (`translation_???`のみをビルド」) is used. These files are not created in the default `Build Project Solution`.

View file

@ -310,7 +310,7 @@ QMenu {
}
QMenu::item {
border: 0;
padding: 3 28 3 5;
padding: 3 28;
}
QMenu::item:selected {
background-color: #5385a6;

View file

@ -310,7 +310,7 @@ QMenu {
}
QMenu::item {
border: 0;
padding: 3 28 3 5;
padding: 3 28;
}
QMenu::item:selected {
background-color: #5385a6;

View file

@ -310,7 +310,7 @@ QMenu {
}
QMenu::item {
border: 0;
padding: 3 28 3 5;
padding: 3 28;
}
QMenu::item:selected {
background-color: #a0c1dd;

View file

@ -310,7 +310,7 @@ QMenu {
}
QMenu::item {
border: 0;
padding: 3 28 3 5;
padding: 3 28;
}
QMenu::item:selected {
background-color: #5385a6;

View file

@ -140,7 +140,7 @@ QMenu {
padding: 2 0;
&::item {
border: 0;
padding: 3 28 3 5;
padding: 3 28;
&:selected {
background-color: @menu-item-bg-color-selected;
color: @menu-item-text-color-selected;

View file

@ -310,7 +310,7 @@ QMenu {
}
QMenu::item {
border: 0;
padding: 3 28 3 5;
padding: 3 28;
}
QMenu::item:selected {
background-color: #8FA0B2;

View file

@ -0,0 +1,74 @@
## Notice about modified Qt
If you are using Windows version of OpenToonz installed from the installer
provided from OpenToonz website (https://opentoonz.github.io/), Qt libraries
distributed with the software may be our customized version.
The other OS versions (macOS, Linux) are not the case.
### To check whether the Qt libraries are customized.
- Launch OpenToonz.
- Open Preferences.
- Check if there is a checkbox "Use Qt's Native Windows Ink Support" in the
"Touch / Tablet Settings" category.
If the option exists, Qt libraries are customized version (Qt 5.15.2 with WinTab support).
----------
## About Qt 5.15.2 with WinTab support
This version is made based on v5.15.2 with cherry-picking the following commit
to the qtbase module, in order to make it enable to use WinTab API in Qt 5.15.2:
commit id: [4c4693cf964e9d7370c27a26e1d263a262aee568](https://github.com/shun-iwasawa/qtbase/commit/4c4693cf964e9d7370c27a26e1d263a262aee568)
commit title: Windows: Provide a way to switch between WinTab and Windows Ink at run-time
### Source Code
You can find the source code tree to build this package and track the modification here:
https://github.com/shun-iwasawa/qt5/tree/v5.15.2_wintab
### Build Configurations
The attached package is built by the following command lines:
```
> configure -debug-and-release -opensource -confirm-license -prefix ../build -make libs -no-pch -openssl OPENSSL_PREFIX="path\to\OpenSSL-Win64" -opengl dynamic
> jom -j4
> jom module-qtscript -j4
> jom install
```
### Dependent Libraries
The attached package is built by using the following libraries / softwares.
- OpenSSL Toolkit 1.1.1j
[Binary package from Shining Light Productions](https://slproweb.com/products/Win32OpenSSL.html)
- Perl
[ActivePerl 5.28](https://www.activestate.com/products/perl/downloads/)
- [Python 2.7.18](https://www.python.org/downloads/release/python-2718/)
- [Ruby 2.7.2-1 (x64)](https://rubyinstaller.org/downloads/)
- ANGLE : already included in the repository.
- Microsoft Visual Studio Community 2019
- [jom](https://wiki.qt.io/Jom)
- ICU : Not used.
#### Reference:
- [Qt for Windows - Requirements](https://doc.qt.io/qt-5/windows-requirements.html)
- [Qt for Windows - Building from Source](https://doc.qt.io/qt-5/windows-building.html)
----------
March 26, 2021
Shun Iwasawa, OpenToonz team

View file

View file

@ -104,6 +104,7 @@ option(WITH_SYSTEM_SUPERLU "Use the system SuperLU library instead of 'thirdpary
option(WITH_CANON "Build with Canon DSLR support - Requires Canon SDK" OFF)
option(WITH_TRANSLATION "Generate translation projects as well" ON)
option(WITH_CRASHRPT "Build CrashRpt support - Requires CrashRpt Library" OFF)
option(WITH_WINTAB "(Windows only) Build with customized Qt with WinTab support. https://github.com/shun-iwasawa/qt5/releases/tag/v5.15.2_wintab" OFF)
# avoid using again
option_defaults_clear()
@ -128,19 +129,7 @@ endif()
message(STATUS "Thirdpary Library Search path:" ${THIRDPARTY_LIBS_HINTS})
if(BUILD_ENV_MSVC)
if(MSVC_VERSION GREATER 1800)
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(QT_PATH "C:/Qt/5.9.2/msvc2015" CACHE PATH "Qt installation directory")
else()
set(QT_PATH "C:/Qt/5.9.2/msvc2015_64" CACHE PATH "Qt installation directory")
endif()
else()
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(QT_PATH "C:/Qt/5.9.2/msvc2013" CACHE PATH "Qt installation directory")
else()
set(QT_PATH "C:/Qt/5.9.2/msvc2013_64" CACHE PATH "Qt installation directory")
endif()
endif()
set(QT_PATH "C:/Qt/5.15.2/msvc2019${PLATFORM2}" CACHE PATH "Qt installation directory")
if(NOT EXISTS ${QT_PATH})
message("Specify QT_PATH properly")
return()

View file

@ -255,6 +255,10 @@ class ArrowToolOptionsBox final : public ToolOptionsBox {
ToolOptionCheckbox *m_globalKey;
// Flip buttons
QPushButton *m_hFlipButton, *m_vFlipButton, *m_leftRotateButton,
*m_rightRotateButton;
// enables adjusting value by dragging on the label
void connectLabelAndField(ClickableLabel *label, MeasuredValueField *field);
@ -283,6 +287,11 @@ protected slots:
void onCurrentStageObjectComboActivated(int index);
void onCurrentAxisChanged(int);
void onFlipHorizontal();
void onFlipVertical();
void onRotateLeft();
void onRotateRight();
};
//=============================================================================

View file

@ -483,6 +483,9 @@ public:
// Tablet tab
bool isWinInkEnabled() const { return getBoolValue(winInkEnabled); }
bool isQtNativeWinInkEnabled() const {
return getBoolValue(useQtNativeWinInk);
}
// Others (not appeared in the popup)
// Shortcut popup settings

View file

@ -183,6 +183,8 @@ enum PreferencesItemId {
// TounchGestureControl // Touch Gesture is a checkable command and not in
// preferences.ini
winInkEnabled,
// This option will be shown & available only when WITH_WINTAB is defined
useQtNativeWinInk,
//----------
// Others (not appeared in the popup)

View file

@ -41,6 +41,7 @@ DVAPI TFilePath getFirstProjectsFolder();
DVAPI TFilePath getStudioPaletteFolder();
DVAPI TFilePath getFxPresetFolder();
DVAPI TFilePath getLibraryFolder();
DVAPI TFilePath getPluginsFolder();
DVAPI TFilePath getReslistPath(bool forCleanup);
DVAPI TFilePath getCacheRootFolder();
DVAPI TFilePath getProfileFolder();

View file

@ -9,6 +9,8 @@ set(MOC_HEADERS
tooloptionscontrols.h
toonzrasterbrushtool.h
viewtools.h
selectiontool.h
edittool.h
../include/tools/imagegrouping.h
../include/tools/screenpicker.h
../include/tools/toolhandle.h
@ -24,7 +26,6 @@ set(HEADERS
rasterselectiontool.h
rgbpickertool.h
rulertool.h
selectiontool.h
setsaveboxtool.h
shifttracetool.h
stylepickertool.h

View file

@ -1,5 +1,5 @@
#include "edittool.h"
#include "tools/tool.h"
#include "tools/cursors.h"
#include "tproperty.h"
@ -633,134 +633,6 @@ bool hasVisibleChildColumn(const TStageObject *obj, const TXsheet *xsh) {
} // namespace
//-----------------------------------------------------------------------------
//=============================================================================
// EditTool
//-----------------------------------------------------------------------------
class EditTool final : public TTool {
Q_DECLARE_TR_FUNCTIONS(EditTool)
DragTool *m_dragTool;
bool m_firstTime;
enum {
None = -1,
Translation = 1,
Rotation,
Scale,
ScaleX,
ScaleY,
ScaleXY,
Center,
ZTranslation,
Shear,
};
// DragInfo m_dragInfo;
TPointD m_lastPos;
TPointD m_curPos;
TPointD m_firstPos;
TPointD m_curCenter;
bool m_active;
bool m_keyFrameAdded;
int m_what;
int m_highlightedDevice;
double m_oldValues[2];
double m_currentScaleFactor;
FxGadgetController *m_fxGadgetController;
bool m_isAltPressed;
TEnumProperty m_scaleConstraint;
TEnumProperty m_autoSelect;
TBoolProperty m_globalKeyframes;
TBoolProperty m_lockCenterX;
TBoolProperty m_lockCenterY;
TBoolProperty m_lockPositionX;
TBoolProperty m_lockPositionY;
TBoolProperty m_lockRotation;
TBoolProperty m_lockShearH;
TBoolProperty m_lockShearV;
TBoolProperty m_lockScaleH;
TBoolProperty m_lockScaleV;
TBoolProperty m_lockGlobalScale;
TBoolProperty m_showEWNSposition;
TBoolProperty m_showZposition;
TBoolProperty m_showSOposition;
TBoolProperty m_showRotation;
TBoolProperty m_showGlobalScale;
TBoolProperty m_showHVscale;
TBoolProperty m_showShear;
TBoolProperty m_showCenterPosition;
TEnumProperty m_activeAxis;
TPropertyGroup m_prop;
void drawMainHandle();
void onEditAllLeftButtonDown(TPointD &pos, const TMouseEvent &e);
public:
EditTool();
~EditTool();
ToolType getToolType() const override { return TTool::ColumnTool; }
bool doesApply() const; // ritorna vero se posso deformare l'oggetto corrente
void saveOldValues();
bool transformEnabled() const;
const TStroke *getSpline() const;
void rotate();
void move();
void moveCenter();
void scale();
void isoScale();
void squeeze();
void shear(const TPointD &pos, bool single);
void updateTranslation() override;
void leftButtonDown(const TPointD &pos, const TMouseEvent &) override;
void leftButtonDrag(const TPointD &pos, const TMouseEvent &) override;
void leftButtonUp(const TPointD &pos, const TMouseEvent &) override;
void mouseMove(const TPointD &, const TMouseEvent &e) override;
void draw() override;
void transform(const TAffine &aff);
void onActivate() override;
void onDeactivate() override;
bool onPropertyChanged(std::string propertyName) override;
void computeBBox();
int getCursorId() const override;
TPropertyGroup *getProperties(int targetType) override { return &m_prop; }
void updateMatrix() override {
setMatrix(
getCurrentObjectParentMatrix2()); // getCurrentObjectParentMatrix());
}
void drawText(const TPointD &p, double unit, std::string text);
QString updateEnabled(int rowIndex, int columnIndex) override;
};
//-----------------------------------------------------------------------------
EditTool::EditTool()
: TTool("T_Edit")
, m_active(false)

View file

@ -0,0 +1,147 @@
#pragma once
#ifndef EDITTOOL_INCLUDED
#define EDITTOOL_INCLUDED
#include "tool.h"
#include "tproperty.h"
#include "edittoolgadgets.h"
// For Qt translation support
#include <QCoreApplication>
using EditToolGadgets::DragTool;
//=============================================================================
// EditTool
//-----------------------------------------------------------------------------
class EditTool final : public QObject, public TTool {
Q_OBJECT
DragTool* m_dragTool;
bool m_firstTime;
enum {
None = -1,
Translation = 1,
Rotation,
Scale,
ScaleX,
ScaleY,
ScaleXY,
Center,
ZTranslation,
Shear,
};
// DragInfo m_dragInfo;
TPointD m_lastPos;
TPointD m_curPos;
TPointD m_firstPos;
TPointD m_curCenter;
bool m_active;
bool m_keyFrameAdded;
int m_what;
int m_highlightedDevice;
double m_oldValues[2];
double m_currentScaleFactor;
FxGadgetController* m_fxGadgetController;
bool m_isAltPressed;
TEnumProperty m_scaleConstraint;
TEnumProperty m_autoSelect;
TBoolProperty m_globalKeyframes;
TBoolProperty m_lockCenterX;
TBoolProperty m_lockCenterY;
TBoolProperty m_lockPositionX;
TBoolProperty m_lockPositionY;
TBoolProperty m_lockRotation;
TBoolProperty m_lockShearH;
TBoolProperty m_lockShearV;
TBoolProperty m_lockScaleH;
TBoolProperty m_lockScaleV;
TBoolProperty m_lockGlobalScale;
TBoolProperty m_showEWNSposition;
TBoolProperty m_showZposition;
TBoolProperty m_showSOposition;
TBoolProperty m_showRotation;
TBoolProperty m_showGlobalScale;
TBoolProperty m_showHVscale;
TBoolProperty m_showShear;
TBoolProperty m_showCenterPosition;
TEnumProperty m_activeAxis;
TPropertyGroup m_prop;
void drawMainHandle();
void onEditAllLeftButtonDown(TPointD& pos, const TMouseEvent& e);
public:
EditTool();
~EditTool();
ToolType getToolType() const override { return TTool::ColumnTool; }
bool doesApply() const; // ritorna vero se posso deformare l'oggetto corrente
void saveOldValues();
bool transformEnabled() const;
const TStroke* getSpline() const;
void rotate();
void move();
void moveCenter();
void scale();
void isoScale();
void squeeze();
void shear(const TPointD& pos, bool single);
void updateTranslation() override;
void leftButtonDown(const TPointD& pos, const TMouseEvent&) override;
void leftButtonDrag(const TPointD& pos, const TMouseEvent&) override;
void leftButtonUp(const TPointD& pos, const TMouseEvent&) override;
void mouseMove(const TPointD&, const TMouseEvent& e) override;
void draw() override;
void transform(const TAffine& aff);
void onActivate() override;
void onDeactivate() override;
bool onPropertyChanged(std::string propertyName) override;
void computeBBox();
int getCursorId() const override;
TPropertyGroup* getProperties(int targetType) override { return &m_prop; }
void updateMatrix() override {
setMatrix(
getCurrentObjectParentMatrix2()); // getCurrentObjectParentMatrix());
}
void drawText(const TPointD& p, double unit, std::string text);
QString updateEnabled(int rowIndex, int columnIndex) override;
signals:
void clickFlipHorizontal();
void clickFlipVertical();
void clickRotateLeft();
void clickRotateRight();
};
#endif // EDITTOOL_INCLUDED

View file

@ -322,8 +322,8 @@ DragSelectionTool::DragTool *createNewScaleTool(
// SelectionTool
//-----------------------------------------------------------------------------
class SelectionTool : public TTool, public TSelection::View {
Q_DECLARE_TR_FUNCTIONS(SelectionTool)
class SelectionTool : public QObject, public TTool, public TSelection::View {
Q_OBJECT
protected:
bool m_firstTime;
@ -467,6 +467,12 @@ public:
bool isEventAcceptable(QEvent *e) override;
virtual bool isSelectionEditable() { return true; }
signals:
void clickFlipHorizontal();
void clickFlipVertical();
void clickRotateLeft();
void clickRotateRight();
};
#endif // SELECTIONTOOL_INCLUDED

View file

@ -7,6 +7,7 @@
#include "tools/toolhandle.h"
#include "tools/toolcommandids.h"
#include "edittool.h"
#include "selectiontool.h"
#include "vectorselectiontool.h"
#include "rasterselectiontool.h"
@ -391,6 +392,8 @@ ArrowToolOptionsBox::ArrowToolOptionsBox(
setObjectName("toolOptionsPanel");
setFixedHeight(26);
EditTool *editTool = dynamic_cast<EditTool *>(tool);
m_axisOptionWidgets = new QWidget *[AllAxis];
/* --- General Parts --- */
@ -549,6 +552,32 @@ ArrowToolOptionsBox::ArrowToolOptionsBox(
m_zField->setPrecision(4);
m_noScaleZField->setPrecision(4);
m_hFlipButton = new QPushButton(this);
m_vFlipButton = new QPushButton(this);
m_leftRotateButton = new QPushButton(this);
m_rightRotateButton = new QPushButton(this);
m_hFlipButton->setFixedSize(QSize(20, 20));
m_vFlipButton->setFixedSize(QSize(20, 20));
m_leftRotateButton->setFixedSize(QSize(20, 20));
m_rightRotateButton->setFixedSize(QSize(20, 20));
m_hFlipButton->setIcon(createQIcon("fliphoriz"));
m_hFlipButton->setIconSize(QSize(20, 20));
m_vFlipButton->setIcon(createQIcon("flipvert"));
m_vFlipButton->setIconSize(QSize(20, 20));
m_leftRotateButton->setIcon(createQIcon("rotateleft"));
m_leftRotateButton->setIconSize(QSize(20, 20));
m_rightRotateButton->setIcon(createQIcon("rotateright"));
m_rightRotateButton->setIconSize(QSize(20, 20));
m_hFlipButton->setToolTip(tr("Flip Object Horizontally"));
m_vFlipButton->setToolTip(tr("Flip Object Vertically"));
m_leftRotateButton->setToolTip(tr("Rotate Object Left"));
m_rightRotateButton->setToolTip(tr("Rotate Object Right"));
bool splined = isCurrentObjectSplined();
if (splined != m_splined) m_splined = splined;
setSplined(m_splined);
@ -637,6 +666,8 @@ ArrowToolOptionsBox::ArrowToolOptionsBox(
rotLay->addWidget(m_rotationLabel, 0);
rotLay->addSpacing(LABEL_SPACING);
rotLay->addWidget(m_rotationField, 10);
rotLay->addWidget(m_leftRotateButton);
rotLay->addWidget(m_rightRotateButton);
rotLay->addSpacing(ITEM_SPACING);
rotLay->addWidget(new DVGui::Separator("", this, false));
@ -666,6 +697,7 @@ ArrowToolOptionsBox::ArrowToolOptionsBox(
scaleLay->addWidget(m_scaleHLabel, 0);
scaleLay->addSpacing(LABEL_SPACING);
scaleLay->addWidget(m_scaleHField, 10);
scaleLay->addWidget(m_hFlipButton);
scaleLay->addWidget(m_lockScaleHCheckbox, 0);
scaleLay->addSpacing(ITEM_SPACING);
@ -673,6 +705,7 @@ ArrowToolOptionsBox::ArrowToolOptionsBox(
scaleLay->addWidget(m_scaleVLabel, 0);
scaleLay->addSpacing(LABEL_SPACING);
scaleLay->addWidget(m_scaleVField, 10);
scaleLay->addWidget(m_vFlipButton);
scaleLay->addWidget(m_lockScaleVCheckbox, 0);
scaleLay->addSpacing(ITEM_SPACING);
@ -793,6 +826,16 @@ ArrowToolOptionsBox::ArrowToolOptionsBox(
connectLabelAndField(m_nsCenterLabel, m_nsCenterField);
onCurrentAxisChanged(activeAxisProp->getIndex());
connect(m_hFlipButton, SIGNAL(clicked()), SLOT(onFlipHorizontal()));
connect(m_vFlipButton, SIGNAL(clicked()), SLOT(onFlipVertical()));
connect(m_leftRotateButton, SIGNAL(clicked()), SLOT(onRotateLeft()));
connect(m_rightRotateButton, SIGNAL(clicked()), SLOT(onRotateRight()));
connect(editTool, SIGNAL(clickFlipHorizontal()), SLOT(onFlipHorizontal()));
connect(editTool, SIGNAL(clickFlipVertical()), SLOT(onFlipVertical()));
connect(editTool, SIGNAL(clickRotateLeft()), SLOT(onRotateLeft()));
connect(editTool, SIGNAL(clickRotateRight()), SLOT(onRotateRight()));
}
//-----------------------------------------------------------------------------
@ -1004,6 +1047,36 @@ void ArrowToolOptionsBox::onCurrentAxisChanged(int axisId) {
m_pickWidget->setVisible(axisId == AllAxis);
}
//-----------------------------------------------------------------------------
void ArrowToolOptionsBox::onFlipHorizontal() {
m_scaleHField->setValue(m_scaleHField->getValue() * -1);
emit m_scaleHField->measuredValueChanged(m_scaleHField->getMeasuredValue());
}
//-----------------------------------------------------------------------------
void ArrowToolOptionsBox::onFlipVertical() {
m_scaleVField->setValue(m_scaleVField->getValue() * -1);
emit m_scaleVField->measuredValueChanged(m_scaleVField->getMeasuredValue());
}
//-----------------------------------------------------------------------------
void ArrowToolOptionsBox::onRotateLeft() {
m_rotationField->setValue(m_rotationField->getValue() + 90);
emit m_rotationField->measuredValueChanged(
m_rotationField->getMeasuredValue());
}
//-----------------------------------------------------------------------------
void ArrowToolOptionsBox::onRotateRight() {
m_rotationField->setValue(m_rotationField->getValue() - 90);
emit m_rotationField->measuredValueChanged(
m_rotationField->getMeasuredValue());
}
//=============================================================================
//
// SelectionToolOptionsBox
@ -1230,6 +1303,13 @@ SelectionToolOptionsBox::SelectionToolOptionsBox(QWidget *parent, TTool *tool,
connect(m_vFlipButton, SIGNAL(clicked()), SLOT(onFlipVertical()));
connect(m_leftRotateButton, SIGNAL(clicked()), SLOT(onRotateLeft()));
connect(m_rightRotateButton, SIGNAL(clicked()), SLOT(onRotateRight()));
connect(selectionTool, SIGNAL(clickFlipHorizontal()),
SLOT(onFlipHorizontal()));
connect(selectionTool, SIGNAL(clickFlipVertical()), SLOT(onFlipVertical()));
connect(selectionTool, SIGNAL(clickRotateLeft()), SLOT(onRotateLeft()));
connect(selectionTool, SIGNAL(clickRotateRight()), SLOT(onRotateRight()));
// assert(ret);
updateStatus();
@ -1701,7 +1781,7 @@ FillToolOptionsBox::FillToolOptionsBox(QWidget *parent, TTool *tool,
m_multiFrameMode->isChecked())
m_onionMode->setEnabled(false);
if (m_autopaintMode) m_autopaintMode->setEnabled(false);
m_referenced->setEnabled(false);
if (m_referenced) m_referenced->setEnabled(false);
}
if (m_toolType->getProperty()->getValue() != L"Normal") {
if (m_segmentMode) m_segmentMode->setEnabled(false);
@ -1738,7 +1818,7 @@ void FillToolOptionsBox::onColorModeChanged(int index) {
}
enabled = range[index] != L"Lines" && !m_multiFrameMode->isChecked();
m_onionMode->setEnabled(enabled);
m_referenced->setEnabled(enabled);
if (m_referenced) m_referenced->setEnabled(enabled);
checkGapSettingsVisibility();
}
@ -1796,7 +1876,7 @@ void FillToolOptionsBox::checkGapSettingsVisibility() {
void FillToolOptionsBox::onToolTypeChanged(int index) {
const TEnumProperty::Range &range = m_toolType->getProperty()->getRange();
bool enabled = range[index] == L"Normal";
m_referenced->setEnabled(enabled);
if (m_referenced) m_referenced->setEnabled(enabled);
if (m_segmentMode)
m_segmentMode->setEnabled(
enabled ? m_colorMode->getProperty()->getValue() != L"Areas" : false);
@ -3027,3 +3107,75 @@ void ToolOptions::onStageObjectChange() {
ToolOptionsBox *panel = it->second;
panel->onStageObjectChange();
}
//***********************************************************************************
// Command instantiation
//***********************************************************************************
class FlipHorizontalCommandHandler final : public MenuItemHandler {
public:
FlipHorizontalCommandHandler(CommandId cmdId) : MenuItemHandler(cmdId) {}
void execute() override {
TTool::Application *app = TTool::getApplication();
TTool *tool = app->getCurrentTool()->getTool();
if (!tool) return;
if (tool->getName() == T_Edit) {
EditTool *editTool = dynamic_cast<EditTool *>(tool);
emit editTool->clickFlipHorizontal();
} else if (tool->getName() == T_Selection) {
SelectionTool *selectionTool = dynamic_cast<SelectionTool *>(tool);
emit selectionTool->clickFlipHorizontal();
}
}
} flipHorizontalCHInstance("A_ToolOption_FlipHorizontal");
class FlipVerticalCommandHandler final : public MenuItemHandler {
public:
FlipVerticalCommandHandler(CommandId cmdId) : MenuItemHandler(cmdId) {}
void execute() override {
TTool::Application *app = TTool::getApplication();
TTool *tool = app->getCurrentTool()->getTool();
if (!tool) return;
if (tool->getName() == T_Edit) {
EditTool *editTool = dynamic_cast<EditTool *>(tool);
emit editTool->clickFlipVertical();
} else if (tool->getName() == T_Selection) {
SelectionTool *selectionTool = dynamic_cast<SelectionTool *>(tool);
emit selectionTool->clickFlipVertical();
}
}
} flipVerticalCHInstance("A_ToolOption_FlipVertical");
class RotateLeftCommandHandler final : public MenuItemHandler {
public:
RotateLeftCommandHandler(CommandId cmdId) : MenuItemHandler(cmdId) {}
void execute() override {
TTool::Application *app = TTool::getApplication();
TTool *tool = app->getCurrentTool()->getTool();
if (!tool) return;
if (tool->getName() == T_Edit) {
EditTool *editTool = dynamic_cast<EditTool *>(tool);
emit editTool->clickRotateLeft();
} else if (tool->getName() == T_Selection) {
SelectionTool *selectionTool = dynamic_cast<SelectionTool *>(tool);
emit selectionTool->clickRotateLeft();
}
}
} rotateLeftCHInstance("A_ToolOption_RotateLeft");
class RotateRightCommandHandler final : public MenuItemHandler {
public:
RotateRightCommandHandler(CommandId cmdId) : MenuItemHandler(cmdId) {}
void execute() override {
TTool::Application *app = TTool::getApplication();
TTool *tool = app->getCurrentTool()->getTool();
if (!tool) return;
if (tool->getName() == T_Edit) {
EditTool *editTool = dynamic_cast<EditTool *>(tool);
emit editTool->clickRotateRight();
} else if (tool->getName() == T_Selection) {
SelectionTool *selectionTool = dynamic_cast<SelectionTool *>(tool);
emit selectionTool->clickRotateRight();
}
}
} rotateRightCHInstance("A_ToolOption_RotateRight");

View file

@ -432,6 +432,10 @@ if (WITH_CRASHRPT)
add_definitions(-DWITH_CRASHRPT)
endif()
if (WITH_WINTAB AND BUILD_TARGET_WIN AND (PLATFORM EQUAL 64))
add_definitions(-DWITH_WINTAB)
endif()
if(BUILD_ENV_APPLE)
include_directories(
../../sources/mousedragfilter

View file

@ -598,6 +598,7 @@ void FileBrowser::refreshCurrentFolderItems() {
if (it->getType() != "tnz" && it->getType() != "scr" &&
it->getType() != "tnzbat" && it->getType() != "mpath" &&
it->getType() != "curve" && it->getType() != "tpl" &&
it->getType() != "macrofx" && it->getType() != "plugin" &&
TFileType::getInfo(*it) == TFileType::UNKNOW_FILE)
continue;
} else if (!m_filter.contains(QString::fromStdString(it->getType())))

View file

@ -20,6 +20,7 @@
#include <QFileInfo>
#include <QDir>
#include <QDirIterator>
#include <QStandardPaths>
#ifdef _WIN32
#include <shlobj.h>
@ -77,6 +78,14 @@ TFilePath getDesktopPath() {
return TFilePath(dir.absolutePath().toStdString());
#endif
}
// Downloads Path
TFilePath getDownloadsPath() {
QStringList stdLocs =
QStandardPaths::standardLocations(QStandardPaths::DownloadLocation);
if (stdLocs.isEmpty()) return TFilePath();
return TFilePath(stdLocs[0]);
}
} // namespace
//=============================================================================
@ -1022,6 +1031,57 @@ QPixmap DvDirModelNetworkNode::getPixmap(bool isOpen) const {
return pixmap;
}
//=============================================================================
//
// DvDirModelStuffFolderNode [Tahoma2D]
//
//-----------------------------------------------------------------------------
DvDirModelStuffFolderNode::DvDirModelStuffFolderNode(DvDirModelNode *parent)
: DvDirModelNode(parent, L"Tahoma2D") {
m_nodeType = "StuffFolder";
}
//-----------------------------------------------------------------------------
void DvDirModelStuffFolderNode::refreshChildren() {
m_childrenValid = true;
if (!m_children.empty()) clearPointerContainer(m_children);
DvDirModelSpecialFileFolderNode *child = new DvDirModelSpecialFileFolderNode(
this, L"Library", ToonzFolder::getLibraryFolder());
child->setPixmap(
recolorPixmap(svgToPixmap(getIconThemePath("actions/16/library.svg"))));
addChild(child);
child = new DvDirModelSpecialFileFolderNode(
this, L"Fx Macros",
ToonzFolder::getFxPresetFolder() + TFilePath("presets/macroFx"));
child->setPixmap(
recolorPixmap(svgToPixmap(getIconThemePath("actions/16/fx_logo.svg"))));
addChild(child);
child = new DvDirModelSpecialFileFolderNode(this, L"Fx Plugins",
ToonzFolder::getPluginsFolder());
child->setPixmap(
recolorPixmap(svgToPixmap(getIconThemePath("actions/16/plugins.svg"))));
addChild(child);
child = new DvDirModelSpecialFileFolderNode(
this, L"Studio Palettes", ToonzFolder::getStudioPaletteFolder());
child->setPixmap(
recolorPixmap(svgToPixmap(getIconThemePath("actions/16/palette.svg"))));
addChild(child);
}
//-----------------------------------------------------------------------------
QPixmap DvDirModelStuffFolderNode::getPixmap(bool isOpen) const {
QIcon icon = createQIcon("tahoma2d");
static QPixmap pixmap = icon.pixmap(16);
return pixmap;
}
//=============================================================================
//
// DvDirModelRootNode [Root]
@ -1070,13 +1130,22 @@ void DvDirModelRootNode::refreshChildren() {
m_specialNodes.push_back(child);
addChild(child);
child = new DvDirModelSpecialFileFolderNode(
this, L"Library", ToonzFolder::getLibraryFolder());
child->setPixmap(
recolorPixmap(svgToPixmap(getIconThemePath("actions/16/library.svg"))));
child = new DvDirModelSpecialFileFolderNode(this, L"Downloads",
getDownloadsPath());
child->setPixmap(recolorPixmap(
svgToPixmap(getIconThemePath("actions/16/downloads.svg"))));
m_specialNodes.push_back(child);
addChild(child);
DvDirModelStuffFolderNode *childstuff = new DvDirModelStuffFolderNode(this);
for (int i = 0; i < childstuff->getChildCount(); i++) {
DvDirModelSpecialFileFolderNode *node =
dynamic_cast<DvDirModelSpecialFileFolderNode *>(
childstuff->getChild(i));
m_specialNodes.push_back(node);
}
addChild(childstuff);
child = new DvDirModelSpecialFileFolderNode(
this, L"Favorites", ToonzFolder::getMyFavoritesFolder());
child->setPixmap(recolorPixmap(

View file

@ -304,6 +304,16 @@ public:
//-----------------------------------------------------------------------------
class DvDirModelStuffFolderNode final : public DvDirModelNode {
public:
DvDirModelStuffFolderNode(DvDirModelNode *parent);
void refreshChildren() override;
QPixmap getPixmap(bool isOpen) const override;
bool isFolder() const override { return true; }
};
//-----------------------------------------------------------------------------
class DvDirModelRootNode final : public DvDirModelNode {
std::vector<DvDirModelFileFolderNode *> m_versionControlNodes;
std::vector<DvDirModelProjectNode *> m_projectNodes;

View file

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="16px"
height="16px"
version="1.1"
xml:space="preserve"
style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;"
id="svg10"
sodipodi:docname="downloads.svg"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"><metadata
id="metadata16"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs14" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1776"
inkscape:window-height="924"
id="namedview12"
showgrid="true"
inkscape:zoom="45.6875"
inkscape:cx="4.3009576"
inkscape:cy="8.1071639"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="svg10"><inkscape:grid
type="xygrid"
id="grid823" /></sodipodi:namedview>
<path
style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.25;stroke-miterlimit:2;stroke-dasharray:none;stroke-opacity:1"
d="M 5 1 L 5 9 L 1 9 L 8 15 L 15 9 L 11 9 L 11 1 L 5 1 z M 6 2 L 10 2 L 10 10 L 12.240234 10 L 8 13.496094 L 3.7382812 10 L 6 10 L 6 2 z "
id="rect815" /></svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

View file

@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="16px"
height="16px"
version="1.1"
xml:space="preserve"
style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;"
id="svg10"
sodipodi:docname="plugins.svg"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"><metadata
id="metadata16"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs14" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1776"
inkscape:window-height="924"
id="namedview12"
showgrid="true"
inkscape:zoom="32.305941"
inkscape:cx="5.6225993"
inkscape:cy="9.8678116"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="svg10"><inkscape:grid
type="xygrid"
id="grid823" /></sodipodi:namedview>
<path
style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.25;stroke-miterlimit:2;stroke-dasharray:none;stroke-opacity:1"
d="M 12.31029,11.228219 C 9.2989358,13.063976 8.0396828,12.660467 5.1650498,10.898304 4.8840244,10.726034 2.785243,12.893926 2.0230434,11.643623 1.3201538,10.490611 4.1657951,9.5349931 4.1347896,9.2149275 3.8106811,5.8691998 4.0865049,4.5298897 7.1051139,2.6897101 7.8940569,4.0402884 12.200257,10.985438 12.31029,11.228219 Z"
id="path830"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cscscc" /><path
style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.25;stroke-miterlimit:2;stroke-dasharray:none;stroke-opacity:1"
d="M 9,3.8768944 C 9.8538509,3.3563768 9.7645646,3.4108068 10.707702,2.8358592 11.650839,2.2609116 12.415404,1.794824 12.935921,2.6486749 13.456439,3.5025258 12.691874,3.9686134 11.748737,4.543561 10.8056,5.1185087 10.894886,5.0640786 10.041035,5.5845962"
id="path833"
inkscape:connector-curvature="0"
sodipodi:nodetypes="csssc" /><path
style="clip-rule:evenodd;opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.25;stroke-linejoin:round;stroke-miterlimit:2;stroke-dasharray:none;stroke-opacity:1"
d="M 11.08207,7.2922981 C 11.935921,6.7717805 11.846635,6.8262105 12.789772,6.2512629 13.73291,5.6763153 14.497474,5.2102277 15.017992,6.0640786 15.538509,6.9179296 14.773945,7.3840172 13.830808,7.9589648 12.88767,8.5339124 12.976957,8.4794824 12.123106,9"
id="path833-6"
inkscape:connector-curvature="0"
sodipodi:nodetypes="csssc" /></svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

View file

@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="16px"
height="16px"
version="1.1"
xml:space="preserve"
style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;"
id="svg10"
sodipodi:docname="tahoma2d.svg"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"><metadata
id="metadata16"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs14" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1776"
inkscape:window-height="924"
id="namedview12"
showgrid="true"
inkscape:zoom="45.6875"
inkscape:cx="8"
inkscape:cy="8.1071639"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="svg10"><inkscape:grid
type="xygrid"
id="grid823" /></sodipodi:namedview>
<path
style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.25;stroke-miterlimit:2;stroke-dasharray:none;stroke-opacity:1"
d="M 1,1 V 15 H 15 V 1 Z M 2,2 H 9 L 2,3 Z M 14,2 V 14 H 2 V 4 Z"
id="rect881"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccccccccc" /><path
style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.25;stroke-miterlimit:2;stroke-dasharray:none;stroke-opacity:1"
d="M 10.030687,5.6615521 14,5 V 7 L 11,7.5048656 V 14 h -1 z"
id="rect890"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccc" /><path
style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.25;stroke-miterlimit:2;stroke-dasharray:none;stroke-opacity:1"
d="M 2,7 7.0208156,6.1631974 7,14 H 5 V 8.5253077 L 2,9 Z"
id="rect892"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccc" /></svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View file

@ -374,8 +374,9 @@ int main(int argc, char *argv[]) {
#ifdef Q_OS_WIN
// Since currently Tahoma does not work with OpenGL of software or
// angle,
// force Qt to use desktop OpenGL
// angle, force Qt to use desktop OpenGL
// FIXME: This options should be called before constructing the application.
// Thus, ANGLE seems to be enabled as of now.
a.setAttribute(Qt::AA_UseDesktopOpenGL, true);
#endif
@ -734,6 +735,19 @@ int main(int argc, char *argv[]) {
QWindowsWindowFunctions::setHasBorderInFullScreen(w.windowHandle(), true);
#endif
// Qt have started to support Windows Ink from 5.12.
// Unlike WinTab API used in Qt 5.9 the tablet behaviors are different and
// are (at least, for OT) problematic. The customized Qt5.15.2 are made with
// cherry-picking the WinTab feature to be officially introduced from 6.0.
// See https://github.com/shun-iwasawa/qt5/releases/tag/v5.15.2_wintab for
// details. The following feature can only be used with the customized Qt,
// with WITH_WINTAB build option, and in Windows-x64 build.
#ifdef WITH_WINTAB
bool useQtNativeWinInk = Preferences::instance()->isQtNativeWinInkEnabled();
QWindowsWindowFunctions::setWinTabEnabled(!useQtNativeWinInk);
#endif
splash.showMessage(offsetStr + "Loading style sheet...",
Qt::AlignRight | Qt::AlignBottom, Qt::black);
a.processEvents();
@ -846,7 +860,9 @@ int main(int argc, char *argv[]) {
#endif
#endif
#ifdef _WIN32
// Windows Ink Support was introduce into Qt 5.12 so disable
// our version when compiling with it
#if defined(_WIN32) && QT_VERSION < QT_VERSION_CHECK(5, 12, 0)
if (Preferences::instance()->isWinInkEnabled()) {
KisTabletSupportWin8 *penFilter = new KisTabletSupportWin8();
if (penFilter->init()) {

View file

@ -2925,6 +2925,14 @@ void MainWindow::defineActions() {
createToolOptionsAction("A_ToolOption_AutoClose", QT_TR_NOOP("Auto Close"), "");
createToolOptionsAction("A_ToolOption_DrawUnder", QT_TR_NOOP("Draw Under"), "");
createToolOptionsAction("A_ToolOption_FlipHorizontal",
QT_TR_NOOP("Flip Selection/Object Horizontally"), "");
createToolOptionsAction("A_ToolOption_FlipVertical",
QT_TR_NOOP("Flip Selection/Object Vertically"), "");
createToolOptionsAction("A_ToolOption_RotateLeft",
QT_TR_NOOP("Rotate Selection/Object Left"), "");
createToolOptionsAction("A_ToolOption_RotateRight",
QT_TR_NOOP("Rotate Selection/Object Right"), "");
// Visualization
createViewerAction(V_ZoomIn, QT_TR_NOOP("Zoom In"), "+");

View file

@ -1165,7 +1165,11 @@ QString PreferencesPopup::getUIString(PreferencesItemId id) {
// Touch / Tablet Settings
// TounchGestureControl // Touch Gesture is a checkable command and not in
// preferences.ini
{winInkEnabled, tr("Enable Windows Ink Support* (EXPERIMENTAL)")}};
{winInkEnabled, tr("Enable Windows Ink Support* (EXPERIMENTAL)")},
{useQtNativeWinInk,
tr("Use Qt's Native Windows Ink Support*\n(CAUTION: This options is for "
"maintenance purpose. \n Do not activate this option or the tablet "
"won't work properly.)")}};
return uiStringTable.value(id, QString());
}
@ -1933,7 +1937,7 @@ QWidget* PreferencesPopup::createVersionControlPage() {
QWidget* PreferencesPopup::createTouchTabletPage() {
bool winInkAvailable = false;
#ifdef _WIN32
#if defined(_WIN32) && QT_VERSION < QT_VERSION_CHECK(5, 12, 0)
winInkAvailable = KisTabletSupportWin8::isAvailable();
#endif
@ -1949,6 +1953,9 @@ QWidget* PreferencesPopup::createTouchTabletPage() {
lay->addWidget(enableTouchGestures, 0, 0, 1, 2);
if (winInkAvailable) insertUI(winInkEnabled, lay);
#ifdef WITH_WINTAB
insertUI(useQtNativeWinInk, lay);
#endif
lay->setRowStretch(lay->rowCount(), 1);
if (winInkAvailable) insertFootNote(lay);

View file

@ -53,6 +53,10 @@
<file>icons/dark/actions/16/rotateleft.svg</file>
<file>icons/dark/actions/16/rotateright.svg</file>
<file>icons/dark/actions/16/tahoma2d.svg</file>
<file>icons/dark/actions/16/plugins.svg</file>
<file>icons/dark/actions/16/downloads.svg</file>
<!-- File / Common -->
<file>icons/dark/actions/16/menu.svg</file>
<file>icons/dark/actions/16/export.svg</file>

View file

@ -639,6 +639,8 @@ void Preferences::definePreferenceItems() {
// TounchGestureControl // Touch Gesture is a checkable command and not in
// preferences.ini
define(winInkEnabled, "winInkEnabled", QMetaType::Bool, false);
// This option will be shown & available only when WITH_WINTAB is defined
define(useQtNativeWinInk, "useQtNativeWinInk", QMetaType::Bool, false);
// Others (not appeared in the popup)
// Shortcut popup settings

View file

@ -107,6 +107,11 @@ TFilePath ToonzFolder::getFxPresetFolder() {
return fp;
}
TFilePath ToonzFolder::getPluginsFolder() {
TFilePath fp = getStuffDir() + TFilePath("plugins");
return fp;
}
TFilePath ToonzFolder::getCacheRootFolder() {
static enum STATE { FIRSTTIME, OK, NG } state = FIRSTTIME;
QString cacheDir =

View file

@ -641,7 +641,8 @@ bool isResource(const QString &path) {
return (TFileType::isViewable(type) || type & TFileType::MESH_IMAGE ||
type == TFileType::AUDIO_LEVEL || type == TFileType::TABSCENE ||
type == TFileType::TOONZSCENE || fp.getType() == "tpl");
type == TFileType::TOONZSCENE || fp.getType() == "tpl" ||
fp.getType() == "macrofx" || fp.getType() == "plugin");
}
//-----------------------------------------------------------------------------