mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
theme.json: preview named colors (IDEA-214797)
GitOrigin-RevId: a946d69951e99762e94934be0d48920df3ecfbee
This commit is contained in:
committed by
intellij-monorepo-bot
parent
73f5f4a202
commit
7e629ae86b
@@ -2,8 +2,8 @@
|
||||
package org.jetbrains.idea.devkit.themes;
|
||||
|
||||
import com.intellij.codeInsight.daemon.LineMarkerSettings;
|
||||
import com.intellij.json.psi.JsonElementGenerator;
|
||||
import com.intellij.json.psi.JsonStringLiteral;
|
||||
import com.intellij.json.psi.*;
|
||||
import com.intellij.json.psi.impl.JsonPsiImplUtils;
|
||||
import com.intellij.lang.annotation.Annotation;
|
||||
import com.intellij.lang.annotation.AnnotationHolder;
|
||||
import com.intellij.lang.annotation.Annotator;
|
||||
@@ -20,6 +20,7 @@ import com.intellij.psi.PsiFile;
|
||||
import com.intellij.ui.ColorChooser;
|
||||
import com.intellij.ui.ColorLineMarkerProvider;
|
||||
import com.intellij.ui.ColorUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.ui.ColorIcon;
|
||||
import com.intellij.util.ui.EmptyIcon;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
@@ -29,6 +30,7 @@ import org.jetbrains.idea.devkit.DevKitBundle;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -60,8 +62,13 @@ public class ThemeColorAnnotator implements Annotator {
|
||||
if (!(element instanceof JsonStringLiteral)) return false;
|
||||
if (!ThemeJsonUtil.isThemeFilename(containingFile.getName())) return false;
|
||||
|
||||
if (JsonPsiImplUtils.isPropertyName((JsonStringLiteral)element)) return false;
|
||||
String text = ((JsonStringLiteral)element).getValue();
|
||||
return isColorCode(text);
|
||||
return isColorCode(text) || isNamedColor(text);
|
||||
}
|
||||
|
||||
private static boolean isNamedColor(String text) {
|
||||
return StringUtil.isLatinAlphanumeric(text);
|
||||
}
|
||||
|
||||
private static boolean isColorCode(@Nullable String text) {
|
||||
@@ -75,19 +82,19 @@ public class ThemeColorAnnotator implements Annotator {
|
||||
private static class MyRenderer extends GutterIconRenderer {
|
||||
private static final int ICON_SIZE = 12;
|
||||
|
||||
private final String myColorHex;
|
||||
private final String myColorText;
|
||||
private final JsonStringLiteral myLiteral;
|
||||
|
||||
|
||||
private MyRenderer(@NotNull String colorHex, @NotNull JsonStringLiteral literal) {
|
||||
myColorHex = colorHex;
|
||||
private MyRenderer(@NotNull String colorText, @NotNull JsonStringLiteral literal) {
|
||||
myColorText = colorText;
|
||||
myLiteral = literal;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Icon getIcon() {
|
||||
Color color = getColor(myColorHex);
|
||||
Color color = getColor(myColorText);
|
||||
if (color != null) {
|
||||
return JBUI.scale(new ColorIcon(ICON_SIZE, color));
|
||||
}
|
||||
@@ -96,28 +103,30 @@ public class ThemeColorAnnotator implements Annotator {
|
||||
|
||||
@Override
|
||||
public boolean isNavigateAction() {
|
||||
return true;
|
||||
return canChooseColor();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getTooltipText() {
|
||||
return "Choose Color";
|
||||
return canChooseColor() ? "Choose Color" : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public AnAction getClickAction() {
|
||||
if (!canChooseColor()) return null;
|
||||
|
||||
return new AnAction("Choose Color...") {
|
||||
@Override
|
||||
public void actionPerformed(@NotNull AnActionEvent e) {
|
||||
Editor editor = e.getData(CommonDataKeys.EDITOR);
|
||||
if (editor == null) return;
|
||||
|
||||
Color currentColor = getColor(myColorHex);
|
||||
Color currentColor = getColor(myColorText);
|
||||
if (currentColor == null) return;
|
||||
|
||||
boolean withAlpha = isRgbaColorHex(myColorHex);
|
||||
boolean withAlpha = isRgbaColorHex(myColorText);
|
||||
Color newColor = ColorChooser.chooseColor(editor.getProject(),
|
||||
editor.getComponent(),
|
||||
DevKitBundle.message("theme.choose.color.dialog.title"),
|
||||
@@ -134,8 +143,21 @@ public class ThemeColorAnnotator implements Annotator {
|
||||
};
|
||||
}
|
||||
|
||||
private boolean canChooseColor() {
|
||||
return isColorCode(myColorText);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Color getColor(@NotNull String colorHex) {
|
||||
private Color getColor(@NotNull String colorText) {
|
||||
if (!isColorCode(colorText)) {
|
||||
return findNamedColor(colorText);
|
||||
}
|
||||
|
||||
return parseColor(colorText);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Color parseColor(@NotNull String colorHex) {
|
||||
boolean isRgba = isRgbaColorHex(colorHex);
|
||||
if (!isRgba && !isRgbColorHex(colorHex)) return null;
|
||||
|
||||
@@ -154,6 +176,19 @@ public class ThemeColorAnnotator implements Annotator {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Color findNamedColor(String colorText) {
|
||||
final PsiFile file = myLiteral.getContainingFile();
|
||||
if (!(file instanceof JsonFile)) return null;
|
||||
final List<JsonProperty> colors = ThemeJsonUtil.getNamedColors((JsonFile)file);
|
||||
final JsonProperty namedColor = ContainerUtil.find(colors, property -> property.getName().equals(colorText));
|
||||
if (namedColor == null) return null;
|
||||
|
||||
final JsonValue value = namedColor.getValue();
|
||||
if (!(value instanceof JsonStringLiteral)) return null;
|
||||
return parseColor(((JsonStringLiteral)value).getValue());
|
||||
}
|
||||
|
||||
private static boolean isRgbaColorHex(@NotNull String colorHex) {
|
||||
return colorHex.length() == HEX_COLOR_LENGTH_RGBA;
|
||||
}
|
||||
@@ -167,13 +202,13 @@ public class ThemeColorAnnotator implements Annotator {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
MyRenderer renderer = (MyRenderer)o;
|
||||
return myColorHex.equals(renderer.myColorHex) &&
|
||||
return myColorText.equals(renderer.myColorText) &&
|
||||
myLiteral.equals(renderer.myLiteral);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(myColorHex, myLiteral);
|
||||
return Objects.hash(myColorText, myLiteral);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,22 @@
|
||||
// Copyright 2000-2019 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 org.jetbrains.idea.devkit.themes;
|
||||
|
||||
import com.intellij.json.psi.*;
|
||||
import com.intellij.json.psi.JsonFile;
|
||||
import com.intellij.json.psi.JsonLiteral;
|
||||
import com.intellij.json.psi.JsonProperty;
|
||||
import com.intellij.model.SymbolResolveResult;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.jetbrains.jsonSchema.impl.JsonSchemaBaseReference;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Konstantin Bulenkov
|
||||
@@ -28,27 +32,11 @@ class ThemeJsonNamedColorPsiReference extends JsonSchemaBaseReference<JsonLitera
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiElement resolveInner() {
|
||||
PsiFile file = getElement().getContainingFile();
|
||||
if (file instanceof JsonFile) {
|
||||
PsiElement object = file.getFirstChild();
|
||||
if (object instanceof JsonObject) {
|
||||
PsiElement[] children = object.getChildren();
|
||||
for (PsiElement child : children) {
|
||||
if (child instanceof JsonProperty && ((JsonProperty)child).getName().equals("colors")) {
|
||||
JsonValue colors = ((JsonProperty)child).getValue();
|
||||
if (colors != null) {
|
||||
for (PsiElement namedColor : colors.getChildren()) {
|
||||
if (namedColor instanceof JsonProperty && ((JsonProperty)namedColor).getName().equals(myName)) {
|
||||
return ((JsonProperty)namedColor).getNameElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
final PsiFile containingFile = getElement().getContainingFile();
|
||||
if (!(containingFile instanceof JsonFile)) return null;
|
||||
|
||||
return null;
|
||||
final List<JsonProperty> namedColors = ThemeJsonUtil.getNamedColors((JsonFile)containingFile);
|
||||
return ContainerUtil.find(namedColors, property -> property.getName().equals(myName));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -3,7 +3,10 @@ package org.jetbrains.idea.devkit.themes;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.ide.ui.UIThemeMetadata;
|
||||
import com.intellij.json.psi.JsonFile;
|
||||
import com.intellij.json.psi.JsonObject;
|
||||
import com.intellij.json.psi.JsonProperty;
|
||||
import com.intellij.json.psi.JsonValue;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiElement;
|
||||
@@ -13,6 +16,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.devkit.themes.metadata.UIThemeMetadataService;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -21,6 +25,9 @@ class ThemeJsonUtil {
|
||||
@NonNls
|
||||
private static final String UI_PROPERTY_NAME = "ui";
|
||||
|
||||
@NonNls
|
||||
private static final String COLORS_PROPERTY_NAME = "colors";
|
||||
|
||||
static boolean isInsideUiProperty(@NotNull JsonProperty property) {
|
||||
PsiElement parent = property;
|
||||
while ((parent = parent.getParent()) != null) {
|
||||
@@ -45,6 +52,16 @@ class ThemeJsonUtil {
|
||||
return StringUtil.endsWithIgnoreCase(fileName, ".theme.json");
|
||||
}
|
||||
|
||||
static List<JsonProperty> getNamedColors(@NotNull JsonFile themeFile) {
|
||||
JsonValue topLevelValue = themeFile.getTopLevelValue();
|
||||
if (!(topLevelValue instanceof JsonObject)) return Collections.emptyList();
|
||||
JsonProperty colorsProperty = ((JsonObject)topLevelValue).findProperty(COLORS_PROPERTY_NAME);
|
||||
if (colorsProperty == null) return Collections.emptyList();
|
||||
final JsonValue colorsValue = colorsProperty.getValue();
|
||||
if (!(colorsValue instanceof JsonObject)) return Collections.emptyList();
|
||||
return ((JsonObject)colorsValue).getPropertyList();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static Pair<UIThemeMetadata, UIThemeMetadata.UIKeyMetadata> findMetadata(@NotNull JsonProperty property) {
|
||||
final String key = property.getName();
|
||||
|
||||
Reference in New Issue
Block a user