001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.gwt.client.ui; 029 030import org.opencms.gwt.client.ui.I_CmsButton.ButtonStyle; 031import org.opencms.util.CmsStringUtil; 032 033import com.google.gwt.core.client.GWT; 034import com.google.gwt.event.dom.client.ClickEvent; 035import com.google.gwt.event.dom.client.ClickHandler; 036import com.google.gwt.event.dom.client.HasClickHandlers; 037import com.google.gwt.event.logical.shared.CloseEvent; 038import com.google.gwt.event.logical.shared.CloseHandler; 039import com.google.gwt.event.logical.shared.ResizeEvent; 040import com.google.gwt.event.logical.shared.ResizeHandler; 041import com.google.gwt.event.shared.HandlerRegistration; 042import com.google.gwt.uibinder.client.UiBinder; 043import com.google.gwt.uibinder.client.UiConstructor; 044import com.google.gwt.uibinder.client.UiField; 045import com.google.gwt.user.client.Event; 046import com.google.gwt.user.client.Window; 047import com.google.gwt.user.client.ui.Composite; 048import com.google.gwt.user.client.ui.PopupPanel; 049import com.google.gwt.user.client.ui.Widget; 050 051/** 052 * Provides a menu button.<p> 053 * 054 * @since 8.0.0 055 */ 056public class CmsMenuButton extends Composite implements HasClickHandlers { 057 058 /** 059 * @see com.google.gwt.uibinder.client.UiBinder 060 */ 061 interface I_CmsMenuButtonUiBinder extends UiBinder<Widget, CmsMenuButton> { 062 // GWT interface, nothing to do here 063 } 064 065 /** The ui-binder instance for this class. */ 066 private static I_CmsMenuButtonUiBinder uiBinder = GWT.create(I_CmsMenuButtonUiBinder.class); 067 068 /** The menu button. */ 069 @UiField 070 protected CmsPushButton m_button; 071 072 /** The menu content. */ 073 protected CmsToolbarPopup m_popup; 074 075 /** Registration of the window resize handler. */ 076 protected HandlerRegistration m_resizeRegistration; 077 078 /** Flag if the menu is open. */ 079 private boolean m_isOpen; 080 081 /** Flag if the menu opens to the right hand side. */ 082 private boolean m_isOpenRight; 083 084 /** 085 * Constructor.<p> 086 * 087 * @param buttonText the menu button text 088 * @param imageClass the menu button image sprite class 089 */ 090 @UiConstructor 091 public CmsMenuButton(String buttonText, String imageClass) { 092 093 this(); 094 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(buttonText)) { 095 m_button.setText(buttonText); 096 } 097 m_button.setImageClass(imageClass); 098 } 099 100 /** 101 * Constructor.<p> 102 */ 103 protected CmsMenuButton() { 104 105 initWidget(uiBinder.createAndBindUi(this)); 106 m_button.setSize(I_CmsButton.Size.big); 107 m_button.setButtonStyle(ButtonStyle.MENU, null); 108 m_button.addStyleName(I_CmsButton.ButtonStyle.FONT_ICON.getCssClassName()); 109 m_isOpen = false; 110 111 m_popup = new CmsToolbarPopup(m_button, false, getElement()); 112 m_popup.addCloseHandler(new CloseHandler<PopupPanel>() { 113 114 public void onClose(CloseEvent<PopupPanel> event) { 115 116 autoClose(); 117 if (m_resizeRegistration != null) { 118 m_resizeRegistration.removeHandler(); 119 m_resizeRegistration = null; 120 } 121 } 122 }); 123 } 124 125 /** 126 * @see com.google.gwt.event.dom.client.HasClickHandlers#addClickHandler(com.google.gwt.event.dom.client.ClickHandler) 127 */ 128 public HandlerRegistration addClickHandler(ClickHandler handler) { 129 130 return addDomHandler(handler, ClickEvent.getType()); 131 } 132 133 /** 134 * Removes all content from menu.<p> 135 */ 136 public void clear() { 137 138 m_popup.clear(); 139 140 } 141 142 /** 143 * Closes the menu and fires the on toggle event.<p> 144 */ 145 public void closeMenu() { 146 147 m_popup.hide(); 148 } 149 150 /** 151 * Disables the menu button.<p> 152 * 153 * @param disabledReason the reason to set in the button title 154 */ 155 public void disable(String disabledReason) { 156 157 m_button.disable(disabledReason); 158 getElement().setPropertyBoolean("disabled", true); 159 } 160 161 /** 162 * Enables or disables the button.<p> 163 */ 164 public void enable() { 165 166 m_button.enable(); 167 getElement().setPropertyBoolean("disabled", false); 168 } 169 170 /** 171 * Hides the menu content as well as the menu connector.<p> 172 */ 173 public void hide() { 174 175 m_popup.hide(); 176 } 177 178 /** 179 * Returns if the menu is open.<p> 180 * 181 * @return <code>true</code> if the menu is opened 182 */ 183 public boolean isOpen() { 184 185 return m_isOpen; 186 } 187 188 /** 189 * Returns the isOpenRight.<p> 190 * 191 * @return the isOpenRight 192 */ 193 public boolean isOpenRight() { 194 195 return m_isOpenRight; 196 } 197 198 /** 199 * @see com.google.gwt.user.client.ui.Composite#onBrowserEvent(com.google.gwt.user.client.Event) 200 */ 201 @Override 202 public void onBrowserEvent(Event event) { 203 204 // Should not act on button if disabled. 205 if (!isEnabled()) { 206 return; 207 } 208 super.onBrowserEvent(event); 209 } 210 211 /** 212 * Opens the menu and fires the on toggle event.<p> 213 */ 214 public void openMenu() { 215 216 m_isOpen = true; 217 setButtonDown(); 218 219 m_popup.show(); 220 m_popup.position(); 221 m_resizeRegistration = Window.addResizeHandler(new ResizeHandler() { 222 223 public void onResize(ResizeEvent event) { 224 225 m_popup.position(); 226 } 227 }); 228 } 229 230 /** 231 * Enables or disables the button.<p> 232 * 233 * @param enabled if true, enables the button, else disables it 234 */ 235 public void setEnabled(boolean enabled) { 236 237 if (enabled) { 238 enable(); 239 } else { 240 m_button.setEnabled(enabled); 241 getElement().setPropertyBoolean("disabled", true); 242 } 243 } 244 245 /** 246 * This will set the menu content widget.<p> 247 * 248 * @param widget the widget to set as content 249 */ 250 public void setMenuWidget(Widget widget) { 251 252 m_popup.remove(widget); 253 m_popup.add(widget); 254 } 255 256 /** 257 * Sets the isOpenRight.<p> 258 * 259 * @param isOpenRight the isOpenRight to set 260 */ 261 public void setOpenRight(boolean isOpenRight) { 262 263 m_isOpenRight = isOpenRight; 264 } 265 266 /** 267 * Sets the isToolbarMode.<p> 268 * 269 * @param isToolbarMode the isToolbarMode to set 270 */ 271 public void setToolbarMode(boolean isToolbarMode) { 272 273 m_popup.setToolbarMode(isToolbarMode); 274 } 275 276 /** 277 * Shows the menu content as well as the menu connector.<p> 278 */ 279 public void show() { 280 281 m_popup.show(); 282 } 283 284 /** 285 * Called on auto close.<p> 286 */ 287 protected void autoClose() { 288 289 setButtonUp(); 290 } 291 292 /** 293 * Returns the popup content.<p> 294 * 295 * @return the popup content 296 */ 297 protected CmsPopup getPopup() { 298 299 return m_popup; 300 } 301 302 /** 303 * Hides the menu content without altering the button state.<p> 304 */ 305 protected void hideMenu() { 306 307 m_popup.hide(); 308 if (m_resizeRegistration != null) { 309 m_resizeRegistration.removeHandler(); 310 m_resizeRegistration = null; 311 } 312 } 313 314 /** 315 * Returns if this button is enabled.<p> 316 * 317 * @return <code>true</code> if the button is enabled 318 */ 319 protected boolean isEnabled() { 320 321 return !getElement().getPropertyBoolean("disabled"); 322 } 323 324 /** 325 * Sets the button to its 'down state'. 326 */ 327 protected void setButtonDown() { 328 329 m_button.setDown(true); 330 } 331 332 /** 333 * Sets button to state up, hides menu fragments (not the content pop-up) and fires the toggle event.<p> 334 */ 335 protected void setButtonUp() { 336 337 m_isOpen = false; 338 m_button.setDown(false); 339 } 340 341}