/******************************************************************************* * Copyright (c) Emil Crumhorn - Hexapixel.com - emil.crumhorn@gmail.com * 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: * emil.crumhorn@gmail.com - initial API and implementation *******************************************************************************/ package com.hexapixel.widgets.ribbon; import java.util.List; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import com.hexapixel.widgets.generic.ColorCache; import com.hexapixel.widgets.generic.ImageCache; public abstract class AbstractShellPainter { public static Color outerBorderNonMaximized = ColorCache.getInstance().getColor(59, 90, 130); public static Color outerBorderNonMaximized_Inactive = ColorCache.getInstance().getColor(151, 165, 183); // top menu bar background private Color veryTopBorderTopTop_1 = ColorCache.getInstance().getColor(227, 235, 246); private Color veryTopBorderTopBottom_1 = ColorCache.getInstance().getColor(218, 233, 233); private Color veryTopBorderTopTop_2 = ColorCache.getInstance().getColor(213, 229, 250); private Color veryTopBorderTopBottom_2 = ColorCache.getInstance().getColor(217, 231, 249); private Color veryTopBorderBottomTop = ColorCache.getInstance().getColor(202, 222, 247); private Color veryTopBorderBottomBottom = ColorCache.getInstance().getColor(228, 239, 253); private Color veryTopBorderBottomLine = ColorCache.getInstance().getColor(219, 244, 254); // top menu bar background - inactive private Color veryTopBorderTopTop_1_Inactive = ColorCache.getInstance().getColor(227, 231, 236); private Color veryTopBorderTopBottom_1_Inactive = ColorCache.getInstance().getColor(223, 230, 239); private Color veryTopBorderTopTop_2_Inactive = ColorCache.getInstance().getColor(221, 228, 237); private Color veryTopBorderTopBottom_2_Inactive = ColorCache.getInstance().getColor(222, 229, 237); private Color veryTopBorderBottomTop_Inactive = ColorCache.getInstance().getColor(216, 225, 236); private Color veryTopBorderBottomBottom_Inactive = ColorCache.getInstance().getColor(227, 232, 239); private Color veryTopBorderBottomLine_Inactive = ColorCache.getInstance().getColor(223, 235, 239); // text colors private Color shellTextColorFadedRight = ColorCache.getInstance().getColor(162, 211, 249); private Color shellTextColorFadedLeft = ColorCache.getInstance().getColor(215, 230, 211); private Color shellTextColor = ColorCache.getInstance().getColor(105, 112, 121); private Color shellTextColorFadedRight_Inactive = ColorCache.getInstance().getColor(192, 217, 237); private Color shellTextColorFadedLeft_Inactive = ColorCache.getInstance().getColor(221, 228, 213); private Color shellTextColor_Inactive = ColorCache.getInstance().getColor(160, 160, 160); // toolbar private Color mToolbarOuterBorder = ColorCache.getInstance().getColor(246, 249, 252); private Color mToolbarBorder = ColorCache.getInstance().getColor(186, 204, 226); private Color mToolbarInnerBorder1 = ColorCache.getInstance().getColor(222, 231, 244); private Color mToolbarInnerBorder2 = ColorCache.getInstance().getColor(230, 238, 249); private Color mToolbarFillTopTop = ColorCache.getInstance().getColor(219, 231, 247); private Color mToolbarFillTopBottom = ColorCache.getInstance().getColor(199, 215, 237); private Color mToolbarFillBottomTop = mToolbarFillTopBottom; private Color mToolbarFillBottomBottom = ColorCache.getInstance().getColor(201, 217, 238); private Color mToolbarBottomBorder = ColorCache.getInstance().getColor(154, 179, 213); private int topHeight = 5; private int bottomHeight = 19; private RibbonShell mRibbonShell; private Shell mShell; private Rectangle mBounds; private boolean mShellMaximized; private boolean mShellInactive; private RibbonTabFolder mTabFolder; private Rectangle mToolbarBounds; public void paintShell(RibbonShell shell, GC gc) { mRibbonShell = shell; mShell = shell.getShell(); mTabFolder = shell.getRibbonTabFolder(); mShellMaximized = mRibbonShell.getMaximized(); mShellInactive = (Display.getDefault().getActiveShell() != mShell); mBounds = mShell.getBounds(); // menu bar drawShellMenuBar(gc); // shell text drawShellText(gc); // draw min, max, close, depending on shell settings as well drawMenuBarButtons(gc); // draw the "office" button //drawBigButton(gc); } private void drawShellMenuBar(GC gc) { // top border is bigger when non-maximized int y = 0; if (mShellMaximized) { if (mShellInactive) { gc.setForeground(veryTopBorderTopTop_1_Inactive); gc.setBackground(veryTopBorderTopBottom_1_Inactive); } else { gc.setForeground(veryTopBorderTopTop_1); gc.setBackground(veryTopBorderTopBottom_1); } gc.fillGradientRectangle(0, y, mBounds.width, topHeight, true); y += topHeight; } else { if (mShellInactive) { gc.setForeground(veryTopBorderTopTop_1_Inactive); gc.setBackground(veryTopBorderTopBottom_1_Inactive); } else { gc.setForeground(veryTopBorderTopTop_1); gc.setBackground(veryTopBorderTopBottom_1); } gc.fillGradientRectangle(0, y, mBounds.width, topHeight, true); if (mShellInactive) gc.setForeground(outerBorderNonMaximized_Inactive); else gc.setForeground(outerBorderNonMaximized); gc.drawLine(0, 0, mBounds.width, 0); y += topHeight; if (mShellInactive) { gc.setForeground(veryTopBorderTopTop_2_Inactive); gc.setBackground(veryTopBorderTopBottom_2_Inactive); } else { gc.setForeground(veryTopBorderTopTop_2); gc.setBackground(veryTopBorderTopBottom_2); } gc.fillGradientRectangle(0, y, mBounds.width, topHeight-1, true); y += topHeight-1; } if (mShellInactive) { gc.setForeground(veryTopBorderBottomTop_Inactive); gc.setBackground(veryTopBorderBottomBottom_Inactive); } else { gc.setForeground(veryTopBorderBottomTop); gc.setBackground(veryTopBorderBottomBottom); } gc.fillGradientRectangle(0, y, mBounds.width, bottomHeight, true); y += bottomHeight; if (mShellInactive) gc.setForeground(veryTopBorderBottomLine_Inactive); else gc.setForeground(veryTopBorderBottomLine); gc.drawLine(0, y, mBounds.width, y); } private void drawShellText(GC gc) { int y = mShellMaximized ? 7 : 9; String toDraw = mShell.getText(); if (toDraw == null || toDraw.length() == 0) return; Font font = gc.getFont(); Font toUse = new Font(gc.getDevice(), font.getFontData()[0].getName(), 9, font.getFontData()[0].getStyle()); gc.setFont(toUse); Point extent = gc.stringExtent(toDraw); int midPoint = (mBounds.width/2) - (extent.x/2); // don't let menu bar text draw on the toolbar area, with a little spacing if (mToolbarBounds != null) { //System.err.println((midPoint-1+5) + " < " + mToolbarBounds.x+) if ((midPoint-1+5) < (mToolbarBounds.x+mToolbarBounds.width)) { midPoint = mToolbarBounds.x + mToolbarBounds.width + 5; } } if (mShellInactive) gc.setForeground(shellTextColorFadedRight_Inactive); else gc.setForeground(shellTextColorFadedRight); gc.drawString(toDraw, midPoint+1, y, true); if (mShellInactive) gc.setForeground(shellTextColorFadedLeft_Inactive); else gc.setForeground(shellTextColorFadedLeft); gc.drawString(toDraw, midPoint-1, y, true); if (mShellInactive) gc.setForeground(shellTextColor_Inactive); else gc.setForeground(shellTextColor); gc.drawString(toDraw, midPoint, y, true); toUse.dispose(); gc.setFont(font); } private void drawMenuBarButtons(GC gc) { Image minImage = null; Image maxImage = null; Image closeImage = null; switch (mTabFolder.getMinButtonState()) { default: case RibbonTabFolder.STATE_NONE: minImage = ImageCache.getImage("mb_min.gif"); break; case RibbonTabFolder.STATE_INACTIVE: minImage = ImageCache.getImage("mb_min_inactive.gif"); break; case RibbonTabFolder.STATE_HOVER: minImage = ImageCache.getImage("mb_min_hover.gif"); break; case RibbonTabFolder.STATE_HOVER_SELECTED: minImage = ImageCache.getImage("mb_min_hover_selected.gif"); break; } switch (mTabFolder.getMaxButtonState()) { default: case RibbonTabFolder.STATE_NONE: if (mRibbonShell.getMaximized()) maxImage = ImageCache.getImage("mb_restore.gif"); else maxImage = ImageCache.getImage("mb_max.gif"); break; case RibbonTabFolder.STATE_INACTIVE: if (mRibbonShell.getMaximized()) maxImage = ImageCache.getImage("mb_restore_inactive.gif"); else maxImage = ImageCache.getImage("mb_max_inactive.gif"); break; case RibbonTabFolder.STATE_HOVER: if (mRibbonShell.getMaximized()) maxImage = ImageCache.getImage("mb_restore_hover.gif"); else maxImage = ImageCache.getImage("mb_max_hover.gif"); break; case RibbonTabFolder.STATE_HOVER_SELECTED: if (mRibbonShell.getMaximized()) maxImage = ImageCache.getImage("mb_restore_hover_selected.gif"); else maxImage = ImageCache.getImage("mb_max_hover_selected.gif"); break; } switch (mTabFolder.getCloseButtonState()) { default: case RibbonTabFolder.STATE_NONE: closeImage = ImageCache.getImage("mb_close.gif"); break; case RibbonTabFolder.STATE_INACTIVE: closeImage = ImageCache.getImage("mb_close_inactive.gif"); break; case RibbonTabFolder.STATE_HOVER: closeImage = ImageCache.getImage("mb_close_hover.gif"); break; case RibbonTabFolder.STATE_HOVER_SELECTED: closeImage = ImageCache.getImage("mb_close_hover_selected.gif"); break; } Rectangle minBounds = mTabFolder.getMinButtonBounds(); Rectangle maxBounds = mTabFolder.getMaxButtonBounds(); Rectangle closeBounds = mTabFolder.getCloseButtonBounds(); if (minImage != null) gc.drawImage(minImage, minBounds.x, minBounds.y); if (maxImage != null) gc.drawImage(maxImage, maxBounds.x, maxBounds.y); if (closeImage != null) gc.drawImage(closeImage, closeBounds.x, closeBounds.y); } public void drawBigButton(GC gc) { Image toDraw = null; switch (mTabFolder.getBigButtonState()) { default: case RibbonTabFolder.STATE_NONE: case RibbonTabFolder.STATE_INACTIVE: toDraw = ImageCache.getImage("big_button.gif"); break; case RibbonTabFolder.STATE_HOVER: toDraw = ImageCache.getImage("big_button_hover.gif"); break; case RibbonTabFolder.STATE_HOVER_SELECTED: toDraw = ImageCache.getImage("big_button_hover_selected.gif"); break; } Rectangle bounds = mTabFolder.getBigButtonBounds(); // draw it gc.drawImage(toDraw, bounds.x, bounds.y); // draw the big button image on top, centered Image bigButtonImage = mRibbonShell.getButtonImage(); if (bigButtonImage != null) { Rectangle imBounds = bigButtonImage.getBounds(); int hSpacer = (bounds.width / 2) - (imBounds.width / 2); int vSpacer = (bounds.height / 2) - (imBounds.height / 2); gc.drawImage(bigButtonImage, bounds.x+hSpacer, bounds.y+vSpacer); } //gc.setBackground(ColorCache.getInstance().getBlack()); //gc.fillRectangle(bounds.x, bounds.y + 20, 38, 18); } public void drawMenubarToolbar(GC gc) { if (mRibbonShell.getToolbar() == null) return; Image leftSide = ImageCache.getImage("mb_tb_left.gif"); Image rightSide = ImageCache.getImage("mb_tb_right.gif"); Point start = mTabFolder.getMenubarToolbarLocation(); int x = start.x; int y = start.y; if (mRibbonShell.getMaximized()) y -= 1; gc.drawImage(leftSide, x, y); x += leftSide.getBounds().width; DefaultButtonPaintManager dpm = new DefaultButtonPaintManager(); // draw toolbar List<RibbonButton> buttons = mRibbonShell.getToolbar().getButtons(); int width = buttons.size() * RibbonGroup.TOOLBAR_BUTTON_WIDTH; int boundsX = x; int boundsY = y; // draw right side, as hovers may draw over gc.drawImage(rightSide, x+width, y); // draw background gc.setForeground(mToolbarOuterBorder); gc.drawLine(x, y, x+width, y); gc.setForeground(mToolbarBorder); gc.drawLine(x, y+1, x+width, y+1); gc.setForeground(mToolbarInnerBorder1); gc.drawLine(x, y+2, x+width, y+2); gc.setForeground(mToolbarInnerBorder2); gc.drawLine(x, y+3, x+width, y+3); gc.setForeground(mToolbarFillTopTop); gc.setBackground(mToolbarFillTopBottom); gc.fillGradientRectangle(x, y+4, width, 9, true); gc.setForeground(mToolbarFillBottomTop); gc.setBackground(mToolbarFillBottomBottom); gc.fillGradientRectangle(x, y+4+9, width, 9, true); gc.setForeground(mToolbarBottomBorder); gc.drawLine(x, y+4+9+9, x+width, y+4+9+9); for (int i = 0; i < buttons.size(); i++) { RibbonButton button = buttons.get(i); // we create the bounds for the button right here button.setBounds(new Rectangle(x, y+1, RibbonGroup.TOOLBAR_BUTTON_WIDTH, RibbonGroup.TOOLBAR_BUTTON_WIDTH)); dpm.drawMenuToolbarButton(gc, button); // we don't care what flags are set on toolbars, groups etc, in this toolbar we draw things only one way, plain and "simple" x += RibbonGroup.TOOLBAR_BUTTON_WIDTH; } // draw arrow button x += 12; y -= 1; Image arrowButton = null; switch (mRibbonShell.getArrowButtonState()) { default: case AbstractButtonPaintManager.STATE_NONE: arrowButton = ImageCache.getImage("mb_qtb_arrow.gif"); break; case AbstractButtonPaintManager.STATE_HOVER: arrowButton = ImageCache.getImage("mb_qtb_arrow_hover.gif"); break; case AbstractButtonPaintManager.STATE_SELECTED: case AbstractButtonPaintManager.STATE_HOVER_AND_SELECTED: arrowButton = ImageCache.getImage("mb_qtb_arrow_hover_selected.gif"); break; } Rectangle arrBounds = arrowButton.getBounds(); gc.drawImage(arrowButton, x, y); mRibbonShell.setArrowButtonBounds(new Rectangle(x, y, arrBounds.width, arrBounds.height)); int boundsWidth = x - boundsX + arrBounds.width; mToolbarBounds = new Rectangle(boundsX, boundsY, boundsWidth, RibbonGroup.TOOLBAR_BUTTON_HEIGHT); mRibbonShell.getRibbonTabFolder().setQuickAccessBounds(mToolbarBounds); } }