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