001 /* 002 * Copyright 2012 GWT-Bootstrap 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package com.github.gwtbootstrap.client.ui; 017 018 import com.github.gwtbootstrap.client.ui.base.HasType; 019 import com.github.gwtbootstrap.client.ui.base.IconAnchor; 020 import com.github.gwtbootstrap.client.ui.base.NavbarButton; 021 import com.github.gwtbootstrap.client.ui.base.StyleHelper; 022 import com.github.gwtbootstrap.client.ui.constants.ButtonType; 023 import com.github.gwtbootstrap.client.ui.constants.Constants; 024 import com.github.gwtbootstrap.client.ui.constants.IconType; 025 import com.github.gwtbootstrap.client.ui.resources.ButtonSize; 026 import com.google.gwt.dom.client.Element; 027 import com.google.gwt.event.dom.client.BlurEvent; 028 import com.google.gwt.event.dom.client.BlurHandler; 029 import com.google.gwt.event.dom.client.ClickEvent; 030 import com.google.gwt.event.dom.client.ClickHandler; 031 import com.google.gwt.event.dom.client.DoubleClickEvent; 032 import com.google.gwt.event.dom.client.DoubleClickHandler; 033 import com.google.gwt.event.dom.client.DragEndEvent; 034 import com.google.gwt.event.dom.client.DragEndHandler; 035 import com.google.gwt.event.dom.client.DragEnterEvent; 036 import com.google.gwt.event.dom.client.DragEnterHandler; 037 import com.google.gwt.event.dom.client.DragEvent; 038 import com.google.gwt.event.dom.client.DragHandler; 039 import com.google.gwt.event.dom.client.DragLeaveEvent; 040 import com.google.gwt.event.dom.client.DragLeaveHandler; 041 import com.google.gwt.event.dom.client.DragOverEvent; 042 import com.google.gwt.event.dom.client.DragOverHandler; 043 import com.google.gwt.event.dom.client.DragStartEvent; 044 import com.google.gwt.event.dom.client.DragStartHandler; 045 import com.google.gwt.event.dom.client.DropEvent; 046 import com.google.gwt.event.dom.client.DropHandler; 047 import com.google.gwt.event.dom.client.FocusEvent; 048 import com.google.gwt.event.dom.client.FocusHandler; 049 import com.google.gwt.event.dom.client.GestureChangeEvent; 050 import com.google.gwt.event.dom.client.GestureChangeHandler; 051 import com.google.gwt.event.dom.client.GestureEndEvent; 052 import com.google.gwt.event.dom.client.GestureEndHandler; 053 import com.google.gwt.event.dom.client.GestureStartEvent; 054 import com.google.gwt.event.dom.client.GestureStartHandler; 055 import com.google.gwt.event.dom.client.HasAllDragAndDropHandlers; 056 import com.google.gwt.event.dom.client.HasAllFocusHandlers; 057 import com.google.gwt.event.dom.client.HasAllGestureHandlers; 058 import com.google.gwt.event.dom.client.HasAllKeyHandlers; 059 import com.google.gwt.event.dom.client.HasAllMouseHandlers; 060 import com.google.gwt.event.dom.client.HasAllTouchHandlers; 061 import com.google.gwt.event.dom.client.HasClickHandlers; 062 import com.google.gwt.event.dom.client.HasDoubleClickHandlers; 063 import com.google.gwt.event.dom.client.KeyDownEvent; 064 import com.google.gwt.event.dom.client.KeyDownHandler; 065 import com.google.gwt.event.dom.client.KeyPressEvent; 066 import com.google.gwt.event.dom.client.KeyPressHandler; 067 import com.google.gwt.event.dom.client.KeyUpEvent; 068 import com.google.gwt.event.dom.client.KeyUpHandler; 069 import com.google.gwt.event.dom.client.MouseDownEvent; 070 import com.google.gwt.event.dom.client.MouseDownHandler; 071 import com.google.gwt.event.dom.client.MouseMoveEvent; 072 import com.google.gwt.event.dom.client.MouseMoveHandler; 073 import com.google.gwt.event.dom.client.MouseOutEvent; 074 import com.google.gwt.event.dom.client.MouseOutHandler; 075 import com.google.gwt.event.dom.client.MouseOverEvent; 076 import com.google.gwt.event.dom.client.MouseOverHandler; 077 import com.google.gwt.event.dom.client.MouseUpEvent; 078 import com.google.gwt.event.dom.client.MouseUpHandler; 079 import com.google.gwt.event.dom.client.MouseWheelEvent; 080 import com.google.gwt.event.dom.client.MouseWheelHandler; 081 import com.google.gwt.event.dom.client.TouchCancelEvent; 082 import com.google.gwt.event.dom.client.TouchCancelHandler; 083 import com.google.gwt.event.dom.client.TouchEndEvent; 084 import com.google.gwt.event.dom.client.TouchEndHandler; 085 import com.google.gwt.event.dom.client.TouchMoveEvent; 086 import com.google.gwt.event.dom.client.TouchMoveHandler; 087 import com.google.gwt.event.dom.client.TouchStartEvent; 088 import com.google.gwt.event.dom.client.TouchStartHandler; 089 import com.google.gwt.event.shared.HandlerRegistration; 090 import com.google.gwt.user.client.ui.HasEnabled; 091 092 //@formatter:off 093 /** 094 * Button with optional icon. 095 * 096 * <p> 097 * <h3>UiBinder Usage:</h3> 098 * 099 * <pre> 100 * {@code <b:Button icon="TRASH" type="ERROR" toggle="true" loadingText="I'm loading..." completeText="Oh hoh, I completed the action!">Delete</b:Button>} 101 * </pre> 102 * 103 * All arguments are optional. 104 * </p> 105 * 106 * @since 2.0.4.0 107 * 108 * @author Carlos Alexandro Becker 109 * 110 * @author Dominik Mayer 111 * 112 * @see <a 113 * href="http://twitter.github.com/bootstrap/base-css.html#buttons">Bootstrap 114 * documentation</a> 115 * @see ButtonGroup 116 * @see ButtonToolbar 117 * @see DropdownButton 118 * @see SplitDropdownButton 119 * @see NavbarButton 120 */ 121 // @formatter:on 122 public class Button extends IconAnchor implements HasClickHandlers, 123 HasDoubleClickHandlers, HasEnabled, HasType<ButtonType>, 124 HasAllDragAndDropHandlers, HasAllFocusHandlers, HasAllGestureHandlers, 125 HasAllKeyHandlers, HasAllMouseHandlers, HasAllTouchHandlers { 126 127 private final LoadingStateBehavior state = new LoadingStateBehavior(); 128 private ButtonType type; 129 private ButtonSize size; 130 131 /** 132 * Creates an empty Button. 133 */ 134 public Button() { 135 super(); 136 addStyleName(Constants.BTN); 137 } 138 139 /** 140 * Creates an Button with ClickHandler 141 * @param handler Butotn ClickHandler 142 */ 143 public Button(ClickHandler handler) { 144 this(); 145 addClickHandler(handler); 146 147 } 148 149 /** 150 * Creates a Button with the given caption. 151 * 152 * @param caption 153 * the caption of the Button 154 */ 155 public Button(String caption) { 156 this(); 157 setText(caption); 158 } 159 160 /** 161 * Create Button with click handler. 162 * @param caption the caption of the Button 163 * @param handler Button Click Handler 164 */ 165 public Button(String caption, ClickHandler handler) { 166 this(caption); 167 addClickHandler(handler); 168 } 169 170 /** 171 * Creates a Button with the given caption and icon. 172 * 173 * @param caption 174 * the caption of the Button 175 * @param icon 176 * the Icon on the caption's left 177 */ 178 public Button(String caption, IconType icon) { 179 this(caption); 180 setIcon(icon); 181 } 182 183 /** 184 * Creates a Button with the given caption and icon and ClickHandler. 185 * 186 * @param caption 187 * the caption of the Button 188 * @param icon 189 * the Icon on the caption's left 190 * @param handler 191 * the ClickHandler of the Button. 192 */ 193 public Button(String caption, IconType icon, ClickHandler handler) { 194 this(caption, icon); 195 addClickHandler(handler); 196 } 197 198 /** 199 * Sets the type of the Button. 200 * <p> 201 * Different types give the button a different look. 202 * 203 * @param type 204 * the type of the Button. 205 */ 206 public void setType(ButtonType type) { 207 this.type = type; 208 StyleHelper.changeStyle(this, type, ButtonType.class); 209 } 210 211 /** 212 * Sets the size of the Button. 213 * 214 * @param size 215 * the size of the Button. 216 */ 217 public void setSize(ButtonSize size) { 218 this.size = size; 219 StyleHelper.changeStyle(this, size, ButtonSize.class); 220 } 221 222 /** 223 * Whether the Button is enabled or disabled. 224 * <p> 225 * A disabled widget cannot be used. 226 * 227 * @return <code>false</code> if the Button is disabled. 228 */ 229 public boolean isEnabled() { 230 return !getStyleName().contains(Constants.DISABLED); 231 } 232 233 /** 234 * Sets whether the Button is enabled or disabled. 235 * <p> 236 * A disabled widget cannot be used. 237 * 238 * @param enabled 239 * <code>false</code> if the Button should be disabled. Default: 240 * <code>true</code> 241 */ 242 public void setEnabled(boolean enabled) { 243 if (enabled) 244 removeStyleName(Constants.DISABLED); 245 else 246 addStyleName(Constants.DISABLED); 247 } 248 249 /** 250 * Enable ou disable the data-toggle behavior. 251 * 252 * @param toggle 253 * <code>true</code> will enable this behavior. 254 * <code>false</code> will disable it or do nothing if it never 255 * was enabled. 256 */ 257 public void setToggle(boolean toggle) { 258 if (toggle) 259 getElement().setAttribute(Constants.DATA_TOGGLE, "button"); 260 else 261 getElement().removeAttribute(Constants.DATA_TOGGLE); 262 } 263 264 /** 265 * Verify if the property "toggle" is set. 266 * 267 * @return true: if the data-toggle is equal 'button' 268 * false: otherwise 269 */ 270 public boolean isToggle() { 271 return getElement().getAttribute(Constants.DATA_TOGGLE).equals("button"); 272 } 273 274 /** 275 * Verify if the button is toggled. 276 * @return true: if yes (it will contain the "active" styleclass 277 * false: otherwise. 278 */ 279 public boolean isToggled() { 280 return getStyleName().toLowerCase().contains("active"); 281 } 282 283 /** 284 * Set a Loading Text to show when some action are in work with this button. 285 * 286 * @see LoadingStateBehavior 287 * @param text 288 */ 289 public void setLoadingText(String text) { 290 if (text == null || text.trim().isEmpty()) { 291 getElement().removeAttribute(Constants.DATA_LOADING_TEXT); 292 return; 293 } 294 295 getElement().setAttribute(Constants.DATA_LOADING_TEXT, text); 296 } 297 298 /** 299 * Set a Loading Text to show when some action are completed with this 300 * button. 301 * 302 * @see LoadingStateBehavior 303 * @param text 304 */ 305 public void setCompleteText(String text) { 306 if (text == null || text.trim().isEmpty()) { 307 getElement().removeAttribute(Constants.DATA_COMPLETE_TEXT); 308 return; 309 } 310 311 getElement().setAttribute(Constants.DATA_COMPLETE_TEXT, text); 312 } 313 314 /** 315 * A simple DSL to change the button state to loading, complete, or reset 316 * it. 317 * 318 * @return 319 */ 320 public LoadingStateBehavior state() { 321 return state; 322 } 323 324 /** 325 * A simple class to encapsulate the button state managing from the user. 326 * 327 * @author Carlos Alexandro Becker 328 */ 329 public class LoadingStateBehavior { 330 331 /** 332 * put the button in the loading state. 333 */ 334 public void loading() { 335 setLoadingBehavior("loading"); 336 } 337 338 /** 339 * reset the button state. 340 */ 341 public void reset() { 342 setLoadingBehavior("reset"); 343 } 344 345 /** 346 * put the button in the completed state. 347 */ 348 public void complete() { 349 setLoadingBehavior("complete"); 350 } 351 352 private void setLoadingBehavior(String behavior) { 353 setLoadingBehavior(getElement(), behavior); 354 } 355 356 private native void setLoadingBehavior(Element e, String behavior) /*-{ 357 $wnd.jQuery(e).button(behavior); 358 }-*/; 359 } 360 361 /** 362 * {@inheritDoc} 363 */ 364 public HandlerRegistration addClickHandler(ClickHandler handler) { 365 return addDomHandler(handler, ClickEvent.getType()); 366 } 367 368 /** 369 * {@inheritDoc} 370 */ 371 public HandlerRegistration addDoubleClickHandler(DoubleClickHandler handler) { 372 return addDomHandler(handler, DoubleClickEvent.getType()); 373 } 374 375 /** 376 * {@inheritDoc} 377 */ 378 public HandlerRegistration addDragEndHandler(DragEndHandler handler) { 379 return addDomHandler(handler, DragEndEvent.getType()); 380 } 381 382 /** 383 * {@inheritDoc} 384 */ 385 public HandlerRegistration addDragEnterHandler(DragEnterHandler handler) { 386 return addDomHandler(handler, DragEnterEvent.getType()); 387 } 388 389 /** 390 * {@inheritDoc} 391 */ 392 public HandlerRegistration addDragLeaveHandler(DragLeaveHandler handler) { 393 return addDomHandler(handler, DragLeaveEvent.getType()); 394 } 395 396 /** 397 * {@inheritDoc} 398 */ 399 public HandlerRegistration addDragHandler(DragHandler handler) { 400 return addDomHandler(handler, DragEvent.getType()); 401 } 402 403 /** 404 * {@inheritDoc} 405 */ 406 public HandlerRegistration addDragOverHandler(DragOverHandler handler) { 407 return addDomHandler(handler, DragOverEvent.getType()); 408 } 409 410 /** 411 * {@inheritDoc} 412 */ 413 public HandlerRegistration addDragStartHandler(DragStartHandler handler) { 414 return addDomHandler(handler, DragStartEvent.getType()); 415 } 416 417 /** 418 * {@inheritDoc} 419 */ 420 public HandlerRegistration addDropHandler(DropHandler handler) { 421 return addDomHandler(handler, DropEvent.getType()); 422 } 423 424 /** 425 * {@inheritDoc} 426 */ 427 public HandlerRegistration addFocusHandler(FocusHandler handler) { 428 return addDomHandler(handler, FocusEvent.getType()); 429 } 430 431 /** 432 * {@inheritDoc} 433 */ 434 public HandlerRegistration addBlurHandler(BlurHandler handler) { 435 return addDomHandler(handler, BlurEvent.getType()); 436 } 437 438 /** 439 * {@inheritDoc} 440 */ 441 public HandlerRegistration addGestureStartHandler( 442 GestureStartHandler handler) { 443 return addDomHandler(handler, GestureStartEvent.getType()); 444 } 445 446 /** 447 * {@inheritDoc} 448 */ 449 public HandlerRegistration addGestureChangeHandler( 450 GestureChangeHandler handler) { 451 return addDomHandler(handler, GestureChangeEvent.getType()); 452 } 453 454 /** 455 * {@inheritDoc} 456 */ 457 public HandlerRegistration addGestureEndHandler(GestureEndHandler handler) { 458 return addDomHandler(handler, GestureEndEvent.getType()); 459 } 460 461 /** 462 * {@inheritDoc} 463 */ 464 public HandlerRegistration addKeyUpHandler(KeyUpHandler handler) { 465 return addDomHandler(handler, KeyUpEvent.getType()); 466 } 467 468 /** 469 * {@inheritDoc} 470 */ 471 public HandlerRegistration addKeyDownHandler(KeyDownHandler handler) { 472 return addDomHandler(handler, KeyDownEvent.getType()); 473 } 474 475 /** 476 * {@inheritDoc} 477 */ 478 public HandlerRegistration addKeyPressHandler(KeyPressHandler handler) { 479 return addDomHandler(handler, KeyPressEvent.getType()); 480 } 481 482 /** 483 * {@inheritDoc} 484 */ 485 public HandlerRegistration addMouseDownHandler(MouseDownHandler handler) { 486 return addDomHandler(handler, MouseDownEvent.getType()); 487 } 488 489 /** 490 * {@inheritDoc} 491 */ 492 public HandlerRegistration addMouseUpHandler(MouseUpHandler handler) { 493 return addDomHandler(handler, MouseUpEvent.getType()); 494 } 495 496 /** 497 * {@inheritDoc} 498 */ 499 public HandlerRegistration addMouseOutHandler(MouseOutHandler handler) { 500 return addDomHandler(handler, MouseOutEvent.getType()); 501 } 502 503 /** 504 * {@inheritDoc} 505 */ 506 public HandlerRegistration addMouseOverHandler(MouseOverHandler handler) { 507 return addDomHandler(handler, MouseOverEvent.getType()); 508 } 509 510 /** 511 * {@inheritDoc} 512 */ 513 public HandlerRegistration addMouseMoveHandler(MouseMoveHandler handler) { 514 return addDomHandler(handler, MouseMoveEvent.getType()); 515 } 516 517 /** 518 * {@inheritDoc} 519 */ 520 public HandlerRegistration addMouseWheelHandler(MouseWheelHandler handler) { 521 return addDomHandler(handler, MouseWheelEvent.getType()); 522 } 523 524 /** 525 * {@inheritDoc} 526 */ 527 public HandlerRegistration addTouchStartHandler(TouchStartHandler handler) { 528 return addDomHandler(handler, TouchStartEvent.getType()); 529 } 530 531 /** 532 * {@inheritDoc} 533 */ 534 public HandlerRegistration addTouchMoveHandler(TouchMoveHandler handler) { 535 return addDomHandler(handler, TouchMoveEvent.getType()); 536 } 537 538 /** 539 * {@inheritDoc} 540 */ 541 public HandlerRegistration addTouchEndHandler(TouchEndHandler handler) { 542 return addDomHandler(handler, TouchEndEvent.getType()); 543 } 544 545 /** 546 * {@inheritDoc} 547 */ 548 public HandlerRegistration addTouchCancelHandler(TouchCancelHandler handler) { 549 return addDomHandler(handler, TouchCancelEvent.getType()); 550 } 551 552 public ButtonType getType() { 553 return type; 554 } 555 556 public ButtonSize getSize() { 557 return size; 558 } 559 560 }