001package polaris.sdk.ui.controls; 002import polaris.sdk.ui.*; 003 004/** Container supporting absolute, row, column and grid layouts. */ 005public class Panel extends Widget { 006 public enum Layout{ABSOLUTE,ROW,COLUMN,GRID} 007 private boolean draggable,dragging;private float dragX,dragY,baseX,baseY; 008 protected Layout flow=Layout.ABSOLUTE;protected float padding=Spacing.INSET,gap=Spacing.GAP;protected int columns=2;protected boolean glass=true; 009 public Panel(){w=320;h=220;clipChildren=true;} public Panel(String title){super(title);w=320;h=220;clipChildren=true;} 010 public Panel glass(boolean b){glass=b;return this;} public Panel layout(Layout l){flow=l;return this;} 011 public Panel padding(float p){padding=Math.max(0,p);return this;} public Panel gap(float g){gap=Math.max(0,g);return this;} 012 public float padding(){return padding;}public float gap(){return gap;} 013 public Panel columns(int n){if(n<1)throw new IllegalArgumentException("columns");columns=n;return this;} 014 /** Opt-in whole-surface dragging; interactive descendants retain their own input. */ 015 public Panel draggable(boolean value){draggable=value;return this;} 016 @Override public Widget hit(float px,float py){Widget hit=super.hit(px,py);if(!draggable||hit==null)return hit; 017 if(hit==this||hit instanceof Label&&!(hit instanceof Button))return this;return hit;} 018 @Override public void event(UiEvent e){ 019 if(!draggable){super.event(e);return;} 020 if(e.type==UiEvent.Type.DOWN&&e.button==1){dragging=true;dragX=e.x;dragY=e.y;beginPositionDrag();baseX=x;baseY=y;e.handled=true;} 021 else if((e.type==UiEvent.Type.MOVE||e.type==UiEvent.Type.UP&&e.button==1)&&dragging){bounds(baseX+e.x-dragX,baseY+e.y-dragY,w,h);changed();e.handled=true;} 022 if(e.type==UiEvent.Type.UP||e.type==UiEvent.Type.BLUR)dragging=false; 023 } 024 protected float contentTop(){return padding;} 025 @Override protected float contentClipRadius(){return glass?theme().panelRadius:0;} 026 @Override protected void layoutChildren(){float x=padding,y=contentTop(),cw=Math.max(0,w-2*padding);int i=0;float rowTop=contentTop(),rowMax=0; 027 for(Widget c:children){if(!c.visible())continue; 028 if(flow==Layout.COLUMN){c.bounds(x,y,cw,c.height());y+=c.height()+gap;} 029 else if(flow==Layout.ROW){c.bounds(x,y,c.width(),Math.max(0,h-contentTop()-padding));x+=c.width()+gap;} 030 else if(flow==Layout.GRID){float cell=(cw-gap*(columns-1))/columns;int col=i%columns;c.bounds(padding+col*(cell+gap),rowTop,Math.max(0,cell),c.height());rowMax=Math.max(rowMax,c.height());i++;if(i%columns==0){rowTop+=rowMax+gap;rowMax=0;}} 031 } 032 } 033 @Override protected void paint(Painter p){if(glass)glassPart(p,ax,ay,w,h,theme().panelRadius,0,theme().surface,0,theme().blur);} 034}