[PATCH] Add user definible options to the print menu

Salvador Cuñat salvador.cunat at gmail.com
Sun Mar 17 10:34:01 PDT 2013


Define a new frame wich will englobe the layout options.
1.-  Move to this frame the color profile printing by Amit
2.-  Add an option which switches the position of the profile and a predefined block
       comprensive of header, tanks data and notes.
             - Divide print() in two macros PROFILE_BLOCK and NOTES_BLOCK
             - Add a gboolean to print_options. If unselected (default) we get the actual
               disposition. If selected, switches blocks.
3.-  Add three spin buttons with labels to set the height of the profile, notes and tanks.
       We select the percentage of layout occupied by each option, reserving 7% for the
       header (non adjustable).
            - Values in % have got hardcoded min/max (e.g. being the profile a major feature
               of subsurface, would be senseless make it < 37%)
            - The values are initialised to the actual ones, so leaving them untouched defaults
               to the old printout.
            - The maths involved in SCALECALLBACK function seem infantile and are,
               probably, very improvable.

Signed-off-by: Salvador Cuñat <salvador.cunat at gmail.com>
---
 display.h |    2 +
 print.c   |  163 +++++++++++++++++++++++++++++++++++++++++++++++++++++--------
 2 files changed, 145 insertions(+), 20 deletions(-)

diff --git a/display.h b/display.h
index c0163ae..eca210e 100644
--- a/display.h
+++ b/display.h
@@ -55,6 +55,8 @@ struct options {
 	enum { PRETTY, TABLE, TWOPERPAGE } type;
 	int print_selected;
 	int color_selected;
+	gboolean notes_up;
+	int profile_height, notes_height, tanks_height;
 };
 
 extern char zoomed_plot, dc_number;
diff --git a/print.c b/print.c
index 9ea0978..e7cf590 100644
--- a/print.c
+++ b/print.c
@@ -20,6 +20,10 @@ static int *first_dive;
 
 static struct options print_options;
 
+typedef struct _Spin_Buttons_Block {
+	GtkWidget *box, *spin1, *spin2, *spin3;
+} Spin_buttons_block;
+
 typedef struct _Print_params {
 	int rotation, dives;
 	double w_scale, h_scale;
@@ -610,6 +614,18 @@ static void show_dive_profile(struct dive *dive, cairo_t *cr, double w,
 	cairo_restore(cr);
 }
 
+#define NOTES_BLOCK()  \
+	show_dive_header(dive, cr, w*2, dive_header_height, font, w_scale_factor);\
+	cairo_translate(cr, 0, dive_header_height); \
+	show_dive_tanks (dive, cr, w*1, dive_tanks_height, font, w_scale_factor);\
+	cairo_translate(cr, 0, dive_tanks_height);\
+	show_dive_notes(dive, cr, w*2, dive_notes_height, font, w_scale_factor);\
+	cairo_translate(cr, 0, dive_notes_height);
+
+#define PROFILE_BLOCK() \
+	show_dive_profile(dive, cr, w*2, dive_profile_height);\
+	cairo_translate(cr, 0, dive_profile_height);
+
 static void print(int divenr, cairo_t *cr, double x, double y, double w,
 	double h, PangoFontDescription *font, double w_scale_factor)
 {
@@ -634,19 +650,18 @@ static void print(int divenr, cairo_t *cr, double x, double y, double w,
 	/* We actually want to scale the text and the lines now */
 	cairo_scale(cr, 0.5, 0.5);
 
-	/* Dive plot in the upper two thirds - note the scaling */
-	show_dive_profile(dive, cr, w*2, h*1.30);
-
-	/* Dive information in the lower third */
-	cairo_translate(cr, 0, h*1.30);
-	show_dive_header(dive, cr, w*2, h*0.15, font, w_scale_factor);
-
-	cairo_translate(cr, 0, h*0.15);
-	show_dive_tanks (dive, cr, w*1, h*0.25, font, w_scale_factor);
-
-	cairo_translate(cr, 0, h*0.25);
-	show_dive_notes(dive, cr, w*2, h*0.30, font, w_scale_factor);
+	double dive_header_height = h*0.15;
+	double dive_tanks_height = h* ((double) print_options.tanks_height/50);
+	double dive_notes_height = h* ((double) print_options.notes_height/50);
+	double dive_profile_height = h* ((double) print_options.profile_height/50);
 
+	if (!print_options.notes_up) {
+		PROFILE_BLOCK()
+		NOTES_BLOCK()
+	} else {
+		NOTES_BLOCK()
+		PROFILE_BLOCK()
+	}
 	cairo_restore(cr);
 }
 
@@ -873,11 +888,55 @@ static void name(GtkWidget *w, gpointer data) \
 
 OPTIONSELECTEDCALLBACK(print_selection_toggle, print_options.print_selected)
 OPTIONSELECTEDCALLBACK(color_selection_toggle, print_options.color_selected)
+OPTIONSELECTEDCALLBACK(notes_up, print_options.notes_up)
+
+/*
+ * Hardcoded minimum and maximum values for the scaling spin_buttons
+ */
+#define profile_height_min (37)
+#define notes_height_min (7)
+#define tanks_height_min (7)
+#define profile_height_max (77)
+#define notes_height_max (49)
+#define tanks_height_max (17)
 
+/*
+ * Callback function that sets the values of the heigths.
+ * It takes care of avoiding sub minimal values as they can result
+ * in plots bigger than avaliable height, e.g. Big numbers for profile
+ * and notes can make tanks < 7, this would be corrected by the spin_button
+ * funcs that will make it 7 again, but then the sum of all three heights
+ * would be bigger than maximum size avaliable for printing 93%.
+ * There's a 7% reserved for the header which isn't scaled
+ */
+#define SCALECALLBACK(name, scales1, scales2, scales3)\
+static void name(GtkWidget *button, Spin_buttons_block *data)\
+{ \
+    print_options.scales1 = gtk_spin_button_get_value(GTK_SPIN_BUTTON(button)); \
+	print_options.scales2 = 93 - print_options.scales1 - print_options.scales3; \
+	if (print_options.scales2 < scales2##_min) { \
+		print_options.scales2 = scales2##_min; \
+		print_options.scales3 = 93 - print_options.scales1 - print_options.scales3; \
+	} \
+	gtk_spin_button_set_value (GTK_SPIN_BUTTON(data->spin1), print_options.profile_height);\
+	gtk_spin_button_set_value (GTK_SPIN_BUTTON(data->spin2), print_options.notes_height);\
+	gtk_spin_button_set_value (GTK_SPIN_BUTTON(data->spin3), print_options.tanks_height);\
+	gtk_box_pack_start (GTK_BOX(data->box), data->spin1, TRUE, TRUE, 5);\
+	gtk_box_pack_start (GTK_BOX(data->box), data->spin2, TRUE, TRUE, 5);\
+	gtk_box_pack_start (GTK_BOX(data->box), data->spin3, TRUE, TRUE, 5);\
+}
+
+SCALECALLBACK (prof_spin_button, profile_height, notes_height, tanks_height)
+SCALECALLBACK (notes_spin_button, notes_height, profile_height, tanks_height)
+SCALECALLBACK (tanks_spin_button, tanks_height, notes_height, profile_height)
 
 static GtkWidget *print_dialog(GtkPrintOperation *operation, gpointer user_data)
 {
-	GtkWidget *vbox, *radio1, *radio2, *radio3, *frame, *box;
+	GtkWidget *vbox, *radio1, *radio2, *radio3, *radio4, *radio5,
+	*frame, *frame1, *frame2,
+	*box, *box1, *box2, *box3, *box4,
+	*button, *colorButton, *label1, *label2, *label3,
+	*scale_prof_button, *scale_notes_button, *scale_tanks_button;
 	int dives;
 	gtk_print_operation_set_custom_tab_label(operation, _("Print type"));
 
@@ -915,20 +974,84 @@ static GtkWidget *print_dialog(GtkPrintOperation *operation, gpointer user_data)
 		gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 1);
 		box = gtk_hbox_new(FALSE, 1);
 		gtk_container_add(GTK_CONTAINER(frame), box);
-		GtkWidget *button;
 		button = gtk_check_button_new_with_label(_("Print only selected dives"));
 		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button),
 			print_options.print_selected);
 		gtk_box_pack_start(GTK_BOX(box), button, FALSE, FALSE, 2);
 		g_signal_connect(G_OBJECT(button), "toggled",
 			G_CALLBACK(print_selection_toggle), NULL);
-		GtkWidget *colorButton;
-		colorButton = gtk_check_button_new_with_label(_("Print in color"));
-		g_signal_connect(G_OBJECT(colorButton), "toggled",
-			G_CALLBACK(color_selection_toggle), NULL);
-		gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(colorButton),TRUE);
-		gtk_box_pack_start(GTK_BOX(box), colorButton, FALSE, FALSE, 2);
 	}
+	frame = gtk_frame_new(_("Layout Options"));
+	gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 1);
+	box = gtk_hbox_new(FALSE, 5);
+	gtk_container_add(GTK_CONTAINER(frame), box);
+	colorButton = gtk_check_button_new_with_label(_("Print in color"));
+	g_signal_connect(G_OBJECT(colorButton), "toggled",
+		G_CALLBACK(color_selection_toggle), NULL);
+	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(colorButton),TRUE);
+	gtk_box_pack_start(GTK_BOX(box), colorButton, FALSE, FALSE, 2);
+
+	frame1 = gtk_frame_new(_("Ordering"));
+	gtk_box_pack_start(GTK_BOX(box), frame1, FALSE, FALSE, 5);
+	box1 = gtk_vbox_new (TRUE, 1);
+	gtk_container_add(GTK_CONTAINER(frame1), box1);
+
+	radio4 = gtk_radio_button_new_with_label_from_widget (NULL, _("Profile on top"));
+	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio4), FALSE);
+	g_signal_connect(G_OBJECT(radio4), "toggled", NULL, NULL);
+
+	radio5 = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio4), _("Notes on top"));
+	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio4), FALSE);
+	g_signal_connect(G_OBJECT(radio5), "toggled", G_CALLBACK(notes_up), NULL);
+
+	gtk_box_pack_start(GTK_BOX(box1), radio4, TRUE, FALSE, 2);
+	gtk_box_pack_start(GTK_BOX(box1), radio5, TRUE, FALSE, 2);
+
+	frame2 = gtk_frame_new(_("Sizing heights (\% of layout)"));
+	gtk_box_pack_start(GTK_BOX(box), frame2, FALSE, FALSE, 5);
+
+	box2 = gtk_hbox_new (TRUE, 1);
+	gtk_container_add (GTK_CONTAINER(frame2), box2);
+
+	box3 = gtk_vbox_new (FALSE, 5);
+	gtk_box_pack_start(GTK_BOX(box2), box3, FALSE, FALSE, 5);
+	box4 = gtk_vbox_new (FALSE, 5);
+	gtk_box_pack_start(GTK_BOX(box2), box4, FALSE, FALSE, 5);
+
+	label1 = gtk_label_new(_("Profile height (37% - 77%)"));
+	label2 = gtk_label_new(_("Notes height (7% - 77%)"));
+	label3 = gtk_label_new(_("Other data height (7% - 17%)"));
+	gtk_box_pack_start (GTK_BOX(box3), label1, FALSE, FALSE, 10);
+	gtk_box_pack_start (GTK_BOX(box3), label2, FALSE, FALSE, 10);
+	gtk_box_pack_start (GTK_BOX(box3), label3, FALSE, FALSE, 10);
+
+	/* Initialize the options to the actual layout */
+	print_options.profile_height = 65;
+	print_options.notes_height = 15;
+	print_options.tanks_height = 12;
+
+	Spin_buttons_block *spin_buttons_block = g_slice_new(Spin_buttons_block);
+	spin_buttons_block->box = box4;
+
+	scale_prof_button = gtk_spin_button_new_with_range (profile_height_min, profile_height_max, 1);
+	gtk_spin_button_set_value (GTK_SPIN_BUTTON(scale_prof_button), print_options.profile_height);
+	spin_buttons_block->spin1 = scale_prof_button;
+
+	scale_notes_button = gtk_spin_button_new_with_range (notes_height_min, notes_height_max, 1);
+	gtk_spin_button_set_value (GTK_SPIN_BUTTON(scale_notes_button), print_options.notes_height);
+	spin_buttons_block->spin2 = scale_notes_button;
+
+	scale_tanks_button = gtk_spin_button_new_with_range (tanks_height_min, tanks_height_max, 1);
+	gtk_spin_button_set_value (GTK_SPIN_BUTTON(scale_tanks_button), print_options.tanks_height);
+	spin_buttons_block->spin3 = scale_tanks_button;
+
+	g_signal_connect(G_OBJECT(scale_prof_button),"value-changed",G_CALLBACK(prof_spin_button), spin_buttons_block);
+	g_signal_connect(G_OBJECT(scale_notes_button),"value-changed",G_CALLBACK(notes_spin_button), spin_buttons_block);
+	g_signal_connect(G_OBJECT(scale_tanks_button),"value-changed",G_CALLBACK(tanks_spin_button), spin_buttons_block);
+
+	gtk_box_pack_start (GTK_BOX(box4), scale_prof_button, TRUE, TRUE, 5);
+	gtk_box_pack_start (GTK_BOX(box4), scale_notes_button, TRUE, TRUE, 5);
+	gtk_box_pack_start (GTK_BOX(box4), scale_tanks_button, TRUE, TRUE, 5);
 
 	gtk_widget_show_all(vbox);
 	return vbox;
-- 
1.7.10.4



More information about the subsurface mailing list