diff --git a/main.go b/main.go index 1518769..2f635ba 100644 --- a/main.go +++ b/main.go @@ -426,6 +426,16 @@ func main() { } var generateBtn *widget.Button errorStates := make(map[string]bool) + var applyingPreset bool + var clearPresetSelection func() + markPresetDirty := func() { + if applyingPreset { + return + } + if clearPresetSelection != nil { + clearPresetSelection() + } + } // ... (other code) @@ -455,6 +465,7 @@ func main() { detailSlider.value.AddListener(binding.NewDataListener(func() { val, _ := detailSlider.value.Get() settings.Detail = val + markPresetDirty() })) roughnessSlider := newNumericInputSlider(0, 100, settings.Roughness, "%.0f%%", "Roughness") @@ -467,6 +478,7 @@ func main() { roughnessSlider.value.AddListener(binding.NewDataListener(func() { val, _ := roughnessSlider.value.Get() settings.Roughness = val + markPresetDirty() })) // Create UI elements for controlling lake generation settings lakesSlider := newNumericInputSlider(0, 15, float64(settings.Lakes), "%.0f", "Lakes") @@ -479,6 +491,7 @@ func main() { lakesSlider.value.AddListener(binding.NewDataListener(func() { val, _ := lakesSlider.value.Get() settings.Lakes = int(val) + markPresetDirty() })) lakeSizeLowerSlider := newNumericInputSlider(1, 100, settings.LakeSizeLower, "%.0f%%", "Min Lake Size") @@ -491,6 +504,7 @@ func main() { lakeSizeLowerSlider.value.AddListener(binding.NewDataListener(func() { val, _ := lakeSizeLowerSlider.value.Get() settings.LakeSizeLower = val + markPresetDirty() })) lakeSizeUpperSlider := newNumericInputSlider(1, 100, settings.LakeSizeUpper, "%.0f%%", "Max Lake Size") @@ -503,6 +517,7 @@ func main() { lakeSizeUpperSlider.value.AddListener(binding.NewDataListener(func() { val, _ := lakeSizeUpperSlider.value.Get() settings.LakeSizeUpper = val + markPresetDirty() })) lakeEdgeRoughnessSlider := newNumericInputSlider(0, 100, settings.LakeEdgeRoughness, "%.0f%%", "Lake Edge Roughness") @@ -515,11 +530,13 @@ func main() { lakeEdgeRoughnessSlider.value.AddListener(binding.NewDataListener(func() { val, _ := lakeEdgeRoughnessSlider.value.Get() settings.LakeEdgeRoughness = val + markPresetDirty() })) lakeShapeLabel := widget.NewLabel("Lake Shape:") lakeShapeSelect := widget.NewSelect([]string{"circle", "oval", "procedural"}, func(s string) { settings.LakeShape = s + markPresetDirty() }) lakeShapeSelect.SetSelected(settings.LakeShape) @@ -533,6 +550,7 @@ func main() { riversSlider.value.AddListener(binding.NewDataListener(func() { val, _ := riversSlider.value.Get() settings.Rivers = int(val) + markPresetDirty() })) minRiverWidthSlider := newNumericInputSlider(1, 100, settings.MinRiverWidth, "%.0f%%", "Min River Width") @@ -545,6 +563,7 @@ func main() { minRiverWidthSlider.value.AddListener(binding.NewDataListener(func() { val, _ := minRiverWidthSlider.value.Get() settings.MinRiverWidth = val + markPresetDirty() })) maxRiverWidthSlider := newNumericInputSlider(1, 100, settings.MaxRiverWidth, "%.0f%%", "Max River Width") @@ -557,6 +576,7 @@ func main() { maxRiverWidthSlider.value.AddListener(binding.NewDataListener(func() { val, _ := maxRiverWidthSlider.value.Get() settings.MaxRiverWidth = val + markPresetDirty() })) riverCurvynessSlider := newNumericInputSlider(0, 100, settings.RiverCurvyness, "%.0f%%", "River Curvyness") @@ -569,6 +589,7 @@ func main() { riverCurvynessSlider.value.AddListener(binding.NewDataListener(func() { val, _ := riverCurvynessSlider.value.Get() settings.RiverCurvyness = val + markPresetDirty() })) riverWidthVariabilitySlider := newNumericInputSlider(0, 100, settings.RiverWidthVariability, "%.0f%%", "River Width Variability") @@ -581,6 +602,7 @@ func main() { riverWidthVariabilitySlider.value.AddListener(binding.NewDataListener(func() { val, _ := riverWidthVariabilitySlider.value.Get() settings.RiverWidthVariability = val + markPresetDirty() })) riverEdgeRoughnessSlider := newNumericInputSlider(0, 100, settings.RiverEdgeRoughness, "%.0f%%", "River Edge Roughness") @@ -593,6 +615,7 @@ func main() { riverEdgeRoughnessSlider.value.AddListener(binding.NewDataListener(func() { val, _ := riverEdgeRoughnessSlider.value.Get() settings.RiverEdgeRoughness = val + markPresetDirty() })) minTreeSizeSlider := newNumericInputSliderWithStep(minTreeSizePercent, maxTreeSizePercent, settings.MinTreeSize, treeSizePercentStep, "%.1f%%", "Min Tree Size") @@ -605,6 +628,7 @@ func main() { minTreeSizeSlider.value.AddListener(binding.NewDataListener(func() { val, _ := minTreeSizeSlider.value.Get() settings.MinTreeSize = val + markPresetDirty() })) maxTreeSizeSlider := newNumericInputSliderWithStep(minTreeSizePercent, maxTreeSizePercent, settings.MaxTreeSize, treeSizePercentStep, "%.1f%%", "Max Tree Size") @@ -617,6 +641,7 @@ func main() { maxTreeSizeSlider.value.AddListener(binding.NewDataListener(func() { val, _ := maxTreeSizeSlider.value.Get() settings.MaxTreeSize = val + markPresetDirty() })) treeCoverageSlider := newNumericInputSlider(1, 100, settings.TreeCoverage, "%.0f%%", "Tree Coverage") @@ -629,6 +654,7 @@ func main() { treeCoverageSlider.value.AddListener(binding.NewDataListener(func() { val, _ := treeCoverageSlider.value.Get() settings.TreeCoverage = val + markPresetDirty() })) treeClumpinessSlider := newNumericInputSlider(0, 100, settings.TreeClumpiness, "%.0f%%", "Tree Clumpiness") @@ -641,6 +667,7 @@ func main() { treeClumpinessSlider.value.AddListener(binding.NewDataListener(func() { val, _ := treeClumpinessSlider.value.Get() settings.TreeClumpiness = val + markPresetDirty() })) minRoadWidthSlider := newNumericInputSliderWithStep(minRoadWidthPercent, maxRoadWidthPercent, settings.MinRoadWidth, roadWidthPercentStep, "%.1f%%", "Min Road Width") minRoadWidthSlider.entry.OnChanged = func(s string) { @@ -652,6 +679,7 @@ func main() { minRoadWidthSlider.value.AddListener(binding.NewDataListener(func() { val, _ := minRoadWidthSlider.value.Get() settings.MinRoadWidth = val + markPresetDirty() })) maxRoadWidthSlider := newNumericInputSliderWithStep(minRoadWidthPercent, maxRoadWidthPercent, settings.MaxRoadWidth, roadWidthPercentStep, "%.1f%%", "Max Road Width") @@ -664,6 +692,7 @@ func main() { maxRoadWidthSlider.value.AddListener(binding.NewDataListener(func() { val, _ := maxRoadWidthSlider.value.Get() settings.MaxRoadWidth = val + markPresetDirty() })) buildingsPerRoadSlider := newNumericInputSlider(1, 20, float64(settings.BuildingsPerRoad), "%.0f", "Buildings Per Road") @@ -676,6 +705,7 @@ func main() { buildingsPerRoadSlider.value.AddListener(binding.NewDataListener(func() { val, _ := buildingsPerRoadSlider.value.Get() settings.BuildingsPerRoad = int(val) + markPresetDirty() })) roadExitsSlider := newNumericInputSlider(0, 100, float64(settings.RoadExits), "%.0f", "Road Exits") @@ -688,6 +718,7 @@ func main() { roadExitsSlider.value.AddListener(binding.NewDataListener(func() { val, _ := roadExitsSlider.value.Get() settings.RoadExits = int(val) + markPresetDirty() })) roadCurvynessSlider := newNumericInputSlider(0, 100, settings.RoadCurvyness, "%.0f%%", "Road Curvyness") @@ -700,6 +731,7 @@ func main() { roadCurvynessSlider.value.AddListener(binding.NewDataListener(func() { val, _ := roadCurvynessSlider.value.Get() settings.RoadCurvyness = val + markPresetDirty() })) roadDistributionSlider := newNumericInputSlider(0, 100, settings.RoadDistribution, "%.0f%%", "Distribution") @@ -712,6 +744,7 @@ func main() { roadDistributionSlider.value.AddListener(binding.NewDataListener(func() { val, _ := roadDistributionSlider.value.Get() settings.RoadDistribution = val + markPresetDirty() })) minRoadAngleSlider := newNumericInputSlider(0, 180, settings.MinRoadAngle, "%.0f°", "Minimum Road Angle") @@ -724,6 +757,7 @@ func main() { minRoadAngleSlider.value.AddListener(binding.NewDataListener(func() { val, _ := minRoadAngleSlider.value.Get() settings.MinRoadAngle = val + markPresetDirty() })) minWallWidthSlider := newNumericInputSliderWithStep(minWallWidthPercent, maxWallWidthPercent, settings.MinWallWidth, wallWidthPercentStep, "%.1f%%", "Min Wall Width") @@ -736,6 +770,7 @@ func main() { minWallWidthSlider.value.AddListener(binding.NewDataListener(func() { val, _ := minWallWidthSlider.value.Get() settings.MinWallWidth = val + markPresetDirty() })) maxWallWidthSlider := newNumericInputSliderWithStep(minWallWidthPercent, maxWallWidthPercent, settings.MaxWallWidth, wallWidthPercentStep, "%.1f%%", "Max Wall Width") @@ -748,6 +783,7 @@ func main() { maxWallWidthSlider.value.AddListener(binding.NewDataListener(func() { val, _ := maxWallWidthSlider.value.Get() settings.MaxWallWidth = val + markPresetDirty() })) numWallsSlider := newNumericInputSlider(0, 5, float64(settings.NumWalls), "%.0f", "Number of Walls") @@ -760,6 +796,7 @@ func main() { numWallsSlider.value.AddListener(binding.NewDataListener(func() { val, _ := numWallsSlider.value.Get() settings.NumWalls = int(val) + markPresetDirty() })) cityCoverageSlider := newNumericInputSlider(1, 100, settings.CityCoverage, "%.0f%%", "City Coverage") @@ -772,6 +809,7 @@ func main() { cityCoverageSlider.value.AddListener(binding.NewDataListener(func() { val, _ := cityCoverageSlider.value.Get() settings.CityCoverage = val + markPresetDirty() })) wallCurvynessSlider := newNumericInputSlider(0, 100, settings.WallCurvyness, "%.0f%%", "Wall Curvyness") @@ -784,10 +822,12 @@ func main() { wallCurvynessSlider.value.AddListener(binding.NewDataListener(func() { val, _ := wallCurvynessSlider.value.Get() settings.WallCurvyness = val + markPresetDirty() })) showTurretsCheck := widget.NewCheck("Show Turrets", func(v bool) { settings.ShowTurrets = v + markPresetDirty() }) showTurretsCheck.SetChecked(settings.ShowTurrets) @@ -801,11 +841,13 @@ func main() { turretSizeSlider.value.AddListener(binding.NewDataListener(func() { val, _ := turretSizeSlider.value.Get() settings.TurretSize = val + markPresetDirty() })) turretShapeLabel := widget.NewLabel("Turret Shape:") turretShapeSelect := widget.NewSelect([]string{"circular", "square"}, func(s string) { settings.TurretShape = s + markPresetDirty() }) turretShapeSelect.SetSelected(settings.TurretShape) @@ -819,6 +861,7 @@ func main() { turretSpacingSlider.value.AddListener(binding.NewDataListener(func() { val, _ := turretSpacingSlider.value.Get() settings.TurretSpacing = val + markPresetDirty() })) gateSpacingSlider := newNumericInputSlider(0, 100, settings.GateSpacing, "%.0f%%", "Gate Spacing") @@ -831,6 +874,7 @@ func main() { gateSpacingSlider.value.AddListener(binding.NewDataListener(func() { val, _ := gateSpacingSlider.value.Get() settings.GateSpacing = val + markPresetDirty() })) turretControls := container.NewVBox( @@ -849,6 +893,7 @@ func main() { } else { turretControls.Hide() } + markPresetDirty() } // Create UI elements for error display and action buttons @@ -1284,6 +1329,7 @@ func main() { numBuildingsSlider.value.AddListener(binding.NewDataListener(func() { val, _ := numBuildingsSlider.value.Get() settings.NumBuildings = int(val) + markPresetDirty() })) minBuildingSizeSlider := newNumericInputSliderWithStep(minBuildingSizePercent, maxBuildingSizePercent, settings.MinBuildingSize, buildingSizePercentStep, "%.1f%%", "Min Building Size") @@ -1296,6 +1342,7 @@ func main() { minBuildingSizeSlider.value.AddListener(binding.NewDataListener(func() { val, _ := minBuildingSizeSlider.value.Get() settings.MinBuildingSize = val + markPresetDirty() })) maxBuildingSizeSlider := newNumericInputSliderWithStep(minBuildingSizePercent, maxBuildingSizePercent, settings.MaxBuildingSize, buildingSizePercentStep, "%.1f%%", "Max Building Size") @@ -1308,6 +1355,7 @@ func main() { maxBuildingSizeSlider.value.AddListener(binding.NewDataListener(func() { val, _ := maxBuildingSizeSlider.value.Get() settings.MaxBuildingSize = val + markPresetDirty() })) buildingDistributionSlider := newNumericInputSlider(0, 100, settings.BuildingDistribution, "%.0f%%", "Building Distribution") @@ -1320,11 +1368,13 @@ func main() { buildingDistributionSlider.value.AddListener(binding.NewDataListener(func() { val, _ := buildingDistributionSlider.value.Get() settings.BuildingDistribution = val + markPresetDirty() })) buildingShapeLabel := widget.NewLabel("Building Shape:") buildingShapeSelect := widget.NewSelect([]string{"squares", "circles", "rectangles", "mixed", "procedural"}, func(s string) { settings.BuildingShape = s + markPresetDirty() }) buildingShapeSelect.SetSelected(settings.BuildingShape) @@ -1360,6 +1410,7 @@ func main() { minBuildingComplexitySlider.value.AddListener(binding.NewDataListener(func() { val, _ := minBuildingComplexitySlider.value.Get() settings.MinBuildingComplexity = int(val) + markPresetDirty() })) maxBuildingComplexitySlider := newNumericInputSlider(1, 6, float64(settings.MaxBuildingComplexity), "%.0f", "Max Building Complexity") @@ -1372,6 +1423,7 @@ func main() { maxBuildingComplexitySlider.value.AddListener(binding.NewDataListener(func() { val, _ := maxBuildingComplexitySlider.value.Get() settings.MaxBuildingComplexity = int(val) + markPresetDirty() })) buildingComplexityRatioSlider := newNumericInputSlider(0, 100, settings.BuildingComplexityRatio, "%.0f%%", "Building Complexity Ratio") @@ -1384,6 +1436,7 @@ func main() { buildingComplexityRatioSlider.value.AddListener(binding.NewDataListener(func() { val, _ := buildingComplexityRatioSlider.value.Get() settings.BuildingComplexityRatio = val + markPresetDirty() })) proceduralContainer := container.NewVBox( @@ -1430,6 +1483,7 @@ func main() { } updateRatioSliders() + markPresetDirty() } circleRatioSlider.OnChanged = func(val float64) { @@ -1460,6 +1514,7 @@ func main() { } updateRatioSliders() + markPresetDirty() } rectangleRatioSlider.OnChanged = func(val float64) { @@ -1491,6 +1546,7 @@ func main() { } updateRatioSliders() + markPresetDirty() } buildingShapeSelect.OnChanged = func(s string) { @@ -1505,6 +1561,7 @@ func main() { proceduralContainer.Hide() ratioContainer.Hide() } + markPresetDirty() } // Initial visibility check if settings.BuildingShape == "mixed" { @@ -1612,15 +1669,27 @@ func main() { if !ok { return } + applyingPreset = true imported, err := loadEmbeddedPreset(path) if err != nil { + applyingPreset = false dialog.ShowError(err, w) return } imported.Seed = settings.Seed applySettingsToUI(imported) + time.AfterFunc(50*time.Millisecond, func() { + fyne.Do(func() { + applyingPreset = false + }) + }) }) presetSelect.SetSelected("No Preset") + clearPresetSelection = func() { + if presetSelect.Selected != "No Preset" { + presetSelect.SetSelected("No Preset") + } + } buildingsTab := container.NewTabItem("Buildings", container.NewVBox( numBuildingsSlider,