Files
libreoffice/sw/source/ui/misc/swruler.cxx
Rodolfo Ribeiro Gomes 55716b1ed9 Highlight fade in SwCommentRuler
It was not implemented, though designed.
No delay was used before start fading. I don't think it flickers.

https://wiki.documentfoundation.org/Design/Whiteboards/Comments_Ruler_Control#Behavior

Change-Id: I419220aac0a9cbfae328874cf6015d9530b93784
Signed-off-by: Rodolfo Ribeiro Gomes <rodolforg@gmail.com>
Reviewed-on: https://gerrit.libreoffice.org/6706
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
2013-11-20 06:07:04 -06:00

302 lines
9.9 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
// FIX fdo#38246 https://bugs.libreoffice.org/show_bug.cgi?id=38246
// Design proposal: https://wiki.documentfoundation.org/Design/Whiteboards/Comments_Ruler_Control
// TODO Alpha blend border when it doesn't fit in window
#include "swruler.hxx"
#include "viewsh.hxx"
#include "edtwin.hxx"
#include "PostItMgr.hxx"
#include "viewopt.hxx"
#include <view.hxx>
#include "cmdid.h"
#include <sfx2/request.hxx>
#include <vcl/svapp.hxx>
#include <vcl/window.hxx>
#include "misc.hrc"
#define CONTROL_BORDER_WIDTH 1
#define CONTROL_LEFT_OFFSET 6
#define CONTROL_RIGHT_OFFSET 3
#define CONTROL_TOP_OFFSET 4
#define CONTROL_TRIANGLE_WIDTH 4
#define CONTROL_TRIANGLE_PAD 3
// Constructor
SwCommentRuler::SwCommentRuler( SwViewShell* pViewSh, Window* pParent, SwEditWin* pWin, sal_uInt16 nRulerFlags, SfxBindings& rBindings, WinBits nWinStyle)
: SvxRuler(pParent, pWin, nRulerFlags, rBindings, nWinStyle | WB_HSCROLL)
, mpViewShell(pViewSh)
, mpSwWin(pWin)
, mbIsHighlighted(false)
, mnFadeRate(0)
, maVirDev( *this )
{
// Set fading timeout: 5 x 40ms = 200ms
maFadeTimer.SetTimeout(40);
maFadeTimer.SetTimeoutHdl( LINK( this, SwCommentRuler, FadeHandler ) );
}
// Destructor
SwCommentRuler::~SwCommentRuler()
{
}
void SwCommentRuler::Paint( const Rectangle& rRect )
{
SvxRuler::Paint( rRect );
// Don't draw if there is not any note
if ( mpViewShell->GetPostItMgr()->HasNotes() )
DrawCommentControl();
}
void SwCommentRuler::DrawCommentControl()
{
const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
bool bIsCollapsed = ! mpViewShell->GetPostItMgr()->ShowNotes();
Rectangle aControlRect = GetCommentControlRegion();
maVirDev.SetOutputSizePixel( aControlRect.GetSize() );
// Paint comment control background
// TODO Check if these are best colors to be used
Color aBgColor = GetFadedColor( rStyleSettings.GetDarkShadowColor(), rStyleSettings.GetWorkspaceColor() );
maVirDev.SetFillColor( aBgColor );
if ( mbIsHighlighted || !bIsCollapsed )
{
// Draw borders
maVirDev.SetLineColor( rStyleSettings.GetShadowColor() );
}
else
{
// No borders
maVirDev.SetLineColor();
}
maVirDev.DrawRect( Rectangle( Point(), aControlRect.GetSize() ) );
// Label and arrow tip
OUString aLabel( SW_RESSTR ( STR_COMMENTS_LABEL ) );
// Get label and arrow coordinates
Point aLabelPos;
Point aArrowPos;
bool bArrowToRight;
// TODO Discover why it should be 0 instead of CONTROL_BORDER_WIDTH + CONTROL_TOP_OFFSET
aLabelPos.Y() = 0;
aArrowPos.Y() = CONTROL_BORDER_WIDTH + CONTROL_TOP_OFFSET;
if ( !Application::GetSettings().GetLayoutRTL() )
{
// LTR
if ( bIsCollapsed )
{
// It should draw something like | > Comments |
aLabelPos.X() = CONTROL_LEFT_OFFSET + CONTROL_TRIANGLE_WIDTH + CONTROL_TRIANGLE_PAD;
aArrowPos.X() = CONTROL_LEFT_OFFSET;
}
else
{
// It should draw something like | Comments < |
aLabelPos.X() = CONTROL_LEFT_OFFSET;
aArrowPos.X() = aControlRect.GetSize().Width() - 1 - CONTROL_RIGHT_OFFSET - CONTROL_BORDER_WIDTH - CONTROL_TRIANGLE_WIDTH;
}
bArrowToRight = bIsCollapsed;
}
else
{
// RTL
long nLabelWidth = GetTextWidth( aLabel );
if ( bIsCollapsed )
{
// It should draw something like | Comments < |
aArrowPos.X() = aControlRect.GetSize().Width() - 1 - CONTROL_RIGHT_OFFSET - CONTROL_BORDER_WIDTH - CONTROL_TRIANGLE_WIDTH;
aLabelPos.X() = aArrowPos.X() - CONTROL_TRIANGLE_PAD - nLabelWidth;
}
else
{
// It should draw something like | > Comments |
aLabelPos.X() = aControlRect.GetSize().Width() - 1 - CONTROL_RIGHT_OFFSET - CONTROL_BORDER_WIDTH - nLabelWidth;
aArrowPos.X() = CONTROL_LEFT_OFFSET;
}
bArrowToRight = !bIsCollapsed;
}
// Draw label
Color aTextColor = GetFadedColor( rStyleSettings.GetButtonTextColor(), rStyleSettings.GetDeactiveTextColor() );
maVirDev.SetTextColor( aTextColor );
// FIXME Expected font size?
maVirDev.DrawText( aLabelPos, aLabel );
// Draw arrow
// FIXME consistence of button colors. http://opengrok.libreoffice.org/xref/core/vcl/source/control/button.cxx#785
Color aArrowColor = GetFadedColor( Color( COL_BLACK ), rStyleSettings.GetShadowColor() );
ImplDrawArrow ( aArrowPos.X(), aArrowPos.Y(), aArrowColor, bArrowToRight );
// Blit comment control
DrawOutDev( aControlRect.TopLeft(), aControlRect.GetSize(), Point(), aControlRect.GetSize(), maVirDev );
}
void SwCommentRuler::ImplDrawArrow(long nX, long nY, const Color& rColor, bool bPointRight)
{
maVirDev.SetLineColor();
maVirDev.SetFillColor( rColor );
if ( bPointRight )
{
maVirDev.DrawRect( Rectangle( nX+0, nY+0, nX+0, nY+6 ) );
maVirDev.DrawRect( Rectangle( nX+1, nY+1, nX+1, nY+5 ) );
maVirDev.DrawRect( Rectangle( nX+2, nY+2, nX+2, nY+4 ) );
maVirDev.DrawRect( Rectangle( nX+3, nY+3, nX+3, nY+3 ) );
}
else
{
maVirDev.DrawRect( Rectangle( nX+0, nY+3, nX+0, nY+3 ) );
maVirDev.DrawRect( Rectangle( nX+1, nY+2, nX+1, nY+4 ) );
maVirDev.DrawRect( Rectangle( nX+2, nY+1, nX+2, nY+5 ) );
maVirDev.DrawRect( Rectangle( nX+3, nY+0, nX+3, nY+6 ) );
}
}
// Just accept double-click outside comment control
void SwCommentRuler::Command( const CommandEvent& rCEvt )
{
Point aMousePos = rCEvt.GetMousePosPixel();
// Ignore command request if it is inside Comment Control
if ( !mpViewShell->GetPostItMgr()
|| !mpViewShell->GetPostItMgr()->HasNotes()
|| !GetCommentControlRegion().IsInside( aMousePos ) )
SvxRuler::Command( rCEvt );
}
void SwCommentRuler::MouseMove(const MouseEvent& rMEvt)
{
SvxRuler::MouseMove(rMEvt);
if ( ! mpViewShell->GetPostItMgr() || ! mpViewShell->GetPostItMgr()->HasNotes() )
return;
Point aMousePos = rMEvt.GetPosPixel();
bool bWasHighlighted = mbIsHighlighted;
mbIsHighlighted = GetCommentControlRegion().IsInside( aMousePos );
if ( mbIsHighlighted != bWasHighlighted )
{
// Set proper help text
if ( mbIsHighlighted )
{
// Mouse over comment control
UpdateCommentHelpText();
}
else
{
// Mouse out of comment control
// FIXME Should remember previous tooltip text?
SetQuickHelpText( OUString() );
}
// Do start fading
maFadeTimer.Start();
}
}
void SwCommentRuler::MouseButtonDown( const MouseEvent& rMEvt )
{
Point aMousePos = rMEvt.GetPosPixel();
if ( !rMEvt.IsLeft() || IsTracking() || !GetCommentControlRegion().IsInside( aMousePos ) )
{
SvxRuler::MouseButtonDown(rMEvt);
return;
}
// Toggle notes visibility
SwView &rView = mpSwWin->GetView();
SfxRequest aRequest( rView.GetViewFrame(), FN_VIEW_NOTES );
rView.ExecViewOptions( aRequest );
// It is inside comment control, so update help text
UpdateCommentHelpText();
Invalidate();
}
void SwCommentRuler::Update()
{
Rectangle aPreviousControlRect = GetCommentControlRegion();
SvxRuler::Update();
if (aPreviousControlRect != GetCommentControlRegion())
Invalidate();
}
void SwCommentRuler::UpdateCommentHelpText()
{
int nTooltipResId;
if ( mpViewShell->GetPostItMgr()->ShowNotes() )
nTooltipResId = STR_HIDE_COMMENTS;
else
nTooltipResId = STR_SHOW_COMMENTS;
SetQuickHelpText( OUString( SW_RESSTR( nTooltipResId ) ) );
}
// TODO Make Ruler return its central rectangle instead of margins.
Rectangle SwCommentRuler::GetCommentControlRegion()
{
long nLeft = 0;
SwPostItMgr *pPostItMgr = mpViewShell->GetPostItMgr();
//rhbz#1006850 When the SwPostItMgr ctor is called from SwView::SwView it
//triggers an update of the uiview, but the result of the ctor hasn't been
//set into the mpViewShell yet, so GetPostItMgr is temporarily still NULL
if (!pPostItMgr)
return Rectangle();
unsigned long nSidebarWidth = pPostItMgr->GetSidebarWidth(true);
//FIXME When the page width is larger then screen, the ruler is misplaced by one pixel
if (GetTextRTL())
nLeft = GetPageOffset() - nSidebarWidth + GetBorderOffset();
else
nLeft = GetWinOffset() + GetPageOffset() + mpSwWin->LogicToPixel(Size(GetPageWidth(), 0)).Width();
long nTop = 0 + 4; // Ruler::ImplDraw uses RULER_OFF (value: 3px) as offset, and Ruler::ImplFormat adds one extra pixel
// Somehow pPostItMgr->GetSidebarBorderWidth() returns border width already doubled
long nRight = nLeft + nSidebarWidth + pPostItMgr->GetSidebarBorderWidth(true);
long nBottom = nTop + GetRulerVirHeight() - 3;
Rectangle aRect(nLeft, nTop, nRight, nBottom);
return aRect;
}
Color SwCommentRuler::GetFadedColor(const Color &rHighColor, const Color &rLowColor)
{
if ( ! maFadeTimer.IsActive() )
return mbIsHighlighted ? rHighColor : rLowColor;
Color aColor = rHighColor;
aColor.Merge( rLowColor, mnFadeRate * 255/100.f );
return aColor;
}
IMPL_LINK_NOARG(SwCommentRuler, FadeHandler)
{
const int nStep = 25;
if ( mbIsHighlighted && mnFadeRate < 100 )
mnFadeRate += nStep;
else if ( !mbIsHighlighted && mnFadeRate > 0 )
mnFadeRate -= nStep;
else
return 0;
Invalidate();
if ( mnFadeRate != 0 && mnFadeRate != 100)
maFadeTimer.Start();
return 0;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */