mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
popups (context menus, combobox popups) fix under aqua laf: round corners, selection, etc
This commit is contained in:
@@ -27,11 +27,14 @@ import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.ui.ColoredSideBorder;
|
||||
import com.intellij.ui.IdeaBlueMetalTheme;
|
||||
import com.intellij.ui.ScreenUtil;
|
||||
import com.intellij.ui.mac.MacPopupMenuUI;
|
||||
import com.intellij.ui.plaf.beg.*;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import com.sun.java.swing.plaf.windows.WindowsLookAndFeel;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.Border;
|
||||
@@ -43,6 +46,8 @@ import javax.swing.plaf.metal.MetalLookAndFeel;
|
||||
import javax.swing.text.DefaultEditorKit;
|
||||
import java.awt.*;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
@@ -307,6 +312,7 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo
|
||||
|
||||
PopupFactory popupFactory;
|
||||
|
||||
final PopupFactory oldFactory = PopupFactory.getSharedInstance();
|
||||
if(HEAVY_WEIGHT_POPUP.equals(popupWeight)){
|
||||
popupFactory=new PopupFactory(){
|
||||
public Popup getPopup(
|
||||
@@ -316,7 +322,7 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo
|
||||
int y
|
||||
) throws IllegalArgumentException{
|
||||
final Point point = fixPopupLocation(contents, x, y);
|
||||
return new Popup(owner,contents,point.x,point.y){};
|
||||
return oldFactory.getPopup(owner, contents, point.x, point.y);
|
||||
}
|
||||
};
|
||||
}else if(MEDIUM_WEIGHT_POPUP.equals(popupWeight)){
|
||||
@@ -328,14 +334,49 @@ public final class LafManagerImpl extends LafManager implements ApplicationCompo
|
||||
|
||||
private Popup createPopup(final Component owner, final Component contents, final int x, final int y) {
|
||||
final Point point = fixPopupLocation(contents, x, y);
|
||||
final Popup popup = super.getPopup(owner, contents, point.x, point.y);
|
||||
return popup;
|
||||
return oldFactory.getPopup(owner, contents, point.x, point.y);
|
||||
}
|
||||
};
|
||||
}else{
|
||||
throw new IllegalStateException("unknown value of property -Didea.popup.weight: "+popupWeight);
|
||||
}
|
||||
PopupFactory.setSharedInstance(popupFactory);
|
||||
|
||||
// update ui for popup menu to get round corners
|
||||
if (UIUtil.isUnderAquaLookAndFeel()) {
|
||||
final UIDefaults uiDefaults = UIManager.getLookAndFeelDefaults();
|
||||
uiDefaults.put("PopupMenuUI", MacPopupMenuUI.class.getCanonicalName());
|
||||
final Icon icon = getAquaMenuInvertedIcon();
|
||||
if (icon != null) {
|
||||
uiDefaults.put("Menu.invertedArrowIcon", icon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Icon getAquaMenuInvertedIcon() {
|
||||
if (!UIUtil.isUnderAquaLookAndFeel()) return null;
|
||||
final Icon arrow = (Icon) UIManager.get("Menu.arrowIcon");
|
||||
if (arrow == null) return null;
|
||||
|
||||
try {
|
||||
final Method method = arrow.getClass().getMethod("getInvertedIcon");
|
||||
if (method != null) {
|
||||
method.setAccessible(true);
|
||||
return (Icon) method.invoke(arrow);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
catch (NoSuchMethodException e1) {
|
||||
return null;
|
||||
}
|
||||
catch (InvocationTargetException e1) {
|
||||
return null;
|
||||
}
|
||||
catch (IllegalAccessException e1) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private Point fixPopupLocation(final Component contents, final int x, final int y) {
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright 2000-2010 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.ui.mac;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.basic.BasicPopupMenuUI;
|
||||
import java.awt.*;
|
||||
import java.awt.event.MouseEvent;
|
||||
|
||||
/**
|
||||
* User: spLeaner
|
||||
*/
|
||||
public class MacPopupMenuUI extends BasicPopupMenuUI {
|
||||
static Stroke THREE_PIXEL_STROKE = new BasicStroke(3F);
|
||||
|
||||
public MacPopupMenuUI() {
|
||||
}
|
||||
|
||||
public static ComponentUI createUI(final JComponent c) {
|
||||
return new MacPopupMenuUI();
|
||||
}
|
||||
|
||||
public boolean isPopupTrigger(final MouseEvent event) {
|
||||
return event.isPopupTrigger();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void installUI(JComponent c) {
|
||||
super.installUI(c);
|
||||
}
|
||||
|
||||
public void paint(final Graphics g, final JComponent jcomponent) {
|
||||
if (!(g instanceof Graphics2D)) {
|
||||
super.paint(g, jcomponent);
|
||||
return;
|
||||
}
|
||||
|
||||
Graphics2D graphics2d = (Graphics2D)g.create();
|
||||
Rectangle rectangle = popupMenu.getBounds();
|
||||
paintRoundRect(graphics2d, rectangle);
|
||||
clipEdges(graphics2d, rectangle);
|
||||
graphics2d.dispose();
|
||||
|
||||
super.paint(g, jcomponent);
|
||||
}
|
||||
|
||||
private static void paintRoundRect(Graphics2D graphics2d, Rectangle rectangle) {
|
||||
graphics2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
graphics2d.setComposite(AlphaComposite.Clear);
|
||||
graphics2d.setStroke(THREE_PIXEL_STROKE);
|
||||
graphics2d.drawRoundRect(-2, -2, rectangle.width + 3, rectangle.height + 3, 12, 12);
|
||||
}
|
||||
|
||||
protected void clipEdges(Graphics2D graphics2d, Rectangle rectangle) {
|
||||
Component component = popupMenu.getInvoker();
|
||||
if (!(component instanceof JMenu)) return;
|
||||
|
||||
Rectangle rectangle1 = component.getBounds();
|
||||
|
||||
rectangle1.setLocation(component.getLocationOnScreen());
|
||||
rectangle.setLocation(popupMenu.getLocationOnScreen());
|
||||
|
||||
Point point = new Point((int)rectangle1.getCenterX(), (int)rectangle1.getCenterY());
|
||||
if (rectangle.contains(point)) return;
|
||||
|
||||
graphics2d.setComposite(AlphaComposite.SrcOver);
|
||||
graphics2d.setColor(popupMenu.getBackground());
|
||||
|
||||
Point point1 = new Point((int)rectangle.getCenterX(), (int)rectangle.getCenterY());
|
||||
boolean flag = point.y <= point1.y;
|
||||
|
||||
if (rectangle1.x + rectangle1.width < rectangle.x + 10) {
|
||||
if (flag) {
|
||||
graphics2d.fillRect(-2, -2, 8, 8);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
graphics2d.fillRect(-2, rectangle.height - 6, 8, 8);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (rectangle.x + rectangle.width < rectangle1.x + 10) {
|
||||
if (flag) {
|
||||
graphics2d.fillRect(rectangle.width - 6, -2, 8, 8);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
graphics2d.fillRect(rectangle.width - 6, rectangle.height - 6, 8, 8);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (rectangle1.y + rectangle1.height < rectangle.y + 10) {
|
||||
graphics2d.fillRect(-2, -2, rectangle.width + 4, 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@ import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.event.MenuDragMouseEvent;
|
||||
import javax.swing.event.MenuDragMouseListener;
|
||||
import javax.swing.event.MouseInputListener;
|
||||
@@ -57,6 +58,8 @@ public class BegMenuItemUI extends BasicMenuItemUI {
|
||||
@NonNls public static final String AQUA_LOOK_AND_FEEL_CLASS_NAME = "apple.laf.AquaLookAndFeel";
|
||||
@NonNls public static final String GET_KEY_MODIFIERS_TEXT = "getKeyModifiersText";
|
||||
|
||||
private static final Border SELECTED_BACKGROUND_PAINTER = (Border) UIManager.get("MenuItem.selectedBackgroundPainter");
|
||||
|
||||
/** invoked by reflection */
|
||||
public static ComponentUI createUI(JComponent component) {
|
||||
return new BegMenuItemUI();
|
||||
@@ -108,18 +111,22 @@ public class BegMenuItemUI extends BasicMenuItemUI {
|
||||
g.setColor(jmenuitem.getBackground());
|
||||
g.fillRect(0, 0, j1, k1);
|
||||
if (buttonmodel.isArmed() || (comp instanceof JMenu) && buttonmodel.isSelected()){
|
||||
g.setColor(selectionBackground);
|
||||
if (icon2 != null){
|
||||
g.fillRect(k, 0, j1 - k, k1);
|
||||
}
|
||||
else{
|
||||
g.fillRect(0, 0, j1, k1);
|
||||
//graphics.setColor(BegResources.q);
|
||||
//graphics.drawLine(0, 0, 0, k1);
|
||||
if (UIUtil.isUnderAquaLookAndFeel()) {
|
||||
SELECTED_BACKGROUND_PAINTER.paintBorder(comp, g, 0, 0, j1, k1);
|
||||
} else {
|
||||
g.setColor(selectionBackground);
|
||||
if (icon2 != null){
|
||||
g.fillRect(k, 0, j1 - k, k1);
|
||||
}
|
||||
else{
|
||||
g.fillRect(0, 0, j1, k1);
|
||||
//graphics.setColor(BegResources.q);
|
||||
//graphics.drawLine(0, 0, 0, k1);
|
||||
g.setColor(selectionBackground);
|
||||
}
|
||||
//graphics.setColor(BegResources.r);
|
||||
//graphics.drawLine(j1 - 1, 0, j1 - 1, k1);
|
||||
}
|
||||
//graphics.setColor(BegResources.r);
|
||||
//graphics.drawLine(j1 - 1, 0, j1 - 1, k1);
|
||||
}
|
||||
g.setColor(color2);
|
||||
}
|
||||
@@ -180,11 +187,16 @@ public class BegMenuItemUI extends BasicMenuItemUI {
|
||||
if (keyStrokeText != null && !keyStrokeText.equals("")){
|
||||
g.setFont(acceleratorFont);
|
||||
if (buttonmodel.isEnabled()){
|
||||
if (buttonmodel.isArmed() || (comp instanceof JMenu) && buttonmodel.isSelected()){
|
||||
g.setColor(acceleratorSelectionForeground);
|
||||
if (UIUtil.isUnderAquaLookAndFeel() && (buttonmodel.isArmed() || (comp instanceof JMenu) && buttonmodel.isSelected())) {
|
||||
g.setColor(selectionForeground);
|
||||
}
|
||||
else{
|
||||
g.setColor(acceleratorForeground);
|
||||
else {
|
||||
if (buttonmodel.isArmed() || (comp instanceof JMenu) && buttonmodel.isSelected()) {
|
||||
g.setColor(acceleratorSelectionForeground);
|
||||
}
|
||||
else {
|
||||
g.setColor(acceleratorForeground);
|
||||
}
|
||||
}
|
||||
BasicGraphicsUtils.drawString(g, keyStrokeText, 0, c.x, c.y + fontmetrics.getAscent());
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import com.intellij.Patches;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.event.MenuKeyEvent;
|
||||
import javax.swing.event.MenuKeyListener;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
@@ -43,6 +44,9 @@ public class IdeaMenuUI extends BasicMenuUI{
|
||||
private static final Rectangle ourIconRect = new Rectangle();
|
||||
private static final Rectangle ourViewRect = new Rectangle(32767, 32767);
|
||||
|
||||
private static final Border SELECTED_BACKGROUND_PAINTER = (Border) UIManager.get("MenuItem.selectedBackgroundPainter");
|
||||
private static final Icon INVERTED_ARROW_ICON = (Icon) UIManager.get("Menu.invertedArrowIcon");
|
||||
|
||||
/** invoked by reflection */
|
||||
public static ComponentUI createUI(JComponent component) {
|
||||
return new IdeaMenuUI();
|
||||
@@ -109,12 +113,17 @@ public class IdeaMenuUI extends BasicMenuUI{
|
||||
g.setColor(jMenu.getBackground());
|
||||
g.fillRect(0, 0, jMenu.getWidth(), jMenu.getHeight());
|
||||
if (buttonmodel.isArmed() || buttonmodel.isSelected()){
|
||||
g.setColor(selectionBackground);
|
||||
if (allowedIcon != null){
|
||||
g.fillRect(k, 0, jMenu.getWidth() - k, jMenu.getHeight());
|
||||
}else{
|
||||
g.fillRect(0, 0, jMenu.getWidth(), jMenu.getHeight());
|
||||
if (UIUtil.isUnderAquaLookAndFeel()) {
|
||||
SELECTED_BACKGROUND_PAINTER.paintBorder(comp, g, 0, 0, jMenu.getWidth(), jMenu.getHeight());
|
||||
} else {
|
||||
g.setColor(selectionBackground);
|
||||
if (allowedIcon != null) {
|
||||
g.fillRect(k, 0, jMenu.getWidth() - k, jMenu.getHeight());
|
||||
}
|
||||
else {
|
||||
g.fillRect(0, 0, jMenu.getWidth(), jMenu.getHeight());
|
||||
g.setColor(selectionBackground);
|
||||
}
|
||||
}
|
||||
}
|
||||
g.setColor(color2);
|
||||
@@ -179,7 +188,9 @@ public class IdeaMenuUI extends BasicMenuUI{
|
||||
}
|
||||
if (useCheckAndArrow()){
|
||||
try {
|
||||
arrowIcon.paintIcon(comp, g, ourArrowIconRect.x, ourArrowIconRect.y);
|
||||
if (UIUtil.isUnderAquaLookAndFeel() && buttonmodel.isSelected() && INVERTED_ARROW_ICON != null) {
|
||||
INVERTED_ARROW_ICON.paintIcon(comp, g, ourArrowIconRect.x, ourArrowIconRect.y);
|
||||
} else arrowIcon.paintIcon(comp, g, ourArrowIconRect.x, ourArrowIconRect.y);
|
||||
}
|
||||
catch (NullPointerException npe) {
|
||||
// GTKIconFactory$MenuArrowIcon.paintIcon since it doesn't expect to be given a null instead of SynthContext
|
||||
|
||||
Reference in New Issue
Block a user