Get rid of ValueSet's internal VirtualDevice, draw to RenderContext

This improves support for Online HiDPI scenarios.

Change-Id: I1d4d13d8877b761cabaefa028dcd50d8345d9893
Reviewed-on: https://gerrit.libreoffice.org/63827
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
This commit is contained in:
Mike Kaganski
2018-11-22 15:20:16 +03:00
parent f23aa1a51c
commit 8ea1bdce62
2 changed files with 49 additions and 121 deletions

View File

@@ -197,8 +197,6 @@ typedef std::vector<std::unique_ptr<SvtValueSetItem>> SvtValueItemList;
class SVT_DLLPUBLIC ValueSet : public Control class SVT_DLLPUBLIC ValueSet : public Control
{ {
private: private:
ScopedVclPtr<VirtualDevice> maVirDev;
Timer maTimer; Timer maTimer;
ValueItemList mItemList; ValueItemList mItemList;
std::unique_ptr<ValueSetItem> mpNoneItem; std::unique_ptr<ValueSetItem> mpNoneItem;
@@ -248,11 +246,10 @@ private:
SVT_DLLPRIVATE void ImplInitScrollBar(); SVT_DLLPRIVATE void ImplInitScrollBar();
SVT_DLLPRIVATE void ImplDeleteItems(); SVT_DLLPRIVATE void ImplDeleteItems();
SVT_DLLPRIVATE void ImplFormatItem(vcl::RenderContext const & rRenderContext, ValueSetItem* pItem, tools::Rectangle aRect); SVT_DLLPRIVATE void ImplFormatItem(vcl::RenderContext& rRenderContext, ValueSetItem* pItem, tools::Rectangle aRect);
SVT_DLLPRIVATE void ImplDrawItemText(vcl::RenderContext& rRenderContext, const OUString& rStr); SVT_DLLPRIVATE void ImplDrawItemText(vcl::RenderContext& rRenderContext, const OUString& rStr);
SVT_DLLPRIVATE void ImplDrawSelect(vcl::RenderContext& rRenderContext, sal_uInt16 nItemId, const bool bFocus, const bool bDrawSel); SVT_DLLPRIVATE void ImplDrawSelect(vcl::RenderContext& rRenderContext, sal_uInt16 nItemId, const bool bFocus, const bool bDrawSel);
SVT_DLLPRIVATE void ImplDrawSelect(vcl::RenderContext& rRenderContext); SVT_DLLPRIVATE void ImplDrawSelect(vcl::RenderContext& rRenderContext);
SVT_DLLPRIVATE void ImplHideSelect(sal_uInt16 nItemId);
SVT_DLLPRIVATE void ImplHighlightItem(sal_uInt16 nItemId, bool bIsSelection = true); SVT_DLLPRIVATE void ImplHighlightItem(sal_uInt16 nItemId, bool bIsSelection = true);
SVT_DLLPRIVATE void ImplDraw(vcl::RenderContext& rRenderContext); SVT_DLLPRIVATE void ImplDraw(vcl::RenderContext& rRenderContext);
using Window::ImplScroll; using Window::ImplScroll;
@@ -273,6 +270,8 @@ private:
ValueSet (const ValueSet &) = delete; ValueSet (const ValueSet &) = delete;
ValueSet & operator= (const ValueSet &) = delete; ValueSet & operator= (const ValueSet &) = delete;
SVT_DLLPRIVATE void Format(vcl::RenderContext& rRenderContext);
protected: protected:
void StartDrag( const CommandEvent& rCEvt, vcl::Region& rRegion ); void StartDrag( const CommandEvent& rCEvt, vcl::Region& rRegion );
@@ -372,7 +371,6 @@ public:
void SetExtraSpacing( sal_uInt16 nNewSpacing ); void SetExtraSpacing( sal_uInt16 nNewSpacing );
void Format(vcl::RenderContext const & rRenderContext);
void SetFormat(); void SetFormat();
void StartSelection(); void StartSelection();

View File

@@ -59,7 +59,6 @@ enum
ValueSet::ValueSet( vcl::Window* pParent, WinBits nWinStyle ) : ValueSet::ValueSet( vcl::Window* pParent, WinBits nWinStyle ) :
Control( pParent, nWinStyle ), Control( pParent, nWinStyle ),
maVirDev( VclPtr<VirtualDevice>::Create(*this) ),
maColor( COL_TRANSPARENT ) maColor( COL_TRANSPARENT )
{ {
mpNoneItem.reset(nullptr); mpNoneItem.reset(nullptr);
@@ -93,9 +92,6 @@ ValueSet::ValueSet( vcl::Window* pParent, WinBits nWinStyle ) :
mbEdgeBlending = false; mbEdgeBlending = false;
mbHasVisibleItems = false; mbHasVisibleItems = false;
// #106446#, #106601# force mirroring of virtual device
maVirDev->EnableRTL( GetParent()->IsRTLEnabled() );
ImplInitSettings( true, true, true ); ImplInitSettings( true, true, true );
} }
@@ -203,7 +199,7 @@ void ValueSet::ImplInitScrollBar()
} }
} }
void ValueSet::ImplFormatItem(vcl::RenderContext const & rRenderContext, ValueSetItem* pItem, tools::Rectangle aRect) void ValueSet::ImplFormatItem(vcl::RenderContext& rRenderContext, ValueSetItem* pItem, tools::Rectangle aRect)
{ {
WinBits nStyle = GetStyle(); WinBits nStyle = GetStyle();
if (nStyle & WB_ITEMBORDER) if (nStyle & WB_ITEMBORDER)
@@ -224,7 +220,7 @@ void ValueSet::ImplFormatItem(vcl::RenderContext const & rRenderContext, ValueSe
} }
else else
{ {
DecorationView aView(maVirDev.get()); DecorationView aView(&rRenderContext);
aRect = aView.DrawFrame(aRect, mnFrameStyle); aRect = aView.DrawFrame(aRect, mnFrameStyle);
} }
} }
@@ -239,42 +235,45 @@ void ValueSet::ImplFormatItem(vcl::RenderContext const & rRenderContext, ValueSe
if (pItem == mpNoneItem.get()) if (pItem == mpNoneItem.get())
{ {
maVirDev->SetFont(rRenderContext.GetFont()); rRenderContext.SetTextColor((nStyle & WB_MENUSTYLEVALUESET)
maVirDev->SetTextColor((nStyle & WB_MENUSTYLEVALUESET) ? rStyleSettings.GetMenuTextColor() : rStyleSettings.GetWindowTextColor()); ? rStyleSettings.GetMenuTextColor()
maVirDev->SetTextFillColor(); : rStyleSettings.GetWindowTextColor());
maVirDev->SetFillColor((nStyle & WB_MENUSTYLEVALUESET) ? rStyleSettings.GetMenuColor() : rStyleSettings.GetWindowColor()); rRenderContext.SetTextFillColor();
maVirDev->DrawRect(aRect); rRenderContext.SetFillColor((nStyle & WB_MENUSTYLEVALUESET)
? rStyleSettings.GetMenuColor()
: rStyleSettings.GetWindowColor());
rRenderContext.DrawRect(aRect);
Point aTxtPos(aRect.Left() + 2, aRect.Top()); Point aTxtPos(aRect.Left() + 2, aRect.Top());
long nTxtWidth = rRenderContext.GetTextWidth(pItem->maText); long nTxtWidth = rRenderContext.GetTextWidth(pItem->maText);
if ((aTxtPos.X() + nTxtWidth) > aRect.Right()) if ((aTxtPos.X() + nTxtWidth) > aRect.Right())
{ {
maVirDev->SetClipRegion(vcl::Region(aRect)); rRenderContext.SetClipRegion(vcl::Region(aRect));
maVirDev->DrawText(aTxtPos, pItem->maText); rRenderContext.DrawText(aTxtPos, pItem->maText);
maVirDev->SetClipRegion(); rRenderContext.SetClipRegion();
} }
else else
maVirDev->DrawText(aTxtPos, pItem->maText); rRenderContext.DrawText(aTxtPos, pItem->maText);
} }
else if (pItem->meType == VALUESETITEM_COLOR) else if (pItem->meType == VALUESETITEM_COLOR)
{ {
maVirDev->SetFillColor(pItem->maColor); rRenderContext.SetFillColor(pItem->maColor);
maVirDev->DrawRect(aRect); rRenderContext.DrawRect(aRect);
} }
else else
{ {
if (IsColor()) if (IsColor())
maVirDev->SetFillColor(maColor); rRenderContext.SetFillColor(maColor);
else if (nStyle & WB_MENUSTYLEVALUESET) else if (nStyle & WB_MENUSTYLEVALUESET)
maVirDev->SetFillColor(rStyleSettings.GetMenuColor()); rRenderContext.SetFillColor(rStyleSettings.GetMenuColor());
else if (IsEnabled()) else if (IsEnabled())
maVirDev->SetFillColor(rStyleSettings.GetWindowColor()); rRenderContext.SetFillColor(rStyleSettings.GetWindowColor());
else else
maVirDev->SetFillColor(rStyleSettings.GetFaceColor()); rRenderContext.SetFillColor(rStyleSettings.GetFaceColor());
maVirDev->DrawRect(aRect); rRenderContext.DrawRect(aRect);
if (pItem->meType == VALUESETITEM_USERDRAW) if (pItem->meType == VALUESETITEM_USERDRAW)
{ {
UserDrawEvent aUDEvt(this, maVirDev.get(), aRect, pItem->mnId); UserDrawEvent aUDEvt(this, &rRenderContext, aRect, pItem->mnId);
UserDraw(aUDEvt); UserDraw(aUDEvt);
} }
else else
@@ -294,31 +293,30 @@ void ValueSet::ImplFormatItem(vcl::RenderContext const & rRenderContext, ValueSe
if (aImageSize.Width() > aRectSize.Width() || if (aImageSize.Width() > aRectSize.Width() ||
aImageSize.Height() > aRectSize.Height()) aImageSize.Height() > aRectSize.Height())
{ {
maVirDev->SetClipRegion(vcl::Region(aRect)); rRenderContext.SetClipRegion(vcl::Region(aRect));
maVirDev->DrawImage(aPos, pItem->maImage, nImageStyle); rRenderContext.DrawImage(aPos, pItem->maImage, nImageStyle);
maVirDev->SetClipRegion(); rRenderContext.SetClipRegion();
} }
else else
maVirDev->DrawImage(aPos, pItem->maImage, nImageStyle); rRenderContext.DrawImage(aPos, pItem->maImage, nImageStyle);
if (pItem->meType == VALUESETITEM_IMAGE_AND_TEXT) if (pItem->meType == VALUESETITEM_IMAGE_AND_TEXT)
{ {
maVirDev->SetFont(rRenderContext.GetFont()); rRenderContext.SetFont(rRenderContext.GetFont());
maVirDev->SetTextColor((nStyle & WB_MENUSTYLEVALUESET) ? rStyleSettings.GetMenuTextColor() : rStyleSettings.GetWindowTextColor()); rRenderContext.SetTextColor((nStyle & WB_MENUSTYLEVALUESET) ? rStyleSettings.GetMenuTextColor() : rStyleSettings.GetWindowTextColor());
maVirDev->SetTextFillColor(); rRenderContext.SetTextFillColor();
long nTxtWidth = maVirDev->GetTextWidth(pItem->maText); long nTxtWidth = rRenderContext.GetTextWidth(pItem->maText);
if (nTxtWidth > aRect.GetWidth()) if (nTxtWidth > aRect.GetWidth())
maVirDev->SetClipRegion(vcl::Region(aRect)); rRenderContext.SetClipRegion(vcl::Region(aRect));
maVirDev->DrawText(Point(aRect.Left() + rRenderContext.DrawText(Point(aRect.Left() + (aRect.GetWidth() - nTxtWidth) / 2,
(aRect.GetWidth() - nTxtWidth) / 2, aRect.Bottom() - rRenderContext.GetTextHeight()),
aRect.Bottom() - maVirDev->GetTextHeight()), pItem->maText);
pItem->maText);
if (nTxtWidth > aRect.GetWidth()) if (nTxtWidth > aRect.GetWidth())
maVirDev->SetClipRegion(); rRenderContext.SetClipRegion();
} }
} }
} }
@@ -334,7 +332,7 @@ void ValueSet::ImplFormatItem(vcl::RenderContext const & rRenderContext, ValueSe
if (!aBlendFrame.IsEmpty()) if (!aBlendFrame.IsEmpty())
{ {
maVirDev->DrawBitmapEx(aRect.TopLeft(), aBlendFrame); rRenderContext.DrawBitmapEx(aRect.TopLeft(), aBlendFrame);
} }
} }
} }
@@ -344,7 +342,7 @@ Reference<XAccessible> ValueSet::CreateAccessible()
return new ValueSetAcc( this ); return new ValueSetAcc( this );
} }
void ValueSet::Format(vcl::RenderContext const & rRenderContext) void ValueSet::Format(vcl::RenderContext& rRenderContext)
{ {
Size aWinSize(GetOutputSizePixel()); Size aWinSize(GetOutputSizePixel());
size_t nItemCount = mItemList.size(); size_t nItemCount = mItemList.size();
@@ -489,11 +487,6 @@ void ValueSet::Format(vcl::RenderContext const & rRenderContext)
mnItemHeight = nCalcHeight / mnVisLines; mnItemHeight = nCalcHeight / mnVisLines;
} }
// Init VirDev
maVirDev->SetSettings(rRenderContext.GetSettings());
maVirDev->SetBackground(rRenderContext.GetBackground());
maVirDev->SetOutputSizePixel(aWinSize);
// nothing is changed in case of too small items // nothing is changed in case of too small items
if ((mnItemWidth <= 0) || if ((mnItemWidth <= 0) ||
(mnItemHeight <= ((nStyle & WB_ITEMBORDER) ? 4 : 2)) || (mnItemHeight <= ((nStyle & WB_ITEMBORDER) ? 4 : 2)) ||
@@ -569,7 +562,7 @@ void ValueSet::Format(vcl::RenderContext const & rRenderContext)
} }
// calculate and draw items // calculate and draw items
maVirDev->SetLineColor(); rRenderContext.SetLineColor();
long x = nStartX; long x = nStartX;
long y = nStartY; long y = nStartY;
@@ -849,41 +842,11 @@ void ValueSet::ImplDrawSelect(vcl::RenderContext& rRenderContext, sal_uInt16 nIt
ImplDrawItemText(rRenderContext, pItem->maText); ImplDrawItemText(rRenderContext, pItem->maText);
} }
void ValueSet::ImplHideSelect( sal_uInt16 nItemId )
{
tools::Rectangle aRect;
const size_t nItemPos = GetItemPos( nItemId );
if ( nItemPos != VALUESET_ITEM_NOTFOUND )
{
if ( !mItemList[nItemPos]->mbVisible )
{
return;
}
aRect = ImplGetItemRect(nItemPos);
}
else
{
if (mpNoneItem == nullptr)
{
return;
}
aRect = maNoneItemRect;
}
HideFocus();
const Point aPos = aRect.TopLeft();
const Size aSize = aRect.GetSize();
DrawOutDev( aPos, aSize, aPos, aSize, *maVirDev.get() );
}
void ValueSet::ImplHighlightItem( sal_uInt16 nItemId, bool bIsSelection ) void ValueSet::ImplHighlightItem( sal_uInt16 nItemId, bool bIsSelection )
{ {
if ( mnHighItemId == nItemId ) if ( mnHighItemId == nItemId )
return; return;
// remember the old item to delete the previous selection
sal_uInt16 nOldItem = mnHighItemId;
mnHighItemId = nItemId; mnHighItemId = nItemId;
// don't draw the selection if nothing is selected // don't draw the selection if nothing is selected
@@ -891,40 +854,15 @@ void ValueSet::ImplHighlightItem( sal_uInt16 nItemId, bool bIsSelection )
mbDrawSelection = false; mbDrawSelection = false;
// remove the old selection and draw the new one // remove the old selection and draw the new one
ImplHideSelect( nOldItem );
Invalidate(); Invalidate();
mbDrawSelection = true; mbDrawSelection = true;
} }
void ValueSet::ImplDraw(vcl::RenderContext& rRenderContext) void ValueSet::ImplDraw(vcl::RenderContext& rRenderContext)
{ {
if (mbFormat) Format(rRenderContext);
Format(rRenderContext);
HideFocus(); HideFocus();
Point aDefPos;
Size aSize = maVirDev->GetOutputSizePixel();
if (mxScrollBar.get() && mxScrollBar->IsVisible())
{
Point aScrPos = mxScrollBar->GetPosPixel();
Size aScrSize = mxScrollBar->GetSizePixel();
Point aTempPos(0, aScrPos.Y());
Size aTempSize(aSize.Width(), aScrPos.Y());
rRenderContext.DrawOutDev(aDefPos, aTempSize, aDefPos, aTempSize, *maVirDev.get());
aTempSize.setWidth( aScrPos.X() - 1 );
aTempSize.setHeight( aScrSize.Height() );
rRenderContext.DrawOutDev(aTempPos, aTempSize, aTempPos, aTempSize, *maVirDev.get());
aTempPos.setY( aScrPos.Y() + aScrSize.Height() );
aTempSize.setWidth( aSize.Width() );
aTempSize.setHeight( aSize.Height() - aTempPos.Y() );
rRenderContext.DrawOutDev(aTempPos, aTempSize, aTempPos, aTempSize, *maVirDev.get());
}
else
rRenderContext.DrawOutDev(aDefPos, aSize, aDefPos, aSize, *maVirDev.get());
// draw parting line to the Namefield // draw parting line to the Namefield
if (GetStyle() & WB_NAMEFIELD) if (GetStyle() & WB_NAMEFIELD)
{ {
@@ -1377,9 +1315,6 @@ void ValueSet::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&
const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings(); const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
rRenderContext.SetLineColor(); rRenderContext.SetLineColor();
rRenderContext.SetFillColor(rStyleSettings.GetFaceColor()); rRenderContext.SetFillColor(rStyleSettings.GetFaceColor());
long nOffY = maVirDev->GetOutputSizePixel().Height();
Size aWinSize(GetOutputSizePixel());
rRenderContext.DrawRect(tools::Rectangle(Point(0, nOffY ), Point( aWinSize.Width(), aWinSize.Height())));
} }
ImplDraw(rRenderContext); ImplDraw(rRenderContext);
@@ -1400,9 +1335,7 @@ void ValueSet::GetFocus()
void ValueSet::LoseFocus() void ValueSet::LoseFocus()
{ {
SAL_INFO("svtools", "value set losing focus"); SAL_INFO("svtools", "value set losing focus");
if ( mbNoSelection && mnSelItemId ) if (!mbNoSelection || !mnSelItemId)
ImplHideSelect( mnSelItemId );
else
HideFocus(); HideFocus();
Control::LoseFocus(); Control::LoseFocus();
@@ -1796,7 +1729,6 @@ void ValueSet::SelectItem( sal_uInt16 nItemId )
else else
{ {
// remove old selection and draw the new one // remove old selection and draw the new one
ImplHideSelect( nOldItem );
Invalidate(); Invalidate();
} }
} }
@@ -1963,14 +1895,13 @@ void ValueSet::SetItemText(sal_uInt16 nItemId, const OUString& rText)
ValueSetItem* pItem = mItemList[nPos].get(); ValueSetItem* pItem = mItemList[nPos].get();
if (pItem->maText == rText)
return;
// Remember old and new name for accessibility event. // Remember old and new name for accessibility event.
Any aOldName; Any aOldName;
Any aNewName; Any aNewName;
OUString sString (pItem->maText); aOldName <<= pItem->maText;
aOldName <<= sString; aNewName <<= rText;
sString = rText;
aNewName <<= sString;
pItem->maText = rText; pItem->maText = rText;
@@ -2220,10 +2151,9 @@ Size ValueSet::GetLargestItemSize()
Size aSize = pItem->maImage.GetSizePixel(); Size aSize = pItem->maImage.GetSizePixel();
if (pItem->meType == VALUESETITEM_IMAGE_AND_TEXT) if (pItem->meType == VALUESETITEM_IMAGE_AND_TEXT)
{ {
aSize.AdjustHeight(3 * NAME_LINE_HEIGHT + aSize.AdjustHeight(3 * NAME_LINE_HEIGHT + GetTextHeight());
maVirDev->GetTextHeight() );
aSize.setWidth( std::max(aSize.Width(), aSize.setWidth( std::max(aSize.Width(),
maVirDev->GetTextWidth(pItem->maText) + NAME_OFFSET) ); GetTextWidth(pItem->maText) + NAME_OFFSET) );
} }
aLargestItem.setWidth( std::max(aLargestItem.Width(), aSize.Width()) ); aLargestItem.setWidth( std::max(aLargestItem.Width(), aSize.Width()) );