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 */ 016package com.github.gwtbootstrap.client.ui; 017 018import java.util.ArrayList; 019import java.util.List; 020 021import com.github.gwtbootstrap.client.ui.base.ComplexWidget; 022import com.github.gwtbootstrap.client.ui.base.ListItem; 023import com.github.gwtbootstrap.client.ui.base.UnorderedList; 024import com.github.gwtbootstrap.client.ui.constants.Constants; 025import com.google.gwt.dom.client.Document; 026import com.google.gwt.user.client.ui.HasText; 027import com.google.gwt.user.client.ui.Widget; 028import com.google.gwt.user.client.ui.WidgetCollection; 029 030/** 031 * The Breadcrumbs container 032 * 033 * <p> 034 * <h3>UiBinder Usage:</h3> 035 * <p/> 036 * <pre> 037 * {@code 038 * <b:Breadcrumbs> 039 * <b:NavLink>Home</b:NavLink> 040 * <b:NavLink>Accoount</b:NavLink> 041 * </b:Breadcrumbs> 042 * <b:Breadcrumbs divider=">"> 043 * <b:NavLink>Home</b:NavLink> 044 * <b:NavLink>Accoount</b:NavLink> 045 * </b:Breadcrumbs> 046 * } 047 * 048 * @since 2.0.4.0 049 * @author Dominik Mayer 050 * @author ohashi keisuke 051 */ 052public class Breadcrumbs extends UnorderedList { 053 054 private WidgetCollection children = new WidgetCollection(this); 055 056 private List<Divider> dividerList = new ArrayList<Divider>(); 057 058 private String divider = "/"; 059 060 private static class Divider extends ComplexWidget { 061 062 public Divider(String divider) { 063 super("span"); 064 setStyleName(Constants.DIVIDER); 065 setDivider(divider); 066 } 067 068 public void setDivider(String divider) { 069 getElement().setInnerText(divider); 070 } 071 } 072 073 074 /** 075 * Create a empty Breadcrumbs 076 */ 077 public Breadcrumbs() { 078 setStyleName(Constants.BREADCRUMB); 079 } 080 081 /** 082 * Create Breadcrumbs with widgets 083 * @param widgets widgets 084 */ 085 public Breadcrumbs(Widget ... widgets) { 086 this(); 087 088 for (Widget widget : widgets) { 089 this.add(widget); 090 } 091 } 092 093 /** 094 * Create Breadcrumbs with setting divider character 095 * @param divider separate char (ex : ">") 096 */ 097 public Breadcrumbs(String divider) { 098 this(); 099 this.setDivider(divider); 100 } 101 102 /** 103 * Set separater character 104 * @param divider separater character 105 */ 106 public void setDivider(String divider) { 107 if(divider == null || divider.isEmpty()) { 108 this.divider = "/"; 109 } else { 110 this.divider = divider; 111 } 112 113 for (Divider dividerWidget : dividerList) { 114 dividerWidget.setDivider(this.divider); 115 } 116 117 } 118 119 /** 120 * {@inheritDoc} 121 */ 122 @Override 123 protected void onAttach() { 124 125 if(!isOrWasAttached() && children.size() > 0) { 126 127 Widget lastWidget = children.get(children.size() -1); 128 129 for (Widget w : children) { 130 ListItem item = lastWidget.equals(w) 131 ? change2TextListItem(w) 132 : getOrCreateListItem(w); 133 super.add(item); 134 } 135 } 136 137 super.onAttach(); 138 } 139 140 /** 141 * {@inheritDoc} 142 */ 143 @Override 144 public void add(Widget w) { 145 146 w.removeStyleName(Constants.ACTIVE); 147 148 if(!isOrWasAttached()) { 149 150 children.add(w); 151 152 return; 153 } 154 155 if(children.size() > 0) { 156 //Change last widget 2 Link 157 158 //pygical remove 159 super.remove(getWidget(getWidgetCount() -1)); 160 161 ListItem item = getOrCreateListItem(children.get(children.size() -1)); 162 163 super.add(item); 164 } 165 166 ListItem newest = change2TextListItem(w); 167 168 super.add(newest); 169 170 children.add(w); 171 } 172 173 private ListItem getOrCreateListItem(Widget lastWidget) { 174 ListItem item = null; 175 176 Divider dividerWidget = new Divider(divider); 177 if(lastWidget instanceof NavWidget) { 178 NavWidget w = (NavWidget)lastWidget; 179 180 if(hasDivier(w)) { 181 182 return w; 183 } else { 184 dividerList.add(dividerWidget); 185 w.addWidget(dividerWidget); 186 return w; 187 } 188 } else if(lastWidget instanceof ListItem) { 189 item = (ListItem)lastWidget; 190 } else { 191 item = new ListItem(lastWidget); 192 } 193 194 if(hasDivier(item)) { 195 return item; 196 } 197 198 item.add(dividerWidget); 199 dividerList.add(dividerWidget); 200 201 return item; 202 } 203 204 private boolean hasDivier(ListItem item) { 205 206 for(Widget w : item) { 207 if(w instanceof Divider) { 208 return true; 209 } 210 } 211 return false; 212 } 213 214 private ListItem change2TextListItem(Widget w) { 215 String text = null; 216 217 if (w instanceof HasText) { 218 text = ((HasText) w).getText(); 219 } else { 220 text = w.getElement().getInnerText(); 221 } 222 223 ListItem newest = new ListItem(); 224 newest.setStyleName(Constants.ACTIVE); 225 newest.getElement().appendChild(Document.get().createTextNode(text)); 226 return newest; 227 } 228 229 /** 230 * {@inheritDoc} 231 */ 232 @Override 233 public boolean remove(Widget w) { 234 235 if(!isOrWasAttached() && children.contains(w)) { 236 children.remove(w); 237 return true; 238 } 239 240 if(getWidgetIndex(w) < 0 && !children.contains(w)) { 241 return false; 242 } 243 244 boolean isLastWidget = (children.indexOf(w) == children.size() -1) || (getWidgetIndex(w) == getWidgetCount() -1); 245 246 if(getWidgetIndex(w) >= 0 && children.contains(w)) { 247 children.remove(w); 248 super.remove(w); 249 } else if(getWidgetIndex(w) >= 0 && !children.contains(w)) { 250 children.remove(getWidgetIndex(w)); 251 super.remove(w); 252 } else if(getWidgetIndex(w) < 0 && children.contains(w)) { 253 return remove(getWidget(children.indexOf(w))); 254 } else { 255 return false; 256 } 257 258 if(isLastWidget && getWidgetCount() > 0) { 259 Widget l = getWidget(getWidgetCount() -1); 260 super.remove(l); 261 super.add(change2TextListItem(l)); 262 } 263 264 return true; 265 } 266 267 /** 268 * {@inheritDoc} 269 */ 270 @Override 271 public void clear() { 272 super.clear(); 273 children = new WidgetCollection(this); 274 dividerList.clear(); 275 } 276}