home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2002 April / pcpro0402.iso / essentials / graphics / Gimp / gimp-src-20001226.exe / src / gimp / unofficial-plug-ins / mathmap / userval.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-04-21  |  9.4 KB  |  427 lines

  1. /*
  2.  * userval.c
  3.  *
  4.  * MathMap
  5.  *
  6.  * Copyright (C) 1997-2000 Mark Probst
  7.  *
  8.  * This program is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU General Public License
  10.  * as published by the Free Software Foundation; either version 2
  11.  * of the License, or (at your option) any later version.
  12.  *
  13.  * This program is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  * GNU General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU General Public License
  19.  * along with this program; if not, write to the Free Software
  20.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <assert.h>
  26. #include <math.h>
  27.  
  28. #include <gtk/gtk.h>
  29. #include <libgimp/gimp.h>
  30. #include <libgimp/gimpui.h>
  31.  
  32. #include "mathmap.h"
  33. #include "userval.h"
  34. #include "tags.h"
  35. #include "colorwell.h"
  36.  
  37. static userval_t *first = 0;
  38.  
  39. static userval_t*
  40. alloc_and_register_userval (const char *name, int type)
  41. {
  42.     userval_t *userval = (userval_t*)malloc(sizeof(userval_t));
  43.     userval_t **p;
  44.  
  45.     strncpy(userval->name, name, MAX_IDENT_LENGTH);
  46.     userval->name[MAX_IDENT_LENGTH] = '\0';
  47.  
  48.     userval->type = type;
  49.  
  50.     userval->tag = 1;
  51.  
  52.     userval->next = 0;
  53.  
  54.     p = &first;
  55.     while (*p != 0)
  56.     p = &(*p)->next;
  57.     *p = userval;
  58.  
  59.     return userval;
  60. }
  61.  
  62. void
  63. untag_uservals (void)
  64. {
  65.     userval_t *userval;
  66.  
  67.     for (userval = first; userval != 0; userval = userval->next)
  68.     userval->tag = 0;
  69. }
  70.  
  71. void
  72. clear_untagged_uservals (void)
  73. {
  74.     userval_t **userval;
  75.  
  76.     userval = &first;
  77.     while (*userval != 0)
  78.     {
  79.     if (!(*userval)->tag)
  80.     {
  81.         userval_t *p = *userval;
  82.  
  83.         *userval = (*userval)->next;
  84.  
  85.         if (p->type == USERVAL_IMAGE && p->v.image.index != -1)
  86.         free_input_drawable(p->v.image.index);
  87.  
  88.         free(p);
  89.     }
  90.     else
  91.         userval = &(*userval)->next;
  92.     }
  93. }
  94.  
  95. userval_t*
  96. lookup_userval (const char *name, int type)
  97. {
  98.     userval_t *userval;
  99.  
  100.     for (userval = first; userval != 0; userval = userval->next)
  101.     if (userval->type == type && strcmp(name, userval->name) == 0)
  102.         return userval;
  103.  
  104.     return 0;
  105. }
  106.  
  107. userval_t*
  108. register_slider (const char *name, float min, float max)
  109. {
  110.     userval_t *userval;
  111.  
  112.     userval = lookup_userval(name, USERVAL_SLIDER);
  113.     if (userval != 0 && userval->tag)
  114.     {
  115.     if (userval->v.slider.min == min && userval->v.slider.max == max)
  116.         return userval;
  117.     return 0;
  118.     }
  119.     else if (userval != 0 && !userval->tag)
  120.     {
  121.     if (userval->v.slider.min != min || userval->v.slider.max != max)
  122.     {
  123.         userval->v.slider.min = min;
  124.         userval->v.slider.max = max;
  125.         userval->v.slider.value = min;
  126.     }
  127.     userval->tag = 1;
  128.     }
  129.     else
  130.     {
  131.     userval = alloc_and_register_userval(name, USERVAL_SLIDER);
  132.     userval->v.slider.min = min;
  133.     userval->v.slider.max = max;
  134.     userval->v.slider.value = min;
  135.     }
  136.  
  137.     return userval;
  138. }
  139.  
  140. userval_t*
  141. register_bool (const char *name)
  142. {
  143.     userval_t *userval;
  144.  
  145.     userval = lookup_userval(name, USERVAL_BOOL);
  146.     if (userval != 0)
  147.     {
  148.     userval->tag = 1;
  149.  
  150.     return userval;
  151.     }
  152.  
  153.     userval = alloc_and_register_userval(name, USERVAL_BOOL);
  154.  
  155.     return userval;
  156. }
  157.  
  158. userval_t*
  159. register_color (const char *name)
  160. {
  161.     userval_t *userval;
  162.  
  163.     userval = lookup_userval(name, USERVAL_COLOR);
  164.     if (userval != 0)
  165.     {
  166.     userval->tag = 1;
  167.  
  168.     return userval;
  169.     }
  170.  
  171.     userval = alloc_and_register_userval(name, USERVAL_COLOR);
  172.  
  173.     userval->v.color.value.number = rgba_tag_number;
  174.     userval->v.color.value.length = 4;
  175.     userval->v.color.value.data[0] = userval->v.color.value.data[1] = userval->v.color.value.data[2] = 0.0;
  176.     userval->v.color.value.data[3] = 1.0;
  177.  
  178.     return userval;
  179. }
  180.  
  181. userval_t*
  182. register_curve (const char *name)
  183. {
  184.     userval_t *userval;
  185.     int i;
  186.  
  187.     userval = lookup_userval(name, USERVAL_CURVE);
  188.     if (userval != 0)
  189.     {
  190.     userval->tag = 1;
  191.  
  192.     return userval;
  193.     }
  194.  
  195.     userval = alloc_and_register_userval(name, USERVAL_CURVE);
  196.  
  197.     for (i = 0; i < USER_CURVE_POINTS; ++i)
  198.     userval->v.curve.values[i] = (float)i / (float)(USER_CURVE_POINTS - 1);
  199.  
  200.     return userval;
  201. }
  202.  
  203. userval_t*
  204. register_image (const char *name)
  205. {
  206.     userval_t *userval;
  207.  
  208.     userval = lookup_userval(name, USERVAL_IMAGE);
  209.     if (userval != 0)
  210.     {
  211.     userval->tag = 1;
  212.  
  213.     return userval;
  214.     }
  215.  
  216.     userval = alloc_and_register_userval(name, USERVAL_IMAGE);
  217.  
  218.     userval->v.image.index = -1;
  219.  
  220.     return userval;
  221. }
  222.  
  223. static void
  224. userval_slider_update (GtkAdjustment *adjustment, userval_t *userval)
  225. {
  226.     userval->v.slider.value = adjustment->value;
  227.  
  228.     if (auto_preview)
  229.     dialog_update_preview();
  230. }
  231.  
  232. static void
  233. userval_bool_update (GtkToggleButton *button, userval_t *userval)
  234. {
  235.     if (gtk_toggle_button_get_active(button))
  236.     userval->v.bool.value = 1.0;
  237.     else
  238.     userval->v.bool.value = 0.0;
  239.  
  240.     if (auto_preview)
  241.     dialog_update_preview();
  242. }
  243.  
  244. static void
  245. userval_color_update (ColorWell *color_well, userval_t *userval)
  246. {
  247.     gdouble color[4];
  248.     int i;
  249.  
  250.     color_well_get_color(color_well, color);
  251.     for (i = 0; i < 4; ++i)
  252.     userval->v.color.value.data[i] = color[i];
  253.  
  254.     if (auto_preview)
  255.     dialog_update_preview();
  256. }
  257.  
  258. static gint
  259. user_image_constrain (gint32 image_id, gint32 drawable_id, gpointer data)
  260. {
  261.     if (drawable_id == -1)
  262.     return TRUE;
  263.  
  264.     if (gimp_drawable_width(drawable_id) == img_width
  265.     && gimp_drawable_height(drawable_id) == img_height)
  266.     return TRUE;
  267.     else
  268.     return FALSE;
  269. }
  270.  
  271. static void
  272. user_image_update (gint32 id, userval_t *userval)
  273. {
  274.     if (userval->v.image.index != -1)
  275.     free_input_drawable(userval->v.image.index);
  276.     userval->v.image.index = alloc_input_drawable(gimp_drawable_get(id));
  277. }
  278.  
  279. GtkWidget*
  280. make_userval_table (void)
  281. {
  282.     int i;
  283.     userval_t *userval;
  284.     GtkWidget *table;
  285.  
  286.     i = 0;
  287.     for (userval = first; userval != 0; userval = userval->next)
  288.     ++i;
  289.  
  290.     if (i == 0)
  291.     return 0;
  292.  
  293.     table = gtk_table_new(i, 2, FALSE);
  294.  
  295.     i = 0;
  296.     for (userval = first; userval != 0; userval = userval->next)
  297.     {
  298.     GtkWidget *widget = 0, *label;
  299.     GtkAttachOptions xoptions = GTK_FILL | GTK_EXPAND, yoptions = 0;
  300.  
  301.     label = gtk_label_new(userval->name);
  302.     gtk_widget_show(label);
  303.     gtk_table_attach(GTK_TABLE(table), label, 0, 1, i, i + 1, 0, 0, 0, 0);
  304.  
  305.     if (userval->type == USERVAL_SLIDER)
  306.     {
  307.         GtkObject *adjustment;
  308.         float range = userval->v.slider.max - userval->v.slider.min;
  309.         int exponent, j;
  310.         float increment;
  311.  
  312.         j = exponent = (int)(floor(log10(range)) - 3);
  313.         increment = 1.0;
  314.         while (j > 0)
  315.         {
  316.         increment *= 10.0;
  317.         --j;
  318.         }
  319.         while (j < 0)
  320.         {
  321.         increment /= 10.0;
  322.         ++j;
  323.         }
  324.  
  325.         adjustment = gtk_adjustment_new(userval->v.slider.value,
  326.                         userval->v.slider.min,
  327.                         userval->v.slider.max,
  328.                         increment, increment * 10, 0.0);
  329.         gtk_signal_connect(adjustment, "value_changed",
  330.                    (GtkSignalFunc)userval_slider_update,
  331.                    userval);
  332.         widget = gtk_hscale_new(GTK_ADJUSTMENT(adjustment));
  333.         if (exponent < 0)
  334.         gtk_scale_set_digits(GTK_SCALE(widget), -exponent);
  335.         else
  336.         gtk_scale_set_digits(GTK_SCALE(widget), 0);
  337.  
  338.         gtk_widget_show(widget);
  339.     }
  340.     else if (userval->type == USERVAL_BOOL)
  341.     {
  342.         widget = gtk_check_button_new();
  343.         gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
  344.                      userval->v.bool.value != 0.0);
  345.         gtk_signal_connect(GTK_OBJECT(widget), "toggled",
  346.                    (GtkSignalFunc)userval_bool_update,
  347.                    userval);
  348.         gtk_widget_show(widget);
  349.     }
  350.     else if (userval->type == USERVAL_COLOR)
  351.     {
  352.         gdouble color[4];
  353.         int j;
  354.  
  355.         widget = color_well_new();
  356.         for (j = 0; j < 4; ++j)
  357.         color[j] = userval->v.color.value.data[j];
  358.         color_well_set_color(COLOR_WELL(widget), color);
  359.         gtk_signal_connect(GTK_OBJECT(widget), "color-changed",
  360.                    (GtkSignalFunc)userval_color_update,
  361.                    userval);
  362.         gtk_widget_show(widget);
  363.     }
  364.     else if (userval->type == USERVAL_CURVE)
  365.     {
  366.         gfloat vector[USER_CURVE_POINTS];
  367.         int j;
  368.  
  369.         for (j = 0; j < USER_CURVE_POINTS; ++j)
  370.         vector[j] = userval->v.curve.values[j] * (USER_CURVE_POINTS - 1);
  371.  
  372.         widget = gtk_gamma_curve_new();
  373.         gtk_widget_show(widget);
  374.         gtk_curve_set_range(GTK_CURVE(GTK_GAMMA_CURVE(widget)->curve),
  375.                 0, USER_CURVE_POINTS - 1, 0, USER_CURVE_POINTS - 1);
  376.         gtk_curve_set_vector(GTK_CURVE(GTK_GAMMA_CURVE(widget)->curve),
  377.                  USER_CURVE_POINTS, vector);
  378.         gtk_curve_set_range(GTK_CURVE(GTK_GAMMA_CURVE(widget)->curve), 0, 1, 0, 1);
  379.  
  380.         yoptions = GTK_FILL | GTK_EXPAND;
  381.     }
  382.     else if (userval->type == USERVAL_IMAGE)
  383.     {
  384.         GtkWidget *menu;
  385.         gint32 drawable_id = -1;
  386.  
  387.         if (userval->v.image.index != -1)
  388.         {
  389.         GDrawable *drawable = get_input_drawable(userval->v.image.index);
  390.  
  391.         if (drawable != 0)
  392.             drawable_id = drawable->id;
  393.         }
  394.  
  395.         widget = gtk_option_menu_new();
  396.         menu = gimp_drawable_menu_new(user_image_constrain, (GimpMenuCallback)user_image_update,
  397.                       userval, drawable_id);
  398.         gtk_option_menu_set_menu(GTK_OPTION_MENU(widget), menu);
  399.         gtk_widget_show(widget);
  400.     }
  401.     else
  402.         assert(0);
  403.  
  404.     gtk_table_attach(GTK_TABLE(table), widget, 1, 2, i, i + 1, xoptions, yoptions, 0, 0);
  405.  
  406.     userval->widget = widget;
  407.  
  408.     ++i;
  409.     }
  410.  
  411.     gtk_widget_show(table);
  412.  
  413.     return table;
  414. }
  415.  
  416. void
  417. update_uservals (void)
  418. {
  419.     userval_t *userval;
  420.  
  421.     for (userval = first; userval != 0; userval = userval->next)
  422.     {
  423.     if (userval->type == USERVAL_CURVE)
  424.         gtk_curve_get_vector(GTK_CURVE(GTK_GAMMA_CURVE(userval->widget)->curve), USER_CURVE_POINTS, userval->v.curve.values);
  425.     }
  426. }
  427.