Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drag and drop widgets #5

Open
swanux opened this issue May 19, 2022 · 2 comments
Open

Drag and drop widgets #5

swanux opened this issue May 19, 2022 · 2 comments
Labels
enhancement New feature or request good first issue Good for newcomers help wanted Extra attention is needed

Comments

@swanux
Copy link

swanux commented May 19, 2022

I came across your repo recently, and finally found an example drag and drop implementation in GTK4 - also, the whole repo is impressive.

Though, I tried to modify the example, so it supports dragging and dropping the widgets (for example to reorder the labels) but no luck so far. Do you have any idea for this scenario?

@natorsc
Copy link
Owner

natorsc commented May 19, 2022

Hello @swanux.

Thank you very much!

Over the weekend I will try to recreate the scenario you described.

The only reference I could find was an example in C in the Gtk 4 demo, I'll try to recreate it in Python:

gtk4-drag-and-drop

If you have any tips or tutorials, be sure to share them here 😁.

@swanux
Copy link
Author

swanux commented May 20, 2022

Hello @natorsc

Thank you for the response.

I took a look into the demo app, and translated the part of the code I thought may be relevant (not a proper translation, just a quick overview).
Here it is:

C:

static void
canvas_item_init (CanvasItem *item)
{
  char *text;
  char *id;
  GdkRGBA rgba;
  GtkDropTarget *dest;
  GtkGesture *gesture;
  GType types[2] = { GDK_TYPE_RGBA, G_TYPE_STRING };

  n_items++;

  text = g_strdup_printf ("Item %d", n_items);
  item->label = gtk_label_new (text);
  gtk_widget_add_css_class (item->label, "canvasitem");
  g_free (text);

  item->fixed = gtk_fixed_new ();
  gtk_widget_set_parent (item->fixed, GTK_WIDGET (item));
  gtk_fixed_put (GTK_FIXED (item->fixed), item->label, 0, 0);

  gtk_widget_add_css_class (item->label, "frame");

  id = g_strdup_printf ("item%d", n_items);
  gtk_widget_set_name (item->label, id);
  g_free (id);

  if (theme_is_dark ())
    gdk_rgba_parse (&rgba, "blue");
  else
    gdk_rgba_parse (&rgba, "yellow");

  set_color (item, &rgba);

  item->angle = 0;

  dest = gtk_drop_target_new (G_TYPE_INVALID, GDK_ACTION_COPY);
  gtk_drop_target_set_gtypes (dest, types, G_N_ELEMENTS (types));
  g_signal_connect (dest, "drop", G_CALLBACK (item_drag_drop), NULL);
  gtk_widget_add_controller (GTK_WIDGET (item->label), GTK_EVENT_CONTROLLER (dest));

  gesture = gtk_gesture_rotate_new ();
  g_signal_connect (gesture, "angle-changed", G_CALLBACK (angle_changed), NULL);
  g_signal_connect (gesture, "end", G_CALLBACK (rotate_done), NULL);
  gtk_widget_add_controller (GTK_WIDGET (item), GTK_EVENT_CONTROLLER (gesture));

  gesture = gtk_gesture_click_new ();
  g_signal_connect (gesture, "released", G_CALLBACK (click_done), NULL);
  gtk_widget_add_controller (GTK_WIDGET (item), GTK_EVENT_CONTROLLER (gesture));
}

Python:

def canvas_item_init(item):
    text = "Item %d" % n_items
    item.label = Gtk.Label(text)
    item.label.get_style_context().add_class("canvasitem")
    item.fixed = Gtk.Fixed()
    item.fixed.set_parent(item)
    item.fixed.put(item.label, 0, 0)
    item.label.get_style_context().add_class("frame")
    id = "item%d" % n_items
    item.label.set_name(id)
    if theme_is_dark():
        rgba = Gdk.RGBA()
        rgba.parse("blue")
    else:
        rgba = Gdk.RGBA()
        rgba.parse("yellow")
    set_color(item, rgba)
    item.angle = 0
    dest = Gtk.DropTarget.new(GObject.TYPE_INVALID, Gdk.DragAction.COPY)
    dest.set_gtypes([Gdk.RGBA, GObject.TYPE_STRING])
    dest.connect("drop", item_drag_drop)
    item.label.add_controller(dest)
    gesture = Gtk.GestureRotate.new()
    gesture.connect("angle-changed", angle_changed)
    gesture.connect("end", rotate_done)
    item.add_controller(gesture)
    gesture = Gtk.GestureClick.new()
    gesture.connect("released", click_done)
    item.add_controller(gesture)

Also, here's an auto-generated API documentation (I find it useful overall): https://amolenaar.github.io/pgi-docgen/

Currently I believe the issue is with the Gtk.DropTarget and what type it accepts - as tested with your code I get every signal emitted, except tha drop which would be the point. Also the usual dnd highlight doesn't appear.

Edit:
Here are some other resources concerning dnd in GTK4 and Python
https://stackoverflow.com/questions/70921068/drag-and-drop-with-gtk4-connecting-dragsource-and-droptarget-via-contentprovide

This one for the types maybe (based on the API doc):
https://stackoverflow.com/questions/24795405/gdk-type-pixbuf-in-gtk-3

@natorsc natorsc added the help wanted Extra attention is needed label May 23, 2022
@natorsc natorsc self-assigned this May 23, 2022
@natorsc natorsc pinned this issue May 23, 2022
@natorsc natorsc removed their assignment May 23, 2022
@natorsc natorsc added enhancement New feature or request good first issue Good for newcomers labels May 24, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request good first issue Good for newcomers help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants