gui/gdc-broken_edge.cc
author hegyi
Mon, 21 Nov 2005 18:03:20 +0000
changeset 1823 cb082cdf3667
parent 1714 66c89fe52d4e
child 1831 75ab76fc4bf2
permissions -rw-r--r--
NewMapWin has become Dialog instead of Window. Therefore it is created dynamically, when there is need for it, instead of keeping one instance in memory. This solution is slower, but more correct than before.
hegyi@1819
     1
#include "graph_displayer_canvas.h"
alpar@1632
     2
#include <cmath>
hegyi@1497
     3
hegyi@1819
     4
GraphDisplayerCanvas::BrokenEdge::BrokenEdge(Gnome::Canvas::Group & g, Gnome::Canvas::Points p, GraphDisplayerCanvas & gc) : Line(g), gdc(gc), isbutton(false)
hegyi@1497
     5
{
hegyi@1499
     6
  my_points=new Gnome::Art::Point[3];
hegyi@1499
     7
hegyi@1499
     8
  arrow=new Gnome::Canvas::Polygon(g);
hegyi@1499
     9
  *arrow << Gnome::Canvas::Properties::fill_color("red");
hegyi@1819
    10
  arrow->signal_event().connect(sigc::mem_fun(*this, &GraphDisplayerCanvas::BrokenEdge::edgeFormerEventHandler));
ladanyi@1645
    11
  arrow->lower_to_bottom();
hegyi@1524
    12
  setPoints(p);
hegyi@1499
    13
}
hegyi@1499
    14
hegyi@1819
    15
GraphDisplayerCanvas::BrokenEdge::~BrokenEdge()
hegyi@1499
    16
{
hegyi@1499
    17
  if(arrow)delete(arrow);
hegyi@1499
    18
}
hegyi@1499
    19
hegyi@1819
    20
void GraphDisplayerCanvas::BrokenEdge::setPoints(Gnome::Canvas::Points p, bool move)
hegyi@1499
    21
{
hegyi@1499
    22
  bool set_arrow=false;
hegyi@1601
    23
  //red arrow losts its position-right button
hegyi@1500
    24
  if(!move)
hegyi@1497
    25
    {
hegyi@1500
    26
      if(p.size()==2)
hegyi@1500
    27
	{
hegyi@1500
    28
	  set_arrow=true;
hegyi@1500
    29
	  Gnome::Canvas::Points points_with_center;
hegyi@1500
    30
	  points_with_center.push_back(my_points[0]=p[0]);
hegyi@1500
    31
	  points_with_center.push_back(my_points[1]=Gnome::Art::Point( (p[0].get_x()+p[1].get_x())/2+0 , (p[0].get_y()+p[1].get_y())/2 )+0 );
hegyi@1500
    32
	  points_with_center.push_back(my_points[2]=p[1]);
hegyi@1500
    33
	  property_points().set_value(points_with_center);
hegyi@1500
    34
	}  
hegyi@1500
    35
      if(p.size()==3)
hegyi@1500
    36
	{
hegyi@1500
    37
	  set_arrow=true;
hegyi@1500
    38
	  property_points().set_value(p);
hegyi@1500
    39
	  for(int i=0;i<3;i++)
hegyi@1500
    40
	    {
hegyi@1500
    41
	      my_points[i]=p[i];
hegyi@1500
    42
	    }
hegyi@1500
    43
	}
hegyi@1500
    44
    }
hegyi@1500
    45
  else
hegyi@1499
    46
    {
hegyi@1601
    47
      //arrow keeps its position-left button
hegyi@1601
    48
hegyi@1714
    49
//       if(p.size()==2)
hegyi@1714
    50
//       	{
hegyi@1714
    51
//       	  Gnome::Canvas::Points points;
hegyi@1714
    52
//       	  my_points[0]=p[0];
hegyi@1714
    53
//       	  my_points[2]=p[1];
hegyi@1714
    54
//       	  for(int i=0;i<3;i++)
hegyi@1714
    55
//       	    {
hegyi@1714
    56
//       	      points.push_back(my_points[i]);
hegyi@1714
    57
//       	    }
hegyi@1714
    58
//       	  property_points().set_value(points);
hegyi@1714
    59
//       	}
hegyi@1602
    60
      set_arrow=true;
hegyi@1601
    61
hegyi@1601
    62
      //////////////////////////////////////////////////////////////////////////////////////////////////////
hegyi@1714
    63
      /////////// keeps shape-with scalar multiplication - version 2.
hegyi@1601
    64
      //////////////////////////////////////////////////////////////////////////////////////////////////////
hegyi@1601
    65
hegyi@1714
    66
      if(p.size()==2)
hegyi@1714
    67
      	{
hegyi@1714
    68
	  //old vector from one to the other node - a
hegyi@1714
    69
	  xy<double> a_v(my_points[2].get_x()-my_points[0].get_x(),my_points[2].get_y()-my_points[0].get_y());
hegyi@1714
    70
	  //new vector from one to the other node - b
hegyi@1714
    71
	  xy<double> b_v(p[1].get_x()-p[0].get_x(),p[1].get_y()-p[0].get_y());
hegyi@1601
    72
hegyi@1714
    73
	  double absa=sqrt(a_v.normSquare());
hegyi@1714
    74
	  double absb=sqrt(b_v.normSquare());
hegyi@1601
    75
hegyi@1714
    76
	  //old vector from one node to the breakpoint - c
hegyi@1714
    77
	  xy<double> c_v(my_points[1].get_x()-my_points[0].get_x(),my_points[1].get_y()-my_points[0].get_y());
hegyi@1601
    78
hegyi@1714
    79
	  //unit vector with the same direction to a_v
hegyi@1714
    80
	  xy<double> a_v_u(a_v.x/absa,a_v.y/absa);
hegyi@1601
    81
hegyi@1714
    82
	  //normal vector of unit vector with the same direction to a_v
hegyi@1714
    83
	  xy<double> a_v_u_n(((-1)*a_v_u.y),a_v_u.x);
hegyi@1601
    84
hegyi@1714
    85
	  //unit vector with the same direction to b_v
hegyi@1714
    86
	  xy<double> b_v_u(b_v.x/absb,b_v.y/absb);
hegyi@1601
    87
hegyi@1714
    88
	  //normal vector of unit vector with the same direction to b_v
hegyi@1714
    89
	  xy<double> b_v_u_n(((-1)*b_v_u.y),b_v_u.x);
hegyi@1601
    90
hegyi@1714
    91
	  //vector c in a_v_u and a_v_u_n co-ordinate system
hegyi@1714
    92
	  xy<double> c_a(c_v*a_v_u,c_v*a_v_u_n);
hegyi@1601
    93
hegyi@1714
    94
	  //new vector from one node to the breakpoint - d - we have to calculate this one
hegyi@1714
    95
	  xy<double> d_v=absb/absa*(c_a.x*b_v_u+c_a.y*b_v_u_n);
hegyi@1601
    96
hegyi@1714
    97
	  my_points[1]=Gnome::Art::Point(d_v.x+p[0].get_x(),d_v.y+p[0].get_y());
hegyi@1601
    98
hegyi@1714
    99
      	  my_points[0]=p[0];
hegyi@1714
   100
      	  my_points[2]=p[1];
hegyi@1601
   101
hegyi@1714
   102
	  Gnome::Canvas::Points points;
hegyi@1714
   103
	  for(int i=0;i<3;i++)
hegyi@1714
   104
	    {
hegyi@1714
   105
	      points.push_back(my_points[i]);
hegyi@1714
   106
	    }
hegyi@1714
   107
	  property_points().set_value(points);
hegyi@1714
   108
	}
hegyi@1499
   109
    }
hegyi@1499
   110
  if(set_arrow)
hegyi@1499
   111
    {
hegyi@1499
   112
      //calculating coordinates of the direction indicator arrow
hegyi@1499
   113
hegyi@1499
   114
      xy<gdouble> target( my_points[2].get_x(), my_points[2].get_y() );
hegyi@1499
   115
      xy<gdouble> center( my_points[1].get_x(), my_points[1].get_y() );
hegyi@1499
   116
hegyi@1499
   117
      xy<gdouble> unit_vector_in_dir(target-center);
hegyi@1499
   118
      //       std::cout << target << " - " << center << " = " << unit_vector_in_dir << "    / " <<unit_vector_in_dir.normSquare() ;
hegyi@1499
   119
      unit_vector_in_dir/=sqrt( unit_vector_in_dir.normSquare() );
hegyi@1499
   120
      //       std::cout << " = " << unit_vector_in_dir << std::endl;
hegyi@1499
   121
hegyi@1499
   122
      xy<gdouble> unit_norm_vector(0-unit_vector_in_dir.y, unit_vector_in_dir.x);
hegyi@1499
   123
      //       std::cout << unit_norm_vector << std::endl;
hegyi@1499
   124
hegyi@1499
   125
      {      
hegyi@1504
   126
	//       /\       // top
hegyi@1504
   127
	//      /  \      //
hegyi@1504
   128
	//      -  -      // c(enter)l(eft), ccl, ccr, cr
hegyi@1504
   129
	//       ||       //
hegyi@1504
   130
	//       ||       // b(ottom)l, br
hegyi@1499
   131
      }
hegyi@1499
   132
hegyi@1499
   133
      double size=3;
hegyi@1499
   134
hegyi@1499
   135
      xy<gdouble> bl (center - unit_vector_in_dir * 3 * size + unit_norm_vector * size );
hegyi@1499
   136
      xy<gdouble> br (center - unit_vector_in_dir * 3 * size - unit_norm_vector * size );
hegyi@1499
   137
      xy<gdouble> ccl(center + unit_vector_in_dir *  size + unit_norm_vector * size );
hegyi@1499
   138
      xy<gdouble> ccr(center + unit_vector_in_dir *  size - unit_norm_vector * size );
hegyi@1499
   139
      xy<gdouble> cl (center + unit_vector_in_dir *  size + unit_norm_vector * 2 * size );
hegyi@1499
   140
      xy<gdouble> cr (center + unit_vector_in_dir *  size - unit_norm_vector * 2 * size );
hegyi@1499
   141
      xy<gdouble> top(center + unit_vector_in_dir * 3 * size);
hegyi@1499
   142
	 
hegyi@1499
   143
      //       std::cout << bl << " " << br << " " << ccl << " "  << ccr << " " << cl << " " << cr << " " << top << std::endl;
hegyi@1499
   144
hegyi@1499
   145
      Gnome::Canvas::Points arrow_points;
hegyi@1499
   146
      arrow_points.push_back(Gnome::Art::Point( bl.x , bl.y  ) );
hegyi@1499
   147
      arrow_points.push_back(Gnome::Art::Point( br.x , br.y  ) );
hegyi@1499
   148
      arrow_points.push_back(Gnome::Art::Point( ccr.x, ccr.y ) );
hegyi@1499
   149
      arrow_points.push_back(Gnome::Art::Point( cr.x , cr.y  ) );
hegyi@1499
   150
      arrow_points.push_back(Gnome::Art::Point( top.x, top.y ) );
hegyi@1499
   151
      arrow_points.push_back(Gnome::Art::Point( cl.x , cl.y  ) );
hegyi@1499
   152
      arrow_points.push_back(Gnome::Art::Point( ccl.x, ccl.y ) );
hegyi@1499
   153
hegyi@1499
   154
      arrow->property_points().set_value(arrow_points);
hegyi@1497
   155
    }
hegyi@1497
   156
}
hegyi@1499
   157
hegyi@1819
   158
bool GraphDisplayerCanvas::BrokenEdge::edgeFormerEventHandler(GdkEvent* e)
hegyi@1499
   159
{
hegyi@1499
   160
  switch(e->type)
hegyi@1499
   161
    {
hegyi@1499
   162
    case GDK_BUTTON_PRESS:
hegyi@1499
   163
      //we mark the location of the event to be able to calculate parameters of dragging
hegyi@1524
   164
      if(gdc.getActualTool()!=CREATE_NODE)
hegyi@1501
   165
	{
hegyi@1524
   166
	  gdc.toggleEdgeActivity(this, true);
hegyi@1501
   167
	  clicked_x=e->button.x;
hegyi@1501
   168
	  clicked_y=e->button.y;
hegyi@1501
   169
	  isbutton=true;
hegyi@1501
   170
	}
hegyi@1499
   171
      break;
hegyi@1499
   172
    case GDK_BUTTON_RELEASE:
hegyi@1524
   173
      if(gdc.getActualTool()!=CREATE_NODE)
hegyi@1505
   174
	{
hegyi@1524
   175
	  gdc.toggleEdgeActivity(this, false);
hegyi@1505
   176
	  isbutton=false;
hegyi@1505
   177
	}
hegyi@1499
   178
      break;
hegyi@1499
   179
    case GDK_MOTION_NOTIFY:
hegyi@1499
   180
      //we only have to do sg. if the mouse button is pressed
hegyi@1499
   181
      if(isbutton)
hegyi@1499
   182
	{
hegyi@1499
   183
	  //new coordinates will be the old values,
hegyi@1499
   184
	  //because the item will be moved to the
hegyi@1499
   185
	  //new coordinate therefore the new movement
hegyi@1499
   186
	  //has to be calculated from here
hegyi@1499
   187
hegyi@1499
   188
	  double dx=e->motion.x-clicked_x;
hegyi@1499
   189
	  double dy=e->motion.y-clicked_y;
hegyi@1499
   190
hegyi@1499
   191
	  Gnome::Canvas::Points points_new;
hegyi@1499
   192
hegyi@1499
   193
	  points_new.push_back(my_points[0]);
hegyi@1499
   194
	  points_new.push_back(my_points[1]=Gnome::Art::Point(my_points[1].get_x()+dx,my_points[1].get_y()+dy));
hegyi@1499
   195
	  points_new.push_back(my_points[2]);
hegyi@1499
   196
hegyi@1524
   197
	  setPoints(points_new);
hegyi@1524
   198
	  gdc.textReposition(xy<double>(my_points[1].get_x(),my_points[1].get_y()));
hegyi@1499
   199
hegyi@1499
   200
	  clicked_x=e->motion.x;
hegyi@1499
   201
	  clicked_y=e->motion.y;
hegyi@1499
   202
hegyi@1499
   203
	}
hegyi@1499
   204
    default: break;
hegyi@1499
   205
    }
hegyi@1499
   206
hegyi@1499
   207
  return true;
hegyi@1499
   208
}
hegyi@1505
   209
hegyi@1819
   210
xy<double> GraphDisplayerCanvas::BrokenEdge::getArrowPos()
hegyi@1505
   211
{
hegyi@1505
   212
  xy<double> ret_val(my_points[1].get_x(),my_points[1].get_y());
hegyi@1505
   213
  return ret_val;
hegyi@1505
   214
}