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