Commit 3d1427dd authored by Jim Nelson's avatar Jim Nelson

#859: Reflow was not occuring after import. This fell out of some of the...

#859: Reflow was not occuring after import.  This fell out of some of the recent optimizations (but is fixed 
thanks to recent erchitecture change!)
parent 6da4dc62
......@@ -273,6 +273,7 @@ public class CheckerboardLayout : Gtk.DrawingArea {
private static Gdk.Pixbuf selection_interior = null;
private ViewCollection view;
private string page_name = "";
private LayoutRow[] item_rows = null;
private Gee.HashSet<LayoutItem> exposed_items = new Gee.HashSet<LayoutItem>();
private Gtk.Adjustment hadjustment = null;
......@@ -290,11 +291,15 @@ public class CheckerboardLayout : Gtk.DrawingArea {
private Gdk.Point drag_endpoint = Gdk.Point();
private Gdk.Rectangle selection_band = Gdk.Rectangle();
private uint32 selection_transparency_color = 0;
private OneShotScheduler reflow_scheduler = null;
private int scale = 0;
private bool flow_dirty = true;
public CheckerboardLayout(ViewCollection view) {
this.view = view;
reflow_scheduler = new OneShotScheduler(background_reflow);
// set existing items to be part of this layout
foreach (DataObject object in view.get_all())
((LayoutItem) object).set_parent(this);
......@@ -333,6 +338,10 @@ public class CheckerboardLayout : Gtk.DrawingArea {
return scale;
}
public void set_name(string name) {
page_name = name;
}
private void on_viewport_resized() {
Gtk.Requisition req;
size_request(out req);
......@@ -345,8 +354,9 @@ public class CheckerboardLayout : Gtk.DrawingArea {
// set the layout's width and height to always match the parent's
set_size_request(parent.allocation.width, parent.allocation.height);
}
// report page change
// possible for this widget's size_allocate not to be called, so need to update the page
// rect here
update_visible_page();
}
......@@ -380,10 +390,7 @@ public class CheckerboardLayout : Gtk.DrawingArea {
// items may be removed, this ensures we're not holding the ref on a removed view
item_rows = null;
if (in_view) {
reflow("on_contents_altered");
queue_draw();
}
schedule_background_reflow();
}
private void on_items_state_changed(Gee.Iterable<DataView> changed) {
......@@ -395,11 +402,7 @@ public class CheckerboardLayout : Gtk.DrawingArea {
}
private void on_ordering_changed() {
if (!in_view)
return;
reflow("on_ordering_changed");
queue_draw();
schedule_background_reflow();
}
private void on_item_view_altered(DataView view) {
......@@ -408,11 +411,7 @@ public class CheckerboardLayout : Gtk.DrawingArea {
}
private void on_item_geometry_altered(DataView view) {
if (!in_view)
return;
reflow("on_item_geometry_altered");
repaint_item((LayoutItem) view);
schedule_background_reflow();
}
private void on_views_altered() {
......@@ -421,11 +420,18 @@ public class CheckerboardLayout : Gtk.DrawingArea {
}
private void on_geometries_altered() {
if (!in_view)
return;
reflow("on_geometries_altered");
queue_draw();
// don't schedule as this indicates all have resized and are ready for reflow
if (reflow("on_geometries_altered"))
queue_draw();
}
private void schedule_background_reflow() {
reflow_scheduler.at_idle();
}
private void background_reflow() {
if (reflow("background_reflow"))
queue_draw();
}
public void set_message(string text) {
......@@ -436,23 +442,19 @@ public class CheckerboardLayout : Gtk.DrawingArea {
set_size_request(parent.allocation.width, parent.allocation.height);
}
private void update_visible_page() {
if (!in_view)
return;
private void update_visible_page(bool reexpose = true) {
if (hadjustment == null || vadjustment == null)
return;
Gdk.Rectangle current_visible = get_adjustment_page(hadjustment, vadjustment);
if (current_visible.width <= 1 || current_visible.height <= 1)
return;
if (rectangles_equal(visible_page, current_visible))
return;
bool changed = !rectangles_equal(visible_page, current_visible);
visible_page = current_visible;
if (!reexpose || !in_view || !changed)
return;
// create a new hash set of exposed items that represents an intersection of the old set
// and the new
Gee.HashSet<LayoutItem> new_exposed_items = new Gee.HashSet<LayoutItem>();
......@@ -477,7 +479,15 @@ public class CheckerboardLayout : Gtk.DrawingArea {
public void set_in_view(bool in_view) {
this.in_view = in_view;
if (in_view) {
update_visible_page();
// update the visible page rectangle, but only re-expose items if not going to reflow
// the layout (which exposes already)
update_visible_page(!flow_dirty);
// if the flow dirtied at some point, now reflow the layout
if (flow_dirty) {
if (reflow("set_in_view"))
queue_draw();
}
return;
}
......@@ -687,27 +697,36 @@ public class CheckerboardLayout : Gtk.DrawingArea {
queue_draw();
}
public void reflow(string caller) {
/*
debug("reflow: %s", caller);
*/
// Returns true if a redraw is required
private bool reflow(string caller) {
// if set in message mode, nothing to do here
if (message != null)
return;
return false;
// don't bother until layout is of some appreciable size (even this is too low)
if (allocation.width <= 1)
return;
return false;
// don't reflow if not in view of the user
if (!in_view) {
flow_dirty = true;
return false;
}
// need to set_size in case all items were removed and the viewport size has changed
int total_items = view.get_count();
if (total_items == 0) {
set_size_request(allocation.width, 0);
flow_dirty = false;
return;
return true;
}
#if TRACE_REFLOW
debug("reflow %s: %s", page_name, caller);
#endif
// clear the rows data structure, as the reflow will completely rearrange it
item_rows = null;
......@@ -821,8 +840,10 @@ public class CheckerboardLayout : Gtk.DrawingArea {
max_cols--;
max_rows = (view.get_count() / max_cols) + 1;
debug("readjusting columns: alloc.width=%d total_width=%d widest=%d gutter=%d max_cols now=%d",
allocation.width, total_width, widest, gutter, max_cols);
#if TRACE_REFLOW
debug("reflow %s: readjusting columns: alloc.width=%d total_width=%d widest=%d gutter=%d max_cols now=%d",
page_name, allocation.width, total_width, widest, gutter, max_cols);
#endif
col = 0;
row = 0;
......@@ -836,10 +857,10 @@ public class CheckerboardLayout : Gtk.DrawingArea {
}
}
/*
debug("refresh(): width:%d total_width:%d max_cols:%d gutter:%d", allocation.width, total_width,
max_cols, gutter);
*/
#if TRACE_REFLOW
debug("reflow %s: width:%d total_width:%d max_cols:%d gutter:%d", page_name, allocation.width,
total_width, max_cols, gutter);
#endif
// for the spatial structure
item_rows = new LayoutRow[max_rows];
......@@ -913,6 +934,10 @@ public class CheckerboardLayout : Gtk.DrawingArea {
// Step 5: Define the total size of the page as the size of the allocated width and
// the height of all the items plus padding
set_size_request(allocation.width, y + row_heights[row] + BOTTOM_PADDING);
flow_dirty = false;
return true;
}
private void repaint_item(LayoutItem item) {
......@@ -961,19 +986,21 @@ public class CheckerboardLayout : Gtk.DrawingArea {
selection_band_gc = new Gdk.GC.with_values(window, gc_values, mask);
}
private override void realize() {
base.realize();
reflow("realize");
}
private override void size_allocate(Gdk.Rectangle allocation) {
base.size_allocate(allocation);
// only refresh() if the width has changed
if (in_view && (allocation.width != last_width)) {
// only reflow() if the width has changed
if (allocation.width != last_width) {
last_width = allocation.width;
reflow("CheckerboardLayout size_allocate %d".printf(last_width));
// update visible page rect but don't call expose events, as reflow will do that
update_visible_page(false);
if (reflow("size_allocate (%d)".printf(last_width)))
queue_draw();
} else {
// update visible page rect, re-exposing as necessary
update_visible_page();
}
}
......
......@@ -646,12 +646,6 @@ public class CollectionPage : CheckerboardPage {
set_thumb_size(current_scale);
}
public override void returning_from_fullscreen() {
refresh("returning_from_fullscreen");
base.returning_from_fullscreen();
}
private void on_contents_altered() {
slideshow_button.sensitive = get_view().get_count() > 0;
}
......
......@@ -131,12 +131,6 @@ public class EventsDirectoryPage : CheckerboardPage {
return actions;
}
public override void realize() {
refresh("realize");
base.realize();
}
public override Gtk.Toolbar get_toolbar() {
return toolbar;
}
......
......@@ -506,7 +506,6 @@ public class ImportPage : CheckerboardPage {
// show 'em all or show none
get_view().clear();
refresh("refresh_camera");
return (refresh_result == GPhoto.Result.IO_LOCK) ? RefreshResult.LOCKED : RefreshResult.LIBRARY_ERROR;
}
......
......@@ -65,7 +65,7 @@ public abstract class Page : Gtk.ScrolledWindow, SidebarPage {
return page_name;
}
public void set_page_name(string page_name) {
public virtual void set_page_name(string page_name) {
this.page_name = page_name;
}
......@@ -494,6 +494,7 @@ public abstract class CheckerboardPage : Page {
base(page_name);
layout = new CheckerboardLayout(get_view());
layout.set_name(name);
set_event_source(layout);
......@@ -554,18 +555,18 @@ public abstract class CheckerboardPage : Page {
public abstract LayoutItem? get_fullscreen_photo();
public void refresh(string caller) {
layout.reflow(caller);
if (is_in_view())
layout.queue_draw();
}
public void set_page_message(string message) {
layout.set_message(message);
if (is_in_view())
layout.queue_draw();
}
public override void set_page_name(string name) {
base.set_page_name(name);
layout.set_name(name);
}
public LayoutItem? get_item_at_pixel(double x, double y) {
return layout.get_item_at_pixel(x, y);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment