home *** CD-ROM | disk | FTP | other *** search
/ Chip 2005 February / CMCD0205.ISO / Linux / gimp-2.2.0.tar.gz / gimp-2.2.0.tar / gimp-2.2.0 / libgimpwidgets / gimpmemsizeentry.c < prev    next >
C/C++ Source or Header  |  2004-10-31  |  8KB  |  307 lines

  1. /* LIBGIMP - The GIMP Library
  2.  * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
  3.  *
  4.  * gimpmemsizeentry.c
  5.  * Copyright (C) 2000-2003  Sven Neumann <sven@gimp.org>
  6.  *
  7.  * This library is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Lesser General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2 of the License, or (at your option) any later version.
  11.  *
  12.  * This library is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * Library General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU Lesser General Public
  18.  * License along with this library; if not, write to the
  19.  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  20.  * Boston, MA 02111-1307, USA.
  21.  */
  22.  
  23. #include "config.h"
  24.  
  25. #include <gtk/gtk.h>
  26.  
  27. #include "gimpwidgetstypes.h"
  28.  
  29. #include "gimpmemsizeentry.h"
  30. #include "gimpwidgets.h"
  31.  
  32. #include "libgimp/libgimp-intl.h"
  33.  
  34.  
  35. enum
  36. {
  37.   VALUE_CHANGED,
  38.   LAST_SIGNAL
  39. };
  40.  
  41. static void  gimp_memsize_entry_class_init    (GimpMemsizeEntryClass *klass);
  42. static void  gimp_memsize_entry_init          (GimpMemsizeEntry      *entry);
  43. static void  gimp_memsize_entry_finalize      (GObject               *object);
  44.  
  45. static void  gimp_memsize_entry_adj_callback  (GtkAdjustment         *adj,
  46.                            GimpMemsizeEntry      *entry);
  47. static void  gimp_memsize_entry_unit_callback (GtkWidget             *widget,
  48.                            GimpMemsizeEntry      *entry);
  49.  
  50.  
  51. static guint         gimp_memsize_entry_signals[LAST_SIGNAL] = { 0 };
  52. static GtkHBoxClass *parent_class                            = NULL;
  53.  
  54.  
  55. GType
  56. gimp_memsize_entry_get_type (void)
  57. {
  58.   static GType entry_type = 0;
  59.  
  60.   if (! entry_type)
  61.     {
  62.       static const GTypeInfo entry_info =
  63.       {
  64.         sizeof (GimpMemsizeEntryClass),
  65.         (GBaseInitFunc) NULL,
  66.         (GBaseFinalizeFunc) NULL,
  67.         (GClassInitFunc) gimp_memsize_entry_class_init,
  68.         NULL,           /* class_finalize */
  69.         NULL,           /* class_data     */
  70.         sizeof (GimpMemsizeEntry),
  71.         0,              /* n_preallocs    */
  72.         (GInstanceInitFunc) gimp_memsize_entry_init,
  73.       };
  74.  
  75.       entry_type = g_type_register_static (GTK_TYPE_HBOX, "GimpMemsizeEntry",
  76.                        &entry_info, 0);
  77.     }
  78.  
  79.   return entry_type;
  80. }
  81.  
  82. static void
  83. gimp_memsize_entry_class_init (GimpMemsizeEntryClass *klass)
  84. {
  85.   GObjectClass *object_class;
  86.  
  87.   parent_class = g_type_class_peek_parent (klass);
  88.  
  89.   object_class = G_OBJECT_CLASS (klass);
  90.  
  91.   object_class->finalize = gimp_memsize_entry_finalize;
  92.  
  93.   gimp_memsize_entry_signals[VALUE_CHANGED] =
  94.     g_signal_new ("value_changed",
  95.           G_TYPE_FROM_CLASS (klass),
  96.           G_SIGNAL_RUN_FIRST,
  97.           G_STRUCT_OFFSET (GimpMemsizeEntryClass, value_changed),
  98.           NULL, NULL,
  99.           g_cclosure_marshal_VOID__VOID,
  100.           G_TYPE_NONE, 0);
  101.  
  102.   klass->value_changed = NULL;
  103. }
  104.  
  105. static void
  106. gimp_memsize_entry_init (GimpMemsizeEntry *entry)
  107. {
  108.   gtk_box_set_spacing (GTK_BOX (entry), 4);
  109.  
  110.   entry->value      = 0;
  111.   entry->lower      = 0;
  112.   entry->upper      = 0;
  113.   entry->shift      = 0;
  114.   entry->adjustment = NULL;
  115.   entry->menu       = NULL;
  116. }
  117.  
  118. static void
  119. gimp_memsize_entry_finalize (GObject *object)
  120. {
  121.   GimpMemsizeEntry *entry = (GimpMemsizeEntry *) object;
  122.  
  123.   if (entry->adjustment)
  124.     {
  125.       g_object_unref (entry->adjustment);
  126.       entry->adjustment = NULL;
  127.     }
  128.  
  129.   G_OBJECT_CLASS (parent_class)->finalize (object);
  130. }
  131.  
  132. static void
  133. gimp_memsize_entry_adj_callback (GtkAdjustment    *adj,
  134.                  GimpMemsizeEntry *entry)
  135. {
  136.   guint64 size = gtk_adjustment_get_value (adj);
  137.  
  138.   entry->value = size << entry->shift;
  139.  
  140.   g_signal_emit (entry, gimp_memsize_entry_signals[VALUE_CHANGED], 0);
  141. }
  142.  
  143. static void
  144. gimp_memsize_entry_unit_callback (GtkWidget        *widget,
  145.                   GimpMemsizeEntry *entry)
  146. {
  147.   guint  shift;
  148.  
  149.   gimp_int_combo_box_get_active (GIMP_INT_COMBO_BOX (widget), (gint *) &shift);
  150.  
  151. #if _MSC_VER < 1300
  152. #  define CAST (gint64)
  153. #else
  154. #  define CAST
  155. #endif
  156.  
  157.   if (shift != entry->shift)
  158.     {
  159.       entry->shift = shift;
  160.  
  161.       entry->adjustment->value = CAST entry->value >> shift;
  162.       entry->adjustment->lower = CAST entry->lower >> shift;
  163.       entry->adjustment->upper = CAST entry->upper >> shift;
  164.  
  165.       gtk_adjustment_value_changed (entry->adjustment);
  166.       gtk_adjustment_changed (entry->adjustment);
  167.     }
  168. #undef CAST
  169. }
  170.  
  171.  
  172. /**
  173.  * gimp_memsize_entry_new:
  174.  * @value: the initial value (in Bytes)
  175.  * @lower: the lower limit for the value (in Bytes)
  176.  * @upper: the upper limit for the value (in Bytes)
  177.  *
  178.  * Creates a new #GimpMemsizeEntry which is a #GtkHBox with a #GtkSpinButton
  179.  * and a #GtkOptionMenu all setup to allow the user to enter memory sizes.
  180.  *
  181.  * Returns: Pointer to the new #GimpMemsizeEntry.
  182.  **/
  183. GtkWidget *
  184. gimp_memsize_entry_new (guint64  value,
  185.             guint64  lower,
  186.             guint64  upper)
  187. {
  188.   GimpMemsizeEntry *entry;
  189.   guint             shift;
  190.  
  191. #if _MSC_VER < 1300
  192. #  define CAST (gint64)
  193. #else
  194. #  define CAST
  195. #endif
  196.  
  197.   g_return_val_if_fail (value >= lower && value <= upper, NULL);
  198.  
  199.   entry = g_object_new (GIMP_TYPE_MEMSIZE_ENTRY, NULL);
  200.  
  201.   for (shift = 30; shift > 10; shift -= 10)
  202.     {
  203.       if (value > ((guint64) 1 << shift) &&
  204.           value % ((guint64) 1 << shift) == 0)
  205.         break;
  206.     }
  207.  
  208.   entry->value = value;
  209.   entry->lower = lower;
  210.   entry->upper = upper;
  211.   entry->shift = shift;
  212.  
  213.   entry->spinbutton = gimp_spin_button_new ((GtkObject **) &entry->adjustment,
  214.                                             CAST (value >> shift),
  215.                                             CAST (lower >> shift),
  216.                                             CAST (upper >> shift),
  217.                                             1, 8, 0, 1, 0);
  218.  
  219. #undef CAST
  220.  
  221.   g_object_ref (entry->adjustment);
  222.   gtk_object_sink (GTK_OBJECT (entry->adjustment));
  223.  
  224.   gtk_entry_set_width_chars (GTK_ENTRY (entry->spinbutton), 10);
  225.   gtk_box_pack_start (GTK_BOX (entry), entry->spinbutton, FALSE, FALSE, 0);
  226.   gtk_widget_show (entry->spinbutton);
  227.  
  228.   g_signal_connect (entry->adjustment, "value_changed",
  229.                     G_CALLBACK (gimp_memsize_entry_adj_callback),
  230.                     entry);
  231.  
  232.   entry->menu = gimp_int_combo_box_new (_("Kilobytes"), 10,
  233.                                         _("Megabytes"), 20,
  234.                                         _("Gigabytes"), 30,
  235.                                         NULL);
  236.  
  237.   gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (entry->menu), shift);
  238.  
  239.   g_signal_connect (entry->menu, "changed",
  240.                     G_CALLBACK (gimp_memsize_entry_unit_callback),
  241.                     entry);
  242.  
  243.   gtk_box_pack_start (GTK_BOX (entry), entry->menu, FALSE, FALSE, 0);
  244.   gtk_widget_show (entry->menu);
  245.  
  246.   return GTK_WIDGET (entry);
  247. }
  248.  
  249. /**
  250.  * gimp_memsize_entry_set_value:
  251.  * @entry: a #GimpMemsizeEntry
  252.  * @value: the new value (in Bytes)
  253.  *
  254.  * Sets the @entry's value. Please note that the #GimpMemsizeEntry rounds
  255.  * the value to full Kilobytes.
  256.  **/
  257. void
  258. gimp_memsize_entry_set_value (GimpMemsizeEntry *entry,
  259.                   guint64           value)
  260. {
  261.   guint shift;
  262.  
  263.   g_return_if_fail (GIMP_IS_MEMSIZE_ENTRY (entry));
  264.   g_return_if_fail (value >= entry->lower && value <= entry->upper);
  265.  
  266.   for (shift = 30; shift > 10; shift -= 10)
  267.     {
  268.       if (value > ((guint64) 1 << shift) &&
  269.           value % ((guint64) 1 << shift) == 0)
  270.         break;
  271.     }
  272.  
  273.   if (shift != entry->shift)
  274.     {
  275.       entry->shift = shift;
  276.       entry->value = value;
  277.  
  278.       gimp_int_combo_box_set_active (GIMP_INT_COMBO_BOX (entry->menu), shift);
  279.     }
  280.  
  281. #if _MSC_VER < 1300
  282. #  define CAST (gint64)
  283. #else
  284. #  define CAST
  285. #endif
  286.  
  287.   gtk_adjustment_set_value (entry->adjustment, CAST (value >> shift));
  288.  
  289. #undef CASE
  290. }
  291.  
  292. /**
  293.  * gimp_memsize_entry_get_value:
  294.  * @entry: a #GimpMemsizeEntry
  295.  *
  296.  * Retrieves the current value from a #GimpMemsizeEntry.
  297.  *
  298.  * Returns: the current value of @entry (in Bytes).
  299.  **/
  300. guint64
  301. gimp_memsize_entry_get_value (GimpMemsizeEntry *entry)
  302. {
  303.   g_return_val_if_fail (GIMP_IS_MEMSIZE_ENTRY (entry), 0);
  304.  
  305.   return entry->value;
  306. }
  307.