mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-192417 Provide an API for adding status bar widgets
review: IDEA-CR-32748
This commit is contained in:
@@ -19,6 +19,7 @@ import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.startup.StartupManager;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.util.messages.MessageBus;
|
||||
import com.intellij.util.messages.Topic;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -95,4 +96,24 @@ public interface StatusBar extends StatusBarInfo, Disposable {
|
||||
IdeFrame getFrame();
|
||||
|
||||
void install(IdeFrame frame);
|
||||
|
||||
class Anchors {
|
||||
public static final String DEFAULT_ANCHOR = after(SystemInfo.isMac
|
||||
? StandardWidgets.ENCODING_PANEL
|
||||
: StandardWidgets.INSERT_OVERWRITE_PANEL);
|
||||
|
||||
public static String before(String widgetId) {
|
||||
return "before " + widgetId;
|
||||
}
|
||||
public static String after(String widgetId) {
|
||||
return "after " + widgetId;
|
||||
}
|
||||
}
|
||||
|
||||
class StandardWidgets {
|
||||
public static final String ENCODING_PANEL = "Encoding";
|
||||
public static final String INSERT_OVERWRITE_PANEL = "InsertOverwrite";
|
||||
public static final String READONLY_ATTRIBUTE_PANEL = "ReadOnlyAttribute";
|
||||
public static final String POSITION_PANEL = "Position";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
// 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.openapi.wm;
|
||||
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Extension point to assist with adding new status bar widgets
|
||||
*/
|
||||
public interface StatusBarWidgetProvider {
|
||||
ExtensionPointName<StatusBarWidgetProvider> EP_NAME = new ExtensionPointName<>("com.intellij.statusBarWidgetProvider");
|
||||
|
||||
/**
|
||||
* Returns a widget to be added to the status bar.
|
||||
* Returning null means that no widget should be added.
|
||||
*
|
||||
* Normally you should return a new instance of your widget here.
|
||||
* @param project Current project
|
||||
* @return Widget or null
|
||||
*/
|
||||
@Nullable
|
||||
StatusBarWidget getWidget(@NotNull Project project);
|
||||
|
||||
/**
|
||||
* Determines position of the added widget in relation to other widgets on the status bar.
|
||||
*
|
||||
* Utility methods from StatusBar.Anchors can be used to create an anchor with 'before' or 'after' rules.
|
||||
* Take a look at StatusBar.StandardWidgets if you need to position your widget relatively to one of the standard widgets.
|
||||
*/
|
||||
@NotNull
|
||||
default String getAnchor() {
|
||||
return StatusBar.Anchors.DEFAULT_ANCHOR;
|
||||
}
|
||||
}
|
||||
@@ -41,6 +41,7 @@ import com.intellij.openapi.wm.impl.status.*;
|
||||
import com.intellij.openapi.wm.impl.welcomeScreen.WelcomeFrame;
|
||||
import com.intellij.ui.*;
|
||||
import com.intellij.ui.mac.MacMainFrameDecorator;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import com.intellij.util.ui.accessibility.AccessibleContextAccessor;
|
||||
@@ -56,6 +57,7 @@ import java.awt.event.WindowEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author Anton Katilin
|
||||
@@ -438,34 +440,36 @@ public class IdeFrameImpl extends JFrame implements IdeFrameEx, AccessibleContex
|
||||
}
|
||||
}
|
||||
|
||||
private final Set<String> widgetIDs = ContainerUtil.newHashSet();
|
||||
private void addWidget(StatusBar statusBar, StatusBarWidget widget, String anchor) {
|
||||
if (!widgetIDs.add(widget.ID())) {
|
||||
LOG.error("Attempting to add more than one widget with ID: " + widget.ID());
|
||||
return;
|
||||
}
|
||||
statusBar.addWidget(widget, anchor);
|
||||
}
|
||||
|
||||
private void installDefaultProjectStatusBarWidgets(@NotNull final Project project) {
|
||||
final StatusBar statusBar = getStatusBar();
|
||||
addWidget(statusBar, new PositionPanel(project), StatusBar.Anchors.before(IdeMessagePanel.FATAL_ERROR));
|
||||
addWidget(statusBar, new IdeNotificationArea(), StatusBar.Anchors.before(IdeMessagePanel.FATAL_ERROR));
|
||||
addWidget(statusBar, new EncodingPanel(project), StatusBar.Anchors.after(StatusBar.StandardWidgets.POSITION_PANEL));
|
||||
addWidget(statusBar, new LineSeparatorPanel(project), StatusBar.Anchors.before(StatusBar.StandardWidgets.ENCODING_PANEL));
|
||||
addWidget(statusBar, new InsertOverwritePanel(project), StatusBar.Anchors.after(StatusBar.StandardWidgets.ENCODING_PANEL));
|
||||
addWidget(statusBar, new ToggleReadOnlyAttributePanel(project),
|
||||
StatusBar.Anchors.after(StatusBar.StandardWidgets.INSERT_OVERWRITE_PANEL));
|
||||
|
||||
final PositionPanel positionPanel = new PositionPanel(project);
|
||||
statusBar.addWidget(positionPanel, "before " + IdeMessagePanel.FATAL_ERROR);
|
||||
|
||||
final IdeNotificationArea notificationArea = new IdeNotificationArea();
|
||||
statusBar.addWidget(notificationArea, "before " + IdeMessagePanel.FATAL_ERROR);
|
||||
|
||||
final EncodingPanel encodingPanel = new EncodingPanel(project);
|
||||
statusBar.addWidget(encodingPanel, "after Position");
|
||||
|
||||
final LineSeparatorPanel lineSeparatorPanel = new LineSeparatorPanel(project);
|
||||
statusBar.addWidget(lineSeparatorPanel, "before " + encodingPanel.ID());
|
||||
|
||||
final ToggleReadOnlyAttributePanel readOnlyAttributePanel = new ToggleReadOnlyAttributePanel(project);
|
||||
|
||||
final InsertOverwritePanel insertOverwritePanel = new InsertOverwritePanel(project);
|
||||
statusBar.addWidget(insertOverwritePanel, "after Encoding");
|
||||
statusBar.addWidget(readOnlyAttributePanel, "after InsertOverwrite");
|
||||
for (StatusBarWidgetProvider widgetProvider: StatusBarWidgetProvider.EP_NAME.getExtensions()) {
|
||||
StatusBarWidget widget = widgetProvider.getWidget(project);
|
||||
if (widget == null) continue;
|
||||
addWidget(statusBar, widget, widgetProvider.getAnchor());
|
||||
}
|
||||
|
||||
Disposer.register(project, () -> {
|
||||
statusBar.removeWidget(encodingPanel.ID());
|
||||
statusBar.removeWidget(lineSeparatorPanel.ID());
|
||||
statusBar.removeWidget(positionPanel.ID());
|
||||
statusBar.removeWidget(notificationArea.ID());
|
||||
statusBar.removeWidget(readOnlyAttributePanel.ID());
|
||||
statusBar.removeWidget(insertOverwritePanel.ID());
|
||||
for (String widgetID: widgetIDs) {
|
||||
statusBar.removeWidget(widgetID);
|
||||
}
|
||||
widgetIDs.clear();
|
||||
|
||||
//noinspection deprecation
|
||||
((StatusBarEx)statusBar).removeCustomIndicationComponents();
|
||||
|
||||
@@ -263,12 +263,12 @@ public class IdeRootPane extends JRootPane implements UISettingsListener, Dispos
|
||||
public void dispose() {
|
||||
componentFactory.disposeComponent(myStatusBar, c);
|
||||
}
|
||||
}, "before " + MemoryUsagePanel.WIDGET_ID);
|
||||
}, StatusBar.Anchors.before(MemoryUsagePanel.WIDGET_ID));
|
||||
}
|
||||
}
|
||||
|
||||
myStatusBar.addWidget(myMemoryWidget);
|
||||
myStatusBar.addWidget(new IdeMessagePanel(frame, MessagePool.getInstance()), "before " + MemoryUsagePanel.WIDGET_ID);
|
||||
myStatusBar.addWidget(new IdeMessagePanel(frame, MessagePool.getInstance()), StatusBar.Anchors.before(MemoryUsagePanel.WIDGET_ID));
|
||||
|
||||
setMemoryIndicatorVisible(UISettings.getInstance().getShowMemoryIndicator());
|
||||
}
|
||||
|
||||
+6
@@ -204,6 +204,12 @@ public abstract class EditorBasedStatusBarPopup extends EditorBasedWidget implem
|
||||
}
|
||||
|
||||
protected static class WidgetState {
|
||||
|
||||
public static final WidgetState HIDDEN = new WidgetState("", "", false);
|
||||
static {
|
||||
HIDDEN.setHidden(true);
|
||||
}
|
||||
|
||||
protected WidgetState(String toolTip, String text, boolean actionEnabled) {
|
||||
this.toolTip = toolTip;
|
||||
this.text = text;
|
||||
|
||||
@@ -17,6 +17,7 @@ import com.intellij.openapi.vfs.encoding.EncodingManager;
|
||||
import com.intellij.openapi.vfs.encoding.EncodingManagerImpl;
|
||||
import com.intellij.openapi.vfs.encoding.EncodingUtil;
|
||||
import com.intellij.openapi.vfs.impl.BulkVirtualFileListenerAdapter;
|
||||
import com.intellij.openapi.wm.StatusBar;
|
||||
import com.intellij.openapi.wm.StatusBarWidget;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -32,8 +33,9 @@ public class EncodingPanel extends EditorBasedStatusBarPopup {
|
||||
@NotNull
|
||||
@Override
|
||||
protected WidgetState getWidgetState(@Nullable VirtualFile file) {
|
||||
// this is done to preserve the old behavior; not sure if it is correct
|
||||
if (file == null) return new WidgetState("", "", false);
|
||||
if (file == null) {
|
||||
return WidgetState.HIDDEN;
|
||||
}
|
||||
|
||||
Pair<Charset, String> check = EncodingUtil.getCharsetAndTheReasonTooltip(file);
|
||||
String failReason = check == null ? null : check.second;
|
||||
@@ -78,6 +80,6 @@ public class EncodingPanel extends EditorBasedStatusBarPopup {
|
||||
@Override
|
||||
@NotNull
|
||||
public String ID() {
|
||||
return "Encoding";
|
||||
return StatusBar.StandardWidgets.ENCODING_PANEL;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -50,7 +50,7 @@ public class InsertOverwritePanel extends EditorBasedWidget implements StatusBar
|
||||
@Override
|
||||
@NotNull
|
||||
public String ID() {
|
||||
return "InsertOverwrite";
|
||||
return StatusBar.StandardWidgets.INSERT_OVERWRITE_PANEL;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+5
-2
@@ -24,7 +24,10 @@ public class LineSeparatorPanel extends EditorBasedStatusBarPopup {
|
||||
@NotNull
|
||||
@Override
|
||||
protected WidgetState getWidgetState(@Nullable VirtualFile file) {
|
||||
String lineSeparator = file == null ? null : LoadTextUtil.detectLineSeparator(file, true);
|
||||
if (file == null) {
|
||||
return WidgetState.HIDDEN;
|
||||
}
|
||||
String lineSeparator = LoadTextUtil.detectLineSeparator(file, true);
|
||||
String toolTipText;
|
||||
String panelText;
|
||||
if (lineSeparator != null) {
|
||||
@@ -33,7 +36,7 @@ public class LineSeparatorPanel extends EditorBasedStatusBarPopup {
|
||||
}
|
||||
else {
|
||||
toolTipText = "No line separator";
|
||||
panelText = file != null ? "n/a" : "";
|
||||
panelText = "n/a";
|
||||
}
|
||||
|
||||
return new WidgetState(toolTipText, panelText, lineSeparator != null);
|
||||
|
||||
@@ -48,7 +48,6 @@ public class PositionPanel extends EditorBasedWidget
|
||||
public static final String SPACE = " ";
|
||||
public static final String SEPARATOR = ":";
|
||||
public static final String MAX_POSSIBLE_TEXT = "0000000000000";
|
||||
public static final String ID = "Position";
|
||||
|
||||
private static final int CHAR_COUNT_SYNC_LIMIT = 500_000;
|
||||
private static final String CHAR_COUNT_UNKNOWN = "...";
|
||||
@@ -71,7 +70,7 @@ public class PositionPanel extends EditorBasedWidget
|
||||
@Override
|
||||
@NotNull
|
||||
public String ID() {
|
||||
return ID;
|
||||
return StatusBar.StandardWidgets.POSITION_PANEL;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -60,7 +60,7 @@ public class ToggleReadOnlyAttributePanel implements StatusBarWidget.Multiframe,
|
||||
@Override
|
||||
@NotNull
|
||||
public String ID() {
|
||||
return "ReadOnlyAttribute";
|
||||
return StatusBar.StandardWidgets.READONLY_ATTRIBUTE_PANEL;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -181,6 +181,7 @@
|
||||
</extensionPoint>
|
||||
|
||||
<extensionPoint name="statusBarComponent" interface="com.intellij.openapi.wm.StatusBarCustomComponentFactory"/>
|
||||
<extensionPoint name="statusBarWidgetProvider" interface="com.intellij.openapi.wm.StatusBarWidgetProvider"/>
|
||||
|
||||
<extensionPoint name="checkinHandlerFactory" interface="com.intellij.openapi.vcs.checkin.CheckinHandlerFactory"/>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user