diff -r 000000000000 -r dd21522fd290 webengine/osswebengine/WebKit/s60/webview/WebScrollbarDrawer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webengine/osswebengine/WebKit/s60/webview/WebScrollbarDrawer.cpp Mon Mar 30 12:54:55 2009 +0300 @@ -0,0 +1,470 @@ +/* +* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + + +#include <../bidi.h> +#include +#include +#include "WebScrollbarDrawer.h" +#include "WebView.h" +#include "WebFrame.h" +#include "WebFrameView.h" +#include "BrCtl.h" +#include "StaticObjectsContainer.h" +#include "WebSurface.h" + +#include "WebKitLogger.h" + +const int KScrollbarWidth = 15; +const TUint32 KMinScrollBarTransparency = 150; +const int KScrollBarFadeInterval = 30000; +const TInt32 KScrollBarTransparencyStep = 10; +const int KMinThumbSize = 30; + +int handleFadeScrollBar(TAny* ptr); + +using namespace WebCore; + +WebScrollbarDrawer* WebScrollbarDrawer::NewL() +{ + WebScrollbarDrawer* self = new(ELeave) WebScrollbarDrawer(); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); //self + return self; +} + + +void WebScrollbarDrawer::ConstructL() +{ + m_scrollBarFader = CPeriodic::NewL(CActive::EPriorityStandard); +} + + + +WebScrollbarDrawer::WebScrollbarDrawer(): + m_webView(NULL), + m_scrollBarTransparency(KMinScrollBarTransparency), + m_scrollBarWidth(KScrollbarWidth), + m_dX(0), m_dY(0) +{ +} + + + +WebScrollbarDrawer::~WebScrollbarDrawer() +{ + if (m_scrollBarFader) { + m_scrollBarFader->Cancel(); + } + delete m_scrollBarFader; + + removeBitmaps(); +} + + +void WebScrollbarDrawer::removeBitmaps() +{ + deleteBitmap(m_scrollBarV, m_gcV, m_devV); + deleteBitmap(m_scrollBarVMask, m_gcVMask, m_devVMask); + + deleteBitmap(m_scrollBarH, m_gcH, m_devH); + deleteBitmap(m_scrollBarHMask, m_gcHMask, m_devHMask); + +} + +TInt WebScrollbarDrawer::InitScrollbar(WebView* view) +{ + TInt err = KErrNone; + m_hasVScroll = EFalse; + m_hasHScroll = EFalse; + m_webView = view; + m_scrollBarTransparency = KMinScrollBarTransparency; + m_dY = 0.0; + m_dX = 0.0; + calculateBitmapRects(); + + err = SetupBitmaps(); + + if (err == KErrNone) { + constructSprite(m_spriteV, m_rectVThum.iTl, m_scrollBarV, m_scrollBarVMask); + constructSprite(m_spriteH, m_rectHThum.iTl, m_scrollBarH, m_scrollBarHMask); + } + + return err; +} + + +int WebScrollbarDrawer::fadeTime() +{ + return KScrollBarFadeInterval; +} + +void WebScrollbarDrawer::fadeScrollbar() +{ + if (m_hasVScroll || m_hasHScroll) { + if (!m_scrollBarFader->IsActive()) { + m_scrollBarFader->Start(0, KScrollBarFadeInterval, + TCallBack(&handleFadeScrollBar, this)); + } + } + else { + m_scrollBarTransparency = 255; + fade(); + } +} + + +int handleFadeScrollBar(TAny* ptr) +{ + (static_cast(ptr))->fade(); + return EFalse; +} + + +void WebScrollbarDrawer::clearSprites() +{ + m_spriteV.Close(); + m_spriteH.Close(); +} + +void WebScrollbarDrawer::fade() +{ + m_scrollBarTransparency += KScrollBarTransparencyStep; + if (m_scrollBarTransparency >= 255) { + m_scrollBarFader->Cancel(); + clearSprites(); + removeBitmaps(); + if (m_webView) { + m_webView->syncRepaint(m_webView->mainFrame()->frameView()->visibleRect()); + m_webView = NULL; + } + m_hasVScroll = EFalse; + m_hasHScroll = EFalse; + } + else { + + if (m_hasVScroll) { + drawThumbMask(m_gcVMask, m_rectVThum); + updateSprite(m_spriteV, m_scrollBarV, m_scrollBarVMask); + } + + if (m_hasHScroll) { + drawThumbMask(m_gcHMask, m_rectHThum); + updateSprite(m_spriteH, m_scrollBarH, m_scrollBarHMask); + } + } +} + +void WebScrollbarDrawer::redrawScrollbar() +{ + TInt err = KErrNone; + calculateBitmapRects(); + removeBitmaps(); + err = SetupBitmaps(); + if (err == KErrNone) { + m_spriteV.SetPosition(m_rectVThum.iTl); + updateSprite(m_spriteV, m_scrollBarV, m_scrollBarVMask); + m_spriteH.SetPosition(m_rectHThum.iTl); + updateSprite(m_spriteH, m_scrollBarH, m_scrollBarHMask); + } + else { + clearSprites(); + } +} + +void WebScrollbarDrawer::drawScrollbar(WebView* view, TPoint& scrollPos) +{ + if (!(view->brCtl()->capabilities() & TBrCtlDefs::ECapabilityDisplayScrollBar)) { + return; + } + + if (m_scrollBarFader->IsActive()) { + m_scrollBarFader->Cancel(); + clearSprites(); + removeBitmaps(); + m_hasVScroll = EFalse; + m_hasHScroll = EFalse; + m_webView = NULL; + } + + if (!m_webView) { + InitScrollbar(view); + } + + if (!m_hasHScroll) { //set it only once + m_hasHScroll = (scrollPos.iX != 0) && (m_displayWidth < m_docWidth); + } + + if (!m_hasVScroll) { //set it only once + m_hasVScroll = (scrollPos.iY != 0) && (m_displayHeight < m_docHeight); + } + + if ((scrollPos.iY != 0) && (m_displayHeight < m_docHeight)) { + m_dY += m_zoomFactor * ((float)scrollPos.iY * (float)m_displayHeight ) / (float)m_docHeight / 100; + + if (m_rectVThum.iTl.iY + m_dY < m_rectV.iTl.iY) { + m_dY = m_rectV.iTl.iY - m_rectVThum.iTl.iY; + } + else if (m_rectVThum.iBr.iY + m_dY > m_rectV.iBr.iY) { + m_dY = m_rectV.iBr.iY - m_rectVThum.iBr.iY; + } + else if ((m_rectVThum.iTl.iY + m_dY == m_rectV.iTl.iY) || + (m_rectVThum.iBr.iY + m_dY == m_rectV.iBr.iY)) { + m_dY = 0.0; + } + + + if (Abs(m_dY) > 1) { + m_rectVThum.Move(0, m_dY); + m_dY = 0.0; + } + + m_spriteV.SetPosition(m_rectVThum.iTl); + updateSprite(m_spriteV, m_scrollBarV, m_scrollBarVMask); + } + + + if ((scrollPos.iX != 0) && (m_displayWidth < m_docWidth)) { + m_dX = m_zoomFactor * ((float)scrollPos.iX * (float)m_displayWidth ) / (float)m_docWidth / 100; + + if (m_rectHThum.iTl.iX + m_dX < m_rectH.iTl.iX) { + m_dX = m_rectH.iTl.iX - m_rectHThum.iTl.iX; + } + else if (m_rectHThum.iBr.iX + m_dX > m_rectH.iBr.iX) { + m_dX = m_rectH.iBr.iX - m_rectHThum.iBr.iX; + } + else if ((m_rectHThum.iTl.iX + m_dX == m_rectH.iTl.iX) || + (m_rectHThum.iBr.iX + m_dX == m_rectH.iBr.iX)) { + m_dX = 0.0; + } + + + if (Abs(m_dX) > 1) { + m_rectHThum.Move(m_dX, 0); + } + + m_spriteH.SetPosition(m_rectHThum.iTl); + updateSprite(m_spriteH, m_scrollBarH, m_scrollBarHMask); + } + + + +} + +void WebScrollbarDrawer::constructSprite(RWsSprite& sprite, TPoint& pos, + CFbsBitmap* bitmap, CFbsBitmap* bitmapMask) +{ + sprite = RWsSprite(m_webView->brCtl()->CCoeControlParent()->ControlEnv()->WsSession()); + RDrawableWindow *window = (RDrawableWindow* )m_webView->brCtl()->CCoeControlParent()->DrawableWindow(); + sprite.Construct(*window, pos, ESpriteNoChildClip); + + TSpriteMember spriteMem; + spriteMem.iBitmap = 0;//bitmap; + spriteMem.iMaskBitmap = 0;//bitmapMask; + spriteMem.iInvertMask = EFalse; + + sprite.AppendMember(spriteMem); + sprite.Activate(); +} + +void WebScrollbarDrawer::updateSprite(RWsSprite& sprite, CFbsBitmap* bitmap, + CFbsBitmap* bitmapMask) +{ + TSpriteMember spriteMem; + spriteMem.iBitmap = bitmap; + spriteMem.iMaskBitmap = bitmapMask; + spriteMem.iInvertMask = ETrue; + sprite.UpdateMember(0, spriteMem); +} + +TInt WebScrollbarDrawer::createBitmap(CFbsBitmap*& bm, CFbsBitGc*& gc, + CFbsBitmapDevice*& dev, TRect& rect) +{ + TInt err = KErrNone; + bm = new CFbsBitmap(); + if (!bm) { + err = KErrNoMemory; + } + if (err == KErrNone) { + bm->Create(rect.Size(), EColor256); + } + TRAP(err, dev = CFbsBitmapDevice::NewL(bm)); + if (err == KErrNone && dev != NULL) { + err = dev->CreateContext(gc); + } + if (err != KErrNone) { + delete dev; + } + return err; +} + + +void WebScrollbarDrawer::deleteBitmap(CFbsBitmap*& bm, CFbsBitGc*& gc, + CFbsBitmapDevice*& dev) +{ + if (bm) { + delete bm; + bm = NULL; + } + + if (gc) { + delete gc; + gc = NULL; + } + + if (dev) { + delete dev; + dev = NULL; + } +} + +TInt WebScrollbarDrawer::SetupBitmaps() +{ + TInt err = KErrNone; + if (!m_scrollBarV) { + err = createBitmap(m_scrollBarV, m_gcV, m_devV, m_rectVThum); + } + + if (!m_scrollBarVMask && err == KErrNone) { + err = createBitmap(m_scrollBarVMask, m_gcVMask, m_devVMask, m_rectVThum); + } + + if (err == KErrNone) { + drawThumb(m_gcV, m_rectVThum); + drawThumbMask(m_gcVMask, m_rectVThum); + } + + if (!m_scrollBarH && err == KErrNone) { + err = createBitmap(m_scrollBarH, m_gcH, m_devH, m_rectHThum); + } + + if (!m_scrollBarHMask && err == KErrNone) { + err = createBitmap(m_scrollBarHMask, m_gcHMask, m_devHMask, m_rectHThum); + } + + if (err == KErrNone) { + drawThumb(m_gcH, m_rectHThum); + drawThumbMask(m_gcHMask, m_rectHThum); + } + + return err; +} + + +void WebScrollbarDrawer::calculateBitmapRects() +{ + m_zoomFactor = ((float)m_webView->scalingFactor() / 100); + m_rect.SetRect(m_webView->brCtl()->Rect().iTl, + m_webView->brCtl()->Rect().Size()); + int delta = 0; + int posX = m_zoomFactor * m_webView->mainFrame()->frameView()->contentPos().iX; + int posY = m_zoomFactor * m_webView->mainFrame()->frameView()->contentPos().iY; + m_docWidth = m_zoomFactor * m_webView->mainFrame()->frameView()->contentSize().iWidth; + m_displayWidth = m_rect.Width(); + m_docHeight = m_zoomFactor * m_webView->mainFrame()->frameView()->contentSize().iHeight; + m_displayHeight = m_rect.Height(); + + m_docHeight = (m_displayHeight > m_docHeight) ? m_displayHeight : m_docHeight; + m_docWidth = (m_displayWidth > m_docWidth) ? m_displayWidth : m_docWidth; + + bool shouldHaveHScroll = (m_displayWidth < m_docWidth); + bool shouldHaveVScroll = (m_displayHeight < m_docHeight); + TPoint vThumbTl; + TPoint hThumbTl; + + if (AknLayoutUtils::LayoutMirrored()) { + if (shouldHaveHScroll) { //horizontal scroll bar + delta = shouldHaveVScroll ? m_scrollBarWidth : 0; //to ajust thumb and scrollbar rect + m_rectH.SetRect(0 + delta, m_rect.Height() - m_scrollBarWidth, m_rect.Width(), m_rect.Height()); + hThumbTl.SetXY(m_scrollBarWidth + (posX * m_rectH.Width()) / m_docWidth, + m_rect.Height() - m_scrollBarWidth); + } + + if (shouldHaveVScroll) { + delta = shouldHaveHScroll ? m_scrollBarWidth : 0; //to ajust thumb and scrollbar rect + m_rectV.SetRect(0, 0, m_scrollBarWidth, m_rect.Height() - delta); + vThumbTl.SetXY(0, (posY * m_rectV.Height()) / m_docHeight); + } + } + else { + if (shouldHaveHScroll) { + delta = shouldHaveVScroll ? m_scrollBarWidth : 0; //to ajust thumb and scrollbar rect + m_rectH.SetRect(0, m_rect.Height() - m_scrollBarWidth, + m_rect.Width() - delta, m_rect.Height()); + hThumbTl.SetXY((posX * m_rectH.Width()) / m_docWidth, + m_rect.Height() - m_scrollBarWidth); + } + + if (shouldHaveVScroll) { + delta = shouldHaveHScroll ? m_scrollBarWidth : 0; //to ajust thumb and scrollbar rect + m_rectV.SetRect(m_rect.Width() - m_scrollBarWidth, 0, + m_rect.Width(), m_rect.Height() - delta); + vThumbTl.SetXY(m_rect.Width() - m_scrollBarWidth, + ((posY * m_rectV.Height()) / m_docHeight)); + } + } + + if (shouldHaveHScroll) { + int thW = ((float)m_rectH.Width() * m_displayWidth) / m_docWidth; + thW = (thW < KMinThumbSize) ? KMinThumbSize : thW; + m_rectHThum.SetRect(hThumbTl, TSize(thW, m_scrollBarWidth)); + if (m_rectHThum.iBr.iX > m_rectH.iBr.iX) { + m_rectHThum.Move(m_rectH.iBr.iX - m_rectHThum.iBr.iX, 0); + } + } + + if (shouldHaveVScroll) { + int thH = ((float)m_rectV.Height() * m_displayHeight) / m_docHeight; + thH = (thH < KMinThumbSize) ? KMinThumbSize : thH; + m_rectVThum.SetRect(vThumbTl, TSize(m_scrollBarWidth, thH)); + if (m_rectVThum.iBr.iY > m_rectV.iBr.iY) { + m_rectVThum.Move(0, m_rectV.iBr.iY - m_rectVThum.iBr.iY); + } + } +} + + +void WebScrollbarDrawer::drawThumb(CBitmapContext* gc, TRect& rect) +{ + TRect r(TPoint(0, 0), rect.Size()); + gc->SetBrushStyle(CGraphicsContext::ESolidBrush); + gc->SetPenStyle(CGraphicsContext::ESolidPen); + gc->SetPenSize(TSize(2,2)); + gc->SetPenColor(TRgb(242, 242, 242)); + gc->SetBrushColor(TRgb(10, 10, 10)); + gc->DrawRoundRect(r, TSize(7, 7)); + +} + + + +void WebScrollbarDrawer::drawThumbMask(CBitmapContext* gc, TRect& rect) +{ + TRect r(TPoint(0, 0), rect.Size()); + TRgb penMaskColor = TRgb(m_scrollBarTransparency, m_scrollBarTransparency, m_scrollBarTransparency); + TRgb brushMaskColor = TRgb(m_scrollBarTransparency, m_scrollBarTransparency, m_scrollBarTransparency);; + + gc->SetBrushStyle(CGraphicsContext::ESolidBrush); + gc->SetPenStyle(CGraphicsContext::ESolidPen); + gc->SetBrushColor(brushMaskColor); + gc->SetPenSize(TSize(2,2)); + gc->SetPenColor(TRgb(5, 5, 5)); + gc->DrawRoundRect(r, TSize(7, 7)); +} +