Skip to content

Commit

Permalink
Add timeline options for onion skin, loop section, and animation dire…
Browse files Browse the repository at this point in the history
…ction

- Add red/blue onion skin type
- Add app::calculate_next_frame() function to calculate the next frame
  depending of the timeline configuration (loop range, animation direction)
- Add app::finder() to simplify the access to widgets loaded from xml files
  • Loading branch information
dacap committed May 18, 2014
1 parent 263f4b5 commit a15aea5
Show file tree
Hide file tree
Showing 20 changed files with 820 additions and 89 deletions.
Binary file modified data/skins/default/sheet.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions data/skins/default/skin.xml
Expand Up @@ -317,6 +317,7 @@
<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_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" />
</parts>

<stylesheet>
Expand Down Expand Up @@ -519,6 +520,11 @@
<background part="timeline_drop_frame_deco" />
</style>

<!-- timeline_loop_range -->
<style id="timeline_loop_range">
<background part="timeline_loop_range" />
</style>

</stylesheet>

</skin>
29 changes: 29 additions & 0 deletions data/widgets/timeline_conf.xml
@@ -0,0 +1,29 @@
<!-- ASEPRITE -->
<!-- Copyright (C) 2014 by David Capello -->
<gui>
<vbox id="mainbox">
<grid columns="2">
<separator cell_hspan="2" text="Onion Skin:" left="true" horizontal="true" />
<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" />

<separator cell_hspan="2" text="Loop:" left="true" horizontal="true" />
<button id="loop_section" text="Set Loop Section" />
<button id="reset_loop_section" text="Reset Loop Section" />
<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>
</grid>
</vbox>
</gui>
2 changes: 2 additions & 0 deletions src/app/CMakeLists.txt
Expand Up @@ -126,6 +126,7 @@ add_library(app-lib
flatten.cpp
gfxmode.cpp
gui_xml.cpp
handle_anidir.cpp
ini_file.cpp
job.cpp
launcher.cpp
Expand Down Expand Up @@ -155,6 +156,7 @@ add_library(app-lib
ui/color_button.cpp
ui/color_selector.cpp
ui/color_sliders.cpp
ui/configure_timeline_popup.cpp
ui/context_bar.cpp
ui/devconsole_view.cpp
ui/document_view.cpp
Expand Down
12 changes: 8 additions & 4 deletions src/app/commands/cmd_play_animation.cpp
Expand Up @@ -28,6 +28,7 @@
#include "app/commands/command.h"
#include "app/context.h"
#include "app/context_access.h"
#include "app/handle_anidir.h"
#include "app/modules/editors.h"
#include "app/modules/gui.h"
#include "app/modules/palettes.h"
Expand Down Expand Up @@ -87,6 +88,7 @@ void PlayAnimationCommand::onExecute(Context* context)
IDocumentSettings* docSettings = context->getSettings()->getDocumentSettings(document);
bool onionskin_state = docSettings->getUseOnionskin();
Palette *oldpal, *newpal;
bool pingPongForward = true;

if (sprite->getTotalFrames() < 2)
return;
Expand Down Expand Up @@ -141,10 +143,12 @@ void PlayAnimationCommand::onExecute(Context* context)
} while (!done && (speed_timer <= 0));

if (!done) {
FrameNumber frame = current_editor->getFrame().next();
if (frame > sprite->getLastFrame())
frame = FrameNumber(0);
current_editor->setFrame(frame);
current_editor->setFrame(
calculate_next_frame(
sprite,
current_editor->getFrame(),
docSettings,
pingPongForward));

speed_timer--;
}
Expand Down
26 changes: 26 additions & 0 deletions src/app/find_widget.h
Expand Up @@ -34,6 +34,32 @@ namespace app {
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

#endif
84 changes: 84 additions & 0 deletions src/app/handle_anidir.cpp
@@ -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
41 changes: 41 additions & 0 deletions src/app/handle_anidir.h
@@ -0,0 +1,41 @@
/* 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_HANDLE_ANIDIR_H_INCLUDED
#define APP_HANDLE_ANIDIR_H_INCLUDED
#pragma once

#include "raster/frame_number.h"

namespace raster {
class Sprite;
}

namespace app {

class IDocumentSettings;

raster::FrameNumber calculate_next_frame(
raster::Sprite* sprite,
raster::FrameNumber frame,
IDocumentSettings* docSettings,
bool& pingPongForward);

} // namespace app

#endif
28 changes: 28 additions & 0 deletions src/app/settings/document_settings.h
Expand Up @@ -24,6 +24,7 @@
#include "filters/tiled_mode.h"
#include "gfx/point.h"
#include "gfx/rect.h"
#include "raster/frame_number.h"

namespace app {
class DocumentSettingsObserver;
Expand Down Expand Up @@ -61,17 +62,44 @@ namespace app {

// Onionskin settings

enum OnionskinType {
Onionskin_Merge,
Onionskin_RedBlueTint,
Onionskin_Last = Onionskin_RedBlueTint
};

virtual bool getUseOnionskin() = 0;
virtual int getOnionskinPrevFrames() = 0;
virtual int getOnionskinNextFrames() = 0;
virtual int getOnionskinOpacityBase() = 0;
virtual int getOnionskinOpacityStep() = 0;
virtual OnionskinType getOnionskinType() = 0;

virtual void setUseOnionskin(bool state) = 0;
virtual void setOnionskinPrevFrames(int frames) = 0;
virtual void setOnionskinNextFrames(int frames) = 0;
virtual void setOnionskinOpacityBase(int base) = 0;
virtual void setOnionskinOpacityStep(int step) = 0;
virtual void setOnionskinType(OnionskinType type) = 0;
virtual void setDefaultOnionskinSettings() = 0;

// Animation

enum AniDir {
AniDir_Normal,
AniDir_Reverse,
AniDir_PingPong
};

virtual bool getLoopAnimation() = 0;
virtual void getLoopRange(raster::FrameNumber* begin, raster::FrameNumber* end) = 0;
virtual AniDir getAnimationDirection() = 0;

virtual void setLoopAnimation(bool state) = 0;
virtual void setLoopRange(raster::FrameNumber begin, raster::FrameNumber end) = 0;
virtual void setAnimationDirection(AniDir dir) = 0;

// Observable

virtual void addObserver(DocumentSettingsObserver* observer) = 0;
virtual void removeObserver(DocumentSettingsObserver* observer) = 0;
Expand Down

0 comments on commit a15aea5

Please sign in to comment.