separate fill type and place; clear button

This commit is contained in:
Gregory.Shrago
2016-05-17 21:02:52 +03:00
parent 50c1d859cd
commit 6edea5d413
5 changed files with 122 additions and 75 deletions
+3 -2
View File
@@ -41,9 +41,10 @@
description="Show a chessboard on transparent image parts">
</action>
<action class="org.intellij.images.editor.actions.SetBackgroundImageAction"
id="Images.SetBackgroundImageAction"
id="Images.SetBackgroundImage"
text="Set Background Image">
<add-to-group group-id="ProjectViewPopupMenu"/>
<add-to-group group-id="EditorPopupMenu3"/>
</action>
<group id="Images.EditorToolbar">
<reference id="Images.ToggleTransparencyChessboard"/>
@@ -81,7 +82,7 @@
<separator/>
<reference id="Images.EditorToolbar"/>
<separator/>
<reference id="CloseEditor"/>
<reference id="Images.SetBackgroundImage"/>
<separator/>
<reference id="AddToFavorites"/>
<separator/>
@@ -3,7 +3,7 @@
<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">
<margin top="10" left="10" bottom="10" right="10"/>
<constraints>
<xy x="48" y="54" width="652" height="456"/>
<xy x="48" y="54" width="652" height="535"/>
</constraints>
<properties/>
<border type="none"/>
@@ -53,7 +53,7 @@
<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"/>
</constraints>
</vspacer>
<grid id="1d970" layout-manager="GridLayoutManager" row-count="11" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<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"/>
@@ -66,7 +66,7 @@
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Placement:"/>
<text value="Fill type:"/>
</properties>
</component>
<component id="a8fd9" class="com.intellij.ui.components.JBRadioButton" binding="myScaleRb">
@@ -85,9 +85,9 @@
<text value="Tile"/>
</properties>
</component>
<component id="1eb66" class="com.intellij.ui.components.JBRadioButton" default-binding="true">
<component id="1eb66" class="com.intellij.ui.components.JBRadioButton" binding="myCenterRb">
<constraints>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="5" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Center"/>
@@ -95,7 +95,7 @@
</component>
<component id="77b44" class="com.intellij.ui.components.JBRadioButton" default-binding="true">
<constraints>
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="6" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Top-left"/>
@@ -103,7 +103,7 @@
</component>
<component id="2830" class="com.intellij.ui.components.JBRadioButton" default-binding="true">
<constraints>
<grid row="5" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="7" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Top-center"/>
@@ -111,7 +111,7 @@
</component>
<component id="683fb" class="com.intellij.ui.components.JBRadioButton" default-binding="true">
<constraints>
<grid row="6" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="8" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Top-right"/>
@@ -119,7 +119,7 @@
</component>
<component id="961d9" class="com.intellij.ui.components.JBRadioButton" default-binding="true">
<constraints>
<grid row="7" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="9" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Bottom-left"/>
@@ -127,7 +127,7 @@
</component>
<component id="b2175" class="com.intellij.ui.components.JBRadioButton" default-binding="true">
<constraints>
<grid row="8" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="10" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Bottom-center"/>
@@ -135,7 +135,7 @@
</component>
<component id="f09c6" class="com.intellij.ui.components.JBRadioButton" default-binding="true">
<constraints>
<grid row="9" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="11" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Bottom-right"/>
@@ -143,9 +143,25 @@
</component>
<vspacer id="f690c">
<constraints>
<grid row="10" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
<grid row="12" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<component id="adc3f" class="com.intellij.ui.components.JBRadioButton" default-binding="true">
<constraints>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Plain"/>
</properties>
</component>
<component id="f6ce5" class="com.intellij.ui.components.JBLabel">
<constraints>
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Placement:"/>
</properties>
</component>
</children>
</grid>
<component id="fe56c" class="javax.swing.JSlider" binding="myOpacitySlider">
@@ -195,15 +211,22 @@
</group>
<group name="myType">
<member id="a8fd9"/>
</group>
<group name="fillGroup">
<member id="adc3f"/>
<member id="adc3f"/>
<member id="a8fd9"/>
<member id="fc37b"/>
<member id="1eb66"/>
<member id="77b44"/>
<member id="2830"/>
<member id="683fb"/>
<member id="961d9"/>
</group>
<group name="placeGroup">
<member id="b2175"/>
<member id="b2175"/>
<member id="77b44"/>
<member id="f09c6"/>
<member id="1eb66"/>
<member id="961d9"/>
<member id="683fb"/>
<member id="2830"/>
</group>
</buttonGroups>
</form>
@@ -15,6 +15,7 @@
*/
package org.intellij.images.editor.actions;
import com.intellij.CommonBundle;
import com.intellij.application.options.colors.ColorAndFontOptions;
import com.intellij.application.options.colors.SimpleEditorPreview;
import com.intellij.ide.util.PropertiesComponent;
@@ -60,11 +61,12 @@ public class SetBackgroundImageDialog extends DialogWrapper {
private final String myPropertyTmp;
private JPanel myRoot;
private JBRadioButton myEditorRb;
private JBRadioButton myScaleRb;
private JBRadioButton myCenterRb;
private JSlider myOpacitySlider;
private JSpinner myOpacitySpinner;
private JPanel myPreviewPanel;
private ComboboxWithBrowseButton myPathField;
private JBRadioButton myScaleRb;
boolean myAdjusting;
private String mySelectedPath;
@@ -191,10 +193,15 @@ public class SetBackgroundImageDialog extends DialogWrapper {
button.setActionCommand(button.getText());
button.addChangeListener(this::targetChanged);
}
for (Enumeration<AbstractButton> e = getTypeRbGroup().getElements(); e.hasMoreElements();) {
for (Enumeration<AbstractButton> e = getFillRbGroup().getElements(); e.hasMoreElements();) {
AbstractButton button = e.nextElement();
button.setActionCommand(button.getText());
button.addChangeListener(this::fillTypeChanged);
button.addChangeListener(this::fillOrPlaceChanged);
}
for (Enumeration<AbstractButton> e = getPlaceRbGroup().getElements(); e.hasMoreElements();) {
AbstractButton button = e.nextElement();
button.setActionCommand(button.getText());
button.addChangeListener(this::fillOrPlaceChanged);
}
ChangeListener opacitySync = new ChangeListener() {
@@ -220,6 +227,7 @@ public class SetBackgroundImageDialog extends DialogWrapper {
myOpacitySlider.setValue(15);
myOpacitySpinner.setValue(15);
myScaleRb.setSelected(true);
myCenterRb.setSelected(true);
myEditorRb.setSelected(true);
myAdjusting = false;
}
@@ -232,7 +240,7 @@ public class SetBackgroundImageDialog extends DialogWrapper {
updatePreview();
}
private void fillTypeChanged(ChangeEvent event) {
private void fillOrPlaceChanged(ChangeEvent event) {
updatePreview();
}
@@ -252,7 +260,7 @@ public class SetBackgroundImageDialog extends DialogWrapper {
mySelectedPath = path;
if (StringUtil.isEmptyOrSpaces(path)) return;
CollectionComboBoxModel<String> comboModel = getComboModel();
if (!comboModel.getItems().contains(path)) {
if (!comboModel.contains(path)) {
comboModel.add(path);
}
comboModel.setSelectedItem(path);
@@ -264,20 +272,15 @@ public class SetBackgroundImageDialog extends DialogWrapper {
String prop = getSystemProp();
String value = StringUtil.notNullize(myResults.get(prop), getProperty(prop));
String[] split = value.split(",");
int opacity = split.length > 1 ? StringUtil.parseInt(split[1], 15) : 15;
String fill = split.length > 2 ? split[2] : "scale";
String place = split.length > 3 ? split[3] : "center";
setSelectedPath(split[0]);
mySelectedPath = null;
int opacity = split.length > 1 ? StringUtil.parseInt(split[1], 15) : 15;
myOpacitySlider.setValue(opacity);
myOpacitySpinner.setValue(opacity);
String type = split.length > 2 ? split[2] : "scale";
for (Enumeration<AbstractButton> e = getTypeRbGroup().getElements(); e.hasMoreElements(); ) {
AbstractButton button = e.nextElement();
String s = button.getActionCommand().replace('-', '_');
if (s.equalsIgnoreCase(type)) {
button.setSelected(true);
break;
}
}
setSelected(getFillRbGroup(), fill);
setSelected(getPlaceRbGroup(), place);
myAdjusting = false;
}
@@ -294,7 +297,7 @@ public class SetBackgroundImageDialog extends DialogWrapper {
String prop = getSystemProp();
myResults.put(prop, value);
if (value.startsWith(",")) return;
if (value.startsWith(",")) value = null;
PropertiesComponent.getInstance().setValue(prop, value);
super.doOKAction();
@@ -319,9 +322,10 @@ public class SetBackgroundImageDialog extends DialogWrapper {
private void restoreRecentImages() {
String value = PropertiesComponent.getInstance().getValue(getRecentItemsKey());
if (value == null) return;
CollectionComboBoxModel<String> model = getComboModel();
for (String s : value.split("\n")) {
//noinspection unchecked
getComboModel().add(s);
if (StringUtil.isEmptyOrSpaces(s) || model.contains(s)) continue;
model.add(s);
}
}
@@ -335,27 +339,44 @@ public class SetBackgroundImageDialog extends DialogWrapper {
}
private void updatePreview() {
if (myAdjusting) return;
String prop = getSystemProp();
String value = calcNewValue();
System.setProperty(myPropertyTmp, value);
myResults.put(prop, value);
myPreviewPanel.validate();
myPreviewPanel.repaint();
boolean clear = value.startsWith(",");
getOKAction().putValue(Action.NAME, clear ? "Clear" : CommonBundle.getOkButtonText());
}
@NotNull
private String calcNewValue() {
String path = (String)myPathField.getComboBox().getEditor().getItem();
String type = getTypeRbGroup().getSelection().getActionCommand()
.replace('-', '_').toLowerCase(Locale.ENGLISH);
return path.trim() + "," + myOpacitySpinner.getValue() + "," + type;
String type = getFillRbGroup().getSelection().getActionCommand().replace('-', '_');
String place = getPlaceRbGroup().getSelection().getActionCommand().replace('-', '_');
return path.trim() + "," + myOpacitySpinner.getValue() + "," + (type + "," + place).toLowerCase(Locale.ENGLISH);
}
private ButtonGroup getTypeRbGroup() {
private static void setSelected(ButtonGroup group, String fill) {
for (Enumeration<AbstractButton> e = group.getElements(); e.hasMoreElements(); ) {
AbstractButton button = e.nextElement();
String s = button.getActionCommand().replace('-', '_');
if (s.equalsIgnoreCase(fill)) {
button.setSelected(true);
break;
}
}
}
private ButtonGroup getFillRbGroup() {
return ((DefaultButtonModel)myScaleRb.getModel()).getGroup();
}
private ButtonGroup getPlaceRbGroup() {
return ((DefaultButtonModel)myCenterRb.getModel()).getGroup();
}
private ButtonGroup getTargetRbGroup() {
return ((DefaultButtonModel)myEditorRb.getModel()).getGroup();
}
@@ -120,7 +120,7 @@ public class IdeBackgroundUtil {
Image centerImage = url == null ? null : ImageLoader.loadFromUrl(url);
if (centerImage != null) {
painters.addPainter(PaintersHelper.newImagePainter(centerImage, PaintersHelper.FillType.TOP_CENTER, 1.0f, JBUI.insets(10, 0, 0, 0)), null);
painters.addPainter(PaintersHelper.newImagePainter(centerImage, PaintersHelper.Fill.PLAIN, PaintersHelper.Place.TOP_CENTER, 1.0f, JBUI.insets(10, 0, 0, 0)), null);
}
painters.addPainter(new AbstractPainter() {
EditorEmptyTextPainter p = ServiceManager.getService(EditorEmptyTextPainter.class);
@@ -152,8 +152,11 @@ final class PaintersHelper implements Painter.Listener {
}
}
public enum FillType {
BG_CENTER, TILE, SCALE,
public enum Fill {
PLAIN, SCALE, TILE
}
public enum Place {
CENTER, TOP_CENTER, BOTTOM_CENTER,
TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT
}
@@ -169,7 +172,8 @@ final class PaintersHelper implements Painter.Listener {
Image image;
float alpha;
Insets insets;
FillType fillType;
Fill fillType;
Place place;
String current;
@@ -181,7 +185,7 @@ final class PaintersHelper implements Painter.Listener {
@Override
public void executePaint(Component component, Graphics2D g) {
if (image == null) return; // covered by needsRepaint()
executePaint(g, component, image, fillType, alpha, insets);
executePaint(g, component, image, fillType, place, alpha, insets);
}
boolean ensureImageLoaded() {
@@ -195,14 +199,15 @@ final class PaintersHelper implements Painter.Listener {
return image != null;
}
private void resetImage(String value, Image newImage, float newAlpha, FillType newFillType) {
private void resetImage(String value, Image newImage, float newAlpha, Fill newFill, Place newPlace) {
if (!Comparing.equal(current, value)) return;
boolean prevOk = image != null;
clearImages(-1);
image = newImage;
insets = JBUI.emptyInsets();
alpha = newAlpha;
fillType = newFillType;
fillType = newFill;
place = newPlace;
boolean newOk = newImage != null;
if (prevOk || newOk) {
repaintAllWindows();
@@ -212,9 +217,14 @@ final class PaintersHelper implements Painter.Listener {
private void loadImageAsync(final String propertyValue) {
String[] parts = (propertyValue != null ? propertyValue : propertyName + ".png").split(",");
final float newAlpha = Math.abs(Math.min(StringUtil.parseInt(parts.length > 1 ? parts[1] : "", 10) / 100f, 1f));
final FillType newFillType = StringUtil.parseEnum(parts.length > 2 ? parts[2].toUpperCase(Locale.ENGLISH) : "", FillType.SCALE, FillType.class);
final Fill newFillType = StringUtil.parseEnum(parts.length > 2 ? parts[2].toUpperCase(Locale.ENGLISH) : "", Fill.SCALE, Fill.class);
final Place newPlace = StringUtil.parseEnum(parts.length > 3 ? parts[3].toUpperCase(Locale.ENGLISH) : "", Place.CENTER, Place.class);
String filePath = parts[0];
if (StringUtil.isEmpty(filePath)) {
resetImage(propertyValue, null, newAlpha, newFillType, newPlace);
return;
}
try {
String filePath = parts[0];
URL url = filePath.contains("://") ? new URL(filePath) :
(FileUtil.isAbsolutePlatformIndependent(filePath)
? new File(filePath)
@@ -226,14 +236,14 @@ final class PaintersHelper implements Painter.Listener {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
resetImage(propertyValue, m, newAlpha, newFillType);
resetImage(propertyValue, m, newAlpha, newFillType, newPlace);
}
}, modalityState);
}
});
}
catch (Exception e) {
resetImage(propertyValue, null, newAlpha, newFillType);
resetImage(propertyValue, null, newAlpha, newFillType, newPlace);
}
}
};
@@ -245,7 +255,7 @@ final class PaintersHelper implements Painter.Listener {
}
}
public static AbstractPainter newImagePainter(@NotNull final Image image, final FillType fillType, final float alpha, final Insets insets) {
public static AbstractPainter newImagePainter(@NotNull final Image image, final Fill fillType, final Place place, final float alpha, final Insets insets) {
return new ImagePainter() {
@Override
public boolean needsRepaint() {
@@ -254,7 +264,7 @@ final class PaintersHelper implements Painter.Listener {
@Override
public void executePaint(Component component, Graphics2D g) {
executePaint(g, component, image, fillType, alpha, insets);
executePaint(g, component, image, fillType, place, alpha, insets);
}
};
}
@@ -274,7 +284,7 @@ final class PaintersHelper implements Painter.Listener {
final Map<GraphicsConfiguration, Cached> cachedMap = ContainerUtil.newHashMap();
public void executePaint(Graphics2D g, Component component, Image image, FillType fillType, float alpha, Insets insets) {
public void executePaint(Graphics2D g, Component component, Image image, Fill fillType, Place place, float alpha, Insets insets) {
int cw0 = component.getWidth();
int ch0 = component.getHeight();
Insets i = JBUI.insets(insets.top * ch0 / 100, insets.left * cw0 / 100, insets.bottom * ch0 / 100, insets.right * cw0 / 100);
@@ -288,9 +298,9 @@ final class PaintersHelper implements Painter.Listener {
GraphicsConfiguration cfg = g.getDeviceConfiguration();
Cached cached = cachedMap.get(cfg);
VolatileImage scaled = cached == null ? null : cached.image;
if (fillType == FillType.SCALE || fillType == FillType.TILE) {
if (fillType == Fill.SCALE || fillType == Fill.TILE) {
int sw, sh;
if (fillType == FillType.SCALE) {
if (fillType == Fill.SCALE) {
boolean useWidth = cw * h > ch * w;
sw = useWidth ? cw : w * ch / h;
sh = useWidth ? h * cw / w : ch;
@@ -312,7 +322,7 @@ final class PaintersHelper implements Painter.Listener {
}
Graphics2D gg = scaled.createGraphics();
gg.setComposite(AlphaComposite.Src);
if (fillType == FillType.SCALE) {
if (fillType == Fill.SCALE) {
gg.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
gg.drawImage(image, 0, 0, sw, sh, null);
@@ -347,18 +357,17 @@ final class PaintersHelper implements Painter.Listener {
}
int x, y;
if (fillType == FillType.CENTER || fillType == FillType.BG_CENTER ||
fillType == FillType.SCALE || fillType == FillType.TILE ||
fillType == FillType.TOP_CENTER || fillType == FillType.BOTTOM_CENTER) {
if (place == Place.CENTER ||
place == Place.TOP_CENTER || place == Place.BOTTOM_CENTER) {
x = i.left + (cw - w) / 2;
y = fillType == FillType.TOP_CENTER ? i.top :
fillType == FillType.BOTTOM_CENTER ? ch0 - i.bottom - h :
y = place == Place.TOP_CENTER ? i.top :
place == Place.BOTTOM_CENTER ? ch0 - i.bottom - h :
i.top + (ch - h) / 2;
}
else if (fillType == FillType.TOP_LEFT || fillType == FillType.TOP_RIGHT ||
fillType == FillType.BOTTOM_LEFT || fillType == FillType.BOTTOM_RIGHT) {
x = fillType == FillType.TOP_LEFT || fillType == FillType.BOTTOM_LEFT ? i.left : cw0 - i.right - w;
y = fillType == FillType.TOP_LEFT || fillType == FillType.TOP_RIGHT ? i.top : ch0 - i.bottom - h;
else if (place == Place.TOP_LEFT || place == Place.TOP_RIGHT ||
place == Place.BOTTOM_LEFT || place == Place.BOTTOM_RIGHT) {
x = place == Place.TOP_LEFT || place == Place.BOTTOM_LEFT ? i.left : cw0 - i.right - w;
y = place == Place.TOP_LEFT || place == Place.TOP_RIGHT ? i.top : ch0 - i.bottom - h;
}
else {
return;
@@ -366,13 +375,6 @@ final class PaintersHelper implements Painter.Listener {
GraphicsConfig gc = new GraphicsConfig(g).setAlpha(alpha);
UIUtil.drawImage(g, scaled, x, y, w, h, null);
if (fillType == FillType.BG_CENTER) {
g.setColor(component.getBackground());
g.fillRect(0, 0, x, ch0);
g.fillRect(x, 0, w, h);
g.fillRect(x + w, 0, x, ch0);
g.fillRect(x, y + h, w, y);
}
gc.restore();
}