gtk2/tests/testwidgetfocus.c
Alexander Larsson 63e060a21d GtkWidget: Start renaming widget->window
This is an automated change doing these command:

git sed -f g gtk_widget_set_has_window gtk_widget_set_has_surface
git sed -f g gtk_widget_get_has_window gtk_widget_get_has_surface
git sed -f g gtk_widget_set_parent_window gtk_widget_set_parent_surface
git sed -f g gtk_widget_get_parent_window gtk_widget_get_parent_surface
git sed -f g gtk_widget_set_window gtk_widget_set_surface
git sed -f g gtk_widget_get_window gtk_widget_get_surface
git sed -f g gtk_widget_register_window gtk_widget_register_surface
git sed -f g gtk_widget_unregister_window gtk_widget_unregister_surface

git checkout NEWS*
2018-03-20 15:21:12 +01:00

299 lines
8.3 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <gtk/gtk.h>
typedef struct _GtkFocusWidget GtkFocusWidget;
typedef struct _GtkFocusWidgetClass GtkFocusWidgetClass;
#define GTK_TYPE_FOCUS_WIDGET (gtk_focus_widget_get_type ())
#define GTK_FOCUS_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST(obj, GTK_TYPE_FOCUS_WIDGET, GtkFocusWidget))
#define GTK_FOCUS_WIDGET_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST(cls, GTK_TYPE_FOCUS_WIDGET, GtkFocusWidgetClass))
#define GTK_IS_FOCUS_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE(obj, GTK_TYPE_FOCUS_WIDGET))
#define GTK_IS_FOCUS_WIDGET_CLASS(cls) (G_TYPE_CHECK_CLASS_TYPE(cls, GTK_TYPE_FOCUS_WIDGET))
#define GTK_FOCUS_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS(obj, GTK_TYPE_FOCUS_WIDGET, GtkFocusWidgetClass))
const char *css =
"* {"
" transition: none; "
"}"
"focuswidget {"
" padding: 30px;"
" font-size: 70%;"
"}"
"focuswidget button:nth-child(1) {"
" margin-right: 15px;"
" margin-bottom: 15px;"
"}"
"focuswidget button:nth-child(2) {"
" margin-left: 15px;"
" margin-bottom: 15px;"
"}"
"focuswidget button:nth-child(3) {"
" margin-right: 15px;"
" margin-top: 15px;"
"}"
"focuswidget button:nth-child(4) {"
" margin-left: 15px;"
" margin-top: 15px;"
"}"
"focuswidget button {"
" min-width: 80px;"
" min-height: 80px;"
" margin: 0px;"
" border: 5px solid green;"
" border-radius: 0px;"
" padding: 10px;"
" background-image: none;"
" background-color: white;"
" box-shadow: none;"
"}"
"focuswidget button:focus(visible) {"
" outline-width: 4px;"
" outline-color: yellow;"
"}"
"focuswidget button:hover {"
" background-color: black;"
" color: white;"
"}"
"focuswidget button label:hover {"
" background-color: green;"
"}"
;
struct _GtkFocusWidget
{
GtkWidget parent_instance;
double mouse_x;
double mouse_y;
union {
struct {
GtkWidget *child1;
GtkWidget *child2;
GtkWidget *child3;
GtkWidget *child4;
};
GtkWidget* children[4];
};
};
struct _GtkFocusWidgetClass
{
GtkWidgetClass parent_class;
};
GType gtk_focus_widget_get_type (void) G_GNUC_CONST;
G_DEFINE_TYPE(GtkFocusWidget, gtk_focus_widget, GTK_TYPE_WIDGET)
static void
gtk_focus_widget_size_allocate (GtkWidget *widget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip)
{
GtkFocusWidget *self = GTK_FOCUS_WIDGET (widget);
int child_width = (allocation->width) / 2;
int child_height = (allocation->height) / 2;
GtkAllocation child_alloc;
child_alloc.x = 0;
child_alloc.y = 0;
child_alloc.width = child_width;
child_alloc.height = child_height;
gtk_widget_size_allocate (self->child1, &child_alloc, -1, out_clip);
child_alloc.x += child_width;
gtk_widget_size_allocate (self->child2, &child_alloc, -1, out_clip);
child_alloc.y += child_height;
gtk_widget_size_allocate (self->child4, &child_alloc, -1, out_clip);
child_alloc.x -= child_width;
gtk_widget_size_allocate (self->child3, &child_alloc, -1, out_clip);
}
static void
gtk_focus_widget_measure (GtkWidget *widget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline)
{
GtkFocusWidget *self = GTK_FOCUS_WIDGET (widget);
int min, nat;
int i;
*minimum = 0;
*natural = 0;
for (i = 0; i < 4; i ++)
{
gtk_widget_measure (self->children[i], orientation, for_size,
&min, &nat, NULL, NULL);
*minimum = MAX (*minimum, min);
*natural = MAX (*natural, nat);
}
*minimum *= 2;
*natural *= 2;
}
static void
gtk_focus_widget_snapshot (GtkWidget *widget, GtkSnapshot *snapshot)
{
GtkFocusWidget *self = GTK_FOCUS_WIDGET (widget);
gtk_widget_snapshot_child (widget, self->child1, snapshot);
gtk_widget_snapshot_child (widget, self->child2, snapshot);
gtk_widget_snapshot_child (widget, self->child3, snapshot);
gtk_widget_snapshot_child (widget, self->child4, snapshot);
if (self->mouse_x != G_MININT && self->mouse_y != G_MININT)
{
PangoLayout *layout;
char *text;
GtkAllocation alloc;
graphene_rect_t bounds;
GdkRGBA black = {0, 0, 0, 1};
gtk_widget_get_allocation (widget, &alloc);
/* Since event coordinates and drawing is supposed to happen in the
* same coodinates space, this should all work out just fine. */
bounds.origin.x = self->mouse_x;
bounds.origin.y = -30;
bounds.size.width = 1;
bounds.size.height = alloc.height;
gtk_snapshot_append_color (snapshot,
&black,
&bounds,
"Crosshair 1");
bounds.origin.x = -30;
bounds.origin.y = self->mouse_y;
bounds.size.width = alloc.width;
bounds.size.height = 1;
gtk_snapshot_append_color (snapshot,
&black,
&bounds,
"Crosshair 2");
layout = gtk_widget_create_pango_layout (widget, NULL);
text = g_strdup_printf ("%.2f×%.2f", self->mouse_x, self->mouse_y);
pango_layout_set_text (layout, text, -1);
gtk_snapshot_render_layout (snapshot,
gtk_widget_get_style_context (widget),
self->mouse_x + 2,
self->mouse_y - 15, /* *shrug* */
layout);
g_free (text);
g_object_unref (layout);
}
}
static gboolean
gtk_focus_widget_event (GtkWidget *widget,
GdkEvent *event)
{
GtkFocusWidget *self = GTK_FOCUS_WIDGET (widget);
double x, y;
if (gdk_event_get_event_type (event) == GDK_MOTION_NOTIFY)
{
gdk_event_get_coords ((GdkEvent *)event, &x, &y);
self->mouse_x = x;
self->mouse_y = y;
gtk_widget_queue_draw (widget);
}
return GDK_EVENT_PROPAGATE;
}
static void
gtk_focus_widget_finalize (GObject *object)
{
GtkFocusWidget *self = GTK_FOCUS_WIDGET (object);
gtk_widget_unparent (self->child1);
gtk_widget_unparent (self->child2);
gtk_widget_unparent (self->child3);
gtk_widget_unparent (self->child4);
G_OBJECT_CLASS (gtk_focus_widget_parent_class)->finalize (object);
}
static void
gtk_focus_widget_init (GtkFocusWidget *self)
{
gtk_widget_set_has_surface (GTK_WIDGET (self), FALSE);
self->child1 = gtk_button_new_with_label ("1");
gtk_widget_set_parent (self->child1, GTK_WIDGET (self));
self->child2 = gtk_button_new_with_label ("2");
gtk_widget_set_parent (self->child2, GTK_WIDGET (self));
self->child3 = gtk_button_new_with_label ("3");
gtk_widget_set_parent (self->child3, GTK_WIDGET (self));
self->child4 = gtk_button_new_with_label ("4");
gtk_widget_set_parent (self->child4, GTK_WIDGET (self));
self->mouse_x = G_MININT;
self->mouse_y = G_MININT;
}
static void
gtk_focus_widget_class_init (GtkFocusWidgetClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
object_class->finalize = gtk_focus_widget_finalize;
widget_class->snapshot = gtk_focus_widget_snapshot;
widget_class->measure = gtk_focus_widget_measure;
widget_class->size_allocate = gtk_focus_widget_size_allocate;
widget_class->event = gtk_focus_widget_event;
gtk_widget_class_set_css_name (widget_class, "focuswidget");
}
int
main()
{
GtkWidget *window;
GtkWidget *widget;
GtkCssProvider *provider;
gtk_init ();
provider = gtk_css_provider_new ();
gtk_css_provider_load_from_data (provider, css, -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 (GTK_WINDOW_TOPLEVEL);
widget = g_object_new (GTK_TYPE_FOCUS_WIDGET, NULL);
gtk_window_set_decorated (GTK_WINDOW (window), FALSE);
gtk_container_add (GTK_CONTAINER (window), widget);
g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
gtk_widget_show (window);
gtk_main ();
}