1 /* 2 * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.apple.laf; 27 28 import java.awt.Insets; 29 import java.util.*; 30 31 import javax.swing.*; 32 import javax.swing.border.Border; 33 34 import apple.laf.JRSUIConstants.*; 35 36 import com.apple.laf.AquaUtilControlSize.*; 37 import com.apple.laf.AquaUtils.RecyclableSingleton; 38 39 import static apple.laf.JRSUIConstants.FOCUS_SIZE; 40 41 /** 42 * All the "magic numbers" in this class should go away once 43 * <rdar://problem/4613866> "default font" and sizes for controls in Java Aqua Look and Feel 44 * has been addressed, and we can cull widget metrics from the native system. 45 */ 46 public class AquaButtonExtendedTypes { 47 protected static Border getBorderForPosition(final AbstractButton c, final Object type, final Object logicalPosition) { 48 final String name = (logicalPosition == null ? (String)type : type + "-" + getRealPositionForLogicalPosition((String)logicalPosition, c.getComponentOrientation().isLeftToRight())); 49 final TypeSpecifier specifier = getSpecifierByName(name); 50 if (specifier == null) return null; 51 52 final Border border = specifier.getBorder(); 53 if (!(border instanceof AquaBorder)) return border; 54 55 return ((AquaBorder)border).deriveBorderForSize(AquaUtilControlSize.getUserSizeFrom(c)); 56 } 57 58 protected static String getRealPositionForLogicalPosition(String logicalPosition, boolean leftToRight) { 59 if (!leftToRight) { 60 if ("first".equalsIgnoreCase(logicalPosition)) return "last"; 61 if ("last".equalsIgnoreCase(logicalPosition)) return "first"; 62 } 63 return logicalPosition; 64 } 65 66 static abstract class TypeSpecifier { 67 final String name; 68 final boolean setIconFont; 69 70 TypeSpecifier(final String name, final boolean setIconFont) { 71 this.name = name; this.setIconFont = setIconFont; 72 } 73 74 abstract Border getBorder(); 75 } 76 77 static class BorderDefinedTypeSpecifier extends TypeSpecifier { 78 final AquaBorder border; 79 80 BorderDefinedTypeSpecifier(final String name, final Widget widget, final SizeVariant variant) { 81 this(name, widget, variant, 0, 0, 0, 0); 82 } 83 84 BorderDefinedTypeSpecifier(final String name, final Widget widget, final SizeVariant variant, final int smallW, final int smallH, final int miniW, final int miniH) { 85 super(name, false); 86 border = initBorder(widget, new SizeDescriptor(variant) { 87 public SizeVariant deriveSmall(final SizeVariant v) { 88 v.alterMinSize(smallW, smallH); 89 return super.deriveSmall(v); 90 } 91 public SizeVariant deriveMini(final SizeVariant v) { 92 v.alterMinSize(miniW, miniH); 93 return super.deriveMini(v); 94 } 95 }); 96 patchUp(border.sizeDescriptor); 97 } 98 99 Border getBorder() { return border; } 100 void patchUp(final SizeDescriptor descriptor) {} 101 102 AquaBorder initBorder(final Widget widget, final SizeDescriptor desc) { 103 return new AquaButtonBorder.Named(widget, desc); 104 } 105 } 106 107 static class SegmentedBorderDefinedTypeSpecifier extends BorderDefinedTypeSpecifier { 108 public SegmentedBorderDefinedTypeSpecifier(final String name, final Widget widget, final SegmentPosition position, final SizeVariant variant) { 109 this(name, widget, position, variant, 0, 0, 0, 0); 110 } 111 112 public SegmentedBorderDefinedTypeSpecifier(final String name, final Widget widget, final SegmentPosition position, final SizeVariant variant, final int smallW, final int smallH, final int miniW, final int miniH) { 113 super(name, widget, variant, smallW, smallH, miniW, miniH); 114 border.painter.state.set(SegmentTrailingSeparator.YES); 115 border.painter.state.set(position); 116 } 117 118 AquaBorder initBorder(final Widget widget, final SizeDescriptor desc) { 119 return new SegmentedNamedBorder(widget, desc); 120 } 121 } 122 123 public static class SegmentedNamedBorder extends AquaButtonBorder.Named { 124 public SegmentedNamedBorder(final SegmentedNamedBorder sizeDescriptor) { 125 super(sizeDescriptor); 126 } 127 128 public SegmentedNamedBorder(final Widget widget, final SizeDescriptor sizeDescriptor) { 129 super(widget, sizeDescriptor); 130 } 131 132 protected boolean isSelectionPressing() { 133 return false; 134 } 135 } 136 137 protected static TypeSpecifier getSpecifierByName(final String name) { 138 return typeDefinitions.get().get(name); 139 } 140 141 protected final static RecyclableSingleton<Map<String, TypeSpecifier>> typeDefinitions = new RecyclableSingleton<Map<String, TypeSpecifier>>() { 142 protected Map<String, TypeSpecifier> getInstance() { 143 return getAllTypes(); 144 } 145 }; 146 147 protected static Map<String, TypeSpecifier> getAllTypes() { 148 final Map<String, TypeSpecifier> specifiersByName = new HashMap<String, TypeSpecifier>(); 149 150 final Insets focusInsets = new Insets(FOCUS_SIZE, FOCUS_SIZE, 151 FOCUS_SIZE, FOCUS_SIZE); 152 153 final TypeSpecifier[] specifiers = { 154 new TypeSpecifier("toolbar", true) { 155 Border getBorder() { return AquaButtonBorder.getToolBarButtonBorder(); } 156 }, 157 new TypeSpecifier("icon", true) { 158 Border getBorder() { return AquaButtonBorder.getToggleButtonBorder(); } 159 }, 160 new TypeSpecifier("text", false) { 161 Border getBorder() { return UIManager.getBorder("Button.border"); } 162 }, 163 new TypeSpecifier("toggle", false) { 164 Border getBorder() { return AquaButtonBorder.getToggleButtonBorder(); } 165 }, 166 new BorderDefinedTypeSpecifier("combobox", Widget.BUTTON_POP_DOWN, new SizeVariant().alterMargins(7, 10, 6, 30).alterInsets(1, 2, 0, 2).alterMinSize(0, 29), 0, -3, 0, -6) { 167 void patchUp(final SizeDescriptor descriptor) { descriptor.small.alterMargins(0, 0, 0, -4); descriptor.mini.alterMargins(0, 0, 0, -6); } 168 }, 169 new BorderDefinedTypeSpecifier("comboboxInternal", Widget.BUTTON_POP_DOWN, new SizeVariant().alterInsets(1, 2, 0, 2).alterMinSize(0, 29), 0, -3, 0, -6), 170 new BorderDefinedTypeSpecifier("comboboxEndCap", Widget.BUTTON_COMBO_BOX, new SizeVariant().alterMargins(5, 10, 6, 10).alterInsets(1, 2, 0, 2).alterMinSize(0, 29), 0, -3, 0, -6){ 171 void patchUp(final SizeDescriptor descriptor) { border.painter.state.set(IndicatorOnly.YES); } 172 }, 173 174 new BorderDefinedTypeSpecifier("square", Widget.BUTTON_BEVEL, new SizeVariant(16, 16).alterMargins(5, 7, 5, 7).replaceInsets(focusInsets)), 175 new BorderDefinedTypeSpecifier("gradient", Widget.BUTTON_BEVEL_INSET, new SizeVariant(18, 18).alterMargins(8, 9, 8, 9).replaceInsets(focusInsets)) { 176 void patchUp(SizeDescriptor descriptor) { descriptor.small.alterMargins(0, 0, 0, 0); } 177 }, 178 new BorderDefinedTypeSpecifier("bevel", Widget.BUTTON_BEVEL_ROUND, new SizeVariant(22, 22).alterMargins(7, 8, 9, 8).alterInsets(0, 0, 0, 0)), 179 180 new BorderDefinedTypeSpecifier("textured", Widget.BUTTON_PUSH_TEXTURED, new SizeVariant(28, 28).alterMargins(5, 10, 6, 10).alterInsets(1, 2, 0, 2)), 181 new BorderDefinedTypeSpecifier("roundRect", Widget.BUTTON_PUSH_INSET, new SizeVariant(28, 28).alterMargins(4, 14, 4, 14).replaceInsets(focusInsets)), 182 new BorderDefinedTypeSpecifier("recessed", Widget.BUTTON_PUSH_SCOPE, new SizeVariant(28, 28).alterMargins(4, 14, 4, 14).replaceInsets(focusInsets)), 183 184 new BorderDefinedTypeSpecifier("well", Widget.FRAME_WELL, new SizeVariant(32, 32)), 185 186 new BorderDefinedTypeSpecifier("help", Widget.BUTTON_ROUND_HELP, new SizeVariant().alterInsets(2, 0, 0, 0).alterMinSize(28, 28), -3, -3, -3, -3), 187 new BorderDefinedTypeSpecifier("round", Widget.BUTTON_ROUND, new SizeVariant().alterInsets(2, 0, 0, 0).alterMinSize(28, 28), -3, -3, -3, -3), 188 new BorderDefinedTypeSpecifier("texturedRound", Widget.BUTTON_ROUND_INSET, new SizeVariant().alterInsets(0, 0, 0, 0).alterMinSize(26, 26), -2, -2, 0, 0), 189 190 new SegmentedBorderDefinedTypeSpecifier("segmented-first", Widget.BUTTON_SEGMENTED, SegmentPosition.FIRST, new SizeVariant().alterMargins(6, 16, 6, 10).alterInsets(2, 3, 2, 0).alterMinSize(0, 28), 0, -3, 0, -3), 191 new SegmentedBorderDefinedTypeSpecifier("segmented-middle", Widget.BUTTON_SEGMENTED, SegmentPosition.MIDDLE, new SizeVariant().alterMargins(6, 9, 6, 10).alterInsets(2, 0, 2, 0).alterMinSize(0, 28), 0, -3, 0, -3), 192 new SegmentedBorderDefinedTypeSpecifier("segmented-last", Widget.BUTTON_SEGMENTED, SegmentPosition.LAST, new SizeVariant().alterMargins(6, 9, 6, 16).alterInsets(2, 0, 2, 3).alterMinSize(0, 28), 0, -3, 0, -3), 193 new SegmentedBorderDefinedTypeSpecifier("segmented-only", Widget.BUTTON_SEGMENTED, SegmentPosition.ONLY, new SizeVariant().alterMargins(6, 16, 6, 16).alterInsets(2, 3, 2, 3).alterMinSize(34, 28), 0, -3, 0, -3), 194 195 new SegmentedBorderDefinedTypeSpecifier("segmentedRoundRect-first", Widget.BUTTON_SEGMENTED_INSET, SegmentPosition.FIRST, new SizeVariant().alterMargins(6, 12, 6, 8).alterInsets(2, 2, 2, 0).alterMinSize(0, 28), 0, -3, 0, -3), 196 new SegmentedBorderDefinedTypeSpecifier("segmentedRoundRect-middle", Widget.BUTTON_SEGMENTED_INSET, SegmentPosition.MIDDLE, new SizeVariant().alterMargins(6, 8, 6, 8).alterInsets(2, 0, 2, 0).alterMinSize(0, 28), 0, -3, 0, -3), 197 new SegmentedBorderDefinedTypeSpecifier("segmentedRoundRect-last", Widget.BUTTON_SEGMENTED_INSET, SegmentPosition.LAST, new SizeVariant().alterMargins(6, 8, 6, 12).alterInsets(2, 0, 2, 2).alterMinSize(0, 28), 0, -3, 0, -3), 198 new SegmentedBorderDefinedTypeSpecifier("segmentedRoundRect-only", Widget.BUTTON_SEGMENTED_INSET, SegmentPosition.ONLY, new SizeVariant().alterMargins(6, 12, 6, 12).alterInsets(2, 2, 2, 2).alterMinSize(0, 28), 0, -3, 0, -3), 199 200 new SegmentedBorderDefinedTypeSpecifier("segmentedTexturedRounded-first", Widget.BUTTON_SEGMENTED_SCURVE, SegmentPosition.FIRST, new SizeVariant().alterMargins(6, 12, 6, 8).alterInsets(2, 2, 2, 0).alterMinSize(0, 28), 0, -3, 0, -3), 201 new SegmentedBorderDefinedTypeSpecifier("segmentedTexturedRounded-middle", Widget.BUTTON_SEGMENTED_SCURVE, SegmentPosition.MIDDLE, new SizeVariant().alterMargins(6, 8, 6, 8).alterInsets(2, 0, 2, 0).alterMinSize(0, 28), 0, -3, 0, -3), 202 new SegmentedBorderDefinedTypeSpecifier("segmentedTexturedRounded-last", Widget.BUTTON_SEGMENTED_SCURVE, SegmentPosition.LAST, new SizeVariant().alterMargins(6, 8, 6, 12).alterInsets(2, 0, 2, 2).alterMinSize(0, 28), 0, -3, 0, -3), 203 new SegmentedBorderDefinedTypeSpecifier("segmentedTexturedRounded-only", Widget.BUTTON_SEGMENTED_SCURVE, SegmentPosition.ONLY, new SizeVariant().alterMargins(6, 12, 6, 12).alterInsets(2, 2, 2, 2).alterMinSize(0, 28), 0, -3, 0, -3), 204 205 new SegmentedBorderDefinedTypeSpecifier("segmentedTextured-first", Widget.BUTTON_SEGMENTED_TEXTURED, SegmentPosition.FIRST, new SizeVariant().alterMargins(6, 12, 6, 8).alterInsets(2, 3, 2, 0).alterMinSize(0, 28), 0, -3, 0, -3), 206 new SegmentedBorderDefinedTypeSpecifier("segmentedTextured-middle", Widget.BUTTON_SEGMENTED_TEXTURED, SegmentPosition.MIDDLE, new SizeVariant().alterMargins(6, 8, 6, 8).alterInsets(2, 0, 2, 0).alterMinSize(0, 28), 0, -3, 0, -3), 207 new SegmentedBorderDefinedTypeSpecifier("segmentedTextured-last", Widget.BUTTON_SEGMENTED_TEXTURED, SegmentPosition.LAST, new SizeVariant().alterMargins(6, 8, 6, 12).alterInsets(2, 0, 2, 3).alterMinSize(0, 28), 0, -3, 0, -3), 208 new SegmentedBorderDefinedTypeSpecifier("segmentedTextured-only", Widget.BUTTON_SEGMENTED_TEXTURED, SegmentPosition.ONLY, new SizeVariant().alterMargins(6, 12, 6, 12).alterInsets(2, 3, 2, 3).alterMinSize(0, 28), 0, -3, 0, -3), 209 210 new SegmentedBorderDefinedTypeSpecifier("segmentedCapsule-first", Widget.BUTTON_SEGMENTED_TOOLBAR, SegmentPosition.FIRST, new SizeVariant().alterMargins(6, 12, 6, 8).alterInsets(2, 2, 2, 0).alterMinSize(0, 28), 0, 0, 0, 0), 211 new SegmentedBorderDefinedTypeSpecifier("segmentedCapsule-middle", Widget.BUTTON_SEGMENTED_TOOLBAR, SegmentPosition.MIDDLE, new SizeVariant().alterMargins(6, 8, 6, 8).alterInsets(2, 0, 2, 0).alterMinSize(0, 28), 0, 0, 0, 0), 212 new SegmentedBorderDefinedTypeSpecifier("segmentedCapsule-last", Widget.BUTTON_SEGMENTED_TOOLBAR, SegmentPosition.LAST, new SizeVariant().alterMargins(6, 8, 6, 12).alterInsets(2, 0, 2, 2).alterMinSize(0, 28), 0, 0, 0, 0), 213 new SegmentedBorderDefinedTypeSpecifier("segmentedCapsule-only", Widget.BUTTON_SEGMENTED_TOOLBAR, SegmentPosition.ONLY, new SizeVariant().alterMargins(6, 12, 6, 12).alterInsets(2, 2, 2, 2).alterMinSize(34, 28), 0, 0, 0, 0), 214 215 new BorderDefinedTypeSpecifier("segmentedGradient-first", Widget.BUTTON_BEVEL_INSET, new SizeVariant(18, 18).alterMargins(4, 5, 4, 5).replaceInsets(new Insets(-2,-0,-2,-0))), 216 new BorderDefinedTypeSpecifier("segmentedGradient-middle", Widget.BUTTON_BEVEL_INSET, new SizeVariant(18, 18).alterMargins(4, 5, 4, 5).replaceInsets(new Insets(-2,-1,-2,-0))), 217 new BorderDefinedTypeSpecifier("segmentedGradient-last", Widget.BUTTON_BEVEL_INSET, new SizeVariant(18, 18).alterMargins(4, 5, 4, 5).replaceInsets(new Insets(-2,-1,-2,-0))), 218 new BorderDefinedTypeSpecifier("segmentedGradient-only", Widget.BUTTON_BEVEL_INSET, new SizeVariant(18, 18).alterMargins(4, 5, 4, 5).replaceInsets(new Insets(-2,-1,-2,-1))), 219 220 new BorderDefinedTypeSpecifier("disclosure", Widget.BUTTON_DISCLOSURE, new SizeVariant().alterMargins(10, 10, 10, 10).replaceInsets(focusInsets).alterMinSize(27, 27), -1, -1, -1, -1), 221 222 //new BorderDefinedTypeSpecifier("disclosureTriangle", false, Widget.DISCLOSURE_TRIANGLE, new SizeVariant()), 223 new BorderDefinedTypeSpecifier("scrollColumnSizer", Widget.SCROLL_COLUMN_SIZER, new SizeVariant(14, 14)), 224 }; 225 226 for (final TypeSpecifier specifier : specifiers) { 227 specifiersByName.put(specifier.name, specifier); 228 } 229 230 return specifiersByName; 231 } 232 }