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