/* * Copyright (c) 2011, grossmann * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the jo-widgets.org nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL jo-widgets.org BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. */ package org.jowidgets.workbench.impl; import java.util.LinkedList; import java.util.List; import org.jowidgets.api.controller.ITabFolderListener; import org.jowidgets.api.controller.ITabSelectionEvent; import org.jowidgets.api.model.item.IMenuBarModel; import org.jowidgets.api.model.item.IToolBarModel; import org.jowidgets.api.toolkit.Toolkit; import org.jowidgets.api.widgets.IComposite; import org.jowidgets.api.widgets.IContainer; import org.jowidgets.api.widgets.IFrame; import org.jowidgets.api.widgets.ISplitComposite; import org.jowidgets.api.widgets.ITabFolder; import org.jowidgets.api.widgets.ITabItem; import org.jowidgets.api.widgets.blueprint.IFrameBluePrint; import org.jowidgets.api.widgets.blueprint.ISplitCompositeBluePrint; import org.jowidgets.api.widgets.blueprint.ITabItemBluePrint; import org.jowidgets.api.widgets.blueprint.factory.IBluePrintFactory; import org.jowidgets.common.application.IApplicationLifecycle; import org.jowidgets.common.types.Cursor; import org.jowidgets.common.types.IVetoable; import org.jowidgets.common.types.SplitResizePolicy; import org.jowidgets.common.widgets.controller.IWindowListener; import org.jowidgets.common.widgets.layout.MigLayoutDescriptor; import org.jowidgets.tools.controller.WindowAdapter; import org.jowidgets.tools.layout.MigLayoutFactory; import org.jowidgets.tools.model.item.MenuBarModel; import org.jowidgets.tools.types.VetoHolder; import org.jowidgets.util.Assert; import org.jowidgets.workbench.api.ITrayItem; import org.jowidgets.workbench.api.IWorkbench; import org.jowidgets.workbench.api.IWorkbenchApplication; import org.jowidgets.workbench.api.IWorkbenchContext; public class WorkbenchContext implements IWorkbenchContext { private final IWorkbench workbench; private final IApplicationLifecycle lifecycle; private final List<Runnable> shutdownHooks; private final IBluePrintFactory bpf; private final IWindowListener windowListener; private final List<IWorkbenchApplication> addedApplications; private final List<WorkbenchApplicationContext> addedApplicationContexts; private final List<ITabItem> addedTabItems; private final IFrame rootFrame; private final IContainer rootContainer; private final IContainer statusBar; private final WorkbenchToolbar toolBar; private final IToolBarModel toolBarModel; private final IContainer workbenchContentContainer; private final WorkbenchContentPanel workbenchContentPanel; private IMenuBarModel menuBarModel; private ITabFolder applicationTabFolder; private boolean disposed; private boolean onComponentChange; private boolean lastToolbarVisible; public WorkbenchContext(final IWorkbench workbench, final IApplicationLifecycle lifecycle) { this.workbench = workbench; this.disposed = false; this.onComponentChange = false; this.bpf = Toolkit.getBluePrintFactory(); this.addedApplications = new LinkedList<IWorkbenchApplication>(); this.addedApplicationContexts = new LinkedList<WorkbenchApplicationContext>(); this.addedTabItems = new LinkedList<ITabItem>(); this.lifecycle = lifecycle; this.shutdownHooks = new LinkedList<Runnable>(); this.windowListener = createWindowListener(workbench); this.rootFrame = createRootFrame(workbench); this.rootContainer = createRootContainer(); this.toolBar = createToolBar(); this.toolBarModel = toolBar.getToolBarModel(); this.workbenchContentContainer = createWorkbenchContentContainer(workbench); this.workbenchContentPanel = new WorkbenchContentPanel(workbenchContentContainer); this.statusBar = createStatusBar(); applicationTabFolder.addTabFolderListener(createTabFolderListener()); workbench.onContextInitialize(this); } @Override public IContainer getStatusBar() { return statusBar; } @Override public IToolBarModel getToolBar() { return toolBarModel; } @Override public IMenuBarModel getMenuBar() { if (this.menuBarModel == null) { this.menuBarModel = new MenuBarModel(); rootFrame.setMenuBar(menuBarModel); } return menuBarModel; } @Override public void add(final IWorkbenchApplication application) { add(addedApplications.size(), application); } @Override public void add(final int index, final IWorkbenchApplication application) { Assert.paramNotNull(application, "application"); final ITabItemBluePrint tabItemBp = bpf.tabItem(); tabItemBp.setText(application.getLabel()); tabItemBp.setToolTipText(application.getTooltip()); tabItemBp.setIcon(application.getIcon()); final ITabItem tabItem = applicationTabFolder.addItem(index, tabItemBp); final WorkbenchApplicationContext applicationContext = new WorkbenchApplicationContext(this, tabItem, application); addedTabItems.add(tabItem); addedApplications.add(index, application); addedApplicationContexts.add(index, applicationContext); application.onContextInitialize(applicationContext); } @Override public void remove(final IWorkbenchApplication workbenchApplication) { Assert.paramNotNull(workbenchApplication, "workbenchApplication"); final int index = addedApplications.indexOf(workbenchApplication); if (index != -1) { addedApplications.remove(index); final WorkbenchApplicationContext applicationContext = addedApplicationContexts.remove(index); applicationContext.dispose(); final ITabItem tabItem = addedTabItems.remove(index); applicationTabFolder.removeItem(tabItem); if (addedTabItems.size() == 0) { selectComponentNode(null); } } } @Override public void addShutdownHook(final Runnable shutdownHook) { shutdownHooks.add(shutdownHook); } @Override public void removeShutdownHook(final Runnable shutdownHook) { shutdownHooks.remove(shutdownHook); } @Override public void finish() { if (!disposed) { dispose(); } } @Override public ITrayItem getTrayItem() { // TODO MG support trayItem return null; } public void run() { if (!this.rootFrame.isVisible()) { this.rootFrame.setVisible(true); if (workbench.isInitialMaximized()) { rootFrame.setMaximized(true); } } } protected void unregsiterApplication(final ITabItem item) { final int index = addedTabItems.indexOf(item); if (index != -1) { addedApplications.remove(index); addedTabItems.remove(index); addedApplicationContexts.remove(index); } if (addedTabItems.size() == 0) { selectComponentNode(null); } } protected void beforeComponentChange() { if (!onComponentChange) { lastToolbarVisible = toolBar.isVisible(); rootContainer.setRedrawEnabled(false); rootFrame.setCursor(Cursor.WAIT); onComponentChange = true; } } protected void selectComponentNode(final ComponentNodeContext newComponentNode) { beforeComponentChange(); if (newComponentNode != null) { if (!newComponentNode.isActive()) { newComponentNode.activate(); } } else { workbenchContentPanel.setEmptyContent(); } afterComponentChange(); } protected void afterComponentChange() { if (onComponentChange) { if (lastToolbarVisible != toolBar.isVisible()) { rootContainer.layoutEnd(); } rootContainer.setRedrawEnabled(true); rootFrame.setCursor(Cursor.DEFAULT); onComponentChange = false; } } protected WorkbenchContentPanel getWorkbenchContentPanel() { return workbenchContentPanel; } private IFrame createRootFrame(final IWorkbench workbench) { final IFrameBluePrint rootFrameBp = bpf.frame(); rootFrameBp.setTitle(workbench.getLabel()); rootFrameBp.setIcon(workbench.getIcon()); rootFrameBp.setPosition(workbench.getInitialPosition()); rootFrameBp.setSize(workbench.getInitialDimension()); rootFrameBp.setDecorated(workbench.isDecorated()); final IFrame result = Toolkit.createRootFrame(rootFrameBp); result.setLayout(MigLayoutFactory.growingInnerCellLayout()); result.addWindowListener(windowListener); return result; } private IContainer createRootContainer() { final IContainer result = rootFrame.add(bpf.composite(), MigLayoutFactory.GROWING_CELL_CONSTRAINTS); result.setLayout(new MigLayoutDescriptor("2[grow]2", "1[]1[grow]1[]1")); return result; } private WorkbenchToolbar createToolBar() { final IContainer toolBarContainer = rootContainer.add(bpf.composite(), "hidemode 2, w 0::, grow, wrap"); toolBarContainer.setLayout(new MigLayoutDescriptor("0[grow, 0::]0", "0[grow, 0::]0")); return new WorkbenchToolbar(toolBarContainer); } private IContainer createWorkbenchContentContainer(final IWorkbench workbench) { final IContainer result; final IComposite contentComposite = rootContainer.add(bpf.composite(), "growx, growy, w 0::, h 0::, wrap"); contentComposite.setLayout(new MigLayoutDescriptor("0[grow, 0::]0", "0[grow, 0::]0")); if (workbench.hasApplicationNavigator()) { final ISplitCompositeBluePrint splitCompositeBp = bpf.splitHorizontal().disableBorders(); splitCompositeBp.setResizePolicy(SplitResizePolicy.RESIZE_SECOND); splitCompositeBp.setWeight(workbench.getInitialSplitWeight()); final ISplitComposite splitComposite = contentComposite.add(splitCompositeBp, "growx, growy, h 0::, w 0::"); final IContainer applicationsContainer = splitComposite.getFirst(); applicationsContainer.setLayout(new MigLayoutDescriptor("0[grow, 0::]0", "0[grow, 0::]0")); applicationsContainer.setVisible(workbench.hasApplicationNavigator()); applicationTabFolder = applicationsContainer .add(bpf.tabFolder().setTabsCloseable(workbench.getApplicationsCloseable()), "growx, growy, h 0::, w 0::"); result = splitComposite.getSecond(); } else { applicationTabFolder = contentComposite.add( bpf.tabFolder().setTabsCloseable(workbench.getApplicationsCloseable()), "hidemode 3, growx, growy, h 0::, w 0::"); applicationTabFolder.setVisible(false); result = contentComposite; } return result; } private IContainer createStatusBar() { return new WorkbenchStatusBar(rootContainer.add(bpf.composite(), "hidemode 2, growx")); } private ITabFolderListener createTabFolderListener() { return new ITabFolderListener() { @Override public void itemSelected(final ITabSelectionEvent selectionEvent) { final ITabItem selectedTab = selectionEvent.getNewSelected(); if (selectedTab != null) { final int selectedIndex = addedTabItems.indexOf(selectedTab); if (selectedIndex != -1) { final WorkbenchApplicationContext applicationContext = addedApplicationContexts.get(selectedIndex); applicationContext.getApplication().onVisibleStateChanged(true); selectComponentNode(applicationContext.getSelectedNodeContext()); } //else{this can happen if the application was just added} } } @Override public void onDeselection(final IVetoable vetoable, final ITabSelectionEvent selectionEvent) { final ITabItem selectedTab = selectionEvent.getLastSelected(); if (selectedTab != null) { final int selectedIndex = addedTabItems.indexOf(selectedTab); if (selectedIndex != -1) { final WorkbenchApplicationContext applicationContext = addedApplicationContexts.get(selectedIndex); final ComponentNodeContext selectedNodeContext = applicationContext.getSelectedNodeContext(); if (selectedNodeContext != null && selectedNodeContext.isActive()) { final VetoHolder vetoHolder = selectedNodeContext.tryDeactivate(); if (vetoHolder.hasVeto()) { vetoable.veto(); return; } } applicationContext.getApplication().onVisibleStateChanged(false); } } } }; } private IWindowListener createWindowListener(final IWorkbench workbench) { return new WindowAdapter() { @Override public void windowClosing(final IVetoable windowCloseVetoable) { final VetoHolder vetoHolder = new VetoHolder(); workbench.onClose(vetoHolder); if (vetoHolder.hasVeto()) { windowCloseVetoable.veto(); } else { dispose(); } } }; } private void dispose() { if (!disposed) { disposed = true; rootFrame.removeWindowListener(windowListener); //dispose the application for (final WorkbenchApplicationContext applicationContext : addedApplicationContexts) { applicationContext.dispose(); } runShutdownHooks(); rootFrame.dispose(); lifecycle.finish(); } } private void runShutdownHooks() { for (final Runnable shutdownHook : shutdownHooks) { shutdownHook.run(); } } }