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_