# HG changeset patch # User hegyi # Date 1118692173 0 # Node ID 1db7a6dd17f8dc514dcabd8856b59fb54c3e64b8 # Parent 09b2a893fc9dbabdd0601d6af7cc89cbd22c6f60 Known bugs are eliminated from gui, and new ones are created by changing tool selectors to special radiobuttons, and by adding edgecreation-canceller function (right-click on any group element). diff -r 09b2a893fc9d -r 1db7a6dd17f8 edit_win.cc --- a/edit_win.cc Mon Jun 13 10:30:08 2005 +0000 +++ b/edit_win.cc Mon Jun 13 19:49:33 2005 +0000 @@ -14,12 +14,23 @@ { set_title(title); set_default_size(200, 50); - + set_keep_above(true); signal_key_press_event().connect(sigc::mem_fun(*this, &EditWin::close_if_escape_is_pressed)); + //buttons array + buttons=new (Gtk::RadioButton *) [TOOL_NUM]; + for(int i=0;iget_group(); + //New node button - button=new Gtk::Button("New Node"); - button->signal_clicked().connect + buttons[CREATE_NODE]=new Gtk::RadioButton("New Node"); + buttons[CREATE_NODE]->set_mode(false); + buttons[CREATE_NODE]->set_group(group); + buttons[CREATE_NODE]->signal_clicked().connect ( sigc::bind ( @@ -27,11 +38,13 @@ 1 ) ); - table.attach(*button,0,1,0,1); + table.attach(*buttons[CREATE_NODE],0,1,0,1); //New edge button - button=new Gtk::Button("New Edge"); - button->signal_clicked().connect + buttons[CREATE_EDGE]=new Gtk::RadioButton("New Edge"); + buttons[CREATE_EDGE]->set_mode(false); + buttons[CREATE_EDGE]->set_group(group); + buttons[CREATE_EDGE]->signal_clicked().connect ( sigc::bind ( @@ -39,11 +52,13 @@ 2 ) ); - table.attach(*button,1,2,0,1); + table.attach(*buttons[CREATE_EDGE],1,2,0,1); //Move button - button=new Gtk::Button("Move"); - button->signal_clicked().connect + buttons[MOVE]=new Gtk::RadioButton("Move"); + buttons[MOVE]->set_mode(false); + buttons[MOVE]->set_group(group); + buttons[MOVE]->signal_clicked().connect ( sigc::bind ( @@ -51,8 +66,8 @@ 0 ) ); - table.attach(*button,0,1,1,2); - + table.attach(*buttons[MOVE],0,1,1,2); + add(table); show_all_children(); diff -r 09b2a893fc9d -r 1db7a6dd17f8 edit_win.h --- a/edit_win.h Mon Jun 13 10:30:08 2005 +0000 +++ b/edit_win.h Mon Jun 13 19:49:33 2005 +0000 @@ -15,15 +15,15 @@ { protected: ///The \ref GraphDisplayerCanvas on which the graph will be drawn. - ///It has to be known for this class, because - ///when a map assigned to a certain attribute - ///a function of the \ref GraphDisplayerCanvas will be called. + ///It has to be known for this class, because the appropriate + //callback function for each tool is implemented in that class GraphDisplayerCanvas & gdc; + ///Table that holds the tools. Gtk::Table table; - Gtk::Label * label; - Gtk::Button * button; + ///these buttons are RadioButtons with classic look + Gtk::RadioButton ** buttons; public: ///Constructor of EditWin creates the widgets shown in EditWin. diff -r 09b2a893fc9d -r 1db7a6dd17f8 graph_displayer_canvas.cc --- a/graph_displayer_canvas.cc Mon Jun 13 10:30:08 2005 +0000 +++ b/graph_displayer_canvas.cc Mon Jun 13 19:49:33 2005 +0000 @@ -6,6 +6,9 @@ actual_handler=displayed_graph.signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::create_edge_event_handler), false); + active_node=INVALID; + active_edge=INVALID; + //set_center_scroll_region(true); //first edges are drawn, to hide joining with nodes later @@ -310,9 +313,12 @@ case MOVE: actual_handler=displayed_graph.signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::move_event_handler), false); break; + + //it has to assigned to canvas, because all the canvas has to be monitored, not only the elements of the already drawn group case CREATE_NODE: actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::create_node_event_handler), false); break; + case CREATE_EDGE: actual_handler=displayed_graph.signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::create_edge_event_handler), false); break; @@ -343,11 +349,12 @@ case GDK_BUTTON_RELEASE: isbutton=false; active_item=NULL; + active_node=INVALID; updateScrollRegion(); break; case GDK_MOTION_NOTIFY: - //we only have to do sg. if the mouse button is pressed - if(isbutton) + //we only have to do sg. if the mouse button is pressed AND the click was on a node that was found in the set of nodes + if(active_node!=INVALID) { //new coordinates will be the old values, //because the item will be moved to the @@ -416,6 +423,8 @@ { switch(e->type) { + + //draw the new node in red at the clicked place case GDK_BUTTON_PRESS: isbutton=true; @@ -429,6 +438,8 @@ *(nodesmap[active_node]) << Gnome::Canvas::Properties::outline_color("black"); (nodesmap[active_node])->show(); break; + + //move the new node case GDK_MOTION_NOTIFY: { double world_motion_x, world_motion_y; @@ -440,10 +451,13 @@ move_event_handler(generated); break; } + + //finalize the new node case GDK_BUTTON_RELEASE: isbutton=false; *active_item << Gnome::Canvas::Properties::fill_color("blue"); active_item=NULL; + active_node=INVALID; updateScrollRegion(); break; default: @@ -457,73 +471,111 @@ switch(e->type) { case GDK_BUTTON_PRESS: - if(!active_item) + //in edge creatino right button has special meaning + if(e->button.button!=3) { - //we mark the location of the event to be able to calculate parameters of dragging - clicked_x=e->button.x; - clicked_y=e->button.y; - active_item=(get_item_at(e->button.x, e->button.y)); - active_node=INVALID; - for (NodeIt i(g); i!=INVALID; ++i) + //there is not yet selected node + if(active_node==INVALID) { - if(nodesmap[i]==active_item) + //we mark the location of the event to be able to calculate parameters of dragging + clicked_x=e->button.x; + clicked_y=e->button.y; + active_item=(get_item_at(e->button.x, e->button.y)); + active_node=INVALID; + for (NodeIt i(g); i!=INVALID; ++i) { - active_node=i; + if(nodesmap[i]==active_item) + { + active_node=i; + } + } + //the clicked item is really a node + if(active_node!=INVALID) + { + *(nodesmap[active_node]) << Gnome::Canvas::Properties::fill_color("red"); + isbutton=true; + } + //clicked item was not a node. It could be e.g. edge. + else + { + active_item=NULL; } } - *(nodesmap[active_node]) << Gnome::Canvas::Properties::fill_color("red"); - isbutton=true; - } - else - { - target_item=(get_item_at(e->button.x, e->button.y)); - Graph::NodeIt target_node=INVALID; - for (NodeIt i(g); i!=INVALID; ++i) + //we only have to do sg. if the mouse button + // is pressed already once AND the click was + // on a node that was found in the set of + //nodes, and now we only search for the second + //node + else { - if(nodesmap[i]==target_item) + target_item=(get_item_at(e->button.x, e->button.y)); + Graph::NodeIt target_node=INVALID; + for (NodeIt i(g); i!=INVALID; ++i) { - target_node=i; + if(nodesmap[i]==target_item) + { + target_node=i; + } + } + //the clicked item is a node, the edge can be drawn + if(target_node!=INVALID) + { + *(nodesmap[target_node]) << Gnome::Canvas::Properties::fill_color("red"); + + //creating new edge + active_edge=EdgeIt(g,g.addEdge(active_node, target_node)); + + //calculating coordinates of new edge + Gnome::Canvas::Points coos; + double x1, x2, y1, y2; + + active_item->get_bounds(x1, y1, x2, y2); + coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2)); + + target_item->get_bounds(x1, y1, x2, y2); + coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2)); + + //drawing new edge + edgesmap[active_edge]=new Gnome::Canvas::Line(displayed_graph, coos); + *(edgesmap[active_edge]) << Gnome::Canvas::Properties::fill_color("green"); + edgesmap[active_edge]->property_width_pixels().set_value(10); + + //redraw nodes to blank terminations of the new edge + target_item->raise_to_top(); + active_item->raise_to_top(); + + //initializing edge-text as well, to empty string + edgesmap[active_edge]->get_bounds(x1, y1, x2, y2); + edgetextmap[active_edge]=new Gnome::Canvas::Text(displayed_graph,(x1+x2)/2, (y1+y2)/2, ""); + edgetextmap[active_edge]->property_fill_color().set_value("black"); + } + //clicked item was not a node. it could be an e.g. edge. we do not deal with it furthermore. + else + { + target_item=NULL; } } - *(nodesmap[target_node]) << Gnome::Canvas::Properties::fill_color("red"); - - //creating new edge - // Graph::Edge new_edge=g.addEdge(active_node, target_node); - active_edge=EdgeIt(g,g.addEdge(active_node, target_node)); - - //calculating coordinates of new edge - Gnome::Canvas::Points coos; - double x1, x2, y1, y2; - - active_item->get_bounds(x1, y1, x2, y2); - coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2)); - - target_item->get_bounds(x1, y1, x2, y2); - coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2)); - - //drawing new edge - edgesmap[active_edge]=new Gnome::Canvas::Line(displayed_graph, coos); - *(edgesmap[active_edge]) << Gnome::Canvas::Properties::fill_color("green"); - edgesmap[active_edge]->property_width_pixels().set_value(10); - - //redraw nodes to blank terminations of the new edge - target_item->raise_to_top(); - active_item->raise_to_top(); - - //initializing edge-text as well, to empty string - edgesmap[active_edge]->get_bounds(x1, y1, x2, y2); - edgetextmap[active_edge]=new Gnome::Canvas::Text(displayed_graph,(x1+x2)/2, (y1+y2)/2, ""); - edgetextmap[active_edge]->property_fill_color().set_value("black"); } break; case GDK_BUTTON_RELEASE: isbutton=false; - if(target_item) + //we clear settings in two cases + //1: the edge is ready (target_item has valid value) + //2: the edge creation is cancelled with right button + if((target_item)||(e->button.button==3)) { - *active_item << Gnome::Canvas::Properties::fill_color("blue"); - *target_item << Gnome::Canvas::Properties::fill_color("blue"); - active_item=NULL; - target_item=NULL; + if(active_item) + { + *active_item << Gnome::Canvas::Properties::fill_color("blue"); + active_item=NULL; + } + if(target_item) + { + *target_item << Gnome::Canvas::Properties::fill_color("blue"); + target_item=NULL; + } + active_node=INVALID; + active_edge=INVALID; } break; default: