public void LayoutCeGui()
        {
            // used to compare UDims
            var absWidth = GetChildContentArea().Get().Width;

            // this is where we store the top offset
            // we continually increase this number as we go through the windows
            var topOffset   = UDim.Zero;
            var layoutWidth = UDim.Zero;

            foreach (var window in d_children.Cast <Window>())
            {
                var offset       = GetOffsetForWindow(window);
                var boundingSize = GetBoundingSizeForWindow(window);

                // full child window width, including margins
                var childWidth = boundingSize.d_x;

                if (CoordConverter.AsAbsolute(layoutWidth, absWidth) < CoordConverter.AsAbsolute(childWidth, absWidth))
                {
                    layoutWidth = childWidth;
                }

                window.SetPosition(offset + new UVector2(UDim.Zero, topOffset));
                topOffset += boundingSize.d_y;
            }

            SetSize(new USize(layoutWidth, topOffset));
            //SetHeight(topOffset);
        }
예제 #2
0
        public override float GetValueFromThumb()
        {
            var w = (Slider)Window;

            // get area the thumb is supposed to use as it's area.
            var wlf  = GetLookNFeel();
            var area = wlf.GetNamedArea("ThumbTrackArea").GetArea().GetPixelRect(w);
            // get accesss to the thumb
            var theThumb = w.GetThumb();

            // slider is vertical
            if (_vertical)
            {
                // pixel extent of total available area the thumb moves in
                var slideExtent = area.Height - theThumb.GetPixelSize().Height;
                // calculate value represented by current thumb position
                var thumbValue = (CoordConverter.AsAbsolute(theThumb.GetYPosition(), w.GetPixelSize().Height) -
                                  area.Top) / (slideExtent / w.GetMaxValue());
                // return final thumb value according to slider settings
                return(_reversed ? thumbValue : w.GetMaxValue() - thumbValue);
            }
            // slider is horizontal
            else
            {
                // pixel extent of total available area the thumb moves in
                var slideExtent = area.Width - theThumb.GetPixelSize().Width;
                // calculate value represented by current thumb position
                var thumbValue = (CoordConverter.AsAbsolute(theThumb.GetXPosition(), w.GetPixelSize().Width) -
                                  area.Left) / (slideExtent / w.GetMaxValue());
                // return final thumb value according to slider settings
                return(_reversed ? w.GetMaxValue() - thumbValue : thumbValue);
            }
        }
        private void LayoutCeGui()
        {
            // used to compare UDims
            var absHeight = GetChildContentArea().Get().Height;

            // this is where we store the left offset
            // we continually increase this number as we go through the windows
            var leftOffset   = UDim.Zero;
            var layoutHeight = UDim.Zero;

            foreach (Window window in d_children)
            {
                //Window* window = static_cast<Window*>(*it);

                var offset       = GetOffsetForWindow(window);
                var boundingSize = GetBoundingSizeForWindow(window);

                // full child window width, including margins
                var childHeight = boundingSize.d_y;

                if (CoordConverter.AsAbsolute(layoutHeight, absHeight) <
                    CoordConverter.AsAbsolute(childHeight, absHeight))
                {
                    layoutHeight = childHeight;
                }

                window.SetPosition(offset + new UVector2(leftOffset, UDim.Zero));
                leftOffset += boundingSize.d_x;
            }

            SetSize(new USize(leftOffset, layoutHeight));
        }
예제 #4
0
        /// <summary>
        /// set the movement range of the thumb for the horizontal axis.
        ///
        /// The values specified here are relative to the parent window for the thumb, and are specified in whichever
        /// metrics mode is active for the widget.
        /// </summary>
        /// <param name="min">
        /// the minimum setting for the thumb on the horizontal axis.
        /// </param>
        /// <param name="max">
        /// the maximum setting for the thumb on the horizontal axis.
        /// </param>
        public void SetHorzRange(float min, float max)
        {
            var parentSize = GetParentPixelSize();

            // ensure min <= max, swap if not.
            if (min > max)
            {
                var tmp = min;
                max = min;
                min = tmp;
            }

            _horzMax = max;
            _horzMin = min;

            // validate current position.
            var cp = CoordConverter.AsAbsolute(GetXPosition(), parentSize.Width);

            if (cp < min)
            {
                SetXPosition(UDim.Absolute(min));
            }
            else if (cp > max)
            {
                SetXPosition(UDim.Absolute(max));
            }
        }
예제 #5
0
        /// <summary>
        /// Return whether the required minimum movement threshold before initiating dragging
        /// has been exceeded.
        /// </summary>
        /// <param name="localMouse">
        /// Mouse position as a pixel offset from the top-left corner of this window.
        /// </param>
        /// <returns>
        /// - true if the threshold has been exceeded and dragging should be initiated.
        /// - false if the threshold has not been exceeded.
        /// </returns>
        protected bool IsDraggingThresholdExceeded(Lunatics.Mathematics.Vector2 localMouse)
        {
            // calculate amount mouse has moved.
            var deltaX = Math.Abs(localMouse.X - CoordConverter.AsAbsolute(_dragPoint.d_x, d_pixelSize.Width));
            var deltaY = Math.Abs(localMouse.Y - CoordConverter.AsAbsolute(_dragPoint.d_y, d_pixelSize.Height));

            // see if mouse has moved far enough to start dragging operation
            return(deltaX > _dragThreshold || deltaY > _dragThreshold);
        }
예제 #6
0
        public override void Layout()
        {
            var colSizes = new List <UDim>(Enumerable.Repeat(UDim.Zero, _gridWidth));
            var rowSizes = new List <UDim>(Enumerable.Repeat(UDim.Zero, _gridHeight));

            // used to compare UDims
            var absWidth  = GetChildContentArea().Get().Width;
            var absHeight = GetChildContentArea().Get().Height;

            // first, we need to determine rowSizes and colSizes, this is needed before
            // any layouting work takes place
            for (var y = 0; y < _gridHeight; ++y)
            {
                for (var x = 0; x < _gridWidth; ++x)
                {
                    // x and y is the position of window in the grid
                    var childIdx = MapFromGridToIdx(x, y, _gridWidth, _gridHeight);

                    var window = GetChildAtIdx(childIdx);
                    var size   = GetBoundingSizeForWindow(window);

                    if (CoordConverter.AsAbsolute(colSizes[x], absWidth) <
                        CoordConverter.AsAbsolute(size.d_x, absWidth))
                    {
                        colSizes[x] = size.d_x;
                    }

                    if (CoordConverter.AsAbsolute(rowSizes[y], absHeight) <
                        CoordConverter.AsAbsolute(size.d_y, absHeight))
                    {
                        rowSizes[y] = size.d_y;
                    }
                }
            }

            // OK, now in rowSizes[y] is the height of y-th row
            //         in colSizes[x] is the width of x-th column

            // second layouting phase starts now
            for (var y = 0; y < _gridHeight; ++y)
            {
                for (var x = 0; x < _gridWidth; ++x)
                {
                    // x and y is the position of window in the grid
                    var childIdx       = MapFromGridToIdx(x, y, _gridWidth, _gridHeight);
                    var window         = GetChildAtIdx(childIdx);
                    var offset         = GetOffsetForWindow(window);
                    var gridCellOffset = GetGridCellOffset(colSizes, rowSizes, x, y);

                    window.SetPosition(gridCellOffset + offset);
                }
            }

            // now we just need to determine the total width and height and set it
            SetSize(GetGridSize(colSizes, rowSizes));
        }
예제 #7
0
        /// <summary>
        /// Internal implementation of make tab visible.
        /// </summary>
        /// <param name="wnd">
        /// Pointer to a Window which is the root of the tab content to make visible
        /// </param>
        protected virtual void MakeTabVisibleImpl(Window wnd)
        {
            TabButton tb = null;

            foreach (var item in d_tabButtonVector)
            {
                // get corresponding tab button and content window
                tb = item;
                var child = tb.GetTargetWindow();
                if (child == wnd)
                {
                    break;
                }

                tb = null;
            }

            if (tb == null)
            {
                return;
            }

            var   ww = GetPixelSize().Width;
            var   x = CoordConverter.AsAbsolute(tb.GetPosition().d_x, ww);
            var   w = tb.GetPixelSize().Width;
            float lx = 0f, rx = ww;

            if (IsChild(ButtonScrollLeft))
            {
                var scrollLeftBtn = GetChild(ButtonScrollLeft);
                lx = CoordConverter.AsAbsolute(scrollLeftBtn.GetArea().d_max.d_x, ww);
                scrollLeftBtn.SetWantsMultiClickEvents(false);
            }

            if (IsChild(ButtonScrollRight))
            {
                var scrollRightBtn = GetChild(ButtonScrollRight);
                rx = CoordConverter.AsAbsolute(scrollRightBtn.GetPosition().d_x, ww);
                scrollRightBtn.SetWantsMultiClickEvents(false);
            }

            if (x < lx)
            {
                d_firstTabOffset += lx - x;
            }
            else
            {
                if (x + w <= rx)
                {
                    return; // nothing to do
                }
                d_firstTabOffset += rx - (x + w);
            }

            PerformChildWindowLayout();
        }
예제 #8
0
        public override void ResizeListToContent(bool fitWidth, bool fitHeight)
        {
            var lb = (Listbox)Window;

            var totalArea   = lb.GetUnclippedOuterRect().Get();
            var contentArea = GetItemRenderingArea(!fitWidth && lb.GetHorzScrollbar().IsVisible(),
                                                   !fitHeight && lb.GetVertScrollbar().IsVisible());

            var withScrollContentArea = GetItemRenderingArea(true, true);

            var frameSize           = totalArea.Size - contentArea.Size;
            var withScrollFrameSize = totalArea.Size - withScrollContentArea.Size;
            var contentSize         = new Sizef(lb.GetWidestItemWidth(),
                                                lb.GetTotalItemsHeight());

            var parentSize = lb.GetParentPixelSize();
            var maxSize    =
                new Sizef(parentSize.Width - CoordConverter.AsAbsolute(lb.GetXPosition(), parentSize.Width),
                          parentSize.Height - CoordConverter.AsAbsolute(lb.GetYPosition(), parentSize.Height));

            var requiredSize = frameSize + contentSize + new Sizef(1, 1);

            if (fitHeight)
            {
                if (requiredSize.Height > maxSize.Height)
                {
                    requiredSize.Height = maxSize.Height;
                    requiredSize.Width  = Math.Min(maxSize.Width,
                                                   requiredSize.Width - frameSize.Width +
                                                   withScrollFrameSize.Width);
                }
            }

            if (fitWidth)
            {
                if (requiredSize.Width > maxSize.Width)
                {
                    requiredSize.Width  = maxSize.Width;
                    requiredSize.Height = Math.Min(maxSize.Height,
                                                   requiredSize.Height - frameSize.Height +
                                                   withScrollFrameSize.Height);
                }
            }

            if (fitHeight)
            {
                lb.SetHeight(new UDim(0, requiredSize.Height));
            }

            if (fitWidth)
            {
                lb.SetWidth(new UDim(0, requiredSize.Width));
            }
        }
예제 #9
0
        /// <summary>
        /// Resize the ItemListBase to exactly fit the content that is attached to it.
        /// Return a Rect object describing, in un-clipped pixels, the window relative area
        /// that is to be used for rendering items.
        /// </summary>
        protected virtual void SizeToContentImpl()
        {
            var renderArea = GetItemRenderArea();
            var wndArea    = CoordConverter.AsAbsolute(GetArea(), GetParentPixelSize());

            // get size of content
            var sz = GetContentSize();

            // calculate the full size with the frame accounted for and resize the window to this
            sz.Width  += wndArea.Width - renderArea.Width;
            sz.Height += wndArea.Height - renderArea.Height;
            SetSize(new USize(UDim.Absolute(sz.Width), UDim.Absolute(sz.Height)));
        }
예제 #10
0
        public override Sizef GetTextSize()
        {
            var w  = (Tooltip)Window;
            var sz = w.GetTextSizeImpl();

            // get WidgetLookFeel for the assigned look.
            var wlf = GetLookNFeel();

            var textArea = wlf.GetNamedArea("TextArea").GetArea().GetPixelRect(w);
            var wndArea  = CoordConverter.AsAbsolute(w.GetArea(), w.GetParentPixelSize());

            sz.Width  = CoordConverter.AlignToPixels(sz.Width + wndArea.Width - textArea.Width);
            sz.Height = CoordConverter.AlignToPixels(sz.Height + wndArea.Height - textArea.Height);
            return(sz);
        }
예제 #11
0
        /// <summary>
        /// Return the current extents of the attached content.
        /// </summary>
        /// <returns>
        /// Rect object that describes the pixel extents of the attached
        /// child windows.  This is effectively the smallest bounding box
        /// that could contain all the attached windows.
        /// </returns>
        public Rectf GetChildExtentsArea()
        {
            var extents = Rectf.Zero;

            var childCount = GetChildCount();

            if (childCount == 0)
            {
                return(extents);
            }

            for (var i = 0; i < childCount; ++i)
            {
                var wnd  = GetChildAtIdx(i);
                var area = new Rectf(CoordConverter.AsAbsolute(wnd.GetPosition(), d_pixelSize), wnd.GetPixelSize());

                if (wnd.GetHorizontalAlignment() == HorizontalAlignment.Centre)
                {
                    area.Position = area.Position - new Lunatics.Mathematics.Vector2(area.Width * 0.5f - d_pixelSize.Width * 0.5f, 0.0f);
                }
                if (wnd.GetVerticalAlignment() == VerticalAlignment.Centre)
                {
                    area.Position = area.Position - new Lunatics.Mathematics.Vector2(0.0f, area.Height * 0.5f - d_pixelSize.Height * 0.5f);
                }

                if (area.d_min.X < extents.d_min.X)
                {
                    extents.d_min.X = area.d_min.X;
                }

                if (area.d_min.Y < extents.d_min.Y)
                {
                    extents.d_min.Y = area.d_min.Y;
                }

                if (area.d_max.X > extents.d_max.X)
                {
                    extents.d_max.X = area.d_max.X;
                }

                if (area.d_max.Y > extents.d_max.Y)
                {
                    extents.d_max.Y = area.d_max.Y;
                }
            }

            return(extents);
        }
예제 #12
0
        /// <summary>
        /// move the window's bottom edge by 'delta'.
        /// The rest of the window does not move, thus this changes the size of the Window.
        /// </summary>
        /// <param name="delta">
        /// float value that specifies the amount to move the window edge, and in which direction.
        /// Positive values make window larger.
        /// </param>
        /// <param name="outArea"></param>
        /// <returns></returns>
        protected bool MoveBottomEdge(float delta, ref URect outArea)
        {
            // store this so we can work out how much size actually changed
            var orgHeight = d_pixelSize.Height;

            // ensure that we only size to the set constraints.
            //
            // NB: We are required to do this here due to our virtually unique sizing nature; the
            // normal system for limiting the window size is unable to supply the information we
            // require for updating our internal state used to manage the dragging, etc.
            var maxHeight = CoordConverter.AsAbsolute(d_maxSize.d_height, GetRootContainerSize().Height);
            var minHeight = CoordConverter.AsAbsolute(d_minSize.d_height, GetRootContainerSize().Height);
            var newHeight = orgHeight + delta;

            if (Math.Abs(maxHeight - 0.0f) > float.Epsilon && newHeight > maxHeight)
            {
                delta = maxHeight - orgHeight;
            }
            else if (newHeight < minHeight)
            {
                delta = minHeight - orgHeight;
            }

            // ensure adjustment will be whole pixel
            var adjustment = /*PixelAligned(*/ delta /*)*/;

            outArea.d_max.d_y.d_offset += adjustment;

            if (d_verticalAlignment == VerticalAlignment.Bottom)
            {
                outArea.d_max.d_y.d_offset += adjustment;
                outArea.d_min.d_y.d_offset += adjustment;
            }
            else if (d_verticalAlignment == VerticalAlignment.Centre)
            {
                outArea.d_max.d_y.d_offset += adjustment * 0.5f;
                outArea.d_min.d_y.d_offset += adjustment * 0.5f;
            }

            // move the dragging point so mouse remains 'attached' to edge of window
            _dragPoint.Y += adjustment;

            return(d_verticalAlignment == VerticalAlignment.Bottom);
        }
예제 #13
0
        public void ResizeViewToContent(ItemView view, bool fitWidth, bool fitHeight)
        {
            var totalArea   = view.GetUnclippedOuterRect().Get();
            var contentArea = GetViewRenderArea(view,
                                                !fitWidth && view.GetHorzScrollbar().IsVisible(),
                                                !fitHeight && view.GetVertScrollbar().IsVisible());
            var withScrollContentArea = GetViewRenderArea(view, true, true);

            var frameSize           = totalArea.Size - contentArea.Size;
            var withScrollFrameSize = totalArea.Size - withScrollContentArea.Size;
            var contentSize         = new Sizef(view.GetRenderedMaxWidth(), view.GetRenderedTotalHeight());

            var parentSize = view.GetParentPixelSize();
            var maxSize    =
                new Sizef(parentSize.Width - CoordConverter.AsAbsolute(view.GetXPosition(), parentSize.Width),
                          parentSize.Height - CoordConverter.AsAbsolute(view.GetYPosition(), parentSize.Height));

            var requiredSize = frameSize + contentSize + new Sizef(1, 1);

            if (fitHeight && requiredSize.Height > maxSize.Height)
            {
                requiredSize.Height = maxSize.Height;
                requiredSize.Width  = Math.Min(maxSize.Width,
                                               requiredSize.Width - frameSize.Width + withScrollFrameSize.Width);
            }

            if (fitWidth && requiredSize.Width > maxSize.Width)
            {
                requiredSize.Width  = maxSize.Width;
                requiredSize.Height = Math.Min(maxSize.Height,
                                               requiredSize.Height - frameSize.Height + withScrollFrameSize.Height);
            }

            if (fitHeight)
            {
                view.SetHeight(new UDim(0, requiredSize.Height));
            }

            if (fitWidth)
            {
                view.SetWidth(new UDim(0, requiredSize.Width));
            }
        }
예제 #14
0
        /// <summary>
        /// Scroll the horizontal list position if needed to ensure that the
        /// ItemEntry \a item is, if possible, fully visible witin the
        /// ScrolledItemListBase viewable area.
        /// </summary>
        /// <param name="item">
        /// const reference to an ItemEntry attached to this ScrolledItemListBase
        /// that should be made visible in the view area.
        /// </param>
        public void EnsureItemIsVisibleHorz(ItemEntry item)
        {
            var renderArea = GetItemRenderArea();
            var h          = GetHorzScrollbar();
            var currPos    = h.GetScrollPosition();

            var left  = CoordConverter.AsAbsolute(item.GetXPosition(), GetPixelSize().Width) - currPos;
            var right = left + item.GetItemPixelSize().Width;

            // if left is left of the view area, or if item too big, scroll item to left
            if ((left < renderArea.d_min.X) || ((right - left) > renderArea.Width))
            {
                h.SetScrollPosition(currPos + left);
            }
            // if right is right of the view area, scroll item to right of list
            else if (right >= renderArea.d_max.X)
            {
                h.SetScrollPosition(currPos + right - renderArea.Width);
            }
        }
예제 #15
0
        /// <summary>
        /// Scroll the vertical list position if needed to ensure that the ItemEntry
        /// \a item is, if possible,  fully visible witin the ScrolledItemListBase
        /// viewable area.
        /// </summary>
        /// <param name="item">
        /// const reference to an ItemEntry attached to this ScrolledItemListBase
        /// that should be made visible in the view area.
        /// </param>
        public void EnsureItemIsVisibleVert(ItemEntry item)
        {
            var renderArea = GetItemRenderArea();
            var v          = GetVertScrollbar();
            var currPos    = v.GetScrollPosition();

            var top    = CoordConverter.AsAbsolute(item.GetYPosition(), GetPixelSize().Height) - currPos;
            var bottom = top + item.GetItemPixelSize().Height;

            // if top is above the view area, or if item is too big, scroll item to top
            if ((top < renderArea.d_min.Y) || ((bottom - top) > renderArea.Height))
            {
                v.SetScrollPosition(currPos + top);
            }
            // if bottom is below the view area, scroll item to bottom of list
            else if (bottom >= renderArea.d_max.Y)
            {
                v.SetScrollPosition(currPos + bottom - renderArea.Height);
            }
        }
예제 #16
0
        /// <summary>
        /// move the window's top edge by 'delta'.
        /// The rest of the window does not move, thus this changes the size of the Window.
        /// </summary>
        /// <param name="delta">
        /// float value that specifies the amount to move the window edge, and in which direction.
        /// Positive values make window smaller.
        /// </param>
        /// <param name="outArea"></param>
        /// <returns></returns>
        protected bool MoveTopEdge(float delta, ref URect outArea)
        {
            var orgHeight = d_pixelSize.Height;

            // ensure that we only size to the set constraints.
            //
            // NB: We are required to do this here due to our virtually unique sizing nature; the
            // normal system for limiting the window size is unable to supply the information we
            // require for updating our internal state used to manage the dragging, etc.
            float maxHeight = CoordConverter.AsAbsolute(d_maxSize.d_height, GetRootContainerSize().Height);
            float minHeight = CoordConverter.AsAbsolute(d_minSize.d_height, GetRootContainerSize().Height);
            float newHeight = orgHeight - delta;

            if (Math.Abs(maxHeight - 0.0f) > float.Epsilon && newHeight > maxHeight)
            {
                delta = orgHeight - maxHeight;
            }
            else if (newHeight < minHeight)
            {
                delta = orgHeight - minHeight;
            }

            // ensure adjustment will be whole pixel
            float adjustment = /*PixelAligned(*/ delta /*)*/;

            if (d_verticalAlignment == VerticalAlignment.Bottom)
            {
                outArea.d_max.d_y.d_offset -= adjustment;
            }
            else if (d_verticalAlignment == VerticalAlignment.Centre)
            {
                outArea.d_max.d_y.d_offset -= adjustment * 0.5f;
                outArea.d_min.d_y.d_offset += adjustment * 0.5f;
            }
            else
            {
                outArea.d_min.d_y.d_offset += adjustment;
            }

            return(d_verticalAlignment == VerticalAlignment.Top);
        }
예제 #17
0
        public override float GetValueFromThumb()
        {
            var w    = (Scrollbar)Window;
            var wlf  = GetLookNFeel();
            var area = wlf.GetNamedArea("ThumbTrackArea").GetArea().GetPixelRect(w);

            var theThumb  = w.GetThumb();
            var posExtent = w.GetDocumentSize() - w.GetPageSize();

            if (_vertical)
            {
                var slideExtent = area.Height - theThumb.GetPixelSize().Height;
                return((CoordConverter.AsAbsolute(theThumb.GetYPosition(), w.GetPixelSize().Height) - area.Top) /
                       (slideExtent / posExtent));
            }
            else
            {
                var slideExtent = area.Width - theThumb.GetPixelSize().Width;
                return((CoordConverter.AsAbsolute(theThumb.GetXPosition(), w.GetPixelSize().Width) - area.Left) /
                       (slideExtent / posExtent));
            }
        }
예제 #18
0
        /// <summary>
        /// Update state for drag sizing.
        /// </summary>
        /// <param name="localMouse">
        /// Mouse position as a pixel offset from the top-left corner of this window.
        /// </param>
        protected void DoDragSizing(Lunatics.Mathematics.Vector2 localMouse)
        {
            var delta = localMouse.X - _dragPoint.X;
            // store this so we can work out how much size actually changed
            var orgWidth = d_pixelSize.Width;

            // ensure that we only size to the set constraints.
            //
            // NB: We are required to do this here due to our virtually unique sizing nature; the
            // normal system for limiting the window size is unable to supply the information we
            // require for updating our internal state used to manage the dragging, etc.
            var maxWidth = CoordConverter.AsAbsolute(d_maxSize.d_width, GetRootContainerSize().Width);
            var minWidth = CoordConverter.AsAbsolute(d_minSize.d_width, GetRootContainerSize().Width);
            var newWidth = orgWidth + delta;

            if (maxWidth != 0.0f && newWidth > maxWidth)
            {
                delta = maxWidth - orgWidth;
            }
            else if (newWidth < minWidth)
            {
                delta = minWidth - orgWidth;
            }

            // update segment area rect
            // URGENT FIXME: The pixel alignment will be done automatically again, right? Why is it done here? setArea_impl will do it!
            var area = new URect(d_area.d_min.d_x, d_area.d_min.d_y,
                                 d_area.d_max.d_x + new UDim(0, /*PixelAligned(*/ delta /*)*/), d_area.d_max.d_y);

            SetAreaImpl(area.d_min, area.Size);

            // move the dragging point so mouse remains 'attached' to edge of segment
            _dragPoint.X += d_pixelSize.Width - orgWidth;

            OnSegmentSized(new WindowEventArgs(this));
        }
예제 #19
0
        // overridden from base class.
        public override void CreateRenderGeometry()
        {
            var w             = (MultiColumnList)Window;
            var header        = w.GetListHeader();
            var vertScrollbar = w.GetVertScrollbar();
            var horzScrollbar = w.GetHorzScrollbar();

            // render general stuff before we handle the items
            CacheListboxBaseImagery();

            //
            // Render list items
            //
            Lunatics.Mathematics.Vector3 itemPos;
            var itemRect = new Rectf();

            // calculate position of area we have to render into
            var itemsArea = GetListRenderArea();

            // set up initial positional details for items
            itemPos.Y = itemsArea.Top - vertScrollbar.GetScrollPosition();
            itemPos.Z = 0.0f;

            var alpha = w.GetEffectiveAlpha();

            // loop through the items
            for (var i = 0; i < w.GetRowCount(); ++i)
            {
                // set initial x position for this row.
                itemPos.X = itemsArea.Left - horzScrollbar.GetScrollPosition();

                // calculate height for this row.
                Sizef itemSize;
                itemSize.Height = w.GetHighestRowItemHeight(i);

                // loop through the columns in this row
                for (var j = 0; j < w.GetColumnCount(); ++j)
                {
                    // allow item to use full width of the column
                    itemSize.Width = CoordConverter.AsAbsolute(header.GetColumnWidth(j), header.GetPixelSize().Width);

                    var item = w.GetItemAtGridReference(new MCLGridRef(i, j));

                    // is the item for this column set?
                    if (item != null)
                    {
                        // calculate destination area for this item.
                        itemRect.Left = itemPos.X;
                        itemRect.Top  = itemPos.Y;
                        itemRect.Size = itemSize;
                        var itemClipper = itemRect.GetIntersection(itemsArea);

                        // skip this item if totally clipped
                        if (itemClipper.Width == 0f)
                        {
                            itemPos.X += itemSize.Width;
                            continue;
                        }

                        // draw this item
                        item.CreateRenderGeometry(itemRect, alpha, itemClipper);
                    }

                    // update position for next column.
                    itemPos.X += itemSize.Width;
                }

                // update position ready for next row
                itemPos.Y += itemSize.Height;
            }
        }