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