mirror of
https://github.com/aseprite/aseprite.git
synced 2025-02-06 12:39:57 +00:00
Move animation controls from StatusBar to Timeline
This commit is contained in:
parent
fbb660da8d
commit
0576bafaa3
@ -285,6 +285,7 @@ add_library(app-lib
|
||||
tools/tool_box.cpp
|
||||
tools/tool_loop_manager.cpp
|
||||
transaction.cpp
|
||||
ui/ani_controls.cpp
|
||||
ui/app_menuitem.cpp
|
||||
ui/button_set.cpp
|
||||
ui/color_bar.cpp
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include "app/context_access.h"
|
||||
#include "app/modules/editors.h"
|
||||
#include "app/ui/editor/editor.h"
|
||||
#include "app/ui/status_bar.h"
|
||||
|
||||
namespace app {
|
||||
|
||||
@ -61,9 +60,6 @@ void PlayAnimationCommand::onExecute(Context* context)
|
||||
current_editor->stop();
|
||||
else
|
||||
current_editor->play();
|
||||
|
||||
// TODO this is an ugly hack, StatusBar should observe Editor changes
|
||||
StatusBar::instance()->updateUsingEditor(current_editor);
|
||||
}
|
||||
|
||||
Command* CommandFactory::createPlayAnimationCommand()
|
||||
|
108
src/app/ui/ani_controls.cpp
Normal file
108
src/app/ui/ani_controls.cpp
Normal file
@ -0,0 +1,108 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
// published by the Free Software Foundation.
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "app/app.h"
|
||||
#include "app/commands/commands.h"
|
||||
#include "app/commands/params.h"
|
||||
#include "app/context_access.h"
|
||||
#include "app/document_access.h"
|
||||
#include "app/document_range.h"
|
||||
#include "app/modules/editors.h"
|
||||
#include "app/modules/gfx.h"
|
||||
#include "app/modules/gui.h"
|
||||
#include "app/modules/palettes.h"
|
||||
#include "app/settings/settings.h"
|
||||
#include "app/tools/tool.h"
|
||||
#include "app/ui/button_set.h"
|
||||
#include "app/ui/color_button.h"
|
||||
#include "app/ui/editor/editor.h"
|
||||
#include "app/ui/keyboard_shortcuts.h"
|
||||
#include "app/ui/main_window.h"
|
||||
#include "app/ui/skin/skin_theme.h"
|
||||
#include "app/ui/status_bar.h"
|
||||
#include "app/ui/timeline.h"
|
||||
#include "app/ui_context.h"
|
||||
#include "app/util/range_utils.h"
|
||||
#include "base/bind.h"
|
||||
#include "doc/cel.h"
|
||||
#include "doc/image.h"
|
||||
#include "doc/layer.h"
|
||||
#include "doc/sprite.h"
|
||||
#include "gfx/size.h"
|
||||
#include "she/font.h"
|
||||
#include "she/surface.h"
|
||||
#include "ui/ui.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdarg>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
namespace app {
|
||||
|
||||
using namespace app::skin;
|
||||
using namespace gfx;
|
||||
using namespace ui;
|
||||
using namespace doc;
|
||||
|
||||
enum AniAction {
|
||||
ACTION_FIRST,
|
||||
ACTION_PREV,
|
||||
ACTION_PLAY,
|
||||
ACTION_NEXT,
|
||||
ACTION_LAST,
|
||||
};
|
||||
|
||||
AniControls::AniControls()
|
||||
: ButtonSet(5)
|
||||
{
|
||||
SkinTheme* theme = static_cast<SkinTheme*>(this->getTheme());
|
||||
|
||||
addItem(theme->get_part(PART_ANI_FIRST));
|
||||
addItem(theme->get_part(PART_ANI_PREVIOUS));
|
||||
addItem(theme->get_part(PART_ANI_PLAY));
|
||||
addItem(theme->get_part(PART_ANI_NEXT));
|
||||
addItem(theme->get_part(PART_ANI_LAST));
|
||||
ItemChange.connect(Bind(&AniControls::onPlayButton, this));
|
||||
|
||||
setTriggerOnMouseUp(true);
|
||||
setTransparent(true);
|
||||
setBgColor(theme->colors.workspace());
|
||||
}
|
||||
|
||||
void AniControls::updateUsingEditor(Editor* editor)
|
||||
{
|
||||
SkinTheme* theme = static_cast<SkinTheme*>(this->getTheme());
|
||||
getItem(ACTION_PLAY)->setIcon(
|
||||
theme->get_part(
|
||||
(editor && editor->isPlaying()) ? PART_ANI_STOP: PART_ANI_PLAY));
|
||||
}
|
||||
|
||||
void AniControls::onPlayButton()
|
||||
{
|
||||
int item = selectedItem();
|
||||
deselectItems();
|
||||
|
||||
Command* cmd = nullptr;
|
||||
switch (item) {
|
||||
case ACTION_FIRST: cmd = CommandsModule::instance()->getCommandByName(CommandId::GotoFirstFrame); break;
|
||||
case ACTION_PREV: cmd = CommandsModule::instance()->getCommandByName(CommandId::GotoPreviousFrame); break;
|
||||
case ACTION_PLAY: cmd = CommandsModule::instance()->getCommandByName(CommandId::PlayAnimation); break;
|
||||
case ACTION_NEXT: cmd = CommandsModule::instance()->getCommandByName(CommandId::GotoNextFrame); break;
|
||||
case ACTION_LAST: cmd = CommandsModule::instance()->getCommandByName(CommandId::GotoLastFrame); break;
|
||||
}
|
||||
if (cmd) {
|
||||
UIContext::instance()->executeCommand(cmd);
|
||||
updateUsingEditor(current_editor);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace app
|
33
src/app/ui/ani_controls.h
Normal file
33
src/app/ui/ani_controls.h
Normal file
@ -0,0 +1,33 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
// published by the Free Software Foundation.
|
||||
|
||||
#ifndef APP_UI_ANI_CONTROLS_H_INCLUDED
|
||||
#define APP_UI_ANI_CONTROLS_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "app/ui/button_set.h"
|
||||
#include "ui/widget.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace app {
|
||||
class Editor;
|
||||
|
||||
class AniControls : public ButtonSet {
|
||||
public:
|
||||
AniControls();
|
||||
|
||||
void updateUsingEditor(Editor* editor);
|
||||
|
||||
private:
|
||||
void onPlayButton();
|
||||
};
|
||||
|
||||
} // namespace app
|
||||
|
||||
#endif
|
@ -53,14 +53,6 @@ using namespace gfx;
|
||||
using namespace ui;
|
||||
using namespace doc;
|
||||
|
||||
enum AniAction {
|
||||
ACTION_FIRST,
|
||||
ACTION_PREV,
|
||||
ACTION_PLAY,
|
||||
ACTION_NEXT,
|
||||
ACTION_LAST,
|
||||
};
|
||||
|
||||
static const char* kStatusBarText = "status_bar_text";
|
||||
static const char* kStatusBarFace = "status_bar_face";
|
||||
|
||||
@ -175,18 +167,9 @@ StatusBar::StatusBar()
|
||||
m_newFrame = new Button("+");
|
||||
m_newFrame->Click.connect(Bind<void>(&StatusBar::newFrame, this));
|
||||
|
||||
setup_mini_look(m_slider);
|
||||
setup_mini_look(m_currentFrame);
|
||||
setup_mini_look(m_newFrame);
|
||||
|
||||
m_buttonSet = new ButtonSet(5);
|
||||
m_buttonSet->setTriggerOnMouseUp(true);
|
||||
m_buttonSet->addItem(theme->get_part(PART_ANI_FIRST));
|
||||
m_buttonSet->addItem(theme->get_part(PART_ANI_PREVIOUS));
|
||||
m_buttonSet->addItem(theme->get_part(PART_ANI_PLAY));
|
||||
m_buttonSet->addItem(theme->get_part(PART_ANI_NEXT));
|
||||
m_buttonSet->addItem(theme->get_part(PART_ANI_LAST));
|
||||
m_buttonSet->ItemChange.connect(Bind(&StatusBar::onPlayButton, this));
|
||||
setup_mini_look(m_slider);
|
||||
|
||||
m_slider->Change.connect(Bind<void>(&slider_change_hook, m_slider));
|
||||
m_slider->setMinSize(gfx::Size(ui::display_w()/5, 0));
|
||||
@ -197,7 +180,6 @@ StatusBar::StatusBar()
|
||||
box4->addChild(m_newFrame);
|
||||
|
||||
box1->addChild(box4);
|
||||
box1->addChild(m_buttonSet);
|
||||
box1->addChild(m_slider);
|
||||
|
||||
m_commandsBox = box1;
|
||||
@ -382,9 +364,16 @@ void StatusBar::onResize(ResizeEvent& ev)
|
||||
{
|
||||
setBoundsQuietly(ev.getBounds());
|
||||
|
||||
Border border = getBorder();
|
||||
Rect rc = ev.getBounds();
|
||||
rc.x += rc.w/2;
|
||||
rc.w /= 2;
|
||||
int w = rc.w/2 - border.getSize().w;
|
||||
rc.x += w + border.left();
|
||||
rc.w = w;
|
||||
|
||||
m_currentFrame->setVisible(w > 250*ui::guiscale());
|
||||
m_newFrame->setVisible(w > 250*ui::guiscale());
|
||||
m_slider->setVisible(w > 200*ui::guiscale());
|
||||
|
||||
m_commandsBox->setBounds(rc);
|
||||
}
|
||||
|
||||
@ -476,7 +465,6 @@ void StatusBar::updateUsingEditor(Editor* editor)
|
||||
{
|
||||
updateFromDocument(editor);
|
||||
updateCurrentFrame(editor);
|
||||
updatePlayButton(editor);
|
||||
}
|
||||
|
||||
bool StatusBar::CustomizedTipWindow::onProcessMessage(Message* msg)
|
||||
@ -517,25 +505,6 @@ static void slider_change_hook(Slider* slider)
|
||||
}
|
||||
}
|
||||
|
||||
void StatusBar::onPlayButton()
|
||||
{
|
||||
int item = m_buttonSet->selectedItem();
|
||||
m_buttonSet->deselectItems();
|
||||
|
||||
Command* cmd = nullptr;
|
||||
switch (item) {
|
||||
case ACTION_FIRST: cmd = CommandsModule::instance()->getCommandByName(CommandId::GotoFirstFrame); break;
|
||||
case ACTION_PREV: cmd = CommandsModule::instance()->getCommandByName(CommandId::GotoPreviousFrame); break;
|
||||
case ACTION_PLAY: cmd = CommandsModule::instance()->getCommandByName(CommandId::PlayAnimation); break;
|
||||
case ACTION_NEXT: cmd = CommandsModule::instance()->getCommandByName(CommandId::GotoNextFrame); break;
|
||||
case ACTION_LAST: cmd = CommandsModule::instance()->getCommandByName(CommandId::GotoLastFrame); break;
|
||||
}
|
||||
if (cmd) {
|
||||
UIContext::instance()->executeCommand(cmd);
|
||||
updatePlayButton(current_editor);
|
||||
}
|
||||
}
|
||||
|
||||
void StatusBar::updateFromDocument(Editor* editor)
|
||||
{
|
||||
try {
|
||||
@ -574,14 +543,6 @@ void StatusBar::updateCurrentFrame(Editor* editor)
|
||||
m_currentFrame->setTextf("%d", editor->frame()+1);
|
||||
}
|
||||
|
||||
void StatusBar::updatePlayButton(Editor* editor)
|
||||
{
|
||||
SkinTheme* theme = static_cast<SkinTheme*>(this->getTheme());
|
||||
m_buttonSet->getItem(ACTION_PLAY)->setIcon(
|
||||
theme->get_part(
|
||||
(editor && editor->isPlaying()) ? PART_ANI_STOP: PART_ANI_PLAY));
|
||||
}
|
||||
|
||||
void StatusBar::newFrame()
|
||||
{
|
||||
Command* cmd = CommandsModule::instance()->getCommandByName(CommandId::NewFrame);
|
||||
|
@ -81,9 +81,7 @@ namespace app {
|
||||
void onCurrentToolChange();
|
||||
void updateFromDocument(Editor* editor);
|
||||
void updateCurrentFrame(Editor* editor);
|
||||
void updatePlayButton(Editor* editor);
|
||||
void newFrame();
|
||||
void onPlayButton();
|
||||
|
||||
enum State { SHOW_TEXT, SHOW_COLOR, SHOW_TOOL };
|
||||
|
||||
@ -107,7 +105,6 @@ namespace app {
|
||||
ui::Slider* m_slider; // Opacity slider
|
||||
ui::Entry* m_currentFrame; // Current frame and go to frame entry
|
||||
ui::Button* m_newFrame; // Button to create a new frame
|
||||
ButtonSet* m_buttonSet;
|
||||
|
||||
// Tip window
|
||||
class CustomizedTipWindow;
|
||||
|
@ -122,6 +122,7 @@ Timeline::Timeline()
|
||||
m_context->documents().addObserver(this);
|
||||
|
||||
setDoubleBuffered(true);
|
||||
addChild(&m_aniControls);
|
||||
}
|
||||
|
||||
Timeline::~Timeline()
|
||||
@ -135,6 +136,8 @@ Timeline::~Timeline()
|
||||
|
||||
void Timeline::updateUsingEditor(Editor* editor)
|
||||
{
|
||||
m_aniControls.updateUsingEditor(editor);
|
||||
|
||||
// As a sprite editor was selected, it looks like the user wants to
|
||||
// execute commands targetting the editor instead of the
|
||||
// timeline. Here we disable the selected range, so commands like
|
||||
@ -417,7 +420,7 @@ bool Timeline::onProcessMessage(Message* msg)
|
||||
// tracked to the mouse's released).
|
||||
if (m_clk.part == PART_SEPARATOR) {
|
||||
m_separator_x = MAX(0, mousePos.x);
|
||||
invalidate();
|
||||
layout();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -781,6 +784,18 @@ void Timeline::onPreferredSize(PreferredSizeEvent& ev)
|
||||
ev.setPreferredSize(Size(32, 32));
|
||||
}
|
||||
|
||||
void Timeline::onResize(ui::ResizeEvent& ev)
|
||||
{
|
||||
gfx::Rect rc = ev.getBounds();
|
||||
setBoundsQuietly(rc);
|
||||
|
||||
gfx::Size sz = m_aniControls.getPreferredSize();
|
||||
m_aniControls.setBounds(
|
||||
gfx::Rect(rc.x, rc.y, MIN(sz.w, m_separator_x),
|
||||
getFont()->height() +
|
||||
skinTheme()->dimensions.timelineTagsAreaHeight()));
|
||||
}
|
||||
|
||||
void Timeline::onPaint(ui::PaintEvent& ev)
|
||||
{
|
||||
Graphics* g = ev.getGraphics();
|
||||
@ -964,6 +979,11 @@ void Timeline::onSelectionChanged(doc::DocumentEvent& ev)
|
||||
invalidate();
|
||||
}
|
||||
|
||||
void Timeline::onStateChanged(Editor* editor)
|
||||
{
|
||||
m_aniControls.updateUsingEditor(editor);
|
||||
}
|
||||
|
||||
void Timeline::onAfterFrameChanged(Editor* editor)
|
||||
{
|
||||
setFrame(editor->frame());
|
||||
@ -1333,13 +1353,11 @@ void Timeline::drawFrameTags(ui::Graphics* g)
|
||||
SkinTheme* theme = skinTheme();
|
||||
SkinTheme::Styles& styles = theme->styles;
|
||||
|
||||
if (!m_sprite->frameTags().empty()) {
|
||||
g->fillRect(theme->colors.workspace(),
|
||||
gfx::Rect(
|
||||
0, getFont()->height(),
|
||||
getClientBounds().w,
|
||||
theme->dimensions.timelineTagsAreaHeight()));
|
||||
}
|
||||
g->fillRect(theme->colors.workspace(),
|
||||
gfx::Rect(
|
||||
0, getFont()->height(),
|
||||
getClientBounds().w,
|
||||
theme->dimensions.timelineTagsAreaHeight()));
|
||||
|
||||
for (FrameTag* frameTag : m_sprite->frameTags()) {
|
||||
gfx::Rect bounds1 = getPartBounds(Hit(PART_HEADER_FRAME, firstLayer(), frameTag->fromFrame()));
|
||||
@ -2303,10 +2321,8 @@ int Timeline::topHeight() const
|
||||
int h = 0;
|
||||
if (m_document && m_sprite) {
|
||||
h += skinTheme()->dimensions.timelineTopBorder();
|
||||
if (!m_sprite->frameTags().empty()) {
|
||||
h += getFont()->height();
|
||||
h += skinTheme()->dimensions.timelineTagsAreaHeight();
|
||||
}
|
||||
h += getFont()->height();
|
||||
h += skinTheme()->dimensions.timelineTagsAreaHeight();
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include "app/document_range.h"
|
||||
#include "app/pref/preferences.h"
|
||||
#include "app/ui/ani_controls.h"
|
||||
#include "app/ui/editor/editor_observer.h"
|
||||
#include "base/connection.h"
|
||||
#include "doc/document_observer.h"
|
||||
@ -96,6 +97,7 @@ namespace app {
|
||||
protected:
|
||||
bool onProcessMessage(ui::Message* msg) override;
|
||||
void onPreferredSize(ui::PreferredSizeEvent& ev) override;
|
||||
void onResize(ui::ResizeEvent& ev) override;
|
||||
void onPaint(ui::PaintEvent& ev) override;
|
||||
|
||||
// DocumentObserver impl.
|
||||
@ -112,6 +114,7 @@ namespace app {
|
||||
void onRemoveDocument(doc::Document* document) override;
|
||||
|
||||
// EditorObserver impl.
|
||||
void onStateChanged(Editor* editor) override;
|
||||
void onAfterFrameChanged(Editor* editor) override;
|
||||
void onAfterLayerChanged(Editor* editor) override;
|
||||
void onDestroyEditor(Editor* editor) override;
|
||||
@ -253,6 +256,8 @@ namespace app {
|
||||
|
||||
bool m_scroll; // True if the drag-and-drop operation is a scroll operation.
|
||||
bool m_copy; // True if the drag-and-drop operation is a copy.
|
||||
|
||||
AniControls m_aniControls;
|
||||
};
|
||||
|
||||
} // namespace app
|
||||
|
Loading…
x
Reference in New Issue
Block a user