예제 #1
0
void GraphEditor::mousePressEvent(QMouseEvent* e)
  {GeometricGraph & G = *(gwp->pGG);
  QPoint p((int)e->pos().x(),(int)e->pos().y());
  setFocus(); // as we might loose the focus
  ColorItem *coloritem;
  if(FindItem(p,coloritem) != 0)
      {if(e->button() == Qt::LeftButton)
          {if(coloritem->node)
              {gwp->NodeColorItem[color_node]->SetPenColor(White);
              coloritem->SetPenColor(coloritem->brush_color);
              color_node = coloritem->brush_color;
              G.vcolor.definit(color_node);
              }
          else
              {gwp->EdgeColorItem[color_edge]->SetPenColor(White);
              coloritem->SetPenColor(coloritem->brush_color);
              color_edge = coloritem->brush_color;
              G.ecolor.definit(color_edge);
              }
          return;
          }
      else if(e->button() == Qt::RightButton)
          {QString t;
          if(coloritem->node)
              t.sprintf("Vertex color:%s",ColorName[coloritem->brush_color]);
          else
              t.sprintf("Edge color:%s",ColorName[coloritem->brush_color]);
          gwp->info_item = CreateInfoItem(gwp,t,p);
          setCursor(QCursor(Qt::WhatsThisCursor));
          return;
          }
      }
  ThickItem *thickitem;
  if(FindItem(p,thickitem) != 0)
      {if(e->button() == Qt::LeftButton)
          {gwp->EdgeThickItem[width_edge]->SetBrushColor(White);
          thickitem->SetBrushColor(Yellow);
          width_edge = thickitem->width;
          G.ewidth.definit(width_edge);
          return;
          }
      else if(e->button() == Qt::RightButton)
          {QString t;
          t.sprintf("Edge width:%d",thickitem->width);
          gwp->info_item = CreateInfoItem(gwp,t,p);
          setCursor(QCursor(Qt::WhatsThisCursor));
          return;
          }
      }
  if(e->button() == Qt::RightButton )
      {NodeItem* node;
      EdgeItem *edge;
      QString t;
      int rtt = FindItem(p,node,edge);
      if(rtt == 0)rtt = FindItem(p,edge);//augment the collision zone
      if(rtt == node_rtti)
          if (G.Set().exist(PROP_VSLABEL) && G.Set(tvertex()).exist(PROP_SLABEL))
              {QString tt;
              Prop1<svector<tstring *> >vslabel(G.Set(),PROP_VSLABEL);
              Prop<int> slabel(G.Set(tvertex()),PROP_SLABEL,0);
              if (vslabel()[slabel[node->v]]==(tstring *)0) tt="(null)";
              else tt=~(*(vslabel()[slabel[node->v]]));
              t.sprintf("vertex:%d Label:%d (%s)",(node->v)(),G.vlabel[node->v],(const char *)tt.toLatin1());
              }
          else
              t.sprintf("vertex:%d Label:%d",(node->v)(),G.vlabel[node->v]);
      else if(rtt == edge_rtti)
          {double d = Distance(G.vcoord[G.vin[edge->e]],G.vcoord[G.vin[-(edge->e)]])+.5;
          t.sprintf("edge:%d Label:%d len:%d",(edge->e)(),G.elabel[edge->e],(int)d);
          }
      else
          {t.sprintf("(%d,%d)",(int)e->pos().x(),(int)e->pos().y());
          setCursor(QCursor(Qt::BlankCursor));
          }
      gwp->info_item = CreateInfoItem(gwp,t,p);
      return;
      }
  //GetMouseAction_1 returns the active radio button (0,5)
  int MouseAction = GetMouseAction_1();
  bool Shift    =  e->modifiers() == Qt::ShiftModifier;
  bool Control  =  e->modifiers() ==  Qt::ControlModifier;
  bool SControl =  e->modifiers() ==  (Qt::ShiftModifier | Qt::ControlModifier);

  if(e->button() == Qt::MidButton) //move
      MouseAction = (Shift) ? -3 : 3;
  else if(Shift && MouseAction == 1)        //add
      MouseAction = -1;                     // delete vertex or edge
  else if(Control && MouseAction == 1)
      MouseAction = 10;                     //duplicate graph
  else if(SControl && MouseAction == 1)
      MouseAction = 11;                     //duplicate +
  else if(Shift && MouseAction == 2)        //Orient or reorient if oriented
      MouseAction = -2;                     //disorient
  else if(Shift && MouseAction == 3)        //move vertices
      MouseAction = -3;                     //move colored vertices
  else if(Shift && MouseAction == 4)        //bissect
      MouseAction = -4;                     //contract
  else if(Shift && MouseAction == 5)        //define exterior face
      MouseAction = -5;                     //define extbrin
  else if(Shift && MouseAction == 6)        //define a label
      MouseAction = -6;                     //reset all labels to indices
  
  if(MouseAction == 0) // color
      {NodeItem* node;
      EdgeItem *edge;
      int rtt = FindItem(p,node,edge);
      if(rtt == 0) //augment the collision zone
          {rtt = FindItem(p,edge);
          if(rtt == 0)return;
          } 
      if(rtt == node_rtti)
          {mywindow->UndoTouch(false);
          G.vcolor[node->v] = color_node;
          node->SetColor(color[color_node]);
          }
      else if(rtt == edge_rtti)
          {mywindow->UndoTouch(false);
          G.ecolor[edge->e] = color_edge;
          G.ewidth[edge->e]  = width_edge;
          if(edge->lower) edge->SetColor(color[color_edge]);
          else edge->opp->SetColor(color[color_edge]);
          }
      return; 
      }
  else if(MouseAction == 1) // Start create an edge
      {mywindow->UndoTouch(false);
      Prop<NodeItem *> nodeitem(G.Set(tvertex()),PROP_CANVAS_ITEM);
      NodeItem* node;
      EdgeItem *edge;
      tvertex v;
      int h = (int)gwp->canvas->height();
      int rtt = FindItem(p,node,edge);
      if(rtt != node_rtti)// add a vertex
          {Tpoint pp((double)p.x(),(double)(h - p.y()));
          v = G.NewVertex(pp);
          ToGrid(v);
          nodeitem[v] = node  = CreateNodeItem(v,gwp);
          mywindow->mouse_actions->ButtonUndoGrid->setDisabled(true);
          }
      else
          v = node->v;
      start_position = QPoint((int)G.vcoord[v].x(),h-(int)G.vcoord[v].y());
      node->SetColor(Qt::red);
      gwp->curs_item = new CursItem(v,start_position,gwp);
      }
  else if(MouseAction == -1) // Delete
      {NodeItem* node;
      EdgeItem *edge;
      int rtt = FindItem(p,node,edge);
      if(rtt == 0) //augment the collision zone
          {rtt = FindItem(p,edge);
          if(rtt == 0)return;
          } 
      if(rtt == node_rtti)
          {mywindow->UndoTouch(true);
          G.DeleteVertex(node->v);
          mywindow->mouse_actions->ButtonUndoGrid->setDisabled(true);
          }
      else
          {mywindow->UndoTouch(true);
          G.DeleteEdge(edge->e);
          }
      load(false);
      mywindow->information();// Informations
      PrintSizeGrid();
      return;
      }
  else if(MouseAction == 3) // Start moving a vertex
      {NodeItem* node;
      EdgeItem *edge;
      int rtt = FindItem(p,node,edge);
      if(rtt != node_rtti)return;
      mywindow->UndoTouch(false);
      gwp->moving_item = node;
      start_position = p;
      return;
      }
  else if(MouseAction == -3) // Start moving a subgraph
      {mywindow->UndoTouch(false);
      gwp->moving_subgraph = true;
      start_position = p;
      return;
      }
  else if(MouseAction == 4) // Bissect an edge
      {mywindow->UndoTouch(true);
      if(FitToGrid)//and we are sure that ButtonFitGrid exists
	  mywindow->mouse_actions->ButtonFitGrid->setChecked(false);
      mywindow->mouse_actions->ButtonUndoGrid->setDisabled(true);
      EdgeItem *edge;
      int rtt = FindItem(p,edge);
      if(rtt != edge_rtti)return;
      G.BissectEdge(edge->e);
      DoNormalise = false;
      load(true);
      DoNormalise = true;
      mywindow->information();// Informations
      return;
      }
  else if(MouseAction == -4) // Contract an edge
      {EdgeItem *edge;
      int rtt = FindItem(p,edge);
      if(rtt != edge_rtti)return;
      mywindow->UndoTouch(true);
      // provisoire
      if(edge->lower)G.ReverseEdge(edge->e);
      // end provisoire
      G.ContractEdge(edge->e);
      load(false);
      mywindow->information();// Informations
      return;
      }
  else if(MouseAction == 5) // Color Exterior face
      {GeometricGraph & G = *(gwp->pGG);
      Prop<EdgeItem *> edgeitem(G.Set(tedge()),PROP_CANVAS_ITEM);
      Tpoint pp((double)p.x(),(double)(gwp->canvas->height()-p.y()));
      if(G.FindExteriorFace(pp) == 0)return;
      //ColorExteriorface
      tedge e;
      ForAllEdges(e,G)edgeitem[e]->SetColor(color[color_edge]);
      tbrin b0 = G.extbrin();
      tbrin b = b0;
      do
          {e = b.GetEdge();
          edgeitem[e]->SetColor(color[Red]);
          } while((b = G.cir[-b]) != b0);
      if(b0() > 0)
          edgeitem[b0.GetEdge()]->SetColor(color[Green],false);
      else
          edgeitem[b0.GetEdge()]->opp->SetColor(color[Green],false);
      return; 	  
      }
  else if(MouseAction == -5) // Define Extbrin
      {EdgeItem *edge;
      int rtt = FindItem(p,edge);
      if(rtt != edge_rtti)return;
      Prop<EdgeItem *> edgeitem(G.Set(tedge()),PROP_CANVAS_ITEM);
      tedge je;
      ForAllEdges(je,G)edgeitem[je]->SetColor(color[color_edge]);
      GeometricGraph & G = *(gwp->pGG);
      je = edge->e;
      //       Prop<NodeItem *> nodeitem(G.Set(tvertex()),PROP_CANVAS_ITEM);
      //       NodeItem *n1 =  nodeitem[G.vin[je]];   Tpoint p1(n1->x(),n1->y());
      //       NodeItem *n2 =  nodeitem[G.vin[-je]];  Tpoint p2(n2->x(),n2->y());
      //       Tpoint pp((double)p.x(),(double)p.y());
      //       G.extbrin() = (Distance2(pp,p1) < Distance2(pp,p2)) ? je.firsttbrin() : je.secondtbrin();
      G.extbrin() = (edge->lower ) ? je.firsttbrin() : je.secondtbrin();
      edge->SetColor(color[Green],false);
      return;
      }
  else if(MouseAction == 6) // Modify label
      {NodeItem* node;
      EdgeItem *edge;
      int rtt = FindItem(p,node,edge);
      if(rtt != node_rtti)return;
      tvertex v = node->v;
      bool ok;
      //int res = QInputDialog::getInteger(this,"Pigale","Enter a number:",(int)G.vlabel[node->v],0,2147483647,1,&ok);
      int res = QInputDialog::getInt(this,"Pigale","Enter a number:",(int)G.vlabel[node->v],0,2147483647,1,&ok);
      if(!ok)return;
      G.vlabel[node->v] = res;
      QString t = getVertexLabel(G.Container(),v);
      node->SetText(t);
      return;
      }
  else if(MouseAction == -6) // Reset all labels
      {Prop<NodeItem *> nodeitem(G.Set(tvertex()),PROP_CANVAS_ITEM);
      for(tvertex v = 1; v <= G.nv();v++)
          {G.vlabel[v] = v();
          nodeitem[v]->SetText(QString("%1").arg(v()));
          }
      for(tedge e = 1; e <= G.ne();e++)
          G.elabel[e] = e();
      }
  else if(MouseAction == 2  || MouseAction == -2) // Orient/Reverse or deorient
      {Prop<bool> eoriented(G.Set(tedge()),PROP_ORIENTED,false);
      Prop<bool> reoriented(G.Set(tedge()),PROP_REORIENTED); 
      Prop<EdgeItem *> edgeitem(G.Set(tedge()),PROP_CANVAS_ITEM);
      mywindow->setShowOrientation(true);
      EdgeItem *edge;
      int rtt = FindItem(p,edge);
      if(rtt != edge_rtti)return;
      mywindow->UndoTouch(true);
      if(MouseAction == 2)
          {if(eoriented[edge->e])
              {G.ReverseEdge(edge->e); eoriented[edge->e] = true;
              reoriented[edge->e] = false;
              edgeitem[edge->e] = CreateEdgeItem(edge->e,gwp); 
	      if(edge->arrow)
                  scene()->removeItem(edge->arrow);
	      else 
                  scene()->removeItem(edge->opp->arrow);
	      scene()->removeItem(edge->opp);scene()->removeItem(edge);
              mywindow->information();// Informations
              return;
              }
          else
              {eoriented[edge->e] = true;
	      if(edge->lower)
                  {G.ReverseEdge(edge->e);reoriented[edge->e] = false;}
	      edgeitem[edge->e] = CreateEdgeItem(edge->e,gwp);
	      if(edge->arrow)
                  scene()->removeItem(edge->arrow);
	      else 
                  scene()->removeItem(edge->opp->arrow);
	      scene()->removeItem(edge->opp);scene()->removeItem(edge);
              mywindow->information();// Informations
              return;
              }
          }
      else
          {eoriented[edge->e] = false;
	  edgeitem[edge->e] = CreateEdgeItem(edge->e,gwp); 
          if(edge->arrow)
              scene()->removeItem(edge->arrow);
          else 
              scene()->removeItem(edge->opp->arrow);
	  scene()->removeItem(edge->opp);scene()->removeItem(edge);
          mywindow->information();// Informations
          return;
          }
      }
  else if(MouseAction == 10)// Duplicate the sugraph of the current color
      {mywindow->UndoTouch(true);
      if(FitToGrid)//and we are sure that ButtonFitGrid exists
          mywindow->mouse_actions->ButtonFitGrid->setChecked(false);
      mywindow->mouse_actions->ButtonUndoGrid->setDisabled(true);
      short vcol=0;  G.vcolor.getinit(vcol);
      G.vcolor.definit((short)((vcol+1)%16));
      GeometricGraph & G = *(gwp->pGG);
      Tpoint translate(this->width()/2.,0);
      int n = G.nv();
      svector<tvertex> newvertex(1,n);
      tvertex v;
      for(v = 1; v <= n;v++)//translate all the graph
          G.vcoord[v] /= 2.;
      for(v = 1; v <= n;v++)
          {if(G.vcolor[v] != vcol)continue;
          newvertex[v] = G.NewVertex(G.vcoord[v] + translate);
          }
      int m = G.ne();
      tvertex v1,v2;
      for(tedge e = 1; e <= m;e++)
          {v1 = G.vin[e];v2 = G.vin[-e];
          if(G.vcolor[v1] == vcol && G.vcolor[v2] == vcol)
              G.NewEdge(newvertex[v1],newvertex[v2]);
          }
      load(true);
      mywindow->information();// Informations
      }
  else if(MouseAction == 11)
      //Duplicate the sugraph of the current color
      // and add edges between a new vertex and its father
      {mywindow->UndoTouch(true);
      if(FitToGrid)//and we are sure that ButtonFitGrid exists
          mywindow->mouse_actions->ButtonFitGrid->setChecked(false);
      mywindow->mouse_actions->ButtonUndoGrid->setDisabled(true);
      mywindow->mouse_actions->ButtonFitGrid->setChecked(false);
      short vcol=0;  G.vcolor.getinit(vcol);
      G.vcolor.definit((short)((vcol+1)%16));
      GeometricGraph & G = *(gwp->pGG);
      Tpoint translate(this->width()/2.,0);
      int n = G.nv();
      svector<tvertex> newvertex(1,n);
      tvertex v;
      for(v = 1; v <= n;v++)//translate all the graph
          G.vcoord[v] /= 2.;
      for(v = 1; v <= n;v++)
          {if(G.vcolor[v] != vcol)continue;
          newvertex[v] = G.NewVertex(G.vcoord[v] + translate);
          }
      int m = G.ne();
      tvertex v1,v2;
      for(tedge e = 1; e <= m;e++)
          {v1 = G.vin[e];v2 = G.vin[-e];
          if(G.vcolor[v1] == vcol && G.vcolor[v2] == vcol)
              G.NewEdge(newvertex[v1],newvertex[v2]);
          }
      for(v = 1; v <= n;v++)
          {if(G.vcolor[v] != vcol)continue;
          G.NewEdge(v,newvertex[v]);
          }
      load(true);
      mywindow->information();// Informations
      }
  }
예제 #2
0
void GraphEditor::mouseReleaseEvent(QMouseEvent* event)
  {//setRenderHints(QPainter::Antialiasing);
  if(gwp->info_item) //end info
      {scene()->removeItem(gwp->info_item->rectitem);
      scene()->removeItem(gwp->info_item);
      gwp->info_item = 0;
      setCursor(QCursor(Qt::ArrowCursor));
      return;
      }
  if(gwp->moving_item) //end moving a vertex
      {if(!FitToGrid)
          {gwp->moving_item = 0;return;}
      GeometricGraph & G = *(gwp->pGG);
      NodeItem *node = gwp->moving_item;
      tvertex v = node->v;
      double prev_x = G.vcoord[v].x();
      double prev_y = G.vcoord[v].y();
      ToGrid(v);
      double dx =  G.vcoord[v].x() - prev_x;
      double dy =  G.vcoord[v].y() - prev_y;
      G.vcoord[v].x() = prev_x;
      G.vcoord[v].y() = prev_y;
      node->moveBy(dx,-dy);
      gwp->moving_item = 0;
      UpdateSizeGrid();
      PrintSizeGrid();
      return;
      }
  if(gwp->moving_subgraph == true)
      {gwp->moving_subgraph = false;
      if(!FitToGrid)return;
      GeometricGraph & G = *(gwp->pGG);
      Prop<NodeItem *> nodeitem(G.Set(tvertex()),PROP_CANVAS_ITEM);
      short vcol=0;  G.vcolor.getinit(vcol);
      NodeItem * node;
      // Find a vertex of the subgraph
      tvertex mv = 0;
      tvertex v;
      for(v = 1; v <= G.nv();v++)
          {node =(NodeItem *)nodeitem[v];
          if(G.vcolor[node->v] != vcol)continue;
          else {mv = v;break;}
          }
      if(!mv)return;
      double prev_x = G.vcoord[mv].x();
      double prev_y = G.vcoord[mv].y();
      ToGrid(mv);
      double dx =  G.vcoord[mv].x() - prev_x;
      double dy =  G.vcoord[mv].y() - prev_y;
      G.vcoord[mv].x() = prev_x;
      G.vcoord[mv].y() = prev_y;
      for(v = 1;v <= G.nv();v++)
          {node =(NodeItem *)nodeitem[v];
          if(G.vcolor[node->v] != vcol)continue;
          node->moveBy(dx,-dy);
          }
      UpdateSizeGrid();
      PrintSizeGrid();
      return;
      }
  if(gwp->curs_item)// end creating an edge
      {GeometricGraph & G = *(gwp->pGG);
      Prop<EdgeItem *> edgeitem(G.Set(tedge()),PROP_CANVAS_ITEM);
      Prop<NodeItem *> nodeitem(G.Set(tvertex()),PROP_CANVAS_ITEM);
      NodeItem* node;
      EdgeItem *edge;
      tvertex v1,v2;
      // Reset the color of starting vertex
      v1 = gwp->curs_item->v;
      node = (NodeItem *)(nodeitem[v1]); node->SetColor(color[G.vcolor[v1]]);
      QPoint p(event->pos()); 
      ToGrid(p);
      int rtt = FindItem(p,node,edge);
      v2 = (rtt != node_rtti) ? 0 : node->v;
      if(rtt != node_rtti) //create a vertex
          {int h = (int)gwp->canvas->height();
          Tpoint pp((double)p.x(),(double)(h - p.y()));
          v2 = G.NewVertex(pp);ToGrid(v2);
          nodeitem[v2] = CreateNodeItem(v2,gwp);
          mywindow->mouse_actions->ButtonUndoGrid->setDisabled(true);
          if(IsGrid)UpdateSizeGrid();
          }
      else
          v2 = node->v;
      if(v1 != v2) // Create an edge 
          {tedge e = G.NewEdge(v1,v2);
          edgeitem[e] = CreateEdgeItem(e,gwp);
          }
      delete gwp->curs_item;      gwp->curs_item = 0;
      mywindow->information();// Informations
      if(v1 == v2) // We have created a vertex
          PrintSizeGrid();
      return;
      }
  }