Logo Search packages:      
Sourcecode: kazehakase version File versions

gtk-utils.c

/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */

/*
 *  Copyright (C) 2003 Hiroyuki Ikezoe
 *  Copyright (C) 2003 Takuro Ashie <ashie@homa.ne.jp>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *
 *  This program 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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include "gtk-utils.h"
#include <string.h>
#include <glib/gi18n.h>

#define ICON_TRANS 192

/**
 * menu_position_under_widget:
 * this function from galeon-1.2.7
 */
void
gtkutil_menu_position_under_widget (GtkMenu *menu, gint *x, gint *y,
                            gboolean *push_in, gpointer user_data)
{
      GtkWidget *w = GTK_WIDGET(user_data);
      gint wheight;
      gint wx, wy;

      gdk_window_get_origin(w->window, x, y);
      wheight = w->requisition.height;
      wx = w->allocation.x;
      wy = w->allocation.y;
      
      *y = *y + wy + wheight;
      *x = *x + wx;
}


gboolean
gtkutil_confirm_file_replace (GtkWindow *parent, const gchar *filename)
{
      GtkWidget *dialog;
      gint res;

      dialog = gtk_message_dialog_new(parent,
                              GTK_DIALOG_DESTROY_WITH_PARENT,
                              GTK_MESSAGE_WARNING,
                              GTK_BUTTONS_NONE,
                              _("%s is already exist.\n\n Replace it?"),
                              filename);
      gtk_dialog_add_buttons(GTK_DIALOG(dialog),
                         _("Cancel"), GTK_RESPONSE_REJECT,
                         _("Replace"), GTK_RESPONSE_ACCEPT,
                         NULL);
      res = gtk_dialog_run(GTK_DIALOG(dialog));
      gtk_widget_destroy(dialog);
      
      return (res == GTK_RESPONSE_ACCEPT);
}

void
gtkutil_copy_text (const gchar *text)
{
      if (text && *text)
      {
            GtkClipboard *clipboard = gtk_clipboard_get(GDK_SELECTION_PRIMARY);
            gtk_clipboard_set_text(clipboard, text, strlen(text));
            clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
            gtk_clipboard_set_text(clipboard, text, strlen(text));
      }
}


static GHashTable *popup_menu_table;

static void
cb_popup_destroy (GtkWidget *widget)
{
      if (popup_menu_table)
            g_hash_table_remove(popup_menu_table, widget);
}


void
gtkutil_append_im_menuitem (GtkMenuShell *shell)
{
      static GtkIMMulticontext *im_context = NULL;
      GtkWidget *immenu, *menuitem;

      if (!im_context)
            im_context = GTK_IM_MULTICONTEXT(gtk_im_multicontext_new());

      if (!popup_menu_table)
            popup_menu_table = g_hash_table_new(g_direct_hash,
                                        g_direct_equal);

      menuitem = g_hash_table_lookup(popup_menu_table, shell);
      if (menuitem)
      {
            gtk_menu_item_remove_submenu(GTK_MENU_ITEM(menuitem));
      }
      else
      {
            /* separator */
            menuitem = gtk_separator_menu_item_new();
            gtk_menu_shell_append(shell, menuitem);
            gtk_widget_show(menuitem);

            /* input methods menuitem */
            menuitem = gtk_menu_item_new_with_label(_("Input Methods"));
            gtk_menu_shell_append(shell, menuitem);
            gtk_widget_show(menuitem);

            /* reference */
            g_hash_table_insert(popup_menu_table, shell, menuitem);
            g_signal_connect(shell, "destroy",
                         G_CALLBACK(cb_popup_destroy), NULL);
      }

      /* input methods submenu */
      immenu = gtk_menu_new();
      gtk_im_multicontext_append_menuitems
            (im_context, GTK_MENU_SHELL(immenu));
      gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), immenu);
}



void
gtkutil_superpose_pixbuf(GtkWidget *widget, GdkPixbuf *pixbuf, 
                   const gchar *stock_id, GtkIconSize size)
{
      gint width, height;
      GdkPixbuf *orig_pixbuf;

      orig_pixbuf = gtk_widget_render_icon(widget, stock_id, 
                                   size,
                                   NULL);
      gtk_icon_size_lookup(size, &width, &height);

      if (pixbuf)
      {
            gint x, y;
            GdkPixbuf *scaled_pixbuf, *transparent_pixbuf;
            
            x = width / 2;
            y = width / 2;
            scaled_pixbuf = gdk_pixbuf_scale_simple(orig_pixbuf,
                                          x, y,
                                          GDK_INTERP_NEAREST);
            transparent_pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
                                        TRUE,
                                        8,
                                        width,
                                        height);
            gdk_pixbuf_fill(transparent_pixbuf, 0);
            gdk_pixbuf_composite(pixbuf,
                             transparent_pixbuf,
                             0, 0,
                             width, height,
                             0, 0,
                             1, 1,
                             GDK_INTERP_NEAREST,
                             ICON_TRANS);
            gdk_pixbuf_composite(scaled_pixbuf,
                             transparent_pixbuf,
                             x, y,
                             x, y,
                             x, y,
                             1, 1,
                             GDK_INTERP_NEAREST,
                             255);
                             
            gtk_image_set_from_pixbuf(GTK_IMAGE(widget), transparent_pixbuf);
            g_object_unref(scaled_pixbuf);
            g_object_unref(transparent_pixbuf);
      }
      else 
            gtk_image_set_from_pixbuf(GTK_IMAGE(widget), orig_pixbuf);

      g_object_unref(orig_pixbuf);
}

#if (GTK_MAJOR_VERSION == 2) && (GTK_MINOR_VERSION < 5)

#define OFFSET(pb, x, y) ((x) * n_channels + (y) * rowstride)
#define DEST_OFFSET(pb, x, y) ((x) * dest_n_channels + (y) * dest_rowstride)

/* this function is taken from GTK+-2.5.x */
GdkPixbuf *
gdk_pixbuf_rotate_simple (const GdkPixbuf   *src,
                    GdkPixbufRotation  angle)
{
      GdkPixbuf *dest;
      guchar *p, *q;
      gint x, y;
      GdkColorspace colorspace;
      gboolean has_alpha;
      guchar *pixels, *dest_pixels;
      int height, width;
      int rowstride, dest_rowstride;
      int bits_per_sample;
      int n_channels, dest_n_channels;

      colorspace      = gdk_pixbuf_get_colorspace(src);
      has_alpha       = gdk_pixbuf_get_has_alpha(src);
      pixels          = gdk_pixbuf_get_pixels(src);
      height          = gdk_pixbuf_get_height(src);
      width           = gdk_pixbuf_get_width(src);
      rowstride       = gdk_pixbuf_get_rowstride(src);
      bits_per_sample = gdk_pixbuf_get_bits_per_sample(src);
      n_channels      = gdk_pixbuf_get_n_channels(src);

      switch (angle % 360)
      {
      case 0:
                  dest = gdk_pixbuf_copy (src);
                  break;
      case 90:
                  dest = gdk_pixbuf_new (colorspace, 
                               has_alpha, 
                               bits_per_sample, 
                               height,
                               width);
                  if (!dest)
                  return NULL;
                  dest_pixels = gdk_pixbuf_get_pixels(dest);
                  dest_n_channels = gdk_pixbuf_get_n_channels(dest);
                  dest_rowstride = gdk_pixbuf_get_rowstride(dest);
                  for (y = 0; y < height; y++) 
            { 
                  for (x = 0; x < width; x++) 
                  { 
                              p = pixels + OFFSET (src, x, y); 
                              q = dest_pixels + DEST_OFFSET (dest, y, width - x - 1); 
                              memcpy (q, p, dest_n_channels);
                  }
            } 
                  break;
      case 180:
            dest = gdk_pixbuf_new (colorspace, 
                               has_alpha, 
                               bits_per_sample, 
                               width, 
                               height);
                  if (!dest)
                  return NULL;

                  dest_pixels = gdk_pixbuf_get_pixels(dest);
                  dest_n_channels = gdk_pixbuf_get_n_channels(dest);
                  dest_rowstride = gdk_pixbuf_get_rowstride(dest);
                  for (y = 0; y < height; y++) 
            { 
                  for (x = 0; x < width; x++) 
                  { 
                              p = pixels + OFFSET (src, x, y); 
                              q = dest_pixels + DEST_OFFSET (dest, width - x - 1, height - y - 1); 
                              memcpy (q, p, n_channels);
                  }
            } 
                  break;
      case 270:
                  dest = gdk_pixbuf_new (colorspace, 
                               has_alpha, 
                               bits_per_sample, 
                               height, 
                               width);
                  if (!dest)
                  return NULL;
                  dest_pixels = gdk_pixbuf_get_pixels(dest);
                  dest_n_channels = gdk_pixbuf_get_n_channels(dest);
                  dest_rowstride = gdk_pixbuf_get_rowstride(dest);
                  for (y = 0; y < height; y++) 
            { 
                  for (x = 0; x < width; x++) 
                  { 
                              p = pixels + OFFSET (src, x, y); 
                              q = dest_pixels + DEST_OFFSET (dest, height - y - 1, x); 
                              memcpy (q, p, n_channels);
                  }
            } 
                  break;
      default:
                  dest = NULL;
                  g_warning ("gdk_pixbuf_rotate_simple() can only rotate "
                     "by multiples of 90 degrees");
                  g_assert_not_reached ();
      } 

      return dest;
}
#endif

Generated by  Doxygen 1.6.0   Back to index