clang-format all files

This commit is contained in:
David Capello 2024-12-16 10:10:34 -03:00
parent 4b3ff3369e
commit b2e4f78b69
1511 changed files with 55829 additions and 61507 deletions

View File

@ -1,22 +1,22 @@
# Contributor Code of Conduct
As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality.
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery
* Personal attacks
* Trolling or insulting/derogatory comments
* Public or private harassment
* Publishing other's private information, such as physical or electronic addresses, without explicit permission
* Other unethical or unprofessional conduct.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team.
This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community.
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0, available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/)
# Contributor Code of Conduct
As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality.
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery
* Personal attacks
* Trolling or insulting/derogatory comments
* Public or private harassment
* Publishing other's private information, such as physical or electronic addresses, without explicit permission
* Other unethical or unprofessional conduct.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team.
This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community.
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0, available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/)

224
README.md
View File

@ -1,112 +1,112 @@
# Aseprite
[![build](https://github.com/aseprite/aseprite/actions/workflows/build.yml/badge.svg)](https://github.com/aseprite/aseprite/actions/workflows/build.yml)
[![Translation Status](https://hosted.weblate.org/widget/aseprite/aseprite/svg-badge.svg)](https://hosted.weblate.org/engage/aseprite/)
[![Discourse Community](https://img.shields.io/badge/discourse-community-brightgreen.svg?style=flat)](https://community.aseprite.org/)
[![Discord Server](https://discordapp.com/api/guilds/324979738533822464/embed.png)](https://discord.gg/Yb2CeX8)
## Introduction
**Aseprite** is a program to create animated sprites. Its main features are:
* Sprites are composed of [layers & frames](https://www.aseprite.org/docs/timeline/) as separated concepts.
* Support for [color profiles](https://www.aseprite.org/docs/color-profile/) and different [color modes](https://www.aseprite.org/docs/color-mode/): RGBA, Indexed (palettes up to 256 colors), Grayscale.
* [Animation facilities](https://www.aseprite.org/docs/animation/), with real-time [preview](https://www.aseprite.org/docs/preview-window/) and [onion skinning](https://www.aseprite.org/docs/onion-skinning/).
* [Export/import](https://www.aseprite.org/docs/exporting/) animations to/from [sprite sheets](https://www.aseprite.org/docs/sprite-sheet/), GIF files, or sequence of PNG files (and FLC, FLI, JPG, BMP, PCX, TGA).
* [Multiple editors](https://www.aseprite.org/docs/workspace/#drag-and-drop-tabs) support.
* [Layer groups](https://imgur.com/x3OKkGj) for organizing your work, and [reference layers](https://twitter.com/aseprite/status/806889204601016325) for rotoscoping.
* Pixel-art specific tools like [Pixel Perfect freehand mode](https://imgur.com/0fdlNau), [Shading ink](https://www.aseprite.org/docs/shading/), [Custom Brushes](https://twitter.com/aseprite/status/1196883990080344067), [Outlines](https://twitter.com/aseprite/status/1126548469865431041), [Wide Pixels](https://imgur.com/1yZKUcs), etc.
* Other special drawing tools like [Pressure sensitivity](https://twitter.com/aseprite/status/1253770784708886533), [Symmetry Tool](https://twitter.com/aseprite/status/659709226747625472), [Stroke and Fill](https://imgur.com/7JZQ81o) selection, [Gradients](https://twitter.com/aseprite/status/1126549217856622597).
* [Tiled mode](https://youtu.be/G_JeWBaxQIg) useful to draw patterns and textures.
* [Transform multiple frames/layers](https://twitter.com/aseprite/status/1170007034651172866) at the same time.
* [Lua scripting capabilities](https://www.aseprite.org/docs/scripting/).
* [CLI - Command Line Interface](https://www.aseprite.org/docs/cli/) to automatize tasks.
* [Quick Reference / Cheat Sheet](https://www.aseprite.org/quickref/) keyboard shortcuts ([customizable keys](https://imgur.com/rvAUxyF) and [mouse wheel](https://imgur.com/oNqFqVb)).
* [Reopen closed files](https://twitter.com/aseprite/status/1202641475256881153) and [recover data](https://www.aseprite.org/docs/data-recovery/) in case of crash.
* Undo/Redo for every operation and support for [non-linear undo](https://imgur.com/9I42fZK).
* [More features & tips](https://twitter.com/aseprite/status/1124442198651678720)
## Issues
There is a list of
[Known Issues](https://github.com/aseprite/aseprite/issues) (things
to be fixed or that aren't yet implemented).
If you found a bug or have a new idea/feature for the program,
[you can report them](https://github.com/aseprite/aseprite/issues/new).
## Support
You can ask for help in:
* [Aseprite Community](https://community.aseprite.org/)
* [Aseprite Discord Server](https://discord.gg/Yb2CeX8)
* Official support: [support@aseprite.org](mailto:support@aseprite.org)
* Social networks and community-driven places:
[Twitter](https://twitter.com/aseprite/),
[Facebook](https://facebook.com/aseprite/),
[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:
* [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.
## License
This program is distributed under three different licenses:
1. Source code and official releases/binaries are distributed under
our [End-User License Agreement for Aseprite (EULA)](EULA.txt). Please check
that there are [modules/libraries in the source code](src/README.md) that
are distributed under the MIT license
(e.g. [laf](https://github.com/aseprite/laf),
[clip](https://github.com/aseprite/clip),
[undo](https://github.com/aseprite/undo),
[observable](https://github.com/aseprite/observable),
[ui](src/ui), etc.).
2. You can request a special
[educational license](https://www.aseprite.org/faq/#is-there-an-educational-license)
in case you are a teacher in an educational institution and want to
use Aseprite in your classroom (in-situ).
3. Steam releases are distributed under the terms of the
[Steam Subscriber Agreement](http://store.steampowered.com/subscriber_agreement/).
You can get more information about Aseprite license in the
[FAQ](https://www.aseprite.org/faq/#licensing-&-commercial).
# Aseprite
[![build](https://github.com/aseprite/aseprite/actions/workflows/build.yml/badge.svg)](https://github.com/aseprite/aseprite/actions/workflows/build.yml)
[![Translation Status](https://hosted.weblate.org/widget/aseprite/aseprite/svg-badge.svg)](https://hosted.weblate.org/engage/aseprite/)
[![Discourse Community](https://img.shields.io/badge/discourse-community-brightgreen.svg?style=flat)](https://community.aseprite.org/)
[![Discord Server](https://discordapp.com/api/guilds/324979738533822464/embed.png)](https://discord.gg/Yb2CeX8)
## Introduction
**Aseprite** is a program to create animated sprites. Its main features are:
* Sprites are composed of [layers & frames](https://www.aseprite.org/docs/timeline/) as separated concepts.
* Support for [color profiles](https://www.aseprite.org/docs/color-profile/) and different [color modes](https://www.aseprite.org/docs/color-mode/): RGBA, Indexed (palettes up to 256 colors), Grayscale.
* [Animation facilities](https://www.aseprite.org/docs/animation/), with real-time [preview](https://www.aseprite.org/docs/preview-window/) and [onion skinning](https://www.aseprite.org/docs/onion-skinning/).
* [Export/import](https://www.aseprite.org/docs/exporting/) animations to/from [sprite sheets](https://www.aseprite.org/docs/sprite-sheet/), GIF files, or sequence of PNG files (and FLC, FLI, JPG, BMP, PCX, TGA).
* [Multiple editors](https://www.aseprite.org/docs/workspace/#drag-and-drop-tabs) support.
* [Layer groups](https://imgur.com/x3OKkGj) for organizing your work, and [reference layers](https://twitter.com/aseprite/status/806889204601016325) for rotoscoping.
* Pixel-art specific tools like [Pixel Perfect freehand mode](https://imgur.com/0fdlNau), [Shading ink](https://www.aseprite.org/docs/shading/), [Custom Brushes](https://twitter.com/aseprite/status/1196883990080344067), [Outlines](https://twitter.com/aseprite/status/1126548469865431041), [Wide Pixels](https://imgur.com/1yZKUcs), etc.
* Other special drawing tools like [Pressure sensitivity](https://twitter.com/aseprite/status/1253770784708886533), [Symmetry Tool](https://twitter.com/aseprite/status/659709226747625472), [Stroke and Fill](https://imgur.com/7JZQ81o) selection, [Gradients](https://twitter.com/aseprite/status/1126549217856622597).
* [Tiled mode](https://youtu.be/G_JeWBaxQIg) useful to draw patterns and textures.
* [Transform multiple frames/layers](https://twitter.com/aseprite/status/1170007034651172866) at the same time.
* [Lua scripting capabilities](https://www.aseprite.org/docs/scripting/).
* [CLI - Command Line Interface](https://www.aseprite.org/docs/cli/) to automatize tasks.
* [Quick Reference / Cheat Sheet](https://www.aseprite.org/quickref/) keyboard shortcuts ([customizable keys](https://imgur.com/rvAUxyF) and [mouse wheel](https://imgur.com/oNqFqVb)).
* [Reopen closed files](https://twitter.com/aseprite/status/1202641475256881153) and [recover data](https://www.aseprite.org/docs/data-recovery/) in case of crash.
* Undo/Redo for every operation and support for [non-linear undo](https://imgur.com/9I42fZK).
* [More features & tips](https://twitter.com/aseprite/status/1124442198651678720)
## Issues
There is a list of
[Known Issues](https://github.com/aseprite/aseprite/issues) (things
to be fixed or that aren't yet implemented).
If you found a bug or have a new idea/feature for the program,
[you can report them](https://github.com/aseprite/aseprite/issues/new).
## Support
You can ask for help in:
* [Aseprite Community](https://community.aseprite.org/)
* [Aseprite Discord Server](https://discord.gg/Yb2CeX8)
* Official support: [support@aseprite.org](mailto:support@aseprite.org)
* Social networks and community-driven places:
[Twitter](https://twitter.com/aseprite/),
[Facebook](https://facebook.com/aseprite/),
[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:
* [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.
## License
This program is distributed under three different licenses:
1. Source code and official releases/binaries are distributed under
our [End-User License Agreement for Aseprite (EULA)](EULA.txt). Please check
that there are [modules/libraries in the source code](src/README.md) that
are distributed under the MIT license
(e.g. [laf](https://github.com/aseprite/laf),
[clip](https://github.com/aseprite/clip),
[undo](https://github.com/aseprite/undo),
[observable](https://github.com/aseprite/observable),
[ui](src/ui), etc.).
2. You can request a special
[educational license](https://www.aseprite.org/faq/#is-there-an-educational-license)
in case you are a teacher in an educational institution and want to
use Aseprite in your classroom (in-situ).
3. Steam releases are distributed under the terms of the
[Steam Subscriber Agreement](http://store.steampowered.com/subscriber_agreement/).
You can get more information about Aseprite license in the
[FAQ](https://www.aseprite.org/faq/#licensing-&-commercial).

View File

@ -1,70 +1,70 @@
GIMP Palette
#Palette Name: AAP-64
#Description: Created by Adigun Polack
#Colors: 64
#https://twitter.com/AdigunPolack
#http://pixeljoint.com/pixelart/119466.htm
6 6 8 #060608
20 16 19 #141013
59 23 37 #3b1725
115 23 45 #73172d
180 32 42 #b4202a
223 62 35 #df3e23
250 106 10 #fa6a0a
249 163 27 #f9a31b
255 213 65 #ffd541
255 252 64 #fffc40
214 242 100 #d6f264
156 219 67 #9cdb43
89 193 53 #59c135
20 160 46 #14a02e
26 122 62 #1a7a3e
36 82 59 #24523b
18 32 32 #122020
20 52 100 #143464
40 92 196 #285cc4
36 159 222 #249fde
32 214 199 #20d6c7
166 252 219 #a6fcdb
255 255 255 #ffffff
254 243 192 #fef3c0
250 214 184 #fad6b8
245 160 151 #f5a097
232 106 115 #e86a73
188 74 155 #bc4a9b
121 58 128 #793a80
64 51 83 #403353
36 34 52 #242234
34 28 26 #221c1a
50 43 40 #322b28
113 65 59 #71413b
187 117 71 #bb7547
219 164 99 #dba463
244 210 156 #f4d29c
218 224 234 #dae0ea
179 185 209 #b3b9d1
139 147 175 #8b93af
109 117 141 #6d758d
74 84 98 #4a5462
51 57 65 #333941
66 36 51 #422433
91 49 56 #5b3138
142 82 82 #8e5252
186 117 106 #ba756a
233 181 163 #e9b5a3
227 230 255 #e3e6ff
185 191 251 #b9bffb
132 155 228 #849be4
88 141 190 #588dbe
71 125 133 #477d85
35 103 78 #23674e
50 132 100 #328464
93 175 141 #5daf8d
146 220 186 #92dcba
205 247 226 #cdf7e2
228 210 170 #e4d2aa
199 176 139 #c7b08b
160 134 98 #a08662
121 103 85 #796755
90 78 68 #5a4e44
66 57 52 #423934
GIMP Palette
#Palette Name: AAP-64
#Description: Created by Adigun Polack
#Colors: 64
#https://twitter.com/AdigunPolack
#http://pixeljoint.com/pixelart/119466.htm
6 6 8 #060608
20 16 19 #141013
59 23 37 #3b1725
115 23 45 #73172d
180 32 42 #b4202a
223 62 35 #df3e23
250 106 10 #fa6a0a
249 163 27 #f9a31b
255 213 65 #ffd541
255 252 64 #fffc40
214 242 100 #d6f264
156 219 67 #9cdb43
89 193 53 #59c135
20 160 46 #14a02e
26 122 62 #1a7a3e
36 82 59 #24523b
18 32 32 #122020
20 52 100 #143464
40 92 196 #285cc4
36 159 222 #249fde
32 214 199 #20d6c7
166 252 219 #a6fcdb
255 255 255 #ffffff
254 243 192 #fef3c0
250 214 184 #fad6b8
245 160 151 #f5a097
232 106 115 #e86a73
188 74 155 #bc4a9b
121 58 128 #793a80
64 51 83 #403353
36 34 52 #242234
34 28 26 #221c1a
50 43 40 #322b28
113 65 59 #71413b
187 117 71 #bb7547
219 164 99 #dba463
244 210 156 #f4d29c
218 224 234 #dae0ea
179 185 209 #b3b9d1
139 147 175 #8b93af
109 117 141 #6d758d
74 84 98 #4a5462
51 57 65 #333941
66 36 51 #422433
91 49 56 #5b3138
142 82 82 #8e5252
186 117 106 #ba756a
233 181 163 #e9b5a3
227 230 255 #e3e6ff
185 191 251 #b9bffb
132 155 228 #849be4
88 141 190 #588dbe
71 125 133 #477d85
35 103 78 #23674e
50 132 100 #328464
93 175 141 #5daf8d
146 220 186 #92dcba
205 247 226 #cdf7e2
228 210 170 #e4d2aa
199 176 139 #c7b08b
160 134 98 #a08662
121 103 85 #796755
90 78 68 #5a4e44
66 57 52 #423934

View File

@ -1,23 +1,23 @@
GIMP Palette
# ------------------------------------------------------
# T h e A A P - M i c r o 1 2 P a l e t t e
# ------------------------------------------------------
# Created by Adigun Azikiwe Polack.
# (c)2018 Adigun Azikiwe Polack. All Rights Reserved.
# ------------------------------------------------------
#
# https://twitter.com/AdigunPolack
# http://pixeljoint.com/pixelart/121151.htm
#
4 3 3 Rich Black (FOGRA39)
28 22 24 Eerie Black
71 65 107 Independence
108 140 80 Palm Leaf
227 210 69 Sandstorm
216 128 56 Bronze
161 61 59 Smoky Topaz
78 40 46 Acajou
154 64 126 Magenta Haze
240 212 114 Hansa Yellow
249 245 239 Seashell
138 143 196 Ube
GIMP Palette
# ------------------------------------------------------
# T h e A A P - M i c r o 1 2 P a l e t t e
# ------------------------------------------------------
# Created by Adigun Azikiwe Polack.
# (c)2018 Adigun Azikiwe Polack. All Rights Reserved.
# ------------------------------------------------------
#
# https://twitter.com/AdigunPolack
# http://pixeljoint.com/pixelart/121151.htm
#
4 3 3 Rich Black (FOGRA39)
28 22 24 Eerie Black
71 65 107 Independence
108 140 80 Palm Leaf
227 210 69 Sandstorm
216 128 56 Bronze
161 61 59 Smoky Topaz
78 40 46 Acajou
154 64 126 Magenta Haze
240 212 114 Hansa Yellow
249 245 239 Seashell
138 143 196 Ube

View File

@ -1,139 +1,139 @@
GIMP Palette
# --------------------------------------------------------
# T h e A A P - S p l e n d o r 1 2 8 P a l e t t e
# --------------------------------------------------------
# Created by Adigun Azikiwe Polack.
# (c)2018 Adigun Azikiwe Polack. All Rights Reserved.
# --------------------------------------------------------
#
# https://twitter.com/AdigunPolack
# http://pixeljoint.com/pixelart/120714.htm
#
5 4 3 Rich Black (FOGRA39)
14 12 12 Smoky Black
45 27 30 Grape Black
97 39 33 Caput Mortuum
185 69 29 Rust
241 100 31 Vivid Vermilion
252 165 112 Light Salmon
255 224 183 Peach Puff
255 255 255 White
255 240 137 Yellow (Crayola)
248 197 58 Saffron
232 138 54 Cadmium Orange
176 91 44 Ruddy Brown
103 57 49 Van Dyke Brown
39 31 27 Dark Bistre
76 61 46 Muddy Taupe
133 95 57 Coyote Brown
211 151 65 Peru
248 246 68 Maximum Yellow
213 220 29 Yellowish Pear
173 184 52 Android Green
127 142 68 Withering Palm Leaf
88 99 53 Deep Yellowish Spring Bud
51 60 36 Kombu Green
24 28 25 Eerie Dark Green
41 63 33 Spring Leather Night Jacket
71 114 56 Spring Fern
97 165 63 Spring Palm Leaf
143 208 50 Yellow-Green
196 241 41 Pear
208 255 234 Aero Blue
151 237 202 Pale Robin Egg Blue
89 207 147 Ocean Green
66 164 89 Middle Green
61 111 67 Fern Green
39 65 45 Withered Leather Jacket
20 18 29 Eerie Dark Blue
27 36 71 Yankees Blue
43 78 149 B'dazzled Blue
39 137 205 Cyan Cornflower Blue
66 191 232 Picton Blue
115 239 232 Medium Sky Blue
241 242 255 Alice Blue
201 212 253 Periwinkle
138 161 246 Jordy Blue
69 114 227 Royal Blue
73 65 130 Dark Slate Blue
120 100 198 Toolbox
156 139 219 Medium Purple
206 170 237 Bright Ube
250 214 255 Pink Lace
238 181 156 Pale Pink
212 128 187 Middle Purple
144 82 188 Deep Lilac
23 21 22 Licorice
55 51 52 Jet Taupe
105 91 89 Wenge
178 139 120 Light Taupe
226 178 126 Middle Yellow Red
246 216 150 Tuscan
252 247 190 Blond
236 235 231 Alabaster
203 198 193 Pale Silver
166 158 154 Quick Silver
128 123 122 Trolley Grey
89 87 87 Davy's Grey
50 50 50 Jet Grey
79 52 47 Acajou
140 91 62 Coconut
198 133 86 Deer
214 168 81 Indian Yellow
180 117 56 Copper
114 75 44 Tuscan Brown
69 42 27 Brown Bistre
97 104 58 Deep Tan Spring Bud
147 148 70 Dark Tan
198 184 88 Vegas Gold
239 221 145 Light Khaki
181 231 203 Magic Mint
134 198 154 Eton Blue
93 155 121 Shiny Shamrock
72 104 89 Feldgrau
44 59 57 Gunmetal Teal
23 24 25 Eerie Black
44 52 56 Gunmetal Turquoise
70 84 86 Davy's Teal
100 135 140 Steel Teal
138 196 195 Pearl Aqua
175 233 223 Powder Blue
220 234 238 Azureish White
184 204 216 Light Steel Blue
136 163 188 Pewter Blue
94 113 142 UCLA Blue
72 82 98 Independence Blue
40 44 60 Gunmetal Blue
70 71 98 Independence Blue-Gray
105 102 130 Dark Blue-Gray
154 151 185 Manatee
197 199 221 Lavender Gray
230 231 240 Glitter
238 230 234 Isabelline
227 205 223 Queen Pink
191 165 201 Lilac
135 115 143 Pomp And Power
86 79 91 Davy's Lavender
50 47 53 Jet Lavender
54 40 43 Burgundy Bistre
101 73 86 Deep Fuchsia Wenge
150 104 136 Antique Fuchsia
192 144 169 Opera Mauve
212 184 184 Pale Magenta
234 224 221 Platinum Pink
241 235 219 Eggshell
221 206 191 Dust Storm
189 164 153 Tuscany
136 110 106 Shadow
89 77 77 Dark Liver
51 39 42 Dark Mahogany-Violet
178 148 118 Light Tanned Taupe
225 191 137 Pale Gold
248 227 152 Flavescent
255 233 227 Misty Rose
253 201 201 Bubble Gum
246 162 168 Mauvelous
226 114 133 Tango Pink
178 82 102 China Rose
100 54 75 Wine Dregs
42 30 35 Raisin Black
GIMP Palette
# --------------------------------------------------------
# T h e A A P - S p l e n d o r 1 2 8 P a l e t t e
# --------------------------------------------------------
# Created by Adigun Azikiwe Polack.
# (c)2018 Adigun Azikiwe Polack. All Rights Reserved.
# --------------------------------------------------------
#
# https://twitter.com/AdigunPolack
# http://pixeljoint.com/pixelart/120714.htm
#
5 4 3 Rich Black (FOGRA39)
14 12 12 Smoky Black
45 27 30 Grape Black
97 39 33 Caput Mortuum
185 69 29 Rust
241 100 31 Vivid Vermilion
252 165 112 Light Salmon
255 224 183 Peach Puff
255 255 255 White
255 240 137 Yellow (Crayola)
248 197 58 Saffron
232 138 54 Cadmium Orange
176 91 44 Ruddy Brown
103 57 49 Van Dyke Brown
39 31 27 Dark Bistre
76 61 46 Muddy Taupe
133 95 57 Coyote Brown
211 151 65 Peru
248 246 68 Maximum Yellow
213 220 29 Yellowish Pear
173 184 52 Android Green
127 142 68 Withering Palm Leaf
88 99 53 Deep Yellowish Spring Bud
51 60 36 Kombu Green
24 28 25 Eerie Dark Green
41 63 33 Spring Leather Night Jacket
71 114 56 Spring Fern
97 165 63 Spring Palm Leaf
143 208 50 Yellow-Green
196 241 41 Pear
208 255 234 Aero Blue
151 237 202 Pale Robin Egg Blue
89 207 147 Ocean Green
66 164 89 Middle Green
61 111 67 Fern Green
39 65 45 Withered Leather Jacket
20 18 29 Eerie Dark Blue
27 36 71 Yankees Blue
43 78 149 B'dazzled Blue
39 137 205 Cyan Cornflower Blue
66 191 232 Picton Blue
115 239 232 Medium Sky Blue
241 242 255 Alice Blue
201 212 253 Periwinkle
138 161 246 Jordy Blue
69 114 227 Royal Blue
73 65 130 Dark Slate Blue
120 100 198 Toolbox
156 139 219 Medium Purple
206 170 237 Bright Ube
250 214 255 Pink Lace
238 181 156 Pale Pink
212 128 187 Middle Purple
144 82 188 Deep Lilac
23 21 22 Licorice
55 51 52 Jet Taupe
105 91 89 Wenge
178 139 120 Light Taupe
226 178 126 Middle Yellow Red
246 216 150 Tuscan
252 247 190 Blond
236 235 231 Alabaster
203 198 193 Pale Silver
166 158 154 Quick Silver
128 123 122 Trolley Grey
89 87 87 Davy's Grey
50 50 50 Jet Grey
79 52 47 Acajou
140 91 62 Coconut
198 133 86 Deer
214 168 81 Indian Yellow
180 117 56 Copper
114 75 44 Tuscan Brown
69 42 27 Brown Bistre
97 104 58 Deep Tan Spring Bud
147 148 70 Dark Tan
198 184 88 Vegas Gold
239 221 145 Light Khaki
181 231 203 Magic Mint
134 198 154 Eton Blue
93 155 121 Shiny Shamrock
72 104 89 Feldgrau
44 59 57 Gunmetal Teal
23 24 25 Eerie Black
44 52 56 Gunmetal Turquoise
70 84 86 Davy's Teal
100 135 140 Steel Teal
138 196 195 Pearl Aqua
175 233 223 Powder Blue
220 234 238 Azureish White
184 204 216 Light Steel Blue
136 163 188 Pewter Blue
94 113 142 UCLA Blue
72 82 98 Independence Blue
40 44 60 Gunmetal Blue
70 71 98 Independence Blue-Gray
105 102 130 Dark Blue-Gray
154 151 185 Manatee
197 199 221 Lavender Gray
230 231 240 Glitter
238 230 234 Isabelline
227 205 223 Queen Pink
191 165 201 Lilac
135 115 143 Pomp And Power
86 79 91 Davy's Lavender
50 47 53 Jet Lavender
54 40 43 Burgundy Bistre
101 73 86 Deep Fuchsia Wenge
150 104 136 Antique Fuchsia
192 144 169 Opera Mauve
212 184 184 Pale Magenta
234 224 221 Platinum Pink
241 235 219 Eggshell
221 206 191 Dust Storm
189 164 153 Tuscany
136 110 106 Shadow
89 77 77 Dark Liver
51 39 42 Dark Mahogany-Violet
178 148 118 Light Tanned Taupe
225 191 137 Pale Gold
248 227 152 Flavescent
255 233 227 Misty Rose
253 201 201 Bubble Gum
246 162 168 Mauvelous
226 114 133 Tango Pink
178 82 102 China Rose
100 54 75 Wine Dregs
42 30 35 Raisin Black

View File

@ -1,27 +1,27 @@
GIMP Palette
# ------------------------------------------------------
# S i m p l e J P C - 1 6 P a l e t t e
# ------------------------------------------------------
# Created by Adigun Azikiwe Polack.
# (c)2018 Adigun Azikiwe Polack. All Rights Reserved.
# ------------------------------------------------------
#
# https://twitter.com/AdigunPolack
# http://pixeljoint.com/pixelart/119844.htm
#
5 4 3 Rich Black (FOGRA39)
34 31 49 Raisin Black
84 53 22 Cafe Noir
155 110 45 Metallic Sunburst
225 176 71 Sunray
245 238 155 Flavescent
254 254 254 White
139 225 224 Pale Robin Egg Blue
124 194 100 Mantis
103 143 203 Livid
49 111 35 Mughal Green
64 74 104 Independence
161 77 63 Reddish Coconut
165 104 212 Rich Lavender
154 147 183 Glossy Grape
234 145 130 Dark Salmon
GIMP Palette
# ------------------------------------------------------
# S i m p l e J P C - 1 6 P a l e t t e
# ------------------------------------------------------
# Created by Adigun Azikiwe Polack.
# (c)2018 Adigun Azikiwe Polack. All Rights Reserved.
# ------------------------------------------------------
#
# https://twitter.com/AdigunPolack
# http://pixeljoint.com/pixelart/119844.htm
#
5 4 3 Rich Black (FOGRA39)
34 31 49 Raisin Black
84 53 22 Cafe Noir
155 110 45 Metallic Sunburst
225 176 71 Sunray
245 238 155 Flavescent
254 254 254 White
139 225 224 Pale Robin Egg Blue
124 194 100 Mantis
103 143 203 Livid
49 111 35 Mughal Green
64 74 104 Independence
161 77 63 Reddish Coconut
165 104 212 Rich Lavender
154 147 183 Glossy Grape
234 145 130 Dark Salmon

View File

@ -1,58 +1,58 @@
GIMP Palette
#
0 0 0 Untitled
0 0 0 Untitled
121 121 121 Untitled
162 162 162 Untitled
48 81 130 Untitled
65 146 195 Untitled
97 211 227 Untitled
162 255 243 Untitled
48 97 65 Untitled
73 162 105 Untitled
113 227 146 Untitled
162 255 203 Untitled
56 109 0 Untitled
73 170 16 Untitled
113 243 65 Untitled
162 243 162 Untitled
56 105 0 Untitled
81 162 0 Untitled
154 235 0 Untitled
203 243 130 Untitled
73 89 0 Untitled
138 138 0 Untitled
235 211 32 Untitled
255 243 146 Untitled
121 65 0 Untitled
195 113 0 Untitled
255 162 0 Untitled
255 219 162 Untitled
162 48 0 Untitled
227 81 0 Untitled
255 121 48 Untitled
255 203 186 Untitled
178 16 48 Untitled
219 65 97 Untitled
255 97 178 Untitled
255 186 235 Untitled
154 32 121 Untitled
219 65 195 Untitled
243 97 255 Untitled
227 178 255 Untitled
97 16 162 Untitled
146 65 243 Untitled
162 113 255 Untitled
195 178 255 Untitled
40 0 186 Untitled
65 65 255 Untitled
81 130 255 Untitled
162 186 255 Untitled
32 0 178 Untitled
65 97 251 Untitled
97 162 255 Untitled
146 211 255 Untitled
121 121 121 Untitled
178 178 178 Untitled
235 235 235 Untitled
255 255 255 Untitled
GIMP Palette
#
0 0 0 Untitled
0 0 0 Untitled
121 121 121 Untitled
162 162 162 Untitled
48 81 130 Untitled
65 146 195 Untitled
97 211 227 Untitled
162 255 243 Untitled
48 97 65 Untitled
73 162 105 Untitled
113 227 146 Untitled
162 255 203 Untitled
56 109 0 Untitled
73 170 16 Untitled
113 243 65 Untitled
162 243 162 Untitled
56 105 0 Untitled
81 162 0 Untitled
154 235 0 Untitled
203 243 130 Untitled
73 89 0 Untitled
138 138 0 Untitled
235 211 32 Untitled
255 243 146 Untitled
121 65 0 Untitled
195 113 0 Untitled
255 162 0 Untitled
255 219 162 Untitled
162 48 0 Untitled
227 81 0 Untitled
255 121 48 Untitled
255 203 186 Untitled
178 16 48 Untitled
219 65 97 Untitled
255 97 178 Untitled
255 186 235 Untitled
154 32 121 Untitled
219 65 195 Untitled
243 97 255 Untitled
227 178 255 Untitled
97 16 162 Untitled
146 65 243 Untitled
162 113 255 Untitled
195 178 255 Untitled
40 0 186 Untitled
65 65 255 Untitled
81 130 255 Untitled
162 186 255 Untitled
32 0 178 Untitled
65 97 251 Untitled
97 162 255 Untitled
146 211 255 Untitled
121 121 121 Untitled
178 178 178 Untitled
235 235 235 Untitled
255 255 255 Untitled

View File

@ -12,4 +12,4 @@ Name: Monokai
230 219 116 Yellow
102 217 239 Blue
166 226 46 Green
174 129 255 Purple
174 129 255 Purple

View File

@ -1,222 +1,222 @@
GIMP Palette
Name: Web Safe Colors
Columns: 6
#
# ColorZilla Web Safe Colors palette
#
255 255 255 Untitled
255 255 204 Untitled
255 255 153 Untitled
255 255 102 Untitled
255 255 51 Untitled
255 255 0 Untitled
255 204 255 Untitled
255 204 204 Untitled
255 204 153 Untitled
255 204 102 Untitled
255 204 51 Untitled
255 204 0 Untitled
255 153 255 Untitled
255 153 204 Untitled
255 153 153 Untitled
255 153 102 Untitled
255 153 51 Untitled
255 153 0 Untitled
255 102 255 Untitled
255 102 204 Untitled
255 102 153 Untitled
255 102 102 Untitled
255 102 51 Untitled
255 102 0 Untitled
255 51 255 Untitled
255 51 204 Untitled
255 51 153 Untitled
255 51 102 Untitled
255 51 51 Untitled
255 51 0 Untitled
255 0 255 Untitled
255 0 204 Untitled
255 0 153 Untitled
255 0 102 Untitled
255 0 51 Untitled
255 0 0 Untitled
204 255 255 Untitled
204 255 204 Untitled
204 255 153 Untitled
204 255 102 Untitled
204 255 51 Untitled
204 255 0 Untitled
204 204 255 Untitled
204 204 204 Untitled
204 204 153 Untitled
204 204 102 Untitled
204 204 51 Untitled
204 204 0 Untitled
204 153 255 Untitled
204 153 204 Untitled
204 153 153 Untitled
204 153 102 Untitled
204 153 51 Untitled
204 153 0 Untitled
204 102 255 Untitled
204 102 204 Untitled
204 102 153 Untitled
204 102 102 Untitled
204 102 51 Untitled
204 102 0 Untitled
204 51 255 Untitled
204 51 204 Untitled
204 51 153 Untitled
204 51 102 Untitled
204 51 51 Untitled
204 51 0 Untitled
204 0 255 Untitled
204 0 204 Untitled
204 0 153 Untitled
204 0 102 Untitled
204 0 51 Untitled
204 0 0 Untitled
153 255 255 Untitled
153 255 204 Untitled
153 255 153 Untitled
153 255 102 Untitled
153 255 51 Untitled
153 255 0 Untitled
153 204 255 Untitled
153 204 204 Untitled
153 204 153 Untitled
153 204 102 Untitled
153 204 51 Untitled
153 204 0 Untitled
153 153 255 Untitled
153 153 204 Untitled
153 153 153 Untitled
153 153 102 Untitled
153 153 51 Untitled
153 153 0 Untitled
153 102 255 Untitled
153 102 204 Untitled
153 102 153 Untitled
153 102 102 Untitled
153 102 51 Untitled
153 102 0 Untitled
153 51 255 Untitled
153 51 204 Untitled
153 51 153 Untitled
153 51 102 Untitled
153 51 51 Untitled
153 51 0 Untitled
153 0 255 Untitled
153 0 204 Untitled
153 0 153 Untitled
153 0 102 Untitled
153 0 51 Untitled
153 0 0 Untitled
102 255 255 Untitled
102 255 204 Untitled
102 255 153 Untitled
102 255 102 Untitled
102 255 51 Untitled
102 255 0 Untitled
102 204 255 Untitled
102 204 204 Untitled
102 204 153 Untitled
102 204 102 Untitled
102 204 51 Untitled
102 204 0 Untitled
102 153 255 Untitled
102 153 204 Untitled
102 153 153 Untitled
102 153 102 Untitled
102 153 51 Untitled
102 153 0 Untitled
102 102 255 Untitled
102 102 204 Untitled
102 102 153 Untitled
102 102 102 Untitled
102 102 51 Untitled
102 102 0 Untitled
102 51 255 Untitled
102 51 204 Untitled
102 51 153 Untitled
102 51 102 Untitled
102 51 51 Untitled
102 51 0 Untitled
102 0 255 Untitled
102 0 204 Untitled
102 0 153 Untitled
102 0 102 Untitled
102 0 51 Untitled
102 0 0 Untitled
51 255 255 Untitled
51 255 204 Untitled
51 255 153 Untitled
51 255 102 Untitled
51 255 51 Untitled
51 255 0 Untitled
51 204 255 Untitled
51 204 204 Untitled
51 204 153 Untitled
51 204 102 Untitled
51 204 51 Untitled
51 204 0 Untitled
51 153 255 Untitled
51 153 204 Untitled
51 153 153 Untitled
51 153 102 Untitled
51 153 51 Untitled
51 153 0 Untitled
51 102 255 Untitled
51 102 204 Untitled
51 102 153 Untitled
51 102 102 Untitled
51 102 51 Untitled
51 102 0 Untitled
51 51 255 Untitled
51 51 204 Untitled
51 51 153 Untitled
51 51 102 Untitled
51 51 51 Untitled
51 51 0 Untitled
51 0 255 Untitled
51 0 204 Untitled
51 0 153 Untitled
51 0 102 Untitled
51 0 51 Untitled
51 0 0 Untitled
0 255 255 Untitled
0 255 204 Untitled
0 255 153 Untitled
0 255 102 Untitled
0 255 51 Untitled
0 255 0 Untitled
0 204 255 Untitled
0 204 204 Untitled
0 204 153 Untitled
0 204 102 Untitled
0 204 51 Untitled
0 204 0 Untitled
0 153 255 Untitled
0 153 204 Untitled
0 153 153 Untitled
0 153 102 Untitled
0 153 51 Untitled
0 153 0 Untitled
0 102 255 Untitled
0 102 204 Untitled
0 102 153 Untitled
0 102 102 Untitled
0 102 51 Untitled
0 102 0 Untitled
0 51 255 Untitled
0 51 204 Untitled
0 51 153 Untitled
0 51 102 Untitled
0 51 51 Untitled
0 51 0 Untitled
0 0 255 Untitled
0 0 204 Untitled
0 0 153 Untitled
0 0 102 Untitled
0 0 51 Untitled
0 0 0 Untitled
GIMP Palette
Name: Web Safe Colors
Columns: 6
#
# ColorZilla Web Safe Colors palette
#
255 255 255 Untitled
255 255 204 Untitled
255 255 153 Untitled
255 255 102 Untitled
255 255 51 Untitled
255 255 0 Untitled
255 204 255 Untitled
255 204 204 Untitled
255 204 153 Untitled
255 204 102 Untitled
255 204 51 Untitled
255 204 0 Untitled
255 153 255 Untitled
255 153 204 Untitled
255 153 153 Untitled
255 153 102 Untitled
255 153 51 Untitled
255 153 0 Untitled
255 102 255 Untitled
255 102 204 Untitled
255 102 153 Untitled
255 102 102 Untitled
255 102 51 Untitled
255 102 0 Untitled
255 51 255 Untitled
255 51 204 Untitled
255 51 153 Untitled
255 51 102 Untitled
255 51 51 Untitled
255 51 0 Untitled
255 0 255 Untitled
255 0 204 Untitled
255 0 153 Untitled
255 0 102 Untitled
255 0 51 Untitled
255 0 0 Untitled
204 255 255 Untitled
204 255 204 Untitled
204 255 153 Untitled
204 255 102 Untitled
204 255 51 Untitled
204 255 0 Untitled
204 204 255 Untitled
204 204 204 Untitled
204 204 153 Untitled
204 204 102 Untitled
204 204 51 Untitled
204 204 0 Untitled
204 153 255 Untitled
204 153 204 Untitled
204 153 153 Untitled
204 153 102 Untitled
204 153 51 Untitled
204 153 0 Untitled
204 102 255 Untitled
204 102 204 Untitled
204 102 153 Untitled
204 102 102 Untitled
204 102 51 Untitled
204 102 0 Untitled
204 51 255 Untitled
204 51 204 Untitled
204 51 153 Untitled
204 51 102 Untitled
204 51 51 Untitled
204 51 0 Untitled
204 0 255 Untitled
204 0 204 Untitled
204 0 153 Untitled
204 0 102 Untitled
204 0 51 Untitled
204 0 0 Untitled
153 255 255 Untitled
153 255 204 Untitled
153 255 153 Untitled
153 255 102 Untitled
153 255 51 Untitled
153 255 0 Untitled
153 204 255 Untitled
153 204 204 Untitled
153 204 153 Untitled
153 204 102 Untitled
153 204 51 Untitled
153 204 0 Untitled
153 153 255 Untitled
153 153 204 Untitled
153 153 153 Untitled
153 153 102 Untitled
153 153 51 Untitled
153 153 0 Untitled
153 102 255 Untitled
153 102 204 Untitled
153 102 153 Untitled
153 102 102 Untitled
153 102 51 Untitled
153 102 0 Untitled
153 51 255 Untitled
153 51 204 Untitled
153 51 153 Untitled
153 51 102 Untitled
153 51 51 Untitled
153 51 0 Untitled
153 0 255 Untitled
153 0 204 Untitled
153 0 153 Untitled
153 0 102 Untitled
153 0 51 Untitled
153 0 0 Untitled
102 255 255 Untitled
102 255 204 Untitled
102 255 153 Untitled
102 255 102 Untitled
102 255 51 Untitled
102 255 0 Untitled
102 204 255 Untitled
102 204 204 Untitled
102 204 153 Untitled
102 204 102 Untitled
102 204 51 Untitled
102 204 0 Untitled
102 153 255 Untitled
102 153 204 Untitled
102 153 153 Untitled
102 153 102 Untitled
102 153 51 Untitled
102 153 0 Untitled
102 102 255 Untitled
102 102 204 Untitled
102 102 153 Untitled
102 102 102 Untitled
102 102 51 Untitled
102 102 0 Untitled
102 51 255 Untitled
102 51 204 Untitled
102 51 153 Untitled
102 51 102 Untitled
102 51 51 Untitled
102 51 0 Untitled
102 0 255 Untitled
102 0 204 Untitled
102 0 153 Untitled
102 0 102 Untitled
102 0 51 Untitled
102 0 0 Untitled
51 255 255 Untitled
51 255 204 Untitled
51 255 153 Untitled
51 255 102 Untitled
51 255 51 Untitled
51 255 0 Untitled
51 204 255 Untitled
51 204 204 Untitled
51 204 153 Untitled
51 204 102 Untitled
51 204 51 Untitled
51 204 0 Untitled
51 153 255 Untitled
51 153 204 Untitled
51 153 153 Untitled
51 153 102 Untitled
51 153 51 Untitled
51 153 0 Untitled
51 102 255 Untitled
51 102 204 Untitled
51 102 153 Untitled
51 102 102 Untitled
51 102 51 Untitled
51 102 0 Untitled
51 51 255 Untitled
51 51 204 Untitled
51 51 153 Untitled
51 51 102 Untitled
51 51 51 Untitled
51 51 0 Untitled
51 0 255 Untitled
51 0 204 Untitled
51 0 153 Untitled
51 0 102 Untitled
51 0 51 Untitled
51 0 0 Untitled
0 255 255 Untitled
0 255 204 Untitled
0 255 153 Untitled
0 255 102 Untitled
0 255 51 Untitled
0 255 0 Untitled
0 204 255 Untitled
0 204 204 Untitled
0 204 153 Untitled
0 204 102 Untitled
0 204 51 Untitled
0 204 0 Untitled
0 153 255 Untitled
0 153 204 Untitled
0 153 153 Untitled
0 153 102 Untitled
0 153 51 Untitled
0 153 0 Untitled
0 102 255 Untitled
0 102 204 Untitled
0 102 153 Untitled
0 102 102 Untitled
0 102 51 Untitled
0 102 0 Untitled
0 51 255 Untitled
0 51 204 Untitled
0 51 153 Untitled
0 51 102 Untitled
0 51 51 Untitled
0 51 0 Untitled
0 0 255 Untitled
0 0 204 Untitled
0 0 153 Untitled
0 0 102 Untitled
0 0 51 Untitled
0 0 0 Untitled

View File

@ -685,11 +685,11 @@
<item command="NewFile" text="@.file_new" group="file_new" />
<item command="OpenFile" text="@.file_open" group="file_open" />
<menu text="@.file_open_recent" group="file_recent">
<item command="ReopenClosedFile" text="@.file_reopen_closed" group="file_recent_reopen" />
<item command="ReopenClosedFile" text="@.file_reopen_closed" group="file_recent_reopen" />
<separator id="recent_files_placeholder" group="file_recent_list" />
<separator />
<item command="ClearRecentFiles" text="@.file_clear_recent_files" group="file_recent_clear" />
</menu>
<item command="ClearRecentFiles" text="@.file_clear_recent_files" group="file_recent_clear" />
</menu>
<separator />
<item command="SaveFile" text="@.file_save" />
<item command="SaveFileAs" text="@.file_save_as" group="file_save" />

View File

@ -1,12 +1,12 @@
# Aseprite Translations
Aseprite is translated using the following Weblate project:
https://hosted.weblate.org/projects/aseprite/aseprite/
You can find all the translations in this other repository:
https://github.com/aseprite/strings
The official English strings are from the [`en.ini` file here](https://github.com/aseprite/aseprite/blob/main/data/strings/en.ini),
and this file will be copied to the [strings repository](https://github.com/aseprite/strings/blob/main/en.ini) regularly.
# Aseprite Translations
Aseprite is translated using the following Weblate project:
https://hosted.weblate.org/projects/aseprite/aseprite/
You can find all the translations in this other repository:
https://github.com/aseprite/strings
The official English strings are from the [`en.ini` file here](https://github.com/aseprite/aseprite/blob/main/data/strings/en.ini),
and this file will be copied to the [strings repository](https://github.com/aseprite/strings/blob/main/en.ini) regularly.

View File

@ -8,14 +8,14 @@
<label text="Animated sprite editor &amp;&amp; pixel art tool" />
<hbox homogeneous="true">
<hbox>
<vbox expansive="true">
<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" />
<vbox minheight="8" />
</vbox>
<separator vertical="true" />
</hbox>
<vbox>
<separator text="Credits" horizontal="true" cell_hspan="2" />

View File

@ -1,58 +1,58 @@
<!-- Aseprite -->
<!-- Copyright (C) 2019-2024 Igara Studio S.A. -->
<!-- Copyright (C) 2001-2018 David Capello -->
<gui>
<window id="canvas_size" text="@.title" help="canvas">
<vbox>
<separator text="@.size" left="true" horizontal="true" />
<hbox>
<grid columns="2">
<label text="@.width" />
<expr text="0" id="width" suffix="px" magnet="true" />
<label text="@.height" />
<expr text="0" id="height" suffix="px" />
<hbox filler="true" cell_hspan="2" />
</grid>
<buttonset columns="3" id="dir">
<item icon="canvas_nw" style="dir_item" />
<item icon="canvas_n" style="dir_item" />
<item icon="canvas_ne" style="dir_item" />
<item icon="canvas_w" style="dir_item" />
<item icon="canvas_c" style="dir_item" />
<item icon="canvas_e" style="dir_item" />
<item icon="canvas_sw" style="dir_item" />
<item icon="canvas_s" style="dir_item" />
<item icon="canvas_se" style="dir_item" />
</buttonset>
</hbox>
<separator text="@.borders" left="true" horizontal="true" />
<grid columns="4">
<label text="@.left" />
<expr text="0" id="left" suffix="px" tooltip="@.left_tooltip" />
<label text="@.top" />
<expr text="0" id="top" suffix="px" tooltip="@.top_tooltip" />
<label text="@.right" />
<expr text="0" id="right" suffix="px" tooltip="@.right_tooltip" />
<label text="@.bottom" />
<expr text="0" id="bottom" suffix="px" tooltip="@.bottom_tooltip" />
</grid>
<separator horizontal="true" />
<check id="trim" text="@.trim" tooltip="@.trim_tooltip" />
<separator horizontal="true" />
<hbox>
<boxfiller />
<hbox homogeneous="true">
<button text="@general.ok" closewindow="true" id="ok" magnet="true" minwidth="60" />
<button text="@general.cancel" closewindow="true" />
</hbox>
</hbox>
</vbox>
</window>
</gui>
<!-- Aseprite -->
<!-- Copyright (C) 2019-2024 Igara Studio S.A. -->
<!-- Copyright (C) 2001-2018 David Capello -->
<gui>
<window id="canvas_size" text="@.title" help="canvas">
<vbox>
<separator text="@.size" left="true" horizontal="true" />
<hbox>
<grid columns="2">
<label text="@.width" />
<expr text="0" id="width" suffix="px" magnet="true" />
<label text="@.height" />
<expr text="0" id="height" suffix="px" />
<hbox filler="true" cell_hspan="2" />
</grid>
<buttonset columns="3" id="dir">
<item icon="canvas_nw" style="dir_item" />
<item icon="canvas_n" style="dir_item" />
<item icon="canvas_ne" style="dir_item" />
<item icon="canvas_w" style="dir_item" />
<item icon="canvas_c" style="dir_item" />
<item icon="canvas_e" style="dir_item" />
<item icon="canvas_sw" style="dir_item" />
<item icon="canvas_s" style="dir_item" />
<item icon="canvas_se" style="dir_item" />
</buttonset>
</hbox>
<separator text="@.borders" left="true" horizontal="true" />
<grid columns="4">
<label text="@.left" />
<expr text="0" id="left" suffix="px" tooltip="@.left_tooltip" />
<label text="@.top" />
<expr text="0" id="top" suffix="px" tooltip="@.top_tooltip" />
<label text="@.right" />
<expr text="0" id="right" suffix="px" tooltip="@.right_tooltip" />
<label text="@.bottom" />
<expr text="0" id="bottom" suffix="px" tooltip="@.bottom_tooltip" />
</grid>
<separator horizontal="true" />
<check id="trim" text="@.trim" tooltip="@.trim_tooltip" />
<separator horizontal="true" />
<hbox>
<boxfiller />
<hbox homogeneous="true">
<button text="@general.ok" closewindow="true" id="ok" magnet="true" minwidth="60" />
<button text="@general.cancel" closewindow="true" />
</hbox>
</hbox>
</vbox>
</window>
</gui>

View File

@ -1,20 +1,20 @@
<!-- Aseprite -->
<!-- Copyright (C) 2020-2024 by Igara Studio S.A. -->
<!-- Copyright (C) 2001-2016 by David Capello -->
<gui>
<window id="cel_properties" text="@.title">
<grid id="properties_grid" columns="4">
<label text="@.opacity" />
<opacityslider id="opacity" cell_align="horizontal" width="128" cell_hspan="2" />
<button id="user_data" icon="icon_user_data" tooltip="@.user_data_tooltip" />
<label text="@.zindex" />
<expr id="zindex" cell_align="horizontal" width="128" />
<buttonset id="zindex_spin" columns="1">
<item icon="spin_up" />
<item icon="spin_down" />
</buttonset>
<boxfiller />
</grid>
</window>
</gui>
<!-- Aseprite -->
<!-- Copyright (C) 2020-2024 by Igara Studio S.A. -->
<!-- Copyright (C) 2001-2016 by David Capello -->
<gui>
<window id="cel_properties" text="@.title">
<grid id="properties_grid" columns="4">
<label text="@.opacity" />
<opacityslider id="opacity" cell_align="horizontal" width="128" cell_hspan="2" />
<button id="user_data" icon="icon_user_data" tooltip="@.user_data_tooltip" />
<label text="@.zindex" />
<expr id="zindex" cell_align="horizontal" width="128" />
<buttonset id="zindex_spin" columns="1">
<item icon="spin_up" />
<item icon="spin_down" />
</buttonset>
<boxfiller />
</grid>
</window>
</gui>

View File

@ -1,45 +1,45 @@
<!-- Aseprite -->
<!-- Copyright (C) 2019-2024 Igara Studio S.A. -->
<!-- Copyright (C) 2017 David Capello -->
<gui>
<window id="color_mode" text="@.title">
<vbox>
<view id="color_mode_view" expansive="true">
<listbox id="color_mode" />
</view>
<hbox id="dithering_placeholder" />
<hbox id="amount">
<label text="@.amount" />
<slider min="0" max="100" id="factor" minwidth="100" />
<label text="%" />
</hbox>
<combobox id="to_gray_combobox">
<listitem text="!Luminance" />
<listitem text="!HSV" />
<listitem text="!HSL" />
</combobox>
<check text="@.flatten" id="flatten" />
<check id="advanced_check" text="@general.advanced_options" />
<grid id="advanced" columns="2">
<label text="@rgbmap_algorithm_selector.label" />
<hbox id="rgbmap_algorithm_placeholder" cell_align="horizontal" />
<label text="@best_fit_criteria_selector.label" />
<hbox id="best_fit_criteria_placeholder" cell_align="horizontal" />
</grid>
<separator horizontal="true" />
<hbox>
<slider min="0" max="100" id="progress" minwidth="100" />
<boxfiller />
<hbox homogeneous="true">
<button text="@general.ok" closewindow="true" id="ok" magnet="true" minwidth="60" />
<button text="@general.cancel" closewindow="true" />
</hbox>
</hbox>
</vbox>
</window>
</gui>
<!-- Aseprite -->
<!-- Copyright (C) 2019-2024 Igara Studio S.A. -->
<!-- Copyright (C) 2017 David Capello -->
<gui>
<window id="color_mode" text="@.title">
<vbox>
<view id="color_mode_view" expansive="true">
<listbox id="color_mode" />
</view>
<hbox id="dithering_placeholder" />
<hbox id="amount">
<label text="@.amount" />
<slider min="0" max="100" id="factor" minwidth="100" />
<label text="%" />
</hbox>
<combobox id="to_gray_combobox">
<listitem text="!Luminance" />
<listitem text="!HSV" />
<listitem text="!HSL" />
</combobox>
<check text="@.flatten" id="flatten" />
<check id="advanced_check" text="@general.advanced_options" />
<grid id="advanced" columns="2">
<label text="@rgbmap_algorithm_selector.label" />
<hbox id="rgbmap_algorithm_placeholder" cell_align="horizontal" />
<label text="@best_fit_criteria_selector.label" />
<hbox id="best_fit_criteria_placeholder" cell_align="horizontal" />
</grid>
<separator horizontal="true" />
<hbox>
<slider min="0" max="100" id="progress" minwidth="100" />
<boxfiller />
<hbox homogeneous="true">
<button text="@general.ok" closewindow="true" id="ok" magnet="true" minwidth="60" />
<button text="@general.cancel" closewindow="true" />
</hbox>
</hbox>
</vbox>
</window>
</gui>

View File

@ -1,12 +1,12 @@
<!-- Aseprite -->
<!-- Copyright (C) 2001-2016 by David Capello -->
<gui>
<box vertical="true" id="controls" expansive="true">
<view expansive="true" id="view" minwidth="128" minheight="64">
<listbox id="stock" />
</view>
<box horizontal="true">
<button text="@convolution_matrix.reload_stock" id="reload" />
</box>
</box>
</gui>
<!-- Aseprite -->
<!-- Copyright (C) 2001-2016 by David Capello -->
<gui>
<box vertical="true" id="controls" expansive="true">
<view expansive="true" id="view" minwidth="128" minheight="64">
<listbox id="stock" />
</view>
<box horizontal="true">
<button text="@convolution_matrix.reload_stock" id="reload" />
</box>
</box>
</gui>

View File

@ -1,12 +1,12 @@
<!-- Aseprite -->
<!-- Copyright (C) 2001-2018 by David Capello -->
<gui>
<hbox id="despeckle">
<grid columns="2">
<label text="@.width" />
<expr id="width" cell_align="horizontal" />
<label text="@.height" />
<expr id="height" cell_align="horizontal" />
</grid>
</hbox>
</gui>
<!-- Aseprite -->
<!-- Copyright (C) 2001-2018 by David Capello -->
<gui>
<hbox id="despeckle">
<grid columns="2">
<label text="@.width" />
<expr id="width" cell_align="horizontal" />
<label text="@.height" />
<expr id="height" cell_align="horizontal" />
</grid>
</hbox>
</gui>

View File

@ -1,23 +1,23 @@
<!-- Aseprite -->
<!-- Copyright (C) 2001-2016 by David Capello -->
<gui>
<window id="duplicate_sprite" text="@.title">
<box vertical="true">
<box horizontal="true" expansive="true">
<box vertical="true" homogeneous="true">
<label text="@.duplicate" />
<label text="@.as" />
</box>
<box vertical="true" homogeneous="true" expansive="true">
<label text="" id="src_name" />
<entry maxsize="256" id="dst_name" magnet="true" />
</box>
</box>
<check text="@.merged_layers" id="flatten" />
<box horizontal="true" homogeneous="true">
<button text="@general.ok" closewindow="true" id="ok" magnet="true" />
<button text="@general.cancel" closewindow="true" />
</box>
</box>
</window>
</gui>
<!-- Aseprite -->
<!-- Copyright (C) 2001-2016 by David Capello -->
<gui>
<window id="duplicate_sprite" text="@.title">
<box vertical="true">
<box horizontal="true" expansive="true">
<box vertical="true" homogeneous="true">
<label text="@.duplicate" />
<label text="@.as" />
</box>
<box vertical="true" homogeneous="true" expansive="true">
<label text="" id="src_name" />
<entry maxsize="256" id="dst_name" magnet="true" />
</box>
</box>
<check text="@.merged_layers" id="flatten" />
<box horizontal="true" homogeneous="true">
<button text="@general.ok" closewindow="true" id="ok" magnet="true" />
<button text="@general.cancel" closewindow="true" />
</box>
</box>
</window>
</gui>

View File

@ -1,58 +1,58 @@
<!-- Aseprite -->
<!-- Copyright (C) 2022-2024 by Igara Studio S.A. -->
<!-- Copyright (C) 2016-2018 by David Capello -->
<gui>
<window id="export_file" text="@.title" help="exporting">
<grid columns="3">
<label text="@.output_file" />
<entry id="output_filename" cell_align="horizontal" maxsize="1024" maxwidth="256" />
<button id="output_filename_browse" text="..." style="mini_button" />
<label id="resize_label" text="@.resize" />
<hbox cell_hspan="2" cell_align="horizontal">
<combobox id="resize" editable="true" suffix="%" expansive="true">
<listitem text="25" />
<listitem text="50" />
<listitem text="100" />
<listitem text="200" />
<listitem text="300" />
<listitem text="400" />
<listitem text="500" />
<listitem text="600" />
<listitem text="700" />
<listitem text="800" />
<listitem text="900" />
<listitem text="1000" />
</combobox>
<label id="area_label" text="@.area" />
<combobox id="area" text="" cell_align="horizontal" cell_hspan="2" expansive="true" />
</hbox>
<label id="layers_label" text="@.layers" />
<combobox id="layers" text="" cell_align="horizontal" cell_hspan="2" />
<label id="frames_label" text="@.frames" />
<combobox id="frames" text="" cell_align="horizontal" cell_hspan="2" />
<label id="anidir_label" text="@.anidir" />
<combobox id="anidir" text="" cell_align="horizontal" cell_hspan="2" />
<check id="play_subtags" text="@.play_subtags" cell_hspan="3" />
<check id="pixel_ratio" text="@.pixel_ratio" cell_hspan="3" />
<hbox cell_hspan="3">
<check id="for_twitter" text="@.for_twitter" tooltip="@.for_twitter_tooltip" />
<button id="adjust_resize" text="@.adjust_resize" style="mini_button" />
</hbox>
<hbox cell_hspan="3">
<boxfiller />
<hbox homogeneous="true">
<button text="@.export" minwidth="60" id="ok" magnet="true" />
<button text="@.cancel" minwidth="60" closewindow="true" />
</hbox>
</hbox>
</grid>
</window>
</gui>
<!-- Aseprite -->
<!-- Copyright (C) 2022-2024 by Igara Studio S.A. -->
<!-- Copyright (C) 2016-2018 by David Capello -->
<gui>
<window id="export_file" text="@.title" help="exporting">
<grid columns="3">
<label text="@.output_file" />
<entry id="output_filename" cell_align="horizontal" maxsize="1024" maxwidth="256" />
<button id="output_filename_browse" text="..." style="mini_button" />
<label id="resize_label" text="@.resize" />
<hbox cell_hspan="2" cell_align="horizontal">
<combobox id="resize" editable="true" suffix="%" expansive="true">
<listitem text="25" />
<listitem text="50" />
<listitem text="100" />
<listitem text="200" />
<listitem text="300" />
<listitem text="400" />
<listitem text="500" />
<listitem text="600" />
<listitem text="700" />
<listitem text="800" />
<listitem text="900" />
<listitem text="1000" />
</combobox>
<label id="area_label" text="@.area" />
<combobox id="area" text="" cell_align="horizontal" cell_hspan="2" expansive="true" />
</hbox>
<label id="layers_label" text="@.layers" />
<combobox id="layers" text="" cell_align="horizontal" cell_hspan="2" />
<label id="frames_label" text="@.frames" />
<combobox id="frames" text="" cell_align="horizontal" cell_hspan="2" />
<label id="anidir_label" text="@.anidir" />
<combobox id="anidir" text="" cell_align="horizontal" cell_hspan="2" />
<check id="play_subtags" text="@.play_subtags" cell_hspan="3" />
<check id="pixel_ratio" text="@.pixel_ratio" cell_hspan="3" />
<hbox cell_hspan="3">
<check id="for_twitter" text="@.for_twitter" tooltip="@.for_twitter_tooltip" />
<button id="adjust_resize" text="@.adjust_resize" style="mini_button" />
</hbox>
<hbox cell_hspan="3">
<boxfiller />
<hbox homogeneous="true">
<button text="@.export" minwidth="60" id="ok" magnet="true" />
<button text="@.cancel" minwidth="60" closewindow="true" />
</hbox>
</hbox>
</grid>
</window>
</gui>

View File

@ -1,44 +1,44 @@
<!-- Aseprite -->
<!-- Copyright (C) 2019-2022 Igara Studio S.A. -->
<!-- Copyright (C) 2001-2018 David Capello -->
<gui>
<window id="file_selector" text="">
<vbox id="main">
<box horizontal="true">
<hbox noborders="true">
<button text="" id="go_back_button" style="go_back_button"
tooltip="@.go_back_button_tooltip" tooltip_dir="bottom" />
<button text="" id="go_forward_button" style="go_forward_button"
tooltip="@.go_forward_button_tooltip" tooltip_dir="bottom" />
</hbox>
<button text="" id="go_up_button" style="go_up_button"
tooltip="@.go_up_button_tooltip" tooltip_dir="bottom" />
<button text="" id="new_folder_button" style="new_folder_button"
tooltip="@.new_folder_button_tooltip" tooltip_dir="bottom" />
<buttonset id="view_type" columns="3">
<item icon="list_view" tooltip="@.list_view_button_tooltip" tooltip_dir="bottom" />
<item icon="small_icon_view" tooltip="@.small_icon_view_button_tooltip" tooltip_dir="bottom" />
<item icon="big_icon_view" tooltip="@.big_icon_view_button_tooltip" tooltip_dir="bottom" />
</buttonset>
<combobox id="location" expansive="true" />
<button text="" id="refresh_button" style="refresh_button"
tooltip="@.refresh_button_tooltip" tooltip_dir="bottom" />
</box>
<vbox id="file_view_placeholder" expansive="true" />
<grid columns="2">
<label text="@.file_name" />
<box id="file_name_placeholder" cell_align="horizontal" />
<label text="@.file_type" />
<hbox cell_align="horizontal">
<combobox id="file_type" minwidth="70" />
<boxfiller />
<box horizontal="true" homogeneous="true">
<button text="@general.ok" closewindow="true" id="ok" magnet="true" minwidth="60" />
<button text="@general.cancel" closewindow="true" id="cancel" />
</box>
</hbox>
</grid>
</vbox>
</window>
</gui>
<!-- Aseprite -->
<!-- Copyright (C) 2019-2022 Igara Studio S.A. -->
<!-- Copyright (C) 2001-2018 David Capello -->
<gui>
<window id="file_selector" text="">
<vbox id="main">
<box horizontal="true">
<hbox noborders="true">
<button text="" id="go_back_button" style="go_back_button"
tooltip="@.go_back_button_tooltip" tooltip_dir="bottom" />
<button text="" id="go_forward_button" style="go_forward_button"
tooltip="@.go_forward_button_tooltip" tooltip_dir="bottom" />
</hbox>
<button text="" id="go_up_button" style="go_up_button"
tooltip="@.go_up_button_tooltip" tooltip_dir="bottom" />
<button text="" id="new_folder_button" style="new_folder_button"
tooltip="@.new_folder_button_tooltip" tooltip_dir="bottom" />
<buttonset id="view_type" columns="3">
<item icon="list_view" tooltip="@.list_view_button_tooltip" tooltip_dir="bottom" />
<item icon="small_icon_view" tooltip="@.small_icon_view_button_tooltip" tooltip_dir="bottom" />
<item icon="big_icon_view" tooltip="@.big_icon_view_button_tooltip" tooltip_dir="bottom" />
</buttonset>
<combobox id="location" expansive="true" />
<button text="" id="refresh_button" style="refresh_button"
tooltip="@.refresh_button_tooltip" tooltip_dir="bottom" />
</box>
<vbox id="file_view_placeholder" expansive="true" />
<grid columns="2">
<label text="@.file_name" />
<box id="file_name_placeholder" cell_align="horizontal" />
<label text="@.file_type" />
<hbox cell_align="horizontal">
<combobox id="file_type" minwidth="70" />
<boxfiller />
<box horizontal="true" homogeneous="true">
<button text="@general.ok" closewindow="true" id="ok" magnet="true" minwidth="60" />
<button text="@general.cancel" closewindow="true" id="cancel" />
</box>
</hbox>
</grid>
</vbox>
</window>
</gui>

View File

@ -1,24 +1,24 @@
<!-- Aseprite -->
<!-- Copyright (C) 2020 Igara Studio S.A. -->
<!-- Copyright (C) 2014-2018 David Capello -->
<gui>
<window id="gif_options" text="@.title">
<vbox>
<separator text="@.general_options" left="true" horizontal="true" />
<check text="@.interlaced" id="interlaced" />
<check text="@.animation_loop" id="loop" />
<check text="@.preserve_palette_order" id="preserve_palette_order" />
<separator horizontal="true" />
<hbox>
<check text="@general.dont_show" id="dont_show" tooltip="@general.dont_show_tooltip" />
<boxfiller />
<hbox homogeneous="true">
<button text="@general.ok" closewindow="true" id="ok" magnet="true" minwidth="60" />
<button text="@general.cancel" closewindow="true" />
</hbox>
</hbox>
</vbox>
</window>
</gui>
<!-- Aseprite -->
<!-- Copyright (C) 2020 Igara Studio S.A. -->
<!-- Copyright (C) 2014-2018 David Capello -->
<gui>
<window id="gif_options" text="@.title">
<vbox>
<separator text="@.general_options" left="true" horizontal="true" />
<check text="@.interlaced" id="interlaced" />
<check text="@.animation_loop" id="loop" />
<check text="@.preserve_palette_order" id="preserve_palette_order" />
<separator horizontal="true" />
<hbox>
<check text="@general.dont_show" id="dont_show" tooltip="@general.dont_show_tooltip" />
<boxfiller />
<hbox homogeneous="true">
<button text="@general.ok" closewindow="true" id="ok" magnet="true" minwidth="60" />
<button text="@general.cancel" closewindow="true" />
</hbox>
</hbox>
</vbox>
</window>
</gui>

View File

@ -1,17 +1,17 @@
<!-- Aseprite -->
<!-- Copyright (C) 2001-2017 by David Capello -->
<gui>
<window id="goto_frame" text="@.title">
<vbox>
<label text="@.frame_or_tags" />
<vbox id="frame_placeholder" />
<separator horizontal="true" />
<hbox homogeneous="true" cell_align="right">
<button text="@general.ok" closewindow="true" id="ok" magnet="true" minwidth="60" />
<button text="@general.cancel" closewindow="true" />
</hbox>
</vbox>
</window>
</gui>
<!-- Aseprite -->
<!-- Copyright (C) 2001-2017 by David Capello -->
<gui>
<window id="goto_frame" text="@.title">
<vbox>
<label text="@.frame_or_tags" />
<vbox id="frame_placeholder" />
<separator horizontal="true" />
<hbox homogeneous="true" cell_align="right">
<button text="@general.ok" closewindow="true" id="ok" magnet="true" minwidth="60" />
<button text="@general.cancel" closewindow="true" />
</hbox>
</vbox>
</window>
</gui>

View File

@ -1,27 +1,27 @@
<!-- Aseprite -->
<!-- Copyright (C) 2001-2018 by David Capello -->
<gui>
<window id="grid_settings" text="@.title">
<grid columns="4">
<label text="@.x" />
<expr id="grid_x" text="" magnet="true" />
<label text="@.y" />
<expr id="grid_y" text="" />
<label text="@.width" />
<expr id="grid_w" text="" />
<label text="@.height" />
<expr id="grid_h" text="" />
<separator horizontal="true" cell_hspan="4" />
<box horizontal="true" homogeneous="true" cell_hspan="4" cell_align="right">
<button text="@general.ok" closewindow="true" id="ok" magnet="true" minwidth="60" />
<button text="@general.cancel" closewindow="true" />
</box>
</grid>
</window>
</gui>
<!-- Aseprite -->
<!-- Copyright (C) 2001-2018 by David Capello -->
<gui>
<window id="grid_settings" text="@.title">
<grid columns="4">
<label text="@.x" />
<expr id="grid_x" text="" magnet="true" />
<label text="@.y" />
<expr id="grid_y" text="" />
<label text="@.width" />
<expr id="grid_w" text="" />
<label text="@.height" />
<expr id="grid_h" text="" />
<separator horizontal="true" cell_hspan="4" />
<box horizontal="true" homogeneous="true" cell_hspan="4" cell_align="right">
<button text="@general.ok" closewindow="true" id="ok" magnet="true" minwidth="60" />
<button text="@general.cancel" closewindow="true" />
</box>
</grid>
</window>
</gui>

View File

@ -1,42 +1,42 @@
<!-- Aseprite -->
<!-- Copyright (C) 2019-2021 Igara Studio S.A. -->
<!-- Copyright (C) 2001-2017 David Capello -->
<gui>
<vbox noborders="true" id="home_view" border="4" childspacing="2" expansive="true">
<hbox noborders="true" id="header_placeholder">
<link id="aseprite_face" style="aseprite_face" />
<vbox border="4" childspacing="4">
<link id="new_file" text="@.new_file" style="workspace_link" />
<link id="open_file" text="@.open_file" style="workspace_link" />
<link id="recover_sprites" text="@.recover_files" style="workspace_link"
tooltip="@.recover_files_tooltip" />
</vbox>
<boxfiller />
<vbox border="4">
<check id="share_crashdb" text="@.share_crashdb"
tooltip="@.share_crashdb_tooltip" style="workspace_check_box" />
<link id="check_update" text="" style="workspace_link" />
</vbox>
</hbox>
<splitter horizontal="true" noborders="true" childspacing="2"
expansive="true" by="percetage" position="50"
style="workspace_splitter">
<splitter vertical="true" noborders="true" childspacing="2"
style="workspace_splitter">
<vbox id="files_placeholder">
<label text="@home_view.recent_files" style="workspace_label" />
<view id="files_view" expansive="true" style="workspace_view" />
</vbox>
<vbox id="folders_placeholder">
<label text="@home_view.recent_folders" style="workspace_label" />
<view id="folders_view" expansive="true" style="workspace_view" />
</vbox>
</splitter>
<vbox id="news_placeholder" noborders="true" childspacing="2">
<label text="@home_view.news" style="workspace_label" />
<view id="news_view" expansive="true" style="workspace_view" />
</vbox>
</splitter>
</vbox>
</gui>
<!-- Aseprite -->
<!-- Copyright (C) 2019-2021 Igara Studio S.A. -->
<!-- Copyright (C) 2001-2017 David Capello -->
<gui>
<vbox noborders="true" id="home_view" border="4" childspacing="2" expansive="true">
<hbox noborders="true" id="header_placeholder">
<link id="aseprite_face" style="aseprite_face" />
<vbox border="4" childspacing="4">
<link id="new_file" text="@.new_file" style="workspace_link" />
<link id="open_file" text="@.open_file" style="workspace_link" />
<link id="recover_sprites" text="@.recover_files" style="workspace_link"
tooltip="@.recover_files_tooltip" />
</vbox>
<boxfiller />
<vbox border="4">
<check id="share_crashdb" text="@.share_crashdb"
tooltip="@.share_crashdb_tooltip" style="workspace_check_box" />
<link id="check_update" text="" style="workspace_link" />
</vbox>
</hbox>
<splitter horizontal="true" noborders="true" childspacing="2"
expansive="true" by="percetage" position="50"
style="workspace_splitter">
<splitter vertical="true" noborders="true" childspacing="2"
style="workspace_splitter">
<vbox id="files_placeholder">
<label text="@home_view.recent_files" style="workspace_label" />
<view id="files_view" expansive="true" style="workspace_view" />
</vbox>
<vbox id="folders_placeholder">
<label text="@home_view.recent_folders" style="workspace_label" />
<view id="folders_view" expansive="true" style="workspace_view" />
</vbox>
</splitter>
<vbox id="news_placeholder" noborders="true" childspacing="2">
<label text="@home_view.news" style="workspace_label" />
<view id="news_view" expansive="true" style="workspace_view" />
</vbox>
</splitter>
</vbox>
</gui>

View File

@ -1,54 +1,54 @@
<!-- Aseprite -->
<!-- Copyright (C) 2019-2024 by Igara Studio S.A. -->
<!-- Copyright (C) 2001-2018 by David Capello -->
<gui>
<window id="import_sprite_sheet" text="@.title" help="sprite-sheet#import">
<vbox>
<grid columns="4">
<button id="select_file" text="@select_file.text" cell_hspan="4" />
<label text="@.type" />
<combobox id="sheet_type" cell_hspan="3" />
<separator text="@.tiles" horizontal="true" cell_hspan="4" />
<label text="@.x" />
<expr id="x" text="0" />
<label text="@.y" />
<expr id="y" text="0" />
<label text="@.width" />
<expr id="width" text="16" />
<label text="@.height" />
<expr id="height" text="16" />
<separator horizontal="true" cell_hspan="4" />
<label text="@.columns" />
<expr id="columns" />
<label text="@.rows" />
<expr id="rows" />
<check id="padding_enabled" text="@.padding" cell_hspan="4" />
<label text="@.horizontal_padding" id="horizontal_padding_label" />
<expr id="horizontal_padding" text="0" />
<label text="@.vertical_padding" id="vertical_padding_label" />
<expr id="vertical_padding" text="0" />
<check id="partial_tiles" text="@.partial_tiles" cell_hspan="4" />
<hbox cell_hspan="4">
<boxfiller />
<hbox>
</hbox>
<button id="import" text="@.import" minwidth="60" magnet="true" cell_align="center" closewindow="true" />
<button id="cancel" text="@.cancel" minwidth="60" cell_align="center" closewindow="true" />
</hbox>
</grid>
</vbox>
</window>
</gui>
<!-- Aseprite -->
<!-- Copyright (C) 2019-2024 by Igara Studio S.A. -->
<!-- Copyright (C) 2001-2018 by David Capello -->
<gui>
<window id="import_sprite_sheet" text="@.title" help="sprite-sheet#import">
<vbox>
<grid columns="4">
<button id="select_file" text="@select_file.text" cell_hspan="4" />
<label text="@.type" />
<combobox id="sheet_type" cell_hspan="3" />
<separator text="@.tiles" horizontal="true" cell_hspan="4" />
<label text="@.x" />
<expr id="x" text="0" />
<label text="@.y" />
<expr id="y" text="0" />
<label text="@.width" />
<expr id="width" text="16" />
<label text="@.height" />
<expr id="height" text="16" />
<separator horizontal="true" cell_hspan="4" />
<label text="@.columns" />
<expr id="columns" />
<label text="@.rows" />
<expr id="rows" />
<check id="padding_enabled" text="@.padding" cell_hspan="4" />
<label text="@.horizontal_padding" id="horizontal_padding_label" />
<expr id="horizontal_padding" text="0" />
<label text="@.vertical_padding" id="vertical_padding_label" />
<expr id="vertical_padding" text="0" />
<check id="partial_tiles" text="@.partial_tiles" cell_hspan="4" />
<hbox cell_hspan="4">
<boxfiller />
<hbox>
</hbox>
<button id="import" text="@.import" minwidth="60" magnet="true" cell_align="center" closewindow="true" />
<button id="cancel" text="@.cancel" minwidth="60" cell_align="center" closewindow="true" />
</hbox>
</grid>
</vbox>
</window>
</gui>

View File

@ -1,21 +1,21 @@
<!-- Aseprite -->
<!-- Copyright (C) 2001-2018 by David Capello -->
<gui>
<window id="jpeg_options" text="@.title">
<grid columns="2">
<label text="@.quality" />
<slider min="0" max="10" id="quality" cell_align="horizontal" width="128" />
<separator horizontal="true" cell_hspan="2" />
<hbox cell_hspan="2">
<check text="@general.dont_show" id="dont_show" tooltip="@general.dont_show_tooltip" />
<boxfiller />
<hbox homogeneous="true">
<button text="@general.ok" closewindow="true" id="ok" magnet="true" minwidth="60" />
<button text="@general.cancel" closewindow="true" />
</hbox>
</hbox>
</grid>
</window>
</gui>
<!-- Aseprite -->
<!-- Copyright (C) 2001-2018 by David Capello -->
<gui>
<window id="jpeg_options" text="@.title">
<grid columns="2">
<label text="@.quality" />
<slider min="0" max="10" id="quality" cell_align="horizontal" width="128" />
<separator horizontal="true" cell_hspan="2" />
<hbox cell_hspan="2">
<check text="@general.dont_show" id="dont_show" tooltip="@general.dont_show_tooltip" />
<boxfiller />
<hbox homogeneous="true">
<button text="@general.ok" closewindow="true" id="ok" magnet="true" minwidth="60" />
<button text="@general.cancel" closewindow="true" />
</hbox>
</hbox>
</grid>
</window>
</gui>

View File

@ -1,124 +1,124 @@
<!-- Aseprite -->
<!-- Copyright (C) 2018-2024 Igara Studio S.A. -->
<!-- Copyright (C) 2001-2016 David Capello -->
<gui>
<window id="keyboard_shortcuts" text="@keyboard_shortcuts.title" help="keyboard-shortcuts">
<vbox>
<splitter horizontal="true" expansive="true" noborders="true" childspacing="2"
by="pixel" position="80" id="section_splitter">
<vbox expansive="true">
<search id="search" magnet="true" />
<view expansive="true">
<listbox id="section" expansive="true">
<listitem text="@.section_menus" />
<listitem text="@.section_commands" />
<listitem text="@.section_tools" />
<listitem text="@.section_action_modifiers" />
<listitem text="@.section_mouse_wheel" />
<listitem text="@.section_drag_value" />
</listbox>
</view>
<separator horizontal="true" />
<button text="@keyboard_shortcuts.import" id="import_button" />
<button text="@keyboard_shortcuts.export" id="export_button" />
<button text="@keyboard_shortcuts.reset" id="reset_button" />
</vbox>
<vbox id="lists_placeholder" expansive="true">
<view id="search_view" expansive="true">
<listbox id="search_list" />
</view>
<view id="menus_view" expansive="true">
<listbox id="menus" />
</view>
<view id="commands_view" expansive="true">
<listbox id="commands" />
</view>
<view id="tools_view" expansive="true">
<listbox id="tools" />
</view>
<view id="actions_view" expansive="true">
<listbox id="actions" />
</view>
<vbox id="wheel_section" expansive="true">
<hbox>
<buttonset columns="2" id="wheel_behavior">
<item text="@.default_wheel_behavior" />
<item text="@.custom_wheel_behavior" />
</buttonset>
</hbox>
<check text="@options.wheel_zoom" id="wheel_zoom"
pref="editor.zoom_with_wheel" />
<check text="@options.slide_zoom" id="slide_zoom"
pref="editor.zoom_with_slide" />
<check text="@.invert_brush_size_wheel" id="invert_brush_size_scroll"
pref="editor.invert_brush_size_wheel" />
<view expansive="true">
<listbox id="wheel_actions" />
</view>
</vbox>
<vbox id="drag_section" expansive="true">
<view expansive="true">
<listbox id="drag_actions" />
</view>
<separator horizontal="true" />
<hbox>
<vbox>
<label text="@.drag_angle" />
</vbox>
<buttonset columns="3" id="drag_angle">
<item icon="canvas_nw"
style="dir_item"
tooltip="@.drag_angle_tooltip"
tooltip_dir="bottom" />
<item icon="canvas_n"
style="dir_item"
tooltip="@.drag_angle_tooltip"
tooltip_dir="bottom" />
<item icon="canvas_ne"
style="dir_item"
tooltip="@.drag_angle_tooltip"
tooltip_dir="bottom" />
<item icon="canvas_w"
style="dir_item"
tooltip="@.drag_angle_tooltip"
tooltip_dir="right" />
<item />
<item icon="canvas_e"
style="dir_item"
tooltip="@.drag_angle_tooltip"
tooltip_dir="left" />
<item icon="canvas_sw"
style="dir_item"
tooltip="@.drag_angle_tooltip"
tooltip_dir="top" />
<item icon="canvas_s"
style="dir_item"
tooltip="@.drag_angle_tooltip"
tooltip_dir="top" />
<item icon="canvas_se"
style="dir_item"
tooltip="@.drag_angle_tooltip"
tooltip_dir="top" />
</buttonset>
<vbox>
<label text="@.drag_distance" />
</vbox>
<vbox>
<slider min="1" max="100" id="drag_distance" cell_align="horizontal" width="128"
tooltip="@.drag_distance_tooltip"
tooltip_dir="bottom" />
</vbox>
</hbox>
</vbox>
</vbox>
</splitter>
<hbox>
<boxfiller />
<hbox homogeneous="true">
<button text="@keyboard_shortcuts.ok" closewindow="true" id="ok" magnet="true" minwidth="60" />
<button text="@keyboard_shortcuts.cancel" closewindow="true" />
</hbox>
</hbox>
</vbox>
</window>
</gui>
<!-- Aseprite -->
<!-- Copyright (C) 2018-2024 Igara Studio S.A. -->
<!-- Copyright (C) 2001-2016 David Capello -->
<gui>
<window id="keyboard_shortcuts" text="@keyboard_shortcuts.title" help="keyboard-shortcuts">
<vbox>
<splitter horizontal="true" expansive="true" noborders="true" childspacing="2"
by="pixel" position="80" id="section_splitter">
<vbox expansive="true">
<search id="search" magnet="true" />
<view expansive="true">
<listbox id="section" expansive="true">
<listitem text="@.section_menus" />
<listitem text="@.section_commands" />
<listitem text="@.section_tools" />
<listitem text="@.section_action_modifiers" />
<listitem text="@.section_mouse_wheel" />
<listitem text="@.section_drag_value" />
</listbox>
</view>
<separator horizontal="true" />
<button text="@keyboard_shortcuts.import" id="import_button" />
<button text="@keyboard_shortcuts.export" id="export_button" />
<button text="@keyboard_shortcuts.reset" id="reset_button" />
</vbox>
<vbox id="lists_placeholder" expansive="true">
<view id="search_view" expansive="true">
<listbox id="search_list" />
</view>
<view id="menus_view" expansive="true">
<listbox id="menus" />
</view>
<view id="commands_view" expansive="true">
<listbox id="commands" />
</view>
<view id="tools_view" expansive="true">
<listbox id="tools" />
</view>
<view id="actions_view" expansive="true">
<listbox id="actions" />
</view>
<vbox id="wheel_section" expansive="true">
<hbox>
<buttonset columns="2" id="wheel_behavior">
<item text="@.default_wheel_behavior" />
<item text="@.custom_wheel_behavior" />
</buttonset>
</hbox>
<check text="@options.wheel_zoom" id="wheel_zoom"
pref="editor.zoom_with_wheel" />
<check text="@options.slide_zoom" id="slide_zoom"
pref="editor.zoom_with_slide" />
<check text="@.invert_brush_size_wheel" id="invert_brush_size_scroll"
pref="editor.invert_brush_size_wheel" />
<view expansive="true">
<listbox id="wheel_actions" />
</view>
</vbox>
<vbox id="drag_section" expansive="true">
<view expansive="true">
<listbox id="drag_actions" />
</view>
<separator horizontal="true" />
<hbox>
<vbox>
<label text="@.drag_angle" />
</vbox>
<buttonset columns="3" id="drag_angle">
<item icon="canvas_nw"
style="dir_item"
tooltip="@.drag_angle_tooltip"
tooltip_dir="bottom" />
<item icon="canvas_n"
style="dir_item"
tooltip="@.drag_angle_tooltip"
tooltip_dir="bottom" />
<item icon="canvas_ne"
style="dir_item"
tooltip="@.drag_angle_tooltip"
tooltip_dir="bottom" />
<item icon="canvas_w"
style="dir_item"
tooltip="@.drag_angle_tooltip"
tooltip_dir="right" />
<item />
<item icon="canvas_e"
style="dir_item"
tooltip="@.drag_angle_tooltip"
tooltip_dir="left" />
<item icon="canvas_sw"
style="dir_item"
tooltip="@.drag_angle_tooltip"
tooltip_dir="top" />
<item icon="canvas_s"
style="dir_item"
tooltip="@.drag_angle_tooltip"
tooltip_dir="top" />
<item icon="canvas_se"
style="dir_item"
tooltip="@.drag_angle_tooltip"
tooltip_dir="top" />
</buttonset>
<vbox>
<label text="@.drag_distance" />
</vbox>
<vbox>
<slider min="1" max="100" id="drag_distance" cell_align="horizontal" width="128"
tooltip="@.drag_distance_tooltip"
tooltip_dir="bottom" />
</vbox>
</hbox>
</vbox>
</vbox>
</splitter>
<hbox>
<boxfiller />
<hbox homogeneous="true">
<button text="@keyboard_shortcuts.ok" closewindow="true" id="ok" magnet="true" minwidth="60" />
<button text="@keyboard_shortcuts.cancel" closewindow="true" />
</hbox>
</hbox>
</vbox>
</window>
</gui>

View File

@ -1,21 +1,21 @@
<!-- Aseprite -->
<!-- Copyright (C) 2020 by Igara Studio S.A. -->
<!-- Copyright (C) 2001-2016 by David Capello -->
<gui>
<window id="layer_properties" text="@.title">
<vbox>
<grid id="properties_grid" columns="3">
<label text="@.name" />
<entry text="" id="name" magnet="true" maxsize="256" minwidth="64" cell_align="horizontal" />
<button id="user_data" icon="icon_user_data" tooltip="@general.user_data" />
<label text="@.mode" />
<combobox id="mode" />
<button id="tileset" icon="tiles" tooltip="@.tileset_tooltip" />
<label text="@.opacity" />
<opacityslider id="opacity" width="128" cell_align="horizontal" cell_hspan="2" />
</grid>
</vbox>
</window>
</gui>
<!-- Aseprite -->
<!-- Copyright (C) 2020 by Igara Studio S.A. -->
<!-- Copyright (C) 2001-2016 by David Capello -->
<gui>
<window id="layer_properties" text="@.title">
<vbox>
<grid id="properties_grid" columns="3">
<label text="@.name" />
<entry text="" id="name" magnet="true" maxsize="256" minwidth="64" cell_align="horizontal" />
<button id="user_data" icon="icon_user_data" tooltip="@general.user_data" />
<label text="@.mode" />
<combobox id="mode" />
<button id="tileset" icon="tiles" tooltip="@.tileset_tooltip" />
<label text="@.opacity" />
<opacityslider id="opacity" width="128" cell_align="horizontal" cell_hspan="2" />
</grid>
</vbox>
</window>
</gui>

View File

@ -1,30 +1,30 @@
<!-- 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>
<!-- 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>

View File

@ -1,19 +1,19 @@
<!-- Aseprite -->
<!-- Copyright (C) 2001-2016 by David Capello -->
<gui>
<window id="new_folder_window" text="@new_folder.title">
<vbox>
<hbox>
<label text="@new_folder.folder_name" />
<entry text="@new_folder.default_new_folder_name" id="name" maxsize="256" magnet="true" expansive="true" minwidth="128" />
</hbox>
<hbox>
<boxfiller />
<hbox homogeneous="true">
<button text="@general.ok" closewindow="true" id="ok" magnet="true" minwidth="60" />
<button text="@general.cancel" closewindow="true" id="cancel" />
</hbox>
</hbox>
</vbox>
</window>
</gui>
<!-- Aseprite -->
<!-- Copyright (C) 2001-2016 by David Capello -->
<gui>
<window id="new_folder_window" text="@new_folder.title">
<vbox>
<hbox>
<label text="@new_folder.folder_name" />
<entry text="@new_folder.default_new_folder_name" id="name" maxsize="256" magnet="true" expansive="true" minwidth="128" />
</hbox>
<hbox>
<boxfiller />
<hbox homogeneous="true">
<button text="@general.ok" closewindow="true" id="ok" magnet="true" minwidth="60" />
<button text="@general.cancel" closewindow="true" id="cancel" />
</hbox>
</hbox>
</vbox>
</window>
</gui>

View File

@ -1,50 +1,50 @@
<!-- Aseprite -->
<!-- Copyright (c) 2020-2024 Igara Studio S.A. -->
<!-- Copyright (c) 2001-2018 David Capello -->
<gui>
<window id="new_sprite" text="@.title" help="new-sprite">
<box vertical="true">
<separator text="@.size" left="true" horizontal="true" />
<grid columns="2">
<label text="@.width" />
<expr id="width" magnet="true" cell_align="horizontal" suffix="px" />
<label text="@.height" />
<expr id="height" cell_align="horizontal" suffix="px" />
</grid>
<separator text="@.color_mode" left="true" horizontal="true" />
<buttonset columns="3" id="color_mode">
<item text="@.rgba" icon="icon_rgb" style="new_sprite_rgb" tooltip="@.rgba_tooltip" tooltip_dir="bottom" />
<item text="@.grayscale" icon="icon_grayscale" style="new_sprite_grayscale" tooltip="@.grayscale_tooltip" tooltip_dir="bottom" />
<item text="@.indexed" icon="icon_indexed" style="new_sprite_indexed" tooltip="@.indexed_tooltip" tooltip_dir="bottom" />
</buttonset>
<separator text="@.background" left="true" horizontal="true" />
<buttonset columns="3" id="bg_color">
<item text="@.transparent" icon="icon_transparent" style="bg_transparent" />
<item text="@.white" icon="icon_white" style="bg_white" />
<item text="@.black" icon="icon_black" style="bg_black" />
</buttonset>
<check id="advanced_check" text="@general.advanced_options" />
<vbox id="advanced">
<label text="@.pixel_ratio" />
<combobox id="pixel_ratio" cell_align="horizontal">
<listitem text="@.square_pixels" value="1:1" />
<listitem text="@.double_wide" value="2:1" />
<listitem text="@.double_high" value="1:2" />
</combobox>
</vbox>
<box horizontal="true">
<box horizontal="true" expansive="true" />
<box horizontal="true" homogeneous="true">
<button text="@general.ok" closewindow="true" id="ok_button" magnet="true" minwidth="60" />
<button text="@general.cancel" closewindow="true" />
</box>
</box>
</box>
</window>
</gui>
<!-- Aseprite -->
<!-- Copyright (c) 2020-2024 Igara Studio S.A. -->
<!-- Copyright (c) 2001-2018 David Capello -->
<gui>
<window id="new_sprite" text="@.title" help="new-sprite">
<box vertical="true">
<separator text="@.size" left="true" horizontal="true" />
<grid columns="2">
<label text="@.width" />
<expr id="width" magnet="true" cell_align="horizontal" suffix="px" />
<label text="@.height" />
<expr id="height" cell_align="horizontal" suffix="px" />
</grid>
<separator text="@.color_mode" left="true" horizontal="true" />
<buttonset columns="3" id="color_mode">
<item text="@.rgba" icon="icon_rgb" style="new_sprite_rgb" tooltip="@.rgba_tooltip" tooltip_dir="bottom" />
<item text="@.grayscale" icon="icon_grayscale" style="new_sprite_grayscale" tooltip="@.grayscale_tooltip" tooltip_dir="bottom" />
<item text="@.indexed" icon="icon_indexed" style="new_sprite_indexed" tooltip="@.indexed_tooltip" tooltip_dir="bottom" />
</buttonset>
<separator text="@.background" left="true" horizontal="true" />
<buttonset columns="3" id="bg_color">
<item text="@.transparent" icon="icon_transparent" style="bg_transparent" />
<item text="@.white" icon="icon_white" style="bg_white" />
<item text="@.black" icon="icon_black" style="bg_black" />
</buttonset>
<check id="advanced_check" text="@general.advanced_options" />
<vbox id="advanced">
<label text="@.pixel_ratio" />
<combobox id="pixel_ratio" cell_align="horizontal">
<listitem text="@.square_pixels" value="1:1" />
<listitem text="@.double_wide" value="2:1" />
<listitem text="@.double_high" value="1:2" />
</combobox>
</vbox>
<box horizontal="true">
<box horizontal="true" expansive="true" />
<box horizontal="true" homogeneous="true">
<button text="@general.ok" closewindow="true" id="ok_button" magnet="true" minwidth="60" />
<button text="@general.cancel" closewindow="true" />
</box>
</box>
</box>
</window>
</gui>

File diff suppressed because it is too large Load Diff

View File

@ -10,16 +10,16 @@
</grid>
<hbox>
<vbox>
<hbox>
<buttonset id="outline_type" columns="2">
<hbox>
<buttonset id="outline_type" columns="2">
<item icon="outline_circle" tooltip="@.circle" tooltip_dir="right" />
<item icon="outline_square" tooltip="@.square" tooltip_dir="left" />
<item icon="outline_horizontal" tooltip="@.horizontal" tooltip_dir="right" />
<item icon="outline_vertical" tooltip="@.vertical" tooltip_dir="left" />
</buttonset>
</hbox>
<hbox>
<buttonset id="outline_matrix" columns="3">
</buttonset>
</hbox>
<hbox>
<buttonset id="outline_matrix" columns="3">
<item icon="outline_empty_pixel" style="outline_cell" />
<item icon="outline_empty_pixel" style="outline_cell" />
<item icon="outline_empty_pixel" style="outline_cell" />
@ -29,14 +29,14 @@
<item icon="outline_empty_pixel" style="outline_cell" />
<item icon="outline_empty_pixel" style="outline_cell" />
<item icon="outline_empty_pixel" style="outline_cell" />
</buttonset>
</hbox>
</buttonset>
</hbox>
</vbox>
<vbox>
<buttonset id="place" columns="1">
<item text="@.outside" />
<item text="@.inside" />
</buttonset>
<buttonset id="place" columns="1">
<item text="@.outside" />
<item text="@.inside" />
</buttonset>
</vbox>
</hbox>
</vbox>

View File

@ -1,29 +1,29 @@
<!-- Aseprite -->
<!-- Copyright (c) 2020 Igara Studio S.A. -->
<!-- Copyright (c) 2015-2018 David Capello -->
<gui>
<window id="palette_from_sprite" text="@.title">
<grid columns="2">
<radio id="new_palette" text="@.new_palette" group="1" />
<expr expansive="true" id="ncolors" magnet="true" />
<radio id="current_palette" text="@.replace_palette" group="1" cell_hspan="2" />
<radio id="current_range" text="@.replace_range" group="1" cell_hspan="2" />
<separator horizontal="true" cell_hspan="2" />
<check id="alpha_channel" text="@.alpha_channel" cell_hspan="2" />
<check id="advanced_check" text="@general.advanced_options" cell_hspan="2" />
<hbox id="advanced" cell_hspan="2">
<label text="@rgbmap_algorithm_selector.label" />
<hbox id="rgbmap_algorithm_placeholder" />
</hbox>
<separator horizontal="true" cell_hspan="2" />
<box horizontal="true" homogeneous="true" cell_hspan="2" cell_align="right">
<button text="@general.ok" closewindow="true" id="ok" magnet="true" minwidth="60" />
<button text="@general.cancel" closewindow="true" />
</box>
</grid>
</window>
</gui>
<!-- Aseprite -->
<!-- Copyright (c) 2020 Igara Studio S.A. -->
<!-- Copyright (c) 2015-2018 David Capello -->
<gui>
<window id="palette_from_sprite" text="@.title">
<grid columns="2">
<radio id="new_palette" text="@.new_palette" group="1" />
<expr expansive="true" id="ncolors" magnet="true" />
<radio id="current_palette" text="@.replace_palette" group="1" cell_hspan="2" />
<radio id="current_range" text="@.replace_range" group="1" cell_hspan="2" />
<separator horizontal="true" cell_hspan="2" />
<check id="alpha_channel" text="@.alpha_channel" cell_hspan="2" />
<check id="advanced_check" text="@general.advanced_options" cell_hspan="2" />
<hbox id="advanced" cell_hspan="2">
<label text="@rgbmap_algorithm_selector.label" />
<hbox id="rgbmap_algorithm_placeholder" />
</hbox>
<separator horizontal="true" cell_hspan="2" />
<box horizontal="true" homogeneous="true" cell_hspan="2" cell_align="right">
<button text="@general.ok" closewindow="true" id="ok" magnet="true" minwidth="60" />
<button text="@general.cancel" closewindow="true" />
</box>
</grid>
</window>
</gui>

View File

@ -1,17 +1,17 @@
<!-- Aseprite -->
<!-- Copyright (C) 2024 by Igara Studio S.A. -->
<!-- Copyright (C) 2014-2017 by David Capello -->
<gui>
<vbox id="palette_popup">
<hbox>
<search id="search" magnet="true" expansive="true" />
<button text="" id="refresh" style="refresh_button" />
</hbox>
<view id="view" expansive="true" />
<hbox>
<button id="load_pal" text="@.load" minwidth="80" magnet="true" />
<hbox expansive="true" />
<button id="open_folder" text="@.open_folder" minwidth="60" />
</hbox>
</vbox>
</gui>
<!-- Aseprite -->
<!-- Copyright (C) 2024 by Igara Studio S.A. -->
<!-- Copyright (C) 2014-2017 by David Capello -->
<gui>
<vbox id="palette_popup">
<hbox>
<search id="search" magnet="true" expansive="true" />
<button text="" id="refresh" style="refresh_button" />
</hbox>
<view id="view" expansive="true" />
<hbox>
<button id="load_pal" text="@.load" minwidth="80" magnet="true" />
<hbox expansive="true" />
<button id="open_folder" text="@.open_folder" minwidth="60" />
</hbox>
</vbox>
</gui>

View File

@ -1,18 +1,18 @@
<!-- Aseprite -->
<!-- Copyright (C) 2015-2018 by David Capello -->
<gui>
<window id="palette_size" text="@.title">
<grid columns="3">
<label text="@.number_of_colors" />
<expr expansive="true" id="colors" magnet="true" />
<box cell_align="horizontal" />
<separator horizontal="true" cell_hspan="3" />
<box horizontal="true" homogeneous="true" cell_hspan="3" cell_align="right">
<button text="@general.ok" closewindow="true" id="ok" magnet="true" minwidth="60" />
<button text="@general.cancel" closewindow="true" />
</box>
</grid>
</window>
</gui>
<!-- Aseprite -->
<!-- Copyright (C) 2015-2018 by David Capello -->
<gui>
<window id="palette_size" text="@.title">
<grid columns="3">
<label text="@.number_of_colors" />
<expr expansive="true" id="colors" magnet="true" />
<box cell_align="horizontal" />
<separator horizontal="true" cell_hspan="3" />
<box horizontal="true" homogeneous="true" cell_hspan="3" cell_align="right">
<button text="@general.ok" closewindow="true" id="ok" magnet="true" minwidth="60" />
<button text="@general.cancel" closewindow="true" />
</box>
</grid>
</window>
</gui>

View File

@ -1,17 +1,17 @@
<!-- Aseprite -->
<!-- Copyright (C) 2019 by Igara Studio S.A. -->
<!-- Copyright (C) 2001-2016 by David Capello -->
<gui>
<vbox expansive="true" id="controls">
<hbox expansive="true">
<grid columns="2" id="controls">
<label text="@replace_color.from" />
<colorpicker id="from" cell_align="horizontal" />
<label text="@replace_color.to" />
<colorpicker id="to" cell_align="horizontal" />
</grid>
</hbox>
<label text="@replace_color.tolerance" />
<slider min="0" max="255" id="tolerance" />
</vbox>
</gui>
<!-- Aseprite -->
<!-- Copyright (C) 2019 by Igara Studio S.A. -->
<!-- Copyright (C) 2001-2016 by David Capello -->
<gui>
<vbox expansive="true" id="controls">
<hbox expansive="true">
<grid columns="2" id="controls">
<label text="@replace_color.from" />
<colorpicker id="from" cell_align="horizontal" />
<label text="@replace_color.to" />
<colorpicker id="to" cell_align="horizontal" />
</grid>
</hbox>
<label text="@replace_color.tolerance" />
<slider min="0" max="255" id="tolerance" />
</vbox>
</gui>

View File

@ -1,38 +1,38 @@
<!-- Aseprite -->
<!-- Copyright (C) 2001-2016 by David Capello -->
<gui>
<window id="select_accelerator" text="@.title">
<vbox expansive="true">
<grid columns="3">
<label text="@.key" />
<hbox id="key_placeholder" cell_align="horizontal" />
<button text="@.clear" id="clear_button" minwidth="60" />
<label text="@.modifiers" />
<hbox cell_hspan="2" cell_align="horizontal">
<check text="@.ctrl" id="ctrl" />
<check text="@.cmd" id="cmd" />
<check text="@.alt" id="alt" />
<check text="@.shift" id="shift" />
<check text="@.space" id="space" />
<check text="@.win" id="win" />
</hbox>
<label text="@.assigned_to" />
<label text="" id="assigned_to" cell_hspan="2" />
</grid>
<boxfiller />
<separator horizontal="true" />
<box horizontal="true">
<boxfiller />
<box horizontal="true" homogeneous="true">
<button text="@.ok" id="ok_button" magnet="true" minwidth="60" />
<button text="@.cancel" id="cancel_button" />
</box>
</box>
</vbox>
</window>
</gui>
<!-- Aseprite -->
<!-- Copyright (C) 2001-2016 by David Capello -->
<gui>
<window id="select_accelerator" text="@.title">
<vbox expansive="true">
<grid columns="3">
<label text="@.key" />
<hbox id="key_placeholder" cell_align="horizontal" />
<button text="@.clear" id="clear_button" minwidth="60" />
<label text="@.modifiers" />
<hbox cell_hspan="2" cell_align="horizontal">
<check text="@.ctrl" id="ctrl" />
<check text="@.cmd" id="cmd" />
<check text="@.alt" id="alt" />
<check text="@.shift" id="shift" />
<check text="@.space" id="space" />
<check text="@.win" id="win" />
</hbox>
<label text="@.assigned_to" />
<label text="" id="assigned_to" cell_hspan="2" />
</grid>
<boxfiller />
<separator horizontal="true" />
<box horizontal="true">
<boxfiller />
<box horizontal="true" homogeneous="true">
<button text="@.ok" id="ok_button" magnet="true" minwidth="60" />
<button text="@.cancel" id="cancel_button" />
</box>
</box>
</vbox>
</window>
</gui>

View File

@ -1,27 +1,27 @@
<!-- Aseprite -->
<!-- Copyright (C) 2014-2016 by David Capello -->
<gui>
<window id="send_crash" text="@.title">
<vbox>
<vbox id="official">
<label text="@.send_file" />
<link id="filename" text="" url="" />
<label text="@.to_email" />
<entry readonly="true" text="support@aseprite.org" maxsize="256" />
<label text="@.explaining" />
</vbox>
<vbox id="dev">
<label text="@.using_dev_ver" />
<label text="@.open_dmp_file" />
<link id="dev_filename" text="" url="" />
</vbox>
<separator horizontal="true" />
<button text="@.do_it_later" closewindow="true" />
<button text="@.delete_file" closewindow="true" id="delete_file" />
</vbox>
</window>
</gui>
<!-- Aseprite -->
<!-- Copyright (C) 2014-2016 by David Capello -->
<gui>
<window id="send_crash" text="@.title">
<vbox>
<vbox id="official">
<label text="@.send_file" />
<link id="filename" text="" url="" />
<label text="@.to_email" />
<entry readonly="true" text="support@aseprite.org" maxsize="256" />
<label text="@.explaining" />
</vbox>
<vbox id="dev">
<label text="@.using_dev_ver" />
<label text="@.open_dmp_file" />
<link id="dev_filename" text="" url="" />
</vbox>
<separator horizontal="true" />
<button text="@.do_it_later" closewindow="true" />
<button text="@.delete_file" closewindow="true" id="delete_file" />
</vbox>
</window>
</gui>

View File

@ -1,64 +1,64 @@
<!-- Aseprite -->
<!-- Copyright (C) 2018-2024 Igara Studio S.A. -->
<!-- Copyright (C) 2001-2016 David Capello -->
<gui>
<window id="sprite_properties" text="@.title" help="sprite-properties">
<vbox>
<grid id="properties_grid" columns="3">
<label text="@.filename" />
<entry text="" id="name" maxsize="256" minwidth="64" readonly="true" cell_align="horizontal" />
<button id="user_data" icon="icon_user_data" maxsize="32" tooltip="@general.user_data" />
<label text="@.type" />
<label text="" id="type" cell_hspan="2" />
<label text="@.size" />
<label text="" id="size" cell_hspan="2" />
<label text="@.frames" />
<label text="" id="frames" cell_hspan="2" />
</grid>
<grid columns="2">
<separator text="@.advanced" horizontal="true" cell_hspan="2" />
<label text="@.transparent_color" />
<hbox>
<hbox id="transparent_color_placeholder" />
</hbox>
<label text="@.pixel_ratio" />
<combobox id="pixel_ratio" cell_align="horizontal">
<listitem text="@.square_pixels" value="1:1" />
<listitem text="@.double_wide" value="2:1" />
<listitem text="@.double_high" value="1:2" />
</combobox>
<label text="@.color_profile" />
<hbox>
<combobox id="color_profile" cell_align="horizontal" expansive="true" />
<hbox homogeneous="true">
<button id="assign_color_profile" text="@.assign" />
<button id="convert_color_profile" text="@.convert" />
</hbox>
</hbox>
</grid>
<vbox expansive="true" id="tilesets_placeholder">
<separator text="@.tilesets" horizontal="true" />
<view id="tilesets_view" expansive="true">
<listbox id="tilesets"></listbox>
</view>
</vbox>
<separator horizontal="true" />
<hbox>
<boxfiller />
<hbox homogeneous="true">
<button text="@general.ok" closewindow="true" id="ok" magnet="true" minwidth="60" />
<button text="@general.cancel" closewindow="true" id="cancel" />
</hbox>
</hbox>
</vbox>
</window>
</gui>
<!-- Aseprite -->
<!-- Copyright (C) 2018-2024 Igara Studio S.A. -->
<!-- Copyright (C) 2001-2016 David Capello -->
<gui>
<window id="sprite_properties" text="@.title" help="sprite-properties">
<vbox>
<grid id="properties_grid" columns="3">
<label text="@.filename" />
<entry text="" id="name" maxsize="256" minwidth="64" readonly="true" cell_align="horizontal" />
<button id="user_data" icon="icon_user_data" maxsize="32" tooltip="@general.user_data" />
<label text="@.type" />
<label text="" id="type" cell_hspan="2" />
<label text="@.size" />
<label text="" id="size" cell_hspan="2" />
<label text="@.frames" />
<label text="" id="frames" cell_hspan="2" />
</grid>
<grid columns="2">
<separator text="@.advanced" horizontal="true" cell_hspan="2" />
<label text="@.transparent_color" />
<hbox>
<hbox id="transparent_color_placeholder" />
</hbox>
<label text="@.pixel_ratio" />
<combobox id="pixel_ratio" cell_align="horizontal">
<listitem text="@.square_pixels" value="1:1" />
<listitem text="@.double_wide" value="2:1" />
<listitem text="@.double_high" value="1:2" />
</combobox>
<label text="@.color_profile" />
<hbox>
<combobox id="color_profile" cell_align="horizontal" expansive="true" />
<hbox homogeneous="true">
<button id="assign_color_profile" text="@.assign" />
<button id="convert_color_profile" text="@.convert" />
</hbox>
</hbox>
</grid>
<vbox expansive="true" id="tilesets_placeholder">
<separator text="@.tilesets" horizontal="true" />
<view id="tilesets_view" expansive="true">
<listbox id="tilesets"></listbox>
</view>
</vbox>
<separator horizontal="true" />
<hbox>
<boxfiller />
<hbox homogeneous="true">
<button text="@general.ok" closewindow="true" id="ok" magnet="true" minwidth="60" />
<button text="@general.cancel" closewindow="true" id="cancel" />
</hbox>
</hbox>
</vbox>
</window>
</gui>

View File

@ -28,9 +28,9 @@
</box>
<box vertical="true" homogeneous="true" expansive="true">
<expr expansive="true" text="100" suffix="%" id="width_perc" magnet="true" tooltip="@.width_perc_tooltip"
decimals="4" />
decimals="4" />
<expr expansive="true" text="100" suffix="%" id="height_perc" tooltip="@.height_perc_tooltip"
decimals="4" />
decimals="4" />
</box>
<box horizontal="true" width="64" />
</box>

View File

@ -1,59 +1,59 @@
<!-- Aseprite -->
<!-- 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>
</vbox>
<vbox>
<separator text="@.frame_header" left="true" horizontal="true" />
<hbox>
<label text="@.first_frame" />
<expr id="first_frame" />
</hbox>
<hbox>
<check id="thumb_enabled" text="@.thumbnails" horizontal="true" />
<separator id="thumb_h_separator" horizontal="true" expansive="true" />
</hbox>
<grid columns="2" id="thumb_box">
<label text="@.thumbnail_size" />
<slider min="1" max="10" id="zoom" cell_align="horizontal" width="128" />
<check id="thumb_overlay_enabled" text="@.overlay_size"/>
<slider min="2" max="10" id="thumb_overlay_size" cell_align="horizontal" width="128" />
</grid>
</vbox>
</hbox>
<separator text="@.onion_skin" left="true" horizontal="true" />
<grid columns="2">
<hbox cell_hspan="2">
<radio group="1" text="@.merge_frames" id="merge" />
<radio group="1" text="@.red_blue_tint" id="tint" />
<button id="reset_onionskin" text="@.reset" minwidth="60" />
</hbox>
<label text="@.opacity" />
<opacityslider id="opacity" cell_align="horizontal" width="128" />
<label text="@.opacity_step" />
<opacityslider id="opacity_step" cell_align="horizontal" width="128" />
<check id="loop_tag" text="@.loop_tags" cell_hspan="2" />
<check id="current_layer" text="@.current_layer" cell_hspan="2" />
<hbox cell_hspan="2">
<radio group="2" text="@.behind_sprite" id="behind" tooltip="@.behind_sprite_toolip" tooltip_dir="top" />
<radio group="2" text="@.in_front" id="infront" tooltip="@.in_front_toolip" />
</hbox>
</grid>
</vbox>
</gui>
<!-- Aseprite -->
<!-- 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>
</vbox>
<vbox>
<separator text="@.frame_header" left="true" horizontal="true" />
<hbox>
<label text="@.first_frame" />
<expr id="first_frame" />
</hbox>
<hbox>
<check id="thumb_enabled" text="@.thumbnails" horizontal="true" />
<separator id="thumb_h_separator" horizontal="true" expansive="true" />
</hbox>
<grid columns="2" id="thumb_box">
<label text="@.thumbnail_size" />
<slider min="1" max="10" id="zoom" cell_align="horizontal" width="128" />
<check id="thumb_overlay_enabled" text="@.overlay_size"/>
<slider min="2" max="10" id="thumb_overlay_size" cell_align="horizontal" width="128" />
</grid>
</vbox>
</hbox>
<separator text="@.onion_skin" left="true" horizontal="true" />
<grid columns="2">
<hbox cell_hspan="2">
<radio group="1" text="@.merge_frames" id="merge" />
<radio group="1" text="@.red_blue_tint" id="tint" />
<button id="reset_onionskin" text="@.reset" minwidth="60" />
</hbox>
<label text="@.opacity" />
<opacityslider id="opacity" cell_align="horizontal" width="128" />
<label text="@.opacity_step" />
<opacityslider id="opacity_step" cell_align="horizontal" width="128" />
<check id="loop_tag" text="@.loop_tags" cell_hspan="2" />
<check id="current_layer" text="@.current_layer" cell_hspan="2" />
<hbox cell_hspan="2">
<radio group="2" text="@.behind_sprite" id="behind" tooltip="@.behind_sprite_toolip" tooltip_dir="top" />
<radio group="2" text="@.in_front" id="infront" tooltip="@.in_front_toolip" />
</hbox>
</grid>
</vbox>
</gui>

2
laf

@ -1 +1 @@
Subproject commit 10d96af44f5d64af3fb277f48fdc0dd8cc950ac6
Subproject commit c84b89b4826b64b05a176eb15725ba526495c6a1

View File

@ -1,98 +1,98 @@
# Aseprite Source Code
If you are here is because you want to learn about Aseprite source
code. We'll try to write in these `README.md` files a summary of each
module/library.
# Modules & Libraries
Aseprite is separated in the following layers/modules:
## Level 0: Completely independent modules
These libraries are easy to be used and embedded in other software
because they don't depend on any other component.
* [clip](https://github.com/aseprite/clip): Clipboard library.
* [fixmath](fixmath/): Fixed point operations (original code from Allegro code by Shawn Hargreaves).
* [flic](https://github.com/aseprite/flic): Library to load/save FLI/FLC files.
* laf/[base](https://github.com/aseprite/laf/tree/main/base): Core/basic stuff, multithreading, utf8, sha1, file system, memory, etc.
* laf/[gfx](https://github.com/aseprite/laf/tree/main/gfx): Abstract graphics structures like point, size, rectangle, region, color, etc.
* [observable](https://github.com/aseprite/observable): Signal/slot functions.
* [scripting](scripting/): JavaScript engine.
* [steam](steam/): Steam API wrapper to avoid static linking to the .lib file.
* [undo](https://github.com/aseprite/undo): Generic library to manage a history of undoable commands.
## Level 1
* [cfg](cfg/) (base): Library to load/save .ini files.
* [gen](gen/) (base): Helper utility to generate C++ files from different XMLs.
* [net](net/) (base): Networking library to send HTTP requests.
* laf/[os](https://github.com/aseprite/laf/tree/main/os) (base, gfx, wacom): OS input/output.
## Level 2
* [doc](doc/) (base, fixmath, gfx): Document model library.
* [ui](ui/) (base, gfx, os): Portable UI library (buttons, windows, text fields, etc.)
* [updater](updater/) (base, cfg, net): Component to check for updates.
## Level 3
* [dio](dio/) (base, doc, fixmath, flic): Load/save sprites/documents.
* [filters](filters/) (base, doc, gfx): Effects for images.
* [render](render/) (base, doc, gfx): Library to render documents.
## Level 4
* [app](app/) (base, doc, dio, filters, fixmath, flic, gfx, pen, render, scripting, os, ui, undo, updater)
* [desktop](desktop/) (base, doc, dio, render): Integration with the desktop (Windows Explorer, Finder, GNOME, KDE, etc.)
## Level 5
* [main](main/) (app, base, os, ui)
# Debugging Tricks
When Aseprite is compiled with `ENABLE_DEVMODE`, you have the
following extra commands/features available:
* `F5`: On Windows shows the amount of used memory.
* `F1`: Switch between new/old/shader renderers.
* `Ctrl+F1`: Switch/test Screen/UI Scaling values.
* `Ctrl+Alt+Shift+Q`: crashes the application in case that you want to
test the anticrash feature or your need a memory dump file.
* `Ctrl+Alt+Shift+R`: recover the active document from the data
recovery store.
* `aseprite.ini`: `[perf] show_render_time=true` shows a performance
clock in the Editor.
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
# Detect Platform
You can check the platform using some `laf` macros:
#if LAF_WINDOWS
// ...
#elif LAF_MACOS
// ...
#elif LAF_LINUX
// ...
#endif
Or using platform-specific macros:
#ifdef _WIN32
#ifdef _WIN64
// Windows x64
#else
// Windows x86
#endif
#elif defined(__APPLE__)
// macOS
#else
// Linux
#endif
# Aseprite Source Code
If you are here is because you want to learn about Aseprite source
code. We'll try to write in these `README.md` files a summary of each
module/library.
# Modules & Libraries
Aseprite is separated in the following layers/modules:
## Level 0: Completely independent modules
These libraries are easy to be used and embedded in other software
because they don't depend on any other component.
* [clip](https://github.com/aseprite/clip): Clipboard library.
* [fixmath](fixmath/): Fixed point operations (original code from Allegro code by Shawn Hargreaves).
* [flic](https://github.com/aseprite/flic): Library to load/save FLI/FLC files.
* laf/[base](https://github.com/aseprite/laf/tree/main/base): Core/basic stuff, multithreading, utf8, sha1, file system, memory, etc.
* laf/[gfx](https://github.com/aseprite/laf/tree/main/gfx): Abstract graphics structures like point, size, rectangle, region, color, etc.
* [observable](https://github.com/aseprite/observable): Signal/slot functions.
* [scripting](scripting/): JavaScript engine.
* [steam](steam/): Steam API wrapper to avoid static linking to the .lib file.
* [undo](https://github.com/aseprite/undo): Generic library to manage a history of undoable commands.
## Level 1
* [cfg](cfg/) (base): Library to load/save .ini files.
* [gen](gen/) (base): Helper utility to generate C++ files from different XMLs.
* [net](net/) (base): Networking library to send HTTP requests.
* laf/[os](https://github.com/aseprite/laf/tree/main/os) (base, gfx, wacom): OS input/output.
## Level 2
* [doc](doc/) (base, fixmath, gfx): Document model library.
* [ui](ui/) (base, gfx, os): Portable UI library (buttons, windows, text fields, etc.)
* [updater](updater/) (base, cfg, net): Component to check for updates.
## Level 3
* [dio](dio/) (base, doc, fixmath, flic): Load/save sprites/documents.
* [filters](filters/) (base, doc, gfx): Effects for images.
* [render](render/) (base, doc, gfx): Library to render documents.
## Level 4
* [app](app/) (base, doc, dio, filters, fixmath, flic, gfx, pen, render, scripting, os, ui, undo, updater)
* [desktop](desktop/) (base, doc, dio, render): Integration with the desktop (Windows Explorer, Finder, GNOME, KDE, etc.)
## Level 5
* [main](main/) (app, base, os, ui)
# Debugging Tricks
When Aseprite is compiled with `ENABLE_DEVMODE`, you have the
following extra commands/features available:
* `F5`: On Windows shows the amount of used memory.
* `F1`: Switch between new/old/shader renderers.
* `Ctrl+F1`: Switch/test Screen/UI Scaling values.
* `Ctrl+Alt+Shift+Q`: crashes the application in case that you want to
test the anticrash feature or your need a memory dump file.
* `Ctrl+Alt+Shift+R`: recover the active document from the data
recovery store.
* `aseprite.ini`: `[perf] show_render_time=true` shows a performance
clock in the Editor.
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
# Detect Platform
You can check the platform using some `laf` macros:
#if LAF_WINDOWS
// ...
#elif LAF_MACOS
// ...
#elif LAF_LINUX
// ...
#endif
Or using platform-specific macros:
#ifdef _WIN32
#ifdef _WIN64
// Windows x64
#else
// Windows x86
#endif
#elif defined(__APPLE__)
// macOS
#else
// Linux
#endif

View File

@ -5,7 +5,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/active_site_handler.h"
@ -29,7 +29,7 @@ void ActiveSiteHandler::addDoc(Doc* doc)
{
Data data;
data.layer = doc::NullId;
if (doc->sprite()) { // The sprite can be nullptr in some tests
if (doc->sprite()) { // The sprite can be nullptr in some tests
if (doc::Layer* layer = doc->sprite()->root()->firstLayer())
data.layer = layer->id();
}
@ -74,7 +74,7 @@ void ActiveSiteHandler::getActiveSiteForDoc(Doc* doc, Site* site)
void ActiveSiteHandler::setActiveLayerInDoc(Doc* doc, doc::Layer* layer)
{
Data& data = getData(doc);
data.layer = (layer ? layer->id(): 0);
data.layer = (layer ? layer->id() : 0);
}
void ActiveSiteHandler::setActiveFrameInDoc(Doc* doc, doc::frame_t frame)
@ -133,9 +133,8 @@ void ActiveSiteHandler::onAddFrame(DocEvent& ev)
void ActiveSiteHandler::onBeforeRemoveLayer(DocEvent& ev)
{
Data& data = getData(ev.document());
doc::Layer* selectedLayer = (data.layer != doc::NullId ?
doc::get<doc::Layer>(data.layer):
nullptr);
doc::Layer* selectedLayer = (data.layer != doc::NullId ? doc::get<doc::Layer>(data.layer) :
nullptr);
if (!selectedLayer)
return;
@ -145,8 +144,7 @@ void ActiveSiteHandler::onBeforeRemoveLayer(DocEvent& ev)
// Select other layer as active
doc::Layer* layerToSelect = candidate_if_layer_is_deleted(selectedLayer, ev.layer());
if (selectedLayer != layerToSelect) {
data.layer = (layerToSelect ? layerToSelect->id():
doc::NullId);
data.layer = (layerToSelect ? layerToSelect->id() : doc::NullId);
}
}

View File

@ -17,53 +17,53 @@
#include <map>
namespace doc {
class Layer;
class Layer;
}
namespace app {
class Doc;
class Site;
class Doc;
class Site;
// Pseudo-DocViews to handle active layer/frame in a non-UI context
// per Doc.
//
// TODO we could move code to handle active frame/layer from
// Timeline to this class.
class ActiveSiteHandler : public DocObserver {
public:
ActiveSiteHandler();
virtual ~ActiveSiteHandler();
// Pseudo-DocViews to handle active layer/frame in a non-UI context
// per Doc.
//
// TODO we could move code to handle active frame/layer from
// Timeline to this class.
class ActiveSiteHandler : public DocObserver {
public:
ActiveSiteHandler();
virtual ~ActiveSiteHandler();
void addDoc(Doc* doc);
void removeDoc(Doc* doc);
void getActiveSiteForDoc(Doc* doc, Site* site);
void setActiveLayerInDoc(Doc* doc, doc::Layer* layer);
void setActiveFrameInDoc(Doc* doc, doc::frame_t frame);
void setRangeInDoc(Doc* doc, const DocRange& range);
void setSelectedColorsInDoc(Doc* doc, const doc::PalettePicks& picks);
void setSelectedTilesInDoc(Doc* doc, const doc::PalettePicks& picks);
void addDoc(Doc* doc);
void removeDoc(Doc* doc);
void getActiveSiteForDoc(Doc* doc, Site* site);
void setActiveLayerInDoc(Doc* doc, doc::Layer* layer);
void setActiveFrameInDoc(Doc* doc, doc::frame_t frame);
void setRangeInDoc(Doc* doc, const DocRange& range);
void setSelectedColorsInDoc(Doc* doc, const doc::PalettePicks& picks);
void setSelectedTilesInDoc(Doc* doc, const doc::PalettePicks& picks);
private:
// DocObserver impl
void onAddLayer(DocEvent& ev) override;
void onAddFrame(DocEvent& ev) override;
void onBeforeRemoveLayer(DocEvent& ev) override;
void onRemoveFrame(DocEvent& ev) override;
private:
// DocObserver impl
void onAddLayer(DocEvent& ev) override;
void onAddFrame(DocEvent& ev) override;
void onBeforeRemoveLayer(DocEvent& ev) override;
void onRemoveFrame(DocEvent& ev) override;
// Active data for a document
struct Data {
doc::ObjectId layer;
doc::frame_t frame;
DocRange range;
doc::PalettePicks selectedColors;
doc::PalettePicks selectedTiles;
};
Data& getData(Doc* doc);
std::map<Doc*, Data> m_data;
// Active data for a document
struct Data {
doc::ObjectId layer;
doc::frame_t frame;
DocRange range;
doc::PalettePicks selectedColors;
doc::PalettePicks selectedTiles;
};
Data& getData(Doc* doc);
std::map<Doc*, Data> m_data;
};
} // namespace app
#endif

View File

@ -6,7 +6,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/app.h"
@ -103,13 +103,10 @@ namespace {
class ConsoleEngineDelegate : public script::EngineDelegate {
public:
ConsoleEngineDelegate(Console& console) : m_console(console) { }
void onConsoleError(const char* text) override {
onConsolePrint(text);
}
void onConsolePrint(const char* text) override {
m_console.printf("%s\n", text);
}
ConsoleEngineDelegate(Console& console) : m_console(console) {}
void onConsoleError(const char* text) override { onConsolePrint(text); }
void onConsolePrint(const char* text) override { m_console.printf("%s\n", text); }
private:
Console& m_console;
};
@ -126,10 +123,7 @@ public:
class App::LoadLanguage {
public:
LoadLanguage(Preferences& pref,
Extensions& exts) {
Strings::createInstance(pref, exts);
}
LoadLanguage(Preferences& pref, Extensions& exts) { Strings::createInstance(pref, exts); }
};
class App::Modules {
@ -152,8 +146,7 @@ public:
std::unique_ptr<app::crash::DataRecovery> m_recovery;
#endif
Modules(const bool createLogInDesktop,
Preferences& pref)
Modules(const bool createLogInDesktop, Preferences& pref)
: m_loggerModule(createLogInDesktop)
, m_loadLanguage(pref, m_extensions)
, m_activeToolManager(&m_toolbox)
@ -164,14 +157,15 @@ public:
{
}
~Modules() {
~Modules()
{
#ifdef ENABLE_DATA_RECOVERY
ASSERT(m_recovery == nullptr ||
ui::get_app_state() == ui::AppState::kClosingWithException);
ASSERT(m_recovery == nullptr || ui::get_app_state() == ui::AppState::kClosingWithException);
#endif
}
app::crash::DataRecovery* recovery() {
app::crash::DataRecovery* recovery()
{
#ifdef ENABLE_DATA_RECOVERY
return m_recovery.get();
#else
@ -179,36 +173,39 @@ public:
#endif
}
void createDataRecovery(Context* ctx) {
void createDataRecovery(Context* ctx)
{
#ifdef ENABLE_DATA_RECOVERY
#ifdef ENABLE_TRIAL_MODE
DRM_INVALID{
#ifdef ENABLE_TRIAL_MODE
DRM_INVALID
{
return;
}
#endif
#endif
m_recovery = std::make_unique<app::crash::DataRecovery>(ctx);
m_recovery->SessionsListIsReady.connect(
[] {
ui::assert_ui_thread();
auto app = App::instance();
if (app && app->mainWindow()) {
// Notify that the list of sessions is ready.
app->mainWindow()->dataRecoverySessionsAreReady();
}
});
m_recovery->SessionsListIsReady.connect([] {
ui::assert_ui_thread();
auto app = App::instance();
if (app && app->mainWindow()) {
// Notify that the list of sessions is ready.
app->mainWindow()->dataRecoverySessionsAreReady();
}
});
#endif
}
void searchDataRecoverySessions() {
void searchDataRecoverySessions()
{
#ifdef ENABLE_DATA_RECOVERY
#ifdef ENABLE_TRIAL_MODE
DRM_INVALID{
#ifdef ENABLE_TRIAL_MODE
DRM_INVALID
{
return;
}
#endif
#endif
ASSERT(m_recovery);
if (m_recovery)
@ -216,19 +213,20 @@ public:
#endif
}
void deleteDataRecovery() {
void deleteDataRecovery()
{
#ifdef ENABLE_DATA_RECOVERY
#ifdef ENABLE_TRIAL_MODE
DRM_INVALID{
#ifdef ENABLE_TRIAL_MODE
DRM_INVALID
{
return;
}
#endif
#endif
m_recovery.reset();
#endif
}
};
App* App::m_instance = nullptr;
@ -273,8 +271,7 @@ int App::initialize(const AppOptions& options)
#if LAF_WINDOWS
if (options.disableWintab() ||
!pref.experimental.loadWintabDriver() ||
if (options.disableWintab() || !pref.experimental.loadWintabDriver() ||
pref.tablet.api() == "pointer") {
tabletOptions.api = os::TabletAPI::WindowsPointerInput;
}
@ -299,20 +296,15 @@ int App::initialize(const AppOptions& options)
system->setTabletOptions(tabletOptions);
system->setAppName(get_app_name());
system->setAppMode(m_isGui ? os::AppMode::GUI:
os::AppMode::CLI);
system->setAppMode(m_isGui ? os::AppMode::GUI : os::AppMode::CLI);
if (m_isGui)
m_uiSystem.reset(new ui::UISystem);
bool createLogInDesktop = false;
switch (options.verboseLevel()) {
case AppOptions::kNoVerbose:
base::set_log_level(ERROR);
break;
case AppOptions::kVerbose:
base::set_log_level(INFO);
break;
case AppOptions::kNoVerbose: base::set_log_level(ERROR); break;
case AppOptions::kVerbose: base::set_log_level(INFO); break;
case AppOptions::kHighlyVerbose:
base::set_log_level(VERBOSE);
createLogInDesktop = true;
@ -333,7 +325,7 @@ int App::initialize(const AppOptions& options)
// Load modules
m_modules = std::make_unique<Modules>(createLogInDesktop, pref);
m_legacy = std::make_unique<LegacyModules>(isGui() ? REQUIRE_INTERFACE: 0);
m_legacy = std::make_unique<LegacyModules>(isGui() ? REQUIRE_INTERFACE : 0);
m_brushes = std::make_unique<AppBrushes>();
// Data recovery is enabled only in GUI mode
@ -425,47 +417,48 @@ int App::initialize(const AppOptions& options)
namespace {
struct CloseMainWindow {
std::unique_ptr<MainWindow>& m_win;
CloseMainWindow(std::unique_ptr<MainWindow>& win) : m_win(win) { }
~CloseMainWindow() { m_win.reset(nullptr); }
};
struct CloseMainWindow {
std::unique_ptr<MainWindow>& m_win;
CloseMainWindow(std::unique_ptr<MainWindow>& win) : m_win(win) {}
~CloseMainWindow() { m_win.reset(nullptr); }
};
// Deletes all docs.
struct DeleteAllDocs {
Context* m_ctx;
DeleteAllDocs(Context* ctx) : m_ctx(ctx) { }
~DeleteAllDocs() {
std::vector<Doc*> docs;
// Deletes all docs.
struct DeleteAllDocs {
Context* m_ctx;
DeleteAllDocs(Context* ctx) : m_ctx(ctx) {}
~DeleteAllDocs()
{
std::vector<Doc*> docs;
// Add all documents that were closed in the past, these docs
// are not part of any context and they are just temporarily in
// memory just in case the user wants to recover them.
for (Doc* doc : static_cast<UIContext*>(m_ctx)->getAndRemoveAllClosedDocs())
docs.push_back(doc);
// Add all documents that were closed in the past, these docs
// are not part of any context and they are just temporarily in
// memory just in case the user wants to recover them.
for (Doc* doc : static_cast<UIContext*>(m_ctx)->getAndRemoveAllClosedDocs())
docs.push_back(doc);
// Add documents that are currently opened/in tabs/in the
// context.
for (Doc* doc : m_ctx->documents())
docs.push_back(doc);
// Add documents that are currently opened/in tabs/in the
// context.
for (Doc* doc : m_ctx->documents())
docs.push_back(doc);
for (Doc* doc : docs) {
// First we close the document. In this way we receive recent
// notifications related to the document as a app::Doc. If
// we delete the document directly, we destroy the app::Doc
// too early, and then doc::~Document() call
// DocsObserver::onRemoveDocument(). In this way, observers
// could think that they have a fully created app::Doc when
// in reality it's a doc::Document (in the middle of a
// destruction process).
//
// TODO: This problem is because we're extending doc::Document,
// in the future, we should remove app::Doc.
doc->close();
delete doc;
}
for (Doc* doc : docs) {
// First we close the document. In this way we receive recent
// notifications related to the document as a app::Doc. If
// we delete the document directly, we destroy the app::Doc
// too early, and then doc::~Document() call
// DocsObserver::onRemoveDocument(). In this way, observers
// could think that they have a fully created app::Doc when
// in reality it's a doc::Document (in the middle of a
// destruction process).
//
// TODO: This problem is because we're extending doc::Document,
// in the future, we should remove app::Doc.
doc->close();
delete doc;
}
};
}
};
} // anonymous namespace
@ -479,9 +472,8 @@ void App::run()
auto manager = ui::Manager::getDefault();
#if LAF_WINDOWS
// How to interpret one finger on Windows tablets.
manager->display()->nativeWindow()
->setInterpretOneFingerGestureAsMouseMovement(
preferences().experimental.oneFingerAsMouseMovement());
manager->display()->nativeWindow()->setInterpretOneFingerGestureAsMouseMovement(
preferences().experimental.oneFingerAsMouseMovement());
#endif
#if LAF_LINUX
@ -535,8 +527,7 @@ void App::run()
#ifdef ENABLE_UPDATER
// Launch the thread to check for updates.
app::CheckUpdateThreadLauncher checkUpdate(
m_mainWindow->getCheckUpdateDelegate());
app::CheckUpdateThreadLauncher checkUpdate(m_mainWindow->getCheckUpdateDelegate());
checkUpdate.launch();
#endif
@ -572,7 +563,7 @@ void App::run()
Shell shell;
shell.run(*m_engine);
}
#endif // ENABLE_SCRIPTING
#endif // ENABLE_SCRIPTING
// ----------------------------------------------------------------------
@ -672,10 +663,8 @@ bool App::isPortable()
{
static std::optional<bool> is_portable;
if (!is_portable) {
is_portable =
base::is_file(base::join_path(
base::get_file_path(base::get_app_path()),
"aseprite.ini"));
is_portable = base::is_file(
base::join_path(base::get_file_path(base::get_app_path()), "aseprite.ini"));
}
return *is_portable;
}
@ -870,14 +859,20 @@ int app_get_color_to_clear_layer(Layer* layer)
}
#ifdef ENABLE_DRM
void app_configure_drm() {
void app_configure_drm()
{
ResourceFinder userDirRf, dataDirRf;
userDirRf.includeUserDir("");
dataDirRf.includeDataDir("");
std::map<std::string, std::string> config = {
{"data", dataDirRf.getFirstOrCreateDefault()}
{ "data", dataDirRf.getFirstOrCreateDefault() }
};
DRM_CONFIGURE(get_app_url(), get_app_name(), get_app_version(), userDirRf.getFirstOrCreateDefault(), updater::getUserAgent(), config);
DRM_CONFIGURE(get_app_url(),
get_app_name(),
get_app_version(),
userDirRf.getFirstOrCreateDefault(),
updater::getUserAgent(),
config);
}
#endif

View File

@ -19,145 +19,146 @@
#include <vector>
namespace doc {
class Layer;
class Layer;
}
namespace ui {
class UISystem;
class UISystem;
}
namespace app {
#ifdef ENABLE_SCRIPTING
namespace script {
class Engine;
}
namespace script {
class Engine;
}
#endif
class AppMod;
class AppOptions;
class BackupIndicator;
class Context;
class ContextBar;
class Doc;
class Extensions;
class INotificationDelegate;
class InputChain;
class LegacyModules;
class LoggerModule;
class MainWindow;
class Preferences;
class RecentFiles;
class Timeline;
class Workspace;
class AppMod;
class AppOptions;
class BackupIndicator;
class Context;
class ContextBar;
class Doc;
class Extensions;
class INotificationDelegate;
class InputChain;
class LegacyModules;
class LoggerModule;
class MainWindow;
class Preferences;
class RecentFiles;
class Timeline;
class Workspace;
namespace crash {
class DataRecovery;
namespace crash {
class DataRecovery;
}
namespace tools {
class ActiveToolManager;
class Tool;
class ToolBox;
} // namespace tools
using namespace doc;
class App {
public:
App(AppMod* mod = nullptr);
~App();
static App* instance() { return m_instance; }
Context* context();
// Returns true if Aseprite is running with GUI available.
bool isGui() const { return m_isGui; }
// Returns true if the application is running in portable mode.
bool isPortable();
// Runs the Aseprite application. In GUI mode it's the top-level
// window, in console/scripting it just runs the specified
// scripts.
int initialize(const AppOptions& options);
void run();
void close();
AppMod* mod() const { return m_mod; }
tools::ToolBox* toolBox() const;
tools::Tool* activeTool() const;
tools::ActiveToolManager* activeToolManager() const;
RecentFiles* recentFiles() const;
MainWindow* mainWindow() const { return m_mainWindow.get(); }
Workspace* workspace() const;
ContextBar* contextBar() const;
Timeline* timeline() const;
Preferences& preferences() const;
Extensions& extensions() const;
crash::DataRecovery* dataRecovery() const;
AppBrushes& brushes()
{
ASSERT(m_brushes.get());
return *m_brushes;
}
namespace tools {
class ActiveToolManager;
class Tool;
class ToolBox;
}
void showNotification(INotificationDelegate* del);
void showBackupNotification(bool state);
void updateDisplayTitleBar();
using namespace doc;
class App {
public:
App(AppMod* mod = nullptr);
~App();
static App* instance() { return m_instance; }
Context* context();
// Returns true if Aseprite is running with GUI available.
bool isGui() const { return m_isGui; }
// Returns true if the application is running in portable mode.
bool isPortable();
// Runs the Aseprite application. In GUI mode it's the top-level
// window, in console/scripting it just runs the specified
// scripts.
int initialize(const AppOptions& options);
void run();
void close();
AppMod* mod() const { return m_mod; }
tools::ToolBox* toolBox() const;
tools::Tool* activeTool() const;
tools::ActiveToolManager* activeToolManager() const;
RecentFiles* recentFiles() const;
MainWindow* mainWindow() const { return m_mainWindow.get(); }
Workspace* workspace() const;
ContextBar* contextBar() const;
Timeline* timeline() const;
Preferences& preferences() const;
Extensions& extensions() const;
crash::DataRecovery* dataRecovery() const;
AppBrushes& brushes() {
ASSERT(m_brushes.get());
return *m_brushes;
}
void showNotification(INotificationDelegate* del);
void showBackupNotification(bool state);
void updateDisplayTitleBar();
InputChain& inputChain();
InputChain& inputChain();
#ifdef ENABLE_SCRIPTING
script::Engine* scriptEngine() { return m_engine.get(); }
script::Engine* scriptEngine() { return m_engine.get(); }
#endif
const std::string& memoryDumpFilename() const { return m_memoryDumpFilename; }
void memoryDumpFilename(const std::string& fn) { m_memoryDumpFilename = fn; }
const std::string& memoryDumpFilename() const { return m_memoryDumpFilename; }
void memoryDumpFilename(const std::string& fn) { m_memoryDumpFilename = fn; }
// App Signals
obs::signal<void()> Exit;
obs::signal<void()> ExitGui;
obs::signal<void()> PaletteChange;
obs::signal<void()> ColorSpaceChange;
obs::signal<void()> PalettePresetsChange;
// App Signals
obs::signal<void()> Exit;
obs::signal<void()> ExitGui;
obs::signal<void()> PaletteChange;
obs::signal<void()> ColorSpaceChange;
obs::signal<void()> PalettePresetsChange;
private:
class CoreModules;
class LoadLanguage;
class Modules;
private:
class CoreModules;
class LoadLanguage;
class Modules;
static App* m_instance;
static App* m_instance;
AppMod* m_mod;
std::unique_ptr<ui::UISystem> m_uiSystem;
std::unique_ptr<CoreModules> m_coreModules;
std::unique_ptr<Modules> m_modules;
std::unique_ptr<LegacyModules> m_legacy;
bool m_isGui;
bool m_isShell;
AppMod* m_mod;
std::unique_ptr<ui::UISystem> m_uiSystem;
std::unique_ptr<CoreModules> m_coreModules;
std::unique_ptr<Modules> m_modules;
std::unique_ptr<LegacyModules> m_legacy;
bool m_isGui;
bool m_isShell;
#ifdef ENABLE_STEAM
bool m_inAppSteam = true;
bool m_inAppSteam = true;
#endif
std::unique_ptr<MainWindow> m_mainWindow;
base::paths m_files;
std::unique_ptr<AppBrushes> m_brushes;
std::unique_ptr<BackupIndicator> m_backupIndicator;
std::unique_ptr<MainWindow> m_mainWindow;
base::paths m_files;
std::unique_ptr<AppBrushes> m_brushes;
std::unique_ptr<BackupIndicator> m_backupIndicator;
#ifdef ENABLE_SCRIPTING
std::unique_ptr<script::Engine> m_engine;
std::unique_ptr<script::Engine> m_engine;
#endif
// Set the memory dump filename to show in the Preferences dialog
// or the "send crash" dialog. It's set by the SendCrash class.
std::string m_memoryDumpFilename;
};
// Set the memory dump filename to show in the Preferences dialog
// or the "send crash" dialog. It's set by the SendCrash class.
std::string m_memoryDumpFilename;
};
void app_refresh_screen();
void app_rebuild_documents_tabs();
PixelFormat app_get_current_pixel_format();
int app_get_color_to_clear_layer(doc::Layer* layer);
void app_configure_drm();
void app_refresh_screen();
void app_rebuild_documents_tabs();
PixelFormat app_get_current_pixel_format();
int app_get_color_to_clear_layer(doc::Layer* layer);
void app_configure_drm();
} // namespace app

View File

@ -6,7 +6,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/app_brushes.h"
@ -41,9 +41,8 @@ ImageRef load_xml_image(const XMLElement* imageElem)
ImageRef image;
int w, h;
if (imageElem->QueryIntAttribute("width", &w) != XML_SUCCESS ||
imageElem->QueryIntAttribute("height", &h) != XML_SUCCESS ||
w < 0 || w > 9999 ||
h < 0 || h > 9999)
imageElem->QueryIntAttribute("height", &h) != XML_SUCCESS || w < 0 || w > 9999 || h < 0 ||
h > 9999)
return image;
auto formatValue = imageElem->Attribute("format");
@ -66,10 +65,14 @@ ImageRef load_xml_image(const XMLElement* imageElem)
if ((end - it) < 4)
break;
int r = *it; ++it;
int g = *it; ++it;
int b = *it; ++it;
int a = *it; ++it;
int r = *it;
++it;
int g = *it;
++it;
int b = *it;
++it;
int a = *it;
++it;
pixel = doc::rgba(r, g, b, a);
}
@ -81,8 +84,10 @@ ImageRef load_xml_image(const XMLElement* imageElem)
if ((end - it) < 2)
break;
int v = *it; ++it;
int a = *it; ++it;
int v = *it;
++it;
int a = *it;
++it;
pixel = doc::graya(v, a);
}
@ -121,10 +126,10 @@ void save_xml_image(XMLElement* imageElem, const Image* image)
std::string format;
switch (image->pixelFormat()) {
case IMAGE_RGB: format = "rgba"; break;
case IMAGE_RGB: format = "rgba"; break;
case IMAGE_GRAYSCALE: format = "grayscale"; break;
case IMAGE_INDEXED: format = "indexed"; break;
case IMAGE_BITMAP: format = "bitmap"; break; // TODO add "bitmap" format
case IMAGE_INDEXED: format = "indexed"; break;
case IMAGE_BITMAP: format = "bitmap"; break; // TODO add "bitmap" format
}
ASSERT(!format.empty());
if (!format.empty())
@ -133,7 +138,7 @@ void save_xml_image(XMLElement* imageElem, const Image* image)
base::buffer data;
data.reserve(h * image->widthBytes());
switch (image->pixelFormat()) {
case IMAGE_RGB:{
case IMAGE_RGB: {
const LockImageBits<RgbTraits> pixels(image);
for (const auto& pixel : pixels) {
data.push_back(doc::rgba_getr(pixel));
@ -143,7 +148,7 @@ void save_xml_image(XMLElement* imageElem, const Image* image)
}
break;
}
case IMAGE_GRAYSCALE:{
case IMAGE_GRAYSCALE: {
const LockImageBits<GrayscaleTraits> pixels(image);
for (const auto& pixel : pixels) {
data.push_back(doc::graya_getv(pixel));
@ -173,7 +178,7 @@ void save_xml_image(XMLElement* imageElem, const Image* image)
imageElem->InsertNewText(data_base64.c_str());
}
} // anonymous namespace
} // anonymous namespace
AppBrushes::AppBrushes()
{
@ -187,8 +192,7 @@ AppBrushes::AppBrushes()
load(fn);
}
catch (const std::exception& ex) {
LOG(ERROR, "BRSH: Error loading user brushes from '%s': %s\n",
fn.c_str(), ex.what());
LOG(ERROR, "BRSH: Error loading user brushes from '%s': %s\n", fn.c_str(), ex.what());
}
}
m_userBrushesFilename = fn;
@ -202,8 +206,10 @@ AppBrushes::~AppBrushes()
}
// We cannot throw exceptions from a destructor
catch (const std::exception& ex) {
LOG(ERROR, "BRSH: Error saving user brushes to '%s': %s\n",
m_userBrushesFilename.c_str(), ex.what());
LOG(ERROR,
"BRSH: Error saving user brushes to '%s': %s\n",
m_userBrushesFilename.c_str(),
ex.what());
}
}
}
@ -211,10 +217,10 @@ AppBrushes::~AppBrushes()
AppBrushes::slot_id AppBrushes::addBrushSlot(const BrushSlot& brush)
{
// Use an empty slot
for (size_t i=0; i<m_slots.size(); ++i) {
for (size_t i = 0; i < m_slots.size(); ++i) {
if (!m_slots[i].locked() || m_slots[i].isEmpty()) {
m_slots[i] = brush;
return i+1;
return i + 1;
}
}
@ -230,8 +236,7 @@ void AppBrushes::removeBrushSlot(slot_id slot)
m_slots[slot] = BrushSlot();
// Erase empty trailing slots
while (!m_slots.empty() &&
m_slots[m_slots.size()-1].isEmpty())
while (!m_slots.empty() && m_slots[m_slots.size() - 1].isEmpty())
m_slots.erase(--m_slots.end());
ItemsChange();
@ -249,8 +254,7 @@ void AppBrushes::removeAllBrushSlots()
bool AppBrushes::hasBrushSlot(slot_id slot) const
{
--slot;
return (slot >= 0 && slot < (int)m_slots.size() &&
!m_slots[slot].isEmpty());
return (slot >= 0 && slot < (int)m_slots.size() && !m_slots[slot].isEmpty());
}
BrushSlot AppBrushes::getBrushSlot(slot_id slot) const
@ -274,8 +278,7 @@ void AppBrushes::setBrushSlot(slot_id slot, const BrushSlot& brush)
void AppBrushes::lockBrushSlot(slot_id slot)
{
--slot;
if (slot >= 0 && slot < (int)m_slots.size() &&
!m_slots[slot].isEmpty()) {
if (slot >= 0 && slot < (int)m_slots.size() && !m_slots[slot].isEmpty()) {
m_slots[slot].setLocked(true);
}
}
@ -283,8 +286,7 @@ void AppBrushes::lockBrushSlot(slot_id slot)
void AppBrushes::unlockBrushSlot(slot_id slot)
{
--slot;
if (slot >= 0 && slot < (int)m_slots.size() &&
!m_slots[slot].isEmpty()) {
if (slot >= 0 && slot < (int)m_slots.size() && !m_slots[slot].isEmpty()) {
m_slots[slot].setLocked(false);
}
}
@ -292,26 +294,22 @@ void AppBrushes::unlockBrushSlot(slot_id slot)
bool AppBrushes::isBrushSlotLocked(slot_id slot) const
{
--slot;
if (slot >= 0 && slot < (int)m_slots.size() &&
!m_slots[slot].isEmpty()) {
if (slot >= 0 && slot < (int)m_slots.size() && !m_slots[slot].isEmpty()) {
return m_slots[slot].locked();
}
else
return false;
}
static const int kBrushFlags =
int(BrushSlot::Flags::BrushType) |
int(BrushSlot::Flags::BrushSize) |
int(BrushSlot::Flags::BrushAngle);
static const int kBrushFlags = int(BrushSlot::Flags::BrushType) | int(BrushSlot::Flags::BrushSize) |
int(BrushSlot::Flags::BrushAngle);
void AppBrushes::load(const std::string& filename)
{
XMLDocumentRef doc = app::open_xml(filename);
XMLHandle handle(doc.get());
XMLElement* brushElem = handle
.FirstChildElement("brushes")
.FirstChildElement("brush").ToElement();
XMLElement* brushElem =
handle.FirstChildElement("brushes").FirstChildElement("brush").ToElement();
while (brushElem) {
// flags
@ -329,14 +327,15 @@ void AppBrushes::load(const std::string& filename)
const char* size = brushElem->Attribute("size");
const char* angle = brushElem->Attribute("angle");
if (type || size || angle) {
if (type) flags |= int(BrushSlot::Flags::BrushType);
if (size) flags |= int(BrushSlot::Flags::BrushSize);
if (angle) flags |= int(BrushSlot::Flags::BrushAngle);
brush.reset(
new Brush(
(type ? string_id_to_brush_type(type): kFirstBrushType),
(size ? base::convert_to<int>(std::string(size)): 1),
(angle ? base::convert_to<int>(std::string(angle)): 0)));
if (type)
flags |= int(BrushSlot::Flags::BrushType);
if (size)
flags |= int(BrushSlot::Flags::BrushSize);
if (angle)
flags |= int(BrushSlot::Flags::BrushAngle);
brush.reset(new Brush((type ? string_id_to_brush_type(type) : kFirstBrushType),
(size ? base::convert_to<int>(std::string(size)) : 1),
(angle ? base::convert_to<int>(std::string(angle)) : 0)));
}
// Brush image
@ -397,16 +396,19 @@ void AppBrushes::load(const std::string& filename)
}
// Image color (enabled by default for backward compatibility)
if (!brushElem->Attribute("imagecolor") ||
bool_attr(brushElem, "imagecolor", false))
if (!brushElem->Attribute("imagecolor") || bool_attr(brushElem, "imagecolor", false))
flags |= int(BrushSlot::Flags::ImageColor);
if (flags != 0)
flags |= int(BrushSlot::Flags::Locked);
BrushSlot brushSlot(BrushSlot::Flags(flags),
brush, fgColor, bgColor,
inkType, inkOpacity, shade,
brush,
fgColor,
bgColor,
inkType,
inkOpacity,
shade,
pixelPerfect);
m_slots.push_back(brushSlot);
@ -437,8 +439,7 @@ void AppBrushes::save(const std::string& filename) const
ASSERT(slot.brush());
if (flags & int(BrushSlot::Flags::BrushType)) {
brushElem->SetAttribute(
"type", brush_type_to_string_id(slot.brush()->type()).c_str());
brushElem->SetAttribute("type", brush_type_to_string_id(slot.brush()->type()).c_str());
}
if (flags & int(BrushSlot::Flags::BrushSize)) {
@ -449,8 +450,7 @@ void AppBrushes::save(const std::string& filename) const
brushElem->SetAttribute("angle", slot.brush()->angle());
}
if (slot.brush()->type() == kImageBrushType &&
slot.brush()->originalImage()) {
if (slot.brush()->type() == kImageBrushType && slot.brush()->originalImage()) {
XMLElement* elem = brushElem->InsertNewChildElement("image");
save_xml_image(elem, slot.brush()->originalImage());
@ -460,9 +460,8 @@ void AppBrushes::save(const std::string& filename) const
}
// Image color
brushElem->SetAttribute(
"imagecolor",
(flags & int(BrushSlot::Flags::ImageColor)) ? "true": "false");
brushElem->SetAttribute("imagecolor",
(flags & int(BrushSlot::Flags::ImageColor)) ? "true" : "false");
}
}
@ -480,8 +479,7 @@ void AppBrushes::save(const std::string& filename) const
// Ink
if (flags & int(BrushSlot::Flags::InkType)) {
XMLElement* elem = brushElem->InsertNewChildElement("inktype");
elem->SetAttribute(
"value", app::tools::ink_type_to_string_id(slot.inkType()).c_str());
elem->SetAttribute("value", app::tools::ink_type_to_string_id(slot.inkType()).c_str());
}
if (flags & int(BrushSlot::Flags::InkOpacity)) {
@ -498,7 +496,7 @@ void AppBrushes::save(const std::string& filename) const
// Pixel-perfect
if (flags & int(BrushSlot::Flags::PixelPerfect)) {
XMLElement* elem = brushElem->InsertNewChildElement("pixelperfect");
elem->SetAttribute("value", slot.pixelPerfect() ? "true": "false");
elem->SetAttribute("value", slot.pixelPerfect() ? "true" : "false");
}
}
}

View File

@ -18,41 +18,41 @@
namespace app {
class AppBrushes {
public:
// Number of slot (a range from 1 to AppBrushes::size() inclusive)
typedef int slot_id;
typedef std::vector<BrushSlot> BrushSlots;
class AppBrushes {
public:
// Number of slot (a range from 1 to AppBrushes::size() inclusive)
typedef int slot_id;
typedef std::vector<BrushSlot> BrushSlots;
AppBrushes();
~AppBrushes();
AppBrushes();
~AppBrushes();
// Adds a new brush and returns the slot number where the brush
// is now available.
slot_id addBrushSlot(const BrushSlot& brush);
void removeBrushSlot(slot_id slot);
void removeAllBrushSlots();
bool hasBrushSlot(slot_id slot) const;
const doc::Brushes& getStandardBrushes() { return m_standard; }
BrushSlot getBrushSlot(slot_id slot) const;
void setBrushSlot(slot_id slot, const BrushSlot& brush);
const BrushSlots& getBrushSlots() const { return m_slots; }
// Adds a new brush and returns the slot number where the brush
// is now available.
slot_id addBrushSlot(const BrushSlot& brush);
void removeBrushSlot(slot_id slot);
void removeAllBrushSlots();
bool hasBrushSlot(slot_id slot) const;
const doc::Brushes& getStandardBrushes() { return m_standard; }
BrushSlot getBrushSlot(slot_id slot) const;
void setBrushSlot(slot_id slot, const BrushSlot& brush);
const BrushSlots& getBrushSlots() const { return m_slots; }
void lockBrushSlot(slot_id slot);
void unlockBrushSlot(slot_id slot);
bool isBrushSlotLocked(slot_id slot) const;
void lockBrushSlot(slot_id slot);
void unlockBrushSlot(slot_id slot);
bool isBrushSlotLocked(slot_id slot) const;
obs::signal<void()> ItemsChange;
obs::signal<void()> ItemsChange;
private:
void load(const std::string& filename);
void save(const std::string& filename) const;
static std::string userBrushesFilename();
private:
void load(const std::string& filename);
void save(const std::string& filename) const;
static std::string userBrushesFilename();
doc::Brushes m_standard;
BrushSlots m_slots;
std::string m_userBrushesFilename;
};
doc::Brushes m_standard;
BrushSlots m_slots;
std::string m_userBrushesFilename;
};
} // namespace app

View File

@ -6,7 +6,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/app_menus.h"
@ -37,11 +37,11 @@
#include "tinyxml2.h"
#include <algorithm>
#include <cctype>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#include <cstdlib>
#define MENUS_TRACE(...) // TRACEARGS
@ -53,18 +53,18 @@ using namespace ui;
namespace {
// TODO Move this to "os" layer
const int kUnicodeEsc = 27;
const int kUnicodeEnter = '\r'; // 10
const int kUnicodeInsert = 0xF727; // NSInsertFunctionKey
const int kUnicodeDel = 0xF728; // NSDeleteFunctionKey
const int kUnicodeHome = 0xF729; // NSHomeFunctionKey
const int kUnicodeEnd = 0xF72B; // NSEndFunctionKey
const int kUnicodePageUp = 0xF72C; // NSPageUpFunctionKey
const int kUnicodeEsc = 27;
const int kUnicodeEnter = '\r'; // 10
const int kUnicodeInsert = 0xF727; // NSInsertFunctionKey
const int kUnicodeDel = 0xF728; // NSDeleteFunctionKey
const int kUnicodeHome = 0xF729; // NSHomeFunctionKey
const int kUnicodeEnd = 0xF72B; // NSEndFunctionKey
const int kUnicodePageUp = 0xF72C; // NSPageUpFunctionKey
const int kUnicodePageDown = 0xF72D; // NSPageDownFunctionKey
const int kUnicodeLeft = 0xF702; // NSLeftArrowFunctionKey
const int kUnicodeRight = 0xF703; // NSRightArrowFunctionKey
const int kUnicodeUp = 0xF700; // NSUpArrowFunctionKey
const int kUnicodeDown = 0xF701; // NSDownArrowFunctionKey
const int kUnicodeLeft = 0xF702; // NSLeftArrowFunctionKey
const int kUnicodeRight = 0xF703; // NSRightArrowFunctionKey
const int kUnicodeUp = 0xF700; // NSUpArrowFunctionKey
const int kUnicodeDown = 0xF701; // NSDownArrowFunctionKey
const char* kFileRecentListGroup = "file_recent_list";
@ -80,22 +80,12 @@ bool is_text_entry_shortcut(const os::Shortcut& shortcut)
const int lchr = std::tolower(chr);
bool result =
((mod == os::KeyModifiers::kKeyNoneModifier ||
mod == os::KeyModifiers::kKeyShiftModifier) &&
chr >= 32 && chr < 0xF000)
||
((mod == os::KeyModifiers::kKeyCmdModifier ||
mod == os::KeyModifiers::kKeyCtrlModifier) &&
(lchr == 'a' || lchr == 'c' || lchr == 'v' || lchr == 'x'))
||
(chr == kUnicodeInsert ||
chr == kUnicodeDel ||
chr == kUnicodeHome ||
chr == kUnicodeEnd ||
chr == kUnicodeLeft ||
chr == kUnicodeRight ||
chr == kUnicodeEsc ||
chr == kUnicodeEnter);
((mod == os::KeyModifiers::kKeyNoneModifier || mod == os::KeyModifiers::kKeyShiftModifier) &&
chr >= 32 && chr < 0xF000) ||
((mod == os::KeyModifiers::kKeyCmdModifier || mod == os::KeyModifiers::kKeyCtrlModifier) &&
(lchr == 'a' || lchr == 'c' || lchr == 'v' || lchr == 'x')) ||
(chr == kUnicodeInsert || chr == kUnicodeDel || chr == kUnicodeHome || chr == kUnicodeEnd ||
chr == kUnicodeLeft || chr == kUnicodeRight || chr == kUnicodeEsc || chr == kUnicodeEnter);
return result;
}
@ -125,8 +115,7 @@ bool can_call_global_shortcut(const AppMenuItem::Native* native)
// prefer text input, so we cannot call shortcuts without
// modifiers (e.g. F or T keystrokes) to trigger a global command
// in a text field.
(focus == nullptr ||
focus->type() != ui::kEntryWidget ||
(focus == nullptr || focus->type() != ui::kEntryWidget ||
!is_text_entry_shortcut(native->shortcut)) &&
(native->keyContext == KeyContext::Any ||
native->keyContext == KeyboardShortcuts::instance()->getCurrentKeyContext());
@ -137,133 +126,133 @@ bool can_call_global_shortcut(const AppMenuItem::Native* native)
int from_scancode_to_unicode(KeyScancode scancode)
{
static int map[] = {
0, // kKeyNil
'a', // kKeyA
'b', // kKeyB
'c', // kKeyC
'd', // kKeyD
'e', // kKeyE
'f', // kKeyF
'g', // kKeyG
'h', // kKeyH
'i', // kKeyI
'j', // kKeyJ
'k', // kKeyK
'l', // kKeyL
'm', // kKeyM
'n', // kKeyN
'o', // kKeyO
'p', // kKeyP
'q', // kKeyQ
'r', // kKeyR
's', // kKeyS
't', // kKeyT
'u', // kKeyU
'v', // kKeyV
'w', // kKeyW
'x', // kKeyX
'y', // kKeyY
'z', // kKeyZ
'0', // kKey0
'1', // kKey1
'2', // kKey2
'3', // kKey3
'4', // kKey4
'5', // kKey5
'6', // kKey6
'7', // kKey7
'8', // kKey8
'9', // kKey9
0, // kKey0Pad
0, // kKey1Pad
0, // kKey2Pad
0, // kKey3Pad
0, // kKey4Pad
0, // kKey5Pad
0, // kKey6Pad
0, // kKey7Pad
0, // kKey8Pad
0, // kKey9Pad
0xF704, // kKeyF1 (NSF1FunctionKey)
0xF705, // kKeyF2
0xF706, // kKeyF3
0xF707, // kKeyF4
0xF708, // kKeyF5
0xF709, // kKeyF6
0xF70A, // kKeyF7
0xF70B, // kKeyF8
0xF70C, // kKeyF9
0xF70D, // kKeyF10
0xF70E, // kKeyF11
0xF70F, // kKeyF12
kUnicodeEsc, // kKeyEsc
'~', // kKeyTilde
'-', // kKeyMinus
'=', // kKeyEquals
8, // kKeyBackspace
9, // kKeyTab
'[', // kKeyOpenbrace
']', // kKeyClosebrace
kUnicodeEnter, // kKeyEnter
':', // kKeyColon
'\'', // kKeyQuote
'\\', // kKeyBackslash
0, // kKeyBackslash2
',', // kKeyComma
'.', // kKeyStop
'/', // kKeySlash
' ', // kKeySpace
kUnicodeInsert, // kKeyInsert (NSInsertFunctionKey)
kUnicodeDel, // kKeyDel (NSDeleteFunctionKey)
kUnicodeHome, // kKeyHome (NSHomeFunctionKey)
kUnicodeEnd, // kKeyEnd (NSEndFunctionKey)
kUnicodePageUp, // kKeyPageUp (NSPageUpFunctionKey)
0, // kKeyNil
'a', // kKeyA
'b', // kKeyB
'c', // kKeyC
'd', // kKeyD
'e', // kKeyE
'f', // kKeyF
'g', // kKeyG
'h', // kKeyH
'i', // kKeyI
'j', // kKeyJ
'k', // kKeyK
'l', // kKeyL
'm', // kKeyM
'n', // kKeyN
'o', // kKeyO
'p', // kKeyP
'q', // kKeyQ
'r', // kKeyR
's', // kKeyS
't', // kKeyT
'u', // kKeyU
'v', // kKeyV
'w', // kKeyW
'x', // kKeyX
'y', // kKeyY
'z', // kKeyZ
'0', // kKey0
'1', // kKey1
'2', // kKey2
'3', // kKey3
'4', // kKey4
'5', // kKey5
'6', // kKey6
'7', // kKey7
'8', // kKey8
'9', // kKey9
0, // kKey0Pad
0, // kKey1Pad
0, // kKey2Pad
0, // kKey3Pad
0, // kKey4Pad
0, // kKey5Pad
0, // kKey6Pad
0, // kKey7Pad
0, // kKey8Pad
0, // kKey9Pad
0xF704, // kKeyF1 (NSF1FunctionKey)
0xF705, // kKeyF2
0xF706, // kKeyF3
0xF707, // kKeyF4
0xF708, // kKeyF5
0xF709, // kKeyF6
0xF70A, // kKeyF7
0xF70B, // kKeyF8
0xF70C, // kKeyF9
0xF70D, // kKeyF10
0xF70E, // kKeyF11
0xF70F, // kKeyF12
kUnicodeEsc, // kKeyEsc
'~', // kKeyTilde
'-', // kKeyMinus
'=', // kKeyEquals
8, // kKeyBackspace
9, // kKeyTab
'[', // kKeyOpenbrace
']', // kKeyClosebrace
kUnicodeEnter, // kKeyEnter
':', // kKeyColon
'\'', // kKeyQuote
'\\', // kKeyBackslash
0, // kKeyBackslash2
',', // kKeyComma
'.', // kKeyStop
'/', // kKeySlash
' ', // kKeySpace
kUnicodeInsert, // kKeyInsert (NSInsertFunctionKey)
kUnicodeDel, // kKeyDel (NSDeleteFunctionKey)
kUnicodeHome, // kKeyHome (NSHomeFunctionKey)
kUnicodeEnd, // kKeyEnd (NSEndFunctionKey)
kUnicodePageUp, // kKeyPageUp (NSPageUpFunctionKey)
kUnicodePageDown, // kKeyPageDown (NSPageDownFunctionKey)
kUnicodeLeft, // kKeyLeft (NSLeftArrowFunctionKey)
kUnicodeRight, // kKeyRight (NSRightArrowFunctionKey)
kUnicodeUp, // kKeyUp (NSUpArrowFunctionKey)
kUnicodeDown, // kKeyDown (NSDownArrowFunctionKey)
'/', // kKeySlashPad
'*', // kKeyAsterisk
0, // kKeyMinusPad
0, // kKeyPlusPad
0, // kKeyDelPad
0, // kKeyEnterPad
0, // kKeyPrtscr
0, // kKeyPause
0, // kKeyAbntC1
0, // kKeyYen
0, // kKeyKana
0, // kKeyConvert
0, // kKeyNoconvert
0, // kKeyAt
0, // kKeyCircumflex
0, // kKeyColon2
0, // kKeyKanji
0, // kKeyEqualsPad
'`', // kKeyBackquote
0, // kKeySemicolon
0, // kKeyUnknown1
0, // kKeyUnknown2
0, // kKeyUnknown3
0, // kKeyUnknown4
0, // kKeyUnknown5
0, // kKeyUnknown6
0, // kKeyUnknown7
0, // kKeyUnknown8
0, // kKeyLShift
0, // kKeyRShift
0, // kKeyLControl
0, // kKeyRControl
0, // kKeyAlt
0, // kKeyAltGr
0, // kKeyLWin
0, // kKeyRWin
0, // kKeyMenu
0, // kKeyCommand
0, // kKeyScrLock
0, // kKeyNumLock
0, // kKeyCapsLock
kUnicodeLeft, // kKeyLeft (NSLeftArrowFunctionKey)
kUnicodeRight, // kKeyRight (NSRightArrowFunctionKey)
kUnicodeUp, // kKeyUp (NSUpArrowFunctionKey)
kUnicodeDown, // kKeyDown (NSDownArrowFunctionKey)
'/', // kKeySlashPad
'*', // kKeyAsterisk
0, // kKeyMinusPad
0, // kKeyPlusPad
0, // kKeyDelPad
0, // kKeyEnterPad
0, // kKeyPrtscr
0, // kKeyPause
0, // kKeyAbntC1
0, // kKeyYen
0, // kKeyKana
0, // kKeyConvert
0, // kKeyNoconvert
0, // kKeyAt
0, // kKeyCircumflex
0, // kKeyColon2
0, // kKeyKanji
0, // kKeyEqualsPad
'`', // kKeyBackquote
0, // kKeySemicolon
0, // kKeyUnknown1
0, // kKeyUnknown2
0, // kKeyUnknown3
0, // kKeyUnknown4
0, // kKeyUnknown5
0, // kKeyUnknown6
0, // kKeyUnknown7
0, // kKeyUnknown8
0, // kKeyLShift
0, // kKeyRShift
0, // kKeyLControl
0, // kKeyRControl
0, // kKeyAlt
0, // kKeyAltGr
0, // kKeyLWin
0, // kKeyRWin
0, // kKeyMenu
0, // kKeyCommand
0, // kKeyScrLock
0, // kKeyNumLock
0, // kKeyCapsLock
};
if (scancode >= 0 && scancode < sizeof(map) / sizeof(map[0]))
return map[scancode];
@ -271,9 +260,8 @@ int from_scancode_to_unicode(KeyScancode scancode)
return 0;
}
AppMenuItem::Native get_native_shortcut_for_command(
const char* commandId,
const Params& params = Params())
AppMenuItem::Native get_native_shortcut_for_command(const char* commandId,
const Params& params = Params())
{
AppMenuItem::Native native;
KeyPtr key = KeyboardShortcuts::instance()->command(commandId, params);
@ -312,8 +300,7 @@ os::Shortcut get_os_shortcut_from_key(const Key* key)
#endif
return os::Shortcut(
(accel.unicodeChar() ? accel.unicodeChar():
from_scancode_to_unicode(accel.scancode())),
(accel.unicodeChar() ? accel.unicodeChar() : from_scancode_to_unicode(accel.scancode())),
accel.modifiers());
}
else
@ -326,18 +313,15 @@ AppMenus* AppMenus::instance()
static AppMenus* instance = NULL;
if (!instance) {
instance = new AppMenus;
App::instance()->Exit.connect([]{ destroy_instance(instance); });
App::instance()->Exit.connect([] { destroy_instance(instance); });
}
return instance;
}
AppMenus::AppMenus()
: m_recentFilesPlaceholder(nullptr)
, m_osMenu(nullptr)
AppMenus::AppMenus() : m_recentFilesPlaceholder(nullptr), m_osMenu(nullptr)
{
m_recentFilesConn =
App::instance()->recentFiles()->Changed.connect(
[this]{ rebuildRecentList(); });
m_recentFilesConn = App::instance()->recentFiles()->Changed.connect(
[this] { rebuildRecentList(); });
}
void AppMenus::reload()
@ -386,8 +370,7 @@ void AppMenus::reload()
// Add one menu item to run each script from the user scripts/ folder
{
MenuItem* scriptsMenu = dynamic_cast<MenuItem*>(
m_rootMenu->findItemById("scripts_menu"));
MenuItem* scriptsMenu = dynamic_cast<MenuItem*>(m_rootMenu->findItemById("scripts_menu"));
#ifdef ENABLE_SCRIPTING
// Load scripts
ResourceFinder rf;
@ -455,9 +438,7 @@ void AppMenus::reload()
LOG("MENU: Loading commands keyboard shortcuts from %s\n", path);
XMLElement* xmlKey = handle
.FirstChildElement("gui")
.FirstChildElement("keyboard").ToElement();
XMLElement* xmlKey = handle.FirstChildElement("gui").FirstChildElement("keyboard").ToElement();
// From a fresh start, load the default keys
KeyboardShortcuts::instance()->clear();
@ -465,11 +446,9 @@ void AppMenus::reload()
// Load extension-defined keys
for (const Extension* ext : App::instance()->extensions()) {
if (ext->isEnabled() &&
ext->hasKeys()) {
if (ext->isEnabled() && ext->hasKeys()) {
for (const auto& kv : ext->keys()) {
KeyboardShortcuts::instance()->importFile(
kv.second, KeySource::ExtensionDefined);
KeyboardShortcuts::instance()->importFile(kv.second, KeySource::ExtensionDefined);
}
}
}
@ -489,15 +468,12 @@ void AppMenus::reload()
}
#ifdef ENABLE_SCRIPTING
void AppMenus::loadScriptsSubmenu(ui::Menu* menu,
const std::string& dir,
const bool rootLevel)
void AppMenus::loadScriptsSubmenu(ui::Menu* menu, const std::string& dir, const bool rootLevel)
{
auto files = base::list_files(dir);
std::sort(files.begin(), files.end(),
[](const std::string& a, const std::string& b) {
return base::compare_filenames(a, b) < 0;
});
std::sort(files.begin(), files.end(), [](const std::string& a, const std::string& b) {
return base::compare_filenames(a, b) < 0;
});
int insertPos = 0;
for (auto fn : files) {
std::string fullFn = base::join_path(dir, fn);
@ -510,18 +486,15 @@ void AppMenus::loadScriptsSubmenu(ui::Menu* menu,
if (base::string_to_lower(base::get_file_extension(fn)) == "lua") {
Params params;
params.set("filename", fullFn.c_str());
menuitem = new AppMenuItem(
base::get_file_title(fn).c_str(),
CommandId::RunScript(),
params);
menuitem =
new AppMenuItem(base::get_file_title(fn).c_str(), CommandId::RunScript(), params);
}
}
else if (base::is_directory(fullFn)) {
Menu* submenu = new Menu();
loadScriptsSubmenu(submenu, fullFn, false);
menuitem = new AppMenuItem(
base::get_file_title(fn).c_str());
menuitem = new AppMenuItem(base::get_file_title(fn).c_str());
menuitem->setSubmenu(submenu);
}
if (menuitem) {
@ -543,7 +516,8 @@ void AppMenus::initTheme()
bool AppMenus::rebuildRecentList()
{
MENUS_TRACE("MENUS: AppMenus::rebuildRecentList m_recentFilesPlaceholder=", m_recentFilesPlaceholder);
MENUS_TRACE("MENUS: AppMenus::rebuildRecentList m_recentFilesPlaceholder=",
m_recentFilesPlaceholder);
if (!m_recentFilesPlaceholder)
return true;
@ -563,21 +537,15 @@ bool AppMenus::rebuildRecentList()
auto recent = App::instance()->recentFiles();
base::paths files;
files.insert(files.end(),
recent->pinnedFiles().begin(),
recent->pinnedFiles().end());
files.insert(files.end(),
recent->recentFiles().begin(),
recent->recentFiles().end());
files.insert(files.end(), recent->pinnedFiles().begin(), recent->pinnedFiles().end());
files.insert(files.end(), recent->recentFiles().begin(), recent->recentFiles().end());
if (!files.empty()) {
Params params;
for (const auto& fn : files) {
params.set("filename", fn.c_str());
std::unique_ptr<AppMenuItem> menuitem(
new AppMenuItem(base::get_file_name(fn).c_str(),
CommandId::OpenFile(),
params));
new AppMenuItem(base::get_file_name(fn).c_str(), CommandId::OpenFile(), params));
menuitem->setIsRecentFileItem(true);
m_recentMenuItems.push_back(menuitem.get());
@ -585,9 +553,8 @@ bool AppMenus::rebuildRecentList()
}
}
else {
std::unique_ptr<AppMenuItem> menuitem(
new AppMenuItem(
Strings::main_menu_file_no_recent_file()));
std::unique_ptr<AppMenuItem> menuitem(
new AppMenuItem(Strings::main_menu_file_no_recent_file()));
menuitem->setIsRecentFileItem(true);
menuitem->setEnabled(false);
@ -596,10 +563,9 @@ bool AppMenus::rebuildRecentList()
}
// Sync native menus
if (owner->native() &&
owner->native()->menuItem) {
if (owner->native() && owner->native()->menuItem) {
auto menus = os::instance()->menus();
os::MenuRef osMenu = (menus ? menus->makeMenu(): nullptr);
os::MenuRef osMenu = (menus ? menus->makeMenu() : nullptr);
if (osMenu) {
createNativeSubmenus(osMenu.get(), menu);
owner->native()->menuItem->setSubmenu(osMenu);
@ -611,16 +577,14 @@ bool AppMenus::rebuildRecentList()
Menu* AppMenus::getAnimationMenu()
{
auto menuItem =
dynamic_cast<MenuItem*>(m_rootMenu->findItemById("animation_menu"));
auto menuItem = dynamic_cast<MenuItem*>(m_rootMenu->findItemById("animation_menu"));
if (menuItem)
return menuItem->getSubmenu();
else
return nullptr;
}
void AppMenus::addMenuGroup(const std::string& groupId,
MenuItem* menuItem)
void AppMenus::addMenuGroup(const std::string& groupId, MenuItem* menuItem)
{
GroupInfo& group = m_groups[groupId];
ASSERT(group.menu == nullptr);
@ -639,22 +603,20 @@ void AppMenus::removeMenuGroup(const std::string& groupId)
if (group.menu->getOwnerMenuItem()) {
ui::MenuItem* item = group.menu->getOwnerMenuItem();
removeMenuItemFromGroup(
[item](Widget* i){
return item == i;
});
removeMenuItemFromGroup([item](Widget* i) { return item == i; });
}
m_groups.erase(it);
}
}
void AppMenus::addMenuItemIntoGroup(const std::string& groupId,
std::unique_ptr<Widget>&& menuItem)
void AppMenus::addMenuItemIntoGroup(const std::string& groupId, std::unique_ptr<Widget>&& menuItem)
{
auto it = m_groups.find(groupId);
if (it == m_groups.end()) {
LOG(ERROR, "MENU: An extension tried to add a command (%s) in a non-existent group (%s)\n",
menuItem->text().c_str(), groupId.c_str());
LOG(ERROR,
"MENU: An extension tried to add a command (%s) in a non-existent group (%s)\n",
menuItem->text().c_str(),
groupId.c_str());
menuItem.release();
return;
}
@ -666,7 +628,7 @@ void AppMenus::addMenuItemIntoGroup(const std::string& groupId,
if (group.end) {
int insertIndex = menu->getChildIndex(group.end);
ASSERT(insertIndex >= 0);
menu->insertChild(insertIndex+1, menuItem.get());
menu->insertChild(insertIndex + 1, menuItem.get());
}
else {
menu->addChild(menuItem.get());
@ -683,7 +645,7 @@ void AppMenus::removeMenuItemFromGroup(Pred pred)
{
for (auto& it : m_groups) {
GroupInfo& group = it.second;
for (auto it=group.items.begin(); it != group.items.end(); ) {
for (auto it = group.items.begin(); it != group.items.end();) {
auto& item = *it;
if (pred(item)) {
if (item == group.end)
@ -702,19 +664,15 @@ void AppMenus::removeMenuItemFromGroup(Pred pred)
void AppMenus::removeMenuItemFromGroup(Command* cmd)
{
removeMenuItemFromGroup(
[cmd](Widget* item){
auto appMenuItem = dynamic_cast<AppMenuItem*>(item);
return (appMenuItem && appMenuItem->getCommand() == cmd);
});
removeMenuItemFromGroup([cmd](Widget* item) {
auto appMenuItem = dynamic_cast<AppMenuItem*>(item);
return (appMenuItem && appMenuItem->getCommand() == cmd);
});
}
void AppMenus::removeMenuItemFromGroup(Widget* menuItem)
{
removeMenuItemFromGroup(
[menuItem](Widget* item){
return (item == menuItem);
});
removeMenuItemFromGroup([menuItem](Widget* item) { return (item == menuItem); });
}
Menu* AppMenus::loadMenuById(XMLHandle& handle, const char* id)
@ -722,10 +680,8 @@ Menu* AppMenus::loadMenuById(XMLHandle& handle, const char* id)
ASSERT(id != NULL);
// <gui><menus><menu>
XMLElement* xmlMenu = handle
.FirstChildElement("gui")
.FirstChildElement("menus")
.FirstChildElement("menu").ToElement();
XMLElement* xmlMenu =
handle.FirstChildElement("gui").FirstChildElement("menus").FirstChildElement("menu").ToElement();
while (xmlMenu) {
const char* menuId = xmlMenu->Attribute("id");
@ -785,9 +741,7 @@ Widget* AppMenus::convertXmlelemToMenuitem(XMLElement* elem, Menu* menu)
}
const char* commandId = elem->Attribute("command");
Command* command =
(commandId ? Commands::instance()->byId(commandId):
nullptr);
Command* command = (commandId ? Commands::instance()->byId(commandId) : nullptr);
// load params
Params params;
@ -805,9 +759,8 @@ Widget* AppMenus::convertXmlelemToMenuitem(XMLElement* elem, Menu* menu)
}
// Create the item
AppMenuItem* menuitem = new AppMenuItem(m_xmlTranslator(elem, "text"),
(command ? command->id(): ""),
params);
AppMenuItem* menuitem =
new AppMenuItem(m_xmlTranslator(elem, "text"), (command ? command->id() : ""), params);
if (!menuitem)
return nullptr;
@ -821,7 +774,8 @@ Widget* AppMenus::convertXmlelemToMenuitem(XMLElement* elem, Menu* menu)
menuitem->processMnemonicFromText();
}
if (id) menuitem->setId(id);
if (id)
menuitem->setId(id);
if (group) {
m_groups[group].menu = menu;
m_groups[group].end = menuitem;
@ -874,8 +828,7 @@ void AppMenus::applyShortcutToMenuitemsWithCommand(Menu* menu,
const std::string& mi_commandId = menuitem->getCommandId();
const Params& mi_params = menuitem->getParams();
if ((base::utf8_icmp(mi_commandId, command->id()) == 0) &&
(mi_params == params)) {
if ((base::utf8_icmp(mi_commandId, command->id()) == 0) && (mi_params == params)) {
// Set the keyboard shortcut to be shown in this menu-item
menuitem->setKey(key);
}
@ -926,7 +879,7 @@ void AppMenus::updateMenusList()
void AppMenus::createNativeMenus()
{
os::Menus* menus = os::instance()->menus();
if (!menus) // This platform doesn't support native menu items
if (!menus) // This platform doesn't support native menu items
return;
// Save a reference to the old menu to avoid destroying it.
@ -938,26 +891,26 @@ void AppMenus::createNativeMenus()
os::MenuItemInfo about(fmt::format("About {}", get_app_name()));
auto native = get_native_shortcut_for_command(CommandId::About());
about.shortcut = native.shortcut;
about.execute = [native]{
about.execute = [native] {
if (can_call_global_shortcut(&native)) {
Command* cmd = Commands::instance()->byId(CommandId::About());
UIContext::instance()->executeCommandFromMenuOrShortcut(cmd);
}
};
about.validate = [native](os::MenuItem* item){
about.validate = [native](os::MenuItem* item) {
item->setEnabled(can_call_global_shortcut(&native));
};
os::MenuItemInfo preferences("Preferences...");
native = get_native_shortcut_for_command(CommandId::Options());
preferences.shortcut = native.shortcut;
preferences.execute = [native]{
preferences.execute = [native] {
if (can_call_global_shortcut(&native)) {
Command* cmd = Commands::instance()->byId(CommandId::Options());
UIContext::instance()->executeCommandFromMenuOrShortcut(cmd);
}
};
preferences.validate = [native](os::MenuItem* item){
preferences.validate = [native](os::MenuItem* item) {
item->setEnabled(can_call_global_shortcut(&native));
};
@ -973,7 +926,8 @@ void AppMenus::createNativeMenus()
appMenu->addItem(menus->makeMenuItem(preferences));
appMenu->addItem(menus->makeMenuItem(os::MenuItemInfo(os::MenuItemInfo::Separator)));
appMenu->addItem(menus->makeMenuItem(hide));
appMenu->addItem(menus->makeMenuItem(os::MenuItemInfo("Hide Others", os::MenuItemInfo::HideOthers)));
appMenu->addItem(
menus->makeMenuItem(os::MenuItemInfo("Hide Others", os::MenuItemInfo::HideOthers)));
appMenu->addItem(menus->makeMenuItem(os::MenuItemInfo("Show All", os::MenuItemInfo::ShowAll)));
appMenu->addItem(menus->makeMenuItem(os::MenuItemInfo(os::MenuItemInfo::Separator)));
appMenu->addItem(menus->makeMenuItem(quit));
@ -1011,7 +965,7 @@ void AppMenus::createNativeMenus()
// We use helpIndex+1 because the first index in m_osMenu is the
// App menu.
m_osMenu->insertItem(helpIndex+1, windowItem);
m_osMenu->insertItem(helpIndex + 1, windowItem);
}
#endif
@ -1020,8 +974,7 @@ void AppMenus::createNativeMenus()
oldOSMenu.reset();
}
void AppMenus::createNativeSubmenus(os::Menu* osMenu,
const ui::Menu* uiMenu)
void AppMenus::createNativeSubmenus(os::Menu* osMenu, const ui::Menu* uiMenu)
{
os::Menus* menus = os::instance()->menus();
@ -1034,17 +987,15 @@ void AppMenus::createNativeSubmenus(os::Menu* osMenu,
info.type = os::MenuItemInfo::Separator;
}
else if (child->type() == kMenuItemWidget) {
if (appMenuItem &&
appMenuItem->getCommand()) {
native = get_native_shortcut_for_command(
appMenuItem->getCommandId().c_str(),
appMenuItem->getParams());
if (appMenuItem && appMenuItem->getCommand()) {
native = get_native_shortcut_for_command(appMenuItem->getCommandId().c_str(),
appMenuItem->getParams());
}
info.type = os::MenuItemInfo::Normal;
info.text = child->text();
info.shortcut = native.shortcut;
info.execute = [appMenuItem]{
info.execute = [appMenuItem] {
if (can_call_global_shortcut(appMenuItem->native()))
appMenuItem->executeClick();
};
@ -1061,7 +1012,7 @@ void AppMenus::createNativeSubmenus(os::Menu* osMenu,
};
}
else {
ASSERT(false); // Unsupported menu item type
ASSERT(false); // Unsupported menu item type
continue;
}
@ -1077,8 +1028,7 @@ void AppMenus::createNativeSubmenus(os::Menu* osMenu,
osItem->setAsStandardEditMenuItem();
}
if (child->type() == ui::kMenuItemWidget &&
((ui::MenuItem*)child)->hasSubmenu()) {
if (child->type() == ui::kMenuItemWidget && ((ui::MenuItem*)child)->hasSubmenu()) {
os::MenuRef osSubmenu = menus->makeMenu();
createNativeSubmenus(osSubmenu.get(), ((ui::MenuItem*)child)->getSubmenu());
osItem->setSubmenu(osSubmenu);

View File

@ -21,112 +21,110 @@
#include <memory>
namespace tinyxml2 {
class XMLElement;
class XMLHandle;
}
class XMLElement;
class XMLHandle;
} // namespace tinyxml2
namespace app {
class Command;
class Params;
class Command;
class Params;
using namespace ui;
using namespace ui;
// Class to handle/get/reload available menus in gui.xml file.
class AppMenus {
AppMenus();
DISABLE_COPYING(AppMenus);
// Class to handle/get/reload available menus in gui.xml file.
class AppMenus {
AppMenus();
DISABLE_COPYING(AppMenus);
public:
static AppMenus* instance();
public:
static AppMenus* instance();
void reload();
void initTheme();
void reload();
void initTheme();
// Updates the menu of recent files.
bool rebuildRecentList();
// Updates the menu of recent files.
bool rebuildRecentList();
Menu* getRootMenu() { return m_rootMenu.get(); }
Menu* getTabPopupMenu() { return m_tabPopupMenu.get(); }
Menu* getDocumentTabPopupMenu() { return m_documentTabPopupMenu.get(); }
Menu* getLayerPopupMenu() { return m_layerPopupMenu.get(); }
Menu* getFramePopupMenu() { return m_framePopupMenu.get(); }
Menu* getCelPopupMenu() { return m_celPopupMenu.get(); }
Menu* getCelMovementPopupMenu() { return m_celMovementPopupMenu.get(); }
Menu* getTagPopupMenu() { return m_tagPopupMenu.get(); }
Menu* getSlicePopupMenu() { return m_slicePopupMenu.get(); }
Menu* getPalettePopupMenu() { return m_palettePopupMenu.get(); }
Menu* getInkPopupMenu() { return m_inkPopupMenu.get(); }
Menu* getAnimationMenu();
Menu* getNewFrameMenu() { return m_newFramePopupMenu.get(); }
Menu* getRootMenu() { return m_rootMenu.get(); }
Menu* getTabPopupMenu() { return m_tabPopupMenu.get(); }
Menu* getDocumentTabPopupMenu() { return m_documentTabPopupMenu.get(); }
Menu* getLayerPopupMenu() { return m_layerPopupMenu.get(); }
Menu* getFramePopupMenu() { return m_framePopupMenu.get(); }
Menu* getCelPopupMenu() { return m_celPopupMenu.get(); }
Menu* getCelMovementPopupMenu() { return m_celMovementPopupMenu.get(); }
Menu* getTagPopupMenu() { return m_tagPopupMenu.get(); }
Menu* getSlicePopupMenu() { return m_slicePopupMenu.get(); }
Menu* getPalettePopupMenu() { return m_palettePopupMenu.get(); }
Menu* getInkPopupMenu() { return m_inkPopupMenu.get(); }
Menu* getAnimationMenu();
Menu* getNewFrameMenu() { return m_newFramePopupMenu.get(); }
void applyShortcutToMenuitemsWithCommand(Command* command, const Params& params,
const KeyPtr& key);
void syncNativeMenuItemKeyShortcuts();
void applyShortcutToMenuitemsWithCommand(Command* command,
const Params& params,
const KeyPtr& key);
void syncNativeMenuItemKeyShortcuts();
// Menu item handling in groups
void addMenuGroup(const std::string& groupId,
MenuItem* menuItem);
void removeMenuGroup(const std::string& groupId);
void addMenuItemIntoGroup(const std::string& groupId,
std::unique_ptr<Widget>&& menuItem);
void removeMenuItemFromGroup(Command* cmd);
void removeMenuItemFromGroup(Widget* menuItem);
// Menu item handling in groups
void addMenuGroup(const std::string& groupId, MenuItem* menuItem);
void removeMenuGroup(const std::string& groupId);
void addMenuItemIntoGroup(const std::string& groupId, std::unique_ptr<Widget>&& menuItem);
void removeMenuItemFromGroup(Command* cmd);
void removeMenuItemFromGroup(Widget* menuItem);
private:
template<typename Pred>
void removeMenuItemFromGroup(Pred pred);
private:
template<typename Pred>
void removeMenuItemFromGroup(Pred pred);
Menu* loadMenuById(tinyxml2::XMLHandle& handle, const char *id);
Menu* convertXmlelemToMenu(tinyxml2::XMLElement* elem);
Widget* convertXmlelemToMenuitem(tinyxml2::XMLElement* elem, Menu* menu);
void applyShortcutToMenuitemsWithCommand(Menu* menu, Command* command, const Params& params,
const KeyPtr& key);
void syncNativeMenuItemKeyShortcuts(Menu* menu);
void updateMenusList();
void createNativeMenus();
void createNativeSubmenus(os::Menu* osMenu,
const ui::Menu* uiMenu);
Menu* loadMenuById(tinyxml2::XMLHandle& handle, const char* id);
Menu* convertXmlelemToMenu(tinyxml2::XMLElement* elem);
Widget* convertXmlelemToMenuitem(tinyxml2::XMLElement* elem, Menu* menu);
void applyShortcutToMenuitemsWithCommand(Menu* menu,
Command* command,
const Params& params,
const KeyPtr& key);
void syncNativeMenuItemKeyShortcuts(Menu* menu);
void updateMenusList();
void createNativeMenus();
void createNativeSubmenus(os::Menu* osMenu, const ui::Menu* uiMenu);
#ifdef ENABLE_SCRIPTING
void loadScriptsSubmenu(ui::Menu* menu,
const std::string& dir,
const bool rootLevel);
void loadScriptsSubmenu(ui::Menu* menu, const std::string& dir, const bool rootLevel);
#endif
struct GroupInfo {
Menu* menu = nullptr;
Widget* end = nullptr;
WidgetsList items;
};
std::unique_ptr<Menu> m_rootMenu;
Widget* m_recentFilesPlaceholder;
MenuItem* m_helpMenuitem;
std::unique_ptr<Menu> m_tabPopupMenu;
std::unique_ptr<Menu> m_documentTabPopupMenu;
std::unique_ptr<Menu> m_layerPopupMenu;
std::unique_ptr<Menu> m_framePopupMenu;
std::unique_ptr<Menu> m_celPopupMenu;
std::unique_ptr<Menu> m_celMovementPopupMenu;
std::unique_ptr<Menu> m_tagPopupMenu;
std::unique_ptr<Menu> m_slicePopupMenu;
std::unique_ptr<Menu> m_palettePopupMenu;
std::unique_ptr<Menu> m_inkPopupMenu;
std::unique_ptr<Menu> m_newFramePopupMenu;
obs::scoped_connection m_recentFilesConn;
std::vector<Menu*> m_menus;
// List of recent menu items pointing to recent files.
WidgetsList m_recentMenuItems;
// Extension points for plugins (each group is a place where new
// menu items can be added).
std::map<std::string, GroupInfo> m_groups;
// Native main menu bar (== nullptr if the platform doesn't
// support native menus)
os::MenuRef m_osMenu;
XmlTranslator m_xmlTranslator;
struct GroupInfo {
Menu* menu = nullptr;
Widget* end = nullptr;
WidgetsList items;
};
os::Shortcut get_os_shortcut_from_key(const Key* key);
std::unique_ptr<Menu> m_rootMenu;
Widget* m_recentFilesPlaceholder;
MenuItem* m_helpMenuitem;
std::unique_ptr<Menu> m_tabPopupMenu;
std::unique_ptr<Menu> m_documentTabPopupMenu;
std::unique_ptr<Menu> m_layerPopupMenu;
std::unique_ptr<Menu> m_framePopupMenu;
std::unique_ptr<Menu> m_celPopupMenu;
std::unique_ptr<Menu> m_celMovementPopupMenu;
std::unique_ptr<Menu> m_tagPopupMenu;
std::unique_ptr<Menu> m_slicePopupMenu;
std::unique_ptr<Menu> m_palettePopupMenu;
std::unique_ptr<Menu> m_inkPopupMenu;
std::unique_ptr<Menu> m_newFramePopupMenu;
obs::scoped_connection m_recentFilesConn;
std::vector<Menu*> m_menus;
// List of recent menu items pointing to recent files.
WidgetsList m_recentMenuItems;
// Extension points for plugins (each group is a place where new
// menu items can be added).
std::map<std::string, GroupInfo> m_groups;
// Native main menu bar (== nullptr if the platform doesn't
// support native menus)
os::MenuRef m_osMenu;
XmlTranslator m_xmlTranslator;
};
os::Shortcut get_os_shortcut_from_key(const Key* key);
} // namespace app

View File

@ -9,13 +9,13 @@
#pragma once
namespace app {
class MainWindow;
class MainWindow;
class AppMod {
public:
virtual ~AppMod() { }
virtual void modMainWindow(MainWindow* mainWindow) = 0;
};
class AppMod {
public:
virtual ~AppMod() {}
virtual void modMainWindow(MainWindow* mainWindow) = 0;
};
} // namespace app

View File

@ -19,17 +19,17 @@ namespace app {
class BrushSlot {
public:
enum class Flags {
Locked = 0x0001,
BrushType = 0x0002,
BrushSize = 0x0004,
BrushAngle = 0x0008,
FgColor = 0x0010,
BgColor = 0x0020,
InkType = 0x0040,
InkOpacity = 0x0080,
Shade = 0x0100,
Locked = 0x0001,
BrushType = 0x0002,
BrushSize = 0x0004,
BrushAngle = 0x0008,
FgColor = 0x0010,
BgColor = 0x0020,
InkType = 0x0040,
InkOpacity = 0x0080,
Shade = 0x0100,
PixelPerfect = 0x0200,
ImageColor = 0x0400,
ImageColor = 0x0400,
};
BrushSlot(Flags flags = Flags(0),
@ -47,26 +47,21 @@ public:
, m_inkType(inkType)
, m_inkOpacity(inkOpacity)
, m_shade(shade)
, m_pixelPerfect(pixelPerfect) {
, m_pixelPerfect(pixelPerfect)
{
}
Flags flags() const { return m_flags; }
void setFlags(Flags flags) { m_flags = flags; }
bool isEmpty() const {
return int(m_flags) == 0;
}
bool isEmpty() const { return int(m_flags) == 0; }
bool hasFlag(Flags flag) const {
return ((int(m_flags) & int(flag)) == int(flag));
}
bool hasFlag(Flags flag) const { return ((int(m_flags) & int(flag)) == int(flag)); }
bool hasBrush() const {
return
(brush() &&
(hasFlag(Flags::BrushType) ||
hasFlag(Flags::BrushSize) ||
hasFlag(Flags::BrushAngle)));
bool hasBrush() const
{
return (brush() &&
(hasFlag(Flags::BrushType) || hasFlag(Flags::BrushSize) || hasFlag(Flags::BrushAngle)));
}
// Can be null if the user deletes the brush.
@ -80,11 +75,10 @@ public:
// True if the user locked the brush using the shortcut key to
// access it.
bool locked() const {
return hasFlag(Flags::Locked);
}
bool locked() const { return hasFlag(Flags::Locked); }
void setLocked(bool locked) {
void setLocked(bool locked)
{
if (locked)
m_flags = static_cast<Flags>(int(m_flags) | int(Flags::Locked));
else

View File

@ -6,28 +6,28 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#ifdef ENABLE_UPDATER
#include "app/check_update.h"
#include "app/check_update.h"
#include "app/check_update_delegate.h"
#include "app/pref/preferences.h"
#include "base/convert_to.h"
#include "base/launcher.h"
#include "base/replace_string.h"
#include "base/thread.h"
#include "base/version.h"
#include "ver/info.h"
#include "app/check_update_delegate.h"
#include "app/pref/preferences.h"
#include "base/convert_to.h"
#include "base/launcher.h"
#include "base/replace_string.h"
#include "base/thread.h"
#include "base/version.h"
#include "ver/info.h"
#if ENABLE_SENTRY
#include "app/sentry_wrapper.h"
#endif
#if ENABLE_SENTRY
#include "app/sentry_wrapper.h"
#endif
#include <ctime>
#include <sstream>
#include <ctime>
#include <sstream>
static const int kMonitoringPeriod = 100;
@ -35,27 +35,22 @@ namespace app {
class CheckUpdateBackgroundJob : public updater::CheckUpdateDelegate {
public:
CheckUpdateBackgroundJob()
: m_received(false) { }
CheckUpdateBackgroundJob() : m_received(false) {}
void abort() {
m_checker.abort();
}
void abort() { m_checker.abort(); }
bool isReceived() const {
return m_received;
}
bool isReceived() const { return m_received; }
void sendRequest(const updater::Uuid& uuid, const std::string& extraParams) {
void sendRequest(const updater::Uuid& uuid, const std::string& extraParams)
{
m_checker.checkNewVersion(uuid, extraParams, this);
}
const updater::CheckUpdateResponse& getResponse() const {
return m_response;
}
const updater::CheckUpdateResponse& getResponse() const { return m_response; }
private:
void onResponse(updater::CheckUpdateResponse& data) override {
void onResponse(updater::CheckUpdateResponse& data) override
{
m_response = data;
m_received = true;
}
@ -72,11 +67,11 @@ CheckUpdateThreadLauncher::CheckUpdateThreadLauncher(CheckUpdateDelegate* delega
, m_received(false)
, m_inits(m_preferences.updater.inits())
, m_exits(m_preferences.updater.exits())
#ifdef _DEBUG
#ifdef _DEBUG
, m_isDeveloper(true)
#else
#else
, m_isDeveloper(m_preferences.updater.isDeveloper())
#endif
#endif
, m_timer(kMonitoringPeriod, NULL)
{
// Get how many days we have to wait for the next "check for update"
@ -87,15 +82,16 @@ CheckUpdateThreadLauncher::CheckUpdateThreadLauncher(CheckUpdateDelegate* delega
time_t now = std::time(NULL);
// Verify if we are in the "WaitDays" period...
if (now < lastCheck+int(double(60*60*24*waitDays)) &&
now > lastCheck) { // <- Avoid broken clocks
if (now < lastCheck + int(double(60 * 60 * 24 * waitDays)) && now > lastCheck) { // <- Avoid
// broken
// clocks
// So we do not check for updates.
m_doCheck = false;
}
}
// Minimal stats: number of initializations
m_preferences.updater.inits(m_inits+1);
m_preferences.updater.inits(m_inits + 1);
m_preferences.save();
}
@ -112,7 +108,7 @@ CheckUpdateThreadLauncher::~CheckUpdateThreadLauncher()
}
// Minimal stats: number of exits
m_preferences.updater.exits(m_exits+1);
m_preferences.updater.exits(m_exits + 1);
m_preferences.save();
}
@ -122,9 +118,9 @@ void CheckUpdateThreadLauncher::launch()
m_uuid = m_preferences.updater.uuid();
if (!m_uuid.empty()) {
#if ENABLE_SENTRY
#if ENABLE_SENTRY
Sentry::setUserID(m_uuid);
#endif
#endif
LOG(VERBOSE, "APP: Saved UUID %s\n", m_uuid.c_str());
}
@ -138,7 +134,7 @@ void CheckUpdateThreadLauncher::launch()
m_delegate->onCheckingUpdates();
m_bgJob.reset(new CheckUpdateBackgroundJob);
m_thread.reset(new std::thread([this]{ checkForUpdates(); }));
m_thread.reset(new std::thread([this] { checkForUpdates(); }));
// Start a timer to monitoring the progress of the background job
// executed in "m_thread". The "onMonitoringTick" method will be
@ -156,11 +152,10 @@ void CheckUpdateThreadLauncher::onMonitoringTick()
{
// If we do not receive a response yet...
if (!m_received)
return; // Skip and wait the next call.
return; // Skip and wait the next call.
// Depending on the type of update received
switch (m_response.getUpdateType()) {
case updater::CheckUpdateResponse::NoUpdate:
// Clear
m_preferences.updater.newVersion("");
@ -182,9 +177,9 @@ void CheckUpdateThreadLauncher::onMonitoringTick()
m_preferences.updater.uuid(m_uuid);
if (!m_uuid.empty()) {
#if ENABLE_SENTRY
#if ENABLE_SENTRY
Sentry::setUserID(m_uuid);
#endif
#endif
LOG(VERBOSE, "APP: New UUID %s\n", m_uuid.c_str());
}
}
@ -207,8 +202,7 @@ void CheckUpdateThreadLauncher::checkForUpdates()
// Add mini-stats in the request
std::stringstream extraParams;
extraParams << "inits=" << m_inits
<< "&exits=" << m_exits;
extraParams << "inits=" << m_inits << "&exits=" << m_exits;
if (m_isDeveloper)
extraParams << "&dev=1";
@ -235,8 +229,7 @@ void CheckUpdateThreadLauncher::showUI()
}
if (newVer) {
m_delegate->onNewUpdate(m_preferences.updater.newUrl(),
m_preferences.updater.newVersion());
m_delegate->onNewUpdate(m_preferences.updater.newUrl(), m_preferences.updater.newVersion());
}
else {
// If the program was updated, reset the "exits" counter
@ -249,6 +242,6 @@ void CheckUpdateThreadLauncher::showUI()
}
}
}
} // namespace app
#endif // ENABLE_UPDATER

View File

@ -11,56 +11,53 @@
#ifdef ENABLE_UPDATER
#include "ui/timer.h"
#include "updater/check_update.h"
#include "ui/timer.h"
#include "updater/check_update.h"
#include <atomic>
#include <memory>
#include <thread>
#include <atomic>
#include <memory>
#include <thread>
namespace app {
class CheckUpdateDelegate;
class CheckUpdateBackgroundJob;
class Preferences;
class CheckUpdateDelegate;
class CheckUpdateBackgroundJob;
class Preferences;
class CheckUpdateThreadLauncher {
public:
CheckUpdateThreadLauncher(CheckUpdateDelegate* delegate);
~CheckUpdateThreadLauncher();
class CheckUpdateThreadLauncher {
public:
CheckUpdateThreadLauncher(CheckUpdateDelegate* delegate);
~CheckUpdateThreadLauncher();
void launch();
void launch();
bool isReceived() const;
bool isReceived() const;
const updater::CheckUpdateResponse& getResponse() const
{
return m_response;
}
const updater::CheckUpdateResponse& getResponse() const { return m_response; }
private:
void onMonitoringTick();
void checkForUpdates();
void showUI();
private:
void onMonitoringTick();
void checkForUpdates();
void showUI();
CheckUpdateDelegate* m_delegate;
Preferences& m_preferences;
updater::Uuid m_uuid;
std::unique_ptr<std::thread> m_thread;
std::unique_ptr<CheckUpdateBackgroundJob> m_bgJob;
bool m_doCheck;
std::atomic<bool> m_received;
CheckUpdateDelegate* m_delegate;
Preferences& m_preferences;
updater::Uuid m_uuid;
std::unique_ptr<std::thread> m_thread;
std::unique_ptr<CheckUpdateBackgroundJob> m_bgJob;
bool m_doCheck;
std::atomic<bool> m_received;
// Mini-stats
int m_inits;
int m_exits;
// Mini-stats
int m_inits;
int m_exits;
// True if this is a developer
bool m_isDeveloper;
// True if this is a developer
bool m_isDeveloper;
updater::CheckUpdateResponse m_response;
ui::Timer m_timer;
};
updater::CheckUpdateResponse m_response;
ui::Timer m_timer;
};
} // namespace app

View File

@ -10,17 +10,17 @@
#ifdef ENABLE_UPDATER
#include <string>
#include <string>
namespace app {
class CheckUpdateDelegate {
public:
virtual ~CheckUpdateDelegate() { }
virtual void onCheckingUpdates() = 0;
virtual void onUpToDate() = 0;
virtual void onNewUpdate(const std::string& url, const std::string& version) = 0;
};
class CheckUpdateDelegate {
public:
virtual ~CheckUpdateDelegate() {}
virtual void onCheckingUpdates() = 0;
virtual void onUpToDate() = 0;
virtual void onNewUpdate(const std::string& url, const std::string& version) = 0;
};
} // namespace app

View File

@ -6,7 +6,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cli/app_options.h"
@ -29,60 +29,145 @@ AppOptions::AppOptions(int argc, const char* argv[])
, m_shell(m_po.add("shell").description("Start an interactive console to execute scripts"))
#endif
, m_batch(m_po.add("batch").mnemonic('b').description("Do not start the UI"))
, m_preview(m_po.add("preview").mnemonic('p').description("Do not execute actions, just print what will be\ndone"))
, m_saveAs(m_po.add("save-as").requiresValue("<filename>").description("Save the last given sprite with other format"))
, m_palette(m_po.add("palette").requiresValue("<filename>").description("Change the palette of the last given sprite"))
, m_scale(m_po.add("scale").requiresValue("<factor>").description("Resize all previously opened sprites"))
, m_ditheringAlgorithm(m_po.add("dithering-algorithm").requiresValue("<algorithm>").description("Dithering algorithm used in --color-mode\nto convert images from RGB to Indexed\n none\n ordered\n old"))
, m_ditheringMatrix(m_po.add("dithering-matrix").requiresValue("<id>").description("Matrix used in ordered dithering algorithm\n bayer2x2\n bayer4x4\n bayer8x8\n filename.png"))
, m_colorMode(m_po.add("color-mode").requiresValue("<mode>").description("Change color mode of all previously\nopened sprites:\n rgb\n grayscale\n indexed"))
, m_shrinkTo(m_po.add("shrink-to").requiresValue("width,height").description("Shrink each sprite if it is\nlarger than width or height"))
, m_data(m_po.add("data").requiresValue("<filename.json>").description("File to store the sprite sheet metadata"))
, m_format(m_po.add("format").requiresValue("<format>").description("Format to export the data file\n(json-hash, json-array)"))
, m_sheet(m_po.add("sheet").requiresValue("<filename.png>").description("Image file to save the texture"))
, m_sheetType(m_po.add("sheet-type").requiresValue("<type>").description("Algorithm to create the sprite sheet:\n horizontal\n vertical\n rows\n columns\n packed"))
, m_preview(m_po.add("preview").mnemonic('p').description(
"Do not execute actions, just print what will be\ndone"))
, m_saveAs(m_po.add("save-as")
.requiresValue("<filename>")
.description("Save the last given sprite with other format"))
, m_palette(m_po.add("palette")
.requiresValue("<filename>")
.description("Change the palette of the last given sprite"))
, m_scale(m_po.add("scale")
.requiresValue("<factor>")
.description("Resize all previously opened sprites"))
, m_ditheringAlgorithm(
m_po.add("dithering-algorithm")
.requiresValue("<algorithm>")
.description(
"Dithering algorithm used in --color-mode\nto convert images from RGB to Indexed\n none\n ordered\n old"))
, m_ditheringMatrix(
m_po.add("dithering-matrix")
.requiresValue("<id>")
.description(
"Matrix used in ordered dithering algorithm\n bayer2x2\n bayer4x4\n bayer8x8\n filename.png"))
, m_colorMode(
m_po.add("color-mode")
.requiresValue("<mode>")
.description(
"Change color mode of all previously\nopened sprites:\n rgb\n grayscale\n indexed"))
, m_shrinkTo(m_po.add("shrink-to")
.requiresValue("width,height")
.description("Shrink each sprite if it is\nlarger than width or height"))
, m_data(m_po.add("data")
.requiresValue("<filename.json>")
.description("File to store the sprite sheet metadata"))
, m_format(m_po.add("format")
.requiresValue("<format>")
.description("Format to export the data file\n(json-hash, json-array)"))
, m_sheet(m_po.add("sheet")
.requiresValue("<filename.png>")
.description("Image file to save the texture"))
, m_sheetType(
m_po.add("sheet-type")
.requiresValue("<type>")
.description(
"Algorithm to create the sprite sheet:\n horizontal\n vertical\n rows\n columns\n packed"))
, m_sheetPack(m_po.add("sheet-pack").description("Same as -sheet-type packed"))
, m_sheetWidth(m_po.add("sheet-width").requiresValue("<pixels>").description("Sprite sheet width"))
, m_sheetHeight(m_po.add("sheet-height").requiresValue("<pixels>").description("Sprite sheet height"))
, m_sheetColumns(m_po.add("sheet-columns").requiresValue("<columns>").description("Fixed # of columns for -sheet-type rows"))
, m_sheetRows(m_po.add("sheet-rows").requiresValue("<rows>").description("Fixed # of rows for -sheet-type columns"))
, m_splitLayers(m_po.add("split-layers").description("Save each visible layer of sprites\nas separated images in the sheet\n"))
, m_sheetWidth(
m_po.add("sheet-width").requiresValue("<pixels>").description("Sprite sheet width"))
, m_sheetHeight(
m_po.add("sheet-height").requiresValue("<pixels>").description("Sprite sheet height"))
, m_sheetColumns(m_po.add("sheet-columns")
.requiresValue("<columns>")
.description("Fixed # of columns for -sheet-type rows"))
, m_sheetRows(m_po.add("sheet-rows")
.requiresValue("<rows>")
.description("Fixed # of rows for -sheet-type columns"))
, m_splitLayers(
m_po.add("split-layers")
.description("Save each visible layer of sprites\nas separated images in the sheet\n"))
, m_splitTags(m_po.add("split-tags").description("Save each tag as a separated file"))
, m_splitSlices(m_po.add("split-slices").description("Save each slice as a separated file"))
, m_splitGrid(m_po.add("split-grid").description("Save each grid tile as a separated file"))
, m_layer(m_po.add("layer").alias("import-layer").requiresValue("<name>").description("Include just the given layer in the sheet\nor save as operation"))
, m_allLayers(m_po.add("all-layers").description("Make all layers visible\nBy default hidden layers will be ignored"))
, m_ignoreLayer(m_po.add("ignore-layer").requiresValue("<name>").description("Exclude the given layer in the sheet\nor save as operation"))
, m_tag(m_po.add("tag").alias("frame-tag").requiresValue("<name>").description("Include tagged frames in the sheet"))
, m_playSubtags(m_po.add("play-subtags").description("Play subtags and repeats when saving the frames of an animated sprite"))
, m_frameRange(m_po.add("frame-range").requiresValue("from,to").description("Only export frames in the [from,to] range"))
, m_layer(m_po.add("layer")
.alias("import-layer")
.requiresValue("<name>")
.description("Include just the given layer in the sheet\nor save as operation"))
, m_allLayers(m_po.add("all-layers")
.description("Make all layers visible\nBy default hidden layers will be ignored"))
, m_ignoreLayer(m_po.add("ignore-layer")
.requiresValue("<name>")
.description("Exclude the given layer in the sheet\nor save as operation"))
, m_tag(m_po.add("tag")
.alias("frame-tag")
.requiresValue("<name>")
.description("Include tagged frames in the sheet"))
, m_playSubtags(
m_po.add("play-subtags")
.description("Play subtags and repeats when saving the frames of an animated sprite"))
, m_frameRange(m_po.add("frame-range")
.requiresValue("from,to")
.description("Only export frames in the [from,to] range"))
, m_ignoreEmpty(m_po.add("ignore-empty").description("Do not export empty frames/cels"))
, m_mergeDuplicates(m_po.add("merge-duplicates").description("Merge all duplicate frames into one in the sprite sheet"))
, m_borderPadding(m_po.add("border-padding").requiresValue("<value>").description("Add padding on the texture borders"))
, m_shapePadding(m_po.add("shape-padding").requiresValue("<value>").description("Add padding between frames"))
, m_innerPadding(m_po.add("inner-padding").requiresValue("<value>").description("Add padding inside each frame"))
, m_trim(m_po.add("trim").description("Trim whole sprite for --save-as\nor individual frames for --sheet"))
, m_trimSprite(m_po.add("trim-sprite").description("Trim the whole sprite (for --save-as and --sheet)"))
, m_trimByGrid(m_po.add("trim-by-grid").description("Trim all images by its correspondent grid boundaries before exporting"))
, m_mergeDuplicates(m_po.add("merge-duplicates")
.description("Merge all duplicate frames into one in the sprite sheet"))
, m_borderPadding(m_po.add("border-padding")
.requiresValue("<value>")
.description("Add padding on the texture borders"))
, m_shapePadding(
m_po.add("shape-padding").requiresValue("<value>").description("Add padding between frames"))
, m_innerPadding(m_po.add("inner-padding")
.requiresValue("<value>")
.description("Add padding inside each frame"))
, m_trim(m_po.add("trim").description(
"Trim whole sprite for --save-as\nor individual frames for --sheet"))
, m_trimSprite(
m_po.add("trim-sprite").description("Trim the whole sprite (for --save-as and --sheet)"))
, m_trimByGrid(
m_po.add("trim-by-grid")
.description("Trim all images by its correspondent grid boundaries before exporting"))
, m_extrude(m_po.add("extrude").description("Extrude all images duplicating all edges one pixel"))
, m_crop(m_po.add("crop").requiresValue("x,y,width,height").description("Crop all the images to the given rectangle"))
, m_slice(m_po.add("slice").requiresValue("<name>").description("Crop the sprite to the given slice area"))
, m_filenameFormat(m_po.add("filename-format").requiresValue("<fmt>").description("Special format to generate filenames"))
, m_tagnameFormat(m_po.add("tagname-format").requiresValue("<fmt>").description("Special format to generate tagnames in JSON data"))
, m_crop(m_po.add("crop")
.requiresValue("x,y,width,height")
.description("Crop all the images to the given rectangle"))
, m_slice(m_po.add("slice").requiresValue("<name>").description(
"Crop the sprite to the given slice area"))
, m_filenameFormat(m_po.add("filename-format")
.requiresValue("<fmt>")
.description("Special format to generate filenames"))
, m_tagnameFormat(m_po.add("tagname-format")
.requiresValue("<fmt>")
.description("Special format to generate tagnames in JSON data"))
#ifdef ENABLE_SCRIPTING
, m_script(m_po.add("script").requiresValue("<filename>").description("Execute a specific script"))
, m_scriptParam(m_po.add("script-param").requiresValue("name=value").description("Parameter for a script executed from the\nCLI that you can access with app.params"))
, m_script(
m_po.add("script").requiresValue("<filename>").description("Execute a specific script"))
, m_scriptParam(
m_po.add("script-param")
.requiresValue("name=value")
.description(
"Parameter for a script executed from the\nCLI that you can access with app.params"))
#endif
, m_listLayers(m_po.add("list-layers").description("List layers of the next given sprite\nor include layers in JSON data"))
, m_listLayerHierarchy(m_po.add("list-layer-hierarchy").description("List layers with groups of the next given sprite\nor include layers hierarchy in JSON data"))
, m_listTags(m_po.add("list-tags").description("List tags of the next given sprite\nor include frame tags in JSON data"))
, m_listSlices(m_po.add("list-slices").description("List slices of the next given sprite\nor include slices in JSON data"))
, m_listLayers(
m_po.add("list-layers")
.description("List layers of the next given sprite\nor include layers in JSON data"))
, m_listLayerHierarchy(
m_po.add("list-layer-hierarchy")
.description(
"List layers with groups of the next given sprite\nor include layers hierarchy in JSON data"))
, m_listTags(
m_po.add("list-tags")
.description("List tags of the next given sprite\nor include frame tags in JSON data"))
, m_listSlices(
m_po.add("list-slices")
.description("List slices of the next given sprite\nor include slices in JSON data"))
, m_oneFrame(m_po.add("oneframe").description("Load just the first frame"))
, m_exportTileset(m_po.add("export-tileset").description("Export only tilesets from visible tilemap layers"))
, m_exportTileset(
m_po.add("export-tileset").description("Export only tilesets from visible tilemap layers"))
, m_verbose(m_po.add("verbose").mnemonic('v').description("Explain what is being done"))
, m_debug(m_po.add("debug").description("Extreme verbose mode and\ncopy log to desktop"))
#ifdef ENABLE_STEAM
, m_noInApp(m_po.add("noinapp").description("Disable \"in game\" visibility on Steam\nDoesn't count playtime"))
, m_noInApp(m_po.add("noinapp").description(
"Disable \"in game\" visibility on Steam\nDoesn't count playtime"))
#endif
#ifdef _WIN32
, m_disableWintab(m_po.add("disable-wintab").description("Don't load wintab32.dll library"))
@ -105,10 +190,7 @@ AppOptions::AppOptions(int argc, const char* argv[])
m_showHelp = m_po.enabled(m_help);
m_showVersion = m_po.enabled(m_version);
if (m_startShell ||
m_showHelp ||
m_showVersion ||
m_po.enabled(m_batch)) {
if (m_startShell || m_showHelp || m_showVersion || m_po.enabled(m_batch)) {
m_startUI = false;
}
}
@ -121,9 +203,7 @@ AppOptions::AppOptions(int argc, const char* argv[])
bool AppOptions::hasExporterParams() const
{
return
m_po.enabled(m_data) ||
m_po.enabled(m_sheet);
return m_po.enabled(m_data) || m_po.enabled(m_sheet);
}
#ifdef ENABLE_STEAM
@ -140,4 +220,4 @@ bool AppOptions::disableWintab() const
}
#endif
}
} // namespace app

View File

@ -21,8 +21,8 @@ class AppOptions {
public:
enum VerboseLevel {
kNoVerbose,
kVerbose, // --verbose
kHighlyVerbose, // --debug
kVerbose, // --verbose
kHighlyVerbose, // --debug
};
typedef base::ProgramOptions PO;
@ -41,9 +41,7 @@ public:
bool showVersion() const { return m_showVersion; }
VerboseLevel verboseLevel() const { return m_verboseLevel; }
const ValueList& values() const {
return m_po.values();
}
const ValueList& values() const { return m_po.values(); }
// Export options
const Option& saveAs() const { return m_saveAs; }
@ -181,7 +179,6 @@ private:
#endif
Option& m_help;
Option& m_version;
};
} // namespace app

View File

@ -13,32 +13,29 @@
namespace app {
class AppOptions;
class Context;
class DocExporter;
class Params;
struct CliOpenFile;
class AppOptions;
class Context;
class DocExporter;
class Params;
struct CliOpenFile;
class CliDelegate {
public:
virtual ~CliDelegate() { }
virtual void showHelp(const AppOptions& options) { }
virtual void showVersion() { }
virtual void uiMode() { }
virtual void shellMode() { }
virtual void batchMode() { }
virtual void beforeOpenFile(const CliOpenFile& cof) { }
virtual void afterOpenFile(const CliOpenFile& cof) { }
virtual void saveFile(Context* ctx, const CliOpenFile& cof) { }
virtual void loadPalette(Context* ctx, const std::string& filename) { }
virtual void exportFiles(Context* ctx, DocExporter& exporter) { }
class CliDelegate {
public:
virtual ~CliDelegate() {}
virtual void showHelp(const AppOptions& options) {}
virtual void showVersion() {}
virtual void uiMode() {}
virtual void shellMode() {}
virtual void batchMode() {}
virtual void beforeOpenFile(const CliOpenFile& cof) {}
virtual void afterOpenFile(const CliOpenFile& cof) {}
virtual void saveFile(Context* ctx, const CliOpenFile& cof) {}
virtual void loadPalette(Context* ctx, const std::string& filename) {}
virtual void exportFiles(Context* ctx, DocExporter& exporter) {}
#ifdef ENABLE_SCRIPTING
virtual int execScript(const std::string& filename,
const Params& params) {
return 0;
}
virtual int execScript(const std::string& filename, const Params& params) { return 0; }
#endif // ENABLE_SCRIPTING
};
};
} // namespace app

View File

@ -6,7 +6,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cli/cli_open_file.h"

View File

@ -17,56 +17,47 @@
namespace app {
class Doc;
class FileOpROI;
class Doc;
class FileOpROI;
struct CliOpenFile {
Doc* document = nullptr;
std::string filename;
std::string filenameFormat;
std::string tagnameFormat;
std::string tag;
std::string slice;
std::vector<std::string> includeLayers;
std::vector<std::string> excludeLayers;
doc::frame_t fromFrame = -1;
doc::frame_t toFrame = -1;
bool splitLayers = false;
bool splitTags = false;
bool splitSlices = false;
bool splitGrid = false;
bool allLayers = false;
bool listLayers = false;
bool listLayerHierarchy = false;
bool listTags = false;
bool listSlices = false;
bool ignoreEmpty = false;
bool trim = false;
bool trimByGrid = false;
bool oneFrame = false;
bool exportTileset = false;
bool playSubtags = false;
gfx::Rect crop;
struct CliOpenFile {
Doc* document = nullptr;
std::string filename;
std::string filenameFormat;
std::string tagnameFormat;
std::string tag;
std::string slice;
std::vector<std::string> includeLayers;
std::vector<std::string> excludeLayers;
doc::frame_t fromFrame = -1;
doc::frame_t toFrame = -1;
bool splitLayers = false;
bool splitTags = false;
bool splitSlices = false;
bool splitGrid = false;
bool allLayers = false;
bool listLayers = false;
bool listLayerHierarchy = false;
bool listTags = false;
bool listSlices = false;
bool ignoreEmpty = false;
bool trim = false;
bool trimByGrid = false;
bool oneFrame = false;
bool exportTileset = false;
bool playSubtags = false;
gfx::Rect crop;
bool hasTag() const {
return (!tag.empty());
}
bool hasTag() const { return (!tag.empty()); }
bool hasSlice() const {
return (!slice.empty());
}
bool hasSlice() const { return (!slice.empty()); }
bool hasFrameRange() const {
return (fromFrame >= 0 && toFrame >= 0);
}
bool hasFrameRange() const { return (fromFrame >= 0 && toFrame >= 0); }
bool hasLayersFilter() const {
return (!includeLayers.empty() ||
!excludeLayers.empty());
}
bool hasLayersFilter() const { return (!includeLayers.empty() || !excludeLayers.empty()); }
FileOpROI roi() const;
};
FileOpROI roi() const;
};
} // namespace app

View File

@ -6,7 +6,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cli/cli_processor.h"
@ -44,9 +44,7 @@ namespace app {
namespace {
bool match_path(const std::string& filter,
const std::string& layer_path,
const bool exclude)
bool match_path(const std::string& filter, const std::string& layer_path, const bool exclude)
{
if (filter == layer_path)
return true;
@ -55,21 +53,18 @@ bool match_path(const std::string& filter,
base::split_string(filter, a, "/");
base::split_string(layer_path, b, "/");
for (std::size_t i=0; i<a.size() && i<b.size(); ++i) {
for (std::size_t i = 0; i < a.size() && i < b.size(); ++i) {
if (a[i] != b[i] && a[i] != "*")
return false;
}
const bool wildcard = (!a.empty() && a[a.size()-1] == "*");
const bool wildcard = (!a.empty() && a[a.size() - 1] == "*");
// Exclude group itself when all children are excluded. This special
// case is only for exclusion because if we leave the group
// selected, the propagation of the selection will include all
// visible children too (see SelectedLayers::propagateSelection()).
if (exclude &&
a.size() > 1 &&
a.size() == b.size()+1 &&
wildcard) {
if (exclude && a.size() > 1 && a.size() == b.size() + 1 && wildcard) {
return true;
}
@ -95,9 +90,8 @@ bool filter_layer(const std::string& layer_path,
// If there is one layer with the given name "filter", we can convert
// the filter to a full path to the layer (e.g. to match child layers
// of a group).
std::string convert_filter_to_layer_path_if_possible(
const Sprite* sprite,
const std::string& filter)
std::string convert_filter_to_layer_path_if_possible(const Sprite* sprite,
const std::string& filter)
{
std::string fullName;
std::queue<Layer*> layers;
@ -107,8 +101,7 @@ std::string convert_filter_to_layer_path_if_possible(
const Layer* layer = layers.front();
layers.pop();
if (layer != sprite->root() &&
layer->name() == filter) {
if (layer != sprite->root() && layer->name() == filter) {
if (fullName.empty()) {
fullName = get_layer_path(layer);
}
@ -152,16 +145,14 @@ void CliProcessor::FilterLayers(const Sprite* sprite,
(!includes.empty() && !filter_layer(layer_path, includes, true)))
continue;
if (!excludes.empty() &&
!filter_layer(layer_path, excludes, false))
if (!excludes.empty() && !filter_layer(layer_path, excludes, false))
continue;
filteredLayers.insert(layer);
}
}
CliProcessor::CliProcessor(CliDelegate* delegate,
const AppOptions& options)
CliProcessor::CliProcessor(CliDelegate* delegate, const AppOptions& options)
: m_delegate(delegate)
, m_options(options)
, m_exporter(nullptr)
@ -307,7 +298,7 @@ int CliProcessor::process(Context* ctx)
"E.g. --frame-range 0,99");
cof.fromFrame = base::convert_to<frame_t>(splitRange[0]);
cof.toFrame = base::convert_to<frame_t>(splitRange[1]);
cof.toFrame = base::convert_to<frame_t>(splitRange[1]);
}
// --ignore-empty
else if (opt == &m_options.ignoreEmpty()) {
@ -403,7 +394,7 @@ int CliProcessor::process(Context* ctx)
// in case the output filename already contains {layer},
// {tag}, or {slice} template elements.
bool hasLayerTemplate = (is_layer_in_filename_format(fn) ||
is_group_in_filename_format(fn));
is_group_in_filename_format(fn));
bool hasTagTemplate = is_tag_in_filename_format(fn);
bool hasSliceTemplate = is_slice_in_filename_format(fn);
@ -451,8 +442,7 @@ int CliProcessor::process(Context* ctx)
// Scale all sprites
for (auto doc : ctx->documents()) {
ctx->setActiveDocument(doc);
ctx->executeCommand(Commands::instance()->byId(CommandId::SpriteSize()),
params);
ctx->executeCommand(Commands::instance()->byId(CommandId::SpriteSize()), params);
}
}
// --dithering-algorithm <algorithm>
@ -466,9 +456,10 @@ int CliProcessor::process(Context* ctx)
else if (value.value() == "error-diffusion")
ditheringAlgorithm = render::DitheringAlgorithm::ErrorDiffusion;
else
throw std::runtime_error("--dithering-algorithm needs a valid algorithm name\n"
"Usage: --dithering-algorithm <algorithm>\n"
"Where <algorithm> can be none, ordered, old, or error-diffusion");
throw std::runtime_error(
"--dithering-algorithm needs a valid algorithm name\n"
"Usage: --dithering-algorithm <algorithm>\n"
"Where <algorithm> can be none, ordered, old, or error-diffusion");
}
// --dithering-matrix <id>
else if (opt == &m_options.ditheringMatrix()) {
@ -487,15 +478,9 @@ int CliProcessor::process(Context* ctx)
else if (value.value() == "indexed") {
params.set("format", "indexed");
switch (ditheringAlgorithm) {
case render::DitheringAlgorithm::None:
params.set("dithering", "none");
break;
case render::DitheringAlgorithm::Ordered:
params.set("dithering", "ordered");
break;
case render::DitheringAlgorithm::Old:
params.set("dithering", "old");
break;
case render::DitheringAlgorithm::None: params.set("dithering", "none"); break;
case render::DitheringAlgorithm::Ordered: params.set("dithering", "ordered"); break;
case render::DitheringAlgorithm::Old: params.set("dithering", "old"); break;
case render::DitheringAlgorithm::ErrorDiffusion:
params.set("dithering", "error-diffusion");
break;
@ -539,8 +524,7 @@ int CliProcessor::process(Context* ctx)
scale = std::min(scaleWidth, scaleHeight);
Params params;
params.set("scale", base::convert_to<std::string>(scale).c_str());
ctx->executeCommand(Commands::instance()->byId(CommandId::SpriteSize()),
params);
ctx->executeCommand(Commands::instance()->byId(CommandId::SpriteSize()), params);
}
}
}
@ -564,8 +548,7 @@ int CliProcessor::process(Context* ctx)
const std::string& v = value.value();
auto i = v.find('=');
if (i != std::string::npos)
scriptParams.set(v.substr(0, i).c_str(),
v.substr(i+1).c_str());
scriptParams.set(v.substr(0, i).c_str(), v.substr(i + 1).c_str());
else
scriptParams.set(v.c_str(), "1");
}
@ -612,11 +595,11 @@ int CliProcessor::process(Context* ctx)
cof.document = nullptr;
cof.filename = base::normalize_path(value.value());
if (// Check that the filename wasn't used loading a sequence
// of images as one sprite
m_usedFiles.find(cof.filename) == m_usedFiles.end() &&
// Open sprite
openFile(ctx, cof)) {
if ( // Check that the filename wasn't used loading a sequence
// of images as one sprite
m_usedFiles.find(cof.filename) == m_usedFiles.end() &&
// Open sprite
openFile(ctx, cof)) {
lastDoc = cof.document;
}
}
@ -652,9 +635,7 @@ bool CliProcessor::openFile(Context* ctx, CliOpenFile& cof)
Doc* oldDoc = ctx->activeDocument();
m_batch.open(ctx,
cof.filename,
cof.oneFrame);
m_batch.open(ctx, cof.filename, cof.oneFrame);
// Mark used file names as "already processed" so we don't try to
// open then again
@ -691,9 +672,8 @@ bool CliProcessor::openFile(Context* ctx, CliOpenFile& cof)
if (cof.hasFrameRange()) {
// --frame-range with --frame-tag
if (tag) {
selFrames.insert(
tag->fromFrame()+std::clamp(cof.fromFrame, 0, tag->frames()-1),
tag->fromFrame()+std::clamp(cof.toFrame, 0, tag->frames()-1));
selFrames.insert(tag->fromFrame() + std::clamp(cof.fromFrame, 0, tag->frames() - 1),
tag->fromFrame() + std::clamp(cof.toFrame, 0, tag->frames() - 1));
}
// --frame-range without --frame-tag
else {
@ -706,25 +686,23 @@ bool CliProcessor::openFile(Context* ctx, CliOpenFile& cof)
filterLayers(doc->sprite(), cof, filteredLayers);
if (cof.exportTileset) {
m_exporter->addTilesetsSamples(
doc,
(cof.hasLayersFilter() ? &filteredLayers: nullptr));
m_exporter->addTilesetsSamples(doc, (cof.hasLayersFilter() ? &filteredLayers : nullptr));
}
else {
m_exporter->addDocumentSamples(
doc, tag,
cof.splitLayers,
cof.splitTags,
cof.splitGrid,
(cof.hasLayersFilter() ? &filteredLayers: nullptr),
(!selFrames.empty() ? &selFrames: nullptr));
m_exporter->addDocumentSamples(doc,
tag,
cof.splitLayers,
cof.splitTags,
cof.splitGrid,
(cof.hasLayersFilter() ? &filteredLayers : nullptr),
(!selFrames.empty() ? &selFrames : nullptr));
}
}
}
m_delegate->afterOpenFile(cof);
return (doc ? true: false);
return (doc ? true : false);
}
void CliProcessor::saveFile(Context* ctx, const CliOpenFile& cof)
@ -742,21 +720,18 @@ void CliProcessor::saveFile(Context* ctx, const CliOpenFile& cof)
cropParams.set("y", base::convert_to<std::string>(cof.crop.y).c_str());
cropParams.set("width", base::convert_to<std::string>(cof.crop.w).c_str());
cropParams.set("height", base::convert_to<std::string>(cof.crop.h).c_str());
ctx->executeCommand(
Commands::instance()->byId(CommandId::CropSprite()),
cropParams);
ctx->executeCommand(Commands::instance()->byId(CommandId::CropSprite()), cropParams);
}
std::string fn = cof.filename;
std::string filenameFormat = cof.filenameFormat;
if (filenameFormat.empty()) { // Default format
bool hasFrames = (cof.roi().frames() > 1);
filenameFormat = get_default_filename_format(
fn,
true, // With path
hasFrames, // Has frames
cof.splitLayers, // Has layer
cof.splitTags); // Has frame tag
filenameFormat = get_default_filename_format(fn,
true, // With path
hasFrames, // Has frames
cof.splitLayers, // Has layer
cof.splitTags); // Has frame tag
}
SelectedLayers filteredLayers;
@ -777,8 +752,7 @@ void CliProcessor::saveFile(Context* ctx, const CliOpenFile& cof)
std::vector<doc::Tag*> tags;
if (cof.hasTag()) {
tags.push_back(
doc->sprite()->tags().getByName(cof.tag));
tags.push_back(doc->sprite()->tags().getByName(cof.tag));
}
else {
doc::Tags& origTags = cof.document->sprite()->tags();
@ -786,8 +760,7 @@ void CliProcessor::saveFile(Context* ctx, const CliOpenFile& cof)
for (doc::Tag* tag : origTags) {
// In case the tag is outside the given --frame-range
if (cof.hasFrameRange()) {
if (tag->toFrame() < cof.fromFrame ||
tag->fromFrame() > cof.toFrame)
if (tag->toFrame() < cof.fromFrame || tag->fromFrame() > cof.toFrame)
continue;
}
tags.push_back(tag);
@ -799,8 +772,7 @@ void CliProcessor::saveFile(Context* ctx, const CliOpenFile& cof)
std::vector<doc::Slice*> slices;
if (cof.hasSlice()) {
slices.push_back(
doc->sprite()->slices().getByName(cof.slice));
slices.push_back(doc->sprite()->slices().getByName(cof.slice));
}
else {
doc::Slices& origSlices = cof.document->sprite()->slices();
@ -826,7 +798,7 @@ void CliProcessor::saveFile(Context* ctx, const CliOpenFile& cof)
// If the user doesn't want all layers and this one is hidden.
if (!layer->isVisible())
continue; // Just ignore this layer.
continue; // Just ignore this layer.
// Make this layer ("show") the only one visible.
layersVisibility.showLayer(layer);
@ -868,9 +840,7 @@ void CliProcessor::saveFile(Context* ctx, const CliOpenFile& cof)
itemCof.includeLayers.push_back(layer->name());
}
if (tag) {
fnInfo
.innerTagName(tag->name())
.outerTagName(tag->name());
fnInfo.innerTagName(tag->name()).outerTagName(tag->name());
itemCof.tag = tag->name();
}
if (slice) {

View File

@ -21,51 +21,47 @@
#include <vector>
namespace doc {
class Sprite;
class Sprite;
}
namespace app {
class AppOptions;
class Context;
class DocExporter;
class AppOptions;
class Context;
class DocExporter;
class CliProcessor {
public:
CliProcessor(CliDelegate* delegate,
const AppOptions& options);
int process(Context* ctx);
class CliProcessor {
public:
CliProcessor(CliDelegate* delegate, const AppOptions& options);
int process(Context* ctx);
// Public so it can be tested
static void FilterLayers(const doc::Sprite* sprite,
// By value because these vectors will be modified inside
std::vector<std::string> includes,
std::vector<std::string> excludes,
doc::SelectedLayers& filteredLayers);
// Public so it can be tested
static void FilterLayers(const doc::Sprite* sprite,
// By value because these vectors will be modified inside
std::vector<std::string> includes,
std::vector<std::string> excludes,
doc::SelectedLayers& filteredLayers);
private:
bool openFile(Context* ctx, CliOpenFile& cof);
void saveFile(Context* ctx, const CliOpenFile& cof);
private:
bool openFile(Context* ctx, CliOpenFile& cof);
void saveFile(Context* ctx, const CliOpenFile& cof);
void filterLayers(const doc::Sprite* sprite,
const CliOpenFile& cof,
doc::SelectedLayers& filteredLayers) {
CliProcessor::FilterLayers(
sprite,
cof.includeLayers,
cof.excludeLayers,
filteredLayers);
}
void filterLayers(const doc::Sprite* sprite,
const CliOpenFile& cof,
doc::SelectedLayers& filteredLayers)
{
CliProcessor::FilterLayers(sprite, cof.includeLayers, cof.excludeLayers, filteredLayers);
}
CliDelegate* m_delegate;
const AppOptions& m_options;
std::unique_ptr<DocExporter> m_exporter;
CliDelegate* m_delegate;
const AppOptions& m_options;
std::unique_ptr<DocExporter> m_exporter;
// Files already used in the CLI processing (e.g. when used to
// load a sequence of files) so we don't ask for them again.
std::set<std::string> m_usedFiles;
OpenBatchOfFiles m_batch;
};
// Files already used in the CLI processing (e.g. when used to
// load a sequence of files) so we don't ask for them again.
std::set<std::string> m_usedFiles;
OpenBatchOfFiles m_batch;
};
} // namespace app

View File

@ -17,7 +17,8 @@ using namespace app;
class CliTestDelegate : public CliDelegate {
public:
CliTestDelegate() {
CliTestDelegate()
{
m_helpWasShown = false;
m_versionWasShown = false;
m_uiMode = false;
@ -30,15 +31,12 @@ public:
void uiMode() override { m_uiMode = true; }
void shellMode() override { m_shellMode = true; }
void batchMode() override { m_batchMode = true; }
void beforeOpenFile(const CliOpenFile& cof) override { }
void afterOpenFile(const CliOpenFile& cof) override { }
void saveFile(Context* ctx, const CliOpenFile& cof) override { }
void exportFiles(Context* ctx, DocExporter& exporter) override { }
void beforeOpenFile(const CliOpenFile& cof) override {}
void afterOpenFile(const CliOpenFile& cof) override {}
void saveFile(Context* ctx, const CliOpenFile& cof) override {}
void exportFiles(Context* ctx, DocExporter& exporter) override {}
#ifdef ENABLE_SCRIPTING
int execScript(const std::string& filename,
const Params& params) override {
return 0;
}
int execScript(const std::string& filename, const Params& params) override { return 0; }
#endif
bool helpWasShown() const { return m_helpWasShown; }
@ -52,12 +50,13 @@ private:
bool m_batchMode;
};
std::unique_ptr<AppOptions> args(std::initializer_list<const char*> l) {
int argc = l.size()+1;
std::unique_ptr<AppOptions> args(std::initializer_list<const char*> l)
{
int argc = l.size() + 1;
const char** argv = new const char*[argc];
argv[0] = "aseprite.exe";
auto it = l.begin();
for (int i=1; i<argc; ++i, ++it) {
for (int i = 1; i < argc; ++i, ++it) {
argv[i] = *it;
TRACE("argv[%d] = %s\n", i, argv[i]);
}
@ -69,7 +68,7 @@ std::unique_ptr<AppOptions> args(std::initializer_list<const char*> l) {
TEST(Cli, None)
{
CliTestDelegate d;
auto a = args({ });
auto a = args({});
CliProcessor p(&d, *a);
p.process(nullptr);
EXPECT_TRUE(!d.helpWasShown());

View File

@ -6,7 +6,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cli/default_cli_delegate.h"
@ -42,16 +42,12 @@ namespace app {
void DefaultCliDelegate::showHelp(const AppOptions& options)
{
std::cout
<< get_app_name() << " v" << get_app_version()
<< " | A pixel art program\n"
<< get_app_copyright()
<< "\n\nUsage:\n"
<< " " << options.exeName() << " [OPTIONS] [FILES]...\n\n"
<< "Options:\n"
<< options.programOptions()
<< "\nFind more information in " << get_app_name()
<< " web site: " << get_app_url() << "\n\n";
std::cout << get_app_name() << " v" << get_app_version() << " | A pixel art program\n"
<< get_app_copyright() << "\n\nUsage:\n"
<< " " << options.exeName() << " [OPTIONS] [FILES]...\n\n"
<< "Options:\n"
<< options.programOptions() << "\nFind more information in " << get_app_name()
<< " web site: " << get_app_url() << "\n\n";
}
void DefaultCliDelegate::showVersion()
@ -61,7 +57,7 @@ void DefaultCliDelegate::showVersion()
void DefaultCliDelegate::afterOpenFile(const CliOpenFile& cof)
{
if (!cof.document) // Do nothing
if (!cof.document) // Do nothing
return;
if (cof.listLayers) {
@ -111,8 +107,7 @@ void DefaultCliDelegate::saveFile(Context* ctx, const CliOpenFile& cof)
ctx->executeCommand(saveAsCommand, params);
}
void DefaultCliDelegate::loadPalette(Context* ctx,
const std::string& filename)
void DefaultCliDelegate::loadPalette(Context* ctx, const std::string& filename)
{
std::unique_ptr<doc::Palette> palette(load_palette(filename.c_str()));
if (palette) {
@ -123,8 +118,7 @@ void DefaultCliDelegate::loadPalette(Context* ctx,
ctx->executeCommand(loadPalCommand, params);
}
else {
Console().printf("Error loading palette in --palette '%s'\n",
filename.c_str());
Console().printf("Error loading palette in --palette '%s'\n", filename.c_str());
}
}
@ -133,8 +127,7 @@ void DefaultCliDelegate::exportFiles(Context* ctx, DocExporter& exporter)
LOG("APP: Exporting sheet...\n");
base::task_token token;
std::unique_ptr<Doc> spriteSheet(
exporter.exportSheet(ctx, token));
std::unique_ptr<Doc> spriteSheet(exporter.exportSheet(ctx, token));
// Sprite sheet isn't used, we just delete it.
@ -142,8 +135,7 @@ void DefaultCliDelegate::exportFiles(Context* ctx, DocExporter& exporter)
}
#ifdef ENABLE_SCRIPTING
int DefaultCliDelegate::execScript(const std::string& filename,
const Params& params)
int DefaultCliDelegate::execScript(const std::string& filename, const Params& params)
{
ScriptInputChain scriptInputChain;
if (!App::instance()->isGui()) {

View File

@ -13,19 +13,18 @@
namespace app {
class DefaultCliDelegate : public CliDelegate {
public:
void showHelp(const AppOptions& programOptions) override;
void showVersion() override;
void afterOpenFile(const CliOpenFile& cof) override;
void saveFile(Context* ctx, const CliOpenFile& cof) override;
void loadPalette(Context* ctx, const std::string& filename) override;
void exportFiles(Context* ctx, DocExporter& exporter) override;
class DefaultCliDelegate : public CliDelegate {
public:
void showHelp(const AppOptions& programOptions) override;
void showVersion() override;
void afterOpenFile(const CliOpenFile& cof) override;
void saveFile(Context* ctx, const CliOpenFile& cof) override;
void loadPalette(Context* ctx, const std::string& filename) override;
void exportFiles(Context* ctx, DocExporter& exporter) override;
#ifdef ENABLE_SCRIPTING
int execScript(const std::string& filename,
const Params& params) override;
int execScript(const std::string& filename, const Params& params) override;
#endif
};
};
} // namespace app

View File

@ -15,8 +15,7 @@ using namespace doc;
class FilterLayers : public ::testing::Test {
public:
FilterLayers()
: sprite(ImageSpec(ColorMode::RGB, 32, 32))
FilterLayers() : sprite(ImageSpec(ColorMode::RGB, 32, 32))
{
a->setName("a");
b->setName("b");
@ -33,12 +32,9 @@ public:
b->addLayer(bb);
}
void filter(
std::vector<std::string> includes,
std::vector<std::string> excludes)
void filter(std::vector<std::string> includes, std::vector<std::string> excludes)
{
CliProcessor::FilterLayers(
&sprite, std::move(includes), std::move(excludes), sel);
CliProcessor::FilterLayers(&sprite, std::move(includes), std::move(excludes), sel);
}
Sprite sprite;

View File

@ -6,7 +6,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cli/preview_cli_delegate.h"
@ -94,10 +94,7 @@ void PreviewCliDelegate::saveFile(Context* ctx, const CliOpenFile& cof)
<< " - Sprite: '" << cof.document->filename() << "'\n";
if (!cof.crop.isEmpty()) {
std::cout << " - Crop: "
<< cof.crop.x << ","
<< cof.crop.y << " "
<< cof.crop.w << "x"
std::cout << " - Crop: " << cof.crop.x << "," << cof.crop.y << " " << cof.crop.w << "x"
<< cof.crop.h << "\n";
}
@ -112,8 +109,7 @@ void PreviewCliDelegate::saveFile(Context* ctx, const CliOpenFile& cof)
std::cout << " - Ignore empty frames\n";
}
std::cout << " - Size: "
<< cof.document->sprite()->width() << "x"
std::cout << " - Size: " << cof.document->sprite()->width() << "x"
<< cof.document->sprite()->height() << "\n";
showLayersFilter(cof);
@ -136,8 +132,7 @@ void PreviewCliDelegate::saveFile(Context* ctx, const CliOpenFile& cof)
const auto& selFrames = cof.roi().framesSequence();
if (!selFrames.empty()) {
if (selFrames.ranges() == 1)
std::cout << " - Frame range from "
<< selFrames.firstFrame() << " to "
std::cout << " - Frame range from " << selFrames.firstFrame() << " to "
<< selFrames.lastFrame() << "\n";
else {
std::cout << " - Specific frames:";
@ -151,13 +146,11 @@ void PreviewCliDelegate::saveFile(Context* ctx, const CliOpenFile& cof)
if (!cof.filenameFormat.empty())
std::cout << " - Filename format: '" << cof.filenameFormat << "'\n";
std::unique_ptr<FileOp> fop(
FileOp::createSaveDocumentOperation(
ctx,
cof.roi(),
cof.filename,
cof.filenameFormat,
cof.ignoreEmpty));
std::unique_ptr<FileOp> fop(FileOp::createSaveDocumentOperation(ctx,
cof.roi(),
cof.filename,
cof.filenameFormat,
cof.ignoreEmpty));
if (fop) {
base::paths files;
@ -173,8 +166,7 @@ void PreviewCliDelegate::saveFile(Context* ctx, const CliOpenFile& cof)
std::cout << " - No output\n";
}
void PreviewCliDelegate::loadPalette(Context* ctx,
const std::string& filename)
void PreviewCliDelegate::loadPalette(Context* ctx, const std::string& filename)
{
std::cout << "- Load palette:\n"
<< " - Palette: '" << filename << "'\n";
@ -185,10 +177,10 @@ void PreviewCliDelegate::exportFiles(Context* ctx, DocExporter& exporter)
std::string type = "None";
switch (exporter.spriteSheetType()) {
case SpriteSheetType::Horizontal: type = "Horizontal"; break;
case SpriteSheetType::Vertical: type = "Vertical"; break;
case SpriteSheetType::Rows: type = "Rows"; break;
case SpriteSheetType::Columns: type = "Columns"; break;
case SpriteSheetType::Packed: type = "Packed"; break;
case SpriteSheetType::Vertical: type = "Vertical"; break;
case SpriteSheetType::Rows: type = "Rows"; break;
case SpriteSheetType::Columns: type = "Columns"; break;
case SpriteSheetType::Packed: type = "Packed"; break;
}
gfx::Size size = exporter.calculateSheetSize();
@ -197,29 +189,26 @@ void PreviewCliDelegate::exportFiles(Context* ctx, DocExporter& exporter)
<< " - Size: " << size.w << "x" << size.h << "\n";
if (!exporter.textureFilename().empty()) {
std::cout << " - Save texture file: '"
<< exporter.textureFilename() << "'\n";
std::cout << " - Save texture file: '" << exporter.textureFilename() << "'\n";
}
if (!exporter.dataFilename().empty()) {
std::string format = "Unknown";
switch (exporter.dataFormat()) {
case SpriteSheetDataFormat::JsonHash: format = "JSON Hash"; break;
case SpriteSheetDataFormat::JsonHash: format = "JSON Hash"; break;
case SpriteSheetDataFormat::JsonArray: format = "JSON Array"; break;
}
std::cout << " - Save data file: '" << exporter.dataFilename() << "'\n"
<< " - Data format: " << format << "\n";
if (!exporter.filenameFormat().empty()) {
std::cout << " - Filename format for JSON items: '"
<< exporter.filenameFormat() << "'\n";
std::cout << " - Filename format for JSON items: '" << exporter.filenameFormat() << "'\n";
}
}
}
#ifdef ENABLE_SCRIPTING
int PreviewCliDelegate::execScript(const std::string& filename,
const Params& params)
int PreviewCliDelegate::execScript(const std::string& filename, const Params& params)
{
std::cout << "- Run script: '" << filename << "'\n";
if (!params.empty()) {
@ -257,8 +246,7 @@ void PreviewCliDelegate::showLayerVisibility(const doc::LayerGroup* group,
continue;
std::cout << indent << "- " << layer->name() << "\n";
if (layer->isGroup())
showLayerVisibility(static_cast<const LayerGroup*>(layer),
indent + " ");
showLayerVisibility(static_cast<const LayerGroup*>(layer), indent + " ");
}
}

View File

@ -14,33 +14,31 @@
#include <string>
namespace doc {
class LayerGroup;
class LayerGroup;
}
namespace app {
class PreviewCliDelegate : public CliDelegate {
public:
void showHelp(const AppOptions& programOptions) override;
void showVersion() override;
void uiMode() override;
void shellMode() override;
void batchMode() override;
void beforeOpenFile(const CliOpenFile& cof) override;
void afterOpenFile(const CliOpenFile& cof) override;
void saveFile(Context* ctx, const CliOpenFile& cof) override;
void loadPalette(Context* ctx, const std::string& filename) override;
void exportFiles(Context* ctx, DocExporter& exporter) override;
class PreviewCliDelegate : public CliDelegate {
public:
void showHelp(const AppOptions& programOptions) override;
void showVersion() override;
void uiMode() override;
void shellMode() override;
void batchMode() override;
void beforeOpenFile(const CliOpenFile& cof) override;
void afterOpenFile(const CliOpenFile& cof) override;
void saveFile(Context* ctx, const CliOpenFile& cof) override;
void loadPalette(Context* ctx, const std::string& filename) override;
void exportFiles(Context* ctx, DocExporter& exporter) override;
#ifdef ENABLE_SCRIPTING
int execScript(const std::string& filename,
const Params& params) override;
int execScript(const std::string& filename, const Params& params) override;
#endif // ENABLE_SCRIPTING
private:
void showLayersFilter(const CliOpenFile& cof);
void showLayerVisibility(const doc::LayerGroup* group,
const std::string& indent);
};
private:
void showLayersFilter(const CliOpenFile& cof);
void showLayerVisibility(const doc::LayerGroup* group, const std::string& indent);
};
} // namespace app

View File

@ -5,7 +5,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/closed_docs.h"
@ -20,22 +20,23 @@
namespace app {
ClosedDocs::ClosedDocs(const Preferences& pref)
: m_done(false)
ClosedDocs::ClosedDocs(const Preferences& pref) : m_done(false)
{
if (pref.general.dataRecovery())
m_dataRecoveryPeriodMSecs = int(1000.0*60.0*pref.general.dataRecoveryPeriod());
m_dataRecoveryPeriodMSecs = int(1000.0 * 60.0 * pref.general.dataRecoveryPeriod());
else
m_dataRecoveryPeriodMSecs = 0;
if (pref.general.keepClosedSpriteOnMemory())
m_keepClosedDocAliveForMSecs = int(1000.0*60.0*pref.general.keepClosedSpriteOnMemoryFor());
m_keepClosedDocAliveForMSecs = int(1000.0 * 60.0 * pref.general.keepClosedSpriteOnMemoryFor());
else
m_keepClosedDocAliveForMSecs = 0;
CLOSEDOC_TRACE("CLOSEDOC: Init",
"dataRecoveryPeriod", m_dataRecoveryPeriodMSecs,
"keepClosedDocs", m_keepClosedDocAliveForMSecs);
"dataRecoveryPeriod",
m_dataRecoveryPeriodMSecs,
"keepClosedDocs",
m_keepClosedDocAliveForMSecs);
}
ClosedDocs::~ClosedDocs()
@ -62,8 +63,7 @@ bool ClosedDocs::hasClosedDocs()
std::unique_lock<std::mutex> lock(m_mutex);
result = !m_docs.empty();
}
CLOSEDOC_TRACE("CLOSEDOC: Has closed docs?",
(result ? "true": "false"));
CLOSEDOC_TRACE("CLOSEDOC: Has closed docs?", (result ? "true" : "false"));
return result;
}
@ -80,7 +80,7 @@ void ClosedDocs::addClosedDoc(Doc* doc)
m_docs.insert(m_docs.begin(), std::move(closedDoc));
if (!m_thread.joinable())
m_thread = std::thread([this]{ backgroundThread(); });
m_thread = std::thread([this] { backgroundThread(); });
else
m_cv.notify_one();
}
@ -126,18 +126,18 @@ void ClosedDocs::backgroundThread()
base::tick_t now = base::current_tick();
base::tick_t waitForMSecs = std::numeric_limits<base::tick_t>::max();
for (auto it=m_docs.begin(); it != m_docs.end(); ) {
for (auto it = m_docs.begin(); it != m_docs.end();) {
const ClosedDoc& closedDoc = *it;
auto doc = closedDoc.doc;
base::tick_t diff = now - closedDoc.timestamp;
if (diff >= m_keepClosedDocAliveForMSecs) {
if (// If we backup process is disabled
m_dataRecoveryPeriodMSecs == 0 ||
// Or this document doesn't need a backup (e.g. an unmodified document)
!doc->needsBackup() ||
// Or the document already has the backup done
doc->isFullyBackedUp()) {
if ( // If we backup process is disabled
m_dataRecoveryPeriodMSecs == 0 ||
// Or this document doesn't need a backup (e.g. an unmodified document)
!doc->needsBackup() ||
// Or the document already has the backup done
doc->isFullyBackedUp()) {
// Finally delete the document (this is the place where we
// delete all documents created/loaded by the user)
CLOSEDOC_TRACE("CLOSEDOC: [BG] Delete doc", doc);
@ -150,7 +150,7 @@ void ClosedDocs::backgroundThread()
}
}
else {
waitForMSecs = std::min(waitForMSecs, m_keepClosedDocAliveForMSecs-diff);
waitForMSecs = std::min(waitForMSecs, m_keepClosedDocAliveForMSecs - diff);
++it;
}
}

View File

@ -18,47 +18,47 @@
namespace app {
class Doc;
class Preferences;
class Doc;
class Preferences;
// Handle the list of closed docs:
// * When a document is closed, we keep it for some time so the user
// can undo the close command without losing the undo history.
// * For the first closed document, a thread is launched to wait
// until we can definitely delete the doc after X minutes (like a
// garbage collector).
// * If the document was not restore, we delete it from memory, if
// the document was restore, we remove it from the m_docs.
class ClosedDocs {
public:
ClosedDocs(const Preferences& pref);
~ClosedDocs();
// Handle the list of closed docs:
// * When a document is closed, we keep it for some time so the user
// can undo the close command without losing the undo history.
// * For the first closed document, a thread is launched to wait
// until we can definitely delete the doc after X minutes (like a
// garbage collector).
// * If the document was not restore, we delete it from memory, if
// the document was restore, we remove it from the m_docs.
class ClosedDocs {
public:
ClosedDocs(const Preferences& pref);
~ClosedDocs();
bool hasClosedDocs();
void addClosedDoc(Doc* doc);
Doc* reopenLastClosedDoc();
bool hasClosedDocs();
void addClosedDoc(Doc* doc);
Doc* reopenLastClosedDoc();
// Called at the very end to get all closed docs, remove them from
// the list of closed docs, and stop the thread.
std::vector<Doc*> getAndRemoveAllClosedDocs();
// Called at the very end to get all closed docs, remove them from
// the list of closed docs, and stop the thread.
std::vector<Doc*> getAndRemoveAllClosedDocs();
private:
void backgroundThread();
private:
void backgroundThread();
struct ClosedDoc {
Doc* doc;
base::tick_t timestamp;
};
std::atomic<bool> m_done;
base::tick_t m_dataRecoveryPeriodMSecs;
base::tick_t m_keepClosedDocAliveForMSecs;
std::vector<ClosedDoc> m_docs;
std::mutex m_mutex;
std::condition_variable m_cv;
std::thread m_thread;
struct ClosedDoc {
Doc* doc;
base::tick_t timestamp;
};
std::atomic<bool> m_done;
base::tick_t m_dataRecoveryPeriodMSecs;
base::tick_t m_keepClosedDocAliveForMSecs;
std::vector<ClosedDoc> m_docs;
std::mutex m_mutex;
std::condition_variable m_cv;
std::thread m_thread;
};
} // namespace app
#endif

View File

@ -5,7 +5,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd.h"
@ -115,7 +115,8 @@ std::string Cmd::onLabel() const
return "";
}
size_t Cmd::onMemSize() const {
size_t Cmd::onMemSize() const
{
return sizeof(*this);
}

View File

@ -15,42 +15,42 @@
namespace app {
class Context;
class Context;
class Cmd : public undo::UndoCommand {
public:
Cmd();
virtual ~Cmd();
class Cmd : public undo::UndoCommand {
public:
Cmd();
virtual ~Cmd();
void execute(Context* ctx);
void execute(Context* ctx);
// undo::UndoCommand impl
void undo() override;
void redo() override;
void dispose() override;
// undo::UndoCommand impl
void undo() override;
void redo() override;
void dispose() override;
std::string label() const;
size_t memSize() const;
std::string label() const;
size_t memSize() const;
Context* context() const { return m_ctx; }
Context* context() const { return m_ctx; }
protected:
virtual void onExecute();
virtual void onUndo();
virtual void onRedo();
virtual void onFireNotifications();
virtual std::string onLabel() const;
virtual size_t onMemSize() const;
protected:
virtual void onExecute();
virtual void onUndo();
virtual void onRedo();
virtual void onFireNotifications();
virtual std::string onLabel() const;
virtual size_t onMemSize() const;
private:
Context* m_ctx;
private:
Context* m_ctx;
#if _DEBUG
enum class State { NotExecuted, Executed, Undone, Redone };
State m_state;
enum class State { NotExecuted, Executed, Undone, Redone };
State m_state;
#endif
DISABLE_COPYING(Cmd);
};
DISABLE_COPYING(Cmd);
};
} // namespace app

View File

@ -1,11 +1,11 @@
## Shared pointers
Do not keep `ImageRef` or any kind of smart pointer to `doc::`
entities. As several `cmd` can persist in parallel with other `cmd`
(due the tree structure of the [undo history](../../undo/undo_history.h))
these smart pointers can generate conflicts in the logic layer.
E.g. If we keep an `ImageRef` inside a `cmd`, the image is
not removed from the [objects hash table](../../doc/object.cpp),
so two or more `cmd` could try to add/remove the same object
in the hash table (there are asserts to check this state, were
someone is trying to add the same `ObjectId` in the hash table).
## Shared pointers
Do not keep `ImageRef` or any kind of smart pointer to `doc::`
entities. As several `cmd` can persist in parallel with other `cmd`
(due the tree structure of the [undo history](../../undo/undo_history.h))
these smart pointers can generate conflicts in the logic layer.
E.g. If we keep an `ImageRef` inside a `cmd`, the image is
not removed from the [objects hash table](../../doc/object.cpp),
so two or more `cmd` could try to add/remove the same object
in the hash table (there are asserts to check this state, were
someone is trying to add the same `ObjectId` in the hash table).

View File

@ -6,7 +6,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/add_cel.h"
@ -21,17 +21,13 @@
#include "doc/layer.h"
#include "doc/subobjects_io.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
using namespace base::serialization;
using namespace base::serialization::little_endian;
using namespace doc;
AddCel::AddCel(Layer* layer, Cel* cel)
: WithLayer(layer)
, WithCel(cel)
, m_size(0)
AddCel::AddCel(Layer* layer, Cel* cel) : WithLayer(layer), WithCel(cel), m_size(0)
{
}
@ -54,7 +50,7 @@ void AddCel::onUndo()
// Save the CelData only if the cel isn't linked
bool has_data = (cel->links() == 0);
write8(m_stream, has_data ? 1: 0);
write8(m_stream, has_data ? 1 : 0);
if (has_data) {
write_image(m_stream, cel->image());
write_celdata(m_stream, cel->data());
@ -119,5 +115,4 @@ void AddCel::removeCel(Layer* layer, Cel* cel)
delete cel;
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

View File

@ -15,37 +15,33 @@
#include <sstream>
namespace doc {
class Cel;
class Layer;
}
class Cel;
class Layer;
} // namespace doc
namespace app {
namespace cmd {
using namespace doc;
namespace app { namespace cmd {
using namespace doc;
class AddCel : public Cmd
, public WithLayer
, public WithCel {
public:
AddCel(Layer* layer, Cel* cel);
class AddCel : public Cmd,
public WithLayer,
public WithCel {
public:
AddCel(Layer* layer, Cel* cel);
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
size_t onMemSize() const override {
return sizeof(*this) + m_size;
}
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
size_t onMemSize() const override { return sizeof(*this) + m_size; }
private:
void addCel(Layer* layer, Cel* cel);
void removeCel(Layer* layer, Cel* cel);
private:
void addCel(Layer* layer, Cel* cel);
void removeCel(Layer* layer, Cel* cel);
size_t m_size;
std::stringstream m_stream;
};
size_t m_size;
std::stringstream m_stream;
};
} // namespace cmd
} // namespace app
}} // namespace app::cmd
#endif

View File

@ -5,7 +5,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/add_frame.h"
@ -18,8 +18,7 @@
#include "doc/primitives.h"
#include "doc/sprite.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
using namespace doc;
@ -77,5 +76,4 @@ void AddFrame::onUndo()
doc->notify_observers<DocEvent&>(&DocObserver::onRemoveFrame, ev);
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

View File

@ -16,34 +16,29 @@
#include <memory>
namespace doc {
class Sprite;
class Sprite;
}
namespace app {
namespace cmd {
using namespace doc;
namespace app { namespace cmd {
using namespace doc;
class AddFrame : public Cmd
, public WithSprite {
public:
AddFrame(Sprite* sprite, frame_t frame);
class AddFrame : public Cmd,
public WithSprite {
public:
AddFrame(Sprite* sprite, frame_t frame);
protected:
void onExecute() override;
void onUndo() override;
size_t onMemSize() const override {
return sizeof(*this) +
(m_addCel ? m_addCel->memSize() : 0);
}
protected:
void onExecute() override;
void onUndo() override;
size_t onMemSize() const override { return sizeof(*this) + (m_addCel ? m_addCel->memSize() : 0); }
private:
void moveFrames(Layer* layer, frame_t fromThis, frame_t delta);
private:
void moveFrames(Layer* layer, frame_t fromThis, frame_t delta);
frame_t m_newFrame;
std::unique_ptr<AddCel> m_addCel;
};
frame_t m_newFrame;
std::unique_ptr<AddCel> m_addCel;
};
} // namespace cmd
} // namespace app
}} // namespace app::cmd
#endif

View File

@ -5,7 +5,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/add_layer.h"
@ -16,8 +16,7 @@
#include "doc/layer_io.h"
#include "doc/subobjects_io.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
using namespace doc;
@ -93,5 +92,4 @@ void AddLayer::removeLayer(Layer* group, Layer* layer)
delete layer;
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

View File

@ -14,37 +14,33 @@
#include <sstream>
namespace doc {
class Layer;
class Layer;
}
namespace app {
namespace cmd {
using namespace doc;
namespace app { namespace cmd {
using namespace doc;
class AddLayer : public Cmd {
public:
AddLayer(Layer* group, Layer* newLayer, Layer* afterThis);
class AddLayer : public Cmd {
public:
AddLayer(Layer* group, Layer* newLayer, Layer* afterThis);
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
size_t onMemSize() const override {
return sizeof(*this) + m_size;
}
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
size_t onMemSize() const override { return sizeof(*this) + m_size; }
private:
void addLayer(Layer* group, Layer* newLayer, Layer* afterThis);
void removeLayer(Layer* group, Layer* layer);
private:
void addLayer(Layer* group, Layer* newLayer, Layer* afterThis);
void removeLayer(Layer* group, Layer* layer);
WithLayer m_group;
WithLayer m_newLayer;
WithLayer m_afterThis;
size_t m_size;
std::stringstream m_stream;
};
WithLayer m_group;
WithLayer m_newLayer;
WithLayer m_afterThis;
size_t m_size;
std::stringstream m_stream;
};
} // namespace cmd
} // namespace app
}} // namespace app::cmd
#endif

View File

@ -5,17 +5,16 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/add_palette.h"
#include "doc/sprite.h"
#include "doc/palette.h"
#include "doc/palette_io.h"
#include "doc/sprite.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
using namespace doc;
@ -47,5 +46,4 @@ void AddPalette::onUndo()
sprite->incrementVersion();
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

View File

@ -15,33 +15,29 @@
#include <sstream>
namespace doc {
class Palette;
class Sprite;
}
class Palette;
class Sprite;
} // namespace doc
namespace app {
namespace cmd {
using namespace doc;
namespace app { namespace cmd {
using namespace doc;
class AddPalette : public Cmd
, public WithSprite {
public:
AddPalette(Sprite* sprite, Palette* pal);
class AddPalette : public Cmd,
public WithSprite {
public:
AddPalette(Sprite* sprite, Palette* pal);
protected:
void onExecute() override;
void onUndo() override;
size_t onMemSize() const override {
return sizeof(*this) + m_size;
}
protected:
void onExecute() override;
void onUndo() override;
size_t onMemSize() const override { return sizeof(*this) + m_size; }
private:
size_t m_size;
std::stringstream m_stream;
frame_t m_frame;
};
private:
size_t m_size;
std::stringstream m_stream;
frame_t m_frame;
};
} // namespace cmd
} // namespace app
}} // namespace app::cmd
#endif // CMD_ADD_PALETTE_H_INCLUDED
#endif // CMD_ADD_PALETTE_H_INCLUDED

View File

@ -6,7 +6,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/add_slice.h"
@ -17,15 +17,11 @@
#include "doc/slice_io.h"
#include "doc/sprite.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
using namespace doc;
AddSlice::AddSlice(Sprite* sprite, Slice* slice)
: WithSprite(sprite)
, WithSlice(slice)
, m_size(0)
AddSlice::AddSlice(Sprite* sprite, Slice* slice) : WithSprite(sprite), WithSlice(slice), m_size(0)
{
}
@ -84,5 +80,4 @@ void AddSlice::removeSlice(Sprite* sprite, Slice* slice)
delete slice;
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

View File

@ -15,33 +15,29 @@
#include <sstream>
namespace app {
namespace cmd {
using namespace doc;
namespace app { namespace cmd {
using namespace doc;
class AddSlice : public Cmd
, public WithSprite
, public WithSlice {
public:
AddSlice(Sprite* sprite, Slice* slice);
class AddSlice : public Cmd,
public WithSprite,
public WithSlice {
public:
AddSlice(Sprite* sprite, Slice* slice);
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
size_t onMemSize() const override {
return sizeof(*this) + m_size;
}
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
size_t onMemSize() const override { return sizeof(*this) + m_size; }
private:
void addSlice(Sprite* sprite, Slice* slice);
void removeSlice(Sprite* sprite, Slice* slice);
private:
void addSlice(Sprite* sprite, Slice* slice);
void removeSlice(Sprite* sprite, Slice* slice);
size_t m_size;
std::stringstream m_stream;
};
size_t m_size;
std::stringstream m_stream;
};
} // namespace cmd
} // namespace app
}} // namespace app::cmd
#endif

View File

@ -6,7 +6,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/add_tag.h"
@ -17,15 +17,11 @@
#include "doc/tag.h"
#include "doc/tag_io.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
using namespace doc;
AddTag::AddTag(Sprite* sprite, Tag* tag)
: WithSprite(sprite)
, WithTag(tag)
, m_size(0)
AddTag::AddTag(Sprite* sprite, Tag* tag) : WithSprite(sprite), WithTag(tag), m_size(0)
{
}
@ -86,5 +82,4 @@ void AddTag::onRedo()
doc->notify_observers<DocEvent&>(&DocObserver::onAddTag, ev);
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

View File

@ -10,35 +10,31 @@
#pragma once
#include "app/cmd.h"
#include "app/cmd/with_tag.h"
#include "app/cmd/with_sprite.h"
#include "app/cmd/with_tag.h"
#include <sstream>
namespace app {
namespace cmd {
using namespace doc;
namespace app { namespace cmd {
using namespace doc;
class AddTag : public Cmd
, public WithSprite
, public WithTag {
public:
AddTag(Sprite* sprite, Tag* tag);
class AddTag : public Cmd,
public WithSprite,
public WithTag {
public:
AddTag(Sprite* sprite, Tag* tag);
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
size_t onMemSize() const override {
return sizeof(*this) + m_size;
}
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
size_t onMemSize() const override { return sizeof(*this) + m_size; }
private:
size_t m_size;
std::stringstream m_stream;
};
private:
size_t m_size;
std::stringstream m_stream;
};
} // namespace cmd
} // namespace app
}} // namespace app::cmd
#endif

View File

@ -5,7 +5,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/add_tile.h"
@ -16,12 +16,9 @@
#include "doc/tileset.h"
#include "doc/tilesets.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
AddTile::AddTile(doc::Tileset* tileset,
const doc::ImageRef& image,
const doc::UserData& userData)
AddTile::AddTile(doc::Tileset* tileset, const doc::ImageRef& image, const doc::UserData& userData)
: WithTileset(tileset)
, WithImage(image.get())
, m_size(0)
@ -31,8 +28,7 @@ AddTile::AddTile(doc::Tileset* tileset,
{
}
AddTile::AddTile(doc::Tileset* tileset,
const doc::tile_index ti)
AddTile::AddTile(doc::Tileset* tileset, const doc::tile_index ti)
: WithTileset(tileset)
, WithImage(tileset->get(ti).get())
, m_size(0)
@ -94,8 +90,7 @@ void AddTile::onFireNotifications()
doc::Tileset* tileset = this->tileset();
// Notify that the tileset's changed
static_cast<Doc*>(tileset->sprite()->document())
->notifyTilesetChanged(tileset);
static_cast<Doc*>(tileset->sprite()->document())->notifyTilesetChanged(tileset);
}
void AddTile::addTile(doc::Tileset* tileset,
@ -111,5 +106,4 @@ void AddTile::addTile(doc::Tileset* tileset,
tileset->incrementVersion();
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

View File

@ -18,47 +18,43 @@
#include <sstream>
namespace doc {
class Tileset;
class Tileset;
}
namespace app {
namespace cmd {
namespace app { namespace cmd {
class AddTile : public Cmd
, public WithTileset
, public WithImage {
public:
AddTile(doc::Tileset* tileset,
const doc::ImageRef& image,
const doc::UserData& userData = UserData());
AddTile(doc::Tileset* tileset,
const doc::tile_index ti);
class AddTile : public Cmd,
public WithTileset,
public WithImage {
public:
AddTile(doc::Tileset* tileset,
const doc::ImageRef& image,
const doc::UserData& userData = UserData());
AddTile(doc::Tileset* tileset, const doc::tile_index ti);
doc::tile_index tileIndex() const { return m_tileIndex; }
doc::tile_index tileIndex() const { return m_tileIndex; }
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
void onFireNotifications() override;
size_t onMemSize() const override {
// TODO add m_userData size
return sizeof(*this) + m_size;
}
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
void onFireNotifications() override;
size_t onMemSize() const override
{
// TODO add m_userData size
return sizeof(*this) + m_size;
}
private:
void addTile(doc::Tileset* tileset,
const doc::ImageRef& image,
const doc::UserData& userData);
private:
void addTile(doc::Tileset* tileset, const doc::ImageRef& image, const doc::UserData& userData);
size_t m_size;
std::stringstream m_stream;
doc::tile_index m_tileIndex;
doc::ImageRef m_imageRef;
doc::UserData m_userData;
};
size_t m_size;
std::stringstream m_stream;
doc::tile_index m_tileIndex;
doc::ImageRef m_imageRef;
doc::UserData m_userData;
};
} // namespace cmd
} // namespace app
}} // namespace app::cmd
#endif

View File

@ -5,7 +5,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/add_tileset.h"
@ -16,8 +16,7 @@
#include "doc/tileset_io.h"
#include "doc/tilesets.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
using namespace doc;
@ -84,5 +83,4 @@ void AddTileset::addTileset(doc::Tileset* tileset)
sprite->tilesets()->incrementVersion();
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

View File

@ -16,38 +16,34 @@
#include <sstream>
namespace doc {
class Tileset;
class Tileset;
}
namespace app {
namespace cmd {
namespace app { namespace cmd {
class AddTileset : public Cmd
, public WithSprite
, public WithTileset {
public:
AddTileset(doc::Sprite* sprite, doc::Tileset* tileset);
AddTileset(doc::Sprite* sprite, const doc::tileset_index tsi);
class AddTileset : public Cmd,
public WithSprite,
public WithTileset {
public:
AddTileset(doc::Sprite* sprite, doc::Tileset* tileset);
AddTileset(doc::Sprite* sprite, const doc::tileset_index tsi);
doc::tileset_index tilesetIndex() const { return m_tilesetIndex; }
doc::tileset_index tilesetIndex() const { return m_tilesetIndex; }
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
size_t onMemSize() const override {
return sizeof(*this) + m_size;
}
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
size_t onMemSize() const override { return sizeof(*this) + m_size; }
private:
void addTileset(doc::Tileset* tileset);
private:
void addTileset(doc::Tileset* tileset);
size_t m_size;
std::stringstream m_stream;
doc::tileset_index m_tilesetIndex;
};
size_t m_size;
std::stringstream m_stream;
doc::tileset_index m_tilesetIndex;
};
} // namespace cmd
} // namespace app
}} // namespace app::cmd
#endif

View File

@ -5,7 +5,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/assign_color_profile.h"
@ -14,8 +14,7 @@
#include "app/doc_event.h"
#include "doc/sprite.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
AssignColorProfile::AssignColorProfile(doc::Sprite* sprite, const gfx::ColorSpaceRef& cs)
: WithSprite(sprite)
@ -45,5 +44,4 @@ void AssignColorProfile::onFireNotifications()
doc->notifyColorSpaceChanged();
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

View File

@ -12,31 +12,27 @@
#include "app/cmd/with_sprite.h"
#include "gfx/color_space.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
class AssignColorProfile : public Cmd,
public WithSprite {
public:
AssignColorProfile(doc::Sprite* sprite, const gfx::ColorSpaceRef& cs);
class AssignColorProfile : public Cmd,
public WithSprite {
public:
AssignColorProfile(doc::Sprite* sprite, const gfx::ColorSpaceRef& cs);
protected:
void onExecute() override;
void onUndo() override;
void onFireNotifications() override;
size_t onMemSize() const override {
return sizeof(*this) +
2*sizeof(gfx::ColorSpace) +
m_oldCS->iccSize() +
m_newCS->iccSize();
}
protected:
void onExecute() override;
void onUndo() override;
void onFireNotifications() override;
size_t onMemSize() const override
{
return sizeof(*this) + 2 * sizeof(gfx::ColorSpace) + m_oldCS->iccSize() + m_newCS->iccSize();
}
private:
gfx::ColorSpaceRef m_oldCS;
gfx::ColorSpaceRef m_newCS;
};
private:
gfx::ColorSpaceRef m_oldCS;
gfx::ColorSpaceRef m_newCS;
};
} // namespace cmd
} // namespace app
}} // namespace app::cmd
#endif

View File

@ -6,7 +6,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/background_from_layer.h"
@ -25,11 +25,9 @@
#include "doc/sprite.h"
#include "render/render.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
BackgroundFromLayer::BackgroundFromLayer(Layer* layer)
: WithLayer(layer)
BackgroundFromLayer::BackgroundFromLayer(Layer* layer) : WithLayer(layer)
{
ASSERT(layer);
ASSERT(layer->isVisible());
@ -42,7 +40,7 @@ BackgroundFromLayer::BackgroundFromLayer(Layer* layer)
void BackgroundFromLayer::onExecute()
{
Layer* layer = this->layer();
ASSERT(!layer->isTilemap()); // TODO support background tilemaps
ASSERT(!layer->isTilemap()); // TODO support background tilemaps
Sprite* sprite = layer->sprite();
auto doc = static_cast<Doc*>(sprite->document());
@ -60,12 +58,13 @@ void BackgroundFromLayer::onExecute()
ASSERT(cel_image->pixelFormat() != IMAGE_TILEMAP);
clear_image(bg_image.get(), bgcolor);
render::composite_image(
bg_image.get(), cel_image,
sprite->palette(cel->frame()),
cel->x(), cel->y(),
std::clamp(cel->opacity(), 0, 255),
static_cast<LayerImage*>(layer)->blendMode());
render::composite_image(bg_image.get(),
cel_image,
sprite->palette(cel->frame()),
cel->x(),
cel->y(),
std::clamp(cel->opacity(), 0, 255),
static_cast<LayerImage*>(layer)->blendMode());
// now we have to copy the new image (bg_image) to the cel...
executeAndAdd(new cmd::SetCelPosition(cel, 0, 0));
@ -76,10 +75,8 @@ void BackgroundFromLayer::onExecute()
// Same size of cel image and background image, we can just
// replace pixels.
if (bg_image->width() == cel_image->width() &&
bg_image->height() == cel_image->height()) {
executeAndAdd(new CopyRect(cel_image, bg_image.get(),
gfx::Clip(0, 0, cel_image->bounds())));
if (bg_image->width() == cel_image->width() && bg_image->height() == cel_image->height()) {
executeAndAdd(new CopyRect(cel_image, bg_image.get(), gfx::Clip(0, 0, cel_image->bounds())));
}
// In other case we have to replace the whole image (this is the
// most common case, a smaller transparent cel that is converted
@ -91,11 +88,10 @@ void BackgroundFromLayer::onExecute()
}
// Fill all empty cels with a flat image filled with bgcolor
for (frame_t frame(0); frame<sprite->totalFrames(); ++frame) {
for (frame_t frame(0); frame < sprite->totalFrames(); ++frame) {
Cel* cel = layer->cel(frame);
if (!cel) {
ImageRef cel_image(Image::create(sprite->pixelFormat(),
sprite->width(), sprite->height()));
ImageRef cel_image(Image::create(sprite->pixelFormat(), sprite->width(), sprite->height()));
clear_image(cel_image.get(), bgcolor);
// Create the new cel and add it to the new background layer
@ -107,5 +103,4 @@ void BackgroundFromLayer::onExecute()
executeAndAdd(new cmd::ConfigureBackground(layer));
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

View File

@ -11,20 +11,18 @@
#include "app/cmd/with_layer.h"
#include "app/cmd_sequence.h"
namespace app {
namespace cmd {
using namespace doc;
namespace app { namespace cmd {
using namespace doc;
class BackgroundFromLayer : public CmdSequence
, public WithLayer {
public:
BackgroundFromLayer(Layer* layer);
class BackgroundFromLayer : public CmdSequence,
public WithLayer {
public:
BackgroundFromLayer(Layer* layer);
protected:
void onExecute() override;
};
protected:
void onExecute() override;
};
} // namespace cmd
} // namespace app
}} // namespace app::cmd
#endif

View File

@ -5,7 +5,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/clear_cel.h"
@ -16,13 +16,11 @@
#include "doc/cel.h"
#include "doc/layer.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
using namespace doc;
ClearCel::ClearCel(Cel* cel)
: WithCel(cel)
ClearCel::ClearCel(Cel* cel) : WithCel(cel)
{
Doc* doc = static_cast<Doc*>(cel->document());
@ -30,8 +28,7 @@ ClearCel::ClearCel(Cel* cel)
Image* image = cel->image();
ASSERT(image);
if (image)
m_seq.add(new cmd::ClearImage(image,
doc->bgColor(cel->layer())));
m_seq.add(new cmd::ClearImage(image, doc->bgColor(cel->layer())));
}
else {
m_seq.add(new cmd::RemoveCel(cel));
@ -53,5 +50,4 @@ void ClearCel::onRedo()
m_seq.redo();
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

View File

@ -12,28 +12,24 @@
#include "app/cmd/with_cel.h"
#include "app/cmd_sequence.h"
namespace app {
namespace cmd {
using namespace doc;
namespace app { namespace cmd {
using namespace doc;
class ClearCel : public Cmd
, public WithCel {
public:
ClearCel(Cel* cel);
class ClearCel : public Cmd,
public WithCel {
public:
ClearCel(Cel* cel);
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
size_t onMemSize() const override {
return sizeof(*this) + m_seq.memSize();
}
protected:
void onExecute() override;
void onUndo() override;
void onRedo() override;
size_t onMemSize() const override { return sizeof(*this) + m_seq.memSize(); }
private:
CmdSequence m_seq;
};
private:
CmdSequence m_seq;
};
} // namespace cmd
} // namespace app
}} // namespace app::cmd
#endif

View File

@ -5,7 +5,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/clear_image.h"
@ -14,14 +14,11 @@
#include "doc/image.h"
#include "doc/primitives.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
using namespace doc;
ClearImage::ClearImage(Image* image, color_t color)
: WithImage(image)
, m_color(color)
ClearImage::ClearImage(Image* image, color_t color) : WithImage(image), m_color(color)
{
}
@ -46,5 +43,4 @@ void ClearImage::onUndo()
image->incrementVersion();
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

View File

@ -13,28 +13,24 @@
#include "doc/color.h"
#include "doc/image_ref.h"
namespace app {
namespace cmd {
using namespace doc;
namespace app { namespace cmd {
using namespace doc;
class ClearImage : public Cmd
, public WithImage {
public:
ClearImage(Image* image, color_t color);
class ClearImage : public Cmd,
public WithImage {
public:
ClearImage(Image* image, color_t color);
protected:
void onExecute() override;
void onUndo() override;
size_t onMemSize() const override {
return sizeof(*this) + (m_copy ? m_copy->getMemSize(): 0);
}
protected:
void onExecute() override;
void onUndo() override;
size_t onMemSize() const override { return sizeof(*this) + (m_copy ? m_copy->getMemSize() : 0); }
private:
ImageRef m_copy;
color_t m_color;
};
private:
ImageRef m_copy;
color_t m_color;
};
} // namespace cmd
} // namespace app
}} // namespace app::cmd
#endif

View File

@ -6,7 +6,7 @@
// the End-User License Agreement for Aseprite.
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#include "app/cmd/clear_mask.h"
@ -21,13 +21,11 @@
#include "doc/mask.h"
#include "doc/primitives.h"
namespace app {
namespace cmd {
namespace app { namespace cmd {
using namespace doc;
ClearMask::ClearMask(Cel* cel)
: WithCel(cel)
ClearMask::ClearMask(Cel* cel) : WithCel(cel)
{
Doc* doc = static_cast<Doc*>(cel->document());
@ -51,8 +49,7 @@ ClearMask::ClearMask(Cel* cel)
gfx::Rect maskBounds;
if (image->pixelFormat() == IMAGE_TILEMAP) {
auto grid = cel->grid();
imageBounds = gfx::Rect(grid.canvasToTile(cel->position()),
cel->image()->size());
imageBounds = gfx::Rect(grid.canvasToTile(cel->position()), cel->image()->size());
maskBounds = grid.canvasToTile(mask->bounds());
m_bgcolor = doc::notile; // TODO configurable empty tile
}
@ -100,12 +97,11 @@ void ClearMask::clear()
Mask* mask = doc->mask();
Grid grid = cel->grid();
doc::algorithm::fill_selection(
cel->image(),
cel->bounds(),
mask,
m_bgcolor,
(cel->image()->isTilemap() ? &grid: nullptr));
doc::algorithm::fill_selection(cel->image(),
cel->bounds(),
mask,
m_bgcolor,
(cel->image()->isTilemap() ? &grid : nullptr));
}
void ClearMask::restore()
@ -114,11 +110,7 @@ void ClearMask::restore()
return;
Cel* cel = this->cel();
copy_image(cel->image(),
m_copy.get(),
m_cropPos.x,
m_cropPos.y);
copy_image(cel->image(), m_copy.get(), m_cropPos.x, m_cropPos.y);
}
} // namespace cmd
} // namespace app
}} // namespace app::cmd

Some files were not shown because too many files have changed in this diff Show More