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.input; 029 030import org.opencms.gwt.client.ui.CmsPushButton; 031import org.opencms.gwt.client.ui.I_CmsButton.ButtonStyle; 032import org.opencms.gwt.client.ui.css.I_CmsInputCss; 033import org.opencms.gwt.client.ui.css.I_CmsInputLayoutBundle; 034 035import com.google.gwt.event.dom.client.ClickEvent; 036import com.google.gwt.event.dom.client.ClickHandler; 037import com.google.gwt.event.logical.shared.HasValueChangeHandlers; 038import com.google.gwt.event.logical.shared.ValueChangeEvent; 039import com.google.gwt.event.logical.shared.ValueChangeHandler; 040import com.google.gwt.event.shared.HandlerRegistration; 041import com.google.gwt.user.client.ui.Composite; 042 043/** 044 * Tri-state checkbox.<p> 045 */ 046public class CmsTriStateCheckBox extends Composite implements HasValueChangeHandlers<CmsTriStateCheckBox.State> { 047 048 /** 049 * The possible check box states.<p> 050 */ 051 public enum State { 052 /** neither on nor off. */ 053 middle, /** off. **/ 054 off, /** on. **/ 055 on; 056 } 057 058 /** The CSS bundle for this class. */ 059 protected static final I_CmsInputCss CSS = I_CmsInputLayoutBundle.INSTANCE.inputCss(); 060 061 /** The button which provides the actual widget layout. */ 062 private CmsPushButton m_button; 063 064 /** The state to use as a next state if the user clicks on the checkbox while it is in its third state. */ 065 private State m_nextStateAfterMiddle = State.off; 066 067 /** The current state. */ 068 private State m_state; 069 070 /** The check box text. */ 071 private String m_text; 072 073 /** 074 * Creates a new instance.<p> 075 * 076 * @param labelText the label text 077 */ 078 public CmsTriStateCheckBox(String labelText) { 079 080 m_button = new CmsPushButton(); 081 m_text = labelText; 082 initWidget(m_button); 083 m_button.setButtonStyle(ButtonStyle.TRANSPARENT, null); 084 addStyleName(CSS.triState()); 085 m_state = State.middle; 086 updateStyle(); 087 m_button.addClickHandler(new ClickHandler() { 088 089 public void onClick(ClickEvent event) { 090 091 CmsTriStateCheckBox.this.onClick(); 092 } 093 }); 094 095 } 096 097 /** 098 * @see com.google.gwt.event.logical.shared.HasValueChangeHandlers#addValueChangeHandler(com.google.gwt.event.logical.shared.ValueChangeHandler) 099 */ 100 public HandlerRegistration addValueChangeHandler(ValueChangeHandler<State> handler) { 101 102 return addHandler(handler, ValueChangeEvent.getType()); 103 } 104 105 /** 106 * Sets the state which the check box should transition to if the user clicks on it while it is neither on nor off.<p> 107 * 108 * @param state the target state 109 */ 110 public void setNextStateAfterIntermediateState(State state) { 111 112 m_nextStateAfterMiddle = state; 113 } 114 115 /** 116 * Sets the state of the check box and optionally fires an event.<p> 117 * 118 * @param state the new state 119 * @param fireEvent true if a ValueChangeEvent should be fired 120 */ 121 public void setState(State state, boolean fireEvent) { 122 123 boolean changed = m_state != state; 124 m_state = state; 125 if (changed) { 126 updateStyle(); 127 } 128 if (fireEvent) { 129 ValueChangeEvent.fire(this, state); 130 } 131 } 132 133 /** 134 * Sets the check box label text.<p> 135 * 136 * @param text the new label text 137 */ 138 public void setText(String text) { 139 140 m_text = text; 141 updateStyle(); 142 } 143 144 /** 145 * Handles clicks on the check box.<p> 146 */ 147 protected void onClick() { 148 149 State newState = getNextState(m_state); 150 setState(newState, true); 151 } 152 153 /** 154 * Gets the image class to use for the check box.<p> 155 * 156 * @return the image class 157 */ 158 private String getImageClass() { 159 160 switch (m_state) { 161 case on: 162 return CSS.triStateOn(); 163 case off: 164 return CSS.triStateOff(); 165 case middle: 166 default: 167 return CSS.triStateMedium(); 168 } 169 170 } 171 172 /** 173 * Gets the state which the check box would change to if cilcked on in a given state.<p> 174 * 175 * @param state the original state 176 * @return the next state 177 */ 178 private State getNextState(State state) { 179 180 State nextState = null; 181 switch (state) { 182 case off: 183 nextState = State.on; 184 break; 185 case on: 186 nextState = State.off; 187 break; 188 case middle: 189 default: 190 nextState = m_nextStateAfterMiddle; 191 } 192 return nextState; 193 } 194 195 /** 196 * Updates the UI state according to the logical state.<p> 197 */ 198 private void updateStyle() { 199 200 m_button.setUpFace(m_text, getImageClass()); 201 } 202}