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}