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 javax.microedition.lcdui.Graphics;
34 import javax.microedition.lcdui.Image;
35
36 /***
37 * This class implements a clickable button.
38 *
39 * @author Mathieu Champlon
40 * @version $Revision$ $Date$
41 */
42 public final class Button
43 {
44 /***
45 * The size of the border each side of the button.
46 */
47 private static final int BORDER_WIDTH = 2;
48 /***
49 * The size of the border above and under the button.
50 */
51 private static final int BORDER_HEIGHT = 2;
52 /***
53 * The command.
54 */
55 private final ICommand command_;
56 /***
57 * The command listener.
58 */
59 private final ICommandListener listener_;
60 /***
61 * The unclicked state image.
62 */
63 private final Image unclicked_;
64 /***
65 * The clicked state image.
66 */
67 private final Image clicked_;
68 /***
69 * Whether the button has been focused or not.
70 */
71 private boolean focus_;
72
73 /***
74 * Create a button.
75 *
76 * @param command the command
77 * @param listener the command listener
78 * @param image the image
79 */
80 public Button( final ICommand command, final ICommandListener listener, final String image )
81 {
82 if( command == null )
83 throw new IllegalArgumentException( "parameter 'command' is null" );
84 if( listener == null )
85 throw new IllegalArgumentException( "parameter 'listener' is null" );
86 command_ = command;
87 listener_ = listener;
88 unclicked_ = load( image );
89 clicked_ = load( getSelection( image ) );
90 }
91
92 /***
93 * Paint the button.
94 *
95 * @param g the graphics
96 */
97 public void paint( final Graphics g )
98 {
99 if( focus_ )
100 {
101 g.fillRect( 0, 0, getWidth(), getHeight() );
102 g.drawImage( clicked_, BORDER_WIDTH, BORDER_HEIGHT, Graphics.TOP | Graphics.LEFT );
103 }
104 else
105 g.drawImage( unclicked_, BORDER_WIDTH, BORDER_HEIGHT, Graphics.TOP | Graphics.LEFT );
106 }
107
108 private Image load( final String filename )
109 {
110 try
111 {
112 return Image.createImage( filename );
113 }
114 catch( Exception e )
115 {
116 throw new RuntimeException( e.getMessage() );
117 }
118 }
119
120 private String getSelection( final String filename )
121 {
122 return getPath( filename ) + "/s_" + getFilename( filename );
123 }
124
125 private String getFilename( final String filename )
126 {
127 final int index = filename.lastIndexOf( '/' );
128 if( index == -1 )
129 return filename;
130 return filename.substring( index + 1 );
131 }
132
133 private String getPath( final String filename )
134 {
135 final int index = filename.lastIndexOf( '/' );
136 if( index == -1 )
137 return "";
138 return filename.substring( 0, index );
139 }
140
141 /***
142 * Retrieve the width.
143 *
144 * @return the wdth in pixels
145 */
146 public int getWidth()
147 {
148 return unclicked_.getWidth() + 2 * BORDER_WIDTH;
149 }
150
151 /***
152 * Retrieve the height.
153 *
154 * @return the height in pixels
155 */
156 public int getHeight()
157 {
158 return unclicked_.getHeight() + 2 * BORDER_HEIGHT;
159 }
160
161 /***
162 * Enter the button.
163 */
164 public void enter()
165 {
166 focus_ = true;
167 }
168
169 /***
170 * Leave the button.
171 */
172 public void leave()
173 {
174 focus_ = false;
175 }
176
177 /***
178 * Trigger the button if in enter state.
179 */
180 public void trigger()
181 {
182 if( focus_ )
183 listener_.triggered( command_ );
184 focus_ = false;
185 }
186 }