package org.mdl4ui.gwt.model.client.ui; import static org.mdl4ui.fields.model.event.FieldEvent.newEvent; import static org.mdl4ui.fields.model.event.FieldEvent.releaseSourceEvent; import java.util.HashMap; import java.util.List; import java.util.Map; import org.mdl4ui.base.model.BlockID; import org.mdl4ui.base.model.GroupID; import org.mdl4ui.base.model.ScreenID; import org.mdl4ui.fields.model.Block; import org.mdl4ui.fields.model.DefaultWizard; import org.mdl4ui.fields.model.Field; import org.mdl4ui.fields.model.Screen; import org.mdl4ui.fields.model.Wizard; import org.mdl4ui.fields.model.event.EventProperty; import org.mdl4ui.fields.model.event.FieldEvent; import org.mdl4ui.gwt.model.client.factory.GwtScreenFactory; import com.github.gwtbootstrap.client.ui.Container; import com.google.gwt.core.shared.GWT; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.logical.shared.HasValueChangeHandlers; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; public class WizardView implements IsWidget { private final Container container; private final GwtScreenFactory screenFactory = GWT.create(GwtScreenFactory.class); private final Map<ScreenID, ScreenView> screens = new HashMap<ScreenID, ScreenView>(); public WizardView(final DefaultWizard wizard) { Screen firstScreen = null; for (final ScreenID screenID : wizard.getScreens().keySet()) { final ScreenView screenView = screenFactory.getView(wizard.getScreens().get(screenID)); if (firstScreen == null) { firstScreen = screenView.getScreen(); } for (final Field field : screenView.getScreen().fields()) { @SuppressWarnings({ "rawtypes", "unchecked" }) HasValueChangeHandlers<Object> hasChangeHandler = (HasValueChangeHandlers) field.getComponent(); hasChangeHandler.addValueChangeHandler(new ValueChangeHandler<Object>() { @Override public void onValueChange(ValueChangeEvent<Object> event) { updateField(wizard, screenView, field); } }); } for (final BlockView blockView : screenView.blocks()) { blockView.getSubmit().addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { submitBlock(wizard, screenID, screenView, blockView); } }); blockView.getModify().addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { modifyBlock(screenView, blockView); } }); } screens.put(screenID, screenView); } container = new Container(); } @Override public Widget asWidget() { return container; } private void updateField(final DefaultWizard wizard, final ScreenView screenView, final Field field) { final FieldEvent event = newEvent(field.getFieldID(), EventProperty.FIELD); try { // udpate field wizard.updateField(field, event); // update owning group for (FieldView fieldView : screenView.fields()) { fieldView.updateField(); } for (GroupView groupView : screenView.groups()) { GroupID groupID = groupView.getGroup().getGroupID(); groupView.asWidget().setVisible(wizard.isVisible(groupID, event)); } } finally { releaseSourceEvent(); } } private void submitBlock(final DefaultWizard wizard, final ScreenID screenID, final ScreenView screenView, final BlockView blockView) { Block block = blockView.getBlock(); wizard.submit(block); for (FieldView fieldView : screenView.fields()) { fieldView.updateField(); } if (block.isValid()) { blockView.collapse(); blockView.getModify().setVisible(true); BlockID nextBlock = screenID.nextBlock(block.getBlockID()); if (nextBlock != null) { for (BlockView screenBlock : screenView.blocks()) { if (screenBlock.getBlock().getBlockID() == nextBlock) { screenBlock.expand(); } } } else { submitScreen(wizard, screenID); } } } private void submitScreen(final DefaultWizard wizard, final ScreenID screenID) { ScreenID nextScreen = wizard.getScenario().nextScreen(screenID); if (nextScreen != null) { displayScreen(wizard, nextScreen); } } private void modifyBlock(ScreenView screenView, BlockView blockView) { final List<BlockView> blocks = screenView.blocks(); boolean canBeModified = true; for (BlockView otherBlock : blocks) { if (blockView == otherBlock) { otherBlock.expand(); canBeModified = false; } else { otherBlock.collapse(); otherBlock.getModify().setVisible(canBeModified); } } } public void displayScreen(Wizard wizard, ScreenID screenID) { container.clear(); ScreenView screenView = screens.get(screenID); if (screenView == null) { throw new IllegalArgumentException("unknow screen id : " + screenView); } screenView.onDisplay(wizard.getContext()); container.add(screenView); wizard.displayScreen(screenView.getScreen()); for (FieldView fieldView : screenView.fields()) { fieldView.updateField(); } List<BlockView> blocks = screenView.blocks(); if (!blocks.isEmpty()) { blocks.get(0).expand(); blocks.remove(0); for (BlockView blockView : blocks) { blockView.collapse(); blockView.getModify().setVisible(false); } } } }