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