Home | History | Annotate | Download | only in scroll
      1 /*
      2  * Copyright (C) 2013 DroidDriver committers
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 package com.google.android.droiddriver.scroll;
     17 
     18 import static com.google.android.droiddriver.scroll.Direction.PhysicalDirection.DOWN;
     19 import static com.google.android.droiddriver.scroll.Direction.PhysicalDirection.LEFT;
     20 import static com.google.android.droiddriver.scroll.Direction.PhysicalDirection.RIGHT;
     21 import static com.google.android.droiddriver.scroll.Direction.PhysicalDirection.UP;
     22 
     23 /**
     24  * A namespace to hold interfaces and constants for scroll directions.
     25  */
     26 public class Direction {
     27   /** Logical directions */
     28   public enum LogicalDirection {
     29     FORWARD {
     30       @Override
     31       public LogicalDirection reverse() {
     32         return BACKWARD;
     33       }
     34     },
     35     BACKWARD {
     36       @Override
     37       public LogicalDirection reverse() {
     38         return FORWARD;
     39       }
     40     };
     41     public abstract LogicalDirection reverse();
     42   }
     43 
     44   /** Physical directions */
     45   public enum PhysicalDirection {
     46     UP {
     47       @Override
     48       public PhysicalDirection reverse() {
     49         return DOWN;
     50       }
     51 
     52       @Override
     53       public Axis axis() {
     54         return Axis.VERTICAL;
     55       }
     56     },
     57     DOWN {
     58       @Override
     59       public PhysicalDirection reverse() {
     60         return UP;
     61       }
     62 
     63       @Override
     64       public Axis axis() {
     65         return Axis.VERTICAL;
     66       }
     67     },
     68     LEFT {
     69       @Override
     70       public PhysicalDirection reverse() {
     71         return RIGHT;
     72       }
     73 
     74       @Override
     75       public Axis axis() {
     76         return Axis.HORIZONTAL;
     77       }
     78     },
     79     RIGHT {
     80       @Override
     81       public PhysicalDirection reverse() {
     82         return LEFT;
     83       }
     84 
     85       @Override
     86       public Axis axis() {
     87         return Axis.HORIZONTAL;
     88       }
     89     };
     90     public abstract PhysicalDirection reverse();
     91 
     92     public abstract Axis axis();
     93   }
     94 
     95   public enum Axis {
     96     HORIZONTAL {
     97       private final PhysicalDirection[] directions = {LEFT, RIGHT};
     98 
     99       @Override
    100       public PhysicalDirection[] getPhysicalDirections() {
    101         return directions;
    102       }
    103     },
    104     VERTICAL {
    105       private final PhysicalDirection[] directions = {UP, DOWN};
    106 
    107       @Override
    108       public PhysicalDirection[] getPhysicalDirections() {
    109         return directions;
    110       }
    111     };
    112 
    113     public abstract PhysicalDirection[] getPhysicalDirections();
    114   }
    115 
    116   /**
    117    * Converts between PhysicalDirection and LogicalDirection. It's possible to
    118    * override this for RTL (right-to-left) views, for example.
    119    */
    120   public static abstract class DirectionConverter {
    121 
    122     /** Follows standard convention: up-to-down, left-to-right */
    123     public static final DirectionConverter STANDARD_CONVERTER = new DirectionConverter() {
    124       @Override
    125       public PhysicalDirection horizontalForwardDirection() {
    126         return RIGHT;
    127       }
    128 
    129       @Override
    130       public PhysicalDirection verticalForwardDirection() {
    131         return DOWN;
    132       }
    133     };
    134 
    135     /** Follows RTL convention: up-to-down, right-to-left */
    136     public static final DirectionConverter RTL_CONVERTER = new DirectionConverter() {
    137       @Override
    138       public PhysicalDirection horizontalForwardDirection() {
    139         return LEFT;
    140       }
    141 
    142       @Override
    143       public PhysicalDirection verticalForwardDirection() {
    144         return DOWN;
    145       }
    146     };
    147 
    148     public abstract PhysicalDirection horizontalForwardDirection();
    149 
    150     public abstract PhysicalDirection verticalForwardDirection();
    151 
    152     public final PhysicalDirection horizontalBackwardDirection() {
    153       return horizontalForwardDirection().reverse();
    154     }
    155 
    156     public final PhysicalDirection verticalBackwardDirection() {
    157       return verticalForwardDirection().reverse();
    158     }
    159 
    160     /** Converts PhysicalDirection to LogicalDirection */
    161     public final LogicalDirection toLogicalDirection(PhysicalDirection physicalDirection) {
    162       LogicalDirection forward = LogicalDirection.FORWARD;
    163       if (toPhysicalDirection(physicalDirection.axis(), forward) == physicalDirection) {
    164         return forward;
    165       }
    166       return forward.reverse();
    167     }
    168 
    169     /** Converts LogicalDirection to PhysicalDirection */
    170     public final PhysicalDirection toPhysicalDirection(Axis axis, LogicalDirection logicalDirection) {
    171       switch (axis) {
    172         case HORIZONTAL:
    173           switch (logicalDirection) {
    174             case BACKWARD:
    175               return horizontalBackwardDirection();
    176             case FORWARD:
    177               return horizontalForwardDirection();
    178           }
    179           break;
    180         case VERTICAL:
    181           switch (logicalDirection) {
    182             case BACKWARD:
    183               return verticalBackwardDirection();
    184             case FORWARD:
    185               return verticalForwardDirection();
    186           }
    187       }
    188       return null;
    189     }
    190   }
    191 
    192   private Direction() {}
    193 }
    194