⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dynamicsash.cpp

📁 Wxpython Implemented on Windows CE, Source code
💻 CPP
📖 第 1 页 / 共 3 页
字号:
        m_container->SetCursor(cursor);

        m_dragging = DSR_NONE;
    }
    else if (m_leaf)
    {
        m_leaf->OnRelease(event);
    }
}

// ============================================================================
// wxDynamicSashWindowLeaf
// ============================================================================

wxDynamicSashWindowLeaf::wxDynamicSashWindowLeaf(wxDynamicSashWindowImpl *impl)
{
    m_impl = impl;

    m_hscroll =
    m_vscroll = NULL;

    m_child = NULL;
}

wxDynamicSashWindowLeaf::~wxDynamicSashWindowLeaf()
{
    m_hscroll->SetEventHandler(m_hscroll);
    m_vscroll->SetEventHandler(m_vscroll);

    m_hscroll->Destroy();
    m_vscroll->Destroy();
    m_viewport->Destroy();
}

bool wxDynamicSashWindowLeaf::Create()
{
    m_hscroll = new wxScrollBar();
    m_vscroll = new wxScrollBar();
    m_viewport = new wxWindow();

    wxDynamicSashWindowImpl *add_child_target = m_impl->m_add_child_target;
    m_impl->m_add_child_target = NULL;

    bool success = m_hscroll->Create(m_impl->m_container, wxID_ANY,
                                     wxDefaultPosition, wxDefaultSize,
                                     wxSB_HORIZONTAL);
    if ( success )
        success = m_vscroll->Create(m_impl->m_container, wxID_ANY,
                                    wxDefaultPosition, wxDefaultSize,
                                    wxSB_VERTICAL);
    if ( success )
        success = m_viewport->Create(m_impl->m_container, wxID_ANY);
    if ( !success )
        return false;

    m_impl->m_add_child_target = add_child_target;

    wxCursor cursor(wxCURSOR_ARROW);
    m_hscroll->SetCursor(cursor);
    m_vscroll->SetCursor(cursor);
    m_viewport->SetCursor(cursor);

    // the viewport must resize its child when it is itself resized, but it's
    // more convenient to do it in our own method instead of deriving a new
    // class just for this: this is why we pass this as last Connect() argument
    m_viewport->Connect(wxEVT_SIZE,
                        wxSizeEventHandler(wxDynamicSashWindowLeaf::OnViewSize),
                        NULL, this);

    Connect(wxEVT_DYNAMIC_SASH_REPARENT,
            wxEventHandler(wxDynamicSashWindowLeaf::OnReparent));

    if (m_impl->m_window->GetWindowStyle() & wxDS_MANAGE_SCROLLBARS)
    {
        m_hscroll->SetEventHandler(this);
        m_vscroll->SetEventHandler(this);

        Connect(wxEVT_SET_FOCUS,
                wxFocusEventHandler(wxDynamicSashWindowLeaf::OnFocus));
        Connect(wxEVT_SCROLL_TOP,
                wxScrollEventHandler(wxDynamicSashWindowLeaf::OnScroll));
        Connect(wxEVT_SCROLL_BOTTOM,
                wxScrollEventHandler(wxDynamicSashWindowLeaf::OnScroll));
        Connect(wxEVT_SCROLL_LINEUP,
                wxScrollEventHandler(wxDynamicSashWindowLeaf::OnScroll));
        Connect(wxEVT_SCROLL_LINEDOWN,
                wxScrollEventHandler(wxDynamicSashWindowLeaf::OnScroll));
        Connect(wxEVT_SCROLL_PAGEUP,
                wxScrollEventHandler(wxDynamicSashWindowLeaf::OnScroll));
        Connect(wxEVT_SCROLL_PAGEDOWN,
                wxScrollEventHandler(wxDynamicSashWindowLeaf::OnScroll));
        Connect(wxEVT_SCROLL_THUMBTRACK,
                wxScrollEventHandler(wxDynamicSashWindowLeaf::OnScroll));
        Connect(wxEVT_SCROLL_THUMBRELEASE,
                wxScrollEventHandler(wxDynamicSashWindowLeaf::OnScroll));
    }

    wxLayoutConstraints *layout = new wxLayoutConstraints();
    if (!layout)
        return false;

    wxSize size = m_hscroll->GetBestSize();

    layout->left.SameAs(m_impl->m_container, wxLeft, 10);
    layout->right.LeftOf(m_vscroll);
    layout->bottom.SameAs(m_impl->m_container, wxBottom, 3);
    layout->height.Absolute(size.GetHeight());
    m_hscroll->SetConstraints(layout);

    layout = new wxLayoutConstraints();
    if (!layout)
        return false;

    size = m_vscroll->GetBestSize();

    layout->top.SameAs(m_impl->m_container, wxTop, 10);
    layout->bottom.Above(m_hscroll);
    layout->right.SameAs(m_impl->m_container, wxRight, 3);
    layout->width.Absolute(size.GetWidth());
    m_vscroll->SetConstraints(layout);

    layout = new wxLayoutConstraints();
    if (!layout)
        return false;
    layout->left.SameAs(m_impl->m_container, wxLeft, 3);
    layout->right.LeftOf(m_vscroll);
    layout->top.SameAs(m_impl->m_container, wxTop, 3);
    layout->bottom.Above(m_hscroll);
    m_viewport->SetConstraints(layout);

    m_impl->m_container->Layout();

    return true;
}

void wxDynamicSashWindowLeaf::AddChild(wxWindow *window)
{
    if (m_child)
        m_child->Destroy();

    m_child = window;

    wxDynamicSashReparentEvent event(this);
    AddPendingEvent(event);
}

DynamicSashRegion wxDynamicSashWindowLeaf::GetRegion(int x, int y)
{
    wxSize size = m_impl->m_container->GetSize();
    int w = size.GetWidth();
    int h = size.GetHeight();
    size = m_hscroll->GetSize();
    int sh = size.GetHeight();
    size = m_vscroll->GetSize();
    int sw = size.GetWidth();

    if (x >= w - sw - 3 && x < w && y >= h - sh - 3 && y < h)
        return DSR_CORNER;
    if (x >= 3 && x < 10 && y >= h - sh - 3 && y < h - 2)
        return DSR_VERTICAL_TAB;
    if (x >= w - sw - 3 && x < w - 2 && y >= 3 && y < 10)
        return DSR_HORIZONTAL_TAB;
    if (x < 3)
        return DSR_LEFT_EDGE;
    if (y < 3)
        return DSR_TOP_EDGE;
    if (x >= w - 2)
        return DSR_RIGHT_EDGE;
    if (y >= h - 2)
        return DSR_BOTTOM_EDGE;

    return DSR_NONE;
}

void wxDynamicSashWindowLeaf::ResizeChild(const wxSize& size)
{
    if (m_child)
    {
        if (m_impl->m_window->HasFlag(wxDS_MANAGE_SCROLLBARS))
        {
            wxSize best_size = m_child->GetBestSize();
            if (best_size.GetWidth() < size.GetWidth())
                best_size.SetWidth(size.GetWidth());
            if (best_size.GetHeight() < size.GetHeight())
                best_size.SetHeight(size.GetHeight());
            m_child->SetSize(best_size);

            int hpos = m_hscroll->GetThumbPosition();
            int vpos = m_vscroll->GetThumbPosition();

            if (hpos < 0)
                hpos = 0;
            if (vpos < 0)
                vpos = 0;
            if (hpos > best_size.GetWidth() - size.GetWidth())
                hpos = best_size.GetWidth() - size.GetWidth();
            if (vpos > best_size.GetHeight() - size.GetHeight())
                vpos = best_size.GetHeight() - size.GetHeight();

            m_hscroll->SetScrollbar(hpos, size.GetWidth(),
                                    best_size.GetWidth(), size.GetWidth());
            m_vscroll->SetScrollbar(vpos, size.GetHeight(),
                                    best_size.GetHeight(), size.GetHeight());

            //  Umm, the scrollbars are doing something insane under GTK+ and subtracting
            //  one from the position I pass in.  This works around that.
            m_hscroll->SetThumbPosition(hpos + hpos - m_hscroll->GetThumbPosition());
            m_vscroll->SetThumbPosition(vpos + vpos - m_vscroll->GetThumbPosition());

            wxPoint pos = m_child->GetPosition();
            m_viewport->ScrollWindow(-hpos - pos.x, -vpos - pos.y);
        }
        else // !wxDS_MANAGE_SCROLLBARS
        {
            m_child->SetSize(size);
        }
    }
}

wxScrollBar *
wxDynamicSashWindowLeaf::FindScrollBar(const wxWindow *child, int vert) const
{
    if (m_child == child)
    {
        return vert ? m_vscroll : m_hscroll;
    }

    return NULL;
}

void wxDynamicSashWindowLeaf::OnSize(wxSizeEvent &WXUNUSED(event))
{
    m_impl->m_container->Refresh();
}

void wxDynamicSashWindowLeaf::OnViewSize(wxSizeEvent &WXUNUSED(event))
{
    if ( m_viewport )
        ResizeChild(m_viewport->GetSize());
}

void wxDynamicSashWindowLeaf::OnPaint(wxPaintEvent &WXUNUSED(event))
{
    wxPaintDC dc(m_impl->m_container);
    dc.SetBackground(wxBrush(m_impl->m_container->GetBackgroundColour(), wxSOLID));
    dc.Clear();

    wxPen highlight(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNHIGHLIGHT), 1, wxSOLID);
    wxPen shadow(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNSHADOW), 1, wxSOLID);
    wxPen black(*wxBLACK, 1, wxSOLID);

    wxSize size = m_impl->m_container->GetSize();
    int w = size.GetWidth();
    int h = size.GetHeight();
    size = m_hscroll->GetSize();
    int sh = size.GetHeight();
    size = m_vscroll->GetSize();
    int sw = size.GetWidth();

    dc.SetPen(shadow);
    dc.DrawLine(1, 1, 1, h - 2);
    dc.DrawLine(1, 1, w - 2, 1);
    dc.SetPen(black);
    dc.DrawLine(2, 2, 2, h - 3);
    dc.DrawLine(2, 2, w - 3, 2);
    dc.SetPen(highlight);
    dc.DrawLine(w - 2, 2, w - 2, h - sh - 2);
    dc.DrawLine(w - 2, h - sh - 2, w - sw - 2, h - sh - 2);
    dc.DrawLine(w - sw - 2, h - sh - 2, w - sw - 2, h - 2);
    dc.DrawLine(w - sw - 2, h - 2, 2, h - 2);

    dc.SetPen(highlight);
    dc.DrawLine(w - sw - 2, 8, w - sw - 2, 4);
    dc.DrawLine(w - sw - 2, 4, w - 5, 4);
    dc.SetPen(shadow);
    dc.DrawLine(w - 5, 4, w - 5, 8);
    dc.DrawLine(w - 5, 8, w - sw - 2, 8);
    dc.SetPen(black);
    dc.DrawLine(w - 4, 3, w - 4, 9);
    dc.DrawLine(w - 4, 9, w - sw - 3, 9);

    dc.SetPen(highlight);
    dc.DrawLine(4, h - 5, 4, h - sh - 2);
    dc.DrawLine(4, h - sh - 2, 8, h - sh - 2);
    dc.SetPen(shadow);
    dc.DrawLine(8, h - sh - 2, 8, h - 5);
    dc.DrawLine(8, h - 5, 4, h - 5);
    dc.SetPen(black);
    dc.DrawLine(9, h - sh - 3, 9, h - 4);
    dc.DrawLine(9, h - 4, 3, h - 4);

    int cy = (h - sh + h - 6) / 2 + 1;
    int cx = (w - sw + w - 6) / 2 + 1;
    int sy = cy;
    while (sy > h - sh)
        sy -= 4;
    int sx = cx;
    while (sx > w - sw)
        sx -= 4;

    int x, y;
    for (y = sy; y < h - 2; y += 4)
    {
        for (x = sx; x < w - 2; x += 4)
        {
            if (x - cx >= -(y - cy))
            {
                dc.SetPen(highlight);
                dc.DrawPoint(x, y);
                dc.SetPen(shadow);
                dc.DrawPoint(x + 1, y + 1);
            }
        }
    }
}

void wxDynamicSashWindowLeaf::OnScroll(wxScrollEvent &WXUNUSED(event))
{
    int nx = -m_hscroll->GetThumbPosition();
    int ny = -m_vscroll->GetThumbPosition();

    if (m_child)
    {
        wxPoint pos = m_child->GetPosition();

        m_viewport->ScrollWindow(nx - pos.x, ny - pos.y);
    }
}

void wxDynamicSashWindowLeaf::OnFocus(wxFocusEvent &event)
{
    if ( event.GetEventObject() == m_hscroll ||
            event.GetEventObject() == m_vscroll )
    {
        m_child->SetFocus();
    }
}


void wxDynamicSashWindowLeaf::OnMouseMove(wxMouseEvent &event)
{
    if (m_impl->m_dragging)
        return;

    DynamicSashRegion region = GetRegion(event.m_x, event.m_y);

    wxCursor cursor(wxCURSOR_ARROW);
    if (region == DSR_HORIZONTAL_TAB)
    {
        cursor = wxCursor(wxCURSOR_SIZENS);
    }
    else if (region == DSR_VERTICAL_TAB)
    {
        cursor = wxCursor(wxCURSOR_SIZEWE);
    }
    else if ((region == DSR_CORNER) &&
               (m_impl->m_window->GetWindowStyle() & wxDS_DRAG_CORNER) != 0)
    {
        cursor = wxCursor(wxCURSOR_SIZENWSE);
    }
    else if (region == DSR_LEFT_EDGE || region == DSR_TOP_EDGE
                || region == DSR_RIGHT_EDGE || region == DSR_BOTTOM_EDGE)
    {
        if (m_impl->FindParent(region))
        {
            if (region == DSR_LEFT_EDGE || region == DSR_RIGHT_EDGE)
            {
                cursor = wxCursor(wxCURSOR_SIZEWE);
            }
            else
            {
                cursor = wxCursor(wxCURSOR_SIZENS);
            }
        }
    }

    m_impl->m_container->SetCursor(cursor);
}

void wxDynamicSashWindowLeaf::OnLeave(wxMouseEvent &WXUNUSED(event))
{
    wxCursor cursor(wxCURSOR_ARROW);
    m_impl->m_container->SetCursor(cursor);
}


void wxDynamicSashWindowLeaf::OnPress(wxMouseEvent &event)
{
    DynamicSashRegion region = GetRegion(event.m_x, event.m_y);

    if ((region == DSR_CORNER) && (m_impl->m_window->GetWindowStyle() & wxDS_DRAG_CORNER) == 0)
        return;

    if (region == DSR_HORIZONTAL_TAB || region == DSR_VERTICAL_TAB || region == DSR_CORNER)
    {
        m_impl->m_dragging = region;
        m_impl->m_drag_x = event.m_x;
        m_impl->m_drag_y = event.m_y;
        m_impl->DrawSash(event.m_x, event.m_y);
        m_impl->m_container->CaptureMouse();
    }
    else if (region == DSR_LEFT_EDGE || region == DSR_TOP_EDGE
                || region == DSR_RIGHT_EDGE || region == DSR_BOTTOM_EDGE)
    {
        wxDynamicSashWindowImpl *parent = m_impl->FindParent(region);

        if (parent)
        {
            int x = event.m_x;
            int y = event.m_y;

            m_impl->m_container->ClientToScreen(&x, &y);
            parent->m_container->ScreenToClient(&x, &y);

            parent->m_dragging = parent->m_split;
            parent->m_drag_x = x;
            parent->m_drag_y = y;
            parent->DrawSash(x, y);
            parent->m_container->CaptureMouse();
        }
    }
}

void wxDynamicSashWindowLeaf::OnRelease(wxMouseEvent &WXUNUSED(event))
{
}

void wxDynamicSashWindowLeaf::OnReparent(wxEvent &WXUNUSED(event))
{
    if (m_child)
    {
        m_child->Reparent(m_viewport);
    }

    ResizeChild(m_viewport->GetSize());
}

// ============================================================================
// events
// ============================================================================

wxDynamicSashSplitEvent::wxDynamicSashSplitEvent()
{
    m_eventObject = NULL;
    m_eventType = wxEVT_DYNAMIC_SASH_SPLIT;
}

wxDynamicSashSplitEvent::wxDynamicSashSplitEvent(wxObject *object)
{
    m_eventObject = object;
    m_eventType = wxEVT_DYNAMIC_SASH_SPLIT;
}

IMPLEMENT_DYNAMIC_CLASS(wxDynamicSashSplitEvent, wxCommandEvent)

wxDynamicSashUnifyEvent::wxDynamicSashUnifyEvent()
{
    m_eventObject = NULL;
    m_eventType = wxEVT_DYNAMIC_SASH_UNIFY;
}

wxDynamicSashUnifyEvent::wxDynamicSashUnifyEvent(wxObject *object)
{
    m_eventObject = object;
    m_eventType = wxEVT_DYNAMIC_SASH_UNIFY;
}

IMPLEMENT_DYNAMIC_CLASS(wxDynamicSashUnifyEvent, wxCommandEvent)


wxDynamicSashReparentEvent::wxDynamicSashReparentEvent()
{
    m_eventObject = NULL;
    m_eventType = wxEVT_DYNAMIC_SASH_REPARENT;
}

wxDynamicSashReparentEvent::wxDynamicSashReparentEvent(wxObject *object)
{
    m_eventObject = object;
    m_eventType = wxEVT_DYNAMIC_SASH_REPARENT;
}

wxDynamicSashReparentEvent::wxDynamicSashReparentEvent(const wxDynamicSashReparentEvent& evt)
    : wxEvent(evt)
{
}

IMPLEMENT_DYNAMIC_CLASS(wxDynamicSashReparentEvent, wxEvent)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -