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.KSMenuItemData;
25  import org.kuali.student.common.ui.client.widgets.menus.MenuChangeEvent;
26  import org.kuali.student.common.ui.client.widgets.menus.MenuEventHandler;
27  import org.kuali.student.common.ui.client.widgets.menus.MenuSelectEvent;
28  import org.kuali.student.common.ui.client.widgets.menus.KSMenu.MenuImageLocation;
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 	/**
218 	 * This method will make the stylish drop down just a button when a list of 1 item is 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             //Code Changed for JIRA-9075 - SONAR Critical issues - Use get(0) with caution - 5
293             int KSMenuItemData = 0;
294 			KSMenuItemData item = items.get(KSMenuItemData);
295 			button = new KSButton();
296 			button.addStyleName("ks-button-spacing");
297 			button.addClickHandler(item.getClickHandler());
298 			button.setText(item.getLabel());
299 			parentPanel.clear();
300 			parentPanel.add(button);
301 		}
302 		else{
303 			if(!namePanel.isAttached()){
304 				parentPanel.clear();
305 				parentPanel.add(namePanel);
306 			}
307 			for(KSMenuItemData item: items){
308 				item.addMenuEventHandler(MenuSelectEvent.TYPE, menuHandler);
309 				item.addMenuEventHandler(MenuChangeEvent.TYPE, menuHandler);
310 			}
311 			menu.setItems(items);
312 		}
313 		
314 	}
315 	
316 	public void setEnabled(boolean enabled){
317 		this.enabled = enabled;
318 		if(!enabled){
319 			layout.addStyleName("KS-CustomDropDown-TitlePanel-Disabled");
320 		}
321 		else{
322 			layout.removeStyleName("KS-CustomDropDown-TitlePanel-Disabled");
323 		}
324 		if(button != null){
325 			button.setEnabled(enabled);
326 		}
327 	}
328 	
329 	public void setImageLocation(MenuImageLocation loc){
330 		imgLoc = loc;
331 		menu.setImageLocation(loc);
332 	}
333 	
334 	@Override
335 	public void addStyleName(String style){
336 		namePanel.addStyleName(style);
337 		menu.addStyleName(style);
338 	}
339 	
340 	public boolean isShowingSelectedItem() {
341 		return showSelectedItem;
342 	}
343 
344 	public void setShowSelectedItem(boolean showSelectedItem) {
345 		this.showSelectedItem = showSelectedItem;
346 	}
347 	
348 	public void setShowTitleIcon(boolean showTitleIcon){
349 		this.showTitleIcon = showTitleIcon;
350 	}
351 	
352 	public boolean isShowingTitleIcon(){
353 		return showTitleIcon;
354 	}
355 	
356 	@Override
357     protected void onEnsureDebugId(String baseID) {
358         super.onEnsureDebugId(baseID);
359         titleLabel.ensureDebugId(DebugIdUtils.createWebDriverSafeDebugId(baseID + "-" + titleLabel.getText() + "-label"));
360         layout.ensureDebugId(DebugIdUtils.createWebDriverSafeDebugId(baseID + "-" + titleLabel.getText() + "-panel"));
361     }
362 	
363 	
364 }