xref: /aoo42x/main/svx/source/dialog/dialcontrol.cxx (revision f6e50924)
1*f6e50924SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*f6e50924SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*f6e50924SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*f6e50924SAndrew Rist  * distributed with this work for additional information
6*f6e50924SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*f6e50924SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*f6e50924SAndrew Rist  * "License"); you may not use this file except in compliance
9*f6e50924SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*f6e50924SAndrew Rist  *
11*f6e50924SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*f6e50924SAndrew Rist  *
13*f6e50924SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*f6e50924SAndrew Rist  * software distributed under the License is distributed on an
15*f6e50924SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*f6e50924SAndrew Rist  * KIND, either express or implied.  See the License for the
17*f6e50924SAndrew Rist  * specific language governing permissions and limitations
18*f6e50924SAndrew Rist  * under the License.
19*f6e50924SAndrew Rist  *
20*f6e50924SAndrew Rist  *************************************************************/
21*f6e50924SAndrew Rist 
22*f6e50924SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_svx.hxx"
26cdf0e10cSrcweir #include "svx/dialcontrol.hxx"
27cdf0e10cSrcweir 
28cdf0e10cSrcweir #include <math.h>
29cdf0e10cSrcweir #include <vcl/virdev.hxx>
30cdf0e10cSrcweir #include <vcl/svapp.hxx>
31cdf0e10cSrcweir #include <vcl/bitmap.hxx>
32cdf0e10cSrcweir #include <vcl/field.hxx>
33cdf0e10cSrcweir #include <svtools/colorcfg.hxx>
34cdf0e10cSrcweir 
35cdf0e10cSrcweir namespace svx {
36cdf0e10cSrcweir 
37cdf0e10cSrcweir // ============================================================================
38cdf0e10cSrcweir 
39cdf0e10cSrcweir const long DIAL_OUTER_WIDTH = 8;
40cdf0e10cSrcweir 
41cdf0e10cSrcweir // ============================================================================
42cdf0e10cSrcweir 
43cdf0e10cSrcweir class DialControlBmp : public VirtualDevice
44cdf0e10cSrcweir {
45cdf0e10cSrcweir public:
46cdf0e10cSrcweir     explicit            DialControlBmp( Window& rParent );
47cdf0e10cSrcweir 
48cdf0e10cSrcweir     void                InitBitmap( const Size& rSize, const Font& rFont );
49cdf0e10cSrcweir     void                CopyBackground( const DialControlBmp& rSrc );
50cdf0e10cSrcweir     void                DrawBackground( const Size& rSize, bool bEnabled );
51cdf0e10cSrcweir     void                DrawElements( const String& rText, sal_Int32 nAngle );
52cdf0e10cSrcweir 
53cdf0e10cSrcweir private:
54cdf0e10cSrcweir     const Color&        GetBackgroundColor() const;
55cdf0e10cSrcweir     const Color&        GetTextColor() const;
56cdf0e10cSrcweir     const Color&        GetScaleLineColor() const;
57cdf0e10cSrcweir     const Color&        GetButtonLineColor() const;
58cdf0e10cSrcweir     const Color&        GetButtonFillColor( bool bMain ) const;
59cdf0e10cSrcweir 
60cdf0e10cSrcweir     void                Init( const Size& rSize );
61cdf0e10cSrcweir     void                DrawBackground();
62cdf0e10cSrcweir 
63cdf0e10cSrcweir     Window&             mrParent;
64cdf0e10cSrcweir     Rectangle           maRect;
65cdf0e10cSrcweir     long                mnCenterX;
66cdf0e10cSrcweir     long                mnCenterY;
67cdf0e10cSrcweir     bool                mbEnabled;
68cdf0e10cSrcweir };
69cdf0e10cSrcweir 
70cdf0e10cSrcweir // ----------------------------------------------------------------------------
71cdf0e10cSrcweir 
72cdf0e10cSrcweir DialControlBmp::DialControlBmp( Window& rParent ) :
73cdf0e10cSrcweir     VirtualDevice( rParent, 0, 0 ),
74cdf0e10cSrcweir     mrParent( rParent ),
75cdf0e10cSrcweir     mbEnabled( true )
76cdf0e10cSrcweir {
77cdf0e10cSrcweir     EnableRTL( sal_False );
78cdf0e10cSrcweir }
79cdf0e10cSrcweir 
80cdf0e10cSrcweir void DialControlBmp::InitBitmap( const Size& rSize, const Font& rFont )
81cdf0e10cSrcweir {
82cdf0e10cSrcweir     Init( rSize );
83cdf0e10cSrcweir     SetFont( rFont );
84cdf0e10cSrcweir }
85cdf0e10cSrcweir 
86cdf0e10cSrcweir void DialControlBmp::CopyBackground( const DialControlBmp& rSrc )
87cdf0e10cSrcweir {
88cdf0e10cSrcweir     Init( rSrc.maRect.GetSize() );
89cdf0e10cSrcweir     mbEnabled = rSrc.mbEnabled;
90cdf0e10cSrcweir     Point aPos;
91cdf0e10cSrcweir     DrawBitmapEx( aPos, rSrc.GetBitmapEx( aPos, maRect.GetSize() ) );
92cdf0e10cSrcweir }
93cdf0e10cSrcweir 
94cdf0e10cSrcweir void DialControlBmp::DrawBackground( const Size& rSize, bool bEnabled )
95cdf0e10cSrcweir {
96cdf0e10cSrcweir     Init( rSize );
97cdf0e10cSrcweir     mbEnabled = bEnabled;
98cdf0e10cSrcweir     DrawBackground();
99cdf0e10cSrcweir }
100cdf0e10cSrcweir 
101cdf0e10cSrcweir void DialControlBmp::DrawElements( const String& rText, sal_Int32 nAngle )
102cdf0e10cSrcweir {
103cdf0e10cSrcweir     // *** rotated text ***
104cdf0e10cSrcweir 
105cdf0e10cSrcweir     Font aFont( GetFont() );
106cdf0e10cSrcweir     aFont.SetColor( GetTextColor() );
107cdf0e10cSrcweir     aFont.SetOrientation( static_cast< short >( (nAngle + 5) / 10 ) );  // Font uses 1/10 degrees
108cdf0e10cSrcweir     aFont.SetWeight( WEIGHT_BOLD );
109cdf0e10cSrcweir     SetFont( aFont );
110cdf0e10cSrcweir 
111cdf0e10cSrcweir     double fAngle = nAngle * F_PI180 / 100.0;
112cdf0e10cSrcweir     double fSin = sin( fAngle );
113cdf0e10cSrcweir     double fCos = cos( fAngle );
114cdf0e10cSrcweir     double fWidth = GetTextWidth( rText ) / 2.0;
115cdf0e10cSrcweir     double fHeight = GetTextHeight() / 2.0;
116cdf0e10cSrcweir     long nX = static_cast< long >( mnCenterX - fWidth * fCos - fHeight * fSin );
117cdf0e10cSrcweir     long nY = static_cast< long >( mnCenterY + fWidth * fSin - fHeight * fCos );
118cdf0e10cSrcweir     Rectangle aRect( nX, nY, 2 * mnCenterX - nX, 2 * mnCenterY - nY );
119cdf0e10cSrcweir     DrawText( aRect, rText, mbEnabled ? 0 : TEXT_DRAW_DISABLE );
120cdf0e10cSrcweir 
121cdf0e10cSrcweir     // *** drag button ***
122cdf0e10cSrcweir 
123cdf0e10cSrcweir     bool bMain = (nAngle % 4500) != 0;
124cdf0e10cSrcweir     SetLineColor( GetButtonLineColor() );
125cdf0e10cSrcweir     SetFillColor( GetButtonFillColor( bMain ) );
126cdf0e10cSrcweir 
127cdf0e10cSrcweir     nX = mnCenterX - static_cast< long >( (DIAL_OUTER_WIDTH / 2 - mnCenterX) * fCos );
128cdf0e10cSrcweir     nY = mnCenterY - static_cast< long >( (mnCenterY - DIAL_OUTER_WIDTH / 2) * fSin );
129cdf0e10cSrcweir     long nSize = bMain ? (DIAL_OUTER_WIDTH / 4) : (DIAL_OUTER_WIDTH / 2 - 1);
130cdf0e10cSrcweir     DrawEllipse( Rectangle( nX - nSize, nY - nSize, nX + nSize, nY + nSize ) );
131cdf0e10cSrcweir }
132cdf0e10cSrcweir 
133cdf0e10cSrcweir // private --------------------------------------------------------------------
134cdf0e10cSrcweir 
135cdf0e10cSrcweir const Color& DialControlBmp::GetBackgroundColor() const
136cdf0e10cSrcweir {
137cdf0e10cSrcweir     return GetSettings().GetStyleSettings().GetDialogColor();
138cdf0e10cSrcweir }
139cdf0e10cSrcweir 
140cdf0e10cSrcweir const Color& DialControlBmp::GetTextColor() const
141cdf0e10cSrcweir {
142cdf0e10cSrcweir     return GetSettings().GetStyleSettings().GetLabelTextColor();
143cdf0e10cSrcweir }
144cdf0e10cSrcweir 
145cdf0e10cSrcweir const Color& DialControlBmp::GetScaleLineColor() const
146cdf0e10cSrcweir {
147cdf0e10cSrcweir     const StyleSettings& rSett = GetSettings().GetStyleSettings();
148cdf0e10cSrcweir     return mbEnabled ? rSett.GetButtonTextColor() : rSett.GetDisableColor();
149cdf0e10cSrcweir }
150cdf0e10cSrcweir 
151cdf0e10cSrcweir const Color& DialControlBmp::GetButtonLineColor() const
152cdf0e10cSrcweir {
153cdf0e10cSrcweir     const StyleSettings& rSett = GetSettings().GetStyleSettings();
154cdf0e10cSrcweir     return mbEnabled ? rSett.GetButtonTextColor() : rSett.GetDisableColor();
155cdf0e10cSrcweir }
156cdf0e10cSrcweir 
157cdf0e10cSrcweir const Color& DialControlBmp::GetButtonFillColor( bool bMain ) const
158cdf0e10cSrcweir {
159cdf0e10cSrcweir     const StyleSettings& rSett = GetSettings().GetStyleSettings();
160cdf0e10cSrcweir     return mbEnabled ? (bMain ? rSett.GetMenuColor() : rSett.GetHighlightColor()) : rSett.GetDisableColor();
161cdf0e10cSrcweir }
162cdf0e10cSrcweir 
163cdf0e10cSrcweir void DialControlBmp::Init( const Size& rSize )
164cdf0e10cSrcweir {
165cdf0e10cSrcweir     SetSettings( mrParent.GetSettings() );
166cdf0e10cSrcweir     maRect.SetPos( Point( 0, 0 ) );
167cdf0e10cSrcweir     maRect.SetSize( rSize );
168cdf0e10cSrcweir     mnCenterX = rSize.Width() / 2;
169cdf0e10cSrcweir     mnCenterY = rSize.Height() / 2;
170cdf0e10cSrcweir     SetOutputSize( rSize );
171cdf0e10cSrcweir     SetBackground();
172cdf0e10cSrcweir }
173cdf0e10cSrcweir 
174cdf0e10cSrcweir void DialControlBmp::DrawBackground()
175cdf0e10cSrcweir {
176cdf0e10cSrcweir     // *** background with 3D effect ***
177cdf0e10cSrcweir 
178cdf0e10cSrcweir     SetLineColor();
179cdf0e10cSrcweir     SetFillColor();
180cdf0e10cSrcweir     Erase();
181cdf0e10cSrcweir 
182cdf0e10cSrcweir     EnableRTL( sal_True ); // #107807# draw 3D effect in correct direction
183cdf0e10cSrcweir 
184cdf0e10cSrcweir     sal_uInt8 nDiff = mbEnabled ? 0x18 : 0x10;
185cdf0e10cSrcweir     Color aColor;
186cdf0e10cSrcweir 
187cdf0e10cSrcweir     aColor = GetBackgroundColor();
188cdf0e10cSrcweir     SetFillColor( aColor );
189cdf0e10cSrcweir     DrawPie( maRect, maRect.TopRight(), maRect.TopCenter() );
190cdf0e10cSrcweir     DrawPie( maRect, maRect.BottomLeft(), maRect.BottomCenter() );
191cdf0e10cSrcweir 
192cdf0e10cSrcweir     aColor.DecreaseLuminance( nDiff );
193cdf0e10cSrcweir     SetFillColor( aColor );
194cdf0e10cSrcweir     DrawPie( maRect, maRect.BottomCenter(), maRect.TopRight() );
195cdf0e10cSrcweir 
196cdf0e10cSrcweir     aColor.DecreaseLuminance( nDiff );
197cdf0e10cSrcweir     SetFillColor( aColor );
198cdf0e10cSrcweir     DrawPie( maRect, maRect.BottomRight(), maRect.RightCenter() );
199cdf0e10cSrcweir 
200cdf0e10cSrcweir     aColor = GetBackgroundColor();
201cdf0e10cSrcweir     aColor.IncreaseLuminance( nDiff );
202cdf0e10cSrcweir     SetFillColor( aColor );
203cdf0e10cSrcweir     DrawPie( maRect, maRect.TopCenter(), maRect.BottomLeft() );
204cdf0e10cSrcweir 
205cdf0e10cSrcweir     aColor.IncreaseLuminance( nDiff );
206cdf0e10cSrcweir     SetFillColor( aColor );
207cdf0e10cSrcweir     DrawPie( maRect, maRect.TopLeft(), maRect.LeftCenter() );
208cdf0e10cSrcweir 
209cdf0e10cSrcweir     EnableRTL( sal_False );
210cdf0e10cSrcweir 
211cdf0e10cSrcweir     // *** calibration ***
212cdf0e10cSrcweir 
213cdf0e10cSrcweir     Point aStartPos( mnCenterX, mnCenterY );
214cdf0e10cSrcweir     Color aFullColor( GetScaleLineColor() );
215cdf0e10cSrcweir     Color aLightColor( GetBackgroundColor() );
216cdf0e10cSrcweir     aLightColor.Merge( aFullColor, 128 );
217cdf0e10cSrcweir 
218cdf0e10cSrcweir     for( int nAngle = 0; nAngle < 360; nAngle += 15 )
219cdf0e10cSrcweir     {
220cdf0e10cSrcweir         SetLineColor( (nAngle % 45) ? aLightColor : aFullColor );
221cdf0e10cSrcweir         double fAngle = nAngle * F_PI180;
222cdf0e10cSrcweir         long nX = static_cast< long >( -mnCenterX * cos( fAngle ) );
223cdf0e10cSrcweir         long nY = static_cast< long >( mnCenterY * sin( fAngle ) );
224cdf0e10cSrcweir         DrawLine( aStartPos, Point( mnCenterX - nX, mnCenterY - nY ) );
225cdf0e10cSrcweir     }
226cdf0e10cSrcweir 
227cdf0e10cSrcweir     // *** clear inner area ***
228cdf0e10cSrcweir 
229cdf0e10cSrcweir     SetLineColor();
230cdf0e10cSrcweir     SetFillColor( GetBackgroundColor() );
231cdf0e10cSrcweir     DrawEllipse( Rectangle( maRect.Left() + DIAL_OUTER_WIDTH, maRect.Top() + DIAL_OUTER_WIDTH,
232cdf0e10cSrcweir         maRect.Right() - DIAL_OUTER_WIDTH, maRect.Bottom() - DIAL_OUTER_WIDTH ) );
233cdf0e10cSrcweir }
234cdf0e10cSrcweir 
235cdf0e10cSrcweir // ============================================================================
236cdf0e10cSrcweir 
237cdf0e10cSrcweir struct DialControl_Impl
238cdf0e10cSrcweir {
239cdf0e10cSrcweir     DialControlBmp      maBmpEnabled;
240cdf0e10cSrcweir     DialControlBmp      maBmpDisabled;
241cdf0e10cSrcweir     DialControlBmp      maBmpBuffered;
242cdf0e10cSrcweir     Link                maModifyHdl;
243cdf0e10cSrcweir     NumericField*       mpLinkField;
244cdf0e10cSrcweir     Size                maWinSize;
245cdf0e10cSrcweir     Font                maWinFont;
246cdf0e10cSrcweir     sal_Int32           mnAngle;
247cdf0e10cSrcweir     sal_Int32           mnOldAngle;
248cdf0e10cSrcweir     long                mnCenterX;
249cdf0e10cSrcweir     long                mnCenterY;
250cdf0e10cSrcweir     bool                mbNoRot;
251cdf0e10cSrcweir 
252cdf0e10cSrcweir     explicit            DialControl_Impl( Window& rParent );
253cdf0e10cSrcweir     void                Init( const Size& rWinSize, const Font& rWinFont );
254cdf0e10cSrcweir };
255cdf0e10cSrcweir 
256cdf0e10cSrcweir // ----------------------------------------------------------------------------
257cdf0e10cSrcweir 
258cdf0e10cSrcweir DialControl_Impl::DialControl_Impl( Window& rParent ) :
259cdf0e10cSrcweir     maBmpEnabled( rParent ),
260cdf0e10cSrcweir     maBmpDisabled( rParent ),
261cdf0e10cSrcweir     maBmpBuffered( rParent ),
262cdf0e10cSrcweir     mpLinkField( 0 ),
263cdf0e10cSrcweir     mnAngle( 0 ),
264cdf0e10cSrcweir     mbNoRot( false )
265cdf0e10cSrcweir {
266cdf0e10cSrcweir }
267cdf0e10cSrcweir 
268cdf0e10cSrcweir void DialControl_Impl::Init( const Size& rWinSize, const Font& rWinFont )
269cdf0e10cSrcweir {
270cdf0e10cSrcweir     // "(x - 1) | 1" creates odd value <= x, to have a well-defined center pixel position
271cdf0e10cSrcweir     maWinSize = Size( (rWinSize.Width() - 1) | 1, (rWinSize.Height() - 1) | 1 );
272cdf0e10cSrcweir     maWinFont = rWinFont;
273cdf0e10cSrcweir 
274cdf0e10cSrcweir     mnCenterX = maWinSize.Width() / 2;
275cdf0e10cSrcweir     mnCenterY = maWinSize.Height() / 2;
276cdf0e10cSrcweir     maWinFont.SetTransparent( sal_True );
277cdf0e10cSrcweir 
278cdf0e10cSrcweir     maBmpEnabled.DrawBackground( maWinSize, true );
279cdf0e10cSrcweir     maBmpDisabled.DrawBackground( maWinSize, false );
280cdf0e10cSrcweir     maBmpBuffered.InitBitmap( maWinSize, maWinFont );
281cdf0e10cSrcweir }
282cdf0e10cSrcweir 
283cdf0e10cSrcweir // ============================================================================
284cdf0e10cSrcweir 
285cdf0e10cSrcweir DialControl::DialControl( Window* pParent, const Size& rSize, const Font& rFont, WinBits nWinStyle ) :
286cdf0e10cSrcweir     Control( pParent, nWinStyle ),
287cdf0e10cSrcweir     mpImpl( new DialControl_Impl( *this ) )
288cdf0e10cSrcweir {
289cdf0e10cSrcweir     Init( rSize, rFont );
290cdf0e10cSrcweir }
291cdf0e10cSrcweir 
292cdf0e10cSrcweir DialControl::DialControl( Window* pParent, const Size& rSize, WinBits nWinStyle ) :
293cdf0e10cSrcweir     Control( pParent, nWinStyle ),
294cdf0e10cSrcweir     mpImpl( new DialControl_Impl( *this ) )
295cdf0e10cSrcweir {
296cdf0e10cSrcweir     if( pParent )
297cdf0e10cSrcweir         Init( rSize, pParent->GetFont() );
298cdf0e10cSrcweir     else
299cdf0e10cSrcweir         Init( rSize );
300cdf0e10cSrcweir }
301cdf0e10cSrcweir 
302cdf0e10cSrcweir DialControl::DialControl( Window* pParent, const ResId& rResId ) :
303cdf0e10cSrcweir     Control( pParent, rResId ),
304cdf0e10cSrcweir     mpImpl( new DialControl_Impl( *this ) )
305cdf0e10cSrcweir {
306cdf0e10cSrcweir     Init( GetOutputSizePixel() );
307cdf0e10cSrcweir }
308cdf0e10cSrcweir 
309cdf0e10cSrcweir DialControl::~DialControl()
310cdf0e10cSrcweir {
311cdf0e10cSrcweir }
312cdf0e10cSrcweir 
313cdf0e10cSrcweir void DialControl::Paint( const Rectangle&  )
314cdf0e10cSrcweir {
315cdf0e10cSrcweir     Point aPos;
316cdf0e10cSrcweir     DrawBitmapEx( aPos, mpImpl->maBmpBuffered.GetBitmapEx( aPos, mpImpl->maWinSize ) );
317cdf0e10cSrcweir }
318cdf0e10cSrcweir 
319cdf0e10cSrcweir void DialControl::StateChanged( StateChangedType nStateChange )
320cdf0e10cSrcweir {
321cdf0e10cSrcweir     if( nStateChange == STATE_CHANGE_ENABLE )
322cdf0e10cSrcweir         InvalidateControl();
323cdf0e10cSrcweir 
324cdf0e10cSrcweir     // update the linked edit field
325cdf0e10cSrcweir     if( mpImpl->mpLinkField )
326cdf0e10cSrcweir     {
327cdf0e10cSrcweir         NumericField& rField = *mpImpl->mpLinkField;
328cdf0e10cSrcweir         switch( nStateChange )
329cdf0e10cSrcweir         {
330cdf0e10cSrcweir             case STATE_CHANGE_VISIBLE:  rField.Show( IsVisible() );     break;
331cdf0e10cSrcweir             case STATE_CHANGE_ENABLE:   rField.Enable( IsEnabled() );   break;
332cdf0e10cSrcweir         }
333cdf0e10cSrcweir     }
334cdf0e10cSrcweir 
335cdf0e10cSrcweir     Control::StateChanged( nStateChange );
336cdf0e10cSrcweir }
337cdf0e10cSrcweir 
338cdf0e10cSrcweir void DialControl::DataChanged( const DataChangedEvent& rDCEvt )
339cdf0e10cSrcweir {
340cdf0e10cSrcweir     if( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_STYLE) )
341cdf0e10cSrcweir     {
342cdf0e10cSrcweir         Init( mpImpl->maWinSize, mpImpl->maWinFont );
343cdf0e10cSrcweir         InvalidateControl();
344cdf0e10cSrcweir     }
345cdf0e10cSrcweir     Control::DataChanged( rDCEvt );
346cdf0e10cSrcweir }
347cdf0e10cSrcweir 
348cdf0e10cSrcweir void DialControl::MouseButtonDown( const MouseEvent& rMEvt )
349cdf0e10cSrcweir {
350cdf0e10cSrcweir     if( rMEvt.IsLeft() )
351cdf0e10cSrcweir     {
352cdf0e10cSrcweir         GrabFocus();
353cdf0e10cSrcweir         CaptureMouse();
354cdf0e10cSrcweir         mpImpl->mnOldAngle = mpImpl->mnAngle;
355cdf0e10cSrcweir         HandleMouseEvent( rMEvt.GetPosPixel(), true );
356cdf0e10cSrcweir     }
357cdf0e10cSrcweir     Control::MouseButtonDown( rMEvt );
358cdf0e10cSrcweir }
359cdf0e10cSrcweir 
360cdf0e10cSrcweir void DialControl::MouseMove( const MouseEvent& rMEvt )
361cdf0e10cSrcweir {
362cdf0e10cSrcweir     if( IsMouseCaptured() && rMEvt.IsLeft() )
363cdf0e10cSrcweir         HandleMouseEvent( rMEvt.GetPosPixel(), false );
364cdf0e10cSrcweir     Control::MouseMove(rMEvt );
365cdf0e10cSrcweir }
366cdf0e10cSrcweir 
367cdf0e10cSrcweir void DialControl::MouseButtonUp( const MouseEvent& rMEvt )
368cdf0e10cSrcweir {
369cdf0e10cSrcweir     if( IsMouseCaptured() )
370cdf0e10cSrcweir     {
371cdf0e10cSrcweir         ReleaseMouse();
372cdf0e10cSrcweir         if( mpImpl->mpLinkField )
373cdf0e10cSrcweir             mpImpl->mpLinkField->GrabFocus();
374cdf0e10cSrcweir     }
375cdf0e10cSrcweir     Control::MouseButtonUp( rMEvt );
376cdf0e10cSrcweir }
377cdf0e10cSrcweir 
378cdf0e10cSrcweir void DialControl::KeyInput( const KeyEvent& rKEvt )
379cdf0e10cSrcweir {
380cdf0e10cSrcweir     const KeyCode& rKCode = rKEvt.GetKeyCode();
381cdf0e10cSrcweir     if( !rKCode.GetModifier() && (rKCode.GetCode() == KEY_ESCAPE) )
382cdf0e10cSrcweir         HandleEscapeEvent();
383cdf0e10cSrcweir     else
384cdf0e10cSrcweir         Control::KeyInput( rKEvt );
385cdf0e10cSrcweir }
386cdf0e10cSrcweir 
387cdf0e10cSrcweir void DialControl::LoseFocus()
388cdf0e10cSrcweir {
389cdf0e10cSrcweir     // release captured mouse
390cdf0e10cSrcweir     HandleEscapeEvent();
391cdf0e10cSrcweir     Control::LoseFocus();
392cdf0e10cSrcweir }
393cdf0e10cSrcweir 
394cdf0e10cSrcweir bool DialControl::HasRotation() const
395cdf0e10cSrcweir {
396cdf0e10cSrcweir     return !mpImpl->mbNoRot;
397cdf0e10cSrcweir }
398cdf0e10cSrcweir 
399cdf0e10cSrcweir void DialControl::SetNoRotation()
400cdf0e10cSrcweir {
401cdf0e10cSrcweir     if( !mpImpl->mbNoRot )
402cdf0e10cSrcweir     {
403cdf0e10cSrcweir         mpImpl->mbNoRot = true;
404cdf0e10cSrcweir         InvalidateControl();
405cdf0e10cSrcweir         if( mpImpl->mpLinkField )
406cdf0e10cSrcweir             mpImpl->mpLinkField->SetText( String() );
407cdf0e10cSrcweir     }
408cdf0e10cSrcweir }
409cdf0e10cSrcweir 
410cdf0e10cSrcweir sal_Int32 DialControl::GetRotation() const
411cdf0e10cSrcweir {
412cdf0e10cSrcweir     return mpImpl->mnAngle;
413cdf0e10cSrcweir }
414cdf0e10cSrcweir 
415cdf0e10cSrcweir void DialControl::SetRotation( sal_Int32 nAngle )
416cdf0e10cSrcweir {
417cdf0e10cSrcweir     ImplSetRotation( nAngle, false );
418cdf0e10cSrcweir }
419cdf0e10cSrcweir 
420cdf0e10cSrcweir void DialControl::SetLinkedField( NumericField* pField )
421cdf0e10cSrcweir {
422cdf0e10cSrcweir     // remove modify handler from old linked field
423cdf0e10cSrcweir     ImplSetFieldLink( Link() );
424cdf0e10cSrcweir     // remember the new linked field
425cdf0e10cSrcweir     mpImpl->mpLinkField = pField;
426cdf0e10cSrcweir     // set modify handler at new linked field
427cdf0e10cSrcweir     ImplSetFieldLink( LINK( this, DialControl, LinkedFieldModifyHdl ) );
428cdf0e10cSrcweir }
429cdf0e10cSrcweir 
430cdf0e10cSrcweir NumericField* DialControl::GetLinkedField() const
431cdf0e10cSrcweir {
432cdf0e10cSrcweir     return mpImpl->mpLinkField;
433cdf0e10cSrcweir }
434cdf0e10cSrcweir 
435cdf0e10cSrcweir void DialControl::SetModifyHdl( const Link& rLink )
436cdf0e10cSrcweir {
437cdf0e10cSrcweir     mpImpl->maModifyHdl = rLink;
438cdf0e10cSrcweir }
439cdf0e10cSrcweir 
440cdf0e10cSrcweir const Link& DialControl::GetModifyHdl() const
441cdf0e10cSrcweir {
442cdf0e10cSrcweir     return mpImpl->maModifyHdl;
443cdf0e10cSrcweir }
444cdf0e10cSrcweir 
445cdf0e10cSrcweir // private --------------------------------------------------------------------
446cdf0e10cSrcweir 
447cdf0e10cSrcweir void DialControl::Init( const Size& rWinSize, const Font& rWinFont )
448cdf0e10cSrcweir {
449cdf0e10cSrcweir     mpImpl->Init( rWinSize, rWinFont );
450cdf0e10cSrcweir     EnableRTL( sal_False ); // #107807# don't mirror mouse handling
451cdf0e10cSrcweir     SetOutputSizePixel( mpImpl->maWinSize );
452cdf0e10cSrcweir     SetBackground();
453cdf0e10cSrcweir }
454cdf0e10cSrcweir 
455cdf0e10cSrcweir void DialControl::Init( const Size& rWinSize )
456cdf0e10cSrcweir {
457cdf0e10cSrcweir     Font aFont( OutputDevice::GetDefaultFont(
458cdf0e10cSrcweir         DEFAULTFONT_UI_SANS, Application::GetSettings().GetUILanguage(), DEFAULTFONT_FLAGS_ONLYONE ) );
459cdf0e10cSrcweir     Init( rWinSize, aFont );
460cdf0e10cSrcweir }
461cdf0e10cSrcweir 
462cdf0e10cSrcweir void DialControl::InvalidateControl()
463cdf0e10cSrcweir {
464cdf0e10cSrcweir     mpImpl->maBmpBuffered.CopyBackground( IsEnabled() ? mpImpl->maBmpEnabled : mpImpl->maBmpDisabled );
465cdf0e10cSrcweir     if( !mpImpl->mbNoRot )
466cdf0e10cSrcweir         mpImpl->maBmpBuffered.DrawElements( GetText(), mpImpl->mnAngle );
467cdf0e10cSrcweir     Invalidate();
468cdf0e10cSrcweir }
469cdf0e10cSrcweir 
470cdf0e10cSrcweir void DialControl::ImplSetRotation( sal_Int32 nAngle, bool bBroadcast )
471cdf0e10cSrcweir {
472cdf0e10cSrcweir     bool bOldSel = mpImpl->mbNoRot;
473cdf0e10cSrcweir     mpImpl->mbNoRot = false;
474cdf0e10cSrcweir 
475cdf0e10cSrcweir     while( nAngle < 0 ) nAngle += 36000;
476cdf0e10cSrcweir     nAngle = (((nAngle + 50) / 100) * 100) % 36000;
477cdf0e10cSrcweir     if( !bOldSel || (mpImpl->mnAngle != nAngle) )
478cdf0e10cSrcweir     {
479cdf0e10cSrcweir         mpImpl->mnAngle = nAngle;
480cdf0e10cSrcweir         InvalidateControl();
481cdf0e10cSrcweir         if( mpImpl->mpLinkField )
482cdf0e10cSrcweir             mpImpl->mpLinkField->SetValue( static_cast< long >( GetRotation() / 100 ) );
483cdf0e10cSrcweir         if( bBroadcast )
484cdf0e10cSrcweir             mpImpl->maModifyHdl.Call( this );
485cdf0e10cSrcweir     }
486cdf0e10cSrcweir }
487cdf0e10cSrcweir 
488cdf0e10cSrcweir void DialControl::ImplSetFieldLink( const Link& rLink )
489cdf0e10cSrcweir {
490cdf0e10cSrcweir     if( mpImpl->mpLinkField )
491cdf0e10cSrcweir     {
492cdf0e10cSrcweir         NumericField& rField = *mpImpl->mpLinkField;
493cdf0e10cSrcweir         rField.SetModifyHdl( rLink );
494cdf0e10cSrcweir         rField.SetUpHdl( rLink );
495cdf0e10cSrcweir         rField.SetDownHdl( rLink );
496cdf0e10cSrcweir         rField.SetFirstHdl( rLink );
497cdf0e10cSrcweir         rField.SetLastHdl( rLink );
498cdf0e10cSrcweir         rField.SetLoseFocusHdl( rLink );
499cdf0e10cSrcweir     }
500cdf0e10cSrcweir }
501cdf0e10cSrcweir 
502cdf0e10cSrcweir void DialControl::HandleMouseEvent( const Point& rPos, bool bInitial )
503cdf0e10cSrcweir {
504cdf0e10cSrcweir     long nX = rPos.X() - mpImpl->mnCenterX;
505cdf0e10cSrcweir     long nY = mpImpl->mnCenterY - rPos.Y();
506cdf0e10cSrcweir     double fH = sqrt( static_cast< double >( nX ) * nX + static_cast< double >( nY ) * nY );
507cdf0e10cSrcweir     if( fH != 0.0 )
508cdf0e10cSrcweir     {
509cdf0e10cSrcweir         double fAngle = acos( nX / fH );
510cdf0e10cSrcweir         sal_Int32 nAngle = static_cast< sal_Int32 >( fAngle / F_PI180 * 100.0 );
511cdf0e10cSrcweir         if( nY < 0 )
512cdf0e10cSrcweir             nAngle = 36000 - nAngle;
513cdf0e10cSrcweir         if( bInitial )  // round to entire 15 degrees
514cdf0e10cSrcweir             nAngle = ((nAngle + 750) / 1500) * 1500;
515cdf0e10cSrcweir         ImplSetRotation( nAngle, true );
516cdf0e10cSrcweir     }
517cdf0e10cSrcweir }
518cdf0e10cSrcweir 
519cdf0e10cSrcweir void DialControl::HandleEscapeEvent()
520cdf0e10cSrcweir {
521cdf0e10cSrcweir     if( IsMouseCaptured() )
522cdf0e10cSrcweir     {
523cdf0e10cSrcweir         ReleaseMouse();
524cdf0e10cSrcweir         ImplSetRotation( mpImpl->mnOldAngle, true );
525cdf0e10cSrcweir         if( mpImpl->mpLinkField )
526cdf0e10cSrcweir             mpImpl->mpLinkField->GrabFocus();
527cdf0e10cSrcweir     }
528cdf0e10cSrcweir }
529cdf0e10cSrcweir 
530cdf0e10cSrcweir IMPL_LINK( DialControl, LinkedFieldModifyHdl, NumericField*, pField )
531cdf0e10cSrcweir {
532cdf0e10cSrcweir     if( pField )
533cdf0e10cSrcweir         ImplSetRotation( static_cast< sal_Int32 >( pField->GetValue() * 100 ), false );
534cdf0e10cSrcweir     return 0;
535cdf0e10cSrcweir }
536cdf0e10cSrcweir 
537cdf0e10cSrcweir // ============================================================================
538cdf0e10cSrcweir 
539cdf0e10cSrcweir DialControlWrapper::DialControlWrapper( DialControl& rDial ) :
540cdf0e10cSrcweir     SingleControlWrapperType( rDial )
541cdf0e10cSrcweir {
542cdf0e10cSrcweir }
543cdf0e10cSrcweir 
544cdf0e10cSrcweir bool DialControlWrapper::IsControlDontKnow() const
545cdf0e10cSrcweir {
546cdf0e10cSrcweir     return !GetControl().HasRotation();
547cdf0e10cSrcweir }
548cdf0e10cSrcweir 
549cdf0e10cSrcweir void DialControlWrapper::SetControlDontKnow( bool bSet )
550cdf0e10cSrcweir {
551cdf0e10cSrcweir     if( bSet )
552cdf0e10cSrcweir         GetControl().SetNoRotation();
553cdf0e10cSrcweir }
554cdf0e10cSrcweir 
555cdf0e10cSrcweir sal_Int32 DialControlWrapper::GetControlValue() const
556cdf0e10cSrcweir {
557cdf0e10cSrcweir     return GetControl().GetRotation();
558cdf0e10cSrcweir }
559cdf0e10cSrcweir 
560cdf0e10cSrcweir void DialControlWrapper::SetControlValue( sal_Int32 nValue )
561cdf0e10cSrcweir {
562cdf0e10cSrcweir     GetControl().SetRotation( nValue );
563cdf0e10cSrcweir }
564cdf0e10cSrcweir 
565cdf0e10cSrcweir // ============================================================================
566cdf0e10cSrcweir 
567cdf0e10cSrcweir } // namespace svx
568cdf0e10cSrcweir 
569