Package com.eclipsesource.tabris.internal.ui

Source Code of com.eclipsesource.tabris.internal.ui.Controller

/*******************************************************************************
* Copyright (c) 2013 EclipseSource and others.
* 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:
*    EclipseSource - initial API and implementation
******************************************************************************/
package com.eclipsesource.tabris.internal.ui;

import static com.eclipsesource.tabris.internal.Preconditions.checkState;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;

import com.eclipsesource.tabris.Store;
import com.eclipsesource.tabris.internal.ZIndexStackLayout;
import com.eclipsesource.tabris.ui.Page;
import com.eclipsesource.tabris.ui.TransitionListener;


public class Controller {

  private final DescriptorHolder content;
  private final Shell shell;
  private final List<RemoteAction> globalActions;
  private final Map<PageDescriptor, RemotePage> rootPages;
  private final RemoteUI remoteUI;
  private PageFlow currentFlow;

  public Controller( Shell shell, RemoteUI remoteUI, DescriptorHolder content ) {
    this.shell = shell;
    this.remoteUI = remoteUI;
    this.content = content;
    this.globalActions = new ArrayList<RemoteAction>();
    this.rootPages = new HashMap<PageDescriptor, RemotePage>();
  }

  public void createRootPages( UIContextImpl context ) {
    List<PageDescriptor> pages = content.getRootPages();
    verifyRootPages( pages );
    createRootRemotePages( context, pages );
    showRoot( context, pages.get( 0 ), new Store() );
  }

  private void createRootRemotePages( UIContextImpl context, List<PageDescriptor> pages ) {
    for( PageDescriptor descriptor : pages ) {
      RemotePage remotePage = new RemotePage( context, descriptor, remoteUI.getRemoteUIId(), new Store() );
      rootPages.put( descriptor, remotePage );
      remotePage.createControl( shell );
    }
  }

  public void createGlobalActions( UIContextImpl context ) {
    List<ActionDescriptor> actions = content.getGlobalActions();
    for( ActionDescriptor actionDescriptor : actions ) {
      globalActions.add( new RemoteAction( context, actionDescriptor, remoteUI.getRemoteUIId() ) );
    }
  }

  private void verifyRootPages( List<PageDescriptor> pages ) {
    if( pages.isEmpty() ) {
      throw new IllegalStateException( "No TopLevel Pages found." );
    }
  }

  void show( UIContextImpl context, PageDescriptor newPage, Store store ) {
    if( newPage.isTopLevel() ) {
      showRoot( context, newPage, store );
    } else {
      showPage( context, newPage, store );
    }
  }

  void showRoot( UIContextImpl context, PageDescriptor newPage, Store store ) {
    RemotePage oldRoot = null;
    RemotePage newRoot = rootPages.get( newPage );
    newRoot.getStore().addStore( store );
    if( currentFlow != null ) {
      oldRoot = cleanupOldRoot( context, newRoot );
    }
    initializeNewRoot( context, oldRoot, newRoot );
  }

  private RemotePage cleanupOldRoot( UIContextImpl context, RemotePage root ) {
    RemotePage oldRoot = currentFlow.getCurrentPage();
    fireTransitionBeforeEvent( context, oldRoot, root );
    oldRoot.destroyActions();
    oldRoot.getPage().deactivate( context );
    currentFlow.destroy();
    return oldRoot;
  }

  private void initializeNewRoot( UIContextImpl context, RemotePage oldRoot, RemotePage newRoot ) {
    currentFlow = new PageFlow( newRoot );
    remoteUI.activate( newRoot.getRemotePageId() );
    newRoot.createActions();
    newRoot.getPage().activate( context );
    makeControlVisible( currentFlow.getCurrentPage().getControl() );
    fireTransitionAfterEvent( context, oldRoot, newRoot );
  }

  RemotePage showPage( UIContextImpl context, PageDescriptor newPage, Store store ) {
    RemotePage oldRemotePage = cleanupOldPage( context );
    return initializeNewPage( context, newPage, oldRemotePage, store );
  }

  private RemotePage cleanupOldPage( UIContextImpl context ) {
    RemotePage oldPage = currentFlow.getCurrentPage();
    oldPage.destroyActions();
    oldPage.getPage().deactivate( context );
    return oldPage;
  }

  private RemotePage initializeNewPage( UIContextImpl context,
                                        PageDescriptor newPage,
                                        RemotePage oldRemotePage,
                                        Store store )
  {
    RemotePage newRemotePage = new RemotePage( context, newPage, remoteUI.getRemoteUIId(), store );
    fireTransitionBeforeEvent( context, oldRemotePage, newRemotePage );
    currentFlow.add( newRemotePage );
    newRemotePage.createControl( shell );
    newRemotePage.createActions();
    remoteUI.activate( newRemotePage.getRemotePageId() );
    newRemotePage.getPage().activate( context );
    makeControlVisible( newRemotePage.getControl() );
    fireTransitionAfterEvent( context, oldRemotePage, newRemotePage );
    return newRemotePage;
  }

  boolean showPreviousPage( UIContextImpl context ) {
    if( currentFlow != null && currentFlow.getPreviousPage() != null ) {
      restorePreviousPage( context, currentFlow.getPreviousPage() );
      return true;
    }
    return false;
  }

  private void restorePreviousPage( UIContextImpl context, RemotePage previousPage ) {
    RemotePage removedPage = cleanUpCurrentPage( context );
    fireTransitionBeforeEvent( context, removedPage, previousPage );
    initializePreviousPage( context, previousPage );
    fireTransitionAfterEvent( context, removedPage, previousPage );
  }

  private RemotePage cleanUpCurrentPage( UIContextImpl context ) {
    RemotePage removedPage = currentFlow.pop();
    removedPage.destroy();
    removedPage.destroyActions();
    removedPage.getPage().deactivate( context );
    return removedPage;
  }

  private void initializePreviousPage( UIContextImpl context, RemotePage previousPage ) {
    remoteUI.activate( previousPage.getRemotePageId() );
    previousPage.createActions();
    previousPage.getPage().activate( context );
    makeControlVisible( previousPage.getControl() );
  }

  private void makeControlVisible( Control control ) {
    ZIndexStackLayout stack = ( ZIndexStackLayout )shell.getLayout();
    stack.setOnTopControl( control );
    shell.layout( true );
  }

  public void setCurrentTitle( String title ) {
    if( currentFlow != null ) {
      currentFlow.getCurrentPage().setTitle( title );
    }
  }

  public Page getCurrentPage() {
    if( currentFlow != null ) {
      return currentFlow.getCurrentPage().getPage();
    }
    return null;
  }

  public Store getCurrentStore() {
    if( currentFlow != null ) {
      return currentFlow.getCurrentPage().getStore();
    }
    return null;
  }

  public String getPageId( String remotePageId ) {
    List<RemotePage> pages = getAllPages();
    for( RemotePage remotePage : pages ) {
      if( remotePage.getRemotePageId().equals( remotePageId ) ) {
        return remotePage.getDescriptor().getId();
      }
    }
    throw new IllegalStateException( "RemotePage with id " + remotePageId + " does not exist." );
  }

  private List<RemotePage> getAllPages() {
    List<RemotePage> pages = new ArrayList<RemotePage>( rootPages.values() );
    if( currentFlow != null ) {
      pages.addAll( currentFlow.getAllPages() );
    }
    return pages;
  }

  public void setActionEnabled( String id, boolean enabled ) {
    RemoteAction action = findRemoteAction( id );
    action.setEnabled( enabled );
  }

  public void setActionVisible( String id, boolean visible ) {
    RemoteAction action = findRemoteAction( id );
    action.setVisible( visible );
  }

  private RemoteAction findRemoteAction( String id ) {
    RemoteAction result = findActionInGlobalActions( id );
    if( result == null ) {
      result = findActionInPageActions( id );
    }
    checkState( result, "Action with id " + id + " does not exist." );
    return result;
  }

  private RemoteAction findActionInGlobalActions( String id ) {
    for( RemoteAction action : globalActions ) {
      if( action.getDescriptor().getId().equals( id ) ) {
        return action;
      }
    }
    return null;
  }

  private RemoteAction findActionInPageActions( String id ) {
    if( currentFlow != null ) {
      return findActionInCurrentFlow( id );
    }
    return null;
  }

  private RemoteAction findActionInCurrentFlow( String id ) {
    List<RemotePage> allPages = currentFlow.getAllPages();
    for( RemotePage page : allPages ) {
      List<RemoteAction> actions = page.getActions();
      for( RemoteAction remoteAction : actions ) {
        if( remoteAction.getDescriptor().getId().equals( id ) ) {
          return remoteAction;
        }
      }
    }
    return null;
  }

  void fireTransitionBeforeEvent( UIContextImpl context, RemotePage from, RemotePage to ) {
    List<TransitionListener> listeners = context.getUI().getTransitionListeners();
    for( TransitionListener listener : listeners ) {
      Page oldPage = from != null ? from.getPage() : null;
      Page newPage = to != null ? to.getPage() : null;
      listener.before( context, oldPage, newPage );
    }
  }

  void fireTransitionAfterEvent( UIContextImpl context, RemotePage from, RemotePage to ) {
    List<TransitionListener> listeners = context.getUI().getTransitionListeners();
    for( TransitionListener listener : listeners ) {
      Page oldPage = from != null ? from.getPage() : null;
      Page newPage = to != null ? to.getPage() : null;
      listener.after( context, oldPage, newPage );
    }
  }

  Map<PageDescriptor, RemotePage> getRootPages() {
    return rootPages;
  }

}
TOP

Related Classes of com.eclipsesource.tabris.internal.ui.Controller

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.