From 614fa9d0c70b583d4b9332dd8b23dad2da94203c Mon Sep 17 00:00:00 2001 From: Natalia Selezneva Date: Wed, 16 May 2018 12:14:07 +0300 Subject: [PATCH] Refactoring: move ScratchFileRenderer to separate file --- .../output/InlayScratchFileRenderer.kt | 78 ++++++++ .../output/InlayScratchFileRenderer.kt.172 | 78 ++++++++ .../output/InlayScratchOutputHandler.kt | 78 +------- .../output/InlayScratchOutputHandler.kt.172 | 175 ------------------ .../scratch/AbstractScratchRunActionTest.kt | 4 +- 5 files changed, 162 insertions(+), 251 deletions(-) create mode 100644 idea/idea-jvm/src/org/jetbrains/kotlin/idea/scratch/output/InlayScratchFileRenderer.kt create mode 100644 idea/idea-jvm/src/org/jetbrains/kotlin/idea/scratch/output/InlayScratchFileRenderer.kt.172 delete mode 100644 idea/idea-jvm/src/org/jetbrains/kotlin/idea/scratch/output/InlayScratchOutputHandler.kt.172 diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/scratch/output/InlayScratchFileRenderer.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/scratch/output/InlayScratchFileRenderer.kt new file mode 100644 index 00000000000..73d1e9ac1cf --- /dev/null +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/scratch/output/InlayScratchFileRenderer.kt @@ -0,0 +1,78 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.scratch.output + +import com.intellij.openapi.editor.Editor +import com.intellij.openapi.editor.EditorCustomElementRenderer +import com.intellij.openapi.editor.impl.ComplementaryFontsRegistry +import com.intellij.openapi.editor.impl.FontInfo +import com.intellij.openapi.editor.markup.TextAttributes +import com.intellij.ui.Colors +import com.intellij.ui.JBColor +import java.awt.Color +import java.awt.Font +import java.awt.Graphics +import java.awt.Rectangle + +class InlayScratchFileRenderer(val text: String, private val outputType: ScratchOutputType) : EditorCustomElementRenderer { + private fun getFontInfo(editor: Editor): FontInfo { + val colorsScheme = editor.colorsScheme + val fontPreferences = colorsScheme.fontPreferences + val attributes = getAttributes() + val fontStyle = attributes.fontType + return ComplementaryFontsRegistry.getFontAbleToDisplay( + 'a'.toInt(), fontStyle, fontPreferences, FontInfo.getFontRenderContext(editor.contentComponent) + ) + } + + override fun calcWidthInPixels(editor: Editor): Int { + val fontInfo = getFontInfo(editor) + return fontInfo.fontMetrics().stringWidth(text) + } + + override fun paint(editor: Editor, g: Graphics, r: Rectangle, textAttributes: TextAttributes) { + val attributes = getAttributes() + val fgColor = attributes.foregroundColor ?: return + g.color = fgColor + val fontInfo = getFontInfo(editor) + g.font = fontInfo.font + val metrics = fontInfo.fontMetrics() + g.drawString(text, r.x, r.y + metrics.ascent) + } + + private fun getAttributes(): TextAttributes { + return when (outputType) { + ScratchOutputType.OUTPUT -> userOutputAttributes + ScratchOutputType.RESULT -> normalAttributes + ScratchOutputType.ERROR -> errorAttributes + } + } + + override fun toString(): String { + return "${outputType.name}: ${text.trim()}" + } + + companion object { + private val normalAttributes = TextAttributes( + JBColor.GRAY, + null, null, null, + Font.ITALIC + ) + + private val errorAttributes = TextAttributes( + JBColor(Colors.DARK_RED, Colors.DARK_RED), + null, null, null, + Font.ITALIC + ) + + private val userOutputColor = Color(0x5C5CFF) + private val userOutputAttributes = TextAttributes( + JBColor(userOutputColor, userOutputColor), + null, null, null, + Font.ITALIC + ) + } +} \ No newline at end of file diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/scratch/output/InlayScratchFileRenderer.kt.172 b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/scratch/output/InlayScratchFileRenderer.kt.172 new file mode 100644 index 00000000000..1480041ebde --- /dev/null +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/scratch/output/InlayScratchFileRenderer.kt.172 @@ -0,0 +1,78 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.scratch.output + +import com.intellij.openapi.editor.Editor +import com.intellij.openapi.editor.EditorCustomElementRenderer +import com.intellij.openapi.editor.impl.ComplementaryFontsRegistry +import com.intellij.openapi.editor.impl.FontInfo +import com.intellij.openapi.editor.markup.TextAttributes +import com.intellij.ui.Colors +import com.intellij.ui.JBColor +import java.awt.Color +import java.awt.Font +import java.awt.Graphics +import java.awt.Rectangle + +class InlayScratchFileRenderer(val text: String, private val outputType: ScratchOutputType) : EditorCustomElementRenderer { + private fun getFontInfo(editor: Editor): FontInfo { + val colorsScheme = editor.colorsScheme + val fontPreferences = colorsScheme.fontPreferences + val attributes = getAttributes() + val fontStyle = attributes.fontType + return ComplementaryFontsRegistry.getFontAbleToDisplay( + 'a'.toInt(), fontStyle, fontPreferences, FontInfo.getFontRenderContext(editor.contentComponent) + ) + } + + override fun calcWidthInPixels(editor: Editor): Int { + val fontInfo = getFontInfo(editor) + return fontInfo.fontMetrics().stringWidth(text) + } + + override fun paint(editor: Editor, g: Graphics, r: Rectangle) { + val attributes = getAttributes() + val fgColor = attributes.foregroundColor ?: return + g.color = fgColor + val fontInfo = getFontInfo(editor) + g.font = fontInfo.font + val metrics = fontInfo.fontMetrics() + g.drawString(text, r.x, r.y + metrics.ascent) + } + + private fun getAttributes(): TextAttributes { + return when (outputType) { + ScratchOutputType.OUTPUT -> userOutputAttributes + ScratchOutputType.RESULT -> normalAttributes + ScratchOutputType.ERROR -> errorAttributes + } + } + + override fun toString(): String { + return "${outputType.name}: ${text.trim()}" + } + + companion object { + private val normalAttributes = TextAttributes( + JBColor.GRAY, + null, null, null, + Font.ITALIC + ) + + private val errorAttributes = TextAttributes( + JBColor(Colors.DARK_RED, Colors.DARK_RED), + null, null, null, + Font.ITALIC + ) + + private val userOutputColor = Color(0x5C5CFF) + private val userOutputAttributes = TextAttributes( + JBColor(userOutputColor, userOutputColor), + null, null, null, + Font.ITALIC + ) + } +} \ No newline at end of file diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/scratch/output/InlayScratchOutputHandler.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/scratch/output/InlayScratchOutputHandler.kt index ce6bfaf96a2..a61ef791292 100644 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/scratch/output/InlayScratchOutputHandler.kt +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/scratch/output/InlayScratchOutputHandler.kt @@ -17,24 +17,13 @@ package org.jetbrains.kotlin.idea.scratch.output import com.intellij.execution.ui.ConsoleViewContentType -import com.intellij.openapi.editor.Editor -import com.intellij.openapi.editor.EditorCustomElementRenderer -import com.intellij.openapi.editor.impl.ComplementaryFontsRegistry -import com.intellij.openapi.editor.impl.FontInfo -import com.intellij.openapi.editor.markup.TextAttributes import com.intellij.openapi.fileEditor.TextEditor import com.intellij.openapi.util.Disposer import com.intellij.openapi.util.text.StringUtil -import com.intellij.ui.Colors -import com.intellij.ui.JBColor import com.intellij.util.ui.UIUtil import org.jetbrains.kotlin.idea.scratch.ScratchExpression import org.jetbrains.kotlin.idea.scratch.ScratchFile import org.jetbrains.kotlin.idea.scratch.ui.ScratchToolWindow -import java.awt.Color -import java.awt.Font -import java.awt.Graphics -import java.awt.Rectangle object InlayScratchOutputHandler : ScratchOutputHandler { private const val maxInsertOffset = 60 @@ -83,15 +72,15 @@ object InlayScratchOutputHandler : ScratchOutputHandler { val existing = editor.inlayModel .getInlineElementsInRange(lineEndOffset, lineEndOffset) - .singleOrNull { it.renderer is ScratchFileRenderer } + .singleOrNull { it.renderer is InlayScratchFileRenderer } if (existing != null) { existing.dispose() editor.inlayModel.addInlineElement( lineEndOffset, - ScratchFileRenderer((existing.renderer as ScratchFileRenderer).text + "; " + inlayText, outputType) + InlayScratchFileRenderer((existing.renderer as InlayScratchFileRenderer).text + "; " + inlayText, outputType) ) } else { - editor.inlayModel.addInlineElement(lineEndOffset, ScratchFileRenderer(" ".repeat(spaceCount) + inlayText, outputType)) + editor.inlayModel.addInlineElement(lineEndOffset, InlayScratchFileRenderer(" ".repeat(spaceCount) + inlayText, outputType)) } } } @@ -108,68 +97,9 @@ object InlayScratchOutputHandler : ScratchOutputHandler { UIUtil.invokeLaterIfNeeded { editor .editor.inlayModel.getInlineElementsInRange(0, editor.editor.document.textLength) - .filter { it.renderer is ScratchFileRenderer } + .filter { it.renderer is InlayScratchFileRenderer } .forEach { Disposer.dispose(it) } } } - class ScratchFileRenderer(val text: String, val outputType: ScratchOutputType) : EditorCustomElementRenderer { - private fun getFontInfo(editor: Editor): FontInfo { - val colorsScheme = editor.colorsScheme - val fontPreferences = colorsScheme.fontPreferences - val attributes = getAttributes() - val fontStyle = attributes.fontType - return ComplementaryFontsRegistry.getFontAbleToDisplay( - 'a'.toInt(), fontStyle, fontPreferences, FontInfo.getFontRenderContext(editor.contentComponent) - ) - } - - override fun calcWidthInPixels(editor: Editor): Int { - val fontInfo = getFontInfo(editor) - return fontInfo.fontMetrics().stringWidth(text) - } - - override fun paint(editor: Editor, g: Graphics, r: Rectangle, textAttributes: TextAttributes) { - val attributes = getAttributes() - val fgColor = attributes.foregroundColor ?: return - g.color = fgColor - val fontInfo = getFontInfo(editor) - g.font = fontInfo.font - val metrics = fontInfo.fontMetrics() - g.drawString(text, r.x, r.y + metrics.ascent) - } - - private fun getAttributes(): TextAttributes { - return when (outputType) { - ScratchOutputType.OUTPUT -> userOutputAttributes - ScratchOutputType.RESULT -> normalAttributes - ScratchOutputType.ERROR -> errorAttributes - } - } - - override fun toString(): String { - return "${outputType.name}: ${text.trim()}" - } - - companion object { - private val normalAttributes = TextAttributes( - JBColor.GRAY, - null, null, null, - Font.ITALIC - ) - - private val errorAttributes = TextAttributes( - JBColor(Colors.DARK_RED, Colors.DARK_RED), - null, null, null, - Font.ITALIC - ) - - private val userOutputColor = Color(0x5C5CFF) - private val userOutputAttributes = TextAttributes( - JBColor(userOutputColor, userOutputColor), - null, null, null, - Font.ITALIC - ) - } - } } \ No newline at end of file diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/scratch/output/InlayScratchOutputHandler.kt.172 b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/scratch/output/InlayScratchOutputHandler.kt.172 deleted file mode 100644 index d2c4c437532..00000000000 --- a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/scratch/output/InlayScratchOutputHandler.kt.172 +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright 2010-2017 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.kotlin.idea.scratch.output - -import com.intellij.execution.ui.ConsoleViewContentType -import com.intellij.openapi.editor.Editor -import com.intellij.openapi.editor.EditorCustomElementRenderer -import com.intellij.openapi.editor.impl.ComplementaryFontsRegistry -import com.intellij.openapi.editor.impl.FontInfo -import com.intellij.openapi.editor.markup.TextAttributes -import com.intellij.openapi.fileEditor.TextEditor -import com.intellij.openapi.util.Disposer -import com.intellij.openapi.util.text.StringUtil -import com.intellij.ui.Colors -import com.intellij.ui.JBColor -import com.intellij.util.ui.UIUtil -import org.jetbrains.kotlin.idea.scratch.ScratchExpression -import org.jetbrains.kotlin.idea.scratch.ScratchFile -import org.jetbrains.kotlin.idea.scratch.ui.ScratchToolWindow -import java.awt.Color -import java.awt.Font -import java.awt.Graphics -import java.awt.Rectangle - -object InlayScratchOutputHandler : ScratchOutputHandler { - private const val maxInsertOffset = 60 - private const val minSpaceCount = 4 - - override fun onStart(file: ScratchFile) { - clear(file) - } - - override fun handle(file: ScratchFile, expression: ScratchExpression, output: ScratchOutput) { - val inlayText = StringUtil.shortenTextWithEllipsis(output.text.substringBefore("\n"), 50, 0) - if (inlayText != output.text) { - ScratchToolWindow.addMessageToToolWindow(file.project, output.text, ConsoleViewContentType.NORMAL_OUTPUT) - } - - createInlay(file, expression.lineStart, inlayText, output.type) - - if (output.type == ScratchOutputType.ERROR) { - error(file, output.text) - } - } - - override fun error(file: ScratchFile, message: String) { - ScratchToolWindow.addMessageToToolWindow(file.project, message, ConsoleViewContentType.ERROR_OUTPUT) - } - - override fun onFinish(file: ScratchFile) { - - } - - override fun clear(file: ScratchFile) { - clearInlays(file.editor) - ScratchToolWindow.clearToolWindow(file.project) - } - - private fun createInlay(file: ScratchFile, line: Int, inlayText: String, outputType: ScratchOutputType) { - UIUtil.invokeLaterIfNeeded { - val editor = file.editor.editor - - val lineStartOffset = editor.document.getLineStartOffset(line) - val lineEndOffset = editor.document.getLineEndOffset(line) - val lineLength = lineEndOffset - lineStartOffset - var spaceCount = maxLineLength(file) - lineLength + minSpaceCount - - while(spaceCount + lineLength > maxInsertOffset && spaceCount > minSpaceCount) spaceCount-- - - val existing = editor.inlayModel - .getInlineElementsInRange(lineEndOffset, lineEndOffset) - .singleOrNull { it.renderer is ScratchFileRenderer } - if (existing != null) { - existing.dispose() - editor.inlayModel.addInlineElement( - lineEndOffset, - ScratchFileRenderer((existing.renderer as ScratchFileRenderer).text + "; " + inlayText, outputType) - ) - } else { - editor.inlayModel.addInlineElement(lineEndOffset, ScratchFileRenderer(" ".repeat(spaceCount) + inlayText, outputType)) - } - } - } - - private fun maxLineLength(file: ScratchFile): Int { - val doc = file.editor.editor.document - return (0 until doc.lineCount) - .map { doc.getLineEndOffset(it) - doc.getLineStartOffset(it) } - .max() - ?: -1 - } - - private fun clearInlays(editor: TextEditor) { - UIUtil.invokeLaterIfNeeded { - editor - .editor.inlayModel.getInlineElementsInRange(0, editor.editor.document.textLength) - .filter { it.renderer is ScratchFileRenderer } - .forEach { Disposer.dispose(it) } - } - } - - class ScratchFileRenderer(val text: String, val outputType: ScratchOutputType) : EditorCustomElementRenderer { - private fun getFontInfo(editor: Editor): FontInfo { - val colorsScheme = editor.colorsScheme - val fontPreferences = colorsScheme.fontPreferences - val attributes = getAttributes() - val fontStyle = attributes.fontType - return ComplementaryFontsRegistry.getFontAbleToDisplay( - 'a'.toInt(), fontStyle, fontPreferences, FontInfo.getFontRenderContext(editor.contentComponent) - ) - } - - override fun calcWidthInPixels(editor: Editor): Int { - val fontInfo = getFontInfo(editor) - return fontInfo.fontMetrics().stringWidth(text) - } - - override fun paint(editor: Editor, g: Graphics, r: Rectangle) { - val attributes = getAttributes() - val fgColor = attributes.foregroundColor ?: return - g.color = fgColor - val fontInfo = getFontInfo(editor) - g.font = fontInfo.font - val metrics = fontInfo.fontMetrics() - g.drawString(text, r.x, r.y + metrics.ascent) - } - - private fun getAttributes(): TextAttributes { - return when (outputType) { - ScratchOutputType.OUTPUT -> userOutputAttributes - ScratchOutputType.RESULT -> normalAttributes - ScratchOutputType.ERROR -> errorAttributes - } - } - - override fun toString(): String { - return "${outputType.name}: ${text.trim()}" - } - - companion object { - private val normalAttributes = TextAttributes( - JBColor.GRAY, - null, null, null, - Font.ITALIC - ) - - private val errorAttributes = TextAttributes( - JBColor(Colors.DARK_RED, Colors.DARK_RED), - null, null, null, - Font.ITALIC - ) - - private val userOutputColor = Color(0x5C5CFF) - private val userOutputAttributes = TextAttributes( - JBColor(userOutputColor, userOutputColor), - null, null, null, - Font.ITALIC - ) - } - } -} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/scratch/AbstractScratchRunActionTest.kt b/idea/tests/org/jetbrains/kotlin/idea/scratch/AbstractScratchRunActionTest.kt index bc123eea034..03a3a551056 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/scratch/AbstractScratchRunActionTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/scratch/AbstractScratchRunActionTest.kt @@ -35,7 +35,7 @@ import com.intellij.util.ui.UIUtil import org.jetbrains.kotlin.compatibility.projectDisposableEx import org.jetbrains.kotlin.idea.KotlinLanguage import org.jetbrains.kotlin.idea.scratch.actions.RunScratchAction -import org.jetbrains.kotlin.idea.scratch.output.InlayScratchOutputHandler +import org.jetbrains.kotlin.idea.scratch.output.InlayScratchFileRenderer import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor import org.jetbrains.kotlin.idea.test.PluginTestCaseBase import org.jetbrains.kotlin.idea.util.application.runWriteAction @@ -129,7 +129,7 @@ abstract class AbstractScratchRunActionTest : FileEditorManagerTestCase() { doc.getLineStartOffset(line), doc.getLineEndOffset(line) ).map { it.renderer } - .filterIsInstance() + .filterIsInstance() .forEach { val str = it.toString() val offset = doc.getLineEndOffset(line); actualOutput.insert(offset, " // $str")