gdc-broken_edge.cc
changeset 1 67188bd752db
equal deleted inserted replaced
-1:000000000000 0:66565245b50a
       
     1 /* -*- C++ -*-
       
     2  *
       
     3  * This file is a part of LEMON, a generic C++ optimization library
       
     4  *
       
     5  * Copyright (C) 2003-2006
       
     6  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
       
     7  * (Egervary Research Group on Combinatorial Optimization, EGRES).
       
     8  *
       
     9  * Permission to use, modify and distribute this software is granted
       
    10  * provided that this copyright notice appears in all copies. For
       
    11  * precise terms see the accompanying LICENSE file.
       
    12  *
       
    13  * This software is provided "AS IS" with no warranty of any kind,
       
    14  * express or implied, and with no claim as to its suitability for any
       
    15  * purpose.
       
    16  *
       
    17  */
       
    18 
       
    19 #include <graph_displayer_canvas.h>
       
    20 #include <mapstorage.h>
       
    21 #include <nbtab.h>
       
    22 #include <cmath>
       
    23 
       
    24 DigraphDisplayerCanvas::ArcBase::ArcBase(Gnome::Canvas::Group& _group, Arc _arc, DigraphDisplayerCanvas& _canvas) : 
       
    25   Gnome::Canvas::Group(_group), arc(_arc), canvas(_canvas), arrow(*this)
       
    26 {
       
    27   arrow.property_fill_color().set_value("red");
       
    28   arrow.lower_to_bottom();
       
    29   lower_to_bottom();
       
    30 }
       
    31 
       
    32 DigraphDisplayerCanvas::ArcBase::~ArcBase()
       
    33 {
       
    34 }
       
    35 
       
    36 void DigraphDisplayerCanvas::ArcBase::drawArrow(XY unit_vector_in_dir)
       
    37 {
       
    38   MapStorage& ms = *canvas.mytab.mapstorage;
       
    39   XY center(ms.getArrowCoords(arc));
       
    40   XY unit_norm_vector(0-unit_vector_in_dir.y, unit_vector_in_dir.x);
       
    41 
       
    42   //       /\       // top
       
    43   //      /  \      //
       
    44   //      -  -      // c(enter)l(eft), ccl, ccr, cr
       
    45   //       ||       //
       
    46   //       ||       // b(ottom)l, br
       
    47 
       
    48   double size=3;
       
    49 
       
    50   XY bl (center - unit_vector_in_dir * 3 * size + unit_norm_vector * size );
       
    51   XY br (center - unit_vector_in_dir * 3 * size - unit_norm_vector * size );
       
    52   XY ccl(center + unit_vector_in_dir *  size + unit_norm_vector * size );
       
    53   XY ccr(center + unit_vector_in_dir *  size - unit_norm_vector * size );
       
    54   XY cl (center + unit_vector_in_dir *  size + unit_norm_vector * 2 * size );
       
    55   XY cr (center + unit_vector_in_dir *  size - unit_norm_vector * 2 * size );
       
    56   XY top(center + unit_vector_in_dir * 3 * size);
       
    57 
       
    58   Gnome::Canvas::Points arrow_points;
       
    59   arrow_points.push_back(Gnome::Art::Point( bl.x , bl.y  ) );
       
    60   arrow_points.push_back(Gnome::Art::Point( br.x , br.y  ) );
       
    61   arrow_points.push_back(Gnome::Art::Point( ccr.x, ccr.y ) );
       
    62   arrow_points.push_back(Gnome::Art::Point( cr.x , cr.y  ) );
       
    63   arrow_points.push_back(Gnome::Art::Point( top.x, top.y ) );
       
    64   arrow_points.push_back(Gnome::Art::Point( cl.x , cl.y  ) );
       
    65   arrow_points.push_back(Gnome::Art::Point( ccl.x, ccl.y ) );
       
    66 
       
    67   arrow.property_points().set_value(arrow_points);
       
    68 }
       
    69 
       
    70 DigraphDisplayerCanvas::BrokenArc::BrokenArc(Gnome::Canvas::Group & g,
       
    71     Arc _arc, DigraphDisplayerCanvas & gc) : ArcBase(g, _arc, gc),
       
    72   isbutton(false), line(*this)
       
    73 {
       
    74   arrow.signal_event().connect(sigc::mem_fun(*this, &DigraphDisplayerCanvas::BrokenArc::arcFormerEventHandler));
       
    75 
       
    76   line.property_fill_color().set_value("green");
       
    77   line.property_width_units().set_value(10);    
       
    78   line.lower_to_bottom();
       
    79 
       
    80   draw();
       
    81 }
       
    82 
       
    83 DigraphDisplayerCanvas::BrokenArc::~BrokenArc()
       
    84 {
       
    85 }
       
    86 
       
    87 void DigraphDisplayerCanvas::BrokenArc::draw()
       
    88 {
       
    89   MapStorage& ms = *canvas.mytab.mapstorage;
       
    90 
       
    91   //calculating coordinates of the direction indicator arrow
       
    92   XY head(ms.getNodeCoords(ms.digraph.target(arc)));
       
    93   XY center(ms.getArrowCoords(arc));
       
    94 
       
    95   XY unit_vector_in_dir(head-center);
       
    96   double length=sqrt( unit_vector_in_dir.normSquare() );
       
    97 
       
    98   if(length!=0)
       
    99     {
       
   100       unit_vector_in_dir/=length;
       
   101     }
       
   102 
       
   103   // update the arrow
       
   104   drawArrow(unit_vector_in_dir);
       
   105 
       
   106   // update the arc
       
   107   Gnome::Canvas::Points points;
       
   108   Node source = ms.digraph.source(arc);
       
   109   Node target = ms.digraph.target(arc);
       
   110   points.push_back(Gnome::Art::Point(ms.getNodeCoords(source).x,
       
   111         ms.getNodeCoords(source).y));
       
   112   points.push_back(Gnome::Art::Point(ms.getArrowCoords(arc).x,
       
   113         ms.getArrowCoords(arc).y));
       
   114   points.push_back(Gnome::Art::Point(ms.getNodeCoords(target).x,
       
   115         ms.getNodeCoords(target).y));
       
   116   line.property_points().set_value(points);
       
   117 }
       
   118 
       
   119 bool DigraphDisplayerCanvas::BrokenArc::arcFormerEventHandler(GdkEvent* e)
       
   120 {
       
   121   switch(e->type)
       
   122   {
       
   123     case GDK_BUTTON_PRESS:
       
   124       //we mark the location of the event to be able to calculate parameters
       
   125       //of dragging
       
   126       if(canvas.getActualTool()!=CREATE_NODE)
       
   127       {
       
   128         canvas.toggleArcActivity(this, true);
       
   129         clicked_x=e->button.x;
       
   130         clicked_y=e->button.y;
       
   131         isbutton=true;
       
   132       }
       
   133       break;
       
   134     case GDK_BUTTON_RELEASE:
       
   135       if(canvas.getActualTool()!=CREATE_NODE)
       
   136       {
       
   137         canvas.toggleArcActivity(this, false);
       
   138         isbutton=false;
       
   139       }
       
   140       break;
       
   141     case GDK_MOTION_NOTIFY:
       
   142       //we only have to do sg. if the mouse button is pressed
       
   143       if(isbutton)
       
   144       {
       
   145         //new coordinates will be the old values,
       
   146         //because the item will be moved to the
       
   147         //new coordinate therefore the new movement
       
   148         //has to be calculated from here
       
   149 
       
   150         double dx=e->motion.x-clicked_x;
       
   151         double dy=e->motion.y-clicked_y;
       
   152 
       
   153         Gnome::Canvas::Points points_new;
       
   154 
       
   155         canvas.mytab.mapstorage->setArrowCoords(arc, canvas.mytab.mapstorage->getArrowCoords(arc) + XY(dx, dy));
       
   156 
       
   157         draw();
       
   158         canvas.textReposition(canvas.mytab.mapstorage->getArrowCoords(arc));
       
   159 
       
   160         clicked_x=e->motion.x;
       
   161         clicked_y=e->motion.y;
       
   162 
       
   163       }
       
   164     default: break;
       
   165   }
       
   166 
       
   167   return true;
       
   168 }
       
   169 
       
   170 void DigraphDisplayerCanvas::BrokenArc::setLineWidth(int w)
       
   171 {
       
   172   line.property_width_units().set_value(w);
       
   173 }
       
   174 
       
   175 void DigraphDisplayerCanvas::BrokenArc::setFillColor(Gdk::Color c)
       
   176 {
       
   177   line.property_fill_color_gdk().set_value(c);
       
   178 }
       
   179 
       
   180 DigraphDisplayerCanvas::LoopArc::LoopArc(Gnome::Canvas::Group& _group,
       
   181     Arc _arc, DigraphDisplayerCanvas& _canvas) :
       
   182   ArcBase(_group, _arc, _canvas), line(*this), isbutton(false)
       
   183 {
       
   184   arrow.signal_event().connect(sigc::mem_fun(*this, &DigraphDisplayerCanvas::LoopArc::arcFormerEventHandler));
       
   185 
       
   186   line.property_outline_color().set_value("green");
       
   187   line.property_width_units().set_value(10);
       
   188   line.lower_to_bottom();
       
   189 
       
   190   draw();
       
   191 }
       
   192 
       
   193 DigraphDisplayerCanvas::LoopArc::~LoopArc()
       
   194 {
       
   195 }
       
   196 
       
   197 void DigraphDisplayerCanvas::LoopArc::draw()
       
   198 {
       
   199   MapStorage& ms = *canvas.mytab.mapstorage;
       
   200 
       
   201   Node node = ms.digraph.source(arc);
       
   202   XY center = (ms.getNodeCoords(node) + ms.getArrowCoords(arc)) / 2.0;
       
   203 
       
   204   XY unit_vector_in_dir(rot90(center - ms.getArrowCoords(arc)));
       
   205   double length = sqrt(unit_vector_in_dir.normSquare());
       
   206   unit_vector_in_dir /= length;
       
   207 
       
   208   drawArrow(unit_vector_in_dir);
       
   209 
       
   210   double radius =
       
   211     sqrt((ms.getArrowCoords(arc) - ms.getNodeCoords(node)).normSquare()) / 2.0;
       
   212 
       
   213   XY p1 = center + XY(-radius,  radius);
       
   214   XY p2 = center + XY( radius, -radius);
       
   215   line.property_x1().set_value(p1.x);
       
   216   line.property_y1().set_value(p1.y);
       
   217   line.property_x2().set_value(p2.x);
       
   218   line.property_y2().set_value(p2.y);
       
   219 }
       
   220 
       
   221 void DigraphDisplayerCanvas::LoopArc::setLineWidth(int w)
       
   222 {
       
   223   line.property_width_units().set_value(w);
       
   224 }
       
   225 
       
   226 void DigraphDisplayerCanvas::LoopArc::setFillColor(Gdk::Color c)
       
   227 {
       
   228   line.property_outline_color_gdk().set_value(c);
       
   229 }
       
   230 
       
   231 bool DigraphDisplayerCanvas::LoopArc::arcFormerEventHandler(GdkEvent* e)
       
   232 {
       
   233   switch(e->type)
       
   234   {
       
   235     case GDK_BUTTON_PRESS:
       
   236       if(canvas.getActualTool()!=CREATE_NODE)
       
   237       {
       
   238         canvas.toggleArcActivity(this, true);
       
   239         isbutton=true;
       
   240       }
       
   241       break;
       
   242     case GDK_BUTTON_RELEASE:
       
   243       if(canvas.getActualTool()!=CREATE_NODE)
       
   244       {
       
   245         canvas.toggleArcActivity(this, false);
       
   246         isbutton=false;
       
   247       }
       
   248       break;
       
   249     case GDK_MOTION_NOTIFY:
       
   250       if(isbutton)
       
   251       {
       
   252         canvas.mytab.mapstorage->setArrowCoords(arc, XY(e->motion.x, e->motion.y));
       
   253 
       
   254         draw();
       
   255         canvas.textReposition(canvas.mytab.mapstorage->getArrowCoords(arc));
       
   256       }
       
   257     default: break;
       
   258   }
       
   259   return true;
       
   260 }