3333using Avalonia . Controls . Shapes ;
3434using static CommunityToolkit . Mvvm . ComponentModel . __Internals . __TaskExtensions . TaskAwaitableWithoutEndValidation ;
3535using FFmpeg . AutoGen ;
36+ using System . Diagnostics ;
3637
3738namespace ZXBasicStudio . DocumentEditors . ZXGraphics
3839{
@@ -44,6 +45,7 @@ public partial class PaletteBuilderDialog : Window, IDisposable
4445
4546 private Rectangle [ ] rectangulos = new Rectangle [ 256 ] ;
4647 private PaletteColor [ ] palette = null ;
48+ private PaletteColor [ ] palette512 = null ;
4749 private string sourceFile = null ;
4850 private string convertedFile = null ;
4951 private bool imgSourceLoaded = false ;
@@ -68,8 +70,9 @@ public PaletteBuilderDialog()
6870
6971 // Set the palette
7072 palette = ServiceLayer . GetPalette ( GraphicsModes . Next ) ;
71- selectedColorIndex = 0 ;
73+ selectedColorIndex = 0 ;
7274 DrawPalette ( ) ;
75+ DrawColorPicker ( ) ;
7376
7477 btnFileSource . Tapped += BtnFileSource_Tapped ;
7578 btnResetPalette . Click += BtnResetPalette_Click ;
@@ -85,7 +88,10 @@ public PaletteBuilderDialog()
8588 btnRefresh . Click += BtnRefresh_Click ;
8689 btnSaveImage . Click += BtnSaveImage_Click ;
8790
91+ btnColorPicker . Click += BtnColorPicker_Click ;
92+
8893 btnClose . Click += BtnClose_Click ;
94+
8995 }
9096
9197
@@ -893,5 +899,170 @@ private void CrearPaletaGPL9bits()
893899 }
894900
895901 #endregion
902+
903+
904+ #region Color Picker
905+
906+ private int Circles = 8 ; //16;
907+ private int Sectors = 32 ;
908+ private double Radius = 200 ;
909+
910+ private void BtnColorPicker_Click ( object ? sender , Avalonia . Interactivity . RoutedEventArgs e )
911+ {
912+ grdColorPicker . IsVisible = true ;
913+ }
914+
915+
916+ private void DrawColorPicker ( )
917+ {
918+ Create512Palette ( ) ;
919+
920+ ColorWheelCanvas . Children . Clear ( ) ;
921+ double ringWidth = Radius / Circles ;
922+ double angleStep = 360.0 / Sectors ;
923+ double cx = Radius ;
924+ double cy = Radius ;
925+
926+ for ( int circle = 0 ; circle < Circles ; circle ++ )
927+ {
928+ double r1 = ringWidth * circle ;
929+ double r2 = ringWidth * ( circle + 1 ) ;
930+ double value = ( circle + 1 ) / ( double ) Circles ;
931+
932+ for ( int sector = 0 ; sector < Sectors ; sector ++ )
933+ {
934+ double hue = sector * angleStep ;
935+ Color color = FromHSV ( hue , 1.0 , value ) ;
936+ int idx = ServiceLayer . GetColor ( color . R , color . G , color . B , palette512 , 5 ) ;
937+ var p = palette512 [ idx ] ;
938+ var color512 = Color . FromRgb ( p . Red , p . Green , p . Blue ) ;
939+ DrawSegment ( cx , cy , r1 , r2 , hue , angleStep , color512 ) ;
940+ }
941+ }
942+ }
943+
944+ private void DrawSegment ( double cx , double cy , double r1 , double r2 , double startAngle , double angleSize , Color color )
945+ {
946+ var startRad = Math . PI * startAngle / 180.0 ;
947+ var endRad = Math . PI * ( startAngle + angleSize ) / 180.0 ;
948+
949+ var p1 = new Point ( cx + r1 * Math . Cos ( startRad ) , cy + r1 * Math . Sin ( startRad ) ) ;
950+ var p2 = new Point ( cx + r2 * Math . Cos ( startRad ) , cy + r2 * Math . Sin ( startRad ) ) ;
951+ var p3 = new Point ( cx + r2 * Math . Cos ( endRad ) , cy + r2 * Math . Sin ( endRad ) ) ;
952+ var p4 = new Point ( cx + r1 * Math . Cos ( endRad ) , cy + r1 * Math . Sin ( endRad ) ) ;
953+
954+ var path = new Avalonia . Controls . Shapes . Path
955+ {
956+ Fill = new SolidColorBrush ( color ) ,
957+ StrokeThickness = 0 ,
958+ Data = new PathGeometry
959+ {
960+ Figures = new PathFigures
961+ {
962+ new PathFigure
963+ {
964+ StartPoint = p1 ,
965+ Segments = new PathSegments
966+ {
967+ new LineSegment { Point = p2 } ,
968+ new ArcSegment
969+ {
970+ Point = p3 ,
971+ Size = new Size ( r2 , r2 ) ,
972+ SweepDirection = SweepDirection . Clockwise ,
973+ IsLargeArc = angleSize > 180
974+ } ,
975+ new LineSegment { Point = p4 } ,
976+ new ArcSegment
977+ {
978+ Point = p1 ,
979+ Size = new Size ( r1 , r1 ) ,
980+ SweepDirection = SweepDirection . CounterClockwise ,
981+ IsLargeArc = angleSize > 180
982+ }
983+ }
984+ }
985+ }
986+ }
987+ } ;
988+
989+ ColorWheelCanvas . Children . Add ( path ) ;
990+ }
991+
992+ private void ColorWheelCanvas_PointerPressed ( object ? sender , PointerPressedEventArgs e )
993+ {
994+ var pos = e . GetPosition ( ColorWheelCanvas ) ;
995+ double dx = pos . X - Radius ;
996+ double dy = pos . Y - Radius ;
997+ double distance = Math . Sqrt ( dx * dx + dy * dy ) ;
998+ if ( distance > Radius ) return ;
999+
1000+ double angle = Math . Atan2 ( dy , dx ) * 180 / Math . PI ;
1001+ if ( angle < 0 ) angle += 360 ;
1002+
1003+ int sector = ( int ) ( angle / ( 360.0 / Sectors ) ) ;
1004+ int circle = ( int ) ( distance / ( Radius / Circles ) ) ;
1005+
1006+ double hue = sector * ( 360.0 / Sectors ) ;
1007+ double value = ( circle + 1 ) / ( double ) Circles ;
1008+ Color color = FromHSV ( hue , 1.0 , value ) ;
1009+
1010+ SelectedColorPreview . Fill = new SolidColorBrush ( color ) ;
1011+ }
1012+
1013+ private static Color FromHSV ( double hue , double saturation , double value )
1014+ {
1015+ double c = value * saturation ;
1016+ double x = c * ( 1 - Math . Abs ( ( hue / 60.0 % 2 ) - 1 ) ) ;
1017+ double m = value - c ;
1018+
1019+ double r = 0 , g = 0 , b = 0 ;
1020+
1021+ if ( hue < 60 ) { r = c ; g = x ; }
1022+ else if ( hue < 120 ) { r = x ; g = c ; }
1023+ else if ( hue < 180 ) { g = c ; b = x ; }
1024+ else if ( hue < 240 ) { g = x ; b = c ; }
1025+ else if ( hue < 300 ) { r = x ; b = c ; }
1026+ else { r = c ; b = x ; }
1027+
1028+ byte R = ( byte ) ( ( r + m ) * 255 ) ;
1029+ byte G = ( byte ) ( ( g + m ) * 255 ) ;
1030+ byte B = ( byte ) ( ( b + m ) * 255 ) ;
1031+
1032+ return Color . FromRgb ( R , G , B ) ;
1033+ }
1034+
1035+ private void Create512Palette ( )
1036+ {
1037+ palette512 = new PaletteColor [ 512 ] ;
1038+ for ( int i = 0 ; i < 512 ; i ++ )
1039+ {
1040+ int r = ( ( i & 0b111000000 ) >> 6 ) * 36 ;
1041+ int g = ( ( i & 0b000111000 ) >> 3 ) * 36 ;
1042+ int b = ( i & 0b000000111 ) * 36 ;
1043+ if ( r > 250 )
1044+ {
1045+ r = 255 ;
1046+ }
1047+ if ( g > 250 )
1048+ {
1049+ g = 255 ;
1050+ }
1051+ if ( b > 250 )
1052+ {
1053+ b = 255 ;
1054+ }
1055+
1056+ palette512 [ i ] = new PaletteColor ( )
1057+ {
1058+ Red = ( byte ) r ,
1059+ Green = ( byte ) g ,
1060+ Blue = ( byte ) b ,
1061+ HasPriority = false
1062+ } ;
1063+ }
1064+ }
1065+
1066+ #endregion
8961067 }
8971068}
0 commit comments