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

📄 scrollviewwx.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
字号:
/* * Copyright (C) 2007 Kevin Ollivier <kevino@theolliviers.com> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  */#include "config.h"#include "ScrollView.h"#include "FloatRect.h"#include "IntRect.h"#include "NotImplemented.h"#include "PlatformWheelEvent.h"#include "Scrollbar.h"#include <algorithm>#include <stdio.h>#include <wx/defs.h>#include <wx/scrolbar.h>#include <wx/scrolwin.h>#include <wx/event.h>using namespace std;namespace WebCore {class ScrollView::ScrollViewPrivate : public wxEvtHandler {public:    ScrollViewPrivate(ScrollView* scrollView)        : wxEvtHandler()        , m_scrollView(scrollView)        , vScrollbarMode(ScrollbarAuto)        , hScrollbarMode(ScrollbarAuto)        , viewStart(0, 0)    {    }    void bindEvents(wxWindow* win)    {        // TODO: is there an easier way to Connect to a range of events? these are contiguous.        win->Connect(wxEVT_SCROLLWIN_TOP,          wxScrollWinEventHandler(ScrollViewPrivate::OnScrollWinEvents), NULL, this);        win->Connect(wxEVT_SCROLLWIN_BOTTOM,       wxScrollWinEventHandler(ScrollViewPrivate::OnScrollWinEvents), NULL, this);        win->Connect(wxEVT_SCROLLWIN_LINEUP,       wxScrollWinEventHandler(ScrollViewPrivate::OnScrollWinEvents), NULL, this);        win->Connect(wxEVT_SCROLLWIN_LINEDOWN,     wxScrollWinEventHandler(ScrollViewPrivate::OnScrollWinEvents), NULL, this);        win->Connect(wxEVT_SCROLLWIN_PAGEUP,       wxScrollWinEventHandler(ScrollViewPrivate::OnScrollWinEvents), NULL, this);        win->Connect(wxEVT_SCROLLWIN_PAGEDOWN,     wxScrollWinEventHandler(ScrollViewPrivate::OnScrollWinEvents), NULL, this);        win->Connect(wxEVT_SCROLLWIN_THUMBTRACK,   wxScrollWinEventHandler(ScrollViewPrivate::OnScrollWinEvents), NULL, this);        win->Connect(wxEVT_SCROLLWIN_THUMBRELEASE, wxScrollWinEventHandler(ScrollViewPrivate::OnScrollWinEvents), NULL, this);    }        void OnScrollWinEvents(wxScrollWinEvent& e)    {        wxEventType scrollType(e.GetEventType());        bool horiz = e.GetOrientation() == wxHORIZONTAL;        wxPoint pos(viewStart);         if (scrollType == wxEVT_SCROLLWIN_THUMBTRACK || scrollType == wxEVT_SCROLLWIN_THUMBRELEASE) {            if (horiz)                 pos.x = e.GetPosition();            else                       pos.y = e.GetPosition();        }        else if (scrollType == wxEVT_SCROLLWIN_LINEDOWN) {            if (horiz)                 pos.x += cScrollbarPixelsPerLineStep;            else                       pos.y += cScrollbarPixelsPerLineStep;        }        else if (scrollType == wxEVT_SCROLLWIN_LINEUP) {            if (horiz)                 pos.x -= cScrollbarPixelsPerLineStep;            else                       pos.y -= cScrollbarPixelsPerLineStep;        }        else if (scrollType == wxEVT_SCROLLWIN_PAGEUP) {            if (horiz)                 pos.x -= m_scrollView->visibleWidth() - cAmountToKeepWhenPaging;            else                       pos.y -= m_scrollView->visibleHeight() - cAmountToKeepWhenPaging;        }        else if (scrollType == wxEVT_SCROLLWIN_PAGEDOWN) {            if (horiz)                 pos.x += m_scrollView->visibleWidth() - cAmountToKeepWhenPaging;            else                       pos.y += m_scrollView->visibleHeight() - cAmountToKeepWhenPaging;        }        else            return e.Skip();        m_scrollView->setScrollPosition(IntPoint(pos.x, pos.y));    }    ScrollView* m_scrollView;    ScrollbarMode vScrollbarMode;    ScrollbarMode hScrollbarMode;    wxPoint viewStart;};void ScrollView::platformInit(){    m_data = new ScrollViewPrivate(this);}void ScrollView::platformDestroy(){    delete m_data;}void ScrollView::setPlatformWidget(wxWindow* win){    Widget::setPlatformWidget(win);    m_data->bindEvents(win);}void ScrollView::platformRepaintContentRectangle(const IntRect& updateRect, bool now){    // we need to convert coordinates to scrolled position    wxRect contentsRect = updateRect;    contentsRect.Offset(-scrollX(), -scrollY());    wxWindow* win = platformWidget();    if (win) {        win->RefreshRect(contentsRect, true);        if (now)            win->Update();    }}IntRect ScrollView::platformVisibleContentRect(bool includeScrollbars) const{    wxWindow* win = platformWidget();    if (!win)        return IntRect();    int width, height;    if (includeScrollbars)        win->GetSize(&width, &height);    else        win->GetClientSize(&width, &height);            return IntRect(m_data->viewStart.x, m_data->viewStart.y, width, height);}IntSize ScrollView::platformContentsSize() const{    int width = 0;    int height = 0;    if (platformWidget()) {        platformWidget()->GetVirtualSize(&width, &height);        ASSERT(width >= 0 && height >= 0);    }    return IntSize(width, height);}void ScrollView::platformSetScrollPosition(const IntPoint& scrollPoint){    wxWindow* win = platformWidget();    wxPoint scrollOffset = m_data->viewStart;    wxPoint orig(scrollOffset);    wxPoint newScrollOffset(scrollPoint);    wxRect vRect(win->GetVirtualSize());    wxRect cRect(win->GetClientSize());    // clamp to scroll area    if (newScrollOffset.x < 0)        newScrollOffset.x = 0;    else if (newScrollOffset.x + cRect.width > vRect.width)        newScrollOffset.x = max(0, vRect.width - cRect.width - 1);    if (newScrollOffset.y < 0)        newScrollOffset.y = 0;    else if (newScrollOffset.y + cRect.height > vRect.height)        newScrollOffset.y = max(0, vRect.height - cRect.height - 1);    if (newScrollOffset == scrollOffset)        return;    m_data->viewStart = newScrollOffset;    wxPoint delta(orig - newScrollOffset);    if (canBlitOnScroll())        win->ScrollWindow(delta.x, delta.y);    else        win->Refresh();    adjustScrollbars();}bool ScrollView::platformScroll(ScrollDirection, ScrollGranularity){    notImplemented();    return true;}void ScrollView::platformSetContentsSize(){    wxWindow* win = platformWidget();    if (!win)        return;    win->SetVirtualSize(m_contentsSize.width(), m_contentsSize.height());    adjustScrollbars();}void ScrollView::adjustScrollbars(int x, int y, bool refresh){    wxWindow* win = platformWidget();    if (!win)        return;    wxRect crect(win->GetClientRect()), vrect(win->GetVirtualSize());    if (x == -1) x = m_data->viewStart.x;    if (y == -1) y = m_data->viewStart.y;    long style = win->GetWindowStyle();    // by setting the wxALWAYS_SHOW_SB wxWindow flag before    // each SetScrollbar call, we can control the scrollbars    // visibility individually.    // horizontal scrollbar    switch (m_data->hScrollbarMode) {        case ScrollbarAlwaysOff:            win->SetWindowStyleFlag(style & ~wxALWAYS_SHOW_SB);            win->SetScrollbar(wxHORIZONTAL, 0, 0, 0, refresh);            break;        case ScrollbarAuto:            win->SetWindowStyleFlag(style & ~wxALWAYS_SHOW_SB);            win->SetScrollbar(wxHORIZONTAL, x, crect.width, vrect.width, refresh);            break;        default: // ScrollbarAlwaysOn            win->SetWindowStyleFlag(style | wxALWAYS_SHOW_SB);            win->SetScrollbar(wxHORIZONTAL, x, crect.width, vrect.width, refresh);            break;    }    // vertical scrollbar    switch (m_data->vScrollbarMode) {        case ScrollbarAlwaysOff:            win->SetWindowStyleFlag(style & ~wxALWAYS_SHOW_SB);            win->SetScrollbar(wxVERTICAL, 0, 0, 0, refresh);            break;        case ScrollbarAlwaysOn:            win->SetWindowStyleFlag(style | wxALWAYS_SHOW_SB);            win->SetScrollbar(wxVERTICAL, y, crect.height, vrect.height, refresh);            break;        default: // case ScrollbarAuto:            win->SetWindowStyleFlag(style & ~wxALWAYS_SHOW_SB);            win->SetScrollbar(wxVERTICAL, y, crect.height, vrect.height, refresh);    }}void ScrollView::platformSetScrollbarModes(){    bool needsAdjust = false;    if (m_data->hScrollbarMode != horizontalScrollbarMode() ) {        m_data->hScrollbarMode = horizontalScrollbarMode();        needsAdjust = true;    }    if (m_data->vScrollbarMode != horizontalScrollbarMode() ) {        m_data->vScrollbarMode = horizontalScrollbarMode();        needsAdjust = true;    }    if (needsAdjust)        adjustScrollbars();}void ScrollView::platformScrollbarModes(ScrollbarMode& horizontal, ScrollbarMode& vertical) const{    horizontal = m_data->hScrollbarMode;    vertical = m_data->vScrollbarMode;}void ScrollView::platformSetCanBlitOnScroll(bool canBlitOnScroll){    m_canBlitOnScroll = canBlitOnScroll;}bool ScrollView::platformCanBlitOnScroll() const{    return m_canBlitOnScroll;}// used for subframes supportvoid ScrollView::platformAddChild(Widget* widget){    // NB: In all cases I'm aware of,    // by the time this is called the ScrollView is already a child    // of its parent Widget by wx port APIs, so I don't think    // we need to do anything here.}void ScrollView::platformRemoveChild(Widget* widget){    if (platformWidget()) {        platformWidget()->RemoveChild(widget->platformWidget());        // FIXME: Is this the right place to do deletion? I see        // detachFromParent2/3/4, initiated by FrameLoader::detachFromParent,        // but I'm not sure if it's better to handle there or not.        widget->platformWidget()->Destroy();    }}IntRect ScrollView::platformContentsToScreen(const IntRect& rect) const{    if (platformWidget()) {        wxRect wxrect = rect;        platformWidget()->ClientToScreen(&wxrect.x, &wxrect.y);        return wxrect;    }    return IntRect();}IntPoint ScrollView::platformScreenToContents(const IntPoint& point) const{    if (platformWidget()) {        return platformWidget()->ScreenToClient(point);    }    return IntPoint();}bool ScrollView::platformIsOffscreen() const{    return !platformWidget() || !platformWidget()->IsShownOnScreen();}}

⌨️ 快捷键说明

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