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