Add New Layer via Cut/Copy commands (fix #1567)

This commit is contained in:
David Capello 2019-07-02 15:28:05 -03:00
parent fed9a2b45c
commit 757fadeaf0
3 changed files with 124 additions and 34 deletions

View File

@ -39,9 +39,6 @@
<key command="CopyMerged" shortcut="Ctrl+Shift+C" mac="Cmd+Shift+C" />
<key command="Paste" shortcut="Ctrl+V" mac="Cmd+V" />
<key command="Paste" shortcut="Shift+Ins" />
<key command="NewLayer" shortcut="Ctrl+Shift+V" mac="Cmd+Shift+V">
<param name="fromClipboard" value="true" />
</key>
<key command="Clear" shortcut="Del" />
<key command="Clear" shortcut="Backspace" />
<key command="Fill" shortcut="F" />
@ -78,6 +75,15 @@
<key command="NewLayer" shortcut="Alt+Shift+N">
<param name="group" value="true" />
</key>
<key command="NewLayer" shortcut="Ctrl+Shift+V" mac="Cmd+Shift+V">
<param name="fromClipboard" value="true" />
</key>
<key command="NewLayer" shortcut="Ctrl+J" mac="Cmd+J">
<param name="viaCopy" value="true" />
</key>
<key command="NewLayer" shortcut="Ctrl+Shift+J" mac="Cmd+Shift+J">
<param name="viaCut" value="true" />
</key>
<key command="GotoPreviousLayer" shortcut="Down" context="Normal" />
<key command="GotoNextLayer" shortcut="Up" context="Normal" />
<!-- Frame -->
@ -770,10 +776,31 @@
<item command="LayerLock" text="@.layer_lock_layers" />
<item command="OpenGroup" text="@.layer_open_group" />
<separator />
<item command="NewLayer" text="@.layer_new_layer" />
<item command="NewLayer" text="@.layer_new_group">
<param name="group" value="true" />
</item>
<menu text="@.layer_new">
<item command="NewLayer" text="@.layer_new_layer" />
<item command="NewLayer" text="@.layer_new_group">
<param name="group" value="true" />
</item>
<separator />
<item command="NewLayer" text="@.layer_new_layer_from_clipboard">
<param name="fromClipboard" value="true" />
</item>
<item command="NewLayer" text="@.layer_new_layer_via_copy">
<param name="viaCopy" value="true" />
</item>
<item command="NewLayer" text="@.layer_new_layer_via_cut">
<param name="viaCut" value="true" />
</item>
<separator />
<item command="NewLayer" text="@.layer_new_reference_layer_from_file">
<param name="reference" value="true" />
<param name="fromFile" value="true" />
</item>
<item command="NewLayer" text="@.layer_new_reference_layer_from_clipboard">
<param name="reference" value="true" />
<param name="fromClipboard" value="true" />
</item>
</menu>
<item command="RemoveLayer" text="@.layer_delete_layer" />
<item command="BackgroundFromLayer" text="@.layer_background_from_layer" />
<item command="LayerFromBackground" text="@.layer_layer_from_background" />
@ -784,11 +811,6 @@
<item command="FlattenLayers" text="@.layer_flatten_visible">
<param name="visibleOnly" value="true" />
</item>
<separator />
<item command="NewLayer" text="@.layer_add_reference_layer">
<param name="reference" value="true" />
<param name="fromFile" value="true" />
</item>
</menu>
<menu text="@.frame">
<item command="FrameProperties" text="@.frame_properties">

View File

@ -211,7 +211,7 @@ AddColor_Specific = Specific
AdvancedMode = Advanced Mode
AutocropSprite = Trim Sprite
AutocropSprite_ByGrid = Trim Sprite by Grid
BackgroundFromLayer = Background From Layer
BackgroundFromLayer = Background from Layer
BrightnessContrast = Adjust Brightness/Contrast
Cancel = Cancel Current Operation
CanvasSize = Canvas Size
@ -295,7 +295,7 @@ InvertColor = Invert Color
InvertMask = Invert Selection
KeyboardShortcuts = Keyboard Shortcuts
Launch = Launch
LayerFromBackground = Layer From Background
LayerFromBackground = Layer from Background
LayerLock = Lock Layers
LayerOpacity = Set Layer Opacity to {0} ({1}%)
LayerProperties = Layer Properties
@ -332,7 +332,7 @@ MoveMask_Boundaries = Selection Boundaries
MoveMask_Content = Selection Content
NewBrush = New Brush
NewFile = New File
NewFile_FromClipboard = New File (From Clipboard)
NewFile_FromClipboard = New File from Clipboard
NewFrame = New Frame
NewFrame_NewEmptyFrame = New Empty Frame
NewFrame_DuplicateCels = Duplicate Linked Cels
@ -343,8 +343,10 @@ NewLayer_BeforeActiveLayer = New {} Below
NewLayer_Layer = Layer
NewLayer_Group = Group
NewLayer_ReferenceLayer = Reference Layer
NewLayer_FromClipboard = {} (From Clipboard)
NewSpriteFromSelection = New Sprite From Selection
NewLayer_FromClipboard = {} from Clipboard
NewLayer_ViaCopy = {} via Copy
NewLayer_ViaCut = {} via Cut
NewSpriteFromSelection = New Sprite from Selection
OpenBrowser = Open Browser
OpenFile = Open Sprite
OpenGroup = Open/Close Group
@ -739,7 +741,7 @@ edit_shift_right = &Right
edit_shift_up = &Up
edit_shift_down = &Down
edit_new_brush = New &Brush
edit_new_sprite_from_selection = &New Sprite from Selection
edit_new_sprite_from_selection = &New Sprite From Selection
edit_replace_color = R&eplace Color...
edit_invert_color = &Invert...
edit_adjustments = Ad&justments
@ -777,8 +779,14 @@ layer_properties = &Properties...
layer_visible = &Visible
layer_lock_layers = Loc&k Layers
layer_open_group = &Open Group
layer_new = &New...
layer_new_layer = &New Layer
layer_new_group = New &Group
layer_new_layer_from_clipboard = New Layer from Clip&board
layer_new_layer_via_copy = New Layer via &Copy
layer_new_layer_via_cut = New Layer via Cu&t
layer_new_reference_layer_from_file = New &Reference Layer from File
layer_new_reference_layer_from_clipboard = New R&eference Layer from Clipboard
layer_delete_layer = Delete Laye&r
layer_background_from_layer = &Background from Layer
layer_layer_from_background = &Layer from Background
@ -786,7 +794,6 @@ layer_duplicate = &Duplicate
layer_merge_down = &Merge Down
layer_flatten = &Flatten
layer_flatten_visible = Flatten Vi&sible
layer_add_reference_layer = Add R&eference Layer
frame = F&rame
frame_properties = Frame &Properties...
frame_cel_properties = &Cel Properties...

View File

@ -10,7 +10,9 @@
#endif
#include "app/app.h"
#include "app/cmd/clear_mask.h"
#include "app/cmd/move_layer.h"
#include "app/cmd/trim_cel.h"
#include "app/commands/command.h"
#include "app/commands/commands.h"
#include "app/commands/new_params.h"
@ -26,6 +28,7 @@
#include "app/ui/status_bar.h"
#include "app/ui_context.h"
#include "app/util/clipboard.h"
#include "app/util/new_image_from_mask.h"
#include "doc/layer.h"
#include "doc/primitives.h"
#include "doc/sprite.h"
@ -52,6 +55,8 @@ struct NewLayerParams : public NewParams {
Param<bool> ask { this, false, "ask" };
Param<bool> fromFile { this, false, { "fromFile", "from-file" } };
Param<bool> fromClipboard { this, false, "fromClipboard" };
Param<bool> viaCut { this, false, "viaCut" };
Param<bool> viaCopy { this, false, "viaCopy" };
Param<bool> top { this, false, "top" };
Param<bool> before { this, false, "before" };
};
@ -70,6 +75,7 @@ protected:
std::string onGetFriendlyName() const override;
private:
void adjustRefCelBounds(Cel* cel, gfx::RectF bounds);
std::string getUniqueLayerName(const Sprite* sprite) const;
int getMaxLayerNum(const Layer* layer) const;
std::string layerPrefix() const;
@ -102,13 +108,22 @@ void NewLayerCommand::onLoadParams(const Params& commandParams)
bool NewLayerCommand::onEnabled(Context* context)
{
return context->checkFlags(ContextFlags::ActiveDocumentIsWritable |
ContextFlags::HasActiveSprite)
&& (!params().fromClipboard()
if (!context->checkFlags(ContextFlags::ActiveDocumentIsWritable |
ContextFlags::HasActiveSprite))
return false;
#ifdef ENABLE_UI
|| (clipboard::get_current_format() == clipboard::ClipboardImage)
if (params().fromClipboard() &&
clipboard::get_current_format() != clipboard::ClipboardImage)
return false;
#endif
);
if ((params().viaCut() ||
params().viaCopy()) &&
!context->checkFlags(ContextFlags::HasVisibleMask))
return false;
return true;
}
namespace {
@ -124,6 +139,7 @@ private:
void NewLayerCommand::onExecute(Context* context)
{
ContextWriter writer(context);
Site site = context->activeSite();
Doc* document(writer.document());
Sprite* sprite(writer.sprite());
std::string name;
@ -180,7 +196,7 @@ void NewLayerCommand::onExecute(Context* context)
LayerGroup* parent = sprite->root();
Layer* activeLayer = writer.layer();
SelectedLayers selLayers = writer.site()->selectedLayers();
SelectedLayers selLayers = site.selectedLayers();
if (activeLayer) {
if (activeLayer->isGroup() &&
activeLayer->isExpanded() &&
@ -243,7 +259,7 @@ void NewLayerCommand::onExecute(Context* context)
}
// Put all selected layers inside the group
if (m_type == Type::Group && writer.site()->inTimeline()) {
if (m_type == Type::Group && site.inTimeline()) {
LayerGroup* commonParent = nullptr;
layer_t sameParents = 0;
for (Layer* l : selLayers) {
@ -314,14 +330,8 @@ void NewLayerCommand::onExecute(Context* context)
if (cel) {
if (layer->isReference()) {
gfx::RectF bounds(0, 0, pasteSpr->width(), pasteSpr->height());
double scale = MIN(double(sprite->width()) / bounds.w,
double(sprite->height()) / bounds.h);
bounds.w *= scale;
bounds.h *= scale;
bounds.x = sprite->width()/2 - bounds.w/2;
bounds.y = sprite->height()/2 - bounds.h/2;
cel->setBoundsF(bounds);
adjustRefCelBounds(
cel, gfx::RectF(0, 0, pasteSpr->width(), pasteSpr->height()));
}
else {
cel->setPosition(sprite->width()/2 - pasteSpr->width()/2,
@ -334,8 +344,43 @@ void NewLayerCommand::onExecute(Context* context)
// Paste new layer from clipboard
else if (params().fromClipboard() && layer->isImage()) {
clipboard::paste(context, false);
if (layer->isReference()) {
if (Cel* cel = layer->cel(site.frame())) {
adjustRefCelBounds(
cel, cel->boundsF());
}
}
}
#endif // ENABLE_UI
// Paste new layer from selection
else if ((params().viaCut() || params().viaCopy())
&& layer->isImage()
&& document->isMaskVisible()) {
const doc::Mask* mask = document->mask();
ASSERT(mask);
ImageRef image(new_image_from_mask(site, mask, true));
if (image) {
Cel* cel = api.addCel(static_cast<LayerImage*>(layer),
site.frame(), image);
if (cel) {
gfx::Point pos = mask->bounds().origin();
cel->setPosition(pos.x, pos.y);
}
if (params().viaCut() &&
site.cel() && site.layer()) {
tx(new cmd::ClearMask(site.cel()));
if (site.layer()->isTransparent()) {
// If the cel wasn't deleted by cmd::ClearMask, we trim it.
cel = site.layer()->cel(site.frame());
if (cel)
tx(new cmd::TrimCel(cel));
}
}
}
}
tx.commit();
}
@ -364,9 +409,25 @@ std::string NewLayerCommand::onGetFriendlyName() const
text = fmt::format(Strings::commands_NewLayer(), layerPrefix());
if (params().fromClipboard())
text = fmt::format(Strings::commands_NewLayer_FromClipboard(), text);
if (params().viaCopy())
text = fmt::format(Strings::commands_NewLayer_ViaCopy(), text);
if (params().viaCut())
text = fmt::format(Strings::commands_NewLayer_ViaCut(), text);
return text;
}
void NewLayerCommand::adjustRefCelBounds(Cel* cel, gfx::RectF bounds)
{
Sprite* sprite = cel->sprite();
double scale = MIN(double(sprite->width()) / bounds.w,
double(sprite->height()) / bounds.h);
bounds.w *= scale;
bounds.h *= scale;
bounds.x = sprite->width()/2 - bounds.w/2;
bounds.y = sprite->height()/2 - bounds.h/2;
cel->setBoundsF(bounds);
}
std::string NewLayerCommand::getUniqueLayerName(const Sprite* sprite) const
{
return fmt::format("{} {}",