0 Replies Latest reply on Mar 29, 2011 11:16 AM by Eli7BBB

    full_scale, zoom and scroll pane question

    Eli7BBB Level 1

      Hi,

       

      I have an application which should be able to do full screen. BUT, only part of the stage should go full screen, some parts stay the same. (like all facebook games, where the friends_bar etc stay the same size).

       

      I want to be able to scroll-pane the background of the app in full screen the same way I do in normal mode...

       

      And I want to be able to zoom, and keep scrolling by draging the mouse.

       

      Going full screen works ok and so does the scroll-pane. BUT when I zoom in full screen - the scrolling does not behave correctly.

       

      I assume this is because - full screen does one change in scale and zooming adds to this change in scale again, but I dont know how to calculate both changes when I calcualte the borders of the scroll.

       

      Again - I am re-scaling when I go full screen manualy.

       

      I am attaching a small fxp which demonstrates the problem.

       

      The main tests.mxml

       

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

      <s:Application

       

       

      xmlns:fx="http://ns.adobe.com/mxml/2009"

      xmlns:s="

      library://ns.adobe.com/flex/spark"

      xmlns:mx="

      library://ns.adobe.com/flex/mx" minWidth="760" minHeight="642"

      width="

      760" height="642" initialize="application1_initializeHandler(event)">

       

       

      <fx:Declarations>

       

       

      <!-- Place non-visual elements (e.g., services, value objects) here -->

       

       

      </fx:Declarations>

       

       

       

      <fx:Script>

      <![CDATA[

       

       

      import Classes.Screen;

       

       

      import flash.display.Sprite;

       

      import flash.display.Stage;

       

      importflash.display.StageDisplayState;

       

      importflash.events.MouseEvent;

       

      import flash.geom.Rectangle;

       

       

      importmx.core.BitmapAsset;

       

      importmx.core.UIComponent;

       

      importmx.events.FlexEvent;

       

       

      private var_fullScreenScale:Number;

       

      private varmain:UIComponent;

       

      private varinFullScreen:Boolean;

       

      private varlogMsgBox:TextField;

       

      public function getfullScreenScale():Number

      {

       

      return_fullScreenScale;

      }

       

       

      private functionenterFullScreen(e:MouseEvent):void

      {

       

       

      if(inFullScreen == false)

      {

       

       

      varredSquare:Sprite = e.target as Sprite;

       

      varw:int = (e.target asSprite).width;

       

      varh:int = (e.target as Sprite).height;

       

      varfullScreenRect:Rectangle = newRectangle(redSquare.x, redSquare.y, redSquare.width, redSquare.height);

      stage.displayState = StageDisplayState.FULL_SCREEN;

       

      var scaling:Number = 1;

       

      if(this.width > this.height)

      {

      scaling = stage.stageWidth /

      this.width;

      }

       

      else

      {

      scaling = stage.stageHeight /

       

      this.height;

      }

      _fullScreenScale = main.scaleX = main.scaleY = scaling;

      stage.align = StageAlign.TOP_LEFT;

       

      this.stage.addEventListener( FullScreenEvent.FULL_SCREEN, leaveFullScreen );

      inFullScreen = !inFullScreen;

      logMsgBox.width = 1000;

      logMsgBox.height = 500;

      }

      else

      {

      leaveFullScreen();

      }

      }

       

       

       

      private functionleaveFullScreen(event:FullScreenEvent=null):void

      {

       

       

      this.stage.removeEventListener( FullScreenEvent.FULL_SCREEN, leaveFullScreen );

       

      this.stage.displayState=StageDisplayState.NORMAL;

      main.scaleX = 1;

      main.scaleY = 1;

      inFullScreen = !inFullScreen;

       

      }

       

       

      public functionlog_msg(str:String):void

      {

      logMsgBox.appendText(str);

      logMsgBox.appendText(

       

      "\n");

      logMsgBox.scrollV = logMsgBox.maxScrollV;

      }

       

       

      private functionzoomIn(event:MouseEvent):void

      {

      (main.getChildAt(0)

       

      asScreen).zoomIn();

      }

       

       

      private functionzoomOut(event:MouseEvent):void

      {

      (main.getChildAt(0)

       

      asScreen).zoomOut();

      }

       

       

      protected functionapplication1_initializeHandler(event:FlexEvent):void

      {

       

       

      varformat:TextFormat = newTextFormat();

       

      format.size = 20;

      format.color = 0x0000ff;

       

       

      // TODO Auto-generated method stub

      main =

       

      newUIComponent();

      main.graphics.beginFill(0xFF88CC);

      main.graphics.drawRect(0, 0, 955, 600);

       

       

      this.addElement(main);

       

      varredSquare:UIComponent = newUIComponent();

      redSquare.graphics.beginFill(0xFF0000);

      redSquare.graphics.drawRect(0, 0, 20, 20);

      redSquare.x = 50;

      redSquare.y = 50;

      redSquare.addEventListener(MouseEvent.CLICK, enterFullScreen);

      redSquare.buttonMode =

      true;

       

      this.addElement(redSquare);

      inFullScreen =

      false;

       

      varblueSquare:UIComponent = newUIComponent();

      blueSquare.graphics.beginFill(0x0000ff);

      blueSquare.graphics.drawRect(0, 0, 20, 20);

      blueSquare.x = 150;

      blueSquare.y = 50;

      blueSquare.addEventListener(MouseEvent.CLICK, zoomIn);

      blueSquare.buttonMode =

      true;

       

      this.addElement(blueSquare);

       

      vargreenSquare:UIComponent = newUIComponent();

      greenSquare.graphics.beginFill(0x0000ff);

      greenSquare.graphics.drawRect(0, 0, 20, 20);

      greenSquare.x = 200;

      greenSquare.y = 50;

      greenSquare.addEventListener(MouseEvent.CLICK, zoomOut);

      greenSquare.buttonMode =

      true;

       

      this.addElement(greenSquare);

       

      varlogMsgUI:UIComponent = newUIComponent();

       

      logMsgBox =

      newTextField();

      logMsgBox.width = 400;

      logMsgBox.height = 300;

      logMsgBox.background =

      true;

      logMsgBox.backgroundColor = 0xFFF000;

      logMsgBox.alpha = .5;

      logMsgBox.setTextFormat(format);

      logMsgBox.defaultTextFormat = format;

      logMsgBox.backgroundColor=0xffffff;

      logMsgBox.border =

      true;

      logMsgBox.borderColor = 0x000000;

      logMsgBox.scrollV = logMsgBox.maxScrollV;

      logMsgUI.addChild(logMsgBox);

      logMsgUI.x =

      this.width - logMsgBox.width;

      logMsgUI.y = 0;

       

       

      this.addElement(logMsgUI);

      log_msg(

      "init");

       

      varscr:Screen = new Screen();

       

      //main.graphics = greenRect;

       

       

      // create red square on stage, turn it into a button for going to full screen

      main.addChild(scr);

       

      }

       

       

      ]]>

       

       

      </fx:Script>

      </s:Application>

       

      __________________________________________________________________________

      The Screen Class

      __________________________________________________________________________

       

      package

       

       

      Classes

      {

       

      import flash.display.Bitmap;

       

      importflash.display.DisplayObject;

       

      import flash.display.Loader;

       

      import flash.display.Sprite;

       

      importflash.display.StageDisplayState;

       

      import flash.events.Event;

       

      importflash.events.MouseEvent;

       

      importflash.geom.Point;

       

      importflash.media.SoundChannel;

       

      importflash.media.SoundTransform;

       

      importflash.net.URLRequest;

       

      importflash.utils.Dictionary;

       

       

      importmx.binding.utils.BindingUtils;

       

      importmx.core.FlexGlobals;

       

      importmx.core.UIComponent;

       

      importmx.events.FlexEvent;

       

      importmx.resources.ResourceManager;

       

      importmx.utils.NameUtil;

       

       

      public classScreen extends Sprite {

       

      public static var SCREEN_WIDTH :Number = 760;

       

      public static var SCREEN_HEIGHT :Number = 540;

       

      public const ZOOM_STEP :Number = 0.25;

       

      public const ZOOM_MAX :Number = 2;

       

      public var ZOOM_MIN :Number = 0.1;

       

       

      protected varstartPoint : Point;

       

      protected var scrolled : Boolean = false;

       

       

      protected varcurrentZoom :Number = 1;

       

      public function getgetZoom () :Number { returncurrentZoom; }

       

      protected varZoomSize :Point;

       

      protected varorigPos :Point;

       

       

      // Mouse pos in glade while scrolling, or null if not scrolling

       

      protected varscrollPos :Point;

       

      protected varprevScrollPos:Point;

       

      protected varorigScrollPos :Point;

       

      private varstageScale:Number;

       

      private varoffsetX:Number;

       

      private varbottomPanelHeight:Number;

       

      private varready : Boolean;

       

      private var image:Bitmap;

       

       

      public function Screen() {

      ready =

      false;

       

       

      var loader:Loader = new Loader;

      loader.contentLoaderInfo.addEventListener(Event.COMPLETE, imageLoaded);

      loader.load(

      newURLRequest("Assets/pic.JPG"));

      FlexGlobals.topLevelApplication.log_msg(

      "started loading");

       

      addEventListener(Event.ADDED_TO_STAGE, init);

      addEventListener(Event.REMOVED_FROM_STAGE, uninit);

      }

       

       

      private functionimageLoaded(event:Event):void

      {

      image =

      newBitmap(event.target.content.bitmapData);

       

      this.addChild(image);

      }

       

       

      protected functioninit(event : Event):void

      {

      origPos =

      new Point(0,0);

      startPoint =

      new Point(0,0);

      removeEventListener(Event.ADDED_TO_STAGE, init);

      addEventListener(MouseEvent.MOUSE_DOWN, startScroll);

       

      }

       

       

      protected functionuninit(event : Event):void

      {

      removeEventListener(Event.REMOVED_FROM_STAGE, uninit);

      }

       

       

       

      private functiongetRealZoom () :Number

      {

       

       

      varzoom :Number = Math.min(ZOOM_MAX, Math.max(getMinZoom(), currentZoom));

       

      //FlexGlobals.topLevelApplication.log_msg ("getReal zoom " + zoom + " bg width " + bg.width + " h " + bg.height);

      ZoomSize =

      new Point (image.width * zoom, image.height * zoom);

       

      return zoom;

      }

       

       

      public functionsetCurrentZoom(gladeCurrentZoom:Number):void

      {

       

      //FlexGlobals.topLevelApplication.log_msg ("set current zoom " + gladeCurrentZoom);

      currentZoom = gladeCurrentZoom;

      setZoom();

      }

       

       

      // Apply zoom (absolute, not relative to current)

       

      public functionsetZoom () :void

      {

       

      varzoom :Number = getRealZoom();

       

      //FlexGlobals.topLevelApplication.log_msg ("setZoom zoom " + zoom);

       

      // Center

       

      if (zoom == 1)

      {

       

      this.x = origPos.x + offsetX;

       

      this.y = origPos.y;

      }

       

      else

      {

       

      // scaleX (or Y) is old zoom

       

      //FlexGlobals.topLevelApplication.log_msg ("set Zoom before scaleX " + scaleX + " zoom " + zoom + " this.x " + this.x + " y " + this.y);

       

      var screen_height:Number;

       

       

      varfactor :Number = (scaleX - zoom) / 2;

       

      //FlexGlobals.topLevelApplication.log_msg ("factor " + factor);

       

      this.x = Math.floor(Math.max(Math.min(this.x + SCREEN_WIDTH * factor, origPos.x), SCREEN_WIDTH - ZoomSize.x));

       

      this.y = Math.floor(Math.max(Math.min(this.y + SCREEN_HEIGHT * factor, origPos.y), SCREEN_HEIGHT - ZoomSize.y));

       

       

      }

       

      // Change

      scaleX = scaleY = zoom;

      FlexGlobals.topLevelApplication.log_msg (

      "set Zoom after scaleX "+ scaleX + " this.x " + this.x + " y " + this.y);

      }

       

       

       

      public functionzoomIn () :void

      {

       

      //if (this.stage.displayState == StageDisplayState.FULL_SCREEN)

       

      //return;

       

      if(currentZoom >= ZOOM_MAX - 0.0001)

       

      return;

      currentZoom = Math.min(currentZoom += ZOOM_STEP, ZOOM_MAX);

       

      setZoom();

       

      //FlexGlobals.topLevelApplication.log_msg ("zoomIn " + currentZoom);

      }

       

       

       

       

      public functionzoomOut () :void

      {

       

      //if (this.stage.displayState == StageDisplayState.FULL_SCREEN)

       

      //return;

       

      //if (this is Glade) SoftTutorial.instance.validateTask(SoftTutorial.ZOOM_GLADE);

       

       

      if(currentZoom <= getMinZoom() + 0.0001)

       

      return;

       

      currentZoom = Math.max(currentZoom -= ZOOM_STEP, getMinZoom());

      setZoom();

       

      //FlexGlobals.topLevelApplication.log_msg ("zoomOut " + currentZoom);

      }

       

       

      public functionstartScroll (e :MouseEvent = null) :void

      {

       

      //FlexGlobals.topLevelApplication.log_msg ("start scroll mousX " + mouseX + " y " + mouseY + " stageX " + stage.mouseX + " y " + stage.mouseY + " parentX " + parent.mouseX + " y " + parent.mouseY);

       

       

      if(ZoomSize == null)

      {

      getRealZoom();

      }

       

       

      // The mouse position relative to forest/glade

       

      varglobpt :Point;

       

       

      if (this.stage.displayState == StageDisplayState.FULL_SCREEN){

      globpt = localToGlobal(

      newPoint (mouseX, mouseY));

      scrollPos = stage.globalToLocal(globpt);

      stageScale = FlexGlobals.topLevelApplication.fullScreenScale;

      }

      else{

      globpt = localToGlobal(

      newPoint (mouseX, mouseY));

      scrollPos = parent.globalToLocal(globpt);

      }

       

      origScrollPos =

      new Point (this.x, this.y);

      prevScrollPos = origScrollPos;

       

      if(!hasEventListener(MouseEvent.MOUSE_MOVE))

      addEventListener(MouseEvent.MOUSE_MOVE, scrollMouseMove);

      addEventListener(MouseEvent.MOUSE_UP, stopAllDrags);

      removeEventListener(MouseEvent.MOUSE_DOWN,startScroll);

      }

       

       

      private functionstopAllDrags(event : MouseEvent = null):void

      {

      stopDrag();

      removeEventListener(MouseEvent.MOUSE_MOVE, scrollMouseMove);

      removeEventListener(MouseEvent.MOUSE_UP,stopAllDrags);

      addEventListener(MouseEvent.MOUSE_DOWN,startScroll);

      }

       

       

      private functionstopScroll (e :MouseEvent = null) :void

      {

       

      //FlexGlobals.topLevelApplication.log_msg ("stop scroll scrollPos x " + this.x + " y " + this.y);

       

      if(hasEventListener(MouseEvent.MOUSE_MOVE))

      removeEventListener(MouseEvent.MOUSE_MOVE, scrollMouseMove);

      scrollPos =

      null;

      scrolled =

      false;

      }

       

       

      public functiontoggleGladeSize(s:Number,bottom_panel_height:Number):void

      {

       

      if(s == 1)

      {

       

      // back to normal mode if y under -277 adjust it back

       

      if (this.y < (SCREEN_HEIGHT - this.height))

       

      this.y = (SCREEN_HEIGHT - this.height);

       

      }

      else

      {

      stageScale = s;

      bottomPanelHeight = bottom_panel_height;

      }

       

      }

       

       

      public functionscrollMouseMove (event :MouseEvent) :void

      {

       

      var_stageScale:Number;

       

      if (this.stage.displayState == StageDisplayState.FULL_SCREEN){

       

      if(scrollPos != null)

      {

       

      varnewX:Number = origScrollPos.x + stage.mouseX - scrollPos.x;

       

      varmarginX:Number;

       

       

      //FlexGlobals.topLevelApplication.log_msg ("FlexGlobals.topLevelApplication.log_msg this.x " + this.x + " width " + this.width + " stage " + this.stage.width + " stage fullScreenWidth " + this.stage.fullScreenWidth);

      _stageScale = stageScale;

       

      marginX = ((stage.fullScreenWidth - (image.width*_stageScale))/_stageScale);

       

      //marginX = GLADE_SCREEN_WIDTH - bg.width;

       

      FlexGlobals.topLevelApplication.log_msg (

      "new X "+ newX + "margin X "+marginX + " stageScale "+ _stageScale );

      FlexGlobals.topLevelApplication.log_msg (

      "image.width "+image.width + " stage.fullScreenWidth " + stage.fullScreenWidth);

       

      if(newX > 0){

       

      this.x = 0;

      }

      else if(newX < marginX){

       

      this.x = marginX;

      }

      else{

       

      this.x = newX;

      }

       

      varnewY:Number = (origScrollPos.y + stage.mouseY - scrollPos.y);

       

      var _x:Number=this.x*currentZoom;

       

      varmarginY:Number;

       

      marginY = ((stage.fullScreenHeight - (image.height*_stageScale))/_stageScale);

       

      FlexGlobals.topLevelApplication.log_msg (

      "stage.fullScreenHeight "+ stage.fullScreenHeight + " image.height " + image.height + " newY "+ newY + " marginY " +marginY);

      FlexGlobals.topLevelApplication.log_msg (

      "newY "+ newY + " marginY "+ marginY + " currentZoom "+ currentZoom + " realzoom "+ getRealZoom() + " gladeZoomSize.y " + ZoomSize.y);

       

       

      if(newY > 0)

       

      this.y = 0;

       

      else

       

      if(newY < marginY)

       

      this.y = marginY;

       

      else

       

      this.y = newY;//origScrollPos.y + parent.mouseY - scrollPos.y ;

       

      var_y:Number=this.y;

       

      }

      }

      else

       

      if(scrollPos != null)

      {

       

      varminX:Number;

       

      if((origScrollPos.x + parent.mouseX - scrollPos.x < origPos.x + startPoint.x))

      minX = origScrollPos.x + parent.mouseX - scrollPos.x;

       

      else

      minX = origPos.x + startPoint.x;

       

       

      if(minX > origPos.x - (ZoomSize.x - SCREEN_WIDTH) + startPoint.x)

       

      this.x = minX;

       

      else

       

      this.x = origPos.x - (ZoomSize.x - SCREEN_WIDTH) + startPoint.x;

       

       

      varminY:Number;

       

      if(origScrollPos.y + parent.mouseY - scrollPos.y < origPos.y + startPoint.y)

      minY = origScrollPos.y + parent.mouseY - scrollPos.y;

       

      else

      minY = origPos.y + startPoint.y;

       

       

      if(minY > origPos.y - (ZoomSize.y - SCREEN_HEIGHT) + startPoint.y)

       

      this.y = minY;

       

      else

       

      this.y = origPos.y - (ZoomSize.y - SCREEN_HEIGHT) + startPoint.y;

      FlexGlobals.topLevelApplication.log_msg (

      "normal min x "+ minX + " minY "+ minY + " this.x " + this.x + " this.y " + this.y);

       

      }

       

      // Change now, dont wait till next frame

      scrolled =

      true;

       

      event.updateAfterEvent();

      }

       

       

      private functiongetMinZoom() : Number {

       

       

      if (image.width > 0)

      {

       

      //if (this.stage.displayState == StageDisplayState.FULL_SCREEN){

       

      //return Math.max(ZOOM_MIN, GLADE_SCREEN_WIDTH / bg.width, stage.fullScreenHeight / bg.height);

       

      //} else

       

      return Math.max(ZOOM_MIN, SCREEN_WIDTH / image.width, SCREEN_HEIGHT / image.height);

      }

       

      else

       

      return ZOOM_MIN;

      }

       

       

      public functionisReady() : Boolean {

       

      return ready;

      }

       

       

      private functionassetsLoaded() : void {

      ready =

      true;

       

       

      dispatchEvent(

      new Event(Event.COMPLETE));

      }

      }

      }

       

       

      Thanks for helping

       

      Elisheva