package org.xmind.ui.internal.e4models; import org.eclipse.e4.ui.internal.workbench.OpaqueElementUtil; import org.eclipse.e4.ui.model.application.ui.MDirtyable; import org.eclipse.e4.ui.model.application.ui.MUILabel; import org.eclipse.e4.ui.model.application.ui.basic.MPart; import org.eclipse.e4.ui.model.application.ui.menu.MMenu; import org.eclipse.e4.ui.model.application.ui.menu.MMenuElement; import org.eclipse.e4.ui.workbench.IPresentationEngine; import org.eclipse.e4.ui.workbench.renderers.swt.MenuManagerRenderer; import org.eclipse.jface.action.IContributionItem; import org.eclipse.jface.action.LegacyActionTools; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.resource.FontDescriptor; import org.eclipse.swt.SWT; import org.eclipse.swt.accessibility.ACC; import org.eclipse.swt.accessibility.Accessible; import org.eclipse.swt.accessibility.AccessibleAdapter; import org.eclipse.swt.accessibility.AccessibleEvent; import org.eclipse.swt.custom.CTabFolder; import org.eclipse.swt.custom.CTabItem; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.ToolBar; import org.eclipse.swt.widgets.ToolItem; import org.xmind.ui.dialogs.Messages; import org.xmind.ui.resources.ColorUtils; import org.xmind.ui.resources.FontUtils; @SuppressWarnings("restriction") public class ViewModelPart extends ModelPart { private Composite rightBar; private Composite menuBar; private boolean adjusting; private ToolBar viewMenuTB; private Label tipLabel; protected void createContent(Composite parent) { CTabFolder ctf = new CTabFolder(parent, SWT.BORDER); ctf.setRenderer(new ViewModelFolderRenderer(ctf)); ctf.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); CTabItem ti = new CTabItem(ctf, SWT.NONE); MPart partModel = getAdapter(MPart.class); ti.setText(getLabel(partModel, partModel.getLocalizedLabel())); ti.setToolTipText(getToolTip(partModel.getLocalizedTooltip())); ctf.setSelection(ti); Composite contentContainer = new Composite(ctf, SWT.NONE); GridLayout layout = new GridLayout(); layout.marginWidth = 0; layout.marginHeight = 0; layout.horizontalSpacing = 0; layout.verticalSpacing = 0; contentContainer.setLayout(layout); ti.setControl(contentContainer); Control content = doCreateContent(contentContainer); content.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); addTopRight(ctf, true); adjustViewMenuBar(true); } protected Control doCreateContent(Composite parent) { return null; } protected String getLabel(MUILabel itemPart, String newName) { if (newName == null) { newName = ""; //$NON-NLS-1$ } else { newName = LegacyActionTools.escapeMnemonics(newName); } if (itemPart instanceof MDirtyable && ((MDirtyable) itemPart).isDirty()) { newName = '*' + newName; } return newName; } protected String getToolTip(String newToolTip) { return newToolTip == null || newToolTip.length() == 0 ? null : LegacyActionTools.escapeMnemonics(newToolTip); } /** * @param visibleOrEnable * true is to setVisible, otherwise to setEnable. */ protected void addTopRight(CTabFolder ctf, boolean visibleOrEnable) { rightBar = new Composite(ctf, SWT.NONE); rightBar.setBackground( (Color) resources.get(ColorUtils.toDescriptor("#f4f4f4"))); //$NON-NLS-1$ GridLayout layout = new GridLayout(2, false); layout.marginWidth = 0; layout.marginHeight = 0; layout.horizontalSpacing = 0; rightBar.setLayout(layout); createTipLabel(rightBar); createMenuBar(rightBar, visibleOrEnable); ctf.setTopRight(rightBar, SWT.RIGHT); } private void createTipLabel(Composite parent) { Composite composite = new Composite(parent, SWT.NONE); composite.setBackground(parent.getBackground()); composite.setLayoutData(new GridData(SWT.LEFT, SWT.FILL, false, true)); GridLayout layout = new GridLayout(1, false); layout.marginWidth = 0; layout.marginHeight = 0; layout.marginRight = 5; composite.setLayout(layout); tipLabel = new Label(composite, SWT.NONE); tipLabel.setBackground(composite.getBackground()); GridData layoutData = new GridData(SWT.LEFT, SWT.CENTER, false, true); layoutData.verticalIndent = 3; tipLabel.setLayoutData(layoutData); tipLabel.setForeground( (Color) resources.get(ColorUtils.toDescriptor("#a1a1a1"))); //$NON-NLS-1$ tipLabel.setFont((Font) resources .get(FontDescriptor.createFrom(FontUtils.relativeHeight( tipLabel.getFont().getFontData(), -1)))); //set initial state composite.setVisible(false); ((GridData) composite.getLayoutData()).exclude = true; } private void createMenuBar(Composite parent, boolean visibleOrEnable) { menuBar = new Composite(parent, SWT.NONE); menuBar.setBackground(parent.getBackground()); menuBar.setLayoutData(new GridData(SWT.LEFT, SWT.FILL, false, true)); GridLayout gridLayout = new GridLayout(1, false); gridLayout.marginWidth = 0; gridLayout.marginHeight = 0; menuBar.setLayout(gridLayout); viewMenuTB = new ToolBar(menuBar, SWT.FLAT | SWT.RIGHT); viewMenuTB.setBackground(menuBar.getBackground()); viewMenuTB.setLayoutData( new GridData(SWT.CENTER, SWT.BOTTOM, false, true)); viewMenuTB.setData(TAG_VIEW_MENU); ToolItem ti = new ToolItem(viewMenuTB, SWT.PUSH); ti.setToolTipText(Messages.ViewModelPart_MenuBar_toolTip); if (visibleOrEnable) { // Initially it's not visible menuBar.setVisible(false); } else { viewMenuTB.setEnabled(false); } ti.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { showViewMenu((ToolItem) e.widget); } public void widgetDefaultSelected(SelectionEvent e) { showViewMenu((ToolItem) e.widget); } }); viewMenuTB.getAccessible() .addAccessibleListener(new AccessibleAdapter() { @Override public void getName(AccessibleEvent e) { if (e.childID != ACC.CHILDID_SELF) { Accessible accessible = (Accessible) e.getSource(); ToolBar toolBar = (ToolBar) accessible.getControl(); if (0 <= e.childID && e.childID < toolBar.getItemCount()) { ToolItem item = toolBar.getItem(e.childID); if (item != null) { e.result = item.getToolTipText(); } } } } }); } protected void setTip(String tip) { tipLabel.setText(tip == null ? "" : tip); //$NON-NLS-1$ Composite tipComposite = tipLabel.getParent(); tipComposite.setVisible(tip != null && !tip.equals("")); //$NON-NLS-1$ ((GridData) tipComposite.getLayoutData()).exclude = !tipComposite .getVisible(); adjustRightBar(); } private void adjustRightBar() { rightBar.setVisible( tipLabel.getParent().getVisible() || menuBar.getVisible()); rightBar.pack(true); } protected void showViewMenu(ToolItem item) { MPart part = getAdapter(MPart.class); if (part == null) return; Control ctrl = (Control) part.getWidget(); MMenu menuModel = getViewMenu(part); if (menuModel == null || !menuModel.isToBeRendered()) return; final Menu swtMenu = (Menu) part.getContext() .get(IPresentationEngine.class) .createGui(menuModel, ctrl.getShell(), part.getContext()); if (swtMenu == null) return; ctrl.addDisposeListener(new DisposeListener() { public void widgetDisposed(DisposeEvent e) { if (!swtMenu.isDisposed()) { swtMenu.dispose(); } } }); // ...and Show it... Rectangle ib = item.getBounds(); Point displayAt = item.getParent().toDisplay(ib.x, ib.y + ib.height); swtMenu.setLocation(displayAt); swtMenu.setVisible(true); Display display = swtMenu.getDisplay(); while (!swtMenu.isDisposed() && swtMenu.isVisible()) { if (!display.readAndDispatch()) display.sleep(); } if (!swtMenu.isDisposed() && !(swtMenu.getData() instanceof MenuManager)) { swtMenu.dispose(); } } /** * @param visibleOrEnable * true is to setVisible, otherwise to setEnable. */ protected void adjustViewMenuBar(boolean visibleOrEnable) { if (adjusting) return; if (menuBar == null) return; adjusting = true; MPart part = getAdapter(MPart.class); MMenu viewMenu = getViewMenu(part); boolean needsMenu = viewMenu != null && hasVisibleMenuItems(viewMenu, part); if (visibleOrEnable) { menuBar.setVisible(needsMenu); ((GridData) menuBar.getLayoutData()).exclude = !menuBar .getVisible(); } else { viewMenuTB.setEnabled(needsMenu); } adjustRightBar(); adjusting = false; } @SuppressWarnings("restriction") private boolean hasVisibleMenuItems(MMenu viewMenu, MPart part) { if (!viewMenu.isToBeRendered() || !viewMenu.isVisible()) { return false; } for (MMenuElement menuElement : viewMenu.getChildren()) { if (menuElement.isToBeRendered() && menuElement.isVisible()) { if (OpaqueElementUtil.isOpaqueMenuItem(menuElement) || OpaqueElementUtil .isOpaqueMenuSeparator(menuElement)) { IContributionItem item = (IContributionItem) OpaqueElementUtil .getOpaqueItem(menuElement); if (item != null && item.isVisible()) { return true; } } else { return true; } } } Object menuRenderer = viewMenu.getRenderer(); if (menuRenderer instanceof MenuManagerRenderer) { MenuManager manager = ((MenuManagerRenderer) menuRenderer) .getManager(viewMenu); if (manager != null && manager.isVisible()) { return true; } } Control control = (Control) part.getWidget(); if (control != null) { Menu menu = (Menu) part.getContext().get(IPresentationEngine.class) .createGui(viewMenu, control.getShell(), part.getContext()); if (menu != null) { menuRenderer = viewMenu.getRenderer(); if (menuRenderer instanceof MenuManagerRenderer) { MenuManagerRenderer menuManagerRenderer = (MenuManagerRenderer) menuRenderer; MenuManager manager = menuManagerRenderer .getManager(viewMenu); if (manager != null) { // remark ourselves as dirty so that the menu will be // reconstructed manager.markDirty(); } } return menu.getItemCount() != 0; } } return false; } protected MMenu getViewMenu(MPart part) { if (part == null || part.getMenus() == null) { return null; } for (MMenu menu : part.getMenus()) { boolean viewMenu = menu.getTags().contains(TAG_VIEW_MENU); if (viewMenu) { return menu; } } return null; } }