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 */ 016package com.github.gwtbootstrap.client.ui.base; 017 018import com.github.gwtbootstrap.client.ui.constants.Placement; 019import com.github.gwtbootstrap.client.ui.constants.Trigger; 020import com.github.gwtbootstrap.client.ui.constants.VisibilityChange; 021import com.google.gwt.core.client.Scheduler; 022import com.google.gwt.core.client.Scheduler.ScheduledCommand; 023import com.google.gwt.dom.client.Element; 024import com.google.gwt.event.logical.shared.AttachEvent; 025import com.google.gwt.user.client.ui.HasOneWidget; 026import com.google.gwt.user.client.ui.HasText; 027import com.google.gwt.user.client.ui.HasWidgets; 028import com.google.gwt.user.client.ui.IsWidget; 029import com.google.gwt.user.client.ui.Widget; 030 031//@formatter:off 032/** 033* Base class for widgets that hover above other widgets. 034* 035* @since 2.0.4.0 036* 037* @author Dominik Mayer 038* 039* @see <a href="http://twitter.github.com/bootstrap/javascript.html#popovers">Bootstrap documentation</a> 040*/ 041//@formatter:on 042public abstract class HoverBase extends MarkupWidget implements IsWidget, HasWidgets, HasOneWidget, IsAnimated, HasTrigger, HasPlacement, HasText, HasShowDelay, HasVisibility { 043 044 /** 045 * Whether the widget is animated or not. 046 */ 047 protected boolean animated = true; 048 049 /** 050 * The placement of the widget relative to its trigger element. 051 */ 052 protected Placement placement = Placement.TOP; 053 054 /** 055 * The action that triggers the widget. 056 */ 057 protected Trigger trigger = Trigger.HOVER; 058 059 /** 060 * The delay until the widget is shown. 061 */ 062 protected int showDelayInMilliseconds = 0; 063 064 /** 065 * The delay until the widget is hidden. 066 */ 067 protected int hideDelayInMilliseconds = 0; 068 069 /** 070 * Appends the popover to a specific element. 071 */ 072 protected String container; 073 074 /** 075 * Creates a new widget based on the provided HTML tag. 076 */ 077 public HoverBase() { 078 } 079 080 /** 081 * {@inheritDoc} 082 */ 083 @Override 084 public Widget asWidget() { 085 086 if(getWidget() != null) { 087 Scheduler.get().scheduleDeferred(new ScheduledCommand() { 088 089 @Override 090 public void execute() { 091 removeDataIfExists(); 092 093 reconfigure(); 094 095 getWidget().addAttachHandler(new AttachEvent.Handler() { 096 097 @Override 098 public void onAttachOrDetach(AttachEvent event) { 099 if (!event.isAttached()) { 100 changeVisibility(VisibilityChange.HIDE); 101 } 102 } 103 }); 104 } 105 }); 106 } 107 108 return getWidget(); 109 110 } 111 112 protected void removeDataIfExists() { 113 hide(); 114 removeDataIfExists(getWidget().getElement(), getDataName()); 115 } 116 117 protected abstract void removeDataIfExists(Element e, String dataName); 118 119 /** 120 * Adds an HTML data attribute to the widget's tag. 121 * 122 * @param e target element 123 * 124 * @param attribute 125 * the name of the attribute without leading <code>"data-"</code> 126 * @param value 127 * the value to be stored 128 */ 129 protected void setDataAttribute(Element e , String attribute, String value) { 130 e.setAttribute("data-" + attribute, value); 131 } 132 133 /** 134 * {@inheritDoc} 135 */ 136 public void setAnimation(boolean animated) { 137 this.animated = animated; 138 } 139 140 /** 141 * Redraws the widget with the currently set options. This must <b>not</b> 142 * be called when a parameter is updated because it would deactivate all 143 * other parameters. No idea why... 144 */ 145 public abstract void reconfigure(); 146 147 /** 148 * {@inheritDoc} 149 */ 150 public boolean getAnimation() { 151 return animated; 152 } 153 154 /** 155 * {@inheritDoc} Relative to its trigger element. 156 */ 157 public void setPlacement(Placement placement) { 158 this.placement = placement; 159 } 160 161 /** 162 * {@inheritDoc} 163 */ 164 public Placement getPlacement() { 165 return placement; 166 } 167 168 /** 169 * {@inheritDoc} 170 */ 171 public void setTrigger(Trigger trigger) { 172 this.trigger = trigger; 173 } 174 175 /** 176 * {@inheritDoc} 177 */ 178 public Trigger getTrigger() { 179 return trigger; 180 } 181 182 /** 183 * {@inheritDoc} 184 */ 185 public void setShowDelay(int delayInMilliseconds) { 186 showDelayInMilliseconds = delayInMilliseconds; 187 } 188 189 /** 190 * {@inheritDoc} 191 */ 192 public int getShowDelay() { 193 return showDelayInMilliseconds; 194 } 195 196 /** 197 * {@inheritDoc} 198 */ 199 public void setHideDelay(int delayInMilliseconds) { 200 hideDelayInMilliseconds = delayInMilliseconds; 201 } 202 203 /** 204 * {@inheritDoc} 205 */ 206 public int getHideDelay() { 207 return hideDelayInMilliseconds; 208 } 209 210 /** 211 * {@inheritDoc} 212 */ 213 public void show() { 214 changeVisibility(VisibilityChange.SHOW); 215 } 216 217 /** 218 * {@inheritDoc} 219 */ 220 public void hide() { 221 changeVisibility(VisibilityChange.HIDE); 222 } 223 224 /** 225 * {@inheritDoc} 226 */ 227 public void toggle() { 228 changeVisibility(VisibilityChange.TOGGLE); 229 } 230 231 /** 232 * Changes the visibility of the widget. 233 * 234 * @param visibilityChange 235 * the action to be performed 236 */ 237 protected abstract void changeVisibility(VisibilityChange visibilityChange); 238 239 /** 240 * Get data name of JS Data API. 241 * @return data name 242 */ 243 protected abstract String getDataName(); 244 245 /** 246 * @return Specific element the Popover/Tooltip is appended to 247 */ 248 public String getContainer() { 249 return container; 250 } 251 252 /** 253 * Set specific element the Popover/Tooltip is appended to 254 * @param container Specific element the Popover/Tooltip is appended to. E.g. 'body' or null. 255 */ 256 public void setContainer(String container) { 257 this.container = container; 258 } 259}