/*******************************************************************************
* Copyright (C) 2011 Angelo Zerr <angelo.zerr@gmail.com>, Pascal Leclercq <pascal.leclercq@gmail.com>
* 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:
* Angelo ZERR - initial API and implementation
* Pascal Leclercq - initial API and implementation
*******************************************************************************/
package org.eclipse.nebula.widgets.pagination.renderers.navigation.graphics;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import org.eclipse.nebula.widgets.pagination.PaginationHelper;
import org.eclipse.nebula.widgets.pagination.Resources;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
/**
* This canvas draw navigation page with {@link GC} like this :
*
* <pre>
* Previous 1 2 ...10 Next
* </pre>
*
*/
public class NavigationPageGraphics extends Canvas {
private List<NavigationPageGraphicsItem> items;
private NavigationPageGraphicsItem selectedItem;
private Integer round = null;
private Color selectedItemForeground;
private Color selectedItemBackground;
private Color selectedItemBorderColor;
private Color itemForeground;
private Color itemBackground;
private Color itemBorderColor;
private Color disabledItemForeground;
private Color disabledItemBackground;
private Color disabledItemBorderColor;
private Integer totalWidth;
private final NavigationPageGraphicsItem previousItem;
private final NavigationPageGraphicsItem nextItem;
public NavigationPageGraphics(Composite parent, int style) {
this(parent, style, BlueNavigationPageGraphicsConfigurator
.getInstance());
}
public NavigationPageGraphics(Composite parent, int style,
INavigationPageGraphicsConfigurator configurator) {
super(parent, style);
// Create previous+next item.
this.previousItem = new NavigationPageGraphicsItem(this,
NavigationPageGraphicsItem.PREVIOUS);
previousItem.setText(Resources.getText(
Resources.PaginationRenderer_previous, Locale.getDefault()));
this.nextItem = new NavigationPageGraphicsItem(this,
NavigationPageGraphicsItem.NEXT);
nextItem.setText(Resources.getText(Resources.PaginationRenderer_next,
Locale.getDefault()));
// Add paint listener to draw the navigation page
this.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
onPaint(e.gc);
}
});
// Add mouse listener to select a page item.
this.addMouseListener(new MouseListener() {
public void mouseUp(MouseEvent e) {
NavigationPageGraphicsItem selectedItem = getItem(e.x, e.y);
if (selectedItem != null) {
select(selectedItem);
}
}
public void mouseDown(MouseEvent e) {
}
public void mouseDoubleClick(MouseEvent arg0) {
}
});
if (configurator != null) {
configurator.configure(this);
}
}
private void onPaint(GC gc) {
gc.setAdvanced(true);
if (gc.getAdvanced())
gc.setTextAntialias(SWT.ON);
if (items == null) {
return;
}
computeBoundsIfNeeded(gc);
Color fg = getDisplay().getSystemColor(SWT.COLOR_WIDGET_FOREGROUND);
Color bg = getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);
boolean separator = false;
int x, y, width, height = 0;
boolean selected = false;
boolean enabled = false;
for (NavigationPageGraphicsItem pageItem : items) {
selected = pageItem.equals(selectedItem);
enabled = pageItem.isEnabled();
separator = pageItem.isSeparator();
x = pageItem.getBounds().x;
y = pageItem.getBounds().y;
width = pageItem.getBounds().width;
height = pageItem.getBounds().height;
// Fill rectangle
Color filledRectangleColor = getFilledRectangleColor(selected,
!separator ? enabled : true, bg);
if (filledRectangleColor != null) {
gc.setBackground(filledRectangleColor);
if (round != null) {
gc.fillRoundRectangle(x, y, width, height, round, round);
} else {
gc.fillRectangle(x, y, width, height);
}
}
// Border rectangle
if (!separator) {
Color borderRectangleColor = getBorderRectangleColor(selected,
enabled, bg);
if (borderRectangleColor != null) {
gc.setForeground(borderRectangleColor);
if (round != null) {
gc.drawRoundRectangle(x, y, width, height, round, round);
} else {
gc.drawRectangle(x, y, width, height);
}
}
}
// Foreground text
Color textColor = getTextColor(selected, enabled);
if (textColor != null) {
gc.setForeground(textColor);
} else {
gc.setForeground(fg);
}
gc.drawString(pageItem.getText(), x + 3, y, true);
}
}
private Color getFilledRectangleColor(boolean selected, boolean enabled,
Color bg) {
if (selected) {
return selectedItemBackground;
}
if (!enabled) {
return disabledItemBackground;
}
return itemBackground;
}
private Color getBorderRectangleColor(boolean selected, boolean enabled,
Color bg) {
if (selected) {
return selectedItemBorderColor;
}
if (!enabled) {
return disabledItemBorderColor;
}
return itemBorderColor;
}
private Color getTextColor(boolean selected, boolean enabled) {
if (selected) {
return selectedItemForeground;
}
if (!enabled) {
return disabledItemForeground;
}
return itemForeground;
}
public void update(int[] pageIndexes, int currentPage) {
update(pageIndexes, currentPage, Locale.getDefault());
}
public void update(int[] pageIndexes, int currentPage, Locale locale) {
// Compute navigation item and updat ethe selected item.
this.items = new ArrayList<NavigationPageGraphicsItem>(
pageIndexes.length + 2);
int index = -1;
items.add(previousItem);
NavigationPageGraphicsItem item = null;
for (int i = 0; i < pageIndexes.length; i++) {
index = pageIndexes[i];
item = new NavigationPageGraphicsItem(this, index);
if (index==PaginationHelper.SEPARATOR) {
item.setText(Resources.getText(Resources.PaginationRenderer_separator, locale));
}
items.add(item);
if (currentPage == index) {
selectedItem = item;
}
}
items.add(nextItem);
// bounds must be recomputed.
this.totalWidth = null;
redraw();
}
@Override
public Point computeSize(int wHint, int hHint, boolean changed) {
checkWidget();
if (wHint == SWT.DEFAULT || hHint == SWT.DEFAULT) {
computeBoundsIfNeeded(null);
if (totalWidth != null) {
return new Point(totalWidth, 15);
}
return new Point(wHint, 15);
}
return super.computeSize(wHint, hHint, changed);
}
/**
* This method loop for item and update for each item their bound.
*
* @param gc
* graphic context used to compute the size font used in page
* item. If GC is null, a new GC is created
*/
private void computeBoundsIfNeeded(GC gc) {
if (items == null || totalWidth != null) {
return;
}
GC tempGC = null;
if (gc == null) {
// GC null, create temporary GC
tempGC = new GC(this);
gc = tempGC;
}
this.totalWidth = 0;
int x = 0;
int y = 0;
int width = 0;
int height = 0;
String text = null;
// Loop for each page item.
for (NavigationPageGraphicsItem pageItem : items) {
text = pageItem.getText();
// Get the size of the text of the current item.
Point size = gc.stringExtent(text);
width = size.x + 4;
height = size.y;
pageItem.setBounds(new Rectangle(x, y, width, height));
x += width + 3;
}
// Updat ethe total width of this control
totalWidth = x + width - 3;
if (tempGC != null) {
// Dispose temporary GC.
tempGC.dispose();
}
}
// NavigationPageGraphicsItem getItem(int index) {
// for (NavigationPageGraphicsItem pageItem : pageItems) {
// if (pageItem.getIndex() == index) {
// return pageItem;
// }
// }
// return null;
// }
/**
* Returns the item which match the given location point.Null if none item
* is selected or if item is disabled.
*
* @param x
* @param y
* @return
*/
private NavigationPageGraphicsItem getItem(int x, int y) {
checkWidget();
if (items == null) {
return null;
}
for (NavigationPageGraphicsItem pageItem : items) {
if (pageItem.contains(x, y)) {
// an item is selected
if (!pageItem.isEnabled()) {
// item is not enable, return null.
return null;
}
// return the selected item.
return pageItem;
}
}
return null;
}
public void select(NavigationPageGraphicsItem pageItem) {
if (!pageItem.isSeparator()) {
// item selected is not the item '...'
selectedItem = pageItem;
redraw();
getDisplay().update();
}
this.handleSelection(pageItem);
}
/**
* This method is called when page item (Next, Previous or page index) is
* selected. By default this method do nothing.
*
* @param selectedItem
*/
protected void handleSelection(NavigationPageGraphicsItem selectedItem) {
// Do nothing.
}
public void setSelectedItemBackground(Color selectedItemBackground) {
this.selectedItemBackground = selectedItemBackground;
}
public Color getSelectedItemBackground() {
return selectedItemBackground;
}
public void setSelectedItemForeground(Color selectedItemForeground) {
this.selectedItemForeground = selectedItemForeground;
}
public Color getSelectedItemForeground() {
return selectedItemForeground;
}
public Color getItemForeground() {
return itemForeground;
}
public void setItemForeground(Color itemForeground) {
this.itemForeground = itemForeground;
}
public Color getItemBackground() {
return itemBackground;
}
public void setItemBackground(Color itemBackground) {
this.itemBackground = itemBackground;
}
public Color getItemBorderColor() {
return itemBorderColor;
}
public void setItemBorderColor(Color itemBorderColor) {
this.itemBorderColor = itemBorderColor;
}
public Color getSelectedItemBorderColor() {
return selectedItemBorderColor;
}
public void setSelectedItemBorderColor(Color selectedItemBorderColor) {
this.selectedItemBorderColor = selectedItemBorderColor;
}
public Color getDisabledItemForeground() {
return disabledItemForeground;
}
public void setDisabledItemForeground(Color disabledItemForeground) {
this.disabledItemForeground = disabledItemForeground;
}
public Color getDisabledItemBorderColor() {
return disabledItemBorderColor;
}
public void setDisabledItemBorderColor(Color disabledItemBorderColor) {
this.disabledItemBorderColor = disabledItemBorderColor;
}
public void setDisabledItemBackground(Color disabledItemBackground) {
this.disabledItemBackground = disabledItemBackground;
}
public Color getDisabledItemBackground() {
return disabledItemBackground;
}
public void setConfigurator(INavigationPageGraphicsConfigurator configurator) {
this.round = null;
configurator.configure(this);
redraw();
}
/**
* Set the round height/width.
*
* @param round
*/
public void setRound(int round) {
this.round = round;
}
/**
* Set text for previous, next item.
*
* @param previousText
* @param nextText
*/
public void setText(String previousText, String nextText) {
previousItem.setText(previousText);
nextItem.setText(nextText);
this.totalWidth = null;
redraw();
}
/**
* Set enabled for previous, next item.
*
* @param hasPreviousPage
* @param hasNextPage
*/
public void setEnabled(boolean hasPreviousPage, boolean hasNextPage) {
previousItem.setEnabled(hasPreviousPage);
nextItem.setEnabled(hasNextPage);
redraw();
}
}