![JAR search and dependency download from the Maven repository](/logo.png)
org.eclipse.swt.custom.CTabFolder Maven / Gradle / Ivy
/*******************************************************************************
* Copyright (c) 2002, 2024 Innoopract Informationssysteme GmbH 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:
* Innoopract Informationssysteme GmbH - initial API and implementation
* EclipseSource - ongoing development
******************************************************************************/
package org.eclipse.swt.custom;
import org.eclipse.rap.rwt.internal.lifecycle.WidgetLCA;
import org.eclipse.rap.rwt.internal.textsize.TextSizeUtil;
import org.eclipse.rap.rwt.internal.theme.ThemeAdapter;
import org.eclipse.rap.rwt.theme.BoxDimensions;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.internal.custom.ICTabFolderAdapter;
import org.eclipse.swt.internal.custom.ctabfolderkit.CTabFolderLCA;
import org.eclipse.swt.internal.custom.ctabfolderkit.CTabFolderThemeAdapter;
import org.eclipse.swt.internal.events.EventTypes;
import org.eclipse.swt.internal.widgets.IItemHolderAdapter;
import org.eclipse.swt.internal.widgets.IWidgetGraphicsAdapter;
import org.eclipse.swt.internal.widgets.ItemHolder;
import org.eclipse.swt.internal.widgets.WidgetGraphicsAdapter;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Layout;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.TypedListener;
/**
* Instances of this class implement the notebook user interface
* metaphor. It allows the user to select a notebook page from
* set of pages.
*
* The item children that may be added to instances of this class
* must be of type CTabItem
.
* Control
children are created and then set into a
* tab item using CTabItem#setControl
.
*
* Note that although this class is a subclass of Composite
,
* it does not make sense to set a layout on it.
*
* IMPORTANT: This class is not intended to be subclassed.
*
*
* - Styles:
* - CLOSE, TOP, BOTTOM, FLAT, BORDER, SINGLE, MULTI
* - Events:
* - Selection
* - "CTabFolder2"
*
*
*
* Note: Only one of the styles TOP and BOTTOM
* may be specified.
*
*
* Implementation Status:
* Attributes, found in SWT, that are not supported
*
* - simple (treated as
true
)
*
*
* @since 1.0
*/
public class CTabFolder extends Composite {
// internal constants
static final int DEFAULT_WIDTH = 64;
static final int DEFAULT_HEIGHT = 64;
static final int BUTTON_SIZE = 18;
static final int SELECTION_FOREGROUND = SWT.COLOR_LIST_FOREGROUND;
static final int SELECTION_BACKGROUND = SWT.COLOR_LIST_BACKGROUND;
static final int BORDER1_COLOR = SWT.COLOR_WIDGET_NORMAL_SHADOW;
static final int FOREGROUND = SWT.COLOR_WIDGET_FOREGROUND;
static final int BACKGROUND = SWT.COLOR_WIDGET_BACKGROUND;
static final int BUTTON_BORDER = SWT.COLOR_WIDGET_DARK_SHADOW;
static final int BUTTON_FILL = SWT.COLOR_LIST_BACKGROUND;
/**
* marginWidth specifies the number of pixels of horizontal margin
* that will be placed along the left and right edges of the form.
*
* The default value is 0.
*/
public int marginWidth = 0;
/**
* marginHeight specifies the number of pixels of vertical margin
* that will be placed along the top and bottom edges of the form.
*
* The default value is 0.
*/
public int marginHeight = 0;
private transient ICTabFolderAdapter tabFolderAdapter;
private final IWidgetGraphicsAdapter selectionGraphicsAdapter;
private final ItemHolder itemHolder = new ItemHolder<>( CTabItem.class );
private final ControlListener resizeListener;
private FocusListener focusListener;
private Menu showMenu;
int selectedIndex = -1;
private int firstIndex = -1; // index of the left most visible tab
private boolean mru;
private int[] priority = new int[ 0 ];
final boolean showClose;
boolean showUnselectedClose = true;
boolean showUnselectedImage = true;
boolean showMax;
boolean showMin;
private boolean inDispose;
boolean minimized;
boolean maximized;
boolean onBottom;
final boolean simple = true; // no curvy tab items supported (yet)
boolean single;
private final Rectangle maxRect = new Rectangle( 0, 0, 0, 0 );
private final Rectangle minRect = new Rectangle( 0, 0, 0, 0 );
// Chevron
private final Rectangle chevronRect = new Rectangle( 0, 0, 0, 0 );
private boolean showChevron;
// Tab bar
private int fixedTabHeight = SWT.DEFAULT;
int tabHeight = 0;
int minChars = 20;
// TopRight control
Control topRight;
private int topRightAlignment = SWT.RIGHT;
private final Rectangle topRightRect = new Rectangle( 0, 0, 0, 0 );
// Client origin and border dimensions
private int xClient;
private int yClient;
private final int highlight_margin;
private int highlight_header;
private int borderRight;
private int borderLeft;
private int borderBottom;
private int borderTop;
// keep track of size changes in order to redraw only affected area
// on Resize
// Point oldSize;
// Colors
private Color selectionBackground = null;
private Color selectionForeground = null;
private Image selectionBgImage = null;
/**
* Constructs a new instance of this class given its parent
* and a style value describing its behavior and appearance.
*
* The style value is either one of the style constants defined in
* class SWT
which is applicable to instances of this
* class, or must be built by bitwise OR'ing together
* (that is, using the int
"|" operator) two or more
* of those SWT
style constants. The class description
* lists the style constants that are applicable to the class.
* Style bits are also inherited from superclasses.
*
*
* @param parent a widget which will be the parent of the new instance (cannot be null)
* @param style the style of widget to construct
*
* @exception IllegalArgumentException
* - ERROR_NULL_ARGUMENT - if the parent is null
*
* @exception SWTException
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent
*
*
* @see SWT#TOP
* @see SWT#BOTTOM
* @see SWT#FLAT
* @see SWT#BORDER
* @see SWT#SINGLE
* @see SWT#MULTI
* @see #getStyle()
*/
public CTabFolder( Composite parent, int style ) {
super( parent, checkStyle( style ) );
super.setLayout( new CTabFolderLayout() );
onBottom = ( super.getStyle() & SWT.BOTTOM ) != 0;
single = ( super.getStyle() & SWT.SINGLE ) != 0;
showClose = ( super.getStyle() & SWT.CLOSE ) != 0;
borderRight = ( style & SWT.BORDER ) != 0 ? 1 : 0;
borderLeft = borderRight;
borderTop = onBottom ? borderLeft : 0;
borderBottom = onBottom ? 0 : borderLeft;
highlight_header = ( style & SWT.FLAT ) != 0 ? 1 : 3;
highlight_margin = ( style & SWT.FLAT ) != 0 ? 0 : 2;
updateTabHeight( false );
resizeListener = new ControlAdapter() {
@Override
public void controlResized( ControlEvent event ) {
onResize();
}
};
addControlListener( resizeListener );
registerDisposeListener();
selectionGraphicsAdapter = new WidgetGraphicsAdapter();
}
//////////////////
// Item management
/**
* Return the tab items.
*
* @return the tab items
*
* @exception SWTException
* - ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
* - ERROR_WIDGET_DISPOSED when the widget has been disposed
*
*/
public CTabItem[] getItems() {
checkWidget();
return itemHolder.getItems();
}
/**
* Return the tab that is located at the specified index.
*
* @param index the index of the tab item
* @return the item at the specified index
*
* @exception IllegalArgumentException
* - ERROR_INVALID_RANGE - if the index is out of range
*
* @exception SWTException
* - ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
* - ERROR_WIDGET_DISPOSED when the widget has been disposed
*
*/
public CTabItem getItem( int index ) {
checkWidget();
return itemHolder.getItem( index );
}
/**
* Gets the item at a point in the widget.
*
* @param pt the point in coordinates relative to the CTabFolder
* @return the item at a point or null
*
* @exception SWTException
* - ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
* - ERROR_WIDGET_DISPOSED when the widget has been disposed
*
* @since 1.2
*/
public CTabItem getItem( Point pt ) {
// checkWidget();
CTabItem result = null;
Point size = getSize();
boolean onChevron = showChevron && chevronRect.contains( pt );
int itemCount = itemHolder.size();
if( itemCount > 0 && size.x > borderLeft + borderRight && !onChevron ) {
CTabItem[] items = itemHolder.getItems();
for( int i = 0; result == null && i < priority.length; i++ ) {
CTabItem item = items[ priority[ i ] ];
Rectangle rect = item.getBounds();
if( rect.contains( pt ) ) {
result = item;
}
}
}
return result ;
}
/**
* Return the number of tabs in the folder.
*
* @return the number of tabs in the folder
*
* @exception SWTException
* - ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
* - ERROR_WIDGET_DISPOSED when the widget has been disposed
*
*/
public int getItemCount() {
checkWidget();
return itemHolder.size();
}
/**
* Return the index of the specified tab or -1 if the tab is not
* in the receiver.
*
* @param item the tab item for which the index is required
*
* @return the index of the specified tab item or -1
*
* @exception IllegalArgumentException
* - ERROR_NULL_ARGUMENT - if the listener is null
*
*
* @exception SWTException
* - ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
* - ERROR_WIDGET_DISPOSED when the widget has been disposed
*
*/
public int indexOf( CTabItem item ) {
checkWidget();
return itemHolder.indexOf( item );
}
///////////////////////
// Selection management
/**
* Set the selection to the tab at the specified index.
*
* @param index the index of the tab item to be selected
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public void setSelection( int index ) {
checkWidget();
if( index >= 0 && index <= itemHolder.size() - 1 ) {
if( selectedIndex != index ) {
int oldSelectionIndex = selectedIndex;
selectedIndex = index;
getItem( selectedIndex ).showing = false;
Control control = getItem( selectedIndex ).getControl();
// Adjust bounds of selected control and make it visible (if any)
if( control != null && !control.isDisposed() ) {
control.setBounds( getClientArea() );
control.setVisible( true );
}
// Hide control of previous selection (if any)
if( oldSelectionIndex >= 0 && oldSelectionIndex < getItemCount() ) {
Control oldControl = getItem( oldSelectionIndex ).getControl();
if( oldControl != null && oldControl != control && !oldControl.isDisposed() ) {
oldControl.setVisible( false );
}
}
}
showItem( getSelection() );
}
}
/**
* Return the index of the selected tab item, or -1 if there
* is no selection.
*
* @return the index of the selected tab item or -1
*
* @exception SWTException
* - ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
* - ERROR_WIDGET_DISPOSED when the widget has been disposed
*
*/
public int getSelectionIndex() {
checkWidget();
return selectedIndex;
}
/**
* Set the selection to the tab at the specified item.
*
* @param item the tab item to be selected
*
* @exception IllegalArgumentException
* - ERROR_NULL_ARGUMENT - if the listener is null
*
*
* @exception SWTException
* - ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
* - ERROR_WIDGET_DISPOSED when the widget has been disposed
*
*/
public void setSelection( CTabItem item ) {
checkWidget();
if( item == null ) {
SWT.error( SWT.ERROR_NULL_ARGUMENT );
}
int index = itemHolder.indexOf( item );
setSelection( index );
}
/**
* Return the selected tab item, or null if there is no selection.
*
* @return the selected tab item, or null if none has been selected
*
* @exception SWTException
* - ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
* - ERROR_WIDGET_DISPOSED when the widget has been disposed
*
*/
public CTabItem getSelection() {
checkWidget();
CTabItem result = null;
if( selectedIndex != -1 ) {
result = itemHolder.getItem( selectedIndex );
}
return result;
}
/**
* Shows the selection. If the selection is already showing in the receiver,
* this method simply returns. Otherwise, the items are scrolled until
* the selection is visible.
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*
* @see CTabFolder#showItem(CTabItem)
*/
public void showSelection () {
checkWidget();
if( selectedIndex != -1 ) {
showItem( getSelection() );
}
}
/**
* Shows the item. If the item is already showing in the receiver,
* this method simply returns. Otherwise, the items are scrolled until
* the item is visible.
*
* @param item the item to be shown
*
* @exception IllegalArgumentException
* - ERROR_NULL_ARGUMENT - if the item is null
* - ERROR_INVALID_ARGUMENT - if the item has been disposed
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*
* @see CTabFolder#showSelection()
*/
public void showItem( CTabItem item ) {
checkWidget();
if( item == null ) {
SWT.error( SWT.ERROR_NULL_ARGUMENT );
}
if( item.isDisposed() ) {
SWT.error( SWT.ERROR_INVALID_ARGUMENT );
}
int index = indexOf( item );
if( index == -1 ) {
SWT.error( SWT.ERROR_INVALID_ARGUMENT );
}
int idx = -1;
for( int i = 0; idx == -1 && i < priority.length; i++ ) {
if( priority[ i ] == index ) {
idx = i;
}
}
if( mru ) {
// move to front of mru order
int[] newPriority = new int[ priority.length ];
System.arraycopy( priority, 0, newPriority, 1, idx );
System.arraycopy( priority,
idx + 1,
newPriority,
idx + 1,
priority.length - idx - 1 );
newPriority[ 0 ] = index;
priority = newPriority;
}
if( !item.isShowing() ) {
updateItems( index );
}
}
//////////////////////////////
// Most recently used settings
/**
* When there is not enough horizontal space to show all the tabs,
* by default, tabs are shown sequentially from left to right in
* order of their index. When the MRU visibility is turned on,
* the tabs that are visible will be the tabs most recently selected.
* Tabs will still maintain their left to right order based on index
* but only the most recently selected tabs are visible.
*
* For example, consider a CTabFolder that contains "Tab 1", "Tab 2",
* "Tab 3" and "Tab 4" (in order by index). The user selects
* "Tab 1" and then "Tab 3". If the CTabFolder is now
* compressed so that only two tabs are visible, by default,
* "Tab 2" and "Tab 3" will be shown ("Tab 3" since it is currently
* selected and "Tab 2" because it is the previous item in index order).
* If MRU visibility is enabled, the two visible tabs will be "Tab 1"
* and "Tab 3" (in that order from left to right).
*
* @param show the new visibility state
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public void setMRUVisible( boolean show ) {
checkWidget();
if( mru != show ) {
mru = show;
if( !mru ) {
int idx = firstIndex;
int next = 0;
for( int i = firstIndex; i < priority.length; i++ ) {
priority[ next++ ] = i;
}
for( int i = 0; i < idx; i++ ) {
priority[ next++ ] = i;
}
updateItems();
}
}
}
/**
* Returns true
if the receiver displays most
* recently used tabs and false
otherwise.
*
* When there is not enough horizontal space to show all the tabs,
* by default, tabs are shown sequentially from left to right in
* order of their index. When the MRU visibility is turned on,
* the tabs that are visible will be the tabs most recently selected.
* Tabs will still maintain their left to right order based on index
* but only the most recently selected tabs are visible.
*
* For example, consider a CTabFolder that contains "Tab 1", "Tab 2",
* "Tab 3" and "Tab 4" (in order by index). The user selects
* "Tab 1" and then "Tab 3". If the CTabFolder is now
* compressed so that only two tabs are visible, by default,
* "Tab 2" and "Tab 3" will be shown ("Tab 3" since it is currently
* selected and "Tab 2" because it is the previous item in index order).
* If MRU visibility is enabled, the two visible tabs will be "Tab 1"
* and "Tab 3" (in that order from left to right).
*
* @return the receiver's header's visibility state
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public boolean getMRUVisible() {
checkWidget();
return mru;
}
////////////////////////////////
// Minimize / Maximize / Restore
/**
* Marks the receiver's maximize button as visible if the argument is true
,
* and marks it invisible otherwise.
*
* @param maximizeVisible the new visibility state
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public void setMaximizeVisible( boolean maximizeVisible ) {
checkWidget();
if( showMax != maximizeVisible ) {
showMax = maximizeVisible;
updateItems();
}
}
/**
* Returns true
if the maximize button
* is visible.
*
* @return the visibility of the maximized button
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public boolean getMaximizeVisible() {
checkWidget();
return showMax;
}
/**
* Marks the receiver's minimize button as visible if the argument is true
,
* and marks it invisible otherwise.
*
* @param minimizeVisible the new visibility state
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public void setMinimizeVisible( boolean minimizeVisible ) {
checkWidget();
if( showMin != minimizeVisible ) {
showMin = minimizeVisible;
updateItems();
}
}
/**
* Returns true
if the minimize button
* is visible.
*
* @return the visibility of the minimized button
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public boolean getMinimizeVisible() {
checkWidget();
return showMin;
}
/**
* Marks the receiver's minimize button as visible if the argument is true
,
* and marks it invisible otherwise.
*
* @param minimized the new visibility state
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public void setMinimized( boolean minimized ) {
checkWidget();
if( this.minimized != minimized ) {
if( minimized && maximized ) {
setMaximized( false );
}
this.minimized = minimized;
}
}
/**
* Returns true
if the receiver is minimized.
*
* @return the receiver's minimized state
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public boolean getMinimized() {
checkWidget();
return minimized;
}
/**
* Sets the maximized state of the receiver.
*
* @param maximized the new maximized state
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public void setMaximized( boolean maximized ) {
checkWidget();
if( this.maximized != maximized ) {
if( maximized && minimized ) {
setMinimized( false );
}
this.maximized = maximized;
}
}
/**
* Returns true
if the receiver is maximized.
*
*
* @return the receiver's maximized state
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public boolean getMaximized() {
checkWidget();
return maximized;
}
//////////////////////////////////////
// Appearance and dimension properties
/**
* Sets the layout which is associated with the receiver to be
* the argument which may be null.
*
* Note: No Layout can be set on this Control because it already
* manages the size and position of its children.
*
*
* @param layout the receiver's new layout or null
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
@Override
public void setLayout( Layout layout ) {
checkWidget();
// ignore - CTabFolder manages its own layout
}
/**
* Specify a fixed height for the tab items. If no height is specified,
* the default height is the height of the text or the image, whichever
* is greater. Specifying a height of -1 will revert to the default height.
*
* @param height the pixel value of the height or -1
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
* - ERROR_INVALID_ARGUMENT - if called with a height of less than 0
*
*/
public void setTabHeight( int height ) {
checkWidget();
if( height < -1 ) {
SWT.error( SWT.ERROR_INVALID_ARGUMENT );
}
fixedTabHeight = height;
updateTabHeight( false );
}
/**
* Returns the height of the tab
*
* @return the height of the tab
*
* @exception SWTException
* - ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
* - ERROR_WIDGET_DISPOSED when the widget has been disposed
*
*/
public int getTabHeight() {
checkWidget();
int result;
if( fixedTabHeight != SWT.DEFAULT ) {
result = fixedTabHeight;
} else {
result = tabHeight - 1; // -1 for line drawn across top of tab
}
return result;
}
/**
* Returns the number of characters that will
* appear in a fully compressed tab.
*
* @return number of characters that will appear in a fully compressed tab
*/
public int getMinimumCharacters() {
checkWidget();
return minChars;
}
/**
* Sets the minimum number of characters that will
* be displayed in a fully compressed tab.
*
* @param minimumCharacters the minimum number of characters that will be displayed in a fully compressed tab
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
* - ERROR_INVALID_RANGE - if the count is less than zero
*
*/
public void setMinimumCharacters( int minimumCharacters ) {
checkWidget();
if( minimumCharacters < 0 ) {
SWT.error( SWT.ERROR_INVALID_RANGE );
}
if( minChars != minimumCharacters ) {
minChars = minimumCharacters;
updateItems();
}
}
@Override
public int getStyle() {
checkWidget();
int result = super.getStyle();
result &= ~( SWT.TOP | SWT.BOTTOM );
result |= onBottom ? SWT.BOTTOM : SWT.TOP;
result &= ~( SWT.SINGLE | SWT.MULTI );
result |= single ? SWT.SINGLE : SWT.MULTI;
if( borderLeft != 0 ) {
result |= SWT.BORDER;
}
return result;
}
/**
* Returns true
if the CTabFolder only displays the selected tab
* and false
if the CTabFolder displays multiple tabs.
*
* @return true
if the CTabFolder only displays the selected tab and false
if the CTabFolder displays multiple tabs
*/
public boolean getSingle() {
checkWidget();
return single;
}
/**
* Sets the number of tabs that the CTabFolder should display
*
* @param single true
if only the selected tab should be displayed otherwise, multiple tabs will be shown.
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public void setSingle( boolean single ) {
checkWidget();
if( this.single != single ) {
this.single = single;
updateItemsWithResizeEvent();
}
}
/**
* Returns the position of the tab. Possible values are SWT.TOP or SWT.BOTTOM.
*
* @return the position of the tab
*
* @exception SWTException
* - ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
* - ERROR_WIDGET_DISPOSED when the widget has been disposed
*
*/
public int getTabPosition() {
checkWidget();
return onBottom ? SWT.BOTTOM : SWT.TOP;
}
/**
* Specify whether the tabs should appear along the top of the folder
* or along the bottom of the folder.
*
* @param position SWT.TOP
for tabs along the top or SWT.BOTTOM
for tabs along the bottom
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
* - ERROR_INVALID_ARGUMENT - if the position value is not either SWT.TOP or SWT.BOTTOM
*
*/
public void setTabPosition( int position ) {
checkWidget();
if( position != SWT.TOP && position != SWT.BOTTOM ) {
SWT.error( SWT.ERROR_INVALID_ARGUMENT );
}
if( onBottom != ( position == SWT.BOTTOM ) ) {
onBottom = position == SWT.BOTTOM;
borderTop = onBottom ? borderLeft : 0;
borderBottom = onBottom ? 0 : borderRight;
updateTabHeight( true );
updateItemsWithResizeEvent();
}
}
/**
* Returns true
if the receiver's border is visible.
*
* @return the receiver's border visibility state
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public boolean getBorderVisible() {
checkWidget();
return borderLeft == 1;
}
/**
* Toggle the visibility of the border
*
* @param show true if the border should be displayed
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public void setBorderVisible( boolean show ) {
checkWidget();
if( ( borderLeft != 1 ) != !show ) {
borderLeft = borderRight = show ? 1 : 0;
borderTop = onBottom ? borderLeft : 0;
borderBottom = onBottom ? 0 : borderLeft;
updateItemsWithResizeEvent();
}
}
/**
* Returns true
if an image appears
* in unselected tabs.
*
* @return true
if an image appears in unselected tabs
*
* @since 1.3
*/
public boolean getUnselectedImageVisible() {
checkWidget();
return showUnselectedImage;
}
/**
* Specify whether the image appears on unselected tabs.
*
* @param visible true
makes the image appear
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*
* @since 1.3
*/
public void setUnselectedImageVisible( boolean visible ) {
checkWidget();
if( showUnselectedImage != visible ) {
showUnselectedImage = visible;
updateItems();
}
}
/**
* Returns true
if the close button appears
* when the user hovers over an unselected tabs.
*
* @return true
if the close button appears on unselected tabs
*/
public boolean getUnselectedCloseVisible() {
checkWidget();
return showUnselectedClose;
}
/**
* Specify whether the close button appears
* when the user hovers over an unselected tabs.
*
* @param visible true
makes the close button appear
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public void setUnselectedCloseVisible( boolean visible ) {
checkWidget();
if( showUnselectedClose != visible ) {
showUnselectedClose = visible;
updateItems();
}
}
@Override
public Rectangle computeTrim( int x, int y, int width, int height ) {
checkWidget();
int trimX = x - marginWidth - highlight_margin - borderLeft;
int trimWidth = width
+ borderLeft
+ borderRight
+ 2 * marginWidth
+ 2 * highlight_margin;
int trimY;
int trimHeight;
if( minimized ) {
trimY = onBottom
? y - borderTop
: y - highlight_header - tabHeight - borderTop;
trimHeight = borderTop + borderBottom + tabHeight + highlight_header;
} else {
trimY = onBottom
? y - marginHeight - highlight_margin - borderTop
: y - marginHeight - highlight_header - tabHeight - borderTop;
trimHeight = height
+ borderTop
+ borderBottom
+ 2 * marginHeight
+ tabHeight
+ highlight_header
+ highlight_margin;
}
return new Rectangle( trimX, trimY, trimWidth, trimHeight );
}
///////////////////
// Selection colors
/**
* Sets the receiver's selection background color to the color specified
* by the argument, or to the default system color for the control
* if the argument is null.
*
* @param color the new color (or null)
*
* @exception IllegalArgumentException
* - ERROR_INVALID_ARGUMENT - if the argument has been disposed
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public void setSelectionBackground( Color color ) {
checkWidget();
if( null != color && color.isDisposed() ) {
SWT.error( SWT.ERROR_INVALID_ARGUMENT );
}
selectionBackground = color;
}
/**
* Returns the receiver's selection background color.
*
* @return the selection background color of the receiver
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public Color getSelectionBackground() {
checkWidget();
Color result = selectionBackground;
if( result == null ) {
result = getThemeAdapter().getSelectedBackground();
}
if( result == null ) {
// Should never happen as the theming must prevent transparency for
// this color
throw new IllegalStateException( "Transparent selection background color" );
}
return result;
}
/**
* Specify a gradient of colours to be draw in the background of the selected tab.
* For example to draw a gradient that varies from dark blue to blue and then to
* white, use the following call to setBackground:
*
* cfolder.setBackground(new Color[]{display.getSystemColor(SWT.COLOR_DARK_BLUE),
* display.getSystemColor(SWT.COLOR_BLUE),
* display.getSystemColor(SWT.COLOR_WHITE),
* display.getSystemColor(SWT.COLOR_WHITE)},
* new int[] {25, 50, 100});
*
*
* @param colors an array of Color that specifies the colors to appear in the gradient
* in order of appearance left to right. The value null
clears the
* background gradient.
* @param percents an array of integers between 0 and 100 specifying the percent of the width
* of the widget at which the color should change. The size of the percents array must be one
* less than the size of the colors array.
*
* @exception SWTException
* - ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
* - ERROR_WIDGET_DISPOSED when the widget has been disposed
*
* @since 1.3
*/
public void setSelectionBackground( Color[] colors, int[] percents ) {
setSelectionBackground( colors, percents, false );
}
/**
* Specify a gradient of colours to be draw in the background of the selected tab.
* For example to draw a vertical gradient that varies from dark blue to blue and then to
* white, use the following call to setBackground:
*
* cfolder.setBackground(new Color[]{display.getSystemColor(SWT.COLOR_DARK_BLUE),
* display.getSystemColor(SWT.COLOR_BLUE),
* display.getSystemColor(SWT.COLOR_WHITE),
* display.getSystemColor(SWT.COLOR_WHITE)},
* new int[] {25, 50, 100}, true);
*
*
* @param colors an array of Color that specifies the colors to appear in the gradient
* in order of appearance top to bottom. The value null
clears the
* background gradient.
* @param percents an array of integers between 0 and 100 specifying the percent of the width
* of the widget at which the color should change. The size of the percents array must be one
* less than the size of the colors array.
*
* @param vertical indicate the direction of the gradient. True is vertical and false is horizontal.
*
* @exception IllegalArgumentException
* - ERROR_INVALID_ARGUMENT - if the argument has been disposed
*
* @exception SWTException
* - ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
* - ERROR_WIDGET_DISPOSED when the widget has been disposed
*
*
* @since 1.3
*/
public void setSelectionBackground( Color[] colors, int[] percents, boolean vertical ) {
checkWidget();
if( colors != null ) {
for( int i = 0; i < colors.length; i++ ) {
if( colors[ i ] != null && colors[ i ].isDisposed() ) {
SWT.error( SWT.ERROR_INVALID_ARGUMENT );
}
}
// The colors array can optionally have an extra entry which describes the
// highlight top color.
// Thus its either one or two larger than the percents array
if( percents == null
|| !( ( percents.length == colors.length - 1 )
|| ( percents.length == colors.length - 2 ) ) )
{
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
for( int i = 0; i < percents.length; i++ ) {
if( percents[ i ] < 0 || percents[ i ] > 100 ) {
SWT.error( SWT.ERROR_INVALID_ARGUMENT );
}
if( i > 0 && percents[ i ] < percents[ i - 1 ] ) {
SWT.error( SWT.ERROR_INVALID_ARGUMENT );
}
}
}
if( colors == null ) {
selectionGraphicsAdapter.setBackgroundGradient( null, null, vertical );
setSelectionBackground( ( Color )null );
} else {
int colorsLength = colors.length;
if( percents.length == colors.length - 2 ) {
colorsLength = colors.length - 1 ;
}
Color[] gradientColors = new Color[ colorsLength ];
System.arraycopy( colors, 0, gradientColors, 0, colorsLength );
int[] gradientPercents = new int[ gradientColors.length ];
if( gradientColors.length > 0 ) {
gradientPercents[ 0 ] = 0;
for( int i = 1; i < gradientPercents.length; i++ ) {
gradientPercents[ i ] = percents[ i - 1 ];
}
selectionGraphicsAdapter.setBackgroundGradient( gradientColors,
gradientPercents,
vertical );
setSelectionBackground( gradientColors[ gradientColors.length - 1 ] );
}
}
}
/**
* Set the image to be drawn in the background of the selected tab. Image
* is stretched or compressed to cover entire selection tab area.
*
* @param image the image to be drawn in the background
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
* @since 1.3
*/
public void setSelectionBackground( Image image ) {
checkWidget();
selectionBgImage = image;
}
/**
* Set the foreground color of the selected tab.
*
* @param color the color of the text displayed in the selected tab
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public void setSelectionForeground( Color color ) {
checkWidget();
selectionForeground = color;
}
/**
* Returns the receiver's selection foreground color.
*
* @return the selection foreground color of the receiver
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public Color getSelectionForeground() {
checkWidget();
Color result = selectionForeground;
if( result == null ) {
result = getThemeAdapter().getSelectedForeground();
}
if( result == null ) {
// Should never happen as the theming must prevent transparency for
// this color
throw new IllegalStateException( "Transparent selection foreground color" );
}
return result;
}
//////////////////////////////////
// Manipulation of topRight control
/**
* Set the control that appears in the top right corner of the tab folder.
* Typically this is a close button or a composite with a Menu and close button.
* The topRight control is optional. Setting the top right control to null will
* remove it from the tab folder.
*
* @param control the control to be displayed in the top right corner or null
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
* - ERROR_INVALID_ARGUMENT - if the control is not a child of this CTabFolder
*
*/
public void setTopRight( Control control ) {
checkWidget();
setTopRight( control, SWT.RIGHT );
}
/**
* Set the control that appears in the top right corner of the tab folder.
* Typically this is a close button or a composite with a Menu and close button.
* The topRight control is optional. Setting the top right control to null
* will remove it from the tab folder.
*
* The alignment parameter sets the layout of the control in the tab area.
* SWT.RIGHT
will cause the control to be positioned on the far
* right of the folder and it will have its default size. SWT.FILL
* will size the control to fill all the available space to the right of the
* last tab. If there is no available space, the control will not be visible.
*
*
* @param control the control to be displayed in the top right corner or null
* @param alignment SWT.RIGHT
or SWT.FILL
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
* - ERROR_INVALID_ARGUMENT - if the control is not a child of this CTabFolder
*
*/
public void setTopRight( Control control, int alignment ) {
checkWidget();
if( alignment != SWT.RIGHT && alignment != SWT.FILL ) {
SWT.error( SWT.ERROR_INVALID_ARGUMENT );
}
if( control != null && control.getParent() != this ) {
SWT.error( SWT.ERROR_INVALID_PARENT );
}
if( topRight != control || topRightAlignment != alignment ) {
topRight = control;
topRightAlignment = alignment;
if( updateItems() ) {
redraw();
}
}
}
/**
* Returns the control in the top right corner of the tab folder.
* Typically this is a close button or a composite with a menu and close button.
*
* @return the control in the top right corner of the tab folder or null
*
* @exception SWTException
* - ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
* - ERROR_WIDGET_DISPOSED when the widget has been disposed
*
*/
public Control getTopRight() {
checkWidget();
return topRight;
}
/**
* Returns the alignment of the top right control.
*
* @return the alignment of the top right control which is either
* SWT.RIGHT
or SWT.FILL
*
* @exception SWTException
* - ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
* - ERROR_WIDGET_DISPOSED when the widget has been disposed
*
*
* @since 1.3
*/
public int getTopRightAlignment() {
checkWidget();
return topRightAlignment;
}
///////////////////////////
// Adaptable implementation
@Override
@SuppressWarnings("unchecked")
public T getAdapter( Class adapter ) {
if( adapter == IItemHolderAdapter.class ) {
return ( T )itemHolder;
}
if( adapter == ICTabFolderAdapter.class ) {
if( tabFolderAdapter == null ) {
tabFolderAdapter = new CTabFolderAdapter();
}
return ( T )tabFolderAdapter;
}
if( adapter == WidgetLCA.class ) {
return ( T )CTabFolderLCA.INSTANCE;
}
return super.getAdapter( adapter );
}
////////////////////
// Control overrides
@Override
public void setFont( Font font ) {
checkWidget();
if( font != getFont() ) {
super.setFont( font );
if( !updateTabHeight( false ) ) {
updateItems();
}
}
}
@Override
public int getBorderWidth() {
checkWidget();
return 0;
}
//////////////////////
// Composite overrides
@Override
public Rectangle getClientArea() {
checkWidget();
Rectangle result;
if( minimized ) {
result = new Rectangle( xClient, yClient, 0, 0 );
} else {
Point size = getSize();
int width = size.x
- borderLeft
- borderRight
- 2 * marginWidth
- 2 * highlight_margin;
int height = size.y
- borderTop
- borderBottom
- 2 * marginHeight
- highlight_margin
- highlight_header;
height -= tabHeight;
result = new Rectangle( xClient, yClient, width, height );
}
return result;
}
///////////////////////////////////////
// Listener registration/deregistration
/**
* Adds the listener to receive events.
*
*
* @param listener the listener
*
* @exception IllegalArgumentException
* - ERROR_NULL_ARGUMENT - if the listener is null
*
* @exception SWTException
* - ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
* - ERROR_WIDGET_DISPOSED when the widget has been disposed
*
*/
public void addSelectionListener( SelectionListener listener ) {
checkWidget();
if( listener == null ) {
SWT.error( SWT.ERROR_NULL_ARGUMENT );
}
TypedListener typedListener = new TypedListener( listener );
addListener( SWT.Selection, typedListener );
addListener( SWT.DefaultSelection, typedListener );
}
/**
* Removes the listener.
*
* @param listener the listener
*
* @exception IllegalArgumentException
* - ERROR_NULL_ARGUMENT - if the listener is null
*
*
* @exception SWTException
* - ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
* - ERROR_WIDGET_DISPOSED when the widget has been disposed
*
*/
public void removeSelectionListener( SelectionListener listener ) {
checkWidget();
if( listener == null ) {
SWT.error( SWT.ERROR_NULL_ARGUMENT );
}
removeListener( SWT.Selection, listener );
removeListener( SWT.DefaultSelection, listener );
}
/**
*
* Adds the listener to the collection of listeners who will
* be notified when a tab item is closed, minimized, maximized,
* restored, or to show the list of items that are not
* currently visible.
*
* @param listener the listener which should be notified
*
* @exception IllegalArgumentException
* - ERROR_NULL_ARGUMENT - if the listener is null
*
*
* @exception SWTException
* - ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
* - ERROR_WIDGET_DISPOSED when the widget has been disposed
*
*
* @see CTabFolder2Listener
* @see #removeCTabFolder2Listener(CTabFolder2Listener)
*/
public void addCTabFolder2Listener( CTabFolder2Listener listener ) {
checkWidget();
if( listener == null ) {
SWT.error( SWT.ERROR_NULL_ARGUMENT );
}
TypedCTabFolderListener typedListener = new TypedCTabFolderListener( listener );
addListener( EventTypes.CTAB_FOLDER_MINIMIZE, typedListener );
addListener( EventTypes.CTAB_FOLDER_MAXIMIZE, typedListener );
addListener( EventTypes.CTAB_FOLDER_RESTORE, typedListener );
addListener( EventTypes.CTAB_FOLDER_CLOSE, typedListener );
addListener( EventTypes.CTAB_FOLDER_SHOW_LIST, typedListener );
}
/**
* Removes the listener.
*
* @param listener the listener
*
* @exception IllegalArgumentException
* - ERROR_NULL_ARGUMENT - if the listener is null
*
*
* @exception SWTException
* - ERROR_THREAD_INVALID_ACCESS when called from the wrong thread
* - ERROR_WIDGET_DISPOSED when the widget has been disposed
*
*
* @see #addCTabFolder2Listener(CTabFolder2Listener)
*/
public void removeCTabFolder2Listener( CTabFolder2Listener listener ) {
checkWidget();
if( listener == null ) {
SWT.error( SWT.ERROR_NULL_ARGUMENT );
}
removeListener( EventTypes.CTAB_FOLDER_MINIMIZE, listener );
removeListener( EventTypes.CTAB_FOLDER_MAXIMIZE, listener );
removeListener( EventTypes.CTAB_FOLDER_RESTORE, listener );
removeListener( EventTypes.CTAB_FOLDER_CLOSE, listener );
removeListener( EventTypes.CTAB_FOLDER_SHOW_LIST, listener );
}
///////////////////////////////////
// Helping methods to arrange items
boolean updateItems() {
return updateItems(selectedIndex);
}
boolean updateItems(int showIndex) {
CTabItem[] items = itemHolder.getItems();
if (!single && !mru && showIndex != -1) {
// make sure selected item will be showing
int firstIndex = showIndex;
if (priority[0] < showIndex) {
int maxWidth = getRightItemEdge() - borderLeft;
// if (!simple) maxWidth -= curveWidth - 2*curveIndent;
int width = 0;
int[] widths = new int[items.length];
// GC gc = new GC(this);
for (int i = priority[0]; i <= showIndex; i++) {
// widths[i] = items[i].preferredWidth(gc, i == selectedIndex, true);
widths[i] = items[i].preferredWidth(i == selectedIndex, true);
width += widths[i];
if (width > maxWidth) {
break;
}
}
if (width > maxWidth) {
width = 0;
for (int i = showIndex; i >= 0; i--) {
// if (widths[i] == 0) widths[i] = items[i].preferredWidth(gc, i == selectedIndex, true);
if (widths[i] == 0) {
widths[i] = items[i].preferredWidth(i == selectedIndex, true);
}
width += widths[i];
if (width > maxWidth) {
break;
}
firstIndex = i;
}
} else {
firstIndex = priority[0];
for (int i = showIndex + 1; i < items.length; i++) {
// widths[i] = items[i].preferredWidth(gc, i == selectedIndex, true);
widths[i] = items[i].preferredWidth(i == selectedIndex, true);
width += widths[i];
if (width >= maxWidth) {
break;
}
}
if (width < maxWidth) {
for (int i = priority[0] - 1; i >= 0; i--) {
// if (widths[i] == 0) widths[i] = items[i].preferredWidth(gc, i == selectedIndex, true);
if (widths[i] == 0) {
widths[i] = items[i].preferredWidth(i == selectedIndex, true);
}
width += widths[i];
if (width > maxWidth) {
break;
}
firstIndex = i;
}
}
}
// gc.dispose();
}
if (firstIndex != priority[0]) {
int index = 0;
for (int i = firstIndex; i < items.length; i++) {
priority[index++] = i;
}
for (int i = 0; i < firstIndex; i++) {
priority[index++] = i;
}
}
}
boolean oldShowChevron = showChevron;
boolean changed = setItemSize();
changed |= setItemLocation();
setButtonBounds();
changed |= showChevron != oldShowChevron;
// if (changed && getToolTipText() != null) {
// Point pt = getDisplay().getCursorLocation();
// pt = toControl(pt);
// _setToolTipText(pt.x, pt.y);
// }
redraw();
return changed;
}
boolean setItemLocation() {
CTabItem[] items = itemHolder.getItems();
boolean changed = false;
if( items.length == 0 ) {
return false;
}
Point size = getSize();
int y = onBottom
? Math.max( borderBottom, size.y - borderBottom - tabHeight )
: borderTop;
if( single ) {
int defaultX = getDisplay().getBounds().width + 10; // off screen
for( int i = 0; i < items.length; i++ ) {
CTabItem item = items[ i ];
if( i == selectedIndex ) {
firstIndex = selectedIndex;
int oldX = item.x, oldY = item.y;
item.x = borderLeft;
item.y = y;
item.showing = true;
if( showClose || item.showClose ) {
item.closeRect.x = borderLeft + getItemPaddingLeft( true );
item.closeRect.y = onBottom
? size.y
- borderBottom
- tabHeight
+ ( tabHeight - BUTTON_SIZE ) / 2
: borderTop + ( tabHeight - BUTTON_SIZE ) / 2;
}
if( item.x != oldX || item.y != oldY ) {
changed = true;
}
} else {
item.x = defaultX;
item.showing = false;
}
}
} else {
int rightItemEdge = getRightItemEdge();
int maxWidth = rightItemEdge - borderLeft;
int width = 0;
for( int i = 0; i < priority.length; i++ ) {
CTabItem item = items[ priority[ i ] ];
width += item.width;
item.showing = i == 0 ? true : item.width > 0 && width <= maxWidth;
// if (!simple && priority[i] == selectedIndex) width += curveWidth - 2*curveIndent;
}
int x = 0;
int defaultX = getDisplay().getBounds().width + 10; // off screen
firstIndex = items.length - 1;
for( int i = 0; i < items.length; i++ ) {
CTabItem item = items[ i ];
if( !item.showing ) {
if( item.x != defaultX ) {
changed = true;
}
item.x = defaultX;
} else {
firstIndex = Math.min( firstIndex, i );
if( item.x != x || item.y != y ) {
changed = true;
}
item.x = x;
item.y = y;
if( i == selectedIndex ) {
int edge = Math.min( item.x + item.width, rightItemEdge );
item.closeRect.x = edge - getItemPaddingRight( true ) - BUTTON_SIZE;
} else {
int rightPadding = getItemPaddingRight( false );
item.closeRect.x = item.x + item.width - rightPadding - BUTTON_SIZE;
}
item.closeRect.y = onBottom
? size.y
- borderBottom
- tabHeight
+ ( tabHeight - BUTTON_SIZE ) / 2
: borderTop + ( tabHeight - BUTTON_SIZE ) / 2;
x = x + item.width;
// if (!simple && i == selectedIndex) x += curveWidth - 2*curveIndent;
}
}
}
return changed;
}
boolean setItemSize() {
CTabItem[] items = itemHolder.getItems();
boolean changed = false;
if( isDisposed() ) {
return changed;
}
Point size = getSize();
if( size.x <= 0 || size.y <= 0 ) {
return changed;
}
// Note [rst] We have to substract the border here because on the client,
// the position 0,0 is not the origin of the border but the origin of the
// area inside the border.
xClient = borderLeft + marginWidth + highlight_margin;
if( onBottom ) {
yClient = borderTop + highlight_margin + marginHeight;
} else {
yClient = borderTop + tabHeight + highlight_header + marginHeight;
}
showChevron = false;
if( single ) {
showChevron = true;
if( selectedIndex != -1 ) {
CTabItem tab = items[ selectedIndex ];
// GC gc = new GC(this);
// int width = tab.preferredWidth(gc, true, false);
// gc.dispose();
int width = tab.preferredWidth( true, false );
width = Math.min( width, getRightItemEdge() - borderLeft );
if( tab.height != tabHeight || tab.width != width ) {
changed = true;
tab.shortenedText = null;
tab.shortenedTextWidth = 0;
tab.height = tabHeight;
tab.width = width;
tab.closeRect.width = tab.closeRect.height = 0;
if( showClose || tab.showClose ) {
tab.closeRect.width = BUTTON_SIZE;
tab.closeRect.height = BUTTON_SIZE;
}
}
}
return changed;
}
if (items.length == 0) {
return changed;
}
int[] widths;
// GC gc = new GC(this);
int tabAreaWidth = size.x - borderLeft - borderRight - 3;
if (showMin) {
tabAreaWidth -= BUTTON_SIZE;
}
if (showMax) {
tabAreaWidth -= BUTTON_SIZE;
}
if (topRightAlignment == SWT.RIGHT && topRight != null) {
Point rightSize = topRight.computeSize(SWT.DEFAULT, SWT.DEFAULT, false);
tabAreaWidth -= rightSize.x + 3;
}
// if (!simple) tabAreaWidth -= curveWidth - 2*curveIndent;
tabAreaWidth = Math.max(0, tabAreaWidth);
// First, try the minimum tab size at full compression.
int minWidth = 0;
int[] minWidths = new int[items.length];
for (int i = 0; i < priority.length; i++) {
int index = priority[i];
// minWidths[index] = items[index].preferredWidth(gc, index == selectedIndex, true);
minWidths[index] = items[index].preferredWidth(index == selectedIndex, true);
minWidth += minWidths[index];
if (minWidth > tabAreaWidth) {
break;
}
}
if (minWidth > tabAreaWidth) {
// full compression required and a chevron
showChevron = items.length > 1;
if (showChevron) {
tabAreaWidth -= 3*BUTTON_SIZE/2;
}
widths = minWidths;
int index = selectedIndex != -1 ? selectedIndex : 0;
if (tabAreaWidth < widths[index]) {
widths[index] = Math.max(0, tabAreaWidth);
}
} else {
int maxWidth = 0;
int[] maxWidths = new int[items.length];
for (int i = 0; i < items.length; i++) {
// maxWidths[i] = items[i].preferredWidth(gc, i == selectedIndex, false);
maxWidths[i] = items[i].preferredWidth(i == selectedIndex, false);
maxWidth += maxWidths[i];
}
if (maxWidth <= tabAreaWidth) {
// no compression required
widths = maxWidths;
} else {
// determine compression for each item
int extra = (tabAreaWidth - minWidth) / items.length;
while (true) {
int large = 0, totalWidth = 0;
for (int i = 0 ; i < items.length; i++) {
if (maxWidths[i] > minWidths[i] + extra) {
totalWidth += minWidths[i] + extra;
large++;
} else {
totalWidth += maxWidths[i];
}
}
if (totalWidth >= tabAreaWidth) {
extra--;
break;
}
if (large == 0 || tabAreaWidth - totalWidth < large) {
break;
}
extra++;
}
widths = new int[items.length];
for (int i = 0; i < items.length; i++) {
widths[i] = Math.min(maxWidths[i], minWidths[i] + extra);
}
}
}
// gc.dispose();
for (int i = 0; i < items.length; i++) {
CTabItem tab = items[i];
int width = widths[i];
if (tab.height != tabHeight || tab.width != width) {
changed = true;
tab.shortenedText = null;
tab.shortenedTextWidth = 0;
tab.height = tabHeight;
tab.width = width;
tab.closeRect.width = tab.closeRect.height = 0;
if (showClose || tab.showClose) {
if (i == selectedIndex || showUnselectedClose) {
tab.closeRect.width = BUTTON_SIZE;
tab.closeRect.height = BUTTON_SIZE;
}
}
}
}
return changed;
}
@SuppressWarnings("unused")
void setButtonBounds() {
CTabItem[] items = itemHolder.getItems();
Point size = getSize();
// int oldX, oldY, oldWidth, oldHeight;
// max button
// oldX = maxRect.x;
// oldY = maxRect.y;
// oldWidth = maxRect.width;
// oldHeight = maxRect.height;
maxRect.x = maxRect.y = maxRect.width = maxRect.height = 0;
if (showMax) {
maxRect.x = size.x - borderRight - BUTTON_SIZE - 3;
if (borderRight > 0) {
maxRect.x += 1;
}
maxRect.y = onBottom ? size.y - borderBottom - tabHeight + (tabHeight - BUTTON_SIZE)/2: borderTop + (tabHeight - BUTTON_SIZE)/2;
maxRect.width = BUTTON_SIZE;
maxRect.height = BUTTON_SIZE;
}
// if (oldX != maxRect.x || oldWidth != maxRect.width ||
// oldY != maxRect.y || oldHeight != maxRect.height) {
// int left = Math.min(oldX, maxRect.x);
// int right = Math.max(oldX + oldWidth, maxRect.x + maxRect.width);
// int top = onBottom ? size.y - borderBottom - tabHeight: borderTop + 1;
// redraw(left, top, right - left, tabHeight, false);
// }
// min button
// oldX = minRect.x;
// oldY = minRect.y;
// oldWidth = minRect.width;
// oldHeight = minRect.height;
minRect.x = minRect.y = minRect.width = minRect.height = 0;
if (showMin) {
minRect.x = size.x - borderRight - maxRect.width - BUTTON_SIZE - 3;
if (borderRight > 0) {
minRect.x += 1;
}
minRect.y = onBottom ? size.y - borderBottom - tabHeight + (tabHeight - BUTTON_SIZE)/2: borderTop + (tabHeight - BUTTON_SIZE)/2;
minRect.width = BUTTON_SIZE;
minRect.height = BUTTON_SIZE;
}
// if (oldX != minRect.x || oldWidth != minRect.width ||
// oldY != minRect.y || oldHeight != minRect.height) {
// int left = Math.min(oldX, minRect.x);
// int right = Math.max(oldX + oldWidth, minRect.x + minRect.width);
// int top = onBottom ? size.y - borderBottom - tabHeight: borderTop + 1;
// redraw(left, top, right - left, tabHeight, false);
// }
// top right control
// oldX = topRightRect.x;
// oldY = topRightRect.y;
// oldWidth = topRightRect.width;
// oldHeight = topRightRect.height;
topRightRect.x = topRightRect.y = topRightRect.width = topRightRect.height = 0;
if (topRight != null) {
switch (topRightAlignment) {
case SWT.FILL: {
int rightEdge = size.x - borderRight - 3 - maxRect.width - minRect.width;
if (!simple && borderRight > 0 && !showMax && !showMin) {
rightEdge -= 2;
}
if (single) {
if (items.length == 0 || selectedIndex == -1) {
topRightRect.x = borderLeft + 3;
topRightRect.width = rightEdge - topRightRect.x;
} else {
// fill size is 0 if item compressed
CTabItem item = items[selectedIndex];
if (item.x + item.width + 7 + 3*BUTTON_SIZE/2 >= rightEdge) {
break;
}
topRightRect.x = item.x + item.width + 7 + 3*BUTTON_SIZE/2;
topRightRect.width = rightEdge - topRightRect.x;
}
} else {
// fill size is 0 if chevron showing
if (showChevron) {
break;
}
if (items.length == 0) {
topRightRect.x = borderLeft + 3;
} else {
CTabItem item = items[items.length - 1];
topRightRect.x = item.x + item.width;
// if (!simple && items.length - 1 == selectedIndex) topRightRect.x += curveWidth - curveIndent;
}
topRightRect.width = Math.max(0, rightEdge - topRightRect.x);
}
topRightRect.y = onBottom ? size.y - borderBottom - tabHeight: borderTop + 1;
topRightRect.height = tabHeight - 1;
break;
}
case SWT.RIGHT: {
Point topRightSize = topRight.computeSize(SWT.DEFAULT, tabHeight, false);
int rightEdge = size.x - borderRight - 3 - maxRect.width - minRect.width;
if (!simple && borderRight > 0 && !showMax && !showMin) {
rightEdge -= 2;
}
topRightRect.x = rightEdge - topRightSize.x;
topRightRect.width = topRightSize.x;
topRightRect.y = onBottom ? size.y - borderBottom - tabHeight: borderTop + 1;
topRightRect.height = tabHeight - 1;
}
}
topRight.setBounds(topRightRect);
}
// if (oldX != topRightRect.x || oldWidth != topRightRect.width ||
// oldY != topRightRect.y || oldHeight != topRightRect.height) {
// int left = Math.min(oldX, topRightRect.x);
// int right = Math.max(oldX + oldWidth, topRightRect.x + topRightRect.width);
// int top = onBottom ? size.y - borderBottom - tabHeight : borderTop + 1;
// redraw(left, top, right - left, tabHeight, false);
// }
// chevron button
// oldX = chevronRect.x;
// oldY = chevronRect.y;
// oldWidth = chevronRect.width;
// oldHeight = chevronRect.height;
chevronRect.x = chevronRect.y = chevronRect.height = chevronRect.width = 0;
if (single) {
if (selectedIndex == -1 || items.length > 1) {
chevronRect.width = 3*BUTTON_SIZE/2;
chevronRect.height = BUTTON_SIZE;
chevronRect.y = onBottom ? size.y - borderBottom - tabHeight + (tabHeight - chevronRect.height)/2 : borderTop + (tabHeight - chevronRect.height)/2;
if (selectedIndex == -1) {
chevronRect.x = size.x - borderRight - 3 - minRect.width - maxRect.width - topRightRect.width - chevronRect.width;
} else {
CTabItem item = items[selectedIndex];
int w = size.x - borderRight - 3 - minRect.width - maxRect.width - chevronRect.width;
if (topRightRect.width > 0) {
w -= topRightRect.width + 3;
}
chevronRect.x = Math.min(item.x + item.width + 3, w);
}
if (borderRight > 0) {
chevronRect.x += 1;
}
}
} else {
if (showChevron) {
chevronRect.width = 3*BUTTON_SIZE/2;
chevronRect.height = BUTTON_SIZE;
int i = 0, lastIndex = -1;
while (i < priority.length && items[priority[i]].showing) {
lastIndex = Math.max(lastIndex, priority[i++]);
}
if (lastIndex == -1) {
lastIndex = firstIndex;
}
CTabItem lastItem = items[lastIndex];
int w = lastItem.x + lastItem.width + 3;
// if (!simple && lastIndex == selectedIndex) w += curveWidth - 2*curveIndent;
chevronRect.x = Math.min(w, getRightItemEdge());
chevronRect.y = onBottom ? size.y - borderBottom - tabHeight + (tabHeight - chevronRect.height)/2 : borderTop + (tabHeight - chevronRect.height)/2;
}
}
// if (oldX != chevronRect.x || oldWidth != chevronRect.width ||
// oldY != chevronRect.y || oldHeight != chevronRect.height) {
// int left = Math.min(oldX, chevronRect.x);
// int right = Math.max(oldX + oldWidth, chevronRect.x + chevronRect.width);
// int top = onBottom ? size.y - borderBottom - tabHeight: borderTop + 1;
// redraw(left, top, right - left, tabHeight, false);
// }
}
boolean updateTabHeight(boolean force){
CTabItem[] items = itemHolder.getItems();
int style = getStyle();
if (fixedTabHeight == 0 && (style & SWT.FLAT) != 0 && (style & SWT.BORDER) == 0) {
highlight_header = 0;
}
int oldHeight = tabHeight;
if (fixedTabHeight != SWT.DEFAULT) {
tabHeight = fixedTabHeight == 0 ? 0 : fixedTabHeight + 1; // +1 for line drawn across top of tab
} else {
int tempHeight = 0;
// GC gc = new GC(this);
if (items.length == 0) {
// tempHeight = gc.textExtent("Default", CTabItem.FLAGS).y + CTabItem.TOP_MARGIN + CTabItem.BOTTOM_MARGIN; //$NON-NLS-1$
BoxDimensions padding = getItemPadding( false );
tempHeight = TextSizeUtil.getCharHeight( getFont() ) + padding.top + padding.bottom;
} else {
for (int i=0; i < items.length; i++) {
// tempHeight = Math.max(tempHeight, items[i].preferredHeight(gc));
tempHeight = Math.max(tempHeight, items[i].preferredHeight(i==selectedIndex));
}
}
// gc.dispose();
tabHeight = tempHeight;
}
if (!force && tabHeight == oldHeight) {
return false;
}
// oldSize = null;
// if (onBottom) {
// int d = tabHeight - 12;
// curve = new int[]{0,13+d, 0,12+d, 2,12+d, 3,11+d, 5,11+d, 6,10+d, 7,10+d, 9,8+d, 10,8+d,
// 11,7+d, 11+d,7,
// 12+d,6, 13+d,6, 15+d,4, 16+d,4, 17+d,3, 19+d,3, 20+d,2, 22+d,2, 23+d,1};
// curveWidth = 26+d;
// curveIndent = curveWidth/3;
// } else {
// int d = tabHeight - 12;
// curve = new int[]{0,0, 0,1, 2,1, 3,2, 5,2, 6,3, 7,3, 9,5, 10,5,
// 11,6, 11+d,6+d,
// 12+d,7+d, 13+d,7+d, 15+d,9+d, 16+d,9+d, 17+d,10+d, 19+d,10+d, 20+d,11+d, 22+d,11+d, 23+d,12+d};
// curveWidth = 26+d;
// curveIndent = curveWidth/3;
//
// //this could be static but since values depend on curve, better to keep in one place
// topCurveHighlightStart = new int[] {
// 0, 2, 1, 2, 2, 2,
// 3, 3, 4, 3, 5, 3,
// 6, 4, 7, 4,
// 8, 5,
// 9, 6, 10, 6};
//
// //also, by adding in 'd' here we save some math cost when drawing the curve
// topCurveHighlightEnd = new int[] {
// 10+d, 6+d,
// 11+d, 7+d,
// 12+d, 8+d, 13+d, 8+d,
// 14+d, 9+d,
// 15+d, 10+d, 16+d, 10+d,
// 17+d, 11+d, 18+d, 11+d, 19+d, 11+d,
// 20+d, 12+d, 21+d, 12+d, 22+d, 12+d };
// }
notifyListeners(SWT.Resize, new Event());
return true;
}
int getRightItemEdge (){
int x = getSize().x - borderRight - 3;
if (showMin) {
x -= BUTTON_SIZE;
}
if (showMax) {
x -= BUTTON_SIZE;
}
if (showChevron) {
x -= 3*BUTTON_SIZE/2;
}
if (topRight != null && topRightAlignment != SWT.FILL) {
Point rightSize = topRight.computeSize(SWT.DEFAULT, SWT.DEFAULT);
x -= rightSize.x + 3;
}
return Math.max(0, x);
}
private void updateItemsWithResizeEvent() {
Rectangle rectBefore = getClientArea();
updateItems();
Rectangle rectAfter = getClientArea();
if( !rectBefore.equals( rectAfter ) ) {
notifyListeners( SWT.Resize, new Event() );
}
}
void onResize() {
// if (updateItems()) redrawTabs();
updateItems();
// Point size = getSize();
// if (oldSize == null) {
// redraw();
// } else {
// if (onBottom && size.y != oldSize.y) {
// redraw();
// } else {
// int x1 = Math.min(size.x, oldSize.x);
// if (size.x != oldSize.x) x1 -= borderRight + highlight_margin + 2;
// if (!simple) x1 -= 5; // rounded top right corner
// int y1 = Math.min(size.y, oldSize.y);
// if (size.y != oldSize.y) y1 -= borderBottom + highlight_margin;
// int x2 = Math.max(size.x, oldSize.x);
// int y2 = Math.max(size.y, oldSize.y);
// redraw(0, y1, x2, y2 - y1, false);
// redraw(x1, 0, x2 - x1, y2, false);
// }
// }
// oldSize = size;
// Differs from SWT code: adjust bounds of the selected items' control
if( selectedIndex != -1 ) {
CTabItem item = itemHolder.getItem( selectedIndex );
Control control = item.getControl();
if( control != null && !control.isDisposed() ) {
control.setBounds( getClientArea() );
}
}
}
///////////
// Disposal
void onDispose() {
/*
* Usually when an item is disposed of, destroyItem will change the size of
* the items array, reset the bounds of all the tabs and manage the widget
* associated with the tab. Since the whole folder is being disposed, this
* is not necessary. For speed the inDispose flag is used to skip over this
* part of the item dispose.
*/
inDispose = true;
removeControlListener( resizeListener );
unregisterFocusListener();
if( showMenu != null && !showMenu.isDisposed() ) {
showMenu.dispose();
showMenu = null;
}
while( itemHolder.size() > 0 ) {
CTabItem item = itemHolder.getItem( 0 );
item.dispose();
itemHolder.remove( item );
}
}
//////////////////
// Helping methods
private static int checkStyle( int style ) {
int mask
= SWT.CLOSE
| SWT.TOP
| SWT.BOTTOM
| SWT.FLAT
| SWT.LEFT_TO_RIGHT
// | SWT.RIGHT_TO_LEFT
| SWT.SINGLE
| SWT.MULTI;
int result = style & mask;
// TOP and BOTTOM are mutually exclusive, TOP is the default
if( ( result & SWT.TOP ) != 0 ) {
result = result & ~SWT.BOTTOM;
}
// SINGLE and MULTI are mutually exclusive, MULTI is the default
if( ( result & SWT.MULTI ) != 0 ) {
result = result & ~SWT.SINGLE;
}
return result;
}
private void registerDisposeListener() {
addDisposeListener( new DisposeListener() {
@Override
public void widgetDisposed( DisposeEvent event ) {
onDispose();
CTabFolder.this.removeDisposeListener( this );
}
} );
}
private void registerFocusListener() {
if( focusListener == null ) {
focusListener = new FocusListener() {
@Override
public void focusGained( FocusEvent event ) {
onFocus();
}
@Override
public void focusLost( FocusEvent event ) {
onFocus();
}
};
addFocusListener( focusListener );
}
}
private void onFocus() {
if( selectedIndex < 0 ) {
setSelection( 0, true );
}
unregisterFocusListener();
}
private void unregisterFocusListener() {
if( focusListener != null ) {
addFocusListener( focusListener );
focusListener = null;
}
}
private void showListMenu() {
CTabItem[] items = getItems();
if( items.length == 0 || !showChevron ) {
return;
}
if( showMenu == null || showMenu.isDisposed() ) {
showMenu = new Menu( this );
} else {
// TODO [rh] optimize: reuse existing menuItems if possible
MenuItem[] menuItems = showMenu.getItems();
for( int i = 0; i < menuItems.length; i++ ) {
menuItems[ i ].dispose();
}
}
showMenu.setOrientation( getOrientation() );
final String id = "CTabFolder_showList_Index"; //$NON-NLS-1$
for( int i = 0; i < items.length; i++ ) {
CTabItem tab = items[ i ];
if( !tab.showing ) {
MenuItem item = new MenuItem( showMenu, SWT.NONE );
item.setText( tab.getText() );
item.setImage( tab.getImage() );
item.setData( id, tab );
item.addSelectionListener( new SelectionAdapter() {
@Override
public void widgetSelected( SelectionEvent event ) {
MenuItem menuItem = ( MenuItem )event.getSource();
int index = indexOf( ( CTabItem )menuItem.getData( id ) );
setSelection( index, true );
}
} );
}
}
// show menu if it contains any item
if( showMenu.getItemCount() > 0 ) {
int x = chevronRect.x;
int y = chevronRect.y + chevronRect.height + 1;
Point location = getDisplay().map( this, null, x, y );
showMenu.setLocation( location.x, location.y );
showMenu.setVisible( true );
}
}
private void setSelection( int index, boolean notify ) {
int oldSelectedIndex = selectedIndex;
setSelection( index );
if( notify && selectedIndex != oldSelectedIndex && selectedIndex != -1 ) {
Event event = new Event();
event.item = getSelection();
notifyListeners( SWT.Selection, event );
}
}
void createItem( CTabItem item, int index ) {
itemHolder.insert( item, index );
if( selectedIndex >= index ) {
selectedIndex++;
}
int[] newPriority = new int[ priority.length + 1 ];
int next = 0, priorityIndex = priority.length;
for( int i = 0; i < priority.length; i++ ) {
if( !mru && priority[ i ] == index ) {
priorityIndex = next++;
}
newPriority[ next++ ] = priority[ i ] >= index
? priority[ i ] + 1
: priority[ i ];
}
newPriority[ priorityIndex ] = index;
priority = newPriority;
updateItems();
if (getItemCount() == 1) {
registerFocusListener(); // RWT specific
if (!updateTabHeight(false)) {
updateItems();
}
redraw();
} else {
updateItems();
// redrawTabs();
redraw();
}
}
void destroyItem( CTabItem item ) {
int index = indexOf( item );
if( !inDispose && index != -1 ) {
CTabItem[] items = getItems();
if( items.length == 1 ) {
itemHolder.remove( item );
priority = new int[ 0 ];
firstIndex = -1;
selectedIndex = -1;
Control control = item.getControl();
if( control != null && !control.isDisposed() ) {
control.setVisible( false );
}
setToolTipText( null );
setButtonBounds();
} else {
itemHolder.remove( item );
int[] newPriority = new int[ priority.length - 1 ];
int next = 0;
for( int i = 0; i < priority.length; i++ ) {
if( priority[ i ] == index ) {
continue;
}
newPriority[ next++ ] = priority[ i ] > index
? priority[ i ] - 1
: priority[ i ];
}
priority = newPriority;
// move the selection if this item is selected
if( selectedIndex == index ) {
Control control = item.getControl();
selectedIndex = -1;
int nextSelection = mru ? priority[ 0 ] : Math.max( 0, index - 1 );
setSelection( nextSelection, true );
if( control != null && !control.isDisposed() ) {
control.setVisible( false );
}
} else if( selectedIndex > index ) {
selectedIndex--;
}
}
updateItems();
if( getItemCount() == 0 ) {
unregisterFocusListener();
}
}
}
//////////////////
// Theming related
int getItemPaddingLeft( boolean selected ) {
return getItemPadding( selected ).left;
}
int getItemPaddingRight( boolean selected ) {
return getItemPadding( selected ).right;
}
BoxDimensions getItemPadding( boolean selected ) {
return getThemeAdapter().getItemPadding( selected );
}
int getItemSpacing( boolean selected ) {
return getThemeAdapter().getItemSpacing( selected );
}
Font getItemFont( boolean selected ) {
return getThemeAdapter().getItemFont( selected );
}
private CTabFolderThemeAdapter getThemeAdapter() {
return ( CTabFolderThemeAdapter )getAdapter( ThemeAdapter.class );
}
///////////////////
// Skinning support
@Override
public void reskin( int flags ) {
super.reskin( flags );
CTabItem[] items = getItems();
for( int i = 0; i < items.length; i++ ) {
items[ i ].reskin( flags );
}
}
////////////////
// Inner classes
private final class CTabFolderAdapter implements ICTabFolderAdapter {
@Override
public Rectangle getChevronRect() {
Rectangle rect = chevronRect;
return new Rectangle( rect.x, rect.y, rect.width, rect.height );
}
@Override
public boolean getChevronVisible() {
return showChevron;
}
@Override
public Rectangle getMinimizeRect() {
Rectangle rect = minRect;
return new Rectangle( rect.x, rect.y, rect.width, rect.height );
}
@Override
public Rectangle getMaximizeRect() {
Rectangle rect = maxRect;
return new Rectangle( rect.x, rect.y, rect.width, rect.height );
}
@Override
public void showListMenu() {
CTabFolder.this.showListMenu();
}
@Override
public boolean showItemImage( CTabItem item ) {
return item.showImage();
}
@Override
public boolean showItemClose( CTabItem item ) {
return item.parent.showClose || item.showClose;
}
@Override
public String getShortenedItemText( CTabItem item ) {
return item.getShortenedText( item.getParent().getSelection() == item );
}
@Override
public Color getUserSelectionForeground() {
return selectionForeground;
}
@Override
public Color getUserSelectionBackground() {
return selectionBackground;
}
@Override
public Image getUserSelectionBackgroundImage() {
return selectionBgImage;
}
@Override
public IWidgetGraphicsAdapter getUserSelectionBackgroundGradient() {
return selectionGraphicsAdapter;
}
@Override
public void doRedraw() {
setButtonBounds();
}
}
}