Merge branch 'dev'

This commit is contained in:
David Capello 2014-06-04 01:10:14 -03:00
commit c221e4a49a
304 changed files with 7006 additions and 5016 deletions

View File

@ -44,6 +44,7 @@ option(ENABLE_UPDATER "Enable automatic check for updates" on)
option(ENABLE_WEBSERVER "Enable support to run a webserver (for HTML5 gamedev)" off) option(ENABLE_WEBSERVER "Enable support to run a webserver (for HTML5 gamedev)" off)
option(ENABLE_TRIAL_MODE "Compile the trial version" off) option(ENABLE_TRIAL_MODE "Compile the trial version" off)
option(FULLSCREEN_PLATFORM "Enable fullscreen by default" off) option(FULLSCREEN_PLATFORM "Enable fullscreen by default" off)
set(CUSTOM_WEBSITE_URL "" CACHE STRING "Enable custom local webserver to check updates")
###################################################################### ######################################################################
# Profile build type # Profile build type

16
TODO.md
View File

@ -1,9 +1,15 @@
# Before release # Next release
* timeline: move a layer to the same place -> crash * ColorSelector: change color type when a tab is pressed
* timeline: select all layers and remove -> crash * canvas dialog should show width and height and expansion point
* timeline: move cel with right click -> crash * double click or right click a range outline in timeline should open popups or properties
* fix animation playback (the duration is not used correctly)
# Hard to reproduce bugs
* does lock alpha work correctly?
* does onscrollchange notification calls onscrollchange notification?
* random clicks on toolbar crashes the program
* click Desktop item in file selector crashes the program
# Tasks # Tasks

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- ASE menus, tools and keyboard shortcuts --> <!-- ASE menus, tools and keyboard shortcuts -->
<gui version="0.9.6-dev"> <gui version="1.0.0-dev">
<!-- Keyboard shortcuts --> <!-- Keyboard shortcuts -->
<keyboard> <keyboard>
@ -18,7 +18,9 @@
<key command="AdvancedMode" shortcut="F11" /> <key command="AdvancedMode" shortcut="F11" />
<key command="DeveloperConsole" shortcut="F12" /> <key command="DeveloperConsole" shortcut="F12" />
<key command="Exit" shortcut="Alt+F4" /> <key command="Exit" shortcut="Alt+F4" />
<key command="Cancel" shortcut="Esc" /> <key command="Cancel" shortcut="Esc">
<param name="type" value="all" />
</key>
<!-- Edit --> <!-- Edit -->
<key command="Undo" shortcut="Ctrl+Z" /> <key command="Undo" shortcut="Ctrl+U" /> <key command="Undo" shortcut="Ctrl+Z" /> <key command="Undo" shortcut="Ctrl+U" />
<key command="Redo" shortcut="Ctrl+Y" /> <key command="Redo" shortcut="Ctrl+Y" />
@ -74,6 +76,7 @@
<key command="Preview" shortcut="F8" /> <key command="Preview" shortcut="F8" />
<key command="ShowGrid" shortcut="Shift+G" /> <key command="ShowGrid" shortcut="Shift+G" />
<key command="SnapToGrid" shortcut="Shift+S" /> <key command="SnapToGrid" shortcut="Shift+S" />
<key command="ShowOnionSkin" shortcut="F3" />
<key command="Timeline" shortcut="Tab"> <key command="Timeline" shortcut="Tab">
<param name="switch" value="true" /> <param name="switch" value="true" />
</key> </key>
@ -373,6 +376,8 @@
<item command="SnapToGrid" text="&amp;Snap to Grid" /> <item command="SnapToGrid" text="&amp;Snap to Grid" />
<item command="GridSettings" text="Gri&amp;d Settings" /> <item command="GridSettings" text="Gri&amp;d Settings" />
<separator /> <separator />
<item command="ShowOnionSkin" text="Show &amp;Onion Skin" />
<separator />
<item command="Timeline" text="&amp;Timeline"> <item command="Timeline" text="&amp;Timeline">
<param name="switch" value="true" /> <param name="switch" value="true" />
</item> </item>
@ -387,21 +392,21 @@
</item> </item>
<separator /> <separator />
<item command="Launch" text="Quick &amp;Reference"> <item command="Launch" text="Quick &amp;Reference">
<param name="type" value="docs" /> <param name="type" value="url" />
<param name="path" value="http://www.aseprite.org/quickref/" /> <param name="path" value="/quickref/" />
</item> </item>
<item command="Launch" text="Documentation"> <item command="Launch" text="Documentation">
<param name="type" value="url" /> <param name="type" value="url" />
<param name="path" value="http://www.aseprite.org/docs/" /> <param name="path" value="/docs/" />
</item> </item>
<item command="Launch" text="Tutorial"> <item command="Launch" text="Tutorial">
<param name="type" value="url" /> <param name="type" value="url" />
<param name="path" value="http://www.aseprite.org/tutorial/" /> <param name="path" value="/tutorial/" />
</item> </item>
<separator /> <separator />
<item command="Launch" text="Release Notes"> <item command="Launch" text="Release Notes">
<param name="type" value="url" /> <param name="type" value="url" />
<param name="path" value="http://www.aseprite.org/release-notes/" /> <param name="path" value="/release-notes/" />
</item> </item>
<item command="Launch" text="Twitter"> <item command="Launch" text="Twitter">
<param name="type" value="url" /> <param name="type" value="url" />
@ -410,7 +415,7 @@
<separator /> <separator />
<item command="Launch" text="&amp;Donate"> <item command="Launch" text="&amp;Donate">
<param name="type" value="url" /> <param name="type" value="url" />
<param name="path" value="http://www.aseprite.org/donate/" /> <param name="path" value="/donate/" />
</item> </item>
<item command="About" text="&amp;About" /> <item command="About" text="&amp;About" />
</menu> </menu>
@ -454,6 +459,10 @@
<menu id="cel_movement_popup"> <menu id="cel_movement_popup">
<item command="MoveCel" text="&amp;Move" /> <item command="MoveCel" text="&amp;Move" />
<item command="CopyCel" text="&amp;Copy" /> <item command="CopyCel" text="&amp;Copy" />
<separator />
<item command="Cancel" text="Cancel">
<param name="type" value="noop" />
</item>
</menu> </menu>
</menus> </menus>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 925 B

After

Width:  |  Height:  |  Size: 191 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 534 B

After

Width:  |  Height:  |  Size: 255 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 713 B

After

Width:  |  Height:  |  Size: 308 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 649 B

After

Width:  |  Height:  |  Size: 372 B

View File

@ -0,0 +1,18 @@
GIMP Palette
#
0 0 0 Untitled
108 41 64 Untitled
64 53 120 Untitled
217 60 240 Untitled
19 87 64 Untitled
128 128 128 Untitled
38 151 240 Untitled
191 180 248 Untitled
64 75 7 Untitled
217 104 15 Untitled
128 128 128 Untitled
236 168 191 Untitled
38 195 15 Untitled
191 202 135 Untitled
147 214 191 Untitled
255 255 255 Untitled

View File

@ -0,0 +1,258 @@
GIMP Palette
#
0 0 0 Untitled
68 68 0 Untitled
112 40 0 Untitled
132 24 0 Untitled
136 0 0 Untitled
120 0 92 Untitled
72 0 120 Untitled
20 0 132 Untitled
0 0 136 Untitled
0 24 124 Untitled
0 44 92 Untitled
0 64 44 Untitled
0 60 0 Untitled
20 56 0 Untitled
44 48 0 Untitled
68 40 0 Untitled
64 64 64 Untitled
100 100 16 Untitled
132 68 20 Untitled
152 52 24 Untitled
156 32 32 Untitled
140 32 116 Untitled
96 32 144 Untitled
48 32 152 Untitled
28 32 156 Untitled
28 56 144 Untitled
28 76 120 Untitled
28 92 72 Untitled
32 92 32 Untitled
52 92 28 Untitled
76 80 28 Untitled
100 72 24 Untitled
108 108 108 Untitled
132 132 36 Untitled
152 92 40 Untitled
172 80 48 Untitled
176 60 60 Untitled
160 60 136 Untitled
120 60 164 Untitled
76 60 172 Untitled
56 64 176 Untitled
56 84 168 Untitled
56 104 144 Untitled
56 124 100 Untitled
64 124 64 Untitled
80 124 56 Untitled
104 112 52 Untitled
132 104 48 Untitled
144 144 144 Untitled
160 160 52 Untitled
172 120 60 Untitled
192 104 72 Untitled
192 88 88 Untitled
176 88 156 Untitled
140 88 184 Untitled
104 88 192 Untitled
80 92 192 Untitled
80 112 188 Untitled
80 132 172 Untitled
80 156 128 Untitled
92 156 92 Untitled
108 152 80 Untitled
132 140 76 Untitled
160 132 68 Untitled
176 176 176 Untitled
184 184 64 Untitled
188 140 76 Untitled
208 128 92 Untitled
208 112 112 Untitled
192 112 176 Untitled
160 112 204 Untitled
124 112 208 Untitled
104 116 208 Untitled
104 136 204 Untitled
104 156 192 Untitled
104 180 148 Untitled
116 180 116 Untitled
132 180 104 Untitled
156 168 100 Untitled
184 156 88 Untitled
200 200 200 Untitled
208 208 80 Untitled
204 160 92 Untitled
224 148 112 Untitled
224 136 136 Untitled
208 132 192 Untitled
180 132 220 Untitled
148 136 224 Untitled
124 140 224 Untitled
124 156 220 Untitled
124 180 212 Untitled
124 208 172 Untitled
140 208 140 Untitled
156 204 124 Untitled
180 192 120 Untitled
208 180 108 Untitled
220 220 220 Untitled
232 232 92 Untitled
220 180 104 Untitled
236 168 128 Untitled
236 160 160 Untitled
220 156 208 Untitled
196 156 236 Untitled
168 160 236 Untitled
144 164 236 Untitled
144 180 236 Untitled
144 204 232 Untitled
144 228 192 Untitled
164 228 164 Untitled
180 228 144 Untitled
204 212 136 Untitled
232 204 124 Untitled
236 236 236 Untitled
252 252 104 Untitled
236 200 120 Untitled
252 188 148 Untitled
252 180 180 Untitled
236 176 224 Untitled
212 176 252 Untitled
188 180 252 Untitled
164 184 252 Untitled
164 200 252 Untitled
164 224 252 Untitled
164 252 212 Untitled
184 252 184 Untitled
200 252 164 Untitled
224 236 156 Untitled
252 224 140 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
255 255 255 Untitled

View File

@ -0,0 +1,130 @@
GIMP Palette
#
0 0 0 Untitled
0 0 0 Untitled
128 88 0 Untitled
68 92 0 Untitled
112 52 0 Untitled
0 100 20 Untitled
112 0 20 Untitled
0 92 92 Untitled
112 0 92 Untitled
0 60 112 Untitled
88 0 112 Untitled
0 32 112 Untitled
60 0 128 Untitled
0 0 136 Untitled
0 0 0 Untitled
0 0 0 Untitled
64 64 64 Untitled
64 64 64 Untitled
148 112 32 Untitled
92 120 32 Untitled
136 80 32 Untitled
32 128 52 Untitled
136 32 52 Untitled
32 116 116 Untitled
132 32 116 Untitled
28 88 136 Untitled
108 32 136 Untitled
28 60 136 Untitled
84 32 148 Untitled
32 32 156 Untitled
64 64 64 Untitled
64 64 64 Untitled
108 108 108 Untitled
108 108 108 Untitled
168 132 60 Untitled
116 144 60 Untitled
160 104 60 Untitled
60 152 80 Untitled
160 60 80 Untitled
60 140 140 Untitled
148 60 136 Untitled
56 116 160 Untitled
128 60 160 Untitled
56 88 160 Untitled
108 60 168 Untitled
60 60 176 Untitled
108 108 108 Untitled
108 108 108 Untitled
144 144 144 Untitled
144 144 144 Untitled
188 156 88 Untitled
140 172 88 Untitled
180 132 88 Untitled
88 176 108 Untitled
180 88 108 Untitled
88 164 164 Untitled
168 88 156 Untitled
80 140 180 Untitled
148 88 180 Untitled
80 116 180 Untitled
128 88 188 Untitled
88 88 192 Untitled
144 144 144 Untitled
144 144 144 Untitled
176 176 176 Untitled
176 176 176 Untitled
204 172 112 Untitled
160 192 112 Untitled
200 152 112 Untitled
112 196 132 Untitled
200 112 132 Untitled
112 184 184 Untitled
180 112 176 Untitled
104 164 200 Untitled
164 112 200 Untitled
104 136 200 Untitled
148 112 204 Untitled
112 112 208 Untitled
176 176 176 Untitled
176 176 176 Untitled
200 200 200 Untitled
200 200 200 Untitled
220 192 132 Untitled
176 212 132 Untitled
220 172 132 Untitled
132 216 156 Untitled
220 132 156 Untitled
132 200 200 Untitled
196 132 192 Untitled
124 184 220 Untitled
180 132 220 Untitled
124 160 220 Untitled
168 132 220 Untitled
132 132 224 Untitled
200 200 200 Untitled
200 200 200 Untitled
220 220 220 Untitled
220 220 220 Untitled
236 208 156 Untitled
192 232 156 Untitled
236 192 156 Untitled
156 232 180 Untitled
236 156 180 Untitled
156 220 220 Untitled
208 156 208 Untitled
144 204 236 Untitled
196 156 236 Untitled
144 180 236 Untitled
184 156 236 Untitled
156 156 236 Untitled
220 220 220 Untitled
220 220 220 Untitled
236 236 236 Untitled
236 236 236 Untitled
252 224 176 Untitled
212 252 176 Untitled
252 212 176 Untitled
176 252 200 Untitled
252 176 200 Untitled
176 236 236 Untitled
224 176 224 Untitled
164 224 252 Untitled
212 176 252 Untitled
164 200 252 Untitled
200 176 252 Untitled
176 176 252 Untitled
236 236 236 Untitled
236 236 236 Untitled

18
data/palettes/cga.gpl Normal file
View File

@ -0,0 +1,18 @@
GIMP Palette
#
0 0 0 Untitled
0 0 170 Untitled
0 170 0 Untitled
0 170 170 Untitled
170 0 0 Untitled
170 0 170 Untitled
170 85 0 Untitled
170 170 170 Untitled
85 85 85 Untitled
85 85 255 Untitled
85 255 85 Untitled
85 255 255 Untitled
255 85 85 Untitled
255 85 255 Untitled
255 255 85 Untitled
255 255 255 Untitled

View File

@ -0,0 +1,130 @@
GIMP Palette
#
0 0 0 Untitled
32 32 32 Untitled
93 8 0 Untitled
0 55 70 Untitled
93 0 109 Untitled
0 78 0 Untitled
32 17 109 Untitled
32 47 0 Untitled
93 16 0 Untitled
62 31 0 Untitled
1 62 0 Untitled
93 1 32 Untitled
0 63 32 Untitled
0 48 109 Untitled
62 1 109 Untitled
0 70 0 Untitled
0 0 0 Untitled
64 64 64 Untitled
125 40 25 Untitled
3 87 102 Untitled
125 18 141 Untitled
3 110 0 Untitled
64 49 141 Untitled
64 79 0 Untitled
125 48 0 Untitled
94 63 0 Untitled
33 94 0 Untitled
125 33 64 Untitled
3 95 64 Untitled
3 80 141 Untitled
94 33 141 Untitled
3 102 25 Untitled
0 0 0 Untitled
96 96 96 Untitled
156 72 57 Untitled
35 119 134 Untitled
156 50 172 Untitled
35 142 19 Untitled
96 81 172 Untitled
96 111 19 Untitled
156 80 19 Untitled
126 95 19 Untitled
65 126 19 Untitled
156 65 96 Untitled
35 127 96 Untitled
35 112 172 Untitled
126 65 172 Untitled
35 134 57 Untitled
0 0 0 Untitled
128 128 128 Untitled
188 104 89 Untitled
67 151 166 Untitled
188 82 204 Untitled
67 173 51 Untitled
128 113 204 Untitled
128 142 51 Untitled
188 111 51 Untitled
158 127 51 Untitled
97 158 51 Untitled
188 97 128 Untitled
67 158 128 Untitled
67 144 204 Untitled
158 97 204 Untitled
67 166 89 Untitled
0 0 0 Untitled
159 159 159 Untitled
220 136 121 Untitled
99 183 198 Untitled
220 113 236 Untitled
99 205 83 Untitled
159 144 236 Untitled
159 174 83 Untitled
220 143 83 Untitled
190 159 83 Untitled
129 190 83 Untitled
220 128 159 Untitled
99 190 159 Untitled
99 175 236 Untitled
190 129 236 Untitled
99 198 121 Untitled
0 0 0 Untitled
191 191 191 Untitled
252 168 153 Untitled
130 215 230 Untitled
252 145 255 Untitled
130 237 114 Untitled
191 176 255 Untitled
191 206 114 Untitled
252 175 114 Untitled
222 191 114 Untitled
161 222 114 Untitled
252 160 191 Untitled
130 222 191 Untitled
130 207 255 Untitled
222 161 255 Untitled
130 230 153 Untitled
0 0 0 Untitled
223 223 223 Untitled
255 200 185 Untitled
162 247 255 Untitled
255 177 255 Untitled
162 255 146 Untitled
223 208 255 Untitled
223 238 146 Untitled
255 207 146 Untitled
254 223 146 Untitled
193 254 146 Untitled
255 192 223 Untitled
162 254 223 Untitled
162 239 255 Untitled
254 193 255 Untitled
162 255 185 Untitled
0 0 0 Untitled
255 255 255 Untitled
255 232 217 Untitled
194 255 255 Untitled
255 209 255 Untitled
194 255 178 Untitled
255 240 255 Untitled
255 255 178 Untitled
255 239 178 Untitled
255 254 178 Untitled
225 255 178 Untitled
255 224 255 Untitled
194 255 255 Untitled
194 255 255 Untitled
255 225 255 Untitled
194 255 217 Untitled

View File

@ -0,0 +1,18 @@
GIMP Palette
#
0 0 0 Untitled
255 255 255 Untitled
120 41 34 Untitled
135 214 221 Untitled
170 95 182 Untitled
26 130 38 Untitled
64 49 141 Untitled
191 206 114 Untitled
170 116 73 Untitled
234 180 137 Untitled
184 105 98 Untitled
199 255 255 Untitled
234 159 246 Untitled
148 224 137 Untitled
128 113 204 Untitled
255 255 178 Untitled

View File

@ -0,0 +1,18 @@
GIMP Palette
#
0 0 0 Untitled
255 255 255 Untitled
136 57 50 Untitled
103 182 189 Untitled
139 63 150 Untitled
85 160 73 Untitled
64 49 141 Untitled
191 206 114 Untitled
139 84 41 Untitled
87 66 0 Untitled
184 105 98 Untitled
80 80 80 Untitled
120 120 120 Untitled
148 224 137 Untitled
120 105 196 Untitled
159 159 159 Untitled

View File

@ -0,0 +1,6 @@
GIMP Palette
#
155 188 15 Untitled
139 172 15 Untitled
48 98 48 Untitled
15 56 15 Untitled

View File

@ -0,0 +1,34 @@
GIMP Palette
#
85 0 85 Untitled
170 85 170 Untitled
255 170 255 Untitled
0 0 85 Untitled
85 85 170 Untitled
170 170 255 Untitled
85 170 170 Untitled
0 85 85 Untitled
170 255 255 Untitled
0 85 0 Untitled
170 255 170 Untitled
85 170 0 Untitled
170 255 0 Untitled
170 170 0 Untitled
85 85 0 Untitled
255 255 85 Untitled
170 170 85 Untitled
255 255 170 Untitled
255 170 0 Untitled
170 85 0 Untitled
255 170 85 Untitled
255 85 0 Untitled
255 0 0 Untitled
170 0 0 Untitled
85 0 0 Untitled
255 85 85 Untitled
170 85 85 Untitled
255 170 170 Untitled
255 255 255 Untitled
170 170 170 Untitled
85 85 85 Untitled
0 0 0 Untitled

66
data/palettes/nes.gpl Normal file
View File

@ -0,0 +1,66 @@
GIMP Palette
#
125 125 125 Untitled
0 0 255 Untitled
0 0 190 Untitled
69 40 190 Untitled
150 0 134 Untitled
170 0 32 Untitled
170 16 0 Untitled
138 20 0 Untitled
81 48 0 Untitled
0 121 0 Untitled
0 105 0 Untitled
0 89 0 Untitled
0 65 89 Untitled
0 0 0 Untitled
0 0 0 Untitled
0 0 0 Untitled
190 190 190 Untitled
0 121 251 Untitled
0 89 251 Untitled
105 69 255 Untitled
219 0 207 Untitled
231 0 89 Untitled
251 56 0 Untitled
231 93 16 Untitled
174 125 0 Untitled
0 186 0 Untitled
0 170 0 Untitled
0 170 69 Untitled
0 138 138 Untitled
8 8 8 Untitled
0 0 0 Untitled
0 0 0 Untitled
251 251 251 Untitled
60 190 255 Untitled
105 138 255 Untitled
154 121 251 Untitled
251 121 251 Untitled
251 89 154 Untitled
251 121 89 Untitled
255 162 69 Untitled
251 186 0 Untitled
186 251 24 Untitled
89 219 85 Untitled
89 251 154 Untitled
0 235 219 Untitled
121 121 121 Untitled
0 0 0 Untitled
0 0 0 Untitled
255 255 255 Untitled
166 231 255 Untitled
186 186 251 Untitled
219 186 251 Untitled
251 186 251 Untitled
251 166 195 Untitled
243 211 178 Untitled
255 227 170 Untitled
251 219 121 Untitled
219 251 121 Untitled
186 251 186 Untitled
186 251 219 Untitled
0 255 255 Untitled
219 219 219 Untitled
0 0 0 Untitled
0 0 0 Untitled

View File

@ -0,0 +1,10 @@
GIMP Palette
#
0 0 0 Untitled
0 0 255 Untitled
255 0 0 Untitled
255 0 255 Untitled
0 255 0 Untitled
0 255 255 Untitled
255 255 0 Untitled
255 255 255 Untitled

18
data/palettes/win16.gpl Normal file
View File

@ -0,0 +1,18 @@
GIMP Palette
#
0 0 0 Untitled
130 0 0 Untitled
0 130 0 Untitled
130 130 0 Untitled
0 0 130 Untitled
130 0 130 Untitled
0 130 130 Untitled
195 195 195 Untitled
130 130 130 Untitled
255 0 0 Untitled
0 255 0 Untitled
255 255 0 Untitled
0 0 255 Untitled
255 0 255 Untitled
0 255 255 Untitled
255 255 255 Untitled

View File

@ -0,0 +1,20 @@
GIMP Palette
#
# ZX Spectrum
#
0 0 0 Black
0 0 192 Basic Blue
192 0 0 Basic Red
192 0 192 Basic Magenta
0 192 0 Basic Green
0 192 192 Basic Cyan
192 192 0 Basic Yellow
192 192 192 Basic White
0 0 0 Black
0 0 255 Bright Blue
255 0 0 Bright Red
255 0 255 Bright Magenta
0 255 0 Bright Green
0 255 255 Bright Cyan
255 255 0 Bright Yellow
255 255 255 Bright White

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -77,6 +77,9 @@
<color id="timeline_padding" value="#7d929e" /> <color id="timeline_padding" value="#7d929e" />
<color id="status_bar_text" value="#2e3234" /> <color id="status_bar_text" value="#2e3234" />
<color id="status_bar_face" value="#7d929e" /> <color id="status_bar_face" value="#7d929e" />
<color id="flag_normal" value="#d3cbbe" />
<color id="flag_active" value="#ff0000" />
<color id="flag_clicked" value="#7d929e" />
</colors> </colors>
<cursors> <cursors>
@ -317,6 +320,14 @@
<part id="timeline_padding_br" x="288" y="24" w1="1" w2="10" w3="1" h1="1" h2="10" h3="1" /> <part id="timeline_padding_br" x="288" y="24" w1="1" w2="10" w3="1" h1="1" h2="10" h3="1" />
<part id="timeline_drop_layer_deco" x="252" y="127" w1="3" w2="1" w3="3" h1="2" h2="1" h3="2" /> <part id="timeline_drop_layer_deco" x="252" y="127" w1="3" w2="1" w3="3" h1="2" h2="1" h3="2" />
<part id="timeline_drop_frame_deco" x="252" y="120" w1="2" w2="1" w3="2" h1="3" h2="1" h3="3" /> <part id="timeline_drop_frame_deco" x="252" y="120" w1="2" w2="1" w3="2" h1="3" h2="1" h3="3" />
<part id="timeline_loop_range" x="240" y="132" w1="3" w2="6" w3="3" h1="3" h2="6" h3="3" />
<part id="flag_normal" x="0" y="240" w="16" h="10" />
<part id="flag_highlight" x="16" y="240" w="16" h="10" />
<part id="drop_pixels_ok" x="176" y="176" w="7" h="8" />
<part id="drop_pixels_ok_selected" x="176" y="184" w="7" h="8" />
<part id="drop_pixels_cancel" x="192" y="176" w="7" h="8" />
<part id="drop_pixels_cancel_selected" x="192" y="184" w="7" h="8" />
<part id="warning_box" x="112" y="80" w="9" h="10" />
</parts> </parts>
<stylesheet> <stylesheet>
@ -519,6 +530,31 @@
<background part="timeline_drop_frame_deco" /> <background part="timeline_drop_frame_deco" />
</style> </style>
<!-- timeline_loop_range -->
<style id="timeline_loop_range">
<background part="timeline_loop_range" />
</style>
<!-- flag -->
<style id="flag">
<background part="flag_normal" color="flag_normal" />
</style>
<style id="flag:active">
<background part="flag_highlight" color="flag_active" />
</style>
<style id="flag:clicked">
<background part="flag_highlight" color="flag_clicked" />
</style>
<!-- warning_box -->
<style id="warning_box">
<background color="face" />
<icon part="warning_box" align="center" valign="middle" />
</style>
<style id="warning_box:hover">
<background color="hot_face" />
</style>
</stylesheet> </stylesheet>
</skin> </skin>

View File

@ -15,11 +15,11 @@
<separator text="Color Mode:" left="true" horizontal="true" /> <separator text="Color Mode:" left="true" horizontal="true" />
<box vertical="true" homogeneous="true" childspacing="0"> <box vertical="true" homogeneous="true" childspacing="0">
<box horizontal="true"> <box horizontal="true">
<radio id="radio3" text="&amp;Indexed with " group="1" tooltip="Using a palette of 256 colors&#10;(8 bits per pixel)" /> <radio id="radio3" text="&amp;Indexed color" group="1" tooltip="Using a palette of 256 colors&#10;(8 bits per pixel)" />
<entry id="colors" maxsize="8" tooltip="Maximum number of colors&#10;(only for Indexed images)&#10;&#10;This field cannot be modified in this beta version." disabled="true" /> <!-- <entry id="colors" maxsize="8" tooltip="Maximum number of colors&#10;(only for Indexed images)&#10;&#10;This field cannot be modified in this beta version." disabled="true" /> -->
<label text="Colors" /> <!-- <label text="Colors" /> -->
</box> </box>
<radio id="radio1" text="&amp;RGB Color" group="1" tooltip="RGBA color mode&#10;(32 bits per pixel)" /> <radio id="radio1" text="&amp;RGB color" group="1" tooltip="RGBA color mode&#10;(32 bits per pixel)" />
<radio id="radio2" text="&amp;Grayscale" group="1" tooltip="Value and Alpha&#10;(16 bits per pixel)" /> <radio id="radio2" text="&amp;Grayscale" group="1" tooltip="Value and Alpha&#10;(16 bits per pixel)" />
</box> </box>

View File

@ -2,32 +2,29 @@
<!-- Copyright (C) 2001-2013 by David Capello --> <!-- Copyright (C) 2001-2013 by David Capello -->
<gui> <gui>
<window text="Sprite Properties" id="sprite_properties"> <window text="Sprite Properties" id="sprite_properties">
<box vertical="true"> <vbox>
<box horizontal="true"> <grid columns="2">
<grid columns="2" expansive="true"> <label text="File name:" />
<entry text="" id="name" maxsize="256" minwidth="64" readonly="true" cell_align="horizontal" />
<label text="File name:" /> <label text="Type:" />
<entry text="" id="name" maxsize="256" minwidth="64" readonly="true" cell_align="horizontal" /> <label text="" id="type" />
<label text="Type:" /> <label text="Size:" />
<label text="" id="type" /> <label text="" id="size" />
<label text="Size:" /> <label text="Frames:" />
<label text="" id="size" /> <label text="" id="frames" />
<label text="Frames:" /> <label text="Transparent Color:" />
<label text="" id="frames" /> <hbox id="box_transparent" tooltip="Palette entry used as&#10;transparent color in each&#10;layer (only for indexed images)." />
</grid>
<label text="Transparent Color:" />
<box horizontal="true" id="box_transparent" tooltip="Palette entry used as transparent color in each layer (only for indexed images)." />
</grid>
</box>
<separator horizontal="true" /> <separator horizontal="true" />
<box horizontal="true"> <hbox>
<box horizontal="true" expansive="true" /> <boxfiller />
<button text="&amp;OK" closewindow="true" id="ok" magnet="true" width="60" /> <button text="&amp;OK" closewindow="true" id="ok" magnet="true" width="60" />
<button text="&amp;Cancel" closewindow="true" id="cancel" width="60" /> <button text="&amp;Cancel" closewindow="true" id="cancel" width="60" />
</box> </hbox>
</box> </vbox>
</window> </window>
</gui> </gui>

View File

@ -0,0 +1,31 @@
<!-- ASEPRITE -->
<!-- Copyright (C) 2014 by David Capello -->
<gui>
<vbox id="mainbox">
<separator cell_hspan="2" 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" width="60" />
</hbox>
<label text="Opacity:" />
<slider min="0" max="255" id="opacity" cell_align="horizontal" width="128" />
<label text="Opacity Step:" />
<slider min="0" max="255" id="opacity_step" cell_align="horizontal" width="128" />
</grid>
<separator text="Loop:" left="true" horizontal="true" />
<hbox cell_hspan="2">
<radio group="2" text="Normal" id="normal" />
<radio group="2" text="Reverse" id="reverse" />
<radio group="2" text="Ping-pong" id="pingpong" />
</hbox>
<hbox cell_hspan="2">
<button id="loop_section" text="Set Loop Section" expansive="true" tooltip="Select a range of frames in the timeline&#10;and then press this button." />
<button id="reset_loop_section" text="Reset Loop Section" />
</hbox>
</vbox>
</gui>

View File

@ -16,14 +16,6 @@ if [ ! -d $destdir ] ; then
git clone --depth=1 $srcdir $destdir git clone --depth=1 $srcdir $destdir
fi fi
# ----------------------------
# Copy the quick reference PDF
# ----------------------------
if [ ! -f $destdir/docs ] ; then
cp $srcdir/docs/quickref.pdf $destdir/docs
fi
# -------------- # --------------
# Update version # Update version
# -------------- # --------------

View File

@ -92,6 +92,10 @@ if (CMAKE_USE_PTHREADS_INIT)
set(sys_libs ${sys_libs} ${CMAKE_THREAD_LIBS_INIT}) set(sys_libs ${sys_libs} ${CMAKE_THREAD_LIBS_INIT})
endif() endif()
if(NOT "${CUSTOM_WEBSITE_URL}" STREQUAL "")
add_definitions(-DCUSTOM_WEBSITE_URL="${CUSTOM_WEBSITE_URL}")
endif()
if(ENABLE_UPDATER) if(ENABLE_UPDATER)
if(USE_SHARED_CURL) if(USE_SHARED_CURL)
find_library(LIBCURL_LIBRARY NAMES curl) find_library(LIBCURL_LIBRARY NAMES curl)

View File

@ -10,3 +10,5 @@ Changes:
* Added resize support for Windows, X11, and Mac OS X ports. * Added resize support for Windows, X11, and Mac OS X ports.
* Removed code and functions that are not used (Allegro GUI, * Removed code and functions that are not used (Allegro GUI,
audio, MIDI, joystick, etc.). audio, MIDI, joystick, etc.).
* The HWND class has CS_DBLCLKS enabled (so UI code can detect
double-clicks from Windows messages).

View File

@ -205,7 +205,7 @@ static void paint_win(RECT *rect)
/* we may have lost the DirectDraw surfaces /* we may have lost the DirectDraw surfaces
* (e.g after the monitor has gone to low power) * (e.g after the monitor has gone to low power)
*/ */
if (IDirectDrawSurface2_IsLost(gfx_directx_primary_surface->id)) if (IDirectDrawSurface2_IsLost(gfx_directx_primary_surface->id) == DDERR_SURFACELOST)
switch_in_win(); switch_in_win();
/* clip the rectangle */ /* clip the rectangle */

View File

@ -427,7 +427,7 @@ static HWND create_directx_window(void)
if (first) { if (first) {
/* setup the window class */ /* setup the window class */
wnd_class.style = CS_HREDRAW | CS_VREDRAW; wnd_class.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
wnd_class.lpfnWndProc = directx_wnd_proc; wnd_class.lpfnWndProc = directx_wnd_proc;
wnd_class.cbClsExtra = 0; wnd_class.cbClsExtra = 0;
wnd_class.cbWndExtra = 0; wnd_class.cbWndExtra = 0;

View File

@ -18,8 +18,8 @@ add_library(app-lib
commands/cmd_canvas_size.cpp commands/cmd_canvas_size.cpp
commands/cmd_cel_properties.cpp commands/cmd_cel_properties.cpp
commands/cmd_change_color.cpp commands/cmd_change_color.cpp
commands/cmd_change_image_type.cpp
commands/cmd_change_pen.cpp commands/cmd_change_pen.cpp
commands/cmd_change_pixel_format.cpp
commands/cmd_clear.cpp commands/cmd_clear.cpp
commands/cmd_close_file.cpp commands/cmd_close_file.cpp
commands/cmd_configure_tools.cpp commands/cmd_configure_tools.cpp
@ -56,6 +56,7 @@ add_library(app-lib
commands/cmd_new_frame.cpp commands/cmd_new_frame.cpp
commands/cmd_new_layer.cpp commands/cmd_new_layer.cpp
commands/cmd_new_layer_set.cpp commands/cmd_new_layer_set.cpp
commands/cmd_onionskin.cpp
commands/cmd_open_file.cpp commands/cmd_open_file.cpp
commands/cmd_open_in_folder.cpp commands/cmd_open_in_folder.cpp
commands/cmd_open_with_app.cpp commands/cmd_open_with_app.cpp
@ -125,6 +126,7 @@ add_library(app-lib
flatten.cpp flatten.cpp
gfxmode.cpp gfxmode.cpp
gui_xml.cpp gui_xml.cpp
handle_anidir.cpp
ini_file.cpp ini_file.cpp
job.cpp job.cpp
launcher.cpp launcher.cpp
@ -154,7 +156,9 @@ add_library(app-lib
ui/color_button.cpp ui/color_button.cpp
ui/color_selector.cpp ui/color_selector.cpp
ui/color_sliders.cpp ui/color_sliders.cpp
ui/configure_timeline_popup.cpp
ui/context_bar.cpp ui/context_bar.cpp
ui/devconsole_view.cpp
ui/document_view.cpp ui/document_view.cpp
ui/drop_down_button.cpp ui/drop_down_button.cpp
ui/editor/cursor.cpp ui/editor/cursor.cpp
@ -179,6 +183,7 @@ add_library(app-lib
ui/main_menu_bar.cpp ui/main_menu_bar.cpp
ui/main_window.cpp ui/main_window.cpp
ui/mini_editor.cpp ui/mini_editor.cpp
ui/notifications.cpp
ui/palette_listbox.cpp ui/palette_listbox.cpp
ui/palette_popup.cpp ui/palette_popup.cpp
ui/palette_view.cpp ui/palette_view.cpp
@ -228,6 +233,7 @@ add_library(app-lib
undoers/set_palette_colors.cpp undoers/set_palette_colors.cpp
undoers/set_sprite_pixel_format.cpp undoers/set_sprite_pixel_format.cpp
undoers/set_sprite_size.cpp undoers/set_sprite_size.cpp
undoers/set_sprite_transparent_color.cpp
undoers/set_stock_pixel_format.cpp undoers/set_stock_pixel_format.cpp
undoers/set_total_frames.cpp undoers/set_total_frames.cpp
util/autocrop.cpp util/autocrop.cpp

View File

@ -145,9 +145,9 @@ App::App(int argc, const char* argv[])
RenderEngine::loadConfig(); RenderEngine::loadConfig();
// Default palette. // Default palette.
base::string palFile(!options.paletteFileName().empty() ? std::string palFile(!options.paletteFileName().empty() ?
options.paletteFileName(): options.paletteFileName():
base::string(get_config_string("GfxMode", "Palette", ""))); std::string(get_config_string("GfxMode", "Palette", "")));
if (palFile.empty()) { if (palFile.empty()) {
// Try to use a default pixel art palette. // Try to use a default pixel art palette.
@ -294,6 +294,9 @@ App::~App()
// Remove Aseprite handlers // Remove Aseprite handlers
PRINTF("ASE: Uninstalling\n"); PRINTF("ASE: Uninstalling\n");
// Delete file formats.
FileFormatsManager::destroyInstance();
// Fire App Exit signal. // Fire App Exit signal.
App::instance()->Exit(); App::instance()->Exit();
@ -328,6 +331,11 @@ RecentFiles* App::getRecentFiles() const
return &m_modules->m_recent_files; return &m_modules->m_recent_files;
} }
void App::showNotification(const char* text, const char* url)
{
m_mainWindow->showNotification(text, url);
}
// Updates palette and redraw the screen. // Updates palette and redraw the screen.
void app_refresh_screen() void app_refresh_screen()
{ {
@ -374,12 +382,15 @@ void app_default_statusbar_message()
int app_get_color_to_clear_layer(Layer* layer) int app_get_color_to_clear_layer(Layer* layer)
{ {
/* all transparent layers are cleared with the mask color */ ASSERT(layer != NULL);
app::Color color = app::Color::fromMask();
/* the `Background' is erased with the `Background Color' */ app::Color color;
if (layer != NULL && layer->isBackground())
// The `Background' is erased with the `Background Color'
if (layer->isBackground())
color = ColorBar::instance()->getBgColor(); color = ColorBar::instance()->getBgColor();
else // All transparent layers are cleared with the mask color
color = app::Color::fromMask();
return color_utils::color_for_layer(color, layer); return color_utils::color_for_layer(color, layer);
} }

View File

@ -26,6 +26,7 @@
#include "base/unique_ptr.h" #include "base/unique_ptr.h"
#include "raster/pixel_format.h" #include "raster/pixel_format.h"
#include <string>
#include <vector> #include <vector>
namespace ui { namespace ui {
@ -70,6 +71,8 @@ namespace app {
RecentFiles* getRecentFiles() const; RecentFiles* getRecentFiles() const;
MainWindow* getMainWindow() const { return m_mainWindow; } MainWindow* getMainWindow() const { return m_mainWindow; }
void showNotification(const char* text, const char* url);
// App Signals // App Signals
Signal0<void> Exit; Signal0<void> Exit;
Signal0<void> PaletteChange; Signal0<void> PaletteChange;
@ -80,7 +83,7 @@ namespace app {
Signal0<void> CurrentToolChange; Signal0<void> CurrentToolChange;
private: private:
typedef std::vector<base::string> FileList; typedef std::vector<std::string> FileList;
class Modules; class Modules;
static App* m_instance; static App* m_instance;

View File

@ -24,7 +24,7 @@
namespace app { namespace app {
Backup::Backup(const base::string& path) Backup::Backup(const std::string& path)
: m_path(path) : m_path(path)
{ {
} }

View File

@ -21,14 +21,15 @@
#pragma once #pragma once
#include "base/disable_copying.h" #include "base/disable_copying.h"
#include "base/string.h"
#include <string>
namespace app { namespace app {
// A class to record/restore backup information. // A class to record/restore backup information.
class Backup { class Backup {
public: public:
Backup(const base::string& path); Backup(const std::string& path);
~Backup(); ~Backup();
// Returns true if there are items that can be restored. // Returns true if there are items that can be restored.
@ -37,7 +38,7 @@ namespace app {
private: private:
DISABLE_COPYING(Backup); DISABLE_COPYING(Backup);
base::string m_path; std::string m_path;
}; };
} // namespace app } // namespace app

View File

@ -24,8 +24,8 @@
#include "app/check_update.h" #include "app/check_update.h"
#include "app/app.h"
#include "app/ini_file.h" #include "app/ini_file.h"
#include "app/ui/status_bar.h"
#include "base/bind.h" #include "base/bind.h"
#include <ctime> #include <ctime>
@ -169,7 +169,7 @@ void CheckUpdateThreadLauncher::onMonitoringTick()
case updater::CheckUpdateResponse::Critical: case updater::CheckUpdateResponse::Critical:
case updater::CheckUpdateResponse::Major: case updater::CheckUpdateResponse::Major:
StatusBar::instance()->showNotification("New Version!", m_response.getUrl().c_str()); App::instance()->showNotification("New Version Available!", m_response.getUrl().c_str());
break; break;
} }

View File

@ -601,14 +601,10 @@ int Color::getIndex() const
return 0; return 0;
case Color::RgbType: case Color::RgbType:
PRINTF("Getting `index' from a RGB color\n"); // TODO return get_current_palette()->findBestfit(getRed(), getGreen(), getBlue());
ASSERT(false);
break;
case Color::HsvType: case Color::HsvType:
PRINTF("Getting `index' from a HSV color\n"); // TODO return get_current_palette()->findBestfit(getRed(), getGreen(), getBlue());
ASSERT(false);
break;
case Color::GrayType: case Color::GrayType:
return m_value.gray; return m_value.gray;

64
src/app/color_target.h Normal file
View File

@ -0,0 +1,64 @@
/* Aseprite
* Copyright (C) 2001-2014 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef APP_COLOR_TARGET_H_INCLUDED
#define APP_COLOR_TARGET_H_INCLUDED
#pragma once
#include "raster/color.h"
#include "raster/layer.h"
#include "raster/pixel_format.h"
#include "raster/sprite.h"
namespace app {
// Represents the kind of surface where we'll use a color.
class ColorTarget {
public:
enum LayerType {
BackgroundLayer,
TransparentLayer
};
ColorTarget(LayerType layerType, raster::PixelFormat pixelFormat, raster::color_t maskColor) :
m_layerType(layerType),
m_pixelFormat(pixelFormat),
m_maskColor(maskColor) {
}
ColorTarget(raster::Layer* layer) :
m_layerType(layer->isBackground() ? BackgroundLayer: TransparentLayer),
m_pixelFormat(layer->getSprite()->getPixelFormat()),
m_maskColor(layer->getSprite()->getTransparentColor()) {
}
bool isBackground() const { return m_layerType == BackgroundLayer; }
bool isTransparent() const { return m_layerType == TransparentLayer; }
LayerType layerType() const { return m_layerType; }
raster::PixelFormat pixelFormat() const { return m_pixelFormat; }
raster::color_t maskColor() const { return m_maskColor; }
private:
LayerType m_layerType;
raster::PixelFormat m_pixelFormat;
raster::color_t m_maskColor;
};
} // namespace app
#endif

View File

@ -1,5 +1,5 @@
/* Aseprite /* Aseprite
* Copyright (C) 2001-2013 David Capello * Copyright (C) 2001-2014 David Capello
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -168,10 +168,7 @@ raster::color_t color_utils::color_for_image(const app::Color& color, PixelForma
c = graya(color.getGray(), 255); c = graya(color.getGray(), 255);
break; break;
case IMAGE_INDEXED: case IMAGE_INDEXED:
if (color.getType() == app::Color::IndexType) c = color.getIndex();
c = color.getIndex();
else
c = get_current_palette()->findBestfit(color.getRed(), color.getGreen(), color.getBlue());
break; break;
} }
@ -180,44 +177,40 @@ raster::color_t color_utils::color_for_image(const app::Color& color, PixelForma
raster::color_t color_utils::color_for_layer(const app::Color& color, Layer* layer) raster::color_t color_utils::color_for_layer(const app::Color& color, Layer* layer)
{ {
raster::color_t pixel_color; return color_for_target(color, ColorTarget(layer));
if (color.getType() == app::Color::MaskType) {
pixel_color = layer->getSprite()->getTransparentColor();
}
else {
PixelFormat format = layer->getSprite()->getPixelFormat();
pixel_color = color_for_image(color, format);
}
return fixup_color_for_layer(layer, pixel_color);
} }
raster::color_t color_utils::fixup_color_for_layer(Layer *layer, raster::color_t color) raster::color_t color_utils::color_for_target(const app::Color& color, const ColorTarget& colorTarget)
{ {
if (layer->isBackground()) if (color.getType() == app::Color::MaskType)
return fixup_color_for_background(layer->getSprite()->getPixelFormat(), color); return colorTarget.maskColor();
else
return color;
}
raster::color_t color_utils::fixup_color_for_background(PixelFormat format, raster::color_t color) raster::color_t c = -1;
{
switch (format) { switch (colorTarget.pixelFormat()) {
case IMAGE_RGB: case IMAGE_RGB:
if (rgba_geta(color) < 255) { c = rgba(color.getRed(), color.getGreen(), color.getBlue(), 255);
return rgba(rgba_getr(color),
rgba_getg(color),
rgba_getb(color), 255);
}
break; break;
case IMAGE_GRAYSCALE: case IMAGE_GRAYSCALE:
if (graya_geta(color) < 255) { c = graya(color.getGray(), 255);
return graya(graya_getv(color), 255); break;
case IMAGE_INDEXED:
if (color.getType() == app::Color::IndexType) {
c = color.getIndex();
}
else {
c = get_current_palette()->findBestfit(
color.getRed(),
color.getGreen(),
color.getBlue(),
colorTarget.isTransparent() ?
colorTarget.maskColor(): // Don't return the mask color
-1); // Return any color, we are in a background layer.
} }
break; break;
} }
return color;
return c;
} }
} // namespace app } // namespace app

View File

@ -1,5 +1,5 @@
/* Aseprite /* Aseprite
* Copyright (C) 2001-2013 David Capello * Copyright (C) 2001-2014 David Capello
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -21,6 +21,7 @@
#pragma once #pragma once
#include "app/color.h" #include "app/color.h"
#include "app/color_target.h"
#include "raster/color.h" #include "raster/color.h"
#include "raster/pixel_format.h" #include "raster/pixel_format.h"
#include "ui/color.h" #include "ui/color.h"
@ -39,9 +40,7 @@ namespace app {
int color_for_allegro(const app::Color& color, int depth); int color_for_allegro(const app::Color& color, int depth);
raster::color_t color_for_image(const app::Color& color, raster::PixelFormat format); raster::color_t color_for_image(const app::Color& color, raster::PixelFormat format);
raster::color_t color_for_layer(const app::Color& color, raster::Layer* layer); raster::color_t color_for_layer(const app::Color& color, raster::Layer* layer);
raster::color_t color_for_target(const app::Color& color, const ColorTarget& colorTarget);
raster::color_t fixup_color_for_layer(raster::Layer* layer, raster::color_t color);
raster::color_t fixup_color_for_background(raster::PixelFormat format, raster::color_t color);
} // namespace color_utils } // namespace color_utils
} // namespace app } // namespace app

View File

@ -68,16 +68,22 @@ void BackgroundFromLayerCommand::onExecute(Context* context)
Document* document(writer.document()); Document* document(writer.document());
Sprite* sprite(writer.sprite()); Sprite* sprite(writer.sprite());
// each frame of the layer to be converted as `Background' must be raster::color_t bgcolor =
// cleared using the selected background color in the color-bar color_utils::color_for_target(
int bgcolor = color_utils::color_for_image(context->getSettings()->getBgColor(), sprite->getPixelFormat()); context->getSettings()->getBgColor(),
bgcolor = color_utils::fixup_color_for_background(sprite->getPixelFormat(), bgcolor); ColorTarget(
ColorTarget::BackgroundLayer,
sprite->getPixelFormat(),
sprite->getTransparentColor()));
{ {
UndoTransaction undo_transaction(writer.context(), "Background from Layer"); UndoTransaction undo_transaction(writer.context(), "Background from Layer");
document->getApi().backgroundFromLayer(static_cast<LayerImage*>(writer.layer()), bgcolor); document->getApi().backgroundFromLayer(
static_cast<LayerImage*>(writer.layer()),
bgcolor);
undo_transaction.commit(); undo_transaction.commit();
} }
update_screen_for_document(document); update_screen_for_document(document);
} }

View File

@ -23,6 +23,7 @@
#include "app/commands/command.h" #include "app/commands/command.h"
#include "app/commands/commands.h" #include "app/commands/commands.h"
#include "app/commands/params.h"
#include "app/context.h" #include "app/context.h"
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
@ -30,26 +31,52 @@ namespace app {
class CancelCommand : public Command { class CancelCommand : public Command {
public: public:
enum Type {
NoOp,
All,
};
CancelCommand(); CancelCommand();
Command* clone() const OVERRIDE { return new CancelCommand(*this); } Command* clone() const OVERRIDE { return new CancelCommand(*this); }
protected: protected:
void onLoadParams(Params* params);
void onExecute(Context* context); void onExecute(Context* context);
private:
Type m_type;
}; };
CancelCommand::CancelCommand() CancelCommand::CancelCommand()
: Command("Cancel", : Command("Cancel",
"Cancel", "Cancel",
CmdUIOnlyFlag) CmdUIOnlyFlag)
, m_type(NoOp)
{ {
} }
void CancelCommand::onLoadParams(Params* params)
{
std::string type = params->get("type");
if (type == "noop") m_type = NoOp;
else if (type == "all") m_type = All;
}
void CancelCommand::onExecute(Context* context) void CancelCommand::onExecute(Context* context)
{ {
if (context->checkFlags(ContextFlags::ActiveDocumentIsWritable | switch (m_type) {
ContextFlags::HasVisibleMask)) {
Command* cmd = CommandsModule::instance()->getCommandByName(CommandId::DeselectMask); case NoOp:
context->executeCommand(cmd); // Do nothing.
break;
case All:
if (context->checkFlags(ContextFlags::ActiveDocumentIsWritable |
ContextFlags::HasVisibleMask)) {
Command* cmd = CommandsModule::instance()->getCommandByName(CommandId::DeselectMask);
context->executeCommand(cmd);
}
break;
} }
} }

View File

@ -212,8 +212,12 @@ void CanvasSizeCommand::onExecute(Context* context)
Sprite* sprite = writer.sprite(); Sprite* sprite = writer.sprite();
UndoTransaction undoTransaction(writer.context(), "Canvas Size"); UndoTransaction undoTransaction(writer.context(), "Canvas Size");
DocumentApi api = document->getApi(); DocumentApi api = document->getApi();
int bgcolor = color_utils::color_for_image(context->getSettings()->getBgColor(), sprite->getPixelFormat()); raster::color_t bgcolor = color_utils::color_for_target(
bgcolor = color_utils::fixup_color_for_background(sprite->getPixelFormat(), bgcolor); context->getSettings()->getBgColor(),
ColorTarget(
ColorTarget::BackgroundLayer,
sprite->getPixelFormat(),
sprite->getTransparentColor()));
api.cropSprite(sprite, gfx::Rect(x1, y1, x2-x1, y2-y1), bgcolor); api.cropSprite(sprite, gfx::Rect(x1, y1, x2-x1, y2-y1), bgcolor);
undoTransaction.commit(); undoTransaction.commit();

View File

@ -23,11 +23,11 @@
#include "app/app.h" #include "app/app.h"
#include "app/commands/command.h" #include "app/commands/command.h"
#include "app/context_access.h" #include "app/context_access.h"
#include "app/document_api.h"
#include "app/find_widget.h" #include "app/find_widget.h"
#include "app/load_widget.h" #include "app/load_widget.h"
#include "app/modules/gui.h" #include "app/modules/gui.h"
#include "app/undo_transaction.h" #include "app/undo_transaction.h"
#include "app/undoers/set_cel_opacity.h"
#include "base/mem_utils.h" #include "base/mem_utils.h"
#include "raster/cel.h" #include "raster/cel.h"
#include "raster/image.h" #include "raster/image.h"
@ -129,22 +129,21 @@ void CelPropertiesCommand::onExecute(Context* context)
if (window->getKiller() == button_ok) { if (window->getKiller() == button_ok) {
ContextWriter writer(reader); ContextWriter writer(reader);
Document* document_writer = writer.document(); Document* document_writer = writer.document();
Sprite* sprite_writer = writer.sprite();
Cel* cel_writer = writer.cel(); Cel* cel_writer = writer.cel();
int new_opacity = slider_opacity->getValue(); int newOpacity = slider_opacity->getValue();
// The opacity was changed? // The opacity was changed?
if (cel_writer != NULL && if (cel_writer != NULL &&
cel_writer->getOpacity() != new_opacity) { cel_writer->getOpacity() != newOpacity) {
UndoTransaction undo(writer.context(), "Cel Opacity Change", undo::ModifyDocument); DocumentApi api = document_writer->getApi();
if (undo.isEnabled()) { {
undo.pushUndoer(new undoers::SetCelOpacity(undo.getObjects(), cel_writer)); UndoTransaction undo(writer.context(), "Cel Opacity Change", undo::ModifyDocument);
api.setCelOpacity(sprite_writer, cel_writer, newOpacity);
undo.commit(); undo.commit();
} }
// Change cel opacity.
cel_writer->setOpacity(new_opacity);
update_screen_for_document(document_writer); update_screen_for_document(document_writer);
} }
} }

View File

@ -66,7 +66,7 @@ void ClearCommand::onExecute(Context* context)
{ {
// Clear of several frames is handled with RemoveCel command. // Clear of several frames is handled with RemoveCel command.
Timeline::Range range = App::instance()->getMainWindow()->getTimeline()->range(); Timeline::Range range = App::instance()->getMainWindow()->getTimeline()->range();
if (range.enabled()) { if (range.enabled() && (range.layers() > 1 || range.frames() > 1)) {
Command* subCommand = CommandsModule::instance() Command* subCommand = CommandsModule::instance()
->getCommandByName(CommandId::RemoveCel); ->getCommandByName(CommandId::RemoveCel);
context->executeCommand(subCommand); context->executeCommand(subCommand);

View File

@ -20,10 +20,14 @@
#include "config.h" #include "config.h"
#endif #endif
#include "app/app.h"
#include "app/commands/command.h" #include "app/commands/command.h"
#include "app/context.h" #include "app/context.h"
#include "app/document.h" #include "app/document.h"
#include "app/documents.h" #include "app/documents.h"
#include "app/ui/devconsole_view.h"
#include "app/ui/main_window.h"
#include "app/ui/workspace.h"
#include "ui/box.h" #include "ui/box.h"
#include "ui/button.h" #include "ui/button.h"
#include "ui/combobox.h" #include "ui/combobox.h"
@ -33,36 +37,6 @@ namespace app {
using namespace ui; using namespace ui;
class DeveloperConsole : public Window {
public:
DeveloperConsole()
: Window(WithTitleBar, "Developer Console")
, m_vbox(JI_VERTICAL)
{
m_vbox.addChild(&m_docs);
addChild(&m_vbox);
remapWindow();
centerWindow();
}
void updateDocuments(Context* context)
{
m_docs.removeAllItems();
m_docs.addItem("Documents");
for (Documents::const_iterator
it = context->getDocuments().begin(),
end = context->getDocuments().end(); it != end; ++it) {
m_docs.addItem((*it)->getFilename().c_str());
}
m_docs.addItem("---------");
}
private:
Box m_vbox;
ComboBox m_docs;
};
class DeveloperConsoleCommand : public Command { class DeveloperConsoleCommand : public Command {
public: public:
DeveloperConsoleCommand(); DeveloperConsoleCommand();
@ -71,7 +45,7 @@ public:
protected: protected:
void onExecute(Context* context); void onExecute(Context* context);
DeveloperConsole* m_devConsole; DevConsoleView* m_devConsole;
}; };
DeveloperConsoleCommand::DeveloperConsoleCommand() DeveloperConsoleCommand::DeveloperConsoleCommand()
@ -84,21 +58,19 @@ DeveloperConsoleCommand::DeveloperConsoleCommand()
DeveloperConsoleCommand::~DeveloperConsoleCommand() DeveloperConsoleCommand::~DeveloperConsoleCommand()
{ {
// delete m_devConsole; delete m_devConsole;
} }
void DeveloperConsoleCommand::onExecute(Context* context) void DeveloperConsoleCommand::onExecute(Context* context)
{ {
if (!m_devConsole) { if (!m_devConsole) {
m_devConsole = new DeveloperConsole(); m_devConsole = new DevConsoleView();
}
else if (m_devConsole->isVisible()) { App::instance()->getMainWindow()->getWorkspace()->addView(m_devConsole);
m_devConsole->closeWindow(NULL);
return;
} }
m_devConsole->updateDocuments(context); App::instance()->getMainWindow()->getTabsBar()->selectTab(m_devConsole);
m_devConsole->openWindow(); App::instance()->getMainWindow()->getWorkspace()->setActiveView(m_devConsole);
} }
Command* CommandFactory::createDeveloperConsoleCommand() Command* CommandFactory::createDeveloperConsoleCommand()

View File

@ -73,7 +73,7 @@ void DuplicateSpriteCommand::onExecute(Context* context)
dst_name = window->findChild("dst_name"); dst_name = window->findChild("dst_name");
flatten = window->findChild("flatten"); flatten = window->findChild("flatten");
base::string fn = document->getFilename(); std::string fn = document->getFilename();
src_name->setText(base::get_file_name(fn)); src_name->setText(base::get_file_name(fn));
dst_name->setText(base::get_file_title(fn) + " Copy." + base::get_file_extension(fn)); dst_name->setText(base::get_file_title(fn) + " Copy." + base::get_file_extension(fn));

View File

@ -92,7 +92,7 @@ public:
hbox1->addChild(hbox2); hbox1->addChild(hbox2);
hbox2->addChild(&m_export); hbox2->addChild(&m_export);
hbox2->addChild(&m_cancel); hbox2->addChild(&m_cancel);
jwidget_set_min_size(&m_export, 60, 0); m_export.setMinSize(gfx::Size(60, 0));
m_grid.addChildInCell(hbox1, 4, 1, 0); m_grid.addChildInCell(hbox1, 4, 1, 0);
} }

View File

@ -104,7 +104,7 @@ void FlipCommand::onExecute(Context* context)
// If the mask isn't a rectangular area, we've to flip the mask too. // If the mask isn't a rectangular area, we've to flip the mask too.
if (mask->getBitmap() != NULL && !mask->isRectangular()) { if (mask->getBitmap() != NULL && !mask->isRectangular()) {
int bgcolor = app_get_color_to_clear_layer(writer.layer()); raster::color_t bgcolor = app_get_color_to_clear_layer(writer.layer());
// Flip the portion of image specified by the mask. // Flip the portion of image specified by the mask.
mask->offsetOrigin(-x, -y); mask->offsetOrigin(-x, -y);

View File

@ -90,7 +90,7 @@ public:
hbox1->addChild(hbox2); hbox1->addChild(hbox2);
hbox2->addChild(&m_import); hbox2->addChild(&m_import);
hbox2->addChild(&m_cancel); hbox2->addChild(&m_cancel);
jwidget_set_min_size(&m_import, 60, 0); m_import.setMinSize(gfx::Size(60, 0));
m_grid.addChildInCell(hbox1, 4, 1, 0); m_grid.addChildInCell(hbox1, 4, 1, 0);
} }

View File

@ -63,6 +63,10 @@ void LaunchCommand::onLoadParams(Params* params)
m_type = Url; m_type = Url;
m_path = params->get("path"); m_path = params->get("path");
if (m_type == Url && !m_path.empty() && m_path[0] == '/') {
m_path = WEBSITE + m_path.substr(1);
}
} }
void LaunchCommand::onExecute(Context* context) void LaunchCommand::onExecute(Context* context)

View File

@ -74,7 +74,7 @@ void LayerPropertiesCommand::onExecute(Context* context)
button_ok->Click.connect(Bind<void>(&Window::closeWindow, window.get(), button_ok)); button_ok->Click.connect(Bind<void>(&Window::closeWindow, window.get(), button_ok));
button_cancel->Click.connect(Bind<void>(&Window::closeWindow, window.get(), button_cancel)); button_cancel->Click.connect(Bind<void>(&Window::closeWindow, window.get(), button_cancel));
jwidget_set_min_size(entry_name, 128, 0); entry_name->setMinSize(gfx::Size(128, 0));
entry_name->setExpansive(true); entry_name->setExpansive(true);
box2->addChild(label_name); box2->addChild(label_name);

View File

@ -70,7 +70,7 @@ void LoadMaskCommand::onExecute(Context* context)
{ {
const ContextReader reader(context); const ContextReader reader(context);
base::string filename = m_filename; std::string filename = m_filename;
if (context->isUiAvailable()) { if (context->isUiAvailable()) {
filename = app::show_file_selector("Load .msk File", filename, "msk"); filename = app::show_file_selector("Load .msk File", filename, "msk");

View File

@ -52,7 +52,7 @@ LoadPaletteCommand::LoadPaletteCommand()
void LoadPaletteCommand::onExecute(Context* context) void LoadPaletteCommand::onExecute(Context* context)
{ {
base::string filename = app::show_file_selector("Load Palette", "", "png,pcx,bmp,tga,lbm,col,gpl"); std::string filename = app::show_file_selector("Load Palette", "", "png,pcx,bmp,tga,lbm,col,gpl");
if (!filename.empty()) { if (!filename.empty()) {
base::UniquePtr<raster::Palette> palette(raster::Palette::load(filename.c_str())); base::UniquePtr<raster::Palette> palette(raster::Palette::load(filename.c_str()));
if (!palette) { if (!palette) {

View File

@ -132,7 +132,7 @@ void MergeDownLayerCommand::onExecute(Context* context)
} }
// With destination // With destination
else { else {
int x1, y1, x2, y2, bgcolor; int x1, y1, x2, y2;
Image *new_image; Image *new_image;
// Merge down in the background layer // Merge down in the background layer
@ -141,7 +141,6 @@ void MergeDownLayerCommand::onExecute(Context* context)
y1 = 0; y1 = 0;
x2 = sprite->getWidth(); x2 = sprite->getWidth();
y2 = sprite->getHeight(); y2 = sprite->getHeight();
bgcolor = app_get_color_to_clear_layer(dst_layer);
} }
// Merge down in a transparent layer // Merge down in a transparent layer
else { else {
@ -149,9 +148,10 @@ void MergeDownLayerCommand::onExecute(Context* context)
y1 = MIN(src_cel->getY(), dst_cel->getY()); y1 = MIN(src_cel->getY(), dst_cel->getY());
x2 = MAX(src_cel->getX()+src_image->getWidth()-1, dst_cel->getX()+dst_image->getWidth()-1); x2 = MAX(src_cel->getX()+src_image->getWidth()-1, dst_cel->getX()+dst_image->getWidth()-1);
y2 = MAX(src_cel->getY()+src_image->getHeight()-1, dst_cel->getY()+dst_image->getHeight()-1); y2 = MAX(src_cel->getY()+src_image->getHeight()-1, dst_cel->getY()+dst_image->getHeight()-1);
bgcolor = 0;
} }
raster::color_t bgcolor = app_get_color_to_clear_layer(dst_layer);
new_image = raster::crop_image(dst_image, new_image = raster::crop_image(dst_image,
x1-dst_cel->getX(), x1-dst_cel->getX(),
y1-dst_cel->getY(), y1-dst_cel->getY(),

View File

@ -76,7 +76,7 @@ NewFileCommand::NewFileCommand()
void NewFileCommand::onExecute(Context* context) void NewFileCommand::onExecute(Context* context)
{ {
PixelFormat format; PixelFormat format;
int w, h, bg, ncolors; int w, h, bg, ncolors = raster::Palette::MaxColors;
char buf[1024]; char buf[1024];
app::Color bg_table[] = { app::Color bg_table[] = {
app::Color::fromMask(), app::Color::fromMask(),
@ -93,7 +93,7 @@ void NewFileCommand::onExecute(Context* context)
Widget* radio1 = app::find_widget<Widget>(window, "radio1"); Widget* radio1 = app::find_widget<Widget>(window, "radio1");
Widget* radio2 = app::find_widget<Widget>(window, "radio2"); Widget* radio2 = app::find_widget<Widget>(window, "radio2");
Widget* radio3 = app::find_widget<Widget>(window, "radio3"); Widget* radio3 = app::find_widget<Widget>(window, "radio3");
Widget* colors = app::find_widget<Widget>(window, "colors"); // Widget* colors = app::find_widget<Widget>(window, "colors");
ListBox* bg_box = app::find_widget<ListBox>(window, "bg_box"); ListBox* bg_box = app::find_widget<ListBox>(window, "bg_box");
Widget* ok = app::find_widget<Widget>(window, "ok_button"); Widget* ok = app::find_widget<Widget>(window, "ok_button");
@ -106,7 +106,7 @@ void NewFileCommand::onExecute(Context* context)
w = get_config_int("NewSprite", "Width", 320); w = get_config_int("NewSprite", "Width", 320);
h = get_config_int("NewSprite", "Height", 240); h = get_config_int("NewSprite", "Height", 240);
bg = get_config_int("NewSprite", "Background", 4); // Default = Background color bg = get_config_int("NewSprite", "Background", 4); // Default = Background color
ncolors = get_config_int("NewSprite", "Colors", 256); // ncolors = get_config_int("NewSprite", "Colors", 256);
// If the clipboard contains an image, we can show the size of the // If the clipboard contains an image, we can show the size of the
// clipboard as default image size. // clipboard as default image size.
@ -118,7 +118,7 @@ void NewFileCommand::onExecute(Context* context)
width->setTextf("%d", MAX(1, w)); width->setTextf("%d", MAX(1, w));
height->setTextf("%d", MAX(1, h)); height->setTextf("%d", MAX(1, h));
colors->setTextf("%d", MID(2, ncolors, 256)); // colors->setTextf("%d", MID(2, ncolors, 256));
// Select image-type // Select image-type
switch (format) { switch (format) {
@ -143,7 +143,7 @@ void NewFileCommand::onExecute(Context* context)
w = width->getTextInt(); w = width->getTextInt();
h = height->getTextInt(); h = height->getTextInt();
ncolors = colors->getTextInt(); // ncolors = colors->getTextInt();
bg = bg_box->getSelectedIndex(); bg = bg_box->getSelectedIndex();
w = MID(1, w, 65535); w = MID(1, w, 65535);
@ -174,7 +174,8 @@ void NewFileCommand::onExecute(Context* context)
(format == IMAGE_INDEXED ? ncolors: 256))); (format == IMAGE_INDEXED ? ncolors: 256)));
Sprite* sprite(document->getSprite()); Sprite* sprite(document->getSprite());
get_default_palette()->copyColorsTo(sprite->getPalette(FrameNumber(0))); if (sprite->getPixelFormat() != IMAGE_GRAYSCALE)
get_default_palette()->copyColorsTo(sprite->getPalette(FrameNumber(0)));
usprintf(buf, "Sprite-%04d", ++_sprite_counter); usprintf(buf, "Sprite-%04d", ++_sprite_counter);
document->setFilename(buf); document->setFilename(buf);
@ -190,7 +191,12 @@ void NewFileCommand::onExecute(Context* context)
layerImage->configureAsBackground(); layerImage->configureAsBackground();
Image* image = sprite->getStock()->getImage(layerImage->getCel(FrameNumber(0))->getImage()); Image* image = sprite->getStock()->getImage(layerImage->getCel(FrameNumber(0))->getImage());
raster::clear_image(image, color_utils::color_for_image(color, format)); raster::clear_image(image,
color_utils::color_for_target(color,
ColorTarget(
ColorTarget::BackgroundLayer,
sprite->getPixelFormat(),
sprite->getTransparentColor())));
} }
} }

View File

@ -60,11 +60,7 @@ NewFrameCommand::NewFrameCommand()
bool NewFrameCommand::onEnabled(Context* context) bool NewFrameCommand::onEnabled(Context* context)
{ {
return context->checkFlags(ContextFlags::ActiveDocumentIsWritable | return context->checkFlags(ContextFlags::ActiveDocumentIsWritable |
ContextFlags::HasActiveSprite | ContextFlags::HasActiveSprite);
ContextFlags::HasActiveLayer |
ContextFlags::ActiveLayerIsReadable |
ContextFlags::ActiveLayerIsWritable |
ContextFlags::ActiveLayerIsImage);
} }
void NewFrameCommand::onExecute(Context* context) void NewFrameCommand::onExecute(Context* context)

View File

@ -101,7 +101,7 @@ void NewLayerCommand::onExecute(Context* context)
base::UniquePtr<Window> window(app::load_widget<Window>("new_layer.xml", "new_layer")); base::UniquePtr<Window> window(app::load_widget<Window>("new_layer.xml", "new_layer"));
Widget* name_widget = app::find_widget<Widget>(window, "name"); Widget* name_widget = app::find_widget<Widget>(window, "name");
name_widget->setText(name.c_str()); name_widget->setText(name.c_str());
jwidget_set_min_size(name_widget, 128, 0); name_widget->setMinSize(gfx::Size(128, 0));
window->openWindowInForeground(); window->openWindowInForeground();

View File

@ -0,0 +1,67 @@
/* Aseprite
* Copyright (C) 2001-2014 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "app/app.h"
#include "app/commands/command.h"
#include "app/context.h"
#include "app/settings/document_settings.h"
#include "app/settings/settings.h"
#include "base/compiler_specific.h"
namespace app {
using namespace ui;
using namespace gfx;
class ShowOnionSkinCommand : public Command {
public:
ShowOnionSkinCommand()
: Command("ShowOnionSkin",
"Show Onion Skin",
CmdUIOnlyFlag)
{
}
Command* clone() const OVERRIDE { return new ShowOnionSkinCommand(*this); }
protected:
bool onChecked(Context* context)
{
IDocumentSettings* docSettings = context->getSettings()->getDocumentSettings(context->getActiveDocument());
return docSettings->getUseOnionskin();
}
void onExecute(Context* context)
{
IDocumentSettings* docSettings = context->getSettings()->getDocumentSettings(context->getActiveDocument());
docSettings->setUseOnionskin(docSettings->getUseOnionskin() ? false: true);
}
};
Command* CommandFactory::createShowOnionSkinCommand()
{
return new ShowOnionSkinCommand;
}
} // namespace app

View File

@ -69,7 +69,11 @@ public:
void showProgressWindow() { void showProgressWindow() {
startJob(); startJob();
fop_stop(m_fop);
if (isCanceled())
fop_stop(m_fop);
waitJob();
} }
private: private:

View File

@ -28,6 +28,7 @@
#include "app/commands/command.h" #include "app/commands/command.h"
#include "app/context.h" #include "app/context.h"
#include "app/context_access.h" #include "app/context_access.h"
#include "app/handle_anidir.h"
#include "app/modules/editors.h" #include "app/modules/editors.h"
#include "app/modules/gui.h" #include "app/modules/gui.h"
#include "app/modules/palettes.h" #include "app/modules/palettes.h"
@ -87,6 +88,7 @@ void PlayAnimationCommand::onExecute(Context* context)
IDocumentSettings* docSettings = context->getSettings()->getDocumentSettings(document); IDocumentSettings* docSettings = context->getSettings()->getDocumentSettings(document);
bool onionskin_state = docSettings->getUseOnionskin(); bool onionskin_state = docSettings->getUseOnionskin();
Palette *oldpal, *newpal; Palette *oldpal, *newpal;
bool pingPongForward = true;
if (sprite->getTotalFrames() < 2) if (sprite->getTotalFrames() < 2)
return; return;
@ -141,10 +143,12 @@ void PlayAnimationCommand::onExecute(Context* context)
} while (!done && (speed_timer <= 0)); } while (!done && (speed_timer <= 0));
if (!done) { if (!done) {
FrameNumber frame = current_editor->getFrame().next(); current_editor->setFrame(
if (frame > sprite->getLastFrame()) calculate_next_frame(
frame = FrameNumber(0); sprite,
current_editor->setFrame(frame); current_editor->getFrame(),
docSettings,
pingPongForward));
speed_timer--; speed_timer--;
} }

View File

@ -140,10 +140,13 @@ void PreviewCommand::onExecute(Context* context)
// Render sprite and leave the result in 'render' variable // Render sprite and leave the result in 'render' variable
if (render == NULL) { if (render == NULL) {
RenderEngine renderEngine(document, sprite, RenderEngine renderEngine(document, sprite,
editor->getLayer(), editor->getLayer(),
editor->getFrame()); editor->getFrame());
render.reset(renderEngine.renderSprite(0, 0, sprite->getWidth(), sprite->getHeight(),
editor->getFrame(), 0, false)); render.reset(
renderEngine.renderSprite(
0, 0, sprite->getWidth(), sprite->getHeight(),
editor->getFrame(), 0, false, false));
} }
// Redraw the screen // Redraw the screen

View File

@ -54,9 +54,11 @@ RemoveLayerCommand::RemoveLayerCommand()
bool RemoveLayerCommand::onEnabled(Context* context) bool RemoveLayerCommand::onEnabled(Context* context)
{ {
ContextWriter writer(context); return context->checkFlags(ContextFlags::ActiveDocumentIsWritable |
Sprite* sprite(writer.sprite()); ContextFlags::HasActiveSprite |
return (sprite != NULL); ContextFlags::HasActiveLayer |
ContextFlags::ActiveLayerIsReadable |
ContextFlags::ActiveLayerIsWritable);
} }
void RemoveLayerCommand::onExecute(Context* context) void RemoveLayerCommand::onExecute(Context* context)

View File

@ -204,6 +204,7 @@ void RotateCanvasCommand::onExecute(Context* context)
{ {
RotateCanvasJob job(reader, m_angle); RotateCanvasJob job(reader, m_angle);
job.startJob(); job.startJob();
job.waitJob();
} }
reader.document()->generateMaskBoundaries(); reader.document()->generateMaskBoundaries();
update_screen_for_document(reader.document()); update_screen_for_document(reader.document());

View File

@ -53,7 +53,12 @@ public:
void showProgressWindow() { void showProgressWindow() {
startJob(); startJob();
fop_stop(m_fop);
if (isCanceled()) {
fop_stop(m_fop);
}
waitJob();
} }
private: private:
@ -88,6 +93,14 @@ static void save_document_in_background(Document* document, bool mark_as_saved)
if (fop->has_error()) { if (fop->has_error()) {
Console console; Console console;
console.printf(fop->error.c_str()); console.printf(fop->error.c_str());
// We don't know if the file was saved correctly or not. So mark
// it as it should be saved again.
document->impossibleToBackToSavedState();
}
// If the job was cancelled, mark the document as modified.
else if (fop_is_stop(fop)) {
document->impossibleToBackToSavedState();
} }
else { else {
App::instance()->getRecentFiles()->addRecentFile(document->getFilename().c_str()); App::instance()->getRecentFiles()->addRecentFile(document->getFilename().c_str());
@ -122,7 +135,7 @@ protected:
void saveAsDialog(const ContextReader& reader, const char* dlgTitle, bool markAsSaved) void saveAsDialog(const ContextReader& reader, const char* dlgTitle, bool markAsSaved)
{ {
const Document* document = reader.document(); const Document* document = reader.document();
base::string filename; std::string filename;
if (!m_filename.empty()) { if (!m_filename.empty()) {
filename = m_filename; filename = m_filename;
@ -134,7 +147,7 @@ protected:
get_writable_extensions(exts, sizeof(exts)); get_writable_extensions(exts, sizeof(exts));
for (;;) { for (;;) {
base::string newfilename = app::show_file_selector(dlgTitle, filename, exts); std::string newfilename = app::show_file_selector(dlgTitle, filename, exts);
if (newfilename.empty()) if (newfilename.empty())
return; return;
@ -283,7 +296,7 @@ void SaveFileCopyAsCommand::onExecute(Context* context)
{ {
const ContextReader reader(context); const ContextReader reader(context);
const Document* document(reader.document()); const Document* document(reader.document());
base::string old_filename = document->getFilename(); std::string old_filename = document->getFilename();
// show "Save As" dialog // show "Save As" dialog
saveAsDialog(reader, "Save Copy As", false); saveAsDialog(reader, "Save Copy As", false);

View File

@ -58,7 +58,7 @@ void SaveMaskCommand::onExecute(Context* context)
{ {
const ContextReader reader(context); const ContextReader reader(context);
const Document* document(reader.document()); const Document* document(reader.document());
base::string filename = "default.msk"; std::string filename = "default.msk";
int ret; int ret;
for (;;) { for (;;) {

View File

@ -51,7 +51,7 @@ SavePaletteCommand::SavePaletteCommand()
void SavePaletteCommand::onExecute(Context* context) void SavePaletteCommand::onExecute(Context* context)
{ {
base::string filename; std::string filename;
int ret; int ret;
again: again:

View File

@ -23,10 +23,12 @@
#include "app/color.h" #include "app/color.h"
#include "app/commands/command.h" #include "app/commands/command.h"
#include "app/context_access.h" #include "app/context_access.h"
#include "app/document_api.h"
#include "app/find_widget.h" #include "app/find_widget.h"
#include "app/load_widget.h" #include "app/load_widget.h"
#include "app/modules/gui.h" #include "app/modules/gui.h"
#include "app/ui/color_button.h" #include "app/ui/color_button.h"
#include "app/undo_transaction.h"
#include "base/bind.h" #include "base/bind.h"
#include "base/mem_utils.h" #include "base/mem_utils.h"
#include "raster/image.h" #include "raster/image.h"
@ -67,7 +69,7 @@ bool SpritePropertiesCommand::onEnabled(Context* context)
void SpritePropertiesCommand::onExecute(Context* context) void SpritePropertiesCommand::onExecute(Context* context)
{ {
Widget* name, *type, *size, *frames, *ok, *box_transparent; Widget* name, *type, *size, *frames, *ok, *box_transparent;
base::string imgtype_text; std::string imgtype_text;
char buf[256]; char buf[256];
ColorButton* color_button = NULL; ColorButton* color_button = NULL;
@ -148,8 +150,11 @@ void SpritePropertiesCommand::onExecute(Context* context)
// property in the sprite. // property in the sprite.
int index = color_button->getColor().getIndex(); int index = color_button->getColor().getIndex();
if (index != sprite->getTransparentColor()) { if (index != sprite->getTransparentColor()) {
// TODO Add undo handling UndoTransaction undoTransaction(writer.context(), "Set Transparent Color");
sprite->setTransparentColor(color_button->getColor().getIndex()); DocumentApi api = writer.document()->getApi();
api.setSpriteTransparentColor(sprite, index);
undoTransaction.commit();
update_screen_for_document(writer.document()); update_screen_for_document(writer.document());
} }
} }

View File

@ -243,6 +243,7 @@ void SpriteSizeCommand::onExecute(Context* context)
{ {
SpriteSizeJob job(reader, new_width, new_height, resize_method); SpriteSizeJob job(reader, new_width, new_height, resize_method);
job.startJob(); job.startJob();
job.waitJob();
} }
ContextWriter writer(reader); ContextWriter writer(reader);

View File

@ -27,6 +27,7 @@
#include "app/ini_file.h" #include "app/ini_file.h"
#include "app/modules/editors.h" #include "app/modules/editors.h"
#include "app/modules/gui.h" #include "app/modules/gui.h"
#include "app/modules/palettes.h"
#include "app/ui/editor/editor.h" #include "app/ui/editor/editor.h"
#include "app/ui/status_bar.h" #include "app/ui/status_bar.h"
#include "base/thread.h" #include "base/thread.h"
@ -117,6 +118,7 @@ void UndoCommand::onExecute(Context* context)
document->destroyExtraCel(); // Regenerate extras document->destroyExtraCel(); // Regenerate extras
update_screen_for_document(document); update_screen_for_document(document);
set_current_palette(writer.palette(), false);
} }
Command* CommandFactory::createUndoCommand() Command* CommandFactory::createUndoCommand()

View File

@ -99,6 +99,7 @@ FOR_EACH_COMMAND(SavePalette)
FOR_EACH_COMMAND(Scroll) FOR_EACH_COMMAND(Scroll)
FOR_EACH_COMMAND(SetPalette) FOR_EACH_COMMAND(SetPalette)
FOR_EACH_COMMAND(ShowGrid) FOR_EACH_COMMAND(ShowGrid)
FOR_EACH_COMMAND(ShowOnionSkin)
FOR_EACH_COMMAND(SnapToGrid) FOR_EACH_COMMAND(SnapToGrid)
FOR_EACH_COMMAND(SplitEditorHorizontally) FOR_EACH_COMMAND(SplitEditorHorizontally)
FOR_EACH_COMMAND(SplitEditorVertically) FOR_EACH_COMMAND(SplitEditorVertically)

View File

@ -60,7 +60,7 @@ public:
{ {
m_view.attachToView(&m_editor); m_view.attachToView(&m_editor);
m_view.setExpansive(true); m_view.setExpansive(true);
jwidget_set_min_size(&m_view, 128, 64); m_view.setMinSize(gfx::Size(128, 64));
getContainer()->addChild(&m_view); getContainer()->addChild(&m_view);

View File

@ -68,7 +68,7 @@ Console::Console()
view->attachToView(textbox); view->attachToView(textbox);
jwidget_set_min_size(button, 60, 0); button->setMinSize(gfx::Size(60, 0));
grid->addChildInCell(view, 1, 1, JI_HORIZONTAL | JI_VERTICAL); grid->addChildInCell(view, 1, 1, JI_HORIZONTAL | JI_VERTICAL);
grid->addChildInCell(button, 1, 1, JI_CENTER); grid->addChildInCell(button, 1, 1, JI_CENTER);
@ -138,7 +138,7 @@ void Console::printf(const char* format, ...)
const std::string& text = wid_textbox->getText(); const std::string& text = wid_textbox->getText();
base::string final; std::string final;
if (!text.empty()) if (!text.empty())
final += text; final += text;
final += buf; final += buf;

View File

@ -51,6 +51,10 @@ namespace app {
return m_location.image(x, y, opacity); return m_location.image(x, y, opacity);
} }
Palette* palette() const {
return m_location.palette();
}
protected: protected:
ContextAccess(const Context* context) ContextAccess(const Context* context)
: m_context(context) : m_context(context)

View File

@ -39,7 +39,7 @@ DataRecovery::DataRecovery(Context* context)
, m_context(context) , m_context(context)
{ {
// Check if there is already data to recover // Check if there is already data to recover
const base::string existent_data_path = get_config_string("DataRecovery", "Path", ""); const std::string existent_data_path = get_config_string("DataRecovery", "Path", "");
if (!existent_data_path.empty() && if (!existent_data_path.empty() &&
base::is_directory(existent_data_path)) { base::is_directory(existent_data_path)) {
// Load the backup data. // Load the backup data.

View File

@ -189,7 +189,7 @@ void Document::notifyCelCopied(Layer* fromLayer, FrameNumber fromFrame, Layer* t
notifyObservers<DocumentEvent&>(&DocumentObserver::onCelCopied, ev); notifyObservers<DocumentEvent&>(&DocumentObserver::onCelCopied, ev);
} }
void Document::setFilename(const base::string& filename) void Document::setFilename(const std::string& filename)
{ {
m_document.setFilename(filename); m_document.setFilename(filename);
} }
@ -210,6 +210,11 @@ void Document::markAsSaved()
m_associated_to_file = true; m_associated_to_file = true;
} }
void Document::impossibleToBackToSavedState()
{
m_undo->impossibleToBackToSavedState();
}
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// Loaded options from file // Loaded options from file
@ -290,8 +295,6 @@ void Document::prepareExtraCel(int x, int y, int w, int h, int opacity)
m_extraImage->getHeight() != h) { m_extraImage->getHeight() != h) {
delete m_extraImage; // image delete m_extraImage; // image
m_extraImage = Image::create(getSprite()->getPixelFormat(), w, h); m_extraImage = Image::create(getSprite()->getPixelFormat(), w, h);
m_extraImage->setMaskColor(0);
clear_image(m_extraImage, m_extraImage->getMaskColor());
} }
} }

View File

@ -24,13 +24,14 @@
#include "base/disable_copying.h" #include "base/disable_copying.h"
#include "base/observable.h" #include "base/observable.h"
#include "base/shared_ptr.h" #include "base/shared_ptr.h"
#include "base/string.h"
#include "base/unique_ptr.h" #include "base/unique_ptr.h"
#include "doc/document.h" #include "doc/document.h"
#include "gfx/transformation.h" #include "gfx/transformation.h"
#include "raster/frame_number.h" #include "raster/frame_number.h"
#include "raster/pixel_format.h" #include "raster/pixel_format.h"
#include <string>
namespace base { namespace base {
class mutex; class mutex;
} }
@ -122,13 +123,19 @@ namespace app {
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// File related properties // File related properties
const base::string& getFilename() const { return m_document.filename(); } const std::string& getFilename() const { return m_document.filename(); }
void setFilename(const base::string& filename); void setFilename(const std::string& filename);
bool isModified() const; bool isModified() const;
bool isAssociatedToFile() const; bool isAssociatedToFile() const;
void markAsSaved(); void markAsSaved();
// You can use this to indicate that we've destroyed (or we cannot
// trust) the file associated with the document (e.g. when we
// cancel a Save operation in the middle). So it's impossible to
// back to the saved state using the UndoHistory.
void impossibleToBackToSavedState();
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// Loaded options from file // Loaded options from file

View File

@ -55,6 +55,7 @@
#include "app/undoers/set_palette_colors.h" #include "app/undoers/set_palette_colors.h"
#include "app/undoers/set_sprite_pixel_format.h" #include "app/undoers/set_sprite_pixel_format.h"
#include "app/undoers/set_sprite_size.h" #include "app/undoers/set_sprite_size.h"
#include "app/undoers/set_sprite_transparent_color.h"
#include "app/undoers/set_stock_pixel_format.h" #include "app/undoers/set_stock_pixel_format.h"
#include "app/undoers/set_total_frames.h" #include "app/undoers/set_total_frames.h"
#include "base/unique_ptr.h" #include "base/unique_ptr.h"
@ -100,6 +101,18 @@ void DocumentApi::setSpriteSize(Sprite* sprite, int w, int h)
m_document->notifyObservers<DocumentEvent&>(&DocumentObserver::onSpriteSizeChanged, ev); m_document->notifyObservers<DocumentEvent&>(&DocumentObserver::onSpriteSizeChanged, ev);
} }
void DocumentApi::setSpriteTransparentColor(Sprite* sprite, color_t maskColor)
{
if (undoEnabled())
m_undoers->pushUndoer(new undoers::SetSpriteTransparentColor(getObjects(), sprite));
sprite->setTransparentColor(maskColor);
DocumentEvent ev(m_document);
ev.sprite(sprite);
m_document->notifyObservers<DocumentEvent&>(&DocumentObserver::onSpriteTransparentColorChanged, ev);
}
void DocumentApi::cropSprite(Sprite* sprite, const gfx::Rect& bounds, color_t bgcolor) void DocumentApi::cropSprite(Sprite* sprite, const gfx::Rect& bounds, color_t bgcolor)
{ {
setSpriteSize(sprite, bounds.w, bounds.h); setSpriteSize(sprite, bounds.w, bounds.h);
@ -160,15 +173,30 @@ void DocumentApi::setPixelFormat(Sprite* sprite, PixelFormat newFormat, Ditherin
// Use the rgbmap for the specified sprite // Use the rgbmap for the specified sprite
const RgbMap* rgbmap = sprite->getRgbMap(frame); const RgbMap* rgbmap = sprite->getRgbMap(frame);
// Get the list of cels from the background layer (if it
// exists). This list will be used to check if each image belong to
// the background layer.
CelList bgCels;
if (sprite->getBackgroundLayer() != NULL)
sprite->getBackgroundLayer()->getCels(bgCels);
for (c=0; c<sprite->getStock()->size(); c++) { for (c=0; c<sprite->getStock()->size(); c++) {
old_image = sprite->getStock()->getImage(c); old_image = sprite->getStock()->getImage(c);
if (!old_image) if (!old_image)
continue; continue;
bool is_image_from_background = false;
for (CelList::iterator it=bgCels.begin(), end=bgCels.end(); it != end; ++it) {
if ((*it)->getImage() == c) {
is_image_from_background = true;
break;
}
}
new_image = quantization::convert_pixel_format new_image = quantization::convert_pixel_format
(old_image, newFormat, dithering_method, rgbmap, (old_image, newFormat, dithering_method, rgbmap,
sprite->getPalette(frame), sprite->getPalette(frame),
sprite->getBackgroundLayer() != NULL); is_image_from_background);
replaceStockImage(sprite, c, new_image); replaceStockImage(sprite, c, new_image);
} }
@ -498,20 +526,13 @@ void DocumentApi::removeCel(LayerImage* layer, Cel* cel)
ev.cel(cel); ev.cel(cel);
m_document->notifyObservers<DocumentEvent&>(&DocumentObserver::onRemoveCel, ev); m_document->notifyObservers<DocumentEvent&>(&DocumentObserver::onRemoveCel, ev);
// Find if the image that use the cel to remove, is used by another // Find if the image that use this cel we are going to remove, is
// cels. // used by other cels.
bool used = false; size_t refs = sprite->getImageRefs(cel->getImage());
for (FrameNumber frame(0); frame<sprite->getTotalFrames(); ++frame) {
Cel* it = layer->getCel(frame);
if (it && it != cel && it->getImage() == cel->getImage()) {
used = true;
break;
}
}
// If the image is only used by this cel, we can remove the image // If the image is only used by this cel, we can remove the image
// from the stock. // from the stock.
if (!used) if (refs == 1)
removeImageFromStock(sprite, cel->getImage()); removeImageFromStock(sprite, cel->getImage());
if (undoEnabled()) if (undoEnabled())
@ -558,6 +579,21 @@ void DocumentApi::setCelPosition(Sprite* sprite, Cel* cel, int x, int y)
m_document->notifyObservers<DocumentEvent&>(&DocumentObserver::onCelPositionChanged, ev); m_document->notifyObservers<DocumentEvent&>(&DocumentObserver::onCelPositionChanged, ev);
} }
void DocumentApi::setCelOpacity(Sprite* sprite, Cel* cel, int newOpacity)
{
ASSERT(cel);
if (undoEnabled())
m_undoers->pushUndoer(new undoers::SetCelOpacity(getObjects(), cel));
cel->setOpacity(newOpacity);
DocumentEvent ev(m_document);
ev.sprite(sprite);
ev.cel(cel);
m_document->notifyObservers<DocumentEvent&>(&DocumentObserver::onCelOpacityChanged, ev);
}
void DocumentApi::cropCel(Sprite* sprite, Cel* cel, int x, int y, int w, int h, color_t bgcolor) void DocumentApi::cropCel(Sprite* sprite, Cel* cel, int x, int y, int w, int h, color_t bgcolor)
{ {
Image* cel_image = sprite->getStock()->getImage(cel->getImage()); Image* cel_image = sprite->getStock()->getImage(cel->getImage());
@ -583,16 +619,17 @@ void DocumentApi::moveCel(Sprite* sprite,
ASSERT(srcFrame >= 0 && srcFrame < sprite->getTotalFrames()); ASSERT(srcFrame >= 0 && srcFrame < sprite->getTotalFrames());
ASSERT(dstFrame >= 0 && dstFrame < sprite->getTotalFrames()); ASSERT(dstFrame >= 0 && dstFrame < sprite->getTotalFrames());
// Background to any other layer, we use copyCel() instead.
if (srcLayer->isBackground()) { if (srcLayer->isBackground()) {
copyCel(sprite, srcLayer, dstLayer, srcFrame, dstFrame, bgcolor); copyCel(sprite, srcLayer, dstLayer, srcFrame, dstFrame, bgcolor);
return; return;
} }
// In this we copy from a transparent layer to another layer...
Cel* srcCel = srcLayer->getCel(srcFrame);
Cel* dstCel = dstLayer->getCel(dstFrame);
// Remove the dstCel (if it exists) because it must be replaced with // Remove the dstCel (if it exists) because it must be replaced with
// srcCel. // srcCel.
Cel* srcCel = srcLayer->getCel(srcFrame);
Cel* dstCel = dstLayer->getCel(dstFrame);
if ((dstCel != NULL) && (!dstLayer->isBackground() || srcCel != NULL)) if ((dstCel != NULL) && (!dstLayer->isBackground() || srcCel != NULL))
removeCel(dstLayer, dstCel); removeCel(dstLayer, dstCel);
@ -603,17 +640,14 @@ void DocumentApi::moveCel(Sprite* sprite,
} }
// Move the cel between different layers. // Move the cel between different layers.
else { else {
if (undoEnabled()) Cel* newCel = new Cel(*srcCel);
m_undoers->pushUndoer(new undoers::RemoveCel(getObjects(), srcLayer, srcCel)); newCel->setFrame(dstFrame);
srcLayer->removeCel(srcCel);
srcCel->setFrame(dstFrame);
// If we are moving a cel from a transparent layer to the // If we are moving a cel from a transparent layer to the
// background layer, we have to clear the background of the // background layer, we have to clear the background of the
// image. // image.
if (!srcLayer->isBackground() && ASSERT(!srcLayer->isBackground());
dstLayer->isBackground()) { if (dstLayer->isBackground()) {
Image* srcImage = sprite->getStock()->getImage(srcCel->getImage()); Image* srcImage = sprite->getStock()->getImage(srcCel->getImage());
Image* dstImage = crop_image(srcImage, Image* dstImage = crop_image(srcImage,
-srcCel->getX(), -srcCel->getX(),
@ -621,24 +655,17 @@ void DocumentApi::moveCel(Sprite* sprite,
sprite->getWidth(), sprite->getWidth(),
sprite->getHeight(), 0); sprite->getHeight(), 0);
if (undoEnabled()) {
m_undoers->pushUndoer(new undoers::ReplaceImage(getObjects(),
sprite->getStock(), srcCel->getImage()));
m_undoers->pushUndoer(new undoers::SetCelPosition(getObjects(), srcCel));
m_undoers->pushUndoer(new undoers::SetCelOpacity(getObjects(), srcCel));
}
clear_image(dstImage, bgcolor); clear_image(dstImage, bgcolor);
composite_image(dstImage, srcImage, srcCel->getX(), srcCel->getY(), 255, BLEND_MODE_NORMAL); composite_image(dstImage, srcImage, srcCel->getX(), srcCel->getY(), 255, BLEND_MODE_NORMAL);
srcCel->setPosition(0, 0); newCel->setPosition(0, 0);
srcCel->setOpacity(255); newCel->setOpacity(255);
newCel->setImage(addImageInStock(sprite, dstImage));
sprite->getStock()->replaceImage(srcCel->getImage(), dstImage);
delete srcImage;
} }
addCel(dstLayer, srcCel); // Add and the remove, so the Stock's image is reused.
addCel(dstLayer, newCel);
removeCel(srcLayer, srcCel);
} }
} }

View File

@ -62,6 +62,7 @@ namespace app {
// Sprite API // Sprite API
void setSpriteSize(Sprite* sprite, int w, int h); void setSpriteSize(Sprite* sprite, int w, int h);
void setSpriteTransparentColor(Sprite* sprite, color_t maskColor);
void cropSprite(Sprite* sprite, const gfx::Rect& bounds, color_t bgcolor); void cropSprite(Sprite* sprite, const gfx::Rect& bounds, color_t bgcolor);
void trimSprite(Sprite* sprite, color_t bgcolor); void trimSprite(Sprite* sprite, color_t bgcolor);
void setPixelFormat(Sprite* sprite, PixelFormat newFormat, DitheringMethod dithering_method); void setPixelFormat(Sprite* sprite, PixelFormat newFormat, DitheringMethod dithering_method);
@ -79,6 +80,7 @@ namespace app {
void addCel(LayerImage* layer, Cel* cel); void addCel(LayerImage* layer, Cel* cel);
void removeCel(LayerImage* layer, Cel* cel); void removeCel(LayerImage* layer, Cel* cel);
void setCelPosition(Sprite* sprite, Cel* cel, int x, int y); void setCelPosition(Sprite* sprite, Cel* cel, int x, int y);
void setCelOpacity(Sprite* sprite, Cel* cel, int newOpacity);
void cropCel(Sprite* sprite, Cel* cel, int x, int y, int w, int h, color_t bgcolor); void cropCel(Sprite* sprite, Cel* cel, int x, int y, int w, int h, color_t bgcolor);
void moveCel(Sprite* sprite, void moveCel(Sprite* sprite,
LayerImage* srcLayer, LayerImage* dstLayer, LayerImage* srcLayer, LayerImage* dstLayer,

View File

@ -194,18 +194,18 @@ void DocumentExporter::captureSamples(Samples& samples)
for (FrameNumber frame=FrameNumber(0); for (FrameNumber frame=FrameNumber(0);
frame<sprite->getTotalFrames(); ++frame) { frame<sprite->getTotalFrames(); ++frame) {
base::string filename = document->getFilename(); std::string filename = document->getFilename();
if (sprite->getTotalFrames() > FrameNumber(1)) { if (sprite->getTotalFrames() > FrameNumber(1)) {
int frameNumWidth = int frameNumWidth =
(sprite->getTotalFrames() < 10)? 1: (sprite->getTotalFrames() < 10)? 1:
(sprite->getTotalFrames() < 100)? 2: (sprite->getTotalFrames() < 100)? 2:
(sprite->getTotalFrames() < 1000)? 3: 4; (sprite->getTotalFrames() < 1000)? 3: 4;
std::sprintf(&buf[0], "%0*d", frameNumWidth, frame); std::sprintf(&buf[0], "%0*d", frameNumWidth, (int)frame);
base::string path = base::get_file_path(filename); std::string path = base::get_file_path(filename);
base::string title = base::get_file_title(filename); std::string title = base::get_file_title(filename);
base::string ext = base::get_file_extension(filename); std::string ext = base::get_file_extension(filename);
filename = base::join_path(path, title + &buf[0] + "." + ext); filename = base::join_path(path, title + &buf[0] + "." + ext);
} }

View File

@ -84,4 +84,9 @@ Image* DocumentLocation::image(int* x, int* y, int* opacity) const
return image; return image;
} }
Palette* DocumentLocation::palette() const
{
return (m_sprite ? m_sprite->getPalette(m_frame): NULL);
}
} // namespace app } // namespace app

View File

@ -67,6 +67,7 @@ namespace app {
void layerIndex(LayerIndex layerIndex); void layerIndex(LayerIndex layerIndex);
Palette* palette(); Palette* palette();
Image* image(int* x = NULL, int* y = NULL, int* opacity = NULL) const; Image* image(int* x = NULL, int* y = NULL, int* opacity = NULL) const;
Palette* palette() const;
private: private:
Document* m_document; Document* m_document;

View File

@ -52,6 +52,7 @@ namespace app {
virtual void onRemoveCel(DocumentEvent& ev) { } virtual void onRemoveCel(DocumentEvent& ev) { }
virtual void onSpriteSizeChanged(DocumentEvent& ev) { } virtual void onSpriteSizeChanged(DocumentEvent& ev) { }
virtual void onSpriteTransparentColorChanged(DocumentEvent& ev) { }
virtual void onLayerRestacked(DocumentEvent& ev) { } virtual void onLayerRestacked(DocumentEvent& ev) { }
virtual void onLayerMergedDown(DocumentEvent& ev) { } virtual void onLayerMergedDown(DocumentEvent& ev) { }

View File

@ -74,6 +74,11 @@ void DocumentUndo::markSavedState()
return m_undoHistory->markSavedState(); return m_undoHistory->markSavedState();
} }
void DocumentUndo::impossibleToBackToSavedState()
{
m_undoHistory->impossibleToBackToSavedState();
}
void DocumentUndo::pushUndoer(undo::Undoer* undoer) void DocumentUndo::pushUndoer(undo::Undoer* undoer)
{ {
return m_undoHistory->pushUndoer(undoer); return m_undoHistory->pushUndoer(undoer);

View File

@ -55,6 +55,7 @@ namespace app {
bool isSavedState() const; bool isSavedState() const;
void markSavedState(); void markSavedState();
void impossibleToBackToSavedState();
// UndoHistoryDelegate implementation. // UndoHistoryDelegate implementation.
undo::ObjectsContainer* getObjects() const OVERRIDE { return m_objects; } undo::ObjectsContainer* getObjects() const OVERRIDE { return m_objects; }

View File

@ -75,39 +75,55 @@ struct ASE_FrameHeader {
uint16_t duration; uint16_t duration;
}; };
// TODO Warning: the writing routines aren't thread-safe struct ASE_Chunk {
static ASE_FrameHeader *current_frame_header = NULL; int type;
static int chunk_type; int start;
static int chunk_start; };
static bool ase_file_read_header(FILE* f, ASE_Header* header); static bool ase_file_read_header(FILE* f, ASE_Header* header);
static void ase_file_prepare_header(FILE* f, ASE_Header* header, const Sprite* sprite); static void ase_file_prepare_header(FILE* f, ASE_Header* header, const Sprite* sprite);
static void ase_file_write_header(FILE* f, ASE_Header* header); static void ase_file_write_header(FILE* f, ASE_Header* header);
static void ase_file_write_header_filesize(FILE* f, ASE_Header* header);
static void ase_file_read_frame_header(FILE *f, ASE_FrameHeader *frame_header); static void ase_file_read_frame_header(FILE* f, ASE_FrameHeader* frame_header);
static void ase_file_prepare_frame_header(FILE *f, ASE_FrameHeader *frame_header); static void ase_file_prepare_frame_header(FILE* f, ASE_FrameHeader* frame_header);
static void ase_file_write_frame_header(FILE *f, ASE_FrameHeader *frame_header); static void ase_file_write_frame_header(FILE* f, ASE_FrameHeader* frame_header);
static void ase_file_write_layers(FILE *f, Layer *layer); static void ase_file_write_layers(FILE* f, ASE_FrameHeader* frame_header, Layer* layer);
static void ase_file_write_cels(FILE *f, Sprite *sprite, Layer *layer, FrameNumber frame); static void ase_file_write_cels(FILE* f, ASE_FrameHeader* frame_header, Sprite* sprite, Layer* layer, FrameNumber frame);
static void ase_file_read_padding(FILE *f, int bytes); static void ase_file_read_padding(FILE* f, int bytes);
static void ase_file_write_padding(FILE *f, int bytes); static void ase_file_write_padding(FILE* f, int bytes);
static std::string ase_file_read_string(FILE *f); static std::string ase_file_read_string(FILE* f);
static void ase_file_write_string(FILE *f, const std::string& string); static void ase_file_write_string(FILE* f, const std::string& string);
static void ase_file_write_start_chunk(FILE *f, int type); static void ase_file_write_start_chunk(FILE* f, ASE_FrameHeader* frame_header, int type, ASE_Chunk* chunk);
static void ase_file_write_close_chunk(FILE *f); static void ase_file_write_close_chunk(FILE* f, ASE_Chunk* chunk);
static Palette *ase_file_read_color_chunk(FILE *f, Sprite *sprite, FrameNumber frame); static Palette* ase_file_read_color_chunk(FILE* f, Sprite* sprite, FrameNumber frame);
static Palette *ase_file_read_color2_chunk(FILE *f, Sprite *sprite, FrameNumber frame); static Palette* ase_file_read_color2_chunk(FILE* f, Sprite* sprite, FrameNumber frame);
static void ase_file_write_color2_chunk(FILE *f, Palette *pal); static void ase_file_write_color2_chunk(FILE* f, ASE_FrameHeader* frame_header, Palette* pal);
static Layer *ase_file_read_layer_chunk(FILE *f, Sprite *sprite, Layer **previous_layer, int *current_level); static Layer* ase_file_read_layer_chunk(FILE* f, Sprite* sprite, Layer** previous_layer, int* current_level);
static void ase_file_write_layer_chunk(FILE *f, Layer *layer); static void ase_file_write_layer_chunk(FILE* f, ASE_FrameHeader* frame_header, Layer* layer);
static Cel *ase_file_read_cel_chunk(FILE *f, Sprite *sprite, FrameNumber frame, PixelFormat pixelFormat, FileOp *fop, ASE_Header *header, size_t chunk_end); static Cel* ase_file_read_cel_chunk(FILE* f, Sprite* sprite, FrameNumber frame, PixelFormat pixelFormat, FileOp* fop, ASE_Header* header, size_t chunk_end);
static void ase_file_write_cel_chunk(FILE *f, Cel *cel, LayerImage *layer, Sprite *sprite); static void ase_file_write_cel_chunk(FILE* f, ASE_FrameHeader* frame_header, Cel* cel, LayerImage* layer, Sprite* sprite);
static Mask *ase_file_read_mask_chunk(FILE *f); static Mask* ase_file_read_mask_chunk(FILE* f);
static void ase_file_write_mask_chunk(FILE *f, Mask *mask); static void ase_file_write_mask_chunk(FILE* f, ASE_FrameHeader* frame_header, Mask* mask);
class ChunkWriter {
public:
ChunkWriter(FILE* f, ASE_FrameHeader* frame_header, int type) : m_file(f) {
ase_file_write_start_chunk(m_file, frame_header, type, &m_chunk);
}
~ChunkWriter() {
ase_file_write_close_chunk(m_file, &m_chunk);
}
private:
FILE* m_file;
ASE_Chunk m_chunk;
};
class AseFormat : public FileFormat { class AseFormat : public FileFormat {
const char* onGetName() const { return "ase"; } const char* onGetName() const { return "ase"; }
@ -137,7 +153,7 @@ FileFormat* CreateAseFormat()
return new AseFormat; return new AseFormat;
} }
bool AseFormat::onLoad(FileOp *fop) bool AseFormat::onLoad(FileOp* fop)
{ {
FileHandle f(open_file_with_exception(fop->filename, "rb")); FileHandle f(open_file_with_exception(fop->filename, "rb"));
@ -148,7 +164,7 @@ bool AseFormat::onLoad(FileOp *fop)
} }
// Create the new sprite // Create the new sprite
Sprite *sprite = new Sprite(header.depth == 32 ? IMAGE_RGB: Sprite* sprite = new Sprite(header.depth == 32 ? IMAGE_RGB:
header.depth == 16 ? IMAGE_GRAYSCALE: IMAGE_INDEXED, header.depth == 16 ? IMAGE_GRAYSCALE: IMAGE_INDEXED,
header.width, header.height, header.ncolors); header.width, header.height, header.ncolors);
if (!sprite) { if (!sprite) {
@ -236,7 +252,7 @@ bool AseFormat::onLoad(FileOp *fop)
} }
case ASE_FILE_CHUNK_MASK: { case ASE_FILE_CHUNK_MASK: {
Mask *mask; Mask* mask;
/* fop_error(fop, "Mask chunk\n"); */ /* fop_error(fop, "Mask chunk\n"); */
@ -286,56 +302,59 @@ bool AseFormat::onLoad(FileOp *fop)
} }
#ifdef ENABLE_SAVE #ifdef ENABLE_SAVE
bool AseFormat::onSave(FileOp *fop) bool AseFormat::onSave(FileOp* fop)
{ {
Sprite* sprite = fop->document->getSprite(); Sprite* sprite = fop->document->getSprite();
ASE_Header header;
ASE_FrameHeader frame_header;
FileHandle f(open_file_with_exception(fop->filename, "wb")); FileHandle f(open_file_with_exception(fop->filename, "wb"));
/* prepare the header */ // Write the header
ASE_Header header;
ase_file_prepare_header(f, &header, sprite); ase_file_prepare_header(f, &header, sprite);
ase_file_write_header(f, &header);
/* write frame */ // Write frames
for (FrameNumber frame(0); frame<sprite->getTotalFrames(); ++frame) { for (FrameNumber frame(0); frame<sprite->getTotalFrames(); ++frame) {
/* prepare the header */ // Prepare the frame header
ASE_FrameHeader frame_header;
ase_file_prepare_frame_header(f, &frame_header); ase_file_prepare_frame_header(f, &frame_header);
/* frame duration */ // Frame duration
frame_header.duration = sprite->getFrameDuration(frame); frame_header.duration = sprite->getFrameDuration(frame);
/* the sprite is indexed and the palette changes? (or is the first frame) */ // The sprite is indexed and the palette changes? (or is the first frame)
if (sprite->getPixelFormat() == IMAGE_INDEXED && if (sprite->getPixelFormat() == IMAGE_INDEXED &&
(frame == 0 || (frame == 0 ||
sprite->getPalette(frame.previous())->countDiff(sprite->getPalette(frame), NULL, NULL) > 0)) { sprite->getPalette(frame.previous())->countDiff(sprite->getPalette(frame), NULL, NULL) > 0)) {
/* write the color chunk */ // Write the color chunk
ase_file_write_color2_chunk(f, sprite->getPalette(frame)); ase_file_write_color2_chunk(f, &frame_header, sprite->getPalette(frame));
} }
/* write extra chunks in the first frame */ // Write extra chunks in the first frame
if (frame == 0) { if (frame == 0) {
LayerIterator it = sprite->getFolder()->getLayerBegin(); LayerIterator it = sprite->getFolder()->getLayerBegin();
LayerIterator end = sprite->getFolder()->getLayerEnd(); LayerIterator end = sprite->getFolder()->getLayerEnd();
/* write layer chunks */ // Write layer chunks
for (; it != end; ++it) for (; it != end; ++it)
ase_file_write_layers(f, *it); ase_file_write_layers(f, &frame_header, *it);
} }
/* write cel chunks */ // Write cel chunks
ase_file_write_cels(f, sprite, sprite->getFolder(), frame); ase_file_write_cels(f, &frame_header, sprite, sprite->getFolder(), frame);
/* write the frame header */ // Write the frame header
ase_file_write_frame_header(f, &frame_header); ase_file_write_frame_header(f, &frame_header);
/* progress */ // Progress
if (sprite->getTotalFrames() > 1) if (sprite->getTotalFrames() > 1)
fop_progress(fop, (float)(frame.next()) / (float)(sprite->getTotalFrames())); fop_progress(fop, (float)(frame.next()) / (float)(sprite->getTotalFrames()));
if (fop_is_stop(fop))
break;
} }
/* write the header */ // Write the missing field (filesize) of the header.
ase_file_write_header(f, &header); ase_file_write_header_filesize(f, &header);
if (ferror(f)) { if (ferror(f)) {
fop_error(fop, "Error writing file.\n"); fop_error(fop, "Error writing file.\n");
@ -347,7 +366,7 @@ bool AseFormat::onSave(FileOp *fop)
} }
#endif #endif
static bool ase_file_read_header(FILE *f, ASE_Header *header) static bool ase_file_read_header(FILE* f, ASE_Header* header)
{ {
header->pos = ftell(f); header->pos = ftell(f);
@ -376,7 +395,7 @@ static bool ase_file_read_header(FILE *f, ASE_Header *header)
return true; return true;
} }
static void ase_file_prepare_header(FILE *f, ASE_Header *header, const Sprite* sprite) static void ase_file_prepare_header(FILE* f, ASE_Header* header, const Sprite* sprite)
{ {
header->pos = ftell(f); header->pos = ftell(f);
@ -397,14 +416,10 @@ static void ase_file_prepare_header(FILE *f, ASE_Header *header, const Sprite* s
header->ignore[1] = 0; header->ignore[1] = 0;
header->ignore[2] = 0; header->ignore[2] = 0;
header->ncolors = sprite->getPalette(FrameNumber(0))->size(); header->ncolors = sprite->getPalette(FrameNumber(0))->size();
fseek(f, header->pos+128, SEEK_SET);
} }
static void ase_file_write_header(FILE *f, ASE_Header *header) static void ase_file_write_header(FILE* f, ASE_Header* header)
{ {
header->size = ftell(f)-header->pos;
fseek(f, header->pos, SEEK_SET); fseek(f, header->pos, SEEK_SET);
fputl(header->size, f); fputl(header->size, f);
@ -423,10 +438,20 @@ static void ase_file_write_header(FILE *f, ASE_Header *header)
fputc(header->ignore[2], f); fputc(header->ignore[2], f);
fputw(header->ncolors, f); fputw(header->ncolors, f);
fseek(f, header->pos+128, SEEK_SET);
}
static void ase_file_write_header_filesize(FILE* f, ASE_Header* header)
{
header->size = ftell(f)-header->pos;
fseek(f, header->pos, SEEK_SET);
fputl(header->size, f);
fseek(f, header->pos+header->size, SEEK_SET); fseek(f, header->pos+header->size, SEEK_SET);
} }
static void ase_file_read_frame_header(FILE *f, ASE_FrameHeader *frame_header) static void ase_file_read_frame_header(FILE* f, ASE_FrameHeader* frame_header)
{ {
frame_header->size = fgetl(f); frame_header->size = fgetl(f);
frame_header->magic = fgetw(f); frame_header->magic = fgetw(f);
@ -435,7 +460,7 @@ static void ase_file_read_frame_header(FILE *f, ASE_FrameHeader *frame_header)
ase_file_read_padding(f, 6); ase_file_read_padding(f, 6);
} }
static void ase_file_prepare_frame_header(FILE *f, ASE_FrameHeader *frame_header) static void ase_file_prepare_frame_header(FILE* f, ASE_FrameHeader* frame_header)
{ {
int pos = ftell(f); int pos = ftell(f);
@ -444,12 +469,10 @@ static void ase_file_prepare_frame_header(FILE *f, ASE_FrameHeader *frame_header
frame_header->chunks = 0; frame_header->chunks = 0;
frame_header->duration = 0; frame_header->duration = 0;
current_frame_header = frame_header;
fseek(f, pos+16, SEEK_SET); fseek(f, pos+16, SEEK_SET);
} }
static void ase_file_write_frame_header(FILE *f, ASE_FrameHeader *frame_header) static void ase_file_write_frame_header(FILE* f, ASE_FrameHeader* frame_header)
{ {
int pos = frame_header->size; int pos = frame_header->size;
int end = ftell(f); int end = ftell(f);
@ -465,24 +488,22 @@ static void ase_file_write_frame_header(FILE *f, ASE_FrameHeader *frame_header)
ase_file_write_padding(f, 6); ase_file_write_padding(f, 6);
fseek(f, end, SEEK_SET); fseek(f, end, SEEK_SET);
current_frame_header = NULL;
} }
static void ase_file_write_layers(FILE *f, Layer *layer) static void ase_file_write_layers(FILE* f, ASE_FrameHeader* frame_header, Layer* layer)
{ {
ase_file_write_layer_chunk(f, layer); ase_file_write_layer_chunk(f, frame_header, layer);
if (layer->isFolder()) { if (layer->isFolder()) {
LayerIterator it = static_cast<LayerFolder*>(layer)->getLayerBegin(); LayerIterator it = static_cast<LayerFolder*>(layer)->getLayerBegin();
LayerIterator end = static_cast<LayerFolder*>(layer)->getLayerEnd(); LayerIterator end = static_cast<LayerFolder*>(layer)->getLayerEnd();
for (; it != end; ++it) for (; it != end; ++it)
ase_file_write_layers(f, *it); ase_file_write_layers(f, frame_header, *it);
} }
} }
static void ase_file_write_cels(FILE *f, Sprite *sprite, Layer *layer, FrameNumber frame) static void ase_file_write_cels(FILE* f, ASE_FrameHeader* frame_header, Sprite* sprite, Layer* layer, FrameNumber frame)
{ {
if (layer->isImage()) { if (layer->isImage()) {
Cel* cel = static_cast<LayerImage*>(layer)->getCel(frame); Cel* cel = static_cast<LayerImage*>(layer)->getCel(frame);
@ -490,7 +511,7 @@ static void ase_file_write_cels(FILE *f, Sprite *sprite, Layer *layer, FrameNumb
/* fop_error(fop, "New cel in frame %d, in layer %d\n", */ /* fop_error(fop, "New cel in frame %d, in layer %d\n", */
/* frame, sprite_layer2index(sprite, layer)); */ /* frame, sprite_layer2index(sprite, layer)); */
ase_file_write_cel_chunk(f, cel, static_cast<LayerImage*>(layer), sprite); ase_file_write_cel_chunk(f, frame_header, cel, static_cast<LayerImage*>(layer), sprite);
} }
} }
@ -499,23 +520,23 @@ static void ase_file_write_cels(FILE *f, Sprite *sprite, Layer *layer, FrameNumb
LayerIterator end = static_cast<LayerFolder*>(layer)->getLayerEnd(); LayerIterator end = static_cast<LayerFolder*>(layer)->getLayerEnd();
for (; it != end; ++it) for (; it != end; ++it)
ase_file_write_cels(f, sprite, *it, frame); ase_file_write_cels(f, frame_header, sprite, *it, frame);
} }
} }
static void ase_file_read_padding(FILE *f, int bytes) static void ase_file_read_padding(FILE* f, int bytes)
{ {
for (int c=0; c<bytes; c++) for (int c=0; c<bytes; c++)
fgetc(f); fgetc(f);
} }
static void ase_file_write_padding(FILE *f, int bytes) static void ase_file_write_padding(FILE* f, int bytes)
{ {
for (int c=0; c<bytes; c++) for (int c=0; c<bytes; c++)
fputc(0, f); fputc(0, f);
} }
static std::string ase_file_read_string(FILE *f) static std::string ase_file_read_string(FILE* f)
{ {
int length = fgetw(f); int length = fgetw(f);
if (length == EOF) if (length == EOF)
@ -530,7 +551,7 @@ static std::string ase_file_read_string(FILE *f)
return string; return string;
} }
static void ase_file_write_string(FILE *f, const std::string& string) static void ase_file_write_string(FILE* f, const std::string& string)
{ {
fputw(string.size(), f); fputw(string.size(), f);
@ -538,28 +559,28 @@ static void ase_file_write_string(FILE *f, const std::string& string)
fputc(string[c], f); fputc(string[c], f);
} }
static void ase_file_write_start_chunk(FILE *f, int type) static void ase_file_write_start_chunk(FILE* f, ASE_FrameHeader* frame_header, int type, ASE_Chunk* chunk)
{ {
current_frame_header->chunks++; frame_header->chunks++;
chunk_type = type; chunk->type = type;
chunk_start = ftell(f); chunk->start = ftell(f);
fseek(f, chunk_start+6, SEEK_SET); fseek(f, chunk->start+6, SEEK_SET);
} }
static void ase_file_write_close_chunk(FILE *f) static void ase_file_write_close_chunk(FILE* f, ASE_Chunk* chunk)
{ {
int chunk_end = ftell(f); int chunk_end = ftell(f);
int chunk_size = chunk_end - chunk_start; int chunk_size = chunk_end - chunk->start;
fseek(f, chunk_start, SEEK_SET); fseek(f, chunk->start, SEEK_SET);
fputl(chunk_size, f); fputl(chunk_size, f);
fputw(chunk_type, f); fputw(chunk->type, f);
fseek(f, chunk_end, SEEK_SET); fseek(f, chunk_end, SEEK_SET);
} }
static Palette *ase_file_read_color_chunk(FILE *f, Sprite *sprite, FrameNumber frame) static Palette* ase_file_read_color_chunk(FILE* f, Sprite* sprite, FrameNumber frame)
{ {
int i, c, r, g, b, packets, skip, size; int i, c, r, g, b, packets, skip, size;
Palette* pal = new Palette(*sprite->getPalette(frame)); Palette* pal = new Palette(*sprite->getPalette(frame));
@ -587,7 +608,7 @@ static Palette *ase_file_read_color_chunk(FILE *f, Sprite *sprite, FrameNumber f
return pal; return pal;
} }
static Palette *ase_file_read_color2_chunk(FILE *f, Sprite *sprite, FrameNumber frame) static Palette* ase_file_read_color2_chunk(FILE* f, Sprite* sprite, FrameNumber frame)
{ {
int i, c, r, g, b, packets, skip, size; int i, c, r, g, b, packets, skip, size;
Palette* pal = new Palette(*sprite->getPalette(frame)); Palette* pal = new Palette(*sprite->getPalette(frame));
@ -614,12 +635,11 @@ static Palette *ase_file_read_color2_chunk(FILE *f, Sprite *sprite, FrameNumber
} }
/* writes the original color chunk in FLI files for the entire palette "pal" */ /* writes the original color chunk in FLI files for the entire palette "pal" */
static void ase_file_write_color2_chunk(FILE *f, Palette *pal) static void ase_file_write_color2_chunk(FILE* f, ASE_FrameHeader* frame_header, Palette* pal)
{ {
ChunkWriter chunk(f, frame_header, ASE_FILE_CHUNK_FLI_COLOR2);
int c, color; int c, color;
ase_file_write_start_chunk(f, ASE_FILE_CHUNK_FLI_COLOR2);
fputw(1, f); // number of packets fputw(1, f); // number of packets
// First packet // First packet
@ -632,14 +652,12 @@ static void ase_file_write_color2_chunk(FILE *f, Palette *pal)
fputc(rgba_getg(color), f); fputc(rgba_getg(color), f);
fputc(rgba_getb(color), f); fputc(rgba_getb(color), f);
} }
ase_file_write_close_chunk(f);
} }
static Layer *ase_file_read_layer_chunk(FILE *f, Sprite *sprite, Layer **previous_layer, int *current_level) static Layer* ase_file_read_layer_chunk(FILE* f, Sprite* sprite, Layer** previous_layer, int* current_level)
{ {
std::string name; std::string name;
Layer *layer = NULL; Layer* layer = NULL;
/* read chunk data */ /* read chunk data */
int flags; int flags;
int layer_type; int layer_type;
@ -686,9 +704,9 @@ static Layer *ase_file_read_layer_chunk(FILE *f, Sprite *sprite, Layer **previou
return layer; return layer;
} }
static void ase_file_write_layer_chunk(FILE *f, Layer *layer) static void ase_file_write_layer_chunk(FILE* f, ASE_FrameHeader* frame_header, Layer* layer)
{ {
ase_file_write_start_chunk(f, ASE_FILE_CHUNK_LAYER); ChunkWriter chunk(f, frame_header, ASE_FILE_CHUNK_LAYER);
// Flags // Flags
fputw(layer->getFlags(), f); fputw(layer->getFlags(), f);
@ -716,8 +734,6 @@ static void ase_file_write_layer_chunk(FILE *f, Layer *layer)
/* layer name */ /* layer name */
ase_file_write_string(f, layer->getName()); ase_file_write_string(f, layer->getName());
ase_file_write_close_chunk(f);
/* fop_error(fop, "Layer name \"%s\" child level: %d\n", layer->name, child_level); */ /* fop_error(fop, "Layer name \"%s\" child level: %d\n", layer->name, child_level); */
} }
@ -985,9 +1001,9 @@ static void write_compressed_image(FILE* f, Image* image)
// Cel Chunk // Cel Chunk
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
static Cel *ase_file_read_cel_chunk(FILE *f, Sprite *sprite, FrameNumber frame, static Cel* ase_file_read_cel_chunk(FILE* f, Sprite* sprite, FrameNumber frame,
PixelFormat pixelFormat, PixelFormat pixelFormat,
FileOp *fop, ASE_Header *header, size_t chunk_end) FileOp* fop, ASE_Header* header, size_t chunk_end)
{ {
/* read chunk data */ /* read chunk data */
LayerIndex layer_index = LayerIndex(fgetw(f)); LayerIndex layer_index = LayerIndex(fgetw(f));
@ -1107,13 +1123,13 @@ static Cel *ase_file_read_cel_chunk(FILE *f, Sprite *sprite, FrameNumber frame,
return newCel; return newCel;
} }
static void ase_file_write_cel_chunk(FILE *f, Cel *cel, LayerImage *layer, Sprite *sprite) static void ase_file_write_cel_chunk(FILE* f, ASE_FrameHeader* frame_header, Cel* cel, LayerImage* layer, Sprite* sprite)
{ {
ChunkWriter chunk(f, frame_header, ASE_FILE_CHUNK_CEL);
int layer_index = sprite->layerToIndex(layer); int layer_index = sprite->layerToIndex(layer);
int cel_type = ASE_FILE_COMPRESSED_CEL; int cel_type = ASE_FILE_COMPRESSED_CEL;
ase_file_write_start_chunk(f, ASE_FILE_CHUNK_CEL);
fputw(layer_index, f); fputw(layer_index, f);
fputw(cel->getX(), f); fputw(cel->getX(), f);
fputw(cel->getY(), f); fputw(cel->getY(), f);
@ -1193,14 +1209,12 @@ static void ase_file_write_cel_chunk(FILE *f, Cel *cel, LayerImage *layer, Sprit
break; break;
} }
} }
ase_file_write_close_chunk(f);
} }
static Mask *ase_file_read_mask_chunk(FILE *f) static Mask* ase_file_read_mask_chunk(FILE* f)
{ {
int c, u, v, byte; int c, u, v, byte;
Mask *mask; Mask* mask;
// Read chunk data // Read chunk data
int x = fgetw(f); int x = fgetw(f);
int y = fgetw(f); int y = fgetw(f);
@ -1225,13 +1239,13 @@ static Mask *ase_file_read_mask_chunk(FILE *f)
return mask; return mask;
} }
static void ase_file_write_mask_chunk(FILE *f, Mask *mask) static void ase_file_write_mask_chunk(FILE* f, ASE_FrameHeader* frame_header, Mask* mask)
{ {
ChunkWriter chunk(f, frame_header, ASE_FILE_CHUNK_MASK);
int c, u, v, byte; int c, u, v, byte;
const gfx::Rect& bounds(mask->getBounds()); const gfx::Rect& bounds(mask->getBounds());
ase_file_write_start_chunk(f, ASE_FILE_CHUNK_MASK);
fputw(bounds.x, f); fputw(bounds.x, f);
fputw(bounds.y, f); fputw(bounds.y, f);
fputw(bounds.w, f); fputw(bounds.w, f);
@ -1250,8 +1264,6 @@ static void ase_file_write_mask_chunk(FILE *f, Mask *mask)
byte |= (1<<(7-c)); byte |= (1<<(7-c));
fputc(byte, f); fputc(byte, f);
} }
ase_file_write_close_chunk(f);
} }
} // namespace app } // namespace app

View File

@ -147,7 +147,7 @@ FileOp* fop_to_load_document(const char* filename, int flags)
return NULL; return NULL;
// Get the extension of the filename (in lower case) // Get the extension of the filename (in lower case)
base::string extension = base::string_to_lower(base::get_file_extension(filename)); std::string extension = base::string_to_lower(base::get_file_extension(filename));
PRINTF("Loading file \"%s\" (%s)\n", filename, extension.c_str()); PRINTF("Loading file \"%s\" (%s)\n", filename, extension.c_str());
@ -244,7 +244,7 @@ FileOp* fop_to_save_document(Document* document)
fop->document = document; fop->document = document;
// Get the extension of the filename (in lower case) // Get the extension of the filename (in lower case)
base::string extension = base::string_to_lower(base::get_file_extension(fop->document->getFilename())); std::string extension = base::string_to_lower(base::get_file_extension(fop->document->getFilename()));
PRINTF("Saving document \"%s\" (%s)\n", PRINTF("Saving document \"%s\" (%s)\n",
fop->document->getFilename().c_str(), extension.c_str()); fop->document->getFilename().c_str(), extension.c_str());
@ -258,7 +258,7 @@ FileOp* fop_to_save_document(Document* document)
} }
// Warnings // Warnings
base::string warnings; std::string warnings;
fatal = false; fatal = false;
/* check image type support */ /* check image type support */

View File

@ -38,11 +38,21 @@ extern FileFormat* CreatePcxFormat();
extern FileFormat* CreatePngFormat(); extern FileFormat* CreatePngFormat();
extern FileFormat* CreateTgaFormat(); extern FileFormat* CreateTgaFormat();
static FileFormatsManager* singleton = NULL;
// static // static
FileFormatsManager& FileFormatsManager::instance() FileFormatsManager& FileFormatsManager::instance()
{ {
static FileFormatsManager instance; if (!singleton)
return instance; singleton = new FileFormatsManager();
return *singleton;
}
// static
void FileFormatsManager::destroyInstance()
{
delete singleton;
singleton = NULL;
} }
FileFormatsManager::~FileFormatsManager() FileFormatsManager::~FileFormatsManager()

View File

@ -36,6 +36,7 @@ namespace app {
public: public:
// Returns a singleton of this class. // Returns a singleton of this class.
static FileFormatsManager& instance(); static FileFormatsManager& instance();
static void destroyInstance();
virtual ~FileFormatsManager(); virtual ~FileFormatsManager();

View File

@ -103,11 +103,36 @@ FileFormat* CreateGifFormat()
static int interlaced_offset[] = { 0, 4, 2, 1 }; static int interlaced_offset[] = { 0, 4, 2, 1 };
static int interlaced_jumps[] = { 8, 8, 4, 2 }; static int interlaced_jumps[] = { 8, 8, 4, 2 };
struct GifFilePtr {
public:
typedef int (*CloseFunc)(GifFileType*, int*);
GifFilePtr(GifFileType* ptr, CloseFunc closeFunc) :
m_ptr(ptr), m_closeFunc(closeFunc) {
}
~GifFilePtr() {
int errCode;
m_closeFunc(m_ptr, &errCode);
}
operator GifFileType*() {
return m_ptr;
}
GifFileType* operator->() {
return m_ptr;
}
private:
GifFileType* m_ptr;
CloseFunc m_closeFunc;
};
bool GifFormat::onLoad(FileOp* fop) bool GifFormat::onLoad(FileOp* fop)
{ {
UniquePtr<GifFileType, int(*)(GifFileType*)> gif_file int errCode;
(DGifOpenFileHandle(open_file_descriptor_with_exception(fop->filename, "rb")), GifFilePtr gif_file(DGifOpenFileHandle(open_file_descriptor_with_exception(fop->filename, "rb"), &errCode), &DGifCloseFile);
DGifCloseFile);
if (!gif_file) { if (!gif_file) {
fop_error(fop, "Error loading GIF header.\n"); fop_error(fop, "Error loading GIF header.\n");
@ -131,9 +156,10 @@ bool GifFormat::onLoad(FileOp* fop)
// Setup the first palette using the global color map. // Setup the first palette using the global color map.
ColorMapObject* colormap = gif_file->SColorMap; ColorMapObject* colormap = gif_file->SColorMap;
for (int i=0; i<colormap->ColorCount; ++i) { for (int i=0; i<colormap->ColorCount; ++i) {
current_palette->setEntry(i, rgba(colormap->Colors[i].Red, current_palette->setEntry(i,
colormap->Colors[i].Green, rgba(colormap->Colors[i].Red,
colormap->Colors[i].Blue, 255)); colormap->Colors[i].Green,
colormap->Colors[i].Blue, 255));
} }
} }
else { else {
@ -214,7 +240,7 @@ bool GifFormat::onLoad(FileOp* fop)
for (int y = 0; y < frame_h; ++y) { for (int y = 0; y < frame_h; ++y) {
addr = frame_image->getPixelAddress(0, y); addr = frame_image->getPixelAddress(0, y);
if (DGifGetLine(gif_file, addr, frame_w) == GIF_ERROR) if (DGifGetLine(gif_file, addr, frame_w) == GIF_ERROR)
throw Exception("Invalid image data (%d).\n", GifLastError()); throw Exception("Invalid image data (%d).\n", gif_file->Error);
} }
} }
@ -492,9 +518,8 @@ void GifFormat::onDestroyData(FileOp* fop)
#ifdef ENABLE_SAVE #ifdef ENABLE_SAVE
bool GifFormat::onSave(FileOp* fop) bool GifFormat::onSave(FileOp* fop)
{ {
UniquePtr<GifFileType, int(*)(GifFileType*)> gif_file int errCode;
(EGifOpenFileHandle(open_file_descriptor_with_exception(fop->filename, "wb")), GifFilePtr gif_file(EGifOpenFileHandle(open_file_descriptor_with_exception(fop->filename, "wb"), &errCode), &EGifCloseFile);
EGifCloseFile);
if (!gif_file) if (!gif_file)
throw Exception("Error creating GIF file.\n"); throw Exception("Error creating GIF file.\n");
@ -510,7 +535,7 @@ bool GifFormat::onSave(FileOp* fop)
Palette* current_palette = sprite->getPalette(FrameNumber(0)); Palette* current_palette = sprite->getPalette(FrameNumber(0));
Palette* previous_palette = current_palette; Palette* previous_palette = current_palette;
ColorMapObject* color_map = MakeMapObject(current_palette->size(), NULL); ColorMapObject* color_map = GifMakeMapObject(current_palette->size(), NULL);
for (int i = 0; i < current_palette->size(); ++i) { for (int i = 0; i < current_palette->size(); ++i) {
color_map->Colors[i].Red = rgba_getr(current_palette->getEntry(i)); color_map->Colors[i].Red = rgba_getr(current_palette->getEntry(i));
color_map->Colors[i].Green = rgba_getg(current_palette->getEntry(i)); color_map->Colors[i].Green = rgba_getg(current_palette->getEntry(i));
@ -603,20 +628,36 @@ bool GifFormat::onSave(FileOp* fop)
// Specify loop extension. // Specify loop extension.
if (frame_num == 0 && loop >= 0) { if (frame_num == 0 && loop >= 0) {
unsigned char extension_bytes[11]; if (EGifPutExtensionLeader(gif_file, APPLICATION_EXT_FUNC_CODE) == GIF_ERROR)
throw Exception("Error writing GIF graphics extension record (header section).");
unsigned char extension_bytes[11];
memcpy(extension_bytes, "NETSCAPE2.0", 11); memcpy(extension_bytes, "NETSCAPE2.0", 11);
if (EGifPutExtensionFirst(gif_file, APPLICATION_EXT_FUNC_CODE, 11, extension_bytes) == GIF_ERROR) if (EGifPutExtensionBlock(gif_file, 11, extension_bytes) == GIF_ERROR)
throw Exception("Error writing GIF graphics extension record for frame %d.\n", (int)frame_num); throw Exception("Error writing GIF graphics extension record (first block).");
extension_bytes[0] = 1; extension_bytes[0] = 1;
extension_bytes[1] = (loop & 0xff); extension_bytes[1] = (loop & 0xff);
extension_bytes[2] = (loop >> 8) & 0xff; extension_bytes[2] = (loop >> 8) & 0xff;
if (EGifPutExtensionNext(gif_file, APPLICATION_EXT_FUNC_CODE, 3, extension_bytes) == GIF_ERROR) if (EGifPutExtensionBlock(gif_file, 3, extension_bytes) == GIF_ERROR)
throw Exception("Error writing GIF graphics extension record for frame %d.\n", (int)frame_num); throw Exception("Error writing GIF graphics extension record (second block).");
if (EGifPutExtensionLast(gif_file, APPLICATION_EXT_FUNC_CODE, 0, NULL) == GIF_ERROR) if (EGifPutExtensionTrailer(gif_file) == GIF_ERROR)
throw Exception("Error writing GIF graphics extension record for frame %d.\n", (int)frame_num); throw Exception("Error writing GIF graphics extension record (trailer section).");
}
// Add Aseprite block (at this moment, it's empty).
if (frame_num == 0) {
if (EGifPutExtensionLeader(gif_file, APPLICATION_EXT_FUNC_CODE) == GIF_ERROR)
throw Exception("Error writing GIF comment (header section).");
unsigned char extension_bytes[11];
memcpy(extension_bytes, "ASEPRITE1.0", 11);
if (EGifPutExtensionBlock(gif_file, sizeof(extension_bytes), extension_bytes) == GIF_ERROR)
throw Exception("Error writing GIF comment (first block).");
if (EGifPutExtensionTrailer(gif_file) == GIF_ERROR)
throw Exception("Error writing GIF comment (trailer section).");
} }
// Write graphics extension record (to save the duration of the // Write graphics extension record (to save the duration of the
@ -640,7 +681,7 @@ bool GifFormat::onSave(FileOp* fop)
// Image color map // Image color map
ColorMapObject* image_color_map = NULL; ColorMapObject* image_color_map = NULL;
if (current_palette != previous_palette) { if (current_palette != previous_palette) {
image_color_map = MakeMapObject(current_palette->size(), NULL); image_color_map = GifMakeMapObject(current_palette->size(), NULL);
for (int i = 0; i < current_palette->size(); ++i) { for (int i = 0; i < current_palette->size(); ++i) {
image_color_map->Colors[i].Red = rgba_getr(current_palette->getEntry(i)); image_color_map->Colors[i].Red = rgba_getr(current_palette->getEntry(i));
image_color_map->Colors[i].Green = rgba_getg(current_palette->getEntry(i)); image_color_map->Colors[i].Green = rgba_getg(current_palette->getEntry(i));

View File

@ -24,9 +24,9 @@
namespace app { namespace app {
base::string show_file_selector(const base::string& title, std::string show_file_selector(const std::string& title,
const base::string& initialPath, const std::string& initialPath,
const base::string& showExtensions) const std::string& showExtensions)
{ {
FileSelector fileSelector; FileSelector fileSelector;
return fileSelector.show(title, initialPath, showExtensions); return fileSelector.show(title, initialPath, showExtensions);

View File

@ -20,13 +20,13 @@
#define APP_FILE_SELECTOR_H_INCLUDED #define APP_FILE_SELECTOR_H_INCLUDED
#pragma once #pragma once
#include "base/string.h" #include <string>
namespace app { namespace app {
base::string show_file_selector(const base::string& title, std::string show_file_selector(const std::string& title,
const base::string& initialPath, const std::string& initialPath,
const base::string& showExtensions); const std::string& showExtensions);
} // namespace app } // namespace app

View File

@ -105,9 +105,9 @@ namespace app {
// a position in the file-system // a position in the file-system
class FileItem : public IFileItem { class FileItem : public IFileItem {
public: public:
base::string keyname; std::string keyname;
base::string filename; std::string filename;
base::string displayname; std::string displayname;
FileItem* parent; FileItem* parent;
FileItemList children; FileItemList children;
unsigned int version; unsigned int version;
@ -138,22 +138,22 @@ public:
bool isFolder() const; bool isFolder() const;
bool isBrowsable() const; bool isBrowsable() const;
base::string getKeyName() const; std::string getKeyName() const;
base::string getFileName() const; std::string getFileName() const;
base::string getDisplayName() const; std::string getDisplayName() const;
IFileItem* getParent() const; IFileItem* getParent() const;
const FileItemList& getChildren(); const FileItemList& getChildren();
bool hasExtension(const base::string& csv_extensions); bool hasExtension(const std::string& csv_extensions);
BITMAP* getThumbnail(); BITMAP* getThumbnail();
void setThumbnail(BITMAP* thumbnail); void setThumbnail(BITMAP* thumbnail);
}; };
typedef std::map<base::string, FileItem*> FileItemMap; typedef std::map<std::string, FileItem*> FileItemMap;
typedef std::map<base::string, BITMAP*> ThumbnailMap; typedef std::map<std::string, BITMAP*> ThumbnailMap;
// the root of the file-system // the root of the file-system
static FileItem* rootitem = NULL; static FileItem* rootitem = NULL;
@ -180,15 +180,15 @@ static unsigned int current_file_system_version = 0;
static LPITEMIDLIST clone_pidl(LPITEMIDLIST pidl); static LPITEMIDLIST clone_pidl(LPITEMIDLIST pidl);
static LPITEMIDLIST remove_last_pidl(LPITEMIDLIST pidl); static LPITEMIDLIST remove_last_pidl(LPITEMIDLIST pidl);
static void free_pidl(LPITEMIDLIST pidl); static void free_pidl(LPITEMIDLIST pidl);
static base::string get_key_for_pidl(LPITEMIDLIST pidl); static std::string get_key_for_pidl(LPITEMIDLIST pidl);
static FileItem* get_fileitem_by_fullpidl(LPITEMIDLIST pidl, bool create_if_not); static FileItem* get_fileitem_by_fullpidl(LPITEMIDLIST pidl, bool create_if_not);
static void put_fileitem(FileItem* fileitem); static void put_fileitem(FileItem* fileitem);
#else #else
static FileItem* get_fileitem_by_path(const base::string& path, bool create_if_not); static FileItem* get_fileitem_by_path(const std::string& path, bool create_if_not);
static void for_each_child_callback(const char *filename, int attrib, int param); static void for_each_child_callback(const char *filename, int attrib, int param);
static base::string remove_backslash_if_needed(const base::string& filename); static std::string remove_backslash_if_needed(const std::string& filename);
static base::string get_key_for_filename(const base::string& filename); static std::string get_key_for_filename(const std::string& filename);
static void put_fileitem(FileItem* fileitem); static void put_fileitem(FileItem* fileitem);
#endif #endif
@ -204,10 +204,14 @@ FileSystemModule::FileSystemModule()
#ifdef USE_PIDLS #ifdef USE_PIDLS
/* get the IMalloc interface */ /* get the IMalloc interface */
SHGetMalloc(&shl_imalloc); HRESULT hr = SHGetMalloc(&shl_imalloc);
if (hr != S_OK)
throw std::runtime_error("Error initializing file system. Report this problem. (SHGetMalloc failed.)");
/* get desktop IShellFolder interface */ /* get desktop IShellFolder interface */
SHGetDesktopFolder(&shl_idesktop); hr = SHGetDesktopFolder(&shl_idesktop);
if (hr != S_OK)
throw std::runtime_error("Error initializing file system. Report this problem. (SHGetDesktopFolder failed.)");
#endif #endif
// first version of the file system // first version of the file system
@ -313,7 +317,7 @@ IFileItem* FileSystemModule::getRootFileItem()
return fileitem; return fileitem;
} }
IFileItem* FileSystemModule::getFileItemFromPath(const base::string& path) IFileItem* FileSystemModule::getFileItemFromPath(const std::string& path)
{ {
IFileItem* fileitem = NULL; IFileItem* fileitem = NULL;
@ -321,7 +325,7 @@ IFileItem* FileSystemModule::getFileItemFromPath(const base::string& path)
#ifdef USE_PIDLS #ifdef USE_PIDLS
{ {
ULONG cbEaten; ULONG cbEaten = 0UL;
LPITEMIDLIST fullpidl = NULL; LPITEMIDLIST fullpidl = NULL;
SFGAOF attrib = SFGAO_FOLDER; SFGAOF attrib = SFGAO_FOLDER;
@ -344,7 +348,7 @@ IFileItem* FileSystemModule::getFileItemFromPath(const base::string& path)
} }
#else #else
{ {
base::string buf = remove_backslash_if_needed(path); std::string buf = remove_backslash_if_needed(path);
fileitem = get_fileitem_by_path(buf, true); fileitem = get_fileitem_by_path(buf, true);
} }
#endif #endif
@ -354,11 +358,11 @@ IFileItem* FileSystemModule::getFileItemFromPath(const base::string& path)
return fileitem; return fileitem;
} }
bool FileSystemModule::dirExists(const base::string& path) bool FileSystemModule::dirExists(const std::string& path)
{ {
struct al_ffblk info; struct al_ffblk info;
int ret; int ret;
base::string path2 = base::join_path(path, "*.*"); std::string path2 = base::join_path(path, "*.*");
ret = al_findfirst(path2.c_str(), &info, FA_ALL); ret = al_findfirst(path2.c_str(), &info, FA_ALL);
al_findclose(&info); al_findclose(&info);
@ -389,21 +393,21 @@ bool FileItem::isBrowsable() const
#endif #endif
} }
base::string FileItem::getKeyName() const std::string FileItem::getKeyName() const
{ {
ASSERT(this->keyname != NOTINITIALIZED); ASSERT(this->keyname != NOTINITIALIZED);
return this->keyname; return this->keyname;
} }
base::string FileItem::getFileName() const std::string FileItem::getFileName() const
{ {
ASSERT(this->filename != NOTINITIALIZED); ASSERT(this->filename != NOTINITIALIZED);
return this->filename; return this->filename;
} }
base::string FileItem::getDisplayName() const std::string FileItem::getDisplayName() const
{ {
ASSERT(this->displayname != NOTINITIALIZED); ASSERT(this->displayname != NOTINITIALIZED);
@ -443,24 +447,27 @@ const FileItemList& FileItem::getChildren()
#ifdef USE_PIDLS #ifdef USE_PIDLS
{ {
IShellFolder* pFolder = NULL; IShellFolder* pFolder = NULL;
HRESULT hr;
if (this == rootitem) if (this == rootitem)
pFolder = shl_idesktop; pFolder = shl_idesktop;
else else {
shl_idesktop->BindToObject(this->fullpidl, hr = shl_idesktop->BindToObject(this->fullpidl,
NULL, NULL, IID_IShellFolder, (LPVOID *)&pFolder);
IID_IShellFolder,
(LPVOID *)&pFolder); if (hr != S_OK)
pFolder = NULL;
}
if (pFolder != NULL) { if (pFolder != NULL) {
IEnumIDList *pEnum = NULL; IEnumIDList *pEnum = NULL;
ULONG c, fetched; ULONG c, fetched;
/* get the interface to enumerate subitems */ /* get the interface to enumerate subitems */
pFolder->EnumObjects(win_get_window(), hr = pFolder->EnumObjects(win_get_window(),
SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &pEnum); SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &pEnum);
if (pEnum != NULL) { if (hr == S_OK && pEnum != NULL) {
LPITEMIDLIST itempidl[256]; LPITEMIDLIST itempidl[256];
SFGAOF attribs[256]; SFGAOF attribs[256];
@ -534,7 +541,9 @@ const FileItemList& FileItem::getChildren()
for (it=this->children.begin(); for (it=this->children.begin();
it!=this->children.end(); ) { it!=this->children.end(); ) {
child = static_cast<FileItem*>(*it); child = static_cast<FileItem*>(*it);
if (child->removed) { ASSERT(child != NULL);
if (child && child->removed) {
it = this->children.erase(it); it = this->children.erase(it);
fileitems_map->erase(fileitems_map->find(child->keyname)); fileitems_map->erase(fileitems_map->find(child->keyname));
@ -551,7 +560,7 @@ const FileItemList& FileItem::getChildren()
return this->children; return this->children;
} }
bool FileItem::hasExtension(const base::string& csv_extensions) bool FileItem::hasExtension(const std::string& csv_extensions)
{ {
ASSERT(this->filename != NOTINITIALIZED); ASSERT(this->filename != NOTINITIALIZED);
@ -709,15 +718,16 @@ static void update_by_pidl(FileItem* fileitem)
STRRET strret; STRRET strret;
WCHAR pszName[MAX_PATH]; WCHAR pszName[MAX_PATH];
IShellFolder *pFolder = NULL; IShellFolder *pFolder = NULL;
HRESULT hr;
if (fileitem == rootitem) if (fileitem == rootitem)
pFolder = shl_idesktop; pFolder = shl_idesktop;
else { else {
ASSERT(fileitem->parent); ASSERT(fileitem->parent);
shl_idesktop->BindToObject(fileitem->parent->fullpidl, hr = shl_idesktop->BindToObject(fileitem->parent->fullpidl,
NULL, NULL, IID_IShellFolder, (LPVOID *)&pFolder);
IID_IShellFolder, if (hr != S_OK)
(LPVOID *)&pFolder); pFolder = NULL;
} }
/****************************************/ /****************************************/
@ -863,7 +873,7 @@ static void free_pidl(LPITEMIDLIST pidl)
shl_imalloc->Free(pidl); shl_imalloc->Free(pidl);
} }
static base::string get_key_for_pidl(LPITEMIDLIST pidl) static std::string get_key_for_pidl(LPITEMIDLIST pidl)
{ {
#if 0 #if 0
char *key = base_malloc(get_pidl_size(pidl)+1); char *key = base_malloc(get_pidl_size(pidl)+1);
@ -894,7 +904,8 @@ static base::string get_key_for_pidl(LPITEMIDLIST pidl)
if (shl_idesktop->GetDisplayNameOf(pidl, if (shl_idesktop->GetDisplayNameOf(pidl,
SHGDN_INFOLDER | SHGDN_FORPARSING, SHGDN_INFOLDER | SHGDN_FORPARSING,
&strret) == S_OK) { &strret) == S_OK) {
StrRetToBuf(&strret, pidl, pszName, MAX_PATH); if (StrRetToBuf(&strret, pidl, pszName, MAX_PATH) != S_OK)
pszName[0] = 0;
//PRINTF("FS: + %s\n", pszName); //PRINTF("FS: + %s\n", pszName);
@ -984,7 +995,7 @@ static void put_fileitem(FileItem* fileitem)
// Allegro for_each_file: Portable // Allegro for_each_file: Portable
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
static FileItem* get_fileitem_by_path(const base::string& path, bool create_if_not) static FileItem* get_fileitem_by_path(const std::string& path, bool create_if_not)
{ {
if (path.empty()) if (path.empty())
return rootitem; return rootitem;
@ -1013,7 +1024,7 @@ static FileItem* get_fileitem_by_path(const base::string& path, bool create_if_n
// get the parent // get the parent
{ {
base::string parent_path = remove_backslash_if_needed(base::join_path(base::get_file_path(path), "")); std::string parent_path = remove_backslash_if_needed(base::join_path(base::get_file_path(path), ""));
fileitem->parent = get_fileitem_by_path(parent_path, true); fileitem->parent = get_fileitem_by_path(parent_path, true);
} }
@ -1055,7 +1066,7 @@ static void for_each_child_callback(const char *filename, int attrib, int param)
fileitem->insertChildSorted(child); fileitem->insertChildSorted(child);
} }
static base::string remove_backslash_if_needed(const base::string& filename) static std::string remove_backslash_if_needed(const std::string& filename)
{ {
if (!filename.empty() && base::is_path_separator(*(filename.end()-1))) { if (!filename.empty() && base::is_path_separator(*(filename.end()-1))) {
int len = filename.size(); int len = filename.size();
@ -1074,9 +1085,9 @@ static base::string remove_backslash_if_needed(const base::string& filename)
return filename; return filename;
} }
static base::string get_key_for_filename(const base::string& filename) static std::string get_key_for_filename(const std::string& filename)
{ {
base::string buf(filename); std::string buf(filename);
#if !defined CASE_SENSITIVE #if !defined CASE_SENSITIVE
buf.tolower(); buf.tolower();

View File

@ -20,8 +20,9 @@
#define APP_FILE_SYSTEM_H_INCLUDED #define APP_FILE_SYSTEM_H_INCLUDED
#pragma once #pragma once
#include "base/string.h" #include "base/mutex.h"
#include <string>
#include <vector> #include <vector>
struct BITMAP; struct BITMAP;
@ -49,10 +50,27 @@ namespace app {
// Returns the FileItem through the specified "path". // Returns the FileItem through the specified "path".
// Warning: You have to call path.fix_separators() before. // Warning: You have to call path.fix_separators() before.
IFileItem* getFileItemFromPath(const base::string& path); IFileItem* getFileItemFromPath(const std::string& path);
bool dirExists(const base::string& path); bool dirExists(const std::string& path);
void lock() { m_mutex.lock(); }
void unlock() { m_mutex.unlock(); }
private:
base::mutex m_mutex;
};
class LockFS {
public:
LockFS(FileSystemModule* fs) : m_fs(fs) {
m_fs->lock();
}
~LockFS() {
m_fs->unlock();
}
private:
FileSystemModule* m_fs;
}; };
class IFileItem { class IFileItem {
@ -62,14 +80,14 @@ namespace app {
virtual bool isFolder() const = 0; virtual bool isFolder() const = 0;
virtual bool isBrowsable() const = 0; virtual bool isBrowsable() const = 0;
virtual base::string getKeyName() const = 0; virtual std::string getKeyName() const = 0;
virtual base::string getFileName() const = 0; virtual std::string getFileName() const = 0;
virtual base::string getDisplayName() const = 0; virtual std::string getDisplayName() const = 0;
virtual IFileItem* getParent() const = 0; virtual IFileItem* getParent() const = 0;
virtual const FileItemList& getChildren() = 0; virtual const FileItemList& getChildren() = 0;
virtual bool hasExtension(const base::string& csv_extensions) = 0; virtual bool hasExtension(const std::string& csv_extensions) = 0;
virtual BITMAP* getThumbnail() = 0; virtual BITMAP* getThumbnail() = 0;
virtual void setThumbnail(BITMAP* thumbnail) = 0; virtual void setThumbnail(BITMAP* thumbnail) = 0;

View File

@ -34,6 +34,32 @@ namespace app {
return child; return child;
} }
class finder {
public:
finder(ui::Widget* parent) : m_parent(parent) {
}
finder& operator>>(const char* id) {
m_lastId = id;
return *this;
}
finder& operator>>(const std::string& id) {
m_lastId = id;
return *this;
}
template<typename T>
finder& operator>>(T*& child) {
child = app::find_widget<T>(m_parent, m_lastId.c_str());
return *this;
}
private:
ui::Widget* m_parent;
std::string m_lastId;
};
} // namespace app } // namespace app
#endif #endif

View File

@ -52,7 +52,7 @@ GuiXml::GuiXml()
m_doc = app::open_xml(rf.filename()); m_doc = app::open_xml(rf.filename());
} }
base::string GuiXml::version() std::string GuiXml::version()
{ {
TiXmlHandle handle(m_doc); TiXmlHandle handle(m_doc);
TiXmlElement* xmlKey = handle.FirstChild("gui").ToElement(); TiXmlElement* xmlKey = handle.FirstChild("gui").ToElement();

View File

@ -21,7 +21,8 @@
#pragma once #pragma once
#include "app/xml_document.h" #include "app/xml_document.h"
#include "base/string.h"
#include <string>
namespace app { namespace app {
@ -43,7 +44,7 @@ namespace app {
return m_doc->Value(); return m_doc->Value();
} }
base::string version(); std::string version();
private: private:
GuiXml(); GuiXml();

84
src/app/handle_anidir.cpp Normal file
View File

@ -0,0 +1,84 @@
/* Aseprite
* Copyright (C) 2001-2014 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "app/handle_anidir.h"
#include "app/settings/document_settings.h"
#include "raster/sprite.h"
namespace app {
raster::FrameNumber calculate_next_frame(
raster::Sprite* sprite,
raster::FrameNumber frame,
IDocumentSettings* docSettings,
bool& pingPongForward)
{
FrameNumber first = FrameNumber(0);
FrameNumber last = sprite->getLastFrame();
if (docSettings->getLoopAnimation()) {
FrameNumber loopBegin, loopEnd;
docSettings->getLoopRange(&loopBegin, &loopEnd);
if (loopBegin < first) loopBegin = first;
if (loopEnd > last) loopEnd = last;
first = loopBegin;
last = loopEnd;
}
switch (docSettings->getAnimationDirection()) {
case IDocumentSettings::AniDir_Normal:
frame = frame.next();
if (frame > last) frame = first;
break;
case IDocumentSettings::AniDir_Reverse:
frame = frame.previous();
if (frame < first) frame = last;
break;
case IDocumentSettings::AniDir_PingPong:
if (pingPongForward) {
frame = frame.next();
if (frame > last) {
frame = last.previous();
if (frame < first) frame = first;
pingPongForward = false;
}
}
else {
frame = frame.previous();
if (frame < first) {
frame = first.next();
if (frame > last) frame = last;
pingPongForward = true;
}
}
break;
}
return frame;
}
} // namespace app

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