Page 1 of 1

Tree

Posted: Fri Jul 11, 2008 19:56
by dewyatt
This is already known.
The tree control is really lacking.
I read removeItem can't remove child items.
I also found that getSelectedCount() doesn't seem to count child items.
Plus, the 'expand' buttons seem to need their hit area increased. That one is probably easily fixed though.

And I know CE has said he isn't really a fan of the current tree implementation.

I could really use a tree control.
I'm near attempting to write it myself but I don't have a lot of experience with recursion or CEGUI's internal code.

I don't think anyone is going to be working on this anytime soon.
But, if anyone can give me some pointers to alternatives or advice on fixing the current implementation, that could help.

Posted: Sat Jul 12, 2008 00:50
by dewyatt
For anyone who needs getSelectedCount() to work as expected (with children), this works perfectly:

Code: Select all

CEGUI::TreeItem* Item = NULL;
unsigned int Count = 0;
for (Item = mStart_Tree->getFirstSelectedItem(); Item; ++Count)
{
   Item = mStart_Tree->getNextSelected(Item);
}

Posted: Sat Jul 12, 2008 05:16
by dewyatt
Also, this public function of TreeItem:
LBItemList & getItemList()

Uses a private typedef. Which can't be right.

Re: Tree

Posted: Sat Jul 12, 2008 06:33
by CrazyEddie
dewyatt wrote:I don't think anyone is going to be working on this anytime soon.

Don't be so sure! While I have no immediate plans, if 'other things' go well, and I have time, it could happen ;)

CE

Re: Tree

Posted: Sat Jul 12, 2008 07:26
by dewyatt
CrazyEddie wrote:
dewyatt wrote:I don't think anyone is going to be working on this anytime soon.

Don't be so sure! While I have no immediate plans, if 'other things' go well, and I have time, it could happen ;)

CE

Well that would be awesome!
I'm actually getting along nicely with the current Tree implementation since I realized the getFirstSelectedItem()/etc functions do their job (and the job of getSelectedCount()).
And luckily I don't currently need to remove child items. Looking at the tree code though, this wouldn't be difficult anyways.

Anyways, I love CEGUI. Tree or no Tree it has saved me more time than I can imagine.

Posted: Wed Mar 04, 2009 03:47
by ttom
Hi CE
I do some code on the tree about the keyboard, let the tree can use the keyboard to do the up and down
In the Tree.h

Code: Select all

virtual void onKeyDown(KeyEventArgs& e);
//below is in the private
Point getTreeItemPosition(const TreeItem *treeItem);

In the Tree.cpp

Code: Select all

void Tree::onKeyDown( KeyEventArgs& e )
{
   // base class processing
   Window::onKeyDown(e);
   if (isActive())
   {
      switch (e.scancode)
      {
      case Key::ArrowDown:
         handleItemDownUp(e.sysKeys,true);
         break;
      case Key::ArrowUp:
         handleItemDownUp(e.sysKeys,false);
         break;
      default:
         return;   
      }
      e.handled = true;
   }//if (isActive())
}
//2009-03-04
void Tree::handleItemDownUp(uint sysKeys, bool down/*=true*/ )
{
   bool modified = false;
   TreeItem* lastselectitem = getLastSelectedItem();
   if (lastselectitem != 0)
   {
      modified = true;
      //get the current position
      Point localPos(getTreeItemPosition(lastselectitem));
      Size itemsize =  lastselectitem->getPixelSize();
      if (down)
      {
         localPos.d_y += itemsize.d_height;
      }else{
         localPos.d_y -= itemsize.d_height;
      }
      TreeItem* nextitem = getItemAtPoint(localPos);
      if (nextitem != 0)
      {
         TreeEventArgs args(this);
         args.treeItem = nextitem;
         setItemSelectState(nextitem,true);
      }

   }else{
      // clear old selections if no control key is pressed or if multi-select is off
      if (!(sysKeys & Control) || !d_multiselect)
      {
         if (clearAllSelections_impl())
         {
            // Changes to the selections were actually made
            TreeEventArgs args(this);
            args.treeItem = lastselectitem;
            onSelectionChanged(args);
         }
      }
   }
}
Point Tree::getTreeItemPosition( const TreeItem *treeItem )
{
   float x = this->getXPosition().d_offset;
   float y = this->getYPosition().d_offset;
   Point Pos(x,y) ;
   float bottom=0;
   float top = 0;
   float itemHeight = treeItem->getPixelSize().d_height;
   float itemWidth = getWidestItemWidth();
   if (!getHeightToItemInList(d_listItems, treeItem, 0, &top))
   {
      throw InvalidRequestException((utf8*)"Tree::getTreeItemPosition - treeItem wasn't found by getHeightToItemInList");
      // treeItem wasn't found by getHeightToItemInList
   }

   // calculate height to bottom of item
   bottom = top ;

   // account for current scrollbar value
   float currPos = d_vertScrollbar->getScrollPosition();
   top      -= currPos;
   bottom   -= currPos;
   //get render height
   float listHeight = getTreeRenderArea().getHeight();
   // if top is above the view area, or if item is too big to fit
   if ((top-itemHeight) < 0.0f )
   {
      // scroll top of item to top of box.
      //d_vertScrollbar->setScrollPosition(currPos + top);
      d_vertScrollbar->setScrollPosition(d_vertScrollbar->getScrollPosition() - d_vertScrollbar->getStepSize() );
   }
   // if bottom is below the view area
   else if ((bottom+itemHeight) >= listHeight)
   {
      // position bottom of item at the bottom of the list
      d_vertScrollbar->setScrollPosition(d_vertScrollbar->getScrollPosition() + d_vertScrollbar->getStepSize() );
   }

   Pos.d_x+=itemWidth/2;
   Pos.d_y+=bottom+1;
   return Pos;
}

Posted: Wed Mar 04, 2009 09:59
by CrazyEddie
Hi,

Thanks for posting the code, perhaps I might convince you to put it in an article on the Wiki?

- or -

If you'd like us to consider it for inclusion into the code, could you attach the changes as a unified diff on the mantis tracker. Although this requirement is not written anywhere at the moment, it is a requirement(!), since it makes it so much easier to see what's changed.

While I don't like the existing Tree, I'm happy to patch it :)

CE.

Posted: Thu Mar 05, 2009 01:53
by ttom
Hi C.E.
thanks to replay. I like it to put code on the base code, but I don't know how to do the unified diff and path file. I will check and study the mantis tracker to see the everyone how to do this.
thanks to CrazyEddie again.
ttom

Posted: Thu Mar 05, 2009 09:49
by CrazyEddie
Hi,

[Edit]
I see you already added the patch to mantis - thanks :)

I'll leave this post here in case others find it useful :P
[/Edit]


How you generate a patch depends upon your system and how you got your CEGUI code ;)

If you have the code from SVN, you can generate a patch by typing something as simple as:

Code: Select all

svn diff

which can be redirected to a file.

If you're on windows, and are using TortoiseSVN (or another GUI client), you can usually right-click on the root folder icon, and select 'create patch...' or similar from the context menu.

If you're using the released source package, you should backup the original files first, then use the 'diff' command to generate the difference between the original file and the modified files. For example:

Code: Select all

diff -u CEGUITree.cpp.org CEGUITree.cpp

The '-u' option here is important because it ensures the generated output is in the unified format.

HTH

CE.