mirror of https://github.com/aseprite/aseprite.git
Merge branch 'beta' into isometric-grid
This commit is contained in:
commit
1ac451de03
|
@ -60,6 +60,8 @@ Checks: >
|
|||
-readability-uppercase-literal-suffix
|
||||
WarningsAsErrors: ''
|
||||
CheckOptions:
|
||||
- key: readability-implicit-bool-conversion.AllowIntegerConditions
|
||||
value: true
|
||||
- key: readability-implicit-bool-conversion.AllowPointerConditions
|
||||
value: true
|
||||
- key: misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
name: build-auto
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- '.github/workflows/build-auto.yml'
|
||||
- 'build.sh'
|
||||
- 'laf'
|
||||
jobs:
|
||||
build-auto:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [windows-latest, macos-latest, ubuntu-latest]
|
||||
build_type: [RelWithDebInfo, Debug]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: 'recursive'
|
||||
- name: Install Dependencies
|
||||
if: runner.os == 'Linux'
|
||||
shell: bash
|
||||
run: |
|
||||
sudo apt-get update -qq
|
||||
sudo apt-get install -y \
|
||||
libpixman-1-dev libfreetype6-dev libharfbuzz-dev zlib1g-dev \
|
||||
libx11-dev libxcursor-dev libxi-dev libgl1-mesa-dev libfontconfig1-dev
|
||||
- uses: aseprite/get-ninja@main
|
||||
- uses: ilammy/msvc-dev-cmd@v1
|
||||
if: runner.os == 'Windows'
|
||||
- name: Building
|
||||
shell: bash
|
||||
run: |
|
||||
bash build.sh --auto --norun
|
||||
- name: Running CLI Tests
|
||||
shell: bash
|
||||
run: |
|
||||
if [[ "${{ runner.os }}" == "Linux" ]] ; then
|
||||
export XVFB=xvfb-run
|
||||
fi
|
||||
export ASEPRITE=$PWD/build/bin/aseprite
|
||||
cd tests
|
||||
$XVFB bash run-tests.sh
|
|
@ -34,16 +34,14 @@ jobs:
|
|||
shell: bash
|
||||
run: |
|
||||
if [[ "${{ runner.os }}" == "Windows" ]] ; then
|
||||
choco install wget -y --no-progress
|
||||
wget https://github.com/aseprite/skia/releases/download/m124-08a5439a6b/Skia-Windows-Release-x64.zip
|
||||
unzip Skia-Windows-Release-x64.zip -d skia
|
||||
elif [[ "${{ runner.os }}" == "macOS" ]] ; then
|
||||
wget https://github.com/aseprite/skia/releases/download/m124-08a5439a6b/Skia-macOS-Release-arm64.zip
|
||||
unzip Skia-macOS-Release-arm64.zip -d skia
|
||||
this_dir=$(cygpath "${{ github.workspace }}")
|
||||
else
|
||||
wget https://github.com/aseprite/skia/releases/download/m124-08a5439a6b/Skia-Linux-Release-x64.zip
|
||||
unzip Skia-Linux-Release-x64.zip -d skia
|
||||
this_dir="${{ github.workspace }}"
|
||||
fi
|
||||
skia_url=$(source $this_dir/laf/misc/skia-url.sh | xargs)
|
||||
skia_file=$(basename $skia_url)
|
||||
curl --ssl-revoke-best-effort -L -o "$skia_file" "$skia_url"
|
||||
unzip "$skia_file" -d skia
|
||||
- name: ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2.17
|
||||
if: ${{ runner.os == 'Linux' || runner.os == 'macOS' }}
|
||||
|
|
|
@ -13,6 +13,6 @@ jobs:
|
|||
post-comments:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: ZedThree/clang-tidy-review/post@v0.20.1
|
||||
- uses: ZedThree/clang-tidy-review/post@v0.21.0
|
||||
with:
|
||||
token: ${{ secrets.CLANG_TIDY_TOKEN }}
|
||||
|
|
|
@ -12,7 +12,9 @@
|
|||
*.res
|
||||
.DS_Store
|
||||
.vs
|
||||
.vscode
|
||||
tests/_test*
|
||||
build
|
||||
.build
|
||||
.deps
|
||||
CMakeSettings.json
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
# Credits
|
||||
|
||||
Aseprite is being developed and maintained currently by [Igara Studio](https://igara.com/).
|
||||
The active team of developers is:
|
||||
|
||||
* [David Capello](https://github.com/dacap)
|
||||
* [Gaspar Capello](https://github.com/Gasparoken)
|
||||
* [Martín Capello](https://github.com/martincapello)
|
||||
* [Christian Kaiser](https://github.com/ckaiser)
|
||||
* [Dante Paola](https://github.com/Liebranca)
|
||||
|
||||
Previous team members that contributed with code/docs/scripts/graphics:
|
||||
|
||||
* [Kacper Woźniak](https://github.com/thkwznk)
|
||||
* [Joshua Ogunyinka](https://github.com/iamOgunyinka)
|
||||
* [David Campo](https://github.com/dncampo)
|
||||
|
||||
## Translations
|
||||
|
||||
The translation work of Aseprite is only possible thanks to the
|
||||
contribution, help, and good will of several translators coordinated
|
||||
through our Weblate project:
|
||||
|
||||
* [Translation Credits](strings/README.md)
|
||||
|
||||
## Graphics
|
||||
|
||||
Aseprite logo was created by David Capello. Graphics used as background
|
||||
of [Aseprite home page](https://www.aseprite.org),
|
||||
on [Steam Store](https://store.steampowered.com/app/431730/Aseprite/),
|
||||
and [social media channels](https://bsky.app/profile/aseprite.org),
|
||||
were created by:
|
||||
|
||||
* [Ilija Melentijevic](https://ilkke.net/)
|
||||
|
||||
## Themes
|
||||
|
||||
The default Aseprite font was created by David Capello, and the
|
||||
default Aseprite theme was introduced in v0.8, originally created by:
|
||||
|
||||
* Ilija Melentijevic
|
||||
|
||||
A modified dark version of this theme was introduced in v1.3-beta1, created by:
|
||||
|
||||
* [Nicolas Desilets](https://twitter.com/MapleGecko)
|
||||
|
||||
These themes are now being maintained by Igara Studio and external
|
||||
contributors from time to time.
|
||||
|
||||
## Palettes
|
||||
|
||||
Aseprite includes color palettes created by:
|
||||
|
||||
* [Richard "DawnBringer" Fhager](http://pixeljoint.com/p/23821.htm), [DB16](http://pixeljoint.com/forum/forum_posts.asp?TID=12795), [DB32](http://pixeljoint.com/forum/forum_posts.asp?TID=16247) (default Aseprite color palette)
|
||||
* [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)
|
||||
* [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
|
||||
* [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
|
||||
* [PineTreePizza](https://twitter.com/PineTreePizza), [Rosy-42](https://twitter.com/PineTreePizza/status/1006536191955623938) palette
|
||||
|
||||
## Pixel-art Features
|
||||
|
||||
Aseprite tries to replicate some pixel-art algorithms:
|
||||
|
||||
* [Shading Ink](https://aseprite.org/docs/shading/): created as a simplification of GrafX2 shade mode, thanks to Ilija Melentijevic for introducing me to this feature in 2009
|
||||
* [RotSprite](http://forums.sonicretro.org/index.php?showtopic=8848&st=15&p=159754&#entry159754) by Xenowhirl.
|
||||
* [Pixel perfect drawing algorithm](https://deepnight.net/blog/tools/pixel-perfect-drawing/)
|
||||
by [Sébastien Bénard](https://twitter.com/deepnightfr) and
|
||||
[Carduus](https://twitter.com/CarduusHimself/status/420554200737935361).
|
||||
|
||||
## Community
|
||||
|
||||
A special thanks to @Outlander for helping us moderating our [Discord server](https://discord.gg/Yb2CeX8).
|
||||
Thanks to all the people that hung around for such a long time.
|
||||
|
||||
## Contributors
|
||||
|
||||
Thank you everyone who contributed to Aseprite with ideas, patches,
|
||||
code, bug reports, new features, donations, tutorials, videos,
|
||||
personal messages, chats, emails, tweets, posts, questions, libraries,
|
||||
compilers, and any other tools that made this program possible today.
|
||||
|
||||
* Thanks to all [contributors](https://github.com/aseprite/aseprite/graphs/contributors)
|
||||
* Thanks to all developers and maintainers behind [other open source projects](docs/LICENSES.md) used by Aseprite
|
||||
* Thanks to all early PayPal donors and donors from our Pledgie Campaign (before Aseprite was commercialized)
|
||||
* Thanks to every who support our business model: this source-available / sell-binaries combo
|
||||
* Thanks to schools and [educational institutions](https://aseprite.org/educational)
|
||||
that are using Aseprite in their classrooms <3
|
||||
* Thanks to our family and friends who always support our work
|
||||
|
||||
It's been more years than I can remember, sorry if we missed someone,
|
||||
please drop me a line to [david@igara.com](mailto:david@igara.com) to
|
||||
fix something or say hi. We'll try to keep this updated (for past and
|
||||
future contributors).
|
||||
|
||||
Sincerely, David.
|
|
@ -243,7 +243,13 @@ if(USE_SHARED_LIBPNG)
|
|||
add_definitions(${PNG_DEFINITIONS})
|
||||
else()
|
||||
set(PNG_FOUND ON)
|
||||
set(PNG_LIBRARY png_static)
|
||||
|
||||
# Skia on Linux includes libpng symbols
|
||||
if(UNIX AND NOT APPLE AND LAF_BACKEND STREQUAL "skia")
|
||||
set(PNG_LIBRARY skia)
|
||||
else()
|
||||
set(PNG_LIBRARY png_static)
|
||||
endif()
|
||||
set(PNG_LIBRARIES ${PNG_LIBRARY})
|
||||
set(PNG_INCLUDE_DIRS
|
||||
${LIBPNG_DIR}
|
||||
|
|
61
INSTALL.md
61
INSTALL.md
|
@ -6,7 +6,8 @@
|
|||
* [Windows dependencies](#windows-dependencies)
|
||||
* [macOS dependencies](#macos-dependencies)
|
||||
* [Linux dependencies](#linux-dependencies)
|
||||
* [Compiling](#compiling)
|
||||
* [Automatic Building](#automatic-building)
|
||||
* [Manual Building](#manual-building)
|
||||
* [Windows details](#windows-details)
|
||||
* [MinGW](#mingw)
|
||||
* [macOS details](#macos-details)
|
||||
|
@ -17,11 +18,12 @@
|
|||
# Platforms
|
||||
|
||||
You should be able to compile Aseprite successfully on the following
|
||||
platforms:
|
||||
platforms (older and newer versions might work):
|
||||
|
||||
* Windows 11 + [Visual Studio Community 2022 + Windows 10.0 SDK (the latest version available)](https://imgur.com/a/7zs51IT) (we don't support [MinGW](#mingw))
|
||||
* macOS 13.0.1 Ventura + Xcode 14.1 + macOS 11.3 SDK (older version might work)
|
||||
* Linux Ubuntu Bionic 18.04 + clang 10.0
|
||||
* Windows 11 + [Visual Studio Community 2022 + Windows 11 SDK](https://imgur.com/a/7zs51IT)
|
||||
* *Important*: We don't support [MinGW](#mingw)
|
||||
* macOS 15.2 Sequoia + Xcode 16.3 + macOS 15.4 SDK
|
||||
* Linux Ubuntu Focal Fossa 20.04 + clang 12
|
||||
|
||||
# Get the source code
|
||||
|
||||
|
@ -49,7 +51,7 @@ clone the repository on Windows.
|
|||
|
||||
To compile Aseprite you will need:
|
||||
|
||||
* The latest version of [CMake](https://cmake.org) (3.16 or greater)
|
||||
* The latest version of [CMake](https://cmake.org)
|
||||
* [Ninja](https://ninja-build.org) build system
|
||||
* And a compiled version of the `aseprite-m124` branch of
|
||||
the [Skia library](https://github.com/aseprite/skia#readme).
|
||||
|
@ -59,25 +61,24 @@ To compile Aseprite you will need:
|
|||
|
||||
## Windows dependencies
|
||||
|
||||
* Windows 10/11 (we don't support cross-compiling)
|
||||
* Windows 11 (we don't support cross-compiling)
|
||||
* [Visual Studio Community 2022](https://visualstudio.microsoft.com/downloads/) (we don't support [MinGW](#mingw))
|
||||
* The [Desktop development with C++ item + Windows 10.0.18362.0 SDK](https://imgur.com/a/7zs51IT)
|
||||
from the Visual Studio installer
|
||||
* The [Desktop development with C++ item + Windows 10.0.26100.0 SDK](https://imgur.com/a/7zs51IT)
|
||||
from Visual Studio installer
|
||||
|
||||
## macOS dependencies
|
||||
|
||||
On macOS you will need macOS 11.3 SDK and Xcode 13.1 (older versions
|
||||
might work).
|
||||
On macOS you will need macOS 15.4 SDK and Xcode 16.3 (older versions might work).
|
||||
|
||||
## Linux dependencies
|
||||
|
||||
You will need the following dependencies on Ubuntu/Debian:
|
||||
|
||||
sudo apt-get install -y g++ clang libc++-dev libc++abi-dev cmake ninja-build libx11-dev libxcursor-dev libxi-dev libgl1-mesa-dev libfontconfig1-dev
|
||||
sudo apt-get install -y g++ clang cmake ninja-build libx11-dev libxcursor-dev libxi-dev libgl1-mesa-dev libfontconfig1-dev
|
||||
|
||||
Or use clang-10 packages (or newer) in case that clang in your distribution is older than clang 10.0:
|
||||
Or use clang-12 packages (or newer) in case that clang in your distribution is older than clang 12.0:
|
||||
|
||||
sudo apt-get install -y clang-10 libc++-10-dev libc++abi-10-dev
|
||||
sudo apt-get install -y clang-12
|
||||
|
||||
On Fedora:
|
||||
|
||||
|
@ -85,13 +86,24 @@ On Fedora:
|
|||
|
||||
On Arch:
|
||||
|
||||
sudo pacman -S gcc clang libc++ cmake ninja libx11 libxcursor mesa-libgl fontconfig libwebp
|
||||
sudo pacman -S gcc clang cmake ninja libx11 libxcursor mesa-libgl fontconfig libwebp
|
||||
|
||||
On SUSE:
|
||||
|
||||
sudo zypper install gcc-c++ clang libc++-devel libc++abi-devel cmake ninja libX11-devel libXcursor-devel libXi-devel Mesa-libGL-devel fontconfig-devel
|
||||
sudo zypper install gcc-c++ clang cmake ninja libX11-devel libXcursor-devel libXi-devel Mesa-libGL-devel fontconfig-devel
|
||||
|
||||
# Compiling
|
||||
# Automatic Building
|
||||
|
||||
We offer a new [build script](build.sh) that automates and help you to
|
||||
compile Aseprite following instructions on screen. This will be the
|
||||
preferred method for new users and developers to compile Aseprite.
|
||||
|
||||
After you get [get Aseprite code](#get-the-source-code) and install
|
||||
[its dependencies](#dependencies), you can run [build.cmd](build.cmd)
|
||||
file on Windows double-clicking it, or [build.sh](build.sh) on macOS or
|
||||
Linux running it from the terminal from the same Aseprite folder.
|
||||
|
||||
# Manual Building
|
||||
|
||||
1. [Get Aseprite code](#get-the-source-code), put it in a folder like
|
||||
`C:\aseprite`, and create a `build` directory inside to leave all
|
||||
|
@ -223,7 +235,9 @@ If you have a Retina display, check the following issue:
|
|||
|
||||
## Linux details
|
||||
|
||||
You need to use clang and libc++ to compile Aseprite:
|
||||
You can compile Aseprite with gcc or clang. In case that you are using
|
||||
the [pre-compiled Skia version](https://github.com/aseprite/skia/releases/),
|
||||
you must use libstdc++ to compile Aseprite:
|
||||
|
||||
cd aseprite
|
||||
mkdir build
|
||||
|
@ -232,8 +246,8 @@ You need to use clang and libc++ to compile Aseprite:
|
|||
export CXX=clang++
|
||||
cmake \
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
||||
-DCMAKE_CXX_FLAGS:STRING=-stdlib=libc++ \
|
||||
-DCMAKE_EXE_LINKER_FLAGS:STRING=-stdlib=libc++ \
|
||||
-DCMAKE_CXX_FLAGS:STRING=-stdlib=libstdc++ \
|
||||
-DCMAKE_EXE_LINKER_FLAGS:STRING=-stdlib=libstdc++ \
|
||||
-DLAF_BACKEND=skia \
|
||||
-DSKIA_DIR=$HOME/deps/skia \
|
||||
-DSKIA_LIBRARY_DIR=$HOME/deps/skia/out/Release-x64 \
|
||||
|
@ -245,13 +259,6 @@ You need to use clang and libc++ to compile Aseprite:
|
|||
In this case, `$HOME/deps/skia` is the directory where Skia was
|
||||
compiled or uncompressed.
|
||||
|
||||
### GCC compiler
|
||||
|
||||
In case that you are using the pre-compiled Skia version, you must use
|
||||
the clang compiler and libc++ to compile Aseprite. Only if you compile
|
||||
Skia with GCC, you will be able to compile Aseprite with GCC, and this
|
||||
is not recommended as you will have a performance penalty doing so.
|
||||
|
||||
# Using shared third party libraries
|
||||
|
||||
If you don't want to use the embedded code of third party libraries
|
||||
|
|
41
README.md
41
README.md
|
@ -48,45 +48,14 @@ You can ask for help in:
|
|||
[YouTube](https://www.youtube.com/user/aseprite),
|
||||
[Instagram](https://www.instagram.com/aseprite/).
|
||||
|
||||
## Authors
|
||||
|
||||
Aseprite is being developed by [Igara Studio](https://igara.com/):
|
||||
|
||||
* [David Capello](https://davidcapello.com/)
|
||||
* [Gaspar Capello](https://github.com/Gasparoken)
|
||||
* [Martín Capello](https://github.com/martincapello)
|
||||
|
||||
## Credits
|
||||
|
||||
The default Aseprite theme was introduced in v0.8, created by:
|
||||
Aseprite was originally created by [David Capello](https://davidcapello.com/)
|
||||
and is now being developed and maintained by [Igara Studio](https://igara.com/)
|
||||
and contributors.
|
||||
|
||||
* [Ilija Melentijevic](https://ilkke.net/)
|
||||
|
||||
A modified dark version of this theme introduced in v1.3-beta1 was created by:
|
||||
|
||||
* [Nicolas Desilets](https://twitter.com/MapleGecko)
|
||||
* [David Capello](https://twitter.com/davidcapello)
|
||||
|
||||
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).
|
||||
* [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).
|
||||
* [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.
|
||||
* [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.
|
||||
* [PineTreePizza](https://twitter.com/PineTreePizza), [Rosy-42](https://twitter.com/PineTreePizza/status/1006536191955623938) palette.
|
||||
|
||||
It tries to replicate some pixel-art algorithms:
|
||||
|
||||
* [RotSprite](http://forums.sonicretro.org/index.php?showtopic=8848&st=15&p=159754&#entry159754) by Xenowhirl.
|
||||
* [Pixel perfect drawing algorithm](https://deepnight.net/blog/tools/pixel-perfect-drawing/) by [Sébastien Bénard](https://twitter.com/deepnightfr) and [Carduus](https://twitter.com/CarduusHimself/status/420554200737935361).
|
||||
|
||||
Thanks to [third-party open source projects](docs/LICENSES.md), to
|
||||
[contributors](https://www.aseprite.org/contributors/), and all the
|
||||
people who have contributed ideas, patches, bugs report, feature
|
||||
requests, donations, and help us to develop Aseprite.
|
||||
Check the [AUTHORS](AUTHORS.md) file for details about the active team
|
||||
of developers working on Aseprite.
|
||||
|
||||
## License
|
||||
|
||||
|
|
141
build.sh
141
build.sh
|
@ -56,31 +56,6 @@ if [ "$1" == "--norun" ] ; then
|
|||
norun=1
|
||||
fi
|
||||
|
||||
# Platform.
|
||||
if [[ "$(uname)" =~ "MINGW32" ]] || [[ "$(uname)" =~ "MINGW64" ]] || [[ "$(uname)" =~ "MSYS_NT-10.0" ]] ; then
|
||||
is_win=1
|
||||
cpu=x64
|
||||
|
||||
if ! cl.exe >/dev/null 2>/dev/null ; then
|
||||
echo ""
|
||||
echo "MSVC compiler (cl.exe) not found in PATH"
|
||||
echo ""
|
||||
echo " PATH=$PATH"
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
elif [[ "$(uname)" == "Linux" ]] ; then
|
||||
is_linux=1
|
||||
cpu=x64
|
||||
elif [[ "$(uname)" =~ "Darwin" ]] ; then
|
||||
is_macos=1
|
||||
if [[ $(uname -m) == "arm64" ]]; then
|
||||
cpu=arm64
|
||||
else
|
||||
cpu=x64
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check utilities.
|
||||
if ! cmake --version >/dev/null ; then
|
||||
echo ""
|
||||
|
@ -137,6 +112,23 @@ if [ $run_submodule_update ] ; then
|
|||
echo "Done"
|
||||
fi
|
||||
|
||||
# Platform.
|
||||
if ! source "$pwd/laf/misc/platform.sh" ; then
|
||||
exit $?
|
||||
fi
|
||||
|
||||
if [ $is_win ] ; then
|
||||
# Check MSVC compiler.
|
||||
if ! cl.exe >/dev/null 2>/dev/null ; then
|
||||
echo ""
|
||||
echo "MSVC compiler (cl.exe) not found in PATH"
|
||||
echo ""
|
||||
echo " PATH=$PATH"
|
||||
echo ""
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Create the directory to store the configuration.
|
||||
if [ ! -d "$pwd/.build" ] ; then
|
||||
mkdir "$pwd/.build"
|
||||
|
@ -150,25 +142,25 @@ if [ ! -f "$pwd/.build/userkind" ] ; then
|
|||
echo "user" > $pwd/.build/userkind
|
||||
else
|
||||
echo ""
|
||||
echo "Select what kind of user you are (press U or D keys):"
|
||||
echo "Select what kind of user you are (press U or D key and then Enter):"
|
||||
echo ""
|
||||
echo " [U]ser: give a try to Aseprite"
|
||||
echo " [D]eveloper: develop/modify Aseprite"
|
||||
echo ""
|
||||
read -sN 1 -p "[U/D]? "
|
||||
echo ""
|
||||
if [[ "$REPLY" == "d" || "$REPLY" == "D" ]] ; then
|
||||
read -p "[U/D]? "
|
||||
REPLY=$(echo $REPLY | tr '[:upper:]' '[:lower:]')
|
||||
if [[ "$REPLY" == "d" || "$REPLY" == "dev" || "$REPLY" == "developer" ]] ; then
|
||||
echo "developer" > $pwd/.build/userkind
|
||||
elif [[ "$REPLY" == "u" || "$REPLY" == "U" ]] ; then
|
||||
elif [[ "$REPLY" == "u" || "$REPLY" == "user" ]] ; then
|
||||
echo "user" > $pwd/.build/userkind
|
||||
else
|
||||
echo "Use U or D keys to select kind of user/build process"
|
||||
echo "Use U or D keys (and press Enter) to select kind of user/build process"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
userkind=$(echo -n $(cat $pwd/.build/userkind))
|
||||
userkind=$(cat $pwd/.build/userkind)
|
||||
if [ "$userkind" == "developer" ] ; then
|
||||
echo "======================= BUILDING FOR DEVELOPER ======================="
|
||||
else
|
||||
|
@ -229,7 +221,7 @@ if [ ! -f "$pwd/.build/builds_dir" ] ; then
|
|||
echo "$builds_dir" > "$pwd/.build/builds_dir"
|
||||
fi
|
||||
# Overwrite $builds_dir variable from the config content.
|
||||
builds_dir="$(echo -n $(cat $pwd/.build/builds_dir))"
|
||||
builds_dir="$(cat $pwd/.build/builds_dir)"
|
||||
|
||||
# List all builds.
|
||||
builds_list="$(mktemp)"
|
||||
|
@ -265,7 +257,8 @@ else
|
|||
# New build
|
||||
if [[ "$build_n" == "n" || "$build_n" == "N" ]] ; then
|
||||
read -p "Select build type [RELEASE/debug]? "
|
||||
if [[ "${REPLY,,}" == "debug" ]] ; then
|
||||
REPLY=$(echo $REPLY | tr '[:upper:]' '[:lower:]')
|
||||
if [[ "${REPLY}" == "debug" ]] ; then
|
||||
build_type=Debug
|
||||
new_build_name=aseprite-debug
|
||||
else
|
||||
|
@ -348,10 +341,7 @@ else
|
|||
elif git --git-dir="$source_dir/.git" branch --contains "$remote/main" | grep -q "^\* $branch_name\$" ; then
|
||||
base_branch_name=main
|
||||
else
|
||||
echo ""
|
||||
echo "Error: Branch $branch_name looks like doesn't belong to main or beta"
|
||||
echo ""
|
||||
exit 1
|
||||
base_branch_name=$branch_name
|
||||
fi
|
||||
fi
|
||||
|
||||
|
@ -366,15 +356,9 @@ else
|
|||
fi
|
||||
|
||||
# Required Skia for the base branch.
|
||||
if [ "$base_branch_name" == "beta" ] ; then
|
||||
skia_tag=m124-08a5439a6b
|
||||
file_skia_dir=beta_skia_dir
|
||||
possible_skia_dir_name=skia-m124
|
||||
else
|
||||
skia_tag=m102-861e4743af
|
||||
file_skia_dir=main_skia_dir
|
||||
possible_skia_dir_name=skia
|
||||
fi
|
||||
skia_tag=$(cat "$pwd/laf/misc/skia-tag.txt")
|
||||
possible_skia_dir_name=skia-$(echo $skia_tag | cut -d "-" -f 1)
|
||||
file_skia_dir="$base_branch_name"_skia_dir
|
||||
|
||||
# Check Skia dependency.
|
||||
if [ ! -f "$pwd/.build/$file_skia_dir" ] ; then
|
||||
|
@ -385,23 +369,33 @@ if [ ! -f "$pwd/.build/$file_skia_dir" ] ; then
|
|||
skia_dir="$HOME/deps/$possible_skia_dir_name"
|
||||
fi
|
||||
|
||||
# Set default location if not found
|
||||
if [ ! -d "$skia_dir" ] ; then
|
||||
echo ""
|
||||
echo "Skia directory wasn't found."
|
||||
echo ""
|
||||
|
||||
echo "Select Skia directory to create [$skia_dir]? "
|
||||
if [ ! $auto ] ; then
|
||||
read skia_dir_read
|
||||
if [ "$skia_dir_read" != "" ] ; then
|
||||
skia_dir="$skia_dir_read"
|
||||
fi
|
||||
# Use .deps directory to download Skia for users (which is a
|
||||
# simple setup). In case of developers we'd prefer the shared
|
||||
# directory by default.
|
||||
if [ "$userkind" == "user" ] ; then
|
||||
skia_dir="$pwd/.deps/$possible_skia_dir_name"
|
||||
fi
|
||||
|
||||
if [ ! -d "$skia_dir" ] ; then
|
||||
echo ""
|
||||
echo "Skia directory wasn't found."
|
||||
echo ""
|
||||
|
||||
echo "Select Skia directory to create [$skia_dir]? "
|
||||
if [ ! $auto ] ; then
|
||||
read skia_dir_read
|
||||
if [ "$skia_dir_read" != "" ] ; then
|
||||
skia_dir="$skia_dir_read"
|
||||
fi
|
||||
fi
|
||||
mkdir -p $skia_dir || exit 1
|
||||
fi
|
||||
mkdir -p $skia_dir || exit 1
|
||||
fi
|
||||
echo $skia_dir > "$pwd/.build/$file_skia_dir"
|
||||
fi
|
||||
skia_dir=$(echo -n $(cat $pwd/.build/$file_skia_dir))
|
||||
skia_dir=$(cat $pwd/.build/$file_skia_dir)
|
||||
if [ ! -d "$skia_dir" ] ; then
|
||||
mkdir "$skia_dir"
|
||||
fi
|
||||
|
@ -421,27 +415,30 @@ if [ ! -d "$skia_library_dir" ] ; then
|
|||
echo "Skia library wasn't found."
|
||||
echo ""
|
||||
if [ ! $auto ] ; then
|
||||
read -sN 1 -p "Download pre-compiled Skia automatically [Y/n]? "
|
||||
read -p "Download pre-compiled Skia automatically [Y/n]? "
|
||||
# Convert the Enter key as the default option: an empty string
|
||||
REPLY=$(echo $REPLY | tr '[:upper:]' '[:lower:]')
|
||||
fi
|
||||
if [[ $auto || "$REPLY" == "" || "$REPLY" == "y" || "$REPLY" == "Y" ]] ; then
|
||||
if [[ $auto || "$REPLY" == "" || "$REPLY" == "y" || "$REPLY" == "yes" ]] ; then
|
||||
if [[ $is_win && "$build_type" == "Debug" ]] ; then
|
||||
skia_build=Debug
|
||||
else
|
||||
skia_build=Release
|
||||
fi
|
||||
|
||||
if [ $is_win ] ; then
|
||||
skia_file=Skia-Windows-$skia_build-$cpu.zip
|
||||
elif [ $is_macos ] ; then
|
||||
skia_file=Skia-macOS-$skia_build-$cpu.zip
|
||||
else
|
||||
skia_file=Skia-Linux-$skia_build-$cpu-libstdc++.zip
|
||||
fi
|
||||
skia_url=https://github.com/aseprite/skia/releases/download/$skia_tag/$skia_file
|
||||
skia_url=$(bash laf/misc/skia-url.sh $skia_build)
|
||||
skia_file=$(basename $skia_url)
|
||||
if [ ! -f "$skia_dir/$skia_file" ] ; then
|
||||
curl -L -o "$skia_dir/$skia_file" "$skia_url"
|
||||
if ! command -v curl >/dev/null 2>&1 ; then
|
||||
echo "Error: 'curl' command line tool is not available in PATH"
|
||||
exit 1
|
||||
fi
|
||||
curl --ssl-revoke-best-effort -L -o "$skia_dir/$skia_file" "$skia_url"
|
||||
fi
|
||||
if [ ! -d "$skia_library_dir" ] ; then
|
||||
if ! command -v unzip >/dev/null 2>&1 ; then
|
||||
echo "Error: 'unzip' command line tool is not available in PATH"
|
||||
exit 1
|
||||
fi
|
||||
unzip -n -d "$skia_dir" "$skia_dir/$skia_file"
|
||||
fi
|
||||
else
|
||||
|
@ -468,7 +465,7 @@ if [ ! -f "$active_build_dir/ninja.build" ] ; then
|
|||
echo "This will take some minutes."
|
||||
echo ""
|
||||
if [ ! $auto ] ; then
|
||||
read -sN 1 -p "Press any key to continue. "
|
||||
read -p "Press Enter to continue."
|
||||
fi
|
||||
|
||||
if [ $is_macos ] ; then
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
@ -216,7 +216,7 @@
|
|||
<part id="tab_normal" x="2" y="112" w1="4" w2="5" w3="5" h1="4" h2="6" h3="2" />
|
||||
<part id="tab_active" x="16" y="112" w1="4" w2="7" w3="5" h1="4" h2="6" h3="2" />
|
||||
<part id="tab_bottom_active" x="16" y="124" w1="4" w2="7" w3="5" h1="2" h2="1" h3="2" />
|
||||
<part id="tab_bottom_normal" x="2" y="124" w="12" h="5" />
|
||||
<part id="tab_bottom_normal" x="2" y="124" w1="4" w2="5" w3="3" h1="2" h2="1" h3="2" />
|
||||
<part id="tab_filler" x="0" y="112" w="2" h="12" />
|
||||
<part id="tab_modified_icon_normal" x="32" y="112" w="5" h="5" />
|
||||
<part id="tab_modified_icon_active" x="32" y="117" w="5" h="5" />
|
||||
|
@ -374,6 +374,7 @@
|
|||
<part id="icon_close" x="152" y="256" w="7" h="7" />
|
||||
<part id="icon_search" x="160" y="256" w="8" h="8" />
|
||||
<part id="icon_user_data" x="168" y="256" w="8" h="8" />
|
||||
<part id="icon_layout" x="176" y="256" w="5" h="6" />
|
||||
<part id="icon_pos" x="144" y="264" w="8" h="8" />
|
||||
<part id="icon_size" x="152" y="264" w="8" h="8" />
|
||||
<part id="icon_selsize" x="160" y="264" w="8" h="8" />
|
||||
|
@ -485,25 +486,25 @@
|
|||
<icon part="window_close_icon" color="button_hot_text" state="mouse" />
|
||||
<icon part="window_close_icon" color="button_selected_text" state="selected" />
|
||||
</style>
|
||||
<style id="window_center_button" extends="window_button" margin-top="3" margin-right="2">
|
||||
<style id="window_center_button" extends="window_button" margin-top="3" margin-right="1">
|
||||
<newlayer />
|
||||
<icon part="window_center_icon" color="button_normal_text" />
|
||||
<icon part="window_center_icon" color="button_hot_text" state="mouse" />
|
||||
<icon part="window_center_icon" color="button_selected_text" state="selected" />
|
||||
</style>
|
||||
<style id="window_play_button" extends="window_button" margin-top="3" margin-right="2">
|
||||
<style id="window_play_button" extends="window_button" margin-top="3" margin-right="1">
|
||||
<newlayer />
|
||||
<icon part="window_play_icon" color="button_normal_text" />
|
||||
<icon part="window_play_icon" color="button_hot_text" state="mouse" />
|
||||
<icon part="window_play_icon" color="button_selected_text" state="selected" />
|
||||
</style>
|
||||
<style id="window_stop_button" extends="window_button" margin-top="3" margin-right="2">
|
||||
<style id="window_stop_button" extends="window_button" margin-top="3" margin-right="1">
|
||||
<newlayer />
|
||||
<icon part="window_stop_icon" color="button_normal_text" />
|
||||
<icon part="window_stop_icon" color="button_hot_text" state="mouse" />
|
||||
<icon part="window_stop_icon" color="button_selected_text" state="selected" />
|
||||
</style>
|
||||
<style id="window_help_button" extends="window_button" margin-top="3" margin-right="2">
|
||||
<style id="window_help_button" extends="window_button" margin-top="3" margin-right="1">
|
||||
<newlayer />
|
||||
<icon part="window_help_icon" color="button_normal_text" />
|
||||
<icon part="window_help_icon" color="button_hot_text" state="mouse" />
|
||||
|
@ -550,10 +551,13 @@
|
|||
<text color="disabled" align="left" state="disabled" />
|
||||
</style>
|
||||
<style id="mini_label" extends="label" font="mini" />
|
||||
<style id="warning_label" extends="label">
|
||||
<icon part="warning_box" align="right" />
|
||||
</style>
|
||||
<style id="list_header_label" padding="2">
|
||||
<text color="text" align="left" x="2" />
|
||||
</style>
|
||||
<style id="link">
|
||||
<style id="link" padding="1">
|
||||
<text color="link_text" align="left" />
|
||||
<text color="link_hover" align="left" state="mouse" />
|
||||
</style>
|
||||
|
@ -706,10 +710,11 @@
|
|||
<style id="workspace_splitter">
|
||||
<background color="workspace" />
|
||||
</style>
|
||||
<style id="horizontal_separator" border-left="2" border-top="4" border-right="2" border-bottom="0">
|
||||
<style id="horizontal_separator" border="2">
|
||||
<background color="window_face" />
|
||||
<background-border part="separator_horz" align="middle" />
|
||||
<text color="separator_label" x="4" align="left middle" />
|
||||
<text color="disabled" x="4" align="left middle" state="disabled"/>
|
||||
</style>
|
||||
<style id="menu_separator" extends="horizontal_separator" />
|
||||
<style id="separator_in_view" extends="horizontal_separator">
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
@ -212,7 +212,7 @@
|
|||
<part id="tab_normal" x="2" y="112" w1="4" w2="5" w3="5" h1="4" h2="6" h3="2" />
|
||||
<part id="tab_active" x="16" y="112" w1="4" w2="7" w3="5" h1="4" h2="6" h3="2" />
|
||||
<part id="tab_bottom_active" x="16" y="124" w1="4" w2="7" w3="5" h1="2" h2="1" h3="2" />
|
||||
<part id="tab_bottom_normal" x="2" y="124" w="12" h="5" />
|
||||
<part id="tab_bottom_normal" x="2" y="124" w1="4" w2="5" w3="3" h1="2" h2="1" h3="2" />
|
||||
<part id="tab_filler" x="0" y="112" w="2" h="12" />
|
||||
<part id="tab_modified_icon_normal" x="32" y="112" w="5" h="5" />
|
||||
<part id="tab_modified_icon_active" x="32" y="117" w="5" h="5" />
|
||||
|
@ -370,6 +370,7 @@
|
|||
<part id="icon_close" x="152" y="256" w="7" h="7" />
|
||||
<part id="icon_search" x="160" y="256" w="8" h="8" />
|
||||
<part id="icon_user_data" x="168" y="256" w="8" h="8" />
|
||||
<part id="icon_layout" x="176" y="256" w="5" h="6" />
|
||||
<part id="icon_pos" x="144" y="264" w="8" h="8" />
|
||||
<part id="icon_size" x="152" y="264" w="8" h="8" />
|
||||
<part id="icon_selsize" x="160" y="264" w="8" h="8" />
|
||||
|
@ -481,25 +482,25 @@
|
|||
<icon part="window_close_icon" color="button_hot_text" state="mouse" />
|
||||
<icon part="window_close_icon" color="button_selected_text" state="selected" />
|
||||
</style>
|
||||
<style id="window_center_button" extends="window_button" margin-top="3" margin-right="2">
|
||||
<style id="window_center_button" extends="window_button" margin-top="3" margin-right="1">
|
||||
<newlayer />
|
||||
<icon part="window_center_icon" color="button_normal_text" />
|
||||
<icon part="window_center_icon" color="button_hot_text" state="mouse" />
|
||||
<icon part="window_center_icon" color="button_selected_text" state="selected" />
|
||||
</style>
|
||||
<style id="window_play_button" extends="window_button" margin-top="3" margin-right="2">
|
||||
<style id="window_play_button" extends="window_button" margin-top="3" margin-right="1">
|
||||
<newlayer />
|
||||
<icon part="window_play_icon" color="button_normal_text" />
|
||||
<icon part="window_play_icon" color="button_hot_text" state="mouse" />
|
||||
<icon part="window_play_icon" color="button_selected_text" state="selected" />
|
||||
</style>
|
||||
<style id="window_stop_button" extends="window_button" margin-top="3" margin-right="2">
|
||||
<style id="window_stop_button" extends="window_button" margin-top="3" margin-right="1">
|
||||
<newlayer />
|
||||
<icon part="window_stop_icon" color="button_normal_text" />
|
||||
<icon part="window_stop_icon" color="button_hot_text" state="mouse" />
|
||||
<icon part="window_stop_icon" color="button_selected_text" state="selected" />
|
||||
</style>
|
||||
<style id="window_help_button" extends="window_button" margin-top="3" margin-right="2">
|
||||
<style id="window_help_button" extends="window_button" margin-top="3" margin-right="1">
|
||||
<newlayer />
|
||||
<icon part="window_help_icon" color="button_normal_text" />
|
||||
<icon part="window_help_icon" color="button_hot_text" state="mouse" />
|
||||
|
@ -543,10 +544,13 @@
|
|||
<text color="disabled" align="left" state="disabled" />
|
||||
</style>
|
||||
<style id="mini_label" extends="label" font="mini" />
|
||||
<style id="warning_label" extends="label">
|
||||
<icon part="warning_box" align="right" />
|
||||
</style>
|
||||
<style id="list_header_label" padding="2">
|
||||
<text color="text" align="left" x="2" />
|
||||
</style>
|
||||
<style id="link">
|
||||
<style id="link" padding="1">
|
||||
<text color="link_text" align="left" />
|
||||
<text color="link_hover" align="left" state="mouse" />
|
||||
</style>
|
||||
|
@ -699,10 +703,11 @@
|
|||
<style id="workspace_splitter">
|
||||
<background color="workspace" />
|
||||
</style>
|
||||
<style id="horizontal_separator" border-left="2" border-top="4" border-right="2" border-bottom="0">
|
||||
<style id="horizontal_separator" border="2">
|
||||
<background color="window_face" />
|
||||
<background-border part="separator_horz" align="middle" />
|
||||
<text color="separator_label" x="4" align="left middle" />
|
||||
<text color="disabled" x="4" align="left middle" state="disabled"/>
|
||||
</style>
|
||||
<style id="menu_separator" extends="horizontal_separator" />
|
||||
<style id="separator_in_view" extends="horizontal_separator">
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 9.1 KiB After Width: | Height: | Size: 9.2 KiB |
|
@ -32,14 +32,16 @@
|
|||
|
||||
<font name="Aseprite"
|
||||
type="spritesheet"
|
||||
descent="2"
|
||||
file="aseprite_font.png">
|
||||
<fallback font="Unicode" size="8" />
|
||||
<fallback font="Unicode" size="14" />
|
||||
</font>
|
||||
|
||||
<font name="Aseprite Mini"
|
||||
type="spritesheet"
|
||||
descent="1"
|
||||
file="aseprite_mini.png">
|
||||
<fallback font="Unicode" size="6" />
|
||||
<fallback font="Unicode" size="10" />
|
||||
</font>
|
||||
|
||||
</fonts>
|
||||
|
|
|
@ -175,6 +175,7 @@
|
|||
<param name="popup" value="background" />
|
||||
</key>
|
||||
<key command="ShowExtras" shortcut="Ctrl+H" />
|
||||
<key command="ToggleWorkspaceLayout" shortcut="Shift+W" />
|
||||
<!-- Tabs -->
|
||||
<key command="GotoNextTab" shortcut="Ctrl+Tab" />
|
||||
<key command="GotoPreviousTab" shortcut="Ctrl+Shift+Tab" />
|
||||
|
@ -1002,6 +1003,7 @@
|
|||
</menu>
|
||||
<menu text="@.view" id="view_menu">
|
||||
<item command="DuplicateView" text="@.view_duplicate_view" group="view_new" />
|
||||
<item command="ToggleWorkspaceLayout" text="@.view_workspace_layout" />
|
||||
<separator />
|
||||
<item command="ShowExtras" text="@.view_show_extras" />
|
||||
<menu text="@.view_show" group="view_extras">
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Aseprite -->
|
||||
<!-- Copyright (C) 2018-2024 Igara Studio S.A. -->
|
||||
<!-- Copyright (C) 2018-2025 Igara Studio S.A. -->
|
||||
<!-- Copyright (C) 2014-2018 David Capello -->
|
||||
<preferences>
|
||||
|
||||
|
@ -167,6 +167,7 @@
|
|||
<option id="keep_closed_sprite_on_memory_for" type="double" default="15.0" />
|
||||
<option id="show_full_path" type="bool" default="true" />
|
||||
<option id="edit_full_path" type="bool" default="false" />
|
||||
<option id="workspace_layout" type="std::string" />
|
||||
<option id="timeline_position" type="TimelinePosition" default="TimelinePosition::BOTTOM" />
|
||||
<option id="timeline_layer_panel_width" type="int" default="100" />
|
||||
<option id="show_menu_bar" type="bool" default="true" />
|
||||
|
@ -255,6 +256,7 @@
|
|||
<option id="one_finger_as_mouse_movement" type="bool" default="true" />
|
||||
<option id="load_wintab_driver" type="bool" default="false" />
|
||||
<option id="flash_layer" type="bool" default="false" />
|
||||
<option id="use_selection_tool_loop" type="bool" default="false" />
|
||||
<option id="nonactive_layers_opacity" type="int" default="255" />
|
||||
<option id="nonactive_layers_opacity_preview" type="int" default="255" />
|
||||
</section>
|
||||
|
@ -356,6 +358,7 @@
|
|||
<section id="file_selector">
|
||||
<option id="current_folder" type="std::string" default=""<empty>"" />
|
||||
<option id="zoom" type="double" default="1.0" />
|
||||
<option id="show_hidden" type="bool" default="false" />
|
||||
</section>
|
||||
<section id="text_tool">
|
||||
<option id="font_face" type="std::string" />
|
||||
|
@ -551,6 +554,7 @@
|
|||
<option id="enabled" type="bool" default="false" />
|
||||
<option id="overlay_enabled" type="bool" default="false" />
|
||||
<option id="overlay_size" type="int" default="5" />
|
||||
<option id="scale_up_to_fit" type="bool" default="false" />
|
||||
</section>
|
||||
<section id="onionskin">
|
||||
<option id="active" type="bool" default="false" />
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Aseprite
|
||||
# Copyright (C) 2018-2024 Igara Studio S.A.
|
||||
# Copyright (C) 2018-2025 Igara Studio S.A.
|
||||
# Copyright (C) 2016-2018 David Capello
|
||||
#
|
||||
# This work is licensed under the Creative Commons Attribution 4.0
|
||||
|
@ -43,7 +43,6 @@ locked_layers = There are locked layers
|
|||
no_active_layers = There is no active layer
|
||||
layer_x_is_hidden = Layer "{}" is hidden
|
||||
unmodifiable_reference_layer = Layer "{}" is reference, cannot be modified
|
||||
filter_no_unlocked_layer = No unlocked layers to apply filter
|
||||
cannot_move_bg_layer = The background layer cannot be moved
|
||||
nothing_to_move = Nothing to move
|
||||
recovery_task_using_sprite = Sprite is used by a backup/data recovery task
|
||||
|
@ -489,6 +488,7 @@ TilesetDuplicate = Duplicate Tileset
|
|||
Undo = Undo
|
||||
UndoHistory = Undo History
|
||||
UnlinkCel = Unlink Cel
|
||||
ToggleWorkspaceLayout = Toggle Workspace Layout
|
||||
Zoom = Zoom
|
||||
Zoom_In = Zoom In
|
||||
Zoom_Out = Zoom Out
|
||||
|
@ -622,6 +622,14 @@ current_layer = Current Layer
|
|||
first_ref_layer = First Reference Layer
|
||||
pick = Pick:
|
||||
sample = Sample:
|
||||
position_label = P:
|
||||
rotation_label = R:
|
||||
position_x = X Position
|
||||
position_y = Y Position
|
||||
size_width = Width
|
||||
size_height = Height
|
||||
rotation_angle = Angle
|
||||
rotation_skew = Skew
|
||||
|
||||
[convolution_matrix]
|
||||
reload_stock = &Reload Stock
|
||||
|
@ -766,6 +774,7 @@ pinned_folders = Pinned Folders
|
|||
recent_folders = Recent Folders
|
||||
all_formats = All formats
|
||||
all_files = All files
|
||||
show_hidden = Show hidden
|
||||
|
||||
[filters]
|
||||
selected_cels = Selected
|
||||
|
@ -786,6 +795,11 @@ load = Load External Font
|
|||
select_truetype_fonts = Select a Font File
|
||||
empty_fonts = No system fonts were found
|
||||
|
||||
[font_style]
|
||||
antialias = Antialias
|
||||
hinting = Hinting
|
||||
ligatures = Ligatures
|
||||
|
||||
[frame_combo]
|
||||
all_frames = All frames
|
||||
selected_frames = Selected frames
|
||||
|
@ -813,6 +827,12 @@ opacity = Opacity:
|
|||
tolerance = Tolerance:
|
||||
show_more = Show more...
|
||||
|
||||
[general_text]
|
||||
copy = &Copy
|
||||
cut = Cu&t
|
||||
paste = &Paste
|
||||
select_all = Select &All
|
||||
|
||||
[gif_options]
|
||||
title = GIF Options
|
||||
general_options = General Options:
|
||||
|
@ -981,6 +1001,7 @@ visible_layers = Visible layers
|
|||
[layer_properties]
|
||||
title = Layer Properties
|
||||
name = Name:
|
||||
uuid = UUID:
|
||||
mode = Mode:
|
||||
opacity = Opacity:
|
||||
tileset_tooltip = Tileset
|
||||
|
@ -1155,6 +1176,7 @@ select_load_from_file = &Load from MSK file
|
|||
select_save_to_file = &Save to MSK file
|
||||
view = &View
|
||||
view_duplicate_view = Duplicate &View
|
||||
view_workspace_layout = Workspace &Layout
|
||||
view_show_extras = &Extras
|
||||
view_show = &Show
|
||||
view_show_layer_edges = &Layer Edges
|
||||
|
@ -1196,6 +1218,14 @@ help_twitter = Twitter
|
|||
help_enter_license = Enter &License
|
||||
help_about = &About
|
||||
|
||||
[main_window]
|
||||
layout = Workspace Layout
|
||||
default_layout = Default
|
||||
mirrored_default_layout = Mirrored Default
|
||||
timeline = Timeline
|
||||
user_layouts = User Layouts
|
||||
new_layout = New Layout...
|
||||
|
||||
[mask_by_color]
|
||||
title = Select Color
|
||||
label_color = Color:
|
||||
|
@ -1224,6 +1254,20 @@ name = Name:
|
|||
tileset = Tileset:
|
||||
default_new_layer_name = New Layer
|
||||
|
||||
[new_layout]
|
||||
title = New Workspace Layout
|
||||
name = Name:
|
||||
deleting_layout = Deleting Layout
|
||||
deleting_layout_confirmation = Are you sure you want to delete the '{}' layout?
|
||||
restoring_layout = Restoring Layout
|
||||
restoring_layout_confirmation = Are you sure you want to restore the '{}' layout?
|
||||
|
||||
[dock]
|
||||
left = Dock Left
|
||||
right = Dock Right
|
||||
top = Dock Top
|
||||
bottom = Dock Bottom
|
||||
|
||||
[news_listbox]
|
||||
more = More...
|
||||
problem_loading = Problems loading news. Please retry.
|
||||
|
@ -1326,7 +1370,7 @@ theme_mode = Theme Mode:
|
|||
screen_scaling = Screen Scaling:
|
||||
ui_scaling = UI Element Scaling:
|
||||
language = Language:
|
||||
download_translations = Download Translations
|
||||
font_warning = Customize font for this language
|
||||
gpu_acceleration = GPU acceleration [DEVMODE/INTERNAL TESTING ONLY]
|
||||
gpu_acceleration_tooltip = Check this option to enable hardware acceleration
|
||||
show_menu_bar = Show Aseprite menu bar
|
||||
|
@ -1513,6 +1557,12 @@ alpha_range = Alpha Range:
|
|||
opacity_range = Opacity Range:
|
||||
8bit_value = 0-255
|
||||
percentage = 0%-100%
|
||||
customize_theme = Customize Theme
|
||||
font = Font:
|
||||
mini_font = Mini Font:
|
||||
preview = Preview:
|
||||
font_preview = Font Preview
|
||||
mini_font_preview = Mini Font Preview
|
||||
available_themes = Available Themes
|
||||
extension_themes = Extension Themes
|
||||
select_theme = &Select
|
||||
|
@ -1550,11 +1600,13 @@ set_cursor_fix = Set cursor position from stylus location
|
|||
set_cursor_fix_tooltip = Sets the mouse position to the pen location when\nyou have two pointers available (e.g. mouse and pen)\n\nUseful to zoom in/out from the pen position and to get the\ncorrect cursor location when screencasting/live streaming.
|
||||
wintab_more_info = (More Information)
|
||||
flash_selected_layer = Flash layer when it is selected
|
||||
use_selection_tool_loop = New selection tools implementation
|
||||
non_active_layer_opacity = Opacity for non-active layers:
|
||||
cel_content_format = Cel content format:
|
||||
cel_format_compressed = Compressed
|
||||
cel_format_keep = Keep format as is in file
|
||||
cel_format_raw = Raw image
|
||||
cel_format_raw_warning = This will increase .aseprite file sizes considerably
|
||||
reset_title = Reset Preferences
|
||||
reset_default = Reset configuration options available in the Preferences window
|
||||
reset_tools = Reset all tool preferences
|
||||
|
@ -1659,6 +1711,11 @@ n_slices_removed = {} slice(s) removed
|
|||
x_removed = Layer "{}" removed
|
||||
layers_removed = Layers removed
|
||||
|
||||
[resource_listbox]
|
||||
loading = Loading
|
||||
pin = Pin this item
|
||||
unpin = Unpin this item
|
||||
|
||||
[save_file]
|
||||
title = Save File
|
||||
save_as = Save As
|
||||
|
@ -1675,7 +1732,8 @@ title = Save Selection (.msk file)
|
|||
[script_access]
|
||||
title = Security
|
||||
script_label = The following script:
|
||||
file_label = wants to access to this file:
|
||||
file_label = wants to access this file:
|
||||
file_write_label = wants to write to this file:
|
||||
command_label = wants to execute the following command:
|
||||
websocket_label = wants to open a WebSocket connection to this URL:
|
||||
clipboard_label = wants to access the system clipboard
|
||||
|
@ -1689,7 +1747,7 @@ allow_load_lib_access = &Allow Load External Library
|
|||
give_full_access = Give Script Full &Access
|
||||
stop_script = &Stop Script
|
||||
|
||||
[select_accelerator]
|
||||
[select_shortcut]
|
||||
title = Keyboard Shortcut
|
||||
key = Key:
|
||||
clear = Clear
|
||||
|
@ -1769,6 +1827,8 @@ change_sprite_props = Change Sprite Properties
|
|||
tilesets = Tilesets
|
||||
delete_tileset = Delete
|
||||
duplicate_tileset = Duplicate
|
||||
use_uuid_for_layers = Create UUID for layers
|
||||
use_uuid_for_layers_tooltip = By checking this an UUID (Universally Unique Identifiers)\nwill be automatically assigned to each layer\nand saved in .aseprite files
|
||||
|
||||
[sprite_size]
|
||||
title = Sprite Size
|
||||
|
@ -1814,16 +1874,26 @@ pixel_scale = Pixel Scale
|
|||
with_vars = Use CSS3 Variables
|
||||
generate_html = Generate Sample HTML File
|
||||
|
||||
[shape]
|
||||
fill = Fill
|
||||
stroke = Stroke
|
||||
stroke_width = Stroke Width
|
||||
|
||||
[text_tool]
|
||||
font_family = Font Family
|
||||
font_size = Font Size
|
||||
bold = Bold
|
||||
italic = Italic
|
||||
more_options = More Options
|
||||
|
||||
[timeline_conf]
|
||||
position = Position:
|
||||
left = &Left
|
||||
right = &Right
|
||||
bottom = &Bottom
|
||||
frame_header = Frame Header:
|
||||
first_frame = First Frame:
|
||||
thumbnails = Thumbnails
|
||||
thumbnail_size = Thumbnail Size:
|
||||
overlay_size = Overlay Size:
|
||||
scale_up_to_fit = Scale up to fit
|
||||
onion_skin = Onion Skin:
|
||||
merge_frames = Merge Frames
|
||||
red_blue_tint = Red/Blue Tint
|
||||
|
@ -1836,6 +1906,7 @@ behind_sprite = Behind sprite
|
|||
behind_sprite_toolip = Only for transparent layers.\nBackground is not included in this onion skin mode.
|
||||
in_front = In front of sprite
|
||||
in_front_toolip = For all kind of layers (background and transparent)
|
||||
set_as_defaults = Set as Defaults
|
||||
|
||||
[tools]
|
||||
rectangular_marquee = Rectangular Marquee Tool
|
||||
|
@ -1874,6 +1945,7 @@ timeline_show = Show Timeline
|
|||
|
||||
[undo_history]
|
||||
title = Undo History
|
||||
initial_state = Initial State
|
||||
|
||||
[user_data]
|
||||
user_data = User Data:
|
||||
|
|
|
@ -1,29 +1,14 @@
|
|||
<!-- Aseprite -->
|
||||
<!-- Copyright (C) 2018-2024 Igara Studio S.A. -->
|
||||
<!-- Copyright (C) 2018-2025 Igara Studio S.A. -->
|
||||
<!-- Copyright (C) 2018 David Capello -->
|
||||
<gui i18nwarnings="false">
|
||||
<window id="about" text="About Aseprite">
|
||||
<vbox>
|
||||
<label text="" id="title" />
|
||||
<label text="Animated sprite editor && pixel art tool" />
|
||||
<hbox homogeneous="true">
|
||||
<hbox>
|
||||
<vbox expansive="true">
|
||||
<separator text="Developer Team" horizontal="true" />
|
||||
<link text="David Capello" url="https://twitter.com/davidcapello" />
|
||||
<link text="Gaspar Capello" url="https://twitter.com/Gasparoken" />
|
||||
<link text="Martín Capello" url="https://twitter.com/martincapell0" />
|
||||
<vbox minheight="8" />
|
||||
</vbox>
|
||||
<separator vertical="true" />
|
||||
</hbox>
|
||||
<vbox>
|
||||
<separator text="Credits" horizontal="true" cell_hspan="2" />
|
||||
<link text="Contributors" url="" id="credits" />
|
||||
<link text="Translators" url="" id="i18n_credits" />
|
||||
<link text="Open Source Projects" url="" id="licenses" />
|
||||
</vbox>
|
||||
</hbox>
|
||||
<link text="Authors && Credits" url="" id="credits" />
|
||||
<link text="Translators" url="" id="i18n_credits" />
|
||||
<link text="Open Source Projects" url="" id="licenses" />
|
||||
<separator horizontal="true" />
|
||||
<hbox>
|
||||
<label text="Copyright (C) 2001-2025" />
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
<combobox id="location" expansive="true" />
|
||||
<button text="" id="refresh_button" style="refresh_button"
|
||||
tooltip="@.refresh_button_tooltip" tooltip_dir="bottom" />
|
||||
<check id="show_hidden_check" text="@.show_hidden" />
|
||||
</box>
|
||||
<vbox id="file_view_placeholder" expansive="true" />
|
||||
<grid columns="2">
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
<!-- Aseprite -->
|
||||
<!-- Copyright (C) 2025 by Igara Studio S.A. -->
|
||||
<gui>
|
||||
<vbox id="font_style">
|
||||
<check id="antialias" text="@.antialias" />
|
||||
<check id="hinting" text="@.hinting" />
|
||||
<separator horizontal="true" />
|
||||
<check id="ligatures" text="@.ligatures" />
|
||||
</vbox>
|
||||
</gui>
|
|
@ -15,6 +15,9 @@
|
|||
|
||||
<label text="@.opacity" />
|
||||
<opacityslider id="opacity" width="128" cell_align="horizontal" cell_hspan="2" />
|
||||
|
||||
<label id="uuid_label" text="@.uuid" visible="false" />
|
||||
<entry id="uuid" readonly="true" maxsize="36" cell_hspan="2" visible="false"/>
|
||||
</grid>
|
||||
</vbox>
|
||||
</window>
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
<!-- Aseprite -->
|
||||
<!-- Copyright (C) 2001-2017 by David Capello -->
|
||||
<gui>
|
||||
<window id="main_window" noborders="true" desktop="true">
|
||||
<vbox noborders="true" expansive="true">
|
||||
<hbox noborders="true" id="menu_bar_placeholder" />
|
||||
<hbox noborders="true" id="tabs_placeholder" />
|
||||
<splitter id="color_bar_splitter"
|
||||
horizontal="true" expansive="true"
|
||||
by="pixel"
|
||||
style="workspace_splitter">
|
||||
<vbox noborders="true" id="color_bar_placeholder" />
|
||||
<vbox noborders="true" expansive="true">
|
||||
<vbox noborders="true" id="context_bar_placeholder" />
|
||||
<hbox noborders="true" expansive="true">
|
||||
<splitter id="timeline_splitter"
|
||||
vertical="true" expansive="true"
|
||||
by="percetage" position="100"
|
||||
style="workspace_splitter">
|
||||
<hbox noborders="true" id="workspace_placeholder" expansive="true" />
|
||||
<vbox noborders="true" id="timeline_placeholder" expansive="true" />
|
||||
</splitter>
|
||||
<vbox noborders="true" id="tool_bar_placeholder" />
|
||||
</hbox>
|
||||
</vbox>
|
||||
</splitter>
|
||||
<hbox noborders="true" id="status_bar_placeholder" />
|
||||
</vbox>
|
||||
</window>
|
||||
</gui>
|
|
@ -0,0 +1,19 @@
|
|||
<!-- Aseprite -->
|
||||
<!-- Copyright (C) 2025 by Igara Studio S.A. -->
|
||||
<gui>
|
||||
<window id="new_layout" text="@.title">
|
||||
<vbox>
|
||||
<hbox>
|
||||
<label text="@.name" />
|
||||
<entry maxsize="128" id="name" magnet="true" expansive="true" />
|
||||
</hbox>
|
||||
|
||||
<separator horizontal="true" />
|
||||
|
||||
<hbox homogeneous="true" cell_align="right">
|
||||
<button text="@general.ok" closewindow="true" id="ok" disabled="true" minwidth="60" magnet="true" />
|
||||
<button text="@general.cancel" closewindow="true" />
|
||||
</hbox>
|
||||
</vbox>
|
||||
</window>
|
||||
</gui>
|
|
@ -1,5 +1,6 @@
|
|||
|
||||
<!-- Aseprite -->
|
||||
<!-- Copyright (C) 2018-2024 Igara Studio S.A. -->
|
||||
<!-- Copyright (C) 2018-2025 Igara Studio S.A. -->
|
||||
<!-- Copyright (C) 2001-2018 David Capello -->
|
||||
<gui>
|
||||
<window id="options" text="@.title" help="preferences">
|
||||
|
@ -34,7 +35,7 @@
|
|||
<!-- General -->
|
||||
<vbox id="section_general">
|
||||
<separator text="@.section_general" horizontal="true" />
|
||||
<grid columns="3">
|
||||
<grid columns="2">
|
||||
<label text="@.ui_windows" />
|
||||
<hbox>
|
||||
<buttonset columns="2" id="ui_windows">
|
||||
|
@ -45,7 +46,6 @@
|
|||
<label text="@.theme_mode" />
|
||||
</hbox>
|
||||
</hbox>
|
||||
<boxfiller />
|
||||
|
||||
<label text="@.screen_scaling" />
|
||||
<combobox id="screen_scale">
|
||||
|
@ -54,7 +54,6 @@
|
|||
<listitem text="300%" value="3" />
|
||||
<listitem text="400%" value="4" />
|
||||
</combobox>
|
||||
<boxfiller />
|
||||
|
||||
<label text="@.ui_scaling" />
|
||||
<combobox id="ui_scale">
|
||||
|
@ -63,12 +62,14 @@
|
|||
<listitem text="300%" value="3" />
|
||||
<listitem text="400%" value="4" />
|
||||
</combobox>
|
||||
<boxfiller />
|
||||
|
||||
<label text="@.language" />
|
||||
<link text="@.language" url="https://www.aseprite.org/languages/" />
|
||||
<combobox id="language" />
|
||||
<link text="@.download_translations" url="https://www.aseprite.org/languages/" />
|
||||
|
||||
<boxfiller id="font_warning_filler" visible="false" />
|
||||
<link text="@.font_warning" id="font_warning" visible="false" />
|
||||
</grid>
|
||||
<separator horizontal="true" />
|
||||
<check id="gpu_acceleration"
|
||||
text="@.gpu_acceleration"
|
||||
tooltip="@.gpu_acceleration_tooltip" />
|
||||
|
@ -545,6 +546,20 @@
|
|||
|
||||
<!-- Theme -->
|
||||
<vbox id="section_theme">
|
||||
<separator text="@.customize_theme" horizontal="true" />
|
||||
<grid columns="2">
|
||||
<label text="@.preview" />
|
||||
<vbox cell_align="horizontal" >
|
||||
<label id="font_preview" text="@.font_preview" />
|
||||
<label id="mini_font_preview" text="@.mini_font_preview" />
|
||||
</vbox>
|
||||
|
||||
<check id="custom_theme_font" text="@.font" />
|
||||
<font id="theme_font" cell_align="horizontal" />
|
||||
|
||||
<check id="custom_mini_font" text="@.mini_font" />
|
||||
<font id="theme_mini_font" cell_align="horizontal" />
|
||||
</grid>
|
||||
<separator text="@.available_themes" horizontal="true" />
|
||||
<view expansive="true" maxsize="true">
|
||||
<listbox id="theme_list" />
|
||||
|
@ -581,6 +596,10 @@
|
|||
<listitem text="@.cel_format_keep" />
|
||||
<listitem text="@.cel_format_raw" />
|
||||
</combobox>
|
||||
|
||||
<boxfiller />
|
||||
<label id="cel_format_warning"
|
||||
text="@.cel_format_raw_warning" style="warning_label" />
|
||||
</grid>
|
||||
</vbox>
|
||||
|
||||
|
@ -613,6 +632,7 @@
|
|||
text="@.hue_with_sat_value"
|
||||
pref="experimental.hue_with_sat_value_for_color_selector" />
|
||||
<check id="flash_layer" text="@.flash_selected_layer" />
|
||||
<check id="use_selection_tool_loop" text="@.use_selection_tool_loop" />
|
||||
<hbox>
|
||||
<label text="@.non_active_layer_opacity" />
|
||||
<slider id="nonactive_layers_opacity" min="0" max="255" width="128" />
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
<!-- Aseprite -->
|
||||
<!-- Copyright (C) 2025 by Igara Studio S.A. -->
|
||||
<!-- Copyright (C) 2001-2016 by David Capello -->
|
||||
<gui>
|
||||
<window id="select_accelerator" text="@.title">
|
||||
<window id="select_shortcut" text="@.title">
|
||||
<vbox expansive="true">
|
||||
<grid columns="3">
|
||||
<label text="@.key" />
|
|
@ -42,6 +42,8 @@
|
|||
<button id="convert_color_profile" text="@.convert" />
|
||||
</hbox>
|
||||
</hbox>
|
||||
|
||||
<check text="@.use_uuid_for_layers" id="use_uuid_for_layers" tooltip="@.use_uuid_for_layers_tooltip" cell_hspan="2" />
|
||||
</grid>
|
||||
|
||||
<vbox expansive="true" id="tilesets_placeholder">
|
||||
|
|
|
@ -1,17 +1,12 @@
|
|||
<!-- Aseprite -->
|
||||
<!-- Copyright (C) 2025 Igara Studio S.A. -->
|
||||
<!-- Copyright (C) 2014-2018 by David Capello -->
|
||||
<gui>
|
||||
<vbox id="timeline_conf">
|
||||
<hbox>
|
||||
<vbox>
|
||||
<separator cell_hspan="2" text="@.position" left="true" horizontal="true" />
|
||||
<hbox>
|
||||
<buttonset columns="2" id="position">
|
||||
<item text="@.left" />
|
||||
<item text="@.right" />
|
||||
<item text="@.bottom" hspan="2" />
|
||||
</buttonset>
|
||||
</hbox>
|
||||
<button id="layout" icon="icon_layout" />
|
||||
</vbox>
|
||||
<vbox>
|
||||
<separator text="@.frame_header" left="true" horizontal="true" />
|
||||
|
@ -30,6 +25,7 @@
|
|||
|
||||
<check id="thumb_overlay_enabled" text="@.overlay_size"/>
|
||||
<slider min="2" max="10" id="thumb_overlay_size" cell_align="horizontal" width="128" />
|
||||
<check id="thumb_scale_up_to_fit" text="@.scale_up_to_fit" cell_hspan="2" />
|
||||
</grid>
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
@ -55,5 +51,11 @@
|
|||
<radio group="2" text="@.in_front" id="infront" tooltip="@.in_front_toolip" />
|
||||
</hbox>
|
||||
</grid>
|
||||
|
||||
<separator horizontal="true" />
|
||||
<hbox>
|
||||
<boxfiller />
|
||||
<button id="defaults" text="@.set_as_defaults" />
|
||||
</hbox>
|
||||
</vbox>
|
||||
</gui>
|
||||
|
|
|
@ -1,5 +1,34 @@
|
|||
Aseprite uses the following open source projects:
|
||||
|
||||
* [Allegro 4](http://liballeg.org/)
|
||||
* [Bresenham algorithm implementations by Alois Zingl](http://members.chello.at/easyfilter/bresenham.html)
|
||||
* [cityhash](https://github.com/google/cityhash)
|
||||
* [cmark](https://github.com/jgm/cmark)
|
||||
* [curl](http://curl.haxx.se/)
|
||||
* [fmt](https://github.com/fmtlib/fmt)
|
||||
* [FreeType](http://www.freetype.org/)
|
||||
* [giflib](http://sourceforge.net/projects/giflib/)
|
||||
* [Google Test](https://github.com/google/googletest)
|
||||
* [harfbuzz](http://harfbuzz.org)
|
||||
* [IXWebSocket](https://github.com/machinezone/IXWebSocket)
|
||||
* [json11](https://github.com/dropbox/json11/)
|
||||
* [libarchive](http://www.libarchive.org/)
|
||||
* [libjpeg-turbo](https://libjpeg-turbo.org/)
|
||||
* [libpng](http://www.libpng.org/pub/png/)
|
||||
* [libwebp](https://developers.google.com/speed/webp/)
|
||||
* [Lua](https://www.lua.org/)
|
||||
* [pixman](http://www.pixman.org/)
|
||||
* [qoi](https://github.com/phoboslab/qoi)
|
||||
* [Sentry](https://sentry.io)
|
||||
* [skia](https://skia.org)
|
||||
* [simpleini](https://github.com/aseprite/simpleini/)
|
||||
* [TinyEXIF](https://github.com/cdcseacave/TinyEXIF)
|
||||
* [tinyexpr](https://github.com/codeplea/tinyexpr)
|
||||
* [tinyxml2](https://github.com/leethomason/tinyxml2)
|
||||
* [ucdn](https://github.com/grigorig/ucdn)
|
||||
* [Wintab API](http://www.wacomeng.com/windows/docs/WintabBackground.htm)
|
||||
* [zlib](http://www.zlib.net/)
|
||||
|
||||
# [Allegro 4](http://liballeg.org/)
|
||||
|
||||
```
|
||||
|
|
|
@ -79,6 +79,7 @@ A 128-byte header (same as FLC/FLI header, but with other magic number):
|
|||
1 = Layer opacity has valid value
|
||||
2 = Layer blend mode/opacity is valid for groups
|
||||
(composite groups separately first when rendering)
|
||||
4 = Layers have an UUID
|
||||
WORD Speed (milliseconds between frame, like in FLC files)
|
||||
DEPRECATED: You should use the frame duration field
|
||||
from each frame header
|
||||
|
@ -202,6 +203,8 @@ entire layers layout:
|
|||
STRING Layer name
|
||||
+ If layer type = 2
|
||||
DWORD Tileset index
|
||||
+ If file header flags have bit 4:
|
||||
UUID Layer's universally unique identifier
|
||||
|
||||
### Cel Chunk (0x2005)
|
||||
|
||||
|
|
2
laf
2
laf
|
@ -1 +1 @@
|
|||
Subproject commit 339a0fa13584853bda8559de486e715e743a5763
|
||||
Subproject commit 01571537bc6002a2e039a66497837365c394d7fa
|
|
@ -1,5 +1,5 @@
|
|||
# Aseprite
|
||||
# Copyright (C) 2019-2024 Igara Studio S.A.
|
||||
# Copyright (C) 2019-2025 Igara Studio S.A.
|
||||
# Copyright (C) 2001-2018 David Capello
|
||||
|
||||
######################################################################
|
||||
|
@ -152,6 +152,12 @@ add_custom_command(
|
|||
MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/../README.md)
|
||||
list(APPEND out_data_files ${DATA_OUTPUT_DIR}/README.md)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${DATA_OUTPUT_DIR}/AUTHORS.md
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/../AUTHORS.md ${DATA_OUTPUT_DIR}/AUTHORS.md
|
||||
MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/../AUTHORS.md)
|
||||
list(APPEND out_data_files ${DATA_OUTPUT_DIR}/AUTHORS.md)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${DATA_OUTPUT_DIR}/EULA.txt
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/../EULA.txt ${DATA_OUTPUT_DIR}/EULA.txt
|
||||
|
@ -174,8 +180,8 @@ if(ENABLE_ASEPRITE_EXE)
|
|||
|
||||
if(WIN32)
|
||||
set(main_resources
|
||||
main/resources_win32.rc
|
||||
main/settings.manifest)
|
||||
main/win/resources_win32.rc
|
||||
main/win/settings.manifest)
|
||||
endif()
|
||||
|
||||
add_executable(${main_target}
|
||||
|
|
|
@ -72,6 +72,10 @@ In Debug mode (`_DEBUG`):
|
|||
* [`TRACEARGS`](https://github.com/aseprite/laf/blob/f3222bdee2d21556e9da55343e73803c730ecd97/base/debug.h#L40):
|
||||
in debug mode, it prints in the terminal/console each given argument
|
||||
|
||||
In release mode you can use a similar function:
|
||||
|
||||
* `PRINTARGS` prints in the terminal/console each given argument
|
||||
|
||||
# Detect Platform
|
||||
|
||||
You can check the platform using some `laf` macros:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# Aseprite
|
||||
# Copyright (C) 2018-2024 Igara Studio S.A.
|
||||
# Copyright (C) 2018-2025 Igara Studio S.A.
|
||||
# Copyright (C) 2001-2018 David Capello
|
||||
|
||||
# Generate a ui::Widget for each widget in a XML file
|
||||
|
@ -98,17 +98,17 @@ add_library(app-lib ${generated_files})
|
|||
# These specific-platform files should be in an external library
|
||||
# (e.g. "base" or "os").
|
||||
if(WIN32)
|
||||
target_sources(app-lib PRIVATE font_path_win.cpp)
|
||||
target_sources(app-lib PRIVATE fonts/font_path_win.cpp)
|
||||
elseif(APPLE)
|
||||
target_sources(app-lib PRIVATE font_path_osx.mm)
|
||||
target_sources(app-lib PRIVATE fonts/font_path_osx.mm)
|
||||
else()
|
||||
target_sources(app-lib PRIVATE font_path_unix.cpp)
|
||||
target_sources(app-lib PRIVATE fonts/font_path_unix.cpp)
|
||||
endif()
|
||||
|
||||
# This defines a specific webp decoding utility function for using
|
||||
# in Windows when dragging and dropping images that are stored as
|
||||
# webp files (like Chrome does).
|
||||
if(WIN32 AND ENABLE_WEBP)
|
||||
if(WIN32 AND ENABLE_WEBP AND LAF_BACKEND STREQUAL "skia")
|
||||
target_sources(app-lib PRIVATE util/decode_webp.cpp)
|
||||
endif()
|
||||
|
||||
|
@ -290,7 +290,6 @@ target_sources(app-lib PRIVATE
|
|||
cmd/copy_region.cpp
|
||||
cmd/crop_cel.cpp
|
||||
cmd/deselect_mask.cpp
|
||||
cmd/drop_on_timeline.cpp
|
||||
cmd/flatten_layers.cpp
|
||||
cmd/flip_image.cpp
|
||||
cmd/flip_mask.cpp
|
||||
|
@ -522,11 +521,13 @@ target_sources(app-lib PRIVATE
|
|||
commands/tileset_mode.cpp
|
||||
commands/toggle_other_layers_opacity.cpp
|
||||
commands/toggle_play_option.cpp
|
||||
commands/toggle_workspace_layout.cpp
|
||||
console.cpp
|
||||
context.cpp
|
||||
context_flags.cpp
|
||||
doc.cpp
|
||||
doc_api.cpp
|
||||
doc_api_dnd_helper.cpp
|
||||
doc_diff.cpp
|
||||
doc_exporter.cpp
|
||||
doc_range_ops.cpp
|
||||
|
@ -545,8 +546,10 @@ target_sources(app-lib PRIVATE
|
|||
file_system.cpp
|
||||
filename_formatter.cpp
|
||||
flatten.cpp
|
||||
font_info.cpp
|
||||
font_path.cpp
|
||||
fonts/font_data.cpp
|
||||
fonts/font_info.cpp
|
||||
fonts/font_path.cpp
|
||||
fonts/fonts.cpp
|
||||
gui_xml.cpp
|
||||
i18n/strings.cpp
|
||||
i18n/xml_translator.cpp
|
||||
|
@ -608,6 +611,7 @@ target_sources(app-lib PRIVATE
|
|||
ui/context_bar.cpp
|
||||
ui/dithering_selector.cpp
|
||||
ui/doc_view.cpp
|
||||
ui/dock.cpp
|
||||
ui/drop_down_button.cpp
|
||||
ui/dynamics_popup.cpp
|
||||
ui/editor/brush_preview.cpp
|
||||
|
@ -652,6 +656,9 @@ target_sources(app-lib PRIVATE
|
|||
ui/input_chain.cpp
|
||||
ui/keyboard_shortcuts.cpp
|
||||
ui/layer_frame_comboboxes.cpp
|
||||
ui/layout.cpp
|
||||
ui/layouts.cpp
|
||||
ui/layout_selector.cpp
|
||||
ui/main_menu_bar.cpp
|
||||
ui/main_window.cpp
|
||||
ui/mini_help_button.cpp
|
||||
|
@ -668,9 +675,8 @@ target_sources(app-lib PRIVATE
|
|||
ui/rgbmap_algorithm_selector.cpp
|
||||
ui/sampling_selector.cpp
|
||||
ui/search_entry.cpp
|
||||
ui/select_accelerator.cpp
|
||||
ui/select_shortcut.cpp
|
||||
ui/selection_mode_field.cpp
|
||||
ui/skin/font_data.cpp
|
||||
ui/skin/skin_part.cpp
|
||||
ui/skin/skin_property.cpp
|
||||
ui/skin/skin_slider_property.cpp
|
||||
|
@ -684,6 +690,7 @@ target_sources(app-lib PRIVATE
|
|||
ui/tile_button.cpp
|
||||
ui/tileset_selector.cpp
|
||||
ui/timeline/ani_controls.cpp
|
||||
ui/timeline/doc_providers.cpp
|
||||
ui/timeline/timeline.cpp
|
||||
ui/toolbar.cpp
|
||||
ui/user_data_view.cpp
|
||||
|
@ -706,6 +713,7 @@ target_sources(app-lib PRIVATE
|
|||
util/layer_utils.cpp
|
||||
util/msk_file.cpp
|
||||
util/new_image_from_mask.cpp
|
||||
util/open_file_job.cpp
|
||||
util/pal_ops.cpp
|
||||
util/pic_file.cpp
|
||||
util/pixel_ratio.cpp
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Aseprite
|
||||
// Copyright (C) 2018-2024 Igara Studio S.A.
|
||||
// Copyright (C) 2018-2025 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
|
@ -79,7 +79,7 @@
|
|||
#include "os/x11/system.h"
|
||||
#endif
|
||||
|
||||
#if ENABLE_WEBP && LAF_WINDOWS
|
||||
#if ENABLE_WEBP && LAF_WINDOWS && LAF_SKIA
|
||||
#include "app/util/decode_webp.h"
|
||||
#endif
|
||||
|
||||
|
@ -485,7 +485,7 @@ void App::run(const bool runGuiManager)
|
|||
// How to interpret one finger on Windows tablets.
|
||||
manager->display()->nativeWindow()->setInterpretOneFingerGestureAsMouseMovement(
|
||||
preferences().experimental.oneFingerAsMouseMovement());
|
||||
#if ENABLE_WEBP
|
||||
#if ENABLE_WEBP && LAF_SKIA
|
||||
// In Windows we use a custom webp decoder for drag & drop operations.
|
||||
os::set_decode_webp(util::decode_webp);
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Aseprite
|
||||
// Copyright (C) 2019-2024 Igara Studio S.A.
|
||||
// Copyright (C) 2019-2025 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
|
@ -113,11 +113,11 @@ bool can_call_global_shortcut(const AppMenuItem::Native* native)
|
|||
(focus == nullptr || focus->type() != ui::kEntryWidget ||
|
||||
!is_text_entry_shortcut(native->shortcut)) &&
|
||||
(native->keyContext == KeyContext::Any ||
|
||||
native->keyContext == KeyboardShortcuts::instance()->getCurrentKeyContext());
|
||||
native->keyContext == KeyboardShortcuts::getCurrentKeyContext());
|
||||
}
|
||||
|
||||
// TODO this should be on "she" library (or we should use
|
||||
// os::Shortcut instead of ui::Accelerators)
|
||||
// TODO this should be on laf-os library (or we should use
|
||||
// os::Shortcut instead of ui::Shortcuts)
|
||||
int from_scancode_to_unicode(KeyScancode scancode)
|
||||
{
|
||||
static int map[] = {
|
||||
|
@ -284,22 +284,21 @@ void destroy_menu_item(ui::Widget* item)
|
|||
|
||||
os::Shortcut get_os_shortcut_from_key(const Key* key)
|
||||
{
|
||||
if (key && !key->accels().empty()) {
|
||||
const ui::Accelerator& accel = key->accels().front();
|
||||
if (key && !key->shortcuts().empty()) {
|
||||
const ui::Shortcut& shortcut = key->shortcuts().front();
|
||||
|
||||
#if LAF_MACOS
|
||||
// Shortcuts with spacebar as modifier do not work well in macOS
|
||||
// (they will be called when the space bar is unpressed too).
|
||||
if ((accel.modifiers() & ui::kKeySpaceModifier) == ui::kKeySpaceModifier)
|
||||
if ((shortcut.modifiers() & ui::kKeySpaceModifier) == ui::kKeySpaceModifier)
|
||||
return os::Shortcut();
|
||||
#endif
|
||||
|
||||
return os::Shortcut(
|
||||
(accel.unicodeChar() ? accel.unicodeChar() : from_scancode_to_unicode(accel.scancode())),
|
||||
accel.modifiers());
|
||||
return os::Shortcut((shortcut.unicodeChar() ? shortcut.unicodeChar() :
|
||||
from_scancode_to_unicode(shortcut.scancode())),
|
||||
shortcut.modifiers());
|
||||
}
|
||||
else
|
||||
return os::Shortcut();
|
||||
return {};
|
||||
}
|
||||
|
||||
AppMenus* AppMenus::s_instance = nullptr;
|
||||
|
@ -719,7 +718,6 @@ Widget* AppMenus::convertXmlelemToMenuitem(XMLElement* elem, Menu* menu)
|
|||
{
|
||||
const char* id = elem->Attribute("id");
|
||||
const char* group = elem->Attribute("group");
|
||||
const char* standard = elem->Attribute("standard");
|
||||
|
||||
// is it a <separator>?
|
||||
if (strcmp(elem->Value(), "separator") == 0) {
|
||||
|
@ -781,6 +779,7 @@ Widget* AppMenus::convertXmlelemToMenuitem(XMLElement* elem, Menu* menu)
|
|||
}
|
||||
|
||||
#if LAF_MACOS
|
||||
const char* standard = elem->Attribute("standard");
|
||||
if (standard && strcmp(standard, "edit") == 0)
|
||||
menuitem->setAsStandardEditMenu();
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// Aseprite
|
||||
// Copyright (C) 2025 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
|
@ -20,7 +21,20 @@ namespace app { namespace cmd {
|
|||
|
||||
using namespace doc;
|
||||
|
||||
ClearRect::ClearRect(Cel* cel, const gfx::Rect& bounds, color_t color)
|
||||
{
|
||||
ASSERT(cel);
|
||||
initialize(cel, bounds, color);
|
||||
}
|
||||
|
||||
ClearRect::ClearRect(Cel* cel, const gfx::Rect& bounds)
|
||||
{
|
||||
ASSERT(cel);
|
||||
Doc* doc = static_cast<Doc*>(cel->document());
|
||||
initialize(cel, bounds, doc->bgColor(cel->layer()));
|
||||
}
|
||||
|
||||
void ClearRect::initialize(Cel* cel, const gfx::Rect& bounds, color_t color)
|
||||
{
|
||||
ASSERT(cel);
|
||||
|
||||
|
@ -37,9 +51,7 @@ ClearRect::ClearRect(Cel* cel, const gfx::Rect& bounds)
|
|||
return;
|
||||
|
||||
m_dstImage.reset(new WithImage(image));
|
||||
|
||||
Doc* doc = static_cast<Doc*>(cel->document());
|
||||
m_bgcolor = doc->bgColor(cel->layer());
|
||||
m_bgcolor = color;
|
||||
|
||||
m_copy.reset(crop_image(image, bounds2.x, bounds2.y, bounds2.w, bounds2.h, m_bgcolor));
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// Aseprite
|
||||
// Copyright (C) 2025 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
|
@ -26,6 +27,7 @@ using namespace doc;
|
|||
class ClearRect : public Cmd {
|
||||
public:
|
||||
ClearRect(Cel* cel, const gfx::Rect& bounds);
|
||||
ClearRect(Cel* cel, const gfx::Rect& bounds, color_t color);
|
||||
|
||||
protected:
|
||||
void onExecute() override;
|
||||
|
@ -37,6 +39,7 @@ protected:
|
|||
}
|
||||
|
||||
private:
|
||||
void initialize(Cel* cel, const gfx::Rect& bounds, color_t color);
|
||||
void clear();
|
||||
void restore();
|
||||
|
||||
|
|
|
@ -1,397 +0,0 @@
|
|||
// Aseprite
|
||||
// Copyright (C) 2024 Igara Studio S.A.
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "app/cmd/drop_on_timeline.h"
|
||||
|
||||
#include "app/cmd/add_layer.h"
|
||||
#include "app/cmd/move_cel.h"
|
||||
#include "app/cmd/set_pixel_format.h"
|
||||
#include "app/console.h"
|
||||
#include "app/context_flags.h"
|
||||
#include "app/doc.h"
|
||||
#include "app/doc_event.h"
|
||||
#include "app/file/file.h"
|
||||
#include "app/tx.h"
|
||||
#include "app/util/layer_utils.h"
|
||||
#include "app/util/open_file_job.h"
|
||||
#include "base/serialization.h"
|
||||
#include "doc/layer_io.h"
|
||||
#include "doc/layer_list.h"
|
||||
#include "doc/subobjects_io.h"
|
||||
#include "render/dithering.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace app { namespace cmd {
|
||||
|
||||
using namespace base::serialization::little_endian;
|
||||
|
||||
DropOnTimeline::DropOnTimeline(app::Doc* doc,
|
||||
doc::frame_t frame,
|
||||
doc::layer_t layerIndex,
|
||||
InsertionPoint insert,
|
||||
DroppedOn droppedOn,
|
||||
const base::paths& paths)
|
||||
: WithDocument(doc)
|
||||
, m_size(0)
|
||||
, m_paths(paths)
|
||||
, m_frame(frame)
|
||||
, m_layerIndex(layerIndex)
|
||||
, m_insert(insert)
|
||||
, m_droppedOn(droppedOn)
|
||||
{
|
||||
ASSERT(m_layerIndex >= 0);
|
||||
for (const auto& path : m_paths)
|
||||
m_size += path.size();
|
||||
|
||||
// Zero layers stored.
|
||||
write32(m_stream, 0);
|
||||
m_size += sizeof(uint32_t);
|
||||
}
|
||||
|
||||
DropOnTimeline::DropOnTimeline(app::Doc* doc,
|
||||
doc::frame_t frame,
|
||||
doc::layer_t layerIndex,
|
||||
InsertionPoint insert,
|
||||
DroppedOn droppedOn,
|
||||
const doc::ImageRef& image)
|
||||
: WithDocument(doc)
|
||||
, m_size(0)
|
||||
, m_image(image)
|
||||
, m_frame(frame)
|
||||
, m_layerIndex(layerIndex)
|
||||
, m_insert(insert)
|
||||
, m_droppedOn(droppedOn)
|
||||
{
|
||||
ASSERT(m_layerIndex >= 0);
|
||||
|
||||
// Zero layers stored.
|
||||
write32(m_stream, 0);
|
||||
m_size += sizeof(uint32_t);
|
||||
}
|
||||
|
||||
void DropOnTimeline::onExecute()
|
||||
{
|
||||
Doc* destDoc = document();
|
||||
m_previousTotalFrames = destDoc->sprite()->totalFrames();
|
||||
|
||||
int docsProcessed = 0;
|
||||
while (hasPendingWork()) {
|
||||
std::unique_ptr<Doc> srcDoc;
|
||||
if (!getNextDoc(srcDoc))
|
||||
return;
|
||||
|
||||
if (srcDoc) {
|
||||
docsProcessed++;
|
||||
// If source document doesn't match the destination document's color
|
||||
// mode, change it.
|
||||
if (srcDoc->colorMode() != destDoc->colorMode()) {
|
||||
// Execute in a source doc transaction because we don't need undo/redo
|
||||
// this.
|
||||
Tx tx(srcDoc.get());
|
||||
tx(new cmd::SetPixelFormat(srcDoc->sprite(),
|
||||
destDoc->sprite()->pixelFormat(),
|
||||
render::Dithering(),
|
||||
Preferences::instance().quantization.rgbmapAlgorithm(),
|
||||
nullptr,
|
||||
nullptr,
|
||||
FitCriteria::DEFAULT));
|
||||
tx.commit();
|
||||
}
|
||||
|
||||
// If there is only one source document to process and it has a cel that
|
||||
// can be moved, then move the cel from the source doc into the
|
||||
// destination doc's selected frame.
|
||||
const bool isJustOneDoc = (docsProcessed == 1 && !hasPendingWork());
|
||||
if (isJustOneDoc && canMoveCelFrom(srcDoc.get())) {
|
||||
auto* srcLayer = static_cast<LayerImage*>(srcDoc->sprite()->firstLayer());
|
||||
auto* destLayer = static_cast<LayerImage*>(destDoc->sprite()->allLayers()[m_layerIndex]);
|
||||
executeAndAdd(new MoveCel(srcLayer, 0, destLayer, m_frame, false));
|
||||
break;
|
||||
}
|
||||
|
||||
// If there is no room for the source frames, add frames to the
|
||||
// destination sprite.
|
||||
if (m_frame + srcDoc->sprite()->totalFrames() > destDoc->sprite()->totalFrames()) {
|
||||
destDoc->sprite()->setTotalFrames(m_frame + srcDoc->sprite()->totalFrames());
|
||||
}
|
||||
|
||||
// Save dropped layers from source document.
|
||||
saveDroppedLayers(srcDoc->sprite()->root()->layers(), destDoc->sprite());
|
||||
}
|
||||
}
|
||||
|
||||
if (m_droppedLayersIds.empty())
|
||||
return;
|
||||
|
||||
destDoc->sprite()->incrementVersion();
|
||||
destDoc->incrementVersion();
|
||||
|
||||
insertDroppedLayers();
|
||||
}
|
||||
|
||||
void DropOnTimeline::onUndo()
|
||||
{
|
||||
CmdSequence::onUndo();
|
||||
|
||||
if (m_droppedLayersIds.empty()) {
|
||||
notifyGeneralUpdate();
|
||||
return;
|
||||
}
|
||||
|
||||
Doc* doc = document();
|
||||
frame_t currentTotalFrames = doc->sprite()->totalFrames();
|
||||
|
||||
for (auto id : m_droppedLayersIds) {
|
||||
auto* layer = doc::get<Layer>(id);
|
||||
ASSERT(layer);
|
||||
if (layer) {
|
||||
DocEvent ev(doc);
|
||||
ev.sprite(layer->sprite());
|
||||
ev.layer(layer);
|
||||
doc->notify_observers<DocEvent&>(&DocObserver::onBeforeRemoveLayer, ev);
|
||||
|
||||
LayerGroup* group = layer->parent();
|
||||
group->removeLayer(layer);
|
||||
group->incrementVersion();
|
||||
group->sprite()->incrementVersion();
|
||||
|
||||
doc->notify_observers<DocEvent&>(&DocObserver::onAfterRemoveLayer, ev);
|
||||
|
||||
delete layer;
|
||||
}
|
||||
}
|
||||
doc->sprite()->setTotalFrames(m_previousTotalFrames);
|
||||
doc->sprite()->incrementVersion();
|
||||
m_previousTotalFrames = currentTotalFrames;
|
||||
}
|
||||
|
||||
void DropOnTimeline::onRedo()
|
||||
{
|
||||
CmdSequence::onRedo();
|
||||
|
||||
if (m_droppedLayersIds.empty()) {
|
||||
notifyGeneralUpdate();
|
||||
return;
|
||||
}
|
||||
|
||||
Doc* doc = document();
|
||||
frame_t currentTotalFrames = doc->sprite()->totalFrames();
|
||||
doc->sprite()->setTotalFrames(m_previousTotalFrames);
|
||||
doc->sprite()->incrementVersion();
|
||||
m_previousTotalFrames = currentTotalFrames;
|
||||
|
||||
insertDroppedLayers();
|
||||
}
|
||||
|
||||
void DropOnTimeline::setupInsertionLayer(Layer*& layer, LayerGroup*& group)
|
||||
{
|
||||
const LayerList& allLayers = document()->sprite()->allLayers();
|
||||
layer = allLayers[m_layerIndex];
|
||||
if (m_insert == InsertionPoint::BeforeLayer && layer->isGroup()) {
|
||||
group = static_cast<LayerGroup*>(layer);
|
||||
// The user is trying to drop layers into an empty group, so there is no after
|
||||
// nor before layer...
|
||||
if (group->layersCount() == 0) {
|
||||
layer = nullptr;
|
||||
return;
|
||||
}
|
||||
layer = group->lastLayer();
|
||||
m_insert = InsertionPoint::AfterLayer;
|
||||
}
|
||||
|
||||
group = layer->parent();
|
||||
}
|
||||
|
||||
bool DropOnTimeline::hasPendingWork()
|
||||
{
|
||||
return m_image || !m_paths.empty();
|
||||
}
|
||||
|
||||
bool DropOnTimeline::getNextDocFromImage(std::unique_ptr<Doc>& srcDoc)
|
||||
{
|
||||
if (!m_image)
|
||||
return true;
|
||||
|
||||
Sprite* sprite = new Sprite(m_image->spec(), 256);
|
||||
LayerImage* layer = new LayerImage(sprite);
|
||||
sprite->root()->addLayer(layer);
|
||||
Cel* cel = new Cel(0, m_image);
|
||||
layer->addCel(cel);
|
||||
srcDoc = std::make_unique<Doc>(sprite);
|
||||
m_image = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DropOnTimeline::getNextDocFromPaths(std::unique_ptr<Doc>& srcDoc)
|
||||
{
|
||||
Console console;
|
||||
Context* context = document()->context();
|
||||
int flags = FILE_LOAD_DATA_FILE | FILE_LOAD_AVOID_BACKGROUND_LAYER | FILE_LOAD_CREATE_PALETTE |
|
||||
FILE_LOAD_SEQUENCE_YES;
|
||||
|
||||
std::unique_ptr<FileOp> fop(FileOp::createLoadDocumentOperation(context, m_paths.front(), flags));
|
||||
// Remove the path that is currently being processed
|
||||
m_paths.erase(m_paths.begin());
|
||||
|
||||
// Do nothing (the user cancelled or something like that)
|
||||
if (!fop)
|
||||
return false;
|
||||
|
||||
if (fop->hasError()) {
|
||||
console.printf(fop->error().c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
base::paths fopFilenames;
|
||||
fop->getFilenameList(fopFilenames);
|
||||
// Remove paths that will be loaded by the current file operation.
|
||||
for (const auto& filename : fopFilenames) {
|
||||
auto it = std::find(m_paths.begin(), m_paths.end(), filename);
|
||||
if (it != m_paths.end())
|
||||
m_paths.erase(it);
|
||||
}
|
||||
|
||||
OpenFileJob task(fop.get(), true);
|
||||
task.showProgressWindow();
|
||||
|
||||
// Post-load processing, it is called from the GUI because may require user intervention.
|
||||
fop->postLoad();
|
||||
|
||||
// Show any error
|
||||
if (fop->hasError() && !fop->isStop())
|
||||
console.printf(fop->error().c_str());
|
||||
|
||||
srcDoc.reset(fop->releaseDocument());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DropOnTimeline::getNextDoc(std::unique_ptr<Doc>& srcDoc)
|
||||
{
|
||||
if (m_image == nullptr && !m_paths.empty())
|
||||
return getNextDocFromPaths(srcDoc);
|
||||
|
||||
return getNextDocFromImage(srcDoc);
|
||||
}
|
||||
|
||||
void DropOnTimeline::storeDroppedLayerIds(const Layer* layer)
|
||||
{
|
||||
if (layer->isGroup()) {
|
||||
const auto* group = static_cast<const LayerGroup*>(layer);
|
||||
for (auto* child : group->layers())
|
||||
storeDroppedLayerIds(child);
|
||||
|
||||
m_droppedLayersIds.push_back(group->id());
|
||||
}
|
||||
else {
|
||||
m_droppedLayersIds.push_back(layer->id());
|
||||
}
|
||||
}
|
||||
|
||||
void DropOnTimeline::saveDroppedLayers(const LayerList& layers, Sprite* sprite)
|
||||
{
|
||||
size_t start = m_stream.tellp();
|
||||
|
||||
// Calculate the new number of layers.
|
||||
m_stream.seekg(0);
|
||||
uint32_t nLayers = read32(m_stream) + layers.size();
|
||||
|
||||
// Flat list of all the dropped layers.
|
||||
LayerList allDroppedLayers;
|
||||
// Write number of layers (at the beginning of the stream).
|
||||
m_stream.seekp(0);
|
||||
write32(m_stream, nLayers);
|
||||
// Move to where we must start writing.
|
||||
m_stream.seekp(start);
|
||||
for (auto it = layers.cbegin(); it != layers.cend(); ++it) {
|
||||
auto* layer = *it;
|
||||
// TODO: If we could "relocate" a layer from the source document to the
|
||||
// destination document we could avoid making a copy here.
|
||||
std::unique_ptr<Layer> layerCopy(copy_layer_with_sprite(layer, sprite));
|
||||
layerCopy->displaceFrames(0, m_frame);
|
||||
|
||||
write_layer(m_stream, layerCopy.get());
|
||||
|
||||
storeDroppedLayerIds(layerCopy.get());
|
||||
}
|
||||
size_t end = m_stream.tellp();
|
||||
m_size += end - start;
|
||||
}
|
||||
|
||||
void DropOnTimeline::insertDroppedLayers()
|
||||
{
|
||||
// Layer used as a reference to determine if the dropped layers will be
|
||||
// inserted after or before it.
|
||||
Layer* refLayer = nullptr;
|
||||
// Parent group of the reference layer layer.
|
||||
LayerGroup* group = nullptr;
|
||||
// Keep track of the current insertion point.
|
||||
InsertionPoint insert = m_insert;
|
||||
|
||||
setupInsertionLayer(refLayer, group);
|
||||
|
||||
SubObjectsFromSprite io(group->sprite());
|
||||
m_stream.seekg(0);
|
||||
auto nLayers = read32(m_stream);
|
||||
for (int i = 0; i < nLayers; ++i) {
|
||||
auto* layer = read_layer(m_stream, &io);
|
||||
|
||||
if (!refLayer) {
|
||||
group->addLayer(layer);
|
||||
refLayer = layer;
|
||||
insert = InsertionPoint::AfterLayer;
|
||||
}
|
||||
else if (insert == InsertionPoint::AfterLayer) {
|
||||
group->insertLayer(layer, refLayer);
|
||||
refLayer = layer;
|
||||
}
|
||||
else if (insert == InsertionPoint::BeforeLayer) {
|
||||
group->insertLayerBefore(layer, refLayer);
|
||||
refLayer = layer;
|
||||
insert = InsertionPoint::AfterLayer;
|
||||
}
|
||||
|
||||
group->incrementVersion();
|
||||
group->sprite()->incrementVersion();
|
||||
|
||||
Doc* doc = static_cast<Doc*>(group->sprite()->document());
|
||||
DocEvent ev(doc);
|
||||
ev.sprite(group->sprite());
|
||||
ev.layer(layer);
|
||||
doc->notify_observers<DocEvent&>(&DocObserver::onAddLayer, ev);
|
||||
}
|
||||
}
|
||||
|
||||
// Returns true if the document srcDoc has a cel that can be moved.
|
||||
// The cel from the srcDoc can be moved only when all of the following
|
||||
// conditions are met:
|
||||
// * Drop took place in a cel.
|
||||
// * Source doc has only one layer with just one frame.
|
||||
// * The layer from the source doc and the destination cel's layer are both
|
||||
// Image layers.
|
||||
// Otherwise this function returns false.
|
||||
bool DropOnTimeline::canMoveCelFrom(app::Doc* srcDoc)
|
||||
{
|
||||
auto* srcLayer = srcDoc->sprite()->firstLayer();
|
||||
auto* destLayer = document()->sprite()->allLayers()[m_layerIndex];
|
||||
return m_droppedOn == DroppedOn::Cel && srcDoc->sprite()->allLayersCount() == 1 &&
|
||||
srcDoc->sprite()->totalFrames() == 1 && srcLayer->isImage() && destLayer->isImage();
|
||||
}
|
||||
|
||||
void DropOnTimeline::notifyGeneralUpdate()
|
||||
{
|
||||
Doc* doc = document();
|
||||
if (!doc)
|
||||
return;
|
||||
|
||||
doc->notifyGeneralUpdate();
|
||||
}
|
||||
|
||||
}} // namespace app::cmd
|
|
@ -1,95 +0,0 @@
|
|||
// Aseprite
|
||||
// Copyright (C) 2024 Igara Studio S.A.
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
|
||||
#ifndef APP_CMD_drop_on_timeline_H_INCLUDED
|
||||
#define APP_CMD_drop_on_timeline_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "app/cmd/with_document.h"
|
||||
#include "app/cmd_sequence.h"
|
||||
#include "app/doc_observer.h"
|
||||
#include "base/paths.h"
|
||||
#include "doc/frame.h"
|
||||
#include "doc/image_ref.h"
|
||||
#include "doc/layer.h"
|
||||
#include "doc/layer_list.h"
|
||||
|
||||
namespace app { namespace cmd {
|
||||
|
||||
class DropOnTimeline : public CmdSequence,
|
||||
public WithDocument {
|
||||
public:
|
||||
enum class InsertionPoint {
|
||||
BeforeLayer,
|
||||
AfterLayer,
|
||||
};
|
||||
|
||||
enum class DroppedOn {
|
||||
Unspecified,
|
||||
Frame,
|
||||
Layer,
|
||||
Cel,
|
||||
};
|
||||
|
||||
// Inserts the layers and frames of the documents pointed by the specified
|
||||
// paths, at the specified frame and before or after the specified layer index.
|
||||
DropOnTimeline(app::Doc* doc,
|
||||
doc::frame_t frame,
|
||||
doc::layer_t layerIndex,
|
||||
InsertionPoint insert,
|
||||
DroppedOn droppedOn,
|
||||
const base::paths& paths);
|
||||
|
||||
// Inserts the image as if it were a document with just one layer and one
|
||||
// frame, at the specified frame and before or after the specified layer index.
|
||||
DropOnTimeline(app::Doc* doc,
|
||||
doc::frame_t frame,
|
||||
doc::layer_t layerIndex,
|
||||
InsertionPoint insert,
|
||||
DroppedOn droppedOn,
|
||||
const doc::ImageRef& image);
|
||||
|
||||
protected:
|
||||
void onExecute() override;
|
||||
void onUndo() override;
|
||||
void onRedo() override;
|
||||
size_t onMemSize() const override { return sizeof(*this) + m_size; }
|
||||
|
||||
private:
|
||||
void setupInsertionLayer(doc::Layer*& layer, doc::LayerGroup*& group);
|
||||
void insertDroppedLayers();
|
||||
bool canMoveCelFrom(app::Doc* srcDoc);
|
||||
void notifyGeneralUpdate();
|
||||
bool hasPendingWork();
|
||||
// Returns the next document to be processed.
|
||||
// Returns false when the user cancelled the process, or true when the
|
||||
// process must go on.
|
||||
bool getNextDoc(std::unique_ptr<Doc>& srcDoc);
|
||||
bool getNextDocFromImage(std::unique_ptr<Doc>& srcDoc);
|
||||
bool getNextDocFromPaths(std::unique_ptr<Doc>& srcDoc);
|
||||
|
||||
void storeDroppedLayerIds(const doc::Layer* layer);
|
||||
void saveDroppedLayers(const doc::LayerList& layers, doc::Sprite* sprite);
|
||||
|
||||
size_t m_size;
|
||||
base::paths m_paths;
|
||||
doc::ImageRef m_image = nullptr;
|
||||
doc::frame_t m_frame;
|
||||
doc::layer_t m_layerIndex;
|
||||
InsertionPoint m_insert;
|
||||
DroppedOn m_droppedOn;
|
||||
// Serialized dropped layers' data. Used for redo operation.
|
||||
std::stringstream m_stream;
|
||||
// Holds the Object IDs of the dropped layers. Used when determining which
|
||||
// layers should be removed in an undo operation.
|
||||
std::vector<doc::ObjectId> m_droppedLayersIds;
|
||||
// Number of frames the doc had before dropping.
|
||||
doc::frame_t m_previousTotalFrames;
|
||||
};
|
||||
|
||||
}} // namespace app::cmd
|
||||
|
||||
#endif
|
|
@ -1,5 +1,5 @@
|
|||
// Aseprite
|
||||
// Copyright (C) 2020-2024 Igara Studio S.A.
|
||||
// Copyright (C) 2020-2025 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
|
@ -11,12 +11,12 @@
|
|||
|
||||
#include "app/app.h"
|
||||
#include "app/commands/command.h"
|
||||
#include "app/modules/gui.h"
|
||||
#include "app/ui/main_window.h"
|
||||
#include "fmt/format.h"
|
||||
#include "ver/info.h"
|
||||
|
||||
#include "about.xml.h"
|
||||
#include "app/context.h"
|
||||
|
||||
namespace app {
|
||||
|
||||
|
@ -27,13 +27,19 @@ public:
|
|||
AboutCommand();
|
||||
|
||||
protected:
|
||||
bool onEnabled(Context* context) override;
|
||||
void onExecute(Context* context) override;
|
||||
};
|
||||
|
||||
AboutCommand::AboutCommand() : Command(CommandId::About(), CmdUIOnlyFlag)
|
||||
AboutCommand::AboutCommand() : Command(CommandId::About())
|
||||
{
|
||||
}
|
||||
|
||||
bool AboutCommand::onEnabled(Context* context)
|
||||
{
|
||||
return context->isUIAvailable();
|
||||
}
|
||||
|
||||
void AboutCommand::onExecute(Context* context)
|
||||
{
|
||||
gen::About window;
|
||||
|
@ -44,7 +50,7 @@ void AboutCommand::onExecute(Context* context)
|
|||
});
|
||||
window.credits()->Click.connect([&window] {
|
||||
window.closeWindow(nullptr);
|
||||
App::instance()->mainWindow()->showBrowser("README.md", "Authors");
|
||||
App::instance()->mainWindow()->showBrowser("AUTHORS.md", "Authors");
|
||||
});
|
||||
window.i18nCredits()->Click.connect([&window] {
|
||||
window.closeWindow(nullptr);
|
||||
|
|
|
@ -63,8 +63,7 @@ protected:
|
|||
std::string onGetFriendlyName() const override;
|
||||
};
|
||||
|
||||
AddColorCommand::AddColorCommand()
|
||||
: CommandWithNewParams<AddColorParams>(CommandId::AddColor(), CmdUIOnlyFlag)
|
||||
AddColorCommand::AddColorCommand() : CommandWithNewParams<AddColorParams>(CommandId::AddColor())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// Aseprite
|
||||
// Copyright (C) 2025 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
|
@ -16,8 +17,7 @@
|
|||
#include "ui/ui.h"
|
||||
|
||||
#include "advanced_mode.xml.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include "app/context.h"
|
||||
|
||||
namespace app {
|
||||
|
||||
|
@ -28,13 +28,19 @@ public:
|
|||
AdvancedModeCommand();
|
||||
|
||||
protected:
|
||||
bool onEnabled(Context* context) override;
|
||||
void onExecute(Context* context) override;
|
||||
};
|
||||
|
||||
AdvancedModeCommand::AdvancedModeCommand() : Command(CommandId::AdvancedMode(), CmdUIOnlyFlag)
|
||||
AdvancedModeCommand::AdvancedModeCommand() : Command(CommandId::AdvancedMode())
|
||||
{
|
||||
}
|
||||
|
||||
bool AdvancedModeCommand::onEnabled(Context* context)
|
||||
{
|
||||
return context->isUIAvailable();
|
||||
}
|
||||
|
||||
void AdvancedModeCommand::onExecute(Context* context)
|
||||
{
|
||||
// Switch advanced mode.
|
||||
|
@ -54,11 +60,11 @@ void AdvancedModeCommand::onExecute(Context* context)
|
|||
|
||||
if (oldMode == MainWindow::NormalMode && pref.advancedMode.showAlert()) {
|
||||
KeyPtr key = KeyboardShortcuts::instance()->command(this->id().c_str());
|
||||
if (!key->accels().empty()) {
|
||||
if (!key->shortcuts().empty()) {
|
||||
app::gen::AdvancedMode window;
|
||||
|
||||
window.warningLabel()->setTextf("You can go back pressing \"%s\" key.",
|
||||
key->accels().front().toString().c_str());
|
||||
key->shortcuts().front().toString().c_str());
|
||||
|
||||
window.openWindowInForeground();
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include "app/modules/gui.h"
|
||||
#include "app/tx.h"
|
||||
#include "doc/layer.h"
|
||||
#include "doc/sprite.h"
|
||||
|
||||
namespace app {
|
||||
|
||||
|
@ -28,8 +27,7 @@ protected:
|
|||
void onExecute(Context* context) override;
|
||||
};
|
||||
|
||||
BackgroundFromLayerCommand::BackgroundFromLayerCommand()
|
||||
: Command(CommandId::BackgroundFromLayer(), CmdRecordableFlag)
|
||||
BackgroundFromLayerCommand::BackgroundFromLayerCommand() : Command(CommandId::BackgroundFromLayer())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ private:
|
|||
Type m_type;
|
||||
};
|
||||
|
||||
CancelCommand::CancelCommand() : Command(CommandId::Cancel(), CmdUIOnlyFlag), m_type(NoOp)
|
||||
CancelCommand::CancelCommand() : Command(CommandId::Cancel()), m_type(NoOp)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#include "app/ui/skin/skin_theme.h"
|
||||
#include "app/ui_context.h"
|
||||
#include "doc/image.h"
|
||||
#include "doc/mask.h"
|
||||
#include "doc/sprite.h"
|
||||
#include "ui/ui.h"
|
||||
|
||||
|
@ -282,8 +281,7 @@ protected:
|
|||
void onExecute(Context* context) override;
|
||||
};
|
||||
|
||||
CanvasSizeCommand::CanvasSizeCommand()
|
||||
: CommandWithNewParams(CommandId::CanvasSize(), CmdRecordableFlag)
|
||||
CanvasSizeCommand::CanvasSizeCommand() : CommandWithNewParams(CommandId::CanvasSize())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -20,8 +20,6 @@
|
|||
#include "app/tx.h"
|
||||
#include "app/ui/timeline/timeline.h"
|
||||
#include "doc/cel.h"
|
||||
#include "doc/cels_range.h"
|
||||
#include "doc/sprite.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
|
@ -42,7 +40,7 @@ private:
|
|||
int m_opacity;
|
||||
};
|
||||
|
||||
CelOpacityCommand::CelOpacityCommand() : Command(CommandId::CelOpacity(), CmdUIOnlyFlag)
|
||||
CelOpacityCommand::CelOpacityCommand() : Command(CommandId::CelOpacity())
|
||||
{
|
||||
m_opacity = 255;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include "app/ui/timeline/timeline.h"
|
||||
#include "app/ui/user_data_view.h"
|
||||
#include "app/ui_context.h"
|
||||
#include "base/mem_utils.h"
|
||||
#include "base/scoped_value.h"
|
||||
#include "doc/cel.h"
|
||||
#include "doc/cels_range.h"
|
||||
|
@ -385,14 +384,14 @@ protected:
|
|||
void onExecute(Context* context) override;
|
||||
};
|
||||
|
||||
CelPropertiesCommand::CelPropertiesCommand() : Command(CommandId::CelProperties(), CmdUIOnlyFlag)
|
||||
CelPropertiesCommand::CelPropertiesCommand() : Command(CommandId::CelProperties())
|
||||
{
|
||||
}
|
||||
|
||||
bool CelPropertiesCommand::onEnabled(Context* context)
|
||||
{
|
||||
return context->checkFlags(ContextFlags::ActiveDocumentIsWritable |
|
||||
ContextFlags::ActiveLayerIsImage);
|
||||
return context->isUIAvailable() && context->checkFlags(ContextFlags::ActiveDocumentIsWritable |
|
||||
ContextFlags::ActiveLayerIsImage);
|
||||
}
|
||||
|
||||
void CelPropertiesCommand::onExecute(Context* context)
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include "app/tools/tool.h"
|
||||
#include "app/ui/context_bar.h"
|
||||
#include "app/ui/main_window.h"
|
||||
#include "base/convert_to.h"
|
||||
#include "doc/algorithm/flip_image.h"
|
||||
#include "doc/brush.h"
|
||||
#include "doc/image_ref.h"
|
||||
|
@ -64,7 +63,7 @@ private:
|
|||
int m_slot;
|
||||
};
|
||||
|
||||
ChangeBrushCommand::ChangeBrushCommand() : Command(CommandId::ChangeBrush(), CmdUIOnlyFlag)
|
||||
ChangeBrushCommand::ChangeBrushCommand() : Command(CommandId::ChangeBrush())
|
||||
{
|
||||
m_change = None;
|
||||
m_slot = 0;
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "app/app.h"
|
||||
#include "app/commands/command.h"
|
||||
#include "app/commands/params.h"
|
||||
#include "app/context.h"
|
||||
#include "app/i18n/strings.h"
|
||||
#include "app/modules/palettes.h"
|
||||
#include "app/ui/color_bar.h"
|
||||
|
@ -39,18 +40,24 @@ public:
|
|||
ChangeColorCommand();
|
||||
|
||||
protected:
|
||||
bool onEnabled(Context* context) override;
|
||||
bool onNeedsParams() const override { return true; }
|
||||
void onLoadParams(const Params& params) override;
|
||||
void onExecute(Context* context) override;
|
||||
std::string onGetFriendlyName() const override;
|
||||
};
|
||||
|
||||
ChangeColorCommand::ChangeColorCommand() : Command(CommandId::ChangeColor(), CmdUIOnlyFlag)
|
||||
ChangeColorCommand::ChangeColorCommand() : Command(CommandId::ChangeColor())
|
||||
{
|
||||
m_background = false;
|
||||
m_change = None;
|
||||
}
|
||||
|
||||
bool ChangeColorCommand::onEnabled(Context* context)
|
||||
{
|
||||
return context->isUIAvailable();
|
||||
}
|
||||
|
||||
void ChangeColorCommand::onLoadParams(const Params& params)
|
||||
{
|
||||
std::string target = params.get("target");
|
||||
|
|
|
@ -21,9 +21,7 @@
|
|||
#include "app/i18n/strings.h"
|
||||
#include "app/load_matrix.h"
|
||||
#include "app/modules/gui.h"
|
||||
#include "app/modules/palettes.h"
|
||||
#include "app/sprite_job.h"
|
||||
#include "app/transaction.h"
|
||||
#include "app/ui/best_fit_criteria_selector.h"
|
||||
#include "app/ui/dithering_selector.h"
|
||||
#include "app/ui/editor/editor.h"
|
||||
|
@ -37,12 +35,10 @@
|
|||
#include "fmt/format.h"
|
||||
#include "render/dithering.h"
|
||||
#include "render/dithering_algorithm.h"
|
||||
#include "render/ordered_dither.h"
|
||||
#include "render/quantization.h"
|
||||
#include "render/render.h"
|
||||
#include "render/task_delegate.h"
|
||||
#include "ui/listitem.h"
|
||||
#include "ui/paint_event.h"
|
||||
#include "ui/size_hint_event.h"
|
||||
|
||||
#include "color_mode.xml.h"
|
||||
|
@ -507,7 +503,7 @@ private:
|
|||
};
|
||||
|
||||
ChangePixelFormatCommand::ChangePixelFormatCommand()
|
||||
: CommandWithNewParams(CommandId::ChangePixelFormat(), CmdUIOnlyFlag)
|
||||
: CommandWithNewParams(CommandId::ChangePixelFormat())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ protected:
|
|||
void onExecute(Context* ctx) override;
|
||||
};
|
||||
|
||||
ClearCommand::ClearCommand() : Command(CommandId::Clear(), CmdUIOnlyFlag)
|
||||
ClearCommand::ClearCommand() : Command(CommandId::Clear())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include "app/ui/status_bar.h"
|
||||
#include "doc/cel.h"
|
||||
#include "doc/layer.h"
|
||||
#include "doc/sprite.h"
|
||||
|
||||
namespace app {
|
||||
|
||||
|
@ -32,7 +31,7 @@ protected:
|
|||
void onExecute(Context* context) override;
|
||||
};
|
||||
|
||||
ClearCelCommand::ClearCelCommand() : Command(CommandId::ClearCel(), CmdRecordableFlag)
|
||||
ClearCelCommand::ClearCelCommand() : Command(CommandId::ClearCel())
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -76,7 +75,7 @@ void ClearCelCommand::onExecute(Context* context)
|
|||
tx.commit();
|
||||
}
|
||||
|
||||
if (nonEditableLayers)
|
||||
if (context->isUIAvailable() && nonEditableLayers)
|
||||
StatusBar::instance()->showTip(1000, Strings::statusbar_tips_locked_layers());
|
||||
|
||||
update_screen_for_document(document);
|
||||
|
|
|
@ -23,8 +23,7 @@ protected:
|
|||
void onExecute(Context* ctx) override;
|
||||
};
|
||||
|
||||
ClearRecentFilesCommand::ClearRecentFilesCommand()
|
||||
: Command(CommandId::ClearRecentFiles(), CmdUIOnlyFlag)
|
||||
ClearRecentFilesCommand::ClearRecentFilesCommand() : Command(CommandId::ClearRecentFiles())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -12,15 +12,9 @@
|
|||
#include "app/app.h"
|
||||
#include "app/commands/command.h"
|
||||
#include "app/commands/commands.h"
|
||||
#include "app/context_access.h"
|
||||
#include "app/ui/doc_view.h"
|
||||
#include "app/ui/status_bar.h"
|
||||
#include "app/ui/workspace.h"
|
||||
#include "app/ui_context.h"
|
||||
#include "doc/sprite.h"
|
||||
#include "ui/ui.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace app {
|
||||
|
||||
|
@ -28,7 +22,7 @@ using namespace ui;
|
|||
|
||||
class CloseFileCommand : public Command {
|
||||
public:
|
||||
CloseFileCommand() : Command(CommandId::CloseFile(), CmdUIOnlyFlag) {}
|
||||
CloseFileCommand() : Command(CommandId::CloseFile()) {}
|
||||
|
||||
protected:
|
||||
bool onEnabled(Context* context) override
|
||||
|
@ -51,12 +45,15 @@ protected:
|
|||
|
||||
class CloseAllFilesCommand : public Command {
|
||||
public:
|
||||
CloseAllFilesCommand() : Command(CommandId::CloseAllFiles(), CmdRecordableFlag)
|
||||
{
|
||||
m_quitting = false;
|
||||
}
|
||||
CloseAllFilesCommand() : Command(CommandId::CloseAllFiles()) { m_quitting = false; }
|
||||
|
||||
protected:
|
||||
bool onEnabled(Context* context) override
|
||||
{
|
||||
// Null if we are in --batch mode
|
||||
return App::instance()->workspace() != nullptr;
|
||||
}
|
||||
|
||||
void onLoadParams(const Params& params) override { m_quitting = params.get_as<bool>("quitting"); }
|
||||
|
||||
void onExecute(Context* context) override
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include "app/transaction.h"
|
||||
#include "app/ui/color_bar.h"
|
||||
#include "app/ui/rgbmap_algorithm_selector.h"
|
||||
#include "app/ui_context.h"
|
||||
#include "doc/palette.h"
|
||||
#include "doc/sprite.h"
|
||||
#include "render/quantization.h"
|
||||
|
@ -71,7 +70,7 @@ protected:
|
|||
};
|
||||
|
||||
ColorQuantizationCommand::ColorQuantizationCommand()
|
||||
: CommandWithNewParams<ColorQuantizationParams>(CommandId::ColorQuantization(), CmdRecordableFlag)
|
||||
: CommandWithNewParams<ColorQuantizationParams>(CommandId::ColorQuantization())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ protected:
|
|||
void onExecute(Context* context) override;
|
||||
};
|
||||
|
||||
ContiguousFillCommand::ContiguousFillCommand() : Command(CommandId::ContiguousFill(), CmdUIOnlyFlag)
|
||||
ContiguousFillCommand::ContiguousFillCommand() : Command(CommandId::ContiguousFill())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ protected:
|
|||
void onExecute(Context* ctx) override;
|
||||
};
|
||||
|
||||
CopyCommand::CopyCommand() : Command(CommandId::Copy(), CmdUIOnlyFlag)
|
||||
CopyCommand::CopyCommand() : Command(CommandId::Copy())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -10,9 +10,7 @@
|
|||
|
||||
#include "app/app.h"
|
||||
#include "app/commands/command.h"
|
||||
#include "app/context_access.h"
|
||||
#include "app/ui/timeline/timeline.h"
|
||||
#include "ui/base.h"
|
||||
|
||||
namespace app {
|
||||
|
||||
|
@ -25,13 +23,13 @@ protected:
|
|||
void onExecute(Context* context) override;
|
||||
};
|
||||
|
||||
CopyCelCommand::CopyCelCommand() : Command(CommandId::CopyCel(), CmdUIOnlyFlag)
|
||||
CopyCelCommand::CopyCelCommand() : Command(CommandId::CopyCel())
|
||||
{
|
||||
}
|
||||
|
||||
bool CopyCelCommand::onEnabled(Context* context)
|
||||
{
|
||||
return App::instance()->timeline()->isMovingCel();
|
||||
return App::instance()->timeline() && App::instance()->timeline()->isMovingCel();
|
||||
}
|
||||
|
||||
void CopyCelCommand::onExecute(Context* context)
|
||||
|
|
|
@ -24,7 +24,7 @@ protected:
|
|||
void onExecute(Context* ctx) override;
|
||||
};
|
||||
|
||||
CopyMergedCommand::CopyMergedCommand() : Command(CommandId::CopyMerged(), CmdUIOnlyFlag)
|
||||
CopyMergedCommand::CopyMergedCommand() : Command(CommandId::CopyMerged())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -16,11 +16,7 @@
|
|||
#include "app/modules/gui.h"
|
||||
#include "app/tx.h"
|
||||
#include "app/ui/color_bar.h"
|
||||
#include "app/util/autocrop.h"
|
||||
#include "doc/image.h"
|
||||
#include "doc/layer.h"
|
||||
#include "doc/mask.h"
|
||||
#include "doc/sprite.h"
|
||||
|
||||
namespace app {
|
||||
|
||||
|
@ -37,7 +33,7 @@ private:
|
|||
gfx::Rect m_bounds;
|
||||
};
|
||||
|
||||
CropSpriteCommand::CropSpriteCommand() : Command(CommandId::CropSprite(), CmdRecordableFlag)
|
||||
CropSpriteCommand::CropSpriteCommand() : Command(CommandId::CropSprite())
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -95,8 +91,7 @@ private:
|
|||
bool m_byGrid = false;
|
||||
};
|
||||
|
||||
AutocropSpriteCommand::AutocropSpriteCommand()
|
||||
: Command(CommandId::AutocropSprite(), CmdRecordableFlag)
|
||||
AutocropSpriteCommand::AutocropSpriteCommand() : Command(CommandId::AutocropSprite())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ protected:
|
|||
void onExecute(Context* ctx) override;
|
||||
};
|
||||
|
||||
CutCommand::CutCommand() : Command(CommandId::Cut(), CmdUIOnlyFlag)
|
||||
CutCommand::CutCommand() : Command(CommandId::Cut())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -14,8 +14,6 @@
|
|||
#include "app/context_access.h"
|
||||
#include "app/modules/gui.h"
|
||||
#include "app/tx.h"
|
||||
#include "doc/mask.h"
|
||||
#include "doc/sprite.h"
|
||||
|
||||
namespace app {
|
||||
|
||||
|
@ -28,7 +26,7 @@ protected:
|
|||
void onExecute(Context* context) override;
|
||||
};
|
||||
|
||||
DeselectMaskCommand::DeselectMaskCommand() : Command(CommandId::DeselectMask(), CmdRecordableFlag)
|
||||
DeselectMaskCommand::DeselectMaskCommand() : Command(CommandId::DeselectMask())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -29,8 +29,7 @@ protected:
|
|||
void onExecute(Context* context);
|
||||
};
|
||||
|
||||
DeveloperConsoleCommand::DeveloperConsoleCommand()
|
||||
: Command(CommandId::DeveloperConsole(), CmdUIOnlyFlag)
|
||||
DeveloperConsoleCommand::DeveloperConsoleCommand() : Command(CommandId::DeveloperConsole())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -12,8 +12,6 @@
|
|||
#include "app/app.h"
|
||||
#include "app/commands/command.h"
|
||||
#include "app/commands/commands.h"
|
||||
#include "app/context_access.h"
|
||||
#include "app/tools/tool_box.h"
|
||||
#include "app/ui/context_bar.h"
|
||||
#include "app/ui_context.h"
|
||||
|
||||
|
@ -28,12 +26,15 @@ protected:
|
|||
void onExecute(Context* context) override;
|
||||
};
|
||||
|
||||
DiscardBrushCommand::DiscardBrushCommand() : Command(CommandId::DiscardBrush(), CmdUIOnlyFlag)
|
||||
DiscardBrushCommand::DiscardBrushCommand() : Command(CommandId::DiscardBrush())
|
||||
{
|
||||
}
|
||||
|
||||
bool DiscardBrushCommand::onEnabled(Context* context)
|
||||
{
|
||||
if (!context->isUIAvailable())
|
||||
return false;
|
||||
|
||||
ContextBar* ctxBar = App::instance()->contextBar();
|
||||
return (ctxBar->activeBrush()->type() == kImageBrushType);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Aseprite
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
// Copyright (C) 2001-2025 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
|
@ -10,16 +10,11 @@
|
|||
|
||||
#include "app/app.h"
|
||||
#include "app/commands/command.h"
|
||||
#include "app/console.h"
|
||||
#include "app/context_access.h"
|
||||
#include "app/doc_api.h"
|
||||
#include "app/doc_undo.h"
|
||||
#include "app/modules/gui.h"
|
||||
#include "app/tx.h"
|
||||
#include "app/ui/editor/editor.h"
|
||||
#include "doc/layer.h"
|
||||
#include "doc/sprite.h"
|
||||
#include "ui/ui.h"
|
||||
|
||||
namespace app {
|
||||
|
||||
|
@ -32,8 +27,7 @@ protected:
|
|||
void onExecute(Context* context) override;
|
||||
};
|
||||
|
||||
DuplicateLayerCommand::DuplicateLayerCommand()
|
||||
: Command(CommandId::DuplicateLayer(), CmdRecordableFlag)
|
||||
DuplicateLayerCommand::DuplicateLayerCommand() : Command(CommandId::DuplicateLayer())
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -51,7 +45,7 @@ void DuplicateLayerCommand::onExecute(Context* context)
|
|||
Tx tx(writer, "Layer Duplication");
|
||||
LayerImage* sourceLayer = static_cast<LayerImage*>(writer.layer());
|
||||
DocApi api = document->getApi(tx);
|
||||
api.duplicateLayerAfter(sourceLayer, sourceLayer->parent(), sourceLayer);
|
||||
api.duplicateLayerAfter(sourceLayer, sourceLayer->parent(), sourceLayer, " Copy");
|
||||
tx.commit();
|
||||
}
|
||||
|
||||
|
|
|
@ -16,13 +16,10 @@
|
|||
#include "app/ini_file.h"
|
||||
#include "app/ui_context.h"
|
||||
#include "base/fs.h"
|
||||
#include "doc/sprite.h"
|
||||
#include "ui/ui.h"
|
||||
|
||||
#include "duplicate_sprite.xml.h"
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
namespace app {
|
||||
|
||||
using namespace ui;
|
||||
|
@ -43,7 +40,7 @@ protected:
|
|||
};
|
||||
|
||||
DuplicateSpriteCommand::DuplicateSpriteCommand()
|
||||
: CommandWithNewParams<DuplicateSpriteParams>(CommandId::DuplicateSprite(), CmdRecordableFlag)
|
||||
: CommandWithNewParams<DuplicateSpriteParams>(CommandId::DuplicateSprite())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -13,8 +13,6 @@
|
|||
#include "app/commands/command.h"
|
||||
#include "app/ui/workspace.h"
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
namespace app {
|
||||
|
||||
// using namespace ui;
|
||||
|
@ -28,7 +26,7 @@ protected:
|
|||
void onExecute(Context* context) override;
|
||||
};
|
||||
|
||||
DuplicateViewCommand::DuplicateViewCommand() : Command(CommandId::DuplicateView(), CmdUIOnlyFlag)
|
||||
DuplicateViewCommand::DuplicateViewCommand() : Command(CommandId::DuplicateView())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
// the End-User License Agreement for Aseprite.
|
||||
|
||||
#include "app/commands/command.h"
|
||||
#include "app/context.h"
|
||||
|
||||
#ifdef ENABLE_DRM
|
||||
#include "app/ui/enter_license.h"
|
||||
|
@ -24,7 +23,7 @@ protected:
|
|||
void onExecute(Context* context) override;
|
||||
};
|
||||
|
||||
EnterLicenseCommand::EnterLicenseCommand() : Command(CommandId::EnterLicense(), CmdUIOnlyFlag)
|
||||
EnterLicenseCommand::EnterLicenseCommand() : Command(CommandId::EnterLicense())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#include "app/doc.h"
|
||||
#include "app/job.h"
|
||||
#include "app/ui/main_window.h"
|
||||
#include "ui/alert.h"
|
||||
|
||||
#ifdef ENABLE_SCRIPTING
|
||||
#include "app/commands/debugger.h"
|
||||
|
@ -32,7 +31,7 @@ protected:
|
|||
void onExecute(Context* context) override;
|
||||
};
|
||||
|
||||
ExitCommand::ExitCommand() : Command(CommandId::Exit(), CmdUIOnlyFlag)
|
||||
ExitCommand::ExitCommand() : Command(CommandId::Exit())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -33,15 +33,12 @@
|
|||
#include "app/ui/status_bar.h"
|
||||
#include "app/ui/timeline/timeline.h"
|
||||
#include "app/util/layer_utils.h"
|
||||
#include "base/convert_to.h"
|
||||
#include "base/fs.h"
|
||||
#include "base/string.h"
|
||||
#include "base/thread.h"
|
||||
#include "doc/layer.h"
|
||||
#include "doc/layer_tilemap.h"
|
||||
#include "doc/tag.h"
|
||||
#include "doc/tileset.h"
|
||||
#include "doc/tilesets.h"
|
||||
#include "fmt/format.h"
|
||||
#include "ui/message.h"
|
||||
#include "ui/system.h"
|
||||
|
@ -1187,8 +1184,7 @@ private:
|
|||
|
||||
} // anonymous namespace
|
||||
|
||||
ExportSpriteSheetCommand::ExportSpriteSheetCommand(const char* id)
|
||||
: CommandWithNewParams(id, CmdRecordableFlag)
|
||||
ExportSpriteSheetCommand::ExportSpriteSheetCommand(const char* id) : CommandWithNewParams(id)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
#include "app/context.h"
|
||||
#include "app/pref/preferences.h"
|
||||
#include "app/site.h"
|
||||
#include "app/tools/tool.h"
|
||||
#include "app/tools/tool_box.h"
|
||||
#include "app/ui/color_bar.h"
|
||||
#include "app/ui/editor/editor.h"
|
||||
|
@ -28,7 +27,7 @@ namespace app {
|
|||
|
||||
using namespace ui;
|
||||
|
||||
EyedropperCommand::EyedropperCommand() : Command(CommandId::Eyedropper(), CmdUIOnlyFlag)
|
||||
EyedropperCommand::EyedropperCommand() : Command(CommandId::Eyedropper())
|
||||
{
|
||||
m_background = false;
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ private:
|
|||
};
|
||||
|
||||
FillCommand::FillCommand(Type type)
|
||||
: Command(type == Stroke ? CommandId::Stroke() : CommandId::Fill(), CmdUIOnlyFlag)
|
||||
: Command(type == Stroke ? CommandId::Stroke() : CommandId::Fill())
|
||||
, m_type(type)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
|
||||
#include "app/app.h"
|
||||
#include "app/commands/command.h"
|
||||
#include "app/context_access.h"
|
||||
#include "app/ui/editor/editor.h"
|
||||
|
||||
namespace app {
|
||||
|
@ -25,7 +24,7 @@ protected:
|
|||
void onExecute(Context* context) override;
|
||||
};
|
||||
|
||||
FitScreenCommand::FitScreenCommand() : Command(CommandId::FitScreen(), CmdUIOnlyFlag)
|
||||
FitScreenCommand::FitScreenCommand() : Command(CommandId::FitScreen())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ protected:
|
|||
bool m_visibleOnly;
|
||||
};
|
||||
|
||||
FlattenLayersCommand::FlattenLayersCommand() : Command(CommandId::FlattenLayers(), CmdUIOnlyFlag)
|
||||
FlattenLayersCommand::FlattenLayersCommand() : Command(CommandId::FlattenLayers())
|
||||
{
|
||||
m_visibleOnly = false;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
#include "app/commands/params.h"
|
||||
#include "app/context_access.h"
|
||||
#include "app/doc_api.h"
|
||||
#include "app/doc_range.h"
|
||||
#include "app/i18n/strings.h"
|
||||
#include "app/modules/gui.h"
|
||||
#include "app/tools/tool_box.h"
|
||||
|
@ -38,11 +37,10 @@
|
|||
#include "doc/layer.h"
|
||||
#include "doc/mask.h"
|
||||
#include "doc/sprite.h"
|
||||
#include "gfx/size.h"
|
||||
|
||||
namespace app {
|
||||
|
||||
FlipCommand::FlipCommand() : Command(CommandId::Flip(), CmdRecordableFlag)
|
||||
FlipCommand::FlipCommand() : Command(CommandId::Flip())
|
||||
{
|
||||
m_flipMask = false;
|
||||
m_flipType = doc::algorithm::FlipHorizontal;
|
||||
|
|
|
@ -44,12 +44,11 @@ private:
|
|||
|
||||
// Frame to be shown. It can be ALL_FRAMES, CURRENT_RANGE, or a
|
||||
// number indicating a specific frame (1 is the first frame).
|
||||
Target m_target;
|
||||
frame_t m_frame;
|
||||
Target m_target = CURRENT_RANGE;
|
||||
frame_t m_frame = 1;
|
||||
};
|
||||
|
||||
FramePropertiesCommand::FramePropertiesCommand()
|
||||
: Command(CommandId::FrameProperties(), CmdUIOnlyFlag)
|
||||
FramePropertiesCommand::FramePropertiesCommand() : Command(CommandId::FrameProperties())
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -59,7 +58,7 @@ void FramePropertiesCommand::onLoadParams(const Params& params)
|
|||
if (frame == "all") {
|
||||
m_target = ALL_FRAMES;
|
||||
}
|
||||
else if (frame == "current") {
|
||||
else if (frame == "current" || !params.has_param("frame")) {
|
||||
m_target = CURRENT_RANGE;
|
||||
}
|
||||
else {
|
||||
|
@ -70,7 +69,7 @@ void FramePropertiesCommand::onLoadParams(const Params& params)
|
|||
|
||||
bool FramePropertiesCommand::onEnabled(Context* context)
|
||||
{
|
||||
return context->checkFlags(ContextFlags::ActiveDocumentIsWritable);
|
||||
return context->isUIAvailable() && context->checkFlags(ContextFlags::ActiveDocumentIsWritable);
|
||||
}
|
||||
|
||||
void FramePropertiesCommand::onExecute(Context* context)
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include "app/cmd/set_tag_range.h"
|
||||
#include "app/cmd/set_tag_repeat.h"
|
||||
#include "app/cmd/set_user_data.h"
|
||||
#include "app/color.h"
|
||||
#include "app/commands/command.h"
|
||||
#include "app/commands/params.h"
|
||||
#include "app/context_access.h"
|
||||
|
@ -48,7 +47,7 @@ private:
|
|||
};
|
||||
|
||||
FrameTagPropertiesCommand::FrameTagPropertiesCommand()
|
||||
: Command(CommandId::FrameTagProperties(), CmdUIOnlyFlag)
|
||||
: Command(CommandId::FrameTagProperties())
|
||||
, m_tagId(NullId)
|
||||
{
|
||||
}
|
||||
|
@ -66,7 +65,7 @@ void FrameTagPropertiesCommand::onLoadParams(const Params& params)
|
|||
|
||||
bool FrameTagPropertiesCommand::onEnabled(Context* context)
|
||||
{
|
||||
return context->checkFlags(ContextFlags::ActiveDocumentIsWritable);
|
||||
return context->isUIAvailable() && context->checkFlags(ContextFlags::ActiveDocumentIsWritable);
|
||||
}
|
||||
|
||||
void FrameTagPropertiesCommand::onExecute(Context* context)
|
||||
|
|
|
@ -27,7 +27,7 @@ protected:
|
|||
void onExecute(Context* context) override;
|
||||
};
|
||||
|
||||
FullscreenModeCommand::FullscreenModeCommand() : Command(CommandId::FullscreenMode(), CmdUIOnlyFlag)
|
||||
FullscreenModeCommand::FullscreenModeCommand() : Command(CommandId::FullscreenMode())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -23,10 +23,7 @@
|
|||
#include "app/ui/main_window.h"
|
||||
#include "app/ui/preview_editor.h"
|
||||
#include "app/ui/status_bar.h"
|
||||
#include "app/util/conversion_to_surface.h"
|
||||
#include "doc/image.h"
|
||||
#include "doc/palette.h"
|
||||
#include "doc/primitives.h"
|
||||
#include "doc/sprite.h"
|
||||
#include "gfx/matrix.h"
|
||||
#include "os/surface.h"
|
||||
|
@ -308,8 +305,7 @@ protected:
|
|||
void onExecute(Context* context) override;
|
||||
};
|
||||
|
||||
FullscreenPreviewCommand::FullscreenPreviewCommand()
|
||||
: Command(CommandId::FullscreenPreview(), CmdUIOnlyFlag)
|
||||
FullscreenPreviewCommand::FullscreenPreviewCommand() : Command(CommandId::FullscreenPreview())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ using namespace doc;
|
|||
|
||||
class GotoCommand : public Command {
|
||||
protected:
|
||||
GotoCommand(const char* id) : Command(id, CmdRecordableFlag) {}
|
||||
GotoCommand(const char* id) : Command(id) {}
|
||||
|
||||
bool onEnabled(Context* context) override { return (Editor::activeEditor() != nullptr); }
|
||||
|
||||
|
|
|
@ -24,11 +24,7 @@ namespace app {
|
|||
|
||||
class GotoLayerCommand : public Command {
|
||||
public:
|
||||
GotoLayerCommand(int offset, const char* id, CommandFlags flags)
|
||||
: Command(id, flags)
|
||||
, m_offset(offset)
|
||||
{
|
||||
}
|
||||
GotoLayerCommand(int offset, const char* id) : Command(id), m_offset(offset) {}
|
||||
|
||||
protected:
|
||||
bool onEnabled(Context* context) override
|
||||
|
@ -88,12 +84,12 @@ private:
|
|||
|
||||
class GotoPreviousLayerCommand : public GotoLayerCommand {
|
||||
public:
|
||||
GotoPreviousLayerCommand() : GotoLayerCommand(-1, "GotoPreviousLayer", CmdUIOnlyFlag) {}
|
||||
GotoPreviousLayerCommand() : GotoLayerCommand(-1, CommandId::GotoPreviousLayer()) {}
|
||||
};
|
||||
|
||||
class GotoNextLayerCommand : public GotoLayerCommand {
|
||||
public:
|
||||
GotoNextLayerCommand() : GotoLayerCommand(+1, "GotoNextLayer", CmdUIOnlyFlag) {}
|
||||
GotoNextLayerCommand() : GotoLayerCommand(+1, CommandId::GotoNextLayer()) {}
|
||||
};
|
||||
|
||||
Command* CommandFactory::createGotoPreviousLayerCommand()
|
||||
|
|
|
@ -24,7 +24,7 @@ protected:
|
|||
void onExecute(Context* context) override;
|
||||
};
|
||||
|
||||
GotoNextTabCommand::GotoNextTabCommand() : Command(CommandId::GotoNextTab(), CmdUIOnlyFlag)
|
||||
GotoNextTabCommand::GotoNextTabCommand() : Command(CommandId::GotoNextTab())
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -50,8 +50,7 @@ protected:
|
|||
void onExecute(Context* context) override;
|
||||
};
|
||||
|
||||
GotoPreviousTabCommand::GotoPreviousTabCommand()
|
||||
: Command(CommandId::GotoPreviousTab(), CmdRecordableFlag)
|
||||
GotoPreviousTabCommand::GotoPreviousTabCommand() : Command(CommandId::GotoPreviousTab())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -16,13 +16,9 @@
|
|||
#include "app/context.h"
|
||||
#include "app/context_access.h"
|
||||
#include "app/doc.h"
|
||||
#include "app/find_widget.h"
|
||||
#include "app/load_widget.h"
|
||||
#include "app/pref/preferences.h"
|
||||
#include "app/tx.h"
|
||||
#include "app/ui/status_bar.h"
|
||||
#include "app/ui_context.h"
|
||||
#include "doc/document.h"
|
||||
#include "doc/mask.h"
|
||||
#include "ui/window.h"
|
||||
|
||||
|
@ -37,7 +33,7 @@ using namespace gfx;
|
|||
|
||||
class SnapToGridCommand : public Command {
|
||||
public:
|
||||
SnapToGridCommand() : Command(CommandId::SnapToGrid(), CmdUIOnlyFlag) {}
|
||||
SnapToGridCommand() : Command(CommandId::SnapToGrid()) {}
|
||||
|
||||
protected:
|
||||
bool onChecked(Context* ctx) override
|
||||
|
@ -52,13 +48,14 @@ protected:
|
|||
bool newValue = !docPref.grid.snap();
|
||||
docPref.grid.snap(newValue);
|
||||
|
||||
StatusBar::instance()->showSnapToGridWarning(newValue);
|
||||
if (ctx->isUIAvailable())
|
||||
StatusBar::instance()->showSnapToGridWarning(newValue);
|
||||
}
|
||||
};
|
||||
|
||||
class SelectionAsGridCommand : public Command {
|
||||
public:
|
||||
SelectionAsGridCommand() : Command(CommandId::SelectionAsGrid(), CmdUIOnlyFlag) {}
|
||||
SelectionAsGridCommand() : Command(CommandId::SelectionAsGrid()) {}
|
||||
|
||||
protected:
|
||||
bool onEnabled(Context* ctx) override
|
||||
|
@ -93,13 +90,13 @@ protected:
|
|||
void onExecute(Context* context) override;
|
||||
};
|
||||
|
||||
GridSettingsCommand::GridSettingsCommand() : Command(CommandId::GridSettings(), CmdUIOnlyFlag)
|
||||
GridSettingsCommand::GridSettingsCommand() : Command(CommandId::GridSettings())
|
||||
{
|
||||
}
|
||||
|
||||
bool GridSettingsCommand::onEnabled(Context* context)
|
||||
{
|
||||
return true;
|
||||
return context->isUIAvailable();
|
||||
}
|
||||
|
||||
void GridSettingsCommand::onExecute(Context* context)
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include "app/app.h"
|
||||
#include "app/commands/command.h"
|
||||
#include "app/context.h"
|
||||
#include "app/ui/main_window.h"
|
||||
|
||||
namespace app {
|
||||
|
@ -26,7 +27,7 @@ protected:
|
|||
bool onEnabled(Context* context) override;
|
||||
};
|
||||
|
||||
HomeCommand::HomeCommand() : Command(CommandId::Home(), CmdUIOnlyFlag)
|
||||
HomeCommand::HomeCommand() : Command(CommandId::Home())
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -41,7 +42,7 @@ void HomeCommand::onExecute(Context* context)
|
|||
|
||||
bool HomeCommand::onEnabled(Context* context)
|
||||
{
|
||||
return !App::instance()->mainWindow()->isHomeSelected();
|
||||
return context->isUIAvailable() && !App::instance()->mainWindow()->isHomeSelected();
|
||||
}
|
||||
|
||||
Command* CommandFactory::createHomeCommand()
|
||||
|
|
|
@ -20,20 +20,14 @@
|
|||
#include "app/doc_api.h"
|
||||
#include "app/i18n/strings.h"
|
||||
#include "app/modules/gui.h"
|
||||
#include "app/modules/palettes.h"
|
||||
#include "app/pref/preferences.h"
|
||||
#include "app/tx.h"
|
||||
#include "app/ui/drop_down_button.h"
|
||||
#include "app/ui/editor/editor.h"
|
||||
#include "app/ui/editor/editor_decorator.h"
|
||||
#include "app/ui/editor/select_box_state.h"
|
||||
#include "app/ui/editor/standby_state.h"
|
||||
#include "app/ui/workspace.h"
|
||||
#include "doc/cel.h"
|
||||
#include "doc/image.h"
|
||||
#include "doc/layer.h"
|
||||
#include "doc/palette.h"
|
||||
#include "doc/primitives.h"
|
||||
#include "doc/sprite.h"
|
||||
#include "render/render.h"
|
||||
#include "ui/ui.h"
|
||||
|
@ -518,7 +512,7 @@ protected:
|
|||
};
|
||||
|
||||
ImportSpriteSheetCommand::ImportSpriteSheetCommand()
|
||||
: CommandWithNewParams(CommandId::ImportSpriteSheet(), CmdRecordableFlag)
|
||||
: CommandWithNewParams(CommandId::ImportSpriteSheet())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ protected:
|
|||
void onExecute(Context* context) override;
|
||||
};
|
||||
|
||||
InvertMaskCommand::InvertMaskCommand() : Command(CommandId::InvertMask(), CmdRecordableFlag)
|
||||
InvertMaskCommand::InvertMaskCommand() : Command(CommandId::InvertMask())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// Aseprite
|
||||
// Copyright (C) 2018-2024 Igara Studio S.A.
|
||||
// Copyright (C) 2018-2025 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
|
@ -23,25 +23,20 @@
|
|||
#include "app/ui/app_menuitem.h"
|
||||
#include "app/ui/keyboard_shortcuts.h"
|
||||
#include "app/ui/search_entry.h"
|
||||
#include "app/ui/select_accelerator.h"
|
||||
#include "app/ui/select_shortcut.h"
|
||||
#include "app/ui/separator_in_view.h"
|
||||
#include "app/ui/skin/skin_theme.h"
|
||||
#include "base/fs.h"
|
||||
#include "base/pi.h"
|
||||
#include "base/scoped_value.h"
|
||||
#include "base/split_string.h"
|
||||
#include "base/string.h"
|
||||
#include "ui/alert.h"
|
||||
#include "ui/fit_bounds.h"
|
||||
#include "ui/graphics.h"
|
||||
#include "ui/listitem.h"
|
||||
#include "ui/message.h"
|
||||
#include "ui/paint_event.h"
|
||||
#include "ui/resize_event.h"
|
||||
#include "ui/separator.h"
|
||||
#include "ui/size_hint_event.h"
|
||||
#include "ui/splitter.h"
|
||||
#include "ui/system.h"
|
||||
|
||||
#include "keyboard_shortcuts.xml.h"
|
||||
|
||||
|
@ -151,7 +146,7 @@ public:
|
|||
, m_keyOrig(key ? new Key(*key) : nullptr)
|
||||
, m_menuitem(menuitem)
|
||||
, m_level(level)
|
||||
, m_hotAccel(-1)
|
||||
, m_hotShortcut(-1)
|
||||
, m_lockButtons(false)
|
||||
, m_headerItem(headerItem)
|
||||
{
|
||||
|
@ -204,45 +199,45 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
void onChangeAccel(int index)
|
||||
void onChangeShortcut(int index)
|
||||
{
|
||||
LockButtons lock(this);
|
||||
Accelerator origAccel = m_key->accels()[index];
|
||||
SelectAccelerator window(origAccel, m_key->keycontext(), m_keys);
|
||||
Shortcut origShortcut = m_key->shortcuts()[index];
|
||||
SelectShortcut window(origShortcut, m_key->keycontext(), m_keys);
|
||||
window.openWindowInForeground();
|
||||
|
||||
if (window.isModified()) {
|
||||
m_key->disableAccel(origAccel, KeySource::UserDefined);
|
||||
if (!window.accel().isEmpty())
|
||||
m_key->add(window.accel(), KeySource::UserDefined, m_keys);
|
||||
m_key->disableShortcut(origShortcut, KeySource::UserDefined);
|
||||
if (!window.shortcut().isEmpty())
|
||||
m_key->add(window.shortcut(), KeySource::UserDefined, m_keys);
|
||||
}
|
||||
|
||||
this->window()->layout();
|
||||
}
|
||||
|
||||
void onDeleteAccel(int index)
|
||||
void onDeleteShortcut(int index)
|
||||
{
|
||||
LockButtons lock(this);
|
||||
// We need to create a copy of the accelerator because
|
||||
// Key::disableAccel() will modify the accels() collection itself.
|
||||
ui::Accelerator accel = m_key->accels()[index];
|
||||
// We need to create a copy of the shortcut because
|
||||
// Key::disableShortcut() will modify the shortcuts() collection itself.
|
||||
ui::Shortcut shortcut = m_key->shortcuts()[index];
|
||||
|
||||
if (ui::Alert::show(Strings::alerts_delete_shortcut(accel.toString())) != 1)
|
||||
if (ui::Alert::show(Strings::alerts_delete_shortcut(shortcut.toString())) != 1)
|
||||
return;
|
||||
|
||||
m_key->disableAccel(accel, KeySource::UserDefined);
|
||||
m_key->disableShortcut(shortcut, KeySource::UserDefined);
|
||||
window()->layout();
|
||||
}
|
||||
|
||||
void onAddAccel()
|
||||
void onAddShortcut()
|
||||
{
|
||||
LockButtons lock(this);
|
||||
ui::Accelerator accel;
|
||||
SelectAccelerator window(accel, m_key ? m_key->keycontext() : KeyContext::Any, m_keys);
|
||||
ui::Shortcut shortcut;
|
||||
SelectShortcut window(shortcut, m_key ? m_key->keycontext() : KeyContext::Any, m_keys);
|
||||
window.openWindowInForeground();
|
||||
|
||||
if ((window.isModified()) ||
|
||||
// We can assign a "None" accelerator to mouse wheel actions
|
||||
// We can assign a "None" shortcut to mouse wheel actions
|
||||
(m_key && m_key->type() == KeyType::WheelAction && window.isOK())) {
|
||||
if (!m_key) {
|
||||
ASSERT(m_menuitem);
|
||||
|
@ -256,7 +251,7 @@ private:
|
|||
m_menuKeys[m_menuitem] = m_key;
|
||||
}
|
||||
|
||||
m_key->add(window.accel(), KeySource::UserDefined, m_keys);
|
||||
m_key->add(window.shortcut(), KeySource::UserDefined, m_keys);
|
||||
}
|
||||
|
||||
this->window()->layout();
|
||||
|
@ -273,8 +268,8 @@ private:
|
|||
size.w = std::max(size.w, w);
|
||||
}
|
||||
|
||||
if (m_key && !m_key->accels().empty()) {
|
||||
size_t combos = m_key->accels().size();
|
||||
if (m_key && !m_key->shortcuts().empty()) {
|
||||
size_t combos = m_key->shortcuts().size();
|
||||
if (combos > 1)
|
||||
size.h *= combos;
|
||||
}
|
||||
|
@ -315,7 +310,7 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
if (m_key && !m_key->accels().empty()) {
|
||||
if (m_key && !m_key->shortcuts().empty()) {
|
||||
if (m_key->keycontext() != KeyContext::Any) {
|
||||
g->drawText(convertKeyContextToUserFriendlyString(m_key->keycontext()),
|
||||
fg,
|
||||
|
@ -324,13 +319,14 @@ private:
|
|||
}
|
||||
|
||||
const int dh = th + 4 * guiscale();
|
||||
IntersectClip clip(g,
|
||||
gfx::Rect(keyXPos, y, contextXPos - keyXPos, dh * m_key->accels().size()));
|
||||
IntersectClip clip(
|
||||
g,
|
||||
gfx::Rect(keyXPos, y, contextXPos - keyXPos, dh * m_key->shortcuts().size()));
|
||||
if (clip) {
|
||||
int i = 0;
|
||||
for (const Accelerator& accel : m_key->accels()) {
|
||||
if (i != m_hotAccel || !m_changeButton) {
|
||||
g->drawText(getAccelText(accel), fg, bg, gfx::Point(keyXPos, y));
|
||||
for (const Shortcut& shortcut : m_key->shortcuts()) {
|
||||
if (i != m_hotShortcut || !m_changeButton) {
|
||||
g->drawText(getShortcutText(shortcut), fg, bg, gfx::Point(keyXPos, y));
|
||||
}
|
||||
y += dh;
|
||||
++i;
|
||||
|
@ -361,40 +357,41 @@ private:
|
|||
gfx::Rect bounds = this->bounds();
|
||||
MouseMessage* mouseMsg = static_cast<MouseMessage*>(msg);
|
||||
|
||||
const Accelerators* accels = (m_key ? &m_key->accels() : NULL);
|
||||
const Shortcuts* shortcuts = (m_key ? &m_key->shortcuts() : NULL);
|
||||
int y = bounds.y;
|
||||
int dh = textSize().h + 4 * guiscale();
|
||||
int maxi = (accels && accels->size() > 1 ? accels->size() : 1);
|
||||
int maxi = (shortcuts && shortcuts->size() > 1 ? shortcuts->size() : 1);
|
||||
|
||||
auto theme = SkinTheme::get(this);
|
||||
auto* theme = SkinTheme::get(this);
|
||||
|
||||
for (int i = 0; i < maxi; ++i, y += dh) {
|
||||
int w = font()->textLength(
|
||||
(accels && i < (int)accels->size() ? getAccelText((*accels)[i]) : std::string()));
|
||||
int w = font()->textLength((shortcuts && i < (int)shortcuts->size() ?
|
||||
getShortcutText((*shortcuts)[i]) :
|
||||
std::string()));
|
||||
gfx::Rect itemBounds(bounds.x + m_headerItem->keyXPos(), y, w, dh);
|
||||
itemBounds = itemBounds.enlarge(
|
||||
gfx::Border(4 * guiscale(), 0, 6 * guiscale(), 1 * guiscale()));
|
||||
|
||||
if (accels && i < (int)accels->size() && mouseMsg->position().y >= itemBounds.y &&
|
||||
if (shortcuts && i < (int)shortcuts->size() && mouseMsg->position().y >= itemBounds.y &&
|
||||
mouseMsg->position().y < itemBounds.y + itemBounds.h) {
|
||||
if (m_hotAccel != i) {
|
||||
m_hotAccel = i;
|
||||
if (m_hotShortcut != i) {
|
||||
m_hotShortcut = i;
|
||||
|
||||
m_changeConn = obs::connection();
|
||||
m_changeButton.reset(new Button(""));
|
||||
m_changeConn = m_changeButton->Click.connect([this, i] { onChangeAccel(i); });
|
||||
m_changeConn = m_changeButton->Click.connect([this, i] { onChangeShortcut(i); });
|
||||
m_changeButton->setStyle(theme->styles.miniButton());
|
||||
addChild(m_changeButton.get());
|
||||
|
||||
m_deleteConn = obs::connection();
|
||||
m_deleteButton.reset(new Button(""));
|
||||
m_deleteConn = m_deleteButton->Click.connect([this, i] { onDeleteAccel(i); });
|
||||
m_deleteConn = m_deleteButton->Click.connect([this, i] { onDeleteShortcut(i); });
|
||||
m_deleteButton->setStyle(theme->styles.miniButton());
|
||||
addChild(m_deleteButton.get());
|
||||
|
||||
m_changeButton->setBgColor(gfx::ColorNone);
|
||||
m_changeButton->setBounds(itemBounds);
|
||||
m_changeButton->setText(getAccelText((*accels)[i]));
|
||||
m_changeButton->setText(getShortcutText((*shortcuts)[i]));
|
||||
|
||||
const char* label = "x";
|
||||
m_deleteButton->setBgColor(gfx::ColorNone);
|
||||
|
@ -411,7 +408,7 @@ private:
|
|||
if (i == 0 && !m_addButton && (!m_menuitem || m_menuitem->getCommand())) {
|
||||
m_addConn = obs::connection();
|
||||
m_addButton.reset(new Button(""));
|
||||
m_addConn = m_addButton->Click.connect([this] { onAddAccel(); });
|
||||
m_addConn = m_addButton->Click.connect([this] { onAddShortcut(); });
|
||||
m_addButton->setStyle(theme->styles.miniButton());
|
||||
addChild(m_addButton.get());
|
||||
|
||||
|
@ -452,17 +449,15 @@ private:
|
|||
m_addButton->setVisible(false);
|
||||
}
|
||||
|
||||
m_hotAccel = -1;
|
||||
m_hotShortcut = -1;
|
||||
}
|
||||
|
||||
std::string getAccelText(const Accelerator& accel) const
|
||||
std::string getShortcutText(const Shortcut& shortcut) const
|
||||
{
|
||||
if (m_key && m_key->type() == KeyType::WheelAction && accel.isEmpty()) {
|
||||
if (m_key && m_key->type() == KeyType::WheelAction && shortcut.isEmpty()) {
|
||||
return Strings::keyboard_shortcuts_default_action();
|
||||
}
|
||||
else {
|
||||
return accel.toString();
|
||||
}
|
||||
return shortcut.toString();
|
||||
}
|
||||
|
||||
KeyboardShortcuts& m_keys;
|
||||
|
@ -471,14 +466,14 @@ private:
|
|||
KeyPtr m_keyOrig;
|
||||
AppMenuItem* m_menuitem;
|
||||
int m_level;
|
||||
ui::Accelerators m_newAccels;
|
||||
ui::Shortcuts m_newShortcuts;
|
||||
std::shared_ptr<ui::Button> m_changeButton;
|
||||
std::shared_ptr<ui::Button> m_deleteButton;
|
||||
std::shared_ptr<ui::Button> m_addButton;
|
||||
obs::scoped_connection m_changeConn;
|
||||
obs::scoped_connection m_deleteConn;
|
||||
obs::scoped_connection m_addConn;
|
||||
int m_hotAccel;
|
||||
int m_hotShortcut;
|
||||
bool m_lockButtons;
|
||||
HeaderItem* m_headerItem;
|
||||
};
|
||||
|
@ -977,6 +972,7 @@ public:
|
|||
KeyboardShortcutsCommand();
|
||||
|
||||
protected:
|
||||
bool onEnabled(Context* context) override;
|
||||
void onLoadParams(const Params& params) override;
|
||||
void onExecute(Context* context) override;
|
||||
|
||||
|
@ -986,11 +982,15 @@ private:
|
|||
std::string m_search;
|
||||
};
|
||||
|
||||
KeyboardShortcutsCommand::KeyboardShortcutsCommand()
|
||||
: Command(CommandId::KeyboardShortcuts(), CmdUIOnlyFlag)
|
||||
KeyboardShortcutsCommand::KeyboardShortcutsCommand() : Command(CommandId::KeyboardShortcuts())
|
||||
{
|
||||
}
|
||||
|
||||
bool KeyboardShortcutsCommand::onEnabled(Context* context)
|
||||
{
|
||||
return context->isUIAvailable();
|
||||
}
|
||||
|
||||
void KeyboardShortcutsCommand::onLoadParams(const Params& params)
|
||||
{
|
||||
m_search = params.get("search");
|
||||
|
|
|
@ -34,10 +34,7 @@ private:
|
|||
std::string m_path;
|
||||
};
|
||||
|
||||
LaunchCommand::LaunchCommand()
|
||||
: Command(CommandId::Launch(), CmdUIOnlyFlag)
|
||||
, m_type(Url)
|
||||
, m_path("")
|
||||
LaunchCommand::LaunchCommand() : Command(CommandId::Launch()), m_type(Url), m_path("")
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -14,8 +14,6 @@
|
|||
#include "app/context_access.h"
|
||||
#include "app/modules/gui.h"
|
||||
#include "app/tx.h"
|
||||
#include "doc/layer.h"
|
||||
#include "doc/sprite.h"
|
||||
|
||||
namespace app {
|
||||
|
||||
|
@ -28,8 +26,7 @@ protected:
|
|||
void onExecute(Context* context) override;
|
||||
};
|
||||
|
||||
LayerFromBackgroundCommand::LayerFromBackgroundCommand()
|
||||
: Command(CommandId::LayerFromBackground(), CmdRecordableFlag)
|
||||
LayerFromBackgroundCommand::LayerFromBackgroundCommand() : Command(CommandId::LayerFromBackground())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -9,11 +9,9 @@
|
|||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "app/app.h"
|
||||
#include "app/commands/command.h"
|
||||
#include "app/context_access.h"
|
||||
#include "app/modules/gui.h"
|
||||
#include "doc/image.h"
|
||||
#include "doc/layer.h"
|
||||
|
||||
namespace app {
|
||||
|
@ -30,7 +28,7 @@ protected:
|
|||
void onExecute(Context* context) override;
|
||||
};
|
||||
|
||||
LayerLockCommand::LayerLockCommand() : Command(CommandId::LayerLock(), CmdRecordableFlag)
|
||||
LayerLockCommand::LayerLockCommand() : Command(CommandId::LayerLock())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "app/app.h"
|
||||
#include "app/cmd/set_layer_opacity.h"
|
||||
#include "app/commands/command.h"
|
||||
#include "app/commands/params.h"
|
||||
|
@ -40,7 +39,7 @@ private:
|
|||
int m_opacity;
|
||||
};
|
||||
|
||||
LayerOpacityCommand::LayerOpacityCommand() : Command(CommandId::LayerOpacity(), CmdUIOnlyFlag)
|
||||
LayerOpacityCommand::LayerOpacityCommand() : Command(CommandId::LayerOpacity())
|
||||
{
|
||||
m_opacity = 255;
|
||||
}
|
||||
|
|
|
@ -32,8 +32,8 @@
|
|||
#include "app/ui/timeline/timeline.h"
|
||||
#include "app/ui/user_data_view.h"
|
||||
#include "app/ui_context.h"
|
||||
#include "base/convert_to.h"
|
||||
#include "base/scoped_value.h"
|
||||
#include "doc/image.h"
|
||||
#include "doc/layer.h"
|
||||
#include "doc/layer_tilemap.h"
|
||||
#include "doc/sprite.h"
|
||||
|
@ -134,8 +134,16 @@ public:
|
|||
|
||||
remapWindow();
|
||||
centerWindow();
|
||||
|
||||
gfx::Rect originalBounds = bounds();
|
||||
|
||||
load_window_pos(this, "LayerProperties");
|
||||
|
||||
// Queue a remap for after the user data view is configured
|
||||
// if the window size has been reset and user data is visible
|
||||
if (originalBounds == bounds() && Preferences::instance().layers.userDataVisibility())
|
||||
m_remapAfterConfigure = true;
|
||||
|
||||
UIContext::instance()->add_observer(this);
|
||||
}
|
||||
|
||||
|
@ -158,6 +166,11 @@ public:
|
|||
|
||||
if (countLayers() > 0) {
|
||||
m_userDataView.configureAndSet(m_layer->userData(), g_window->propertiesGrid());
|
||||
if (m_remapAfterConfigure) {
|
||||
remapWindow();
|
||||
centerWindow();
|
||||
m_remapAfterConfigure = false;
|
||||
}
|
||||
}
|
||||
|
||||
updateFromLayer();
|
||||
|
@ -463,6 +476,13 @@ private:
|
|||
m_userDataView.setVisible(false, false);
|
||||
}
|
||||
|
||||
bool uuidVisible = m_document && m_document->sprite() && m_document->sprite()->useLayerUuids();
|
||||
uuidLabel()->setVisible(uuidVisible);
|
||||
uuid()->setVisible(uuidVisible);
|
||||
|
||||
if (uuidVisible)
|
||||
uuid()->setText(m_layer ? base::convert_to<std::string>(m_layer->uuid()) : std::string());
|
||||
|
||||
if (tileset()->isVisible() != tilemapVisibility) {
|
||||
tileset()->setVisible(tilemapVisibility);
|
||||
tileset()->parent()->layout();
|
||||
|
@ -476,16 +496,17 @@ private:
|
|||
view::RealRange m_range;
|
||||
bool m_selfUpdate = false;
|
||||
UserDataView m_userDataView;
|
||||
bool m_remapAfterConfigure = false;
|
||||
};
|
||||
|
||||
LayerPropertiesCommand::LayerPropertiesCommand()
|
||||
: Command(CommandId::LayerProperties(), CmdRecordableFlag)
|
||||
LayerPropertiesCommand::LayerPropertiesCommand() : Command(CommandId::LayerProperties())
|
||||
{
|
||||
}
|
||||
|
||||
bool LayerPropertiesCommand::onEnabled(Context* context)
|
||||
{
|
||||
return context->checkFlags(ContextFlags::ActiveDocumentIsWritable | ContextFlags::HasActiveLayer);
|
||||
return context->isUIAvailable() &&
|
||||
context->checkFlags(ContextFlags::ActiveDocumentIsWritable | ContextFlags::HasActiveLayer);
|
||||
}
|
||||
|
||||
void LayerPropertiesCommand::onExecute(Context* context)
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
#include "app/commands/command.h"
|
||||
#include "app/context_access.h"
|
||||
#include "app/modules/gui.h"
|
||||
#include "doc/image.h"
|
||||
#include "doc/layer.h"
|
||||
|
||||
namespace app {
|
||||
|
@ -29,8 +28,7 @@ protected:
|
|||
void onExecute(Context* context) override;
|
||||
};
|
||||
|
||||
LayerVisibilityCommand::LayerVisibilityCommand()
|
||||
: Command(CommandId::LayerVisibility(), CmdRecordableFlag)
|
||||
LayerVisibilityCommand::LayerVisibilityCommand() : Command(CommandId::LayerVisibility())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
#include "app/ui/status_bar.h"
|
||||
#include "doc/cel.h"
|
||||
#include "doc/layer.h"
|
||||
#include "doc/sprite.h"
|
||||
|
||||
namespace app {
|
||||
|
||||
|
@ -31,7 +30,7 @@ protected:
|
|||
void onExecute(Context* context) override;
|
||||
};
|
||||
|
||||
LinkCelsCommand::LinkCelsCommand() : Command(CommandId::LinkCels(), CmdRecordableFlag)
|
||||
LinkCelsCommand::LinkCelsCommand() : Command(CommandId::LinkCels())
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -88,7 +87,7 @@ void LinkCelsCommand::onExecute(Context* context)
|
|||
tx.commit();
|
||||
}
|
||||
|
||||
if (nonEditableLayers)
|
||||
if (context->isUIAvailable() && nonEditableLayers)
|
||||
StatusBar::instance()->showTip(1000, Strings::statusbar_tips_locked_layers());
|
||||
|
||||
update_screen_for_document(document);
|
||||
|
|
|
@ -26,6 +26,7 @@ namespace app {
|
|||
|
||||
class LoadMaskCommand : public Command {
|
||||
std::string m_filename;
|
||||
bool m_ui = true;
|
||||
|
||||
public:
|
||||
LoadMaskCommand();
|
||||
|
@ -36,13 +37,16 @@ protected:
|
|||
void onExecute(Context* context) override;
|
||||
};
|
||||
|
||||
LoadMaskCommand::LoadMaskCommand() : Command(CommandId::LoadMask(), CmdRecordableFlag)
|
||||
LoadMaskCommand::LoadMaskCommand() : Command(CommandId::LoadMask())
|
||||
{
|
||||
m_filename = "";
|
||||
}
|
||||
|
||||
void LoadMaskCommand::onLoadParams(const Params& params)
|
||||
{
|
||||
if (params.has_param("ui"))
|
||||
m_ui = params.get_as<bool>("ui");
|
||||
else
|
||||
m_ui = true;
|
||||
m_filename = params.get("filename");
|
||||
}
|
||||
|
||||
|
@ -55,7 +59,7 @@ void LoadMaskCommand::onExecute(Context* context)
|
|||
{
|
||||
const ContextReader reader(context);
|
||||
|
||||
if (context->isUIAvailable()) {
|
||||
if (context->isUIAvailable() && m_ui) {
|
||||
base::paths exts = { "msk" };
|
||||
base::paths selectedFilename;
|
||||
if (!app::show_file_selector(Strings::load_selection_title(),
|
||||
|
@ -70,7 +74,8 @@ void LoadMaskCommand::onExecute(Context* context)
|
|||
|
||||
std::unique_ptr<Mask> mask(load_msk_file(m_filename.c_str()));
|
||||
if (!mask) {
|
||||
ui::Alert::show(Strings::alerts_error_loading_file(m_filename));
|
||||
if (context->isUIAvailable())
|
||||
ui::Alert::show(Strings::alerts_error_loading_file(m_filename));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,14 +37,19 @@ protected:
|
|||
private:
|
||||
std::string m_preset;
|
||||
std::string m_filename;
|
||||
bool m_ui = true;
|
||||
};
|
||||
|
||||
LoadPaletteCommand::LoadPaletteCommand() : Command(CommandId::LoadPalette(), CmdRecordableFlag)
|
||||
LoadPaletteCommand::LoadPaletteCommand() : Command(CommandId::LoadPalette())
|
||||
{
|
||||
}
|
||||
|
||||
void LoadPaletteCommand::onLoadParams(const Params& params)
|
||||
{
|
||||
if (params.has_param("ui"))
|
||||
m_ui = params.get_as<bool>("ui");
|
||||
else
|
||||
m_ui = true;
|
||||
m_preset = params.get("preset");
|
||||
m_filename = params.get("filename");
|
||||
}
|
||||
|
@ -58,20 +63,20 @@ void LoadPaletteCommand::onExecute(Context* context)
|
|||
if (!base::is_file(filename))
|
||||
filename = get_preset_palette_filename(m_preset, ".gpl");
|
||||
}
|
||||
else if (!m_filename.empty()) {
|
||||
filename = m_filename;
|
||||
}
|
||||
else if (context->isUIAvailable()) {
|
||||
base::paths exts = get_readable_palette_extensions();
|
||||
else if (context->isUIAvailable() && m_ui) {
|
||||
const base::paths exts = get_readable_palette_extensions();
|
||||
base::paths filenames;
|
||||
if (app::show_file_selector(Strings::load_palette_title(),
|
||||
"",
|
||||
m_filename,
|
||||
exts,
|
||||
FileSelectorType::Open,
|
||||
filenames)) {
|
||||
filename = filenames.front();
|
||||
}
|
||||
}
|
||||
else if (!m_filename.empty()) {
|
||||
filename = m_filename;
|
||||
}
|
||||
|
||||
// Do nothing
|
||||
if (filename.empty())
|
||||
|
|
|
@ -29,7 +29,7 @@ protected:
|
|||
void onExecute(Context* context) override;
|
||||
};
|
||||
|
||||
MaskAllCommand::MaskAllCommand() : Command(CommandId::MaskAll(), CmdRecordableFlag)
|
||||
MaskAllCommand::MaskAllCommand() : Command(CommandId::MaskAll())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
#include "app/color_utils.h"
|
||||
#include "app/commands/command.h"
|
||||
#include "app/commands/new_params.h"
|
||||
#include "app/console.h"
|
||||
#include "app/context.h"
|
||||
#include "app/context_access.h"
|
||||
#include "app/doc.h"
|
||||
|
@ -26,9 +25,6 @@
|
|||
#include "app/ui/color_bar.h"
|
||||
#include "app/ui/color_button.h"
|
||||
#include "app/ui/selection_mode_field.h"
|
||||
#include "base/chrono.h"
|
||||
#include "base/convert_to.h"
|
||||
#include "base/scoped_value.h"
|
||||
#include "doc/image.h"
|
||||
#include "doc/mask.h"
|
||||
#include "doc/sprite.h"
|
||||
|
@ -203,8 +199,7 @@ protected:
|
|||
void onExecute(Context* context) override;
|
||||
};
|
||||
|
||||
MaskByColorCommand::MaskByColorCommand()
|
||||
: CommandWithNewParams(CommandId::MaskByColor(), CmdUIOnlyFlag)
|
||||
MaskByColorCommand::MaskByColorCommand() : CommandWithNewParams(CommandId::MaskByColor())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue