Tk canvas drag items

Could somebody kindly direct me to a Ruby Tk example of dragging a
tagged canvas item using canvas coordinates?

There are one or two examples supplied in Ruby 1.8.6 (Probably thanks to
Nagai-san) that allow for selecting canvas items and dragging them, but
they use the window's coordinates, and I can't figure out how to change
the code so it uses canvasx and canvasy.

Also, I'd like to know how to query a canvas item to determine its x
or y coordinate.

Any help would be much appreciated.

···

--
Posted via http://www.ruby-forum.com/.

Hi,

···

From: Ignatz Hafflegab <mcpeople@hotmail.com>
Subject: tk canvas drag items
Date: Sat, 26 Feb 2011 13:38:03 +0900
Message-ID: <f3ded5a806f226cea24a5965af3da4a5@ruby-forum.com>

Could somebody kindly direct me to a Ruby Tk example of dragging a
tagged canvas item using canvas coordinates?

There are one or two examples supplied in Ruby 1.8.6 (Probably thanks to
Nagai-san) that allow for selecting canvas items and dragging them, but
they use the window's coordinates, and I can't figure out how to change
the code so it uses canvasx and canvasy.

Could you tell me your purpose? If you want to drag items only,
you don't need coordinates but difference of coordinates to move.
The difference doesn't depend on whether it is based on canvas
coordinates or screen coordinates (see ext/tk/sample/demoes-en/plot.rb
on ruby's source tree).

Also, I'd like to know how to query a canvas item to determine its x
or y coordinate.

For example,
--------------------------------------------------------------
c = TkCanvas.new
  ...
c.bind('1', :x, :y){|x,y| # (x,y) is screen coordinates
  cx = c.canvasx x # get canvas x coordinate
  cy = c.canvasy y # get canvas y coordinate
  p c.find_closest(cx,cy) # find an item which is closest to (cx,cy)
  p c.find_overlapping(cx,cy,cx,cy) # find items which is under (cx,cy)
  p c.find_overlapping(cx-2,cy-2,cx+2,cy+2)
                          # find items loosely about clicked position
}
--------------------------------------------------------------

If you find items which have given coords in coords list,
--------------------------------------------------------------
c.find_overlapping(cx,cy,cx,cy).find_all{|item|
  item.coords.each_slice(2).collect.include? [cx, cy]
}
--------------------------------------------------------------
--
Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
Department of Artificial Intelligence, Kyushu Institute of Technology

Thank you very much for your reply. I hope that you didn't feel
obligated because I dropped your name. It was mentioned because I was
grateful for the samples included in the 1.8.6 Ruby installer.

The plot.rb sample prompted my ambiguous questions. I wanted to
constrain the points to the actual size of the canvas. When
plot.rb's window is not maximized, a point can be dragged completely off
the canvas. If it is dragged off the east edge of the canvas, it will
reappear when the window is maximized. I assume that's because the
canvas is set to FILL X. However, if a point is dragged far enough off
of the west, north, or south edge when the canvas is not maximized, it
is consigned to oblivion, and it will not be see again.

What I'm looking for is an example that will confine a selected item
within the boundaries fixed-size canvas while the item is dragged.

···

--
Posted via http://www.ruby-forum.com/.

Message-ID: <70c564908d72fa5bff5bb1fd5b562698@ruby-forum.com>

What I'm looking for is an example that will confine a selected item
within the boundaries fixed-size canvas while the item is dragged.

It's not difficult.
Please select "A simple 2-D plot" on widget-demo,
and press "Show Code" button on the plot-demo window.
On the "Demo Code" window, please edit plotMove method like the following.

···

From: Ignatz Hafflegab <mcpeople@hotmail.com>
Subject: Re: tk canvas drag items
Date: Tue, 1 Mar 2011 12:06:19 +0900
-----------------------------------------------------
def plotMove (w, x, y)
  if x < 0
    x = 0
  else
    width = w.winfo_width
    x = width if x > width
  end
  if y < 0
    y = 0
  else
    height = w.winfo_height
    y = height if y > height
  end
  w.move 'selected', x - $plot['lastX'], y - $plot['lastY']
  $plot['lastX'] = x
  $plot['lastY'] = y
end
-----------------------------------------------------
As you see, it checks whether the coordinates are within the canvas window.
If you want control the region by canvas coordinates, you mark (on PlotDown
method) and check coords by canvas coords.

After editing, click "Rerun Demo" button on the editor window.
And then, dragging the points on the restarted demo will be restricted
by the canvas window size.
--
Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
Department of Artificial Intelligence, Kyushu Institute of Technology