Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : */
9 :
10 : #include <basegfx/polygon/b2dpolygon.hxx>
11 : #include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
12 : #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
13 : #include <drawinglayer/processor2d/baseprocessor2d.hxx>
14 : #include <drawinglayer/processor2d/processorfromoutputdevice.hxx>
15 : #include <sfx2/bindings.hxx>
16 : #include <sfx2/dispatch.hxx>
17 : #include <sfx2/infobar.hxx>
18 : #include <sfx2/objsh.hxx>
19 : #include <sfx2/sfx.hrc>
20 : #include <sfx2/viewsh.hxx>
21 : #include <vcl/svapp.hxx>
22 : #include <vcl/settings.hxx>
23 :
24 : using namespace std;
25 :
26 : namespace
27 : {
28 : class SfxCloseButton : public PushButton
29 : {
30 : public:
31 2 : SfxCloseButton( vcl::Window* pParent ) : PushButton( pParent, 0 )
32 : {
33 2 : }
34 :
35 4 : virtual ~SfxCloseButton( ) { }
36 :
37 : virtual void Paint( const Rectangle& rRect ) SAL_OVERRIDE;
38 : };
39 :
40 2 : void SfxCloseButton::Paint( const Rectangle& )
41 : {
42 2 : const drawinglayer::geometry::ViewInformation2D aNewViewInfos;
43 : drawinglayer::processor2d::BaseProcessor2D * pProcessor =
44 : drawinglayer::processor2d::createBaseProcessor2DFromOutputDevice(
45 2 : *this, aNewViewInfos );
46 :
47 2 : const Rectangle aRect( Rectangle( Point( 0, 0 ), PixelToLogic( GetSizePixel() ) ) );
48 :
49 4 : drawinglayer::primitive2d::Primitive2DSequence aSeq( 2 );
50 :
51 4 : basegfx::BColor aLightColor( 1.0, 1.0, 191.0 / 255.0 );
52 4 : basegfx::BColor aDarkColor( 217.0 / 255.0, 217.0 / 255.0, 78.0 / 255.0 );
53 :
54 2 : const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
55 2 : if ( rSettings.GetHighContrastMode() )
56 : {
57 0 : aLightColor = rSettings.GetLightColor( ).getBColor( );
58 0 : aDarkColor = rSettings.GetDialogTextColor( ).getBColor( );
59 :
60 : }
61 :
62 : // Light background
63 4 : basegfx::B2DPolygon aPolygon;
64 2 : aPolygon.append( basegfx::B2DPoint( aRect.Left( ), aRect.Top( ) ) );
65 2 : aPolygon.append( basegfx::B2DPoint( aRect.Right( ), aRect.Top( ) ) );
66 2 : aPolygon.append( basegfx::B2DPoint( aRect.Right( ), aRect.Bottom( ) ) );
67 2 : aPolygon.append( basegfx::B2DPoint( aRect.Left( ), aRect.Bottom( ) ) );
68 2 : aPolygon.setClosed( true );
69 : drawinglayer::primitive2d::PolyPolygonColorPrimitive2D* pBack =
70 : new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(
71 2 : basegfx::B2DPolyPolygon( aPolygon ), aLightColor );
72 2 : aSeq[0] = pBack;
73 :
74 4 : drawinglayer::attribute::LineAttribute aLineAttribute( aDarkColor, 2.0 );
75 :
76 : // Cross
77 4 : basegfx::B2DPolyPolygon aCross;
78 4 : basegfx::B2DPolygon aLine1;
79 2 : aLine1.append( basegfx::B2DPoint( aRect.Left(), aRect.Top( ) ) );
80 2 : aLine1.append( basegfx::B2DPoint( aRect.Right(), aRect.Bottom( ) ) );
81 2 : aCross.append( aLine1 );
82 4 : basegfx::B2DPolygon aLine2;
83 2 : aLine2.append( basegfx::B2DPoint( aRect.Right(), aRect.Top( ) ) );
84 2 : aLine2.append( basegfx::B2DPoint( aRect.Left(), aRect.Bottom( ) ) );
85 2 : aCross.append( aLine2 );
86 :
87 : drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D * pCross =
88 : new drawinglayer::primitive2d::PolyPolygonStrokePrimitive2D (
89 2 : aCross, aLineAttribute, drawinglayer::attribute::StrokeAttribute( ) );
90 :
91 2 : aSeq[1] = pCross;
92 :
93 2 : pProcessor->process( aSeq );
94 4 : delete pProcessor;
95 2 : }
96 : }
97 :
98 2 : SfxInfoBarWindow::SfxInfoBarWindow( vcl::Window* pParent, const OUString& sId,
99 : const OUString& sMessage, vector< PushButton* > aButtons ) :
100 : Window( pParent, 0 ),
101 : m_sId( sId ),
102 : m_pMessage( NULL ),
103 : m_pCloseBtn( NULL ),
104 2 : m_aActionBtns( aButtons )
105 : {
106 2 : long nWidth = pParent->GetSizePixel().getWidth();
107 2 : SetPosSizePixel( Point( 0, 0 ), Size( nWidth, 40 ) );
108 2 : m_pMessage = new FixedText( this, 0 );
109 2 : m_pMessage->SetText( sMessage );
110 2 : m_pMessage->SetBackground( Wallpaper( Color( 255, 255, 191 ) ) );
111 2 : m_pMessage->Show( );
112 :
113 2 : m_pCloseBtn = new SfxCloseButton( this );
114 2 : m_pCloseBtn->SetPosSizePixel( Point( nWidth - 25, 15 ), Size( 10, 10 ) );
115 2 : m_pCloseBtn->SetClickHdl( LINK( this, SfxInfoBarWindow, CloseHandler ) );
116 2 : m_pCloseBtn->Show( );
117 :
118 : // Reparent the buttons and place them on the right of the bar
119 2 : long nX = m_pCloseBtn->GetPosPixel( ).getX( ) - 15;
120 2 : long nBtnGap = 5;
121 12 : for ( vector< PushButton* >::iterator it = m_aActionBtns.begin( );
122 8 : it != m_aActionBtns.end( ); ++it )
123 : {
124 2 : PushButton* pBtn = *it;
125 2 : pBtn->SetParent( this );
126 2 : long nBtnWidth = pBtn->GetSizePixel( ).getWidth();
127 2 : nX -= nBtnWidth;
128 2 : pBtn->SetPosSizePixel( Point( nX, 5 ), Size( nBtnWidth, 30 ) );
129 2 : nX -= nBtnGap;
130 2 : pBtn->Show( );
131 : }
132 :
133 2 : m_pMessage->SetPosSizePixel( Point( 10, 10 ), Size( nX - 20, 20 ) );
134 2 : }
135 :
136 6 : SfxInfoBarWindow::~SfxInfoBarWindow( )
137 : {
138 2 : delete m_pMessage;
139 2 : delete m_pCloseBtn;
140 :
141 12 : for ( vector< PushButton* >::iterator it = m_aActionBtns.begin( );
142 8 : it != m_aActionBtns.end( ); ++it )
143 : {
144 2 : delete *it;
145 : }
146 2 : m_aActionBtns.clear( );
147 4 : }
148 :
149 2 : void SfxInfoBarWindow::Paint( const Rectangle& rPaintRect )
150 : {
151 2 : const drawinglayer::geometry::ViewInformation2D aNewViewInfos;
152 : drawinglayer::processor2d::BaseProcessor2D * pProcessor =
153 : drawinglayer::processor2d::createBaseProcessor2DFromOutputDevice(
154 2 : *this, aNewViewInfos );
155 :
156 2 : const Rectangle aRect( Rectangle( Point( 0, 0 ), PixelToLogic( GetSizePixel() ) ) );
157 :
158 4 : drawinglayer::primitive2d::Primitive2DSequence aSeq( 2 );
159 :
160 4 : basegfx::BColor aLightColor( 1.0, 1.0, 191.0 / 255.0 );
161 4 : basegfx::BColor aDarkColor( 217.0 / 255.0, 217.0 / 255.0, 78.0 / 255.0 );
162 :
163 2 : const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
164 2 : if ( rSettings.GetHighContrastMode() )
165 : {
166 0 : aLightColor = rSettings.GetLightColor( ).getBColor( );
167 0 : aDarkColor = rSettings.GetDialogTextColor( ).getBColor( );
168 : }
169 :
170 : // Update the label background color
171 2 : m_pMessage->SetBackground( Wallpaper( Color( aLightColor ) ) );
172 :
173 : // Light background
174 4 : basegfx::B2DPolygon aPolygon;
175 2 : aPolygon.append( basegfx::B2DPoint( aRect.Left( ), aRect.Top( ) ) );
176 2 : aPolygon.append( basegfx::B2DPoint( aRect.Right( ), aRect.Top( ) ) );
177 2 : aPolygon.append( basegfx::B2DPoint( aRect.Right( ), aRect.Bottom( ) ) );
178 2 : aPolygon.append( basegfx::B2DPoint( aRect.Left( ), aRect.Bottom( ) ) );
179 2 : aPolygon.setClosed( true );
180 : drawinglayer::primitive2d::PolyPolygonColorPrimitive2D* pBack =
181 : new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(
182 2 : basegfx::B2DPolyPolygon( aPolygon ), aLightColor );
183 2 : aSeq[0] = pBack;
184 :
185 4 : drawinglayer::attribute::LineAttribute aLineAttribute( aDarkColor, 1.0 );
186 :
187 : // Bottom dark line
188 4 : basegfx::B2DPolygon aPolygonBottom;
189 2 : aPolygonBottom.append( basegfx::B2DPoint( aRect.Left(), aRect.Bottom( ) ) );
190 2 : aPolygonBottom.append( basegfx::B2DPoint( aRect.Right(), aRect.Bottom( ) ) );
191 :
192 : drawinglayer::primitive2d::PolygonStrokePrimitive2D * pLineBottom =
193 : new drawinglayer::primitive2d::PolygonStrokePrimitive2D (
194 2 : aPolygonBottom, aLineAttribute );
195 :
196 2 : aSeq[1] = pLineBottom;
197 :
198 2 : pProcessor->process( aSeq );
199 2 : delete pProcessor;
200 :
201 4 : Window::Paint( rPaintRect );
202 2 : }
203 :
204 4 : void SfxInfoBarWindow::Resize( )
205 : {
206 4 : long nWidth = GetSizePixel().getWidth();
207 4 : m_pCloseBtn->SetPosSizePixel( Point( nWidth - 25, 15 ), Size( 10, 10 ) );
208 :
209 : // Reparent the buttons and place them on the right of the bar
210 4 : long nX = m_pCloseBtn->GetPosPixel( ).getX( ) - 15;
211 4 : long nBtnGap = 5;
212 24 : for ( vector< PushButton* >::iterator it = m_aActionBtns.begin( );
213 16 : it != m_aActionBtns.end( ); ++it )
214 : {
215 4 : PushButton* pBtn = *it;
216 4 : long nBtnWidth = pBtn->GetSizePixel( ).getWidth();
217 4 : nX -= nBtnWidth;
218 4 : pBtn->SetPosSizePixel( Point( nX, 5 ), Size( nBtnWidth, 30 ) );
219 4 : nX -= nBtnGap;
220 : }
221 :
222 4 : m_pMessage->SetPosSizePixel( Point( 10, 10 ), Size( nX - 20, 20 ) );
223 4 : }
224 :
225 0 : IMPL_LINK_NOARG( SfxInfoBarWindow, CloseHandler )
226 : {
227 0 : static_cast<SfxInfoBarContainerWindow*>(GetParent())->removeInfoBar( this );
228 0 : return 0;
229 : }
230 :
231 5406 : SfxInfoBarContainerWindow::SfxInfoBarContainerWindow( SfxInfoBarContainerChild* pChildWin ) :
232 : Window( pChildWin->GetParent( ), 0 ),
233 : m_pChildWin( pChildWin ),
234 5406 : m_pInfoBars( )
235 : {
236 5406 : }
237 :
238 16218 : SfxInfoBarContainerWindow::~SfxInfoBarContainerWindow( )
239 : {
240 16224 : for ( vector< SfxInfoBarWindow* >::iterator it = m_pInfoBars.begin( );
241 10816 : it != m_pInfoBars.end( ); ++it )
242 : {
243 2 : delete *it;
244 : }
245 5406 : m_pInfoBars.clear( );
246 10812 : }
247 :
248 2 : void SfxInfoBarContainerWindow::appendInfoBar( const OUString& sId, const OUString& sMessage, vector< PushButton* > aButtons )
249 : {
250 2 : Size aSize = GetSizePixel( );
251 :
252 2 : SfxInfoBarWindow* pInfoBar = new SfxInfoBarWindow( this, sId, sMessage, aButtons );
253 2 : pInfoBar->SetPosPixel( Point( 0, aSize.getHeight( ) ) );
254 2 : pInfoBar->Show( );
255 2 : m_pInfoBars.push_back( pInfoBar );
256 :
257 2 : long nHeight = pInfoBar->GetSizePixel( ).getHeight( );
258 2 : aSize.setHeight( aSize.getHeight() + nHeight );
259 2 : SetSizePixel( aSize );
260 2 : }
261 :
262 0 : SfxInfoBarWindow* SfxInfoBarContainerWindow::getInfoBar( const OUString& sId )
263 : {
264 0 : SfxInfoBarWindow* pRet = NULL;
265 0 : for ( vector< SfxInfoBarWindow* >::iterator it = m_pInfoBars.begin( );
266 0 : it != m_pInfoBars.end( ) && pRet == NULL; ++it )
267 : {
268 0 : SfxInfoBarWindow* pBar = *it;
269 0 : if ( pBar->getId( ) == sId )
270 0 : pRet = pBar;
271 : }
272 0 : return pRet;
273 : }
274 :
275 0 : void SfxInfoBarContainerWindow::removeInfoBar( SfxInfoBarWindow* pInfoBar )
276 : {
277 0 : for ( vector< SfxInfoBarWindow* >::iterator it = m_pInfoBars.begin( );
278 0 : it != m_pInfoBars.end( ); ++it )
279 : {
280 0 : if ( pInfoBar == *it )
281 : {
282 0 : m_pInfoBars.erase( it );
283 0 : break;
284 : }
285 : }
286 0 : delete pInfoBar;
287 :
288 0 : long nY = 0;
289 0 : for ( vector< SfxInfoBarWindow* >::iterator it = m_pInfoBars.begin( ); it != m_pInfoBars.end( ); ++it )
290 : {
291 0 : SfxInfoBarWindow* pBar = *it;
292 0 : pBar->SetPosPixel( Point( 0, nY ) );
293 0 : nY += pBar->GetSizePixel( ).getHeight( );
294 : }
295 :
296 0 : Size aSize = GetSizePixel( );
297 0 : aSize.setHeight( nY );
298 0 : SetSizePixel( aSize );
299 :
300 0 : m_pChildWin->Update( );
301 0 : }
302 :
303 10814 : void SfxInfoBarContainerWindow::Resize( )
304 : {
305 : // Only need to change the width of the infobars
306 10814 : long nWidth = GetSizePixel( ).getWidth( );
307 32448 : for ( vector< SfxInfoBarWindow * >::iterator it = m_pInfoBars.begin( );
308 21632 : it != m_pInfoBars.end( ); ++it )
309 : {
310 2 : SfxInfoBarWindow* pInfoBar = *it;
311 2 : Size aSize = pInfoBar->GetSizePixel( );
312 2 : aSize.setWidth( nWidth );
313 2 : pInfoBar->SetSizePixel( aSize );
314 2 : pInfoBar->Resize( );
315 : }
316 10814 : }
317 :
318 6071 : SFX_IMPL_POS_CHILDWINDOW_WITHID( SfxInfoBarContainerChild, SID_INFOBARCONTAINER, SFX_OBJECTBAR_OBJECT );
319 :
320 5406 : SfxInfoBarContainerChild::SfxInfoBarContainerChild( vcl::Window* _pParent, sal_uInt16 nId, SfxBindings* pBindings, SfxChildWinInfo* ) :
321 : SfxChildWindow( _pParent, nId ),
322 5406 : m_pBindings( pBindings )
323 : {
324 5406 : pWindow = new SfxInfoBarContainerWindow( this );
325 5406 : pWindow->SetPosSizePixel( Point( 0, 0 ), Size( _pParent->GetSizePixel( ).getWidth(), 0 ) );
326 5406 : pWindow->Show( );
327 :
328 5406 : eChildAlignment = SFX_ALIGN_LOWESTTOP;
329 5406 : }
330 :
331 10812 : SfxInfoBarContainerChild::~SfxInfoBarContainerChild( )
332 : {
333 10812 : }
334 :
335 5424 : SfxChildWinInfo SfxInfoBarContainerChild::GetInfo( ) const
336 : {
337 5424 : SfxChildWinInfo aInfo = SfxChildWindow::GetInfo();
338 5424 : return aInfo;
339 : }
340 :
341 0 : void SfxInfoBarContainerChild::Update( )
342 : {
343 : // Refresh the frame to take the infobars container height change into account
344 0 : const sal_uInt16 nId = GetChildWindowId();
345 0 : SfxViewFrame* pVFrame = m_pBindings->GetDispatcher( )->GetFrame( );
346 0 : pVFrame->ShowChildWindow( nId );
347 :
348 : // Give the focus to the document view
349 0 : pVFrame->GetWindow().GrabFocusToDocument();
350 951 : }
351 :
352 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|