Skip to content

Commit 0076139

Browse files
authored
Remove dependencies on built-in Flutter icons (#5824)
* Remove dependencies on built-in Flutter icons * cleanup
1 parent 05ff570 commit 0076139

File tree

8 files changed

+107
-49
lines changed

8 files changed

+107
-49
lines changed

gen/icons/FlutterIcons.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ private static Icon load(String path) {
2121

2222
public static final Icon Phone = load("/icons/phone.png");
2323
public static final Icon Feedback = load("/icons/feedback.png");
24+
public static final Icon RefreshItems = load("/icons/frefresh_items.png");
2425

2526
public static final Icon Dart_16 = load("/icons/dart_16.svg");
2627

resources/icons/refresh_items.png

463 Bytes
Loading

src/io/flutter/actions/DeviceSelectorRefresherAction.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@
88
import com.intellij.openapi.actionSystem.AnAction;
99
import com.intellij.openapi.actionSystem.AnActionEvent;
1010
import com.intellij.openapi.project.Project;
11-
import io.flutter.editor.FlutterMaterialIcons;
11+
import icons.FlutterIcons;
1212
import io.flutter.run.daemon.DeviceService;
1313
import io.flutter.utils.FlutterModuleUtils;
1414
import org.jetbrains.annotations.NotNull;
1515

1616
public class DeviceSelectorRefresherAction extends AnAction {
1717
public DeviceSelectorRefresherAction() {
18-
super(FlutterMaterialIcons.getIconForName("refresh"));
18+
super(FlutterIcons.RefreshItems);
1919
}
2020

2121
@Override

src/io/flutter/editor/FlutterCompletionContributor.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public class FlutterCompletionContributor extends DartCompletionExtension {
2727
@Override
2828
@Nullable
2929
public LookupElementBuilder createLookupElement(@NotNull final Project project, @NotNull final CompletionSuggestion suggestion) {
30-
final Icon icon = findIcon(suggestion);
30+
final Icon icon = findIcon(suggestion, project);
3131
if (icon != null) {
3232
final LookupElementBuilder lookup =
3333
DartServerCompletionContributor.createLookupElement(project, suggestion).withTypeText("", icon, false);
@@ -38,7 +38,8 @@ public LookupElementBuilder createLookupElement(@NotNull final Project project,
3838
return null;
3939
}
4040

41-
private static Icon findIcon(@NotNull final CompletionSuggestion suggestion) {
41+
@Nullable
42+
private static Icon findIcon(@NotNull final CompletionSuggestion suggestion, @NotNull Project project) {
4243
final Element element = suggestion.getElement();
4344
if (element != null) {
4445
final String returnType = element.getReturnType();
@@ -59,12 +60,12 @@ else if (Objects.equals(declaringType, "CupertinoColors")) {
5960
}
6061
}
6162
else if (Objects.equals(declaringType, "Icons")) {
62-
final Icon icon = FlutterMaterialIcons.getIconForName(name);
63+
final Icon icon = FlutterIconLineMarkerProvider.getMaterialIconByName(project, name);
6364
// If we have no icon, show an empty node (which is preferable to the default "IconData" text).
6465
return icon != null ? icon : EMPTY_ICON;
6566
}
6667
else if (Objects.equals(declaringType, "CupertinoIcons")) {
67-
final Icon icon = FlutterCupertinoIcons.getIconForName(name);
68+
final Icon icon = FlutterIconLineMarkerProvider.getCupertinoIconByName(project, name);
6869
// If we have no icon, show an empty node (which is preferable to the default "IconData" text).
6970
return icon != null ? icon : EMPTY_ICON;
7071
}

src/io/flutter/editor/FlutterIconLineMarkerProvider.java

Lines changed: 75 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,40 @@ public static void initialize() {
7474
BuiltInPaths.put("CupertinoIcons", CupertinoRelativeIconsPath);
7575
}
7676

77+
@Nullable
78+
public static Icon getCupertinoIconByName(@Nullable Project project, @NotNull String iconName) {
79+
if (project == null) return null;
80+
final FlutterSdk sdk = FlutterSdk.getFlutterSdk(project);
81+
if (sdk == null) return null;
82+
final IconInfo iconDef =
83+
findStandardDefinition("CupertinoIcons", iconName, project, sdk.getHomePath() + BuiltInPaths.get("CupertinoIcons"), sdk);
84+
if (iconDef == null) return null;
85+
final String path = FlutterSdkUtil.getPathToCupertinoIconsPackage(project);
86+
// <pub_cache>/hosted/pub.dartlang.org/cupertino_icons-v.m.n/assets/CupertinoIcons.ttf
87+
return findStandardIconFromDef(iconName, iconDef, path + CupertinoRelativeAssetPath);
88+
}
89+
90+
@Nullable
91+
public static Icon getMaterialIconByName(@Nullable Project project, @NotNull String iconName) {
92+
if (project == null) return null;
93+
final FlutterSdk sdk = FlutterSdk.getFlutterSdk(project);
94+
if (sdk == null) return null;
95+
final IconInfo iconDef =
96+
findStandardDefinition("Icons", iconName, project, sdk.getHomePath() + BuiltInPaths.get("Icons"), sdk);
97+
if (iconDef == null) return null;
98+
// <flutter-sdk>/bin/cache/artifacts/material_fonts/MaterialIcons-Regular.otf
99+
return findStandardIconFromDef(iconName, iconDef, sdk.getHomePath() + MaterialRelativeAssetPath);
100+
}
101+
102+
@Nullable
103+
public static Icon getMaterialIconFromCodepoint(@Nullable Project project, int codepoint) {
104+
if (project == null) return null;
105+
final FlutterSdk sdk = FlutterSdk.getFlutterSdk(project);
106+
if (sdk == null) return null;
107+
final IconPreviewGenerator generator = new IconPreviewGenerator(sdk.getHomePath() + MaterialRelativeAssetPath);
108+
return generator.convert(codepoint);
109+
}
110+
77111
@Nullable("null means disabled")
78112
@Override
79113
public @GutterName String getName() {
@@ -87,9 +121,10 @@ public LineMarkerInfo<?> getLineMarkerInfo(@NotNull PsiElement element) {
87121
return sdk == null ? null : getLineMarkerInfo(element, sdk);
88122
}
89123

124+
@SuppressWarnings("MissingRecentApi")
90125
@VisibleForTesting
91126
@Nullable
92-
LineMarkerInfo<?> getLineMarkerInfo(@NotNull PsiElement element, @NotNull FlutterSdk sdk) {
127+
static LineMarkerInfo<?> getLineMarkerInfo(@NotNull PsiElement element, @NotNull FlutterSdk sdk) {
93128
if ((element.getNode() != null ? element.getNode().getElementType() : null) != DartTokenTypes.IDENTIFIER) return null;
94129

95130
final String name = element.getText();
@@ -146,30 +181,12 @@ LineMarkerInfo<?> getLineMarkerInfo(@NotNull PsiElement element, @NotNull Flutte
146181
assert parentNode != null;
147182
if (parentNode.getElementType() == DartTokenTypes.CALL_EXPRESSION) {
148183
// Check font family and package
149-
final DartArguments arguments = DartPsiImplUtil.getArguments((DartCallExpression)parent);
150-
if (arguments == null) return null;
151-
final String family = getValueOfNamedArgument(arguments, "fontFamily");
152-
final PsiElement fontPackage = getNamedArgumentExpression(arguments, "fontPackage");
153-
final String argument = getValueOfPositionalArgument(arguments, 0);
154-
if (argument == null) return null;
155-
final Icon icon = getIconFromPackage(fontPackage, family, argument, element.getProject(), sdk);
156-
if (icon != null) {
157-
return createLineMarker(element, icon);
158-
}
184+
return getIconFromArguments(DartPsiImplUtil.getArguments((DartCallExpression)parent), element, sdk);
159185
}
160186
else if (parentNode.getElementType() == DartTokenTypes.SIMPLE_TYPE) {
161187
parent = getNewExprFromType(parent);
162188
if (parent == null) return null;
163-
final DartArguments arguments = DartPsiImplUtil.getArguments((DartNewExpression)parent);
164-
if (arguments == null) return null;
165-
final String family = getValueOfNamedArgument(arguments, "fontFamily");
166-
final PsiElement fontPackage = getNamedArgumentExpression(arguments, "fontPackage");
167-
final String argument = getValueOfPositionalArgument(arguments, 0);
168-
if (argument == null) return null;
169-
final Icon icon = getIconFromPackage(fontPackage, family, argument, element.getProject(), sdk);
170-
if (icon != null) {
171-
return createLineMarker(element, icon);
172-
}
189+
return getIconFromArguments(DartPsiImplUtil.getArguments((DartNewExpression)parent), element, sdk);
173190
}
174191
else {
175192
final PsiElement idNode = refExpr.getFirstChild();
@@ -181,17 +198,10 @@ else if (parentNode.getElementType() == DartTokenTypes.SIMPLE_TYPE) {
181198
final String selector = AstBufferUtil.getTextSkippingWhitespaceComments(selectorNode.getNode());
182199
final Icon icon;
183200
if (name.equals("Icons")) {
184-
final IconInfo iconDef = findStandardDefinition(name, selector, element.getProject(), knownPath, sdk);
185-
if (iconDef == null) return null;
186-
// <flutter-sdk>/bin/cache/artifacts/material_fonts/MaterialIcons-Regular.otf
187-
icon = findStandardIconFromDef(name, iconDef, sdk.getHomePath() + MaterialRelativeAssetPath);
201+
icon = getMaterialIconByName(element.getProject(), selector);
188202
}
189203
else if (name.equals("CupertinoIcons")) {
190-
final IconInfo iconDef = findStandardDefinition(name, selector, element.getProject(), knownPath, sdk);
191-
if (iconDef == null) return null;
192-
final String path = FlutterSdkUtil.getPathToCupertinoIconsPackage(element.getProject());
193-
// <pub_cache>/hosted/pub.dartlang.org/cupertino_icons-v.m.n/assets/CupertinoIcons.ttf
194-
icon = findStandardIconFromDef(name, iconDef, path + CupertinoRelativeAssetPath);
204+
icon = getCupertinoIconByName(element.getProject(), selector);
195205
}
196206
else {
197207
// Note: I want to keep this code until I'm sure we won't use pubspec.yaml.
@@ -227,7 +237,24 @@ else if (name.equals("CupertinoIcons")) {
227237
}
228238

229239
@Nullable
230-
private IconInfo findStandardDefinition(@NotNull String className, @NotNull String iconName, @NotNull Project project, @Nullable String path, @NotNull FlutterSdk sdk) {
240+
private static LineMarkerInfo<PsiElement> getIconFromArguments(@Nullable DartArguments arguments,
241+
@NotNull PsiElement element,
242+
@NotNull FlutterSdk sdk) {
243+
if (arguments == null) return null;
244+
final String family = getValueOfNamedArgument(arguments, "fontFamily");
245+
final PsiElement fontPackage = getNamedArgumentExpression(arguments, "fontPackage");
246+
final String argument = getValueOfPositionalArgument(arguments, 0);
247+
if (argument == null) return null;
248+
final Icon icon = getIconFromPackage(fontPackage, family, argument, element.getProject(), sdk);
249+
return icon == null ? null : createLineMarker(element, icon);
250+
}
251+
252+
@Nullable
253+
private static IconInfo findStandardDefinition(@NotNull String className,
254+
@NotNull String iconName,
255+
@NotNull Project project,
256+
@Nullable String path,
257+
@NotNull FlutterSdk sdk) {
231258
if (path != null) {
232259
return findDefinition(className, iconName, project, path);
233260
}
@@ -236,7 +263,7 @@ private IconInfo findStandardDefinition(@NotNull String className, @NotNull Stri
236263
}
237264

238265
@Nullable
239-
private Icon findStandardIconFromDef(@NotNull String name, @NotNull IconInfo iconDef, @NotNull String path) {
266+
private static Icon findStandardIconFromDef(@NotNull String name, @NotNull IconInfo iconDef, @NotNull String path) {
240267
assert LocalFileSystem.getInstance() != null;
241268
final VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByPath(path);
242269
if (virtualFile == null) return null;
@@ -246,7 +273,11 @@ private Icon findStandardIconFromDef(@NotNull String name, @NotNull IconInfo ico
246273

247274
// Note: package flutter_icons is not currently supported because it takes forever to analyze it.
248275
@Nullable
249-
private Icon getIconFromPackage(@Nullable PsiElement aPackage, @Nullable String family, @NotNull String argument, @NotNull Project project, @NotNull FlutterSdk sdk) {
276+
private static Icon getIconFromPackage(@Nullable PsiElement aPackage,
277+
@Nullable String family,
278+
@NotNull String argument,
279+
@NotNull Project project,
280+
@NotNull FlutterSdk sdk) {
250281
final int code;
251282
try {
252283
code = parseLiteralNumber(argument);
@@ -257,16 +288,17 @@ private Icon getIconFromPackage(@Nullable PsiElement aPackage, @Nullable String
257288
family = family == null ? "MaterialIcons" : family;
258289
if (aPackage == null) {
259290
// Looking for IconData with no package -- package specification not currently supported.
260-
final String relativeAssetPath = family.equals("MaterialIcons") ? MaterialRelativeAssetPath : CupertinoRelativeAssetPath;
261-
// TODO Base path is wrong for cupertino -- is there a test for this branch (IconData with cupertino family)?
262-
final IconPreviewGenerator generator = new IconPreviewGenerator(sdk.getHomePath() + relativeAssetPath);
291+
final String assetPath = family.equals("MaterialIcons")
292+
? sdk.getHomePath() + MaterialRelativeAssetPath
293+
: FlutterSdkUtil.getPathToCupertinoIconsPackage(project) + CupertinoRelativeAssetPath;
294+
final IconPreviewGenerator generator = new IconPreviewGenerator(assetPath);
263295
return generator.convert(code);
264296
}
265297
return null;
266298
}
267299

268300
@Nullable
269-
private LineMarkerInfo<PsiElement> createLineMarker(@Nullable PsiElement element, @NotNull Icon icon) {
301+
private static LineMarkerInfo<PsiElement> createLineMarker(@Nullable PsiElement element, @NotNull Icon icon) {
270302
if (element == null) return null;
271303
assert element.getTextRange() != null;
272304
//noinspection MissingRecentApi
@@ -275,7 +307,10 @@ private LineMarkerInfo<PsiElement> createLineMarker(@Nullable PsiElement element
275307
}
276308

277309
@Nullable
278-
private IconInfo findDefinition(@NotNull String className, @NotNull String iconName, @NotNull Project project, @NotNull String path) {
310+
private static IconInfo findDefinition(@NotNull String className,
311+
@NotNull String iconName,
312+
@NotNull Project project,
313+
@NotNull String path) {
279314
assert LocalFileSystem.getInstance() != null;
280315
final VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByPath(path);
281316
if (virtualFile == null) return null;
@@ -289,7 +324,7 @@ private IconInfo findDefinition(@NotNull String className, @NotNull String iconN
289324
}
290325

291326
@Nullable
292-
private Icon findIconFromDef(@NotNull String iconClassName, @NotNull IconInfo iconDef, @NotNull String path) {
327+
private static Icon findIconFromDef(@NotNull String iconClassName, @NotNull IconInfo iconDef, @NotNull String path) {
293328
assert LocalFileSystem.getInstance() != null;
294329
final VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByPath(path);
295330
if (virtualFile == null) return null;
@@ -342,7 +377,7 @@ public boolean visitFile(@NotNull VirtualFile file) {
342377
return null;
343378
}
344379

345-
public double findPattern(@NotNull String t, @NotNull String p) {
380+
public static double findPattern(@NotNull String t, @NotNull String p) {
346381
// This is from https://github.com/tdebatty/java-string-similarity
347382
// It's MIT license file is: https://github.com/tdebatty/java-string-similarity/blob/master/LICENSE.md
348383
final JaroWinkler jw = new JaroWinkler();

src/io/flutter/utils/UIUtils.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
import com.intellij.openapi.actionSystem.Presentation;
1010
import com.intellij.openapi.editor.colors.ColorKey;
1111
import com.intellij.openapi.editor.colors.EditorColors;
12+
import com.intellij.openapi.project.Project;
13+
import com.intellij.openapi.wm.IdeFrame;
14+
import com.intellij.openapi.wm.WindowManager;
1215
import org.jetbrains.annotations.NotNull;
1316
import org.jetbrains.annotations.Nullable;
1417

@@ -34,4 +37,18 @@ public static JComponent getComponentOfActionEvent(@NotNull AnActionEvent e) {
3437
public static ColorKey getEditorNotificationBackgroundColor() {
3538
return EditorColors.GUTTER_BACKGROUND;
3639
}
40+
41+
@Nullable
42+
public static Project findVisibleProject() {
43+
final WindowManager wm = WindowManager.getInstance();
44+
if (wm == null) return null;
45+
final JFrame jframe = wm.findVisibleFrame();
46+
if (jframe == null) return null;
47+
for (IdeFrame frame : wm.getAllProjectFrames()) {
48+
if (frame.getComponent() == jframe.getRootPane()) {
49+
return frame.getProject();
50+
}
51+
}
52+
return null;
53+
}
3754
}

src/io/flutter/view/DiagnosticsTreeCellRenderer.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,11 @@
1212
import com.intellij.ui.SimpleTextAttributes;
1313
import com.intellij.ui.speedSearch.SpeedSearchSupply;
1414
import com.intellij.util.ui.UIUtil;
15-
import io.flutter.editor.FlutterMaterialIcons;
15+
import io.flutter.editor.FlutterIconLineMarkerProvider;
1616
import io.flutter.inspector.DiagnosticLevel;
1717
import io.flutter.inspector.DiagnosticsNode;
1818
import io.flutter.utils.ColorIconMaker;
19+
import io.flutter.utils.UIUtils;
1920
import org.apache.commons.lang.StringUtils;
2021
import org.jetbrains.annotations.NotNull;
2122

@@ -154,7 +155,7 @@ else if (isLinkedChild || panel.currentShowNode == value) {
154155
case "IconData": {
155156
final int codePoint = getIntMember(properties, "codePoint");
156157
if (codePoint > 0) {
157-
final Icon icon = FlutterMaterialIcons.getIconForHex(String.format("%1$04x", codePoint));
158+
final Icon icon = FlutterIconLineMarkerProvider.getMaterialIconFromCodepoint(UIUtils.findVisibleProject(), codePoint);
158159
if (icon != null) {
159160
this.addIcon(icon);
160161
this.setIconOpaque(false);

src/io/flutter/view/InspectorPanel.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import com.intellij.xdebugger.XSourcePosition;
2525
import io.flutter.FlutterBundle;
2626
import io.flutter.FlutterUtils;
27+
import io.flutter.editor.FlutterIconLineMarkerProvider;
2728
import io.flutter.editor.FlutterMaterialIcons;
2829
import io.flutter.inspector.*;
2930
import io.flutter.run.daemon.FlutterApp;
@@ -52,6 +53,8 @@
5253
import java.util.*;
5354
import java.util.concurrent.CompletableFuture;
5455

56+
import static io.flutter.utils.UIUtils.findVisibleProject;
57+
5558
public class InspectorPanel extends JPanel implements Disposable, InspectorService.InspectorServiceClient, InspectorTabPanel {
5659
/**
5760
* Maximum frame rate to refresh the inspector panel at to avoid taxing the
@@ -1345,7 +1348,7 @@ protected void customizeCellRenderer(JTable table, @Nullable Object value, boole
13451348
// IconData(U+0E88F)
13461349
final int codePoint = getIntProperty(properties, "codePoint");
13471350
if (codePoint > 0) {
1348-
final Icon icon = FlutterMaterialIcons.getIconForHex(String.format("%1$04x", codePoint));
1351+
final Icon icon = FlutterIconLineMarkerProvider.getMaterialIconFromCodepoint(UIUtils.findVisibleProject(), codePoint);
13491352
if (icon != null) {
13501353
this.setIcon(icon);
13511354
this.setIconOpaque(false);

0 commit comments

Comments
 (0)