/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * 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/. */ #include #include #include #include #include #include #include SwContentControlButton::SwContentControlButton(SwEditWin* pEditWin, std::shared_ptr pContentControl) : Control(pEditWin, WB_DIALOGCONTROL) , m_pContentControl(std::move(pContentControl)) { assert(GetParent()); assert(dynamic_cast(GetParent())); SetBackground(); EnableChildTransparentMode(); SetParentClipMode(ParentClipMode::NoClip); SetPaintTransparent(true); } SwContentControlButton::~SwContentControlButton() { disposeOnce(); } void SwContentControlButton::LaunchPopup() { m_xPopup->connect_closed(LINK(this, SwContentControlButton, PopupModeEndHdl)); tools::Rectangle aRect(Point(0, 0), GetSizePixel()); weld::Window* pParent = weld::GetPopupParent(*this, aRect); m_xPopup->popup_at_rect(pParent, aRect); } void SwContentControlButton::DestroyPopup() { m_xPopup.reset(); m_xPopupBuilder.reset(); } void SwContentControlButton::dispose() { DestroyPopup(); Control::dispose(); } void SwContentControlButton::CalcPosAndSize(const SwRect& rPortionPaintArea) { assert(GetParent()); Point aBoxPos = GetParent()->LogicToPixel(rPortionPaintArea.Pos()); Size aBoxSize = GetParent()->LogicToPixel(rPortionPaintArea.SSize()); // First calculate the size of the frame around the content control's last portion int nPadding = aBoxSize.Height() / 4; aBoxPos.AdjustX(-nPadding / 2); aBoxPos.AdjustY(-1); aBoxSize.AdjustWidth(nPadding); aBoxSize.AdjustHeight(2); m_aFramePixel = tools::Rectangle(aBoxPos, aBoxSize); // Then extend the size with the button area if (m_bRTL) { aBoxPos.AdjustX(-GetParent()->LogicToPixel(rPortionPaintArea.SSize()).Height()); } aBoxSize.AdjustWidth(GetParent()->LogicToPixel(rPortionPaintArea.SSize()).Height()); if (aBoxPos != GetPosPixel() || aBoxSize != GetSizePixel()) { SetPosSizePixel(aBoxPos, aBoxSize); Invalidate(); } } void SwContentControlButton::MouseButtonDown(const MouseEvent&) { StartPopup(); } void SwContentControlButton::StartPopup() { if (m_xPopup) // tdf#152257 already launched, don't relaunch return; LaunchPopup(); Invalidate(); } IMPL_LINK_NOARG(SwContentControlButton, PopupModeEndHdl, weld::Popover&, void) { DestroyPopup(); Show(false); Invalidate(); } void SwContentControlButton::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&) { SetMapMode(MapMode(MapUnit::MapPixel)); Color aLineColor = COL_BLACK; Color aFillColor = aLineColor; aFillColor.IncreaseLuminance(255 * (m_xPopup ? 0.5 : 0.75)); // Calc the frame around the content control's last portion int nPadding = 1; Point aPos(nPadding, nPadding); Size aSize(m_aFramePixel.GetSize().Width() - nPadding, m_aFramePixel.GetSize().Height() - nPadding); const tools::Rectangle aFrameRect(tools::Rectangle(aPos, aSize)); // Draw the button next to the frame Point aButtonPos(aFrameRect.TopLeft()); if (m_bRTL) { aButtonPos.AdjustX(nPadding * 2); } else { aButtonPos.AdjustX(aFrameRect.GetSize().getWidth() - nPadding * 2); } Size aButtonSize(aFrameRect.GetSize()); aButtonSize.setWidth(GetSizePixel().getWidth() - aFrameRect.getOpenWidth() - nPadding); const tools::Rectangle aButtonRect(tools::Rectangle(aButtonPos, aButtonSize)); // Background & border rRenderContext.SetLineColor(aLineColor); rRenderContext.SetFillColor(aFillColor); rRenderContext.DrawRect(aButtonRect); // the arrowhead DecorationView aDecoView(&rRenderContext); tools::Rectangle aSymbolRect(aButtonRect); // 20% distance to the left and right button border const tools::Long nBorderDistanceLeftAndRight = aSymbolRect.GetWidth() / 4; aSymbolRect.AdjustLeft(nBorderDistanceLeftAndRight); aSymbolRect.AdjustRight(-nBorderDistanceLeftAndRight); // 20% distance to the top and bottom button border const tools::Long nBorderDistanceTopAndBottom = aSymbolRect.GetHeight() / 4; aSymbolRect.AdjustTop(nBorderDistanceTopAndBottom); aSymbolRect.AdjustBottom(-nBorderDistanceTopAndBottom); AntialiasingFlags eAntialiasing = rRenderContext.GetAntialiasing(); if (SwDrawView::IsAntiAliasing()) { rRenderContext.SetAntialiasing(eAntialiasing | AntialiasingFlags::Enable); } aDecoView.DrawSymbol(aSymbolRect, SymbolType::SPIN_DOWN, GetTextColor(), DrawSymbolFlags::NONE); if (SwDrawView::IsAntiAliasing()) { rRenderContext.SetAntialiasing(eAntialiasing); } } WindowHitTest SwContentControlButton::ImplHitTest(const Point& rFramePos) { // We need to check whether the position hits the button (the frame should be mouse transparent) WindowHitTest aResult = Control::ImplHitTest(rFramePos); if (aResult != WindowHitTest::Inside) return aResult; else { if (m_bRTL) { return rFramePos.X() <= m_aFramePixel.Left() ? WindowHitTest::Inside : WindowHitTest::Transparent; } return rFramePos.X() >= m_aFramePixel.Right() ? WindowHitTest::Inside : WindowHitTest::Transparent; } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */