//--------------------------------------------------------------------------------// // COPYRIGHT NOTICE // //--------------------------------------------------------------------------------// // Copyright (c) 2012, Instituto de Microelectronica de Sevilla (IMSE-CNM) // // // // All rights reserved. // // // // Redistribution and use in source and binary forms, with or without // // modification, are permitted provided that the following conditions are met: // // // // * Redistributions of source code must retain the above copyright notice, // // this list of conditions and the following disclaimer. // // // // * Redistributions in binary form must reproduce the above copyright // // notice, this list of conditions and the following disclaimer in the // // documentation and/or other materials provided with the distribution. // // // // * Neither the name of the IMSE-CNM nor the names of its contributors may // // be used to endorse or promote products derived from this software // // without specific prior written permission. // // // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE // // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL // // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR // // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER // // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, // // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // //--------------------------------------------------------------------------------// package xfuzzy.xfedit; import xfuzzy.lang.*; import xfuzzy.util.*; import javax.swing.*; import java.awt.*; import java.util.Vector; /** * Componente que dibuja una llamada a un m�dulo * * @author Francisco Jos� Moreno Velo * */ public class XfeditCallComponent { //----------------------------------------------------------------------------// // MIEMBROS P�BLICOS // //----------------------------------------------------------------------------// /** * Descripci�n de la llamada a representar */ public ModuleCall call; /** * Nivel de profundidad en el esquema jer�rquico */ public int level; /** * Altura del componente */ public int height; //----------------------------------------------------------------------------// // MIEMBROS PRIVADOS // //----------------------------------------------------------------------------// /** * Editor de la estructura jer�rquica */ private XfeditStructure structure; /** * Componentes que marcan los puntos de las variables de entrada a la llamada */ private XfeditVariableDot inputdot[]; /** * Componentes que marcan los puntos de las variables de salida de la llamada */ private XfeditVariableDot outputdot[]; /** * Llamadas a m�dulos que deben preceder a la llamada a representar */ private Vector previous; /** * Marcador para indicar si el componente est� seleccionado */ private boolean selected = false; /** * Posici�n en la que est� colocado el componente */ private int x, y; /** * Anchura del componente */ private int width; /** * Caracter�sticas de la fuente de letra */ private int ascent, descent; /** * Fuente de letra a utilizar */ private FontMetrics fm; /** * Icono a mostrar en el componente */ private Icon callicon; //----------------------------------------------------------------------------// // CONSTRUCTOR // //----------------------------------------------------------------------------// /** * Constructor */ public XfeditCallComponent(XfeditStructure structure, ModuleCall call) { this.fm = structure.getFontMetrics(structure.getFont()); this.ascent = fm.getAscent(); this.descent = fm.getDescent(); if(call instanceof CrispBlockCall) this.callicon = XfeditIcons.crispblock; else this.callicon = XfeditIcons.rulebase; this.structure = structure; this.call = call; this.level = 0; this.previous = new Vector(); Variable inputvar[] = call.getInputVariables(); int inputlength = call.getNumberOfInputs(); int outputlength = call.getNumberOfOutputs(); this.inputdot = new XfeditVariableDot[inputlength]; this.outputdot = new XfeditVariableDot[outputlength]; for(int i=0; i<inputlength; i++) { inputdot[i] = new XfeditVariableDot(structure,this,i,0,true); structure.addDot(inputdot[i]); XfeditVariableDot ldot = structure.searchOriginDot(inputvar[i]); if(ldot != null && ldot.call != null && !inputvar[i].equals("NULL")) previous.addElement(ldot.call); if(ldot != null && ldot.level > level) level = ldot.level; } for(int i=0; i<inputlength; i++) inputdot[i].level = level; for(int i=0; i<outputlength; i++) { outputdot[i] = new XfeditVariableDot(structure,this,i,level+1,false); structure.addDot(outputdot[i]); } int hl = ascent+descent+5; int hv = hl+hl*(inputlength>outputlength? inputlength: outputlength); int hv2 = callicon.getIconHeight() + 2*hl; this.height = (hv>hv2 ? hv : hv2); } //----------------------------------------------------------------------------// // M�TODOS P�BLICOS // //----------------------------------------------------------------------------// /** * Estudia si la posici�n se encuentra dentro del componente */ public boolean include(int px, int py) { return (px>x && px<x+width && py>y && py<y+height); } /** * Asigna el estado de selecci�n del componente */ public void setSelected(boolean selected) { this.selected = selected; } /** * Limpia el vector de llamadas previas */ public void clearPrevious() { this.previous.removeAllElements(); } /** * Recalcula el vector de llamadas previas */ public void setPrevious() { this.previous.removeAllElements(); for(int i=0; i<inputdot.length; i++) { if(inputdot[i].sysvar.equals("NULL")) continue; XfeditVariableDot ldot = structure.searchDot(inputdot[i].sysvar); if(ldot != null && ldot.call != null) previous.addElement(ldot.call); } } /** * Verifica si un componente corresponde a una llamada previa */ public boolean isPrevious(XfeditCallComponent cc) { for(int i=0; i<previous.size(); i++) { XfeditCallComponent pr = (XfeditCallComponent) previous.elementAt(i); if(cc == pr || pr.isPrevious(cc)) return true; } return false; } /** * Dibuja el componente */ public void paintCall(Graphics g, int xx, int yy, int w) { String label = call.getName(); int cw = fm.stringWidth(label); int ih = height/(inputdot.length+1); int oh = height/(outputdot.length+1); this.x = xx; this.y = yy; this.width = w; for(int i=0; i<inputdot.length; i++) { int ypos = y+ih*(i+1); inputdot[i].setPoint(x,ypos); inputdot[i].paintDot(g); } for(int i=0; i<outputdot.length; i++) { int ypos = y+oh*(i+1); outputdot[i].setPoint(x+w,ypos); outputdot[i].paintDot(g); } int labelh = ascent+descent+10; if(selected) g.setColor(Color.red); else g.setColor(Color.blue); g.fillRect(x,y,width,labelh); g.setColor(XConstants.callbg); g.fillRect(x,y+labelh,width,height-labelh); g.setColor(Color.black); g.drawRect(x,y,width,labelh); g.drawRect(x,y+labelh,width,height-labelh); int iconw = callicon.getIconWidth(); int iconh = callicon.getIconHeight(); int labely = y+5+ascent; int icony = y+labelh+(height-labelh-iconh)/2; if(icony<labely+5) icony = labely+5; g.setColor(Color.white); g.drawString(label,x+(w-cw)/2,labely); g.setColor(Color.black); callicon.paintIcon(structure,g,x+(w-iconw)/2,icony); } /** * Dibuja los enlaces del componente */ public void paintLinks(Graphics g) { for(int i=0; i<inputdot.length; i++) structure.paintLink(g,structure.searchOriginDot(inputdot[i].sysvar),inputdot[i]); for(int i=0; i<outputdot.length; i++) if(outputdot[i].sysvar != null && outputdot[i].sysvar.isOutput()) structure.paintLink(g,outputdot[i],structure.searchDot(outputdot[i].sysvar)); } }