Skip to content

Commit ae408c2

Browse files
authored
[Property Editor] Add Property Editor as a side panel (#7958)
1 parent 7bcc79c commit ae408c2

File tree

9 files changed

+114
-0
lines changed

9 files changed

+114
-0
lines changed

flutter-idea/src/icons/FlutterIcons.java

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ private static Icon load(String path) {
1414
public static final Icon DevTools = load("/icons/expui/devTools.svg");
1515
public static final Icon DevToolsExtensions = load("/icons/expui/extensions.svg");
1616
public static final Icon DevToolsInspector = load("icons/expui/inspector.svg");
17+
public static final Icon PropertyEditor = load("/icons/expui/propertyEditor.svg");
1718

1819
public static final Icon Flutter_13_2x = load("/icons/[email protected]");
1920
public static final Icon Flutter_64 = load("/icons/flutter_64.png");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
* Copyright 2025 The Chromium Authors. All rights reserved.
3+
* Use of this source code is governed by a BSD-style license that can be
4+
* found in the LICENSE file.
5+
*/
6+
package io.flutter.propertyeditor;
7+
8+
import com.intellij.openapi.application.ApplicationManager;
9+
import com.intellij.openapi.project.Project;
10+
import com.intellij.openapi.wm.ToolWindow;
11+
import com.intellij.openapi.wm.ToolWindowFactory;
12+
import io.flutter.FlutterUtils;
13+
import io.flutter.actions.RefreshToolWindowAction;
14+
import io.flutter.bazel.WorkspaceCache;
15+
import io.flutter.devtools.DevToolsIdeFeature;
16+
import io.flutter.devtools.DevToolsUrl;
17+
import io.flutter.run.daemon.DevToolsService;
18+
import io.flutter.sdk.FlutterSdk;
19+
import io.flutter.sdk.FlutterSdkVersion;
20+
import io.flutter.utils.AsyncUtils;
21+
import kotlin.coroutines.Continuation;
22+
import org.jetbrains.annotations.NotNull;
23+
24+
import java.util.List;
25+
import java.util.Optional;
26+
27+
public class PropertyEditorViewFactory implements ToolWindowFactory {
28+
@NotNull private static String TOOL_WINDOW_ID = "Flutter Property Editor";
29+
30+
@Override
31+
public Object isApplicableAsync(@NotNull Project project, @NotNull Continuation<? super Boolean> $completion) {
32+
FlutterSdk sdk = FlutterSdk.getFlutterSdk(project);
33+
FlutterSdkVersion sdkVersion = sdk == null ? null : sdk.getVersion();
34+
return sdkVersion != null && sdkVersion.canUsePropertyEditor();
35+
}
36+
37+
@Override
38+
public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) {
39+
FlutterSdk sdk = FlutterSdk.getFlutterSdk(project);
40+
FlutterSdkVersion sdkVersion = sdk == null ? null : sdk.getVersion();
41+
42+
AsyncUtils.whenCompleteUiThread(
43+
DevToolsService.getInstance(project).getDevToolsInstance(),
44+
(instance, error) -> {
45+
// Skip displaying if the project has been closed.
46+
if (!project.isOpen()) {
47+
return;
48+
}
49+
50+
if (error != null) {
51+
return;
52+
}
53+
54+
if (instance == null) {
55+
return;
56+
}
57+
58+
final DevToolsUrl devToolsUrl = new DevToolsUrl.Builder()
59+
.setDevToolsHost(instance.host())
60+
.setDevToolsPort(instance.port())
61+
.setPage("propertyEditor")
62+
.setEmbed(true)
63+
.setFlutterSdkVersion(sdkVersion)
64+
.setWorkspaceCache(WorkspaceCache.getInstance(project))
65+
.setIdeFeature(DevToolsIdeFeature.TOOL_WINDOW)
66+
.build();
67+
68+
ApplicationManager.getApplication().invokeLater(() -> {
69+
Optional.ofNullable(
70+
FlutterUtils.embeddedBrowser(project))
71+
.ifPresent(embeddedBrowser -> embeddedBrowser.openPanel(toolWindow, "Property Editor", devToolsUrl, System.out::println));
72+
});
73+
}
74+
);
75+
76+
toolWindow.setTitleActions(List.of(new RefreshToolWindowAction(TOOL_WINDOW_ID)));
77+
}
78+
}

flutter-idea/src/io/flutter/sdk/FlutterSdkVersion.java

+7
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ public final class FlutterSdkVersion implements Comparable<FlutterSdkVersion> {
4646
@NotNull
4747
private static final FlutterSdkVersion MIN_SUPPORTS_DTD = new FlutterSdkVersion("3.22.0");
4848

49+
@NotNull
50+
private static final FlutterSdkVersion MIN_SUPPORTS_PROPERTY_EDITOR = new FlutterSdkVersion("3.29.0");
51+
4952
@Nullable
5053
private final Version version;
5154
@Nullable
@@ -127,6 +130,10 @@ public boolean canUseDeepLinksTool() {
127130
return supportsVersion(MIN_SUPPORTS_DEEP_LINKS_TOOL);
128131
}
129132

133+
public boolean canUsePropertyEditor() {
134+
return supportsVersion(MIN_SUPPORTS_PROPERTY_EDITOR);
135+
}
136+
130137
public boolean canUseDevToolsMultiEmbed() {
131138
return supportsVersion(MIN_SUPPORTS_DEVTOOLS_MULTI_EMBED);
132139
}

resources/META-INF/plugin.xml

+2
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,8 @@
387387
<toolWindow id="Flutter Inspector" anchor="right" icon="FlutterIcons.DevToolsInspector"
388388
factoryClass="io.flutter.view.FlutterViewFactory"/>
389389
<projectService serviceImplementation="io.flutter.view.FlutterView" overrides="false"/>
390+
<!-- Do not uncomment until ready to release the Property Editor. -->
391+
<!-- <toolWindow id="Flutter Property Editor" anchor="right" icon="FlutterIcons.PropertyEditor" factoryClass="io.flutter.propertyeditor.PropertyEditorViewFactory" /> -->
390392
<toolWindow id="Flutter Deep Links" anchor="right" icon="FlutterIcons.DevToolsDeepLinks" factoryClass="io.flutter.deeplinks.DeepLinksViewFactory" />
391393
<toolWindow id="Flutter DevTools" anchor="right" icon="FlutterIcons.DevTools" factoryClass="io.flutter.devtools.RemainingDevToolsViewFactory" />
392394
<toolWindow id="Flutter DevTools Extensions" anchor="right" icon="FlutterIcons.DevToolsExtensions" factoryClass="io.flutter.devtools.DevToolsExtensionsViewFactory" />

resources/META-INF/plugin_template.xml

+2
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,8 @@
315315
<toolWindow id="Flutter Inspector" anchor="right" icon="FlutterIcons.DevToolsInspector"
316316
factoryClass="io.flutter.view.FlutterViewFactory"/>
317317
<projectService serviceImplementation="io.flutter.view.FlutterView" overrides="false"/>
318+
<!-- Do not uncomment until ready to release the Property Editor. -->
319+
<!-- <toolWindow id="Flutter Property Editor" anchor="right" icon="FlutterIcons.PropertyEditor" factoryClass="io.flutter.propertyeditor.PropertyEditorViewFactory" /> -->
318320
<toolWindow id="Flutter Deep Links" anchor="right" icon="FlutterIcons.DevToolsDeepLinks" factoryClass="io.flutter.deeplinks.DeepLinksViewFactory" />
319321
<toolWindow id="Flutter DevTools" anchor="right" icon="FlutterIcons.DevTools" factoryClass="io.flutter.devtools.RemainingDevToolsViewFactory" />
320322
<toolWindow id="Flutter DevTools Extensions" anchor="right" icon="FlutterIcons.DevToolsExtensions" factoryClass="io.flutter.devtools.DevToolsExtensionsViewFactory" />
+6
Loading
+6
Loading
Loading
Loading

0 commit comments

Comments
 (0)