Skip to content

Commit

Permalink
Add context menu to copy, paste and clear frame
Browse files Browse the repository at this point in the history
  • Loading branch information
Mignari committed Feb 26, 2022
1 parent b7ce218 commit f67e588
Show file tree
Hide file tree
Showing 4 changed files with 278 additions and 5 deletions.
62 changes: 62 additions & 0 deletions src/otlib/components/FrameSpriteGroup.as
@@ -0,0 +1,62 @@
package otlib.components
{
import flash.ui.ContextMenu;

import spark.components.Button;
import spark.components.Group;

import otlib.core.otlib_internal;
import otlib.events.FrameSpriteGroupEvent;

public class FrameSpriteGroup extends Group
{
//--------------------------------------------------------------------------
// PROPERTIES
//--------------------------------------------------------------------------

[Bindable]
public var editor:ThingTypeEditor;

public function FrameSpriteGroup()
{

}

//--------------------------------------------------------------------------
// METHODS
//--------------------------------------------------------------------------

//--------------------------------------
// Internal
//--------------------------------------

otlib_internal function onContextMenuDisplaying(button:Button, menu:ContextMenu):void
{
if (!editor.hasTransferData)
menu.items[2].enabled = false; // Paste Frame
}

otlib_internal function onContextMenuSelect(button:Button, type:String):void
{
switch(type) {
case FrameSpriteGroupEvent.CLEAR_SPRITE:
var frame:int = editor.currentFrame;
var index:int = parseInt(button.label);
editor.clearSprite(frame, index);
break;

case FrameSpriteGroupEvent.COPY_FRAME:
editor.copyFrame(editor.currentFrame);
break;

case FrameSpriteGroupEvent.PASTE_FRAME:
editor.pasteFrame(editor.currentFrame);
break;

case FrameSpriteGroupEvent.CLEAR_FRAME:
editor.clearFrame(editor.currentFrame);
break;
}
}
}
}
82 changes: 78 additions & 4 deletions src/otlib/components/ThingTypeEditor.mxml
Expand Up @@ -92,6 +92,8 @@ THE SOFTWARE.
private var _previewMode:Boolean;
private var _lastAnimationFrame:uint;
private var _virtualTransferArea:Vector.<SpriteData>;
//--------------------------------------
// Getters / Setters
//--------------------------------------
Expand Down Expand Up @@ -122,6 +124,20 @@ THE SOFTWARE.
}
}
public function get currentFrame():int
{
if(_thingData)
return animationSlider.value;
return -1;
}
public function get hasTransferData():Boolean
{
if(_thingData && _virtualTransferArea)
return true;
return false;
}
//--------------------------------------------------------------------------
// METHODS
//--------------------------------------------------------------------------
Expand Down Expand Up @@ -185,6 +201,62 @@ THE SOFTWARE.
invalidateProperties();
}
public function clearSprite(frame:int, index:int):void
{
if (!_thingData || frame < 0 || frame >= _thingBinding.frames || index < 0 || index >= _thingBinding.spriteIndex.length)
return;
_thingBinding.setSprite(index, new SpriteData());
updatePreview();
}
public function copyFrame(frame:int):void
{
if (!_thingData || frame < 0 || frame >= _thingBinding.frames)
return;
var length:int = buttonsContainer.numElements;
_virtualTransferArea = new Vector.<SpriteData>(length, true);
for (var i:int = 0; i < length; i++) {
var button:Button = buttonsContainer.getElementAt(i) as Button;
var index:int = parseInt(button.label);
_virtualTransferArea[i] = _thingBinding.sprites[index].clone();
}
}
public function pasteFrame(frame:int):void
{
if (!_thingData || frame < 0 || frame >= _thingBinding.frames)
return;
if (!_virtualTransferArea) return;
var length:int = buttonsContainer.numElements;
if (_virtualTransferArea.length != length) return;
for (var i:int = 0; i < length; i++) {
var button:Button = buttonsContainer.getElementAt(i) as Button;
var index:int = parseInt(button.label);
_thingBinding.setSprite(index, _virtualTransferArea[i]);
}
updatePreview();
}
public function clearFrame(frame:int):void
{
if (!_thingData || frame < 0 || frame >= _thingBinding.frames)
return;
var sprite:SpriteData = new SpriteData();
var length:int = buttonsContainer.numElements;
for (var i:int = 0; i < length; i++) {
var button:Button = buttonsContainer.getElementAt(i) as Button;
var index:int = parseInt(button.label);
_thingBinding.setSprite(index, sprite);
}
updatePreview();
}
//--------------------------------------
// Override Protected
//--------------------------------------
Expand Down Expand Up @@ -220,6 +292,7 @@ THE SOFTWARE.
_lastAnimationFrame = 0;
thingView.thingData = thingData;
_virtualTransferArea = null;
_thingBinding.reset();
animationSlider.value = 0;
mountSlider.value = 0;
Expand Down Expand Up @@ -929,10 +1002,11 @@ THE SOFTWARE.
change="thingViewFrameChangeHandler(event)"
complete="thingViewAnimationCompleteHandler(event)"/>

<s:Group id="buttonsContainer"
updateComplete="drawCropSize()"
width="{bitmapView.width}"
height="{bitmapView.height}"/>
<otlib:FrameSpriteGroup id="buttonsContainer"
editor="{this}"
updateComplete="drawCropSize()"
width="{bitmapView.width}"
height="{bitmapView.height}"/>
</s:Group>
</s:Group>

Expand Down
79 changes: 78 additions & 1 deletion src/otlib/components/skins/SpriteButtonSkin.mxml
Expand Up @@ -25,13 +25,90 @@ THE SOFTWARE.
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:fb="http://ns.adobe.com/flashbuilder/2009"
minWidth="23"
minHeight="23">
minHeight="23"
creationComplete="creationCompleteHandler(event)">

<!-- host component -->
<fx:Metadata>
<![CDATA[[HostComponent("spark.components.Button")]]]>
</fx:Metadata>

<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
import mx.resources.IResourceManager;
import mx.resources.ResourceManager;
import spark.components.Button;
import otlib.components.FrameSpriteGroup;
import otlib.core.otlib_internal;
import otlib.events.FrameSpriteGroupEvent;
use namespace otlib_internal;
//--------------------------------------------------------------------------
// METHODS
//--------------------------------------------------------------------------
//--------------------------------------
// Event Handlers
//--------------------------------------
private function creationCompleteHandler(event:FlexEvent):void
{
if (owner is Button) {
var cm:ContextMenu = createContextMenu();
cm.addEventListener(Event.SELECT, contextMenuSelectHandler);
cm.addEventListener(Event.DISPLAYING, contextMenuDisplayingHandler);
Button(owner).contextMenu = cm;
}
}
private function contextMenuDisplayingHandler(event:Event):void
{
if (owner is Button) {
var parent:DisplayObjectContainer = Button(owner).parent;
if (parent && parent is FrameSpriteGroup) {
FrameSpriteGroup(parent).onContextMenuDisplaying(Button(owner), ContextMenu(event.target));
}
}
}
private function contextMenuSelectHandler(event:Event):void
{
if (owner is Button) {
var parent:DisplayObjectContainer = Button(owner).parent;
if (parent && parent is FrameSpriteGroup) {
var type:String = NativeMenuItem(event.target).data as String;
FrameSpriteGroup(parent).onContextMenuSelect(Button(owner), type);
}
}
}
//--------------------------------------------------------------------------
// STATIC
//--------------------------------------------------------------------------
private static function createContextMenu():ContextMenu
{
var resource:IResourceManager = ResourceManager.getInstance();
var clearSpriteMenu:ContextMenuItem = new ContextMenuItem("Clear Sprite");
clearSpriteMenu.data = FrameSpriteGroupEvent.CLEAR_SPRITE;
var copyFrameMenu:ContextMenuItem = new ContextMenuItem("Copy Frame", true);
copyFrameMenu.data = FrameSpriteGroupEvent.COPY_FRAME;
var pasteFrameMenu:ContextMenuItem = new ContextMenuItem("Paste Frame");
pasteFrameMenu.data = FrameSpriteGroupEvent.PASTE_FRAME;
var clearFrameMenu:ContextMenuItem = new ContextMenuItem("Clear Frame");
clearFrameMenu.data = FrameSpriteGroupEvent.CLEAR_FRAME;
var menu:ContextMenu = new ContextMenu();
menu.customItems = [clearSpriteMenu, copyFrameMenu, pasteFrameMenu, clearFrameMenu];
return menu;
}
]]>
</fx:Script>

<!-- states -->
<s:states>
<s:State name="up" />
Expand Down
60 changes: 60 additions & 0 deletions src/otlib/events/FrameSpriteGroupEvent.as
@@ -0,0 +1,60 @@
/*
* Copyright (c) 2014-2022 Object Builder <https://github.com/ottools/ObjectBuilder>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

package otlib.events
{
import flash.events.Event;

public class FrameSpriteGroupEvent extends Event
{
//--------------------------------------------------------------------------
// CONSTRUCTOR
//--------------------------------------------------------------------------

public function FrameSpriteGroupEvent(type:String)
{
super(type);
}

//--------------------------------------------------------------------------
// METHODS
//--------------------------------------------------------------------------

//--------------------------------------
// Override Public
//--------------------------------------

override public function clone():Event
{
return new FrameSpriteGroupEvent(this.type);
}

//--------------------------------------------------------------------------
// STATIC
//--------------------------------------------------------------------------

public static const CLEAR_SPRITE:String = "clearSprite";
public static const COPY_FRAME:String = "copyFrame";
public static const PASTE_FRAME:String = "pasteFrame";
public static const CLEAR_FRAME:String = "clearFrame";
}
}

0 comments on commit f67e588

Please sign in to comment.