View Javadoc

1   /***
2    * Redistribution  and use  in source  and binary  forms, with  or without
3    * modification, are permitted provided  that the following conditions are
4    * met :
5    *
6    * . Redistributions  of  source  code  must  retain  the  above copyright
7    *   notice, this list of conditions and the following disclaimer.
8    *
9    * . Redistributions in  binary form  must reproduce  the above  copyright
10   *   notice, this list of conditions  and the following disclaimer in  the
11   *   documentation and/or other materials provided with the distribution.
12   *
13   * . The name of the author may not be used to endorse or promote products
14   *   derived from this software without specific prior written permission.
15   *
16   * THIS SOFTWARE IS  PROVIDED BY THE  AUTHOR ``AS IS''  AND ANY EXPRESS  OR
17   * IMPLIED  WARRANTIES,  INCLUDING,  BUT   NOT  LIMITED  TO,  THE   IMPLIED
18   * WARRANTIES OF MERCHANTABILITY AND  FITNESS FOR A PARTICULAR  PURPOSE ARE
19   * DISCLAIMED.  IN NO  EVENT SHALL  THE AUTHOR  BE LIABLE  FOR ANY  DIRECT,
20   * INDIRECT,  INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR  CONSEQUENTIAL  DAMAGES
21   * (INCLUDING,  BUT  NOT LIMITED  TO,  PROCUREMENT OF  SUBSTITUTE  GOODS OR
22   * SERVICES;  LOSS  OF USE,  DATA,  OR PROFITS;  OR  BUSINESS INTERRUPTION)
23   * HOWEVER CAUSED  AND ON  ANY THEORY  OF LIABILITY,  WHETHER IN  CONTRACT,
24   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
25   * ANY  WAY  OUT OF  THE  USE OF  THIS  SOFTWARE, EVEN  IF  ADVISED OF  THE
26   * POSSIBILITY OF SUCH DAMAGE.
27   *
28   * $Id$
29   */
30  
31  package palmed.edit.view;
32  
33  import java.io.IOException;
34  import java.io.InputStream;
35  import java.io.OutputStream;
36  import java.util.Enumeration;
37  import java.util.Vector;
38  import palmed.edit.selection.ILineVisitor;
39  import palmed.edit.util.Coordinate;
40  
41  /***
42   * This class implements a viewport on a content.
43   *
44   * @author Mathieu Champlon
45   * @version $Revision$ $Date$
46   */
47  public final class Viewport implements IViewport, IContent, IView
48  {
49      /***
50       * The current upper-left character coordinate.
51       */
52      private final Coordinate scroll_;
53      /***
54       * Visible text size in characters.
55       */
56      private int visibleColumns_, visibleLines_;
57      /***
58       * Current text size in characters.
59       */
60      private int maxColumns_, maxLines_;
61      /***
62       * The current cursor position.
63       */
64      private final Coordinate cursorPosition_;
65      /***
66       * The content.
67       */
68      private final IContent content_;
69      /***
70       * The view.
71       */
72      private IView view_;
73      /***
74       * The scroll views.
75       */
76      private final Vector views_;
77  
78      /***
79       * Create a content viewport.
80       *
81       * @param content the content to manage
82       */
83      public Viewport( final IContent content )
84      {
85          if( content == null )
86              throw new IllegalArgumentException( "parameter 'content' is null" );
87          content_ = content;
88          scroll_ = new Coordinate();
89          view_ = new NullView();
90          cursorPosition_ = new Coordinate();
91          views_ = new Vector();
92          content_.register( this );
93      }
94  
95      /***
96       * {@inheritDoc}
97       */
98      public void type( final int keyCode )
99      {
100         content_.type( keyCode );
101         showCursor();
102     }
103 
104     /***
105      * {@inheritDoc}
106      */
107     public void drag( final int x, final int y )
108     {
109         content_.drag( x + scroll_.x_, y + scroll_.y_ );
110         showCursor();
111     }
112 
113     /***
114      * {@inheritDoc}
115      */
116     public void click( final int x, final int y )
117     {
118         content_.click( x + scroll_.x_, y + scroll_.y_ );
119         showCursor();
120     }
121 
122     /***
123      * {@inheritDoc}
124      */
125     public void enter()
126     {
127         content_.enter();
128         showCursor();
129     }
130 
131     /***
132      * {@inheritDoc}
133      */
134     public void backspace()
135     {
136         content_.backspace();
137         showCursor();
138     }
139 
140     /***
141      * {@inheritDoc}
142      */
143     public void accept( final ILineVisitor visitor, final int y )
144     {
145         content_.accept( new TranslatedLineVisitor( visitor, scroll_.x_ ), y + scroll_.y_ );
146     }
147 
148     /***
149      * {@inheritDoc}
150      */
151     public void register( final IView view )
152     {
153         if( view == null )
154             throw new IllegalArgumentException( "parameter 'view' is null" );
155         view_ = view;
156     }
157 
158     /***
159      * {@inheritDoc}
160      */
161     public void scroll( final int columns, final int lines )
162     {
163         scroll_.x_ += columns;
164         scroll_.y_ += lines;
165         center();
166     }
167 
168     /***
169      * {@inheritDoc}
170      */
171     public void update( final Coordinate position )
172     {
173         cursorPosition_.x_ = position.x_;
174         cursorPosition_.y_ = position.y_;
175         view_.update( new Coordinate( cursorPosition_.x_ - scroll_.x_, cursorPosition_.y_ - scroll_.y_ ) );
176     }
177 
178     /***
179      * {@inheritDoc}
180      */
181     public void update( final int columns, final int lines )
182     {
183         maxColumns_ = columns;
184         maxLines_ = lines;
185         center();
186     }
187 
188     /***
189      * {@inheritDoc}
190      */
191     public void modified( final boolean status )
192     {
193         view_.modified( status );
194     }
195 
196     /***
197      * {@inheritDoc}
198      */
199     public void resize( final int columns, final int lines )
200     {
201         visibleColumns_ = columns;
202         visibleLines_ = lines;
203         center();
204     }
205 
206     private void center()
207     {
208         scroll_.x_ = Math.max( 0, Math.min( scroll_.x_, maxColumns_ - visibleColumns_ ) );
209         scroll_.y_ = Math.max( 0, Math.min( scroll_.y_, maxLines_ - visibleLines_ ) );
210         view_.update( new Coordinate( cursorPosition_.x_ - scroll_.x_, cursorPosition_.y_ - scroll_.y_ ) );
211         view_.update( maxColumns_, maxLines_ );
212         final Enumeration e = views_.elements();
213         while( e.hasMoreElements() )
214             ((IScrollView)e.nextElement()).scrolled( scroll_ );
215     }
216 
217     /***
218      * {@inheritDoc}
219      */
220     public void register( final IScrollView view )
221     {
222         if( view == null )
223             throw new IllegalArgumentException( "parameter 'view' is null" );
224         views_.addElement( view );
225         view.scrolled( scroll_ );
226     }
227 
228     /***
229      * {@inheritDoc}
230      */
231     public void unmarshall( final InputStream stream ) throws IOException
232     {
233         scroll_.unmarshall( stream );
234         content_.unmarshall( stream );
235     }
236 
237     /***
238      * {@inheritDoc}
239      */
240     public void marshall( final OutputStream stream ) throws IOException
241     {
242         scroll_.marshall( stream );
243         content_.marshall( stream );
244     }
245 
246     /***
247      * {@inheritDoc}
248      */
249     public void clear()
250     {
251         content_.clear();
252     }
253 
254     private void showCursor()
255     {
256         scroll( nearestColumn( cursorPosition_.x_ - scroll_.x_ ), nearestLine( cursorPosition_.y_ - scroll_.y_ ) );
257     }
258 
259     private int nearestLine( final int y )
260     {
261         if( visibleLines_ > 0 )
262         {
263             if( y >= visibleLines_ )
264                 return y - visibleLines_ + 1;
265             else if( y < 0 )
266                 return y;
267         }
268         return 0;
269     }
270 
271     private int nearestColumn( final int x )
272     {
273         if( visibleColumns_ > 0 )
274         {
275             if( x > visibleColumns_ )
276                 return x - visibleColumns_;
277             else if( x <= 0 )
278                 return x - 1;
279         }
280         return 0;
281     }
282 
283     /***
284      * {@inheritDoc}
285      */
286     public void copy( final OutputStream stream ) throws IOException
287     {
288         content_.copy( stream );
289     }
290 
291     /***
292      * {@inheritDoc}
293      */
294     public void cut( final OutputStream stream ) throws IOException
295     {
296         content_.cut( stream );
297         showCursor();
298     }
299 
300     /***
301      * {@inheritDoc}
302      */
303     public void paste( final InputStream stream ) throws IOException
304     {
305         content_.paste( stream );
306         showCursor();
307     }
308 
309     /***
310      * {@inheritDoc}
311      */
312     public void undo()
313     {
314         content_.undo();
315         showCursor();
316     }
317 
318     /***
319      * {@inheritDoc}
320      */
321     public void redo()
322     {
323         content_.redo();
324         showCursor();
325     }
326 }