After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 109832 - Lines' points change without warning
Lines' points change without warning
Status: RESOLVED WONTFIX
Product: libgnomecanvasmm
Classification: Deprecated
Component: general
git master
Other Linux
: Normal normal
: ---
Assigned To: libgnomecanvasmm-maint
libgnomecanvasmm-maint
gnome[unmaintained]
Depends on:
Blocks:
 
 
Reported: 2003-04-03 01:10 UTC by Ethan Glasser-Camp
Modified: 2014-08-02 12:48 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
lines.cc (3.29 KB, text/plain)
2003-07-21 20:33 UTC, Murray Cumming
Details

Description Ethan Glasser-Camp 2003-04-03 01:10:23 UTC

Comment 1 Ethan Glasser-Camp 2003-04-03 01:17:18 UTC
Oops.. sorry about the above.

I'm making an application with Gnome::Canvas, and I construct lines
whose endpoints have the potential to move.

So in one event handler, I do:      
      Gnome::Canvas::Points points;   
      points.push_back(Gnome::Art::Point(startx,starty));
      points.push_back(Gnome::Art::Point(event->button.x,
event->button.y));
      Gnome::Canvas::Line * line = 
	manage(new Gnome::Canvas::Line(*tmpgrp->get_canvas()->root(), points));
      (*i)->lines.push_back(line);

(This is done twice -- two lines are constructed at different points.)

Then, in another event handler, I do this:

	points.push_back(p->lines[i]->property_points().get_value()[0]);
	points.push_back(p->lines[i]->property_points().get_value()[1]);
	points[!p->lines_start_here[i]] += 
	  Gnome::Art::Point(event->button.x - oldx, event->button.y - oldy);
	p->lines[i]->property_points().set_value(points);

In other words, what I'm trying to do is make another
Gnome::Canvas::Points, and alter one of the points, and then set the
line's points to the altered point.

But what I'm finding is that by the time I get to the first line to
move it, the endpoints have already changed -- specifically, the
second endpoint changes to the second endpoint of the second line.

Does anyone have any ideas? I can send you the source code of the
entire project, if you like.
Comment 2 Murray Cumming 2003-04-03 06:18:26 UTC
A simple-as-possible test case might make this clearer.
Comment 3 Ethan Glasser-Camp 2003-04-03 06:58:45 UTC
OK. Here's a simple program that tries to do the same thing. It's 113
lines.

#include <libgnomecanvasmm/canvas.h>
#include <libgnomecanvasmm/init.h>
#include <libgnomecanvasmm/line.h>
#include <libgnomecanvasmm/rect.h>
#include <gtkmm/window.h>
#include <gtkmm/main.h>
#include <iostream>
#include <vector>
using std::vector;
using std::endl;
using std::cout;

class Simpletest: public Gtk::Window {
public:
  Simpletest();

protected:
  vector<Gnome::Canvas::Line*> lines;
  Gnome::Canvas::Canvas * canvas;
  bool on_item_event(GdkEvent* event);
};


Simpletest::Simpletest(){
  canvas = manage(new Gnome::Canvas::Canvas());
  add(*canvas);
  canvas->set_flags(Gtk::CAN_FOCUS);
  canvas->set_size_request(600, 400);
  canvas->set_center_scroll_region(false);
  Gnome::Canvas::Rect* rect = manage(new
Gnome::Canvas::Rect(*canvas->root()));
  rect->property_x1() = 0.0;
  rect->property_y1() = 0.0;
  rect->property_x2() = 600.0;
  rect->property_y2() = 400.0;
  rect->property_fill_color_rgba() = 0x10308000;
  Gnome::Canvas::Points points;   
  points.push_back(Gnome::Art::Point(100, 100));
  points.push_back(Gnome::Art::Point(200, 200));
  Gnome::Canvas::Line * line = 
    manage(new Gnome::Canvas::Line(*canvas->root(), points));
  lines.push_back(line);
  points[0] = Gnome::Art::Point(100, 200);
  points[1] = Gnome::Art::Point(200, 100);
  line = manage(new Gnome::Canvas::Line(*canvas->root(), points));
  lines.push_back(line);
  rect->signal_event()
    .connect(slot(*this, &Simpletest::on_item_event));
  canvas->update_now();
  show_all();
  cout << lines[0]->property_points().get_value().size() << endl;
  cout << lines[0]->property_points().get_value()[1].get_y() << endl;
}


bool Simpletest::on_item_event(GdkEvent * event){
  static double startx, starty;
  static double oldx, oldy;
  static int button;
  static bool dragging;
  //  cout << p->labelstring << endl;
  switch(event->type){
  case GDK_BUTTON_PRESS:
    startx = event->button.x;
    starty = event->button.y;
    oldx = startx;
    oldy = starty;
    button = event->button.button;
    return true;
    break;
  case GDK_MOTION_NOTIFY:
    if(button == 1){
      dragging = true;
      for(int i = 0; i < lines.size(); i++){
	Gnome::Canvas::Points points;
	points.push_back(lines[i]->property_points().get_value()[0]);
	points.push_back(lines[i]->property_points().get_value()[1]);
	//points.push_back(p->lines[i]->property_points().get_value()[2]);
	cout << lines[i]->property_points().get_value().size() << endl;

	cout << points[0].get_x() << ", " << points[0].get_y()
	     << " -> " << points[1].get_x() << ", " << points[1].get_y()
	     << " Delta: " << event->button.x - oldx << ", "
	     << event->button.y - oldy << endl;
	points[0] += 
	  Gnome::Art::Point(event->button.x - oldx, event->button.y - oldy);
	//	cout << points.size() << endl;
	cout << points[0].get_x() << ", " << points[0].get_y()
	     << " -> " << points[1].get_x() << ", " << points[1].get_y()
	     << endl;
	lines[i]->property_points().set_value(points);
      }
	canvas->update_now();
	cout << endl;
      oldx = event->button.x;
      oldy = event->button.y;
    }
    return true;
    break;
  case GDK_BUTTON_RELEASE:
    button = 0;
    return true;
    break;
  }
  return false;
}
int main(int argc, char * argv[]){
  Gnome::Canvas::init();
  Gtk::Main app(argc, argv);
  Simpletest sbw;
  app.run(sbw);
  return 0;
}


What I think should happen:
The first line should print out 2. That is the first cout -- it
happens at the end of the Simpletest constructor. The
line.property_points().get_value() should be a vector of two points,
shouldn't it? Maybe I misinterpreted the function names.

The second line should be 200. lines[0] is the first line pointer,
constructed from (100, 100) to (200, 200).
lines[0]->property_points.get_value()[1] should be the second
Gnome::Art::Point, (200, 200). Thus, the y coord should be 200.

Click the blue rectangle and move it around. The lines move -- but
IMMEDIATELY the first line relocates its second point to be the same
as the second line's second point. This is the phenomenon I'm getting.
The output shows each line's endpoints before and after the move
(delta is how much they should move by). It is entirely possible that
I wrote bad code.
Comment 4 Ethan Glasser-Camp 2003-04-03 07:28:27 UTC
OK, I just cut and pasted the first cout statement to right after line
is created, and right after it has been pushed back, and it stays the
same (not 200). Neither is it 200 if I change it to get_x(). So I'm
obviously missing the point.

line->property_points() returns PropertyProxy<Gnome::Canvas::Points>.
line->property_points().get_value() should return
Gnome::Canvas::Points, which is essentially a std::vector. Thus, when
I create a line with a Gnome::Canvas::Points with two points in it,
that vector should be size two, with those two points at vector[0] and
vector[1].
line->property_points().get_value()[1] should be one of those points
-- Gnome::Art::Point -- the second endpoint. 
(line->property_points().get_value()[0] remains (100, 100))
line->property_points().get_value()[1].get_y() should be the y-coord
of the second endpoint of the line.

Which parts of the above are wrong?
Comment 5 Murray Cumming 2003-04-04 06:45:48 UTC
I have not read this yet. In future, please _attach_ test cases so
things remain readable.
Comment 6 Murray Cumming 2003-04-21 11:39:02 UTC
We need to investigate what happens in this set_property() line in the
Gnome::Canvas::Line constructor:
http://cvs.gnome.org/lxr/source/gnomemm/libgnomecanvasmm/libgnomecanvas/src/line.ccg#103
Comment 7 Murray Cumming 2003-07-21 20:33:49 UTC
Created attachment 18494 [details]
lines.cc
Comment 8 Murray Cumming 2003-07-21 20:36:15 UTC
The attached version of the test case (lines.cc) shows the problem
more clearly. It looks like GnomeCanvasLine does not take a copy of
the points data, but just remembers the pointer. So in the first
example you are changing data that is still used by another Line, and
in my version it segfaults because the pointer is orphaned.

We should probably either
- Mark this as a libgnomecanvas bug.
or
- Document it.  
Comment 9 Murray Cumming 2003-07-23 09:21:23 UTC
We could also add a member variable to store our own copy, but that
would break ABI.
Comment 10 André Klapper 2014-08-02 12:48:30 UTC
The last libgnomecanvasmm code changes took place in 2008:
https://git.gnome.org/browse/archive/libgnomecanvasmm/log/

This project is not under active development anymore.

This project got recently archived in GNOME Git.

It is currently unlikely that there will be any further active development.

Closing this report as WONTFIX as part of Bugzilla Housekeeping to reflect reality. Please feel free to reopen this bug report in the future if anyone takes the responsibility for active development again.