forked from AuroraMiddleware/gtk
Compare commits
10 Commits
main
...
matthiasc/
Author | SHA1 | Date | |
---|---|---|---|
|
4dafd10201 | ||
|
58af693e79 | ||
|
b4bb8c61a6 | ||
|
e7df61455b | ||
|
e5e08cc0d7 | ||
|
eb828a5d76 | ||
|
53bd9f5443 | ||
|
fedb7a8809 | ||
|
9dcc24e7bf | ||
|
eaf79cb1f0 |
@ -12,6 +12,7 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include <string.h>
|
||||
#include "demoimage.h"
|
||||
#include "gtkthrobber.h"
|
||||
|
||||
static void
|
||||
copy_button_clicked (GtkStack *source_stack,
|
||||
@ -364,6 +365,26 @@ drag_prepare (GtkDragSource *drag_source,
|
||||
return gdk_content_provider_new_for_value (&value);
|
||||
}
|
||||
|
||||
static void
|
||||
drag_begin (GtkDragSource *drag_source,
|
||||
GdkDrag *drag,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkWidget *button;
|
||||
GdkFrameClock *clock;
|
||||
GdkPaintable *paintable;
|
||||
|
||||
button = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (drag_source));
|
||||
clock = gtk_widget_get_frame_clock (button);
|
||||
paintable = gtk_throbber_new (clock,
|
||||
"/transparent/portland-rose.jpg",
|
||||
0.02, 0.1,
|
||||
drag);
|
||||
|
||||
gtk_drag_source_set_icon (drag_source, paintable, 10, 10);
|
||||
g_object_unref (paintable);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
do_clipboard (GtkWidget *do_widget)
|
||||
{
|
||||
@ -384,6 +405,7 @@ do_clipboard (GtkWidget *do_widget)
|
||||
gtk_builder_cscope_add_callback (scope, open_folder_cb);
|
||||
gtk_builder_cscope_add_callback (scope, on_drop);
|
||||
gtk_builder_cscope_add_callback (scope, drag_prepare);
|
||||
gtk_builder_cscope_add_callback (scope, drag_begin);
|
||||
builder = gtk_builder_new ();
|
||||
gtk_builder_set_scope (builder, scope);
|
||||
gtk_builder_add_from_resource (builder, "/clipboard/clipboard.ui", NULL);
|
||||
|
@ -91,6 +91,7 @@
|
||||
<child>
|
||||
<object class="GtkDragSource">
|
||||
<signal name="prepare" handler="drag_prepare"/>
|
||||
<signal name="drag-begin" handler="drag_begin"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
|
174
demos/gtk-demo/gtkthrobber.c
Normal file
174
demos/gtk-demo/gtkthrobber.c
Normal file
@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Copyright © 2018 Benjamin Otte
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Benjamin Otte <otte@gnome.org>
|
||||
*/
|
||||
|
||||
#include "gtkthrobber.h"
|
||||
|
||||
#include "gtk.h"
|
||||
|
||||
struct _GtkThrobber
|
||||
{
|
||||
GObject parent_instance;
|
||||
|
||||
GdkFrameClock *clock;
|
||||
GdkTexture *texture;
|
||||
guint clock_tick_id;
|
||||
|
||||
float min, max, scale, delta;
|
||||
float delta2, hot;
|
||||
|
||||
GdkDrag *drag;
|
||||
};
|
||||
|
||||
struct _GtkThrobberClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
static void
|
||||
gtk_throbber_paintable_snapshot (GdkPaintable *paintable,
|
||||
GdkSnapshot *snapshot,
|
||||
double width,
|
||||
double height)
|
||||
{
|
||||
GtkThrobber *self = GTK_THROBBER (paintable);
|
||||
|
||||
gtk_snapshot_append_texture (snapshot, self->texture, &GRAPHENE_RECT_INIT (0, 0, width, height));
|
||||
}
|
||||
|
||||
static int
|
||||
gtk_throbber_paintable_get_intrinsic_width (GdkPaintable *paintable)
|
||||
{
|
||||
GtkThrobber *self = GTK_THROBBER (paintable);
|
||||
|
||||
return gdk_texture_get_width (self->texture) * self->scale;
|
||||
}
|
||||
|
||||
static int
|
||||
gtk_throbber_paintable_get_intrinsic_height (GdkPaintable *paintable)
|
||||
{
|
||||
GtkThrobber *self = GTK_THROBBER (paintable);
|
||||
|
||||
return gdk_texture_get_height (self->texture) * self->scale;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_throbber_paintable_init (GdkPaintableInterface *iface)
|
||||
{
|
||||
iface->snapshot = gtk_throbber_paintable_snapshot;
|
||||
iface->get_intrinsic_width = gtk_throbber_paintable_get_intrinsic_width;
|
||||
iface->get_intrinsic_height = gtk_throbber_paintable_get_intrinsic_height;
|
||||
}
|
||||
|
||||
G_DEFINE_TYPE_EXTENDED (GtkThrobber, gtk_throbber, G_TYPE_OBJECT, 0,
|
||||
G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE,
|
||||
gtk_throbber_paintable_init))
|
||||
|
||||
static void
|
||||
gtk_throbber_dispose (GObject *object)
|
||||
{
|
||||
GtkThrobber *self = GTK_THROBBER (object);
|
||||
|
||||
gdk_frame_clock_end_updating (self->clock);
|
||||
g_signal_handler_disconnect (self->clock, self->clock_tick_id);
|
||||
self->clock_tick_id = 0;
|
||||
|
||||
g_clear_object (&self->clock);
|
||||
g_clear_object (&self->texture);
|
||||
g_clear_object (&self->drag);
|
||||
|
||||
G_OBJECT_CLASS (gtk_throbber_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_throbber_class_init (GtkThrobberClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
gobject_class->dispose = gtk_throbber_dispose;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_throbber_init (GtkThrobber *self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
on_frame_clock_update (GdkFrameClock *clock,
|
||||
GtkThrobber *self)
|
||||
{
|
||||
self->scale += self->delta;
|
||||
if (self->scale >= self->max)
|
||||
{
|
||||
self->scale = self->max;
|
||||
self->delta = - self->delta;
|
||||
}
|
||||
else if (self->scale <= self->min)
|
||||
{
|
||||
self->scale = self->min;
|
||||
self->delta = - self->delta;
|
||||
}
|
||||
|
||||
self->hot += self->delta2;
|
||||
if (self->hot >= 1.)
|
||||
{
|
||||
self->hot = 1.;
|
||||
self->delta2 = - self->delta2;
|
||||
}
|
||||
else if (self->hot <= 0.)
|
||||
{
|
||||
self->hot = 0.;
|
||||
self->delta2 = - self->delta2;
|
||||
}
|
||||
|
||||
gdk_paintable_invalidate_size (GDK_PAINTABLE (self));
|
||||
|
||||
gdk_drag_set_hotspot (self->drag,
|
||||
gdk_texture_get_width (self->texture) * self->scale * self->hot,
|
||||
gdk_texture_get_height (self->texture) * self->scale * self->hot);
|
||||
}
|
||||
|
||||
|
||||
GdkPaintable *
|
||||
gtk_throbber_new (GdkFrameClock *clock,
|
||||
const char *resource_path,
|
||||
float min,
|
||||
float max,
|
||||
GdkDrag *drag)
|
||||
{
|
||||
GtkThrobber *self;
|
||||
|
||||
self = g_object_new (GTK_TYPE_THROBBER, NULL);
|
||||
|
||||
self->clock = g_object_ref (clock);
|
||||
self->texture = gdk_texture_new_from_resource (resource_path);
|
||||
self->drag = g_object_ref (drag);
|
||||
self->min = min;
|
||||
self->max = max;
|
||||
self->scale = min;
|
||||
self->delta = (max - min) / (15 * 16);
|
||||
self->delta2 = 1. / (10 * 16);
|
||||
self->hot = 0.;
|
||||
|
||||
self->clock_tick_id = g_signal_connect (self->clock, "update",
|
||||
G_CALLBACK (on_frame_clock_update), self);
|
||||
|
||||
gdk_frame_clock_begin_updating (self->clock);
|
||||
|
||||
return GDK_PAINTABLE (self);
|
||||
}
|
36
demos/gtk-demo/gtkthrobber.h
Normal file
36
demos/gtk-demo/gtkthrobber.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright © 2023 Matthias Clasen
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors: Benjamin Otte <otte@gnome.org>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_THROBBER (gtk_throbber_get_type ())
|
||||
|
||||
G_DECLARE_FINAL_TYPE (GtkThrobber, gtk_throbber, GTK, THROBBER, GObject)
|
||||
|
||||
GdkPaintable * gtk_throbber_new (GdkFrameClock *clock,
|
||||
const char *resource_path,
|
||||
float min,
|
||||
float max,
|
||||
GdkDrag *drag);
|
||||
|
||||
G_END_DECLS
|
@ -134,6 +134,7 @@ extra_demo_sources = files([
|
||||
'unicode-names.c',
|
||||
'suggestionentry.c',
|
||||
'language-names.c',
|
||||
'gtkthrobber.c',
|
||||
])
|
||||
|
||||
if os_unix
|
||||
|
@ -37,6 +37,22 @@
|
||||
|
||||
G_DEFINE_INTERFACE (GdkDragSurface, gdk_drag_surface, GDK_TYPE_SURFACE)
|
||||
|
||||
enum
|
||||
{
|
||||
COMPUTE_SIZE,
|
||||
|
||||
N_SIGNALS
|
||||
};
|
||||
|
||||
static guint signals[N_SIGNALS] = { 0 };
|
||||
|
||||
void
|
||||
gdk_drag_surface_notify_compute_size (GdkDragSurface *surface,
|
||||
GdkDragSurfaceSize *size)
|
||||
{
|
||||
g_signal_emit (surface, signals[COMPUTE_SIZE], 0, size);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_drag_surface_default_present (GdkDragSurface *drag_surface,
|
||||
int width,
|
||||
@ -49,6 +65,16 @@ static void
|
||||
gdk_drag_surface_default_init (GdkDragSurfaceInterface *iface)
|
||||
{
|
||||
iface->present = gdk_drag_surface_default_present;
|
||||
|
||||
signals[COMPUTE_SIZE] =
|
||||
g_signal_new (I_("compute-size"),
|
||||
GDK_TYPE_DRAG_SURFACE,
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL, NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE, 1,
|
||||
GDK_TYPE_DRAG_SURFACE_SIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define __GDK_DRAG_SURFACE_PRIVATE_H__
|
||||
|
||||
#include "gdkdragsurface.h"
|
||||
#include "gdkdragsurfacesize.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@ -15,6 +16,9 @@ struct _GdkDragSurfaceInterface
|
||||
int height);
|
||||
};
|
||||
|
||||
void gdk_drag_surface_notify_compute_size (GdkDragSurface *surface,
|
||||
GdkDragSurfaceSize *size);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_DRAG_SURFACE_PRIVATE_H__ */
|
||||
|
53
gdk/gdkdragsurfacesize.c
Normal file
53
gdk/gdkdragsurfacesize.c
Normal file
@ -0,0 +1,53 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2023 Red Hat
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkdragsurfacesizeprivate.h"
|
||||
|
||||
/**
|
||||
* GdkDragSurfaceSize:
|
||||
*
|
||||
* The `GdkDragSurfaceSize` struct contains information that is useful
|
||||
* to compute the size of a drag surface.
|
||||
*/
|
||||
|
||||
G_DEFINE_POINTER_TYPE (GdkDragSurfaceSize, gdk_drag_surface_size)
|
||||
|
||||
void
|
||||
gdk_drag_surface_size_init (GdkDragSurfaceSize *size)
|
||||
{
|
||||
*size = (GdkDragSurfaceSize) { 0 };
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_drag_surface_size_set_size:
|
||||
* @size: a `GdkDragSurfaceSize`
|
||||
* @width: the width
|
||||
* @height: the height
|
||||
*
|
||||
* Sets the size the drag surface prefers to be resized to.
|
||||
*/
|
||||
void
|
||||
gdk_drag_surface_size_set_size (GdkDragSurfaceSize *size,
|
||||
int width,
|
||||
int height)
|
||||
{
|
||||
size->width = width;
|
||||
size->height = height;
|
||||
}
|
42
gdk/gdkdragsurfacesize.h
Normal file
42
gdk/gdkdragsurfacesize.h
Normal file
@ -0,0 +1,42 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2023 Red Hat
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(__GDK_H_INSIDE__) && !defined(GTK_COMPILATION)
|
||||
#error "Only <gdk/gdk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gdk/gdktypes.h>
|
||||
#include <gdk/gdkversionmacros.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GdkDragSurfaceSize GdkDragSurfaceSize;
|
||||
|
||||
#define GDK_TYPE_DRAG_SURFACE_SIZE (gdk_drag_surface_size_get_type ())
|
||||
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
GType gdk_drag_surface_size_get_type (void);
|
||||
|
||||
GDK_AVAILABLE_IN_4_10
|
||||
void gdk_drag_surface_size_set_size (GdkDragSurfaceSize *size,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
G_END_DECLS
|
29
gdk/gdkdragsurfacesizeprivate.h
Normal file
29
gdk/gdkdragsurfacesizeprivate.h
Normal file
@ -0,0 +1,29 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2023 Red Hat
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "gdkdragsurfacesize.h"
|
||||
|
||||
struct _GdkDragSurfaceSize
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
|
||||
void gdk_drag_surface_size_init (GdkDragSurfaceSize *size);
|
@ -16,6 +16,8 @@ gdk_public_sources = files([
|
||||
'gdkdisplay.c',
|
||||
'gdkdisplaymanager.c',
|
||||
'gdkdrag.c',
|
||||
'gdkdragsurface.c',
|
||||
'gdkdragsurfacesize.c',
|
||||
'gdkdrawcontext.c',
|
||||
'gdkdrop.c',
|
||||
'gdkevents.c',
|
||||
@ -52,7 +54,6 @@ gdk_public_sources = files([
|
||||
'gdktoplevellayout.c',
|
||||
'gdktoplevelsize.c',
|
||||
'gdktoplevel.c',
|
||||
'gdkdragsurface.c',
|
||||
'loaders/gdkpng.c',
|
||||
'loaders/gdktiff.c',
|
||||
'loaders/gdkjpeg.c',
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "gdksurfaceprivate.h"
|
||||
#include "gdktoplevelprivate.h"
|
||||
#include "gdkdevice-wayland-private.h"
|
||||
#include "gdkdragsurfacesizeprivate.h"
|
||||
|
||||
#include <wayland/xdg-shell-unstable-v6-client-protocol.h>
|
||||
#include <wayland/xdg-foreign-unstable-v2-client-protocol.h>
|
||||
@ -78,6 +79,14 @@ gdk_wayland_drag_surface_compute_size (GdkSurface *surface)
|
||||
|
||||
if (impl->next_layout.surface_geometry_dirty)
|
||||
{
|
||||
GdkDragSurfaceSize size;
|
||||
|
||||
gdk_drag_surface_size_init (&size);
|
||||
gdk_drag_surface_notify_compute_size (GDK_DRAG_SURFACE (surface), &size);
|
||||
|
||||
impl->next_layout.configured_width = size.width;
|
||||
impl->next_layout.configured_height = size.height;
|
||||
|
||||
gdk_wayland_surface_update_size (surface,
|
||||
impl->next_layout.configured_width,
|
||||
impl->next_layout.configured_height,
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "gdkglcontext-x11.h"
|
||||
#include "gdkprivate-x11.h"
|
||||
#include "gdktextureprivate.h"
|
||||
#include "gdkdragsurfacesizeprivate.h"
|
||||
|
||||
#include "gdkseatprivate.h"
|
||||
#include "gdkprivate.h"
|
||||
@ -345,6 +346,37 @@ compute_toplevel_size (GdkSurface *surface,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
compute_drag_surface_size (GdkSurface *surface,
|
||||
int *width,
|
||||
int *height)
|
||||
{
|
||||
GdkX11Surface *impl = GDK_X11_SURFACE (surface);
|
||||
GdkDragSurfaceSize size;
|
||||
int new_width, new_height;
|
||||
|
||||
gdk_drag_surface_size_init (&size);
|
||||
gdk_drag_surface_notify_compute_size (GDK_DRAG_SURFACE (surface), &size);
|
||||
|
||||
new_width = size.width;
|
||||
new_height = size.height;
|
||||
|
||||
if ((impl->last_computed_width != new_width ||
|
||||
impl->last_computed_height != new_height) &&
|
||||
(impl->next_layout.configured_width != new_width ||
|
||||
impl->next_layout.configured_height != new_height))
|
||||
{
|
||||
*width = new_width;
|
||||
*height = new_height;
|
||||
impl->last_computed_width = new_width;
|
||||
impl->last_computed_height = new_height;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
compute_size_idle (gpointer user_data)
|
||||
{
|
||||
@ -394,6 +426,24 @@ gdk_x11_surface_compute_size (GdkSurface *surface)
|
||||
impl->surface_scale);
|
||||
}
|
||||
|
||||
impl->next_layout.surface_geometry_dirty = FALSE;
|
||||
impl->next_layout.configure_pending = FALSE;
|
||||
}
|
||||
else if (GDK_IS_DRAG_SURFACE (surface))
|
||||
{
|
||||
int width, height;
|
||||
|
||||
if (compute_drag_surface_size (surface, &width, &height))
|
||||
gdk_x11_surface_toplevel_resize (surface, width, height);
|
||||
|
||||
if (surface->resize_count == 0)
|
||||
{
|
||||
gdk_x11_surface_update_size (impl,
|
||||
impl->next_layout.configured_width,
|
||||
impl->next_layout.configured_height,
|
||||
impl->surface_scale);
|
||||
}
|
||||
|
||||
impl->next_layout.surface_geometry_dirty = FALSE;
|
||||
impl->next_layout.configure_pending = FALSE;
|
||||
}
|
||||
|
@ -183,6 +183,18 @@ surface_render (GdkSurface *surface,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
surface_compute_size (GdkDragSurface *surface,
|
||||
int *width,
|
||||
int *height,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
GtkRequisition size;
|
||||
gtk_widget_get_preferred_size (widget, NULL, &size);
|
||||
*width = size.width;
|
||||
*height = size.height;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_drag_icon_realize (GtkWidget *widget)
|
||||
{
|
||||
@ -193,6 +205,7 @@ gtk_drag_icon_realize (GtkWidget *widget)
|
||||
gdk_surface_set_widget (icon->surface, widget);
|
||||
|
||||
g_signal_connect (icon->surface, "render", G_CALLBACK (surface_render), widget);
|
||||
g_signal_connect (icon->surface, "compute-size", G_CALLBACK (surface_compute_size), widget);
|
||||
|
||||
GTK_WIDGET_CLASS (gtk_drag_icon_parent_class)->realize (widget);
|
||||
|
||||
@ -216,6 +229,7 @@ gtk_drag_icon_unrealize (GtkWidget *widget)
|
||||
if (icon->surface)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (icon->surface, surface_render, widget);
|
||||
g_signal_handlers_disconnect_by_func (icon->surface, surface_compute_size, widget);
|
||||
gdk_surface_set_widget (icon->surface, NULL);
|
||||
}
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ gtk_tests = [
|
||||
['testdialog'],
|
||||
['testdnd'],
|
||||
['testdnd2'],
|
||||
['testdndresize'],
|
||||
['testellipsise'],
|
||||
['testentrycompletion'],
|
||||
['testentryicons'],
|
||||
|
123
tests/testdndresize.c
Normal file
123
tests/testdndresize.c
Normal file
@ -0,0 +1,123 @@
|
||||
#include "gtkcssprovider.h"
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
static GtkRequisition size;
|
||||
static gint64 start_time;
|
||||
static gboolean stop_update_size;
|
||||
|
||||
static gboolean
|
||||
update_size (GtkWidget *widget, GdkFrameClock *clock, gpointer data)
|
||||
{
|
||||
GdkDrag *drag = data;
|
||||
gint64 now = g_get_monotonic_time ();
|
||||
float t;
|
||||
int width, height;
|
||||
|
||||
if (stop_update_size)
|
||||
return G_SOURCE_REMOVE;
|
||||
|
||||
t = fmodf ((now - start_time) / (float) G_TIME_SPAN_SECOND, 1);
|
||||
if (t >= 0.5)
|
||||
t = 1 - t;
|
||||
|
||||
width = size.width + t * 300;
|
||||
height = size.height + t * 150;
|
||||
|
||||
gtk_widget_set_size_request (widget, width, height);
|
||||
gdk_drag_set_hotspot (drag, width / 2, height / 2);
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static void
|
||||
drag_begin (GtkDragSource *source,
|
||||
GdkDrag *drag)
|
||||
{
|
||||
GtkWidget *widget;
|
||||
GtkWidget *icon;
|
||||
|
||||
icon = gtk_drag_icon_get_for_drag (drag);
|
||||
|
||||
widget = gtk_label_new ("This Should Resize\n\nAnd Stay Centered");
|
||||
gtk_widget_add_css_class (widget, "dnd");
|
||||
gtk_widget_get_preferred_size (widget, NULL, &size);
|
||||
|
||||
gtk_drag_icon_set_child (GTK_DRAG_ICON (icon), widget);
|
||||
gtk_widget_set_size_request (widget, size.width, size.height);
|
||||
gdk_drag_set_hotspot (drag, size.width / 2, size.height / 2);
|
||||
|
||||
start_time = g_get_monotonic_time ();
|
||||
stop_update_size = FALSE;
|
||||
gtk_widget_add_tick_callback (widget, update_size, drag, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
drag_end (GtkDragSource *source,
|
||||
GdkDrag *drag,
|
||||
gboolean delete_data,
|
||||
gboolean data)
|
||||
{
|
||||
stop_update_size = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
quit_cb (GtkWidget *widget,
|
||||
gpointer data)
|
||||
{
|
||||
gboolean *done = data;
|
||||
|
||||
*done = TRUE;
|
||||
|
||||
g_main_context_wakeup (NULL);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
GtkCssProvider *provider;
|
||||
GtkWidget *window;
|
||||
GtkWidget *label;
|
||||
GtkDragSource *source;
|
||||
GdkContentProvider *content;
|
||||
gboolean done = FALSE;
|
||||
|
||||
gtk_init ();
|
||||
|
||||
provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_data (provider,
|
||||
".dnd {"
|
||||
"background-color: red;"
|
||||
"border-top: 10px solid rebeccapurple;"
|
||||
"}",
|
||||
-1);
|
||||
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
|
||||
GTK_STYLE_PROVIDER(provider),
|
||||
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||
|
||||
window = gtk_window_new ();
|
||||
g_signal_connect (window, "destroy", G_CALLBACK (quit_cb), &done);
|
||||
|
||||
label = gtk_label_new ("Drag Me");
|
||||
g_object_set (label,
|
||||
"margin-start", 64,
|
||||
"margin-end", 64,
|
||||
"margin-top", 64,
|
||||
"margin-bottom", 64,
|
||||
NULL);
|
||||
|
||||
source = gtk_drag_source_new ();
|
||||
content = gdk_content_provider_new_typed (G_TYPE_STRING, "I'm data!");
|
||||
gtk_drag_source_set_content (source, content);
|
||||
g_signal_connect (source, "drag-begin", G_CALLBACK (drag_begin), NULL);
|
||||
g_signal_connect (source, "drag-end", G_CALLBACK (drag_end), NULL);
|
||||
gtk_widget_add_controller (label, GTK_EVENT_CONTROLLER (source));
|
||||
|
||||
gtk_window_set_child (GTK_WINDOW (window), label);
|
||||
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
|
||||
while (!done)
|
||||
g_main_context_iteration (NULL, TRUE);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user