mirror of
https://github.com/TermoraDev/termora.git
synced 2026-01-15 18:02: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) {
|
set(value) {
|
||||||
enableManager.setFlag("Plugins.bg.interval", 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.GlassPaneExtension
|
||||||
import app.termora.WindowScope
|
import app.termora.WindowScope
|
||||||
|
import app.termora.restore
|
||||||
|
import app.termora.save
|
||||||
import com.formdev.flatlaf.FlatLaf
|
import com.formdev.flatlaf.FlatLaf
|
||||||
import java.awt.AlphaComposite
|
import java.awt.AlphaComposite
|
||||||
import java.awt.Graphics2D
|
import java.awt.Graphics2D
|
||||||
@@ -12,15 +14,52 @@ class BGGlassPaneExtension private constructor() : GlassPaneExtension {
|
|||||||
val instance = BGGlassPaneExtension()
|
val instance = BGGlassPaneExtension()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun paint(scope: WindowScope, c: JComponent, g2d: Graphics2D) {
|
override fun paint(scope: WindowScope, c: JComponent, g2d: Graphics2D) {
|
||||||
|
|
||||||
val img = BackgroundManager.getInstance().getBackgroundImage() ?: return
|
val img = BackgroundManager.getInstance().getBackgroundImage() ?: return
|
||||||
|
g2d.save()
|
||||||
g2d.composite = AlphaComposite.getInstance(
|
g2d.composite = AlphaComposite.getInstance(
|
||||||
AlphaComposite.SRC_OVER,
|
AlphaComposite.SRC_OVER,
|
||||||
if (FlatLaf.isLafDark()) 0.2f else 0.1f
|
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.apache.commons.lang3.exception.ExceptionUtils
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import java.awt.BorderLayout
|
import java.awt.BorderLayout
|
||||||
|
import java.awt.Component
|
||||||
|
import java.awt.event.ItemEvent
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.nio.file.StandardCopyOption
|
import java.nio.file.StandardCopyOption
|
||||||
import javax.swing.*
|
import javax.swing.*
|
||||||
@@ -23,6 +25,7 @@ class BackgroundOption : JPanel(BorderLayout()), OptionsPane.PluginOption {
|
|||||||
private val owner get() = SwingUtilities.getWindowAncestor(this)
|
private val owner get() = SwingUtilities.getWindowAncestor(this)
|
||||||
|
|
||||||
val backgroundImageTextField = OutlineTextField()
|
val backgroundImageTextField = OutlineTextField()
|
||||||
|
val fillModeComboBox = OutlineComboBox<FillMode>()
|
||||||
val intervalSpinner = NumberSpinner(360, minimum = 30, maximum = 86400)
|
val intervalSpinner = NumberSpinner(360, minimum = 30, maximum = 86400)
|
||||||
|
|
||||||
private val backgroundButton = JButton(Icons.folder)
|
private val backgroundButton = JButton(Icons.folder)
|
||||||
@@ -36,6 +39,38 @@ class BackgroundOption : JPanel(BorderLayout()), OptionsPane.PluginOption {
|
|||||||
|
|
||||||
private fun initView() {
|
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.isEditable = false
|
||||||
backgroundImageTextField.trailingComponent = backgroundButton
|
backgroundImageTextField.trailingComponent = backgroundButton
|
||||||
backgroundImageTextField.text = Appearance.backgroundImage
|
backgroundImageTextField.text = Appearance.backgroundImage
|
||||||
@@ -80,6 +115,15 @@ class BackgroundOption : JPanel(BorderLayout()), OptionsPane.PluginOption {
|
|||||||
Appearance.interval = value
|
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) {
|
private fun onSelectedBackgroundImage(file: File) {
|
||||||
@@ -124,7 +168,7 @@ class BackgroundOption : JPanel(BorderLayout()), OptionsPane.PluginOption {
|
|||||||
private fun getFormPanel(): JPanel {
|
private fun getFormPanel(): JPanel {
|
||||||
val layout = FormLayout(
|
val layout = FormLayout(
|
||||||
"left:pref, $FORM_MARGIN, default:grow, $FORM_MARGIN, default",
|
"left:pref, $FORM_MARGIN, default:grow, $FORM_MARGIN, default",
|
||||||
"pref, $FORM_MARGIN, pref"
|
"pref, $FORM_MARGIN, pref, $FORM_MARGIN, pref"
|
||||||
)
|
)
|
||||||
|
|
||||||
var rows = 1
|
var rows = 1
|
||||||
@@ -138,6 +182,10 @@ class BackgroundOption : JPanel(BorderLayout()), OptionsPane.PluginOption {
|
|||||||
.add(bgClearBox).xy(5, rows)
|
.add(bgClearBox).xy(5, rows)
|
||||||
.apply { rows += step }
|
.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)
|
builder.add("${BGI18n.getString("termora.plugins.bg.interval")}:").xy(1, rows)
|
||||||
.add(intervalSpinner).xy(3, rows)
|
.add(intervalSpinner).xy(3, rows)
|
||||||
.apply { rows += step }
|
.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.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
|
termora.plugins.bg.background-image=Background Image
|
||||||
|
|||||||
@@ -1,2 +1,8 @@
|
|||||||
termora.plugins.bg.background-image=背景图
|
termora.plugins.bg.background-image=背景图
|
||||||
termora.plugins.bg.interval=切换间隔
|
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.background-image=背景圖
|
||||||
termora.plugins.bg.interval=切換間隔
|
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