Statistics
| Branch: | Tag: | Revision:

root / web_client / src / gr / grnet / pithos / web / client / components / TristateCheckBox.java @ 58777026

History | View | Annotate | Download (5.2 kB)

1
/*
2
 * Copyright 2011 GRNET S.A. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or
5
 * without modification, are permitted provided that the following
6
 * conditions are met:
7
 *
8
 *   1. Redistributions of source code must retain the above
9
 *      copyright notice, this list of conditions and the following
10
 *      disclaimer.
11
 *
12
 *   2. Redistributions in binary form must reproduce the above
13
 *      copyright notice, this list of conditions and the following
14
 *      disclaimer in the documentation and/or other materials
15
 *      provided with the distribution.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
18
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
21
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
24
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28
 * POSSIBILITY OF SUCH DAMAGE.
29
 *
30
 * The views and conclusions contained in the software and
31
 * documentation are those of the authors and should not be
32
 * interpreted as representing official policies, either expressed
33
 * or implied, of GRNET S.A.
34
 */
35
package gr.grnet.pithos.web.client.components;
36

    
37
import com.google.gwt.event.dom.client.ClickEvent;
38
import com.google.gwt.event.dom.client.ClickHandler;
39
import com.google.gwt.event.logical.shared.ValueChangeEvent;
40
import com.google.gwt.event.logical.shared.ValueChangeHandler;
41
import com.google.gwt.event.shared.HandlerRegistration;
42
import com.google.gwt.user.client.DOM;
43
import com.google.gwt.user.client.Element;
44
import com.google.gwt.user.client.ui.FocusWidget;
45
import com.google.gwt.user.client.ui.HasValue;
46

    
47
/**
48
 * Checkbox with three states (checked, unchecked and undefined).
49
 *
50
 */
51
public class TristateCheckBox extends FocusWidget implements HasValue<Boolean> {
52

    
53
    private static final String UNCHECKED_IMG = "images/tristate_unchecked.gif";
54

    
55
    private static final String UNKNOWN_IMG = "images/tristate_intermediate.gif";
56

    
57
    private static final String CHECKED_IMG = "images/tristate_checked.gif";
58

    
59
    private final Element buttonElement = DOM.createElement("input");
60

    
61
    private boolean valueChangeHandlerInitialized;
62

    
63
    private Boolean value;
64

    
65
    private Boolean initialValue;
66

    
67
    public TristateCheckBox(final Boolean state) {
68
        DOM.setElementProperty(buttonElement, "type", "image");
69
        setElement(buttonElement);
70
        setStyleName("tristateCheckbox");
71
        DOM.setElementAttribute(buttonElement, "src", UNCHECKED_IMG);
72

    
73
        addClickHandler(new ClickHandler() {
74

    
75
                        @Override
76
                        public void onClick(ClickEvent event) {
77
                final String img = DOM.getElementAttribute(buttonElement, "src");
78
                String newImg;
79
                if (img.endsWith(UNCHECKED_IMG))
80
                                        newImg = CHECKED_IMG;
81
                                else if (img.endsWith(UNKNOWN_IMG))
82
                                        newImg = UNCHECKED_IMG;
83
                                else if (img.endsWith(CHECKED_IMG))
84
                                        if (initialValue==null) // Only show unknown choice if there is a reason for it
85
                                                newImg = UNKNOWN_IMG;
86
                                        else
87
                                                newImg = UNCHECKED_IMG;
88
                                else
89
                                        throw new IllegalArgumentException("unknown checkbox state");
90

    
91
                DOM.setElementAttribute(buttonElement, "src", newImg);
92
            }
93

    
94
        });
95

    
96
        setState(state);
97
        initialValue = state;
98
    }
99

    
100
    public void setState(final Boolean state) {
101
            DOM.setElementAttribute(buttonElement, "src", state == null ?
102
                            UNKNOWN_IMG : state.booleanValue() ? CHECKED_IMG : UNCHECKED_IMG);
103
    }
104

    
105
    public Boolean getState() {
106
        final String img = DOM.getElementAttribute(buttonElement, "src");
107
        if (img.endsWith(UNCHECKED_IMG))
108
                        return Boolean.FALSE;
109
                else if (img.endsWith(UNKNOWN_IMG))
110
                        return null;
111
                else if (img.endsWith(CHECKED_IMG))
112
                        return Boolean.TRUE;
113
                else
114
                        throw new IllegalArgumentException("unknown checkbox state");
115
    }
116

    
117
    @Override
118
        public Boolean getValue() {
119
        return value;
120
    }
121

    
122
    @Override
123
        public void setValue(final Boolean _value) {
124
        value = _value;
125
    }
126

    
127
    @Override
128
        public HandlerRegistration addValueChangeHandler(
129
            ValueChangeHandler<Boolean> handler) {
130
            // Is this the first value change handler? If so, time to add handlers
131
            if (!valueChangeHandlerInitialized) {
132
                    ensureDomEventHandlers();
133
                    valueChangeHandlerInitialized = true;
134
            }
135
            return addHandler(handler, ValueChangeEvent.getType());
136
          }
137

    
138
    protected void ensureDomEventHandlers() {
139
        addClickHandler(new ClickHandler() {
140
                @Override
141
                        public void onClick(ClickEvent event) {
142
                        ValueChangeEvent.fire(TristateCheckBox.this, getValue());
143
                }
144
        });
145
    }
146

    
147
    @Override
148
        public void setValue(Boolean _value, boolean fireEvents) {
149
        Boolean oldValue = getValue();
150
        setValue(_value);
151
        if (_value.equals(oldValue))
152
                        return;
153
        if (fireEvents)
154
                        ValueChangeEvent.fire(this, _value);
155
    }
156

    
157
}