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.Icon; 019import com.github.gwtbootstrap.client.ui.constants.*; 020import com.google.gwt.dom.client.AnchorElement; 021import com.google.gwt.event.dom.client.ClickEvent; 022import com.google.gwt.event.dom.client.ClickHandler; 023import com.google.gwt.event.dom.client.HasClickHandlers; 024import com.google.gwt.event.dom.client.HasMouseDownHandlers; 025import com.google.gwt.event.dom.client.MouseDownEvent; 026import com.google.gwt.event.dom.client.MouseDownHandler; 027import com.google.gwt.event.shared.HandlerRegistration; 028import com.google.gwt.user.client.DOM; 029import com.google.gwt.user.client.Event; 030import com.google.gwt.user.client.ui.Focusable; 031import com.google.gwt.user.client.ui.HasEnabled; 032import com.google.gwt.user.client.ui.HasName; 033import com.google.gwt.user.client.ui.HasText; 034import com.google.gwt.user.client.ui.impl.FocusImpl; 035 036/** 037 * An Anchor with optional image and caret. 038 * 039 * <p> 040 * It uses a HTML {@code <a>} tag and can contain text and child widgets. But 041 * not both at the same time. 042 * </p> 043 * 044 * <p> 045 * <h3>UiBinder Usage:</h3> 046 * {@code <b:IconAnchor icon="plane" href="www.twitter.com">Some Text</b:IconAnchor>} 047 * </p> 048 * 049 * <p> 050 * Here we add a second Icon: 051 * 052 * <pre> 053 * {@code <b:IconAnchor icon="STAR" text="There is a widget so the text goes here"> 054 * <b:Icon type="STAR" /> 055 * </b:IconAnchor>} 056 * </pre> 057 * 058 * All parameter are optional. All setters can be used as parameters. 059 * </p> 060 * 061 * @since 2.0.4.0 062 * 063 * @author Dominik Mayer 064 * @author ohashi keisuke 065 */ 066public class IconAnchor extends ComplexWidget implements HasText, HasIcon, HasHref, HasClickHandlers, HasEnabled, Focusable, HasName, HasMouseDownHandlers { 067 068 private static final FocusImpl impl = FocusImpl.getFocusImplForWidget(); 069 070 private Icon icon = new Icon(); 071 072 private TextNode text = new TextNode(""); 073 074 private Caret caret = new Caret(); 075 076 private IconPosition iconPosition; 077 078 /** 079 * Creates the widget and sets the {@code href} property to 080 * {@code javascript:;} in order to avoid problems when clicking on it. 081 */ 082 public IconAnchor() { 083 super("a"); 084 setIconPosition(IconPosition.LEFT); 085 setEmptyHref(); 086 } 087 088 /** 089 * {@inheritDoc} 090 */ 091 @Override 092 public void setIconPosition(IconPosition position) { 093 094 this.iconPosition = position; 095 icon.removeFromParent(); 096 text.removeFromParent(); 097 098 if(IconPosition.RIGHT == position) { 099 this.insert(text , 0); 100 this.insert(icon , 1); 101 return; 102 103 } else if(IconPosition.LEFT == position){ 104 this.insert(icon, 0); 105 this.insert(text, 1); 106 return; 107 } 108 109 } 110 111 /** 112 * {@inheritDoc} 113 */ 114 @Override 115 public void setIcon(IconType type) { 116 setBaseIcon(type); 117 } 118 119 /** 120 * {@inheritDoc} 121 */ 122 @Override 123 public void setBaseIcon(BaseIconType type) { 124 this.icon.setBaseType(type); 125 } 126 127 /** 128 * {@inheritDoc} 129 */ 130 @Override 131 public void setIconSize(IconSize size) { 132 icon.setIconSize(size); 133 } 134 135 /** 136 * {@inheritDoc} 137 */ 138 public void setText(String text) { 139 this.text.removeFromParent(); 140 this.text = new TextNode(" " + text + " "); 141 setIconPosition(iconPosition); 142 } 143 144 /** 145 * {@inheritDoc} 146 */ 147 public String getText() { 148 return text.getText(); 149 } 150 151 /** 152 * {@inheritDoc} 153 */ 154 public void setHref(String href) { 155 getElement().setAttribute("href", href); 156 } 157 158 /** 159 * {@inheritDoc} 160 */ 161 public String getHref() { 162 return getElement().getAttribute("href"); 163 } 164 165 /** 166 * Shows or hides the caret. 167 * 168 * @param visible 169 * <code>true</code> if the caret should be shown. 170 */ 171 public void setCaret(boolean visible) { 172 if (visible) 173 super.add(caret); 174 else 175 super.remove(caret); 176 } 177 178 /** 179 * {@inheritDoc} 180 */ 181 public void setTargetHistoryToken(String targetHistoryToken) { 182 setHref("#" + targetHistoryToken); 183 } 184 185 /** 186 * {@inheritDoc} 187 */ 188 public String getTargetHistoryToken() { 189 String[] hrefs = getHref().split("#"); 190 return hrefs[1]; 191 } 192 193 /** 194 * Sets the <code>href</code>property of this element to "javascript:;" in 195 * order to get another cursor (hand). 196 */ 197 public void setEmptyHref() { 198 setHref(Constants.EMPTY_HREF); 199 } 200 201 /** 202 * {@inheritDoc} 203 */ 204 @Override 205 public HandlerRegistration addClickHandler(ClickHandler handler) { 206 return addDomHandler(handler, ClickEvent.getType()); 207 } 208 209 /** 210 * {@inheritDoc} 211 */ 212 @Override 213 public HandlerRegistration addMouseDownHandler(MouseDownHandler handler) { 214 return addDomHandler(handler, MouseDownEvent.getType()); 215 } 216 217 /** 218 * {@inheritDoc} 219 */ 220 @Override 221 public boolean isEnabled() { 222 return !DOM.getElementPropertyBoolean(getElement(), "disabled"); 223 } 224 225 /** 226 * {@inheritDoc} 227 */ 228 @Override 229 public void setEnabled(boolean enabled) { 230 DOM.setElementPropertyBoolean(getElement(), "disabled", !enabled); 231 } 232 233 /** 234 * {@inheritDoc} 235 */ 236 @Override 237 public void onBrowserEvent(Event event) { 238 switch (DOM.eventGetType(event)) { 239 case Event.ONCLICK: 240 if (isEnabled()) { 241 super.onBrowserEvent(event); 242 } 243 break; 244 default: 245 super.onBrowserEvent(event); 246 break; 247 } 248 249 } 250 251 @Override 252 public int getTabIndex() { 253 return impl.getTabIndex(getElement()); 254 } 255 256 @Override 257 public void setAccessKey(char key) { 258 DOM.setElementProperty(getElement(), "accessKey", "" + key); 259 } 260 261 @Override 262 public void setFocus(boolean focused) { 263 if (focused) { 264 impl.focus(getElement()); 265 } else { 266 impl.blur(getElement()); 267 } 268 } 269 270 @Override 271 public void setTabIndex(int index) { 272 impl.setTabIndex(getElement(), index); 273 } 274 275 @Override 276 protected void onAttach() { 277 super.onAttach(); 278 279 // Accessibility: setting tab index to be 0 by default, ensuring element 280 // appears in tab sequence. We must ensure that the element doesn't already 281 // have a tabIndex set. This is not a problem for normal widgets, but when 282 // a widget is used to wrap an existing static element, it can already have 283 // a tabIndex. 284 int tabIndex = getTabIndex(); 285 if (-1 == tabIndex) { 286 setTabIndex(0); 287 } 288 } 289 290 /** 291 * Set active style name. 292 * @param active <code>true</code> : set active <code>false</code> : unset active 293 */ 294 public void setActive(boolean active) { 295 setStyleName(Constants.ACTIVE, active); 296 } 297 298 /** 299 * Has the active css style name? 300 * @return <code>true</code>: has <code>false</code> : none. 301 */ 302 public boolean isActive() { 303 return getStyleName().contains(Constants.ACTIVE); 304 } 305 306 /** 307 * {@inheritDoc} 308 */ 309 @Override 310 public void setName(String name) { 311 getAnchorElement().setName(name); 312 } 313 314 /** 315 * {@inheritDoc} 316 */ 317 @Override 318 public String getName() { 319 return getAnchorElement().getName(); 320 } 321 322 /** 323 * Set target attribute 324 * @param target target name 325 */ 326 public void setTarget(String target) { 327 getAnchorElement().setTarget(target); 328 } 329 330 /** 331 * Get target attribute value 332 * @return target attribute value 333 */ 334 public String getTarget() { 335 return getAnchorElement().getTarget(); 336 } 337 338 protected AnchorElement getAnchorElement() { 339 return AnchorElement.as(getElement()); 340 } 341 342 /** 343 * {@inheritDoc} 344 */ 345 @Override 346 public void setCustomIconStyle(String customIconStyle) { 347 icon.addStyleName(customIconStyle); 348 } 349 350}