Reflow when images become available

This commit is contained in:
Brian Anderson 2012-08-17 16:56:29 -07:00
parent 5e379067e6
commit 7bf10c8e06
6 changed files with 55 additions and 16 deletions

View file

@ -88,7 +88,8 @@ struct Content<S:Sink send copy> {
let resource_task: ResourceTask; let resource_task: ResourceTask;
new(layout: Layout, sink: S, from_master: Port<ControlMsg>, resource_task: ResourceTask) { new(layout: Layout, sink: S, from_master: Port<ControlMsg>,
resource_task: ResourceTask) {
self.layout = layout; self.layout = layout;
self.sink = sink; self.sink = sink;
self.from_master = from_master; self.from_master = from_master;
@ -193,7 +194,7 @@ struct Content<S:Sink send copy> {
// Send new document and relevant styles to layout // Send new document and relevant styles to layout
// FIXME: Put CSS rules in an arc or something. // FIXME: Put CSS rules in an arc or something.
self.layout.send(BuildMsg(document.root, clone(&document.css_rules), copy *doc_url)); self.layout.send(BuildMsg(document.root, clone(&document.css_rules), copy *doc_url, self.event_port.chan()));
// Indicate that reader was forked so any further // Indicate that reader was forked so any further
// changes will be isolated. // changes will be isolated.
@ -215,6 +216,19 @@ struct Content<S:Sink send copy> {
} }
return true; return true;
} }
ReflowEvent => {
#debug("content got reflow event");
match copy self.document {
none => {
// Nothing to do.
}
some(document) => {
assert self.doc_url.is_some();
self.relayout(*document, &self.doc_url.get());
}
}
return true;
}
} }
} }
} }

View file

@ -1,4 +1,5 @@
enum Event { enum Event {
ResizeEvent(int, int) ResizeEvent(int, int),
ReflowEvent
} }

View file

@ -21,6 +21,7 @@ import resource::image_cache_task;
import image_cache_task::ImageCacheTask; import image_cache_task::ImageCacheTask;
import core::to_str::ToStr; import core::to_str::ToStr;
import std::arc::{arc, clone}; import std::arc::{arc, clone};
import task::spawn;
enum BoxKind { enum BoxKind {
BlockBox, BlockBox,
@ -87,11 +88,13 @@ struct ImageHolder {
let mut url : option<url>; let mut url : option<url>;
let mut image : option<arc<~Image>>; let mut image : option<arc<~Image>>;
let image_cache_task: ImageCacheTask; let image_cache_task: ImageCacheTask;
let reflow: fn~();
new(-url : url, image_cache_task: ImageCacheTask) { new(-url : url, image_cache_task: ImageCacheTask, reflow: fn~()) {
self.url = some(copy url); self.url = some(copy url);
self.image = none; self.image = none;
self.image_cache_task = image_cache_task; self.image_cache_task = image_cache_task;
self.reflow = copy reflow;
// Tell the image cache we're going to be interested in this url // Tell the image cache we're going to be interested in this url
// FIXME: These two messages must be sent to prep an image for use // FIXME: These two messages must be sent to prep an image for use
@ -117,8 +120,22 @@ struct ImageHolder {
self.image_cache_task.send(image_cache_task::GetImage(copy url, response_port.chan())); self.image_cache_task.send(image_cache_task::GetImage(copy url, response_port.chan()));
self.image = match response_port.recv() { self.image = match response_port.recv() {
image_cache_task::ImageReady(image) => some(clone(&image)), image_cache_task::ImageReady(image) => some(clone(&image)),
image_cache_task::ImageNotReady image_cache_task::ImageNotReady => {
| image_cache_task::ImageFailed => { // Need to reflow when the image is available
let image_cache_task = self.image_cache_task;
let reflow = copy self.reflow;
do spawn |copy url, move reflow| {
let response_port = port();
image_cache_task.send(image_cache_task::WaitForImage(copy url, response_port.chan()));
match response_port.recv() {
image_cache_task::ImageReady(*) => reflow(),
image_cache_task::ImageNotReady => fail /*not possible*/,
image_cache_task::ImageFailed => ()
}
}
none
}
image_cache_task::ImageFailed => {
#info("image was not ready for %s", url.to_str()); #info("image was not ready for %s", url.to_str());
// FIXME: Need to schedule another layout when the image is ready // FIXME: Need to schedule another layout when the image is ready
none none

View file

@ -12,6 +12,7 @@ import gfx::renderer::Renderer;
import resource::image_cache_task::ImageCacheTask; import resource::image_cache_task::ImageCacheTask;
import std::net::url::url; import std::net::url::url;
import style::apply::apply_style; import style::apply::apply_style;
import dom::event::{Event, ReflowEvent};
import task::*; import task::*;
import comm::*; import comm::*;
@ -19,7 +20,7 @@ import comm::*;
type Layout = Chan<Msg>; type Layout = Chan<Msg>;
enum Msg { enum Msg {
BuildMsg(Node, arc<Stylesheet>, url), BuildMsg(Node, arc<Stylesheet>, url, Chan<Event>),
PingMsg(Chan<content::PingMsg>), PingMsg(Chan<content::PingMsg>),
ExitMsg ExitMsg
} }
@ -33,7 +34,7 @@ fn Layout(renderer: Renderer, image_cache_task: ImageCacheTask) -> Layout {
#debug("layout: ExitMsg received"); #debug("layout: ExitMsg received");
break; break;
} }
BuildMsg(node, styles, doc_url) => { BuildMsg(node, styles, doc_url, event_chan) => {
#debug("layout: received layout request for:"); #debug("layout: received layout request for:");
node.dump(); node.dump();
@ -44,7 +45,9 @@ fn Layout(renderer: Renderer, image_cache_task: ImageCacheTask) -> Layout {
let this_box = node.construct_boxes(); let this_box = node.construct_boxes();
this_box.dump(); this_box.dump();
apply_style(this_box, &doc_url, image_cache_task); let reflow: fn~() = || event_chan.send(ReflowEvent);
apply_style(this_box, &doc_url, image_cache_task, reflow);
this_box.reflow_subtree(px_to_au(800)); this_box.reflow_subtree(px_to_au(800));

View file

@ -14,13 +14,15 @@ struct StyleApplicator {
box: @Box; box: @Box;
doc_url: &url; doc_url: &url;
image_cache_task: ImageCacheTask; image_cache_task: ImageCacheTask;
reflow: fn~();
} }
fn apply_style(box: @Box, doc_url: &url, image_cache_task: ImageCacheTask) { fn apply_style(box: @Box, doc_url: &url, image_cache_task: ImageCacheTask, reflow: fn~()) {
let applicator = StyleApplicator { let applicator = StyleApplicator {
box: box, box: box,
doc_url: doc_url, doc_url: doc_url,
image_cache_task: image_cache_task image_cache_task: image_cache_task,
reflow: reflow
}; };
applicator.apply_css_style(); applicator.apply_css_style();
@ -28,11 +30,12 @@ fn apply_style(box: @Box, doc_url: &url, image_cache_task: ImageCacheTask) {
#[doc="A wrapper around a set of functions that can be applied as a top-down traversal of layout #[doc="A wrapper around a set of functions that can be applied as a top-down traversal of layout
boxes."] boxes."]
fn inheritance_wrapper(box : @Box, doc_url: &url, image_cache_task: ImageCacheTask) { fn inheritance_wrapper(box : @Box, doc_url: &url, image_cache_task: ImageCacheTask, reflow: fn~()) {
let applicator = StyleApplicator { let applicator = StyleApplicator {
box: box, box: box,
doc_url: doc_url, doc_url: doc_url,
image_cache_task: image_cache_task image_cache_task: image_cache_task,
reflow: reflow
}; };
applicator.apply_style(); applicator.apply_style();
inhereit_height(box); inhereit_height(box);
@ -103,8 +106,9 @@ impl StyleApplicator {
fn apply_css_style() { fn apply_css_style() {
let doc_url = copy *self.doc_url; let doc_url = copy *self.doc_url;
let image_cache_task = self.image_cache_task; let image_cache_task = self.image_cache_task;
let reflow = copy self.reflow;
do top_down_traversal(self.box) |box, move doc_url| { do top_down_traversal(self.box) |box, move doc_url| {
inheritance_wrapper(box, &doc_url, image_cache_task); inheritance_wrapper(box, &doc_url, image_cache_task, reflow);
} }
} }
@ -136,7 +140,7 @@ impl StyleApplicator {
// FIXME: Some sort of BASE HREF support! // FIXME: Some sort of BASE HREF support!
// FIXME: Parse URLs! // FIXME: Parse URLs!
let new_url = make_url(option::unwrap(url), some(copy *self.doc_url)); let new_url = make_url(option::unwrap(url), some(copy *self.doc_url));
self.box.appearance.background_image = some(ImageHolder(new_url, self.image_cache_task)) self.box.appearance.background_image = some(ImageHolder(new_url, self.image_cache_task, self.reflow))
}; };
} }
_ => { /* Ignore. */ } _ => { /* Ignore. */ }

View file

@ -1,4 +1,4 @@
export Msg, Prefetch, Decode, GetImage, Exit; export Msg, Prefetch, Decode, GetImage, WaitForImage, Exit;
export ImageResponseMsg, ImageReady, ImageNotReady, ImageFailed; export ImageResponseMsg, ImageReady, ImageNotReady, ImageFailed;
export ImageCacheTask; export ImageCacheTask;
export image_cache_task; export image_cache_task;