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

View File

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

View File

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