mirror of
https://github.com/TermoraDev/termora.git
synced 2026-01-16 02:12:58 +08:00
feat: background image supports fill mode
This commit is contained in:
@@ -3,7 +3,7 @@ plugins {
|
||||
}
|
||||
|
||||
|
||||
project.version = "0.0.5"
|
||||
project.version = "0.0.6"
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -18,4 +18,8 @@ object Appearance {
|
||||
set(value) {
|
||||
enableManager.setFlag("Plugins.bg.interval", value)
|
||||
}
|
||||
|
||||
var fillMode: String
|
||||
get() = enableManager.getFlag("Plugins.bg.fillMode", FillMode.STRETCH.name)
|
||||
set(value) = enableManager.setFlag("Plugins.bg.fillMode", value)
|
||||
}
|
||||
@@ -2,6 +2,8 @@ package app.termora.plugins.bg
|
||||
|
||||
import app.termora.GlassPaneExtension
|
||||
import app.termora.WindowScope
|
||||
import app.termora.restore
|
||||
import app.termora.save
|
||||
import com.formdev.flatlaf.FlatLaf
|
||||
import java.awt.AlphaComposite
|
||||
import java.awt.Graphics2D
|
||||
@@ -12,15 +14,52 @@ class BGGlassPaneExtension private constructor() : GlassPaneExtension {
|
||||
val instance = BGGlassPaneExtension()
|
||||
}
|
||||
|
||||
|
||||
override fun paint(scope: WindowScope, c: JComponent, g2d: Graphics2D) {
|
||||
|
||||
val img = BackgroundManager.getInstance().getBackgroundImage() ?: return
|
||||
g2d.save()
|
||||
g2d.composite = AlphaComposite.getInstance(
|
||||
AlphaComposite.SRC_OVER,
|
||||
if (FlatLaf.isLafDark()) 0.2f else 0.1f
|
||||
)
|
||||
g2d.drawImage(img, 0, 0, c.width, c.height, null)
|
||||
g2d.composite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER)
|
||||
|
||||
when (Appearance.fillMode) {
|
||||
FillMode.STRETCH.name -> {
|
||||
g2d.drawImage(img, 0, 0, c.width, c.height, null)
|
||||
}
|
||||
|
||||
FillMode.CENTER.name -> {
|
||||
val x = (c.width - img.width) / 2
|
||||
val y = (c.height - img.height) / 2
|
||||
g2d.drawImage(img, x, y, null)
|
||||
}
|
||||
|
||||
FillMode.TILE.name -> {
|
||||
val iw = img.width
|
||||
val ih = img.height
|
||||
var y = 0
|
||||
while (y < c.height) {
|
||||
var x = 0
|
||||
while (x < c.width) {
|
||||
g2d.drawImage(img, x, y, null)
|
||||
x += iw
|
||||
}
|
||||
y += ih
|
||||
}
|
||||
}
|
||||
|
||||
FillMode.FIT.name -> {
|
||||
val scale = maxOf(c.width.toDouble() / img.width, c.height.toDouble() / img.height)
|
||||
val newW = (img.width * scale).toInt()
|
||||
val newH = (img.height * scale).toInt()
|
||||
val x = (c.width - newW) / 2
|
||||
val y = (c.height - newH) / 2
|
||||
g2d.drawImage(img, x, y, newW, newH, null)
|
||||
}
|
||||
}
|
||||
|
||||
g2d.restore()
|
||||
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,8 @@ import org.apache.commons.lang3.StringUtils
|
||||
import org.apache.commons.lang3.exception.ExceptionUtils
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.awt.BorderLayout
|
||||
import java.awt.Component
|
||||
import java.awt.event.ItemEvent
|
||||
import java.io.File
|
||||
import java.nio.file.StandardCopyOption
|
||||
import javax.swing.*
|
||||
@@ -23,6 +25,7 @@ class BackgroundOption : JPanel(BorderLayout()), OptionsPane.PluginOption {
|
||||
private val owner get() = SwingUtilities.getWindowAncestor(this)
|
||||
|
||||
val backgroundImageTextField = OutlineTextField()
|
||||
val fillModeComboBox = OutlineComboBox<FillMode>()
|
||||
val intervalSpinner = NumberSpinner(360, minimum = 30, maximum = 86400)
|
||||
|
||||
private val backgroundButton = JButton(Icons.folder)
|
||||
@@ -36,6 +39,38 @@ class BackgroundOption : JPanel(BorderLayout()), OptionsPane.PluginOption {
|
||||
|
||||
private fun initView() {
|
||||
|
||||
fillModeComboBox.addItem(FillMode.STRETCH)
|
||||
fillModeComboBox.addItem(FillMode.FIT)
|
||||
fillModeComboBox.addItem(FillMode.CENTER)
|
||||
fillModeComboBox.addItem(FillMode.TILE)
|
||||
|
||||
fillModeComboBox.selectedItem = runCatching { FillMode.valueOf(Appearance.fillMode) }
|
||||
.getOrNull() ?: FillMode.STRETCH
|
||||
|
||||
fillModeComboBox.renderer = object : DefaultListCellRenderer() {
|
||||
override fun getListCellRendererComponent(
|
||||
list: JList<*>?,
|
||||
value: Any?,
|
||||
index: Int,
|
||||
isSelected: Boolean,
|
||||
cellHasFocus: Boolean
|
||||
): Component? {
|
||||
var text = value?.toString()
|
||||
|
||||
if (value == FillMode.STRETCH) {
|
||||
text = BGI18n.getString("termora.plugins.bg.fill-mode.stretch")
|
||||
} else if (value == FillMode.FIT) {
|
||||
text = BGI18n.getString("termora.plugins.bg.fill-mode.fit")
|
||||
} else if (value == FillMode.CENTER) {
|
||||
text = BGI18n.getString("termora.plugins.bg.fill-mode.center")
|
||||
} else if (value == FillMode.TILE) {
|
||||
text = BGI18n.getString("termora.plugins.bg.fill-mode.tile")
|
||||
}
|
||||
|
||||
return super.getListCellRendererComponent(list, text, index, isSelected, cellHasFocus)
|
||||
}
|
||||
}
|
||||
|
||||
backgroundImageTextField.isEditable = false
|
||||
backgroundImageTextField.trailingComponent = backgroundButton
|
||||
backgroundImageTextField.text = Appearance.backgroundImage
|
||||
@@ -80,6 +115,15 @@ class BackgroundOption : JPanel(BorderLayout()), OptionsPane.PluginOption {
|
||||
Appearance.interval = value
|
||||
}
|
||||
}
|
||||
|
||||
fillModeComboBox.addItemListener {
|
||||
if (it.stateChange == ItemEvent.SELECTED) {
|
||||
Appearance.fillMode = fillModeComboBox.selectedItem?.toString() ?: FillMode.STRETCH.name
|
||||
for (frame in TermoraFrameManager.getInstance().getWindows()) {
|
||||
SwingUtilities.invokeLater { SwingUtilities.updateComponentTreeUI(frame) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun onSelectedBackgroundImage(file: File) {
|
||||
@@ -124,7 +168,7 @@ class BackgroundOption : JPanel(BorderLayout()), OptionsPane.PluginOption {
|
||||
private fun getFormPanel(): JPanel {
|
||||
val layout = FormLayout(
|
||||
"left:pref, $FORM_MARGIN, default:grow, $FORM_MARGIN, default",
|
||||
"pref, $FORM_MARGIN, pref"
|
||||
"pref, $FORM_MARGIN, pref, $FORM_MARGIN, pref"
|
||||
)
|
||||
|
||||
var rows = 1
|
||||
@@ -138,6 +182,10 @@ class BackgroundOption : JPanel(BorderLayout()), OptionsPane.PluginOption {
|
||||
.add(bgClearBox).xy(5, rows)
|
||||
.apply { rows += step }
|
||||
|
||||
builder.add("${BGI18n.getString("termora.plugins.bg.fill-mode")}:").xy(1, rows)
|
||||
.add(fillModeComboBox).xy(3, rows)
|
||||
.apply { rows += step }
|
||||
|
||||
builder.add("${BGI18n.getString("termora.plugins.bg.interval")}:").xy(1, rows)
|
||||
.add(intervalSpinner).xy(3, rows)
|
||||
.apply { rows += step }
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package app.termora.plugins.bg
|
||||
|
||||
enum class FillMode {
|
||||
STRETCH, // 拉伸
|
||||
FIT, // 等比例铺满
|
||||
CENTER, // 居中
|
||||
TILE, // 平铺
|
||||
}
|
||||
@@ -1,2 +1,7 @@
|
||||
termora.plugins.bg.interval=Interval
|
||||
termora.plugins.bg.fill-mode=Fill Mode
|
||||
termora.plugins.bg.fill-mode.stretch=Stretch
|
||||
termora.plugins.bg.fill-mode.fit=Fit
|
||||
termora.plugins.bg.fill-mode.center=Center
|
||||
termora.plugins.bg.fill-mode.tile=Tile
|
||||
termora.plugins.bg.background-image=Background Image
|
||||
|
||||
@@ -1,2 +1,8 @@
|
||||
termora.plugins.bg.background-image=背景图
|
||||
termora.plugins.bg.interval=切换间隔
|
||||
|
||||
termora.plugins.bg.fill-mode=填充模式
|
||||
termora.plugins.bg.fill-mode.stretch=拉伸
|
||||
termora.plugins.bg.fill-mode.fit=适合
|
||||
termora.plugins.bg.fill-mode.center=居中
|
||||
termora.plugins.bg.fill-mode.tile=平铺
|
||||
|
||||
@@ -1,2 +1,8 @@
|
||||
termora.plugins.bg.background-image=背景圖
|
||||
termora.plugins.bg.interval=切換間隔
|
||||
|
||||
termora.plugins.bg.fill-mode=填充模式
|
||||
termora.plugins.bg.fill-mode.stretch=拉伸
|
||||
termora.plugins.bg.fill-mode.fit=適合
|
||||
termora.plugins.bg.fill-mode.center=居中
|
||||
termora.plugins.bg.fill-mode.tile=平鋪
|
||||
|
||||
Reference in New Issue
Block a user