mirror of
https://github.com/TermoraDev/termora.git
synced 2026-01-16 02:12:58 +08:00
feat: editor support maximization
This commit is contained in:
@@ -4,7 +4,7 @@ plugins {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
project.version = "0.0.6"
|
project.version = "0.0.7"
|
||||||
|
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|||||||
@@ -1,94 +0,0 @@
|
|||||||
package app.termora.plugins.editor
|
|
||||||
|
|
||||||
import app.termora.DialogWrapper
|
|
||||||
import app.termora.Disposable
|
|
||||||
import app.termora.Disposer
|
|
||||||
import app.termora.OptionPane
|
|
||||||
import java.awt.Dimension
|
|
||||||
import java.awt.Window
|
|
||||||
import java.awt.event.WindowAdapter
|
|
||||||
import java.awt.event.WindowEvent
|
|
||||||
import java.io.File
|
|
||||||
import java.nio.file.Path
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean
|
|
||||||
import javax.swing.JComponent
|
|
||||||
import javax.swing.JOptionPane
|
|
||||||
import javax.swing.UIManager
|
|
||||||
import kotlin.io.path.absolutePathString
|
|
||||||
import kotlin.io.path.name
|
|
||||||
|
|
||||||
|
|
||||||
class EditorDialog(file: Path, owner: Window, private val myDisposable: Disposable) : DialogWrapper(null) {
|
|
||||||
|
|
||||||
private val filename = file.name
|
|
||||||
private val filepath = File(file.absolutePathString())
|
|
||||||
private val editorPanel = EditorPanel(this, filepath)
|
|
||||||
private val disposed = AtomicBoolean()
|
|
||||||
|
|
||||||
init {
|
|
||||||
size = Dimension(UIManager.getInt("Dialog.width"), UIManager.getInt("Dialog.height"))
|
|
||||||
isModal = false
|
|
||||||
controlsVisible = true
|
|
||||||
isResizable = true
|
|
||||||
title = filename
|
|
||||||
iconImages = owner.iconImages
|
|
||||||
escapeDispose = false
|
|
||||||
defaultCloseOperation = DO_NOTHING_ON_CLOSE
|
|
||||||
|
|
||||||
initEvents()
|
|
||||||
|
|
||||||
setLocationRelativeTo(owner)
|
|
||||||
|
|
||||||
init()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private fun initEvents() {
|
|
||||||
|
|
||||||
addWindowListener(object : WindowAdapter() {
|
|
||||||
override fun windowClosing(e: WindowEvent?) {
|
|
||||||
if (disposed.compareAndSet(false, true)) {
|
|
||||||
doCancelAction()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
Disposer.register(myDisposable, object : Disposable {
|
|
||||||
override fun dispose() {
|
|
||||||
if (disposed.compareAndSet(false, true)) {
|
|
||||||
doCancelAction()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
Disposer.register(disposable, object : Disposable {
|
|
||||||
override fun dispose() {
|
|
||||||
if (disposed.compareAndSet(false, true)) {
|
|
||||||
Disposer.dispose(myDisposable)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun doCancelAction() {
|
|
||||||
if (editorPanel.changes()) {
|
|
||||||
if (OptionPane.showConfirmDialog(
|
|
||||||
this,
|
|
||||||
"文件尚未保存,你确定要退出吗?",
|
|
||||||
optionType = JOptionPane.OK_CANCEL_OPTION,
|
|
||||||
) != JOptionPane.OK_OPTION
|
|
||||||
) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
super.doCancelAction()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun createCenterPanel(): JComponent {
|
|
||||||
return editorPanel
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun createSouthPanel(): JComponent? {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
package app.termora.plugins.editor
|
||||||
|
|
||||||
|
import app.termora.Disposable
|
||||||
|
import app.termora.Disposer
|
||||||
|
import app.termora.EnableManager
|
||||||
|
import app.termora.OptionPane
|
||||||
|
import java.awt.BorderLayout
|
||||||
|
import java.awt.Dimension
|
||||||
|
import java.awt.Window
|
||||||
|
import java.awt.event.WindowAdapter
|
||||||
|
import java.awt.event.WindowEvent
|
||||||
|
import java.io.File
|
||||||
|
import java.nio.file.Path
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
|
import javax.swing.JFrame
|
||||||
|
import javax.swing.JOptionPane
|
||||||
|
import javax.swing.UIManager
|
||||||
|
import kotlin.io.path.absolutePathString
|
||||||
|
import kotlin.io.path.name
|
||||||
|
import kotlin.math.max
|
||||||
|
|
||||||
|
class EditorFrame(private val file: Path, private val owner: Window, private val disposable: Disposable) : JFrame() {
|
||||||
|
private val enableManager get() = EnableManager.getInstance()
|
||||||
|
private val disposed = AtomicBoolean()
|
||||||
|
private val filepath = File(file.absolutePathString())
|
||||||
|
private val frame get() = this
|
||||||
|
private val editorPanel = EditorPanel(this, filepath)
|
||||||
|
|
||||||
|
init {
|
||||||
|
initView()
|
||||||
|
initEvent()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initEvent() {
|
||||||
|
|
||||||
|
Disposer.register(disposable, object : Disposable {
|
||||||
|
override fun dispose() {
|
||||||
|
if (disposed.compareAndSet(false, true)) frame.dispose()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
addWindowListener(object : WindowAdapter() {
|
||||||
|
override fun windowClosed(e: WindowEvent) {
|
||||||
|
if (disposed.compareAndSet(false, true)) Disposer.dispose(disposable)
|
||||||
|
enableManager.setFlag("Plugins.editor.dialog.width", width)
|
||||||
|
enableManager.setFlag("Plugins.editor.dialog.height", height)
|
||||||
|
enableManager.setFlag("Plugins.editor.dialog.extendedState", extendedState)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun windowClosing(e: WindowEvent?) {
|
||||||
|
if (editorPanel.changes()) {
|
||||||
|
if (OptionPane.showConfirmDialog(
|
||||||
|
frame,
|
||||||
|
EditorI18n.getString("termora.plugins.editor.not-save"),
|
||||||
|
optionType = JOptionPane.OK_CANCEL_OPTION,
|
||||||
|
) == JOptionPane.OK_OPTION
|
||||||
|
) {
|
||||||
|
frame.dispose()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
frame.dispose()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initView() {
|
||||||
|
size = Dimension(UIManager.getInt("Dialog.width"), UIManager.getInt("Dialog.height"))
|
||||||
|
val state = enableManager.getFlag("Plugins.editor.dialog.extendedState", 0)
|
||||||
|
|
||||||
|
if ((state and MAXIMIZED_BOTH) == MAXIMIZED_BOTH) {
|
||||||
|
frame.setLocationRelativeTo(null)
|
||||||
|
frame.extendedState = state
|
||||||
|
} else {
|
||||||
|
val mySize = size
|
||||||
|
mySize.width = max(enableManager.getFlag("Plugins.editor.dialog.width", mySize.width), mySize.width)
|
||||||
|
mySize.height = max(enableManager.getFlag("Plugins.editor.dialog.height", mySize.height), mySize.height)
|
||||||
|
size = mySize
|
||||||
|
setLocationRelativeTo(owner)
|
||||||
|
}
|
||||||
|
|
||||||
|
title = file.name
|
||||||
|
iconImages = owner.iconImages
|
||||||
|
defaultCloseOperation = DO_NOTHING_ON_CLOSE
|
||||||
|
|
||||||
|
rootPane.contentPane.layout = BorderLayout()
|
||||||
|
rootPane.contentPane.add(editorPanel, BorderLayout.CENTER)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package app.termora.plugins.editor
|
||||||
|
|
||||||
|
import app.termora.NamedI18n
|
||||||
|
import org.slf4j.Logger
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
|
|
||||||
|
object EditorI18n : NamedI18n("i18n/messages") {
|
||||||
|
private val log = LoggerFactory.getLogger(EditorI18n::class.java)
|
||||||
|
|
||||||
|
override fun getLogger(): Logger {
|
||||||
|
return log
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -35,7 +35,7 @@ import javax.swing.event.DocumentEvent
|
|||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
class EditorPanel(private val window: JDialog, private val file: File) : JPanel(BorderLayout()) {
|
class EditorPanel(private val window: JFrame, private val file: File) : JPanel(BorderLayout()) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val log = LoggerFactory.getLogger(EditorPanel::class.java)
|
private val log = LoggerFactory.getLogger(EditorPanel::class.java)
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class MyTransportEditFileExtension private constructor() : TransportEditFileExte
|
|||||||
|
|
||||||
override fun edit(owner: Window, path: Path): Disposable {
|
override fun edit(owner: Window, path: Path): Disposable {
|
||||||
val disposable = Disposer.newDisposable()
|
val disposable = Disposer.newDisposable()
|
||||||
SwingUtilities.invokeLater { EditorDialog(path, owner, disposable).isVisible = true }
|
SwingUtilities.invokeLater { EditorFrame(path, owner, disposable).isVisible = true }
|
||||||
return disposable
|
return disposable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
termora.plugins.editor.not-save=The file has not been saved. Are you sure you want to exit?
|
||||||
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
termora.plugins.editor.not-save=Файл не сохранён. Вы уверены, что хотите выйти?
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
termora.plugins.editor.not-save=文件尚未保存,你确定要退出吗?
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
termora.plugins.editor.not-save=檔案尚未儲存,你確定要退出嗎?
|
||||||
@@ -1,8 +1,11 @@
|
|||||||
package app.termora.plugin.internal.updater
|
package app.termora.plugin.internal.updater
|
||||||
|
|
||||||
import app.termora.*
|
import app.termora.*
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.swing.Swing
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
import org.semver4j.Semver
|
import org.semver4j.Semver
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import java.awt.KeyboardFocusManager
|
import java.awt.KeyboardFocusManager
|
||||||
@@ -20,7 +23,7 @@ internal class MyApplicationRunnerExtension private constructor() : ApplicationR
|
|||||||
|
|
||||||
|
|
||||||
override fun ready() {
|
override fun ready() {
|
||||||
swingCoroutineScope.launch {
|
swingCoroutineScope.launch(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
delay(3.seconds)
|
delay(3.seconds)
|
||||||
scheduleUpdate()
|
scheduleUpdate()
|
||||||
@@ -31,7 +34,7 @@ internal class MyApplicationRunnerExtension private constructor() : ApplicationR
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun scheduleUpdate() {
|
private suspend fun scheduleUpdate() {
|
||||||
if (disabledUpdater) return
|
if (disabledUpdater) return
|
||||||
|
|
||||||
val latestVersion = updaterManager.fetchLatestVersion()
|
val latestVersion = updaterManager.fetchLatestVersion()
|
||||||
@@ -45,13 +48,15 @@ internal class MyApplicationRunnerExtension private constructor() : ApplicationR
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
withContext(Dispatchers.Swing) {
|
||||||
val owner = KeyboardFocusManager.getCurrentKeyboardFocusManager().focusedWindow
|
val owner = KeyboardFocusManager.getCurrentKeyboardFocusManager().focusedWindow
|
||||||
?: TermoraFrameManager.getInstance().getWindows().firstOrNull()
|
?: TermoraFrameManager.getInstance().getWindows().firstOrNull()
|
||||||
if (owner == null) return
|
if (owner != null) {
|
||||||
|
|
||||||
val dialog = UpdaterDialog(owner, latestVersion)
|
val dialog = UpdaterDialog(owner, latestVersion)
|
||||||
dialog.isModal = true
|
dialog.isModal = true
|
||||||
dialog.isVisible = true
|
dialog.isVisible = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user