diff --git a/serverpackcreator-gui/build.gradle.kts b/serverpackcreator-gui/build.gradle.kts index 46c1fdb9d..625270428 100644 --- a/serverpackcreator-gui/build.gradle.kts +++ b/serverpackcreator-gui/build.gradle.kts @@ -11,6 +11,7 @@ dependencies { api(project(":serverpackcreator-api")) api("commons-io:commons-io:2.11.0") api("org.jetbrains.kotlinx:kotlinx-coroutines-swing:1.6.4") + api("org.jetbrains.kotlin:kotlin-reflect:1.8.20") implementation(project(":serverpackcreator-updater")) //New GUI @@ -26,6 +27,7 @@ dependencies { api("net.java.balloontip:balloontip:1.2.4.1") api("com.github.dyorgio.runtime:run-as-root:1.2.3") api("com.cronutils:cron-utils:9.2.1") + api("tokyo.northside:tipoftheday:0.4.2") testImplementation("org.junit.jupiter:junit-jupiter-api:5.9.3") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.9.3") diff --git a/serverpackcreator-gui/src/main/i18n/Gui_en_GB.properties b/serverpackcreator-gui/src/main/i18n/Gui_en_GB.properties index 6664d0d6a..be9efe9d8 100644 --- a/serverpackcreator-gui/src/main/i18n/Gui_en_GB.properties +++ b/serverpackcreator-gui/src/main/i18n/Gui_en_GB.properties @@ -221,6 +221,7 @@ menubar.gui.menuitem.spcdir=Open installation directory menubar.gui.menuitem.homedir=Open configs directory menubar.gui.menuitem.serverfilesdir=Open server-files directory menubar.gui.menuitem.licensereport=Third Party Notices +menubar.gui.menuitem.tipoftheday=Tip Of The Day menubar.gui.config.load.message=Do you want to load the selected configuration into the current tab, or a new tab?\n\n{0} menubar.gui.config.load.title=Load Configuration menubar.gui.config.load.current=Current Tab @@ -361,6 +362,54 @@ main.unsaved.title=Unsaved Settings! main.tabs.config=Configs main.tabs.logs=Logs main.tabs.settings=Settings +tips.title=Tip Of The Day! +tips.know=Did you know... +tips.show=Show tips on startup +tips.next=Next > +tips.previous=< Previous +tips.close=Close +tip.1.content=You can save the currently selected server pack configuration by pressing CTRL + S. +tip.1.name=Save quickly +tip.2.content=You can open a new server pack configuration tab by pressing CTRL + T. +tip.2.name=Open a new tab +tip.3.content=Identified a mod which crashes servers, and therefore only required on the clientside, but not on the server side i.e. in your server pack? Submit an Improvement Request on GitHub, with the name of the mod and the link to CurseForge / Modrinth! +tip.3.name=Contribute clientside mods +tip.4.content=You can create server packs from zipped modpacks. Make sure all modpack contents are at the root of the ZIP-archive, and not bundled in a sub-folder inside the archive. Point the Modpack Directory setting of your server pack configuration at your ZIP-archive and set everything else according to your modpack. You still need to tell ServerPackCreator which directories or files to include, which Minecraft version, modloader and modloader version your modpack uses, though! +tip.4.name=Zipped modpacks +tip.5.content=Want to tickle some more performance out of your server? Try out Aikars Flags! Check out Advanced Settings -> Use Aikars Flags which will add said Aikars Flags to your server packs Run Arguments. Generate your server pack and run your server to see whether it improved your servers performance! +tip.5.name=Custom JVM flags / run args +tip.6.content=Want to keep different versions of a server pack, generated from the same modpack? Take a look at Server Pack Suffix which will add said suffix to the generated server pack, allowing you to try out different settings for your server pack, without loosing previous generation. Suffixes like Aikars_Flags, With_Blueprints, With_BlueMap to give you an idea. +tip.6.name=Identify with suffixes +tip.7.content=You can add server icons for quick selection by copying them to the server icon directory. In the menu at the top, click View -> Open server-icon directory. Any PNG-, JPG-, JPEG- and BMP-image added to said directory will be available in your server pack configs Server Icon Quick select dropdown. Select an image from said dropdown to quickly use it as your servers icon! +tip.7.name=Server icon +tip.8.content=You can add server properties for quick selection by copying them to the server properties directory. In the menu at the top, click View -> Open server-properties directory. Any PROPERTIES-file added to said directory will be available in your server pack configs Server Properties Quick select dropdown. Select an entry from said dropdown to quickly use it as your servers properties-file! +tip.8.name=Shipped properties +tip.9.content=You can let ServerPackCreator scan your modpack-directory and try to automatically set the Minecraft version, modloader and modloader version, as well as some commonly used directories in servers. Hit the magnifying-glass-button on the right to your Modpack Directory-setting. +tip.9.name=Clientside detection +tip.10.content=You can let ServerPackCreator copy a file or directory to a customized destination in your server pack. Say you've got a folder MyAwesomeStuff in your modpack configured as the Source, filling Destination with, say, AwesomeStuff will copy the aforementioned Source to your specified Destination inside your server pack.
Inclusions which specify an explicit Destination are marked with a D. +tip.10.name=Advanced inclusion +tip.11.content=You can filter files and directories from any Source-specification by providing a Inclusion-Filter. Any file or directory matching the Regex-expression you provided will be included in your server pack. To include everything from your specified Source, leave Inclusion-Filter empty. +tip.11.name=Advanced inclusion filtering +tip.12.content=You can filter files and directories from any Source-specification by providing an Exclusion-Filter. Any file or directory matching the Regex-expression you provided will be excluded from your server pack. If you leave Exclusion-Filter empty, no files or directories will be excluded from the specified Source. +tip.12.name=Advanced exclusion filtering +tip.13.content=Global exclusion-filters allow you to globally exclude files and directories from any source during the creation of your server pack. To specify a global exclusion-filter, add a new entry in your Server-files, leave Source empty, but fill Exclusion-Filter with a Regex-expression based on which files or directories should be excluded during the creation of your server pack. A global exclusion-filter will be marked with (E) in your Server-files list. +tip.13.name=Global filtering +tip.14.content=If ServerPackCreators default font size is too small for you, or the theme not to your liking, you can change these settings in Settings -> Gui to better fit your personal preferences. +tip.14.name=Size matters +tip.15.content=Not sure if a clientside-only mod is included in the list of clientside-only mods in your server pack config? Click the aforementioned list and hit CTRL+F and search for it! Try searching for "advan" to highlight all entries which contain that text! You can perform text-searches like that in every textarea of ServerPackCreator. Searching textfields is not possible, though, so keep that in mind. +tip.15.name=Searching... +tip.16.content=Need to replace some text in a textarea? Say, for example, you've got some JVM flags / run arguments you want to replace with something else? Click Advanced Settings -> Run Arguments and hit CTRL+R, then type in the text you want to replace as well as the text you want to place it with and hit OK. You can perform replace-actions like that in every textarea of ServerPackCreator. Replacing in textfields is not possible, though, so keep that in mind. +tip.16.name=This to that +tip.17.content=No longer need the currently selected server pack configuration? Close it by pressing CTRL+W! +tip.17.name=Be gone, config! +tip.18.content=You can save all currently opened server pack configurations, or in other words, all currently opened tabs with your server pack configurations, by pressing CTRL+SHIFT+S! +tip.18.name=Gotta save 'em all! +tip.19.content=You can open the dialog to load a server pack configuration by pressing CTRL+L. +tip.19.name=Quick loading +tip.20.content=You can start a server pack generation for the currently selected config-tab by pressing CTRL+G. +tip.20.name=Quick generation +tip.21.content=Does your server crash, with a message like "Error: could not find or load main class @user_jvm_args.txt"? This is most likely because you are trying to run the server with an incompatible Java version. Java 8 is required to run Minecraft versions 1.12 through 1.17. Java 17 is required to run Minecraft version 1.18 and up. +tip.21.name=Use the right version! # LOGS ## Error logs configuration.title.error=This configuration has errors! diff --git a/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/GuiProps.kt b/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/GuiProps.kt index 762892130..e4b921a82 100644 --- a/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/GuiProps.kt +++ b/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/GuiProps.kt @@ -43,6 +43,21 @@ import javax.swing.SwingUtilities import javax.swing.UIManager import javax.swing.plaf.FontUIResource +private const val tabbedPaneFocusColorProp = "TabbedPane.focusColor" +private const val panelBackgroundProp = "Panel.background" +private const val tabbedPaneUnderlineColorProp = "TabbedPane.underlineColor" +private const val focusStartProp = "focus.start" +private const val focusGenerationProp = "focus.generation" +private const val themeProp = "theme" +private const val fontSizeProp = "font.size" +private const val defaultFontProp = "defaultFont" +private const val fontFamilyProp = "font.family" +private const val jetBrainsMono = "JetBrains Mono" +private const val tipsViewedProp = "tips.viewed" +private const val tipsShowOnStartupProp = "tips.show" +private const val falseAsStr = "false" +private const val trueAsStr = "true" + /** * Properties used at various places across the whole of the ServerPackCreator GUI, such as icons. * @@ -278,6 +293,12 @@ class GuiProps(private val apiProperties: ApiProperties) { defaultSize ) + val fancyInfoIcon = ImageUtilities.fromBase64( + "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", + 32, + 32 + ) + val infoIcon = FlatSVGIcon("de/griefed/resources/gui/svg/informationDialog.svg", defaultSize, defaultSize) val warningIcon = FlatSVGIcon("de/griefed/resources/gui/svg/warningDialog.svg", defaultSize, defaultSize) val errorIcon = FlatSVGIcon("de/griefed/resources/gui/svg/errorDialog.svg", defaultSize, defaultSize) @@ -314,16 +335,16 @@ class GuiProps(private val apiProperties: ApiProperties) { useDivider = false, cylonAnimation = false, eyeColours = arrayOf( - UIManager.getColor("TabbedPane.focusColor"), - UIManager.getColor("TabbedPane.focusColor"), - UIManager.getColor("TabbedPane.focusColor"), - UIManager.getColor("TabbedPane.focusColor"), - UIManager.getColor("TabbedPane.focusColor"), - UIManager.getColor("TabbedPane.focusColor"), - UIManager.getColor("TabbedPane.focusColor") + UIManager.getColor(tabbedPaneFocusColorProp), + UIManager.getColor(tabbedPaneFocusColorProp), + UIManager.getColor(tabbedPaneFocusColorProp), + UIManager.getColor(tabbedPaneFocusColorProp), + UIManager.getColor(tabbedPaneFocusColorProp), + UIManager.getColor(tabbedPaneFocusColorProp), + UIManager.getColor(tabbedPaneFocusColorProp) ), - scannerBackgroundColour = UIManager.getColor("Panel.background"), - eyeBackgroundColour = UIManager.getColor("Panel.background") + scannerBackgroundColour = UIManager.getColor(panelBackgroundProp), + eyeBackgroundColour = UIManager.getColor(panelBackgroundProp) ) } val busyConfig: ScannerConfig @@ -343,23 +364,23 @@ class GuiProps(private val apiProperties: ApiProperties) { useDivider = true, cylonAnimation = false, eyeColours = arrayOf( - UIManager.getColor("TabbedPane.focusColor"), - UIManager.getColor("TabbedPane.focusColor"), - UIManager.getColor("TabbedPane.focusColor"), - UIManager.getColor("TabbedPane.focusColor"), - UIManager.getColor("TabbedPane.focusColor"), - UIManager.getColor("TabbedPane.focusColor"), - UIManager.getColor("TabbedPane.focusColor") + UIManager.getColor(tabbedPaneFocusColorProp), + UIManager.getColor(tabbedPaneFocusColorProp), + UIManager.getColor(tabbedPaneFocusColorProp), + UIManager.getColor(tabbedPaneFocusColorProp), + UIManager.getColor(tabbedPaneFocusColorProp), + UIManager.getColor(tabbedPaneFocusColorProp), + UIManager.getColor(tabbedPaneFocusColorProp) ), - scannerBackgroundColour = UIManager.getColor("Panel.background"), - eyeBackgroundColour = UIManager.getColor("Panel.background") + scannerBackgroundColour = UIManager.getColor(panelBackgroundProp), + eyeBackgroundColour = UIManager.getColor(panelBackgroundProp) ) } val balloonStyle: BalloonTipStyle get() { return EdgedBalloonStyle( - UIManager.getColor("Panel.background"), - UIManager.getColor("TabbedPane.underlineColor") + UIManager.getColor(panelBackgroundProp), + UIManager.getColor(tabbedPaneUnderlineColorProp) ) } val whitespace = "^.*,\\s*\\\\*$".toRegex() @@ -372,7 +393,7 @@ class GuiProps(private val apiProperties: ApiProperties) { private val guiPropertyPrefix = "gui." var currentTheme: FlatLaf = FlatDarkPurpleIJTheme() get() { - val themeClassName = getGuiProperty("theme", FlatDarkPurpleIJTheme().javaClass.name) + val themeClassName = getGuiProperty(themeProp, FlatDarkPurpleIJTheme().javaClass.name) val themeClass = Class.forName(themeClassName) val theme: FlatLaf = themeClass.getDeclaredConstructor().newInstance() as FlatLaf field = theme @@ -388,31 +409,31 @@ class GuiProps(private val apiProperties: ApiProperties) { SwingUtilities.updateComponentTreeUI(frame) } FlatAnimatedLafChange.hideSnapshotWithAnimation() - storeGuiProperty("theme", field.javaClass.name) + storeGuiProperty(themeProp, field.javaClass.name) } - var startFocusEnabled: Boolean = getGuiProperty("focus.start", "false").toBoolean() + var startFocusEnabled: Boolean = getGuiProperty(focusStartProp, falseAsStr).toBoolean() get() { - val prop = getGuiProperty("focus.start", "false") - field = prop == "true" + val prop = getGuiProperty(focusStartProp, falseAsStr) + field = prop == trueAsStr return field } set(value) { field = value - storeGuiProperty("focus.start",value.toString()) + storeGuiProperty(focusStartProp,value.toString()) } - var generationFocusEnabled: Boolean = getGuiProperty("focus.generation", "false").toBoolean() + var generationFocusEnabled: Boolean = getGuiProperty(focusGenerationProp, falseAsStr).toBoolean() get() { - val prop = getGuiProperty("focus.generation", "false") - field = prop == "true" + val prop = getGuiProperty(focusGenerationProp, falseAsStr) + field = prop == trueAsStr return field } set(value) { field = value - storeGuiProperty("focus.generation",value.toString()) + storeGuiProperty(focusGenerationProp,value.toString()) } - var fontSize: Int = getGuiProperty("font.size","12")!!.toInt() + var fontSize: Int = getGuiProperty(fontSizeProp,"12")!!.toInt() get() { - val prop = getGuiProperty("font.size","12") + val prop = getGuiProperty(fontSizeProp,"12") field = if (prop != null) { return prop.toInt() } else { @@ -422,24 +443,46 @@ class GuiProps(private val apiProperties: ApiProperties) { } set(value) { field = value - storeGuiProperty("font.size",value.toString()) - val currentFont = UIManager.get("defaultFont") as Font - UIManager.put("defaultFont",FontUIResource(currentFont.fontName, currentFont.style, value)) + storeGuiProperty(fontSizeProp,value.toString()) + val currentFont = UIManager.get(defaultFontProp) as Font + UIManager.put(defaultFontProp,FontUIResource(currentFont.fontName, currentFont.style, value)) FlatLaf.updateUI() } - var font: FontUIResource = FontUIResource(getGuiProperty("font.family","JetBrains Mono"),Font.PLAIN,fontSize) + var font: FontUIResource = FontUIResource(getGuiProperty(fontFamilyProp, jetBrainsMono),Font.PLAIN,fontSize) get() { - val prop = FontUIResource(getGuiProperty("font.family","JetBrains Mono"),Font.PLAIN,fontSize) + val prop = FontUIResource(getGuiProperty(fontFamilyProp, jetBrainsMono),Font.PLAIN,fontSize) field = prop return field } set(value) { val font = FontUIResource(value.family,Font.PLAIN,fontSize) field = font - UIManager.put("defaultFont",font) - storeGuiProperty("font.family",font.family) + UIManager.put(defaultFontProp,font) + storeGuiProperty(fontFamilyProp,font.family) FlatLaf.updateUI() } + var viewedTips: TreeSet = TreeSet() + get() { + val prop = getGuiProperty(tipsViewedProp,null) + val viewed = prop?.split(",")?.map { it.toInt() } ?: listOf() + field = TreeSet(viewed) + return field + } + set(value) { + field = value + val prop = field.joinToString(",") { it.toString() } + storeGuiProperty(tipsViewedProp,prop) + } + var showTipOnStartup: Boolean = true + get() { + val prop = getGuiProperty(tipsShowOnStartupProp,"true") + field = prop.toBoolean() + return field + } + set(value) { + field = value + storeGuiProperty(tipsShowOnStartupProp,field.toString()) + } /** * Update the [larsonScanner] and GUI configurations to match the current theme. @@ -447,8 +490,8 @@ class GuiProps(private val apiProperties: ApiProperties) { * @author Griefed */ private fun updateThemeRelatedComponents() { - val panelBackgroundColour = UIManager.getColor("Panel.background") - val tabbedPaneFocusColor = UIManager.getColor("TabbedPane.focusColor") + val panelBackgroundColour = UIManager.getColor(panelBackgroundProp) + val tabbedPaneFocusColor = UIManager.getColor(tabbedPaneFocusColorProp) busyConfig.eyeBackgroundColour = panelBackgroundColour busyConfig.scannerBackgroundColour = panelBackgroundColour idleConfig.eyeBackgroundColour = panelBackgroundColour @@ -486,9 +529,9 @@ class GuiProps(private val apiProperties: ApiProperties) { * @author Griefed */ fun initFont() { - val value = getGuiProperty("font.size","12")!!.toInt() - val currentFont = UIManager.get("defaultFont") as Font - UIManager.put("defaultFont",FontUIResource(currentFont.fontName, currentFont.style, value)) + val value = getGuiProperty(fontSizeProp,"12")!!.toInt() + val currentFont = UIManager.get(defaultFontProp) as Font + UIManager.put(defaultFontProp,FontUIResource(currentFont.fontName, currentFont.style, value)) FlatLaf.updateUI() } } \ No newline at end of file diff --git a/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/utilities/ImageUtilities.kt b/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/utilities/ImageUtilities.kt index a15414b12..b17774c27 100644 --- a/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/utilities/ImageUtilities.kt +++ b/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/utilities/ImageUtilities.kt @@ -21,6 +21,7 @@ package de.griefed.serverpackcreator.gui.utilities +import java.awt.Dimension import java.awt.Image import java.util.* import javax.imageio.ImageIO @@ -80,4 +81,39 @@ class ImageUtilities { */ fun ImageIcon.getScaledInstance(width: Int, height: Int, scaling: Int = Image.SCALE_SMOOTH): ImageIcon { return ImageIcon(this.image.getScaledInstance(width, height, scaling)) +} + +/** + * Scale the image, keeping the aspect ratio, to the given [size]. By default, the width of the image will be changed to + * the desired [size]. If you want to change the height of the image to the desired [size], then set [scaleBy] to [ScaleBy.HEIGHT]. + * + * @author Griefed + */ +fun ImageIcon.getAspectRatioScaledInstsance(size: Int, scaleBy: ScaleBy = ScaleBy.WIDTH, scaling: Int = Image.SCALE_SMOOTH): ImageIcon { + val imgSize = Dimension(iconWidth, iconHeight) + val widthRatio: Double + val heightRatio: Double + var newHeight = iconHeight + var newWidth = iconWidth + when (scaleBy) { + ScaleBy.WIDTH -> { + newWidth = size + widthRatio = size.toDouble() / imgSize.width + newHeight = (iconHeight * widthRatio).toInt() + } + ScaleBy.HEIGHT -> { + newHeight = size + heightRatio = size.toDouble() / imgSize.height + newWidth = (iconHeight * heightRatio).toInt() + } + } + return getScaledInstance(newWidth,newHeight,scaling) +} + +/** + * @author Griefed + */ +enum class ScaleBy { + WIDTH, + HEIGHT } \ No newline at end of file diff --git a/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/MainFrame.kt b/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/MainFrame.kt index c33a28e15..a840a8c73 100644 --- a/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/MainFrame.kt +++ b/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/MainFrame.kt @@ -23,6 +23,7 @@ import Gui import de.griefed.serverpackcreator.api.ApiWrapper import de.griefed.serverpackcreator.gui.GuiProps import de.griefed.serverpackcreator.gui.window.menu.MainMenuBar +import de.griefed.serverpackcreator.gui.window.tips.TipOfTheDayManager import de.griefed.serverpackcreator.updater.MigrationManager import de.griefed.serverpackcreator.updater.UpdateChecker import java.awt.Dimension @@ -30,6 +31,8 @@ import java.awt.event.WindowAdapter import java.awt.event.WindowEvent import javax.swing.JFrame import javax.swing.WindowConstants +import javax.swing.event.HyperlinkEvent +import javax.swing.event.HyperlinkListener /** * Main Frame of ServerPackCreator, housing [MainPanel], [MainMenuBar]. @@ -77,6 +80,9 @@ class MainFrame( toFront() } menu.displayMigrationMessages() + if (guiProps.showTipOnStartup) { + menu.showTip() + } } /** diff --git a/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/menu/MainMenuBar.kt b/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/menu/MainMenuBar.kt index a1364ab14..4694487ea 100644 --- a/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/menu/MainMenuBar.kt +++ b/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/menu/MainMenuBar.kt @@ -63,11 +63,17 @@ class MainMenuBar( menuBar.add(updateButton) } - /** * @author Griefed */ fun displayMigrationMessages() { about.displayMigrationMessages() } + + /** + * @author Griefed + */ + fun showTip() { + about.showTip() + } } \ No newline at end of file diff --git a/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/menu/about/AboutMenu.kt b/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/menu/about/AboutMenu.kt index 1b4f3aa97..574f7b54c 100644 --- a/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/menu/about/AboutMenu.kt +++ b/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/menu/about/AboutMenu.kt @@ -56,6 +56,7 @@ class AboutMenu( private val discord = DiscordItem(webUtilities) private val donate = DonationsItem(webUtilities) private val thirdparty = ThirdPartyNoticesItem(mainFrame,guiProps) + private val tipOfTheDayItem = TipOfTheDayItem(guiProps, mainFrame) init { add(update) @@ -73,6 +74,8 @@ class AboutMenu( add(donate) add(JSeparator()) add(thirdparty) + add(JSeparator()) + add(tipOfTheDayItem) } /** @@ -81,4 +84,11 @@ class AboutMenu( fun displayMigrationMessages() { migration.displayMigrationMessages() } + + /** + * @author Griefed + */ + fun showTip() { + tipOfTheDayItem.showTip() + } } \ No newline at end of file diff --git a/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/menu/about/TipOfTheDayItem.kt b/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/menu/about/TipOfTheDayItem.kt new file mode 100644 index 000000000..c61a88c5f --- /dev/null +++ b/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/menu/about/TipOfTheDayItem.kt @@ -0,0 +1,46 @@ +/* Copyright (C) 2023 Griefed + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * The full license can be found at https:github.com/Griefed/ServerPackCreator/blob/main/LICENSE + */ +package de.griefed.serverpackcreator.gui.window.menu.about + +import de.griefed.serverpackcreator.gui.GuiProps +import de.griefed.serverpackcreator.gui.window.MainFrame +import de.griefed.serverpackcreator.gui.window.tips.TipOfTheDayManager +import javax.swing.JMenuItem + +/** + * Menuitem to display the tip of the day. + * + * @author Griefed + */ +class TipOfTheDayItem(guiProps: GuiProps, mainFrame: MainFrame): JMenuItem(Gui.menubar_gui_menuitem_tipoftheday.toString()) { + + private val tipManager = TipOfTheDayManager(mainFrame.frame,guiProps) + + init { + this.addActionListener { showTip() } + } + + /** + * @author Griefed + */ + fun showTip() { + tipManager.showTipOfTheDay() + } +} \ No newline at end of file diff --git a/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/tips/CustomTip.kt b/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/tips/CustomTip.kt new file mode 100644 index 000000000..bbe00fbbb --- /dev/null +++ b/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/tips/CustomTip.kt @@ -0,0 +1,36 @@ +/* Copyright (C) 2023 Griefed + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * The full license can be found at https:github.com/Griefed/ServerPackCreator/blob/main/LICENSE + */ +package de.griefed.serverpackcreator.gui.window.tips + +import tokyo.northside.swing.tips.DefaultTip +import javax.swing.ImageIcon + +/** + * @author Griefed + */ +class CustomTip(name: String, tip: Any, private val imageResource: String): DefaultTip(name,tip) { + fun getImage(): ImageIcon? { + return try { + ImageIcon(this.javaClass.getResource(imageResource)) + } catch (_: Exception) { + null + } + } +} \ No newline at end of file diff --git a/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/tips/CustomTipOfTheDayUI.kt b/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/tips/CustomTipOfTheDayUI.kt new file mode 100644 index 000000000..3e84eeaed --- /dev/null +++ b/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/tips/CustomTipOfTheDayUI.kt @@ -0,0 +1,303 @@ +/* Copyright (C) 2023 Griefed + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * The full license can be found at https:github.com/Griefed/ServerPackCreator/blob/main/LICENSE + */ +package de.griefed.serverpackcreator.gui.window.tips + +import Gui +import de.griefed.serverpackcreator.gui.GuiProps +import de.griefed.serverpackcreator.gui.utilities.getAspectRatioScaledInstsance +import io.ktor.util.reflect.* +import tokyo.northside.swing.TipOfTheDay +import tokyo.northside.swing.plaf.DefaultTipOfTheDayUI +import java.awt.* +import java.awt.event.* +import java.util.* +import javax.swing.* +import javax.swing.plaf.BorderUIResource +import javax.swing.plaf.FontUIResource +import javax.swing.plaf.basic.BasicHTML + +/** + * Custom UI for the tip of the day dialog to assure it always resembles the current theme. + * + * @author Griefed + */ +class CustomTipOfTheDayUI(tipOfTheDay: TipOfTheDay, private val guiProps: GuiProps) : + DefaultTipOfTheDayUI(tipOfTheDay) { + + private val tipImage = JLabel() + private val preferredDimension = Dimension(600,350) + private val defaultSize = Dimension(500,350) + + /** + * @author Griefed + */ + override fun installDefaults(defaults: UIDefaults) { + super.installDefaults(defaults) + tipPane.background = UIManager.getColor("Panel.background") + tipPane.foreground = UIManager.getColor("Panel.foreground") + tipPane.font = guiProps.font + tipFont = guiProps.font.deriveFont(Font.BOLD) + UIManager.put("TipOfTheDay.dialogTitle", Gui.tips_title.toString()) + UIManager.put("TipOfTheDay.showOnStartupText", Gui.tips_show.toString()) + } + + /** + * @author Griefed + */ + override fun installComponents(defaults: UIDefaults) { + super.installComponents() + val tipIcon = JLabel(Gui.tips_know.toString()) + tipIcon.setIcon(guiProps.fancyInfoIcon) + tipIcon.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2)) + tipIcon.font = guiProps.font.deriveFont(Font.BOLD, (guiProps.fontSize + 5).toFloat()) + tipPane.add("North", tipIcon) + } + + /** + * @author Griefed + */ + override fun addUIDefaults(defaults: UIDefaults) { + super.addUIDefaults(defaults) + val font = guiProps.font.deriveFont(Font.BOLD, (guiProps.fontSize + 3).toFloat()) + val tipOfTheDayFont = guiProps.font + defaults["TipOfTheDay.font"] = tipOfTheDayFont + defaults["TipOfTheDay.tipFont"] = FontUIResource(font) + defaults["TipOfTheDay.background"] = UIManager.getColor("Panel.background") + defaults["TipOfTheDay.border"] = + BorderUIResource(BorderFactory.createLineBorder(UIManager.getColor("Component.borderColor"))) + } + + /** + * Customized dialog based on [tokyo.northside.swing.plaf.BasicTipOfTheDayUI.createDialog] + * + * @author Griefed + */ + override fun createDialog(parentComponent: Component, choice: TipOfTheDay.ShowOnStartupChoice): JDialog { + val title = Gui.tips_title.toString() + + val dialog: JDialog + + val window: Window = if (parentComponent is Window) { + parentComponent + } else SwingUtilities.getWindowAncestor( + parentComponent + ) + + dialog = if (window is Frame) { + JDialog(window, title, true) + } else { + JDialog(window as Dialog, title, true) + } + + dialog.contentPane.setLayout(BorderLayout(10, 10)) + dialog.contentPane.add(tipPane, BorderLayout.CENTER) + (dialog.contentPane as JComponent).setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)) + + // tip control + val controls = JPanel(BorderLayout()) + dialog.add("South", controls) + + val showOnStartupBox = JCheckBox(Gui.tips_show.toString(), choice.isShowingOnStartup) + controls.add(showOnStartupBox, BorderLayout.CENTER) + + val buttons = JPanel(GridLayout(1, 2, 9, 0)) + controls.add(buttons, BorderLayout.LINE_END) + + val previousTipButton = JButton(Gui.tips_previous.toString()) + buttons.add(previousTipButton) + previousTipButton.addActionListener(PreviousTipAction()) + + val nextTipButton = JButton(Gui.tips_next.toString()) + buttons.add(nextTipButton) + nextTipButton.addActionListener(NextTipAction()) + + val closeButton = JButton(Gui.tips_close.toString()) + buttons.add(closeButton) + + closeButton.addActionListener { + if (dialog.isDisplayable) { + dialog.isVisible = false + } + choice.isShowingOnStartup = showOnStartupBox.isSelected + } + + dialog.rootPane.setDefaultButton(closeButton) + + dialog.addWindowListener(object : WindowAdapter() { + override fun windowClosing(e: WindowEvent) { + choice.isShowingOnStartup = showOnStartupBox.isSelected + } + }) + + val closeAction = ActionListener { _: ActionEvent? -> + if (dialog.isDisplayable) { + dialog.isVisible = false + } + } + + (dialog.contentPane as JComponent).registerKeyboardAction( + closeAction, + KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), + JComponent.WHEN_IN_FOCUSED_WINDOW + ) + + dialog.isResizable = false + dialog.pack() + dialog.setLocationRelativeTo(parentComponent) + updatePreferredSize() + dialog.size = preferredDimension + dialog.preferredSize = preferredDimension + return dialog + } + + /** + * Customized tip-update based on [tokyo.northside.swing.plaf.BasicTipOfTheDayUI.showCurrentTip] + * + * @author Griefed + */ + override fun showCurrentTip() { + if (currentTipComponent != null) { + tipArea.remove(currentTipComponent) + } + + val currentTip = tipPane.currentTip + if (currentTip == -1) { + val label = JLabel() + label.setOpaque(true) + label.setBackground(UIManager.getColor("TextArea.background")) + currentTipComponent = label + tipArea.add("Center", currentTipComponent) + updateImage(currentTip) + return + } + + // tip does not fall in current tip range + if (tipPane.model == null || tipPane.model.tipCount == 0 || currentTip < 0 && currentTip >= tipPane.model.tipCount) { + currentTipComponent = JLabel() + } else { + val tip = tipPane.model.getTipAt(currentTip) + val tipObject = tip.tip + val tipScroll = JScrollPane() + tipScroll.setBorder(null) + tipScroll.setOpaque(false) + tipScroll.viewport.setOpaque(false) + tipScroll.setBorder(null) + val text = tipObject?.toString() ?: "" + val editor = JEditorPane("text/html", text) + editor.setFont(tipPane.font) + BasicHTML.updateRenderer(editor, text) + editor.isEditable = false + editor.setBorder(null) + editor.setMargin(null) + editor.setOpaque(false) + editor.setFont(tipFont) + tipScroll.viewport.setView(editor) + + currentTipComponent = tipScroll + } + + updateImage(currentTip) + + tipArea.add("Center", currentTipComponent) + tipArea.revalidate() + tipArea.repaint() + } + + /** + * @author Griefed + */ + private fun updateImage(currentTip: Int) { + if ((tipPane.model.getTipAt(currentTip) as CustomTip).getImage() != null) { + tipImage.icon = (tipPane.model.getTipAt(currentTip) as CustomTip).getImage()!!.getAspectRatioScaledInstsance(800) + tipArea.add("East",tipImage) + } else { + tipImage.icon = null + tipArea.remove(tipImage) + } + } + + /** + * @author Griefed + */ + private fun updatePreferredSize() { + if (tipImage.icon == null) { + preferredDimension.width = defaultSize.width + preferredDimension.height = defaultSize.height + } else { + if (defaultSize.width <= (defaultSize.width + tipImage.icon.iconWidth)) { + preferredDimension.width = defaultSize.width + tipImage.icon.iconWidth + } + if (defaultSize.height <= ((defaultSize.height / 2) + tipImage.icon.iconHeight)) { + preferredDimension.height = (defaultSize.height / 2) + tipImage.icon.iconHeight + } + } + try { + var parent = tipArea.parent + while(!parent.instanceOf(JDialog::class)) { + parent = parent.parent + } + parent.size = preferredDimension + parent.preferredSize = preferredDimension + } catch (_: NullPointerException) {} + } + + /** + * @author Griefed + */ + private fun updateViewedTips() { + val newViewed = TreeSet(guiProps.viewedTips) + newViewed.add(tipPane.currentTip) + guiProps.viewedTips = newViewed + } + + /** + * See [tokyo.northside.swing.plaf.BasicTipOfTheDayUI.PreviousTipAction] + * @author Frederic Lavigne + * @author Hiroshi Miura + */ + inner class PreviousTipAction : AbstractAction("previousTip") { + override fun actionPerformed(e: ActionEvent) { + tipPane.previousTip() + updateViewedTips() + updatePreferredSize() + } + + override fun isEnabled(): Boolean { + return tipPane.isEnabled + } + } + + /** + * See [tokyo.northside.swing.plaf.BasicTipOfTheDayUI.NextTipAction] + * @author Frederic Lavigne + * @author Hiroshi Miura + */ + inner class NextTipAction : AbstractAction("nextTip") { + override fun actionPerformed(e: ActionEvent) { + tipPane.nextTip() + updateViewedTips() + updatePreferredSize() + } + + override fun isEnabled(): Boolean { + return tipPane.isEnabled + } + } +} \ No newline at end of file diff --git a/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/tips/TipOfTheDayManager.kt b/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/tips/TipOfTheDayManager.kt new file mode 100644 index 000000000..24058b8a8 --- /dev/null +++ b/serverpackcreator-gui/src/main/kotlin/de/griefed/serverpackcreator/gui/window/tips/TipOfTheDayManager.kt @@ -0,0 +1,110 @@ +/* Copyright (C) 2023 Griefed + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + * USA + * + * The full license can be found at https:github.com/Griefed/ServerPackCreator/blob/main/LICENSE + */ +package de.griefed.serverpackcreator.gui.window.tips + +import Gui +import de.griefed.serverpackcreator.gui.GuiProps +import kotlinx.coroutines.DelicateCoroutinesApi +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch +import kotlinx.coroutines.swing.Swing +import tokyo.northside.swing.TipOfTheDay +import tokyo.northside.swing.TipOfTheDay.ShowOnStartupChoice +import tokyo.northside.swing.tips.DefaultTip +import tokyo.northside.swing.tips.DefaultTipOfTheDayModel +import tokyo.northside.swing.tips.Tip +import java.util.* +import javax.swing.JFrame +import kotlin.reflect.full.memberProperties + +/** + * Tip of the day manager which creates and stores all tips ready for display. + * + * @author Griefed + */ +class TipOfTheDayManager(private val mainFrame: JFrame, private val guiProps: GuiProps) { + + private val showOnStartupChoice = ShowOnStartup() + private val tipOfTheDayModel = DefaultTipOfTheDayModel() + + init { + val memberProperties = Gui::class.memberProperties.filter { it.name.matches("tip_\\d+_name".toRegex()) } + for (memberProp in memberProperties) { + val number = memberProp.name + .replace("tip_", "") + .replace("_name", "") + val name = memberProp.get(Gui).toString() + val value = Gui::class.memberProperties + .find { it.name == "tip_${number}_content" } + ?.get(Gui)?.toString() + ?: "Could not retrieve tip for ${memberProp.name}." + tipOfTheDayModel.add(CustomTip(name, value,"/de/griefed/resources/gui/tip$number.png")) + } + } + + /** + * @author Griefed + */ + private fun createTip(name: String, tip: Any): Tip { + return DefaultTip.of(name, tip) + } + + /** + * @author Griefed + */ + @OptIn(DelicateCoroutinesApi::class) + fun showTipOfTheDay() { + GlobalScope.launch(Dispatchers.Swing) { + var random = (0..