/* * Copyright (c) 2010 Zhihua (Dennis) Jiang * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package com.gwtmobile.ui.client.widgets; import java.util.ArrayList; import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.ScheduledCommand; import com.google.gwt.dom.client.Element; import com.google.gwt.dom.client.EventTarget; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.ui.HasWidgets; import com.google.gwt.user.client.ui.Widget; import com.gwtmobile.ui.client.CSS.StyleNames.Primary; import com.gwtmobile.ui.client.CSS.StyleNames.Secondary; import com.gwtmobile.ui.client.event.DragController; import com.gwtmobile.ui.client.event.DragEvent; import com.gwtmobile.ui.client.event.DragEventsHandler; import com.gwtmobile.ui.client.event.SelectionChangedEvent; import com.gwtmobile.ui.client.event.SelectionChangedHandler; import com.gwtmobile.ui.client.utils.Utils; public class CheckBoxGroup extends PanelBase implements HasWidgets, ClickHandler, DragEventsHandler, ValueChangeHandler<Boolean> { private int _pressed = -1; public CheckBoxGroup() { super(); addDomHandler(this, ClickEvent.getType()); setStyleName(Primary.CheckBoxGroup); addStyleName(Secondary.Vertical); } @Override public void onLoad() { super.onLoad(); DragController.get().addDragEventsHandler(this); } @Override protected void onUnload() { super.onUnload(); DragController.get().removeDragEventsHandler(this); } public HandlerRegistration addSelectionChangedHandler(SelectionChangedHandler handler) { return this.addHandler(handler, SelectionChangedEvent.TYPE); } @Override public void onClick(ClickEvent e) { final EventTarget target = e.getNativeEvent().getEventTarget(); String targetTagName = ((Element)target.cast()).getTagName().toUpperCase(); Utils.Console("onClick target " + targetTagName); if (targetTagName.equals("LABEL")) { return; // if check box label is click, another (simulated) click event with // check box INPUT as target will fire after this one. So this click event // can be safely ignored. } Element div = Element.as(target); while (!div.getNodeName().toUpperCase().equals("SPAN") || div.getParentElement() != this.getElement()) { div = div.getParentElement(); if (div == null) { Utils.Console("CheckBoxGroup onClick: span not found"); return; } } final int index = DOM.getChildIndex(this.getElement(), (com.google.gwt.user.client.Element)div); com.google.gwt.user.client.ui.CheckBox checkbox = (com.google.gwt.user.client.ui.CheckBox) getWidget(index); Utils.Console("onClick " + checkbox.getValue()); if (targetTagName.equals("INPUT")) { Utils.Console("onClick value changed"); checkbox.setValue(checkbox.getValue()); // if target is check box INPUT, check box value is // already changed when click event is fired. // just need to set its current value back to the check box // to update style. } else { checkbox.setValue(!checkbox.getValue()); } Scheduler.get().scheduleDeferred(new ScheduledCommand() { @Override public void execute() { SelectionChangedEvent selectionChangedEvent = new SelectionChangedEvent(index, target); fireEvent(selectionChangedEvent); } }); } public ArrayList<Integer> getCheckedIndices() { ArrayList<Integer> checkedList = new ArrayList<Integer>(getWidgetCount()); for (int i = 0; i < getWidgetCount(); i++) { com.google.gwt.user.client.ui.CheckBox radio = (com.google.gwt.user.client.ui.CheckBox) getWidget(i); if (radio.getValue()) { checkedList.add(i); } } return checkedList; } public ArrayList<Widget> getCheckedWidgets() { ArrayList<Widget> checkedList = new ArrayList<Widget>(getWidgetCount()); for (int i = 0; i < getWidgetCount(); i++) { com.google.gwt.user.client.ui.CheckBox radio = (com.google.gwt.user.client.ui.CheckBox) getWidget(i); if (radio.getValue()) { checkedList.add(radio); } } return checkedList; } @Override public void add(Widget w) { assert w instanceof CheckBox : "Can only contain CheckBox widgets in CheckBoxGroup"; CheckBox checkbox = (CheckBox) w; super.add(checkbox); checkbox.addValueChangeHandler(this); } public void addWidgetToPanel(Widget w) { super.add(w); } public void setVertical(boolean vertical) { if (vertical) { addStyleName(Secondary.Vertical); removeStyleName(Secondary.Horizontal); } else { addStyleName(Secondary.Horizontal); removeStyleName(Secondary.Vertical); } } @Override public void onValueChange(ValueChangeEvent<Boolean> event) { Utils.Console("onValueChange " + event.getValue() + " " + event.getSource().getClass()); } @Override public void onDragStart(DragEvent e) { _pressed = Utils.getTargetItemIndex(getElement(), e.getNativeEvent().getEventTarget()); if (_pressed >= 0) { Widget item = getWidget(_pressed); item.addStyleName(Secondary.Pressed); } } @Override public void onDragMove(DragEvent e) { if (_pressed >= 0) { Widget item = getWidget(_pressed); item.removeStyleName(Secondary.Pressed); _pressed = -1; } } @Override public void onDragEnd(DragEvent e) { onDragMove(e); } }