gui/graph_displayer_canvas-event.cc
author ladanyi
Fri, 26 Aug 2005 07:35:23 +0000
changeset 1648 dd8672338691
parent 1647 d5dc956393b2
child 1651 e40c41eae31f
permissions -rwxr-xr-x
- use Gtk::Dialog to set the new values of edge and node maps
- update all edges/nodes when editing a map so that edge widths and node
sizes change properly
- coordinate maps are no longer selectable in the maps window
ladanyi@1606
     1
#include "graph_displayer_canvas.h"
ladanyi@1606
     2
#include "broken_edge.h"
alpar@1632
     3
#include <cmath>
hegyi@1510
     4
hegyi@1510
     5
hegyi@1510
     6
bool GraphDisplayerCanvas::on_expose_event(GdkEventExpose *event)
hegyi@1510
     7
{
hegyi@1510
     8
  Gnome::Canvas::CanvasAA::on_expose_event(event);
hegyi@1510
     9
  //usleep(10000);
hegyi@1510
    10
  //rezoom();
hegyi@1510
    11
  return true;
hegyi@1510
    12
}
hegyi@1510
    13
hegyi@1510
    14
void GraphDisplayerCanvas::changeEditorialTool(int newtool)
hegyi@1510
    15
{
hegyi@1562
    16
  if(actual_tool!=newtool)
hegyi@1562
    17
    {
hegyi@1510
    18
hegyi@1562
    19
      actual_handler.disconnect();
hegyi@1510
    20
hegyi@1562
    21
      switch(actual_tool)
hegyi@1562
    22
	{
hegyi@1562
    23
	case CREATE_EDGE:
hegyi@1562
    24
	  {
hegyi@1562
    25
	    GdkEvent * generated=new GdkEvent();
hegyi@1562
    26
	    generated->type=GDK_BUTTON_RELEASE;
hegyi@1562
    27
	    generated->button.button=3;
hegyi@1562
    28
	    createEdgeEventHandler(generated);      
hegyi@1562
    29
	    break;
hegyi@1562
    30
	  }
hegyi@1562
    31
	case EDGE_MAP_EDIT:
hegyi@1579
    32
	  //has to do the same thing as in the case of NODE_MAP_EDIT
hegyi@1579
    33
	case NODE_MAP_EDIT:
hegyi@1579
    34
	  {
hegyi@1579
    35
	    break;
hegyi@1579
    36
	  }
hegyi@1562
    37
	default:
hegyi@1562
    38
	  break;
hegyi@1562
    39
	}
hegyi@1510
    40
hegyi@1562
    41
      active_item=NULL; 
hegyi@1562
    42
      target_item=NULL; 
hegyi@1562
    43
      active_edge=INVALID;	
hegyi@1562
    44
      active_node=INVALID;	
hegyi@1551
    45
hegyi@1510
    46
hegyi@1562
    47
      actual_tool=newtool;
hegyi@1562
    48
  
hegyi@1562
    49
      switch(newtool)
hegyi@1562
    50
	{
hegyi@1562
    51
	case MOVE:
hegyi@1562
    52
	  actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::moveEventHandler), false);
hegyi@1562
    53
	  break;
hegyi@1510
    54
hegyi@1562
    55
	case CREATE_NODE:
hegyi@1562
    56
	  actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::createNodeEventHandler), false);
hegyi@1562
    57
	  break;
hegyi@1510
    58
hegyi@1562
    59
	case CREATE_EDGE:
hegyi@1562
    60
	  actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::createEdgeEventHandler), false);
hegyi@1562
    61
	  break;
hegyi@1510
    62
hegyi@1562
    63
	case ERASER:
hegyi@1562
    64
	  actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::eraserEventHandler), false);
hegyi@1562
    65
	  break;
hegyi@1550
    66
hegyi@1562
    67
	case EDGE_MAP_EDIT:
hegyi@1562
    68
	  grab_focus();
hegyi@1562
    69
	  actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::edgeMapEditEventHandler), false);
hegyi@1562
    70
	  break;
hegyi@1550
    71
hegyi@1562
    72
	case NODE_MAP_EDIT:
hegyi@1562
    73
	  actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::nodeMapEditEventHandler), false);
hegyi@1562
    74
	  break;
hegyi@1562
    75
hegyi@1562
    76
	default:
hegyi@1562
    77
	  break;
hegyi@1562
    78
	}
hegyi@1510
    79
    }
hegyi@1510
    80
}
hegyi@1510
    81
hegyi@1524
    82
int GraphDisplayerCanvas::getActualTool()
hegyi@1510
    83
{
hegyi@1510
    84
  return actual_tool;
hegyi@1510
    85
}
hegyi@1510
    86
hegyi@1524
    87
bool GraphDisplayerCanvas::moveEventHandler(GdkEvent* e)
hegyi@1510
    88
{
hegyi@1510
    89
  switch(e->type)
hegyi@1510
    90
  {
hegyi@1510
    91
    case GDK_BUTTON_PRESS:
hegyi@1510
    92
      //we mark the location of the event to be able to calculate parameters of dragging
hegyi@1525
    93
      window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
hegyi@1525
    94
hegyi@1525
    95
      active_item=(get_item_at(clicked_x, clicked_y));
hegyi@1510
    96
      active_node=INVALID;
ladanyi@1606
    97
      for (NodeIt i(mapstorage.graph); i!=INVALID; ++i)
hegyi@1510
    98
	{
hegyi@1510
    99
	  if(nodesmap[i]==active_item)
hegyi@1510
   100
	    {
hegyi@1510
   101
	      active_node=i;
hegyi@1510
   102
	    }
hegyi@1510
   103
	}
hegyi@1510
   104
      switch(e->button.button)
hegyi@1510
   105
	{
hegyi@1510
   106
	case 3:      
hegyi@1510
   107
	  isbutton=3;
hegyi@1510
   108
	  break;
hegyi@1510
   109
	default:
hegyi@1510
   110
	  isbutton=1;
hegyi@1510
   111
	  break;
hegyi@1510
   112
	}
hegyi@1510
   113
      break;
hegyi@1510
   114
    case GDK_BUTTON_RELEASE:
hegyi@1510
   115
      isbutton=0;
hegyi@1510
   116
      active_item=NULL;
hegyi@1510
   117
      active_node=INVALID;
hegyi@1510
   118
      break;
hegyi@1510
   119
    case GDK_MOTION_NOTIFY:
hegyi@1510
   120
      //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
hegyi@1510
   121
      if(active_node!=INVALID)
hegyi@1510
   122
      {
ladanyi@1606
   123
        mapstorage.modified = true;
ladanyi@1606
   124
        mapstorage.coords.set(active_node, xy<double>(clicked_x, clicked_y));
hegyi@1510
   125
	//new coordinates will be the old values,
hegyi@1510
   126
	//because the item will be moved to the
hegyi@1510
   127
	//new coordinate therefore the new movement
hegyi@1510
   128
	//has to be calculated from here
hegyi@1510
   129
hegyi@1525
   130
	double new_x, new_y;
hegyi@1525
   131
hegyi@1525
   132
	window_to_world (e->motion.x, e->motion.y, new_x, new_y);
hegyi@1525
   133
hegyi@1525
   134
        double dx=new_x-clicked_x;
hegyi@1525
   135
        double dy=new_y-clicked_y;
hegyi@1510
   136
hegyi@1512
   137
	//repositioning node and its text
hegyi@1510
   138
        active_item->move(dx, dy);
hegyi@1512
   139
	nodetextmap[active_node]->move(dx, dy);
hegyi@1510
   140
hegyi@1525
   141
        clicked_x=new_x;
hegyi@1525
   142
        clicked_y=new_y;
hegyi@1510
   143
hegyi@1510
   144
	//all the edges connected to the moved point has to be redrawn
hegyi@1510
   145
        EdgeIt ei;
hegyi@1510
   146
ladanyi@1606
   147
        mapstorage.graph.firstOut(ei,active_node);
hegyi@1510
   148
ladanyi@1606
   149
        for(;ei!=INVALID;mapstorage.graph.nextOut(ei))
hegyi@1510
   150
        {
hegyi@1510
   151
            Gnome::Canvas::Points coos;
hegyi@1510
   152
            double x1, x2, y1, y2;
hegyi@1510
   153
ladanyi@1606
   154
            nodesmap[mapstorage.graph.source(ei)]->get_bounds(x1, y1, x2, y2);
hegyi@1510
   155
            coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
hegyi@1510
   156
ladanyi@1606
   157
            nodesmap[mapstorage.graph.target(ei)]->get_bounds(x1, y1, x2, y2);
hegyi@1510
   158
            coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
hegyi@1510
   159
hegyi@1510
   160
	    if(isbutton==3)
hegyi@1510
   161
	      {
hegyi@1524
   162
		edgesmap[ei]->setPoints(coos);
hegyi@1510
   163
	      }
hegyi@1510
   164
	    else
hegyi@1510
   165
	      {
hegyi@1524
   166
		edgesmap[ei]->setPoints(coos,true);
hegyi@1510
   167
	      }
hegyi@1510
   168
hegyi@1512
   169
	    //reposition of edgetext
hegyi@1524
   170
	    xy<double> text_pos=edgesmap[ei]->getArrowPos();
hegyi@1510
   171
	    text_pos+=(xy<double>(10,10));
hegyi@1510
   172
	    edgetextmap[ei]->property_x().set_value(text_pos.x);
hegyi@1510
   173
	    edgetextmap[ei]->property_y().set_value(text_pos.y);
hegyi@1510
   174
        }
hegyi@1510
   175
ladanyi@1606
   176
        mapstorage.graph.firstIn(ei,active_node);
ladanyi@1606
   177
        for(;ei!=INVALID;mapstorage.graph.nextIn(ei))
hegyi@1510
   178
        {
hegyi@1510
   179
            Gnome::Canvas::Points coos;
hegyi@1510
   180
            double x1, x2, y1, y2;
hegyi@1510
   181
ladanyi@1606
   182
            nodesmap[mapstorage.graph.source(ei)]->get_bounds(x1, y1, x2, y2);
hegyi@1510
   183
            coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
hegyi@1510
   184
ladanyi@1606
   185
            nodesmap[mapstorage.graph.target(ei)]->get_bounds(x1, y1, x2, y2);
hegyi@1510
   186
            coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
hegyi@1510
   187
hegyi@1510
   188
	    if(isbutton==3)
hegyi@1510
   189
	      {
hegyi@1524
   190
		edgesmap[ei]->setPoints(coos);
hegyi@1510
   191
	      }
hegyi@1510
   192
	    else
hegyi@1510
   193
	      {
hegyi@1524
   194
		edgesmap[ei]->setPoints(coos,true);
hegyi@1510
   195
	      }
hegyi@1510
   196
hegyi@1524
   197
	    xy<double> text_pos=edgesmap[ei]->getArrowPos();
hegyi@1510
   198
	    text_pos+=(xy<double>(10,10));
hegyi@1510
   199
	    edgetextmap[ei]->property_x().set_value(text_pos.x);
hegyi@1510
   200
	    edgetextmap[ei]->property_y().set_value(text_pos.y);
hegyi@1510
   201
        }
hegyi@1510
   202
      }
hegyi@1510
   203
    default: break;
hegyi@1510
   204
  }
hegyi@1510
   205
hegyi@1525
   206
  return false;
hegyi@1510
   207
}
hegyi@1510
   208
hegyi@1524
   209
bool GraphDisplayerCanvas::createNodeEventHandler(GdkEvent* e)
hegyi@1510
   210
{
hegyi@1510
   211
  switch(e->type)
ladanyi@1645
   212
  {
ladanyi@1645
   213
    //move the new node
ladanyi@1645
   214
    case GDK_MOTION_NOTIFY:
ladanyi@1645
   215
      {
ladanyi@1645
   216
        GdkEvent * generated=new GdkEvent();
ladanyi@1645
   217
        generated->motion.x=e->motion.x;
ladanyi@1645
   218
        generated->motion.y=e->motion.y;
ladanyi@1645
   219
        generated->type=GDK_MOTION_NOTIFY;
ladanyi@1645
   220
        moveEventHandler(generated);      
ladanyi@1645
   221
        break;
ladanyi@1645
   222
      }
hegyi@1510
   223
ladanyi@1645
   224
    case GDK_BUTTON_RELEASE:
ladanyi@1606
   225
      mapstorage.modified = true;
ladanyi@1606
   226
hegyi@1510
   227
      isbutton=1;
hegyi@1510
   228
alpar@1643
   229
      active_node=mapstorage.graph.addNode();
hegyi@1510
   230
hegyi@1510
   231
      //initiating values corresponding to new node in maps
hegyi@1510
   232
hegyi@1510
   233
      window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
hegyi@1510
   234
ladanyi@1645
   235
      // update coordinates
ladanyi@1606
   236
      mapstorage.coords.set(active_node, xy<double>(clicked_x, clicked_y));
ladanyi@1645
   237
ladanyi@1645
   238
      // update all other maps
ladanyi@1645
   239
      for (std::map<std::string, Graph::NodeMap<double>*>::const_iterator it =
ladanyi@1645
   240
          mapstorage.nodemap_storage.begin(); it !=
ladanyi@1645
   241
          mapstorage.nodemap_storage.end(); ++it)
ladanyi@1645
   242
      {
ladanyi@1646
   243
        if ((it->first != "coordinates_x") &&
ladanyi@1646
   244
            (it->first != "coordinates_y"))
ladanyi@1645
   245
        {
ladanyi@1645
   246
          (*(it->second))[active_node] =
ladanyi@1645
   247
            mapstorage.nodemap_default[it->first];
ladanyi@1645
   248
        }
ladanyi@1645
   249
      }
ladanyi@1646
   250
      // increment the id map's default value
ladanyi@1646
   251
      mapstorage.nodemap_default["id"] += 1.0;
ladanyi@1645
   252
ladanyi@1606
   253
      nodesmap[active_node]=new Gnome::Canvas::Ellipse(displayed_graph,
ladanyi@1645
   254
          clicked_x-20, clicked_y-20, clicked_x+20, clicked_y+20);
hegyi@1510
   255
      active_item=(Gnome::Canvas::Item *)(nodesmap[active_node]);
ladanyi@1645
   256
      *(nodesmap[active_node]) <<
ladanyi@1645
   257
        Gnome::Canvas::Properties::fill_color("blue");
ladanyi@1645
   258
      *(nodesmap[active_node]) <<
ladanyi@1645
   259
        Gnome::Canvas::Properties::outline_color("black");
ladanyi@1645
   260
      active_item->raise_to_top();
ladanyi@1645
   261
hegyi@1510
   262
      (nodesmap[active_node])->show();
hegyi@1512
   263
ladanyi@1606
   264
      nodetextmap[active_node]=new Gnome::Canvas::Text(displayed_graph,
ladanyi@1645
   265
          clicked_x+node_property_defaults[N_RADIUS]+5,
ladanyi@1645
   266
          clicked_y+node_property_defaults[N_RADIUS]+5, "");
hegyi@1512
   267
      nodetextmap[active_node]->property_fill_color().set_value("darkblue");
ladanyi@1645
   268
      nodetextmap[active_node]->raise_to_top();
hegyi@1512
   269
ladanyi@1606
   270
      mapwin.updateNode(active_node);
hegyi@1512
   271
hegyi@1510
   272
      isbutton=0;
hegyi@1525
   273
      target_item=NULL;
hegyi@1510
   274
      active_item=NULL;
hegyi@1510
   275
      active_node=INVALID;
ladanyi@1645
   276
hegyi@1510
   277
      break;
hegyi@1510
   278
    default:
hegyi@1510
   279
      break;
ladanyi@1645
   280
  }
hegyi@1510
   281
  return false;
hegyi@1510
   282
}
hegyi@1510
   283
hegyi@1524
   284
bool GraphDisplayerCanvas::createEdgeEventHandler(GdkEvent* e)
hegyi@1510
   285
{
hegyi@1510
   286
  switch(e->type)
ladanyi@1645
   287
  {
hegyi@1510
   288
    case GDK_BUTTON_PRESS:
hegyi@1510
   289
      //in edge creation right button has special meaning
hegyi@1510
   290
      if(e->button.button!=3)
ladanyi@1645
   291
      {
ladanyi@1645
   292
        //there is not yet selected node
ladanyi@1645
   293
        if(active_node==INVALID)
ladanyi@1645
   294
        {
ladanyi@1645
   295
          //we mark the location of the event to be able to calculate parameters of dragging
hegyi@1525
   296
ladanyi@1645
   297
          window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
hegyi@1525
   298
ladanyi@1645
   299
          active_item=(get_item_at(clicked_x, clicked_y));
ladanyi@1645
   300
          active_node=INVALID;
ladanyi@1645
   301
          for (NodeIt i(mapstorage.graph); i!=INVALID; ++i)
ladanyi@1645
   302
          {
ladanyi@1645
   303
            if(nodesmap[i]==active_item)
ladanyi@1645
   304
            {
ladanyi@1645
   305
              active_node=i;
ladanyi@1645
   306
            }
ladanyi@1645
   307
          }
ladanyi@1645
   308
          //the clicked item is really a node
ladanyi@1645
   309
          if(active_node!=INVALID)
ladanyi@1645
   310
          {
ladanyi@1645
   311
            *(nodesmap[active_node]) << Gnome::Canvas::Properties::fill_color("red");
ladanyi@1645
   312
            isbutton=1;
ladanyi@1645
   313
          }
ladanyi@1645
   314
          //clicked item was not a node. It could be e.g. edge.
ladanyi@1645
   315
          else
ladanyi@1645
   316
          {
ladanyi@1645
   317
            active_item=NULL;
ladanyi@1645
   318
          }
ladanyi@1645
   319
        }
ladanyi@1645
   320
        //we only have to do sg. if the mouse button
ladanyi@1645
   321
        // is pressed already once AND the click was
ladanyi@1645
   322
        // on a node that was found in the set of 
ladanyi@1645
   323
        //nodes, and now we only search for the second 
ladanyi@1645
   324
        //node
ladanyi@1645
   325
        else
ladanyi@1645
   326
        {
ladanyi@1645
   327
          window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
ladanyi@1645
   328
          target_item=(get_item_at(clicked_x, clicked_y));
ladanyi@1645
   329
          Node target_node=INVALID;
ladanyi@1645
   330
          for (NodeIt i(mapstorage.graph); i!=INVALID; ++i)
ladanyi@1645
   331
          {
ladanyi@1645
   332
            if(nodesmap[i]==target_item)
ladanyi@1645
   333
            {
ladanyi@1645
   334
              target_node=i;
ladanyi@1645
   335
            }
ladanyi@1645
   336
          }
ladanyi@1645
   337
          //the clicked item is a node, the edge can be drawn
ladanyi@1645
   338
          if(target_node!=INVALID)
ladanyi@1645
   339
          {
ladanyi@1645
   340
            if(target_node!=active_node)		
ladanyi@1645
   341
            {
ladanyi@1645
   342
              mapstorage.modified = true;
ladanyi@1606
   343
ladanyi@1645
   344
              *(nodesmap[target_node]) <<
ladanyi@1645
   345
                Gnome::Canvas::Properties::fill_color("red");
hegyi@1510
   346
ladanyi@1645
   347
              //creating new edge
ladanyi@1645
   348
              active_edge=mapstorage.graph.addEdge(active_node,
ladanyi@1645
   349
                  target_node);
hegyi@1510
   350
ladanyi@1646
   351
              // update maps
ladanyi@1645
   352
              for (std::map<std::string,
ladanyi@1645
   353
                  Graph::EdgeMap<double>*>::const_iterator it =
ladanyi@1645
   354
                  mapstorage.edgemap_storage.begin(); it !=
ladanyi@1645
   355
                  mapstorage.edgemap_storage.end(); ++it)
ladanyi@1645
   356
              {
ladanyi@1646
   357
                (*(it->second))[active_edge] =
ladanyi@1646
   358
                  mapstorage.edgemap_default[it->first];
ladanyi@1645
   359
              }
ladanyi@1646
   360
              // increment the id map's default value
ladanyi@1646
   361
              mapstorage.edgemap_default["id"] += 1.0;
hegyi@1510
   362
ladanyi@1645
   363
              //calculating coordinates of new edge
ladanyi@1645
   364
              Gnome::Canvas::Points coos;
ladanyi@1645
   365
              double x1, x2, y1, y2;
hegyi@1510
   366
ladanyi@1645
   367
              active_item->get_bounds(x1, y1, x2, y2);
ladanyi@1645
   368
              coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
hegyi@1510
   369
ladanyi@1645
   370
              target_item->get_bounds(x1, y1, x2, y2);
ladanyi@1645
   371
              coos.push_back(Gnome::Art::Point((x1+x2)/2,(y1+y2)/2));
hegyi@1510
   372
ladanyi@1645
   373
              //drawing new edge
ladanyi@1645
   374
              edgesmap[active_edge]=new BrokenEdge(displayed_graph, coos,
ladanyi@1645
   375
                  *this);
ladanyi@1645
   376
              *(edgesmap[active_edge]) <<
ladanyi@1645
   377
                Gnome::Canvas::Properties::fill_color("green");
ladanyi@1645
   378
              edgesmap[active_edge]->property_width_pixels().set_value(10);
hegyi@1510
   379
ladanyi@1645
   380
              edgesmap[active_edge]->lower_to_bottom();
hegyi@1512
   381
ladanyi@1645
   382
              //initializing edge-text as well, to empty string
ladanyi@1645
   383
              xy<double> text_pos=edgesmap[active_edge]->getArrowPos();
ladanyi@1645
   384
              text_pos+=(xy<double>(10,10));
ladanyi@1645
   385
ladanyi@1645
   386
              edgetextmap[active_edge]=new Gnome::Canvas::Text(displayed_graph,
ladanyi@1645
   387
                  text_pos.x, text_pos.y, "");
ladanyi@1645
   388
              edgetextmap[active_edge]->property_fill_color().set_value(
ladanyi@1645
   389
                  "darkgreen");
ladanyi@1645
   390
              edgetextmap[active_edge]->raise_to_top();
ladanyi@1645
   391
ladanyi@1645
   392
              //updating its properties
ladanyi@1645
   393
              mapwin.updateEdge(active_edge);
ladanyi@1645
   394
            }
ladanyi@1645
   395
            else
ladanyi@1645
   396
            {
ladanyi@1645
   397
              target_node=INVALID;
ladanyi@1645
   398
              std::cerr << "Loop edge is not yet implemented!" << std::endl;
ladanyi@1645
   399
            }
ladanyi@1645
   400
          }
ladanyi@1645
   401
          //clicked item was not a node. it could be an e.g. edge. we do not
ladanyi@1645
   402
          //deal with it furthermore.
ladanyi@1645
   403
          else
ladanyi@1645
   404
          {
ladanyi@1645
   405
            target_item=NULL;
ladanyi@1645
   406
          }
ladanyi@1645
   407
        }
ladanyi@1645
   408
      }
hegyi@1510
   409
      break;
hegyi@1510
   410
    case GDK_BUTTON_RELEASE:
hegyi@1510
   411
      isbutton=0;
hegyi@1510
   412
      //we clear settings in two cases
hegyi@1510
   413
      //1: the edge is ready (target_item has valid value)
hegyi@1510
   414
      //2: the edge creation is cancelled with right button
hegyi@1510
   415
      if((target_item)||(e->button.button==3))
ladanyi@1645
   416
      {
ladanyi@1645
   417
        if(active_item)
ladanyi@1645
   418
        {
ladanyi@1645
   419
          *active_item << Gnome::Canvas::Properties::fill_color("blue");
ladanyi@1645
   420
          active_item=NULL;
ladanyi@1645
   421
        }
ladanyi@1645
   422
        if(target_item)
ladanyi@1645
   423
        {
ladanyi@1645
   424
          *target_item << Gnome::Canvas::Properties::fill_color("blue");
ladanyi@1645
   425
          target_item=NULL;
ladanyi@1645
   426
        }
ladanyi@1645
   427
        active_node=INVALID;
ladanyi@1645
   428
        active_edge=INVALID;
ladanyi@1645
   429
      }
hegyi@1510
   430
      break;
hegyi@1510
   431
    default:
hegyi@1510
   432
      break;
ladanyi@1645
   433
  }
hegyi@1510
   434
  return false;
hegyi@1510
   435
}
hegyi@1510
   436
hegyi@1524
   437
bool GraphDisplayerCanvas::eraserEventHandler(GdkEvent* e)
hegyi@1510
   438
{
hegyi@1510
   439
  switch(e->type)
hegyi@1510
   440
    {
hegyi@1510
   441
    case GDK_BUTTON_PRESS:
hegyi@1594
   442
      //finding the clicked items
hegyi@1525
   443
      window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
hegyi@1525
   444
      active_item=(get_item_at(clicked_x, clicked_y));
hegyi@1510
   445
      active_node=INVALID;
hegyi@1510
   446
      active_edge=INVALID;
hegyi@1594
   447
      //was it a node?
ladanyi@1606
   448
      for (NodeIt i(mapstorage.graph); i!=INVALID; ++i)
hegyi@1510
   449
	{
hegyi@1510
   450
	  if(nodesmap[i]==active_item)
hegyi@1510
   451
	    {
hegyi@1510
   452
	      active_node=i;
hegyi@1510
   453
	    }
hegyi@1510
   454
	}
hegyi@1594
   455
      //or was it an edge?
hegyi@1510
   456
      if(active_node==INVALID)
hegyi@1510
   457
	{
ladanyi@1606
   458
	  for (EdgeIt i(mapstorage.graph); i!=INVALID; ++i)
hegyi@1510
   459
	    {
hegyi@1510
   460
	      if(edgesmap[i]==active_item)
hegyi@1510
   461
		{
hegyi@1510
   462
		  active_edge=i;
hegyi@1510
   463
		}
hegyi@1510
   464
	    }
hegyi@1510
   465
	}
hegyi@1594
   466
hegyi@1594
   467
      //recolor activated item
hegyi@1525
   468
      if(active_item)
hegyi@1525
   469
	{
hegyi@1525
   470
	  *active_item << Gnome::Canvas::Properties::fill_color("red");
hegyi@1525
   471
	}
hegyi@1510
   472
      break;
hegyi@1510
   473
hegyi@1510
   474
    case GDK_BUTTON_RELEASE:
hegyi@1525
   475
      window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
hegyi@1525
   476
      if(active_item)
hegyi@1510
   477
	{
hegyi@1594
   478
	  //the cursor was not moved since pressing it
hegyi@1525
   479
	  if( active_item == ( get_item_at (clicked_x, clicked_y) ) )
hegyi@1510
   480
	    {
hegyi@1594
   481
	      //a node was found
hegyi@1525
   482
	      if(active_node!=INVALID)
hegyi@1525
   483
		{
ladanyi@1606
   484
                  mapstorage.modified = true;
hegyi@1510
   485
hegyi@1525
   486
		  //collecting edges to delete
hegyi@1525
   487
		  EdgeIt e;
hegyi@1525
   488
		  std::set<Graph::Edge> edges_to_delete;
hegyi@1510
   489
ladanyi@1606
   490
		  mapstorage.graph.firstOut(e,active_node);
ladanyi@1606
   491
		  for(;e!=INVALID;mapstorage.graph.nextOut(e))
hegyi@1525
   492
		    {
hegyi@1525
   493
		      edges_to_delete.insert(e);
hegyi@1525
   494
		    }
hegyi@1525
   495
ladanyi@1606
   496
		  mapstorage.graph.firstIn(e,active_node);
ladanyi@1606
   497
		  for(;e!=INVALID;mapstorage.graph.nextIn(e))
hegyi@1525
   498
		    {
hegyi@1525
   499
		      edges_to_delete.insert(e);
hegyi@1525
   500
		    }
hegyi@1525
   501
hegyi@1525
   502
		  //deleting collected edges
hegyi@1525
   503
		  for(std::set<Graph::Edge>::iterator edge_set_it=edges_to_delete.begin();edge_set_it!=edges_to_delete.end();edge_set_it++)
hegyi@1525
   504
		    {
hegyi@1525
   505
		      deleteItem(*edge_set_it);
hegyi@1525
   506
		    }
hegyi@1525
   507
		  deleteItem(active_node);
hegyi@1525
   508
		}
hegyi@1525
   509
	      //a simple edge was chosen
hegyi@1525
   510
	      else
hegyi@1510
   511
		{
hegyi@1525
   512
		  deleteItem(active_edge);
hegyi@1510
   513
		}
hegyi@1510
   514
	    }
hegyi@1525
   515
	  //pointer was moved, deletion is cancelled
hegyi@1510
   516
	  else
hegyi@1510
   517
	    {
hegyi@1525
   518
	      if(active_node!=INVALID)
hegyi@1525
   519
		{
hegyi@1525
   520
		  *active_item << Gnome::Canvas::Properties::fill_color("blue");
hegyi@1525
   521
		}
hegyi@1525
   522
	      else
hegyi@1525
   523
		{
hegyi@1525
   524
		  *active_item << Gnome::Canvas::Properties::fill_color("green");
hegyi@1525
   525
		}
hegyi@1510
   526
	    }
hegyi@1510
   527
	}
hegyi@1510
   528
      //reseting datas
hegyi@1510
   529
      active_item=NULL;
hegyi@1510
   530
      active_edge=INVALID;
hegyi@1510
   531
      active_node=INVALID;
hegyi@1510
   532
      break;
hegyi@1510
   533
hegyi@1510
   534
    case GDK_MOTION_NOTIFY:
hegyi@1510
   535
      break;
hegyi@1510
   536
hegyi@1510
   537
    default:
hegyi@1510
   538
      break;
hegyi@1510
   539
    }
hegyi@1525
   540
  return false;
hegyi@1510
   541
}
hegyi@1510
   542
hegyi@1550
   543
bool GraphDisplayerCanvas::edgeMapEditEventHandler(GdkEvent* e)
hegyi@1550
   544
{
hegyi@1599
   545
  if(actual_tool==EDGE_MAP_EDIT)
ladanyi@1648
   546
  {
ladanyi@1648
   547
    switch(e->type)
hegyi@1550
   548
    {
ladanyi@1648
   549
      case GDK_BUTTON_PRESS:
ladanyi@1648
   550
        {
ladanyi@1648
   551
          //for determine, whether it was an edge
ladanyi@1648
   552
          Edge clicked_edge=INVALID;
hegyi@1594
   553
ladanyi@1648
   554
          window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
ladanyi@1648
   555
          active_item=(get_item_at(clicked_x, clicked_y));
hegyi@1599
   556
ladanyi@1648
   557
          //find the activated item between texts
ladanyi@1648
   558
          for (EdgeIt i(mapstorage.graph); i!=INVALID; ++i)
ladanyi@1648
   559
          {
ladanyi@1648
   560
            //at the same time only one can be active
ladanyi@1648
   561
            if(edgetextmap[i]==active_item)
ladanyi@1648
   562
            {
ladanyi@1648
   563
              clicked_edge=i;
ladanyi@1648
   564
            }
ladanyi@1648
   565
          }
ladanyi@1647
   566
ladanyi@1648
   567
          //if it was not between texts, search for it between edges
ladanyi@1648
   568
          if(clicked_edge==INVALID)
ladanyi@1648
   569
          {
ladanyi@1648
   570
            for (EdgeIt i(mapstorage.graph); i!=INVALID; ++i)
ladanyi@1648
   571
            {
ladanyi@1648
   572
              //at the same time only one can be active
ladanyi@1648
   573
              if((edgesmap[i]==active_item)||(edgetextmap[i]==active_item))
ladanyi@1648
   574
              {
ladanyi@1648
   575
                clicked_edge=i;
ladanyi@1648
   576
              }
ladanyi@1648
   577
            }
ladanyi@1648
   578
          }
ladanyi@1648
   579
 
ladanyi@1648
   580
          //if it was really an edge...
ladanyi@1648
   581
          if(clicked_edge!=INVALID)
ladanyi@1648
   582
          {
ladanyi@1648
   583
            // the id map is not editable
ladanyi@1648
   584
            if (edgemap_to_edit == "id") return 0;
hegyi@1599
   585
ladanyi@1648
   586
            //and there is activated map
ladanyi@1648
   587
            if(edgetextmap[clicked_edge]->property_text().get_value()!="")
ladanyi@1648
   588
            {
ladanyi@1648
   589
              //activate the general variable for it
ladanyi@1648
   590
              active_edge=clicked_edge;
hegyi@1599
   591
ladanyi@1648
   592
              //create a dialog
ladanyi@1648
   593
              Gtk::Dialog dialog("Edit value", *parentwin, true);
ladanyi@1648
   594
              dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
ladanyi@1648
   595
              dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_ACCEPT);
ladanyi@1648
   596
              Gtk::VBox* vbox = dialog.get_vbox();
ladanyi@1648
   597
              Gtk::Adjustment adj(
ladanyi@1648
   598
                  (*mapstorage.edgemap_storage[edgemap_to_edit])[active_edge],
ladanyi@1648
   599
                  -1000000.0,
ladanyi@1648
   600
                  1000000.0,
ladanyi@1648
   601
                  1.0, 5.0, 0.0);
ladanyi@1648
   602
              //TODO: find out why doesn't it work with
ladanyi@1648
   603
              //numeric_limits<double>::min/max
ladanyi@1648
   604
              Gtk::SpinButton spin(adj);
ladanyi@1648
   605
              spin.set_numeric(true);
ladanyi@1648
   606
              spin.set_digits(4);
ladanyi@1648
   607
              vbox->add(spin);
ladanyi@1648
   608
              spin.show();
ladanyi@1648
   609
              switch (dialog.run())
ladanyi@1648
   610
              {
ladanyi@1648
   611
                case Gtk::RESPONSE_NONE:
ladanyi@1648
   612
                case Gtk::RESPONSE_CANCEL:
ladanyi@1648
   613
                  break;
ladanyi@1648
   614
                case Gtk::RESPONSE_ACCEPT:
ladanyi@1648
   615
                  double new_value = spin.get_value();
ladanyi@1648
   616
                  (*mapstorage.edgemap_storage[edgemap_to_edit])[active_edge] =
ladanyi@1648
   617
                    new_value;
ladanyi@1648
   618
                  std::ostringstream ostr;
ladanyi@1648
   619
                  ostr << new_value;
ladanyi@1648
   620
                  edgetextmap[active_edge]->property_text().set_value(
ladanyi@1648
   621
                      ostr.str());
ladanyi@1648
   622
                  //mapwin.updateEdge(active_edge);
ladanyi@1648
   623
                  mapwin.updateEdge(Edge(INVALID));
ladanyi@1648
   624
              }
ladanyi@1648
   625
            }
ladanyi@1648
   626
          }
ladanyi@1648
   627
          break;
ladanyi@1648
   628
        }
ladanyi@1648
   629
      default:
ladanyi@1648
   630
        break;
hegyi@1550
   631
    }
ladanyi@1648
   632
  }
hegyi@1550
   633
  return false;  
hegyi@1550
   634
}
hegyi@1550
   635
hegyi@1550
   636
bool GraphDisplayerCanvas::nodeMapEditEventHandler(GdkEvent* e)
hegyi@1550
   637
{
hegyi@1599
   638
  if(actual_tool==NODE_MAP_EDIT)
ladanyi@1648
   639
  {
ladanyi@1648
   640
    switch(e->type)
hegyi@1579
   641
    {
ladanyi@1648
   642
      case GDK_BUTTON_PRESS:
ladanyi@1648
   643
        {
ladanyi@1648
   644
          //for determine, whether it was a node
ladanyi@1648
   645
          Node clicked_node=INVALID;
hegyi@1594
   646
ladanyi@1648
   647
          window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
ladanyi@1648
   648
          active_item=(get_item_at(clicked_x, clicked_y));
hegyi@1594
   649
ladanyi@1648
   650
          //find the activated item between texts
ladanyi@1648
   651
          for (NodeIt i(mapstorage.graph); i!=INVALID; ++i)
ladanyi@1648
   652
          {
ladanyi@1648
   653
            //at the same time only one can be active
ladanyi@1648
   654
            if(nodetextmap[i]==active_item)
ladanyi@1648
   655
            {
ladanyi@1648
   656
              clicked_node=i;
ladanyi@1648
   657
            }
ladanyi@1648
   658
          }
hegyi@1599
   659
ladanyi@1648
   660
          //if there was not, search for it between nodes
ladanyi@1648
   661
          if(clicked_node==INVALID)
ladanyi@1648
   662
          {
ladanyi@1648
   663
            for (NodeIt i(mapstorage.graph); i!=INVALID; ++i)
ladanyi@1648
   664
            {
ladanyi@1648
   665
              //at the same time only one can be active
ladanyi@1648
   666
              if(nodesmap[i]==active_item)
ladanyi@1648
   667
              {
ladanyi@1648
   668
                clicked_node=i;
ladanyi@1648
   669
              }
ladanyi@1648
   670
            }
ladanyi@1648
   671
          }
hegyi@1599
   672
ladanyi@1648
   673
          //if it was really a node...
ladanyi@1648
   674
          if(clicked_node!=INVALID)
ladanyi@1648
   675
          {
ladanyi@1648
   676
            // the id map is not editable
ladanyi@1648
   677
            if (nodemap_to_edit == "id") return 0;
hegyi@1599
   678
ladanyi@1648
   679
            //and there is activated map
ladanyi@1648
   680
            if(nodetextmap[clicked_node]->property_text().get_value()!="")
ladanyi@1648
   681
            {
ladanyi@1648
   682
              //activate the general variable for it
ladanyi@1648
   683
              active_node=clicked_node;
hegyi@1599
   684
ladanyi@1648
   685
              //create a dialog
ladanyi@1648
   686
              Gtk::Dialog dialog("Edit value", *parentwin, true);
ladanyi@1648
   687
              dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
ladanyi@1648
   688
              dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_ACCEPT);
ladanyi@1648
   689
              Gtk::VBox* vbox = dialog.get_vbox();
ladanyi@1648
   690
              Gtk::Adjustment adj(
ladanyi@1648
   691
                  (*mapstorage.nodemap_storage[nodemap_to_edit])[active_node],
ladanyi@1648
   692
                  -1000000.0,
ladanyi@1648
   693
                  1000000.0,
ladanyi@1648
   694
                  1.0, 5.0, 0.0);
ladanyi@1648
   695
              //TODO: find out why doesn't it work with
ladanyi@1648
   696
              //numeric_limits<double>::min/max
ladanyi@1648
   697
              Gtk::SpinButton spin(adj);
ladanyi@1648
   698
              spin.set_numeric(true);
ladanyi@1648
   699
              spin.set_digits(4);
ladanyi@1648
   700
              vbox->add(spin);
ladanyi@1648
   701
              spin.show();
ladanyi@1648
   702
              switch (dialog.run())
ladanyi@1648
   703
              {
ladanyi@1648
   704
                case Gtk::RESPONSE_NONE:
ladanyi@1648
   705
                case Gtk::RESPONSE_CANCEL:
ladanyi@1648
   706
                  break;
ladanyi@1648
   707
                case Gtk::RESPONSE_ACCEPT:
ladanyi@1648
   708
                  double new_value = spin.get_value();
ladanyi@1648
   709
                  (*mapstorage.nodemap_storage[nodemap_to_edit])[active_node] =
ladanyi@1648
   710
                    new_value;
ladanyi@1648
   711
                  std::ostringstream ostr;
ladanyi@1648
   712
                  ostr << new_value;
ladanyi@1648
   713
                  nodetextmap[active_node]->property_text().set_value(
ladanyi@1648
   714
                      ostr.str());
ladanyi@1648
   715
                  //mapwin.updateNode(active_node);
ladanyi@1648
   716
                  mapwin.updateNode(Node(INVALID));
ladanyi@1648
   717
              }
ladanyi@1648
   718
            }
ladanyi@1648
   719
          }
ladanyi@1648
   720
          break;
ladanyi@1648
   721
        }
ladanyi@1648
   722
      default:
ladanyi@1648
   723
        break;
hegyi@1579
   724
    }
ladanyi@1648
   725
  }
hegyi@1579
   726
  return false;  
hegyi@1550
   727
}
hegyi@1550
   728
alpar@1643
   729
void GraphDisplayerCanvas::deleteItem(Node node_to_delete)
hegyi@1510
   730
{
hegyi@1512
   731
  delete(nodetextmap[node_to_delete]);
hegyi@1510
   732
  delete(nodesmap[node_to_delete]);
ladanyi@1606
   733
  mapstorage.graph.erase(node_to_delete);
hegyi@1510
   734
}
hegyi@1510
   735
alpar@1643
   736
void GraphDisplayerCanvas::deleteItem(Edge edge_to_delete)
hegyi@1510
   737
{
hegyi@1512
   738
  delete(edgetextmap[edge_to_delete]);
hegyi@1510
   739
  delete(edgesmap[edge_to_delete]);
ladanyi@1606
   740
  mapstorage.graph.erase(edge_to_delete);
hegyi@1510
   741
}
hegyi@1510
   742
hegyi@1524
   743
void GraphDisplayerCanvas::textReposition(xy<double> new_place)
hegyi@1510
   744
{
hegyi@1510
   745
  new_place+=(xy<double>(10,10));
hegyi@1579
   746
  edgetextmap[forming_edge]->property_x().set_value(new_place.x);
hegyi@1579
   747
  edgetextmap[forming_edge]->property_y().set_value(new_place.y);
hegyi@1510
   748
}
hegyi@1510
   749
hegyi@1524
   750
void GraphDisplayerCanvas::toggleEdgeActivity(BrokenEdge* active_bre, bool on)
hegyi@1510
   751
{
hegyi@1510
   752
  if(on)
hegyi@1510
   753
    {
hegyi@1579
   754
      if(forming_edge!=INVALID)
hegyi@1510
   755
	{
hegyi@1599
   756
	  std::cerr << "ERROR!!!! Valid edge found!" << std::endl;
hegyi@1510
   757
	}
hegyi@1510
   758
      else
hegyi@1510
   759
	{
ladanyi@1606
   760
	  for (EdgeIt i(mapstorage.graph); i!=INVALID; ++i)
hegyi@1510
   761
	    {
hegyi@1510
   762
	      if(edgesmap[i]==active_bre)
hegyi@1510
   763
		{
hegyi@1579
   764
		  forming_edge=i;
hegyi@1510
   765
		}
hegyi@1510
   766
	    }
hegyi@1510
   767
	}
hegyi@1510
   768
    }
hegyi@1510
   769
  else
hegyi@1510
   770
    {
hegyi@1579
   771
      if(forming_edge!=INVALID)
hegyi@1510
   772
	{
hegyi@1579
   773
	  forming_edge=INVALID;
hegyi@1510
   774
	}
hegyi@1510
   775
      else
hegyi@1510
   776
	{
hegyi@1599
   777
	  std::cerr << "ERROR!!!! Invalid edge found!" << std::endl;
hegyi@1510
   778
	}
hegyi@1510
   779
    }
hegyi@1510
   780
hegyi@1510
   781
}
hegyi@1550
   782
hegyi@1597
   783
int GraphDisplayerCanvas::addNewEdgeMap(double default_value, std::string mapname)
hegyi@1585
   784
{
hegyi@1594
   785
  //create the new map
ladanyi@1606
   786
  Graph::EdgeMap<double> * emptr=new Graph::EdgeMap<double> (mapstorage.graph, default_value);
hegyi@1597
   787
hegyi@1597
   788
  //if addition was not successful addEdgeMap returns one.
hegyi@1597
   789
  //cause can be that there is already a map named like the new one
ladanyi@1645
   790
  if(mapstorage.addEdgeMap(mapname,emptr, default_value))
hegyi@1597
   791
    {
hegyi@1597
   792
      return 1;
hegyi@1597
   793
    }
hegyi@1597
   794
hegyi@1594
   795
hegyi@1594
   796
  //add it to the list of the displayable maps
ladanyi@1606
   797
  mapwin.registerNewEdgeMap(mapname);
hegyi@1594
   798
hegyi@1594
   799
  //display it
hegyi@1592
   800
  changeEdgeText(mapname);
hegyi@1597
   801
hegyi@1597
   802
  return 0;
hegyi@1585
   803
}
hegyi@1585
   804
hegyi@1597
   805
int GraphDisplayerCanvas::addNewNodeMap(double default_value, std::string mapname)
hegyi@1585
   806
{
hegyi@1594
   807
  //create the new map
ladanyi@1606
   808
  Graph::NodeMap<double> * emptr=new Graph::NodeMap<double> (mapstorage.graph,default_value);
hegyi@1597
   809
hegyi@1597
   810
  //if addition was not successful addNodeMap returns one.
hegyi@1597
   811
  //cause can be that there is already a map named like the new one
ladanyi@1645
   812
  if(mapstorage.addNodeMap(mapname,emptr, default_value))
hegyi@1597
   813
    {
hegyi@1597
   814
      return 1;
hegyi@1597
   815
    }
hegyi@1594
   816
hegyi@1594
   817
  //add it to the list of the displayable maps
ladanyi@1606
   818
  mapwin.registerNewNodeMap(mapname);
hegyi@1594
   819
hegyi@1594
   820
  //display it
hegyi@1592
   821
  changeNodeText(mapname);
hegyi@1597
   822
hegyi@1597
   823
  return 0;
hegyi@1585
   824
}
hegyi@1585
   825