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>
302 lines
9.9 KiB
C++
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: */
|