diff --git a/src/main/kotlin/com/spoiligaming/generator/gui/TabContainer.kt b/src/main/kotlin/com/spoiligaming/generator/gui/TabContainer.kt index ecb9749..40260d3 100644 --- a/src/main/kotlin/com/spoiligaming/generator/gui/TabContainer.kt +++ b/src/main/kotlin/com/spoiligaming/generator/gui/TabContainer.kt @@ -11,9 +11,11 @@ import javafx.scene.layout.Background import javafx.scene.layout.BackgroundFill import javafx.scene.layout.CornerRadii import javafx.scene.layout.GridPane +import javafx.scene.layout.HBox import javafx.scene.layout.Region import javafx.scene.layout.VBox import javafx.scene.paint.Color +import javafx.scene.shape.SVGPath class TabContainer : GridPane() { companion object { @@ -49,8 +51,14 @@ class TabContainer : GridPane() { private fun implementTabBox() { val tabs = - listOf("General", "Proxy", "Fortification", "Advanced", "Visuals", "Console").mapIndexed { index, labelText -> - createTab(labelText, index) + listOf( + "General" to "M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z", // Home icon + "Proxy" to "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-1 17.93c-3.95-.49-7-3.85-7-7.93 0-.62.08-1.21.21-1.79L9 15v1c0 1.1.9 2 2 2v1.93zm6.9-2.54c-.26-.81-1-1.39-1.9-1.39h-1v-3c0-.55-.45-1-1-1H8v-2h2c.55 0 1-.45 1-1V7h2c1.1 0 2-.9 2-2v-.41c2.93 1.19 5 4.06 5 7.41 0 2.08-.8 3.97-2.1 5.39z", // Globe icon + "Fortification" to "M12 1L3 5v6c0 5.55 3.84 10.74 9 12 5.16-1.26 9-6.45 9-12V5l-9-4zm0 10.99h7c-.53 4.12-3.28 7.79-7 8.94V12H5V6.3l7-3.11v8.8z", // Shield icon + "Advanced" to "M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z", // Gear icon + "Visuals" to "M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z", // Eye icon + ).mapIndexed { index, (labelText, svgPath) -> + createTab(labelText, index, svgPath) } fun switchTab(tabNumber: Int) { @@ -93,6 +101,7 @@ class TabContainer : GridPane() { private fun createTab( labelText: String, tabNumber: Int, + svgPath: String ): VBox = VBox().apply { setMaxSize(145.0, 35.0) @@ -110,14 +119,25 @@ class TabContainer : GridPane() { } children.add( - Label(labelText).apply { - style = - "-fx-text-fill: ${ColorPalette.textColor}; -fx-font-family: '${ResourceHandler.comfortaaBold.family}'; -fx-font-size: 14;" + HBox().apply { setMaxSize(145.0, 35.0) setMinSize(145.0, 35.0) alignment = Pos.CENTER_LEFT - padding = Insets(0.0, 0.0, 0.0, 20.0) - }, + padding = Insets(0.0, 0.0, 0.0, 10.0) + spacing = 10.0 + + children.addAll( + SVGPath().apply { + content = svgPath + fill = Color.web(ColorPalette.textColor) + maxWidth(16.0) + maxHeight(16.0) + }, + Label(labelText).apply { + style = "-fx-text-fill: ${ColorPalette.textColor}; -fx-font-family: '${ResourceHandler.comfortaaBold.family}'; -fx-font-size: 14;" + } + ) + } ) } diff --git a/src/main/kotlin/com/spoiligaming/generator/gui/element/ElementBoolean.kt b/src/main/kotlin/com/spoiligaming/generator/gui/element/ElementBoolean.kt index 70c654f..27961d6 100644 --- a/src/main/kotlin/com/spoiligaming/generator/gui/element/ElementBoolean.kt +++ b/src/main/kotlin/com/spoiligaming/generator/gui/element/ElementBoolean.kt @@ -1,12 +1,16 @@ package com.spoiligaming.generator.gui.element import com.spoiligaming.generator.gui.ColorPalette -import com.spoiligaming.generator.gui.ResourceHandler +import javafx.animation.TranslateTransition import javafx.geometry.Insets import javafx.geometry.Pos import javafx.scene.Cursor -import javafx.scene.control.CheckBox import javafx.scene.layout.HBox +import javafx.scene.layout.StackPane +import javafx.scene.paint.Color +import javafx.scene.shape.Circle +import javafx.scene.shape.Rectangle +import javafx.util.Duration object ElementBoolean { fun addBooleanValue( @@ -18,27 +22,64 @@ object ElementBoolean { ): HBox = HBox().apply { alignment = Pos.TOP_LEFT - spacing = 5.0 + spacing = 10.0 this.padding = padding children.addAll( - CheckBox().apply { - alignment = Pos.CENTER - style = - "-fx-text-fill: ${ColorPalette.accentColor}; -fx-font-family: '${ResourceHandler.comfortaaSemiBold.family}'; -fx-mark-color: ${ColorPalette.accentColor};" - isSelected = initialValue - - setOnMouseEntered { cursor = Cursor.HAND } - setOnMouseExited { cursor = Cursor.DEFAULT } - - selectedProperty().addListener { _, _, newValue -> - valueUpdater(newValue) - } - }, + createToggleSwitch(initialValue, valueUpdater), CommonElement.createLabel(labelText), ) tooltipText?.let { children.add(CommonElement.createTooltip(it)) } } + + private fun createToggleSwitch(initialValue: Boolean, valueUpdater: (Boolean) -> Unit): StackPane { + val width = 50.0 + val height = 20.0 + val thumbSizeMultiplier = 1.2 + + // Background rectangle + val background = Rectangle(width, height).apply { + arcWidth = height + arcHeight = height + style = + "-fx-fill: ${if (initialValue) "-fx-on-color" else "-fx-off-color"};" + } + + // Thumb circle with larger size + val thumbSize = height * thumbSizeMultiplier + val thumb = Circle(thumbSize / 2).apply { + style = """ + -fx-fill: -fx-thumb-color; + -fx-stroke-width: 0; + """ + translateX = if (initialValue) (width - thumbSize) / 2 else -(width - thumbSize) / 2 + } + + val transition = TranslateTransition(Duration.millis(100.0), thumb) + + return StackPane(background, thumb).apply { + cursor = Cursor.HAND + + // custom style variables + style = """ + -fx-on-color: ${ColorPalette.controlColor}; + -fx-off-color: #383839; + -fx-thumb-color: gray; + """ + + setOnMouseClicked { + val newValue = !background.style.contains("-fx-fill: -fx-on-color") + background.style = + "-fx-fill: ${if (newValue) "-fx-on-color" else "-fx-off-color"};" + transition.toX = if (newValue) (width - thumbSize) / 2 else -(width - thumbSize) / 2 + transition.play() + valueUpdater(newValue) + } + + setOnMouseEntered { cursor = Cursor.HAND } + setOnMouseExited { cursor = Cursor.DEFAULT } + } + } } diff --git a/src/main/kotlin/com/spoiligaming/generator/gui/element/ElementValue.kt b/src/main/kotlin/com/spoiligaming/generator/gui/element/ElementValue.kt index 89061d5..d524902 100644 --- a/src/main/kotlin/com/spoiligaming/generator/gui/element/ElementValue.kt +++ b/src/main/kotlin/com/spoiligaming/generator/gui/element/ElementValue.kt @@ -10,11 +10,13 @@ import javafx.geometry.Insets import javafx.geometry.Pos import javafx.scene.Cursor import javafx.scene.control.Button +import javafx.scene.control.Slider import javafx.scene.control.TextField import javafx.scene.input.ContextMenuEvent import javafx.scene.input.KeyCode import javafx.scene.input.MouseButton import javafx.scene.layout.HBox +import javafx.scene.layout.Priority import java.text.DecimalFormat object ElementValue { @@ -33,6 +35,7 @@ object ElementValue { this.padding = padding children.addAll( +// createSlider(property, valueUpdater), // Slider added before text field createTextField(property, valueUpdater), createButton("-", 30.0, 25.0) { updateValue(property, -1, valueUpdater as (Number) -> Unit) }, createButton("+", 30.0, 25.0) { updateValue(property, 1, valueUpdater as (Number) -> Unit) }, @@ -125,6 +128,53 @@ object ElementValue { setOnAction { onClick() } } + private fun createSlider( + property: Any, + valueUpdater: (T) -> Unit + ) = Slider().apply { + min = 0.0 + max = 100.0 + + if (property is SimpleIntegerProperty) { + value = property.get().toDouble() + } else if (property is SimpleLongProperty) { + value = property.get().toDouble() + } + + style = """ + .track { + -fx-background-color: gray; + } + .track:filled { + -fx-background-color: darkgray; + } + .thumb { + -fx-background-color: ${ColorPalette.accentColor}; + } + """.trimIndent() + + isShowTickMarks = false + isShowTickLabels = false + isSnapToTicks = true + + valueProperty().addListener { _, _, newValue -> + if (newValue.toInt() >= 0) { + when (property) { + is SimpleIntegerProperty -> { + property.set(newValue.toInt()) + valueUpdater(newValue as T) + } + is SimpleLongProperty -> { + property.set(newValue.toLong()) + valueUpdater(newValue as T) + } + } + } + } + + HBox.setHgrow(this, Priority.ALWAYS) + } + private fun updateValue( property: Any, increment: Long,