/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* AquaMenuPainter, implements paintMenuItem to avoid code duplication
*
* BasicMenuItemUI didn't factor out the various parts of the Menu, and
* we subclass it and its subclasses BasicMenuUI
* Our classes need an implementation of paintMenuItem
* that allows them to paint their own backgrounds
*/
public class AquaMenuPainter {
// Glyph statics:
// ASCII character codes
static final byte
// Unicode character codes
static final char
static final int sUnsupportedModifiersMask = ~(InputEvent.CTRL_MASK | InputEvent.ALT_MASK | InputEvent.SHIFT_MASK | InputEvent.META_MASK | ALT_GRAPH_MASK);
interface Client {
}
// Return a string with the proper modifier glyphs
}
// Return a string with the proper modifier glyphs
// Order (from StandardMenuDef.c): control, option(alt), shift, cmd
// reverse for right-to-left
//$ check for substitute key glyphs for localization
if (isLeftToRight) {
}
}
}
}
} else {
}
}
}
}
}
}
static final RecyclableSingleton<AquaMenuPainter> sPainter = new RecyclableSingletonFromDefaultConstructor<AquaMenuPainter>(AquaMenuPainter.class);
}
static final int kAcceleratorArrowSpace = 16; // Accel space doesn't overlap arrow space, even though items can't have both
}
protected final RecyclableBorder menuBarPainter = new RecyclableBorder("MenuBar.backgroundPainter");
protected final RecyclableBorder selectedMenuBarItemPainter = new RecyclableBorder("MenuBar.selectedBackgroundPainter");
protected final RecyclableBorder selectedMenuItemPainter = new RecyclableBorder("MenuItem.selectedBackgroundPainter");
public void paintMenuBarBackground(final Graphics g, final int width, final int height, final JComponent c) {
}
}
}
protected void paintMenuItem(final Client client, final Graphics g, final JComponent c, final Icon checkIcon, final Icon arrowIcon, final Color background, final Color foreground, final Color disabledForeground, final Color selectionForeground, final int defaultTextIconGap, final Font acceleratorFont) {
// Dimension size = b.getSize();
final int menuHeight = b.getHeight();
g.setFont(f);
// Paint background (doesn't touch the Graphics object's color)
if (c.isOpaque()) {
}
// get Accelerator text
if (accelerator != null) {
if (modifiers > 0) {
}
if (keyCode != 0) {
} else {
}
}
// layout the text and icon
final String text = layoutMenuItem(b, fm, b.getText(), fmAccel, keyString, modifiersString, b.getIcon(), checkIcon, arrowIcon, b.getVerticalAlignment(), b.getHorizontalAlignment(), b.getVerticalTextPosition(), b.getHorizontalTextPosition(), viewRect, iconRect, textRect, acceleratorRect, checkIconRect, arrowIconRect, b.getText() == null ? 0 : defaultTextIconGap, defaultTextIconGap);
// if this is in a AquaScreenMenuBar that's attached to a DialogPeer
// the native menu will be disabled, though the awt Menu won't know about it
// so the JPopupMenu will not have visibility set and the items should draw disabled
// If it's not on a JPopupMenu then it should just use the model's enable state
boolean isSelected = false;
if (!isEnabled) {
// *** paint the text disabled
} else {
// *** paint the text normally
isSelected = true;
} else {
g.setColor(parentIsMenuBar ? parent.getForeground() : b.getForeground()); // Which is either MenuItem.foreground or the user's choice
}
}
// We want to paint the icon after the text color is set since some icon painting depends on the correct
// graphics color being set
// See <rdar://problem/3792383> Menu icons missing in Java2D's Lines.Joins demo
// Paint the Icon
}
// Paint the Check using the current text color
}
// Draw the accelerator first in case the HTML renderer changes the color
// just draw the keyString
} else {
int underlinedChar = 0;
if ((modifiers & ALT_GRAPH_MASK) > 0) underlinedChar = kUOptionGlyph; // This is a Java2 thing, we won't be getting kOptionGlyph
// The keyStrings should all line up, so always adjust the width by the same amount
// (if they're multi-char, they won't line up but at least they won't be cut off)
if (leftToRight) {
drawString(g, c, modifiersString, underlinedChar, acceleratorRect.x, yAccel, isEnabled, isSelected);
g.setFont(f);
SwingUtilities2.drawString(c, g, keyString, acceleratorRect.x + acceleratorRect.width - emWidth, yAccel);
} else {
g.setFont(f);
}
}
}
// Draw the Text
if (v != null) {
} else {
}
}
// Paint the Arrow
}
}
// All this had to be copied from BasicMenuItemUI, just to get the right keyModifiersText fn
// and a few Mac tweaks
protected Dimension getPreferredMenuItemSize(final JComponent c, final Icon checkIcon, final Icon arrowIcon, final int defaultTextIconGap, final Font acceleratorFont) {
if (accelerator != null) {
if (modifiers > 0) {
}
if (keyCode != 0) {
} else {
}
}
layoutMenuItem(b, fm, text, fmAccel, keyString, modifiersString, icon, checkIcon, arrowIcon, b.getVerticalAlignment(), b.getHorizontalAlignment(), b.getVerticalTextPosition(), b.getHorizontalTextPosition(), viewRect, iconRect, textRect, acceleratorRect, checkIconRect, arrowIconRect, text == null ? 0 : defaultTextIconGap, defaultTextIconGap);
// find the union of the icon and text rects
// r = iconRect.union(textRect);
// Add in the accelerator
if (!acceleratorTextIsEmpty) {
}
if (!isTopLevelMenu(b)) {
// Add in the checkIcon
r.width += defaultTextIconGap;
// Add in the arrowIcon space
r.width += defaultTextIconGap;
}
}
// Tweak for Mac
return r.getSize();
}
protected void paintCheck(final Graphics g, final JMenuItem item, Icon checkIcon, Rectangle checkIconRect) {
} else {
}
}
protected void paintIcon(final Graphics g, final JMenuItem c, final Rectangle localIconRect, boolean isEnabled) {
if (!isEnabled) {
icon = c.getDisabledIcon();
icon = c.getPressedIcon();
// Use default icon
}
} else {
}
}
protected void paintArrow(Graphics g, JMenuItem c, ButtonModel model, Icon arrowIcon, Rectangle arrowIconRect) {
if (isTopLevelMenu(c)) return;
if (c instanceof JMenu && (model.isArmed() || model.isSelected()) && arrowIcon instanceof InvertableIcon) {
} else {
}
}
/** Draw a string with the graphics g at location (x,y) just like g.drawString() would.
* The first occurence of underlineChar in text will be underlined. The matching is
* not case sensitive.
*/
public void drawString(final Graphics g, final JComponent c, final String text, final int underlinedChar, final int x, final int y, final boolean isEnabled, final boolean isSelected) {
if (underlinedChar != '\0') {
}
}
/*
* Returns false if the component is a JMenu and it is a top
* level menu (on the menubar).
*/
}
private String layoutMenuItem(final JMenuItem menuItem, final FontMetrics fm, final String text, final FontMetrics fmAccel, String keyString, final String modifiersString, final Icon icon, final Icon checkIcon, final Icon arrowIcon, final int verticalAlignment, final int horizontalAlignment, final int verticalTextPosition, final int horizontalTextPosition, final Rectangle viewR, final Rectangle iconR, final Rectangle textR, final Rectangle acceleratorR, final Rectangle checkIconR, final Rectangle arrowIconR, final int textIconGap, final int menuItemGap) {
// Force it to do "LEFT", then flip the rects if we're right-to-left
SwingUtilities.layoutCompoundLabel(menuItem, fm, text, icon, verticalAlignment, SwingConstants.LEFT, verticalTextPosition, horizontalTextPosition, viewR, iconR, textR, textIconGap);
if (acceleratorTextIsEmpty) {
keyString = "";
} else {
// Accel space doesn't overlap arrow space, even though items can't have both
// The keyStrings should all line up, so always adjust the width by the same amount
// (if they're multi-char, they won't line up but at least they won't be cut off)
acceleratorR.width += Math.max(fm.charWidth('M'), SwingUtilities.computeStringWidth(fm, keyString));
}
/* Initialize the checkIcon bounds rectangle checkIconR.
*/
if (!isTopLevelMenu) {
} else {
}
/* Initialize the arrowIcon bounds rectangle arrowIconR.
*/
} else {
}
textR.x += 12;
iconR.x += 12;
}
// Position the Accelerator text rect
// Menu shortcut text *ought* to have the letters left-justified - look at a menu with an "M" in it
if (!isTopLevelMenu) {
// if ( GetSysDirection() < 0 ) hierRect.right = hierRect.left + w + 4;
// else hierRect.left = hierRect.right - w - 4;
checkIconR.x = 5;
}
/*System.out.println("Layout: " +horizontalAlignment+ " v=" +viewR+" c="+checkIconR+" i="+
iconR+" t="+textR+" acc="+acceleratorR+" a="+arrowIconR);*/
// Flip the rectangles so that instead of [check][icon][text][accel/arrow] it's [accel/arrow][text][icon][check]
}
textR.x += menuItemGap;
iconR.x += menuItemGap;
return text;
}
return border;
}
return border;
}
return border;
}
}