/**
* Copyright (c) 2014 - 2017 Frank Appel
* 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:
* Frank Appel - initial API and implementation
*/
package com.codeaffine.eclipse.swt.widget.scrollable;
import static com.codeaffine.eclipse.swt.util.ControlReflectionUtil.DISPLAY;
import static com.codeaffine.eclipse.swt.util.ControlReflectionUtil.SCROLL_BAR;
import static com.codeaffine.eclipse.swt.widget.scrollable.Demeanor.EXPAND_SCROLL_BAR_ON_MOUSE_OVER;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Layout;
import org.eclipse.swt.widgets.ScrollBar;
import org.eclipse.swt.widgets.Scrollable;
import org.eclipse.swt.widgets.Widget;
import com.codeaffine.eclipse.swt.util.ControlReflectionUtil;
import com.codeaffine.eclipse.swt.widget.scrollable.context.AdaptionContext;
import com.codeaffine.eclipse.swt.widget.scrollbar.FlatScrollBar;
abstract class ScrollableLayoutFactory<T extends Scrollable> implements LayoutFactory<T> {
static final String SCROLL_BAR_ADAPTER_CLASS = "org.eclipse.swt.widgets.ScrollBarAdapter";
private final ControlReflectionUtil reflectionUtil;
private FlatScrollBar horizontalBar;
private ScrollBar horizontalAdapter;
private AdaptionContext<T> context;
private FlatScrollBar verticalBar;
private ScrollBar verticalAdapter;
private Label cornerOverlay;
ScrollableLayoutFactory() {
reflectionUtil = new ControlReflectionUtil();
}
public abstract Layout create( AdaptionContext<T> context, FlatScrollBar horizontal, FlatScrollBar vertical );
public abstract DisposeListener createWatchDog( AdaptionContext<T> context, FlatScrollBar horizontal, FlatScrollBar vertical );
public abstract SelectionListener createHorizontalSelectionListener( AdaptionContext<T> context );
public abstract SelectionListener createVerticalSelectionListener( AdaptionContext<T> context );
@Override
public Layout create( AdaptionContext<T> context ) {
this.context = context;
context.put( Demeanor.class, EXPAND_SCROLL_BAR_ON_MOUSE_OVER );
context.getAdapter().setBackgroundMode( SWT.INHERIT_DEFAULT );
context.getAdapter().setBackground( context.getScrollable().getBackground() );
horizontalBar = createFlatScrollBar( context, SWT.HORIZONTAL );
verticalBar = createFlatScrollBar( context, SWT.VERTICAL );
horizontalBar.addSelectionListener( createHorizontalSelectionListener( context ) );
verticalBar.addSelectionListener( createVerticalSelectionListener( context ) );
context.getAdapter().addDisposeListener( createWatchDog( context, horizontalBar, verticalBar ) );
cornerOverlay = createCornerOverlay( context.getAdapter() );
return create( context, horizontalBar, verticalBar );
}
private static Label createCornerOverlay( Composite parent ) {
Label result = new Label( parent, SWT.NONE );
result.setBackground( parent.getBackground() );
result.moveAbove( null );
return result;
}
@Override
public ScrollBar getVerticalBarAdapter() {
if( verticalAdapter == null ) {
verticalAdapter = createFlatScrollBarAdapter( verticalBar );
}
return verticalAdapter;
}
@Override
public ScrollBar getHorizontalBarAdapter() {
if( horizontalAdapter == null ) {
horizontalAdapter = createFlatScrollBarAdapter( horizontalBar );
}
return horizontalAdapter;
}
@Override
public void setIncrementButtonLength( int incrementButtonLength ) {
horizontalBar.setIncrementButtonLength( incrementButtonLength );
verticalBar.setIncrementButtonLength( incrementButtonLength );
}
@Override
public int getIncrementButtonLength() {
return horizontalBar.getIncrementButtonLength();
}
@Override
public void setIncrementColor( Color incrementColor ) {
horizontalBar.setIncrementColor( incrementColor );
verticalBar.setIncrementColor( incrementColor );
}
@Override
public Color getIncrementColor() {
return horizontalBar.getIncrementColor();
}
@Override
public void setPageIncrementColor( Color pageIncrementColor ) {
horizontalBar.setPageIncrementColor( pageIncrementColor );
verticalBar.setPageIncrementColor( pageIncrementColor );
}
@Override
public Color getPageIncrementColor() {
return horizontalBar.getPageIncrementColor();
}
@Override
public void setThumbColor( Color thumbColor ) {
horizontalBar.setThumbColor( thumbColor );
verticalBar.setThumbColor( thumbColor );
}
@Override
public Color getThumbColor() {
return horizontalBar.getThumbColor();
}
@Override
public void setBackgroundColor( Color backgroundColor ) {
horizontalBar.setBackground( backgroundColor );
verticalBar.setBackground( backgroundColor );
cornerOverlay.setBackground( backgroundColor );
verticalBar.getParent().setBackground( backgroundColor );
}
@Override
public Color getBackgroundColor() {
return horizontalBar.getBackground();
}
@Override
public void setDemeanor( Demeanor demeanor ) {
context.put( Demeanor.class, demeanor );
}
@Override
public Demeanor getDemeanor() {
return context.get( Demeanor.class );
}
Label getCornerOverlay(){
return cornerOverlay;
}
private FlatScrollBar createFlatScrollBar( AdaptionContext<T> context, int direction ) {
FlatScrollBar result = new FlatScrollBar( context.getAdapter(), direction );
result.setBackground( context.getScrollable().getBackground() );
return result;
}
private ScrollBar createFlatScrollBarAdapter( FlatScrollBar scrollBar ) {
Class<? extends Widget> adapterClass = reflectionUtil.defineWidgetClass( SCROLL_BAR_ADAPTER_CLASS );
Widget widget = reflectionUtil.newInstance( adapterClass );
reflectionUtil.setField( widget, DISPLAY, Display.getCurrent() );
reflectionUtil.setField( widget, SCROLL_BAR, scrollBar );
return ( ScrollBar )widget;
}
}