001package polaris.sdk.ui.controls;
002import polaris.sdk.ui.*;
003
004import java.util.*;
005import java.util.function.BiConsumer;
006public class PropertyGrid extends ScrollPane {
007 private static final class PropertyLabel extends Label {
008  PropertyLabel(String text){super(text);}
009  @Override protected void paint(Painter p){p.text(text,ax,ay+(h-size)/2,size,ink());}
010 }
011 private final java.util.Map<String,Object> values=new LinkedHashMap<String,Object>();private BiConsumer<String,Object> listener;
012 public PropertyGrid(){w=360;h=210;}
013 public PropertyGrid onPropertyChange(BiConsumer<String,Object> c){listener=c;return this;}public Map<String,Object> values(){return Collections.unmodifiableMap(values);}
014 public PropertyGrid property(String name,Object value){if(values.containsKey(name))throw new IllegalArgumentException("Duplicate property "+name);values.put(name,value);Label label=new PropertyLabel(name);label.bounds(12,12+(values.size()-1)*45,130,28);add(label);Widget editor;
015  if(value instanceof Boolean){Switch box=new Switch("");box.selected((Boolean)value);box.onChange(w->update(name,box.selected()));editor=box;}
016  else if(value instanceof Number){NumberField number=new NumberField(((Number)value).doubleValue());number.onChange(w->update(name,number.number()));editor=number;}
017  else {TextField text=new TextField(String.valueOf(value));text.onChange(w->update(name,text.value()));editor=text;}
018  editor.bounds(145,8+(values.size()-1)*45,Math.max(80,w-165),34);add(editor);return this;
019 }
020 private void update(String name,Object value){values.put(name,value);changed();if(listener!=null)listener.accept(name,value);}
021 @Override protected void layoutChildren(){
022  float content=Math.max(0,w-2*padding),labelWidth=Math.max(0,(content-gap)*.40f);
023  for(int i=0;i<children.size();i++){
024   Widget c=children.get(i);float yy=padding+(i/2)*(Spacing.CONTROL_HEIGHT+gap);
025   c.bounds(i%2==0?padding:padding+labelWidth+gap,yy,
026      i%2==0?labelWidth:Math.max(0,content-labelWidth-gap),Spacing.CONTROL_HEIGHT);
027  }
028  super.layoutChildren();
029 }
030}