0 Replies Latest reply on Mar 16, 2010 12:33 PM by Eli7BBB

    Problems with the DragManager....

    Eli7BBB

      Hi all,

       

      I am developing a component for a drag-drop-quiz. The idea is that the questions and answers will be uploaded from an external XML, which has the following structure:

       

      <?xml version="1.0" encoding="utf-8"?>

      <ddquiz lang='language' dir="rtl">

       

      <snt id='0' label='The following example shows how you can export a TextFlow object in Flex 4 by using the TextConverter 88class88'></snt>

       

          <snt id='0' label='Learn how to use the FLARManager library to make creating AR applications a 88breeeze88'></snt>

           <snt id='1' label='Learn about all of the new 88features88 coming in Flash CS5 in addition to the iPhone workflow'></snt>

       

      <snt id='2' label='The HALO application model provides a 88core88 set of components, layouts, themes, behaviors'></snt>

      <snt id='3' label='88Here88 are links to books and resources of interest in the area of experience'></snt>

      <snt id='4' label='This is where the power of Flex gets 88interesting88'></snt>

      </ddquiz>

       

      The answers are marked with the '88' before an after...

       

      There is a parser which, works on the loaded xml and position, first  the bank of answer words, followed by sentences with an empty space where the answer should be...

       

      All is working, EXCEPT (of course....) when the user drag and drops the word (it's a text area), I am getting the x and y positions from the target which init the DragEvent.DRAG_DROP event. The x position is OK but the Y position is always 0.

       

      I am attaching my code:

       

      The main mxml is:

       

      <?xml version="1.0" encoding="utf-8"?>

      <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" backgroundColor="0x0D65D9" layout="absolute" creationComplete="onComplete(event)">

       

      <mx:Style>

      TextArea {

         fontFamily: Tahoma;

         fontSize: 16;

         paddingLeft: 2;

         paddingRight: 2;

         textIndent: 1;

         backgroundAlpha: 0.67;

         backgroundColor: #66cccc;

         borderColor: #33ccff;

         borderThickness: 2;

         dropShadowEnabled: false;

         cornerRadius: 4;

      }

       

              Button {

         fontFamily: Tahoma;

         fontSize: 16;

      }

       

      Panel {

      headerHeight: 38;

      titleStyleName: "qPpanelTitle";

      }

       

      .qPpanelTitle {

         letterSpacing: 2;

         textAlign: center;

         fontFamily: Tahoma;

         fontSize: 16;

         fontWeight: normal;

      }

       

          </mx:Style>

      <mx:Script>

      <![CDATA[

      import mx.controls.Spacer;

      import mx.core.IUIComponent;

      import mx.core.UIComponent;

      import mx.events.IndexChangedEvent;

      import mx.events.ItemClickEvent;

      import mx.events.DragEvent;

      import mx.controls.Button;

      import mx.collections.ArrayCollection;

      import mx.managers.DragManager;

                  import mx.core.DragSource;

                  import mx.core.UITextFormat;

       

      import classes.DDQuizClass;

      import classes.events.QuizDataEvent;

       

      private static const FORMAT:String = "txt";

       

      [Bindable]

      private var answersDP:ArrayCollection;

       

      [Bindable]

      private var dragInit:Boolean;

       

      [Bindable]

      private var ansButArray:Array;

       

      [Bindable]

      private var sntsArray:Array;

       

      [Bindable]

      private var sntsBoxArray:Array;

       

      private var dragInitiator:TextArea;

      private var dragSource:DragSource;

       

       

      private function onComplete(event:Event):void {

      dragInit = false;

      var ddQ:DDQuizClass = new DDQuizClass();

      ddQ.addEventListener(QuizDataEvent.QUIZ_DATA_EVENT,positionData);

      ddQ.initDDQ("data/quiz.xml");

      }

       

      private function positionData(event:QuizDataEvent):void {

      logMsg("positionData");

      var dataArr:Array = event.params as Array;

      var maxAnsLen:int=0;

      answersDP = new ArrayCollection();

      ansButArray = new Array();

      sntsArray = new Array();

      sntsBoxArray = new Array();

      // ans box gets the answers in random order

      // calculate the width of the longest word

      var ansDP:Array = new Array();

      for  (var i:int=0;i<dataArr.length;i++) {

      for (var j:int=0;j<dataArr[i].patterns.length;j++) {

      ansDP.push(dataArr[i].patterns[j]);

      if (String(dataArr[i].patterns[j]).length > maxAnsLen) {

      maxAnsLen = String(dataArr[i].patterns[j]).length;

      }

      var txt:TextArea = new TextArea();

      txt.text = dataArr[i].patterns[j];

      ansButArray.push(txt);

      }

      sntsArray.push(dataArr[i].parts);

      }

      // sent box gets the sentences in random order dont add the ans clause

       

      var finalArray:Array = shuffleArray(ansButArray);

      /* for (i=0;i<finalArray.length;i++) {

      ansBox.addChild(finalArray[i]);

      } */

      addButtons2Stage(finalArray);

      // now add the sentences

      // prepare a spacer

      var sp:Spacer = new Spacer();

      sp.width = 10;

      for (i=0;i<sntsArray.length;i++) {

      var hb:HBox = new HBox();

       

      for (j=0;j<sntsArray[i].length;j++) {

      var t:TextField = new TextField();

      t.text = sntsArray[i][j];

      var txtPl:TextArea = new TextArea();

      txtPl.verticalScrollPolicy = 'false';

      txtPl.horizontalScrollPolicy = 'false';

      txtPl.selectable = false;

       

       

      if (isPattern(t.text) == true) {

      // put the longest place holder

      txtPl.addEventListener(DragEvent.DRAG_ENTER,dragEnterHandler);

      txtPl.addEventListener(DragEvent.DRAG_DROP,dragDropHandler);

      txtPl.addEventListener(DragEvent.DRAG_OVER,onDragOverHandler);

       

      txtPl.width = maxAnsLen*getWidth(maxAnsLen);

       

      } else {

      // put the string as is

      txtPl.text = t.text;

      txtPl.width = String(sntsArray[i][j]).length*getWidth(String(sntsArray[i][j]).length);

       

      }

      hb.addChild(sp);

      hb.addChild(txtPl);

      hb.addChild(sp);

       

      }

      sentBox.addChild(hb);

      sntsBoxArray.push(hb);

      }

      }

       

       

      private function getWidth(n:int):int {

      if (n < 10) {

      return (10.8);

      }

      if (n < 15) {

      return (10.5);

      }

      if (n < 25) {

      return (10.4);

      }

      if (n < 35) {

      return (10.3);

      }

      if (n < 45) {

      return (10.2);

      }

      if (n < 55) {

      return (10.1);

      }

      if (n < 65) {

      return (10.0);

      }

      if (n < 75) {

      return (9.9);

      }

      if (n < 85) {

      return (9.8);

      }

      if (n < 95) {

      return (9.7);

      }

      return(9.0);

      }

      private function isPattern(s:String):Boolean {

      for (var i:int;i<ansButArray.length;i++) {

      if (s == ansButArray[i].text) {

      return true;

      }

      }

      return false;

      }

       

      private function addButtons2Stage(a:Array):void {

      var hb:HBox = new HBox();

      for (var i:int=0;i<a.length;i++) {

      var bt:TextArea = new TextArea();

      bt.text = a[i].text;

      bt.selectable = false;

      bt.verticalScrollPolicy = 'false';

      bt.width = String(bt.text).length+100;

      bt.addEventListener(MouseEvent.MOUSE_MOVE,onStartDrag);

      hb.addChild(bt);

      }

      sentBox.addChild(hb);

      var sp:Spacer = new Spacer();

      sp.height = 20;

      sentBox.addChild(sp);

      }

       

      private function shuffleArray(arr:Array):Array {

      var arr2:Array = [];

      var arr1:Array = new Array();

      for (var i:int=0;i<arr.length;i++) {

      arr1[i] = arr[i];

      }

      while (arr1.length > 0) {

      arr2.push(arr1.splice(Math.round(Math.random() * (arr1.length - 1)), 1)[0]);

      }

      return arr2;

      }

      private function onStartDrag(event:MouseEvent):void {

       

                      dragInitiator = TextArea(event.currentTarget);

       

                      // create the dragSource - data for the dragInitiator

                      dragSource = new DragSource();

                      var buttonData:Object = new Object();

      buttonData.width = event.currentTarget.width;

      buttonData.height= event.currentTarget.height;

      buttonData.label = event.currentTarget.text;

      buttonData.backgroundColor = dragInitiator.getStyle( "backgroundColor" );

      dragSource.addData( buttonData, FORMAT );

      // create the proxy - duplicate of the button which is dragged

                      var txtProxy:TextArea = new TextArea();

                      txtProxy.width = buttonData.width;

      txtProxy.height = buttonData.height;

      txtProxy.verticalScrollPolicy = 'false';

      txtProxy.text = buttonData.label;

              DragManager.doDrag(dragInitiator, dragSource, event,txtProxy, 0, 0, .5);

       

                  dragInit = true;

      }

       

                  private function dragEnterHandler(event:DragEvent):void {

                  DragManager.acceptDragDrop(TextArea(event.currentTarget));

                  }

       

                  // The dragDrop event handler for the Canvas container

                  // sets the Image control's position by

                  // "dropping" it in its new location.

                  private function dragDropHandler(event:DragEvent):void {

                  var dropTarget:IUIComponent = event.currentTarget as IUIComponent;

       

                      TextArea(event.dragInitiator).x = dropTarget.x;//_stageX;// TextArea(event.currentTarget).x;

                      TextArea(event.dragInitiator).y = dropTarget.y;//_stageY;// TextArea(event.currentTarget).y;

                      DragManager.acceptDragDrop( TextArea(event.currentTarget) );

                  }

       

                  private function onDragOverHandler(event:DragEvent):void {

                      DragManager.showFeedback(DragManager.COPY);

                  }

       

                  private function onSubmit(event:Event):void {

                 

                  }

       

                  private function onCancel(event:Event):void {

                 

                  }

       

      public function logMsg(s:String):void {

      logger.text += s + '\n';

      }

      ]]>

      </mx:Script>

      <mx:Panel id="mainPanel" title="Drag-n-Drop Quiz" verticalCenter="0" horizontalCenter="0" width="80%" height="80%" backgroundAlpha=".5" backgroundColor="0x5391E6">

       

      <mx:VBox id="sentBox" backgroundColor="0x70A6FC" width="100%" height="80%">

       

      </mx:VBox>

      <mx:Spacer height="5%"/>

      <mx:HBox id='submit_cancel_container' height="10%" width="100%" >

      <mx:Spacer width="10%"/>

      <mx:Button id='cancel_btn' label="Cancel" labelPlacement="bottom" click="onCancel(event)"/>

      <mx:Spacer width="80%"/>

      <mx:Button id="submit_btn" label="Submit" labelPlacement="bottom" click="onSubmit(event)"/>

      <mx:Spacer width="10%"/>

      </mx:HBox>

      <mx:TextArea id='logger' width="50%" height="20%"/>

      </mx:Panel>

      </mx:Application>

      The data file should be in the data folder
      <?xml version="1.0" encoding="utf-8"?>
      <ddquiz lang='language' dir="rtl">
      <snt id='0' label='The following example shows how you can export a TextFlow object in Flex 4 by using the TextConverter 88class88'></snt>
          
          <snt id='0' label='Learn how to use the FLARManager library to make creating AR applications a 88breeeze88'></snt>
           <snt id='1' label='Learn about all of the new 88features88 coming in Flash CS5 in addition to the iPhone workflow'></snt>
      <snt id='2' label='The HALO application model provides a 88core88 set of components, layouts, themes, behaviors'></snt>
      <snt id='3' label='88Here88 are links to books and resources of interest in the area of experience'></snt>
      <snt id='4' label='This is where the power of Flex gets 88interesting88'></snt>
      </ddquiz>

       

      The class which loads and parses the xml should be in the classes folder

       

      package classes

      {

      import classes.events.QuizDataEvent;

       

      import flash.display.MovieClip;

      import flash.events.Event;

      import flash.events.IOErrorEvent;

      import flash.net.URLLoader;

      import flash.net.URLLoaderDataFormat;

      import flash.net.URLRequest;

       

      import mx.core.Application;

      public class DDQuizClass extends MovieClip {

       

      private var sAns:Array;

      private var sSnt:Array;

      private var pattern:String = '88';

       

      public function DDQuizClass():void {

      super();

      }

       

      public function initDDQ(fl:String):void {

       

       

      sAns = new Array();

      sSnt = new Array();

       

      Application.application.logMsg ('begin Loading');

       

      var quizRequest:URLRequest = new URLRequest(fl);

       

       



      var quizLoader:URLLoader = new URLLoader();

      quizLoader.dataFormat = URLLoaderDataFormat.TEXT;


       

      quizLoader.addEventListener(Event.COMPLETE, onComplete);

      quizLoader.addEventListener(IOErrorEvent.IO_ERROR, onIoError);

       

      quizLoader.load(quizRequest);

      }

       

      private function onIoError(event:IOErrorEvent):void {

      Application.application.logMsg ('onIoError '+event.text);

      }

       

      private function onComplete(event:Event):void {

       

      event.currentTarget.removeEventListener(IOErrorEvent.IO_ERROR, onIoError);

      event.currentTarget.removeEventListener(Event.COMPLETE, onComplete);

      //Application.application.logMsg ('onComplete ' + event.currentTarget);

      var q:XML = new XML( event.target.data );

       

       

      var wArr:Array = new Array();

      // I want to create an array of objects

      // each object will have

      // array of the whole sentence

      // array of the patterns

      for each (var textNode:XML in q.* ) {

      var s:String = textNode.@label;

      var tempObject:Object = new Object();

      var parts:Array = s.split(pattern);

      // if I have an empty part which can be in the last position or first - get rid of it

      if (parts[0] == "") {

      parts.shift();

      } else

      if (parts[parts.length-1] == "") {

      parts.pop();

      }

      var partsInd:Array = new Array();

      var strArr:Array = new Array();

      var fIndex:int = 0;

      var startIndex:int = 0;

      while (s.indexOf(pattern, startIndex) != -1) {

      if (fIndex%2 == 1) {

      partsInd.push(s.indexOf(pattern, startIndex));

      strArr.push(s.substring(partsInd[0]+pattern.length,partsInd[1]));

      partsInd.splice(0,2);

      } else {

      partsInd.push(s.indexOf(pattern, startIndex));

      }

      startIndex = s.indexOf(pattern, startIndex) + 1;

      fIndex++;

      }

      // strArr is the array of patterns

      // partys is the array of the parts of the sentence

      tempObject.patterns = strArr;

      tempObject.parts = parts;

       

      //Application.application.logMsg( 'tempObject.patterns ' + tempObject.patterns + ' tempObject.parts ' + tempObject.parts);

      wArr.push(tempObject);

       

       

       

       

      }

       

      var quizDataEventRec:QuizDataEvent = new QuizDataEvent('quizDataReceived',wArr);

      dispatchEvent(quizDataEventRec);

      }

      }

      }

       

      The event class which is dispatched when the parse is complete should be in the classes/events folder

       

      package classes.events

      {

      import flash.events.Event;


      public class QuizDataEvent extends Event {

       

      public var params:Object;

      public static const QUIZ_DATA_EVENT:String = 'quizDataReceived';

       

      public function QuizDataEvent(type:String, params:Object=null,bubbles:Boolean=false, cancelable:Boolean=false) {

      super(type, bubbles, cancelable);

      this.params = params;

      }

       

      override public function clone():Event {

      var newEvent:QuizDataEvent = new QuizDataEvent(type);

      newEvent.params = params;

      return newEvent;

      }

       

      }

      }

       

       

      Please try it .... and I would appreciate any comments about this issue...

       

      Thanks

       

      Elisheva