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; 32 33 import javax.microedition.lcdui.Graphics; 34 import javax.microedition.lcdui.Item; 35 import palmed.edit.selection.ISelectionView; 36 import palmed.edit.util.Coordinate; 37 import palmed.edit.view.Viewport; 38 import palmed.ui.IComponent; 39 40 /*** 41 * This class implements a text area component. 42 * 43 * @author Mathieu Champlon 44 * @version $Revision$ $Date$ 45 */ 46 public final class TextArea implements IComponent, ISelectionView 47 { 48 /*** 49 * The background color. 50 */ 51 private static final int BACKGROUND_COLOR = 0xFFFFFF; 52 /*** 53 * The cursor color. 54 */ 55 private static final int CURSOR_COLOR = 0x000000; 56 /*** 57 * The cursor width in pixels. 58 */ 59 private static final int CURSOR_WIDTH = 2; 60 /*** 61 * Current view size in pixels. 62 */ 63 private int width_, height_; 64 /*** 65 * The font to display the text. 66 */ 67 private IFont font_; 68 /*** 69 * The current cursor position. 70 */ 71 private final Coordinate cursorPosition_; 72 /*** 73 * The viewport. 74 */ 75 private final Viewport viewport_; 76 77 /*** 78 * Create a text area component. 79 * 80 * @param viewport the viewport 81 */ 82 public TextArea( final Viewport viewport ) 83 { 84 if( viewport == null ) 85 throw new IllegalArgumentException( "parameter 'viewport' is null" ); 86 viewport_ = viewport; 87 font_ = new MonospacedFont( "ProFontWindows_12" ); 88 cursorPosition_ = new Coordinate(); 89 } 90 91 /*** 92 * {@inheritDoc} 93 */ 94 public void paint( final Graphics g ) 95 { 96 paintBackground( g ); 97 paintText( g ); 98 paintCursor( g ); 99 } 100 101 private void paintBackground( final Graphics g ) 102 { 103 g.setColor( BACKGROUND_COLOR ); 104 g.fillRect( 0, 0, width_, height_ ); 105 } 106 107 private void paintText( final Graphics g ) 108 { 109 final LineDrawer drawer = new LineDrawer( font_, width_ / font_.getWidth() + 1 ); 110 for( int y = 0; y < height_ / font_.getHeight() + 1; ++y ) 111 { 112 drawer.configure( g, y ); 113 viewport_.accept( drawer, y ); 114 } 115 } 116 117 private void paintCursor( final Graphics g ) 118 { 119 g.setColor( CURSOR_COLOR ); 120 g.fillRect( cursorPosition_.x_, cursorPosition_.y_, CURSOR_WIDTH, font_.getHeight() ); 121 } 122 123 /*** 124 * {@inheritDoc} 125 */ 126 public void resize( final int width, final int height ) 127 { 128 width_ = width; 129 height_ = height; 130 viewport_.resize( getColumns(), getLines() ); 131 } 132 133 /*** 134 * {@inheritDoc} 135 */ 136 public int getLayout() 137 { 138 return Item.LAYOUT_EXPAND + Item.LAYOUT_VEXPAND; 139 } 140 141 /*** 142 * {@inheritDoc} 143 */ 144 public int getWidth() 145 { 146 return width_; 147 } 148 149 /*** 150 * {@inheritDoc} 151 */ 152 public int getHeight() 153 { 154 return height_; 155 } 156 157 /*** 158 * {@inheritDoc} 159 */ 160 public boolean click( final int x, final int y ) 161 { 162 viewport_.click( pixelToColumn( x ), pixelToLine( y ) ); 163 return true; 164 } 165 166 /*** 167 * {@inheritDoc} 168 */ 169 public void drag( final int x, final int y ) 170 { 171 viewport_.drag( pixelToColumn( x ), pixelToLine( y ) ); 172 } 173 174 /*** 175 * {@inheritDoc} 176 */ 177 public void unclick( final int x, final int y ) 178 { 179 } 180 181 /*** 182 * {@inheritDoc} 183 */ 184 public void update( final Coordinate position ) 185 { 186 cursorPosition_.x_ = columnToPixel( position.x_ ); 187 cursorPosition_.y_ = lineToPixel( position.y_ ); 188 } 189 190 private int pixelToColumn( final int x ) 191 { 192 return (x + font_.getWidth() / 2) / font_.getWidth(); 193 } 194 195 private int pixelToLine( final int y ) 196 { 197 if( y == 0 ) 198 return -1; 199 return y / font_.getHeight(); 200 } 201 202 private int lineToPixel( final int line ) 203 { 204 return line * font_.getHeight(); 205 } 206 207 private int columnToPixel( final int column ) 208 { 209 final int x = column * font_.getWidth() - 1; 210 if( x == -1 ) 211 return 0; 212 return x; 213 } 214 215 /*** 216 * Retrieve the number of lines. 217 * 218 * @return the number of lines 219 */ 220 public int getLines() 221 { 222 return height_ / font_.getHeight(); 223 } 224 225 /*** 226 * Retrieve the number of columns. 227 * 228 * @return the number of columns 229 */ 230 public int getColumns() 231 { 232 return width_ / font_.getWidth(); 233 } 234 235 /*** 236 * Change the font. 237 * 238 * @param name the font resource name 239 */ 240 public void setFont( final String name ) 241 { 242 font_ = new MonospacedFont( name ); 243 viewport_.resize( getColumns(), getLines() ); 244 } 245 }