diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java index a5b567c64df1..63028f062e85 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/LafManagerImpl.java @@ -529,7 +529,9 @@ public final class LafManagerImpl extends LafManager implements PersistentStateC * and default UI is created there directly. */ private static void fixOptionButton(UIDefaults uiDefaults) { - uiDefaults.put("OptionButtonUI", BasicOptionButtonUI.class.getCanonicalName()); + if (!UIUtil.isUnderIntelliJLaF() && !UIUtil.isUnderDarcula()) { + uiDefaults.put("OptionButtonUI", BasicOptionButtonUI.class.getCanonicalName()); + } } /** diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/DarculaOptionButtonUI.kt b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/DarculaOptionButtonUI.kt new file mode 100644 index 000000000000..c0c294d0f603 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/DarculaOptionButtonUI.kt @@ -0,0 +1,101 @@ +/* + * Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + */ +package com.intellij.ide.ui.laf.darcula + +import com.intellij.ide.ui.laf.darcula.DarculaUIUtil.lw +import com.intellij.ide.ui.laf.darcula.ui.DarculaButtonPainter +import com.intellij.ide.ui.laf.darcula.ui.DarculaButtonUI.getDisabledTextColor +import com.intellij.ide.ui.laf.darcula.ui.DarculaButtonUI.getTextColor +import com.intellij.ide.ui.laf.darcula.ui.DarculaComboBoxUI +import com.intellij.ui.components.BasicOptionButtonUI +import com.intellij.util.ui.JBUI +import com.intellij.util.ui.JBUI.scale +import java.awt.Dimension +import java.awt.Graphics +import java.awt.Graphics2D +import java.awt.RenderingHints +import java.awt.geom.Line2D +import javax.swing.AbstractButton +import javax.swing.JComponent +import javax.swing.border.Border + +open class DarculaOptionButtonUI : BasicOptionButtonUI() { + protected open val clipXOffset = scale(7) + + private var optionButtonBorder: Border? = null + + override fun configureOptionButton() = super.configureOptionButton().also { optionButtonBorder = optionButton.border } + override fun unconfigureOptionButton() = super.unconfigureOptionButton().also { + optionButton.border = optionButtonBorder + optionButtonBorder = null + } + + override fun createMainButton() = object : MainButton() { + override fun paintNotSimple(g: Graphics2D) { + g.clipRect(0, 0, width - clipXOffset, height) + paintBackground(g, this) + + super.paintNotSimple(g) + } + } + + override fun configureMainButton() = super.configureMainButton().also { mainButton.isOpaque = false } + override fun unconfigureMainButton() = super.unconfigureMainButton().also { mainButton.isOpaque = true } + + override fun createArrowButton() = object : ArrowButton() { + override fun paintNotSimple(g: Graphics2D) { + g.clipRect(clipXOffset, 0, width - clipXOffset, height) + paintBackground(g, this) + + super.paintNotSimple(g) + paintArrow(g, this) + } + } + + protected open fun paintArrow(g: Graphics2D, b: AbstractButton) { + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON) + g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE) + + g.color = if (b.isEnabled) getTextColor(b) else getDisabledTextColor() + g.fill(DarculaComboBoxUI.getArrowShape(b.width, b.height)) + } + + override fun configureArrowButton() = super.configureArrowButton().also { arrowButton.isOpaque = false } + override fun unconfigureArrowButton() = super.unconfigureArrowButton().also { arrowButton.isOpaque = true } + + override val arrowButtonPreferredSize get() = Dimension(scale(28), optionButton.preferredSize.height) + + override val showPopupXOffset get() = JBUI.scale(5) + + override fun paint(g: Graphics, c: JComponent) { + if (!isSimpleButton) paintSeparatorArea(g as Graphics2D, c) + } + + protected open fun paintSeparatorArea(g: Graphics2D, c: JComponent) { + g.clipRect(mainButton.width - clipXOffset, 0, 2 * clipXOffset, c.height) + paintBackground(g, c) + + mainButton.ui.paint(g, c) + paintSeparator(g, c) + } + + protected open fun paintSeparator(g: Graphics2D, c: JComponent) { + val insets = mainButton.insets + val yOffset = (insets.top + insets.bottom) / 4 + lw(g) + val x = mainButton.width.toFloat() + + g.color = (mainButton.border as DarculaButtonPainter).borderColor + g.draw(Line2D.Float(x, yOffset, x, mainButton.height - yOffset)) + } + + override fun updateOptions() = super.updateOptions().also { + optionButton.border = if (isSimpleButton) optionButtonBorder else mainButton.border + } + + companion object { + @Suppress("UNUSED_PARAMETER") + @JvmStatic + fun createUI(c: JComponent) = DarculaOptionButtonUI() + } +} \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/darcula.properties b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/darcula.properties index d851c5c3ce74..06713d70c5ae 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/darcula.properties +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/darcula.properties @@ -177,3 +177,5 @@ Tree.leftChildIndent=7 Tree.rightChildIndent=11 FileView.fileIcon=AllIcons.FileTypes.Unknown + +OptionButtonUI=com.intellij.ide.ui.laf.darcula.DarculaOptionButtonUI \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaButtonPainter.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaButtonPainter.java index 06bdcf3aff12..c88816bbf259 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaButtonPainter.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaButtonPainter.java @@ -97,7 +97,7 @@ public class DarculaButtonPainter implements Border, UIResource { } } - protected Color getBorderColor() { + public Color getBorderColor() { return Gray._100.withAlpha(180); } diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaButtonUI.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaButtonUI.java index 6495d2bb6854..ede99af3b572 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaButtonUI.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaButtonUI.java @@ -25,6 +25,7 @@ import com.intellij.util.ui.JBInsets; import com.intellij.util.ui.JBUI; import com.intellij.util.ui.MacUIUtil; import com.intellij.util.ui.UIUtil; +import org.jetbrains.annotations.NotNull; import sun.swing.SwingUtilities2; import javax.swing.*; @@ -131,14 +132,7 @@ public class DarculaButtonUI extends BasicButtonUI { AbstractButton button = (AbstractButton)c; ButtonModel model = button.getModel(); - Color fg = button.getForeground(); - if (fg instanceof UIResource && isDefaultButton(button)) { - final Color selectedFg = UIManager.getColor("Button.darcula.selectedButtonForeground"); - if (selectedFg != null) { - fg = selectedFg; - } - } - g.setColor(fg); + g.setColor(getTextColor(button)); //UISettings.setupAntialiasing(g); @@ -155,12 +149,27 @@ public class DarculaButtonUI extends BasicButtonUI { } } + public static Color getTextColor(@NotNull AbstractButton button) { + Color fg = button.getForeground(); + if (fg instanceof UIResource && isDefaultButton(button)) { + final Color selectedFg = UIManager.getColor("Button.darcula.selectedButtonForeground"); + if (selectedFg != null) { + fg = selectedFg; + } + } + return fg; + } + + public static Color getDisabledTextColor() { + return UIManager.getColor("Button.disabledText"); + } + protected void paintDisabledText(Graphics g, String text, JComponent c, Rectangle textRect, FontMetrics metrics) { g.setColor(UIManager.getColor("Button.darcula.disabledText.shadow")); SwingUtilities2.drawStringUnderlineCharAt(c, g, text, -1, textRect.x + getTextShiftOffset()+1, textRect.y + metrics.getAscent() + getTextShiftOffset()+1); - g.setColor(UIManager.getColor("Button.disabledText")); + g.setColor(getDisabledTextColor()); SwingUtilities2.drawStringUnderlineCharAt(c, g, text, -1, textRect.x + getTextShiftOffset(), textRect.y + metrics.getAscent() + getTextShiftOffset()); diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaComboBoxUI.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaComboBoxUI.java index 32d905291138..6f63cd815677 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaComboBoxUI.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaComboBoxUI.java @@ -126,27 +126,12 @@ public class DarculaComboBoxUI extends BasicComboBoxUI implements Border, ErrorB g2.fill(new Rectangle2D.Float(0, bw + lw, lw(g2), getHeight() - (bw + lw) * 2)); g2.setColor(new JBColor(Gray._255, comboBox.isEnabled() ? getForeground() : getOutlineColor(comboBox.isEnabled()))); - g2.fill(getArrowShape()); + g2.fill(getArrowShape(getWidth(), getHeight())); } finally { g2.dispose(); } } - private Shape getArrowShape() { - int tW = JBUI.scale(8); - int tH = JBUI.scale(6); - int xU = (getWidth() - tW) / 2 - JBUI.scale(1); - int yU = (getHeight() - tH) / 2 + JBUI.scale(1); - - Path2D path = new Path2D.Float(); - path.moveTo(xU, yU); - path.lineTo(xU + tW, yU); - path.lineTo(xU + tW/2, yU + tH); - path.lineTo(xU, yU); - path.closePath(); - return path; - } - @Override public Dimension getPreferredSize() { Insets i = comboBox.getInsets(); @@ -167,6 +152,22 @@ public class DarculaComboBoxUI extends BasicComboBoxUI implements Border, ErrorB return JBUI.insets(3, 8, 3, 3).asUIResource(); } + @NotNull + public static Shape getArrowShape(int width, int height) { + int tW = JBUI.scale(8); + int tH = JBUI.scale(6); + int xU = (width - tW) / 2 - JBUI.scale(1); + int yU = (height - tH) / 2 + JBUI.scale(1); + + Path2D path = new Path2D.Float(); + path.moveTo(xU, yU); + path.lineTo(xU + tW, yU); + path.lineTo(xU + tW / 2, yU + tH); + path.lineTo(xU, yU); + path.closePath(); + return path; + } + @Override public void paint(Graphics g, JComponent c) { Container parent = c.getParent(); diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJButtonUI.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJButtonUI.java index fbc4839793ad..284347963d43 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJButtonUI.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJButtonUI.java @@ -62,7 +62,7 @@ public class MacIntelliJButtonUI extends DarculaButtonUI { g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, MacUIUtil.USE_QUARTZ ? RenderingHints.VALUE_STROKE_PURE : RenderingHints.VALUE_STROKE_NORMALIZE); - float lw = UIUtil.isRetina(g2) ? 0.5f : 1.0f; + float lw = getLineWidth(g2); Insets i = c.getBorder().getBorderInsets(c); // ComboButton adds arrow width to the insets, so take the bare border. // Draw background @@ -90,16 +90,7 @@ public class MacIntelliJButtonUI extends DarculaButtonUI { h - lw*2 - (i.top + i.bottom), ARC_SIZE - lw, ARC_SIZE - lw), false); - if (!b.isEnabled()) { - p = new GradientPaint(w/2, i.top, Gray.xD2, w/2, h - (i.top + i.bottom), Gray.xC3); - } else if (isDefaultButton(c)) { - p = IntelliJLaf.isGraphite() ? - new GradientPaint(w/2, i.top, new Color(0xa5a5ab), w/2, h - (i.top + i.bottom), new Color(0x7d7d83)) : - new GradientPaint(w/2, i.top, new Color(0x4ba0f8), w/2, h - (i.top + i.bottom), new Color(0x095eff)); - } else { - p = new GradientPaint(w/2, i.top, Gray.xC9, w/2, h - (i.top + i.bottom), Gray.xAC); - } - + p = getBorderPaint(c); g2.setPaint(p); g2.fill(outline); @@ -110,6 +101,30 @@ public class MacIntelliJButtonUI extends DarculaButtonUI { } } + public static float getLineWidth(Graphics2D g) { + return UIUtil.isRetina(g) ? 0.5f : 1.0f; + } + + @SuppressWarnings("UseJBColor") + public static Paint getBorderPaint(JComponent c) { + int w = c.getWidth(); + int h = c.getHeight(); + Insets i = c.getBorder().getBorderInsets(c); + Paint p; + if (!c.isEnabled()) { + p = new GradientPaint(w / 2, i.top, Gray.xD2, w / 2, h - (i.top + i.bottom), Gray.xC3); + } + else if (isDefaultButton(c)) { + p = IntelliJLaf.isGraphite() ? + new GradientPaint(w / 2, i.top, new Color(0xa5a5ab), w / 2, h - (i.top + i.bottom), new Color(0x7d7d83)) : + new GradientPaint(w / 2, i.top, new Color(0x4ba0f8), w / 2, h - (i.top + i.bottom), new Color(0x095eff)); + } + else { + p = new GradientPaint(w / 2, i.top, Gray.xC9, w / 2, h - (i.top + i.bottom), Gray.xAC); + } + return p; + } + @Override public Dimension getPreferredSize(JComponent c) { Dimension size = super.getPreferredSize(c); diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJOptionButtonUI.kt b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJOptionButtonUI.kt new file mode 100644 index 000000000000..15a93daadb38 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/MacIntelliJOptionButtonUI.kt @@ -0,0 +1,38 @@ +/* + * Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + */ +package com.intellij.ide.ui.laf.intellij + +import com.intellij.ide.ui.laf.darcula.DarculaOptionButtonUI +import com.intellij.util.ui.JBUI.scale +import java.awt.Dimension +import java.awt.Graphics2D +import java.awt.geom.Rectangle2D +import javax.swing.JComponent + +// TODO replace arrow with specific icon when it's ready +class MacIntelliJOptionButtonUI : DarculaOptionButtonUI() { + override val arrowButtonPreferredSize get() = Dimension(scale(21), optionButton.preferredSize.height) + + override val showPopupXOffset = scale(3) + + override fun paintSeparatorArea(g: Graphics2D, c: JComponent) = super.paintSeparatorArea(g, c).also { + // clipXOffset is rather big for mac and cuts arrow - so we also paint arrow part here + g.translate(mainButton.width, 0) + paintArrow(g, arrowButton) + } + + override fun paintSeparator(g: Graphics2D, c: JComponent) { + val insets = mainButton.insets + val lw = MacIntelliJButtonUI.getLineWidth(g) + + g.paint = MacIntelliJButtonUI.getBorderPaint(c) + g.fill(Rectangle2D.Float(mainButton.width.toFloat(), insets.top + lw, lw, mainButton.height - (insets.top + insets.bottom + 2 * lw))) + } + + companion object { + @Suppress("UNUSED_PARAMETER") + @JvmStatic + fun createUI(c: JComponent) = MacIntelliJOptionButtonUI() + } +} \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/WinIntelliJButtonBorder.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/WinIntelliJButtonBorder.java index 213ac2227b09..b6c4403e2d5d 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/WinIntelliJButtonBorder.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/WinIntelliJButtonBorder.java @@ -20,6 +20,7 @@ import com.intellij.openapi.actionSystem.ActionToolbar; import com.intellij.util.ui.JBInsets; import com.intellij.util.ui.JBUI; import com.intellij.util.ui.UIUtil; +import org.jetbrains.annotations.NotNull; import javax.swing.*; import javax.swing.border.Border; @@ -43,7 +44,7 @@ public class WinIntelliJButtonBorder implements Border, UIResource { ButtonModel bm = b.getModel(); Rectangle outerRect = new Rectangle(x, y, width, height); try { - JBInsets.removeFrom(outerRect, JBUI.insets(1)); + JBInsets.removeFrom(outerRect, getOuterInsets()); if (UIUtil.getParentOfType(ActionToolbar.class, c) != null) { JBInsets.removeFrom(outerRect, JBUI.insetsRight(3)); } @@ -52,7 +53,6 @@ public class WinIntelliJButtonBorder implements Border, UIResource { g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE); Color color = UIManager.getColor("Button.intellij.native.borderColor"); - int bw = 1; if (!c.isEnabled()) { g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, DISABLED_ALPHA_LEVEL)); } else if (bm.isPressed()) { @@ -61,10 +61,10 @@ public class WinIntelliJButtonBorder implements Border, UIResource { color = UIManager.getColor("Button.intellij.native.focusedBorderColor"); } else { if (DarculaButtonUI.isDefaultButton(b)) { - bw = 2; color = UIManager.getColor("Button.intellij.native.focusedBorderColor"); } } + int bw = getBorderWidth(b); Path2D border = new Path2D.Float(Path2D.WIND_EVEN_ODD); border.append(outerRect, false); @@ -80,6 +80,20 @@ public class WinIntelliJButtonBorder implements Border, UIResource { } } + @NotNull + public JBInsets getOuterInsets() { + return JBUI.insets(1); + } + + public static boolean isWideBorder(@NotNull AbstractButton b) { + ButtonModel bm = b.getModel(); + return b.isEnabled() && !bm.isPressed() && !b.hasFocus() && !bm.isRollover() && DarculaButtonUI.isDefaultButton(b); + } + + public static int getBorderWidth(@NotNull AbstractButton b) { + return isWideBorder(b) ? 2 : 1; + } + @Override public Insets getBorderInsets(Component c) { if (isSquare(c)) { diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/WinIntelliJComboBoxUI.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/WinIntelliJComboBoxUI.java index e5c68791568e..e9efa1935b57 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/WinIntelliJComboBoxUI.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/WinIntelliJComboBoxUI.java @@ -26,6 +26,7 @@ import com.intellij.util.ui.JBUI; import com.intellij.util.ui.UIUtil; import com.intellij.util.ui.components.BorderLayoutPanel; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.border.Border; @@ -246,7 +247,7 @@ public class WinIntelliJComboBoxUI extends DarculaComboBoxUI { } } - Icon icon = MacIntelliJIconCache.getIcon("comboDropTriangle", false, false, isEnabled()); + Icon icon = getArrowIcon(this); int x = JBUI.scale(5); int y = (getHeight() - icon.getIconHeight()) / 2; icon.paintIcon(this, g2, x, y); @@ -276,6 +277,10 @@ public class WinIntelliJComboBoxUI extends DarculaComboBoxUI { return button; } + public static Icon getArrowIcon(@NotNull JComponent c) { + return MacIntelliJIconCache.getIcon("comboDropTriangle", false, false, c.isEnabled()); + } + @Override public void unconfigureArrowButton() { super.unconfigureArrowButton(); if (arrowButton != null) { diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/WinIntelliJOptionButtonUI.kt b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/WinIntelliJOptionButtonUI.kt new file mode 100644 index 000000000000..c48cf5ffa82b --- /dev/null +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellij/WinIntelliJOptionButtonUI.kt @@ -0,0 +1,102 @@ +/* + * Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + */ +package com.intellij.ide.ui.laf.intellij + +import com.intellij.ide.ui.laf.intellij.WinIntelliJButtonUI.DISABLED_ALPHA_LEVEL +import com.intellij.ui.components.BasicOptionButtonUI +import com.intellij.util.ui.JBUI.scale +import java.awt.* +import javax.swing.AbstractButton +import javax.swing.JComponent +import javax.swing.UIManager + +class WinIntelliJOptionButtonUI : BasicOptionButtonUI() { + private val outerInsets get() = (mainButton.border as WinIntelliJButtonBorder).outerInsets + private val lw get() = scale(1) + + override fun createMainButton() = object : MainButton() { + override fun paintNotSimple(g: Graphics2D) { + g.clipRect(0, 0, width - outerInsets.right, height) +// background is painted in button ui + + super.paintNotSimple(g) + } + + override fun paintBorderNotSimple(g: Graphics2D) = super.paintBorderNotSimple(g).also { + // we do not need any rendering hints set by border here - so we clone again + cloneAndPaint(g) { paintSeparatorArea(it, this) } + } + } + + override fun configureMainButton() = super.configureMainButton().also { mainButton.isOpaque = false } + override fun unconfigureMainButton() = super.unconfigureMainButton().also { mainButton.isOpaque = true } + + override fun createArrowButton() = object : ArrowButton() { + override fun paintNotSimple(g: Graphics2D) { + val bw = scale(2) + g.clipRect(outerInsets.left + bw, 0, width - (outerInsets.left + bw), height) +// background is painted in button ui + + super.paintNotSimple(g) + paintArrow(g, this) + } + } + + fun paintArrow(g: Graphics2D, b: AbstractButton) { + val icon = WinIntelliJComboBoxUI.getArrowIcon(b) + if (icon != null) { + val x = scale(7) + val y = (b.height - icon.iconHeight) / 2 + icon.paintIcon(b, g, x, y) + } + } + + override fun configureArrowButton() = super.configureArrowButton().also { arrowButton.isOpaque = false } + override fun unconfigureArrowButton() = super.unconfigureArrowButton().also { arrowButton.isOpaque = true } + + override val arrowButtonPreferredSize get() = Dimension(scale(23), optionButton.preferredSize.height) + + override val showPopupXOffset get() = scale(4) + + override fun createLayoutManager() = object : OptionButtonLayout() { + override fun layoutContainer(parent: Container) { + val mainButtonWidth = optionButton.width - if (arrowButton.isVisible) arrowButton.preferredSize.width else 0 + val offset = if (arrowButton.isVisible) scale(2) else 0 + + mainButton.bounds = Rectangle(offset, 0, mainButtonWidth, optionButton.height) + arrowButton.bounds = Rectangle(mainButtonWidth - offset, 0, arrowButton.preferredSize.width, optionButton.height) + } + } + + fun paintSeparatorArea(g: Graphics2D, c: JComponent) { + val bw = scale(WinIntelliJButtonBorder.getBorderWidth(mainButton)) + val x = mainButton.width - outerInsets.right - lw + val y = outerInsets.top + bw + val height = mainButton.height - (outerInsets.top + outerInsets.bottom + 2 * bw) + + paintSeparator(g, c, x, y, height) + if (WinIntelliJButtonBorder.isWideBorder(mainButton)) { + paintMainButtonBackground(g, x - 2 * lw, y, height) + } + } + + private fun paintSeparator(g: Graphics2D, c: JComponent, x: Int, y: Int, height: Int) { + g.color = UIManager.getColor("Button.intellij.native.borderColor") + if (!c.isEnabled) { + g.composite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, DISABLED_ALPHA_LEVEL) + } + g.fill(Rectangle(x, y, lw, height)) + } + + private fun paintMainButtonBackground(g: Graphics2D, x: Int, y: Int, height: Int) { + g.color = mainButton.background + g.fill(Rectangle(x, y, 2 * lw, height)) + } + + companion object { + @Suppress("UNUSED_PARAMETER") + @JvmStatic + fun createUI(c: JComponent) = WinIntelliJOptionButtonUI() + } +} \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf.properties b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf.properties index 0c5b70efd0c1..38385080c0a0 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf.properties +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf.properties @@ -179,3 +179,5 @@ Tree.leftChildIndent=7 Tree.rightChildIndent=11 FileView.fileIcon=AllIcons.FileTypes.Unknown + +OptionButtonUI=com.intellij.ide.ui.laf.darcula.DarculaOptionButtonUI \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf_mac.properties b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf_mac.properties index cf5b7c7b4a7b..62a2c8a53a3d 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf_mac.properties +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf_mac.properties @@ -54,3 +54,5 @@ TabbedPane.selectedTabTitleNormalColor=dcdcdc TableHeader.cellBorder=2,2,2,2 Tree.rowHeight=20 + +OptionButtonUI=com.intellij.ide.ui.laf.intellij.MacIntelliJOptionButtonUI \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf_native.properties b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf_native.properties index e35276c2c586..042309edaff7 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf_native.properties +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf_native.properties @@ -207,4 +207,6 @@ RootPaneUI=com.intellij.ide.ui.laf.darcula.ui.DarculaRootPaneUI OnOffButtonUI=com.intellij.ide.ui.laf.intellij.WinOnOffButtonUI HelpTooltip.xOffset=1 -HelpTooltip.yOffset=1 \ No newline at end of file +HelpTooltip.yOffset=1 + +OptionButtonUI=com.intellij.ide.ui.laf.intellij.WinIntelliJOptionButtonUI \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/notification/impl/NotificationsManagerImpl.java b/platform/platform-impl/src/com/intellij/notification/impl/NotificationsManagerImpl.java index 8a8d13744ea3..e50f49e7ed64 100644 --- a/platform/platform-impl/src/com/intellij/notification/impl/NotificationsManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/notification/impl/NotificationsManagerImpl.java @@ -701,7 +701,7 @@ public class NotificationsManagerImpl extends NotificationsManager { if (isDarcula) { setBorder(new DarculaButtonPainter() { @Override - protected Color getBorderColor() { + public Color getBorderColor() { return new ColorUIResource(0x616263); } }); diff --git a/platform/platform-impl/src/com/intellij/ui/components/BasicOptionButtonUI.kt b/platform/platform-impl/src/com/intellij/ui/components/BasicOptionButtonUI.kt index 4440c2750e42..869e2ed9e1ca 100644 --- a/platform/platform-impl/src/com/intellij/ui/components/BasicOptionButtonUI.kt +++ b/platform/platform-impl/src/com/intellij/ui/components/BasicOptionButtonUI.kt @@ -177,7 +177,7 @@ open class BasicOptionButtonUI : OptionButtonUI() { closePopup() updateExtraWidth() updateTooltip() - arrowButton.isVisible = !isSimpleButton + updateOptions() } } } @@ -305,9 +305,19 @@ open class BasicOptionButtonUI : OptionButtonUI() { arrowButton.toolTipText = toolTip } + protected open fun updateOptions() { + arrowButton.isVisible = !isSimpleButton + } + open inner class BaseButton : JButton() { override fun hasFocus() = optionButton.hasFocus() override fun isDefaultButton() = optionButton.isDefaultButton + + override fun paint(g: Graphics) = if (isSimpleButton) super.paint(g) else cloneAndPaint(g) { paintNotSimple(it) } + open fun paintNotSimple(g: Graphics2D) = super.paint(g) + + override fun paintBorder(g: Graphics) = if (isSimpleButton) super.paintBorder(g) else cloneAndPaint(g) { paintBorderNotSimple(it) } + open fun paintBorderNotSimple(g: Graphics2D) = super.paintBorder(g) } open inner class MainButton : BaseButton() @@ -377,5 +387,20 @@ open class BasicOptionButtonUI : OptionButtonUI() { @Suppress("UNUSED_PARAMETER") @JvmStatic fun createUI(c: JComponent) = BasicOptionButtonUI() + + fun paintBackground(g: Graphics, c: JComponent) { + g.color = c.background + g.fillRect(0, 0, c.width, c.height) + } + + fun cloneAndPaint(g: Graphics, block: (Graphics2D) -> Unit) { + val g2 = g.create() as Graphics2D + try { + block(g2) + } + finally { + g2.dispose() + } + } } } \ No newline at end of file