1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/gdc-broken_edge.cc Mon Jul 07 08:10:39 2008 -0500
1.3 @@ -0,0 +1,260 @@
1.4 +/* -*- C++ -*-
1.5 + *
1.6 + * This file is a part of LEMON, a generic C++ optimization library
1.7 + *
1.8 + * Copyright (C) 2003-2006
1.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
1.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
1.11 + *
1.12 + * Permission to use, modify and distribute this software is granted
1.13 + * provided that this copyright notice appears in all copies. For
1.14 + * precise terms see the accompanying LICENSE file.
1.15 + *
1.16 + * This software is provided "AS IS" with no warranty of any kind,
1.17 + * express or implied, and with no claim as to its suitability for any
1.18 + * purpose.
1.19 + *
1.20 + */
1.21 +
1.22 +#include <graph_displayer_canvas.h>
1.23 +#include <mapstorage.h>
1.24 +#include <nbtab.h>
1.25 +#include <cmath>
1.26 +
1.27 +DigraphDisplayerCanvas::ArcBase::ArcBase(Gnome::Canvas::Group& _group, Arc _arc, DigraphDisplayerCanvas& _canvas) :
1.28 + Gnome::Canvas::Group(_group), arc(_arc), canvas(_canvas), arrow(*this)
1.29 +{
1.30 + arrow.property_fill_color().set_value("red");
1.31 + arrow.lower_to_bottom();
1.32 + lower_to_bottom();
1.33 +}
1.34 +
1.35 +DigraphDisplayerCanvas::ArcBase::~ArcBase()
1.36 +{
1.37 +}
1.38 +
1.39 +void DigraphDisplayerCanvas::ArcBase::drawArrow(XY unit_vector_in_dir)
1.40 +{
1.41 + MapStorage& ms = *canvas.mytab.mapstorage;
1.42 + XY center(ms.getArrowCoords(arc));
1.43 + XY unit_norm_vector(0-unit_vector_in_dir.y, unit_vector_in_dir.x);
1.44 +
1.45 + // /\ // top
1.46 + // / \ //
1.47 + // - - // c(enter)l(eft), ccl, ccr, cr
1.48 + // || //
1.49 + // || // b(ottom)l, br
1.50 +
1.51 + double size=3;
1.52 +
1.53 + XY bl (center - unit_vector_in_dir * 3 * size + unit_norm_vector * size );
1.54 + XY br (center - unit_vector_in_dir * 3 * size - unit_norm_vector * size );
1.55 + XY ccl(center + unit_vector_in_dir * size + unit_norm_vector * size );
1.56 + XY ccr(center + unit_vector_in_dir * size - unit_norm_vector * size );
1.57 + XY cl (center + unit_vector_in_dir * size + unit_norm_vector * 2 * size );
1.58 + XY cr (center + unit_vector_in_dir * size - unit_norm_vector * 2 * size );
1.59 + XY top(center + unit_vector_in_dir * 3 * size);
1.60 +
1.61 + Gnome::Canvas::Points arrow_points;
1.62 + arrow_points.push_back(Gnome::Art::Point( bl.x , bl.y ) );
1.63 + arrow_points.push_back(Gnome::Art::Point( br.x , br.y ) );
1.64 + arrow_points.push_back(Gnome::Art::Point( ccr.x, ccr.y ) );
1.65 + arrow_points.push_back(Gnome::Art::Point( cr.x , cr.y ) );
1.66 + arrow_points.push_back(Gnome::Art::Point( top.x, top.y ) );
1.67 + arrow_points.push_back(Gnome::Art::Point( cl.x , cl.y ) );
1.68 + arrow_points.push_back(Gnome::Art::Point( ccl.x, ccl.y ) );
1.69 +
1.70 + arrow.property_points().set_value(arrow_points);
1.71 +}
1.72 +
1.73 +DigraphDisplayerCanvas::BrokenArc::BrokenArc(Gnome::Canvas::Group & g,
1.74 + Arc _arc, DigraphDisplayerCanvas & gc) : ArcBase(g, _arc, gc),
1.75 + isbutton(false), line(*this)
1.76 +{
1.77 + arrow.signal_event().connect(sigc::mem_fun(*this, &DigraphDisplayerCanvas::BrokenArc::arcFormerEventHandler));
1.78 +
1.79 + line.property_fill_color().set_value("green");
1.80 + line.property_width_units().set_value(10);
1.81 + line.lower_to_bottom();
1.82 +
1.83 + draw();
1.84 +}
1.85 +
1.86 +DigraphDisplayerCanvas::BrokenArc::~BrokenArc()
1.87 +{
1.88 +}
1.89 +
1.90 +void DigraphDisplayerCanvas::BrokenArc::draw()
1.91 +{
1.92 + MapStorage& ms = *canvas.mytab.mapstorage;
1.93 +
1.94 + //calculating coordinates of the direction indicator arrow
1.95 + XY head(ms.getNodeCoords(ms.digraph.target(arc)));
1.96 + XY center(ms.getArrowCoords(arc));
1.97 +
1.98 + XY unit_vector_in_dir(head-center);
1.99 + double length=sqrt( unit_vector_in_dir.normSquare() );
1.100 +
1.101 + if(length!=0)
1.102 + {
1.103 + unit_vector_in_dir/=length;
1.104 + }
1.105 +
1.106 + // update the arrow
1.107 + drawArrow(unit_vector_in_dir);
1.108 +
1.109 + // update the arc
1.110 + Gnome::Canvas::Points points;
1.111 + Node source = ms.digraph.source(arc);
1.112 + Node target = ms.digraph.target(arc);
1.113 + points.push_back(Gnome::Art::Point(ms.getNodeCoords(source).x,
1.114 + ms.getNodeCoords(source).y));
1.115 + points.push_back(Gnome::Art::Point(ms.getArrowCoords(arc).x,
1.116 + ms.getArrowCoords(arc).y));
1.117 + points.push_back(Gnome::Art::Point(ms.getNodeCoords(target).x,
1.118 + ms.getNodeCoords(target).y));
1.119 + line.property_points().set_value(points);
1.120 +}
1.121 +
1.122 +bool DigraphDisplayerCanvas::BrokenArc::arcFormerEventHandler(GdkEvent* e)
1.123 +{
1.124 + switch(e->type)
1.125 + {
1.126 + case GDK_BUTTON_PRESS:
1.127 + //we mark the location of the event to be able to calculate parameters
1.128 + //of dragging
1.129 + if(canvas.getActualTool()!=CREATE_NODE)
1.130 + {
1.131 + canvas.toggleArcActivity(this, true);
1.132 + clicked_x=e->button.x;
1.133 + clicked_y=e->button.y;
1.134 + isbutton=true;
1.135 + }
1.136 + break;
1.137 + case GDK_BUTTON_RELEASE:
1.138 + if(canvas.getActualTool()!=CREATE_NODE)
1.139 + {
1.140 + canvas.toggleArcActivity(this, false);
1.141 + isbutton=false;
1.142 + }
1.143 + break;
1.144 + case GDK_MOTION_NOTIFY:
1.145 + //we only have to do sg. if the mouse button is pressed
1.146 + if(isbutton)
1.147 + {
1.148 + //new coordinates will be the old values,
1.149 + //because the item will be moved to the
1.150 + //new coordinate therefore the new movement
1.151 + //has to be calculated from here
1.152 +
1.153 + double dx=e->motion.x-clicked_x;
1.154 + double dy=e->motion.y-clicked_y;
1.155 +
1.156 + Gnome::Canvas::Points points_new;
1.157 +
1.158 + canvas.mytab.mapstorage->setArrowCoords(arc, canvas.mytab.mapstorage->getArrowCoords(arc) + XY(dx, dy));
1.159 +
1.160 + draw();
1.161 + canvas.textReposition(canvas.mytab.mapstorage->getArrowCoords(arc));
1.162 +
1.163 + clicked_x=e->motion.x;
1.164 + clicked_y=e->motion.y;
1.165 +
1.166 + }
1.167 + default: break;
1.168 + }
1.169 +
1.170 + return true;
1.171 +}
1.172 +
1.173 +void DigraphDisplayerCanvas::BrokenArc::setLineWidth(int w)
1.174 +{
1.175 + line.property_width_units().set_value(w);
1.176 +}
1.177 +
1.178 +void DigraphDisplayerCanvas::BrokenArc::setFillColor(Gdk::Color c)
1.179 +{
1.180 + line.property_fill_color_gdk().set_value(c);
1.181 +}
1.182 +
1.183 +DigraphDisplayerCanvas::LoopArc::LoopArc(Gnome::Canvas::Group& _group,
1.184 + Arc _arc, DigraphDisplayerCanvas& _canvas) :
1.185 + ArcBase(_group, _arc, _canvas), line(*this), isbutton(false)
1.186 +{
1.187 + arrow.signal_event().connect(sigc::mem_fun(*this, &DigraphDisplayerCanvas::LoopArc::arcFormerEventHandler));
1.188 +
1.189 + line.property_outline_color().set_value("green");
1.190 + line.property_width_units().set_value(10);
1.191 + line.lower_to_bottom();
1.192 +
1.193 + draw();
1.194 +}
1.195 +
1.196 +DigraphDisplayerCanvas::LoopArc::~LoopArc()
1.197 +{
1.198 +}
1.199 +
1.200 +void DigraphDisplayerCanvas::LoopArc::draw()
1.201 +{
1.202 + MapStorage& ms = *canvas.mytab.mapstorage;
1.203 +
1.204 + Node node = ms.digraph.source(arc);
1.205 + XY center = (ms.getNodeCoords(node) + ms.getArrowCoords(arc)) / 2.0;
1.206 +
1.207 + XY unit_vector_in_dir(rot90(center - ms.getArrowCoords(arc)));
1.208 + double length = sqrt(unit_vector_in_dir.normSquare());
1.209 + unit_vector_in_dir /= length;
1.210 +
1.211 + drawArrow(unit_vector_in_dir);
1.212 +
1.213 + double radius =
1.214 + sqrt((ms.getArrowCoords(arc) - ms.getNodeCoords(node)).normSquare()) / 2.0;
1.215 +
1.216 + XY p1 = center + XY(-radius, radius);
1.217 + XY p2 = center + XY( radius, -radius);
1.218 + line.property_x1().set_value(p1.x);
1.219 + line.property_y1().set_value(p1.y);
1.220 + line.property_x2().set_value(p2.x);
1.221 + line.property_y2().set_value(p2.y);
1.222 +}
1.223 +
1.224 +void DigraphDisplayerCanvas::LoopArc::setLineWidth(int w)
1.225 +{
1.226 + line.property_width_units().set_value(w);
1.227 +}
1.228 +
1.229 +void DigraphDisplayerCanvas::LoopArc::setFillColor(Gdk::Color c)
1.230 +{
1.231 + line.property_outline_color_gdk().set_value(c);
1.232 +}
1.233 +
1.234 +bool DigraphDisplayerCanvas::LoopArc::arcFormerEventHandler(GdkEvent* e)
1.235 +{
1.236 + switch(e->type)
1.237 + {
1.238 + case GDK_BUTTON_PRESS:
1.239 + if(canvas.getActualTool()!=CREATE_NODE)
1.240 + {
1.241 + canvas.toggleArcActivity(this, true);
1.242 + isbutton=true;
1.243 + }
1.244 + break;
1.245 + case GDK_BUTTON_RELEASE:
1.246 + if(canvas.getActualTool()!=CREATE_NODE)
1.247 + {
1.248 + canvas.toggleArcActivity(this, false);
1.249 + isbutton=false;
1.250 + }
1.251 + break;
1.252 + case GDK_MOTION_NOTIFY:
1.253 + if(isbutton)
1.254 + {
1.255 + canvas.mytab.mapstorage->setArrowCoords(arc, XY(e->motion.x, e->motion.y));
1.256 +
1.257 + draw();
1.258 + canvas.textReposition(canvas.mytab.mapstorage->getArrowCoords(arc));
1.259 + }
1.260 + default: break;
1.261 + }
1.262 + return true;
1.263 +}