Guest User

Untitled

a guest
Jun 10th, 2014
256
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 8.56 KB | None | 0 0
  1. package com.javadaemon.teaclient.ui;
  2.  
  3. import com.badlogic.gdx.Input;
  4. import com.badlogic.gdx.graphics.g2d.Batch;
  5. import com.badlogic.gdx.scenes.scene2d.Actor;
  6. import com.badlogic.gdx.scenes.scene2d.InputEvent;
  7. import com.badlogic.gdx.scenes.scene2d.InputListener;
  8. import com.badlogic.gdx.scenes.scene2d.Stage;
  9. import com.badlogic.gdx.scenes.scene2d.Touchable;
  10. import com.badlogic.gdx.scenes.scene2d.ui.Skin;
  11. import com.badlogic.gdx.scenes.scene2d.ui.Table;
  12. import com.badlogic.gdx.scenes.scene2d.utils.Align;
  13. import com.badlogic.gdx.scenes.scene2d.utils.Drawable;
  14.  
  15. /**
  16.  * This is very much like a regular Table, although it has some extra features.
  17.  * It is movable on a Stage, and can be resized by dragging.
  18.  * It can also act modal if needed, and be locked to be inside of the Stage if needed.
  19.  *
  20.  * This is basicly Window from scene2d.ui, with a few modifications.
  21.  *
  22.  * @author Mads Peter Horndrup
  23.  */
  24. public class MovableTable extends Table {
  25.    
  26.     /** Different flags to define different behaviors */
  27.     private boolean isModal, isResizable, isMovable;
  28.    
  29.     /** Maximum pixels from the border where the MovableWindow can be resized */
  30.     private int resizeBorder = 8;
  31.    
  32.     /** Are we currently resizing or moving the MovableWindow?? */
  33.     private boolean dragging;
  34.    
  35.     /** Should we make sure the MovableWindow stays inside the Viewport?? */
  36.     private boolean keepWithinStage;
  37.    
  38.     /** What Actors allow the MovableWindow to be dragged */
  39.     protected Actor[] dragActors;
  40.    
  41.     private MovableTableStyle style;
  42.    
  43.     /** Used to indicate that side of the MovableWindow that is being resized, and if it's being moved */
  44.     static private final int MOVE = 1 << 5;
  45.    
  46.     public MovableTable(Skin skin) {
  47.         this(skin.get(MovableTableStyle.class));
  48.         setSkin(skin);
  49.     }
  50.  
  51.     public MovableTable(Skin skin, String styleName) {
  52.         this(skin.get(styleName, MovableTableStyle.class));
  53.         setSkin(skin);
  54.     }
  55.  
  56.     public MovableTable(MovableTableStyle closeableWindowStyle) {
  57.         setTouchable(Touchable.enabled);
  58.         setClip(true);
  59.         setStyle(closeableWindowStyle);
  60.         setWidth(150);
  61.         setHeight(150);
  62.         setMovable(true);
  63.         setResizable(false);
  64.         setKeepWithinStage(true);
  65.        
  66.         dragActors = new Actor[1];
  67.         dragActors[0] = this;
  68.  
  69.         addCaptureListener(new InputListener() {
  70.             public boolean touchDown(InputEvent event, float x, float y,
  71.                     int pointer, int button) {
  72.                 toFront();
  73.                 return false;
  74.             }
  75.         });
  76.         addListener(new InputListener() {
  77.             int edge;
  78.             float startX, startY, lastX, lastY;
  79.  
  80.             public boolean touchDown(InputEvent event, float x, float y,
  81.                     int pointer, int button) {
  82.                 Actor hitActor = hit(x,y,true);
  83.                 boolean success = false;
  84.                 for (Actor a : getDraggableRegions()) {
  85.                     if (hitActor.equals(a)) {
  86.                         success = true;
  87.                     }
  88.                 }
  89.                 if (!success) {
  90.                     return false;
  91.                 }
  92.                 if (button == Input.Buttons.LEFT) {
  93.                     int border = resizeBorder;
  94.                     float width = getWidth(), height = getHeight();
  95.                     edge = 0;
  96.                     if (isResizable) {
  97.                         if (x < border)
  98.                             edge |= Align.left;
  99.                         if (x > width - border)
  100.                             edge |= Align.right;
  101.                         if (y < border)
  102.                             edge |= Align.bottom;
  103.                         if (y > height - border)
  104.                             edge |= Align.top;
  105.                         if (edge != 0)
  106.                             border += 25;
  107.                         if (x < border)
  108.                             edge |= Align.left;
  109.                         if (x > width - border)
  110.                             edge |= Align.right;
  111.                         if (y < border)
  112.                             edge |= Align.bottom;
  113.                         if (y > height - border)
  114.                             edge |= Align.top;
  115.                     }
  116.                     if (isMovable
  117.                             && edge == 0    // We are not resizing!
  118.                             && y <= height  // Inside the Window
  119.                             && y >= 0      
  120.                             && x >= 0
  121.                             && x <= width)
  122.                         edge = MOVE;
  123.                     dragging = edge != 0;
  124.                     startX = x;
  125.                     startY = y;
  126.                     lastX = x;
  127.                     lastY = y;
  128.                 }
  129.                 return edge != 0 || isModal;
  130.             }
  131.  
  132.             public void touchUp(InputEvent event, float x, float y,
  133.                     int pointer, int button) {
  134.                 dragging = false;
  135.             }
  136.  
  137.             public void touchDragged(InputEvent event, float x, float y,
  138.                     int pointer) {
  139.                 if (!dragging)
  140.                     return;
  141.                 float width = getWidth(), height = getHeight();
  142.                 float windowX = getX(), windowY = getY();
  143.  
  144.                 float minWidth = getMinWidth(), maxWidth = getMaxWidth();
  145.                 float minHeight = getMinHeight(), maxHeight = getMaxHeight();
  146.                 Stage stage = getStage();
  147.                 boolean clampPosition = keepWithinStage
  148.                         && getParent() == stage.getRoot();
  149.  
  150.                 if ((edge & MOVE) != 0) { // We are moving!
  151.                     float amountX = x - startX, amountY = y - startY;
  152.                     windowX += amountX;
  153.                     windowY += amountY;
  154.                 }
  155.                 if ((edge & Align.left) != 0) { // We are resizing!
  156.                     float amountX = x - startX;
  157.                     if (width - amountX < minWidth)
  158.                         amountX = -(minWidth - width);
  159.                     if (clampPosition && windowX + amountX < 0)
  160.                         amountX = -windowX;
  161.                     width -= amountX;
  162.                     windowX += amountX;
  163.                 }
  164.                 if ((edge & Align.bottom) != 0) {
  165.                     float amountY = y - startY;
  166.                     if (height - amountY < minHeight)
  167.                         amountY = -(minHeight - height);
  168.                     if (clampPosition && windowY + amountY < 0)
  169.                         amountY = -windowY;
  170.                     height -= amountY;
  171.                     windowY += amountY;
  172.                 }
  173.                 if ((edge & Align.right) != 0) {
  174.                     float amountX = x - lastX;
  175.                     if (width + amountX < minWidth)
  176.                         amountX = minWidth - width;
  177.                     if (clampPosition
  178.                             && windowX + width + amountX > stage.getWidth())
  179.                         amountX = stage.getWidth() - windowX - width;
  180.                     width += amountX;
  181.                 }
  182.                 if ((edge & Align.top) != 0) {
  183.                     float amountY = y - lastY;
  184.                     if (height + amountY < minHeight)
  185.                         amountY = minHeight - height;
  186.                     if (clampPosition
  187.                             && windowY + height + amountY > stage.getHeight())
  188.                         amountY = stage.getHeight() - windowY - height;
  189.                     height += amountY;
  190.                 }
  191.                 lastX = x;
  192.                 lastY = y;
  193.                 setBounds(Math.round(windowX), Math.round(windowY),
  194.                         Math.round(width), Math.round(height));
  195.             }
  196.  
  197.             public boolean mouseMoved(InputEvent event, float x, float y) {
  198.                 return isModal;
  199.             }
  200.  
  201.             public boolean scrolled(InputEvent event, float x, float y,
  202.                     int amount) {
  203.                 return isModal;
  204.             }
  205.  
  206.             public boolean keyDown(InputEvent event, int keycode) {
  207.                 return isModal;
  208.             }
  209.  
  210.             public boolean keyUp(InputEvent event, int keycode) {
  211.                 return isModal;
  212.             }
  213.  
  214.             public boolean keyTyped(InputEvent event, char character) {
  215.                 return isModal;
  216.             }
  217.         });
  218.     }
  219.    
  220.     /**
  221.      * Checks if the Window is within the Stage. If not, it is pushed inside.
  222.      */
  223.     private void keepWithinStage () {
  224.         if (!keepWithinStage) return;
  225.         Stage stage = getStage();
  226.         if (getParent() == stage.getRoot()) {
  227.             float parentWidth = stage.getWidth();
  228.             float parentHeight = stage.getHeight();
  229.             if (getX() < 0) setX(0);
  230.             if (getRight() > parentWidth) setX(parentWidth - getWidth());
  231.             if (getY() < 0) setY(0);
  232.             if (getTop() > parentHeight) setY(parentHeight - getHeight());
  233.         }
  234.     }
  235.    
  236.     /**
  237.      * @return  The Actor that was hit first.
  238.      */
  239.     public Actor hit (float x, float y, boolean touchable) {
  240.         Actor hit = super.hit(x, y, touchable);
  241.         if (hit == null && isModal && (!touchable || getTouchable() == Touchable.enabled)) return this;
  242.         return hit;
  243.     }
  244.    
  245.     /**
  246.      * This method is used to determine what Actors can be clicked to drag the dialog.
  247.      * This is to prevent dragging inside the content of the MovableWindow.
  248.      * @return  An Array of Actors that can be used to drag the MovableWindow.
  249.      */
  250.     protected Actor[] getDraggableRegions() {
  251.         return dragActors;
  252.     }
  253.    
  254.     /**
  255.      * Renders the beautiful Table.
  256.      */
  257.     public void draw(Batch batch, float parentAlpha) {
  258.         keepWithinStage();
  259.         super.draw(batch, parentAlpha);
  260.     }
  261.    
  262.     public void setStyle(MovableTableStyle style) {
  263.         if (style == null) throw new IllegalArgumentException("style cannot be null.");
  264.         this.style = style;
  265.         setBackground(style.background);
  266.         invalidateHierarchy(); // This one is questionable!
  267.     }
  268.    
  269.     public MovableTableStyle getStyle () {
  270.         return style;
  271.     }
  272.    
  273.     public boolean isModal() {
  274.         return isModal;
  275.     }
  276.  
  277.     public void setModal(boolean isModal) {
  278.         this.isModal = isModal;
  279.     }
  280.  
  281.     public boolean isResizable() {
  282.         return isResizable;
  283.     }
  284.  
  285.     public void setResizable(boolean isResizable) {
  286.         this.isResizable = isResizable;
  287.     }
  288.  
  289.     public boolean isMovable() {
  290.         return isMovable;
  291.     }
  292.  
  293.     public void setMovable(boolean isMovable) {
  294.         this.isMovable = isMovable;
  295.     }
  296.  
  297.     public boolean isKeepWithinStage() {
  298.         return keepWithinStage;
  299.     }
  300.  
  301.     public void setKeepWithinStage(boolean keepWithinStage) {
  302.         this.keepWithinStage = keepWithinStage;
  303.     }
  304.  
  305.     static public class MovableTableStyle {
  306.        
  307.         public Drawable background;
  308.     }
  309. }
Advertisement
Add Comment
Please, Sign In to add comment