/*******************************************************************************
* This is part of SketchChair, an open-source tool for designing your own furniture.
* www.sketchchair.cc
*
* Copyright (C) 2012, Diatom Studio ltd. Contact: hello@diatom.cc
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package cc.sketchchair.widgets;
import java.awt.event.MouseEvent;
import cc.sketchchair.core.GLOBAL;
import cc.sketchchair.core.PickBuffer;
import cc.sketchchair.core.SETTINGS;
import cc.sketchchair.core.UITools;
import cc.sketchchair.sketch.LOGGER;
import cc.sketchchair.sketch.Sketch;
import processing.core.PApplet;
import processing.core.PGraphics;
import processing.core.PImage;
import toxi.geom.Vec2D;
import ModalGUI.GUIButton;
import ModalGUI.GUIComponents;
import ModalGUI.GUIEvent;
import ModalGUI.GUILabel;
import ModalGUI.GUIPanel;
import ModalGUI.GUIScrollbar;
import ModalGUI.GUISlider;
import ModalGUI.GUIToggle;
import ModalGUI.ModalGUI;
import ShapePacking.spShapePack;
public class WidgetPreviewPanel extends GUIPanel {
ModalGUI gui;
float previewW = 150;
float previewH = 150;
float previewBorderY = 160;
float previewBorderX = 10;
PImage ergoFig = null;
PGraphics patternPreview = null;
PGraphics chairPreview = null;
public GUIButton makeItBtn = null;
public GUIButton designItBtn = null;
PImage patternPreviewCache ;
GUIScrollbar patternSlider = null;
float prevPatternSlider = -1;
boolean minimizeTop = false;
boolean minimizePattern = false;
public GUIComponents topComponents = new GUIComponents();
public GUIComponents middleComponents = new GUIComponents();
public GUIComponents bottomComponents = new GUIComponents();
private spShapePack previewShapePack;
float modelPannelYPos = 35;
float patternPannelYPos = 270;
float modelPannelYPosBase = patternPannelYPos - 25;
public WidgetPreviewPanel(float x, float y, float w, float h, ModalGUI gui) {
super(x, y, w, h, gui);
this.gui = gui;
this.renderBorder = false;
this.hideSelectBar = true;
ergoFig = gui.applet.loadImage("gui/GUI_ERGO_FIGURE.png");
chairPreview = gui.applet.createGraphics((int)previewW,(int)previewH, PApplet.OPENGL );
chairPreview.smooth(8);
chairPreview.hint(PApplet.DISABLE_TRANSFORM_CACHE);
chairPreview.hint(PApplet.ENABLE_ACCURATE_2D);
patternPreview = gui.applet.createGraphics((int) getWidth(), (int) (getHeight()-patternPannelYPos), PApplet.OPENGL );
patternPreview.smooth(8);
patternPreview.hint(PApplet.DISABLE_TRANSFORM_CACHE);
patternPreview.hint(PApplet.ENABLE_ACCURATE_2D);
previewShapePack = new spShapePack();
float posX = 0;
float posY = 0;
/*
GUIToggle toggle = new GUIToggle(yPos, 10,
"gui/GUI_ERGO_FIGURE.png", "gui/GUI_ERGO_FIGURE_OFF.png", gui);
toggle.addActionListener(GLOBAL.uiTools, "togglePerson", null);
gui.add(toggle);
*/
posY = 65;
GUIToggle toggle = new GUIToggle(this.getWidth()-20,modelPannelYPos - 15,"gui/GUI_MINMIMIZE_PANEL_UP.png","gui/GUI_MINMIMIZE_PANEL_DOWN.png",gui );
toggle.addActionListener(this, "minimizeToggleTop", null);
this.add(toggle);
topComponents.add(toggle);
toggle = new GUIToggle(this.getWidth()-20,patternPannelYPos - 15,"gui/GUI_MINMIMIZE_PANEL_UP.png","gui/GUI_MINMIMIZE_PANEL_DOWN.png",gui );
toggle.addActionListener(this, "minimizeTogglePattern", null);
middleComponents.add(toggle);
this.add(toggle);
posX += 80;
toggle = new GUIToggle(posX-5+150,modelPannelYPosBase-75,"gui/GUI_ERGO_SHOW.png","gui/GUI_ERGO_HIDE.png",gui );
toggle.addActionListener(GLOBAL.uiTools, "togglePerson", null);
this.add(toggle);
middleComponents.add(toggle);
/*
label = new GUILabel(2,modelPannelYPos-20,"model | view", gui);
label.addActionListener(GLOBAL.uiTools, "viewModel", null);
this.add(label);
*/
//middleComponents.add(label);
makeItBtn = new GUIButton(posX,-7,"gui/make_it_up.png","gui/make_it_down.png",gui );
makeItBtn.addActionListener(GLOBAL.uiTools, "viewPattern", null);
this.add(makeItBtn);
designItBtn = new GUIButton(posX,-7,"gui/design_it_up.png","gui/design_it_down.png",gui );
designItBtn.addActionListener(GLOBAL.uiTools, "viewModel", null);
this.add(designItBtn);
if(GLOBAL.uiTools.currentView == UITools.VIEW_CHAIR_EDIT){
designItBtn.hide();
makeItBtn.show();
}else{
designItBtn.show();
makeItBtn.hide();
}
GUIButton button = null;
button = new GUIButton(posX+150,modelPannelYPosBase-50,"gui/GUI_ERGO_BIGGER.png","gui/GUI_ERGO_BIGGER.png",gui );
button.addActionListener(GLOBAL.uiTools, "figureGrow", null);
this.add(button);
middleComponents.add(button);
button = new GUIButton(posX+150,modelPannelYPosBase - 35,"gui/GUI_ERGO_BAR.png","gui/GUI_ERGO_BAR.png",gui );
this.add(button);
middleComponents.add(button);
button = new GUIButton(posX+150,modelPannelYPosBase-10,"gui/GUI_ERGO_SMALLER.png","gui/GUI_ERGO_SMALLER.png",gui );
button.addActionListener(GLOBAL.uiTools, "figureShrink", null);
this.add(button);
middleComponents.add(button);
/*
label = new GUILabel(2,patternPannelYPos-20,"pattern | view", gui);
label.addActionListener(GLOBAL.uiTools, "viewPattern", null);
this.add(label);
middleComponents.add(label);
*/
patternSlider = new GUIScrollbar(this.getWidth()-10,patternPannelYPos+10,getHeight()-patternPannelYPos-20,0,200,GUISlider.VERTICAL,gui);
this.add(patternSlider);
bottomComponents.add(patternSlider);
}
public void render(PGraphics g) {
if (this.minimized)
return;
if (prevPatternSlider != patternSlider.getVal()
&& previewShapePack != null)
rebuildPatternPreview();
//Render on update optimization
if(gui.renderOnUpdate && !reRender){
components.render(g);
return;
}
//if(controller.renderOnUpdate)
//reRender = false; // only render once
g.pushMatrix();
g.translate(getX(), getY());
g.fill(250);
g.noStroke();
g.rect(0, 0, getWidth(), getHeight());
g.stroke(100);
g.strokeWeight(0.5f);
g.line(0, modelPannelYPos, getWidth(), modelPannelYPos);
g.popMatrix();
super.render(g);
g.pushMatrix();
g.translate(getX(), getY());
if(minimizeTop){
g.popMatrix();
return;
}
g.stroke(100);
g.strokeWeight(0.5f);
g.line(0, patternPannelYPos, getWidth(), patternPannelYPos);
float scale = 0.15f;
float scaleFactor = (scale * GLOBAL.person.getScale()) * 6.5f;
g.pushMatrix();
g.translate(45 - ((ergoFig.width / 2) * scaleFactor)+150, modelPannelYPosBase - (ergoFig.height * scaleFactor));
g.scale(scaleFactor); // what is the scale factor between the full size furniture and the ergo fig bitmap?
g.image(ergoFig, 0, 0);
g.popMatrix();
if(chairPreview != null){
float x = previewBorderX;
float y = modelPannelYPosBase - chairPreview.height;
//chairPreview.beginDraw();
//g.rect(x,y,chairPreview.width,chairPreview.height);
g.pushMatrix();
if(GLOBAL.uiTools.currentView == UITools.VIEW_SHAPE_PACK){
g.translate(125*(1.0f-SETTINGS.scale), 250*(1.0f-SETTINGS.scale));
g.scale(SETTINGS.scale);
}
g.image(chairPreview,x,y);
g.popMatrix();
//chairPreview.endDraw();
}
if(minimizePattern){
g.popMatrix();
return;
}
if (patternPreview != null){
//patternPreview.beginDraw();
g.image(patternPreview, 0, patternPannelYPos+5);
//patternPreview.endDraw();
//g.rect(0, patternPannelYPos+5, 1, 1);
}
g.popMatrix();
//scroll pattern
/*
if (prevPatternSlider != patternSlider.getVal()
&& previewShapePack != null) {
patternPreview.beginDraw();
patternPreview.translate(0, -patternSlider.getVal());
patternPreview.background(250);
patternPreview.fill(250);
patternPreview.noStroke();
patternPreview.rect(0,0,patternPreview.width,patternPreview.height);
previewShapePack.renderList(patternPreview);
//patternPreviewCache = patternPreview.get();
patternPreview.endDraw();
patternSlider.setMaxVal(previewShapePack.getHeight()-patternPreview.height+50);
}
*/
prevPatternSlider = patternSlider.getVal();
if (GLOBAL.undo.getMouseUpChair() != null &&
PickBuffer.getInstance().usePickBuffer
&& GLOBAL.uiTools.mousePressed) {
GLOBAL.undo.getMouseUpChair().slicePlanesY
.setRenderMode(Sketch.RENDER_3D_PREVIW);
GLOBAL.undo.getMouseUpChair().slicePlanesSlatSlices
.setRenderMode(Sketch.RENDER_3D_PREVIW);
float minX = GLOBAL.undo.getMouseUpChair().getSlicePlanesY()
.getMinX();
float minY = GLOBAL.undo.getMouseUpChair().getSlicePlanesY()
.getMinY();
float maxX = GLOBAL.undo.getMouseUpChair().getSlicePlanesY()
.getMaxX();
float maxY = GLOBAL.undo.getMouseUpChair().getSlicePlanesY()
.getMaxY();
float width = Math.abs(maxX - minX);
float height = Math.abs(maxY - minY);
float widthDelta = previewW / width;
float heightDelta = previewH / height;
scale = Math.min(widthDelta, heightDelta);
//now we want to clamp this scale to a max and min;
//scale changes in 5% increments;
scale = (((int) ((scale * 100.0f) / 5.0f)) * 5.0f) / 100.0f;
scale = gui.applet.constrain(scale, 0.1f, 0.15f);
scale = 0.15f; //just keep one scale at the moment
Vec2D v = new Vec2D(width/2,GLOBAL.sketchChairs.getCurChair().getWidth()/2.0f);
v.rotate((float) (Math.PI/2));
float rotatedWidth = -v.x*2;
float totalWidth = ((rotatedWidth*scale)+(width*scale/2));
float yBorder = 10;
float x = this.getX()+previewBorderX+((rotatedWidth/2)*scale) + ((((previewW)-totalWidth)/2));//((previewW/scale) -rotatedWidth);)
//float x =((rotatedWidth/2)*scale) + 100;
float y = (this.getY()+modelPannelYPosBase) -(height*scale);//previewH - previewH + modelPannelYPosBase-100 + this.getY();
g.pushMatrix();
g.ortho(-(int)(GLOBAL.windowWidth / 2), (int)(GLOBAL.windowWidth / 2), -(int)(GLOBAL.windowHeight / 2), (int)(GLOBAL.windowHeight / 2),
-10000, 10000);
//g.hint(PApplet.DISABLE_STROKE_PERSPECTIVE);
g.scale(scale);
g.translate(x/scale , y/scale );
g.rotateY((float) (-Math.PI / 4));
g.translate(-minX, -minY);
PickBuffer.getInstance().pickBuffer.beginDraw();
PickBuffer.getInstance().pickBuffer.resetMatrix();
PickBuffer.getInstance().pickBuffer.setMatrix(g.getMatrix());
GLOBAL.sketchChairs.getCurChair().slicePlanesY
.renderPickBuffer(PickBuffer.getInstance().pickBuffer);
PickBuffer.getInstance().pickBuffer.endDraw();
g.perspective();
g.popMatrix();
float xp = (this.getX()-getWidth())/2.0f;//((previewW/scale) -rotatedWidth);)
// float yp =-(patternPannelYPos/2.0f)+(15);//previewH - previewH + modelPannelYPosBase-100 + this.getY();
float yp =-(GLOBAL.windowHeight/2)+patternPannelYPos+5;//previewH - previewH + modelPannelYPosBase-100 + this.getY();
PickBuffer.getInstance().pickBuffer.beginDraw();
PickBuffer.getInstance().pickBuffer.resetMatrix();
PickBuffer.getInstance().pickBuffer.translate(0, -patternSlider.getVal());
PickBuffer.getInstance().pickBuffer.translate(xp,yp);
previewShapePack.renderPickBufferList(PickBuffer.getInstance().pickBuffer);
//previewShapePack.renderList(patternPreview);
PickBuffer.getInstance().pickBuffer.endDraw();
patternPreview.endDraw();
}
}
@Override
public void setup() {
}
@Override
public void update() {
super.update();
}
public void rebuildPatternPreview(){
float scale = 0;
//Render preview chair, if we have mouse pressed use the undo version of our chair otherwise
if (GLOBAL.sketchChairs.getCurChair() != null) {
GLOBAL.sketchChairs.getCurChair().slicePlanesY
.setRenderMode(Sketch.RENDER_3D_PREVIW);
GLOBAL.sketchChairs.getCurChair().slicePlanesSlatSlices
.setRenderMode(Sketch.RENDER_3D_PREVIW);
float minX = GLOBAL.sketchChairs.getCurChair().getSlicePlanesY()
.getMinX();
float minY = GLOBAL.sketchChairs.getCurChair().getSlicePlanesY()
.getMinY();
float maxX = GLOBAL.sketchChairs.getCurChair().getSlicePlanesY()
.getMaxX();
float maxY = GLOBAL.sketchChairs.getCurChair().getSlicePlanesY()
.getMaxY();
float width = Math.abs(maxX - minX);
float height = Math.abs(maxY - minY);
float widthDelta = previewW / width;
float heightDelta = previewH / height;
scale = Math.min(widthDelta, heightDelta);
//now we want to clamp this scale to a max and min;
//scale changes in 5% increments;
scale = (((int) ((scale * 100.0f) / 5.0f)) * 5.0f) / 100.0f;
scale = gui.applet.constrain(scale, 0.1f, 0.15f);
scale = 0.15f;//0.15f; //just keep one scale at the moment
Vec2D v = new Vec2D(width/2,GLOBAL.sketchChairs.getCurChair().getWidth()/2.0f);
v.rotate((float) (Math.PI/2));
float rotatedWidth = -v.x*2;
float yBorder =10;
float totalWidth = ((rotatedWidth*scale)+(width*scale/2));
//setting at 0 0 draws the chair in the top left corner of the fbo
float x = (rotatedWidth/2)+((((previewW)-totalWidth)/2)/scale);//((previewW/scale) -rotatedWidth);
float y = (previewH/scale) - height-yBorder;
float goundOffset = (previewH - (height * scale)) / scale;
chairPreview.beginDraw();
chairPreview.background(250);
chairPreview.pushMatrix();
chairPreview.ortho(-(int)(chairPreview.width / 2), (int)(chairPreview.width / 2), -(int)(chairPreview.height / 2), (int)(chairPreview.height / 2),
-1000, 1000);
//chairPreview.hint(PApplet.DISABLE_STROKE_PERSPECTIVE);
chairPreview.smooth(8);
chairPreview.scale(scale);
chairPreview.translate(x,y);
//chairPreview.translate(0, +(height / 2));
chairPreview.rotateY((float) (-Math.PI / 4));
chairPreview.translate(-minX , -minY );
GLOBAL.sketchChairs.getCurChair().slicePlanesY.render(chairPreview);
chairPreview.perspective();
chairPreview.popMatrix();
chairPreview.endDraw();
}
if(minimizePattern)
return;
if(GLOBAL.sketchChairs.getCurChair() != null && patternPreview!=null){
previewShapePack.empty();
previewShapePack.materialWidth = this.getWidth()-15;
previewShapePack.materialHeight = 1000000;
previewShapePack.autoPackPieces = false;
GLOBAL.sketchChairs.getCurChair().addToPreviewShapePack(previewShapePack);
previewShapePack.scaleAll(0.15f);
previewShapePack.build();
//prevents draw
// if(patternPreview.canDraw()){
patternPreview.beginDraw();
patternPreview.translate(0, -patternSlider.getVal());
patternPreview.fill(250);
patternPreview.background(250);
patternPreview.noStroke();
//patternPreview.rect(0,0,patternPreview.width,patternPreview.height);
previewShapePack.renderList(patternPreview);
//patternPreviewCache = patternPreview.get();
patternPreview.endDraw();
//}
patternSlider.setMaxVal(previewShapePack.getHeight());
}
}
@Override
public void mouseEvent(MouseEvent e) {
super.mouseEvent(e);
if (!this.visible)
return;
if (e.getID() == MouseEvent.MOUSE_PRESSED) {
} else if (e.getID() == MouseEvent.MOUSE_RELEASED) {
if (!GLOBAL.gui.overComponent() && !GLOBAL.gui.hasFocus()) {
//rebuildPatternPreview();
}
isDragging = false;
}
}
public void minimizeToggleTop(GUIEvent e){
minimizeTop = !minimizeTop;
if(minimizeTop){
this.setSize(this.getWidth(), modelPannelYPos+5);
middleComponents.hideAll();
bottomComponents.hideAll();
this.controller.reBuildStencilBuffer();
}else{
this.setSize(this.getWidth(), GLOBAL.windowHeight);
middleComponents.showAll();
bottomComponents.showAll();
minimizePattern = false;
this.controller.reBuildStencilBuffer();
}
}
public void minimizeTogglePattern(GUIEvent e){
minimizePattern = !minimizePattern;
if(minimizePattern){
this.setSize(this.getWidth(), patternPannelYPos+5);
bottomComponents.hideAll();
this.controller.reBuildStencilBuffer();
}else{
this.setSize(this.getWidth(), GLOBAL.windowHeight);
bottomComponents.showAll();
this.rebuildPatternPreview();
this.controller.reBuildStencilBuffer();
}
}
}