diff --git a/pom.xml b/pom.xml index 4e44f8f..113cb05 100755 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ 4.0.0 com.github.hanseter json-properties-fx - 2.0.4 + 2.0.5 bundle JSON Properties Editor Fx @@ -210,6 +210,12 @@ 21.0.2 test + + io.github.mkpaz + atlantafx-base + 2.0.1 + test + diff --git a/src/main/kotlin/com/github/hanseter/json/editor/JsonPropertiesEditor.kt b/src/main/kotlin/com/github/hanseter/json/editor/JsonPropertiesEditor.kt index 5355eb7..6759162 100755 --- a/src/main/kotlin/com/github/hanseter/json/editor/JsonPropertiesEditor.kt +++ b/src/main/kotlin/com/github/hanseter/json/editor/JsonPropertiesEditor.kt @@ -86,7 +86,7 @@ class JsonPropertiesEditor @JvmOverloads constructor( ) columns.addAll(keyColumn, createControlColumn(), createActionColumn()) isShowRoot = false - columnResizePolicy = TreeTableView.CONSTRAINED_RESIZE_POLICY + columnResizePolicy = TreeTableView.CONSTRAINED_RESIZE_POLICY_FLEX_NEXT_COLUMN root = rootItem this.selectionModel.isCellSelectionEnabled = true TreeTableNavigation.addNavigationToTreeTableView(this) @@ -349,6 +349,7 @@ class JsonPropertiesEditor @JvmOverloads constructor( cellValueFactory = Callback { it.value.valueProperty() } cellFactory = Callback { ValueCell() } minWidth = 150.0 + prefWidth = USE_COMPUTED_SIZE styleClass.add("control-cell") isSortable = false } diff --git a/src/main/kotlin/com/github/hanseter/json/editor/ui/PropertiesEditorToolbar.kt b/src/main/kotlin/com/github/hanseter/json/editor/ui/PropertiesEditorToolbar.kt index 44638d1..5e01187 100755 --- a/src/main/kotlin/com/github/hanseter/json/editor/ui/PropertiesEditorToolbar.kt +++ b/src/main/kotlin/com/github/hanseter/json/editor/ui/PropertiesEditorToolbar.kt @@ -5,9 +5,9 @@ import javafx.scene.control.Button import javafx.scene.control.ContextMenu import javafx.scene.control.Label import javafx.scene.control.MenuItem +import javafx.scene.control.TextField import javafx.scene.layout.HBox import javafx.scene.layout.Priority -import org.controlsfx.control.textfield.TextFields class PropertiesEditorToolbar( private val editor: JsonPropertiesEditor @@ -20,7 +20,7 @@ class PropertiesEditorToolbar( val additionalOptions = ArrayList() - private val filterText = TextFields.createClearableTextField().apply { + private val filterText = TextField().apply { id = "searchField" promptText = "" textProperty().addListener { _ -> diff --git a/src/main/kotlin/com/github/hanseter/json/editor/ui/TreeTableNavigation.kt b/src/main/kotlin/com/github/hanseter/json/editor/ui/TreeTableNavigation.kt index f5d4ee9..6a41282 100644 --- a/src/main/kotlin/com/github/hanseter/json/editor/ui/TreeTableNavigation.kt +++ b/src/main/kotlin/com/github/hanseter/json/editor/ui/TreeTableNavigation.kt @@ -7,6 +7,8 @@ package com.github.hanseter.json.editor.ui import javafx.scene.control.TreeItem import javafx.scene.control.TreeTableView +import javafx.scene.control.skin.TreeTableViewSkin +import javafx.scene.control.skin.VirtualFlow import javafx.scene.input.KeyCode import javafx.scene.input.KeyEvent @@ -57,6 +59,10 @@ object TreeTableNavigation { } + private fun TreeTableView<*>.getVirtualFlow() = (this.skin as? TreeTableViewSkin<*>)?.children + ?.filterIsInstance>() + ?.firstOrNull() + private fun TreeTableView<*>.getSelected() = selectionModel.selectedCells.firstOrNull()?.treeItem @@ -95,29 +101,33 @@ object TreeTableNavigation { } } - private fun TreeTableView<*>.scrollToCurrentRow() { - scrollTo(selectionModel.selectedIndex) + private fun TreeTableView<*>.scrollToSelectedRow() { + scrollToRow(selectionModel.selectedIndex) + } + + private fun TreeTableView<*>.scrollToRow(rowIndex:Int) { + getVirtualFlow()?.scrollTo(rowIndex) } private fun TreeTableView<*>.selectFirst() { selectionModel.selectFirst() - scrollToCurrentRow() + scrollToSelectedRow() } private fun TreeTableView<*>.selectLast() { selectionModel.selectLast() - scrollToCurrentRow() + scrollToSelectedRow() } private fun TreeTableView<*>.selectUp() { selectionModel.selectAboveCell() - scrollToCurrentRow() + scrollToSelectedRow() } private fun TreeTableView<*>.selectDown() { selectionModel.selectBelowCell() - scrollToCurrentRow() + scrollToSelectedRow() } private fun TreeTableView<*>.selectLeft() { diff --git a/src/main/resources/com/github/hanseter/json/editor/ui/skins/toggleSwitch.css b/src/main/resources/com/github/hanseter/json/editor/ui/skins/toggleSwitch.css index 1ee369f..edf454c 100644 --- a/src/main/resources/com/github/hanseter/json/editor/ui/skins/toggleSwitch.css +++ b/src/main/resources/com/github/hanseter/json/editor/ui/skins/toggleSwitch.css @@ -3,47 +3,79 @@ * ToggleSwitch * * * ******************************************************************************/ + +.check-box { + -toggle-switch-base-color: #ececec; + -toggle-switch-outer-border: derive(-toggle-switch-base-color, -23%); + -toggle-switch-inner-border: linear-gradient(to bottom, + ladder(-toggle-switch-base-color, + derive(-toggle-switch-base-color, 30%) 0%, + derive(-toggle-switch-base-color, 20%) 40%, + derive(-toggle-switch-base-color, 25%) 60%, + derive(-toggle-switch-base-color, 55%) 80%, + derive(-toggle-switch-base-color, 55%) 90%, + derive(-toggle-switch-base-color, 75%) 100%), + ladder(-toggle-switch-base-color, + derive(-toggle-switch-base-color, 20%) 0%, + derive(-toggle-switch-base-color, 10%) 20%, + derive(-toggle-switch-base-color, 5%) 40%, + derive(-toggle-switch-base-color, -2%) 60%, + derive(-toggle-switch-base-color, -5%) 100%)); + -toggle-switch-body-color: linear-gradient(to bottom, + ladder(-toggle-switch-base-color, + derive(-toggle-switch-base-color, 8%) 75%, + derive(-toggle-switch-base-color, 10%) 80%), + derive(-toggle-switch-base-color, -8%)); + -toggle-switch-focus-color: #039ED3; + -toggle-switch-hover-color: ladder(-toggle-switch-base-color, + derive(-toggle-switch-base-color, 20%) 20%, + derive(-toggle-switch-base-color, 30%) 35%, + derive(-toggle-switch-base-color, 40%) 50%); + -toggle-switch-active-color: #00BEDC; + -toggle-switch-inactive-color: #FE8389; +} + .check-box .thumb { - -fx-background-color: -fx-outer-border, -fx-inner-border, -fx-body-color; + -fx-background-color: -toggle-switch-outer-border, -toggle-switch-inner-border, -toggle-switch-body-color; -fx-background-insets: 0, 1, 2; - -fx-background-radius: 1.0em; /* large value to make sure this remains circular */ + -fx-background-radius: 1.0em;/* large value to make sure this remains circular */ -fx-padding: 0.75em; -fx-alignment: CENTER; -fx-content-display: LEFT; -fx-border-color: transparent; -fx-border-radius: 1em; } -.check-box:hover .thumb{ - -fx-color: -fx-hover-base + +.check-box:hover .thumb { + -fx-color: -toggle-switch-hover-color } -.check-box .thumb-area{ +.check-box .thumb-area { -fx-background-radius: 1em; - -fx-background-color: -fx-outer-border, -fx-inner-border, #FE8389; + -fx-background-color: -toggle-switch-outer-border, -toggle-switch-inner-border, -toggle-switch-inactive-color; -fx-background-insets: 0, 1; - -fx-padding: 0.75em 1.333333em 0.75em 1.333333em; /* 7 16 7 16 */ + -fx-padding: 0.75em 1.333333em 0.75em 1.333333em;/* 7 16 7 16 */ -fx-border-color: transparent; -fx-border-radius: 1em; -fx-border-insets: 0, 1; } -.check-box:selected .thumb-area{ - -fx-background-color: -fx-outer-border, -fx-inner-border,#00bedc +.check-box:selected .thumb-area { + -fx-background-color: -toggle-switch-outer-border, -toggle-switch-inner-border, -toggle-switch-active-color } -.check-box:indeterminate .thumb-area{ - -fx-background-color: -fx-outer-border, -fx-inner-border, #f5f5f5; +.check-box:indeterminate .thumb-area { + -fx-background-color: -toggle-switch-outer-border, -toggle-switch-inner-border, #f5f5f5; } -.check-box:focused .thumb-area{ - -fx-border-color: -fx-focus-color; +.check-box:focused .thumb-area { + -fx-border-color: -toggle-switch-focus-color; } -.check-box:focused .thumb{ - -fx-border-color: -fx-focus-color; +.check-box:focused .thumb { + -fx-border-color: -toggle-switch-focus-color; } -.check-box:disabled -{ +.check-box:disabled { -fx-opacity: 0.4; -} +} \ No newline at end of file diff --git a/src/test/kotlin/com/github/hanseter/json/editor/app/ControlsPreviewTestApp.kt b/src/test/kotlin/com/github/hanseter/json/editor/app/ControlsPreviewTestApp.kt index 6b26b15..305f827 100644 --- a/src/test/kotlin/com/github/hanseter/json/editor/app/ControlsPreviewTestApp.kt +++ b/src/test/kotlin/com/github/hanseter/json/editor/app/ControlsPreviewTestApp.kt @@ -14,30 +14,29 @@ import com.github.hanseter.json.editor.controls.TypeControl import com.github.hanseter.json.editor.extensions.SimpleEffectiveSchema import com.github.hanseter.json.editor.util.* import javafx.application.Application +import javafx.application.Application.launch import javafx.scene.Scene import javafx.scene.control.Label import javafx.scene.control.ScrollPane import javafx.scene.control.SplitPane import javafx.scene.layout.BorderPane import javafx.scene.layout.GridPane +import javafx.scene.layout.HBox import javafx.scene.layout.VBox import javafx.stage.Stage import org.json.JSONObject + +fun main(args: Array) { + launch(ControlsPreviewTestApp::class.java, *args) +} /** * * @author Henrik Frühling (henrik.fruehling@siemens.com) */ class ControlsPreviewTestApp : Application() { - companion object { - @JvmStatic - fun main(args: Array) { - launch(ControlsPreviewTestApp::class.java, *args) - } - } - private val objId = "test" private val previewContainer = GridPane().apply { @@ -70,7 +69,7 @@ class ControlsPreviewTestApp : Application() { selectionModel.selectFirst() } - root.top = schemas + root.top = HBox(5.0,schemas,TestUtils.createThemeComboBox()) root.center = SplitPane(propEdit, VBox(10.0).apply { children.setAll( diff --git a/src/test/kotlin/com/github/hanseter/json/editor/app/JsonPropertiesEditorTestApp.kt b/src/test/kotlin/com/github/hanseter/json/editor/app/JsonPropertiesEditorTestApp.kt index 5572e79..43fc04f 100644 --- a/src/test/kotlin/com/github/hanseter/json/editor/app/JsonPropertiesEditorTestApp.kt +++ b/src/test/kotlin/com/github/hanseter/json/editor/app/JsonPropertiesEditorTestApp.kt @@ -1,5 +1,6 @@ package com.github.hanseter.json.editor.app +import atlantafx.base.theme.* import com.github.hanseter.json.editor.IdReferenceProposalProvider import com.github.hanseter.json.editor.JsonPropertiesEditor import com.github.hanseter.json.editor.ResolutionScopeProvider @@ -13,6 +14,7 @@ import com.github.hanseter.json.editor.util.IdRefDisplayMode import com.github.hanseter.json.editor.util.PropertyGrouping import com.github.hanseter.json.editor.util.ViewOptions import javafx.application.Application +import javafx.collections.FXCollections import javafx.scene.Parent import javafx.scene.Scene import javafx.scene.control.CheckBox @@ -20,12 +22,14 @@ import javafx.scene.control.ComboBox import javafx.scene.layout.HBox import javafx.scene.layout.VBox import javafx.stage.Stage +import javafx.util.StringConverter import org.everit.json.schema.StringSchema import org.json.JSONObject import org.json.JSONTokener import java.net.URI import java.util.stream.Stream + fun main(args: Array) { Application.launch(JsonPropertiesEditorTestApp::class.java, *args) } @@ -70,17 +74,18 @@ class JsonPropertiesEditorTestApp : Application() { private fun buildUi(propEdit: JsonPropertiesEditor): Parent { + val themeComboBox = TestUtils.createThemeComboBox() + val showStars = CheckBox("Show *") - val groupBy = ComboBox().apply { - items.addAll(PropertyGrouping.values()) - selectionModel.select(0) + val groupBy = ComboBox(FXCollections.observableArrayList(PropertyGrouping.entries)).apply { + selectionModel.selectFirst() } - val schemas=TestUtils.createSchemaComboBox().apply { + val schemas = TestUtils.createSchemaComboBox().apply { this.valueProperty().addListener { _, _, newValue -> - if(newValue!=null){ + if (newValue != null) { display(propEdit, newValue, JSONObject()) } } @@ -103,10 +108,11 @@ class JsonPropertiesEditorTestApp : Application() { showStars, groupBy, schemas, - ).apply { spacing=10.0 }, + themeComboBox, + ).apply { spacing = 10.0 }, PropertiesEditorToolbar(propEdit).node, propEdit - ).apply { spacing=10.0 } + ).apply { spacing = 10.0 } } object ReferenceProvider : IdReferenceProposalProvider { diff --git a/src/test/kotlin/com/github/hanseter/json/editor/app/ToggleSwitchTestApp.kt b/src/test/kotlin/com/github/hanseter/json/editor/app/ToggleSwitchTestApp.kt index b28b9e3..b0e95c7 100644 --- a/src/test/kotlin/com/github/hanseter/json/editor/app/ToggleSwitchTestApp.kt +++ b/src/test/kotlin/com/github/hanseter/json/editor/app/ToggleSwitchTestApp.kt @@ -1,5 +1,6 @@ package com.github.hanseter.json.editor.app +import com.github.hanseter.json.editor.base.TestUtils import com.github.hanseter.json.editor.ui.skins.ToggleSwitchSkin import javafx.application.Application import javafx.geometry.Insets @@ -40,6 +41,7 @@ class ToggleSwitchTestApp : Application() { } val root = VBox(16.0, + TestUtils.createThemeComboBox(), switch1, switch2, switch3 ).apply { padding = Insets(32.0) diff --git a/src/test/kotlin/com/github/hanseter/json/editor/base/TestUtils.kt b/src/test/kotlin/com/github/hanseter/json/editor/base/TestUtils.kt index 2424d95..bf06287 100644 --- a/src/test/kotlin/com/github/hanseter/json/editor/base/TestUtils.kt +++ b/src/test/kotlin/com/github/hanseter/json/editor/base/TestUtils.kt @@ -1,5 +1,11 @@ package com.github.hanseter.json.editor.base +import atlantafx.base.theme.* +import javafx.application.Application +import javafx.application.Application.setUserAgentStylesheet +import javafx.collections.FXCollections +import javafx.scene.control.ComboBox +import javafx.util.StringConverter import org.controlsfx.control.SearchableComboBox import org.json.JSONObject import org.json.JSONTokener @@ -24,6 +30,40 @@ object TestUtils { items.addAll(getAllSchemas()) } + fun createThemeComboBox(): ComboBox { + val themeComboBox = ComboBox( + FXCollections.observableArrayList( + null, + PrimerLight(), + CupertinoLight(), + NordLight(), + PrimerDark(), + CupertinoDark(), + NordDark(), + Dracula(), + ) + ).apply { + converter = object : StringConverter() { + override fun toString(theme: Theme?): String { + return theme?.name ?: Application.STYLESHEET_MODENA + } + + override fun fromString(string: String?): Theme? { + TODO("Not yet implemented") + } + } + selectionModel.selectedItemProperty().addListener { _, _, new -> + if (new != null) { + setUserAgentStylesheet(new.userAgentStylesheet) + } else { + setUserAgentStylesheet(null) + } + + } + } + return themeComboBox + } + fun waitForAsyncFx(callback: () -> T): T? { var ret: T? = null WaitForAsyncUtils.asyncFx { ret = callback() }