Skip to content

Commit

Permalink
Merge branch 'master' into macos_preferences
Browse files Browse the repository at this point in the history
  • Loading branch information
weisJ committed Apr 1, 2020
2 parents 2898b63 + f2958a2 commit 401a47b
Show file tree
Hide file tree
Showing 30 changed files with 945 additions and 213 deletions.
7 changes: 4 additions & 3 deletions core/src/main/java/com/github/weisj/darklaf/DarkLaf.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
*/
package com.github.weisj.darklaf;

import com.github.weisj.darklaf.platform.Decorations;
import com.github.weisj.darklaf.platform.DecorationsHandler;
import com.github.weisj.darklaf.task.*;
import com.github.weisj.darklaf.theme.Theme;
import com.github.weisj.darklaf.ui.DarkPopupFactory;
Expand All @@ -42,6 +42,7 @@
public class DarkLaf extends BasicLookAndFeel {

public static final String SYSTEM_PROPERTY_PREFIX = "darklaf.";
public static final String ALLOW_NATIVE_CODE_FLAG = DarkLaf.SYSTEM_PROPERTY_PREFIX + "allowNativeCode";
private static final Logger LOGGER = Logger.getLogger(DarkLaf.class.getName());
/*
* All tasks for initializing the ui defaults in order of execution.
Expand Down Expand Up @@ -111,7 +112,7 @@ public void initialize() {
}

private void setupDecorations() {
Decorations.initialize();
DecorationsHandler.getSharedInstance().initialize();
JFrame.setDefaultLookAndFeelDecorated(true);
JDialog.setDefaultLookAndFeelDecorated(true);
}
Expand Down Expand Up @@ -166,6 +167,6 @@ public boolean isSupportedLookAndFeel() {

@Override
public boolean getSupportsWindowDecorations() {
return Decorations.isCustomDecorationSupported();
return DecorationsHandler.getSharedInstance().isCustomDecorationSupported();
}
}
93 changes: 84 additions & 9 deletions core/src/main/java/com/github/weisj/darklaf/LafManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,12 @@
*/
package com.github.weisj.darklaf;

import com.github.weisj.darklaf.platform.DecorationsHandler;
import com.github.weisj.darklaf.platform.ThemePreferencesHandler;
import com.github.weisj.darklaf.task.DefaultsAdjustmentTask;
import com.github.weisj.darklaf.theme.DarculaTheme;
import com.github.weisj.darklaf.theme.Theme;
import com.github.weisj.darklaf.theme.event.ThemePreferenceListener;
import com.github.weisj.darklaf.theme.info.DefaultThemeProvider;
import com.github.weisj.darklaf.theme.info.PreferredThemeStyle;
import com.github.weisj.darklaf.theme.info.ThemeProvider;
Expand All @@ -51,7 +54,6 @@ public final class LafManager {
private static ThemeProvider themeProvider;
private static Theme theme;
private static boolean logEnabled = false;
private static boolean decorationsOverwrite = true;
private static final Collection<DefaultsAdjustmentTask> uiDefaultsTasks = new HashSet<>();

static {
Expand Down Expand Up @@ -84,13 +86,13 @@ public static void enableLogging(final boolean logEnabled) {
}

/**
* Returns whther custom decorations should be used. If this returns true decorations still might not be used if the
* theme or platform don't support them.
* Returns whether custom decorations should be used. If this returns true decorations still might not be used if
* the theme or platform don't support them.
*
* @return true if decorations should be used.
*/
public static boolean isDecorationsEnabled() {
return decorationsOverwrite;
return DecorationsHandler.getSharedInstance().isCustomDecorationSupported();
}

/**
Expand All @@ -100,23 +102,95 @@ public static boolean isDecorationsEnabled() {
* @param enabled true if decorations should be used if available.
*/
public static void setDecorationsEnabled(final boolean enabled) {
if (decorationsOverwrite != enabled) {
decorationsOverwrite = enabled;
if (!decorationsOverwrite) {
updateLaf();
}
boolean isEnabled = isDecorationsEnabled();
DecorationsHandler.getSharedInstance().setDecorationsEnabled(enabled);
if (isEnabled != enabled) {
updateLaf();
}
}

/**
* Enabled whether changes in the preferred theme style should be reported to {@link ThemePreferenceListener}s. On
* some platforms this setting may do nothing.
*
* @param enabled true if changes should be reported.
*/
public static void enabledPreferenceChangeReporting(final boolean enabled) {
ThemePreferencesHandler.getSharedInstance().enablePreferenceChangeReporting(enabled);
}

/**
* Returns whether changes to the preferred theme style should be reported to {@link ThemePreferenceListener}s.
*
* @return true if enabled and currently reporting.
*/
public static boolean isPreferenceChangeReportingEnabled() {
return ThemePreferencesHandler.getSharedInstance().isPreferenceChangeReportingEnabled();
}

/**
* Adds a {@link ThemePreferenceListener}. If preference change reporting is enabled the handler will receive events
* if preferences have changed.
*
* @param listener the listener to add.
* @see ThemePreferenceListener
* @see #enabledPreferenceChangeReporting(boolean)
* @see #isPreferenceChangeReportingEnabled()
*/
public static void addThemePreferenceChangeListener(final ThemePreferenceListener listener) {
ThemePreferencesHandler.getSharedInstance().addThemePreferenceChangeListener(listener);
}

/**
* Removes a {@link ThemePreferenceListener}.
*
* @param listener the listener to add.
* @see ThemePreferenceListener
* @see #enabledPreferenceChangeReporting(boolean)
* @see #isPreferenceChangeReportingEnabled()
*/
public static void removeThemePreferenceChangeListener(final ThemePreferenceListener listener) {
ThemePreferencesHandler.getSharedInstance().removeThemePreferenceChangeListener(listener);
}

/**
* Gets the preferred theme style. If theme preference change reporting is enabled this may use native os settings
* to determine these values.
*
* @return the preferred theme style.
* @see #isPreferenceChangeReportingEnabled()
* @see #enabledPreferenceChangeReporting(boolean)
*/
public static PreferredThemeStyle getPreferredThemeStyle() {
return ThemePreferencesHandler.getSharedInstance().getPreferredThemeStyle();
}

/**
* Get the current theme provider. The theme provider is responsible the produce available themes for a given
* preferred theme style.
*
* @return the theme provider.
* @see PreferredThemeStyle
*/
public static ThemeProvider getThemeProvider() {
if (themeProvider == null) themeProvider = createDefaultThemeProvider();
return themeProvider;
}

/**
* Set the current theme provider. The theme provider is responsible the produce available themes for a given
* preferred theme style.
*
* @param themeProvider the theme provider.
* @see PreferredThemeStyle
*/
public static void setThemeProvider(final ThemeProvider themeProvider) {
LafManager.themeProvider = themeProvider;
}

/*
* Default theme provider. Defaults to IntelliJ/Darcula Light/Dark high contrast themes.
*/
private static ThemeProvider createDefaultThemeProvider() {
return new DefaultThemeProvider();
}
Expand All @@ -131,6 +205,7 @@ public static Theme themeForPreferredStyle(final PreferredThemeStyle style) {
return getThemeProvider().getTheme(style);
}


/**
* Get the current theme. This method will never return null even if the LaF isn#t currently installed.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,73 +23,27 @@
*/
package com.github.weisj.darklaf.components;

import com.github.weisj.darklaf.util.DarkUIUtil;
import com.github.weisj.darklaf.ui.popupmenu.PopupMenuContainer;
import com.github.weisj.darklaf.util.PropertyKey;

import javax.swing.*;
import javax.swing.event.MenuKeyEvent;
import javax.swing.event.MenuKeyListener;
import java.awt.*;

/**
* @author Jannis Weis
*/
public class ScrollPopupMenu extends JPopupMenu {

private final JPanel contentPane;
private final JScrollPane scrollPane;
private final PopupMenuContainer popupMenuContainer;
private int maxHeight;
private JWindow popWin;
private Popup popup;
private int posX;
private int posY;
private JPanel view;
private boolean isVisible;

public ScrollPopupMenu(final int maxHeight) {
popupMenuContainer = new PopupMenuContainer();
this.maxHeight = maxHeight;
contentPane = new JPanel(new BorderLayout());
OverlayScrollPane overlayScrollPane = createScrollPane();
scrollPane = overlayScrollPane.getScrollPane();
contentPane.add(overlayScrollPane, BorderLayout.CENTER);
contentPane.setBorder(getBorder());
setDoubleBuffered(true);
MenuKeyListener menuKeyListener = new MenuKeyListener() {
@Override
public void menuKeyTyped(final MenuKeyEvent e) {
}

@Override
public void menuKeyPressed(final MenuKeyEvent e) {
SwingUtilities.invokeLater(() -> {
MenuElement[] path = e.getMenuSelectionManager().getSelectedPath();
if (path.length == 0) {
return;
}
Rectangle bounds = path[path.length - 1].getComponent().getBounds();
Rectangle r = SwingUtilities.convertRectangle(ScrollPopupMenu.this, bounds, scrollPane);
scrollPane.getViewport().scrollRectToVisible(r);
});
}

@Override
public void menuKeyReleased(final MenuKeyEvent e) {

}
};
addMenuKeyListener(menuKeyListener);
}


private OverlayScrollPane createScrollPane() {
view = new JPanel(new BorderLayout());
view.add(this, BorderLayout.CENTER);
OverlayScrollPane overlayScrollPane =
new OverlayScrollPane(view, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
JScrollBar bar = overlayScrollPane.getVerticalScrollBar();
bar.putClientProperty("JScrollBar.thin", Boolean.TRUE);
DarkUIUtil.doNotCancelPopupSetup(bar);
DarkUIUtil.doNotCancelPopupSetup(overlayScrollPane.getScrollPane());
return overlayScrollPane;
}

/**
Expand All @@ -104,52 +58,30 @@ public void setMaxHeight(final int maxHeight) {
this.maxHeight = maxHeight;
}

@Override
public JMenuItem add(final JMenuItem menuItem) {
menuItem.getModel().addChangeListener(e -> contentPane.repaint(menuItem.getBounds()));
return super.add(menuItem);
}

protected void showPopup() {
Component comp = getInvoker();
if (comp == null) return;

while (comp.getParent() != null) {
comp = comp.getParent();
}

if (popWin == null || popWin.getOwner() != comp) {
popWin = comp instanceof Window ? new JWindow((Window) comp) : new JWindow(new JFrame());
}
pack();
popWin.setLocation(posX, posY);
popWin.setVisible(true);
requestFocus();
isVisible = true;
popup = createPopup();
popup.show();
}

/**
* Get the scroll pane of the popup.
*
* @return scroll pane;
*/

public JScrollPane getScrollPane() {
return scrollPane;
return popupMenuContainer.getScrollPane();
}

@Override
public boolean isVisible() {
return popWin != null && popWin.isShowing();
return isVisible;
}

@Override
public void setLocation(final int x, final int y) {
if (popWin != null && popWin.isShowing()) {
popWin.setLocation(x, y);
} else {
posX = x;
posY = y;
}
posX = x;
posY = y;
}


Expand Down Expand Up @@ -177,41 +109,24 @@ public void setVisible(final boolean b) {
}

protected void hidePopup() {
if (popWin != null) {
if (popup != null) {
firePopupMenuWillBecomeInvisible();
popWin.setVisible(false);
popWin = null;
popup.hide();
isVisible = false;
popup = null;
firePropertyChange(PropertyKey.VISIBLE, Boolean.TRUE, Boolean.FALSE);
if (isPopupMenu()) {
MenuSelectionManager.defaultManager().clearSelectedPath();
}
}
}

private Popup createPopup() {
return popupMenuContainer.createPopup(this, posX, posY, maxHeight);
}

@Override
public void pack() {
if (popWin == null) {
return;
}
final Dimension prefSize = getPreferredSize();
if (maxHeight <= 0 || prefSize.height <= maxHeight) {
setBounds(0, 0, prefSize.width, prefSize.height);
popWin.setContentPane(this);
setBorderPainted(true);
popWin.setSize(prefSize.width, prefSize.height);
} else {
int increment = getComponentCount() > 0
? Math.max(1, getComponent(0).getPreferredSize().height / 2)
: 1;
JScrollBar bar = scrollPane.getVerticalScrollBar();
bar.setValue(bar.getMinimum());
bar.setUnitIncrement(increment);
setBorderPainted(false);
view.add(this);
popWin.setContentPane(contentPane);
popWin.pack();
popWin.setSize(prefSize.width + bar.getPreferredSize().width, maxHeight);
}
}

private boolean isPopupMenu() {
Expand Down
Loading

0 comments on commit 401a47b

Please sign in to comment.