62f541df208c8580358f3a798cd79402c78af0b2
[idea/community.git] / platform / editor-ui-api / src / com / intellij / openapi / editor / VisualPosition.java
1 /*
2  * Copyright 2000-2015 JetBrains s.r.o.
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.intellij.openapi.editor;
17
18 import org.jetbrains.annotations.NonNls;
19 import org.jetbrains.annotations.NotNull;
20
21 /**
22  * Represents a visual position in the editor. Visual positions take folding into account -
23  * for example, if the top 10 lines of the document are folded, the 10th line in the document
24  * will have the line number 1 in its visual position.
25  * <p>
26  * Visual position corresponds to a boundary between two characters and can be associated with either a preceding or succeeding character 
27  * (see {@link #leansRight}). This association makes a difference in a bidirectional text, where a mapping from visual to logical position 
28  * is not continuous.
29  *
30  * @see LogicalPosition
31  * @see Editor#logicalToVisualPosition(LogicalPosition)
32  * @see Editor#offsetToVisualPosition(int)
33  * @see Editor#xyToVisualPosition(java.awt.Point)
34  */
35 public class VisualPosition {
36   public final int line;
37   public final int column;
38   /**
39    * If <code>true</code>, this position is associated with succeeding character (in visual order), otherwise it's associated with 
40    * preceding character. This can make difference in bidirectional text, where visual positions which differ only in this flag's value
41    * can correspond to a different logical positions.
42    * <p>
43    * This field has no impact on equality and comparison relationships between <code>VisualPosition</code> instances.
44    */
45   public final boolean leansRight;
46
47   public VisualPosition(int line, int column) {
48     this(line, column, false);
49   }
50
51   public VisualPosition(int line, int column, boolean leansRight) {
52     if (line < 0) throw new IllegalArgumentException("line must be non negative: "+line);
53     if (column < 0) throw new IllegalArgumentException("column must be non negative: "+column);
54     this.line = line;
55     this.column = column;
56     this.leansRight = leansRight;
57   }
58
59   /**
60    * Allows to answer if current visual position is located after the given one.
61    * <p/>
62    * One visual position is considered to be 'after' another only if one of the following is true:
63    * <pre>
64    * <ul>
65    *   <li>its visual line is greater;</li>
66    *   <li>it has the same visual line but its column is greater;</li>
67    * </ul>
68    * </pre>
69    *
70    * @param other   visual position to compare with the current one
71    * @return        <code>true</code> if current position is 'after' the given one; <code>false</code> otherwise
72    */
73   public boolean after(@NotNull VisualPosition other) {
74     if (line == other.line) {
75       return column > other.column;
76     }
77     return line > other.line;
78   }
79
80   /**
81    * Constructs a new <code>VisualPosition</code> instance with a given value of {@link #leansRight} flag.
82    */
83   public VisualPosition leanRight(boolean value) {
84     return new VisualPosition(line, column, value);
85   }
86
87   @NonNls
88   public String toString() {
89     return "VisualPosition: (" + line + ", " + column+")" + (leansRight ? " leans right" : "");
90   }
91
92   @Override
93   public boolean equals(final Object o) {
94     if (this == o) return true;
95     if (!(o instanceof VisualPosition)) return false;
96
97     final VisualPosition that = (VisualPosition)o;
98
99     if (column != that.column) return false;
100     if (line != that.line) return false;
101
102     return true;
103   }
104
105   @Override
106   public int hashCode() {
107     int result = line;
108     result = 31 * result + column;
109     return result;
110   }
111
112   public int getLine() {
113     return line;
114   }
115
116   public int getColumn() {
117     return column;
118   }
119 }