Browse Source

Prevent installation of decorations on popups that are for tooltips.

Improved tooltip fadein animation.
pull/109/head
weisj 5 years ago
parent
commit
357edc5dd9
  1. 25
      core/src/main/java/com/github/weisj/darklaf/DarkLaf.java
  2. 33
      core/src/main/java/com/github/weisj/darklaf/components/tooltip/DarkToolTip.java
  3. 7
      core/src/main/java/com/github/weisj/darklaf/platform/Decorations.java
  4. 58
      core/src/main/java/com/github/weisj/darklaf/ui/DarkPopupFactory.java
  5. 20
      core/src/main/java/com/github/weisj/darklaf/ui/menu/DarkMenuUI.java
  6. 1
      core/src/main/java/com/github/weisj/darklaf/ui/rootpane/DarkRootPaneUI.java
  7. 21
      core/src/main/java/com/github/weisj/darklaf/ui/tooltip/DarkTooltipUI.java
  8. 8
      decorations-base/src/main/java/com/github/weisj/darklaf/decorations/DecorationsProvider.java
  9. 13
      windows/src/main/java/com/github/weisj/darklaf/platform/windows/WindowsDecorationsProvider.java

25
core/src/main/java/com/github/weisj/darklaf/DarkLaf.java

@ -26,8 +26,8 @@ package com.github.weisj.darklaf;
import com.github.weisj.darklaf.components.border.DarkBorders;
import com.github.weisj.darklaf.platform.Decorations;
import com.github.weisj.darklaf.theme.Theme;
import com.github.weisj.darklaf.ui.DarkPopupFactory;
import com.github.weisj.darklaf.ui.popupmenu.DarkPopupMenuUI;
import com.github.weisj.darklaf.ui.rootpane.DarkRootPaneUI;
import com.github.weisj.darklaf.util.SystemInfo;
import sun.awt.AppContext;
@ -354,27 +354,7 @@ public class DarkLaf extends BasicLookAndFeel implements PropertyChangeListener
* This is disadvantageous for the behaviour of custom tooltips.
*/
call("initialize");
PopupFactory.setSharedInstance(new PopupFactory() {
@Override
public Popup getPopup(final Component owner, final Component contents,
final int x, final int y) throws IllegalArgumentException {
Popup popup = super.getPopup(owner, contents, x, y);
// Sometimes the background is java.awt.SystemColor[i=7]
// It results in a flash of white background, that is repainted with
// the proper popup background later.
// That is why we set window background explicitly.
Window window = SwingUtilities.getWindowAncestor(contents);
if (window != null) {
window.setBackground(UIManager.getColor("PopupMenu.translucentBackground"));
if (window instanceof RootPaneContainer) {
JRootPane rootPane = ((RootPaneContainer) window).getRootPane();
rootPane.putClientProperty(DarkRootPaneUI.KEY_IS_POPUP, true);
}
Decorations.initPopupWindow(window);
}
return popup;
}
});
PopupFactory.setSharedInstance(new DarkPopupFactory());
PropertyLoader.reset();
UIManager.addPropertyChangeListener(this);
}
@ -465,4 +445,5 @@ public class DarkLaf extends BasicLookAndFeel implements PropertyChangeListener
public boolean getSupportsWindowDecorations() {
return Decorations.isCustomDecorationSupported();
}
}

33
core/src/main/java/com/github/weisj/darklaf/components/tooltip/DarkToolTip.java

@ -23,7 +23,6 @@
*/
package com.github.weisj.darklaf.components.tooltip;
import com.github.weisj.darklaf.decorators.AncestorAdapter;
import com.github.weisj.darklaf.ui.tooltip.DarkTooltipBorder;
import com.github.weisj.darklaf.util.Alignment;
import com.github.weisj.darklaf.util.Animator;
@ -31,7 +30,6 @@ import com.github.weisj.darklaf.util.GraphicsContext;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.event.AncestorEvent;
import java.awt.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
@ -40,11 +38,9 @@ import java.util.Objects;
public class DarkToolTip extends JToolTip implements PropertyChangeListener {
public static final String TIP_TEXT_PROPERTY = "tiptext";
private static final long REPAINT_THRESHOLD = 150;
private static final AlphaComposite COMPOSITE = AlphaComposite.getInstance(AlphaComposite.SRC_OVER);
private static final float MAX_ALPHA = 1.0f;
private final Animator fadeAnimator;
private long lastHidden;
private float alpha = 0;
public DarkToolTip(final Alignment alignment) {
@ -52,24 +48,16 @@ public class DarkToolTip extends JToolTip implements PropertyChangeListener {
setOpaque(false);
fadeAnimator = new FadeInAnimator();
addPropertyChangeListener(this);
addAncestorListener(new AncestorAdapter() {
@Override
public void ancestorAdded(final AncestorEvent event) {
boolean resume = false;
if (Math.abs(System.currentTimeMillis() - lastHidden) < REPAINT_THRESHOLD) {
alpha = 1.0f;
} else {
alpha = 0;
resume = true;
}
setVisible(true);
notifyToolTipListeners(ToolTipEvent.SHOWN);
if (resume) {
fadeAnimator.reset();
fadeAnimator.resume();
}
}
});
}
@Override
public void addNotify() {
alpha = 0;
setVisible(true);
notifyToolTipListeners(ToolTipEvent.SHOWN);
fadeAnimator.reset();
fadeAnimator.resume();
super.addNotify();
}
public void setAlignment(final Alignment alignment) {
@ -127,7 +115,6 @@ public class DarkToolTip extends JToolTip implements PropertyChangeListener {
public void removeNotify() {
super.removeNotify();
notifyToolTipListeners(ToolTipEvent.HIDDEN);
lastHidden = System.currentTimeMillis();
alpha = 0;
}

7
core/src/main/java/com/github/weisj/darklaf/platform/Decorations.java

@ -64,10 +64,13 @@ public final class Decorations {
return decorationsProvider.createTitlePane(rootPane, decorationStyle);
}
public static void initPopupWindow(final Window window) {
decorationsProvider.initPopupWindow(window);
public static void installPopupWindow(final Window window) {
decorationsProvider.installPopupMenu(window);
}
public static void uninstallPopupWindow(final Window window) {
decorationsProvider.uninstallPopupWindow(window);
}
public static boolean isCustomDecorationSupported() {
return decorationsProvider.isCustomDecorationSupported()

58
core/src/main/java/com/github/weisj/darklaf/ui/DarkPopupFactory.java

@ -0,0 +1,58 @@
/*
* MIT License
*
* Copyright (c) 2020 Jannis Weis
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.github.weisj.darklaf.ui;
import com.github.weisj.darklaf.platform.Decorations;
import com.github.weisj.darklaf.ui.rootpane.DarkRootPaneUI;
import javax.swing.*;
import java.awt.*;
public class DarkPopupFactory extends PopupFactory {
@Override
public Popup getPopup(final Component owner, final Component contents,
final int x, final int y) throws IllegalArgumentException {
Popup popup = super.getPopup(owner, contents, x, y);
// Sometimes the background is java.awt.SystemColor[i=7]
// It results in a flash of white background, that is repainted with
// the proper popup background later.
// That is why we set window background explicitly.
Window window = SwingUtilities.getWindowAncestor(contents);
if (window != null) {
window.setBackground(UIManager.getColor("PopupMenu.translucentBackground"));
boolean install = true;
if (window instanceof RootPaneContainer) {
JRootPane rootPane = ((RootPaneContainer) window).getRootPane();
rootPane.putClientProperty(DarkRootPaneUI.KEY_IS_POPUP, true);
install = !Boolean.TRUE.equals(rootPane.getClientProperty(DarkRootPaneUI.KEY_IS_TOOLTIP));
}
if (install) {
Decorations.installPopupWindow(window);
} else {
Decorations.uninstallPopupWindow(window);
}
}
return popup;
}
}

20
core/src/main/java/com/github/weisj/darklaf/ui/menu/DarkMenuUI.java

@ -61,6 +61,9 @@ public class DarkMenuUI extends BasicMenuUI {
if (listener.getClass().getEnclosingClass().equals(BasicMenuUI.class)) {
menu.removeMouseListener(listener);
mouseListener = new MouseDelegate(listener) {
private boolean pressed = false;
private boolean wasEnabled = false;
@Override
public void mouseEntered(final MouseEvent e) {
MenuSelectionManager manager = MenuSelectionManager.defaultManager();
@ -72,6 +75,23 @@ public class DarkMenuUI extends BasicMenuUI {
}
super.mouseEntered(e);
}
@Override
public void mousePressed(final MouseEvent e) {
pressed = true;
wasEnabled = menu.isEnabled() && menu.isSelected() && menu.getPopupMenu().isShowing();
super.mousePressed(e);
}
@Override
public void mouseReleased(final MouseEvent e) {
if (!menu.isEnabled()) return;
if (pressed && wasEnabled) {
pressed = false;
return;
}
super.mouseReleased(e);
}
};
menu.addMouseListener(mouseListener);
break;

1
core/src/main/java/com/github/weisj/darklaf/ui/rootpane/DarkRootPaneUI.java

@ -48,6 +48,7 @@ public class DarkRootPaneUI extends BasicRootPaneUI implements HierarchyListener
public static final String KEY_PREFIX = "JRootPane.";
public static final String KEY_IS_POPUP = KEY_PREFIX + "isPopup";
public static final String KEY_IS_TOOLTIP = KEY_PREFIX + "isToolTip";
private Window window;
private CustomTitlePane titlePane;
private LayoutManager layoutManager;

21
core/src/main/java/com/github/weisj/darklaf/ui/tooltip/DarkTooltipUI.java

@ -23,6 +23,8 @@
*/
package com.github.weisj.darklaf.ui.tooltip;
import com.github.weisj.darklaf.components.tooltip.ToolTipStyle;
import com.github.weisj.darklaf.ui.rootpane.DarkRootPaneUI;
import com.github.weisj.darklaf.util.Alignment;
import com.github.weisj.darklaf.util.DarkUIUtil;
import com.github.weisj.darklaf.util.PropertyKey;
@ -54,6 +56,8 @@ public class DarkTooltipUI extends BasicToolTipUI implements PropertyChangeListe
public static final String VARIANT_BALLOON = "balloon";
protected JToolTip toolTip;
protected JRootPane lastRootPane;
protected ToolTipStyle style;
protected MouseListener exitListener = new MouseAdapter() {
@Override
public void mouseExited(final MouseEvent e) {
@ -130,6 +134,7 @@ public class DarkTooltipUI extends BasicToolTipUI implements PropertyChangeListe
toolTip = (JToolTip) c;
super.installUI(c);
toolTip.setBorder(new DarkTooltipBorder());
toolTip.putClientProperty(KEY_STYLE, ToolTipStyle.BALLOON);
}
@Override
@ -211,8 +216,17 @@ public class DarkTooltipUI extends BasicToolTipUI implements PropertyChangeListe
//For MediumWeightPopup still need to make parent non opaque.
((JComponent) toolTip.getParent()).setOpaque(false);
}
if (lastRootPane != null) {
lastRootPane.putClientProperty(DarkRootPaneUI.KEY_IS_TOOLTIP, false);
}
if (w != null && !isDecorated(w) && (w.getClass().getEnclosingClass().equals(Popup.class))) {
w.setBackground(DarkUIUtil.TRANSPARENT_COLOR);
if (w instanceof RootPaneContainer) {
lastRootPane = ((RootPaneContainer) w).getRootPane();
if (lastRootPane != null) {
lastRootPane.putClientProperty(DarkRootPaneUI.KEY_IS_TOOLTIP, true);
}
}
}
}
@ -270,6 +284,13 @@ public class DarkTooltipUI extends BasicToolTipUI implements PropertyChangeListe
}
}
protected ToolTipStyle getStyle() {
Object prop = toolTip.getClientProperty(KEY_STYLE);
String propValue = prop != null ? prop.toString() : null;
if (ToolTipStyle.BALLOON.name().equals(propValue)) return ToolTipStyle.BALLOON;
return ToolTipStyle.PLAIN;
}
protected void updateSize() {
toolTip.setTipText(toolTip.getTipText());
toolTip.setPreferredSize(getPreferredSize(toolTip));

8
decorations-base/src/main/java/com/github/weisj/darklaf/decorations/DecorationsProvider.java

@ -62,6 +62,12 @@ public interface DecorationsProvider {
/**
* Initialize the window of a popup menu.
*/
default void initPopupWindow(final Window window) {
default void installPopupMenu(final Window window) {
}
/**
* Uninstall the window of a popup menu.
*/
default void uninstallPopupWindow(final Window window) {
}
}

13
windows/src/main/java/com/github/weisj/darklaf/platform/windows/WindowsDecorationsProvider.java

@ -54,7 +54,7 @@ public class WindowsDecorationsProvider implements DecorationsProvider {
}
@Override
public void initPopupWindow(final Window window) {
public void installPopupMenu(final Window window) {
if (!window.isDisplayable()) {
window.addNotify();
}
@ -70,6 +70,17 @@ public class WindowsDecorationsProvider implements DecorationsProvider {
}
}
@Override
public void uninstallPopupWindow(final Window window) {
if (window.isDisplayable()) {
long hwnd = PointerUtil.getHWND(window);
if (hwnd != 0) {
JNIDecorationsWindows.uninstallDecorations(hwnd);
}
window.dispose();
}
}
@Override
public void loadDecorationProperties(final Properties properties, final UIDefaults currentDefaults) {
IconLoader iconLoader = IconLoader.get(WindowsDecorationsProvider.class);

Loading…
Cancel
Save