package ppj09.gwt.swapweb.client.gui;
/*
RateIt Widget for GWT
Copyright (C) 2006 Alexei Sokolov http://gwt.components.googlepages.com/
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.ChangeListener;
import com.google.gwt.user.client.ui.ChangeListenerCollection;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FocusPanel;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.KeyboardListener;
import com.google.gwt.user.client.ui.KeyboardListenerAdapter;
import com.google.gwt.user.client.ui.MouseListenerAdapter;
import com.google.gwt.user.client.ui.SourcesChangeEvents;
import com.google.gwt.user.client.ui.Widget;
public class RateItWidget extends Composite implements SourcesChangeEvents {
private static class RatePanel extends Image {
private int rating;
public RatePanel(int rating, Image anotherImage) {
super(anotherImage.getUrl());
this.rating = rating;
}
public int getRating() {
return rating;
}
public void replaceImage(Image newWidget) {
this.setUrl(newWidget.getUrl());
}
}
private static class CellMouseListener extends MouseListenerAdapter {
private RateItWidget rateItWidget;
public CellMouseListener(RateItWidget rateItWidget) {
this.rateItWidget = rateItWidget;
}
public void onMouseEnter(Widget sender) {
rateItWidget.drawRating(((RatePanel) sender).getRating());
}
}
private static class CellClickListener implements ClickListener {
private RateItWidget rateItWidget;
public CellClickListener(RateItWidget rateItWidget) {
this.rateItWidget = rateItWidget;
}
public void onClick(Widget sender) {
rateItWidget.setUserRating(((RatePanel) sender).getRating(), true);
}
}
private Grid grid;
private Image normalImage;
private Image normalZeroImage;
private Image ratedImage;
private Image ratedZeroImage;
private Image[] ratingImages;
private int userRating;
private ChangeListenerCollection changeListeners;
private boolean rated = false;
private double rating;
private CellMouseListener cellMouseListener = new CellMouseListener(this);
private CellClickListener cellClickListener = new CellClickListener(this);
public RateItWidget(double rating, int maxRating, Image normalImage,
Image ratedImage, Image normalZeroImage, Image ratedZeroImage,
Image ratingImage) {
this(rating, maxRating, normalImage, ratedImage, normalZeroImage,
ratedZeroImage, new Image[] { ratingImage });
}
public RateItWidget(double rating, int maxRating, Image normalImage,
Image ratedImage, Image normalZeroImage, Image ratedZeroImage,
Image[] ratingImages) {
FocusPanel panel = new FocusPanel();
panel.addMouseListener(new MouseListenerAdapter() {
public void onMouseLeave(Widget sender) {
if (isRated()) {
drawRating(getUserRating());
} else {
setup();
}
}
});
panel.addKeyboardListener(new KeyboardListenerAdapter() {
public void onKeyUp(Widget sender, char keyCode, int modifiers) {
if (keyCode == KeyboardListener.KEY_RIGHT) {
RateItWidget.this.setUserRating(
RateItWidget.this.getUserRating() + 1, true);
} else if (keyCode == KeyboardListener.KEY_LEFT) {
RateItWidget.this.setUserRating(
RateItWidget.this.getUserRating() - 1, true);
} else if (keyCode >= '0' && keyCode <= '9') {
RateItWidget.this.setUserRating(keyCode - '0', true);
}
}
});
grid = new Grid(1, maxRating + 1) {
public boolean clearCell(int row, int column) {
boolean retValue = super.clearCell(row, column);
Element td = getCellFormatter().getElement(row, column);
DOM.setInnerHTML(td, "");
return retValue;
}
};
grid.setCellSpacing(0);
grid.setCellPadding(0);
this.normalImage = normalImage;
this.ratedImage = ratedImage;
this.normalZeroImage = normalZeroImage;
this.ratedZeroImage = ratedZeroImage;
this.ratingImages = ratingImages;
this.rating = rating;
this.userRating = 0;
setup();
panel.add(grid);
setWidget(panel);
setStyleName("RateItWidget");
}
public void setUserRating(int rating) {
setUserRating(rating, false);
}
public int getUserRating() {
return userRating;
}
public boolean isRated() {
return rated;
}
public double getRating() {
return rating;
}
public void setRating(double rating) {
this.rating = rating;
if (!isRated()) {
setup();
}
}
public void addChangeListener(ChangeListener listener) {
if (changeListeners == null) {
changeListeners = new ChangeListenerCollection();
}
changeListeners.add(listener);
}
public void removeChangeListener(ChangeListener listener) {
if (changeListeners != null) {
changeListeners.remove(listener);
}
}
protected void setUserRating(int rating, boolean fireEvents) {
if (rating < 0 || rating >= grid.getColumnCount()) {
return;
}
this.userRating = rating;
drawRating(userRating);
if (fireEvents) {
this.rated = true;
changeListeners.fireChange(this);
}
}
protected void drawRating(int rating) {
int colCount = grid.getColumnCount();
int rateCount = Math.min(rating, colCount);
if (rateCount == 0) {
((RatePanel) grid.getWidget(0, 0)).replaceImage(ratedZeroImage);
} else {
((RatePanel) grid.getWidget(0, 0)).replaceImage(normalZeroImage);
}
int i;
for (i = 1; i <= rateCount; i++) {
((RatePanel) grid.getWidget(0, i)).replaceImage(ratedImage);
}
for (; i < colCount; i++) {
((RatePanel) grid.getWidget(0, i)).replaceImage(normalImage);
}
}
protected void setup() {
final int colCount = grid.getColumnCount();
boolean ratingImages10 = ratingImages != null && ratingImages.length == 10;
Image ratingImage = (ratingImages != null && ratingImages.length > 0) ?
ratingImages[0] : normalImage;
for (int i = 0; i < colCount; i++) {
Image img;
if (i == 0) {
img = normalZeroImage;
} else if (i <= rating) {
img = ratingImage;
} else if (ratingImages10 && i < rating + 1) {
int f = (int) ((rating - i + 1) * 10);
if (f > 0) {
img = ratingImages[f];
} else {
img = normalImage;
}
} else {
img = normalImage;
}
final RatePanel panel = new RatePanel(i, img);
panel.addMouseListener(cellMouseListener);
panel.addClickListener(cellClickListener);
grid.setWidget(0, i, panel);
}
}
}