home *** CD-ROM | disk | FTP | other *** search
/ PC Pro 2002 April / pcpro0402.iso / essentials / graphics / Gimp / gimp-src-20001226.exe / src / gimp / plug-ins / imagemap / imap_cmd_guides.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-02-23  |  9.8 KB  |  274 lines

  1. /*
  2.  * This is a plug-in for the GIMP.
  3.  *
  4.  * Generates clickable image maps.
  5.  *
  6.  * Copyright (C) 1998-1999 Maurits Rijk  lpeek.mrijk@consunet.nl
  7.  *
  8.  * This program is free software; you can redistribute it and/or modify
  9.  * it under the terms of the GNU General Public License as published by
  10.  * the Free Software Foundation; either version 2 of the License, or
  11.  * (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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  21.  *
  22.  */
  23.  
  24. #include <stdio.h>
  25.  
  26. #include "config.h"
  27. #include "imap_cmd_create.h"
  28. #include "imap_default_dialog.h"
  29. #include "imap_cmd_guides.h"
  30. #include "libgimp/stdplugins-intl.h"
  31. #include "imap_main.h"
  32. #include "imap_rectangle.h"
  33. #include "imap_table.h"
  34.  
  35. typedef struct {
  36.    DefaultDialog_t     *dialog;
  37.    GtkWidget        *image_dimensions;
  38.    GtkWidget        *guide_bounds;
  39.    GtkWidget        *width;
  40.    GtkWidget        *height;
  41.    GtkWidget        *left;
  42.    GtkWidget        *top;
  43.    GtkWidget        *horz_spacing;
  44.    GtkWidget        *vert_spacing;
  45.    GtkWidget        *no_across;
  46.    GtkWidget        *no_down;
  47.    GtkWidget        *base_url;
  48.  
  49.    ObjectList_t        *list;
  50. } GuidesDialog_t;
  51.  
  52. static void
  53. guides_ok_cb(gpointer data)
  54. {
  55.    GuidesDialog_t *param = (GuidesDialog_t*) data;
  56.    gint y;
  57.    int i, j;
  58.    gint width, height, left, top, hspace, vspace, rows, cols;
  59.  
  60.    width = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(param->width));
  61.    height = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(param->height));
  62.    left = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(param->left));
  63.    top = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(param->top));
  64.    hspace = gtk_spin_button_get_value_as_int(
  65.       GTK_SPIN_BUTTON(param->horz_spacing));
  66.    vspace = gtk_spin_button_get_value_as_int(
  67.       GTK_SPIN_BUTTON(param->vert_spacing));
  68.    rows = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(param->no_down));
  69.    cols = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(param->no_across));
  70.  
  71.    subcommand_start(_("Create Guides"));
  72.    y = top;
  73.    for (i = 0; i < rows; i++) {
  74.       gint x = left;
  75.       for (j = 0; j < cols; j++) {
  76.      Object_t *obj = create_rectangle(x, y, width, height);
  77.      Command_t *command = create_command_new(param->list, obj);
  78.  
  79.      object_set_url(obj, gtk_entry_get_text(GTK_ENTRY(param->base_url)));
  80.      command_execute(command);
  81.      x += width + hspace;
  82.       }
  83.       y += height + vspace;
  84.    }
  85.    subcommand_end();
  86.    redraw_preview();
  87. }
  88.  
  89. static void
  90. recalc_bounds(GtkWidget *widget, gpointer data)
  91. {
  92.    GuidesDialog_t *param = (GuidesDialog_t*) data;
  93.    gint width, height, left, top, hspace, vspace, rows, cols;
  94.    gint bound_w, bound_h;
  95.    gchar *bounds;
  96.  
  97.    width = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(param->width));
  98.    height = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(param->height));
  99.    left = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(param->left));
  100.    top = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(param->top));
  101.    hspace = gtk_spin_button_get_value_as_int(
  102.       GTK_SPIN_BUTTON(param->horz_spacing));
  103.    vspace = gtk_spin_button_get_value_as_int(
  104.       GTK_SPIN_BUTTON(param->vert_spacing));
  105.    rows = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(param->no_down));
  106.    cols = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(param->no_across));
  107.  
  108.    bound_w = (width + hspace) * cols - hspace;
  109.    bound_h = (height + vspace) * rows - vspace;
  110.  
  111.    bounds = g_strdup_printf (_("Resulting Guide Bounds: %d,%d to %d,%d (%d areas)"),
  112.                  left, top, left + bound_w, top + bound_h, rows * cols);
  113.    if (left + bound_w > get_image_width() || 
  114.        top + bound_h > get_image_height()) {
  115.       default_dialog_set_ok_sensitivity(param->dialog, FALSE);
  116.    } else {
  117.       default_dialog_set_ok_sensitivity(param->dialog, TRUE);
  118.    }
  119.    gtk_label_set_text(GTK_LABEL(param->guide_bounds), bounds);
  120.    g_free (bounds);
  121. }
  122.  
  123. static GuidesDialog_t*
  124. make_guides_dialog()
  125. {
  126.    GuidesDialog_t *data = g_new(GuidesDialog_t, 1);
  127.    DefaultDialog_t *dialog;
  128.    GtkWidget *table;
  129.    GtkWidget *label;
  130.    GtkWidget *hbox;
  131.    
  132.    dialog = data->dialog = make_default_dialog("Create Guides");
  133.    default_dialog_set_ok_cb(dialog, guides_ok_cb, data);
  134.    
  135.    label = gtk_label_new(
  136.       _("Guides are pre-defined rectangles covering the image. You define\n"
  137.     "them by their width, height, and spacing from each other. This\n"
  138.     "allows you to rapidly create the most common image map type -\n"
  139.     "image collection of \"thumbnails\", suitable for navigation bars."));
  140.    gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
  141.    gtk_container_set_border_width(
  142.       GTK_CONTAINER(GTK_DIALOG(dialog->dialog)->vbox), 10);
  143.    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog->dialog)->vbox), label, 
  144.               TRUE, TRUE, 10);
  145.    gtk_widget_show(label);
  146.    
  147.    data->image_dimensions = gtk_label_new("");
  148.    gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog->dialog)->vbox), 
  149.              data->image_dimensions);
  150.    gtk_widget_show(data->image_dimensions);
  151.  
  152.    data->guide_bounds = gtk_label_new("");
  153.    gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog->dialog)->vbox), 
  154.              data->guide_bounds);
  155.    gtk_widget_show(data->guide_bounds);
  156.  
  157.    table = gtk_table_new(4, 4, FALSE);
  158.    gtk_container_set_border_width(GTK_CONTAINER(table), 10);
  159.    gtk_table_set_row_spacings(GTK_TABLE(table), 10);
  160.    gtk_table_set_col_spacings(GTK_TABLE(table), 10);
  161.    gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog->dialog)->vbox), table);
  162.    gtk_widget_show(table);
  163.  
  164.    create_label_in_table(table, 0, 0, _("Width"));
  165.    data->width = create_spin_button_in_table(table, 0, 1, 32, 1, 100);
  166.    gtk_signal_connect(GTK_OBJECT(data->width), "changed",
  167.               GTK_SIGNAL_FUNC(recalc_bounds), (gpointer) data);
  168.  
  169.    create_label_in_table(table, 0, 2, _("Left Start at"));
  170.    data->left = create_spin_button_in_table(table, 0, 3, 0, 0, 100);
  171.    gtk_signal_connect(GTK_OBJECT(data->left), "changed",
  172.               GTK_SIGNAL_FUNC(recalc_bounds), (gpointer) data);
  173.  
  174.    create_label_in_table(table, 1, 0, _("Height"));
  175.    data->height = create_spin_button_in_table(table, 1, 1, 32, 1, 100);
  176.    gtk_signal_connect(GTK_OBJECT(data->height), "changed",
  177.               GTK_SIGNAL_FUNC(recalc_bounds), (gpointer) data);
  178.  
  179.    create_label_in_table(table, 1, 2, _("Top Start at"));
  180.    data->top = create_spin_button_in_table(table, 1, 3, 0, 0, 100);
  181.    gtk_signal_connect(GTK_OBJECT(data->top), "changed",
  182.               GTK_SIGNAL_FUNC(recalc_bounds), (gpointer) data);
  183.  
  184.    create_label_in_table(table, 2, 0, _("Horz. Spacing"));
  185.    data->horz_spacing = create_spin_button_in_table(table, 2, 1, 0, 0, 100);
  186.    gtk_signal_connect(GTK_OBJECT(data->horz_spacing), "changed",
  187.               GTK_SIGNAL_FUNC(recalc_bounds), (gpointer) data);
  188.  
  189.    create_label_in_table(table, 2, 2, _("No. Across"));
  190.    data->no_across = create_spin_button_in_table(table, 2, 3, 0, 0, 100);
  191.    gtk_signal_connect(GTK_OBJECT(data->no_across), "changed",
  192.               GTK_SIGNAL_FUNC(recalc_bounds), (gpointer) data);
  193.  
  194.    create_label_in_table(table, 3, 0, _("Vert. Spacing"));
  195.    data->vert_spacing = create_spin_button_in_table(table, 3, 1, 0, 0, 100);
  196.    gtk_signal_connect(GTK_OBJECT(data->vert_spacing), "changed",
  197.               GTK_SIGNAL_FUNC(recalc_bounds), (gpointer) data);
  198.  
  199.    create_label_in_table(table, 3, 2, _("No. Down"));
  200.    data->no_down = create_spin_button_in_table(table, 3, 3, 0, 0, 100);
  201.    gtk_signal_connect(GTK_OBJECT(data->no_down), "changed",
  202.               GTK_SIGNAL_FUNC(recalc_bounds), (gpointer) data);
  203.  
  204.    hbox = gtk_hbox_new(FALSE, 1);
  205.    gtk_container_set_border_width(GTK_CONTAINER(hbox), 10);
  206.    gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog->dialog)->vbox), hbox);
  207.    label = gtk_label_new("Base URL:");
  208.    gtk_widget_show(label);
  209.    gtk_container_add(GTK_CONTAINER(hbox), label);
  210.    data->base_url = gtk_entry_new();
  211.    gtk_container_add(GTK_CONTAINER(hbox), data->base_url);
  212.    gtk_widget_show(data->base_url);
  213.    gtk_widget_show(hbox);
  214.  
  215.    return data;
  216. }
  217.  
  218. static void
  219. init_guides_dialog(GuidesDialog_t *dialog, ObjectList_t *list)
  220. {
  221.    gchar *dimension;
  222.  
  223.    dialog->list = list;
  224.    dimension = g_strdup_printf (_("Image dimensions: %d x %d"), get_image_width(),
  225.                    get_image_height());
  226.    gtk_label_set_text(GTK_LABEL(dialog->image_dimensions), dimension);
  227.    g_free (dimension);
  228.    gtk_label_set_text(GTK_LABEL(dialog->guide_bounds), 
  229.               _("Resulting Guide Bounds: 0,0 to 0,0 (0 areas)"));
  230.    gtk_widget_grab_focus(dialog->width);
  231. }
  232.  
  233. static void
  234. do_create_guides_dialog(ObjectList_t *list)
  235. {
  236.    static GuidesDialog_t *dialog;
  237.  
  238.    if (!dialog)
  239.       dialog = make_guides_dialog();
  240.  
  241.    init_guides_dialog(dialog, list);
  242.    default_dialog_show(dialog->dialog);
  243. }
  244.  
  245. static CmdExecuteValue_t guides_command_execute(Command_t *parent);
  246.  
  247. static CommandClass_t guides_command_class = {
  248.    NULL,            /* guides_command_destruct */
  249.    guides_command_execute,
  250.    NULL,            /* guides_command_undo */
  251.    NULL                /* guides_command_redo */
  252. };
  253.  
  254. typedef struct {
  255.    Command_t parent;
  256.    ObjectList_t *list;
  257. } GuidesCommand_t;
  258.  
  259. Command_t*
  260. guides_command_new(ObjectList_t *list)
  261. {
  262.    GuidesCommand_t *command = g_new(GuidesCommand_t, 1);
  263.    command->list = list;
  264.    return command_init(&command->parent, _("Guides"), &guides_command_class);
  265. }
  266.  
  267. static CmdExecuteValue_t
  268. guides_command_execute(Command_t *parent)
  269. {
  270.    GuidesCommand_t *command = (GuidesCommand_t*) parent;
  271.    do_create_guides_dialog(command->list);
  272.    return CMD_DESTRUCT;
  273. }
  274.