/// <summary>Update causes all changes to be applied and layouts to occur.</summary> public void Update() { if (DoLayout && AllowLayout) { // Layout RootDocument. Layout(); } else if (StylesToUpdate != null) { // Local update - these events typically fire from changes to things like colour/z-index etc // as well as for reflows of "flow root" nodes. // It's done down here incase a full layout request is made (above). // If a full layout request was made, it would cover all of these anyway. UpdateMode modeToUse = HighestUpdateMode; HighestUpdateMode = UpdateMode.None; bool anyReflowMode = ((int)modeToUse > (int)UpdateMode.PaintAll); if (anyReflowMode) { // We'll be re-rendering. Reset(); // Invalidate input pointers: // (So they figure out what elements are under the mouse/fingers) PowerUI.Input.PointersInvalid = true; // First, push all batches to the pool - inlined for speed: // Note that no isolated batches enter either the queue or the pool until their no longer isolated. if (FirstBatch != null) { LastBatch.BatchAfter = UIBatchPool.First; UIBatchPool.First = FirstBatch; } FirstBatch = LastBatch = null; // Note: Batches are Prepared For Layout as they are added. LayoutOccuring = true; } Css.RenderableData style = StylesToUpdate; StylesToUpdate = null; while (style != null) { UpdateMode mode = style.NextUpdateMode; switch (mode) { case UpdateMode.PaintAll: // Don't bother if we're doing either kind of reflow: if (anyReflowMode) { continue; } // Repaint it: style.RepaintAll(this); break; case UpdateMode.Paint: // Repaint it: style.Repaint(this); // Must also repaint the nodes child text nodes too (as they share the same CS): NodeList kids = style.Node.childNodes_; if (kids != null) { // For each child node.. for (int i = 0; i < kids.length; i++) { // Get it as a text node: Node child = kids[i]; if (child is TextNode) { // Repaint it too: (child as IRenderableNode).RenderData.Repaint(this); } } } break; case UpdateMode.Reflow: // Flow root reflow request. // Must setup stacks and any other renderer settings here! // Perform the initial reflow now: style.UpdateCss(this); style.Reflow(this); break; case UpdateMode.Render: // Only call render: style.Render(this); break; /* * case UpdateMode.FastReflow: * * // Fast reflow request only requires a repaint. * * break; */ } // Clear its update mode: style.NextUpdateMode = UpdateMode.None; style = style.Next; } if (!anyReflowMode) { // Only a flush is required: UIBatch toFlush = FirstBatch; while (toFlush != null) { toFlush.Flush(); toFlush = toFlush.BatchAfter; } } else { // Position elements locally. // This sets their ParentOffset values and as a result finds their PixelWidth. IRenderableNode root = RootDocument.documentElement as IRenderableNode; if (root != null) { // Finally, position them globally: // This calculates OffsetLeft/Top and also fires the render event on the computed style object. root.RenderData.Render(this); } LayoutOccuring = false; // Tell each batch we're done laying them out: UIBatch currentBatch = FirstBatch; while (currentBatch != null) { currentBatch.CompletedLayout(); currentBatch = currentBatch.BatchAfter; } // Hide all pool entries: UIBatchPool.HideAll(); } } }