Add AniDir as a FrameTag property (it's persisted in .ase files)

This commit is contained in:
David Capello 2015-02-19 13:05:39 -03:00
parent 9f8505f490
commit adf3e6c00d
10 changed files with 73 additions and 17 deletions

View File

@ -18,11 +18,6 @@
<value id="MERGE" value="0" /> <value id="MERGE" value="0" />
<value id="RED_BLUE_TINT" value="1" /> <value id="RED_BLUE_TINT" value="1" />
</enum> </enum>
<enum id="AniDir">
<value id="FORWARD" value="0" />
<value id="REVERSE" value="1" />
<value id="PING_PONG" value="2" />
</enum>
<enum id="FreehandAlgorithm"> <enum id="FreehandAlgorithm">
<value id="REGULAR" value="0" /> <value id="REGULAR" value="0" />
<value id="PIXEL_PERFECT" value="1" /> <value id="PIXEL_PERFECT" value="1" />
@ -137,7 +132,7 @@
<option id="visible" type="bool" default="false" /> <option id="visible" type="bool" default="false" />
<option id="from" type="doc::frame_t" default="0" /> <option id="from" type="doc::frame_t" default="0" />
<option id="to" type="doc::frame_t" default="1" /> <option id="to" type="doc::frame_t" default="1" />
<option id="ani_dir" type="AniDir" default="AniDir::FORWARD" /> <option id="ani_dir" type="doc::AniDir" default="doc::AniDir::FORWARD" />
</section> </section>
</document> </document>

View File

@ -231,10 +231,17 @@ Frame Tags Chunk (0x2018)
---------------------------------------- ----------------------------------------
WORD Number of tags WORD Number of tags
BYTE[8] For future (set to zero)
+ For each tag + For each tag
WORD From frame WORD From frame
WORD To frame WORD To frame
BYTE Loop animation direction
0 - Forward
1 - Reverse
2 - Ping-pong
BYTE[8] For future (set to zero)
BYTE[3] RGB values of the tag color BYTE[3] RGB values of the tag color
BYTE Extra byte (zero)
STRING Tag name STRING Tag name

View File

@ -1277,12 +1277,23 @@ static void ase_file_write_mask_chunk(FILE* f, ASE_FrameHeader* frame_header, Ma
static void ase_file_read_frame_tags_chunk(FILE* f, FrameTags* frameTags) static void ase_file_read_frame_tags_chunk(FILE* f, FrameTags* frameTags)
{ {
size_t tags = fgetw(f); size_t tags = fgetw(f);
fgetl(f); // 8 reserved bytes
fgetl(f);
for (size_t c=0; c<tags; ++c) { for (size_t c=0; c<tags; ++c) {
frame_t from = fgetw(f); frame_t from = fgetw(f);
frame_t to = fgetw(f); frame_t to = fgetw(f);
int aniDir = fgetc(f);
fgetl(f); // 8 reserved bytes
fgetl(f);
int r = fgetc(f); int r = fgetc(f);
int g = fgetc(f); int g = fgetc(f);
int b = fgetc(f); int b = fgetc(f);
fgetc(f); // Skip
std::string name = ase_file_read_string(f); std::string name = ase_file_read_string(f);
FrameTag* tag = new FrameTag(from, to); FrameTag* tag = new FrameTag(from, to);
@ -1297,12 +1308,23 @@ static void ase_file_write_frame_tags_chunk(FILE* f, ASE_FrameHeader* frame_head
ChunkWriter chunk(f, frame_header, ASE_FILE_CHUNK_FRAME_TAGS); ChunkWriter chunk(f, frame_header, ASE_FILE_CHUNK_FRAME_TAGS);
fputw(frameTags->size(), f); fputw(frameTags->size(), f);
fputl(0, f); // 8 reserved bytes
fputl(0, f);
for (FrameTag* tag : *frameTags) { for (FrameTag* tag : *frameTags) {
fputw(tag->fromFrame(), f); fputw(tag->fromFrame(), f);
fputw(tag->toFrame(), f); fputw(tag->toFrame(), f);
fputc((int)tag->aniDir(), f);
fputl(0, f); // 8 reserved bytes
fputl(0, f);
fputc(doc::rgba_getr(tag->color()), f); fputc(doc::rgba_getr(tag->color()), f);
fputc(doc::rgba_getg(tag->color()), f); fputc(doc::rgba_getg(tag->color()), f);
fputc(doc::rgba_getb(tag->color()), f); fputc(doc::rgba_getb(tag->color()), f);
fputc(0, f);
ase_file_write_string(f, tag->name().c_str()); ase_file_write_string(f, tag->name().c_str());
} }
} }

View File

@ -37,19 +37,19 @@ doc::frame_t calculate_next_frame(
switch (docPref.loop.aniDir()) { switch (docPref.loop.aniDir()) {
case app::gen::AniDir::FORWARD: case doc::AniDir::FORWARD:
++frame; ++frame;
if (frame > last) if (frame > last)
frame = first; frame = first;
break; break;
case app::gen::AniDir::REVERSE: case doc::AniDir::REVERSE:
--frame; --frame;
if (frame < first) if (frame < first)
frame = last; frame = last;
break; break;
case app::gen::AniDir::PING_PONG: case doc::AniDir::PING_PONG:
if (pingPongForward) { if (pingPongForward) {
++frame; ++frame;
if (frame > last) { if (frame > last) {

View File

@ -61,9 +61,9 @@ ConfigureTimelinePopup::ConfigureTimelinePopup()
m_resetOnionskin->Click.connect(Bind<void>(&ConfigureTimelinePopup::onResetOnionskin, this)); m_resetOnionskin->Click.connect(Bind<void>(&ConfigureTimelinePopup::onResetOnionskin, this));
m_setLoopSection->Click.connect(Bind<void>(&ConfigureTimelinePopup::onSetLoopSection, this)); m_setLoopSection->Click.connect(Bind<void>(&ConfigureTimelinePopup::onSetLoopSection, this));
m_resetLoopSection->Click.connect(Bind<void>(&ConfigureTimelinePopup::onResetLoopSection, this)); m_resetLoopSection->Click.connect(Bind<void>(&ConfigureTimelinePopup::onResetLoopSection, this));
m_normalDir->Click.connect(Bind<void>(&ConfigureTimelinePopup::onAniDir, this, app::gen::AniDir::FORWARD)); m_normalDir->Click.connect(Bind<void>(&ConfigureTimelinePopup::onAniDir, this, doc::AniDir::FORWARD));
m_reverseDir->Click.connect(Bind<void>(&ConfigureTimelinePopup::onAniDir, this, app::gen::AniDir::REVERSE)); m_reverseDir->Click.connect(Bind<void>(&ConfigureTimelinePopup::onAniDir, this, doc::AniDir::REVERSE));
m_pingPongDir->Click.connect(Bind<void>(&ConfigureTimelinePopup::onAniDir, this, app::gen::AniDir::PING_PONG)); m_pingPongDir->Click.connect(Bind<void>(&ConfigureTimelinePopup::onAniDir, this, doc::AniDir::PING_PONG));
} }
DocumentPreferences& ConfigureTimelinePopup::docPref() DocumentPreferences& ConfigureTimelinePopup::docPref()
@ -98,13 +98,13 @@ void ConfigureTimelinePopup::updateWidgetsFromCurrentSettings()
} }
switch (docPref.loop.aniDir()) { switch (docPref.loop.aniDir()) {
case app::gen::AniDir::FORWARD: case doc::AniDir::FORWARD:
m_normalDir->setSelected(true); m_normalDir->setSelected(true);
break; break;
case app::gen::AniDir::REVERSE: case doc::AniDir::REVERSE:
m_reverseDir->setSelected(true); m_reverseDir->setSelected(true);
break; break;
case app::gen::AniDir::PING_PONG: case doc::AniDir::PING_PONG:
m_pingPongDir->setSelected(true); m_pingPongDir->setSelected(true);
break; break;
} }
@ -170,7 +170,7 @@ void ConfigureTimelinePopup::onResetLoopSection()
docPref().loop.visible(false); docPref().loop.visible(false);
} }
void ConfigureTimelinePopup::onAniDir(app::gen::AniDir aniDir) void ConfigureTimelinePopup::onAniDir(doc::AniDir aniDir)
{ {
docPref().loop.aniDir(aniDir); docPref().loop.aniDir(aniDir);
} }

View File

@ -10,6 +10,7 @@
#pragma once #pragma once
#include "app/pref/preferences.h" #include "app/pref/preferences.h"
#include "doc/anidir.h"
#include "ui/popup_window.h" #include "ui/popup_window.h"
namespace ui { namespace ui {
@ -33,7 +34,7 @@ namespace app {
void onResetOnionskin(); void onResetOnionskin();
void onSetLoopSection(); void onSetLoopSection();
void onResetLoopSection(); void onResetLoopSection();
void onAniDir(app::gen::AniDir aniDir); void onAniDir(doc::AniDir aniDir);
private: private:
void updateWidgetsFromCurrentSettings(); void updateWidgetsFromCurrentSettings();

21
src/doc/anidir.h Normal file
View File

@ -0,0 +1,21 @@
// Aseprite Document Library
// Copyright (c) 2001-2015 David Capello
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#ifndef DOC_ANIDIR_H_INCLUDED
#define DOC_ANIDIR_H_INCLUDED
#pragma once
namespace doc {
enum class AniDir {
FORWARD = 0,
REVERSE = 1,
PING_PONG = 2,
};
} // namespace doc
#endif // DOC_ANIDIR_H_INCLUDED

View File

@ -37,4 +37,9 @@ void FrameTag::setColor(color_t color)
m_color = color; m_color = color;
} }
void FrameTag::setAniDir(AniDir aniDir)
{
m_aniDir = aniDir;
}
} // namespace doc } // namespace doc

View File

@ -9,6 +9,7 @@
#pragma once #pragma once
#include "base/disable_copying.h" #include "base/disable_copying.h"
#include "doc/anidir.h"
#include "doc/color.h" #include "doc/color.h"
#include "doc/frame.h" #include "doc/frame.h"
#include "doc/object.h" #include "doc/object.h"
@ -25,15 +26,18 @@ namespace doc {
frame_t toFrame() const { return m_to; } frame_t toFrame() const { return m_to; }
const std::string& name() const { return m_name; } const std::string& name() const { return m_name; }
color_t color() const { return m_color; } color_t color() const { return m_color; }
AniDir aniDir() const { return m_aniDir; }
void setFrameRange(frame_t from, frame_t to); void setFrameRange(frame_t from, frame_t to);
void setName(const std::string& name); void setName(const std::string& name);
void setColor(color_t color); void setColor(color_t color);
void setAniDir(AniDir aniDir);
public: public:
frame_t m_from, m_to; frame_t m_from, m_to;
color_t m_color; color_t m_color;
std::string m_name; std::string m_name;
AniDir m_aniDir;
DISABLE_COPYING(FrameTag); DISABLE_COPYING(FrameTag);
}; };

View File

@ -186,6 +186,7 @@ void gen_pref_header(TiXmlDocument* doc, const std::string& inputFn)
<< "\n" << "\n"
<< "#include \"app/color.h\"\n" << "#include \"app/color.h\"\n"
<< "#include \"app/pref/option.h\"\n" << "#include \"app/pref/option.h\"\n"
<< "#include \"doc/anidir.h\"\n"
<< "#include \"doc/frame.h\"\n" << "#include \"doc/frame.h\"\n"
<< "#include \"gfx/rect.h\"\n" << "#include \"gfx/rect.h\"\n"
<< "#include \"filters/tiled_mode.h\"\n" << "#include \"filters/tiled_mode.h\"\n"