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.NavLink;
019 import com.github.gwtbootstrap.client.ui.constants.Constants;
020 import com.google.gwt.core.client.GWT;
021 import com.google.gwt.dom.client.Document;
022 import com.google.gwt.dom.client.Element;
023 import com.google.gwt.event.dom.client.ChangeEvent;
024 import com.google.gwt.event.dom.client.ChangeHandler;
025 import com.google.gwt.event.dom.client.ClickEvent;
026 import com.google.gwt.event.dom.client.ClickHandler;
027 import com.google.gwt.event.dom.client.DomEvent;
028 import com.google.gwt.event.dom.client.HasChangeHandlers;
029 import com.google.gwt.event.dom.client.HasClickHandlers;
030 import com.google.gwt.event.shared.HandlerRegistration;
031 import com.google.gwt.user.client.ui.HasText;
032 import com.google.gwt.user.client.ui.HasWidgets;
033 import com.google.gwt.user.client.ui.Widget;
034
035 //@formatter:off
036
037 /**
038 * Base class for dropdown widgets.
039 *
040 * @author Carlos A Becker
041 * @author Dominik Mayer
042 * @since 2.0.4.0
043 */
044 //@formatter:on
045 public abstract class DropdownBase extends ComplexWidget implements HasChangeHandlers, HasClickHandlers, HasWidgets, HasText {
046
047 private UnorderedList menu = new UnorderedList();
048
049 private IconAnchor trigger;
050
051 private NavLink link;
052
053 private NavLinkClickHandler handler = new NavLinkClickHandler();
054
055 /**
056 * Creates a new widget of the given type.
057 *
058 * @param type
059 * the HTML tag to be used for the widget
060 */
061 public DropdownBase(String type) {
062 super(type);
063 createAndAddTrigger();
064 menu.setStyleName("dropdown-menu");
065 super.add(menu);
066 }
067
068 private void createAndAddTrigger() {
069 trigger = createTrigger();
070 trigger.addStyleName("dropdown-toggle");
071 trigger.getElement().setAttribute(Constants.DATA_TOGGLE, "dropdown");
072 super.add(trigger);
073 }
074
075 /**
076 * Sets the text of the dropdown trigger.
077 *
078 * @param text
079 */
080 public void setText(String text) {
081 trigger.setText(text);
082 }
083
084 /**
085 * @return the text of the dropdown trigger.
086 */
087 public String getText() {
088 return trigger.getText();
089 }
090
091 /**
092 * Implement this method to create the trigger appropriate for your widget.
093 * It has to be an {@link IconAnchor} or a subtype.
094 *
095 * @return the created trigger
096 */
097 protected abstract IconAnchor createTrigger();
098
099 /**
100 * Set dropup style.
101 *
102 * @param dropup
103 * true:Set Dropup false:Un-set Dropup
104 */
105 public void setDropup(boolean dropup) {
106 if (dropup)
107 addStyleName(Constants.DROPUP);
108 else
109 removeStyleName(Constants.DROPUP);
110 }
111
112 /**
113 * {@inheritDoc}
114 */
115 @Override
116 protected void onLoad() {
117 super.onLoad();
118 if (trigger != null) {
119 configure(trigger.getElement());
120 }
121 }
122
123 /**
124 * Adds a widget to the dropdown menu.
125 *
126 * @param widget
127 * the widget that will be added to the menu
128 * @see #addWidget(Widget)
129 */
130 @Override
131 public void add(Widget widget) {
132 menu.add(widget);
133 if (widget instanceof NavLink) {
134 ((NavLink) widget).addClickHandler(handler);
135 }
136 }
137
138 @Override
139 public HandlerRegistration addChangeHandler(ChangeHandler handler) {
140 return addDomHandler(handler, ChangeEvent.getType());
141 }
142 /**
143 * Adds a widget to the the dropdown widget, <b>not</b> to the dropdown
144 * menu.
145 * <p/>
146 * <p/>
147 * Use {@link #add(Widget)} if you want to add a widget to the dropdown
148 * menu.
149 *
150 * @param widget
151 * the widget to be added.
152 */
153 protected void addWidget(Widget widget) {
154 super.add(widget);
155 }
156
157 private native void configure(Element e) /*-{
158 $wnd.jQuery(e).dropdown();
159 }-*/;
160
161 /**
162 * Pull the dropdown menu to right
163 *
164 * @param rightDropdown
165 * <code>true</code> pull to right, otherwise to left. Default is
166 * <code>false</code>
167 */
168 public void setRightDropdown(boolean rightDropdown) {
169 if (rightDropdown) {
170 menu.addStyleName("pull-right");
171 } else {
172 menu.removeStyleName("pull-right");
173 }
174 }
175
176 private class NavLinkClickHandler implements ClickHandler {
177
178 @Override
179 public void onClick(ClickEvent event) {
180 try {
181 IconAnchor iconAnchor = (IconAnchor) event.getSource();
182 link = (NavLink) iconAnchor.getParent();
183 } catch (Exception e) {
184 GWT.log(e.getMessage() , e);
185 }
186 DomEvent.fireNativeEvent(Document.get().createChangeEvent(), DropdownBase.this);
187 }
188
189 }
190
191 /**
192 * Method to get the {@link NavLink} that has been clicked most recently.
193 *
194 * @return Last clicked NavLink or <code>null</code> if none have been
195 * clicked.
196 */
197 public NavLink getLastSelectedNavLink() {
198 return link;
199 }
200
201 @Override
202 public void clear() {
203 menu.clear();
204 }
205
206 @Override
207 public HandlerRegistration addClickHandler(ClickHandler handler) {
208 return trigger.addClickHandler(handler);
209 }
210 }