Alexey Tsvetkov
3 years ago
committed by
GitHub
9 changed files with 150 additions and 102 deletions
@ -1,21 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright 2020-2021 JetBrains s.r.o. and respective authors and developers. |
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. |
|
||||||
*/ |
|
||||||
|
|
||||||
package org.jetbrains.compose.desktop.ui.tooling.preview.rpc |
|
||||||
|
|
||||||
interface PreviewErrorReporter { |
|
||||||
fun report(e: Throwable, details: String? = null) |
|
||||||
fun report(e: String, details: String? = null) |
|
||||||
} |
|
||||||
|
|
||||||
object StderrPreviewErrorReporter : PreviewErrorReporter { |
|
||||||
override fun report(e: Throwable, details: String?) { |
|
||||||
report(e.stackTraceString) |
|
||||||
} |
|
||||||
|
|
||||||
override fun report(e: String, details: String?) { |
|
||||||
System.err.println(e) |
|
||||||
} |
|
||||||
} |
|
@ -1,27 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright 2020-2021 JetBrains s.r.o. and respective authors and developers. |
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. |
|
||||||
*/ |
|
||||||
|
|
||||||
package org.jetbrains.compose.desktop.ide.preview |
|
||||||
|
|
||||||
import com.intellij.openapi.diagnostic.Logger |
|
||||||
import org.jetbrains.compose.desktop.ui.tooling.preview.rpc.PreviewErrorReporter |
|
||||||
|
|
||||||
internal class IdePreviewErrorReporter( |
|
||||||
private val logger: Logger, |
|
||||||
private val previewStateService: PreviewStateService |
|
||||||
) : PreviewErrorReporter { |
|
||||||
override fun report(e: Throwable, details: String?) { |
|
||||||
report(e.stackTraceToString(), details) |
|
||||||
} |
|
||||||
|
|
||||||
override fun report(e: String, details: String?) { |
|
||||||
if (details != null) { |
|
||||||
logger.error(e, details) |
|
||||||
} else { |
|
||||||
logger.error(e) |
|
||||||
} |
|
||||||
previewStateService.clearPreviewOnError() |
|
||||||
} |
|
||||||
} |
|
@ -1,43 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright 2020-2021 JetBrains s.r.o. and respective authors and developers. |
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. |
|
||||||
*/ |
|
||||||
|
|
||||||
package org.jetbrains.compose.desktop.ide.preview |
|
||||||
|
|
||||||
import java.awt.Color |
|
||||||
import java.awt.Dimension |
|
||||||
import java.awt.Graphics |
|
||||||
import java.awt.image.BufferedImage |
|
||||||
import javax.swing.JPanel |
|
||||||
|
|
||||||
internal class PreviewPanel : JPanel() { |
|
||||||
private var image: BufferedImage? = null |
|
||||||
private var imageDimension: Dimension? = null |
|
||||||
|
|
||||||
override fun paintComponent(g: Graphics) { |
|
||||||
super.paintComponent(g) |
|
||||||
|
|
||||||
synchronized(this) { |
|
||||||
image?.let { image -> |
|
||||||
val w = imageDimension!!.width |
|
||||||
val h = imageDimension!!.height |
|
||||||
g.color = Color.WHITE |
|
||||||
g.fillRect(0, 0, w, h) |
|
||||||
g.drawImage(image, 0, 0, w, h, null) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
fun previewImage(image: BufferedImage?, imageDimension: Dimension?) { |
|
||||||
synchronized(this) { |
|
||||||
this.image = image |
|
||||||
this.imageDimension = imageDimension |
|
||||||
} |
|
||||||
|
|
||||||
repaint() |
|
||||||
} |
|
||||||
|
|
||||||
override fun getPreferredSize(): Dimension? = |
|
||||||
imageDimension ?: super.getPreferredSize() |
|
||||||
} |
|
@ -0,0 +1,89 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2020-2022 JetBrains s.r.o. and respective authors and developers. |
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. |
||||||
|
*/ |
||||||
|
|
||||||
|
package org.jetbrains.compose.desktop.ide.preview.ui |
||||||
|
|
||||||
|
import com.intellij.icons.AllIcons |
||||||
|
import com.intellij.openapi.project.Project |
||||||
|
import com.intellij.ui.SimpleTextAttributes |
||||||
|
import com.intellij.ui.components.JBPanel |
||||||
|
import com.intellij.util.ui.StatusText |
||||||
|
import java.awt.Color |
||||||
|
import java.awt.Dimension |
||||||
|
import java.awt.Graphics |
||||||
|
import java.awt.image.BufferedImage |
||||||
|
import java.util.concurrent.atomic.AtomicReference |
||||||
|
import javax.swing.SwingUtilities |
||||||
|
|
||||||
|
internal class PreviewPanel(private val myProject: Project) : JBPanel<PreviewPanel>() { |
||||||
|
sealed class PreviewPanelState { |
||||||
|
data class Image(val image: BufferedImage, val dimension: Dimension) : PreviewPanelState() |
||||||
|
class Error(val error: String) : PreviewPanelState() |
||||||
|
} |
||||||
|
private val myState = AtomicReference<PreviewPanelState>() |
||||||
|
private val myStatusText = object : StatusText(this) { |
||||||
|
override fun isStatusVisible(): Boolean { |
||||||
|
return myState.get() is PreviewPanelState.Error |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
init { |
||||||
|
SwingUtilities.invokeLater { |
||||||
|
myStatusText.initStatusText() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
fun StatusText.initStatusText() { |
||||||
|
clear() |
||||||
|
appendLine( |
||||||
|
AllIcons.General.Error, |
||||||
|
"Preview rendering encountered an error", |
||||||
|
SimpleTextAttributes.REGULAR_ATTRIBUTES, |
||||||
|
null |
||||||
|
) |
||||||
|
appendLine( |
||||||
|
"Show details", |
||||||
|
SimpleTextAttributes.LINK_ATTRIBUTES |
||||||
|
) { |
||||||
|
val errorText = (myState.get() as? PreviewPanelState.Error)?.error |
||||||
|
showTextDialog("Preview Error Details", errorText.orEmpty(), myProject) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
override fun paintComponent(g: Graphics) { |
||||||
|
super.paintComponent(g) |
||||||
|
|
||||||
|
when (val state = myState.get()) { |
||||||
|
is PreviewPanelState.Image -> { |
||||||
|
val (image, dimension) = state |
||||||
|
val w = dimension.width |
||||||
|
val h = dimension.height |
||||||
|
g.color = Color.WHITE |
||||||
|
g.fillRect(0, 0, w, h) |
||||||
|
g.drawImage(image, 0, 0, w, h, null) |
||||||
|
} |
||||||
|
is PreviewPanelState.Error -> { |
||||||
|
myStatusText.paint(this, g) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
fun previewImage(image: BufferedImage, imageDimension: Dimension) { |
||||||
|
myState.set(PreviewPanelState.Image(image, imageDimension)) |
||||||
|
SwingUtilities.invokeLater { |
||||||
|
repaint() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
fun error(error: String) { |
||||||
|
myState.set(PreviewPanelState.Error(error)) |
||||||
|
SwingUtilities.invokeLater { |
||||||
|
repaint() |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
override fun getPreferredSize(): Dimension? = |
||||||
|
(myState.get() as? PreviewPanelState.Image)?.dimension ?: super.getPreferredSize() |
||||||
|
} |
@ -0,0 +1,39 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2020-2022 JetBrains s.r.o. and respective authors and developers. |
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. |
||||||
|
*/ |
||||||
|
|
||||||
|
package org.jetbrains.compose.desktop.ide.preview.ui |
||||||
|
|
||||||
|
import com.intellij.openapi.project.Project |
||||||
|
import com.intellij.openapi.ui.DialogWrapper |
||||||
|
import com.intellij.ui.ScrollPaneFactory |
||||||
|
import java.awt.BorderLayout |
||||||
|
import javax.swing.JComponent |
||||||
|
import javax.swing.JPanel |
||||||
|
import javax.swing.JTextArea |
||||||
|
|
||||||
|
fun showTextDialog( |
||||||
|
title: String, |
||||||
|
text: String, |
||||||
|
project: Project? = null |
||||||
|
) { |
||||||
|
val wrapper: DialogWrapper = object : DialogWrapper(project, false) { |
||||||
|
init { |
||||||
|
init() |
||||||
|
} |
||||||
|
|
||||||
|
override fun createCenterPanel(): JComponent { |
||||||
|
val textArea = JTextArea(text).apply { |
||||||
|
isEditable = false |
||||||
|
rows = 40 |
||||||
|
columns = 70 |
||||||
|
} |
||||||
|
return JPanel(BorderLayout()).apply { |
||||||
|
add(ScrollPaneFactory.createScrollPane(textArea)) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
wrapper.title = title |
||||||
|
wrapper.show() |
||||||
|
} |
Loading…
Reference in new issue