001 package org.gwtbootstrap3.client.ui.base.button;
002
003 /*
004 * #%L
005 * GwtBootstrap3
006 * %%
007 * Copyright (C) 2013 GwtBootstrap3
008 * %%
009 * Licensed under the Apache License, Version 2.0 (the "License");
010 * you may not use this file except in compliance with the License.
011 * You may obtain a copy of the License at
012 *
013 * http://www.apache.org/licenses/LICENSE-2.0
014 *
015 * Unless required by applicable law or agreed to in writing, software
016 * distributed under the License is distributed on an "AS IS" BASIS,
017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018 * See the License for the specific language governing permissions and
019 * limitations under the License.
020 * #L%
021 */
022
023 import java.util.List;
024
025 import org.gwtbootstrap3.client.ui.base.ComplexWidget;
026 import org.gwtbootstrap3.client.ui.base.HasActive;
027 import org.gwtbootstrap3.client.ui.base.HasDataTarget;
028 import org.gwtbootstrap3.client.ui.base.HasSize;
029 import org.gwtbootstrap3.client.ui.base.HasType;
030 import org.gwtbootstrap3.client.ui.base.helper.StyleHelper;
031 import org.gwtbootstrap3.client.ui.base.mixin.ActiveMixin;
032 import org.gwtbootstrap3.client.ui.base.mixin.DataTargetMixin;
033 import org.gwtbootstrap3.client.ui.base.mixin.FocusableMixin;
034 import org.gwtbootstrap3.client.ui.constants.Attributes;
035 import org.gwtbootstrap3.client.ui.constants.ButtonDismiss;
036 import org.gwtbootstrap3.client.ui.constants.ButtonSize;
037 import org.gwtbootstrap3.client.ui.constants.ButtonType;
038 import org.gwtbootstrap3.client.ui.constants.Styles;
039
040 import com.google.gwt.dom.client.Document;
041 import com.google.gwt.dom.client.Element;
042 import com.google.gwt.dom.client.NativeEvent;
043 import com.google.gwt.event.dom.client.ClickEvent;
044 import com.google.gwt.event.dom.client.ClickHandler;
045 import com.google.gwt.event.dom.client.DomEvent;
046 import com.google.gwt.event.dom.client.HasAllMouseHandlers;
047 import com.google.gwt.event.dom.client.HasClickHandlers;
048 import com.google.gwt.event.dom.client.MouseDownEvent;
049 import com.google.gwt.event.dom.client.MouseDownHandler;
050 import com.google.gwt.event.dom.client.MouseMoveEvent;
051 import com.google.gwt.event.dom.client.MouseMoveHandler;
052 import com.google.gwt.event.dom.client.MouseOutEvent;
053 import com.google.gwt.event.dom.client.MouseOutHandler;
054 import com.google.gwt.event.dom.client.MouseOverEvent;
055 import com.google.gwt.event.dom.client.MouseOverHandler;
056 import com.google.gwt.event.dom.client.MouseUpEvent;
057 import com.google.gwt.event.dom.client.MouseUpHandler;
058 import com.google.gwt.event.dom.client.MouseWheelEvent;
059 import com.google.gwt.event.dom.client.MouseWheelHandler;
060 import com.google.gwt.event.shared.HandlerRegistration;
061 import com.google.gwt.user.client.ui.Focusable;
062 import com.google.gwt.user.client.ui.HasEnabled;
063 import com.google.gwt.user.client.ui.Widget;
064
065 /**
066 * Abstract base class for different kinds of buttons.
067 *
068 * @author Sven Jacobs
069 * @author Joshua Godi
070 */
071 public abstract class AbstractButton extends ComplexWidget implements HasEnabled, HasActive, HasType<ButtonType>,
072 HasSize<ButtonSize>, HasDataTarget, HasClickHandlers, Focusable, HasAllMouseHandlers {
073
074 public class ButtonStateHandler {
075 private ButtonStateHandler() {
076 }
077
078 public void loading() {
079 button(getElement(), "loading");
080 }
081
082 public void reset() {
083 button(getElement(), "reset");
084 }
085
086 /**
087 * Resets button to specified text state.
088 *
089 * @param state Text state
090 */
091 public void reset(final String state) {
092 button(getElement(), state);
093 }
094 }
095
096 private final ButtonStateHandler buttonStateHandler = new ButtonStateHandler();
097 private final DataTargetMixin<AbstractButton> targetMixin = new DataTargetMixin<AbstractButton>(this);
098 private final ActiveMixin<AbstractButton> activeMixin = new ActiveMixin<AbstractButton>(this);
099 private final FocusableMixin<AbstractButton> focusableMixin = new FocusableMixin<AbstractButton>(this);
100
101 /**
102 * Creates button with DEFAULT type.
103 */
104 protected AbstractButton() {
105 this(ButtonType.DEFAULT);
106 }
107
108 protected AbstractButton(final ButtonType type) {
109 setElement(createElement());
110 setStyleName(Styles.BTN);
111 setType(type);
112 }
113
114 @Override
115 public boolean isActive() {
116 return activeMixin.isActive();
117 }
118
119 @Override
120 public void setActive(final boolean active) {
121 activeMixin.setActive(active);
122 }
123
124 @Override
125 public void setEnabled(final boolean enabled) {
126 getElement().setPropertyBoolean("disabled", !enabled);
127 }
128
129 @Override
130 public boolean isEnabled() {
131 return !getElement().getPropertyBoolean("disabled");
132 }
133
134 @Override
135 public HandlerRegistration addClickHandler(final ClickHandler handler) {
136 return addDomHandler(handler, ClickEvent.getType());
137 }
138
139 /**
140 * Sets type of button.
141 *
142 * @param type Type of button
143 */
144 @Override
145 public void setType(final ButtonType type) {
146 StyleHelper.addUniqueEnumStyleName(this, ButtonType.class, type);
147 }
148
149 @Override
150 public ButtonType getType() {
151 return ButtonType.fromStyleName(getStyleName());
152 }
153
154 /**
155 * Sets size of button.
156 *
157 * @param size Size of button
158 */
159 @Override
160 public void setSize(final ButtonSize size) {
161 StyleHelper.addUniqueEnumStyleName(this, ButtonSize.class, size);
162 }
163
164 @Override
165 public ButtonSize getSize() {
166 return ButtonSize.fromStyleName(getStyleName());
167 }
168
169 @Override
170 public void setDataTargetWidgets(final List<Widget> widgets) {
171 targetMixin.setDataTargetWidgets(widgets);
172 }
173
174 @Override
175 public void setDataTargetWidget(final Widget widget) {
176 targetMixin.setDataTargetWidget(widget);
177 }
178
179 @Override
180 public void setDataTarget(final String dataTarget) {
181 targetMixin.setDataTarget(dataTarget);
182 }
183
184 @Override
185 public String getDataTarget() {
186 return targetMixin.getDataTarget();
187 }
188
189 @Override
190 public int getTabIndex() {
191 return focusableMixin.getTabIndex();
192 }
193
194 @Override
195 public void setAccessKey(final char key) {
196 focusableMixin.setAccessKey(key);
197 }
198
199 @Override
200 public void setFocus(final boolean focused) {
201 focusableMixin.setFocus(focused);
202 }
203
204 @Override
205 public void setTabIndex(final int index) {
206 focusableMixin.setTabIndex(index);
207 }
208
209 @Override
210 public HandlerRegistration addMouseDownHandler(final MouseDownHandler handler) {
211 return addDomHandler(handler, MouseDownEvent.getType());
212 }
213
214 @Override
215 public HandlerRegistration addMouseMoveHandler(final MouseMoveHandler handler) {
216 return addDomHandler(handler, MouseMoveEvent.getType());
217 }
218
219 @Override
220 public HandlerRegistration addMouseOutHandler(final MouseOutHandler handler) {
221 return addDomHandler(handler, MouseOutEvent.getType());
222 }
223
224 @Override
225 public HandlerRegistration addMouseOverHandler(final MouseOverHandler handler) {
226 return addDomHandler(handler, MouseOverEvent.getType());
227 }
228
229 @Override
230 public HandlerRegistration addMouseUpHandler(final MouseUpHandler handler) {
231 return addDomHandler(handler, MouseUpEvent.getType());
232 }
233
234 @Override
235 public HandlerRegistration addMouseWheelHandler(final MouseWheelHandler handler) {
236 return addDomHandler(handler, MouseWheelEvent.getType());
237 }
238
239 /**
240 * Makes button a block level element that spawns full width of parent.
241 *
242 * @param block True for block level element
243 */
244 public void setBlock(final boolean block) {
245 if (block) {
246 addStyleName(Styles.BTN_BLOCK);
247 } else {
248 removeStyleName(Styles.BTN_BLOCK);
249 }
250 }
251
252 /**
253 * Sets dismiss type of button.
254 * <p/>
255 * If button is inside a
256 * {@link org.gwtbootstrap3.client.ui.Modal} and dismiss type is
257 * {@code MODAL} the button will act as the dismiss (close) button for this
258 * Modal. Same goes for {@link org.gwtbootstrap3.client.ui.Alert}
259 * and dismiss type {@code ALERT}.
260 *
261 * @param dismiss Dismiss type of button
262 * @see org.gwtbootstrap3.client.ui.Modal
263 * @see org.gwtbootstrap3.client.ui.Alert
264 */
265 public void setDataDismiss(final ButtonDismiss dismiss) {
266 if (dismiss != null) {
267 getElement().setAttribute(Attributes.DATA_DISMISS, dismiss.getDismiss());
268 } else {
269 getElement().removeAttribute(Attributes.DATA_DISMISS);
270 }
271 }
272
273 public void setDataLoadingText(final String loadingText) {
274 if (loadingText != null) {
275 getElement().setAttribute(Attributes.DATA_LOADING_TEXT, loadingText);
276 } else {
277 getElement().removeAttribute(Attributes.DATA_LOADING_TEXT);
278 }
279 }
280
281 public void toggle() {
282 button(getElement(), "toggle");
283 }
284
285 public ButtonStateHandler state() {
286 return buttonStateHandler;
287 }
288
289 public void click() {
290 final NativeEvent event = Document.get().createClickEvent(0, 0, 0, 0, 0, false, false, false, false);
291 DomEvent.fireNativeEvent(event, this);
292 }
293
294 protected abstract Element createElement();
295
296 // @formatter:off
297
298 private native void button(final Element e, final String arg) /*-{
299 $wnd.jQuery(e).button(arg);
300 }-*/;
301 }