Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/macosx/classes/com/apple/laf/AquaButtonLabeledUI.java
41154 views
1
/*
2
* Copyright (c) 2011, 2021, 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.*;
29
import java.awt.image.BufferedImage;
30
31
import javax.swing.*;
32
import javax.swing.border.Border;
33
import javax.swing.plaf.UIResource;
34
import javax.swing.plaf.basic.BasicHTML;
35
import javax.swing.text.View;
36
37
import apple.laf.*;
38
import apple.laf.JRSUIConstants.*;
39
import apple.laf.JRSUIState.ValueState;
40
41
import com.apple.laf.AquaUtilControlSize.*;
42
import com.apple.laf.AquaUtils.RecyclableSingleton;
43
44
public abstract class AquaButtonLabeledUI extends AquaButtonToggleUI implements Sizeable {
45
private static final RecyclableSizingIcon regularIcon = new RecyclableSizingIcon(18);
46
private static final RecyclableSizingIcon smallIcon = new RecyclableSizingIcon(16);
47
private static final RecyclableSizingIcon miniIcon = new RecyclableSizingIcon(14);
48
49
protected static class RecyclableSizingIcon extends RecyclableSingleton<Icon> {
50
final int iconSize;
51
public RecyclableSizingIcon(final int iconSize) { this.iconSize = iconSize; }
52
53
protected Icon getInstance() {
54
return new ImageIcon(new BufferedImage(iconSize, iconSize, BufferedImage.TYPE_INT_ARGB_PRE));
55
}
56
}
57
58
protected AquaButtonBorder widgetBorder;
59
60
public AquaButtonLabeledUI() {
61
widgetBorder = getPainter();
62
}
63
64
public void applySizeFor(final JComponent c, final Size newSize) {
65
super.applySizeFor(c, newSize);
66
widgetBorder = (AquaButtonBorder)widgetBorder.deriveBorderForSize(newSize);
67
}
68
69
public Icon getDefaultIcon(final JComponent c) {
70
final Size componentSize = AquaUtilControlSize.getUserSizeFrom(c);
71
if (componentSize == Size.REGULAR) return regularIcon.get();
72
if (componentSize == Size.SMALL) return smallIcon.get();
73
if (componentSize == Size.MINI) return miniIcon.get();
74
return regularIcon.get();
75
}
76
77
protected void setThemeBorder(final AbstractButton b) {
78
super.setThemeBorder(b);
79
80
Border border = b.getBorder();
81
if (border == null || border instanceof UIResource) {
82
// Set the correct border
83
b.setBorder(AquaButtonBorder.getBevelButtonBorder());
84
}
85
}
86
87
protected abstract AquaButtonBorder getPainter();
88
89
public synchronized void paint(final Graphics g, final JComponent c) {
90
final AbstractButton b = (AbstractButton)c;
91
final ButtonModel model = b.getModel();
92
93
final Font f = c.getFont();
94
g.setFont(f);
95
final FontMetrics fm = g.getFontMetrics();
96
97
Dimension size = b.getSize();
98
99
final Insets i = c.getInsets();
100
101
Rectangle viewRect = new Rectangle(b.getWidth(), b.getHeight());
102
Rectangle iconRect = new Rectangle();
103
Rectangle textRect = new Rectangle();
104
105
Icon altIcon = b.getIcon();
106
107
final boolean isCellEditor = c.getParent() instanceof CellRendererPane;
108
109
// This was erroneously removed to fix [3155996] but really we wanted the controls to just be
110
// opaque. So we put this back in to fix [3179839] (radio buttons not being translucent)
111
if (b.isOpaque() || isCellEditor) {
112
g.setColor(b.getBackground());
113
g.fillRect(0, 0, size.width, size.height);
114
}
115
116
// only do this if borders are on!
117
if (((AbstractButton)c).isBorderPainted() && !isCellEditor) {
118
final Border border = c.getBorder();
119
if (border instanceof AquaButtonBorder) {
120
((AquaButtonBorder)border).paintButton(c, g, viewRect.x, viewRect.y, viewRect.width, viewRect.height);
121
}
122
}
123
124
viewRect.x = i.left;
125
viewRect.y = i.top;
126
viewRect.width = b.getWidth() - (i.right + viewRect.x);
127
viewRect.height = b.getHeight() - (i.bottom + viewRect.y);
128
129
// normal size ??
130
// at some point we substitute the small icon instead of the normal icon
131
// we should base this on height. Use normal unless we are under a certain size
132
// see our button code!
133
134
final String text = SwingUtilities.layoutCompoundLabel(c, fm, b.getText(), altIcon != null ? altIcon : getDefaultIcon(b), b.getVerticalAlignment(), b.getHorizontalAlignment(), b.getVerticalTextPosition(), b.getHorizontalTextPosition(), viewRect, iconRect, textRect, b.getText() == null ? 0 : b.getIconTextGap());
135
136
// fill background
137
138
// draw the native radio button stuff here.
139
if (altIcon == null) {
140
widgetBorder.paintButton(c, g, iconRect.x, iconRect.y, iconRect.width, iconRect.height);
141
} else {
142
// Paint the button
143
if (!model.isEnabled()) {
144
if (model.isSelected()) {
145
altIcon = b.getDisabledSelectedIcon();
146
} else {
147
altIcon = b.getDisabledIcon();
148
}
149
} else if (model.isPressed() && model.isArmed()) {
150
altIcon = b.getPressedIcon();
151
if (altIcon == null) {
152
// Use selected icon
153
altIcon = b.getSelectedIcon();
154
}
155
} else if (model.isSelected()) {
156
if (b.isRolloverEnabled() && model.isRollover()) {
157
altIcon = b.getRolloverSelectedIcon();
158
if (altIcon == null) {
159
altIcon = b.getSelectedIcon();
160
}
161
} else {
162
altIcon = b.getSelectedIcon();
163
}
164
} else if (b.isRolloverEnabled() && model.isRollover()) {
165
altIcon = b.getRolloverIcon();
166
}
167
168
if (altIcon == null) {
169
altIcon = b.getIcon();
170
}
171
172
int offset = 0;
173
if (b.isFocusOwner()) {
174
offset = 2;
175
altIcon = AquaFocus.createFocusedIcon(altIcon, c, 2);
176
}
177
178
altIcon.paintIcon(c, g, iconRect.x - offset, iconRect.y - offset);
179
}
180
181
// Draw the Text
182
if (text != null) {
183
final View v = (View)c.getClientProperty(BasicHTML.propertyKey);
184
if (v != null) {
185
v.paint(g, textRect);
186
} else {
187
paintText(g, b, textRect, text);
188
}
189
}
190
}
191
192
/**
193
* The preferred size of the button
194
*/
195
public Dimension getPreferredSize(final JComponent c) {
196
if (c.getComponentCount() > 0) { return null; }
197
198
final AbstractButton b = (AbstractButton)c;
199
200
final String text = b.getText();
201
202
Icon buttonIcon = b.getIcon();
203
if (buttonIcon == null) {
204
buttonIcon = getDefaultIcon(b);
205
}
206
207
final Font font = b.getFont();
208
final FontMetrics fm = b.getFontMetrics(font);
209
210
Rectangle prefViewRect = new Rectangle(Short.MAX_VALUE, Short.MAX_VALUE);
211
Rectangle prefIconRect = new Rectangle();
212
Rectangle prefTextRect = new Rectangle();
213
214
SwingUtilities.layoutCompoundLabel(c, fm, text, buttonIcon, b.getVerticalAlignment(), b.getHorizontalAlignment(), b.getVerticalTextPosition(), b.getHorizontalTextPosition(), prefViewRect, prefIconRect, prefTextRect, text == null ? 0 : b.getIconTextGap());
215
216
// find the union of the icon and text rects (from Rectangle.java)
217
final int x1 = Math.min(prefIconRect.x, prefTextRect.x);
218
final int x2 = Math.max(prefIconRect.x + prefIconRect.width, prefTextRect.x + prefTextRect.width);
219
final int y1 = Math.min(prefIconRect.y, prefTextRect.y);
220
final int y2 = Math.max(prefIconRect.y + prefIconRect.height, prefTextRect.y + prefTextRect.height);
221
int width = x2 - x1;
222
int height = y2 - y1;
223
224
Insets prefInsets = b.getInsets();
225
width += prefInsets.left + prefInsets.right;
226
height += prefInsets.top + prefInsets.bottom;
227
return new Dimension(width, height);
228
}
229
230
public abstract static class LabeledButtonBorder extends AquaButtonBorder {
231
public LabeledButtonBorder(final SizeDescriptor sizeDescriptor) {
232
super(sizeDescriptor);
233
}
234
235
public LabeledButtonBorder(final LabeledButtonBorder other) {
236
super(other);
237
}
238
239
@Override
240
protected AquaPainter<? extends JRSUIState> createPainter() {
241
final AquaPainter<ValueState> painter = AquaPainter.create(JRSUIStateFactory.getLabeledButton());
242
painter.state.set(AlignmentVertical.CENTER);
243
painter.state.set(AlignmentHorizontal.CENTER);
244
return painter;
245
}
246
247
protected void doButtonPaint(final AbstractButton b, final ButtonModel model, final Graphics g, final int x, final int y, final int width, final int height) {
248
painter.state.set(AquaUtilControlSize.getUserSizeFrom(b));
249
((ValueState)painter.state).setValue(model.isSelected() ? isIndeterminate(b) ? 2 : 1 : 0); // 2=mixed, 1=on, 0=off
250
super.doButtonPaint(b, model, g, x, y, width, height);
251
}
252
253
protected State getButtonState(final AbstractButton b, final ButtonModel model) {
254
final State state = super.getButtonState(b, model);
255
256
if (state == State.INACTIVE) return State.INACTIVE;
257
if (state == State.DISABLED) return State.DISABLED;
258
if (model.isArmed() && model.isPressed()) return State.PRESSED;
259
if (model.isSelected()) return State.ACTIVE;
260
261
return state;
262
}
263
264
static boolean isIndeterminate(final AbstractButton b) {
265
return "indeterminate".equals(b.getClientProperty("JButton.selectedState"));
266
}
267
}
268
}
269
270