001 /** 002 * Copyright 2010 The Kuali Foundation Licensed under the 003 * Educational Community License, Version 2.0 (the "License"); you may 004 * not use this file except in compliance with the License. You may 005 * obtain a copy of the License at 006 * 007 * http://www.osedu.org/licenses/ECL-2.0 008 * 009 * Unless required by applicable law or agreed to in writing, 010 * software distributed under the License is distributed on an "AS IS" 011 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 012 * or implied. See the License for the specific language governing 013 * permissions and limitations under the License. 014 */ 015 016 package org.kuali.student.lum.common.client.lo; 017 018 import java.util.ArrayList; 019 import java.util.HashMap; 020 import java.util.Map; 021 022 import org.kuali.student.common.assembly.data.QueryPath; 023 import org.kuali.student.common.ui.client.configurable.mvc.FieldDescriptor; 024 import org.kuali.student.common.ui.client.configurable.mvc.sections.VerticalSection; 025 import org.kuali.student.common.ui.client.theme.Theme; 026 import org.kuali.student.common.ui.client.widgets.field.layout.element.MessageKeyInfo; 027 028 import com.google.gwt.event.dom.client.MouseMoveHandler; 029 import com.google.gwt.event.logical.shared.ValueChangeEvent; 030 import com.google.gwt.event.logical.shared.ValueChangeHandler; 031 import com.google.gwt.event.shared.HandlerRegistration; 032 import com.google.gwt.user.client.DOM; 033 import com.google.gwt.user.client.Event; 034 import com.google.gwt.user.client.ui.HasValue; 035 import com.google.gwt.user.client.ui.HorizontalPanel; 036 import com.google.gwt.user.client.ui.Image; 037 import com.google.gwt.user.client.ui.Label; 038 import com.google.gwt.user.client.ui.VerticalPanel; 039 import com.google.gwt.user.client.ui.Widget; 040 041 042 public class OutlineManager extends VerticalSection implements HasValue<OutlineNodeModel> { 043 OutlineNodeModel<?> outlineModel; 044 String startOfPath; 045 String endOfPath; 046 String middleOfPath; 047 048 public OutlineManager(String pathStart, String pathMiddle, String pathEnd) { 049 startOfPath = pathStart; 050 middleOfPath = pathMiddle; 051 endOfPath = pathEnd; 052 } 053 054 public void render() { 055 Map<Integer, Integer> levelIndexes = new HashMap<Integer, Integer>(); 056 int currIndent = 0; 057 058 levelIndexes.put(0, -1); // first node increments the 0'th indent's index 059 OutlineNode[] outlineNodes = outlineModel.toOutlineNodes(); 060 for (final OutlineNode aNode : outlineNodes) { 061 NodePanel nodePanel = new NodePanel(); 062 nodePanel.setStyleName("KS-LONodePanel"); 063 nodePanel.setOutlineNode(aNode); 064 if (aNode.getIndentLevel() > currIndent) { 065 currIndent = aNode.getIndentLevel(); 066 levelIndexes.put(currIndent, 0); 067 } else if (aNode.getIndentLevel() < currIndent) { 068 currIndent = aNode.getIndentLevel(); 069 levelIndexes.put(currIndent, levelIndexes.get(currIndent) + 1); 070 } else { 071 levelIndexes.put(currIndent, levelIndexes.get(currIndent) + 1); 072 } 073 074 addField(getFieldKey(currIndent, levelIndexes), null, nodePanel, null); 075 076 showAllToolbar(); 077 } 078 } 079 080 private String getFieldKey(int currIndent, Map<Integer, Integer> levelIndexes) { 081 StringBuilder keyBuilder = new StringBuilder(startOfPath); 082 083 keyBuilder.append("/").append(levelIndexes.get(0)).append("/"); 084 for (int idx = 1; idx <= currIndent; idx++) { 085 keyBuilder.append(middleOfPath).append("/").append(levelIndexes.get(idx)).append("/"); 086 } 087 keyBuilder.append(endOfPath); 088 089 return keyBuilder.toString(); 090 } 091 092 private FieldDescriptor addField(String fieldKey, MessageKeyInfo messageKey, Widget widget, String parentPath) { 093 QueryPath path = QueryPath.concat(parentPath, fieldKey); 094 095 FieldDescriptor fd = new FieldDescriptor(path.toString(), messageKey, null); 096 if (widget != null) { 097 fd.setFieldWidget(widget); 098 fd.setHasHadFocus(true); 099 } 100 this.addField(fd); 101 return fd; 102 } 103 104 public void closeAllToolbar(){ 105 for (FieldDescriptor fd : this.getFields()) { 106 if (fd.getFieldWidget() instanceof NodePanel) { 107 ((NodePanel) fd.getFieldWidget()).hideToolbar(); 108 } 109 } 110 } 111 112 public void showAllToolbar(){ 113 for (FieldDescriptor fd : this.getFields()) { 114 if (fd.getFieldWidget() instanceof NodePanel) { 115 ((NodePanel) fd.getFieldWidget()).showToolbar(); 116 } 117 } 118 } 119 120 class NodePanel extends VerticalPanel{ 121 OutlineManagerToolbar toolbar = new OutlineManagerToolbar(); 122 HorizontalPanel emptySpacePanel = new HorizontalPanel(); 123 ArrayList<MouseMoveHandler> mouseMoveHandlerList = new ArrayList<MouseMoveHandler>(); 124 HorizontalPanel horitonalPanel = new HorizontalPanel(); 125 OutlineNode currentNode; 126 NodePanel() { 127 toolbar.setModel(outlineModel); 128 horitonalPanel.setStyleName("KS-LOHNodePanel"); 129 super.sinkEvents(Event.ONMOUSEMOVE); 130 super.sinkEvents(Event.ONMOUSEOUT); 131 emptySpacePanel.setStyleName("KS-LOOutlineManagerToolbar"); 132 Image ieHack = Theme.INSTANCE.getCommonImages().getSpacer(); 133 emptySpacePanel.add(ieHack); 134 super.insert(emptySpacePanel,0); 135 } 136 137 public void setOutlineNode(OutlineNode aNode) { 138 currentNode = aNode; 139 for (int i = 0; i < aNode.getIndentLevel(); i++) { 140 Label label = new Label(); 141 label.setStyleName("KS-LONodeIndent"); 142 horitonalPanel.add(label); 143 144 // space for toolbar 145 label = new Label(); 146 label.setStyleName("KS-LONodeIndentToolbar"); 147 toolbar.insert(label, 0); 148 } 149 Widget userWidget = (Widget) aNode.getUserObject(); 150 userWidget.setStyleName("KS-LOaNode"); 151 horitonalPanel.add(userWidget); 152 153 add(horitonalPanel); 154 } 155 156 public void addMouseMoveHandler(MouseMoveHandler handler) { 157 mouseMoveHandlerList.add(handler); 158 } 159 160 public void setToolbar(OutlineManagerToolbar t) { 161 toolbar = t; 162 } 163 public void showToolbar(){ 164 super.remove(emptySpacePanel); 165 super.insert(toolbar, 0); 166 } 167 public void hideToolbar(){ 168 super.remove(toolbar); 169 super.insert(emptySpacePanel,0); 170 } 171 @Override 172 public void onBrowserEvent(Event event) { 173 switch (DOM.eventGetType(event)) { 174 case Event.ONMOUSEMOVE: { 175 outlineModel.setCurrentNode(currentNode); 176 break; 177 } 178 case Event.ONMOUSEOUT: 179 break; 180 } 181 super.onBrowserEvent(event); 182 } 183 184 @Override 185 protected void onEnsureDebugId(String baseID) { 186 super.onEnsureDebugId(baseID); 187 toolbar.ensureDebugId(baseID); 188 if (currentNode != null) { 189 Object userObject = currentNode.getUserObject(); 190 if (userObject instanceof Widget) { 191 ((Widget) userObject).ensureDebugId(baseID); 192 } 193 } 194 } 195 196 197 } 198 199 @Override 200 public OutlineNodeModel getValue() { 201 return outlineModel; 202 } 203 204 @Override 205 public void setValue(OutlineNodeModel value) { 206 outlineModel = value; 207 } 208 209 @Override 210 public void setValue(OutlineNodeModel value, boolean fireEvents) { 211 setValue(value); 212 } 213 214 @Override 215 public HandlerRegistration addValueChangeHandler(ValueChangeHandler<OutlineNodeModel> handler) { 216 return addHandler(handler, ValueChangeEvent.getType()); 217 } 218 }