graph_displayer_canvas-event.cc
author ladanyi
Wed, 02 Jan 2008 21:03:09 +0000
changeset 201 879e47e5b731
parent 200 c7ae8642a8d8
permissions -rwxr-xr-x
Merge branches/akos to trunk.
alpar@174
     1
/* -*- C++ -*-
alpar@174
     2
 *
alpar@174
     3
 * This file is a part of LEMON, a generic C++ optimization library
alpar@174
     4
 *
alpar@174
     5
 * Copyright (C) 2003-2006
alpar@174
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@174
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
alpar@174
     8
 *
alpar@174
     9
 * Permission to use, modify and distribute this software is granted
alpar@174
    10
 * provided that this copyright notice appears in all copies. For
alpar@174
    11
 * precise terms see the accompanying LICENSE file.
alpar@174
    12
 *
alpar@174
    13
 * This software is provided "AS IS" with no warranty of any kind,
alpar@174
    14
 * express or implied, and with no claim as to its suitability for any
alpar@174
    15
 * purpose.
alpar@174
    16
 *
alpar@174
    17
 */
alpar@174
    18
hegyi@194
    19
#include <graph_displayer_canvas.h>
hegyi@194
    20
#include <mapstorage.h>
hegyi@194
    21
#include <nbtab.h>
alpar@59
    22
#include <cmath>
hegyi@27
    23
hegyi@27
    24
hegyi@27
    25
bool GraphDisplayerCanvas::on_expose_event(GdkEventExpose *event)
hegyi@27
    26
{
hegyi@27
    27
  Gnome::Canvas::CanvasAA::on_expose_event(event);
hegyi@27
    28
  //usleep(10000);
hegyi@27
    29
  //rezoom();
hegyi@27
    30
  return true;
hegyi@27
    31
}
hegyi@27
    32
hegyi@27
    33
void GraphDisplayerCanvas::changeEditorialTool(int newtool)
hegyi@27
    34
{
hegyi@34
    35
  if(actual_tool!=newtool)
ladanyi@201
    36
  {
ladanyi@201
    37
ladanyi@201
    38
    actual_handler.disconnect();
ladanyi@201
    39
ladanyi@201
    40
    switch(actual_tool)
hegyi@34
    41
    {
ladanyi@201
    42
      case CREATE_EDGE:
ladanyi@201
    43
        {
ladanyi@201
    44
          GdkEvent * generated=new GdkEvent();
ladanyi@201
    45
          generated->type=GDK_BUTTON_RELEASE;
ladanyi@201
    46
          generated->button.button=3;
ladanyi@201
    47
          createEdgeEventHandler(generated);      
ladanyi@201
    48
          break;
ladanyi@201
    49
        }
ladanyi@201
    50
      case MAP_EDIT:
ladanyi@201
    51
        {
ladanyi@201
    52
          break;
ladanyi@201
    53
        }
ladanyi@201
    54
      default:
ladanyi@201
    55
        break;
ladanyi@201
    56
    }
hegyi@27
    57
ladanyi@201
    58
    active_item=NULL; 
ladanyi@201
    59
    target_item=NULL; 
ladanyi@201
    60
    active_edge=INVALID;	
ladanyi@201
    61
    active_node=INVALID;	
hegyi@27
    62
hegyi@27
    63
ladanyi@201
    64
    actual_tool=newtool;
hegyi@33
    65
ladanyi@201
    66
    switch(newtool)
ladanyi@201
    67
    {
ladanyi@201
    68
      case MOVE:
ladanyi@201
    69
        actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::moveEventHandler), false);
ladanyi@201
    70
        break;
hegyi@27
    71
ladanyi@201
    72
      case CREATE_NODE:
ladanyi@201
    73
        actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::createNodeEventHandler), false);
ladanyi@201
    74
        break;
hegyi@27
    75
ladanyi@201
    76
      case CREATE_EDGE:
ladanyi@201
    77
        actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::createEdgeEventHandler), false);
ladanyi@201
    78
        break;
hegyi@27
    79
ladanyi@201
    80
      case ERASER:
ladanyi@201
    81
        actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::eraserEventHandler), false);
ladanyi@201
    82
        break;
hegyi@27
    83
ladanyi@201
    84
      case MAP_EDIT:
ladanyi@201
    85
        grab_focus();
ladanyi@201
    86
        actual_handler=signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::mapEditEventHandler), false);
ladanyi@201
    87
        break;
hegyi@32
    88
ladanyi@201
    89
      default:
ladanyi@201
    90
        break;
hegyi@27
    91
    }
ladanyi@201
    92
  }
hegyi@27
    93
}
hegyi@27
    94
hegyi@30
    95
int GraphDisplayerCanvas::getActualTool()
hegyi@27
    96
{
hegyi@27
    97
  return actual_tool;
hegyi@27
    98
}
hegyi@27
    99
hegyi@187
   100
bool GraphDisplayerCanvas::scrollEventHandler(GdkEvent* e)
hegyi@187
   101
{
hegyi@187
   102
  bool handled=false;
hegyi@187
   103
  if(e->type==GDK_SCROLL)
hegyi@187
   104
    {
hegyi@187
   105
hegyi@187
   106
      //pointer shows this win point before zoom
hegyi@187
   107
      XY win_coord(((GdkEventScroll*)e)->x, ((GdkEventScroll*)e)->y);
hegyi@187
   108
hegyi@187
   109
      //the original scroll settings
hegyi@187
   110
      int scroll_offset_x, scroll_offset_y;
hegyi@187
   111
      get_scroll_offsets(scroll_offset_x, scroll_offset_y);
hegyi@187
   112
hegyi@187
   113
      //pointer shows this canvas point before zoom
hegyi@187
   114
      XY canvas_coord;
hegyi@187
   115
      window_to_world(win_coord.x, win_coord.y, canvas_coord.x, canvas_coord.y);
hegyi@187
   116
hegyi@187
   117
      if(((GdkEventScroll*)e)->direction) //IN
hegyi@187
   118
	{
hegyi@187
   119
	  zoomIn();
hegyi@187
   120
	}
hegyi@187
   121
      else
hegyi@187
   122
	{
hegyi@187
   123
	  zoomOut();
hegyi@187
   124
	}
hegyi@187
   125
hegyi@187
   126
      //pointer shows this window point after zoom
hegyi@187
   127
      XY post_win_coord;
hegyi@187
   128
      world_to_window(canvas_coord.x, canvas_coord.y, post_win_coord.x, post_win_coord.y);
hegyi@187
   129
hegyi@187
   130
      //we have to add the difference between new and old window point to original scroll offset
hegyi@187
   131
      scroll_to(scroll_offset_x+(int)(post_win_coord.x-win_coord.x),scroll_offset_y+(int)(post_win_coord.y-win_coord.y));
hegyi@187
   132
      
hegyi@187
   133
      //no other eventhandler is needed
hegyi@187
   134
      handled=true;
hegyi@187
   135
    }
hegyi@187
   136
  return handled;
hegyi@187
   137
}
hegyi@187
   138
hegyi@30
   139
bool GraphDisplayerCanvas::moveEventHandler(GdkEvent* e)
hegyi@27
   140
{
ladanyi@201
   141
  MapStorage& ms = *mytab.mapstorage;
ladanyi@201
   142
ladanyi@70
   143
  static Gnome::Canvas::Text *coord_text = 0;
hegyi@27
   144
  switch(e->type)
ladanyi@201
   145
  {
hegyi@27
   146
    case GDK_BUTTON_PRESS:
hegyi@27
   147
      //we mark the location of the event to be able to calculate parameters of dragging
hegyi@31
   148
      window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
ladanyi@201
   149
hegyi@31
   150
      active_item=(get_item_at(clicked_x, clicked_y));
hegyi@27
   151
      active_node=INVALID;
ladanyi@201
   152
      for (NodeIt i(ms.graph); i!=INVALID; ++i)
ladanyi@201
   153
      {
ladanyi@201
   154
        if(nodesmap[i]==active_item)
ladanyi@201
   155
        {
ladanyi@201
   156
          active_node=i;
ladanyi@201
   157
        }
ladanyi@201
   158
      }
hegyi@148
   159
      isbutton=e->button.button;
hegyi@27
   160
      break;
hegyi@27
   161
    case GDK_BUTTON_RELEASE:
ladanyi@70
   162
      if (coord_text)
ladanyi@201
   163
      {
ladanyi@201
   164
        delete coord_text;
ladanyi@201
   165
        coord_text = 0;
ladanyi@201
   166
      }
hegyi@27
   167
      isbutton=0;
hegyi@27
   168
      active_item=NULL;
hegyi@27
   169
      active_node=INVALID;
hegyi@27
   170
      break;
hegyi@27
   171
    case GDK_MOTION_NOTIFY:
hegyi@27
   172
      //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
   173
      if(active_node!=INVALID)
ladanyi@201
   174
      {
ladanyi@201
   175
        ms.setModified();
ladanyi@70
   176
ladanyi@201
   177
        //new coordinates will be the old values,
ladanyi@201
   178
        //because the item will be moved to the
ladanyi@201
   179
        //new coordinate therefore the new movement
ladanyi@201
   180
        //has to be calculated from here
hegyi@27
   181
ladanyi@201
   182
        double new_x, new_y;
hegyi@31
   183
ladanyi@201
   184
        window_to_world (e->motion.x, e->motion.y, new_x, new_y);
hegyi@31
   185
ladanyi@201
   186
        double dx=new_x-clicked_x;
ladanyi@201
   187
        double dy=new_y-clicked_y;
ladanyi@201
   188
ladanyi@201
   189
        moveNode(dx, dy);
ladanyi@201
   190
ladanyi@201
   191
        clicked_x=new_x;
ladanyi@201
   192
        clicked_y=new_y;
ladanyi@201
   193
ladanyi@201
   194
        // reposition the coordinates text
ladanyi@201
   195
        std::ostringstream ostr;
ladanyi@201
   196
        ostr << "(" <<
ladanyi@201
   197
          ms.getNodeCoords(active_node).x << ", " <<
ladanyi@201
   198
          ms.getNodeCoords(active_node).y << ")";
ladanyi@201
   199
        double radius =
ladanyi@201
   200
          (nodesmap[active_node]->property_x2().get_value() -
ladanyi@201
   201
           nodesmap[active_node]->property_x1().get_value()) / 2.0;
ladanyi@201
   202
        if (coord_text)
ladanyi@201
   203
        {
ladanyi@201
   204
          coord_text->property_text().set_value(ostr.str());
ladanyi@201
   205
          coord_text->property_x().set_value(
ladanyi@201
   206
              ms.getNodeCoords(active_node).x + radius);
ladanyi@201
   207
          coord_text->property_y().set_value(
ladanyi@201
   208
              ms.getNodeCoords(active_node).y - radius);
ladanyi@201
   209
        }
ladanyi@201
   210
        else
ladanyi@201
   211
        {
ladanyi@201
   212
          coord_text = new Gnome::Canvas::Text(
ladanyi@201
   213
              displayed_graph,
ladanyi@201
   214
              ms.getNodeCoords(active_node).x + radius,
ladanyi@201
   215
              ms.getNodeCoords(active_node).y - radius,
ladanyi@201
   216
              ostr.str());
ladanyi@201
   217
          coord_text->property_fill_color().set_value("black");
ladanyi@201
   218
          coord_text->property_anchor().set_value(Gtk::ANCHOR_SOUTH_WEST);
ladanyi@201
   219
        }
ladanyi@201
   220
ladanyi@201
   221
ladanyi@201
   222
      }
hegyi@160
   223
    default: break;
ladanyi@201
   224
  }
hegyi@27
   225
ladanyi@201
   226
  return false;
hegyi@27
   227
}
hegyi@27
   228
hegyi@148
   229
XY GraphDisplayerCanvas::calcArrowPos(XY moved_node_1, XY moved_node_2, XY fix_node, XY old_arrow_pos, int move_code)
ladanyi@98
   230
{
hegyi@148
   231
  switch(move_code)
ladanyi@201
   232
  {
hegyi@148
   233
    case 1:
hegyi@148
   234
      return XY((moved_node_2.x + fix_node.x) / 2.0, (moved_node_2.y + fix_node.y) / 2.0);
hegyi@148
   235
      break;
hegyi@148
   236
    case 2:
hegyi@148
   237
      return old_arrow_pos;
hegyi@148
   238
      break;
hegyi@148
   239
    case 3:
hegyi@148
   240
      {
ladanyi@201
   241
        //////////////////////////////////////////////////////////////////////////////////////////////////////
ladanyi@201
   242
        /////////// keeps shape-with scalar multiplication - version 2.
ladanyi@201
   243
        //////////////////////////////////////////////////////////////////////////////////////////////////////
ladanyi@98
   244
ladanyi@201
   245
        //old vector from one to the other node - a
ladanyi@201
   246
        XY a_v(moved_node_1.x-fix_node.x,moved_node_1.y-fix_node.y);
ladanyi@201
   247
        //new vector from one to the other node - b
ladanyi@201
   248
        XY b_v(moved_node_2.x-fix_node.x,moved_node_2.y-fix_node.y);
ladanyi@98
   249
ladanyi@201
   250
        double absa=sqrt(a_v.normSquare());
ladanyi@201
   251
        double absb=sqrt(b_v.normSquare());
ladanyi@98
   252
ladanyi@201
   253
        if ((absa == 0.0) || (absb == 0.0))
ladanyi@201
   254
        {
ladanyi@201
   255
          return old_arrow_pos;
ladanyi@201
   256
        }
ladanyi@201
   257
        else
ladanyi@201
   258
        {
ladanyi@201
   259
          //old vector from one node to the breakpoint - c
ladanyi@201
   260
          XY c_v(old_arrow_pos.x-fix_node.x,old_arrow_pos.y-fix_node.y);
hegyi@148
   261
ladanyi@201
   262
          //unit vector with the same direction to a_v
ladanyi@201
   263
          XY a_v_u(a_v.x/absa,a_v.y/absa);
hegyi@148
   264
ladanyi@201
   265
          //normal vector of unit vector with the same direction to a_v
ladanyi@201
   266
          XY a_v_u_n(((-1)*a_v_u.y),a_v_u.x);
hegyi@148
   267
ladanyi@201
   268
          //unit vector with the same direction to b_v
ladanyi@201
   269
          XY b_v_u(b_v.x/absb,b_v.y/absb);
hegyi@148
   270
ladanyi@201
   271
          //normal vector of unit vector with the same direction to b_v
ladanyi@201
   272
          XY b_v_u_n(((-1)*b_v_u.y),b_v_u.x);
hegyi@148
   273
ladanyi@201
   274
          //vector c in a_v_u and a_v_u_n co-ordinate system
ladanyi@201
   275
          XY c_a(c_v*a_v_u,c_v*a_v_u_n);
hegyi@148
   276
ladanyi@201
   277
          //new vector from one node to the breakpoint - d - we have to calculate this one
ladanyi@201
   278
          XY d_v=absb/absa*(c_a.x*b_v_u+c_a.y*b_v_u_n);
hegyi@148
   279
ladanyi@201
   280
          return XY(d_v.x+fix_node.x,d_v.y+fix_node.y);
ladanyi@201
   281
        }
ladanyi@201
   282
        break;
hegyi@148
   283
      }
hegyi@148
   284
    default:
hegyi@148
   285
      break;
ladanyi@201
   286
  }
hegyi@148
   287
}
ladanyi@98
   288
ladanyi@98
   289
hegyi@30
   290
bool GraphDisplayerCanvas::createNodeEventHandler(GdkEvent* e)
hegyi@27
   291
{
ladanyi@201
   292
  MapStorage& ms = *mytab.mapstorage;
ladanyi@201
   293
hegyi@27
   294
  switch(e->type)
ladanyi@63
   295
  {
ladanyi@63
   296
    //move the new node
ladanyi@63
   297
    case GDK_MOTION_NOTIFY:
ladanyi@63
   298
      {
ladanyi@63
   299
        GdkEvent * generated=new GdkEvent();
ladanyi@63
   300
        generated->motion.x=e->motion.x;
ladanyi@63
   301
        generated->motion.y=e->motion.y;
ladanyi@63
   302
        generated->type=GDK_MOTION_NOTIFY;
ladanyi@63
   303
        moveEventHandler(generated);      
ladanyi@63
   304
        break;
ladanyi@63
   305
      }
hegyi@27
   306
ladanyi@63
   307
    case GDK_BUTTON_RELEASE:
ladanyi@201
   308
      ms.setModified();
ladanyi@53
   309
hegyi@178
   310
      is_drawn=true;
hegyi@178
   311
hegyi@27
   312
      isbutton=1;
hegyi@27
   313
hegyi@27
   314
      window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
hegyi@27
   315
ladanyi@201
   316
      active_node = ms.addNode(XY(clicked_x, clicked_y));
ladanyi@63
   317
ladanyi@53
   318
      nodesmap[active_node]=new Gnome::Canvas::Ellipse(displayed_graph,
ladanyi@63
   319
          clicked_x-20, clicked_y-20, clicked_x+20, clicked_y+20);
hegyi@27
   320
      active_item=(Gnome::Canvas::Item *)(nodesmap[active_node]);
ladanyi@63
   321
      *(nodesmap[active_node]) <<
ladanyi@63
   322
        Gnome::Canvas::Properties::fill_color("blue");
ladanyi@63
   323
      *(nodesmap[active_node]) <<
ladanyi@63
   324
        Gnome::Canvas::Properties::outline_color("black");
ladanyi@63
   325
      active_item->raise_to_top();
ladanyi@63
   326
hegyi@27
   327
      (nodesmap[active_node])->show();
hegyi@28
   328
ladanyi@53
   329
      nodetextmap[active_node]=new Gnome::Canvas::Text(displayed_graph,
ladanyi@63
   330
          clicked_x+node_property_defaults[N_RADIUS]+5,
ladanyi@63
   331
          clicked_y+node_property_defaults[N_RADIUS]+5, "");
hegyi@28
   332
      nodetextmap[active_node]->property_fill_color().set_value("darkblue");
ladanyi@63
   333
      nodetextmap[active_node]->raise_to_top();
hegyi@28
   334
ladanyi@201
   335
      //       mapwin.updateNode(active_node);
hegyi@94
   336
      propertyUpdate(active_node);
hegyi@28
   337
hegyi@27
   338
      isbutton=0;
hegyi@31
   339
      target_item=NULL;
hegyi@27
   340
      active_item=NULL;
hegyi@27
   341
      active_node=INVALID;
hegyi@27
   342
      break;
hegyi@27
   343
    default:
hegyi@27
   344
      break;
ladanyi@63
   345
  }
hegyi@27
   346
  return false;
hegyi@27
   347
}
hegyi@27
   348
hegyi@30
   349
bool GraphDisplayerCanvas::createEdgeEventHandler(GdkEvent* e)
hegyi@27
   350
{
ladanyi@201
   351
  MapStorage& ms = *mytab.mapstorage;
ladanyi@201
   352
hegyi@27
   353
  switch(e->type)
ladanyi@63
   354
  {
hegyi@27
   355
    case GDK_BUTTON_PRESS:
hegyi@27
   356
      //in edge creation right button has special meaning
hegyi@27
   357
      if(e->button.button!=3)
ladanyi@63
   358
      {
ladanyi@63
   359
        //there is not yet selected node
ladanyi@63
   360
        if(active_node==INVALID)
ladanyi@63
   361
        {
ladanyi@63
   362
          //we mark the location of the event to be able to calculate parameters of dragging
hegyi@31
   363
ladanyi@63
   364
          window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
hegyi@31
   365
ladanyi@63
   366
          active_item=(get_item_at(clicked_x, clicked_y));
ladanyi@63
   367
          active_node=INVALID;
ladanyi@201
   368
          for (NodeIt i(ms.graph); i!=INVALID; ++i)
ladanyi@63
   369
          {
ladanyi@63
   370
            if(nodesmap[i]==active_item)
ladanyi@63
   371
            {
ladanyi@63
   372
              active_node=i;
ladanyi@63
   373
            }
ladanyi@63
   374
          }
ladanyi@63
   375
          //the clicked item is really a node
ladanyi@63
   376
          if(active_node!=INVALID)
ladanyi@63
   377
          {
ladanyi@63
   378
            *(nodesmap[active_node]) << Gnome::Canvas::Properties::fill_color("red");
ladanyi@63
   379
            isbutton=1;
ladanyi@63
   380
          }
ladanyi@63
   381
          //clicked item was not a node. It could be e.g. edge.
ladanyi@63
   382
          else
ladanyi@63
   383
          {
ladanyi@63
   384
            active_item=NULL;
ladanyi@63
   385
          }
ladanyi@63
   386
        }
ladanyi@63
   387
        //we only have to do sg. if the mouse button
ladanyi@63
   388
        // is pressed already once AND the click was
ladanyi@63
   389
        // on a node that was found in the set of 
ladanyi@63
   390
        //nodes, and now we only search for the second 
ladanyi@63
   391
        //node
ladanyi@63
   392
        else
ladanyi@63
   393
        {
ladanyi@63
   394
          window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
ladanyi@63
   395
          target_item=(get_item_at(clicked_x, clicked_y));
ladanyi@63
   396
          Node target_node=INVALID;
ladanyi@201
   397
          for (NodeIt i(ms.graph); i!=INVALID; ++i)
ladanyi@63
   398
          {
ladanyi@63
   399
            if(nodesmap[i]==target_item)
ladanyi@63
   400
            {
ladanyi@63
   401
              target_node=i;
ladanyi@63
   402
            }
ladanyi@63
   403
          }
ladanyi@63
   404
          //the clicked item is a node, the edge can be drawn
ladanyi@63
   405
          if(target_node!=INVALID)
ladanyi@63
   406
          {
ladanyi@201
   407
            ms.setModified();
ladanyi@151
   408
ladanyi@151
   409
            *(nodesmap[target_node]) <<
ladanyi@151
   410
              Gnome::Canvas::Properties::fill_color("red");
ladanyi@151
   411
ladanyi@201
   412
            active_edge = ms.addEdge(active_node, target_node);
ladanyi@151
   413
ladanyi@63
   414
            if(target_node!=active_node)		
ladanyi@63
   415
            {
ladanyi@201
   416
              edgesmap[active_edge]=new BrokenEdge(displayed_graph, active_edge, *this);
ladanyi@63
   417
            }
ladanyi@63
   418
            else
ladanyi@63
   419
            {
ladanyi@201
   420
              edgesmap[active_edge]=new LoopEdge(displayed_graph, active_edge, *this);
ladanyi@63
   421
            }
ladanyi@151
   422
ladanyi@151
   423
            //initializing edge-text as well, to empty string
ladanyi@201
   424
            XY text_pos=ms.getArrowCoords(active_edge);
ladanyi@151
   425
            text_pos+=(XY(10,10));
ladanyi@151
   426
ladanyi@151
   427
            edgetextmap[active_edge]=new Gnome::Canvas::Text(displayed_graph,
ladanyi@151
   428
                text_pos.x, text_pos.y, "");
ladanyi@151
   429
            edgetextmap[active_edge]->property_fill_color().set_value(
ladanyi@151
   430
                "darkgreen");
ladanyi@151
   431
            edgetextmap[active_edge]->raise_to_top();
ladanyi@151
   432
ladanyi@151
   433
            propertyUpdate(active_edge);
ladanyi@63
   434
          }
ladanyi@63
   435
          //clicked item was not a node. it could be an e.g. edge. we do not
ladanyi@63
   436
          //deal with it furthermore.
ladanyi@63
   437
          else
ladanyi@63
   438
          {
ladanyi@63
   439
            target_item=NULL;
ladanyi@63
   440
          }
ladanyi@63
   441
        }
ladanyi@63
   442
      }
hegyi@27
   443
      break;
hegyi@27
   444
    case GDK_BUTTON_RELEASE:
hegyi@27
   445
      isbutton=0;
hegyi@27
   446
      //we clear settings in two cases
hegyi@27
   447
      //1: the edge is ready (target_item has valid value)
hegyi@27
   448
      //2: the edge creation is cancelled with right button
hegyi@27
   449
      if((target_item)||(e->button.button==3))
ladanyi@63
   450
      {
ladanyi@63
   451
        if(active_item)
ladanyi@63
   452
        {
ladanyi@201
   453
          propertyUpdate(active_node,N_COLOR);
ladanyi@63
   454
          active_item=NULL;
ladanyi@63
   455
        }
ladanyi@63
   456
        if(target_item)
ladanyi@63
   457
        {
ladanyi@201
   458
          propertyUpdate(ms.graph.target(active_edge),N_COLOR);
ladanyi@63
   459
          target_item=NULL;
ladanyi@63
   460
        }
ladanyi@63
   461
        active_node=INVALID;
ladanyi@63
   462
        active_edge=INVALID;
ladanyi@63
   463
      }
hegyi@27
   464
      break;
hegyi@27
   465
    default:
hegyi@27
   466
      break;
ladanyi@63
   467
  }
hegyi@27
   468
  return false;
hegyi@27
   469
}
hegyi@27
   470
hegyi@30
   471
bool GraphDisplayerCanvas::eraserEventHandler(GdkEvent* e)
hegyi@27
   472
{
ladanyi@201
   473
  MapStorage& ms = *mytab.mapstorage;
ladanyi@201
   474
hegyi@27
   475
  switch(e->type)
ladanyi@201
   476
  {
hegyi@27
   477
    case GDK_BUTTON_PRESS:
hegyi@43
   478
      //finding the clicked items
hegyi@31
   479
      window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
hegyi@31
   480
      active_item=(get_item_at(clicked_x, clicked_y));
hegyi@27
   481
      active_node=INVALID;
hegyi@27
   482
      active_edge=INVALID;
hegyi@43
   483
      //was it a node?
ladanyi@201
   484
      for (NodeIt i(ms.graph); i!=INVALID; ++i)
ladanyi@201
   485
      {
ladanyi@201
   486
        if(nodesmap[i]==active_item)
ladanyi@201
   487
        {
ladanyi@201
   488
          active_node=i;
ladanyi@201
   489
        }
ladanyi@201
   490
      }
hegyi@43
   491
      //or was it an edge?
hegyi@27
   492
      if(active_node==INVALID)
ladanyi@201
   493
      {
ladanyi@201
   494
        for (EdgeIt i(ms.graph); i!=INVALID; ++i)
ladanyi@201
   495
        {
ladanyi@201
   496
          if(edgesmap[i]->getLine()==active_item)
ladanyi@201
   497
          {
ladanyi@201
   498
            active_edge=i;
ladanyi@201
   499
          }
ladanyi@201
   500
        }
ladanyi@201
   501
      }
hegyi@43
   502
ladanyi@129
   503
      // return if the clicked object is neither an edge nor a node
ladanyi@129
   504
      if (active_edge == INVALID) return false;
ladanyi@201
   505
hegyi@43
   506
      //recolor activated item
hegyi@31
   507
      if(active_item)
ladanyi@201
   508
      {
ladanyi@201
   509
        *active_item << Gnome::Canvas::Properties::fill_color("red");
ladanyi@201
   510
      }
hegyi@27
   511
      break;
hegyi@27
   512
hegyi@27
   513
    case GDK_BUTTON_RELEASE:
hegyi@31
   514
      window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
hegyi@31
   515
      if(active_item)
ladanyi@201
   516
      {
ladanyi@201
   517
        //the cursor was not moved since pressing it
ladanyi@201
   518
        if( active_item == ( get_item_at (clicked_x, clicked_y) ) )
ladanyi@201
   519
        {
ladanyi@201
   520
          //a node was found
ladanyi@201
   521
          if(active_node!=INVALID)
ladanyi@201
   522
          {
ladanyi@201
   523
            ms.setModified();
hegyi@27
   524
ladanyi@201
   525
            std::set<Graph::Edge> edges_to_delete;
hegyi@27
   526
ladanyi@201
   527
            for(OutEdgeIt e(ms.graph,active_node);e!=INVALID;++e)
ladanyi@201
   528
            {
ladanyi@201
   529
              edges_to_delete.insert(e);
ladanyi@201
   530
            }
ladanyi@201
   531
ladanyi@201
   532
            for(InEdgeIt e(ms.graph,active_node);e!=INVALID;++e)
ladanyi@201
   533
            {
ladanyi@201
   534
              edges_to_delete.insert(e);
ladanyi@201
   535
            }
ladanyi@201
   536
ladanyi@201
   537
            //deleting collected edges
ladanyi@201
   538
            for(std::set<Graph::Edge>::iterator
ladanyi@201
   539
                edge_set_it=edges_to_delete.begin();
ladanyi@201
   540
                edge_set_it!=edges_to_delete.end();
ladanyi@201
   541
                ++edge_set_it)
ladanyi@201
   542
            {
ladanyi@201
   543
              deleteItem(*edge_set_it);
ladanyi@201
   544
            }
ladanyi@201
   545
            deleteItem(active_node);
ladanyi@201
   546
          }
ladanyi@201
   547
          //a simple edge was chosen
ladanyi@201
   548
          else if (active_edge != INVALID)
ladanyi@201
   549
          {
ladanyi@201
   550
            deleteItem(active_edge);
ladanyi@201
   551
          }
ladanyi@201
   552
        }
ladanyi@201
   553
        //pointer was moved, deletion is cancelled
ladanyi@201
   554
        else
ladanyi@201
   555
        {
ladanyi@201
   556
          if(active_node!=INVALID)
ladanyi@201
   557
          {
ladanyi@201
   558
            *active_item << Gnome::Canvas::Properties::fill_color("blue");
ladanyi@201
   559
          }
ladanyi@201
   560
          else if (active_edge != INVALID)
ladanyi@201
   561
          {
ladanyi@201
   562
            *active_item << Gnome::Canvas::Properties::fill_color("green");
ladanyi@201
   563
          }
ladanyi@201
   564
        }
ladanyi@201
   565
      }
hegyi@27
   566
      //reseting datas
hegyi@27
   567
      active_item=NULL;
hegyi@27
   568
      active_edge=INVALID;
hegyi@27
   569
      active_node=INVALID;
hegyi@27
   570
      break;
hegyi@27
   571
hegyi@27
   572
    case GDK_MOTION_NOTIFY:
hegyi@27
   573
      break;
hegyi@27
   574
hegyi@27
   575
    default:
hegyi@27
   576
      break;
ladanyi@201
   577
  }
hegyi@31
   578
  return false;
hegyi@27
   579
}
hegyi@27
   580
hegyi@149
   581
bool GraphDisplayerCanvas::mapEditEventHandler(GdkEvent* e)
hegyi@32
   582
{
ladanyi@201
   583
  MapStorage& ms = *mytab.mapstorage;
ladanyi@201
   584
hegyi@149
   585
  if(actual_tool==MAP_EDIT)
ladanyi@201
   586
  {
ladanyi@201
   587
    switch(e->type)
hegyi@32
   588
    {
ladanyi@201
   589
      case GDK_BUTTON_PRESS:
ladanyi@201
   590
        {
ladanyi@201
   591
          //for determine, whether it was an edge
ladanyi@201
   592
          Edge clicked_edge=INVALID;
ladanyi@201
   593
          //for determine, whether it was a node
ladanyi@201
   594
          Node clicked_node=INVALID;
hegyi@43
   595
ladanyi@201
   596
          window_to_world (e->button.x, e->button.y, clicked_x, clicked_y);
ladanyi@201
   597
          active_item=(get_item_at(clicked_x, clicked_y));
hegyi@48
   598
ladanyi@201
   599
          //find the activated item between text of nodes
ladanyi@201
   600
          for (NodeIt i(ms.graph); i!=INVALID; ++i)
ladanyi@201
   601
          {
ladanyi@201
   602
            //at the same time only one can be active
ladanyi@201
   603
            if(nodetextmap[i]==active_item)
ladanyi@201
   604
            {
ladanyi@201
   605
              clicked_node=i;
ladanyi@201
   606
            }
ladanyi@201
   607
          }
ladanyi@65
   608
ladanyi@201
   609
          //if there was not, search for it between nodes
ladanyi@201
   610
          if(clicked_node==INVALID)
ladanyi@201
   611
          {
ladanyi@201
   612
            for (NodeIt i(ms.graph); i!=INVALID; ++i)
ladanyi@201
   613
            {
ladanyi@201
   614
              //at the same time only one can be active
ladanyi@201
   615
              if(nodesmap[i]==active_item)
ladanyi@201
   616
              {
ladanyi@201
   617
                clicked_node=i;
ladanyi@201
   618
              }
ladanyi@201
   619
            }
ladanyi@201
   620
          }
hegyi@48
   621
ladanyi@201
   622
          if(clicked_node==INVALID)
ladanyi@201
   623
          {
ladanyi@201
   624
            //find the activated item between texts
ladanyi@201
   625
            for (EdgeIt i(ms.graph); i!=INVALID; ++i)
ladanyi@201
   626
            {
ladanyi@201
   627
              //at the same time only one can be active
ladanyi@201
   628
              if(edgetextmap[i]==active_item)
ladanyi@201
   629
              {
ladanyi@201
   630
                clicked_edge=i;
ladanyi@201
   631
              }
ladanyi@201
   632
            }
hegyi@48
   633
ladanyi@201
   634
            //if it was not between texts, search for it between edges
ladanyi@201
   635
            if(clicked_edge==INVALID)
ladanyi@201
   636
            {
ladanyi@201
   637
              for (EdgeIt i(ms.graph); i!=INVALID; ++i)
ladanyi@201
   638
              {
ladanyi@201
   639
                //at the same time only one can be active
ladanyi@201
   640
                if((edgesmap[i]->getLine())==active_item)
ladanyi@201
   641
                {
ladanyi@201
   642
                  clicked_edge=i;
ladanyi@201
   643
                }
ladanyi@201
   644
              }
ladanyi@201
   645
            }
ladanyi@201
   646
          }
hegyi@149
   647
ladanyi@201
   648
          //if it was really a node...
ladanyi@201
   649
          if(clicked_node!=INVALID)
ladanyi@201
   650
          {
ladanyi@201
   651
            // the id map is not editable
ladanyi@201
   652
            if (nodemap_to_edit == "label") return 0;
hegyi@149
   653
ladanyi@201
   654
            //and there is activated map
ladanyi@201
   655
            if(nodetextmap[clicked_node]->property_text().get_value()!="")
ladanyi@201
   656
            {
ladanyi@201
   657
              //activate the general variable for it
ladanyi@201
   658
              active_node=clicked_node;
hegyi@149
   659
ladanyi@201
   660
              //create a dialog
ladanyi@201
   661
              Gtk::Dialog dialog("Edit value", true);
ladanyi@201
   662
              dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
ladanyi@201
   663
              dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_ACCEPT);
ladanyi@201
   664
              Gtk::VBox* vbox = dialog.get_vbox();
hegyi@149
   665
ladanyi@201
   666
              /*
ladanyi@201
   667
              Gtk::SpinButton spin(0.0, 4);
ladanyi@201
   668
              spin.set_increments(1.0, 10.0);
ladanyi@201
   669
              spin.set_range(-1000000.0, 1000000.0);
ladanyi@201
   670
              spin.set_numeric(true);
ladanyi@201
   671
              spin.set_value(atof(nodetextmap[active_node]->property_text().get_value().c_str()));
ladanyi@201
   672
              vbox->add(spin);
ladanyi@201
   673
              spin.show();
ladanyi@201
   674
              */
ladanyi@201
   675
              Gtk::Entry entry;
ladanyi@201
   676
              entry.set_text(nodetextmap[active_node]->property_text().get_value());
ladanyi@201
   677
              vbox->add(entry);
ladanyi@201
   678
              entry.show();
hegyi@149
   679
ladanyi@201
   680
              switch (dialog.run())
ladanyi@201
   681
              {
ladanyi@201
   682
                case Gtk::RESPONSE_NONE:
ladanyi@201
   683
                case Gtk::RESPONSE_CANCEL:
ladanyi@201
   684
                  break;
ladanyi@201
   685
                case Gtk::RESPONSE_ACCEPT:
ladanyi@201
   686
                  switch (ms.getNodeMapElementType(nodemap_to_edit))
ladanyi@201
   687
                  {
ladanyi@201
   688
                    case MapValue::NUMERIC:
ladanyi@201
   689
                      ms.set(nodemap_to_edit, active_node,
ladanyi@201
   690
                          atof(entry.get_text().c_str()));
ladanyi@201
   691
                      break;
ladanyi@201
   692
                    case MapValue::STRING:
ladanyi@201
   693
                      ms.set(nodemap_to_edit, active_node,
ladanyi@201
   694
                          static_cast<std::string>(entry.get_text()));
ladanyi@201
   695
                      break;
ladanyi@201
   696
                  }
ladanyi@201
   697
                  nodetextmap[active_node]->property_text().set_value(
ladanyi@201
   698
                      static_cast<std::string>(ms.get(nodemap_to_edit, active_node)));
ladanyi@201
   699
ladanyi@201
   700
                  //mapwin.updateNode(active_node);
ladanyi@201
   701
                  //mapwin.updateNode(Node(INVALID));
ladanyi@201
   702
                  propertyUpdate(Node(INVALID));
ladanyi@201
   703
              }
ladanyi@201
   704
            }
ladanyi@201
   705
          }
ladanyi@201
   706
          else
ladanyi@201
   707
            //if it was really an edge...
ladanyi@201
   708
            if(clicked_edge!=INVALID)
ladanyi@201
   709
            {
ladanyi@201
   710
              // the id map is not editable
ladanyi@201
   711
              if (edgemap_to_edit == "label") return 0;
ladanyi@201
   712
ladanyi@201
   713
              //and there is activated map
ladanyi@201
   714
              if(edgetextmap[clicked_edge]->property_text().get_value()!="")
ladanyi@201
   715
              {
ladanyi@201
   716
                //activate the general variable for it
ladanyi@201
   717
                active_edge=clicked_edge;
ladanyi@201
   718
ladanyi@201
   719
                //create a dialog
ladanyi@201
   720
                Gtk::Dialog dialog("Edit value", true);
ladanyi@201
   721
                dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
ladanyi@201
   722
                dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_ACCEPT);
ladanyi@201
   723
                Gtk::VBox* vbox = dialog.get_vbox();
ladanyi@201
   724
ladanyi@201
   725
                /*
ladanyi@201
   726
                Gtk::SpinButton spin(0.0, 4);
ladanyi@201
   727
                spin.set_increments(1.0, 10.0);
ladanyi@201
   728
                spin.set_range(-1000000.0, 1000000.0);
ladanyi@201
   729
                spin.set_numeric(true);
ladanyi@201
   730
                spin.set_value(atof(edgetextmap[active_edge]->property_text().get_value().c_str()));
ladanyi@201
   731
                vbox->add(spin);
ladanyi@201
   732
                spin.show();
ladanyi@201
   733
                */
ladanyi@201
   734
                Gtk::Entry entry;
ladanyi@201
   735
                entry.set_text(edgetextmap[active_edge]->property_text().get_value());
ladanyi@201
   736
                vbox->add(entry);
ladanyi@201
   737
                entry.show();
ladanyi@201
   738
ladanyi@201
   739
                std::cout << edgemap_to_edit << std::endl;
ladanyi@201
   740
                switch (dialog.run())
ladanyi@201
   741
                {
ladanyi@201
   742
                  case Gtk::RESPONSE_NONE:
ladanyi@201
   743
                  case Gtk::RESPONSE_CANCEL:
ladanyi@201
   744
                    break;
ladanyi@201
   745
                  case Gtk::RESPONSE_ACCEPT:
ladanyi@201
   746
                    switch (ms.getEdgeMapElementType(edgemap_to_edit))
ladanyi@201
   747
                    {
ladanyi@201
   748
                      case MapValue::NUMERIC:
ladanyi@201
   749
                        ms.set(edgemap_to_edit, active_edge,
ladanyi@201
   750
                            atof(entry.get_text().c_str()));
ladanyi@201
   751
                        break;
ladanyi@201
   752
                      case MapValue::STRING:
ladanyi@201
   753
                        ms.set(edgemap_to_edit, active_edge,
ladanyi@201
   754
                            static_cast<std::string>(entry.get_text()));
ladanyi@201
   755
                        break;
ladanyi@201
   756
                    }
ladanyi@201
   757
                    edgetextmap[active_edge]->property_text().set_value(
ladanyi@201
   758
                        static_cast<std::string>(ms.get(edgemap_to_edit, active_edge)));
ladanyi@201
   759
ladanyi@201
   760
                    //mapwin.updateEdge(active_edge);
ladanyi@201
   761
                    //                   mapwin.updateEdge(Edge(INVALID));
ladanyi@201
   762
                    propertyUpdate(Edge(INVALID));
ladanyi@201
   763
                }
ladanyi@201
   764
              }
ladanyi@201
   765
            }
ladanyi@201
   766
          break;
ladanyi@201
   767
        }
ladanyi@201
   768
      default:
ladanyi@201
   769
        break;
hegyi@32
   770
    }
ladanyi@201
   771
  }
hegyi@35
   772
  return false;  
hegyi@32
   773
}
hegyi@32
   774
alpar@62
   775
void GraphDisplayerCanvas::deleteItem(Node node_to_delete)
hegyi@27
   776
{
hegyi@28
   777
  delete(nodetextmap[node_to_delete]);
hegyi@27
   778
  delete(nodesmap[node_to_delete]);
ladanyi@201
   779
  mytab.mapstorage->graph.erase(node_to_delete);
hegyi@27
   780
}
hegyi@27
   781
alpar@62
   782
void GraphDisplayerCanvas::deleteItem(Edge edge_to_delete)
hegyi@27
   783
{
hegyi@28
   784
  delete(edgetextmap[edge_to_delete]);
hegyi@27
   785
  delete(edgesmap[edge_to_delete]);
ladanyi@201
   786
  mytab.mapstorage->graph.erase(edge_to_delete);
hegyi@27
   787
}
hegyi@27
   788
hegyi@150
   789
void GraphDisplayerCanvas::textReposition(XY new_place)
hegyi@27
   790
{
hegyi@150
   791
  new_place+=(XY(10,10));
hegyi@35
   792
  edgetextmap[forming_edge]->property_x().set_value(new_place.x);
hegyi@35
   793
  edgetextmap[forming_edge]->property_y().set_value(new_place.y);
hegyi@27
   794
}
hegyi@27
   795
ladanyi@147
   796
void GraphDisplayerCanvas::toggleEdgeActivity(EdgeBase* active_bre, bool on)
hegyi@27
   797
{
hegyi@27
   798
  if(on)
ladanyi@147
   799
  {
ladanyi@147
   800
    if(forming_edge!=INVALID)
hegyi@27
   801
    {
ladanyi@147
   802
      std::cerr << "ERROR!!!! Valid edge found!" << std::endl;
hegyi@27
   803
    }
ladanyi@147
   804
    else
ladanyi@147
   805
    {
ladanyi@201
   806
      for (EdgeIt i(mytab.mapstorage->graph); i!=INVALID; ++i)
ladanyi@147
   807
      {
ladanyi@147
   808
        if(edgesmap[i]==active_bre)
ladanyi@147
   809
        {
ladanyi@147
   810
          forming_edge=i;
ladanyi@147
   811
        }
ladanyi@147
   812
      }
ladanyi@147
   813
    }
ladanyi@147
   814
  }
hegyi@27
   815
  else
ladanyi@201
   816
  {
ladanyi@201
   817
    if(forming_edge!=INVALID)
hegyi@27
   818
    {
ladanyi@201
   819
      forming_edge=INVALID;
hegyi@27
   820
    }
ladanyi@201
   821
    else
ladanyi@201
   822
    {
ladanyi@201
   823
      std::cerr << "ERROR!!!! Invalid edge found!" << std::endl;
ladanyi@201
   824
    }
ladanyi@201
   825
  }
hegyi@160
   826
}
hegyi@160
   827
hegyi@160
   828
void GraphDisplayerCanvas::moveNode(double dx, double dy, Gnome::Canvas::Item * item, Node node)
hegyi@160
   829
{
ladanyi@201
   830
  MapStorage& ms = *mytab.mapstorage;
ladanyi@201
   831
hegyi@160
   832
  Gnome::Canvas::Item * moved_item=item;
hegyi@160
   833
  Node moved_node=node;
hegyi@160
   834
hegyi@160
   835
  if(item==NULL && node==INVALID)
ladanyi@201
   836
  {
ladanyi@201
   837
    moved_item=active_item;
ladanyi@201
   838
    moved_node=active_node;
ladanyi@201
   839
  }
hegyi@160
   840
  else
ladanyi@201
   841
  {
ladanyi@201
   842
    isbutton=1;
ladanyi@201
   843
  }
hegyi@160
   844
hegyi@160
   845
  //repositioning node and its text
hegyi@160
   846
  moved_item->move(dx, dy);
hegyi@160
   847
  nodetextmap[moved_node]->move(dx, dy);
hegyi@160
   848
hegyi@160
   849
  // the new coordinates of the centre of the node 
ladanyi@201
   850
  double coord_x = dx + ms.getNodeCoords(moved_node).x;
ladanyi@201
   851
  double coord_y = dy + ms.getNodeCoords(moved_node).y;
hegyi@160
   852
hegyi@160
   853
  // write back the new coordinates to the coords map
ladanyi@201
   854
  ms.setNodeCoords(moved_node, XY(coord_x, coord_y));
hegyi@160
   855
hegyi@160
   856
  //all the edges connected to the moved point has to be redrawn
ladanyi@201
   857
  for(OutEdgeIt ei(ms.graph,moved_node);ei!=INVALID;++ei)
ladanyi@201
   858
  {
ladanyi@201
   859
    XY arrow_pos;
ladanyi@201
   860
ladanyi@201
   861
    if (ms.graph.source(ei) == ms.graph.target(ei))
hegyi@160
   862
    {
ladanyi@201
   863
      arrow_pos = ms.getArrowCoords(ei) + XY(dx, dy);
ladanyi@201
   864
    }
ladanyi@201
   865
    else
ladanyi@201
   866
    {
ladanyi@201
   867
      XY moved_node_1(coord_x - dx, coord_y - dy);
ladanyi@201
   868
      XY moved_node_2(coord_x, coord_y);
ladanyi@201
   869
      Node target = ms.graph.target(ei);
ladanyi@201
   870
      XY fix_node = ms.getNodeCoords(target);
ladanyi@201
   871
      XY old_arrow_pos(ms.getArrowCoords(ei));
ladanyi@201
   872
ladanyi@201
   873
      arrow_pos = calcArrowPos(moved_node_1, moved_node_2, fix_node, old_arrow_pos, isbutton);
ladanyi@201
   874
    }
ladanyi@201
   875
ladanyi@201
   876
    ms.setArrowCoords(ei, arrow_pos);
ladanyi@201
   877
    edgesmap[ei]->draw();
ladanyi@201
   878
ladanyi@201
   879
    //reposition of edgetext
ladanyi@201
   880
    XY text_pos=ms.getArrowCoords(ei);
ladanyi@201
   881
    text_pos+=(XY(10,10));
ladanyi@201
   882
    edgetextmap[ei]->property_x().set_value(text_pos.x);
ladanyi@201
   883
    edgetextmap[ei]->property_y().set_value(text_pos.y);
ladanyi@201
   884
  }
ladanyi@201
   885
ladanyi@201
   886
  for(InEdgeIt ei(ms.graph,moved_node);ei!=INVALID;++ei)
ladanyi@201
   887
  {
ladanyi@201
   888
    if (ms.graph.source(ei) != ms.graph.target(ei))
ladanyi@201
   889
    {
ladanyi@201
   890
      XY moved_node_1(coord_x - dx, coord_y - dy);
ladanyi@201
   891
      XY moved_node_2(coord_x, coord_y);
ladanyi@201
   892
      Node source = ms.graph.source(ei);
ladanyi@201
   893
      XY fix_node = ms.getNodeCoords(source);
ladanyi@201
   894
      XY old_arrow_pos(ms.getArrowCoords(ei));
ladanyi@201
   895
hegyi@160
   896
      XY arrow_pos;
ladanyi@201
   897
      arrow_pos = calcArrowPos(moved_node_1, moved_node_2, fix_node, old_arrow_pos, isbutton);
hegyi@160
   898
ladanyi@201
   899
      ms.setArrowCoords(ei, arrow_pos);
hegyi@160
   900
      edgesmap[ei]->draw();
hegyi@160
   901
hegyi@160
   902
      //reposition of edgetext
ladanyi@201
   903
      XY text_pos=ms.getArrowCoords(ei);
hegyi@160
   904
      text_pos+=(XY(10,10));
hegyi@160
   905
      edgetextmap[ei]->property_x().set_value(text_pos.x);
hegyi@160
   906
      edgetextmap[ei]->property_y().set_value(text_pos.y);
hegyi@160
   907
    }
ladanyi@201
   908
  }
hegyi@27
   909
}
hegyi@179
   910
hegyi@179
   911
Gdk::Color GraphDisplayerCanvas::rainbowColorCounter(double min, double max, double w)
hegyi@179
   912
{
hegyi@179
   913
  Gdk::Color color;
hegyi@179
   914
hegyi@179
   915
  double pos=(w-min)/(max-min);
hegyi@179
   916
  int phase=0;
hegyi@179
   917
hegyi@179
   918
  //rainbow transitions contain 6 phase
hegyi@179
   919
  //in each phase only one color is changed
hegyi@179
   920
  //first we determine the phase, in which
hegyi@179
   921
  //the actual value belongs to
hegyi@179
   922
  for (int i=0;i<=5;i++)
ladanyi@201
   923
  {
ladanyi@201
   924
    if(((double)i/6<pos)&&(pos<=(double(i+1)/6)))
hegyi@179
   925
    {
ladanyi@201
   926
      phase=i;
hegyi@179
   927
    }
ladanyi@201
   928
  }
hegyi@179
   929
  if(phase<6)
ladanyi@201
   930
  {
ladanyi@201
   931
    //within its 1/6 long phase the relativ position
ladanyi@201
   932
    //determines the power of the color changed in
ladanyi@201
   933
    //that phase
ladanyi@201
   934
    //we normalize that to one, to be able to give percentage
ladanyi@201
   935
    //value for the function
ladanyi@201
   936
    double rel_pos=(pos-(phase/6.0))*6.0;
ladanyi@201
   937
ladanyi@201
   938
    switch(phase)
hegyi@179
   939
    {
ladanyi@201
   940
      case 0:
ladanyi@201
   941
        color.set_rgb_p (1, 0, 1-rel_pos);
ladanyi@201
   942
        break;
ladanyi@201
   943
      case 1:
ladanyi@201
   944
        color.set_rgb_p (1, rel_pos, 0);
ladanyi@201
   945
        break;
ladanyi@201
   946
      case 2:
ladanyi@201
   947
        color.set_rgb_p (1-rel_pos, 1, 0);
ladanyi@201
   948
        break;
ladanyi@201
   949
      case 3:
ladanyi@201
   950
        color.set_rgb_p (0, 1, rel_pos);
ladanyi@201
   951
        break;
ladanyi@201
   952
      case 4:
ladanyi@201
   953
        color.set_rgb_p (0, 1-rel_pos, 1);
ladanyi@201
   954
        break;
ladanyi@201
   955
      case 5:
ladanyi@201
   956
        color.set_rgb_p ((rel_pos/3.0), 0, 1);
ladanyi@201
   957
        break;
ladanyi@201
   958
      default:
ladanyi@201
   959
        std::cout << "Wrong phase: " << phase << " " << pos << std::endl;
hegyi@179
   960
    }
ladanyi@201
   961
  }
hegyi@179
   962
  else
ladanyi@201
   963
  {
ladanyi@201
   964
    std::cout << "Wrong phase: " << phase << " " << pos << std::endl;
ladanyi@201
   965
  }
hegyi@179
   966
  return color;
hegyi@179
   967
}