[aseprite] 133/308: Add "Play Once" option in "Play" button popup
Tobias Hansen
thansen at moszumanska.debian.org
Tue Mar 8 02:45:01 UTC 2016
This is an automated email from the git hooks/post-receive script.
thansen pushed a commit to branch master
in repository aseprite.
commit fcbb3640856919dfa66789342acd0bbe4b7b017a
Author: David Capello <davidcapello at gmail.com>
Date: Fri Dec 18 18:51:30 2015 -0300
Add "Play Once" option in "Play" button popup
---
data/pref.xml | 4 +++
src/app/commands/cmd_play_animation.cpp | 3 +-
src/app/ui/ani_controls.cpp | 3 +-
src/app/ui/editor/editor.cpp | 21 ++++++++++---
src/app/ui/editor/editor.h | 6 ++--
src/app/ui/editor/play_state.cpp | 52 ++++++++++++++++++++++++++++++---
src/app/ui/editor/play_state.h | 3 +-
src/app/ui/preview_editor.cpp | 46 +++++++++++++++++++++++------
src/app/ui/preview_editor.h | 8 ++++-
9 files changed, 123 insertions(+), 23 deletions(-)
diff --git a/data/pref.xml b/data/pref.xml
index 1cd907d..c151c5b 100644
--- a/data/pref.xml
+++ b/data/pref.xml
@@ -89,6 +89,10 @@
<option id="right_click_mode" type="RightClickMode" default="RightClickMode::PAINT_BGCOLOR" migrate="Options.RightClickMode" />
<option id="auto_select_layer" type="bool" default="false" migrate="Options.AutoSelectLayer" />
<option id="cursor_color" type="app::Color" default="app::Color::fromMask()" migrate="Tools.CursorColor" />
+ <option id="play_once" type="bool" default="false" />
+ </section>
+ <section id="preview" text="Preview">
+ <option id="play_once" type="bool" default="false" />
</section>
<section id="theme" text="Theme">
<option id="selected" type="std::string" default=""default"" migrate="Skin.Selected" />
diff --git a/src/app/commands/cmd_play_animation.cpp b/src/app/commands/cmd_play_animation.cpp
index b5178cd..26b2f10 100644
--- a/src/app/commands/cmd_play_animation.cpp
+++ b/src/app/commands/cmd_play_animation.cpp
@@ -13,6 +13,7 @@
#include "app/context.h"
#include "app/context_access.h"
#include "app/modules/editors.h"
+#include "app/pref/preferences.h"
#include "app/ui/editor/editor.h"
namespace app {
@@ -59,7 +60,7 @@ void PlayAnimationCommand::onExecute(Context* context)
if (current_editor->isPlaying())
current_editor->stop();
else
- current_editor->play();
+ current_editor->play(Preferences::instance().editor.playOnce());
}
Command* CommandFactory::createPlayAnimationCommand()
diff --git a/src/app/ui/ani_controls.cpp b/src/app/ui/ani_controls.cpp
index 826760a..c70282d 100644
--- a/src/app/ui/ani_controls.cpp
+++ b/src/app/ui/ani_controls.cpp
@@ -110,7 +110,8 @@ void AniControls::onRightClick(Item* item)
ButtonSet::onRightClick(item);
if (item == getItem(ACTION_PLAY) && current_editor)
- current_editor->showAnimationSpeedMultiplierPopup(true);
+ current_editor->showAnimationSpeedMultiplierPopup(
+ Preferences::instance().editor.playOnce, true);
}
const char* AniControls::getCommandId(int index) const
diff --git a/src/app/ui/editor/editor.cpp b/src/app/ui/editor/editor.cpp
index 5399a9c..d1eafbf 100644
--- a/src/app/ui/editor/editor.cpp
+++ b/src/app/ui/editor/editor.cpp
@@ -1594,14 +1594,14 @@ void Editor::notifyScrollChanged()
m_observers.notifyScrollChanged(this);
}
-void Editor::play()
+void Editor::play(bool playOnce)
{
ASSERT(m_state);
if (!m_state)
return;
if (!dynamic_cast<PlayState*>(m_state.get()))
- setState(EditorStatePtr(new PlayState));
+ setState(EditorStatePtr(new PlayState(playOnce)));
}
void Editor::stop()
@@ -1619,7 +1619,8 @@ bool Editor::isPlaying() const
return (dynamic_cast<PlayState*>(m_state.get()) != nullptr);
}
-void Editor::showAnimationSpeedMultiplierPopup(bool withStopBehaviorOptions)
+void Editor::showAnimationSpeedMultiplierPopup(Option<bool>& playOnce,
+ bool withStopBehaviorOptions)
{
double options[] = { 0.25, 0.5, 1.0, 1.5, 2.0, 3.0 };
Menu menu;
@@ -1631,8 +1632,20 @@ void Editor::showAnimationSpeedMultiplierPopup(bool withStopBehaviorOptions)
menu.addChild(item);
}
+ menu.addChild(new MenuSeparator);
+
+ // Play once option
+ {
+ MenuItem* item = new MenuItem("Play Once");
+ item->Click.connect(
+ [&playOnce]() {
+ playOnce(!playOnce());
+ });
+ item->setSelected(playOnce());
+ menu.addChild(item);
+ }
+
if (withStopBehaviorOptions) {
- menu.addChild(new MenuSeparator);
MenuItem* item = new MenuItem("Rewind on Stop");
item->Click.connect(
[]() {
diff --git a/src/app/ui/editor/editor.h b/src/app/ui/editor/editor.h
index 90b7a9f..70efb2f 100644
--- a/src/app/ui/editor/editor.h
+++ b/src/app/ui/editor/editor.h
@@ -12,6 +12,7 @@
#include "app/app_render.h"
#include "app/color.h"
#include "app/document.h"
+#include "app/pref/option.h"
#include "app/tools/selection_mode.h"
#include "app/ui/editor/brush_preview.h"
#include "app/ui/editor/editor_observers.h"
@@ -194,12 +195,13 @@ namespace app {
void notifyScrollChanged();
// Animation control
- void play();
+ void play(bool playOnce);
void stop();
bool isPlaying() const;
// Shows a popup menu to change the editor animation speed.
- void showAnimationSpeedMultiplierPopup(bool withStopBehaviorOptions);
+ void showAnimationSpeedMultiplierPopup(Option<bool>& playOnce,
+ bool withStopBehaviorOptions);
double getAnimationSpeedMultiplier() const;
void setAnimationSpeedMultiplier(double speed);
diff --git a/src/app/ui/editor/play_state.cpp b/src/app/ui/editor/play_state.cpp
index d2ad40f..242d32d 100644
--- a/src/app/ui/editor/play_state.cpp
+++ b/src/app/ui/editor/play_state.cpp
@@ -18,6 +18,7 @@
#include "app/ui/editor/editor.h"
#include "app/ui/editor/scrolling_state.h"
#include "app/ui_context.h"
+#include "doc/frame_tag.h"
#include "doc/handle_anidir.h"
#include "ui/manager.h"
#include "ui/message.h"
@@ -27,8 +28,9 @@ namespace app {
using namespace ui;
-PlayState::PlayState()
+PlayState::PlayState(bool playOnce)
: m_editor(nullptr)
+ , m_playOnce(playOnce)
, m_toScroll(false)
, m_playTimer(10)
, m_nextFrameTime(-1)
@@ -51,6 +53,21 @@ void PlayState::onEnterState(Editor* editor)
m_refFrame = editor->frame();
}
+ // Go to the first frame of the animation or active frame tag
+ if (m_playOnce) {
+ frame_t frame = 0;
+
+ doc::FrameTag* tag = get_animation_tag(
+ m_editor->sprite(), m_refFrame);
+ if (tag) {
+ frame = (tag->aniDir() == AniDir::REVERSE ?
+ tag->toFrame():
+ tag->fromFrame());
+ }
+
+ m_editor->setFrame(frame);
+ }
+
m_toScroll = false;
m_nextFrameTime = getNextFrameTime();
m_curFrameTick = ui::clock();
@@ -65,7 +82,7 @@ void PlayState::onEnterState(Editor* editor)
EditorState::LeaveAction PlayState::onLeaveState(Editor* editor, EditorState* newState)
{
if (!m_toScroll) {
- if (Preferences::instance().general.rewindOnStop())
+ if (m_playOnce || Preferences::instance().general.rewindOnStop())
m_editor->setFrame(m_refFrame);
// We don't stop the timer if we are going to the ScrollingState
@@ -135,8 +152,35 @@ void PlayState::onPlaybackTick()
doc::FrameTag* tag = get_animation_tag(sprite, m_refFrame);
while (m_nextFrameTime <= 0) {
- doc::frame_t frame = calculate_next_frame(
- sprite, m_editor->frame(), frame_t(1), tag,
+ doc::frame_t frame = m_editor->frame();
+
+ if (m_playOnce) {
+ bool atEnd = false;
+ if (tag) {
+ switch (tag->aniDir()) {
+ case AniDir::FORWARD:
+ atEnd = (frame == tag->toFrame());
+ break;
+ case AniDir::REVERSE:
+ atEnd = (frame == tag->fromFrame());
+ break;
+ case AniDir::PING_PONG:
+ atEnd = (!m_pingPongForward &&
+ frame == tag->fromFrame());
+ break;
+ }
+ }
+ else {
+ atEnd = (frame == sprite->lastFrame());
+ }
+ if (atEnd) {
+ m_editor->stop();
+ break;
+ }
+ }
+
+ frame = calculate_next_frame(
+ sprite, frame, frame_t(1), tag,
m_pingPongForward);
m_editor->setFrame(frame);
diff --git a/src/app/ui/editor/play_state.h b/src/app/ui/editor/play_state.h
index 0f6e3b2..4ada6d9 100644
--- a/src/app/ui/editor/play_state.h
+++ b/src/app/ui/editor/play_state.h
@@ -20,7 +20,7 @@ namespace app {
class PlayState : public StateWithWheelBehavior {
public:
- PlayState();
+ PlayState(bool playOnce);
void onEnterState(Editor* editor) override;
LeaveAction onLeaveState(Editor* editor, EditorState* newState) override;
@@ -39,6 +39,7 @@ namespace app {
double getNextFrameTime();
Editor* m_editor;
+ bool m_playOnce;
bool m_toScroll;
ui::Timer m_playTimer;
diff --git a/src/app/ui/preview_editor.cpp b/src/app/ui/preview_editor.cpp
index a017328..ee95b91 100644
--- a/src/app/ui/preview_editor.cpp
+++ b/src/app/ui/preview_editor.cpp
@@ -21,6 +21,7 @@
#include "app/ui/editor/editor.h"
#include "app/ui/editor/editor_view.h"
#include "app/ui/editor/navigate_state.h"
+#include "app/ui/editor/play_state.h"
#include "app/ui/skin/skin_button.h"
#include "app/ui/skin/skin_theme.h"
#include "app/ui/status_bar.h"
@@ -101,6 +102,11 @@ public:
bool isPlaying() const { return m_isPlaying; }
+ void stop() {
+ m_isPlaying = false;
+ setupIcons();
+ }
+
base::Signal0<void> Popup;
private:
@@ -251,8 +257,7 @@ void PreviewEditorWindow::onClose(ui::CloseEvent& ev)
// state. TODO abstract this event
ToolBar::instance()->invalidate();
- delete m_docView;
- m_docView = NULL;
+ destroyDocView();
}
}
@@ -282,7 +287,7 @@ void PreviewEditorWindow::onPlayClicked()
if (m_playButton->isPlaying()) {
m_refFrame = miniEditor->frame();
- miniEditor->play();
+ miniEditor->play(Preferences::instance().preview.playOnce());
}
else
miniEditor->stop();
@@ -294,7 +299,8 @@ void PreviewEditorWindow::onPopupSpeed()
if (!miniEditor || !miniEditor->document())
return;
- miniEditor->showAnimationSpeedMultiplierPopup(false);
+ miniEditor->showAnimationSpeedMultiplierPopup(
+ Preferences::instance().preview.playOnce, false);
m_aniSpeed = miniEditor->getAnimationSpeedMultiplier();
}
@@ -323,7 +329,8 @@ void PreviewEditorWindow::updateUsingEditor(Editor* editor)
// Set the same location as in the given editor.
if (!miniEditor || miniEditor->document() != document) {
- delete m_docView;
+ destroyDocView();
+
m_docView = new DocumentView(document, DocumentView::Preview);
addChild(m_docView);
@@ -333,6 +340,7 @@ void PreviewEditorWindow::updateUsingEditor(Editor* editor)
miniEditor->setFrame(editor->frame());
miniEditor->setState(EditorStatePtr(new NavigateState));
miniEditor->setAnimationSpeedMultiplier(m_aniSpeed);
+ miniEditor->addObserver(this);
layout();
center = true;
}
@@ -356,7 +364,7 @@ void PreviewEditorWindow::updateUsingEditor(Editor* editor)
if (!miniEditor->isPlaying())
miniEditor->setFrame(m_refFrame = editor->frame());
- miniEditor->play();
+ miniEditor->play(Preferences::instance().preview.playOnce());
}
}
@@ -366,13 +374,33 @@ void PreviewEditorWindow::uncheckCenterButton()
m_centerButton->setSelected(false);
}
-void PreviewEditorWindow::hideWindow()
+void PreviewEditorWindow::onStateChanged(Editor* editor)
{
- delete m_docView;
- m_docView = NULL;
+ EditorStatePtr state = editor->getState();
+ PlayState* playState = (state ? dynamic_cast<PlayState*>(state.get()): nullptr);
+ if (!playState) {
+ // We have to switch the "play button" state to "play" because the
+ // editor animation has just stopped. This happens when we use
+ // "play once" option and the PlayState stops automatically.
+ m_playButton->stop();
+ }
+}
+void PreviewEditorWindow::hideWindow()
+{
+ destroyDocView();
if (isVisible())
closeWindow(NULL);
}
+void PreviewEditorWindow::destroyDocView()
+{
+ if (m_docView) {
+ m_docView->getEditor()->removeObserver(this);
+
+ delete m_docView;
+ m_docView = nullptr;
+ }
+}
+
} // namespace app
diff --git a/src/app/ui/preview_editor.h b/src/app/ui/preview_editor.h
index f61c369..57ff4f6 100644
--- a/src/app/ui/preview_editor.h
+++ b/src/app/ui/preview_editor.h
@@ -10,6 +10,7 @@
#pragma once
#include "app/ui/document_view.h"
+#include "app/ui/editor/editor_observer.h"
#include "doc/frame.h"
#include "ui/window.h"
@@ -17,7 +18,8 @@ namespace app {
class MiniCenterButton;
class MiniPlayButton;
- class PreviewEditorWindow : public ui::Window {
+ class PreviewEditorWindow : public ui::Window
+ , public EditorObserver {
public:
PreviewEditorWindow();
~PreviewEditorWindow();
@@ -30,6 +32,9 @@ namespace app {
Editor* relatedEditor() const { return m_relatedEditor; }
+ // EditorObserver impl
+ void onStateChanged(Editor* editor) override;
+
protected:
bool onProcessMessage(ui::Message* msg) override;
void onClose(ui::CloseEvent& ev) override;
@@ -40,6 +45,7 @@ namespace app {
void onPlayClicked();
void onPopupSpeed();
void hideWindow();
+ void destroyDocView();
bool m_isEnabled;
DocumentView* m_docView;
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/aseprite.git
More information about the Pkg-games-commits
mailing list