001package com.github.gwtbootstrap.client.ui; 002 003import com.github.gwtbootstrap.client.ui.base.HasPlacement; 004import com.github.gwtbootstrap.client.ui.base.HasShowDelay; 005import com.github.gwtbootstrap.client.ui.base.HasTrigger; 006import com.github.gwtbootstrap.client.ui.base.IsAnimated; 007import com.github.gwtbootstrap.client.ui.constants.Placement; 008import com.github.gwtbootstrap.client.ui.constants.Trigger; 009import com.google.gwt.cell.client.Cell; 010import com.google.gwt.cell.client.ValueUpdater; 011import com.google.gwt.core.client.GWT; 012import com.google.gwt.core.client.Scheduler; 013import com.google.gwt.core.client.Scheduler.ScheduledCommand; 014import com.google.gwt.dom.client.Element; 015import com.google.gwt.dom.client.NativeEvent; 016import com.google.gwt.safehtml.client.SafeHtmlTemplates; 017import com.google.gwt.safehtml.shared.SafeHtml; 018import com.google.gwt.safehtml.shared.SafeHtmlBuilder; 019import com.google.gwt.user.client.DOM; 020import com.google.gwt.user.client.ui.HasText; 021 022import java.util.Set; 023 024/** 025 * Cell decorator as a Tooltip. 026 * @author ohashi keisuke 027 * 028 * @param <C> Decorated Cell Parameter 029 */ 030public class TooltipCellDecorator<C> implements Cell<C> ,IsAnimated, HasTrigger, HasPlacement, HasText, HasShowDelay{ 031 032 /** 033 * Whether the widget is animated or not. 034 */ 035 protected boolean animated = true; 036 037 /** 038 * The placement of the widget relative to its trigger element. 039 */ 040 protected Placement placement = Placement.TOP; 041 042 /** 043 * The action that triggers the widget. 044 */ 045 protected Trigger trigger = Trigger.HOVER; 046 047 /** 048 * The delay until the widget is shown. 049 */ 050 protected int showDelayInMilliseconds = 0; 051 052 /** 053 * The delay until the widget is hidden. 054 */ 055 protected int hideDelayInMilliseconds = 0; 056 057 /** 058 * Appends the popover to a specific element. 059 */ 060 protected String container; 061 062 interface Template extends SafeHtmlTemplates { 063 @Template("<span class='gb-tooltip-cell' id='{0}'>{1}</span>") 064 SafeHtml span(String id , SafeHtml content); 065 066 } 067 068 private static Template template = GWT.create(Template.class); 069 070 private final Cell<C> cell; 071 072 private String tooltip; 073 074 /** 075 * Create Decorator cell 076 * @param cell decorated cell 077 */ 078 public TooltipCellDecorator(Cell<C> cell) { 079 this.cell = cell; 080 } 081 082 /** 083 * {@inheritDoc} 084 */ 085 @Override 086 public boolean dependsOnSelection() { 087 return cell.dependsOnSelection(); 088 } 089 090 /** 091 * {@inheritDoc} 092 */ 093 @Override 094 public Set<String> getConsumedEvents() { 095 return cell.getConsumedEvents(); 096 } 097 098 /** 099 * {@inheritDoc} 100 */ 101 @Override 102 public boolean handlesSelection() { 103 return cell.handlesSelection(); 104 } 105 106 /** 107 * {@inheritDoc} 108 */ 109 @Override 110 public boolean isEditing(com.google.gwt.cell.client.Cell.Context context, 111 Element parent, C value) { 112 return cell.isEditing(context, getCellParent(parent), value); 113 } 114 115 /** 116 * {@inheritDoc} 117 */ 118 @Override 119 public void onBrowserEvent(com.google.gwt.cell.client.Cell.Context context, 120 Element parent, C value, NativeEvent event, 121 ValueUpdater<C> valueUpdater) { 122 cell.onBrowserEvent(context, getCellParent(parent), value, event, valueUpdater); 123 } 124 125 /** 126 * {@inheritDoc} 127 */ 128 @Override 129 public void render(final com.google.gwt.cell.client.Cell.Context context, 130 final C value, SafeHtmlBuilder sb) { 131 132 SafeHtmlBuilder cellBuilder = new SafeHtmlBuilder(); 133 134 cell.render(context, value, cellBuilder); 135 136 final String id = DOM.createUniqueId(); 137 sb.append(template.span(id, cellBuilder.toSafeHtml())); 138 139 Scheduler.get().scheduleDeferred(new ScheduledCommand() { 140 141 @Override 142 public void execute() { 143 144 Tooltip.configure("#" + id + "> :first-child", 145 getTooltipText(context, value), 146 getAnimation(context, value), 147 getPlacement(context, value).get(), 148 getTrigger(context, value).get(), 149 getShowDelay(context, value), 150 getHideDelay(context, value), 151 getContainer() 152 ); 153 154 }; 155 156 }); 157 } 158 @Override 159 public boolean resetFocus(com.google.gwt.cell.client.Cell.Context context, 160 Element parent, C value) { 161 return cell.resetFocus(context, getCellParent(parent), value); 162 } 163 164 @Override 165 public void setValue(com.google.gwt.cell.client.Cell.Context context, 166 Element parent, C value) { 167 cell.setValue(context, getCellParent(parent), value); 168 } 169 170 /** 171 * {@inheritDoc} 172 */ 173 public void setAnimation(boolean animated) { 174 this.animated = animated; 175 } 176 177 /** 178 * {@inheritDoc} 179 */ 180 public boolean getAnimation() { 181 return animated; 182 } 183 184 protected boolean getAnimation(Context context,C value) { 185 return getAnimation(); 186 } 187 188 /** 189 * {@inheritDoc} Relative to its trigger element. 190 */ 191 public void setPlacement(Placement placement) { 192 193 assert placement != null : "should not be null"; 194 195 this.placement = placement; 196 } 197 198 /** 199 * {@inheritDoc} 200 */ 201 public Placement getPlacement() { 202 return placement; 203 } 204 205 protected Placement getPlacement(Context context, C value) { 206 return getPlacement(); 207 } 208 209 /** 210 * {@inheritDoc} 211 */ 212 public void setTrigger(Trigger trigger) { 213 assert trigger != null : "should not be null"; 214 this.trigger = trigger; 215 } 216 217 /** 218 * {@inheritDoc} 219 */ 220 public Trigger getTrigger() { 221 return trigger; 222 } 223 224 protected Trigger getTrigger(Context context,C value) { 225 return getTrigger(); 226 } 227 228 /** 229 * {@inheritDoc} 230 */ 231 public void setShowDelay(int delayInMilliseconds) { 232 showDelayInMilliseconds = delayInMilliseconds; 233 } 234 235 /** 236 * {@inheritDoc} 237 */ 238 public int getShowDelay() { 239 return showDelayInMilliseconds; 240 } 241 242 protected int getShowDelay(Context context, C value) { 243 return getShowDelay(); 244 } 245 246 /** 247 * {@inheritDoc} 248 */ 249 public void setHideDelay(int delayInMilliseconds) { 250 hideDelayInMilliseconds = delayInMilliseconds; 251 } 252 253 /** 254 * {@inheritDoc} 255 */ 256 public int getHideDelay() { 257 return hideDelayInMilliseconds; 258 } 259 260 protected int getHideDelay(Context context, C value) { 261 return getHideDelay(); 262 } 263 264 /** 265 * {@inheritDoc} 266 */ 267 @Override 268 public String getText() { 269 return this.tooltip; 270 } 271 272 /** 273 * {@inheritDoc} 274 */ 275 @Override 276 public void setText(String text) { 277 assert text != null : "should not be null"; 278 this.tooltip = text; 279 } 280 281 protected String getTooltipText(Context context, C value) { 282 return getText(); 283 } 284 285 /** 286 * Get the parent element of the decorated cell. 287 * 288 * @param parent the parent of this cell 289 * @return the decorated cell's parent 290 */ 291 private Element getCellParent(Element parent) { 292 return parent.getFirstChildElement().cast(); 293 } 294 295 /** 296 * @return Specific element the Popover/Tooltip is appended to 297 */ 298 public String getContainer() { 299 return container; 300 } 301 302 /** 303 * Set specific element the Popover/Tooltip is appended to 304 * @param container Specific element the Popover/Tooltip is appended to. E.g. 'body' or null. 305 */ 306 public void setContainer(String container) { 307 this.container = container; 308 } 309}