Merge branch '1.0'

Conflicts:
	src/app/file/gif_format.cpp
	src/app/file/gif_options.h
	src/app/ui/editor/moving_cel_state.cpp
	src/app/ui/editor/standby_state.cpp
	src/app/util/range_utils.cpp
This commit is contained in:
David Capello 2015-01-29 12:18:13 -03:00
commit 06636fd16e
10 changed files with 128 additions and 10 deletions

View File

@ -56,6 +56,7 @@
<key command="SpriteProperties" shortcut="Ctrl+P" mac="Cmd+P" />
<!-- Layer -->
<key command="LayerProperties" shortcut="Shift+P" />
<key command="LayerVisibility" shortcut="Shift+X" />
<key command="NewLayer" shortcut="Shift+N" />
<key command="GotoPreviousLayer" shortcut="Down" context="Normal" />
<key command="GotoNextLayer" shortcut="Up" context="Normal" />
@ -497,6 +498,7 @@
</menu>
<menu text="&amp;Layer">
<item command="LayerProperties" text="&amp;Properties..." />
<item command="LayerVisibility" text="&amp;Visible" />
<separator />
<item command="NewLayer" text="&amp;New Layer" />
<item command="RemoveLayer" text="&amp;Remove Layer" />
@ -576,7 +578,7 @@
<menu text="&amp;Help">
<item command="Launch" text="Readme">
<param name="type" value="url" />
<param name="path" value="https://github.com/dacap/aseprite#readme" />
<param name="path" value="https://github.com/aseprite/aseprite#readme" />
</item>
<separator />
<item command="Launch" text="Quick &amp;Reference">

View File

@ -13,8 +13,9 @@
<radio id="no_quantize" text="&amp;Don't modify color palette" group="1" />
</vbox>
<separator text="Optimize for Web:" left="true" horizontal="true" />
<separator text="General Options:" left="true" horizontal="true" />
<check text="Interlaced" id="interlaced" />
<check text="Animation Loop" id="loop" />
<separator horizontal="true" />

View File

@ -144,6 +144,7 @@ add_library(app-lib
commands/cmd_launch.cpp
commands/cmd_layer_from_background.cpp
commands/cmd_layer_properties.cpp
commands/cmd_layer_visibility.cpp
commands/cmd_load_mask.cpp
commands/cmd_load_palette.cpp
commands/cmd_mask_all.cpp

View File

@ -0,0 +1,85 @@
/* 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 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 "base/bind.h"
#include "ui/ui.h"
#include "app/app.h"
#include "app/commands/command.h"
#include "app/context_access.h"
#include "app/modules/gui.h"
#include "doc/image.h"
#include "doc/layer.h"
#include "generated_layer_properties.h"
namespace app {
using namespace ui;
class LayerVisibilityCommand : public Command {
public:
LayerVisibilityCommand();
Command* clone() const override { return new LayerVisibilityCommand(*this); }
protected:
bool onEnabled(Context* context) override;
bool onChecked(Context* context) override;
void onExecute(Context* context) override;
};
LayerVisibilityCommand::LayerVisibilityCommand()
: Command("LayerVisibility",
"Layer Visibility",
CmdRecordableFlag)
{
}
bool LayerVisibilityCommand::onEnabled(Context* context)
{
return context->checkFlags(ContextFlags::ActiveDocumentIsWritable |
ContextFlags::HasActiveLayer);
}
bool LayerVisibilityCommand::onChecked(Context* context)
{
const ContextReader reader(context);
const Layer* layer = reader.layer();
return (layer && layer->isVisible());
}
void LayerVisibilityCommand::onExecute(Context* context)
{
ContextWriter writer(context);
Layer* layer = writer.layer();
layer->setVisible(!layer->isVisible());
update_screen_for_document(writer.document());
}
Command* CommandFactory::createLayerVisibilityCommand()
{
return new LayerVisibilityCommand;
}
} // namespace app

View File

@ -65,6 +65,7 @@ FOR_EACH_COMMAND(KeyboardShortcuts)
FOR_EACH_COMMAND(Launch)
FOR_EACH_COMMAND(LayerFromBackground)
FOR_EACH_COMMAND(LayerProperties)
FOR_EACH_COMMAND(LayerVisibility)
FOR_EACH_COMMAND(LoadMask)
FOR_EACH_COMMAND(LoadPalette)
FOR_EACH_COMMAND(MakeUniqueEditor)

View File

@ -545,7 +545,7 @@ bool GifFormat::onSave(FileOp* fop)
int sprite_h = sprite->height();
PixelFormat sprite_format = sprite->pixelFormat();
bool interlaced = gif_options->interlaced();
int loop = 0;
int loop = (gif_options->loop() ? 0: -1);
bool has_background = (sprite->backgroundLayer() ? true: false);
int background_color = (sprite_format == IMAGE_INDEXED ? sprite->transparentColor(): 0);
int transparent_index = (has_background ? -1: sprite->transparentColor());
@ -801,6 +801,7 @@ SharedPtr<FormatOptions> GifFormat::onGetFormatOptions(FileOp* fop)
// Configuration parameters
gif_options->setQuantize((GifOptions::Quantize)get_config_int("GIF", "Quantize", (int)gif_options->quantize()));
gif_options->setInterlaced(get_config_bool("GIF", "Interlaced", gif_options->interlaced()));
gif_options->setLoop(get_config_bool("GIF", "Loop", gif_options->loop()));
gif_options->setDithering((doc::DitheringMethod)get_config_int("GIF", "Dither", (int)gif_options->dithering()));
// Load the window to ask to the user the GIF options he wants.
@ -814,6 +815,7 @@ SharedPtr<FormatOptions> GifFormat::onGetFormatOptions(FileOp* fop)
case GifOptions::QuantizeAll: win.quantizeAll()->setSelected(true); break;
}
win.interlaced()->setSelected(gif_options->interlaced());
win.loop()->setSelected(gif_options->loop());
win.dither()->setEnabled(true);
win.dither()->setSelected(gif_options->dithering() == doc::DitheringMethod::ORDERED);
@ -829,12 +831,14 @@ SharedPtr<FormatOptions> GifFormat::onGetFormatOptions(FileOp* fop)
gif_options->setQuantize(GifOptions::NoQuantize);
gif_options->setInterlaced(win.interlaced()->isSelected());
gif_options->setLoop(win.loop()->isSelected());
gif_options->setDithering(win.dither()->isSelected() ?
doc::DitheringMethod::ORDERED:
doc::DitheringMethod::NONE);
set_config_int("GIF", "Quantize", gif_options->quantize());
set_config_bool("GIF", "Interlaced", gif_options->interlaced());
set_config_bool("GIF", "Loop", gif_options->loop());
set_config_int("GIF", "Dither", int(gif_options->dithering()));
}
else {

View File

@ -33,23 +33,28 @@ namespace app {
GifOptions(
Quantize quantize = QuantizeEach,
bool interlaced = false,
bool loop = true,
DitheringMethod dithering = doc::DitheringMethod::NONE)
: m_quantize(quantize)
, m_interlaced(interlaced)
, m_loop(loop)
, m_dithering(dithering) {
}
Quantize quantize() const { return m_quantize; }
bool interlaced() const { return m_interlaced; }
bool loop() const { return m_loop; }
doc::DitheringMethod dithering() const { return m_dithering; }
void setQuantize(const Quantize quantize) { m_quantize = quantize; }
void setInterlaced(bool interlaced) { m_interlaced = interlaced; }
void setLoop(bool loop) { m_loop = loop; }
void setDithering(const doc::DitheringMethod dithering) { m_dithering = dithering; }
private:
Quantize m_quantize;
bool m_interlaced;
bool m_loop;
doc::DitheringMethod m_dithering;
};

View File

@ -96,8 +96,12 @@ bool MovingCelState::onMouseUp(Editor* editor, MouseMessage* msg)
DocumentRange range = App::instance()->getMainWindow()->getTimeline()->range();
if (range.enabled()) {
for (Cel* cel : get_cels_in_range(writer.sprite(), range))
api.setCelPosition(writer.sprite(), cel, cel->x()+delta.x, cel->y()+delta.y);
for (Cel* cel : get_cels_in_range(writer.sprite(), range)) {
Layer* layer = cel->layer();
ASSERT(layer);
if (layer && layer->isMovable() && !layer->isBackground())
api.setCelPosition(writer.sprite(), cel, cel->x()+delta.x, cel->y()+delta.y);
}
}
else if (m_cel) {
api.setCelPosition(writer.sprite(), m_cel, m_celNew.x, m_celNew.y);

View File

@ -238,7 +238,7 @@ bool StandbyState::onMouseDown(Editor* editor, MouseMessage* msg)
if (handle != NoHandle) {
int x, y, opacity;
Image* image = location.image(&x, &y, &opacity);
if (image) {
if (layer && image) {
if (!layer->isEditable()) {
StatusBar::instance()->showTip(1000,
"Layer '%s' is locked", layer->name().c_str());
@ -253,7 +253,7 @@ bool StandbyState::onMouseDown(Editor* editor, MouseMessage* msg)
}
// Move selected pixels
if (editor->isInsideSelection() && msg->left()) {
if (layer && editor->isInsideSelection() && msg->left()) {
if (!layer->isEditable()) {
StatusBar::instance()->showTip(1000,
"Layer '%s' is locked", layer->name().c_str());

View File

@ -31,17 +31,32 @@ namespace app {
using namespace doc;
// TODO the DocumentRange should be "iteratable" to replace this function
CelList get_cels_in_range(Sprite* sprite, const DocumentRange& range)
CelList get_cels_in_range(Sprite* sprite, const DocumentRange& inrange)
{
DocumentRange range = inrange;
CelList cels;
switch (range.type()) {
case DocumentRange::kNone:
return cels;
case DocumentRange::kCels:
break;
case DocumentRange::kFrames:
range.startRange(LayerIndex(0), inrange.frameBegin(), DocumentRange::kCels);
range.endRange(LayerIndex(sprite->countLayers()-1), inrange.frameEnd());
break;
case DocumentRange::kLayers:
range.startRange(inrange.layerBegin(), frame_t(0), DocumentRange::kCels);
range.endRange(inrange.layerEnd(), sprite->lastFrame());
break;
}
for (LayerIndex layerIdx = range.layerBegin(); layerIdx <= range.layerEnd(); ++layerIdx) {
Layer* layer = sprite->indexToLayer(layerIdx);
if (!layer->isImage())
if (!layer || !layer->isImage())
continue;
LayerImage* layerImage = static_cast<LayerImage*>(layer);
for (frame_t frame = range.frameEnd(),
begin = range.frameBegin()-1;
frame != begin;