mirror of
https://github.com/aseprite/aseprite.git
synced 2024-09-02 13:09:27 +00:00
Put playback options into Frame > Playback submenu
This menu was accessible right-clicking the Play button in the Timeline (and in the Preview window, with specific options for the Preview). This change includes some changes: 1. Now if a menu <item> in gui.xml doesn't specify a text field, the text of the command is used (to avoid double translation, the bad side is that we don't have a mnemonic specified). 2. Menu::showPopup() can be used with submenus from the root menu, to do this we have to remove the menu item owner temporarily before we show the menu as popup (see the change in Menu::showPopup()) 3. We can specify a special active DocView for commands with UIContext::SetTargetView, this is used to set the Preview editor as active view for commands like TogglePlayOnce, etc.
This commit is contained in:
parent
0dbcdc8159
commit
30a88c8e3d
20
data/gui.xml
20
data/gui.xml
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Aseprite -->
|
||||
<!-- Copyright (C) 2018-2022 Igara Studio S.A. -->
|
||||
<!-- Copyright (C) 2018-2023 Igara Studio S.A. -->
|
||||
<!-- Copyright (C) 2001-2018 David Capello -->
|
||||
<gui>
|
||||
<!-- Keyboard shortcuts -->
|
||||
@ -911,6 +911,23 @@
|
||||
</item>
|
||||
<item command="RemoveFrame" text="@.frame_delete_frame" group="cel_delete" />
|
||||
<separator />
|
||||
<menu text="@.frame_playback" id="animation_menu" group="cel_animation">
|
||||
<item command="PlayAnimation" />
|
||||
<item command="PlayPreviewAnimation" />
|
||||
<separator />
|
||||
<item command="SetPlaybackSpeed"><param name="multiplier" value="0.25" /></item>
|
||||
<item command="SetPlaybackSpeed"><param name="multiplier" value="0.5" /></item>
|
||||
<item command="SetPlaybackSpeed"><param name="multiplier" value="1.0" /></item>
|
||||
<item command="SetPlaybackSpeed"><param name="multiplier" value="1.5" /></item>
|
||||
<item command="SetPlaybackSpeed"><param name="multiplier" value="2.0" /></item>
|
||||
<item command="SetPlaybackSpeed"><param name="multiplier" value="3.0" /></item>
|
||||
<separator />
|
||||
<item command="TogglePlayOnce" />
|
||||
<item command="TogglePlayAll" />
|
||||
<item command="TogglePlaySubtags" />
|
||||
<separator />
|
||||
<item command="ToggleRewindOnStop" />
|
||||
</menu>
|
||||
<menu text="@.frame_tags">
|
||||
<item command="FrameTagProperties" text="@.frame_tags_tag_properties" />
|
||||
<separator />
|
||||
@ -928,7 +945,6 @@
|
||||
<separator />
|
||||
<item command="GotoFrame" text="@.frame_go_to_frame" />
|
||||
</menu>
|
||||
<item command="PlayAnimation" text="@.frame_play_animation" group="cel_animation" />
|
||||
<separator />
|
||||
<item command="FrameProperties" text="@.frame_constant_frame_rate">
|
||||
<param name="frame" value="all" />
|
||||
|
@ -549,6 +549,7 @@ SetInkType = Set Ink Type: {0}
|
||||
SetLoopSection = Set Loop Section
|
||||
SetPalette = Set Palette
|
||||
SetPaletteEntrySize = Set Palette Entry Size
|
||||
SetPlaybackSpeed = Playback Speed {0}x
|
||||
SetSameInk = Same Ink in All Tools
|
||||
ShowAutoGuides = Show Auto Guides
|
||||
ShowBrushPreview = Show Brush Preview
|
||||
@ -577,13 +578,17 @@ SwitchNonactiveLayersOpacity = Switch Nonactive Layers Opacity
|
||||
SymmetryMode = Symmetry Mode
|
||||
TiledMode = Tiled Mode
|
||||
Timeline = Switch Timeline
|
||||
TogglePlayAll = Play All Frames (Ignore Tags)
|
||||
TogglePlayOnce = Play Once
|
||||
TogglePlaySubtags = Play Subtags & Repetitions
|
||||
TogglePreview = Toggle Preview
|
||||
ToggleRewindOnStop = Rewind on Stop
|
||||
ToggleTilesMode = Toggle Tiles Mode
|
||||
ToggleTimelineThumbnails = Toggle Timeline Thumbnails
|
||||
TilesetMode = Tileset Mode: {}
|
||||
TilesetMode_Manual = Manual
|
||||
TilesetMode_Auto = Auto
|
||||
TilesetMode_Stack = Stack
|
||||
ToggleTimelineThumbnails = Toggle Timeline Thumbnails
|
||||
Undo = Undo
|
||||
UndoHistory = Undo History
|
||||
UnlinkCel = Unlink Cel
|
||||
@ -1244,13 +1249,14 @@ layer_merge_down = &Merge Down
|
||||
layer_flatten = &Flatten
|
||||
layer_flatten_visible = Flatten Vi&sible
|
||||
frame = F&rame
|
||||
frame_properties = Frame &Properties...
|
||||
frame_properties = &Frame Properties...
|
||||
frame_cel_properties = &Cel Properties...
|
||||
frame_new_frame = &New Frame
|
||||
frame_new_empty_frame = New &Empty Frame
|
||||
frame_duplicate_cels = &Duplicate Cel(s)
|
||||
frame_duplicate_linked_cels = Duplicate &Linked Cel(s)
|
||||
frame_delete_frame = Delete F&rame
|
||||
frame_playback = &Playback
|
||||
frame_tags = &Tags
|
||||
frame_tags_tag_properties = Tag &Properties...
|
||||
frame_tags_new_tag = New &Tag
|
||||
@ -1263,7 +1269,6 @@ frame_jump_to_last_frame = &Last Frame
|
||||
frame_jump_to_first_frame_in_tag = First Frame In Tag
|
||||
frame_jump_to_last_frame_in_tag = Last Frame In Tag
|
||||
frame_go_to_frame = &Go to Frame
|
||||
frame_play_animation = &Play Animation
|
||||
frame_constant_frame_rate = Constant Frame Rate
|
||||
frame_reverse_frames = Re&verse Frames
|
||||
select = Selec&t
|
||||
@ -1799,11 +1804,6 @@ antialias_tooltip = Smooth font edges
|
||||
|
||||
[preview]
|
||||
title = Preview
|
||||
speed_x = Speed x{}
|
||||
play_once = Play Once
|
||||
play_all_no_tags = Play All Frames (Ignore Tags)
|
||||
play_subtags_and_repeats = Play Subtags & Repetitions
|
||||
rewind_on_stop = Rewind on Stop
|
||||
|
||||
[recover_files]
|
||||
title = Recover Files
|
||||
|
@ -323,8 +323,10 @@ if(ENABLE_UI)
|
||||
commands/filters/filter_target_buttons.cpp
|
||||
commands/filters/filter_window.cpp
|
||||
commands/screenshot.cpp
|
||||
commands/set_playback_speed.cpp
|
||||
commands/show_menu.cpp
|
||||
commands/tileset_mode.cpp
|
||||
commands/toggle_play_option.cpp
|
||||
file_selector.cpp
|
||||
modules/gfx.cpp
|
||||
modules/gui.cpp
|
||||
|
@ -608,6 +608,16 @@ bool AppMenus::rebuildRecentList()
|
||||
return true;
|
||||
}
|
||||
|
||||
Menu* AppMenus::getAnimationMenu()
|
||||
{
|
||||
auto menuItem =
|
||||
dynamic_cast<MenuItem*>(m_rootMenu->findItemById("animation_menu"));
|
||||
if (menuItem)
|
||||
return menuItem->getSubmenu();
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void AppMenus::addMenuGroup(const std::string& groupId,
|
||||
MenuItem* menuItem)
|
||||
{
|
||||
@ -766,10 +776,10 @@ Widget* AppMenus::convertXmlelemToMenuitem(TiXmlElement* elem, Menu* menu)
|
||||
return item;
|
||||
}
|
||||
|
||||
const char* command_id = elem->Attribute("command");
|
||||
const char* commandId = elem->Attribute("command");
|
||||
Command* command =
|
||||
command_id ? Commands::instance()->byId(command_id):
|
||||
nullptr;
|
||||
(commandId ? Commands::instance()->byId(commandId):
|
||||
nullptr);
|
||||
|
||||
// load params
|
||||
Params params;
|
||||
@ -793,8 +803,17 @@ Widget* AppMenus::convertXmlelemToMenuitem(TiXmlElement* elem, Menu* menu)
|
||||
if (!menuitem)
|
||||
return nullptr;
|
||||
|
||||
// Get menu item text from command friendly name
|
||||
if (command && menuitem->text().empty()) {
|
||||
command->loadParams(params);
|
||||
menuitem->setText(command->friendlyName());
|
||||
}
|
||||
// If the menu item has a specific text, process its mnemonic
|
||||
else {
|
||||
menuitem->processMnemonicFromText();
|
||||
}
|
||||
|
||||
if (id) menuitem->setId(id);
|
||||
menuitem->processMnemonicFromText();
|
||||
if (group) {
|
||||
m_groups[group].menu = menu;
|
||||
m_groups[group].end = menuitem;
|
||||
|
@ -54,6 +54,7 @@ namespace app {
|
||||
Menu* getSlicePopupMenu() { return m_slicePopupMenu.get(); }
|
||||
Menu* getPalettePopupMenu() { return m_palettePopupMenu.get(); }
|
||||
Menu* getInkPopupMenu() { return m_inkPopupMenu.get(); }
|
||||
Menu* getAnimationMenu();
|
||||
|
||||
void applyShortcutToMenuitemsWithCommand(Command* command, const Params& params,
|
||||
const KeyPtr& key);
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2022 Igara Studio S.A.
|
||||
// Copyright (C) 2022-2023 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -29,8 +29,9 @@ public:
|
||||
PlayAnimationCommand();
|
||||
|
||||
protected:
|
||||
bool onEnabled(Context* context) override;
|
||||
void onExecute(Context* context) override;
|
||||
bool onEnabled(Context* ctx) override;
|
||||
bool onChecked(Context* ctx) override;
|
||||
void onExecute(Context* ctx) override;
|
||||
};
|
||||
|
||||
PlayAnimationCommand::PlayAnimationCommand()
|
||||
@ -38,17 +39,23 @@ PlayAnimationCommand::PlayAnimationCommand()
|
||||
{
|
||||
}
|
||||
|
||||
bool PlayAnimationCommand::onEnabled(Context* context)
|
||||
bool PlayAnimationCommand::onEnabled(Context* ctx)
|
||||
{
|
||||
return context->checkFlags(ContextFlags::ActiveDocumentIsWritable |
|
||||
ContextFlags::HasActiveSprite);
|
||||
return ctx->checkFlags(ContextFlags::ActiveDocumentIsWritable |
|
||||
ContextFlags::HasActiveSprite);
|
||||
}
|
||||
|
||||
void PlayAnimationCommand::onExecute(Context* context)
|
||||
bool PlayAnimationCommand::onChecked(Context* ctx)
|
||||
{
|
||||
auto editor = Editor::activeEditor();
|
||||
return (editor && editor->isPlaying());
|
||||
}
|
||||
|
||||
void PlayAnimationCommand::onExecute(Context* ctx)
|
||||
{
|
||||
// Do not play one-frame images
|
||||
{
|
||||
ContextReader writer(context);
|
||||
ContextReader writer(ctx);
|
||||
Sprite* sprite(writer.sprite());
|
||||
if (!sprite || sprite->totalFrames() < 2)
|
||||
return;
|
||||
@ -74,8 +81,9 @@ public:
|
||||
PlayPreviewAnimationCommand();
|
||||
|
||||
protected:
|
||||
bool onEnabled(Context* context) override;
|
||||
void onExecute(Context* context) override;
|
||||
bool onEnabled(Context* ctx) override;
|
||||
bool onChecked(Context* ctx) override;
|
||||
void onExecute(Context* ctx) override;
|
||||
};
|
||||
|
||||
PlayPreviewAnimationCommand::PlayPreviewAnimationCommand()
|
||||
@ -83,13 +91,19 @@ PlayPreviewAnimationCommand::PlayPreviewAnimationCommand()
|
||||
{
|
||||
}
|
||||
|
||||
bool PlayPreviewAnimationCommand::onEnabled(Context* context)
|
||||
bool PlayPreviewAnimationCommand::onEnabled(Context* ctx)
|
||||
{
|
||||
return context->checkFlags(ContextFlags::ActiveDocumentIsWritable |
|
||||
ContextFlags::HasActiveSprite);
|
||||
return ctx->checkFlags(ContextFlags::ActiveDocumentIsWritable |
|
||||
ContextFlags::HasActiveSprite);
|
||||
}
|
||||
|
||||
void PlayPreviewAnimationCommand::onExecute(Context* context)
|
||||
bool PlayPreviewAnimationCommand::onChecked(Context* ctx)
|
||||
{
|
||||
PreviewEditorWindow* preview = App::instance()->mainWindow()->getPreviewEditor();
|
||||
return (preview && preview->previewEditor()->isPlaying());
|
||||
}
|
||||
|
||||
void PlayPreviewAnimationCommand::onExecute(Context* ctx)
|
||||
{
|
||||
PreviewEditorWindow* preview = App::instance()->mainWindow()->getPreviewEditor();
|
||||
if (!preview->isPreviewEnabled())
|
||||
|
@ -146,6 +146,7 @@ FOR_EACH_COMMAND(SetInkType)
|
||||
FOR_EACH_COMMAND(SetLoopSection)
|
||||
FOR_EACH_COMMAND(SetPalette)
|
||||
FOR_EACH_COMMAND(SetPaletteEntrySize)
|
||||
FOR_EACH_COMMAND(SetPlaybackSpeed)
|
||||
FOR_EACH_COMMAND(SetSameInk)
|
||||
FOR_EACH_COMMAND(ShowAutoGuides)
|
||||
FOR_EACH_COMMAND(ShowBrushPreview)
|
||||
@ -167,7 +168,11 @@ FOR_EACH_COMMAND(SymmetryMode)
|
||||
FOR_EACH_COMMAND(TiledMode)
|
||||
FOR_EACH_COMMAND(TilesetMode)
|
||||
FOR_EACH_COMMAND(Timeline)
|
||||
FOR_EACH_COMMAND(TogglePlayAll)
|
||||
FOR_EACH_COMMAND(TogglePlayOnce)
|
||||
FOR_EACH_COMMAND(TogglePlaySubtags)
|
||||
FOR_EACH_COMMAND(TogglePreview)
|
||||
FOR_EACH_COMMAND(ToggleRewindOnStop)
|
||||
FOR_EACH_COMMAND(ToggleTilesMode)
|
||||
FOR_EACH_COMMAND(ToggleTimelineThumbnails)
|
||||
FOR_EACH_COMMAND(UndoHistory)
|
||||
|
66
src/app/commands/set_playback_speed.cpp
Normal file
66
src/app/commands/set_playback_speed.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
// Aseprite
|
||||
// Copyright (c) 2023 Igara Studio S.A.
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "app/commands/new_params.h"
|
||||
#include "app/ui_context.h"
|
||||
#include "app/ui/editor/editor.h"
|
||||
#include "fmt/format.h"
|
||||
|
||||
namespace app {
|
||||
|
||||
struct SetPlaybackSpeedParams : public NewParams {
|
||||
Param<double> multiplier { this, 1.0, "multiplier" };
|
||||
};
|
||||
|
||||
class SetPlaybackSpeedCommand : public CommandWithNewParams<SetPlaybackSpeedParams> {
|
||||
public:
|
||||
SetPlaybackSpeedCommand();
|
||||
protected:
|
||||
bool onChecked(Context* ctx) override;
|
||||
void onExecute(Context* ctx) override;
|
||||
std::string onGetFriendlyName() const override;
|
||||
};
|
||||
|
||||
SetPlaybackSpeedCommand::SetPlaybackSpeedCommand()
|
||||
: CommandWithNewParams(CommandId::SetPlaybackSpeed(), CmdUIOnlyFlag)
|
||||
{
|
||||
}
|
||||
|
||||
bool SetPlaybackSpeedCommand::onChecked(Context* ctx)
|
||||
{
|
||||
Editor* editor = nullptr;
|
||||
if (ctx->isUIAvailable())
|
||||
editor = static_cast<UIContext*>(ctx)->activeEditor();
|
||||
if (editor)
|
||||
return (params().multiplier() == editor->getAnimationSpeedMultiplier());
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void SetPlaybackSpeedCommand::onExecute(Context* ctx)
|
||||
{
|
||||
Editor* editor = nullptr;
|
||||
if (ctx->isUIAvailable())
|
||||
editor = static_cast<UIContext*>(ctx)->activeEditor();
|
||||
if (editor)
|
||||
editor->setAnimationSpeedMultiplier(params().multiplier());
|
||||
}
|
||||
|
||||
std::string SetPlaybackSpeedCommand::onGetFriendlyName() const
|
||||
{
|
||||
return fmt::format(getBaseFriendlyName(), params().multiplier());
|
||||
}
|
||||
|
||||
Command* CommandFactory::createSetPlaybackSpeedCommand()
|
||||
{
|
||||
return new SetPlaybackSpeedCommand;
|
||||
}
|
||||
|
||||
} // namespace app
|
116
src/app/commands/toggle_play_option.cpp
Normal file
116
src/app/commands/toggle_play_option.cpp
Normal file
@ -0,0 +1,116 @@
|
||||
// Aseprite
|
||||
// Copyright (c) 2023 Igara Studio S.A.
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "app/commands/command.h"
|
||||
#include "app/pref/preferences.h"
|
||||
#include "app/ui/doc_view.h"
|
||||
#include "app/ui_context.h"
|
||||
|
||||
namespace app {
|
||||
|
||||
class TogglePlayOptionCommand : public Command {
|
||||
public:
|
||||
TogglePlayOptionCommand(const char* id,
|
||||
Option<bool>* general,
|
||||
Option<bool>* preview);
|
||||
|
||||
protected:
|
||||
DocView* docView(Context* ctx) {
|
||||
if (ctx->isUIAvailable())
|
||||
return static_cast<UIContext*>(ctx)->activeView();
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool onEnabled(Context* ctx) override;
|
||||
bool onChecked(Context* ctx) override;
|
||||
void onExecute(Context* ctx) override;
|
||||
|
||||
Option<bool>* m_general;
|
||||
Option<bool>* m_preview;
|
||||
};
|
||||
|
||||
TogglePlayOptionCommand::TogglePlayOptionCommand(
|
||||
const char* id,
|
||||
Option<bool>* general,
|
||||
Option<bool>* preview)
|
||||
: Command(id, CmdUIOnlyFlag)
|
||||
, m_general(general)
|
||||
, m_preview(preview)
|
||||
{
|
||||
ASSERT(m_general);
|
||||
}
|
||||
|
||||
bool TogglePlayOptionCommand::onEnabled(Context* ctx)
|
||||
{
|
||||
if (auto docView = this->docView(ctx))
|
||||
return (!docView->isPreview() || m_preview);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TogglePlayOptionCommand::onChecked(Context* ctx)
|
||||
{
|
||||
if (auto docView = this->docView(ctx))
|
||||
return (docView->isPreview() && m_preview ? (*m_preview)(): (*m_general)());
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void TogglePlayOptionCommand::onExecute(Context* ctx)
|
||||
{
|
||||
if (auto docView = this->docView(ctx)) {
|
||||
if (docView->isPreview()) {
|
||||
ASSERT(m_preview);
|
||||
if (m_preview)
|
||||
(*m_preview)(!(*m_preview)());
|
||||
}
|
||||
else
|
||||
(*m_general)(!(*m_general)());
|
||||
}
|
||||
}
|
||||
|
||||
Command* CommandFactory::createTogglePlayOnceCommand()
|
||||
{
|
||||
auto& pref = Preferences::instance();
|
||||
return new TogglePlayOptionCommand(
|
||||
CommandId::TogglePlayOnce(),
|
||||
&pref.editor.playOnce,
|
||||
&pref.preview.playOnce);
|
||||
}
|
||||
|
||||
Command* CommandFactory::createTogglePlayAllCommand()
|
||||
{
|
||||
auto& pref = Preferences::instance();
|
||||
return new TogglePlayOptionCommand(
|
||||
CommandId::TogglePlayAll(),
|
||||
&pref.editor.playAll,
|
||||
&pref.preview.playAll);
|
||||
}
|
||||
|
||||
Command* CommandFactory::createTogglePlaySubtagsCommand()
|
||||
{
|
||||
auto& pref = Preferences::instance();
|
||||
return new TogglePlayOptionCommand(
|
||||
CommandId::TogglePlaySubtags(),
|
||||
&pref.editor.playSubtags,
|
||||
&pref.preview.playSubtags);
|
||||
}
|
||||
|
||||
Command* CommandFactory::createToggleRewindOnStopCommand()
|
||||
{
|
||||
auto& pref = Preferences::instance();
|
||||
return new TogglePlayOptionCommand(
|
||||
CommandId::ToggleRewindOnStop(),
|
||||
&pref.general.rewindOnStop,
|
||||
nullptr); // No option for preview
|
||||
}
|
||||
|
||||
} // namespace app
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2018-2022 Igara Studio S.A.
|
||||
// Copyright (C) 2018-2023 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -12,6 +12,7 @@
|
||||
#include "app/ui/editor/editor.h"
|
||||
|
||||
#include "app/app.h"
|
||||
#include "app/app_menus.h"
|
||||
#include "app/color.h"
|
||||
#include "app/color_picker.h"
|
||||
#include "app/color_utils.h"
|
||||
@ -34,6 +35,7 @@
|
||||
#include "app/tools/tool_box.h"
|
||||
#include "app/ui/color_bar.h"
|
||||
#include "app/ui/context_bar.h"
|
||||
#include "app/ui/doc_view.h"
|
||||
#include "app/ui/editor/drawing_state.h"
|
||||
#include "app/ui/editor/editor_customization_delegate.h"
|
||||
#include "app/ui/editor/editor_decorator.h"
|
||||
@ -2789,76 +2791,29 @@ bool Editor::isPlaying() const
|
||||
return m_isPlaying;
|
||||
}
|
||||
|
||||
void Editor::showAnimationSpeedMultiplierPopup(Option<bool>& playOnce,
|
||||
Option<bool>& playAll,
|
||||
Option<bool>& playSubtags,
|
||||
const bool withStopBehaviorOptions)
|
||||
void Editor::showAnimationSpeedMultiplierPopup()
|
||||
{
|
||||
const double options[] = { 0.25, 0.5, 1.0, 1.5, 2.0, 3.0 };
|
||||
Menu menu;
|
||||
|
||||
for (double option : options) {
|
||||
MenuItem* item = new MenuItem(fmt::format(Strings::preview_speed_x(), option));
|
||||
item->Click.connect([this, option]{ setAnimationSpeedMultiplier(option); });
|
||||
item->setSelected(m_aniSpeed == option);
|
||||
menu.addChild(item);
|
||||
if (auto menu = AppMenus::instance()->getAnimationMenu()) {
|
||||
UIContext::SetTargetView setView(m_docView);
|
||||
menu->showPopup(mousePosInDisplay(), display());
|
||||
}
|
||||
|
||||
menu.addChild(new MenuSeparator);
|
||||
|
||||
// Play once option
|
||||
{
|
||||
MenuItem* item = new MenuItem(Strings::preview_play_once());
|
||||
item->Click.connect(
|
||||
[&playOnce]() {
|
||||
playOnce(!playOnce());
|
||||
});
|
||||
item->setSelected(playOnce());
|
||||
menu.addChild(item);
|
||||
}
|
||||
|
||||
// Play all option
|
||||
{
|
||||
MenuItem* item = new MenuItem(Strings::preview_play_all_no_tags());
|
||||
item->Click.connect(
|
||||
[&playAll]() {
|
||||
playAll(!playAll());
|
||||
});
|
||||
item->setSelected(playAll());
|
||||
menu.addChild(item);
|
||||
}
|
||||
|
||||
// Play subtags & repeats
|
||||
{
|
||||
MenuItem* item = new MenuItem(Strings::preview_play_subtags_and_repeats());
|
||||
item->Click.connect(
|
||||
[&playSubtags]() {
|
||||
playSubtags(!playSubtags());
|
||||
});
|
||||
item->setSelected(playSubtags());
|
||||
menu.addChild(item);
|
||||
}
|
||||
|
||||
if (withStopBehaviorOptions) {
|
||||
MenuItem* item = new MenuItem(Strings::preview_rewind_on_stop());
|
||||
item->Click.connect(
|
||||
[]() {
|
||||
// Switch the "rewind_on_stop" option
|
||||
Preferences::instance().general.rewindOnStop(
|
||||
!Preferences::instance().general.rewindOnStop());
|
||||
});
|
||||
item->setSelected(Preferences::instance().general.rewindOnStop());
|
||||
menu.addChild(item);
|
||||
}
|
||||
|
||||
menu.showPopup(mousePosInDisplay(), display());
|
||||
|
||||
if (isPlaying()) {
|
||||
// Re-play
|
||||
stop();
|
||||
play(playOnce(),
|
||||
playAll(),
|
||||
playSubtags());
|
||||
|
||||
// TODO improve/generalize this in some way
|
||||
auto& pref = Preferences::instance();
|
||||
if (m_docView->isPreview()) {
|
||||
play(pref.preview.playOnce(),
|
||||
pref.preview.playAll(),
|
||||
pref.preview.playSubtags());
|
||||
}
|
||||
else {
|
||||
play(pref.editor.playOnce(),
|
||||
pref.editor.playAll(),
|
||||
pref.editor.playSubtags());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2018-2022 Igara Studio S.A.
|
||||
// Copyright (C) 2018-2023 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -282,10 +282,7 @@ namespace app {
|
||||
bool isPlaying() const;
|
||||
|
||||
// Shows a popup menu to change the editor animation speed.
|
||||
void showAnimationSpeedMultiplierPopup(Option<bool>& playOnce,
|
||||
Option<bool>& playAll,
|
||||
Option<bool>& playSubtags,
|
||||
const bool withStopBehaviorOptions);
|
||||
void showAnimationSpeedMultiplierPopup();
|
||||
double getAnimationSpeedMultiplier() const;
|
||||
void setAnimationSpeedMultiplier(double speed);
|
||||
|
||||
|
@ -332,13 +332,7 @@ void PreviewEditorWindow::onPopupSpeed()
|
||||
if (!miniEditor || !miniEditor->document())
|
||||
return;
|
||||
|
||||
auto& pref = Preferences::instance();
|
||||
|
||||
miniEditor->showAnimationSpeedMultiplierPopup(
|
||||
pref.preview.playOnce,
|
||||
pref.preview.playAll,
|
||||
pref.preview.playSubtags,
|
||||
false);
|
||||
miniEditor->showAnimationSpeedMultiplierPopup();
|
||||
m_aniSpeed = miniEditor->getAnimationSpeedMultiplier();
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2018-2022 Igara Studio S.A.
|
||||
// Copyright (C) 2018-2023 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2017 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -95,10 +95,7 @@ void AniControls::onRightClick(Item* item)
|
||||
|
||||
auto editor = Editor::activeEditor();
|
||||
if (item == getItem(ACTION_PLAY) && editor) {
|
||||
editor->showAnimationSpeedMultiplierPopup(
|
||||
Preferences::instance().editor.playOnce,
|
||||
Preferences::instance().editor.playAll,
|
||||
Preferences::instance().editor.playSubtags, true);
|
||||
editor->showAnimationSpeedMultiplierPopup();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019-2022 Igara Studio S.A.
|
||||
// Copyright (C) 2019-2023 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -34,8 +34,7 @@ namespace app {
|
||||
UIContext* UIContext::m_instance = nullptr;
|
||||
|
||||
UIContext::UIContext()
|
||||
: m_lastSelectedView(nullptr)
|
||||
, m_closedDocs(preferences())
|
||||
: m_closedDocs(preferences())
|
||||
{
|
||||
ASSERT(m_instance == nullptr);
|
||||
m_instance = this;
|
||||
@ -67,6 +66,10 @@ DocView* UIContext::activeView() const
|
||||
if (!isUIAvailable())
|
||||
return nullptr;
|
||||
|
||||
// Bypass the active workspace view.
|
||||
if (m_targetView)
|
||||
return m_targetView;
|
||||
|
||||
Workspace* workspace = App::instance()->workspace();
|
||||
if (!workspace)
|
||||
return nullptr;
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2019-2021 Igara Studio S.A.
|
||||
// Copyright (C) 2019-2023 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
@ -49,6 +49,23 @@ namespace app {
|
||||
void reopenLastClosedDoc();
|
||||
std::vector<Doc*> getAndRemoveAllClosedDocs();
|
||||
|
||||
// Sets the DocView used to run some specific commands
|
||||
// (e.g. commands that depend on the current view or the preview
|
||||
// view).
|
||||
class SetTargetView {
|
||||
DocView* m_old;
|
||||
public:
|
||||
SetTargetView(DocView* newView) {
|
||||
auto ctx = UIContext::instance();
|
||||
m_old = ctx->m_targetView;
|
||||
ctx->m_targetView = newView;
|
||||
}
|
||||
~SetTargetView() {
|
||||
auto ctx = UIContext::instance();
|
||||
ctx->m_targetView = m_old;
|
||||
}
|
||||
};
|
||||
|
||||
protected:
|
||||
void onAddDocument(Doc* doc) override;
|
||||
void onRemoveDocument(Doc* doc) override;
|
||||
@ -62,7 +79,13 @@ namespace app {
|
||||
void onCloseDocument(Doc* doc) override;
|
||||
|
||||
private:
|
||||
DocView* m_lastSelectedView;
|
||||
DocView* m_lastSelectedView = nullptr;
|
||||
|
||||
// Temporary DocView used to change activeView() behavior, used in
|
||||
// some specific commands that depends on the current DocView (or
|
||||
// the preview DocView).
|
||||
DocView* m_targetView = nullptr;
|
||||
|
||||
ClosedDocs m_closedDocs;
|
||||
|
||||
static UIContext* m_instance;
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite UI Library
|
||||
// Copyright (C) 2018-2022 Igara Studio S.A.
|
||||
// Copyright (C) 2018-2023 Igara Studio S.A.
|
||||
// Copyright (C) 2001-2018 David Capello
|
||||
//
|
||||
// This file is released under the terms of the MIT license.
|
||||
@ -11,6 +11,7 @@
|
||||
|
||||
#include "ui/menu.h"
|
||||
|
||||
#include "base/scoped_value.h"
|
||||
#include "gfx/size.h"
|
||||
#include "os/font.h"
|
||||
#include "ui/display.h"
|
||||
@ -344,6 +345,11 @@ bool MenuItem::hasSubmenu() const
|
||||
void Menu::showPopup(const gfx::Point& pos,
|
||||
Display* parentDisplay)
|
||||
{
|
||||
// Set the owner menu item to nullptr temporarily in case that we
|
||||
// are re-using a menu from the root menu as popup menu (e.g. like
|
||||
// "animation_menu", that is used when right-cliking a Play button)
|
||||
base::ScopedValue<MenuItem*> restoreOwner(m_menuitem, nullptr, m_menuitem);
|
||||
|
||||
// Generally, when we call showPopup() the menu shouldn't contain a
|
||||
// parent menu-box, because we're filtering kMouseDownMessage to
|
||||
// close the popup automatically when we click outside the menubox.
|
||||
@ -1169,7 +1175,11 @@ void Menu::highlightItem(MenuItem* menuitem, bool click, bool open_submenu, bool
|
||||
menuitem->invalidate();
|
||||
|
||||
// Scroll
|
||||
View* view = View::getView(menuitem->parent()->parent());
|
||||
View* view = nullptr;
|
||||
if (menuitem->parent() &&
|
||||
menuitem->parent()->parent()) {
|
||||
view = View::getView(menuitem->parent()->parent());
|
||||
}
|
||||
if (view) {
|
||||
gfx::Rect itemBounds = menuitem->bounds();
|
||||
itemBounds.y -= menuitem->parent()->origin().y;
|
||||
|
Loading…
Reference in New Issue
Block a user