001package polaris.sdk.ui.controls;
002import polaris.sdk.ui.*;
003import java.awt.Color;
004public class ColorPicker extends Button {
005 private int color=0xff77b7ff;
006 public ColorPicker(){refresh();}
007 public ColorPicker color(int rgba){color=rgba;refresh();return this;}public int color(){return color;}
008 private void refresh(){text=String.format("#%08X",color);}
009 @Override protected void paint(Painter p){super.paint(p);p.fill(ax+10,ay+8,20,h-16,5,color);}
010 @Override public void activate(){if(ui!=null)ui.popup(new ColorPopup(),ax,ay+h+Spacing.COMPACT_INSET);}
011 private final class ColorPopup extends Panel {
012  float hue,sat,bright,alpha,planeHeight;boolean drag;
013  final Slider hueBar=new Slider(),alphaBar=new Slider();final TextField hex=new TextField();final Button done=new Button("完成");
014  ColorPopup(){
015   w=320;h=326;
016   float[] hsv=Color.RGBtoHSB((color>>16)&255,(color>>8)&255,color&255,null);hue=hsv[0];sat=hsv[1];bright=hsv[2];alpha=(color>>>24)/255f;
017   hueBar.range(0,1).step(.001).value(hue);hueBar.id("colorHue");hueBar.onChange(w->{hue=(float)hueBar.value();update();});
018   alphaBar.range(0,1).step(.001).value(alpha);alphaBar.id("colorAlpha");alphaBar.onChange(w->{alpha=(float)alphaBar.value();update();});
019   hex.id("colorHex");hex.value(String.format("#%08X",color));
020   hex.onSubmit(s->{try{String raw=s.replace("#","");long n=Long.parseLong(raw,16);if(raw.length()==6)n|=0xff000000L;if(raw.length()!=6&&raw.length()!=8)throw new IllegalArgumentException();ColorPicker.this.color((int)n);ColorPicker.this.changed();ui.close(this);}catch(Exception e){ui.notify("颜色格式","使用 #RRGGBB 或 #AARRGGBB");}});
021   done.id("colorDone");done.onClick(w->ui.close(this));add(hueBar);add(alphaBar);add(hex);add(done);
022  }
023  @Override protected void layoutChildren(){
024   float content=Math.max(0,w-2*padding),footer=h-padding-Spacing.CONTROL_HEIGHT;
025   float aY=footer-gap-30,hY=aY-gap-30,labelWidth=Spacing.LABEL_HEIGHT;
026   planeHeight=Math.max(0,hY-gap-padding);
027   hueBar.bounds(padding+labelWidth+gap,hY,Math.max(0,content-labelWidth-gap),30);
028   alphaBar.bounds(padding+labelWidth+gap,aY,Math.max(0,content-labelWidth-gap),30);
029   float buttonWidth=Math.min(88,Math.max(0,(content-gap)*.34f));
030   hex.bounds(padding,footer,Math.max(0,content-buttonWidth-gap),Spacing.CONTROL_HEIGHT);
031   done.bounds(w-padding-buttonWidth,footer,buttonWidth,Spacing.CONTROL_HEIGHT);
032  }
033  void update(){ColorPicker.this.color((Math.round(alpha*255)<<24)|(Color.HSBtoRGB(hue,sat,bright)&0xffffff));hex.value(String.format("#%08X",color));ColorPicker.this.changed();}
034  @Override protected void paint(Painter p){
035   glassPart(p,ax,ay,w,h,theme().panelRadius,.07f,theme().surface,0,theme().blur);
036   float pw=Math.max(0,w-2*padding);p.colorPlane(ax+padding,ay+padding,pw,planeHeight,hue);
037   float cx=ax+padding+sat*pw,cy=ay+padding+(1-bright)*planeHeight;
038   p.stroke(cx-5,cy-5,10,10,5,2,0xffffffff);
039   p.text("H",ax+padding,ay+hueBar.y()+(hueBar.height()-12)/2,12,theme().muted);
040   p.text("A",ax+padding,ay+alphaBar.y()+(alphaBar.height()-12)/2,12,theme().muted);
041  }
042  @Override public void event(UiEvent e){
043   if(e.type==UiEvent.Type.DOWN&&e.button==1&&e.x>=ax+padding&&e.x<ax+w-padding&&e.y>=ay+padding&&e.y<ay+padding+planeHeight){drag=true;set(e);e.handled=true;}
044   else if(e.type==UiEvent.Type.MOVE&&drag){set(e);e.handled=true;}
045   else if(e.type==UiEvent.Type.UP||e.type==UiEvent.Type.BLUR)drag=false;
046  }
047  void set(UiEvent e){sat=Math.max(0,Math.min(1,(e.x-ax-padding)/Math.max(1,w-2*padding)));bright=1-Math.max(0,Math.min(1,(e.y-ay-padding)/Math.max(1,planeHeight)));update();}
048 }
049}