/*******************************************************************************
* 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.ui.ridgets.swt;
import java.beans.PropertyChangeSupport;
import org.eclipse.swt.custom.CCombo;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Table;
import org.eclipse.riena.internal.ui.ridgets.swt.DisabledMarkerVisualizer;
import org.eclipse.riena.ui.ridgets.AbstractMarkerSupport;
import org.eclipse.riena.ui.ridgets.IBasicMarkableRidget;
import org.eclipse.riena.ui.swt.lnf.LnfKeyConstants;
import org.eclipse.riena.ui.swt.lnf.LnfManager;
import org.eclipse.riena.ui.swt.utils.SwtUtilities;
/**
* Helper class for Ridgets to delegate their marker issues to that just handles the basic markers for uneditable Ridgets: the HiddenMarker to toggle visibility
* and the DisabledMarker that toggles the enabled state.
*
* @since 3.0
*/
public class BasicMarkerSupport extends AbstractMarkerSupport {
private static boolean alwaysSkipRedraw = false;
private static boolean osChecked = false;
private boolean initialEnabled = true;
private boolean initialVisible;
/**
* @since 3.0
*/
protected DisabledMarkerVisualizer disabledMarkerVisualizer;
public BasicMarkerSupport() {
super();
initialVisible = true;
}
public BasicMarkerSupport(final IBasicMarkableRidget ridget, final PropertyChangeSupport propertyChangeSupport) {
super(ridget, propertyChangeSupport);
initialVisible = true;
}
/**
* {@inheritDoc}
*/
@Override
public void init(final IBasicMarkableRidget ridget, final PropertyChangeSupport propertyChangeSupport) {
super.init(ridget, propertyChangeSupport);
final Control control = getUIControl();
if (!SwtUtilities.isDisposed(control)) {
control.addDisposeListener(new DisposeListener() {
public void widgetDisposed(final DisposeEvent e) {
final Control control = getUIControl();
if (e.widget == control) {
// workaround for Bug 304869
if (!(control instanceof CCombo)) {
clearAllMarkers(control);
}
}
}
});
}
// workaround for 272863
if (!osChecked) {
osChecked = true;
final String osname = System.getProperty("org.osgi.framework.os.name"); //$NON-NLS-1$
if (osname != null && osname.equalsIgnoreCase("macosx")) { //$NON-NLS-1$
alwaysSkipRedraw = true;
}
}
createDisabledMarkerVisualizer();
}
@Override
public void updateMarkers() {
updateUIControl();
}
// protected methods
////////////////////
/**
* Does nothing. Subclasses may override.
*
* @param control
* the control
*/
protected void clearAllMarkers(final Control control) {
clearDisabled(control);
clearVisible(control);
}
private void clearDisabled(final Control control) {
disabledMarkerVisualizer.updateDisabled(control, initialEnabled);
}
private void clearVisible(final Control control) {
control.setVisible(initialVisible);
}
/**
* @since 3.0
*/
@Override
public void bind() {
if (getUIControl() != null) {
//save initial state of control
saveState();
}
}
/**
* @since 3.0
*/
@Override
public void unbind() {
if (getUIControl() != null) {
//restore initial state of control
clearAllMarkers(getUIControl());
}
}
/**
* @since 3.0
*/
protected void saveState() {
this.initialEnabled = getUIControl().getEnabled();
this.initialVisible = getUIControl().getVisible();
}
/**
* @since 3.0
*/
public boolean isInitialEnabled() {
return initialEnabled;
}
/**
* {@inheritDoc}
*/
@Override
protected Control getUIControl() {
return (Control) super.getUIControl();
}
@Override
protected void handleMarkerAttributesChanged() {
updateUIControl();
super.handleMarkerAttributesChanged();
}
protected void updateUIControl(final Control control) {
updateVisible(control);
// ask the ridget if it controls the disabled marker state
if (getRidget() == null || !getRidget().handlesDisabledMarker()) {
// the ridget does not control disabled state. Handle it here!
updateDisabled(control);
}
}
protected void updateVisible(final Control control) {
control.setVisible(!hasHiddenMarkers());
}
protected void updateDisabled(final Control control) {
final boolean on = LnfManager.getLnf().getBooleanSetting(LnfKeyConstants.DISABLED_MARKER_ADVANCED);
if (on) {
// delegate to the visualizer for rendering
getDisabledMarkerVisualizer().updateDisabled();
} else {
control.setEnabled(getRidget().isEnabled());
}
}
// helping methods
//////////////////
private void createDisabledMarkerVisualizer() {
this.disabledMarkerVisualizer = new DisabledMarkerVisualizer(getRidget());
}
private DisabledMarkerVisualizer getDisabledMarkerVisualizer() {
return disabledMarkerVisualizer;
}
private void startRedraw(final Control control) {
if (!skipRedrawForBug258176(control)) {
control.setRedraw(true);
}
control.redraw();
}
private void stopRedraw(final Control control) {
if (!skipRedrawForBug258176(control)) {
control.setRedraw(false);
}
}
/**
* These controls are affected by bug 258176 in SWT.
*/
private boolean skipRedrawForBug258176(final Control control) {
if (alwaysSkipRedraw) {
return true;
}
return (control instanceof Combo) || (control instanceof Table) || (control instanceof List);
}
private void updateUIControl() {
final Control control = getUIControl();
if (control != null) {
stopRedraw(control);
try {
updateUIControl(control);
} finally {
startRedraw(control);
}
}
}
}