/*
* RHQ Management Platform
* Copyright (C) 2005-2010 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation version 2 of the License.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package org.rhq.coregui.client.components.wizard;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.HTMLFlow;
import com.smartgwt.client.widgets.IButton;
import com.smartgwt.client.widgets.Label;
import com.smartgwt.client.widgets.Window;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.events.CloseClickEvent;
import com.smartgwt.client.widgets.events.CloseClickHandler;
import com.smartgwt.client.widgets.events.DrawEvent;
import com.smartgwt.client.widgets.events.DrawHandler;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.LayoutSpacer;
import com.smartgwt.client.widgets.toolbar.ToolStrip;
import org.rhq.coregui.client.CoreGUI;
import org.rhq.coregui.client.Messages;
import org.rhq.coregui.client.util.enhanced.EnhancedIButton;
import org.rhq.coregui.client.util.enhanced.EnhancedVLayout;
import org.rhq.coregui.client.util.enhanced.EnhancedIButton.ButtonColor;
/**
* @author Greg Hinkle
*/
public class WizardView extends EnhancedVLayout {
static private final Messages MSG = CoreGUI.getMessages();
static private final String CANCEL = MSG.common_button_cancel();
static private final String NEXT = MSG.common_button_next();
static private final String PREVIOUS = MSG.common_button_previous();
private Window wizardWindow;
private Wizard wizard;
private int currentStep;
private int dialogWidth;
private int dialogHeight;
HLayout titleBar;
HTMLFlow titleLabel;
Label stepLabel;
Label stepTitleLabel;
HLayout contentLayout;
HLayout messageBar;
HTMLFlow messageLabel;
ToolStrip buttonBar;
IButton cancelButton;
IButton previousButton;
IButton nextButton;
ArrayList<IButton> customButtons = new ArrayList<IButton>();
Canvas currentCanvas;
HashSet<Canvas> createdCanvases = new HashSet<Canvas>();
public WizardView(Wizard wizard) {
this(wizard, 800, 600);
}
public WizardView(Wizard wizard, int dialogWidth, int dialogHeight) {
super(10);
this.wizard = wizard;
this.dialogWidth = dialogWidth;
this.dialogHeight = dialogHeight;
}
@Override
protected void onDraw() {
super.onDraw();
titleBar = new HLayout(30);
titleBar.setHeight(50);
titleBar.setPadding(10);
titleBar.setBackgroundColor("#F0F0F0");
titleLabel = new HTMLFlow();
refreshTitleLabelContents();
titleLabel.setWidth("*");
stepLabel = new Label();
stepLabel.setWidth(60);
titleBar.addMember(titleLabel);
titleBar.addMember(stepLabel);
addMember(titleBar);
stepTitleLabel = new Label();
stepTitleLabel.setWidth100();
stepTitleLabel.setHeight(40);
stepTitleLabel.setPadding(20);
stepTitleLabel.setStyleName("HeaderLabel");
addMember(stepTitleLabel);
contentLayout = new HLayout();
contentLayout.setHeight("*");
contentLayout.setWidth100();
contentLayout.setPadding(10);
addMember(contentLayout);
messageBar = new HLayout();
messageBar.setHeight(20);
messageBar.setPadding(2);
messageBar.setBackgroundColor("#F0F0F0");
messageLabel = new HTMLFlow();
messageLabel.setWidth("*");
messageLabel.setLeft(20);
messageBar.addMember(messageLabel);
messageBar.setVisible(false);
addMember(messageBar);
buttonBar = new ToolStrip();
buttonBar.setPadding(5);
buttonBar.setWidth100();
buttonBar.setMembersMargin(15);
setupButtons();
addMember(buttonBar);
setStep(0);
}
/**
* You can call this if you ever change the wizard's title or subtitle and you want to see it
* reflected in the wizard UI.
*/
public void refreshTitleLabelContents() {
this.titleLabel.setContents("<span class=\"HeaderLabel\">" + wizard.getTitle() + "</span><br/>"
+ (wizard.getSubtitle() != null ? wizard.getSubtitle() : ""));
}
public void showMessage(String message) {
if (null == message) {
hideMessage();
} else {
this.messageLabel.setContents("<span style='color:red'>" + message + "</span>");
this.messageBar.show();
}
}
public void hideMessage() {
this.messageBar.hide();
}
private void setupButtons() {
cancelButton = new EnhancedIButton(CANCEL);
cancelButton.setDisabled(false);
cancelButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent clickEvent) {
wizard.cancel();
closeDialog();
}
});
buttonBar.addMember(cancelButton);
buttonBar.addMember(new LayoutSpacer());
previousButton = new EnhancedIButton(PREVIOUS);
previousButton.setDisabled(true);
previousButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent clickEvent) {
WizardStep step = wizard.getSteps().get(currentStep);
if (step.previousPage()) {
decrementStep();
}
}
});
if (wizard.getSteps().size() <= 1) {
previousButton.setVisible(false);
}
buttonBar.addMember(previousButton);
nextButton = new EnhancedIButton(NEXT, ButtonColor.BLUE);
nextButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent clickEvent) {
WizardStep step = wizard.getSteps().get(currentStep);
if (step.nextPage()) {
incrementStep();
}
}
});
buttonBar.addMember(nextButton);
}
private void setStep(final int stepIndex) {
previousButton.setVisible(stepIndex >= 1);
if (stepIndex < 0) {
previousButton.setDisabled(true);
return;
}
// determine if we are "finished" - that is, going past our last step
final List<WizardStep> wizardSteps = wizard.getSteps();
if (stepIndex >= wizardSteps.size()) {
closeDialog();
return;
}
// a valid step, continue
currentStep = stepIndex;
stepLabel.setContents(MSG.common_msg_step_x_of_y(String.valueOf(stepIndex + 1), String.valueOf(wizardSteps
.size())));
stepLabel.setWrap(false);
final WizardStep step = wizardSteps.get(currentStep);
stepTitleLabel.setContents(step.getName());
cancelButton.setDisabled(true);
previousButton.setDisabled(true);
nextButton.setDisabled(true);
for (IButton button : customButtons) {
buttonBar.removeMember(button);
}
customButtons.clear();
List<IButton> newCustomButtons = wizard.getCustomButtons(currentStep);
if (newCustomButtons != null) {
for (IButton button : newCustomButtons) {
button.setDisabled(true);
buttonBar.addMember(button);
customButtons.add(button);
}
}
if (currentCanvas != null) {
contentLayout.removeMember(currentCanvas);
}
currentCanvas = wizardSteps.get(currentStep).getCanvas();
// if null, advance to the next step by automatically "clicking" the Next button
if (null == currentCanvas) {
if (step.nextPage()) {
wizardSteps.get(currentStep).nextPage();
}
cancelButton.setDisabled(false);
previousButton.setDisabled(stepIndex == 0);
nextButton.setDisabled(false);
} else {
// after the canvas is drawn, enable the wizard buttons (unlikely a user will notice, but useful
// for keeping automated testing from advancing too quickly).
currentCanvas.addDrawHandler(new DrawHandler() {
@Override
public void onDraw(DrawEvent event) {
boolean last = (stepIndex == (wizardSteps.size() - 1));
if (last) {
nextButton.setTitle(MSG.common_button_finish());
} else {
nextButton.setTitle(MSG.common_button_next());
}
cancelButton.setDisabled(false);
previousButton.setDisabled(stepIndex == 0);
nextButton.setDisabled(!step.isNextButtonEnabled());
for (IButton button : customButtons) {
button.setDisabled(false);
}
markForRedraw();
}
});
createdCanvases.add(currentCanvas);
contentLayout.addMember(currentCanvas);
// clean any message from a previous step
hideMessage();
}
markForRedraw();
}
public void displayDialog() {
wizardWindow = new Window();
wizardWindow.setTitle(wizard.getWindowTitle());
wizardWindow.setWidth(dialogWidth);
wizardWindow.setHeight(dialogHeight);
wizardWindow.setIsModal(true);
wizardWindow.setShowModalMask(true);
wizardWindow.setCanDragResize(true);
wizardWindow.setShowResizer(true);
wizardWindow.centerInPage();
wizardWindow.addCloseClickHandler(new CloseClickHandler() {
public void onCloseClick(CloseClickEvent closeClickEvent) {
wizard.cancel();
closeDialog();
}
});
wizardWindow.addItem(this);
wizardWindow.show();
}
public void closeDialog() {
// Attempt to clean up canvases created in the steps
for (Canvas canvas : createdCanvases) {
canvas.destroy();
}
wizardWindow.destroy();
}
public IButton getCancelButton() {
return cancelButton;
}
public IButton getPreviousButton() {
return previousButton;
}
public IButton getNextButton() {
return nextButton;
}
public ArrayList<IButton> getCustomButtons() {
return customButtons;
}
public void incrementStep() {
setStep(currentStep + 1);
}
public void decrementStep() {
setStep(currentStep - 1);
}
public void updateButtonEnablement() {
WizardStep step = wizard.getSteps().get(currentStep);
getNextButton().setDisabled(!step.isNextButtonEnabled());
}
}