mirror of
https://github.com/aseprite/aseprite.git
synced 2025-01-30 15:32:38 +00:00
Merge branch 'master' into tilemap-editor
This commit is contained in:
commit
7319309630
@ -1,4 +1,5 @@
|
|||||||
# Aseprite
|
# Aseprite
|
||||||
|
# Copyright (C) 2018-2020 Igara Studio S.A.
|
||||||
# Copyright (C) 2001-2018 David Capello
|
# Copyright (C) 2001-2018 David Capello
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 3.4)
|
cmake_minimum_required(VERSION 3.4)
|
||||||
@ -23,12 +24,8 @@ if(NOT CMAKE_BUILD_TYPE)
|
|||||||
FORCE)
|
FORCE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Restrict configuration types to the selected build type.
|
set(CMAKE_USER_MAKE_RULES_OVERRIDE ${CMAKE_CURRENT_SOURCE_DIR}/laf/cmake/c_flag_overrides.cmake)
|
||||||
# Note: This needs to be done before the project command
|
set(CMAKE_USER_MAKE_RULES_OVERRIDE_CXX ${CMAKE_CURRENT_SOURCE_DIR}/laf/cmake/cxx_flag_overrides.cmake)
|
||||||
set(CMAKE_CONFIGURATION_TYPES "${CMAKE_BUILD_TYPE}" CACHE INTERNAL "internal")
|
|
||||||
|
|
||||||
set(CMAKE_USER_MAKE_RULES_OVERRIDE ${CMAKE_CURRENT_SOURCE_DIR}/cmake/c_flag_overrides.cmake)
|
|
||||||
set(CMAKE_USER_MAKE_RULES_OVERRIDE_CXX ${CMAKE_CURRENT_SOURCE_DIR}/cmake/cxx_flag_overrides.cmake)
|
|
||||||
|
|
||||||
# Aseprite project
|
# Aseprite project
|
||||||
project(aseprite C CXX)
|
project(aseprite C CXX)
|
||||||
|
184
INSTALL.md
184
INSTALL.md
@ -12,19 +12,15 @@
|
|||||||
* [Issues with Retina displays](#issues-with-retina-displays)
|
* [Issues with Retina displays](#issues-with-retina-displays)
|
||||||
* [Linux details](#linux-details)
|
* [Linux details](#linux-details)
|
||||||
* [Using shared third party libraries](#using-shared-third-party-libraries)
|
* [Using shared third party libraries](#using-shared-third-party-libraries)
|
||||||
* [Building Skia dependency](#building-skia-dependency)
|
|
||||||
* [Skia on Windows](#skia-on-windows)
|
|
||||||
* [Skia on macOS](#skia-on-macos)
|
|
||||||
* [Skia on Linux](#skia-on-linux)
|
|
||||||
|
|
||||||
# Platforms
|
# Platforms
|
||||||
|
|
||||||
You should be able to compile Aseprite successfully on the following
|
You should be able to compile Aseprite successfully on the following
|
||||||
platforms:
|
platforms:
|
||||||
|
|
||||||
* Windows 10 + [Visual Studio Community 2019 + Windows 10.0.17763.0 SDK](https://imgur.com/4Pq2Cbv)
|
* Windows 10 + [Visual Studio Community 2019 + Windows 10.0.18362.0 SDK](https://imgur.com/a/7zs51IT)
|
||||||
* macOS 10.14.4 Mojave + Xcode 10.2.1 + macOS 10.14 SDK
|
* macOS 10.15.3 Mojave + Xcode 11.2.1 + macOS 10.15 SDK (older version might work)
|
||||||
* Linux + gcc 4.8 or clang 7.0
|
* Linux + gcc 9.2 or clang 9.0
|
||||||
|
|
||||||
# Get the source code
|
# Get the source code
|
||||||
|
|
||||||
@ -54,32 +50,24 @@ To compile Aseprite you will need:
|
|||||||
|
|
||||||
* The latest version of [CMake](https://cmake.org) (3.14 or greater)
|
* The latest version of [CMake](https://cmake.org) (3.14 or greater)
|
||||||
* [Ninja](https://ninja-build.org) build system
|
* [Ninja](https://ninja-build.org) build system
|
||||||
* You will need a compiled version of the Skia library.
|
* And a compiled version of the `aseprite-m81` branch of
|
||||||
Please check the details about [how to build Skia](#building-skia-dependency)
|
the [Skia library](https://github.com/aseprite/skia#readme).
|
||||||
on your platform.
|
There are [pre-built packages available](https://github.com/aseprite/skia/releases).
|
||||||
|
You can get some extra information in
|
||||||
|
the [*laf* dependencies](https://github.com/aseprite/laf#dependencies) page.
|
||||||
|
|
||||||
## Windows dependencies
|
## Windows dependencies
|
||||||
|
|
||||||
First of all, you will need:
|
|
||||||
|
|
||||||
* Windows 10 (**we don't support cross-compiling and don't know if this would be possible**)
|
* Windows 10 (**we don't support cross-compiling and don't know if this would be possible**)
|
||||||
* [Visual Studio Community 2019](https://visualstudio.microsoft.com/downloads/)
|
* [Visual Studio Community 2019](https://visualstudio.microsoft.com/downloads/)
|
||||||
* The [Desktop development with C++ item + Windows 10.0.17763.0 SDK](https://imgur.com/4Pq2Cbv)
|
* The [Desktop development with C++ item + Windows 10.0.18362.0 SDK](https://imgur.com/a/7zs51IT)
|
||||||
from the Visual Studio installer
|
from the Visual Studio installer
|
||||||
|
|
||||||
You will need to [compile Skia](#skia-on-windows) before and then
|
|
||||||
continue in the [Compiling](#compiling) section. Remember to check the
|
|
||||||
[Windows details](#windows-details) section to know how to call
|
|
||||||
`cmake` correctly.
|
|
||||||
|
|
||||||
## macOS dependencies
|
## macOS dependencies
|
||||||
|
|
||||||
On macOS you will need macOS 10.14 SDK and Xcode 10.2.1 (older
|
On macOS you will need macOS 10.15 SDK and Xcode 11.2.1 (older
|
||||||
versions might work).
|
versions might work).
|
||||||
|
|
||||||
You must also compile [Skia](#skia-on-macos) before starting with the
|
|
||||||
[compilation](#compiling).
|
|
||||||
|
|
||||||
## Linux dependencies
|
## Linux dependencies
|
||||||
|
|
||||||
You will need the following dependencies on Ubuntu/Debian:
|
You will need the following dependencies on Ubuntu/Debian:
|
||||||
@ -88,10 +76,7 @@ You will need the following dependencies on Ubuntu/Debian:
|
|||||||
|
|
||||||
On Fedora:
|
On Fedora:
|
||||||
|
|
||||||
sudo yum install -y gcc-c++ cmake ninja-build libX11-devel libXcursor-devel mesa-libGL-devel fontconfig-devel
|
sudo dnf install -y gcc-c++ cmake ninja-build libX11-devel libXcursor-devel mesa-libGL-devel fontconfig-devel
|
||||||
|
|
||||||
You must also compile [Skia](#skia-on-linux) before starting with the
|
|
||||||
[compilation](#compiling).
|
|
||||||
|
|
||||||
# Compiling
|
# Compiling
|
||||||
|
|
||||||
@ -109,7 +94,7 @@ You must also compile [Skia](#skia-on-linux) before starting with the
|
|||||||
2. Enter in the new directory and execute `cmake`:
|
2. Enter in the new directory and execute `cmake`:
|
||||||
|
|
||||||
cd C:\aseprite\build
|
cd C:\aseprite\build
|
||||||
cmake -G Ninja ..
|
cmake -G Ninja -DLAF_BACKEND=skia ..
|
||||||
|
|
||||||
Here `cmake` needs different options depending on your
|
Here `cmake` needs different options depending on your
|
||||||
platform. You must check the details for
|
platform. You must check the details for
|
||||||
@ -129,8 +114,7 @@ You must also compile [Skia](#skia-on-linux) before starting with the
|
|||||||
|
|
||||||
## Windows details
|
## Windows details
|
||||||
|
|
||||||
After you've [compiled Skia](#skia-on-windows),
|
Open a [developer command prompt](https://docs.microsoft.com/en-us/dotnet/framework/tools/developer-command-prompt-for-vs)
|
||||||
open a [developer command prompt](https://docs.microsoft.com/en-us/dotnet/framework/tools/developer-command-prompt-for-vs)
|
|
||||||
or in the command line (`cmd.exe`) call:
|
or in the command line (`cmd.exe`) call:
|
||||||
|
|
||||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Tools\VsDevCmd.bat" -arch=x64
|
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Tools\VsDevCmd.bat" -arch=x64
|
||||||
@ -140,16 +124,15 @@ And then
|
|||||||
cd aseprite
|
cd aseprite
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DLAF_OS_BACKEND=skia -DSKIA_DIR=C:\deps\skia -DSKIA_OUT_DIR=C:\deps\skia\out\Release -G Ninja ..
|
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DLAF_BACKEND=skia -DSKIA_DIR=C:\deps\skia -DSKIA_LIBRARY_DIR=C:\deps\skia\out\Release-x64 -G Ninja ..
|
||||||
ninja aseprite
|
ninja aseprite
|
||||||
|
|
||||||
In this case, `C:\deps\skia` is the directory where Skia was compiled
|
In this case, `C:\deps\skia` is the directory where Skia was compiled
|
||||||
as described in [Skia on Windows](#skia-on-windows) section.
|
or uncompressed.
|
||||||
|
|
||||||
## macOS details
|
## macOS details
|
||||||
|
|
||||||
After [compiling Skia](#skia-on-macos), you should run `cmake` with
|
Run `cmake` with the following parameters and then `ninja`:
|
||||||
the following parameters and then `ninja`:
|
|
||||||
|
|
||||||
cd aseprite
|
cd aseprite
|
||||||
mkdir build
|
mkdir build
|
||||||
@ -158,19 +141,18 @@ the following parameters and then `ninja`:
|
|||||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
||||||
-DCMAKE_OSX_ARCHITECTURES=x86_64 \
|
-DCMAKE_OSX_ARCHITECTURES=x86_64 \
|
||||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=10.9 \
|
-DCMAKE_OSX_DEPLOYMENT_TARGET=10.9 \
|
||||||
-DCMAKE_OSX_SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk \
|
-DCMAKE_OSX_SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk \
|
||||||
-DLAF_OS_BACKEND=skia \
|
-DLAF_BACKEND=skia \
|
||||||
-DSKIA_DIR=$HOME/deps/skia \
|
-DSKIA_DIR=$HOME/deps/skia \
|
||||||
-DSKIA_OUT_DIR=$HOME/deps/skia/out/Release \
|
-DSKIA_LIBRARY_DIR=$HOME/deps/skia/out/Release-x64 \
|
||||||
-G Ninja \
|
-G Ninja \
|
||||||
..
|
..
|
||||||
ninja aseprite
|
ninja aseprite
|
||||||
|
|
||||||
In this case, `$HOME/deps/skia` is the directory where Skia was
|
In this case, `$HOME/deps/skia` is the directory where Skia was
|
||||||
compiled as described in [Skia on macOS](#skia-on-macos) section.
|
compiled or downloaded. Make sure that `CMAKE_OSX_SYSROOT` is
|
||||||
Make sure that `CMAKE_OSX_SYSROOT` is pointing to the correct SDK
|
pointing to the correct SDK directory (in this case
|
||||||
directory (in this case
|
`/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk`),
|
||||||
`/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk`),
|
|
||||||
but it could be different in your Mac.
|
but it could be different in your Mac.
|
||||||
|
|
||||||
### Issues with Retina displays
|
### Issues with Retina displays
|
||||||
@ -181,23 +163,22 @@ If you have a Retina display, check the following issue:
|
|||||||
|
|
||||||
## Linux details
|
## Linux details
|
||||||
|
|
||||||
First you have to [compile Skia](#skia-on-linux), then you should run
|
Run `cmake` with the following parameters and then `ninja`:
|
||||||
`cmake` with the following parameters and then `ninja`:
|
|
||||||
|
|
||||||
cd aseprite
|
cd aseprite
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake \
|
cmake \
|
||||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
||||||
-DLAF_OS_BACKEND=skia \
|
-DLAF_BACKEND=skia \
|
||||||
-DSKIA_DIR=$HOME/deps/skia \
|
-DSKIA_DIR=$HOME/deps/skia \
|
||||||
-DSKIA_OUT_DIR=$HOME/deps/skia/out/Release \
|
-DSKIA_LIBRARY_DIR=$HOME/deps/skia/out/Release-x64 \
|
||||||
-G Ninja \
|
-G Ninja \
|
||||||
..
|
..
|
||||||
ninja aseprite
|
ninja aseprite
|
||||||
|
|
||||||
In this case, `$HOME/deps/skia` is the directory where Skia was
|
In this case, `$HOME/deps/skia` is the directory where Skia was
|
||||||
compiled as described in [Skia on Linux](#skia-on-linux) section.
|
compiled or uncompressed.
|
||||||
|
|
||||||
# Using shared third party libraries
|
# Using shared third party libraries
|
||||||
|
|
||||||
@ -208,116 +189,3 @@ configuring each `USE_SHARED_` option.
|
|||||||
After running `cmake -G`, you can edit `build/CMakeCache.txt` file,
|
After running `cmake -G`, you can edit `build/CMakeCache.txt` file,
|
||||||
and enable the `USE_SHARED_` flag (set its value to `ON`) of the
|
and enable the `USE_SHARED_` flag (set its value to `ON`) of the
|
||||||
library that you want to be linked dynamically.
|
library that you want to be linked dynamically.
|
||||||
|
|
||||||
# Building Skia dependency
|
|
||||||
|
|
||||||
When you compile Aseprite with [Skia](https://skia.org) as back-end on
|
|
||||||
Windows or macOS, you need to compile a specific version of Skia. In
|
|
||||||
the following sections you will find straightforward steps to compile
|
|
||||||
Skia.
|
|
||||||
|
|
||||||
You can always check the
|
|
||||||
[official Skia instructions](https://skia.org/user/build) and select
|
|
||||||
the OS you are building for. Aseprite uses the `aseprite-m71` Skia
|
|
||||||
branch from `https://github.com/aseprite/skia`.
|
|
||||||
|
|
||||||
## Skia on Windows
|
|
||||||
|
|
||||||
Download
|
|
||||||
[Google depot tools](https://storage.googleapis.com/chrome-infra/depot_tools.zip)
|
|
||||||
and uncompress it in some place like `C:\deps\depot_tools`.
|
|
||||||
|
|
||||||
[It's recommended to compile Skia with Clang](https://github.com/google/skia/blob/master/site/user/build.md#a-note-on-software-backend-performance)
|
|
||||||
to get better performance. So you will need to [download Clang](http://releases.llvm.org/8.0.0/LLVM-8.0.0-win64.exe),
|
|
||||||
and install it on a folder like `C:\deps\llvm` (a folder without whitespaces).
|
|
||||||
|
|
||||||
Open a [developer command prompt](https://docs.microsoft.com/en-us/dotnet/framework/tools/developer-command-prompt-for-vs)
|
|
||||||
or command line (`cmd.exe`) and call:
|
|
||||||
|
|
||||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Tools\VsDevCmd.bat" -arch=x64
|
|
||||||
|
|
||||||
Then:
|
|
||||||
|
|
||||||
set PATH=C:\deps\depot_tools;%PATH%
|
|
||||||
cd C:\deps\depot_tools
|
|
||||||
gclient sync
|
|
||||||
|
|
||||||
(The `gclient` command might print an error like
|
|
||||||
`Error: client not configured; see 'gclient config'`.
|
|
||||||
Just ignore it.)
|
|
||||||
|
|
||||||
cd C:\deps
|
|
||||||
git clone -b aseprite-m71 https://github.com/aseprite/skia.git
|
|
||||||
cd skia
|
|
||||||
set GIT_EXECUTABLE=git.bat
|
|
||||||
python tools/git-sync-deps
|
|
||||||
|
|
||||||
(The `tools/git-sync-deps` will take some minutes because it downloads
|
|
||||||
a lot of packages, please wait and re-run the same command in case it
|
|
||||||
fails.)
|
|
||||||
|
|
||||||
Finally, if you've downloaded Clang, use this command:
|
|
||||||
|
|
||||||
set PATH=C:\deps\llvm\bin;%PATH%
|
|
||||||
gn gen out/Release --args="is_official_build=true skia_use_system_expat=false skia_use_system_libjpeg_turbo=false skia_use_system_libpng=false skia_use_system_libwebp=false skia_use_system_zlib=false target_cpu=""x64"" cc=""clang"" cxx=""clang++"" clang_win=""c:\deps\llvm"" win_vc=""C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC"""
|
|
||||||
ninja -C out/Release skia
|
|
||||||
|
|
||||||
If you haven't installed Clang, and want to compile Skia with MSVC
|
|
||||||
(anyway it's not recommended because the performance penalty is too
|
|
||||||
big), you can use the following commands instead:
|
|
||||||
|
|
||||||
gn gen out/Release --args="is_official_build=true skia_use_system_expat=false skia_use_system_libjpeg_turbo=false skia_use_system_libpng=false skia_use_system_libwebp=false skia_use_system_zlib=false target_cpu=""x64"" win_vc=""C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC"""
|
|
||||||
ninja -C out/Release skia
|
|
||||||
|
|
||||||
More information about these steps in the
|
|
||||||
[official Skia documentation](https://skia.org/user/build).
|
|
||||||
|
|
||||||
## Skia on macOS
|
|
||||||
|
|
||||||
These steps will create a `deps` folder in your home directory with a
|
|
||||||
couple of subdirectories needed to build Skia (you can change the
|
|
||||||
`$HOME/deps` with other directory). Some of these commands will take
|
|
||||||
several minutes to finish:
|
|
||||||
|
|
||||||
mkdir $HOME/deps
|
|
||||||
cd $HOME/deps
|
|
||||||
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
|
|
||||||
git clone -b aseprite-m71 https://github.com/aseprite/skia.git
|
|
||||||
export PATH="${PWD}/depot_tools:${PATH}"
|
|
||||||
cd skia
|
|
||||||
python tools/git-sync-deps
|
|
||||||
gn gen out/Release --args="is_official_build=true skia_use_system_expat=false skia_use_system_icu=false skia_use_libjpeg_turbo=false skia_use_system_libpng=false skia_use_system_libwebp=false skia_use_system_zlib=false extra_cflags_cc=[\"-frtti\"]"
|
|
||||||
ninja -C out/Release skia
|
|
||||||
|
|
||||||
After this you should have all Skia libraries compiled. When you
|
|
||||||
[compile Aseprite](#compiling), remember to add
|
|
||||||
`-DSKIA_DIR=$HOME/deps/skia` parameter to your `cmake` call as
|
|
||||||
described in the [macOS details](#macos-details) section.
|
|
||||||
|
|
||||||
More information about these steps in the
|
|
||||||
[official Skia documentation](https://skia.org/user/build).
|
|
||||||
|
|
||||||
## Skia on Linux
|
|
||||||
|
|
||||||
These steps will create a `deps` folder in your home directory with a
|
|
||||||
couple of subdirectories needed to build Skia (you can change the
|
|
||||||
`$HOME/deps` with other directory). Some of these commands will take
|
|
||||||
several minutes to finish:
|
|
||||||
|
|
||||||
mkdir $HOME/deps
|
|
||||||
cd $HOME/deps
|
|
||||||
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
|
|
||||||
git clone -b aseprite-m71 https://github.com/aseprite/skia.git
|
|
||||||
export PATH="${PWD}/depot_tools:${PATH}"
|
|
||||||
cd skia
|
|
||||||
python tools/git-sync-deps
|
|
||||||
gn gen out/Release --args="is_debug=false is_official_build=true skia_use_system_expat=false skia_use_system_icu=false skia_use_system_libjpeg_turbo=false skia_use_system_libpng=false skia_use_system_libwebp=false skia_use_system_zlib=false"
|
|
||||||
ninja -C out/Release skia
|
|
||||||
|
|
||||||
After this you should have all Skia libraries compiled. When you
|
|
||||||
[compile Aseprite](#compiling), remember to add
|
|
||||||
`-DSKIA_DIR=$HOME/deps/skia` parameter to your `cmake` call as
|
|
||||||
described in the [Linux details](#linux-details) section.
|
|
||||||
|
|
||||||
More information about these steps in the
|
|
||||||
[official Skia documentation](https://skia.org/user/build).
|
|
||||||
|
@ -10,10 +10,10 @@
|
|||||||
**Aseprite** is a program to create animated sprites. Its main
|
**Aseprite** is a program to create animated sprites. Its main
|
||||||
features are:
|
features are:
|
||||||
|
|
||||||
* Sprites are composed by [**layers** & **frames**](http://www.aseprite.org/docs/timeline/) (as separated concepts).
|
* Sprites are composed of [**layers** & **frames**](http://www.aseprite.org/docs/timeline/) (as separated concepts).
|
||||||
* Supported [color modes](http://www.aseprite.org/docs/color/): **RGBA**, **Indexed** (palettes up to 256
|
* Supported [color modes](http://www.aseprite.org/docs/color/): **RGBA**, **Indexed** (palettes up to 256
|
||||||
colors), and Grayscale.
|
colors), and Grayscale.
|
||||||
* Load/save sequence of **PNG** files and **GIF** animations (and
|
* Load/save a sequence of **PNG** files and **GIF** animations (and
|
||||||
FLC, FLI, JPG, BMP, PCX, TGA).
|
FLC, FLI, JPG, BMP, PCX, TGA).
|
||||||
* Export/import animations to/from **Sprite Sheets**.
|
* Export/import animations to/from **Sprite Sheets**.
|
||||||
* **Tiled** drawing mode, useful to draw **patterns** and textures.
|
* **Tiled** drawing mode, useful to draw **patterns** and textures.
|
||||||
@ -64,12 +64,12 @@ Aseprite includes color palettes created by:
|
|||||||
|
|
||||||
* [Richard "DawnBringer" Fhager](http://pixeljoint.com/p/23821.htm), [16 colors](http://pixeljoint.com/forum/forum_posts.asp?TID=12795), [32 colors](http://pixeljoint.com/forum/forum_posts.asp?TID=16247).
|
* [Richard "DawnBringer" Fhager](http://pixeljoint.com/p/23821.htm), [16 colors](http://pixeljoint.com/forum/forum_posts.asp?TID=12795), [32 colors](http://pixeljoint.com/forum/forum_posts.asp?TID=16247).
|
||||||
* [Arne Niklas Jansson](http://androidarts.com/), [16 colors](http://androidarts.com/palette/16pal.htm), [32 colors](http://wayofthepixel.net/index.php?topic=15824.msg144494).
|
* [Arne Niklas Jansson](http://androidarts.com/), [16 colors](http://androidarts.com/palette/16pal.htm), [32 colors](http://wayofthepixel.net/index.php?topic=15824.msg144494).
|
||||||
* [ENDESGA Studios](https://twitter.com/ENDESGA), [EDG16 and EDG32](https://forums.tigsource.com/index.php?topic=46126.msg1279124#msg1279124), and [other palettes](https://twitter.com/ENDESGA/status/865812366931353600)
|
* [ENDESGA Studios](https://twitter.com/ENDESGA), [EDG16 and EDG32](https://forums.tigsource.com/index.php?topic=46126.msg1279124#msg1279124), and [other palettes](https://twitter.com/ENDESGA/status/865812366931353600).
|
||||||
* [Hyohnoo Games](https://twitter.com/Hyohnoo), [mail24](https://twitter.com/Hyohnoo/status/797472587974639616) palette.
|
* [Hyohnoo Games](https://twitter.com/Hyohnoo), [mail24](https://twitter.com/Hyohnoo/status/797472587974639616) palette.
|
||||||
* [Davit Masia](https://twitter.com/DavitMasia), [matriax8c](https://twitter.com/DavitMasia/status/834862452164612096) palette.
|
* [Davit Masia](https://twitter.com/DavitMasia), [matriax8c](https://twitter.com/DavitMasia/status/834862452164612096) palette.
|
||||||
* [Javier Guerrero](https://twitter.com/Xavier_Gd), [nyx8](https://twitter.com/Xavier_Gd/status/868519467864686594) palette.
|
* [Javier Guerrero](https://twitter.com/Xavier_Gd), [nyx8](https://twitter.com/Xavier_Gd/status/868519467864686594) palette.
|
||||||
* [Adigun A. Polack](https://twitter.com/adigunpolack), [AAP-64](http://pixeljoint.com/pixelart/119466.htm), [AAP-Splendor128](http://pixeljoint.com/pixelart/120714.htm), [SimpleJPC-16](http://pixeljoint.com/pixelart/119844.htm), and [AAP-Micro12](http://pixeljoint.com/pixelart/121151.htm) palette.
|
* [Adigun A. Polack](https://twitter.com/adigunpolack), [AAP-64](http://pixeljoint.com/pixelart/119466.htm), [AAP-Splendor128](http://pixeljoint.com/pixelart/120714.htm), [SimpleJPC-16](http://pixeljoint.com/pixelart/119844.htm), and [AAP-Micro12](http://pixeljoint.com/pixelart/121151.htm) palette.
|
||||||
* [PineTreePizza](https://twitter.com/PineTreePizza), [Rosy-42](https://twitter.com/PineTreePizza/status/1006536191955623938) palette
|
* [PineTreePizza](https://twitter.com/PineTreePizza), [Rosy-42](https://twitter.com/PineTreePizza/status/1006536191955623938) palette.
|
||||||
|
|
||||||
It tries to replicate some pixel-art algorithms:
|
It tries to replicate some pixel-art algorithms:
|
||||||
|
|
||||||
|
@ -35,38 +35,15 @@ include(FindPkgConfig)
|
|||||||
pkg_check_modules(PC_HARFBUZZ harfbuzz>=0.9.7)
|
pkg_check_modules(PC_HARFBUZZ harfbuzz>=0.9.7)
|
||||||
|
|
||||||
find_path(HARFBUZZ_INCLUDE_DIRS NAMES hb.h
|
find_path(HARFBUZZ_INCLUDE_DIRS NAMES hb.h
|
||||||
HINTS ${PC_HARFBUZZ_INCLUDE_DIRS} ${PC_HARFBUZZ_INCLUDEDIR}
|
HINTS ${PC_HARFBUZZ_INCLUDE_DIRS} ${PC_HARFBUZZ_INCLUDEDIR})
|
||||||
)
|
|
||||||
|
|
||||||
find_library(HARFBUZZ_LIBRARIES NAMES harfbuzz
|
find_library(HARFBUZZ_LIBRARIES NAMES harfbuzz
|
||||||
HINTS ${PC_HARFBUZZ_LIBRARY_DIRS} ${PC_HARFBUZZ_LIBDIR}
|
HINTS ${PC_HARFBUZZ_LIBRARY_DIRS} ${PC_HARFBUZZ_LIBDIR})
|
||||||
)
|
|
||||||
|
|
||||||
# HarfBuzz 0.9.18 split ICU support into a separate harfbuzz-icu library.
|
|
||||||
if ("${PC_HARFBUZZ_VERSION}" VERSION_GREATER "0.9.17")
|
|
||||||
if (HarfBuzz_FIND_REQUIRED)
|
|
||||||
set(_HARFBUZZ_REQUIRED REQUIRED)
|
|
||||||
else ()
|
|
||||||
set(_HARFBUZZ_REQUIRED "")
|
|
||||||
endif ()
|
|
||||||
pkg_check_modules(PC_HARFBUZZ_ICU harfbuzz-icu>=0.9.18 ${_HARFBUZZ_REQUIRED})
|
|
||||||
find_library(HARFBUZZ_ICU_LIBRARIES NAMES harfbuzz-icu
|
|
||||||
HINTS ${PC_HARFBUZZ_ICU_LIBRARY_DIRS} ${PC_HARFBUZZ_ICU_LIBDIR}
|
|
||||||
)
|
|
||||||
if (HARFBUZZ_ICU_LIBRARIES)
|
|
||||||
list(APPEND HARFBUZZ_LIBRARIES "${HARFBUZZ_ICU_LIBRARIES}")
|
|
||||||
endif ()
|
|
||||||
set(_HARFBUZZ_EXTRA_REQUIRED_VAR "HARFBUZZ_ICU_LIBRARIES")
|
|
||||||
else ()
|
|
||||||
set(_HARFBUZZ_EXTRA_REQUIRED_VAR "")
|
|
||||||
endif ()
|
|
||||||
|
|
||||||
include(FindPackageHandleStandardArgs)
|
include(FindPackageHandleStandardArgs)
|
||||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(HarfBuzz DEFAULT_MSG HARFBUZZ_INCLUDE_DIRS
|
FIND_PACKAGE_HANDLE_STANDARD_ARGS(HarfBuzz DEFAULT_MSG HARFBUZZ_INCLUDE_DIRS
|
||||||
HARFBUZZ_LIBRARIES ${_HARFBUZZ_EXTRA_REQUIRED_VAR})
|
HARFBUZZ_LIBRARIES)
|
||||||
|
|
||||||
mark_as_advanced(
|
mark_as_advanced(
|
||||||
HARFBUZZ_ICU_LIBRARIES
|
|
||||||
HARFBUZZ_INCLUDE_DIRS
|
HARFBUZZ_INCLUDE_DIRS
|
||||||
HARFBUZZ_LIBRARIES
|
HARFBUZZ_LIBRARIES)
|
||||||
)
|
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
if(MSVC)
|
|
||||||
set(CMAKE_C_FLAGS_DEBUG_INIT "/D_DEBUG /MTd /Zi /Ob0 /Od /RTC1")
|
|
||||||
set(CMAKE_C_FLAGS_MINSIZEREL_INIT "/MT /O1 /Ob1 /D NDEBUG")
|
|
||||||
set(CMAKE_C_FLAGS_RELEASE_INIT "/MT /O2 /Ob2 /D NDEBUG")
|
|
||||||
set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "/MT /Zi /O2 /Ob1 /D NDEBUG")
|
|
||||||
endif()
|
|
@ -1,6 +0,0 @@
|
|||||||
if(MSVC)
|
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG_INIT "/D_DEBUG /MTd /Zi /Ob0 /Od /RTC1")
|
|
||||||
set(CMAKE_CXX_FLAGS_MINSIZEREL_INIT "/MT /O1 /Ob1 /D NDEBUG")
|
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE_INIT "/MT /O2 /Ob2 /D NDEBUG")
|
|
||||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "/MT /Zi /O2 /Ob1 /D NDEBUG")
|
|
||||||
endif()
|
|
@ -2,7 +2,7 @@
|
|||||||
<!-- Aseprite -->
|
<!-- Aseprite -->
|
||||||
<!-- Copyright (C) 2018-2020 Igara Studio S.A. -->
|
<!-- Copyright (C) 2018-2020 Igara Studio S.A. -->
|
||||||
<!-- Copyright (C) 2001-2018 David Capello -->
|
<!-- Copyright (C) 2001-2018 David Capello -->
|
||||||
<gui version="1.3-dev">
|
<gui>
|
||||||
<!-- Keyboard shortcuts -->
|
<!-- Keyboard shortcuts -->
|
||||||
<keyboard version="1">
|
<keyboard version="1">
|
||||||
|
|
||||||
|
2
laf
2
laf
@ -1 +1 @@
|
|||||||
Subproject commit 60b2e83ce159a79368141c5386a764e16ede0c27
|
Subproject commit 98506341d68a318f4916a891ab12351a5db05f98
|
@ -1,5 +1,5 @@
|
|||||||
# Aseprite
|
# Aseprite
|
||||||
# Copyright (C) 2019 Igara Studio S.A.
|
# Copyright (C) 2019-2020 Igara Studio S.A.
|
||||||
# Copyright (C) 2001-2018 David Capello
|
# Copyright (C) 2001-2018 David Capello
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
@ -37,13 +37,6 @@ if(WIN32)
|
|||||||
include_directories(..)
|
include_directories(..)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
######################################################################
|
|
||||||
# Custom Aseprite website (for testing server-side)
|
|
||||||
|
|
||||||
if(NOT "${CUSTOM_WEBSITE_URL}" STREQUAL "")
|
|
||||||
add_definitions(-DCUSTOM_WEBSITE_URL="${CUSTOM_WEBSITE_URL}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
# With static libcurl
|
# With static libcurl
|
||||||
|
|
||||||
@ -106,6 +99,7 @@ add_subdirectory(flic)
|
|||||||
add_subdirectory(render)
|
add_subdirectory(render)
|
||||||
add_subdirectory(dio)
|
add_subdirectory(dio)
|
||||||
add_subdirectory(ui)
|
add_subdirectory(ui)
|
||||||
|
add_subdirectory(ver)
|
||||||
|
|
||||||
if(REQUIRE_CURL)
|
if(REQUIRE_CURL)
|
||||||
add_subdirectory(net)
|
add_subdirectory(net)
|
||||||
@ -182,6 +176,7 @@ if(ENABLE_ASEPRITE_EXE)
|
|||||||
if(WIN32 AND ENABLE_UI)
|
if(WIN32 AND ENABLE_UI)
|
||||||
set_target_properties(aseprite PROPERTIES WIN32_EXECUTABLE true)
|
set_target_properties(aseprite PROPERTIES WIN32_EXECUTABLE true)
|
||||||
endif()
|
endif()
|
||||||
|
set_target_properties(aseprite PROPERTIES LINK_FLAGS "${LAF_BACKEND_LINK_FLAGS}")
|
||||||
target_link_libraries(aseprite app-lib)
|
target_link_libraries(aseprite app-lib)
|
||||||
add_dependencies(aseprite copy_data)
|
add_dependencies(aseprite copy_data)
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# Aseprite
|
# Aseprite
|
||||||
# Copyright (C) 2018-2019 Igara Studio S.A.
|
# Copyright (C) 2018-2020 Igara Studio S.A.
|
||||||
# Copyright (C) 2001-2018 David Capello
|
# Copyright (C) 2001-2018 David Capello
|
||||||
|
|
||||||
# Generate a ui::Widget for each widget in a XML file
|
# Generate a ui::Widget for each widget in a XML file
|
||||||
@ -305,7 +305,6 @@ if(ENABLE_UI)
|
|||||||
modules/editors.cpp
|
modules/editors.cpp
|
||||||
modules/gfx.cpp
|
modules/gfx.cpp
|
||||||
modules/gui.cpp
|
modules/gui.cpp
|
||||||
send_crash.cpp
|
|
||||||
ui/app_menuitem.cpp
|
ui/app_menuitem.cpp
|
||||||
ui/backup_indicator.cpp
|
ui/backup_indicator.cpp
|
||||||
ui/browser_view.cpp
|
ui/browser_view.cpp
|
||||||
@ -585,6 +584,7 @@ add_library(app-lib
|
|||||||
res/resources_loader.cpp
|
res/resources_loader.cpp
|
||||||
resource_finder.cpp
|
resource_finder.cpp
|
||||||
restore_visible_layers.cpp
|
restore_visible_layers.cpp
|
||||||
|
send_crash.cpp
|
||||||
shade.cpp
|
shade.cpp
|
||||||
site.cpp
|
site.cpp
|
||||||
snap_to_grid.cpp
|
snap_to_grid.cpp
|
||||||
@ -629,6 +629,10 @@ add_library(app-lib
|
|||||||
${scripting_files}
|
${scripting_files}
|
||||||
${generated_files})
|
${generated_files})
|
||||||
|
|
||||||
|
if(TARGET generated_version)
|
||||||
|
add_dependencies(app-lib generated_version)
|
||||||
|
endif()
|
||||||
|
|
||||||
target_link_libraries(app-lib
|
target_link_libraries(app-lib
|
||||||
laf-base
|
laf-base
|
||||||
cfg-lib
|
cfg-lib
|
||||||
@ -643,6 +647,7 @@ target_link_libraries(app-lib
|
|||||||
laf-ft
|
laf-ft
|
||||||
laf-os
|
laf-os
|
||||||
ui-lib
|
ui-lib
|
||||||
|
ver-lib
|
||||||
undo
|
undo
|
||||||
${CMARK_LIBRARIES}
|
${CMARK_LIBRARIES}
|
||||||
${TINYXML_LIBRARY}
|
${TINYXML_LIBRARY}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2018-2019 Igara Studio S.A.
|
// Copyright (C) 2018-2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -67,6 +67,7 @@
|
|||||||
#include "render/render.h"
|
#include "render/render.h"
|
||||||
#include "ui/intern.h"
|
#include "ui/intern.h"
|
||||||
#include "ui/ui.h"
|
#include "ui/ui.h"
|
||||||
|
#include "ver/info.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@ -514,7 +515,7 @@ App::~App()
|
|||||||
// no re-throw
|
// no re-throw
|
||||||
}
|
}
|
||||||
catch (...) {
|
catch (...) {
|
||||||
os::error_message("Error closing " PACKAGE ".\n(uncaught exception)");
|
os::error_message("Error closing the program.\n(uncaught exception)");
|
||||||
|
|
||||||
// no re-throw
|
// no re-throw
|
||||||
}
|
}
|
||||||
@ -606,7 +607,8 @@ crash::DataRecovery* App::dataRecovery() const
|
|||||||
#ifdef ENABLE_UI
|
#ifdef ENABLE_UI
|
||||||
void App::showNotification(INotificationDelegate* del)
|
void App::showNotification(INotificationDelegate* del)
|
||||||
{
|
{
|
||||||
m_mainWindow->showNotification(del);
|
if (m_mainWindow)
|
||||||
|
m_mainWindow->showNotification(del);
|
||||||
}
|
}
|
||||||
|
|
||||||
void App::showBackupNotification(bool state)
|
void App::showBackupNotification(bool state)
|
||||||
@ -625,7 +627,7 @@ void App::showBackupNotification(bool state)
|
|||||||
|
|
||||||
void App::updateDisplayTitleBar()
|
void App::updateDisplayTitleBar()
|
||||||
{
|
{
|
||||||
std::string defaultTitle = PACKAGE " v" VERSION;
|
std::string defaultTitle = fmt::format("{} v{}", get_app_name(), get_app_version());
|
||||||
std::string title;
|
std::string title;
|
||||||
|
|
||||||
DocView* docView = UIContext::instance()->activeView();
|
DocView* docView = UIContext::instance()->activeView();
|
||||||
@ -636,7 +638,7 @@ void App::updateDisplayTitleBar()
|
|||||||
}
|
}
|
||||||
|
|
||||||
title += defaultTitle;
|
title += defaultTitle;
|
||||||
os::instance()->defaultDisplay()->setTitleBar(title);
|
os::instance()->defaultDisplay()->setTitle(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
InputChain& App::inputChain()
|
InputChain& App::inputChain()
|
||||||
@ -709,18 +711,4 @@ int app_get_color_to_clear_layer(Layer* layer)
|
|||||||
return color_utils::color_for_layer(color, layer);
|
return color_utils::color_for_layer(color, layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string memory_dump_filename()
|
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
|
||||||
static const char* kDefaultCrashName = PACKAGE "-crash-" VERSION ".dmp";
|
|
||||||
|
|
||||||
app::ResourceFinder rf;
|
|
||||||
rf.includeUserDir(kDefaultCrashName);
|
|
||||||
return rf.getFirstOrCreateDefault();
|
|
||||||
|
|
||||||
#else
|
|
||||||
return "";
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace app
|
} // namespace app
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2018-2019 Igara Studio S.A.
|
// Copyright (C) 2018-2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -117,6 +117,9 @@ namespace app {
|
|||||||
script::Engine* scriptEngine() { return m_engine.get(); }
|
script::Engine* scriptEngine() { return m_engine.get(); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
const std::string& memoryDumpFilename() const { return m_memoryDumpFilename; }
|
||||||
|
void memoryDumpFilename(const std::string& fn) { m_memoryDumpFilename = fn; }
|
||||||
|
|
||||||
// App Signals
|
// App Signals
|
||||||
obs::signal<void()> Exit;
|
obs::signal<void()> Exit;
|
||||||
obs::signal<void()> PaletteChange;
|
obs::signal<void()> PaletteChange;
|
||||||
@ -145,13 +148,16 @@ namespace app {
|
|||||||
#ifdef ENABLE_SCRIPTING
|
#ifdef ENABLE_SCRIPTING
|
||||||
std::unique_ptr<script::Engine> m_engine;
|
std::unique_ptr<script::Engine> m_engine;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Set the memory dump filename to show in the Preferences dialog
|
||||||
|
// or the "send crash" dialog. It's set by the SendCrash class.
|
||||||
|
std::string m_memoryDumpFilename;
|
||||||
};
|
};
|
||||||
|
|
||||||
void app_refresh_screen();
|
void app_refresh_screen();
|
||||||
void app_rebuild_documents_tabs();
|
void app_rebuild_documents_tabs();
|
||||||
PixelFormat app_get_current_pixel_format();
|
PixelFormat app_get_current_pixel_format();
|
||||||
int app_get_color_to_clear_layer(doc::Layer* layer);
|
int app_get_color_to_clear_layer(doc::Layer* layer);
|
||||||
std::string memory_dump_filename();
|
|
||||||
|
|
||||||
} // namespace app
|
} // namespace app
|
||||||
|
|
||||||
|
@ -29,9 +29,11 @@
|
|||||||
#include "base/bind.h"
|
#include "base/bind.h"
|
||||||
#include "base/fs.h"
|
#include "base/fs.h"
|
||||||
#include "base/string.h"
|
#include "base/string.h"
|
||||||
|
#include "fmt/format.h"
|
||||||
#include "os/menus.h"
|
#include "os/menus.h"
|
||||||
#include "os/system.h"
|
#include "os/system.h"
|
||||||
#include "ui/ui.h"
|
#include "ui/ui.h"
|
||||||
|
#include "ver/info.h"
|
||||||
|
|
||||||
#include "tinyxml.h"
|
#include "tinyxml.h"
|
||||||
|
|
||||||
@ -337,12 +339,6 @@ void AppMenus::reload()
|
|||||||
|
|
||||||
m_rootMenu.reset(loadMenuById(handle, "main_menu"));
|
m_rootMenu.reset(loadMenuById(handle, "main_menu"));
|
||||||
|
|
||||||
#if _DEBUG
|
|
||||||
// Add a warning element because the user is not using the last well-known gui.xml file.
|
|
||||||
if (GuiXml::instance()->version() != VERSION)
|
|
||||||
m_rootMenu->insertChild(0, createInvalidVersionMenuitem());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
LOG("MENU: Main menu loaded.\n");
|
LOG("MENU: Main menu loaded.\n");
|
||||||
|
|
||||||
m_tabPopupMenu.reset(loadMenuById(handle, "tab_popup_menu"));
|
m_tabPopupMenu.reset(loadMenuById(handle, "tab_popup_menu"));
|
||||||
@ -633,20 +629,6 @@ Widget* AppMenus::convertXmlelemToMenuitem(TiXmlElement* elem)
|
|||||||
return menuitem;
|
return menuitem;
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget* AppMenus::createInvalidVersionMenuitem()
|
|
||||||
{
|
|
||||||
AppMenuItem* menuitem = new AppMenuItem("WARNING!");
|
|
||||||
Menu* subMenu = new Menu();
|
|
||||||
subMenu->addChild(new AppMenuItem(PACKAGE " is using a customized gui.xml (maybe from your HOME directory)."));
|
|
||||||
subMenu->addChild(new AppMenuItem("You should update your customized gui.xml file to the new version to get"));
|
|
||||||
subMenu->addChild(new AppMenuItem("the latest commands available."));
|
|
||||||
subMenu->addChild(new MenuSeparator);
|
|
||||||
subMenu->addChild(new AppMenuItem("You can bypass this validation adding the correct version"));
|
|
||||||
subMenu->addChild(new AppMenuItem("number in <gui version=\"" VERSION "\"> element."));
|
|
||||||
menuitem->setSubmenu(subMenu);
|
|
||||||
return menuitem;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppMenus::applyShortcutToMenuitemsWithCommand(Command* command,
|
void AppMenus::applyShortcutToMenuitemsWithCommand(Command* command,
|
||||||
const Params& params,
|
const Params& params,
|
||||||
const KeyPtr& key)
|
const KeyPtr& key)
|
||||||
@ -732,7 +714,7 @@ void AppMenus::createNativeMenus()
|
|||||||
|
|
||||||
#ifdef __APPLE__ // Create default macOS app menus (App ... Window)
|
#ifdef __APPLE__ // Create default macOS app menus (App ... Window)
|
||||||
{
|
{
|
||||||
os::MenuItemInfo about("About " PACKAGE);
|
os::MenuItemInfo about(fmt::format("About {}", get_app_name()));
|
||||||
auto native = get_native_shortcut_for_command(CommandId::About());
|
auto native = get_native_shortcut_for_command(CommandId::About());
|
||||||
about.shortcut = native.shortcut;
|
about.shortcut = native.shortcut;
|
||||||
about.execute = [native]{
|
about.execute = [native]{
|
||||||
@ -758,10 +740,10 @@ void AppMenus::createNativeMenus()
|
|||||||
item->setEnabled(can_call_global_shortcut(&native));
|
item->setEnabled(can_call_global_shortcut(&native));
|
||||||
};
|
};
|
||||||
|
|
||||||
os::MenuItemInfo hide("Hide " PACKAGE, os::MenuItemInfo::Hide);
|
os::MenuItemInfo hide(fmt::format("Hide {}", get_app_name()), os::MenuItemInfo::Hide);
|
||||||
hide.shortcut = os::Shortcut('h', os::kKeyCmdModifier);
|
hide.shortcut = os::Shortcut('h', os::kKeyCmdModifier);
|
||||||
|
|
||||||
os::MenuItemInfo quit("Quit " PACKAGE, os::MenuItemInfo::Quit);
|
os::MenuItemInfo quit(fmt::format("Quit {}", get_app_name()), os::MenuItemInfo::Quit);
|
||||||
quit.shortcut = os::Shortcut('q', os::kKeyCmdModifier);
|
quit.shortcut = os::Shortcut('q', os::kKeyCmdModifier);
|
||||||
|
|
||||||
os::Menu* appMenu = menus->createMenu();
|
os::Menu* appMenu = menus->createMenu();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2019 Igara Studio S.A.
|
// Copyright (C) 2019-2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -69,7 +69,6 @@ namespace app {
|
|||||||
Menu* loadMenuById(TiXmlHandle& handle, const char *id);
|
Menu* loadMenuById(TiXmlHandle& handle, const char *id);
|
||||||
Menu* convertXmlelemToMenu(TiXmlElement* elem);
|
Menu* convertXmlelemToMenu(TiXmlElement* elem);
|
||||||
Widget* convertXmlelemToMenuitem(TiXmlElement* elem);
|
Widget* convertXmlelemToMenuitem(TiXmlElement* elem);
|
||||||
Widget* createInvalidVersionMenuitem();
|
|
||||||
void applyShortcutToMenuitemsWithCommand(Menu* menu, Command* command, const Params& params,
|
void applyShortcutToMenuitemsWithCommand(Menu* menu, Command* command, const Params& params,
|
||||||
const KeyPtr& key);
|
const KeyPtr& key);
|
||||||
void syncNativeMenuItemKeyShortcuts(Menu* menu);
|
void syncNativeMenuItemKeyShortcuts(Menu* menu);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
|
// Copyright (C) 2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2017 David Capello
|
// Copyright (C) 2001-2017 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -19,6 +20,7 @@
|
|||||||
#include "base/launcher.h"
|
#include "base/launcher.h"
|
||||||
#include "base/replace_string.h"
|
#include "base/replace_string.h"
|
||||||
#include "base/version.h"
|
#include "base/version.h"
|
||||||
|
#include "ver/info.h"
|
||||||
|
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@ -202,7 +204,7 @@ void CheckUpdateThreadLauncher::checkForUpdates()
|
|||||||
|
|
||||||
void CheckUpdateThreadLauncher::showUI()
|
void CheckUpdateThreadLauncher::showUI()
|
||||||
{
|
{
|
||||||
std::string localVersionStr = VERSION;
|
std::string localVersionStr = get_app_version();
|
||||||
base::replace_string(localVersionStr, "-x64", "");
|
base::replace_string(localVersionStr, "-x64", "");
|
||||||
bool newVer = false;
|
bool newVer = false;
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2018-2019 Igara Studio S.A.
|
// Copyright (C) 2018-2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2016-2018 David Capello
|
// Copyright (C) 2016-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -26,6 +26,7 @@
|
|||||||
#include "doc/slice.h"
|
#include "doc/slice.h"
|
||||||
#include "doc/sprite.h"
|
#include "doc/sprite.h"
|
||||||
#include "doc/tag.h"
|
#include "doc/tag.h"
|
||||||
|
#include "ver/info.h"
|
||||||
|
|
||||||
#ifdef ENABLE_SCRIPTING
|
#ifdef ENABLE_SCRIPTING
|
||||||
#include "app/app.h"
|
#include "app/app.h"
|
||||||
@ -40,18 +41,20 @@ namespace app {
|
|||||||
void DefaultCliDelegate::showHelp(const AppOptions& options)
|
void DefaultCliDelegate::showHelp(const AppOptions& options)
|
||||||
{
|
{
|
||||||
std::cout
|
std::cout
|
||||||
<< PACKAGE << " v" << VERSION << " | A pixel art program\n" << COPYRIGHT
|
<< get_app_name() << " v" << get_app_version()
|
||||||
|
<< " | A pixel art program\n"
|
||||||
|
<< get_app_copyright()
|
||||||
<< "\n\nUsage:\n"
|
<< "\n\nUsage:\n"
|
||||||
<< " " << options.exeName() << " [OPTIONS] [FILES]...\n\n"
|
<< " " << options.exeName() << " [OPTIONS] [FILES]...\n\n"
|
||||||
<< "Options:\n"
|
<< "Options:\n"
|
||||||
<< options.programOptions()
|
<< options.programOptions()
|
||||||
<< "\nFind more information in " << PACKAGE
|
<< "\nFind more information in " << get_app_name()
|
||||||
<< " web site: " << WEBSITE << "\n\n";
|
<< " web site: " << get_app_url() << "\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefaultCliDelegate::showVersion()
|
void DefaultCliDelegate::showVersion()
|
||||||
{
|
{
|
||||||
std::cout << PACKAGE << ' ' << VERSION << '\n';
|
std::cout << get_app_name() << ' ' << get_app_version() << '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefaultCliDelegate::afterOpenFile(const CliOpenFile& cof)
|
void DefaultCliDelegate::afterOpenFile(const CliOpenFile& cof)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2018-2019 Igara Studio S.A.
|
// Copyright (C) 2018-2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2016-2018 David Capello
|
// Copyright (C) 2016-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -19,6 +19,8 @@
|
|||||||
#include "base/fs.h"
|
#include "base/fs.h"
|
||||||
#include "doc/layer.h"
|
#include "doc/layer.h"
|
||||||
#include "doc/sprite.h"
|
#include "doc/sprite.h"
|
||||||
|
#include "fmt/format.h"
|
||||||
|
#include "ver/info.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@ -27,12 +29,12 @@ namespace app {
|
|||||||
|
|
||||||
void PreviewCliDelegate::showHelp(const AppOptions& options)
|
void PreviewCliDelegate::showHelp(const AppOptions& options)
|
||||||
{
|
{
|
||||||
std::cout << "- Show " PACKAGE " CLI usage\n";
|
std::cout << fmt::format("- Show {} CLI usage\n", get_app_name());
|
||||||
}
|
}
|
||||||
|
|
||||||
void PreviewCliDelegate::showVersion()
|
void PreviewCliDelegate::showVersion()
|
||||||
{
|
{
|
||||||
std::cout << "- Show " PACKAGE " version\n";
|
std::cout << fmt::format("- Show {} version\n", get_app_name());
|
||||||
}
|
}
|
||||||
|
|
||||||
void PreviewCliDelegate::uiMode()
|
void PreviewCliDelegate::uiMode()
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2019 Igara Studio S.A.
|
// Copyright (C) 2019-2020 Igara Studio S.A.
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
// the End-User License Agreement for Aseprite.
|
// the End-User License Agreement for Aseprite.
|
||||||
@ -22,8 +22,6 @@ namespace app {
|
|||||||
ClosedDocs::ClosedDocs(const Preferences& pref)
|
ClosedDocs::ClosedDocs(const Preferences& pref)
|
||||||
: m_done(false)
|
: m_done(false)
|
||||||
{
|
{
|
||||||
CLOSEDOC_TRACE("CLOSEDOC: Init");
|
|
||||||
|
|
||||||
if (pref.general.dataRecovery())
|
if (pref.general.dataRecovery())
|
||||||
m_dataRecoveryPeriodMSecs = int(1000.0*60.0*pref.general.dataRecoveryPeriod());
|
m_dataRecoveryPeriodMSecs = int(1000.0*60.0*pref.general.dataRecoveryPeriod());
|
||||||
else
|
else
|
||||||
@ -33,6 +31,10 @@ ClosedDocs::ClosedDocs(const Preferences& pref)
|
|||||||
m_keepClosedDocAliveForMSecs = int(1000.0*60.0*pref.general.keepClosedSpriteOnMemoryFor());
|
m_keepClosedDocAliveForMSecs = int(1000.0*60.0*pref.general.keepClosedSpriteOnMemoryFor());
|
||||||
else
|
else
|
||||||
m_keepClosedDocAliveForMSecs = 0;
|
m_keepClosedDocAliveForMSecs = 0;
|
||||||
|
|
||||||
|
CLOSEDOC_TRACE("CLOSEDOC: Init",
|
||||||
|
"dataRecoveryPeriod", m_dataRecoveryPeriodMSecs,
|
||||||
|
"keepClosedDocs", m_keepClosedDocAliveForMSecs);
|
||||||
}
|
}
|
||||||
|
|
||||||
ClosedDocs::~ClosedDocs()
|
ClosedDocs::~ClosedDocs()
|
||||||
@ -123,15 +125,20 @@ void ClosedDocs::backgroundThread()
|
|||||||
|
|
||||||
for (auto it=m_docs.begin(); it != m_docs.end(); ) {
|
for (auto it=m_docs.begin(); it != m_docs.end(); ) {
|
||||||
const ClosedDoc& closedDoc = *it;
|
const ClosedDoc& closedDoc = *it;
|
||||||
|
auto doc = closedDoc.doc;
|
||||||
|
|
||||||
base::tick_t diff = now - closedDoc.timestamp;
|
base::tick_t diff = now - closedDoc.timestamp;
|
||||||
if (diff >= m_keepClosedDocAliveForMSecs) {
|
if (diff >= m_keepClosedDocAliveForMSecs) {
|
||||||
if (m_dataRecoveryPeriodMSecs == 0 ||
|
if (// If we backup process is disabled
|
||||||
closedDoc.doc->isFullyBackedUp()) {
|
m_dataRecoveryPeriodMSecs == 0 ||
|
||||||
|
// Or this document doesn't need a backup (e.g. an unmodified document)
|
||||||
|
!doc->needsBackup() ||
|
||||||
|
// Or the document already has the backup done
|
||||||
|
doc->isFullyBackedUp()) {
|
||||||
// Finally delete the document (this is the place where we
|
// Finally delete the document (this is the place where we
|
||||||
// delete all documents created/loaded by the user)
|
// delete all documents created/loaded by the user)
|
||||||
CLOSEDOC_TRACE("CLOSEDOC: [BG] Delete doc", closedDoc.doc);
|
CLOSEDOC_TRACE("CLOSEDOC: [BG] Delete doc", doc);
|
||||||
delete closedDoc.doc;
|
delete doc;
|
||||||
it = m_docs.erase(it);
|
it = m_docs.erase(it);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
|
// Copyright (C) 2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -13,6 +14,8 @@
|
|||||||
#include "app/modules/gui.h"
|
#include "app/modules/gui.h"
|
||||||
#include "app/ui/main_window.h"
|
#include "app/ui/main_window.h"
|
||||||
#include "base/bind.h"
|
#include "base/bind.h"
|
||||||
|
#include "fmt/format.h"
|
||||||
|
#include "ver/info.h"
|
||||||
|
|
||||||
#include "about.xml.h"
|
#include "about.xml.h"
|
||||||
|
|
||||||
@ -36,7 +39,7 @@ AboutCommand::AboutCommand()
|
|||||||
void AboutCommand::onExecute(Context* context)
|
void AboutCommand::onExecute(Context* context)
|
||||||
{
|
{
|
||||||
gen::About window;
|
gen::About window;
|
||||||
window.title()->setText(PACKAGE " v" VERSION);
|
window.title()->setText(fmt::format("{} v{}", get_app_name(), get_app_version()));
|
||||||
window.licenses()->Click.connect(
|
window.licenses()->Click.connect(
|
||||||
[&window]{
|
[&window]{
|
||||||
window.closeWindow(nullptr);
|
window.closeWindow(nullptr);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
|
// Copyright (C) 2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2017 David Capello
|
// Copyright (C) 2001-2017 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -12,6 +13,7 @@
|
|||||||
#include "app/commands/params.h"
|
#include "app/commands/params.h"
|
||||||
#include "app/launcher.h"
|
#include "app/launcher.h"
|
||||||
#include "base/fs.h"
|
#include "base/fs.h"
|
||||||
|
#include "ver/info.h"
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
|
|
||||||
@ -42,7 +44,7 @@ void LaunchCommand::onLoadParams(const Params& params)
|
|||||||
m_path = params.get("path");
|
m_path = params.get("path");
|
||||||
|
|
||||||
if (m_type == Url && !m_path.empty() && m_path[0] == '/') {
|
if (m_type == Url && !m_path.empty() && m_path[0] == '/') {
|
||||||
m_path = WEBSITE + m_path.substr(1);
|
m_path = std::string(get_app_url()) + m_path.substr(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "base/bind.h"
|
#include "base/bind.h"
|
||||||
#include "base/chrono.h"
|
#include "base/chrono.h"
|
||||||
#include "base/convert_to.h"
|
#include "base/convert_to.h"
|
||||||
|
#include "base/scoped_value.h"
|
||||||
#include "doc/image.h"
|
#include "doc/image.h"
|
||||||
#include "doc/mask.h"
|
#include "doc/mask.h"
|
||||||
#include "doc/sprite.h"
|
#include "doc/sprite.h"
|
||||||
@ -70,11 +71,11 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Window* m_window; // TODO we cannot use a std::unique_ptr because clone() needs a copy ctor
|
Window* m_window = nullptr;
|
||||||
ColorButton* m_buttonColor;
|
ColorButton* m_buttonColor = nullptr;
|
||||||
CheckBox* m_checkPreview;
|
CheckBox* m_checkPreview = nullptr;
|
||||||
Slider* m_sliderTolerance;
|
Slider* m_sliderTolerance = nullptr;
|
||||||
SelModeField* m_selMode;
|
SelModeField* m_selMode = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
MaskByColorCommand::MaskByColorCommand()
|
MaskByColorCommand::MaskByColorCommand()
|
||||||
@ -91,6 +92,8 @@ bool MaskByColorCommand::onEnabled(Context* context)
|
|||||||
|
|
||||||
void MaskByColorCommand::onExecute(Context* context)
|
void MaskByColorCommand::onExecute(Context* context)
|
||||||
{
|
{
|
||||||
|
ASSERT(!m_window);
|
||||||
|
|
||||||
const ContextReader reader(context);
|
const ContextReader reader(context);
|
||||||
const Sprite* sprite = reader.sprite();
|
const Sprite* sprite = reader.sprite();
|
||||||
|
|
||||||
@ -102,7 +105,8 @@ void MaskByColorCommand::onExecute(Context* context)
|
|||||||
if (!image)
|
if (!image)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_window = new Window(Window::WithTitleBar, "Mask by Color");
|
std::unique_ptr<Window> win(new Window(Window::WithTitleBar, "Mask by Color"));
|
||||||
|
base::ScopedValue<Window*> setWindow(m_window, win.get(), nullptr);
|
||||||
TooltipManager* tooltipManager = new TooltipManager();
|
TooltipManager* tooltipManager = new TooltipManager();
|
||||||
m_window->addChild(tooltipManager);
|
m_window->addChild(tooltipManager);
|
||||||
auto box1 = new Box(VERTICAL);
|
auto box1 = new Box(VERTICAL);
|
||||||
@ -135,7 +139,6 @@ void MaskByColorCommand::onExecute(Context* context)
|
|||||||
button_ok->Click.connect(base::Bind<void>(&Window::closeWindow, m_window, button_ok));
|
button_ok->Click.connect(base::Bind<void>(&Window::closeWindow, m_window, button_ok));
|
||||||
button_cancel->Click.connect(base::Bind<void>(&Window::closeWindow, m_window, button_cancel));
|
button_cancel->Click.connect(base::Bind<void>(&Window::closeWindow, m_window, button_cancel));
|
||||||
|
|
||||||
|
|
||||||
m_buttonColor->Change.connect(base::Bind<void>(&MaskByColorCommand::maskPreview, this, base::Ref(reader)));
|
m_buttonColor->Change.connect(base::Bind<void>(&MaskByColorCommand::maskPreview, this, base::Ref(reader)));
|
||||||
m_sliderTolerance->Change.connect(base::Bind<void>(&MaskByColorCommand::maskPreview, this, base::Ref(reader)));
|
m_sliderTolerance->Change.connect(base::Bind<void>(&MaskByColorCommand::maskPreview, this, base::Ref(reader)));
|
||||||
m_checkPreview->Click.connect(base::Bind<void>(&MaskByColorCommand::maskPreview, this, base::Ref(reader)));
|
m_checkPreview->Click.connect(base::Bind<void>(&MaskByColorCommand::maskPreview, this, base::Ref(reader)));
|
||||||
@ -198,7 +201,6 @@ void MaskByColorCommand::onExecute(Context* context)
|
|||||||
|
|
||||||
// Save window configuration.
|
// Save window configuration.
|
||||||
save_window_pos(m_window, "MaskColor");
|
save_window_pos(m_window, "MaskColor");
|
||||||
delete m_window;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Mask* MaskByColorCommand::generateMask(const Mask& origMask,
|
Mask* MaskByColorCommand::generateMask(const Mask& origMask,
|
||||||
@ -245,7 +247,8 @@ Mask* MaskByColorCommand::generateMask(const Mask& origMask,
|
|||||||
|
|
||||||
void MaskByColorCommand::maskPreview(const ContextReader& reader)
|
void MaskByColorCommand::maskPreview(const ContextReader& reader)
|
||||||
{
|
{
|
||||||
if (m_checkPreview->isSelected()) {
|
ASSERT(m_window);
|
||||||
|
if (m_window && m_checkPreview->isSelected()) {
|
||||||
int xpos, ypos;
|
int xpos, ypos;
|
||||||
const Image* image = reader.image(&xpos, &ypos);
|
const Image* image = reader.image(&xpos, &ypos);
|
||||||
std::unique_ptr<Mask> mask(generateMask(*reader.document()->mask(),
|
std::unique_ptr<Mask> mask(generateMask(*reader.document()->mask(),
|
||||||
|
@ -421,11 +421,10 @@ public:
|
|||||||
|
|
||||||
// Links
|
// Links
|
||||||
locateFile()->Click.connect(base::Bind<void>(&OptionsWindow::onLocateConfigFile, this));
|
locateFile()->Click.connect(base::Bind<void>(&OptionsWindow::onLocateConfigFile, this));
|
||||||
#if _WIN32
|
if (!App::instance()->memoryDumpFilename().empty())
|
||||||
locateCrashFolder()->Click.connect(base::Bind<void>(&OptionsWindow::onLocateCrashFolder, this));
|
locateCrashFolder()->Click.connect(base::Bind<void>(&OptionsWindow::onLocateCrashFolder, this));
|
||||||
#else
|
else
|
||||||
locateCrashFolder()->setVisible(false);
|
locateCrashFolder()->setVisible(false);
|
||||||
#endif
|
|
||||||
|
|
||||||
// Undo preferences
|
// Undo preferences
|
||||||
limitUndo()->Click.connect(base::Bind<void>(&OptionsWindow::onLimitUndoCheck, this));
|
limitUndo()->Click.connect(base::Bind<void>(&OptionsWindow::onLimitUndoCheck, this));
|
||||||
@ -1017,7 +1016,8 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void onLocateCrashFolder() {
|
void onLocateCrashFolder() {
|
||||||
app::launcher::open_folder(base::get_file_path(app::memory_dump_filename()));
|
app::launcher::open_folder(
|
||||||
|
base::get_file_path(App::instance()->memoryDumpFilename()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void onLocateConfigFile() {
|
void onLocateConfigFile() {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2018-2019 Igara Studio S.A.
|
// Copyright (C) 2018-2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -97,15 +97,23 @@ void BackupObserver::onRemoveDocument(Doc* doc)
|
|||||||
std::unique_lock<std::mutex> lock(m_mutex);
|
std::unique_lock<std::mutex> lock(m_mutex);
|
||||||
base::remove_from_container(m_documents, doc);
|
base::remove_from_container(m_documents, doc);
|
||||||
}
|
}
|
||||||
if (m_config->keepEditedSpriteDataFor > 0 &&
|
if (doc->needsBackup() &&
|
||||||
doc->needsBackup() &&
|
// If the document is already fully backed up, we don't need to
|
||||||
|
// add it to the background thread to create its backup
|
||||||
|
!doc->isFullyBackedUp() &&
|
||||||
// If the backup is disabled, we don't need it (e.g. when the
|
// If the backup is disabled, we don't need it (e.g. when the
|
||||||
// document is destroyed from a script with Sprite:close(), the
|
// document is destroyed from a script with Sprite:close(), the
|
||||||
// backup is disabled)
|
// backup is disabled)
|
||||||
!doc->inhibitBackup()) {
|
!doc->inhibitBackup()) {
|
||||||
|
// If m_config->keepEditedSpriteDataFor == 0 we add the document
|
||||||
|
// in m_closedDocs list anyway so we call markAsBackedUp(), and
|
||||||
|
// then it's deleted from ClosedDocs::backgroundThread()
|
||||||
|
|
||||||
|
TRACE("RECO: Adding to CLOSEDOC %p\n", doc);
|
||||||
m_closedDocs.push_back(doc);
|
m_closedDocs.push_back(doc);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
TRACE("RECO: Removing doc %p from session\n", doc);
|
||||||
m_session->removeDocument(doc);
|
m_session->removeDocument(doc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2019 Igara Studio S.A.
|
// Copyright (C) 2019-2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -31,6 +31,7 @@
|
|||||||
#include "base/time.h"
|
#include "base/time.h"
|
||||||
#include "doc/cancel_io.h"
|
#include "doc/cancel_io.h"
|
||||||
#include "fmt/format.h"
|
#include "fmt/format.h"
|
||||||
|
#include "ver/info.h"
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
namespace crash {
|
namespace crash {
|
||||||
@ -170,7 +171,7 @@ void Session::create(base::pid pid)
|
|||||||
std::ofstream verf(FSTREAM_PATH(verFilename()));
|
std::ofstream verf(FSTREAM_PATH(verFilename()));
|
||||||
|
|
||||||
pidf << m_pid;
|
pidf << m_pid;
|
||||||
verf << VERSION;
|
verf << get_app_version();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Session::close()
|
void Session::close()
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2018-2019 Igara Studio S.A.
|
// Copyright (C) 2018-2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -39,6 +39,8 @@
|
|||||||
#include <limits>
|
#include <limits>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
#define DOC_TRACE(...) // TRACEARGS
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
|
|
||||||
using namespace base;
|
using namespace base;
|
||||||
@ -61,10 +63,12 @@ Doc::Doc(Sprite* sprite)
|
|||||||
sprites().add(sprite);
|
sprites().add(sprite);
|
||||||
|
|
||||||
updateOSColorSpace(false);
|
updateOSColorSpace(false);
|
||||||
|
DOC_TRACE("DOC: New", this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Doc::~Doc()
|
Doc::~Doc()
|
||||||
{
|
{
|
||||||
|
DOC_TRACE("DOC: Deleting", this);
|
||||||
removeFromContext();
|
removeFromContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,6 +81,8 @@ void Doc::setContext(Context* ctx)
|
|||||||
|
|
||||||
m_ctx = ctx;
|
m_ctx = ctx;
|
||||||
if (ctx) {
|
if (ctx) {
|
||||||
|
DOC_TRACE("DOC: Removing as fully backed up", this);
|
||||||
|
|
||||||
// Remove the flag that indicates that this doc is fully backed
|
// Remove the flag that indicates that this doc is fully backed
|
||||||
// up, because now we are inside a context, so the user can change
|
// up, because now we are inside a context, so the user can change
|
||||||
// it again and the backup will be outdated.
|
// it again and the backup will be outdated.
|
||||||
@ -263,6 +269,8 @@ void Doc::setInhibitBackup(const bool inhibitBackup)
|
|||||||
|
|
||||||
void Doc::markAsBackedUp()
|
void Doc::markAsBackedUp()
|
||||||
{
|
{
|
||||||
|
DOC_TRACE("DOC: Mark as fully backed up", this);
|
||||||
|
|
||||||
m_flags |= kFullyBackedUp;
|
m_flags |= kFullyBackedUp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
#include "render/dithering.h"
|
#include "render/dithering.h"
|
||||||
#include "render/ordered_dither.h"
|
#include "render/ordered_dither.h"
|
||||||
#include "render/render.h"
|
#include "render/render.h"
|
||||||
|
#include "ver/info.h"
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
@ -1303,8 +1304,8 @@ void DocExporter::createDataFile(const Samples& samples,
|
|||||||
// "meta" property
|
// "meta" property
|
||||||
os << ",\n"
|
os << ",\n"
|
||||||
<< " \"meta\": {\n"
|
<< " \"meta\": {\n"
|
||||||
<< " \"app\": \"" << WEBSITE << "\",\n"
|
<< " \"app\": \"" << get_app_url() << "\",\n"
|
||||||
<< " \"version\": \"" << VERSION << "\",\n";
|
<< " \"version\": \"" << get_app_version() << "\",\n";
|
||||||
|
|
||||||
if (!m_textureFilename.empty())
|
if (!m_textureFilename.empty())
|
||||||
os << " \"image\": \""
|
os << " \"image\": \""
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2018-2019 Igara Studio S.A.
|
// Copyright (C) 2018-2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -27,6 +27,7 @@
|
|||||||
#include "fixmath/fixmath.h"
|
#include "fixmath/fixmath.h"
|
||||||
#include "fmt/format.h"
|
#include "fmt/format.h"
|
||||||
#include "ui/alert.h"
|
#include "ui/alert.h"
|
||||||
|
#include "ver/info.h"
|
||||||
#include "zlib.h"
|
#include "zlib.h"
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
@ -288,7 +289,7 @@ bool AseFormat::onPostLoad(FileOp* fop)
|
|||||||
|
|
||||||
// Forward Compatibility: In 1.1 we convert a file with layer groups
|
// Forward Compatibility: In 1.1 we convert a file with layer groups
|
||||||
// (saved with 1.2) as top level layers
|
// (saved with 1.2) as top level layers
|
||||||
std::string ver = VERSION;
|
std::string ver = get_app_version();
|
||||||
bool flat = (ver[0] == '1' &&
|
bool flat = (ver[0] == '1' &&
|
||||||
ver[1] == '.' &&
|
ver[1] == '.' &&
|
||||||
ver[2] == '1');
|
ver[2] == '1');
|
||||||
@ -305,7 +306,7 @@ bool AseFormat::onPostLoad(FileOp* fop)
|
|||||||
"<<Note: Layers inside groups will be converted to top level layers."
|
"<<Note: Layers inside groups will be converted to top level layers."
|
||||||
"||&Yes||&No",
|
"||&Yes||&No",
|
||||||
base::get_file_name(fop->filename()),
|
base::get_file_name(fop->filename()),
|
||||||
PACKAGE, ver)) != 1) {
|
get_app_name(), ver)) != 1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ase_ungroup_all(group);
|
ase_ungroup_all(group);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2018-2019 Igara Studio S.A.
|
// Copyright (C) 2018-2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -41,6 +41,7 @@
|
|||||||
#include "ui/alert.h"
|
#include "ui/alert.h"
|
||||||
#include "ui/listitem.h"
|
#include "ui/listitem.h"
|
||||||
#include "ui/system.h"
|
#include "ui/system.h"
|
||||||
|
#include "ver/info.h"
|
||||||
|
|
||||||
#include "ask_for_color_profile.xml.h"
|
#include "ask_for_color_profile.xml.h"
|
||||||
#include "open_sequence.xml.h"
|
#include "open_sequence.xml.h"
|
||||||
@ -200,7 +201,7 @@ FileOp* FileOp::createLoadDocumentOperation(Context* context,
|
|||||||
dio::detect_format(filename));
|
dio::detect_format(filename));
|
||||||
if (!fop->m_format ||
|
if (!fop->m_format ||
|
||||||
!fop->m_format->support(FILE_SUPPORT_LOAD)) {
|
!fop->m_format->support(FILE_SUPPORT_LOAD)) {
|
||||||
fop->setError("%s can't load \"%s\" file (\"%s\")\n", PACKAGE,
|
fop->setError("%s can't load \"%s\" file (\"%s\")\n", get_app_name(),
|
||||||
filename.c_str(), base::get_file_extension(filename).c_str());
|
filename.c_str(), base::get_file_extension(filename).c_str());
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
@ -354,7 +355,7 @@ FileOp* FileOp::createSaveDocumentOperation(const Context* context,
|
|||||||
dio::detect_format_by_file_extension(filename));
|
dio::detect_format_by_file_extension(filename));
|
||||||
if (!fop->m_format ||
|
if (!fop->m_format ||
|
||||||
!fop->m_format->support(FILE_SUPPORT_SAVE)) {
|
!fop->m_format->support(FILE_SUPPORT_SAVE)) {
|
||||||
fop->setError("%s can't save \"%s\" file (\"%s\")\n", PACKAGE,
|
fop->setError("%s can't save \"%s\" file (\"%s\")\n", get_app_name(),
|
||||||
filename.c_str(), base::get_file_extension(filename).c_str());
|
filename.c_str(), base::get_file_extension(filename).c_str());
|
||||||
return fop.release();
|
return fop.release();
|
||||||
}
|
}
|
||||||
@ -835,8 +836,9 @@ void FileOp::operate(IFileOpProgress* progress)
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
setError(
|
setError(
|
||||||
"Save operation is not supported in trial version.\n"
|
fmt::format("Save operation is not supported in trial version.\n"
|
||||||
"Go to " WEBSITE_DOWNLOAD " and get the full-version.");
|
"Go to {} and get the full-version.",
|
||||||
|
get_app_download_url()));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2019 Igara Studio S.A.
|
// Copyright (C) 2019-2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -154,6 +154,7 @@ public:
|
|||||||
|
|
||||||
// A more easy PIDLs interface (without using the SH* & IL* routines of W2K)
|
// A more easy PIDLs interface (without using the SH* & IL* routines of W2K)
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
static SFGAOF get_pidl_attrib(FileItem* fileitem, SFGAOF attrib);
|
||||||
static void update_by_pidl(FileItem* fileitem, SFGAOF attrib);
|
static void update_by_pidl(FileItem* fileitem, SFGAOF attrib);
|
||||||
static LPITEMIDLIST concat_pidl(LPITEMIDLIST pidlHead, LPITEMIDLIST pidlTail);
|
static LPITEMIDLIST concat_pidl(LPITEMIDLIST pidlHead, LPITEMIDLIST pidlTail);
|
||||||
static UINT get_pidl_size(LPITEMIDLIST pidl);
|
static UINT get_pidl_size(LPITEMIDLIST pidl);
|
||||||
@ -453,7 +454,7 @@ const FileItemList& FileItem::children()
|
|||||||
IEnumIDList *pEnum = NULL;
|
IEnumIDList *pEnum = NULL;
|
||||||
ULONG c, fetched;
|
ULONG c, fetched;
|
||||||
|
|
||||||
/* get the interface to enumerate subitems */
|
// Get the interface to enumerate subitems
|
||||||
hr = pFolder->EnumObjects(reinterpret_cast<HWND>(os::instance()->defaultDisplay()->nativeHandle()),
|
hr = pFolder->EnumObjects(reinterpret_cast<HWND>(os::instance()->defaultDisplay()->nativeHandle()),
|
||||||
SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &pEnum);
|
SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &pEnum);
|
||||||
|
|
||||||
@ -461,16 +462,16 @@ const FileItemList& FileItem::children()
|
|||||||
LPITEMIDLIST itempidl[256];
|
LPITEMIDLIST itempidl[256];
|
||||||
SFGAOF attribs[256];
|
SFGAOF attribs[256];
|
||||||
|
|
||||||
/* enumerate the items in the folder */
|
// Enumerate the items in the folder
|
||||||
while (pEnum->Next(256, itempidl, &fetched) == S_OK && fetched > 0) {
|
while (pEnum->Next(256, itempidl, &fetched) == S_OK && fetched > 0) {
|
||||||
/* request the SFGAO_FOLDER attribute to know what of the
|
// Request the SFGAO_FOLDER attribute to know what of the
|
||||||
item is a folder */
|
// item is file or a folder
|
||||||
for (c=0; c<fetched; ++c) {
|
for (c=0; c<fetched; ++c) {
|
||||||
attribs[c] = SFGAO_FOLDER;
|
attribs[c] = SFGAO_FOLDER;
|
||||||
pFolder->GetAttributesOf(1, (LPCITEMIDLIST *)itempidl, attribs+c);
|
pFolder->GetAttributesOf(1, (LPCITEMIDLIST *)itempidl, attribs+c);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* generate the FileItems */
|
// Generate the FileItems
|
||||||
for (c=0; c<fetched; ++c) {
|
for (c=0; c<fetched; ++c) {
|
||||||
LPITEMIDLIST fullpidl = concat_pidl(m_fullpidl,
|
LPITEMIDLIST fullpidl = concat_pidl(m_fullpidl,
|
||||||
itempidl[c]);
|
itempidl[c]);
|
||||||
@ -680,6 +681,34 @@ static bool calc_is_folder(std::string filename, SFGAOF attrib)
|
|||||||
&& ((!filename.empty() && (*filename.begin()) != ':') || (filename == MYPC_CSLID));
|
&& ((!filename.empty() && (*filename.begin()) != ':') || (filename == MYPC_CSLID));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SFGAOF get_pidl_attrib(FileItem* fileitem, SFGAOF attrib)
|
||||||
|
{
|
||||||
|
ASSERT(fileitem->m_pidl);
|
||||||
|
ASSERT(fileitem->m_parent);
|
||||||
|
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
IShellFolder* pFolder = nullptr;
|
||||||
|
if (fileitem->m_parent == rootitem)
|
||||||
|
pFolder = shl_idesktop;
|
||||||
|
else {
|
||||||
|
hr = shl_idesktop->BindToObject(fileitem->m_parent->m_fullpidl,
|
||||||
|
nullptr, IID_IShellFolder, (LPVOID*)&pFolder);
|
||||||
|
if (hr != S_OK)
|
||||||
|
pFolder = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pFolder) {
|
||||||
|
SFGAOF attrib2 = SFGAO_FOLDER;
|
||||||
|
hr = pFolder->GetAttributesOf(1, (LPCITEMIDLIST*)&fileitem->m_pidl, &attrib2);
|
||||||
|
if (hr == S_OK)
|
||||||
|
attrib = attrib2;
|
||||||
|
if (pFolder && pFolder != shl_idesktop)
|
||||||
|
pFolder->Release();
|
||||||
|
}
|
||||||
|
return attrib;
|
||||||
|
}
|
||||||
|
|
||||||
// Updates the names of the file-item through its PIDL
|
// Updates the names of the file-item through its PIDL
|
||||||
static void update_by_pidl(FileItem* fileitem, SFGAOF attrib)
|
static void update_by_pidl(FileItem* fileitem, SFGAOF attrib)
|
||||||
{
|
{
|
||||||
@ -693,7 +722,7 @@ static void update_by_pidl(FileItem* fileitem, SFGAOF attrib)
|
|||||||
else {
|
else {
|
||||||
ASSERT(fileitem->m_parent);
|
ASSERT(fileitem->m_parent);
|
||||||
hr = shl_idesktop->BindToObject(fileitem->m_parent->m_fullpidl,
|
hr = shl_idesktop->BindToObject(fileitem->m_parent->m_fullpidl,
|
||||||
NULL, IID_IShellFolder, (LPVOID *)&pFolder);
|
nullptr, IID_IShellFolder, (LPVOID*)&pFolder);
|
||||||
if (hr != S_OK)
|
if (hr != S_OK)
|
||||||
pFolder = NULL;
|
pFolder = NULL;
|
||||||
}
|
}
|
||||||
@ -921,7 +950,7 @@ static FileItem* get_fileitem_by_fullpidl(LPITEMIDLIST fullpidl, bool create_if_
|
|||||||
if (!create_if_not)
|
if (!create_if_not)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
// Check if the pidl exists
|
// Validate if the fullpidl exists.
|
||||||
SFGAOF attrib = SFGAO_FOLDER | SFGAO_VALIDATE;
|
SFGAOF attrib = SFGAO_FOLDER | SFGAO_VALIDATE;
|
||||||
HRESULT hr = shl_idesktop->GetAttributesOf(1, (LPCITEMIDLIST*)&fullpidl, &attrib);
|
HRESULT hr = shl_idesktop->GetAttributesOf(1, (LPCITEMIDLIST*)&fullpidl, &attrib);
|
||||||
if (hr != S_OK)
|
if (hr != S_OK)
|
||||||
@ -939,6 +968,12 @@ static FileItem* get_fileitem_by_fullpidl(LPITEMIDLIST fullpidl, bool create_if_
|
|||||||
fileitem->m_parent = get_fileitem_by_fullpidl(parent_fullpidl, true);
|
fileitem->m_parent = get_fileitem_by_fullpidl(parent_fullpidl, true);
|
||||||
|
|
||||||
free_pidl(parent_fullpidl);
|
free_pidl(parent_fullpidl);
|
||||||
|
|
||||||
|
// Get specific pidl attributes
|
||||||
|
if (fileitem->m_pidl &&
|
||||||
|
fileitem->m_parent) {
|
||||||
|
attrib = get_pidl_attrib(fileitem, attrib);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
update_by_pidl(fileitem, attrib);
|
update_by_pidl(fileitem, attrib);
|
||||||
@ -949,9 +984,7 @@ static FileItem* get_fileitem_by_fullpidl(LPITEMIDLIST fullpidl, bool create_if_
|
|||||||
return fileitem;
|
return fileitem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// Inserts the fileitem in the hash map of items.
|
||||||
* Inserts the @a fileitem in the hash map of items.
|
|
||||||
*/
|
|
||||||
static void put_fileitem(FileItem* fileitem)
|
static void put_fileitem(FileItem* fileitem)
|
||||||
{
|
{
|
||||||
ASSERT(fileitem->m_filename != NOTINITIALIZED);
|
ASSERT(fileitem->m_filename != NOTINITIALIZED);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
|
// Copyright (C) 2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2016 David Capello
|
// Copyright (C) 2001-2016 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -40,17 +41,4 @@ GuiXml::GuiXml()
|
|||||||
m_doc = app::open_xml(rf.filename());
|
m_doc = app::open_xml(rf.filename());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GuiXml::version()
|
|
||||||
{
|
|
||||||
TiXmlHandle handle(m_doc.get());
|
|
||||||
TiXmlElement* xmlKey = handle.FirstChild("gui").ToElement();
|
|
||||||
|
|
||||||
if (xmlKey && xmlKey->Attribute("version")) {
|
|
||||||
const char* guixml_version = xmlKey->Attribute("version");
|
|
||||||
return guixml_version;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace app
|
} // namespace app
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
|
// Copyright (C) 2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2015 David Capello
|
// Copyright (C) 2001-2015 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -32,8 +33,6 @@ namespace app {
|
|||||||
return m_doc->Value();
|
return m_doc->Value();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string version();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GuiXml();
|
GuiXml();
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
|
// Copyright (C) 2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2016 David Capello
|
// Copyright (C) 2001-2016 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -13,6 +14,8 @@
|
|||||||
#include "app/app.h"
|
#include "app/app.h"
|
||||||
#include "app/resource_finder.h"
|
#include "app/resource_finder.h"
|
||||||
#include "base/log.h"
|
#include "base/log.h"
|
||||||
|
#include "fmt/format.h"
|
||||||
|
#include "ver/info.h"
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
|
|
||||||
@ -20,10 +23,14 @@ LoggerModule::LoggerModule(bool createLogInDesktop)
|
|||||||
{
|
{
|
||||||
app::ResourceFinder rf(false);
|
app::ResourceFinder rf(false);
|
||||||
|
|
||||||
if (createLogInDesktop)
|
if (createLogInDesktop) {
|
||||||
rf.includeDesktopDir(PACKAGE "-v" VERSION "-DebugOutput.txt");
|
rf.includeDesktopDir(fmt::format("{}-v{}-DebugOutput.txt",
|
||||||
else
|
get_app_name(),
|
||||||
rf.includeUserDir("aseprite.log");
|
get_app_version()).c_str());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rf.includeUserDir(fmt::format("{}.log", get_app_name()).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
auto filename = rf.defaultFilename();
|
auto filename = rf.defaultFilename();
|
||||||
base::set_log_filename(filename.c_str());
|
base::set_log_filename(filename.c_str());
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2018-2019 Igara Studio S.A.
|
// Copyright (C) 2018-2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -217,18 +217,19 @@ void draw_alpha_slider(os::Surface* s,
|
|||||||
color.getGreen(),
|
color.getGreen(),
|
||||||
color.getBlue(), 255): 0);
|
color.getBlue(), 255): 0);
|
||||||
|
|
||||||
|
os::Paint paint;
|
||||||
for (int x=0; x<rc.w; ++x) {
|
for (int x=0; x<rc.w; ++x) {
|
||||||
const int a = (255 * x / xmax);
|
const int a = (255 * x / xmax);
|
||||||
const doc::color_t c1 = doc::rgba_blender_normal(gridColor1, c, a);
|
const doc::color_t c1 = doc::rgba_blender_normal(gridColor1, c, a);
|
||||||
const doc::color_t c2 = doc::rgba_blender_normal(gridColor2, c, a);
|
const doc::color_t c2 = doc::rgba_blender_normal(gridColor2, c, a);
|
||||||
const int mid = rc.h/2;
|
const int mid = rc.h/2;
|
||||||
const int odd = (x / rc.h) & 1;
|
const int odd = (x / rc.h) & 1;
|
||||||
s->drawVLine(
|
|
||||||
app::color_utils::color_for_ui(app::Color::fromImage(IMAGE_RGB, odd ? c2: c1)),
|
paint.color(app::color_utils::color_for_ui(app::Color::fromImage(IMAGE_RGB, odd ? c2: c1)));
|
||||||
rc.x+x, rc.y, mid);
|
s->drawRect(gfx::Rect(rc.x+x, rc.y, 1, mid), paint);
|
||||||
s->drawVLine(
|
|
||||||
app::color_utils::color_for_ui(app::Color::fromImage(IMAGE_RGB, odd ? c1: c2)),
|
paint.color(app::color_utils::color_for_ui(app::Color::fromImage(IMAGE_RGB, odd ? c1: c2)));
|
||||||
rc.x+x, rc.y+mid, rc.h-mid);
|
s->drawRect(gfx::Rect(rc.x+x, rc.y+mid, 1, rc.h-mid), paint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
|
// Copyright (C) 2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2016 David Capello
|
// Copyright (C) 2001-2016 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -18,6 +19,7 @@
|
|||||||
#include "base/string.h"
|
#include "base/string.h"
|
||||||
#include "net/http_request.h"
|
#include "net/http_request.h"
|
||||||
#include "net/http_response.h"
|
#include "net/http_response.h"
|
||||||
|
#include "ver/info.h"
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
@ -49,7 +51,7 @@ void HttpLoader::threadHttpRequest()
|
|||||||
|
|
||||||
LOG("HTTP: Sending http request to %s\n", m_url.c_str());
|
LOG("HTTP: Sending http request to %s\n", m_url.c_str());
|
||||||
|
|
||||||
std::string dir = base::join_path(base::get_temp_path(), PACKAGE);
|
std::string dir = base::join_path(base::get_temp_path(), get_app_name());
|
||||||
base::make_all_directories(dir);
|
base::make_all_directories(dir);
|
||||||
|
|
||||||
std::string fn = m_url;
|
std::string fn = m_url;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2019 Igara Studio S.A.
|
// Copyright (C) 2019-2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2016 David Capello
|
// Copyright (C) 2001-2016 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -14,6 +14,7 @@
|
|||||||
#include "app/app.h"
|
#include "app/app.h"
|
||||||
#include "base/fs.h"
|
#include "base/fs.h"
|
||||||
#include "base/string.h"
|
#include "base/string.h"
|
||||||
|
#include "ver/info.h"
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
@ -178,7 +179,7 @@ void ResourceFinder::includeUserDir(const char* filename)
|
|||||||
// $HOME/Library/Application Support/Aseprite/filename
|
// $HOME/Library/Application Support/Aseprite/filename
|
||||||
addPath(
|
addPath(
|
||||||
base::join_path(
|
base::join_path(
|
||||||
base::join_path(base::get_lib_app_support_path(), PACKAGE),
|
base::join_path(base::get_lib_app_support_path(), get_app_name()),
|
||||||
filename).c_str());
|
filename).c_str());
|
||||||
|
|
||||||
#else // !__APPLE__
|
#else // !__APPLE__
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
#include "doc/tag.h"
|
#include "doc/tag.h"
|
||||||
#include "render/render.h"
|
#include "render/render.h"
|
||||||
#include "ui/alert.h"
|
#include "ui/alert.h"
|
||||||
|
#include "ver/info.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
@ -490,7 +491,7 @@ int App_get_isUIAvailable(lua_State* L)
|
|||||||
|
|
||||||
int App_get_version(lua_State* L)
|
int App_get_version(lua_State* L)
|
||||||
{
|
{
|
||||||
std::string ver = VERSION;
|
std::string ver = get_app_version();
|
||||||
base::replace_string(ver, "-x64", ""); // Remove "-x64" suffix
|
base::replace_string(ver, "-x64", ""); // Remove "-x64" suffix
|
||||||
push_version(L, base::Version(ver));
|
push_version(L, base::Version(ver));
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
|
// Copyright (C) 2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -14,26 +15,105 @@
|
|||||||
#include "app/console.h"
|
#include "app/console.h"
|
||||||
#include "app/i18n/strings.h"
|
#include "app/i18n/strings.h"
|
||||||
#include "app/resource_finder.h"
|
#include "app/resource_finder.h"
|
||||||
|
#include "app/task.h"
|
||||||
#include "base/bind.h"
|
#include "base/bind.h"
|
||||||
#include "base/fs.h"
|
#include "base/fs.h"
|
||||||
#include "base/launcher.h"
|
#include "base/launcher.h"
|
||||||
|
#include "fmt/format.h"
|
||||||
#include "ui/alert.h"
|
#include "ui/alert.h"
|
||||||
|
#include "ui/system.h"
|
||||||
|
#include "ver/info.h"
|
||||||
|
|
||||||
#include "send_crash.xml.h"
|
#include "send_crash.xml.h"
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
|
|
||||||
|
// static
|
||||||
|
std::string SendCrash::DefaultMemoryDumpFilename()
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
std::string kDefaultCrashName = fmt::format("{}-crash-{}.dmp",
|
||||||
|
get_app_name(),
|
||||||
|
get_app_version());
|
||||||
|
ResourceFinder rf;
|
||||||
|
rf.includeUserDir(kDefaultCrashName.c_str());
|
||||||
|
return rf.getFirstOrCreateDefault();
|
||||||
|
#else
|
||||||
|
return std::string();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
SendCrash::~SendCrash()
|
||||||
|
{
|
||||||
|
if (m_task.running()) {
|
||||||
|
m_task.cancel();
|
||||||
|
m_task.wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SendCrash::search()
|
void SendCrash::search()
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
m_dumpFilename = memory_dump_filename();
|
// On Windows we use one mini-dump to report bugs, then we can open
|
||||||
|
// this .dmp file locally along with the .exe + .pdb to check the
|
||||||
|
// stack trace and detect the cause of the bug.
|
||||||
|
|
||||||
if (base::is_file(m_dumpFilename)) {
|
m_dumpFilename = SendCrash::DefaultMemoryDumpFilename();
|
||||||
App::instance()->showNotification(this);
|
if (!m_dumpFilename.empty() &&
|
||||||
|
base::is_file(m_dumpFilename)) {
|
||||||
|
auto app = App::instance();
|
||||||
|
app->memoryDumpFilename(m_dumpFilename);
|
||||||
|
#ifdef ENABLE_UI
|
||||||
|
app->showNotification(this);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
// On macOS we can show the possibility to send the latest crash
|
||||||
|
// report from ~/Library/Logs/DiagnosticReports which is the
|
||||||
|
// location where crash reports (.crash files) are located.
|
||||||
|
|
||||||
|
m_task.run(
|
||||||
|
[this](base::task_token&){
|
||||||
|
ResourceFinder rf;
|
||||||
|
rf.includeHomeDir("Library/Logs/DiagnosticReports");
|
||||||
|
std::string dir = rf.defaultFilename();
|
||||||
|
if (base::is_directory(dir)) {
|
||||||
|
std::vector<std::string> candidates;
|
||||||
|
int n = std::strlen(get_app_name());
|
||||||
|
for (const auto& fn : base::list_files(dir)) {
|
||||||
|
// Cancel everything
|
||||||
|
if (m_task.canceled())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (base::utf8_icmp(get_app_name(), fn, n) == 0) {
|
||||||
|
candidates.push_back(fn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::sort(candidates.begin(), candidates.end());
|
||||||
|
if (!candidates.empty()) {
|
||||||
|
std::string fn = base::join_path(dir, candidates.back());
|
||||||
|
if (base::is_file(fn)) {
|
||||||
|
ui::execute_from_ui_thread(
|
||||||
|
[this, fn]{
|
||||||
|
m_dumpFilename = fn;
|
||||||
|
if (auto app = App::instance()) {
|
||||||
|
app->memoryDumpFilename(fn);
|
||||||
|
#ifdef ENABLE_UI
|
||||||
|
app->showNotification(this);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_UI
|
||||||
|
|
||||||
std::string SendCrash::notificationText()
|
std::string SendCrash::notificationText()
|
||||||
{
|
{
|
||||||
return "Report last crash";
|
return "Report last crash";
|
||||||
@ -48,15 +128,24 @@ void SendCrash::notificationClick()
|
|||||||
|
|
||||||
app::gen::SendCrash dlg;
|
app::gen::SendCrash dlg;
|
||||||
|
|
||||||
// The current version is a "development" version if the VERSION
|
#if _WIN32
|
||||||
// macro contains the "dev" word.
|
// Only on Windows, if the current version is a development version
|
||||||
bool isDev = (std::string(VERSION).find("dev") != std::string::npos);
|
// (i.e. the get_app_version() contains "-dev"), the .dmp
|
||||||
|
// file is useless for us. This is because we need the .exe + .pdb +
|
||||||
|
// source code used in the compilation process to make some sense of
|
||||||
|
// the .dmp file.
|
||||||
|
|
||||||
|
bool isDev = (std::string(get_app_version()).find("-dev") != std::string::npos);
|
||||||
if (isDev) {
|
if (isDev) {
|
||||||
dlg.official()->setVisible(false);
|
dlg.official()->setVisible(false);
|
||||||
dlg.devFilename()->setText(m_dumpFilename);
|
dlg.devFilename()->setText(m_dumpFilename);
|
||||||
dlg.devFilename()->Click.connect(base::Bind(&SendCrash::onClickDevFilename, this));
|
dlg.devFilename()->Click.connect(base::Bind(&SendCrash::onClickDevFilename, this));
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
#endif // On other platforms the crash file might be useful even in
|
||||||
|
// the "-dev" version (e.g. on macOS it's a text file with
|
||||||
|
// stack traces).
|
||||||
|
{
|
||||||
dlg.dev()->setVisible(false);
|
dlg.dev()->setVisible(false);
|
||||||
dlg.filename()->setText(m_dumpFilename);
|
dlg.filename()->setText(m_dumpFilename);
|
||||||
dlg.filename()->Click.connect(base::Bind(&SendCrash::onClickFilename, this));
|
dlg.filename()->Click.connect(base::Bind(&SendCrash::onClickFilename, this));
|
||||||
@ -84,4 +173,6 @@ void SendCrash::onClickDevFilename()
|
|||||||
base::launcher::open_file(m_dumpFilename);
|
base::launcher::open_file(m_dumpFilename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // ENABLE_UI
|
||||||
|
|
||||||
} // namespace app
|
} // namespace app
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
|
// Copyright (C) 2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -9,22 +10,36 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "app/notification_delegate.h"
|
#include "app/notification_delegate.h"
|
||||||
|
#include "app/task.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
|
|
||||||
class SendCrash : public INotificationDelegate {
|
class SendCrash
|
||||||
|
#ifdef ENABLE_UI
|
||||||
|
: public INotificationDelegate
|
||||||
|
#endif
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
|
static std::string DefaultMemoryDumpFilename();
|
||||||
|
|
||||||
|
~SendCrash();
|
||||||
|
|
||||||
void search();
|
void search();
|
||||||
|
|
||||||
|
#ifdef ENABLE_UI
|
||||||
|
public: // INotificationDelegate impl
|
||||||
virtual std::string notificationText() override;
|
virtual std::string notificationText() override;
|
||||||
virtual void notificationClick() override;
|
virtual void notificationClick() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void onClickFilename();
|
void onClickFilename();
|
||||||
void onClickDevFilename();
|
void onClickDevFilename();
|
||||||
|
#endif // ENABLE_UI
|
||||||
|
|
||||||
|
private:
|
||||||
|
Task m_task;
|
||||||
std::string m_dumpFilename;
|
std::string m_dumpFilename;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
|
// Copyright (C) 2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2016 David Capello
|
// Copyright (C) 2001-2016 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -14,7 +15,9 @@
|
|||||||
|
|
||||||
#include "app/shell.h"
|
#include "app/shell.h"
|
||||||
|
|
||||||
|
#include "fmt/format.h"
|
||||||
#include "script/engine.h"
|
#include "script/engine.h"
|
||||||
|
#include "ver/info.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -31,7 +34,8 @@ Shell::~Shell()
|
|||||||
|
|
||||||
void Shell::run(script::Engine& engine)
|
void Shell::run(script::Engine& engine)
|
||||||
{
|
{
|
||||||
std::cout << "Welcome to " PACKAGE " v" VERSION " Interactive Console" << std::endl;
|
std::cout << fmt::format("Welcome to {} v{} Interactive Console",
|
||||||
|
get_app_name(), get_app_version()) << std::endl;
|
||||||
std::string line;
|
std::string line;
|
||||||
while (std::getline(std::cin, line)) {
|
while (std::getline(std::cin, line)) {
|
||||||
engine.evalCode(line);
|
engine.evalCode(line);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2019 Igara Studio S.A.
|
// Copyright (C) 2019-2020 Igara Studio S.A.
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
// the End-User License Agreement for Aseprite.
|
// the End-User License Agreement for Aseprite.
|
||||||
@ -11,6 +11,7 @@
|
|||||||
#include "app/task.h"
|
#include "app/task.h"
|
||||||
|
|
||||||
#include "base/task.h"
|
#include "base/task.h"
|
||||||
|
#include "base/thread.h"
|
||||||
#include "base/thread_pool.h"
|
#include "base/thread_pool.h"
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
@ -32,4 +33,12 @@ void Task::run(base::task::func_t&& func)
|
|||||||
m_token = &m_task.start(tasks_pool);
|
m_token = &m_task.start(tasks_pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Task::wait()
|
||||||
|
{
|
||||||
|
// TODO wait a condition variable
|
||||||
|
while (!m_task.completed()) {
|
||||||
|
base::this_thread::sleep_for(0.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace app
|
} // namespace app
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2019 Igara Studio S.A.
|
// Copyright (C) 2019-2020 Igara Studio S.A.
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
// the End-User License Agreement for Aseprite.
|
// the End-User License Agreement for Aseprite.
|
||||||
@ -20,6 +20,7 @@ namespace app {
|
|||||||
~Task();
|
~Task();
|
||||||
|
|
||||||
void run(base::task::func_t&& func);
|
void run(base::task::func_t&& func);
|
||||||
|
void wait();
|
||||||
|
|
||||||
// Returns true when the task is completed (whether it was
|
// Returns true when the task is completed (whether it was
|
||||||
// canceled or not)
|
// canceled or not)
|
||||||
@ -27,6 +28,10 @@ namespace app {
|
|||||||
return m_task.completed();
|
return m_task.completed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool running() const {
|
||||||
|
return m_task.running();
|
||||||
|
}
|
||||||
|
|
||||||
bool canceled() const {
|
bool canceled() const {
|
||||||
if (m_token)
|
if (m_token)
|
||||||
return m_token->canceled();
|
return m_token->canceled();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2018 Igara Studio S.A.
|
// Copyright (C) 2018-2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2017 David Capello
|
// Copyright (C) 2001-2017 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -102,6 +102,9 @@ namespace app {
|
|||||||
|
|
||||||
// Called for each point shape.
|
// Called for each point shape.
|
||||||
virtual void prepareForPointShape(ToolLoop* loop, bool firstPoint, int x, int y) { }
|
virtual void prepareForPointShape(ToolLoop* loop, bool firstPoint, int x, int y) { }
|
||||||
|
virtual void prepareVForPointShape(ToolLoop* loop, int y) { }
|
||||||
|
virtual void prepareUForPointShapeWholeScanline(ToolLoop* loop, int x1) { }
|
||||||
|
virtual void prepareUForPointShapeSlicedScanline(ToolLoop* loop, bool leftSlice, int x1) { }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -34,6 +34,9 @@ public:
|
|||||||
virtual void processScanline(int x1, int y, int x2, ToolLoop* loop) = 0;
|
virtual void processScanline(int x1, int y, int x2, ToolLoop* loop) = 0;
|
||||||
virtual void prepareForStrokes(ToolLoop* loop, Strokes& strokes) { }
|
virtual void prepareForStrokes(ToolLoop* loop, Strokes& strokes) { }
|
||||||
virtual void prepareForPointShape(ToolLoop* loop, bool firstPoint, int x, int y) { }
|
virtual void prepareForPointShape(ToolLoop* loop, bool firstPoint, int x, int y) { }
|
||||||
|
virtual void prepareVForPointShape(ToolLoop* loop, int y) { }
|
||||||
|
virtual void prepareUForPointShapeWholeScanline(ToolLoop* loop, int x1) { }
|
||||||
|
virtual void prepareUForPointShapeSlicedScanline(ToolLoop* loop, bool leftSlice, int x1) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::unique_ptr<BaseInkProcessing> InkProcessingPtr;
|
typedef std::unique_ptr<BaseInkProcessing> InkProcessingPtr;
|
||||||
@ -1124,8 +1127,51 @@ public:
|
|||||||
void prepareForPointShape(ToolLoop* loop, bool firstPoint, int x, int y) override {
|
void prepareForPointShape(ToolLoop* loop, bool firstPoint, int x, int y) override {
|
||||||
if ((m_brush->pattern() == BrushPattern::ALIGNED_TO_DST && firstPoint) ||
|
if ((m_brush->pattern() == BrushPattern::ALIGNED_TO_DST && firstPoint) ||
|
||||||
(m_brush->pattern() == BrushPattern::PAINT_BRUSH)) {
|
(m_brush->pattern() == BrushPattern::PAINT_BRUSH)) {
|
||||||
m_u = (m_brush->patternOrigin().x - loop->getCelOrigin().x) % m_width;
|
m_u = ((m_brush->patternOrigin().x % loop->sprite()->width()) - loop->getCelOrigin().x) % m_width;
|
||||||
|
m_v = ((m_brush->patternOrigin().y % loop->sprite()->height()) - loop->getCelOrigin().y) % m_height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void prepareVForPointShape(ToolLoop* loop, int y) override {
|
||||||
|
|
||||||
|
if (m_brush->pattern() == doc::BrushPattern::ALIGNED_TO_SRC) {
|
||||||
m_v = (m_brush->patternOrigin().y - loop->getCelOrigin().y) % m_height;
|
m_v = (m_brush->patternOrigin().y - loop->getCelOrigin().y) % m_height;
|
||||||
|
if (m_v < 0) m_v += m_height;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int spriteH = loop->sprite()->height();
|
||||||
|
if (y/spriteH > 0)
|
||||||
|
// 'y' is outside of the center tile.
|
||||||
|
m_v = (m_brush->patternOrigin().y + m_height - (y/spriteH) * spriteH) % m_height;
|
||||||
|
else
|
||||||
|
// 'y' is inside of the center tile.
|
||||||
|
m_v = ((m_brush->patternOrigin().y % spriteH) - loop->getCelOrigin().y) % m_height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void prepareUForPointShapeWholeScanline(ToolLoop* loop, int x1) override {
|
||||||
|
if (m_brush->pattern() == doc::BrushPattern::ALIGNED_TO_SRC) {
|
||||||
|
m_u = (m_brush->patternOrigin().x - loop->getCelOrigin().x) % m_width;
|
||||||
|
if (m_u < 0) m_u += m_height;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_u = ((m_brush->patternOrigin().x % loop->sprite()->width()) - loop->getCelOrigin().x ) % m_width;
|
||||||
|
if (x1/loop->sprite()->width() > 0)
|
||||||
|
m_u = (m_brush->patternOrigin().x + m_width - (x1/loop->sprite()->width()) * loop->sprite()->width()) % m_width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void prepareUForPointShapeSlicedScanline(ToolLoop* loop, bool leftSlice, int x1) override {
|
||||||
|
if (loop->getBrush()->pattern() == doc::BrushPattern::ALIGNED_TO_SRC) {
|
||||||
|
m_u = (m_brush->patternOrigin().x - loop->getCelOrigin().x) % m_width;
|
||||||
|
if (m_u < 0) m_u += m_height;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (leftSlice)
|
||||||
|
m_u = ((m_brush->patternOrigin().x % loop->sprite()->width()) - loop->getCelOrigin().x ) % m_width;
|
||||||
|
else
|
||||||
|
m_u = (m_brush->patternOrigin().x + m_width - (x1/loop->sprite()->width() + 1) * loop->sprite()->width()) % m_width;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2018-2019 Igara Studio S.A.
|
// Copyright (C) 2018-2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -34,6 +34,21 @@ public:
|
|||||||
m_proc->prepareForPointShape(loop, firstPoint, x, y);
|
m_proc->prepareForPointShape(loop, firstPoint, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void prepareVForPointShape(ToolLoop* loop, int y) override {
|
||||||
|
ASSERT(m_proc);
|
||||||
|
m_proc->prepareVForPointShape(loop, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void prepareUForPointShapeWholeScanline(ToolLoop* loop, int x1) override {
|
||||||
|
ASSERT(m_proc);
|
||||||
|
m_proc->prepareUForPointShapeWholeScanline(loop, x1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void prepareUForPointShapeSlicedScanline(ToolLoop* loop, bool leftSlice, int x1) override {
|
||||||
|
ASSERT(m_proc);
|
||||||
|
m_proc->prepareUForPointShapeSlicedScanline(loop, leftSlice, x1);
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void setProc(BaseInkProcessing* proc) {
|
void setProc(BaseInkProcessing* proc) {
|
||||||
m_proc.reset(proc);
|
m_proc.reset(proc);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
|
// Copyright (C) 2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2015 David Capello
|
// Copyright (C) 2001-2015 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -13,7 +14,9 @@
|
|||||||
#include "app/tools/ink.h"
|
#include "app/tools/ink.h"
|
||||||
#include "app/tools/tool_loop.h"
|
#include "app/tools/tool_loop.h"
|
||||||
#include "app/util/wrap_value.h"
|
#include "app/util/wrap_value.h"
|
||||||
|
#include "doc/brush.h"
|
||||||
#include "doc/image.h"
|
#include "doc/image.h"
|
||||||
|
#include "doc/sprite.h"
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
namespace tools {
|
namespace tools {
|
||||||
@ -53,13 +56,20 @@ void PointShape::doInkHline(int x1, int y, int x2, ToolLoop* loop)
|
|||||||
if (w >= size)
|
if (w >= size)
|
||||||
loop->getInk()->inkHline(0, y, size-1, loop);
|
loop->getInk()->inkHline(0, y, size-1, loop);
|
||||||
else {
|
else {
|
||||||
x = x1;
|
x = wrap_value(x1, loop->sprite()->width());
|
||||||
x = wrap_value(x, size);
|
if (x+w <= loop->sprite()->width()) {
|
||||||
|
// Here we asure that tile limit line does not bisect the current
|
||||||
if (x+w-1 <= size-1)
|
// scanline, i.e. the scanline is enterely contained inside the tile.
|
||||||
|
loop->getInk()->prepareUForPointShapeWholeScanline(loop, x1);
|
||||||
loop->getInk()->inkHline(x, y, x+w-1, loop);
|
loop->getInk()->inkHline(x, y, x+w-1, loop);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
|
// Here the tile limit line bisect the current scanline.
|
||||||
|
// So we need to execute TWO times the inkHline function, each one with a different m_u.
|
||||||
|
loop->getInk()->prepareUForPointShapeSlicedScanline(loop, true, x1);// true = left slice
|
||||||
loop->getInk()->inkHline(x, y, size-1, loop);
|
loop->getInk()->inkHline(x, y, size-1, loop);
|
||||||
|
|
||||||
|
loop->getInk()->prepareUForPointShapeSlicedScanline(loop, false, x1);// false = right slice
|
||||||
loop->getInk()->inkHline(0, y, w-(size-x)-1, loop);
|
loop->getInk()->inkHline(0, y, w-(size-x)-1, loop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2019 Igara Studio S.A.
|
// Copyright (C) 2019-2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2017 David Capello
|
// Copyright (C) 2001-2017 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -7,6 +7,8 @@
|
|||||||
|
|
||||||
#include "app/util/wrap_point.h"
|
#include "app/util/wrap_point.h"
|
||||||
|
|
||||||
|
#include "app/tools/ink.h"
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
namespace tools {
|
namespace tools {
|
||||||
|
|
||||||
@ -67,13 +69,24 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (int(loop->getTiledMode()) & int(TiledMode::X_AXIS)) {
|
||||||
|
int wrappedPatternOriginX = wrap_value(m_brush->patternOrigin().x, loop->sprite()->width()) % m_brush->bounds().w;
|
||||||
|
m_brush->setPatternOrigin(gfx::Point(wrappedPatternOriginX, m_brush->patternOrigin().y));
|
||||||
|
x = wrap_value(x, loop->sprite()->width());
|
||||||
|
}
|
||||||
|
if (int(loop->getTiledMode()) & int(TiledMode::Y_AXIS)) {
|
||||||
|
int wrappedPatternOriginY = wrap_value(m_brush->patternOrigin().y, loop->sprite()->height()) % m_brush->bounds().h;
|
||||||
|
m_brush->setPatternOrigin(gfx::Point(m_brush->patternOrigin().x, wrappedPatternOriginY));
|
||||||
|
y = wrap_value(y, loop->sprite()->height());
|
||||||
|
}
|
||||||
|
|
||||||
loop->getInk()->prepareForPointShape(loop, m_firstPoint, x, y);
|
loop->getInk()->prepareForPointShape(loop, m_firstPoint, x, y);
|
||||||
|
|
||||||
for (auto scanline : *m_compressedImage) {
|
for (auto scanline : *m_compressedImage) {
|
||||||
int u = x+scanline.x;
|
int u = x+scanline.x;
|
||||||
|
loop->getInk()->prepareVForPointShape(loop, y+scanline.y);
|
||||||
doInkHline(u, y+scanline.y, u+scanline.w-1, loop);
|
doInkHline(u, y+scanline.y, u+scanline.w-1, loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_firstPoint = false;
|
m_firstPoint = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2018 Igara Studio S.A.
|
// Copyright (C) 2018-2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2016-2018 David Capello
|
// Copyright (C) 2016-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -113,7 +113,10 @@ public:
|
|||||||
|
|
||||||
auto oldCanvas = m_canvas;
|
auto oldCanvas = m_canvas;
|
||||||
m_canvas = os::instance()->createSurface(w, h, activeCS);
|
m_canvas = os::instance()->createSurface(w, h, activeCS);
|
||||||
m_canvas->fillRect(bgColor, gfx::Rect(0, 0, w, h));
|
os::Paint paint;
|
||||||
|
paint.color(bgColor);
|
||||||
|
paint.style(os::Paint::Fill);
|
||||||
|
m_canvas->drawRect(gfx::Rect(0, 0, w, h), paint);
|
||||||
if (oldCanvas) {
|
if (oldCanvas) {
|
||||||
m_canvas->drawSurface(oldCanvas, 0, 0);
|
m_canvas->drawSurface(oldCanvas, 0, 0);
|
||||||
oldCanvas->dispose();
|
oldCanvas->dispose();
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
|
// Copyright (C) 2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -111,11 +112,12 @@ void ColorSpectrum::onPaintSurfaceInBgThread(
|
|||||||
if (m_paintFlags & BottomBarFlag) {
|
if (m_paintFlags & BottomBarFlag) {
|
||||||
double lit = m_color.getHslLightness();
|
double lit = m_color.getHslLightness();
|
||||||
double hue = m_color.getHslHue();
|
double hue = m_color.getHslHue();
|
||||||
|
os::Paint paint;
|
||||||
for (int x=0; x<bottom.w && !stop; ++x) {
|
for (int x=0; x<bottom.w && !stop; ++x) {
|
||||||
gfx::Color color = color_utils::color_for_ui(
|
paint.color(
|
||||||
app::Color::fromHsl(hue, double(x) / double(bottom.w), lit));
|
color_utils::color_for_ui(
|
||||||
|
app::Color::fromHsl(hue, double(x) / double(bottom.w), lit)));
|
||||||
s->drawVLine(color, bottom.x+x, bottom.y, bottom.h);
|
s->drawRect(gfx::Rect(bottom.x+x, bottom.y, 1, bottom.h), paint);
|
||||||
}
|
}
|
||||||
if (stop)
|
if (stop)
|
||||||
return;
|
return;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
|
// Copyright (C) 2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2016-2018 David Capello
|
// Copyright (C) 2016-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -100,12 +101,14 @@ void ColorTintShadeTone::onPaintSurfaceInBgThread(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_paintFlags & BottomBarFlag) {
|
if (m_paintFlags & BottomBarFlag) {
|
||||||
|
os::Paint paint;
|
||||||
for (int x=0; x<bottom.w && !stop; ++x) {
|
for (int x=0; x<bottom.w && !stop; ++x) {
|
||||||
gfx::Color color = color_utils::color_for_ui(
|
paint.color(
|
||||||
app::Color::fromHsv(
|
color_utils::color_for_ui(
|
||||||
(360.0 * x / bottom.w), 1.0, 1.0));
|
app::Color::fromHsv(
|
||||||
|
(360.0 * x / bottom.w), 1.0, 1.0)));
|
||||||
|
|
||||||
s->drawVLine(color, bottom.x+x, bottom.y, bottom.h);
|
s->drawRect(gfx::Rect(bottom.x+x, bottom.y, 1, bottom.h), paint);
|
||||||
}
|
}
|
||||||
if (stop)
|
if (stop)
|
||||||
return;
|
return;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
|
// Copyright (C) 2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -275,12 +276,13 @@ void ColorWheel::onPaintSurfaceInBgThread(os::Surface* s,
|
|||||||
if (m_paintFlags & BottomBarFlag) {
|
if (m_paintFlags & BottomBarFlag) {
|
||||||
double hue = m_color.getHsvHue();
|
double hue = m_color.getHsvHue();
|
||||||
double sat = m_color.getHsvSaturation();
|
double sat = m_color.getHsvSaturation();
|
||||||
|
os::Paint paint;
|
||||||
for (int x=0; x<bottom.w && !stop; ++x) {
|
for (int x=0; x<bottom.w && !stop; ++x) {
|
||||||
gfx::Color color = color_utils::color_for_ui(
|
paint.color(
|
||||||
app::Color::fromHsv(hue, sat, double(x) / double(bottom.w)));
|
color_utils::color_for_ui(
|
||||||
|
app::Color::fromHsv(hue, sat, double(x) / double(bottom.w))));
|
||||||
|
|
||||||
s->drawVLine(color, bottom.x+x, bottom.y, bottom.h);
|
s->drawRect(gfx::Rect(bottom.x+x, bottom.y, 1, bottom.h), paint);
|
||||||
}
|
}
|
||||||
if (stop)
|
if (stop)
|
||||||
return;
|
return;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2019 Igara Studio S.A.
|
// Copyright (C) 2019-2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2017 David Capello
|
// Copyright (C) 2001-2017 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -40,6 +40,7 @@
|
|||||||
#include "ui/size_hint_event.h"
|
#include "ui/size_hint_event.h"
|
||||||
#include "ui/system.h"
|
#include "ui/system.h"
|
||||||
#include "ui/view.h"
|
#include "ui/view.h"
|
||||||
|
#include "ver/info.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
@ -314,7 +315,7 @@ void DataRecoveryView::fillListWith(const bool crashes)
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string title = session->name();
|
std::string title = session->name();
|
||||||
if (session->version() != VERSION)
|
if (session->version() != get_app_version())
|
||||||
title =
|
title =
|
||||||
fmt::format(Strings::recover_files_incompatible(),
|
fmt::format(Strings::recover_files_incompatible(),
|
||||||
title, session->version());
|
title, session->version());
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
|
// Copyright (C) 2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -18,11 +19,13 @@
|
|||||||
#include "app/app_menus.h"
|
#include "app/app_menus.h"
|
||||||
#include "app/ui/skin/skin_theme.h"
|
#include "app/ui/skin/skin_theme.h"
|
||||||
#include "app/ui/workspace.h"
|
#include "app/ui/workspace.h"
|
||||||
|
#include "fmt/format.h"
|
||||||
#include "ui/entry.h"
|
#include "ui/entry.h"
|
||||||
#include "ui/message.h"
|
#include "ui/message.h"
|
||||||
#include "ui/system.h"
|
#include "ui/system.h"
|
||||||
#include "ui/textbox.h"
|
#include "ui/textbox.h"
|
||||||
#include "ui/view.h"
|
#include "ui/view.h"
|
||||||
|
#include "ver/info.h"
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
|
|
||||||
@ -64,7 +67,8 @@ protected:
|
|||||||
|
|
||||||
DevConsoleView::DevConsoleView()
|
DevConsoleView::DevConsoleView()
|
||||||
: Box(VERTICAL)
|
: Box(VERTICAL)
|
||||||
, m_textBox("Welcome to " PACKAGE " v" VERSION " Console\n(Experimental)", LEFT)
|
, m_textBox(fmt::format("Welcome to {} v{} Console\n(Experimental)",
|
||||||
|
get_app_name(), get_app_version()), LEFT)
|
||||||
, m_label(">")
|
, m_label(">")
|
||||||
, m_entry(new CommmandEntry)
|
, m_entry(new CommmandEntry)
|
||||||
, m_engine(App::instance()->scriptEngine())
|
, m_engine(App::instance()->scriptEngine())
|
||||||
|
@ -394,13 +394,17 @@ void DocView::onAddLayer(DocEvent& ev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO why note move this code to Editor::onBeforeRemoveLayer?
|
||||||
void DocView::onBeforeRemoveLayer(DocEvent& ev)
|
void DocView::onBeforeRemoveLayer(DocEvent& ev)
|
||||||
{
|
{
|
||||||
Sprite* sprite = ev.sprite();
|
Sprite* sprite = ev.sprite();
|
||||||
Layer* layer = ev.layer();
|
Layer* layer = ev.layer();
|
||||||
|
|
||||||
// If the layer that was removed is the selected one
|
// If the layer that was removed is the selected one in the editor,
|
||||||
if (layer == m_editor->layer()) {
|
// or is an ancestor of the selected one.
|
||||||
|
if ((m_editor->layer() == layer) ||
|
||||||
|
(m_editor->layer() &&
|
||||||
|
m_editor->layer()->hasAncestor(layer))) {
|
||||||
LayerGroup* parent = layer->parent();
|
LayerGroup* parent = layer->parent();
|
||||||
Layer* layer_select = NULL;
|
Layer* layer_select = NULL;
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2018 Igara Studio S.A.
|
// Copyright (C) 2018-2020 Igara Studio S.A.
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
// the End-User License Agreement for Aseprite.
|
// the End-User License Agreement for Aseprite.
|
||||||
@ -142,8 +142,10 @@ private:
|
|||||||
|
|
||||||
{
|
{
|
||||||
os::SurfaceLock lock(surface);
|
os::SurfaceLock lock(surface);
|
||||||
surface->fillRect(gfx::rgba(0, 0, 0, 0),
|
os::Paint paint;
|
||||||
gfx::Rect(0, 0, surface->width(), surface->height()));
|
paint.color(gfx::rgba(0, 0, 0, 0));
|
||||||
|
paint.style(os::Paint::Fill);
|
||||||
|
surface->drawRect(gfx::Rect(0, 0, surface->width(), surface->height()), paint);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
ui::Graphics g(surface, 0, 0);
|
ui::Graphics g(surface, 0, 0);
|
||||||
|
@ -716,7 +716,9 @@ void Editor::drawOneSpriteUnclippedRect(ui::Graphics* g, const gfx::Rect& sprite
|
|||||||
// internal state of a SkCanvas or SkBitmap thing is
|
// internal state of a SkCanvas or SkBitmap thing is
|
||||||
// updated after this, because convert_image_to_surface()
|
// updated after this, because convert_image_to_surface()
|
||||||
// will overwrite these pixels anyway.
|
// will overwrite these pixels anyway.
|
||||||
tmp->drawRect(gfx::rgba(0, 0, 0, 255), gfx::Rect(0, 0, 1, 1));
|
os::Paint paint;
|
||||||
|
paint.color(gfx::rgba(0, 0, 0, 255));
|
||||||
|
tmp->drawRect(gfx::Rect(0, 0, 1, 1), paint);
|
||||||
}
|
}
|
||||||
|
|
||||||
convert_image_to_surface(rendered.get(), m_sprite->palette(m_frame),
|
convert_image_to_surface(rendered.get(), m_sprite->palette(m_frame),
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2019 Igara Studio S.A.
|
// Copyright (C) 2019-2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2017-2018 David Capello
|
// Copyright (C) 2017-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -92,6 +92,36 @@ bool MovingSliceState::onMouseMove(Editor* editor, MouseMessage* msg)
|
|||||||
rc.x += delta.x;
|
rc.x += delta.x;
|
||||||
rc.y += delta.y;
|
rc.y += delta.y;
|
||||||
}
|
}
|
||||||
|
// Move/resize 9-slices center
|
||||||
|
else if (m_hit.type() == EditorHit::SliceCenter) {
|
||||||
|
if (m_hit.border() & LEFT) {
|
||||||
|
rc.x += delta.x;
|
||||||
|
rc.w -= delta.x;
|
||||||
|
if (rc.w < 1) {
|
||||||
|
rc.x += rc.w-1;
|
||||||
|
rc.w = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (m_hit.border() & TOP) {
|
||||||
|
rc.y += delta.y;
|
||||||
|
rc.h -= delta.y;
|
||||||
|
if (rc.h < 1) {
|
||||||
|
rc.y += rc.h-1;
|
||||||
|
rc.h = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (m_hit.border() & RIGHT) {
|
||||||
|
rc.w += delta.x;
|
||||||
|
if (rc.w < 1)
|
||||||
|
rc.w = 1;
|
||||||
|
}
|
||||||
|
if (m_hit.border() & BOTTOM) {
|
||||||
|
rc.h += delta.y;
|
||||||
|
if (rc.h < 1)
|
||||||
|
rc.h = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Move/resize bounds
|
||||||
else {
|
else {
|
||||||
if (m_hit.border() & LEFT) {
|
if (m_hit.border() & LEFT) {
|
||||||
rc.x += delta.x * (totalBounds.x2() - rc.x) / totalBounds.w;
|
rc.x += delta.x * (totalBounds.x2() - rc.x) / totalBounds.w;
|
||||||
|
@ -57,6 +57,8 @@
|
|||||||
#include "render/render.h"
|
#include "render/render.h"
|
||||||
#include "ui/ui.h"
|
#include "ui/ui.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
|
|
||||||
using namespace ui;
|
using namespace ui;
|
||||||
@ -601,6 +603,8 @@ public:
|
|||||||
if (!m_editor->selectSliceBox(bounds) &&
|
if (!m_editor->selectSliceBox(bounds) &&
|
||||||
(bounds.w > 1 || bounds.h > 1)) {
|
(bounds.w > 1 || bounds.h > 1)) {
|
||||||
Slice* slice = new Slice;
|
Slice* slice = new Slice;
|
||||||
|
slice->setName(getUniqueSliceName());
|
||||||
|
|
||||||
SliceKey key(bounds);
|
SliceKey key(bounds);
|
||||||
slice->insert(getFrame(), key);
|
slice->insert(getFrame(), key);
|
||||||
|
|
||||||
@ -622,6 +626,21 @@ public:
|
|||||||
m_canceled = true;
|
m_canceled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
#ifdef ENABLE_UI
|
||||||
|
std::string getUniqueSliceName() const {
|
||||||
|
std::string prefix = "Slice";
|
||||||
|
int max = 0;
|
||||||
|
|
||||||
|
for (Slice* slice : m_sprite->slices())
|
||||||
|
if (std::strncmp(slice->name().c_str(), prefix.c_str(), prefix.size()) == 0)
|
||||||
|
max = std::max(max, (int)std::strtol(slice->name().c_str()+prefix.size(), nullptr, 10));
|
||||||
|
|
||||||
|
return fmt::format("{} {}", prefix, max+1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef ENABLE_UI
|
#ifdef ENABLE_UI
|
||||||
|
@ -613,37 +613,34 @@ again:
|
|||||||
}
|
}
|
||||||
// else file-name specified in the entry is really a file to open...
|
// else file-name specified in the entry is really a file to open...
|
||||||
|
|
||||||
// check if the filename doesn't contain slashes or other ilegal characters...
|
|
||||||
bool has_invalid_char = (fn.find('/') != std::string::npos);
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
has_invalid_char =
|
// Check that the filename doesn't contain ilegal characters.
|
||||||
has_invalid_char ||
|
// Linux allows all kind of characters, only '/' is disallowed,
|
||||||
(fn.find('\\') != std::string::npos ||
|
// but in that case we consider that a full path was entered in
|
||||||
fn.find(':') != std::string::npos ||
|
// the filename and we can enter to the full path folder.
|
||||||
fn.find('*') != std::string::npos ||
|
if (!enter_folder) {
|
||||||
fn.find('?') != std::string::npos ||
|
const bool has_invalid_char =
|
||||||
fn.find('\"') != std::string::npos ||
|
(fn.find(':') != std::string::npos ||
|
||||||
fn.find('<') != std::string::npos ||
|
fn.find('*') != std::string::npos ||
|
||||||
fn.find('>') != std::string::npos ||
|
fn.find('?') != std::string::npos ||
|
||||||
fn.find('|') != std::string::npos);
|
fn.find('\"') != std::string::npos ||
|
||||||
#endif
|
fn.find('<') != std::string::npos ||
|
||||||
if (has_invalid_char) {
|
fn.find('>') != std::string::npos ||
|
||||||
const char* invalid_chars =
|
fn.find('|') != std::string::npos);
|
||||||
"/"
|
if (has_invalid_char) {
|
||||||
#ifdef _WIN32
|
const char* invalid_chars = ": * ? \" < > |";
|
||||||
" \\ : * ? \" < > |"
|
|
||||||
#endif
|
|
||||||
;
|
|
||||||
|
|
||||||
ui::Alert::show(
|
ui::Alert::show(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
Strings::alerts_invalid_chars_in_filename(),
|
Strings::alerts_invalid_chars_in_filename(),
|
||||||
invalid_chars));
|
invalid_chars));
|
||||||
|
|
||||||
// show the window again
|
// show the window again
|
||||||
setVisible(true);
|
setVisible(true);
|
||||||
goto again;
|
goto again;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// does it not have extension? ...we should add the extension
|
// does it not have extension? ...we should add the extension
|
||||||
// selected in the filetype combo-box
|
// selected in the filetype combo-box
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2019 Igara Studio S.A.
|
// Copyright (C) 2019-2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -33,6 +33,7 @@
|
|||||||
#include "ui/system.h"
|
#include "ui/system.h"
|
||||||
#include "ui/textbox.h"
|
#include "ui/textbox.h"
|
||||||
#include "ui/view.h"
|
#include "ui/view.h"
|
||||||
|
#include "ver/info.h"
|
||||||
|
|
||||||
#ifdef ENABLE_NEWS
|
#ifdef ENABLE_NEWS
|
||||||
#include "app/ui/news_listbox.h"
|
#include "app/ui/news_listbox.h"
|
||||||
@ -177,7 +178,7 @@ void HomeView::onCheckingUpdates()
|
|||||||
void HomeView::onUpToDate()
|
void HomeView::onUpToDate()
|
||||||
{
|
{
|
||||||
checkUpdate()->setText(
|
checkUpdate()->setText(
|
||||||
fmt::format(Strings::home_view_is_up_to_date(), PACKAGE));
|
fmt::format(Strings::home_view_is_up_to_date(), get_app_name()));
|
||||||
checkUpdate()->setVisible(true);
|
checkUpdate()->setVisible(true);
|
||||||
|
|
||||||
layout();
|
layout();
|
||||||
@ -186,7 +187,8 @@ void HomeView::onUpToDate()
|
|||||||
void HomeView::onNewUpdate(const std::string& url, const std::string& version)
|
void HomeView::onNewUpdate(const std::string& url, const std::string& version)
|
||||||
{
|
{
|
||||||
checkUpdate()->setText(
|
checkUpdate()->setText(
|
||||||
fmt::format(Strings::home_view_new_version_available(), PACKAGE, version));
|
fmt::format(Strings::home_view_new_version_available(),
|
||||||
|
get_app_name(), version));
|
||||||
checkUpdate()->setUrl(url);
|
checkUpdate()->setUrl(url);
|
||||||
checkUpdate()->setVisible(true);
|
checkUpdate()->setVisible(true);
|
||||||
checkUpdate()->InitTheme.connect(
|
checkUpdate()->InitTheme.connect(
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
|
// Copyright (C) 2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2017 David Capello
|
// Copyright (C) 2001-2017 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -23,6 +24,7 @@
|
|||||||
#include "ui/paint_event.h"
|
#include "ui/paint_event.h"
|
||||||
#include "ui/size_hint_event.h"
|
#include "ui/size_hint_event.h"
|
||||||
#include "ui/view.h"
|
#include "ui/view.h"
|
||||||
|
#include "ver/info.h"
|
||||||
|
|
||||||
#include "tinyxml.h"
|
#include "tinyxml.h"
|
||||||
|
|
||||||
@ -209,7 +211,7 @@ void NewsListBox::reload()
|
|||||||
if (view)
|
if (view)
|
||||||
view->updateView();
|
view->updateView();
|
||||||
|
|
||||||
m_loader = new HttpLoader(WEBSITE_NEWS_RSS);
|
m_loader = new HttpLoader(get_app_news_rss_url());
|
||||||
m_timer.start();
|
m_timer.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2018 Igara Studio S.A.
|
// Copyright (C) 2018-2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -100,6 +100,7 @@ public:
|
|||||||
void setPlaying(bool state) {
|
void setPlaying(bool state) {
|
||||||
m_isPlaying = state;
|
m_isPlaying = state;
|
||||||
setupIcons();
|
setupIcons();
|
||||||
|
invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
obs::signal<void()> Popup;
|
obs::signal<void()> Popup;
|
||||||
@ -209,8 +210,7 @@ void PreviewEditorWindow::setPreviewEnabled(bool state)
|
|||||||
|
|
||||||
void PreviewEditorWindow::pressPlayButton()
|
void PreviewEditorWindow::pressPlayButton()
|
||||||
{
|
{
|
||||||
m_playButton->setSelected(
|
m_playButton->setPlaying(!m_playButton->isPlaying());
|
||||||
!m_playButton->isSelected());
|
|
||||||
onPlayClicked();
|
onPlayClicked();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
|
// Copyright (C) 2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2017 David Capello
|
// Copyright (C) 2001-2017 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -51,7 +52,7 @@ FontData::~FontData()
|
|||||||
|
|
||||||
os::Font* FontData::getFont(int size)
|
os::Font* FontData::getFont(int size)
|
||||||
{
|
{
|
||||||
if (m_type == os::FontType::kSpriteSheet)
|
if (m_type == os::FontType::SpriteSheet)
|
||||||
size = 1; // Same size always
|
size = 1; // Same size always
|
||||||
|
|
||||||
// Use cache
|
// Use cache
|
||||||
@ -63,10 +64,10 @@ os::Font* FontData::getFont(int size)
|
|||||||
os::Font* font = nullptr;
|
os::Font* font = nullptr;
|
||||||
|
|
||||||
switch (m_type) {
|
switch (m_type) {
|
||||||
case os::FontType::kSpriteSheet:
|
case os::FontType::SpriteSheet:
|
||||||
font = os::instance()->loadSpriteSheetFont(m_filename.c_str(), size);
|
font = os::instance()->loadSpriteSheetFont(m_filename.c_str(), size);
|
||||||
break;
|
break;
|
||||||
case os::FontType::kTrueType: {
|
case os::FontType::FreeType: {
|
||||||
font = os::instance()->loadTrueTypeFont(m_filename.c_str(), size);
|
font = os::instance()->loadTrueTypeFont(m_filename.c_str(), size);
|
||||||
if (font)
|
if (font)
|
||||||
font->setAntialias(m_antialias);
|
font->setAntialias(m_antialias);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2019 Igara Studio S.A.
|
// Copyright (C) 2019-2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -113,7 +113,7 @@ static FontData* load_font(std::map<std::string, FontData*>& fonts,
|
|||||||
if (type == "spritesheet") {
|
if (type == "spritesheet") {
|
||||||
const char* fileStr = xmlFont->Attribute("file");
|
const char* fileStr = xmlFont->Attribute("file");
|
||||||
if (fileStr) {
|
if (fileStr) {
|
||||||
font.reset(new FontData(os::FontType::kSpriteSheet));
|
font.reset(new FontData(os::FontType::SpriteSheet));
|
||||||
font->setFilename(base::join_path(xmlDir, fileStr));
|
font->setFilename(base::join_path(xmlDir, fileStr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -143,7 +143,7 @@ static FontData* load_font(std::map<std::string, FontData*>& fonts,
|
|||||||
// The filename can be empty if the font was not found, anyway we
|
// The filename can be empty if the font was not found, anyway we
|
||||||
// want to keep the font information (e.g. to use the fallback
|
// want to keep the font information (e.g. to use the fallback
|
||||||
// information of this font).
|
// information of this font).
|
||||||
font.reset(new FontData(os::FontType::kTrueType));
|
font.reset(new FontData(os::FontType::FreeType));
|
||||||
font->setFilename(fontFilename);
|
font->setFilename(fontFilename);
|
||||||
font->setAntialias(antialias);
|
font->setAntialias(antialias);
|
||||||
|
|
||||||
@ -934,7 +934,7 @@ int SkinTheme::getScrollbarSize()
|
|||||||
|
|
||||||
gfx::Size SkinTheme::getEntryCaretSize(Widget* widget)
|
gfx::Size SkinTheme::getEntryCaretSize(Widget* widget)
|
||||||
{
|
{
|
||||||
if (widget->font()->type() == os::FontType::kTrueType)
|
if (widget->font()->type() == os::FontType::FreeType)
|
||||||
return gfx::Size(2*guiscale(), widget->textHeight());
|
return gfx::Size(2*guiscale(), widget->textHeight());
|
||||||
else
|
else
|
||||||
return gfx::Size(2*guiscale(), widget->textHeight()+2*guiscale());
|
return gfx::Size(2*guiscale(), widget->textHeight()+2*guiscale());
|
||||||
@ -986,7 +986,8 @@ public:
|
|||||||
void preProcessChar(const int index,
|
void preProcessChar(const int index,
|
||||||
const int codepoint,
|
const int codepoint,
|
||||||
gfx::Color& fg,
|
gfx::Color& fg,
|
||||||
gfx::Color& bg) override {
|
gfx::Color& bg,
|
||||||
|
const gfx::Rect& charBounds) override {
|
||||||
// Normal text
|
// Normal text
|
||||||
auto& colors = SkinTheme::instance()->colors;
|
auto& colors = SkinTheme::instance()->colors;
|
||||||
bg = ColorNone;
|
bg = ColorNone;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2018-2019 Igara Studio S.A.
|
// Copyright (C) 2018-2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -46,6 +46,7 @@
|
|||||||
#include "os/font.h"
|
#include "os/font.h"
|
||||||
#include "os/surface.h"
|
#include "os/surface.h"
|
||||||
#include "ui/ui.h"
|
#include "ui/ui.h"
|
||||||
|
#include "ver/info.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstdarg>
|
#include <cstdarg>
|
||||||
@ -621,7 +622,7 @@ void StatusBar::showDefaultText()
|
|||||||
}
|
}
|
||||||
else if (App::instance()->mainWindow()->isHomeSelected()) {
|
else if (App::instance()->mainWindow()->isHomeSelected()) {
|
||||||
setStatusText(0, "-- %s %s by David & Gaspar Capello -- Igara Studio --",
|
setStatusText(0, "-- %s %s by David & Gaspar Capello -- Igara Studio --",
|
||||||
PACKAGE, VERSION);
|
get_app_name(), get_app_version());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
clearText();
|
clearText();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2018-2019 Igara Studio S.A.
|
// Copyright (C) 2018-2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2017 David Capello
|
// Copyright (C) 2001-2017 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -936,7 +936,10 @@ void Tabs::createFloatingOverlay(Tab* tab)
|
|||||||
// Fill the surface with pink color
|
// Fill the surface with pink color
|
||||||
{
|
{
|
||||||
os::SurfaceLock lock(surface);
|
os::SurfaceLock lock(surface);
|
||||||
surface->fillRect(gfx::rgba(0, 0, 0, 0), gfx::Rect(0, 0, surface->width(), surface->height()));
|
os::Paint paint;
|
||||||
|
paint.color(gfx::rgba(0, 0, 0, 0));
|
||||||
|
paint.style(os::Paint::Fill);
|
||||||
|
surface->drawRect(gfx::Rect(0, 0, surface->width(), surface->height()), paint);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
Graphics g(surface, 0, 0);
|
Graphics g(surface, 0, 0);
|
||||||
|
2
src/clip
2
src/clip
@ -1 +1 @@
|
|||||||
Subproject commit 04fa07966a4d413f102f9c26cde229f0ef369943
|
Subproject commit 8b026c048d775a2e3139e1059636fc5e65ef45b1
|
21
src/config.h
21
src/config.h
@ -1,15 +1,15 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2018-2019 Igara Studio S.A.
|
// Copyright (C) 2018-2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
// the End-User License Agreement for Aseprite.
|
// the End-User License Agreement for Aseprite.
|
||||||
|
|
||||||
#ifdef __ASE_CONFIG_H
|
#ifdef __ASEPRITE_CONFIG_H
|
||||||
#error You cannot use config.h two times
|
#error You cannot use config.h two times
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define __ASE_CONFIG_H
|
#define __ASEPRITE_CONFIG_H
|
||||||
|
|
||||||
// In MSVC
|
// In MSVC
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
@ -26,21 +26,6 @@
|
|||||||
#pragma warning(disable:4710)
|
#pragma warning(disable:4710)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// General information
|
|
||||||
#define PACKAGE "Aseprite"
|
|
||||||
#define VERSION "1.3-dev"
|
|
||||||
|
|
||||||
#ifdef CUSTOM_WEBSITE_URL
|
|
||||||
#define WEBSITE CUSTOM_WEBSITE_URL // To test web server
|
|
||||||
#else
|
|
||||||
#define WEBSITE "http://www.aseprite.org/"
|
|
||||||
#endif
|
|
||||||
#define WEBSITE_DOWNLOAD WEBSITE "download/"
|
|
||||||
#define WEBSITE_CONTRIBUTORS WEBSITE "contributors/"
|
|
||||||
#define WEBSITE_NEWS_RSS "http://blog.aseprite.org/rss"
|
|
||||||
#define UPDATE_URL WEBSITE "update/?xml=1"
|
|
||||||
#define COPYRIGHT "Copyright (C) 2001-2019 Igara Studio S.A."
|
|
||||||
|
|
||||||
#include "base/base.h"
|
#include "base/base.h"
|
||||||
#include "base/debug.h"
|
#include "base/debug.h"
|
||||||
#include "base/log.h"
|
#include "base/log.h"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// Aseprite Document Library
|
// Aseprite Document Library
|
||||||
// Copyright (c) 2019 Igara Studio S.A.
|
// Copyright (C) 2019-2020 Igara Studio S.A.
|
||||||
// Copyright (c) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This file is released under the terms of the MIT license.
|
// This file is released under the terms of the MIT license.
|
||||||
// Read LICENSE.txt for more information.
|
// Read LICENSE.txt for more information.
|
||||||
@ -179,6 +179,17 @@ bool Layer::isEditableHierarchy() const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Layer::hasAncestor(const Layer* ancestor) const
|
||||||
|
{
|
||||||
|
Layer* it = parent();
|
||||||
|
while (it) {
|
||||||
|
if (it == ancestor)
|
||||||
|
return true;
|
||||||
|
it = it->parent();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Cel* Layer::cel(frame_t frame) const
|
Cel* Layer::cel(frame_t frame) const
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// Aseprite Document Library
|
// Aseprite Document Library
|
||||||
// Copyright (c) 2019 Igara Studio S.A.
|
// Copyright (C) 2019-2020 Igara Studio S.A.
|
||||||
// Copyright (c) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This file is released under the terms of the MIT license.
|
// This file is released under the terms of the MIT license.
|
||||||
// Read LICENSE.txt for more information.
|
// Read LICENSE.txt for more information.
|
||||||
@ -91,6 +91,7 @@ namespace doc {
|
|||||||
|
|
||||||
bool isVisibleHierarchy() const;
|
bool isVisibleHierarchy() const;
|
||||||
bool isEditableHierarchy() const;
|
bool isEditableHierarchy() const;
|
||||||
|
bool hasAncestor(const Layer* ancestor) const;
|
||||||
|
|
||||||
void setBackground(bool state) { switchFlags(LayerFlags::Background, state); }
|
void setBackground(bool state) { switchFlags(LayerFlags::Background, state); }
|
||||||
void setVisible (bool state) { switchFlags(LayerFlags::Visible, state); }
|
void setVisible (bool state) { switchFlags(LayerFlags::Visible, state); }
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2019 Igara Studio S.A.
|
// Copyright (C) 2019-2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2016 David Capello
|
// Copyright (C) 2001-2016 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -59,7 +59,7 @@ int app_main(int argc, char* argv[])
|
|||||||
std::srand(static_cast<unsigned int>(std::time(nullptr)));
|
std::srand(static_cast<unsigned int>(std::time(nullptr)));
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
::CoInitialize(NULL);
|
::CoInitialize(nullptr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -70,11 +70,12 @@ int app_main(int argc, char* argv[])
|
|||||||
os::ScopedHandle<os::System> system(os::create_system());
|
os::ScopedHandle<os::System> system(os::create_system());
|
||||||
app::App app;
|
app::App app;
|
||||||
|
|
||||||
// Change the name of the memory dump file
|
// Change the memory dump filename to save on disk (.dmp
|
||||||
|
// file). Note: Only useful on Windows.
|
||||||
{
|
{
|
||||||
const std::string filename = app::memory_dump_filename();
|
const std::string fn = app::SendCrash::DefaultMemoryDumpFilename();
|
||||||
if (!filename.empty())
|
if (!fn.empty())
|
||||||
memoryDump.setFileName(filename);
|
memoryDump.setFileName(fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
const int code = app.initialize(options);
|
const int code = app.initialize(options);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite UI Library
|
// Aseprite UI Library
|
||||||
// Copyright (C) 2018-2019 Igara Studio S.A.
|
// Copyright (C) 2018-2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This file is released under the terms of the MIT license.
|
// This file is released under the terms of the MIT license.
|
||||||
@ -845,7 +845,9 @@ public:
|
|||||||
|
|
||||||
void preProcessChar(const int index,
|
void preProcessChar(const int index,
|
||||||
const int codepoint,
|
const int codepoint,
|
||||||
gfx::Color& fg, gfx::Color& bg) override {
|
gfx::Color& fg,
|
||||||
|
gfx::Color& bg,
|
||||||
|
const gfx::Rect& charBounds) override {
|
||||||
if (!m_boxes.empty())
|
if (!m_boxes.empty())
|
||||||
m_boxes.back().to = index;
|
m_boxes.back().to = index;
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite UI Library
|
// Aseprite UI Library
|
||||||
// Copyright (C) 2019 Igara Studio S.A.
|
// Copyright (C) 2019-2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This file is released under the terms of the MIT license.
|
// This file is released under the terms of the MIT license.
|
||||||
@ -117,7 +117,9 @@ void Graphics::drawHLine(gfx::Color color, int x, int y, int w)
|
|||||||
dirty(gfx::Rect(m_dx+x, m_dy+y, w, 1));
|
dirty(gfx::Rect(m_dx+x, m_dy+y, w, 1));
|
||||||
|
|
||||||
os::SurfaceLock lock(m_surface);
|
os::SurfaceLock lock(m_surface);
|
||||||
m_surface->drawHLine(color, m_dx+x, m_dy+y, w);
|
os::Paint paint;
|
||||||
|
paint.color(color);
|
||||||
|
m_surface->drawRect(gfx::Rect(m_dx+x, m_dy+y, w, 1), paint);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::drawVLine(gfx::Color color, int x, int y, int h)
|
void Graphics::drawVLine(gfx::Color color, int x, int y, int h)
|
||||||
@ -125,7 +127,9 @@ void Graphics::drawVLine(gfx::Color color, int x, int y, int h)
|
|||||||
dirty(gfx::Rect(m_dx+x, m_dy+y, 1, h));
|
dirty(gfx::Rect(m_dx+x, m_dy+y, 1, h));
|
||||||
|
|
||||||
os::SurfaceLock lock(m_surface);
|
os::SurfaceLock lock(m_surface);
|
||||||
m_surface->drawVLine(color, m_dx+x, m_dy+y, h);
|
os::Paint paint;
|
||||||
|
paint.color(color);
|
||||||
|
m_surface->drawRect(gfx::Rect(m_dx+x, m_dy+y, 1, h), paint);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::drawLine(gfx::Color color, const gfx::Point& _a, const gfx::Point& _b)
|
void Graphics::drawLine(gfx::Color color, const gfx::Point& _a, const gfx::Point& _b)
|
||||||
@ -135,7 +139,9 @@ void Graphics::drawLine(gfx::Color color, const gfx::Point& _a, const gfx::Point
|
|||||||
dirty(gfx::Rect(a, b));
|
dirty(gfx::Rect(a, b));
|
||||||
|
|
||||||
os::SurfaceLock lock(m_surface);
|
os::SurfaceLock lock(m_surface);
|
||||||
m_surface->drawLine(color, a, b);
|
os::Paint paint;
|
||||||
|
paint.color(color);
|
||||||
|
m_surface->drawLine(a, b, paint);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::drawRect(gfx::Color color, const gfx::Rect& rcOrig)
|
void Graphics::drawRect(gfx::Color color, const gfx::Rect& rcOrig)
|
||||||
@ -145,7 +151,10 @@ void Graphics::drawRect(gfx::Color color, const gfx::Rect& rcOrig)
|
|||||||
dirty(rc);
|
dirty(rc);
|
||||||
|
|
||||||
os::SurfaceLock lock(m_surface);
|
os::SurfaceLock lock(m_surface);
|
||||||
m_surface->drawRect(color, rc);
|
os::Paint paint;
|
||||||
|
paint.color(color);
|
||||||
|
paint.style(os::Paint::Stroke);
|
||||||
|
m_surface->drawRect(rc, paint);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::fillRect(gfx::Color color, const gfx::Rect& rcOrig)
|
void Graphics::fillRect(gfx::Color color, const gfx::Rect& rcOrig)
|
||||||
@ -155,7 +164,10 @@ void Graphics::fillRect(gfx::Color color, const gfx::Rect& rcOrig)
|
|||||||
dirty(rc);
|
dirty(rc);
|
||||||
|
|
||||||
os::SurfaceLock lock(m_surface);
|
os::SurfaceLock lock(m_surface);
|
||||||
m_surface->fillRect(color, rc);
|
os::Paint paint;
|
||||||
|
paint.color(color);
|
||||||
|
paint.style(os::Paint::Fill);
|
||||||
|
m_surface->drawRect(rc, paint);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::fillRegion(gfx::Color color, const gfx::Region& rgn)
|
void Graphics::fillRegion(gfx::Color color, const gfx::Region& rgn)
|
||||||
@ -321,7 +333,8 @@ public:
|
|||||||
void preProcessChar(const int index,
|
void preProcessChar(const int index,
|
||||||
const int codepoint,
|
const int codepoint,
|
||||||
gfx::Color& fg,
|
gfx::Color& fg,
|
||||||
gfx::Color& bg) override {
|
gfx::Color& bg,
|
||||||
|
const gfx::Rect& charBounds) override {
|
||||||
if (m_surface) {
|
if (m_surface) {
|
||||||
if (m_mnemonic &&
|
if (m_mnemonic &&
|
||||||
// TODO use ICU library to lower unicode chars
|
// TODO use ICU library to lower unicode chars
|
||||||
@ -344,11 +357,16 @@ public:
|
|||||||
if (!gfx::is_transparent(m_underscoreColor)) {
|
if (!gfx::is_transparent(m_underscoreColor)) {
|
||||||
// TODO underscore height = guiscale() should be configurable from ui::Theme
|
// TODO underscore height = guiscale() should be configurable from ui::Theme
|
||||||
int dy = 0;
|
int dy = 0;
|
||||||
if (m_font->type() == os::FontType::kTrueType) // TODO use other method to locate the underline
|
if (m_font->type() == os::FontType::FreeType) // TODO use other method to locate the underline
|
||||||
dy += guiscale();
|
dy += guiscale();
|
||||||
gfx::Rect underscoreBounds(charBounds.x, charBounds.y+charBounds.h+dy,
|
gfx::Rect underscoreBounds(charBounds.x, charBounds.y+charBounds.h+dy,
|
||||||
charBounds.w, guiscale());
|
charBounds.w, guiscale());
|
||||||
m_surface->fillRect(m_underscoreColor, underscoreBounds);
|
|
||||||
|
os::Paint paint;
|
||||||
|
paint.color(m_underscoreColor);
|
||||||
|
paint.style(os::Paint::Fill);
|
||||||
|
m_surface->drawRect(underscoreBounds, paint);
|
||||||
|
|
||||||
m_bounds |= underscoreBounds;
|
m_bounds |= underscoreBounds;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite UI Library
|
// Aseprite UI Library
|
||||||
// Copyright (C) 2018-2019 Igara Studio S.A.
|
// Copyright (C) 2018-2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This file is released under the terms of the MIT license.
|
// This file is released under the terms of the MIT license.
|
||||||
@ -302,10 +302,11 @@ Widget* Menu::findItemById(const char* id)
|
|||||||
return result;
|
return result;
|
||||||
for (auto child : children()) {
|
for (auto child : children()) {
|
||||||
if (child->type() == kMenuItemWidget) {
|
if (child->type() == kMenuItemWidget) {
|
||||||
result = static_cast<MenuItem*>(child)
|
if (Menu* submenu = static_cast<MenuItem*>(child)->getSubmenu()) {
|
||||||
->getSubmenu()->findItemById(id);
|
result = submenu->findItemById(id);
|
||||||
if (result)
|
if (result)
|
||||||
return result;
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
# ASEPRITE
|
# ASEPRITE
|
||||||
|
# Copyright (C) 2020 Igara Studio S.A.
|
||||||
# Copyright (C) 2001-2017 David Capello
|
# Copyright (C) 2001-2017 David Capello
|
||||||
|
|
||||||
set(UPDATER_LIB_SOURCES
|
set(UPDATER_LIB_SOURCES
|
||||||
@ -16,4 +17,5 @@ add_library(updater-lib ${UPDATER_LIB_SOURCES})
|
|||||||
target_link_libraries(updater-lib
|
target_link_libraries(updater-lib
|
||||||
net-lib
|
net-lib
|
||||||
cfg-lib
|
cfg-lib
|
||||||
|
ver-lib
|
||||||
${TINYXML_LIBRARY})
|
${TINYXML_LIBRARY})
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
|
// Copyright (C) 2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2018 David Capello
|
// Copyright (C) 2001-2018 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -18,6 +19,7 @@
|
|||||||
#include "net/http_response.h"
|
#include "net/http_response.h"
|
||||||
#include "tinyxml.h"
|
#include "tinyxml.h"
|
||||||
#include "updater/user_agent.h"
|
#include "updater/user_agent.h"
|
||||||
|
#include "ver/info.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@ -97,12 +99,7 @@ public:
|
|||||||
|
|
||||||
bool checkNewVersion(const Uuid& uuid, const std::string& extraParams, CheckUpdateDelegate* delegate)
|
bool checkNewVersion(const Uuid& uuid, const std::string& extraParams, CheckUpdateDelegate* delegate)
|
||||||
{
|
{
|
||||||
#ifndef UPDATE_URL
|
std::string url = get_app_update_url();
|
||||||
#define UPDATE_URL ""
|
|
||||||
#pragma message("warning: Define UPDATE_URL macro")
|
|
||||||
#endif
|
|
||||||
|
|
||||||
std::string url = UPDATE_URL;
|
|
||||||
if (!uuid.empty()) {
|
if (!uuid.empty()) {
|
||||||
url += "&uuid=";
|
url += "&uuid=";
|
||||||
url += uuid;
|
url += uuid;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2019 Igara Studio S.A.
|
// Copyright (C) 2019-2020 Igara Studio S.A.
|
||||||
// Copyright (C) 2001-2017 David Capello
|
// Copyright (C) 2001-2017 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
@ -9,6 +9,9 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "updater/user_agent.h"
|
||||||
|
#include "ver/info.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
@ -39,18 +42,7 @@ std::string getUserAgent()
|
|||||||
std::stringstream userAgent;
|
std::stringstream userAgent;
|
||||||
|
|
||||||
// App name and version
|
// App name and version
|
||||||
|
userAgent << get_app_name() << "/" << get_app_version() << " (";
|
||||||
#ifndef PACKAGE
|
|
||||||
#define PACKAGE ""
|
|
||||||
#pragma message("warning: Define PACKAGE macro")
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef VERSION
|
|
||||||
#define VERSION ""
|
|
||||||
#pragma message("warning: Define VERSION macro")
|
|
||||||
#endif
|
|
||||||
|
|
||||||
userAgent << PACKAGE << "/" << VERSION << " (";
|
|
||||||
|
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
|
|
||||||
|
18
src/ver/CMakeLists.txt
Normal file
18
src/ver/CMakeLists.txt
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# ASEPRITE
|
||||||
|
# Copyright (C) 2020 Igara Studio S.A.
|
||||||
|
|
||||||
|
# Version of Aseprite
|
||||||
|
set(VERSION "1.x-dev")
|
||||||
|
|
||||||
|
configure_file(
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/generated_version.h.in"
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/generated_version.h")
|
||||||
|
|
||||||
|
# Custom Aseprite website (for testing server-side)
|
||||||
|
if(NOT "${CUSTOM_WEBSITE_URL}" STREQUAL "")
|
||||||
|
add_definitions(-DCUSTOM_WEBSITE_URL="${CUSTOM_WEBSITE_URL}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_library(ver-lib info.c ${gen_ver_fn})
|
||||||
|
add_dependencies(ver-lib generated_version_h)
|
||||||
|
target_include_directories(ver-lib PRIVATE "${CMAKE_CURRENT_BINARY_DIR}")
|
1
src/ver/generated_version.h.in
Normal file
1
src/ver/generated_version.h.in
Normal file
@ -0,0 +1 @@
|
|||||||
|
#cmakedefine VERSION "@VERSION@"
|
31
src/ver/info.c
Normal file
31
src/ver/info.c
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/* Aseprite
|
||||||
|
Copyright (C) 2020 Igara Studio S.A.
|
||||||
|
|
||||||
|
This program is distributed under the terms of
|
||||||
|
the End-User License Agreement for Aseprite. */
|
||||||
|
|
||||||
|
#include "ver/info.h"
|
||||||
|
#include "generated_version.h" /* It defines the VERSION macro */
|
||||||
|
|
||||||
|
#define PACKAGE "Aseprite"
|
||||||
|
#define COPYRIGHT "Copyright (C) 2001-2020 Igara Studio S.A."
|
||||||
|
|
||||||
|
#ifdef CUSTOM_WEBSITE_URL
|
||||||
|
#define WEBSITE CUSTOM_WEBSITE_URL /* To test web server */
|
||||||
|
#else
|
||||||
|
#define WEBSITE "http://www.aseprite.org/"
|
||||||
|
#endif
|
||||||
|
#define WEBSITE_DOWNLOAD WEBSITE "download/"
|
||||||
|
#define WEBSITE_CONTRIBUTORS WEBSITE "contributors/"
|
||||||
|
#define WEBSITE_NEWS_RSS "http://blog.aseprite.org/rss"
|
||||||
|
#define WEBSITE_UPDATE WEBSITE "update/?xml=1"
|
||||||
|
|
||||||
|
const char* get_app_name() { return PACKAGE; }
|
||||||
|
const char* get_app_version() { return VERSION; }
|
||||||
|
const char* get_app_copyright() { return COPYRIGHT; }
|
||||||
|
|
||||||
|
const char* get_app_url() { return WEBSITE; }
|
||||||
|
const char* get_app_download_url() { return WEBSITE_DOWNLOAD; }
|
||||||
|
const char* get_app_contributors_url() { return WEBSITE_CONTRIBUTORS; }
|
||||||
|
const char* get_app_news_rss_url() { return WEBSITE_NEWS_RSS; }
|
||||||
|
const char* get_app_update_url() { return WEBSITE_UPDATE; }
|
29
src/ver/info.h
Normal file
29
src/ver/info.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/* Aseprite
|
||||||
|
Copyright (C) 2020 Igara Studio S.A.
|
||||||
|
|
||||||
|
This program is distributed under the terms of
|
||||||
|
the End-User License Agreement for Aseprite. */
|
||||||
|
|
||||||
|
#ifndef VER_INFO_H_INCLUDED
|
||||||
|
#define VER_INFO_H_INCLUDED
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const char* get_app_name();
|
||||||
|
const char* get_app_version();
|
||||||
|
const char* get_app_copyright();
|
||||||
|
|
||||||
|
const char* get_app_url();
|
||||||
|
const char* get_app_download_url();
|
||||||
|
const char* get_app_contributors_url();
|
||||||
|
const char* get_app_news_rss_url();
|
||||||
|
const char* get_app_update_url();
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* VER_INFO_H_INCLUDED */
|
2
third_party/libarchive
vendored
2
third_party/libarchive
vendored
@ -1 +1 @@
|
|||||||
Subproject commit ca48183b244c549841c33a2863672b46ed3cbe88
|
Subproject commit e1309af03a4bcea2f0f0bb1f48530f2b794cc8b2
|
Loading…
x
Reference in New Issue
Block a user