TreeViewItem line drawing


#1

Hello,

In one of our tools, the lines drawn on the main TreeView must be different colours to help indicate state/relationship information. To achieve this, I had to modify the TreeViewItem code slightly (and then promptly forgot about it). The changes simply make it possible to override the line drawing per item. Now that I’m finally updating that tool to use the Juce modules, I’ve found I need to re-apply my changes, so thought I’d post them here in case you might put similar functionality into the library.

Here’s an example of what I needed it for:

Below are the small changes I had to make to support this…

All it consists of is two new virtual functions (one for vertical, one for horizontal), and replacement of the drawLine calls in paintRecursively() for these.

TreeViewItem.cpp

// New virtual function
void TreeViewItem::drawHorizontalConnectingLine (Graphics& g, const Line<float>& line)
{
	g.setColour (ownerView->findColour (TreeView::linesColourId));
	g.drawLine(line);
}

// New virtual function
void TreeViewItem::drawVerticalConnectingLine (Graphics& g, const Line<float>& line, TreeViewItem* parent)
{
	g.setColour (ownerView->findColour (TreeView::linesColourId));
	g.drawLine(line);
}

void TreeViewItem::paintRecursively (Graphics& g, int width)
{

    // ...

    if (depth >= 0 && ownerView->openCloseButtonsVisible)
    {
        float x = (depth + 0.5f) * indentWidth;

        if (parentItem != nullptr && parentItem->drawLinesInside)
	{
		//g.drawLine (x, 0, x, isLastOfSiblings() ? halfH : (float) itemHeight);
		Line<float> line(x,0,x,isLastOfSiblings() ? halfH : (float) itemHeight);
		drawVerticalConnectingLine (g, line, nullptr);
	}

        if ((parentItem != nullptr && parentItem->drawLinesInside)
             || (parentItem == nullptr && drawLinesInside))
	{
		//g.drawLine (x, halfH, x + indentWidth / 2, halfH);
		Line<float> line (x, halfH, x + indentWidth / 2, halfH);
		drawHorizontalConnectingLine (g, line);
	}

        {
            TreeViewItem* p = parentItem;
            int d = depth;

            while (p != nullptr && --d >= 0)
            {
                x -= (float) indentWidth;

                if ((p->parentItem == nullptr || p->parentItem->drawLinesInside)
                     && ! p->isLastOfSiblings())
                {
	                //g.drawLine (x, 0, x, (float) itemHeight);
			Line<float> line (x, 0, x, (float) itemHeight);
			drawVerticalConnectingLine (g, line, p); // this is a bypass line, so we provide p; it's more an indicator for the parent item than this one
                }

                p = p->parentItem;
            }
        }

       // ...
}

It’d probably make more sense to use the ‘parent’ itself for the bypass line, but I can’t remember if there might have been a reason for me not doing so at the time (or if it was just because I didn’t think of it)… but yeah. That’s what I did. It’d be nice if I didn’t have to keep merging the changes back in :slight_smile:


#2

Nice! I’ll add that. I do think it makes more sense to just call the relevant parent to draw the bypass line, so I’ll implement it that way… Can’t think of a reason not to (it shouldn’t ever be necessary to know about the child that the line is bypassing), but let me know if you do think of something.


#3

Yeah, I think I initially just implemented it without considering what the line was for; I must have just gone with the first idea to fix it that popped into my head when I saw that the colour was wrong on those bits :slight_smile: [it was* a pretty busy time!]. I only realised it was a strange approach when merging the changes back in :smiley:

[*as always]


#4

Checked-in now, see what you reckon…


#5

alas, I don’t have GIT stuff set up on this work PC (seems like just about the only version control system we don’t use!) - for now I’m making do with the modules retrieved by the introjucer. Hopefully I’ll get a moment to try it out a little later though, cheers!


#6

I just re-checked my subclass’ implementation of the vertical line drawing function, and indeed it wasn’t doing anything special for bypass lines [other than getting the required colour from the parent instead of itself]. It was purely haste rather than design :slight_smile:

If your change looks right for a normal tree, I’m sure it’ll be suitable for my needs too!


#7

Righto. An introjucer module update is overdue anyway, I’ll do one later. BTW, if you get a moment on skype, I wanted to ask you something offline…


#8

Just a bit of info, you can download zip packages of commits from GitHub, just click on the Zip button from the main page so you don’t need Git installed. Can be quite useful for small projects that aren’t under SCM.


#9

That’s a really cool looking tree view! It’s too bad that the text looks terrible…split stems all over the place…no hinting…

I see the same problem in the IntroJucer tree view.