示例#1
0
void TreeDiagram::drawConnectors(FTextStream &t,Image *image,
                                 bool doBase,bool bitmap,
                                 uint baseRows,uint superRows,
                                 uint cellWidth,uint cellHeight)
{
  DiagramRow *dr=first();
  bool done=FALSE;
  while (dr && !done) // for each row
  {
    DiagramItem *di=dr->first();
    if (di->isInList()) // row consists of list connectors
    {
      int x=0,y=0,ys=0;
      float xf=0.0,yf=0.0,ysf=0.0;
      while (di)
      {
        DiagramItem *pi=di->parentItem();
        DiagramItemList *dil=pi->getChildren();
        DiagramItem *last=dil->getLast();
        if (di==last) // single child
        {
          if (bitmap) // draw pixels
          {
            x = di->xPos()*(cellWidth+labelHorSpacing)/gridWidth + cellWidth/2;
            if (doBase) // base classes
            {
              y = image->getHeight()-
                (superRows-1)*(cellHeight+labelVertSpacing)-
                di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
              image->drawVertArrow(x,y,y+labelVertSpacing/2,
                                   protToColor(di->protection()),
                                   protToMask(di->protection()));
            }
            else // super classes
            {
              y = (baseRows-1)*(cellHeight+labelVertSpacing)-
                labelVertSpacing/2+
                di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
              image->drawVertLine(x,y,y+labelVertSpacing/2,
                                  protToColor(di->protection()),
                                  protToMask(di->protection()));
            }
          }
          else // draw vectors
          {
            t << protToString(di->protection()) << endl;
            if (doBase)
            {
              t << "1 " << (di->xPos()/(float)gridWidth) << " " 
                << (di->yPos()/(float)gridHeight+superRows-1) << " in\n";
            }
            else
            {
              t << "0 " << (di->xPos()/(float)gridWidth) << " " 
                << ((float)superRows-0.25-di->yPos()/(float)gridHeight)
                << " in\n";
            }
          }
        }
        else // multiple children, put them in a vertical list
        {
          if (bitmap)
          {
            x = di->parentItem()->xPos()*
              (cellWidth+labelHorSpacing)/gridWidth+cellWidth/2;
            if (doBase) // base classes
            {
              ys = image->getHeight()-
                (superRows-1)*(cellHeight+labelVertSpacing)-
                di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
              y = ys - cellHeight/2;
            }
            else // super classes
            {
              ys = (baseRows-1)*(cellHeight+labelVertSpacing)+
                di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
              y = ys + cellHeight/2;
            }
          }
          else
          {
            xf = di->parentItem()->xPos()/(float)gridWidth;
            if (doBase)
            {
              ysf = di->yPos()/(float)gridHeight+superRows-1;
              yf = ysf + 0.5;
            }
            else
            {
              ysf = (float)superRows-0.25-di->yPos()/(float)gridHeight;
              yf = ysf - 0.25;
            }
          }
          while (di!=last) // more children to add
          {
            if (bitmap)
            {
              if (doBase) // base classes
              {
                image->drawHorzArrow(y,x,x+cellWidth/2+labelHorSpacing,
                    protToColor(di->protection()),
                    protToMask(di->protection()));
                y -= cellHeight+labelVertSpacing;
              }
              else // super classes
              {
                image->drawHorzLine(y,x,x+cellWidth/2+labelHorSpacing,
                    protToColor(di->protection()),
                    protToMask(di->protection()));
                y += cellHeight+labelVertSpacing;
              }
            }
            else
            {
              t << protToString(di->protection()) << endl;
              if (doBase)
              {
                t << "1 " << xf << " " << yf << " hedge\n";
                yf += 1.0;
              }
              else
              {
                t << "0 " << xf << " " << yf << " hedge\n";
                yf -= 1.0;
              }
            }
            di=dr->next();
          }
          // add last horizonal line and a vertical connection line
          if (bitmap)
          {
            if (doBase) // base classes
            {
              image->drawHorzArrow(y,x,x+cellWidth/2+labelHorSpacing,
                  protToColor(di->protection()),
                  protToMask(di->protection()));
              image->drawVertLine(x,y,ys+labelVertSpacing/2,
                  protToColor(getMinProtectionLevel(dil)),
                  protToMask(getMinProtectionLevel(dil)));
            }
            else // super classes
            {
              image->drawHorzLine(y,x,x+cellWidth/2+labelHorSpacing,
                  protToColor(di->protection()),
                  protToMask(di->protection()));
              image->drawVertLine(x,ys-labelVertSpacing/2,y,
                  protToColor(getMinProtectionLevel(dil)),
                  protToMask(getMinProtectionLevel(dil)));
            }
          }
          else
          {
            t << protToString(di->protection()) << endl;
            if (doBase)
            {
              t << "1 " << xf << " " << yf << " hedge\n";
            }
            else
            {
              t << "0 " << xf << " " << yf << " hedge\n";
            }
            t << protToString(getMinProtectionLevel(dil)) << endl;
            if (doBase)
            {
              t << xf << " " << ysf << " " << yf << " vedge\n";
            }
            else
            {
              t << xf << " " << (ysf + 0.25) << " " << yf << " vedge\n";
            }
          }
        }
        di=dr->next();
      }
      done=TRUE; // the tree is drawn now
    }
    else // normal tree connector
    {
      while (di)
      {
        int x=0,y=0;
        DiagramItemList *dil = di->getChildren();
        DiagramItem *parent  = di->parentItem();
        if (parent) // item has a parent -> connect to it
        {
          if (bitmap) // draw pixels
          {
            x = di->xPos()*(cellWidth+labelHorSpacing)/gridWidth + cellWidth/2;
            if (doBase) // base classes
            {
              y = image->getHeight()-
                (superRows-1)*(cellHeight+labelVertSpacing)-
                di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
              /* write input line */
              image->drawVertArrow(x,y,y+labelVertSpacing/2,
                  protToColor(di->protection()),
                  protToMask(di->protection()));
            }
            else // super classes
            {
              y = (baseRows-1)*(cellHeight+labelVertSpacing)-
                labelVertSpacing/2+
                di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
              /* write output line */
              image->drawVertLine(x,y,y+labelVertSpacing/2,
                  protToColor(di->protection()),
                  protToMask(di->protection()));
            }
          }
          else // draw pixels
          {
            t << protToString(di->protection()) << endl;
            if (doBase)
            {
              t << "1 " << di->xPos()/(float)gridWidth << " " 
                << (di->yPos()/(float)gridHeight+superRows-1) << " in\n";
            }
            else
            {
              t << "0 " << di->xPos()/(float)gridWidth << " " 
                << ((float)superRows-0.25-di->yPos()/(float)gridHeight)
                << " in\n";
            }
          }
        }
        if (dil->count()>0)
        {
          Protection p=getMinProtectionLevel(dil);
          uint mask=protToMask(p);
          uint col=protToColor(p);
          if (bitmap)
          {
            x = di->xPos()*(cellWidth+labelHorSpacing)/gridWidth + cellWidth/2;
            if (doBase) // base classes
            {
              y = image->getHeight()-
                (superRows-1)*(cellHeight+labelVertSpacing)-
                cellHeight-labelVertSpacing/2-
                di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
              image->drawVertLine(x,y,y+labelVertSpacing/2-1,col,mask);
            }
            else // super classes
            {
              y = (baseRows-1)*(cellHeight+labelVertSpacing)+
                cellHeight+
                di->yPos()*(cellHeight+labelVertSpacing)/gridHeight;
              image->drawVertArrow(x,y,y+labelVertSpacing/2-1,col,mask);
            }
          }
          else
          {
            t << protToString(p) << endl;
            if (doBase)
            {
              t << "0 " << di->xPos()/(float)gridWidth  << " " 
                << (di->yPos()/(float)gridHeight+superRows-1) << " out\n";
            }
            else
            {
              t << "1 " << di->xPos()/(float)gridWidth  << " " 
                << ((float)superRows-1.75-di->yPos()/(float)gridHeight)
                << " out\n";
            }
          }
          /* write input line */
          DiagramItem *first = dil->first();
          DiagramItem *last  = dil->last();
          if (first!=last && !first->isInList()) /* connect with all base classes */
          {
            if (bitmap)
            {
              int xs = first->xPos()*(cellWidth+labelHorSpacing)/gridWidth
                + cellWidth/2;
              int xe = last->xPos()*(cellWidth+labelHorSpacing)/gridWidth
                + cellWidth/2; 
              if (doBase) // base classes
              {
                image->drawHorzLine(y,xs,xe,col,mask); 
              }
              else // super classes
              {
                image->drawHorzLine(y+labelVertSpacing/2,xs,xe,col,mask); 
              }
            }
            else
            {
              t << protToString(p) << endl;
              if (doBase)
              {
                t << first->xPos()/(float)gridWidth << " " 
                  << last->xPos()/(float)gridWidth << " "
                  << (first->yPos()/(float)gridHeight+superRows-1) 
                  << " conn\n";
              }
              else
              {
                t << first->xPos()/(float)gridWidth << " " 
                  << last->xPos()/(float)gridWidth << " "
                  << ((float)superRows-first->yPos()/(float)gridHeight)
                  << " conn\n";
              }
            }
          }
        }
        di=dr->next();
      }
      dr=next();
    }
  }
}