/******************************************************************************* * Copyright (c) 2007, 2014 compeople AG and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * compeople AG - initial API and implementation *******************************************************************************/ package org.eclipse.riena.internal.ui.ridgets.swt; import org.eclipse.core.databinding.observable.list.WritableList; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.riena.ui.ridgets.swt.AbstractSWTRidget; import org.eclipse.riena.ui.swt.ChoiceComposite; import org.eclipse.riena.ui.swt.lnf.LnFUpdater; import org.eclipse.riena.ui.swt.utils.SWTControlFinder; import org.eclipse.riena.ui.swt.utils.SwtUtilities; /** * Baseclass for all ChoiceRidgets. */ public abstract class AbstractChoiceRidget extends AbstractSWTRidget { protected static final String CHOICE_RIDGET_LISTENER = "choiceRidget.listener"; //$NON-NLS-1$ protected final static LnFUpdater LNF_UPDATER = LnFUpdater.getInstance(); protected String[] optionLabels; /** The list of available options. */ protected WritableList optionsObservable = new WritableList(); public AbstractChoiceRidget() { optionsObservable = new WritableList(); } protected void layoutNewChildren() { final ChoiceComposite control = (ChoiceComposite) getUIControl(); if (SwtUtilities.isDisposed(control)) { return; } final Control[] childrenButtonsOld = control.getChildrenButtons(); final int oldCount = childrenButtonsOld.length; final int newCount = optionsObservable.toArray().length; // disposeChildren(control); createChildren(control, true); if (oldCount != newCount) { // if the number of children has changed // update the layout of the parent composite control.getParent().layout(true, false); } } protected void createChildren(final ChoiceComposite control) { createChildren(control, false); } protected void createChildren(final ChoiceComposite control, final boolean reuseButtons) { if (control != null && !control.isDisposed()) { final Object[] values = optionsObservable.toArray(); final Control[] childrenOld = control.getChildrenButtons(); int i; for (i = 0; i < values.length; i++) { final Object value = values[i]; final String caption = optionLabels != null ? optionLabels[i] : String.valueOf(value); Button button; if (reuseButtons && i < childrenOld.length) { button = (Button) childrenOld[i]; unconfigureOptionButton(button); button.setText(caption); } else { button = control.createChild(caption); } button.setData(value); configureOptionButton(button); } if (reuseButtons) { // dispose buttons that are not needed anymore while (i < childrenOld.length) { childrenOld[i++].dispose(); } } updateSelection(control); LNF_UPDATER.updateUIControls(control, true); } } protected abstract void updateSelection(final ChoiceComposite control); protected abstract void configureOptionButton(final Button button); protected abstract void unconfigureOptionButton(final Button button); protected void disposeChildren(final ChoiceComposite control) { if (control != null && !control.isDisposed()) { for (final Control child : control.getChildrenButtons()) { child.dispose(); } } } /** * Returns the number of the children of the given UI control. * <p> * this method is not API, visibility for testing * * @param control * UI control * * @return number of children */ public int getChildrenCount(final ChoiceComposite control) { if (SwtUtilities.isDisposed(control)) { return 0; } return control.getChildrenButtons().length; } @Override public boolean hasFocus() { if (!SwtUtilities.isDisposed(getUIControl())) { final Control control = getUIControl(); if (control.isFocusControl()) { return true; } if (!(control instanceof Composite)) { return false; } final ChildFocusChecker checker = new ChildFocusChecker((Composite) control); checker.run(); return checker.childHasFocus; } return false; } public void updateEditable(final ChoiceComposite control, final boolean isEditable) { if (control != null && !control.isDisposed()) { control.updateReadOnly(!isEnabled() || !isEditable); } } /** * Iterates over the child controls of a given composite and checks if one them has the focus. */ private static class ChildFocusChecker extends SWTControlFinder { private boolean childHasFocus = false; public ChildFocusChecker(final Composite composite) { super(composite); } @Override public void handleBoundControl(final Control control, final String bindingProperty) { super.handleControl(control); } @Override public void handleControl(final Control control) { super.handleControl(control); if (control.isFocusControl()) { childHasFocus = true; } } } }