wxWidgets 的自定义分隔条控件
默认的好象不太好用,自己写一个其实也不难.
#ifndef _VSPLITPANEL_H_
#define _VSPLITPANEL_H_#include <wx/intl.h>#include <wx/string.h>#include <wx/panel.h>#include <wx/button.h>#include <wx/dialog.h>#include <wx/msgdlg.h>#include <vector>//虚拟的分隔条//继承自 wxEvtHandler 的才可以绑定事件class vSplitPanel : public wxEvtHandler//: public wxPanel{ public: static std::vector<vSplitPanel *> allSplitWindow; public: vSplitPanel() { init(); } virtual ~vSplitPanel(); public: //wxPanel wxWindow * panel; wxWindow * parentWindow; wxWindow * leftWindow; wxWindow * rightWindow; wxWindow * topWindow; wxWindow * bottomWindow; bool isLeft; bool isTop; //-------------------------------------------------- //拖放 int lastX; int lastY; bool isDown;//鼠标正在按下 //-------------------------------------------------- void init() { panel = NULL; parentWindow = NULL; leftWindow = NULL; rightWindow = NULL; topWindow = NULL; bottomWindow = NULL; isLeft = false; isTop = false; lastX = 0; lastY = 0; isDown = false; }// //关联控件,默认左右方向 void Assign(wxWindow * splitPanel, wxWindow * parentWindow, wxWindow * w1, wxWindow * w2, bool isLeft=true) { init(); this->isLeft = isLeft; this->panel = splitPanel; this->parentWindow = parentWindow; if(isLeft) { leftWindow = w1; rightWindow = w2; } else { topWindow = w1; bottomWindow = w2; } }// //父窗口改变时重置子窗口 onsize 时调用就可以了 int getH(wxWindow * window) { if (window == NULL) return 0; return window->GetSize().y; }// int getW(wxWindow * window) { if (window == NULL) return 0; return window->GetSize().x; }// int getLeft(wxWindow * window) { if (window == NULL) return 0; return window->GetPosition().x; }// int getTop(wxWindow * window) { if (window == NULL) return 0; return window->GetPosition().y; }// void MoveWindow(wxWindow * window, int x, int y, int width, int height) { if (window != NULL) { //rightWindow->SetPosition(wxPoint(left,10));//目前的 wxWidgets-2.8.12 版本中,这个居然会改变 panel 中子控件的位置所最好用封装过的函数 //rightWindow->SetSize(left,10, wxDefaultCoord, wxDefaultCoord, wxSIZE_USE_EXISTING); //rightWindow->SetSize(client.x - left, client.y); window->SetSize(x, y, width, height);//, wxDefaultCoord); } }// void MoveWindowPos(wxWindow * window, int x, int y) { if (window != NULL) { wxRect rect = window->GetRect(); MoveWindow(window, x, y, rect.width, rect.height); } }// void MoveWindowLeft(wxWindow * window, int x) { if (window != NULL) { wxRect rect = window->GetRect(); MoveWindow(window, x, rect.y, rect.width, rect.height); } }// void MoveWindowWidth(wxWindow * window, int width) { if (window != NULL) { wxRect rect = window->GetRect(); MoveWindow(window, rect.x, rect.y, width, rect.height); } }// void MoveWindowHeight(wxWindow * window, int height) { if (window != NULL) { wxRect rect = window->GetRect(); MoveWindow(window, rect.x, rect.y, rect.width, height); } }// void OnParentSize(bool refresh = true) { wxSize client = parentWindow->GetClientSize(); int left = getW(leftWindow); int top = getH(topWindow); left += panel->GetSize().x; top += panel->GetSize().y; if (leftWindow != NULL) { //leftWindow->SetPosition(wxPoint(0,0)); //leftWindow->SetSize(getW(leftWindow), client.y); MoveWindow(leftWindow, 0, 0, getW(leftWindow), client.y); } if (topWindow != NULL) { MoveWindow(topWindow, 0, 0, client.x, getH(topWindow)); } if (rightWindow != NULL) { //rightWindow->SetPosition(wxPoint(left,10));//目前的 wxWidgets-2.8.12 版本中,这个居然会改变 panel 中子控件的位置所最好用封装过的函数 //rightWindow->SetSize(left,10, wxDefaultCoord, wxDefaultCoord, wxSIZE_USE_EXISTING); //rightWindow->SetSize(client.x - left, client.y); rightWindow->SetSize(left, 0, client.x - left, client.y);//, wxDefaultCoord); MoveWindow(rightWindow, left, 0, client.x - left, client.y); } if (bottomWindow != NULL) { MoveWindow(bottomWindow, 0, top, client.x, client.y - top); } if (isLeft == true) { //panel->SetPosition(wxPoint(getW(leftWindow), 0)); //panel->SetSize(getW(panel), client.y); MoveWindow(panel, getW(leftWindow), 0, getW(panel), client.y); }else { MoveWindow(panel, 0, getH(topWindow), client.x, getH(panel)); } if (refresh == true) { //this->Panel1->Refresh();//根据 wx 帮助文件 //根据 wx 帮助文件,移动窗口后需要调用一这个 //if (leftWindow != NULL) leftWindow->Refresh(); //if (rightWindow != NULL) rightWindow->Refresh(); //if (topWindow != NULL) topWindow->Refresh(); //if (bottomWindow != NULL) bottomWindow->Refresh(); // RefreshWindow(panel); RefreshWindow(parentWindow); // RefreshWindow(leftWindow); // RefreshWindow(rightWindow); // RefreshWindow(topWindow); // RefreshWindow(bottomWindow);//顺序有讲究,不懂为什么 } //panel->CaptureMouse(); }// //继承自 wxEvtHandler 的才可以绑定事件 void SetEvents()//test { //panel->Connect(wxEVT_LEFT_DOWN,(wxObjectEventFunction)&vSplitPanel::OnLeftDown,0,this); panel->Connect(wxEVT_LEFT_DOWN,(wxObjectEventFunction)&vSplitPanel::OnLeftDown, 0, this); panel->Connect(wxEVT_LEFT_UP,(wxObjectEventFunction)&vSplitPanel::DoOnLeftUp, 0, this); panel->Connect(wxEVT_MOTION,(wxObjectEventFunction)&vSplitPanel::DoOnMouseMove, 0, this); //panel->Connect(wxEVT_LEFT_DOWN,(wxObjectEventFunction)&vSplitPanel::OnLeftDown, 0, this); } // void OnLeftDown(wxMouseEvent& event) { //panel->CaptureMouse(); //wxMessageBox("",""); DoOnLeftDown(event); }// // on.. 时要做事情 void DoOnLeftDown(wxMouseEvent& event) { int x = ::wxGetMousePosition().x;//event.m_x; int y = ::wxGetMousePosition().y;//event.m_y; panel->CaptureMouse(); //wxMessageBox("",""); lastX = x; lastY = y; isDown = true; }// // on.. 时要做事情 void DoOnLeftUp(wxMouseEvent& event) { isDown = false; int x = ::wxGetMousePosition().x;//event.m_x; int y = ::wxGetMousePosition().y;//event.m_y; panel->ReleaseMouse();//CaptureMouse(); //wxMessageBox("up",""); lastX = x; lastY = y; }// //void RefreshWindow void RefreshWindow(wxWindow * window) { if (window == NULL) return; window->Refresh(); window->Update();//根据 wx 帮助,还需要调用这个都能立即重画 } // on.. 时要做事情 void DoOnMouseMove(wxMouseEvent& event) { int x = ::wxGetMousePosition().x;//event.m_x; int y = ::wxGetMousePosition().y;//event.m_y; int left = getLeft(panel); if (isDown == true) { //panel->CaptureMouse(); //wxMessageBox("",""); if (isLeft == true) { int sp = x - lastX; left += sp; //MoveWindowLeft(panel, left); //left = getLeft(rightWindow); //MoveWindowLeft(rightWindow, left + sp); int w = getW(leftWindow); w += sp; if (w > 0) MoveWindowWidth(leftWindow, w); }//left else { int sp = y - lastY; int h = getH(topWindow); h += sp; if (h> 0) MoveWindowHeight(topWindow, h); }//top OnParentSize(true); lastX = x; lastY = y; } }// protected: private:};#endif // _VSPLITPANEL_H_