// // ERXNavigationMenu.java: Class file for WO Component 'ERXNavigationMenu' // Project ERExtensions // // Created by max on Wed Oct 30 2002 // package er.extensions.appserver.navigation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.webobjects.appserver.WOActionResults; import com.webobjects.appserver.WOContext; import com.webobjects.appserver.WORequest; import com.webobjects.appserver.WOResponse; import com.webobjects.foundation.NSArray; import com.webobjects.foundation.NSKeyValueCoding; import er.extensions.appserver.ERXSession; import er.extensions.components.ERXStatelessComponent; import er.extensions.foundation.ERXValueUtilities; /** Please read "Documentation/Navigation.html" to fnd out how to use the navigation components.i */ public class ERXNavigationMenu extends ERXStatelessComponent { /** * Do I need to update serialVersionUID? * See section 5.6 <cite>Type Changes Affecting Serialization</cite> on page 51 of the * <a href="http://java.sun.com/j2se/1.4/pdf/serial-spec.pdf">Java Object Serialization Spec</a> */ private static final long serialVersionUID = 1L; private static final Logger log = LoggerFactory.getLogger(ERXNavigationMenu.class); public ERXNavigationItem aNavigationItem; protected ERXNavigationState _navigationState; protected NSKeyValueCoding _navigationContext; protected NSArray _level1Items; protected NSArray _level2Items; protected NSArray _level3Items; public int _level1SpacerWidth=0; public int _level2SpacerWidth=0; public int _level3SpacerWidth=0; public int _renderLevelCount; protected int l2Colspan; protected boolean _menuIsSetUp=false; public ERXNavigationMenu(WOContext context) { super(context); } @Override public void reset() { _level1Items=null; _level2Items=null; _level3Items=null; _menuIsSetUp=false; _renderLevelCount=0; aNavigationItem = null; _navigationState = null; _navigationContext = null; super.reset(); } protected NSKeyValueCoding navigationContext() { if (_navigationContext == null) { _navigationContext = (NSKeyValueCoding)valueForBinding("navigationContext"); } return _navigationContext; } public void setUpMenu() { if (!_menuIsSetUp) { if (navigationContext() != null) { Object o = navigationContext().valueForKey("navigationState"); if(o != null) { NSArray navigationState = (o instanceof NSArray ? (NSArray)o : NSArray.componentsSeparatedByString(o.toString(), ".")); if (navigationState != null && navigationState.count() > 0) { navigationState().setState(navigationState); } else { o = navigationContext().valueForKey("additionalNavigationState"); o = (o == null ? NSArray.EmptyArray : o); NSArray additionalNavigationState = (o instanceof NSArray ? (NSArray)o : NSArray.componentsSeparatedByString(o.toString(), ".")); if (additionalNavigationState != null && additionalNavigationState.count() > 0) { navigationState().setAdditionalState(additionalNavigationState); } else if (ERXValueUtilities.booleanValue(navigationContext().valueForKey("shouldResetNavigationState"))) { navigationState().setState(NSArray.EmptyArray); } } } } // init numOfLevels int numOfLevels = menuLevelsToShow(); log.debug("Number of levels: {}", numOfLevels); //set the values in the arrays setLevel1Items(itemsForLevel(1)); setLevel1SpacerWidth(setupLevel1SpacerWidth()); if (numOfLevels >= 2) { setLevel2Items(itemsForLevel(2)); setLevel2SpacerWidth(setupLevel2SpacerWidth()); // For additional nav situation if (numOfLevels >= 3) { setLevel3Items(itemsForLevel(3)); setLevel3SpacerWidth(setupLevel3SpacerWidth()); } } _menuIsSetUp=true; } } public ERXNavigationState navigationState() { if (_navigationState == null) _navigationState = ERXNavigationManager.manager().navigationStateForSession(session()); return _navigationState; } public NSArray itemsForLevel(int level) { NSArray children = navigationState().navigationItemsForLevel(level, this); log.debug("Children: {} for level: {}", children.count(), level); if (children.count() > 0) _renderLevelCount++; return children; } @Override public void takeValuesFromRequest(WORequest r, WOContext c) { setUpMenu(); super.takeValuesFromRequest(r,c); } @Override public void appendToResponse(WOResponse r, WOContext c) { setUpMenu(); super.appendToResponse(r,c); } @Override public WOActionResults invokeAction(WORequest r, WOContext c) { WOActionResults results=null; setUpMenu(); try { results = super.invokeAction(r,c); } catch (RuntimeException e) { // Might need to ignore rapid clicks, catch some type of IllegalArgumentException throw e; } return results; } public int setupLevel2SpacerWidth() { //String tmpString = new String(); int totalWidth = 0; int lev1Width = level1Width(); int lev2Width = level2Width(); int i = 0; for (i=0; i < level1Items().count(); i++) { ERXNavigationItem anObject = (ERXNavigationItem)level1Items().objectAtIndex(i); /* code to act on each element */ //tmpString = (String)anObject.componentPath(); int tmpInt = anObject.width(); totalWidth = totalWidth + tmpInt; if (navigationState().state().containsObject(anObject.name())) { // we need to stop going through the objects here if (lev2Width <= (totalWidth + level1SpacerWidth())) { // it will fit aligned right if ((i + 1) == level1Items().count()) { return 0; } return (lev1Width - totalWidth); } if (lev2Width < (lev1Width - (totalWidth - tmpInt))) { //it will fit aligned left totalWidth = totalWidth - tmpInt; return ((lev1Width - totalWidth) - lev2Width); } } } return (lev1Width - lev2Width); } public int setupLevel3SpacerWidth() { //String tmpString = new String(); int totalWidth = 0; int lev2Width = level2SpacerWidth() + level2Width(); int lev3Width = level3Width(); int i = 0; for (i=0; i < _level2Items.count(); i++) { ERXNavigationItem anObject = (ERXNavigationItem)_level2Items.objectAtIndex(i); /* code to act on each element */ //tmpString = (String)anObject.componentPath(); int tmpInt=anObject.width(); totalWidth = totalWidth + tmpInt; if (navigationState().state().containsObject(anObject.name())) { // we need to stop going through the objects here //for aligning left, which is our first choice here totalWidth = totalWidth - tmpInt; if (lev3Width <= (lev2Width - totalWidth)) { return (lev2Width - totalWidth) - lev3Width; } // for aligning right if (lev3Width < (level1Width() - (totalWidth + tmpInt))) { totalWidth = totalWidth + tmpInt; return (lev2Width - totalWidth); } } } return 0; } public boolean showLevel2() { return navigationState().stateAsString() != null ? (navigationState().state().count()>=1 && _level2Items != null && _level2Items.count()>0) : false; } public boolean showLevel3() { // In theory we could have other stuff at level 3, but for now we don't.. // return _level3Items != null && _level3Items.count()>0; return navigationState().stateAsString() != null && navigationState().state().count()>=2 && _level3Items != null && _level3Items.count()>0; } public int menuLevelsToShow() { int result=1; NSArray tmpArray = navigationState().state(); result= tmpArray.count()+(tmpArray.count() <= 2 ? 1 : 0); return result; } public NSArray level1Items() { return _level1Items; } public int level1SpacerWidth() { return _level1SpacerWidth; } public int level1Width() { int totalWidth = 0; if (_level1Items != null) { for (int i=0; i < _level1Items.count(); i++) { totalWidth += ((ERXNavigationItem)_level1Items.objectAtIndex(i)).width(); } } return totalWidth; } public NSArray level2Items() { return _level2Items; } public int level2SpacerWidth() { return _level2SpacerWidth; } public int level2Width() { int totalWidth = 0; if (_level2Items != null) { for (int i=0; i < _level2Items.count(); i++) { totalWidth += ((ERXNavigationItem)_level2Items.objectAtIndex(i)).width(); } } return totalWidth; } public NSArray level3Items() { return _level3Items; } public int level3SpacerWidth() { return _level3SpacerWidth; } public int level3Width() { int totalWidth = 0; if (_level3Items != null) { for (int i=0; i < _level3Items.count(); i++) { totalWidth += ((ERXNavigationItem)_level3Items.objectAtIndex(i)).width(); } } return totalWidth; } public int setupLevel1SpacerWidth() { return navItemsTableWidth()-level1Width(); } public void setLevel1Items(NSArray newLevel1Items) { _level1Items = newLevel1Items; } public void setLevel1SpacerWidth(int newLevel1SpacerWidth) { _level1SpacerWidth = newLevel1SpacerWidth; } public void setLevel2Items(NSArray newLevel2Items) { _level2Items = newLevel2Items; } public void setLevel2SpacerWidth(int newLevel2SpacerWidth) { _level2SpacerWidth = newLevel2SpacerWidth; } public void setLevel3Items(NSArray newLevel3Items) { _level3Items = newLevel3Items; } public void setLevel3SpacerWidth(int newLevel3SpacerWidth) { _level3SpacerWidth = newLevel3SpacerWidth; } public int navItemsTableWidth() { int level1Width=level1Width(); return level1Width < 200 ? 200 : level1Width; } public String paddingWidth() { return ((ERXSession)session()).browser().isNetscape() ? "width=\"100%\"" : ""; } // CSS Additions public String level1itemsClass() { String classString = showLevel2() ? " L1WithChildren" : ""; return "Level1Items" + classString; } public String level2itemsClass() { String classString = showLevel3() ? " L2WithChildren" : ""; return "Level2Items" + classString; } }