View Javadoc

1   package org.kuali.student.common.ui.client.configurable.mvc.layouts;
2   
3   import java.util.ArrayList;
4   import java.util.HashMap;
5   import java.util.List;
6   import java.util.Map;
7   
8   import org.kuali.student.common.ui.client.configurable.mvc.LayoutController;
9   import org.kuali.student.common.ui.client.mvc.Callback;
10  import org.kuali.student.common.ui.client.mvc.View;
11  import org.kuali.student.common.ui.client.util.ExportElement;
12  import org.kuali.student.common.ui.client.widgets.KSButton;
13  import org.kuali.student.common.ui.client.widgets.headers.KSDocumentHeader;
14  import org.kuali.student.common.ui.client.widgets.menus.KSMenuItemData;
15  import org.kuali.student.common.ui.client.widgets.menus.impl.KSBlockMenuImpl;
16  import org.kuali.student.common.ui.client.widgets.panels.collapsable.VerticalCollapsableDrawer;
17  
18  import com.google.gwt.core.client.GWT;
19  import com.google.gwt.event.dom.client.ClickEvent;
20  import com.google.gwt.event.dom.client.ClickHandler;
21  import com.google.gwt.user.client.Command;
22  import com.google.gwt.user.client.DeferredCommand;
23  import com.google.gwt.user.client.ui.FlowPanel;
24  import com.google.gwt.user.client.ui.HorizontalPanel;
25  import com.google.gwt.user.client.ui.SimplePanel;
26  import com.google.gwt.user.client.ui.VerticalPanel;
27  import com.google.gwt.user.client.ui.Widget;
28  
29  /**
30   * A layout controller which generates a menu for views that added to it through addMenuItem calls.
31   * The user can click on items in the menu to show the view.
32   * 
33   * @author Kuali Student Team
34   *
35   */
36  public class MenuSectionController extends LayoutController implements ContentNavLayoutController {
37  
38      protected KSBlockMenuImpl menu = new KSBlockMenuImpl();
39      protected List<KSMenuItemData> topLevelMenuItems = new ArrayList<KSMenuItemData>();
40      protected Map<String, List<View>> menuViewMap = new HashMap<String, List<View>>();
41      private Map<Enum<?>, List<KSButton>> viewButtonsMap = new HashMap<Enum<?>, List<KSButton>>();
42      private Map<Enum<?>, List<KSButton>> topViewButtonsMap = new HashMap<Enum<?>, List<KSButton>>();
43      protected Map<Enum<?>, KSMenuItemData> viewMenuItemMap = new HashMap<Enum<?>, KSMenuItemData>();
44      private List<View> menuOrder = new ArrayList<View>();
45      private HorizontalPanel layout = new HorizontalPanel();
46      private KSDocumentHeader header = new KSDocumentHeader();
47      protected FlowPanel rightPanel = new FlowPanel();
48      private FlowPanel contentPanel = new FlowPanel();
49      private FlowPanel infoPanel = new FlowPanel();
50      private FlowPanel bottomButtonPanel = new FlowPanel();
51      private FlowPanel topButtonPanel = new FlowPanel();
52      protected VerticalPanel leftPanel = new VerticalPanel();
53      private SimplePanel sideBar = new SimplePanel();
54      private boolean refreshMenuOnAdd = true;
55      private VerticalCollapsableDrawer collapsablePanel = GWT.create(VerticalCollapsableDrawer.class);
56  
57      private Callback<Boolean> showViewCallback = new Callback<Boolean>() {
58  
59          @Override
60          public void exec(Boolean result) {
61              if (result == false) {
62                  KSMenuItemData item = viewMenuItemMap.get(MenuSectionController.this.getCurrentView().getViewEnum());
63                  if (item != null) {
64                      item.setSelected(true, false);
65                  }
66              }
67          }
68      };
69  
70      public MenuSectionController() {
71          super();
72          List<View> list = new ArrayList<View>();
73          menuViewMap.put("", list);
74          menu.setStyleName("ks-menu-layout-menu");
75          rightPanel.setStyleName("ks-menu-layout-rightColumn");
76          collapsablePanel.addStyleName("ks-menu-layout-leftColumn");
77          layout.addStyleName("ks-menu-layout");
78          menu.setTopLevelItems(topLevelMenuItems);
79          collapsablePanel.setContent(leftPanel);
80          leftPanel.add(menu);
81          leftPanel.add(sideBar);
82          rightPanel.add(header);
83          rightPanel.add(infoPanel);
84          rightPanel.add(topButtonPanel);
85          rightPanel.add(contentPanel);
86          rightPanel.add(bottomButtonPanel);
87          layout.add(collapsablePanel);
88          layout.add(rightPanel);
89          header.setVisible(false);
90          this.showPrint(true);
91          this.initWidget(layout);
92      }
93  
94      public void removeMenuNavigation() {
95          collapsablePanel.removeFromParent();
96      }
97  
98      public void setContentTitle(String title) {
99          header.setTitle(title);
100         header.setVisible(true);
101     }
102 
103     public void addContentWidget(Widget w) {
104         header.addWidget(w);
105         header.setVisible(true);
106     }
107     
108     public void addInfoWidget(Widget w) {
109         infoPanel.add(w);
110     }
111 
112     public void setSideBarWidget(Widget w) {
113         sideBar.setWidget(w);
114     }
115 
116     public void setContentInfo(String info) {
117         header.getInfoLabel().setHTML(info);
118         header.getInfoLabel().removeStyleName("content-warning");
119         header.getInfoLabel().addStyleName("content-info");
120     }
121 
122     public void setContentWarning(String info) {
123         header.getInfoLabel().setHTML(info);
124         header.getInfoLabel().removeStyleName("content-info");
125         header.getInfoLabel().addStyleName("content-warning");
126 
127     }
128 
129     public void showPrint(boolean show) {
130         header.showPrint(show);
131     }
132     
133     public void showExport(boolean show) {
134         header.showExport(show);
135     }
136 
137     /**
138      * @see org.kuali.student.common.ui.client.configurable.mvc.layouts.ContentNavLayoutController#addCommonButton(java.lang.String, org.kuali.student.common.ui.client.widgets.KSButton)
139      */
140     public void addCommonButton(String parentMenu, KSButton button) {
141         if (parentMenu != null) {
142             List<View> views = menuViewMap.get(parentMenu);
143             if (views != null) {
144                 for (int i = 0; i < views.size(); i++) {
145                     addButtonForView(views.get(i).getViewEnum(), button);
146                 }
147             }
148         }
149     }
150 
151     /**
152      * @see org.kuali.student.common.ui.client.configurable.mvc.layouts.ContentNavLayoutController#addCommonButton(java.lang.String, org.kuali.student.common.ui.client.widgets.KSButton, java.util.List)
153      */
154     public void addCommonButton(String parentMenu, KSButton button, List<Enum<?>> excludedViews) {
155         if (parentMenu != null) {
156             List<View> views = menuViewMap.get(parentMenu);
157             if (views != null) {
158                 for (int i = 0; i < views.size(); i++) {
159                     if (!excludedViews.contains(views.get(i).getViewEnum())) {
160                         addButtonForView(views.get(i).getViewEnum(), button);
161                     }
162                 }
163             }
164         }
165     }
166 
167     public void showNextViewOnMenu() {
168         int i = menuOrder.indexOf(this.getCurrentView());
169         if (i != -1 && i + 1 < menuOrder.size()) {
170             this.showView(menuOrder.get(i + 1).getViewEnum());
171         }
172     }
173 
174     public void addButtonForView(Enum<?> viewType, KSButton button) {
175         List<KSButton> buttons = viewButtonsMap.get(viewType);
176         if (buttons == null) {
177             buttons = new ArrayList<KSButton>();
178             button.addStyleName("ks-button-spacing");
179             buttons.add(button);
180             viewButtonsMap.put(viewType, buttons);
181         } else {
182             buttons.add(button);
183         }
184     }
185 
186     public void addTopButtonForView(Enum<?> viewType, KSButton button) {
187         List<KSButton> buttons = topViewButtonsMap.get(viewType);
188         if (buttons == null) {
189             buttons = new ArrayList<KSButton>();
190             button.addStyleName("ks-button-spacing");
191             buttons.add(button);
192             topViewButtonsMap.put(viewType, buttons);
193         } else {
194             buttons.add(button);
195         }
196     }
197 
198     @Override
199     protected void hideView(View view) {
200         contentPanel.clear();
201         bottomButtonPanel.clear();
202     }
203 
204     @Override
205     protected void renderView(View view) {
206         contentPanel.add(view.asWidget());
207 
208         //Render bottom buttons
209         List<KSButton> buttons = viewButtonsMap.get(view.getViewEnum());
210         if (buttons != null) {
211             for (KSButton button : buttons) {
212                 bottomButtonPanel.add(button);
213             }
214         }
215         
216         //Render top buttons
217         buttons = topViewButtonsMap.get(view.getViewEnum());
218         if (buttons != null) {
219             for (KSButton button : buttons) {
220                 topButtonPanel.add(button);
221             }
222         }
223 
224         KSMenuItemData item = viewMenuItemMap.get(view.getViewEnum());
225         if (item != null) {
226             item.setSelected(true, false);
227         }
228     }
229 
230     /* Adds 'name' of the menu above menu items. This menu name has no view */
231     public void addMenu(String title) {
232         if (title != null && !title.equals("")) {
233             KSMenuItemData item = new KSMenuItemData(title);
234             topLevelMenuItems.add(item);
235             List<View> list = new ArrayList<View>();
236             menuViewMap.put(title, list);
237             if (refreshMenuOnAdd) {
238                 menu.refresh();
239             }
240         }
241     }
242 
243     /**
244      * Adds a view whose view the menu at first.  addMenuItem() should not be called before this method if it is
245      * intended for this to be the first view the user sees.  revealMenuItems()
246      * must be called to show any items that were added after this call.
247      * IMPORTANT: the order in which you call this method, addMenuItem and addSpecialMenuItem affects the order in which they appear
248      * on the menu, but also the order in which they are shown when the showNextViewOnMenu is called.  Care must be
249      * taken when calling these methods to insure a consistent/logical UI.
250      */
251     public void addStartMenuItem(String parentMenu, final View view) {
252         addMenuItem(parentMenu, view);
253         this.setDefaultView(view.getViewEnum());
254         refreshMenuOnAdd = false;
255         menu.refresh();
256     }
257 
258     public void revealMenuItems() {
259         menu.refresh();
260         refreshMenuOnAdd = true;
261     }
262 
263     /**
264      * Adds a view whose view name will appear as a link on the menu, the view will be shown when this item is clicked.
265      * IMPORTANT: the order in which you call addMenuItem and addSpecialMenuItem affects the order in which they appear
266      * on the menu, but also the order in which they are shown when the showNextViewOnMenu is called.  Care must be
267      * taken when calling these methods to insure a consistent/logical UI.
268      */
269     @Override
270     public void addMenuItem(String parentMenu, final View view) {
271         super.addView(view);
272         KSMenuItemData parentItem = null;
273         for (int i = 0; i < topLevelMenuItems.size(); i++) {
274             if (topLevelMenuItems.get(i).getLabel().equals(parentMenu)) {
275                 parentItem = topLevelMenuItems.get(i);
276                 break;
277             }
278         }
279 
280         KSMenuItemData item = new KSMenuItemData(view.getName());
281         viewMenuItemMap.put(view.getViewEnum(), item);
282         item.setClickHandler(new ClickHandler() {
283 
284             @Override
285             public void onClick(ClickEvent event) {
286                 DeferredCommand.addCommand(new Command() {
287                     @Override
288                     public void execute() {
289                         MenuSectionController.this.showView(view.getViewEnum(), showViewCallback);
290                     }
291                 });
292             }
293 
294         });
295 
296         if (parentItem != null) {
297             menuOrder.add(view);
298             parentItem.addSubItem(item);
299             menuViewMap.get(parentMenu).add(view);
300         } else {
301             menuOrder.add(view);
302             topLevelMenuItems.add(item);
303             menuViewMap.get("").add(view);
304         }
305 
306         if (refreshMenuOnAdd) {
307             menu.refresh();
308         }
309     }
310 
311 
312     /**
313      * This adds a special item that is a top level menu item to the menu, this will appear directly below other
314      * menus that are currently added to the menu.  This menu item has special styling to make it more apparent on
315      * the menu visually.
316      * IMPORTANT: the order in which you call addMenuItem and addSpecialMenuItem affects the order in which they appear
317      * on the menu, but also the order in which they are shown when the showNextViewOnMenu is called.  Care must be
318      * taken when calling these methods to insure a consistent/logical UI.
319      */
320     @Override
321     public void addSpecialMenuItem(final View view, String description) {
322         //TODO add description to the menu item
323         super.addView(view);
324         menuViewMap.get("").add(view);
325         menuOrder.add(view);
326         KSMenuItemData item = new KSMenuItemData(view.getName());
327         item.addSpecialStyle("ks-menu-layout-special-menu-item-panel");
328         viewMenuItemMap.put(view.getViewEnum(), item);
329         item.setClickHandler(new ClickHandler() {
330 
331             @Override
332             public void onClick(ClickEvent event) {
333                 DeferredCommand.addCommand(new Command() {
334                     @Override
335                     public void execute() {
336                         MenuSectionController.this.showView(view.getViewEnum(), showViewCallback);
337                     }
338                 });
339             }
340 
341         });
342         topLevelMenuItems.add(item);
343         if (refreshMenuOnAdd) {
344             menu.refresh();
345         }
346     }
347 
348     /**
349      * This version of updateModel only traverses views that can be accessed through its menu.
350      * Views that are part of this controller, but not part of the menu, can update their views through
351      * updateModelFromCurrentView and updateModelFromView methods.
352      */
353     @Override
354     public void updateModel() {
355         for (View v : menuOrder) {
356             v.updateModel();
357         }
358 
359     }
360 
361     @Override
362     public List<ExportElement> getExportElementsFromView() {
363         return super.getExportElementsFromView();
364         
365     }
366     
367     public void addStyleName(String style){
368     	layout.addStyleName(style);
369     }
370 }