[glom] Print Layout: Avoid grouping items at the tops of pages.
- From: Murray Cumming <murrayc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glom] Print Layout: Avoid grouping items at the tops of pages.
- Date: Fri, 14 Oct 2011 18:58:45 +0000 (UTC)
commit ec191a4966789fd936784ba0539a35897c6dba32
Author: Murray Cumming <murrayc murrayc com>
Date: Fri Oct 14 12:30:17 2011 +0200
Print Layout: Avoid grouping items at the tops of pages.
* glom/print_layout/print_layout_utils.[h|cc]: move_fully_to_page():
Change this to needs_move_fully_to_page(), so we can decide later how
much to move the items.
* glom/print_layout/canvas_print_layout.[h|cc]: move_items_below_item():
Rename to move_items_down(), not taking an item, and ignoring the x
dimension, moving everything down.
Remember the highest item that needs moving down more, because it
is in a page margin, then move everything below it down by the same
offset. Keep doing that until no items are in margins, gradually adding
pages. This is a simple form of pagination, and not a particularly
efficient one.
ChangeLog | 16 +++++++
glom/print_layout/canvas_print_layout.cc | 70 +++++++++++++++++++++---------
glom/print_layout/canvas_print_layout.h | 6 +-
glom/print_layout/print_layout_utils.cc | 46 ++++++++++++-------
glom/print_layout/print_layout_utils.h | 10 +++--
5 files changed, 103 insertions(+), 45 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index b76377d..7c3a3eb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,21 @@
2011-10-14 Murray Cumming <murrayc murrayc com>
+ Print Layout: Avoid grouping items at the tops of pages.
+
+ * glom/print_layout/print_layout_utils.[h|cc]: move_fully_to_page():
+ Change this to needs_move_fully_to_page(), so we can decide later how
+ much to move the items.
+ * glom/print_layout/canvas_print_layout.[h|cc]: move_items_below_item():
+ Rename to move_items_down(), not taking an item, and ignoring the x
+ dimension, moving everything down.
+ Remember the highest item that needs moving down more, because it
+ is in a page margin, then move everything below it down by the same
+ offset. Keep doing that until no items are in margins, gradually adding
+ pages. This is a simple form of pagination, and not a particularly
+ efficient one.
+
+2011-10-14 Murray Cumming <murrayc murrayc com>
+
Print Layout: Another expansion fixes.
* glom/print_layout/print_layout_utils.[h|cc]: move_fully_to_page():
diff --git a/glom/print_layout/canvas_print_layout.cc b/glom/print_layout/canvas_print_layout.cc
index 6741083..ad6118f 100644
--- a/glom/print_layout/canvas_print_layout.cc
+++ b/glom/print_layout/canvas_print_layout.cc
@@ -931,7 +931,7 @@ void Canvas_PrintLayout::fill_with_data_portal(const Glib::RefPtr<CanvasLayoutIt
double y = 0;
canvas_item->get_xy(x, y);
const double offset = portal_height - old_height;
- move_items_below_item(canvas_item, y + old_height, offset);
+ move_items_down(y + old_height, offset);
canvas_item->add_portal_rows_if_necessary(rows_count);
//TODO: Move everything else down.
@@ -1188,18 +1188,16 @@ Goocanvas::Bounds Canvas_PrintLayout::get_page_bounds(guint page_num) const
return bounds;
}
-void Canvas_PrintLayout::move_items_below_item(const Glib::RefPtr<CanvasLayoutItem>& canvas_item, double y_start, double offset)
+Glib::RefPtr<CanvasLayoutItem> Canvas_PrintLayout::move_items_down(double y_start, double offset)
{
+ //Keep track of the top-most item that needs to be moved all the way on to a new page:
+ Glib::RefPtr<CanvasLayoutItem> needs_moving_top;
+ double y_needs_moving_top = 0;
+ double needs_moving_top_height = 0;
+
Glib::RefPtr<Goocanvas::Item> root = m_items_group;
if(!root)
- return;
-
- double item_x = 0;
- double item_y = 0;
- canvas_item->get_xy(item_x, item_y);
- double item_width = 0;
- double item_height = 0;
- canvas_item->get_width_height(item_width, item_height);
+ return needs_moving_top;
double bottom_max = 0;
@@ -1209,13 +1207,13 @@ void Canvas_PrintLayout::move_items_below_item(const Glib::RefPtr<CanvasLayoutIt
for(int i = 0; i < count; ++i)
{
Glib::RefPtr<Goocanvas::Item> child = root->get_child(i);
- Glib::RefPtr<CanvasItemMovable> derived =
- CanvasItemMovable::cast_to_movable(child);
+ Glib::RefPtr<CanvasLayoutItem> derived =
+ Glib::RefPtr<CanvasLayoutItem>::cast_dynamic(child);
if(!derived)
+ {
+ std::cout << "debug: not derived" << std::endl;
continue;
-
- if(derived == canvas_item)
- continue;
+ }
//Ignore items above y_start:
double x = 0;
@@ -1228,18 +1226,29 @@ void Canvas_PrintLayout::move_items_below_item(const Glib::RefPtr<CanvasLayoutIt
double width = 0;
double height = 0;
derived->get_width_height(width, height);
- if( (x + width) < item_x)
- continue;
+ //if( (x + width) < item_x)
+ // continue;
- if( x > (item_x + item_width))
- continue;
+ //if( x > (item_x + item_width))
+ // continue;
//Move it down:
y += offset;
derived->set_xy(x, y);
+
//Move it some more if necessary:
- y = PrintLayoutUtils::move_fully_to_page(page_Setup, property_units(),
- derived);
+ //See if it should be moved down (but do that later):
+ const bool needs_moving = PrintLayoutUtils::needs_move_fully_to_page(page_Setup, property_units(), derived);
+ if(needs_moving)
+ {
+ if(!needs_moving_top || (y <= y_needs_moving_top))
+ {
+ y_needs_moving_top = y;
+
+ needs_moving_top = derived;
+ needs_moving_top_height = height;
+ }
+ }
//Check where the bottom is:
const double bottom = y + height;
@@ -1253,6 +1262,25 @@ void Canvas_PrintLayout::move_items_below_item(const Glib::RefPtr<CanvasLayoutIt
{
set_page_count(last_page_needed + 1);
}
+
+ //Now move everything further, completely on to the next page
+ //and then do that again for the next page until all the pages are done:
+ if(needs_moving_top && (y_needs_moving_top > y_start))
+ {
+ std::cout << "extra move: y_needs_moving_top=" << y_needs_moving_top << std::endl;
+ const double extra_offset =
+ PrintLayoutUtils::get_offset_to_move_fully_to_next_page(
+ page_Setup, property_units(),
+ y_needs_moving_top, needs_moving_top_height);
+ if(extra_offset)
+ {
+ needs_moving_top = move_items_down(y_needs_moving_top, extra_offset);
+ }
+ else
+ needs_moving_top.reset();
+ }
+
+ return needs_moving_top;
}
double Canvas_PrintLayout::get_page_height() const
diff --git a/glom/print_layout/canvas_print_layout.h b/glom/print_layout/canvas_print_layout.h
index 8a20b04..c5efb4b 100644
--- a/glom/print_layout/canvas_print_layout.h
+++ b/glom/print_layout/canvas_print_layout.h
@@ -91,11 +91,11 @@ public:
Goocanvas::Bounds get_page_bounds(guint page_num) const;
/** Look for any items that overlap the @a canvas_item and move them down so that the no longer overlap.
- * @param canvas_item The item that should push items out of the way.
* @param y_start Ignore any items whose y position is less than this.
- * @param offset Move items down by this amount:
+ * @param offset Move items down by this amount
+ * @param result The highest item that should be moved down to the start of the next page, if any:
*/
- void move_items_below_item(const Glib::RefPtr<CanvasLayoutItem>& canvas_item, double y_start, double offset);
+ Glib::RefPtr<CanvasLayoutItem> move_items_down(double y_start, double offset);
private:
diff --git a/glom/print_layout/print_layout_utils.cc b/glom/print_layout/print_layout_utils.cc
index 57a17fb..a2a6d80 100644
--- a/glom/print_layout/print_layout_utils.cc
+++ b/glom/print_layout/print_layout_utils.cc
@@ -88,40 +88,49 @@ static void get_page_y_start_and_end(const Glib::RefPtr<const Gtk::PageSetup>& p
//std::cout << G_STRFUNC << "page_number=" << page_number << ", y1=" << y1 << "y2=" << y2 << std::endl;
}
-
-static double move_fully_to_page(const Glib::RefPtr<const Gtk::PageSetup>& page_setup, Gtk::Unit units, double y, double height)
+double get_offset_to_move_fully_to_next_page(const Glib::RefPtr<const Gtk::PageSetup>& page_setup, Gtk::Unit units, double y, double height)
{
double top_margin = 0;
double bottom_margin = 0;
const double page_height = get_page_height(page_setup, units, top_margin, bottom_margin);
- //Ignore items that would not overlap even if they had the same y:
- //Note that we try to keep an extra GRID_GAP from the edge of the margin:
- const double usable_page_height = page_height - top_margin - bottom_margin - GRID_GAP * 2;
- if(height > usable_page_height)
- return y; //It will always be in a margin because it is so big. We could never move it somewhere where it would not be.
-
const guint current_page = PrintLayoutUtils::get_page_for_y(page_setup, units, y);
const double usable_page_start = current_page * page_height + top_margin + GRID_GAP;
//std::cout << G_STRFUNC << ": debug: current_page=" << current_page << ", usable_page_start =" << usable_page_start << std::endl;
if(y < usable_page_start) //If it is in the top margin:
{
- //Move it to the end of the top margin:
- y = usable_page_start;
+ return usable_page_start - y;
}
const double usable_page_end = (current_page + 1) * page_height - bottom_margin - GRID_GAP;
- if((y + height) > usable_page_end) //If it is in the top margin:
+ if((y + height) > usable_page_end) //If it is in the bottom margin:
{
//Move it to the start of the next page:
- y = (current_page + 1) * page_height + top_margin + GRID_GAP;
+ const double start_next_page_y = (current_page + 1) * page_height + top_margin + GRID_GAP;
+ return start_next_page_y - y;
}
- return y;
+ return 0;
}
-double move_fully_to_page(const Glib::RefPtr<const Gtk::PageSetup>& page_setup, Gtk::Unit units, const Glib::RefPtr<CanvasItemMovable>& item)
+static double move_fully_to_page(const Glib::RefPtr<const Gtk::PageSetup>& page_setup, Gtk::Unit units, double y, double height)
+{
+ double top_margin = 0;
+ double bottom_margin = 0;
+ const double page_height = get_page_height(page_setup, units, top_margin, bottom_margin);
+
+ //Ignore items that would not overlap even if they had the same y:
+ //Note that we try to keep an extra GRID_GAP from the edge of the margin:
+ const double usable_page_height = page_height - top_margin - bottom_margin - GRID_GAP * 2;
+ if(height > usable_page_height)
+ return y; //It will always be in a margin because it is so big. We could never move it somewhere where it would not be.
+
+ const double offset = get_offset_to_move_fully_to_next_page(page_setup, units, y, height);
+ return y + offset;
+}
+
+bool needs_move_fully_to_page(const Glib::RefPtr<const Gtk::PageSetup>& page_setup, Gtk::Unit units, const Glib::RefPtr<const CanvasItemMovable>& item)
{
double x = 0;
double y = 0;
@@ -131,11 +140,14 @@ double move_fully_to_page(const Glib::RefPtr<const Gtk::PageSetup>& page_setup,
double height = 0;
item->get_width_height(width, height);
+ //We don't actually move it, because items would then group together
+ //at the top of pages.
+ //Instead, the caller will discover an offset to apply to all items:
const double y_new = move_fully_to_page(page_setup, units, y, height);
if(y_new != y)
- item->set_xy(x, y_new);
-
- return y_new;
+ return true;
+
+ return false;
}
/*
diff --git a/glom/print_layout/print_layout_utils.h b/glom/print_layout/print_layout_utils.h
index be2101e..e9ea15b 100644
--- a/glom/print_layout/print_layout_utils.h
+++ b/glom/print_layout/print_layout_utils.h
@@ -53,12 +53,14 @@ double get_page_height(const Glib::RefPtr<const Gtk::PageSetup>& page_setup, Gtk
*/
guint get_page_for_y(const Glib::RefPtr<const Gtk::PageSetup>& page_setup, Gtk::Unit units, double y);
-/** Move the item to the start of a page, past the top margin,
- * if it is currently in the bottom margin of a page, or in the top margin of a page.
+/** See if the item needs to move to the start of a page, past the top margin,
+ * or if it is currently in the bottom margin of a page, or in the top margin of a page.
*
- * @result The new y position of the item.
+ * @result Whether the item needs to be moved.
*/
-double move_fully_to_page(const Glib::RefPtr<const Gtk::PageSetup>& page_setup, Gtk::Unit units, const Glib::RefPtr<CanvasItemMovable>& item);
+bool needs_move_fully_to_page(const Glib::RefPtr<const Gtk::PageSetup>& page_setup, Gtk::Unit units, const Glib::RefPtr<const CanvasItemMovable>& item);
+
+double get_offset_to_move_fully_to_next_page(const Glib::RefPtr<const Gtk::PageSetup>& page_setup, Gtk::Unit units, double y, double height);
} //namespace PrintLayoutUtils
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]