/******************************************************************************* * Copyright 2011 Antti Havanko * * This file is part of Motiver.fi. * Motiver.fi is licensed under one open source license and one commercial license. * * Commercial license: This is the appropriate option if you want to use Motiver.fi in * commercial purposes. Contact license@motiver.fi for licensing options. * * Open source license: This is the appropriate option if you are creating an open source * application with a license compatible with the GNU GPL license v3. Although the GPLv3 has * many terms, the most important is that you must provide the source code of your application * to your users so they can be free to modify your application for their own needs. ******************************************************************************/ package com.delect.motiver.client.presenter; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import com.google.gwt.event.shared.EventHandler; import com.google.gwt.event.shared.GwtEvent; import com.google.gwt.event.shared.GwtEvent.Type; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.event.shared.SimpleEventBus; import com.google.gwt.http.client.Request; import com.google.gwt.user.client.ui.Widget; import com.delect.motiver.client.event.LoadingEvent; import com.delect.motiver.client.service.MyServiceAsync; import com.delect.motiver.client.view.Display; import com.extjs.gxt.ui.client.widget.LayoutContainer; /** Base class for presenters. */ public abstract class Presenter { private List<HandlerRegistration> listHandlers = new ArrayList<HandlerRegistration>(); private Set<Request> rpcRequests = new HashSet<Request>(); protected LayoutContainer container = null; protected SimpleEventBus eventBus; protected MyServiceAsync rpcService; private Presenter parent = null; /** * Constructor for Presenter. * @param rpcService MyServiceAsync * @param eventBus SimpleEventBus */ public Presenter(MyServiceAsync rpcService, SimpleEventBus eventBus) { // System.out.println("Presenter: " + this.getClass().getName()); this.rpcService = rpcService; this.eventBus = eventBus; } /** * Adds handler to event bus. Handlers are removed when presenter is stopped * @param type * @param handler * @return HandlerRegistration */ public <H extends EventHandler> HandlerRegistration addEventHandler(Type<H> type, H handler) { final HandlerRegistration ret = eventBus.addHandler(type, handler); listHandlers.add(ret); return ret; } /** * Fires event to event bus * @param event */ public final void fireEvent(GwtEvent<?> event) { eventBus.fireEventFromSource(event, this); } /** * Returns view for this presenter * @return view */ public abstract Display getView(); /** * Hides presenter. For example when switching through tabs * <br>Calls display's onStop() method */ public final void hide() { //stop display (closes popups etc...) if(getView() != null) { getView().onStop(); } setVisible(false); // System.out.println("Presenter: " + this.getClass().toString() + " onHide()"); onHide(); } /** * Calls displays highlight function */ public final void highlight() { if(getView() != null) { getView().highlight(); } } /** * Called before presenter is runned. Can be used for attaching handler etc. */ public void onBind() { } /** * Called after presenter is hidden. */ public void onHide() { } /** * Called when presenter is run for the second time. Sub-class can just refresh the presenter */ public void onRefresh() { } /** * Called when presenter is run. This is called ONCE after presenter is added to container. */ public void onRun() { } /** * Called when presenter is stopped. Presenter's container is removed after this */ public void onStop() { } /** * Shows content of panel. Only necessary if panel can be closed, etc... */ public void show() { } /** * refresh the presenter (and display) and calls run */ public final void refresh() { onStop(); onBind(); if(container != null) { container.removeAll(); if(getView() != null) { container.add(getView().asWidget()); } container.layout(); } setVisible(true); // System.out.println("Presenter: " + this.getClass().getName() + " onBind() & onRun()"); onRun(); } /** * Removes presenter from parent container. Does NOT clear display! */ public final void remove() { container.removeFromParent(); } public final void run(LayoutContainer containerParent) { run(containerParent, true); } /** * Called when presenter is run. It adds presenter to given container and calls onRun * @param containerParent LayoutContainer * @param doLayout boolean */ public final void run(LayoutContainer containerParent, boolean doLayout) { //if parent is null -> cancel if(containerParent == null) { return; } onBind(); //if container not set -> run for the first time if(container == null) { container = new LayoutContainer(); if(getView() != null) { final Widget p = getView().asWidget(); //if left menu enabled if(getView().panelMenuLeft != null) { container.add(getView().panelMenuLeft); ((LayoutContainer)p).setStyleAttribute("marginLeft", "160px"); } container.add(p); } containerParent.add(container); if(doLayout) { containerParent.layout(); } setVisible(true); if(getView() != null && !getView().isEnabled()) { getView().setContentEnabled(true); } // System.out.println("Presenter: " + this.getClass().getName() + " onBind() & onRun()"); onRun(); } //container already set -> just refresh else { setVisible(true); if(getView() != null) { getView().setContentEnabled(true); } // System.out.println("Presenter: " + this.getClass().getName() + " onBind() & onRefresh()"); onRefresh(); } } /** * Called when presenter is stopped * <br>We can remove presenter from parent */ public final void stop() { //cancel RPC calls for(Request request : rpcRequests) { if(request != null && request.isPending()) { request.cancel(); //cancel loading event eventBus.fireEvent(new LoadingEvent(null)); } } if(getView() != null) { getView().onStop(); } //remove event handlers for(int i=0; i < listHandlers.size(); i++) { if(listHandlers.get(i) != null) { listHandlers.get(i).removeHandler(); } } listHandlers.clear(); // System.out.println("Presenter: " + this.getClass().getName() + " onStop()"); onStop(); if(container != null) { container.removeFromParent(); } container = null; } /** * Updates current container to given parent. * <br>Calls run if container is null * @param containerParent */ public final void update(LayoutContainer containerParent) { if(container != null) { containerParent.add(container); containerParent.layout(); } else { run(containerParent); } } /** * Shows / hides presenter * @param visible boolean */ private void setVisible(boolean visible) { if(container != null && container.isVisible(false) != visible) { container.setVisible(visible); if(container.isVisible()) { container.layout(true); } } } /** * Adds rpc request to array. These requests are cancelled when presenters stops * @param request */ public final void addRequest(Request request) { rpcRequests.add(request); } public void setParent(Presenter parent) { this.parent = parent; } public Presenter getParent() { return parent; } }