graph_displayer_canvas-event.cc
branchgui
changeset 68 1a27576aa199
parent 65 1b8e20c04704
child 69 6bb290b67e19
equal deleted inserted replaced
23:a210ce345a95 24:725495fb4ca0
    30 	  }
    30 	  }
    31 	case EDGE_MAP_EDIT:
    31 	case EDGE_MAP_EDIT:
    32 	  //has to do the same thing as in the case of NODE_MAP_EDIT
    32 	  //has to do the same thing as in the case of NODE_MAP_EDIT
    33 	case NODE_MAP_EDIT:
    33 	case NODE_MAP_EDIT:
    34 	  {
    34 	  {
    35 	    GdkEvent * generated=new GdkEvent();
       
    36 	    generated->type=GDK_KEY_PRESS;
       
    37 	    ((GdkEventKey*)generated)->keyval=GDK_KP_Enter;
       
    38 	    entryWidgetChangeHandler(generated);
       
    39 	    entrywidget.hide();
       
    40 	    break;
    35 	    break;
    41 	  }
    36 	  }
    42 	default:
    37 	default:
    43 	  break;
    38 	  break;
    44 	}
    39 	}
   546 }
   541 }
   547 
   542 
   548 bool GraphDisplayerCanvas::edgeMapEditEventHandler(GdkEvent* e)
   543 bool GraphDisplayerCanvas::edgeMapEditEventHandler(GdkEvent* e)
   549 {
   544 {
   550   if(actual_tool==EDGE_MAP_EDIT)
   545   if(actual_tool==EDGE_MAP_EDIT)
       
   546   {
       
   547     switch(e->type)
   551     {
   548     {
   552       switch(e->type)
   549       case GDK_BUTTON_PRESS:
   553 	{
   550         {
   554 	case GDK_KEY_PRESS:
   551           //for determine, whether it was an edge
   555 	  //for Escape or Enter hide the displayed widget
   552           Edge clicked_edge=INVALID;
   556 	  {
   553 
   557 	    nodeMapEditEventHandler(e);
   554           window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
   558 	    break;
   555           active_item=(get_item_at(clicked_x, clicked_y));
   559 	  }
   556 
   560 	case GDK_BUTTON_PRESS:
   557           //find the activated item between texts
   561 	  //If the click happened on an edge we place the entrywidget there and fill in the value of the activated map at that edge.
   558           for (EdgeIt i(mapstorage.graph); i!=INVALID; ++i)
   562 	  {
   559           {
   563 	    //for determine, whether it was an edge
   560             //at the same time only one can be active
   564 	    Edge clicked_edge=INVALID;
   561             if(edgetextmap[i]==active_item)
   565 
   562             {
   566 	    //find the activated item between texts
   563               clicked_edge=i;
   567             window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
   564             }
   568             active_item=(get_item_at(clicked_x, clicked_y));
   565           }
   569 	    for (EdgeIt i(mapstorage.graph); i!=INVALID; ++i)
   566 
   570 	      {
   567           //if it was not between texts, search for it between edges
   571 		if(edgetextmap[i]==active_item)
   568           if(clicked_edge==INVALID)
   572 		  {
   569           {
   573 		    clicked_edge=i;
   570             for (EdgeIt i(mapstorage.graph); i!=INVALID; ++i)
   574 		  }
   571             {
   575 	      }
   572               //at the same time only one can be active
   576 
   573               if((edgesmap[i]==active_item)||(edgetextmap[i]==active_item))
   577 	    //if it was not between texts, search for it between edges
   574               {
   578 	    if(clicked_edge==INVALID)
   575                 clicked_edge=i;
   579 	      {
   576               }
   580 		for (EdgeIt i(mapstorage.graph); i!=INVALID; ++i)
   577             }
   581 		  {
   578           }
   582 		    //at the same time only one can be active
   579  
   583 		    if((edgesmap[i]==active_item)||(edgetextmap[i]==active_item))
   580           //if it was really an edge...
   584 		      {
   581           if(clicked_edge!=INVALID)
   585 			clicked_edge=i;
   582           {
   586 		      }
   583             // the id map is not editable
   587 		  }
   584             if (edgemap_to_edit == "id") return 0;
   588 	      }
   585 
   589 	    //if it was really an edge...
   586             //and there is activated map
   590 	    if(clicked_edge!=INVALID)
   587             if(edgetextmap[clicked_edge]->property_text().get_value()!="")
   591 	      {
   588             {
   592                 // the id map is not editable
   589               //activate the general variable for it
   593                 if (edgemap_to_edit == "id") return 0;
   590               active_edge=clicked_edge;
   594 
   591 
   595 		//If there is already edited edge, it has to be saved first
   592               //create a dialog
   596 		if(entrywidget.is_visible())
   593               Gtk::Dialog dialog("Edit value", *parentwin, true);
   597 		  {
   594               dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
   598 		    GdkEvent * generated=new GdkEvent();
   595               dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_ACCEPT);
   599 		    generated->type=GDK_KEY_PRESS;
   596               Gtk::VBox* vbox = dialog.get_vbox();
   600 		    ((GdkEventKey*)generated)->keyval=GDK_KP_Enter;
   597               Gtk::Adjustment adj(
   601 		    entryWidgetChangeHandler(generated);
   598                   (*mapstorage.edgemap_storage[edgemap_to_edit])[active_edge],
   602 		  }
   599                   -1000000.0,
   603 		//If the previous value could be saved, we can go further, otherwise not
   600                   1000000.0,
   604 		if(!entrywidget.is_visible())
   601                   1.0, 5.0, 0.0);
   605 		  {
   602               //TODO: find out why doesn't it work with
   606 		    //and there is activated map
   603               //numeric_limits<double>::min/max
   607 		    if(edgetextmap[clicked_edge]->property_text().get_value()!="")
   604               Gtk::SpinButton spin(adj);
   608 		      {
   605               spin.set_numeric(true);
   609 			//activate the general variable for it
   606               spin.set_digits(4);
   610 			active_edge=clicked_edge;
   607               vbox->add(spin);
   611 			//delete visible widget if there is
   608               spin.show();
   612 			if(canvasentrywidget)
   609               switch (dialog.run())
   613 			  {
   610               {
   614 			    delete(canvasentrywidget);
   611                 case Gtk::RESPONSE_NONE:
   615 			  }
   612                 case Gtk::RESPONSE_CANCEL:
   616 
   613                   break;
   617 			//initialize the entry
   614                 case Gtk::RESPONSE_ACCEPT:
   618 			entrywidget.show();
   615                   double new_value = spin.get_value();
   619 
   616                   (*mapstorage.edgemap_storage[edgemap_to_edit])[active_edge] =
   620 			//fill in the correct value
   617                     new_value;
   621 			entrywidget.set_text(edgetextmap[active_edge]->property_text().get_value());
   618                   std::ostringstream ostr;
   622 
   619                   ostr << new_value;
   623 			//replace and resize the entry to the activated edge and put it in a Canvas::Widget to be able to display it on gdc
   620                   edgetextmap[active_edge]->property_text().set_value(
   624 			xy<double> entry_coos;
   621                       ostr.str());
   625 			entry_coos.x=(edgetextmap[active_edge])->property_x().get_value();
   622                   //mapwin.updateEdge(active_edge);
   626 			entry_coos.x-=edgetextmap[active_edge]->property_text_width().get_value()/2;
   623                   mapwin.updateEdge(Edge(INVALID));
   627 			entry_coos.y=(edgetextmap[active_edge])->property_y().get_value();
   624               }
   628 			entry_coos.y-=edgetextmap[active_edge]->property_text_height().get_value()*1.5/2;
   625             }
   629 			canvasentrywidget=new Gnome::Canvas::Widget(displayed_graph, entry_coos.x, entry_coos.y, entrywidget);
   626           }
   630 			canvasentrywidget->property_width().set_value(edgetextmap[active_edge]->property_text_width().get_value()*4);
   627           break;
   631 			canvasentrywidget->property_height().set_value(edgetextmap[active_edge]->property_text_height().get_value()*1.5);
   628         }
   632 
   629       default:
   633 			//setting the focus to newly created widget
   630         break;
   634 			parentwin->set_focus(entrywidget);
       
   635 			parentwin->activate_focus();
       
   636 		      }
       
   637 		  }
       
   638 	      }
       
   639 	    //if it was not an edge...
       
   640 	    else
       
   641 	      {
       
   642 		//In this case the click did not happen on an edge
       
   643 		//if there is visible entry we save the value in it
       
   644 		//we pretend like an Enter was presse din the Entry widget
       
   645 		GdkEvent * generated=new GdkEvent();
       
   646 		generated->type=GDK_KEY_PRESS;
       
   647 		((GdkEventKey*)generated)->keyval=GDK_KP_Enter;
       
   648 		entryWidgetChangeHandler(generated);
       
   649 	      }
       
   650 	    break;
       
   651 	  }
       
   652 	default:
       
   653 	  break;
       
   654 	}
       
   655     }
   631     }
       
   632   }
   656   return false;  
   633   return false;  
   657 }
   634 }
   658 
   635 
   659 bool GraphDisplayerCanvas::nodeMapEditEventHandler(GdkEvent* e)
   636 bool GraphDisplayerCanvas::nodeMapEditEventHandler(GdkEvent* e)
   660 {
   637 {
   661   if(actual_tool==NODE_MAP_EDIT)
   638   if(actual_tool==NODE_MAP_EDIT)
       
   639   {
       
   640     switch(e->type)
   662     {
   641     {
   663       switch(e->type)
   642       case GDK_BUTTON_PRESS:
   664 	{
   643         {
   665 	case GDK_KEY_PRESS:
   644           //for determine, whether it was a node
   666 	  //for Escape or Enter hide the displayed widget
   645           Node clicked_node=INVALID;
   667 	  {
   646 
   668 	    switch(((GdkEventKey*)e)->keyval)
   647           window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
   669 	      {
   648           active_item=(get_item_at(clicked_x, clicked_y));
   670 	      case GDK_Escape:
   649 
   671 		entrywidget.hide();
   650           //find the activated item between texts
   672 		break;
   651           for (NodeIt i(mapstorage.graph); i!=INVALID; ++i)
   673 	      case GDK_Return:
   652           {
   674 	      case GDK_KP_Enter:
   653             //at the same time only one can be active
   675 		entrywidget.hide();
   654             if(nodetextmap[i]==active_item)
   676 		break;
   655             {
   677 	      default:
   656               clicked_node=i;
   678 		break;
   657             }
   679 	      }
   658           }
   680   
   659 
   681 	    break;
   660           //if there was not, search for it between nodes
   682 	  }
   661           if(clicked_node==INVALID)
   683 	case GDK_BUTTON_PRESS:
   662           {
   684 	  //If the click happened on an edge we place the entrywidget there and fill in the value of the activated map at that edge.
   663             for (NodeIt i(mapstorage.graph); i!=INVALID; ++i)
   685 	  {
   664             {
   686 	    //for determine, whether it was a node
   665               //at the same time only one can be active
   687 	    Node clicked_node=INVALID;
   666               if(nodesmap[i]==active_item)
   688 
   667               {
   689 	    //find the activated item between texts
   668                 clicked_node=i;
   690 	    active_item=(get_item_at(e->button.x, e->button.y));
   669               }
   691 	    for (NodeIt i(mapstorage.graph); i!=INVALID; ++i)
   670             }
   692 	      {
   671           }
   693 		//at the same time only one can be active
   672 
   694 		if(nodetextmap[i]==active_item)
   673           //if it was really a node...
   695 		  {
   674           if(clicked_node!=INVALID)
   696 		    clicked_node=i;
   675           {
   697 		  }
   676             // the id map is not editable
   698 	      }
   677             if (nodemap_to_edit == "id") return 0;
   699 
   678 
   700 	    //if there was not, search for it between nodes
   679             //and there is activated map
   701 	    if(clicked_node==INVALID)
   680             if(nodetextmap[clicked_node]->property_text().get_value()!="")
   702 	      {
   681             {
   703 		window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
   682               //activate the general variable for it
   704 		active_item=(get_item_at(clicked_x, clicked_y));
   683               active_node=clicked_node;
   705 
   684 
   706 		for (NodeIt i(mapstorage.graph); i!=INVALID; ++i)
   685               //create a dialog
   707 		  {
   686               Gtk::Dialog dialog("Edit value", *parentwin, true);
   708 		    //at the same time only one can be active
   687               dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
   709 		    if(nodesmap[i]==active_item)
   688               dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_ACCEPT);
   710 		      {
   689               Gtk::VBox* vbox = dialog.get_vbox();
   711 			clicked_node=i;
   690               Gtk::Adjustment adj(
   712 		      }
   691                   (*mapstorage.nodemap_storage[nodemap_to_edit])[active_node],
   713 		  }
   692                   -1000000.0,
   714 	      }
   693                   1000000.0,
   715 	    //if it was really an edge...
   694                   1.0, 5.0, 0.0);
   716 	    if(clicked_node!=INVALID)
   695               //TODO: find out why doesn't it work with
   717 	      {
   696               //numeric_limits<double>::min/max
   718                 // the id map is not editable
   697               Gtk::SpinButton spin(adj);
   719                 if (nodemap_to_edit == "id") return 0;
   698               spin.set_numeric(true);
   720 		//If there is already edited edge, it has to be saved first
   699               spin.set_digits(4);
   721 		if(entrywidget.is_visible())
   700               vbox->add(spin);
   722 		  {
   701               spin.show();
   723 		    GdkEvent * generated=new GdkEvent();
   702               switch (dialog.run())
   724 		    generated->type=GDK_KEY_PRESS;
   703               {
   725 		    ((GdkEventKey*)generated)->keyval=GDK_KP_Enter;
   704                 case Gtk::RESPONSE_NONE:
   726 		    entryWidgetChangeHandler(generated);
   705                 case Gtk::RESPONSE_CANCEL:
   727 		  }
   706                   break;
   728 		//If the previous value could be saved, we can go further, otherwise not
   707                 case Gtk::RESPONSE_ACCEPT:
   729 		if(!entrywidget.is_visible())
   708                   double new_value = spin.get_value();
   730 		  {
   709                   (*mapstorage.nodemap_storage[nodemap_to_edit])[active_node] =
   731 		    //and there is activated map
   710                     new_value;
   732 		    if(nodetextmap[clicked_node]->property_text().get_value()!="")
   711                   std::ostringstream ostr;
   733 		      {
   712                   ostr << new_value;
   734 			//activate the general variable for it
   713                   nodetextmap[active_node]->property_text().set_value(
   735 			active_node=clicked_node;
   714                       ostr.str());
   736 			//delete visible widget if there is
   715                   //mapwin.updateNode(active_node);
   737 			if(canvasentrywidget)
   716                   mapwin.updateNode(Node(INVALID));
   738 			  {
   717               }
   739 			    delete(canvasentrywidget);
   718             }
   740 			  }
   719           }
   741 
   720           break;
   742 			//initialize the entry
   721         }
   743 			entrywidget.show();
   722       default:
   744 
   723         break;
   745 			//fill in the correct value
       
   746 			entrywidget.set_text(nodetextmap[active_node]->property_text().get_value());
       
   747 
       
   748 			//replace and resize the entry to the activated node and put it in a Canvas::Widget to be able to display it on gdc
       
   749 			xy<double> entry_coos;
       
   750 			entry_coos.x=(nodetextmap[active_node])->property_x().get_value();
       
   751 			entry_coos.x-=nodetextmap[active_node]->property_text_width().get_value()/2;
       
   752 			entry_coos.y=(nodetextmap[active_node])->property_y().get_value();
       
   753 			entry_coos.y-=nodetextmap[active_node]->property_text_height().get_value()*1.5/2;
       
   754 			canvasentrywidget=new Gnome::Canvas::Widget(displayed_graph, entry_coos.x, entry_coos.y, entrywidget);
       
   755 			canvasentrywidget->property_width().set_value(nodetextmap[active_node]->property_text_width().get_value()*4);
       
   756 			canvasentrywidget->property_height().set_value(nodetextmap[active_node]->property_text_height().get_value()*1.5);
       
   757 		      }
       
   758 		  }
       
   759 	      }
       
   760 	    //if it was not an edge...
       
   761 	    else
       
   762 	      {
       
   763 		//In this case the click did not happen on an edge
       
   764 		//if there is visible entry we save the value in it
       
   765 		//we pretend like an Enter was presse din the Entry widget
       
   766 		GdkEvent * generated=new GdkEvent();
       
   767 		generated->type=GDK_KEY_PRESS;
       
   768 		((GdkEventKey*)generated)->keyval=GDK_KP_Enter;
       
   769 		entryWidgetChangeHandler(generated);
       
   770 	      }
       
   771 	    break;
       
   772 	  }
       
   773 	default:
       
   774 	  break;
       
   775 	}
       
   776     }
   724     }
       
   725   }
   777   return false;  
   726   return false;  
   778 }
       
   779 
       
   780 bool GraphDisplayerCanvas::entryWidgetChangeHandler(GdkEvent* e)
       
   781 {
       
   782   if(entrywidget.is_visible())
       
   783     {
       
   784       if(e->type==GDK_KEY_PRESS)
       
   785 	{
       
   786 	  switch(((GdkEventKey*)e)->keyval)
       
   787 	    {
       
   788 	    case GDK_Escape:
       
   789 	      entrywidget.hide();
       
   790 	      break;
       
   791 	    case GDK_KP_Enter:
       
   792 	    case GDK_Return:
       
   793 	      {
       
   794 		//these variables check whether the text in the entry is valid
       
   795 		bool valid_double=true;
       
   796 		int point_num=0;
       
   797 
       
   798 		//getting the value from the entry and converting it to double
       
   799 		Glib::ustring mapvalue_str = entrywidget.get_text();
       
   800 
       
   801 		char * mapvalue_ch=new char [mapvalue_str.length()];
       
   802 		for(int i=0;i<(int)(mapvalue_str.length());i++)
       
   803 		  {
       
   804 		    if(((mapvalue_str[i]<'0')||(mapvalue_str[i]>'9'))&&(mapvalue_str[i]!='.'))
       
   805 		      {
       
   806 			valid_double=false;
       
   807 		      }
       
   808 		    else
       
   809 		      {
       
   810 			if(mapvalue_str[i]=='.')
       
   811 			  {
       
   812 			    point_num++;
       
   813 			  }
       
   814 		      }
       
   815 		    mapvalue_ch[i]=mapvalue_str[i];
       
   816 		  }
       
   817   	      
       
   818 		//if the text in the entry was correct
       
   819 		if((point_num<=1)&&(valid_double))
       
   820 		  {
       
   821 		    double mapvalue_d=atof(mapvalue_ch);
       
   822 
       
   823 		    //reconvert the double to string for the correct format
       
   824 		    std::ostringstream ostr;
       
   825 		    ostr << mapvalue_d;
       
   826 
       
   827 		    //save the value to the correct place
       
   828 		    switch(actual_tool)
       
   829 		      {
       
   830 		      case EDGE_MAP_EDIT:
       
   831 			edgetextmap[active_edge]->property_text().set_value(ostr.str());
       
   832 			(*(mapstorage.edgemap_storage)[edgemap_to_edit])[active_edge]=mapvalue_d;
       
   833 			mapwin.updateEdge(active_edge);
       
   834 			break;
       
   835 		      case NODE_MAP_EDIT:
       
   836 			nodetextmap[active_node]->property_text().set_value(ostr.str());
       
   837 			(*(mapstorage.nodemap_storage)[nodemap_to_edit])[active_node]=mapvalue_d;
       
   838 			mapwin.updateNode(active_node);
       
   839 			break;
       
   840 		      default:
       
   841 			break;
       
   842 		      }
       
   843 		    entrywidget.hide();
       
   844 		  }
       
   845 		//the text in the entry was not correct for a double
       
   846 		else
       
   847 		  {
       
   848 		    std::cerr << "ERROR: only handling of double values is implemented yet!" << std::endl;
       
   849 		  }
       
   850 
       
   851 		break;
       
   852 	      }
       
   853 	    default:
       
   854 	      break;
       
   855 	    }
       
   856 	}
       
   857     }
       
   858   return false;
       
   859 }
   727 }
   860 
   728 
   861 void GraphDisplayerCanvas::deleteItem(Node node_to_delete)
   729 void GraphDisplayerCanvas::deleteItem(Node node_to_delete)
   862 {
   730 {
   863   delete(nodetextmap[node_to_delete]);
   731   delete(nodetextmap[node_to_delete]);