Properly position a panel

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.
Post Reply
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 5314
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Properly position a panel

Post by ONEEYEMAN » Mon Jul 05, 2021 12:15 am

Hi, ALL,
I have kind of weird problem.

I have a wxNotebook. One of the panels there contains wxGrid with 4 columns. When I do a right click I want a pop-up menu to show up. Everything up to this point works fine.

Now when I choose one of the items in that menu I want a wxPanel to be displayed. The bottom of that wxPanel should be where the clicked row is. So it should work just like a wxComboBox except that I don't want the arrow to be displayed and the panel should work like a popup window where I can get a selection and the string I selected will show up in the appropriate cell

My problem is - how do I position the wxPanel?

I can probably figure out the position of the first {visible} row in the wxGrid and set the position of the wxPanel, but what I do with the second+ row?
And am I thinking correctly even for the first row?

Thank you.

P.S.: I hope I explained my problem properly. Let me know if it is not clear enough.

User avatar
doublemax@work
Earned some good credits
Earned some good credits
Posts: 131
Joined: Wed Jul 29, 2020 6:06 pm

Re: Properly position a panel

Post by doublemax@work » Mon Jul 05, 2021 1:40 pm

In general i'd recommend to use wxPopupWindow instead of adding a wxPanel to the grid.

The wxGridEvent should contain mouse coordinates relative to the client window. Convert them with CalcGridWindowUnscrolledPosition or CalcGridWindowScrolledPosition (i can never tell which one does what).
https://docs.wxwidgets.org/trunk/classw ... 3cffee65fa

utelle
Moderator
Moderator
Posts: 1046
Joined: Tue Jul 05, 2005 10:00 pm
Location: Cologne, Germany
Contact:

Re: Properly position a panel

Post by utelle » Mon Jul 05, 2021 1:53 pm

If I understood it correctly, you want to show a panel below the selected grid cell. You will have to do something like the following to determine the screen position of the panel:

Code: Select all

void GridFrame::OnSelectCell( wxGridEvent& ev )
{
  // Get grid object
  wxGrid* grid = ((wxGrid*) ev.GetEventObject());

  // Determine grid position on screen (position of cell (0,0))
  wxPoint gridPosOnScreen = grid->GetScreenPosition();

  // Determine relative position of selected cell
  wxGridCellCoords selectedCellCoords(ev.GetRow(), ev.GetCol());
  wxRect relCellPos = grid->BlockToDeviceRect(selectedCellCoords, selectedCellCoords);

  // Determine size of grid corner label window
  wxWindow* cornerWin = grid->GetGridCornerLabelWindow();
  wxSize cornerSize = cornerWin->GetSize();

  // Calculate position of popup menu
  wxPoint menuPosition = gridPosOnScreen;
  menuPosition.x += (relCellPos.x + cornerSize.GetWidth());
  menuPosition.y += (relCellPos.y + relCellPos.height + cornerSize.GetHeight());
  ScreenToClient(&menuPosition.x, &menuPosition.y);

  // Show popup menu
  wxMenu actionMenu;
  actionMenu.Append(10101, "Action 1");
  actionMenu.Append(10102, "Action 2");
  actionMenu.Append(10103, "Action 3");
  PopupMenu(&actionMenu, menuPosition);
  
  ev.Skip();
}
PopupMenu is a method of a wxWindow. Therefore the screen position has to be transformed into a client position using ScreenToClient. However, in your case you will probably have to use the screen position directly (without using ScreenToClient), because your panel will be positioned using screen coordinates.

ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 5314
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Properly position a panel

Post by ONEEYEMAN » Mon Jul 05, 2021 3:57 pm

Ulrich,
No, I want to show it above.
The notebook with grid will be at the bottom of the window (at least initially).

Hence the question of calculating its position.

Thank you.

ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 5314
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Properly position a panel

Post by ONEEYEMAN » Mon Jul 05, 2021 3:59 pm

doublemax,
Even if I use wxPopu{Transient}Window, I will still need to calculate its position, right?
Or the library will do that for me?

Thank you.

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

Re: Properly position a panel

Post by doublemax » Mon Jul 05, 2021 4:31 pm

Even if I use wxPopu{Transient}Window, I will still need to calculate its position, right?
Yes, but it takes screen coordinates, which might be easier to calculate using wxWindow::ClientToScreen
Use the source, Luke!

utelle
Moderator
Moderator
Posts: 1046
Joined: Tue Jul 05, 2005 10:00 pm
Location: Cologne, Germany
Contact:

Re: Properly position a panel

Post by utelle » Mon Jul 05, 2021 4:35 pm

ONEEYEMAN wrote:
Mon Jul 05, 2021 3:57 pm
No, I want to show it above.
Well, in that case you need to know the size (especially the height) of the panel, you intend to show above the selected grid cell. Thereafter the approach would be very similar to the one I showed in my previous post.

Code: Select all

  // Create panel
  wxPanel* panel = new wxPanel(...);

  // ...
  wxSize panelSize = panel->GetSize();

  wxPoint panelPosition = gridPosOnScreen;
  panelPosition.x += (relCellPos.x + cornerSize.GetWidth());
  panelPosition.y += (relCellPos.y + cornerSize.GetHeight() - panelSize.GetHeight);
  
  panel->SetPosition();
Of course, you need to make sure that the y-coordinate does not become negative.
ONEEYEMAN wrote:
Mon Jul 05, 2021 3:57 pm
The notebook with grid will be at the bottom of the window (at least initially).

Hence the question of calculating its position.
Maybe I haven't understood what you really intend to accomplish, but if you want to show some sort of popup panel above a selected grid cell, calculating the position of the popup panel should be rather straight forward as in the above code snippet.

Post Reply