Issues with Enhanced wxTreeListCtrl

Are you writing your own components and need help with how to set them up or have questions about the components you are deriving from ? Ask them here.
Post Reply
metalogic
Super wx Problem Solver
Super wx Problem Solver
Posts: 307
Joined: Fri Oct 08, 2004 8:21 am
Location: Area 51
Contact:

Issues with Enhanced wxTreeListCtrl

Post by metalogic »

First of all, thanks a lot Guru for this enhancement.

I'm looking to build upon what you have done and enhance it further. Hopefully you will be interested in collaborating so that we can have a single "enhanced" version. But that will come later, I'm just beginning to do some proof-of-concept.

As I've started playing with this control I've found a few issues. Here is the first batch:

When adding columns using AddColumn, the first column added ends up being last rather than first. The problem appears to be lines 2276-2277. They are not needed and removing them fixes the problem.

When the text is too wide to fit in a column, ellipsis appear but they truncate the string leaving only the first character rather than fitting as much text as possible before the ellipsis. You can see that in your demo by simply shrinking one of the columns just enough so that the last letter doesn't fit.
jmason1182
Earned some good credits
Earned some good credits
Posts: 149
Joined: Fri Dec 14, 2007 3:40 pm
Location: Midland, TX
Contact:

Post by jmason1182 »

OKay, now it's been a few years since this post was continued. But I am experiencing the same issues with this control as they were in 2004....

I need to get the checkbox to show up in column one... so I changed from an original version to the new version so I can use the new features.

Now, I get HDS_HOTTRACK not declared... so i do as mentioned and added the following:


#ifdef __WXMSW__
#define _WIN32_IE 0x0600
#include <commctrl.h>
#endif

Now it sees HDS_HOTTRACK. But now wxGetInstance isn't declared in scope.

Also, I have a number of errors/warnings I'm trying to sift through. I need this to work, so any assistance is appreciated! I'll post updated code once I get this debugged.


warning: int format, float arg (arg 3)
warning: converting to `long int' from `float'
warning: int format, long int arg (arg 2)
warning: int format, float arg (arg 3)
warning: cannot pass objects of non-POD type `class wxString' through `...'; call will abort at runtime

error: `wxGetInstance' was not declared in this scope
warning: unused variable 'bDontFall'
warning: unused variable 'colInfo'
warning: `BeginDrawing' is deprecated (declared at C:/wx/wxWidgets2.8/include/wx/dc.h:392)
warning: `EndDrawing' is deprecated (declared at C:/wx/wxWidgets2.8/include/wx/dc.h:393)
warning: comparison between signed and unsigned integer expressions
warning: comparison between signed and unsigned integer expressions|

error: `wxValidator::wxValidator(const wxValidator&)' is private
error: invalid conversion from `int' to `wxTreeListItemType'


||=== Build finished: 4 errors, 12 warnings ===|
John A. Mason
Midland, TX
jmason1182
Earned some good credits
Earned some good credits
Posts: 149
Joined: Fri Dec 14, 2007 3:40 pm
Location: Midland, TX
Contact:

Post by jmason1182 »

First off, I found a post (http://forums.wxwidgets.org/viewtopic.php?t=2999) that said wxGetInstance is in an undocumented header (and undocumented function)

Code: Select all

ifdef __WXMSW__
     #nclude "wx/msw/private.h"
endif
So that takes care of 1 error.
John A. Mason
Midland, TX
jmason1182
Earned some good credits
Earned some good credits
Posts: 149
Joined: Fri Dec 14, 2007 3:40 pm
Location: Midland, TX
Contact:

Post by jmason1182 »

Second error is the validator private error...

Thanks to phlox81, I just altered the treelistctrl.cpp file with this:

Code: Select all

class wxEditLongValidator : public wxValidator
{
     long *val;
 public:
     wxEditLongValidator(long* val);
     wxEditLongValidator(const  wxEditLongValidator& copy):val(val){};
     wxObject* Clone() const;
     bool TransferFromWindow();
     bool TransferToWindow();
     bool Validate(wxWindow* parent);
};
Now no error there.

Next is a conversion from int to wxTreeListItemType....
John A. Mason
Midland, TX
jmason1182
Earned some good credits
Earned some good credits
Posts: 149
Joined: Fri Dec 14, 2007 3:40 pm
Location: Midland, TX
Contact:

Post by jmason1182 »

And I figured that the intent was to return a wxTreeListItemType that made sense for an incomplete item... which tells me that the 0 needs to be a blank wxTreeListItemType(). ( I could be wrong... guru would know)

This took care of the invalid cast error:

Code: Select all

wxCHECK_MSG (itemId.IsOk(), wxTreeListItemType(), _T("invalid tree item") );
But now that all the errors are gone, I now have an undefined reference:
5916|undefined reference to `wxTreeListMainWindow::SetItemChecked(wxTreeItemId const&, int, bool)'|

SO now to track this one down....
John A. Mason
Midland, TX
jmason1182
Earned some good credits
Earned some good credits
Posts: 149
Joined: Fri Dec 14, 2007 3:40 pm
Location: Midland, TX
Contact:

Post by jmason1182 »

I changed the format strings of some sscanf's and some wxString::Format from %d to %ld and changed the float t to a long int t to get rid of the
warning: int format, float arg (arg 3)
warning: converting to `long int' from `float'
warning: int format, long int arg (arg 2)
warning: int format, float arg (arg 3)
Next, I looked up BeginDrawing and EndDrawing... not only deprecated, but empty. So I just commented them out.

Now I have only 2 errors and no warnings left.


5918|undefined reference to `wxTreeListMainWindow::SetItemChecked(wxTreeItemId const&, int, bool)'
5923|undefined reference to `wxTreeListMainWindow::GetItemChecked(wxTreeItemId const&, int)'



So here goes....
John A. Mason
Midland, TX
jmason1182
Earned some good credits
Earned some good credits
Posts: 149
Joined: Fri Dec 14, 2007 3:40 pm
Location: Midland, TX
Contact:

Post by jmason1182 »

And plain and simply the functions were defined, but not implemented.

SO I added them... they are simple -

Code: Select all


void wxTreeListMainWindow::SetItemChecked (const wxTreeItemId& itemId, const int column, bool checked)
{
    wxCHECK_RET (itemId.IsOk(), _T("invalid tree item"));
    wxClientDC dc (this);
    wxTreeListItem *item = (wxTreeListItem*) itemId.m_pItem;
    item->SetItemChecked(column, checked);
    CalculateSize (item, dc);
    RefreshLine (item);
}

bool wxTreeListMainWindow::GetItemChecked (const wxTreeItemId& itemId, const int column)
{
    wxCHECK_MSG (itemId.IsOk(), false, _T("invalid tree item") );
    wxTreeListItem *item = (wxTreeListItem*) itemId.m_pItem;
    return item->GetItemChecked(column);
}
And now it works... or at least it builds and now I'll post again in a bit after testing the functionality of it.
John A. Mason
Midland, TX
metalogic
Super wx Problem Solver
Super wx Problem Solver
Posts: 307
Joined: Fri Oct 08, 2004 8:21 am
Location: Area 51
Contact:

Re: Issues with Enhanced wxTreeListCtrl

Post by metalogic »

metalogic wrote:When the text is too wide to fit in a column, ellipsis appear but they truncate the string leaving only the first character rather than fitting as much text as possible before the ellipsis.
I got to the bottom of this one.

Line 4128:

Code: Select all

text = MakeShortString(dc,text,col_w-x,0);
Should simply be:

Code: Select all

text = MakeShortString(dc,text,col_w,0);
BTW, guru, if you are around, please chime in or send me a PM. I would like to collaborate if you are interested. If you are not interested I guess I'll do a fork but I'd rather enhance the same control.

Thanks!
rex666
Earned a small fee
Earned a small fee
Posts: 20
Joined: Mon Nov 08, 2004 12:15 am

Re: Issues with Enhanced wxTreeListCtrl

Post by rex666 »

metalogic wrote:I got to the bottom of this one.
This may sound dumb, but is there anywhere I can download the current version of the wxTreeListCtrl files? I went to your website, but the files there are still from last year (the version I am currently using) and there are some issues using it on wxMac (using wxMac 2.6.4 -- yes I'm stuck in a time warp, but I can't update now, or it will push my release date back too far, and everything else is working fine on Windows and Linux, so why fix what ain't broke?)

I want to update to the latest build possible, to see if those issues have been resolved, or to at least be as up-to-date as possible to fix them.

BTW, the issue is a strange refresh issue causing a section of the window to be erased to the background color underneath an open item. It does not happen upon opening up the item, but my program goes through and updates a running time on the top level items, and somewhere in this update of the parent item, it is causing the background to be erased on a portion of the window below and to the right of the open item. I haven't debugged it much further than that yet.

Thanks for your help
-robin
jmason1182
Earned some good credits
Earned some good credits
Posts: 149
Joined: Fri Dec 14, 2007 3:40 pm
Location: Midland, TX
Contact:

Post by jmason1182 »

WHOAH! Quick note... ok... IMPORTANT NOTE:

The wxTreeListCtrl uses the Idle events for some of its updates.

In my app, the refreshing BROKE because I was needing to use the idle events:

wxIdleEvent::SetMode(wxIDLE_PROCESS_SPECIFIED);

And so if you need to use the idle events for anything (like I was doing) DON'T FORGET TO PUT wxWS_EX_PROCESS_IDLE for your frame holding you wxTreeListCtrl (or the control itself I guess) because otherwise you will NOT get a refreshing window!
John A. Mason
Midland, TX
borr_1
Super wx Problem Solver
Super wx Problem Solver
Posts: 362
Joined: Wed Mar 07, 2007 8:10 am
Location: Russia, Shakhty

Post by borr_1 »

Why can't get item from event

Code: Select all

Tree = new wxTreeListCtrl(this,ID_TREE,wxDefaultPosition,wxDefaultSize,
	wxTR_ROW_LINES | wxTR_HAS_BUTTONS | wxTR_HAS_VARIABLE_ROW_HEIGHT | wxTR_FULL_ROW_HIGHLIGHT | wxTR_EDIT_LABELS,
	wxDefaultValidator, _T("ID_TREE"));
Tree->Connect(ID_TREE, wxEVT_COMMAND_TREE_KEY_DOWN, (wxObjectEventFunction)&OrgStruct::OnTreeKeyDown, NULL, this);
	Tree->SetDropTarget(new TreeDropTarget(Tree)); 
	Connect(ID_TREE, wxEVT_COMMAND_TREE_BEGIN_DRAG, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) &OrgStruct::OnDragAvailTree); 
...................
void OrgStruct::OnDragAvailTree(wxTreeEvent&event)
{
  wxTreeItemId nod = event.GetItem();
  if(!nod.IsOk()/*Always false*/)
}

void OrgStruct::OnTreeKeyDown(wxTreeEvent &event)
{
  wxTreeItemId nod = event.GetItem();
  nod.IsOk() /*Always false*/
}
The same code works well for wxTreeCtrl
BuschnicK
Experienced Solver
Experienced Solver
Posts: 80
Joined: Thu Oct 13, 2005 1:30 pm
Contact:

performance of GetNextSibling

Post by BuschnicK »

The documentation states GetNextChild is obsolete and one should prefer GetNextSibling instead. This is very bad advice in my experience. Reason: GetNextSibling doesn't use the cookie value for iterating over the items. It'll instead iterate the whole child array in order to find the item's index (using wxArray::Index) and then increment that. In other words: The runtime behaviour for GetNextSibling is O(n^2) where n is the number of child items. This is _very_ noticeable with big trees, especially since you typically use GetNextSibling to iterate all of them.

Summary: don't trust the documentation on this one. Prefer GetNextChild.

cheers,

Sören
duarteroso
In need of some credit
In need of some credit
Posts: 7
Joined: Tue Jun 22, 2010 7:52 am

Post by duarteroso »

It seemed to me that there was no wxEVT_COMMAND_CHECKBOX_CLICKED event sent, so I add it.
I don't know if it was the right place to do or the right thing, but it did the trick to me. Hope it help.

treelistctrl: line 4952

Code: Select all

if (item->GetItemType(m_curColumn) == wxCheckboxItemType)
{
    item->SetItemChecked(m_curColumn,! m_curItem->GetItemChecked(m_curColumn));
    wxCommandEvent event( wxEVT_COMMAND_CHECKBOX_CLICKED, m_owner->GetId() );
    event.SetEventObject( m_owner );
    event.SetInt(m_curColumn); // Send column number. Get the checkbox status using GetItemChecked.
    m_owner->ProcessEvent( event );
}
Post Reply