private KTreeNodeMeasurements(KTreeNodeMeasurements orig, int x, int y)
        {
            this._node          = orig._node;
            this._options       = orig._options;
            this._paddingOveral = orig._paddingOveral;
            this._sizes         = (Size[])orig._sizes.Clone();

            // The node rectangle is the sum of the widths, and the maximum height (plus padding).
            // TODO: special handling for control part, make that fit with e.g. a Dock option?
            _nodeRect = new Rectangle(orig._nodeRect.X + x, y + orig._nodeRect.Y,
                                      _sizes.Select((i) => i.Width).Sum() + _paddingOveral.Horizontal,
                                      _sizes.Select((i) => i.Height).Max() + _paddingOveral.Vertical);

            for (int i = 0; i < (int)Part.None; ++i)
            {
                _paddingInternal[i] = new Padding();

                // Align any parts whose height does not match the total height
                if (_sizes[i].Height != InnerRect.Height)
                {
                    _paddingInternal[i].Bottom = (InnerRect.Height - _sizes[i].Height) / 2;
                    _paddingInternal[i].Top    = (InnerRect.Height - _sizes[i].Height) - _paddingInternal[i].Bottom;

                    // Quick hack to make sure checkboxes are properly aligned, make the rect square again
                    // TODO: use padding/dock modes for this
                    if (i == (int)Part.CheckBox && !_sizes[i].IsEmpty && _sizes[i].IsSquare())
                    {
                        _paddingInternal[i].Left  = _paddingInternal[i].Bottom;
                        _paddingInternal[i].Right = _paddingInternal[i].Top;
                    }
                }
            }
        }
Beispiel #2
0
        protected KTreeNodeMeasurements GetNodeSize(Graphics graphics, KTreeNode node)
        {
            KTreeNodeMeasurements dimension = new KTreeNodeMeasurements(node, _tree);

            // Expander
            dimension[KTreeNodeMeasurements.Part.Expander] = GetExpanderSize(graphics, node);

            // Checkbox
            if (node.Owner.CheckManager != null && node.HasCheckBox)
            {
                dimension[KTreeNodeMeasurements.Part.CheckBox] = CheckBoxRenderer.GetGlyphSize(graphics, CheckBoxState.CheckedNormal);
            }

            // Image
            if (_tree.Images != null)
            {
                // Image size specified by imagelist
                // Scale depending on resolution
                dimension[KTreeNodeMeasurements.Part.Image] = _tree.Images.ImageSize.ScaleDpi(graphics);
            }

            // Text size
            dimension[KTreeNodeMeasurements.Part.Text] = TextRenderer.MeasureText(graphics, node.Text, _tree.Font, Size.Empty, TEXT_FLAGS);

            // Control
            if (node.Control != null)
            {
                dimension[KTreeNodeMeasurements.Part.Control] = node.Control.PreferredSize;
            }

            return(dimension);
        }
Beispiel #3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="graphics">The graphics to render into</param>
        /// <param name="node">The node</param>
        /// <param name="scrollOffset">The current scrollbar offset</param>
        /// <param name="highlight">If not null, the part of the node that is highlighted. May be Part.None to indicate the row is
        /// highlighted, but not a specific part</param>
        public void RenderNode(Graphics graphics, KTreeNode node, Point scrollOffset, KTreeNodeMeasurements.Part?highlight)
        {
            // Make sure the node has been measured
            if (node.EffectiveDimension == null)
            {
                MeasureNode(graphics, node);
            }

            KTreeNodeMeasurements dims = node.EffectiveDimension.Offset(-scrollOffset.X, -scrollOffset.Y);

            Rectangle containerRect = dims.NodeRect;

            containerRect.X     = _clientRect.X;
            containerRect.Width = Math.Max(_totalRect.Width, _clientRect.Width);
            // Overlap the rectangle with the control border, to prevent duplicate lines
            containerRect = containerRect.Expand(new Padding(_tree.BorderThickness));

            // Selection background
            RenderNodeOutline(graphics, node, _tree.FullRowSelect ? containerRect : dims.NodeRect, highlight);

            // Expander
            if (node.ChildLoader.NeedsExpander)
            {
                RenderNodeExpander(graphics, node, dims.GetPartRect(KTreeNodeMeasurements.Part.Expander, true), highlight);
            }

            // Checkbox
            if (_tree.CheckManager != null && node.HasCheckBox)
            {
                RenderCheckBox(graphics, node, dims.GetPartRect(KTreeNodeMeasurements.Part.CheckBox, true), highlight);
            }

            // Images
            if (_tree.Images != null && node.ImageIndex.HasValue && node.ImageIndex >= 0 && node.ImageIndex < _tree.Images.Images.Count)
            {
                Rectangle imageRect = dims.GetPartRect(KTreeNodeMeasurements.Part.Image, true);
                // TODO: if the rectangle is larger than the image, this probably leads to upscaling.
                //       if the imagelist stores high-res icons as 16x16, that throws away resolution.
                //       make a custom image list to handle this? That could also handle scaling automatically
                Image image = _tree.Images.Images[node.ImageIndex.Value];
                graphics.DrawImage(image, imageRect.X, imageRect.Y, imageRect.Width, imageRect.Height);
            }

            // Text
            RenderNodeText(graphics, node, dims.GetPartRect(KTreeNodeMeasurements.Part.Text, true), highlight);

            // Control
            if (node.Control != null)
            {
                node.Control.Bounds = dims.GetPartRect(KTreeNodeMeasurements.Part.Control, true);
            }
        }
Beispiel #4
0
        internal KTreeNodeMeasurements MeasureNode(Graphics graphics, KTreeNode node)
        {
            // Determine the row rectangle
            KTreeNodeMeasurements dims = GetNodeSize(graphics, node).Offset(_totalRect.X, _totalRect.Height);

            node.EffectiveDimension = dims;

            // Set up for the next node
            _totalRect.Height += dims.NodeRect.Height;
            _totalRect.Width   = Math.Max(_totalRect.Right, dims.NodeRect.Right) - _totalRect.X;

            return(dims);
        }