[gnome-sudoku] Allow to chose how many puzzles to print per page



commit bc4625907a22d19eed5cf60bd1cdcdb235a8c462
Author: Andrey Kutejko <andy128k gmail com>
Date:   Fri Aug 14 02:06:43 2020 +0200

    Allow to chose how many puzzles to print per page

 data/org.gnome.Sudoku.gschema.xml |  6 +++++
 data/print-dialog.ui              | 46 ++++++++++++++++++++++++++++++--
 src/gnome-sudoku.vala             |  2 +-
 src/print-dialog.vala             |  5 +++-
 src/sudoku-printer.vala           | 55 +++++++++++++++++++++++++++------------
 5 files changed, 93 insertions(+), 21 deletions(-)
---
diff --git a/data/org.gnome.Sudoku.gschema.xml b/data/org.gnome.Sudoku.gschema.xml
index 5867c7f..1db8f5a 100644
--- a/data/org.gnome.Sudoku.gschema.xml
+++ b/data/org.gnome.Sudoku.gschema.xml
@@ -17,6 +17,12 @@
       <summary>Number of Sudokus to print</summary>
       <description>Set the number of sudokus you want to print</description>
     </key>
+    <key name="print-multiple-sudokus-to-print-per-page" type="i">
+      <default>2</default>
+      <range min="1" max="100" />
+      <summary>Number of Sudokus to print per page</summary>
+      <description>Set the number of sudokus you want to print per page</description>
+    </key>
     <key name="show-warnings" type="b">
       <default>true</default>
       <summary>Warn about unfillable squares and duplicate numbers</summary>
diff --git a/data/print-dialog.ui b/data/print-dialog.ui
index e67881f..dfe7a7f 100644
--- a/data/print-dialog.ui
+++ b/data/print-dialog.ui
@@ -8,6 +8,12 @@
     <property name="step-increment">1</property>
     <property name="page-increment">10</property>
   </object>
+  <object class="GtkAdjustment" id="adjustment2">
+    <property name="lower">1</property>
+    <property name="upper">100</property>
+    <property name="step-increment">1</property>
+    <property name="page-increment">1</property>
+  </object>
   <template class="PrintDialog" parent="GtkDialog">
     <property name="title" translatable="yes">Print Multiple Puzzles</property>
     <property name="can-focus">False</property>
@@ -88,6 +94,42 @@
                 <property name="top-attach">0</property>
               </packing>
             </child>
+            <child>
+              <object class="GtkLabel">
+                <property name="visible">True</property>
+                <property name="can-focus">False</property>
+                <property name="label" translatable="yes">_Number of puzzles per page</property>
+                <property name="use-underline">True</property>
+                <property name="mnemonic-widget">n_sudokus_per_page_button</property>
+                <property name="valign">center</property>
+                <property name="halign">end</property>
+                <property name="width-request">150</property>
+                <property name="xalign">1.0</property>
+              </object>
+              <packing>
+                <property name="left-attach">0</property>
+                <property name="top-attach">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkSpinButton" id="n_sudokus_per_page_button">
+                <property name="visible">True</property>
+                <property name="can-focus">True</property>
+                <property name="halign">center</property>
+                <property name="primary-icon-activatable">False</property>
+                <property name="secondary-icon-activatable">False</property>
+                <property name="primary-icon-sensitive">True</property>
+                <property name="secondary-icon-sensitive">True</property>
+                <property name="adjustment">adjustment2</property>
+                <property name="climb-rate">1</property>
+                <property name="valign">center</property>
+                <property name="margin-start">12</property>
+              </object>
+              <packing>
+                <property name="left-attach">1</property>
+                <property name="top-attach">1</property>
+              </packing>
+            </child>
             <child>
               <object class="GtkLabel">
                 <property name="visible">True</property>
@@ -100,7 +142,7 @@
               </object>
               <packing>
                 <property name="left-attach">0</property>
-                <property name="top-attach">1</property>
+                <property name="top-attach">2</property>
               </packing>
             </child>
             <child>
@@ -176,7 +218,7 @@
               </object>
               <packing>
                 <property name="left-attach">1</property>
-                <property name="top-attach">1</property>
+                <property name="top-attach">2</property>
               </packing>
             </child>
           </object>
diff --git a/src/gnome-sudoku.vala b/src/gnome-sudoku.vala
index 92ca706..1d2538b 100644
--- a/src/gnome-sudoku.vala
+++ b/src/gnome-sudoku.vala
@@ -576,7 +576,7 @@ public class Sudoku : Gtk.Application
 
         var list = new Gee.ArrayList<SudokuBoard> ();
         list.add (game.board.clone ());
-        var printer = new SudokuPrinter (list, window);
+        var printer = new SudokuPrinter (list, 1, window);
         printer.print_sudoku ();
 
         print_action.set_enabled (true);
diff --git a/src/print-dialog.vala b/src/print-dialog.vala
index 79956d3..b92dc66 100644
--- a/src/print-dialog.vala
+++ b/src/print-dialog.vala
@@ -30,6 +30,7 @@ public class PrintDialog : Dialog
     [GtkChild] private Button print_button;
     [GtkChild] private Grid print_grid;
     [GtkChild] private SpinButton n_sudokus_button;
+    [GtkChild] private SpinButton n_sudokus_per_page_button;
     [GtkChild] private RadioButton easy_radio_button;
     [GtkChild] private RadioButton medium_radio_button;
     [GtkChild] private RadioButton hard_radio_button;
@@ -75,6 +76,7 @@ public class PrintDialog : Dialog
             assert_not_reached ();
 
         wrap_adjustment ("print-multiple-sudokus-to-print", n_sudokus_button.get_adjustment ());
+        wrap_adjustment ("print-multiple-sudokus-to-print-per-page", 
n_sudokus_per_page_button.get_adjustment ());
     }
 
     private void wrap_adjustment (string key_name, Adjustment action)
@@ -101,6 +103,7 @@ public class PrintDialog : Dialog
         }
 
         var nsudokus = (int) n_sudokus_button.get_adjustment ().get_value ();
+        var nsudokus_per_page = (int) n_sudokus_per_page_button.get_adjustment ().get_value ();
         DifficultyCategory level;
 
         if (easy_radio_button.get_active ())
@@ -130,7 +133,7 @@ public class PrintDialog : Dialog
                 spinner.stop ();
                 revealer.hide ();
 
-                var printer = new SudokuPrinter (boards, this);
+                var printer = new SudokuPrinter (boards, nsudokus_per_page, this);
                 if (printer.print_sudoku () == PrintOperationResult.APPLY)
                 {
                     foreach (SudokuBoard board in boards)
diff --git a/src/sudoku-printer.vala b/src/sudoku-printer.vala
index f708f25..7b5fcbf 100644
--- a/src/sudoku-printer.vala
+++ b/src/sudoku-printer.vala
@@ -28,7 +28,7 @@ public class SudokuPrinter : GLib.Object {
 
     private int margin;
     private int n_sudokus;
-    private const int SUDOKUS_PER_PAGE = 2;
+    private int sudokus_per_page;
 
     private PrintOperation print_op;
 
@@ -50,12 +50,13 @@ public class SudokuPrinter : GLib.Object {
         return PrintOperationResult.ERROR;
     }
 
-    public SudokuPrinter (Gee.List<SudokuBoard> boards, Window window)
+    public SudokuPrinter (Gee.List<SudokuBoard> boards, int sudokus_per_page, Window window)
     {
         this.boards = boards;
         this.window = window;
         this.margin = 25;
         this.n_sudokus = boards.size;
+        this.sudokus_per_page = sudokus_per_page;
 
         this.print_op = new PrintOperation ();
         print_op.begin_print.connect (begin_print_cb);
@@ -64,8 +65,8 @@ public class SudokuPrinter : GLib.Object {
 
     private void begin_print_cb (PrintOperation operation, PrintContext context)
     {
-        int pages = n_sudokus / SUDOKUS_PER_PAGE;
-        while (pages * SUDOKUS_PER_PAGE < n_sudokus)
+        int pages = n_sudokus / sudokus_per_page;
+        while (pages * sudokus_per_page < n_sudokus)
             pages += 1;
 
         operation.set_n_pages (pages);
@@ -77,49 +78,69 @@ public class SudokuPrinter : GLib.Object {
         var width = context.get_width ();
         var height = context.get_height ();
 
-        var best_square_size = fit_squares_in_rectangle (width, height, margin);
+        set_label_font (cr);
+        Cairo.TextExtents label_extents;
+        cr.text_extents ("Ww", out label_extents);
 
-        var start = page_nr * SUDOKUS_PER_PAGE;
-        var end = int.min ((start + SUDOKUS_PER_PAGE), boards.size);
+        uint n_across, n_down;
+        var best_square_size = fit_squares_in_rectangle (width, height, label_extents.height, margin, out 
n_across, out n_down);
+        double margin_x = (width - best_square_size * n_across) / (n_across + 1);
+        double margin_y = (height - best_square_size * n_down) / (n_down + 1);
+
+        var start = page_nr * sudokus_per_page;
+        var end = int.min ((start + sudokus_per_page), boards.size);
         Gee.List<SudokuBoard> sudokus_on_page = boards.slice (start, end);
 
-        double left = (width - best_square_size) / 2;
-        double top = margin;
+        uint index = 0;
 
         foreach (SudokuBoard sudoku in sudokus_on_page)
         {
+            double left = margin_x + (index % n_across) * (best_square_size + margin_x);
+            double top = margin_y + label_extents.height + (index / n_across) * (best_square_size + margin_y 
+ label_extents.height);
+
             var label = sudoku.difficulty_category.to_string ();
-            cr.set_font_size (12);
-            cr.select_font_face ("Sans", Cairo.FontSlant.NORMAL, Cairo.FontWeight.BOLD);
+            set_label_font (cr);
             cr.set_source_rgb (0, 0, 0);
             Cairo.TextExtents extents;
             cr.text_extents (label, out extents);
-            cr.move_to ((width - extents.width) / 2, top - extents.height / 2);
+            cr.move_to (left + (best_square_size - extents.width) / 2, top - extents.height / 2);
             cr.show_text (label);
 
             draw_sudoku (cr, sudoku, best_square_size, left, top);
 
-            top += best_square_size + (2 * margin);
+            index += 1;
         }
     }
 
-    private double fit_squares_in_rectangle (double width, double height, int margin)
+    private void set_label_font (Cairo.Context cr)
     {
-        var n = SUDOKUS_PER_PAGE;
+        cr.set_font_size (12);
+        cr.select_font_face ("Sans", Cairo.FontSlant.NORMAL, Cairo.FontWeight.BOLD);
+    }
+
+    private double fit_squares_in_rectangle (double width, double height, double label_height, int margin, 
out uint across, out uint down)
+    {
+        var n = sudokus_per_page;
         var best_square_size = 0.0;
         var square_size = 0.0;
+        across = 1;
+        down = n;
 
         for (var n_across = 1; n_across <= n; n_across++)
         {
-            double n_down = n / n_across;
+            int n_down = (n + n_across - 1) / n_across;
             double across_size = width - ((n_across + 1) * margin);
             across_size = across_size / n_across;
-            double down_size = height - ((n_down + 1) * margin);
+            double down_size = height - ((n_down + 1) * margin) - n_down * label_height;
             down_size = down_size / n_down;
 
             square_size = double.min (across_size, down_size);
             if (square_size > best_square_size)
+            {
                 best_square_size = square_size;
+                across = n_across;
+                down = n_down;
+            }
         }
 
         return best_square_size;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]