35#define IS_VALID_ICON_ENTRY_POSITION(pos) \
36 ((pos) == SEXY_ICON_ENTRY_PRIMARY || \
37 (pos) == SEXY_ICON_ENTRY_SECONDARY)
72 GtkRequisition *requisition);
74 GtkAllocation *allocation);
77 GdkEventCrossing *event);
79 GdkEventCrossing *event);
81 GdkEventButton *event);
83 GdkEventButton *event);
90 G_IMPLEMENT_INTERFACE(GTK_TYPE_EDITABLE,
96 GObjectClass *gobject_class;
97 GtkObjectClass *object_class;
98 GtkWidgetClass *widget_class;
99 GtkEntryClass *entry_class;
103 gobject_class = G_OBJECT_CLASS(klass);
104 object_class = GTK_OBJECT_CLASS(klass);
105 widget_class = GTK_WIDGET_CLASS(klass);
106 entry_class = GTK_ENTRY_CLASS(klass);
136 g_signal_new(
"icon_pressed",
137 G_TYPE_FROM_CLASS(gobject_class),
138 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
159 g_signal_new(
"icon_released",
160 G_TYPE_FROM_CLASS(gobject_class),
161 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
186 g_return_if_fail(obj != NULL);
250 GtkRequisition requisition;
251 gint menu_icon_width;
255 if (icon_info->
icon == NULL)
258 gtk_widget_size_request(GTK_WIDGET(icon_info->
icon), &requisition);
259 gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &menu_icon_width, NULL);
261 width = MAX(requisition.width, menu_icon_width);
269 GtkWidget *widget = GTK_WIDGET(entry);
271 gboolean interior_focus;
273 gtk_widget_style_get(widget,
274 "interior-focus", &interior_focus,
275 "focus-line-width", &focus_width,
278 if (gtk_entry_get_has_frame(GTK_ENTRY(entry)))
280 *xborder = widget->style->xthickness;
281 *yborder = widget->style->ythickness;
291 *xborder += focus_width;
292 *yborder += focus_width;
299 GtkWidget *widget = GTK_WIDGET(entry);
300 GtkRequisition requisition;
301 gint xborder, yborder;
303 gtk_widget_get_child_requisition(widget, &requisition);
308 alloc->width = widget->allocation.width - xborder * 2;
309 alloc->height = requisition.height - yborder * 2;
315 GtkAllocation *widget_alloc,
316 GtkAllocation *text_area_alloc,
317 GtkAllocation *allocation,
322 rtl = (gtk_widget_get_direction(GTK_WIDGET(icon_entry)) ==
330 allocation->y = text_area_alloc->y;
332 allocation->height = text_area_alloc->height;
338 allocation->x = text_area_alloc->x + text_area_alloc->width -
347 GdkWindowAttr attributes;
348 gint attributes_mask;
355 attributes.width = 1;
356 attributes.height = 1;
357 attributes.window_type = GDK_WINDOW_CHILD;
358 attributes.wclass = GDK_INPUT_OUTPUT;
359 attributes.visual = gtk_widget_get_visual(widget);
360 attributes.colormap = gtk_widget_get_colormap(widget);
361 attributes.event_mask = gtk_widget_get_events(widget);
362 attributes.event_mask |=
364 | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK
365 | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK);
367 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
374 icon_info->
window = gdk_window_new(widget->window, &attributes,
376 gdk_window_set_user_data(icon_info->
window, widget);
378 gdk_window_set_background(icon_info->
window,
382 gtk_widget_queue_resize(widget);
397 gdk_window_destroy(icon_info->
window);
407 gint icon_widths = 0;
410 gtkentry = GTK_ENTRY(widget);
421 GTK_WIDGET_CLASS(
parent_class)->size_request(widget, requisition);
423 if (icon_widths > requisition->width)
424 requisition->width += icon_widths;
432 GtkAllocation left_icon_alloc;
433 GtkAllocation right_icon_alloc;
434 GtkAllocation text_area_alloc;
438 &left_icon_alloc, &left_icon_pos);
440 &right_icon_alloc, &right_icon_pos);
442 if (left_icon_alloc.width > 0)
444 text_area_alloc.x = left_icon_alloc.x + left_icon_alloc.width +
448 if (right_icon_alloc.width > 0)
449 text_area_alloc.width -= right_icon_alloc.width +
ICON_MARGIN;
451 text_area_alloc.width -= text_area_alloc.x;
454 left_icon_alloc.x, left_icon_alloc.y,
455 left_icon_alloc.width, left_icon_alloc.height);
458 right_icon_alloc.x, right_icon_alloc.y,
459 right_icon_alloc.width, right_icon_alloc.height);
461 gdk_window_move_resize(GTK_ENTRY(icon_entry)->
text_area,
462 text_area_alloc.x, text_area_alloc.y,
463 text_area_alloc.width, text_area_alloc.height);
470 g_return_if_fail(allocation != NULL);
472 widget->allocation = *allocation;
474 GTK_WIDGET_CLASS(
parent_class)->size_allocate(widget, allocation);
483 GdkPixbuf *pixbuf = NULL;
488 switch (gtk_image_get_storage_type(GTK_IMAGE(icon_info->
icon)))
490 case GTK_IMAGE_PIXBUF:
491 pixbuf = gtk_image_get_pixbuf(GTK_IMAGE(icon_info->
icon));
492 g_object_ref(pixbuf);
495 case GTK_IMAGE_STOCK:
496 gtk_image_get_stock(GTK_IMAGE(icon_info->
icon), &stock_id, &size);
497 pixbuf = gtk_widget_render_icon(GTK_WIDGET(entry),
498 stock_id, size, NULL);
513 gint
width,
height, has_alpha, src_rowstride, dest_rowstride;
514 guchar *target_pixels;
515 guchar *original_pixels;
521 has_alpha = gdk_pixbuf_get_has_alpha(src);
522 width = gdk_pixbuf_get_width(src);
523 height = gdk_pixbuf_get_height(src);
524 src_rowstride = gdk_pixbuf_get_rowstride(src);
525 dest_rowstride = gdk_pixbuf_get_rowstride(dest);
526 original_pixels = gdk_pixbuf_get_pixels(src);
527 target_pixels = gdk_pixbuf_get_pixels(dest);
529 for (i = 0; i <
height; i++)
531 pix_dest = target_pixels + i * dest_rowstride;
532 pix_src = original_pixels + i * src_rowstride;
534 for (j = 0; j <
width; j++)
541 *(pix_dest++) = CLAMP(val, 0, 255);
544 *(pix_dest++) = CLAMP(val, 0, 255);
547 *(pix_dest++) = CLAMP(val, 0, 255);
550 *(pix_dest++) = *(pix_src++);
579 if (gdk_pixbuf_get_height(pixbuf) >
height)
581 GdkPixbuf *temp_pixbuf;
586 temp_pixbuf = gdk_pixbuf_scale_simple(pixbuf, scale, scale,
587 GDK_INTERP_BILINEAR);
589 g_object_unref(pixbuf);
591 pixbuf = temp_pixbuf;
594 x = (
width - gdk_pixbuf_get_width(pixbuf)) / 2;
595 y = (
height - gdk_pixbuf_get_height(pixbuf)) / 2;
599 GdkPixbuf *temp_pixbuf;
601 temp_pixbuf = gdk_pixbuf_copy(pixbuf);
605 g_object_unref(pixbuf);
607 pixbuf = temp_pixbuf;
610 gdk_draw_pixbuf(icon_info->
window, widget->style->black_gc, pixbuf,
612 GDK_RGB_DITHER_NORMAL, 0, 0);
614 g_object_unref(pixbuf);
623 g_return_val_if_fail(event != NULL, FALSE);
629 gboolean found = FALSE;
632 for (i = 0; i <
MAX_ICONS && !found; i++)
636 if (event->window == icon_info->
window)
639 GtkAllocation text_area_alloc;
642 gdk_drawable_get_size(icon_info->
window, &
width, NULL);
644 gtk_paint_flat_box(widget->style, icon_info->
window,
646 NULL, widget,
"entry_bg",
647 0, 0,
width, text_area_alloc.height);
656 GTK_WIDGET_CLASS(
parent_class)->expose_event(widget, event);
667 const char *name = g_param_spec_get_name(param);
669 if (strcmp(name,
"pixbuf") && strcmp(name,
"stock") &&
670 strcmp(name,
"image") && strcmp(name,
"pixmap") &&
671 strcmp(name,
"icon_set") && strcmp(name,
"pixbuf_animation"))
677 gtk_widget_queue_resize(GTK_WIDGET(entry));
738 if (event->button == 1 &&
753 return GTK_WIDGET_CLASS(
parent_class)->button_press_event(widget,
769 if (event->window == icon_window)
772 gdk_drawable_get_size(icon_window, &
width, &
height);
774 if (event->button == 1 &&
776 event->x >= 0 && event->y >= 0 &&
790 if (GTK_WIDGET_CLASS(
parent_class)->button_release_event)
791 return GTK_WIDGET_CLASS(
parent_class)->button_release_event(widget,
824 g_return_if_fail(entry != NULL);
827 g_return_if_fail(icon == NULL || GTK_IS_IMAGE(icon));
829 icon_info = &entry->
priv->
icons[icon_pos];
831 if (icon == icon_info->
icon)
843 if (icon_info->
icon != NULL)
845 gtk_widget_destroy(GTK_WIDGET(icon_info->
icon));
846 icon_info->
icon = NULL;
852 if (icon_info->
window != NULL && GDK_IS_WINDOW(icon_info->
window))
853 gdk_window_hide(icon_info->
window);
858 if (icon_info->
window != NULL && icon_info->
icon == NULL)
859 gdk_window_show(icon_info->
window);
861 g_signal_connect(G_OBJECT(icon),
"notify",
864 icon_info->
icon = icon;
886 g_return_if_fail(entry != NULL);
890 icon_info = &entry->
priv->
icons[icon_pos];
911 g_return_val_if_fail(entry != NULL, NULL);
931 g_return_val_if_fail(entry != NULL, FALSE);
946 gtk_entry_set_text(GTK_ENTRY(icon_entry),
"");
961 g_return_if_fail(icon_entry != NULL);
966 gtk_widget_show(icon);
975 g_signal_handler_disconnect(icon_entry,
980 g_signal_connect(G_OBJECT(icon_entry),
"icon_released",
gboolean nsgtk_widget_is_drawable(GtkWidget *widget)
GtkWidget * nsgtk_image_new_from_stock(const gchar *id, GtkIconSize size)
Creates a GtkImage displaying a stock icon.
gboolean nsgtk_widget_get_mapped(GtkWidget *widget)
gboolean nsgtk_widget_get_realized(GtkWidget *widget)
Compatibility functions for older GTK versions (interface)
#define NSGTK_STOCK_CLEAR
GtkStateType nsgtk_widget_get_state(GtkWidget *widget)
static void sexy_icon_entry_size_request(GtkWidget *widget, GtkRequisition *requisition)
static gint sexy_icon_entry_expose(GtkWidget *widget, GdkEventExpose *event)
static void get_icon_allocation(SexyIconEntry *icon_entry, gboolean left, GtkAllocation *widget_alloc, GtkAllocation *text_area_alloc, GtkAllocation *allocation, SexyIconEntryPosition *icon_pos)
static guint signals[LAST_SIGNAL]
static gint sexy_icon_entry_leave_notify(GtkWidget *widget, GdkEventCrossing *event)
static void clear_button_clicked_cb(SexyIconEntry *icon_entry, SexyIconEntryPosition icon_pos, int button)
static void get_borders(SexyIconEntry *entry, gint *xborder, gint *yborder)
void sexy_icon_entry_class_init(SexyIconEntryClass *klass)
static void sexy_icon_entry_realize(GtkWidget *widget)
static void update_icon(GObject *obj, GParamSpec *param, SexyIconEntry *entry)
static GdkPixbuf * get_pixbuf_from_icon(SexyIconEntry *entry, SexyIconEntryPosition icon_pos)
static void sexy_icon_entry_unmap(GtkWidget *widget)
G_DEFINE_TYPE_EXTENDED(SexyIconEntry, sexy_icon_entry, GTK_TYPE_ENTRY, 0, G_IMPLEMENT_INTERFACE(GTK_TYPE_EDITABLE, sexy_icon_entry_editable_init))
static gint sexy_icon_entry_enter_notify(GtkWidget *widget, GdkEventCrossing *event)
GtkWidget * sexy_icon_entry_new(void)
static void place_windows(SexyIconEntry *icon_entry, GtkAllocation *widget_alloc)
static gint sexy_icon_entry_button_press(GtkWidget *widget, GdkEventButton *event)
void sexy_icon_entry_init(SexyIconEntry *entry)
static void sexy_icon_entry_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
#define IS_VALID_ICON_ENTRY_POSITION(pos)
gboolean sexy_icon_entry_get_icon_highlight(const SexyIconEntry *entry, SexyIconEntryPosition icon_pos)
static GtkEntryClass * parent_class
void sexy_icon_entry_set_icon(SexyIconEntry *entry, SexyIconEntryPosition icon_pos, GtkImage *icon)
static void sexy_icon_entry_map(GtkWidget *widget)
static gint sexy_icon_entry_button_release(GtkWidget *widget, GdkEventButton *event)
void sexy_icon_entry_add_clear_button(SexyIconEntry *icon_entry)
static void sexy_icon_entry_finalize(GObject *obj)
static void get_text_area_size(SexyIconEntry *entry, GtkAllocation *alloc)
static void sexy_icon_entry_destroy(GtkObject *obj)
static gint get_icon_width(SexyIconEntry *entry, SexyIconEntryPosition icon_pos)
static void draw_icon(GtkWidget *widget, SexyIconEntryPosition icon_pos)
static void colorshift_pixbuf(GdkPixbuf *dest, GdkPixbuf *src, int shift)
static void sexy_icon_entry_editable_init(GtkEditableClass *iface)
static void sexy_icon_entry_unrealize(GtkWidget *widget)
void sexy_icon_entry_set_icon_highlight(SexyIconEntry *entry, SexyIconEntryPosition icon_pos, gboolean highlight)
GtkImage * sexy_icon_entry_get_icon(const SexyIconEntry *entry, SexyIconEntryPosition icon_pos)
#define SEXY_IS_ICON_ENTRY(obj)
@ SEXY_ICON_ENTRY_SECONDARY
@ SEXY_ICON_ENTRY_PRIMARY
#define SEXY_ICON_ENTRY(obj)
#define SEXY_TYPE_ICON_ENTRY
Interface to utility string handling.
SexyIconInfo icons[MAX_ICONS]