Added the new Animator Editor.

Other minor changes & refactorings.
This commit is contained in:
David Capello 2008-04-27 20:27:06 +00:00
parent 215fd7dbd0
commit 837cf39c54
49 changed files with 2296 additions and 483 deletions

View File

@ -1,3 +1,38 @@
2008-04-27 David A. Capello <dacap@users.sourceforge.net>
* src/jinete/jdraw.c (ji_move_region): Renamed ji_blit_region to
ji_move_region.
* src/jinete/jwidget.c (jwidget_scroll): Done.
* src/jinete/jdraw.c (jdraw_inverted_sprite): Rewritten to use
Allegro routines instead of get/putpixel.
2008-04-26 David A. Capello <dacap@users.sourceforge.net>
* src/dialogs/aniedit.c (anieditor_msg_proc): Now the user can
move layers.
* src/script/functions.c (MoveLayerAfter): Added.
* src/widgets/colbar.c (FGBGSIZE): Added.
* src/modules/gui.h: Renamed GUISCALE to guiscale() function.
* src/script/functions.c (SetFrameLength): Added.
(MoveFrameBefore): Fixed to undo frame-lengths.
* src/raster/undo.c (undo_set_frlen): Added.
2008-04-17 David A. Capello <dacap@users.sourceforge.net>
* src/dialogs/aniedit.c: In these days I was working in the new
Animation Editor. Right now you can create/remove/move
frames. Select layers and frame. See thumbnails. Change the
separator position. It doesn't support scroll yet.
* src/script/functions.c (MoveFrameBefore): Added.
2008-04-14 David A. Capello <dacap@users.sourceforge.net>
* src/modules/tools.c: Added the Jumble tool & ink.

View File

@ -10,6 +10,7 @@ NEWS
+ Transparent cel handling for the end-user (you can move a cel and
don't worry about its bounds).
+ Rewritten the color-bar and color-selector dialog.
+ New tools: Eraser, Blur, Jumble.
+ Replaced the "List" menu with the tabs selector.
+ Rewritten the File Selector:
+ Preview support.
@ -17,10 +18,11 @@ NEWS
+ History of navigation (Back/Forward).
+ In Windows: you can visit Desktop, My Documents and My Computer
locations.
+ Optimized the loading/saving operations (using threads).
+ Optimized some operations like load/save files and "apply effect"
(convolution matrices, color curves, median, etc.)
+ Restructured all the menus (more user friendly options).
+ Enhanced GUI:
+ more borders for windows and more spacing between widgets.
+ more borders for windows and more spacing between controls.
+ better mouse behavior (now in Windows the mouse is captured).
+ added tooltips.
+ Added screen pixel-scaling support (with double-buffering). This
@ -36,10 +38,10 @@ NEWS
to create scripts.
- Removed screen saver.
- Removed sessions.
- Removed draw-text (it'll return in next versions).
- Removed layer-sets (the Film-Editor can't handle them right at the
moment).
- Removed mapgen.
- Removed draw-text (it'll return in next versions like text-layers).
- Removed layer-sets (the Animation-Editor can't handle them right at
the moment).
- Removed map-generation utility.
- Removed linked-cels (were complex for the end-user).
0.5

View File

@ -10,11 +10,29 @@ Next beta
+ quick_swap
- tooltips for color-bar.
+ agregar soporte para UNDO al cambiar los colores de la paleta.
- search "TODO next release"
- search "TODO remove me"
High priority work
------------------
- search for TODO;
- add AseContext structure to handle the current state of the
application (and hook changes in the context/options):
+ src/ase/ directory
+ src/ase/context.[ch]
+ the current sprite should be in the AseContext
+ the commands should be enabled/disabled/checked by the current
context state
+ the commands should use a new ase/ API and not the raster/ low-level
+ the dependencies should be:
commands/ -> ase/ -> raster/ -> jinete/
+ the list of 'sprites' should be in the context (maybe a
AseSharedContext).
+ the scripts should start with a new default AseContext (but
with the AseSharedContext visible)
+
- brush options by tool.
- if there is activated the Tools Configuration dialog box, the
Shift+G and Shift+S should update it
+ Solution: with hooks and Options (add core/options.[ch])
@ -64,9 +82,6 @@ High priority work
- when press Plus/Minus pad in the editor and the configuration tool
window is active, the slider of the "Brush Size" must be updated.
- make keys like 9, 0, + Pad, - Pad configurable.
- drawing tools:
+ real-spray;
+ Animator Pro like: oval, petal, rpoly, star, poly, spiral;
Wish-list
---------

View File

@ -35,6 +35,126 @@ brightness 1 1 0 0 { 1 } 1 +8 rgb
contrast 1 1 0 0 { 1 } 1 -8 rgb
negative 1 1 0 0 { -1 } auto auto rgb
blur-3x3 3 3 1 1
{ 1 2 1
2 4 2
1 2 1 } auto auto rgba
blur-3x3-hard 3 3 1 1
{ 0 1 0
1 8 1
0 1 0 } auto auto rgba
blur-5x5 5 5 2 2
{ 1 2 3 2 1
2 3 4 3 2
3 4 5 4 3
2 3 4 3 2
1 2 3 2 1 } auto auto rgba
blur-7x7 7 7 3 3
{ 1 2 3 4 3 2 1
2 3 4 5 4 3 2
3 4 5 6 5 4 3
4 5 6 7 6 5 4
3 4 5 6 5 4 3
2 3 4 5 4 3 2
1 2 3 4 3 2 1 } auto auto rgba
blur-9x9 9 9 4 4
{ 1 2 3 4 5 4 3 2 1
2 3 4 5 6 5 4 3 2
3 4 5 6 7 6 5 4 3
4 5 6 7 8 7 6 5 4
5 6 7 8 9 8 7 6 5
4 5 6 7 8 7 6 5 4
3 4 5 6 7 6 5 4 3
2 3 4 5 6 5 4 3 2
1 2 3 4 5 4 3 2 1 } auto auto rgba
blur-17x17 17 17 8 8
{ 1 2 3 4 5 6 7 8 9 8 7 6 5 4 3 2 1
2 3 4 5 6 7 8 9 10 9 8 7 6 5 4 3 2
3 4 5 6 7 8 9 10 11 10 9 8 7 6 5 4 3
4 5 6 7 8 9 10 11 12 11 10 9 8 7 6 5 4
5 6 7 8 9 10 11 12 13 12 11 10 9 8 7 6 5
6 7 8 9 10 11 12 13 14 13 12 11 10 9 8 7 6
7 8 9 10 11 12 13 14 15 14 13 12 11 10 9 8 7
8 9 10 11 12 13 14 15 16 15 14 13 12 11 10 9 8
9 10 11 12 13 14 15 16 17 16 15 14 13 12 11 10 9
8 9 10 11 12 13 14 15 16 15 14 13 12 11 10 9 8
7 8 9 10 11 12 13 14 15 14 13 12 11 10 9 8 7
6 7 8 9 10 11 12 13 14 13 12 11 10 9 8 7 6
5 6 7 8 9 10 11 12 13 12 11 10 9 8 7 6 5
4 5 6 7 8 9 10 11 12 11 10 9 8 7 6 5 4
3 4 5 6 7 8 9 10 11 10 9 8 7 6 5 4 3
2 3 4 5 6 7 8 9 10 9 8 7 6 5 4 3 2
1 2 3 4 5 6 7 8 9 8 7 6 5 4 3 2 1 } auto auto rgba
blur-5x3-left 5 3 0 1
{ 2 3 2 1 0
6 4 3 2 1
2 3 2 1 0 } auto auto rgba
blur-17x3-left 17 3 0 1
{ 14 16 13 12 10 8 6 4 3 2 1 0 0 0 0 0 0
24 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
14 16 13 12 10 8 6 4 3 2 1 0 0 0 0 0 0 } auto auto rgba
blur-3x17-top 3 17 1 0
{ 14 24 14
16 16 16
13 15 13
12 14 12
10 13 10
8 12 8
6 11 6
4 10 4
3 9 3
2 8 2
1 7 1
0 6 0
0 5 0
0 4 0
0 3 0
0 2 0
0 1 0 } auto auto rgba
blur-5x5-diagonal(\) 5 5 2 2
{ 1 1 1 0 0
1 2 2 1 0
1 2 3 2 1
0 1 2 2 1
0 0 1 1 1 } auto auto rgba
blur-5x5-diagonal(/) 5 5 2 2
{ 0 0 1 1 1
0 1 2 2 1
1 2 3 2 1
1 2 2 1 0
1 1 1 0 0 } auto auto rgba
sharpen-3x3 3 3 1 1
{ -1 -1 -1
-1 16 -1
-1 -1 -1 } 8 0 rgba
sharpen-5x5 5 5 2 2
{ 0 -1 -2 -1 0
-1 -2 -4 -2 -1
-2 -4 48 -4 -2
-1 -2 -4 -2 -1
0 -1 -2 -1 0 } 8 0 rgba
sharpen-7x7 7 7 3 3
{ 0 -1 -2 -4 -2 -1 0
-1 -2 -4 -8 -4 -2 -1
-2 -4 -8 -16 -8 -4 -2
-4 -8 -16 224 -16 -8 -4
-2 -4 -8 -16 -8 -4 -2
-1 -2 -4 -8 -4 -2 -1
0 -1 -2 -4 -2 -1 -0 } 16 0 rgba
edges-find 3 3 1 1
{ -1 -1 -1
-1 8 -1
@ -200,123 +320,3 @@ drunk-17x17_o 17 17 8 8
0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0
0 0 0 0 0 1 1 0 0 0 1 1 0 0 0 0 0
0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 } auto auto rgba
sharpen-3x3 3 3 1 1
{ -1 -1 -1
-1 16 -1
-1 -1 -1 } 8 0 rgba
sharpen-5x5 5 5 2 2
{ 0 -1 -2 -1 0
-1 -2 -4 -2 -1
-2 -4 48 -4 -2
-1 -2 -4 -2 -1
0 -1 -2 -1 0 } 8 0 rgba
sharpen-7x7 7 7 3 3
{ 0 -1 -2 -4 -2 -1 0
-1 -2 -4 -8 -4 -2 -1
-2 -4 -8 -16 -8 -4 -2
-4 -8 -16 224 -16 -8 -4
-2 -4 -8 -16 -8 -4 -2
-1 -2 -4 -8 -4 -2 -1
0 -1 -2 -4 -2 -1 -0 } 16 0 rgba
smooth-3x3 3 3 1 1
{ 1 2 1
2 4 2
1 2 1 } auto auto rgba
smooth-3x3-hard 3 3 1 1
{ 0 1 0
1 8 1
0 1 0 } auto auto rgba
smooth-5x5 5 5 2 2
{ 1 2 3 2 1
2 3 4 3 2
3 4 5 4 3
2 3 4 3 2
1 2 3 2 1 } auto auto rgba
smooth-7x7 7 7 3 3
{ 1 2 3 4 3 2 1
2 3 4 5 4 3 2
3 4 5 6 5 4 3
4 5 6 7 6 5 4
3 4 5 6 5 4 3
2 3 4 5 4 3 2
1 2 3 4 3 2 1 } auto auto rgba
smooth-9x9 9 9 4 4
{ 1 2 3 4 5 4 3 2 1
2 3 4 5 6 5 4 3 2
3 4 5 6 7 6 5 4 3
4 5 6 7 8 7 6 5 4
5 6 7 8 9 8 7 6 5
4 5 6 7 8 7 6 5 4
3 4 5 6 7 6 5 4 3
2 3 4 5 6 5 4 3 2
1 2 3 4 5 4 3 2 1 } auto auto rgba
smooth-17x17 17 17 8 8
{ 1 2 3 4 5 6 7 8 9 8 7 6 5 4 3 2 1
2 3 4 5 6 7 8 9 10 9 8 7 6 5 4 3 2
3 4 5 6 7 8 9 10 11 10 9 8 7 6 5 4 3
4 5 6 7 8 9 10 11 12 11 10 9 8 7 6 5 4
5 6 7 8 9 10 11 12 13 12 11 10 9 8 7 6 5
6 7 8 9 10 11 12 13 14 13 12 11 10 9 8 7 6
7 8 9 10 11 12 13 14 15 14 13 12 11 10 9 8 7
8 9 10 11 12 13 14 15 16 15 14 13 12 11 10 9 8
9 10 11 12 13 14 15 16 17 16 15 14 13 12 11 10 9
8 9 10 11 12 13 14 15 16 15 14 13 12 11 10 9 8
7 8 9 10 11 12 13 14 15 14 13 12 11 10 9 8 7
6 7 8 9 10 11 12 13 14 13 12 11 10 9 8 7 6
5 6 7 8 9 10 11 12 13 12 11 10 9 8 7 6 5
4 5 6 7 8 9 10 11 12 11 10 9 8 7 6 5 4
3 4 5 6 7 8 9 10 11 10 9 8 7 6 5 4 3
2 3 4 5 6 7 8 9 10 9 8 7 6 5 4 3 2
1 2 3 4 5 6 7 8 9 8 7 6 5 4 3 2 1 } auto auto rgba
smooth-5x3-left 5 3 0 1
{ 2 3 2 1 0
6 4 3 2 1
2 3 2 1 0 } auto auto rgba
smooth-17x3-left 17 3 0 1
{ 14 16 13 12 10 8 6 4 3 2 1 0 0 0 0 0 0
24 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
14 16 13 12 10 8 6 4 3 2 1 0 0 0 0 0 0 } auto auto rgba
smooth-3x17-top 3 17 1 0
{ 14 24 14
16 16 16
13 15 13
12 14 12
10 13 10
8 12 8
6 11 6
4 10 4
3 9 3
2 8 2
1 7 1
0 6 0
0 5 0
0 4 0
0 3 0
0 2 0
0 1 0 } auto auto rgba
smooth-5x5-diagonal(\) 5 5 2 2
{ 1 1 1 0 0
1 2 2 1 0
1 2 3 2 1
0 1 2 2 1
0 0 1 1 1 } auto auto rgba
smooth-5x5-diagonal(/) 5 5 2 2
{ 0 0 1 1 1
0 1 2 2 1
1 2 3 2 1
1 2 2 1 0
1 1 1 0 0 } auto auto rgba

View File

@ -30,6 +30,8 @@
<!-- layer -->
<key command="layer_properties" shortcut="Shift+P" />
<key command="new_layer" shortcut="Shift+N" />
<key command="goto_previous_layer" shortcut="Down" />
<key command="goto_next_layer" shortcut="Up" />
<!-- frame -->
<key command="new_frame" shortcut="N" />
<key command="goto_first_frame" shortcut="Home" />

View File

@ -1,7 +1,7 @@
<!-- ASE - Allegro Sprite Editor -->
<!-- Copyright (C) 2001-2008 by David A. Capello -->
<jinete>
<window text="Configure Screen" name="configure_screen" width="200">
<window text="Configure Screen" name="configure_screen">
<box vertical>
<box horizontal expansive>
<box vertical homogeneous>

View File

@ -31,6 +31,7 @@ COMMON_SOURCES = \
src/commands/cmd_flip.c \
src/commands/cmd_frame_properties.c \
src/commands/cmd_goto_frame.c \
src/commands/cmd_goto_layer.c \
src/commands/cmd_grid.c \
src/commands/cmd_invert_mask.c \
src/commands/cmd_layer_from_background.c \
@ -86,6 +87,7 @@ COMMON_SOURCES = \
src/core/dirs.c \
src/core/file_system.c \
src/core/modules.c \
src/dialogs/aniedit.c \
src/dialogs/canvasze.c \
src/dialogs/drawtext.c \
src/dialogs/filesel.c \

View File

@ -24,7 +24,7 @@
/* #include "core/app.h" */
#include "modules/sprites.h"
/* #include "raster/sprite.h" */
#include "dialogs/filmedit.h"
#include "dialogs/aniedit.h"
static bool cmd_film_editor_enabled(const char *argument)
{
@ -33,7 +33,7 @@ static bool cmd_film_editor_enabled(const char *argument)
static void cmd_film_editor_execute(const char *argument)
{
switch_between_film_and_sprite_editor();
switch_between_animation_and_sprite_editor();
}
Command cmd_film_editor = {

View File

@ -80,7 +80,7 @@ void dialogs_frame_length(int sprite_frame)
sprite_set_speed(current_sprite, num);
}
else
sprite_set_frlen(current_sprite, num, sprite_frame);
sprite_set_frlen(current_sprite, sprite_frame, num);
}
jwidget_free(window);
}

View File

@ -0,0 +1,99 @@
/* ASE - Allegro Sprite Editor
* Copyright (C) 2008 David A. 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
*/
#include "config.h"
#include "commands/commands.h"
#include "core/app.h"
#include "modules/gui.h"
#include "modules/editors.h"
#include "modules/sprites.h"
#include "raster/layer.h"
#include "raster/sprite.h"
#include "widgets/editor.h"
#include "widgets/statebar.h"
/* ======================== */
/* goto_previous_layer */
/* ======================== */
static bool cmd_goto_previous_layer_enabled(const char *argument)
{
return current_sprite != NULL;
}
static void cmd_goto_previous_layer_execute(const char *argument)
{
int i = sprite_layer2index(current_sprite, current_sprite->layer);
if (i > 0)
i--;
else
i = sprite_count_layers(current_sprite)-1;
current_sprite->layer = sprite_index2layer(current_sprite, i);
update_screen_for_sprite(current_sprite);
editor_update_statusbar_for_standby(current_editor);
statusbar_show_tip(app_get_statusbar(), 1000,
_("Layer `%s' selected"),
current_sprite->layer->name);
}
/* ======================== */
/* goto_next_layer */
/* ======================== */
static bool cmd_goto_next_layer_enabled(const char *argument)
{
return current_sprite != NULL;
}
static void cmd_goto_next_layer_execute(const char *argument)
{
int i = sprite_layer2index(current_sprite, current_sprite->layer);
if (i < sprite_count_layers(current_sprite)-1)
i++;
else
i = 0;
current_sprite->layer = sprite_index2layer(current_sprite, i);
update_screen_for_sprite(current_sprite);
editor_update_statusbar_for_standby(current_editor);
statusbar_show_tip(app_get_statusbar(), 1000,
_("Layer `%s' selected"),
current_sprite->layer->name);
}
Command cmd_goto_previous_layer = {
CMD_GOTO_PREVIOUS_LAYER,
cmd_goto_previous_layer_enabled,
NULL,
cmd_goto_previous_layer_execute,
};
Command cmd_goto_next_layer = {
CMD_GOTO_NEXT_LAYER,
cmd_goto_next_layer_enabled,
NULL,
cmd_goto_next_layer_execute,
};

View File

@ -76,7 +76,7 @@ static void cmd_layer_properties_execute(const char *argument)
jlistbox_select_index(list_bm, layer->blend_mode);
jview_attach(view_bm, list_bm);
jwidget_set_min_size(view_bm, 128, 64);
jwidget_set_min_size(view_bm, 128*guiscale(), 64*guiscale());
jwidget_expansive(view_bm, TRUE);
}

View File

@ -18,6 +18,7 @@
#include "config.h"
#include <assert.h>
#include "jinete/jinete.h"
#include "commands/commands.h"
@ -126,14 +127,18 @@ static bool copy_cel_in_next_frame(Sprite *sprite, Layer *layer, int frame)
Cel *src_cel;
Cel *dst_cel;
assert(frame > 0);
/* create a copy of the previous cel */
src_cel = layer_get_cel(layer, frame-1);
src_image = src_cel ? stock_get_image(sprite->stock,
src_cel->image):
NULL;
if (src_image == NULL || frame == 0)
dst_image = image_new(sprite->imgtype, sprite->w, sprite->h);
if (src_image == NULL) {
/* do nothing, it will be a transparent cel */
return TRUE;
}
else
dst_image = image_new_copy(src_image);

View File

@ -23,6 +23,7 @@
#include "modules/sprites.h"
#include "raster/cel.h"
#include "raster/layer.h"
#include "raster/undo.h"
#include "raster/sprite.h"
#include "script/functions.h"
@ -39,11 +40,14 @@ static bool cmd_remove_cel_enabled(const char *argument)
static void cmd_remove_cel_execute(const char *argument)
{
Cel *cel = layer_get_cel(current_sprite->layer,
current_sprite->frame);
Sprite *sprite = current_sprite;
Cel *cel = layer_get_cel(sprite->layer, sprite->frame);
RemoveCel(current_sprite->layer, cel);
update_screen_for_sprite(current_sprite);
if (undo_is_enabled(sprite->undo))
undo_set_label(sprite->undo, "Remove Cel");
RemoveCel(sprite->layer, cel);
update_screen_for_sprite(sprite);
}
Command cmd_remove_cel = {

View File

@ -66,7 +66,9 @@ extern Command cmd_frame_properties;
extern Command cmd_goto_first_frame;
extern Command cmd_goto_last_frame;
extern Command cmd_goto_next_frame;
extern Command cmd_goto_next_layer;
extern Command cmd_goto_previous_frame;
extern Command cmd_goto_previous_layer;
extern Command cmd_invert_color;
extern Command cmd_invert_mask;
extern Command cmd_layer_from_background;
@ -160,7 +162,9 @@ static Command *commands[] = {
&cmd_goto_first_frame,
&cmd_goto_last_frame,
&cmd_goto_next_frame,
&cmd_goto_next_layer,
&cmd_goto_previous_frame,
&cmd_goto_previous_layer,
&cmd_invert_color,
&cmd_invert_mask,
&cmd_layer_from_background,

View File

@ -60,7 +60,9 @@
#define CMD_GOTO_FIRST_FRAME "goto_first_frame"
#define CMD_GOTO_LAST_FRAME "goto_last_frame"
#define CMD_GOTO_NEXT_FRAME "goto_next_frame"
#define CMD_GOTO_NEXT_LAYER "goto_next_layer"
#define CMD_GOTO_PREVIOUS_FRAME "goto_previous_frame"
#define CMD_GOTO_PREVIOUS_LAYER "goto_previous_layer"
#define CMD_INVERT_COLOR "invert_color"
#define CMD_INVERT_MASK "invert_mask"
#define CMD_LAYER_FROM_BACKGROUND "layer_from_background"

View File

@ -646,21 +646,27 @@ int get_color_for_layer(Layer *layer, color_t color)
int fixup_color_for_layer(Layer *layer, int color)
{
if (layer_is_background(layer)) {
switch (layer->sprite->imgtype) {
case IMAGE_RGB:
if (_rgba_geta(color) < 255) {
return _rgba(_rgba_getr(color),
_rgba_getg(color),
_rgba_getb(color), 255);
}
break;
case IMAGE_GRAYSCALE:
if (_graya_geta(color) < 255) {
return _graya(_graya_getv(color), 255);
}
break;
}
if (layer_is_background(layer))
return fixup_color_for_background(layer->sprite->imgtype, color);
else
return color;
}
int fixup_color_for_background(int imgtype, int color)
{
switch (imgtype) {
case IMAGE_RGB:
if (_rgba_geta(color) < 255) {
return _rgba(_rgba_getr(color),
_rgba_getg(color),
_rgba_getb(color), 255);
}
break;
case IMAGE_GRAYSCALE:
if (_graya_geta(color) < 255) {
return _graya(_graya_getv(color), 255);
}
break;
}
return color;
}

View File

@ -62,6 +62,7 @@ int get_color_for_allegro(int depth, color_t color);
int get_color_for_image(int imgtype, color_t color);
int get_color_for_layer(struct Layer *layer, color_t color);
int fixup_color_for_layer(struct Layer *layer, int color);
int fixup_color_for_background(int imgtype, int color);
color_t image_getpixel_color(struct Image *image, int x, int y);
void color_to_formalstring(int imgtype, color_t color, char *buf,

1346
src/dialogs/aniedit.c Normal file

File diff suppressed because it is too large Load Diff

25
src/dialogs/aniedit.h Normal file
View File

@ -0,0 +1,25 @@
/* ASE - Allegro Sprite Editor
* Copyright (C) 2001-2008 David A. 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 DIALOGS_ANIEDIT_H
#define DIALOGS_ANIEDIT_H
void switch_between_animation_and_sprite_editor(void);
#endif /* DIALOGS_ANIEDIT_H */

View File

@ -396,13 +396,17 @@ static bool layer_box_msg_proc(JWidget widget, JMessage msg)
}
/* new_frame, remove_frame, new_cel, remove_cel */
if (command &&
if ((command != NULL) &&
(strcmp(command->name, CMD_NEW_CEL) == 0 ||
strcmp(command->name, CMD_NEW_FRAME) == 0 ||
strcmp(command->name, CMD_NEW_LAYER) == 0 ||
strcmp(command->name, CMD_REMOVE_CEL) == 0 ||
strcmp(command->name, CMD_REMOVE_FRAME) == 0 ||
strcmp(command->name, CMD_REMOVE_LAYER) == 0)) {
strcmp(command->name, CMD_REMOVE_LAYER) == 0 ||
strcmp(command->name, CMD_GOTO_FIRST_FRAME) == 0 ||
strcmp(command->name, CMD_GOTO_PREVIOUS_FRAME) == 0 ||
strcmp(command->name, CMD_GOTO_NEXT_FRAME) == 0 ||
strcmp(command->name, CMD_GOTO_LAST_FRAME) == 0)) {
command_execute(command, NULL);
update_after_command(layer_box);
return TRUE;
@ -679,7 +683,7 @@ static bool cel_box_msg_proc(JWidget widget, JMessage msg)
k_image = cel->image;
cel_link = cel_is_link(cel, layer);
thumbnail = generate_thumbnail(cel_link ? cel_link: cel, sprite);
thumbnail = generate_thumbnail(layer, cel_link ? cel_link: cel, sprite);
x1 = k_frame*FRMSIZE-scroll_x+FRMSIZE/2-THUMBSIZE/2;
y1 = y+3;

View File

@ -38,7 +38,7 @@
#define ASE_FILE_RAW_CEL 0
#define ASE_FILE_LINK_CEL 1
#define ASE_FILE_RLE_COMPRESSED_CEL 2
#define ASE_FILE_RLE_COMPRESSED_CEL 2 /* TODO change this with zlib */
typedef struct ASE_Header
{
@ -174,7 +174,7 @@ static bool load_ASE(FileOp *fop)
if (frame_header.magic == ASE_FILE_FRAME_MAGIC) {
/* use frame-duration field? */
if (frame_header.duration > 0)
sprite_set_frlen(sprite, frame_header.duration, frame);
sprite_set_frlen(sprite, frame, frame_header.duration);
/* read chunks */
for (c=0; c<frame_header.chunks; c++) {

View File

@ -175,9 +175,8 @@ static bool load_FLI(FileOp *fop)
#endif
/* the palette and the image don't change: add duration to the last added frame */
else {
sprite_set_frlen(sprite,
sprite_get_frlen(sprite, frpos_out)+fli_header.speed,
frpos_out);
sprite_set_frlen(sprite, frpos_out,
sprite_get_frlen(sprite, frpos_out)+fli_header.speed);
}
/* update the old image and color-map to the new ones to compare later */

View File

@ -130,7 +130,7 @@ static bool load_GIF(FileOp *fop)
pal = &gif->palette;
/* 1/100th seconds to milliseconds */
sprite_set_frlen(sprite, gif->frames[i].duration*10, i);
sprite_set_frlen(sprite, i, gif->frames[i].duration*10);
/* make the palette */
for (c=0; c<pal->colors_count; c++) {

View File

@ -307,12 +307,22 @@ static bool combobox_msg_proc(JWidget widget, JMessage msg)
break;
case JM_REQSIZE: {
JLink link;
int w, h;
msg->reqsize.w = 0;
msg->reqsize.h = 0;
jwidget_request_size(combobox->entry, &w, &h);
/* get the text-length of every item and put in 'w' the maximum value */
JI_LIST_FOR_EACH(combobox->items, link) {
int item_w = 2+text_length(widget->text_font,
((ComboItem *)link->data)->text)+2;
w = MAX(w, item_w);
}
msg->reqsize.w += w;
msg->reqsize.h += h;

View File

@ -228,22 +228,18 @@ void jdraw_widget_text(JWidget widget, int fg, int bg, bool fill_bg)
void jdraw_inverted_sprite(BITMAP *bmp, BITMAP *sprite, int x, int y)
{
register int c, mask = bitmap_mask_color(sprite);
int u, v;
for (v=0; v<sprite->h; ++v) {
for (u=0; u<sprite->w; ++u) {
c = getpixel(sprite, u, v);
if (c != mask)
putpixel(bmp, x+u, y+v,
makecol(255-getr(c),
255-getg(c),
255-getb(c)));
}
if (bitmap_color_depth(bmp) == 8) {
draw_character_ex(bmp, sprite, x, y, makecol(255, 255, 255), -1);
}
else {
drawing_mode(DRAW_MODE_TRANS, NULL, 0, 0);
set_invert_blender(0, 0, 0, 255);
draw_lit_sprite(bmp, sprite, x, y, 255);
drawing_mode(DRAW_MODE_SOLID, NULL, 0, 0);
}
}
void ji_blit_region(JRegion region, int dx, int dy)
void ji_move_region(JRegion region, int dx, int dy)
{
int c, nrects = JI_REGION_NUM_RECTS(region);
JRect rc;
@ -263,6 +259,7 @@ void ji_blit_region(JRegion region, int dx, int dy)
}
/* blit saving areas and copy them ************************************/
else if (nrects > 1) {
/* TODO optimize this routine, it's really slow */
JList images = jlist_new();
BITMAP *bmp;
JLink link;

View File

@ -68,7 +68,7 @@ void jdraw_widget_text(JWidget widget, int fg, int bg, bool fill_bg);
void jdraw_inverted_sprite(struct BITMAP *bmp, struct BITMAP *sprite, int x, int y);
void ji_blit_region(JRegion region, int dx, int dy);
void ji_move_region(JRegion region, int dx, int dy);
JI_END_DECLS

View File

@ -1254,46 +1254,28 @@ void jwidget_invalidate_region(JWidget widget, const JRegion region)
}
}
void jwidget_scroll(JWidget widget, int dx, int dy, const JRect rect,
JRegion update_region)
void jwidget_scroll(JWidget widget, JRegion region, int dx, int dy)
{
JRegion reg1, reg2;
if (dx != 0 || dy != 0) {
JRegion reg2 = jregion_new(NULL, 0);
assert_valid_widget(widget);
reg1 = jwidget_get_drawable_region(widget,
JI_GDR_CUTTOPWINDOWS |
JI_GDR_USECHILDAREA);
reg2 = jregion_new(rect, 0);
jregion_intersect(reg1, reg1, reg2);
jregion_copy(reg2, region);
jregion_translate(reg2, dx, dy);
jregion_intersect(reg2, reg2, region);
jregion_copy(reg2, reg1);
jregion_translate(reg1, -dx, -dy);
jregion_intersect(reg2, reg2, reg1);
jregion_translate(reg2, -dx, -dy);
ji_move_region(reg2, dx, dy);
jregion_translate(reg2, dx, dy);
jmouse_hide();
ji_blit_region(reg2, dx, dy);
jmouse_show();
if (!update_region) {
jregion_union(widget->update_region, widget->update_region, reg1);
jregion_union(widget->update_region, widget->update_region, region);
jregion_subtract(widget->update_region, widget->update_region, reg2);
}
else {
jregion_copy(update_region, reg1);
jregion_subtract(update_region, update_region, reg2);
jregion_union(widget->update_region,
widget->update_region, update_region);
}
/* TODO */
/* refresh the update_region */
/* jwidget_flush_redraw(widget); */
/* jmanager_dispatch_messages(); */
/* refresh the update_region */
jwidget_flush_redraw(widget);
jmanager_dispatch_messages(ji_get_default_manager());
jregion_free(reg1);
jregion_free(reg2);
jregion_free(reg2);
}
}
/**********************************************************************/

View File

@ -211,8 +211,7 @@ void jwidget_redraw_region(JWidget widget, const JRegion region);
void jwidget_invalidate(JWidget widget);
void jwidget_invalidate_rect(JWidget widget, const JRect rect);
void jwidget_invalidate_region(JWidget widget, const JRegion region);
void jwidget_scroll(JWidget widget, int dx, int dy, const JRect rect,
JRegion update_region);
void jwidget_scroll(JWidget widget, JRegion region, int dx, int dy);
/* signal handle */

View File

@ -703,7 +703,7 @@ static void move_window(JWidget widget, JRect rect, bool use_blit)
set_clip(ji_screen,
man_pos->x1, man_pos->y1, man_pos->x2-1, man_pos->y2-1);
ji_blit_region(moveable_region,
ji_move_region(moveable_region,
widget->rc->x1 - old_pos->x1,
widget->rc->y1 - old_pos->y1);
set_clip(ji_screen, 0, 0, JI_SCREEN_W-1, JI_SCREEN_H-1);

View File

@ -44,7 +44,7 @@ static BITMAP *gfx_bmps[GFX_BITMAP_COUNT];
static void convert_data_to_bitmap(DATA *data, BITMAP **bmp)
{
int guiscale = GUISCALE;
int scale = guiscale();
const char *p;
int x, y;
int black = makecol(0, 0, 0);
@ -52,14 +52,14 @@ static void convert_data_to_bitmap(DATA *data, BITMAP **bmp)
int white = makecol(255, 255, 255);
int mask;
*bmp = create_bitmap(data->w * guiscale,
data->h * guiscale);
*bmp = create_bitmap(data->w * scale,
data->h * scale);
mask = bitmap_mask_color(*bmp);
p = data->line;
for (y=0; y<(*bmp)->h; y+=guiscale) {
for (x=0; x<(*bmp)->w; x+=guiscale) {
rectfill(*bmp, x, y, x+guiscale-1, y+guiscale-1,
for (y=0; y<(*bmp)->h; y+=scale) {
for (x=0; x<(*bmp)->w; x+=scale) {
rectfill(*bmp, x, y, x+scale-1, y+scale-1,
(*p == '#') ? black:
(*p == '%') ? gray:
(*p == '.') ? white: mask);
@ -549,10 +549,6 @@ void draw_color(BITMAP *bmp, int x1, int y1, int x2, int y2,
int w = x2 - x1 + 1;
int h = y2 - y1 + 1;
BITMAP *graph;
int grid;
grid = MIN(w, h) / 2;
grid += MIN(w, h) - grid*2;
if (type == COLOR_TYPE_INDEX) {
data = color_get_index(imgtype, color);

View File

@ -186,13 +186,13 @@ static DATA gfx_data[GFX_BITMAP_COUNT] =
" ### " },
/* GFX_TOOL_JUMBLE */
{ 8, 8,
" "
" ## "
" # # "
"## # ###"
"### # ##"
" # # "
" ## "
" # # "
" # # "
"# # "
" # "
"# # #"
" # # "
" # "
" " },
/* GFX_TOOL_CONFIGURATION */
{ 8, 8,

View File

@ -310,6 +310,11 @@ void exit_module_gui(void)
remove_timer();
}
int guiscale(void)
{
return (JI_SCREEN_W > 512 ? 2: 1);
}
static Monitor *monitor_new(void (*proc)(void *),
void (*free)(void *), void *data)
{
@ -486,7 +491,7 @@ void reload_default_font(void)
if ((user_font) && (*user_font))
dirs_add_path(dirs, user_font);
usprintf(buf, "fonts/ase%d.pcx", GUISCALE);
usprintf(buf, "fonts/ase%d.pcx", guiscale());
dirs_cat_dirs(dirs, filename_in_datadir(buf));
/* try to load the font */
@ -494,7 +499,7 @@ void reload_default_font(void)
theme->default_font = ji_font_load(dir->path);
if (theme->default_font) {
if (ji_font_is_scalable(theme->default_font))
ji_font_set_size(theme->default_font, 8*GUISCALE);
ji_font_set_size(theme->default_font, 8*guiscale());
break;
}
}

View File

@ -24,8 +24,6 @@
#define HOOK(widget, signal, signal_handler, data) \
hook_signal((widget), (signal), (signal_handler), (void *)(data))
#define GUISCALE (JI_SCREEN_W > 512 ? 2: 1)
struct Sprite;
struct Monitor;
@ -34,6 +32,8 @@ typedef struct Monitor Monitor;
int init_module_gui(void);
void exit_module_gui(void);
int guiscale(void);
int get_screen_scaling(void);
void set_screen_scaling(int scaling);

View File

@ -858,8 +858,9 @@ void control_tool(JWidget widget, Tool *tool,
const char *_end = _("End");
const char *_size = _("Size");
bool click2 = get_config_bool("Options", "DrawClick2", FALSE);
Image *cel_image;
Cel *cel;
Cel *cel = NULL;
Image *cel_image = NULL;
bool cel_created = FALSE;
ToolData tool_data;
/* First of all we have to dispatch the enqueue messages. Why is it
@ -872,34 +873,8 @@ void control_tool(JWidget widget, Tool *tool,
jmanager_dispatch_messages(jwidget_get_manager(widget));
jwidget_flush_redraw(jwidget_get_manager(widget));
/* get cel and image where we can draw */
cel_image = NULL;
if (sprite != NULL &&
sprite->layer != NULL &&
layer_is_image(sprite->layer)) {
cel = layer_get_cel(sprite->layer,
sprite->frame);
if (cel != NULL) {
if ((cel->image >= 0) &&
(cel->image < sprite->stock->nimage)) {
cel_image = sprite->stock->image[cel->image];
}
old_cel_x = cel->x;
old_cel_y = cel->y;
}
}
/* we have a image layer to paint in? */
if (!cel_image) {
jalert(_(PACKAGE
"<<The current layer doesn't have a surface to draw."
"||&Close"));
return;
}
/* error, the active layer is not visible */
else if (!layer_is_readable(sprite->layer)) {
if (!layer_is_readable(sprite->layer)) {
jalert(_(PACKAGE
"<<The current layer is hidden,"
"<<make it visible and try again"
@ -915,6 +890,54 @@ void control_tool(JWidget widget, Tool *tool,
return;
}
/* get cel and image where we can draw */
cel_image = NULL;
if (sprite != NULL &&
sprite->layer != NULL &&
layer_is_image(sprite->layer)) {
cel = layer_get_cel(sprite->layer,
sprite->frame);
if (cel != NULL)
cel_image = sprite->stock->image[cel->image];
}
if (cel == NULL) {
/* int image_index; */
/* create the image */
cel_image = image_new(sprite->imgtype, sprite->w, sprite->h);
image_clear(cel_image, 0);
/* add it to the stock */
/* image_index = stock_add_image(sprite->stock, cel_image); */
/* create the cel */
cel = cel_new(sprite->frame, 0);
layer_add_cel(sprite->layer, cel);
cel_created = TRUE;
}
/* /\* isn't a cel in the current frame/layer, we create a new one *\/ */
/* if (cel == NULL) { */
/* cel_created = TRUE; */
/* cel = cel_new(sprite->frame, -1); */
/* } */
/* /\* if we don't have an image to paint in, we create new image to paint in *\/ */
/* if (cel_image == NULL) { */
/* cel_image_created = TRUE; */
/* } */
/* /\* if the cel is linked we make a copy of it (so it can be unlinked) *\/ */
/* else if (cel_is_link(cel, sprite->layer)) { */
/* cel_image_created = TRUE; */
/* cel_image = image_new_copy(cel_image); */
/* } */
old_cel_x = cel->x;
old_cel_y = cel->y;
/* prepare the ToolData... */
tool_data.sprite = sprite;
tool_data.layer = sprite->layer;
@ -1407,21 +1430,49 @@ void control_tool(JWidget widget, Tool *tool,
cel->y == old_cel_y &&
cel_image->w == tool_data.dst_image->w &&
cel_image->h == tool_data.dst_image->h) {
/* undo the dirty region */
if (undo_is_enabled(sprite->undo)) {
Dirty *dirty = dirty_new_from_differences(cel_image,
tool_data.dst_image);
/* TODO error handling: if (dirty == NULL) */
/* was the 'cel_image' created in the start of the tool-loop? */
if (cel_created) {
/* then we can keep the 'cel_image'... */
/* we copy the 'destination' image to the 'cel_image' */
image_copy(cel_image, tool_data.dst_image, 0, 0);
dirty_save_image_data(dirty);
if (dirty != NULL)
undo_dirty(sprite->undo, dirty);
/* add the 'cel_image' in the images' stock of the sprite */
cel->image = stock_add_image(sprite->stock, cel_image);
dirty_free(dirty);
/* is the undo enabled? */
if (undo_is_enabled(sprite->undo)) {
/* we can temporary remove the cel */
layer_remove_cel(sprite->layer, cel);
/* we create the undo information (for the new cel_image
in the stock and the new cel in the layer)... */
undo_open(sprite->undo);
undo_add_image(sprite->undo, sprite->stock, cel->image);
undo_add_cel(sprite->undo, sprite->layer, cel);
undo_close(sprite->undo);
/* and finally we add the cel again in the layer */
layer_add_cel(sprite->layer, cel);
}
}
else {
/* undo the dirty region */
if (undo_is_enabled(sprite->undo)) {
Dirty *dirty = dirty_new_from_differences(cel_image,
tool_data.dst_image);
/* TODO error handling: if (dirty == NULL) */
/* copy the 'dst_image' to the cel_image */
image_copy(cel_image, tool_data.dst_image, 0, 0);
dirty_save_image_data(dirty);
if (dirty != NULL)
undo_dirty(sprite->undo, dirty);
dirty_free(dirty);
}
/* copy the 'dst_image' to the cel_image */
image_copy(cel_image, tool_data.dst_image, 0, 0);
}
}
/* if the size of both images are different, we have to replace
the entire image */
@ -1462,6 +1513,12 @@ void control_tool(JWidget widget, Tool *tool,
else {
cel->x = old_cel_x;
cel->y = old_cel_y;
if (cel_created) {
layer_remove_cel(sprite->layer, cel);
cel_free(cel);
image_free(cel_image);
}
}
/* redraw all the sprites */

View File

@ -42,7 +42,7 @@ enum {
TOOL_RECTANGLE,
TOOL_ELLIPSE,
TOOL_BLUR,
TOOL_GUMBLE,
TOOL_JUMBLE,
MAX_TOOLS
};

View File

@ -31,6 +31,7 @@
static Layer *index2layer(Layer *layer, int index, int *index_count);
static int layer2index(const Layer *layer, const Layer *find_layer, int *index_count);
static int layer_count_layers(const Layer *layer);
static Sprite *general_copy(const Sprite *src_sprite);
@ -468,7 +469,7 @@ void sprite_set_frames(Sprite *sprite, int frames)
sprite->frames = frames;
}
void sprite_set_frlen(Sprite *sprite, int msecs, int frame)
void sprite_set_frlen(Sprite *sprite, int frame, int msecs)
{
if (frame >= 0 && frame < sprite->frames)
sprite->frlens[frame] = MID(1, msecs, 65535);
@ -702,6 +703,7 @@ void sprite_generate_mask_boundaries(Sprite *sprite)
Layer *sprite_index2layer(Sprite *sprite, int index)
{
int index_count = -1;
assert(sprite != NULL);
return index2layer(sprite->set, index, &index_count);
}
@ -709,10 +711,17 @@ Layer *sprite_index2layer(Sprite *sprite, int index)
int sprite_layer2index(const Sprite *sprite, const Layer *layer)
{
int index_count = -1;
assert(sprite != NULL);
return layer2index(sprite->set, layer, &index_count);
}
int sprite_count_layers(const Sprite *sprite)
{
assert(sprite != NULL);
return layer_count_layers(sprite->set)-1;
}
/**
* Gets a pixel from the sprite in the specified position. If in the
* specified coordinates there're background this routine will return
@ -791,6 +800,20 @@ static int layer2index(const Layer *layer, const Layer *find_layer, int *index_c
}
}
static int layer_count_layers(const Layer *layer)
{
int count = 1;
if (layer_is_set(layer)) {
JLink link;
JI_LIST_FOR_EACH(layer->layers, link) {
count += layer_count_layers(link->data);
}
}
return count;
}
/**
* Makes a copy "sprite" without the layers (only with the empty layer set)
*/

View File

@ -112,7 +112,7 @@ void sprite_set_filename(Sprite *sprite, const char *filename);
void sprite_set_format_options(Sprite *sprite, struct FormatOptions *format_options);
void sprite_set_size(Sprite *sprite, int w, int h);
void sprite_set_frames(Sprite *sprite, int frames);
void sprite_set_frlen(Sprite *sprite, int msecs, int frame);
void sprite_set_frlen(Sprite *sprite, int frame, int msecs);
int sprite_get_frlen(Sprite *sprite, int frame);
void sprite_set_speed(Sprite *sprite, int msecs);
void sprite_set_path(Sprite *sprite, const struct Path *path);
@ -135,6 +135,7 @@ void sprite_generate_mask_boundaries(Sprite *sprite);
struct Layer *sprite_index2layer(Sprite *sprite, int index);
int sprite_layer2index(const Sprite *sprite, const struct Layer *layer);
int sprite_count_layers(const Sprite *sprite);
int sprite_getpixel(Sprite *sprite, int x, int y);

View File

@ -73,6 +73,7 @@ enum {
/* misc */
UNDO_TYPE_SET_MASK,
UNDO_TYPE_SET_FRAMES,
UNDO_TYPE_SET_FRLEN,
};
typedef struct UndoChunkData UndoChunkData;
@ -90,6 +91,7 @@ typedef struct UndoChunkMoveLayer UndoChunkMoveLayer;
typedef struct UndoChunkSetLayer UndoChunkSetLayer;
typedef struct UndoChunkSetMask UndoChunkSetMask;
typedef struct UndoChunkSetFrames UndoChunkSetFrames;
typedef struct UndoChunkSetFrlen UndoChunkSetFrlen;
typedef struct UndoChunk
{
@ -168,6 +170,9 @@ static void chunk_set_mask_invert(UndoStream *stream, UndoChunkSetMask *chunk, i
static void chunk_set_frames_new(UndoStream *stream, Sprite *sprite);
static void chunk_set_frames_invert(UndoStream *stream, UndoChunkSetFrames *chunk, int state);
static void chunk_set_frlen_new(UndoStream *stream, Sprite *sprite, int frame);
static void chunk_set_frlen_invert(UndoStream *stream, UndoChunkSetFrlen *chunk, int state);
#define DECL_UNDO_ACTION(name) \
{ #name, (void (*)(UndoStream *, UndoChunk *, int))chunk_##name##_invert }
@ -189,7 +194,8 @@ static UndoAction undo_actions[] = {
DECL_UNDO_ACTION(move_layer),
DECL_UNDO_ACTION(set_layer),
DECL_UNDO_ACTION(set_mask),
DECL_UNDO_ACTION(set_frames)
DECL_UNDO_ACTION(set_frames),
DECL_UNDO_ACTION(set_frlen)
};
/* UndoChunk */
@ -1297,6 +1303,54 @@ static void chunk_set_frames_invert(UndoStream *stream, UndoChunkSetFrames *chun
}
}
/***********************************************************************
"set_frlen"
DWORD sprite ID
DWORD frame
DWORD frlen
***********************************************************************/
struct UndoChunkSetFrlen
{
UndoChunk head;
ase_uint32 sprite_id;
ase_uint32 frame;
ase_uint32 frlen;
};
void undo_set_frlen(Undo *undo, Sprite *sprite, int frame)
{
chunk_set_frlen_new(undo->undo_stream, sprite, frame);
update_undo(undo);
}
static void chunk_set_frlen_new(UndoStream *stream, Sprite *sprite, int frame)
{
UndoChunkSetFrlen *chunk = (UndoChunkSetFrlen *)
undo_chunk_new(stream,
UNDO_TYPE_SET_FRLEN,
sizeof(UndoChunkSetFrlen));
assert(frame >= 0 && frame < sprite->frames);
chunk->sprite_id = sprite->gfxobj.id;
chunk->frame = frame;
chunk->frlen = sprite->frlens[frame];
}
static void chunk_set_frlen_invert(UndoStream *stream, UndoChunkSetFrlen *chunk, int state)
{
Sprite *sprite = (Sprite *)gfxobj_find(chunk->sprite_id);
if (sprite != NULL) {
chunk_set_frlen_new(stream, sprite, chunk->frame);
sprite_set_frlen(sprite, chunk->frame, chunk->frlen);
}
}
/***********************************************************************
Helper routines for UndoChunk

View File

@ -85,6 +85,7 @@ void undo_move_layer(Undo *undo, struct Layer *layer);
void undo_set_layer(Undo *undo, struct Sprite *sprite);
void undo_set_mask(Undo *undo, struct Sprite *sprite);
void undo_set_frames(Undo *undo, struct Sprite *sprite);
void undo_set_frlen(Undo *undo, struct Sprite *sprite, int frame);
#define undo_int(undo, gfxobj, value_address) \
undo_data((undo), (gfxobj), (void *)(value_address), sizeof(int))

View File

@ -217,25 +217,17 @@ static void displace_layers(Undo *undo, Layer *layer, int x, int y)
static int get_max_layer_num(Layer *layer);
/**
* Creates a new layer with one cel in the current frame of the
* sprite.
*
* @param name Name of the layer (could be NULL)
* @param x Horizontal position of the first cel
* @param y Vertical position of the first cel
* @param w
* @param h
*
* with the specified position and size (if w=h=0 the
* routine will use the sprite dimension)
* Creates a new transparent layer.
*/
Layer *NewLayer(void)
{
Sprite *sprite = current_sprite;
Layer *layer;
#if 0
Image *image;
Cel *cel;
int index;
#endif
if (sprite == NULL) {
console_printf("NewLayer: No current sprite\n");
@ -243,33 +235,33 @@ Layer *NewLayer(void)
}
/* new image */
#if 0
image = image_new(sprite->imgtype, sprite->w, sprite->h);
if (!image) {
console_printf("NewLayer: Not enough memory\n");
return NULL;
}
#endif
/* new layer */
layer = layer_new(sprite);
if (!layer) {
#if 0
image_free(image);
#endif
console_printf("NewLayer: Not enough memory\n");
return NULL;
}
#if 0
/* clear with mask color */
image_clear(image, 0);
#endif
/* configure layer name and blend mode */
/* TODO */
/* { */
/* char *name; */
/* name = GetUniqueLayerName(); */
/* layer_set_name(layer, name); */
/* jfree(name); */
/* } */
layer_set_blend_mode(layer, BLEND_MODE_NORMAL);
#if 0
/* add image in the layer stock */
index = stock_add_image(sprite->stock, image);
@ -278,7 +270,8 @@ Layer *NewLayer(void)
/* add cel */
layer_add_cel(layer, cel);
#endif
/* undo stuff */
if (undo_is_enabled(sprite->undo)) {
undo_set_label(sprite->undo, "New Layer");
@ -670,6 +663,7 @@ void BackgroundFromLayer(void)
/* each frame of the layer to be converted as `Background' must be
cleared using the selected background color in the color-bar */
bgcolor = app_get_bg_color(sprite);
bgcolor = fixup_color_for_background(sprite->imgtype, bgcolor);
if (undo_is_enabled(sprite->undo)) {
undo_set_label(sprite->undo, "Background from Layer");
@ -805,6 +799,14 @@ void LayerFromBackground(void)
layer_set_name(sprite->layer, "Layer 0");
}
void MoveLayerAfter(Layer *layer, Layer *after_this)
{
if (undo_is_enabled(layer->sprite->undo))
undo_move_layer(layer->sprite->undo, layer);
layer_move_layer(layer->parent_layer, layer, after_this);
}
/* internal routine */
static int get_max_layer_num(Layer *layer)
{
@ -824,6 +826,119 @@ static int get_max_layer_num(Layer *layer)
return max;
}
/* ======================================= */
/* Frame */
/* ======================================= */
static void MoveFrameBeforeLayer2(Undo *undo, Layer *layer, int frame, int before_frame);
void SetFrameLength(Sprite *sprite, int frame, int msecs)
{
if (undo_is_enabled(sprite->undo))
undo_set_frlen(sprite->undo, sprite, frame);
sprite_set_frlen(sprite, frame, msecs);
}
void MoveFrameBefore(int frame, int before_frame)
{
Sprite *sprite = current_sprite;
int c, frlen_aux;
if (sprite &&
frame != before_frame &&
frame >= 0 &&
frame < sprite->frames &&
before_frame >= 0 &&
before_frame < sprite->frames) {
if (undo_is_enabled(sprite->undo))
undo_open(sprite->undo);
/* Change the frame-lengths... */
frlen_aux = sprite->frlens[frame];
/* moving the frame to the future */
if (frame < before_frame) {
frlen_aux = sprite->frlens[frame];
for (c=frame; c<before_frame-1; c++)
SetFrameLength(sprite, c, sprite->frlens[c+1]);
SetFrameLength(sprite, before_frame-1, frlen_aux);
}
/* moving the frame to the past */
else if (before_frame < frame) {
frlen_aux = sprite->frlens[frame];
for (c=frame; c>before_frame; c--)
SetFrameLength(sprite, c, sprite->frlens[c-1]);
SetFrameLength(sprite, before_frame, frlen_aux);
}
/* Change the cels of position... */
MoveFrameBeforeLayer2(sprite->undo, sprite->set, frame, before_frame);
if (undo_is_enabled(sprite->undo))
undo_close(sprite->undo);
}
}
static void MoveFrameBeforeLayer2(Undo *undo, Layer *layer, int frame, int before_frame)
{
switch (layer->gfxobj.type) {
case GFXOBJ_LAYER_IMAGE: {
Cel *cel;
JLink link;
int new_frame;
JI_LIST_FOR_EACH(layer->cels, link) {
cel = link->data;
new_frame = cel->frame;
/* moving the frame to the future */
if (frame < before_frame) {
if (cel->frame == frame) {
new_frame = before_frame-1;
}
else if (cel->frame > frame &&
cel->frame < before_frame) {
new_frame--;
}
}
/* moving the frame to the past */
else if (before_frame < frame) {
if (cel->frame == frame) {
new_frame = before_frame;
}
else if (cel->frame >= before_frame &&
cel->frame < frame) {
new_frame++;
}
}
if (cel->frame != new_frame) {
if (undo_is_enabled(undo))
undo_int(undo, (GfxObj *)cel, &cel->frame);
cel->frame = new_frame;
}
}
break;
}
case GFXOBJ_LAYER_SET: {
JLink link;
JI_LIST_FOR_EACH(layer->layers, link)
MoveFrameBeforeLayer2(undo, link->data, frame, before_frame);
break;
}
}
}
/* ======================================= */
/* Cel */
/* ======================================= */
@ -848,10 +963,8 @@ void RemoveCel(Layer *layer, Cel *cel)
}
}
if (undo_is_enabled(sprite->undo)) {
undo_set_label(sprite->undo, "Remove Cel");
if (undo_is_enabled(sprite->undo))
undo_open(sprite->undo);
}
if (!used) {
/* if the image is only used by this cel, we can remove the

View File

@ -52,6 +52,15 @@ void CropLayer(void);
void BackgroundFromLayer(void);
void LayerFromBackground(void);
void MoveLayerAfter(struct Layer *layer, struct Layer *after_this);
/* ======================================= */
/* Frame */
/* ======================================= */
void SetFrameLength(struct Sprite *sprite, int frame, int msecs);
void MoveFrameBefore(int frame, int before_frame);
/* ======================================= */
/* Cel */
/* ======================================= */

View File

@ -19,6 +19,7 @@
#include "config.h"
#include <allegro.h>
#include <assert.h>
#include <string.h>
#include "jinete/jlist.h"
@ -37,6 +38,7 @@
#include "modules/tools2.h"
#include "raster/raster.h"
#include "util/misc.h"
#include "script/functions.h"
#include "widgets/editor.h"
#include "widgets/statebar.h"
@ -123,17 +125,30 @@ void ClearMask(void)
Image *image;
div_t d;
if (sprite) {
if (sprite != NULL) {
image = GetImage2(sprite, &x, &y, NULL);
if (image) {
int bgcolor = app_get_color_to_clear_layer(sprite->layer);
/* if the mask is empty then we have to clear the entire image
in the cel */
if (mask_is_empty(sprite->mask)) {
if (undo_is_enabled(sprite->undo))
undo_image(sprite->undo, image, 0, 0, image->w, image->h);
/* if the layer is the background then we clear the image */
if (layer_is_background(sprite->layer)) {
if (undo_is_enabled(sprite->undo))
undo_image(sprite->undo, image, 0, 0, image->w, image->h);
/* clear all */
image_clear(image, bgcolor);
/* clear all */
image_clear(image, bgcolor);
}
/* if the layer is transparent we can remove the cel (and it's
associated image) */
else {
assert(layer_get_cel(sprite->layer, sprite->frame) != NULL);
RemoveCel(sprite->layer, layer_get_cel(sprite->layer,
sprite->frame));
}
}
else {
int x1 = MAX(0, sprite->mask->x);

View File

@ -30,16 +30,17 @@
/************************************************************************/
/* Render engine */
/* static Layer *onionskin_layer = NULL; */
static int global_opacity = 255;
static Layer *selected_layer = NULL;
static Image *rastering_image = NULL;
static void render_layer(Layer *layer, Image *image,
static void render_layer(Sprite *sprite, Layer *layer, Image *image,
int source_x, int source_y,
int frame, int zoom,
void (*zoomed_func)(Image *, Image *, int, int, int, int, int));
void (*zoomed_func)(Image *, Image *, int, int, int, int, int),
bool render_background,
bool render_transparent);
static void merge_zoomed_image1(Image *dst, Image *src, int x, int y, int opacity, int blend_mode, int zoom);
static void merge_zoomed_image2(Image *dst, Image *src, int x, int y, int opacity, int blend_mode, int zoom);
@ -65,10 +66,7 @@ Image *render_sprite(Sprite *sprite,
{
void (*zoomed_func)(Image *, Image *, int, int, int, int, int);
Layer *background = sprite_get_background_layer(sprite);
/* TODO restore this, it's temporary to test that the background
layer never has a color with Alpha < 255 */
/* bool need_grid = (background != NULL ? !layer_is_readable(background): TRUE); */
bool need_grid = TRUE;
bool need_grid = (background != NULL ? !layer_is_readable(background): TRUE);
int depth;
Image *image;
@ -93,11 +91,6 @@ Image *render_sprite(Sprite *sprite,
return NULL;
}
/* if ((get_onionskin()) && (sprite->frame > 0)) */
/* onionskin_layer = sprite->layer; */
/* else */
/* onionskin_layer = NULL; */
/* create a temporary bitmap to draw all to it */
image = image_new(sprite->imgtype, width, height);
if (!image)
@ -116,10 +109,11 @@ Image *render_sprite(Sprite *sprite,
c1 = _graya(128, 255);
c2 = _graya(192, 255);
break;
case IMAGE_INDEXED:
c1 = rgb_map->data[16][16][16];
c2 = rgb_map->data[24][24][24];
break;
/* TODO remove this */
/* case IMAGE_INDEXED: */
/* c1 = rgb_map->data[16][16][16]; */
/* c2 = rgb_map->data[24][24][24]; */
/* break; */
default:
c1 = c2 = 0;
break;
@ -160,55 +154,68 @@ Image *render_sprite(Sprite *sprite,
/* onion-skin feature: draw the previous frame */
if (get_onionskin() && (frame > 0)) {
/* draw background layer of the current frame with opacity=255 */
color_map = NULL;
global_opacity = 255;
render_layer(sprite, sprite->set, image, source_x, source_y,
frame, zoom, zoomed_func, TRUE, FALSE);
/* draw transparent layers of the previous frame with opacity=128 */
color_map = orig_trans_map;
global_opacity = 128;
render_layer(sprite->set, image, source_x, source_y,
frame-1, zoom, zoomed_func);
render_layer(sprite, sprite->set, image, source_x, source_y,
frame-1, zoom, zoomed_func, FALSE, TRUE);
/* draw transparent layers of the current frame with opacity=255 */
color_map = NULL;
global_opacity = 255;
}
/* draw the frame */
render_layer(sprite->set, image, source_x, source_y,
frame, zoom, zoomed_func);
render_layer(sprite, sprite->set, image, source_x, source_y,
frame, zoom, zoomed_func, FALSE, TRUE);
}
/* just draw the current frame */
else {
render_layer(sprite, sprite->set, image, source_x, source_y,
frame, zoom, zoomed_func, TRUE, TRUE);
}
return image;
}
static void render_layer(Layer *layer, Image *image,
static void render_layer(Sprite *sprite, Layer *layer, Image *image,
int source_x, int source_y,
int frame, int zoom,
void (*zoomed_func)(Image *, Image *, int, int, int, int, int))
void (*zoomed_func)(Image *, Image *, int, int, int, int, int),
bool render_background,
bool render_transparent)
{
/* we can't read from this layer */
if (!layer_is_readable(layer))
return;
/* /\* onion-skin feature *\/ */
/* if (onionskin_layer == layer) { */
/* onionskin_layer = NULL; */
/* color_map = orig_trans_map; */
/* global_opacity = 128; */
/* /\* render the previous frame *\/ */
/* render_layer(layer, image, source_x, source_y, frame-1, zoom, zoomed_func); */
/* color_map = NULL; */
/* global_opacity = 255; */
/* } */
switch (layer->gfxobj.type) {
case GFXOBJ_LAYER_IMAGE: {
Cel *cel = layer_get_cel(layer, frame);
Image *src_image;
Cel *cel;
if (cel) {
if ((cel->image >= 0) &&
(cel->image < layer->sprite->stock->nimage))
if ((!render_background && layer_is_background(layer)) ||
(!render_transparent && !layer_is_background(layer)))
break;
cel = layer_get_cel(layer, frame);
if (cel != NULL) {
/* is the 'rastering_image' setted to be used with this layer? */
if ((frame == sprite->frame) &&
(selected_layer == layer) &&
(rastering_image != NULL)) {
src_image = rastering_image;
}
/* if not, we use the original cel-image from the images' stock */
else if ((cel->image >= 0) &&
(cel->image < layer->sprite->stock->nimage))
src_image = layer->sprite->stock->image[cel->image];
else
src_image = NULL;
@ -217,9 +224,6 @@ static void render_layer(Layer *layer, Image *image,
int output_opacity;
register int t;
if ((selected_layer == layer) && (rastering_image != NULL))
src_image = rastering_image;
output_opacity = MID(0, cel->opacity, 255);
output_opacity = INT_MULT(output_opacity, global_opacity, t);
@ -243,8 +247,11 @@ static void render_layer(Layer *layer, Image *image,
case GFXOBJ_LAYER_SET: {
JLink link;
JI_LIST_FOR_EACH(layer->layers, link)
render_layer(link->data, image, source_x, source_y,
frame, zoom, zoomed_func);
render_layer(sprite, link->data, image,
source_x, source_y,
frame, zoom, zoomed_func,
render_background,
render_transparent);
break;
}

View File

@ -18,15 +18,19 @@
#include "config.h"
#include <assert.h>
#include <allegro/color.h>
#include <allegro/draw.h>
#include <allegro/gfx.h>
#include "jinete/jlist.h"
#include "modules/gfx.h"
#include "modules/palettes.h"
#include "raster/blend.h"
#include "raster/cel.h"
#include "raster/image.h"
#include "raster/layer.h"
#include "raster/palette.h"
#include "raster/sprite.h"
#include "raster/stock.h"
@ -45,7 +49,7 @@ static JList thumbnails = NULL;
static Thumbnail *thumbnail_new(Cel *cel, BITMAP *bmp);
static void thumbnail_free(Thumbnail *thumbnail);
static void thumbnail_create_bitmap(BITMAP *bmp, Image *image);
static void thumbnail_render(BITMAP *bmp, Image *image, bool has_alpha);
void destroy_thumbnails(void)
{
@ -60,7 +64,7 @@ void destroy_thumbnails(void)
}
}
BITMAP *generate_thumbnail(Cel *cel, Sprite *sprite)
BITMAP *generate_thumbnail(Layer *layer, Cel *cel, Sprite *sprite)
{
Thumbnail *thumbnail;
BITMAP *bmp;
@ -80,7 +84,9 @@ BITMAP *generate_thumbnail(Cel *cel, Sprite *sprite)
if (!bmp)
return NULL;
thumbnail_create_bitmap(bmp, stock_get_image(sprite->stock, cel->image));
thumbnail_render(bmp,
stock_get_image(sprite->stock, cel->image),
!layer_is_background(layer));
thumbnail = thumbnail_new(cel, bmp);
if (!thumbnail) {
@ -112,32 +118,79 @@ static void thumbnail_free(Thumbnail *thumbnail)
jfree(thumbnail);
}
static void thumbnail_create_bitmap(BITMAP *bmp, Image *image)
static void thumbnail_render(BITMAP *bmp, Image *image, bool has_alpha)
{
if (!image) {
clear_to_color(bmp, makecol(128, 128, 128));
line(bmp, 0, 0, bmp->w-1, bmp->h-1, makecol(0, 0, 0));
line(bmp, 0, bmp->h-1, bmp->w-1, 0, makecol(0, 0, 0));
register int c, x, y;
int w, h, x1, y1;
double sx, sy, scale;
assert(image != NULL);
sx = (double)image->w / (double)bmp->w;
sy = (double)image->h / (double)bmp->h;
scale = MAX(sx, sy);
w = image->w / scale;
h = image->h / scale;
w = MIN(bmp->w, w);
h = MIN(bmp->h, h);
x1 = bmp->w/2 - w/2;
y1 = bmp->h/2 - h/2;
x1 = MAX(0, x1);
y1 = MAX(0, y1);
/* with alpha blending */
if (has_alpha) {
register int c2;
rectgrid(bmp, 0, 0, bmp->w-1, bmp->h-1,
bmp->w/4, bmp->h/4);
switch (image->imgtype) {
case IMAGE_RGB:
for (y=0; y<h; y++)
for (x=0; x<w; x++) {
c = image_getpixel(image, x*scale, y*scale);
c2 = getpixel(bmp, x1+x, y1+y);
c = _rgba_blend_normal(_rgba(getr(c2), getg(c2), getb(c2), 255), c, 255);
putpixel(bmp, x1+x, y1+y, makecol(_rgba_getr(c),
_rgba_getg(c),
_rgba_getb(c)));
}
break;
case IMAGE_GRAYSCALE:
for (y=0; y<h; y++)
for (x=0; x<w; x++) {
c = image_getpixel(image, x*scale, y*scale);
c2 = getpixel(bmp, x1+x, y1+y);
c = _graya_blend_normal(_graya(getr(c2), 255), c, 255);
putpixel(bmp, x1+x, y1+y, makecol(_graya_getv(c),
_graya_getv(c),
_graya_getv(c)));
}
break;
case IMAGE_INDEXED: {
Palette *pal = get_current_palette();
for (y=0; y<h; y++)
for (x=0; x<w; x++) {
c = image_getpixel(image, x*scale, y*scale);
if (c != 0) {
c = pal->color[MID(0, c, MAX_PALETTE_COLORS-1)];
putpixel(bmp, x1+x, y1+y, makecol(_rgba_getr(c),
_rgba_getg(c),
_rgba_getb(c)));
}
}
break;
}
}
}
/* without alpha blending */
else {
register int c, x, y;
int w, h, x1, y1;
double sx, sy, scale;
sx = (double)image->w / (double)bmp->w;
sy = (double)image->h / (double)bmp->h;
scale = MAX(sx, sy);
w = image->w / scale;
h = image->h / scale;
w = MIN(bmp->w, w);
h = MIN(bmp->h, h);
x1 = bmp->w/2 - w/2;
y1 = bmp->h/2 - h/2;
x1 = MAX(0, x1);
y1 = MAX(0, y1);
clear_to_color(bmp, makecol(128, 128, 128));
switch (image->imgtype) {

View File

@ -23,7 +23,7 @@ struct Cel;
struct Sprite;
void destroy_thumbnails(void);
struct BITMAP *generate_thumbnail(struct Cel *cel, struct Sprite *sprite);
struct BITMAP *generate_thumbnail(struct Layer *layer, struct Cel *cel, struct Sprite *sprite);
#endif /* UTIL_THMBNAIL_H */

View File

@ -42,7 +42,9 @@
#include "widgets/paledit.h"
#include "widgets/statebar.h"
#define COLORBAR_MAX_COLORS 256
#define COLORBAR_MAX_COLORS 256
#define FGBGSIZE (16*guiscale())
typedef enum {
HOTCOLOR_NONE = -3,
@ -181,7 +183,7 @@ color_t colorbar_get_color_by_position(JWidget widget, int x, int y)
++x1, ++y1, --x2, --y2;
h = (y2-y1+1-(4+16+16+4));
h = (y2-y1+1-(4+FGBGSIZE*2+4));
for (c=beg; c<=end; c++) {
v1 = y1 + h*(c-beg )/(end-beg+1);
@ -192,14 +194,14 @@ color_t colorbar_get_color_by_position(JWidget widget, int x, int y)
}
/* in foreground color */
v1 = y2-4-16-16;
v2 = y2-4-16;
v1 = y2-4-FGBGSIZE*2;
v2 = y2-4-FGBGSIZE;
if ((y >= v1) && (y <= v2)) {
return colorbar->fgcolor;
}
/* in background color */
v1 = y2-4-16+1;
v1 = y2-4-FGBGSIZE+1;
v2 = y2-4;
if ((y >= v1) && (y <= v2)) {
return colorbar->bgcolor;
@ -284,7 +286,7 @@ static bool colorbar_msg_proc(JWidget widget, JMessage msg)
rectfill(doublebuffer, x1, y1, x2, y2, ji_color_face());
++x1, ++y1, --x2, --y2;
h = (y2-y1+1-(4+16+16+4));
h = (y2-y1+1-(4+FGBGSIZE*2+4));
/* draw gradient */
for (c=beg; c<=end; c++) {
@ -299,15 +301,15 @@ static bool colorbar_msg_proc(JWidget widget, JMessage msg)
}
/* draw foreground color */
v1 = y2-4-16-16;
v2 = y2-4-16;
v1 = y2-4-FGBGSIZE*2;
v2 = y2-4-FGBGSIZE;
draw_color_button(doublebuffer, x1, v1, x2, v2, 1, 1, 0, 0,
imgtype, colorbar->fgcolor,
(colorbar->hot == HOTCOLOR_FGCOLOR ||
colorbar->hot_editing == HOTCOLOR_FGCOLOR));
/* draw background color */
v1 = y2-4-16+1;
v1 = y2-4-FGBGSIZE+1;
v2 = y2-4;
draw_color_button(doublebuffer, x1, v1, x2, v2, 0, 0, 1, 1,
imgtype, colorbar->bgcolor,
@ -345,7 +347,7 @@ static bool colorbar_msg_proc(JWidget widget, JMessage msg)
++x1, ++y1, --x2, --y2;
h = (y2-y1+1-(4+16+16+4));
h = (y2-y1+1-(4+FGBGSIZE*2+4));
for (c=beg; c<=end; c++) {
v1 = y1 + h*(c-beg )/(end-beg+1);
@ -362,8 +364,8 @@ static bool colorbar_msg_proc(JWidget widget, JMessage msg)
}
/* in foreground color */
v1 = y2-4-16-16;
v2 = y2-4-16;
v1 = y2-4-FGBGSIZE*2;
v2 = y2-4-FGBGSIZE;
if ((msg->mouse.y >= v1) && (msg->mouse.y <= v2)) {
colorbar->hot = HOTCOLOR_FGCOLOR;
hot_v1 = v1;
@ -371,7 +373,7 @@ static bool colorbar_msg_proc(JWidget widget, JMessage msg)
}
/* in background color */
v1 = y2-4-16+1;
v1 = y2-4-FGBGSIZE+1;
v2 = y2-4;
if ((msg->mouse.y >= v1) && (msg->mouse.y <= v2)) {
colorbar->hot = HOTCOLOR_BGCOLOR;

View File

@ -277,8 +277,8 @@ static bool colorselector_msg_proc(JWidget widget, JMessage msg)
int idxlen = ji_font_text_len(jwidget_get_font(idx), "Index=888");
jwidget_set_min_size(idx, idxlen, 0);
paledit_set_boxsize(pal, 4*GUISCALE);
jwidget_set_min_size(grid2, 200*GUISCALE, 0);
paledit_set_boxsize(pal, 4*guiscale());
jwidget_set_min_size(grid2, 200*guiscale(), 0);
}
break;

View File

@ -1,5 +0,0 @@
- this should be called by some routine in the program exit (by cursor.c):
if (cursor_bound.seg) {
r_free (cursor_bound.seg);
cursor_bound.seg = NULL;
}

View File

@ -75,6 +75,7 @@ static bool editor_msg_proc(JWidget widget, JMessage msg);
static void editor_request_size(JWidget widget, int *w, int *h);
static void editor_draw_sprite_boundary(JWidget widget);
static void editor_setcursor(JWidget widget, int x, int y);
static void editor_update_candraw(JWidget widget);
JWidget editor_view_new(void)
{
@ -184,75 +185,10 @@ void editor_set_scroll(JWidget widget, int x, int y, int use_refresh_region)
jview_get_scroll(view, &new_scroll_x, &new_scroll_y);
/* move screen with blits */
if (old_scroll_x != new_scroll_x || old_scroll_y != new_scroll_y) {
int offset_x = old_scroll_x - new_scroll_x;
int offset_y = old_scroll_y - new_scroll_y;
JRegion reg2 = jregion_new(NULL, 0);
int c, nrects;
JRect rc;
jregion_copy(reg2, region);
jregion_translate(reg2, offset_x, offset_y);
jregion_intersect(reg2, reg2, region);
nrects = JI_REGION_NUM_RECTS(reg2);
if (!thick)
jmouse_hide();
/* blit directly screen to screen *************************************/
if (is_linear_bitmap(ji_screen) && nrects == 1) {
rc = JI_REGION_RECTS(reg2);
blit(ji_screen, ji_screen,
rc->x1-offset_x, rc->y1-offset_y,
rc->x1, rc->y1, jrect_w(rc), jrect_h(rc));
}
/* blit saving areas and copy them ************************************/
else if (nrects > 1) {
JList images = jlist_new();
BITMAP *bmp;
JLink link;
for (c=0, rc=JI_REGION_RECTS(reg2);
c<nrects;
c++, rc++) {
bmp = create_bitmap(jrect_w(rc), jrect_h(rc));
blit(ji_screen, bmp,
rc->x1-offset_x, rc->y1-offset_y, 0, 0, bmp->w, bmp->h);
jlist_append(images, bmp);
}
for (c=0, rc=JI_REGION_RECTS(reg2), link=jlist_first(images);
c<nrects;
c++, rc++, link=link->next) {
bmp = link->data;
blit(bmp, ji_screen, 0, 0, rc->x1, rc->y1, bmp->w, bmp->h);
destroy_bitmap(bmp);
}
jlist_free(images);
}
/**********************************************************************/
if (!thick)
jmouse_show();
/* if (editor->refresh_region) */
/* jregion_free(editor->refresh_region); */
/* editor->refresh_region = jregion_new(NULL, 0); */
/* jregion_copy(editor->refresh_region, region); */
/* jregion_subtract(editor->refresh_region, editor->refresh_region, reg2); */
/* TODO jwidget_validate */
jregion_union(widget->update_region, widget->update_region, region);
jregion_subtract(widget->update_region, widget->update_region, reg2);
/* refresh the update_region */
jwidget_flush_redraw(widget);
jmanager_dispatch_messages(ji_get_default_manager());
jregion_free(reg2);
}
jwidget_scroll(widget, region,
old_scroll_x - new_scroll_x,
old_scroll_y - new_scroll_y);
jregion_free(region);
/* editor->widget->flags &= ~JI_DIRTY; */
}
@ -617,8 +553,7 @@ void editor_draw_grid_safe(JWidget widget)
JRect rc;
for (c=0, rc=JI_REGION_RECTS(region);
c<nrects;
c++, rc++) {
c<nrects; c++, rc++) {
set_clip(ji_screen, rc->x1, rc->y1, rc->x2-1, rc->y2-1);
editor_draw_grid(widget);
}
@ -1085,19 +1020,10 @@ static bool editor_msg_proc(JWidget widget, JMessage msg)
/* when the mouse enter to the editor, we can calculate the
'cursor_candraw' field to avoid a heavy if-condition in the
'editor_setcursor' routine */
editor->cursor_candraw =
(editor->sprite != NULL &&
!sprite_is_locked(editor->sprite) &&
editor->sprite->layer != NULL &&
layer_is_image(editor->sprite->layer) &&
layer_is_readable(editor->sprite->layer) &&
layer_is_writable(editor->sprite->layer) &&
layer_get_cel(editor->sprite->layer,
editor->sprite->frame) != NULL);
editor_update_candraw(widget);
if (msg->any.shifts & KB_ALT_FLAG) editor->alt_pressed = TRUE;
if (msg->any.shifts & KB_CTRL_FLAG) editor->ctrl_pressed = TRUE;
/* TODO another way to get the KEY_SPACE state? */
if (key[KEY_SPACE]) editor->space_pressed = TRUE;
break;
@ -1117,8 +1043,7 @@ static bool editor_msg_proc(JWidget widget, JMessage msg)
break;
/* move the scroll */
if ((msg->mouse.middle && has_only_shifts(msg, 0)) ||
(msg->mouse.left && editor->space_pressed)) {
if (msg->mouse.middle || editor->space_pressed) {
editor->state = EDIT_MOVING_SCROLL;
editor_setcursor(widget, msg->mouse.x, msg->mouse.y);
@ -1449,6 +1374,8 @@ static void editor_setcursor(JWidget widget, int x, int y)
case EDIT_STANDBY:
if (editor->sprite) {
editor_update_candraw(widget); /* TODO remove this */
/* eyedropper */
if (editor->alt_pressed) {
hide_drawing_cursor(widget);
@ -1483,3 +1410,19 @@ static void editor_setcursor(JWidget widget, int x, int y)
}
}
/* TODO this routine should be called in a change of context */
static void editor_update_candraw(JWidget widget)
{
Editor *editor = editor_data(widget);
editor->cursor_candraw =
(editor->sprite != NULL &&
!sprite_is_locked(editor->sprite) &&
editor->sprite->layer != NULL &&
layer_is_image(editor->sprite->layer) &&
layer_is_readable(editor->sprite->layer) &&
layer_is_writable(editor->sprite->layer) /* && */
/* layer_get_cel(editor->sprite->layer, editor->sprite->frame) != NULL */
);
}