1999 lines
75 KiB
C++
1999 lines
75 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/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
*/
|
|
|
|
#include <strings.hrc>
|
|
#include <svdata.hxx>
|
|
#include <brdwin.hxx>
|
|
#include <salframe.hxx>
|
|
#include <window.h>
|
|
|
|
#include <vcl/textrectinfo.hxx>
|
|
#include <vcl/event.hxx>
|
|
#include <vcl/decoview.hxx>
|
|
#include <vcl/syswin.hxx>
|
|
#include <vcl/dockwin.hxx>
|
|
#include <vcl/toolkit/floatwin.hxx>
|
|
#include <vcl/help.hxx>
|
|
#include <vcl/toolkit/edit.hxx>
|
|
#include <vcl/settings.hxx>
|
|
#include <vcl/toolbox.hxx>
|
|
#include <vcl/ptrstyle.hxx>
|
|
|
|
using namespace ::com::sun::star::uno;
|
|
|
|
// useful caption height for title bar buttons
|
|
#define MIN_CAPTION_HEIGHT 18
|
|
|
|
namespace vcl {
|
|
|
|
void Window::ImplCalcSymbolRect( tools::Rectangle& rRect )
|
|
{
|
|
// Add border, not shown in the non-default representation,
|
|
// as we want to use it for small buttons
|
|
rRect.AdjustLeft( -1 );
|
|
rRect.AdjustTop( -1 );
|
|
rRect.AdjustRight( 1 );
|
|
rRect.AdjustBottom( 1 );
|
|
|
|
// we leave 5% room between the symbol and the button border
|
|
tools::Long nExtraWidth = ((rRect.GetWidth()*50)+500)/1000;
|
|
tools::Long nExtraHeight = ((rRect.GetHeight()*50)+500)/1000;
|
|
rRect.AdjustLeft(nExtraWidth );
|
|
rRect.AdjustRight( -nExtraWidth );
|
|
rRect.AdjustTop(nExtraHeight );
|
|
rRect.AdjustBottom( -nExtraHeight );
|
|
}
|
|
|
|
} /* namespace vcl */
|
|
|
|
static void ImplDrawBrdWinSymbol( vcl::RenderContext* pDev,
|
|
const tools::Rectangle& rRect, SymbolType eSymbol )
|
|
{
|
|
// we leave 5% room between the symbol and the button border
|
|
DecorationView aDecoView( pDev );
|
|
tools::Rectangle aTempRect = rRect;
|
|
vcl::Window::ImplCalcSymbolRect( aTempRect );
|
|
aDecoView.DrawSymbol( aTempRect, eSymbol,
|
|
pDev->GetSettings().GetStyleSettings().GetButtonTextColor() );
|
|
}
|
|
|
|
static void ImplDrawBrdWinSymbolButton( vcl::RenderContext* pDev,
|
|
const tools::Rectangle& rRect,
|
|
SymbolType eSymbol, DrawButtonFlags nState )
|
|
{
|
|
bool bMouseOver(nState & DrawButtonFlags::Highlight);
|
|
nState &= ~DrawButtonFlags::Highlight;
|
|
|
|
tools::Rectangle aTempRect;
|
|
vcl::Window *pWin = pDev->GetOwnerWindow();
|
|
if( pWin )
|
|
{
|
|
if( bMouseOver )
|
|
{
|
|
// provide a bright background for selection effect
|
|
pDev->SetFillColor( pDev->GetSettings().GetStyleSettings().GetWindowColor() );
|
|
pDev->SetLineColor();
|
|
pDev->DrawRect( rRect );
|
|
pWin->DrawSelectionBackground( rRect, 2, bool(nState & DrawButtonFlags::Pressed),
|
|
true );
|
|
}
|
|
aTempRect = rRect;
|
|
aTempRect.AdjustLeft(3 );
|
|
aTempRect.AdjustRight( -4 );
|
|
aTempRect.AdjustTop(3 );
|
|
aTempRect.AdjustBottom( -4 );
|
|
}
|
|
else
|
|
{
|
|
DecorationView aDecoView( pDev );
|
|
aTempRect = aDecoView.DrawButton( rRect, nState|DrawButtonFlags::Flat );
|
|
}
|
|
ImplDrawBrdWinSymbol( pDev, aTempRect, eSymbol );
|
|
}
|
|
|
|
|
|
ImplBorderWindowView::~ImplBorderWindowView()
|
|
{
|
|
}
|
|
|
|
bool ImplBorderWindowView::MouseMove( const MouseEvent& )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
bool ImplBorderWindowView::MouseButtonDown( const MouseEvent& )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
bool ImplBorderWindowView::Tracking( const TrackingEvent& )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
OUString ImplBorderWindowView::RequestHelp( const Point&, tools::Rectangle& )
|
|
{
|
|
return OUString();
|
|
}
|
|
|
|
tools::Rectangle ImplBorderWindowView::GetMenuRect() const
|
|
{
|
|
return tools::Rectangle();
|
|
}
|
|
|
|
void ImplBorderWindowView::ImplInitTitle(ImplBorderFrameData* pData)
|
|
{
|
|
ImplBorderWindow* pBorderWindow = pData->mpBorderWindow;
|
|
|
|
if ( !(pBorderWindow->GetStyle() & (WB_MOVEABLE | WB_POPUP)) ||
|
|
(pData->mnTitleType == BorderWindowTitleType::NONE) )
|
|
{
|
|
pData->mnTitleType = BorderWindowTitleType::NONE;
|
|
pData->mnTitleHeight = 0;
|
|
}
|
|
else
|
|
{
|
|
const StyleSettings& rStyleSettings = pData->mpOutDev->GetSettings().GetStyleSettings();
|
|
if (pData->mnTitleType == BorderWindowTitleType::Tearoff)
|
|
pData->mnTitleHeight = ToolBox::ImplGetDragWidth(*pData->mpBorderWindow, false) + 2;
|
|
else
|
|
{
|
|
if (pData->mnTitleType == BorderWindowTitleType::Small)
|
|
{
|
|
pBorderWindow->SetPointFont(*pBorderWindow->GetOutDev(), rStyleSettings.GetFloatTitleFont() );
|
|
pData->mnTitleHeight = rStyleSettings.GetFloatTitleHeight();
|
|
}
|
|
else // pData->mnTitleType == BorderWindowTitleType::Normal
|
|
{
|
|
// FIXME RenderContext
|
|
pBorderWindow->SetPointFont(*pBorderWindow->GetOutDev(), rStyleSettings.GetTitleFont());
|
|
pData->mnTitleHeight = rStyleSettings.GetTitleHeight();
|
|
}
|
|
tools::Long nTextHeight = pBorderWindow->GetTextHeight();
|
|
if (nTextHeight > pData->mnTitleHeight)
|
|
pData->mnTitleHeight = nTextHeight;
|
|
}
|
|
}
|
|
}
|
|
|
|
BorderWindowHitTest ImplBorderWindowView::ImplHitTest( ImplBorderFrameData const * pData, const Point& rPos )
|
|
{
|
|
ImplBorderWindow* pBorderWindow = pData->mpBorderWindow;
|
|
|
|
if ( pData->maTitleRect.Contains( rPos ) )
|
|
{
|
|
if ( pData->maCloseRect.Contains( rPos ) )
|
|
return BorderWindowHitTest::Close;
|
|
else if ( pData->maMenuRect.Contains( rPos ) )
|
|
return BorderWindowHitTest::Menu;
|
|
else if ( pData->maDockRect.Contains( rPos ) )
|
|
return BorderWindowHitTest::Dock;
|
|
else if ( pData->maHideRect.Contains( rPos ) )
|
|
return BorderWindowHitTest::Hide;
|
|
else if ( pData->maHelpRect.Contains( rPos ) )
|
|
return BorderWindowHitTest::Help;
|
|
else
|
|
return BorderWindowHitTest::Title;
|
|
}
|
|
|
|
if (pBorderWindow->GetStyle() & WB_SIZEABLE)
|
|
{
|
|
tools::Long nSizeWidth = pData->mnNoTitleTop+pData->mnTitleHeight;
|
|
if ( nSizeWidth < 16 )
|
|
nSizeWidth = 16;
|
|
|
|
// no corner resize for floating toolbars, which would lead to jumps while formatting
|
|
// setting nSizeWidth = 0 will only return pure left,top,right,bottom
|
|
if( pBorderWindow->GetStyle() & (WB_OWNERDRAWDECORATION | WB_POPUP) )
|
|
nSizeWidth = 0;
|
|
|
|
if ( rPos.X() < pData->mnLeftBorder )
|
|
{
|
|
if ( rPos.Y() < nSizeWidth )
|
|
return BorderWindowHitTest::TopLeft;
|
|
else if ( rPos.Y() >= pData->mnHeight-nSizeWidth )
|
|
return BorderWindowHitTest::BottomLeft;
|
|
else
|
|
return BorderWindowHitTest::Left;
|
|
}
|
|
else if ( rPos.X() >= pData->mnWidth-pData->mnRightBorder )
|
|
{
|
|
if ( rPos.Y() < nSizeWidth )
|
|
return BorderWindowHitTest::TopRight;
|
|
else if ( rPos.Y() >= pData->mnHeight-nSizeWidth )
|
|
return BorderWindowHitTest::BottomRight;
|
|
else
|
|
return BorderWindowHitTest::Right;
|
|
}
|
|
else if ( rPos.Y() < pData->mnNoTitleTop )
|
|
{
|
|
if ( rPos.X() < nSizeWidth )
|
|
return BorderWindowHitTest::TopLeft;
|
|
else if ( rPos.X() >= pData->mnWidth-nSizeWidth )
|
|
return BorderWindowHitTest::TopRight;
|
|
else
|
|
return BorderWindowHitTest::Top;
|
|
}
|
|
else if ( rPos.Y() >= pData->mnHeight-pData->mnBottomBorder )
|
|
{
|
|
if ( rPos.X() < nSizeWidth )
|
|
return BorderWindowHitTest::BottomLeft;
|
|
else if ( rPos.X() >= pData->mnWidth-nSizeWidth )
|
|
return BorderWindowHitTest::BottomRight;
|
|
else
|
|
return BorderWindowHitTest::Bottom;
|
|
}
|
|
}
|
|
|
|
return BorderWindowHitTest::NONE;
|
|
}
|
|
|
|
void ImplBorderWindowView::ImplMouseMove( ImplBorderFrameData* pData, const MouseEvent& rMEvt )
|
|
{
|
|
DrawButtonFlags oldCloseState = pData->mnCloseState;
|
|
DrawButtonFlags oldMenuState = pData->mnMenuState;
|
|
pData->mnCloseState &= ~DrawButtonFlags::Highlight;
|
|
pData->mnMenuState &= ~DrawButtonFlags::Highlight;
|
|
|
|
Point aMousePos = rMEvt.GetPosPixel();
|
|
BorderWindowHitTest nHitTest = ImplHitTest( pData, aMousePos );
|
|
PointerStyle ePtrStyle = PointerStyle::Arrow;
|
|
if ( nHitTest & BorderWindowHitTest::Left )
|
|
ePtrStyle = PointerStyle::WindowWSize;
|
|
else if ( nHitTest & BorderWindowHitTest::Right )
|
|
ePtrStyle = PointerStyle::WindowESize;
|
|
else if ( nHitTest & BorderWindowHitTest::Top )
|
|
ePtrStyle = PointerStyle::WindowNSize;
|
|
else if ( nHitTest & BorderWindowHitTest::Bottom )
|
|
ePtrStyle = PointerStyle::WindowSSize;
|
|
else if ( nHitTest & BorderWindowHitTest::TopLeft )
|
|
ePtrStyle = PointerStyle::WindowNWSize;
|
|
else if ( nHitTest & BorderWindowHitTest::BottomRight )
|
|
ePtrStyle = PointerStyle::WindowSESize;
|
|
else if ( nHitTest & BorderWindowHitTest::TopRight )
|
|
ePtrStyle = PointerStyle::WindowNESize;
|
|
else if ( nHitTest & BorderWindowHitTest::BottomLeft )
|
|
ePtrStyle = PointerStyle::WindowSWSize;
|
|
else if ( nHitTest & BorderWindowHitTest::Close )
|
|
pData->mnCloseState |= DrawButtonFlags::Highlight;
|
|
else if ( nHitTest & BorderWindowHitTest::Menu )
|
|
pData->mnMenuState |= DrawButtonFlags::Highlight;
|
|
else if ( nHitTest & BorderWindowHitTest::Title &&
|
|
pData->mnTitleType == BorderWindowTitleType::Tearoff && !rMEvt.IsLeaveWindow() )
|
|
ePtrStyle = PointerStyle::Move;
|
|
pData->mpBorderWindow->SetPointer( ePtrStyle );
|
|
|
|
if( pData->mnCloseState != oldCloseState )
|
|
pData->mpBorderWindow->Invalidate( pData->maCloseRect );
|
|
if( pData->mnMenuState != oldMenuState )
|
|
pData->mpBorderWindow->Invalidate( pData->maMenuRect );
|
|
}
|
|
|
|
OUString ImplBorderWindowView::ImplRequestHelp( ImplBorderFrameData const * pData,
|
|
const Point& rPos,
|
|
tools::Rectangle& rHelpRect )
|
|
{
|
|
TranslateId pHelpId;
|
|
OUString aHelpStr;
|
|
BorderWindowHitTest nHitTest = ImplHitTest( pData, rPos );
|
|
if ( nHitTest != BorderWindowHitTest::NONE )
|
|
{
|
|
if ( nHitTest & BorderWindowHitTest::Close )
|
|
{
|
|
pHelpId = SV_HELPTEXT_CLOSE;
|
|
rHelpRect = pData->maCloseRect;
|
|
}
|
|
else if ( nHitTest & BorderWindowHitTest::Dock )
|
|
{
|
|
pHelpId = SV_HELPTEXT_MAXIMIZE;
|
|
rHelpRect = pData->maDockRect;
|
|
}
|
|
else if ( nHitTest & BorderWindowHitTest::Hide )
|
|
{
|
|
pHelpId = SV_HELPTEXT_MINIMIZE;
|
|
rHelpRect = pData->maHideRect;
|
|
}
|
|
else if ( nHitTest & BorderWindowHitTest::Help )
|
|
{
|
|
pHelpId = SV_HELPTEXT_HELP;
|
|
rHelpRect = pData->maHelpRect;
|
|
}
|
|
else if ( nHitTest & BorderWindowHitTest::Title )
|
|
{
|
|
if( !pData->maTitleRect.IsEmpty() )
|
|
{
|
|
// tooltip only if title truncated
|
|
if( pData->mbTitleClipped )
|
|
{
|
|
rHelpRect = pData->maTitleRect;
|
|
// no help id, use window title as help string
|
|
aHelpStr = pData->mpBorderWindow->GetText();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (pHelpId)
|
|
aHelpStr = VclResId(pHelpId);
|
|
|
|
return aHelpStr;
|
|
}
|
|
|
|
tools::Long ImplBorderWindowView::ImplCalcTitleWidth( const ImplBorderFrameData* pData )
|
|
{
|
|
// title is not visible therefore no width
|
|
if ( !pData->mnTitleHeight )
|
|
return 0;
|
|
|
|
ImplBorderWindow* pBorderWindow = pData->mpBorderWindow;
|
|
tools::Long nTitleWidth = pBorderWindow->GetTextWidth( pBorderWindow->GetText() )+6;
|
|
auto nCloseRectWidth = pData->maCloseRect.GetWidth();
|
|
assert(nCloseRectWidth >= 0 && "coverity 2023.12.2");
|
|
nTitleWidth += nCloseRectWidth;
|
|
auto nDockRectWidth = pData->maDockRect.GetWidth();
|
|
assert(nDockRectWidth >= 0 && "coverity 2023.12.2");
|
|
nTitleWidth += nDockRectWidth;
|
|
auto nMenuRectWidth = pData->maMenuRect.GetWidth();
|
|
assert(nMenuRectWidth >= 0 && "coverity 2023.12.2");
|
|
nTitleWidth += nMenuRectWidth;
|
|
auto nHideRectWidth = pData->maHideRect.GetWidth();
|
|
assert(nHideRectWidth >= 0 && "coverity 2023.12.2");
|
|
nTitleWidth += nHideRectWidth;
|
|
auto nHelpRectWidth = pData->maHelpRect.GetWidth();
|
|
assert(nHelpRectWidth >= 0 && "coverity 2023.12.2");
|
|
nTitleWidth += nHelpRectWidth;
|
|
nTitleWidth += pData->mnLeftBorder+pData->mnRightBorder;
|
|
return nTitleWidth;
|
|
}
|
|
|
|
|
|
ImplNoBorderWindowView::ImplNoBorderWindowView()
|
|
{
|
|
}
|
|
|
|
void ImplNoBorderWindowView::Init( OutputDevice*, tools::Long, tools::Long )
|
|
{
|
|
}
|
|
|
|
void ImplNoBorderWindowView::GetBorder( sal_Int32& rLeftBorder, sal_Int32& rTopBorder,
|
|
sal_Int32& rRightBorder, sal_Int32& rBottomBorder ) const
|
|
{
|
|
rLeftBorder = 0;
|
|
rTopBorder = 0;
|
|
rRightBorder = 0;
|
|
rBottomBorder = 0;
|
|
}
|
|
|
|
tools::Long ImplNoBorderWindowView::CalcTitleWidth() const
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
void ImplNoBorderWindowView::DrawWindow(vcl::RenderContext&, const Point*)
|
|
{
|
|
}
|
|
|
|
ImplSmallBorderWindowView::ImplSmallBorderWindowView( ImplBorderWindow* pBorderWindow )
|
|
: mpBorderWindow(pBorderWindow)
|
|
, mpOutDev(nullptr)
|
|
, mnWidth(0)
|
|
, mnHeight(0)
|
|
, mnLeftBorder(0)
|
|
, mnTopBorder(0)
|
|
, mnRightBorder(0)
|
|
, mnBottomBorder(0)
|
|
, mbNWFBorder(false)
|
|
{
|
|
}
|
|
|
|
void ImplSmallBorderWindowView::Init( OutputDevice* pDev, tools::Long nWidth, tools::Long nHeight )
|
|
{
|
|
mpOutDev = pDev;
|
|
mnWidth = nWidth;
|
|
mnHeight = nHeight;
|
|
mbNWFBorder = false;
|
|
|
|
vcl::Window *pWin = mpOutDev->GetOwnerWindow();
|
|
vcl::Window *pCtrl = nullptr;
|
|
vcl::Window *pSubEdit = nullptr;
|
|
if (pWin)
|
|
pCtrl = mpBorderWindow->GetWindow(GetWindowType::Client);
|
|
|
|
tools::Long nOrigLeftBorder = mnLeftBorder;
|
|
tools::Long nOrigTopBorder = mnTopBorder;
|
|
tools::Long nOrigRightBorder = mnRightBorder;
|
|
tools::Long nOrigBottomBorder = mnBottomBorder;
|
|
|
|
WindowBorderStyle nBorderStyle = mpBorderWindow->GetBorderStyle();
|
|
if ( nBorderStyle & WindowBorderStyle::NOBORDER )
|
|
{
|
|
mnLeftBorder = 0;
|
|
mnTopBorder = 0;
|
|
mnRightBorder = 0;
|
|
mnBottomBorder = 0;
|
|
}
|
|
else
|
|
{
|
|
// FIXME: this is currently only on macOS, check with other
|
|
// platforms
|
|
if( ImplGetSVData()->maNWFData.mbNoFocusRects && !( nBorderStyle & WindowBorderStyle::NWF ) )
|
|
{
|
|
// for native widget drawing we must find out what
|
|
// control this border belongs to
|
|
ControlType aCtrlType = ControlType::Generic;
|
|
ControlPart aCtrlPart = ControlPart::Entire;
|
|
if (pCtrl && !(pCtrl->GetBorderStyle() & WindowBorderStyle::NONATIVEBORDER))
|
|
{
|
|
switch( pCtrl->GetType() )
|
|
{
|
|
case WindowType::LISTBOX:
|
|
if( pCtrl->GetStyle() & WB_DROPDOWN )
|
|
{
|
|
aCtrlType = ControlType::Listbox;
|
|
mbNWFBorder = true;
|
|
pSubEdit = static_cast<Edit*>(pCtrl)->GetSubEdit();
|
|
}
|
|
break;
|
|
case WindowType::LISTBOXWINDOW:
|
|
aCtrlType = ControlType::Listbox;
|
|
aCtrlPart = ControlPart::ListboxWindow;
|
|
mbNWFBorder = true;
|
|
break;
|
|
case WindowType::COMBOBOX:
|
|
if( pCtrl->GetStyle() & WB_DROPDOWN )
|
|
{
|
|
aCtrlType = ControlType::Combobox;
|
|
mbNWFBorder = true;
|
|
pSubEdit = static_cast<Edit*>(pCtrl)->GetSubEdit();
|
|
}
|
|
break;
|
|
case WindowType::MULTILINEEDIT:
|
|
aCtrlType = ControlType::MultilineEditbox;
|
|
mbNWFBorder = true;
|
|
break;
|
|
case WindowType::EDIT:
|
|
case WindowType::PATTERNFIELD:
|
|
case WindowType::METRICFIELD:
|
|
case WindowType::CURRENCYFIELD:
|
|
case WindowType::DATEFIELD:
|
|
case WindowType::TIMEFIELD:
|
|
case WindowType::SPINFIELD:
|
|
case WindowType::FORMATTEDFIELD:
|
|
mbNWFBorder = true;
|
|
if (pCtrl->GetStyle() & WB_SPIN)
|
|
aCtrlType = ControlType::Spinbox;
|
|
else
|
|
aCtrlType = ControlType::Editbox;
|
|
pSubEdit = static_cast<Edit*>(pCtrl)->GetSubEdit();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
if( mbNWFBorder )
|
|
{
|
|
ImplControlValue aControlValue;
|
|
Size aMinSize( mnWidth, mnHeight );
|
|
if( aMinSize.Width() < 10 ) aMinSize.setWidth( 10 );
|
|
if( aMinSize.Height() < 10 ) aMinSize.setHeight( 10 );
|
|
tools::Rectangle aCtrlRegion( Point(), aMinSize );
|
|
tools::Rectangle aBounds, aContent;
|
|
if( pWin->GetNativeControlRegion( aCtrlType, aCtrlPart, aCtrlRegion,
|
|
ControlState::ENABLED, aControlValue,
|
|
aBounds, aContent ) )
|
|
{
|
|
aBounds.AdjustLeft(mnLeftBorder);
|
|
aBounds.AdjustRight(-mnRightBorder);
|
|
aBounds.AdjustTop(mnTopBorder);
|
|
aBounds.AdjustBottom(-mnBottomBorder);
|
|
aContent.AdjustLeft(mnLeftBorder);
|
|
aContent.AdjustRight(-mnRightBorder);
|
|
aContent.AdjustTop(mnTopBorder);
|
|
aContent.AdjustBottom(-mnBottomBorder);
|
|
mnLeftBorder = aContent.Left() - aBounds.Left();
|
|
mnRightBorder = aBounds.Right() - aContent.Right();
|
|
mnTopBorder = aContent.Top() - aBounds.Top();
|
|
mnBottomBorder = aBounds.Bottom() - aContent.Bottom();
|
|
if( mnWidth && mnHeight )
|
|
{
|
|
|
|
mpBorderWindow->SetPaintTransparent( true );
|
|
mpBorderWindow->SetBackground();
|
|
if (!pCtrl->IsControlBackground())
|
|
{
|
|
pCtrl->SetPaintTransparent(true);
|
|
if (pSubEdit)
|
|
pSubEdit->SetPaintTransparent(true);
|
|
}
|
|
|
|
vcl::Window* pCompoundParent = nullptr;
|
|
if( pWin->GetParent() && pWin->GetParent()->IsCompoundControl() )
|
|
pCompoundParent = pWin->GetParent();
|
|
|
|
if( pCompoundParent )
|
|
pCompoundParent->SetPaintTransparent( true );
|
|
|
|
if( mnWidth < aBounds.GetWidth() || mnHeight < aBounds.GetHeight() )
|
|
{
|
|
if( ! pCompoundParent ) // compound controls have to fix themselves
|
|
{
|
|
Point aPos( mpBorderWindow->GetPosPixel() );
|
|
if( mnWidth < aBounds.GetWidth() )
|
|
aPos.AdjustX( -((aBounds.GetWidth() - mnWidth) / 2) );
|
|
if( mnHeight < aBounds.GetHeight() )
|
|
aPos.AdjustY( -((aBounds.GetHeight() - mnHeight) / 2) );
|
|
mpBorderWindow->SetPosSizePixel( aPos, aBounds.GetSize() );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
mbNWFBorder = false;
|
|
}
|
|
}
|
|
|
|
if( ! mbNWFBorder )
|
|
{
|
|
DrawFrameStyle nStyle = DrawFrameStyle::NONE;
|
|
DrawFrameFlags nFlags = DrawFrameFlags::NoDraw;
|
|
// move border outside if border was converted or if the BorderWindow is a frame window,
|
|
if ( mpBorderWindow->mbSmallOutBorder )
|
|
nStyle = DrawFrameStyle::DoubleOut;
|
|
else if ( nBorderStyle & WindowBorderStyle::NWF )
|
|
nStyle = DrawFrameStyle::NWF;
|
|
else
|
|
nStyle = DrawFrameStyle::DoubleIn;
|
|
if ( nBorderStyle & WindowBorderStyle::MONO )
|
|
nFlags |= DrawFrameFlags::Mono;
|
|
|
|
DecorationView aDecoView( mpOutDev );
|
|
tools::Rectangle aRect( 0, 0, 10, 10 );
|
|
tools::Rectangle aCalcRect = aDecoView.DrawFrame( aRect, nStyle, nFlags );
|
|
mnLeftBorder = aCalcRect.Left();
|
|
mnTopBorder = aCalcRect.Top();
|
|
mnRightBorder = aRect.Right()-aCalcRect.Right();
|
|
mnBottomBorder = aRect.Bottom()-aCalcRect.Bottom();
|
|
}
|
|
}
|
|
|
|
if (pCtrl)
|
|
{
|
|
//fdo#57090 If the borders have changed, then trigger a queue_resize on
|
|
//the bordered window, which will resync its borders at that point
|
|
if (nOrigLeftBorder != mnLeftBorder ||
|
|
nOrigTopBorder != mnTopBorder ||
|
|
nOrigRightBorder != mnRightBorder ||
|
|
nOrigBottomBorder != mnBottomBorder)
|
|
{
|
|
pCtrl->queue_resize();
|
|
}
|
|
}
|
|
}
|
|
|
|
void ImplSmallBorderWindowView::GetBorder( sal_Int32& rLeftBorder, sal_Int32& rTopBorder,
|
|
sal_Int32& rRightBorder, sal_Int32& rBottomBorder ) const
|
|
{
|
|
rLeftBorder = mnLeftBorder;
|
|
rTopBorder = mnTopBorder;
|
|
rRightBorder = mnRightBorder;
|
|
rBottomBorder = mnBottomBorder;
|
|
}
|
|
|
|
tools::Long ImplSmallBorderWindowView::CalcTitleWidth() const
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
void ImplSmallBorderWindowView::DrawWindow(vcl::RenderContext& rRenderContext, const Point*)
|
|
{
|
|
WindowBorderStyle nBorderStyle = mpBorderWindow->GetBorderStyle();
|
|
if (nBorderStyle & WindowBorderStyle::NOBORDER)
|
|
return;
|
|
|
|
bool bNativeOK = false;
|
|
// for native widget drawing we must find out what
|
|
// control this border belongs to
|
|
vcl::Window* pCtrl = mpBorderWindow->GetWindow(GetWindowType::Client);
|
|
|
|
ControlType aCtrlType = ControlType::Generic;
|
|
ControlPart aCtrlPart = ControlPart::Entire;
|
|
if (pCtrl)
|
|
{
|
|
switch (pCtrl->GetType())
|
|
{
|
|
case WindowType::MULTILINEEDIT:
|
|
aCtrlType = ControlType::MultilineEditbox;
|
|
break;
|
|
case WindowType::EDIT:
|
|
case WindowType::PATTERNFIELD:
|
|
case WindowType::METRICFIELD:
|
|
case WindowType::CURRENCYFIELD:
|
|
case WindowType::DATEFIELD:
|
|
case WindowType::TIMEFIELD:
|
|
case WindowType::SPINFIELD:
|
|
case WindowType::FORMATTEDFIELD:
|
|
if (pCtrl->GetStyle() & WB_SPIN)
|
|
aCtrlType = ControlType::Spinbox;
|
|
else
|
|
aCtrlType = ControlType::Editbox;
|
|
break;
|
|
|
|
case WindowType::LISTBOX:
|
|
case WindowType::MULTILISTBOX:
|
|
case WindowType::TREELISTBOX:
|
|
aCtrlType = ControlType::Listbox;
|
|
if (pCtrl->GetStyle() & WB_DROPDOWN)
|
|
aCtrlPart = ControlPart::Entire;
|
|
else
|
|
aCtrlPart = ControlPart::ListboxWindow;
|
|
break;
|
|
|
|
case WindowType::LISTBOXWINDOW:
|
|
aCtrlType = ControlType::Listbox;
|
|
aCtrlPart = ControlPart::ListboxWindow;
|
|
break;
|
|
|
|
case WindowType::COMBOBOX:
|
|
case WindowType::PATTERNBOX:
|
|
case WindowType::NUMERICBOX:
|
|
case WindowType::METRICBOX:
|
|
case WindowType::CURRENCYBOX:
|
|
case WindowType::DATEBOX:
|
|
case WindowType::TIMEBOX:
|
|
case WindowType::LONGCURRENCYBOX:
|
|
if (pCtrl->GetStyle() & WB_DROPDOWN)
|
|
{
|
|
aCtrlType = ControlType::Combobox;
|
|
aCtrlPart = ControlPart::Entire;
|
|
}
|
|
else
|
|
{
|
|
aCtrlType = ControlType::Listbox;
|
|
aCtrlPart = ControlPart::ListboxWindow;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (aCtrlType != ControlType::Generic && pCtrl->IsNativeControlSupported(aCtrlType, aCtrlPart))
|
|
{
|
|
ImplControlValue aControlValue;
|
|
ControlState nState = ControlState::ENABLED;
|
|
|
|
if (!mpBorderWindow->IsEnabled())
|
|
nState &= ~ControlState::ENABLED;
|
|
if (mpBorderWindow->HasFocus() || pCtrl->HasFocus() || pCtrl->HasChildPathFocus())
|
|
nState |= ControlState::FOCUSED;
|
|
|
|
bool bMouseOver = pCtrl->IsMouseOver();
|
|
if (!bMouseOver)
|
|
{
|
|
vcl::Window *pCtrlChild = pCtrl->GetWindow(GetWindowType::FirstChild);
|
|
while(pCtrlChild)
|
|
{
|
|
bMouseOver = pCtrlChild->IsMouseOver();
|
|
if (bMouseOver)
|
|
break;
|
|
pCtrlChild = pCtrlChild->GetWindow(GetWindowType::Next);
|
|
}
|
|
}
|
|
|
|
if (bMouseOver)
|
|
nState |= ControlState::ROLLOVER;
|
|
|
|
Point aPoint;
|
|
tools::Rectangle aCtrlRegion(aPoint, Size(mnWidth, mnHeight));
|
|
|
|
tools::Rectangle aBoundingRgn(aPoint, Size(mnWidth, mnHeight));
|
|
tools::Rectangle aContentRgn(aCtrlRegion);
|
|
if (!ImplGetSVData()->maNWFData.mbCanDrawWidgetAnySize &&
|
|
rRenderContext.GetNativeControlRegion(aCtrlType, aCtrlPart, aCtrlRegion,
|
|
nState, aControlValue,
|
|
aBoundingRgn, aContentRgn))
|
|
{
|
|
aCtrlRegion=aContentRgn;
|
|
}
|
|
|
|
Color aBackgroundColor = COL_AUTO;
|
|
if (pCtrl->IsControlBackground())
|
|
aBackgroundColor = pCtrl->GetBackgroundColor();
|
|
bNativeOK = rRenderContext.DrawNativeControl(aCtrlType, aCtrlPart, aCtrlRegion, nState, aControlValue, OUString(), aBackgroundColor);
|
|
|
|
// if the native theme draws the spinbuttons in one call, make sure the proper settings
|
|
// are passed, this might force a redraw though... (TODO: improve)
|
|
if ((aCtrlType == ControlType::Spinbox) && !pCtrl->IsNativeControlSupported(ControlType::Spinbox, ControlPart::ButtonUp))
|
|
{
|
|
Edit* pEdit = static_cast<Edit*>(pCtrl)->GetSubEdit();
|
|
if (pEdit && !pEdit->SupportsDoubleBuffering())
|
|
pCtrl->Paint(*pCtrl->GetOutDev(), tools::Rectangle()); // make sure the buttons are also drawn as they might overwrite the border
|
|
}
|
|
}
|
|
|
|
if (bNativeOK)
|
|
return;
|
|
|
|
DrawFrameStyle nStyle = DrawFrameStyle::NONE;
|
|
DrawFrameFlags nFlags = DrawFrameFlags::NONE;
|
|
// move border outside if border was converted or if the border window is a frame window,
|
|
if (mpBorderWindow->mbSmallOutBorder)
|
|
nStyle = DrawFrameStyle::DoubleOut;
|
|
else if (nBorderStyle & WindowBorderStyle::NWF)
|
|
nStyle = DrawFrameStyle::NWF;
|
|
else
|
|
nStyle = DrawFrameStyle::DoubleIn;
|
|
if (nBorderStyle & WindowBorderStyle::MONO)
|
|
nFlags |= DrawFrameFlags::Mono;
|
|
if (nBorderStyle & WindowBorderStyle::MENU)
|
|
nFlags |= DrawFrameFlags::Menu;
|
|
// tell DrawFrame that we're drawing a window border of a frame window to avoid round corners
|
|
if (mpBorderWindow == mpBorderWindow->ImplGetFrameWindow())
|
|
nFlags |= DrawFrameFlags::WindowBorder;
|
|
|
|
DecorationView aDecoView(&rRenderContext);
|
|
tools::Rectangle aInRect(Point(), Size(mnWidth, mnHeight));
|
|
aDecoView.DrawFrame(aInRect, nStyle, nFlags);
|
|
}
|
|
|
|
|
|
ImplStdBorderWindowView::ImplStdBorderWindowView( ImplBorderWindow* pBorderWindow )
|
|
{
|
|
maFrameData.mpBorderWindow = pBorderWindow;
|
|
maFrameData.mbDragFull = false;
|
|
maFrameData.mnHitTest = BorderWindowHitTest::NONE;
|
|
maFrameData.mnCloseState = DrawButtonFlags::NONE;
|
|
maFrameData.mnDockState = DrawButtonFlags::NONE;
|
|
maFrameData.mnMenuState = DrawButtonFlags::NONE;
|
|
maFrameData.mnHideState = DrawButtonFlags::NONE;
|
|
maFrameData.mnHelpState = DrawButtonFlags::NONE;
|
|
maFrameData.mbTitleClipped = false;
|
|
}
|
|
|
|
ImplStdBorderWindowView::~ImplStdBorderWindowView()
|
|
{
|
|
}
|
|
|
|
bool ImplStdBorderWindowView::MouseMove( const MouseEvent& rMEvt )
|
|
{
|
|
ImplMouseMove( &maFrameData, rMEvt );
|
|
return true;
|
|
}
|
|
|
|
bool ImplStdBorderWindowView::MouseButtonDown( const MouseEvent& rMEvt )
|
|
{
|
|
ImplBorderWindow* pBorderWindow = maFrameData.mpBorderWindow;
|
|
|
|
if ( rMEvt.IsLeft() || rMEvt.IsRight() )
|
|
{
|
|
maFrameData.maMouseOff = rMEvt.GetPosPixel();
|
|
maFrameData.mnHitTest = ImplHitTest( &maFrameData, maFrameData.maMouseOff );
|
|
if ( maFrameData.mnHitTest != BorderWindowHitTest::NONE )
|
|
{
|
|
DragFullOptions nDragFullTest = DragFullOptions::NONE;
|
|
bool bTracking = true;
|
|
bool bHitTest = true;
|
|
|
|
if ( maFrameData.mnHitTest & BorderWindowHitTest::Close )
|
|
{
|
|
maFrameData.mnCloseState |= DrawButtonFlags::Pressed;
|
|
pBorderWindow->InvalidateBorder();
|
|
}
|
|
else if ( maFrameData.mnHitTest & BorderWindowHitTest::Dock )
|
|
{
|
|
maFrameData.mnDockState |= DrawButtonFlags::Pressed;
|
|
pBorderWindow->InvalidateBorder();
|
|
}
|
|
else if ( maFrameData.mnHitTest & BorderWindowHitTest::Menu )
|
|
{
|
|
maFrameData.mnMenuState |= DrawButtonFlags::Pressed;
|
|
pBorderWindow->InvalidateBorder();
|
|
|
|
// call handler already on mouse down
|
|
if ( pBorderWindow->ImplGetClientWindow()->IsSystemWindow() )
|
|
{
|
|
SystemWindow* pClientWindow = static_cast<SystemWindow*>(pBorderWindow->ImplGetClientWindow());
|
|
pClientWindow->TitleButtonClick( TitleButton::Menu );
|
|
}
|
|
|
|
maFrameData.mnMenuState &= ~DrawButtonFlags::Pressed;
|
|
pBorderWindow->InvalidateBorder();
|
|
|
|
bTracking = false;
|
|
}
|
|
else if ( maFrameData.mnHitTest & BorderWindowHitTest::Hide )
|
|
{
|
|
maFrameData.mnHideState |= DrawButtonFlags::Pressed;
|
|
pBorderWindow->InvalidateBorder();
|
|
}
|
|
else if ( maFrameData.mnHitTest & BorderWindowHitTest::Help )
|
|
{
|
|
maFrameData.mnHelpState |= DrawButtonFlags::Pressed;
|
|
pBorderWindow->InvalidateBorder();
|
|
}
|
|
else
|
|
{
|
|
if ( rMEvt.GetClicks() == 1 )
|
|
{
|
|
Point aPos = pBorderWindow->GetPosPixel();
|
|
Size aSize = pBorderWindow->GetOutputSizePixel();
|
|
maFrameData.mnTrackX = aPos.X();
|
|
maFrameData.mnTrackY = aPos.Y();
|
|
maFrameData.mnTrackWidth = aSize.Width();
|
|
maFrameData.mnTrackHeight = aSize.Height();
|
|
|
|
if (maFrameData.mnHitTest & BorderWindowHitTest::Title)
|
|
nDragFullTest = DragFullOptions::WindowMove;
|
|
else
|
|
nDragFullTest = DragFullOptions::WindowSize;
|
|
}
|
|
else
|
|
{
|
|
bTracking = false;
|
|
|
|
if ( (maFrameData.mnHitTest & BorderWindowHitTest::Title) &&
|
|
((rMEvt.GetClicks() % 2) == 0) )
|
|
{
|
|
maFrameData.mnHitTest = BorderWindowHitTest::NONE;
|
|
bHitTest = false;
|
|
|
|
if ( pBorderWindow->ImplGetClientWindow()->IsSystemWindow() )
|
|
{
|
|
SystemWindow* pClientWindow = static_cast<SystemWindow*>(pBorderWindow->ImplGetClientWindow());
|
|
// always perform docking on double click, no button required
|
|
pClientWindow->TitleButtonClick( TitleButton::Docking );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( bTracking )
|
|
{
|
|
maFrameData.mbDragFull = false;
|
|
if ( nDragFullTest != DragFullOptions::NONE )
|
|
maFrameData.mbDragFull = true; // always fulldrag for proper docking, ignore system settings
|
|
pBorderWindow->StartTracking();
|
|
}
|
|
else if ( bHitTest )
|
|
maFrameData.mnHitTest = BorderWindowHitTest::NONE;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ImplStdBorderWindowView::Tracking( const TrackingEvent& rTEvt )
|
|
{
|
|
ImplBorderWindow* pBorderWindow = maFrameData.mpBorderWindow;
|
|
|
|
if ( rTEvt.IsTrackingEnded() )
|
|
{
|
|
BorderWindowHitTest nHitTest = maFrameData.mnHitTest;
|
|
maFrameData.mnHitTest = BorderWindowHitTest::NONE;
|
|
|
|
if ( nHitTest & BorderWindowHitTest::Close )
|
|
{
|
|
if ( maFrameData.mnCloseState & DrawButtonFlags::Pressed )
|
|
{
|
|
maFrameData.mnCloseState &= ~DrawButtonFlags::Pressed;
|
|
pBorderWindow->InvalidateBorder();
|
|
|
|
// do not call a Click-Handler when aborting
|
|
if ( !rTEvt.IsTrackingCanceled() )
|
|
{
|
|
// dispatch to correct window type (why is Close() not virtual ??? )
|
|
// TODO: make Close() virtual
|
|
VclPtr<vcl::Window> pWin = pBorderWindow->ImplGetClientWindow()->ImplGetWindow();
|
|
SystemWindow *pSysWin = dynamic_cast<SystemWindow* >(pWin.get());
|
|
DockingWindow *pDockWin = dynamic_cast<DockingWindow*>(pWin.get());
|
|
if ( pSysWin )
|
|
pSysWin->Close();
|
|
else if ( pDockWin )
|
|
pDockWin->Close();
|
|
}
|
|
}
|
|
}
|
|
else if ( nHitTest & BorderWindowHitTest::Dock )
|
|
{
|
|
if ( maFrameData.mnDockState & DrawButtonFlags::Pressed )
|
|
{
|
|
maFrameData.mnDockState &= ~DrawButtonFlags::Pressed;
|
|
pBorderWindow->InvalidateBorder();
|
|
|
|
// do not call a Click-Handler when aborting
|
|
if ( !rTEvt.IsTrackingCanceled() )
|
|
{
|
|
if ( pBorderWindow->ImplGetClientWindow()->IsSystemWindow() )
|
|
{
|
|
SystemWindow* pClientWindow = static_cast<SystemWindow*>(pBorderWindow->ImplGetClientWindow());
|
|
pClientWindow->TitleButtonClick( TitleButton::Docking );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if ( nHitTest & BorderWindowHitTest::Menu )
|
|
{
|
|
if ( maFrameData.mnMenuState & DrawButtonFlags::Pressed )
|
|
{
|
|
maFrameData.mnMenuState &= ~DrawButtonFlags::Pressed;
|
|
pBorderWindow->InvalidateBorder();
|
|
|
|
// handler already called on mouse down
|
|
}
|
|
}
|
|
else if ( nHitTest & BorderWindowHitTest::Hide )
|
|
{
|
|
if ( maFrameData.mnHideState & DrawButtonFlags::Pressed )
|
|
{
|
|
maFrameData.mnHideState &= ~DrawButtonFlags::Pressed;
|
|
pBorderWindow->InvalidateBorder();
|
|
|
|
// do not call a Click-Handler when aborting
|
|
if ( !rTEvt.IsTrackingCanceled() )
|
|
{
|
|
if ( pBorderWindow->ImplGetClientWindow()->IsSystemWindow() )
|
|
{
|
|
SystemWindow* pClientWindow = static_cast<SystemWindow*>(pBorderWindow->ImplGetClientWindow());
|
|
pClientWindow->TitleButtonClick( TitleButton::Hide );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if ( nHitTest & BorderWindowHitTest::Help )
|
|
{
|
|
if ( maFrameData.mnHelpState & DrawButtonFlags::Pressed )
|
|
{
|
|
maFrameData.mnHelpState &= ~DrawButtonFlags::Pressed;
|
|
pBorderWindow->InvalidateBorder();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( maFrameData.mbDragFull )
|
|
{
|
|
// restore old state when aborting
|
|
if ( rTEvt.IsTrackingCanceled() )
|
|
pBorderWindow->SetPosSizePixel( Point( maFrameData.mnTrackX, maFrameData.mnTrackY ), Size( maFrameData.mnTrackWidth, maFrameData.mnTrackHeight ) );
|
|
}
|
|
else
|
|
{
|
|
pBorderWindow->HideTracking();
|
|
if ( !rTEvt.IsTrackingCanceled() )
|
|
pBorderWindow->SetPosSizePixel( Point( maFrameData.mnTrackX, maFrameData.mnTrackY ), Size( maFrameData.mnTrackWidth, maFrameData.mnTrackHeight ) );
|
|
}
|
|
|
|
if ( !rTEvt.IsTrackingCanceled() )
|
|
{
|
|
if ( pBorderWindow->ImplGetClientWindow()->ImplIsFloatingWindow() )
|
|
{
|
|
if ( static_cast<FloatingWindow*>(pBorderWindow->ImplGetClientWindow())->IsInPopupMode() )
|
|
static_cast<FloatingWindow*>(pBorderWindow->ImplGetClientWindow())->EndPopupMode( FloatWinPopupEndFlags::TearOff );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if ( !rTEvt.GetMouseEvent().IsSynthetic() )
|
|
{
|
|
Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel();
|
|
|
|
if ( maFrameData.mnHitTest & BorderWindowHitTest::Close )
|
|
{
|
|
if ( maFrameData.maCloseRect.Contains( aMousePos ) )
|
|
{
|
|
if ( !(maFrameData.mnCloseState & DrawButtonFlags::Pressed) )
|
|
{
|
|
maFrameData.mnCloseState |= DrawButtonFlags::Pressed;
|
|
pBorderWindow->InvalidateBorder();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( maFrameData.mnCloseState & DrawButtonFlags::Pressed )
|
|
{
|
|
maFrameData.mnCloseState &= ~DrawButtonFlags::Pressed;
|
|
pBorderWindow->InvalidateBorder();
|
|
}
|
|
}
|
|
}
|
|
else if ( maFrameData.mnHitTest & BorderWindowHitTest::Dock )
|
|
{
|
|
if ( maFrameData.maDockRect.Contains( aMousePos ) )
|
|
{
|
|
if ( !(maFrameData.mnDockState & DrawButtonFlags::Pressed) )
|
|
{
|
|
maFrameData.mnDockState |= DrawButtonFlags::Pressed;
|
|
pBorderWindow->InvalidateBorder();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( maFrameData.mnDockState & DrawButtonFlags::Pressed )
|
|
{
|
|
maFrameData.mnDockState &= ~DrawButtonFlags::Pressed;
|
|
pBorderWindow->InvalidateBorder();
|
|
}
|
|
}
|
|
}
|
|
else if ( maFrameData.mnHitTest & BorderWindowHitTest::Menu )
|
|
{
|
|
if ( maFrameData.maMenuRect.Contains( aMousePos ) )
|
|
{
|
|
if ( !(maFrameData.mnMenuState & DrawButtonFlags::Pressed) )
|
|
{
|
|
maFrameData.mnMenuState |= DrawButtonFlags::Pressed;
|
|
pBorderWindow->InvalidateBorder();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( maFrameData.mnMenuState & DrawButtonFlags::Pressed )
|
|
{
|
|
maFrameData.mnMenuState &= ~DrawButtonFlags::Pressed;
|
|
pBorderWindow->InvalidateBorder();
|
|
}
|
|
}
|
|
}
|
|
else if ( maFrameData.mnHitTest & BorderWindowHitTest::Hide )
|
|
{
|
|
if ( maFrameData.maHideRect.Contains( aMousePos ) )
|
|
{
|
|
if ( !(maFrameData.mnHideState & DrawButtonFlags::Pressed) )
|
|
{
|
|
maFrameData.mnHideState |= DrawButtonFlags::Pressed;
|
|
pBorderWindow->InvalidateBorder();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( maFrameData.mnHideState & DrawButtonFlags::Pressed )
|
|
{
|
|
maFrameData.mnHideState &= ~DrawButtonFlags::Pressed;
|
|
pBorderWindow->InvalidateBorder();
|
|
}
|
|
}
|
|
}
|
|
else if ( maFrameData.mnHitTest & BorderWindowHitTest::Help )
|
|
{
|
|
if ( maFrameData.maHelpRect.Contains( aMousePos ) )
|
|
{
|
|
if ( !(maFrameData.mnHelpState & DrawButtonFlags::Pressed) )
|
|
{
|
|
maFrameData.mnHelpState |= DrawButtonFlags::Pressed;
|
|
pBorderWindow->InvalidateBorder();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( maFrameData.mnHelpState & DrawButtonFlags::Pressed )
|
|
{
|
|
maFrameData.mnHelpState &= ~DrawButtonFlags::Pressed;
|
|
pBorderWindow->InvalidateBorder();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
aMousePos.AdjustX( -(maFrameData.maMouseOff.X()) );
|
|
aMousePos.AdjustY( -(maFrameData.maMouseOff.Y()) );
|
|
|
|
if ( maFrameData.mnHitTest & BorderWindowHitTest::Title )
|
|
{
|
|
maFrameData.mpBorderWindow->SetPointer( PointerStyle::Move );
|
|
|
|
Point aPos = pBorderWindow->GetPosPixel();
|
|
aPos.AdjustX(aMousePos.X() );
|
|
aPos.AdjustY(aMousePos.Y() );
|
|
if ( maFrameData.mbDragFull )
|
|
{
|
|
pBorderWindow->SetPosPixel( aPos );
|
|
pBorderWindow->ImplUpdateAll();
|
|
pBorderWindow->ImplGetFrameWindow()->ImplUpdateAll();
|
|
}
|
|
else
|
|
{
|
|
maFrameData.mnTrackX = aPos.X();
|
|
maFrameData.mnTrackY = aPos.Y();
|
|
pBorderWindow->ShowTracking( tools::Rectangle( pBorderWindow->ScreenToOutputPixel( aPos ), pBorderWindow->GetOutputSizePixel() ), ShowTrackFlags::Big );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Point aOldPos = pBorderWindow->GetPosPixel();
|
|
Size aSize = pBorderWindow->GetSizePixel();
|
|
tools::Rectangle aNewRect( aOldPos, aSize );
|
|
tools::Long nOldWidth = aSize.Width();
|
|
tools::Long nOldHeight = aSize.Height();
|
|
tools::Long nBorderWidth = maFrameData.mnLeftBorder+maFrameData.mnRightBorder;
|
|
tools::Long nBorderHeight = maFrameData.mnTopBorder+maFrameData.mnBottomBorder;
|
|
tools::Long nMinWidth = pBorderWindow->mnMinWidth+nBorderWidth;
|
|
tools::Long nMinHeight = pBorderWindow->mnMinHeight+nBorderHeight;
|
|
tools::Long nMinWidth2 = nBorderWidth;
|
|
tools::Long nMaxWidth = pBorderWindow->mnMaxWidth+nBorderWidth;
|
|
tools::Long nMaxHeight = pBorderWindow->mnMaxHeight+nBorderHeight;
|
|
|
|
if ( maFrameData.mnTitleHeight )
|
|
{
|
|
nMinWidth2 += 4;
|
|
|
|
if ( pBorderWindow->GetStyle() & WB_CLOSEABLE )
|
|
nMinWidth2 += maFrameData.maCloseRect.GetWidth();
|
|
}
|
|
if ( nMinWidth2 > nMinWidth )
|
|
nMinWidth = nMinWidth2;
|
|
if ( maFrameData.mnHitTest & (BorderWindowHitTest::Left | BorderWindowHitTest::TopLeft | BorderWindowHitTest::BottomLeft) )
|
|
{
|
|
aNewRect.AdjustLeft(aMousePos.X() );
|
|
if ( aNewRect.GetWidth() < nMinWidth )
|
|
aNewRect.SetLeft( aNewRect.Right()-nMinWidth+1 );
|
|
else if ( aNewRect.GetWidth() > nMaxWidth )
|
|
aNewRect.SetLeft( aNewRect.Right()-nMaxWidth+1 );
|
|
}
|
|
else if ( maFrameData.mnHitTest & (BorderWindowHitTest::Right | BorderWindowHitTest::TopRight | BorderWindowHitTest::BottomRight) )
|
|
{
|
|
aNewRect.AdjustRight(aMousePos.X() );
|
|
if ( aNewRect.GetWidth() < nMinWidth )
|
|
aNewRect.SetRight( aNewRect.Left()+nMinWidth+1 );
|
|
else if ( aNewRect.GetWidth() > nMaxWidth )
|
|
aNewRect.SetRight( aNewRect.Left()+nMaxWidth+1 );
|
|
}
|
|
if ( maFrameData.mnHitTest & (BorderWindowHitTest::Top | BorderWindowHitTest::TopLeft | BorderWindowHitTest::TopRight) )
|
|
{
|
|
aNewRect.AdjustTop(aMousePos.Y() );
|
|
if ( aNewRect.GetHeight() < nMinHeight )
|
|
aNewRect.SetTop( aNewRect.Bottom()-nMinHeight+1 );
|
|
else if ( aNewRect.GetHeight() > nMaxHeight )
|
|
aNewRect.SetTop( aNewRect.Bottom()-nMaxHeight+1 );
|
|
}
|
|
else if ( maFrameData.mnHitTest & (BorderWindowHitTest::Bottom | BorderWindowHitTest::BottomLeft | BorderWindowHitTest::BottomRight) )
|
|
{
|
|
aNewRect.AdjustBottom(aMousePos.Y() );
|
|
if ( aNewRect.GetHeight() < nMinHeight )
|
|
aNewRect.SetBottom( aNewRect.Top()+nMinHeight+1 );
|
|
else if ( aNewRect.GetHeight() > nMaxHeight )
|
|
aNewRect.SetBottom( aNewRect.Top()+nMaxHeight+1 );
|
|
}
|
|
|
|
// call Resizing-Handler for SystemWindows
|
|
if ( pBorderWindow->ImplGetClientWindow()->IsSystemWindow() )
|
|
{
|
|
// adjust size for Resizing-call
|
|
aSize = aNewRect.GetSize();
|
|
aSize.AdjustWidth( -nBorderWidth );
|
|
aSize.AdjustHeight( -nBorderHeight );
|
|
static_cast<SystemWindow*>(pBorderWindow->ImplGetClientWindow())->Resizing( aSize );
|
|
aSize.AdjustWidth(nBorderWidth );
|
|
aSize.AdjustHeight(nBorderHeight );
|
|
if ( aSize.Width() < nMinWidth )
|
|
aSize.setWidth( nMinWidth );
|
|
if ( aSize.Height() < nMinHeight )
|
|
aSize.setHeight( nMinHeight );
|
|
if ( aSize.Width() > nMaxWidth )
|
|
aSize.setWidth( nMaxWidth );
|
|
if ( aSize.Height() > nMaxHeight )
|
|
aSize.setHeight( nMaxHeight );
|
|
if ( maFrameData.mnHitTest & (BorderWindowHitTest::Left | BorderWindowHitTest::TopLeft | BorderWindowHitTest::BottomLeft) )
|
|
aNewRect.SetLeft( aNewRect.Right()-aSize.Width()+1 );
|
|
else
|
|
aNewRect.SetRight( aNewRect.Left()+aSize.Width()-1 );
|
|
if ( maFrameData.mnHitTest & (BorderWindowHitTest::Top | BorderWindowHitTest::TopLeft | BorderWindowHitTest::TopRight) )
|
|
aNewRect.SetTop( aNewRect.Bottom()-aSize.Height()+1 );
|
|
else
|
|
aNewRect.SetBottom( aNewRect.Top()+aSize.Height()-1 );
|
|
}
|
|
|
|
if ( maFrameData.mbDragFull )
|
|
{
|
|
// no move (only resize) if position did not change
|
|
if( aOldPos != aNewRect.TopLeft() )
|
|
pBorderWindow->setPosSizePixel( aNewRect.Left(), aNewRect.Top(),
|
|
aNewRect.GetWidth(), aNewRect.GetHeight() );
|
|
else
|
|
pBorderWindow->setPosSizePixel( aNewRect.Left(), aNewRect.Top(),
|
|
aNewRect.GetWidth(), aNewRect.GetHeight(), PosSizeFlags::Size );
|
|
|
|
pBorderWindow->ImplUpdateAll();
|
|
pBorderWindow->ImplGetFrameWindow()->ImplUpdateAll();
|
|
if ( maFrameData.mnHitTest & (BorderWindowHitTest::Right | BorderWindowHitTest::TopRight | BorderWindowHitTest::BottomRight) )
|
|
maFrameData.maMouseOff.AdjustX(aNewRect.GetWidth()-nOldWidth );
|
|
if ( maFrameData.mnHitTest & (BorderWindowHitTest::Bottom | BorderWindowHitTest::BottomLeft | BorderWindowHitTest::BottomRight) )
|
|
maFrameData.maMouseOff.AdjustY(aNewRect.GetHeight()-nOldHeight );
|
|
}
|
|
else
|
|
{
|
|
maFrameData.mnTrackX = aNewRect.Left();
|
|
maFrameData.mnTrackY = aNewRect.Top();
|
|
maFrameData.mnTrackWidth = aNewRect.GetWidth();
|
|
maFrameData.mnTrackHeight = aNewRect.GetHeight();
|
|
pBorderWindow->ShowTracking( tools::Rectangle( pBorderWindow->ScreenToOutputPixel( aNewRect.TopLeft() ), aNewRect.GetSize() ), ShowTrackFlags::Big );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
OUString ImplStdBorderWindowView::RequestHelp( const Point& rPos, tools::Rectangle& rHelpRect )
|
|
{
|
|
return ImplRequestHelp( &maFrameData, rPos, rHelpRect );
|
|
}
|
|
|
|
tools::Rectangle ImplStdBorderWindowView::GetMenuRect() const
|
|
{
|
|
return maFrameData.maMenuRect;
|
|
}
|
|
|
|
void ImplStdBorderWindowView::Init( OutputDevice* pDev, tools::Long nWidth, tools::Long nHeight )
|
|
{
|
|
ImplBorderFrameData* pData = &maFrameData;
|
|
ImplBorderWindow* pBorderWindow = maFrameData.mpBorderWindow;
|
|
const StyleSettings& rStyleSettings = pDev->GetSettings().GetStyleSettings();
|
|
DecorationView aDecoView( pDev );
|
|
tools::Rectangle aRect( 0, 0, 10, 10 );
|
|
tools::Rectangle aCalcRect = aDecoView.DrawFrame( aRect, DrawFrameStyle::DoubleOut, DrawFrameFlags::NoDraw );
|
|
|
|
pData->mpOutDev = pDev;
|
|
pData->mnWidth = nWidth;
|
|
pData->mnHeight = nHeight;
|
|
|
|
pData->mnTitleType = pBorderWindow->mnTitleType;
|
|
|
|
if ( !(pBorderWindow->GetStyle() & (WB_MOVEABLE | WB_POPUP)) || (pData->mnTitleType == BorderWindowTitleType::NONE) )
|
|
pData->mnBorderSize = 0;
|
|
else if ( pData->mnTitleType == BorderWindowTitleType::Tearoff )
|
|
pData->mnBorderSize = 0;
|
|
else
|
|
pData->mnBorderSize = StyleSettings::GetBorderSize();
|
|
pData->mnLeftBorder = aCalcRect.Left();
|
|
pData->mnTopBorder = aCalcRect.Top();
|
|
pData->mnRightBorder = aRect.Right()-aCalcRect.Right();
|
|
pData->mnBottomBorder = aRect.Bottom()-aCalcRect.Bottom();
|
|
pData->mnLeftBorder += pData->mnBorderSize;
|
|
pData->mnTopBorder += pData->mnBorderSize;
|
|
pData->mnRightBorder += pData->mnBorderSize;
|
|
pData->mnBottomBorder += pData->mnBorderSize;
|
|
pData->mnNoTitleTop = pData->mnTopBorder;
|
|
|
|
ImplInitTitle(&maFrameData);
|
|
if (pData->mnTitleHeight)
|
|
{
|
|
// to improve symbol display force a minimum title height
|
|
if (pData->mnTitleType != BorderWindowTitleType::Tearoff &&
|
|
pData->mnTitleHeight < MIN_CAPTION_HEIGHT)
|
|
pData->mnTitleHeight = MIN_CAPTION_HEIGHT;
|
|
|
|
// set a proper background for drawing
|
|
// highlighted buttons in the title
|
|
pBorderWindow->SetBackground( rStyleSettings.GetFaceColor() );
|
|
|
|
pData->maTitleRect.SetLeft( pData->mnLeftBorder );
|
|
pData->maTitleRect.SetRight( nWidth-pData->mnRightBorder-1 );
|
|
pData->maTitleRect.SetTop( pData->mnTopBorder );
|
|
pData->maTitleRect.SetBottom( pData->maTitleRect.Top()+pData->mnTitleHeight-1 );
|
|
|
|
if ( pData->mnTitleType & (BorderWindowTitleType::Normal | BorderWindowTitleType::Small) )
|
|
{
|
|
tools::Long nRight = pData->maTitleRect.Right() - 3;
|
|
tools::Long const nItemTop = pData->maTitleRect.Top() + 2;
|
|
tools::Long const nItemBottom = pData->maTitleRect.Bottom() - 2;
|
|
|
|
auto addSquareOnRight = [&nRight, nItemTop, nItemBottom](
|
|
tools::Rectangle & rect, tools::Long gap)
|
|
{
|
|
rect.SetTop( nItemTop );
|
|
rect.SetBottom( nItemBottom );
|
|
rect.SetRight( nRight );
|
|
rect.SetLeft( rect.Right() - rect.GetHeight() + 1 );
|
|
nRight -= rect.GetWidth() + gap;
|
|
};
|
|
|
|
if ( pBorderWindow->GetStyle() & WB_CLOSEABLE )
|
|
{
|
|
addSquareOnRight(pData->maCloseRect, 3);
|
|
}
|
|
|
|
if ( pBorderWindow->mbMenuBtn )
|
|
{
|
|
addSquareOnRight(pData->maMenuRect, 0);
|
|
}
|
|
|
|
if ( pBorderWindow->mbDockBtn )
|
|
{
|
|
addSquareOnRight(pData->maDockRect, 0);
|
|
}
|
|
|
|
if ( pBorderWindow->mbHideBtn )
|
|
{
|
|
addSquareOnRight(pData->maHideRect, 0);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pData->maCloseRect.SetEmpty();
|
|
pData->maDockRect.SetEmpty();
|
|
pData->maMenuRect.SetEmpty();
|
|
pData->maHideRect.SetEmpty();
|
|
pData->maHelpRect.SetEmpty();
|
|
}
|
|
|
|
pData->mnTopBorder += pData->mnTitleHeight;
|
|
}
|
|
else
|
|
{
|
|
pData->maTitleRect.SetEmpty();
|
|
pData->maCloseRect.SetEmpty();
|
|
pData->maDockRect.SetEmpty();
|
|
pData->maMenuRect.SetEmpty();
|
|
pData->maHideRect.SetEmpty();
|
|
pData->maHelpRect.SetEmpty();
|
|
}
|
|
}
|
|
|
|
void ImplStdBorderWindowView::GetBorder( sal_Int32& rLeftBorder, sal_Int32& rTopBorder,
|
|
sal_Int32& rRightBorder, sal_Int32& rBottomBorder ) const
|
|
{
|
|
rLeftBorder = maFrameData.mnLeftBorder;
|
|
rTopBorder = maFrameData.mnTopBorder;
|
|
rRightBorder = maFrameData.mnRightBorder;
|
|
rBottomBorder = maFrameData.mnBottomBorder;
|
|
}
|
|
|
|
tools::Long ImplStdBorderWindowView::CalcTitleWidth() const
|
|
{
|
|
return ImplCalcTitleWidth( &maFrameData );
|
|
}
|
|
|
|
void ImplStdBorderWindowView::DrawWindow(vcl::RenderContext& rRenderContext, const Point* pOffset)
|
|
{
|
|
ImplBorderFrameData* pData = &maFrameData;
|
|
ImplBorderWindow* pBorderWindow = pData->mpBorderWindow;
|
|
Point aTmpPoint = pOffset ? *pOffset : Point();
|
|
tools::Rectangle aInRect( aTmpPoint, Size( pData->mnWidth, pData->mnHeight ) );
|
|
const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
|
|
Color aFaceColor(rStyleSettings.GetFaceColor());
|
|
Color aFrameColor(aFaceColor);
|
|
|
|
aFrameColor.DecreaseContrast(sal_uInt8(0.5 * 255));
|
|
|
|
// Draw Frame
|
|
vcl::Region oldClipRgn(rRenderContext.GetClipRegion());
|
|
|
|
// for popups, don't draw part of the frame
|
|
const bool bShowJunctionToLauncher = !(pData->mnTitleType & (BorderWindowTitleType::Normal | BorderWindowTitleType::Small));
|
|
if (bShowJunctionToLauncher && !ImplGetSVData()->maNWFData.mbNoFrameJunctionForPopups)
|
|
{
|
|
FloatingWindow* pWin = dynamic_cast<FloatingWindow*>(pData->mpBorderWindow->GetWindow(GetWindowType::Client));
|
|
if (pWin)
|
|
{
|
|
vcl::Region aClipRgn(aInRect);
|
|
AbsoluteScreenPixelRectangle aItemClipRect(pWin->ImplGetItemEdgeClipRect());
|
|
if (!aItemClipRect.IsEmpty())
|
|
{
|
|
tools::Rectangle aTmp(pData->mpBorderWindow->AbsoluteScreenToOutputPixel(aItemClipRect.TopLeft()), aItemClipRect.GetSize());
|
|
aClipRgn.Exclude(aTmp);
|
|
rRenderContext.SetClipRegion(aClipRgn);
|
|
}
|
|
}
|
|
}
|
|
|
|
// single line frame
|
|
rRenderContext.SetLineColor(aFrameColor);
|
|
rRenderContext.SetFillColor();
|
|
rRenderContext.DrawRect(aInRect);
|
|
aInRect.AdjustLeft( 1 );
|
|
aInRect.AdjustRight( -1 );
|
|
aInRect.AdjustTop( 1 );
|
|
aInRect.AdjustBottom( -1 );
|
|
|
|
// restore
|
|
if (!(pData->mnTitleType & (BorderWindowTitleType::Normal | BorderWindowTitleType::Small)))
|
|
rRenderContext.SetClipRegion(oldClipRgn);
|
|
|
|
// Draw Border
|
|
rRenderContext.SetLineColor();
|
|
tools::Long nBorderSize = pData->mnBorderSize;
|
|
if (nBorderSize)
|
|
{
|
|
rRenderContext.SetFillColor(rStyleSettings.GetFaceColor());
|
|
rRenderContext.DrawRect(tools::Rectangle(Point(aInRect.Left(), aInRect.Top()),
|
|
Size(aInRect.GetWidth(), nBorderSize)));
|
|
rRenderContext.DrawRect(tools::Rectangle(Point(aInRect.Left(), aInRect.Top() + nBorderSize),
|
|
Size(nBorderSize, aInRect.GetHeight() - nBorderSize)));
|
|
rRenderContext.DrawRect(tools::Rectangle(Point(aInRect.Left(), aInRect.Bottom() - nBorderSize + 1),
|
|
Size(aInRect.GetWidth(), nBorderSize)));
|
|
rRenderContext.DrawRect(tools::Rectangle(Point(aInRect.Right()-nBorderSize + 1, aInRect.Top() + nBorderSize),
|
|
Size(nBorderSize, aInRect.GetHeight() - nBorderSize)));
|
|
}
|
|
|
|
// Draw Title
|
|
if (!pData->maTitleRect.IsEmpty())
|
|
{
|
|
aInRect = pData->maTitleRect;
|
|
|
|
// use no gradient anymore, just a static titlecolor
|
|
if (pData->mnTitleType == BorderWindowTitleType::Tearoff)
|
|
rRenderContext.SetFillColor(rStyleSettings.GetFaceGradientColor());
|
|
else if (pData->mnTitleType == BorderWindowTitleType::Popup)
|
|
rRenderContext.SetFillColor(aFaceColor);
|
|
else
|
|
rRenderContext.SetFillColor(aFrameColor);
|
|
|
|
rRenderContext.SetTextColor(rStyleSettings.GetButtonTextColor());
|
|
tools::Rectangle aTitleRect(pData->maTitleRect);
|
|
if(pOffset)
|
|
aTitleRect.Move(pOffset->X(), pOffset->Y());
|
|
rRenderContext.DrawRect(aTitleRect);
|
|
|
|
if (pData->mnTitleType != BorderWindowTitleType::Tearoff)
|
|
{
|
|
aInRect.AdjustLeft(2 );
|
|
aInRect.AdjustRight( -2 );
|
|
|
|
if (!pData->maHelpRect.IsEmpty())
|
|
aInRect.SetRight( pData->maHelpRect.Left() - 2 );
|
|
else if (!pData->maHideRect.IsEmpty())
|
|
aInRect.SetRight( pData->maHideRect.Left() - 2 );
|
|
else if (!pData->maDockRect.IsEmpty())
|
|
aInRect.SetRight( pData->maDockRect.Left() - 2 );
|
|
else if (!pData->maMenuRect.IsEmpty())
|
|
aInRect.SetRight( pData->maMenuRect.Left() - 2 );
|
|
else if (!pData->maCloseRect.IsEmpty())
|
|
aInRect.SetRight( pData->maCloseRect.Left() - 2 );
|
|
|
|
if (pOffset)
|
|
aInRect.Move(pOffset->X(), pOffset->Y());
|
|
|
|
DrawTextFlags nTextStyle = DrawTextFlags::Left | DrawTextFlags::VCenter | DrawTextFlags::EndEllipsis | DrawTextFlags::Clip;
|
|
|
|
// must show tooltip ?
|
|
TextRectInfo aInfo;
|
|
rRenderContext.GetTextRect(aInRect, pBorderWindow->GetText(), nTextStyle, &aInfo);
|
|
pData->mbTitleClipped = aInfo.IsEllipses();
|
|
|
|
rRenderContext.DrawText(aInRect, pBorderWindow->GetText(), nTextStyle);
|
|
}
|
|
else
|
|
{
|
|
ToolBox::ImplDrawGrip(rRenderContext, aTitleRect, ToolBox::ImplGetDragWidth(rRenderContext, false),
|
|
WindowAlign::Left, false);
|
|
}
|
|
}
|
|
|
|
if (!pData->maCloseRect.IsEmpty())
|
|
{
|
|
tools::Rectangle aSymbolRect(pData->maCloseRect);
|
|
if (pOffset)
|
|
aSymbolRect.Move(pOffset->X(), pOffset->Y());
|
|
ImplDrawBrdWinSymbolButton(&rRenderContext, aSymbolRect, SymbolType::CLOSE, pData->mnCloseState);
|
|
}
|
|
if (!pData->maDockRect.IsEmpty())
|
|
{
|
|
tools::Rectangle aSymbolRect(pData->maDockRect);
|
|
if (pOffset)
|
|
aSymbolRect.Move(pOffset->X(), pOffset->Y());
|
|
ImplDrawBrdWinSymbolButton(&rRenderContext, aSymbolRect, SymbolType::DOCK, pData->mnDockState);
|
|
}
|
|
if (!pData->maMenuRect.IsEmpty())
|
|
{
|
|
tools::Rectangle aSymbolRect(pData->maMenuRect);
|
|
if (pOffset)
|
|
aSymbolRect.Move(pOffset->X(), pOffset->Y());
|
|
ImplDrawBrdWinSymbolButton(&rRenderContext, aSymbolRect, SymbolType::MENU, pData->mnMenuState);
|
|
}
|
|
if (!pData->maHideRect.IsEmpty())
|
|
{
|
|
tools::Rectangle aSymbolRect(pData->maHideRect);
|
|
if (pOffset)
|
|
aSymbolRect.Move(pOffset->X(), pOffset->Y());
|
|
ImplDrawBrdWinSymbolButton(&rRenderContext, aSymbolRect, SymbolType::HIDE, pData->mnHideState);
|
|
}
|
|
|
|
if (!pData->maHelpRect.IsEmpty())
|
|
{
|
|
tools::Rectangle aSymbolRect(pData->maHelpRect);
|
|
if (pOffset)
|
|
aSymbolRect.Move(pOffset->X(), pOffset->Y());
|
|
ImplDrawBrdWinSymbolButton(&rRenderContext, aSymbolRect, SymbolType::HELP, pData->mnHelpState);
|
|
}
|
|
}
|
|
|
|
void ImplBorderWindow::ImplInit( vcl::Window* pParent,
|
|
WinBits nStyle, BorderWindowStyle nTypeStyle,
|
|
SystemParentData* pSystemParentData
|
|
)
|
|
{
|
|
// remove all unwanted WindowBits
|
|
WinBits nOrgStyle = nStyle;
|
|
WinBits nTestStyle = (WB_MOVEABLE | WB_SIZEABLE | WB_CLOSEABLE | WB_STANDALONE | WB_DIALOGCONTROL | WB_NODIALOGCONTROL | WB_SYSTEMFLOATWIN | WB_INTROWIN | WB_DEFAULTWIN | WB_TOOLTIPWIN | WB_NOSHADOW | WB_OWNERDRAWDECORATION | WB_SYSTEMCHILDWINDOW | WB_POPUP);
|
|
if ( nTypeStyle & BorderWindowStyle::App )
|
|
nTestStyle |= WB_APP;
|
|
nStyle &= nTestStyle;
|
|
|
|
mpWindowImpl->mbBorderWin = true;
|
|
mbSmallOutBorder = false;
|
|
if ( nTypeStyle & BorderWindowStyle::Frame )
|
|
{
|
|
mpWindowImpl->mbOverlapWin = true;
|
|
mpWindowImpl->mbFrame = true;
|
|
|
|
if( nStyle & WB_SYSTEMCHILDWINDOW )
|
|
{
|
|
mbFrameBorder = false;
|
|
}
|
|
else if( nStyle & (WB_OWNERDRAWDECORATION | WB_POPUP) )
|
|
{
|
|
mbFrameBorder = (nOrgStyle & WB_NOBORDER) == 0;
|
|
}
|
|
else
|
|
{
|
|
mbFrameBorder = false;
|
|
// closeable windows may have a border as well, eg. system floating windows without caption
|
|
if ( (nOrgStyle & (WB_BORDER | WB_NOBORDER | WB_MOVEABLE | WB_SIZEABLE/* | WB_CLOSEABLE*/)) == WB_BORDER )
|
|
mbSmallOutBorder = true;
|
|
}
|
|
}
|
|
else if ( nTypeStyle & BorderWindowStyle::Overlap )
|
|
{
|
|
mpWindowImpl->mbOverlapWin = true;
|
|
mbFrameBorder = true;
|
|
}
|
|
else
|
|
mbFrameBorder = false;
|
|
|
|
if ( nTypeStyle & BorderWindowStyle::Float )
|
|
mbFloatWindow = true;
|
|
else
|
|
mbFloatWindow = false;
|
|
|
|
Window::ImplInit( pParent, nStyle, pSystemParentData );
|
|
SetBackground();
|
|
SetTextFillColor();
|
|
|
|
mpMenuBarWindow = nullptr;
|
|
mnMinWidth = 0;
|
|
mnMinHeight = 0;
|
|
mnMaxWidth = SHRT_MAX;
|
|
mnMaxHeight = SHRT_MAX;
|
|
mnOrgMenuHeight = 0;
|
|
mbMenuHide = false;
|
|
mbDockBtn = false;
|
|
mbMenuBtn = false;
|
|
mbHideBtn = false;
|
|
mbDisplayActive = IsActive();
|
|
|
|
if ( nTypeStyle & BorderWindowStyle::Float )
|
|
mnTitleType = BorderWindowTitleType::Small;
|
|
else
|
|
mnTitleType = BorderWindowTitleType::Normal;
|
|
mnBorderStyle = WindowBorderStyle::NORMAL;
|
|
InitView();
|
|
}
|
|
|
|
ImplBorderWindow::ImplBorderWindow( vcl::Window* pParent,
|
|
SystemParentData* pSystemParentData,
|
|
WinBits nStyle, BorderWindowStyle nTypeStyle
|
|
) : Window( WindowType::BORDERWINDOW )
|
|
{
|
|
ImplInit( pParent, nStyle, nTypeStyle, pSystemParentData );
|
|
}
|
|
|
|
ImplBorderWindow::ImplBorderWindow( vcl::Window* pParent, WinBits nStyle ,
|
|
BorderWindowStyle nTypeStyle ) :
|
|
Window( WindowType::BORDERWINDOW )
|
|
{
|
|
ImplInit( pParent, nStyle, nTypeStyle, nullptr );
|
|
}
|
|
|
|
ImplBorderWindow::~ImplBorderWindow()
|
|
{
|
|
disposeOnce();
|
|
}
|
|
|
|
void ImplBorderWindow::dispose()
|
|
{
|
|
mpBorderView.reset();
|
|
mpMenuBarWindow.clear();
|
|
mpNotebookBar.disposeAndClear();
|
|
vcl::Window::dispose();
|
|
}
|
|
|
|
void ImplBorderWindow::MouseMove( const MouseEvent& rMEvt )
|
|
{
|
|
if (mpBorderView)
|
|
mpBorderView->MouseMove( rMEvt );
|
|
}
|
|
|
|
void ImplBorderWindow::MouseButtonDown( const MouseEvent& rMEvt )
|
|
{
|
|
if (mpBorderView)
|
|
mpBorderView->MouseButtonDown( rMEvt );
|
|
}
|
|
|
|
void ImplBorderWindow::Tracking( const TrackingEvent& rTEvt )
|
|
{
|
|
if (mpBorderView)
|
|
mpBorderView->Tracking( rTEvt );
|
|
}
|
|
|
|
void ImplBorderWindow::Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& )
|
|
{
|
|
if (mpBorderView)
|
|
mpBorderView->DrawWindow(rRenderContext);
|
|
}
|
|
|
|
void ImplBorderWindow::Draw( OutputDevice* pOutDev, const Point& rPos )
|
|
{
|
|
if (mpBorderView)
|
|
mpBorderView->DrawWindow(*pOutDev, &rPos);
|
|
}
|
|
|
|
void ImplBorderWindow::Activate()
|
|
{
|
|
SetDisplayActive( true );
|
|
Window::Activate();
|
|
}
|
|
|
|
void ImplBorderWindow::Deactivate()
|
|
{
|
|
// remove active windows from the ruler, also ignore the Deactivate
|
|
// if a menu becomes active
|
|
if (GetActivateMode() != ActivateModeFlags::NONE && !ImplGetSVData()->mpWinData->mbNoDeactivate)
|
|
SetDisplayActive( false );
|
|
Window::Deactivate();
|
|
}
|
|
|
|
void ImplBorderWindow::RequestHelp( const HelpEvent& rHEvt )
|
|
{
|
|
// no keyboard help for border window
|
|
if ( rHEvt.GetMode() & (HelpEventMode::BALLOON | HelpEventMode::QUICK) && !rHEvt.KeyboardActivated() )
|
|
{
|
|
Point aMousePosPixel = ScreenToOutputPixel( rHEvt.GetMousePosPixel() );
|
|
tools::Rectangle aHelpRect;
|
|
OUString aHelpStr( mpBorderView->RequestHelp( aMousePosPixel, aHelpRect ) );
|
|
|
|
// retrieve rectangle
|
|
if ( !aHelpStr.isEmpty() )
|
|
{
|
|
aHelpRect.SetPos( OutputToScreenPixel( aHelpRect.TopLeft() ) );
|
|
if ( rHEvt.GetMode() & HelpEventMode::BALLOON )
|
|
Help::ShowBalloon( this, aHelpRect.Center(), aHelpRect, aHelpStr );
|
|
else
|
|
Help::ShowQuickHelp( this, aHelpRect, aHelpStr );
|
|
return;
|
|
}
|
|
}
|
|
|
|
Window::RequestHelp( rHEvt );
|
|
}
|
|
|
|
void ImplBorderWindow::Resize()
|
|
{
|
|
Size aSize = GetOutputSizePixel();
|
|
|
|
vcl::Window* pClientWindow = ImplGetClientWindow();
|
|
|
|
sal_Int32 nLeftBorder;
|
|
sal_Int32 nTopBorder;
|
|
sal_Int32 nRightBorder;
|
|
sal_Int32 nBottomBorder;
|
|
mpBorderView->GetBorder( nLeftBorder, nTopBorder, nRightBorder, nBottomBorder );
|
|
|
|
if (mpMenuBarWindow)
|
|
{
|
|
tools::Long nMenuHeight = mpMenuBarWindow->GetSizePixel().Height();
|
|
if ( mbMenuHide )
|
|
{
|
|
if ( nMenuHeight )
|
|
mnOrgMenuHeight = nMenuHeight;
|
|
nMenuHeight = 0;
|
|
}
|
|
else
|
|
{
|
|
if ( !nMenuHeight )
|
|
nMenuHeight = mnOrgMenuHeight;
|
|
}
|
|
mpMenuBarWindow->setPosSizePixel(
|
|
nLeftBorder, nTopBorder,
|
|
aSize.Width()-nLeftBorder-nRightBorder,
|
|
nMenuHeight);
|
|
|
|
// shift the notebookbar down accordingly
|
|
nTopBorder += nMenuHeight;
|
|
}
|
|
|
|
if (mpNotebookBar)
|
|
{
|
|
tools::Long nNotebookBarHeight = mpNotebookBar->GetSizePixel().Height();
|
|
mpNotebookBar->setPosSizePixel(
|
|
nLeftBorder, nTopBorder,
|
|
aSize.Width() - nLeftBorder - nRightBorder,
|
|
nNotebookBarHeight);
|
|
}
|
|
|
|
GetBorder( pClientWindow->mpWindowImpl->mnLeftBorder, pClientWindow->mpWindowImpl->mnTopBorder,
|
|
pClientWindow->mpWindowImpl->mnRightBorder, pClientWindow->mpWindowImpl->mnBottomBorder );
|
|
pClientWindow->ImplPosSizeWindow( pClientWindow->mpWindowImpl->mnLeftBorder,
|
|
pClientWindow->mpWindowImpl->mnTopBorder,
|
|
aSize.Width()-pClientWindow->mpWindowImpl->mnLeftBorder-pClientWindow->mpWindowImpl->mnRightBorder,
|
|
aSize.Height()-pClientWindow->mpWindowImpl->mnTopBorder-pClientWindow->mpWindowImpl->mnBottomBorder,
|
|
PosSizeFlags::X | PosSizeFlags::Y |
|
|
PosSizeFlags::Width | PosSizeFlags::Height );
|
|
|
|
// UpdateView
|
|
mpBorderView->Init( GetOutDev(), aSize.Width(), aSize.Height() );
|
|
InvalidateBorder();
|
|
|
|
Window::Resize();
|
|
}
|
|
|
|
void ImplBorderWindow::StateChanged( StateChangedType nType )
|
|
{
|
|
if ( (nType == StateChangedType::Text) ||
|
|
(nType == StateChangedType::Data) )
|
|
{
|
|
if (IsReallyVisible() && mbFrameBorder)
|
|
InvalidateBorder();
|
|
}
|
|
|
|
Window::StateChanged( nType );
|
|
}
|
|
|
|
void ImplBorderWindow::DataChanged( const DataChangedEvent& rDCEvt )
|
|
{
|
|
if ( (rDCEvt.GetType() == DataChangedEventType::FONTS) ||
|
|
(rDCEvt.GetType() == DataChangedEventType::FONTSUBSTITUTION) ||
|
|
((rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
|
|
(rDCEvt.GetFlags() & AllSettingsFlags::STYLE)) )
|
|
{
|
|
if ( !mpWindowImpl->mbFrame || (GetStyle() & (WB_OWNERDRAWDECORATION | WB_POPUP)) )
|
|
UpdateView( true, ImplGetWindow()->GetOutputSizePixel() );
|
|
}
|
|
|
|
Window::DataChanged( rDCEvt );
|
|
}
|
|
|
|
void ImplBorderWindow::InitView()
|
|
{
|
|
if ( mbSmallOutBorder )
|
|
mpBorderView.reset(new ImplSmallBorderWindowView( this ));
|
|
else if ( mpWindowImpl->mbFrame )
|
|
{
|
|
if( mbFrameBorder )
|
|
mpBorderView.reset(new ImplStdBorderWindowView( this ));
|
|
else
|
|
mpBorderView.reset(new ImplNoBorderWindowView);
|
|
}
|
|
else if ( !mbFrameBorder )
|
|
mpBorderView.reset(new ImplSmallBorderWindowView( this ));
|
|
else
|
|
mpBorderView.reset(new ImplStdBorderWindowView( this ));
|
|
Size aSize = GetOutputSizePixel();
|
|
mpBorderView->Init( GetOutDev(), aSize.Width(), aSize.Height() );
|
|
}
|
|
|
|
void ImplBorderWindow::UpdateView( bool bNewView, const Size& rNewOutSize )
|
|
{
|
|
sal_Int32 nLeftBorder;
|
|
sal_Int32 nTopBorder;
|
|
sal_Int32 nRightBorder;
|
|
sal_Int32 nBottomBorder;
|
|
Size aOldSize = GetSizePixel();
|
|
Size aOutputSize = rNewOutSize;
|
|
|
|
if ( bNewView )
|
|
{
|
|
mpBorderView.reset();
|
|
InitView();
|
|
}
|
|
else
|
|
{
|
|
Size aSize = aOutputSize;
|
|
mpBorderView->GetBorder( nLeftBorder, nTopBorder, nRightBorder, nBottomBorder );
|
|
aSize.AdjustWidth(nLeftBorder+nRightBorder );
|
|
aSize.AdjustHeight(nTopBorder+nBottomBorder );
|
|
mpBorderView->Init( GetOutDev(), aSize.Width(), aSize.Height() );
|
|
}
|
|
|
|
vcl::Window* pClientWindow = ImplGetClientWindow();
|
|
if ( pClientWindow )
|
|
{
|
|
GetBorder( pClientWindow->mpWindowImpl->mnLeftBorder, pClientWindow->mpWindowImpl->mnTopBorder,
|
|
pClientWindow->mpWindowImpl->mnRightBorder, pClientWindow->mpWindowImpl->mnBottomBorder );
|
|
}
|
|
GetBorder( nLeftBorder, nTopBorder, nRightBorder, nBottomBorder );
|
|
if ( aOldSize.Width() || aOldSize.Height() )
|
|
{
|
|
aOutputSize.AdjustWidth(nLeftBorder+nRightBorder );
|
|
aOutputSize.AdjustHeight(nTopBorder+nBottomBorder );
|
|
if ( aOutputSize == GetSizePixel() )
|
|
InvalidateBorder();
|
|
else
|
|
SetSizePixel( aOutputSize );
|
|
}
|
|
}
|
|
|
|
void ImplBorderWindow::InvalidateBorder()
|
|
{
|
|
if ( !IsReallyVisible() )
|
|
return;
|
|
|
|
// invalidate only if we have a border
|
|
sal_Int32 nLeftBorder;
|
|
sal_Int32 nTopBorder;
|
|
sal_Int32 nRightBorder;
|
|
sal_Int32 nBottomBorder;
|
|
mpBorderView->GetBorder( nLeftBorder, nTopBorder, nRightBorder, nBottomBorder );
|
|
if ( !(nLeftBorder || nTopBorder || nRightBorder || nBottomBorder) )
|
|
return;
|
|
|
|
tools::Rectangle aWinRect( Point( 0, 0 ), GetOutputSizePixel() );
|
|
vcl::Region aRegion( aWinRect );
|
|
aWinRect.AdjustLeft(nLeftBorder );
|
|
aWinRect.AdjustTop(nTopBorder );
|
|
aWinRect.AdjustRight( -nRightBorder );
|
|
aWinRect.AdjustBottom( -nBottomBorder );
|
|
// no output area anymore, now invalidate all
|
|
if ( (aWinRect.Right() < aWinRect.Left()) ||
|
|
(aWinRect.Bottom() < aWinRect.Top()) )
|
|
Invalidate( InvalidateFlags::NoChildren );
|
|
else
|
|
{
|
|
aRegion.Exclude( aWinRect );
|
|
Invalidate( aRegion, InvalidateFlags::NoChildren );
|
|
}
|
|
}
|
|
|
|
void ImplBorderWindow::SetDisplayActive( bool bActive )
|
|
{
|
|
if ( mbDisplayActive != bActive )
|
|
{
|
|
mbDisplayActive = bActive;
|
|
if ( mbFrameBorder )
|
|
InvalidateBorder();
|
|
}
|
|
}
|
|
|
|
void ImplBorderWindow::SetTitleType( BorderWindowTitleType nTitleType, const Size& rSize )
|
|
{
|
|
mnTitleType = nTitleType;
|
|
UpdateView( false, rSize );
|
|
}
|
|
|
|
void ImplBorderWindow::SetBorderStyle( WindowBorderStyle nStyle )
|
|
{
|
|
if ( !mbFrameBorder && (mnBorderStyle != nStyle) )
|
|
{
|
|
mnBorderStyle = nStyle;
|
|
UpdateView( false, ImplGetWindow()->GetOutputSizePixel() );
|
|
}
|
|
}
|
|
|
|
void ImplBorderWindow::SetCloseButton()
|
|
{
|
|
SetStyle( GetStyle() | WB_CLOSEABLE );
|
|
Size aSize = GetOutputSizePixel();
|
|
mpBorderView->Init( GetOutDev(), aSize.Width(), aSize.Height() );
|
|
InvalidateBorder();
|
|
}
|
|
|
|
void ImplBorderWindow::SetDockButton( bool bDockButton )
|
|
{
|
|
mbDockBtn = bDockButton;
|
|
Size aSize = GetOutputSizePixel();
|
|
mpBorderView->Init( GetOutDev(), aSize.Width(), aSize.Height() );
|
|
InvalidateBorder();
|
|
}
|
|
|
|
void ImplBorderWindow::SetHideButton( bool bHideButton )
|
|
{
|
|
mbHideBtn = bHideButton;
|
|
Size aSize = GetOutputSizePixel();
|
|
mpBorderView->Init( GetOutDev(), aSize.Width(), aSize.Height() );
|
|
InvalidateBorder();
|
|
}
|
|
|
|
void ImplBorderWindow::SetMenuButton( bool bMenuButton )
|
|
{
|
|
mbMenuBtn = bMenuButton;
|
|
Size aSize = GetOutputSizePixel();
|
|
mpBorderView->Init( GetOutDev(), aSize.Width(), aSize.Height() );
|
|
InvalidateBorder();
|
|
}
|
|
|
|
void ImplBorderWindow::UpdateMenuHeight()
|
|
{
|
|
Resize();
|
|
}
|
|
|
|
void ImplBorderWindow::SetMenuBarWindow( vcl::Window* pWindow )
|
|
{
|
|
mpMenuBarWindow = pWindow;
|
|
UpdateMenuHeight();
|
|
if ( pWindow )
|
|
pWindow->Show();
|
|
}
|
|
|
|
void ImplBorderWindow::SetMenuBarMode( bool bHide )
|
|
{
|
|
mbMenuHide = bHide;
|
|
UpdateMenuHeight();
|
|
}
|
|
|
|
void ImplBorderWindow::SetNotebookBar(const OUString& rUIXMLDescription,
|
|
const css::uno::Reference<css::frame::XFrame>& rFrame,
|
|
const NotebookBarAddonsItem& aNotebookBarAddonsItem)
|
|
{
|
|
if (mpNotebookBar)
|
|
mpNotebookBar.disposeAndClear();
|
|
mpNotebookBar = VclPtr<NotebookBar>::Create(this, "NotebookBar", rUIXMLDescription, rFrame,
|
|
aNotebookBarAddonsItem);
|
|
Resize();
|
|
}
|
|
|
|
void ImplBorderWindow::CloseNotebookBar()
|
|
{
|
|
if (mpNotebookBar)
|
|
mpNotebookBar.disposeAndClear();
|
|
mpNotebookBar = nullptr;
|
|
Resize();
|
|
}
|
|
|
|
void ImplBorderWindow::GetBorder( sal_Int32& rLeftBorder, sal_Int32& rTopBorder,
|
|
sal_Int32& rRightBorder, sal_Int32& rBottomBorder ) const
|
|
{
|
|
mpBorderView->GetBorder(rLeftBorder, rTopBorder, rRightBorder, rBottomBorder);
|
|
|
|
if (mpMenuBarWindow && !mbMenuHide)
|
|
rTopBorder += mpMenuBarWindow->GetSizePixel().Height();
|
|
|
|
if (mpNotebookBar && mpNotebookBar->IsVisible())
|
|
rTopBorder += mpNotebookBar->GetSizePixel().Height();
|
|
}
|
|
|
|
tools::Long ImplBorderWindow::CalcTitleWidth() const
|
|
{
|
|
return mpBorderView->CalcTitleWidth();
|
|
}
|
|
|
|
tools::Rectangle ImplBorderWindow::GetMenuRect() const
|
|
{
|
|
return mpBorderView->GetMenuRect();
|
|
}
|
|
|
|
Size ImplBorderWindow::GetOptimalSize() const
|
|
{
|
|
const vcl::Window* pClientWindow = ImplGetClientWindow();
|
|
if (pClientWindow)
|
|
return pClientWindow->GetOptimalSize();
|
|
return Size(mnMinWidth, mnMinHeight);
|
|
}
|
|
|
|
void ImplBorderWindow::queue_resize(StateChangedType eReason)
|
|
{
|
|
//if we are floating, then we don't want to inform our parent that it needs
|
|
//to calculate a new layout allocation. Because while we are a child
|
|
//of our parent we are not embedded into the parent so it doesn't care
|
|
//about us.
|
|
if (mbFloatWindow)
|
|
return;
|
|
vcl::Window::queue_resize(eReason);
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|