From 693c2b9d9d2e8765e87d9e75210ae458e04ccb17 Mon Sep 17 00:00:00 2001 From: Diego Perez Date: Thu, 23 Apr 2015 16:50:25 +0100 Subject: Refresh preview after a build is completed When a build is done, components might dissapear and some other might have been added. When adding components from the support library, we need to detect the finished build and reload the preview. Change-Id: I7e56c5f7a41e95a3c2b06d1dacd58b6d34b9a3ac --- .../editors/theme/AndroidThemePreviewPanel.java | 98 ++++++++++++---------- .../idea/editors/theme/ThemeEditorComponent.java | 29 +++++-- 2 files changed, 77 insertions(+), 50 deletions(-) diff --git a/android/src/com/android/tools/idea/editors/theme/AndroidThemePreviewPanel.java b/android/src/com/android/tools/idea/editors/theme/AndroidThemePreviewPanel.java index 1bd913a767c..cb47af645f0 100644 --- a/android/src/com/android/tools/idea/editors/theme/AndroidThemePreviewPanel.java +++ b/android/src/com/android/tools/idea/editors/theme/AndroidThemePreviewPanel.java @@ -174,7 +174,6 @@ public class AndroidThemePreviewPanel extends Box implements RenderContext { myDumbService = DumbService.getInstance(myConfiguration.getModule().getProject()); myMinApiLevel = configuration.getTarget() != null ? configuration.getTarget().getVersion().getApiLevel() : Integer.MAX_VALUE; - rebuild(false/*forceRepaint*/); JBScrollPane scrollPanel = new JBScrollPane(myAndroidPreviewPanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, @@ -221,11 +220,61 @@ public class AndroidThemePreviewPanel extends Box implements RenderContext { add(mySearchTextField); add(scrollPanel); - // Find custom controls + reloadComponents(); + + myBreadcrumbs.addItemListener(new NavigationComponent.ItemListener() { + @Override + public void itemSelected(@NotNull Breadcrumb item) { + myBreadcrumbs.goTo(item); + rebuild(); + } + }); + + myAndroidPreviewPanel.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + ViewInfo view = myAndroidPreviewPanel.findViewAtPoint(e.getPoint()); + + if (view == null) { + return; + } + + mySearchTextField.setText(""); + + Object cookie = view.getCookie(); + if (cookie instanceof MergeCookie) { + cookie = ((MergeCookie)cookie).getCookie(); + } + + if (!(cookie instanceof Element)) { + return; + } + + NamedNodeMap attributes = ((Element)cookie).getAttributes(); + Node group = attributes.getNamedItemNS(ThemePreviewBuilder.BUILDER_URI, ThemePreviewBuilder.BUILDER_ATTR_GROUP); + + if (group != null) { + myBreadcrumbs.push(new Breadcrumb(ThemePreviewBuilder.ComponentGroup.valueOf(group.getNodeValue()))); + rebuild(); + } + } + }); + } + + @NotNull + public Set getUsedAttrs() { + return myAndroidPreviewPanel.getUsedAttrs(); + } + + /** + * Searches the PSI for both custom components and support library classes. Call this method when you + * want to refresh the components displayed on the preview. + */ + public void reloadComponents() { myDumbService.runWhenSmart(new Runnable() { @Override public void run() { - Project project = configuration.getModule().getProject(); + Project project = myConfiguration.getModule().getProject(); if (!project.isOpen()) { return; } @@ -279,48 +328,7 @@ public class AndroidThemePreviewPanel extends Box implements RenderContext { } }); - myBreadcrumbs.addItemListener(new NavigationComponent.ItemListener() { - @Override - public void itemSelected(@NotNull Breadcrumb item) { - myBreadcrumbs.goTo(item); - rebuild(); - } - }); - - myAndroidPreviewPanel.addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - ViewInfo view = myAndroidPreviewPanel.findViewAtPoint(e.getPoint()); - - if (view == null) { - return; - } - - mySearchTextField.setText(""); - - Object cookie = view.getCookie(); - if (cookie instanceof MergeCookie) { - cookie = ((MergeCookie)cookie).getCookie(); - } - - if (!(cookie instanceof Element)) { - return; - } - - NamedNodeMap attributes = ((Element)cookie).getAttributes(); - Node group = attributes.getNamedItemNS(ThemePreviewBuilder.BUILDER_URI, ThemePreviewBuilder.BUILDER_ATTR_GROUP); - - if (group != null) { - myBreadcrumbs.push(new Breadcrumb(ThemePreviewBuilder.ComponentGroup.valueOf(group.getNodeValue()))); - rebuild(); - } - } - }); - } - - @NotNull - public Set getUsedAttrs() { - return myAndroidPreviewPanel.getUsedAttrs(); + rebuild(false); } /** diff --git a/android/src/com/android/tools/idea/editors/theme/ThemeEditorComponent.java b/android/src/com/android/tools/idea/editors/theme/ThemeEditorComponent.java index a5f55cf8404..007216e4592 100644 --- a/android/src/com/android/tools/idea/editors/theme/ThemeEditorComponent.java +++ b/android/src/com/android/tools/idea/editors/theme/ThemeEditorComponent.java @@ -23,12 +23,11 @@ import com.android.tools.idea.configurations.Configuration; import com.android.tools.idea.configurations.ConfigurationListener; import com.android.tools.idea.configurations.DeviceMenuAction; import com.android.tools.idea.configurations.ThemeSelectionDialog; -import com.android.tools.idea.editors.theme.attributes.AttributesGrouper; -import com.android.tools.idea.editors.theme.attributes.AttributesModelColorPaletteModel; -import com.android.tools.idea.editors.theme.attributes.AttributesTableModel; -import com.android.tools.idea.editors.theme.attributes.ShowJavadocAction; -import com.android.tools.idea.editors.theme.attributes.TableLabel; +import com.android.tools.idea.editors.theme.attributes.*; import com.android.tools.idea.editors.theme.attributes.editors.*; +import com.android.tools.idea.gradle.compiler.PostProjectBuildTasksExecutor; +import com.android.tools.idea.gradle.project.GradleBuildListener; +import com.android.tools.idea.gradle.util.BuildMode; import com.android.tools.idea.rendering.RenderLogger; import com.android.tools.idea.rendering.RenderService; import com.android.tools.idea.rendering.RenderTask; @@ -45,6 +44,8 @@ import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Splitter; import com.intellij.util.Processor; +import com.intellij.util.messages.MessageBus; +import com.intellij.util.messages.MessageBusConnection; import com.intellij.util.ui.UIUtil; import org.jetbrains.android.dom.drawable.DrawableDomElement; import org.jetbrains.android.dom.resources.Flag; @@ -115,6 +116,7 @@ public class ThemeEditorComponent extends Splitter { } }; private ThemeEditorStyle mySelectedTheme; + private MessageBusConnection myMessageBusConnection; public ThemeEditorComponent(final Configuration configuration, final Module module) { this.myConfiguration = configuration; @@ -288,6 +290,21 @@ public class ThemeEditorComponent extends Splitter { setFirstComponent(myPreviewPanel); setSecondComponent(myPanel.getRightPanel()); setShowDividerControls(false); + + myMessageBusConnection = project.getMessageBus().connect(project); + myMessageBusConnection.subscribe(PostProjectBuildTasksExecutor.GRADLE_BUILD_TOPIC, new GradleBuildListener() { + @Override + public void buildFinished(@NotNull Project project, @Nullable BuildMode mode) { + if (project != myModule.getProject()) { + return; + } + + // Classes probably have changed so reload the custom components and support library classes. + myPreviewPanel.reloadComponents(); + myPreviewPanel.revalidate(); + myPreviewPanel.repaint(); + } + }); } /** @@ -660,6 +677,8 @@ public class ThemeEditorComponent extends Splitter { @Override public void dispose() { myConfiguration.removeListener(myConfigListener); + myMessageBusConnection.disconnect(); + myMessageBusConnection = null; super.dispose(); } -- cgit v1.2.3