001/* 002 * #%L 003 * GwtMaterial 004 * %% 005 * Copyright (C) 2015 - 2017 GwtMaterialDesign 006 * %% 007 * Licensed under the Apache License, Version 2.0 (the "License"); 008 * you may not use this file except in compliance with the License. 009 * You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 * #L% 019 */ 020package gwt.material.design.client.ui; 021 022import com.google.gwt.dom.client.Document; 023import com.google.gwt.event.logical.shared.*; 024import com.google.gwt.event.shared.HandlerRegistration; 025import gwt.material.design.client.base.HasAxis; 026import gwt.material.design.client.base.HasType; 027import gwt.material.design.client.base.MaterialWidget; 028import gwt.material.design.client.base.mixin.CssNameMixin; 029import gwt.material.design.client.base.mixin.CssTypeMixin; 030import gwt.material.design.client.constants.Axis; 031import gwt.material.design.client.constants.CssName; 032import gwt.material.design.client.constants.FABType; 033 034import static gwt.material.design.client.js.JsMaterialElement.$; 035 036//@formatter:off 037 038/** 039 * Floating action buttons are used for a promoted action. They 040 * are distinguished by a circled icon floating above the UI and 041 * have motion behaviors that include morphing, launching, and a 042 * transferring anchor point. 043 * <p> 044 * <h3>UiBinder Usage:</h3> 045 * <pre> 046 * {@code 047 * <m:MaterialFAB> 048 * <m:MaterialButton type="FLOATING" backgroundColor="BLUE" iconType="POLYMER" size="LARGE"/> 049 * <m:MaterialFABList> 050 * <m:MaterialButton type="FLOATING" backgroundColor="RED" iconType="POLYMER"/> 051 * <m:MaterialButton type="FLOATING" backgroundColor="ORANGE" iconType="POLYMER"/> 052 * <m:MaterialButton type="FLOATING" backgroundColor="WHITE" iconType="POLYMER" iconColor="BLACK"/> 053 * </m:MaterialFABList> 054 * </m:MaterialFAB>} 055 * </pre> 056 * </p> 057 * 058 * @author kevzlou7979 059 * @see <a href="http://gwtmaterialdesign.github.io/gwt-material-demo/#buttons">Material FAB</a> 060 * @see <a href="https://material.io/guidelines/components/buttons-floating-action-button.html">Material Design Specification</a> 061 */ 062//@formatter:on 063public class MaterialFAB extends MaterialWidget implements HasType<FABType>, HasAxis, HasCloseHandlers<MaterialFAB>, 064 HasOpenHandlers<MaterialFAB> { 065 066 private CssTypeMixin<FABType, MaterialFAB> typeMixin; 067 private CssNameMixin<MaterialFAB, Axis> axisMixin; 068 069 public MaterialFAB() { 070 super(Document.get().createDivElement(), CssName.FIXED_ACTION_BTN); 071 } 072 073 @Override 074 protected void onLoad() { 075 super.onLoad(); 076 077 if (getType() == FABType.CLICK_ONLY) { 078 registerHandler(addClickHandler(clickEvent -> { 079 if (isEnabled()) { 080 if (!isOpen()) { 081 open(); 082 } else { 083 close(); 084 } 085 } 086 })); 087 } else { 088 registerHandler(addMouseOverHandler(mouseOverEvent -> OpenEvent.fire(this, this))); 089 registerHandler(addMouseOutHandler(mouseOutEvent -> CloseEvent.fire(this, this))); 090 } 091 } 092 093 /** 094 * Open the FAB programmatically 095 */ 096 public void open() { 097 open(true); 098 } 099 100 /** 101 * Open the FAB programmatically 102 * 103 * @param fireEvent flag whether this component fires Open Event 104 */ 105 public void open(boolean fireEvent) { 106 if (fireEvent) { 107 OpenEvent.fire(this, this); 108 } 109 $(getElement()).openFAB(); 110 } 111 112 /** 113 * Close the FAB programmatically 114 */ 115 public void close() { 116 close(true); 117 } 118 119 /** 120 * Close the FAB programmatically 121 * 122 * @param fireEvent flag whether this component fires Close Event 123 */ 124 public void close(boolean fireEvent) { 125 if (fireEvent) { 126 CloseEvent.fire(this, this); 127 } 128 $(getElement()).closeFAB(); 129 } 130 131 @Override 132 public void setType(FABType type) { 133 getTypeMixin().setType(type); 134 } 135 136 @Override 137 public FABType getType() { 138 return getTypeMixin().getType(); 139 } 140 141 @Override 142 public void setAxis(Axis axis) { 143 getAxisMixin().setCssName(axis); 144 } 145 146 @Override 147 public Axis getAxis() { 148 return getAxisMixin().getCssName(); 149 } 150 151 public boolean isOpen() { 152 return getElement().hasClassName(CssName.ACTIVE); 153 } 154 155 @Override 156 public HandlerRegistration addCloseHandler(CloseHandler<MaterialFAB> handler) { 157 return addHandler(handler, CloseEvent.getType()); 158 } 159 160 @Override 161 public HandlerRegistration addOpenHandler(OpenHandler handler) { 162 return addHandler(handler, OpenEvent.getType()); 163 } 164 165 protected CssTypeMixin<FABType, MaterialFAB> getTypeMixin() { 166 if (typeMixin == null) { 167 typeMixin = new CssTypeMixin<>(this); 168 } 169 return typeMixin; 170 } 171 172 protected CssNameMixin<MaterialFAB, Axis> getAxisMixin() { 173 if (axisMixin == null) { 174 axisMixin = new CssNameMixin<>(this); 175 } 176 return axisMixin; 177 } 178}