clq

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

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_

posted on 2012-02-13 15:41  clq  阅读(951)  评论(0编辑  收藏  举报