User sizable panel?
User sizable panel?
Is there a way to have a panel that is sizable by user using drag and drop? (EDIT: mouse dragging).
I especially need to resize the panel itself and not use a wxSplitterWindow which portions space between two windows, but keeps the total size constant.
wxPython seems to implement this with wx.lib.resizewidget but I'm using C++. Also, in this thread from 2013 it was suggested to "use MDI or wxAUI" but I'd prefer easier solution.
Also, the particular use case here is that I'd like a wxListView that can be resized by user.
I especially need to resize the panel itself and not use a wxSplitterWindow which portions space between two windows, but keeps the total size constant.
wxPython seems to implement this with wx.lib.resizewidget but I'm using C++. Also, in this thread from 2013 it was suggested to "use MDI or wxAUI" but I'd prefer easier solution.
Also, the particular use case here is that I'd like a wxListView that can be resized by user.
Last edited by thoray on Wed Jul 18, 2018 2:13 pm, edited 1 time in total.
Re: User sizable panel?
It's not clear to me what you are talking about. Resize when drag and drop an object (e.g. a bitmap, or text)? Or resize by dragging a border/corner of the window?
For the first case, use a wxDragImage http://docs.wxwidgets.org/trunk/classwx_drag_image.html and after calling EndDrag() you can resize the window (a panel or a control or any wxWindow) by the values you wish.
For the second case, a wxPanel can not be resized that way. Only "top level" windows (which have a border you can drag) can: wxFrame, wxDialog, and those of wxAUI and wxMDI. As a special addition, a wxSplliterWindow allows also user border-dragging.
If you want a control to be resized, just let it be child of a window with border, and use a sizer that takes all the available space. If the control is the only child of a wxFrame then no sizer is needed, the whole client space will be used by the child.
For the first case, use a wxDragImage http://docs.wxwidgets.org/trunk/classwx_drag_image.html and after calling EndDrag() you can resize the window (a panel or a control or any wxWindow) by the values you wish.
For the second case, a wxPanel can not be resized that way. Only "top level" windows (which have a border you can drag) can: wxFrame, wxDialog, and those of wxAUI and wxMDI. As a special addition, a wxSplliterWindow allows also user border-dragging.
If you want a control to be resized, just let it be child of a window with border, and use a sizer that takes all the available space. If the control is the only child of a wxFrame then no sizer is needed, the whole client space will be used by the child.
Re: User sizable panel?
I'm referring to resize by dragging a border/corner of the window. And in a situation where the window is not a "top level" window but a container for controls, like wxPanel or wxWindow.
I guess the answer to the question is then that it not be done unless using wxAUI or wxMDI.
Besides sizable panel, which it seems is not possible, making the control itself sizable by border dragging would also implement the functionality that I'm after, which is having a wxListView whose size can be expanded downwards by border dragging that is one control amongst others in wxPanel/wxWindow.
I guess the answer to the question is then that it not be done unless using wxAUI or wxMDI.
Besides sizable panel, which it seems is not possible, making the control itself sizable by border dragging would also implement the functionality that I'm after, which is having a wxListView whose size can be expanded downwards by border dragging that is one control amongst others in wxPanel/wxWindow.
Re: User sizable panel?
Hi,
Can't you use an actual wxPanel or (non-modal) wxDialog?
What is the problem with them? Did you try?
Thank you.
Can't you use an actual wxPanel or (non-modal) wxDialog?
What is the problem with them? Did you try?
Thank you.
Re: User sizable panel?
I did try putting the control inside a wxWindow but all that gave me was e.g. ability to turn on drawing of borders, but not sizing by border dragging.ONEEYEMAN wrote:Hi,
Can't you use an actual wxPanel or (non-modal) wxDialog?
What is the problem with them? Did you try?
Thank you.
Using a free standing wxDialog window would allow to resize the control by border dragging, but I want the control to be fixed in a panel and not in a separate window.
Re: User sizable panel?
Did you look into wxSashWindow? I have no experience with this class, but AFAIK it will only provide mouse resizing of the child window, the "form" resizing logic, i.e., what happens with other controls in the form would still need to be coded depending on your needs.
TBH, I do not understand the issue from the user point of view. If the user resizes the panel, what happens to the top level window containing it when a more room is needed and when (unlike with a splitter) the space cannot be taken away from the sibling windows? I assume it will become scrollable - top level windows changing their size based on the user resizing their windows are not very common...
TBH, I do not understand the issue from the user point of view. If the user resizes the panel, what happens to the top level window containing it when a more room is needed and when (unlike with a splitter) the space cannot be taken away from the sibling windows? I assume it will become scrollable - top level windows changing their size based on the user resizing their windows are not very common...
Re: User sizable panel?
Which style(s) did you use for the wxWindow?thoray wrote:I did try putting the control inside a wxWindow but all that gave me was e.g. ability to turn on drawing of borders, but not sizing by border dragging.ONEEYEMAN wrote: Hi,
Can't you use an actual wxPanel or (non-modal) wxDialog?
What is the problem with them? Did you try?
Thank you.
Could you please do some sketch on what do you mean here?thoray wrote: Using a free standing wxDialog window would allow to resize the control by border dragging, but I want the control to be fixed in a panel and not in a separate window.
Preferably just an initial setup and what happens after user drag-resize the dialog/panel.
Thank you.
Re: User sizable panel?
Unless you're building a GUI editor, i just can't think of any situation where it makes sense to resize an individual control.
You can of course catch the mouse motion event, check if the mouse is near the edge of a control, change the mouse cursor and if the user clicks, you capture the mouse and resize the control.
But what would happen to other controls that may lie next to or below that one control?
What you would usually do in a wxWidgets application would be to put the control in a sizer and allow it to grow in both directions. And if the user wants it bigger, he will increase the main frame and the inner control will grow and occupy the additional space.
You can of course catch the mouse motion event, check if the mouse is near the edge of a control, change the mouse cursor and if the user clicks, you capture the mouse and resize the control.
But what would happen to other controls that may lie next to or below that one control?
What you would usually do in a wxWidgets application would be to put the control in a sizer and allow it to grow in both directions. And if the user wants it bigger, he will increase the main frame and the inner control will grow and occupy the additional space.
Use the source, Luke!
Re: User sizable panel?
I made a minimal test app to show a case for user sizable control using wxSashWindow. User can drag the middle horizontal slider to show more or less of the list. This way user can free more space to controls after the list or to see more of the list.
If this was implemented with a wxSplitterWindow then controls after the list would get hidden after showing more of the list. Here instead a scrollbar is added to the panel.
Moving the sash doesn't properly size the list, however. I also get some bugged graphics for the sash moving in GTK2. Also, wxSashWindow doesn't seem to support live updates which makes it look non native, although that would be OK if it worked otherwise.
If this was implemented with a wxSplitterWindow then controls after the list would get hidden after showing more of the list. Here instead a scrollbar is added to the panel.
Moving the sash doesn't properly size the list, however. I also get some bugged graphics for the sash moving in GTK2. Also, wxSashWindow doesn't seem to support live updates which makes it look non native, although that would be OK if it worked otherwise.
Code: Select all
#include "wx/wx.h"
#include <wx/sashwin.h>
#include <wx/listctrl.h>
class MyApp : public wxApp
{
public:
virtual bool OnInit() override;
};
class MyFrame : public wxFrame
{
public:
MyFrame(const wxString& title);
void OnQuit(wxCommandEvent& event);
void OnSashDragged(wxSashEvent& event);
private:
wxDECLARE_EVENT_TABLE();
wxScrolledWindow* m_p;
wxSashWindow* m_sw;
wxListView* m_list;
};
enum
{
Minimal_Quit = wxID_EXIT,
M_SW,
};
wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_SASH_DRAGGED(M_SW, MyFrame::OnSashDragged)
EVT_MENU(Minimal_Quit, MyFrame::OnQuit)
wxEND_EVENT_TABLE()
wxIMPLEMENT_APP(MyApp);
bool MyApp::OnInit()
{
if ( !wxApp::OnInit() )
return false;
MyFrame *frame = new MyFrame("Minimal SashWindow Test App");
frame->Show(true);
return true;
}
MyFrame::MyFrame(const wxString& title)
: wxFrame(NULL, wxID_ANY, title)
{
// Add my control panel as scrolled window
m_p = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxSize(100,200), wxBORDER_THEME, "m_p");
m_p->SetScrollRate(5, 5);
wxBoxSizer* bs = new wxBoxSizer(wxVERTICAL);
wxTextCtrl* m_tc = new wxTextCtrl(m_p, wxID_ANY, "My control panel controls", wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
// Add sashwindow for resizing m_list
m_sw = new wxSashWindow(m_p, M_SW, wxDefaultPosition, wxDefaultSize, wxSW_3DSASH, "m_sw");
m_sw->SetSashVisible(wxSASH_BOTTOM,true);
m_list = new wxListView(m_sw, wxID_ANY, wxDefaultPosition, wxDefaultSize);
wxBoxSizer* bs2 = new wxBoxSizer(wxVERTICAL);
wxButton* m_button0 = new wxButton(m_p,wxID_ANY,"button0");
wxButton* m_button1 = new wxButton(m_p,wxID_ANY,"button1");
wxTextCtrl* m_tc2 = new wxTextCtrl(m_p, wxID_ANY, "Drag the sash to alter list size", wxDefaultPosition, wxDefaultSize, wxTE_READONLY | wxTE_CENTRE);
// Add first column
wxListItem col0;
col0.SetId(0);
col0.SetText( _("Col0") );
col0.SetWidth(75);
m_list->InsertColumn(0, col0);
// Add 2nd column
wxListItem col1;
col1.SetId(1);
col1.SetText( _("Col1") );
col1.SetWidth(75);
m_list->InsertColumn(1, col1);
// Add list items
wxListItem item;
for (int k=0;k<4;k++)
{
item.SetId(k);
m_list->InsertItem( item );
m_list->SetItem(k,0,"Hello");
m_list->SetItem(k,1,"World");
}
// Add controls to sizers
bs->Add(m_tc,0,wxEXPAND);
bs->Add(m_sw,0,wxEXPAND);
bs2->Add(m_list,0,wxEXPAND);
bs->Add(m_button0,0,wxEXPAND);
bs->Add(m_button1,0,wxEXPAND);
bs->Add(m_tc2,0,wxEXPAND);
// Associate sizers with controls
m_sw->SetSizer(bs2);
m_p->SetSize(GetClientSize());
m_p->SetSizer(bs);
m_p->FitInside();
this->SetSize(400,500);
}
void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
{
Close(true);
}
void MyFrame::OnSashDragged(wxSashEvent& event)
{
wxRect rect = event.GetDragRect();
std::cout << "new size: " << rect.GetX() << " " << rect.GetY() << std::endl;
// FIXME: This does not work
m_sw->SetSize(rect);
}
Re: User sizable panel?
Now that I have some idea how layout management works in wxWidgets, I managed to fix my minimal sample from 2018:
The relevant change is in OnSashDragged() but I also improved the sample overall (usersizablecontrol2.zip). Now this wxSashWindow sample fully works.
Since there is no wxSashWindow sample in wxWidgets how about adding one based on this? wxListView has otherwise fixed vertical size so adding user controlled vertical sizing mechanism can make a lot of sense in an application.
Code: Select all
void MyFrame::OnSashDragged(wxSashEvent& event)
{
wxRect rect = event.GetDragRect();
- std::cout << "new size: " << rect.GetX() << " " << rect.GetY() << std::endl;
- // FIXME: This does not work
- m_sw->SetSize(rect);
+ wxSize s = rect.GetSize();
+ s.SetWidth(-1); // Don't set fixed minsize horizontally
+ m_sashw->SetInitialSize(s); // Set new fixed minsize vertically for sashwindow
+ m_sw->Layout(); // Layout resized items in scrolledwindow
+ m_sw->FitInside(); // Fit scrolledwindow inside the frame, adding a scrollbar if necessary
}
Since there is no wxSashWindow sample in wxWidgets how about adding one based on this? wxListView has otherwise fixed vertical size so adding user controlled vertical sizing mechanism can make a lot of sense in an application.
- Attachments
-
- usersizablecontrol2.zip
- (1.46 KiB) Downloaded 100 times
Re: User sizable panel?
Hi,
This is a user forum.
You should send an E-mail to wx-dev or wx-users ML to discuss any changes to the wx distribution.
Thank you.
This is a user forum.
You should send an E-mail to wx-dev or wx-users ML to discuss any changes to the wx distribution.
Thank you.