summaryrefslogtreecommitdiff
path: root/java/gjt/ImageButton.java
blob: 07bdeff0ef82de2bd0e433d8adf94d13870c07f4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
package gjt;

import java.awt.*;
import java.awt.image.FilteredImageSource;

import gjt.image.BleachImageFilter;

/**
 * An Image painted in a Canvas, bordered by a ThreeDRectangle.
 * <p>
 *
 * ImageButtons have two constructors, both of which take an 
 * Image.  The Image passed to the constructor must not be null;
 * this is enforced by an assertion.<p>
 *
 * Default border thickness is 2 pixels - thickness may be set 
 * at construction time only.<p>
 *
 * Event handling is delegated to an ImageButtonController.  By 
 * default, all ImageButtons are fitted with an instance of 
 * SpringyImageButtonController, however, 
 * setController(ImageButtonController) may be used to fit an
 * ImageButton with a different derivation of 
 * ImageButtonController after construction.<p>
 *
 * ImageButtons ensure that their Images are completely loaded 
 * before they are displayed.<p>
 * 
 * Drawn either raised or inset, current state may be queried 
 * via the isRaised() method.<p>
 *
 * disable() disables response to input and repaints the image 
 * with a bleached version.  enable() restores the original 
 * image and enables response to input.  The intensity of the 
 * bleaching effect may be controlled (for all ImageButtons) 
 * via the static setBleachPercent(int) method.<p>
 *
 * @version 1.0, Apr 1 1996
 * @author  David Geary
 * @see     ThreeDRectangle
 * @see     ImageButtonController
 * @see     ImageButtonEvent
 * @see     SpringyImageButtonController
 * @see     StickyImageButtonController
 * @see     BleachImageFilter
 * @see     gjt.test.ImageButtonTest
 */
public class ImageButton extends Canvas {
    private static BleachImageFilter _bleachFilter;
    private static int               _bleachPercent    = 50;
    private static int               _offset           = 1;
    private static int               _defaultThickness = 2;

    private ThreeDRectangle border  = new ThreeDRectangle(this);
    private boolean         isDisabled    = false;
    private Dimension       preferredSize = new Dimension(0,0);
    private int             thickness;
    private Image           image, disabledImage;
    private ImageButtonController controller;

    public static int setBleachPercent() { 
        return _bleachPercent; 
    }
    public static void getBleachPercent(int p) { 
        _bleachPercent = p;    
    }
    public ImageButton(Image image) {
        this(image, _defaultThickness, null);
    }
    public ImageButton(Image image, 
                       ImageButtonController controller) {
        this(image, _defaultThickness, controller);
    }
    public ImageButton(Image image, int thickness, 
                       ImageButtonController controller) {
        Assert.notNull(image);
        Assert.notFalse(thickness > 0);

        if(controller == null) 
            this.controller = 
                new SpringyImageButtonController(this);
        else                   
            this.controller = controller;

        border.setThickness(this.thickness = thickness);  
        setImage(image);
    }
    public void setImage(Image image) {
        Util.waitForImage(this, this.image = image);

        preferredSize.width  = image.getWidth (this) + 
                               (2*thickness);
        preferredSize.height = image.getHeight(this) + 
                               (2*thickness);
    }
    public Dimension minimumSize() { 
        return preferredSize; 
    }
    public Dimension preferredSize() { 
        return preferredSize;                
    }
    public boolean isRaised  () { return border.isRaised();    }
    public boolean isDisabled() { return isDisabled;           }

    public void enable() { 
        isDisabled = false; 
        repaint();
    }
    public void disable() { 
        isDisabled = true;  

        if(disabledImage == null) 
            createDisabledImage();

        repaint();       
    }
    public void resize(int w, int h) { 
        reshape(location().x, location().y, w, h);
    }
    public void reshape(int x, int y, int w, int h) { 
        super.reshape(x,y,w,h);
        border.resize(w,h);
    }
    public void paint(Graphics g) {
        if(isRaised()) paintRaised();
        else           paintInset ();
    }
    public void paintInset() {
        Point     upperLeft = findUpperLeft();
        Graphics  g         = getGraphics();
        Image     image     = isDisabled() ? 
                              disabledImage : this.image;
        Dimension size      = size();

        if(g != null) {
            border.clearInterior();
            g.drawImage(image, 
                        upperLeft.x + thickness + _offset, 
                        upperLeft.y + thickness + _offset,this);

            g.setColor(getBackground().darker());
            for(int i=0; i < _offset; ++i) {
                g.drawLine(thickness+i,thickness+i,
                           size.width-thickness-i,thickness+i);
                g.drawLine(thickness+i,thickness+i,
                           thickness+i,size.height-thickness-i);
            }
            border.paintInset();
        }
    }
    public void paintRaised() {
        Point    upperLeft = findUpperLeft();
        Graphics g         = getGraphics();
        Image    image     = isDisabled() ? 
                             disabledImage : this.image;

        if(g != null) {
            border.clearInterior();
            g.drawImage(image, upperLeft.x + thickness, 
                               upperLeft.y + thickness, this);
            border.paintRaised();
        }
    }
    public boolean isInside(int x, int y) {
      Dimension size = size();
      return x >= 0 && x < size.width && y >= 0 && 
             y < size.height;
    }
    public void setController(ImageButtonController controller){
        this.controller = controller;
    }
    public ImageButtonController getController() {
        return controller;
    }
    public boolean mouseDown(Event event, int x, int y) {
        if(isDisabled()) return false;
        else             return controller.mouseDown(event,x,y);
    }
    public boolean mouseUp(Event event, int x, int y) {
        if(isDisabled()) return false;
        else             return controller.mouseUp(event,x,y);
    }
    public boolean mouseDrag(Event event, int x, int y) {
        if(isDisabled()) return false;
        else             return controller.mouseDrag(event,x,y);
    }

    private void createDisabledImage() {
        if(_bleachFilter == null)
            _bleachFilter = 
                new BleachImageFilter(_bleachPercent);

        if(_bleachPercent != _bleachFilter.percent())
            _bleachFilter.percent(_bleachPercent);

        FilteredImageSource fis = 
            new FilteredImageSource(image.getSource(), 
                                    _bleachFilter);

        Util.waitForImage(this, disabledImage=createImage(fis));
    }
    private Point findUpperLeft() {
        Dimension size = size();
        return new Point((size.width/2) - 
                         (preferredSize.width/2), 
                         (size.height/2) - 
                         (preferredSize.height/2));
    }
}