114
113
button_widget_realize(GtkWidget *widget)
116
GtkAllocation allocation;
117
GdkWindowAttr attributes;
118
gint attributes_mask;
121
g_return_if_fail (widget != NULL);
122
g_return_if_fail (BUTTON_IS_WIDGET (widget));
124
button = GTK_BUTTON (widget);
126
gtk_widget_set_realized (widget, TRUE);
128
gtk_widget_get_allocation (widget, &allocation);
130
attributes.window_type = GDK_WINDOW_CHILD;
131
attributes.x = allocation.x;
132
attributes.y = allocation.y;
133
attributes.width = allocation.width;
134
attributes.height = allocation.height;
135
attributes.wclass = GDK_INPUT_ONLY;
136
attributes.event_mask = (GDK_BUTTON_PRESS_MASK |
137
GDK_BUTTON_RELEASE_MASK |
138
GDK_POINTER_MOTION_MASK |
139
GDK_POINTER_MOTION_HINT_MASK |
141
GDK_ENTER_NOTIFY_MASK |
142
GDK_LEAVE_NOTIFY_MASK);
143
attributes_mask = GDK_WA_X | GDK_WA_Y;
145
gtk_widget_set_window (widget, gtk_widget_get_parent_window (widget));
146
g_object_ref (gtk_widget_get_window (widget));
148
button->event_window = gdk_window_new (gtk_widget_get_parent_window (widget),
151
gdk_window_set_user_data (button->event_window, widget);
153
widget->style = gtk_style_attach (widget->style, gtk_widget_get_window (widget));
116
gtk_widget_add_events (widget, GDK_POINTER_MOTION_MASK |
117
GDK_POINTER_MOTION_HINT_MASK |
120
GTK_WIDGET_CLASS (button_widget_parent_class)->realize (widget);
155
122
BUTTON_WIDGET (widget)->priv->icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget));
156
123
g_signal_connect_object (BUTTON_WIDGET (widget)->priv->icon_theme,
158
125
G_CALLBACK (button_widget_icon_theme_changed),
160
127
G_CONNECT_SWAPPED);
162
129
button_widget_reload_pixbuf (BUTTON_WIDGET (widget));
368
button_widget_expose (GtkWidget *widget,
369
GdkEventExpose *event)
328
button_widget_draw (GtkWidget *widget,
371
ButtonWidget *button_widget;
374
GtkAllocation allocation;
375
GdkRectangle area, image_bound;
331
ButtonWidget *button_widget = BUTTON_WIDGET (widget);
332
GtkStyleContext *context;
333
GtkStateFlags state_flags;
334
gboolean hover_highlight;
379
338
GdkPixbuf *pb = NULL;
381
g_return_val_if_fail (BUTTON_IS_WIDGET (widget), FALSE);
382
g_return_val_if_fail (event != NULL, FALSE);
384
if (!gtk_widget_get_visible (widget) || !gtk_widget_get_mapped (widget))
387
button_widget = BUTTON_WIDGET (widget);
389
340
if (!button_widget->priv->pixbuf_hc && !button_widget->priv->pixbuf)
392
button = GTK_BUTTON (widget);
393
window = gtk_widget_get_window (widget);
394
gtk_widget_get_allocation (widget, &allocation);
343
width = gtk_widget_get_allocated_width (widget);
344
height = gtk_widget_get_allocated_height (widget);
396
346
/* offset for pressed buttons */
397
off = (button_widget->priv->activatable &&
398
button->in_button && button->button_down) ?
399
BUTTON_WIDGET_DISPLACEMENT * allocation.height / 48.0 : 0;
347
state_flags = gtk_widget_get_state_flags (widget);
348
gtk_widget_style_get (widget, "hover-highlight", &hover_highlight, NULL);
350
off = (button_widget->priv->activatable && (state_flags & GTK_STATE_FLAG_PRELIGHT) &&
351
(state_flags & GTK_STATE_FLAG_ACTIVE)) ?
352
BUTTON_WIDGET_DISPLACEMENT * height / 48.0 : 0;
354
/* FIXMEchpe replace this by cairo ops too! */
401
355
if (!button_widget->priv->activatable) {
402
356
pb = gdk_pixbuf_copy (button_widget->priv->pixbuf);
403
357
gdk_pixbuf_saturate_and_pixelate (button_widget->priv->pixbuf,
407
} else if (panel_global_config_get_highlight_when_over () &&
408
(button->in_button || gtk_widget_has_focus (widget)))
361
} else if (hover_highlight &&
362
(state_flags & GTK_STATE_FLAG_PRELIGHT || gtk_widget_has_focus (widget)))
409
363
pb = g_object_ref (button_widget->priv->pixbuf_hc);
411
365
pb = g_object_ref (button_widget->priv->pixbuf);
415
369
w = gdk_pixbuf_get_width (pb);
416
370
h = gdk_pixbuf_get_height (pb);
417
x = allocation.x + off + (allocation.width - w)/2;
418
y = allocation.y + off + (allocation.height - h)/2;
422
image_bound.width = w;
423
image_bound.height = h;
371
x = off + (width - w)/2;
372
y = off + (height - h)/2;
427
if (gdk_rectangle_intersect (&area, &allocation, &area) &&
428
gdk_rectangle_intersect (&image_bound, &area, &image_bound))
429
gdk_draw_pixbuf (window, NULL, pb,
430
image_bound.x - x, image_bound.y - y,
431
image_bound.x, image_bound.y,
432
image_bound.width, image_bound.height,
433
GDK_RGB_DITHER_NORMAL,
375
gdk_cairo_set_source_pixbuf (cr, pb, x, y);
436
379
g_object_unref (pb);
438
style = gtk_widget_get_style (widget);
381
context = gtk_widget_get_style_context (widget);
440
383
if (button_widget->priv->arrow) {
441
384
GtkArrowType arrow_type;
442
int x, y, width, height;
444
x = y = width = height = -1;
387
gtk_style_context_save (context);
388
gtk_style_context_set_state (context, state_flags);
446
390
arrow_type = calc_arrow (button_widget->priv->orientation,
454
gtk_paint_arrow (style,
396
gtk_render_arrow (context, cr, angle, x, y, size);
399
gtk_style_context_restore (context);
469
402
if (button_widget->priv->dnd_highlight) {
470
gdk_draw_rectangle(window, style->black_gc, FALSE,
471
allocation.x, allocation.y,
472
allocation.width - 1,
473
allocation.height - 1);
404
cairo_set_line_width (cr, 1);
405
cairo_set_source_rgb (cr, 0., 0., 0.);
406
cairo_rectangle (cr, 0.5, 0.5, width - 1, height - 1);
476
411
if (gtk_widget_has_focus (widget)) {
477
gint focus_width, focus_pad;
478
gint x, y, width, height;
414
gtk_style_context_save (context);
415
gtk_style_context_set_state (context, state_flags);
480
417
gtk_widget_style_get (widget,
481
"focus-line-width", &focus_width,
482
418
"focus-padding", &focus_pad,
484
x = allocation.x + focus_pad;
485
y = allocation.y + focus_pad;
486
width = allocation.width - 2 * focus_pad;
487
height = allocation.height - 2 * focus_pad;
488
gtk_paint_focus (style, window,
490
&event->area, widget, "button",
491
x, y, width, height);
422
w = width - 2 * focus_pad;
423
h = height - 2 * focus_pad;
426
gtk_render_focus (context, cr, x, y, w, h);
429
gtk_style_context_restore (context);
498
button_widget_size_request (GtkWidget *widget,
499
GtkRequisition *requisition)
501
ButtonWidget *button_widget = BUTTON_WIDGET (widget);
503
if (button_widget->priv->pixbuf) {
504
requisition->width = gdk_pixbuf_get_width (button_widget->priv->pixbuf);
505
requisition->height = gdk_pixbuf_get_height (button_widget->priv->pixbuf);
436
button_widget_get_preferred_width (GtkWidget *widget,
440
ButtonWidget *button_widget = BUTTON_WIDGET (widget);
444
parent = gtk_widget_get_parent (widget);
446
if (button_widget->priv->orientation & PANEL_HORIZONTAL_MASK)
447
size = gtk_widget_get_allocated_height (parent);
449
size = gtk_widget_get_allocated_width (parent);
451
*minimal_width = *natural_width = size;
455
button_widget_get_preferred_height (GtkWidget *widget,
456
gint *minimal_height,
457
gint *natural_height)
459
ButtonWidget *button_widget = BUTTON_WIDGET (widget);
463
parent = gtk_widget_get_parent (widget);
465
if (button_widget->priv->orientation & PANEL_HORIZONTAL_MASK)
466
size = gtk_widget_get_allocated_height (parent);
468
size = gtk_widget_get_allocated_width (parent);
470
*minimal_height = *natural_height = size;
510
475
button_widget_size_allocate (GtkWidget *widget,
511
476
GtkAllocation *allocation)
513
478
ButtonWidget *button_widget = BUTTON_WIDGET (widget);
514
GtkButton *button = GTK_BUTTON (widget);
481
GTK_WIDGET_CLASS (button_widget_parent_class)->size_allocate (widget, allocation);
517
483
if (button_widget->priv->orientation & PANEL_HORIZONTAL_MASK)
518
484
size = allocation->height;
578
534
button_widget_enter_notify (GtkWidget *widget, GdkEventCrossing *event)
536
GtkStateFlags state_flags;
580
537
gboolean in_button;
538
gboolean hover_highlight;
582
540
g_return_val_if_fail (BUTTON_IS_WIDGET (widget), FALSE);
584
in_button = GTK_BUTTON (widget)->in_button;
542
state_flags = gtk_widget_get_state_flags (widget);
543
in_button = state_flags & GTK_STATE_FLAG_PRELIGHT;
585
545
GTK_WIDGET_CLASS (button_widget_parent_class)->enter_notify_event (widget, event);
586
if (in_button != GTK_BUTTON (widget)->in_button &&
587
panel_global_config_get_highlight_when_over ())
547
state_flags = gtk_widget_get_state_flags (widget);
548
gtk_widget_style_get (widget, "hover-highlight", &hover_highlight, NULL);
550
if (in_button != (state_flags & GTK_STATE_FLAG_PRELIGHT) &&
588
552
gtk_widget_queue_draw (widget);
594
558
button_widget_leave_notify (GtkWidget *widget, GdkEventCrossing *event)
560
GtkStateFlags state_flags;
596
561
gboolean in_button;
562
gboolean hover_highlight;
598
564
g_return_val_if_fail (BUTTON_IS_WIDGET (widget), FALSE);
600
in_button = GTK_BUTTON (widget)->in_button;
566
state_flags = gtk_widget_get_state_flags (widget);
567
in_button = state_flags & GTK_STATE_FLAG_PRELIGHT;
601
569
GTK_WIDGET_CLASS (button_widget_parent_class)->leave_notify_event (widget, event);
602
if (in_button != GTK_BUTTON (widget)->in_button &&
603
panel_global_config_get_highlight_when_over ())
571
state_flags = gtk_widget_get_state_flags (widget);
572
gtk_widget_style_get (widget, "hover-highlight", &hover_highlight, NULL);
574
if (in_button != (state_flags & GTK_STATE_FLAG_PRELIGHT) &&
604
576
gtk_widget_queue_draw (widget);
641
613
g_type_class_add_private (klass, sizeof (ButtonWidgetPrivate));
643
widget_class->realize = button_widget_realize;
644
widget_class->unrealize = button_widget_unrealize;
645
widget_class->size_allocate = button_widget_size_allocate;
646
widget_class->size_request = button_widget_size_request;
647
widget_class->button_press_event = button_widget_button_press;
648
widget_class->enter_notify_event = button_widget_enter_notify;
649
widget_class->leave_notify_event = button_widget_leave_notify;
650
widget_class->expose_event = button_widget_expose;
615
widget_class->realize = button_widget_realize;
616
widget_class->unrealize = button_widget_unrealize;
617
widget_class->size_allocate = button_widget_size_allocate;
618
widget_class->get_preferred_width = button_widget_get_preferred_width;
619
widget_class->get_preferred_height = button_widget_get_preferred_height;
620
widget_class->button_press_event = button_widget_button_press;
621
widget_class->enter_notify_event = button_widget_enter_notify;
622
widget_class->leave_notify_event = button_widget_leave_notify;
623
widget_class->draw = button_widget_draw;
652
625
button_class->activate = button_widget_activate;