mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-117223 Custom background image/colour for each project
This commit is contained in:
@@ -19,7 +19,7 @@
|
||||
<fileLookupInfoProvider implementation="org.intellij.images.completion.ImageLookupInfoProvider"/>
|
||||
<documentationProvider implementation="org.intellij.images.fileTypes.ImageDocumentationProvider"/>
|
||||
|
||||
<statistics.usagesCollector implementation="org.intellij.images.statistics.BackgroundUsageCollector"/>
|
||||
<statistics.usagesCollector implementation="org.intellij.images.statistics.BackgroundImagesUsageCollector"/>
|
||||
</extensions>
|
||||
|
||||
<actions>
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.intellij.images.editor.actions.SetBackgroundImageDialog">
|
||||
<grid id="cbd77" binding="myRoot" layout-manager="GridLayoutManager" row-count="4" column-count="6" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<grid id="cbd77" binding="myRoot" layout-manager="GridLayoutManager" row-count="4" column-count="5" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="10" left="10" bottom="10" right="10"/>
|
||||
<constraints>
|
||||
<xy x="48" y="54" width="652" height="535"/>
|
||||
<xy x="48" y="54" width="721" height="535"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<grid id="4ca83" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<grid id="4ca83" layout-manager="GridLayoutManager" row-count="1" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="3" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
<grid row="3" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="0" anchor="0" fill="3" indent="0" use-parent-layout="true"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
@@ -21,7 +21,7 @@
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Frame background"/>
|
||||
<text value="Frame"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="c72f5" class="com.intellij.ui.components.JBRadioButton" binding="myEditorRb">
|
||||
@@ -29,14 +29,28 @@
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Editor background"/>
|
||||
<actionCommand value=""/>
|
||||
<text value="Editor and tools"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="ec878" class="com.intellij.ui.components.JBCheckBox" binding="myThisProjectOnlyCb">
|
||||
<constraints>
|
||||
<grid row="0" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="This project only"/>
|
||||
</properties>
|
||||
</component>
|
||||
<hspacer id="d9d4b">
|
||||
<constraints>
|
||||
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</hspacer>
|
||||
</children>
|
||||
</grid>
|
||||
<grid id="73c41" binding="myPreviewPanel" layout-manager="BorderLayout" hgap="0" vgap="0">
|
||||
<constraints>
|
||||
<grid row="2" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
<grid row="2" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
@@ -44,19 +58,19 @@
|
||||
</grid>
|
||||
<component id="94212" class="com.intellij.ui.ComboboxWithBrowseButton" binding="myPathField" custom-create="true">
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="5" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
<grid row="0" column="1" row-span="1" col-span="4" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<vspacer id="abb42">
|
||||
<constraints>
|
||||
<grid row="2" column="3" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
<grid row="2" column="2" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
<grid id="1d970" layout-manager="GridLayoutManager" row-count="13" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="2" column="4" row-span="1" col-span="2" vsize-policy="3" hsize-policy="0" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
<grid row="2" column="3" row-span="1" col-span="2" vsize-policy="3" hsize-policy="0" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
@@ -166,7 +180,7 @@
|
||||
</grid>
|
||||
<component id="fe56c" class="javax.swing.JSlider" binding="myOpacitySlider">
|
||||
<constraints>
|
||||
<grid row="1" column="1" row-span="1" col-span="4" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
|
||||
<grid row="1" column="1" row-span="1" col-span="3" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<paintTicks value="false"/>
|
||||
@@ -174,7 +188,7 @@
|
||||
</component>
|
||||
<component id="a265f" class="javax.swing.JSpinner" binding="myOpacitySpinner">
|
||||
<constraints>
|
||||
<grid row="1" column="5" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
|
||||
<grid row="1" column="4" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
@@ -196,11 +210,6 @@
|
||||
<text value="Opacity:"/>
|
||||
</properties>
|
||||
</component>
|
||||
<hspacer id="909f7">
|
||||
<constraints>
|
||||
<grid row="3" column="2" row-span="1" col-span="4" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</hspacer>
|
||||
</children>
|
||||
</grid>
|
||||
<buttonGroups>
|
||||
|
||||
@@ -30,10 +30,12 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.ComboBox;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.TextComponentAccessor;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.ui.CollectionComboBoxModel;
|
||||
import com.intellij.ui.ComboboxWithBrowseButton;
|
||||
import com.intellij.ui.DocumentAdapter;
|
||||
import com.intellij.ui.components.JBCheckBox;
|
||||
import com.intellij.ui.components.JBLabel;
|
||||
import com.intellij.ui.components.JBRadioButton;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
@@ -59,6 +61,7 @@ import static com.intellij.openapi.wm.impl.IdeBackgroundUtil.*;
|
||||
|
||||
public class SetBackgroundImageDialog extends DialogWrapper {
|
||||
private final String myPropertyTmp;
|
||||
private final Project myProject;
|
||||
private JPanel myRoot;
|
||||
private JBRadioButton myEditorRb;
|
||||
private JBRadioButton myScaleRb;
|
||||
@@ -67,6 +70,7 @@ public class SetBackgroundImageDialog extends DialogWrapper {
|
||||
private JSpinner myOpacitySpinner;
|
||||
private JPanel myPreviewPanel;
|
||||
private ComboboxWithBrowseButton myPathField;
|
||||
private JBCheckBox myThisProjectOnlyCb;
|
||||
|
||||
boolean myAdjusting;
|
||||
private String mySelectedPath;
|
||||
@@ -77,6 +81,7 @@ public class SetBackgroundImageDialog extends DialogWrapper {
|
||||
|
||||
public SetBackgroundImageDialog(@NotNull Project project, @Nullable String selectedPath) {
|
||||
super(project, true);
|
||||
myProject = project;
|
||||
setTitle("Background Image");
|
||||
mySelectedPath = selectedPath;
|
||||
myEditorPreview = createEditorPreview();
|
||||
@@ -221,6 +226,8 @@ public class SetBackgroundImageDialog extends DialogWrapper {
|
||||
myScaleRb.setSelected(true);
|
||||
myCenterRb.setSelected(true);
|
||||
myEditorRb.setSelected(true);
|
||||
boolean perProject = !Comparing.equal(getBackgroundSpec(myProject, getSystemProp()), getBackgroundSpec(null, getSystemProp()));
|
||||
myThisProjectOnlyCb.setSelected(perProject);
|
||||
myAdjusting = false;
|
||||
}
|
||||
|
||||
@@ -265,7 +272,7 @@ public class SetBackgroundImageDialog extends DialogWrapper {
|
||||
private void retrieveExistingValue() {
|
||||
myAdjusting = true;
|
||||
String prop = getSystemProp();
|
||||
String value = StringUtil.notNullize(myResults.get(prop), getBackgroundSpec(prop));
|
||||
String value = StringUtil.notNullize(myResults.get(prop), getBackgroundSpec(myProject, prop));
|
||||
String[] split = value.split(",");
|
||||
int opacity = split.length > 1 ? StringUtil.parseInt(split[1], 15) : 15;
|
||||
String fill = split.length > 2 ? split[2] : "scale";
|
||||
@@ -295,7 +302,11 @@ public class SetBackgroundImageDialog extends DialogWrapper {
|
||||
myResults.put(prop, value);
|
||||
|
||||
if (value.startsWith(",")) value = null;
|
||||
PropertiesComponent.getInstance().setValue(prop, value);
|
||||
|
||||
PropertiesComponent propertiesComponent =
|
||||
myThisProjectOnlyCb.isSelected() ?
|
||||
PropertiesComponent.getInstance(myProject) : PropertiesComponent.getInstance();
|
||||
propertiesComponent.setValue(prop, value);
|
||||
|
||||
repaintAllWindows();
|
||||
}
|
||||
|
||||
+23
-5
@@ -15,14 +15,16 @@
|
||||
*/
|
||||
package org.intellij.images.statistics;
|
||||
|
||||
import com.intellij.internal.statistic.AbstractApplicationUsagesCollector;
|
||||
import com.intellij.internal.statistic.CollectUsagesException;
|
||||
import com.intellij.internal.statistic.UsagesCollector;
|
||||
import com.intellij.internal.statistic.beans.GroupDescriptor;
|
||||
import com.intellij.internal.statistic.beans.UsageDescriptor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.intellij.openapi.wm.impl.IdeBackgroundUtil.*;
|
||||
@@ -30,7 +32,7 @@ import static com.intellij.openapi.wm.impl.IdeBackgroundUtil.*;
|
||||
/**
|
||||
* @author gregsh
|
||||
*/
|
||||
public class BackgroundUsageCollector extends UsagesCollector {
|
||||
public class BackgroundImagesUsageCollector extends AbstractApplicationUsagesCollector {
|
||||
@NotNull
|
||||
@Override
|
||||
public GroupDescriptor getGroupId() {
|
||||
@@ -40,9 +42,25 @@ public class BackgroundUsageCollector extends UsagesCollector {
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<UsageDescriptor> getUsages() throws CollectUsagesException {
|
||||
boolean editor = StringUtil.isNotEmpty(getBackgroundSpec(EDITOR_PROP));
|
||||
boolean ide = StringUtil.isNotEmpty(getBackgroundSpec(FRAME_PROP));
|
||||
return ContainerUtil.newHashSet(new UsageDescriptor("editor", editor ? 1 : 0), new UsageDescriptor("frame", ide ? 1 : 0));
|
||||
// join usages from all projects
|
||||
HashMap<String, UsageDescriptor> map = ContainerUtil.newHashMap();
|
||||
for (UsageDescriptor descriptor : super.getUsages()) {
|
||||
String key = descriptor.getKey();
|
||||
int idx = key.indexOf(' ');
|
||||
key = idx > 0 ? key.substring(0, idx) : key;
|
||||
UsageDescriptor existing = map.get(key);
|
||||
if (existing == null || existing.getValue() == 0) {
|
||||
map.put(key, new UsageDescriptor(key, descriptor.getValue()));
|
||||
}
|
||||
}
|
||||
return ContainerUtil.newHashSet(map.values());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<UsageDescriptor> getProjectUsages(@NotNull Project project) throws CollectUsagesException {
|
||||
boolean editor = StringUtil.isNotEmpty(getBackgroundSpec(project, EDITOR_PROP));
|
||||
boolean frame = StringUtil.isNotEmpty(getBackgroundSpec(project, FRAME_PROP));
|
||||
return ContainerUtil.newHashSet(new UsageDescriptor("editor", editor ? 1 : 0), new UsageDescriptor("frame", frame ? 1 : 0));
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,7 @@ import com.intellij.openapi.editor.ex.EditorGutterComponentEx;
|
||||
import com.intellij.openapi.editor.impl.EditorComponentImpl;
|
||||
import com.intellij.openapi.fileEditor.impl.EditorEmptyTextPainter;
|
||||
import com.intellij.openapi.fileEditor.impl.EditorsSplitters;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.AbstractPainter;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
@@ -163,8 +164,10 @@ public class IdeBackgroundUtil {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getBackgroundSpec(@NotNull String propertyName) {
|
||||
return StringUtil.notNullize(PropertiesComponent.getInstance().getValue(propertyName), System.getProperty(propertyName, ""));
|
||||
public static String getBackgroundSpec(@Nullable Project project, @NotNull String propertyName) {
|
||||
String spec = project == null ? null : PropertiesComponent.getInstance(project).getValue(propertyName);
|
||||
if (spec == null) spec = PropertiesComponent.getInstance().getValue(propertyName);
|
||||
return StringUtil.notNullize(spec, System.getProperty(propertyName, ""));
|
||||
}
|
||||
|
||||
public static void repaintAllWindows() {
|
||||
|
||||
@@ -19,12 +19,14 @@ import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.AbstractPainter;
|
||||
import com.intellij.openapi.ui.GraphicsConfig;
|
||||
import com.intellij.openapi.ui.Painter;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.wm.IdeFrame;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.ImageLoader;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
@@ -163,12 +165,12 @@ final class PaintersHelper implements Painter.Listener {
|
||||
}
|
||||
|
||||
public static void initWallpaperPainter(@NotNull String propertyName, @NotNull PaintersHelper painters) {
|
||||
ModalityState modalityState = ModalityState.stateForComponent(painters.myRootComponent);
|
||||
ImagePainter painter = (ImagePainter)newWallpaperPainter(propertyName, modalityState);
|
||||
ImagePainter painter = (ImagePainter)newWallpaperPainter(propertyName, painters.myRootComponent);
|
||||
painters.addPainter(painter, null);
|
||||
}
|
||||
|
||||
private static AbstractPainter newWallpaperPainter(@NotNull final String propertyName, @NotNull final ModalityState modalityState) {
|
||||
private static AbstractPainter newWallpaperPainter(@NotNull final String propertyName,
|
||||
@NotNull final JComponent rootComponent) {
|
||||
return new ImagePainter() {
|
||||
Image image;
|
||||
float alpha;
|
||||
@@ -190,7 +192,9 @@ final class PaintersHelper implements Painter.Listener {
|
||||
}
|
||||
|
||||
boolean ensureImageLoaded() {
|
||||
String value = getBackgroundSpec(propertyName);
|
||||
IdeFrame frame = UIUtil.getParentOfType(IdeFrame.class, rootComponent);
|
||||
Project project = frame == null ? null : frame.getProject();
|
||||
String value = getBackgroundSpec(project, propertyName);
|
||||
if (!Comparing.equal(value, current)) {
|
||||
current = value;
|
||||
loadImageAsync(value);
|
||||
@@ -210,6 +214,7 @@ final class PaintersHelper implements Painter.Listener {
|
||||
place = newPlace;
|
||||
boolean newOk = newImage != null;
|
||||
if (prevOk || newOk) {
|
||||
ModalityState modalityState = ModalityState.stateForComponent(rootComponent);
|
||||
if (modalityState.dominates(ModalityState.NON_MODAL)) {
|
||||
UIUtil.getActiveWindow().repaint();
|
||||
}
|
||||
@@ -236,6 +241,7 @@ final class PaintersHelper implements Painter.Listener {
|
||||
: new File(PathManager.getConfigPath(), filePath)).toURI().toURL();
|
||||
ApplicationManager.getApplication().executeOnPooledThread(() -> {
|
||||
final Image m = ImageLoader.loadFromUrl(url);
|
||||
ModalityState modalityState = ModalityState.stateForComponent(rootComponent);
|
||||
ApplicationManager.getApplication().invokeLater(() -> resetImage(propertyValue, m, newAlpha, newFillType, newPlace), modalityState);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user