@@ -126,6 +126,10 @@ class ConfigSheetController: NSObject {
126126 private var skipIntroCheckbox : NSButton !
127127 private var loopsCheckbox : NSButton !
128128
129+ // Custom colors
130+ private var paletteTextField : NSTextField !
131+ private var stripeColorsTextField : NSTextField !
132+
129133 // URL preview
130134 private var urlPreviewField : NSTextField !
131135 private var currentURLString : String = " https://rezmason.github.io/matrix/ "
@@ -576,6 +580,14 @@ class ConfigSheetController: NSObject {
576580 self . effectPopup = popup
577581 }
578582
583+ y = addTextFieldRow ( to: view, y: y, label: " Palette (RGB): " , placeholder: " r,g,b,pos,r,g,b,pos,... " ) { textField in
584+ self . paletteTextField = textField
585+ }
586+
587+ y = addTextFieldRow ( to: view, y: y, label: " Stripe Colors (RGB): " , placeholder: " r,g,b,r,g,b,... " ) { textField in
588+ self . stripeColorsTextField = textField
589+ }
590+
579591 y = addSliderRow ( to: view, y: y, label: " Bloom Strength: " , min: 0.0 , max: 1.0 , value: 0.7 ) { slider, label in
580592 self . bloomStrengthSlider = slider
581593 self . bloomStrengthLabel = label
@@ -697,6 +709,24 @@ class ConfigSheetController: NSObject {
697709 return y - 36
698710 }
699711
712+ private func addTextFieldRow( to view: NSView , y: CGFloat , label: String , placeholder: String , configure: ( NSTextField ) -> Void ) -> CGFloat {
713+ let labelField = NSTextField ( labelWithString: label)
714+ labelField. frame = NSRect ( x: 20 , y: y, width: 150 , height: 20 )
715+ labelField. alignment = . right
716+ view. addSubview ( labelField)
717+
718+ let textField = NSTextField ( frame: NSRect ( x: 180 , y: y - 2 , width: 340 , height: 22 ) )
719+ textField. placeholderString = placeholder
720+ textField. font = NSFont . monospacedSystemFont ( ofSize: 11 , weight: . regular)
721+ textField. target = self
722+ textField. action = #selector( controlChanged)
723+ view. addSubview ( textField)
724+
725+ configure ( textField)
726+
727+ return y - 32
728+ }
729+
700730 // MARK: - Actions
701731
702732 @objc private func perMonitorChanged( ) {
@@ -763,9 +793,10 @@ class ConfigSheetController: NSObject {
763793 " glyphRotation " , " slant " , " volumetric " , " isometric " , " isPolar " , " baseTexture " , " glintTexture " ,
764794 " backgroundColor " , " cursorColor " , " glintColor " , " cursorIntensity " , " glintIntensity " ,
765795 " isolateCursor " , " isolateGlint " , " baseBrightness " , " baseContrast " , " glintBrightness " ,
766- " glintContrast " , " brightnessOverride " , " brightnessThreshold " , " effect " , " bloomStrength " ,
767- " bloomSize " , " highPassThreshold " , " ditherMagnitude " , " hasThunder " , " rippleTypeName " ,
768- " rippleScale " , " rippleThickness " , " rippleSpeed " , " renderer " , " useHalfFloat " , " skipIntro " , " loops "
796+ " glintContrast " , " brightnessOverride " , " brightnessThreshold " , " effect " , " paletteData " ,
797+ " stripeColors " , " bloomStrength " , " bloomSize " , " highPassThreshold " , " ditherMagnitude " ,
798+ " hasThunder " , " rippleTypeName " , " rippleScale " , " rippleThickness " , " rippleSpeed " ,
799+ " renderer " , " useHalfFloat " , " skipIntro " , " loops "
769800 ]
770801
771802 for targetScreenID in allScreenIDs {
@@ -894,6 +925,10 @@ class ConfigSheetController: NSObject {
894925 skipIntroCheckbox. state = . on
895926 loopsCheckbox. state = . off
896927
928+ // Custom colors
929+ paletteTextField. stringValue = " "
930+ stripeColorsTextField. stringValue = " "
931+
897932 updateURLPreview ( )
898933 }
899934
@@ -1115,6 +1150,10 @@ class ConfigSheetController: NSObject {
11151150 rippleSpeedSlider. doubleValue = getCachedDouble ( " rippleSpeed " , screen: screen, default: 0.2 )
11161151 rippleSpeedLabel. stringValue = String ( format: " %.2f " , rippleSpeedSlider. doubleValue)
11171152
1153+ // Custom colors
1154+ paletteTextField. stringValue = getCachedString ( " paletteData " , screen: screen, default: " " )
1155+ stripeColorsTextField. stringValue = getCachedString ( " stripeColors " , screen: screen, default: " " )
1156+
11181157 // Advanced
11191158 rendererPopup. selectItem ( withTitle: getCachedString ( " renderer " , screen: screen, default: " regl " ) )
11201159 useHalfFloatCheckbox. state = getCachedBool ( " useHalfFloat " , screen: screen, default: false ) ? . on : . off
@@ -1187,6 +1226,10 @@ class ConfigSheetController: NSObject {
11871226 setCached ( rippleThicknessSlider. doubleValue, forKey: " rippleThickness " , screen: screen)
11881227 setCached ( rippleSpeedSlider. doubleValue, forKey: " rippleSpeed " , screen: screen)
11891228
1229+ // Custom colors
1230+ setCached ( paletteTextField. stringValue, forKey: " paletteData " , screen: screen)
1231+ setCached ( stripeColorsTextField. stringValue, forKey: " stripeColors " , screen: screen)
1232+
11901233 // Advanced
11911234 setCached ( rendererPopup. titleOfSelectedItem ?? " regl " , forKey: " renderer " , screen: screen)
11921235 setCached ( useHalfFloatCheckbox. state == . on, forKey: " useHalfFloat " , screen: screen)
@@ -1292,6 +1335,17 @@ class ConfigSheetController: NSObject {
12921335
12931336 // Effects
12941337 addString ( " effect " , value: effectPopup. titleOfSelectedItem, defaultValue: " palette " )
1338+
1339+ // Custom palette and stripe colors (only add if non-empty)
1340+ let paletteValue = paletteTextField. stringValue. trimmingCharacters ( in: . whitespaces)
1341+ if !paletteValue. isEmpty {
1342+ items. append ( URLQueryItem ( name: " palette " , value: paletteValue) )
1343+ }
1344+ let stripeColorsValue = stripeColorsTextField. stringValue. trimmingCharacters ( in: . whitespaces)
1345+ if !stripeColorsValue. isEmpty {
1346+ items. append ( URLQueryItem ( name: " stripeColors " , value: stripeColorsValue) )
1347+ }
1348+
12951349 addDouble ( " bloomStrength " , value: bloomStrengthSlider. doubleValue, defaultValue: 0.7 )
12961350 addDouble ( " bloomSize " , value: bloomSizeSlider. doubleValue, defaultValue: 0.4 )
12971351 addDouble ( " highPassThreshold " , value: highPassThresholdSlider. doubleValue, defaultValue: 0.1 )
0 commit comments