1 /* GIMP - The GNU Image Manipulation Program
2 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18 #include "config.h"
19
20 #include <gegl.h>
21 #include <gtk/gtk.h>
22
23 #include "libgimpmath/gimpmath.h"
24 #include "libgimpbase/gimpbase.h"
25 #include "libgimpwidgets/gimpwidgets.h"
26
27 #include "resolution-calibrate-dialog.h"
28
29 #include "gimp-intl.h"
30
31
32 static GtkWidget *calibrate_entry = NULL;
33 static gdouble calibrate_xres = 1.0;
34 static gdouble calibrate_yres = 1.0;
35 static gint ruler_width = 1;
36 static gint ruler_height = 1;
37
38
39 /**
40 * resolution_calibrate_dialog:
41 * @resolution_entry: a #GimpSizeEntry to connect the dialog to
42 * @icon_name: an optional icon-name for the upper left corner
43 *
44 * Displays a dialog that allows the user to interactively determine
45 * her monitor resolution. This dialog runs it's own GTK main loop and
46 * is connected to a #GimpSizeEntry handling the resolution to be set.
47 **/
48 void
resolution_calibrate_dialog(GtkWidget * resolution_entry,const gchar * icon_name)49 resolution_calibrate_dialog (GtkWidget *resolution_entry,
50 const gchar *icon_name)
51 {
52 GtkWidget *dialog;
53 GtkWidget *table;
54 GtkWidget *vbox;
55 GtkWidget *hbox;
56 GtkWidget *ruler;
57 GtkWidget *label;
58 GdkScreen *screen;
59 GdkRectangle rect;
60 gint monitor;
61
62 g_return_if_fail (GIMP_IS_SIZE_ENTRY (resolution_entry));
63 g_return_if_fail (gtk_widget_get_realized (resolution_entry));
64
65 /* this dialog can only exist once */
66 if (calibrate_entry)
67 return;
68
69 dialog = gimp_dialog_new (_("Calibrate Monitor Resolution"),
70 "gimp-resolution-calibration",
71 gtk_widget_get_toplevel (resolution_entry),
72 GTK_DIALOG_DESTROY_WITH_PARENT,
73 NULL, NULL,
74
75 _("_Cancel"), GTK_RESPONSE_CANCEL,
76 _("_OK"), GTK_RESPONSE_OK,
77
78 NULL);
79
80 gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
81 GTK_RESPONSE_OK,
82 GTK_RESPONSE_CANCEL,
83 -1);
84
85 screen = gtk_widget_get_screen (dialog);
86 monitor = gdk_screen_get_monitor_at_window (screen,
87 gtk_widget_get_window (resolution_entry));
88 gdk_screen_get_monitor_workarea (screen, monitor, &rect);
89
90 ruler_width = rect.width - 300 - (rect.width % 100);
91 ruler_height = rect.height - 300 - (rect.height % 100);
92
93 table = gtk_table_new (4, 4, FALSE);
94 gtk_container_set_border_width (GTK_CONTAINER (table), 12);
95 gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
96 table, TRUE, TRUE, 0);
97 gtk_widget_show (table);
98
99 if (icon_name)
100 {
101 GtkWidget *image = gtk_image_new_from_icon_name (icon_name,
102 GTK_ICON_SIZE_DIALOG);
103
104 gtk_table_attach (GTK_TABLE (table), image, 0, 1, 0, 1,
105 GTK_SHRINK, GTK_SHRINK, 4, 4);
106 gtk_widget_show (image);
107 }
108
109 ruler = gimp_ruler_new (GTK_ORIENTATION_HORIZONTAL);
110 gtk_widget_set_size_request (ruler, ruler_width, 32);
111 gimp_ruler_set_range (GIMP_RULER (ruler), 0, ruler_width, ruler_width);
112 gtk_table_attach (GTK_TABLE (table), ruler, 1, 3, 0, 1,
113 GTK_SHRINK, GTK_SHRINK, 0, 0);
114 gtk_widget_show (ruler);
115
116 ruler = gimp_ruler_new (GTK_ORIENTATION_VERTICAL);
117 gtk_widget_set_size_request (ruler, 32, ruler_height);
118 gimp_ruler_set_range (GIMP_RULER (ruler), 0, ruler_height, ruler_height);
119 gtk_table_attach (GTK_TABLE (table), ruler, 0, 1, 1, 3,
120 GTK_SHRINK, GTK_SHRINK, 0, 0);
121 gtk_widget_show (ruler);
122
123 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
124 gtk_table_attach (GTK_TABLE (table), vbox, 1, 2, 1, 2,
125 GTK_SHRINK, GTK_SHRINK, 0, 0);
126 gtk_widget_show (vbox);
127
128 label =
129 gtk_label_new (_("Measure the rulers and enter their lengths:"));
130 gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
131 gtk_label_set_xalign (GTK_LABEL (label), 0.0);
132 gimp_label_set_attributes (GTK_LABEL (label),
133 PANGO_ATTR_SCALE, PANGO_SCALE_LARGE,
134 PANGO_ATTR_WEIGHT, PANGO_WEIGHT_BOLD,
135 -1);
136 gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
137 gtk_widget_show (label);
138
139 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
140 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
141 gtk_widget_show (hbox);
142
143 calibrate_xres =
144 gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (resolution_entry), 0);
145 calibrate_yres =
146 gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (resolution_entry), 1);
147
148 calibrate_entry =
149 gimp_coordinates_new (GIMP_UNIT_INCH, "%p",
150 FALSE, FALSE, 10,
151 GIMP_SIZE_ENTRY_UPDATE_SIZE,
152 FALSE,
153 FALSE,
154 _("_Horizontal:"),
155 ruler_width,
156 calibrate_xres,
157 1, GIMP_MAX_IMAGE_SIZE,
158 0, 0,
159 _("_Vertical:"),
160 ruler_height,
161 calibrate_yres,
162 1, GIMP_MAX_IMAGE_SIZE,
163 0, 0);
164 gtk_widget_hide (GTK_WIDGET (GIMP_COORDINATES_CHAINBUTTON (calibrate_entry)));
165 g_signal_connect (dialog, "destroy",
166 G_CALLBACK (gtk_widget_destroyed),
167 &calibrate_entry);
168
169 gtk_box_pack_end (GTK_BOX (hbox), calibrate_entry, FALSE, FALSE, 0);
170 gtk_widget_show (calibrate_entry);
171
172 gtk_widget_show (dialog);
173
174 switch (gimp_dialog_run (GIMP_DIALOG (dialog)))
175 {
176 case GTK_RESPONSE_OK:
177 {
178 GtkWidget *chain_button;
179 gdouble x, y;
180
181 x = gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (calibrate_entry), 0);
182 y = gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (calibrate_entry), 1);
183
184 calibrate_xres = (gdouble) ruler_width * calibrate_xres / x;
185 calibrate_yres = (gdouble) ruler_height * calibrate_yres / y;
186
187 chain_button = GIMP_COORDINATES_CHAINBUTTON (resolution_entry);
188
189 if (ABS (x - y) > GIMP_MIN_RESOLUTION)
190 gimp_chain_button_set_active (GIMP_CHAIN_BUTTON (chain_button),
191 FALSE);
192
193 gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (resolution_entry),
194 0, calibrate_xres);
195 gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (resolution_entry),
196 1, calibrate_yres);
197 }
198
199 default:
200 break;
201 }
202
203 gtk_widget_destroy (dialog);
204 }
205