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.ui; 32 33 import java.util.Enumeration; 34 import java.util.Vector; 35 import javax.microedition.lcdui.Canvas; 36 import javax.microedition.lcdui.Graphics; 37 import javax.microedition.lcdui.Image; 38 import javax.microedition.lcdui.Item; 39 40 /*** 41 * This class implements a graphical container of components. 42 * 43 * @author Mathieu Champlon 44 * @version $Revision$ $Date$ 45 */ 46 public class Container extends Canvas implements ILayoutManager 47 { 48 /*** 49 * The components. 50 */ 51 private final Vector components_; 52 /*** 53 * The component holding focus. 54 */ 55 private Component focus_; 56 /*** 57 * The offscreen buffer to handle double buffering manually if needed. 58 */ 59 private Image offscreen_; 60 /*** 61 * Whether a refresh must be performed or not. 62 */ 63 private boolean mustRefresh_; 64 65 /*** 66 * Create a container. 67 */ 68 public Container() 69 { 70 setFullScreenMode( true ); 71 components_ = new Vector(); 72 mustRefresh_ = false; 73 } 74 75 /*** 76 * Add a component in the container. 77 * 78 * @param component the component 79 */ 80 public final void add( final IComponent component ) 81 { 82 components_.insertElementAt( new Component( component ), 0 ); 83 mustRefresh_ = true; 84 } 85 86 /*** 87 * {@inheritDoc} 88 */ 89 protected final void paint( final Graphics g ) 90 { 91 while( mustRefresh_ ) 92 layoutComponents( getWidth(), getHeight() ); 93 if( offscreen_ == null ) 94 paintComponents( g ); 95 else 96 { 97 paintComponents( offscreen_.getGraphics() ); 98 g.drawImage( offscreen_, 0, 0, Graphics.LEFT | Graphics.TOP ); 99 } 100 } 101 102 private void paintComponents( final Graphics g ) 103 { 104 final Enumeration components = components_.elements(); 105 while( components.hasMoreElements() ) 106 ((Component)components.nextElement()).paint( g ); 107 } 108 109 /*** 110 * {@inheritDoc} 111 */ 112 protected final void sizeChanged( final int width, final int height ) 113 { 114 if( !isDoubleBuffered() ) 115 offscreen_ = Image.createImage( width, height ); 116 mustRefresh_ = true; 117 } 118 119 /*** 120 * {@inheritDoc} 121 */ 122 public final void refresh() 123 { 124 mustRefresh_ = true; 125 repaint(); 126 } 127 128 private void layoutComponents( final int width, final int height ) 129 { 130 mustRefresh_ = false; 131 int w = width; 132 int h = height; 133 final Enumeration components = components_.elements(); 134 while( components.hasMoreElements() ) 135 { 136 int componentX = 0; 137 int componentY = 0; 138 int componentWidth, componentHeight; 139 final Component component = (Component)components.nextElement(); 140 if( expandsHorizontally( component ) ) 141 { 142 componentWidth = w; 143 w = width; 144 } 145 else 146 { 147 componentWidth = component.getWidth(); 148 componentX = w - componentWidth; 149 w -= componentWidth; 150 } 151 if( expandsVertically( component ) ) 152 componentHeight = h; 153 else 154 { 155 componentHeight = component.getHeight(); 156 componentY = h - componentHeight; 157 if( expandsHorizontally( component ) ) 158 h -= componentHeight; 159 } 160 component.move( componentX, componentY ); 161 component.resize( componentWidth, componentHeight ); 162 } 163 } 164 165 private boolean expandsVertically( final IComponent component ) 166 { 167 return (component.getLayout() & Item.LAYOUT_VEXPAND) != 0; 168 } 169 170 private boolean expandsHorizontally( final IComponent component ) 171 { 172 return (component.getLayout() & Item.LAYOUT_EXPAND) != 0; 173 } 174 175 /*** 176 * {@inheritDoc} 177 */ 178 protected final void pointerPressed( final int x, final int y ) 179 { 180 final Enumeration components = components_.elements(); 181 while( components.hasMoreElements() ) 182 { 183 final Component component = (Component)components.nextElement(); 184 if( component.click( x, y ) ) 185 { 186 focus_ = component; 187 repaint(); 188 } 189 } 190 } 191 192 /*** 193 * {@inheritDoc} 194 */ 195 protected final void pointerReleased( final int x, final int y ) 196 { 197 if( focus_ != null ) 198 { 199 focus_.unclick( x, y ); 200 focus_ = null; 201 repaint(); 202 } 203 } 204 205 /*** 206 * {@inheritDoc} 207 */ 208 protected final void pointerDragged( final int x, final int y ) 209 { 210 if( focus_ != null ) 211 { 212 focus_.drag( x, y ); 213 repaint(); 214 } 215 } 216 }