Simple drag and drop application where mc is dragged out of one parent mc and dropped into another parent mc.
All works OK until I added 2 text boxes to the mc's -- one is a non-selectable dynamic text box (a label) which is set by the code, the other is selectable input text that the user can amend.The text boxes cause 开发者_StackOverflowsome problems:
- Finger cursor disappears when user hovers over the section of the mc that contains the text fields (even non-selectable text??)
- When the user trys to drag the mc by inadvertantly click-dragging anywhere within both text areas it causes this error: TypeError: Error #1034: Type Coercion failed: cannot convert flash.text::TextField@2374a381 to flash.display.MovieClip (same error appears for both text boxes)
- The input text box may confuse the user - how do they sometimes click to drag and sometimes click to amend? I'm thinking the input text needs to be clearly a non-click-drag 'zone' in the mc. (hope that makes sense)
Not sure, but maybe I need to create an overlay area within the mc that is click-detected for the drag?
Any other suggestions?Here's the relevant bits of code:
var itemArray:Array = [
{iname:"police",ititle:"POLICE OFFICER"},
{iname:"insurance_assessor",ititle:"INSURANCE ASSESSOR"},
{iname:"estimator",ititle:"ESTIMATOR"}
];
for (var i:int=0; i < itemArray.length; i++)
{
var itemname:String = itemArray[i].iname;
var curritem:MovieClip = MovieClip(scrollitems.getChildByName(itemname));
if (curritem != null)
{
curritem.ititle.text = itemArray[i].ititle;
curritem.addEventListener(MouseEvent.MOUSE_DOWN, pickUp);
curritem.addEventListener(MouseEvent.MOUSE_UP, dropIt);
curritem.buttonMode = true;
}
}
function pickUp(event:MouseEvent):void
{
var dragIt:MovieClip = MovieClip(event.target); //type casting
var dragPoint:Point = dragIt.parent.localToGlobal(new Point(dragIt.x,dragIt.y));
dragIt.parent.removeChild(dragIt); // remove item from current parent mc
stage.addChild(dragIt); //temp add to stage
dragIt.x = dragPoint.x;
dragIt.y = dragPoint.y;
dragIt.startDrag();
}
The problem that you have is that the Textfields are mouseEnabled. The label field mouseEnabled property should be set to false , as for the other TextField I can think of two solutions.
The simpler approach (as you already mention ) could be to create a draggable hitArea within your mc , similar to the top of a window on a desktop , you could add your event listeners to this area so that the mc can only be dragged from there.
A second approach could be to set your mc's mouseChildren property to false on a MouseDown and back to true on a MouseUp. This shouldn't interfere with a user entering text in your input textfield.
Simply add event listeners (focus_in & out) to the text fields, make the functions and remove the events of the drags on focus_in and give them back on focus_out. Like this:
drag.textFieldName.addEventListener(FocusEvent.FOCUS_IN, setFIn);
drag.textFieldName.addEventListener(FocusEvent.FOCUS_OUT, setFOut);
function setFIn(focus:FocusEvent):void {
var item = focus.target.parent;
item.removeEventListener(MouseEvent.MOUSE_DOWN, MCdrag_press);
item.removeEventListener(MouseEvent.MOUSE_UP, MCdrag_release);
}
function setFOut(focus:FocusEvent):void {
var item = focus.target.parent;
item.addEventListener(MouseEvent.MOUSE_DOWN, MCdrag_press);
item.addEventListener(MouseEvent.MOUSE_UP, MCdrag_release);
}
If the user ever touches the text areas, it doesn't drag it by mistake, or even show up the flash error. Cheers
Issue arises from the fact that MOUSE_DOWN is used to start editing TextFields and also start dragging your MovieClip. Thus if you could differentiate whether the clicked object is a TextField you can come out of this ambiguity like following:
var curritem:MovieClip = new MovieClip();
curritem.Width = 125;
curritem.Height = 25;
var fontFormat:TextFormat = new TextFormat( );
fontFormat.font = "Arial";
var tf:TextField = new TextField();
tf.type = TextFieldType.INPUT;
tf.setTextFormat(fontFormat);
tf.text = "Some Text";
curritem.addChild(tf);
curritem.addEventListener(MouseEvent.MOUSE_DOWN, startMove);
curritem.addEventListener(MouseEvent.MOUSE_UP, stopMove);
function startMove(act:MouseEvent):void
{
if (getQualifiedClassName(act.target) == "flash.text::TextField")
{
trace("text is down");
act.target.parent.startDrag();
}
else
{
trace("movieclip is down");
act.target.startDrag();
}
}
function stopMove(act:MouseEvent):void
{
if (getQualifiedClassName(act.target) == "flash.text::TextField")
{
trace("text is up");
act.target.parent.stopDrag();
}
else
{
trace("movieclip is up");
act.target.stopDrag();
}
}
精彩评论