Merge branch '1.0'

This commit is contained in:
David Capello 2014-10-24 18:51:16 -03:00
commit 66d88ffe5d
15 changed files with 225 additions and 23 deletions

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- ASE menus, tools and keyboard shortcuts --> <!-- ASE menus, tools and keyboard shortcuts -->
<gui version="1.0.5-dev"> <gui version="1.0.6-dev">
<!-- Keyboard shortcuts --> <!-- Keyboard shortcuts -->
<keyboard> <keyboard>
@ -66,6 +66,7 @@
<key command="FrameProperties" shortcut="P"> <key command="FrameProperties" shortcut="P">
<param name="frame" value="current" /> <param name="frame" value="current" />
</key> </key>
<key command="ReverseFrames" shortcut="Alt+I" />
<key command="GotoFirstFrame" shortcut="Home" /> <key command="GotoFirstFrame" shortcut="Home" />
<key command="GotoPreviousFrame" shortcut="Left" context="Normal" /> <key command="GotoPreviousFrame" shortcut="Left" context="Normal" />
<key command="GotoNextFrame" shortcut="Right" context="Normal" /> <key command="GotoNextFrame" shortcut="Right" context="Normal" />
@ -503,7 +504,7 @@
<item command="CelProperties" text="&amp;Cel Properties..." /> <item command="CelProperties" text="&amp;Cel Properties..." />
<separator /> <separator />
<item command="NewFrame" text="&amp;New Frame" /> <item command="NewFrame" text="&amp;New Frame" />
<item command="NewFrame" text="&amp;New Empty Frame"> <item command="NewFrame" text="New &amp;Empty Frame">
<param name="content" value="empty" /> <param name="content" value="empty" />
</item> </item>
<item command="RemoveFrame" text="&amp;Remove Frame" /> <item command="RemoveFrame" text="&amp;Remove Frame" />
@ -521,6 +522,7 @@
<item command="FrameProperties" text="Constant Frame Rate"> <item command="FrameProperties" text="Constant Frame Rate">
<param name="frame" value="all" /> <param name="frame" value="all" />
</item> </item>
<item command="ReverseFrames" text="Re&amp;verse Frames" />
</menu> </menu>
<menu text="&amp;Palette"> <menu text="&amp;Palette">
<item command="PaletteEditor" text="&amp;Palette Editor"> <item command="PaletteEditor" text="&amp;Palette Editor">

View File

@ -72,6 +72,7 @@ add_library(app-lib
commands/cmd_remove_layer.cpp commands/cmd_remove_layer.cpp
commands/cmd_repeat_last_export.cpp commands/cmd_repeat_last_export.cpp
commands/cmd_reselect_mask.cpp commands/cmd_reselect_mask.cpp
commands/cmd_reverse_frames.cpp
commands/cmd_rotate.cpp commands/cmd_rotate.cpp
commands/cmd_save_file.cpp commands/cmd_save_file.cpp
commands/cmd_save_mask.cpp commands/cmd_save_mask.cpp

View File

@ -262,6 +262,11 @@ std::string Color::toHumanReadableString(PixelFormat pixelFormat, HumanReadableS
ASSERT(false); ASSERT(false);
break; break;
} }
result << " #" << std::hex << std::setfill('0')
<< std::setw(2) << getRed()
<< std::setw(2) << getGreen()
<< std::setw(2) << getBlue();
} }
else if (humanReadable == ShortHumanReadableString) { else if (humanReadable == ShortHumanReadableString) {
switch (getType()) { switch (getType()) {

View File

@ -0,0 +1,73 @@
/* Aseprite
* Copyright (C) 2001-2014 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 "app/app.h"
#include "app/commands/command.h"
#include "app/context_access.h"
#include "app/modules/gui.h"
#include "app/ui/main_window.h"
#include "app/ui/timeline.h"
#include "app/document_range_ops.h"
namespace app {
class ReverseFramesCommand : public Command {
public:
ReverseFramesCommand();
Command* clone() const override { return new ReverseFramesCommand(*this); }
protected:
bool onEnabled(Context* context);
void onExecute(Context* context);
};
ReverseFramesCommand::ReverseFramesCommand()
: Command("ReverseFrames",
"Reverse Frames",
CmdUIOnlyFlag)
{
}
bool ReverseFramesCommand::onEnabled(Context* context)
{
return context->checkFlags(ContextFlags::ActiveDocumentIsWritable);
}
void ReverseFramesCommand::onExecute(Context* context)
{
DocumentRange range = App::instance()->getMainWindow()->getTimeline()->range();
if (!range.enabled())
return; // Nothing to do
Document* doc = context->activeDocument();
reverse_frames(doc, range);
update_screen_for_document(doc);
}
Command* CommandFactory::createReverseFramesCommand()
{
return new ReverseFramesCommand;
}
} // namespace app

View File

@ -1,5 +1,5 @@
/* Aseprite /* Aseprite
* Copyright (C) 2001-2013 David Capello * Copyright (C) 2001-2014 David Capello
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -91,6 +91,7 @@ FOR_EACH_COMMAND(RemoveLayer)
FOR_EACH_COMMAND(RepeatLastExport) FOR_EACH_COMMAND(RepeatLastExport)
FOR_EACH_COMMAND(ReplaceColor) FOR_EACH_COMMAND(ReplaceColor)
FOR_EACH_COMMAND(ReselectMask) FOR_EACH_COMMAND(ReselectMask)
FOR_EACH_COMMAND(ReverseFrames)
FOR_EACH_COMMAND(Rotate) FOR_EACH_COMMAND(Rotate)
FOR_EACH_COMMAND(SaveFile) FOR_EACH_COMMAND(SaveFile)
FOR_EACH_COMMAND(SaveFileAs) FOR_EACH_COMMAND(SaveFileAs)

View File

@ -472,7 +472,7 @@ void DocumentApi::moveFrame(Sprite* sprite, FrameNumber frame, FrameNumber befor
frame <= sprite->lastFrame() && frame <= sprite->lastFrame() &&
beforeFrame >= 0 && beforeFrame >= 0 &&
beforeFrame <= sprite->lastFrame().next()) { beforeFrame <= sprite->lastFrame().next()) {
// Change the frame-lengths... // Change the frame-lengths.
int frlen_aux = sprite->getFrameDuration(frame); int frlen_aux = sprite->getFrameDuration(frame);
// Moving the frame to the future. // Moving the frame to the future.
@ -490,7 +490,7 @@ void DocumentApi::moveFrame(Sprite* sprite, FrameNumber frame, FrameNumber befor
setFrameDuration(sprite, beforeFrame, frlen_aux); setFrameDuration(sprite, beforeFrame, frlen_aux);
} }
// change the cels of position... // Change cel positions.
moveFrameLayer(sprite->folder(), frame, beforeFrame); moveFrameLayer(sprite->folder(), frame, beforeFrame);
} }
} }
@ -818,6 +818,21 @@ void DocumentApi::copyCel(
m_document->notifyCelCopied(srcLayer, srcFrame, dstLayer, dstFrame); m_document->notifyCelCopied(srcLayer, srcFrame, dstLayer, dstFrame);
} }
void DocumentApi::swapCel(
LayerImage* layer, FrameNumber frame1, FrameNumber frame2)
{
Sprite* sprite = layer->sprite();
ASSERT(sprite != NULL);
ASSERT(frame1 >= 0 && frame1 < sprite->totalFrames());
ASSERT(frame2 >= 0 && frame2 < sprite->totalFrames());
Cel* cel1 = layer->getCel(frame1);
Cel* cel2 = layer->getCel(frame2);
if (cel1) setCelFramePosition(layer, cel1, frame2);
if (cel2) setCelFramePosition(layer, cel2, frame1);
}
LayerImage* DocumentApi::newLayer(Sprite* sprite) LayerImage* DocumentApi::newLayer(Sprite* sprite)
{ {
LayerImage* layer = new LayerImage(sprite); LayerImage* layer = new LayerImage(sprite);

View File

@ -1,5 +1,5 @@
/* Aseprite /* Aseprite
* Copyright (C) 2001-2013 David Capello * Copyright (C) 2001-2014 David Capello
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -90,6 +90,8 @@ namespace app {
void copyCel( void copyCel(
LayerImage* srcLayer, FrameNumber srcFrame, LayerImage* srcLayer, FrameNumber srcFrame,
LayerImage* dstLayer, FrameNumber dstFrame); LayerImage* dstLayer, FrameNumber dstFrame);
void swapCel(
LayerImage* layer, FrameNumber frame1, FrameNumber frame2);
// Layers API // Layers API
LayerImage* newLayer(Sprite* sprite); LayerImage* newLayer(Sprite* sprite);

View File

@ -341,4 +341,62 @@ DocumentRange copy_range(Document* doc, const DocumentRange& from, const Documen
return drop_range_op(doc, Copy, from, place, to); return drop_range_op(doc, Copy, from, place, to);
} }
void reverse_frames(Document* doc, const DocumentRange& range)
{
const app::Context* context = static_cast<app::Context*>(doc->context());
const ContextReader reader(context);
ContextWriter writer(reader);
UndoTransaction undo(writer.context(), "Reverse Frames");
DocumentApi api = doc->getApi();
Sprite* sprite = doc->sprite();
FrameNumber frameBegin, frameEnd;
int layerBegin, layerEnd;
bool moveFrames = false;
switch (range.type()) {
case DocumentRange::kCels:
frameBegin = range.frameBegin();
frameEnd = range.frameEnd();
layerBegin = range.layerBegin();
layerEnd = range.layerEnd() + 1;
break;
case DocumentRange::kFrames:
frameBegin = range.frameBegin();
frameEnd = range.frameEnd();
moveFrames = true;
break;
case DocumentRange::kLayers:
frameBegin = FrameNumber(0);
frameEnd = sprite->totalFrames().previous();
layerBegin = range.layerBegin();
layerEnd = range.layerEnd() + 1;
break;
}
if (moveFrames) {
for (FrameNumber frameRev = frameEnd.next();
frameRev > frameBegin;
frameRev = frameRev.previous()) {
api.moveFrame(sprite, frameBegin, frameRev);
}
}
else {
std::vector<Layer*> layers;
sprite->getLayersList(layers);
for (int layerIdx = layerBegin; layerIdx != layerEnd; ++layerIdx) {
for (FrameNumber frame = frameBegin,
frameRev = frameEnd;
frame != FrameNumber((frameBegin+frameEnd)/2).next();
frame = frame.next(),
frameRev = frameRev.previous()) {
LayerImage* layer = static_cast<LayerImage*>(layers[layerIdx]);
api.swapCel(layer, frame, frameRev);
}
}
}
undo.commit();
}
} // namespace app } // namespace app

View File

@ -37,6 +37,8 @@ namespace app {
DocumentRange move_range(Document* doc, const DocumentRange& from, const DocumentRange& to, DocumentRangePlace place); DocumentRange move_range(Document* doc, const DocumentRange& from, const DocumentRange& to, DocumentRangePlace place);
DocumentRange copy_range(Document* doc, const DocumentRange& from, const DocumentRange& to, DocumentRangePlace place); DocumentRange copy_range(Document* doc, const DocumentRange& from, const DocumentRange& to, DocumentRangePlace place);
void reverse_frames(Document* doc, const DocumentRange& range);
} // namespace app } // namespace app
#endif #endif

View File

@ -764,3 +764,35 @@ TEST_F(DocRangeOps, CopyFrames) {
TEST_F(DocRangeOps, CopyCels) { TEST_F(DocRangeOps, CopyCels) {
// TODO // TODO
} }
TEST_F(DocRangeOps, ReverseFrames) {
reverse_frames(doc, frames_range(0, 0));
EXPECT_FRAME_ORDER(0, 1, 2, 3);
reverse_frames(doc, frames_range(1, 1));
EXPECT_FRAME_ORDER(0, 1, 2, 3);
reverse_frames(doc, frames_range(1, 2));
EXPECT_FRAME_ORDER(0, 2, 1, 3);
doc->getUndo()->doUndo();
EXPECT_FRAME_ORDER(0, 1, 2, 3);
reverse_frames(doc, frames_range(0, 2));
EXPECT_FRAME_ORDER(2, 1, 0, 3);
doc->getUndo()->doUndo();
EXPECT_FRAME_ORDER(0, 1, 2, 3);
reverse_frames(doc, frames_range(1, 3));
EXPECT_FRAME_ORDER(0, 3, 2, 1);
doc->getUndo()->doUndo();
EXPECT_FRAME_ORDER(0, 1, 2, 3);
reverse_frames(doc, frames_range(0, 3));
EXPECT_FRAME_ORDER(3, 2, 1, 0);
doc->getUndo()->doUndo();
EXPECT_FRAME_ORDER(0, 1, 2, 3);
}
TEST_F(DocRangeOps, ReverseCels) {
// TODO
}

View File

@ -1013,9 +1013,16 @@ void Editor::updateQuicktool()
return; return;
} }
// Hide the drawing cursor with the current tool brush size before
// we change the quicktool. In this way we avoid using the
// quicktool brush size to clean the current tool cursor.
hideDrawingCursor();
tools::Tool* old_quicktool = m_quicktool; tools::Tool* old_quicktool = m_quicktool;
m_quicktool = m_customizationDelegate->getQuickTool(current_tool); m_quicktool = m_customizationDelegate->getQuickTool(current_tool);
showDrawingCursor();
// If the tool has changed, we must to update the status bar because // If the tool has changed, we must to update the status bar because
// the new tool can display something different in the status bar (e.g. Eyedropper) // the new tool can display something different in the status bar (e.g. Eyedropper)
if (old_quicktool != m_quicktool) { if (old_quicktool != m_quicktool) {

View File

@ -33,7 +33,7 @@
// General information // General information
#define PACKAGE "Aseprite" #define PACKAGE "Aseprite"
#define VERSION "1.0.5-dev" #define VERSION "1.0.6-dev"
#ifdef CUSTOM_WEBSITE_URL #ifdef CUSTOM_WEBSITE_URL
#define WEBSITE CUSTOM_WEBSITE_URL // To test web server #define WEBSITE CUSTOM_WEBSITE_URL // To test web server
#else #else

View File

@ -3,8 +3,8 @@ allegro_icon ICON data/icons/ase.ico
1 ICON data/icons/doc.ico 1 ICON data/icons/doc.ico
1 VERSIONINFO 1 VERSIONINFO
FILEVERSION 1,0,5,0 FILEVERSION 1,0,6,0
PRODUCTVERSION 1,0,5,0 PRODUCTVERSION 1,0,6,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -21,12 +21,12 @@ BEGIN
BEGIN BEGIN
VALUE "Comments", "http://aseprite.org/" VALUE "Comments", "http://aseprite.org/"
VALUE "FileDescription", "Aseprite - Animated sprites editor & pixel art tool" VALUE "FileDescription", "Aseprite - Animated sprites editor & pixel art tool"
VALUE "FileVersion", "1,0,5,0" VALUE "FileVersion", "1,0,6,0"
VALUE "InternalName", "aseprite" VALUE "InternalName", "aseprite"
VALUE "LegalCopyright", "Copyright (C) 2001-2014 by David Capello" VALUE "LegalCopyright", "Copyright (C) 2001-2014 by David Capello"
VALUE "OriginalFilename", "aseprite.exe" VALUE "OriginalFilename", "aseprite.exe"
VALUE "ProductName", "ASEPRITE" VALUE "ProductName", "ASEPRITE"
VALUE "ProductVersion", "1,0,5,0" VALUE "ProductVersion", "1,0,6,0"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View File

@ -689,7 +689,8 @@ bool MenuItem::onProcessMessage(Message* msg)
// When a menu item receives the mouse, start a timer to open the submenu... // When a menu item receives the mouse, start a timer to open the submenu...
if (isEnabled() && hasSubmenu()) { if (isEnabled() && hasSubmenu()) {
// Start the timer to open the submenu... // Start the timer to open the submenu...
startTimer(); if (!inBar())
startTimer();
} }
break; break;
@ -723,7 +724,7 @@ bool MenuItem::onProcessMessage(Message* msg)
// Menubox position // Menubox position
Rect pos = window->getBounds(); Rect pos = window->getBounds();
if (this->getParent()->getParent()->type == kMenuBarWidget) { if (inBar()) {
pos.x = MID(0, getBounds().x, ui::display_w()-pos.w); pos.x = MID(0, getBounds().x, ui::display_w()-pos.w);
pos.y = MID(0, getBounds().y2(), ui::display_h()-pos.h); pos.y = MID(0, getBounds().y2(), ui::display_h()-pos.h);
} }
@ -872,15 +873,12 @@ void MenuItem::onClick()
void MenuItem::onPreferredSize(PreferredSizeEvent& ev) void MenuItem::onPreferredSize(PreferredSizeEvent& ev)
{ {
Size size(0, 0); Size size(0, 0);
bool bar = (getParent() &&
getParent()->getParent() &&
getParent()->getParent()->type == kMenuBarWidget);
if (hasText()) { if (hasText()) {
size.w = size.w =
+ this->border_width.l + this->border_width.l
+ getTextWidth() + getTextWidth()
+ (bar ? this->child_spacing/4: this->child_spacing) + (inBar() ? this->child_spacing/4: this->child_spacing)
+ this->border_width.r; + this->border_width.r;
size.h = size.h =
@ -1003,6 +1001,14 @@ void Menu::unhighlightItem()
highlightItem(NULL, false, false, false); highlightItem(NULL, false, false, false);
} }
bool MenuItem::inBar()
{
return
(getParent() &&
getParent()->getParent() &&
getParent()->getParent()->type == kMenuBarWidget);
}
void MenuItem::openSubmenu(bool select_first) void MenuItem::openSubmenu(bool select_first)
{ {
Widget* menu; Widget* menu;

View File

@ -55,8 +55,7 @@ namespace ui {
friend class MenuItem; friend class MenuItem;
}; };
class MenuBox : public Widget class MenuBox : public Widget {
{
public: public:
MenuBox(WidgetType type = kMenuBoxWidget); MenuBox(WidgetType type = kMenuBoxWidget);
~MenuBox(); ~MenuBox();
@ -86,14 +85,12 @@ namespace ui {
friend class Menu; friend class Menu;
}; };
class MenuBar : public MenuBox class MenuBar : public MenuBox {
{
public: public:
MenuBar(); MenuBar();
}; };
class MenuItem : public Widget class MenuItem : public Widget {
{
public: public:
MenuItem(const std::string& text); MenuItem(const std::string& text);
~MenuItem(); ~MenuItem();
@ -131,6 +128,7 @@ namespace ui {
virtual void onClick(); virtual void onClick();
private: private:
bool inBar();
void openSubmenu(bool select_first); void openSubmenu(bool select_first);
void closeSubmenu(bool last_of_close_chain); void closeSubmenu(bool last_of_close_chain);
void startTimer(); void startTimer();