Get selected column in virtual wxListCtrl  [SOLVED]

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
csc81
In need of some credit
In need of some credit
Posts: 5
Joined: Mon Feb 02, 2009 4:44 pm
Contact:

Get selected column in virtual wxListCtrl

Postby csc81 » Mon Feb 02, 2009 7:44 pm

wx-Version: 2.8.9.0 - GTK


Hi :)

I'm having a virtual wxListCtrl in report mode (wxLC_REPORT and wxLC_VIRTUAL). The list has 5 columns and approximately 1000000 rows.

The problem: I would like to get the column number of the item (not the header) the user clicked on. I tried the following code which is part of my overloaded wxListCtrl.

...
void MyListCtrl::OnSelected(wxListEvent& event) {
long col = event.getColumn(); // PROBLEM: Always returned 0!!
wxLogMessage(wxT("Currently selected item: col=%ld"), col);
}
...

Is this even possible with wxListCtrl?
-- Experience is what you get if you don't get what you want.

JimFairway
wxWorld Domination!
wxWorld Domination!
Posts: 1059
Joined: Sun Dec 30, 2007 6:40 pm
Location: Canada

Postby JimFairway » Mon Feb 02, 2009 10:59 pm

Hi,

According to the docs, the column is only valid for column events.
http://docs.wxwidgets.org/stable/wx_wxl ... tgetcolumn

wxListItem::GetColumn says it's useful for report mode, so you should be able it get the column by getting the item first.
See http://docs.wxwidgets.org/stable/wx_wxl ... mgetcolumn

Hope that helps,

Jim

ps. Welcome to the forum, it's best to use the code tags to improve the readability of your posts.
OS: Vista SP1, wxWidgets 2.8.7.

csc81
In need of some credit
In need of some credit
Posts: 5
Joined: Mon Feb 02, 2009 4:44 pm
Contact:

Postby csc81 » Tue Feb 03, 2009 8:44 am

Hi Jim :)

Thanks for your quick reply. The links you sent were quite useful and now I understand why it does not work the way I tried.

If I got it right, you proposed to get the item first and then the column from the item. I thought about it but have no idea how this can solve my problem.

Actually, what I want the user to do is:

The user selects one row in the wxListCtrl. This row has several columns. Then the user clicks right - lets say to the third column in this row. A popup window opens and then the user can select "Copy" from the popup menu. Then, finally, the content from the cell where the user clicked on should be copied to the clipboard (The wxListCtrl only contains text).

I have already implemented the popup menu and the clipboard mechanism. What I would need now is a way to get the text from the cell where the user clicked on.
-- Experience is what you get if you don't get what you want.

User avatar
doublemax
Moderator
Moderator
Posts: 12677
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Postby doublemax » Tue Feb 03, 2009 11:39 am

You could try iterating over the column widths and compare it with the x-position of the mouse click:

Code: Select all

void myListCtrl::OnItemRightClick(wxListEvent& event)
{
  int column;
  int x=0;
  for(column=0; column<GetColumnCount(); column++) {
    x+=GetColumnWidth(column);
    if(x>=event.GetPoint().x) break;
   }
   wxLogDebug( wxT("column clicked: %d"), column);
}
The docs say that GetPoint() is only valid for drag events, but i tested it on MSW and it also works here. But this may not be guaranteed on other platforms.
Use the source, Luke!

csc81
In need of some credit
In need of some credit
Posts: 5
Joined: Mon Feb 02, 2009 4:44 pm
Contact:

Postby csc81 » Tue Feb 03, 2009 5:48 pm

Hej!

Thanks, that's a cool idea. I tried out your piece of code in my program and it works if there is no horizontal scrollbar in the wxListCtrl.

Now, the problem is that

Code: Select all

event.GetPosition().x
only gives the distance from the x-position of the wxListCtrl to the mouse pointers x position. So if someone scrolls to the right, the x-position of the wxListCtrl does not change of course. In this case the calculated column number becomes wrong.

So far, I tried to get the amount of pixels the user scrolled with

Code: Select all

GetScrollPos(wxHORIZONTAL)
(which is part of the wxWindow class). Unfortunately, this method only returns "scroll units" and not pixels.

Is there a way to compute the amount of pixels from this "scroll units"?

Or is there maybe a much easier way to get the correct distance-value?

My code so far:

Code: Select all

void ProblemListCtrl::OnContextMenu(wxContextMenuEvent& event) {
   wxPoint point = event.GetPosition();
   int column;
   int x=0;
   
   for(column=0; column<GetColumnCount(); column++) {
      x+=this->GetColumnWidth(column);
      
      // FIXME: point.x does not contain scrolled region :(
      if(x >= point.x ) break;
   }

   ...
}
-- Experience is what you get if you don't get what you want.

User avatar
doublemax
Moderator
Moderator
Posts: 12677
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Postby doublemax » Tue Feb 03, 2009 6:54 pm

i tested it and the value returned from GetScrollPos() seemed to be in pixels. What platform are you on?

In my test i just replaced the line

Code: Select all

int x=0;
with

Code: Select all

int x = -GetScrollPos(wxHORIZONTAL);
Use the source, Luke!

csc81
In need of some credit
In need of some credit
Posts: 5
Joined: Mon Feb 02, 2009 4:44 pm
Contact:

Postby csc81 » Tue Feb 03, 2009 8:35 pm

Hi!

Hm, this is strange :?

My system is: Linux / wxGTK.
'wx-config --basename --version --libs' returns:

2.8.9
wx_gtk2
-L/home/schmica/Applications//lib -pthread -lwx_gtk2_richtext-2.8 -lwx_gtk2_aui-2.8 -lwx_gtk2_xrc-2.8 -lwx_gtk2_qa-2.8 -lwx_gtk2_html-2.8 -lwx_gtk2_adv-2.8 -lwx_gtk2_core-2.8 -lwx_base_xml-2.8 -lwx_base_net-2.8 -lwx_base-2.8

One scroll unit returned by

Code: Select all

GetScrollPos(wxHORIZONTAL)
approximately corresponds to 15 pixels. Of course I could calculate from this value to the pixel count but this would be more a hack than a solution.

I also tried to find a correlation to the scroll thumb

Code: Select all

GetScrollThumb(wxHORIZONTAL)

but this method always returns 0.

So do I maybe have care about the scrollbar of the wxListCtrl by myself?
-- Experience is what you get if you don't get what you want.

User avatar
doublemax
Moderator
Moderator
Posts: 12677
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

  [SOLVED]

Postby doublemax » Tue Feb 03, 2009 8:47 pm

One scroll unit returned by

Code: Select all

GetScrollPos(wxHORIZONTAL)

approximately corresponds to 15 pixels. Of course I could calculate from this value to the pixel count but this would be more a hack than a solution.
the Linux version uses the generic listctrl, while MSW has a native one.

I checked the source and the generic version has a hardcoded value of 15, so your observation was correct.

Code: Select all

static const int SCROLL_UNIT_X = 15;

Unfortunately in the wxListCtrl interface these values are not exposed. So you probably have to use a little hack here.
Use the source, Luke!

csc81
In need of some credit
In need of some credit
Posts: 5
Joined: Mon Feb 02, 2009 4:44 pm
Contact:

Postby csc81 » Tue Feb 03, 2009 9:27 pm

Hm okej, if there is no official way to solve the problem at the moment it at least doesn't feel so bad to make a hack here :wink: Maybe a better way will be provided in future releases of wx...

Thank you very much for your help!
-- Experience is what you get if you don't get what you want.

shawnee
Knows some wx things
Knows some wx things
Posts: 31
Joined: Tue Jan 16, 2018 1:05 am

Re:

Postby shawnee » Wed May 09, 2018 3:12 pm

doublemax wrote:You could try iterating over the column widths and compare it with the x-position of the mouse click:

Code: Select all

void myListCtrl::OnItemRightClick(wxListEvent& event)
{
  int column;
  int x=0;
  for(column=0; column<GetColumnCount(); column++) {
    x+=GetColumnWidth(column);
    if(x>=event.GetPoint().x) break;
   }
   wxLogDebug( wxT("column clicked: %d"), column);
}
The docs say that GetPoint() is only valid for drag events, but i tested it on MSW and it also works here. But this may not be guaranteed on other platforms.


Hi doublemax,
Does event.GetPoint().x really work? In my codes, it always 0.
I checked the header file in v3.1, GetPoint() returns the value of m_pointDrag. It seems not mouse clicking position.

User avatar
doublemax
Moderator
Moderator
Posts: 12677
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Re:

Postby doublemax » Wed May 09, 2018 4:46 pm

shawnee wrote:Does event.GetPoint().x really work? In my codes, it always 0.
I checked the header file in v3.1, GetPoint() returns the value of m_pointDrag. It seems not mouse clicking position.


Like i wrote:
The docs say that GetPoint() is only valid for drag events, but i tested it on MSW and it also works here. But this may not be guaranteed on other platforms.


If it doesn't work under GTK, use ScreenToClient( ::wxGetMousePosition() )
Use the source, Luke!

shawnee
Knows some wx things
Knows some wx things
Posts: 31
Joined: Tue Jan 16, 2018 1:05 am

Re: Re:

Postby shawnee » Thu May 10, 2018 7:46 am

doublemax wrote:
shawnee wrote:Does event.GetPoint().x really work? In my codes, it always 0.
I checked the header file in v3.1, GetPoint() returns the value of m_pointDrag. It seems not mouse clicking position.


Like i wrote:
The docs say that GetPoint() is only valid for drag events, but i tested it on MSW and it also works here. But this may not be guaranteed on other platforms.


If it doesn't work under GTK, use ScreenToClient( ::wxGetMousePosition() )


I used ScreenToClient( ::wxGetMousePosition() ), then done. Thank you!


Return to “C++ Development”

Who is online

Users browsing this forum: No registered users and 19 guests