UISettings/EditorColors: push events through components hierarchy

This commit is contained in:
Gregory.Shrago
2016-06-02 09:21:14 +03:00
parent 4d515218ad
commit 12afee018e
18 changed files with 207 additions and 142 deletions
@@ -28,6 +28,7 @@ import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.SimpleModificationTracker;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.util.ComponentTreeEventDispatcher;
import com.intellij.util.EventDispatcher;
import com.intellij.util.PlatformUtils;
import com.intellij.util.SystemProperties;
@@ -54,8 +55,10 @@ public class UISettings extends SimpleModificationTracker implements PersistentS
/** Not tabbed pane. */
public static final int TABS_NONE = 0;
private static UISettings ourSettings;
public static UISettings getInstance() {
return ServiceManager.getService(UISettings.class);
return ourSettings = ServiceManager.getService(UISettings.class);
}
/**
@@ -134,6 +137,7 @@ public class UISettings extends SimpleModificationTracker implements PersistentS
public boolean MERGE_EQUAL_STACKTRACES = true;
private final EventDispatcher<UISettingsListener> myDispatcher = EventDispatcher.create(UISettingsListener.class);
private final ComponentTreeEventDispatcher<UISettingsListener> myTreeDispatcher = ComponentTreeEventDispatcher.create(UISettingsListener.class);
public UISettings() {
tweakPlatformDefaults();
@@ -171,12 +175,21 @@ public class UISettings extends SimpleModificationTracker implements PersistentS
public void fireUISettingsChanged() {
incModificationCount();
myDispatcher.getMulticaster().uiSettingsChanged(this);
ApplicationManager.getApplication().getMessageBus().syncPublisher(UISettingsListener.TOPIC).uiSettingsChanged(this);
if (ourSettings == this) {
// if this is the main UISettings instance push event to bus and to all current components
myTreeDispatcher.getMulticaster().uiSettingsChanged(this);
ApplicationManager.getApplication().getMessageBus().syncPublisher(UISettingsListener.TOPIC).uiSettingsChanged(this);
}
IconLoader.setFilter(Registry.is("color.blindness.daltonization")
? DaltonizationFilter.get(COLOR_BLINDNESS)
: MatrixFilter.get(COLOR_BLINDNESS));
}
/**
* @deprecated use {@link UISettings#addUISettingsListener(UISettingsListener, Disposable disposable)} instead.
*/
public void removeUISettingsListener(UISettingsListener listener) {
myDispatcher.removeListener(listener);
}
@@ -65,7 +65,7 @@ import java.util.List;
public class JBTabsImpl extends JComponent
implements JBTabs, PropertyChangeListener, TimerListener, DataProvider, PopupMenuListener, Disposable, JBTabsPresentation, Queryable,
QuickActionProvider, Accessible {
UISettingsListener, QuickActionProvider, Accessible {
public static final DataKey<JBTabsImpl> NAVIGATION_ACTIONS_KEY = DataKey.create("JBTabs");
@NonNls public static final Key<Integer> SIDE_TABS_SIZE_LIMIT_KEY = Key.create("SIDE_TABS_SIZE_LIMIT_KEY");
@@ -255,33 +255,6 @@ public class JBTabsImpl extends JComponent
}
});
UISettings.getInstance().addUISettingsListener(new UISettingsListener() {
@Override
public void uiSettingsChanged(UISettings source) {
myImage = null;
for (Map.Entry<TabInfo, TabLabel> entry : myInfo2Label.entrySet()) {
entry.getKey().revalidate();
entry.getValue().setInactiveStateImage(null);
}
boolean oldHideTabsIfNeed = mySingleRowLayout instanceof ScrollableSingleRowLayout;
boolean newHideTabsIfNeed = UISettings.getInstance().HIDE_TABS_IF_NEED;
boolean wasSingleRow = isSingleRow();
if (oldHideTabsIfNeed != newHideTabsIfNeed) {
if (mySingleRowLayout != null) {
remove(mySingleRowLayout.myLeftGhost);
remove(mySingleRowLayout.myRightGhost);
}
mySingleRowLayout = createSingleRowLayout();
if (wasSingleRow) {
myLayout = mySingleRowLayout;
}
add(mySingleRowLayout.myLeftGhost);
add(mySingleRowLayout.myRightGhost);
relayout(true, true);
}
}
}, this);
myAnimator = new Animator("JBTabs Attractions", 2, 500, true) {
@Override
public void paintNow(final int frame, final int totalFrames, final int cycle) {
@@ -355,6 +328,31 @@ public class JBTabsImpl extends JComponent
});
}
@Override
public void uiSettingsChanged(UISettings source) {
myImage = null;
for (Map.Entry<TabInfo, TabLabel> entry : myInfo2Label.entrySet()) {
entry.getKey().revalidate();
entry.getValue().setInactiveStateImage(null);
}
boolean oldHideTabsIfNeed = mySingleRowLayout instanceof ScrollableSingleRowLayout;
boolean newHideTabsIfNeed = UISettings.getInstance().HIDE_TABS_IF_NEED;
boolean wasSingleRow = isSingleRow();
if (oldHideTabsIfNeed != newHideTabsIfNeed) {
if (mySingleRowLayout != null) {
remove(mySingleRowLayout.myLeftGhost);
remove(mySingleRowLayout.myRightGhost);
}
mySingleRowLayout = createSingleRowLayout();
if (wasSingleRow) {
myLayout = mySingleRowLayout;
}
add(mySingleRowLayout.myLeftGhost);
add(mySingleRowLayout.myRightGhost);
relayout(true, true);
}
}
protected SingleRowLayout createSingleRowLayout() {
return new SingleRowLayout(this);
}
@@ -49,17 +49,11 @@ import java.util.List;
/**
* @author spleaner
*/
public class IdeNotificationArea extends JLabel implements CustomStatusBarWidget, IconLikeCustomStatusBarWidget {
public class IdeNotificationArea extends JLabel implements UISettingsListener, CustomStatusBarWidget, IconLikeCustomStatusBarWidget {
public static final String WIDGET_ID = "Notifications";
private StatusBar myStatusBar;
public IdeNotificationArea() {
UISettings.getInstance().addUISettingsListener(new UISettingsListener() {
@Override
public void uiSettingsChanged(UISettings source) {
updateStatus();
}
}, this);
new ClickListener() {
@Override
public boolean onClick(@NotNull MouseEvent e, int clickCount) {
@@ -72,6 +66,11 @@ public class IdeNotificationArea extends JLabel implements CustomStatusBarWidget
() -> ApplicationManager.getApplication().invokeLater(() -> updateStatus()));
}
@Override
public void uiSettingsChanged(UISettings source) {
updateStatus();
}
public WidgetPresentation getPresentation(@NotNull PlatformType type) {
return null;
}
@@ -39,9 +39,9 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.ComponentTreeEventDispatcher;
import com.intellij.util.EventDispatcher;
import com.intellij.util.JdomKt;
import com.intellij.util.ThrowableConvertor;
import com.intellij.util.io.URLUtil;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.xmlb.annotations.OptionTag;
@@ -51,7 +51,10 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.net.URL;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
@State(
name = "EditorColorsManagerImpl",
@@ -64,7 +67,8 @@ public class EditorColorsManagerImpl extends EditorColorsManager implements Pers
@NonNls private static final String SCHEME_NODE_NAME = "scheme";
private static final String DEFAULT_NAME = "Default";
private final EventDispatcher<EditorColorsListener> myListeners = EventDispatcher.create(EditorColorsListener.class);
private final EventDispatcher<EditorColorsListener> myDispatcher = EventDispatcher.create(EditorColorsListener.class);
private final ComponentTreeEventDispatcher<EditorColorsListener> myTreeDispatcher = ComponentTreeEventDispatcher.create(EditorColorsListener.class);
private final DefaultColorSchemesManager myDefaultColorSchemeManager;
private final SchemesManager<EditorColorsScheme, EditorColorsSchemeImpl> mySchemeManager;
@@ -147,7 +151,7 @@ public class EditorColorsManagerImpl extends EditorColorsManager implements Pers
private void loadBundledSchemes() {
if (!isUnitTestOrHeadlessMode()) {
for (BundledColorSchemeEP ep : BundledColorSchemeEP.EP_NAME.getExtensions()) {
mySchemeManager.loadBundledScheme(ep.path + ".xml", ep, element -> new ReadOnlyColorsSchemeImpl(element));
mySchemeManager.loadBundledScheme(ep.path + ".xml", ep, ReadOnlyColorsSchemeImpl::new);
}
}
}
@@ -158,6 +162,9 @@ public class EditorColorsManagerImpl extends EditorColorsManager implements Pers
for (Project project : ProjectManager.getInstance().getOpenProjects()) {
DaemonCodeAnalyzer.getInstance(project).restart();
}
// we need to push events to components that use editor font, e.g. HTML editor panes
EditorColorsManagerImpl instance = (EditorColorsManagerImpl)getInstance();
instance.myTreeDispatcher.getMulticaster().globalSchemeChange(instance.getGlobalScheme());
}
static class ReadOnlyColorsSchemeImpl extends EditorColorsSchemeImpl implements ReadOnlyColorsScheme {
@@ -274,22 +281,23 @@ public class EditorColorsManagerImpl extends EditorColorsManager implements Pers
}
private void fireChanges(EditorColorsScheme scheme) {
myListeners.getMulticaster().globalSchemeChange(scheme);
myDispatcher.getMulticaster().globalSchemeChange(scheme);
myTreeDispatcher.getMulticaster().globalSchemeChange(scheme);
}
@Override
public void addEditorColorsListener(@NotNull EditorColorsListener listener) {
myListeners.addListener(listener);
myDispatcher.addListener(listener);
}
@Override
public void addEditorColorsListener(@NotNull EditorColorsListener listener, @NotNull Disposable disposable) {
myListeners.addListener(listener, disposable);
myDispatcher.addListener(listener, disposable);
}
@Override
public void removeEditorColorsListener(@NotNull EditorColorsListener listener) {
myListeners.removeListener(listener);
myDispatcher.removeListener(listener);
}
@Override
@@ -16,7 +16,7 @@
package com.intellij.openapi.editor.impl;
import com.intellij.ide.ui.UISettings;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.ide.ui.UISettingsListener;
import com.intellij.ui.JBColor;
import com.intellij.ui.border.CustomLineBorder;
import org.jetbrains.annotations.NotNull;
@@ -27,12 +27,10 @@ import java.awt.*;
/**
* @author gregsh
*/
public class EditorHeaderComponent extends JPanel {
public class EditorHeaderComponent extends JPanel implements UISettingsListener {
public EditorHeaderComponent() {
super(new BorderLayout(0, 0));
boolean topBorderRequired = !SystemInfo.isMac && UISettings.getInstance().EDITOR_TAB_PLACEMENT != SwingConstants.TOP &&
!(UISettings.getInstance().SHOW_MAIN_TOOLBAR && UISettings.getInstance().SHOW_NAVIGATION_BAR);
setBorder(new CustomLineBorder(JBColor.border(), topBorderRequired ? 1 : 0, 0, 1, 0));
uiSettingsChanged(UISettings.getInstance());
}
@Override
@@ -40,4 +38,11 @@ public class EditorHeaderComponent extends JPanel {
UISettings.setupAntialiasing(g);
super.paint(g);
}
@Override
public void uiSettingsChanged(UISettings source) {
boolean topBorderRequired = source.EDITOR_TAB_PLACEMENT != SwingConstants.TOP &&
(source.SHOW_NAVIGATION_BAR || source.SHOW_MAIN_TOOLBAR);
setBorder(new CustomLineBorder(JBColor.border(), topBorderRequired ? 1 : 0, 0, 1, 0));
}
}
@@ -528,7 +528,6 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark
scrollbar.addMouseWheelListener(this);
myErrorStripeButton.addMouseMotionListener(this);
myErrorStripeButton.addMouseListener(this);
UISettings.getInstance().addUISettingsListener(this);
}
@Override
@@ -537,7 +536,6 @@ public class EditorMarkupModelImpl extends MarkupModelImpl implements EditorMark
scrollbar.removeMouseListener(this);
myErrorStripeButton.removeMouseMotionListener(this);
myErrorStripeButton.removeMouseListener(this);
UISettings.getInstance().removeUISettingsListener(this);
super.uninstallListeners();
}
@@ -107,7 +107,6 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener
}
};
KeymapManager.getInstance().addKeymapManagerListener(keymapListener, this);
UISettings.getInstance().addUISettingsListener(this, this);
}
public FileEditorManagerImpl getManager() {
@@ -101,7 +101,7 @@ public class IdeFrameImpl extends JFrame implements IdeFrameEx, AccessibleContex
DataManager dataManager,
Application application) {
super(applicationInfoEx.getFullApplicationName());
myRootPane = createRootPane(actionManager, UISettings.getInstance(), dataManager, application);
myRootPane = createRootPane(actionManager, dataManager, application);
setRootPane(myRootPane);
setBackground(UIUtil.getPanelBackground());
AppUIUtil.updateWindowIcon(this);
@@ -207,10 +207,9 @@ public class IdeFrameImpl extends JFrame implements IdeFrameEx, AccessibleContex
}
protected IdeRootPane createRootPane(ActionManagerEx actionManager,
UISettings uiSettings,
DataManager dataManager,
Application application) {
return new IdeRootPane(actionManager, uiSettings, dataManager, application, this);
return new IdeRootPane(actionManager, dataManager, application, this);
}
@NotNull
@@ -77,7 +77,6 @@ public class IdeRootPane extends JRootPane implements UISettingsListener {
private ToolWindowsPane myToolWindowsPane;
private JBPanel myContentPane;
private final ActionManager myActionManager;
private final UISettings myUISettings;
private final boolean myGlassPaneInitialized;
private final IdeGlassPaneImpl myGlassPane;
@@ -88,13 +87,12 @@ public class IdeRootPane extends JRootPane implements UISettingsListener {
private boolean myFullScreen;
public IdeRootPane(ActionManagerEx actionManager, UISettings uiSettings, DataManager dataManager, Application application, final IdeFrame frame) {
public IdeRootPane(ActionManagerEx actionManager, DataManager dataManager, Application application, final IdeFrame frame) {
if (SystemInfo.isWindows && (UIUtil.isUnderDarcula() || UIUtil.isUnderIntelliJLaF()) && frame instanceof IdeFrameImpl) {
//setUI(DarculaRootPaneUI.createUI(this));
setWindowDecorationStyle(FRAME);
}
myActionManager = actionManager;
myUISettings = uiSettings;
myContentPane.add(myNorthPanel, BorderLayout.NORTH);
@@ -151,14 +149,12 @@ public class IdeRootPane extends JRootPane implements UISettingsListener {
*/
public final void addNotify(){
super.addNotify();
myUISettings.addUISettingsListener(this);
}
/**
* Invoked when enclosed frame is being disposed.
*/
public final void removeNotify(){
myUISettings.removeUISettingsListener(this);
if (ScreenUtil.isStandardAddRemoveNotify(this)) {
removeToolbar();
}
@@ -281,7 +277,7 @@ public class IdeRootPane extends JRootPane implements UISettingsListener {
myStatusBar.addWidget(myMemoryWidget);
myStatusBar.addWidget(new IdeMessagePanel(MessagePool.getInstance()), "before " + MemoryUsagePanel.WIDGET_ID);
setMemoryIndicatorVisible(myUISettings.SHOW_MEMORY_INDICATOR);
setMemoryIndicatorVisible(UISettings.getInstance().SHOW_MEMORY_INDICATOR);
}
void setMemoryIndicatorVisible(final boolean visible) {
@@ -303,18 +299,18 @@ public class IdeRootPane extends JRootPane implements UISettingsListener {
}
private void updateToolbarVisibility(){
myToolbar.setVisible(myUISettings.SHOW_MAIN_TOOLBAR && !UISettings.getInstance().PRESENTATION_MODE);
myToolbar.setVisible(UISettings.getInstance().SHOW_MAIN_TOOLBAR && !UISettings.getInstance().PRESENTATION_MODE);
}
private void updateStatusBarVisibility(){
myStatusBar.setVisible(myUISettings.SHOW_STATUS_BAR && !myUISettings.PRESENTATION_MODE);
myStatusBar.setVisible(UISettings.getInstance().SHOW_STATUS_BAR && !UISettings.getInstance().PRESENTATION_MODE);
}
public void installNorthComponents(final Project project) {
ContainerUtil.addAll(myNorthComponents, Extensions.getExtensions(IdeRootPaneNorthExtension.EP_NAME, project));
for (IdeRootPaneNorthExtension northComponent : myNorthComponents) {
myNorthPanel.add(northComponent.getComponent());
northComponent.uiSettingsChanged(myUISettings);
northComponent.uiSettingsChanged(UISettings.getInstance());
}
}
@@ -41,11 +41,10 @@ import java.util.List;
/**
* @author Eugene Belyaev
*/
final class Stripe extends JPanel {
final class Stripe extends JPanel implements UISettingsListener {
private final int myAnchor;
private final ArrayList<StripeButton> myButtons = new ArrayList<StripeButton>();
private final MyKeymapManagerListener myWeakKeymapManagerListener;
private final MyUISettingsListener myUISettingsListener;
private Dimension myPrefSize;
private StripeButton myDragButton;
@@ -64,10 +63,14 @@ final class Stripe extends JPanel {
myManager = manager;
myAnchor = anchor;
myWeakKeymapManagerListener = new MyKeymapManagerListener();
myUISettingsListener = new MyUISettingsListener();
setBorder(new AdaptiveBorder());
}
@Override
public void uiSettingsChanged(UISettings source) {
updatePresentation();
}
private static class AdaptiveBorder implements Border {
@Override
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
@@ -149,9 +152,6 @@ final class Stripe extends JPanel {
super.addNotify();
updatePresentation();
KeymapManagerEx.getInstanceEx().addWeakListener(myWeakKeymapManagerListener);
if (ScreenUtil.isStandardAddRemoveNotify(this)) {
UISettings.getInstance().addUISettingsListener(myUISettingsListener, myDisposable);
}
}
/**
@@ -539,14 +539,6 @@ final class Stripe extends JPanel {
}
}
private final class MyUISettingsListener implements UISettingsListener {
@Override
public void uiSettingsChanged(UISettings source) {
updatePresentation();
}
}
public String toString() {
String anchor = null;
switch (myAnchor) {
@@ -202,7 +202,6 @@ public abstract class ToolWindowHeader extends JPanel implements Disposable, UIS
setOpaque(true);
setBorder(BorderFactory.createEmptyBorder(TabsUtil.TABS_BORDER, 1, TabsUtil.TABS_BORDER, 1));
UISettings.getInstance().addUISettingsListener(this, toolWindow.getContentUI());
myUpdater = new ToolbarUpdater(this) {
@Override
protected void updateActionsImpl(boolean transparentOnly, boolean forced) {
@@ -54,7 +54,7 @@ import java.util.Comparator;
* @author Anton Katilin
* @author Vladimir Kondratyev
*/
public final class ToolWindowsPane extends JBLayeredPane implements Disposable {
public final class ToolWindowsPane extends JBLayeredPane implements UISettingsListener, Disposable {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.wm.impl.ToolWindowsPane");
private final IdeFrameImpl myFrame;
@@ -86,7 +86,6 @@ public final class ToolWindowsPane extends JBLayeredPane implements Disposable {
private final ArrayList<Stripe> myStripes = new ArrayList<Stripe>();
private final MyUISettingsListenerImpl myUISettingsListener;
private final ToolWindowManagerImpl myManager;
private boolean myStripesOverlayed;
@@ -104,7 +103,6 @@ public final class ToolWindowsPane extends JBLayeredPane implements Disposable {
myId2Decorator = new HashMap<String, InternalDecorator>();
myButton2Info = new HashMap<StripeButton, WindowInfoImpl>();
myDecorator2Info = new HashMap<InternalDecorator, WindowInfoImpl>();
myUISettingsListener = new MyUISettingsListenerImpl();
myId2SplitProportion = new HashMap<String, Float>();
// Splitters
@@ -197,9 +195,6 @@ public final class ToolWindowsPane extends JBLayeredPane implements Disposable {
*/
public final void addNotify() {
super.addNotify();
if (ScreenUtil.isStandardAddRemoveNotify(this)) {
UISettings.getInstance().addUISettingsListener(myUISettingsListener, myDisposable);
}
}
/**
@@ -216,6 +211,11 @@ public final class ToolWindowsPane extends JBLayeredPane implements Disposable {
return myFrame.getProject();
}
public final void uiSettingsChanged(final UISettings source) {
updateToolStripesVisibility();
updateLayout();
}
/**
* Creates command which adds button into the specified tool stripe.
* Command uses copy of passed <code>info</code> object.
@@ -786,31 +786,20 @@ public final class ToolWindowsPane extends JBLayeredPane implements Disposable {
try {
float newWeight;
final ToolWindowAnchor anchor = myInfo.getAnchor();
final Disposable splitterDisposable = new Disposable() {
class MySplitter extends Splitter implements UISettingsListener {
@Override
public void dispose() {
}
};
Disposer.register(myDisposable, splitterDisposable);
final Splitter splitter = new Splitter(anchor.isSplitVertically()) {
@Override
public void removeNotify() {
super.removeNotify();
Disposer.dispose(splitterDisposable);
}
};
if (!anchor.isHorizontal()) {
UISettings.getInstance().addUISettingsListener(new UISettingsListener() {
@Override
public void uiSettingsChanged(UISettings source) {
if (anchor == ToolWindowAnchor.LEFT) {
splitter.setOrientation(!source.LEFT_HORIZONTAL_SPLIT);
}
if (anchor == ToolWindowAnchor.RIGHT) {
splitter.setOrientation(!source.RIGHT_HORIZONTAL_SPLIT);
}
public void uiSettingsChanged(UISettings source) {
if (anchor == ToolWindowAnchor.LEFT) {
setOrientation(!source.LEFT_HORIZONTAL_SPLIT);
}
}, splitterDisposable);
else if (anchor == ToolWindowAnchor.RIGHT) {
setOrientation(!source.RIGHT_HORIZONTAL_SPLIT);
}
}
}
Splitter splitter = new MySplitter();
splitter.setOrientation(anchor.isSplitVertically());
if (!anchor.isHorizontal()) {
splitter.setAllowSwitchOrientationByMouseClick(true);
splitter.addPropertyChangeListener(new PropertyChangeListener() {
@Override
@@ -1215,12 +1204,6 @@ public final class ToolWindowsPane extends JBLayeredPane implements Disposable {
}
}
private final class MyUISettingsListenerImpl implements UISettingsListener {
public final void uiSettingsChanged(final UISettings source) {
updateToolStripesVisibility();
updateLayout();
}
}
private final class MyLayeredPane extends JBLayeredPane {
/*
* These images are used to perform animated showing and hiding of components.
@@ -0,0 +1,57 @@
/*
* Copyright 2000-2016 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.util;
import com.intellij.openapi.util.Getter;
import org.jetbrains.annotations.NotNull;
import java.awt.*;
import java.util.Arrays;
import java.util.EventListener;
import static com.intellij.util.ui.UIUtil.uiTraverser;
/**
* @author gregsh
*/
public class ComponentTreeEventDispatcher<T extends EventListener> {
private final Class<T> myListenerClass;
private final T myMulticaster;
public static <T extends EventListener> ComponentTreeEventDispatcher<T> create(@NotNull Class<T> listenerClass) {
return new ComponentTreeEventDispatcher<T>(listenerClass);
}
private ComponentTreeEventDispatcher(@NotNull Class<T> listenerClass) {
myListenerClass = listenerClass;
myMulticaster = EventDispatcher.createMulticaster(listenerClass, new Getter<Iterable<T>>() {
@Override
public Iterable<T> get() {
return uiTraverser(null)
.withRoots(Arrays.asList(Window.getWindows()))
.postOrderDfsTraversal()
.filter(myListenerClass);
}
});
}
@NotNull
public T getMulticaster() {
return myMulticaster;
}
}
@@ -18,6 +18,7 @@ package com.intellij.util;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Getter;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -43,6 +44,16 @@ public class EventDispatcher<T extends EventListener> {
}
private EventDispatcher(@NotNull Class<T> listenerClass) {
myMulticaster = createMulticaster(listenerClass, new Getter<Iterable<T>>() {
@Override
public Iterable<T> get() {
return myListeners;
}
});
}
@NotNull
static <T> T createMulticaster(@NotNull Class<T> listenerClass, final Getter<Iterable<T>> listeners) {
LOG.assertTrue(listenerClass.isInterface(), "listenerClass must be an interface");
InvocationHandler handler = new InvocationHandler() {
@Override
@@ -65,14 +76,14 @@ public class EventDispatcher<T extends EventListener> {
}
}
else {
dispatch(method, args);
dispatch(listeners.get(), method, args);
return null;
}
}
};
//noinspection unchecked
myMulticaster = (T)Proxy.newProxyInstance(listenerClass.getClassLoader(), new Class[]{listenerClass}, handler);
return (T)Proxy.newProxyInstance(listenerClass.getClassLoader(), new Class[]{listenerClass}, handler);
}
@NotNull
@@ -80,10 +91,10 @@ public class EventDispatcher<T extends EventListener> {
return myMulticaster;
}
private void dispatch(@NotNull Method method, Object[] args) {
private static <T> void dispatch(Iterable<T> listeners, @NotNull Method method, Object[] args) {
method.setAccessible(true);
for (T listener : myListeners) {
for (T listener : listeners) {
try {
method.invoke(listener, args);
}
@@ -29,6 +29,8 @@ import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.colors.EditorColorsListener;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.fileEditor.*;
import com.intellij.openapi.ide.CopyPasteManager;
import com.intellij.openapi.progress.ProcessCanceledException;
@@ -95,7 +97,7 @@ import static com.intellij.openapi.vcs.ui.FontUtil.getHtmlWithFonts;
/**
* author: lesya
*/
public class FileHistoryPanelImpl extends PanelWithActionsAndCloseButton implements CopyProvider {
public class FileHistoryPanelImpl extends PanelWithActionsAndCloseButton implements EditorColorsListener, CopyProvider {
private static final Logger LOG = Logger.getInstance("#com.intellij.cvsSupport2.ui.FileHistoryDialog");
private static final String COMMIT_MESSAGE_TITLE = VcsBundle.message("label.selected.revision.commit.message");
private static final String VCS_HISTORY_ACTIONS_GROUP = "VcsHistoryActionsGroup";
@@ -532,7 +534,7 @@ public class FileHistoryPanelImpl extends PanelWithActionsAndCloseButton impleme
}
else {
myComments.setText("<html><head>" +
UIUtil.getCssFontDeclaration(UIUtil.getLabelFont()) +
UIUtil.getCssFontDeclaration(VcsHistoryUtil.getCommitDetailsFont()) +
"</head><body>" +
html.toString() +
"</body></html>");
@@ -891,6 +893,11 @@ public class FileHistoryPanelImpl extends PanelWithActionsAndCloseButton impleme
return true;
}
@Override
public void globalSchemeChange(EditorColorsScheme scheme) {
updateMessage();
}
public static class RevisionColumnInfo extends VcsColumnInfo<VcsRevisionNumber> {
private final Comparator<VcsFileRevision> myComparator;
@@ -22,6 +22,8 @@ import com.intellij.diff.contents.DiffContent;
import com.intellij.diff.requests.DiffRequest;
import com.intellij.diff.requests.SimpleDiffRequest;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorFontType;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
@@ -39,6 +41,7 @@ import com.intellij.util.WaitForProgressToShow;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
import java.io.IOException;
public class VcsHistoryUtil {
@@ -214,4 +217,9 @@ public class VcsHistoryUtil {
}
}.queue();
}
@NotNull
public static Font getCommitDetailsFont() {
return EditorColorsManager.getInstance().getGlobalScheme().getFont(EditorFontType.PLAIN);
}
}
@@ -16,8 +16,6 @@
package com.intellij.vcs.log.ui.frame;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorFontType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.text.StringUtil;
@@ -59,6 +57,8 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
import static com.intellij.openapi.vcs.history.VcsHistoryUtil.getCommitDetailsFont;
class CommitPanel extends JBPanel {
private static final Logger LOG = Logger.getInstance("Vcs.Log");
@@ -161,11 +161,6 @@ class CommitPanel extends JBPanel {
return myDataPanel.isExpanded();
}
@NotNull
public static Font getCommitDetailsFont() {
return EditorColorsManager.getInstance().getGlobalScheme().getFont(EditorFontType.PLAIN);
}
@NotNull
public static Color getCommitDetailsBackground() {
return UIUtil.getTableBackground();
@@ -17,13 +17,13 @@ package com.intellij.vcs.log.ui.frame;
import com.google.common.primitives.Ints;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.editor.colors.EditorColorsAdapter;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorColorsListener;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.progress.util.ProgressWindow;
import com.intellij.openapi.roots.ui.componentsList.components.ScrollablePanel;
import com.intellij.openapi.ui.OnePixelDivider;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.history.VcsHistoryUtil;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.SeparatorComponent;
import com.intellij.ui.components.JBLabel;
@@ -49,7 +49,7 @@ import java.util.Set;
/**
* @author Kirill Likhodedov
*/
class DetailsPanel extends JPanel {
class DetailsPanel extends JPanel implements EditorColorsListener {
private static final int MAX_ROWS = 50;
@NotNull private final VcsLogData myLogData;
@@ -132,22 +132,20 @@ class DetailsPanel extends JPanel {
};
myLoadingPanel.add(myScrollPane);
EditorColorsManager.getInstance().addEditorColorsListener(new EditorColorsAdapter() {
@Override
public void globalSchemeChange(EditorColorsScheme scheme) {
for (int i = 0; i < mySelection.size(); i++) {
CommitPanel commitPanel = getCommitPanel(i);
commitPanel.update();
}
}
}, parent);
setLayout(new BorderLayout());
add(myLoadingPanel, BorderLayout.CENTER);
myEmptyText.setText("Commit details");
}
@Override
public void globalSchemeChange(EditorColorsScheme scheme) {
for (int i = 0; i < mySelection.size(); i++) {
CommitPanel commitPanel = getCommitPanel(i);
commitPanel.update();
}
}
@Override
public Color getBackground() {
return CommitPanel.getCommitDetailsBackground();
@@ -196,7 +194,7 @@ class DetailsPanel extends JPanel {
if (selectionLength > MAX_ROWS) {
myMainContentPanel.add(new SeparatorComponent(0, OnePixelDivider.BACKGROUND, null));
JBLabel label = new JBLabel("(showing " + MAX_ROWS + " of " + selectionLength + " selected commits)");
label.setFont(CommitPanel.getCommitDetailsFont());
label.setFont(VcsHistoryUtil.getCommitDetailsFont());
label.setBorder(JBUI.Borders.empty(VcsLogGraphTable.ROOT_INDICATOR_WHITE_WIDTH / 2,
myColorManager.isMultipleRoots()
? VcsLogGraphTable.ROOT_INDICATOR_WHITE_WIDTH +