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 <[email protected]> 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 _______________________________________________ Pkg-games-commits mailing list [email protected] http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-games-commits

