Skip to content

Commit

Permalink
Logpanel Overhaul (rebased) (#41)
Browse files Browse the repository at this point in the history
Co-authored-by: Cosmo Stevens <[email protected]>
Co-authored-by: Corbin Harrell <[email protected]>
  • Loading branch information
3 people authored Jul 28, 2023
1 parent 2bfe2a2 commit e662ac2
Show file tree
Hide file tree
Showing 43 changed files with 2,019 additions and 846 deletions.
2 changes: 1 addition & 1 deletion buildSrc/src/main/kotlin/DownloadJavadocsPlugin.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ private fun legacyJavadoc(url: String) = JavadocUrl(url, noframe = true)
class DownloadJavadocsPlugin : Plugin<Project> {
private val toDownload = mapOf(
"8.1" to listOf(
javadoc("https://files.inductiveautomation.com/sdk/javadoc/ignition81/8.1.27/"),
javadoc("https://files.inductiveautomation.com/sdk/javadoc/ignition81/8.1.29/"),
javadoc("https://docs.oracle.com/en/java/javase/11/docs/api/"),
legacyJavadoc("https://www.javadoc.io/static/org.python/jython-standalone/2.7.1/")
),
Expand Down
2 changes: 2 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ flatlaf-extras = { group = "com.formdev", name = "flatlaf-extras", version.ref =
flatlaf-jide = { group = "com.formdev", name = "flatlaf-jide-oss", version.ref = "flatlaf" }
flatlaf-swingx = { group = "com.formdev", name = "flatlaf-swingx", version.ref = "flatlaf" }
flatlaf-themes = { group = "com.formdev", name = "flatlaf-intellij-themes", version.ref = "flatlaf" }
flatlaf-fonts-roboto = { group = "com.formdev", name = "flatlaf-fonts-roboto", version = "2.137"}
svgSalamander = { group = "com.formdev", name = "svgSalamander", version = "1.1.4" }
jide-common = { group = "com.formdev", name = "jide-oss", version = "3.7.12" }
swingx = { group = "org.swinglabs.swingx", name = "swingx-all", version = "1.6.5-1" }
Expand Down Expand Up @@ -62,6 +63,7 @@ flatlaf = [
"flatlaf-jide",
"flatlaf-swingx",
"flatlaf-themes",
"flatlaf-fonts-roboto",
]
kotest = [
"kotest-junit",
Expand Down
96 changes: 76 additions & 20 deletions src/main/kotlin/io/github/inductiveautomation/kindling/MainPanel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@ import com.formdev.flatlaf.extras.FlatAnimatedLafChange
import com.formdev.flatlaf.extras.FlatSVGIcon
import com.formdev.flatlaf.extras.FlatUIDefaultsInspector
import com.formdev.flatlaf.extras.components.FlatTextArea
import com.formdev.flatlaf.fonts.roboto.FlatRobotoFont
import com.formdev.flatlaf.util.SystemInfo
import io.github.inductiveautomation.kindling.core.ClipboardTool
import io.github.inductiveautomation.kindling.core.CustomIconView
import io.github.inductiveautomation.kindling.core.Kindling.Preferences.Advanced.Debug
import io.github.inductiveautomation.kindling.core.Kindling.Preferences.General.ChoosableEncodings
import io.github.inductiveautomation.kindling.core.Kindling.Preferences.General.DefaultEncoding
import io.github.inductiveautomation.kindling.core.Kindling.Preferences.General.DefaultTool
import io.github.inductiveautomation.kindling.core.Kindling.Preferences.General.HomeLocation
import io.github.inductiveautomation.kindling.core.Kindling.Preferences.UI.ScaleFactor
Expand All @@ -25,9 +28,12 @@ import io.github.inductiveautomation.kindling.utils.TabStrip
import io.github.inductiveautomation.kindling.utils.chooseFiles
import io.github.inductiveautomation.kindling.utils.getLogger
import io.github.inductiveautomation.kindling.utils.jFrame
import io.github.inductiveautomation.kindling.utils.menuShortcutKeyMaskEx
import io.github.inductiveautomation.kindling.utils.traverseChildren
import net.miginfocom.layout.PlatformDefaults
import net.miginfocom.layout.UnitValue
import net.miginfocom.swing.MigLayout
import java.awt.BorderLayout
import java.awt.Desktop
import java.awt.Dimension
import java.awt.EventQueue
Expand All @@ -39,22 +45,57 @@ import java.awt.event.KeyEvent
import java.awt.event.MouseAdapter
import java.awt.event.MouseEvent
import java.io.File
import java.nio.charset.Charset
import javax.swing.Box
import javax.swing.JButton
import javax.swing.JComboBox
import javax.swing.JFileChooser
import javax.swing.JFrame
import javax.swing.JLabel
import javax.swing.JMenu
import javax.swing.JMenuBar
import javax.swing.JPanel
import javax.swing.KeyStroke
import javax.swing.SwingConstants
import javax.swing.UIManager
import javax.swing.filechooser.FileFilter

class MainPanel(empty: Boolean) : JPanel(MigLayout("ins 6, fill")) {
class MainPanel : JPanel(MigLayout("ins 6, fill")) {
private val fileChooser = JFileChooser(HomeLocation.currentValue.toFile()).apply {
isMultiSelectionEnabled = true
fileView = CustomIconView()

val encodingSelector = JComboBox(ChoosableEncodings).apply {
toolTipText = "Charset Encoding for Wrapper Logs"
selectedItem = DefaultEncoding.currentValue
addActionListener {
DefaultEncoding.currentValue = selectedItem as Charset
}
isEnabled = DefaultTool.currentValue.respectsEncoding
}

traverseChildren().filterIsInstance<JPanel>().last().apply {
add(encodingSelector, 0)
add(
JLabel("Encoding: ", SwingConstants.RIGHT).apply {
verticalAlignment = SwingConstants.BOTTOM
},
0,
)
}

Tool.byFilter.keys.forEach(this::addChoosableFileFilter)
fileFilter = DefaultTool.currentValue.filter
addPropertyChangeListener(JFileChooser.FILE_FILTER_CHANGED_PROPERTY) { e ->
val relevantTool = Tool.byFilter[e.newValue as FileFilter]
encodingSelector.isEnabled = relevantTool?.respectsEncoding != false // null = 'all files', so enabled
}

addActionListener {
if (selectedFile != null) {
HomeLocation.currentValue = selectedFile.parentFile.toPath()
}
}

Theme.addChangeListener {
updateUI()
Expand All @@ -63,16 +104,30 @@ class MainPanel(empty: Boolean) : JPanel(MigLayout("ins 6, fill")) {

private val openAction = Action(
name = "Open...",
accelerator = KeyStroke.getKeyStroke(KeyEvent.VK_O, Toolkit.getDefaultToolkit().menuShortcutKeyMaskEx),
accelerator = KeyStroke.getKeyStroke(KeyEvent.VK_O, menuShortcutKeyMaskEx),
) {
fileChooser.chooseFiles(this)?.let { selectedFiles ->
fileChooser.chooseFiles(this@MainPanel)?.let { selectedFiles ->
val selectedTool: Tool? = Tool.byFilter[fileChooser.fileFilter]
openFiles(selectedFiles, selectedTool)
}
}

private val tabs = TabStrip()
private val openButton = JButton(openAction)
private val tabs = TabStrip().apply {
if (SystemInfo.isMacFullWindowContentSupported) {
// add padding component for MacOS window controls
leadingComponent = Box.createHorizontalStrut(70)
}

trailingComponent = JPanel(BorderLayout()).apply {
add(
JButton(openAction).apply {
hideActionText = true
icon = FlatSVGIcon("icons/bx-plus.svg")
},
BorderLayout.WEST,
)
}
}

private val debugMenu = JMenu("Debug").apply {
add(
Expand Down Expand Up @@ -116,7 +171,7 @@ class MainPanel(empty: Boolean) : JPanel(MigLayout("ins 6, fill")) {
clipboardTool.open(clipString)
}
} else {
println("No string data found on clipboard")
LOGGER.info("No string data found on clipboard")
}
},
)
Expand All @@ -143,13 +198,6 @@ class MainPanel(empty: Boolean) : JPanel(MigLayout("ins 6, fill")) {
* Opens a path in a tool (blocking). In the event of any error, opens an 'Error' tab instead.
*/
private fun openOrError(title: String, description: String, openFunction: () -> ToolPanel) {
synchronized(treeLock) {
val child = getComponent(0)
if (child == openButton) {
remove(openButton)
add(tabs, "dock center")
}
}
runCatching {
val toolPanel = openFunction()
tabs.addTab(component = toolPanel, select = true)
Expand Down Expand Up @@ -199,11 +247,7 @@ class MainPanel(empty: Boolean) : JPanel(MigLayout("ins 6, fill")) {
}

init {
if (empty) {
add(openButton, "dock center")
} else {
add(tabs, "dock center")
}
add(tabs, "dock center")

Debug.addChangeListener { newValue ->
debugMenu.isVisible = newValue
Expand All @@ -217,15 +261,21 @@ class MainPanel(empty: Boolean) : JPanel(MigLayout("ins 6, fill")) {
fun main(args: Array<String>) {
System.setProperty("apple.awt.application.name", "Kindling")
System.setProperty("apple.laf.useScreenMenuBar", "true")
System.setProperty("apple.awt.application.appearance", "system")
System.setProperty("flatlaf.uiScale", ScaleFactor.currentValue.toString())

EventQueue.invokeLater {
lafSetup()

jFrame("Kindling", 1280, 800) {
jFrame(
title = "Kindling",
width = 1280,
height = 800,
embedContentIntoTitleBar = true,
) {
defaultCloseOperation = JFrame.EXIT_ON_CLOSE

val mainPanel = MainPanel(args.isEmpty())
val mainPanel = MainPanel()
add(mainPanel)
jMenuBar = mainPanel.menuBar

Expand All @@ -245,9 +295,15 @@ class MainPanel(empty: Boolean) : JPanel(MigLayout("ins 6, fill")) {
}

private fun lafSetup() {
FlatRobotoFont.install()
FlatLaf.setPreferredFontFamily(FlatRobotoFont.FAMILY)
FlatLaf.setPreferredLightFontFamily(FlatRobotoFont.FAMILY_LIGHT)
FlatLaf.setPreferredSemiboldFontFamily(FlatRobotoFont.FAMILY_SEMIBOLD)
applyTheme(false)

UIManager.getDefaults().apply {
put("Component.focusWidth", 0)
put("Component.innerfocusWidth", 1)
put("ScrollBar.width", 16)
put("TabbedPane.tabType", "card")
put("MenuItem.minimumIconSize", Dimension()) // https://github.com/JFormDesigner/FlatLaf/issues/328
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,15 @@ class AlarmJournalData(

val body by lazy {
data.properties.map { property ->
println(property.name)
"${property.name} (${property.type.simpleName}) = ${data.getOrDefault(property)}"
}
}

fun toDetail(): Detail {
return Detail(
title = "Alarm Journal Data",
details = details,
body = body,
)
}
fun toDetail() = Detail(
title = "Alarm Journal Data",
details = details,
body = body,
)

companion object {
@JvmStatic
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import io.github.inductiveautomation.kindling.core.Detail.BodyLine
data class Detail(
val title: String,
val message: String? = null,
val details: Map<String, String> = emptyMap(),
val details: Map<String, String?> = emptyMap(),
val body: List<BodyLine> = emptyList(),
) {
data class BodyLine(val text: String, val link: String? = null)
Expand All @@ -14,7 +14,7 @@ data class Detail(
operator fun invoke(
title: String,
message: String? = null,
details: Map<String, String> = emptyMap(),
details: Map<String, String?> = emptyMap(),
body: List<String> = emptyList(),
) = Detail(
title,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.formdev.flatlaf.themes.FlatMacLightLaf
import com.formdev.flatlaf.util.SystemInfo
import io.github.inductiveautomation.kindling.core.Preference.Companion.PreferenceCheckbox
import io.github.inductiveautomation.kindling.core.Preference.Companion.preference
import io.github.inductiveautomation.kindling.utils.CharsetSerializer
import io.github.inductiveautomation.kindling.utils.PathSerializer
import io.github.inductiveautomation.kindling.utils.PathSerializer.serializedForm
import io.github.inductiveautomation.kindling.utils.ThemeSerializer
Expand All @@ -22,6 +23,7 @@ import kotlinx.serialization.json.encodeToStream
import org.jdesktop.swingx.JXTextField
import java.awt.Image
import java.awt.Toolkit
import java.nio.charset.Charset
import java.nio.file.Path
import java.util.Vector
import javax.swing.JComboBox
Expand All @@ -37,13 +39,15 @@ import kotlin.io.path.outputStream
import kotlin.time.Duration.Companion.seconds
import io.github.inductiveautomation.kindling.core.Theme.Companion as KindlingTheme

object Kindling {
data object Kindling {
val frameIcon: Image = Toolkit.getDefaultToolkit().getImage(Kindling::class.java.getResource("/icons/kindling.png"))

object Preferences {
object General : PreferenceCategory {
const val SECONDARY_ACTION_ICON_SCALE = 0.75F

data object Preferences {
data object General : PreferenceCategory {
val HomeLocation: Preference<Path> = preference(
name = "Home Location",
name = "Browse Location",
description = "The default path to start looking for files.",
default = Path(System.getProperty("user.home"), "Downloads"),
serializer = PathSerializer,
Expand All @@ -67,7 +71,7 @@ object Kindling {
)

val DefaultTool: Preference<Tool> = preference(
"Default Tool",
name = "Default Tool",
description = "The default tool to use when invoking the file selector",
default = Tool.tools.first(),
serializer = ToolSerializer,
Expand Down Expand Up @@ -95,6 +99,33 @@ object Kindling {
},
)

val ChoosableEncodings = arrayOf(
Charsets.UTF_8,
Charsets.ISO_8859_1,
Charsets.US_ASCII,
)

val DefaultEncoding: Preference<Charset> = preference(
name = "Encoding",
description = "The default encoding to use when loading text files",
default = if (SystemInfo.isWindows) Charsets.ISO_8859_1 else Charsets.UTF_8,
serializer = CharsetSerializer,
editor = {
JComboBox(ChoosableEncodings).apply {
selectedItem = currentValue

configureCellRenderer { _, value, _, _, _ ->
text = value?.displayName()
toolTipText = value?.displayName()
}

addActionListener {
currentValue = selectedItem as Charset
}
}
},
)

val ShowFullLoggerNames: Preference<Boolean> = preference(
name = "Logger Names",
default = false,
Expand All @@ -112,10 +143,11 @@ object Kindling {
)

override val displayName: String = "General"
override val key: String = "general"
override val preferences: List<Preference<*>> = listOf(HomeLocation, DefaultTool, ShowFullLoggerNames, UseHyperlinks)
}

object UI : PreferenceCategory {
data object UI : PreferenceCategory {
val Theme: Preference<Theme> = preference(
name = "Theme",
default = KindlingTheme.themes.getValue(if (SystemInfo.isMacOS) FlatMacLightLaf.NAME else FlatLightLaf.NAME),
Expand Down Expand Up @@ -145,10 +177,11 @@ object Kindling {
)

override val displayName: String = "UI"
override val key: String = "ui"
override val preferences: List<Preference<*>> = listOf(Theme, ScaleFactor)
}

object Advanced : PreferenceCategory {
data object Advanced : PreferenceCategory {
val Debug: Preference<Boolean> = preference(
name = "Debug Mode",
description = null,
Expand All @@ -163,7 +196,7 @@ object Kindling {
default = LinkHandlingStrategy.OpenInBrowser,
serializer = LinkHandlingStrategy.serializer(),
editor = {
JComboBox(LinkHandlingStrategy.values()).apply {
JComboBox(Vector(LinkHandlingStrategy.entries)).apply {
selectedItem = currentValue

configureCellRenderer { _, value, _, _, _ ->
Expand All @@ -178,6 +211,7 @@ object Kindling {
)

override val displayName: String = "Advanced"
override val key: String = "advanced"
override val preferences: List<Preference<*>> = listOf(Debug, HyperlinkStrategy)
}

Expand Down
Loading

0 comments on commit e662ac2

Please sign in to comment.