Add the old "Animation Editor" as a timeline at the bottom of sprite editors (Workspace)

- Renamed AnimationEditor (dialogs/aniedit.h) to Timeline
  class (app/ui/timeline.h)
- Renamed FilmEditor command to Timeline
This commit is contained in:
David Capello 2013-11-10 18:27:11 -03:00
parent e6450877bb
commit b0cd01b425
15 changed files with 372 additions and 294 deletions

View File

@ -31,8 +31,6 @@
* Add "Remap" button to palette editor after a palette entry is modified:
This button should apply a color curve to the whole sprite to remap
old indexes to the new positions.
* Move src/app/dialogs/aniedit,filesel to src/app/ui
(remove app/dialogs/ directory).
* Merge everything related to configuration/settings in one class
(allow configuration per document). Use cfg.cpp and settings/ dir.
* Refactor src/file/ in several layers.

View File

@ -74,7 +74,9 @@
<key command="Preview" shortcut="F8" />
<key command="ShowGrid" shortcut="Shift+G" />
<key command="SnapToGrid" shortcut="Shift+S" />
<key command="FilmEditor" shortcut="Tab" />
<key command="Timeline" shortcut="Tab">
<param name="switch" value="true" />
</key>
<key command="PaletteEditor" shortcut="F4">
<param name="switch" value="true" />
</key>
@ -362,7 +364,9 @@
<item command="SnapToGrid" text="&amp;Snap to Grid" />
<item command="GridSettings" text="Gri&amp;d Settings" />
<separator />
<item command="FilmEditor" text="&amp;Animation Editor" />
<item command="Timeline" text="&amp;Timeline">
<param name="switch" value="true" />
</item>
<item command="PaletteEditor" text="&amp;Palette Editor">
<param name="switch" value="true" />
</item>

View File

@ -11,7 +11,12 @@
<box noborders="true" vertical="true" id="colorbar" />
<vbox noborders="true" expansive="true">
<vbox noborders="true" id="contextbar" />
<hbox noborders="true" id="workspace" expansive="true" />
<splitter id="timelinesplitter"
veritical="true" expansive="true"
by="percetage" position="75">
<hbox noborders="true" id="workspace" expansive="true" />
<vbox noborders="true" id="timeline" expansive="true" />
</splitter>
</vbox>
</splitter>
<box noborders="true" vertical="true" id="toolbar" />

View File

@ -33,7 +33,6 @@ add_library(app-library
commands/cmd_exit.cpp
commands/cmd_export_sprite_sheet.cpp
commands/cmd_eyedropper.cpp
commands/cmd_film_editor.cpp
commands/cmd_flatten_layers.cpp
commands/cmd_flip.cpp
commands/cmd_frame_properties.cpp
@ -76,6 +75,7 @@ add_library(app-library
commands/cmd_sprite_properties.cpp
commands/cmd_sprite_size.cpp
commands/cmd_switch_colors.cpp
commands/cmd_timeline.cpp
commands/cmd_undo.cpp
commands/command.cpp
commands/commands.cpp
@ -96,7 +96,6 @@ add_library(app-library
context_flags.cpp
context_observer_list.cpp
data_recovery.cpp
dialogs/aniedit.cpp
dialogs/maskcol.cpp
document.cpp
document_api.cpp
@ -181,6 +180,7 @@ add_library(app-library
ui/skin/skin_theme.cpp
ui/status_bar.cpp
ui/tabs.cpp
ui/timeline.cpp
ui/toolbar.cpp
ui/workspace.cpp
ui/workspace_part.cpp

View File

@ -20,9 +20,11 @@
#include "config.h"
#endif
#include "app/app.h"
#include "app/commands/command.h"
#include "app/context_access.h"
#include "app/dialogs/aniedit.h"
#include "app/ui/timeline.h"
#include "app/ui/main_window.h"
#include "app/util/celmove.h"
#include "ui/base.h"
@ -47,7 +49,7 @@ CopyCelCommand::CopyCelCommand()
bool CopyCelCommand::onEnabled(Context* context)
{
return animation_editor_is_movingcel();
return App::instance()->getMainWindow()->getTimeline()->isMovingCel();
}
void CopyCelCommand::onExecute(Context* context)

View File

@ -1,63 +0,0 @@
/* Aseprite
* Copyright (C) 2001-2013 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 "ui/ui.h"
#include "app/commands/command.h"
#include "app/context.h"
#include "app/dialogs/aniedit.h"
namespace app {
class FilmEditorCommand : public Command {
public:
FilmEditorCommand();
Command* clone() { return new FilmEditorCommand(*this); }
protected:
bool onEnabled(Context* context);
void onExecute(Context* context);
};
FilmEditorCommand::FilmEditorCommand()
: Command("FilmEditor",
"Animation Editor",
CmdUIOnlyFlag)
{
}
bool FilmEditorCommand::onEnabled(Context* context)
{
return context->checkFlags(ContextFlags::ActiveDocumentIsWritable);
}
void FilmEditorCommand::onExecute(Context* context)
{
switch_between_animation_and_sprite_editor(context);
}
Command* CommandFactory::createFilmEditorCommand()
{
return new FilmEditorCommand;
}
} // namespace app

View File

@ -20,9 +20,11 @@
#include "config.h"
#endif
#include "app/app.h"
#include "app/commands/command.h"
#include "app/context_access.h"
#include "app/dialogs/aniedit.h"
#include "app/ui/main_window.h"
#include "app/ui/timeline.h"
#include "app/util/celmove.h"
#include "ui/base.h"
@ -47,7 +49,7 @@ MoveCelCommand::MoveCelCommand()
bool MoveCelCommand::onEnabled(Context* context)
{
return animation_editor_is_movingcel();
return App::instance()->getMainWindow()->getTimeline()->isMovingCel();
}
void MoveCelCommand::onExecute(Context* context)

View File

@ -0,0 +1,94 @@
/* Aseprite
* Copyright (C) 2001-2013 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 "ui/ui.h"
#include "app/app.h"
#include "app/commands/command.h"
#include "app/commands/params.h"
#include "app/context.h"
#include "app/ui/main_window.h"
#include "app/ui/timeline.h"
namespace app {
class TimelineCommand : public Command {
public:
TimelineCommand();
Command* clone() { return new TimelineCommand(*this); }
protected:
void onLoadParams(Params* params) OVERRIDE;
void onExecute(Context* context) OVERRIDE;
bool m_open;
bool m_close;
bool m_switch;
};
TimelineCommand::TimelineCommand()
: Command("Timeline",
"Switch Timeline",
CmdUIOnlyFlag)
{
m_open = true;
m_close = false;
m_switch = false;
}
void TimelineCommand::onLoadParams(Params* params)
{
std::string open_str = params->get("open");
if (open_str == "true") m_open = true;
else m_open = false;
std::string close_str = params->get("close");
if (close_str == "true") m_close = true;
else m_close = false;
std::string switch_str = params->get("switch");
if (switch_str == "true") m_switch = true;
else m_switch = false;
}
void TimelineCommand::onExecute(Context* context)
{
bool visible = App::instance()->getMainWindow()->getTimelineVisibility();
bool newVisible = visible;
if (m_switch)
newVisible = !visible;
else if (m_close)
newVisible = false;
else if (m_open)
newVisible = true;
if (visible != newVisible)
App::instance()->getMainWindow()->setTimelineVisibility(newVisible);
}
Command* CommandFactory::createTimelineCommand()
{
return new TimelineCommand;
}
} // namespace app

View File

@ -44,7 +44,6 @@ FOR_EACH_COMMAND(DuplicateSprite)
FOR_EACH_COMMAND(Exit)
FOR_EACH_COMMAND(ExportSpriteSheet)
FOR_EACH_COMMAND(Eyedropper)
FOR_EACH_COMMAND(FilmEditor)
FOR_EACH_COMMAND(FlattenLayers)
FOR_EACH_COMMAND(Flip)
FOR_EACH_COMMAND(FrameProperties)
@ -53,9 +52,9 @@ FOR_EACH_COMMAND(GotoFrame)
FOR_EACH_COMMAND(GotoLastFrame)
FOR_EACH_COMMAND(GotoNextFrame)
FOR_EACH_COMMAND(GotoNextLayer)
FOR_EACH_COMMAND(GotoNextTab)
FOR_EACH_COMMAND(GotoPreviousFrame)
FOR_EACH_COMMAND(GotoPreviousLayer)
FOR_EACH_COMMAND(GotoNextTab)
FOR_EACH_COMMAND(GotoPreviousTab)
FOR_EACH_COMMAND(GridSettings)
FOR_EACH_COMMAND(ImportSpriteSheet)
@ -102,4 +101,5 @@ FOR_EACH_COMMAND(SplitEditorVertically)
FOR_EACH_COMMAND(SpriteProperties)
FOR_EACH_COMMAND(SpriteSize)
FOR_EACH_COMMAND(SwitchColors)
FOR_EACH_COMMAND(Timeline)
FOR_EACH_COMMAND(Undo)

View File

@ -1,31 +0,0 @@
/* Aseprite
* Copyright (C) 2001-2013 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_DIALOGS_ANIEDIT_H_INCLUDED
#define APP_DIALOGS_ANIEDIT_H_INCLUDED
namespace app {
class Context;
bool animation_editor_is_movingcel();
void switch_between_animation_and_sprite_editor(Context* context);
} // namespace app
#endif

View File

@ -24,7 +24,9 @@
#include "app/app.h"
#include "app/app_menus.h"
#include "app/commands/commands.h"
#include "app/load_widget.h"
#include "app/modules/editors.h"
#include "app/ui/color_bar.h"
#include "app/ui/context_bar.h"
#include "app/ui/document_view.h"
@ -34,14 +36,13 @@
#include "app/ui/mini_editor.h"
#include "app/ui/status_bar.h"
#include "app/ui/tabs.h"
#include "app/ui/timeline.h"
#include "app/ui/toolbar.h"
#include "app/ui/workspace.h"
#include "app/commands/commands.h"
#include "app/modules/editors.h"
#include "app/ui_context.h"
#include "ui/splitter.h"
#include "ui/system.h"
#include "ui/view.h"
#include "app/ui_context.h"
namespace app {
@ -50,6 +51,7 @@ using namespace ui;
MainWindow::MainWindow()
: Window(true, "")
, m_lastSplitterPos(0.0)
, m_lastTimelineSplitterPos(75.0)
, m_advancedMode(false)
{
setId("main_window");
@ -67,6 +69,7 @@ MainWindow::MainWindow()
Widget* box_statusbar = findChild("statusbar");
Widget* box_tabsbar = findChild("tabsbar");
Widget* box_workspace = findChild("workspace");
Widget* box_timeline = findChild("timeline");
m_menuBar = new MainMenuBar();
m_contextBar = new ContextBar();
@ -77,7 +80,11 @@ MainWindow::MainWindow()
m_workspace = new Workspace();
m_workspace->ActiveViewChanged.connect(&MainWindow::onActiveViewChange, this);
m_miniEditor = new MiniEditorWindow();
m_timeline = new Timeline();
m_colorBarSplitter = findChildT<Splitter>("colorbarsplitter");
m_timelineSplitter = findChildT<Splitter>("timelinesplitter");
m_lastTimelineSplitterPos = m_timelineSplitter->getPosition();
// configure all widgets to expansives
m_menuBar->setExpansive(true);
@ -86,6 +93,7 @@ MainWindow::MainWindow()
m_colorBar->setExpansive(true);
m_toolBar->setExpansive(true);
m_tabsBar->setExpansive(true);
m_timeline->setExpansive(true);
m_workspace->setExpansive(true);
// Setup the menus
@ -99,6 +107,7 @@ MainWindow::MainWindow()
if (box_statusbar) box_statusbar->addChild(m_statusBar);
if (box_tabsbar) box_tabsbar->addChild(m_tabsBar);
if (box_workspace) box_workspace->addChild(m_workspace);
if (box_timeline) box_timeline->addChild(m_timeline);
// Prepare the window
remapWindow();
@ -153,6 +162,29 @@ void MainWindow::setAdvancedMode(bool advanced)
layout();
}
bool MainWindow::getTimelineVisibility() const
{
return m_timeline->isVisible();
}
void MainWindow::setTimelineVisibility(bool visible)
{
m_timeline->setVisible(visible);
if (visible) {
if (m_timelineSplitter->getPosition() >= 100.0)
m_timelineSplitter->setPosition(m_lastTimelineSplitterPos);
}
else {
if (m_timelineSplitter->getPosition() < 100.0) {
m_lastTimelineSplitterPos = m_timelineSplitter->getPosition();
m_timelineSplitter->setPosition(100.0);
}
}
layout();
}
void MainWindow::onSaveLayout(SaveLayoutEvent& ev)
{
Window::onSaveLayout(ev);

View File

@ -27,12 +27,14 @@ namespace ui {
}
namespace app {
class ColorBar;
class ContextBar;
class MainMenuBar;
class MiniEditorWindow;
class StatusBar;
class Tabs;
class Timeline;
class Workspace;
class MainWindow : public ui::Window
@ -44,6 +46,7 @@ namespace app {
MainMenuBar* getMenuBar() { return m_menuBar; }
ContextBar* getContextBar() { return m_contextBar; }
Tabs* getTabsBar() { return m_tabsBar; }
Timeline* getTimeline() { return m_timeline; }
Workspace* getWorkspace() { return m_workspace; }
MiniEditorWindow* getMiniEditor() { return m_miniEditor; }
@ -52,6 +55,9 @@ namespace app {
bool isAdvancedMode() const { return m_advancedMode; }
void setAdvancedMode(bool advanced);
bool getTimelineVisibility() const;
void setTimelineVisibility(bool visible);
// TabsDelegate implementation.
void clickTab(Tabs* tabs, TabView* tabView, ui::MouseButtons buttons);
void mouseOverTab(Tabs* tabs, TabView* tabView);
@ -66,10 +72,13 @@ namespace app {
StatusBar* m_statusBar;
ColorBar* m_colorBar;
ui::Splitter* m_colorBarSplitter;
ui::Splitter* m_timelineSplitter;
ui::Widget* m_toolBar;
Tabs* m_tabsBar;
double m_lastSplitterPos;
double m_lastTimelineSplitterPos;
bool m_advancedMode;
Timeline* m_timeline;
Workspace* m_workspace;
MiniEditorWindow* m_miniEditor;
};

View File

@ -20,6 +20,8 @@
#include "config.h"
#endif
#include "app/ui/timeline.h"
#include "app/app_menus.h"
#include "app/commands/command.h"
#include "app/commands/commands.h"
@ -29,11 +31,11 @@
#include "app/document.h"
#include "app/document_api.h"
#include "app/document_event.h"
#include "app/document_observer.h"
#include "app/document_undo.h"
#include "app/modules/editors.h"
#include "app/modules/gfx.h"
#include "app/modules/gui.h"
#include "app/ui/document_view.h"
#include "app/ui/editor/editor.h"
#include "app/ui/skin/skin_theme.h"
#include "app/ui_context.h"
@ -51,7 +53,7 @@
#include <vector>
/*
Animator Editor
Timeline
Frames ...
@ -105,146 +107,30 @@ enum {
A_PART_CEL
};
class AnimationEditor : public Widget
, public DocumentObserver {
public:
enum State {
STATE_STANDBY,
STATE_SCROLLING,
STATE_MOVING_SEPARATOR,
STATE_MOVING_LAYER,
STATE_MOVING_CEL,
STATE_MOVING_FRAME,
};
AnimationEditor(Context* context);
~AnimationEditor();
Sprite* getSprite() { return m_sprite; }
Layer* getLayer() { return m_layer; }
FrameNumber getFrame() { return m_frame; }
void setLayer(Layer* layer) {
m_layer = layer;
if (current_editor)
current_editor->setLayer(m_layer);
}
void setFrame(FrameNumber frame) {
m_frame = frame;
if (current_editor)
current_editor->setFrame(m_frame);
}
void centerCurrentCel();
State getState() const { return m_state; }
protected:
bool onProcessMessage(Message* msg) OVERRIDE;
void onPreferredSize(PreferredSizeEvent& ev) OVERRIDE;
// DocumentObserver impl.
void onAddLayer(DocumentEvent& ev) OVERRIDE;
void onRemoveLayer(DocumentEvent& ev) OVERRIDE;
void onAddFrame(DocumentEvent& ev) OVERRIDE;
void onRemoveFrame(DocumentEvent& ev) OVERRIDE;
void onTotalFramesChanged(DocumentEvent& ev) OVERRIDE;
private:
void setCursor(int x, int y);
void getDrawableLayers(const gfx::Rect& clip, int* first_layer, int* last_layer);
void getDrawableFrames(const gfx::Rect& clip, FrameNumber* first_frame, FrameNumber* last_frame);
void drawHeader(const gfx::Rect& clip);
void drawHeaderFrame(const gfx::Rect& clip, FrameNumber frame);
void drawHeaderPart(const gfx::Rect& clip, int x1, int y1, int x2, int y2,
bool is_hot, bool is_clk,
const char* line1, int align1,
const char* line2, int align2);
void drawSeparator(const gfx::Rect& clip);
void drawLayer(const gfx::Rect& clip, int layer_index);
void drawLayerPadding();
void drawCel(const gfx::Rect& clip, int layer_index, FrameNumber frame, Cel* cel);
bool drawPart(int part, int layer, FrameNumber frame);
void regenerateLayers();
void hotThis(int hot_part, int hot_layer, FrameNumber hotFrame);
void centerCel(int layer, FrameNumber frame);
void showCel(int layer, FrameNumber frame);
void showCurrentCel();
void cleanClk();
void setScroll(int x, int y, bool use_refresh_region);
int getLayerIndex(const Layer* layer);
Context* m_context;
Document* m_document;
Sprite* m_sprite;
Layer* m_layer;
FrameNumber m_frame;
State m_state;
std::vector<Layer*> m_layers;
int m_scroll_x;
int m_scroll_y;
int m_separator_x;
int m_separator_w;
// The 'hot' part is where the mouse is on top of
int m_hot_part;
int m_hot_layer;
FrameNumber m_hot_frame;
// The 'clk' part is where the mouse's button was pressed (maybe for a drag & drop operation)
int m_clk_part;
int m_clk_layer;
FrameNumber m_clk_frame;
// Keys
bool m_space_pressed;
};
static AnimationEditor* current_anieditor = NULL;
static void icon_rect(BITMAP* icon_normal, BITMAP* icon_selected, int x1, int y1, int x2, int y2,
bool is_selected, bool is_hot, bool is_clk);
bool animation_editor_is_movingcel()
{
return
current_anieditor != NULL &&
current_anieditor->getState() == AnimationEditor::STATE_MOVING_CEL;
}
// Shows the animation editor for the current sprite.
void switch_between_animation_and_sprite_editor(Context* context)
{
const Document* document;
const Sprite* sprite;
{
const ContextReader reader(context);
document = reader.document();
sprite = reader.sprite();
}
// Create the window & the animation-editor
{
base::UniquePtr<Window> window(new Window(true, ""));
AnimationEditor anieditor(context);
window->addChild(&anieditor);
window->remapWindow();
anieditor.centerCurrentCel();
// Show the window
window->openWindowInForeground();
}
// Destroy thumbnails
destroy_thumbnails();
}
//////////////////////////////////////////////////////////////////////
// The Animation Editor
AnimationEditor::AnimationEditor(Context* context)
Timeline::Timeline()
: Widget(kGenericWidget)
, m_context(context)
, m_context(UIContext::instance())
, m_document(NULL)
{
DocumentLocation location = context->getActiveLocation();
}
Timeline::~Timeline()
{
if (m_document)
m_document->removeObserver(this);
}
void Timeline::updateUsingEditor(Editor* editor)
{
if (m_document)
m_document->removeObserver(this);
DocumentView* view = editor->getDocumentView();
DocumentLocation location;
view->getDocumentLocation(&location);
m_document = location.document();
m_sprite = location.sprite();
@ -259,22 +145,36 @@ AnimationEditor::AnimationEditor(Context* context)
m_clk_part = A_PART_NOTHING;
m_space_pressed = false;
this->setFocusStop(true);
setFocusStop(true);
regenerateLayers();
current_anieditor = this;
m_document->addObserver(this);
}
AnimationEditor::~AnimationEditor()
bool Timeline::isMovingCel() const
{
current_anieditor = NULL;
m_document->removeObserver(this);
return (m_state == Timeline::STATE_MOVING_CEL);
}
bool AnimationEditor::onProcessMessage(Message* msg)
void Timeline::setLayer(Layer* layer)
{
m_layer = layer;
if (current_editor)
current_editor->setLayer(m_layer);
}
void Timeline::setFrame(FrameNumber frame)
{
m_frame = frame;
if (current_editor)
current_editor->setFrame(m_frame);
}
bool Timeline::onProcessMessage(Message* msg)
{
if (!m_document)
return Widget::onProcessMessage(msg);
switch (msg->type()) {
case kPaintMessage: {
@ -724,18 +624,12 @@ bool AnimationEditor::onProcessMessage(Message* msg)
}
break;
#if 0
case kKeyDownMessage: {
Command* command = NULL;
Params* params = NULL;
get_command_from_key_message(msg, &command, &params);
// Close animation editor.
if ((command && (strcmp(command->short_name(), CommandId::FilmEditor) == 0)) ||
(static_cast<KeyMessage*>(msg)->scancode() == kKeyEsc)) {
closeWindow();
return true;
}
// Undo or redo.
if (command && (strcmp(command->short_name(), CommandId::Undo) == 0 ||
strcmp(command->short_name(), CommandId::Redo) == 0)) {
@ -790,6 +684,7 @@ bool AnimationEditor::onProcessMessage(Message* msg)
break;
}
#endif
case kKeyUpMessage:
switch (static_cast<KeyMessage*>(msg)->scancode()) {
@ -838,20 +733,19 @@ bool AnimationEditor::onProcessMessage(Message* msg)
return Widget::onProcessMessage(msg);
}
void AnimationEditor::onPreferredSize(PreferredSizeEvent& ev)
void Timeline::onPreferredSize(PreferredSizeEvent& ev)
{
// This doesn't matter, the AniEditor'll use the entire screen anyway.
ev.setPreferredSize(Size(32, 32));
}
void AnimationEditor::onAddLayer(DocumentEvent& ev)
void Timeline::onAddLayer(DocumentEvent& ev)
{
ASSERT(ev.layer() != NULL);
setLayer(ev.layer());
}
void AnimationEditor::onRemoveLayer(DocumentEvent& ev)
void Timeline::onRemoveLayer(DocumentEvent& ev)
{
Sprite* sprite = ev.sprite();
Layer* layer = ev.layer();
@ -874,12 +768,12 @@ void AnimationEditor::onRemoveLayer(DocumentEvent& ev)
}
}
void AnimationEditor::onAddFrame(DocumentEvent& ev)
void Timeline::onAddFrame(DocumentEvent& ev)
{
setFrame(ev.frame());
}
void AnimationEditor::onRemoveFrame(DocumentEvent& ev)
void Timeline::onRemoveFrame(DocumentEvent& ev)
{
// Adjust current frame of all editors that are in a frame more
// advanced that the removed one.
@ -894,14 +788,14 @@ void AnimationEditor::onRemoveFrame(DocumentEvent& ev)
}
}
void AnimationEditor::onTotalFramesChanged(DocumentEvent& ev)
void Timeline::onTotalFramesChanged(DocumentEvent& ev)
{
if (getFrame() >= getSprite()->getTotalFrames()) {
setFrame(getSprite()->getLastFrame());
}
}
void AnimationEditor::setCursor(int x, int y)
void Timeline::setCursor(int x, int y)
{
int mx = x - getBounds().x;
//int my = y - getBounds().y;
@ -946,19 +840,19 @@ void AnimationEditor::setCursor(int x, int y)
}
}
void AnimationEditor::getDrawableLayers(const gfx::Rect& clip, int* first_layer, int* last_layer)
void Timeline::getDrawableLayers(const gfx::Rect& clip, int* first_layer, int* last_layer)
{
*first_layer = 0;
*last_layer = m_layers.size()-1;
}
void AnimationEditor::getDrawableFrames(const gfx::Rect& clip, FrameNumber* first_frame, FrameNumber* last_frame)
void Timeline::getDrawableFrames(const gfx::Rect& clip, FrameNumber* first_frame, FrameNumber* last_frame)
{
*first_frame = FrameNumber(0);
*last_frame = m_sprite->getLastFrame();
}
void AnimationEditor::drawHeader(const gfx::Rect& clip)
void Timeline::drawHeader(const gfx::Rect& clip)
{
// bool is_hot = (m_hot_part == A_PART_HEADER_LAYER);
// bool is_clk = (m_clk_part == A_PART_HEADER_LAYER);
@ -977,7 +871,7 @@ void AnimationEditor::drawHeader(const gfx::Rect& clip)
"Layers", -1);
}
void AnimationEditor::drawHeaderFrame(const gfx::Rect& clip, FrameNumber frame)
void Timeline::drawHeaderFrame(const gfx::Rect& clip, FrameNumber frame)
{
SkinTheme* theme = static_cast<SkinTheme*>(getTheme());
bool is_hot = (m_hot_part == A_PART_HEADER_FRAME &&
@ -1033,7 +927,7 @@ void AnimationEditor::drawHeaderFrame(const gfx::Rect& clip, FrameNumber frame)
set_clip_rect(ji_screen, cx1, cy1, cx2, cy2);
}
void AnimationEditor::drawHeaderPart(const gfx::Rect& clip, int x1, int y1, int x2, int y2,
void Timeline::drawHeaderPart(const gfx::Rect& clip, int x1, int y1, int x2, int y2,
bool is_hot, bool is_clk,
const char *line1, int align1,
const char *line2, int align2)
@ -1079,7 +973,7 @@ void AnimationEditor::drawHeaderPart(const gfx::Rect& clip, int x1, int y1, int
}
}
void AnimationEditor::drawSeparator(const gfx::Rect& clip)
void Timeline::drawSeparator(const gfx::Rect& clip)
{
SkinTheme* theme = static_cast<SkinTheme*>(getTheme());
bool is_hot = (m_hot_part == A_PART_SEPARATOR);
@ -1098,7 +992,7 @@ void AnimationEditor::drawSeparator(const gfx::Rect& clip)
theme->getColor(ThemeColor::Text)));
}
void AnimationEditor::drawLayer(const gfx::Rect& clip, int layer_index)
void Timeline::drawLayer(const gfx::Rect& clip, int layer_index)
{
Layer* layer = m_layers[layer_index];
SkinTheme* theme = static_cast<SkinTheme*>(this->getTheme());
@ -1161,7 +1055,7 @@ void AnimationEditor::drawLayer(const gfx::Rect& clip, int layer_index)
(m_clk_part == A_PART_LAYER_EYE_ICON &&
m_clk_layer == layer_index));
u += u+ICONBORDER+icon1->w+ICONBORDER;
u += ICONBORDER+icon1->w+ICONBORDER;
// Draw the padlock (writable flag).
icon_rect(icon2, icon2_selected,
@ -1178,7 +1072,7 @@ void AnimationEditor::drawLayer(const gfx::Rect& clip, int layer_index)
u += ICONBORDER+icon2->w+ICONBORDER+ICONSEP;
// Draw the layer's name.
jdraw_text(ji_screen, this->getFont(), layer->getName().c_str(),
jdraw_text(ji_screen, getFont(), layer->getName().c_str(),
u, y_mid - ji_font_get_size(this->getFont())/2,
fg, bg, true, jguiscale());
@ -1194,7 +1088,7 @@ void AnimationEditor::drawLayer(const gfx::Rect& clip, int layer_index)
set_clip_rect(ji_screen, cx1, cy1, cx2, cy2);
}
void AnimationEditor::drawLayerPadding()
void Timeline::drawLayerPadding()
{
SkinTheme* theme = static_cast<SkinTheme*>(this->getTheme());
int layer_index = m_layers.size()-1;
@ -1216,7 +1110,7 @@ void AnimationEditor::drawLayerPadding()
}
}
void AnimationEditor::drawCel(const gfx::Rect& clip, int layer_index, FrameNumber frame, Cel* cel)
void Timeline::drawCel(const gfx::Rect& clip, int layer_index, FrameNumber frame, Cel* cel)
{
SkinTheme* theme = static_cast<SkinTheme*>(this->getTheme());
Layer *layer = m_layers[layer_index];
@ -1311,7 +1205,7 @@ void AnimationEditor::drawCel(const gfx::Rect& clip, int layer_index, FrameNumbe
set_clip_rect(ji_screen, cx1, cy1, cx2, cy2);
}
bool AnimationEditor::drawPart(int part, int layer, FrameNumber frame)
bool Timeline::drawPart(int part, int layer, FrameNumber frame)
{
switch (part) {
case A_PART_NOTHING:
@ -1351,7 +1245,7 @@ bool AnimationEditor::drawPart(int part, int layer, FrameNumber frame)
return false;
}
void AnimationEditor::regenerateLayers()
void Timeline::regenerateLayers()
{
m_layers.clear();
size_t nlayers = m_sprite->countLayers();
@ -1362,7 +1256,7 @@ void AnimationEditor::regenerateLayers()
}
}
void AnimationEditor::hotThis(int hot_part, int hot_layer, FrameNumber hot_frame)
void Timeline::hotThis(int hot_part, int hot_layer, FrameNumber hot_frame)
{
int old_hot_part;
@ -1393,7 +1287,7 @@ void AnimationEditor::hotThis(int hot_part, int hot_layer, FrameNumber hot_frame
}
}
void AnimationEditor::centerCel(int layer, FrameNumber frame)
void Timeline::centerCel(int layer, FrameNumber frame)
{
int target_x = (getBounds().x + m_separator_x + m_separator_w + getBounds().x2())/2 - FRMSIZE/2;
int target_y = (getBounds().y + HDRSIZE + getBounds().y2())/2 - LAYSIZE/2;
@ -1403,7 +1297,7 @@ void AnimationEditor::centerCel(int layer, FrameNumber frame)
setScroll(scroll_x, scroll_y, false);
}
void AnimationEditor::showCel(int layer, FrameNumber frame)
void Timeline::showCel(int layer, FrameNumber frame)
{
int scroll_x, scroll_y;
int x1, y1, x2, y2;
@ -1435,21 +1329,21 @@ void AnimationEditor::showCel(int layer, FrameNumber frame)
setScroll(scroll_x, scroll_y, true);
}
void AnimationEditor::centerCurrentCel()
void Timeline::centerCurrentCel()
{
int layer = getLayerIndex(m_layer);
if (layer >= 0)
centerCel(layer, m_frame);
}
void AnimationEditor::showCurrentCel()
void Timeline::showCurrentCel()
{
int layer = getLayerIndex(m_layer);
if (layer >= 0)
showCel(layer, m_frame);
}
void AnimationEditor::cleanClk()
void Timeline::cleanClk()
{
int clk_part = m_clk_part;
m_clk_part = A_PART_NOTHING;
@ -1459,7 +1353,7 @@ void AnimationEditor::cleanClk()
m_clk_frame);
}
void AnimationEditor::setScroll(int x, int y, bool use_refresh_region)
void Timeline::setScroll(int x, int y, bool use_refresh_region)
{
int old_scroll_x = 0;
int old_scroll_y = 0;
@ -1519,7 +1413,7 @@ void AnimationEditor::setScroll(int x, int y, bool use_refresh_region)
}
}
int AnimationEditor::getLayerIndex(const Layer* layer)
int Timeline::getLayerIndex(const Layer* layer)
{
for (size_t i=0; i<m_layers.size(); i++)
if (m_layers[i] == layer)

130
src/app/ui/timeline.h Normal file
View File

@ -0,0 +1,130 @@
/* Aseprite
* Copyright (C) 2001-2013 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_UI_TIMELINE_H_INCLUDED
#define APP_UI_TIMELINE_H_INCLUDED
#include "app/document_observer.h"
#include "base/compiler_specific.h"
#include "raster/frame_number.h"
#include "ui/widget.h"
#include <vector>
namespace raster {
class Cel;
class Layer;
class Sprite;
}
namespace app {
using namespace raster;
class Context;
class Document;
class Editor;
class Timeline : public ui::Widget
, public DocumentObserver {
public:
enum State {
STATE_STANDBY,
STATE_SCROLLING,
STATE_MOVING_SEPARATOR,
STATE_MOVING_LAYER,
STATE_MOVING_CEL,
STATE_MOVING_FRAME,
};
Timeline();
~Timeline();
void updateUsingEditor(Editor* editor);
Sprite* getSprite() { return m_sprite; }
Layer* getLayer() { return m_layer; }
FrameNumber getFrame() { return m_frame; }
void setLayer(Layer* layer);
void setFrame(FrameNumber frame);
void centerCurrentCel();
State getState() const { return m_state; }
bool isMovingCel() const;
protected:
bool onProcessMessage(ui::Message* msg) OVERRIDE;
void onPreferredSize(ui::PreferredSizeEvent& ev) OVERRIDE;
// DocumentObserver impl.
void onAddLayer(DocumentEvent& ev) OVERRIDE;
void onRemoveLayer(DocumentEvent& ev) OVERRIDE;
void onAddFrame(DocumentEvent& ev) OVERRIDE;
void onRemoveFrame(DocumentEvent& ev) OVERRIDE;
void onTotalFramesChanged(DocumentEvent& ev) OVERRIDE;
private:
void setCursor(int x, int y);
void getDrawableLayers(const gfx::Rect& clip, int* first_layer, int* last_layer);
void getDrawableFrames(const gfx::Rect& clip, FrameNumber* first_frame, FrameNumber* last_frame);
void drawHeader(const gfx::Rect& clip);
void drawHeaderFrame(const gfx::Rect& clip, FrameNumber frame);
void drawHeaderPart(const gfx::Rect& clip, int x1, int y1, int x2, int y2,
bool is_hot, bool is_clk,
const char* line1, int align1,
const char* line2, int align2);
void drawSeparator(const gfx::Rect& clip);
void drawLayer(const gfx::Rect& clip, int layer_index);
void drawLayerPadding();
void drawCel(const gfx::Rect& clip, int layer_index, FrameNumber frame, Cel* cel);
bool drawPart(int part, int layer, FrameNumber frame);
void regenerateLayers();
void hotThis(int hot_part, int hot_layer, FrameNumber hotFrame);
void centerCel(int layer, FrameNumber frame);
void showCel(int layer, FrameNumber frame);
void showCurrentCel();
void cleanClk();
void setScroll(int x, int y, bool use_refresh_region);
int getLayerIndex(const Layer* layer);
Context* m_context;
Document* m_document;
Sprite* m_sprite;
Layer* m_layer;
FrameNumber m_frame;
State m_state;
std::vector<Layer*> m_layers;
int m_scroll_x;
int m_scroll_y;
int m_separator_x;
int m_separator_w;
// The 'hot' part is where the mouse is on top of
int m_hot_part;
int m_hot_layer;
FrameNumber m_hot_frame;
// The 'clk' part is where the mouse's button was pressed (maybe for a drag & drop operation)
int m_clk_part;
int m_clk_layer;
FrameNumber m_clk_frame;
// Keys
bool m_space_pressed;
};
} // namespace app
#endif

View File

@ -21,20 +21,21 @@
#endif
#include "app/app.h"
#include "app/document.h"
#include "app/modules/editors.h"
#include "app/settings/ui_settings_impl.h"
#include "app/ui/color_bar.h"
#include "app/ui/document_view.h"
#include "app/ui/editor/editor.h"
#include "app/ui/main_window.h"
#include "app/ui/mini_editor.h"
#include "app/ui/tabs.h"
#include "app/ui/timeline.h"
#include "app/ui/workspace.h"
#include "app/ui_context.h"
#include "base/mutex.h"
#include "base/path.h"
#include "app/document.h"
#include "app/modules/editors.h"
#include "raster/sprite.h"
#include "app/settings/ui_settings_impl.h"
#include "app/ui_context.h"
#include "undo/undo_history.h"
#include <allegro/file.h>
@ -82,6 +83,7 @@ void UIContext::setActiveView(DocumentView* docView)
current_editor->requestFocus();
App::instance()->getMainWindow()->getMiniEditor()->updateUsingEditor(current_editor);
App::instance()->getMainWindow()->getTimeline()->updateUsingEditor(current_editor);
// Change the image-type of color bar.
ColorBar::instance()->setPixelFormat(app_get_current_pixel_format());