Drag&Drop en Gtkmm

8 views
Skip to first unread message

Gabriel Raineri

unread,
Oct 31, 2008, 7:28:33 AM10/31/08
to 7542 - Taller de Programación
Muchachos,

Ante mi desesperación de no poder mover un círculo usando Gtkmm y
Cairo (claro, en realidad no es un círculo sino un dibujo, o sea, una
consecución de puntitos con lo cual, ¿cómo demonios sabe Gtkmm que eso
es un Widget?) mandé un mensaje a la lista de Cairo.

Quería compartirlo con ustedes por si a alguien le es útil:

Pregunta
-----------------------
Hi all!
I'm using Gtkmm and Cairo.
My idea is to draw a bunch of circles in a Gtk::DrawingArea and make
them
draggable but I don't know how to do this.

Any help will be really appreciated.

Thanks a lot in advance!
Cheers,
Gabe

Respuesta
---------------------
You need a scenegraph, there are many cairo based ones available for
GTK.
Otherwise you will have to make your own by storing the shapes as
objects
and handling and testing for mouse events. This is not something cairo
provides. To test for a point in cairo you can use cairo_in_fill and
cairo_in_stroke but in my own code I just use bounding boxes.
Depending on
your requirements first check out the existing gtk scenegraphs/canvas
projects (http://live.gnome.org/ProjectRidley/CanvasOverview) or even
custom GTK widgets before going it alone.

~Gerdus

Leandro Fernández

unread,
Oct 31, 2008, 7:59:30 AM10/31/08
to tallerdepr...@googlegroups.com
No soy experto en Cairo. Pero me parece que hay un error conceptual. El circulo o cualquier otra cosa que dibujes en el drawing area no es un widget. Para implementar el drag and drop, el drawing area deberá enterarse de que le está llegando X figura y luego informarlo al modelo; una  vez que el usuario lo suelta.

¿Qué tan avanzada está la funcionalidad de tu drawing area y su comunicación con el modelo?

2008/10/31 Gabriel Raineri <grai...@gmail.com>



--
_Leo_
[http://www.eeeuser.com.ar]

Gabriel Raineri

unread,
Oct 31, 2008, 11:44:24 AM10/31/08
to 7542 - Taller de Programación
Claro, es lo que intenté decir en mi mail:
"...en realidad no es un círculo sino un dibujo, o sea, una
consecución de puntitos con lo cual, ¿cómo demonios sabe Gtkmm que
eso
es un Widget?"

La pregunta es retórica. Es decir, Gtkmm no tiene idea que eso es un
Widget. =)

Por suerte no está muy avanzada y estamos buscando una manera de
resolver esto.

Estamos investigando varias alternativas. Queríamos ver si podíamos
hacer en Gtkmm pero sino iremos para el lado de SDL.

¡Gracias Leo por tu respuesta!


On Oct 31, 9:59 am, "Leandro Fernández" <drkb...@gmail.com> wrote:
> No soy experto en Cairo. Pero me parece que hay un error conceptual. El
> circulo o cualquier otra cosa que dibujes en el drawing area no es un
> widget. Para implementar el drag and drop, el drawing area deberá enterarse
> de que le está llegando X figura y luego informarlo al modelo; una  vez que
> el usuario lo suelta.
>
> ¿Qué tan avanzada está la funcionalidad de tu drawing area y su comunicación
> con el modelo?
>
> 2008/10/31 Gabriel Raineri <grain...@gmail.com>

Leandro Fernández

unread,
Oct 31, 2008, 12:07:55 PM10/31/08
to tallerdepr...@googlegroups.com
Vos tenés que programar el comportamiento del que hablás. Sin importar si estás con Gtkmm o SDL.

Tu aplicación va a mostrar un área de trabajo y una serie de elementos "arrastrables". Estos pueden ser widgets de gtk o cualquier otra cosa. Si lo haces con widgets posiblemente Gtk te resuelva el drag y el drop sobre el drawing area. En ese momento vas a tener que interpretar el drop y generar un dibujo en el lugar correspondiente.
La otra posibilidad es que los arrastrables ya estén dentro del drawing area, en un apartado destinado a hacer las veces de toolbar. En ese caso el drag and drop sería completamente dentro de tu modelo y gtkmm no se enteraría.

Lo que acabo de escribir refiere a dos formas de solucionar el mismo problema. La primera asume que un widget de gtkmm se puede arrastrar sin tener que programar demasiado. La segunda es más simple, porque eso lo tenés que hacer de todas formas. Siempre tengo que poder arrastrar objetos DENTRO del espacio de trabajo. Tanto en el editor como en el cliente.

2008/10/31 Gabriel Raineri <grai...@gmail.com>



--
_Leo_
[http://www.eeeuser.com.ar]

Federico Vidueiro

unread,
Oct 31, 2008, 2:26:03 PM10/31/08
to tallerdepr...@googlegroups.com
Gabriel yo lo hice en opengl, lo que tengo son estructuras que conocen la posicion de los vertices de las figuras y en base a eso se dibujan. Por otro lado tomo los eventos del mouse y comparo con los objetos para ver si esta sobre alguno de ellos (comparando con las posiciones de los puntos de la figura) si es asi modifico la posicion de la figura modificando la posicion de los puntos a la nueva posicion del mouse. Efecto, cuando se vuelve a dibujar la figura se dibuja en la nueva posicion.
La contra de esto es que en los eventos de mouse down checkeo todos los objetos a ver si coninciden con la posicion del mouse alguno...

Mariano Chouza

unread,
Oct 31, 2008, 2:37:53 PM10/31/08
to tallerdepr...@googlegroups.com
2008/10/31 Federico Vidueiro <vidu...@gmail.com>:

> La contra de esto es que en los eventos de mouse down checkeo todos los
> objetos a ver si coninciden con la posicion del mouse alguno...

En general esto no es un problema, ya que "alguien tiene que hacerlo":
la deteccion de eventos sobre los "widgets" no es gratis. Si bien
existen métodos [1][2][3] para evitar revisar *todos* los objetos por
cada evento del mouse, no hacen una gran diferencia al trabajar
cantidades pequeñas de objetos (en el orden de 100 o menos).

Saludos.

[1] http://en.wikipedia.org/wiki/Quadtree
[2] http://lab.polygonal.de/2007/09/09/quadtree-demonstration/
[3] http://homepages.ge.ucl.ac.uk/~mhaklay/java.htm

--
Mariano M. Chouza
http://www.chouza.com.ar/
http://spin-foam.blogspot.com/

"Since the beginning, not one unusual thing has ever happened."
-- Eliezer Yudkowsky

Ezequiel Damico

unread,
Oct 31, 2008, 3:35:54 PM10/31/08
to tallerdepr...@googlegroups.com
Federico tirale el algoritmo (nombre si es q tiene) que usaste para saber si el puntero esta dentro de un poligono porque sino van a morir en el intento.

Eze

Mariano Chouza

unread,
Oct 31, 2008, 3:37:48 PM10/31/08
to tallerdepr...@googlegroups.com
2008/10/31 Ezequiel Damico <ezed...@gmail.com>:

> Federico tirale el algoritmo (nombre si es q tiene) que usaste para saber si
> el puntero esta dentro de un poligono porque sino van a morir en el intento.

http://en.wikipedia.org/wiki/Point_in_polygon

Federico Vidueiro

unread,
Oct 31, 2008, 6:04:55 PM10/31/08
to tallerdepr...@googlegroups.com
obviamente que si la figura es una circunferencia es mas fácil, solo necesita saber si la distancia entre el centro y el mouse es menor al radio. y en el caso de un rectángulo también es sencillo (caso particular de un polígono)

Gabriel Raineri

unread,
Oct 31, 2008, 9:13:43 PM10/31/08
to 7542 - Taller de Programación
¡Millones de gracias a todos!

Ya pude capturar correctamente los eventos del mouse en un DrawingArea
de Gtkmm (era eso un poco lo que me preocupaba).

Con respecto a la lógica, era consciente que seguramente hubiera que
aplicar algún algoritmo que me permitiese identificar si en el lugar
donde se hizo click hay alguna figura.

Para aquellos que utilicen Gtkmm, el DrawingArea no acepta por defecto
los eventos de click del mouse, con lo cual hay que agregarlos.
¿Cómo se hace?
myDrawingArea.add_events(Gdk::BUTTON_PRESS_MASK);
myDrawingArea.add_events(Gdk::BUTTON_RELEASE_MASK);

Luego se hace el binding típico al método que maneje al evento.
Por ejemplo:
myDrawingArea.signal_button_press_event().connect(sigc::mem_fun(*this,
&MyWindow::onClick));

Donde el método onClick debe ser de respetar la siguiente signatura:
bool onClick(GdkEventButton* event) { ... }

Con eso ya estaríamos en condiciones de capturar los eventos del mouse
sobre un DrawingArea.
GdkEventButton posee información útil sobre el evento (posición X,
posición Y, etc, etc...)

Les agradezco una vez más a todos.

Saludos,
Gaby



On Oct 31, 8:04 pm, "Federico Vidueiro" <viduei...@gmail.com> wrote:
> obviamente que si la figura es una circunferencia es mas fácil, solo
> necesita saber si la distancia entre el centro y el mouse es menor al radio.
> y en el caso de un rectángulo también es sencillo (caso particular de un
> polígono)
>
> El 31 de octubre de 2008 17:37, Mariano Chouza <mcho...@gmail.com> escribió:
>
>
>
> > 2008/10/31 Ezequiel Damico <ezedam...@gmail.com>:
Reply all
Reply to author
Forward
0 new messages