Stage align and scale mode

Now, the stage’s align and scale mode is supported perfectly(Only tested HTML5 target).

  1. Active this api as follow:
    Suggestion realization about HTML5Window

  2. Modify Stage.__resize

    • append @access to function

      @:access(lime.ui.Window) // access private member
      @:noCompletion private function __resize():Void
      
    • change __logicalWidth and __logicalHeight:
      https://github.com/openfl/openfl/blob/17bbd9f7ae65bfc9051d61275a9fa4a98644be5e/src/openfl/display/Stage.hx#L2830-L2831

      switch (this.scaleMode)
      {
         case StageScaleMode.NO_SCALE:
            __logicalWidth = windowWidth;
            __logicalHeight = windowHeight;
         case StageScaleMode.SHOW_ALL, StageScaleMode.EXACT_FIT, StageScaleMode.NO_BORDER:
            __logicalWidth = this.window.__attributes.width;
            __logicalHeight = this.window.__attributes.height;
      }
      
    • change __displayMatrix: https://github.com/openfl/openfl/blob/17bbd9f7ae65bfc9051d61275a9fa4a98644be5e/src/openfl/display/Stage.hx#L2851-L2870

      if (__logicalWidth == 0 && __logicalHeight == 0) 
      {
         this.stageWidth = windowWidth;
         this.stageHeight = windowHeight;
      }
      else
      {
         this.stageWidth = __logicalWidth;
         this.stageHeight = __logicalHeight;
      
         var scaleX = windowWidth / this.stageWidth;
         var scaleY = windowHeight / this.stageHeight;
      
         switch (this.scaleMode)
         {
            case StageScaleMode.NO_SCALE:
               scaleX = scaleY = 1;
            case StageScaleMode.SHOW_ALL:
               scaleX = scaleY = Math.min(scaleX, scaleY);
            case StageScaleMode.NO_BORDER:
               scaleX = scaleY = Math.max(scaleX, scaleY);
            case StageScaleMode.EXACT_FIT:
        }
      
        var top_y = 0;
        var middle_y = (windowHeight - (this.stageHeight * scaleY)) / 2;
        var bottom_y = windowHeight - this.stageHeight * scaleY;
      
        var left_x = 0;
        var right_x = windowWidth - this.stageWidth * scaleX;
        var middle_x = (windowWidth - (this.stageWidth * scaleX)) / 2;
      
        var offsetX = middle_x;
        var offsetY = middle_y;
      
        switch (this.align)
        {
        	case StageAlign.TOP:
        		offsetY = top_y;
        	case StageAlign.TOP_RIGHT:
        		offsetX = right_x;
        		offsetY = top_y;
        	case StageAlign.RIGHT:
        		offsetX = right_x;
        	case StageAlign.BOTTOM_RIGHT:
        		offsetX = right_x;
        		offsetY = bottom_y;
        	case StageAlign.BOTTOM:
        		offsetY = bottom_y;
        	case StageAlign.BOTTOM_LEFT:
        		offsetX = left_x;
        		offsetY = bottom_y;
        		case StageAlign.LEFT:
        		offsetX = left_x;
        	case StageAlign.TOP_LEFT:
        		offsetX = left_x;
        		offsetY = top_y;
        }
        this.__displayMatrix.scale(scaleX, scaleY);
        this.__displayMatrix.translate(offsetX, offsetY);
      }
      
  3. modify OpenGLRenderer.__resize
    https://github.com/openfl/openfl/blob/17bbd9f7ae65bfc9051d61275a9fa4a98644be5e/src/openfl/display/OpenGLRenderer.hx#L880-L886

    __offsetX = 0;
    __offsetY = 0;
    __displayWidth = width;
    __displayHeight = height;
    

Done, and there is useage:

// set stage size.
let stage = new Stage(800, 600, 0x000000, App);
// it seems stage.window need to open.
stage.window.resizable = true;
// flash default value
stage.align = "";
stage.scaleMode = StageScaleMode.SHOW_ALL;

Finally, I propose to amend some other places (or open existed API).

  1. Add stage.setStageSize(width, height) to enable change stage.stageWidth and stage.stageHeight.`
  2. Open stage.canvas to get real size of canvas element.
  3. Change stage.align and stage.scaleMode to setter and getter to enable update stage size immediately.
  4. Add a param to Stage constructor to enable put in resizable option.

:grinning:
Through above means, the characteristics of adaptive window will be strengthened.