00001
00002
00003
00004 package org.hfbk.vis.visnode;
00005
00006 import java.awt.event.MouseEvent;
00007
00008 import org.dronus.gl.GLBoxRenderer;
00009 import org.dronus.gl.GLTextPanel;
00010 import org.dronus.graph.Node;
00011 import org.lwjgl.opengl.GL11;
00012 import org.lwjgl.util.vector.Vector3f;
00013
00019 public class VisImagefield extends VisNodeDraggable {
00020
00021 final float LAYOUT_TIME=3;
00022 final int LAYOUT_STACK=0, LAYOUT_PLANE=1, LAYOUT_SPIRAL=2, LAYOUT_CLOUD=3, LAYOUTS_END=4;
00023
00024 Vector3f[] targetPos;
00025
00026
00027 public VisImagefield(Node n, Vector3f position) {
00028 super(n, position);
00029 layoutLocked=false;
00030 w=h=radius=3;
00031 }
00032
00033
00034 float layoutEta=LAYOUT_TIME;
00035
00036 int layoutMode=LAYOUT_PLANE;
00037
00038 VisNode morebutton=null;
00039
00040 void setLayout(int mode){
00041
00042
00043 layoutMode=mode;
00044 targetPos=null;
00045 layoutLocked=false;
00046 layoutEta=LAYOUT_TIME;
00047 }
00048
00049
00050 float frac(float x){
00051 return x-(int)x;
00052 }
00053
00058 void computeLayout(){
00059
00060 targetPos=new Vector3f[children.size()];
00061
00062 float x=0,y=0, z=0;
00063 int n=targetPos.length;
00064
00065 switch(layoutMode){
00066 case LAYOUT_STACK:
00067 for (int i=0; i<n; i++)
00068 targetPos[n-i-1]=new Vector3f(10,0,-i);
00069 break;
00070 case LAYOUT_PLANE:
00071 float rowlength=(float)Math.sqrt(n)*15-7;
00072 for (int i=0; i<n; i++){
00073 targetPos[n-i-1]=new Vector3f(10+x,5-y,z);
00074
00075 if (children.get(n-i-1) instanceof VisImagefield)
00076 targetPos[n-i-1]=new Vector3f(rowlength+15,0,0);
00077
00078
00079
00080
00081
00082 float sx=x/100, sy=y/100;
00083 z=frac(sx+((int)sx)/2f)+frac(sy);
00084
00085 x+=15;
00086 if (x>rowlength){
00087 x=0;
00088 y+=15;
00089 }
00090 }
00091
00092 break;
00093
00094 case LAYOUT_SPIRAL:
00095 z=0;
00096 for (int i=0; i<n; i++){
00097 z-=6f;
00098
00099 x=(float)Math.sin(i/2f)*20;
00100 y=(float)Math.cos(i/2f)*20;
00101
00102 targetPos[n-i-1]=new Vector3f(x,-y,z);
00103 }
00104 break;
00105 case LAYOUT_CLOUD:
00106 float r=(float)Math.cbrt(n)*15;
00107 z=0;
00108 for (int i=0; i<n; i++){
00109 z-=r/n;
00110
00111 x=(float)Math.random()*r;
00112 y=(float)Math.random()*r;
00113
00114 targetPos[n-i-1]=new Vector3f(x,20-y,z);
00115 }
00116 break;
00117 }
00118 }
00119
00124 void renderSelf() {
00125
00126 if(morebutton==null && url!=null){
00127 add(morebutton=new MoreButton(new Vector3f(0,5,0)));
00128 targetPos=null;
00129 }
00130 if (isHoovered)
00131 GLBoxRenderer.renderColoredBox(w,h,w,1,1,1);
00132 else
00133 GLBoxRenderer.renderColoredBox(w,h,w,2,1,0);
00134
00135 if (layoutLocked) return;
00136
00137
00138 if(targetPos==null) computeLayout();
00139
00140
00141 float dt=getRoot().client.dt;
00142 int i=0;
00143
00144 for(VisNode child: children){
00145 Vector3f dpos=Vector3f.sub(targetPos[i], child.position, null);
00146 if (layoutEta>0){
00147 dpos.scale(dt/layoutEta);
00148 Vector3f.add(child.position,dpos, child.position);
00149 }else
00150 child.position=targetPos[i];
00151 i++;
00152 }
00153 if (layoutEta<0)
00154 layoutLocked=true;
00155
00156 layoutEta-=dt;
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170 }
00171
00178 void handleEvent(VisMouseEvent evt) {
00179 super.handleEvent(evt);
00180 if (evt.getID()==MouseEvent.MOUSE_CLICKED){
00181 layoutMode++;
00182 if (layoutMode==LAYOUTS_END) layoutMode=0;
00183 setLayout(layoutMode);
00184 if (evt.getButton()==MouseEvent.BUTTON3){
00185 VisNode root=this;
00186 while (root.parent instanceof VisImagefield)
00187 root=root.parent;
00188 ((VisImagefield)root).propagateLayout(layoutMode);
00189 }
00190 }
00191 }
00192
00193 void propagateLayout(int mode){
00194 setLayout(mode);
00195 for (VisNode child: children)
00196 if(child instanceof VisImagefield)
00197 ((VisImagefield)child).propagateLayout(mode);
00198 }
00199
00205 public void add(VisNode node) {
00206 children.add((int)(Math.random()*children.size()), node);
00207
00208 node.parent=this;
00209
00210 if (node instanceof VisImagefield) propagateLayout(layoutMode);
00211 }
00212
00218 void fetchMore(){
00219
00220
00221
00222 int start=1;
00223 int index=url.indexOf("&start=");
00224 if (index>0){
00225 start=Integer.parseInt(url.substring(index+7));
00226 url=url.substring(0,index);
00227 }
00228
00229 url+="&start="+(start+1);
00230 getRoot().fetch(url, this);
00231 }
00232
00238 class MoreButton extends VisButton{
00239 GLTextPanel plus;
00240 public MoreButton(Vector3f pos) {
00241 super("",pos);
00242 w=h=radius=10;
00243
00244 }
00245
00246 public void handleClick() {
00247 parent.remove(this);
00248 fetchMore();
00249 }
00250
00251 void renderSelf() {
00252 if(plus==null)
00253 plus=new GLTextPanel("+",0,0);
00254 GL11.glEnable(GL11.GL_TEXTURE_2D);
00255 GL11.glColor3f(.7f,1f,0);
00256
00257 GL11.glTranslatef(-radius / 2, -radius / 2, 0);
00258 GL11.glScalef(radius/2,radius,0);
00259 plus.render();
00260 if(isHoovered){
00261 if (helpPanel==null)
00262 helpPanel=new GLTextPanel(help,0,0);
00263 GL11.glEnable(GL11.GL_TEXTURE_2D);
00264 GL11.glPushMatrix();
00265 GL11.glTranslatef(1f,-.5f,0);
00266 GL11.glScalef(.5f,1,1);
00267 helpPanel.render();
00268 GL11.glPopMatrix();
00269 GL11.glDisable(GL11.GL_TEXTURE_2D);
00270 GL11.glColor4f(1,1,1,.5f);
00271 }
00272 }
00273 }
00274
00275
00276 }