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]); |