Sunday, March 18, 2012

QML Improved Tree View

I added some styling to the tree view exercise, so it looks better overall. A little change to the ListView layout - there is now the separation line between the items, which is just a rectangle with the height of 2. Additionally, I do a couple other things when the selected item changes, by hooking to the onFocusChanged event and checking in the delegate if the item is selected: I toggle the transparency first, so that the highlight color is visible, but also when the selection is lost, the item is returned to its background color. Also, I invert the color of the item text (to white when the item is selected).

// ListView item layout
Rectangle{
id: listItemRect
anchors.fill: parent
color: "#E2E3E4"

Rectangle{ //dividing line
height: 2
width: parent.width

anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right

color: "#AFADB3"
}

Rectangle{

height: parent.height - 2
width: parent.width
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
color: "transparent"
...
}
}
//set text color to white if the item is selected.    
onFocusChanged: {
if(ListView.view.currentIndex == index)
{
listItemRect.color = "transparent";
textDelegate.color = "white";
}
else
{
listItemRect.color = "#E2E3E4";
textDelegate.color = "black";
}
}

Another addition is the navigation bar on the top, so the user knows where in the document structure he is currently positioned. The arrows effect is achieved by simply adding some "help" images that are toggled and their visibility is changed as required by calling the setVisibility function from outside. Navigation bar itself responds to clicks on the items, bringing the user back to the position in the document structure according to the element being clicked.

Here's how the improved tree view looks like:

Just loaded

Last level in the tree

Navigation bar modifications in main.qml and navigation bar code:

//added a navigation bar in NavigationBar.qml
Rectangle {
id:main

//change visibility of the navigation bar elements
function setVisibility()
{
navigationRect.hideRect(2, false)

if(level == 0)
{
navigationRect.hideRect(1, false)
backButton.visible = false;
}
else
{
navigationRect.hideRect(1, true)

if(level == 1)
{
navigationRect.setText(0, level0Name);
}
if(level == 2)
{
navigationRect.hideRect(2, true)
}
}
}
...

NavigationBar{
id:navigationRect
}
}
//Navigation bar code

import QtQuick 1.0

Rectangle{
id: navigationRect
height: 50
width: parent.width
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.topMargin: marginValue
anchors.leftMargin: marginValue
anchors.rightMargin: marginValue

function setText(rect, text)
{
var texts = [level0Text, level1Text, level2Text];
texts[rect].text = text;
}

function hideRect(rect, hide)
{
var rects = [level0Rect, level1Rect, level2Rect];
var helps = [level0Help, level1Help, level2Help];
rects[rect].visible = hide;
helps[rect].visible = hide;

if(rect > 0)
{
hide? helps[rect-1].children[0].source = "icons/selected_black.png" : helps[rect-1].children[0].source = "icons/selected_black_half.png"
}
if(rect == 2)
{
hide? helps[rect].children[0].source = "icons/selected_black_half.png" : helps[rect].children[0].source = ""
}
}

Component.onCompleted: {
level1Rect.visible = false;
level2Rect.visible = false;
level2Rect.visible = false;
level2Help.visible = false;
}

Rectangle{
id: level0Rect
width: parent.width*4/15
height: parent.height
anchors.left: parent.left
anchors.top: parent.top
color: "black"

Text{
id: level0Text
anchors.centerIn: parent
color: "white"
text: level0Label
font.pixelSize: 10
}

MouseArea{
id: level0Mouse
anchors.fill: parent

onClicked: {
level = 0;
setQueries();
}
}
}

Rectangle{
id: level0Help
width: parent.width/15
height: parent.height
anchors.left: level0Rect.right
anchors.top: parent.top

Image{
anchors.fill: parent
}
}

Rectangle{
id: level1Rect
width: parent.width*4/15
height: parent.height
anchors.left: level0Help.right
anchors.top: parent.top
color: "black"

Text{
id: level1Text
color: "white"
anchors.centerIn: parent
text: level1Label
font.pixelSize: 10
}

MouseArea{
id: level1Mouse
anchors.fill: parent

onClicked: {
level = 1;
setQueries();
}
}
}

Rectangle{
id: level1Help
width: parent.width/15
height: parent.height
anchors.left: level1Rect.right
anchors.top: parent.top

Image{
anchors.fill: parent
}
}

Rectangle{
id: level2Rect
width: parent.width*4/15
height: parent.height
anchors.left: level1Help.right
anchors.top: parent.top
color: "black"

Text{
id: level2Text
color: "white"
anchors.centerIn: parent
text: level2Label
font.pixelSize: 10
}

MouseArea{
id: level2Mouse
anchors.fill: parent
}
}

Rectangle{
id: level2Help
width: parent.width/15
height: parent.height
anchors.left: level2Rect.right
anchors.top: parent.top

Image{
anchors.fill: parent
}
}
}
by . Also posted on my website

No comments: