View Javadoc

1   /**
2    * Copyright 2010 The Kuali Foundation Licensed under the
3    * Educational Community License, Version 2.0 (the "License"); you may
4    * not use this file except in compliance with the License. You may
5    * obtain a copy of the License at
6    *
7    * http://www.osedu.org/licenses/ECL-2.0
8    *
9    * Unless required by applicable law or agreed to in writing,
10   * software distributed under the License is distributed on an "AS IS"
11   * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12   * or implied. See the License for the specific language governing
13   * permissions and limitations under the License.
14   */
15  
16  package org.kuali.student.common.ui.client.widgets;
17  
18  import java.util.List;
19  
20  import org.kuali.student.common.ui.client.mvc.Callback;
21  import org.kuali.student.common.ui.client.theme.Theme;
22  import org.kuali.student.common.ui.client.util.DebugIdUtils;
23  import org.kuali.student.common.ui.client.widgets.field.layout.element.SpanPanel;
24  import org.kuali.student.common.ui.client.widgets.menus.KSMenu.MenuImageLocation;
25  import org.kuali.student.common.ui.client.widgets.menus.KSMenuItemData;
26  import org.kuali.student.common.ui.client.widgets.menus.MenuChangeEvent;
27  import org.kuali.student.common.ui.client.widgets.menus.MenuEventHandler;
28  import org.kuali.student.common.ui.client.widgets.menus.MenuSelectEvent;
29  import org.kuali.student.common.ui.client.widgets.menus.impl.KSListMenuImpl;
30  
31  import com.google.gwt.event.dom.client.ClickEvent;
32  import com.google.gwt.event.dom.client.ClickHandler;
33  import com.google.gwt.event.dom.client.FocusEvent;
34  import com.google.gwt.event.dom.client.FocusHandler;
35  import com.google.gwt.event.dom.client.KeyDownEvent;
36  import com.google.gwt.event.dom.client.KeyDownHandler;
37  import com.google.gwt.event.dom.client.MouseOutEvent;
38  import com.google.gwt.event.dom.client.MouseOutHandler;
39  import com.google.gwt.event.dom.client.MouseOverEvent;
40  import com.google.gwt.event.dom.client.MouseOverHandler;
41  import com.google.gwt.user.client.ui.Composite;
42  import com.google.gwt.user.client.ui.HTMLPanel;
43  import com.google.gwt.user.client.ui.HasHorizontalAlignment;
44  import com.google.gwt.user.client.ui.HorizontalPanel;
45  import com.google.gwt.user.client.ui.Image;
46  import com.google.gwt.user.client.ui.KeyboardListener;
47  import com.google.gwt.user.client.ui.PopupPanel;
48  import com.google.gwt.user.client.ui.Widget;
49  
50  public class StylishDropDown extends Composite{
51  	
52  	protected ClickablePanel namePanel = new ClickablePanel();
53  	protected SpanPanel parentPanel = new SpanPanel();
54  	protected boolean showSelectedItem = false;
55  	protected boolean showTitleIcon = false;
56  	protected PopupPanel menuPanel = new PopupPanel();
57  	protected KSListMenuImpl menu = new KSListMenuImpl();
58  	protected HorizontalPanel layout = new HorizontalPanel();
59  	protected KSLabel titleLabel = new KSLabel();
60  	protected Image titleImage = Theme.INSTANCE.getCommonImages().getSpacer();
61  	protected HorizontalPanel titleLayout = new HorizontalPanel();
62  	protected Image defaultArrow = Theme.INSTANCE.getCommonImages().getDropDownIconBlack();
63  	private boolean mouseOver = false;
64  	protected MenuImageLocation imgLoc = MenuImageLocation.RIGHT;
65  	private boolean makeButton = false;
66  	protected boolean enabled = true;
67  	
68  	//optional button
69  	private KSButton button;
70  	
71  	protected ClickHandler panelHandler = new ClickHandler(){
72  
73  		@Override
74  		public void onClick(ClickEvent event) {
75  			if(enabled){
76  				if(!menuPanel.isShowing()){
77  					StylishDropDown.this.showMenu();
78  				}
79  				else{
80  					StylishDropDown.this.hideMenu();
81  				}
82  			}
83  			
84  		}
85  		
86  	};
87  
88  	protected KeyDownHandler downHandler = new KeyDownHandler(){
89  
90  		@Override
91  		public void onKeyDown(KeyDownEvent event) {
92  			if(enabled){
93  				if (event.getNativeKeyCode() == KeyboardListener.KEY_DOWN || event.getNativeKeyCode() == KeyboardListener.KEY_ENTER) 
94  					StylishDropDown.this.showMenu();
95  				else if (event.getNativeKeyCode() == KeyboardListener.KEY_UP)
96  					StylishDropDown.this.hideMenu();
97  				else if (event.getNativeKeyCode() == KeyboardListener.KEY_TAB)
98  				{
99  					StylishDropDown.this.showMenu();
100 					titleLayout.removeStyleName("KS-Basic-Menu-Item-Panel-Main-Hover");
101 				}					
102 			}	
103 		} 
104 	}; 
105 
106 	protected FocusHandler focusHandler = new FocusHandler(){
107 
108 		@Override
109 		public void onFocus(FocusEvent event) {
110 			if(enabled) 
111 				titleLayout.addStyleName("KS-Basic-Menu-Item-Panel-Main-Hover");
112 		}
113 	}; 
114 
115 	protected MouseOverHandler mouseOverHandler = new MouseOverHandler() {
116 
117 		@Override
118 		public void onMouseOver(MouseOverEvent event) {
119 			titleLayout.addStyleName("KS-Basic-Menu-Item-Panel-Main-Hover");
120 		}
121 		
122 	};
123 
124 	protected MouseOutHandler mouseOutHandler = new MouseOutHandler() {
125 
126 		@Override
127 		public void onMouseOut(MouseOutEvent event) {
128 			titleLayout.removeStyleName("KS-Basic-Menu-Item-Panel-Main-Hover");
129 		}
130 		
131 	};
132 
133 	private MenuEventHandler menuHandler = new MenuEventHandler(){
134 
135 		@Override
136 		public void onChange(MenuChangeEvent e) {
137 			//Not needed?
138 			
139 		}
140 
141 		@Override
142 		public void onSelect(MenuSelectEvent e) {
143 			KSMenuItemData i = (KSMenuItemData) e.getSource();
144 			StylishDropDown.this.hideMenu();
145 			if(showSelectedItem){
146 				titleLayout.clear();
147 				titleLabel.setText(i.getLabel());
148 				titleLayout.add(titleLabel);
149 				if(i.getShownIcon() != null){
150 					titleLayout.add(i.getShownIcon());
151 				}
152 			}
153 			
154 		}
155 	};
156 	
157 	public StylishDropDown() {}
158 	
159 	public StylishDropDown(String title){
160 		titleLayout.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);
161 		titleLabel.setText(title);
162 		titleLayout.add(titleLabel);
163 		titleLayout.add(titleImage);
164 		init();
165 	}
166 	
167 	public StylishDropDown(String title, Image image, MenuImageLocation imgLoc){
168 		titleLayout.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);
169 		titleLabel.setText(title);
170 		titleImage = image;
171 		titleLayout.add(titleLabel);
172 		if(imgLoc == MenuImageLocation.RIGHT){
173 			titleLayout.add(titleImage);
174 		}
175 		else{
176 			titleLayout.insert(titleImage, 0);
177 		}
178 		menu.setImageLocation(imgLoc);
179         init();
180     }
181 
182     public StylishDropDown(Widget widget) {
183         titleLayout.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);
184         titleLayout.add(widget);
185         init();
186     }
187 
188     public void initialise(String title) {
189         titleLayout.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);
190         titleLabel.setText(title);
191         titleLayout.add(titleLabel);
192         titleLayout.add(titleImage);
193         init();
194     }
195 
196     public void initialise(String title, Image image, MenuImageLocation imgLoc) {
197         titleLayout.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);
198         titleLabel.setText(title);
199         titleImage = image;
200         titleLayout.add(titleLabel);
201         if (imgLoc == MenuImageLocation.RIGHT) {
202             titleLayout.add(titleImage);
203         } else {
204             titleLayout.insert(titleImage, 0);
205         }
206         menu.setImageLocation(imgLoc);
207         init();
208     }
209 
210     public void initialise(Widget widget) {
211         titleLayout.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_LEFT);
212         titleLayout.add(widget);
213         init();
214     }
215 
216     /**
217      * This method will make the stylish drop down just a button when a list of 1 item is
218      * passed in
219      * @param makeButton
220      */
221     public void makeAButtonWhenOneItem(boolean makeButton) {
222         this.makeButton = makeButton;
223     }
224 	
225 	protected void init(){
226 		layout.clear();
227 		layout.setWidth("100%");
228 		layout.add(titleLayout);
229 		layout.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
230 		layout.add(defaultArrow);
231 
232 		namePanel.setWidget(layout);
233 		menu.addGlobalMenuItemSelectCallback(new Callback<KSMenuItemData>(){
234 
235 			@Override
236 			public void exec(KSMenuItemData item) {
237 				if(item.getClickHandler() != null){
238 					StylishDropDown.this.hideMenu();
239 					if(showSelectedItem){
240 						titleLabel.setText(item.getLabel());
241 						if(item.getShownIcon() != null && showTitleIcon){
242 							titleLayout.remove(titleImage);
243 							Image image = item.getShownIcon();
244 							titleImage = new Image(image.getUrl(), image.getOriginLeft(), 
245 									image.getOriginTop(), image.getWidth(), image.getHeight());
246 							if(imgLoc == MenuImageLocation.RIGHT){
247 								titleLayout.add(titleImage);
248 							}
249 							else{
250 								titleLayout.insert(titleImage, 0);
251 							}
252 							
253 						}
254 					}
255 				}
256 			}
257 		});
258 		menuPanel.setWidget(menu);
259 		namePanel.addClickHandler(panelHandler);
260 		namePanel.addKeyDownHandler(downHandler);
261 		namePanel.addFocusHandler(focusHandler);
262 		namePanel.addMouseOverHandler(mouseOverHandler);
263 		namePanel.addMouseOutHandler(mouseOutHandler);
264 		namePanel.setTabIndex(1);
265 		menuPanel.setAutoHideEnabled(true);
266 		menuPanel.addAutoHidePartner(namePanel.getElement());
267 		namePanel.getElement().setAttribute("id", HTMLPanel.createUniqueId());
268 		parentPanel.add(namePanel);
269 		this.initWidget(parentPanel);
270 		titleLabel.addStyleName("KS-CustomDropDown-TitleLabel");
271 		layout.addStyleName("KS-CustomDropDown-TitlePanel");
272 		defaultArrow.addStyleName("KS-CustomDropDown-Arrow");
273 	}
274 	
275 	public void showMenu(){
276 		menuPanel.setPopupPosition(layout.getAbsoluteLeft(), layout.getAbsoluteTop() + layout.getOffsetHeight());
277 		menuPanel.show();
278 	}
279 	
280 	public void hideMenu(){
281 		menuPanel.hide();
282 	}
283 	
284 	public void setArrowImage(Image arrow){
285 		layout.remove(defaultArrow);
286 		arrow.addStyleName("KS-CustomDropDown-Arrow");
287 		layout.add(arrow);
288 	}
289 	
290 	public void setItems(List<KSMenuItemData> items){
291 		if(makeButton && items.size() == 1){
292 			KSMenuItemData item = items.get(0);
293 			button = new KSButton();
294 			button.addStyleName("ks-button-spacing");
295 			button.addClickHandler(item.getClickHandler());
296 			button.setText(item.getLabel());
297 			parentPanel.clear();
298 			parentPanel.add(button);
299 		}
300 		else{
301 			if(!namePanel.isAttached()){
302 				parentPanel.clear();
303 				parentPanel.add(namePanel);
304 			}
305 			for(KSMenuItemData item: items){
306 				item.addMenuEventHandler(MenuSelectEvent.TYPE, menuHandler);
307 				item.addMenuEventHandler(MenuChangeEvent.TYPE, menuHandler);
308 			}
309 			menu.setItems(items);
310 		}
311 		
312 	}
313 	
314 	public void setEnabled(boolean enabled){
315 		this.enabled = enabled;
316 		if(!enabled){
317 			layout.addStyleName("KS-CustomDropDown-TitlePanel-Disabled");
318 		}
319 		else{
320 			layout.removeStyleName("KS-CustomDropDown-TitlePanel-Disabled");
321 		}
322 		if(button != null){
323 			button.setEnabled(enabled);
324 		}
325 	}
326 	
327 	public void setImageLocation(MenuImageLocation loc){
328 		imgLoc = loc;
329 		menu.setImageLocation(loc);
330 	}
331 	
332 	@Override
333 	public void addStyleName(String style){
334 		namePanel.addStyleName(style);
335 		menu.addStyleName(style);
336 	}
337 	
338 	public boolean isShowingSelectedItem() {
339 		return showSelectedItem;
340 	}
341 
342 	public void setShowSelectedItem(boolean showSelectedItem) {
343 		this.showSelectedItem = showSelectedItem;
344 	}
345 	
346 	public void setShowTitleIcon(boolean showTitleIcon){
347 		this.showTitleIcon = showTitleIcon;
348 	}
349 	
350 	public boolean isShowingTitleIcon(){
351 		return showTitleIcon;
352 	}
353 	
354 	@Override
355     protected void onEnsureDebugId(String baseID) {
356         super.onEnsureDebugId(baseID);
357         titleLabel.ensureDebugId(DebugIdUtils.createWebDriverSafeDebugId(baseID + "-" + titleLabel.getText() + "-label"));
358         layout.ensureDebugId(DebugIdUtils.createWebDriverSafeDebugId(baseID + "-" + titleLabel.getText() + "-panel"));
359     }
360 	
361 	
362 }